aboutsummaryrefslogtreecommitdiff
path: root/src/algebra
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
committerdos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
commitab8cc85adde879fb963c94d15675783f2cf4b183 (patch)
treec202482327f474583b750b2c45dedfc4e4312b1d /src/algebra
downloadopen-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz
Initial population.
Diffstat (limited to 'src/algebra')
-rw-r--r--src/algebra/ChangeLog143
-rw-r--r--src/algebra/Lattice.pamphlet45354
-rw-r--r--src/algebra/Makefile.in1151
-rw-r--r--src/algebra/Makefile.pamphlet2305
-rw-r--r--src/algebra/acplot.spad.pamphlet1241
-rw-r--r--src/algebra/aggcat.spad.pamphlet3227
-rw-r--r--src/algebra/aggcat2.spad.pamphlet223
-rw-r--r--src/algebra/algcat.spad.pamphlet382
-rw-r--r--src/algebra/algext.spad.pamphlet235
-rw-r--r--src/algebra/algfact.spad.pamphlet346
-rw-r--r--src/algebra/algfunc.spad.pamphlet577
-rw-r--r--src/algebra/allfact.spad.pamphlet486
-rw-r--r--src/algebra/alql.spad.pamphlet265
-rw-r--r--src/algebra/annacat.spad.pamphlet504
-rw-r--r--src/algebra/any.spad.pamphlet241
-rw-r--r--src/algebra/array1.spad.pamphlet606
-rw-r--r--src/algebra/array2.spad.pamphlet451
-rw-r--r--src/algebra/asp.spad.pamphlet4295
-rw-r--r--src/algebra/attreg.spad.pamphlet127
-rw-r--r--src/algebra/axtimer.as.pamphlet191
-rw-r--r--src/algebra/bags.spad.pamphlet329
-rw-r--r--src/algebra/bezout.spad.pamphlet206
-rw-r--r--src/algebra/boolean.spad.pamphlet587
-rw-r--r--src/algebra/brill.spad.pamphlet161
-rw-r--r--src/algebra/c02.spad.pamphlet130
-rw-r--r--src/algebra/c05.spad.pamphlet176
-rw-r--r--src/algebra/c06.spad.pamphlet339
-rw-r--r--src/algebra/card.spad.pamphlet206
-rw-r--r--src/algebra/carten.spad.pamphlet684
-rw-r--r--src/algebra/catdef.spad.pamphlet4565
-rw-r--r--src/algebra/cden.spad.pamphlet238
-rw-r--r--src/algebra/clifford.spad.pamphlet533
-rw-r--r--src/algebra/clip.spad.pamphlet341
-rw-r--r--src/algebra/cmplxrt.spad.pamphlet117
-rw-r--r--src/algebra/coerce.spad.pamphlet125
-rw-r--r--src/algebra/color.spad.pamphlet202
-rw-r--r--src/algebra/combfunc.spad.pamphlet913
-rw-r--r--src/algebra/combinat.spad.pamphlet201
-rw-r--r--src/algebra/complet.spad.pamphlet377
-rw-r--r--src/algebra/constant.spad.pamphlet243
-rw-r--r--src/algebra/cont.spad.pamphlet357
-rw-r--r--src/algebra/contfrac.spad.pamphlet425
-rw-r--r--src/algebra/coordsys.spad.pamphlet240
-rw-r--r--src/algebra/cra.spad.pamphlet131
-rw-r--r--src/algebra/crfp.spad.pamphlet643
-rw-r--r--src/algebra/curve.spad.pamphlet946
-rw-r--r--src/algebra/cycles.spad.pamphlet323
-rw-r--r--src/algebra/cyclotom.spad.pamphlet109
-rw-r--r--src/algebra/d01.spad.pamphlet447
-rw-r--r--src/algebra/d01Package.spad.pamphlet559
-rw-r--r--src/algebra/d01agents.spad.pamphlet430
-rw-r--r--src/algebra/d01routine.spad.pamphlet751
-rw-r--r--src/algebra/d01transform.spad.pamphlet212
-rw-r--r--src/algebra/d01weights.spad.pamphlet311
-rw-r--r--src/algebra/d02.spad.pamphlet483
-rw-r--r--src/algebra/d02Package.spad.pamphlet457
-rw-r--r--src/algebra/d02agents.spad.pamphlet424
-rw-r--r--src/algebra/d02routine.spad.pamphlet424
-rw-r--r--src/algebra/d03.spad.pamphlet195
-rw-r--r--src/algebra/d03Package.spad.pamphlet307
-rw-r--r--src/algebra/d03agents.spad.pamphlet147
-rw-r--r--src/algebra/d03routine.spad.pamphlet164
-rw-r--r--src/algebra/ddfact.spad.pamphlet309
-rw-r--r--src/algebra/defaults.spad.pamphlet221
-rw-r--r--src/algebra/defintef.spad.pamphlet267
-rw-r--r--src/algebra/defintrf.spad.pamphlet398
-rw-r--r--src/algebra/degred.spad.pamphlet99
-rw-r--r--src/algebra/derham.spad.pamphlet468
-rw-r--r--src/algebra/dhmatrix.spad.pamphlet1741
-rw-r--r--src/algebra/divisor.spad.pamphlet1009
-rw-r--r--src/algebra/dpolcat.spad.pamphlet591
-rw-r--r--src/algebra/draw.spad.pamphlet1200
-rw-r--r--src/algebra/drawopt.spad.pamphlet458
-rw-r--r--src/algebra/drawpak.spad.pamphlet226
-rw-r--r--src/algebra/e01.spad.pamphlet329
-rw-r--r--src/algebra/e02.spad.pamphlet588
-rw-r--r--src/algebra/e04.spad.pamphlet397
-rw-r--r--src/algebra/e04Package.spad.pamphlet448
-rw-r--r--src/algebra/e04agents.spad.pamphlet313
-rw-r--r--src/algebra/e04routine.spad.pamphlet691
-rw-r--r--src/algebra/efstruc.spad.pamphlet961
-rw-r--r--src/algebra/efuls.spad.pamphlet400
-rw-r--r--src/algebra/efupxs.spad.pamphlet313
-rw-r--r--src/algebra/eigen.spad.pamphlet340
-rw-r--r--src/algebra/elemntry.spad.pamphlet914
-rw-r--r--src/algebra/elfuts.spad.pamphlet110
-rw-r--r--src/algebra/equation1.spad.pamphlet112
-rw-r--r--src/algebra/equation2.spad.pamphlet325
-rw-r--r--src/algebra/error.spad.pamphlet139
-rw-r--r--src/algebra/expexpan.spad.pamphlet555
-rw-r--r--src/algebra/exposed.lsp.pamphlet1257
-rw-r--r--src/algebra/expr.spad.pamphlet915
-rw-r--r--src/algebra/expr2ups.spad.pamphlet383
-rw-r--r--src/algebra/exprode.spad.pamphlet255
-rw-r--r--src/algebra/f01.spad.pamphlet343
-rw-r--r--src/algebra/f02.spad.pamphlet565
-rw-r--r--src/algebra/f04.spad.pamphlet408
-rw-r--r--src/algebra/f07.spad.pamphlet182
-rw-r--r--src/algebra/facutil.spad.pamphlet218
-rw-r--r--src/algebra/ffcat.spad.pamphlet873
-rw-r--r--src/algebra/ffcg.spad.pamphlet467
-rw-r--r--src/algebra/fff.spad.pamphlet304
-rw-r--r--src/algebra/ffhom.spad.pamphlet431
-rw-r--r--src/algebra/ffnb.spad.pamphlet887
-rw-r--r--src/algebra/ffp.spad.pamphlet403
-rw-r--r--src/algebra/ffpoly.spad.pamphlet1036
-rw-r--r--src/algebra/ffpoly2.spad.pamphlet172
-rw-r--r--src/algebra/ffrac.as.pamphlet204
-rw-r--r--src/algebra/ffx.spad.pamphlet120
-rw-r--r--src/algebra/files.spad.pamphlet562
-rw-r--r--src/algebra/float.spad.pamphlet1064
-rw-r--r--src/algebra/fmod.spad.pamphlet143
-rw-r--r--src/algebra/fname.spad.pamphlet148
-rw-r--r--src/algebra/fnla.spad.pamphlet344
-rw-r--r--src/algebra/formula.spad.pamphlet519
-rw-r--r--src/algebra/fortcat.spad.pamphlet345
-rw-r--r--src/algebra/fortmac.spad.pamphlet461
-rw-r--r--src/algebra/fortpak.spad.pamphlet659
-rw-r--r--src/algebra/fortran.spad.pamphlet1787
-rw-r--r--src/algebra/forttyp.spad.pamphlet703
-rw-r--r--src/algebra/fourier.spad.pamphlet169
-rw-r--r--src/algebra/fparfrac.spad.pamphlet232
-rw-r--r--src/algebra/fr.spad.pamphlet677
-rw-r--r--src/algebra/fraction.spad.pamphlet846
-rw-r--r--src/algebra/free.spad.pamphlet601
-rw-r--r--src/algebra/fs2expxp.spad.pamphlet598
-rw-r--r--src/algebra/fs2ups.spad.pamphlet812
-rw-r--r--src/algebra/fspace.spad.pamphlet1246
-rw-r--r--src/algebra/funcpkgs.spad.pamphlet193
-rw-r--r--src/algebra/functions.spad.pamphlet120
-rw-r--r--src/algebra/galfact.spad.pamphlet862
-rw-r--r--src/algebra/galfactu.spad.pamphlet214
-rw-r--r--src/algebra/galpolyu.spad.pamphlet156
-rw-r--r--src/algebra/galutil.spad.pamphlet173
-rw-r--r--src/algebra/gaussfac.spad.pamphlet233
-rw-r--r--src/algebra/gaussian.spad.pamphlet828
-rw-r--r--src/algebra/gb.spad.pamphlet211
-rw-r--r--src/algebra/gbeuclid.spad.pamphlet596
-rw-r--r--src/algebra/gbintern.spad.pamphlet514
-rw-r--r--src/algebra/gdirprod.spad.pamphlet254
-rw-r--r--src/algebra/gdpoly.spad.pamphlet378
-rw-r--r--src/algebra/geneez.spad.pamphlet248
-rw-r--r--src/algebra/generic.spad.pamphlet406
-rw-r--r--src/algebra/genufact.spad.pamphlet116
-rw-r--r--src/algebra/genups.spad.pamphlet249
-rw-r--r--src/algebra/ghensel.spad.pamphlet202
-rw-r--r--src/algebra/gpgcd.spad.pamphlet691
-rw-r--r--src/algebra/gpol.spad.pamphlet214
-rw-r--r--src/algebra/grdef.spad.pamphlet143
-rw-r--r--src/algebra/groebf.spad.pamphlet385
-rw-r--r--src/algebra/groebsol.spad.pamphlet245
-rw-r--r--src/algebra/gseries.spad.pamphlet165
-rw-r--r--src/algebra/herm.as.pamphlet369
-rw-r--r--src/algebra/ideal.spad.pamphlet474
-rw-r--r--src/algebra/idecomp.spad.pamphlet440
-rw-r--r--src/algebra/indexedp.spad.pamphlet350
-rw-r--r--src/algebra/infprod.spad.pamphlet346
-rw-r--r--src/algebra/intaf.spad.pamphlet782
-rw-r--r--src/algebra/intalg.spad.pamphlet488
-rw-r--r--src/algebra/intaux.spad.pamphlet299
-rw-r--r--src/algebra/intclos.spad.pamphlet816
-rw-r--r--src/algebra/intef.spad.pamphlet389
-rw-r--r--src/algebra/integer.spad.pamphlet865
-rw-r--r--src/algebra/integrat.spad.pamphlet269
-rw-r--r--src/algebra/interval.as.pamphlet564
-rw-r--r--src/algebra/interval.spad.pamphlet547
-rw-r--r--src/algebra/intfact.spad.pamphlet534
-rw-r--r--src/algebra/intpm.spad.pamphlet377
-rw-r--r--src/algebra/intrf.spad.pamphlet911
-rw-r--r--src/algebra/invnode.as.pamphlet340
-rw-r--r--src/algebra/invrender.as.pamphlet172
-rw-r--r--src/algebra/invtypes.as.pamphlet302
-rw-r--r--src/algebra/invutils.as.pamphlet172
-rw-r--r--src/algebra/irexpand.spad.pamphlet343
-rw-r--r--src/algebra/irsn.spad.pamphlet365
-rw-r--r--src/algebra/ituple.spad.pamphlet140
-rw-r--r--src/algebra/iviews.as.pamphlet330
-rw-r--r--src/algebra/kl.spad.pamphlet361
-rw-r--r--src/algebra/kovacic.spad.pamphlet152
-rw-r--r--src/algebra/laplace.spad.pamphlet337
-rw-r--r--src/algebra/laurent.spad.pamphlet678
-rw-r--r--src/algebra/leadcdet.spad.pamphlet167
-rw-r--r--src/algebra/libdb.text78
-rw-r--r--src/algebra/lie.spad.pamphlet259
-rw-r--r--src/algebra/limitps.spad.pamphlet768
-rw-r--r--src/algebra/lindep.spad.pamphlet165
-rw-r--r--src/algebra/lingrob.spad.pamphlet362
-rw-r--r--src/algebra/liouv.spad.pamphlet246
-rw-r--r--src/algebra/list.spad.pamphlet803
-rw-r--r--src/algebra/listgcd.spad.pamphlet268
-rw-r--r--src/algebra/lmdict.spad.pamphlet200
-rw-r--r--src/algebra/lodo.spad.pamphlet293
-rw-r--r--src/algebra/lodof.spad.pamphlet533
-rw-r--r--src/algebra/lodop.spad.pamphlet349
-rw-r--r--src/algebra/manip.spad.pamphlet874
-rw-r--r--src/algebra/mappkg.spad.pamphlet304
-rw-r--r--src/algebra/matcat.spad.pamphlet904
-rw-r--r--src/algebra/matfuns.spad.pamphlet803
-rw-r--r--src/algebra/matrix.spad.pamphlet530
-rw-r--r--src/algebra/matstor.spad.pamphlet246
-rw-r--r--src/algebra/mesh.spad.pamphlet188
-rw-r--r--src/algebra/mfinfact.spad.pamphlet547
-rw-r--r--src/algebra/misc.spad.pamphlet74
-rw-r--r--src/algebra/mkfunc.spad.pamphlet497
-rw-r--r--src/algebra/mkrecord.spad.pamphlet70
-rw-r--r--src/algebra/mlift.spad.jhd.pamphlet272
-rw-r--r--src/algebra/mlift.spad.pamphlet277
-rw-r--r--src/algebra/moddfact.spad.pamphlet282
-rw-r--r--src/algebra/modgcd.spad.pamphlet315
-rw-r--r--src/algebra/modmon.spad.pamphlet224
-rw-r--r--src/algebra/modmonom.spad.pamphlet158
-rw-r--r--src/algebra/modring.spad.pamphlet280
-rw-r--r--src/algebra/moebius.spad.pamphlet154
-rw-r--r--src/algebra/mring.spad.pamphlet405
-rw-r--r--src/algebra/mset.spad.pamphlet339
-rw-r--r--src/algebra/mts.spad.pamphlet367
-rw-r--r--src/algebra/multfact.spad.pamphlet604
-rw-r--r--src/algebra/multpoly.spad.pamphlet760
-rw-r--r--src/algebra/multsqfr.spad.pamphlet395
-rw-r--r--src/algebra/naalg.spad.pamphlet1095
-rw-r--r--src/algebra/naalgc.spad.pamphlet1260
-rw-r--r--src/algebra/ndftip.as.pamphlet1174
-rw-r--r--src/algebra/nepip.as.pamphlet626
-rw-r--r--src/algebra/newdata.spad.pamphlet671
-rw-r--r--src/algebra/newpoint.spad.pamphlet732
-rw-r--r--src/algebra/newpoly.spad.pamphlet1888
-rw-r--r--src/algebra/nlinsol.spad.pamphlet224
-rw-r--r--src/algebra/nlode.spad.pamphlet207
-rw-r--r--src/algebra/noptip.as.pamphlet241
-rw-r--r--src/algebra/npcoef.spad.pamphlet212
-rw-r--r--src/algebra/nqip.as.pamphlet231
-rw-r--r--src/algebra/nrc.as.pamphlet132
-rw-r--r--src/algebra/nregset.spad.pamphlet288
-rw-r--r--src/algebra/nsfip.as.pamphlet1223
-rw-r--r--src/algebra/nsregset.spad.pamphlet203
-rw-r--r--src/algebra/numeigen.spad.pamphlet413
-rw-r--r--src/algebra/numeric.spad.pamphlet520
-rw-r--r--src/algebra/numode.spad.pamphlet410
-rw-r--r--src/algebra/numquad.spad.pamphlet600
-rw-r--r--src/algebra/numsolve.spad.pamphlet485
-rw-r--r--src/algebra/numtheor.spad.pamphlet736
-rw-r--r--src/algebra/oct.spad.pamphlet414
-rw-r--r--src/algebra/odealg.spad.pamphlet393
-rw-r--r--src/algebra/odeef.spad.pamphlet643
-rw-r--r--src/algebra/oderf.spad.pamphlet900
-rw-r--r--src/algebra/omcat.spad.pamphlet85
-rw-r--r--src/algebra/omdev.spad.pamphlet385
-rw-r--r--src/algebra/omerror.spad.pamphlet151
-rw-r--r--src/algebra/omserver.spad.pamphlet120
-rw-r--r--src/algebra/op.spad.pamphlet541
-rw-r--r--src/algebra/opalg.spad.pamphlet294
-rw-r--r--src/algebra/openmath.spad.pamphlet331
-rw-r--r--src/algebra/ore.spad.pamphlet559
-rw-r--r--src/algebra/out.spad.pamphlet311
-rw-r--r--src/algebra/outform.spad.pamphlet964
-rw-r--r--src/algebra/pade.spad.pamphlet247
-rw-r--r--src/algebra/padic.spad.pamphlet624
-rw-r--r--src/algebra/padiclib.spad.pamphlet571
-rw-r--r--src/algebra/paramete.spad.pamphlet218
-rw-r--r--src/algebra/partperm.spad.pamphlet168
-rw-r--r--src/algebra/patmatch1.spad.pamphlet712
-rw-r--r--src/algebra/patmatch2.spad.pamphlet404
-rw-r--r--src/algebra/pattern.spad.pamphlet555
-rw-r--r--src/algebra/pcurve.spad.pamphlet132
-rw-r--r--src/algebra/pdecomp.spad.pamphlet135
-rw-r--r--src/algebra/perm.spad.pamphlet534
-rw-r--r--src/algebra/perman.spad.pamphlet319
-rw-r--r--src/algebra/permgrps.spad.pamphlet1188
-rw-r--r--src/algebra/pf.spad.pamphlet266
-rw-r--r--src/algebra/pfbr.spad.pamphlet591
-rw-r--r--src/algebra/pfo.spad.pamphlet612
-rw-r--r--src/algebra/pfr.spad.pamphlet438
-rw-r--r--src/algebra/pgcd.spad.pamphlet458
-rw-r--r--src/algebra/pgrobner.spad.pamphlet121
-rw-r--r--src/algebra/pinterp.spad.pamphlet111
-rw-r--r--src/algebra/pleqn.spad.pamphlet654
-rw-r--r--src/algebra/plot.spad.pamphlet651
-rw-r--r--src/algebra/plot3d.spad.pamphlet541
-rw-r--r--src/algebra/plottool.spad.pamphlet130
-rw-r--r--src/algebra/polset.spad.pamphlet582
-rw-r--r--src/algebra/poltopol.spad.pamphlet204
-rw-r--r--src/algebra/poly.spad.pamphlet1249
-rw-r--r--src/algebra/polycat.spad.pamphlet4785
-rw-r--r--src/algebra/primelt.spad.pamphlet269
-rw-r--r--src/algebra/print.spad.pamphlet75
-rw-r--r--src/algebra/product.spad.pamphlet151
-rw-r--r--src/algebra/prs.spad.pamphlet986
-rw-r--r--src/algebra/prtition.spad.pamphlet218
-rw-r--r--src/algebra/pscat.spad.pamphlet691
-rw-r--r--src/algebra/pseudolin.spad.pamphlet208
-rw-r--r--src/algebra/ptranfn.spad.pamphlet146
-rw-r--r--src/algebra/puiseux.spad.pamphlet658
-rw-r--r--src/algebra/qalgset.spad.pamphlet353
-rw-r--r--src/algebra/quat.spad.pamphlet312
-rw-r--r--src/algebra/radeigen.spad.pamphlet235
-rw-r--r--src/algebra/radix.spad.pamphlet427
-rw-r--r--src/algebra/random.spad.pamphlet348
-rw-r--r--src/algebra/ratfact.spad.pamphlet113
-rw-r--r--src/algebra/rdeef.spad.pamphlet568
-rw-r--r--src/algebra/rderf.spad.pamphlet226
-rw-r--r--src/algebra/rdesys.spad.pamphlet362
-rw-r--r--src/algebra/real0q.spad.pamphlet129
-rw-r--r--src/algebra/realzero.spad.pamphlet347
-rw-r--r--src/algebra/reclos.spad.pamphlet1242
-rw-r--r--src/algebra/regset.spad.pamphlet1806
-rw-r--r--src/algebra/rep1.spad.pamphlet380
-rw-r--r--src/algebra/rep2.spad.pamphlet827
-rw-r--r--src/algebra/resring.spad.pamphlet109
-rw-r--r--src/algebra/retract.spad.pamphlet137
-rw-r--r--src/algebra/rf.spad.pamphlet263
-rw-r--r--src/algebra/riccati.spad.pamphlet600
-rw-r--r--src/algebra/rinterp.spad.pamphlet150
-rw-r--r--src/algebra/routines.spad.pamphlet648
-rw-r--r--src/algebra/rule.spad.pamphlet349
-rw-r--r--src/algebra/s.spad.pamphlet833
-rw-r--r--src/algebra/seg.spad.pamphlet531
-rw-r--r--src/algebra/setorder.spad.pamphlet186
-rw-r--r--src/algebra/sets.spad.pamphlet233
-rw-r--r--src/algebra/sex.spad.pamphlet217
-rw-r--r--src/algebra/sf.spad.pamphlet1403
-rw-r--r--src/algebra/sgcf.spad.pamphlet526
-rw-r--r--src/algebra/si.spad.pamphlet1557
-rw-r--r--src/algebra/sign.spad.pamphlet392
-rw-r--r--src/algebra/smith.spad.pamphlet284
-rw-r--r--src/algebra/solvedio.spad.pamphlet232
-rw-r--r--src/algebra/solvefor.spad.pamphlet327
-rw-r--r--src/algebra/solvelin.spad.pamphlet282
-rw-r--r--src/algebra/solverad.spad.pamphlet328
-rw-r--r--src/algebra/sortpak.spad.pamphlet107
-rw-r--r--src/algebra/space.spad.pamphlet700
-rw-r--r--src/algebra/special.spad.pamphlet456
-rw-r--r--src/algebra/sregset.spad.pamphlet1606
-rw-r--r--src/algebra/stream.spad.pamphlet1296
-rw-r--r--src/algebra/string.spad.pamphlet735
-rw-r--r--src/algebra/sttaylor.spad.pamphlet515
-rw-r--r--src/algebra/sttf.spad.pamphlet743
-rw-r--r--src/algebra/sturm.spad.pamphlet421
-rw-r--r--src/algebra/suchthat.spad.pamphlet79
-rw-r--r--src/algebra/suls.spad.pamphlet250
-rw-r--r--src/algebra/sum.spad.pamphlet390
-rw-r--r--src/algebra/sups.spad.pamphlet1114
-rw-r--r--src/algebra/supxs.spad.pamphlet142
-rw-r--r--src/algebra/suts.spad.pamphlet439
-rw-r--r--src/algebra/symbol.spad.pamphlet462
-rw-r--r--src/algebra/syssolp.spad.pamphlet297
-rw-r--r--src/algebra/system.spad.pamphlet86
-rw-r--r--src/algebra/table.spad.pamphlet265
-rw-r--r--src/algebra/tableau.spad.pamphlet234
-rw-r--r--src/algebra/taylor.spad.pamphlet490
-rw-r--r--src/algebra/tex.spad.pamphlet709
-rw-r--r--src/algebra/tools.spad.pamphlet470
-rw-r--r--src/algebra/transsolve.spad.pamphlet694
-rw-r--r--src/algebra/tree.spad.pamphlet694
-rw-r--r--src/algebra/trigcat.spad.pamphlet333
-rw-r--r--src/algebra/triset.spad.pamphlet1739
-rw-r--r--src/algebra/tube.spad.pamphlet508
-rw-r--r--src/algebra/twofact.spad.pamphlet330
-rw-r--r--src/algebra/unifact.spad.pamphlet368
-rw-r--r--src/algebra/updecomp.spad.pamphlet178
-rw-r--r--src/algebra/updivp.spad.pamphlet99
-rw-r--r--src/algebra/utsode.spad.pamphlet181
-rw-r--r--src/algebra/variable.spad.pamphlet146
-rw-r--r--src/algebra/vector.spad.pamphlet528
-rw-r--r--src/algebra/view2D.spad.pamphlet1170
-rw-r--r--src/algebra/view3D.spad.pamphlet1006
-rw-r--r--src/algebra/viewDef.spad.pamphlet264
-rw-r--r--src/algebra/viewpack.spad.pamphlet156
-rw-r--r--src/algebra/void.spad.pamphlet145
-rw-r--r--src/algebra/weier.spad.pamphlet202
-rw-r--r--src/algebra/wtpol.spad.pamphlet199
-rw-r--r--src/algebra/xlpoly.spad.pamphlet1216
-rw-r--r--src/algebra/xpoly.spad.pamphlet1132
-rw-r--r--src/algebra/ystream.spad.pamphlet96
-rw-r--r--src/algebra/zerodim.spad.pamphlet1189
374 files changed, 233542 insertions, 0 deletions
diff --git a/src/algebra/ChangeLog b/src/algebra/ChangeLog
new file mode 100644
index 00000000..8c392ad9
--- /dev/null
+++ b/src/algebra/ChangeLog
@@ -0,0 +1,143 @@
+2007-08-06 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (strap/%.o): Tidy. Don't pipe command
+ into $(DEPSYS); directly invoke the compiler in batch mode
+ so that Makefile can see the real exit status.
+
+ * Makefile.in: Regenerate.
+
+2007-06-20 Gabriel Dos Reis <gdr@cs.tamu,edu>
+
+ * Makefile.pamphlet (mkdir-output-directory): Use $(mkinstalldirs).
+ (${OUT}/%.o): Be verbose.
+ (mk-target-src-algabra-dir): New target.
+ ($(OUTSRC)/%.spad): Make it a prerequisite.
+ (mk-target-doc-dir): New target.
+ ($(DOC)/%.dvi): Make it a prerequisite.
+ * Makefile.in: Regenerate.
+
+2007-05-30 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (%.NRLIB/code.o): Don't use NOISE.
+ (strap/%.o): Likewise.
+ ($(builddir)/%.dvi): Likewise.
+ * Makefile.in: Regenerate.
+
+2007-04-01 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (DEPSYS): Adjust path.
+ (INTERPSYS): Likewise.
+ * Makefile.in: Regenerate.
+
+2006-12-16 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (MID): Remove.
+ (INPUT): Adjust value.
+ * Makefile.in: Regenerate.
+
+2006-12-14 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Restructure.
+ Compile algebra bootstrap files to strap/ sub-directory.
+ Write out the dependency between layers.
+ Avoid chaging to distant directories.
+ * Makefile.in: Regenerate.
+
+2006-12-09 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (INTERPSYS): Point DAASE to databases included
+ in the source files.
+
+2006-12-09 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (MID): Adjust definition.
+ (INPUT): Likewise.
+ * Makefile.in: Regenerate.
+
+2006-12-07 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (EXTRACT_BOOTSTRAP_FILE): New variable.
+ Encapsulate rules for extracting algebra bootstrap files.
+ (${MID}/%.o): Take prerequisites from current build directory.
+ (<<findAlgebraFiles>>): Remove.
+ * Makefile.in: Regenerate.
+
+2006-11-24 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Mark as not adequate for parallel build.
+ (all-algebra): New phony target.
+ * Makefile.in: Regenerate.
+
+2006-10-26 Bill Page <Bill.Page@drdc-rddc.gc.ca>
+
+ * Makefile.pamphlet (${MID}/%.NRLIB/code.o): Fix tabs.
+ (<<findSpadFiles>>): Don't escape dollar sign inside AWK expression.
+ (<<findBootstrapFiles>>): Likewise.
+ * Makefile.in: Regenerate.
+
+2006-10-25 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * Makefile.pamphlet (libdb.text): remove
+ * Makefile.in: Regenerate.
+
+2006-10-08 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Remove commented codes. Remove references to
+ ${MNT}.
+ (OUTSRC): New rule.
+ (all): Depend on it.
+ (clean-local): Rename from clean.
+ (mostlyclean-local, distclean-local): New.
+
+2006-10-07 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * Makefile.pamphlet (${MID}/%.NRLIB/code.o): Remove old NRLIB
+ * Makefile.in: Regenerate.
+
+2006-10-03 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (document): Remove.
+
+2006-10-02 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (DEPSYS): Set dirname to $(axiom_build_bindir)
+ (INTERPSYS): Likewise.
+ * Makefile.in: Regenerate.
+
+2006-09-26 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (all): Create stamp file.
+
+2006-09-19 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (all): Don't build $(DOCFILES) yet.
+
+2006-09-18 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet (subdir): New.
+ * Makefile.in: Regenerate.
+
+2006-09-11 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Use $(axiom_build_document) to tangle
+ pamphlets. Add support for out-of-source build.
+ * Makefile.in: Regenerate.
+
+2006-09-09 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Rework generic rules for building docs.
+ * Makefile.in: Regenerate.
+
+2006-09-03 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.in: New.
+
+2006-09-02 Vanuxem Grégory <g.vanuxem@wanadoo.fr>
+
+ * attreg.spad.pamphlet: Fix typo.
+ * clifford.spad.pamphlet: Likewise.
+
+2006-08-27 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * Makefile.pamphlet: Don't overwite $(TMP)/trace; append instead.
+
diff --git a/src/algebra/Lattice.pamphlet b/src/algebra/Lattice.pamphlet
new file mode 100644
index 00000000..635243ae
--- /dev/null
+++ b/src/algebra/Lattice.pamphlet
@@ -0,0 +1,45354 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra Makefile}
+\author{Timothy Daly}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{Adding new algebra}
+This is a complex process by its very nature. Developers and Maintainers
+who undertake the process need to understand quite a lot of detail. The
+ultimate steps to add algebra are tedious but simple. Note that only
+algebra code that gets shipped with the system needs to undergo this
+process. User code can be compiled once the distributed algebra exists
+and does not need either this Makefile or this installation process.
+
+Since understanding is the key to making correct changes to this file
+I'll work on explaining the details of why things need to exist.
+
+The first idea that you need to understand is the overall process
+of adding algebra code. Lets assume that you have a brand new spad
+file, called [[foo.spad]] containing a simple domain [[BAR]]. The
+steps in the process of adding this file are:
+\begin{enumerate}
+\item Find out where the algebra code lives in the lattice.
+
+You do this by
+\begin{enumerate}
+\item starting a new interpsys session
+\item collecting all the names of the algebra files BAR requires
+\item determining which layer each of the required files resides
+\item determine the highest layer (e.g. 14) that contains the required files
+\end{enumerate}
+
+\item insert the documentation into the next layer (e.g. 15)
+\item insert the [[${OUT}/BAR.o]] file into the layer's file list
+\item create a new subsection for the [[foo.spad]] file
+\item add a stanza to extract [[foo.spad]] from [[foo.spad.pamphlet]]
+\item add a stanza to extract [[foo.dvi]] from [[foo.spad.pamphlet]]
+\item add a stanza to compile [[foo.spad]] to get [[BAR.lsp]]
+\item add a stanza to compile [[BAR.lsp]] to get [[BAR.o]]
+\item add a stanza to copy [[BAR.o]] to the final algebra directory
+\item add the 5 chunk names into the default Makefile section
+\end{enumerate}
+
+\section{Rebuilding the algebra from scratch}
+Compile order is important. Here we try to define the ordered lattice
+of spad file dependencies. However this is, in reality, a graph rather
+than a lattice. In order to break cycles in this graph we explicitly
+cache a few of the intermediate generated lisp code for certain files.
+These are marked throughout (both here and in the various pamphlet
+files) with the word {\bf BOOTSTRAP}.
+
+If we take a cycle such as {\bf RING} we discover that in order to
+compile the spad code we must load the compiled definition of {\bf RING}.
+In this case we must compile the cached lisp code before we try to
+compile the spad file.
+
+The cycle for {\bf SETCAT} is longer consisting of: {\bf SETCAT} needs
+{\bf SINT} needs {\bf UFD} needs {\bf GCDDOM} needs {\bf COMRING} needs
+{\bf RING} needs {\bf RNG} needs {\bf ABELGRP} needs {\bf CABMON} needs
+{\bf ABELMON} needs {\bf ABELSG} needs {\bf SETCAT}.
+
+It is highly recommended that you try to become a developer of Axiom
+and read the archived mailing lists before you decide to change a
+cached file. In the fullness of time we will rewrite the whole algebra
+structure into a proper lattice if possible. Alternatively we'll
+reimplement the compiler to handle graphs. Or deeply adopt the
+extensible domains. Whatever we do will be much discussed (and cause
+much disgust) around the campfire. If you come up with a brilliant
+plan that gets adopted we'll even inscribe your name on a log and add
+it to the fire.
+
+In the code that follows we find the categories, packages and domains
+that compile with no dependencies and call this set ``layer 0''. Next
+we find the categories, packages and domains that will compile using
+only ``layer 0'' code and call this ``layer 1''. We walk up the
+lattice in this fashion adding layers. Note that at layer 3 this
+process runs into cycles and we create the ``layer 3 bootstrap''
+stanzas before continuing upward.
+
+I used to have code that would automatically generate this lattice but
+it got lost in the move from IBM to NAG. The current information was
+hand generated during the coding of this Makefile. Except for the
+bootstrap files most of the stanzas have the dependency graph encoded
+in the precondition lists for each makefile stanza. Thus we can see
+that building the package {\bf ANY1} requires the category {\bf TYPE}.
+
+\begin{verbatim}
+${MID}/ANY1.NRLIB: ${OUT}/TYPE.o ${MID}/ANY1.spad
+\end{verbatim}
+
+This information also exists in the comments before each layer.
+Ordinary users of Axiom won't need to know this. However developers
+of the standard system should strive to keep this information up to
+date and correct. The spad compiler will tell you this information
+as part of the compile.
+
+Once we reach the point in the lattice where all of the individual
+categories, domains and packages in each spad file have been compiled
+we can start building the system directly from the whole spad code
+files rather than the individual domains.
+\section{Pamphlets (category, packages, and domains)}
+DONE acplot.spad.pamphlet
+DONE )abbrev package REALSOLV RealSolvePackage
+DONE )abbrev domain ACPLOT PlaneAlgebraicCurvePlot
+DONE aggcat2.spad.pamphlet
+DONE )abbrev package FLAGG2 FiniteLinearAggregateFunctions2
+DONE )abbrev package FSAGG2 FiniteSetAggregateFunctions2
+DONE aggcat.spad.pamphlet
+DONE )abbrev category AGG Aggregate
+DONE )abbrev category HOAGG HomogeneousAggregate
+DONE )abbrev category CLAGG Collection
+DONE )abbrev category BGAGG BagAggregate
+DONE )abbrev category SKAGG StackAggregate
+DONE )abbrev category QUAGG QueueAggregate
+DONE )abbrev category DQAGG DequeueAggregate
+DONE )abbrev category PRQAGG PriorityQueueAggregate
+DONE )abbrev category DIOPS DictionaryOperations
+DONE )abbrev category DIAGG Dictionary
+DONE )abbrev category MDAGG MultiDictionary
+DONE )abbrev category SETAGG SetAggregate
+DONE )abbrev category FSAGG FiniteSetAggregate
+DONE )abbrev category MSETAGG MultisetAggregate
+DONE )abbrev category OMSAGG OrderedMultisetAggregate
+DONE )abbrev category KDAGG KeyedDictionary
+DONE )abbrev category ELTAB Eltable
+DONE )abbrev category ELTAGG EltableAggregate
+DONE )abbrev category IXAGG IndexedAggregate
+DONE )abbrev category TBAGG TableAggregate
+DONE )abbrev category RCAGG RecursiveAggregate
+DONE )abbrev category BRAGG BinaryRecursiveAggregate
+DONE )abbrev category DLAGG DoublyLinkedAggregate
+DONE )abbrev category URAGG UnaryRecursiveAggregate
+DONE )abbrev category STAGG StreamAggregate
+DONE )abbrev category LNAGG LinearAggregate
+DONE )abbrev category FLAGG FiniteLinearAggregate
+DONE )abbrev category A1AGG OneDimensionalArrayAggregate
+DONE )abbrev category ELAGG ExtensibleLinearAggregate
+DONE )abbrev category LSAGG ListAggregate
+DONE )abbrev category ALAGG AssociationListAggregate
+DONE )abbrev category SRAGG StringAggregate
+DONE )abbrev category BTAGG BitAggregate
+algcat.spad.pamphlet
+DONE )abbrev category FINRALG FiniteRankAlgebra
+DONE )abbrev category FRAMALG FramedAlgebra
+DONE )abbrev category MONOGEN MonogenicAlgebra
+)abbrev package CPIMA CharacteristicPolynomialInMonogenicalAlgebra
+DONE )abbrev package NORMMA NormInMonogenicAlgebra
+DONE algext.spad.pamphlet
+DONE )abbrev domain SAE SimpleAlgebraicExtension
+DONE algfact.spad.pamphlet
+DONE )abbrev package IALGFACT InnerAlgFactor
+DONE )abbrev package SAEFACT SimpleAlgebraicExtensionAlgFactor
+DONE )abbrev package RFFACT RationalFunctionFactor
+DONE )abbrev package SAERFFC SAERationalFunctionAlgFactor
+DONE )abbrev package ALGFACT AlgFactor
+DONE algfunc.spad.pamphlet
+DONE )abbrev category ACF AlgebraicallyClosedField
+DONE )abbrev category ACFS AlgebraicallyClosedFunctionSpace
+DONE )abbrev package AF AlgebraicFunction
+DONE allfact.spad.pamphlet
+DONE )abbrev package MRATFAC MRationalFactorize
+DONE )abbrev package MPRFF MPolyCatRationalFunctionFactorizer
+DONE )abbrev package MPCPF MPolyCatPolyFactorizer
+DONE )abbrev package GENMFACT GeneralizedMultivariateFactorize
+DONE )abbrev package RFFACTOR RationalFunctionFactorizer
+DONE )abbrev package SUPFRACF SupFractionFactorizer
+DONE alql.spad.pamphlet
+DONE )abbrev domain DLIST DataList
+DONE )abbrev domain ICARD IndexCard
+DONE )abbrev domain DBASE Database
+DONE )abbrev domain QEQUAT QueryEquation
+DONE )abbrev package MTHING MergeThing
+DONE )abbrev package OPQUERY OperationsQuery
+DONE annacat.spad.pamphlet
+DONE )abbrev domain NIPROB NumericalIntegrationProblem
+DONE )abbrev domain ODEPROB NumericalODEProblem
+DONE )abbrev domain PDEPROB NumericalPDEProblem
+DONE )abbrev domain OPTPROB NumericalOptimizationProblem
+DONE )abbrev category NUMINT NumericalIntegrationCategory
+DONE )abbrev category ODECAT OrdinaryDifferentialEquationsSolverCategory
+DONE )abbrev category PDECAT PartialDifferentialEquationsSolverCategory
+DONE )abbrev category OPTCAT NumericalOptimizationCategory
+DONE any.spad.pamphlet
+DONE )abbrev domain NONE None
+DONE )abbrev package NONE1 NoneFunctions1
+DONE )abbrev domain ANY Any
+DONE )abbrev package ANY1 AnyFunctions1
+DONE array1.spad.pamphlet
+DONE )abbrev domain PRIMARR PrimitiveArray
+DONE )abbrev package PRIMARR2 PrimitiveArrayFunctions2
+DONE )abbrev domain TUPLE Tuple
+DONE )abbrev domain IFARRAY IndexedFlexibleArray
+DONE )abbrev domain FARRAY FlexibleArray
+DONE )abbrev domain IARRAY1 IndexedOneDimensionalArray
+DONE )abbrev domain ARRAY1 OneDimensionalArray
+DONE )abbrev package ARRAY12 OneDimensionalArrayFunctions2
+DONE array2.spad.pamphlet
+DONE )abbrev category ARR2CAT TwoDimensionalArrayCategory
+DONE )abbrev domain IIARRAY2 InnerIndexedTwoDimensionalArray
+DONE )abbrev domain IARRAY2 IndexedTwoDimensionalArray
+DONE )abbrev domain ARRAY2 TwoDimensionalArray
+DONE asp.spad.pamphlet
+DONE )abbrev domain ASP1 Asp1
+DONE )abbrev domain ASP10 Asp10
+DONE )abbrev domain ASP12 Asp12
+DONE )abbrev domain ASP19 Asp19
+DONE )abbrev domain ASP20 Asp20
+DONE )abbrev domain ASP24 Asp24
+DONE )abbrev domain ASP27 Asp27
+DONE )abbrev domain ASP28 Asp28
+DONE )abbrev domain ASP29 Asp29
+DONE )abbrev domain ASP30 Asp30
+DONE )abbrev domain ASP31 Asp31
+DONE )abbrev domain ASP33 Asp33
+DONE )abbrev domain ASP34 Asp34
+DONE )abbrev domain ASP35 Asp35
+DONE )abbrev domain ASP4 Asp4
+DONE )abbrev domain ASP41 Asp41
+DONE )abbrev domain ASP42 Asp42
+DONE )abbrev domain ASP49 Asp49
+DONE )abbrev domain ASP50 Asp50
+DONE )abbrev domain ASP55 Asp55
+DONE )abbrev domain ASP6 Asp6
+DONE )abbrev domain ASP7 Asp7
+DONE )abbrev domain ASP73 Asp73
+DONE )abbrev domain ASP74 Asp74
+DONE )abbrev domain ASP77 Asp77
+DONE )abbrev domain ASP78 Asp78
+DONE )abbrev domain ASP8 Asp8
+DONE )abbrev domain ASP80 Asp80
+DONE )abbrev domain ASP9 Asp9
+DONE attreg.spad.pamphlet
+DONE )abbrev category ATTREG AttributeRegistry
+axtimer.as.pamphlet
+DONE bags.spad.pamphlet
+DONE )abbrev domain STACK Stack
+DONE )abbrev domain ASTACK ArrayStack
+DONE )abbrev domain QUEUE Queue
+DONE )abbrev domain DEQUEUE Dequeue
+DONE )abbrev domain HEAP Heap
+DONE bezout.spad.pamphlet
+DONE )abbrev package BEZOUT BezoutMatrix
+DONE boolean.spad.pamphlet
+DONE )abbrev domain REF Reference
+DONE )abbrev category LOGIC Logic
+DONE )abbrev domain BOOLEAN Boolean
+DONE )abbrev domain IBITS IndexedBits
+DONE )abbrev domain BITS Bits
+DONE brill.spad.pamphlet
+DONE )abbrev package BRILL BrillhartTests
+DONE c02.spad.pamphlet
+DONE )abbrev package NAGC02 NagPolynomialRootsPackage
+DONE c05.spad.pamphlet
+DONE )abbrev package NAGC05 NagRootFindingPackage
+DONE c06.spad.pamphlet
+DONE )abbrev package NAGC06 NagSeriesSummationPackage
+DONE card.spad.pamphlet
+DONE )abbrev domain CARD CardinalNumber
+DONE carten.spad.pamphlet
+DONE )abbrev category GRMOD GradedModule
+DONE )abbrev category GRALG GradedAlgebra
+DONE )abbrev domain CARTEN CartesianTensor
+DONE )abbrev package CARTEN2 CartesianTensorFunctions2
+DONE catdef.spad.pamphlet
+DONE )abbrev category ABELGRP AbelianGroup
+DONE )abbrev category ABELMON AbelianMonoid
+DONE )abbrev category ABELSG AbelianSemiGroup
+DONE )abbrev category ALGEBRA Algebra
+DONE )abbrev category BASTYPE BasicType
+DONE )abbrev category BMODULE BiModule
+DONE )abbrev category CABMON CancellationAbelianMonoid
+DONE )abbrev category CHARNZ CharacteristicNonZero
+DONE )abbrev category CHARZ CharacteristicZero
+DONE )abbrev category COMRING CommutativeRing
+DONE )abbrev category DIFRING DifferentialRing
+DONE )abbrev category DIFEXT DifferentialExtension
+DONE )abbrev category DIVRING DivisionRing
+DONE )abbrev category ENTIRER EntireRing
+DONE )abbrev category EUCDOM EuclideanDomain
+DONE )abbrev category FIELD Field
+DONE )abbrev category FINITE Finite
+DONE )abbrev category FLINEXP FullyLinearlyExplicitRingOver
+DONE )abbrev category GCDDOM GcdDomain
+DONE )abbrev category GROUP Group
+DONE )abbrev category INTDOM IntegralDomain
+DONE )abbrev category LMODULE LeftModule
+DONE )abbrev category LINEXP LinearlyExplicitRingOver
+DONE )abbrev category MODULE Module
+DONE )abbrev category MONOID Monoid
+DONE )abbrev category OAGROUP OrderedAbelianGroup
+DONE )abbrev category OAMON OrderedAbelianMonoid
+DONE )abbrev category OAMONS OrderedAbelianMonoidSup
+DONE )abbrev category OASGP OrderedAbelianSemiGroup
+DONE )abbrev category OCAMON OrderedCancellationAbelianMonoid
+DONE )abbrev category ORDFIN OrderedFinite
+DONE )abbrev category OINTDOM OrderedIntegralDomain
+DONE )abbrev category ORDMON OrderedMonoid
+DONE )abbrev category ORDRING OrderedRing
+DONE )abbrev category ORDSET OrderedSet
+DONE )abbrev category PDRING PartialDifferentialRing
+DONE )abbrev category PFECAT PolynomialFactorizationExplicit
+DONE )abbrev category PID PrincipalIdealDomain
+DONE )abbrev category RMODULE RightModule
+DONE )abbrev category RING Ring
+DONE )abbrev category RNG Rng
+DONE )abbrev category SGROUP SemiGroup
+DONE )abbrev category SETCAT SetCategory
+DONE )abbrev category STEP StepThrough
+DONE )abbrev category UFD UniqueFactorizationDomain
+DONE )abbrev category VSPACE VectorSpace
+DONE cden.spad.pamphlet
+DONE )abbrev package ICDEN InnerCommonDenominator
+DONE )abbrev package CDEN CommonDenominator
+DONE )abbrev package UPCDEN UnivariatePolynomialCommonDenominator
+DONE )abbrev package MCDEN MatrixCommonDenominator
+DONE clifford.spad.pamphlet
+DONE )abbrev domain QFORM QuadraticForm
+DONE )abbrev domain CLIF CliffordAlgebra
+DONE clip.spad.pamphlet
+DONE )abbrev package CLIP TwoDimensionalPlotClipping
+DONE cmplxrt.spad.pamphlet
+DONE )abbrev package CMPLXRT ComplexRootPackage
+DONE coerce.spad.pamphlet
+DONE )abbrev category TYPE Type
+DONE )abbrev category KOERCE CoercibleTo
+DONE )abbrev category KONVERT ConvertibleTo
+DONE )abbrev category RETRACT RetractableTo
+DONE color.spad.pamphlet
+DONE )abbrev domain COLOR Color
+DONE )abbrev domain PALETTE Palette
+combfunc.spad.pamphlet
+DONE )abbrev category COMBOPC CombinatorialOpsCategory
+)abbrev package COMBF CombinatorialFunction
+DONE )abbrev package FSPECF FunctionalSpecialFunction
+DONE )abbrev package SUMFS FunctionSpaceSum
+DONE combinat.spad.pamphlet
+DONE )abbrev package COMBINAT IntegerCombinatoricFunctions
+DONE complet.spad.pamphlet
+DONE )abbrev domain ORDCOMP OrderedCompletion
+DONE )abbrev package ORDCOMP2 OrderedCompletionFunctions2
+DONE )abbrev domain ONECOMP OnePointCompletion
+DONE )abbrev package ONECOMP2 OnePointCompletionFunctions2
+DONE )abbrev package INFINITY Infinity
+DONE constant.spad.pamphlet
+DONE )abbrev domain IAN InnerAlgebraicNumber
+DONE )abbrev domain AN AlgebraicNumber
+DONE contfrac.spad.pamphlet
+DONE )abbrev domain CONTFRAC ContinuedFraction
+DONE )abbrev package NCNTFRAC NumericContinuedFraction
+DONE cont.spad.pamphlet
+DONE )abbrev package ESCONT ExpertSystemContinuityPackage
+DONE )abbrev package ESCONT1 ExpertSystemContinuityPackage1
+DONE coordsys.spad.pamphlet
+DONE )abbrev package COORDSYS CoordinateSystems
+DONE cra.spad.pamphlet
+DONE )abbrev package CRAPACK CRApackage
+DONE crfp.spad.pamphlet
+DONE )abbrev package CRFP ComplexRootFindingPackage
+DONE curve.spad.pamphlet
+DONE )abbrev category FFCAT FunctionFieldCategory
+DONE )abbrev package MMAP MultipleMap
+DONE )abbrev package FFCAT2 FunctionFieldCategoryFunctions2
+DONE )abbrev package CHVAR ChangeOfVariable
+DONE )abbrev domain RADFF RadicalFunctionField
+DONE )abbrev domain ALGFF AlgebraicFunctionField
+DONE cycles.spad.pamphlet
+DONE )abbrev package CYCLES CycleIndicators
+DONE )abbrev package EVALCYC EvaluateCycleIndicators
+DONE cyclotom.spad.pamphlet
+DONE )abbrev package CYCLOTOM CyclotomicPolynomialPackage
+d01agents.spad.pamphlet
+DONE )abbrev domain INTFTBL IntegrationFunctionsTable
+)abbrev package D01AGNT d01AgentsPackage
+DONE d01Package.spad.pamphlet
+DONE )abbrev package INTPACK AnnaNumericalIntegrationPackage
+DONE d01routine.spad.pamphlet
+DONE )abbrev domain D01AJFA d01ajfAnnaType
+DONE )abbrev domain D01AKFA d01akfAnnaType
+DONE )abbrev domain D01AMFA d01amfAnnaType
+DONE )abbrev domain D01APFA d01apfAnnaType
+DONE )abbrev domain D01AQFA d01aqfAnnaType
+DONE )abbrev domain D01ALFA d01alfAnnaType
+DONE )abbrev domain D01ANFA d01anfAnnaType
+DONE )abbrev domain D01ASFA d01asfAnnaType
+DONE )abbrev domain D01GBFA d01gbfAnnaType
+DONE )abbrev domain D01FCFA d01fcfAnnaType
+DONE d01.spad.pamphlet
+DONE )abbrev package NAGD01 NagIntegrationPackage
+DONE d01transform.spad.pamphlet
+DONE )abbrev domain D01TRNS d01TransformFunctionType
+d01weights.spad.pamphlet
+)abbrev package D01WGTS d01WeightsPackage
+d02agents.spad.pamphlet
+DONE )abbrev domain ODEIFTBL ODEIntensityFunctionsTable
+)abbrev package D02AGNT d02AgentsPackage
+DONE d02Package.spad.pamphlet
+DONE )abbrev package ODEPACK AnnaOrdinaryDifferentialEquationPackage
+DONE d02routine.spad.pamphlet
+DONE )abbrev domain D02BBFA d02bbfAnnaType
+DONE )abbrev domain D02BHFA d02bhfAnnaType
+DONE )abbrev domain D02CJFA d02cjfAnnaType
+DONE )abbrev domain D02EJFA d02ejfAnnaType
+DONE d02.spad.pamphlet
+DONE )abbrev package NAGD02 NagOrdinaryDifferentialEquationsPackage
+DONE d03agents.spad.pamphlet
+DONE )abbrev package D03AGNT d03AgentsPackage
+DONE d03Package.spad.pamphlet
+DONE )abbrev package PDEPACK AnnaPartialDifferentialEquationPackage
+DONE d03routine.spad.pamphlet
+DONE )abbrev domain D03EEFA d03eefAnnaType
+DONE )abbrev domain D03FAFA d03fafAnnaType
+DONE d03.spad.pamphlet
+DONE )abbrev package NAGD03 NagPartialDifferentialEquationsPackage
+DONE ddfact.spad.pamphlet
+DONE )abbrev package DDFACT DistinctDegreeFactorize
+DONE defaults.spad.pamphlet
+DONE )abbrev package REPSQ RepeatedSquaring
+DONE )abbrev package REPDB RepeatedDoubling
+DONE )abbrev package FLASORT FiniteLinearAggregateSort
+DONE defintef.spad.pamphlet
+DONE )abbrev package DEFINTEF ElementaryFunctionDefiniteIntegration
+DONE defintrf.spad.pamphlet
+DONE )abbrev package DFINTTLS DefiniteIntegrationTools
+DONE )abbrev package DEFINTRF RationalFunctionDefiniteIntegration
+DONE degred.spad.pamphlet
+DONE )abbrev package DEGRED DegreeReductionPackage
+DONE derham.spad.pamphlet
+DONE )abbrev category LALG LeftAlgebra
+DONE )abbrev domain EAB ExtAlgBasis
+DONE )abbrev domain ANTISYM AntiSymm
+DONE )abbrev domain DERHAM DeRhamComplex
+DONE dhmatrix.spad.pamphlet
+DONE )abbrev domain DHMATRIX DenavitHartenbergMatrix
+DONE divisor.spad.pamphlet
+DONE )abbrev domain FRIDEAL FractionalIdeal
+DONE )abbrev package FRIDEAL2 FractionalIdealFunctions2
+DONE )abbrev package MHROWRED ModularHermitianRowReduction
+DONE )abbrev domain FRMOD FramedModule
+DONE )abbrev category FDIVCAT FiniteDivisorCategory
+DONE )abbrev domain HELLFDIV HyperellipticFiniteDivisor
+DONE )abbrev domain FDIV FiniteDivisor
+DONE )abbrev package FDIV2 FiniteDivisorFunctions2
+DONE dpolcat.spad.pamphlet
+DONE )abbrev category DVARCAT DifferentialVariableCategory
+DONE )abbrev domain ODVAR OrderlyDifferentialVariable
+DONE )abbrev domain SDVAR SequentialDifferentialVariable
+DONE )abbrev category DPOLCAT DifferentialPolynomialCategory
+DONE )abbrev domain DSMP DifferentialSparseMultivariatePolynomial
+DONE )abbrev domain ODPOL OrderlyDifferentialPolynomial
+DONE )abbrev domain SDPOL SequentialDifferentialPolynomial
+DONE drawopt.spad.pamphlet
+DONE )abbrev domain DROPT DrawOption
+DONE )abbrev package DROPT1 DrawOptionFunctions1
+DONE )abbrev package DROPT0 DrawOptionFunctions0
+DONE drawpak.spad.pamphlet
+DONE )abbrev package DRAWCX DrawComplex
+DONE draw.spad.pamphlet
+DONE )abbrev package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions
+DONE )abbrev package DRAW TopLevelDrawFunctions
+DONE )abbrev package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves
+DONE )abbrev package DRAWPT TopLevelDrawFunctionsForPoints
+DONE e01.spad.pamphlet
+DONE )abbrev package NAGE01 NagInterpolationPackage
+DONE e02.spad.pamphlet
+DONE )abbrev package NAGE02 NagFittingPackage
+DONE e04agents.spad.pamphlet
+DONE )abbrev package E04AGNT e04AgentsPackage
+DONE e04Package.spad.pamphlet
+DONE )abbrev package OPTPACK AnnaNumericalOptimizationPackage
+DONE e04routine.spad.pamphlet
+DONE )abbrev domain E04DGFA e04dgfAnnaType
+DONE )abbrev domain E04FDFA e04fdfAnnaType
+DONE )abbrev domain E04GCFA e04gcfAnnaType
+DONE )abbrev domain E04JAFA e04jafAnnaType
+DONE )abbrev domain E04MBFA e04mbfAnnaType
+DONE )abbrev domain E04NAFA e04nafAnnaType
+DONE )abbrev domain E04UCFA e04ucfAnnaType
+DONE e04.spad.pamphlet
+DONE )abbrev package NAGE04 NagOptimisationPackage
+DONE efstruc.spad.pamphlet
+DONE )abbrev package SYMFUNC SymmetricFunctions
+DONE )abbrev package TANEXP TangentExpansions
+DONE )abbrev package EFSTRUC ElementaryFunctionStructurePackage
+DONE )abbrev package ITRIGMNP InnerTrigonometricManipulations
+DONE )abbrev package TRIGMNIP TrigonometricManipulations
+DONE )abbrev package CTRIGMNP ComplexTrigonometricManipulations
+DONE efuls.spad.pamphlet
+DONE )abbrev package EFULS ElementaryFunctionsUnivariateLaurentSeries
+DONE efupxs.spad.pamphlet
+DONE )abbrev package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries
+DONE eigen.spad.pamphlet
+DONE )abbrev package EP EigenPackage
+DONE )abbrev package CHARPOL CharacteristicPolynomialPackage
+DONE elemntry.spad.pamphlet
+DONE )abbrev package EF ElementaryFunction
+DONE elfuts.spad.pamphlet
+DONE )abbrev package ELFUTS EllipticFunctionsUnivariateTaylorSeries
+DONE equation1.spad.pamphlet
+DONE )abbrev category IEVALAB InnerEvalable
+DONE )abbrev category EVALAB Evalable
+DONE equation2.spad.pamphlet
+DONE )abbrev domain EQ Equation
+DONE )abbrev package EQ2 EquationFunctions2
+DONE )abbrev category FEVALAB FullyEvalableOver
+DONE error.spad.pamphlet
+DONE )abbrev package ERROR ErrorFunctions
+DONE expexpan.spad.pamphlet
+DONE )abbrev domain EXPUPXS ExponentialOfUnivariatePuiseuxSeries
+DONE )abbrev domain UPXSSING UnivariatePuiseuxSeriesWithExponentialSingularity
+DONE )abbrev domain EXPEXPAN ExponentialExpansion
+DONE expr2ups.spad.pamphlet
+DONE )abbrev package EXPR2UPS ExpressionToUnivariatePowerSeries
+DONE exprode.spad.pamphlet
+DONE )abbrev package EXPRODE ExpressionSpaceODESolver
+DONE expr.spad.pamphlet
+DONE )abbrev domain EXPR Expression
+DONE )abbrev package PAN2EXPR PolynomialAN2Expression
+DONE )abbrev package EXPR2 ExpressionFunctions2
+DONE )abbrev package PMPREDFS FunctionSpaceAttachPredicates
+DONE )abbrev package PMASSFS FunctionSpaceAssertions
+DONE )abbrev package PMPRED AttachPredicates
+DONE )abbrev package PMASS PatternMatchAssertions
+DONE )abbrev domain HACKPI Pi
+DONE )abbrev package PICOERCE PiCoercions
+DONE f01.spad.pamphlet
+DONE )abbrev package NAGF01 NagMatrixOperationsPackage
+DONE f02.spad.pamphlet
+DONE )abbrev package NAGF02 NagEigenPackage
+DONE f04.spad.pamphlet
+DONE )abbrev package NAGF04 NagLinearEquationSolvingPackage
+DONE f07.spad.pamphlet
+DONE )abbrev package NAGF07 NagLapack
+DONE facutil.spad.pamphlet
+DONE )abbrev package FACUTIL FactoringUtilities
+DONE )abbrev package PUSHVAR PushVariables
+DONE ffcat.spad.pamphlet
+DONE )abbrev category FPC FieldOfPrimeCharacteristic
+DONE )abbrev category XF ExtensionField
+DONE )abbrev category FAXF FiniteAlgebraicExtensionField
+DONE )abbrev package DLP DiscreteLogarithmPackage
+DONE )abbrev category FFIELDC FiniteFieldCategory
+DONE )abbrev package FFSLPE FiniteFieldSolveLinearPolynomialEquation
+DONE ffcg.spad.pamphlet
+DONE )abbrev domain FFCGP FiniteFieldCyclicGroupExtensionByPolynomial
+DONE )abbrev domain FFCGX FiniteFieldCyclicGroupExtension
+DONE )abbrev domain FFCG FiniteFieldCyclicGroup
+DONE fff.spad.pamphlet
+DONE )abbrev package FFF FiniteFieldFunctions
+DONE ffhom.spad.pamphlet
+DONE )abbrev package FFHOM FiniteFieldHomomorphisms
+ffnb.spad.pamphlet
+)abbrev package INBFF InnerNormalBasisFieldFunctions
+DONE )abbrev domain FFNBP FiniteFieldNormalBasisExtensionByPolynomial
+DONE )abbrev domain FFNBX FiniteFieldNormalBasisExtension
+DONE )abbrev domain FFNB FiniteFieldNormalBasis
+DONE ffpoly2.spad.pamphlet
+DONE )abbrev package FFPOLY2 FiniteFieldPolynomialPackage2
+DONE ffpoly.spad.pamphlet
+DONE )abbrev package FFPOLY FiniteFieldPolynomialPackage
+DONE ffp.spad.pamphlet
+DONE )abbrev domain FFP FiniteFieldExtensionByPolynomial
+DONE )abbrev domain FFX FiniteFieldExtension
+DONE )abbrev domain IFF InnerFiniteField
+DONE )abbrev domain FF FiniteField
+ffrac.as.pamphlet
+DONE ffx.spad.pamphlet
+DONE )abbrev package IRREDFFX IrredPolyOverFiniteField
+DONE files.spad.pamphlet
+DONE )abbrev category FILECAT FileCategory
+DONE )abbrev domain FILE File
+DONE )abbrev domain TEXTFILE TextFile
+DONE )abbrev domain BINFILE BinaryFile
+DONE )abbrev domain KAFILE KeyedAccessFile
+DONE )abbrev domain LIB Library
+DONE float.spad.pamphlet
+DONE )abbrev domain FLOAT Float
+DONE fmod.spad.pamphlet
+DONE )abbrev domain ZMOD IntegerMod
+DONE fname.spad.pamphlet
+DONE )abbrev category FNCAT FileNameCategory
+DONE )abbrev domain FNAME FileName
+DONE fnla.spad.pamphlet
+DONE )abbrev domain OSI OrdSetInts
+DONE )abbrev domain COMM Commutator
+DONE )abbrev package HB HallBasis
+DONE )abbrev domain FNLA FreeNilpotentLie
+DONE formula.spad.pamphlet
+DONE )abbrev domain FORMULA ScriptFormulaFormat
+DONE )abbrev package FORMULA1 ScriptFormulaFormat1
+DONE fortcat.spad.pamphlet
+DONE )abbrev category FORTFN FortranFunctionCategory
+DONE )abbrev category FMC FortranMatrixCategory
+DONE )abbrev category FORTCAT FortranProgramCategory
+DONE )abbrev category FVC FortranVectorCategory
+DONE )abbrev category FMTC FortranMachineTypeCategory
+DONE )abbrev category FMFUN FortranMatrixFunctionCategory
+DONE )abbrev category FVFUN FortranVectorFunctionCategory
+DONE fortmac.spad.pamphlet
+DONE )abbrev domain MINT MachineInteger
+DONE )abbrev domain MFLOAT MachineFloat
+DONE )abbrev domain MCMPLX MachineComplex
+DONE fortpak.spad.pamphlet
+DONE )abbrev package FCPAK1 FortranCodePackage1
+DONE )abbrev package NAGSP NAGLinkSupportPackage
+DONE )abbrev package FORT FortranPackage
+DONE )abbrev package FOP FortranOutputStackPackage
+DONE )abbrev package TEMUTL TemplateUtilities
+DONE )abbrev package MCALCFN MultiVariableCalculusFunctions
+DONE fortran.spad.pamphlet
+DONE )abbrev domain RESULT Result
+DONE )abbrev domain FC FortranCode
+DONE )abbrev domain FORTRAN FortranProgram
+DONE )abbrev domain M3D ThreeDimensionalMatrix
+DONE )abbrev domain SFORT SimpleFortranProgram
+DONE )abbrev domain SWITCH Switch
+DONE )abbrev domain FTEM FortranTemplate
+DONE )abbrev domain FEXPR FortranExpression
+DONE forttyp.spad.pamphlet
+DONE )abbrev domain FST FortranScalarType
+DONE )abbrev domain FT FortranType
+DONE )abbrev domain SYMTAB SymbolTable
+DONE )abbrev domain SYMS TheSymbolTable
+DONE fourier.spad.pamphlet
+DONE )abbrev domain FCOMP FourierComponent
+DONE )abbrev domain FSERIES FourierSeries
+DONE fparfrac.spad.pamphlet
+DONE )abbrev domain FPARFRAC FullPartialFractionExpansion
+DONE fraction.spad.pamphlet
+DONE )abbrev domain LO Localize
+DONE )abbrev domain LA LocalAlgebra
+DONE )abbrev category QFCAT QuotientFieldCategory
+DONE )abbrev package QFCAT2 QuotientFieldCategoryFunctions2
+DONE )abbrev domain FRAC Fraction
+DONE )abbrev package LPEFRAC LinearPolynomialEquationByFractions
+DONE )abbrev package FRAC2 FractionFunctions2
+DONE free.spad.pamphlet
+DONE )abbrev domain LMOPS ListMonoidOps
+DONE )abbrev domain FMONOID FreeMonoid
+DONE )abbrev domain FGROUP FreeGroup
+DONE )abbrev category FAMONC FreeAbelianMonoidCategory
+DONE )abbrev domain IFAMON InnerFreeAbelianMonoid
+DONE )abbrev domain FAMONOID FreeAbelianMonoid
+DONE )abbrev domain FAGROUP FreeAbelianGroup
+DONE fr.spad.pamphlet
+DONE )abbrev domain FR Factored
+DONE )abbrev package FRUTIL FactoredFunctionUtilities
+DONE )abbrev package FR2 FactoredFunctions2
+DONE fs2expxp.spad.pamphlet
+DONE )abbrev package FS2EXPXP FunctionSpaceToExponentialExpansion
+DONE fs2ups.spad.pamphlet
+DONE )abbrev package FS2UPS FunctionSpaceToUnivariatePowerSeries
+DONE fspace.spad.pamphlet
+DONE )abbrev category ES ExpressionSpace
+DONE )abbrev package ES1 ExpressionSpaceFunctions1
+DONE )abbrev package ES2 ExpressionSpaceFunctions2
+DONE )abbrev category FS FunctionSpace
+DONE )abbrev package FS2 FunctionSpaceFunctions2
+DONE funcpkgs.spad.pamphlet
+DONE )abbrev package FSUPFACT FunctionSpaceUnivariatePolynomialFactor
+DONE functions.spad.pamphlet
+DONE )abbrev domain BFUNCT BasicFunctions
+DONE galfact.spad.pamphlet
+DONE )abbrev package GALFACT GaloisGroupFactorizer
+DONE galfactu.spad.pamphlet
+DONE )abbrev package GALFACTU GaloisGroupFactorizationUtilities
+DONE galpolyu.spad.pamphlet
+DONE )abbrev package GALPOLYU GaloisGroupPolynomialUtilities
+DONE galutil.spad.pamphlet
+DONE )abbrev package GALUTIL GaloisGroupUtilities
+DONE gaussfac.spad.pamphlet
+DONE )abbrev package GAUSSFAC GaussianFactorizationPackage
+DONE gaussian.spad.pamphlet
+DONE )abbrev category COMPCAT ComplexCategory
+DONE )abbrev package COMPLPAT ComplexPattern
+DONE )abbrev package CPMATCH ComplexPatternMatch
+DONE )abbrev domain COMPLEX Complex
+DONE )abbrev package COMPLEX2 ComplexFunctions2
+DONE )abbrev package COMPFACT ComplexFactorization
+DONE )abbrev package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation
+DONE gbeuclid.spad.pamphlet
+DONE )abbrev package GBEUCLID EuclideanGroebnerBasisPackage
+DONE gbintern.spad.pamphlet
+DONE )abbrev package GBINTERN GroebnerInternalPackage
+DONE gb.spad.pamphlet
+DONE )abbrev package GB GroebnerPackage
+DONE gdirprod.spad.pamphlet
+DONE )abbrev package ORDFUNS OrderingFunctions
+DONE )abbrev domain ODP OrderedDirectProduct
+DONE )abbrev domain HDP HomogeneousDirectProduct
+DONE )abbrev domain SHDP SplitHomogeneousDirectProduct
+DONE gdpoly.spad.pamphlet
+DONE )abbrev domain GDMP GeneralDistributedMultivariatePolynomial
+DONE )abbrev domain DMP DistributedMultivariatePolynomial
+DONE )abbrev domain HDMP HomogeneousDistributedMultivariatePolynomial
+DONE geneez.spad.pamphlet
+DONE )abbrev package GENEEZ GenExEuclid
+DONE generic.spad.pamphlet
+DONE )abbrev domain GCNAALG GenericNonAssociativeAlgebra
+DONE )abbrev package CVMP CoerceVectorMatrixPackage
+DONE genufact.spad.pamphlet
+DONE )abbrev package GENUFACT GenUFactorize
+DONE genups.spad.pamphlet
+DONE )abbrev package GENUPS GenerateUnivariatePowerSeries
+DONE ghensel.spad.pamphlet
+DONE )abbrev package GHENSEL GeneralHenselPackage
+DONE gpgcd.spad.pamphlet
+DONE )abbrev package GENPGCD GeneralPolynomialGcdPackage
+DONE gpol.spad.pamphlet
+DONE )abbrev domain LAUPOL LaurentPolynomial
+DONE grdef.spad.pamphlet
+DONE )abbrev package GRDEF GraphicsDefaults
+DONE groebf.spad.pamphlet
+DONE )abbrev package GBF GroebnerFactorizationPackage
+DONE groebsol.spad.pamphlet
+DONE )abbrev package GROEBSOL GroebnerSolve
+DONE gseries.spad.pamphlet
+DONE )abbrev domain GSERIES GeneralUnivariatePowerSeries
+herm.as.pamphlet
+DONE ideal.spad.pamphlet
+DONE )abbrev domain IDEAL PolynomialIdeals
+DONE idecomp.spad.pamphlet
+DONE )abbrev package IDECOMP IdealDecompositionPackage
+DONE indexedp.spad.pamphlet
+DONE )abbrev category IDPC IndexedDirectProductCategory
+DONE )abbrev domain IDPO IndexedDirectProductObject
+DONE )abbrev domain IDPAM IndexedDirectProductAbelianMonoid
+DONE )abbrev domain IDPOAM IndexedDirectProductOrderedAbelianMonoid
+DONE )abbrev domain IDPOAMS IndexedDirectProductOrderedAbelianMonoidSup
+DONE )abbrev domain IDPAG IndexedDirectProductAbelianGroup
+DONE infprod.spad.pamphlet
+DONE )abbrev package STINPROD StreamInfiniteProduct
+DONE )abbrev package INFPROD0 InfiniteProductCharacteristicZero
+DONE )abbrev package INPRODPF InfiniteProductPrimeField
+DONE )abbrev package INPRODFF InfiniteProductFiniteField
+DONE intaf.spad.pamphlet
+DONE )abbrev package INTG0 GenusZeroIntegration
+DONE )abbrev package INTPAF PureAlgebraicIntegration
+DONE )abbrev package INTAF AlgebraicIntegration
+DONE intalg.spad.pamphlet
+DONE )abbrev package DBLRESP DoubleResultantPackage
+DONE )abbrev package INTHERAL AlgebraicHermiteIntegration
+DONE )abbrev package INTALG AlgebraicIntegrate
+DONE intaux.spad.pamphlet
+DONE )abbrev domain IR IntegrationResult
+DONE )abbrev package IR2 IntegrationResultFunctions2
+DONE intclos.spad.pamphlet
+DONE )abbrev package TRIMAT TriangularMatrixOperations
+DONE )abbrev package IBATOOL IntegralBasisTools
+DONE )abbrev package FFINTBAS FunctionFieldIntegralBasis
+DONE )abbrev package WFFINTBS WildFunctionFieldIntegralBasis
+DONE )abbrev package NFINTBAS NumberFieldIntegralBasis
+DONE intef.spad.pamphlet
+DONE )abbrev package INTEF ElementaryIntegration
+DONE integer.spad.pamphlet
+DONE )abbrev package INTSLPE IntegerSolveLinearPolynomialEquation
+DONE )abbrev domain INT Integer
+DONE )abbrev domain NNI NonNegativeInteger
+DONE )abbrev domain PI PositiveInteger
+DONE )abbrev domain ROMAN RomanNumeral
+DONE integrat.spad.pamphlet
+DONE )abbrev package FSCINT FunctionSpaceComplexIntegration
+DONE )abbrev package FSINT FunctionSpaceIntegration
+interval.as.pamphlet
+DONE intfact.spad.pamphlet
+DONE )abbrev package PRIMES IntegerPrimesPackage
+DONE )abbrev package IROOT IntegerRoots
+DONE )abbrev package INTFACT IntegerFactorizationPackage
+DONE intpm.spad.pamphlet
+DONE )abbrev package INTPM PatternMatchIntegration
+DONE intrf.spad.pamphlet
+DONE )abbrev package SUBRESP SubResultantPackage
+DONE )abbrev package MONOTOOL MonomialExtensionTools
+DONE )abbrev package INTHERTR TranscendentalHermiteIntegration
+DONE )abbrev package INTTR TranscendentalIntegration
+DONE )abbrev package INTRAT RationalIntegration
+DONE )abbrev package INTRF RationalFunctionIntegration
+invnode.as.pamphlet
+invrender.as.pamphlet
+invtypes.as.pamphlet
+invutils.as.pamphlet
+DONE irexpand.spad.pamphlet
+DONE )abbrev package IR2F IntegrationResultToFunction
+DONE )abbrev package IRRF2F IntegrationResultRFToFunction
+DONE irsn.spad.pamphlet
+DONE )abbrev package IRSN IrrRepSymNatPackage
+DONE ituple.spad.pamphlet
+DONE )abbrev domain ITUPLE InfiniteTuple
+DONE )abbrev package ITFUN2 InfiniteTupleFunctions2
+DONE )abbrev package ITFUN3 InfiniteTupleFunctions3
+iviews.as.pamphlet
+DONE kl.spad.pamphlet
+DONE )abbrev category CACHSET CachableSet
+DONE )abbrev package SCACHE SortedCache
+DONE )abbrev domain MKCHSET MakeCachableSet
+DONE )abbrev domain KERNEL Kernel
+DONE )abbrev package KERNEL2 KernelFunctions2
+DONE kovacic.spad.pamphlet
+DONE )abbrev package KOVACIC Kovacic
+DONE laplace.spad.pamphlet
+DONE )abbrev package LAPLACE LaplaceTransform
+DONE )abbrev package INVLAPLA InverseLaplaceTransform
+DONE laurent.spad.pamphlet
+DONE )abbrev category ULSCCAT UnivariateLaurentSeriesConstructorCategory
+DONE )abbrev domain ULSCONS UnivariateLaurentSeriesConstructor
+DONE )abbrev domain ULS UnivariateLaurentSeries
+DONE )abbrev package ULS2 UnivariateLaurentSeriesFunctions2
+DONE leadcdet.spad.pamphlet
+DONE )abbrev package LEADCDET LeadingCoefDetermination
+DONE lie.spad.pamphlet
+DONE )abbrev domain LIE AssociatedLieAlgebra
+DONE )abbrev domain JORDAN AssociatedJordanAlgebra
+DONE )abbrev domain LSQM LieSquareMatrix
+limitps.spad.pamphlet
+DONE )abbrev package LIMITPS PowerSeriesLimitPackage
+)abbrev package SIGNEF ElementaryFunctionSign
+DONE lindep.spad.pamphlet
+DONE )abbrev package LINDEP LinearDependence
+DONE )abbrev package ZLINDEP IntegerLinearDependence
+DONE lingrob.spad.pamphlet
+DONE )abbrev package LGROBP LinGroebnerPackage
+DONE liouv.spad.pamphlet
+DONE )abbrev package LF LiouvillianFunction
+DONE listgcd.spad.pamphlet
+DONE )abbrev package HEUGCD HeuGcd
+DONE list.spad.pamphlet
+DONE )abbrev domain ILIST IndexedList
+DONE )abbrev domain LIST List
+DONE )abbrev package LIST2 ListFunctions2
+DONE )abbrev package LIST3 ListFunctions3
+DONE )abbrev package LIST2MAP ListToMap
+DONE )abbrev domain ALIST AssociationList
+DONE lmdict.spad.pamphlet
+DONE )abbrev domain LMDICT ListMultiDictionary
+DONE lodof.spad.pamphlet
+DONE )abbrev domain SETMN SetOfMIntegersInOneToN
+DONE )abbrev package PREASSOC PrecomputedAssociatedEquations
+DONE )abbrev package ASSOCEQ AssociatedEquations
+DONE )abbrev package LODOF LinearOrdinaryDifferentialOperatorFactorizer
+DONE lodop.spad.pamphlet
+DONE )abbrev category MLO MonogenicLinearOperator
+DONE )abbrev domain OMLO OppositeMonogenicLinearOperator
+DONE )abbrev package NCODIV NonCommutativeOperatorDivision
+DONE )abbrev domain ODR OrdinaryDifferentialRing
+DONE )abbrev domain DPMO DirectProductModule
+DONE )abbrev domain DPMM DirectProductMatrixModule
+lodo.spad.pamphlet
+DONE )abbrev category LODOCAT LinearOrdinaryDifferentialOperatorCategory
+DONE )abbrev package LODOOPS LinearOrdinaryDifferentialOperatorsOps
+)abbrev domain LODO LinearOrdinaryDifferentialOperator
+)abbrev domain LODO1 LinearOrdinaryDifferentialOperator1
+DONE )abbrev domain LODO2 LinearOrdinaryDifferentialOperator2
+DONE manip.spad.pamphlet
+DONE )abbrev package FACTFUNC FactoredFunctions
+DONE )abbrev package POLYROOT PolynomialRoots
+DONE )abbrev package ALGMANIP AlgebraicManipulations
+DONE )abbrev package SIMPAN SimplifyAlgebraicNumberConvertPackage
+DONE )abbrev package TRMANIP TranscendentalManipulations
+DONE mappkg.spad.pamphlet
+DONE )abbrev package MAPHACK1 MappingPackageInternalHacks1
+DONE )abbrev package MAPHACK2 MappingPackageInternalHacks2
+DONE )abbrev package MAPHACK3 MappingPackageInternalHacks3
+DONE )abbrev package MAPPKG1 MappingPackage1
+DONE )abbrev package MAPPKG2 MappingPackage2
+DONE )abbrev package MAPPKG3 MappingPackage3
+DONE matcat.spad.pamphlet
+DONE )abbrev category MATCAT MatrixCategory
+DONE )abbrev category RMATCAT RectangularMatrixCategory
+DONE )abbrev category SMATCAT SquareMatrixCategory
+DONE matfuns.spad.pamphlet
+DONE )abbrev package IMATLIN InnerMatrixLinearAlgebraFunctions
+DONE )abbrev package MATCAT2 MatrixCategoryFunctions2
+DONE )abbrev package RMCAT2 RectangularMatrixCategoryFunctions2
+DONE )abbrev package IMATQF InnerMatrixQuotientFieldFunctions
+DONE )abbrev package MATLIN MatrixLinearAlgebraFunctions
+DONE matrix.spad.pamphlet
+DONE )abbrev domain IMATRIX IndexedMatrix
+DONE )abbrev domain MATRIX Matrix
+DONE )abbrev domain RMATRIX RectangularMatrix
+DONE )abbrev domain SQMATRIX SquareMatrix
+DONE matstor.spad.pamphlet
+DONE )abbrev package MATSTOR StorageEfficientMatrixOperations
+DONE mesh.spad.pamphlet
+DONE )abbrev package MESH MeshCreationRoutinesForThreeDimensions
+DONE mfinfact.spad.pamphlet
+DONE )abbrev package MFINFACT MultFiniteFactorize
+DONE misc.spad.pamphlet
+DONE )abbrev domain SAOS SingletonAsOrderedSet
+DONE mkfunc.spad.pamphlet
+DONE )abbrev domain INFORM InputForm
+DONE )abbrev package INFORM1 InputFormFunctions1
+DONE )abbrev package MKFUNC MakeFunction
+DONE )abbrev package MKUCFUNC MakeUnaryCompiledFunction
+DONE )abbrev package MKBCFUNC MakeBinaryCompiledFunction
+DONE )abbrev package MKFLCFN MakeFloatCompiledFunction
+DONE mkrecord.spad.pamphlet
+DONE )abbrev package MKRECORD MakeRecord
+DONE mlift.spad.jhd.pamphlet
+DONE )abbrev package MLIFT MultivariateLifting
+DONE mlift.spad.pamphlet
+DONE )abbrev package MLIFT MultivariateLifting
+DONE moddfact.spad.pamphlet
+DONE )abbrev package MDDFACT ModularDistinctDegreeFactorizer
+DONE modgcd.spad.pamphlet
+DONE )abbrev package INMODGCD InnerModularGcd
+DONE modmonom.spad.pamphlet
+DONE )abbrev domain MODMONOM ModuleMonomial
+DONE )abbrev domain GMODPOL GeneralModulePolynomial
+DONE modmon.spad.pamphlet
+DONE )abbrev domain MODMON ModMonic
+DONE modring.spad.pamphlet
+DONE )abbrev domain MODRING ModularRing
+DONE )abbrev domain EMR EuclideanModularRing
+DONE )abbrev domain MODFIELD ModularField
+DONE moebius.spad.pamphlet
+DONE )abbrev domain MOEBIUS MoebiusTransform
+DONE mring.spad.pamphlet
+DONE )abbrev domain MRING MonoidRing
+DONE )abbrev package MRF2 MonoidRingFunctions2
+DONE mset.spad.pamphlet
+DONE )abbrev domain MSET Multiset
+DONE mts.spad.pamphlet
+DONE )abbrev domain SMTS SparseMultivariateTaylorSeries
+DONE )abbrev domain TS TaylorSeries
+DONE multfact.spad.pamphlet
+DONE )abbrev package INNMFACT InnerMultFact
+DONE )abbrev package MULTFACT MultivariateFactorize
+DONE )abbrev package ALGMFACT AlgebraicMultFact
+DONE multpoly.spad.pamphlet
+DONE )abbrev domain POLY Polynomial
+DONE )abbrev package POLY2 PolynomialFunctions2
+DONE )abbrev domain MPOLY MultivariatePolynomial
+DONE )abbrev domain SMP SparseMultivariatePolynomial
+DONE )abbrev domain INDE IndexedExponents
+DONE multsqfr.spad.pamphlet
+DONE )abbrev package MULTSQFR MultivariateSquareFree
+DONE naalgc.spad.pamphlet
+DONE )abbrev category MONAD Monad
+DONE )abbrev category MONADWU MonadWithUnit
+DONE )abbrev category NARNG NonAssociativeRng
+DONE )abbrev category NASRING NonAssociativeRing
+DONE )abbrev category NAALG NonAssociativeAlgebra
+DONE )abbrev category FINAALG FiniteRankNonAssociativeAlgebra
+DONE )abbrev category FRNAALG FramedNonAssociativeAlgebra
+DONE naalg.spad.pamphlet
+DONE )abbrev domain ALGSC AlgebraGivenByStructuralConstants
+DONE )abbrev package SCPKG StructuralConstantsPackage
+DONE )abbrev package ALGPKG AlgebraPackage
+DONE )abbrev package FRNAAF2 FramedNonAssociativeAlgebraFunctions2
+ndftip.as.pamphlet
+nepip.as.pamphlet
+DONE newdata.spad.pamphlet
+DONE )abbrev package IPRNTPK InternalPrintPackage
+DONE )abbrev package TBCMPPK TabulatedComputationPackage
+DONE )abbrev domain SPLNODE SplittingNode
+DONE )abbrev domain SPLTREE SplittingTree
+DONE newpoint.spad.pamphlet
+DONE )abbrev category PTCAT PointCategory
+DONE )abbrev domain POINT Point
+DONE )abbrev domain COMPPROP SubSpaceComponentProperty
+DONE )abbrev domain SUBSPACE SubSpace
+DONE )abbrev package PTPACK PointPackage
+DONE )abbrev package PTFUNC2 PointFunctions2
+DONE newpoly.spad.pamphlet
+DONE )abbrev domain NSUP NewSparseUnivariatePolynomial
+DONE )abbrev package NSUP2 NewSparseUnivariatePolynomialFunctions2
+DONE )abbrev category RPOLCAT RecursivePolynomialCategory
+DONE )abbrev domain NSMP NewSparseMultivariatePolynomial
+DONE nlinsol.spad.pamphlet
+DONE )abbrev package RETSOL RetractSolvePackage
+DONE )abbrev package NLINSOL NonLinearSolvePackage
+DONE nlode.spad.pamphlet
+DONE )abbrev package NODE1 NonLinearFirstOrderODESolver
+noptip.as.pamphlet
+DONE npcoef.spad.pamphlet
+DONE )abbrev package NPCOEF NPCoef
+nqip.as.pamphlet
+nrc.as.pamphlet
+nregset.spad.pamphlet
+)abbrev category NTSCAT NormalizedTriangularSetCategory
+)abbrev package NORMPK NormalizationPackage
+nsfip.as.pamphlet
+nsregset.spad.pamphlet
+)abbrev category SNTSCAT SquareFreeNormalizedTriangularSetCategory
+)abbrev package LAZM3PK LazardSetSolvingPackage
+DONE numeigen.spad.pamphlet
+DONE )abbrev package INEP InnerNumericEigenPackage
+DONE )abbrev package NREP NumericRealEigenPackage
+DONE )abbrev package NCEP NumericComplexEigenPackage
+DONE numeric.spad.pamphlet
+DONE )abbrev package NUMERIC Numeric
+DONE )abbrev package DRAWHACK DrawNumericHack
+DONE numode.spad.pamphlet
+DONE )abbrev package NUMODE NumericalOrdinaryDifferentialEquations
+DONE numquad.spad.pamphlet
+DONE )abbrev package NUMQUAD NumericalQuadrature
+DONE numsolve.spad.pamphlet
+DONE )abbrev package INFSP InnerNumericFloatSolvePackage
+DONE )abbrev package FLOATRP FloatingRealPackage
+DONE )abbrev package FLOATCP FloatingComplexPackage
+DONE numtheor.spad.pamphlet
+DONE )abbrev package INTHEORY IntegerNumberTheoryFunctions
+DONE )abbrev package PNTHEORY PolynomialNumberTheoryFunctions
+DONE oct.spad.pamphlet
+DONE )abbrev category OC OctonionCategory
+DONE )abbrev domain OCT Octonion
+DONE )abbrev package OCTCT2 OctonionCategoryFunctions2
+DONE odealg.spad.pamphlet
+DONE )abbrev package ODESYS SystemODESolver
+DONE )abbrev package ODERED ReduceLODE
+DONE )abbrev package ODEPAL PureAlgebraicLODE
+odeef.spad.pamphlet
+DONE )abbrev package REDORDER ReductionOfOrder
+DONE )abbrev package LODEEF ElementaryFunctionLODESolver
+)abbrev package ODEEF ElementaryFunctionODESolver
+oderf.spad.pamphlet
+DONE )abbrev package BALFACT BalancedFactorisation
+DONE )abbrev package BOUNDZRO BoundIntegerRoots
+DONE )abbrev package ODEPRIM PrimitiveRatDE
+DONE )abbrev package UTSODETL UTSodetools
+DONE )abbrev package ODERAT RationalLODE
+DONE )abbrev package ODETOOLS ODETools
+DONE )abbrev package ODEINT ODEIntegration
+DONE )abbrev package ODECONST ConstantLODE
+DONE omcat.spad.pamphlet
+DONE )abbrev category OM OpenMath
+DONE omdev.spad.pamphlet
+DONE )abbrev domain OMENC OpenMathEncoding
+DONE )abbrev domain OMDEV OpenMathDevice
+DONE )abbrev domain OMCONN OpenMathConnection
+DONE )abbrev package OMPKG OpenMathPackage
+DONE omerror.spad.pamphlet
+DONE )abbrev domain OMERRK OpenMathErrorKind
+DONE )abbrev domain OMERR OpenMathError
+DONE omserver.spad.pamphlet
+DONE )abbrev package OMSERVER OpenMathServerPackage
+DONE opalg.spad.pamphlet
+DONE )abbrev domain MODOP ModuleOperator
+DONE )abbrev domain OP Operator
+DONE openmath.spad.pamphlet
+DONE )abbrev package OMEXPR ExpressionToOpenMath
+DONE op.spad.pamphlet
+DONE )abbrev domain BOP BasicOperator
+DONE )abbrev package BOP1 BasicOperatorFunctions1
+DONE )abbrev package COMMONOP CommonOperators
+DONE ore.spad.pamphlet
+DONE )abbrev category OREPCAT UnivariateSkewPolynomialCategory
+DONE )abbrev package APPLYORE ApplyUnivariateSkewPolynomial
+DONE )abbrev domain AUTOMOR Automorphism
+DONE )abbrev package OREPCTO UnivariateSkewPolynomialCategoryOps
+DONE )abbrev domain ORESUP SparseUnivariateSkewPolynomial
+DONE )abbrev domain OREUP UnivariateSkewPolynomial
+DONE outform.spad.pamphlet
+DONE )abbrev package NUMFMT NumberFormats
+DONE )abbrev domain OUTFORM OutputForm
+DONE out.spad.pamphlet
+DONE )abbrev package OUT OutputPackage
+DONE )abbrev package SPECOUT SpecialOutputPackage
+DONE )abbrev package DISPLAY DisplayPackage
+DONE pade.spad.pamphlet
+DONE )abbrev package PADEPAC PadeApproximantPackage
+DONE )abbrev package PADE PadeApproximants
+DONE padiclib.spad.pamphlet
+DONE )abbrev package IBPTOOLS IntegralBasisPolynomialTools
+DONE )abbrev package IBACHIN ChineseRemainderToolsForIntegralBases
+DONE )abbrev package PWFFINTB PAdicWildFunctionFieldIntegralBasis
+DONE padic.spad.pamphlet
+DONE )abbrev category PADICCT PAdicIntegerCategory
+DONE )abbrev domain IPADIC InnerPAdicInteger
+DONE )abbrev domain PADIC PAdicInteger
+DONE )abbrev domain BPADIC BalancedPAdicInteger
+DONE )abbrev domain PADICRC PAdicRationalConstructor
+DONE )abbrev domain PADICRAT PAdicRational
+DONE )abbrev domain BPADICRT BalancedPAdicRational
+DONE paramete.spad.pamphlet
+DONE )abbrev domain PARPCURV ParametricPlaneCurve
+DONE )abbrev package PARPC2 ParametricPlaneCurveFunctions2
+DONE )abbrev domain PARSCURV ParametricSpaceCurve
+DONE )abbrev package PARSC2 ParametricSpaceCurveFunctions2
+DONE )abbrev domain PARSURF ParametricSurface
+DONE )abbrev package PARSU2 ParametricSurfaceFunctions2
+DONE partperm.spad.pamphlet
+DONE )abbrev package PARTPERM PartitionsAndPermutations
+DONE patmatch1.spad.pamphlet
+DONE )abbrev domain PATRES PatternMatchResult
+DONE )abbrev package PATRES2 PatternMatchResultFunctions2
+DONE )abbrev domain PATLRES PatternMatchListResult
+DONE )abbrev category PATMAB PatternMatchable
+DONE )abbrev category FPATMAB FullyPatternMatchable
+DONE )abbrev package PMSYM PatternMatchSymbol
+DONE )abbrev package PMKERNEL PatternMatchKernel
+DONE )abbrev package PMDOWN PatternMatchPushDown
+DONE )abbrev package PMTOOLS PatternMatchTools
+DONE )abbrev package PMLSAGG PatternMatchListAggregate
+DONE patmatch2.spad.pamphlet
+DONE )abbrev package PMINS PatternMatchIntegerNumberSystem
+DONE )abbrev package PMQFCAT PatternMatchQuotientFieldCategory
+DONE )abbrev package PMPLCAT PatternMatchPolynomialCategory
+DONE )abbrev package PMFS PatternMatchFunctionSpace
+DONE )abbrev package PATMATCH PatternMatch
+DONE pattern.spad.pamphlet
+DONE )abbrev domain PATTERN Pattern
+DONE )abbrev package PATTERN1 PatternFunctions1
+DONE )abbrev package PATTERN2 PatternFunctions2
+DONE )abbrev category PATAB Patternable
+DONE pcurve.spad.pamphlet
+DONE )abbrev category PPCURVE PlottablePlaneCurveCategory
+DONE )abbrev category PSCURVE PlottableSpaceCurveCategory
+DONE pdecomp.spad.pamphlet
+DONE )abbrev package PCOMP PolynomialComposition
+DONE )abbrev package PDECOMP PolynomialDecomposition
+DONE perman.spad.pamphlet
+DONE )abbrev package GRAY GrayCode
+DONE )abbrev package PERMAN Permanent
+DONE permgrps.spad.pamphlet
+DONE )abbrev domain PERMGRP PermutationGroup
+DONE )abbrev package PGE PermutationGroupExamples
+DONE perm.spad.pamphlet
+DONE )abbrev category PERMCAT PermutationCategory
+DONE )abbrev domain PERM Permutation
+DONE pfbr.spad.pamphlet
+DONE )abbrev package PFBRU PolynomialFactorizationByRecursionUnivariate
+DONE )abbrev package PFBR PolynomialFactorizationByRecursion
+DONE pfo.spad.pamphlet
+DONE )abbrev package FORDER FindOrderFinite
+DONE )abbrev package RDIV ReducedDivisor
+DONE )abbrev package PFOTOOLS PointsOfFiniteOrderTools
+DONE )abbrev package PFOQ PointsOfFiniteOrderRational
+DONE )abbrev package FSRED FunctionSpaceReduce
+DONE )abbrev package PFO PointsOfFiniteOrder
+DONE pfr.spad.pamphlet
+DONE )abbrev domain PFR PartialFraction
+DONE )abbrev package PFRPAC PartialFractionPackage
+DONE pf.spad.pamphlet
+DONE )abbrev domain IPF InnerPrimeField
+DONE )abbrev domain PF PrimeField
+DONE pgcd.spad.pamphlet
+DONE )abbrev package PGCD PolynomialGcdPackage
+DONE pgrobner.spad.pamphlet
+DONE )abbrev package PGROEB PolyGroebner
+DONE pinterp.spad.pamphlet
+DONE )abbrev package PINTERPA PolynomialInterpolationAlgorithms
+DONE )abbrev package PINTERP PolynomialInterpolation
+DONE pleqn.spad.pamphlet
+DONE )abbrev package PLEQN ParametricLinearEquations
+DONEplot3d.spad.pamphlet
+DONE )abbrev domain PLOT3D Plot3D
+DONE plot.spad.pamphlet
+DONE )abbrev domain PLOT Plot
+DONE )abbrev package PLOT1 PlotFunctions1
+DONE plottool.spad.pamphlet
+DONE )abbrev package PLOTTOOL PlotTools
+DONE polset.spad.pamphlet
+DONE )abbrev category PSETCAT PolynomialSetCategory
+DONE )abbrev domain GPOLSET GeneralPolynomialSet
+DONE poltopol.spad.pamphlet
+DONE )abbrev package MPC2 MPolyCatFunctions2
+DONE )abbrev package MPC3 MPolyCatFunctions3
+DONE )abbrev package POLTOPOL PolToPol
+DONE polycat.spad.pamphlet
+DONE )abbrev category AMR AbelianMonoidRing
+DONE )abbrev category FAMR FiniteAbelianMonoidRing
+DONE )abbrev category POLYCAT PolynomialCategory
+DONE )abbrev package POLYLIFT PolynomialCategoryLifting
+DONE )abbrev category UPOLYC UnivariatePolynomialCategory
+DONE )abbrev package UPOLYC2 UnivariatePolynomialCategoryFunctions2
+DONE )abbrev package COMMUPC CommuteUnivariatePolynomialCategory
+DONE poly.spad.pamphlet
+DONE )abbrev domain FM FreeModule
+DONE )abbrev domain PR PolynomialRing
+DONE )abbrev domain SUP SparseUnivariatePolynomial
+DONE )abbrev package SUP2 SparseUnivariatePolynomialFunctions2
+DONE )abbrev domain UP UnivariatePolynomial
+DONE )abbrev package UP2 UnivariatePolynomialFunctions2
+DONE )abbrev package POLY2UP PolynomialToUnivariatePolynomial
+DONE )abbrev package UPSQFREE UnivariatePolynomialSquareFree
+DONE )abbrev package PSQFR PolynomialSquareFree
+DONE )abbrev package UPMP UnivariatePolynomialMultiplicationPackage
+DONE primelt.spad.pamphlet
+DONE )abbrev package PRIMELT PrimitiveElement
+DONE )abbrev package FSPRMELT FunctionSpacePrimitiveElement
+DONE print.spad.pamphlet
+DONE )abbrev package PRINT PrintPackage
+DONE product.spad.pamphlet
+DONE )abbrev domain PRODUCT Product
+DONE prs.spad.pamphlet
+DONE )abbrev package PRS PseudoRemainderSequence
+DONE prtition.spad.pamphlet
+DONE )abbrev domain PRTITION Partition
+DONE )abbrev domain SYMPOLY SymmetricPolynomial
+DONE pscat.spad.pamphlet
+DONE )abbrev category PSCAT PowerSeriesCategory
+DONE )abbrev category UPSCAT UnivariatePowerSeriesCategory
+DONE )abbrev category UTSCAT UnivariateTaylorSeriesCategory
+DONE )abbrev category ULSCAT UnivariateLaurentSeriesCategory
+DONE )abbrev category UPXSCAT UnivariatePuiseuxSeriesCategory
+DONE )abbrev category MTSCAT MultivariateTaylorSeriesCategory
+DONE pseudolin.spad.pamphlet
+DONE )abbrev package PSEUDLIN PseudoLinearNormalForm
+DONE ptranfn.spad.pamphlet
+DONE )abbrev category PTRANFN PartialTranscendentalFunctions
+DONE puiseux.spad.pamphlet
+DONE )abbrev category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory
+DONE )abbrev domain UPXSCONS UnivariatePuiseuxSeriesConstructor
+DONE )abbrev domain UPXS UnivariatePuiseuxSeries
+DONE )abbrev package UPXS2 UnivariatePuiseuxSeriesFunctions2
+DONE qalgset.spad.pamphlet
+DONE )abbrev domain QALGSET QuasiAlgebraicSet
+DONE )abbrev package QALGSET2 QuasiAlgebraicSet2
+DONE quat.spad.pamphlet
+DONE )abbrev category QUATCAT QuaternionCategory
+DONE )abbrev domain QUAT Quaternion
+DONE )abbrev package QUATCT2 QuaternionCategoryFunctions2
+DONE radeigen.spad.pamphlet
+DONE )abbrev package REP RadicalEigenPackage
+DONE radix.spad.pamphlet
+DONE )abbrev domain RADIX RadixExpansion
+DONE )abbrev domain BINARY BinaryExpansion
+DONE )abbrev domain DECIMAL DecimalExpansion
+DONE )abbrev domain HEXADEC HexadecimalExpansion
+DONE )abbrev package RADUTIL RadixUtilities
+DONE random.spad.pamphlet
+DONE )abbrev package RANDSRC RandomNumberSource
+DONE )abbrev package RDIST RandomDistributions
+DONE )abbrev package INTBIT IntegerBits
+DONE )abbrev package RIDIST RandomIntegerDistributions
+DONE )abbrev package RFDIST RandomFloatDistributions
+DONE ratfact.spad.pamphlet
+DONE )abbrev package RATFACT RationalFactorize
+DONE rdeef.spad.pamphlet
+DONE )abbrev package INTTOOLS IntegrationTools
+DONE )abbrev package RDEEF ElementaryRischDE
+DONE rderf.spad.pamphlet
+DONE )abbrev package RDETR TranscendentalRischDE
+DONE rdesys.spad.pamphlet
+DONE )abbrev package RDETRS TranscendentalRischDESystem
+DONE )abbrev package RDEEFS ElementaryRischDESystem
+DONE real0q.spad.pamphlet
+DONE )abbrev package REAL0Q RealZeroPackageQ
+DONE realzero.spad.pamphlet
+DONE )abbrev package REAL0 RealZeroPackage
+DONE reclos.spad.pamphlet
+DONE )abbrev package POLUTIL RealPolynomialUtilitiesPackage
+DONE )abbrev category RRCC RealRootCharacterizationCategory
+DONE )abbrev category RCFIELD RealClosedField
+DONE )abbrev domain ROIRC RightOpenIntervalRootCharacterization
+DONE )abbrev domain RECLOS RealClosure
+regset.spad.pamphlet
+DONE )abbrev category RSETCAT RegularTriangularSetCategory
+)abbrev package QCMPACK QuasiComponentPackage
+)abbrev package RSETGCD RegularTriangularSetGcdPackage
+)abbrev package RSDCMPK RegularSetDecompositionPackage
+)abbrev domain REGSET RegularTriangularSet
+DONE rep1.spad.pamphlet
+DONE )abbrev package REP1 RepresentationPackage1
+DONE rep2.spad.pamphlet
+DONE )abbrev package REP2 RepresentationPackage2
+DONE resring.spad.pamphlet
+DONE )abbrev domain RESRING ResidueRing
+DONE retract.spad.pamphlet
+DONE )abbrev category FRETRCT FullyRetractableTo
+DONE )abbrev package INTRET IntegerRetractions
+DONE )abbrev package RATRET RationalRetractions
+DONE rf.spad.pamphlet
+DONE )abbrev package POLYCATQ PolynomialCategoryQuotientFunctions
+DONE )abbrev package RF RationalFunction
+DONE riccati.spad.pamphlet
+DONE )abbrev package ODEPRRIC PrimitiveRatRicDE
+DONE )abbrev package ODERTRIC RationalRicDE
+DONE routines.spad.pamphlet
+DONE )abbrev domain ROUTINE RoutinesTable
+DONE )abbrev domain ATTRBUT AttributeButtons
+DONE rule.spad.pamphlet
+DONE )abbrev domain RULE RewriteRule
+DONE )abbrev package APPRULE ApplyRules
+DONE )abbrev domain RULESET Ruleset
+DONE seg.spad.pamphlet
+DONE )abbrev category SEGCAT SegmentCategory
+DONE )abbrev category SEGXCAT SegmentExpansionCategory
+DONE )abbrev domain SEG Segment
+DONE )abbrev package SEG2 SegmentFunctions2
+DONE )abbrev domain SEGBIND SegmentBinding
+DONE )abbrev package SEGBIND2 SegmentBindingFunctions2
+DONE )abbrev domain UNISEG UniversalSegment
+DONE )abbrev package UNISEG2 UniversalSegmentFunctions2
+DONE )abbrev package INCRMAPS IncrementingMaps
+DONE setorder.spad.pamphlet
+DONE )abbrev package UDPO UserDefinedPartialOrdering
+DONE )abbrev package UDVO UserDefinedVariableOrdering
+DONE sets.spad.pamphlet
+DONE )abbrev domain SET Set
+DONE sex.spad.pamphlet
+DONE )abbrev category SEXCAT SExpressionCategory
+DONE )abbrev domain SEXOF SExpressionOf
+DONE )abbrev domain SEX SExpression
+DONE sf.spad.pamphlet
+DONE )abbrev category REAL RealConstant
+DONE )abbrev category RADCAT RadicalCategory
+DONE )abbrev category RNS RealNumberSystem
+DONE )abbrev category FPS FloatingPointSystem
+DONE )abbrev domain DFLOAT DoubleFloat
+DONE sgcf.spad.pamphlet
+DONE )abbrev package SGCF SymmetricGroupCombinatoricFunctions
+DONE sign.spad.pamphlet
+DONE )abbrev package TOOLSIGN ToolsForSign
+DONE )abbrev package INPSIGN InnerPolySign
+DONE )abbrev package SIGNRF RationalFunctionSign
+DONE )abbrev package LIMITRF RationalFunctionLimitPackage
+DONE si.spad.pamphlet
+DONE )abbrev category INS IntegerNumberSystem
+DONE )abbrev domain SINT SingleInteger
+DONE smith.spad.pamphlet
+DONE )abbrev package SMITH SmithNormalForm
+DONE solvedio.spad.pamphlet
+DONE )abbrev package DIOSP DiophantineSolutionPackage
+DONE solvefor.spad.pamphlet
+DONE )abbrev package SOLVEFOR PolynomialSolveByFormulas
+DONE solvelin.spad.pamphlet
+DONE )abbrev package LSMP LinearSystemMatrixPackage
+DONE )abbrev package LSMP1 LinearSystemMatrixPackage1
+DONE )abbrev package LSPP LinearSystemPolynomialPackage
+DONE solverad.spad.pamphlet
+DONE )abbrev package SOLVERAD RadicalSolvePackage
+DONE sortpak.spad.pamphlet
+DONE )abbrev package SORTPAK SortPackage
+DONE space.spad.pamphlet
+DONE )abbrev category SPACEC ThreeSpaceCategory
+DONE )abbrev domain SPACE3 ThreeSpace
+DONE )abbrev package TOPSP TopLevelThreeSpace
+DONE special.spad.pamphlet
+DONE )abbrev package DFSFUN DoubleFloatSpecialFunctions
+DONE )abbrev package ORTHPOL OrthogonalPolynomialFunctions
+DONE )abbrev package NTPOLFN NumberTheoreticPolynomialFunctions
+sregset.spad.pamphlet
+)abbrev category SFRTCAT SquareFreeRegularTriangularSetCategory
+)abbrev package SFQCMPK SquareFreeQuasiComponentPackage
+)abbrev package SFRGCD SquareFreeRegularTriangularSetGcdPackage
+)abbrev package SRDCMPK SquareFreeRegularSetDecompositionPackage
+)abbrev domain SREGSET SquareFreeRegularTriangularSet
+DONE s.spad.pamphlet
+DONE )abbrev package NAGS NagSpecialFunctionsPackage
+DONE stream.spad.pamphlet
+DONE )abbrev category LZSTAGG LazyStreamAggregate
+DONE )abbrev package CSTTOOLS CyclicStreamTools
+DONE )abbrev domain STREAM Stream
+DONE )abbrev package STREAM1 StreamFunctions1
+DONE )abbrev package STREAM2 StreamFunctions2
+DONE )abbrev package STREAM3 StreamFunctions3
+DONE string.spad.pamphlet
+DONE )abbrev domain CHAR Character
+DONE )abbrev domain CCLASS CharacterClass
+DONE )abbrev domain ISTRING IndexedString
+DONE )abbrev domain STRING String
+DONE )abbrev category STRICAT StringCategory
+DONE sttaylor.spad.pamphlet
+DONE )abbrev package STTAYLOR StreamTaylorSeriesOperations
+DONE sttf.spad.pamphlet
+DONE )abbrev package STTF StreamTranscendentalFunctions
+DONE )abbrev package STTFNC StreamTranscendentalFunctionsNonCommutative
+DONE sturm.spad.pamphlet
+DONE )abbrev package SHP SturmHabichtPackage
+DONE suchthat.spad.pamphlet
+DONE )abbrev domain SUCH SuchThat
+DONE suls.spad.pamphlet
+DONE )abbrev domain SULS SparseUnivariateLaurentSeries
+DONE sum.spad.pamphlet
+DONE )abbrev package ISUMP InnerPolySum
+DONE )abbrev package GOSPER GosperSummationMethod
+DONE )abbrev package SUMRF RationalFunctionSum
+DONE sups.spad.pamphlet
+DONE )abbrev domain ISUPS InnerSparseUnivariatePowerSeries
+DONE supxs.spad.pamphlet
+DONE )abbrev domain SUPXS SparseUnivariatePuiseuxSeries
+DONE suts.spad.pamphlet
+DONE )abbrev domain SUTS SparseUnivariateTaylorSeries
+DONE symbol.spad.pamphlet
+DONE )abbrev domain SYMBOL Symbol
+DONE syssolp.spad.pamphlet
+DONE )abbrev package SYSSOLP SystemSolvePackage
+DONE system.spad.pamphlet
+DONE )abbrev package MSYSCMD MoreSystemCommands
+DONE tableau.spad.pamphlet
+DONE )abbrev domain TABLEAU Tableau
+DONE )abbrev package TABLBUMP TableauxBumpers
+DONE table.spad.pamphlet
+DONE )abbrev domain HASHTBL HashTable
+DONE )abbrev domain INTABL InnerTable
+DONE )abbrev domain TABLE Table
+DONE )abbrev domain EQTBL EqTable
+DONE )abbrev domain STRTBL StringTable
+DONE )abbrev domain GSTBL GeneralSparseTable
+DONE )abbrev domain STBL SparseTable
+DONE taylor.spad.pamphlet
+DONE )abbrev domain ITAYLOR InnerTaylorSeries
+DONE )abbrev domain UTS UnivariateTaylorSeries
+DONE )abbrev package UTS2 UnivariateTaylorSeriesFunctions2
+DONE tex.spad.pamphlet
+DONE )abbrev domain TEX TexFormat
+DONE )abbrev package TEX1 TexFormat1
+DONE tools.spad.pamphlet
+DONE )abbrev package ESTOOLS ExpertSystemToolsPackage
+DONE )abbrev package ESTOOLS1 ExpertSystemToolsPackage1
+DONE )abbrev package ESTOOLS2 ExpertSystemToolsPackage2
+transsolve.spad.pamphlet
+)abbrev package SOLVETRA TransSolvePackage
+DONE )abbrev package SOLVESER TransSolvePackageService
+DONE tree.spad.pamphlet
+DONE )abbrev domain TREE Tree
+DONE )abbrev category BTCAT BinaryTreeCategory
+DONE )abbrev domain BTREE BinaryTree
+DONE )abbrev domain BSTREE BinarySearchTree
+DONE )abbrev domain BTOURN BinaryTournament
+DONE )abbrev domain BBTREE BalancedBinaryTree
+DONE )abbrev domain PENDTREE PendantTree
+DONE trigcat.spad.pamphlet
+DONE )abbrev category ELEMFUN ElementaryFunctionCategory
+DONE )abbrev category AHYP ArcHyperbolicFunctionCategory
+DONE )abbrev category ATRIG ArcTrigonometricFunctionCategory
+DONE )abbrev category HYPCAT HyperbolicFunctionCategory
+DONE )abbrev category TRANFUN TranscendentalFunctionCategory
+DONE )abbrev category TRIGCAT TrigonometricFunctionCategory
+DONE )abbrev category PRIMCAT PrimitiveFunctionCategory
+DONE )abbrev category LFCAT LiouvillianFunctionCategory
+DONE )abbrev category CFCAT CombinatorialFunctionCategory
+DONE )abbrev category SPFCAT SpecialFunctionCategory
+DONE triset.spad.pamphlet
+DONE )abbrev category TSETCAT TriangularSetCategory
+DONE )abbrev domain GTSET GeneralTriangularSet
+DONE )abbrev package PSETPK PolynomialSetUtilitiesPackage
+DONE )abbrev domain WUTSET WuWenTsunTriangularSet
+DONE tube.spad.pamphlet
+DONE )abbrev domain TUBE TubePlot
+DONE )abbrev package TUBETOOL TubePlotTools
+DONE )abbrev package EXPRTUBE ExpressionTubePlot
+DONE )abbrev package NUMTUBE NumericTubePlot
+DONE twofact.spad.pamphlet
+DONE )abbrev package NORMRETR NormRetractPackage
+DONE )abbrev package TWOFACT TwoFactorize
+DONE unifact.spad.pamphlet
+DONE )abbrev package UNIFACT UnivariateFactorize
+DONE updecomp.spad.pamphlet
+DONE )abbrev package UPDECOMP UnivariatePolynomialDecompositionPackage
+DONE updivp.spad.pamphlet
+DONE )abbrev package UPDIVP UnivariatePolynomialDivisionPackage
+DONE utsode.spad.pamphlet
+DONE )abbrev package UTSODE UnivariateTaylorSeriesODESolver
+DONE variable.spad.pamphlet
+DONE )abbrev domain OVAR OrderedVariableList
+DONE )abbrev domain VARIABLE Variable
+DONE )abbrev domain RULECOLD RuleCalled
+DONE )abbrev domain FUNCTION FunctionCalled
+DONE )abbrev domain ANON AnonymousFunction
+DONE vector.spad.pamphlet
+DONE )abbrev category VECTCAT VectorCategory
+DONE )abbrev domain IVECTOR IndexedVector
+DONE )abbrev domain VECTOR Vector
+DONE )abbrev package VECTOR2 VectorFunctions2
+DONE )abbrev category DIRPCAT DirectProductCategory
+DONE )abbrev domain DIRPROD DirectProduct
+DONE )abbrev package DIRPROD2 DirectProductFunctions2
+DONE view2D.spad.pamphlet
+DONE )abbrev domain GRIMAGE GraphImage
+DONE )abbrev domain VIEW2D TwoDimensionalViewport
+DONE view3D.spad.pamphlet
+DONE )abbrev domain VIEW3D ThreeDimensionalViewport
+DONE viewDef.spad.pamphlet
+DONE )abbrev package VIEWDEF ViewDefaultsPackage
+DONE viewpack.spad.pamphlet
+DONE )abbrev package VIEW ViewportPackage
+DONE void.spad.pamphlet
+DONE )abbrev domain VOID Void
+DONE )abbrev domain EXIT Exit
+DONE )abbrev package RESLATC ResolveLatticeCompletion
+DONE weier.spad.pamphlet
+DONE )abbrev package WEIER WeierstrassPreparation
+DONE wtpol.spad.pamphlet
+DONE )abbrev domain WP WeightedPolynomials
+DONE )abbrev domain OWP OrdinaryWeightedPolynomials
+DONE xlpoly.spad.pamphlet
+DONE )abbrev domain MAGMA Magma
+DONE )abbrev domain LWORD LyndonWord
+DONE )abbrev category LIECAT LieAlgebra
+DONE )abbrev category FLALG FreeLieAlgebra
+DONE )abbrev package XEXPPKG XExponentialPackage
+DONE )abbrev domain LPOLY LiePolynomial
+DONE )abbrev domain PBWLB PoincareBirkhoffWittLyndonBasis
+DONE )abbrev domain XPBWPOLY XPBWPolynomial
+DONE )abbrev domain LEXP LieExponentials
+DONE xpoly.spad.pamphlet
+DONE )abbrev domain OFMONOID OrderedFreeMonoid
+DONE )abbrev category FMCAT FreeModuleCat
+DONE )abbrev domain FM1 FreeModule1
+DONE )abbrev category XALG XAlgebra
+DONE )abbrev category XFALG XFreeAlgebra
+DONE )abbrev category XPOLYC XPolynomialsCat
+DONE )abbrev domain XPR XPolynomialRing
+DONE )abbrev domain XDPOLY XDistributedPolynomial
+DONE )abbrev domain XRPOLY XRecursivePolynomial
+DONE )abbrev domain XPOLY XPolynomial
+DONE ystream.spad.pamphlet
+DONE )abbrev package YSTREAM ParadoxicalCombinatorsForStreams
+zerodim.spad.pamphlet
+DONE )abbrev package FGLMICPK FGLMIfCanPackage
+)abbrev domain RGCHAIN RegularChain
+)abbrev package LEXTRIPK LexTriangularPackage
+)abbrev package IRURPK InternalRationalUnivariateRepresentationPackage
+)abbrev package RURPK RationalUnivariateRepresentationPackage
+)abbrev package ZDSOLVE ZeroDimensionalSolvePackage
+
+\section{The Algebra Lattice Layers}
+\subsection{Layer 0 Bootstrap}
+\begin{verbatim}
+catdef ABELGRP (ignore -- bootstrap from lisp)
+catdef ABELMON (ignore -- bootstrap from lisp)
+catdef ABELSG (ignore -- bootstrap from lisp)
+aggcat ALAGG (ignore -- bootstrap from lisp)
+boolean BOOLEAN (ignore -- bootstrap from lisp)
+catdef CABMON (ignore -- bootstrap from lisp)
+aggcat CLAGG (ignore -- bootstrap from lisp)
+catdef COMRING (ignore -- bootstrap from lisp)
+sf DFLOAT (ignore -- bootstrap from lisp)
+catdef DIFRING (ignore -- bootstrap from lisp)
+catdef DIVRING (ignore -- bootstrap from lisp)
+catdef ENTIRER (ignore -- bootstrap from lisp)
+fspace ES (ignore -- bootstrap from lisp)
+catdef EUCDOM (ignore -- bootstrap from lisp)
+ffcat FFIELDC (ignore -- bootstrap from lisp)
+sf FPS (ignore -- bootstrap from lisp)
+catdef GCDMON (ignore -- bootstrap from lisp)
+aggcat HOAGG (ignore -- bootstrap from lisp)
+list ILIST (ignore -- bootstrap from lisp)
+si INS (ignore -- bootstrap from lisp)
+integer INT (ignore -- bootstrap from lisp)
+catdef INTDOM (ignore -- bootstrap from lisp)
+string ISTRING (ignore -- bootstrap from lisp)
+list LIST (ignore -- bootstrap from lisp)
+aggcat LNAGG (ignore -- bootstrap from lisp)
+aggcat LSAGG (ignore -- bootstrap from lisp)
+pscat MTSCAT (ignore -- bootstrap from lisp)
+catdef MONOID (ignore -- bootstrap from lisp)
+integer NNI (ignore -- bootstrap from lisp)
+catdef OINTDOM (ignore -- bootstrap from lisp)
+catdef ORDRING (ignore -- bootstrap from lisp)
+outform OUTFORM (ignore -- bootstrap from lisp)
+integer PI (ignore -- bootstrap from lisp)
+polycat POLYCAT (ignore -- bootstrap from lisp)
+polset PSETCAT (ignore -- bootstrap from lisp)
+array1 PRIMARR (ignore -- bootstrap from lisp)
+aggcat RCAGG (ignore -- bootstrap from lisp)
+boolean REF (ignore -- bootstrap from lisp)
+catdef RING (ignore -- bootstrap from lisp)
+catdef RNG (ignore -- bootstrap from lisp)
+aggcat SETAGG (ignore -- bootstrap from lisp)
+catdef SETCAT (ignore -- bootstrap from lisp)
+si SINT (ignore -- bootstrap from lisp)
+aggcat STAGG (ignore -- bootstrap from lisp)
+triset TSETCAT (ignore -- bootstrap from lisp)
+catdef UFD (ignore -- bootstrap from lisp)
+aggcat URAGG (ignore -- bootstrap from lisp)
+polycat UPOLYC (ignore -- bootstrap from lisp)
+vector VECTOR (ignore -- bootstrap from lisp)
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+si.spad.pamphlet (INS SINT)
+
+\end{verbatim}
+Note well that none of the algebra stanzas should include these
+files in the preconditions otherwise we have an infinite compile
+loop. These files are originally bootstrapped from lisp code
+when we build the system for the first time but they are
+forcibly recompiled at the end of the build so they reflect
+current code (just in case someone changes the spad code but
+does not re-cache the generated lisp). If you add these files
+as preconditions (note that they are all in the {\bf MID}
+directory rather than the {\bf OUT} directory like everything
+else) then the final recompile will invalidate all of the
+rest of the algebra targets which will get rebuilt again causing
+these targets to be out of date. The rest of the loop is left
+up to the student.
+
+The bootstrap process works because first we ask for the compiled
+lisp code stanzas (the [[${MID}/BAR.o]] files), THEN we ask for
+the final algebra code stanzas (the [[${OUT}/BAR.o]] files). This
+is a very subtle point so think it through carefully. Notice that
+this is the only layer calling for [[${MID}]] files. All other
+layers call for [[${OUT}]] files. If you break this the world
+will no longer compile so don't change it if you don't understand it.
+
+\begin{verbatim}
+LAYER0BOOTSTRAP=${OUT}/XPR.o
+\end{verbatim}
+
+<<layer0 bootstrap>>=
+LAYER0BOOTSTRAP=\
+ ${MID}/ABELGRP.o ${MID}/ABELGRP-.o \
+ ${MID}/ABELMON.o ${MID}/ABELMON-.o \
+ ${MID}/ABELSG.o ${MID}/ABELSG-.o \
+ ${MID}/ALAGG.o \
+ ${MID}/BOOLEAN.o ${MID}/CABMON.o ${MID}/CHAR.o \
+ ${MID}/CLAGG.o ${MID}/CLAGG-.o \
+ ${MID}/COMRING.o ${MID}/DFLOAT.o \
+ ${MID}/DIFRING.o ${MID}/DIFRING-.o \
+ ${MID}/DIVRING.o ${MID}/DIVRING-.o \
+ ${MID}/ENTIRER.o \
+ ${MID}/ES.o ${MID}/ES-.o \
+ ${MID}/EUCDOM.o ${MID}/EUCDOM-.o \
+ ${MID}/FFIELDC.o ${MID}/FFIELDC-.o \
+ ${MID}/FPS.o ${MID}/FPS-.o \
+ ${MID}/GCDDOM.o ${MID}/GCDDOM-.o \
+ ${MID}/HOAGG.o ${MID}/HOAGG-.o ${MID}/ILIST.o \
+ ${MID}/INS.o ${MID}/INS-.o \
+ ${MID}/INT.o \
+ ${MID}/INTDOM.o ${MID}/INTDOM-.o \
+ ${MID}/ISTRING.o ${MID}/LIST.o \
+ ${MID}/LNAGG.o ${MID}/LNAGG-.o \
+ ${MID}/LSAGG.o ${MID}/LSAGG-.o \
+ ${MID}/MONOID.o ${MID}/MONOID-.o \
+ ${MID}/MTSCAT.o \
+ ${MID}/NNI.o ${MID}/OINTDOM.o \
+ ${MID}/ORDRING.o ${MID}/ORDRING-.o ${MID}/OUTFORM.o \
+ ${MID}/PI.o ${MID}/PRIMARR.o \
+ ${MID}/POLYCAT.o ${MID}/POLYCAT-.o \
+ ${MID}/PSETCAT.o ${MID}/PSETCAT-.o \
+ ${MID}/QFCAT.o ${MID}/QFCAT-.o \
+ ${MID}/RCAGG.o ${MID}/RCAGG-.o \
+ ${MID}/REF.o \
+ ${MID}/RING.o ${MID}/RING-.o \
+ ${MID}/RNG.o \
+ ${MID}/RNS.o ${MID}/RNS-.o \
+ ${MID}/SETAGG.o ${MID}/SETAGG-.o \
+ ${MID}/SETCAT.o ${MID}/SETCAT-.o \
+ ${MID}/SINT.o \
+ ${MID}/STAGG.o ${MID}/STAGG-.o \
+ ${MID}/SYMBOL.o \
+ ${MID}/TSETCAT.o ${MID}/TSETCAT-.o \
+ ${MID}/UFD.o ${MID}/UFD-.o \
+ ${MID}/ULSCAT.o \
+ ${MID}/UPOLYC.o ${MID}/UPOLYC-.o \
+ ${MID}/URAGG.o ${MID}/URAGG-.o \
+ ${MID}/VECTOR.o
+@
+\subsection{Layer 0}
+\begin{verbatim}
+trigcat AHYP nothing
+attreg ATTREG nothing
+trigcat CFCAT nothing
+aggcat ELTAB nothing
+coerce KOERCE nothing
+coerce KONVERT nothing
+system MSYSCMD nothing
+d02agents ODEIFTBL nothing
+omcat OM nothing
+omdev OMCONN nothing
+omdev OMDEV nothing
+out OUT nothing
+trigcat PRIMCAT nothing
+print PRINT nothing
+ptranfn PTRANFN nothing
+trigcat SPFCAT nothing
+coerce TYPE nothing
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+attreg.spad.pamphlet (ATTREG)
+dhmatrix.spad.pamphlet (DHMATRIX)
+omcat.spad.pamphlet (OM)
+print.spad.pamphlet (PRINT)
+ptranfn.spad.pamphlet (PTRANFN)
+system.spad.pamphlet (MSYSCMD)
+\end{verbatim}
+
+<<layer0>>=
+LAYER0=${OUT}/AHYP.o ${OUT}/ATTREG.o ${OUT}/CFCAT.o ${OUT}/ELTAB.o \
+ ${OUT}/KOERCE.o ${OUT}/KONVERT.o ${OUT}/MSYSCMD.o ${OUT}/ODEIFTBL.o \
+ ${OUT}/OM.o ${OUT}/OMCONN.o ${OUT}/OMDEV.o \
+ ${OUT}/OUT.o ${OUT}/PRIMCAT.o ${OUT}/PRINT.o ${OUT}/PTRANFN.o \
+ ${OUT}/SPFCAT.o ${OUT}/TYPE.o
+
+@
+\subsection{Layer 1}
+\begin{verbatim}
+any ANY1 TYPE
+combfunc COMBOPC CFCAT
+drawopt DROPT1 TYPE
+equation2 EQ2 TYPE
+fortcat FORTCAT TYPE KOERCE
+ituple ITFUN2 TYPE
+ituple ITFUN3 TYPE
+ituple ITUPLE KOERCE TYPE
+mkrecord MKRECORD TYPE
+mkfunc MKUCFUNC KONVERT TYPE
+any NONE1 TYPE
+pattern PATAB KONVERT
+plot PLOT1 KONVERT
+pcurve PPCURVE KOERCE
+pcurve PSCURVE KOERCE
+sf REAL KONVERT
+coerce RETRACT TYPE
+seg SEGBIND2 TYPE
+seg SEGCAT TYPE
+stream STREAM1 TYPE
+stream STREAM2 TYPE
+stream STREAM3 TYPE
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+ituple.spad.pamphlet (ITFUN2 ITFUN3 ITUPLE)
+mkrecord.spad.pamphlet (MKRECORD)
+pcurve.spad.pamphlet (PPCURVE PSCURVE)
+coerce.spad.pamphlet (TYPE KOERCE KONVERT RETRACT)
+
+\end{verbatim}
+
+<<layer1>>=
+LAYER1=${OUT}/ANY1.o ${OUT}/COMBOPC.o ${OUT}/DROPT1.o \
+ ${OUT}/EQ2.o \
+ ${OUT}/FORTCAT.o ${OUT}/ITFUN2.o ${OUT}/ITFUN3.o ${OUT}/ITUPLE.o \
+ ${OUT}/MKBCFUNC.o ${OUT}/MKRECORD.o ${OUT}/MKUCFUNC.o \
+ ${OUT}/NONE1.o \
+ ${OUT}/PATAB.o ${OUT}/PLOT1.o ${OUT}/PPCURVE.o \
+ ${OUT}/PSCURVE.o ${OUT}/REAL.o ${OUT}/RESLATC.o \
+ ${OUT}/RETRACT.o ${OUT}/RETRACT-.o ${OUT}/SEGBIND2.o ${OUT}/SEGCAT.o \
+ ${OUT}/STREAM1.o ${OUT}/STREAM2.o ${OUT}/STREAM3.o
+
+@
+\subsection{Layer 2}
+\begin{verbatim}
+fortcat FMC FORTCAT TYPE KOERCE
+fortcat FMFUN FORTCAT TYPE KOERCE
+fortcat FORTFN FORTCAT TYPE KOERCE
+fortcat FVC FORTCAT TYPE KOERCE
+fortcat FVFUN FORTCAT TYPE KOERCE
+retract INTRET RETRACT
+seg SEGXCAT SEGCAT TYPE
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+<<layer2>>=
+LAYER2=${OUT}/FMC.o ${OUT}/FMFUN.o \
+ ${OUT}/FORTFN.o ${OUT}/FVC.o ${OUT}/FVFUN.o ${OUT}/INTRET.o \
+ ${OUT}/SEGXCAT.o
+
+@
+\subsection{Layer 3}
+\begin{verbatim}
+aggcat AGG TYPE NNI INT
+catdef BASTYPE BOOLEAN
+grdef GRDEF BOOLEAN
+list LIST3 TYPE INT LIST ILIST
+mkfunc MKFUNC KONVERT INT LIST
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+grdef.spad.pamphlet (GRDEF)
+
+\end{verbatim}
+
+<<layer3>>=
+LAYER3=${OUT}/AGG.o ${OUT}/AGG-.o \
+ ${OUT}/BASTYPE.o ${OUT}/BASTYPE-.o ${OUT}/GRDEF.o \
+ ${OUT}/LIST3.o ${OUT}/MKFUNC.o
+
+@
+\begin{verbatim}
+\subsection{Layer 4}
+variable ANON SETCAT BASTYPE KOERCE
+asp ASP29 FORTCAT TYPE KOERCE BOOLEAN
+color COLOR ABELSG SETCAT BASTYPE KOERCE DFLOAT INT FPS RNS NNI PI
+ BOOLEAN
+fnla COMM SETCAT BASTYPE KOERCE BOOLEAN
+newpoint COMPPROP SETCAT BASTYPE KOERCE BOOLEAN
+aggcat ELTAGG ELTAB SETCAT BASTYPE KOERCE TYPE
+void EXIT SETCAT BASTYPE KOERCE
+free FAMONC CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE RETRACT
+files FILECAT SETCAT BASTYPE KOERCE
+catdef FINITE SETCAT BASTYPE KOERCE
+fname FNCAT SETCAT BASTYPE KOERCE
+formula FORMULA1 SETCAT BASTYPE KOERCE
+indexedp IDPC SETCAT BASTYPE KOERCE
+equation1 IEVALAB SETCAT BASTYPE KOERCE TYPE
+random INTBIT INT
+catdef LMODULE ABELGRP CABMON ABELMON SETCAT BASTYPE KOERCE
+boolean LOGIC BASTYPE
+mappkg MAPHACK1 SETCAT BASTYPE KOERCE SINT NNI INT
+mappkg MAPHACK2 SETCAT BASTYPE KOERCE
+mappkg MAPHACK3 SETCAT BASTYPE KOERCE
+mappkg MAPPKG1 SETCAT BASTYPE KOERCE SINT NNI INT BOOLEAN
+mappkg MAPPKG2 SETCAT BASTYPE KOERCE
+mappkg MAPPKG3 SETCAT BASTYPE KOERCE
+naalgc MONAD SETCAT BASTYPE KOERCE PI NNI INT SINT
+annacat NIPROB SETCAT BASTYPE KOERCE
+any NONE SETCAT BASTYPE KOERCE
+annacat NUMINT SETCAT BASTYPE KOERCE
+annacat ODECAT SETCAT BASTYPE KOERCE
+annacat ODEPROB SETCAT BASTYPE KOERCE
+omdev OMENC SETCAT BASTYPE KOERCE SINT
+complet ONECOMP2 SETCAT BASTYPE KOERCE
+annacat OPTCAT SETCAT BASTYPE KOERCE
+annacat OPTPROB SETCAT BASTYPE KOERCE
+catdef ORDSET SETCAT BASTYPE KOERCE
+color PALETTE SETCAT BASTYPE KOERCE INT LIST ILIST LSAGG STAGG
+paramete PARPCURV TYPE NNI INT
+paramete PARPC2 TYPE NNI INT
+paramete PARSCURV TYPE NNI INT
+paramete PARSC2 TYPE NNI INT
+paramete PARSURF TYPE NNI INT
+paramete PARSU2 TYPE NNI INT
+patmatch1 PATMAB SETCAT BASTYPE KOERCE
+pattern PATTERN1 SETCAT BASTYPE KOERCE TYPE INT LIST ILIST LSAGG STAGG
+patmatch1 PATRES2 SETCAT BASTYPE KOERCE
+annacat PDECAT SETCAT BASTYPE KOERCE
+annacat PDEPROB SETCAT BASTYPE KOERCE
+defaults REPSQ SETCAT BASTYPE KOERCE PI NNI INT
+defaults REPDB SETCAT BASTYPE KOERCE PI NNI INT
+random RFDIST INT PI NNI BOOLEAN SINT
+random RIDIST SINT NNI INT
+catdef RMODULE ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+sex SEXCAT SETCAT BASTYPE KOERCE
+catdef SGROUP SETCAT BASTYPE KOERCE
+space SPACEC SETCAT BASTYPE KOERCE
+newdata SPLNODE SETCAT BASTYPE KOERCE AGG TYPE BOOLEAN
+catdef STEP SETCAT BASTYPE KOERCE
+suchthat SUCH SETCAT BASTYPE KOERCE
+tex TEX1 SETCAT BASTYPE KOERCE
+setorder UDVO INT LIST ILIST SETCAT BASTYPE KOERCE
+ystream YSTREAM TYPE INT SINT NNI
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+annacat.spad.pamphlet (NIPROB ODEPROB PDEPROB OPTPROB NUMINT ODECAT PDECAT
+ OPTCAT)
+color.spad.pamphlet (COLOR PALETTE)
+mappkg.spad.pamphlet (MAPHACK1 MAPHACK2 MAPHACK3 MAPPKG1 MAPPKG2 MAPPKG3)
+paramete.spad.pamphlet (PARPCURV PARPC2 PARSCURV PARSC2 PARSURF PARSU2
+suchthat.spad.pamphlet (SUCH)
+ystream.spad.pamphlet (YSTREAM)
+
+\end{verbatim}
+
+<<layer4>>=
+LAYER4=${OUT}/ANON.o ${OUT}/COLOR.o \
+ ${OUT}/COMM.o ${OUT}/COMPPROP.o \
+ ${OUT}/ELTAGG.o ${OUT}/ELTAGG-.o ${OUT}/ESCONT1.o \
+ ${OUT}/EXIT.o ${OUT}/FAMONC.o ${OUT}/FILECAT.o \
+ ${OUT}/FINITE.o ${OUT}/FNCAT.o \
+ ${OUT}/FORMULA1.o \
+ ${OUT}/IDPC.o ${OUT}/IEVALAB.o ${OUT}/IEVALAB-.o \
+ ${OUT}/INTBIT.o \
+ ${OUT}/LMODULE.o \
+ ${OUT}/LOGIC.o ${OUT}/LOGIC-.o ${OUT}/MAPHACK1.o ${OUT}/MAPHACK2.o \
+ ${OUT}/MAPHACK3.o ${OUT}/MAPPKG1.o ${OUT}/MAPPKG2.o \
+ ${OUT}/MAPPKG3.o ${OUT}/MONAD.o ${OUT}/MONAD-.o \
+ ${OUT}/NIPROB.o ${OUT}/NONE.o ${OUT}/NUMINT.o \
+ ${OUT}/ODECAT.o ${OUT}/ODEPROB.o ${OUT}/OMENC.o ${OUT}/ONECOMP2.o \
+ ${OUT}/OPTCAT.o ${OUT}/OPTPROB.o \
+ ${OUT}/ORDSET.o ${OUT}/ORDSET-.o ${OUT}/PALETTE.o \
+ ${OUT}/PARPCURV.o ${OUT}/PARPC2.o ${OUT}/PARSCURV.o \
+ ${OUT}/PARSC2.o ${OUT}/PARSURF.o ${OUT}/PARSU2.o ${OUT}/PATMAB.o \
+ ${OUT}/PATRES2.o ${OUT}/PATTERN1.o ${OUT}/PDECAT.o ${OUT}/PDEPROB.o \
+ ${OUT}/REPSQ.o ${OUT}/REPDB.o ${OUT}/RFDIST.o ${OUT}/RIDIST.o \
+ ${OUT}/RMODULE.o \
+ ${OUT}/SEXCAT.o ${OUT}/SGROUP.o ${OUT}/SGROUP-.o \
+ ${OUT}/SPACEC.o ${OUT}/SPLNODE.o \
+ ${OUT}/STEP.o ${OUT}/SUCH.o ${OUT}/TEX1.o \
+ ${OUT}/UDVO.o ${OUT}/YSTREAM.o
+
+@
+\subsection{Layer 5}
+\begin{verbatim}
+trigcat ATRIG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+catdef BMODULE RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+kl CACHSET ORDSET SETCAT BASTYPE KOERCE
+catdef CHARNZ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+catdef CHARZ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+dpolcat DVARCAT ORDSET SETCAT BASTYPE KOERCE RETRACT NNI INT BOOLEAN
+trigcat ELEMFUN MONOID SGROUP SETCAT BASTYPE KOERCE
+tools ESTOOLS2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+equation1 EVALAB IEVALAB SETCAT BASTYPE KOERCE
+equation2 FEVALAB IEVALAB
+fourier FCOMP ORDSET SETCAT BASTYPE KOERCE BOOLEAN
+patmatch1 FPATMAB TYPE PATMAB SETCAT BASTYPE KOERCE
+catdef GROUP MONOID SGROUP SETCAT BASTYPE KOERCE INT
+indexedp IDPAM ABELMON ABELSG SETCAT BASTYPE KOERCE IDPC ORDSET INT LIST
+ ILIST BOOLEAN
+indexedp IDPO IDPC SETCAT BASTYPE KOERCE ORDSET INT LIST BOOLEAN ILIST
+seg INCRMAPS MONOID SGROUP SETCAT BASTYPE KOERCE ABELSG
+aggcat IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ ELTAGG ELTAB ORDSET
+kl KERNEL2 ORDSET SETCAT BASTYPE KOERCE INT LIST NNI
+derham LALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+catdef LINEXP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+modmonom MODMONOM ORDSET SETCAT BASTYPE KOERCE
+naalgc MONADWU MONAD SETCAT BASTYPE KOERCE NNI INT SINT
+mring MRF2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+naalgc NARNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE MONAD
+newpoly NSUP2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+catdef OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON ABELSG
+dpolcat ODVAR DVARCAT ORDSET SETCAT BASTYPE KOERCE RETRACT
+alql OPQUERY ORDSET SETCAT BASTYPE KOERCE
+catdef ORDFIN ORDSET SETCAT BASTYPE KOERCE FINITE
+catdef ORDMON ORDSET SETCAT BASTYPE KOERCE MONOID SGROUP
+patmatch2 PATMATCH SETCAT BASTYPE KOERCE PATMAB KONVERT BOOLEAN RETRACT
+ INT LIST ILIST RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE
+catdef PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE SINT NNI INT
+perm PERMCAT GROUP MONOID SGROUP SETCAT BASTYPE KOERCE ORDSET FINITE
+aggcat PRQAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+aggcat QUAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+dpolcat SDVAR DVARCAT ORDSET SETCAT BASTYPE KOERCE RETRACT NNI INT
+aggcat SKAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+poly SUP2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+trigcat TRIGCAT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+laurent ULS2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+poly UP2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+equation1.spad.pamphlet (EVALAB IEVALAB)
+
+\end{verbatim}
+
+<<layer5>>=
+LAYER5=${OUT}/ATRIG.o ${OUT}/ATRIG-.o ${OUT}/BMODULE.o \
+ ${OUT}/CACHSET.o ${OUT}/CHARNZ.o ${OUT}/CHARZ.o \
+ ${OUT}/DVARCAT.o ${OUT}/DVARCAT-.o \
+ ${OUT}/ELEMFUN.o ${OUT}/ELEMFUN-.o ${OUT}/ESTOOLS2.o \
+ ${OUT}/EVALAB.o ${OUT}/EVALAB-.o \
+ ${OUT}/FCOMP.o ${OUT}/FEVALAB.o ${OUT}/FEVALAB-.o \
+ ${OUT}/FPATMAB.o ${OUT}/GROUP.o ${OUT}/GROUP-.o \
+ ${OUT}/IDPAM.o ${OUT}/IDPO.o ${OUT}/INCRMAPS.o \
+ ${OUT}/IXAGG.o ${OUT}/IXAGG-.o ${OUT}/KERNEL2.o \
+ ${OUT}/LALG.o ${OUT}/LALG-.o \
+ ${OUT}/LINEXP.o \
+ ${OUT}/MODMONOM.o ${OUT}/MONADWU.o ${OUT}/MONADWU-.o \
+ ${OUT}/MRF2.o ${OUT}/NARNG.o ${OUT}/NARNG-.o \
+ ${OUT}/NSUP2.o ${OUT}/OASGP.o ${OUT}/ODVAR.o \
+ ${OUT}/OPQUERY.o \
+ ${OUT}/ORDFIN.o ${OUT}/ORDMON.o ${OUT}/PATMATCH.o ${OUT}/PERMCAT.o \
+ ${OUT}/PDRING.o ${OUT}/PDRING-.o \
+ ${OUT}/SDVAR.o \
+ ${OUT}/SUP2.o \
+ ${OUT}/TRIGCAT.o ${OUT}/TRIGCAT-.o ${OUT}/ULS2.o ${OUT}/UP2.o
+
+@
+\subsection{Layer6}
+\begin{verbatim}
+ore AUTOMOR GROUP MONOID SGROUP SETCAT BASTYPE KOERCE ELTAB RING RNG
+ ABELGRP CABMON ABELMON ABELSG LMODULE INT SINT NNI
+aggcat BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+aggcat BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+carten CARTEN2 COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+eigen CHARPOL COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ NNI INT SINT PI
+gaussian COMPLEX2 COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+catdef DIFEXT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE DIFRING PDRING SINT NNI INT
+aggcat DLAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+aggcat ELAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT NNI INT ORDSET
+fspace ES1 ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB TYPE
+fspace ES2 ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB
+carten GRMOD SETCAT BASTYPE KOERCE COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+trigcat HYPCAT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE ELEMFUN
+modring MODRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE COMRING BMODULE RMODULE
+ BOOLEAN
+naalgc NASRING NARNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ MONAD MONADWU
+kl MKCHSET CACHSET ORDSET SETCAT BASTYPE KOERCE NNI INT
+catdef MODULE COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+catdef OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON ABELSG
+sortpak SORTPAK TYPE IXAGG HOAGG AGG SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ ELTAGG ELTAB SINT NNI INT BOOLEAN PI ORDSET URAGG RCAGG
+fmod ZMOD COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ FINITE KONVERT STEP SINT INT PI NNI INS EUCDOM
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+fmod.spad.pamphlet (ZMOD)
+sortpak.spad.pamphlet (SORTPAK)
+\end{verbatim}
+
+<<layer6>>=
+LAYER6=${OUT}/AUTOMOR.o ${OUT}/BGAGG.o ${OUT}/BGAGG-.o \
+ ${OUT}/BRAGG.o ${OUT}/BRAGG-.o \
+ ${OUT}/CARTEN2.o ${OUT}/CHARPOL.o ${OUT}/COMPLEX2.o \
+ ${OUT}/DIFEXT.o ${OUT}/DIFEXT-.o ${OUT}/DLAGG.o \
+ ${OUT}/ELAGG.o ${OUT}/ELAGG-.o ${OUT}/ES1.o ${OUT}/ES2.o \
+ ${OUT}/GRMOD.o ${OUT}/GRMOD-.o \
+ ${OUT}/HYPCAT.o ${OUT}/HYPCAT-.o ${OUT}/MKCHSET.o \
+ ${OUT}/MODRING.o ${OUT}/MODULE.o ${OUT}/MODULE-.o \
+ ${OUT}/NASRING.o ${OUT}/NASRING-.o \
+ ${OUT}/OAMON.o ${OUT}/SORTPAK.o \
+ ${OUT}/ZMOD.o
+
+@
+\subsection{Layer7}
+\begin{verbatim}
+catdef ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+tree BTCAT BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB NNI INT
+xpoly FMCAT BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE RMODULE RETRACT MODULE
+carten GRALG GRMOD SETCAT BASTYPE KOERCE RETRACT COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+indexedp IDPOAM OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON ABELSG
+ IDPC INT LIST ILIST BOOLEAN
+free IFAMON CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE FAMONC RETRACT
+ INT LIST ILIST OAMON OASGP ORDSET
+catdef OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON ABELSG
+ CABMON
+aggcat PRQAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+aggcat QUAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+aggcat SKAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+\end{verbatim}
+
+<<layer7>>=
+LAYER7=${OUT}/ALGEBRA.o ${OUT}/ALGEBRA-.o ${OUT}/BTCAT.o ${OUT}/BTCAT-.o \
+ ${OUT}/FMCAT.o \
+ ${OUT}/IDPOAM.o ${OUT}/IFAMON.o ${OUT}/GRALG.o ${OUT}/GRALG-.o \
+ ${OUT}/OCAMON.o ${OUT}/PRQAGG.o ${OUT}/QUAGG.o ${OUT}/SKAGG.o
+
+@
+\subsection{Layer8}
+\begin{verbatim}
+tree BSTREE BTCAT BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ORDSET INT ILIST ILIST
+tree BTOURN BTCAT BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ORDSET INT LIST ILIST
+card CARD ORDSET SETCAT BASTYPE KOERCE ABELMON ABELSG MONOID SGROUP
+ RETRACT BOOLEAN INT NNI INS EUCDOM UFD GCDDOM INTDOM ALGEBRA
+ DIFRING ORDRING MODULE RING ABELGRP
+numeric DRAWHACK ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER KONVERT
+aggcat DQAGG SKAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB QUAGG
+manip FACTFUNC INTDOM COMRING RING RNG CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER INT LIST ILIST INS EUCDOM UFD GCDDOM NNI LSAGG
+ STAGG ELAGG
+fr FR2 INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER
+fraction FRAC2 INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER
+fr FRUTIL INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER INT LIST ILIST PI NNI LSAGG STAGG
+fortcat FMTC INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER ORDSET RETRACT
+lodop MLO RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+naalgc NAALG NARNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ MONAD MODULE BMODULE LMODULE RMODULE COMRING RING RNG
+ SGROUP MONOID PI NNI INT
+catdef OAGROUP OCAMON OAMON OAGSP ORDSET SETCAT BASTYPE KOERCE ABELMON
+ ABELSG CABMON ABELGRP
+catdef OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON
+ ABELSG CABMON
+opalg OP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE RETRACT ELTAB CHARZ CHARNZ ALGEBRA
+ MODULE BMODULE RMODULE COMRING ORDSET
+complet ORDCOMP2 SETCAT BASTYPE KOERCE SINT INS EUCDOM UFD GCDDOM INTDOM
+ ALGEBRA MODULE DIFRING ORDRING RING ABELGRP ABELMON MONOID
+catdef PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER
+random RANDSRC INT PI NNI INS EUCDOM UFD GCDDOM INTDOM ALGEBRA DIFRING
+ ORDRING MODULE RING ABELGRP ABELMON
+seg UNISEG2 TYPE ORDRING OAGROUP OCAMON OAMON OASGP ORDSET SETCAT
+ BASTYPE KOERCE ABELMON ABELSG CABMON ABELGRP RING RNG
+ SGROUP MONOID LMODULE
+xpoly XALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+taylor ITAYLOR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE INTDOM COMRING BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+card.spad.pamphlet (CARD)
+fortcat.spad.pamphlet (FORTFN FMC FORTCAT FVC FMTC FMFUN FVFUN)
+\end{verbatim}
+
+<<layer8>>=
+LAYER8=${OUT}/BSTREE.o ${OUT}/BTOURN.o ${OUT}/CARD.o \
+ ${OUT}/DRAWHACK.o ${OUT}/DQAGG.o ${OUT}/FACTFUNC.o \
+ ${OUT}/FMTC.o ${OUT}/FR2.o ${OUT}/FRAC2.o ${OUT}/FRUTIL.o \
+ ${OUT}/ITAYLOR.o \
+ ${OUT}/MLO.o ${OUT}/NAALG.o ${OUT}/NAALG-.o \
+ ${OUT}/OAGROUP.o ${OUT}/OAMONS.o \
+ ${OUT}/OP.o ${OUT}/ORDCOMP2.o ${OUT}/PID.o ${OUT}/RANDSRC.o \
+ ${OUT}/UNISEG2.o ${OUT}/XALG.o
+
+@
+\subsection{Layer9}
+\begin{verbatim}
+polycat AMR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE COMRING ALGEBRA
+ MODULE CHARZ CHARNZ INTDOM ENTIRER OAMON OASGP ORDSET INS
+ UFD GCDDOM EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON DIFRING
+ KONVERT RETRACT LINEXP PATMAB CFCAT REAL STEP
+degred DEGRED RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE INTDOM COMRING BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET BOOLEAN INT LIST ILIST INS
+ EUCDOM UFD GCDDOM DIFRING PI NNI INS UFD GCDDOM EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP SINT
+ffcat DLP MONOID SGROUP SETCAT BASTYPE KOERCE FINITE INT NNI BOOLEAN
+ SINT PI ABELSG OAMONS OCAMON OAMON OASGP ORDSET ABELMON
+ CABMON
+derham EAB ORDSET SETCAT BASTYPE KOERCE INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP OM INT LIST ILIST
+ BOOLEAN NNI SINT
+tools ESTOOLS1 ORDRING OAGROUP OCAMON OAMON OASGP ORDSET SETCAT BASTYPE
+ KOERCE ABELMON ABELSG CABMON ABELGRP RING RNG SGROUP
+ MONOID LMODULE
+free FAGROUP ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE MODULE
+ BMODULE LMODULE RMODULE FAMONC RETRACT ORDSET INS UFD
+ GCDDOM INTDOM COMRING RING RNG SGROUP MONOID ALGEBRA
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP DIFRING KONVERT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ INT LIST ILIST BOOLEAN OM
+free FAMONOID FAMONC CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE RETRACT
+ OAMONS OCAMON OAMON OASGP ORDSET NNI INT MONOID SGROUP
+catdef FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING BOOLEAN
+ INT NNI
+aggcat FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET INS UFD GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP OM
+catdef FLINEXP INS UFD GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET DIFRING KONVERT RETRACT PATMAB CFCAT REAL
+ CHARZ STEP
+retract FRETRCT TYPE INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP
+fourier FSERIES ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ COMRING ORDSET PI NNI INT INS UFD GCDDOM INTDOM ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ LIST
+forttyp FT SETCAT BASTYPE KOERCE INS UFD GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP INT LIST ILIST
+ BOOLEAN
+indexedp IDPAG OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON IDPC INT LIST ILIST
+indexedp IDPOAMS OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON IDPC INT LIST ILIST
+complet INFINITY INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+fraction LA ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET COMRING
+lodop OMLO MLO RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ DIFRING COMRING
+special ORTHPOL COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ NNI INT SINT PI ALGEBRA MODULE INS UFD GCDDOM INTDOM
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP
+padic PADICCT EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER CHARZ
+expr PMASS INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+expr PMPRED TYPE INS UFD GCDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+product PRODUCT SETCAT BASTYPE KOERCE FINITE MONOID SGROUP ABELMON ABELSG
+ CABMON GROUP ABELGRP OAMONS OCAMON OAMON OASGP ORDSET
+ NNI INT
+newpoint PTFUNC2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE INS UFD GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP OM
+sf RADCAT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP
+radix RADUTIL INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+retract RATRET RETRACT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING
+ KONVERT LINEXP PATMAB CFCAT REAL CHARZ STEP
+xpoly XFALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE XALG BMODULE RMODULE ALGEBRA MODULE
+ RETRACT
+puiseux UPXS2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE INS UFD GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP
+lindep ZLINDEP LINEXP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE INS UFD GCDDOM INTDOM COMRING
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT PATMAB CFCAT REAL CHARZ STEP OM
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+degred.spad.pamphlet (DEGRED)
+indexedp.spad.pamphlet (IDPC IDPO IDPAM IDPOAM IDPOAMS IDPAG)
+product.spad.pamphlet (PRODUCT)
+retract.spad.pamphlet (RETRACT FRETRCT RATRET)
+sf.spad.pamphlet (REAL RADCAT RNS FPS DFLOAT)
+\end{verbatim}
+
+<<layer9>>=
+LAYER9=${OUT}/AMR.o ${OUT}/AMR-.o ${OUT}/DEGRED.o \
+ ${OUT}/DLP.o ${OUT}/EAB.o \
+ ${OUT}/ESTOOLS1.o \
+ ${OUT}/FAGROUP.o \
+ ${OUT}/FAMONOID.o ${OUT}/FIELD.o ${OUT}/FIELD-.o \
+ ${OUT}/FLAGG.o ${OUT}/FLAGG-.o \
+ ${OUT}/FLINEXP.o ${OUT}/FLINEXP-.o \
+ ${OUT}/FRETRCT.o ${OUT}/FRETRCT-.o \
+ ${OUT}/FSERIES.o ${OUT}/FT.o ${OUT}/IDPAG.o ${OUT}/IDPOAMS.o \
+ ${OUT}/INFINITY.o ${OUT}/LA.o ${OUT}/OMLO.o \
+ ${OUT}/ORTHPOL.o ${OUT}/PRODUCT.o \
+ ${OUT}/PADICCT.o ${OUT}/PMPRED.o \
+ ${OUT}/PMASS.o ${OUT}/PTFUNC2.o \
+ ${OUT}/RADCAT.o ${OUT}/RADCAT-.o \
+ ${OUT}/RATRET.o ${OUT}/RADUTIL.o ${OUT}/UPXS2.o ${OUT}/XFALG.o \
+ ${OUT}/ZLINDEP.o
+
+@
+\subsection{Layer10}
+\begin{verbatim}
+aggcat A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET INS
+ UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP OM BOOLEAN SINT INT NNI LIST ILIST LSAGG
+ STAGG URAGG RCAGG ELAGG
+array2 ARR2CAT FLAGG LNAGG IXAGG ELTAGG CLAGG KONVERT ORDSET BOOLEAN
+ NNI INT SINT LIST ILIST INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM
+asp ASP34 FMC FORTCAT TYPE KOERCE BOOLEAN INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP FPS RNS FIELD DIVRING RADCAT NNI
+ INT OM
+tree BBTREE BTCAT BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB BOOLEAN LSAGG STAGG URAGG LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST NNI
+ SINT PI
+functions BFUNCT SETCAT BASTYPE KOERCE ORDSET DFLOAT FPS RNS FIELD EUCDOM
+ UFD GCDDOM DIVRING INTDOM ALGEBRA DIFRING ORDRING INT
+padic BPADIC BOOLEAN PADICCT EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER CHARZ
+ INS UFD OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL STEP
+tree BTREE BTCAT BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB INT LIST ILIST BOOLEAN LSAGG STAGG URAGG
+ LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+cra CRAPACK EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST
+ NNI
+bags DEQUEUE DQAGG SKAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB QUAGG INT LIST ILIST LSAGG STAGG ELAGG
+ FLAGG URAGG INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM LNAGG RCAGG IXAGG ELTAGG
+ ELTAGG ELTAB CLAGG FLAGG ELAGG
+alql DLIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ORDSET ELAGG INT LIST ILIST INS UFD
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP OM
+d01routine D01GBFA NUMINT SETCAT BASTYPE KOERCE DFLOAT PI NNI INT FPS RNS
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT
+ RADCAT PATMAB CHARZ SINT LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM LIST ILIST INS DIFRING
+d02routine D02EJFA ODECAT SETCAT BASTYPE KOERCE NNI INT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM LIST ILIST
+ DFLOAT FPS RNS FIELD EUCDOM UFD GCDDOM DIVRING INTDOM
+ ALGEBRA DIFRING ORDRING PID COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE MODULE ENTIRER DIVRING OAGROUP OCAMON OAMON
+ OASGP REAL RETRACT RADCAT PATMAB CHARZ PI
+d03routine D03FAFA PDECAT SETCAT BASTYPE KOERCE LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST NNI
+drawpak DRAWCX DFLOAT PI NNI INT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ SINT LIST ILIST
+draw DRAWPT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST
+ INS EUCDOM UFD DIFRING DFLOAT PI NNI SINT
+polycat FAMR OAMON OASGP ORDSET NNI INT LIST ILIST PI BOOLEAN FIELD
+ EUCDOM PID GCDDOM UFD DIVRING
+free FGROUP GROUP MONOID SGROUP SETCAT BASTYPE KOERCE RETRACT INS UFD
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET DIFRING KONVERT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP INT LIST ILIST BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM
+aggcat2 FLAGG2 TYPE FLAGG LNAGG IXAGG HOAGG AGG SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET LSAGG
+ STAGG URAGG RCAGG ELAGG INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM INT
+defaults FLASORT TYPE FLAGG LNAGG IXAGG HOAGG AGG SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET INS UFD
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP OM INT PI NNI SINT BOOLEAN
+poly FM BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE RMODULE IDPC MODULE RING RNG SGROUP MONOID
+ ORDSET ENTIRER BOOLEAN INT LIST ILIST LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ELAGG OM
+free FMONOID MONOID SGROUP SETCAT BASTYPE KOERCE RETRACT ORDSET OAMONS
+ OCAMON OAMON OASGP ABELMON ABELSG CABMON NNI INT LIST
+ ILIST LSAGG STAGG ELAGG FLAGG URAGG RCAGG HOAGG AGG TYPE
+ EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ELAGG OM BOOLEAN
+xpoly FM1 FMCAT BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE RMODULE RETRACT MODULE ORDSET RING RNG
+ SGROUP MONOID LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ELAGG OM INT LIST ILIST NNI BOOLEAN
+ffcat FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARNZ INT INS
+multpoly INDE OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON IDPC NNI INT LIST ILIST LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM
+padic IPADIC PADICCT EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER CHARZ INT
+ NNI INS SINT BOOLEAN PI UFD OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL STEP LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM
+intfact IROOT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP PI NNI INT
+ BOOLEAN SINT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM
+ LIST ILIST
+intaux IR2 FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+xlpoly LEXP GROUP MONOID SGROUP SETCAT BASTYPE KOERCE ORDSET COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG LMODULE BMODULE
+ RMODULE MODULE INT LIST ILIST NNI LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG KONVERT FLAGG ELAGG OM PI
+xlpoly LIECAT COMRING RING RNG SGROUP MONOID FIELD EUCDOM PID GCDDOM
+ INTDOM ALGEBRA ENTIRER UFD DIVRING
+list LIST2 LSAGG STAGG URAGG RCAGG HOAGG AGG SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ORDSET ELAGG
+list LIST2MAP SETCAT BASTYPE KOERCE TYPE INT LIST ILIST LSAGG STAGG ELAGG
+ FLAGG INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM
+free LMOPS ABELMON ABELSG SETCAT BASTYPE KOERCE RETRACT INT LIST
+ ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG
+ OM INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP DIFRING LINEXP PATMAB CFCAT REAL CHARZ STEP NNI
+ BOOLEAN
+stream LZSTAGG BOOLEAN INT LIST ILIST NNI SINT LSAGG FLAGG ORDSET ELAGG OM
+xlpoly MAGMA ORDSET SETCAT BASTYPE KOERCE RETRACT BOOLEAN INT LIST LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM ILIST PI NNI
+mesh MESH INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM FPS RNS
+ FIELD DIVRING RADCAT INT LIST DFLOAT PI NNI SINT ILIST
+ BOOLEAN
+modring MODFIELD FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+opalg MODOP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE RETRACT ELTAB CHARZ CHARNZ
+ ALGEBRA MODULE BMODULE RMODULE COMRING LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ CLAGG KONVERT FLAGG ORDSET ELAGG INT LIST ILIST OM ES
+ SINT NNI
+moebius MOEBIUS GROUP MONOID SGROUP SETCAT BASTYPE KOERCE FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING INT LIST ILIST BOOLEAN LSAGG STAGG ELAGG FLAGG
+ LNAGG RCAGG IXAGG
+mring MRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE RETRACT CHARZ CHARNZ ALGEBRA MODULE
+ BMODULE RMODULE FINITE COMRING INT LIST ILIST NNI SINT PI
+ BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET
+ ELAGG OM GROUP ORDMON
+alql MTHING ORDSET SETCAT BASTYPE KOERCE INT LIST ILIST BOOLEAN LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM
+lodop NCODIV MLO RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ INT BOOLEAN
+contfrac NCNTFRAC FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ INS OINTDOM DIFRING
+ LINEXP CFCAT STEP INT
+tube NUMTUBE PSCURVE KOERCE DFLOAT FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT
+ LIST ILIST NNI PI BOOLEAN
+lodop ODR SETCAT BASTYPE KOERCE BMODULE LMODULE ABELGRP CABMON ABELMON
+ ABELSG RMODULE DIFRING RING RNG SGROUP MONOID FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING ALGEBRA MODULE ENTIRER UFD DIVRING
+ PDRING INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+xpoly OFMONOID ORDMON ORDSET SETCAT BASTYPE KOERCE MONOID SGROUP RETRACT
+ OAMONS OCAMON OAMON OASGP ABELMON ABELSG CABMON NNI INT
+ LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG
+ ELAGG OM BOOLEAN
+complet ONECOMP SETCAT BASTYPE KOERCE FRETRCT RETRACT ABELGRP CABMON
+ ABELMON ABELSG ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET RING RNG SGROUP MONOID LMODULE BOOLEAN INT INS
+ UFD GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM DIFRING KONVERT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP
+complet ORDCOMP SETCAT BASTYPE KOERCE FRETRCT RETRACT ABELGRP CABMON
+ ABELMON ABELSG ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ RING RNG SGROUP MONOID LMODULE BOOLEAN SINT INT INS UFD
+ GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM DIFRING KONVERT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP
+ore OREPCAT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE FRETRCT
+ RETRACT ALGEBRA MODULE NNI INT LIST ILIST BOOLEAN
+ INTDOM COMRING ENTIRER GCDDOM FIELD EUCDOM PID UFD
+ DIVRING INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET DIFRING KONVERT LINEXP PATMAB CFCAT REAL CHARZ STEP
+wtpol OWP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE ALGEBRA MODULE BMODULE
+ RMODULE COMRING FIELD EUCDOM PID GCDDOM INTDOM ENTIRER
+ UFD DIVRING
+padic PADIC BOOLEAN PADICCT EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ CHARZ INS UFD OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL STEP
+partperm PARTPERM INT LIST ILIST SINT NNI BOOLEAN LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+patmatch1 PATLRES SETCAT BASTYPE KOERCE LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ORDSET ELAGG BOOLEAN
+pattern PATTERN2 SETCAT BASTYPE KOERCE LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ORDSET ELAGG OM INT LIST ILIST
+xlpoly PBWLB ORDSET SETCAT BASTYPE KOERCE RETRACT INT LIST ILIST LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM
+pgrobner PGROEB GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST
+tree PENDTREE BRAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB INT LIST ILIST LSAGG STAGG ELAGG FLAGG URAGG LNAGG
+ RCAGG IXAGG CLAGG HOAGG ORDSET AGG ELTAGG SETCAT BASTYPE
+permgrps PGE INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP SINT NNI INT
+ LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM PI
+pinterp PINTERP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+plottool PLOTTOOL DFLOAT INT LIST ILIST FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT
+ RADCAT PATMAB CHARZ
+pfr PFR FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ INT LIST ILIST BOOLEAN LSAGG STAGG ELAGG FLAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG KONVERT FLAGG ORDSET ELAGG OM PI NNI INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP
+patmatch1 PMDOWN SETCAT BASTYPE KOERCE PATMAB RETRACT INT LIST ILIST LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+patmatch2 PMINS INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST NNI
+patmatch1 PMLSAGG SETCAT BASTYPE KOERCE PATMAB LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ORDSET ELAGG BOOLEAN INT LIST ILIST
+prtition PRTITION OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON
+ ABELSG CABMON INT LIST ILIST LSAGG STAGG ELAGG FLAGG
+ BOOLEAN NNI LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INS
+ UFD GCDDOM INTDOM COMRING RING RNG ABELGRP SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP
+pscat PSCAT AMR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER OAMON OASGP
+ ORDSET INT INS UFD GCDDOM EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL STEP FIELD DIVRING
+patmatch1 PMTOOLS SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE ORDSET KONVERT RETRACT LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST NNI
+clifford QFORM ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+bags QUEUE QUAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB INT LIST ILIST LSAGG STAGG URAGG RCAGG LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+kl SCACHE CACHSET ORDSET SETCAT BASTYPE KOERCE INT LIST BOOLEAN ILIST
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM SINT
+seg SEG SEGCAT TYPE SETCAT BASTYPE KOERCE SEGXCAT BOOLEAN ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET ABELMON ABELSG CABMON
+ ABELGRP RING RNG SGROUP MONOID LMODULE LIST ILIST LSAGG
+ STAGG URAGG RCAGG HOAGG AGG EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM
+seg SEG2 TYPE ORDRING OAGROUP OCAMON OAMON OASGP ORDSET SETCAT
+ BASTYPE KOERCE ABELMON ABELSG CABMON ABELGRP RING RNG
+ SGROUP MONOID LMODULE INT LIST BOOLEAN ILIST LSAGG STAGG
+ URAGG RCAGG HOAGG AGG EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ELAGG OM
+sex SEXOF SEXCAT SETCAT BASTYPE KOERCE INT LIST ILIST BOOLEAN LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM NNI
+bags STACK SKAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB INT LIST ILIST LSAGG STAGG URAGG RCAGG LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+sttaylor STTAYLOR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE SINT NNI INT LIST ILIST LSAGG
+ STAGG ALGEBRA MODULE BMODULE RMODULE INS UFD GCDDOM INTDOM
+ COMRING ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP FIELD DIVRING
+tableau TABLBUMP ORDSET SETCAT BASTYPE KOERCE INT LIST BOOLEAN ILIST LSAGG
+ STAGG PI NNI ELAGG FLAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+tableau TABLEAU SETCAT BASTYPE KOERCE INT LIST ILIST LSAGG SINT NNI STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+space TOPSP FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ
+trigcat TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ PI NNI INT FIELD EUCDOM PID GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+tube TUBE PSCURVE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ BOOLEAN
+setorder UDPO SETCAT BASTYPE KOERCE INT LIST ILIST BOOLEAN LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM
+seg UNISEG SEGCAT TYPE SETCAT BASTYPE KOERCE SEGXCAT INT BOOLEAN
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET ABELMON ABELSG
+ CABMON ABELGRP RING RNG SGROUP MONOID LMODULE LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG LNAGG RCAGG IXAGG CLAGG HOAGG
+ AGG ELTAGG
+viewpack VIEW INT LIST FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM ILIST SINT PI NNI
+catdef VSPACE FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+xpoly XPOLYC XFALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE XALG BMODULE RMODULE ALGEBRA
+ MODULE RETRACT
+xpoly XPR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE XALG BMODULE RMODULE ALGEBRA
+ MODULE FMCAT RETRACT COMRING ORDMON ORDSET LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM INT LIST ILIST
+ BOOLEAN NNI FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD
+ DIVRING
+\end{verbatim}
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+complet.spad.pamphlet (ORDCOMP ORDCOMP2 ONECOMP ONECOMP2 INFINITY)
+cra.spad.pamphlet (CRAPACK)
+defaults.spad.pamphlet (REPSQ REPDB FLASORT)
+drawpak.spad.pamphlet (DRAWCX)
+free.spad.pamphlet (LMOPS FMONOID FGROUP FAMONC IFAMON FAMONOID FAGROUP)
+fourier.spad.pamphlet (FCOMP FSERIES)
+functions.spad.pamphlet (BFUNCT)
+mesh.spad.pamphlet (MESH)
+moebius.spad.pamphlet (MOEBIUS)
+mring.spad.pamphlet (MRING MRF2)
+opalg.spad.pamphlet (MODOP OP)
+partperm.spad.pamphlet (PARTPERM)
+pgrobner.spad.pamphlet (PGROEB)
+plottool.spad.pamphlet (PLOTTOOL)
+setorder.spad.pamphlet (UDPO UDVO)
+sttaylor.spad.pamphlet (STTAYLOR)
+tableau.spad.pamphlet (TABLBUMP TABLEAU)
+viewpack.spad.pamphlet (VIEW)
+\end{verbatim}
+
+<<layer10>>=
+LAYER10=${OUT}/A1AGG.o ${OUT}/A1AGG-.o \
+ ${OUT}/ARR2CAT.o ${OUT}/ARR2CAT-.o \
+ ${OUT}/ASP34.o ${OUT}/BBTREE.o \
+ ${OUT}/BFUNCT.o ${OUT}/BPADIC.o ${OUT}/BTREE.o \
+ ${OUT}/CRAPACK.o \
+ ${OUT}/DEQUEUE.o ${OUT}/DLIST.o ${OUT}/DRAWCX.o \
+ ${OUT}/D01GBFA.o ${OUT}/D02EJFA.o \
+ ${OUT}/D03FAFA.o ${OUT}/DRAWPT.o \
+ ${OUT}/FAMR.o ${OUT}/FAMR-.o \
+ ${OUT}/FLASORT.o ${OUT}/FLAGG2.o ${OUT}/FGROUP.o \
+ ${OUT}/FM.o ${OUT}/FM1.o ${OUT}/FPC.o ${OUT}/FPC-.o \
+ ${OUT}/FMONOID.o \
+ ${OUT}/INDE.o ${OUT}/IPADIC.o \
+ ${OUT}/IROOT.o ${OUT}/IR2.o \
+ ${OUT}/LEXP.o ${OUT}/LIECAT.o ${OUT}/LIECAT-.o \
+ ${OUT}/LIST2.o ${OUT}/LIST2MAP.o ${OUT}/LMOPS.o \
+ ${OUT}/LZSTAGG.o ${OUT}/LZSTAGG-.o ${OUT}/MAGMA.o \
+ ${OUT}/MESH.o ${OUT}/MOEBIUS.o \
+ ${OUT}/MODFIELD.o ${OUT}/MODOP.o ${OUT}/MRING.o ${OUT}/MTHING.o \
+ ${OUT}/NCNTFRAC.o \
+ ${OUT}/NCODIV.o ${OUT}/NUMTUBE.o ${OUT}/ODR.o \
+ ${OUT}/OFMONOID.o ${OUT}/ONECOMP.o \
+ ${OUT}/ORDCOMP.o ${OUT}/OREPCAT.o ${OUT}/OREPCAT-.o \
+ ${OUT}/OWP.o \
+ ${OUT}/PADIC.o ${OUT}/PATTERN2.o \
+ ${OUT}/PATLRES.o ${OUT}/PARTPERM.o ${OUT}/PBWLB.o ${OUT}/PENDTREE.o \
+ ${OUT}/PGE.o \
+ ${OUT}/PGROEB.o ${OUT}/PINTERP.o ${OUT}/PLOTTOOL.o \
+ ${OUT}/PFR.o ${OUT}/PMDOWN.o \
+ ${OUT}/PRTITION.o \
+ ${OUT}/PMINS.o ${OUT}/PMLSAGG.o ${OUT}/PMTOOLS.o \
+ ${OUT}/PSCAT.o ${OUT}/PSCAT-.o ${OUT}/QFORM.o ${OUT}/QUEUE.o \
+ ${OUT}/SCACHE.o ${OUT}/SEG.o \
+ ${OUT}/SEG2.o ${OUT}/SEXOF.o ${OUT}/STACK.o ${OUT}/STTAYLOR.o \
+ ${OUT}/TABLBUMP.o ${OUT}/TABLEAU.o \
+ ${OUT}/TOPSP.o ${OUT}/TRANFUN.o ${OUT}/TRANFUN-.o \
+ ${OUT}/TUBE.o ${OUT}/UDPO.o ${OUT}/UNISEG.o \
+ ${OUT}/VIEW.o ${OUT}/VSPACE.o ${OUT}/VSPACE-.o \
+ ${OUT}/XPOLYC.o ${OUT}/XPR.o
+
+@
+\subsection{Layer11}
+\begin{verbatim}
+ore APPLYORE RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE OREPCAT BMODULE RMODULE
+ FRETRCT RETRACT ALGEBRA MODULE SINT NNI INT
+array1 ARRAY1 A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET INT
+ LSAGG STAGG URAGG RCAGG ELAGG OM LIST ILIST NNI INS UFD
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP
+array1 ARRAY12 A1AGG FLAGG LNAGG IXAGG HOAGG AGG SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+array2 ARRAY2 ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ A1AGG FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT ORDSET
+ INT
+bags ASTACK SKAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB INT A1AGG FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT ORDSET ELAGG LIST ILIST SINT NNI LSAGG STAGG ELAGG
+ URAGG RCAGG HOAGG INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM
+aggcat BTAGG ORDSET SETCAT BASTYPE KOERCE LOGIC A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+combinat COMBINAT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP NNI INT OM
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG ELAGG SINT PI
+stream CSTTOOLS TYPE LZSTAGG STAGG URAGG RCAGG HOAGG AGG SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT SINT NNI INT
+d01routine D01FCFA NUMINT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ SINT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST NNI DIFRING TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ PI DFLOAT INS
+e04routine E04MBFA OPTCAT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ DIFRING OM TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN INT
+ NNI LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG
+ DFLOAT PI INS BOOLEAN
+array1 FARRAY A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ ELAGG INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP OM
+xlpoly FLALG LIECAT MODULE BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE RMODULE
+galutil GALUTIL RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ INT NNI
+ PI A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG ELAGG
+bags HEAP PRQAGG BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ORDSET INT LSAGG STAGG URAGG RCAGG LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM LIST ILIST NNI
+ INS EUCDOM UFD GCDDOM INTDOM ALGEBRA DIFRING ORDRING
+ MODULE RING ABELGRP ABELMON PI A1AGG SINT
+array1 IARRAY1 A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ SINT NNI INT INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM
+array2 IARRAY2 ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ A1AGG FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT ORDSET
+array1 IFARRAY A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ ELAGG BOOLEAN PRIMARR LSAGG STAGG URAGG RCAGG OM LIST
+ ILIST NNI SINT INS EUCDOM UFD GCDDOM INTDOM ALGEBRA
+ DIFRING MODULE RING ABELGRP ABELMON PI COMRING RNG CABMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ENTIRER PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP
+interval INTCAT GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN RADCAT RETRACT
+numtheor INTHEORY NNI INT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP PI A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG ELAGG BOOLEAN LIST ILIST
+ffx IRREDFFX FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING CHARNZ FINITE STEP DIFRING INT PI NNI
+ BOOLEAN
+trigcat LFCAT PRIMCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+lodo LODOCAT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE OREPCAT BMODULE RMODULE
+ FRETRCT RETRACT ALGEBRA MODULE ELTAB NNI INT BOOLEAN
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+xlpoly LWORD ORDSET SETCAT BASTYPE KOERCE RETRACT BOOLEAN LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG OM INT LIST ILIST NNI PI
+ A1AGG SINT
+matcat MATCAT ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ ORDSET NNI INT BOOLEAN SINT LIST ILIST LSAGG STAGG URAGG
+ RCAGG ELAGG OM INS UFD GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP FIELD DIVRING
+matstor MATSTOR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE NNI INT SINT PRIMARR A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG KONVERT ORDSET BOOLEAN
+ore OREPCTO RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE OREPCAT BMODULE RMODULE
+ FRETRCT RETRACT ALGEGRA MODULE BOOLEAN NNI INT SINT
+ INTDOM COMRING ENTIRER FIELD EUCDOM PID GCDDOM UFD DIVRING
+ore ORESUP OREPCAT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ FRETRCT RETRACT ALGEBRA MODULE INTDOM COMRING ENTIRER
+ FIELD EUCDOM PID GCDDOM UFD DIVRING INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP
+ore OREUP OREPCAT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ FRETRCT RETRACT ALGEBRA MODULE NNI INT FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT LINEXP PATMAB CFCAT REAL CHARZ STEP
+plot3d PLOT3D PSCURVE KOERCE BOOLEAN INT DFLOAT FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ LIST
+ ILIST NNI PI LSAGG STAGG ELAGG FLAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG OM SINT
+ DIFRING INS OINTDOM LINEXP CFCAT STEP TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN
+poly PR FAMR AMR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT
+ RETRACT OAMON OASGP ORDSET LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ELAGG OM INT LIST ILIST BOOLEAN NNI FIELD
+ EUCDOM PID GCDDOM UFD DIVRING INS OINTDOM ORDRING OAGROUP
+ OCAMON DIFRING LINEXP PATMAB CFCAT REAL STEP
+lodof PREASSOC INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER LODOCAT OREPCAT FRETRCT RETRACT
+ ELTAB NNI INT PI PRIMARR SINT A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG CLAGG KONVERT ORDSET
+array1 PRIMARR2 TYPE A1AGG FLAGG LNAGG IXAGG HOAGG AGG SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+odeef REDORDER FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ LODOCAT OREPCAT FRETRCT RETRACT ELTAB INT INS PRIMARR LIST
+ ILIST LSAGG STAGG ELAGG BOOLEAN NNI A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG CLAGG KONVERT ORDSET
+ SINT
+aggcat SRAGG A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP OM NNI INT
+stream STREAM LZSTAGG STAGG URAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT INT LIST ILIST SINT NNI BOOLEAN LSAGG FLAGG ORDSET
+ ELAGG OM INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP
+prtition SYMPOLY OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON
+ ABELSG CABMON FAMR AMR RING RNG ABELGRP SGROUP MONOID
+ LMODULE BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ
+ CHARNZ INTDOM ENTIRER FRETRCT RETRACT INT LIST ILIST
+ BOOLEAN KONVERT INS UFD GCDDOM EUCDOM PID OINTDOM ORDRING
+ OAGROUP DIFRING LINEXP PATMAB CFCAT REAL STEP FIELD DIVRING
+mts TS MTSCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE PSCAT AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER IEVALAB EVALAB RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN SINT NNI INT BOOLEAN INS UFD GCDDOM
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL
+ STEP FIELD DIVRING
+ituple TUPLE KOERCE SETCAT BASTYPE TYPE A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET INT
+ PRIMARR NNI BOOLEAN INS UFD GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM
+pscat UPSCAT PSCAT OAMON OASGP ORDSET INT LIST ILIST LSAGG
+vector VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ ABELSG NNI INT ABELMON ABELGRP CABMON MONOID SGROUP RING
+ RNG LMODULE INS UFD GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP OM PI RADCAT
+xpoly XDPOLY FMCAT BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE RMODULE RETRACT MODULE XPOLYC XFALG RING RNG
+ SGROUP MONOID XALG ALGEBRA ORDMON ORDSET INT LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG COMRING NNI RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ELAGG OM BOOLEAN
+xlpoly XEXPPKG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE ORDSET
+ XPOLYC XFALG XALG ALGEBRA RETRACT SINT NNI INT INS UFD
+ GCDDOM INTDOM COMRING ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING KONVERT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP PI
+xlpoly XPBWPOLY XPOLYC XFALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE XALG BMODULE RMODULE
+ ALGEBRA MODULE RETRACT FMCAT COMRING ORDSET INT BOOLEAN
+ LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG
+ OM INS UFD GCDDOM INTDOM ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING LINEXP PATMAB CFCAT REAL
+ CHARZ STEP
+xpoly XPOLY XPOLYC XFALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE XALG BMODULE RMODULE
+ ALGEBRA MODULE RETRACT COMRING
+xpoly XRPOLY XPOLYC XFALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE XALG BMODULE RMODULE
+ ALGEBRA MODULE RETRACT ORDSET BOOLEAN LIST ILIST LSAGG
+ STAGG ELAGG FLAGG COMRING URAGG LNAGG RCAGG IXAGG CLAGG
+ HOAGG ORDSET AGG ELTAGG SETCAT BASTYPE TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM
+ffcat XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ RETRACT VSPACE CHARZ FPC CHARNZ FINITE BOOLEAN NNI INT
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+array1.spad.pamphlet (PRIMARR PRIMARR2 TUPLE IFARRAY FARRAY IARRAY1 ARRAY1
+ ARRAY12)
+bags.spad.pamphlet (STACK ASTACK QUEUE DEQUEUE HEAP)
+combinat.spad.pamphlet (COMBINAT)
+ffx.spad.pamphlet (IRREDFFX)
+galutil.spad.pamphlet (GALUTIL)
+matstor.spad.pamphlet (MATSTOR)
+ore.spad.pamphlet (OREPCAT APPLYORE AUTOMOR OREPCTO ORESUP OREUP)
+plot3d.spad.pamphlet (PLOT3D)
+prtition.spad.pamphlet (PRTITION SYMPOLY)
+stream.spad.pamphlet (LZSTAGG CSTTOOLS STREAM STREAM1 STREAM2 STREAM3)
+trigcat.spad.pamphlet (ELEMFUN AHYP ATRIG HYPCAT TRANFUN TRIGCAT PRIMCAT
+ LFCAT CFCAT SPFCAT)
+xlpoly.spad.pamphlet (MAGMA LWORD LIECAT FLALG XEXPPKG LPOLY PBWLB XPBWPOLY
+ LEXP)
+xpoly.spad.pamphlet (OFMONOID FMCAT FM1 XALG XFALG XPOLYC XPR XDPOLY XRPOLY
+ XPOLY)
+\end{verbatim}
+
+<<layer11>>=
+LAYER11=${OUT}/APPLYORE.o ${OUT}/ARRAY1.o ${OUT}/ARRAY12.o ${OUT}/ARRAY2.o \
+ ${OUT}/ASTACK.o ${OUT}/BTAGG.o ${OUT}/BTAGG-.o \
+ ${OUT}/COMBINAT.o ${OUT}/CSTTOOLS.o \
+ ${OUT}/D01FCFA.o ${OUT}/E04MBFA.o \
+ ${OUT}/FARRAY.o \
+ ${OUT}/FLALG.o ${OUT}/GALUTIL.o ${OUT}/HEAP.o \
+ ${OUT}/IARRAY1.o ${OUT}/IARRAY2.o ${OUT}/IFARRAY.o ${OUT}/INTCAT.o \
+ ${OUT}/INTHEORY.o ${OUT}/IRREDFFX.o \
+ ${OUT}/LFCAT.o ${OUT}/LODOCAT.o ${OUT}/LODOCAT-.o ${OUT}/LWORD.o \
+ ${OUT}/MATCAT.o ${OUT}/MATCAT-.o ${OUT}/MATSTOR.o \
+ ${OUT}/ORESUP.o ${OUT}/OREPCTO.o ${OUT}/OREUP.o ${OUT}/PLOT3D.o \
+ ${OUT}/PR.o ${OUT}/PREASSOC.o \
+ ${OUT}/PRIMARR2.o ${OUT}/REDORDER.o \
+ ${OUT}/SRAGG.o ${OUT}/SRAGG-.o \
+ ${OUT}/STREAM.o ${OUT}/SYMPOLY.o ${OUT}/TS.o ${OUT}/TUPLE.o \
+ ${OUT}/UPSCAT.o ${OUT}/UPSCAT-.o ${OUT}/VECTCAT.o ${OUT}/VECTCAT-.o \
+ ${OUT}/XDPOLY.o ${OUT}/XEXPPKG.o \
+ ${OUT}/XF.o ${OUT}/XF-.o ${OUT}/XPBWPOLY.o ${OUT}/XPOLY.o \
+ ${OUT}/XRPOLY.o
+
+@
+\subsection{Layer12}
+LODO1 should be here but is broken. See Bug 12.
+LODO2 should be here but is broken. See Bug 13.
+\begin{verbatim}
+boolean BITS BTAGG ORDSET SETCAT BASTYPE KOERCE LOGIC A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT INT FINITE INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM
+vector DIRPROD2 TYPE VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+matrix IMATRIX MATCAT ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB VECTCAT A1AGG FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT ORDSET RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE PRIMARR EUCDOM PID GCDDOM INTDOM
+ COMRING BMODULE RMODULE ALGEBRA MODULE ENTIRER FIELD UFD
+ DIVRING
+interval INTRVL INTCAT GCDDOM INTDOM COMRING RING ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN RADCAT RETRACT FPS RNS FIELD FIELD EUCDOM PID UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP REAL KONVERT PATMAB
+ CHARZ INS OINTDOM DIFRING LINEXP CFCAT STEP
+vector IVECTOR VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ INS UFD GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM
+lodo LODO1 DIFRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE LODOCAT OREPCAT BMODULE FRETRCT
+ RETRACT ALGEBRA MODULE ELTAB FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING ENTIRER UFD DIVRING INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET KONVERT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP
+lodo LODO2 LODOCAT OREPCAT RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ FRETRCT RETRACT ALGEBRA MODULE ELTAB DIFRING FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET KONVERT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP
+xlpoly LPOLY FLALG LIECAT MODULE BMODULE LMODULE ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE RMODULE FMCAT RETRACT COMRING
+ RING RNG SGROUP MONOID ORDSET LSAGG STAGG URAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ELAGG OM INT LIST ILIST BOOLEAN NNI FIELD EUCDOM PID
+ GCDDOM INTDOM ALGEBRA ENTIRER UFD DIVRING
+solvelin LSMP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG KONVERT ORDSET MATCAT ARR2CAT NNI INT BOOLEAN
+ PRIMARR SINT A1AGG INS OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP OM LIST ILIST
+solvelin LSMP1 FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+matfuns MATCAT2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE FLAGG LNAGG IXAGG HOAGG AGG TYPE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET MATCAT
+ ARR2CAT
+intclos TRIMAT INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET MATCAT ARR2CAT
+ INT NNI PI
+newpoint PTCAT VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+string STRICAT SRAGG A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET OM
+
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+interval.spad.pamphlet (INTCAT INTRVL)
+\end{verbatim}
+
+<<layer12>>=
+ ${OUT}/BITS.o ${OUT}/DIRPROD2.o ${OUT}/IMATRIX.o ${OUT}/INTRVL.o \
+ ${OUT}/IVECTOR.o ${OUT}/LPOLY.o ${OUT}/LSMP.o ${OUT}/LSMP1.o \
+ ${OUT}/MATCAT2.o ${OUT}/PTCAT.o ${OUT}/STRICAT.o ${OUT}/TRIMAT.o
+#${OUT}/LODO1.o ${OUT}/LODO2.o
+
+@
+\subsection{Layer13}
+\begin{verbatim}
+lodof ASSOCEQ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER LODOCAT OREPCAT FRETRCT
+ RETRACT ELTAB SINT NNI INT VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG CLAGG KONVERT
+ ORDSET VECTOR IVECTOR IARRAY1 LIST ILIST PI BOOLEAN
+ FIELD EUCDOM PID GCDDOM UFD DIVRING
+carten CARTEN GRALG GRMOD SETCAT BASTYPE KOERCE RETRACT OAMONS OCAMON
+ OAMON OASGP ORDSET ABELMON ABELSG CABMON INS UFD GCDDOM
+ INTDOM COMRING RING RNG ABELGRP SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP DIFRING KONVERT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP NNI INT MONOID VECTCAT A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG VECTOR
+ IVECTOR IARRAY1 SINT PI INS BOOLEAN LSAGG STAGG URAGG
+ RCAGG ELAGG OM LIST ILIST
+clifford CLIF RING RNG ABELGRP CABMON ABELMON SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE ALGEBRA MODULE BMODULE RMODULE
+ VSPACE FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER
+ UFD DIVRING SINT PI NNI INT ABELSG PRIMARR BOOLEAN
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG KONVERT ORDSET INS LIST ILIST LSAGG
+ STAGG URAGG RCAGG ELAGG OM ELAGG RCAGG VECTOR VECTCAT
+ IVECTOR IARRAY1
+clip CLIP DFLOAT FPS RNS FIELD EUCDOM UFD GCDDOM DIVRING INTDOM
+ ALGEBRA DIFRING ORDRING MODULE RING ABELGRP MONOID ORDSET
+ ABELSG SGROUP TRANFUN SETCAT ELEMFUN HYPCAT ATRIG TRIGCAT
+ RADCAT RETRACT BASTYPE PID COMRING RNG CABMON ABELMON
+ KOERCE LMODULE BMODULE RMODULE ENTIRER DIVRING OAGROUP
+ OCAMON OAMON OASGP REAL KONVERT PATMAB CHARZ PTCAT VECTCAT
+ A1AGG FLAGG LNAGG IXAGG HOAGG ATT TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG INS OINTDOM LINEXP STEP OM INT LIST ILIST LSAGG
+ STAGG URAGG RCAGG ELAGG PI NNI SINT BOOLEAN
+coordsys COORDSYS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RADCAT INT PI
+ NNI PTCAT VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+alql DBASE SETCAT BASTYPE KOERCE ORDSET STRICAT SRAGG A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB
+ CLAGG KONVERT OM INT LIST ILIST LSAGG STAGG URAGG RCAGG
+ ELAGG NNI SINT PI
+dhmatrix DHMATRIX MATCAT ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING VECTCAT A1AGG
+ FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT ORDSET TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN INT VECTOR IVECTOR IARRAY1
+solvedio DIOSP INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP NNI INT LIST
+ ILIST OAMONS VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG
+ LNAGG IXAGG CLAGG HOAGG ORDSET AGG ELTAGG SETCAT BASTYPE
+ BOOLEAN TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG SINT
+vector DIRPCAT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP IXAGG HOAGG AGG
+ TYPE EVALAB IEVALAB ELTAGG ELTAB FRETRCT DIFEXT PDRING
+ FLINEXP FINITE OAMONS VSPACE FIELD DIVRING VECTCAT A1AGG
+ FLAGG LNAGG CLAGG INT VECTOR IVECTOR IARRAY1 NNI LSAGG STAGG
+ URAGG RCAGG ELAGG OM LIST ILIST
+d02routinne D02BBFA ODECAT SETCAT BASTYPE KOERCE NNI INT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM LIST ILIST
+ DFLOAT FPS RNS FIELD EUCDOM UFD GCDDOM DIVRING INTDOM
+ ALGEBRA DIFRING ORDRING PID COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL RETRACT RADCAT PATMAB CHARZ
+ VECTCAT A1AGG VECTOR IVECTOR IARRAY1 PI
+d02routine D02BHFA ODECAT SETCAT BASTYPE KOERCE NNI INT DFLOAT FPS RNS
+ FIELD EUCDOM UFD GCDDOM DIVRING INTDOM ALGEBRA DIFRING
+ ORDRING PID COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG VECTOR IVECTOR IARRAY1 PI
+d02routine D02CJFA ODECAT SETCAT BASTYPE KOERCE INT LIST ILIST LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM DFLOAT
+ FPS RNS FIELD EUCDOM UFD GCDDOM DIVRING INTDOM ALGEBRA
+ DIFRING ORDRING PID COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL RETRACT RADCAT PATMAB CHARZ
+ VECTCAT A1AGG VECTOR IVECTOR IARRAY1
+ffcat FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC STEP DIFRING
+ SINT PI NNI INT VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT ORDSET INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP LINEXP PATMAB CFCAT REAL OM BOOLEAN LIST ILIST LSAGG
+ STAGG ELAGG
+ffpoly2 FFPOLY2 FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARNZ FFIELDC FINITE STEP DIFRING NNI INT PI VECTOR
+ IVECTOR IARRAY1 PRIMARR SINT
+fnla FNLA NAALG NARNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE MONAG MODULE BMODULE LMODULE RMODULE COMRING RING
+ RNG SGROUP MONOID VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ INT VECTOR IVECTOR IARRAY1 LIST ILIST LSAGG STAGG PI NNI
+perman GRAY INT VECTOR IVECTOR IARRAY1 PI NNI VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG KONVERT ORDSET SINT
+fnla HB INT SINT NNI INS EUCDOM UFD GCDDOM INTDOM ALGEBRA DIFRING
+ ORDRING MODULE RING ABELGRP BOOLEAN VECTOR IVECTOR IARRAY1
+ VECTCAT A1AGG FLAGG LNAGG IXAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAG ELTAGG CLAGG KONVERT ORDSET LIST
+ ILIST LSAGG STAGG
+irsn IRSN INT LIST NNI INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING
+ KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP SINT
+ PI OM ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG BOOLEAN
+ VECTOR IARRAY1 VECTCAT A1AGG FINITE LOGIC
+fortpack MCALCFN SETCAT BASTYPE KOERCE PDRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+ ORDSET INT VECTOR LSAGG STAGG URAGG RCAGG ELAGG OM LIST
+ ILIST INS UFD GCDDOM INTDOM COMRING BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP IVECTOR IARRAY1 NNI SINT PI
+divisor MHROWRED EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB
+ CLAGG KONVERT ORDSET INT VECTOR IVECTOR IARRAY1 BOOLEAN
+ INS UFD OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM LSAGG STAGG
+ URAGG RCAGG ELAGG LIST ILIST SINT NNI INS PI FIELD DIVRING
+numode NUMODE NNI INT VECTOR IVECTOR IARRAY1 PI SINT VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET LSAGG STAGG
+ URAGG RCAGG ELAGG OM LIST ILIST VECTCAT A1AGG
+numquad NUMQUAD INT NNI PI BOOLEAN SINT LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM LIST
+ ILIST VECTOR IVECTOR IARRAY1 VECTCAT A1AGG INS EUCDOM
+ UFD GCDDOM INTDOM ALGEBRA DIFRING ORDRING MODULE RING
+ ABELGRP ABELMON
+odealg ODESYS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ LODOCAT OREPCAT FRETRCT RETRACT ELTAB INT LIST ILIST NNI
+ VECTOR IVECTOR IARRAY1 LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG CLAGG KONVERT FLAGG
+ ORDSET ELAGG OM VECTCAT A1AGG INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING LINEXP PATMAB CFCAT REAL CHARZ
+ STEP BOOLEAN
+oderf ODETOOLS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ LODOCAT OREPCAT FRETRCT RETRACT ELTAB LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST VECTOR
+ VECTCAT A1AGG IVECTOR IARRAY1 INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING LINEXP PATMAB CFCAT REAL CHARZ
+ STEP
+gdirprod ORDFUNS OAMON OASGP ORDSET SETCAT BASTYPE KOERCE ABELMON ABELSG
+ SINT NNI INT VECTOR IVECTOR IARRAY1 BOOLEAN
+perman PERMAN RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE INT VECTOR IVECTOR IARRAY1
+ PI NNI BOOLEAN SINT VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE ENTIRER
+catdef PFECAT UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER CHARNZ INT VECTOR IVECTOR
+ IARRAY1 FIELD EUCDOM PID DIVRING
+newpoint POINT PTCAT VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT
+ BASTYPE KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+ ORDSET RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE LSAGG STAGG URAGG RCAGG ELAGG OM INT LIST ILIST INS
+ UFD GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ NNI PI RADCAT
+pseudolin PSEUDLIN FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ INT LIST ILIST BOOLEAN NNI VECTOR IVECTOR IARRAY1 VECTCAT
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG KONVERT ORDSET SINT
+newpoint PTPACK RING RNG ABELGRP CABMON ABELMON SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE INT PTCAT VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT ORDSET NNI
+rep2 REP2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE SINT NNI INT PI VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT ORDSET VECTOR IVECTOR IARRAY1 BOOLEAN LSAGG STAGG
+ URAGG RCAGG ELAGG OM LIST ILIST EUCDOM PID GCDDOM INTDOM
+ COMRING BMODULE RMODULE ALGEBRA MODULE ENTIRER INT UFD
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP FIELD DIVRING MATCAT
+ ARR2CAT FINITE
+lodof SETMN FINITE SETCAT BASTYPE KOERCE INT VECTOR IVECTOR IARRAY1
+ VECTCAT A1AGG FLAGG LNAGG IXAGG CLAGG HOAGG ORDSET AGG
+ ELTAGG NNI PI SINT LIST ILIST BOOLEAN BTAGG LOGIC TYPE
+ EVALAB IEVALAB ELTAB KONVERT LSAGG STAGG URAGG RCAGG ELAGG
+ OM
+sex SEX ORDSET SETCAT BASTYPE KOERCE INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP FPS RNS FIELD
+ DIVRING RADCAT SEXCAT STRICAT SRAGG A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG OM
+string STRING STRICAT SRAGG A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE SETCAT
+ BASTYPE KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+ ORDSET OM INT ORDFIN FINITE INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP
+efstruc SYMFUNC RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE PI NNI INT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM LIST ILIST INS
+ UFD GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ VECTOR IVECTOR IARRAY1 SINT VECTCAT A1AGG MONOID ABELMON
+ VECTCAT A1AGG
+vector VECTOR2 VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET INT
+ VECTOR IVECTOR IARRAY1 LIST LSAGG STAGG URAGG RCAGG ELAGG
+ OM ILIST
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+carten.spad.pamphlet (GRMOD GRALG CARTEN CARTEN2)
+catdef.spad.pamphlet (ABELGRP ABELMON ABELSG ALGEBRA BASTYPE BMODULE CABMON
+ CHARNZ CHARZ COMRING DIFRING DIFEXT DIVRING ENTIRER
+ EUCDOM FIELD FINITE FLINEXP GCDDOM GROUP INTDOM LMODULE
+ LINEXP MODULE MONOID OAGROUP OAMON OAMONS OASGP OCAMON
+ ORDFIN OINTDOM ORDMON ORDRING ORDSET PDRING PFECAT PID
+ RMODULE RING RNG SGROUP SETCAT STEP UFD VSPACE)
+clifford.spad.pamphlet (QFORM CLIF)
+clip.spad.pamphlet (CLIP)
+coordsys.spad.pamphlet (COORDSYS)
+dhmatrix.spad.pamphlet (DHMATRIX)
+d02routine.spad.pamphlet (D02BBFA D02BHFA D02CJFA D02EJFA)
+ffpoly2.spad.pamphlet (FFPOLY2)
+irsn.spad.pamphlet (IRSN)
+numode.spad.pamphlet (NUMODE)
+numquad.spad.pamphlet (NUMQUAD)
+perman.spad.pamphlet (GRAY PERMAN)
+pseudolin.spad.pamphlet (PSEUDLIN)
+rep2.spad.pamphlet (REP2)
+sex.spad.pamphlet (SEXCAT SEXOF SEX)
+solvedio.spad.pamphlet (DIOSP)
+\end{verbatim}
+
+<<layer13>>=
+LAYER13=${OUT}/ASSOCEQ.o ${OUT}/CARTEN.o ${OUT}/CLIF.o \
+ ${OUT}/CLIP.o ${OUT}/COORDSYS.o ${OUT}/DBASE.o ${OUT}/DHMATRIX.o \
+ ${OUT}/DIOSP.o \
+ ${OUT}/DIRPCAT.o ${OUT}/DIRPCAT-.o ${OUT}/D02BBFA.o ${OUT}/D02BHFA.o \
+ ${OUT}/D02CJFA.o ${OUT}/FAXF.o ${OUT}/FAXF-.o \
+ ${OUT}/FFPOLY2.o ${OUT}/FNLA.o ${OUT}/GRAY.o \
+ ${OUT}/HB.o ${OUT}/IRSN.o \
+ ${OUT}/MCALCFN.o ${OUT}/MHROWRED.o \
+ ${OUT}/NUMODE.o ${OUT}/NUMQUAD.o ${OUT}/ODESYS.o \
+ ${OUT}/ODETOOLS.o ${OUT}/ORDFUNS.o ${OUT}/PERMAN.o \
+ ${OUT}/PFECAT.o ${OUT}/PFECAT-.o ${OUT}/POINT.o ${OUT}/PSEUDLIN.o \
+ ${OUT}/PTPACK.o ${OUT}/REP2.o \
+ ${OUT}/SETMN.o ${OUT}/SEX.o ${OUT}/STRING.o \
+ ${OUT}/SYMFUNC.o ${OUT}/VECTOR2.o
+
+@
+\subsection{Layer14}
+\begin{verbatim}
+asp ASP1 FORTFN FORTCAT TYPE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ FMTC INS OINTDOM DIFRING LINEXP CFCAT STEP POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP
+ PFECAT
+asp ASP10 FVFUN FORTCAT TYPE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ FMTC INS OINTDOM DIFRING LINEXP CFCAT STEP POLYCAT PDRING
+ FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG ELTAGG ELTAB
+ CLAGG INT VECTOR IVECTOR IARRAY1 NNI PI
+asp ASP24 FORTFN FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ FMTC INS OINTDOM DIFRING LINEXP CFCAT STEP
+ POLYCAT PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB
+ FLINEXP PFECAT
+asp ASP4 FORTFN FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ FMTC INS OINTDOM DIFRING LINEXP CFCAT STEP POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP
+ PFECAT
+asp ASP50 FVFUN FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABLEMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET READ KONVERT RETRACT RADCAT PATMAB
+ CHARZ FMTC INS OINTDOM DIFRING LINEXP CFCAT STEP POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP
+ PFECAT
+asp ASP6 FVFUN FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ FMTC INS OINTDOM DIFRING LINEXP CFCAT STEP POLYCAT PDRING
+ FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT
+asp ASP73 FVFUN FORTCAT TYPE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ INS OINTDOM DIFRING LINEXP CFCAT STEP OM INT VECTOR
+ IVECTOR IARRAY1 PI NNI FMTC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP PFECAT
+oderf BALFACT GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER CHARZ UPOLYC POLYCAT PDRING
+ FAMR AMR CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB PFECAT UFD ELTAB DIFRING
+ DIFEXT STEP EUCDOM PID FIELD DIVRING INT LIST ILIST LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG
+ FLAGG ELAGG OM
+bezout BEZOUT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING MATCAT
+ ARR2CAT HOAGG AGG TYPE FLAGG LNAGG IXAGG ELTAGG CLAGG
+ NNI INT BOOLEAN SINT PI
+radix BINARY QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB STEP
+ ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL CHARZ
+ CHARNZ PFECAT INS CFCAT OM FPS RNS RADCAT UPOLYC POLYCAT
+ FAMR AMR FRETRCT
+files BINFILE FILECAT SETCAT BASTYPE KOERCE FNCAT INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP STRING CHAR SINT OUTFORM LIST INT PRIMARR
+ A1AGG ISTRING
+oderf BOUNDZRO FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ UFD DIVRING RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT STEP INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL
+ QFCAT FEVALAB PATAB FPATMAB TYPE INT OM
+padic BPADICRT QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT PADICCT FPS RNS RADCAT INS CFCAT UPOLYC
+ POLYCAT FAMR AMR FRETRCT
+brill BRILL UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB DIFRING
+ DIFEXT STEP EUCDOM PID FIELD DIVRING NNI INT BOOLEAN
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT
+ REAL FPS RNS RADCAT OM TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN PI
+cden CDEN INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD EUCDOM PID
+ GCDDOM UFD DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB
+ DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT
+ FPATMAB TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL CHARZ CHARNZ PFECAT FLAGG LNAGG
+ IXAGG HOAGG AGG ELTAGG CLAGG
+curve CHVAR UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING FAMR
+ AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT
+ STEP EUCDOM PID FIELD DIVRING NNI INT BOOLEAN PI INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL OM
+ QFCAT FEVALAB PATAB FPATMAB TYPE SINT
+polycat COMMUPC RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING BOOLEAN
+contfrac CONTFRAC ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ QFCAT RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG
+ IXAGG ELTAGG CLAGG FLAGG ELAGG OM INS CFCAT
+generic CVMP COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ POLYCAT PDRING FAMR AMR ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD INT VECTOR
+ IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG
+ TYPE ELTAGG ELTAB CLAGG LIST ILIST QFCAT FIELD EUCDOM PID
+ DIVRING FEVALAB DIFEXT DIFRING PATAB FPATMAB STEP OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL
+cycles CYCLES INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FIELD
+ DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP
+ PATAB FPATMAB TYPE CHARNZ PFECAT LSAGG STAGG URAGG RCAGG
+ HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM FAMR AMR
+ FRETRCT
+cyclotom CYCLOTOM INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP INT NNI SINT
+ LIST UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT EVALAB
+ IEVALAB FLINEXP PFECAT ELTAB DIFEXT FIELD DIVRING
+ddfact DDFACT FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING CHARNZ FINITE STEP DIFRING UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT ELTAB
+ DIFEXT NNI INT SINT PI LIST ILIST BOOLEAN INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL
+radix DECIMAL QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT INS CFCAT OM FPS RNS RADCAT UPOLYC
+ POLYCAT FAMR AMR FRETRCT
+aggcat DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ CLAGG KONVERT STRING CHAR SINT OUTFORM LIST INT PRIMARR
+ A1AGG ISTRING
+vector DIRPROD DIRPCAT IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE LMODULE
+ ABELGRP CABMON ABELMON ABELSG RMODULE DIFEXT RING RNG
+ SGROUP MONOID DIFRING PDRING FLINEXP LINEXP FINITE ALGEBRA
+ MODULE COMRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ OAMONS VSPACE FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD
+ DIVRING INS OINTDOM KONVERT PATMAB CFCAT REAL CHARZ STEP
+ OM INT VECTOR IVECTOR IARRAY1 VECTCAT A1AGG SINT NNI
+ BOOLEAN FLAGG LNAGG CLAGG PI
+out DISPLAY INT LIST ILIST LSAGG STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING STRICAT SRAGG A1AGG FLAGG LNAGG IXAGG HOAGG AGG
+ TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB ELTAGG ELTAB
+ CLAGG KONVERT ORDSET OM
+gdpoly DMP POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST DIRPCAT DIFEXT DIFRING FINITE ORDRING OAGROUP OCAMON
+ OAMON OASGP OAMONS VSPACE FIELD EUCDOM PID DIVRING ORDFIN
+ FPS RNS REAL RADCAT INS OINTDOM CFCAT STEP UPOLYC
+lodop DPMO DIRPCAT IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE LMODULE
+ ABELGRP CABMON ABELMON ABELSG RMODULE DIFEXT RING RNG
+ SGROUP MONOID DIFRING PDRING FLINEXP LINEXP FINITE ALGEBRA
+ MODULE COMRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ OAMONS VSPACE FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD
+ DIVRING SINT NNI INT INS OINTDOM KONVERT PATMAB CFCAT
+ REAL CHARZ STEP OM
+dpolcat DPOLCAT DVARCAT ORDSET SETCAT BASTYPE KOERCE RETRACT POLYCAT
+ PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE FAMR AMR BMODULE RMODULE COMRING ALGEBRA
+ MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT EVALAB IEVALAB
+ FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT UFD DIFEXT
+ DIFRING OAMONS OCAMON OAMON OASGP NNI INT LIST ILIST
+ LSAGG STAGG ELAGG URAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ ELTAB CLAGG FLAGG OM SINT INS EUCDOM PID OINTDOM ORDRING
+ OAGROUP CFCAT REAL STEP
+d01routine D01AJFA NUMINT SETCAT BASTYPE KOERCE PI NNI INT STRING CHAR SINT
+ OUTFORM LIST PRIMARR A1AGG ISTRING SRAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET READ KONVERT RETRACT RADCAT PATMAB
+ CHARZ DFLOAT INS
+d01routine D01AKFA NUMINT SETCAT BASTYPE KOERCE NNI INT STRING CHAR SINT
+ OUTFORM LIST PRIMARR A1AGG ISTRING SRAGG PI FPS RNS
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ DFLOAT INS
+d01routine D01ALFA NUMINT SETCAT BASTYPE KOERCE STRICAT SRAGG A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB
+ CLAGG KONVERT ORDSET OM INT LIST ILIST LSAGG STAGG URAGG
+ RCAGG ELAGG NNI INS STRING CHAR SINT OUTFORM PRIMARR
+ ISTRING FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP REAL RETRACT
+ RADCAT PATMAB CHARZ DIFRING TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN DFLOAT PI
+d01routine D01AMFA NUMINT SETCAT BASTYPE KOERCE NNI INT STRING CHAR SINT
+ OUTFORM LIST PRIMARR A1AGG ISTRING SRAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ PI INS DFLOAT
+d01routine D01APFA NUMINT SETCAT BASTYPE KOERCE DFLOAT INT LIST ILIST LSAGG
+ STAGG NNI STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT
+ RETRACT RADCAT PATMAB CHARZ DIFRING OM TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN ELAGG FLAGG URAGG PI INS
+d01routine D01AQFA FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ DIFRING OM TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN INT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB
+ IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG LIST
+ ILIST NNI PI STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG INS OINTDOM LINEXP CFCAT STEP QFCAT FEVALAB DIFEXT
+ PDRING FLINEXP PATAB FPATMAB CHARNZ PFECAT DFLOAT
+modring EMR EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABLESG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP FIELD DIVRING INT NNI BOOLEAN
+equation2 EQ TYPE IEVALAB SETCAT BASTYPE KOERCE ABELSG ABELGRP CABMON
+ ABELMON SGROUP MONOID GROUP RING RNG LMODULE BMODULE
+ RMODULE MODULE PDRING VSPACE COMRING FIELD EUCDOM PID
+ GCDDOM INTDOM ALGEBRA ENTIRER UFD DIVRING EVALAB BOOLEAN
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP POLYCAT FAMR AMR CHARNZ FRETRCT FLINEXP PFECAT ES
+erroor ERROR INT LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+cycles EVALCYC ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ INS UFD GCDDOM INTDOM COMRING ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FIELD
+ DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP
+ PATAB FPATMAB TYPE CHARNZ PFECAT
+e04routine E04DGFA OPTCAT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST NNI INS STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING DIFRING TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ DFLOAT MONOID PI BOOLEAN
+e04routine E04FDFA OPTCAT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST NNI INS STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING DIFRING TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN PI
+e04routine E04GCFA OPTCAT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST NNI INS STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING DIFRING TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN PI DFLOAT
+e04routine E04JAFA OPTCAT SETCAT BASTYPE KOERCE INT LIST ILIST LSAGG STAGG
+ FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT
+ RETRACT RADCAT PATMAB CHARZ URAGG RCAGG HOAGG AGG TYPE
+ EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG OM DIFRING TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ INS STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING STRICAT
+ SRAGG NNI PI DFLOAT
+facutil FACUTIL OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON RING RNG ABELGRP SGROUP MONOID
+ LMODULE POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT
+ UFD NNI INT LIST FFIELDC FPC FIELD EUCDOM PID DIVRING
+ FINITE STEP DIFRING PI BOOLEAN
+ffp FF FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC STEP
+ DIFRING KONVERT OAMONS OCAMON OAMON OASGP ORDSET INS OINTDOM
+ ORDRING OAGROUP LINEXP PATMAB CFCAT REAL
+ffcg FFCG FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING KONVERT OAMONS OCAMON OAMON OASGP ORDSET INS
+ OINTDOM ORDRING OAGROUP LINEXP PATMAB CFCAT REAL
+ffcg FFCGX FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING OAMONS OCAMON OAMON OASGP ORDSET INS OINTDOM
+ ORDRING OAGROUP KONVERT LINEXP PATMAB CFCAT REAL
+fff FFF FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING CHARNZ FINITE STEP DIFRING NNI INT SINT
+ PI INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ OM VECTOR
+ IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG
+ TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG LIST ILIST LSAGG
+ STAGG URAGG RCAGG ELAGG PRIMARR BOOLEAN UPOLYC POLYCAT
+ PDRING FAMR AMR FRETRCT FLINEXP PFECAT DIFEXT
+ffhom FFHOM FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC STEP
+ DIFRING NNI INT BOOLEAN SINT PI PRIMARR VECTOR IVECTOR
+ IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ffnb FFNB FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC STEP
+ DIFRING KONVERT OAMONS OCAMON OAMON OASGP ORDSET INS OINTDOM
+ ORDRING OAGROUP LINEXP PATMAB CFCAT REAL
+ffnb FFNBX FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING OAMONS OCAMON OAMON OASGP ORDSET INT OINTDOM
+ ORDRING OAGROUP KONVERT LINEXP PATMAB CFCAT REAL
+ffpoly FFPOLY FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ UFD DIVRING CHARNZ FINITE STEP DIFRING INT LIST ILIST PI
+ NNI PRIMARR A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET SINT BOOLEAN
+ VECTOR IVECTOR IARRAY1 VECTCAT UPOLYC POLYCAT PDRING FAMR
+ AMR CHARZ FRETRCT RETRACT FLINEXP LINEXP PATMAB PFECAT
+ DIFEXT LSAGG STAGG INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP CFCAT REAL URAGG RCAGG ELAGG OM
+ffcat FFSLPE FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING CHARNZ FINITE STEP DIFRING UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT ELTAB
+ DIFEXT NNI INT LIST ILIST BOOLEAN
+ffp FFX FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING OAMONS OCAMON OAMON OASGP ORDSET INS OINTDOM
+ ORDRING OAGROUP KONVERT LINEXP PATMAB CFCAT REAL
+zerodim FGLMICPK GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST
+ DIRPCAT FRETRCT RETRACT DIFEXT DIFRING PDRING FLINEXP
+ LINEXP FINITE ORDRING OAGROUP OCAMON OAMON OASGP OAMONS
+ VSPACE FIELD EUCDOM PID UFD DIVRING ORDFIN BOOLEAN NNI
+ POLYCAT FAMR AMR CHARZ CHARNZ PATMAB PFECAT
+files FILE FILECAT SETCAT BASTYPE KOERCE FNCAT STRING CHAR SINT
+ OUTFORM LIST INT PRIMARR A1AGG ISTRING
+naalgc FINAALG COMRING RING RNG SGROUP MONOID UPOLYC POLYCAT PDRING
+ FAMR AMR ALGEBRA CHARZ CHARNZ INTDOM ENTIRER FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING SINT PI NNI INT VECTOR IVECTOR IARRAY1
+ BOOLEAN INT OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL OM LIST ILIST VECTCAT A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE ELTAGG CLAGG
+algcat FINRALG COMRING UPOLYC POLYCAT PDRING FAMR AMR INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT
+ STEP EUCDOM PID FIELD DIVRING VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE ELTAGG CLAGG INT VECTOR IVECTOR
+ IARRAY1 INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL OM SINT PI NNI
+numsolve FLOATRP ORDRING OAGROUP OCAMON OAMON OASGP ORDSET SETCAT BASTYPE
+ KOERCE ABELMON ABELSG CABMON ABELGRP RING RNG SGROUP MONOID
+ LMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING INS OINTDOM
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ POLYCAT PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB
+ FLINEXP PFECAT BOOLEAN OM INT LIST ILIST
+fname FNAME FNCAT SETCAT BASTYPE KOERCE STRING CHAR SINT OUTFORM LIST
+ INT PRIMARR A1AGG ISTRING
+fortpak FOP STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING
+formula FORMULA SETCAT BASTYPE KOERCE INT NNI LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ILIST LSAGG STAGG STRICAT SRAGG A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB
+ CLAGG KONVERT ORDSET OM ISTRING PI ELAGG FLAGG URAGG RCAGG
+ ELAGG
+fortpak FORT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ORDSET ELAGG OM STRICAT SRAGG A1AGG INT LIST
+ ILIST STRING CHAR SINT OUTFORM PRIMARR ISTRING INS UFD
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP
+fraction FRAC QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT OM INS CFCAT BOOLEAN NNI INT PI SINT
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG ELTAGG CLAGG
+ VECTOR IVECTOR IARRAY1 UPOLYC POLYCAT FAMR AMR FRETRCT LIST
+ ILIST FPS RNS RADCAT
+fortran FTEM FILECAT SETCAT BASTYPE KOERCE FNCAT STRING CHAR SINT
+ OUTFORM LIST INT PRIMARR A1AGG ISTRING BOOLEAN INS UFD
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP OM SRAGG FLAGG LNAGG STRICAT IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+galfactu GALFACTU RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING FPS RNS
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL RADCAT TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PI NNI INT INT OINTDOM
+ CFCAT SINT INS
+galpolyu GALPOLYU RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INT LIST
+ ILIST NNI SINT PI OAMONS OCAMON OAMON OASGP VECTCAT A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG VECTOR
+ IVECTOR IARRAY1
+gb GB GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER OAMONS OCAMON OAMON
+ OASGP ORDSET POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ PFECAT UFD FIELD EUCDOM PID DIVRING INT LIST ILIST LSAGG
+ STAGG ELAGG FLAGG URAGG LNAGG RCAGG IXAGG BOOLEAN STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING PI NNI
+gbeuclid GBEUCLID EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER OAMONS
+ OCAMON OAMON OASGP ORDSET POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD INT STRING CHAR SINT OUTFORM
+ LIST PRIMARR A1AGG ISTRING ILIST LSAGG STAGG ELAGG FLAGG
+ BOOLEAN URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ ELTAB CLAGG OM NNI
+groebf GBF EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER CHARZ
+ OAMONS OCAMON OAMON OASGP ORDSET POLYCAT PDRING FAMR
+ AMR CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD BOOLEAN INT LIST ILIST NNI
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ ELTAB CLAGG FLAGG ELAGG OM
+gbintern GBINTERN GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER OAMONS OCAMON OAMON OASGP ORDSET
+ POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP KONVERT PATMAB PFECAT UFD NNI INT
+ BOOLEAN LIST ILIST LSAGG STAGG ELAGG FLAGG URAGG RCAGG HOAGG
+ AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM SINT
+geneez GENEEZ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB
+ PFECAT UFD ELTAB DIFRING DIFEXT STEP FIELD DIVRING NNI
+ INT PI INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL VECTOR IVECTOR IARRAY1 SINT BOOLEAN VECTCAT
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG
+ LSAGG STAGG URAGG RCAGG ELAGG OM LIST ILIST
+allfact GENMFACT ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON INTDOM COMRING RING RNG ABELGRP
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD FFIELDC FPC FIELD EUCDOM PID DIVRING
+ FINITE STEP DIFRING
+gpgcd GENPGCD OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON PFECAT UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB NNI INT LIST LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM
+ ILIST STEP BOOLEAN PI SINT
+ghensel GHENSEL EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB
+ PFECAT UFD ELTAB DIFRING DIFEXT STEP FIELD DIVRING INT
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ CLAGG FLAGG ELAGG OM LIST ILIST NNI BOOLEAN
+modmonom GMODPOL MODULE BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE RMODULE POLYCAT PDRING RING RNG
+ SGROUP MONOID FAMR AMR COMRING ALGEBRA CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD DIRPCAT
+ IXAGG HOAGG AGG TYPE ELTAGG ELTAB DIFEXT DIFRING FINITE
+ ORDRING OAGROUP OCAMON OAMON OASGP OAMONS VSPACE FIELD
+ EUCDOM PID DIVRING
+sum GOSPER OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON INTDOM COMRING RING RNG ABELGRP
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD FIELD EUCDOM PID DIVRING INS OINTDOM
+ ORDRING OAGROUP DIFRING CFCAT REAL STEP QFCAT FEVALAB
+ ELTAB DIFEXT PATAB FPATMAB TYPE INT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM
+ LIST ILIST SINT NNI PI VECTOR IVECTOR IARRAY1 BOOLEAN
+ VECTCAT A1AGG
+view2D GRIMAGE SETCAT BASTYPE KOERCE INS UFD GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM FPS RNS
+ FIELD DIVRING RADCAT INT LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG LIST ILIST NNI PI DFLOAT PTCAT VECTCAT A1AGG STRING
+ CHAR SINT OUTFORM PRIMARR STRICAT SRAGG ISTRING TRANFUN
+ ELEMFUN HYPCAT ATRIG TRIGCAT AHYP BOOLEAN
+grdef GROEBSOL GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT FLINEXP
+ LINEXP PATMAB PFECAT UFD NNI DIRPCAT DIFEXT DIFRING FINITE
+ ORDRING OAGROUP OCAMON OAMON OASGP OAMONS VSPACE FIELD
+ EUCDOM PID DIVRING ORDFIN SINT BOOLEAN
+gdpoly HDMP POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST DIRPCAT DIFEXT DIFRING FINITE ORDRING OAGROUP OCAMON
+ OAMON OASGP OAMONS VSPACE FIELD EUCDOM PID DIVRING ORDFIN
+ FPS RNS REAL RADCAT INT OINTDOM CFCAT STEP
+gdirprod HDP DIRPCAT IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE
+ LMODULE ABELGRP CABMON ABELMON ABELSG RMODULE DIFEXT RING
+ RNG SGROUP MONOID DIFRING PDRING FLINEXP LINEXP FINITE
+ ALGEBRA MODULE COMRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET OAMONS VSPACE FIELD EUCDOM PID GCDDOM INTDOM
+ ENTIRER UFD DIVRING SINT NNI INT BOOLEAN INS OINTDOM
+ KONVERT PATMAB CFCAT REAL CHARZ STEP OM
+radix HEXADEC QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT EVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT INS CFCAT FPS RNS RADCAT UPOLYC POLYCAT
+ FAMR AMR FRETRCT
+listgcd HEUGCD UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMONN ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INT BOOLEAN
+ PI SINT LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP CFCAT REAL OAMONS
+boolean IBITS BTAGG ORDSET SETCAT BASTYPE KOERCE LOGIC A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT INT STRING CHAR SINT OUTFORM LIST PRIMARR ISTRING
+ INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP OM SRAGG STRICAT FINITE
+padiclib IBPTOOLS RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING BOOLEAN
+ SINT NNI INT
+alql ICARD ORDSET SETCAT BASTYPE KOERCE ORDFIN FINITE STRING CHAR
+ SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING PI NNI
+cden ICDEN INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD EUCDOM PID
+ GCDDOM UFD DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB
+ DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB
+ TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL CHARZ CHARNZ PFECAT FLAGG LNAGG IXAGG
+ HOAGG AGG ELTAGG CLAGG
+idecomp IDECOMP INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP POLYCAT PDRING
+ FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT QFCAT
+ FIELD DIVRING FEVALAB ELTAB DIFEXT PATAB FPATMAB TYPE
+ DIRPCAT IXAGG HOAGG AGG ELTAGG FINITE OAMONS VSPACE ORDFIN
+ LSAGG STAGG URAGG RCAGG LNAGG CLAGG FLAGG ELAGG OM INT LIST
+ ILIST NNI
+ffp IFF FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING KONVERT OAMONS OCAMON OAMON OASGP ORDSET INS
+ OINTDOM ORDRING OAGROUP LINEXP PATMAB CFCAT REAL
+array2 IIARRAY2 ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ ORDSET INT PRIMARR A1AGG AGG NNI INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM
+ A1AGG STRING CHAR SINT OUTFORM LIST ISTRING
+matfuns IMATLIN FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG KONVERT ORDSET MATCAT ARR2CAT BOOLEAN INT
+ SINT NNI LIST A1AGG PI UPOLYC POLYCAT PDRING FAMR AMR
+ CHARZ CHARNZ FRETRCT RETRACT FLINEXP LINEXP PATMAB PFECAT
+ DIFRING DIFEXT STEP QFCAT FEVALAB PATAB FPATMAB OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL VECTCAT OM
+matfuns IMATQF INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER FLAGG LNAGG IXAGG HOAGG
+ AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET
+ MATCAT ARR2CAT QFCAT FIELD EUCDOM PID GCDDOM UFD DIVRING
+ RETRACT FEVALAB DIFEXT DIFRING PDRING FLINEXP LINEXP
+ PATAB FPATMAB PATMAB STEP OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL CHARZ CHARNZ PFECAT
+modgcd INMODGCD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB PFECAT UFD ELTAB DIFRING DIFEXT
+ STEP FIELD DIVRING INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP CFCAT REAL INT LIST ILIST BOOLEAN NNI LSAGG STAGG
+ ELAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG
+ FLAGG OM OAMONS PI
+multfact INNMFACT ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER CHARZ POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB PFECAT
+ UFD PI NNI INT ILIST UPOLYC ELTAB DIFRING DIFEXT STEP FIELD
+ DIVRING BOOLEAN LSAGG STAGG ELAGG FLAGG SINT URAGG RCAGG
+ HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG OM
+sign INPSIGN RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INT INS
+intrf INTHERTR FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP NNI INT
+intrf INTRAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB
+ PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL
+intrf INTRF INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER RETRACT CHARZ POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD QFCAT FIELD
+ EUCDOM PID DIVRING FEVALAB ELTAB DIFEXT DIFRING PATAB
+ FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL UPOLYC
+integer INTSLPE INT VECTOR IVECTOR IARRAY1 INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB
+ FLINEXP PFECAT ELTAB DIFEXT FIELD DIVRING LIST ILIST NNI
+intrf INTTR FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB PATAB FPATMAB TYPE
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL BOOLEAN
+ NNI INT PRIMARR INS CFCAT LIST ILIST PI LSAGG STAGG ELAGG
+ FLAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG OM SINT
+sum ISUMP OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON INTDOM COMRING RING RNG ABELGRP
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD INS EUCDOM PID OINTDOM ORDRING OAGROUP
+ DIFRING CFCAT REAL STEP QFCAT FIELD DIVRING FEVALAB ELTAB
+ DIFEXT PATAB FPATMAB TYPE INT LIST BOOLEAN NNI ILIST
+gpol LAUPOL DIFEXT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE DIFRING PDRING INTDOM COMRING
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER KONVERT FRETRCT
+ RETRACT CHARZ CHARNZ EUCDOM PID GCDDOM FIELD UFD DIVRING
+ UPOLYC POLYCAT FAMR AMR EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ PATMAB PFECAT ELTAB STEP INT BOOLEAN NNI LIST ILIST LSAGG
+ STAGG ELAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ CLAGG FLAGG OM INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP CFCAT REAL
+leadcdet LEADCDET ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ PATMAB PFECAT UFD SINT NNI INT LIST ILIST LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG OM PI
+lingrob LGROBP GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT ORDSET INT VECTOR IVECTOR IARRAY1 SINT NNI LSAGG
+ STAGG URAGG RCAGG ELAGG OM LIST ILIST DIRPCAT FRETRCT
+ RETRACT DIFEXT DIFRING PDRING FLINEXP LINEXP FINITE ORDRING
+ OAGROUP OCAMON OAMON OASGP OAMONS VSPACE FIELD EUCDOM PID
+ UFD DIVRING ORDFIN PI BOOLEAN POLYCAT FAMR AMR CHARZ CHARNZ
+ PATMAB PFECAT
+sign LIMITRF GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT UFD QFCAT
+ FIELD EUCDOM PID DIVRING FEVALAB ELTAB DIFEXT DIFRING
+ PATAB FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL INT OM UPOLYC NNI
+lindep LINDEP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER LINEXP INT LIST ILIST VECTCAT A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG KONVERT ORDSET VECTOR IVECTOR IARRAY1 VECTCAT
+ NNI BOOLEAN INS UFD GCDDOM EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT PATMAB CFCAT
+ REAL CHARZ STEP OM FIELD DIVRING QFCAT FEVALAB DIFEXT PDRING
+ FLINEXP PATAB FPATMAB CHARNZ PFECAT
+fraction LO MODULE BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE RMODULE OAGROUP OCAMON OAMON OASGP ORDSET
+ COMRING RING RNG SGROUP MONOID STRING CHAR SINT OUTFORM
+ LIST INT PRIMARR A1AGG ISTRING
+fraction LPEFRAC PFECAT UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD EUCDOM
+ PID DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT
+ DIFRING PDRING FLINEXP LINNEXP PATAB KONVERT FPATMAB TYPE
+ PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL CHARZ CHARNZ
+solvelin LSPP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER OAMONS OCAMON OAMON OASGP
+ ORDSET POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ LNAGG IXAGG ELTAGG ELTAGG CLAGG FLAGG ELAGG OM INT LIST
+ ILIST VECTOR IVECTOR IARRAY1 SINT NNI BOOLEAN VECTCAT
+ A1AGG QFCAT FIELD EUCDOM PID DIVRING FEVALAB DIFEXT
+ DIFRING PAGAB FPATMAB STEP OINTDOM ORDRING OAGROUP REAL
+matfuns MATLIN COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG KONVERT ORDSET MATCAT ARR2CAT BOOLEAN INT
+ PRIMARR LIST ILIST PI NNI A1AGG SINT INTDOM ALGEBRA
+ MODULE ENTIRER FIELD EUCDOM PID GCDDOM UFD DIVRING
+ VECTCAT QFCAT RETRACT FEVALAB DIFEXT DIFRING PDRING
+ FLINEXP LINEXP PATAB FPATMAB PATMAB STEP OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL CHARZ CHARNZ PFECAT INS
+ CFCAT
+cden MCDEN INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD EUCDOM PID
+ GCDDOM UFD DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB
+ DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT
+ FPATMAB TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL CHARZ CHARNZ PFECAT VECTCAT A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG ELTAGG CLAGG LSAGG STAGG URAGG
+ RCAGG ELAGG OM INT LIST ILIST
+moddfact MDDFACT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INT INS
+ EUCDOM OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT
+ REAL NNI SINT PI ILIST
+mfinfact MFINFACT ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON FFIELDC FPC FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING CHARNZ
+ FINITE STEP DIFRING POLYCAT PDRING FAMR AMR CHARZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB PFECAT
+ UPOLYC ELTAB DIFEXT INT LIST ILIST NNI LSAGG STAGG ELAGG
+ FLAGG BOOLEAN PI URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG CLAGG OM SINT
+fortmac MFLOAT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ FMTC INS OINTDOM
+ DIFRING LINEXP CFCAT STEP INT PI NNI OM STRING CHAR SINT
+ OUTFORM LIST PRIMARR A1AGG ISTRING TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN BOOLEAN
+fortmac MINT FMTC INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT INS UFD GCDDOM EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ KONVERT LINEXP PATMAB CFCAT REAL CHARZ STEP PI NNI INT
+ MONOID ABELSG SGROUP STRING CHAR SINT OUTFORM LIST
+ PRIMARR A1AGG ISTRING
+mlift MLIFT OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT
+ LIST ILIST NNI SINT BOOLEAN PI
+curve MMAP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING FAMR
+ AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING QFCAT
+ FEVALAB PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL
+modmon MODMON UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING FINITE NNI INT PI FFIELDC FPC PRIMARR
+ A1AGG FLAGG LNAGG IXAGG CLAGG HOAGG AGG ELTAGG BOOLEAN SINT
+ TYPE VECTOR IVECTOR IARRAY1 FPS RNS ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL RADCAT INS OINTDOM CFCAT
+intrf MONOTOOL FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP NNI INT
+allfact MPCPF OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD INT OM
+poltopol MPC2 ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON RING RNG ABELGRP SGROUP MONOID
+ LMODULE POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD NNI INT
+poltopol MPC3 ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON RING RNG ABELGRP SGROUP MONOID
+ LMODULE POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT
+ UFD BOOLEAN
+multpoly MPOLY ORDFIN ORDSET SETCAT BASTYPE KOERCE FINITE POLYCAT PDRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE FAMR AMR BMODULE RMODULE COMRING ALGEBRA MODULE
+ CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT UFD FPS RNS
+ FIELD EUCDOM PID DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ REAL RADCAT INT OINTDOM DIFRING CFCAT STEP UPOLYC ELTAB
+ DIFEXT
+allfact MPRFF OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON INTDOM COMRING RING RNG ABELGRP
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD INS EUCDOM PID OINTDOM ORDRING OAGROUP
+ DIFRING CFCAT REAL STEP QFCAT FIELD DIVRING FEVALAB ELTAB
+ DIFEXT PATAB FPATMAB TYPE FFIELDC FPC FINITE BOOLEAN NNI
+ INT
+allfact MRATFAC OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER CHARZ POLYCAT PDRING FAMR AMR
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD QFCAT FIELD DIVRING FEVALAB
+ ELTAB DIFEXT DIFRING PATAB FPATMAB TYPE STEP OINTDOM
+ ORDRING OAGROUP REAL PI NNI INT INS CFCAT
+multsqfr MULTSQFR OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD PI NNI INT BOOLEAN LIST ILIST
+ LSAGG STAGG ELAGG FLAGG UPOLYC ELTAB DIFRING DIFEXT STEP
+ FIELD DIVRING SINNT URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG CLAGG OM
+twofact NORMRETR FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING CHARNZ FINITE STEP DIFRING FAXF XF
+ RETRACT VSPACE CHARZ UPOLYC POLYCAT PDRING FAMR AMR FRETRCT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFEXT SINT PI NNI INT LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM LIST ILIST
+ BOOLEAN
+npcoef NPCOEF UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING OAMONS
+ OCAMON OAMON OASGP INT LIST ILIST SINT NNI VECTOR LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG
+ FLAGG ELAGG OM BOOLEAN PI IVECTOR IARRAY1 VECTCAT A1AGG
+newpoly NSUP UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB DIFRING
+ DIFEXT STEP EUCDOM PID FIELD DIVRING INT LIST ILIST NNI FPS
+ RNS ORDRING OAGROUP OCAMON OASGP REAL RADCAT INS OINTDOM
+ CFCAT
+special NTPOLFN COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE INS
+ UFD GCDDOM INTDOM ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP NNI INT BOOLEAN
+ QFCAT FIELD DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT
+ PDRING FLINEXP PATAB FPATMAB TYPE CHARZ PFECAT
+gdirprod ODP DIRPCAT IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE
+ LMODULE ABELGRP CABMON ABELMON ABELSG RMODULE DIFEXT RING
+ RNG SGROUP MONOID DIFRING PDRING FLINEXP LINEXP FINITE
+ ALGEBRA MODULE COMRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET OAMONS VSPACE FIELD EUCDOM PID GCDDOM INTDOM
+ ENTIRER UFD DIVRING INS OINTDOM KONVERT PATMAB CFCAT
+ REAL CHARZ STEP OM
+oderf ODEPRIM FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP LODOCAT OREPCAT
+ NNI INT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG BOOLEAN LIST ILIST SINT PI
+riccati ODEPRRIC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP LODOCAT OREPCAT
+ SINT INT NNI LIST ILIST LSAGG STAGG INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP CFCAT REAL OM PI URAGG RCAGG
+ HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OAMONS
+ INS
+omdev OMPKG STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING
+ BOOLEAN
+omserver OMSERVER BOOLEAN INT DFLOAT STRING CHAR SINT OUTFORM LIST PRIMARR
+ A1AGG
+pade PADEPAC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ NNI INT UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT STEP
+padic PADICRAT QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT PADICCT RNS RADCAT INS CFCAT UPOLYC
+ POLYCAT FAMR AMR FRETRCT
+padic PADICRC QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT PADICCT INT INS CFCAT BOOLEAN LIST ILIST
+ SINT NNI LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG OM FPS RNS RADCAT UPOLYC POLYCAT
+ FAMR AMR FRETRCT
+pdecomp PCOMP UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING BOOLEAN
+pdecomp PDECOMP UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING SINT NNI
+ INT BOOLEAN LIST
+pf PF FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING CHARNZ FINITE STEP DIFRING FAXF XF RETRACT VSPACE
+ CHARZ KONVERT OAMONS OCAMON OAMON OASGP ORDSET INS OINTDOM
+ ORDRING OAGROUP LINEXP PATMAB CFCAT REAL
+pfbr PFBR PFECAT UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER OAMONS
+ OCAMON OAMON OASGP ORDSET POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB INT PI NNI LIST ILIST BOOLEAN LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM UPOLYC DIFRING DIFEXT STEP EUCDOM PID
+ FIELD DIVRING FFIELDC FPC FINITE
+pfbr PFBRU PFECAT UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI INT SINT
+ PI LIST ILIST BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM
+pfo PFOTOOLS UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INT INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL
+ QFCAT FEVALAB PATAB FPATMAB TYPE OM
+pfr PFRPAC EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER CHARZ POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT UFD QFCAT
+ FIELD DIVRING FEVALAB ELTAB DIFEXT DIFRING PATAB FPATMAB
+ TYPE STEP OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ UPOLYC
+pgcd PGCD OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFECAT UFD PI NNI INT BOOLEAN LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG ELTAB
+ CLAGG FLAGG ELAGG OM LIST ILIST SINT UPOLYC DIFRING
+ DIFEXT STEP FIELD DIVRING
+pinterp PINTERPA FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT STEP LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG
+ FLAGG ELAGG OM INT LIST ILIST NNI SINT BOOLEAN
+pleqn PLEQN EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER CHARZ ORDSET KONVERT
+ OAMONS OCAMON OAMON OASGP POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP PATMAB PFECAT
+ UFD QFCAT FIELD DIVRING FEVALAB ELTAB DIFEXT DIFRING PATAB
+ FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP REAL NNI INT INS
+ CFCAT OM LIST VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG ELTAGG CLAGG SINT ILIST LSAGG STAGG
+ URAGG RCAGG ELAGG PI BOOLEAN
+patmatch2 PMPLCAT SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP ORDSET
+ ABELMON ABELSG CABMON RING RNG ABELGRP SGROUP MONOID
+ LMODULE PATMAB POLYCAT PDRING FAMR AMR BMODULE RMODULE
+ COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ GCDDOM PFECAT UFD INT LIST ILIST LSAGG STAGG ELAGG
+ FLAGG URAGG
+patmatch2 PMQFCAT SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER PATMAB KONVERT QFCAT FIELD
+ EUCDOM PID GCDDOM UFD DIVRING RETRACT FEVALAB ELTAB
+ EVALAB IEVALAB DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB
+ FPATMAB TYPE STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL CHARZ CHARNZ PFECAT
+poltopol POLTOPOL RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE ORDFIN ORDSET FINITE LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM INT LIST
+ ILIST DIRPCAT FRETRCT RETRACT BMODULE RMODULE DIFEXT
+ DIFRING PDRING FLINEXP LINEXP ALGEBRA MODULE COMRING
+ ORDRING OAGROUP OCAMON OAMON OASGP OAMONS VSPACE FIELD
+ EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING
+numtheor PNTHEORY INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP INT NNI QFCAT
+ FIELD DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING
+ FLINEXP PATAB FPATMAB TYPE CHARNZ PFECAT BOOLEAN OM PI SINT
+ UFD
+reclos POLUTIL FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP BOOLEAN INT LIST
+ NNI LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG OM ILIST ORDRING OAGROUP
+ OCAMON OAMON OASGP LSAGG STAGG
+rf POLYCATQ OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON RING RNG ABELGRP SGROUP MONOID
+ LMODULE POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD FIELD EUCDOM PID DDIVRING UPOLYC ELTAB
+ DIFRING DIFEXT STEP INT LIST ILIST LSAGG STAGG ELAGG
+polycat POLYLIFT OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON RING RNG ABELGRP SGROUP MONOID
+ LMODULE POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT
+ UFD BOOLEAN
+manip POLYROOT OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON INTDOM COMRING RING RNG ABELGRP
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD FIELD EUCDOM PID DIVRING INT NNI INS
+ OINTDOM ORDRING OAGROUP DIFRING CFCAT REAL STEP UFD
+multpoly POLY2 RING RNG ABELGRP CABMON ABELMON ABLESG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE POLYCAT PDRING FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD
+poly POLY2UP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE POLYCAT PDRING FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD
+prs PRS INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING NNI INT VECTOR IVECTOR IARRAY1 VECTCAT
+ BOOLEAN A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG
+ FINITE LIST ILIST LSAGG STAGG
+poly PSQFR ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON GCDDOM INTDOM COMRING RING RNG
+ ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ PATMAB PFECAT UFD INT LIST ILIST BOOLEAN UPOLYC ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI
+facutil PUSHVAR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE OAMONS OCAMON OAMON OASGP
+ ORDSET POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ GCDDOM PFECAT UFD NNI INT BOOLEAN
+qalgset QALGSET SETCAT BASTYPE KOERCE GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET OAMONS
+ OCAMON OAMON OASGP POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ PATMAB PFECAT UFD EUCDOM PID INT LIST LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG OM ILIST NNI BOOLEAN
+fraction QFCAT2 INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD EUCDOM PID
+ GCDDOM UFD DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB
+ DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT
+ FPATMAB TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL CHARZ CHARNZ PFECAT
+radix RADIX QFCAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB
+ STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ CHARZ CHARNZ PFECAT INS CFCAT INT NNI LIST ILIST BOOLEAN
+ LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG
+ FLAGG ELAGG PI STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING FPS RNS RADCAT UPOLYC POLYCAT FAMR AMR FRETRCT
+ratfact RATFACT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL INT QFCAT
+ FEVALAB PATAB FPATMAB TYPE BOOLEAN
+reclos RCFIELD INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FIELD
+ DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP
+ PATAB FPATMAB TYPE CHARNZ PFECAT FRETRCT RADCAT NNI INT
+ LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG
+ FLAGG ELAGG OM LIST ILIST PI
+rderf RDETR FIELD EUCDOM PID GCDDOM INTDOM COMRING RRING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP BOOLEAN NNI INT
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL
+rdesys RDETRS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP INT LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG VECTOR VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG IVECTOR IARRAY1
+ PI NNI
+realzero REAL0 UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL INT OM
+ NNI LIST ILIST PI BOOLEAN INS SINT VECTOR IVECTOR IARRAY1
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG
+ CLAGG
+real0q REAL0Q UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL INT QFCAT
+ FEVALAB PATAB FPATMAB TYPE
+resring RESRING POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD FIELD
+ EUCDOM PID DIVRING OAMONS OCAMON OAMON OASGP INT LIST ILIST
+nlinsol RETSOL INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER RETRACT PDRING FAMR AMR
+ CHARZ CHARNZ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB GCDDOM PFECAT UFD INT LIST ILIST BOOLEAN
+acplot REALSOLV INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP POLYCAT PDRING FAMR AMR CHARNZ FRETRCT EVALAB
+ IEVALAB FLINEXP PFECAT QFCAT FIELD DIVRING FEVALAB ELTAB
+ DIFEXT PATAB FPATMAB TYPE FPS RNS RADCAT
+rf RF INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER POLYCAT PDRING FAMR AMR
+ CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD QFCAT
+ FIELD EUCDOM PID DIVRING FEVALAB ELTAB DIFEXT DIFRING
+ PATAB FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL UPOLYC
+allfact RFFACTOR EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER INS UFD OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FIELD
+ DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP
+ PATAB FPATMAB TYPE CHARNZ PFECAT POLYCAT FAMR AMR FRETRCT
+ FFIELDC FPC FINITE
+matcat RMATCAT DIRPCAT IXAGG ELTAGG ELTAB FRETRCT RETRACT DIFEXT DIFRING
+ PDRING FLINEXP LINEXP FINITE ALGEBRA ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET OAMONS VSPACE FIELD EUCDOM PID
+ GCDDOM INTDOM ENTIRER UFD DIVRING NNI INT
+reclos RRCC ORDRING OAGROUP OCAMON OAMON OASGP ORDSET ABELMON ABELSG
+ CABMON ABELGRP RING RNG SGROUP MONOID LMODULE FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING UPOLYC POLYCAT PDRING FAMR
+ AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT STEP
+ INT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG OM LIST ILIST NNI
+naalg SCPKG FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM INT
+ LIST ILIST VECTOR IVECTOR IARRAY1 VECTCAT A1AGG INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP NNI SINT POLYCAT PDRING FAMR
+ AMR CHARNZ FRETRCT FLINEXP PFECAT BOOLEAN QFCAT FEVALAB
+ DIFEXT PATAB FPATMAB
+gdirprod SHDP DIRPCAT IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE LMODULE
+ ABELGRP CABMON ABELMON ABELSG RMODULE DIFEXT RING RNG
+ SGROUP MONOID DIFRING PDRING FLINEXP LINEXP FINITE ALGEBRA
+ MODULE COMRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ OAMONS VSPACE FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD
+ DIVRING BOOLEAN NNI INT SINT INS OINTDOM KONVERT PATMAB
+ CFCAT REAL CHARZ STEP
+sturm SHP OINTDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET NNI INT LIST PI ILIST SINT BOOLEAN
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT FLAGG ELAGG OM
+ INS UFD GCDDOM EUCDOM PID DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP UPOLYC POLYCAT PDRING FAMR AMR
+ CHARNZ FRETRCT FLINEXP PFECAT DIFEXT FIELD DIVRING
+sign SIGNRF GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT UFD INT
+ QFCAT FIELD EUCDOM PID DIVRING FEVALAB ELTAB DIFEXT
+ DIFRING PATAB FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL UPOLYC LIST ILIST
+smith SMITH EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+ ORDSET MATCAT ARR2CAT NNI INT SINT BOOLEAN PI QFCAT FIELD
+ UFD DIVRING RETRACT FEVALAB DIFEXT DIFRING PDRING FLINEXP
+ LINEXP PATAB FPATMAB PATMAB STEP OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL CHARZ CHARNZ PFECAT VECTCAT A1AGG
+ OM LIST ILIST
+multpoly SMP POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD BOOLEAN NNI INT PI LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM LIST ILIST FIELD EUCDOM PID DIVRING FPS RNS
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL RADCAT INS OINTDOM
+ DIFRING CFCAT STEP UPOLYC DIFEXT
+mts SMTS MTSCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE PSCAT AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER IEVALAB EVALAB RADCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN ORDSET POLYCAT FAMR FRETRCT
+ RETRACT FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT UFD
+ NNI INT BOOLEAN LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM
+ INS EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP DIFRING CFCAT REAL STEP PI FIELD DIVRING
+solvefor SOLVEFOR UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING BOOLEAN
+ INT LIST ILIST LSAGG STAGG NNI PI INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP CFCAT REAL
+newdata SPLTREE RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ INT LIST ILIST LSAGG STAGG ELAGG FLAGG URAGG LNAGG RCAGG
+ IXAGG CLAGG HOAGG ORDSET AGG ELTAGG BOOLEAN KONVERT OM NNI
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+infprod STINPROD INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER CHARZ FIELD EUCDOM PID
+ GCDDOM UFD DIVRING QFCAT RETRACT FEVALAB ELTAB EVALAB
+ DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB
+ TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL CHARNZ PFECAT
+sttf STTFNC ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ INT STRING CHAR SINT OUTFORM LIST PRIMARR A1AGG ISTRING
+intrf SUBRESP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING FAMR
+ AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI INT
+ PRIMARR LIST A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG
+ CLAGG PI ILIST BOOLEAN
+sum SUMRF INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER ORDSET RETRACT POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT EVALAB IEVALAB
+ FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT UFD QFCAT
+ FIELD EUCDOM PID DIVRING FEVALAB ELTAB DIFEXT DIFRING
+ PATAB FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL
+poly SUP UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING OAMONS OCAMON OAMON OASGP FPC INT LIST
+ NNI PI ILIST BOOLEAN FFIELDC FINITE LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM FPS
+ RNS ORDRING OAGROUP REAL RADCAT INS OINTDOM CFCAT
+allfact SUPFRACF OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON GCDDOM INTDOM COMRING RING RNG
+ ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ PATMAB PFECAT UFD QFCAT FIELD EUCDOM PID DIVRING FEVALAB
+ ELTAB DIFEXT DIFRING PATAB FPATMAB TYPE STEP OINTDOM
+ ORDRING OAGROUP REAL UPOLYC
+efstruc TANEXP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ INT UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB PFECAT ELTAB DIFRING DIFEXT STEP INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL OM VECTOR
+ IVECTOR IARRAY1 SINT VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG TYPE ELTAGG CLAGG NNI PI
+fortpak TEMUTL INT STRING CHAR SINT OUTFORM LIST PRIMARR A1AGG ISTRING
+ SRAGG
+tex TEX SETCAT BASTYPE KOERCE INT NNI STRING CHAR SINT OUTFORM
+ LIST PRIMARR A1AGG ISTRING ILIST STRICAT SRAGG FLAGG LNAGG
+ IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT ORDSET OM PI BOOLEAN LSAGG STAGG URAGG RCAGG ELAGG
+ ORDFIN FINITE
+files TEXTFILE FILECAT SETCAT BASTYPE KOERCE FNCAT STRICAT SRAGG A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAB
+ CLAGG KONVERT ORDSET OM STRING CHAR SINT OUTFORM LIST INT
+ PRIMARR A1AGG ISTRING
+tree TREE RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB
+ NNI INT LIST ILIST BOOLEAN LSAGG STAGG URAGG LNAGG IXAGG
+ ELTAGG ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM PI STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+twofact TWOFACT FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING CHARNZ FINITE STEP DIFRING UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB PFECAT ELTAB DIFEXT INT INS PI NNI
+ LIST ILIST BOOLEAN FAXF XF VSPACE LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM
+unifact UNIFACT UPOLYC POLYCAT PDRRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING BOOLEAN INT
+ LIST INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT
+ REAL OM INS NNI SINT PI LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG ILIST
+poly UP UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING NNI INT FPS RNS ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL RADCAT INS OINTDOM CFCAT
+cden UPCDEN INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD EUCDOM PID
+ GCDDOM UFD DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB
+ DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB
+ TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL CHARZ CHARNZ PFECAT UPOLYC POLYCAT FAMR
+ AMR FRETRCT LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG
+updecomp UPDECOMP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER CHARZ UPOLYC POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD
+ ELTAB DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI
+ INT SINT BOOLEAN
+upddivp UPDIVP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD
+ ELTAB DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI
+ BOOLEAN
+poly UPMP RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINXEP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI INT
+ LIST ILIST
+polycat UPOLYC2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING BOOLEAN
+poly UPSQFREE INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD
+ ELTAB DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING FFIELDC
+ FPC FINITE INT NNI BOOLEAN LIST PI
+pscat UPXSCAT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FIELD
+ DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP
+ PATAB FPATMAB TYPE CHARNZ PFECAT UPSCAT PSCAT AMR RADCAT
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+viewdef VIEWDEF NNI INT BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ SETCAT BASTYPE KOERCE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM LIST ILIST STRING
+ CHAR SINT OUTFORM A1AGG ISTRING SRAGG STRICAT
+view2D VIEW2D SETCAT BASTYPE KOERCE DFLOAT INT BOOLEAN PI NNI VECTCAT
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG KONVERT ORDSET VECTOR IVECTOR IARRAY1
+ LIST ILIST LSAGG STAGG SINT STRING CHAR OUTFORM PRIMARR
+ A1AGG ISTRING INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ STEP OM SRAGG STRICAT ELAGG FLAGG FPS RNS FIELD
+ DIVRING RADCAT
+void VOID STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING
+weier WEIER FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ INT LIST ILIST NNI POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT MTSCAT PSCAT RADCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN
+wtpol WP ORDSET SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON
+ ABELSG SGROUP MONOID LMODULE ALGEBRA MODULE BMODULE
+ RMODULE OAMONS OCAMON OAMON OASGP POLYCAT PDRING FAMR
+ AMR COMRING CHARNZ INTDOM ENTIRER FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT UFD
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST NNI BOOLEAN
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+allfact.spad.pamphlet (MRATFAC MPRFF MPCPF GENMFACT RFFACTOR SUPFRACF)
+array2.spad.pamphlet (ARR2CAT IIARRAY2 IARRAY2 ARRAY2)
+bezout.spad.pamphlet (BEZOUT)
+boolean.spad.pamphlet (REF LOGIC BOOLEAN IBITS BITS)
+brill.spad.pamphlet (BRILL)
+cden.spad.pamphlet (ICDEN CDEN UPCDEN MCDEN)
+contfrac.spad.pamphlet (CONTFRAC NCNTFRAC)
+cycles.spad.pamphlet (CYCLES EVALCYC)
+cyclotom.spad.pamphlet (CYCLOTOM)
+ddfact.spad.pamphlet (DDFACT)
+equation2.spad.pamphlet (EQ EQ2 FEVALAB)
+error.spad.pamphlet (ERROR)
+facutil.spad.pamphlet (FACUTIL PUSHVAR)
+ffcat.spad.pamphlet (FPC XF FAXF DLP FFIELDC FFSLPE)
+fff.spad.pamphlet (FFF)
+ffhom.spad.pamphlet (FFHOM)
+ffpoly.spad.pamphlet (FFPOLY)
+fname.spad.pamphlet (FNCAT FNAME)
+formula.spad.pamphlet (FORMULA FORMULA1)
+fraction.spad.pamphlet (LO LA QFCAT QFCAT2 FRAC LPEFRAC FRAC2)
+galfactu.spad.pamphlet (GALFACTU)
+galpolyu.spad.pamphlet (GALPOLYU)
+gb.spad.pamphlet (GB)
+gbeuclid.spad.pamphlet (GBEUCLID)
+gbintern.spad.pamphlet (GBINTERN)
+gdirprod.spad.pamphlet (ORDFUNS ODP HDP SHDP)
+geneez.spad.pamphlet (GENEEZ)
+ghensel.spad.pamphlet (GHENSEL)
+gpgcd.spad.pamphlet (GENPGCD)
+gpol.spad.pamphlet (LAUPOL)
+groebf.spad.pamphlet (GBF)
+groebsol.spad.pamphlet (GROEBSOL)
+intrf.spad.pamphlet (SUBRESP MONOTOOL INTHERTR INTTR INTRAT INTRF)
+idecomp.spad.pamphlet (IDECOMP)
+leadcdet.spad.pamphlet (LEADCDET)
+lindep.spad.pamphlet (LINDEP ZLINDEP)
+lingrob.spad.pamphlet (LGROBP)
+listgcd.spad.pamphlet (HEUGCD)
+matfuns.spad.pamphlet (IMATLIN MATCAT2 RMCAT2 IMATQF MATLIN)
+mfinfact.spad.pamphlet (MFINFACT)
+mlift.spad.pamphlet (MLIST)
+moddfact.spad.pamphlet (MDDFACT)
+modmon.spad.pamphlet (MODMON)
+modring.spad.pamphlet (MODRING EMR MODFIELD)
+mts.spad.pamphlet (SMTS TS)
+multsqfr.spad.pamphlet (MULTSQFR)
+newpoint.spad.pamphlet (PTCAT POINT COMPPROP SUBSPACE PTPACK PTFUNC2)
+numtheor.spad.pamphlet (INTHEORY PNTHEORY)
+npcoef.spad.pamphlet (NPCOEF)
+omdev.spad.pamphlet (OMENC OMDEV OMCONN OMPKG)
+omserver.spad.pamphlet (OMSERVER)
+padic.spad.pamphlet (PADICCT IPADIC PADIC BPADIC PADICRC PADICRAT BPADICRT)
+pdecomp.spad.pamphlet (PCOMP PDECOMP)
+pfbr.spad.pamphlet (PFBRU PFBR)
+pfr.spad.pamphlet (PFR PFRPAC)
+pgcd.spad.pamphlet (PGCD)
+pinterp.spad.pamphlet (PINTERPA PINTERP)
+pleqn.spad.pamphlet (PLEQN)
+poltopol.spad.pamphlet (MPC2 MPC3 POLTOPOL)
+poly.spad.pamphlet (FM PR SUP SUP2 UP UP2 POLY2UP UPSQFREE PSQFR UPMP)
+polycat.spad.pamphlet (AMR FAMR POLYCAT POLYLIFT UPOLYC UPOLYC2 COMMUPC)
+prs.spad.pamphlet (PRS)
+radix.spad.pamphlet (RADIX BINARY DECIMAL HEXADEC RADUTIL)
+ratfact.spad.pamphlet (RATFACT)
+rderf.spad.pamphlet (RDETR)
+realzero.spad.pamphlet (REAL0)
+real0q.spad.pamphlet (REAL0Q)
+resring.spad.pamphlet (RESRING)
+rf.spad.pamphlet (POLYCATQ RF)
+solvefor.spad.pamphlet (SOLVEFOR)
+solvelin.spad.pamphlet (LSMP LSMP1 LSPP)
+smith.spad.pamphlet (SMITH)
+sttf.spad.pamphlet (STTF STTFNC)
+sturm.spad.pamphlet (SHP)
+sum.spad.pamphlet (ISUMP GOSPER SUMRF)
+tex.spad.pamphlet (TEX)
+tree.spad.pamphlet (TREE BTCAT BTREE BSTREE BTOURN BBTREE PENDTREE)
+twofact.spad.pamphlet (NORMRETR TWOFACT)
+unifact.spad.pamphlet (UNIFACT)
+updecomp.spad.pamphlet (UPDECOMP)
+updivp.spad.pamphlet (UPDIVP)
+viewDef.spad.pamphlet (VIEWDEF)
+vector.spad.pamphlet (VECTCAT IVECTOR VECTOR VECTOR2 DIRPCAT DIRPROD DIRPROD2)
+view2D.spad.pamphlet (GRIMAGE VIEW2D)
+void.spad.pamphlet (VOID EXIT)
+weier.spad.pamphlet (WEIER)
+wtpol.spad.pamphlet (WP OWP)
+\end{verbatim}
+
+<<layer14>>=
+LAYER14=${OUT}/ASP1.o ${OUT}/ASP10.o ${OUT}/ASP24.o ${OUT}/ASP4.o \
+ ${OUT}/ASP50.o ${OUT}/ASP6.o ${OUT}/ASP73.o \
+ ${OUT}/BALFACT.o ${OUT}/BEZOUT.o ${OUT}/BINARY.o \
+ ${OUT}/BINFILE.o ${OUT}/BOUNDZRO.o ${OUT}/BPADICRT.o ${OUT}/BRILL.o \
+ ${OUT}/CDEN.o ${OUT}/CHVAR.o ${OUT}/COMMUPC.o \
+ ${OUT}/CONTFRAC.o \
+ ${OUT}/CVMP.o ${OUT}/CYCLOTOM.o ${OUT}/CYCLES.o ${OUT}/DDFACT.o \
+ ${OUT}/DECIMAL.o \
+ ${OUT}/DIOPS.o ${OUT}/DIOPS-.o ${OUT}/DIRPROD.o \
+ ${OUT}/DISPLAY.o ${OUT}/DMP.o ${OUT}/DPMO.o \
+ ${OUT}/DPOLCAT.o ${OUT}/DPOLCAT-.o \
+ ${OUT}/D01AJFA.o ${OUT}/D01AKFA.o ${OUT}/D01ALFA.o \
+ ${OUT}/D01AMFA.o ${OUT}/D01APFA.o ${OUT}/D01AQFA.o \
+ ${OUT}/EMR.o ${OUT}/EQ.o \
+ ${OUT}/ERROR.o ${OUT}/EVALCYC.o \
+ ${OUT}/E04DGFA.o \
+ ${OUT}/E04FDFA.o ${OUT}/E04GCFA.o ${OUT}/E04JAFA.o \
+ ${OUT}/FACUTIL.o ${OUT}/FF.o \
+ ${OUT}/FFCG.o ${OUT}/FFCGX.o ${OUT}/FFHOM.o \
+ ${OUT}/FFNB.o ${OUT}/FFNBX.o ${OUT}/FFPOLY.o ${OUT}/FFX.o \
+ ${OUT}/FFSLPE.o \
+ ${OUT}/FGLMICPK.o ${OUT}/FILE.o \
+ ${OUT}/FINAALG.o ${OUT}/FINAALG-.o \
+ ${OUT}/FINRALG.o ${OUT}/FINRALG-.o \
+ ${OUT}/FFF.o ${OUT}/FLOATRP.o ${OUT}/FNAME.o \
+ ${OUT}/FOP.o ${OUT}/FORMULA.o ${OUT}/FORT.o ${OUT}/FRAC.o \
+ ${OUT}/FTEM.o ${OUT}/GENEEZ.o ${OUT}/GENMFACT.o \
+ ${OUT}/GENPGCD.o \
+ ${OUT}/GALFACTU.o ${OUT}/GALPOLYU.o \
+ ${OUT}/GB.o ${OUT}/GBEUCLID.o \
+ ${OUT}/GBF.o ${OUT}/GBINTERN.o ${OUT}/GHENSEL.o \
+ ${OUT}/GMODPOL.o \
+ ${OUT}/GOSPER.o ${OUT}/GRIMAGE.o \
+ ${OUT}/GROEBSOL.o ${OUT}/HDMP.o ${OUT}/HDP.o ${OUT}/HEXADEC.o \
+ ${OUT}/HEUGCD.o \
+ ${OUT}/IBPTOOLS.o ${OUT}/IFF.o \
+ ${OUT}/IBITS.o ${OUT}/ICARD.o ${OUT}/ICDEN.o ${OUT}/IDECOMP.o \
+ ${OUT}/IIARRAY2.o ${OUT}/IMATLIN.o ${OUT}/IMATQF.o \
+ ${OUT}/INMODGCD.o ${OUT}/INNMFACT.o \
+ ${OUT}/INPSIGN.o ${OUT}/INTHERTR.o ${OUT}/INTRAT.o ${OUT}/INTRF.o \
+ ${OUT}/INTSLPE.o ${OUT}/INTTR.o \
+ ${OUT}/ISUMP.o ${OUT}/LAUPOL.o ${OUT}/LEADCDET.o \
+ ${OUT}/LGROBP.o ${OUT}/LIMITRF.o ${OUT}/LINDEP.o ${OUT}/LO.o \
+ ${OUT}/LPEFRAC.o ${OUT}/LSPP.o \
+ ${OUT}/MATLIN.o ${OUT}/MCDEN.o ${OUT}/MDDFACT.o ${OUT}/MFINFACT.o \
+ ${OUT}/MFLOAT.o \
+ ${OUT}/MINT.o ${OUT}/MLIFT.o ${OUT}/MMAP.o ${OUT}/MODMON.o \
+ ${OUT}/MONOTOOL.o ${OUT}/MPCPF.o \
+ ${OUT}/MPC2.o ${OUT}/MPC3.o ${OUT}/MPOLY.o ${OUT}/MPRFF.o \
+ ${OUT}/MRATFAC.o ${OUT}/MULTSQFR.o ${OUT}/NORMRETR.o \
+ ${OUT}/NPCOEF.o ${OUT}/NSUP.o ${OUT}/NTPOLFN.o \
+ ${OUT}/ODP.o ${OUT}/ODEPRIM.o \
+ ${OUT}/ODEPRRIC.o ${OUT}/OMPKG.o ${OUT}/OMSERVER.o \
+ ${OUT}/PADEPAC.o ${OUT}/PADICRAT.o ${OUT}/PADICRC.o \
+ ${OUT}/PCOMP.o ${OUT}/PDECOMP.o ${OUT}/PF.o \
+ ${OUT}/PFBR.o ${OUT}/PFBRU.o ${OUT}/PFOTOOLS.o ${OUT}/PFRPAC.o \
+ ${OUT}/PGCD.o ${OUT}/PINTERPA.o ${OUT}/PLEQN.o \
+ ${OUT}/PMPLCAT.o ${OUT}/PMQFCAT.o \
+ ${OUT}/PNTHEORY.o \
+ ${OUT}/POLUTIL.o ${OUT}/POLTOPOL.o ${OUT}/POLYCATQ.o \
+ ${OUT}/POLYLIFT.o \
+ ${OUT}/POLYROOT.o \
+ ${OUT}/POLY2.o ${OUT}/POLY2UP.o ${OUT}/PRS.o \
+ ${OUT}/PSQFR.o ${OUT}/PUSHVAR.o \
+ ${OUT}/QALGSET.o ${OUT}/QFCAT2.o ${OUT}/RADIX.o ${OUT}/RATFACT.o \
+ ${OUT}/RCFIELD.o ${OUT}/RCFIELD-.o \
+ ${OUT}/RDETR.o ${OUT}/RDETRS.o ${OUT}/REAL0.o ${OUT}/REAL0Q.o \
+ ${OUT}/REALSOLV.o \
+ ${OUT}/RESRING.o ${OUT}/RETSOL.o ${OUT}/RF.o \
+ ${OUT}/RFFACTOR.o ${OUT}/RMATCAT.o ${OUT}/RMATCAT-.o \
+ ${OUT}/RRCC.o ${OUT}/RRCC-.o ${OUT}/SCPKG.o ${OUT}/SHDP.o \
+ ${OUT}/SHP.o ${OUT}/SIGNRF.o ${OUT}/SMITH.o ${OUT}/SMP.o \
+ ${OUT}/SMTS.o \
+ ${OUT}/SOLVEFOR.o ${OUT}/SPLTREE.o ${OUT}/STINPROD.o \
+ ${OUT}/STTFNC.o ${OUT}/SUBRESP.o ${OUT}/SUMRF.o ${OUT}/SUP.o \
+ ${OUT}/SUPFRACF.o \
+ ${OUT}/TANEXP.o ${OUT}/TEMUTL.o \
+ ${OUT}/TEX.o ${OUT}/TEXTFILE.o \
+ ${OUT}/TREE.o ${OUT}/TWOFACT.o \
+ ${OUT}/UNIFACT.o ${OUT}/UP.o ${OUT}/UPCDEN.o \
+ ${OUT}/UPDECOMP.o ${OUT}/UPDIVP.o \
+ ${OUT}/UPMP.o ${OUT}/UPOLYC2.o ${OUT}/UPXSCAT.o \
+ ${OUT}/UPSQFREE.o ${OUT}/VIEWDEF.o ${OUT}/VIEW2D.o \
+ ${OUT}/VOID.o ${OUT}/WEIER.o ${OUT}/WP.o
+
+@
+\subsection{Layer15}
+\begin{verbatim}
+aggcat DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB CLAGG KONVERT BOOLEAN NNI INT
+dpolcat DSMP DPOLCAT POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB GCDDOM PFECAT UFD DIFEXT DIFRING
+ DVARCAT NNI INT FPS RNS FIELD EUCDOM PID DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL RADCAT INS OINTDOM CFCAT
+ STEP UPOLYC ELTAB
+expexpan EXPUPXS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDSET UPXSCAT UPSCAT PSCAT AMR CHARZ CHARNZ ELTAB DIFRING
+ PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ OAMON OASGP INS OINTDOM ORDRING OAGROUP OCAMON KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL STEP INT LIST ILIST
+ BOOLEAN OM QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP
+ PATAB FPATMAB TYPE PFECAT
+algcat FRAMALG FINRALG ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE
+ RMODULE CHARZ CHARNZ COMRING UPOLYC POLYCAT PDRING FAMR
+ AMR INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING VECTCAT A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG INT VECTOR
+ IVECTOR IARRAY1 INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP CFCAT REAL OM NNI SINT LIST ILIST
+aggcat MDAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB CLAGG KONVERT
+dpolcat ODPOL DPOLCAT POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB GCDDOM PFECAT UFD DIFEXT DIFRING DVARCAT FPS
+ RNS FIELD EUCDOM PID DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL RADCAT OINTDOM CFCAT STEP INS OINTDOM STEP
+ UPOLYC ELTAB
+plot PLOT PPCURVE KOERCE BOOLEAN INT DFLOAT FPS RNS FIELD EUCDOM UFD
+ GCDDOM DIVRING INTDOM ALGEBRA DIFRING ORDRING MODULE RING
+ ABELGRP ABELMON MONOID ORDSET ABELSG SGROUP TRANFUN SETCAT
+ ELEMFUN HYPCAT ATRIG TRIGCAT RADCAT RETRACT BASTYPE PID
+ COMRING RING RNG CABMON LMODULE BMODULE RMODULE ENTIRER
+ OAGROUP OCAMON OAMON OASGP REAL KONVERT RETRACT PATMAB
+ CHARZ PTCAT VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG ILIST LSAGG STAGG URAGG
+ RCAGG ELAGG OM NNI PI SINT INS OINTDOM LINEXP CFCAT STEP
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN FRAC
+matfuns RMCAT2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE DIRPCAT IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE RMODULE DIFEXT
+ DIFRING PDRING FLINEXP LINEXP FINITE ALGEBRA MODULE COMRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET OAMONS VSPACE
+ FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING RMATCAT
+ NNI INT
+reclos ROIRC RRCC SETCAT BASTYPE KOERCE ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET ABELMON ABELSG CABMON ABELGRP RING RNG SGROUP
+ MONOID LMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP KONVERT PATMAB PFECAT ELTAB DIFRING
+ DIFEXT STEP NNI INT LIST LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM ILIST PI
+ BOOLEAN INS OINTDOM CFCAT REAL
+dpolcat SDPOL DPOLCAT POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB GCDDOM PFECAT UFD DIFEXT DIFRING DVARCAT FPS
+ RNS FIELD EUCDOM PID DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL RADCAT INS OINTDOM CFCAT STEP UPOLYC ELTAB
+matcat SMATCAT DIFEXT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE DIFRING PDRING BMODULE RMODULE
+ RMATCAT HOAGG AGG TYPE EVALAB IEVALAB MODULE COMRING FRETRCT
+ RETRACT FLINEXP LINEXP ALGEBRA DIRPCAT IXAGG ELTAGG ELTAB
+ FINITE ORDRING OAGROUP OCAMON OAMON OASGP ORDSET OAMONS
+ VSPACE FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING
+ INT NNI VECTOR IVECTOR IARRAY1 INS OINTDOM KONVERT PATMAB
+ CFCAT REAL CHARZ STEP OM VECTCAT A1AGG FLAGG LNAGG CLAGG
+ LSAGG STAGG URAGG RCAGG ELAGG LIST ILIST INS
+tube TUBETOOL FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ INS OINTDOM DIFRING
+ LINEXP CFCAT STEP OM INT DFLOAT LIST FRAC SINT PI NNI ILIST
+ BOOLEAN LSAGG STAGG ELAGG FLAGG URAGG
+efupxs UPXSCCA UPXSCAT UPSCAT PSCAT AMR RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING RETRACT
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+dpolcat.spad.pamphlet (DVARCAT ODVAR SDVAR DPOLCAT DSMP ODPOL SDPOL)
+matcat.spad.pamphlet (MATCAT RMATCAT SMATCAT)
+plot.spad.pamphlet (PLOT PLOT1)
+\end{verbatim}
+
+<<layer15>>=
+LAYER15=${OUT}/DIAGG.o ${OUT}/DIAGG-.o ${OUT}/DSMP.o ${OUT}/EXPUPXS.o \
+ ${OUT}/FRAMALG.o ${OUT}/FRAMALG-.o \
+ ${OUT}/MDAGG.o ${OUT}/ODPOL.o ${OUT}/PLOT.o ${OUT}/RMCAT2.o \
+ ${OUT}/ROIRC.o \
+ ${OUT}/SDPOL.o ${OUT}/SMATCAT.o ${OUT}/SMATCAT-.o ${OUT}/TUBETOOL.o \
+ ${OUT}/UPXSCCA.o ${OUT}/UPXSCCA-.o
+
+@
+\subsection{Layer16}
+\begin{verbatim}
+lodop DPMM DIRPCAT IXAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB ELTAGG ELTAB FRETRCT RETRACT BMODULE LMODULE ABELGRP
+ CABMON ABELMON ABELSG RMODULE DIFEXT RING RNG SGROUP MONOID
+ DIFRING PDRING FLINEXP LINEXP FINITE ALGEBRA MODULE COMRING
+ ORDRING OSAGROUP OCAMON OAMON OASGP ORDSET OAMONS VSPACE
+ FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING SMATCAT
+ RMATCAT SINT PI NNI INT INS OINTDOM KONVERT PATMAB CFCAT
+ REAL CHARZ STEP OM
+efupxs EFUPXS PTRANFN UPXSCCA UPXSCAT UPSCAT PSCAT AMR RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD
+ DIVRING RETRACT ULSCAT NNI INT INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET KONVERT LINEXP PATMAB CFCAT REAL
+ STEP OM PI STRING CHAR SINT OUTFORM LIST PRIMARR A1AGG
+ ISTRING
+intclos FFINTBAS EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB PFECAT UFD ELTAB DIFRING DIFEXT
+ STEP FIELD DIVRING FRAMALG FINRALG INT VECTCAT A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG NNI
+divisor FRIDEAL GROUP MONOID SGROUP SETCAT BASTYPE KOERCE EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ QFCAT FIELD UFD DIVRING RETRACT FEVALAB ELTAB EVALAB
+ IEVALAB DIFEXT DIFRING PDRING FLINEXP LINEXP PATAB KONVERT
+ FPATMAB TYPE PATMAB STEP ORDSET OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL CHARZ CHARNZ PFECAT UPOLYC POLYCAT
+ FAMR AMR FRETRCT FRAMALG FINRALG VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG ELTAGG CLAGG INT VECTOR IVECTOR IARRAY1
+ BOOLEAN LSAGG STAGG URAGG RCAGG ELAGG OM LIST ILIST SINT
+ NNI INS CFCAT FINITE PI
+divisor FRIDEAL2 EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER QFCAT FIELD UFD
+ DIVRING RETRACT FEVALAB ELTAB EVALAB IEVALAB DIFEXT DIFRING
+ PDRING FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB STEP
+ ORDSET OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL CHARZ
+ CHARNZ PFECAT UPOLYC POLYCAT FAMR AMR FRETRCT FRAMALG
+ FINRALG INS CFCAT OM INT VECTOR IVECTOR IARRAY1
+divisor FRMOD FRAMALG FINRALG ALGEBRA RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE MODULE
+ BMODULE RMODULE CHARZ CHARNZ EUCDOM PID GCDDOM INTDOM
+ COMRING ENTIRER QFCAT FIELD UFD DIVRING RETRACT FEVALAB
+ ELTAB EVALAB IEVALAB DIFEXT DIFRING PDRING FLINEXP LINEXP
+ PATAB KONVERT FPATMAB TYPE PATMAB STEP ORDSET OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL PFECAT UPOLYC
+ POLYCAT FAMR AMR FRETRCT BOOLEAN VECTCAT A1AGG FLAGG LNAGG
+ IXAGG HOAGG AGG ELTAGG CLAGG INT VECTOR IVECTOR IARRAY1
+ INS CFCAT OM NNI PI
+aggcat FSAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB CLAGG KONVERT SETAGG FINITE NNI INT BOOLEAN
+ SINT PI INS ORDSET LIST ILIST LSAGG STAGG URAGG RCAGG LNAGG
+ IXAGG ELTAGG ELTAB FLAGG ELAGG OM
+intclos IBATOOL EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB PFECAT UFD ELTAB DIFRING DIFEXT
+ STEP FIELD DIVRING FRAMALG FINRALG SINT NNI INT PI INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL OM
+ VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG TYPE ELTAGG CLAGG
+intfact INTFACT INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP INT INS LIST
+ ILIST LSAGG STAGG ELAGG PI NNI SINT BOOLEAN MDAGG DIOPS
+ BGAGG HOAGG AGG TYPE EVALAB IEVALAB CLAGG
+aggcat KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB CLAGG KONVERT BOOLEAN
+algcat MONOGEN COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ FRAMALG FINRALG ALGEBRA MODULE CHARZ CHARNZ KONVERT
+ FRETRCT RETRACT FLINEXP LINEXP FINITE FIELD EUCDOM PID
+ GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT DIFRING PDRING
+ FFIELDC FPC STEP UPOLYC POLYCAT FAMR AMR EVALAB IEVALAB
+ ORDSET PATMAB PFECAT ELTAB NNI INT SINT PI VECTOR IVECTOR
+ IARRAY1 INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL
+aggcat MSETAGG MDAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB CLAGG KONVERT SETAGG
+intclos NFINTBAS UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING FRAMALG FINRALG INT VECTOR IVECTOR IARRAY1
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL OM
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG
+ LIST ILIST PI NNI
+space SPACE3 SPACEC SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BOOLEAN INT LIST LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM ILIST NNI PI
+ OAMONS OCAMON OAMON OASGP FLAGG DIAGG DIOPS BGAGG SETAGG
+ FINITE
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+efupxs.spad.pamphlet (EFUPXS)
+lodop.spad.pamphlet (MLO OMLO NCODIV ODR DPMO DPMM)
+space.spad.pamphlet (SPACEC SPACE3 TOPSP)
+\end{verbatim}
+
+<<layer16>>=
+LAYER16=${OUT}/DPMM.o ${OUT}/EFUPXS.o \
+ ${OUT}/FFINTBAS.o ${OUT}/FRIDEAL.o ${OUT}/FRIDEAL2.o \
+ ${OUT}/FRMOD.o ${OUT}/FSAGG.o ${OUT}/FSAGG-.o ${OUT}/IBATOOL.o \
+ ${OUT}/INTFACT.o \
+ ${OUT}/KDAGG.o ${OUT}/KDAGG-.o ${OUT}/MSETAGG.o \
+ ${OUT}/MONOGEN.o ${OUT}/MONOGEN-.o \
+ ${OUT}/NFINTBAS.o ${OUT}/SPACE3.o
+
+@
+\subsection{Layer17}
+\begin{verbatim}
+string CCLASS SETCAT BASTYPE KOERCE KONVERT FSAGG DIAGG DIOPS BGAGG HOAGG
+ AGG TYPE EVALAB IEVALAB CLAGG SETCAT FINITE ORDFIN ORDSET
+ INT STRING CHAR SINT OUTFORM LIST PRIMARR A1AGG ISTRING
+ SRAGG NNI BOOLEAN INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP OM FLAGG LNAGG BTAGG LOGIC A1AGG IXAGG
+ ELTAGG ELTAB
+aggcat2 FSAGG2 SETCAT BASTYPE KOERCE FSAGG DIAGG DIOPS BGAGG HOAGG AGG
+ TYPE EVALAB IEVALAB CLAGG KONVERT SETAGG FINITE
+galfact GALFACT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING BOOLEAN INS OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP CFCAT REAL OM INT PI NNI OAMONS FSAGG DIAGG
+ DIOPS BGAGG HOAGG AGG TYPE CLAGG SETAGG FINITE LIST ILIST
+ FPS RNS RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ LSAGG STAGG URAGG RCAGG LNAGG IXAGG ELTAGG FLAGG ELAGG
+algfact IALGFACT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP MONOGEN FRAMALG FINRALG FINITE
+ FFIELDC FPC NNI INT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM LIST ILIST
+padiclib IBACHIN FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING CHARNZ FINITE STEP DIFRING UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT ELTAB
+ DIFEXT SINT NNI INT LIST ILIST LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM
+ PI MONOGEN FRAMALG FINRALG BOOLEAN VECTCAT A1AGG
+algcat NORMMA GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC
+odealg ODERED FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ LODOCAT OREPCAT FRETRCT RETRACT ELTAB UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT DIFRING DIFEXT STEP MONOGEN FRAMALG
+ FINRALG FINITE FFIELDC FPC VECTCAT A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE ELTAGG CLAGG NNI INT SINT PI
+aggcat OMSAGG ORDSET SETCAT BASTYPE KOERCE MSETAGG MDAGG DIOPS BGAGG
+ HOAGG AGG TYPE EVALAB IEVALAB CLAGG KONVERT SETAGG PRQAGG
+perm PERM PERMCAT GROUP MONOID SGROUP SETCAT BASTYPE KOERCE ORDSET
+ FINITE INT BOOLEAN LIST ILIST INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING KONVERT RETRACT LINEXP
+ PATMAB CFCAT REAL CHARZ STEP OM LSAGG STAGG ELAGG FLAGG
+ URAGG LNAGG SINT RCAGG HOAGG AGG TYPE EVALAB IEVALAB IXAGG
+ ELTAGG ELTAB CLAGG VECTOR IVECTOR IARRAY1 PI NNI FSAGG DIAGG
+ DIOPS BGAGG SETAGG VECTCAT A1AGG
+permgrps PERMGRP SETCAT BASTYPE KOERCE NNI INT BOOLEAN LIST ILIST SINT INS
+ UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT
+ REAL CHARZ STEP OM LSAGG STAGG ELAGG FLAGG URAGG LNAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB IXAGG ELTAGG ELTAB CLAGG
+ OAMONS VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FSAGG DIAGG
+ DIOPS BGAGG SETAGG FINITE PI PERMCAT GROUP
+intfact PRIMES INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP PI NNI INT
+ VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG CLAGG
+ HOAGG AGG ELTAGG LIST ILIST LSAGG STAGG URAGG RCAGG TYPE
+ EVALAB IEVALAB ELTAB ELAGG OM SINT BOOLEAN FSAGG DIAGG DIOPS
+ BGAGG SETAGG FINITE
+padiclib PWFFINTB FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING CHARNZ FINITE STEP DIFRING UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB PFECAT ELTAB DIFEXT MONOGEN FRAMALG
+ FINRALG QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL OM INT LIST ILIST LSAGG
+ STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG
+ ELAGG PI NNI INS CFCAT VECTCAT A1AGG
+random RDIST SETCAT BASTYPE KOERCE INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM VECTCAT A1AGG FSAGG DIAGG DIOPS BGAGG SETAGG
+ FINITE
+algext SAE UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING MONOGEN
+ FRAMALG FINRALG FINITE FFIELDC FPC NNI INT BOOLEAN SINT
+ VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG ELTAGG TYPE ELTAGG CLAGG QFCAT FEVALAB PATAB
+ FPATMAB OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ PI INS CFCAT
+algfact SAEFACT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING MONOGEN FRAMALG FINRALG FINITE FFIELDC
+ FPC INS OINTDOM ORDRING OAGROUP OCAMONN OAMON OASGP CFCAT
+ REAL QFCAT FEVALAB PATAB FPATMAB TYPE
+algfact SAERFFC UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING MONOGEN FRAMALG FINRALG FINITE FFIELDC
+ FPC INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT
+ REAL QFCAT FEVALAB PATAB FPATMAB TYPE
+sgcf SGCF INT SINT NNI LIST ILIST LSAGG VECTOR IVECTOR IARRAY1
+ BOOLEAN STAGG VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE
+ SETCAT BASTYPE KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ KONVERT ORDSET URAGG RCAGG ELAGG OM INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP FSAGG DIAGG DIOPS BGAGG
+ SETAGG FINITE
+aggcat TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB BOOLEAN NNI
+ INT LIST ILIST
+view3D VIEW3D SETCAT BASTYPE KOERCE NNI INT DFLOAT BOOLEAN PI FPS RNS
+ FIELD EUCDOM UFD GCDDOM DIVRING INTDOM ALGEBRA DIFRING
+ ORDRING MODULE FRAC RING ABELGRP ABELMON STRING CHAR SINT
+ OUTFORM LIST PRIMARR A1AGG ISTRING ILIST LSAGG STAGG PID
+ COMRING RNG CABMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ENTIRER UFD OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ OM FSAGG DIAGG DIOPS
+ BGAGG HOAGG AGG TYPE EVALAB IEVALAB CLAGG SETAGG FINITE
+ URAGG RCAGG LNAGG IXAGG ELTAGG ELTAB FLAGG ELAGG INS OINTDOM
+ LINEXP CFCAT STEP SRAGG STRICAT
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+algext.spad.pamphlet (SAE)
+aggcat.spad.pamphlet (AGG HOAGG CLAGG BGAGG SKAGG QUAGG DQAGG PRQAGG DIOPS
+ DIAGG MDAGG SETAGG FSAGG MSETAGG OMSAGG KDAGG ELTAB
+ ELTAGG ISAGG TBAGG RCAGG BRAGG DLAGG URAGG STAGG LNAGG
+ FLAGG A1AGG ELAGG LSAGG ALAGG SRAGG BTAGG ITAGG)
+aggcat2.spad.pamphlet (FLAGG2 FSAGG2)
+galfact.spad.pamphlet (GALFACT)
+intfact.spad.pamphlet (PRIMES IROOT INTFACT)
+padiclib.spad.pamphlet (IBPTOOLS IBACHIN PWFFINTB)
+perm.spad.pamphlet (PERMCAT PERM)
+permgrps.spad.pamphlet (PERMGRP PGE)
+random.spad.pamphlet (RANDSRC RDIST INTBIT RIDIST RFDIST)
+sgcf.spad.pamphlet (SGCF)
+string.spad.pamphlet (CHAR CCLASS ISTRING STRING STRICAT)
+view3D.spad.pamphlet (VIEW3D)
+\end{verbatim}
+
+<<layer17>>=
+LAYER17=${OUT}/CCLASS.o \
+ ${OUT}/FSAGG2.o ${OUT}/GALFACT.o ${OUT}/IALGFACT.o \
+ ${OUT}/IBACHIN.o ${OUT}/NORMMA.o ${OUT}/ODERED.o ${OUT}/OMSAGG.o \
+ ${OUT}/PERM.o ${OUT}/PERMGRP.o ${OUT}/PRIMES.o \
+ ${OUT}/PWFFINTB.o ${OUT}/RDIST.o \
+ ${OUT}/SAE.o ${OUT}/SAEFACT.o ${OUT}/SAERFFC.o ${OUT}/SGCF.o \
+ ${OUT}/TBAGG.o ${OUT}/TBAGG-.o ${OUT}/VIEW3D.o
+
+@
+\subsection{Layer18}
+\begin{verbatim}
+list ALIST ALAGG TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT
+ BASTYPE KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG
+ ELTAB LSAGG STAGG URAGG RCAGG LNAGG FLAGG ORDSET ELAGG INT
+ LIST ILIST OM INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP BOOLEAN STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING
+table EQTBL TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ORDSET
+table GSTBL TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE EVALAB IEVALAB
+ CLAGG KONVERT IXAGG ELTAGG ELTAB ORDSET
+table HASHTBL TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ORDSET
+table INTABL TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ORDSET
+d01agents INTFTBL TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+d01Package INTPACK FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ DIFRING OM TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG FLAGG ELAGG DFLOAT TBAGG KDAGG DIAGG DIOPS BGAGG
+ STRICAT SRAGG A1AGG
+pf IPF FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING CHARNZ FINITE STEP DIFRING FAXF XF RETRACT VSPACE
+ CHARZ KONVERT PI NNI INT LIST BOOLEAN OAMONS OCAMON OAMON
+ OASGP ORDSET TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE
+ EVALAB IEVALAB CLAGG IXAGG ELTAGG ELTAB SINT INS ILIST
+ OINTDOM ORDRING OAGROUP LINEXP PATMAB CFCAT REAL VECTOR
+ IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG
+files KAFILE FILECAT SETCAT BASTYPE KOERCE TBAGG KDAGG DIAGG DIOPS BGAGG
+ HOAGG AGG TYPE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG
+ FNCAT STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG
+ ISTRING LSAGG STAGG URAGG RCAGG LNAGG FLAGG ORDSET ELAGG OM
+ ILIST STRICAT SRAGG ORDFIN FINITE
+patmatch1 PATRES SETCAT BASTYPE KOERCE ORDSET ALAGG TBAGG KDAGG DIAGG DIOPS
+ BGAGG AGG TYPE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG
+ ELTAB LSAGG STAGG URAGG RCAGG LNAGG FLAGG ELAGG INT LIST
+ ILIST
+table STBL SETCAT BASTYPE KOERCE TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG
+ AGG TYPE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ORDSET
+table STRTBL TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ STRICAT SRAGG A1AGG FLAGG LNAGG ORDSET OM ORDFIN FINITE
+table TABLE TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ALAGG LSAGG STAGG URAGG RCAGG LNAGG FLAGG ORDSET ELAGG
+newdata TBCMPPK SETCAT BASTYPE KOERCE BOOLEAN NNI INT STRING CHAR SINT
+ OUTFORM LIST PRIMARR A1AGG ISTRING TBAGG KDAGG DIAGG BGAGG
+ HOAGG AGG TYPE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG
+ ELTAB
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+d01Package.spad.pamphlet (INTPACK)
+list.spad.pamphlet (ILIST LIST LIST2 LIST3 LIST2MAP ALIST)
+pf.spad.pamphlet (IPF PF)
+table.spad.pamphlet (HASHTBL INTABL TABLE EQTBL STRTBL GSTBL STBL)
+\end{verbatim}
+
+<<layer18>>=
+LAYER18=${OUT}/ALIST.o ${OUT}/EQTBL.o ${OUT}/GSTBL.o \
+ ${OUT}/HASHTBL.o ${OUT}/INTABL.o ${OUT}/INTFTBL.o ${OUT}/INTPACK.o \
+ ${OUT}/IPF.o ${OUT}/KAFILE.o ${OUT}/PATRES.o \
+ ${OUT}/STBL.o ${OUT}/STRTBL.o ${OUT}/TABLE.o \
+ ${OUT}/TBCMPPK.o
+
+@
+\subsection{Layer19}
+\begin{verbatim}
+algfunc ACF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ RADCAT SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ILIST UPOLYC
+ POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT ELTAB
+ DIFRING DIFEXT STEP LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ IXAGG ELTAGG CLAGG ELAGG OM BOOLEAN
+acplot ACPLOT PPCURVE KOERCE PI NNI INT DFLOAT FPS RNS FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ BOOLEAN INS OINTDOM DIFRING LINEXP CFCAT STEP QFCAT
+ FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP PATAB
+ FPATMAB TYPE CHARNZ PFECAT LIST ILIST LSAGG STAGG ELAGG
+ FLAGG URAGG OM RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG
+ ELAGG REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG POLYCAT FAMR AMR FRETRCT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN
+derham ANTISYM LALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE RETRACT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST
+ BOOLEAN NNI SINT PI EUCDOM UFD GCDDOM INTDOM ALGEBRA
+ DIFRING ORDRING MODULE RING ABELGRP SYMBOL REF ALIST
+any ANY SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG ILIST LSAGG
+asp ASP12 FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM
+asp ASP27 FMC FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ SINT PI NNI INT SYMBOL REF ALIST LIST STRING CHAR
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG FMTC
+asp ASP28 FMC FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ SINT PI NNI INT SYMBOL REF ALIST LIST STRING
+ CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG FMTC
+ VECTOR
+asp ASP33 FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN
+asp ASP49 FORTFN FORTCAT TYPE KOERCE BOOLEAN SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ ES IEVALAB
+ EVALAB VECTCAT IXAGG HOAGG AGG ELTAGG CLAGG LSAGG STAGG
+ URAGG RCAGG ELAGG FMTC INS OINTDOM DIFRING LINEXP CFCAT
+ STEP POLYCAT PDRING FAMR AMR CHARNZ FRETRCT FLINEXP
+ PFECAT
+asp ASP55 FVFUN FORTCAT TYPE KOERCE BOOLEAN SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG ILIST FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ INS
+ OINTDOM DIFRING LINEXP CFCAT STEP OM VECTOR IVECTOR IARRAY1
+ NNI IXAGG LSAGG STAGG URAGG RCAGG HOAGG AGG EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG ES VECTCAT FMTC POLYCAT PDRING FAMR AMR
+ CHARNZ FRETRCT FLINEXP PFECAT
+asp ASP7 FVFUN FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ FMTC INS OINTDOM
+ DIFRING LINEXP CFCAT STEP POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP PFECAT
+asp ASP78 FVFUN FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ FMTC INS OINTDOM DIFRING
+ LINEXP CFCAT STEP POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ EVALAB IEVALAB FLINEXP PFECAT
+asp ASP8 FVC FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ SYMBOL INT REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG INS OINTDOM
+ DIFRING LINEXP CFCAT STEP VECTCAT IXAGG HOAGG AGG EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG VECTOR IVECTOR IARRAY1 FMTC NNI
+ OM ILIST
+asp ASP9 FORTFN FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG BOOLEAN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ FMTC
+ INS OINTDOM DIFRING LINEXP CFCAT STEP POLYCAT PDRING FAMR
+ AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT
+routines ATTRBUT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT
+ RETRACT RADCAT PATMAB CHARZ INT LIST ILIST SYMBOL REF ALIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG
+op BOP ORDSET SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG STRICAT IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG
+ ELTAB CLAGG KONVERT OM BOOLEAN NNI FSAGG DIAGG DIOPS BGAGG
+ SETAGG FINITE ORDFIN
+op BOP1 SETCAT BASTYPE KOERCE ORDSET SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG NNI BOOLEAN KONVERT
+op COMMONOP BOOLEAN SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG NNI ILIST LSAGG
+ STAGG PI
+gaussian COMPCAT COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ MONOGEN FRAMALG FINRALG ALGEBRA MODULE CHARZ CHARNZ
+ KONVERT FRETRCT RETRACT FLINEXP LINEXP FINITE FIELD EUCDOM
+ PID GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT DIFRING PDRING
+ FFIELDC FPC STEP FEVALAB ELTAB EVALAB IEVALAB FPATMAB TYPE
+ PATMAB PATAB ORDSET TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN RADCAT PFECAT NNI INT PI INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP CFCAT REAL BOOLEAN UPOLYC
+ POLYCAT FAMR AMR LIST OM VECTOR IVECTOR IARRAY1 VECTCAT
+ A1AGG FLAGG LNAGG AGG ELTAGG CLAGG SYMBOL REF ALIST STRING
+ CHAR SINT OUTFORM PRIMARR ISTRING SRAGG RNS FPS
+draw DRAW KONVERT SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG ILIST NNI FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL RETRACT
+ RADCAT PATMAB CHARZ
+draw DRAWCFUN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG ILIST LSAGG STAGG ELAGG URAGG DFLOAT DIFRING
+ OM TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PI PTCAT
+ VECTCAT IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB
+ CLAGG BOOLEAN
+drawopt DROPT SETCAT BASTYPE KOERCE LSAGG STAGG URAGG HOAGG AGG TYPE
+ EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ORDSET ELAGG OM INT LIST ILIST INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP SYMBOL REF ALIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+drawopt DROPT0 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ
+d01routine D01ANFA NUMINT SETCAT BASTYPE KOERCE NNI INT SYMBOL REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT
+ RADCAT PATMAB CHARZ DIFRING OM TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN PI INS
+d01routine D01ASFA NNI INT SYMBOL REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ DIFRING OM TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PI
+ INS DFLOAT
+d03agents D03AGNT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ DIFRING OM TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN NNI INT INS OINTDOM
+ LINEXP CFCAT STEP SYMBOL REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB IXAGG ELTAGG ELTAB
+ CLAGG ELAGG ILIST DFLOAT PI BOOLEAN
+eigen EP GCDDOM INT COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET KONVERT OM PATMAB POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP PFECAT UFD QFCAT FIELD EUCDOM PID DIVRING
+ FEVALAB ELTAB DIFEXT DIFRING PATAB FPATMAB TYPE STEP
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL NNI INT
+ BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG LIST ILIST SINT PI SYMBOL REF ALIST
+ STRING CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG UPOLYC
+ VECTOR IVECTOR IARRAY1
+e04agents E04AGNT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ DIFRING OM TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN DFLOAT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG FLAGG ELAGG INT LIST ILIST SINT NNI INS OINTDOM
+ LINEXP CFCAT STEP QFCAT FEVALAB DIFEXT PDRING FLINEXP PATAB
+ FPATMAB CHARNZ PFECAT BOOLEAN SYMBOL REF ALIST STRING CHAR
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG PI VECTOR
+fortpak FCPAK1 INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM SYMBOL INT
+ REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG
+fortran FEXPR ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB
+ ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE MODULE BMODULE RMODULE PDRING FMTC INTDOM
+ COMRING ENTIRER BOOLEAN SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE IXAGG ELTAGG ELTAB
+ CLAGG KONVERT ELAGG OM ILIST NNI PATMAB INS UFD GCDDOM
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING LINEXP CFCAT REAL CHARZ STEP POLYCAT FAMR AMR
+ CHARNZ FRETRCT FLINEXP PFECAT FPS RNS FIELD DIVRING RADCAT
+curve FFCAT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING QFCAT FEVALAB
+ PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG ELTAGG CLAGG INS
+ CFCAT OM
+ffcg FFCGP FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC STEP
+ DIFRING NNI INT ORDSET PI SINT PRIMARR SYMBOL REF ALIST
+ LIST STRING CHAR OUTFORM A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN OAMONS OCAMON OAMON OASGP ORDSET VECTOR IVECTOR
+ IARRAY1 INS ORDRING ILIST OINTDOM OAGROUP KONVERT LINEXP
+ PATMAB CFCAT REAL
+ffp FFNBP FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING SYMBOL INT REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN PI
+ NNI VECTOR IVECTOR IARRAY1 VECTCAT IXAGG HOAGG AGG TYPE
+ EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT ORDSET OAMONS
+ OCAMON OAMON OASGP TBAGG KDAGG DIAGG DIOPS BGAGG UPOLYC
+ POLYCAT PDRING FAMR AMR FRETRCT FLINEXP LINEXP PATMAB
+ PFECAT DIFEXT LSAGG STAGG URAGG RCAGG ELAGG OM ILIST INS
+ OINTDOM ORDRING OAGROUP CFCAT REAL
+ffp FFP FAXF XF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RETRACT VSPACE CHARZ FPC CHARNZ FINITE FFIELDC
+ STEP DIFRING SYMBOL INT REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG NNI ORDSET
+ PI BOOLEAN OAMONS OCAMON OAMON OASGP ORDSET TBAGG KDAGG
+ DIAGG DIOPS BGAGG HOAGG AGG TYPE EVALAB IEVALAB CLAGG
+ KONVERT IXAGG ELTAGG ELTAB VECTOR IVECTOR IARRAY1 VECTCAT
+ ILIST LSAGG STAGG ELAGG INS OINTDOM ORDRING OAGROUP LINEXP
+ PATMAB CFCAT REAL
+float FLOAT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ DIFRING OM TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PI NNI INT INS SINT
+ BOOLEAN OINTDOM LINEXP CFCAT STEP STRICAT SRAGG A1AGG FLAGG
+ LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG
+ STRING CHAR OUTFORM LIST PRIMARR ISTRING SYMBOL REF ALIST
+ DFLOAT
+fparfrac FPARFRAC SETCAT BASTYPE KOERCE KONVERT UPOLYC POLYCAT PDRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ FAMR AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP
+ EUCDOM PID FIELD DIVRING SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ NNI QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL PI OM ILIST LSAGG STAGG DPOLCAT INS
+ CFCAT
+fr FR INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER DIFEXT DIFRING PDRING FEVALAB ELTAB EVALAB
+ IEVALAB FRETRCT RETRACT GCDDOM REAL KONVERT UFD INT LIST
+ ILIST SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG ORDSET BOOLEAN LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE IXAGG ELTAGG CLAGG ELAGG OM NNI
+ INS EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ LINEXP PATMAB CFCAT CHARZ STEP DFLOAT
+naalgc FRNAALG FINAALG NAALG NARNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE MONAD MODULE BMODULE LMODULE RMODULE COMRING
+ RING RNG SGROUP MONOID FIELD EUCDOM PID GCDDOM INTDOM
+ ALGEBRA ENTIRER UFD DIVRING SINT PI NNI INT STRING CHAR
+ OUTFORM LIST PRIMARR A1AGG ISTRING SYMBOL REF ALIST SRAGG
+ FLAGG LNAGG POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB
+ PFECAT VECTOR IVECTOR IARRAY1 VECTCAT IXAGG HOAGG AGG TYPE
+ ELTAGG ELTAB CLAGG ILIST INS OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP DIFRING CFCAT REAL STEP OM
+fspace FS ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID SGROUP
+ GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE
+ PDRING FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE
+ RMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD
+ DIVRING SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG STAGG ELAGG
+ URAGG RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG OM CACHSET
+ NNI POLYCAT FAMR AMR PFECAT INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING CFCAT REAL STEP FPS RNS RADCAT
+ UPOLYC DIFEXT QFCAT FEVALAB
+fortran FST KOERCE SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN
+variable FUNCTION SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN
+gdpoly GDMP POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD DIRPCAT IXAGG HOAGG AGG TYPE ELTAGG
+ ELTAB DIFEXT DIFRING FINITE ORDRING OAGROUP OCAMON OAMON
+ OASGP OAMONS VSPACE FIELD EUCDOM PID DIVRING ORDFIN LSAGG
+ STAGG URAGG RCAGG LNAGG CLAGG FLAGG ELAGG OM INT LIST ILIST
+ NNI VECTCAT A1AGG VECTOR IVECTOR IARRAY1 SINT PI BOOLEAN
+ FPS RNS REAL RADCAT SYMBOL REF ALIST STRING CHAR OUTFORM
+ PRIMARR ISTRING SRAGG INS OINTDOM CFCAT STEP UPOLYC
+expr HACKPI FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT REAL KONVERT INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET DIFRING LINEXP PATMAB CFCAT STEP
+ UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB
+ FLINEXP PFECAT ELTAB DIFEXT SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ NNI DFLOAT OM BOOLEAN FPS RNS RADCAT
+ideal IDEAL SETCAT BASTYPE KOERCE FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING OAMONS
+ OCAMON OAMON OASGP ORDSET POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ PATMAB PFECAT NNI INT LIST ILIST LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM
+ SINT SYMBOL REF ALIST STRING CHAR OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG DIRPCAT DIFEXT DIFRING FINITE ORDRING OAGROUP
+ VSPACE ORDFIN VECTOR IVECTOR IARRAY1 VECTCAT
+mkfunc INFORM SEXCAT SETCAT BASTYPE KOERCE KONVERT ORDSET INS UFD GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP FPS RNS FIELD
+ DIVRING RADCAT INT SYMBOL REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG DFLOAT
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB IXAGG
+ ELTAGG ELTAB CLAGG ELAGG OM ILIST NNI STRICAT
+mkfunc INFORM1 TYPE SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+newdata IPRNTPK SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG
+intaux IR MODULE BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE RMODULE RETRACT INS UFD GCDDOM INTDOM COMRING
+ RING RNG SGROUP MONOID ALGEBRA ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FIELD DIVRING
+ FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP PATAB
+ FPATMAB TYPE CHARNZ PFECAT SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ ILIST NNI BOOLEAN LFCAT PRIMCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN LSAGG STAGG ELAGG URAGG RCAGG IXAGG PI
+ HOAGG AGG ELTAGG CLAGG OM
+sups ISUPS UPSCAT PSCAT AMR RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER ELTAB
+ DIFRING PDRING INS UFD GCDDOM EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET KONVERT RETRACT LINEXP
+ PATMAB CFCAT REAL STEP BOOLEAN INT OM SINT NNI LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG TRANFUN TRIGCAT ATRIG HYPCAT
+ ATRIG HYPCAT AHYP ELEMFUN STRING CHAR OUTFORM PRIMARR A1AGG
+ ISTRING SYMBOL REF ALIST SRAGG LNAGG RCAGG HOAGG AGG TYPE
+ EVALAB IEVALAB IXAGG ELTAGG CLAGG ELAGG FIELD DIVRING
+kl KERNEL CACHSET ORDSET SETCAT BASTYPE KOERCE PATAB KONVERT INT NNI
+ LIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM ILIST SYMBOL
+ REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG INS UFD GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP FPS RNS FIELD DIVRING RADCAT
+files LIB TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG STRICAT ORDSET OM ORDFIN
+ FINITE
+lmdict LMDICT MDAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE
+ EVALAB IEVALAB CLAGG KONVERT LSAGG STAGG URAGG RCAGG LNAGG
+ IXAGG ELTAGG ELTAB FLAGG ORDSET ELAGG OM INT SYMBOL REF
+ ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ NNI BOOLEAN
+lodo LODOOPS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ LODOCAT OREPCAT FRETRCT RETRACT ELTAB SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG VECTCAT IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG CLAGG KONVERT ORDSET VECTOR IVECTOR IARRAY1 PI INS
+ DPOLCAT POLYCAT PDRING FAMR AMR CHARZ CHARNZ FLINEXP LINEXP
+ PATMAB PFECAT DIFEXT DIFRING ILIST LSAGG BOOLEAN
+matrix MATRIX MATCAT ARR2CAT HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB KONVERT VECTCAT A1AGG FLAGG LNAGG IXAGG ELTAGG
+ ELTAB CLAGG ORDSET RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE INT PRIMARR NNI EUCDOM PID GCDDOM
+ INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE ENTIRER FIELD
+ UFD DIVRING INS VECTOR IVECTOR IARRAY1 OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP OM SYMBOL REF ALIST LIST STRING CHAR
+ SINT OUTFORM ISTRING SRAGG LSAGG STAGG URAGG RCAGG ELAGG
+mkfunc MKFLCFN KONVERT SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ILIST LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB
+ IEVALAB IXAGG ELTAGG ELTAB CLAGG ORDSET ELAGG OM STRICAT
+ DFLOAT
+mset MSET MSETAGG MDAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT SETAGG INS UFD GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ
+ STEP INT SYMBOL REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ILIST LSAGG STAGG
+ URAGG RCAGG IXAGG ELTAGG ELTAB ELAGG OM NNI BOOLEAN
+fortran M3D HOAGG AGG TYPE SETCAT BASTYPE KOERCE EVALAB IEVALAB SYMBOL
+ INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG NNI VECTOR IVECTOR IARRAY1 PI
+ IXAGG ELTAGG ELTAB CLAGG KONVERT ORDSET VECTCAT RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE LSAGG
+ STAGG URAGG RCAGG ELAGG OM ILIST
+c02 NAGC02 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING STAGG FLAGG LNAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT
+ RADCAT PATMAB CHARZ
+c05 NAGC05 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT
+ RADCAT PATMAB CHARZ
+c06 NAGC06 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT
+ RADCAT PATMAB CHARZ
+d03 NAGD03 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ
+e01 NAGE01 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ INS OINTDOM DIFRING LINEXP CFCAT STEP
+e02 NAGE02 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ INS OINTDOM DIFRING LINEXP CFCAT STEP
+e04 NAGE04 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ INS OINTDOM DIFRING LINEXP CFCAT STEP
+f07 NAGF07 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ INS OINTDOM DIFRING LINEXP CFCAT STEP
+s NAGS SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+fortpak NAGSP SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN FPS RNS FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ INT OINTDOM DIFRING LINEXP CFCAT STEP
+numeigen NREP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET SYMBOL INT REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG INS OINTDOM DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FEVALAB ELTAB
+ EVALAB IEVALAB DIFEXT PDRING FLINEXP PATAB FPATMAB TYPE
+ CHARNZ PFECAT UPOLYC POLYCAT FAMR AMR FRETRCT
+outform NUMFMT STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG IXAGG STRICAT HOAGG AGG TYPE SETCAT
+ BASTYPE KOERCE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+ ORDSET OM BOOLEAN SYMBOL REF ALIST INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP PI NNI
+oct OC COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE FRETRCT RETRACT FEVALAB ELTAB EVALAB IEVALAB FINITE
+ ORDSET KONVERT CHARZ CHARNZ BOOLEAN SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD
+ DIVRING RNS ORDRING OAGROUP OCAMON OAMON OASGP REAL RADCAT
+ PATMAB INS OINTDOM DIFRING LINEXP CFCAT STEP
+d02Package ODEPACK FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG FLAGG ELAGG OM INT LIST ILIST INS STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG TBAGG KDAGG DIAGG DIOPS
+ BGAGG NNI SYMBOL REF ALIST DFLOAT DIFRING TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN PI VECTCAT A1AGG VECTOR IVECTOR
+ IARRAY1
+oderf ODERAT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL LSAGG STAGG URAGG RCAGG HOAGG AGG
+ IXAGG ELTAGG CLAGG ELAGG OM ILIST NNI INS CFCAT VECTOR
+ IVECTOR IARRAY1 VECTCAT A1AGG PI BOOLEAN
+omerror OMERR SETCAT BASTYPE KOERCE LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ORDSET ELAGG OM INT LIST ILIST NNI SYMBOL REF ALIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG PI
+omerror OMERRK SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+e04Package OPTPACK FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ STRING CHAR SINT OUTFORM
+ LIST INT PRIMARR A1AGG ISTRING SRAGG ILIST TBAGG KDAGG
+ DIAGG DIOPS BGAGG HOAGG AGG TYPE EVALAB IEVALAB CLAGG IXAGG
+ ELTAGG ELTAB NNI SYMBOL REF ALIST FLAGG LNAGG LSAGG STAGG
+ ELAGG INS DFLOAT PI RCAGG OM DIFRING TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN
+fnla OSI ORDSET SETCAT BASTYPE KOERCE INT SYMBOL REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG
+variable OVAR ORDFIN ORDSET SETCAT BASTYPE KOERCE FINITE KONVERT FPS RNS
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL RETRACT RADCAT PATMAB CHARZ INS OINTDOM
+ DIFRING LINEXP CFCAT STEP LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG OM INT LIST ILIST SYMBOL REF ALIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG NNI
+pattern PATTERN SETCAT BASTYPE KOERCE RETRACT SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG BOOLEAN NNI ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB IXAGG ELTAGG ELTAB CLAGG KONVERT ORDSET
+ ELAGG OM MONOID SGROUP ABELMON ABELSG PI
+patmatch1 PMKERNEL SETCAT BASTYPE KOERCE ORDSET RETRACT KONVERT PATMAB LSAGG
+ STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST NNI SYMBOL
+ REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG MONOID SGROUP ABELMON ABELSG
+patmatch1 PMSYM SETCAT BASTYPE KOERCE ORDSET SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG
+multpoly POLY POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ FPS RNS FIELD EUCDOM PID DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL RADCAT INS OINTDOM DIFRING CFCAT STEP
+ UPOLYC ELTAB DIFEXT
+primelt PRIMELT FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ SINT NNI INT INS LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG KONVERT
+ FLAGG ORDSET ELAGG OM PATMAB LIST ILIST SYMBOL REF ALIST
+ STRING CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT RETRACT FLINEXP LINEXP PFECAT
+qalgset QALGSET2 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG ILIST INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ QFCAT FIELD DIVRING FEVALAB ELTAB EVALAB IEVALAB DIFEXT
+ PDRING FLINEXP PATAB FPATMAB TYPE CHARNZ PFECAT DIRPCAT
+ IXAGG HOAGG AGG ELTAGG FRETRCT FINITE OAMONS VSPACE
+ POLYCAT FAMR AMR LSAGG STAGG URAGG RCAGG CLAGG OM BOOLEAN
+alql QEQUAT KOERCE SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+quat QUATCAT COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE FRETRCT RETRACT DIFEXT DIFRING PDRING
+ FEVALAB ELTAB EVALAB IEVALAB FLINEXP LINEXP ENTIRER ORDSET
+ DIVRING KONVERT CHARZ CHARNZ FIELD EUCDOM PID GCDDOM INTDOM
+ UFD BOOLEAN SYMBOL INT REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG RNS ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL RADCAT PATMAB INS OINTDOM
+ CFCAT STEP
+reclos RECLOS RCFIELD CHARZ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET COMRING BMODULE RMODULE FIELD EUCDOM PID
+ GCDDOM INTDOM ALGEBRA MODULE ENTIRER UFD DIVRING FRETRCT
+ RETRACT RADCAT REAL KONVERT PI NNI INT SYMBOL REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG INS OINTDOM DIFRING LINEXP PATMAB CFCAT STEP
+ ILIST LSAGG STAGG ELAGG URAGG RCAGG IXAGG CLAGG HOAGG AGG
+ ELTAGG TYPE EVALAB IEVALAB ELTAB OM BOOLEAN QFCAT FEVALAB
+ DIFEXT PDRING FLINEXP PATAB FPATMAB CHARNZ PFECAT
+regset REP1 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE INT SINT INS UFD GCDDOM INTDOM COMRING
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG LNAGG NNI VECTOR IVECTOR
+ IARRAY1 VECTCAT A1AGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG PI BOOLEAN RCAGG POLYCAT PDRING FAMR AMR
+ CHARNZ FRETRCT FLINEXP PFECAT SYMBOL REF ALIST STRING CHAR
+ OUTFORM PRIMARR ISTRING SRAGG
+fortran RESULT TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ORDSET SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN LSAGG STAGG
+ URAGG RCAGG ELAGG OM ILIST
+algfact RFFACT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING SYMBOL INT
+ REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ STRING SRAGG FLAGG LNAGG INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP CFCAT REAL QFCAT FEVALAB PATAB FPATMAB
+ TYPE
+matrix RMATRIX RMATCAT BMODULE LMODULE ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE RMODULE HOAGG AGG TYPE EVALAB IEVALAB MODULE
+ COMRING RING RNG SGROUP MONOID VSPACE KONVERT FIELD EUCDOM
+ PID GCDDOM INTDOM ALGEBRA ENTIRER UFD DIVRING NNI INT LSAGG
+ STAGG URAGG RCAGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ORDSET ELAGG OM LIST ILIST SYMBOL REF ALIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG
+integer ROMAN INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP SYMBOL INT REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG
+routines ROUTINE TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG ELTAGG ELTAB
+ ORDSET STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG
+ ISTRING BOOLEAN ILIST LSAGG STAGG PI NNI SYMBOL REF ALIST
+ SRAGG FLAGG LNAGG URAGG RCAGG ELAGG OM
+newpoly RPOLCAT POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD OAMONS OCAMON OAMON OASGP NNI INT
+ LIST BOOLEAN ILIST EUCDOM PID FIELD DIVRING FINITE SINT OM
+ LSAGG STAGG ELAGG FLAGG INS OINTDOM ORDRING OAGROUP DIFRING
+ CFCAT REAL STEP QFCAT FEVALAB ELTAB DIFEXT PATAB FPATMAB
+ TYPE RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG STRING CHAR
+ OUTFORM PRIMARR A1AGG ISTRING SYMBOL REF ALIST SRAGG STRICAT
+ FPS RNS RADCAT
+variable RULECOLD SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN
+misc SAOS ORDSET SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG
+seg SEGBIND TYPE SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN
+sets SET FSAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB CLAGG KONVERT SETAGG FINITE A1AGG
+ FLAGG LNAGG IXAGG ELTAGG ELTAB ORDSET ELAGG INS UFD GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM
+ PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM SYMBOL INT
+ REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR ISTRING
+ SRAGG LSAGG STAGG URAGG RCAGG ILIST NNI BOOLEAN
+out SPECOUT SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG
+matrix SQMATRIX SMATCAT DIFEXT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE DIFRING PDRING BMODULE
+ RMODULE RMATCAT HOAGG AGG TYPE EVALAB IEVALAB MODULE COMRING
+ FRETRCT RETRACT FLINEXP LINEXP ALGEBRA KONVERT NNI INT
+ LSAGG STAGG URAGG RCAGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ORDSET ELAGG OM LIST ILIST EUCDOM PID GCDDOM INTDOM ENTIRER
+ FIELD UFD DIVRING SYMBOL REF ALIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP PATMAB CFCAT REAL CHARZ STEP
+fortran SWITCH KOERCE INT LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE SETCAT BASTYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB
+ CLAGG KONVERT FLAGG ORDSET ELAGG OM INS UFD GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP NNI
+ SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG
+forttyp SYMS KOERCE ORDSET SETCAT BASTYPE SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG ILIST
+forttyp SYMTAB KOERCE ORDSET SETCAT BASTYPE INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP INT LIST ILIST
+ OM SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG LSAGG STAGG ELAGG URAGG RCAGG
+ IXAGG CLAGG HOAGG AGG ELTAGG
+syssolp SYSSOLP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB
+ GCDDOM PFECAT UFD QFCAT FIELD EUCDOM PID DIVRING FEVALAB
+ ELTAB DIFEXT DIFRING PATAB FPATMAB TYPE STEP OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL OM INT LIST ILIST LSAGG
+ STAGG ELAGG FLAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG
+ CLAGG NNI SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG BOOLEAN DIRPCAT FINITE OAMONS VSPACE
+ ORDFIN VECTOR IVECTOR IARRAY1 VECTCAT
+pscat UTSCAT OAMONS OCAMON OAMON OASGP ORDSET SETCAT BASTYPE KOERCE
+ ABELMON ABELSG CABMON UPSCAT PSCAT AMR RING RNG ABELGRP
+ SGROUP MONOID LMODULE BMODULE RMODULE COMRING ALGEBRA MODULE
+ CHARZ CHARNZ INTDOM ENTIRER ELTAB DIFRING PDRING RADCAT
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN BOOLEAN INT
+ SYMBOL REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG ILIST NNI LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB IXAGG ELTAGG CLAGG
+ KONVERT ELAGG OM FIELD EUCDOM PID GCDDOM UFD DIVRING INS
+ OINTDOM ORDRING OAGROUP RETRACT LINEXP PATMAB CFCAT REAL
+ STEP
+variable VARIABLE SETCAT BASTYPE KOERCE SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN
+intclos WFFINTBS FFIELDC FPC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING CHARNZ FINITE STEP DIFRING UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB PFECAT ELTAB DIFEXT FRAMALG FINRALG
+ INT LIST ILIST SINT PI NNI VECTOR IVECTOR IARRAY1 VECTCAT
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG MONOGEN
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+acplot.spad.pamphlet (REALSOLV ACPLOT)
+alql.spad.pamphlet (DLIST ICARD DBASE QEQUAT MTHING OPQUERY)
+any.spad.pamphlet (NONE NONE1 ANY ANY1)
+c02.spad.pamphlet (NAGC02)
+c05.spad.pamphlet (NAGC05)
+c06.spad.pamphlet (NAGC06)
+d01routine.spad.pamphlet (D01AJFA D01AKFA D01AMFA D01APFA D01AQFA D01ALFA
+ D01ANFA D01ASFA D01GBFA D01FCFA)
+d02Package.spad.pamphlet (ODEPACK)
+d03agents.spad.pamphlet (D03AGNT)
+d03Package.spad.pamphlet (PDEPACK)
+drawopt.spad.pamphlet (DROPT DROPT1 DROPT0)
+eigen.spad.pamphlet (EP CHARPOL)
+e01.spad.pamphlet (NAGE01)
+e02.spad.pamphlet (NAGE02)
+e04.spad.pamphlet (NAGE04)
+e04agents.spad.pamphlet (E04AGNT)
+e04Package.spad.pamphlet (OPTPACK)
+ffcg.spad.pamphlet (FFCGP FFCGX FFCG)
+ffp.spad.pamphlet (FFP FFX IFF FF)
+files.spad.pamphlet (FILECAT FILE TEXTFILE BINFILE KAFILE LIB)
+float.spad.pamphlet (FLOAT)
+fnla.spad.pamphlet (OSI COMM HB FNLA)
+fortpak.spad.pamphlet (FCPAK1 NAGSP FORT FOP TEMUTL MCALCFN)
+forttyp.spad.pamphlet (FST FT SYMTAB SYMS)
+fparfrac.spad.pamphlet (FPARFRAC)
+fr.spad.pamphlet (FR FRUTIL FR2)
+f07.spad.pamphlet (NAGF07)
+gdpoly.spad.pamphlet (GDMP DMP HDMP)
+ideal.spad.pamphlet (IDEAL)
+intaux.spad.pamphlet (IR IR2)
+intclos.spad.pamphlet (TRIMAT IBATOOL FFINTBAS WFFINTBS NFINTBAS)
+integer.spad.pamphlet (INTSLPE INT NNI PI ROMAN)
+kl.spad.pamphlet (CACHSET SCACHE MKCHSET KERNEL KERNEL2)
+lmdict.spad.pamphlet (LMDICT)
+matrix.spad.pamphlet (IMATRIX MATRIX RMATRIX SQMATRIX)
+misc.spad.pamphlet (SAOS)
+mkfunc.spad.pamphlet (INFORM INFORM1 MKFUNC MKUCFUNC MKBCFUNC MKFLCFN)
+modgcd.spad.pamphlet (INMODGCD)
+mset.spad.pamphlet (MSET)
+multpoly.spad.pamphlet (POLY POLY2 MPOLY SMP INDE)
+naalgc.spad.pamphlet (MONAD MONADWU NARNG NASRING NAALG FINAALG FRNAALG)
+newdata.spad.pamphlet (IPRNTPK TBCMPPK SPLNODE SPLTREE)
+omerror.spad.pamphlet (OMERRK OMERR)
+op.spad.pamphlet (BOP BOP1 COMMONOP)
+out.spad.pamphlet (OUT SPECOUT DISPLAY)
+outform.spad.pamphlet (NUMFMT OUTFORM)
+patmatch1.spad.pamphlet (PATRES PATRES2 PATLRES PATMAB FPATMAB PMSYM PMKERNEL
+ PMDOWN PMTOOLS PMLSAGG)
+pattern.spad.pamphlet (PATTERN PATTERN1 PATTERN2 PATAB)
+pscat.spad.pamphlet (PSCAT UPSCAT UTSCAT ULSCAT UPXSCAT MTSCAT)
+qalgset.spad.pamphlet (QALGSET QALGSET2)
+reclos.spad.pamphlet (POLUTIL RRCC RCFIELD ROIRC RECLOS)
+rep1.spad.pamphlet (REP1)
+routines.spad.pamphlet (ROUTINE ATTRBUT)
+s.spad.pamphlet (NAGS)
+seg.spad.pamphlet (SEGCAT SEGXCAT SEG SEG2 SEGBIND SETBIND2 UNISEG UNISEG2
+ INCRMAPS)
+sets.spad.pamphlet (SET)
+sups.spad.pamphlet (ISUPS)
+syssolp.spad.pamphlet (SYSSOLP)
+variable.spad.pamphlet (OVAR VARIABLE RULECOLD FUNCTION ANON)
+\end{verbatim}
+
+<<layer19>>=
+LAYER19=${OUT}/ACF.o ${OUT}/ACF-.o ${OUT}/ACPLOT.o ${OUT}/ANTISYM.o \
+ ${OUT}/ANY.o \
+ ${OUT}/ASP12.o ${OUT}/ASP27.o ${OUT}/ASP28.o ${OUT}/ASP33.o \
+ ${OUT}/ASP49.o ${OUT}/ASP55.o ${OUT}/ASP7.o ${OUT}/ASP78.o \
+ ${OUT}/ASP8.o ${OUT}/ASP9.o ${OUT}/ATTRBUT.o \
+ ${OUT}/BOP.o ${OUT}/BOP1.o ${OUT}/COMMONOP.o \
+ ${OUT}/COMPCAT.o ${OUT}/COMPCAT-.o ${OUT}/DRAW.o ${OUT}/DRAWCFUN.o \
+ ${OUT}/DROPT.o ${OUT}/DROPT0.o ${OUT}/D01ANFA.o \
+ ${OUT}/D01ASFA.o ${OUT}/D03AGNT.o ${OUT}/EP.o ${OUT}/E04AGNT.o \
+ ${OUT}/FCPAK1.o ${OUT}/FEXPR.o \
+ ${OUT}/FFCAT.o ${OUT}/FFCAT-.o ${OUT}/FFCGP.o ${OUT}/FFNBP.o \
+ ${OUT}/FFP.o ${OUT}/FLOAT.o ${OUT}/FPARFRAC.o ${OUT}/FR.o \
+ ${OUT}/FRNAALG.o ${OUT}/FRNAALG-.o \
+ ${OUT}/FS.o ${OUT}/FS-.o ${OUT}/FST.o ${OUT}/FUNCTION.o \
+ ${OUT}/GDMP.o \
+ ${OUT}/HACKPI.o ${OUT}/IDEAL.o ${OUT}/INFORM.o ${OUT}/INFORM1.o \
+ ${OUT}/IPRNTPK.o ${OUT}/IR.o ${OUT}/ISUPS.o ${OUT}/KERNEL.o \
+ ${OUT}/LIB.o ${OUT}/LMDICT.o ${OUT}/LODOOPS.o ${OUT}/MATRIX.o \
+ ${OUT}/MKFLCFN.o ${OUT}/MSET.o ${OUT}/M3D.o \
+ ${OUT}/NAGC02.o ${OUT}/NAGC05.o ${OUT}/NAGC06.o ${OUT}/NAGD03.o \
+ ${OUT}/NAGE01.o ${OUT}/NAGE02.o ${OUT}/NAGE04.o ${OUT}/NAGF07.o \
+ ${OUT}/NAGS.o \
+ ${OUT}/NAGSP.o ${OUT}/NREP.o ${OUT}/NUMFMT.o ${OUT}/OC.o ${OUT}/OC-.o \
+ ${OUT}/ODEPACK.o ${OUT}/ODERAT.o ${OUT}/OMERR.o ${OUT}/OMERRK.o \
+ ${OUT}/OPTPACK.o ${OUT}/OSI.o ${OUT}/PATTERN.o ${OUT}/OVAR.o \
+ ${OUT}/PMKERNEL.o \
+ ${OUT}/PMSYM.o ${OUT}/POLY.o ${OUT}/PRIMELT.o ${OUT}/QALGSET2.o \
+ ${OUT}/QEQUAT.o ${OUT}/RECLOS.o ${OUT}/REP1.o ${OUT}/RESULT.o \
+ ${OUT}/QUATCAT.o ${OUT}/QUATCAT-.o \
+ ${OUT}/RFFACT.o ${OUT}/RMATRIX.o ${OUT}/ROMAN.o ${OUT}/ROUTINE.o \
+ ${OUT}/RPOLCAT.o ${OUT}/RPOLCAT-.o ${OUT}/RULECOLD.o \
+ ${OUT}/SAOS.o ${OUT}/SEGBIND.o ${OUT}/SET.o ${OUT}/SPECOUT.o \
+ ${OUT}/SQMATRIX.o \
+ ${OUT}/SWITCH.o ${OUT}/SYMS.o ${OUT}/SYMTAB.o ${OUT}/SYSSOLP.o \
+ ${OUT}/UTSCAT.o ${OUT}/UTSCAT-.o ${OUT}/VARIABLE.o ${OUT}/WFFINTBS.o
+
+
+@
+\subsection{Layer20}
+\begin{verbatim}
+algfunc ACFS ACF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RADCAT FS ES ORDSET RETRACT IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ INT LIST ILIST UPOLYC POLYCAT FAMR
+ AMR PFECAT ELTAB DIFRING DIFEXT STEP NNI
+algfunc AF ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER FS ES RETRACT
+ IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT
+ GROUP PDRING FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM
+ PID GCDDOM UFD DIVRING SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG ILIST LSAGG STAGG ELAGG URAGG UPOLYC POLYCAT FAMR
+ AMR PFECAT ELTAB DIFRING DIFEXT STEP NNI ACF RADCAT
+ BOOLEAN CACHSET INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP CFCAT REAL
+algfact ALGFACT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING INT LIST
+ ILIST LSAGG STAGG ES URAGG RCAGG HOAGG AGG TYPE LNAGG
+ IXAGG ELTAGG CLAGG FLAGG ELAGG OM CACHSET PATAB INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL
+ QFCAT FEVALAB FPATMAB ACF RADCAT NNI BOOLEAN MONOGEN
+ FRAMALG FINRALG FINITE FFIELDC FPC
+curve ALGFF UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING FFCAT MONOGEN
+ FRAMALG FINRALG FINITE FFIELDC FPC QFCAT FEVALAB PATAB
+ FPATMAB TYPE OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ REAL VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG ELTAGG CLAGG
+ INS CFCAT OM
+manip ALGMANIP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER FIELD EUCDOM PID GCDDOM UFD DIVRING
+ ES ORDSET RETRACT IEVALAB EVALAB SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG ILIST LSAGG CACHSET UPOLYC POLYCAT PDRING FAMR AMR
+ CHARZ CHARNZ FRETRCT FLINEXP LINEXP KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP STAGG ELAGG URAGG RCAGG HOAGG AGG
+ TYPE IXAGG ELTAGG CLAGG OM PATAB BOOLEAN FS FPATMAB GROUP
+ RADCAT INS NNI ORDRING OINTDOM OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL
+multfact ALGMFACT ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON POLYCAT PDRING RING RNG ABELGRP
+ SGROUP MONOID LMODULE FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT
+ UFD ES ACF FIELD EUCDOM PID DIVRING RADCAT UPOLYC ELTAB
+ DIFRING DIFEXT STEP REAL
+naalg ALGPKG INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER FRNAALG FINAALG NAALG NARNG MONAD PI NNI INT
+ SINT VECTOR IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG
+ HOAGG AGG TYPE EVALAB IEVALAB ELTAGG ELTAB CLAGG KONVERT
+ ORDSET INS UFD GCDDOM EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING RETRACT LINEXP PATMAB CFCAT REAL
+ CHARZ OM BOOLEAN LIST ILIST
+naalg ALGSC FRNAALG FINAALG NAALG NARNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE MONAD MODULE BMODULE LMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG SGROUP
+ MONOID ALGEBRA ENTIRER UFD DIVRING SMATCAT DIFEXT DIFRING
+ PDRING RMATCAT HOAGG AGG TYPE EVALAB IEVALAB FRETRCT RETRACT
+ FLINEXP LINEXP INT VECTOR INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET KONVERT PATMAB CFCAT REAL CHARZ
+ STEP OM IVECTOR IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG
+ CLAGG ELTAGG SINT PI NNI VECTCAT ELTAB LIST ILIST LSAGG
+ STAGG SYMBOL REF ALIST STRING CHAR OUTFORM PRIMARR ISTRING
+ SRAGG URAGG RCAGG ELAGG BOOLEAN POLYCAT FAMR AMR CHARNZ
+ PFECAT
+constant AN ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB ACF
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING RADCAT LINEXP REAL
+ KONVERT CHARZ DIFRING INS OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP PATMAB CFCAT STEP QFCAT FEVALAB ELTAB DIFEXT
+ PDRING FLINEXP PATAB FPATMAB TYPE CHARNZ PFECAT FPS RNS
+ CACHSET
+rule APPRULE SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE PATMAB ORDSET KONVERT FS ES RETRACT
+ IEVALAB EVALAB PATAB FPATMAB TYPE FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ INT LIST ILIST PI NNI SINT LSAGG STAGG URAGG RCAGG HOAGG
+ AGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INS
+asp ASP19 FVFUN FORTCAT TYPE KOERCE BOOLEAN SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG ILIST FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ FS ES IEVALAB EVALAB PATAB FPATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARNZ VECTCAT IXAGG HOAGG AGG ELTAGG ELTAB
+ CLAGG INS OINTDOM DIFRING CFCAT STEP FMTC NNI VECTOR
+ IVECTOR IARRAY1 OM LSAGG STAGG URAGG RCAGG ELAGG PI
+ POLYCAT FAMR AMR PFECAT
+asp ASP20 FMFUN FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRCT RADCAT
+ PATMAB CHARZ ES IEVALAB EVALAB SINT PI NNI INT SYMBOL REF
+ ALIST LIST STRING CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG FMTC INS OUTFORM DIFRING LINEXP CFCAT STEP
+ POLYCAT PDRING FAMR AMR CHARNZ FRETRCT FLINEXP PFECAT
+ QFCAT FEVALAB ELTAB DIFEXT PATAB FPATMAB VECTCAT IXAGG
+ HOAGG AGG ELTAGG CLAGG FS GROUP
+asp ASP30 FMC FORTCAT TYPE KOERCE BOOLEAN FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ INS OINTDOM DIFRING LINEXP CFCAT STEP SYMBOL
+ INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG OM
+asp ASP31 FVFUN FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG BOOLEAN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ FS
+ ES IEVALAB EVALAB PATAB FPATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARNZ VECTCAT IXAGG HOAGG AGG ELTAGG ELTAB
+ CLAGG NNI ILIST VECTOR IVECTOR IARRAY1 INS OINTDOM DIFRING
+ CFCAT STEP OM LSAGG STAGG URAGG RCAGG ELAGG FMTC POLYCAT
+ FAMR AMR PFECAT
+asp ASP35 FVFUN FORTCAT TYPE KOERCE BOOLEAN SINT NNI INT SYMBOL REF
+ ALIST LIST STRING CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ FS ES
+ IEVALAB EVALAB PATAB FPATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARNZ VECTCAT IXAGG HOAGG AGG ELTAGG ELTAB CLAGG
+ INS OINTDOM DIFRING CFCAT STEP OM VECTOR IVECTOR IARRAY1
+ LSAGG STAGG URAGG RCAGG ELAGG FMTC POLYCAT FAMR AMR PFECAT
+asp ASP41 FVFUN FORTCAT TYPE KOERCE BOOLEAN SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ FS ES
+ IEVALAB EVALAB PATAB FPATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARNZ VECTCAT IXAGG HOAGG AGG ELTAGG ELTAB CLAGG
+ VECTOR IVECTOR IARRAY1 NNI INS OINTDOM DIFRING CFCAT STEP
+ OM LSAGG STAGG URAGG RCAGG ELAGG FMTC POLYCAT FAMR AMR
+ PFECAT
+asp ASP42 FVFUN FORTCAT TYPE KOERCE BOOLEAN SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG NNI ILIST FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ FS ES IEVALAB EVALAB PATAB FPATMAB FRETRCT GROUP
+ PDRING FLINEXP LINEXP CHARNZ VECTCAT IXAGG HOAGG AGG
+ ELTAGG ELTAB CLAGG INS OINTDOM DIFRING CFCAT STEP OM
+ VECTOR IVECTOR IARRAY1 LSAGG STAGG URAGG RCAGG ELAGG
+ FMTC POLYCAT FAMR AMR PFECAT
+asp ASP74 FMFUN FORTCAT TYPE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ ES IEVALAB EVALAB NNI INT INS OINTDOM DIFRING LINEXP CFCAT
+ STEP OM PI FMTC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ FLINEXP PFECAT QFCAT FEVALAB ELTAB DIFEXT PATAB FPATMAB
+ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG ELTAGG CLAGG
+ FS GROUP
+asp ASP77 FMFUN FORTCAT TYPE KOERCE FPS RNS FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ FS ES IEVALAB EVALAB PATAB FPATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARNZ VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG ELTAGG ELTAB CLAGG INS OINTDOM DIFRING CFCAT STEP
+ BOOLEAN FMTC POLYCAT FAMR AMR PFECAT QFCAT FEVALAB DIFEXT
+asp ASP80 FMFUN FORTCAT TYPE KOERCE SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ BOOLEAN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ FMTC ES
+ IEVALAB EVALAB PI NNI INS OINTDOM DIFRING LINEXP CFCAT STEP
+ POLYCAT PDRING FAMR AMR CHARNZ FRETRCT FLINEXP PFECAT QFCAT
+ FEVALAB ELTAB DIFEXT PATAB FPATMAB VECTCAT IXAGG HOAGG AGG
+ ELTAGG CLAGG FS GROUP
+gaussian CINTSLPE INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP COMPCAT MONGEN
+ FRAMALG FINRALG CHARNZ FRETRCT FLINEXP FINITE FIELD DIVRING
+ DIFEXT PDRING FFIELDC PFC FEVALAB ELTAB EVALAB IEVALAB
+ FPATMAB TYPE PATAB TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ RADCAT PFECAT INT VECTOR IVECTOR IARRAY1 UPOLYC POLYCAT FAMR
+ AMR LIST ILIST NNI BOOLEAN
+cmplxrt CMPLXRT UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG INS
+ OINTDOM CFCAT REAL ILIST COMPCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC FEVALAB FPATMAB TYPE PATAB TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RADCAT LSAGG STAGG
+ ELAGG URAGG
+gaussian COMPFACT EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT UFD ELTAB
+ DIFRING DIFEXT STEP FIELD DIVRING INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP CFCAT REAL QFCAT FEVALAB PATAB
+ FPATMAB TYPE COMPCAT MONOGEN FRAMALG FINRALG FINITE
+ FFIELDC FPC TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ RADCAT INT SINT NNI OM LIST
+gaussian COMPLEX COMPCAT MONOGEN FRAMALG FINRALG ALGEBRA RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE MODULE BMODULE RMODULE CHARZ CHARNZ COMRING KONVERT
+ FRETRCT RETRACT FLINEXP LINEXP FINITE FIELD EUCDOM PID
+ GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT DIFRING PDRING
+ FFIELDC FPC STEP FEVALAB ELTAB EVALAB IEVALAB FPATMAB
+ TYPE PATMAB PATAB ORDSET TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN RADCAT PFECAT OM BOOLEAN UPOLYC POLYCAT FAMR AMR
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL
+ RNS FPS OAMONS
+gaussian COMPLPAT SETCAT BASTYPE KOERCE KONVERT COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE COMPCAT MONOGEN FRAMALG FINRALG ALGEBRA MODULE
+ CHARZ CHARNZ FRETRCT RETRACT FLINEXP LINEXP FINITE FIELD
+ EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT
+ DIFRING PDRING FFIELDC FPC STEP FEVALAB ELTAB EVALAB
+ IEVALAB FPATMAB TYPE PATMAB PATAB ORDSET TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN RADCAT PFECAT SYMBOL INT REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG BOOLEAN
+gaussian CPMATCH SETCAT BASTYPE KOERCE PATMAB COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE COMPCAT MONOGEN FRAMALG FINRALG ALGEBRA MODULE
+ CHARZ CHARNZ KONVERT FRETRCT RETRACT FLINEXP LINEXP FINITE
+ FIELD EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT
+ DIFRING PDRING FFIELDC FPC STEP FEVALAB ELTAB EVALAB
+ IEVALAB FPATMAB TYPE PATAB ORDSET TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN RADCAT PFECAT SYMBOL INT REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG NNI POLYCAT FAMR AMR
+crfp CRFP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET UPOLYC POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT
+ STEP COMPCAT MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC
+ FEVALAB FPATMAB TYPE PATAB TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN RADCAT QFCAT OINTDOM REAL OM LSAGG STAGG URAGG
+ RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG INS
+ CFCAT RNS
+efstruc CTRIGMNP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER ORDSET RETRACT ACF FIELD EUCDOM PID GCDDOM
+ UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB
+ FRETRCT GROUP PDRING FLINEXP LINEXP CHARZ CHARNZ LSAGG STAGG
+ URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG OM INT LIST ILIST COMPCAT MONOGEN FRAMALG FINRALG
+ FINITE DIFEXT DIFRING FFIELDC FPC STEP FEVALAB PFECAT
+ CACHSET BOOLEAN SYMBOL REF ALIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG
+intalg DBLRESP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL NNI INT PI
+derham DERHAM LALG RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE RETRACT FS ES ORDSET IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP
+ PDRING FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE
+ BMODULE RMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING
+ ENTIRER UFD DIVRING LSAGG STAGG URAGG RCAGG HOAGG AGG
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM
+special DFSFUN FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ DFLOAT NNI INT DIFRING
+ OM TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN COMPCAT
+ MONOGEN FRAMALG FINRALG CHARNZ FRETRCT FLINEXP LINEXP
+ FINITE DIFEXT PDRING FFIELDC FPC STEP FEVALAB ELTAB EVALAB
+ IEVALAB FPATMAB TYPE PATAB PFECAT FRAC
+draw DRAWCURV INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT FS ES IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD
+ DIVRING POLYCAT FAMR AMR PFECAT INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING CFCAT REAL STEP SYMBOL INT REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG ILIST STAGG ELAGG URAGG OM FPS RNS RADCAT
+d01weights D01WGTS FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ FS ES IEVALAB EVALAB
+ PATAB FPATMAB TYPE FRETRCT GROUP PDRING FLINEXP LINEXP
+ CHARNZ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG STAGG URAGG
+ RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM
+ ILIST NNI BOOLEAN DIFRING TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN INT OINTDOM CFCAT STEP DFLOAT
+d02agents D02AGNT LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE SETCAT BASTYPE
+ KOERCE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST DFLOAT NNI
+ FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL RETRACT RADCAT PATMAB CHARZ
+ VECTCAT A1AGG VECTOR IVECTOR IARRAY1 DIFRING TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN BOOLEAN FS ES PATAB FPATMAB
+ FRETRCT GROUP PDRING FLINEXP LINEXP CHARNZ MATCAT ARR2CAT
+ INS OINTDOM CFCAT STEP QFCAT FEVALAB DIFEXT PFECAT SINT
+ SYMBOL REF ALIST STRING CHAR OUTFORM PRIMARR ISTRING SRAGG
+d03routine D03EEFA PDECAT SETCAT BASTYPE KOERCE LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ORDSET ELAGG OM INT LIST ILIST NNI PI MONOID
+ ABELMON DFLOAT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL RETRACT RADCAT
+ PATMAB CHARZ VECTOR FS ES PATAB FPATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARNZ
+elemntry EF ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD
+ DIVRING RADCAT SYMBOL INT REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN ILIST INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP DIFRING CFCAT REAL STEP OM INS
+ LSAGG STAGG PI NNI BOOLEAN CACHSET
+efstruc EFSTRUC INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP ACF FIELD
+ EUCDOM PID GCDDOM UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ
+ CHARNZ COMBOPC CFCAT BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG
+ AGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST
+ ILIST INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ REAL STEP PI NNI SINT SYMBOL REF ALIST STRING CHAR OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG VECTOR IVECTOR IARRAY1 VECTCAT
+elfuts ELFUTS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UTSCAT UPSCAT PSCAT AMR CHARZ CHARNZ ELTAB DIFRING PDRING
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN INT LIST
+ ILIST LSAGG STAGG
+tools ESTOOLS INT LIST ILIST NNI FPS RNS FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ SINT
+ LSAGG DFLOAT INS OINTDOM DIFRING LINEXP CFCAT STEP OM
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN QFCAT FEVALAB
+ ELTAB EVALAB IEVALAB DIFEXT PDRING FLINEXP PATAB FPATMAB
+ TYPE CHARNZ PFECAT LZSTAGG STAGG URAGG RCAGG HOAGG AGG LNAGG
+ IXAGG ELTAGG CLAGG VECTOR VECTCAT A1AGG FLAGG IVECTOR
+ IARRAY1 BOOLEAN ELAGG FS ES FRETRCT GROUP PI TBAGG KDAGG
+ DIAGG DIOPS BGAGG STRING CHAR OUTFORM PRIMARR ISTRING
+expexpan EXPEXPAN ACF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FS ES ORDSET RETRACT IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ QFCAT FEVALAB ELTAB DIFEXT DIFRING
+ STEP OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ PFECAT FAMR AMR PI NNI INT INS CFCAT OM LSAGG STAGG
+ URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG
+ ELTAGG CLAGG FLAGG ELAGG LIST ILIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING UPXSCCA UPXSCAT UPSCAT
+ PSCAT
+exprode EXPRODE ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER KONVERT FS ES RETRACT IEVALAB EVALAB
+ PATAB FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING
+ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING CFCAT REAL STEP CACHSET UPOLYC
+ POLYCAT FAMR AMR PFECAT ELTAB DIFEXT NNI LSAGG STAGG URAGG
+ RCAGG HOAGG AGG IXAGG ELTAGG CLAGG ELAGG OM ILIST
+tube EXPRTUBE INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG FLAGG ELAGG INT LIST ILIST NNI SYMBOL
+ REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG BOOLEAN FS ES PATAB FPATMAB FRETRCT GROUP
+ PDRING FLINEXP CHARNZ FIELD DIVRING FPS RNS RADCAT
+expr EXPR2 ORDSET SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+e04routine E04NAFA OPTCAT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING
+ STRICAT SRAGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB
+ IEVALAB ELTAGG ELTAB CLAGG OM NNI DIFRING TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN ILIST LSAGG STAGG URAGG RCAGG
+ ELAGG DFLOAT PI POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ FLINEXP LINEXP PFECAT VECTCAT FS ES PATAB FPATMAB GROUP
+ INS OINTDOM CFCAT STEP BOOLEAN
+e04routine E04UCFA OPTCAT SETCAT BASTYPE KOERCE FPS RNS FIELD EUCDOM PID
+ GCDDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG
+ IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST NNI
+ DIFRING TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN DFLOAT PI
+ INS OINTDOM LINEXP CFCAT STEP POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT FLINEXP PFECAT QFCAT FEVALAB DIFEXT PATAB FPATMAB
+ VECTOR BOOLEAN
+fortran FC SETCAT BASTYPE KOERCE SINT INS UFD GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP INT LIST ILIST
+ LSAGG STAGG SYMBOL REF ALIST STRING CHAR OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG POLYCAT PDRING FAMR AMR
+ CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT STRICAT IXAGG
+ HOAGG AGG TYPE ELTAGG ELTAB CLAGG OM NNI DFLOAT BOOLEAN
+ FMTC FPS RNS FIELD DIVRING RADCAT COMPCA MONOGEN FRAMALG
+ FINRALG FINITE DIFEXT FFIELDC FPC FEVALAB FPATMAB PATAB
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN VECTOR IVECTOR
+ IARRAY1 VECTCAT FS ES GROUP
+divisor FDIVCAT ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC 19
+divisor FDIV2 FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC
+curve FFCAT2 UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING FAMR
+ AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP
+ LINEXP ORDSET KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT
+ STEP EUCDOM PID FIELD DIVRING FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC
+numsolve FLOATCP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET INS OINTDOM
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ COMPCAT MONOGEN FRAMALG FINRALG CHARNZ FRETRCT FLINEXP
+ FINITE DIFEXT PDRING FFIELDC FPC FEVALAB ELTAB EVALAB
+ IEVALAB FPATMAB TYPE PATAB TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN RADCAT PFECAT POLYCAT FAMR AMR BOOLEAN OM INT
+ LIST ILIST QFCAT
+pfo FORDER FINITE SETCAT BASTYPE KOERCE FIELD EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FFIELDC FPC SINT NNI INT
+fortran FORTRAN FORTCAT TYPE KOERCE SINT SYMBOL INT REF ALIST LIST STRING
+ CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ILIST
+ LSAGG STAGG ELAGG URAGG RCAGG IXAGG ORDSET SETCAT BASTYPE
+ KONVERT OM PATMAB FMTC INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT HOAGG AGG EVALAB ELTAGG ELTAB
+ CLAGG NNI FPS RNS FIELD EUCDOM PID GCDDOM UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL RADCAT CHARZ INS
+ OINTDOM DIFRING LINEXP CFCAT STEP COMPCAT MONOGEN FRAMALG
+ FINRALG CHARNZ FRETRCT FLINEXP FINITE DIFEXT PDRING FFIELDC
+ FPC FEVALAB FPATMAB PATAB TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN PFECAT
+naalg FRNAAF2 FRNAALG FINAALG NAALG NARNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE MONAD MODULE BMODULE LMODULE RMODULE
+ COMRING RING RNG SGROUP MONOID PI NNI INT SINT VECTOR
+ IVECTOR IARRAY1
+combfunc FSPECF ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER FS ES RETRACT
+ IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT
+ FGROUP PDRING FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM PID
+ GCDDOM UFD DIVRING SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ POLYCAT FAMR AMR PFECAT SPFCAT INS ILIST LSAGG STAGG
+ ELAGG URAGG ELEMFUN
+pfo FSRED ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT FS ES IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING
+ CACHSET INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING CFCAT REAL STEP UPOLYC POLYCAT FAMR AMR PFECAT ELTAB
+ DIFEXT QFCAT FEVALAB OM INT
+funcpkgs FSUPFACT INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT FS ES IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD
+ DIVRING UPOLYC POLYCAT FAMR AMR PFECAT ELTAB DIFRING DIFEXT
+ STEP SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ACF RADCAT INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL QFCAT
+ FEVALAB BOOLEAN CACHSET
+fspace FS2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE ORDSET FS ES RETRACT IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP
+ PDRING FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE
+ RMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD
+ DIVRING CACHSET
+fs2ups FS2UPS GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP ACF
+ FIELD EUCDOM PID UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ
+ CHARNZ ORDRING OAGROUP OCAMON OAMON OASGP UPSCAT PSCAT AMR
+ ELTAB DIFRING PTRANFN NNI INT INS POLYCAT FAMR PFECAT
+ BOOLEAN SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG STAGG URAGG RCAGG
+ HOAGG AGG IXAGG ELTAGG CLAGG ELAGG OM OINTDOM CFCAT REAL
+ STEP PI CACHSET STRICAT
+gaussfac GAUSSFAC INS EUCDOM UFD GCDDOM INTDOM COMRING RING ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP BOOLEAN PI NNI
+ LIST ILIST OM LSAGG STAGG COMPCAT MONOGEN FRAMALG FINRALG
+ CHARNZ FRETRCT FLINEXP FINITE FIELD DIVRING DIFEXT PDRING
+ FFIELDC FPC FEVALAB ELTAB EVALAB IEVALAB FPATMAB TYPE PATAB
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RADCAT PFECAT
+generic GCNAALG FRNAALG FINAALG NAALG NARNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE MONAD MODULE BMODULE LMODULE RMODULE
+ COMRING RING RNG SGROUP MONOID POLYCAT PDRING FAMR AMR
+ ALGEBRA CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT EVALAB
+ IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT
+ UFD QFCAT FIELD EUCDOM PID DIVRING FEVALAB ELTAB DIFEXT
+ DIFRING PATAB FPATMAB TYPE STEP OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL SMATCAT RMATCAT HOAGG AGG SINT PI
+ NNI INT STRING CHAR OUTFORM LIST PRIMARR A1AGG ISTRING
+ SYMBOL REF ALIST SRAGG FLAGG LNAGG VECTOR IVECTOR IARRAY1
+ VECTCAT IXAGG INS CFCAT OM ILIST LSAGG STAGG ELAGG URAGG
+ CLAGG HOAGG ORDSET AGG ELTAGG BOOLEAN
+genufact GENUFACT EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER INS UFD OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP UPOLYC POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT
+ ELTAB DIFEXT FIELD DIVRING QFCAT FEVALAB PATAB FPATMAB TYPE
+ FFIELDC FPC FINITE COMPCAT MONOGEN FRAMALG FINRALG TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RADCAT ES ACF
+genups GENUPS INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER ORDSET RETRACT LINEXP ACF FIELD EUCDOM PID
+ GCDDOM UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE
+ PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ CHARNZ INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING CFCAT REAL STEP
+ OM
+triset GTSET TSETCAT PSETCAT SETCAT BASTYPE KOERCE CLAGG HOAGG AGG TYPE
+ EVALAB IEVALAB KONVERT INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER OAMONS OCAMON OAMON OASGP ORDSET
+ RPOLCAT POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ FLINEXP LINEXP PATMAB GCDDOM PFECAT UFD INT LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG LNAGG RCAGG IXAGG ELTAGG
+ ELTAB OM BOOLEAN FINITE
+polset GPOLSET PSETCAT SETCAT BASTYPE KOERCE CLAGG HOAGG AGG TYPE EVALAB
+ IEVALAB KONVERT RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE OAMONS OCAMON OAMON OASGP ORDSET
+ RPOLCAT POLYCAT PDRING FAMR AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER FRETRCT RETRACT
+ FLINEXP PATMAB GCDDOM PFECAT UFD LSAGG STAGG URAGG RCAGG
+ LNAGG IXAGG ELTAGG ELTAB FLAGG ELAGG OM INT LIST ILIST
+constant IAN ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB
+ ACF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING RADCAT LINEXP REAL
+ KONVERT CHARZ DIFRING INS OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP PATMAB CFCAT STEP QFCAT FEVALAB ELTAB DIFEXT
+ PDRING FLINEXP PATAB FPATMAB TYPE CHARNZ PFECAT FPS RNS FS
+ FRETRCT GROUP OM CACHSET POLYCAT FAMR AMR UPOLYC COMPCAT
+ MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN
+numeigen INEP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET INS OINTDOM
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP
+ OM FPS RNS RADCAT QFCAT FEVALAB ELTAB EVALAB IEVALAB DIFEXT
+ PDRING FLINEXP PATAB FPATMAB TYPE CHARNZ PFECAT TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN UPOLYC POLYCAT FAMR AMR
+ FRETRCT NNI INT SINT VECTOR IVECTOR IARRAY1 LIST COMPCAT
+ MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC
+infprod INFPROD0 INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER CHARZ UTSCAT UPSCAT PSCAT AMR CHARNZ ELTAB
+ DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN
+numsolve INFSP GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER FIELD EUCDOM PID UFD DIVRING ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET INS OINTDOM DIFRING
+ KONVERT RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP FPS
+ RNS RADCAT QFCAT FEVALAB ELTAB EVALAB IEVALAB DIFEXT PDRING
+ FLINEXP PATAB FPATMAB TYPE CHARNZ PFECAT OM NNI INT POLYCAT
+ FAMR AMR FRETRCT COMPCAT MONOGEN FRAMALG FINRALG FINITE
+ FFIELDC FPC TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ UPOLYC LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG
+ IXAGG ELTAGG CLAGG FLAGG ELAGG PRIMARR PI DIRPCAT OAMONS
+ VSPACE ORDFIN BOOLEAN
+infprod INPRODFF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ FINITE KONVERT UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET PATMAB
+ PFECAT ELTAB DIFRING DIFEXT STEP MONOGEN FRAMALG FINRALG
+ FFIELDC FPC UTSCAT UPSCAT PSCAT RADCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP CFCAT REAL QFCAT FEVALAB PATAB FPATMAB
+ TYPE BOOLEAN
+infprod INPRODPF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ FINITE KONVERT UTSCAT UPSCAT PSCAT AMR CHARZ CHARNZ ELTAB
+ DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ ORDSET RETRACT LINEXP PATMAB CFCAT REAL STEP
+intaf INTAF ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ACF FIELD EUCDOM PID GCDDOM UFD
+ DIVRING RADCAT FS ES RETRACT IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP LINEXP
+ CHARZ CHARNZ CACHSET UPOLYC POLYCAT FAMR AMR PFECAT ELTAB
+ DIFRING DIFEXT STEP QFCAT FEVALAB OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL NNI INT SYMBOL REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+intalg INTALG ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT ACF FIELD EUCDOM PID GCDDOM
+ UFD DIVRING RADCAT FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP LINEXP
+ CHARZ CHARNZ UPOLYC POLYCAT FAMR AMR PFECAT ELTAB DIFRING
+ DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG FINITE FFIELDC
+ FPC SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG VECTCAT A1AGG IXAGG
+ HOAGG AGG ELTAGG CLAGG VECTOR IVECTOR IARRAY1 INS OINTDOM
+ OAGROUP OCAMON OASGP CFCAT REAL OM ILIST QFCAT FEVALAB
+ LSAGG STAGG ELAGG NNI URAGG RCAGG BOOLEAN PI CACHSET
+intef INTEF GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT LINEXP ACF
+ FIELD EUCDOM PID UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARNZ
+ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG BOOLEAN ILIST UPOLYC POLYCAT
+ FAMR AMR PFECAT ELTAB DIFRING DIFEXT STEP CACHSET QFCAT
+ FEVALAB OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL
+ LSAGG STAGG ELAGG URAGG RCAGG IXAGG LFCAT PRIMCAT HOAGG AGG
+ ELTAGG CLAGG OM
+intaf INTG0 GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT ORDSET CHARZ LINEXP FS ES
+ IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT
+ GROUP PDRING FLINEXP CHARNZ FIELD EUCDOM PID UFD DIVRING
+ ACF RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG CACHSET ILIST UPOLYC POLYCAT
+ FAMR AMR PFECAT ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL NNI LODOCAT
+ OREPCAT
+intalg INTHERAL FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC INT VECTOR IVECTOR IARRAY1 VECTCAT PI NNI
+ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL OM
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG QFCAT
+ FEVALAB PATAB FPATMAB
+intaf INTPAF GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT ORDSET CHARZ LINEXP FS ES
+ IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT
+ GROUP PDRING FLINEXP CHARNZ FIELD EUCDOM PID UFD DIVRING
+ ACF RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN SYMBOL
+ INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG UPOLYC POLYCAT FAMR AMR PFECAT
+ ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL BOOLEAN NNI CACHSET PI ILIST
+ LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG
+ ELAGG LODOCAT OREPCAT
+intpm INTPM ORDSET SETCAT BASTYPE KOERCE RETRACT GCDDOM INTDOM COMRING
+ RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER LINEXP ACF FIELD
+ EUCDOM PID UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB
+ TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ CHARNZ
+ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING CFCAT REAL STEP LSAGG STAGG URAGG
+ RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG ELAGG OM ILIST PI
+ NNI LFCAT PRIMCAT CACHSET BOOLEAN POLYCAT FAMR AMR PFECAT
+ UPOLYC DIFEXT SPFCAT
+rdeef INTTOOLS ORDSET SETCAT BASTYPE KOERCE FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID SGROUP
+ GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ CACHSET INT LIST LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG
+ IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM ILIST NNI BOOLEAN
+ SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG ELEMFUN POLYCAT FAMR AMR PFECAT
+ UPOLYC DIFRING DIFEXT STEP LFCAT PRIMCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP
+efstruc ITRIGMNP INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD
+ DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ COMPCAT MONOGEN FRAMALG FINRALG FINITE DIFEXT DIFRING
+ FFIELDC FPC STEP FEVALAB ELTAB PFECAT OM CACHSET LSAGG
+ STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG
+ ELAGG INT LIST ILIST SYMBOL REF ALIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG POLYCAT FAMR AMR
+lie JORDAN NAALG NARNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE MONAD MODULE BMODULE LMODULE RMODULE FRNAALG FINAALG
+ COMRING RING RNG SGROUP MONOID FIELD EUCDOM PID GCDDOM
+ INTDOM ALGEBRA ENTIRER UFD DIVRING POLYCAT PDRING FAMR AMR
+ CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB PFECAT
+kovacic KOVACIC CHARZ RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE ACF FIELD EUCDOM PID GCDDOM
+ INTDOM COMRING BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING RADCAT RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB
+ PFECAT ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB PATAB FPATMAB
+ TYPE OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL PI NNI
+ INT LIST ILIST BOOLEAN
+liouv LF ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER FS ES RETRACT IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN SYMBOL INT
+ REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG ILIST LSAGG STAGG ELAGG URAGG NNI
+ BOOLEAN
+lie LIE NAALG NARNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE MONAD MODULE BMODULE LMODULE RMODULE FRNAALG FINAALG
+ COMRING RING RNG SGROUP MONOID PI NNI FIELD EUCDOM PID
+ GCDDOM INTDOM ALGEBRA ENTIRER UFD DIVRING POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+lodof LODOF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB PATAB FPATMAB TYPE
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL BOOLEAN INT
+ LIST ILIST LSAGG STAGG SINT NNI OM URAGG RCAGG HOAGG AGG
+ LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG PI ACF RADCAT ES
+lie LSQM SMATCAT DIFEXT RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE DIFRING PDRING BMODULE
+ RMODULE RMATCAT HOAGG AGG TYPE EVALAB IEVALAB MODULE COMRING
+ FRETRCT RETRACT FLINEXP LINEXP ALGEBRA FRNAALG FINAALG NAALG
+ NARNG MONAD INTDOM ENTIRER PI NNI INT SINT VECTOR IVECTOR
+ IARRAY1 VECTCAT A1AGG FLAGG LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT ORDSET HOAGG AGG EUCDOM PID GCDDOM FIELD UFD DIVRING
+ POLYCAT FAMR AMR CHARZ CHARNZ PATMAB PFECAT INT OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL STEP
+openmath OMEXPR OM ORDSET SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BOOLEAN LSAGG STAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG KONVERT FLAGG INT LIST ILIST NNI PI SYMBOL REF
+ ALIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FS ES RETRACT PATAB FPATMAB PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+fortmac MCMPLX FMTC INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT COMPCAT MONOGEN
+ FRAMALG FINRALG CHARZ CHARNZ KONVERT FRETRCT FLINEXP LINEXP
+ FINITE FIELD EUCDOM PID GCDDOM UFD DIVRING DIFEXT DIFRING
+ PDRING FFIELDC FPC STEP FEVALAB ELTAB EVALAB IEVALAB FPATMAB
+ TYPE PATMAB PATAB TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ RADCAT PFECAT FPS RNS ORDRING OAGROUP OCAMON OAMON OASGP
+ REAL INS OINTDOM CFCAT UPOLYC POLYCAT FAMR AMR OAMONS
+multfact MULTFACT ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER CHARZ POLYCAT PDRING FAMR AMR CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB
+ PFECAT UFD INS OINTDOM ORDRING OAGROUP DIFRING CFCAT REAL
+ STEP COMPCAT MONOGEN FRAMALG FINRALG FINITE FIELD DIVRING
+ DIFEXT FFIELDC FPC FEVALAB ELTAB FPATMAB TYPE PATAB TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RADCAT UPOLYC
+d01 NAGD01 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ
+d02 NAGD02 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGRP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+f01 NAGF01 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB
+ CHARZ INS OINTDOM DIFRING LINEXP CFCAT STEP COMPCAT MONOGEN
+ FRAMALG FINRALG CHARNZ FRETRCT FLINEXP FINITE DIFEXT PDRING
+ FFIELDC FPC FEVALAB ELTAB EVALAB IEVALAB FPATMAB TYPE PATAB
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PFECAT
+f02 NAGF02 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ INS DIFRING DFLOAT PI NNI COMPCAT MONOGEN FRAMALG FINRALG
+ CHARNZ FRETRCT FLINEXP LINEXP FINITE DIFEXT DIFRING PDRING
+ FFIELDC FPC STEP FEVALAB ELTAB EVALAB IEVALAB FPATMAB TYPE
+ PATAB TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PFECAT
+f04 NAGF04 SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG FPS RNS FIELD EUCDOM PID
+ GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT PATMAB CHARZ
+ COMPCAT MONOGEN FRAMALG FINRALG CHARNZ FRETRCT FLINEXP
+ LINEXP FINITE DIFEXT DIFRING PDRING FFIELDC FPC STEP FEVALAB
+ ELTAB EVALAB IEVALAB FPATMAB TYPE PATAB TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN PFECAT INS OINTDOM CFCAT DFLOAT
+numeigen NCEP FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET SYMBOL INT REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG INS OINTDOM DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP QFCAT FEVALAB ELTAB
+ EVALAB DIFEXT PDRING FLINEXP PATAB FPATMAB TYPE CHARNZ
+ PFECAT COMPCAT MONOGEN FRAMALG FINRALG FRETRCT FINITE
+ FFIELDC FPC TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN RADCAT
+ UPOLYC POLYCAT FAMR AMR
+nlinsol NLINSOL INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER ORDSET KONVERT OM PATMAB INT LIST POLYCAT
+ PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP GCDDOM PFECAT UFD ACF FIELD EUCDOM PID
+ DIVRING RADCAT ILIST LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE
+ LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG NNI INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP DIFRING CFCAT REAL STEP
+ QFCAT FEVALAB DIFEXT PATAB FPATMAB
+newpoly NSMP RPOLCAT POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB GCDDOM PFECAT UFD NNI INT LIST ILIST
+ LSAGG STAGG ELAGG FLAGG URAGG LNAGG RCAGG IXAGG CLAGG HOAGG
+ AGG ELTAGG BOOLEAN PI EUCDOM PID INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING CFCAT REAL STEP QFCAT FIELD
+ DIVRING FEVALAB ELTAB DIFEXT PATAB FPATMAB TYPE FPS RNS
+ RADCAT UPOLYC
+numeric NUMERIC KONVERT COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE COMPCAT MONOGEN FRAMALG FINRALG ALGEBRA MODULE
+ CHARZ CHARNZ FRETRCT RETRACT FLINEXP LINEXP FINITE FIELD
+ EUCDOM PID GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT DIFRING
+ PDRING FFIELDC FPC STEP FEVALAB ELTAB EVALAB IEVALAB
+ FPATMAB TYPE PATMAB PATAB ORDSET TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN RADCAT PFECAT FPS RNS ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL OM POLYCAT FAMR AMR
+oct OCT OC ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ FRETRCT RETRACT FEVALAB ELTAB EVALAB IEVALAB FINITE ORDSET
+ KONVERT CHARZ CHARNZ COMRING QUATCAT DIFEXT DIFRING PDRING
+ FLINEXP LINEXP ENTIRER DIVRING FIELD EUCDOM PID GCDDOM
+ INTDOM UFD INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ PATMAB CFCAT REAL STEP RNS RADCAT
+oct OCTCT2 OC ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ FRETRCT RETRACT FEVALAB ELTAB EVALAB IEVALAB FINITE ORDSET
+ KONVERT CHARZ CHARNZ COMRING
+odealg ODEPAL FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL LODOCAT OREPCAT
+riccati ODERTRIC FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ CHARZ RETRACT UPOLYC POLYCAT PDRING FAMR AMR CHARNZ FRETRCT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP SYMBOL INT REF ALIST LIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+ QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL ILIST NNI LSAGG STAGG URAGG RCAGG
+ HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM BOOLEAN
+ UTSCAT UPSCAT PSCAT RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN ACF
+pade PADE FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UTSCAT UPSCAT PSCAT AMR CHARZ CHARNZ ELTAB DIFRING PDRING
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN UPOLYC
+ POLYCAT FAMR FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ ORDSET KONVERT PATMAB PFECAT DIFEXT STEP NNI INT SINT LIST
+ ILIST PI
+expr PAN2EXPR INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP ES IEVALAB
+ EVALAB ACF FIELD DIVRING RADCAT FS PATAB FPATMAB TYPE
+ FRETRCT GROUP PDRING FLINEXP CHARNZ POLYCAT FAMR AMR
+ PFECAT OM
+d03Package PDEPACK STRING CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING
+ SRAGG ILIST TBAGG KDAGG DIAGG DIOPS BGAGG HOAGG AGG TYPE
+ SETCAT BASTYPE KOERCE EVALAB IEVALAB CLAGG KONVERT IXAGG
+ ELTAGG ELTAB NNI SYMBOL REF ALIST FLAGG LNAGG FPS RNS FIELD
+ EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET REAL RETRACT
+pfo PFO ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT FS ES IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING
+ UPOLYC POLYCAT FAMR AMR PFECAT ELTAB DIFRING DIFEXT STEP
+ FFCAT MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL QFCAT
+ FEVALAB CACHSET INT LIST LSAGG STAGG URAGG RCAGG HOAGG AGG
+ LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM ILIST NNI PI VECTCAT
+ A1AGG BOOLEAN
+pfo PFOQ UPOLYC POLYCAT PDRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING FFCAT MONOGEN FRAMALG FINRALG FINITE
+ FFIELDC FPC INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL QFCAT FEVALAB PATAB FPATMAB TYPE OM INT VECTOR
+ IVECTOR IARRAY1 NNI PI VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG
+ AGG ELTAGG CLAGG
+expr PICOERCE ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER INS UFD GCDDOM EUCDOM PID
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP UPOLYC POLYCAT
+ PDRING FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP
+ PFECAT ELTAB DIFEXT FIELD DIVRING FS ES PATAB FPATMAB TYPE
+ GROUP
+expr PMASSFS ORDSET SETCAT BASTYPE KOERCE FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID SGROUP
+ GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ INT LIST ILIST
+patmatch2 PMFS SETCAT BASTYPE KOERCE INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER ORDSET PATMAB FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHAR CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING
+ CACHSET INT LIST ILIST LSAGG STAGG ELAGG FLAGG URAGG
+expr PMPREDFS ORDSET SETCAT BASTYPE KOERCE FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID SGROUP
+ GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ INT LIST ILIST LSAGG STAGG SYMBOL REF ALIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG
+primelt PRIMELT INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER ORDSET CHARZ FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING
+ CACHSET POLYCAT FAMR AMR PFECAT LSAGG STAGG URAGG RCAGG
+ HOAGG AGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT
+ LIST ILIST SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG NNI ACF RADCAT BOOLEAN UPOLYC DIFRING
+ DIFEXT STEP PI
+triset PSETPK INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER OAMONS OCAMON OAMON OASGP ORDSET
+ RPOLCAT POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP KONVERT PATMAB GCDDOM PFECAT
+ UFD LSAGG STAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG ELTAB CLAGG FLAGG ELAGG OM INT LIST ILIST BOOLEAN
+ NNI TSETCAT PSETCAT EUCDOM PID
+quat QUAT QUATCAT ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE
+ RMODULE FRETRCT RETRACT DIFEXT DIFRING PDRING FEVALAB ELTAB
+ EVALAB IEVALAB FLINEXP LINEXP ENTIRER ORDSET DIVRING KONVERT
+ CHARZ CHARNZ FIELD EUCDOM PID GCDDOM INTDOM COMRING UFD INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP PATMAB CFCAT REAL
+ STEP RNS RADCAT
+quat QUATCT2 QUATCAT ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE
+ RMODULE FRETRCT RETRACT DIFEXT DIFRING PDRING FEVALAB ELTAB
+ EVALAB IEVALAB FLINEXP LINEXP ENTIRER ORDSET DIVRING KONVERT
+ CHARZ CHARNZ FIELD EUCDOM PID GCDDOM INTDOM COMRING UFD
+curve RADFF FFCAT MONOGEN FRAMALG FINRALG ALGEBRA RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE MODULE BMODULE RMODULE CHARZ CHARNZ COMRING KONVERT
+ FRETRCT RETRACT FLINEXP LINEXP FINITE FIELD EUCDOM PID
+ GCDDOM INTDOM ENTIRER UFD DIVRING DIFEXT DIFRING PDRING
+ FFIELDC FPC STEP UPOLYC POLYCAT FAMR AMR EVALAB IEVALAB
+ ORDSET PATMAB PFECAT ELTAB QFCAT FEVALAB PATAB FPATMAB TYPE
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL INS CFCAT
+ OM VECTCAT A1AGG FLAGG LNAGG IXAGG HOAGG AGG ELTAGG CLAGG
+rdeef RDEEF GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT LINEXP TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN ACF FIELD EUCDOM PID UFD
+ DIVRING RADCAT FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB
+ TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARNZ LSAGG STAGG
+ URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG UPOLYC POLYCAT FAMR AMR PFECAT DIFRING DIFEXT STEP
+ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG OM CACHSET ILIST BOOLEAN NNI INS OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP CFCAT REAL PI
+rdesys RDEEFS GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT LINEXP TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN ACF FIELD EUCDOM PID UFD
+ DIVRING RADCAT FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB
+ TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARNZ UPOLYC
+ POLYCAT FAMR AMR PFECAT ELTAB DIFRING DIFEXT STEP INT LIST
+ ILIST CACHSET LSAGG STAGG ELAGG FLAGG URAGG
+pfo RDIV FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP FFCAT MONOGEN FRAMALG FINRALG
+ FINITE FFIELDC FPC QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL
+regset RSETCAT GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER TSETCAT PSETCAT CLAGG HOAGG AGG TYPE
+ EVALAB IEVALAB KONVERT OAMONS OCAMON OAMON OASGP ORDSET
+ RPOLCAT POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ FLINEXP LINEXP PATMAB PFECAT UFD BOOLEAN INT LIST ILIST
+ FINITE NNI LSAGG STAGG ELAGG FLAGG URAGG RCAGG LNAGG IXAGG
+ ELTAGG ELTAB OM CLAGG
+rule RULE SETCAT BASTYPE KOERCE ELTAB RETRACT FS ES ORDSET IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID
+ SGROUP GROUP ABELMON ABELSG CABMON RING RNG LMODULE PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ INT LIST ILIST OM BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG AGG
+ LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG SYMBOL REF ALIST STRING
+ CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+rule RULESET SETCAT BASTYPE KOERCE ELTAB FS ES ORDSET RETRACT IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID
+ SGROUP GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE
+ PDRING FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE
+ RMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD
+ DIVRING INT LIST ILIST FSAGG DIAGG DIOPS BGAGG HOAGG AGG
+ CLAGG SETAGG FINITE
+manip SIMPAN INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP FS ES IEVALAB
+ EVALAB PATAB FPATMAB TYPE FRETRCT GROUP PDRING FLINEXP
+ CHARNZ FIELD DIVRING
+fortran SFORT FORTCAT TYPE KOERCE ORDSET SETCAT BASTYPE FS ES RETRACT
+ IEVALAB EVALAB PATAB KONVERT FPATMAB PATMAB FRETRCT MONOID
+ SGROUP GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE
+ PDRING FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE
+ RMODULE FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD
+ DIVRING SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ILIST
+transsolve SOLVESER INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG FS ES RETRACT IEVALAB EVALAB PATAB KONVERT FPATMAB
+ TYPE PATMAB FRETRCT GROUP PDRING FLINEXP LINEXP CHARZ
+ CHARNZ FIELD EUCDOM PID GCDDOM UFD DIVRING UPOLYC POLYCAT
+ FAMR AMR PFECAT ELTAB DIFRING DIFEXT STEP NNI VECTOR IVECTOR
+ IARRAY1 ILIST PI VECTCAT IXAGG HOAGG AGG ELTAGG CLAGG
+combfunc SUMFS INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP FS ES IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP
+ PDRING FLINEXP CHARZ CHARNZ FIELD EUCDOM PID GCDDOM UFD
+ DIVRING COMBOPC CFCAT ACF RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN SYMBOL INT REF ALIST LIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG
+ STAGG URAGG RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG ELAGG
+ OM CACHSET ILIST BOOLEAN
+suts SUTS UTSCAT UPSCAT PSCAT AMR BMODULE RMODULE COMRING ALGEBRA
+ MODULE CHARZ CHARNZ INTDOM ENTIRER ELTAB DIFRING PDRING
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN BOOLEAN
+ NNI INS UFD GCDDOM EUCDOM PID OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL STEP OM STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING FIELD DIVRING
+sign TOOLSIGN RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE INS UFD GCDDOM INTDOM COMRING BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT RETRACT
+ LINEXP PATMAB CFCAT REAL CHARZ STEP FS ES IEVALAB EVALAB
+ PATAB FPATMAB TYPE FRETRCT GROUP PDRING FLINEXP CHARNZ FIELD
+ DIVRING INT INS STRING CHAR SINT OUTFORM LIST PRIMARR A1AGG
+ ISTRING
+efstruc TRIGMNIP GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP ACF
+ FIELD EUCDOM PID UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ
+ CHARNZ INT LIST ILIST COMPCAT MONOGEN FRAMALG FINRALG
+ FINITE DIFEXT DIFRING FFIELDC FPC STEP FEVALAB ELTAB
+ PFECAT OM SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG STAGG ELAGG URAGG INS
+ NNI RCAGG HOAGG AGG IXAGG ELTAGG CLAGG BOOLEAN
+manip TRMANIP ORDSET SETCAT BASTYPE KOERCE GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER FS ES RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP LINEXP CHARZ CHARNZ FIELD EUCDOM PID UFD DIVRING
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN SYMBOL INT REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG LSAGG STAGG URAGG RCAGG HOAGG AGG IXAGG
+ ELTAGG ELTAB CLAGG ELAGG OM NNI BOOLEAN CACHSET POLYCAT FAMR
+ AMR PFECAT
+laurent ULSCCAT ULSCAT UPSCAT PSCAT AMR RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING RETRACT
+ QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP LINEXP PATAB
+ KONVERT FPATMAB TYPE PATMAB STEP ORDSET OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL PFECAT INS CFCAT
+expexpan UPXSSING ACF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FS ES ORDSET RETRACT IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ LINEXP CHARZ CHARNZ FAMR AMR UPXSCCA UPXSCAT UPSCAT PSCAT
+ ELTAB DIFRING NNI INT LIST ILIST INS OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP CFCAT REAL STEP BOOLEAN OM
+ LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG
+ CLAGG FLAGG ELAGG STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING QFCAT FEVALAB DIFEXT PFECAT
+utsode UTSODE ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ UTSCAT UPSCAT PSCAT AMR COMRING CHARZ CHARNZ INTDOM ENTIRER
+ ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN INT LIST ILIST LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG CLAGG KONVERT
+ FLAGG ORDSET ELAGG OM
+oderf UTSODETL RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE UPOLYC POLYCAT PDRING FAMR AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT
+ PATMAB GCDDOM PFECAT UFD ELTAB DIFRING DIFEXT STEP EUCDOM
+ PID FIELD DIVRING LODOCAT OREPCAT UTSCAT UPSCAT PSCAT RADCAT
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN NNI INT SINT
+ VECTOR IVECTOR IARRAY1
+taylor UTS2 RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE UTSCAT UPSCAT PSCAT AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN
+triset WUTSET TSETCAT PSETCAT SETCAT BASTYPE KOERCE CLAGG HOAGG AGG TYPE
+ EVALAB IEVALAB KONVERT INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER OAMONS OCAMON OAMON OASGP ORDSET
+ RPOLCAT POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ FLINEXP LINEXP PATMAB GCDDOM PFECAT UFD LSAGG STAGG URAGG
+ RCAGG LNAGG IXAGG ELTAGG ELTAB FLAGG ELAGG OM INT LIST ILIST
+ BOOLEAN FINITE
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+algfact.spad.pamphlet (IALGFACT SAEFACT RFFACT SAERFFC ALGFACT)
+algfunc.spad.pamphlet (ACF ACFS AF)
+asp.spad.pamphlet (ASP1 ASP10 ASP12 ASP19 ASP20 ASP24 ASP27 ASP28 ASP29 ASP30
+ ASP31 ASP33 ASP34 ASP35 ASP4 ASP41 ASP42 ASP49 ASP50 ASP55
+ ASP6 ASP7 ASP73 ASP74 ASP77 ASP78 ASP8 ASP80 ASP9)
+constant.spad.pamphlet (IAN AN)
+cmplxrt.spad.pamphlet (CMPLXRT)
+crfp.spad.pamphlet (CRFP)
+curve.spad.pamphlet (FFCAT MMAP FFCAT2 CHAVAR RDFF ALGFF)
+derham.spad.pamphlet (LALG EAB ANTISYM DERHAM)
+draw.spad.pamphlet (DRAWCFUN DRAW DRAWCURV DRAWPT)
+d01.spad.pamphlet (NAGD01)
+efstruc.spad.pamphlet (SYMFUNC TANEXP EFSTRUC ITRIGMNP TRIGMNIP CTRIGMNP)
+elemntry.spad.pamphlet (EF)
+elfuts.spad.pamphlet (ELFUTS)
+expexpan.spad.pamphlet (EXPUPXS UPXSSING EXPEXPAN)
+exprode.spad.pamphlet (EXPRODE)
+e04routine.spad.pamphlet (E04DFGA E04FDFA E04GCFA E04JAFA E04MBFA E04NAFA
+ E04UCFA)
+f01.spad.pamphlet (NAGF01)
+f02.spad.pamphlet (NAGF02)
+f04.spad.pamphlet (NAGF04)
+fortmac.spad.pamphlet (MINT MFLOAT MCMPLX)
+fortran.spad.pamphlet (RESULT FC FORTRAN M3D SFORT SWITCH FTEM FEXPR)
+fspace.spad.pamphlet (ES ES1 ES2 FS FS2)
+fs2ups.spad.pamphlet (FS2UPS)
+funcpkgs.spad.pamphlet (FSUPFACT)
+gaussfac.spad.pamphlet (GAUSSFAC)
+gaussian.spad.pamphlet (COMPCAT COMPLPAT CPMATCH COMPLEX COMPLEX2 COMPFACT
+ CINTSLPE)
+generic.spad.pamphlet (GCNAALG CVMP)
+genufact.spad.pamphlet (GENUFACT)
+genups.spad.pamphlet (GENUPS)
+infprod.spad.pamphlet (STINPROD INFPROD0 INPRODPF INPRODFF)
+intaf.spad.pamphlet (INTG0 INTPAF INTAF)
+intalg.spad.pamphlet (DBLRESP INTHERAL INTALG)
+intef.spad.pamphlet (INTEF)
+intpm.spad.pamphlet (INTPM)
+kovacic.spad.pamphlet (KOVACIC)
+lie.spad.pamphlet (LIE JORDAN LSQM)
+liouv.spad.pamphlet (LF)
+lodof.spad.pamphlet (SETMN PREASSOC ASSOCEQ LODOF)
+manip.spad.pamphlet (FACTFUNC POLYROOT ALGMANIP SIMPAN TRMANIP)
+multfact.spad.pamphlet (INNMFACT MULTFACT ALGMFACT)
+naalg.spad.pamphlet (ALGSC SCPKG ALGPKG FRNAAF2)
+newpoly.spad.pamphlet (NSUP NSUP2 RPOLCAT NSMP)
+nlinsol.spad.pamphlet (RETSOL NLINSOL)
+numeigen.spad.pamphlet (INEP NREP NCEP)
+numeric.spad.pamphlet (NUMERIC DRAWHACK)
+numsolve.spad.pamphlet (INFSP FLOATRP FLOATCP)
+oct.spad.pamphlet (OC OCT OCTCT2)
+odealg.spad.pamphlet (ODESYS ODERED ODEPAL)
+openmath.spad.pamphlet (OMEXPR)
+pade.spad.pamphlet (PADEPAC PADE)
+patmatch2.spad.pamphlet (PMINS PMQFCAT PMPLCT PMFS PATMATCH)
+pfo.spad.pamphlet (FORDER RDIV PFOTOOLS PFOQ FSRED PFO)
+polset.spad.pamphlet (PSETCAT GPOLSET)
+primelt.spad.pamphlet (PRIMELT FSPRMELT)
+quat.spad.pamphlet (QUATCAT QUAT QUATCT2)
+rdeef.spad.pamphlet (INTTOOLS RDEEF)
+rdesys.spad.pamphlet (RDETRS RDEEFS)
+riccati.spad.pamphlet (ODEPRRIC ODERTRIC)
+rule.spad.pamphlet (RULE APPRULE RULESET)
+sign.spad.pamphlet (TOOLSIGN INPSIGN SIGNRF LIMITRF)
+special.spad.pamphlet (DFSFUN ORTHPOL NTPOLFN)
+suts.spad.pamphlet (SUTS)
+tools.spad.pamphlet (ESTOOLS ESTOOLS1 ESTOOLS2)
+triset.spad.pamphlet (TSETCAT GTSET PSETPK)
+tube.spad.pamphlet (TUBE TUBETOOL EXPRTUBE NUMTUBE)
+utsode.spad.pamphlet (UTSODE)
+\end{verbatim}
+
+<<layer20>>=
+LAYER20=${OUT}/ACFS.o ${OUT}/ACFS-.o \
+ ${OUT}/AF.o ${OUT}/ALGFACT.o ${OUT}/ALGFF.o \
+ ${OUT}/ALGMANIP.o ${OUT}/ALGMFACT.o ${OUT}/ALGPKG.o \
+ ${OUT}/ALGSC.o \
+ ${OUT}/AN.o ${OUT}/APPRULE.o \
+ ${OUT}/ASP19.o \
+ ${OUT}/ASP20.o ${OUT}/ASP30.o ${OUT}/ASP31.o ${OUT}/ASP35.o \
+ ${OUT}/ASP41.o ${OUT}/ASP42.o ${OUT}/ASP74.o ${OUT}/ASP77.o \
+ ${OUT}/ASP80.o ${OUT}/ASP9.o ${OUT}/CINTSLPE.o \
+ ${OUT}/COMPFACT.o ${OUT}/COMPLEX.o \
+ ${OUT}/COMPLPAT.o ${OUT}/CMPLXRT.o ${OUT}/CPMATCH.o \
+ ${OUT}/CRFP.o ${OUT}/CTRIGMNP.o ${OUT}/D01WGTS.o \
+ ${OUT}/D02AGNT.o ${OUT}/D03EEFA.o \
+ ${OUT}/DBLRESP.o \
+ ${OUT}/DERHAM.o ${OUT}/DFSFUN.o \
+ ${OUT}/DRAWCURV.o ${OUT}/E04NAFA.o ${OUT}/E04UCFA.o \
+ ${OUT}/EF.o \
+ ${OUT}/EFSTRUC.o ${OUT}/ELFUTS.o ${OUT}/ESTOOLS.o \
+ ${OUT}/EXPEXPAN.o \
+ ${OUT}/EXPRODE.o ${OUT}/EXPRTUBE.o ${OUT}/EXPR2.o ${OUT}/FC.o \
+ ${OUT}/FDIVCAT.o ${OUT}/FDIVCAT-.o \
+ ${OUT}/FDIV2.o ${OUT}/FFCAT2.o ${OUT}/FLOATCP.o \
+ ${OUT}/FORDER.o ${OUT}/FORTRAN.o ${OUT}/FSRED.o \
+ ${OUT}/FSUPFACT.o ${OUT}/FRNAAF2.o \
+ ${OUT}/FSPECF.o ${OUT}/FS2.o ${OUT}/FS2UPS.o \
+ ${OUT}/GAUSSFAC.o ${OUT}/GCNAALG.o ${OUT}/GENUFACT.o ${OUT}/GENUPS.o \
+ ${OUT}/GTSET.o ${OUT}/GPOLSET.o ${OUT}/IAN.o ${OUT}/INEP.o \
+ ${OUT}/INFPROD0.o ${OUT}/INFSP.o ${OUT}/INPRODFF.o \
+ ${OUT}/INPRODPF.o ${OUT}/INTAF.o ${OUT}/INTALG.o ${OUT}/INTEF.o \
+ ${OUT}/INTG0.o ${OUT}/INTHERAL.o \
+ ${OUT}/INTPAF.o ${OUT}/INTPM.o ${OUT}/INTTOOLS.o \
+ ${OUT}/ITRIGMNP.o ${OUT}/JORDAN.o \
+ ${OUT}/KOVACIC.o ${OUT}/LF.o ${OUT}/LIE.o ${OUT}/LODOF.o \
+ ${OUT}/LSQM.o ${OUT}/OMEXPR.o \
+ ${OUT}/MCMPLX.o ${OUT}/MULTFACT.o ${OUT}/NAGD01.o \
+ ${OUT}/NAGD02.o ${OUT}/NAGF01.o ${OUT}/NAGF02.o ${OUT}/NAGF04.o \
+ ${OUT}/NCEP.o ${OUT}/NLINSOL.o ${OUT}/NSMP.o ${OUT}/NUMERIC.o \
+ ${OUT}/OCT.o ${OUT}/OCTCT2.o ${OUT}/ODEPAL.o ${OUT}/ODERTRIC.o \
+ ${OUT}/PADE.o \
+ ${OUT}/PAN2EXPR.o ${OUT}/PDEPACK.o ${OUT}/PFO.o \
+ ${OUT}/PFOQ.o ${OUT}/PICOERCE.o \
+ ${OUT}/PMASSFS.o ${OUT}/PMFS.o \
+ ${OUT}/PMPREDFS.o ${OUT}/PRIMELT.o ${OUT}/PSETPK.o \
+ ${OUT}/QUAT.o ${OUT}/QUATCT2.o \
+ ${OUT}/RADFF.o ${OUT}/RDEEF.o ${OUT}/RDEEFS.o \
+ ${OUT}/RDIV.o ${OUT}/RSETCAT.o ${OUT}/RSETCAT-.o ${OUT}/RULE.o \
+ ${OUT}/RULESET.o ${OUT}/SIMPAN.o \
+ ${OUT}/SFORT.o ${OUT}/SOLVESER.o \
+ ${OUT}/SUMFS.o ${OUT}/SUTS.o ${OUT}/TOOLSIGN.o \
+ ${OUT}/TRIGMNIP.o ${OUT}/TRMANIP.o \
+ ${OUT}/ULSCCAT.o ${OUT}/ULSCCAT-.o ${OUT}/UPXSSING.o ${OUT}/UTSODE.o \
+ ${OUT}/UTSODETL.o ${OUT}/UTS2.o ${OUT}/WUTSET.o
+
+@
+\subsection{Layer21}
+\begin{verbatim}
+defintef DEFINTEF EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT
+ LINEXP TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PRIMCAT
+ ACFS ACF FIELD UFD DIVRING RADCAT FS ES IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING
+ FLINEXP CHARZ BOOLEAN CACHSET SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ CFCAT REAL STEP OM ILIST POLYCAT FAMR AMR PFECAT LSAGG
+ STAGG URAGG RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG ELAGG
+defintrf DEFINTRF EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT
+ LINEXP FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE
+ PATMAB FRETRCT GROUP PDRING FLINEXP CHARNZ FIELD UFD DIVRING
+ BOOLEAN POLYCAT FAMR AMR PFECAT INT LIST ILIST QFCAT FEVALAB
+ ELTAB DIFEXT DIFRING STEP OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP REAL ACFS ACF RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN COMBOPC CFCAT LFCAT PRIMCAT SPFCAT
+defintrf DFINTTLS GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN ACFS ACF FIELD
+ EUCDOM PID UFD DIVRING RADCAT FS ES IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ CHARZ CHARNZ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING CFCAT REAL STEP OM BOOLEAN STRING CHAR SINT OUTFORM
+ LIST PRIMARR A1AGG ISTRING SYMBOL REF ALIST SRAGG FLAGG
+ LNAGG ILIST POLYCAT FAMR AMR PFECAT QFCAT FEVALAB ELTAB
+ DIFEXT LSAGG
+d01transform D01TRNS NUMINT SETCAT BASTYPE KOERCE STRING CHAR SINT OUTFORM
+ LIST INT PRIMARR A1AGG ISTRING SRAGG SYMBOL REF ALIST FLAGG
+ LNAGG INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA
+ MODULE ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP QFCAT FIELD DIVRING FEVALAB ELTAB
+ EVALAB IEVALAB DIFEXT PDRING FLINEXP PATAB FPATMAB TYPE
+ CHARNZ PFECAT OM FPS RNS RADCAT FS ES FRETRCT GROUP TRANFUN
+cont ESCONT FPS RNS FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING ORDRING OAGROUP OCAMON OAMON OASGP ORDSET REAL
+ KONVERT RETRACT RADCAT PATMAB CHARZ DIFRING OM TRANFUN
+ TRIGCAT ATRIG HYPCAT AHYP ELEMFUN DFLOAT LSAGG STAGG URAGG
+ RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG
+ ELTAB CLAGG FLAGG ELAGG INS OINTDOM LINEXP CFCAT STEP QFCAT
+ FEVALAB DIFEXT PDRING FLINEXP PATAB FPATMAB CHARNZ PFECAT
+ FS ES FRETRCT GROUP VECTCAT A1AGG ACFS ACF COMBOPC LFCAT
+ PRIMCAT SPFCAT
+efuls EFULS PTRANFN ULSCCAT ULSCAT UPSCAT PSCAT AMR RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD
+ DIVRING RETRACT QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP
+ LINEXP PATAB KONVERT FPATMB TYPE PATMAB STEP ORDSET OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL PFECAT UTSCAT NNI
+ INT INS CFCAT STRING CHAR SINT OUTFORM LIST PRIMARR A1AGG
+ ISTRING
+expr EXPR FS ES ORDSET SETCAT BASTYPE KOERCE RETRACT IEVALAB EVALAB
+ PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT MONOID SGROUP
+ GROUP ABELMON ABELSG ABELGRP CABMON RING RNG LMODULE PDRING
+ FLINEXP LINEXP CHARZ CHARNZ ALGEBRA MODULE BMODULE RMODULE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING ENTIRER UFD DIVRING
+ ACFS ACF RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ COMBOPC CFCAT LFCAT PRIMCAT SPFCAT BOOLEAN CACHSET POLYCAT
+ FAMR AMR PFECAT SYMBOL INT REF ALIST LIST STRING CHAR SINT
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ILIST LSAGG
+ STAGG ELAGG URAGG RCAGG IXAGG CLAGG HOAGG ORDSET AGG ELTAGG
+ ELTAB OM NNI PI VECTOR IVECTOR ARRAY1 VECTCAT QFCAT FEVALAB
+ DIFEXT DIFRING STEP OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP REAL UPOLYC INS FPS RNS
+expr2ups EXPR2UPS GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP ACF
+ FIELD EUCDOM PID UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ
+ CHARNZ INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING CFCAT REAL STEP ULSCCAT ULSCAT UPSCAT PSCAT AMR
+ ELTAB QFCAT FEVALAB DIFEXT PFECAT BOOLEAN STRING CHAR SINT
+ OUTFORM LIST INT PRIMARR A1AGG ISTRING NNI ILIST UPXSCCA
+ UPXSCAT
+divisor FDIV FDIVCAT ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD
+ DIVRING UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT
+ RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB
+ PFECAT ELTAB DIFRING DEFEXT STEP FFCAT MONOGEN FRAMALG
+ FINRALG FINITE FFIELDC FPC INT VECTOR IVECTOR IARRAY1
+ VECTCAT A1AGG INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ CFCAT REAL OM NNI PI FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG
+ CLAGG QFCAT FEVALAB PATAB FPATMAB
+integrat FSCINT EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT
+ LINEXP TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN ACFS ACF
+ FIELD UFD DIVRING RADCAT FS ES IEVALAB EVALAB PATAB KONVERT
+ FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARNZ
+ INT LIST ILIST COMPCAT MONOGEN FRAMALG FINRALG FINITE DIFEXT
+ DIFRING FFIELDC FPC STEP FEVALAB ELTAB PFECAT OM LFCAT
+ PRIMCAT BOOLEAN LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG
+ IXAGG ELTAGG CLAGG FLAGG ELAGG SYMBOL REF ALIST STRING CHAR
+ SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+integrat FSINT EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT
+ LINEXP TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PRIMCAT
+ ACFS ACF FIELD UFD DIVRING RADCAT FS ES IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ CHARNZ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG NNI ILIST COMPCAT
+ MONOGEN FRAMALG FINRALG FINITE DIFEXT DIFRING FFIELDC FPC
+ STEP FEVALAB ELTAB PFECAT OM LSAGG STAGG URAGG RCAGG HOAGG
+ AGG IXAGG ELTAGG CLAGG ELAGG CACHSET BOOLEAN
+fs2expxp FS2EXPXP ACF FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN FS ES
+ ORDSET RETRACT IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE
+ PATMAB FRETRCT GROUP PDRING FLINEXP LINEXP CHARZ CHARNZ PI
+ NNI INT INS OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP
+ DIFRING CFCAT REAL STEP CACHSET LIST ILIST SYMBOL REF ALIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG BOOLEAN QFCAT FEVALAB ELTAB DIFEXT PFECAT UPXSCCA
+ UPXSCAT UPSCAT PSCAT AMR ULSCCAT ULSCAT LSAGG STAGG ELAGG
+ URAGG OM RCAGG HOAGG AGG IXAGG ELTAGG CLAGG STRICAT
+gseries GSERIES RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE UPXSCAT UPSCAT PSCAT AMR BMODULE
+ RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER
+ ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING STRING
+ CHAR SINT OUTFORM LIST INT PRIMARR A1AGG ISTRING SYMBOL REF
+ ALIST SRAGG FLAGG LNAGG LSAGG STAGG URAGG RCAGG HOAGG AGG
+ TYPE EVALAB IEVALAB IXAGG ELTAGG CLAGG KONVERT ORDSET ELAGG
+ OM PATMAB ILIST PRIMCAT ACFS ACF FS ES RETRACT PATAB FPATMAB
+ FRETRCT GROUP FLINEXP LINEXP INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP CFCAT REAL STEP QFCAT FEVALAB DIFEXT
+ PFECAT
+divisor HELLFDIV FDIVCAT ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG
+ SGROUP MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE
+ ENTIRER UFD DIVRING UPOLYC POLYCAT PDRING FAMR AMR CHARZ
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP ORDSET
+ KONVERT PATMAB PFECAT ELTAB DIFRING DIFEXT STEP FFCAT
+ MONOGEN FRAMALG FINRALG FINITE FFIELDC FPC INT SYMBOL REF
+ ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ SRAGG FLAGG LNAGG BOOLEAN NNI ILIST LSAGG STAGG ELAGG URAGG
+ QFCAT FEVALAB PATAB FPATMAB TYPE OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL OM VECTCAT IXAGG HOAGG AGG ELTAGG
+ CLAGG VECTOR IVECTOR IARRAY1 INS CFCAT PI
+laplace INVLAPLA EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT
+ LINEXP TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PRIMCAT
+ SPFCAT ACFS ACF FIELD UFD DIVRING RADCAT FS ES IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP
+ PDRING FLINEXP CHARNZ BOOLEAN UPOLYC POLYCAT FAMR AMR
+ PFECAT ELTAB DIFRING DIFEXT STEP LSAGG STAGG URAGG RCAGG
+ HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM INT LIST
+ ILIST NNI CACHSET PI INS OINTDOM ORDRING OAGROUP OCAMON
+ OASGP CFCAT REAL
+irexpand IR2F GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT ORDSET LINEXP ACFS ACF FIELD
+ EUCDOM PID UFD DIVRING RADCAT FS ES IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ CHARZ CHARNZ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN INT
+ LIST ILIST SYMBOL REF ALIST STRING CHAR SINT OUTFORM PRIMARR
+ A1AGG ISTRING SRAGG FLAGG LNAGG LSAGG STAGG ELAGG URAGG INS
+ BOOLEAN OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING
+ CFCAT REAL STEP NNI PI CACHSET UPOLYC POLYCAT FAMR AMR
+ PFECAT ELTAB DIFEXT OM VECTOR IVECTOR IARRAY1 RCAGG HOAGG
+ AGG IXAGG ELTAGG CLAGG
+irexpand IRRF2F GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER RETRACT ORDSET LINEXP POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT EVALAB IEVALAB FLINEXP KONVERT
+ PATMAB PFECAT UFD FS ES PATAB FPATMAB TYPE GROUP FIELD
+ EUCDOM PID DIVRING QFCAT FEVALAB ELTAB DIFEXT DIFRING STEP
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL ACFS ACF
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN COMBOPC
+ CFCAT LFCAT PRIMCAT SPFCAT INT LIST ILIST
+laplace LAPLACE EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ RETRACT
+ LINEXP TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN PRIMCAT
+ ACFS ACF FIELD UFD DIVRING RADCAT FS ES IEVALAB EVALAB PATAB
+ KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP PDRING FLINEXP
+ CHARNZ SYMBOL INT REF ALIST LIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG NNI LSAGG STAGG
+ URAGG RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG ELAGG OM
+ ILIST BOOLEAN UPOLYC POLYCAT FAMR AMR PFECAT DIFRING DIFEXT
+ STEP CACHSET
+limitps LIMITPS GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER ORDSET RETRACT LINEXP ACF FIELD
+ EUCDOM PID UFD DIVRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB
+ TYPE PATMAB FRETRCT GROUP PDRING FLINEXP CHARZ CHARNZ LSAGG
+ STAGG URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG OM INT LIST ILIST BOOLEAN SYMBOL REF ALIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING NNI INS
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP DIFRING CFCAT
+ REAL STEP QFCAT FEVALAB DIFEXT PFECAT UPXSCCA UPXSCAT PSCAT
+ AMR ULSCCAT ULSCAT
+odeef LODEEF ORDSET SETCAT BASTYPE KOERCE EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER RETRACT
+ LINEXP CHARZ ACFS ACF FIELD UFD DIVRING RADCAT FS ES IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP
+ PDRING FLINEXP CHARNZ TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN PRIMCAT LODOCAT OREPCAT ELTAB CACHSET POLYCAT FAMR
+ AMR PFECAT NNI INT LSAGG STAGG URAGG RCAGG HOAGG AGG LNAGG
+ IXAGG ELTAGG CLAGG FLAGG ELAGG OM LIST ILIST BOOLEAN UPOLYC
+ DIFRING DIFEXT STEP QFCAT FEVALAB OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP REAL VECTOR IVECTOR IARRAY1 INS CFCAT
+ VECTCAT A1AGG
+nlode NODE1 ORDSET SETCAT BASTYPE KOERCE EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ RETRACT LINEXP CHARZ ACFS ACF FIELD UFD DIVRING RADCAT
+ FS ES IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB
+ FRETRCT GROUP PDRING FLINEXP CHARNZ TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN PRIMCAT SYMBOL INT REF ALIST LIST
+ STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG
+ LNAGG CACHSET ILIST LSAGG STAGG URAGG HOAGG AGG IXAGG
+ ELTAGG ELTAB CLAGG ELAGG OM POLYCAT FAMR AMR PFECAT NNI PI
+oderf ODECONST ORDSET SETCAT BASTYPE KOERCE EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ RETRACT LINEXP CHARZ ACFS ACF FIELD UFD DIVRING RADCAT FS
+ ES IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT
+ GROUP PDRING FLINEXP CHARNZ TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN PRIMCAT LODOCAT OREPCAT ELTAB BOOLEAN INT LIST
+ ILIST UPOLYC POLYCAT FAMR AMR PFECAT DIFRING DIFEXT STEP
+ SINT NNI
+oderf ODEINT ORDSET SETCAT BASTYPE KOERCE EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER RETRACT
+ LINEXP CHARZ ACFS ACF FIELD UFD DIVRING RADCAT FS ES IEVALAB
+ EVALAB PATAB KONVERT FPATMAB TYPE PATMAB FRETRCT GROUP
+ PDRING FLINEXP CHARNZ TRANFUN TRIGCAT ATRIG HYPCAT AHYP
+ ELEMFUN PRIMCAT INT LIST ILIST INS OINTDOM ORDRING OAGROUP
+ OCAMON OAMON OASGP DIFRING CFCAT REAL STEP LSAGG STAGG
+ URAGG RCAGG HOAGG AGG LNAGG IXAGG ELTAGG ELTAB CLAGG FLAGG
+ ELAGG OM CACHSET SYMBOL REF ALIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG NNI
+radeigen REP INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP POLYCAT PDRING
+ FAMR AMR CHARNZ FRETRCT EVALAB IEVALAB FLINEXP PFECAT QFCAT
+ FIELD DIVRING FEVALAB ELTAB DIFEXT PATAB FPATMAB TYPE FS ES
+ GROUP OM NNI INT SINT SYMBOL REF ALIST LIST STRING CHAR
+ OUTFORM PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG ACFS ACF
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN COMBOPC
+ LFCAT PRIMCAT SPFCAT ILIST MATCAT ARR2CAT HOAGG AGG PI LSAGG
+ STAGG URAGG RCAGG IXAGG ELTAGG CLAGG ELAGG
+solverad SOLVERAD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER ORDSET CHARZ BOOLEAN
+ FS ES RETRACT IEVALAB EVALAB PATAB KONVERT FPATMAB TYPE
+ PATMAB FRETRCT GROUP PDRING FLINEXP LINEXP CHARNZ FIELD
+ UFD DIVRING ACFS ACF RADCAT TRANFUN TRIGCAT ATRIG HYPCAT
+ AHYP ELEMFUN COMBOPC CFCAT LFCAT PRIMCAT SPFCAT SYMBOL INT
+ REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG POLYCAT FAMR AMR PFECAT ILIST
+ LSAGG STAGG URAGG RCAGG HOAGG AGG IXAGG ELTAGG ELTAB CLAGG
+ ELAGG OM PI
+suls SULS RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE ULSCCAT ULSCAT UPSCAT PSCAT AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING
+ RETRACT QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP LINEXP
+ PATAB KONVERT FPATMAB TYPE PATMAB STEP ORDSET OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL PFECAT INT BOOLEAN
+ POLYCAT FAMR FRETRCT INS CFCAT UTSCAT OAMONS FPS RNS UPOLYC
+ OM
+supxs SUPXS UPXSCCA UPXSCAT UPSCAT PSCAT AMR BMODULE RMODULE COMRING
+ ALGEBRA MODULE CHARZ CHARNZ INTDOM ENTIRER ELTAB DIFRING
+ PDRING RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+ FIELD EUCDOM PID GCDDOM UFD DIVRING RETRACT ULSCCAT ULSCAT
+ QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP LINEXP PATAB
+ KONVERT FPATMAB TYPE PATMAB STEP ORDSET OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OASGP REAL PFECAT INS CFCAT INT NNI OM
+laurent ULS RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE ULSCCAT ULSCAT UPSCAT PSCAT
+ AMR BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ
+ INTDOM ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT
+ ATRIG HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD
+ DIVRING RETRACT QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP
+ LINEXP PATAB KONVERT FPATMAB TYPE PATMAB STEP ORDSET OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL PFECAT UTSCAT OAMONS
+ FPS RNS INS CFCAT UPOLYC POLYCAT FAMR FRETRCT OM
+laurent ULSCONS ULSCCAT ULSCAT UPSCAT PSCAT AMR RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING
+ RETRACT QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP LINEXP
+ PATAB KONVERT FPATMAB TYPE PATMAB STEP ORDSET OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP REAL PFECAT UTSCAT INT
+ NNI BOOLEAN INS OAMONS POLYCAT FAMR FRETRCT SYMBOL REF ALIST
+ LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING SRAGG
+ FLAGG LNAGG INS CFCAT LSAGG STAGG URAGG RCAGG HOAGG AGG
+ IXAGG ELTAGG CLAGG OM ILIST PRIMCAT ACFS ACF FS ES GROUP
+ FPS RNS UPOLYC
+puiseux UPXS RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE
+ SGROUP MONOID LMODULE UPXSCCA UPXSCAT UPSCAT PSCAT AMR
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING
+ RETRACT ULSCCAT ULSCAT QFCAT FEVALAB EVALAB IEVALAB DIFEXT
+ FLINEXP LINEXP PATAB KONVERT FPATMAB TYPE PATMAB STEP ORDSET
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL PFECAT INS
+ CFCAT INT NNI PI LIST ILIST SINT LSAGG STAGG URAGG RCAGG
+ HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM SYMBOL
+ REF ALIST STRING CHAR OUTFORM PRIMARR A1AGG ISTRING SRAGG
+puiseux UPXSCONS UPXSCCA UPXSCAT UPSCAT PSCAT AMR RING RNG ABELGRP CABMON
+ ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE COMRING ALGEBRA MODULE CHARZ CHARNZ INTDOM
+ ENTIRER ELTAB DIFRING PDRING RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN FIELD EUCDOM PID GCDDOM UFD DIVRING
+ RETRACT ULSCAT INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET KONVERT LINEXP PATMAB CFCAT REAL STEP INT NNI
+ SYMBOL REF ALIST LIST STRING CHAR SINT OUTFORM PRIMARR A1AGG
+ ISTRING SRAGG FLAGG LNAGG LSAGG STAGG URAGG HOAGG AGG TYPE
+ EVALAB IEVALAB IXAGG ELTAGG CLAGG ELAGG ILIST RCAGG ACFS
+ ACF FS ES PATAB FPATMAB FRETRCT GROUP FLINEXP QFCAT FEVALAB
+ DIFEXT PFECAT
+taylor UTS UTSCAT UPSCAT PSCAT AMR BMODULE RMODULE COMRING ALGEBRA
+ MODULE CHARZ CHARNZ INTDOM ENTIRER ELTAB DIFRING PDRING
+ RADCAT TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN NNI INT
+ BOOLEAN SINT PI SYMBOL REF ALIST LIST STRING CHAR OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG FLAGG LNAGG FIELD EUCDOM PID
+ GCDDOM UFD DIVRING INS OINTDOM ORDRING OAGROUP OCAMON OAMON
+ OASGP ORDSET KONVERT RETRACT LINEXP PATMAB CFCAT REAL STEP
+ QFCAT FEVALAB EVALAB IEVALAB DIFEXT FLINEXP PATAB FPATMAB
+ TYPE PFECAT OM LSAGG STAGG URAGG RCAGG HOAGG AGG IXAGG
+ ELTAGG CLAGG ELAGG ILIST PRIMCAT ACFS ACF FS ES FRETRCT
+ GROUP OAMONS
+\end{verbatim}
+\subsubsection{Completed spad files}
+\begin{verbatim}
+cont.spad.pamphlet (ESCONT ESCONT1)
+ddfact.spad.pamphlet (DDFACT)
+defintef.spad.pamphlet (DEFINTEF)
+defintrf.spad.pamphlet (DFINTTLS DEFINTRF)
+divisor.spad.pamphlet (FRIDEAL FRIDEAL2 MHROWRED FRMOD FDIVCAT HELLFDIV FDIV
+ FDIV2)
+d01transform.spad.pamphlet (D01TRNS)
+efuls.spad.pamphlet (EFULS)
+expr.spad.pamphlet (EXPR PAN2EXPR EXPR2 PMPREDFS PMASSFS PMPRED PMASS HACKPI
+ PICOERCE)
+expr2ups.spad.pamphlet (EXPR2UPS)
+fs2expxp.spad.pamphlet (FS2EXPXP)
+gseries.spad.pamphlet (GSERIES)
+integrat.spad.pamphlet (FSCINT FSINT)
+irexpand.spad.pamphlet (IR2F IRRF2F)
+laplace.spad.pamphlet (LAPLACE INVLAPLA)
+laurent.spad.pamphlet (ULSCCAT ULSCONS ULS USL2)
+nlode.spad.pamphlet (NODE1)
+oderf.spad.pamphlet (BALFACT BOUNDZRO ODEPRIM UTSODETL ODERAT ODETOOLS ODEINT
+ ODECONST)
+puiseux.spad.pamphlet (UPXSCCA UPXSCONS UPXS UPXS2)
+radeigen.spad.pamphlet (REP)
+solverad.spad.pamphlet (SOLVERAD)
+suls.spad.pamphlet (SULS)
+supxs.spad.pamphlet (SUPXS)
+taylor.spad.pamphlet (ITAYLOR UTS UTS2)
+\end{verbatim}
+
+<<layer21>>=
+LAYER21=${OUT}/DEFINTEF.o ${OUT}/DFINTTLS.o ${OUT}/DEFINTRF.o \
+ ${OUT}/D01TRNS.o ${OUT}/EFULS.o \
+ ${OUT}/ESCONT.o ${OUT}/EXPR.o \
+ ${OUT}/EXPR2UPS.o ${OUT}/FDIV.o ${OUT}/FSCINT.o ${OUT}/FSINT.o \
+ ${OUT}/FS2EXPXP.o ${OUT}/GSERIES.o \
+ ${OUT}/HELLFDIV.o ${OUT}/INVLAPLA.o \
+ ${OUT}/IR2F.o ${OUT}/IRRF2F.o ${OUT}/LAPLACE.o ${OUT}/LIMITPS.o \
+ ${OUT}/LODEEF.o ${OUT}/NODE1.o ${OUT}/ODECONST.o \
+ ${OUT}/ODEINT.o ${OUT}/REP.o ${OUT}/SOLVERAD.o ${OUT}/SULS.o \
+ ${OUT}/SUPXS.o ${OUT}/ULS.o \
+ ${OUT}/ULSCONS.o ${OUT}/UPXS.o ${OUT}/UPXSCONS.o ${OUT}/UTS.o
+
+@
+
+\subsection{Order}
+The final order of the layers is determined here.
+<<order>>=
+ORDER= ${LAYER0BOOTSTRAP} ${LAYER0} ${LAYER1} ${LAYER2} ${LAYER3} ${LAYER4} \
+ ${LAYER5} ${LAYER6} ${LAYER7} ${LAYER8} ${LAYER9} ${LAYER10} \
+ ${LAYER11} ${LAYER12} ${LAYER13} ${LAYER14} ${LAYER15} ${LAYER16} \
+ ${LAYER17} ${LAYER18} ${LAYER19} ${LAYER20} ${LAYER21}
+
+@
+
+
+transsolve SOLVETRA ORDSET SETCAT BASTYPE KOERCE EUCDOM PID GCDDOM INTDOM
+ COMRING RING RNG ABELGRP CABMON ABELMON ABELSG SGROUP
+ MONOID LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER
+ RETRACT LINEXP CHARZ INT LIST ILIST LSAGG STAGG URAGG RCAGG
+ HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ KONVERT FLAGG ELAGG OM NNI QFCAT FIELD UFD DIVRING FEVALAB
+ DIFEXT DIFRING PDRING FLINEXP PATAB FPATMAB PATMAB STEP
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL CHARNZ
+ PFECAT BOOLEAN SYMBOL REF ALIST STRING CHAR SINT OUTFORM
+ PRIMARR A1AGG ISTRING SRAGG UPOLYC POLYCAT FAMR AMR FRETRCT
+ FS ES GROUP CACHSET ACFS ACF RADCAT TRANFUN TRIGCAT ATRIG
+ HYPCAT AHYP ELEMFUN COMBOPC CFCAT LFCAT PRIMCAT SPFCAT
+
+
+catdef ABELGRP CABMON
+catdef ABELMON ABELSG
+catdef ABELSG (SETCAT)
+catdef ABELSG- (SETCAT RING) RNG
+multfact ALGMFACT (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+op BOP (ORDSET SETCAT BASTYPE KOERCE) SYMBOL
+combfunc COMBF (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+op COMMONOP (BOOLEAN) SYMBOL
+algcat CPIMA (COMRING) RING
+catdef DIVRING (INS) UFD
+exprode EXPRODE (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+expr EXPR2 (ORDSET SETCAT BASTYPE KOERCE RING) RNG
+numsolve FLOATRP ORDRING
+fortran FORTRAN (FORTCAT TYPE KOERCE SINT) SYMBOL
+pfo FSRED (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+gbintern 14 GBINTERN GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER OAMONS OCAMON
+ OAMON OASGP ORDSET POLYCAT PDRING FAMR AMR CHARZ CHARNZ
+ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP KONVERT
+ PATMAB PFECAT UFD NNI INT BOOLEAN LIST ILIST LSAGG STAGG
+ ELAGG FLAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG ELTAGG
+ ELTAB CLAGG FLAGG ELAGG OM PI
+view2D 14 GRIMAGE SETCAT BASTYPE KOERCE INS UFD GCDDOM INTDOM COMRING RING
+ RNG ABELGRP CABMON ABELMON ABELSG SGROUP MONOID LMODULE
+ BMODULE RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM
+ ORDRING OAGROUP OCAMON OAMON OASGP ORDSET DIFRING KONVERT
+ RETRACT LINEXP PATMAB CFCAT REAL CHARZ STEP OM FPS RNS
+ FIELD DIVRING RADCAT INT LSAGG STAGG URAGG RCAGG HOAGG
+ AGG TYPE EVALAB IEVALAB LNAGG IXAGG ELTAGG ELTAB CLAGG
+ FLAGG ELAGG LIST ILIST NNI PI DFLOAT PTCAT VECTCAT A1AGG
+ STRING CHAR SINT OUTFORM PRIMARR STRICAT SRAGG ISTRING
+ TRANFUN ELEMFUN HYPCAT ATRIG TRIGCAT RADCAT AHYP BOOLEAN
+multfact 14 INNMFACT ORDSET SETCAT BASTYPE KOERCE OAMONS OCAMON OAMON OASGP
+ ABELMON ABELSG CABMON EUCDOM PID GCDDOM INTDOM COMRING
+ RING RNG ABELGRP SGROUP MONOID LMODULE BMODULE RMODULE
+ ALGEBRA MODULE ENTIRER CHARZ POLYCAT PDRING FAMR AMR
+ CHARNZ FRETRCT RETRACT EVALAB IEVALAB FLINEXP LINEXP
+ KONVERT PATMAB PFDCAT UFD PI NNI INT LIST ILIST UPOLYC
+ ELTAB DIFRING DIFEXT STEP FIELD DIVRING BOOLEAN LSAGG
+ STAGG ELAGG FLAGG URAGG RCAGG HOAGG AGG TYPE LNAGG IXAGG
+ ELTAGG CLAGG FLAGG ELAGG OM
+intaf INTAF (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+intalg INTALG (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+intpm INTPM (ORDSET SETCAT BASTYPE KOERCE RETRACT) GCDDOM
+rdeef INTTOOLS (ORDSET SETCAT BASTYPE KOERCE) FS
+intrf 14 INTTR FIELD EUCDOM PID GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SETCAT BASTYPE KOERCE SGROUP MONOID
+ LMODULE BMODULE RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING
+ UPOLYC POLYCAT PDRING FAMR AMR CHARZ CHARNZ FRETRCT RETRACT
+ EVALAB IEVALAB FLINEXP LINEXP ORDSET KONVERT PATMAB PFECAT
+ ELTAB DIFRING DIFEXT STEP QFCAT FEVALAB PATAB FPATMAB TYPE
+ OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP REAL BOOLEAN
+ NNI INT PRIMARR INS CFCAT LIST ILIST PI LSAGG STAGG URAGG
+ RCAGG HOAGG AGG LNAGG IXAGG ELTAGG CLAGG FLAGG ELAGG OM
+ SINT
+kl KERNEL (CACHSET ORDSET SETCAT BASTYPE KOERCE PATAB KONVERT) INT
+liouv LF (ORDSET SETCAT BASTYPE KOERCE INTDOM COMRING RING) RNG
+odeef LODEEF (ORDSET SETCAT BASTYPE KOERCE) EUCDOM
+lodof LODOF FIELD
+catdef GCDDOM (INTDOM COMRING RING) RNG
+mfinfact MFINFACT (ORDSET SETCAT BASTYPE KOERCE) OAMONS
+special NTPOLFN (COMRING) RING
+numeric NUMERIC (KONVERT COMRING) RING
+oct OC (COMRING) RING
+openmath OMEXPR (OM ORDSET SETCAT BASTYPE KOERCE RING) RNG
+plot PLOT (PPCURVE KOERCE BOOLEAN) INT
+plot3d PLOT3D PSCURVE KOERCE BOOLEAN INT DFLOAT FPS RNS FIELD EUCDOM
+ PID GCDDOM INTDOM COMRING RING RNG ABELGRP CABMON ABELMON
+ ABELSG SETCAT BASTYPE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UFD DIVRING ORDRING OAGROUP
+ OCAMON OAMON OASGP ORDSET REAL KONVERT RETRACT RADCAT
+ PATMAB CHARZ LIST ILIST NNI PI LSAGG STAGG ELAGG FLAGG
+ URAGG RCAGG HOAGG AGG TYPE EVALAB IEVALAB LNAGG IXAGG
+ ELTAGG ELTAB CLAGG FLAGG OM SINT INS OINTDOM DIFRING LINEXP
+ CFCAT STEP TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN
+prs 14 PRS INTDOM COMRING RING RNG ABELGRP CABMON ABELMON ABELSG
+ SETCAT BASTYPE KOERCE SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER UPOLYC POLYCAT PDRING
+ FAMR AMR CHARZ CHARNZ FRETRCT RETRACT EVALAB IEVALAB
+ FLINEXP LINEXP ORDSET KONVERT PATMAB GCDDOM PFECAT UFD
+ ELTAB DIFRING DIFEXT STEP EUCDOM PID FIELD DIVRING NNI
+ INT VECTOR IVECTOR IARRAY1 VECTCAT BOOLEAN PI A1AGG
+ FLAGG LNAGG IXAGG HOAGG AGG TYPE ELTAGG CLAGG FINITE
+ LIST ILIST LSAGG STAGG
+quat QUATCAT (COMRING) RING
+boolean REF TYPE SETCAT BASTYPE KOERCE fails
+routines ROUTINE TBAGG
+sttaylor STTAYLOR RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT BASTYPE
+ KOERCE SGROUP MONOID LMODULE SINT NNI INT LIST ILIST LSAGG
+ STAGG ALGEBRA MODULE BMODULE RMODULE INS UFD GCDDOM INTDOM
+ COMRING ENTIRER EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON
+ OAMON OASGRP ORDSET DIFRING KONVERT RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP
+sttf (14)STTF ALGEBRA RING RNG ABELGRP CABMON ABELMON ABELSG SETCAT
+ BASTYPE KOERCE SGROUP MONOID LMODULE MODULE BMODULE RMODULE
+ TRANFUN TRIGCAT ATRIG HYPCAT AHYP ELEMFUN STRING CHAR SINT
+ OUTFORM LIST INT PRIMARR A1AGG ISTRING ILIST LSAGG STAGG
+ ELAGG FLAGG URAGG INS UFD GCDDOM INTDOM COMRING ENTIRER
+ EUCDOM PID OINTDOM ORDRING OAGROUP OCAMON OAMON OASGP ORDSET
+ DIFRING KONVERT RETRACT LINEXP PATMAB CFCA REAL CHARZ STEP
+ NNI PI
+newpoint (14) SUBSPACE SETCAT BASTYPE KOERCE RING RNG ABELGRP CABMON ABELMON ABELSG
+ SGROUP MONOID LMODULE INT LIST ILIST LSAGG STAGG ELAGG FLAGG
+ URAGG LNAGG RCAGG IXAGG CLAGG HOAGG ORDSET AGG ELTAGG NNI
+ BOOLEAN PI STRING CHAR SINT OUTFORM PRIMARR A1AGG ISTRING
+ TYPE EVALAB IEVALAB ELTAB KONVERT OM
+symbol SYMBOL (ORDSET SETCAT BASTYPE KOERCE KONVERT OM PATMAB INS) UFD
+catdef UFD GCDDOM
+view2d 14 VIEW2D SETCAT BASTYPE KOERCE DFLOAT INT BOOLEAN PI NNI VECTCAT
+ A1AGG FLAGG LNAGG IXAGG HOAGG AGG TYPE EVALAB IEVALAB
+ ELTAGG ELTAB CLAGG KONVERT ORDSET VECTOR IVECTOR IARRAY1
+ LIST ILIST LSAGG STAGG SINT STRING CHAR OUTFORM PRIMARR
+ ISTRING INS UFD GCDDOM INTDOM COMRING RING RNG ABELGRP
+ CABMON ABELMON ABELSG SGROUP MONOID LMODULE BMODULE
+ RMODULE ALGEBRA MODULE ENTIRER EUCDOM PID OINTDOM ORDRING
+ OAGROUP OCAMON OAMON OAGSP DIFRING RETRACT LINEXP PATMAB
+ CFCAT REAL CHARZ STEP OM SRAGG STRICAT ELAGG FLAGG FPS
+ RNS FIELD DIVRING RADCAT
+
+ALAGG failed
+ALGMANIP INTDOM
+ALGPKG INTDOM
+ALGSC FRNAALG
+ALIST ALAGG
+APPRULE SETCAT
+ATTRBUT TBAGG
+
+BBTREE BTCAT
+BINARY QFCAT
+BOP1 SETCAT
+BPADICRT QFCAT
+BSTREE BTCAT
+BTCAT RCAGG
+BTOURN RCAGG
+BTREE RCAGG
+
+CCLASS SETCAT
+CLAGG HOAGG
+
+D01AGNT failed
+D01WGTS failed
+DBLRESP FIELD
+DECIMAL QFCAT
+DEFINTRF EUCDOM
+DFSFUN FPS
+DIFRING RING
+DMP POLYCAT
+
+
+ES ES
+ESTOOLS failed
+EXPEXPAN FIELD
+EXPR FS
+EXPRTUBE INS
+EXPUPXS FIELD
+
+FCPAK1 INS
+FC SETCAT
+FEXPR ES
+FFCGP XF
+FFCG XF
+FFCGX XF
+FFF FFIELDC
+FFHOM XF
+FFNBP XF
+FFNB XF
+FFNBX XF
+FFPOLY FPC
+FFP XF
+FF XF
+FFX XF
+FLOATCP PID
+FLOAT FPS
+FMTC INTDOM
+FORDER SETCAT
+FPARFRAC SETCAT
+FPS RNS
+FRAC QFCAT
+FRNAAF2 FRNAALG
+FRNAALG NAALG
+FR INTDOM
+FS2EXPXP PID
+FS2UPS GCDDOM
+FSINT PID
+FSPRMELT INTDOM
+FST SYMBOL
+FSUPFACT INTDOM
+FUNCTION SETCAT
+
+GALFACT UPOLYC
+GAUSSFAC INT
+generic GCNAALG FRNAALG
+GDMP POLYCAT
+GENUFACT PID
+GENUPS INTDOM
+GPOLSET PSETCAT
+GSERIES RING
+GTSET TSETCAT
+
+HACKPI PID
+HDMP POLYCAT
+HEXADEC QFCAT
+HOAGG SETCAT
+
+IDEAL SETCAT
+IDECOMP INS
+IFF XF
+ILIST LSAGG
+INBFF PID
+INEP PID
+INFORM1 SYMBOL
+INFORM SEXCAT
+INFPROD0 INTDOM
+INFSP INTDOM
+INMODGCD PID
+INPRODFF PID
+INPRODPF PID
+INTEF INTDOM
+INTG0 INTDOM
+INTHERAL PID
+INTPAF INTDOM
+INTSLPE INT
+INT INS
+INVLAPLA PID
+IPF PID
+IPRNTPK SYMBOL
+IR2F INTDOM
+IRRF2F INTDOM
+IR MODULE
+IRURPK PID
+ISTRING SRAGG
+ISUPS UPSCAT
+
+JORDAN NAALG
+
+KOVACIC RING
+
+LAPLACE PID
+LA RING
+LAUPOL RING
+LAZM3PK INTDOM
+LEXTRIPK INTDOM
+LIB TBAGG
+LIE NAALG
+LIMITPS INTDOM
+LINDEP INTDOM
+LMDICT MDAGG
+LODOOPS PID
+LODO LODOCAT
+LO MODULE
+LSQM SMATCAT
+p
+M3D SETCAT
+MATRIX SETCAT
+MCMPLX INTDOM
+MFLOAT RNS
+MKFLCFN SYMBOL
+mkfunc MKBCFUNC KONVERT TYPE
+MODMON UPOLYC
+MPOLY ORDFIN
+MRING RING
+MSET SETCAT
+MTSCAT ORDSET
+MULTFACT ORDSET
+
+NAGF01 SYMBOL
+NAGF02 SYMBOL
+NAGF04 SYMBOL
+NAGF07 SYMBOL
+NAGSP SYMBOL
+NAGS SYMBOL
+NCEP PID
+NLINSOL INTDOM
+NODE1 ORDSET
+NORMPK INTDOM
+NORMRETR PID
+NREP PID
+NSMP RPOLCAT
+NSUP UPOLYC
+NTSCAT RSETCAT
+NUMFMT STRING
+
+OCTCT2 OC
+OCT OC
+ODECONST ORDSET
+ODEEF ORDSET
+ODEINT ORDSET
+ODEPAL PID
+ODEPROB SETCAT
+ODERAT PID
+ODERTRIC PID
+ODR SETCAT
+OMERRK SETCAT
+OMERR SETCAT
+OMLO RING
+OPTPACK failed
+OSI SETCAT
+OUTFORM SETCAT
+OVAR SETCAT
+
+PADE PID
+PADICRAT QFCAT
+PADICRC QFCAT
+PAN2EXPR INS
+PATTERN SETCAT
+PDEPACK failed
+PENDTREE RCAGG
+PERMGRP SETCAT
+PERM MONOID
+PFOQ UPOLYC
+PFO SETCAT
+PF PID
+PICOERCE SETCAT
+PI SETCAT
+PLEQN INTDOM
+PMASSFS SETCAT
+PMFS SETCAT
+PMKERNEL SETCAT
+PMPREDFS SETCAT
+PMSYM SETCAT
+PNTHEORY failed
+POLY POLYCAT
+PRIMELT INTDOM
+PRIMES INS
+PSETPK INTDOM
+
+QALGSET2 SYMBOL
+QCMPACK INTDOM
+QUATCT2 QUATCAT
+QUAT QUATCAT
+
+RADIX QFCAT
+RCAGG SETCAT
+RCFIELD INS
+RDEEF INTDOM
+RDEEFS INTDOM
+RDIST SETCAT
+RDIV INTDOM
+RECLOS RCFIELD
+REGSET RSETCAT
+REP1 RING
+REP2 RING
+REP INS
+RESULT TBAGG
+RGCHAIN RSETCAT
+RMATRIX BMODULE
+RNS INS
+ROIRC RRCC
+ROMAN INS
+RPOLCAT POLYCAT
+RSDCMPK INTDOM
+RSETCAT INTDOM
+RSETGCD INTDOM
+RULECOLD SETCAT
+RULESET SETCAT
+RULE SETCAT
+RURPK INTDOM
+
+SAOS SETCAT
+SCPKG INTDOM
+SEGBIND SETCAT
+SETAGG SETCAT
+SETMN INT
+SET failed
+SFORT ES
+SFQCMPK INTDOM
+SFRGCD INTDOM
+SFRTCAT RSETCAT
+SGCF INT
+SIGNEF INTDOM
+SIMPAN INS
+SMP POLYCAT
+SNTSCAT RSETCAT
+SOLVERAD INTDOM
+SOLVESER INTDOM
+SOLVETRA INTDOM
+SPACE3 SPACEC
+SPECOUT SYMBOL
+SQMATRIX RING
+SRDCMPK INTDOM
+SREGSET RSETCAT
+STAGG URAGG
+STTFNC RING
+SULS RING
+SUP UPOLYC
+SUPXS RING
+SUTS RING
+SWITCH INT
+SYMS SYMBOL
+SYMTAB INS
+SYSSOLP INTDOM
+
+TOOLSIGN RING
+TRMANIP INTDOM
+TUBETOOL RNS
+TWOFACT INTDOM
+
+ULSCONS ULSCAT
+ULS RING
+UP UPOLYC
+UPXSCONS UPXSCAT
+UPXSSING INTDOM
+UPXS RING
+URAGG failed
+UTS2 RING
+UTSODE RING
+UTSODETL RING
+UTS RING
+
+VARIABLE SYMBOL
+VIEW3D NNI
+VOID STRING
+
+WUTSET TSETCAT
+
+
+
+ZDSOLVE failed
+
+\section{The Environment}
+\subsection{The working directories}
+We define 5 directories for this build. The {\bf IN} directory
+contains the pamphlet files for the algebra. These are expanded
+into the {\bf MID} directory as either .spad or .as files. The
+.spad files are compiled by the native spad internal compiler.
+The .as files are compiled using the Aldor compiler. The output
+of the compilation has two purposes. Part of the information is
+used to build various database files (daase files). The other
+part is executable code which is placed in the
+{\bf OUT} directory. When invoked as ``make document'' we
+construct the .dvi files in the {\bf DOC} directory.
+<<environment>>=
+IN=${SRC}/algebra
+MID=${INT}/algebra
+OUT=${MNT}/${SYS}/algebra
+DOC=${INT}/doc/int/algebra
+
+@
+\subsection{The depsys variable}
+The {\bf depsys} image is the compile-time environment for boot and lisp
+files.
+<<environment>>=
+DEPSYS=${OBJ}/${SYS}/bin/depsys
+
+@
+\subsection{The interpsys variable}
+The {\bf interpsys} image is the compile-time environment for algebra
+files.
+<<environment>>=
+INTERPSYS=${OBJ}/${SYS}/bin/interpsys
+
+@
+\subsection{The SPADFILES list}
+Note that we have excluded {\bf mlift.spad.jhd} from this list.
+We need to figure out which mlift.spad to keep.
+<<environment>>=
+SPADFILES= \
+ ${MID}/acplot.spad ${MID}/aggcat2.spad ${MID}/aggcat.spad \
+ ${MID}/algcat.spad ${MID}/algext.spad ${MID}/algfact.spad \
+ ${MID}/algfunc.spad ${MID}/allfact.spad ${MID}/alql.spad \
+ ${MID}/annacat.spad ${MID}/any.spad ${MID}/array1.spad \
+ ${MID}/array2.spad ${MID}/asp.spad ${MID}/attreg.spad \
+ ${MID}/bags.spad ${MID}/bezout.spad ${MID}/boolean.spad \
+ ${MID}/brill.spad \
+ ${MID}/c02.spad ${MID}/c05.spad ${MID}/c06.spad \
+ ${MID}/card.spad ${MID}/carten.spad ${MID}/catdef.spad \
+ ${MID}/cden.spad ${MID}/clifford.spad ${MID}/clip.spad \
+ ${MID}/cmplxrt.spad ${MID}/coerce.spad ${MID}/color.spad \
+ ${MID}/combfunc.spad ${MID}/combinat.spad ${MID}/complet.spad \
+ ${MID}/constant.spad ${MID}/contfrac.spad ${MID}/cont.spad \
+ ${MID}/coordsys.spad ${MID}/cra.spad ${MID}/crfp.spad \
+ ${MID}/curve.spad ${MID}/cycles.spad ${MID}/cyclotom.spad \
+ ${MID}/d01agents.spad ${MID}/d01Package.spad \
+ ${MID}/d01routine.spad ${MID}/d01.spad ${MID}/d01transform.spad \
+ ${MID}/d01weights.spad ${MID}/d02agents.spad \
+ ${MID}/d02Package.spad ${MID}/d02routine.spad ${MID}/d02.spad \
+ ${MID}/d03agents.spad ${MID}/d03Package.spad \
+ ${MID}/d03routine.spad ${MID}/d03.spad ${MID}/ddfact.spad \
+ ${MID}/defaults.spad ${MID}/defintef.spad ${MID}/defintrf.spad \
+ ${MID}/degred.spad ${MID}/derham.spad ${MID}/dhmatrix.spad \
+ ${MID}/divisor.spad ${MID}/dpolcat.spad ${MID}/drawopt.spad \
+ ${MID}/drawpak.spad ${MID}/draw.spad \
+ ${MID}/e01.spad ${MID}/e02.spad ${MID}/e04agents.spad \
+ ${MID}/e04Package.spad ${MID}/e04routine.spad ${MID}/e04.spad \
+ ${MID}/efstruc.spad ${MID}/efuls.spad ${MID}/efupxs.spad \
+ ${MID}/eigen.spad ${MID}/elemntry.spad ${MID}/elfuts.spad \
+ ${MID}/equation1.spad ${MID}/equation2.spad ${MID}/error.spad \
+ ${MID}/expexpan.spad ${MID}/exposed.lsp ${MID}/expr2ups.spad \
+ ${MID}/exprode.spad ${MID}/expr.spad \
+ ${MID}/f01.spad ${MID}/f02.spad ${MID}/f04.spad \
+ ${MID}/f07.spad ${MID}/facutil.spad ${MID}/ffcat.spad \
+ ${MID}/ffcg.spad ${MID}/fff.spad ${MID}/ffhom.spad \
+ ${MID}/ffnb.spad ${MID}/ffpoly2.spad ${MID}/ffpoly.spad \
+ ${MID}/ffp.spad ${MID}/ffx.spad \
+ ${MID}/files.spad ${MID}/float.spad ${MID}/fmod.spad \
+ ${MID}/fname.spad ${MID}/fnla.spad ${MID}/formula.spad \
+ ${MID}/fortcat.spad ${MID}/fortmac.spad ${MID}/fortpak.spad \
+ ${MID}/fortran.spad ${MID}/forttyp.spad ${MID}/fourier.spad \
+ ${MID}/fparfrac.spad ${MID}/fraction.spad ${MID}/free.spad \
+ ${MID}/fr.spad ${MID}/fs2expxp.spad ${MID}/fs2ups.spad \
+ ${MID}/fspace.spad ${MID}/funcpkgs.spad ${MID}/functions.spad \
+ ${MID}/galfact.spad ${MID}/galfactu.spad ${MID}/galpolyu.spad \
+ ${MID}/galutil.spad ${MID}/gaussfac.spad ${MID}/gaussian.spad \
+ ${MID}/gbeuclid.spad ${MID}/gbintern.spad ${MID}/gb.spad \
+ ${MID}/gdirprod.spad ${MID}/gdpoly.spad ${MID}/geneez.spad \
+ ${MID}/generic.spad ${MID}/genufact.spad ${MID}/genups.spad \
+ ${MID}/ghensel.spad ${MID}/gpgcd.spad ${MID}/gpol.spad \
+ ${MID}/grdef.spad ${MID}/groebf.spad ${MID}/groebsol.spad \
+ ${MID}/gseries.spad \
+ ${MID}/ideal.spad ${MID}/idecomp.spad ${MID}/indexedp.spad \
+ ${MID}/infprod.spad ${MID}/intaf.spad ${MID}/intalg.spad \
+ ${MID}/intaux.spad ${MID}/intclos.spad ${MID}/intef.spad \
+ ${MID}/integer.spad ${MID}/integrat.spad ${MID}/INTERP.EXPOSED \
+ ${MID}/interval.spad \
+ ${MID}/intfact.spad ${MID}/intpm.spad \
+ ${MID}/intrf.spad \
+ ${MID}/irexpand.spad \
+ ${MID}/irsn.spad ${MID}/ituple.spad \
+ ${MID}/kl.spad ${MID}/kovacic.spad \
+ ${MID}/laplace.spad ${MID}/laurent.spad ${MID}/leadcdet.spad \
+ ${MID}/lie.spad ${MID}/limitps.spad ${MID}/lindep.spad \
+ ${MID}/lingrob.spad ${MID}/liouv.spad ${MID}/listgcd.spad \
+ ${MID}/list.spad ${MID}/lmdict.spad ${MID}/lodof.spad \
+ ${MID}/lodop.spad ${MID}/lodo.spad \
+ ${MID}/manip.spad ${MID}/mappkg.spad ${MID}/matcat.spad \
+ ${MID}/matfuns.spad ${MID}/matrix.spad ${MID}/matstor.spad \
+ ${MID}/mesh.spad ${MID}/mfinfact.spad ${MID}/misc.spad \
+ ${MID}/mkfunc.spad ${MID}/mkrecord.spad \
+ ${MID}/mlift.spad ${MID}/moddfact.spad ${MID}/modgcd.spad \
+ ${MID}/modmonom.spad ${MID}/modmon.spad ${MID}/modring.spad \
+ ${MID}/moebius.spad ${MID}/mring.spad ${MID}/mset.spad \
+ ${MID}/mts.spad ${MID}/multfact.spad ${MID}/multpoly.spad \
+ ${MID}/multsqfr.spad \
+ ${MID}/naalgc.spad ${MID}/naalg.spad \
+ ${MID}/newdata.spad ${MID}/newpoint.spad \
+ ${MID}/newpoly.spad ${MID}/nlinsol.spad ${MID}/nlode.spad \
+ ${MID}/npcoef.spad \
+ ${MID}/nregset.spad \
+ ${MID}/nsregset.spad ${MID}/numeigen.spad ${MID}/numeric.spad \
+ ${MID}/numode.spad ${MID}/numquad.spad ${MID}/numsolve.spad \
+ ${MID}/numtheor.spad \
+ ${MID}/oct.spad ${MID}/odealg.spad ${MID}/odeef.spad \
+ ${MID}/oderf.spad ${MID}/omcat.spad ${MID}/omdev.spad \
+ ${MID}/omerror.spad ${MID}/omserver.spad ${MID}/opalg.spad \
+ ${MID}/openmath.spad ${MID}/op.spad ${MID}/ore.spad \
+ ${MID}/outform.spad ${MID}/out.spad \
+ ${MID}/pade.spad ${MID}/padiclib.spad ${MID}/padic.spad \
+ ${MID}/paramete.spad ${MID}/partperm.spad ${MID}/patmatch1.spad \
+ ${MID}/patmatch2.spad ${MID}/pattern.spad ${MID}/pcurve.spad \
+ ${MID}/pdecomp.spad ${MID}/perman.spad ${MID}/permgrps.spad \
+ ${MID}/perm.spad ${MID}/pfbr.spad ${MID}/pfo.spad \
+ ${MID}/pfr.spad ${MID}/pf.spad ${MID}/pgcd.spad \
+ ${MID}/pgrobner.spad ${MID}/pinterp.spad ${MID}/pleqn.spad \
+ ${MID}/plot3d.spad ${MID}/plot.spad ${MID}/plottool.spad \
+ ${MID}/polset.spad ${MID}/poltopol.spad ${MID}/polycat.spad \
+ ${MID}/poly.spad ${MID}/primelt.spad ${MID}/print.spad \
+ ${MID}/product.spad ${MID}/prs.spad ${MID}/prtition.spad \
+ ${MID}/pscat.spad ${MID}/pseudolin.spad ${MID}/ptranfn.spad \
+ ${MID}/puiseux.spad \
+ ${MID}/qalgset.spad ${MID}/quat.spad \
+ ${MID}/radeigen.spad ${MID}/radix.spad ${MID}/random.spad \
+ ${MID}/ratfact.spad ${MID}/rdeef.spad ${MID}/rderf.spad \
+ ${MID}/rdesys.spad ${MID}/real0q.spad ${MID}/realzero.spad \
+ ${MID}/reclos.spad ${MID}/regset.spad ${MID}/rep1.spad \
+ ${MID}/rep2.spad ${MID}/resring.spad ${MID}/retract.spad \
+ ${MID}/rf.spad ${MID}/riccati.spad ${MID}/routines.spad \
+ ${MID}/rule.spad \
+ ${MID}/seg.spad ${MID}/setorder.spad ${MID}/sets.spad \
+ ${MID}/sex.spad ${MID}/sf.spad ${MID}/sgcf.spad \
+ ${MID}/sign.spad ${MID}/si.spad ${MID}/smith.spad \
+ ${MID}/solvedio.spad ${MID}/solvefor.spad ${MID}/solvelin.spad \
+ ${MID}/solverad.spad ${MID}/sortpak.spad ${MID}/space.spad \
+ ${MID}/special.spad ${MID}/sregset.spad ${MID}/s.spad \
+ ${MID}/stream.spad ${MID}/string.spad ${MID}/sttaylor.spad \
+ ${MID}/sttf.spad ${MID}/sturm.spad ${MID}/suchthat.spad \
+ ${MID}/suls.spad ${MID}/sum.spad ${MID}/sups.spad \
+ ${MID}/supxs.spad ${MID}/suts.spad ${MID}/symbol.spad \
+ ${MID}/syssolp.spad ${MID}/system.spad \
+ ${MID}/tableau.spad ${MID}/table.spad ${MID}/taylor.spad \
+ ${MID}/tex.spad ${MID}/tools.spad ${MID}/transsolve.spad \
+ ${MID}/tree.spad ${MID}/trigcat.spad ${MID}/triset.spad \
+ ${MID}/tube.spad ${MID}/twofact.spad \
+ ${MID}/unifact.spad ${MID}/updecomp.spad ${MID}/updivp.spad \
+ ${MID}/utsode.spad \
+ ${MID}/variable.spad ${MID}/vector.spad ${MID}/view2D.spad \
+ ${MID}/view3D.spad ${MID}/viewDef.spad ${MID}/viewpack.spad \
+ ${MID}/void.spad \
+ ${MID}/weier.spad ${MID}/wtpol.spad \
+ ${MID}/xlpoly.spad ${MID}/xpoly.spad \
+ ${MID}/ystream.spad \
+ ${MID}/zerodim.spad
+
+@
+\subsection{The ALDORFILES list}
+<<environment>>=
+ALDORFILES= \
+ ${MID}/axtimer.as \
+ ${MID}/ffrac.as \
+ ${MID}/herm.as \
+ ${MID}/interval.as \
+ ${MID}/invnode.as ${MID}/invrender.as \
+ ${MID}/invtypes.as ${MID}/invutils.as \
+ ${MID}/iviews.as \
+ ${MID}/ndftip.as \
+ ${MID}/nepip.as \
+ ${MID}/noptip.as ${MID}/nqip.as \
+ ${MID}/nrc.as ${MID}/nsfip.as
+
+@
+\subsection{The DOCFILES list}
+<<environment>>=
+DOCFILES= \
+ ${DOC}/acplot.spad.dvi ${DOC}/aggcat2.spad.dvi ${DOC}/aggcat.spad.dvi \
+ ${DOC}/algcat.spad.dvi ${DOC}/algext.spad.dvi ${DOC}/algfact.spad.dvi \
+ ${DOC}/algfunc.spad.dvi ${DOC}/allfact.spad.dvi ${DOC}/alql.spad.dvi \
+ ${DOC}/annacat.spad.dvi ${DOC}/any.spad.dvi ${DOC}/array1.spad.dvi \
+ ${DOC}/array2.spad.dvi ${DOC}/asp.spad.dvi ${DOC}/attreg.spad.dvi \
+ ${DOC}/axtimer.as.dvi \
+ ${DOC}/bags.spad.dvi ${DOC}/bezout.spad.dvi ${DOC}/boolean.spad.dvi \
+ ${DOC}/brill.spad.dvi \
+ ${DOC}/c02.spad.dvi ${DOC}/c05.spad.dvi ${DOC}/c06.spad.dvi \
+ ${DOC}/card.spad.dvi ${DOC}/carten.spad.dvi ${DOC}/catdef.spad.dvi \
+ ${DOC}/cden.spad.dvi ${DOC}/clifford.spad.dvi ${DOC}/clip.spad.dvi \
+ ${DOC}/cmplxrt.spad.dvi ${DOC}/coerce.spad.dvi ${DOC}/color.spad.dvi \
+ ${DOC}/combfunc.spad.dvi ${DOC}/combinat.spad.dvi ${DOC}/complet.spad.dvi \
+ ${DOC}/constant.spad.dvi ${DOC}/contfrac.spad.dvi ${DOC}/cont.spad.dvi \
+ ${DOC}/coordsys.spad.dvi ${DOC}/cra.spad.dvi ${DOC}/crfp.spad.dvi \
+ ${DOC}/curve.spad.dvi ${DOC}/cycles.spad.dvi ${DOC}/cyclotom.spad.dvi \
+ ${DOC}/d01agents.spad.dvi ${DOC}/d01Package.spad.dvi \
+ ${DOC}/d01routine.spad.dvi ${DOC}/d01.spad.dvi ${DOC}/d01transform.spad.dvi \
+ ${DOC}/d01weights.spad.dvi ${DOC}/d02agents.spad.dvi \
+ ${DOC}/d02Package.spad.dvi ${DOC}/d02routine.spad.dvi ${DOC}/d02.spad.dvi \
+ ${DOC}/d03agents.spad.dvi ${DOC}/d03Package.spad.dvi \
+ ${DOC}/d03routine.spad.dvi ${DOC}/d03.spad.dvi ${DOC}/ddfact.spad.dvi \
+ ${DOC}/defaults.spad.dvi ${DOC}/defintef.spad.dvi ${DOC}/defintrf.spad.dvi \
+ ${DOC}/degred.spad.dvi ${DOC}/derham.spad.dvi ${DOC}/dhmatrix.spad.dvi \
+ ${DOC}/divisor.spad.dvi ${DOC}/dpolcat.spad.dvi ${DOC}/drawopt.spad.dvi \
+ ${DOC}/drawpak.spad.dvi ${DOC}/draw.spad.dvi \
+ ${DOC}/e01.spad.dvi ${DOC}/e02.spad.dvi ${DOC}/e04agents.spad.dvi \
+ ${DOC}/e04Package.spad.dvi ${DOC}/e04routine.spad.dvi ${DOC}/e04.spad.dvi \
+ ${DOC}/efstruc.spad.dvi ${DOC}/efuls.spad.dvi ${DOC}/efupxs.spad.dvi \
+ ${DOC}/eigen.spad.dvi ${DOC}/elemntry.spad.dvi ${DOC}/elfuts.spad.dvi \
+ ${DOC}/equation1.spad.dvi ${DOC}/equation2.spad.dvi ${DOC}/error.spad.dvi \
+ ${DOC}/expexpan.spad.dvi ${DOC}/exposed.lsp.dvi ${DOC}/expr2ups.spad.dvi \
+ ${DOC}/exprode.spad.dvi ${DOC}/expr.spad.dvi \
+ ${DOC}/f01.spad.dvi ${DOC}/f02.spad.dvi ${DOC}/f04.spad.dvi \
+ ${DOC}/f07.spad.dvi ${DOC}/facutil.spad.dvi ${DOC}/ffcat.spad.dvi \
+ ${DOC}/ffcg.spad.dvi ${DOC}/fff.spad.dvi ${DOC}/ffhom.spad.dvi \
+ ${DOC}/ffnb.spad.dvi ${DOC}/ffpoly2.spad.dvi ${DOC}/ffpoly.spad.dvi \
+ ${DOC}/ffp.spad.dvi ${DOC}/ffrac.as.dvi ${DOC}/ffx.spad.dvi \
+ ${DOC}/files.spad.dvi ${DOC}/float.spad.dvi ${DOC}/fmod.spad.dvi \
+ ${DOC}/fname.spad.dvi ${DOC}/fnla.spad.dvi ${DOC}/formula.spad.dvi \
+ ${DOC}/fortcat.spad.dvi ${DOC}/fortmac.spad.dvi ${DOC}/fortpak.spad.dvi \
+ ${DOC}/fortran.spad.dvi ${DOC}/forttyp.spad.dvi ${DOC}/fourier.spad.dvi \
+ ${DOC}/fparfrac.spad.dvi ${DOC}/fraction.spad.dvi ${DOC}/free.spad.dvi \
+ ${DOC}/fr.spad.dvi ${DOC}/fs2expxp.spad.dvi ${DOC}/fs2ups.spad.dvi \
+ ${DOC}/fspace.spad.dvi ${DOC}/funcpkgs.spad.dvi ${DOC}/functions.spad.dvi \
+ ${DOC}/galfact.spad.dvi ${DOC}/galfactu.spad.dvi ${DOC}/galpolyu.spad.dvi \
+ ${DOC}/galutil.spad.dvi ${DOC}/gaussfac.spad.dvi ${DOC}/gaussian.spad.dvi \
+ ${DOC}/gbeuclid.spad.dvi ${DOC}/gbintern.spad.dvi ${DOC}/gb.spad.dvi \
+ ${DOC}/gdirprod.spad.dvi ${DOC}/gdpoly.spad.dvi ${DOC}/geneez.spad.dvi \
+ ${DOC}/generic.spad.dvi ${DOC}/genufact.spad.dvi ${DOC}/genups.spad.dvi \
+ ${DOC}/ghensel.spad.dvi ${DOC}/gpgcd.spad.dvi ${DOC}/gpol.spad.dvi \
+ ${DOC}/grdef.spad.dvi ${DOC}/groebf.spad.dvi ${DOC}/groebsol.spad.dvi \
+ ${DOC}/gseries.spad.dvi \
+ ${DOC}/herm.as.dvi \
+ ${DOC}/ideal.spad.dvi ${DOC}/idecomp.spad.dvi ${DOC}/indexedp.spad.dvi \
+ ${DOC}/infprod.spad.dvi ${DOC}/intaf.spad.dvi ${DOC}/intalg.spad.dvi \
+ ${DOC}/intaux.spad.dvi ${DOC}/intclos.spad.dvi ${DOC}/intef.spad.dvi \
+ ${DOC}/integer.spad.dvi ${DOC}/integrat.spad.dvi ${DOC}/INTERP.EXPOSED.dvi \
+ ${DOC}/interval.as.dvi ${DOC}/interval.spad.div \
+ ${DOC}/intfact.spad.dvi ${DOC}/intpm.spad.dvi \
+ ${DOC}/intrf.spad.dvi ${DOC}/invnode.as.dvi ${DOC}/invrender.as.dvi \
+ ${DOC}/invtypes.as.dvi ${DOC}/invutils.as.dvi ${DOC}/irexpand.spad.dvi \
+ ${DOC}/irsn.spad.dvi ${DOC}/ituple.spad.dvi ${DOC}/iviews.as.dvi \
+ ${DOC}/kl.spad.dvi ${DOC}/kovacic.spad.dvi \
+ ${DOC}/laplace.spad.dvi ${DOC}/laurent.spad.dvi ${DOC}/leadcdet.spad.dvi \
+ ${DOC}/lie.spad.dvi ${DOC}/limitps.spad.dvi ${DOC}/lindep.spad.dvi \
+ ${DOC}/lingrob.spad.dvi ${DOC}/liouv.spad.dvi ${DOC}/listgcd.spad.dvi \
+ ${DOC}/list.spad.dvi ${DOC}/lmdict.spad.dvi ${DOC}/lodof.spad.dvi \
+ ${DOC}/lodop.spad.dvi ${DOC}/lodo.spad.dvi \
+ ${DOC}/manip.spad.dvi ${DOC}/mappkg.spad.dvi ${DOC}/matcat.spad.dvi \
+ ${DOC}/matfuns.spad.dvi ${DOC}/matrix.spad.dvi ${DOC}/matstor.spad.dvi \
+ ${DOC}/mesh.spad.dvi ${DOC}/mfinfact.spad.dvi ${DOC}/misc.spad.dvi \
+ ${DOC}/mkfunc.spad.dvi ${DOC}/mkrecord.spad.dvi ${DOC}/mlift.spad.jhd.dvi \
+ ${DOC}/mlift.spad.dvi ${DOC}/moddfact.spad.dvi ${DOC}/modgcd.spad.dvi \
+ ${DOC}/modmonom.spad.dvi ${DOC}/modmon.spad.dvi ${DOC}/modring.spad.dvi \
+ ${DOC}/moebius.spad.dvi ${DOC}/mring.spad.dvi ${DOC}/mset.spad.dvi \
+ ${DOC}/mts.spad.dvi ${DOC}/multfact.spad.dvi ${DOC}/multpoly.spad.dvi \
+ ${DOC}/multsqfr.spad.dvi \
+ ${DOC}/naalgc.spad.dvi ${DOC}/naalg.spad.dvi ${DOC}/ndftip.as.dvi \
+ ${DOC}/nepip.as.dvi ${DOC}/newdata.spad.dvi ${DOC}/newpoint.spad.dvi \
+ ${DOC}/newpoly.spad.dvi ${DOC}/nlinsol.spad.dvi ${DOC}/nlode.spad.dvi \
+ ${DOC}/noptip.as.dvi ${DOC}/npcoef.spad.dvi ${DOC}/nqip.as.dvi \
+ ${DOC}/nrc.as.dvi ${DOC}/nregset.spad.dvi ${DOC}/nsfip.as.dvi \
+ ${DOC}/nsregset.spad.dvi ${DOC}/numeigen.spad.dvi ${DOC}/numeric.spad.dvi \
+ ${DOC}/numode.spad.dvi ${DOC}/numquad.spad.dvi ${DOC}/numsolve.spad.dvi \
+ ${DOC}/numtheor.spad.dvi \
+ ${DOC}/oct.spad.dvi ${DOC}/odealg.spad.dvi ${DOC}/odeef.spad.dvi \
+ ${DOC}/oderf.spad.dvi ${DOC}/omcat.spad.dvi ${DOC}/omdev.spad.dvi \
+ ${DOC}/omerror.spad.dvi ${DOC}/omserver.spad.dvi ${DOC}/opalg.spad.dvi \
+ ${DOC}/openmath.spad.dvi ${DOC}/op.spad.dvi ${DOC}/ore.spad.dvi \
+ ${DOC}/outform.spad.dvi ${DOC}/out.spad.dvi \
+ ${DOC}/pade.spad.dvi ${DOC}/padiclib.spad.dvi ${DOC}/padic.spad.dvi \
+ ${DOC}/paramete.spad.dvi ${DOC}/partperm.spad.dvi ${DOC}/patmatch1.spad.dvi \
+ ${DOC}/patmatch2.spad.dvi ${DOC}/pattern.spad.dvi ${DOC}/pcurve.spad.dvi \
+ ${DOC}/pdecomp.spad.dvi ${DOC}/perman.spad.dvi ${DOC}/permgrps.spad.dvi \
+ ${DOC}/perm.spad.dvi ${DOC}/pfbr.spad.dvi ${DOC}/pfo.spad.dvi \
+ ${DOC}/pfr.spad.dvi ${DOC}/pf.spad.dvi ${DOC}/pgcd.spad.dvi \
+ ${DOC}/pgrobner.spad.dvi ${DOC}/pinterp.spad.dvi ${DOC}/pleqn.spad.dvi \
+ ${DOC}/plot3d.spad.dvi ${DOC}/plot.spad.dvi ${DOC}/plottool.spad.dvi \
+ ${DOC}/polset.spad.dvi ${DOC}/poltopol.spad.dvi ${DOC}/polycat.spad.dvi \
+ ${DOC}/poly.spad.dvi ${DOC}/primelt.spad.dvi ${DOC}/print.spad.dvi \
+ ${DOC}/product.spad.dvi ${DOC}/prs.spad.dvi ${DOC}/prtition.spad.dvi \
+ ${DOC}/pscat.spad.dvi ${DOC}/pseudolin.spad.dvi ${DOC}/ptranfn.spad.dvi \
+ ${DOC}/puiseux.spad.dvi \
+ ${DOC}/qalgset.spad.dvi ${DOC}/quat.spad.dvi \
+ ${DOC}/radeigen.spad.dvi ${DOC}/radix.spad.dvi ${DOC}/random.spad.dvi \
+ ${DOC}/ratfact.spad.dvi ${DOC}/rdeef.spad.dvi ${DOC}/rderf.spad.dvi \
+ ${DOC}/rdesys.spad.dvi ${DOC}/real0q.spad.dvi ${DOC}/realzero.spad.dvi \
+ ${DOC}/reclos.spad.dvi ${DOC}/regset.spad.dvi ${DOC}/rep1.spad.dvi \
+ ${DOC}/rep2.spad.dvi ${DOC}/resring.spad.dvi ${DOC}/retract.spad.dvi \
+ ${DOC}/rf.spad.dvi ${DOC}/riccati.spad.dvi ${DOC}/routines.spad.dvi \
+ ${DOC}/rule.spad.dvi \
+ ${DOC}/seg.spad.dvi ${DOC}/setorder.spad.dvi ${DOC}/sets.spad.dvi \
+ ${DOC}/sex.spad.dvi ${DOC}/sf.spad.dvi ${DOC}/sgcf.spad.dvi \
+ ${DOC}/sign.spad.dvi ${DOC}/si.spad.dvi ${DOC}/smith.spad.dvi \
+ ${DOC}/solvedio.spad.dvi ${DOC}/solvefor.spad.dvi ${DOC}/solvelin.spad.dvi \
+ ${DOC}/solverad.spad.dvi ${DOC}/sortpak.spad.dvi ${DOC}/space.spad.dvi \
+ ${DOC}/special.spad.dvi ${DOC}/sregset.spad.dvi ${DOC}/s.spad.dvi \
+ ${DOC}/stream.spad.dvi ${DOC}/string.spad.dvi ${DOC}/sttaylor.spad.dvi \
+ ${DOC}/sttf.spad.dvi ${DOC}/sturm.spad.dvi ${DOC}/suchthat.spad.dvi \
+ ${DOC}/suls.spad.dvi ${DOC}/sum.spad.dvi ${DOC}/sups.spad.dvi \
+ ${DOC}/supxs.spad.dvi ${DOC}/suts.spad.dvi ${DOC}/symbol.spad.dvi \
+ ${DOC}/syssolp.spad.dvi ${DOC}/system.spad.dvi \
+ ${DOC}/tableau.spad.dvi ${DOC}/table.spad.dvi ${DOC}/taylor.spad.dvi \
+ ${DOC}/tex.spad.dvi ${DOC}/tools.spad.dvi ${DOC}/transsolve.spad.dvi \
+ ${DOC}/tree.spad.dvi ${DOC}/trigcat.spad.dvi ${DOC}/triset.spad.dvi \
+ ${DOC}/tube.spad.dvi ${DOC}/twofact.spad.dvi \
+ ${DOC}/unifact.spad.dvi ${DOC}/updecomp.spad.dvi ${DOC}/updivp.spad.dvi \
+ ${DOC}/utsode.spad.dvi \
+ ${DOC}/variable.spad.dvi ${DOC}/vector.spad.dvi ${DOC}/view2D.spad.dvi \
+ ${DOC}/view3D.spad.dvi ${DOC}/viewDef.spad.dvi ${DOC}/viewpack.spad.dvi \
+ ${DOC}/void.spad.dvi \
+ ${DOC}/weier.spad.dvi ${DOC}/wtpol.spad.dvi \
+ ${DOC}/xlpoly.spad.dvi ${DOC}/xpoly.spad.dvi \
+ ${DOC}/ystream.spad.dvi \
+ ${DOC}/zerodim.spad.dvi
+
+@
+\section{The Makefile Stanzas}
+Subsections within this section are organized by the [[spad]] pamphlet.
+A [[spad]] pamphlet can contain many Axiom [[categories]], [[domains]], and
+[[packages]].
+
+For the purpose of explanation we assume that the pamphlet file is
+named [[foo.spad.pamphlet]]. It contains the domains [[BAR]], [[BAX]],
+and [[BAZ]]. Thus there will be a subsection named [[foo.spad]].
+
+Since pamphlet files (e.g. [[foo.spad.pamphlet]] contain a spad file
+(e.g. [[foo.spad]]) it follows that
+every subsection contains a Makefile stanza that extract the [[foo.spad]]
+file using [[notangle]].
+
+Since pamphlet files are intended as documents it follows that each
+subsection contains a Makefile stanza that extracts a [[dvi]] file
+using [[noweave]].
+
+For each domain in [[foo.spad]] we will have either 3, 5, or 9
+Makefile stanzas related to that domain. Note that the items in each
+stanzas are actually explained in reverse order from the way they are
+listed in the code. Since Makefiles are rule based programs the order
+does not matter. The reason the stanzas are listed in what appears to
+be reverse order is that we are following a ``pull'' model of rule
+based programming. We specify the end-state desired (the final [[.o]]
+file in the algebra directory) and backward-derive rules that achieve
+that state. Thus you can read the Makefile stanzas starting with the
+final state and deriving the previous required state. If this doesn't
+make sense to you and you don't understand the ``pull'' model of
+rule based programming don't worry about it. Just be aware that they
+are listed in a logical order and that [[make]] doesn't care.
+
+A 3 stanza group exists for the normal code case. The stanzas perform
+the functions:
+\begin{enumerate}
+\item extract the domain [[BAR.spad]] from the spad file [[foo.spad]]
+\item compile the extracted [[BAR.spad]] domain
+\item copy the compiled [[BAR.o]] file to the final algebra directory
+\end{enumerate}
+
+Once we go beyond the normal case we have a few things that vary.
+
+First, we could have a category that has default implementation code.
+Compiling this category will generate files with a trailing [[-]] sign.
+So, for instances, you'll see [[BAR]] and [[BAR-]] code generated when
+compiling [[BAR.spad]]. This is the first cause of a 5 stanza group.
+
+A 5 stanza group for this case performs the following functions:
+\begin{enumerate}
+\item extract the domain [[BAR]] from the spad file [[foo.spad]]
+\item compile the extracted [[BAR]] domain
+\item copy the compiled [[BAR.o]] to the final algebra directory
+\item compile the extracted [[BAR]] domain (to get [[BAR-.o]])
+\item copy the compiled [[BAR-.o]] to the final algebra directory
+\end{enumerate}
+
+Notice the subtle point of step four above. In order to get the
+[[BAR-.o]] file we need to compile [[BAR]]. Step four will only
+happen if the [[BAR-.o]] file gets erased and the [[BAR.o]] file
+still exists. It is skipped during a normal build. It is required,
+however, to cover the case where there are lost files in the
+intermediate directory ([[BAR-.o]]) that represent a partial
+build. Step four will recover from that case.
+
+The second reason for a 5 stanza group is that
+we could have a category, domain, or package that is in
+the ``bootstrap'' list. Bootstrap spad files contain their generated
+lisp code in special sections. The way bootstrapping works is that
+we extract the lisp code and compile it rather than extracting the
+spad code. We do this because we need the domain to exist before we
+can compile the domain. Some domains depend on themselves directly.
+Some domains depend on themselves thru a long chain of other domains.
+In either case we can't compile the domain until it exists so we
+cache the generated lisp code and, when we need to bootstrap the
+domain, we compile the raw lisp rather than the spad.
+
+This will only happen when the system is built from scratch. Once
+the system has been built the bootstrap code is no longer executed
+and these algebra files will appear as normal algebra files. That
+means that once the system has been built once only the last three
+rules will ever be executed. The first two rules happen when the
+system is built from scratch.
+
+A 5 stanza group for this case performs the following functions:
+\begin{enumerate}
+\item extract the lisp [[BAR.lsp]] from the pamphlet [[foo.spad.pamphlet]]
+\item compile and copy the bootstrap lisp to the final algebra directory
+\item extract the bootstrap [[BAR.lsp]] from the spad file [[foo.spad]]
+\item compile the extracted [[BAR]] domain
+\item copy the compiled [[BAR]] to the final algebra directory
+\end{enumerate}
+
+The subtle point here occurs in the first item. The bootstrap code
+group (in the [[layer0 bootstrap]] code chunk above) asks for the
+compiled [[.o]] files in the [[${MID}]] directory. Essentially this
+code group calls for intermediate compiled files. This triggers the
+bootstrap stanzas (items 1 and 2 above). All of the other layer
+chunks ask for compiled code in the [[${OUT}]] directory which is
+the final algebra directory.
+
+The bootstrap process works because first we ask for the compiled
+lisp code stanzas (the [[${MID}/BAR.o]] files), THEN we ask for
+the final algebra code stanzas (the [[${OUT}/BAR.o]] files). This
+is a very subtle point so think it through carefully. The layer0
+bootstrap list is the only file list that calls for [[${MID}]]
+files. All other layers ask for [[${OUT}]] files. Make sure you
+understand this before you change things. If you break it the
+world will no longer compile.
+
+So we have a 3 stanza group for normal files, a 3+2 (5) stanza
+group for normal files with default code, and a 3+2 (5) stanza
+group for normal files that need to be bootstrapped. There is
+another combination that occurs, namely bootstrap code that
+also contains default code which gives a 3+2+2+2 (9) stanza case.
+(see TSETCAT for an example. Be sure to read the items in reverse order).
+
+A 9 stanza group for this case performs the following functions:
+\begin{enumerate}
+\item extract the bootstrap [[BAR.lsp]] from the [[foo.spad.pamphlet]]
+\item compile the bootstrap [[BAR.lsp]] and copy to the intermediate directory
+\item extract the bootstrap [[BAR-.lsp]] from the [[foo.spad.pamphlet]]
+\item compile the bootstrap [[BAR-.lsp]] and copy to intermediate directory
+\item extract the spad [[BAR.spad]] from the pamphlet [[foo.spad.pamphlet]]
+\item compile the extracted [[BAR.spad]] domain (to get [[BAR.o]])
+\item copy the [[BAR.o]] to the final algebra directory
+\item compile the extracted [[BAR.spad]] domain (to get [[BAR-.o]])
+\item copy the [[BAR-.o]] to the final algebra directory
+\end{enumerate}
+
+As you can see this is just the combination of the two possible 5
+stanza case. We just have to deal with the [[BAR-]] both in regular
+and bootstrap files. The first four stanzas will only happen when
+the system is built from scratch. Once the system is built these
+four rules no longer apply and these stanzas effectively act like
+the 5 stanza rules above.
+
+I'm sure all of this seems confusing but it is very stylized code.
+Basically you need to figure out which kind of stanza group you need,
+copy an existing stanza group, and do a correct renaming of the parts.
+The decision tree looks something like:
+\begin{verbatim}
+IF (you have a regular spad domain)
+ THEN use a 3 stanza form (see YSTREAM)
+IF (you have a default spad domain (it generates [[-]] files)) AND
+ (it does not require bootstrapping)
+ THEN use the first 5 stanza form explained above (see LIECAT)
+IF (you have a normal spad domain) AND
+ (it requires bootstrapping)
+ THEN use the second 5 stanza form explained above (see VECTOR)
+IF (you have a default spad domain (it generates [[-]] files)) AND
+ (it requires bootstrapping)
+ THEN use the 9 stanza form explained above (see TSETCAT)
+\end{verbatim}
+
+
+\subsection{acplot.spad \cite{1}}
+<<acplot.spad (SPAD from IN)>>=
+${MID}/acplot.spad: ${IN}/acplot.spad.pamphlet
+ @ echo 0 making ${MID}/acplot.spad from ${IN}/acplot.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/acplot.spad.pamphlet >acplot.spad )
+
+@
+<<ACPLOT.o (O from NRLIB)>>=
+${OUT}/ACPLOT.o: ${MID}/ACPLOT.NRLIB
+ @ echo 0 making ${OUT}/ACPLOT.o from ${MID}/ACPLOT.NRLIB
+ @ cp ${MID}/ACPLOT.NRLIB/code.o ${OUT}/ACPLOT.o
+
+@
+<<ACPLOT.NRLIB (NRLIB from MID)>>=
+${MID}/ACPLOT.NRLIB: ${MID}/ACPLOT.spad
+ @ echo 0 making ${MID}/ACPLOT.NRLIB from ${MID}/ACPLOT.spad
+ @ (cd ${MID} ; echo ')co ACPLOT.spad' | ${INTERPSYS} )
+
+@
+<<ACPLOT.spad (SPAD from IN)>>=
+${MID}/ACPLOT.spad: ${IN}/acplot.spad.pamphlet
+ @ echo 0 making ${MID}/ACPLOT.spad from ${IN}/acplot.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ACPLOT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ACPLOT PlaneAlgebraicCurvePlot" ${IN}/acplot.spad.pamphlet >ACPLOT.spad )
+
+@
+<<REALSOLV.o (O from NRLIB)>>=
+${OUT}/REALSOLV.o: ${MID}/REALSOLV.NRLIB
+ @ echo 0 making ${OUT}/REALSOLV.o from ${MID}/REALSOLV.NRLIB
+ @ cp ${MID}/REALSOLV.NRLIB/code.o ${OUT}/REALSOLV.o
+
+@
+<<REALSOLV.NRLIB (NRLIB from MID)>>=
+${MID}/REALSOLV.NRLIB: ${MID}/REALSOLV.spad
+ @ echo 0 making ${MID}/REALSOLV.NRLIB from ${MID}/REALSOLV.spad
+ @ (cd ${MID} ; echo ')co REALSOLV.spad' | ${INTERPSYS} )
+
+@
+<<REALSOLV.spad (SPAD from IN)>>=
+${MID}/REALSOLV.spad: ${IN}/acplot.spad.pamphlet
+ @ echo 0 making ${MID}/REALSOLV.spad from ${IN}/acplot.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REALSOLV.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REALSOLV RealSolvePackage" ${IN}/acplot.spad.pamphlet >REALSOLV.spad )
+
+@
+<<acplot.spad.dvi (DOC from IN)>>=
+${DOC}/acplot.spad.dvi: ${IN}/acplot.spad.pamphlet
+ @ echo 0 making ${DOC}/acplot.spad.dvi from ${IN}/acplot.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/acplot.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} acplot.spad ; \
+ rm -f ${DOC}/acplot.spad.pamphlet ; \
+ rm -f ${DOC}/acplot.spad.tex ; \
+ rm -f ${DOC}/acplot.spad )
+
+@
+\subsection{aggcat2.spad \cite{1}}
+<<aggcat2.spad (SPAD from IN)>>=
+${MID}/aggcat2.spad: ${IN}/aggcat2.spad.pamphlet
+ @ echo 0 making ${MID}/aggcat2.spad from ${IN}/aggcat2.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/aggcat2.spad.pamphlet >aggcat2.spad )
+
+@
+<<FLAGG2.o (O from NRLIB)>>=
+${OUT}/FLAGG2.o: ${MID}/FLAGG2.NRLIB
+ @ echo 0 making ${OUT}/FLAGG2.o from ${MID}/FLAGG2.NRLIB
+ @ cp ${MID}/FLAGG2.NRLIB/code.o ${OUT}/FLAGG2.o
+
+@
+<<FLAGG2.NRLIB (NRLIB from MID)>>=
+${MID}/FLAGG2.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/FLAGG2.spad
+ @ echo 0 making ${MID}/FLAGG2.NRLIB from ${MID}/FLAGG2.spad
+ @ (cd ${MID} ; echo ')co FLAGG2.spad' | ${INTERPSYS} )
+
+@
+<<FLAGG2.spad (SPAD from IN)>>=
+${MID}/FLAGG2.spad: ${IN}/aggcat2.spad.pamphlet
+ @ echo 0 making ${MID}/FLAGG2.spad from ${IN}/aggcat2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLAGG2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FLAGG2 FiniteLinearAggregateFunctions2" ${IN}/aggcat2.spad.pamphlet >FLAGG2.spad )
+
+@
+<<FSAGG2.o (O from NRLIB)>>=
+${OUT}/FSAGG2.o: ${MID}/FSAGG2.NRLIB
+ @ echo 0 making ${OUT}/FSAGG2.o from ${MID}/FSAGG2.NRLIB
+ @ cp ${MID}/FSAGG2.NRLIB/code.o ${OUT}/FSAGG2.o
+
+@
+<<FSAGG2.NRLIB (NRLIB from MID)>>=
+${MID}/FSAGG2.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/FSAGG2.spad
+ @ echo 0 making ${MID}/FSAGG2.NRLIB from ${MID}/FSAGG2.spad
+ @ (cd ${MID} ; echo ')co FSAGG2.spad' | ${INTERPSYS} )
+
+@
+<<FSAGG2.spad (SPAD from IN)>>=
+${MID}/FSAGG2.spad: ${IN}/aggcat2.spad.pamphlet
+ @ echo 0 making ${MID}/FSAGG2.spad from ${IN}/aggcat2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSAGG2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSAGG2 FiniteSetAggregateFunctions2" ${IN}/aggcat2.spad.pamphlet >FSAGG2.spad )
+
+@
+<<aggcat2.spad.dvi (DOC from IN)>>=
+${DOC}/aggcat2.spad.dvi: ${IN}/aggcat2.spad.pamphlet
+ @ echo 0 making ${DOC}/aggcat2.spad.dvi from ${IN}/aggcat2.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/aggcat2.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} aggcat2.spad ; \
+ rm -f ${DOC}/aggcat2.spad.pamphlet ; \
+ rm -f ${DOC}/aggcat2.spad.tex ; \
+ rm -f ${DOC}/aggcat2.spad )
+
+@
+\subsection{aggcat.spad \cite{1}}
+<<aggcat.spad (SPAD from IN)>>=
+${MID}/aggcat.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/aggcat.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/aggcat.spad.pamphlet >aggcat.spad )
+
+@
+<<ALAGG.o (O from NRLIB)>>=
+${OUT}/ALAGG.o: ${MID}/ALAGG.NRLIB
+ @ echo 0 making ${OUT}/ALAGG.o from ${MID}/ALAGG.NRLIB
+ @ cp ${MID}/ALAGG.NRLIB/code.o ${OUT}/ALAGG.o
+
+@
+<<ALAGG.NRLIB (NRLIB from MID)>>=
+${MID}/ALAGG.NRLIB: ${MID}/ALAGG.spad
+ @ echo 0 making ${MID}/ALAGG.NRLIB from ${MID}/ALAGG.spad
+ @ (cd ${MID} ; echo ')co ALAGG.spad' | ${INTERPSYS} )
+
+@
+<<ALAGG.spad (SPAD from IN)>>=
+${MID}/ALAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/ALAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ALAGG AssociationListAggregate" ${IN}/aggcat.spad.pamphlet >ALAGG.spad )
+
+@
+<<ALAGG.o (BOOTSTRAP from MID)>>=
+${MID}/ALAGG.o: ${MID}/ALAGG.lsp
+ @ echo 0 making ${MID}/ALAGG.o from ${MID}/ALAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ALAGG.lsp" :output-file "ALAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ALAGG.o ${OUT}/ALAGG.o
+
+@
+<<ALAGG.lsp (LISP from IN)>>=
+${MID}/ALAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/ALAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALAGG.NRLIB ; \
+ rm -rf ${OUT}/ALAGG.o ; \
+ ${SPADBIN}/notangle -R"ALAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >ALAGG.lsp )
+
+@
+<<A1AGG-.o (O from NRLIB)>>=
+${OUT}/A1AGG-.o: ${MID}/A1AGG.NRLIB
+ @ echo 0 making ${OUT}/A1AGG-.o from ${MID}/A1AGG-.NRLIB
+ @ cp ${MID}/A1AGG-.NRLIB/code.o ${OUT}/A1AGG-.o
+
+@
+<<A1AGG-.NRLIB (NRLIB from MID)>>=
+${MID}/A1AGG-.NRLIB: ${OUT}/TYPE.o ${MID}/A1AGG.spad
+ @ echo 0 making ${MID}/A1AGG-.NRLIB from ${MID}/A1AGG.spad
+ @ (cd ${MID} ; echo ')co A1AGG.spad' | ${INTERPSYS} )
+
+@
+<<A1AGG.o (O from NRLIB)>>=
+${OUT}/A1AGG.o: ${MID}/A1AGG.NRLIB
+ @ echo 0 making ${OUT}/A1AGG.o from ${MID}/A1AGG.NRLIB
+ @ cp ${MID}/A1AGG.NRLIB/code.o ${OUT}/A1AGG.o
+
+@
+<<A1AGG.NRLIB (NRLIB from MID)>>=
+${MID}/A1AGG.NRLIB: ${MID}/A1AGG.spad
+ @ echo 0 making ${MID}/A1AGG.NRLIB from ${MID}/A1AGG.spad
+ @ (cd ${MID} ; echo ')co A1AGG.spad' | ${INTERPSYS} )
+
+@
+<<A1AGG.spad (SPAD from IN)>>=
+${MID}/A1AGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/A1AGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf A1AGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category A1AGG OneDimensionalArrayAggregate" ${IN}/aggcat.spad.pamphlet >A1AGG.spad )
+
+@
+<<AGG-.o (O from NRLIB)>>=
+${OUT}/AGG-.o: ${MID}/AGG.NRLIB
+ @ echo 0 making ${OUT}/AGG-.o from ${MID}/AGG-.NRLIB
+ @ cp ${MID}/AGG-.NRLIB/code.o ${OUT}/AGG-.o
+
+@
+<<AGG-.NRLIB (NRLIB from MID)>>=
+${MID}/AGG-.NRLIB: ${OUT}/TYPE.o ${MID}/AGG.spad
+ @ echo 0 making ${MID}/AGG-.NRLIB from ${MID}/AGG.spad
+ @ (cd ${MID} ; echo ')co AGG.spad' | ${INTERPSYS} )
+
+@
+<<AGG.o (O from NRLIB)>>=
+${OUT}/AGG.o: ${MID}/AGG.NRLIB
+ @ echo 0 making ${OUT}/AGG.o from ${MID}/AGG.NRLIB
+ @ cp ${MID}/AGG.NRLIB/code.o ${OUT}/AGG.o
+
+@
+<<AGG.NRLIB (NRLIB from MID)>>=
+${MID}/AGG.NRLIB: ${MID}/AGG.spad
+ @ echo 0 making ${MID}/AGG.NRLIB from ${MID}/AGG.spad
+ @ (cd ${MID} ; echo ')co AGG.spad' | ${INTERPSYS} )
+
+@
+<<AGG.spad (SPAD from IN)>>=
+${MID}/AGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/AGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf AGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category AGG Aggregate" ${IN}/aggcat.spad.pamphlet >AGG.spad )
+
+@
+<<BGAGG-.o (O from NRLIB)>>=
+${OUT}/BGAGG-.o: ${MID}/BGAGG.NRLIB
+ @ echo 0 making ${OUT}/BGAGG-.o from ${MID}/BGAGG-.NRLIB
+ @ cp ${MID}/BGAGG-.NRLIB/code.o ${OUT}/BGAGG-.o
+
+@
+<<BGAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/BGAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/BGAGG.spad
+ @ echo 0 making ${MID}/BGAGG-.NRLIB from ${MID}/BGAGG.spad
+ @ (cd ${MID} ; echo ')co BGAGG.spad' | ${INTERPSYS} )
+
+@
+<<BGAGG.o (O from NRLIB)>>=
+${OUT}/BGAGG.o: ${MID}/BGAGG.NRLIB
+ @ echo 0 making ${OUT}/BGAGG.o from ${MID}/BGAGG.NRLIB
+ @ cp ${MID}/BGAGG.NRLIB/code.o ${OUT}/BGAGG.o
+
+@
+<<BGAGG.NRLIB (NRLIB from MID)>>=
+${MID}/BGAGG.NRLIB: ${MID}/BGAGG.spad
+ @ echo 0 making ${MID}/BGAGG.NRLIB from ${MID}/BGAGG.spad
+ @ (cd ${MID} ; echo ')co BGAGG.spad' | ${INTERPSYS} )
+
+@
+<<BGAGG.spad (SPAD from IN)>>=
+${MID}/BGAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/BGAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BGAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category BGAGG BagAggregate" ${IN}/aggcat.spad.pamphlet >BGAGG.spad )
+
+@
+<<BRAGG-.o (O from NRLIB)>>=
+${OUT}/BRAGG-.o: ${MID}/BRAGG.NRLIB
+ @ echo 0 making ${OUT}/BRAGG-.o from ${MID}/BRAGG-.NRLIB
+ @ cp ${MID}/BRAGG-.NRLIB/code.o ${OUT}/BRAGG-.o
+
+@
+<<BRAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/BRAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/BRAGG.spad
+ @ echo 0 making ${MID}/BRAGG-.NRLIB from ${MID}/BRAGG.spad
+ @ (cd ${MID} ; echo ')co BRAGG.spad' | ${INTERPSYS} )
+
+@
+<<BRAGG.o (O from NRLIB)>>=
+${OUT}/BRAGG.o: ${MID}/BRAGG.NRLIB
+ @ echo 0 making ${OUT}/BRAGG.o from ${MID}/BRAGG.NRLIB
+ @ cp ${MID}/BRAGG.NRLIB/code.o ${OUT}/BRAGG.o
+
+@
+<<BRAGG.NRLIB (NRLIB from MID)>>=
+${MID}/BRAGG.NRLIB: ${MID}/BRAGG.spad
+ @ echo 0 making ${MID}/BRAGG.NRLIB from ${MID}/BRAGG.spad
+ @ (cd ${MID} ; echo ')co BRAGG.spad' | ${INTERPSYS} )
+
+@
+<<BRAGG.spad (SPAD from IN)>>=
+${MID}/BRAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/BRAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BRAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category BRAGG BinaryRecursiveAggregate" ${IN}/aggcat.spad.pamphlet >BRAGG.spad )
+
+@
+<<BTAGG-.o (O from NRLIB)>>=
+${OUT}/BTAGG-.o: ${MID}/BTAGG.NRLIB
+ @ echo 0 making ${OUT}/BTAGG-.o from ${MID}/BTAGG-.NRLIB
+ @ cp ${MID}/BTAGG-.NRLIB/code.o ${OUT}/BTAGG-.o
+
+@
+<<BTAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/BTAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/BTAGG.spad
+ @ echo 0 making ${MID}/BTAGG-.NRLIB from ${MID}/BTAGG.spad
+ @ (cd ${MID} ; echo ')co BTAGG.spad' | ${INTERPSYS} )
+
+@
+<<BTAGG.o (O from NRLIB)>>=
+${OUT}/BTAGG.o: ${MID}/BTAGG.NRLIB
+ @ echo 0 making ${OUT}/BTAGG.o from ${MID}/BTAGG.NRLIB
+ @ cp ${MID}/BTAGG.NRLIB/code.o ${OUT}/BTAGG.o
+
+@
+<<BTAGG.NRLIB (NRLIB from MID)>>=
+${MID}/BTAGG.NRLIB: ${MID}/BTAGG.spad
+ @ echo 0 making ${MID}/BTAGG.NRLIB from ${MID}/BTAGG.spad
+ @ (cd ${MID} ; echo ')co BTAGG.spad' | ${INTERPSYS} )
+
+@
+<<BTAGG.spad (SPAD from IN)>>=
+${MID}/BTAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/BTAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BTAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category BTAGG BitAggregate" ${IN}/aggcat.spad.pamphlet >BTAGG.spad )
+
+@
+<<CLAGG-.o (O from NRLIB)>>=
+${OUT}/CLAGG-.o: ${MID}/CLAGG.NRLIB
+ @ echo 0 making ${OUT}/CLAGG-.o from ${MID}/CLAGG-.NRLIB
+ @ cp ${MID}/CLAGG-.NRLIB/code.o ${OUT}/CLAGG-.o
+
+@
+<<CLAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/CLAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/CLAGG.spad
+ @ echo 0 making ${MID}/CLAGG-.NRLIB from ${MID}/CLAGG.spad
+ @ (cd ${MID} ; echo ')co CLAGG.spad' | ${INTERPSYS} )
+
+@
+<<CLAGG.o (O from NRLIB)>>=
+${OUT}/CLAGG.o: ${MID}/CLAGG.NRLIB
+ @ echo 0 making ${OUT}/CLAGG.o from ${MID}/CLAGG.NRLIB
+ @ cp ${MID}/CLAGG.NRLIB/code.o ${OUT}/CLAGG.o
+
+@
+<<CLAGG.NRLIB (NRLIB from MID)>>=
+${MID}/CLAGG.NRLIB: ${MID}/CLAGG.spad
+ @ echo 0 making ${MID}/CLAGG.NRLIB from ${MID}/CLAGG.spad
+ @ (cd ${MID} ; echo ')co CLAGG.spad' | ${INTERPSYS} )
+
+@
+<<CLAGG.spad (SPAD from IN)>>=
+${MID}/CLAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/CLAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CLAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category CLAGG Collection" ${IN}/aggcat.spad.pamphlet >CLAGG.spad )
+
+@
+<<CLAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/CLAGG-.o: ${MID}/CLAGG-.lsp
+ @ echo 0 making ${MID}/CLAGG-.o from ${MID}/CLAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "CLAGG-.lsp" :output-file "CLAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/CLAGG-.o ${OUT}/CLAGG-.o
+
+@
+<<CLAGG-.lsp (LISP from IN)>>=
+${MID}/CLAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/CLAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CLAGG-.NRLIB ; \
+ rm -rf ${OUT}/CLAGG-.o ; \
+ ${SPADBIN}/notangle -R"CLAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >CLAGG-.lsp )
+
+@
+<<CLAGG.o (BOOTSTRAP from MID)>>=
+${MID}/CLAGG.o: ${MID}/CLAGG.lsp
+ @ echo 0 making ${MID}/CLAGG.o from ${MID}/CLAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "CLAGG.lsp" :output-file "CLAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/CLAGG.o ${OUT}/CLAGG.o
+
+@
+<<CLAGG.lsp (LISP from IN)>>=
+${MID}/CLAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/CLAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CLAGG.NRLIB ; \
+ rm -rf ${OUT}/CLAGG.o ; \
+ ${SPADBIN}/notangle -R"CLAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >CLAGG.lsp )
+
+@
+<<DIAGG-.o (O from NRLIB)>>=
+${OUT}/DIAGG-.o: ${MID}/DIAGG.NRLIB
+ @ echo 0 making ${OUT}/DIAGG-.o from ${MID}/DIAGG-.NRLIB
+ @ cp ${MID}/DIAGG-.NRLIB/code.o ${OUT}/DIAGG-.o
+
+@
+<<DIAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/DIAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/DIAGG.spad
+ @ echo 0 making ${MID}/DIAGG-.NRLIB from ${MID}/DIAGG.spad
+ @ (cd ${MID} ; echo ')co DIAGG.spad' | ${INTERPSYS} )
+
+@
+<<DIAGG.o (O from NRLIB)>>=
+${OUT}/DIAGG.o: ${MID}/DIAGG.NRLIB
+ @ echo 0 making ${OUT}/DIAGG.o from ${MID}/DIAGG.NRLIB
+ @ cp ${MID}/DIAGG.NRLIB/code.o ${OUT}/DIAGG.o
+
+@
+<<DIAGG.NRLIB (NRLIB from MID)>>=
+${MID}/DIAGG.NRLIB: ${MID}/DIAGG.spad
+ @ echo 0 making ${MID}/DIAGG.NRLIB from ${MID}/DIAGG.spad
+ @ (cd ${MID} ; echo ')co DIAGG.spad' | ${INTERPSYS} )
+
+@
+<<DIAGG.spad (SPAD from IN)>>=
+${MID}/DIAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/DIAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DIAGG Dictionary" ${IN}/aggcat.spad.pamphlet >DIAGG.spad )
+
+@
+<<DIOPS-.o (O from NRLIB)>>=
+${OUT}/DIOPS-.o: ${MID}/DIOPS.NRLIB
+ @ echo 0 making ${OUT}/DIOPS-.o from ${MID}/DIOPS-.NRLIB
+ @ cp ${MID}/DIOPS-.NRLIB/code.o ${OUT}/DIOPS-.o
+
+@
+<<DIOPS-.NRLIB (NRLIB from MID)>>=
+${MID}/DIOPS-.NRLIB: ${OUT}/TYPE.o ${MID}/DIOPS.spad
+ @ echo 0 making ${MID}/DIOPS-.NRLIB from ${MID}/DIOPS.spad
+ @ (cd ${MID} ; echo ')co DIOPS.spad' | ${INTERPSYS} )
+
+@
+<<DIOPS.o (O from NRLIB)>>=
+${OUT}/DIOPS.o: ${MID}/DIOPS.NRLIB
+ @ echo 0 making ${OUT}/DIOPS.o from ${MID}/DIOPS.NRLIB
+ @ cp ${MID}/DIOPS.NRLIB/code.o ${OUT}/DIOPS.o
+
+@
+<<DIOPS.NRLIB (NRLIB from MID)>>=
+${MID}/DIOPS.NRLIB: ${MID}/DIOPS.spad
+ @ echo 0 making ${MID}/DIOPS.NRLIB from ${MID}/DIOPS.spad
+ @ (cd ${MID} ; echo ')co DIOPS.spad' | ${INTERPSYS} )
+
+@
+<<DIOPS.spad (SPAD from IN)>>=
+${MID}/DIOPS.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/DIOPS.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIOPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DIOPS DictionaryOperations" ${IN}/aggcat.spad.pamphlet >DIOPS.spad )
+
+@
+<<DLAGG.o (O from NRLIB)>>=
+${OUT}/DLAGG.o: ${MID}/DLAGG.NRLIB
+ @ echo 0 making ${OUT}/DLAGG.o from ${MID}/DLAGG.NRLIB
+ @ cp ${MID}/DLAGG.NRLIB/code.o ${OUT}/DLAGG.o
+
+@
+<<DLAGG.NRLIB (NRLIB from MID)>>=
+${MID}/DLAGG.NRLIB: ${MID}/DLAGG.spad
+ @ echo 0 making ${MID}/DLAGG.NRLIB from ${MID}/DLAGG.spad
+ @ (cd ${MID} ; echo ')co DLAGG.spad' | ${INTERPSYS} )
+
+@
+<<DLAGG.spad (SPAD from IN)>>=
+${MID}/DLAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/DLAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DLAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DLAGG DoublyLinkedAggregate" ${IN}/aggcat.spad.pamphlet >DLAGG.spad )
+
+@
+<<DQAGG.o (O from NRLIB)>>=
+${OUT}/DQAGG.o: ${MID}/DQAGG.NRLIB
+ @ echo 0 making ${OUT}/DQAGG.o from ${MID}/DQAGG.NRLIB
+ @ cp ${MID}/DQAGG.NRLIB/code.o ${OUT}/DQAGG.o
+
+@
+<<DQAGG.NRLIB (NRLIB from MID)>>=
+${MID}/DQAGG.NRLIB: ${MID}/DQAGG.spad
+ @ echo 0 making ${MID}/DQAGG.NRLIB from ${MID}/DQAGG.spad
+ @ (cd ${MID} ; echo ')co DQAGG.spad' | ${INTERPSYS} )
+
+@
+<<DQAGG.spad (SPAD from IN)>>=
+${MID}/DQAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/DQAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DQAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DQAGG DequeueAggregate" ${IN}/aggcat.spad.pamphlet >DQAGG.spad )
+
+@
+<<ELAGG-.o (O from NRLIB)>>=
+${OUT}/ELAGG-.o: ${MID}/ELAGG.NRLIB
+ @ echo 0 making ${OUT}/ELAGG-.o from ${MID}/ELAGG-.NRLIB
+ @ cp ${MID}/ELAGG-.NRLIB/code.o ${OUT}/ELAGG-.o
+
+@
+<<ELAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/ELAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/ELAGG.spad
+ @ echo 0 making ${MID}/ELAGG-.NRLIB from ${MID}/ELAGG.spad
+ @ (cd ${MID} ; echo ')co ELAGG.spad' | ${INTERPSYS} )
+
+@
+<<ELAGG.o (O from NRLIB)>>=
+${OUT}/ELAGG.o: ${MID}/ELAGG.NRLIB
+ @ echo 0 making ${OUT}/ELAGG.o from ${MID}/ELAGG.NRLIB
+ @ cp ${MID}/ELAGG.NRLIB/code.o ${OUT}/ELAGG.o
+
+@
+<<ELAGG.NRLIB (NRLIB from MID)>>=
+${MID}/ELAGG.NRLIB: ${MID}/ELAGG.spad
+ @ echo 0 making ${MID}/ELAGG.NRLIB from ${MID}/ELAGG.spad
+ @ (cd ${MID} ; echo ')co ELAGG.spad' | ${INTERPSYS} )
+
+@
+<<ELAGG.spad (SPAD from IN)>>=
+${MID}/ELAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/ELAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ELAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ELAGG ExtensibleLinearAggregate" ${IN}/aggcat.spad.pamphlet >ELAGG.spad )
+
+@
+<<ELTAB.o (O from NRLIB)>>=
+${OUT}/ELTAB.o: ${MID}/ELTAB.NRLIB
+ @ echo 0 making ${OUT}/ELTAB.o from ${MID}/ELTAB.NRLIB
+ @ cp ${MID}/ELTAB.NRLIB/code.o ${OUT}/ELTAB.o
+
+@
+<<ELTAB.NRLIB (NRLIB from MID)>>=
+${MID}/ELTAB.NRLIB: ${MID}/ELTAB.spad
+ @ echo 0 making ${MID}/ELTAB.NRLIB from ${MID}/ELTAB.spad
+ @ (cd ${MID} ; echo ')co ELTAB.spad' | ${INTERPSYS} )
+
+@
+<<ELTAB.spad (SPAD from IN)>>=
+${MID}/ELTAB.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/ELTAB.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ELTAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ELTAB Eltable" ${IN}/aggcat.spad.pamphlet >ELTAB.spad )
+
+@
+<<ELTAGG-.o (O from NRLIB)>>=
+${OUT}/ELTAGG-.o: ${MID}/ELTAGG.NRLIB
+ @ echo 0 making ${OUT}/ELTAGG-.o from ${MID}/ELTAGG-.NRLIB
+ @ cp ${MID}/ELTAGG-.NRLIB/code.o ${OUT}/ELTAGG-.o
+
+@
+<<ELTAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/ELTAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/ELTAGG.spad
+ @ echo 0 making ${MID}/ELTAGG-.NRLIB from ${MID}/ELTAGG.spad
+ @ (cd ${MID} ; echo ')co ELTAGG.spad' | ${INTERPSYS} )
+
+@
+<<ELTAGG.o (O from NRLIB)>>=
+${OUT}/ELTAGG.o: ${MID}/ELTAGG.NRLIB
+ @ echo 0 making ${OUT}/ELTAGG.o from ${MID}/ELTAGG.NRLIB
+ @ cp ${MID}/ELTAGG.NRLIB/code.o ${OUT}/ELTAGG.o
+
+@
+<<ELTAGG.NRLIB (NRLIB from MID)>>=
+${MID}/ELTAGG.NRLIB: ${OUT}/TYPE.o ${MID}/ELTAGG.spad
+ @ echo 0 making ${MID}/ELTAGG.NRLIB from ${MID}/ELTAGG.spad
+ @ (cd ${MID} ; echo ')co ELTAGG.spad' | ${INTERPSYS} )
+
+@
+<<ELTAGG.spad (SPAD from IN)>>=
+${MID}/ELTAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/ELTAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ELTAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ELTAGG EltableAggregate" ${IN}/aggcat.spad.pamphlet >ELTAGG.spad )
+
+@
+<<FLAGG-.o (O from NRLIB)>>=
+${OUT}/FLAGG-.o: ${MID}/FLAGG.NRLIB
+ @ echo 0 making ${OUT}/FLAGG-.o from ${MID}/FLAGG-.NRLIB
+ @ cp ${MID}/FLAGG-.NRLIB/code.o ${OUT}/FLAGG-.o
+
+@
+<<FLAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/FLAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/FLAGG.spad
+ @ echo 0 making ${MID}/FLAGG-.NRLIB from ${MID}/FLAGG.spad
+ @ (cd ${MID} ; echo ')co FLAGG.spad' | ${INTERPSYS} )
+
+@
+<<FLAGG.o (O from NRLIB)>>=
+${OUT}/FLAGG.o: ${MID}/FLAGG.NRLIB
+ @ echo 0 making ${OUT}/FLAGG.o from ${MID}/FLAGG.NRLIB
+ @ cp ${MID}/FLAGG.NRLIB/code.o ${OUT}/FLAGG.o
+
+@
+<<FLAGG.NRLIB (NRLIB from MID)>>=
+${MID}/FLAGG.NRLIB: ${MID}/FLAGG.spad
+ @ echo 0 making ${MID}/FLAGG.NRLIB from ${MID}/FLAGG.spad
+ @ (cd ${MID} ; echo ')co FLAGG.spad' | ${INTERPSYS} )
+
+@
+<<FLAGG.spad (SPAD from IN)>>=
+${MID}/FLAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/FLAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FLAGG FiniteLinearAggregate" ${IN}/aggcat.spad.pamphlet >FLAGG.spad )
+
+@
+<<FSAGG-.o (O from NRLIB)>>=
+${OUT}/FSAGG-.o: ${MID}/FSAGG.NRLIB
+ @ echo 0 making ${OUT}/FSAGG-.o from ${MID}/FSAGG-.NRLIB
+ @ cp ${MID}/FSAGG-.NRLIB/code.o ${OUT}/FSAGG-.o
+
+@
+<<FSAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/FSAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/FSAGG.spad
+ @ echo 0 making ${MID}/FSAGG-.NRLIB from ${MID}/FSAGG.spad
+ @ (cd ${MID} ; echo ')co FSAGG.spad' | ${INTERPSYS} )
+
+@
+<<FSAGG.o (O from NRLIB)>>=
+${OUT}/FSAGG.o: ${MID}/FSAGG.NRLIB
+ @ echo 0 making ${OUT}/FSAGG.o from ${MID}/FSAGG.NRLIB
+ @ cp ${MID}/FSAGG.NRLIB/code.o ${OUT}/FSAGG.o
+
+@
+<<FSAGG.NRLIB (NRLIB from MID)>>=
+${MID}/FSAGG.NRLIB: ${MID}/FSAGG.spad
+ @ echo 0 making ${MID}/FSAGG.NRLIB from ${MID}/FSAGG.spad
+ @ (cd ${MID} ; echo ')co FSAGG.spad' | ${INTERPSYS} )
+
+@
+<<FSAGG.spad (SPAD from IN)>>=
+${MID}/FSAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/FSAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FSAGG FiniteSetAggregate" ${IN}/aggcat.spad.pamphlet >FSAGG.spad )
+
+@
+<<MSETAGG.o (O from NRLIB)>>=
+${OUT}/MSETAGG.o: ${MID}/MSETAGG.NRLIB
+ @ echo 0 making ${OUT}/MSETAGG.o from ${MID}/MSETAGG.NRLIB
+ @ cp ${MID}/MSETAGG.NRLIB/code.o ${OUT}/MSETAGG.o
+
+@
+<<MSETAGG.NRLIB (NRLIB from MID)>>=
+${MID}/MSETAGG.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MSETAGG.spad
+ @ echo 0 making ${MID}/MSETAGG.NRLIB from ${MID}/MSETAGG.spad
+ @ (cd ${MID} ; echo ')co MSETAGG.spad' | ${INTERPSYS} )
+
+@
+<<MSETAGG.spad (SPAD from IN)>>=
+${MID}/MSETAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/MSETAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MSETAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MSETAGG MultisetAggregate" ${IN}/aggcat.spad.pamphlet >MSETAGG.spad )
+
+@
+<<HOAGG-.o (O from NRLIB)>>=
+${OUT}/HOAGG-.o: ${MID}/HOAGG.NRLIB
+ @ echo 0 making ${OUT}/HOAGG-.o from ${MID}/HOAGG-.NRLIB
+ @ cp ${MID}/HOAGG-.NRLIB/code.o ${OUT}/HOAGG-.o
+
+@
+<<HOAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/HOAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/HOAGG.spad
+ @ echo 0 making ${MID}/HOAGG-.NRLIB from ${MID}/HOAGG.spad
+ @ (cd ${MID} ; echo ')co HOAGG.spad' | ${INTERPSYS} )
+
+@
+<<HOAGG.o (O from NRLIB)>>=
+${OUT}/HOAGG.o: ${MID}/HOAGG.NRLIB
+ @ echo 0 making ${OUT}/HOAGG.o from ${MID}/HOAGG.NRLIB
+ @ cp ${MID}/HOAGG.NRLIB/code.o ${OUT}/HOAGG.o
+
+@
+<<HOAGG.NRLIB (NRLIB from MID)>>=
+${MID}/HOAGG.NRLIB: ${MID}/HOAGG.spad
+ @ echo 0 making ${MID}/HOAGG.NRLIB from ${MID}/HOAGG.spad
+ @ (cd ${MID} ; echo ')co HOAGG.spad' | ${INTERPSYS} )
+
+@
+<<HOAGG.spad (SPAD from IN)>>=
+${MID}/HOAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/HOAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HOAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category HOAGG HomogeneousAggregate" ${IN}/aggcat.spad.pamphlet >HOAGG.spad )
+
+@
+<<HOAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/HOAGG-.o: ${MID}/HOAGG-.lsp
+ @ echo 0 making ${MID}/HOAGG-.o from ${MID}/HOAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "HOAGG-.lsp" :output-file "HOAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/HOAGG-.o ${OUT}/HOAGG-.o
+
+@
+<<HOAGG-.lsp (LISP from IN)>>=
+${MID}/HOAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/HOAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HOAGG-.NRLIB ; \
+ rm -rf ${OUT}/HOAGG-.o ; \
+ ${SPADBIN}/notangle -R"HOAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >HOAGG-.lsp )
+
+@
+<<HOAGG.o (BOOTSTRAP from MID)>>=
+${MID}/HOAGG.o: ${MID}/HOAGG.lsp
+ @ echo 0 making ${MID}/HOAGG.o from ${MID}/HOAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "HOAGG.lsp" :output-file "HOAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/HOAGG.o ${OUT}/HOAGG.o
+
+@
+<<HOAGG.lsp (LISP from IN)>>=
+${MID}/HOAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/HOAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HOAGG.NRLIB ; \
+ rm -rf ${OUT}/HOAGG.o ; \
+ ${SPADBIN}/notangle -R"HOAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >HOAGG.lsp )
+
+@
+<<IXAGG-.o (O from NRLIB)>>=
+${OUT}/IXAGG-.o: ${MID}/IXAGG.NRLIB
+ @ echo 0 making ${OUT}/IXAGG-.o from ${MID}/IXAGG-.NRLIB
+ @ cp ${MID}/IXAGG-.NRLIB/code.o ${OUT}/IXAGG-.o
+
+@
+<<IXAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/IXAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/IXAGG.spad
+ @ echo 0 making ${MID}/IXAGG-.NRLIB from ${MID}/IXAGG.spad
+ @ (cd ${MID} ; echo ')co IXAGG.spad' | ${INTERPSYS} )
+
+@
+<<IXAGG.o (O from NRLIB)>>=
+${OUT}/IXAGG.o: ${MID}/IXAGG.NRLIB
+ @ echo 0 making ${OUT}/IXAGG.o from ${MID}/IXAGG.NRLIB
+ @ cp ${MID}/IXAGG.NRLIB/code.o ${OUT}/IXAGG.o
+
+@
+<<IXAGG.NRLIB (NRLIB from MID)>>=
+${MID}/IXAGG.NRLIB: ${MID}/IXAGG.spad
+ @ echo 0 making ${MID}/IXAGG.NRLIB from ${MID}/IXAGG.spad
+ @ (cd ${MID} ; echo ')co IXAGG.spad' | ${INTERPSYS} )
+
+@
+<<IXAGG.spad (SPAD from IN)>>=
+${MID}/IXAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/IXAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IXAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category IXAGG IndexedAggregate" ${IN}/aggcat.spad.pamphlet >IXAGG.spad )
+
+@
+<<KDAGG-.o (O from NRLIB)>>=
+${OUT}/KDAGG-.o: ${MID}/KDAGG.NRLIB
+ @ echo 0 making ${OUT}/KDAGG-.o from ${MID}/KDAGG-.NRLIB
+ @ cp ${MID}/KDAGG-.NRLIB/code.o ${OUT}/KDAGG-.o
+
+@
+<<KDAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/KDAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/KDAGG.spad
+ @ echo 0 making ${MID}/KDAGG-.NRLIB from ${MID}/KDAGG.spad
+ @ (cd ${MID} ; echo ')co KDAGG.spad' | ${INTERPSYS} )
+
+@
+<<KDAGG.o (O from NRLIB)>>=
+${OUT}/KDAGG.o: ${MID}/KDAGG.NRLIB
+ @ echo 0 making ${OUT}/KDAGG.o from ${MID}/KDAGG.NRLIB
+ @ cp ${MID}/KDAGG.NRLIB/code.o ${OUT}/KDAGG.o
+
+@
+<<KDAGG.NRLIB (NRLIB from MID)>>=
+${MID}/KDAGG.NRLIB: ${MID}/KDAGG.spad
+ @ echo 0 making ${MID}/KDAGG.NRLIB from ${MID}/KDAGG.spad
+ @ (cd ${MID} ; echo ')co KDAGG.spad' | ${INTERPSYS} )
+
+@
+<<KDAGG.spad (SPAD from IN)>>=
+${MID}/KDAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/KDAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf KDAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category KDAGG KeyedDictionary" ${IN}/aggcat.spad.pamphlet >KDAGG.spad )
+
+@
+<<LSAGG-.o (O from NRLIB)>>=
+${OUT}/LSAGG-.o: ${MID}/LSAGG.NRLIB
+ @ echo 0 making ${OUT}/LSAGG-.o from ${MID}/LSAGG-.NRLIB
+ @ cp ${MID}/LSAGG-.NRLIB/code.o ${OUT}/LSAGG-.o
+
+@
+<<LSAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/LSAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/LSAGG.spad
+ @ echo 0 making ${MID}/LSAGG-.NRLIB from ${MID}/LSAGG.spad
+ @ (cd ${MID} ; echo ')co LSAGG.spad' | ${INTERPSYS} )
+
+@
+<<LSAGG.o (O from NRLIB)>>=
+${OUT}/LSAGG.o: ${MID}/LSAGG.NRLIB
+ @ echo 0 making ${OUT}/LSAGG.o from ${MID}/LSAGG.NRLIB
+ @ cp ${MID}/LSAGG.NRLIB/code.o ${OUT}/LSAGG.o
+
+@
+<<LSAGG.NRLIB (NRLIB from MID)>>=
+${MID}/LSAGG.NRLIB: ${MID}/LSAGG.spad
+ @ echo 0 making ${MID}/LSAGG.NRLIB from ${MID}/LSAGG.spad
+ @ (cd ${MID} ; echo ')co LSAGG.spad' | ${INTERPSYS} )
+
+@
+<<LSAGG.spad (SPAD from IN)>>=
+${MID}/LSAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/LSAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LSAGG ListAggregate" ${IN}/aggcat.spad.pamphlet >LSAGG.spad )
+
+@
+<<LSAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/LSAGG-.o: ${MID}/LSAGG-.lsp
+ @ echo 0 making ${MID}/LSAGG-.o from ${MID}/LSAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "LSAGG-.lsp" :output-file "LSAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/LSAGG-.o ${OUT}/LSAGG-.o
+
+@
+<<LSAGG-.lsp (LISP from IN)>>=
+${MID}/LSAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/LSAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSAGG-.NRLIB ; \
+ rm -rf ${OUT}/LSAGG-.o ; \
+ ${SPADBIN}/notangle -R"LSAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >LSAGG-.lsp )
+
+@
+<<LSAGG.o (BOOTSTRAP from MID)>>=
+${MID}/LSAGG.o: ${MID}/LSAGG.lsp
+ @ echo 0 making ${MID}/LSAGG.o from ${MID}/LSAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "LSAGG.lsp" :output-file "LSAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/LSAGG.o ${OUT}/LSAGG.o
+
+@
+<<LSAGG.lsp (LISP from IN)>>=
+${MID}/LSAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/LSAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSAGG.NRLIB ; \
+ rm -rf ${OUT}/LSAGG.o ; \
+ ${SPADBIN}/notangle -R"LSAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >LSAGG.lsp )
+
+@
+<<LNAGG-.o (O from NRLIB)>>=
+${OUT}/LNAGG-.o: ${MID}/LNAGG.NRLIB
+ @ echo 0 making ${OUT}/LNAGG-.o from ${MID}/LNAGG-.NRLIB
+ @ cp ${MID}/LNAGG-.NRLIB/code.o ${OUT}/LNAGG-.o
+
+@
+<<LNAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/LNAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/LNAGG.spad
+ @ echo 0 making ${MID}/LNAGG-.NRLIB from ${MID}/LNAGG.spad
+ @ (cd ${MID} ; echo ')co LNAGG.spad' | ${INTERPSYS} )
+
+@
+<<LNAGG.o (O from NRLIB)>>=
+${OUT}/LNAGG.o: ${MID}/LNAGG.NRLIB
+ @ echo 0 making ${OUT}/LNAGG.o from ${MID}/LNAGG.NRLIB
+ @ cp ${MID}/LNAGG.NRLIB/code.o ${OUT}/LNAGG.o
+
+@
+<<LNAGG.NRLIB (NRLIB from MID)>>=
+${MID}/LNAGG.NRLIB: ${MID}/LNAGG.spad
+ @ echo 0 making ${MID}/LNAGG.NRLIB from ${MID}/LNAGG.spad
+ @ (cd ${MID} ; echo ')co LNAGG.spad' | ${INTERPSYS} )
+
+@
+<<LNAGG.spad (SPAD from IN)>>=
+${MID}/LNAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/LNAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LNAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LNAGG LinearAggregate" ${IN}/aggcat.spad.pamphlet >LNAGG.spad )
+
+@
+<<LNAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/LNAGG-.o: ${MID}/LNAGG-.lsp
+ @ echo 0 making ${MID}/LNAGG-.o from ${MID}/LNAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "LNAGG-.lsp" :output-file "LNAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/LNAGG-.o ${OUT}/LNAGG-.o
+
+@
+<<LNAGG-.lsp (LISP from IN)>>=
+${MID}/LNAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/LNAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LNAGG-.NRLIB ; \
+ rm -rf ${OUT}/LNAGG-.o ; \
+ ${SPADBIN}/notangle -R"LNAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >LNAGG-.lsp )
+
+@
+<<LNAGG.o (BOOTSTRAP from MID)>>=
+${MID}/LNAGG.o: ${MID}/LNAGG.lsp
+ @ echo 0 making ${MID}/LNAGG.o from ${MID}/LNAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "LNAGG.lsp" :output-file "LNAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/LNAGG.o ${OUT}/LNAGG.o
+
+@
+<<LNAGG.lsp (LISP from IN)>>=
+${MID}/LNAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/LNAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LNAGG.NRLIB ; \
+ rm -rf ${OUT}/LNAGG.o ; \
+ ${SPADBIN}/notangle -R"LNAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >LNAGG.lsp )
+
+@
+<<MDAGG.o (O from NRLIB)>>=
+${OUT}/MDAGG.o: ${MID}/MDAGG.NRLIB
+ @ echo 0 making ${OUT}/MDAGG.o from ${MID}/MDAGG.NRLIB
+ @ cp ${MID}/MDAGG.NRLIB/code.o ${OUT}/MDAGG.o
+
+@
+<<MDAGG.NRLIB (NRLIB from MID)>>=
+${MID}/MDAGG.NRLIB: ${MID}/MDAGG.spad
+ @ echo 0 making ${MID}/MDAGG.NRLIB from ${MID}/MDAGG.spad
+ @ (cd ${MID} ; echo ')co MDAGG.spad' | ${INTERPSYS} )
+
+@
+<<MDAGG.spad (SPAD from IN)>>=
+${MID}/MDAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/MDAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MDAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MDAGG MultiDictionary" ${IN}/aggcat.spad.pamphlet >MDAGG.spad )
+
+@
+<<OMSAGG.o (O from NRLIB)>>=
+${OUT}/OMSAGG.o: ${MID}/OMSAGG.NRLIB
+ @ echo 0 making ${OUT}/OMSAGG.o from ${MID}/OMSAGG.NRLIB
+ @ cp ${MID}/OMSAGG.NRLIB/code.o ${OUT}/OMSAGG.o
+
+@
+<<OMSAGG.NRLIB (NRLIB from MID)>>=
+${MID}/OMSAGG.NRLIB: ${MID}/OMSAGG.spad
+ @ echo 0 making ${MID}/OMSAGG.NRLIB from ${MID}/OMSAGG.spad
+ @ (cd ${MID} ; echo ')co OMSAGG.spad' | ${INTERPSYS} )
+
+@
+<<OMSAGG.spad (SPAD from IN)>>=
+${MID}/OMSAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/OMSAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMSAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OMSAGG OrderedMultisetAggregate" ${IN}/aggcat.spad.pamphlet >OMSAGG.spad )
+
+@
+<<PRQAGG.o (O from NRLIB)>>=
+${OUT}/PRQAGG.o: ${MID}/PRQAGG.NRLIB
+ @ echo 0 making ${OUT}/PRQAGG.o from ${MID}/PRQAGG.NRLIB
+ @ cp ${MID}/PRQAGG.NRLIB/code.o ${OUT}/PRQAGG.o
+
+@
+<<PRQAGG.NRLIB (NRLIB from MID)>>=
+${MID}/PRQAGG.NRLIB: ${MID}/PRQAGG.spad
+ @ echo 0 making ${MID}/PRQAGG.NRLIB from ${MID}/PRQAGG.spad
+ @ (cd ${MID} ; echo ')co PRQAGG.spad' | ${INTERPSYS} )
+
+@
+<<PRQAGG.spad (SPAD from IN)>>=
+${MID}/PRQAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/PRQAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRQAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PRQAGG PriorityQueueAggregate" ${IN}/aggcat.spad.pamphlet >PRQAGG.spad )
+
+@
+<<QUAGG.o (O from NRLIB)>>=
+${OUT}/QUAGG.o: ${MID}/QUAGG.NRLIB
+ @ echo 0 making ${OUT}/QUAGG.o from ${MID}/QUAGG.NRLIB
+ @ cp ${MID}/QUAGG.NRLIB/code.o ${OUT}/QUAGG.o
+
+@
+<<QUAGG.NRLIB (NRLIB from MID)>>=
+${MID}/QUAGG.NRLIB: ${MID}/QUAGG.spad
+ @ echo 0 making ${MID}/QUAGG.NRLIB from ${MID}/QUAGG.spad
+ @ (cd ${MID} ; echo ')co QUAGG.spad' | ${INTERPSYS} )
+
+@
+<<QUAGG.spad (SPAD from IN)>>=
+${MID}/QUAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/QUAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QUAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category QUAGG QueueAggregate" ${IN}/aggcat.spad.pamphlet >QUAGG.spad )
+
+@
+<<RCAGG-.o (O from NRLIB)>>=
+${OUT}/RCAGG-.o: ${MID}/RCAGG.NRLIB
+ @ echo 0 making ${OUT}/RCAGG-.o from ${MID}/RCAGG-.NRLIB
+ @ cp ${MID}/RCAGG-.NRLIB/code.o ${OUT}/RCAGG-.o
+
+@
+<<RCAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/RCAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/RCAGG.spad
+ @ echo 0 making ${MID}/RCAGG-.NRLIB from ${MID}/RCAGG.spad
+ @ (cd ${MID} ; echo ')co RCAGG.spad' | ${INTERPSYS} )
+
+@
+<<RCAGG.o (O from NRLIB)>>=
+${OUT}/RCAGG.o: ${MID}/RCAGG.NRLIB
+ @ echo 0 making ${OUT}/RCAGG.o from ${MID}/RCAGG.NRLIB
+ @ cp ${MID}/RCAGG.NRLIB/code.o ${OUT}/RCAGG.o
+
+@
+<<RCAGG.NRLIB (NRLIB from MID)>>=
+${MID}/RCAGG.NRLIB: ${MID}/RCAGG.spad
+ @ echo 0 making ${MID}/RCAGG.NRLIB from ${MID}/RCAGG.spad
+ @ (cd ${MID} ; echo ')co RCAGG.spad' | ${INTERPSYS} )
+
+@
+<<RCAGG.spad (SPAD from IN)>>=
+${MID}/RCAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/RCAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RCAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RCAGG RecursiveAggregate" ${IN}/aggcat.spad.pamphlet >RCAGG.spad )
+
+@
+<<RCAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/RCAGG-.o: ${MID}/RCAGG-.lsp
+ @ echo 0 making ${MID}/RCAGG-.o from ${MID}/RCAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RCAGG-.lsp" :output-file "RCAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RCAGG-.o ${OUT}/RCAGG-.o
+
+@
+<<RCAGG-.lsp (LISP from IN)>>=
+${MID}/RCAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/RCAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RCAGG-.NRLIB ; \
+ rm -rf ${OUT}/RCAGG-.o ; \
+ ${SPADBIN}/notangle -R"RCAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >RCAGG-.lsp )
+
+@
+<<RCAGG.o (BOOTSTRAP from MID)>>=
+${MID}/RCAGG.o: ${MID}/RCAGG.lsp
+ @ echo 0 making ${MID}/RCAGG.o from ${MID}/RCAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RCAGG.lsp" :output-file "RCAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RCAGG.o ${OUT}/RCAGG.o
+
+@
+<<RCAGG.lsp (LISP from IN)>>=
+${MID}/RCAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/RCAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RCAGG.NRLIB ; \
+ rm -rf ${OUT}/RCAGG.o ; \
+ ${SPADBIN}/notangle -R"RCAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >RCAGG.lsp )
+
+@
+<<SETAGG-.o (O from NRLIB)>>=
+${OUT}/SETAGG-.o: ${MID}/SETAGG.NRLIB
+ @ echo 0 making ${OUT}/SETAGG-.o from ${MID}/SETAGG-.NRLIB
+ @ cp ${MID}/SETAGG-.NRLIB/code.o ${OUT}/SETAGG-.o
+
+@
+<<SETAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/SETAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/SETAGG.spad
+ @ echo 0 making ${MID}/SETAGG-.NRLIB from ${MID}/SETAGG.spad
+ @ (cd ${MID} ; echo ')co SETAGG.spad' | ${INTERPSYS} )
+
+@
+<<SETAGG.o (O from NRLIB)>>=
+${OUT}/SETAGG.o: ${MID}/SETAGG.NRLIB
+ @ echo 0 making ${OUT}/SETAGG.o from ${MID}/SETAGG.NRLIB
+ @ cp ${MID}/SETAGG.NRLIB/code.o ${OUT}/SETAGG.o
+
+@
+<<SETAGG.NRLIB (NRLIB from MID)>>=
+${MID}/SETAGG.NRLIB: ${MID}/SETAGG.spad
+ @ echo 0 making ${MID}/SETAGG.NRLIB from ${MID}/SETAGG.spad
+ @ (cd ${MID} ; echo ')co SETAGG.spad' | ${INTERPSYS} )
+
+@
+<<SETAGG.spad (SPAD from IN)>>=
+${MID}/SETAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/SETAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SETAGG SetAggregate" ${IN}/aggcat.spad.pamphlet >SETAGG.spad )
+
+@
+<<SETAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/SETAGG-.o: ${MID}/SETAGG-.lsp
+ @ echo 0 making ${MID}/SETAGG-.o from ${MID}/SETAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "SETAGG-.lsp" :output-file "SETAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/SETAGG-.o ${OUT}/SETAGG-.o
+
+@
+<<SETAGG-.lsp (LISP from IN)>>=
+${MID}/SETAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/SETAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETAGG-.NRLIB ; \
+ rm -rf ${OUT}/SETAGG-.o ; \
+ ${SPADBIN}/notangle -R"SETAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >SETAGG-.lsp )
+
+@
+<<SETAGG.o (BOOTSTRAP from MID)>>=
+${MID}/SETAGG.o: ${MID}/SETAGG.lsp
+ @ echo 0 making ${MID}/SETAGG.o from ${MID}/SETAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "SETAGG.lsp" :output-file "SETAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/SETAGG.o ${OUT}/SETAGG.o
+
+@
+<<SETAGG.lsp (LISP from IN)>>=
+${MID}/SETAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/SETAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETAGG.NRLIB ; \
+ rm -rf ${OUT}/SETAGG.o ; \
+ ${SPADBIN}/notangle -R"SETAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >SETAGG.lsp )
+
+@
+<<SKAGG.o (O from NRLIB)>>=
+${OUT}/SKAGG.o: ${MID}/SKAGG.NRLIB
+ @ echo 0 making ${OUT}/SKAGG.o from ${MID}/SKAGG.NRLIB
+ @ cp ${MID}/SKAGG.NRLIB/code.o ${OUT}/SKAGG.o
+
+@
+<<SKAGG.NRLIB (NRLIB from MID)>>=
+${MID}/SKAGG.NRLIB: ${MID}/SKAGG.spad
+ @ echo 0 making ${MID}/SKAGG.NRLIB from ${MID}/SKAGG.spad
+ @ (cd ${MID} ; echo ')co SKAGG.spad' | ${INTERPSYS} )
+
+@
+<<SKAGG.spad (SPAD from IN)>>=
+${MID}/SKAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/SKAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SKAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SKAGG StackAggregate" ${IN}/aggcat.spad.pamphlet >SKAGG.spad )
+
+@
+<<SRAGG-.o (O from NRLIB)>>=
+${OUT}/SRAGG-.o: ${MID}/SRAGG.NRLIB
+ @ echo 0 making ${OUT}/SRAGG-.o from ${MID}/SRAGG-.NRLIB
+ @ cp ${MID}/SRAGG-.NRLIB/code.o ${OUT}/SRAGG-.o
+
+@
+<<SRAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/SRAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/SRAGG.spad
+ @ echo 0 making ${MID}/SRAGG-.NRLIB from ${MID}/SRAGG.spad
+ @ (cd ${MID} ; echo ')co SRAGG.spad' | ${INTERPSYS} )
+
+@
+<<SRAGG.o (O from NRLIB)>>=
+${OUT}/SRAGG.o: ${MID}/SRAGG.NRLIB
+ @ echo 0 making ${OUT}/SRAGG.o from ${MID}/SRAGG.NRLIB
+ @ cp ${MID}/SRAGG.NRLIB/code.o ${OUT}/SRAGG.o
+
+@
+<<SRAGG.NRLIB (NRLIB from MID)>>=
+${MID}/SRAGG.NRLIB: ${MID}/SRAGG.spad
+ @ echo 0 making ${MID}/SRAGG.NRLIB from ${MID}/SRAGG.spad
+ @ (cd ${MID} ; echo ')co SRAGG.spad' | ${INTERPSYS} )
+
+@
+<<SRAGG.spad (SPAD from IN)>>=
+${MID}/SRAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/SRAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SRAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SRAGG StringAggregate" ${IN}/aggcat.spad.pamphlet >SRAGG.spad )
+
+@
+<<STAGG-.o (O from NRLIB)>>=
+${OUT}/STAGG-.o: ${MID}/STAGG.NRLIB
+ @ echo 0 making ${OUT}/STAGG-.o from ${MID}/STAGG-.NRLIB
+ @ cp ${MID}/STAGG-.NRLIB/code.o ${OUT}/STAGG-.o
+
+@
+<<STAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/STAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/STAGG.spad
+ @ echo 0 making ${MID}/STAGG-.NRLIB from ${MID}/STAGG.spad
+ @ (cd ${MID} ; echo ')co STAGG.spad' | ${INTERPSYS} )
+
+@
+<<STAGG.o (O from NRLIB)>>=
+${OUT}/STAGG.o: ${MID}/STAGG.NRLIB
+ @ echo 0 making ${OUT}/STAGG.o from ${MID}/STAGG.NRLIB
+ @ cp ${MID}/STAGG.NRLIB/code.o ${OUT}/STAGG.o
+
+@
+<<STAGG.NRLIB (NRLIB from MID)>>=
+${MID}/STAGG.NRLIB: ${MID}/STAGG.spad
+ @ echo 0 making ${MID}/STAGG.NRLIB from ${MID}/STAGG.spad
+ @ (cd ${MID} ; echo ')co STAGG.spad' | ${INTERPSYS} )
+
+@
+<<STAGG.spad (SPAD from IN)>>=
+${MID}/STAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/STAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category STAGG StreamAggregate" ${IN}/aggcat.spad.pamphlet >STAGG.spad )
+
+@
+<<STAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/STAGG-.o: ${MID}/STAGG-.lsp
+ @ echo 0 making ${MID}/STAGG-.o from ${MID}/STAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "STAGG-.lsp" :output-file "STAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/STAGG-.o ${OUT}/STAGG-.o
+
+@
+<<STAGG-.lsp (LISP from IN)>>=
+${MID}/STAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/STAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STAGG-.NRLIB ; \
+ rm -rf ${OUT}/STAGG-.o ; \
+ ${SPADBIN}/notangle -R"STAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >STAGG-.lsp )
+
+@
+<<STAGG.o (BOOTSTRAP from MID)>>=
+${MID}/STAGG.o: ${MID}/STAGG.lsp
+ @ echo 0 making ${MID}/STAGG.o from ${MID}/STAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "STAGG.lsp" :output-file "STAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/STAGG.o ${OUT}/STAGG.o
+
+@
+<<STAGG.lsp (LISP from IN)>>=
+${MID}/STAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/STAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STAGG.NRLIB ; \
+ rm -rf ${OUT}/STAGG.o ; \
+ ${SPADBIN}/notangle -R"STAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >STAGG.lsp )
+
+@
+<<TBAGG-.o (O from NRLIB)>>=
+${OUT}/TBAGG-.o: ${MID}/TBAGG.NRLIB
+ @ echo 0 making ${OUT}/TBAGG-.o from ${MID}/TBAGG-.NRLIB
+ @ cp ${MID}/TBAGG-.NRLIB/code.o ${OUT}/TBAGG-.o
+
+@
+<<TBAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/TBAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/TBAGG.spad
+ @ echo 0 making ${MID}/TBAGG-.NRLIB from ${MID}/TBAGG.spad
+ @ (cd ${MID} ; echo ')co TBAGG.spad' | ${INTERPSYS} )
+
+@
+<<TBAGG.o (O from NRLIB)>>=
+${OUT}/TBAGG.o: ${MID}/TBAGG.NRLIB
+ @ echo 0 making ${OUT}/TBAGG.o from ${MID}/TBAGG.NRLIB
+ @ cp ${MID}/TBAGG.NRLIB/code.o ${OUT}/TBAGG.o
+
+@
+<<TBAGG.NRLIB (NRLIB from MID)>>=
+${MID}/TBAGG.NRLIB: ${MID}/TBAGG.spad
+ @ echo 0 making ${MID}/TBAGG.NRLIB from ${MID}/TBAGG.spad
+ @ (cd ${MID} ; echo ')co TBAGG.spad' | ${INTERPSYS} )
+
+@
+<<TBAGG.spad (SPAD from IN)>>=
+${MID}/TBAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/TBAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TBAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category TBAGG TableAggregate" ${IN}/aggcat.spad.pamphlet >TBAGG.spad )
+
+@
+<<URAGG-.o (O from NRLIB)>>=
+${OUT}/URAGG-.o: ${MID}/URAGG.NRLIB
+ @ echo 0 making ${OUT}/URAGG-.o from ${MID}/URAGG-.NRLIB
+ @ cp ${MID}/URAGG-.NRLIB/code.o ${OUT}/URAGG-.o
+
+@
+<<URAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/URAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/URAGG.spad
+ @ echo 0 making ${MID}/URAGG-.NRLIB from ${MID}/URAGG.spad
+ @ (cd ${MID} ; echo ')co URAGG.spad' | ${INTERPSYS} )
+
+@
+<<URAGG.o (O from NRLIB)>>=
+${OUT}/URAGG.o: ${MID}/URAGG.NRLIB
+ @ echo 0 making ${OUT}/URAGG.o from ${MID}/URAGG.NRLIB
+ @ cp ${MID}/URAGG.NRLIB/code.o ${OUT}/URAGG.o
+
+@
+<<URAGG.NRLIB (NRLIB from MID)>>=
+${MID}/URAGG.NRLIB: ${MID}/URAGG.spad
+ @ echo 0 making ${MID}/URAGG.NRLIB from ${MID}/URAGG.spad
+ @ (cd ${MID} ; echo ')co URAGG.spad' | ${INTERPSYS} )
+
+@
+<<URAGG.spad (SPAD from IN)>>=
+${MID}/URAGG.spad: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/URAGG.spad from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf URAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category URAGG UnaryRecursiveAggregate" ${IN}/aggcat.spad.pamphlet >URAGG.spad )
+
+@
+<<URAGG-.o (BOOTSTRAP from MID)>>=
+${MID}/URAGG-.o: ${MID}/URAGG-.lsp
+ @ echo 0 making ${MID}/URAGG-.o from ${MID}/URAGG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "URAGG-.lsp" :output-file "URAGG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/URAGG-.o ${OUT}/URAGG-.o
+
+@
+<<URAGG-.lsp (LISP from IN)>>=
+${MID}/URAGG-.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/URAGG-.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf URAGG-.NRLIB ; \
+ rm -rf ${OUT}/URAGG-.o ; \
+ ${SPADBIN}/notangle -R"URAGG-.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >URAGG-.lsp )
+
+@
+<<URAGG.o (BOOTSTRAP from MID)>>=
+${MID}/URAGG.o: ${MID}/URAGG.lsp
+ @ echo 0 making ${MID}/URAGG.o from ${MID}/URAGG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "URAGG.lsp" :output-file "URAGG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/URAGG.o ${OUT}/URAGG.o
+
+@
+<<URAGG.lsp (LISP from IN)>>=
+${MID}/URAGG.lsp: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${MID}/URAGG.lsp from ${IN}/aggcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf URAGG.NRLIB ; \
+ rm -rf ${OUT}/URAGG.o ; \
+ ${SPADBIN}/notangle -R"URAGG.lsp BOOTSTRAP" ${IN}/aggcat.spad.pamphlet >URAGG.lsp )
+
+@
+<<aggcat.spad.dvi (DOC from IN)>>=
+${DOC}/aggcat.spad.dvi: ${IN}/aggcat.spad.pamphlet
+ @ echo 0 making ${DOC}/aggcat.spad.dvi from ${IN}/aggcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/aggcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} aggcat.spad ; \
+ rm -f ${DOC}/aggcat.spad.pamphlet ; \
+ rm -f ${DOC}/aggcat.spad.tex ; \
+ rm -f ${DOC}/aggcat.spad )
+
+@
+\subsection{algcat.spad \cite{1}}
+<<algcat.spad (SPAD from IN)>>=
+${MID}/algcat.spad: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${MID}/algcat.spad from ${IN}/algcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/algcat.spad.pamphlet >algcat.spad )
+
+@
+<<CPIMA.o (O from NRLIB)>>=
+${OUT}/CPIMA.o: ${MID}/CPIMA.NRLIB
+ @ echo 0 making ${OUT}/CPIMA.o from ${MID}/CPIMA.NRLIB
+ @ cp ${MID}/CPIMA.NRLIB/code.o ${OUT}/CPIMA.o
+
+@
+<<CPIMA.NRLIB (NRLIB from MID)>>=
+${MID}/CPIMA.NRLIB: ${MID}/CPIMA.spad
+ @ echo 0 making ${MID}/CPIMA.NRLIB from ${MID}/CPIMA.spad
+ @ (cd ${MID} ; echo ')co CPIMA.spad' | ${INTERPSYS} )
+
+@
+<<CPIMA.spad (SPAD from IN)>>=
+${MID}/CPIMA.spad: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${MID}/CPIMA.spad from ${IN}/algcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CPIMA.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CPIMA CharacteristicPolynomialInMonogenicalAlgebra" ${IN}/algcat.spad.pamphlet >CPIMA.spad )
+
+@
+<<FINRALG-.o (O from NRLIB)>>=
+${OUT}/FINRALG-.o: ${MID}/FINRALG.NRLIB
+ @ echo 0 making ${OUT}/FINRALG-.o from ${MID}/FINRALG-.NRLIB
+ @ cp ${MID}/FINRALG-.NRLIB/code.o ${OUT}/FINRALG-.o
+
+@
+<<FINRALG-.NRLIB (NRLIB from MID)>>=
+${MID}/FINRALG-.NRLIB: ${OUT}/TYPE.o ${MID}/FINRALG.spad
+ @ echo 0 making ${MID}/FINRALG-.NRLIB from ${MID}/FINRALG.spad
+ @ (cd ${MID} ; echo ')co FINRALG.spad' | ${INTERPSYS} )
+
+@
+<<FINRALG.o (O from NRLIB)>>=
+${OUT}/FINRALG.o: ${MID}/FINRALG.NRLIB
+ @ echo 0 making ${OUT}/FINRALG.o from ${MID}/FINRALG.NRLIB
+ @ cp ${MID}/FINRALG.NRLIB/code.o ${OUT}/FINRALG.o
+
+@
+<<FINRALG.NRLIB (NRLIB from MID)>>=
+${MID}/FINRALG.NRLIB: ${MID}/FINRALG.spad
+ @ echo 0 making ${MID}/FINRALG.NRLIB from ${MID}/FINRALG.spad
+ @ (cd ${MID} ; echo ')co FINRALG.spad' | ${INTERPSYS} )
+
+@
+<<FINRALG.spad (SPAD from IN)>>=
+${MID}/FINRALG.spad: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${MID}/FINRALG.spad from ${IN}/algcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FINRALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FINRALG FiniteRankAlgebra" ${IN}/algcat.spad.pamphlet >FINRALG.spad )
+
+@
+<<FRAMALG-.o (O from NRLIB)>>=
+${OUT}/FRAMALG-.o: ${MID}/FRAMALG.NRLIB
+ @ echo 0 making ${OUT}/FRAMALG-.o from ${MID}/FRAMALG-.NRLIB
+ @ cp ${MID}/FRAMALG-.NRLIB/code.o ${OUT}/FRAMALG-.o
+
+@
+<<FRAMALG-.NRLIB (NRLIB from MID)>>=
+${MID}/FRAMALG-.NRLIB: ${OUT}/TYPE.o ${MID}/FRAMALG.spad
+ @ echo 0 making ${MID}/FRAMALG-.NRLIB from ${MID}/FRAMALG.spad
+ @ (cd ${MID} ; echo ')co FRAMALG.spad' | ${INTERPSYS} )
+
+@
+<<FRAMALG.o (O from NRLIB)>>=
+${OUT}/FRAMALG.o: ${MID}/FRAMALG.NRLIB
+ @ echo 0 making ${OUT}/FRAMALG.o from ${MID}/FRAMALG.NRLIB
+ @ cp ${MID}/FRAMALG.NRLIB/code.o ${OUT}/FRAMALG.o
+
+@
+<<FRAMALG.NRLIB (NRLIB from MID)>>=
+${MID}/FRAMALG.NRLIB: ${MID}/FRAMALG.spad
+ @ echo 0 making ${MID}/FRAMALG.NRLIB from ${MID}/FRAMALG.spad
+ @ (cd ${MID} ; echo ')co FRAMALG.spad' | ${INTERPSYS} )
+
+@
+<<FRAMALG.spad (SPAD from IN)>>=
+${MID}/FRAMALG.spad: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${MID}/FRAMALG.spad from ${IN}/algcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRAMALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FRAMALG FramedAlgebra" ${IN}/algcat.spad.pamphlet >FRAMALG.spad )
+
+@
+<<MONOGEN-.o (O from NRLIB)>>=
+${OUT}/MONOGEN-.o: ${MID}/MONOGEN.NRLIB
+ @ echo 0 making ${OUT}/MONOGEN-.o from ${MID}/MONOGEN-.NRLIB
+ @ cp ${MID}/MONOGEN-.NRLIB/code.o ${OUT}/MONOGEN-.o
+
+@
+<<MONOGEN-.NRLIB (NRLIB from MID)>>=
+${MID}/MONOGEN-.NRLIB: ${OUT}/TYPE.o ${MID}/MONOGEN.spad
+ @ echo 0 making ${MID}/MONOGEN-.NRLIB from ${MID}/MONOGEN.spad
+ @ (cd ${MID} ; echo ')co MONOGEN.spad' | ${INTERPSYS} )
+
+@
+<<MONOGEN.o (O from NRLIB)>>=
+${OUT}/MONOGEN.o: ${MID}/MONOGEN.NRLIB
+ @ echo 0 making ${OUT}/MONOGEN.o from ${MID}/MONOGEN.NRLIB
+ @ cp ${MID}/MONOGEN.NRLIB/code.o ${OUT}/MONOGEN.o
+
+@
+<<MONOGEN.NRLIB (NRLIB from MID)>>=
+${MID}/MONOGEN.NRLIB: ${MID}/MONOGEN.spad
+ @ echo 0 making ${MID}/MONOGEN.NRLIB from ${MID}/MONOGEN.spad
+ @ (cd ${MID} ; echo ')co MONOGEN.spad' | ${INTERPSYS} )
+
+@
+<<MONOGEN.spad (SPAD from IN)>>=
+${MID}/MONOGEN.spad: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${MID}/MONOGEN.spad from ${IN}/algcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONOGEN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MONOGEN MonogenicAlgebra" ${IN}/algcat.spad.pamphlet >MONOGEN.spad )
+
+@
+<<NORMMA.o (O from NRLIB)>>=
+${OUT}/NORMMA.o: ${MID}/NORMMA.NRLIB
+ @ echo 0 making ${OUT}/NORMMA.o from ${MID}/NORMMA.NRLIB
+ @ cp ${MID}/NORMMA.NRLIB/code.o ${OUT}/NORMMA.o
+
+@
+<<NORMMA.NRLIB (NRLIB from MID)>>=
+${MID}/NORMMA.NRLIB: ${MID}/NORMMA.spad
+ @ echo 0 making ${MID}/NORMMA.NRLIB from ${MID}/NORMMA.spad
+ @ (cd ${MID} ; echo ')co NORMMA.spad' | ${INTERPSYS} )
+
+@
+<<NORMMA.spad (SPAD from IN)>>=
+${MID}/NORMMA.spad: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${MID}/NORMMA.spad from ${IN}/algcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NORMMA.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NORMMA NormInMonogenicAlgebra" ${IN}/algcat.spad.pamphlet >NORMMA.spad )
+
+@
+<<algcat.spad.dvi (DOC from IN)>>=
+${DOC}/algcat.spad.dvi: ${IN}/algcat.spad.pamphlet
+ @ echo 0 making ${DOC}/algcat.spad.dvi from ${IN}/algcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/algcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} algcat.spad ; \
+ rm -f ${DOC}/algcat.spad.pamphlet ; \
+ rm -f ${DOC}/algcat.spad.tex ; \
+ rm -f ${DOC}/algcat.spad )
+
+@
+\subsection{algext.spad \cite{1}}
+<<algext.spad (SPAD from IN)>>=
+${MID}/algext.spad: ${IN}/algext.spad.pamphlet
+ @ echo 0 making ${MID}/algext.spad from ${IN}/algext.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/algext.spad.pamphlet >algext.spad )
+
+@
+<<SAE.o (O from NRLIB)>>=
+${OUT}/SAE.o: ${MID}/SAE.NRLIB
+ @ echo 0 making ${OUT}/SAE.o from ${MID}/SAE.NRLIB
+ @ cp ${MID}/SAE.NRLIB/code.o ${OUT}/SAE.o
+
+@
+<<SAE.NRLIB (NRLIB from MID)>>=
+${MID}/SAE.NRLIB: ${MID}/SAE.spad
+ @ echo 0 making ${MID}/SAE.NRLIB from ${MID}/SAE.spad
+ @ (cd ${MID} ; echo ')co SAE.spad' | ${INTERPSYS} )
+
+@
+<<SAE.spad (SPAD from IN)>>=
+${MID}/SAE.spad: ${IN}/algext.spad.pamphlet
+ @ echo 0 making ${MID}/SAE.spad from ${IN}/algext.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SAE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SAE SimpleAlgebraicExtension" ${IN}/algext.spad.pamphlet >SAE.spad )
+
+@
+<<algext.spad.dvi (DOC from IN)>>=
+${DOC}/algext.spad.dvi: ${IN}/algext.spad.pamphlet
+ @ echo 0 making ${DOC}/algext.spad.dvi from ${IN}/algext.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/algext.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} algext.spad ; \
+ rm -f ${DOC}/algext.spad.pamphlet ; \
+ rm -f ${DOC}/algext.spad.tex ; \
+ rm -f ${DOC}/algext.spad )
+
+@
+\subsection{algfact.spad \cite{1}}
+<<algfact.spad (SPAD from IN)>>=
+${MID}/algfact.spad: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${MID}/algfact.spad from ${IN}/algfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/algfact.spad.pamphlet >algfact.spad )
+
+@
+<<ALGFACT.o (O from NRLIB)>>=
+${OUT}/ALGFACT.o: ${MID}/ALGFACT.NRLIB
+ @ echo 0 making ${OUT}/ALGFACT.o from ${MID}/ALGFACT.NRLIB
+ @ cp ${MID}/ALGFACT.NRLIB/code.o ${OUT}/ALGFACT.o
+
+@
+<<ALGFACT.NRLIB (NRLIB from MID)>>=
+${MID}/ALGFACT.NRLIB: ${MID}/ALGFACT.spad
+ @ echo 0 making ${MID}/ALGFACT.NRLIB from ${MID}/ALGFACT.spad
+ @ (cd ${MID} ; echo ')co ALGFACT.spad' | ${INTERPSYS} )
+
+@
+<<ALGFACT.spad (SPAD from IN)>>=
+${MID}/ALGFACT.spad: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${MID}/ALGFACT.spad from ${IN}/algfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ALGFACT AlgFactor" ${IN}/algfact.spad.pamphlet >ALGFACT.spad )
+
+@
+<<IALGFACT.o (O from NRLIB)>>=
+${OUT}/IALGFACT.o: ${MID}/IALGFACT.NRLIB
+ @ echo 0 making ${OUT}/IALGFACT.o from ${MID}/IALGFACT.NRLIB
+ @ cp ${MID}/IALGFACT.NRLIB/code.o ${OUT}/IALGFACT.o
+
+@
+<<IALGFACT.NRLIB (NRLIB from MID)>>=
+${MID}/IALGFACT.NRLIB: ${MID}/IALGFACT.spad
+ @ echo 0 making ${MID}/IALGFACT.NRLIB from ${MID}/IALGFACT.spad
+ @ (cd ${MID} ; echo ')co IALGFACT.spad' | ${INTERPSYS} )
+
+@
+<<IALGFACT.spad (SPAD from IN)>>=
+${MID}/IALGFACT.spad: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${MID}/IALGFACT.spad from ${IN}/algfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IALGFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IALGFACT InnerAlgFactor" ${IN}/algfact.spad.pamphlet >IALGFACT.spad )
+
+@
+<<RFFACT.o (O from NRLIB)>>=
+${OUT}/RFFACT.o: ${MID}/RFFACT.NRLIB
+ @ echo 0 making ${OUT}/RFFACT.o from ${MID}/RFFACT.NRLIB
+ @ cp ${MID}/RFFACT.NRLIB/code.o ${OUT}/RFFACT.o
+
+@
+<<RFFACT.NRLIB (NRLIB from MID)>>=
+${MID}/RFFACT.NRLIB: ${MID}/RFFACT.spad
+ @ echo 0 making ${MID}/RFFACT.NRLIB from ${MID}/RFFACT.spad
+ @ (cd ${MID} ; echo ')co RFFACT.spad' | ${INTERPSYS} )
+
+@
+<<RFFACT.spad (SPAD from IN)>>=
+${MID}/RFFACT.spad: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${MID}/RFFACT.spad from ${IN}/algfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RFFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RFFACT RationalFunctionFactor" ${IN}/algfact.spad.pamphlet >RFFACT.spad )
+
+@
+<<SAEFACT.o (O from NRLIB)>>=
+${OUT}/SAEFACT.o: ${MID}/SAEFACT.NRLIB
+ @ echo 0 making ${OUT}/SAEFACT.o from ${MID}/SAEFACT.NRLIB
+ @ cp ${MID}/SAEFACT.NRLIB/code.o ${OUT}/SAEFACT.o
+
+@
+<<SAEFACT.NRLIB (NRLIB from MID)>>=
+${MID}/SAEFACT.NRLIB: ${MID}/SAEFACT.spad
+ @ echo 0 making ${MID}/SAEFACT.NRLIB from ${MID}/SAEFACT.spad
+ @ (cd ${MID} ; echo ')co SAEFACT.spad' | ${INTERPSYS} )
+
+@
+<<SAEFACT.spad (SPAD from IN)>>=
+${MID}/SAEFACT.spad: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${MID}/SAEFACT.spad from ${IN}/algfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SAEFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SAEFACT SimpleAlgebraicExtensionAlgFactor" ${IN}/algfact.spad.pamphlet >SAEFACT.spad )
+
+@
+<<SAERFFC.o (O from NRLIB)>>=
+${OUT}/SAERFFC.o: ${MID}/SAERFFC.NRLIB
+ @ echo 0 making ${OUT}/SAERFFC.o from ${MID}/SAERFFC.NRLIB
+ @ cp ${MID}/SAERFFC.NRLIB/code.o ${OUT}/SAERFFC.o
+
+@
+<<SAERFFC.NRLIB (NRLIB from MID)>>=
+${MID}/SAERFFC.NRLIB: ${MID}/SAERFFC.spad
+ @ echo 0 making ${MID}/SAERFFC.NRLIB from ${MID}/SAERFFC.spad
+ @ (cd ${MID} ; echo ')co SAERFFC.spad' | ${INTERPSYS} )
+
+@
+<<SAERFFC.spad (SPAD from IN)>>=
+${MID}/SAERFFC.spad: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${MID}/SAERFFC.spad from ${IN}/algfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SAERFFC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SAERFFC SAERationalFunctionAlgFactor" ${IN}/algfact.spad.pamphlet >SAERFFC.spad )
+
+@
+<<algfact.spad.dvi (DOC from IN)>>=
+${DOC}/algfact.spad.dvi: ${IN}/algfact.spad.pamphlet
+ @ echo 0 making ${DOC}/algfact.spad.dvi from ${IN}/algfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/algfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} algfact.spad ; \
+ rm -f ${DOC}/algfact.spad.pamphlet ; \
+ rm -f ${DOC}/algfact.spad.tex ; \
+ rm -f ${DOC}/algfact.spad )
+
+@
+\subsection{algfunc.spad \cite{1}}
+<<algfunc.spad (SPAD from IN)>>=
+${MID}/algfunc.spad: ${IN}/algfunc.spad.pamphlet
+ @ echo 0 making ${MID}/algfunc.spad from ${IN}/algfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/algfunc.spad.pamphlet >algfunc.spad )
+
+@
+<<ACF-.o (O from NRLIB)>>=
+${OUT}/ACF-.o: ${MID}/ACF.NRLIB
+ @ echo 0 making ${OUT}/ACF-.o from ${MID}/ACF-.NRLIB
+ @ cp ${MID}/ACF-.NRLIB/code.o ${OUT}/ACF-.o
+
+@
+<<ACF-.NRLIB (NRLIB from MID)>>=
+${MID}/ACF-.NRLIB: ${OUT}/TYPE.o ${MID}/ACF.spad
+ @ echo 0 making ${MID}/ACF-.NRLIB from ${MID}/ACF.spad
+ @ (cd ${MID} ; echo ')co ACF.spad' | ${INTERPSYS} )
+
+@
+<<ACF.o (O from NRLIB)>>=
+${OUT}/ACF.o: ${MID}/ACF.NRLIB
+ @ echo 0 making ${OUT}/ACF.o from ${MID}/ACF.NRLIB
+ @ cp ${MID}/ACF.NRLIB/code.o ${OUT}/ACF.o
+
+@
+<<ACF.NRLIB (NRLIB from MID)>>=
+${MID}/ACF.NRLIB: ${MID}/ACF.spad
+ @ echo 0 making ${MID}/ACF.NRLIB from ${MID}/ACF.spad
+ @ (cd ${MID} ; echo ')co ACF.spad' | ${INTERPSYS} )
+
+@
+<<ACF.spad (SPAD from IN)>>=
+${MID}/ACF.spad: ${IN}/algfunc.spad.pamphlet
+ @ echo 0 making ${MID}/ACF.spad from ${IN}/algfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ACF.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ACF AlgebraicallyClosedField" ${IN}/algfunc.spad.pamphlet >ACF.spad )
+
+@
+<<ACFS-.o (O from NRLIB)>>=
+${OUT}/ACFS-.o: ${MID}/ACFS.NRLIB
+ @ echo 0 making ${OUT}/ACFS-.o from ${MID}/ACFS-.NRLIB
+ @ cp ${MID}/ACFS-.NRLIB/code.o ${OUT}/ACFS-.o
+
+@
+<<ACFS-.NRLIB (NRLIB from MID)>>=
+${MID}/ACFS-.NRLIB: ${OUT}/TYPE.o ${MID}/ACFS.spad
+ @ echo 0 making ${MID}/ACFS-.NRLIB from ${MID}/ACFS.spad
+ @ (cd ${MID} ; echo ')co ACFS.spad' | ${INTERPSYS} )
+
+@
+<<ACFS.o (O from NRLIB)>>=
+${OUT}/ACFS.o: ${MID}/ACFS.NRLIB
+ @ echo 0 making ${OUT}/ACFS.o from ${MID}/ACFS.NRLIB
+ @ cp ${MID}/ACFS.NRLIB/code.o ${OUT}/ACFS.o
+
+@
+<<ACFS.NRLIB (NRLIB from MID)>>=
+${MID}/ACFS.NRLIB: ${MID}/ACFS.spad
+ @ echo 0 making ${MID}/ACFS.NRLIB from ${MID}/ACFS.spad
+ @ (cd ${MID} ; echo ')co ACFS.spad' | ${INTERPSYS} )
+
+@
+<<ACFS.spad (SPAD from IN)>>=
+${MID}/ACFS.spad: ${IN}/algfunc.spad.pamphlet
+ @ echo 0 making ${MID}/ACFS.spad from ${IN}/algfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ACFS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ACFS AlgebraicallyClosedFunctionSpace" ${IN}/algfunc.spad.pamphlet >ACFS.spad )
+
+@
+<<AF.o (O from NRLIB)>>=
+${OUT}/AF.o: ${MID}/AF.NRLIB
+ @ echo 0 making ${OUT}/AF.o from ${MID}/AF.NRLIB
+ @ cp ${MID}/AF.NRLIB/code.o ${OUT}/AF.o
+
+@
+<<AF.NRLIB (NRLIB from MID)>>=
+${MID}/AF.NRLIB: ${MID}/AF.spad
+ @ echo 0 making ${MID}/AF.NRLIB from ${MID}/AF.spad
+ @ (cd ${MID} ; echo ')co AF.spad' | ${INTERPSYS} )
+
+@
+<<AF.spad (SPAD from IN)>>=
+${MID}/AF.spad: ${IN}/algfunc.spad.pamphlet
+ @ echo 0 making ${MID}/AF.spad from ${IN}/algfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf AF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package AF AlgebraicFunction" ${IN}/algfunc.spad.pamphlet >AF.spad )
+
+@
+<<algfunc.spad.dvi (DOC from IN)>>=
+${DOC}/algfunc.spad.dvi: ${IN}/algfunc.spad.pamphlet
+ @ echo 0 making ${DOC}/algfunc.spad.dvi from ${IN}/algfunc.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/algfunc.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} algfunc.spad ; \
+ rm -f ${DOC}/algfunc.spad.pamphlet ; \
+ rm -f ${DOC}/algfunc.spad.tex ; \
+ rm -f ${DOC}/algfunc.spad )
+
+@
+\subsection{allfact.spad \cite{1}}
+<<allfact.spad (SPAD from IN)>>=
+${MID}/allfact.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/allfact.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/allfact.spad.pamphlet >allfact.spad )
+
+@
+<<GENMFACT.o (O from NRLIB)>>=
+${OUT}/GENMFACT.o: ${MID}/GENMFACT.NRLIB
+ @ echo 0 making ${OUT}/GENMFACT.o from ${MID}/GENMFACT.NRLIB
+ @ cp ${MID}/GENMFACT.NRLIB/code.o ${OUT}/GENMFACT.o
+
+@
+<<GENMFACT.NRLIB (NRLIB from MID)>>=
+${MID}/GENMFACT.NRLIB: ${MID}/GENMFACT.spad
+ @ echo 0 making ${MID}/GENMFACT.NRLIB from ${MID}/GENMFACT.spad
+ @ (cd ${MID} ; echo ')co GENMFACT.spad' | ${INTERPSYS} )
+
+@
+<<GENMFACT.spad (SPAD from IN)>>=
+${MID}/GENMFACT.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/GENMFACT.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GENMFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GENMFACT GeneralizedMultivariateFactorize" ${IN}/allfact.spad.pamphlet >GENMFACT.spad )
+
+@
+<<MPCPF.o (O from NRLIB)>>=
+${OUT}/MPCPF.o: ${MID}/MPCPF.NRLIB
+ @ echo 0 making ${OUT}/MPCPF.o from ${MID}/MPCPF.NRLIB
+ @ cp ${MID}/MPCPF.NRLIB/code.o ${OUT}/MPCPF.o
+
+@
+<<MPCPF.NRLIB (NRLIB from MID)>>=
+${MID}/MPCPF.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MPCPF.spad
+ @ echo 0 making ${MID}/MPCPF.NRLIB from ${MID}/MPCPF.spad
+ @ (cd ${MID} ; echo ')co MPCPF.spad' | ${INTERPSYS} )
+
+@
+<<MPCPF.spad (SPAD from IN)>>=
+${MID}/MPCPF.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/MPCPF.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MPCPF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MPCPF MPolyCatPolyFactorizer" ${IN}/allfact.spad.pamphlet >MPCPF.spad )
+
+@
+<<MPRFF.o (O from NRLIB)>>=
+${OUT}/MPRFF.o: ${MID}/MPRFF.NRLIB
+ @ echo 0 making ${OUT}/MPRFF.o from ${MID}/MPRFF.NRLIB
+ @ cp ${MID}/MPRFF.NRLIB/code.o ${OUT}/MPRFF.o
+
+@
+<<MPRFF.NRLIB (NRLIB from MID)>>=
+${MID}/MPRFF.NRLIB: ${MID}/MPRFF.spad
+ @ echo 0 making ${MID}/MPRFF.NRLIB from ${MID}/MPRFF.spad
+ @ (cd ${MID} ; echo ')co MPRFF.spad' | ${INTERPSYS} )
+
+@
+<<MPRFF.spad (SPAD from IN)>>=
+${MID}/MPRFF.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/MPRFF.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MPRFF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MPRFF MPolyCatRationalFunctionFactorizer" ${IN}/allfact.spad.pamphlet >MPRFF.spad )
+
+@
+<<MRATFAC.o (O from NRLIB)>>=
+${OUT}/MRATFAC.o: ${MID}/MRATFAC.NRLIB
+ @ echo 0 making ${OUT}/MRATFAC.o from ${MID}/MRATFAC.NRLIB
+ @ cp ${MID}/MRATFAC.NRLIB/code.o ${OUT}/MRATFAC.o
+
+@
+<<MRATFAC.NRLIB (NRLIB from MID)>>=
+${MID}/MRATFAC.NRLIB: ${MID}/MRATFAC.spad
+ @ echo 0 making ${MID}/MRATFAC.NRLIB from ${MID}/MRATFAC.spad
+ @ (cd ${MID} ; echo ')co MRATFAC.spad' | ${INTERPSYS} )
+
+@
+<<MRATFAC.spad (SPAD from IN)>>=
+${MID}/MRATFAC.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/MRATFAC.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MRATFAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MRATFAC MRationalFactorize" ${IN}/allfact.spad.pamphlet >MRATFAC.spad )
+
+@
+<<RFFACTOR.o (O from NRLIB)>>=
+${OUT}/RFFACTOR.o: ${MID}/RFFACTOR.NRLIB
+ @ echo 0 making ${OUT}/RFFACTOR.o from ${MID}/RFFACTOR.NRLIB
+ @ cp ${MID}/RFFACTOR.NRLIB/code.o ${OUT}/RFFACTOR.o
+
+@
+<<RFFACTOR.NRLIB (NRLIB from MID)>>=
+${MID}/RFFACTOR.NRLIB: ${MID}/RFFACTOR.spad
+ @ echo 0 making ${MID}/RFFACTOR.NRLIB from ${MID}/RFFACTOR.spad
+ @ (cd ${MID} ; echo ')co RFFACTOR.spad' | ${INTERPSYS} )
+
+@
+<<RFFACTOR.spad (SPAD from IN)>>=
+${MID}/RFFACTOR.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/RFFACTOR.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RFFACTOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RFFACTOR RationalFunctionFactorizer" ${IN}/allfact.spad.pamphlet >RFFACTOR.spad )
+
+@
+<<SUPFRACF.o (O from NRLIB)>>=
+${OUT}/SUPFRACF.o: ${MID}/SUPFRACF.NRLIB
+ @ echo 0 making ${OUT}/SUPFRACF.o from ${MID}/SUPFRACF.NRLIB
+ @ cp ${MID}/SUPFRACF.NRLIB/code.o ${OUT}/SUPFRACF.o
+
+@
+<<SUPFRACF.NRLIB (NRLIB from MID)>>=
+${MID}/SUPFRACF.NRLIB: ${MID}/SUPFRACF.spad
+ @ echo 0 making ${MID}/SUPFRACF.NRLIB from ${MID}/SUPFRACF.spad
+ @ (cd ${MID} ; echo ')co SUPFRACF.spad' | ${INTERPSYS} )
+
+@
+<<SUPFRACF.spad (SPAD from IN)>>=
+${MID}/SUPFRACF.spad: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${MID}/SUPFRACF.spad from ${IN}/allfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUPFRACF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SUPFRACF SupFractionFactorizer" ${IN}/allfact.spad.pamphlet >SUPFRACF.spad )
+
+@
+<<allfact.spad.dvi (DOC from IN)>>=
+${DOC}/allfact.spad.dvi: ${IN}/allfact.spad.pamphlet
+ @ echo 0 making ${DOC}/allfact.spad.dvi from ${IN}/allfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/allfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} allfact.spad ; \
+ rm -f ${DOC}/allfact.spad.pamphlet ; \
+ rm -f ${DOC}/allfact.spad.tex ; \
+ rm -f ${DOC}/allfact.spad )
+
+@
+\subsection{alql.spad \cite{1}}
+<<alql.spad (SPAD from IN)>>=
+${MID}/alql.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/alql.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/alql.spad.pamphlet >alql.spad )
+
+@
+<<DBASE.o (O from NRLIB)>>=
+${OUT}/DBASE.o: ${MID}/DBASE.NRLIB
+ @ echo 0 making ${OUT}/DBASE.o from ${MID}/DBASE.NRLIB
+ @ cp ${MID}/DBASE.NRLIB/code.o ${OUT}/DBASE.o
+
+@
+<<DBASE.NRLIB (NRLIB from MID)>>=
+${MID}/DBASE.NRLIB: ${MID}/DBASE.spad
+ @ echo 0 making ${MID}/DBASE.NRLIB from ${MID}/DBASE.spad
+ @ (cd ${MID} ; echo ')co DBASE.spad' | ${INTERPSYS} )
+
+@
+<<DBASE.spad (SPAD from IN)>>=
+${MID}/DBASE.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/DBASE.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DBASE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DBASE Database" ${IN}/alql.spad.pamphlet >DBASE.spad )
+
+@
+<<DLIST.o (O from NRLIB)>>=
+${OUT}/DLIST.o: ${MID}/DLIST.NRLIB
+ @ echo 0 making ${OUT}/DLIST.o from ${MID}/DLIST.NRLIB
+ @ cp ${MID}/DLIST.NRLIB/code.o ${OUT}/DLIST.o
+
+@
+<<DLIST.NRLIB (NRLIB from MID)>>=
+${MID}/DLIST.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DLIST.spad
+ @ echo 0 making ${MID}/DLIST.NRLIB from ${MID}/DLIST.spad
+ @ (cd ${MID} ; echo ')co DLIST.spad' | ${INTERPSYS} )
+
+@
+<<DLIST.spad (SPAD from IN)>>=
+${MID}/DLIST.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/DLIST.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DLIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DLIST DataList" ${IN}/alql.spad.pamphlet >DLIST.spad )
+
+@
+<<ICARD.o (O from NRLIB)>>=
+${OUT}/ICARD.o: ${MID}/ICARD.NRLIB
+ @ echo 0 making ${OUT}/ICARD.o from ${MID}/ICARD.NRLIB
+ @ cp ${MID}/ICARD.NRLIB/code.o ${OUT}/ICARD.o
+
+@
+<<ICARD.NRLIB (NRLIB from MID)>>=
+${MID}/ICARD.NRLIB: ${MID}/ICARD.spad
+ @ echo 0 making ${MID}/ICARD.NRLIB from ${MID}/ICARD.spad
+ @ (cd ${MID} ; echo ')co ICARD.spad' | ${INTERPSYS} )
+
+@
+<<ICARD.spad (SPAD from IN)>>=
+${MID}/ICARD.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/ICARD.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ICARD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ICARD IndexCard" ${IN}/alql.spad.pamphlet >ICARD.spad )
+
+@
+<<MTHING.o (O from NRLIB)>>=
+${OUT}/MTHING.o: ${MID}/MTHING.NRLIB
+ @ echo 0 making ${OUT}/MTHING.o from ${MID}/MTHING.NRLIB
+ @ cp ${MID}/MTHING.NRLIB/code.o ${OUT}/MTHING.o
+
+@
+<<MTHING.NRLIB (NRLIB from MID)>>=
+${MID}/MTHING.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MTHING.spad
+ @ echo 0 making ${MID}/MTHING.NRLIB from ${MID}/MTHING.spad
+ @ (cd ${MID} ; echo ')co MTHING.spad' | ${INTERPSYS} )
+
+@
+<<MTHING.spad (SPAD from IN)>>=
+${MID}/MTHING.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/MTHING.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MTHING.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MTHING MergeThing" ${IN}/alql.spad.pamphlet >MTHING.spad )
+
+@
+<<OPQUERY.o (O from NRLIB)>>=
+${OUT}/OPQUERY.o: ${MID}/OPQUERY.NRLIB
+ @ echo 0 making ${OUT}/OPQUERY.o from ${MID}/OPQUERY.NRLIB
+ @ cp ${MID}/OPQUERY.NRLIB/code.o ${OUT}/OPQUERY.o
+
+@
+<<OPQUERY.NRLIB (NRLIB from MID)>>=
+${MID}/OPQUERY.NRLIB: ${OUT}/TYPE.o ${MID}/OPQUERY.spad
+ @ echo 0 making ${MID}/OPQUERY.NRLIB from ${MID}/OPQUERY.spad
+ @ (cd ${MID} ; echo ')co OPQUERY.spad' | ${INTERPSYS} )
+
+@
+<<OPQUERY.spad (SPAD from IN)>>=
+${MID}/OPQUERY.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/OPQUERY.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OPQUERY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OPQUERY OperationsQuery" ${IN}/alql.spad.pamphlet >OPQUERY.spad )
+
+@
+<<QEQUAT.o (O from NRLIB)>>=
+${OUT}/QEQUAT.o: ${MID}/QEQUAT.NRLIB
+ @ echo 0 making ${OUT}/QEQUAT.o from ${MID}/QEQUAT.NRLIB
+ @ cp ${MID}/QEQUAT.NRLIB/code.o ${OUT}/QEQUAT.o
+
+@
+<<QEQUAT.NRLIB (NRLIB from MID)>>=
+${MID}/QEQUAT.NRLIB: ${MID}/QEQUAT.spad
+ @ echo 0 making ${MID}/QEQUAT.NRLIB from ${MID}/QEQUAT.spad
+ @ (cd ${MID} ; echo ')co QEQUAT.spad' | ${INTERPSYS} )
+
+@
+<<QEQUAT.spad (SPAD from IN)>>=
+${MID}/QEQUAT.spad: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${MID}/QEQUAT.spad from ${IN}/alql.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QEQUAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain QEQUAT QueryEquation" ${IN}/alql.spad.pamphlet >QEQUAT.spad )
+
+@
+<<alql.spad.dvi (DOC from IN)>>=
+${DOC}/alql.spad.dvi: ${IN}/alql.spad.pamphlet
+ @ echo 0 making ${DOC}/alql.spad.dvi from ${IN}/alql.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/alql.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} alql.spad ; \
+ rm -f ${DOC}/alql.spad.pamphlet ; \
+ rm -f ${DOC}/alql.spad.tex ; \
+ rm -f ${DOC}/alql.spad )
+
+@
+\subsection{annacat.spad \cite{1}}
+<<annacat.spad (SPAD from IN)>>=
+${MID}/annacat.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/annacat.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/annacat.spad.pamphlet >annacat.spad )
+
+@
+<<NIPROB.o (O from NRLIB)>>=
+${OUT}/NIPROB.o: ${MID}/NIPROB.NRLIB
+ @ echo 0 making ${OUT}/NIPROB.o from ${MID}/NIPROB.NRLIB
+ @ cp ${MID}/NIPROB.NRLIB/code.o ${OUT}/NIPROB.o
+
+@
+<<NIPROB.NRLIB (NRLIB from MID)>>=
+${MID}/NIPROB.NRLIB: ${MID}/NIPROB.spad
+ @ echo 0 making ${MID}/NIPROB.NRLIB from ${MID}/NIPROB.spad
+ @ (cd ${MID} ; echo ')co NIPROB.spad' | ${INTERPSYS} )
+
+@
+<<NIPROB.spad (SPAD from IN)>>=
+${MID}/NIPROB.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/NIPROB.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NIPROB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain NIPROB NumericalIntegrationProblem" ${IN}/annacat.spad.pamphlet >NIPROB.spad )
+
+@
+<<NUMINT.o (O from NRLIB)>>=
+${OUT}/NUMINT.o: ${MID}/NUMINT.NRLIB
+ @ echo 0 making ${OUT}/NUMINT.o from ${MID}/NUMINT.NRLIB
+ @ cp ${MID}/NUMINT.NRLIB/code.o ${OUT}/NUMINT.o
+
+@
+<<NUMINT.NRLIB (NRLIB from MID)>>=
+${MID}/NUMINT.NRLIB: ${OUT}/TYPE.o ${MID}/NUMINT.spad
+ @ echo 0 making ${MID}/NUMINT.NRLIB from ${MID}/NUMINT.spad
+ @ (cd ${MID} ; echo ')co NUMINT.spad' | ${INTERPSYS} )
+
+@
+<<NUMINT.spad (SPAD from IN)>>=
+${MID}/NUMINT.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/NUMINT.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NUMINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category NUMINT NumericalIntegrationCategory" ${IN}/annacat.spad.pamphlet >NUMINT.spad )
+
+@
+<<ODECAT.o (O from NRLIB)>>=
+${OUT}/ODECAT.o: ${MID}/ODECAT.NRLIB
+ @ echo 0 making ${OUT}/ODECAT.o from ${MID}/ODECAT.NRLIB
+ @ cp ${MID}/ODECAT.NRLIB/code.o ${OUT}/ODECAT.o
+
+@
+<<ODECAT.NRLIB (NRLIB from MID)>>=
+${MID}/ODECAT.NRLIB: ${OUT}/TYPE.o ${MID}/ODECAT.spad
+ @ echo 0 making ${MID}/ODECAT.NRLIB from ${MID}/ODECAT.spad
+ @ (cd ${MID} ; echo ')co ODECAT.spad' | ${INTERPSYS} )
+
+@
+<<ODECAT.spad (SPAD from IN)>>=
+${MID}/ODECAT.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/ODECAT.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODECAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ODECAT OrdinaryDifferentialEquationsSolverCategory" ${IN}/annacat.spad.pamphlet >ODECAT.spad )
+
+@
+<<ODEPROB.o (O from NRLIB)>>=
+${OUT}/ODEPROB.o: ${MID}/ODEPROB.NRLIB
+ @ echo 0 making ${OUT}/ODEPROB.o from ${MID}/ODEPROB.NRLIB
+ @ cp ${MID}/ODEPROB.NRLIB/code.o ${OUT}/ODEPROB.o
+
+@
+<<ODEPROB.NRLIB (NRLIB from MID)>>=
+${MID}/ODEPROB.NRLIB: ${MID}/ODEPROB.spad
+ @ echo 0 making ${MID}/ODEPROB.NRLIB from ${MID}/ODEPROB.spad
+ @ (cd ${MID} ; echo ')co ODEPROB.spad' | ${INTERPSYS} )
+
+@
+<<ODEPROB.spad (SPAD from IN)>>=
+${MID}/ODEPROB.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/ODEPROB.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEPROB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ODEPROB NumericalODEProblem" ${IN}/annacat.spad.pamphlet >ODEPROB.spad )
+
+@
+<<OPTPROB.o (O from NRLIB)>>=
+${OUT}/OPTPROB.o: ${MID}/OPTPROB.NRLIB
+ @ echo 0 making ${OUT}/OPTPROB.o from ${MID}/OPTPROB.NRLIB
+ @ cp ${MID}/OPTPROB.NRLIB/code.o ${OUT}/OPTPROB.o
+
+@
+<<OPTPROB.NRLIB (NRLIB from MID)>>=
+${MID}/OPTPROB.NRLIB: ${MID}/OPTPROB.spad
+ @ echo 0 making ${MID}/OPTPROB.NRLIB from ${MID}/OPTPROB.spad
+ @ (cd ${MID} ; echo ')co OPTPROB.spad' | ${INTERPSYS} )
+
+@
+<<OPTPROB.spad (SPAD from IN)>>=
+${MID}/OPTPROB.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/OPTPROB.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OPTPROB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OPTPROB NumericalOptimizationProblem" ${IN}/annacat.spad.pamphlet >OPTPROB.spad )
+
+@
+<<PDECAT.o (O from NRLIB)>>=
+${OUT}/PDECAT.o: ${MID}/PDECAT.NRLIB
+ @ echo 0 making ${OUT}/PDECAT.o from ${MID}/PDECAT.NRLIB
+ @ cp ${MID}/PDECAT.NRLIB/code.o ${OUT}/PDECAT.o
+
+@
+<<PDECAT.NRLIB (NRLIB from MID)>>=
+${MID}/PDECAT.NRLIB: ${OUT}/TYPE.o ${MID}/PDECAT.spad
+ @ echo 0 making ${MID}/PDECAT.NRLIB from ${MID}/PDECAT.spad
+ @ (cd ${MID} ; echo ')co PDECAT.spad' | ${INTERPSYS} )
+
+@
+<<PDECAT.spad (SPAD from IN)>>=
+${MID}/PDECAT.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/PDECAT.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PDECAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PDECAT PartialDifferentialEquationsSolverCategory" ${IN}/annacat.spad.pamphlet >PDECAT.spad )
+
+@
+<<PDEPROB.o (O from NRLIB)>>=
+${OUT}/PDEPROB.o: ${MID}/PDEPROB.NRLIB
+ @ echo 0 making ${OUT}/PDEPROB.o from ${MID}/PDEPROB.NRLIB
+ @ cp ${MID}/PDEPROB.NRLIB/code.o ${OUT}/PDEPROB.o
+
+@
+<<PDEPROB.NRLIB (NRLIB from MID)>>=
+${MID}/PDEPROB.NRLIB: ${MID}/PDEPROB.spad
+ @ echo 0 making ${MID}/PDEPROB.NRLIB from ${MID}/PDEPROB.spad
+ @ (cd ${MID} ; echo ')co PDEPROB.spad' | ${INTERPSYS} )
+
+@
+<<PDEPROB.spad (SPAD from IN)>>=
+${MID}/PDEPROB.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/PDEPROB.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PDEPROB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PDEPROB NumericalPDEProblem" ${IN}/annacat.spad.pamphlet >PDEPROB.spad )
+
+@
+<<OPTCAT.o (O from NRLIB)>>=
+${OUT}/OPTCAT.o: ${MID}/OPTCAT.NRLIB
+ @ echo 0 making ${OUT}/OPTCAT.o from ${MID}/OPTCAT.NRLIB
+ @ cp ${MID}/OPTCAT.NRLIB/code.o ${OUT}/OPTCAT.o
+
+@
+<<OPTCAT.NRLIB (NRLIB from MID)>>=
+${MID}/OPTCAT.NRLIB: ${OUT}/TYPE.o ${MID}/OPTCAT.spad
+ @ echo 0 making ${MID}/OPTCAT.NRLIB from ${MID}/OPTCAT.spad
+ @ (cd ${MID} ; echo ')co OPTCAT.spad' | ${INTERPSYS} )
+
+@
+<<OPTCAT.spad (SPAD from IN)>>=
+${MID}/OPTCAT.spad: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${MID}/OPTCAT.spad from ${IN}/annacat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OPTCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OPTCAT NumericalOptimizationCategory" ${IN}/annacat.spad.pamphlet >OPTCAT.spad )
+
+@
+<<annacat.spad.dvi (DOC from IN)>>=
+${DOC}/annacat.spad.dvi: ${IN}/annacat.spad.pamphlet
+ @ echo 0 making ${DOC}/annacat.spad.dvi from ${IN}/annacat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/annacat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} annacat.spad ; \
+ rm -f ${DOC}/annacat.spad.pamphlet ; \
+ rm -f ${DOC}/annacat.spad.tex ; \
+ rm -f ${DOC}/annacat.spad )
+
+@
+\subsection{any.spad \cite{1}}
+<<any.spad (SPAD from IN)>>=
+${MID}/any.spad: ${IN}/any.spad.pamphlet
+ @ echo 0 making ${MID}/any.spad from ${IN}/any.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/any.spad.pamphlet >any.spad )
+
+@
+<<ANY.o (O from NRLIB)>>=
+${OUT}/ANY.o: ${MID}/ANY.NRLIB
+ @ echo 0 making ${OUT}/ANY.o from ${MID}/ANY.NRLIB
+ @ cp ${MID}/ANY.NRLIB/code.o ${OUT}/ANY.o
+
+@
+<<ANY.NRLIB (NRLIB from MID)>>=
+${MID}/ANY.NRLIB: ${MID}/ANY.spad
+ @ echo 0 making ${MID}/ANY.NRLIB from ${MID}/ANY.spad
+ @ (cd ${MID} ; echo ')co ANY.spad' | ${INTERPSYS} )
+
+@
+<<ANY.spad (SPAD from IN)>>=
+${MID}/ANY.spad: ${IN}/any.spad.pamphlet
+ @ echo 0 making ${MID}/ANY.spad from ${IN}/any.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ANY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ANY Any" ${IN}/any.spad.pamphlet >ANY.spad )
+
+@
+<<ANY1.o (O from NRLIB)>>=
+${OUT}/ANY1.o: ${MID}/ANY1.NRLIB
+ @ echo 0 making ${OUT}/ANY1.o from ${MID}/ANY1.NRLIB
+ @ cp ${MID}/ANY1.NRLIB/code.o ${OUT}/ANY1.o
+
+@
+<<ANY1.NRLIB (NRLIB from MID)>>=
+${MID}/ANY1.NRLIB: ${OUT}/TYPE.o ${MID}/ANY1.spad
+ @ echo 0 making ${MID}/ANY1.NRLIB from ${MID}/ANY1.spad
+ @ (cd ${MID} ; echo ')co ANY1.spad' | ${INTERPSYS} )
+
+@
+<<ANY1.spad (SPAD from IN)>>=
+${MID}/ANY1.spad: ${IN}/any.spad.pamphlet
+ @ echo 0 making ${MID}/ANY1.spad from ${IN}/any.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ANY1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ANY1 AnyFunctions1" ${IN}/any.spad.pamphlet >ANY1.spad )
+
+@
+<<NONE1.o (O from NRLIB)>>=
+${OUT}/NONE1.o: ${MID}/NONE1.NRLIB
+ @ echo 0 making ${OUT}/NONE1.o from ${MID}/NONE1.NRLIB
+ @ cp ${MID}/NONE1.NRLIB/code.o ${OUT}/NONE1.o
+
+@
+<<NONE1.NRLIB (NRLIB from MID)>>=
+${MID}/NONE1.NRLIB: ${OUT}/TYPE.o ${MID}/NONE1.spad
+ @ echo 0 making ${MID}/NONE1.NRLIB from ${MID}/NONE1.spad
+ @ (cd ${MID} ; echo ')co NONE1.spad' | ${INTERPSYS} )
+
+@
+<<NONE1.spad (SPAD from IN)>>=
+${MID}/NONE1.spad: ${IN}/any.spad.pamphlet
+ @ echo 0 making ${MID}/NONE1.spad from ${IN}/any.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NONE1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NONE1 NoneFunctions1" ${IN}/any.spad.pamphlet >NONE1.spad )
+
+@
+<<NONE.o (O from NRLIB)>>=
+${OUT}/NONE.o: ${MID}/NONE.NRLIB
+ @ echo 0 making ${OUT}/NONE.o from ${MID}/NONE.NRLIB
+ @ cp ${MID}/NONE.NRLIB/code.o ${OUT}/NONE.o
+
+@
+<<NONE.NRLIB (NRLIB from MID)>>=
+${MID}/NONE.NRLIB: ${OUT}/TYPE.o ${MID}/NONE.spad
+ @ echo 0 making ${MID}/NONE.NRLIB from ${MID}/NONE.spad
+ @ (cd ${MID} ; echo ')co NONE.spad' | ${INTERPSYS} )
+
+@
+<<NONE.spad (SPAD from IN)>>=
+${MID}/NONE.spad: ${IN}/any.spad.pamphlet
+ @ echo 0 making ${MID}/NONE.spad from ${IN}/any.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NONE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain NONE None" ${IN}/any.spad.pamphlet >NONE.spad )
+
+@
+<<any.spad.dvi (DOC from IN)>>=
+${DOC}/any.spad.dvi: ${IN}/any.spad.pamphlet
+ @ echo 0 making ${DOC}/any.spad.dvi from ${IN}/any.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/any.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} any.spad ; \
+ rm -f ${DOC}/any.spad.pamphlet ; \
+ rm -f ${DOC}/any.spad.tex ; \
+ rm -f ${DOC}/any.spad )
+
+@
+\subsection{array1.spad \cite{1}}
+<<array1.spad (SPAD from IN)>>=
+${MID}/array1.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/array1.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/array1.spad.pamphlet >array1.spad )
+
+@
+<<ARRAY1.o (O from NRLIB)>>=
+${OUT}/ARRAY1.o: ${MID}/ARRAY1.NRLIB
+ @ echo 0 making ${OUT}/ARRAY1.o from ${MID}/ARRAY1.NRLIB
+ @ cp ${MID}/ARRAY1.NRLIB/code.o ${OUT}/ARRAY1.o
+
+@
+<<ARRAY1.NRLIB (NRLIB from MID)>>=
+${MID}/ARRAY1.NRLIB: ${MID}/ARRAY1.spad
+ @ echo 0 making ${MID}/ARRAY1.NRLIB from ${MID}/ARRAY1.spad
+ @ (cd ${MID} ; echo ')co ARRAY1.spad' | ${INTERPSYS} )
+
+@
+<<ARRAY1.spad (SPAD from IN)>>=
+${MID}/ARRAY1.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/ARRAY1.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ARRAY1.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ARRAY1 OneDimensionalArray" ${IN}/array1.spad.pamphlet >ARRAY1.spad )
+
+@
+<<ARRAY12.o (O from NRLIB)>>=
+${OUT}/ARRAY12.o: ${MID}/ARRAY12.NRLIB
+ @ echo 0 making ${OUT}/ARRAY12.o from ${MID}/ARRAY12.NRLIB
+ @ cp ${MID}/ARRAY12.NRLIB/code.o ${OUT}/ARRAY12.o
+
+@
+<<ARRAY12.NRLIB (NRLIB from MID)>>=
+${MID}/ARRAY12.NRLIB: ${MID}/ARRAY12.spad
+ @ echo 0 making ${MID}/ARRAY12.NRLIB from ${MID}/ARRAY12.spad
+ @ (cd ${MID} ; echo ')co ARRAY12.spad' | ${INTERPSYS} )
+
+@
+<<ARRAY12.spad (SPAD from IN)>>=
+${MID}/ARRAY12.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/ARRAY12.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ARRAY12.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ARRAY12 OneDimensionalArrayFunctions2" ${IN}/array1.spad.pamphlet >ARRAY12.spad )
+
+@
+<<FARRAY.o (O from NRLIB)>>=
+${OUT}/FARRAY.o: ${MID}/FARRAY.NRLIB
+ @ echo 0 making ${OUT}/FARRAY.o from ${MID}/FARRAY.NRLIB
+ @ cp ${MID}/FARRAY.NRLIB/code.o ${OUT}/FARRAY.o
+
+@
+<<FARRAY.NRLIB (NRLIB from MID)>>=
+${MID}/FARRAY.NRLIB: ${MID}/FARRAY.spad
+ @ echo 0 making ${MID}/FARRAY.NRLIB from ${MID}/FARRAY.spad
+ @ (cd ${MID} ; echo ')co FARRAY.spad' | ${INTERPSYS} )
+
+@
+<<FARRAY.spad (SPAD from IN)>>=
+${MID}/FARRAY.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/FARRAY.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FARRAY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FARRAY FlexibleArray" ${IN}/array1.spad.pamphlet >FARRAY.spad )
+
+@
+<<IARRAY1.o (O from NRLIB)>>=
+${OUT}/IARRAY1.o: ${MID}/IARRAY1.NRLIB
+ @ echo 0 making ${OUT}/IARRAY1.o from ${MID}/IARRAY1.NRLIB
+ @ cp ${MID}/IARRAY1.NRLIB/code.o ${OUT}/IARRAY1.o
+
+@
+<<IARRAY1.NRLIB (NRLIB from MID)>>=
+${MID}/IARRAY1.NRLIB: ${MID}/IARRAY1.spad
+ @ echo 0 making ${MID}/IARRAY1.NRLIB from ${MID}/IARRAY1.spad
+ @ (cd ${MID} ; echo ')co IARRAY1.spad' | ${INTERPSYS} )
+
+@
+<<IARRAY1.spad (SPAD from IN)>>=
+${MID}/IARRAY1.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/IARRAY1.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IARRAY1.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IARRAY1 IndexedOneDimensionalArray" ${IN}/array1.spad.pamphlet >IARRAY1.spad )
+
+@
+<<IFARRAY.o (O from NRLIB)>>=
+${OUT}/IFARRAY.o: ${MID}/IFARRAY.NRLIB
+ @ echo 0 making ${OUT}/IFARRAY.o from ${MID}/IFARRAY.NRLIB
+ @ cp ${MID}/IFARRAY.NRLIB/code.o ${OUT}/IFARRAY.o
+
+@
+<<IFARRAY.NRLIB (NRLIB from MID)>>=
+${MID}/IFARRAY.NRLIB: ${MID}/IFARRAY.spad
+ @ echo 0 making ${MID}/IFARRAY.NRLIB from ${MID}/IFARRAY.spad
+ @ (cd ${MID} ; echo ')co IFARRAY.spad' | ${INTERPSYS} )
+
+@
+<<IFARRAY.spad (SPAD from IN)>>=
+${MID}/IFARRAY.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/IFARRAY.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IFARRAY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IFARRAY IndexedFlexibleArray" ${IN}/array1.spad.pamphlet >IFARRAY.spad )
+
+@
+<<PRIMARR.o (O from NRLIB)>>=
+${OUT}/PRIMARR.o: ${MID}/PRIMARR.NRLIB
+ @ echo 0 making ${OUT}/PRIMARR.o from ${MID}/PRIMARR.NRLIB
+ @ cp ${MID}/PRIMARR.NRLIB/code.o ${OUT}/PRIMARR.o
+
+@
+<<PRIMARR.NRLIB (NRLIB from MID)>>=
+${MID}/PRIMARR.NRLIB: ${MID}/PRIMARR.spad
+ @ echo 0 making ${MID}/PRIMARR.NRLIB from ${MID}/PRIMARR.spad
+ @ (cd ${MID} ; echo ')co PRIMARR.spad' | ${INTERPSYS} )
+
+@
+<<PRIMARR.spad (SPAD from IN)>>=
+${MID}/PRIMARR.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/PRIMARR.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRIMARR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PRIMARR PrimitiveArray" ${IN}/array1.spad.pamphlet >PRIMARR.spad )
+
+@
+<<PRIMARR.o (BOOTSTRAP from MID)>>=
+${MID}/PRIMARR.o: ${MID}/PRIMARR.lsp
+ @ echo 0 making ${MID}/PRIMARR.o from ${MID}/PRIMARR.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "PRIMARR.lsp" :output-file "PRIMARR.o"))' | ${DEPSYS} )
+ @ cp ${MID}/PRIMARR.o ${OUT}/PRIMARR.o
+
+@
+<<PRIMARR.lsp (LISP from IN)>>=
+${MID}/PRIMARR.lsp: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/PRIMARR.lsp from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRIMARR.NRLIB ; \
+ rm -rf ${OUT}/PRIMARR.o ; \
+ ${SPADBIN}/notangle -R"PRIMARR.lsp BOOTSTRAP" ${IN}/array1.spad.pamphlet >PRIMARR.lsp )
+
+@
+<<PRIMARR2.o (O from NRLIB)>>=
+${OUT}/PRIMARR2.o: ${MID}/PRIMARR2.NRLIB
+ @ echo 0 making ${OUT}/PRIMARR2.o from ${MID}/PRIMARR2.NRLIB
+ @ cp ${MID}/PRIMARR2.NRLIB/code.o ${OUT}/PRIMARR2.o
+
+@
+<<PRIMARR2.NRLIB (NRLIB from MID)>>=
+${MID}/PRIMARR2.NRLIB: ${MID}/PRIMARR2.spad
+ @ echo 0 making ${MID}/PRIMARR2.NRLIB from ${MID}/PRIMARR2.spad
+ @ (cd ${MID} ; echo ')co PRIMARR2.spad' | ${INTERPSYS} )
+
+@
+<<PRIMARR2.spad (SPAD from IN)>>=
+${MID}/PRIMARR2.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/PRIMARR2.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRIMARR2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PRIMARR2 PrimitiveArrayFunctions2" ${IN}/array1.spad.pamphlet >PRIMARR2.spad )
+
+@
+<<TUPLE.o (O from NRLIB)>>=
+${OUT}/TUPLE.o: ${MID}/TUPLE.NRLIB
+ @ echo 0 making ${OUT}/TUPLE.o from ${MID}/TUPLE.NRLIB
+ @ cp ${MID}/TUPLE.NRLIB/code.o ${OUT}/TUPLE.o
+
+@
+<<TUPLE.NRLIB (NRLIB from MID)>>=
+${MID}/TUPLE.NRLIB: ${MID}/TUPLE.spad
+ @ echo 0 making ${MID}/TUPLE.NRLIB from ${MID}/TUPLE.spad
+ @ (cd ${MID} ; echo ')co TUPLE.spad' | ${INTERPSYS} )
+
+@
+<<TUPLE.spad (SPAD from IN)>>=
+${MID}/TUPLE.spad: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${MID}/TUPLE.spad from ${IN}/array1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TUPLE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TUPLE Tuple" ${IN}/array1.spad.pamphlet >TUPLE.spad )
+
+@
+<<array1.spad.dvi (DOC from IN)>>=
+${DOC}/array1.spad.dvi: ${IN}/array1.spad.pamphlet
+ @ echo 0 making ${DOC}/array1.spad.dvi from ${IN}/array1.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/array1.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} array1.spad ; \
+ rm -f ${DOC}/array1.spad.pamphlet ; \
+ rm -f ${DOC}/array1.spad.tex ; \
+ rm -f ${DOC}/array1.spad )
+
+@
+\subsection{array2.spad \cite{1}}
+<<array2.spad (SPAD from IN)>>=
+${MID}/array2.spad: ${IN}/array2.spad.pamphlet
+ @ echo 0 making ${MID}/array2.spad from ${IN}/array2.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/array2.spad.pamphlet >array2.spad )
+
+@
+<<ARRAY2.o (O from NRLIB)>>=
+${OUT}/ARRAY2.o: ${MID}/ARRAY2.NRLIB
+ @ echo 0 making ${OUT}/ARRAY2.o from ${MID}/ARRAY2.NRLIB
+ @ cp ${MID}/ARRAY2.NRLIB/code.o ${OUT}/ARRAY2.o
+
+@
+<<ARRAY2.NRLIB (NRLIB from MID)>>=
+${MID}/ARRAY2.NRLIB: ${MID}/ARRAY2.spad
+ @ echo 0 making ${MID}/ARRAY2.NRLIB from ${MID}/ARRAY2.spad
+ @ (cd ${MID} ; echo ')co ARRAY2.spad' | ${INTERPSYS} )
+
+@
+<<ARRAY2.spad (SPAD from IN)>>=
+${MID}/ARRAY2.spad: ${IN}/array2.spad.pamphlet
+ @ echo 0 making ${MID}/ARRAY2.spad from ${IN}/array2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ARRAY2.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ARRAY2 TwoDimensionalArray" ${IN}/array2.spad.pamphlet >ARRAY2.spad )
+
+@
+<<ARR2CAT-.o (O from NRLIB)>>=
+${OUT}/ARR2CAT-.o: ${MID}/ARR2CAT.NRLIB
+ @ echo 0 making ${OUT}/ARR2CAT-.o from ${MID}/ARR2CAT-.NRLIB
+ @ cp ${MID}/ARR2CAT-.NRLIB/code.o ${OUT}/ARR2CAT-.o
+
+@
+<<ARR2CAT-.NRLIB (NRLIB from MID)>>=
+${MID}/ARR2CAT-.NRLIB: ${OUT}/TYPE.o ${MID}/ARR2CAT.spad
+ @ echo 0 making ${MID}/ARR2CAT-.NRLIB from ${MID}/ARR2CAT.spad
+ @ (cd ${MID} ; echo ')co ARR2CAT.spad' | ${INTERPSYS} )
+
+@
+<<ARR2CAT.o (O from NRLIB)>>=
+${OUT}/ARR2CAT.o: ${MID}/ARR2CAT.NRLIB
+ @ echo 0 making ${OUT}/ARR2CAT.o from ${MID}/ARR2CAT.NRLIB
+ @ cp ${MID}/ARR2CAT.NRLIB/code.o ${OUT}/ARR2CAT.o
+
+@
+<<ARR2CAT.NRLIB (NRLIB from MID)>>=
+${MID}/ARR2CAT.NRLIB: ${MID}/ARR2CAT.spad
+ @ echo 0 making ${MID}/ARR2CAT.NRLIB from ${MID}/ARR2CAT.spad
+ @ (cd ${MID} ; echo ')co ARR2CAT.spad' | ${INTERPSYS} )
+
+@
+<<ARR2CAT.spad (SPAD from IN)>>=
+${MID}/ARR2CAT.spad: ${IN}/array2.spad.pamphlet
+ @ echo 0 making ${MID}/ARR2CAT.spad from ${IN}/array2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ARR2CAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ARR2CAT TwoDimensionalArrayCategory" ${IN}/array2.spad.pamphlet >ARR2CAT.spad )
+
+@
+<<IARRAY2.o (O from NRLIB)>>=
+${OUT}/IARRAY2.o: ${MID}/IARRAY2.NRLIB
+ @ echo 0 making ${OUT}/IARRAY2.o from ${MID}/IARRAY2.NRLIB
+ @ cp ${MID}/IARRAY2.NRLIB/code.o ${OUT}/IARRAY2.o
+
+@
+<<IARRAY2.NRLIB (NRLIB from MID)>>=
+${MID}/IARRAY2.NRLIB: ${MID}/IARRAY2.spad
+ @ echo 0 making ${MID}/IARRAY2.NRLIB from ${MID}/IARRAY2.spad
+ @ (cd ${MID} ; echo ')co IARRAY2.spad' | ${INTERPSYS} )
+
+@
+<<IARRAY2.spad (SPAD from IN)>>=
+${MID}/IARRAY2.spad: ${IN}/array2.spad.pamphlet
+ @ echo 0 making ${MID}/IARRAY2.spad from ${IN}/array2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IARRAY2.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IARRAY2 IndexedTwoDimensionalArray" ${IN}/array2.spad.pamphlet >IARRAY2.spad )
+
+@
+<<IIARRAY2.o (O from NRLIB)>>=
+${OUT}/IIARRAY2.o: ${MID}/IIARRAY2.NRLIB
+ @ echo 0 making ${OUT}/IIARRAY2.o from ${MID}/IIARRAY2.NRLIB
+ @ cp ${MID}/IIARRAY2.NRLIB/code.o ${OUT}/IIARRAY2.o
+
+@
+<<IIARRAY2.NRLIB (NRLIB from MID)>>=
+${MID}/IIARRAY2.NRLIB: ${MID}/IIARRAY2.spad
+ @ echo 0 making ${MID}/IIARRAY2.NRLIB from ${MID}/IIARRAY2.spad
+ @ (cd ${MID} ; echo ')co IIARRAY2.spad' | ${INTERPSYS} )
+
+@
+<<IIARRAY2.spad (SPAD from IN)>>=
+${MID}/IIARRAY2.spad: ${IN}/array2.spad.pamphlet
+ @ echo 0 making ${MID}/IIARRAY2.spad from ${IN}/array2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IIARRAY2.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IIARRAY2 InnerIndexedTwoDimensionalArray" ${IN}/array2.spad.pamphlet >IIARRAY2.spad )
+
+@
+<<array2.spad.dvi (DOC from IN)>>=
+${DOC}/array2.spad.dvi: ${IN}/array2.spad.pamphlet
+ @ echo 0 making ${DOC}/array2.spad.dvi from ${IN}/array2.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/array2.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} array2.spad ; \
+ rm -f ${DOC}/array2.spad.pamphlet ; \
+ rm -f ${DOC}/array2.spad.tex ; \
+ rm -f ${DOC}/array2.spad )
+
+@
+\subsection{asp.spad \cite{1}}
+<<asp.spad (SPAD from IN)>>=
+${MID}/asp.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/asp.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/asp.spad.pamphlet >asp.spad )
+
+@
+<<ASP1.o (O from NRLIB)>>=
+${OUT}/ASP1.o: ${MID}/ASP1.NRLIB
+ @ echo 0 making ${OUT}/ASP1.o from ${MID}/ASP1.NRLIB
+ @ cp ${MID}/ASP1.NRLIB/code.o ${OUT}/ASP1.o
+
+@
+<<ASP1.NRLIB (NRLIB from MID)>>=
+${MID}/ASP1.NRLIB: ${MID}/ASP1.spad
+ @ echo 0 making ${MID}/ASP1.NRLIB from ${MID}/ASP1.spad
+ @ (cd ${MID} ; echo ')co ASP1.spad' | ${INTERPSYS} )
+
+@
+<<ASP1.spad (SPAD from IN)>>=
+${MID}/ASP1.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP1.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP1.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP1 Asp1" ${IN}/asp.spad.pamphlet >ASP1.spad )
+
+@
+<<ASP10.o (O from NRLIB)>>=
+${OUT}/ASP10.o: ${MID}/ASP10.NRLIB
+ @ echo 0 making ${OUT}/ASP10.o from ${MID}/ASP10.NRLIB
+ @ cp ${MID}/ASP10.NRLIB/code.o ${OUT}/ASP10.o
+
+@
+<<ASP10.NRLIB (NRLIB from MID)>>=
+${MID}/ASP10.NRLIB: ${MID}/ASP10.spad
+ @ echo 0 making ${MID}/ASP10.NRLIB from ${MID}/ASP10.spad
+ @ (cd ${MID} ; echo ')co ASP10.spad' | ${INTERPSYS} )
+
+@
+<<ASP10.spad (SPAD from IN)>>=
+${MID}/ASP10.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP10.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP10.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP10 Asp10" ${IN}/asp.spad.pamphlet >ASP10.spad )
+
+@
+<<ASP12.o (O from NRLIB)>>=
+${OUT}/ASP12.o: ${MID}/ASP12.NRLIB
+ @ echo 0 making ${OUT}/ASP12.o from ${MID}/ASP12.NRLIB
+ @ cp ${MID}/ASP12.NRLIB/code.o ${OUT}/ASP12.o
+
+@
+<<ASP12.NRLIB (NRLIB from MID)>>=
+${MID}/ASP12.NRLIB: ${MID}/ASP12.spad
+ @ echo 0 making ${MID}/ASP12.NRLIB from ${MID}/ASP12.spad
+ @ (cd ${MID} ; echo ')co ASP12.spad' | ${INTERPSYS} )
+
+@
+<<ASP12.spad (SPAD from IN)>>=
+${MID}/ASP12.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP12.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP12.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP12 Asp12" ${IN}/asp.spad.pamphlet >ASP12.spad )
+
+@
+<<ASP19.o (O from NRLIB)>>=
+${OUT}/ASP19.o: ${MID}/ASP19.NRLIB
+ @ echo 0 making ${OUT}/ASP19.o from ${MID}/ASP19.NRLIB
+ @ cp ${MID}/ASP19.NRLIB/code.o ${OUT}/ASP19.o
+
+@
+<<ASP19.NRLIB (NRLIB from MID)>>=
+${MID}/ASP19.NRLIB: ${MID}/ASP19.spad
+ @ echo 0 making ${MID}/ASP19.NRLIB from ${MID}/ASP19.spad
+ @ (cd ${MID} ; echo ')co ASP19.spad' | ${INTERPSYS} )
+
+@
+<<ASP19.spad (SPAD from IN)>>=
+${MID}/ASP19.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP19.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP19.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP19 Asp19" ${IN}/asp.spad.pamphlet >ASP19.spad )
+
+@
+<<ASP20.o (O from NRLIB)>>=
+${OUT}/ASP20.o: ${MID}/ASP20.NRLIB
+ @ echo 0 making ${OUT}/ASP20.o from ${MID}/ASP20.NRLIB
+ @ cp ${MID}/ASP20.NRLIB/code.o ${OUT}/ASP20.o
+
+@
+<<ASP20.NRLIB (NRLIB from MID)>>=
+${MID}/ASP20.NRLIB: ${MID}/ASP20.spad
+ @ echo 0 making ${MID}/ASP20.NRLIB from ${MID}/ASP20.spad
+ @ (cd ${MID} ; echo ')co ASP20.spad' | ${INTERPSYS} )
+
+@
+<<ASP20.spad (SPAD from IN)>>=
+${MID}/ASP20.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP20.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP20.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP20 Asp20" ${IN}/asp.spad.pamphlet >ASP20.spad )
+
+@
+<<ASP24.o (O from NRLIB)>>=
+${OUT}/ASP24.o: ${MID}/ASP24.NRLIB
+ @ echo 0 making ${OUT}/ASP24.o from ${MID}/ASP24.NRLIB
+ @ cp ${MID}/ASP24.NRLIB/code.o ${OUT}/ASP24.o
+
+@
+<<ASP24.NRLIB (NRLIB from MID)>>=
+${MID}/ASP24.NRLIB: ${MID}/ASP24.spad
+ @ echo 0 making ${MID}/ASP24.NRLIB from ${MID}/ASP24.spad
+ @ (cd ${MID} ; echo ')co ASP24.spad' | ${INTERPSYS} )
+
+@
+<<ASP24.spad (SPAD from IN)>>=
+${MID}/ASP24.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP24.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP24.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP24 Asp24" ${IN}/asp.spad.pamphlet >ASP24.spad )
+
+@
+<<ASP27.o (O from NRLIB)>>=
+${OUT}/ASP27.o: ${MID}/ASP27.NRLIB
+ @ echo 0 making ${OUT}/ASP27.o from ${MID}/ASP27.NRLIB
+ @ cp ${MID}/ASP27.NRLIB/code.o ${OUT}/ASP27.o
+
+@
+<<ASP27.NRLIB (NRLIB from MID)>>=
+${MID}/ASP27.NRLIB: ${MID}/ASP27.spad
+ @ echo 0 making ${MID}/ASP27.NRLIB from ${MID}/ASP27.spad
+ @ (cd ${MID} ; echo ')co ASP27.spad' | ${INTERPSYS} )
+
+@
+<<ASP27.spad (SPAD from IN)>>=
+${MID}/ASP27.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP27.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP27.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP27 Asp27" ${IN}/asp.spad.pamphlet >ASP27.spad )
+
+@
+<<ASP28.o (O from NRLIB)>>=
+${OUT}/ASP28.o: ${MID}/ASP28.NRLIB
+ @ echo 0 making ${OUT}/ASP28.o from ${MID}/ASP28.NRLIB
+ @ cp ${MID}/ASP28.NRLIB/code.o ${OUT}/ASP28.o
+
+@
+<<ASP28.NRLIB (NRLIB from MID)>>=
+${MID}/ASP28.NRLIB: ${MID}/ASP28.spad
+ @ echo 0 making ${MID}/ASP28.NRLIB from ${MID}/ASP28.spad
+ @ (cd ${MID} ; echo ')co ASP28.spad' | ${INTERPSYS} )
+
+@
+<<ASP28.spad (SPAD from IN)>>=
+${MID}/ASP28.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP28.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP28.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP28 Asp28" ${IN}/asp.spad.pamphlet >ASP28.spad )
+
+@
+<<ASP29.o (O from NRLIB)>>=
+${OUT}/ASP29.o: ${MID}/ASP29.NRLIB
+ @ echo 0 making ${OUT}/ASP29.o from ${MID}/ASP29.NRLIB
+ @ cp ${MID}/ASP29.NRLIB/code.o ${OUT}/ASP29.o
+
+@
+<<ASP29.NRLIB (NRLIB from MID)>>=
+${MID}/ASP29.NRLIB: ${MID}/ASP29.spad
+ @ echo 0 making ${MID}/ASP29.NRLIB from ${MID}/ASP29.spad
+ @ (cd ${MID} ; echo ')co ASP29.spad' | ${INTERPSYS} )
+
+@
+<<ASP29.spad (SPAD from IN)>>=
+${MID}/ASP29.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP29.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP29.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP29 Asp29" ${IN}/asp.spad.pamphlet >ASP29.spad )
+
+@
+<<ASP30.o (O from NRLIB)>>=
+${OUT}/ASP30.o: ${MID}/ASP30.NRLIB
+ @ echo 0 making ${OUT}/ASP30.o from ${MID}/ASP30.NRLIB
+ @ cp ${MID}/ASP30.NRLIB/code.o ${OUT}/ASP30.o
+
+@
+<<ASP30.NRLIB (NRLIB from MID)>>=
+${MID}/ASP30.NRLIB: ${MID}/ASP30.spad
+ @ echo 0 making ${MID}/ASP30.NRLIB from ${MID}/ASP30.spad
+ @ (cd ${MID} ; echo ')co ASP30.spad' | ${INTERPSYS} )
+
+@
+<<ASP30.spad (SPAD from IN)>>=
+${MID}/ASP30.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP30.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP30.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP30 Asp30" ${IN}/asp.spad.pamphlet >ASP30.spad )
+
+@
+<<ASP31.o (O from NRLIB)>>=
+${OUT}/ASP31.o: ${MID}/ASP31.NRLIB
+ @ echo 0 making ${OUT}/ASP31.o from ${MID}/ASP31.NRLIB
+ @ cp ${MID}/ASP31.NRLIB/code.o ${OUT}/ASP31.o
+
+@
+<<ASP31.NRLIB (NRLIB from MID)>>=
+${MID}/ASP31.NRLIB: ${MID}/ASP31.spad
+ @ echo 0 making ${MID}/ASP31.NRLIB from ${MID}/ASP31.spad
+ @ (cd ${MID} ; echo ')co ASP31.spad' | ${INTERPSYS} )
+
+@
+<<ASP31.spad (SPAD from IN)>>=
+${MID}/ASP31.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP31.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP31.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP31 Asp31" ${IN}/asp.spad.pamphlet >ASP31.spad )
+
+@
+<<ASP33.o (O from NRLIB)>>=
+${OUT}/ASP33.o: ${MID}/ASP33.NRLIB
+ @ echo 0 making ${OUT}/ASP33.o from ${MID}/ASP33.NRLIB
+ @ cp ${MID}/ASP33.NRLIB/code.o ${OUT}/ASP33.o
+
+@
+<<ASP33.NRLIB (NRLIB from MID)>>=
+${MID}/ASP33.NRLIB: ${MID}/ASP33.spad
+ @ echo 0 making ${MID}/ASP33.NRLIB from ${MID}/ASP33.spad
+ @ (cd ${MID} ; echo ')co ASP33.spad' | ${INTERPSYS} )
+
+@
+<<ASP33.spad (SPAD from IN)>>=
+${MID}/ASP33.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP33.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP33.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP33 Asp33" ${IN}/asp.spad.pamphlet >ASP33.spad )
+
+@
+<<ASP34.o (O from NRLIB)>>=
+${OUT}/ASP34.o: ${MID}/ASP34.NRLIB
+ @ echo 0 making ${OUT}/ASP34.o from ${MID}/ASP34.NRLIB
+ @ cp ${MID}/ASP34.NRLIB/code.o ${OUT}/ASP34.o
+
+@
+<<ASP34.NRLIB (NRLIB from MID)>>=
+${MID}/ASP34.NRLIB: ${MID}/ASP34.spad
+ @ echo 0 making ${MID}/ASP34.NRLIB from ${MID}/ASP34.spad
+ @ (cd ${MID} ; echo ')co ASP34.spad' | ${INTERPSYS} )
+
+@
+<<ASP34.spad (SPAD from IN)>>=
+${MID}/ASP34.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP34.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP34.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP34 Asp34" ${IN}/asp.spad.pamphlet >ASP34.spad )
+
+@
+<<ASP35.o (O from NRLIB)>>=
+${OUT}/ASP35.o: ${MID}/ASP35.NRLIB
+ @ echo 0 making ${OUT}/ASP35.o from ${MID}/ASP35.NRLIB
+ @ cp ${MID}/ASP35.NRLIB/code.o ${OUT}/ASP35.o
+
+@
+<<ASP35.NRLIB (NRLIB from MID)>>=
+${MID}/ASP35.NRLIB: ${MID}/ASP35.spad
+ @ echo 0 making ${MID}/ASP35.NRLIB from ${MID}/ASP35.spad
+ @ (cd ${MID} ; echo ')co ASP35.spad' | ${INTERPSYS} )
+
+@
+<<ASP35.spad (SPAD from IN)>>=
+${MID}/ASP35.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP35.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP35.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP35 Asp35" ${IN}/asp.spad.pamphlet >ASP35.spad )
+
+@
+<<ASP4.o (O from NRLIB)>>=
+${OUT}/ASP4.o: ${MID}/ASP4.NRLIB
+ @ echo 0 making ${OUT}/ASP4.o from ${MID}/ASP4.NRLIB
+ @ cp ${MID}/ASP4.NRLIB/code.o ${OUT}/ASP4.o
+
+@
+<<ASP4.NRLIB (NRLIB from MID)>>=
+${MID}/ASP4.NRLIB: ${MID}/ASP4.spad
+ @ echo 0 making ${MID}/ASP4.NRLIB from ${MID}/ASP4.spad
+ @ (cd ${MID} ; echo ')co ASP4.spad' | ${INTERPSYS} )
+
+@
+<<ASP4.spad (SPAD from IN)>>=
+${MID}/ASP4.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP4.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP4.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP4 Asp4" ${IN}/asp.spad.pamphlet >ASP4.spad )
+
+@
+<<ASP41.o (O from NRLIB)>>=
+${OUT}/ASP41.o: ${MID}/ASP41.NRLIB
+ @ echo 0 making ${OUT}/ASP41.o from ${MID}/ASP41.NRLIB
+ @ cp ${MID}/ASP41.NRLIB/code.o ${OUT}/ASP41.o
+
+@
+<<ASP41.NRLIB (NRLIB from MID)>>=
+${MID}/ASP41.NRLIB: ${MID}/ASP41.spad
+ @ echo 0 making ${MID}/ASP41.NRLIB from ${MID}/ASP41.spad
+ @ (cd ${MID} ; echo ')co ASP41.spad' | ${INTERPSYS} )
+
+@
+<<ASP41.spad (SPAD from IN)>>=
+${MID}/ASP41.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP41.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP41.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP41 Asp41" ${IN}/asp.spad.pamphlet >ASP41.spad )
+
+@
+<<ASP42.o (O from NRLIB)>>=
+${OUT}/ASP42.o: ${MID}/ASP42.NRLIB
+ @ echo 0 making ${OUT}/ASP42.o from ${MID}/ASP42.NRLIB
+ @ cp ${MID}/ASP42.NRLIB/code.o ${OUT}/ASP42.o
+
+@
+<<ASP42.NRLIB (NRLIB from MID)>>=
+${MID}/ASP42.NRLIB: ${MID}/ASP42.spad
+ @ echo 0 making ${MID}/ASP42.NRLIB from ${MID}/ASP42.spad
+ @ (cd ${MID} ; echo ')co ASP42.spad' | ${INTERPSYS} )
+
+@
+<<ASP42.spad (SPAD from IN)>>=
+${MID}/ASP42.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP42.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP42.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP42 Asp42" ${IN}/asp.spad.pamphlet >ASP42.spad )
+
+@
+<<ASP49.o (O from NRLIB)>>=
+${OUT}/ASP49.o: ${MID}/ASP49.NRLIB
+ @ echo 0 making ${OUT}/ASP49.o from ${MID}/ASP49.NRLIB
+ @ cp ${MID}/ASP49.NRLIB/code.o ${OUT}/ASP49.o
+
+@
+<<ASP49.NRLIB (NRLIB from MID)>>=
+${MID}/ASP49.NRLIB: ${MID}/ASP49.spad
+ @ echo 0 making ${MID}/ASP49.NRLIB from ${MID}/ASP49.spad
+ @ (cd ${MID} ; echo ')co ASP49.spad' | ${INTERPSYS} )
+
+@
+<<ASP49.spad (SPAD from IN)>>=
+${MID}/ASP49.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP49.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP49.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP49 Asp49" ${IN}/asp.spad.pamphlet >ASP49.spad )
+
+@
+<<ASP50.o (O from NRLIB)>>=
+${OUT}/ASP50.o: ${MID}/ASP50.NRLIB
+ @ echo 0 making ${OUT}/ASP50.o from ${MID}/ASP50.NRLIB
+ @ cp ${MID}/ASP50.NRLIB/code.o ${OUT}/ASP50.o
+
+@
+<<ASP50.NRLIB (NRLIB from MID)>>=
+${MID}/ASP50.NRLIB: ${MID}/ASP50.spad
+ @ echo 0 making ${MID}/ASP50.NRLIB from ${MID}/ASP50.spad
+ @ (cd ${MID} ; echo ')co ASP50.spad' | ${INTERPSYS} )
+
+@
+<<ASP50.spad (SPAD from IN)>>=
+${MID}/ASP50.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP50.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP50.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP50 Asp50" ${IN}/asp.spad.pamphlet >ASP50.spad )
+
+@
+<<ASP55.o (O from NRLIB)>>=
+${OUT}/ASP55.o: ${MID}/ASP55.NRLIB
+ @ echo 0 making ${OUT}/ASP55.o from ${MID}/ASP55.NRLIB
+ @ cp ${MID}/ASP55.NRLIB/code.o ${OUT}/ASP55.o
+
+@
+<<ASP55.NRLIB (NRLIB from MID)>>=
+${MID}/ASP55.NRLIB: ${MID}/ASP55.spad
+ @ echo 0 making ${MID}/ASP55.NRLIB from ${MID}/ASP55.spad
+ @ (cd ${MID} ; echo ')co ASP55.spad' | ${INTERPSYS} )
+
+@
+<<ASP55.spad (SPAD from IN)>>=
+${MID}/ASP55.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP55.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP55.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP55 Asp55" ${IN}/asp.spad.pamphlet >ASP55.spad )
+
+@
+<<ASP6.o (O from NRLIB)>>=
+${OUT}/ASP6.o: ${MID}/ASP6.NRLIB
+ @ echo 0 making ${OUT}/ASP6.o from ${MID}/ASP6.NRLIB
+ @ cp ${MID}/ASP6.NRLIB/code.o ${OUT}/ASP6.o
+
+@
+<<ASP6.NRLIB (NRLIB from MID)>>=
+${MID}/ASP6.NRLIB: ${MID}/ASP6.spad
+ @ echo 0 making ${MID}/ASP6.NRLIB from ${MID}/ASP6.spad
+ @ (cd ${MID} ; echo ')co ASP6.spad' | ${INTERPSYS} )
+
+@
+<<ASP6.spad (SPAD from IN)>>=
+${MID}/ASP6.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP6.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP6.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP6 Asp6" ${IN}/asp.spad.pamphlet >ASP6.spad )
+
+@
+<<ASP7.o (O from NRLIB)>>=
+${OUT}/ASP7.o: ${MID}/ASP7.NRLIB
+ @ echo 0 making ${OUT}/ASP7.o from ${MID}/ASP7.NRLIB
+ @ cp ${MID}/ASP7.NRLIB/code.o ${OUT}/ASP7.o
+
+@
+<<ASP7.NRLIB (NRLIB from MID)>>=
+${MID}/ASP7.NRLIB: ${MID}/ASP7.spad
+ @ echo 0 making ${MID}/ASP7.NRLIB from ${MID}/ASP7.spad
+ @ (cd ${MID} ; echo ')co ASP7.spad' | ${INTERPSYS} )
+
+@
+<<ASP7.spad (SPAD from IN)>>=
+${MID}/ASP7.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP7.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP7.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP7 Asp7" ${IN}/asp.spad.pamphlet >ASP7.spad )
+
+@
+<<ASP73.o (O from NRLIB)>>=
+${OUT}/ASP73.o: ${MID}/ASP73.NRLIB
+ @ echo 0 making ${OUT}/ASP73.o from ${MID}/ASP73.NRLIB
+ @ cp ${MID}/ASP73.NRLIB/code.o ${OUT}/ASP73.o
+
+@
+<<ASP73.NRLIB (NRLIB from MID)>>=
+${MID}/ASP73.NRLIB: ${MID}/ASP73.spad
+ @ echo 0 making ${MID}/ASP73.NRLIB from ${MID}/ASP73.spad
+ @ (cd ${MID} ; echo ')co ASP73.spad' | ${INTERPSYS} )
+
+@
+<<ASP73.spad (SPAD from IN)>>=
+${MID}/ASP73.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP73.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP73.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP73 Asp73" ${IN}/asp.spad.pamphlet >ASP73.spad )
+
+@
+<<ASP74.o (O from NRLIB)>>=
+${OUT}/ASP74.o: ${MID}/ASP74.NRLIB
+ @ echo 0 making ${OUT}/ASP74.o from ${MID}/ASP74.NRLIB
+ @ cp ${MID}/ASP74.NRLIB/code.o ${OUT}/ASP74.o
+
+@
+<<ASP74.NRLIB (NRLIB from MID)>>=
+${MID}/ASP74.NRLIB: ${MID}/ASP74.spad
+ @ echo 0 making ${MID}/ASP74.NRLIB from ${MID}/ASP74.spad
+ @ (cd ${MID} ; echo ')co ASP74.spad' | ${INTERPSYS} )
+
+@
+<<ASP74.spad (SPAD from IN)>>=
+${MID}/ASP74.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP74.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP74.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP74 Asp74" ${IN}/asp.spad.pamphlet >ASP74.spad )
+
+@
+<<ASP77.o (O from NRLIB)>>=
+${OUT}/ASP77.o: ${MID}/ASP77.NRLIB
+ @ echo 0 making ${OUT}/ASP77.o from ${MID}/ASP77.NRLIB
+ @ cp ${MID}/ASP77.NRLIB/code.o ${OUT}/ASP77.o
+
+@
+<<ASP77.NRLIB (NRLIB from MID)>>=
+${MID}/ASP77.NRLIB: ${MID}/ASP77.spad
+ @ echo 0 making ${MID}/ASP77.NRLIB from ${MID}/ASP77.spad
+ @ (cd ${MID} ; echo ')co ASP77.spad' | ${INTERPSYS} )
+
+@
+<<ASP77.spad (SPAD from IN)>>=
+${MID}/ASP77.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP77.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP77.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP77 Asp77" ${IN}/asp.spad.pamphlet >ASP77.spad )
+
+@
+<<ASP78.o (O from NRLIB)>>=
+${OUT}/ASP78.o: ${MID}/ASP78.NRLIB
+ @ echo 0 making ${OUT}/ASP78.o from ${MID}/ASP78.NRLIB
+ @ cp ${MID}/ASP78.NRLIB/code.o ${OUT}/ASP78.o
+
+@
+<<ASP78.NRLIB (NRLIB from MID)>>=
+${MID}/ASP78.NRLIB: ${MID}/ASP78.spad
+ @ echo 0 making ${MID}/ASP78.NRLIB from ${MID}/ASP78.spad
+ @ (cd ${MID} ; echo ')co ASP78.spad' | ${INTERPSYS} )
+
+@
+<<ASP78.spad (SPAD from IN)>>=
+${MID}/ASP78.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP78.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP78.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP78 Asp78" ${IN}/asp.spad.pamphlet >ASP78.spad )
+
+@
+<<ASP8.o (O from NRLIB)>>=
+${OUT}/ASP8.o: ${MID}/ASP8.NRLIB
+ @ echo 0 making ${OUT}/ASP8.o from ${MID}/ASP8.NRLIB
+ @ cp ${MID}/ASP8.NRLIB/code.o ${OUT}/ASP8.o
+
+@
+<<ASP8.NRLIB (NRLIB from MID)>>=
+${MID}/ASP8.NRLIB: ${MID}/ASP8.spad
+ @ echo 0 making ${MID}/ASP8.NRLIB from ${MID}/ASP8.spad
+ @ (cd ${MID} ; echo ')co ASP8.spad' | ${INTERPSYS} )
+
+@
+<<ASP8.spad (SPAD from IN)>>=
+${MID}/ASP8.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP8.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP8.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP8 Asp8" ${IN}/asp.spad.pamphlet >ASP8.spad )
+
+@
+<<ASP80.o (O from NRLIB)>>=
+${OUT}/ASP80.o: ${MID}/ASP80.NRLIB
+ @ echo 0 making ${OUT}/ASP80.o from ${MID}/ASP80.NRLIB
+ @ cp ${MID}/ASP80.NRLIB/code.o ${OUT}/ASP80.o
+
+@
+<<ASP80.NRLIB (NRLIB from MID)>>=
+${MID}/ASP80.NRLIB: ${MID}/ASP80.spad
+ @ echo 0 making ${MID}/ASP80.NRLIB from ${MID}/ASP80.spad
+ @ (cd ${MID} ; echo ')co ASP80.spad' | ${INTERPSYS} )
+
+@
+<<ASP80.spad (SPAD from IN)>>=
+${MID}/ASP80.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP80.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP80.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP80 Asp80" ${IN}/asp.spad.pamphlet >ASP80.spad )
+
+@
+<<ASP9.o (O from NRLIB)>>=
+${OUT}/ASP9.o: ${MID}/ASP9.NRLIB
+ @ echo 0 making ${OUT}/ASP9.o from ${MID}/ASP9.NRLIB
+ @ cp ${MID}/ASP9.NRLIB/code.o ${OUT}/ASP9.o
+
+@
+<<ASP9.NRLIB (NRLIB from MID)>>=
+${MID}/ASP9.NRLIB: ${MID}/ASP9.spad
+ @ echo 0 making ${MID}/ASP9.NRLIB from ${MID}/ASP9.spad
+ @ (cd ${MID} ; echo ')co ASP9.spad' | ${INTERPSYS} )
+
+@
+<<ASP9.spad (SPAD from IN)>>=
+${MID}/ASP9.spad: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${MID}/ASP9.spad from ${IN}/asp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASP9.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASP9 Asp9" ${IN}/asp.spad.pamphlet >ASP9.spad )
+
+@
+<<asp.spad.dvi (DOC from IN)>>=
+${DOC}/asp.spad.dvi: ${IN}/asp.spad.pamphlet
+ @ echo 0 making ${DOC}/asp.spad.dvi from ${IN}/asp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/asp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} asp.spad ; \
+ rm -f ${DOC}/asp.spad.pamphlet ; \
+ rm -f ${DOC}/asp.spad.tex ; \
+ rm -f ${DOC}/asp.spad )
+
+@
+\subsection{attreg.spad \cite{1}}
+<<attreg.spad (SPAD from IN)>>=
+${MID}/attreg.spad: ${IN}/attreg.spad.pamphlet
+ @ echo 0 making ${MID}/attreg.spad from ${IN}/attreg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/attreg.spad.pamphlet >attreg.spad )
+
+@
+<<ATTREG.o (O from NRLIB)>>=
+${OUT}/ATTREG.o: ${MID}/ATTREG.NRLIB
+ @ echo 0 making ${OUT}/ATTREG.o from ${MID}/ATTREG.NRLIB
+ @ cp ${MID}/ATTREG.NRLIB/code.o ${OUT}/ATTREG.o
+
+@
+<<ATTREG.NRLIB (NRLIB from MID)>>=
+${MID}/ATTREG.NRLIB: ${MID}/ATTREG.spad
+ @ echo 0 making ${MID}/ATTREG.NRLIB from ${MID}/ATTREG.spad
+ @ (cd ${MID} ; echo ')co ATTREG.spad' | ${INTERPSYS} )
+
+@
+<<ATTREG.spad (SPAD from IN)>>=
+${MID}/ATTREG.spad: ${IN}/attreg.spad.pamphlet
+ @ echo 0 making ${MID}/ATTREG.spad from ${IN}/attreg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ATTREG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ATTREG AttributeRegistry" ${IN}/attreg.spad.pamphlet >ATTREG.spad )
+
+@
+<<attreg.spad.dvi (DOC from IN)>>=
+${DOC}/attreg.spad.dvi: ${IN}/attreg.spad.pamphlet
+ @ echo 0 making ${DOC}/attreg.spad.dvi from ${IN}/attreg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/attreg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} attreg.spad ; \
+ rm -f ${DOC}/attreg.spad.pamphlet ; \
+ rm -f ${DOC}/attreg.spad.tex ; \
+ rm -f ${DOC}/attreg.spad )
+
+@
+\subsection{axtimer.as \cite{1}}
+<<axtimer.as (SPAD from IN)>>=
+${MID}/axtimer.as: ${IN}/axtimer.as.pamphlet
+ @ echo 0 making ${MID}/axtimer.as from ${IN}/axtimer.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/axtimer.as.pamphlet >axtimer.as )
+
+@
+<<axtimer.as.dvi (DOC from IN)>>=
+${DOC}/axtimer.as.dvi: ${IN}/axtimer.as.pamphlet
+ @ echo 0 making ${DOC}/axtimer.as.dvi from ${IN}/axtimer.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/axtimer.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} axtimer.as ; \
+ rm -f ${DOC}/axtimer.as.pamphlet ; \
+ rm -f ${DOC}/axtimer.as.tex ; \
+ rm -f ${DOC}/axtimer.as )
+
+@
+\subsection{bags.spad \cite{1}}
+<<bags.spad (SPAD from IN)>>=
+${MID}/bags.spad: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${MID}/bags.spad from ${IN}/bags.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/bags.spad.pamphlet >bags.spad )
+
+@
+<<ASTACK.o (O from NRLIB)>>=
+${OUT}/ASTACK.o: ${MID}/ASTACK.NRLIB
+ @ echo 0 making ${OUT}/ASTACK.o from ${MID}/ASTACK.NRLIB
+ @ cp ${MID}/ASTACK.NRLIB/code.o ${OUT}/ASTACK.o
+
+@
+<<ASTACK.NRLIB (NRLIB from MID)>>=
+${MID}/ASTACK.NRLIB: ${MID}/ASTACK.spad
+ @ echo 0 making ${MID}/ASTACK.NRLIB from ${MID}/ASTACK.spad
+ @ (cd ${MID} ; echo ')co ASTACK.spad' | ${INTERPSYS} )
+
+@
+<<ASTACK.spad (SPAD from IN)>>=
+${MID}/ASTACK.spad: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${MID}/ASTACK.spad from ${IN}/bags.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASTACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ASTACK ArrayStack" ${IN}/bags.spad.pamphlet >ASTACK.spad )
+
+@
+<<DEQUEUE.o (O from NRLIB)>>=
+${OUT}/DEQUEUE.o: ${MID}/DEQUEUE.NRLIB
+ @ echo 0 making ${OUT}/DEQUEUE.o from ${MID}/DEQUEUE.NRLIB
+ @ cp ${MID}/DEQUEUE.NRLIB/code.o ${OUT}/DEQUEUE.o
+
+@
+<<DEQUEUE.NRLIB (NRLIB from MID)>>=
+${MID}/DEQUEUE.NRLIB: ${MID}/DEQUEUE.spad
+ @ echo 0 making ${MID}/DEQUEUE.NRLIB from ${MID}/DEQUEUE.spad
+ @ (cd ${MID} ; echo ')co DEQUEUE.spad' | ${INTERPSYS} )
+
+@
+<<DEQUEUE.spad (SPAD from IN)>>=
+${MID}/DEQUEUE.spad: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${MID}/DEQUEUE.spad from ${IN}/bags.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DEQUEUE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DEQUEUE Dequeue" ${IN}/bags.spad.pamphlet >DEQUEUE.spad )
+
+@
+<<HEAP.o (O from NRLIB)>>=
+${OUT}/HEAP.o: ${MID}/HEAP.NRLIB
+ @ echo 0 making ${OUT}/HEAP.o from ${MID}/HEAP.NRLIB
+ @ cp ${MID}/HEAP.NRLIB/code.o ${OUT}/HEAP.o
+
+@
+<<HEAP.NRLIB (NRLIB from MID)>>=
+${MID}/HEAP.NRLIB: ${MID}/HEAP.spad
+ @ echo 0 making ${MID}/HEAP.NRLIB from ${MID}/HEAP.spad
+ @ (cd ${MID} ; echo ')co HEAP.spad' | ${INTERPSYS} )
+
+@
+<<HEAP.spad (SPAD from IN)>>=
+${MID}/HEAP.spad: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${MID}/HEAP.spad from ${IN}/bags.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HEAP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HEAP Heap" ${IN}/bags.spad.pamphlet >HEAP.spad )
+
+@
+<<QUEUE.o (O from NRLIB)>>=
+${OUT}/QUEUE.o: ${MID}/QUEUE.NRLIB
+ @ echo 0 making ${OUT}/QUEUE.o from ${MID}/QUEUE.NRLIB
+ @ cp ${MID}/QUEUE.NRLIB/code.o ${OUT}/QUEUE.o
+
+@
+<<QUEUE.NRLIB (NRLIB from MID)>>=
+${MID}/QUEUE.NRLIB: ${MID}/QUEUE.spad
+ @ echo 0 making ${MID}/QUEUE.NRLIB from ${MID}/QUEUE.spad
+ @ (cd ${MID} ; echo ')co QUEUE.spad' | ${INTERPSYS} )
+
+@
+<<QUEUE.spad (SPAD from IN)>>=
+${MID}/QUEUE.spad: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${MID}/QUEUE.spad from ${IN}/bags.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QUEUE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain QUEUE Queue" ${IN}/bags.spad.pamphlet >QUEUE.spad )
+
+@
+<<STACK.o (O from NRLIB)>>=
+${OUT}/STACK.o: ${MID}/STACK.NRLIB
+ @ echo 0 making ${OUT}/STACK.o from ${MID}/STACK.NRLIB
+ @ cp ${MID}/STACK.NRLIB/code.o ${OUT}/STACK.o
+
+@
+<<STACK.NRLIB (NRLIB from MID)>>=
+${MID}/STACK.NRLIB: ${MID}/STACK.spad
+ @ echo 0 making ${MID}/STACK.NRLIB from ${MID}/STACK.spad
+ @ (cd ${MID} ; echo ')co STACK.spad' | ${INTERPSYS} )
+
+@
+<<STACK.spad (SPAD from IN)>>=
+${MID}/STACK.spad: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${MID}/STACK.spad from ${IN}/bags.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain STACK Stack" ${IN}/bags.spad.pamphlet >STACK.spad )
+
+@
+<<bags.spad.dvi (DOC from IN)>>=
+${DOC}/bags.spad.dvi: ${IN}/bags.spad.pamphlet
+ @ echo 0 making ${DOC}/bags.spad.dvi from ${IN}/bags.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/bags.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} bags.spad ; \
+ rm -f ${DOC}/bags.spad.pamphlet ; \
+ rm -f ${DOC}/bags.spad.tex ; \
+ rm -f ${DOC}/bags.spad )
+
+@
+\subsection{bezout.spad \cite{1}}
+<<bezout.spad (SPAD from IN)>>=
+${MID}/bezout.spad: ${IN}/bezout.spad.pamphlet
+ @ echo 0 making ${MID}/bezout.spad from ${IN}/bezout.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/bezout.spad.pamphlet >bezout.spad )
+
+@
+<<BEZOUT.o (O from NRLIB)>>=
+${OUT}/BEZOUT.o: ${MID}/BEZOUT.NRLIB
+ @ echo 0 making ${OUT}/BEZOUT.o from ${MID}/BEZOUT.NRLIB
+ @ cp ${MID}/BEZOUT.NRLIB/code.o ${OUT}/BEZOUT.o
+
+@
+<<BEZOUT.NRLIB (NRLIB from MID)>>=
+${MID}/BEZOUT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/BEZOUT.spad
+ @ echo 0 making ${MID}/BEZOUT.NRLIB from ${MID}/BEZOUT.spad
+ @ (cd ${MID} ; echo ')co BEZOUT.spad' | ${INTERPSYS} )
+
+@
+<<BEZOUT.spad (SPAD from IN)>>=
+${MID}/BEZOUT.spad: ${IN}/bezout.spad.pamphlet
+ @ echo 0 making ${MID}/BEZOUT.spad from ${IN}/bezout.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BEZOUT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package BEZOUT BezoutMatrix" ${IN}/bezout.spad.pamphlet >BEZOUT.spad )
+
+@
+<<bezout.spad.dvi (DOC from IN)>>=
+${DOC}/bezout.spad.dvi: ${IN}/bezout.spad.pamphlet
+ @ echo 0 making ${DOC}/bezout.spad.dvi from ${IN}/bezout.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/bezout.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} bezout.spad ; \
+ rm -f ${DOC}/bezout.spad.pamphlet ; \
+ rm -f ${DOC}/bezout.spad.tex ; \
+ rm -f ${DOC}/bezout.spad )
+
+@
+\subsection{boolean.spad \cite{1}}
+<<boolean.spad (SPAD from IN)>>=
+${MID}/boolean.spad: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/boolean.spad from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/boolean.spad.pamphlet >boolean.spad )
+
+@
+<<BITS.o (O from NRLIB)>>=
+${OUT}/BITS.o: ${MID}/BITS.NRLIB
+ @ echo 0 making ${OUT}/BITS.o from ${MID}/BITS.NRLIB
+ @ cp ${MID}/BITS.NRLIB/code.o ${OUT}/BITS.o
+
+@
+<<BITS.NRLIB (NRLIB from MID)>>=
+${MID}/BITS.NRLIB: ${MID}/BITS.spad
+ @ echo 0 making ${MID}/BITS.NRLIB from ${MID}/BITS.spad
+ @ (cd ${MID} ; echo ')co BITS.spad' | ${INTERPSYS} )
+
+@
+<<BITS.spad (SPAD from IN)>>=
+${MID}/BITS.spad: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/BITS.spad from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BITS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BITS Bits" ${IN}/boolean.spad.pamphlet >BITS.spad )
+
+@
+<<BOOLEAN.o (O from NRLIB)>>=
+${OUT}/BOOLEAN.o: ${MID}/BOOLEAN.NRLIB
+ @ echo 0 making ${OUT}/BOOLEAN.o from ${MID}/BOOLEAN.NRLIB
+ @ cp ${MID}/BOOLEAN.NRLIB/code.o ${OUT}/BOOLEAN.o
+
+@
+<<BOOLEAN.NRLIB (NRLIB from MID)>>=
+${MID}/BOOLEAN.NRLIB: ${MID}/BOOLEAN.spad
+ @ echo 0 making ${MID}/BOOLEAN.NRLIB from ${MID}/BOOLEAN.spad
+ @ (cd ${MID} ; echo ')co BOOLEAN.spad' | ${INTERPSYS} )
+
+@
+<<BOOLEAN.spad (SPAD from IN)>>=
+${MID}/BOOLEAN.spad: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/BOOLEAN.spad from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BOOLEAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BOOLEAN Boolean" ${IN}/boolean.spad.pamphlet >BOOLEAN.spad )
+
+@
+<<BOOLEAN.o (BOOTSTRAP from MID)>>=
+${MID}/BOOLEAN.o: ${MID}/BOOLEAN.lsp
+ @ echo 0 making ${MID}/BOOLEAN.o from ${MID}/BOOLEAN.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "BOOLEAN.lsp" :output-file "BOOLEAN.o"))' | ${DEPSYS} )
+ @ cp ${MID}/BOOLEAN.o ${OUT}/BOOLEAN.o
+
+@
+<<BOOLEAN.lsp (LISP from IN)>>=
+${MID}/BOOLEAN.lsp: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/BOOLEAN.lsp from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BOOLEAN.NRLIB ; \
+ rm -rf ${OUT}/BOOLEAN.o ; \
+ ${SPADBIN}/notangle -R"BOOLEAN.lsp BOOTSTRAP" ${IN}/boolean.spad.pamphlet >BOOLEAN.lsp )
+
+@
+<<IBITS.o (O from NRLIB)>>=
+${OUT}/IBITS.o: ${MID}/IBITS.NRLIB
+ @ echo 0 making ${OUT}/IBITS.o from ${MID}/IBITS.NRLIB
+ @ cp ${MID}/IBITS.NRLIB/code.o ${OUT}/IBITS.o
+
+@
+<<IBITS.NRLIB (NRLIB from MID)>>=
+${MID}/IBITS.NRLIB: ${MID}/IBITS.spad
+ @ echo 0 making ${MID}/IBITS.NRLIB from ${MID}/IBITS.spad
+ @ (cd ${MID} ; echo ')co IBITS.spad' | ${INTERPSYS} )
+
+@
+<<IBITS.spad (SPAD from IN)>>=
+${MID}/IBITS.spad: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/IBITS.spad from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IBITS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IBITS IndexedBits" ${IN}/boolean.spad.pamphlet >IBITS.spad )
+
+@
+<<LOGIC-.o (O from NRLIB)>>=
+${OUT}/LOGIC-.o: ${MID}/LOGIC.NRLIB
+ @ echo 0 making ${OUT}/LOGIC-.o from ${MID}/LOGIC-.NRLIB
+ @ cp ${MID}/LOGIC-.NRLIB/code.o ${OUT}/LOGIC-.o
+
+@
+<<LOGIC-.NRLIB (NRLIB from MID)>>=
+${MID}/LOGIC-.NRLIB: ${OUT}/BOOLEAN.o ${MID}/LOGIC.spad
+ @ echo 0 making ${MID}/LOGIC-.NRLIB from ${MID}/LOGIC.spad
+ @ (cd ${MID} ; echo ')co LOGIC.spad' | ${INTERPSYS} )
+
+@
+<<LOGIC.o (O from NRLIB)>>=
+${OUT}/LOGIC.o: ${MID}/LOGIC.NRLIB
+ @ echo 0 making ${OUT}/LOGIC.o from ${MID}/LOGIC.NRLIB
+ @ cp ${MID}/LOGIC.NRLIB/code.o ${OUT}/LOGIC.o
+
+@
+<<LOGIC.NRLIB (NRLIB from MID)>>=
+${MID}/LOGIC.NRLIB: ${MID}/LOGIC.spad
+ @ echo 0 making ${MID}/LOGIC.NRLIB from ${MID}/LOGIC.spad
+ @ (cd ${MID} ; echo ')co LOGIC.spad' | ${INTERPSYS} )
+
+@
+<<LOGIC.spad (SPAD from IN)>>=
+${MID}/LOGIC.spad: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/LOGIC.spad from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LOGIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LOGIC Logic" ${IN}/boolean.spad.pamphlet >LOGIC.spad )
+
+@
+<<REF.o (O from NRLIB)>>=
+${OUT}/REF.o: ${MID}/REF.NRLIB
+ @ echo 0 making ${OUT}/REF.o from ${MID}/REF.NRLIB
+ @ cp ${MID}/REF.NRLIB/code.o ${OUT}/REF.o
+
+@
+<<REF.NRLIB (NRLIB from MID)>>=
+${MID}/REF.NRLIB: ${MID}/REF.spad
+ @ echo 0 making ${MID}/REF.NRLIB from ${MID}/REF.spad
+ @ (cd ${MID} ; echo ')co REF.spad' | ${INTERPSYS} )
+
+@
+<<REF.spad (SPAD from IN)>>=
+${MID}/REF.spad: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/REF.spad from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain REF Reference" ${IN}/boolean.spad.pamphlet >REF.spad )
+
+@
+<<REF.o (BOOTSTRAP from MID)>>=
+${MID}/REF.o: ${MID}/REF.lsp
+ @ echo 0 making ${MID}/REF.o from ${MID}/REF.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "REF.lsp" :output-file "REF.o"))' | ${DEPSYS} )
+ @ cp ${MID}/REF.o ${OUT}/REF.o
+
+@
+<<REF.lsp (LISP from IN)>>=
+${MID}/REF.lsp: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${MID}/REF.lsp from ${IN}/boolean.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REF.NRLIB ; \
+ rm -rf ${OUT}/REF.o ; \
+ ${SPADBIN}/notangle -R"REF.lsp BOOTSTRAP" ${IN}/boolean.spad.pamphlet >REF.lsp )
+
+@
+<<boolean.spad.dvi (DOC from IN)>>=
+${DOC}/boolean.spad.dvi: ${IN}/boolean.spad.pamphlet
+ @ echo 0 making ${DOC}/boolean.spad.dvi from ${IN}/boolean.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/boolean.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} boolean.spad ; \
+ rm -f ${DOC}/boolean.spad.pamphlet ; \
+ rm -f ${DOC}/boolean.spad.tex ; \
+ rm -f ${DOC}/boolean.spad )
+
+@
+\subsection{brill.spad \cite{1}}
+<<brill.spad (SPAD from IN)>>=
+${MID}/brill.spad: ${IN}/brill.spad.pamphlet
+ @ echo 0 making ${MID}/brill.spad from ${IN}/brill.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/brill.spad.pamphlet >brill.spad )
+
+@
+<<BRILL.o (O from NRLIB)>>=
+${OUT}/BRILL.o: ${MID}/BRILL.NRLIB
+ @ echo 0 making ${OUT}/BRILL.o from ${MID}/BRILL.NRLIB
+ @ cp ${MID}/BRILL.NRLIB/code.o ${OUT}/BRILL.o
+
+@
+<<BRILL.NRLIB (NRLIB from MID)>>=
+${MID}/BRILL.NRLIB: ${MID}/BRILL.spad
+ @ echo 0 making ${MID}/BRILL.NRLIB from ${MID}/BRILL.spad
+ @ (cd ${MID} ; echo ')co BRILL.spad' | ${INTERPSYS} )
+
+@
+<<BRILL.spad (SPAD from IN)>>=
+${MID}/BRILL.spad: ${IN}/brill.spad.pamphlet
+ @ echo 0 making ${MID}/BRILL.spad from ${IN}/brill.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BRILL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package BRILL BrillhartTests" ${IN}/brill.spad.pamphlet >BRILL.spad )
+
+@
+<<brill.spad.dvi (DOC from IN)>>=
+${DOC}/brill.spad.dvi: ${IN}/brill.spad.pamphlet
+ @ echo 0 making ${DOC}/brill.spad.dvi from ${IN}/brill.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/brill.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} brill.spad ; \
+ rm -f ${DOC}/brill.spad.pamphlet ; \
+ rm -f ${DOC}/brill.spad.tex ; \
+ rm -f ${DOC}/brill.spad )
+
+@
+\subsection{c02.spad \cite{1}}
+<<c02.spad (SPAD from IN)>>=
+${MID}/c02.spad: ${IN}/c02.spad.pamphlet
+ @ echo 0 making ${MID}/c02.spad from ${IN}/c02.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/c02.spad.pamphlet >c02.spad )
+
+@
+<<NAGC02.o (O from NRLIB)>>=
+${OUT}/NAGC02.o: ${MID}/NAGC02.NRLIB
+ @ echo 0 making ${OUT}/NAGC02.o from ${MID}/NAGC02.NRLIB
+ @ cp ${MID}/NAGC02.NRLIB/code.o ${OUT}/NAGC02.o
+
+@
+<<NAGC02.NRLIB (NRLIB from MID)>>=
+${MID}/NAGC02.NRLIB: ${MID}/NAGC02.spad
+ @ echo 0 making ${MID}/NAGC02.NRLIB from ${MID}/NAGC02.spad
+ @ (cd ${MID} ; echo ')co NAGC02.spad' | ${INTERPSYS} )
+
+@
+<<NAGC02.spad (SPAD from IN)>>=
+${MID}/NAGC02.spad: ${IN}/c02.spad.pamphlet
+ @ echo 0 making ${MID}/NAGC02.spad from ${IN}/c02.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGC02.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGC02 NagPolynomialRootsPackage" ${IN}/c02.spad.pamphlet >NAGC02.spad )
+
+@
+<<c02.spad.dvi (DOC from IN)>>=
+${DOC}/c02.spad.dvi: ${IN}/c02.spad.pamphlet
+ @ echo 0 making ${DOC}/c02.spad.dvi from ${IN}/c02.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/c02.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} c02.spad ; \
+ rm -f ${DOC}/c02.spad.pamphlet ; \
+ rm -f ${DOC}/c02.spad.tex ; \
+ rm -f ${DOC}/c02.spad )
+
+@
+\subsection{c05.spad \cite{1}}
+<<c05.spad (SPAD from IN)>>=
+${MID}/c05.spad: ${IN}/c05.spad.pamphlet
+ @ echo 0 making ${MID}/c05.spad from ${IN}/c05.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/c05.spad.pamphlet >c05.spad )
+
+@
+<<NAGC05.o (O from NRLIB)>>=
+${OUT}/NAGC05.o: ${MID}/NAGC05.NRLIB
+ @ echo 0 making ${OUT}/NAGC05.o from ${MID}/NAGC05.NRLIB
+ @ cp ${MID}/NAGC05.NRLIB/code.o ${OUT}/NAGC05.o
+
+@
+<<NAGC05.NRLIB (NRLIB from MID)>>=
+${MID}/NAGC05.NRLIB: ${MID}/NAGC05.spad
+ @ echo 0 making ${MID}/NAGC05.NRLIB from ${MID}/NAGC05.spad
+ @ (cd ${MID} ; echo ')co NAGC05.spad' | ${INTERPSYS} )
+
+@
+<<NAGC05.spad (SPAD from IN)>>=
+${MID}/NAGC05.spad: ${IN}/c05.spad.pamphlet
+ @ echo 0 making ${MID}/NAGC05.spad from ${IN}/c05.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGC05.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGC05 NagRootFindingPackage" ${IN}/c05.spad.pamphlet >NAGC05.spad )
+
+@
+<<c05.spad.dvi (DOC from IN)>>=
+${DOC}/c05.spad.dvi: ${IN}/c05.spad.pamphlet
+ @ echo 0 making ${DOC}/c05.spad.dvi from ${IN}/c05.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/c05.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} c05.spad ; \
+ rm -f ${DOC}/c05.spad.pamphlet ; \
+ rm -f ${DOC}/c05.spad.tex ; \
+ rm -f ${DOC}/c05.spad )
+
+@
+\subsection{c06.spad \cite{1}}
+<<c06.spad (SPAD from IN)>>=
+${MID}/c06.spad: ${IN}/c06.spad.pamphlet
+ @ echo 0 making ${MID}/c06.spad from ${IN}/c06.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/c06.spad.pamphlet >c06.spad )
+
+@
+<<NAGC06.o (O from NRLIB)>>=
+${OUT}/NAGC06.o: ${MID}/NAGC06.NRLIB
+ @ echo 0 making ${OUT}/NAGC06.o from ${MID}/NAGC06.NRLIB
+ @ cp ${MID}/NAGC06.NRLIB/code.o ${OUT}/NAGC06.o
+
+@
+<<NAGC06.NRLIB (NRLIB from MID)>>=
+${MID}/NAGC06.NRLIB: ${MID}/NAGC06.spad
+ @ echo 0 making ${MID}/NAGC06.NRLIB from ${MID}/NAGC06.spad
+ @ (cd ${MID} ; echo ')co NAGC06.spad' | ${INTERPSYS} )
+
+@
+<<NAGC06.spad (SPAD from IN)>>=
+${MID}/NAGC06.spad: ${IN}/c06.spad.pamphlet
+ @ echo 0 making ${MID}/NAGC06.spad from ${IN}/c06.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGC06.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGC06 NagSeriesSummationPackage" ${IN}/c06.spad.pamphlet >NAGC06.spad )
+
+@
+<<c06.spad.dvi (DOC from IN)>>=
+${DOC}/c06.spad.dvi: ${IN}/c06.spad.pamphlet
+ @ echo 0 making ${DOC}/c06.spad.dvi from ${IN}/c06.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/c06.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} c06.spad ; \
+ rm -f ${DOC}/c06.spad.pamphlet ; \
+ rm -f ${DOC}/c06.spad.tex ; \
+ rm -f ${DOC}/c06.spad )
+
+@
+<<CARD.o (O from NRLIB)>>=
+${OUT}/CARD.o: ${MID}/CARD.NRLIB
+ @ echo 0 making ${OUT}/CARD.o from ${MID}/CARD.NRLIB
+ @ cp ${MID}/CARD.NRLIB/code.o ${OUT}/CARD.o
+
+@
+<<CARD.NRLIB (NRLIB from MID)>>=
+${MID}/CARD.NRLIB: ${MID}/CARD.spad
+ @ echo 0 making ${MID}/CARD.NRLIB from ${MID}/CARD.spad
+ @ (cd ${MID} ; echo ')co CARD.spad' | ${INTERPSYS} )
+
+@
+<<CARD.spad (SPAD from IN)>>=
+${MID}/CARD.spad: ${IN}/card.spad.pamphlet
+ @ echo 0 making ${MID}/CARD.spad from ${IN}/card.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CARD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain CARD CardinalNumber" ${IN}/card.spad.pamphlet >CARD.spad )
+
+@
+\subsection{card.spad \cite{1}}
+<<card.spad (SPAD from IN)>>=
+${MID}/card.spad: ${IN}/card.spad.pamphlet
+ @ echo 0 making ${MID}/card.spad from ${IN}/card.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/card.spad.pamphlet >card.spad )
+
+@
+<<card.spad.dvi (DOC from IN)>>=
+${DOC}/card.spad.dvi: ${IN}/card.spad.pamphlet
+ @ echo 0 making ${DOC}/card.spad.dvi from ${IN}/card.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/card.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} card.spad ; \
+ rm -f ${DOC}/card.spad.pamphlet ; \
+ rm -f ${DOC}/card.spad.tex ; \
+ rm -f ${DOC}/card.spad )
+
+@
+\subsection{carten.spad \cite{1}}
+<<carten.spad (SPAD from IN)>>=
+${MID}/carten.spad: ${IN}/carten.spad.pamphlet
+ @ echo 0 making ${MID}/carten.spad from ${IN}/carten.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/carten.spad.pamphlet >carten.spad )
+
+@
+<<CARTEN.o (O from NRLIB)>>=
+${OUT}/CARTEN.o: ${MID}/CARTEN.NRLIB
+ @ echo 0 making ${OUT}/CARTEN.o from ${MID}/CARTEN.NRLIB
+ @ cp ${MID}/CARTEN.NRLIB/code.o ${OUT}/CARTEN.o
+
+@
+<<CARTEN.NRLIB (NRLIB from MID)>>=
+${MID}/CARTEN.NRLIB: ${MID}/CARTEN.spad
+ @ echo 0 making ${MID}/CARTEN.NRLIB from ${MID}/CARTEN.spad
+ @ (cd ${MID} ; echo ')co CARTEN.spad' | ${INTERPSYS} )
+
+@
+<<CARTEN.spad (SPAD from IN)>>=
+${MID}/CARTEN.spad: ${IN}/carten.spad.pamphlet
+ @ echo 0 making ${MID}/CARTEN.spad from ${IN}/carten.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CARTEN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain CARTEN CartesianTensor" ${IN}/carten.spad.pamphlet >CARTEN.spad )
+
+@
+<<CARTEN2.o (O from NRLIB)>>=
+${OUT}/CARTEN2.o: ${MID}/CARTEN2.NRLIB
+ @ echo 0 making ${OUT}/CARTEN2.o from ${MID}/CARTEN2.NRLIB
+ @ cp ${MID}/CARTEN2.NRLIB/code.o ${OUT}/CARTEN2.o
+
+@
+<<CARTEN2.NRLIB (NRLIB from MID)>>=
+${MID}/CARTEN2.NRLIB: ${MID}/CARTEN2.spad
+ @ echo 0 making ${MID}/CARTEN2.NRLIB from ${MID}/CARTEN2.spad
+ @ (cd ${MID} ; echo ')co CARTEN2.spad' | ${INTERPSYS} )
+
+@
+<<CARTEN2.spad (SPAD from IN)>>=
+${MID}/CARTEN2.spad: ${IN}/carten.spad.pamphlet
+ @ echo 0 making ${MID}/CARTEN2.spad from ${IN}/carten.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CARTEN2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CARTEN2 CartesianTensorFunctions2" ${IN}/carten.spad.pamphlet >CARTEN2.spad )
+
+@
+<<GRALG-.o (O from NRLIB)>>=
+${OUT}/GRALG-.o: ${MID}/GRALG.NRLIB
+ @ echo 0 making ${OUT}/GRALG-.o from ${MID}/GRALG-.NRLIB
+ @ cp ${MID}/GRALG-.NRLIB/code.o ${OUT}/GRALG-.o
+
+@
+<<GRALG-.NRLIB (NRLIB from MID)>>=
+${MID}/GRALG-.NRLIB: ${OUT}/BOOLEAN.o ${MID}/GRALG.spad
+ @ echo 0 making ${MID}/GRALG-.NRLIB from ${MID}/GRALG.spad
+ @ (cd ${MID} ; echo ')co GRALG.spad' | ${INTERPSYS} )
+
+@
+<<GRALG.o (O from NRLIB)>>=
+${OUT}/GRALG.o: ${MID}/GRALG.NRLIB
+ @ echo 0 making ${OUT}/GRALG.o from ${MID}/GRALG.NRLIB
+ @ cp ${MID}/GRALG.NRLIB/code.o ${OUT}/GRALG.o
+
+@
+<<GRALG.NRLIB (NRLIB from MID)>>=
+${MID}/GRALG.NRLIB: ${MID}/BOOLEAN.o ${MID}/GRALG.spad
+ @ echo 0 making ${MID}/GRALG.NRLIB from ${MID}/GRALG.spad
+ @ (cd ${MID} ; echo ')co GRALG.spad' | ${INTERPSYS} )
+
+@
+<<GRALG.spad (SPAD from IN)>>=
+${MID}/GRALG.spad: ${IN}/carten.spad.pamphlet
+ @ echo 0 making ${MID}/GRALG.spad from ${IN}/carten.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GRALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category GRALG GradedAlgebra" ${IN}/carten.spad.pamphlet >GRALG.spad )
+
+@
+<<GRMOD-.o (O from NRLIB)>>=
+${OUT}/GRMOD-.o: ${MID}/GRMOD.NRLIB
+ @ echo 0 making ${OUT}/GRMOD-.o from ${MID}/GRMOD-.NRLIB
+ @ cp ${MID}/GRMOD-.NRLIB/code.o ${OUT}/GRMOD-.o
+
+@
+<<GRMOD-.NRLIB (NRLIB from MID)>>=
+${MID}/GRMOD-.NRLIB: ${OUT}/TYPE.o ${MID}/GRMOD.spad
+ @ echo 0 making ${MID}/GRMOD-.NRLIB from ${MID}/GRMOD.spad
+ @ (cd ${MID} ; echo ')co GRMOD.spad' | ${INTERPSYS} )
+
+@
+<<GRMOD.o (O from NRLIB)>>=
+${OUT}/GRMOD.o: ${MID}/GRMOD.NRLIB
+ @ echo 0 making ${OUT}/GRMOD.o from ${MID}/GRMOD.NRLIB
+ @ cp ${MID}/GRMOD.NRLIB/code.o ${OUT}/GRMOD.o
+
+@
+<<GRMOD.NRLIB (NRLIB from MID)>>=
+${MID}/GRMOD.NRLIB: ${MID}/GRMOD.spad
+ @ echo 0 making ${MID}/GRMOD.NRLIB from ${MID}/GRMOD.spad
+ @ (cd ${MID} ; echo ')co GRMOD.spad' | ${INTERPSYS} )
+
+@
+<<GRMOD.spad (SPAD from IN)>>=
+${MID}/GRMOD.spad: ${IN}/carten.spad.pamphlet
+ @ echo 0 making ${MID}/GRMOD.spad from ${IN}/carten.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GRMOD.NRLIB ; \
+ ${SPADBIN}/notangle -R"category GRMOD GradedModule" ${IN}/carten.spad.pamphlet >GRMOD.spad )
+
+@
+<<carten.spad.dvi (DOC from IN)>>=
+${DOC}/carten.spad.dvi: ${IN}/carten.spad.pamphlet
+ @ echo 0 making ${DOC}/carten.spad.dvi from ${IN}/carten.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/carten.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} carten.spad ; \
+ rm -f ${DOC}/carten.spad.pamphlet ; \
+ rm -f ${DOC}/carten.spad.tex ; \
+ rm -f ${DOC}/carten.spad )
+
+@
+\subsection{catdef.spad \cite{1}}
+<<catdef.spad (SPAD from IN)>>=
+${MID}/catdef.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/catdef.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/catdef.spad.pamphlet >catdef.spad )
+
+@
+<<ABELGRP-.o (O from NRLIB)>>=
+${OUT}/ABELGRP-.o: ${MID}/ABELGRP.NRLIB
+ @ echo 0 making ${OUT}/ABELGRP-.o from ${MID}/ABELGRP-.NRLIB
+ @ cp ${MID}/ABELGRP-.NRLIB/code.o ${OUT}/ABELGRP-.o
+
+@
+<<ABELGRP-.NRLIB (NRLIB from MID)>>=
+${MID}/ABELGRP-.NRLIB: ${OUT}/TYPE.o ${MID}/ABELGRP.spad
+ @ echo 0 making ${MID}/ABELGRP-.NRLIB from ${MID}/ABELGRP.spad
+ @ (cd ${MID} ; echo ')co ABELGRP.spad' | ${INTERPSYS} )
+
+@
+<<ABELGRP.o (O from NRLIB)>>=
+${OUT}/ABELGRP.o: ${MID}/ABELGRP.NRLIB
+ @ echo 0 making ${OUT}/ABELGRP.o from ${MID}/ABELGRP.NRLIB
+ @ cp ${MID}/ABELGRP.NRLIB/code.o ${OUT}/ABELGRP.o
+
+@
+<<ABELGRP.NRLIB (NRLIB from MID)>>=
+${MID}/ABELGRP.NRLIB: ${MID}/ABELGRP.spad
+ @ echo 0 making ${MID}/ABELGRP.NRLIB from ${MID}/ABELGRP.spad
+ @ (cd ${MID} ; echo ')co ABELGRP.spad' | ${INTERPSYS} )
+
+@
+<<ABELGRP.spad (SPAD from IN)>>=
+${MID}/ABELGRP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELGRP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELGRP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ABELGRP AbelianGroup" ${IN}/catdef.spad.pamphlet >ABELGRP.spad )
+
+@
+<<ABELGRP-.o (BOOTSTRAP from MID)>>=
+${MID}/ABELGRP-.o: ${MID}/ABELGRP-.lsp
+ @ echo 0 making ${MID}/ABELGRP-.o from ${MID}/ABELGRP-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ABELGRP-.lsp" :output-file "ABELGRP-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ABELGRP-.o ${OUT}/ABELGRP-.o
+
+@
+<<ABELGRP-.lsp (LISP from IN)>>=
+${MID}/ABELGRP-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELGRP-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELGRP-.NRLIB ; \
+ rm -rf ${OUT}/ABELGRP-.o ; \
+ ${SPADBIN}/notangle -R"ABELGRP-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ABELGRP-.lsp )
+
+@
+<<ABELGRP.o (BOOTSTRAP from MID)>>=
+${MID}/ABELGRP.o: ${MID}/ABELGRP.lsp
+ @ echo 0 making ${MID}/ABELGRP.o from ${MID}/ABELGRP.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ABELGRP.lsp" :output-file "ABELGRP.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ABELGRP.o ${OUT}/ABELGRP.o
+
+@
+<<ABELGRP.lsp (LISP from IN)>>=
+${MID}/ABELGRP.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELGRP.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELGRP.NRLIB ; \
+ rm -rf ${OUT}/ABELGRP.o ; \
+ ${SPADBIN}/notangle -R"ABELGRP.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ABELGRP.lsp )
+
+@
+<<ABELMON-.o (O from NRLIB)>>=
+${OUT}/ABELMON-.o: ${MID}/ABELMON.NRLIB
+ @ echo 0 making ${OUT}/ABELMON-.o from ${MID}/ABELMON-.NRLIB
+ @ cp ${MID}/ABELMON-.NRLIB/code.o ${OUT}/ABELMON-.o
+
+@
+<<ABELMON-.NRLIB (NRLIB from MID)>>=
+${MID}/ABELMON-.NRLIB: ${OUT}/TYPE.o ${MID}/ABELMON.spad
+ @ echo 0 making ${MID}/ABELMON-.NRLIB from ${MID}/ABELMON.spad
+ @ (cd ${MID} ; echo ')co ABELMON.spad' | ${INTERPSYS} )
+
+@
+<<ABELMON.o (O from NRLIB)>>=
+${OUT}/ABELMON.o: ${MID}/ABELMON.NRLIB
+ @ echo 0 making ${OUT}/ABELMON.o from ${MID}/ABELMON.NRLIB
+ @ cp ${MID}/ABELMON.NRLIB/code.o ${OUT}/ABELMON.o
+
+@
+<<ABELMON.NRLIB (NRLIB from MID)>>=
+${MID}/ABELMON.NRLIB: ${MID}/ABELMON.spad
+ @ echo 0 making ${MID}/ABELMON.NRLIB from ${MID}/ABELMON.spad
+ @ (cd ${MID} ; echo ')co ABELMON.spad' | ${INTERPSYS} )
+
+@
+<<ABELMON.spad (SPAD from IN)>>=
+${MID}/ABELMON.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELMON.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ABELMON AbelianMonoid" ${IN}/catdef.spad.pamphlet >ABELMON.spad )
+
+@
+<<ABELMON-.o (BOOTSTRAP from MID)>>=
+${MID}/ABELMON-.o: ${MID}/ABELMON-.lsp
+ @ echo 0 making ${MID}/ABELMON-.o from ${MID}/ABELMON-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ABELMON-.lsp" :output-file "ABELMON-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ABELMON-.o ${OUT}/ABELMON-.o
+
+@
+<<ABELMON-.lsp (LISP from IN)>>=
+${MID}/ABELMON-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELMON-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELMON-.NRLIB ; \
+ rm -rf ${OUT}/ABELMON-.o ; \
+ ${SPADBIN}/notangle -R"ABELMON-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ABELMON-.lsp )
+
+@
+<<ABELMON.o (BOOTSTRAP from MID)>>=
+${MID}/ABELMON.o: ${MID}/ABELMON.lsp
+ @ echo 0 making ${MID}/ABELMON.o from ${MID}/ABELMON.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ABELMON.lsp" :output-file "ABELMON.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ABELMON.o ${OUT}/ABELMON.o
+
+@
+<<ABELMON.lsp (LISP from IN)>>=
+${MID}/ABELMON.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELMON.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELMON.NRLIB ; \
+ rm -rf ${OUT}/ABELMON.o ; \
+ ${SPADBIN}/notangle -R"ABELMON.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ABELMON.lsp )
+
+@
+<<ABELSG-.o (O from NRLIB)>>=
+${OUT}/ABELSG-.o: ${MID}/ABELSG.NRLIB
+ @ echo 0 making ${OUT}/ABELSG-.o from ${MID}/ABELSG-.NRLIB
+ @ cp ${MID}/ABELSG-.NRLIB/code.o ${OUT}/ABELSG-.o
+
+@
+<<ABELSG-.NRLIB (NRLIB from MID)>>=
+${MID}/ABELSG-.NRLIB: ${OUT}/TYPE.o ${MID}/ABELSG.spad
+ @ echo 0 making ${MID}/ABELSG-.NRLIB from ${MID}/ABELSG.spad
+ @ (cd ${MID} ; echo ')co ABELSG.spad' | ${INTERPSYS} )
+
+@
+<<ABELSG.o (O from NRLIB)>>=
+${OUT}/ABELSG.o: ${MID}/ABELSG.NRLIB
+ @ echo 0 making ${OUT}/ABELSG.o from ${MID}/ABELSG.NRLIB
+ @ cp ${MID}/ABELSG.NRLIB/code.o ${OUT}/ABELSG.o
+
+@
+<<ABELSG.NRLIB (NRLIB from MID)>>=
+${MID}/ABELSG.NRLIB: ${MID}/ABELSG.spad
+ @ echo 0 making ${MID}/ABELSG.NRLIB from ${MID}/ABELSG.spad
+ @ (cd ${MID} ; echo ')co ABELSG.spad' | ${INTERPSYS} )
+
+@
+<<ABELSG.spad (SPAD from IN)>>=
+${MID}/ABELSG.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELSG.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELSG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ABELSG AbelianSemiGroup" ${IN}/catdef.spad.pamphlet >ABELSG.spad )
+
+@
+<<ABELSG-.o (BOOTSTRAP from MID)>>=
+${MID}/ABELSG-.o: ${MID}/ABELSG-.lsp
+ @ echo 0 making ${MID}/ABELSG-.o from ${MID}/ABELSG-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ABELSG-.lsp" :output-file "ABELSG-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ABELSG-.o ${OUT}/ABELSG-.o
+
+@
+<<ABELSG-.lsp (LISP from IN)>>=
+${MID}/ABELSG-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELSG-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELSG-.NRLIB ; \
+ rm -rf ${OUT}/ABELSG-.o ; \
+ ${SPADBIN}/notangle -R"ABELSG-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ABELSG-.lsp )
+
+@
+<<ABELSG.o (BOOTSTRAP from MID)>>=
+${MID}/ABELSG.o: ${MID}/ABELSG.lsp
+ @ echo 0 making ${MID}/ABELSG.o from ${MID}/ABELSG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ABELSG.lsp" :output-file "ABELSG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ABELSG.o ${OUT}/ABELSG.o
+
+@
+<<ABELSG.lsp (LISP from IN)>>=
+${MID}/ABELSG.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ABELSG.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ABELSG.NRLIB ; \
+ rm -rf ${OUT}/ABELSG.o ; \
+ ${SPADBIN}/notangle -R"ABELSG.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ABELSG.lsp )
+
+@
+<<ALGEBRA-.o (O from NRLIB)>>=
+${OUT}/ALGEBRA-.o: ${MID}/ALGEBRA.NRLIB
+ @ echo 0 making ${OUT}/ALGEBRA-.o from ${MID}/ALGEBRA-.NRLIB
+ @ cp ${MID}/ALGEBRA-.NRLIB/code.o ${OUT}/ALGEBRA-.o
+
+@
+<<ALGEBRA-.NRLIB (NRLIB from MID)>>=
+${MID}/ALGEBRA-.NRLIB: ${OUT}/BOOLEAN.o ${MID}/ALGEBRA.spad
+ @ echo 0 making ${MID}/ALGEBRA-.NRLIB from ${MID}/ALGEBRA.spad
+ @ (cd ${MID} ; echo ')co ALGEBRA.spad' | ${INTERPSYS} )
+
+@
+<<ALGEBRA.o (O from NRLIB)>>=
+${OUT}/ALGEBRA.o: ${MID}/ALGEBRA.NRLIB
+ @ echo 0 making ${OUT}/ALGEBRA.o from ${MID}/ALGEBRA.NRLIB
+ @ cp ${MID}/ALGEBRA.NRLIB/code.o ${OUT}/ALGEBRA.o
+
+@
+<<ALGEBRA.NRLIB (NRLIB from MID)>>=
+${MID}/ALGEBRA.NRLIB: ${MID}/BOOLEAN.o ${MID}/ALGEBRA.spad
+ @ echo 0 making ${MID}/ALGEBRA.NRLIB from ${MID}/ALGEBRA.spad
+ @ (cd ${MID} ; echo ')co ALGEBRA.spad' | ${INTERPSYS} )
+
+@
+<<ALGEBRA.spad (SPAD from IN)>>=
+${MID}/ALGEBRA.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ALGEBRA.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGEBRA.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ALGEBRA Algebra" ${IN}/catdef.spad.pamphlet >ALGEBRA.spad )
+
+@
+<<BASTYPE-.o (O from NRLIB)>>=
+${OUT}/BASTYPE-.o: ${MID}/BASTYPE.NRLIB
+ @ echo 0 making ${OUT}/BASTYPE-.o from ${MID}/BASTYPE-.NRLIB
+ @ cp ${MID}/BASTYPE-.NRLIB/code.o ${OUT}/BASTYPE-.o
+
+@
+<<BASTYPE-.NRLIB (NRLIB from MID)>>=
+${MID}/BASTYPE-.NRLIB: ${OUT}/BOOLEAN.o ${MID}/BASTYPE.spad
+ @ echo 0 making ${MID}/BASTYPE-.NRLIB from ${MID}/BASTYPE.spad
+ @ (cd ${MID} ; echo ')co BASTYPE.spad' | ${INTERPSYS} )
+
+@
+<<BASTYPE.o (O from NRLIB)>>=
+${OUT}/BASTYPE.o: ${MID}/BASTYPE.NRLIB
+ @ echo 0 making ${OUT}/BASTYPE.o from ${MID}/BASTYPE.NRLIB
+ @ cp ${MID}/BASTYPE.NRLIB/code.o ${OUT}/BASTYPE.o
+
+@
+<<BASTYPE.NRLIB (NRLIB from MID)>>=
+${MID}/BASTYPE.NRLIB: ${MID}/BOOLEAN.o ${MID}/BASTYPE.spad
+ @ echo 0 making ${MID}/BASTYPE.NRLIB from ${MID}/BASTYPE.spad
+ @ (cd ${MID} ; echo ')co BASTYPE.spad' | ${INTERPSYS} )
+
+@
+<<BASTYPE.spad (SPAD from IN)>>=
+${MID}/BASTYPE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/BASTYPE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BASTYPE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category BASTYPE BasicType" ${IN}/catdef.spad.pamphlet >BASTYPE.spad )
+
+@
+<<BMODULE.o (O from NRLIB)>>=
+${OUT}/BMODULE.o: ${MID}/BMODULE.NRLIB
+ @ echo 0 making ${OUT}/BMODULE.o from ${MID}/BMODULE.NRLIB
+ @ cp ${MID}/BMODULE.NRLIB/code.o ${OUT}/BMODULE.o
+
+@
+<<BMODULE.NRLIB (NRLIB from MID)>>=
+${MID}/BMODULE.NRLIB: ${MID}/BMODULE.spad
+ @ echo 0 making ${MID}/BMODULE.NRLIB from ${MID}/BMODULE.spad
+ @ (cd ${MID} ; echo ')co BMODULE.spad' | ${INTERPSYS} )
+
+@
+<<BMODULE.spad (SPAD from IN)>>=
+${MID}/BMODULE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/BMODULE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BMODULE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category BMODULE BiModule" ${IN}/catdef.spad.pamphlet >BMODULE.spad )
+
+@
+<<CABMON.o (O from NRLIB)>>=
+${OUT}/CABMON.o: ${MID}/CABMON.NRLIB
+ @ echo 0 making ${OUT}/CABMON.o from ${MID}/CABMON.NRLIB
+ @ cp ${MID}/CABMON.NRLIB/code.o ${OUT}/CABMON.o
+
+@
+<<CABMON.NRLIB (NRLIB from MID)>>=
+${MID}/CABMON.NRLIB: ${MID}/CABMON.spad
+ @ echo 0 making ${MID}/CABMON.NRLIB from ${MID}/CABMON.spad
+ @ (cd ${MID} ; echo ')co CABMON.spad' | ${INTERPSYS} )
+
+@
+<<CABMON.spad (SPAD from IN)>>=
+${MID}/CABMON.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/CABMON.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CABMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"category CABMON CancellationAbelianMonoid" ${IN}/catdef.spad.pamphlet >CABMON.spad )
+
+@
+<<CABMON.o (BOOTSTRAP from MID)>>=
+${MID}/CABMON.o: ${MID}/CABMON.lsp
+ @ echo 0 making ${MID}/CABMON.o from ${MID}/CABMON.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "CABMON.lsp" :output-file "CABMON.o"))' | ${DEPSYS} )
+ @ cp ${MID}/CABMON.o ${OUT}/CABMON.o
+
+@
+<<CABMON.lsp (LISP from IN)>>=
+${MID}/CABMON.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/CABMON.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CABMON.NRLIB ; \
+ rm -rf ${OUT}/CABMON.o ; \
+ ${SPADBIN}/notangle -R"CABMON.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >CABMON.lsp )
+
+@
+<<CHARNZ.o (O from NRLIB)>>=
+${OUT}/CHARNZ.o: ${MID}/CHARNZ.NRLIB
+ @ echo 0 making ${OUT}/CHARNZ.o from ${MID}/CHARNZ.NRLIB
+ @ cp ${MID}/CHARNZ.NRLIB/code.o ${OUT}/CHARNZ.o
+
+@
+<<CHARNZ.NRLIB (NRLIB from MID)>>=
+${MID}/CHARNZ.NRLIB: ${MID}/CHARNZ.spad
+ @ echo 0 making ${MID}/CHARNZ.NRLIB from ${MID}/CHARNZ.spad
+ @ (cd ${MID} ; echo ')co CHARNZ.spad' | ${INTERPSYS} )
+
+@
+<<CHARNZ.spad (SPAD from IN)>>=
+${MID}/CHARNZ.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/CHARNZ.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CHARNZ.NRLIB ; \
+ ${SPADBIN}/notangle -R"category CHARNZ CharacteristicNonZero" ${IN}/catdef.spad.pamphlet >CHARNZ.spad )
+
+@
+<<CHARZ.o (O from NRLIB)>>=
+${OUT}/CHARZ.o: ${MID}/CHARZ.NRLIB
+ @ echo 0 making ${OUT}/CHARZ.o from ${MID}/CHARZ.NRLIB
+ @ cp ${MID}/CHARZ.NRLIB/code.o ${OUT}/CHARZ.o
+
+@
+<<CHARZ.NRLIB (NRLIB from MID)>>=
+${MID}/CHARZ.NRLIB: ${MID}/CHARZ.spad
+ @ echo 0 making ${MID}/CHARZ.NRLIB from ${MID}/CHARZ.spad
+ @ (cd ${MID} ; echo ')co CHARZ.spad' | ${INTERPSYS} )
+
+@
+<<CHARZ.spad (SPAD from IN)>>=
+${MID}/CHARZ.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/CHARZ.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CHARZ.NRLIB ; \
+ ${SPADBIN}/notangle -R"category CHARZ CharacteristicZero" ${IN}/catdef.spad.pamphlet >CHARZ.spad )
+
+@
+<<COMRING.o (O from NRLIB)>>=
+${OUT}/COMRING.o: ${MID}/COMRING.NRLIB
+ @ echo 0 making ${OUT}/COMRING.o from ${MID}/COMRING.NRLIB
+ @ cp ${MID}/COMRING.NRLIB/code.o ${OUT}/COMRING.o
+
+@
+<<COMRING.NRLIB (NRLIB from MID)>>=
+${MID}/COMRING.NRLIB: ${MID}/COMRING.spad
+ @ echo 0 making ${MID}/COMRING.NRLIB from ${MID}/COMRING.spad
+ @ (cd ${MID} ; echo ')co COMRING.spad' | ${INTERPSYS} )
+
+@
+<<COMRING.spad (SPAD from IN)>>=
+${MID}/COMRING.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/COMRING.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category COMRING CommutativeRing" ${IN}/catdef.spad.pamphlet >COMRING.spad )
+
+@
+<<COMRING.o (BOOTSTRAP from MID)>>=
+${MID}/COMRING.o: ${MID}/COMRING.lsp
+ @ echo 0 making ${MID}/COMRING.o from ${MID}/COMRING.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "COMRING.lsp" :output-file "COMRING.o"))' | ${DEPSYS} )
+ @ cp ${MID}/COMRING.o ${OUT}/COMRING.o
+
+@
+<<COMRING.lsp (LISP from IN)>>=
+${MID}/COMRING.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/COMRING.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMRING.NRLIB ; \
+ rm -rf ${OUT}/COMRING.o ; \
+ ${SPADBIN}/notangle -R"COMRING.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >COMRING.lsp )
+
+@
+<<DIFEXT-.o (O from NRLIB)>>=
+${OUT}/DIFEXT-.o: ${MID}/DIFEXT.NRLIB
+ @ echo 0 making ${OUT}/DIFEXT-.o from ${MID}/DIFEXT-.NRLIB
+ @ cp ${MID}/DIFEXT-.NRLIB/code.o ${OUT}/DIFEXT-.o
+
+@
+<<DIFEXT-.NRLIB (NRLIB from MID)>>=
+${MID}/DIFEXT-.NRLIB: ${OUT}/TYPE.o ${MID}/DIFEXT.spad
+ @ echo 0 making ${MID}/DIFEXT-.NRLIB from ${MID}/DIFEXT.spad
+ @ (cd ${MID} ; echo ')co DIFEXT.spad' | ${INTERPSYS} )
+
+@
+<<DIFEXT.o (O from NRLIB)>>=
+${OUT}/DIFEXT.o: ${MID}/DIFEXT.NRLIB
+ @ echo 0 making ${OUT}/DIFEXT.o from ${MID}/DIFEXT.NRLIB
+ @ cp ${MID}/DIFEXT.NRLIB/code.o ${OUT}/DIFEXT.o
+
+@
+<<DIFEXT.NRLIB (NRLIB from MID)>>=
+${MID}/DIFEXT.NRLIB: ${MID}/DIFEXT.spad
+ @ echo 0 making ${MID}/DIFEXT.NRLIB from ${MID}/DIFEXT.spad
+ @ (cd ${MID} ; echo ')co DIFEXT.spad' | ${INTERPSYS} )
+
+@
+<<DIFEXT.spad (SPAD from IN)>>=
+${MID}/DIFEXT.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIFEXT.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIFEXT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DIFEXT DifferentialExtension" ${IN}/catdef.spad.pamphlet >DIFEXT.spad )
+
+@
+<<DIFRING-.o (O from NRLIB)>>=
+${OUT}/DIFRING-.o: ${MID}/DIFRING.NRLIB
+ @ echo 0 making ${OUT}/DIFRING-.o from ${MID}/DIFRING-.NRLIB
+ @ cp ${MID}/DIFRING-.NRLIB/code.o ${OUT}/DIFRING-.o
+
+@
+<<DIFRING-.NRLIB (NRLIB from MID)>>=
+${MID}/DIFRING-.NRLIB: ${OUT}/BOOLEAN.o ${MID}/DIFRING.spad
+ @ echo 0 making ${MID}/DIFRING-.NRLIB from ${MID}/DIFRING.spad
+ @ (cd ${MID} ; echo ')co DIFRING.spad' | ${INTERPSYS} )
+
+@
+<<DIFRING.o (O from NRLIB)>>=
+${OUT}/DIFRING.o: ${MID}/DIFRING.NRLIB
+ @ echo 0 making ${OUT}/DIFRING.o from ${MID}/DIFRING.NRLIB
+ @ cp ${MID}/DIFRING.NRLIB/code.o ${OUT}/DIFRING.o
+
+@
+<<DIFRING.NRLIB (NRLIB from MID)>>=
+${MID}/DIFRING.NRLIB: ${MID}/DIFRING.spad
+ @ echo 0 making ${MID}/DIFRING.NRLIB from ${MID}/DIFRING.spad
+ @ (cd ${MID} ; echo ')co DIFRING.spad' | ${INTERPSYS} )
+
+@
+<<DIFRING.spad (SPAD from IN)>>=
+${MID}/DIFRING.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIFRING.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIFRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DIFRING DifferentialRing" ${IN}/catdef.spad.pamphlet >DIFRING.spad )
+
+@
+<<DIFRING-.o (BOOTSTRAP from MID)>>=
+${MID}/DIFRING-.o: ${MID}/DIFRING-.lsp
+ @ echo 0 making ${MID}/DIFRING-.o from ${MID}/DIFRING-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "DIFRING-.lsp" :output-file "DIFRING-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/DIFRING-.o ${OUT}/DIFRING-.o
+
+@
+<<DIFRING-.lsp (LISP from IN)>>=
+${MID}/DIFRING-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIFRING-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIFRING-.NRLIB ; \
+ rm -rf ${OUT}/DIFRING-.o ; \
+ ${SPADBIN}/notangle -R"DIFRING-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >DIFRING-.lsp )
+
+@
+<<DIFRING.o (BOOTSTRAP from MID)>>=
+${MID}/DIFRING.o: ${MID}/DIFRING.lsp
+ @ echo 0 making ${MID}/DIFRING.o from ${MID}/DIFRING.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "DIFRING.lsp" :output-file "DIFRING.o"))' | ${DEPSYS} )
+ @ cp ${MID}/DIFRING.o ${OUT}/DIFRING.o
+
+@
+<<DIFRING.lsp (LISP from IN)>>=
+${MID}/DIFRING.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIFRING.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIFRING.NRLIB ; \
+ rm -rf ${OUT}/DIFRING.o ; \
+ ${SPADBIN}/notangle -R"DIFRING.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >DIFRING.lsp )
+
+@
+<<DIVRING-.o (O from NRLIB)>>=
+${OUT}/DIVRING-.o: ${MID}/DIVRING.NRLIB
+ @ echo 0 making ${OUT}/DIVRING-.o from ${MID}/DIVRING-.NRLIB
+ @ cp ${MID}/DIVRING-.NRLIB/code.o ${OUT}/DIVRING-.o
+
+@
+<<DIVRING-.NRLIB (NRLIB from MID)>>=
+${MID}/DIVRING-.NRLIB: ${OUT}/TYPE.o ${MID}/DIVRING.spad
+ @ echo 0 making ${MID}/DIVRING-.NRLIB from ${MID}/DIVRING.spad
+ @ (cd ${MID} ; echo ')co DIVRING.spad' | ${INTERPSYS} )
+
+@
+<<DIVRING.o (O from NRLIB)>>=
+${OUT}/DIVRING.o: ${MID}/DIVRING.NRLIB
+ @ echo 0 making ${OUT}/DIVRING.o from ${MID}/DIVRING.NRLIB
+ @ cp ${MID}/DIVRING.NRLIB/code.o ${OUT}/DIVRING.o
+
+@
+<<DIVRING.NRLIB (NRLIB from MID)>>=
+${MID}/DIVRING.NRLIB: ${MID}/DIVRING.spad
+ @ echo 0 making ${MID}/DIVRING.NRLIB from ${MID}/DIVRING.spad
+ @ (cd ${MID} ; echo ')co DIVRING.spad' | ${INTERPSYS} )
+
+@
+<<DIVRING.spad (SPAD from IN)>>=
+${MID}/DIVRING.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIVRING.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIVRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DIVRING DivisionRing" ${IN}/catdef.spad.pamphlet >DIVRING.spad )
+
+@
+<<DIVRING-.o (BOOTSTRAP from MID)>>=
+${MID}/DIVRING-.o: ${MID}/DIVRING-.lsp
+ @ echo 0 making ${MID}/DIVRING-.o from ${MID}/DIVRING-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "DIVRING-.lsp" :output-file "DIVRING-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/DIVRING-.o ${OUT}/DIVRING-.o
+
+@
+<<DIVRING-.lsp (LISP from IN)>>=
+${MID}/DIVRING-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIVRING-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIVRING-.NRLIB ; \
+ rm -rf ${OUT}/DIVRING-.o ; \
+ ${SPADBIN}/notangle -R"DIVRING-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >DIVRING-.lsp )
+
+@
+<<DIVRING.o (BOOTSTRAP from MID)>>=
+${MID}/DIVRING.o: ${MID}/DIVRING.lsp
+ @ echo 0 making ${MID}/DIVRING.o from ${MID}/DIVRING.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "DIVRING.lsp" :output-file "DIVRING.o"))' | ${DEPSYS} )
+ @ cp ${MID}/DIVRING.o ${OUT}/DIVRING.o
+
+@
+<<DIVRING.lsp (LISP from IN)>>=
+${MID}/DIVRING.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/DIVRING.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIVRING.NRLIB ; \
+ rm -rf ${OUT}/DIVRING.o ; \
+ ${SPADBIN}/notangle -R"DIVRING.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >DIVRING.lsp )
+
+@
+<<ENTIRER.o (O from NRLIB)>>=
+${OUT}/ENTIRER.o: ${MID}/ENTIRER.NRLIB
+ @ echo 0 making ${OUT}/ENTIRER.o from ${MID}/ENTIRER.NRLIB
+ @ cp ${MID}/ENTIRER.NRLIB/code.o ${OUT}/ENTIRER.o
+
+@
+<<ENTIRER.NRLIB (NRLIB from MID)>>=
+${MID}/ENTIRER.NRLIB: ${MID}/ENTIRER.spad
+ @ echo 0 making ${MID}/ENTIRER.NRLIB from ${MID}/ENTIRER.spad
+ @ (cd ${MID} ; echo ')co ENTIRER.spad' | ${INTERPSYS} )
+
+@
+<<ENTIRER.spad (SPAD from IN)>>=
+${MID}/ENTIRER.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ENTIRER.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ENTIRER.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ENTIRER CommutativeRing" ${IN}/catdef.spad.pamphlet >ENTIRER.spad )
+
+@
+<<ENTIRER.o (BOOTSTRAP from MID)>>=
+${MID}/ENTIRER.o: ${MID}/ENTIRER.lsp
+ @ echo 0 making ${MID}/ENTIRER.o from ${MID}/ENTIRER.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ENTIRER.lsp" :output-file "ENTIRER.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ENTIRER.o ${OUT}/ENTIRER.o
+
+@
+<<ENTIRER.lsp (LISP from IN)>>=
+${MID}/ENTIRER.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ENTIRER.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ENTIRER.NRLIB ; \
+ rm -rf ${OUT}/ENTIRER.o ; \
+ ${SPADBIN}/notangle -R"ENTIRER.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ENTIRER.lsp )
+
+@
+<<EUCDOM-.o (O from NRLIB)>>=
+${OUT}/EUCDOM-.o: ${MID}/EUCDOM.NRLIB
+ @ echo 0 making ${OUT}/EUCDOM-.o from ${MID}/EUCDOM-.NRLIB
+ @ cp ${MID}/EUCDOM-.NRLIB/code.o ${OUT}/EUCDOM-.o
+
+@
+<<EUCDOM-.NRLIB (NRLIB from MID)>>=
+${MID}/EUCDOM-.NRLIB: ${OUT}/TYPE.o ${MID}/EUCDOM.spad
+ @ echo 0 making ${MID}/EUCDOM-.NRLIB from ${MID}/EUCDOM.spad
+ @ (cd ${MID} ; echo ')co EUCDOM.spad' | ${INTERPSYS} )
+
+@
+<<EUCDOM.o (O from NRLIB)>>=
+${OUT}/EUCDOM.o: ${MID}/EUCDOM.NRLIB
+ @ echo 0 making ${OUT}/EUCDOM.o from ${MID}/EUCDOM.NRLIB
+ @ cp ${MID}/EUCDOM.NRLIB/code.o ${OUT}/EUCDOM.o
+
+@
+<<EUCDOM.NRLIB (NRLIB from MID)>>=
+${MID}/EUCDOM.NRLIB: ${MID}/EUCDOM.spad
+ @ echo 0 making ${MID}/EUCDOM.NRLIB from ${MID}/EUCDOM.spad
+ @ (cd ${MID} ; echo ')co EUCDOM.spad' | ${INTERPSYS} )
+
+@
+<<EUCDOM.spad (SPAD from IN)>>=
+${MID}/EUCDOM.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/EUCDOM.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EUCDOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"category EUCDOM EuclideanDomain" ${IN}/catdef.spad.pamphlet >EUCDOM.spad )
+
+@
+<<EUCDOM-.o (BOOTSTRAP from MID)>>=
+${MID}/EUCDOM-.o: ${MID}/EUCDOM-.lsp
+ @ echo 0 making ${MID}/EUCDOM-.o from ${MID}/EUCDOM-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "EUCDOM-.lsp" :output-file "EUCDOM-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/EUCDOM-.o ${OUT}/EUCDOM-.o
+
+@
+<<EUCDOM-.lsp (LISP from IN)>>=
+${MID}/EUCDOM-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/EUCDOM-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EUCDOM-.NRLIB ; \
+ rm -rf ${OUT}/EUCDOM-.o ; \
+ ${SPADBIN}/notangle -R"EUCDOM-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >EUCDOM-.lsp )
+
+@
+<<EUCDOM.o (BOOTSTRAP from MID)>>=
+${MID}/EUCDOM.o: ${MID}/EUCDOM.lsp
+ @ echo 0 making ${MID}/EUCDOM.o from ${MID}/EUCDOM.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "EUCDOM.lsp" :output-file "EUCDOM.o"))' | ${DEPSYS} )
+ @ cp ${MID}/EUCDOM.o ${OUT}/EUCDOM.o
+
+@
+<<EUCDOM.lsp (LISP from IN)>>=
+${MID}/EUCDOM.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/EUCDOM.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EUCDOM.NRLIB ; \
+ rm -rf ${OUT}/EUCDOM.o ; \
+ ${SPADBIN}/notangle -R"EUCDOM.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >EUCDOM.lsp )
+
+@
+<<FIELD-.o (O from NRLIB)>>=
+${OUT}/FIELD-.o: ${MID}/FIELD.NRLIB
+ @ echo 0 making ${OUT}/FIELD-.o from ${MID}/FIELD-.NRLIB
+ @ cp ${MID}/FIELD-.NRLIB/code.o ${OUT}/FIELD-.o
+
+@
+<<FIELD-.NRLIB (NRLIB from MID)>>=
+${MID}/FIELD-.NRLIB: ${OUT}/TYPE.o ${MID}/FIELD.spad
+ @ echo 0 making ${MID}/FIELD-.NRLIB from ${MID}/FIELD.spad
+ @ (cd ${MID} ; echo ')co FIELD.spad' | ${INTERPSYS} )
+
+@
+<<FIELD.o (O from NRLIB)>>=
+${OUT}/FIELD.o: ${MID}/FIELD.NRLIB
+ @ echo 0 making ${OUT}/FIELD.o from ${MID}/FIELD.NRLIB
+ @ cp ${MID}/FIELD.NRLIB/code.o ${OUT}/FIELD.o
+
+@
+<<FIELD.NRLIB (NRLIB from MID)>>=
+${MID}/FIELD.NRLIB: ${MID}/FIELD.spad
+ @ echo 0 making ${MID}/FIELD.NRLIB from ${MID}/FIELD.spad
+ @ (cd ${MID} ; echo ')co FIELD.spad' | ${INTERPSYS} )
+
+@
+<<FIELD.spad (SPAD from IN)>>=
+${MID}/FIELD.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/FIELD.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FIELD.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FIELD Field" ${IN}/catdef.spad.pamphlet >FIELD.spad )
+
+@
+<<FINITE.o (O from NRLIB)>>=
+${OUT}/FINITE.o: ${MID}/FINITE.NRLIB
+ @ echo 0 making ${OUT}/FINITE.o from ${MID}/FINITE.NRLIB
+ @ cp ${MID}/FINITE.NRLIB/code.o ${OUT}/FINITE.o
+
+@
+<<FINITE.NRLIB (NRLIB from MID)>>=
+${MID}/FINITE.NRLIB: ${MID}/FINITE.spad
+ @ echo 0 making ${MID}/FINITE.NRLIB from ${MID}/FINITE.spad
+ @ (cd ${MID} ; echo ')co FINITE.spad' | ${INTERPSYS} )
+
+@
+<<FINITE.spad (SPAD from IN)>>=
+${MID}/FINITE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/FINITE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FINITE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FINITE Finite" ${IN}/catdef.spad.pamphlet >FINITE.spad )
+
+@
+<<FLINEXP-.o (O from NRLIB)>>=
+${OUT}/FLINEXP-.o: ${MID}/FLINEXP.NRLIB
+ @ echo 0 making ${OUT}/FLINEXP-.o from ${MID}/FLINEXP-.NRLIB
+ @ cp ${MID}/FLINEXP-.NRLIB/code.o ${OUT}/FLINEXP-.o
+
+@
+<<FLINEXP-.NRLIB (NRLIB from MID)>>=
+${MID}/FLINEXP-.NRLIB: ${OUT}/TYPE.o ${MID}/FLINEXP.spad
+ @ echo 0 making ${MID}/FLINEXP-.NRLIB from ${MID}/FLINEXP.spad
+ @ (cd ${MID} ; echo ')co FLINEXP.spad' | ${INTERPSYS} )
+
+@
+<<FLINEXP.o (O from NRLIB)>>=
+${OUT}/FLINEXP.o: ${MID}/FLINEXP.NRLIB
+ @ echo 0 making ${OUT}/FLINEXP.o from ${MID}/FLINEXP.NRLIB
+ @ cp ${MID}/FLINEXP.NRLIB/code.o ${OUT}/FLINEXP.o
+
+@
+<<FLINEXP.NRLIB (NRLIB from MID)>>=
+${MID}/FLINEXP.NRLIB: ${MID}/FLINEXP.spad
+ @ echo 0 making ${MID}/FLINEXP.NRLIB from ${MID}/FLINEXP.spad
+ @ (cd ${MID} ; echo ')co FLINEXP.spad' | ${INTERPSYS} )
+
+@
+<<FLINEXP.spad (SPAD from IN)>>=
+${MID}/FLINEXP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/FLINEXP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLINEXP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FLINEXP FullyLinearlyExplicitRingOver" ${IN}/catdef.spad.pamphlet >FLINEXP.spad )
+
+@
+<<GCDDOM-.o (O from NRLIB)>>=
+${OUT}/GCDDOM-.o: ${MID}/GCDDOM.NRLIB
+ @ echo 0 making ${OUT}/GCDDOM-.o from ${MID}/GCDDOM-.NRLIB
+ @ cp ${MID}/GCDDOM-.NRLIB/code.o ${OUT}/GCDDOM-.o
+
+@
+<<GCDDOM-.NRLIB (NRLIB from MID)>>=
+${MID}/GCDDOM-.NRLIB: ${OUT}/TYPE.o ${MID}/GCDDOM.spad
+ @ echo 0 making ${MID}/GCDDOM-.NRLIB from ${MID}/GCDDOM.spad
+ @ (cd ${MID} ; echo ')co GCDDOM.spad' | ${INTERPSYS} )
+
+@
+<<GCDDOM.o (O from NRLIB)>>=
+${OUT}/GCDDOM.o: ${MID}/GCDDOM.NRLIB
+ @ echo 0 making ${OUT}/GCDDOM.o from ${MID}/GCDDOM.NRLIB
+ @ cp ${MID}/GCDDOM.NRLIB/code.o ${OUT}/GCDDOM.o
+
+@
+<<GCDDOM.NRLIB (NRLIB from MID)>>=
+${MID}/GCDDOM.NRLIB: ${MID}/GCDDOM.spad
+ @ echo 0 making ${MID}/GCDDOM.NRLIB from ${MID}/GCDDOM.spad
+ @ (cd ${MID} ; echo ')co GCDDOM.spad' | ${INTERPSYS} )
+
+@
+<<GCDDOM.spad (SPAD from IN)>>=
+${MID}/GCDDOM.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/GCDDOM.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GCDDOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"category GCDDOM GcdDomain" ${IN}/catdef.spad.pamphlet >GCDDOM.spad )
+
+@
+<<GCDDOM-.o (BOOTSTRAP from MID)>>=
+${MID}/GCDDOM-.o: ${MID}/GCDDOM-.lsp
+ @ echo 0 making ${MID}/GCDDOM-.o from ${MID}/GCDDOM-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "GCDDOM-.lsp" :output-file "GCDDOM-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/GCDDOM-.o ${OUT}/GCDDOM-.o
+
+@
+<<GCDDOM-.lsp (LISP from IN)>>=
+${MID}/GCDDOM-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/GCDDOM-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GCDDOM-.NRLIB ; \
+ rm -rf ${OUT}/GCDDOM-.o ; \
+ ${SPADBIN}/notangle -R"GCDDOM-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >GCDDOM-.lsp )
+
+@
+<<GCDDOM.o (BOOTSTRAP from MID)>>=
+${MID}/GCDDOM.o: ${MID}/GCDDOM.lsp
+ @ echo 0 making ${MID}/GCDDOM.o from ${MID}/GCDDOM.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "GCDDOM.lsp" :output-file "GCDDOM.o"))' | ${DEPSYS} )
+ @ cp ${MID}/GCDDOM.o ${OUT}/GCDDOM.o
+
+@
+<<GCDDOM.lsp (LISP from IN)>>=
+${MID}/GCDDOM.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/GCDDOM.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GCDDOM.NRLIB ; \
+ rm -rf ${OUT}/GCDDOM.o ; \
+ ${SPADBIN}/notangle -R"GCDDOM.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >GCDDOM.lsp )
+
+@
+<<GROUP-.o (O from NRLIB)>>=
+${OUT}/GROUP-.o: ${MID}/GROUP.NRLIB
+ @ echo 0 making ${OUT}/GROUP-.o from ${MID}/GROUP-.NRLIB
+ @ cp ${MID}/GROUP-.NRLIB/code.o ${OUT}/GROUP-.o
+
+@
+<<GROUP-.NRLIB (NRLIB from MID)>>=
+${MID}/GROUP-.NRLIB: ${OUT}/TYPE.o ${MID}/GROUP.spad
+ @ echo 0 making ${MID}/GROUP-.NRLIB from ${MID}/GROUP.spad
+ @ (cd ${MID} ; echo ')co GROUP.spad' | ${INTERPSYS} )
+
+@
+<<GROUP.o (O from NRLIB)>>=
+${OUT}/GROUP.o: ${MID}/GROUP.NRLIB
+ @ echo 0 making ${OUT}/GROUP.o from ${MID}/GROUP.NRLIB
+ @ cp ${MID}/GROUP.NRLIB/code.o ${OUT}/GROUP.o
+
+@
+<<GROUP.NRLIB (NRLIB from MID)>>=
+${MID}/GROUP.NRLIB: ${MID}/GROUP.spad
+ @ echo 0 making ${MID}/GROUP.NRLIB from ${MID}/GROUP.spad
+ @ (cd ${MID} ; echo ')co GROUP.spad' | ${INTERPSYS} )
+
+@
+<<GROUP.spad (SPAD from IN)>>=
+${MID}/GROUP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/GROUP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GROUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category GROUP Group" ${IN}/catdef.spad.pamphlet >GROUP.spad )
+
+@
+<<INTDOM-.o (O from NRLIB)>>=
+${OUT}/INTDOM-.o: ${MID}/INTDOM.NRLIB
+ @ echo 0 making ${OUT}/INTDOM-.o from ${MID}/INTDOM-.NRLIB
+ @ cp ${MID}/INTDOM-.NRLIB/code.o ${OUT}/INTDOM-.o
+
+@
+<<INTDOM-.NRLIB (NRLIB from MID)>>=
+${MID}/INTDOM-.NRLIB: ${OUT}/TYPE.o ${MID}/INTDOM.spad
+ @ echo 0 making ${MID}/INTDOM-.NRLIB from ${MID}/INTDOM.spad
+ @ (cd ${MID} ; echo ')co INTDOM.spad' | ${INTERPSYS} )
+
+@
+<<INTDOM.o (O from NRLIB)>>=
+${OUT}/INTDOM.o: ${MID}/INTDOM.NRLIB
+ @ echo 0 making ${OUT}/INTDOM.o from ${MID}/INTDOM.NRLIB
+ @ cp ${MID}/INTDOM.NRLIB/code.o ${OUT}/INTDOM.o
+
+@
+<<INTDOM.NRLIB (NRLIB from MID)>>=
+${MID}/INTDOM.NRLIB: ${MID}/INTDOM.spad
+ @ echo 0 making ${MID}/INTDOM.NRLIB from ${MID}/INTDOM.spad
+ @ (cd ${MID} ; echo ')co INTDOM.spad' | ${INTERPSYS} )
+
+@
+<<INTDOM.spad (SPAD from IN)>>=
+${MID}/INTDOM.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/INTDOM.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTDOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"category INTDOM IntegralDomain" ${IN}/catdef.spad.pamphlet >INTDOM.spad )
+
+@
+<<INTDOM-.o (BOOTSTRAP from MID)>>=
+${MID}/INTDOM-.o: ${MID}/INTDOM-.lsp
+ @ echo 0 making ${MID}/INTDOM-.o from ${MID}/INTDOM-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "INTDOM-.lsp" :output-file "INTDOM-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/INTDOM-.o ${OUT}/INTDOM-.o
+
+@
+<<INTDOM-.lsp (LISP from IN)>>=
+${MID}/INTDOM-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/INTDOM-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTDOM-.NRLIB ; \
+ rm -rf ${OUT}/INTDOM-.o ; \
+ ${SPADBIN}/notangle -R"INTDOM-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >INTDOM-.lsp )
+
+@
+<<INTDOM.o (BOOTSTRAP from MID)>>=
+${MID}/INTDOM.o: ${MID}/INTDOM.lsp
+ @ echo 0 making ${MID}/INTDOM.o from ${MID}/INTDOM.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "INTDOM.lsp" :output-file "INTDOM.o"))' | ${DEPSYS} )
+ @ cp ${MID}/INTDOM.o ${OUT}/INTDOM.o
+
+@
+<<INTDOM.lsp (LISP from IN)>>=
+${MID}/INTDOM.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/INTDOM.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTDOM.NRLIB ; \
+ rm -rf ${OUT}/INTDOM.o ; \
+ ${SPADBIN}/notangle -R"INTDOM.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >INTDOM.lsp )
+
+@
+<<LINEXP.o (O from NRLIB)>>=
+${OUT}/LINEXP.o: ${MID}/LINEXP.NRLIB
+ @ echo 0 making ${OUT}/LINEXP.o from ${MID}/LINEXP.NRLIB
+ @ cp ${MID}/LINEXP.NRLIB/code.o ${OUT}/LINEXP.o
+
+@
+<<LINEXP.NRLIB (NRLIB from MID)>>=
+${MID}/LINEXP.NRLIB: ${MID}/LINEXP.spad
+ @ echo 0 making ${MID}/LINEXP.NRLIB from ${MID}/LINEXP.spad
+ @ (cd ${MID} ; echo ')co LINEXP.spad' | ${INTERPSYS} )
+
+@
+<<LINEXP.spad (SPAD from IN)>>=
+${MID}/LINEXP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/LINEXP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LINEXP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LINEXP LinearlyExplicitRingOver" ${IN}/catdef.spad.pamphlet >LINEXP.spad )
+
+@
+<<LMODULE.o (O from NRLIB)>>=
+${OUT}/LMODULE.o: ${MID}/LMODULE.NRLIB
+ @ echo 0 making ${OUT}/LMODULE.o from ${MID}/LMODULE.NRLIB
+ @ cp ${MID}/LMODULE.NRLIB/code.o ${OUT}/LMODULE.o
+
+@
+<<LMODULE.NRLIB (NRLIB from MID)>>=
+${MID}/LMODULE.NRLIB: ${OUT}/TYPE.o ${MID}/LMODULE.spad
+ @ echo 0 making ${MID}/LMODULE.NRLIB from ${MID}/LMODULE.spad
+ @ (cd ${MID} ; echo ')co LMODULE.spad' | ${INTERPSYS} )
+
+@
+<<LMODULE.spad (SPAD from IN)>>=
+${MID}/LMODULE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/LMODULE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LMODULE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LMODULE LeftModule" ${IN}/catdef.spad.pamphlet >LMODULE.spad )
+
+@
+<<MONOID-.o (O from NRLIB)>>=
+${OUT}/MONOID-.o: ${MID}/MONOID.NRLIB
+ @ echo 0 making ${OUT}/MONOID-.o from ${MID}/MONOID-.NRLIB
+ @ cp ${MID}/MONOID-.NRLIB/code.o ${OUT}/MONOID-.o
+
+@
+<<MONOID-.NRLIB (NRLIB from MID)>>=
+${MID}/MONOID-.NRLIB: ${OUT}/TYPE.o ${MID}/MONOID.spad
+ @ echo 0 making ${MID}/MONOID-.NRLIB from ${MID}/MONOID.spad
+ @ (cd ${MID} ; echo ')co MONOID.spad' | ${INTERPSYS} )
+
+@
+<<MONOID.o (O from NRLIB)>>=
+${OUT}/MONOID.o: ${MID}/MONOID.NRLIB
+ @ echo 0 making ${OUT}/MONOID.o from ${MID}/MONOID.NRLIB
+ @ cp ${MID}/MONOID.NRLIB/code.o ${OUT}/MONOID.o
+
+@
+<<MONOID.NRLIB (NRLIB from MID)>>=
+${MID}/MONOID.NRLIB: ${OUT}/TYPE.o ${MID}/MONOID.spad
+ @ echo 0 making ${MID}/MONOID.NRLIB from ${MID}/MONOID.spad
+ @ (cd ${MID} ; echo ')co MONOID.spad' | ${INTERPSYS} )
+
+@
+<<MONOID.spad (SPAD from IN)>>=
+${MID}/MONOID.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/MONOID.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONOID.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MONOID Monoid" ${IN}/catdef.spad.pamphlet >MONOID.spad )
+
+@
+<<MONOID-.o (BOOTSTRAP from MID)>>=
+${MID}/MONOID-.o: ${MID}/MONOID-.lsp
+ @ echo 0 making ${MID}/MONOID-.o from ${MID}/MONOID-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "MONOID-.lsp" :output-file "MONOID-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/MONOID-.o ${OUT}/MONOID-.o
+
+@
+<<MONOID-.lsp (LISP from IN)>>=
+${MID}/MONOID-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/MONOID-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONOID-.NRLIB ; \
+ rm -rf ${OUT}/MONOID-.o ; \
+ ${SPADBIN}/notangle -R"MONOID-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >MONOID-.lsp )
+
+@
+<<MONOID.o (BOOTSTRAP from MID)>>=
+${MID}/MONOID.o: ${MID}/MONOID.lsp
+ @ echo 0 making ${MID}/MONOID.o from ${MID}/MONOID.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "MONOID.lsp" :output-file "MONOID.o"))' | ${DEPSYS} )
+ @ cp ${MID}/MONOID.o ${OUT}/MONOID.o
+
+@
+<<MONOID.lsp (LISP from IN)>>=
+${MID}/MONOID.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/MONOID.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONOID.NRLIB ; \
+ rm -rf ${OUT}/MONOID.o ; \
+ ${SPADBIN}/notangle -R"MONOID.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >MONOID.lsp )
+
+@
+<<MODULE-.o (O from NRLIB)>>=
+${OUT}/MODULE-.o: ${MID}/MODULE.NRLIB
+ @ echo 0 making ${OUT}/MODULE-.o from ${MID}/MODULE-.NRLIB
+ @ cp ${MID}/MODULE-.NRLIB/code.o ${OUT}/MODULE-.o
+
+@
+<<MODULE-.NRLIB (NRLIB from MID)>>=
+${MID}/MODULE-.NRLIB: ${OUT}/TYPE.o ${MID}/MODULE.spad
+ @ echo 0 making ${MID}/MODULE-.NRLIB from ${MID}/MODULE.spad
+ @ (cd ${MID} ; echo ')co MODULE.spad' | ${INTERPSYS} )
+
+@
+<<MODULE.o (O from NRLIB)>>=
+${OUT}/MODULE.o: ${MID}/MODULE.NRLIB
+ @ echo 0 making ${OUT}/MODULE.o from ${MID}/MODULE.NRLIB
+ @ cp ${MID}/MODULE.NRLIB/code.o ${OUT}/MODULE.o
+
+@
+<<MODULE.NRLIB (NRLIB from MID)>>=
+${MID}/MODULE.NRLIB: ${MID}/MODULE.spad
+ @ echo 0 making ${MID}/MODULE.NRLIB from ${MID}/MODULE.spad
+ @ (cd ${MID} ; echo ')co MODULE.spad' | ${INTERPSYS} )
+
+@
+<<MODULE.spad (SPAD from IN)>>=
+${MID}/MODULE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/MODULE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MODULE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MODULE Module" ${IN}/catdef.spad.pamphlet >MODULE.spad )
+
+@
+<<OCAMON.o (O from NRLIB)>>=
+${OUT}/OCAMON.o: ${MID}/OCAMON.NRLIB
+ @ echo 0 making ${OUT}/OCAMON.o from ${MID}/OCAMON.NRLIB
+ @ cp ${MID}/OCAMON.NRLIB/code.o ${OUT}/OCAMON.o
+
+@
+<<OCAMON.NRLIB (NRLIB from MID)>>=
+${MID}/OCAMON.NRLIB: ${OUT}/TYPE.o ${MID}/OCAMON.spad
+ @ echo 0 making ${MID}/OCAMON.NRLIB from ${MID}/OCAMON.spad
+ @ (cd ${MID} ; echo ')co OCAMON.spad' | ${INTERPSYS} )
+
+@
+<<OCAMON.spad (SPAD from IN)>>=
+${MID}/OCAMON.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OCAMON.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OCAMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OCAMON OrderedCancellationAbelianMonoid" ${IN}/catdef.spad.pamphlet >OCAMON.spad )
+
+@
+<<OAGROUP.o (O from NRLIB)>>=
+${OUT}/OAGROUP.o: ${MID}/OAGROUP.NRLIB
+ @ echo 0 making ${OUT}/OAGROUP.o from ${MID}/OAGROUP.NRLIB
+ @ cp ${MID}/OAGROUP.NRLIB/code.o ${OUT}/OAGROUP.o
+
+@
+<<OAGROUP.NRLIB (NRLIB from MID)>>=
+${MID}/OAGROUP.NRLIB: ${MID}/OAGROUP.spad
+ @ echo 0 making ${MID}/OAGROUP.NRLIB from ${MID}/OAGROUP.spad
+ @ (cd ${MID} ; echo ')co OAGROUP.spad' | ${INTERPSYS} )
+
+@
+<<OAGROUP.spad (SPAD from IN)>>=
+${MID}/OAGROUP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OAGROUP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OAGROUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OAGROUP OrderedAbelianGroup" ${IN}/catdef.spad.pamphlet >OAGROUP.spad )
+
+@
+<<OAMON.o (O from NRLIB)>>=
+${OUT}/OAMON.o: ${MID}/OAMON.NRLIB
+ @ echo 0 making ${OUT}/OAMON.o from ${MID}/OAMON.NRLIB
+ @ cp ${MID}/OAMON.NRLIB/code.o ${OUT}/OAMON.o
+
+@
+<<OAMON.NRLIB (NRLIB from MID)>>=
+${MID}/OAMON.NRLIB: ${OUT}/TYPE.o ${MID}/OAMON.spad
+ @ echo 0 making ${MID}/OAMON.NRLIB from ${MID}/OAMON.spad
+ @ (cd ${MID} ; echo ')co OAMON.spad' | ${INTERPSYS} )
+
+@
+<<OAMON.spad (SPAD from IN)>>=
+${MID}/OAMON.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OAMON.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OAMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OAMON OrderedAbelianMonoid" ${IN}/catdef.spad.pamphlet >OAMON.spad )
+
+@
+<<OAMONS.o (O from NRLIB)>>=
+${OUT}/OAMONS.o: ${MID}/OAMONS.NRLIB
+ @ echo 0 making ${OUT}/OAMONS.o from ${MID}/OAMONS.NRLIB
+ @ cp ${MID}/OAMONS.NRLIB/code.o ${OUT}/OAMONS.o
+
+@
+<<OAMONS.NRLIB (NRLIB from MID)>>=
+${MID}/OAMONS.NRLIB: ${OUT}/TYPE.o ${MID}/OAMONS.spad
+ @ echo 0 making ${MID}/OAMONS.NRLIB from ${MID}/OAMONS.spad
+ @ (cd ${MID} ; echo ')co OAMONS.spad' | ${INTERPSYS} )
+
+@
+<<OAMONS.spad (SPAD from IN)>>=
+${MID}/OAMONS.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OAMONS.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OAMONS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OAMONS OrderedAbelianMonoidSup" ${IN}/catdef.spad.pamphlet >OAMONS.spad )
+
+@
+<<OASGP.o (O from NRLIB)>>=
+${OUT}/OASGP.o: ${MID}/OASGP.NRLIB
+ @ echo 0 making ${OUT}/OASGP.o from ${MID}/OASGP.NRLIB
+ @ cp ${MID}/OASGP.NRLIB/code.o ${OUT}/OASGP.o
+
+@
+<<OASGP.NRLIB (NRLIB from MID)>>=
+${MID}/OASGP.NRLIB: ${OUT}/TYPE.o ${MID}/OASGP.spad
+ @ echo 0 making ${MID}/OASGP.NRLIB from ${MID}/OASGP.spad
+ @ (cd ${MID} ; echo ')co OASGP.spad' | ${INTERPSYS} )
+
+@
+<<OASGP.spad (SPAD from IN)>>=
+${MID}/OASGP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OASGP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OASGP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OASGP OrderedAbelianSemiGroup" ${IN}/catdef.spad.pamphlet >OASGP.spad )
+
+@
+<<ORDFIN.o (O from NRLIB)>>=
+${OUT}/ORDFIN.o: ${MID}/ORDFIN.NRLIB
+ @ echo 0 making ${OUT}/ORDFIN.o from ${MID}/ORDFIN.NRLIB
+ @ cp ${MID}/ORDFIN.NRLIB/code.o ${OUT}/ORDFIN.o
+
+@
+<<ORDFIN.NRLIB (NRLIB from MID)>>=
+${MID}/ORDFIN.NRLIB: ${OUT}/TYPE.o ${MID}/ORDFIN.spad
+ @ echo 0 making ${MID}/ORDFIN.NRLIB from ${MID}/ORDFIN.spad
+ @ (cd ${MID} ; echo ')co ORDFIN.spad' | ${INTERPSYS} )
+
+@
+<<ORDFIN.spad (SPAD from IN)>>=
+${MID}/ORDFIN.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ORDFIN.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDFIN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ORDFIN OrderedFinite" ${IN}/catdef.spad.pamphlet >ORDFIN.spad )
+
+@
+<<OINTDOM.o (O from NRLIB)>>=
+${OUT}/OINTDOM.o: ${MID}/OINTDOM.NRLIB
+ @ echo 0 making ${OUT}/OINTDOM.o from ${MID}/OINTDOM.NRLIB
+ @ cp ${MID}/OINTDOM.NRLIB/code.o ${OUT}/OINTDOM.o
+
+@
+<<OINTDOM.NRLIB (NRLIB from MID)>>=
+${MID}/OINTDOM.NRLIB: ${MID}/OINTDOM.spad
+ @ echo 0 making ${MID}/OINTDOM.NRLIB from ${MID}/OINTDOM.spad
+ @ (cd ${MID} ; echo ')co OINTDOM.spad' | ${INTERPSYS} )
+
+@
+<<OINTDOM.spad (SPAD from IN)>>=
+${MID}/OINTDOM.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OINTDOM.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OINTDOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OINTDOM OrderedIntegralDomain" ${IN}/catdef.spad.pamphlet >OINTDOM.spad )
+
+@
+<<OINTDOM.o (BOOTSTRAP from MID)>>=
+${MID}/OINTDOM.o: ${MID}/OINTDOM.lsp
+ @ echo 0 making ${MID}/OINTDOM.o from ${MID}/OINTDOM.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "OINTDOM.lsp" :output-file "OINTDOM.o"))' | ${DEPSYS} )
+ @ cp ${MID}/OINTDOM.o ${OUT}/OINTDOM.o
+
+@
+<<OINTDOM.lsp (LISP from IN)>>=
+${MID}/OINTDOM.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/OINTDOM.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OINTDOM.NRLIB ; \
+ rm -rf ${OUT}/OINTDOM.o ; \
+ ${SPADBIN}/notangle -R"OINTDOM.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >OINTDOM.lsp )
+
+@
+<<ORDMON.o (O from NRLIB)>>=
+${OUT}/ORDMON.o: ${MID}/ORDMON.NRLIB
+ @ echo 0 making ${OUT}/ORDMON.o from ${MID}/ORDMON.NRLIB
+ @ cp ${MID}/ORDMON.NRLIB/code.o ${OUT}/ORDMON.o
+
+@
+<<ORDMON.NRLIB (NRLIB from MID)>>=
+${MID}/ORDMON.NRLIB: ${MID}/ORDMON.spad
+ @ echo 0 making ${MID}/ORDMON.NRLIB from ${MID}/ORDMON.spad
+ @ (cd ${MID} ; echo ')co ORDMON.spad' | ${INTERPSYS} )
+
+@
+<<ORDMON.spad (SPAD from IN)>>=
+${MID}/ORDMON.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ORDMON.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ORDMON OrderedMonoid" ${IN}/catdef.spad.pamphlet >ORDMON.spad )
+
+@
+<<ORDRING-.o (O from NRLIB)>>=
+${OUT}/ORDRING-.o: ${MID}/ORDRING.NRLIB
+ @ echo 0 making ${OUT}/ORDRING-.o from ${MID}/ORDRING-.NRLIB
+ @ cp ${MID}/ORDRING-.NRLIB/code.o ${OUT}/ORDRING-.o
+
+@
+<<ORDRING-.NRLIB (NRLIB from MID)>>=
+${MID}/ORDRING-.NRLIB: ${OUT}/TYPE.o ${MID}/ORDRING.spad
+ @ echo 0 making ${MID}/ORDRING-.NRLIB from ${MID}/ORDRING.spad
+ @ (cd ${MID} ; echo ')co ORDRING.spad' | ${INTERPSYS} )
+
+@
+<<ORDRING.o (O from NRLIB)>>=
+${OUT}/ORDRING.o: ${MID}/ORDRING.NRLIB
+ @ echo 0 making ${OUT}/ORDRING.o from ${MID}/ORDRING.NRLIB
+ @ cp ${MID}/ORDRING.NRLIB/code.o ${OUT}/ORDRING.o
+
+@
+<<ORDRING.NRLIB (NRLIB from MID)>>=
+${MID}/ORDRING.NRLIB: ${MID}/ORDRING.spad
+ @ echo 0 making ${MID}/ORDRING.NRLIB from ${MID}/ORDRING.spad
+ @ (cd ${MID} ; echo ')co ORDRING.spad' | ${INTERPSYS} )
+
+@
+<<ORDRING.spad (SPAD from IN)>>=
+${MID}/ORDRING.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ORDRING.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ORDRING OrderedRing" ${IN}/catdef.spad.pamphlet >ORDRING.spad )
+
+@
+<<ORDRING-.o (BOOTSTRAP from MID)>>=
+${MID}/ORDRING-.o: ${MID}/ORDRING-.lsp
+ @ echo 0 making ${MID}/ORDRING-.o from ${MID}/ORDRING-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ORDRING-.lsp" :output-file "ORDRING-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ORDRING-.o ${OUT}/ORDRING-.o
+
+@
+<<ORDRING-.lsp (LISP from IN)>>=
+${MID}/ORDRING-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ORDRING-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDRING-.NRLIB ; \
+ rm -rf ${OUT}/ORDRING-.o ; \
+ ${SPADBIN}/notangle -R"ORDRING-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ORDRING-.lsp )
+
+@
+<<ORDRING.o (BOOTSTRAP from MID)>>=
+${MID}/ORDRING.o: ${MID}/ORDRING.lsp
+ @ echo 0 making ${MID}/ORDRING.o from ${MID}/ORDRING.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ORDRING.lsp" :output-file "ORDRING.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ORDRING.o ${OUT}/ORDRING.o
+
+@
+<<ORDRING.lsp (LISP from IN)>>=
+${MID}/ORDRING.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ORDRING.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDRING.NRLIB ; \
+ rm -rf ${OUT}/ORDRING.o ; \
+ ${SPADBIN}/notangle -R"ORDRING.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >ORDRING.lsp )
+
+@
+<<ORDSET-.o (O from NRLIB)>>=
+${OUT}/ORDSET-.o: ${MID}/ORDSET.NRLIB
+ @ echo 0 making ${OUT}/ORDSET-.o from ${MID}/ORDSET-.NRLIB
+ @ cp ${MID}/ORDSET-.NRLIB/code.o ${OUT}/ORDSET-.o
+
+@
+<<ORDSET-.NRLIB (NRLIB from MID)>>=
+${MID}/ORDSET-.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/ORDSET.spad
+ @ echo 0 making ${MID}/ORDSET-.NRLIB from ${MID}/ORDSET.spad
+ @ (cd ${MID} ; echo ')co ORDSET.spad' | ${INTERPSYS} )
+
+@
+<<ORDSET.o (O from NRLIB)>>=
+${OUT}/ORDSET.o: ${MID}/ORDSET.NRLIB
+ @ echo 0 making ${OUT}/ORDSET.o from ${MID}/ORDSET.NRLIB
+ @ cp ${MID}/ORDSET.NRLIB/code.o ${OUT}/ORDSET.o
+
+@
+<<ORDSET.NRLIB (NRLIB from MID)>>=
+${MID}/ORDSET.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/ORDSET.spad
+ @ echo 0 making ${MID}/ORDSET.NRLIB from ${MID}/ORDSET.spad
+ @ (cd ${MID} ; echo ')co ORDSET.spad' | ${INTERPSYS} )
+
+@
+<<ORDSET.spad (SPAD from IN)>>=
+${MID}/ORDSET.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/ORDSET.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ORDSET OrderedSet" ${IN}/catdef.spad.pamphlet >ORDSET.spad )
+
+@
+<<PDRING-.o (O from NRLIB)>>=
+${OUT}/PDRING-.o: ${MID}/PDRING.NRLIB
+ @ echo 0 making ${OUT}/PDRING-.o from ${MID}/PDRING-.NRLIB
+ @ cp ${MID}/PDRING-.NRLIB/code.o ${OUT}/PDRING-.o
+
+@
+<<PDRING-.NRLIB (NRLIB from MID)>>=
+${MID}/PDRING-.NRLIB: ${OUT}/TYPE.o ${MID}/PDRING.spad
+ @ echo 0 making ${MID}/PDRING-.NRLIB from ${MID}/PDRING.spad
+ @ (cd ${MID} ; echo ')co PDRING.spad' | ${INTERPSYS} )
+
+@
+<<PDRING.o (O from NRLIB)>>=
+${OUT}/PDRING.o: ${MID}/PDRING.NRLIB
+ @ echo 0 making ${OUT}/PDRING.o from ${MID}/PDRING.NRLIB
+ @ cp ${MID}/PDRING.NRLIB/code.o ${OUT}/PDRING.o
+
+@
+<<PDRING.NRLIB (NRLIB from MID)>>=
+${MID}/PDRING.NRLIB: ${MID}/PDRING.spad
+ @ echo 0 making ${MID}/PDRING.NRLIB from ${MID}/PDRING.spad
+ @ (cd ${MID} ; echo ')co PDRING.spad' | ${INTERPSYS} )
+
+@
+<<PDRING.spad (SPAD from IN)>>=
+${MID}/PDRING.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/PDRING.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PDRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PDRING PartialDifferentialRing" ${IN}/catdef.spad.pamphlet >PDRING.spad )
+
+@
+<<PID.o (O from NRLIB)>>=
+${OUT}/PID.o: ${MID}/PID.NRLIB
+ @ echo 0 making ${OUT}/PID.o from ${MID}/PID.NRLIB
+ @ cp ${MID}/PID.NRLIB/code.o ${OUT}/PID.o
+
+@
+<<PID.NRLIB (NRLIB from MID)>>=
+${MID}/PID.NRLIB: ${MID}/PID.spad
+ @ echo 0 making ${MID}/PID.NRLIB from ${MID}/PID.spad
+ @ (cd ${MID} ; echo ')co PID.spad' | ${INTERPSYS} )
+
+@
+<<PID.spad (SPAD from IN)>>=
+${MID}/PID.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/PID.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PID.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PID PrincipalIdealDomain" ${IN}/catdef.spad.pamphlet >PID.spad )
+
+@
+<<PFECAT-.o (O from NRLIB)>>=
+${OUT}/PFECAT-.o: ${MID}/PFECAT.NRLIB
+ @ echo 0 making ${OUT}/PFECAT-.o from ${MID}/PFECAT-.NRLIB
+ @ cp ${MID}/PFECAT-.NRLIB/code.o ${OUT}/PFECAT-.o
+
+@
+<<PFECAT-.NRLIB (NRLIB from MID)>>=
+${MID}/PFECAT-.NRLIB: ${OUT}/TYPE.o ${MID}/PFECAT.spad
+ @ echo 0 making ${MID}/PFECAT-.NRLIB from ${MID}/PFECAT.spad
+ @ (cd ${MID} ; echo ')co PFECAT.spad' | ${INTERPSYS} )
+
+@
+<<PFECAT.o (O from NRLIB)>>=
+${OUT}/PFECAT.o: ${MID}/PFECAT.NRLIB
+ @ echo 0 making ${OUT}/PFECAT.o from ${MID}/PFECAT.NRLIB
+ @ cp ${MID}/PFECAT.NRLIB/code.o ${OUT}/PFECAT.o
+
+@
+<<PFECAT.NRLIB (NRLIB from MID)>>=
+${MID}/PFECAT.NRLIB: ${MID}/PFECAT.spad
+ @ echo 0 making ${MID}/PFECAT.NRLIB from ${MID}/PFECAT.spad
+ @ (cd ${MID} ; echo ')co PFECAT.spad' | ${INTERPSYS} )
+
+@
+<<PFECAT.spad (SPAD from IN)>>=
+${MID}/PFECAT.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/PFECAT.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFECAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PFECAT PolynomialFactorizationExplicit" ${IN}/catdef.spad.pamphlet >PFECAT.spad )
+
+@
+<<RMODULE.o (O from NRLIB)>>=
+${OUT}/RMODULE.o: ${MID}/RMODULE.NRLIB
+ @ echo 0 making ${OUT}/RMODULE.o from ${MID}/RMODULE.NRLIB
+ @ cp ${MID}/RMODULE.NRLIB/code.o ${OUT}/RMODULE.o
+
+@
+<<RMODULE.NRLIB (NRLIB from MID)>>=
+${MID}/RMODULE.NRLIB: ${OUT}/TYPE.o ${MID}/RMODULE.spad
+ @ echo 0 making ${MID}/RMODULE.NRLIB from ${MID}/RMODULE.spad
+ @ (cd ${MID} ; echo ')co RMODULE.spad' | ${INTERPSYS} )
+
+@
+<<RMODULE.spad (SPAD from IN)>>=
+${MID}/RMODULE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/RMODULE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RMODULE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RMODULE RightModule" ${IN}/catdef.spad.pamphlet >RMODULE.spad )
+
+@
+<<RING-.o (O from NRLIB)>>=
+${OUT}/RING-.o: ${MID}/RING.NRLIB
+ @ echo 0 making ${OUT}/RING-.o from ${MID}/RING-.NRLIB
+ @ cp ${MID}/RING-.NRLIB/code.o ${OUT}/RING-.o
+
+@
+<<RING-.NRLIB (NRLIB from MID)>>=
+${MID}/RING-.NRLIB: ${OUT}/TYPE.o ${MID}/RING.spad
+ @ echo 0 making ${MID}/RING-.NRLIB from ${MID}/RING.spad
+ @ (cd ${MID} ; echo ')co RING.spad' | ${INTERPSYS} )
+
+@
+<<RING.o (O from NRLIB)>>=
+${OUT}/RING.o: ${MID}/RING.NRLIB
+ @ echo 0 making ${OUT}/RING.o from ${MID}/RING.NRLIB
+ @ cp ${MID}/RING.NRLIB/code.o ${OUT}/RING.o
+
+@
+<<RING.NRLIB (NRLIB from MID)>>=
+${MID}/RING.NRLIB: ${MID}/RING.spad
+ @ echo 0 making ${MID}/RING.NRLIB from ${MID}/RING.spad
+ @ (cd ${MID} ; echo ')co RING.spad' | ${INTERPSYS} )
+
+@
+<<RING.spad (SPAD from IN)>>=
+${MID}/RING.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/RING.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RING Ring" ${IN}/catdef.spad.pamphlet >RING.spad )
+
+@
+<<RING-.o (BOOTSTRAP from MID)>>=
+${MID}/RING-.o: ${MID}/RING-.lsp
+ @ echo 0 making ${MID}/RING-.o from ${MID}/RING-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RING-.lsp" :output-file "RING-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RING-.o ${OUT}/RING-.o
+
+@
+<<RING-.lsp (LISP from IN)>>=
+${MID}/RING-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/RING-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RING-.NRLIB ; \
+ rm -rf ${OUT}/RING-.o ; \
+ ${SPADBIN}/notangle -R"RING-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >RING-.lsp )
+
+@
+<<RING.o (BOOTSTRAP from MID)>>=
+${MID}/RING.o: ${MID}/RING.lsp
+ @ echo 0 making ${MID}/RING.o from ${MID}/RING.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RING.lsp" :output-file "RING.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RING.o ${OUT}/RING.o
+
+@
+<<RING.lsp (LISP from IN)>>=
+${MID}/RING.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/RING.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RING.NRLIB ; \
+ rm -rf ${OUT}/RING.o ; \
+ ${SPADBIN}/notangle -R"RING.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >RING.lsp )
+
+@
+<<RNG.o (O from NRLIB)>>=
+${OUT}/RNG.o: ${MID}/RNG.NRLIB
+ @ echo 0 making ${OUT}/RNG.o from ${MID}/RNG.NRLIB
+ @ cp ${MID}/RNG.NRLIB/code.o ${OUT}/RNG.o
+
+@
+<<RNG.NRLIB (NRLIB from MID)>>=
+${MID}/RNG.NRLIB: ${MID}/RNG.spad
+ @ echo 0 making ${MID}/RNG.NRLIB from ${MID}/RNG.spad
+ @ (cd ${MID} ; echo ')co RNG.spad' | ${INTERPSYS} )
+
+@
+<<RNG.spad (SPAD from IN)>>=
+${MID}/RNG.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/RNG.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RNG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RNG Rng" ${IN}/catdef.spad.pamphlet >RNG.spad )
+
+@
+<<RNG.o (BOOTSTRAP from MID)>>=
+${MID}/RNG.o: ${MID}/RNG.lsp
+ @ echo 0 making ${MID}/RNG.o from ${MID}/RNG.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RNG.lsp" :output-file "RNG.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RNG.o ${OUT}/RNG.o
+
+@
+<<RNG.lsp (LISP from IN)>>=
+${MID}/RNG.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/RNG.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RNG.NRLIB ; \
+ rm -rf ${OUT}/RNG.o ; \
+ ${SPADBIN}/notangle -R"RNG.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >RNG.lsp )
+
+@
+<<SETCAT-.o (O from NRLIB)>>=
+${OUT}/SETCAT-.o: ${MID}/SETCAT.NRLIB
+ @ echo 0 making ${OUT}/SETCAT-.o from ${MID}/SETCAT-.NRLIB
+ @ cp ${MID}/SETCAT-.NRLIB/code.o ${OUT}/SETCAT-.o
+
+@
+<<SETCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/SETCAT-.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${OUT}/SINT.o \
+ ${MID}/SETCAT.spad
+ @ echo 0 making ${MID}/SETCAT-.NRLIB from ${MID}/SETCAT.spad
+ @ (cd ${MID} ; echo ')co SETCAT.spad' | ${INTERPSYS} )
+
+@
+<<SETCAT-.o (BOOTSTRAP from MID)>>=
+${MID}/SETCAT-.o: ${MID}/SETCAT-.lsp
+ @ echo 0 making ${MID}/SETCAT-.o from ${MID}/SETCAT-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "SETCAT-.lsp" :output-file "SETCAT-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/SETCAT-.o ${OUT}/SETCAT-.o
+
+@
+<<SETCAT-.lsp (LISP from IN)>>=
+${MID}/SETCAT-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/SETCAT-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETCAT-.NRLIB ; \
+ rm -rf ${OUT}/SETCAT-.o ; \
+ ${SPADBIN}/notangle -R"SETCAT-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >SETCAT-.lsp )
+
+@
+<<SETCAT.o (O from NRLIB)>>=
+${OUT}/SETCAT.o: ${MID}/SETCAT.NRLIB
+ @ echo 0 making ${OUT}/SETCAT.o from ${MID}/SETCAT.NRLIB
+ @ cp ${MID}/SETCAT.NRLIB/code.o ${OUT}/SETCAT.o
+
+@
+<<SETCAT.NRLIB (NRLIB from MID)>>=
+${MID}/SETCAT.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/SETCAT.spad
+ @ echo 0 making ${MID}/SETCAT.NRLIB from ${MID}/SETCAT.spad
+ @ (cd ${MID} ; echo ')co SETCAT.spad' | ${INTERPSYS} )
+
+@
+<<SETCAT.spad (SPAD from IN)>>=
+${MID}/SETCAT.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/SETCAT.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SETCAT SetCategory" ${IN}/catdef.spad.pamphlet >SETCAT.spad )
+
+@
+<<SETCAT.o (BOOTSTRAP from MID)>>=
+${MID}/SETCAT.o: ${MID}/SETCAT.lsp
+ @ echo 0 making ${MID}/SETCAT.o from ${MID}/SETCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "SETCAT.lsp" :output-file "SETCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/SETCAT.o ${OUT}/SETCAT.o
+
+@
+<<SETCAT.lsp (LISP from IN)>>=
+${MID}/SETCAT.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/SETCAT.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETCAT.NRLIB ; \
+ rm -rf ${OUT}/SETCAT.o ; \
+ ${SPADBIN}/notangle -R"SETCAT.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >SETCAT.lsp )
+
+@
+<<SGROUP-.o (O from NRLIB)>>=
+${OUT}/SGROUP-.o: ${MID}/SGROUP.NRLIB
+ @ echo 0 making ${OUT}/SGROUP-.o from ${MID}/SGROUP-.NRLIB
+ @ cp ${MID}/SGROUP-.NRLIB/code.o ${OUT}/SGROUP-.o
+
+@
+<<SGROUP-.NRLIB (NRLIB from MID)>>=
+${MID}/SGROUP-.NRLIB: ${OUT}/TYPE.o ${MID}/SGROUP.spad
+ @ echo 0 making ${MID}/SGROUP-.NRLIB from ${MID}/SGROUP.spad
+ @ (cd ${MID} ; echo ')co SGROUP.spad' | ${INTERPSYS} )
+
+@
+<<SGROUP.o (O from NRLIB)>>=
+${OUT}/SGROUP.o: ${MID}/SGROUP.NRLIB
+ @ echo 0 making ${OUT}/SGROUP.o from ${MID}/SGROUP.NRLIB
+ @ cp ${MID}/SGROUP.NRLIB/code.o ${OUT}/SGROUP.o
+
+@
+<<SGROUP.NRLIB (NRLIB from MID)>>=
+${MID}/SGROUP.NRLIB: ${MID}/SGROUP.spad
+ @ echo 0 making ${MID}/SGROUP.NRLIB from ${MID}/SGROUP.spad
+ @ (cd ${MID} ; echo ')co SGROUP.spad' | ${INTERPSYS} )
+
+@
+<<SGROUP.spad (SPAD from IN)>>=
+${MID}/SGROUP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/SGROUP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SGROUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SGROUP SemiGroup" ${IN}/catdef.spad.pamphlet >SGROUP.spad )
+
+@
+<<STEP.o (O from NRLIB)>>=
+${OUT}/STEP.o: ${MID}/STEP.NRLIB
+ @ echo 0 making ${OUT}/STEP.o from ${MID}/STEP.NRLIB
+ @ cp ${MID}/STEP.NRLIB/code.o ${OUT}/STEP.o
+
+@
+<<STEP.NRLIB (NRLIB from MID)>>=
+${MID}/STEP.NRLIB: ${MID}/STEP.spad
+ @ echo 0 making ${MID}/STEP.NRLIB from ${MID}/STEP.spad
+ @ (cd ${MID} ; echo ')co STEP.spad' | ${INTERPSYS} )
+
+@
+<<STEP.spad (SPAD from IN)>>=
+${MID}/STEP.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/STEP.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STEP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category STEP StepThrough" ${IN}/catdef.spad.pamphlet >STEP.spad )
+
+@
+<<UFD-.o (O from NRLIB)>>=
+${OUT}/UFD-.o: ${MID}/UFD.NRLIB
+ @ echo 0 making ${OUT}/UFD-.o from ${MID}/UFD-.NRLIB
+ @ cp ${MID}/UFD-.NRLIB/code.o ${OUT}/UFD-.o
+
+@
+<<UFD-.NRLIB (NRLIB from MID)>>=
+${MID}/UFD-.NRLIB: ${OUT}/TYPE.o ${MID}/UFD.spad
+ @ echo 0 making ${MID}/UFD-.NRLIB from ${MID}/UFD.spad
+ @ (cd ${MID} ; echo ')co UFD.spad' | ${INTERPSYS} )
+
+@
+<<UFD.o (O from NRLIB)>>=
+${OUT}/UFD.o: ${MID}/UFD.NRLIB
+ @ echo 0 making ${OUT}/UFD.o from ${MID}/UFD.NRLIB
+ @ cp ${MID}/UFD.NRLIB/code.o ${OUT}/UFD.o
+
+@
+<<UFD.NRLIB (NRLIB from MID)>>=
+${MID}/UFD.NRLIB: ${MID}/UFD.spad
+ @ echo 0 making ${MID}/UFD.NRLIB from ${MID}/UFD.spad
+ @ (cd ${MID} ; echo ')co UFD.spad' | ${INTERPSYS} )
+
+@
+<<UFD.spad (SPAD from IN)>>=
+${MID}/UFD.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/UFD.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UFD.NRLIB ; \
+ ${SPADBIN}/notangle -R"category UFD UniqueFactorizationDomain" ${IN}/catdef.spad.pamphlet >UFD.spad )
+
+@
+<<UFD-.o (BOOTSTRAP from MID)>>=
+${MID}/UFD-.o: ${MID}/UFD-.lsp
+ @ echo 0 making ${MID}/UFD-.o from ${MID}/UFD-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "UFD-.lsp" :output-file "UFD-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/UFD-.o ${OUT}/UFD-.o
+
+@
+<<UFD-.lsp (LISP from IN)>>=
+${MID}/UFD-.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/UFD-.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UFD-.NRLIB ; \
+ rm -rf ${OUT}/UFD-.o ; \
+ ${SPADBIN}/notangle -R"UFD-.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >UFD-.lsp )
+
+@
+<<UFD.o (BOOTSTRAP from MID)>>=
+${MID}/UFD.o: ${MID}/UFD.lsp
+ @ echo 0 making ${MID}/UFD.o from ${MID}/UFD.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "UFD.lsp" :output-file "UFD.o"))' | ${DEPSYS} )
+ @ cp ${MID}/UFD.o ${OUT}/UFD.o
+
+@
+<<UFD.lsp (LISP from IN)>>=
+${MID}/UFD.lsp: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/UFD.lsp from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UFD.NRLIB ; \
+ rm -rf ${OUT}/UFD.o ; \
+ ${SPADBIN}/notangle -R"UFD.lsp BOOTSTRAP" ${IN}/catdef.spad.pamphlet >UFD.lsp )
+
+@
+<<VSPACE-.o (O from NRLIB)>>=
+${OUT}/VSPACE-.o: ${MID}/VSPACE.NRLIB
+ @ echo 0 making ${OUT}/VSPACE-.o from ${MID}/VSPACE-.NRLIB
+ @ cp ${MID}/VSPACE-.NRLIB/code.o ${OUT}/VSPACE-.o
+
+@
+<<VSPACE-.NRLIB (NRLIB from MID)>>=
+${MID}/VSPACE-.NRLIB: ${OUT}/TYPE.o ${MID}/VSPACE.spad
+ @ echo 0 making ${MID}/VSPACE-.NRLIB from ${MID}/VSPACE.spad
+ @ (cd ${MID} ; echo ')co VSPACE.spad' | ${INTERPSYS} )
+
+@
+<<VSPACE.o (O from NRLIB)>>=
+${OUT}/VSPACE.o: ${MID}/VSPACE.NRLIB
+ @ echo 0 making ${OUT}/VSPACE.o from ${MID}/VSPACE.NRLIB
+ @ cp ${MID}/VSPACE.NRLIB/code.o ${OUT}/VSPACE.o
+
+@
+<<VSPACE.NRLIB (NRLIB from MID)>>=
+${MID}/VSPACE.NRLIB: ${MID}/VSPACE.spad
+ @ echo 0 making ${MID}/VSPACE.NRLIB from ${MID}/VSPACE.spad
+ @ (cd ${MID} ; echo ')co VSPACE.spad' | ${INTERPSYS} )
+
+@
+<<VSPACE.spad (SPAD from IN)>>=
+${MID}/VSPACE.spad: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${MID}/VSPACE.spad from ${IN}/catdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VSPACE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category VSPACE VectorSpace" ${IN}/catdef.spad.pamphlet >VSPACE.spad )
+
+@
+<<catdef.spad.dvi (DOC from IN)>>=
+${DOC}/catdef.spad.dvi: ${IN}/catdef.spad.pamphlet
+ @ echo 0 making ${DOC}/catdef.spad.dvi from ${IN}/catdef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/catdef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} catdef.spad ; \
+ rm -f ${DOC}/catdef.spad.pamphlet ; \
+ rm -f ${DOC}/catdef.spad.tex ; \
+ rm -f ${DOC}/catdef.spad )
+
+@
+\subsection{cden.spad \cite{1}}
+<<cden.spad (SPAD from IN)>>=
+${MID}/cden.spad: ${IN}/cden.spad.pamphlet
+ @ echo 0 making ${MID}/cden.spad from ${IN}/cden.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/cden.spad.pamphlet >cden.spad )
+
+@
+<<CDEN.o (O from NRLIB)>>=
+${OUT}/CDEN.o: ${MID}/CDEN.NRLIB
+ @ echo 0 making ${OUT}/CDEN.o from ${MID}/CDEN.NRLIB
+ @ cp ${MID}/CDEN.NRLIB/code.o ${OUT}/CDEN.o
+
+@
+<<CDEN.NRLIB (NRLIB from MID)>>=
+${MID}/CDEN.NRLIB: ${MID}/CDEN.spad
+ @ echo 0 making ${MID}/CDEN.NRLIB from ${MID}/CDEN.spad
+ @ (cd ${MID} ; echo ')co CDEN.spad' | ${INTERPSYS} )
+
+@
+<<CDEN.spad (SPAD from IN)>>=
+${MID}/CDEN.spad: ${IN}/cden.spad.pamphlet
+ @ echo 0 making ${MID}/CDEN.spad from ${IN}/cden.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CDEN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CDEN CommonDenominator" ${IN}/cden.spad.pamphlet >CDEN.spad )
+
+@
+<<ICDEN.o (O from NRLIB)>>=
+${OUT}/ICDEN.o: ${MID}/ICDEN.NRLIB
+ @ echo 0 making ${OUT}/ICDEN.o from ${MID}/ICDEN.NRLIB
+ @ cp ${MID}/ICDEN.NRLIB/code.o ${OUT}/ICDEN.o
+
+@
+<<ICDEN.NRLIB (NRLIB from MID)>>=
+${MID}/ICDEN.NRLIB: ${MID}/ICDEN.spad
+ @ echo 0 making ${MID}/ICDEN.NRLIB from ${MID}/ICDEN.spad
+ @ (cd ${MID} ; echo ')co ICDEN.spad' | ${INTERPSYS} )
+
+@
+<<ICDEN.spad (SPAD from IN)>>=
+${MID}/ICDEN.spad: ${IN}/cden.spad.pamphlet
+ @ echo 0 making ${MID}/ICDEN.spad from ${IN}/cden.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ICDEN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ICDEN InnerCommonDenominator" ${IN}/cden.spad.pamphlet >ICDEN.spad )
+
+@
+<<MCDEN.o (O from NRLIB)>>=
+${OUT}/MCDEN.o: ${MID}/MCDEN.NRLIB
+ @ echo 0 making ${OUT}/MCDEN.o from ${MID}/MCDEN.NRLIB
+ @ cp ${MID}/MCDEN.NRLIB/code.o ${OUT}/MCDEN.o
+
+@
+<<MCDEN.NRLIB (NRLIB from MID)>>=
+${MID}/MCDEN.NRLIB: ${MID}/MCDEN.spad
+ @ echo 0 making ${MID}/MCDEN.NRLIB from ${MID}/MCDEN.spad
+ @ (cd ${MID} ; echo ')co MCDEN.spad' | ${INTERPSYS} )
+
+@
+<<MCDEN.spad (SPAD from IN)>>=
+${MID}/MCDEN.spad: ${IN}/cden.spad.pamphlet
+ @ echo 0 making ${MID}/MCDEN.spad from ${IN}/cden.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MCDEN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MCDEN MatrixCommonDenominator" ${IN}/cden.spad.pamphlet >MCDEN.spad )
+
+@
+<<UPCDEN.o (O from NRLIB)>>=
+${OUT}/UPCDEN.o: ${MID}/UPCDEN.NRLIB
+ @ echo 0 making ${OUT}/UPCDEN.o from ${MID}/UPCDEN.NRLIB
+ @ cp ${MID}/UPCDEN.NRLIB/code.o ${OUT}/UPCDEN.o
+
+@
+<<UPCDEN.NRLIB (NRLIB from MID)>>=
+${MID}/UPCDEN.NRLIB: ${MID}/UPCDEN.spad
+ @ echo 0 making ${MID}/UPCDEN.NRLIB from ${MID}/UPCDEN.spad
+ @ (cd ${MID} ; echo ')co UPCDEN.spad' | ${INTERPSYS} )
+
+@
+<<UPCDEN.spad (SPAD from IN)>>=
+${MID}/UPCDEN.spad: ${IN}/cden.spad.pamphlet
+ @ echo 0 making ${MID}/UPCDEN.spad from ${IN}/cden.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPCDEN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPCDEN UnivariatePolynomialCommonDenominator" ${IN}/cden.spad.pamphlet >UPCDEN.spad )
+
+@
+<<cden.spad.dvi (DOC from IN)>>=
+${DOC}/cden.spad.dvi: ${IN}/cden.spad.pamphlet
+ @ echo 0 making ${DOC}/cden.spad.dvi from ${IN}/cden.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/cden.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} cden.spad ; \
+ rm -f ${DOC}/cden.spad.pamphlet ; \
+ rm -f ${DOC}/cden.spad.tex ; \
+ rm -f ${DOC}/cden.spad )
+
+@
+\subsection{clifford.spad \cite{1}}
+<<clifford.spad (SPAD from IN)>>=
+${MID}/clifford.spad: ${IN}/clifford.spad.pamphlet
+ @ echo 0 making ${MID}/clifford.spad from ${IN}/clifford.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/clifford.spad.pamphlet >clifford.spad )
+
+@
+<<CLIF.o (O from NRLIB)>>=
+${OUT}/CLIF.o: ${MID}/CLIF.NRLIB
+ @ echo 0 making ${OUT}/CLIF.o from ${MID}/CLIF.NRLIB
+ @ cp ${MID}/CLIF.NRLIB/code.o ${OUT}/CLIF.o
+
+@
+<<CLIF.NRLIB (NRLIB from MID)>>=
+${MID}/CLIF.NRLIB: ${MID}/CLIF.spad
+ @ echo 0 making ${MID}/CLIF.NRLIB from ${MID}/CLIF.spad
+ @ (cd ${MID} ; echo ')co CLIF.spad' | ${INTERPSYS} )
+
+@
+<<CLIF.spad (SPAD from IN)>>=
+${MID}/CLIF.spad: ${IN}/clifford.spad.pamphlet
+ @ echo 0 making ${MID}/CLIF.spad from ${IN}/clifford.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CLIF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain CLIF CliffordAlgebra" ${IN}/clifford.spad.pamphlet >CLIF.spad )
+
+@
+<<QFORM.o (O from NRLIB)>>=
+${OUT}/QFORM.o: ${MID}/QFORM.NRLIB
+ @ echo 0 making ${OUT}/QFORM.o from ${MID}/QFORM.NRLIB
+ @ cp ${MID}/QFORM.NRLIB/code.o ${OUT}/QFORM.o
+
+@
+<<QFORM.NRLIB (NRLIB from MID)>>=
+${MID}/QFORM.NRLIB: ${MID}/QFORM.spad
+ @ echo 0 making ${MID}/QFORM.NRLIB from ${MID}/QFORM.spad
+ @ (cd ${MID} ; echo ')co QFORM.spad' | ${INTERPSYS} )
+
+@
+<<QFORM.spad (SPAD from IN)>>=
+${MID}/QFORM.spad: ${IN}/clifford.spad.pamphlet
+ @ echo 0 making ${MID}/QFORM.spad from ${IN}/clifford.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QFORM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain QFORM QuadraticForm" ${IN}/clifford.spad.pamphlet >QFORM.spad )
+
+@
+<<clifford.spad.dvi (DOC from IN)>>=
+${DOC}/clifford.spad.dvi: ${IN}/clifford.spad.pamphlet
+ @ echo 0 making ${DOC}/clifford.spad.dvi from ${IN}/clifford.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/clifford.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} clifford.spad ; \
+ rm -f ${DOC}/clifford.spad.pamphlet ; \
+ rm -f ${DOC}/clifford.spad.tex ; \
+ rm -f ${DOC}/clifford.spad )
+
+@
+\subsection{clip.spad \cite{1}}
+<<clip.spad (SPAD from IN)>>=
+${MID}/clip.spad: ${IN}/clip.spad.pamphlet
+ @ echo 0 making ${MID}/clip.spad from ${IN}/clip.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/clip.spad.pamphlet >clip.spad )
+
+@
+<<CLIP.o (O from NRLIB)>>=
+${OUT}/CLIP.o: ${MID}/CLIP.NRLIB
+ @ echo 0 making ${OUT}/CLIP.o from ${MID}/CLIP.NRLIB
+ @ cp ${MID}/CLIP.NRLIB/code.o ${OUT}/CLIP.o
+
+@
+<<CLIP.NRLIB (NRLIB from MID)>>=
+${MID}/CLIP.NRLIB: ${MID}/CLIP.spad
+ @ echo 0 making ${MID}/CLIP.NRLIB from ${MID}/CLIP.spad
+ @ (cd ${MID} ; echo ')co CLIP.spad' | ${INTERPSYS} )
+
+@
+<<CLIP.spad (SPAD from IN)>>=
+${MID}/CLIP.spad: ${IN}/clip.spad.pamphlet
+ @ echo 0 making ${MID}/CLIP.spad from ${IN}/clip.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CLIP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CLIP TwoDimensionalPlotClipping" ${IN}/clip.spad.pamphlet >CLIP.spad )
+
+@
+<<clip.spad.dvi (DOC from IN)>>=
+${DOC}/clip.spad.dvi: ${IN}/clip.spad.pamphlet
+ @ echo 0 making ${DOC}/clip.spad.dvi from ${IN}/clip.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/clip.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} clip.spad ; \
+ rm -f ${DOC}/clip.spad.pamphlet ; \
+ rm -f ${DOC}/clip.spad.tex ; \
+ rm -f ${DOC}/clip.spad )
+
+@
+\subsection{cmplxrt.spad \cite{1}}
+<<cmplxrt.spad (SPAD from IN)>>=
+${MID}/cmplxrt.spad: ${IN}/cmplxrt.spad.pamphlet
+ @ echo 0 making ${MID}/cmplxrt.spad from ${IN}/cmplxrt.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/cmplxrt.spad.pamphlet >cmplxrt.spad )
+
+@
+<<CMPLXRT.o (O from NRLIB)>>=
+${OUT}/CMPLXRT.o: ${MID}/CMPLXRT.NRLIB
+ @ echo 0 making ${OUT}/CMPLXRT.o from ${MID}/CMPLXRT.NRLIB
+ @ cp ${MID}/CMPLXRT.NRLIB/code.o ${OUT}/CMPLXRT.o
+
+@
+<<CMPLXRT.NRLIB (NRLIB from MID)>>=
+${MID}/CMPLXRT.NRLIB: ${MID}/CMPLXRT.spad
+ @ echo 0 making ${MID}/CMPLXRT.NRLIB from ${MID}/CMPLXRT.spad
+ @ (cd ${MID} ; echo ')co CMPLXRT.spad' | ${INTERPSYS} )
+
+@
+<<CMPLXRT.spad (SPAD from IN)>>=
+${MID}/CMPLXRT.spad: ${IN}/cmplxrt.spad.pamphlet
+ @ echo 0 making ${MID}/CMPLXRT.spad from ${IN}/cmplxrt.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CMPLXRT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CMPLXRT ComplexRootPackage" ${IN}/cmplxrt.spad.pamphlet >CMPLXRT.spad )
+
+@
+<<cmplxrt.spad.dvi (DOC from IN)>>=
+${DOC}/cmplxrt.spad.dvi: ${IN}/cmplxrt.spad.pamphlet
+ @ echo 0 making ${DOC}/cmplxrt.spad.dvi from ${IN}/cmplxrt.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/cmplxrt.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} cmplxrt.spad ; \
+ rm -f ${DOC}/cmplxrt.spad.pamphlet ; \
+ rm -f ${DOC}/cmplxrt.spad.tex ; \
+ rm -f ${DOC}/cmplxrt.spad )
+
+@
+\subsection{coerce.spad \cite{1}}
+Builds KOERCE KONVERT RETRACT- RETRACT TYPE
+<<coerce.spad (SPAD from IN)>>=
+${MID}/coerce.spad: ${IN}/coerce.spad.pamphlet
+ @ echo 0 making ${MID}/coerce.spad from ${IN}/coerce.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/coerce.spad.pamphlet >coerce.spad )
+
+@
+<<KOERCE.o (O from NRLIB)>>=
+${OUT}/KOERCE.o: ${MID}/KOERCE.NRLIB
+ @ echo 0 making ${OUT}/KOERCE.o from ${MID}/KOERCE.NRLIB
+ @ cp ${MID}/KOERCE.NRLIB/code.o ${OUT}/KOERCE.o
+
+@
+<<KOERCE.NRLIB (NRLIB from MID)>>=
+${MID}/KOERCE.NRLIB: ${MID}/KOERCE.spad
+ @ echo 0 making ${MID}/KOERCE.NRLIB from ${MID}/KOERCE.spad
+ @(cd ${MID} ; echo ')co KOERCE.spad' | ${INTERPSYS} )
+
+@
+<<KOERCE.spad (SPAD from IN)>>=
+${MID}/KOERCE.spad: ${IN}/coerce.spad.pamphlet
+ @ echo 0 making ${MID}/KOERCE.spad from ${IN}/coerce.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf KOERCE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category KOERCE CoercibleTo" ${IN}/coerce.spad.pamphlet >KOERCE.spad )
+
+@
+<<KONVERT.o (O from NRLIB)>>=
+${OUT}/KONVERT.o: ${MID}/KONVERT.NRLIB
+ @ echo 0 making ${OUT}/KONVERT.o from ${MID}/KONVERT.NRLIB
+ @ cp ${MID}/KONVERT.NRLIB/code.o ${OUT}/KONVERT.o
+
+@
+<<KONVERT.NRLIB (NRLIB from MID)>>=
+${MID}/KONVERT.NRLIB: ${MID}/KONVERT.spad
+ @ echo 0 making ${MID}/KONVERT.NRLIB from ${MID}/KONVERT.spad
+ @ (cd ${MID} ; echo ')co KONVERT.spad' | ${INTERPSYS} )
+
+@
+<<KONVERT.spad (SPAD from IN)>>=
+${MID}/KONVERT.spad: ${IN}/coerce.spad.pamphlet
+ @ echo 0 making ${MID}/KONVERT.spad from ${IN}/coerce.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle -R"category KONVERT ConvertibleTo" ${IN}/coerce.spad.pamphlet >KONVERT.spad )
+
+@
+<<RETRACT-.o (O from NRLIB)>>=
+${OUT}/RETRACT-.o: ${MID}/RETRACT.NRLIB
+ @ echo 0 making ${OUT}/RETRACT-.o from ${MID}/RETRACT-.NRLIB
+ @ cp ${MID}/RETRACT-.NRLIB/code.o ${OUT}/RETRACT-.o
+
+@
+<<RETRACT-.NRLIB (NRLIB from MID)>>=
+${MID}/RETRACT-.NRLIB: ${OUT}/TYPE.o ${MID}/RETRACT.spad
+ @ echo 0 making ${MID}/RETRACT-.NRLIB from ${MID}/RETRACT.spad
+ @ (cd ${MID} ; echo ')co RETRACT.spad' | ${INTERPSYS} )
+
+@
+<<RETRACT.o (O from NRLIB)>>=
+${OUT}/RETRACT.o: ${MID}/RETRACT.NRLIB
+ @ echo 0 making ${OUT}/RETRACT.o from ${MID}/RETRACT.NRLIB
+ @ cp ${MID}/RETRACT.NRLIB/code.o ${OUT}/RETRACT.o
+
+@
+<<RETRACT.NRLIB (NRLIB from MID)>>=
+${MID}/RETRACT.NRLIB: ${OUT}/TYPE.o ${MID}/RETRACT.spad
+ @ echo 0 making ${MID}/RETRACT.NRLIB from ${MID}/RETRACT.spad
+ @ (cd ${MID} ; echo ')co RETRACT.spad' | ${INTERPSYS} )
+
+@
+<<RETRACT.spad (SPAD from IN)>>=
+${MID}/RETRACT.spad: ${IN}/coerce.spad.pamphlet
+ @ echo 0 making ${MID}/RETRACT.spad from ${IN}/coerce.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle -R"category RETRACT RetractableTo" ${IN}/coerce.spad.pamphlet >RETRACT.spad )
+
+@
+<<TYPE.o (O from NRLIB)>>=
+${OUT}/TYPE.o: ${MID}/TYPE.NRLIB
+ @ echo 0 making ${OUT}/TYPE.o from ${MID}/TYPE.NRLIB
+ @ cp ${MID}/TYPE.NRLIB/code.o ${OUT}/TYPE.o
+
+@
+<<TYPE.NRLIB (NRLIB from MID)>>=
+${MID}/TYPE.NRLIB: ${MID}/TYPE.spad
+ @ echo 0 making ${MID}/TYPE.NRLIB from ${MID}/TYPE.spad
+ @ (cd ${MID} ; echo ')co TYPE.spad' | ${INTERPSYS} )
+
+@
+<<TYPE.spad (SPAD from IN)>>=
+${MID}/TYPE.spad: ${IN}/coerce.spad.pamphlet
+ @ echo 0 making ${MID}/TYPE.spad from ${IN}/coerce.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle -R"category TYPE Type" ${IN}/coerce.spad.pamphlet >TYPE.spad )
+
+@
+<<coerce.spad.dvi (DOC from IN)>>=
+${DOC}/coerce.spad.dvi: ${IN}/coerce.spad.pamphlet
+ @ echo 0 making ${DOC}/coerce.spad.dvi from ${IN}/coerce.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/coerce.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} coerce.spad ; \
+ rm -f ${DOC}/coerce.spad.pamphlet ; \
+ rm -f ${DOC}/coerce.spad.tex ; \
+ rm -f ${DOC}/coerce.spad )
+
+@
+\subsection{color.spad \cite{1}}
+<<color.spad (SPAD from IN)>>=
+${MID}/color.spad: ${IN}/color.spad.pamphlet
+ @ echo 0 making ${MID}/color.spad from ${IN}/color.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/color.spad.pamphlet >color.spad )
+
+@
+<<COLOR.o (O from NRLIB)>>=
+${OUT}/COLOR.o: ${MID}/COLOR.NRLIB
+ @ echo 0 making ${OUT}/COLOR.o from ${MID}/COLOR.NRLIB
+ @ cp ${MID}/COLOR.NRLIB/code.o ${OUT}/COLOR.o
+
+@
+<<COLOR.NRLIB (NRLIB from MID)>>=
+${MID}/COLOR.NRLIB: ${MID}/COLOR.spad
+ @ echo 0 making ${MID}/COLOR.NRLIB from ${MID}/COLOR.spad
+ @ (cd ${MID} ; echo ')co COLOR.spad' | ${INTERPSYS} )
+
+@
+<<COLOR.spad (SPAD from IN)>>=
+${MID}/COLOR.spad: ${IN}/color.spad.pamphlet
+ @ echo 0 making ${MID}/COLOR.spad from ${IN}/color.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COLOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain COLOR Color" ${IN}/color.spad.pamphlet >COLOR.spad )
+
+@
+<<PALETTE.o (O from NRLIB)>>=
+${OUT}/PALETTE.o: ${MID}/PALETTE.NRLIB
+ @ echo 0 making ${OUT}/PALETTE.o from ${MID}/PALETTE.NRLIB
+ @ cp ${MID}/PALETTE.NRLIB/code.o ${OUT}/PALETTE.o
+
+@
+<<PALETTE.NRLIB (NRLIB from MID)>>=
+${MID}/PALETTE.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PALETTE.spad
+ @ echo 0 making ${MID}/PALETTE.NRLIB from ${MID}/PALETTE.spad
+ @ (cd ${MID} ; echo ')co PALETTE.spad' | ${INTERPSYS} )
+
+@
+<<PALETTE.spad (SPAD from IN)>>=
+${MID}/PALETTE.spad: ${IN}/color.spad.pamphlet
+ @ echo 0 making ${MID}/PALETTE.spad from ${IN}/color.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PALETTE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PALETTE Palette" ${IN}/color.spad.pamphlet >PALETTE.spad )
+
+@
+<<color.spad.dvi (DOC from IN)>>=
+${DOC}/color.spad.dvi: ${IN}/color.spad.pamphlet
+ @ echo 0 making ${DOC}/color.spad.dvi from ${IN}/color.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/color.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} color.spad ; \
+ rm -f ${DOC}/color.spad.pamphlet ; \
+ rm -f ${DOC}/color.spad.tex ; \
+ rm -f ${DOC}/color.spad )
+
+@
+\subsection{combfunc.spad \cite{1}}
+<<combfunc.spad (SPAD from IN)>>=
+${MID}/combfunc.spad: ${IN}/combfunc.spad.pamphlet
+ @ echo 0 making ${MID}/combfunc.spad from ${IN}/combfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/combfunc.spad.pamphlet >combfunc.spad )
+
+@
+<<COMBF.o (O from NRLIB)>>=
+${OUT}/COMBF.o: ${MID}/COMBF.NRLIB
+ @ echo 0 making ${OUT}/COMBF.o from ${MID}/COMBF.NRLIB
+ @ cp ${MID}/COMBF.NRLIB/code.o ${OUT}/COMBF.o
+
+@
+<<COMBF.NRLIB (NRLIB from MID)>>=
+${MID}/COMBF.NRLIB: ${OUT}/CFCAT.o ${MID}/COMBF.spad
+ @ echo 0 making ${MID}/COMBF.NRLIB from ${MID}/COMBF.spad
+ @ (cd ${MID} ; echo ')co COMBF.spad' | ${INTERPSYS} )
+
+@
+<<COMBF.spad (SPAD from IN)>>=
+${MID}/COMBF.spad: ${IN}/combfunc.spad.pamphlet
+ @ echo 0 making ${MID}/COMBF.spad from ${IN}/combfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMBF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMBF CombinatorialFunction" ${IN}/combfunc.spad.pamphlet >COMBF.spad )
+
+@
+<<COMBOPC.o (O from NRLIB)>>=
+${OUT}/COMBOPC.o: ${MID}/COMBOPC.NRLIB
+ @ echo 0 making ${OUT}/COMBOPC.o from ${MID}/COMBOPC.NRLIB
+ @ cp ${MID}/COMBOPC.NRLIB/code.o ${OUT}/COMBOPC.o
+
+@
+<<COMBOPC.NRLIB (NRLIB from MID)>>=
+${MID}/COMBOPC.NRLIB: ${OUT}/CFCAT.o ${MID}/COMBOPC.spad
+ @ echo 0 making ${MID}/COMBOPC.NRLIB from ${MID}/COMBOPC.spad
+ @ (cd ${MID} ; echo ')co COMBOPC.spad' | ${INTERPSYS} )
+
+@
+<<COMBOPC.spad (SPAD from IN)>>=
+${MID}/COMBOPC.spad: ${IN}/combfunc.spad.pamphlet
+ @ echo 0 making ${MID}/COMBOPC.spad from ${IN}/combfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMBOPC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category COMBOPC CombinatorialOpsCategory" ${IN}/combfunc.spad.pamphlet >COMBOPC.spad )
+
+@
+<<FSPECF.o (O from NRLIB)>>=
+${OUT}/FSPECF.o: ${MID}/FSPECF.NRLIB
+ @ echo 0 making ${OUT}/FSPECF.o from ${MID}/FSPECF.NRLIB
+ @ cp ${MID}/FSPECF.NRLIB/code.o ${OUT}/FSPECF.o
+
+@
+<<FSPECF.NRLIB (NRLIB from MID)>>=
+${MID}/FSPECF.NRLIB: ${MID}/FSPECF.spad
+ @ echo 0 making ${MID}/FSPECF.NRLIB from ${MID}/FSPECF.spad
+ @ (cd ${MID} ; echo ')co FSPECF.spad' | ${INTERPSYS} )
+
+@
+<<FSPECF.spad (SPAD from IN)>>=
+${MID}/FSPECF.spad: ${IN}/combfunc.spad.pamphlet
+ @ echo 0 making ${MID}/FSPECF.spad from ${IN}/combfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSPECF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSPECF FunctionalSpecialFunction" ${IN}/combfunc.spad.pamphlet >FSPECF.spad )
+
+@
+<<SUMFS.o (O from NRLIB)>>=
+${OUT}/SUMFS.o: ${MID}/SUMFS.NRLIB
+ @ echo 0 making ${OUT}/SUMFS.o from ${MID}/SUMFS.NRLIB
+ @ cp ${MID}/SUMFS.NRLIB/code.o ${OUT}/SUMFS.o
+
+@
+<<SUMFS.NRLIB (NRLIB from MID)>>=
+${MID}/SUMFS.NRLIB: ${MID}/SUMFS.spad
+ @ echo 0 making ${MID}/SUMFS.NRLIB from ${MID}/SUMFS.spad
+ @ (cd ${MID} ; echo ')co SUMFS.spad' | ${INTERPSYS} )
+
+@
+<<SUMFS.spad (SPAD from IN)>>=
+${MID}/SUMFS.spad: ${IN}/combfunc.spad.pamphlet
+ @ echo 0 making ${MID}/SUMFS.spad from ${IN}/combfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUMFS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SUMFS FunctionSpaceSum" ${IN}/combfunc.spad.pamphlet >SUMFS.spad )
+
+@
+<<combfunc.spad.dvi (DOC from IN)>>=
+${DOC}/combfunc.spad.dvi: ${IN}/combfunc.spad.pamphlet
+ @ echo 0 making ${DOC}/combfunc.spad.dvi from ${IN}/combfunc.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/combfunc.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} combfunc.spad ; \
+ rm -f ${DOC}/combfunc.spad.pamphlet ; \
+ rm -f ${DOC}/combfunc.spad.tex ; \
+ rm -f ${DOC}/combfunc.spad )
+
+@
+\subsection{combinat.spad \cite{1}}
+<<combinat.spad (SPAD from IN)>>=
+${MID}/combinat.spad: ${IN}/combinat.spad.pamphlet
+ @ echo 0 making ${MID}/combinat.spad from ${IN}/combinat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/combinat.spad.pamphlet >combinat.spad )
+
+@
+<<COMBINAT.o (O from NRLIB)>>=
+${OUT}/COMBINAT.o: ${MID}/COMBINAT.NRLIB
+ @ echo 0 making ${OUT}/COMBINAT.o from ${MID}/COMBINAT.NRLIB
+ @ cp ${MID}/COMBINAT.NRLIB/code.o ${OUT}/COMBINAT.o
+
+@
+<<COMBINAT.NRLIB (NRLIB from MID)>>=
+${MID}/COMBINAT.NRLIB: ${MID}/COMBINAT.spad
+ @ echo 0 making ${MID}/COMBINAT.NRLIB from ${MID}/COMBINAT.spad
+ @ (cd ${MID} ; echo ')co COMBINAT.spad' | ${INTERPSYS} )
+
+@
+<<COMBINAT.spad (SPAD from IN)>>=
+${MID}/COMBINAT.spad: ${IN}/combinat.spad.pamphlet
+ @ echo 0 making ${MID}/COMBINAT.spad from ${IN}/combinat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMBINAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMBINAT IntegerCombinatoricFunctions" ${IN}/combinat.spad.pamphlet >COMBINAT.spad )
+
+@
+<<combinat.spad.dvi (DOC from IN)>>=
+${DOC}/combinat.spad.dvi: ${IN}/combinat.spad.pamphlet
+ @ echo 0 making ${DOC}/combinat.spad.dvi from ${IN}/combinat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/combinat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} combinat.spad ; \
+ rm -f ${DOC}/combinat.spad.pamphlet ; \
+ rm -f ${DOC}/combinat.spad.tex ; \
+ rm -f ${DOC}/combinat.spad )
+
+@
+\subsection{complet.spad \cite{1}}
+<<complet.spad (SPAD from IN)>>=
+${MID}/complet.spad: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${MID}/complet.spad from ${IN}/complet.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/complet.spad.pamphlet >complet.spad )
+
+@
+<<INFINITY.o (O from NRLIB)>>=
+${OUT}/INFINITY.o: ${MID}/INFINITY.NRLIB
+ @ echo 0 making ${OUT}/INFINITY.o from ${MID}/INFINITY.NRLIB
+ @ cp ${MID}/INFINITY.NRLIB/code.o ${OUT}/INFINITY.o
+
+@
+<<INFINITY.NRLIB (NRLIB from MID)>>=
+${MID}/INFINITY.NRLIB: ${MID}/INFINITY.spad
+ @ echo 0 making ${MID}/INFINITY.NRLIB from ${MID}/INFINITY.spad
+ @ (cd ${MID} ; echo ')co INFINITY.spad' | ${INTERPSYS} )
+
+@
+<<INFINITY.spad (SPAD from IN)>>=
+${MID}/INFINITY.spad: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${MID}/INFINITY.spad from ${IN}/complet.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INFINITY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INFINITY Infinity" ${IN}/complet.spad.pamphlet >INFINITY.spad )
+
+@
+<<ONECOMP.o (O from NRLIB)>>=
+${OUT}/ONECOMP.o: ${MID}/ONECOMP.NRLIB
+ @ echo 0 making ${OUT}/ONECOMP.o from ${MID}/ONECOMP.NRLIB
+ @ cp ${MID}/ONECOMP.NRLIB/code.o ${OUT}/ONECOMP.o
+
+@
+<<ONECOMP.NRLIB (NRLIB from MID)>>=
+${MID}/ONECOMP.NRLIB: ${MID}/ONECOMP.spad
+ @ echo 0 making ${MID}/ONECOMP.NRLIB from ${MID}/ONECOMP.spad
+ @ (cd ${MID} ; echo ')co ONECOMP.spad' | ${INTERPSYS} )
+
+@
+<<ONECOMP.spad (SPAD from IN)>>=
+${MID}/ONECOMP.spad: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${MID}/ONECOMP.spad from ${IN}/complet.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ONECOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ONECOMP OnePointCompletion" ${IN}/complet.spad.pamphlet >ONECOMP.spad )
+
+@
+<<ONECOMP2.o (O from NRLIB)>>=
+${OUT}/ONECOMP2.o: ${MID}/ONECOMP2.NRLIB
+ @ echo 0 making ${OUT}/ONECOMP2.o from ${MID}/ONECOMP2.NRLIB
+ @ cp ${MID}/ONECOMP2.NRLIB/code.o ${OUT}/ONECOMP2.o
+
+@
+<<ONECOMP2.NRLIB (NRLIB from MID)>>=
+${MID}/ONECOMP2.NRLIB: ${MID}/ONECOMP2.spad
+ @ echo 0 making ${MID}/ONECOMP2.NRLIB from ${MID}/ONECOMP2.spad
+ @ (cd ${MID} ; echo ')co ONECOMP2.spad' | ${INTERPSYS} )
+
+@
+<<ONECOMP2.spad (SPAD from IN)>>=
+${MID}/ONECOMP2.spad: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${MID}/ONECOMP2.spad from ${IN}/complet.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ONECOMP2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ONECOMP2 OnePointCompletionFunctions2" ${IN}/complet.spad.pamphlet >ONECOMP2.spad )
+
+@
+<<ORDCOMP.o (O from NRLIB)>>=
+${OUT}/ORDCOMP.o: ${MID}/ORDCOMP.NRLIB
+ @ echo 0 making ${OUT}/ORDCOMP.o from ${MID}/ORDCOMP.NRLIB
+ @ cp ${MID}/ORDCOMP.NRLIB/code.o ${OUT}/ORDCOMP.o
+
+@
+<<ORDCOMP.NRLIB (NRLIB from MID)>>=
+${MID}/ORDCOMP.NRLIB: ${MID}/ORDCOMP.spad
+ @ echo 0 making ${MID}/ORDCOMP.NRLIB from ${MID}/ORDCOMP.spad
+ @ (cd ${MID} ; echo ')co ORDCOMP.spad' | ${INTERPSYS} )
+
+@
+<<ORDCOMP.spad (SPAD from IN)>>=
+${MID}/ORDCOMP.spad: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${MID}/ORDCOMP.spad from ${IN}/complet.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDCOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ORDCOMP OrderedCompletion" ${IN}/complet.spad.pamphlet >ORDCOMP.spad )
+
+@
+<<ORDCOMP2.o (O from NRLIB)>>=
+${OUT}/ORDCOMP2.o: ${MID}/ORDCOMP2.NRLIB
+ @ echo 0 making ${OUT}/ORDCOMP2.o from ${MID}/ORDCOMP2.NRLIB
+ @ cp ${MID}/ORDCOMP2.NRLIB/code.o ${OUT}/ORDCOMP2.o
+
+@
+<<ORDCOMP2.NRLIB (NRLIB from MID)>>=
+${MID}/ORDCOMP2.NRLIB: ${MID}/ORDCOMP2.spad
+ @ echo 0 making ${MID}/ORDCOMP2.NRLIB from ${MID}/ORDCOMP2.spad
+ @ (cd ${MID} ; echo ')co ORDCOMP2.spad' | ${INTERPSYS} )
+
+@
+<<ORDCOMP2.spad (SPAD from IN)>>=
+${MID}/ORDCOMP2.spad: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${MID}/ORDCOMP2.spad from ${IN}/complet.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDCOMP2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ORDCOMP2 OrderedCompletionFunctions2" ${IN}/complet.spad.pamphlet >ORDCOMP2.spad )
+
+@
+<<complet.spad.dvi (DOC from IN)>>=
+${DOC}/complet.spad.dvi: ${IN}/complet.spad.pamphlet
+ @ echo 0 making ${DOC}/complet.spad.dvi from ${IN}/complet.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/complet.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} complet.spad ; \
+ rm -f ${DOC}/complet.spad.pamphlet ; \
+ rm -f ${DOC}/complet.spad.tex ; \
+ rm -f ${DOC}/complet.spad )
+
+@
+\subsection{constant.spad \cite{1}}
+<<constant.spad (SPAD from IN)>>=
+${MID}/constant.spad: ${IN}/constant.spad.pamphlet
+ @ echo 0 making ${MID}/constant.spad from ${IN}/constant.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/constant.spad.pamphlet >constant.spad )
+
+@
+<<AN.o (O from NRLIB)>>=
+${OUT}/AN.o: ${MID}/AN.NRLIB
+ @ echo 0 making ${OUT}/AN.o from ${MID}/AN.NRLIB
+ @ cp ${MID}/AN.NRLIB/code.o ${OUT}/AN.o
+
+@
+<<AN.NRLIB (NRLIB from MID)>>=
+${MID}/AN.NRLIB: ${MID}/AN.spad
+ @ echo 0 making ${MID}/AN.NRLIB from ${MID}/AN.spad
+ @ (cd ${MID} ; echo ')co AN.spad' | ${INTERPSYS} )
+
+@
+<<AN.spad (SPAD from IN)>>=
+${MID}/AN.spad: ${IN}/constant.spad.pamphlet
+ @ echo 0 making ${MID}/AN.spad from ${IN}/constant.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf AN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain AN AlgebraicNumber" ${IN}/constant.spad.pamphlet >AN.spad )
+
+@
+<<IAN.o (O from NRLIB)>>=
+${OUT}/IAN.o: ${MID}/IAN.NRLIB
+ @ echo 0 making ${OUT}/IAN.o from ${MID}/IAN.NRLIB
+ @ cp ${MID}/IAN.NRLIB/code.o ${OUT}/IAN.o
+
+@
+<<IAN.NRLIB (NRLIB from MID)>>=
+${MID}/IAN.NRLIB: ${MID}/IAN.spad
+ @ echo 0 making ${MID}/IAN.NRLIB from ${MID}/IAN.spad
+ @ (cd ${MID} ; echo ')co IAN.spad' | ${INTERPSYS} )
+
+@
+<<IAN.spad (SPAD from IN)>>=
+${MID}/IAN.spad: ${IN}/constant.spad.pamphlet
+ @ echo 0 making ${MID}/IAN.spad from ${IN}/constant.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IAN InnerAlgebraicNumber" ${IN}/constant.spad.pamphlet >IAN.spad )
+
+@
+<<constant.spad.dvi (DOC from IN)>>=
+${DOC}/constant.spad.dvi: ${IN}/constant.spad.pamphlet
+ @ echo 0 making ${DOC}/constant.spad.dvi from ${IN}/constant.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/constant.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} constant.spad ; \
+ rm -f ${DOC}/constant.spad.pamphlet ; \
+ rm -f ${DOC}/constant.spad.tex ; \
+ rm -f ${DOC}/constant.spad )
+
+@
+\subsection{contfrac.spad \cite{1}}
+<<contfrac.spad (SPAD from IN)>>=
+${MID}/contfrac.spad: ${IN}/contfrac.spad.pamphlet
+ @ echo 0 making ${MID}/contfrac.spad from ${IN}/contfrac.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/contfrac.spad.pamphlet >contfrac.spad )
+
+@
+<<CONTFRAC.o (O from NRLIB)>>=
+${OUT}/CONTFRAC.o: ${MID}/CONTFRAC.NRLIB
+ @ echo 0 making ${OUT}/CONTFRAC.o from ${MID}/CONTFRAC.NRLIB
+ @ cp ${MID}/CONTFRAC.NRLIB/code.o ${OUT}/CONTFRAC.o
+
+@
+<<CONTFRAC.NRLIB (NRLIB from MID)>>=
+${MID}/CONTFRAC.NRLIB: ${MID}/CONTFRAC.spad
+ @ echo 0 making ${MID}/CONTFRAC.NRLIB from ${MID}/CONTFRAC.spad
+ @ (cd ${MID} ; echo ')co CONTFRAC.spad' | ${INTERPSYS} )
+
+@
+<<CONTFRAC.spad (SPAD from IN)>>=
+${MID}/CONTFRAC.spad: ${IN}/contfrac.spad.pamphlet
+ @ echo 0 making ${MID}/CONTFRAC.spad from ${IN}/contfrac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CONTFRAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain CONTFRAC ContinuedFraction" ${IN}/contfrac.spad.pamphlet >CONTFRAC.spad )
+
+@
+<<NCNTFRAC.o (O from NRLIB)>>=
+${OUT}/NCNTFRAC.o: ${MID}/NCNTFRAC.NRLIB
+ @ echo 0 making ${OUT}/NCNTFRAC.o from ${MID}/NCNTFRAC.NRLIB
+ @ cp ${MID}/NCNTFRAC.NRLIB/code.o ${OUT}/NCNTFRAC.o
+
+@
+<<NCNTFRAC.NRLIB (NRLIB from MID)>>=
+${MID}/NCNTFRAC.NRLIB: ${MID}/NCNTFRAC.spad
+ @ echo 0 making ${MID}/NCNTFRAC.NRLIB from ${MID}/NCNTFRAC.spad
+ @ (cd ${MID} ; echo ')co NCNTFRAC.spad' | ${INTERPSYS} )
+
+@
+<<NCNTFRAC.spad (SPAD from IN)>>=
+${MID}/NCNTFRAC.spad: ${IN}/contfrac.spad.pamphlet
+ @ echo 0 making ${MID}/NCNTFRAC.spad from ${IN}/contfrac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NCNTFRAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NCNTFRAC NumericContinuedFraction" ${IN}/contfrac.spad.pamphlet >NCNTFRAC.spad )
+
+@
+<<contfrac.spad.dvi (DOC from IN)>>=
+${DOC}/contfrac.spad.dvi: ${IN}/contfrac.spad.pamphlet
+ @ echo 0 making ${DOC}/contfrac.spad.dvi from ${IN}/contfrac.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/contfrac.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} contfrac.spad ; \
+ rm -f ${DOC}/contfrac.spad.pamphlet ; \
+ rm -f ${DOC}/contfrac.spad.tex ; \
+ rm -f ${DOC}/contfrac.spad )
+
+@
+\subsection{cont.spad \cite{1}}
+<<cont.spad (SPAD from IN)>>=
+${MID}/cont.spad: ${IN}/cont.spad.pamphlet
+ @ echo 0 making ${MID}/cont.spad from ${IN}/cont.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/cont.spad.pamphlet >cont.spad )
+
+@
+<<ESCONT.o (O from NRLIB)>>=
+${OUT}/ESCONT.o: ${MID}/ESCONT.NRLIB
+ @ echo 0 making ${OUT}/ESCONT.o from ${MID}/ESCONT.NRLIB
+ @ cp ${MID}/ESCONT.NRLIB/code.o ${OUT}/ESCONT.o
+
+@
+<<ESCONT.NRLIB (NRLIB from MID)>>=
+${MID}/ESCONT.NRLIB: ${MID}/ESCONT.spad
+ @ echo 0 making ${MID}/ESCONT.NRLIB from ${MID}/ESCONT.spad
+ @ (cd ${MID} ; echo ')co ESCONT.spad' | ${INTERPSYS} )
+
+@
+<<ESCONT.spad (SPAD from IN)>>=
+${MID}/ESCONT.spad: ${IN}/cont.spad.pamphlet
+ @ echo 0 making ${MID}/ESCONT.spad from ${IN}/cont.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ESCONT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ESCONT ExpertSystemContinuityPackage" ${IN}/cont.spad.pamphlet >ESCONT.spad )
+
+@
+<<ESCONT1.o (O from NRLIB)>>=
+${OUT}/ESCONT1.o: ${MID}/ESCONT1.NRLIB
+ @ echo 0 making ${OUT}/ESCONT1.o from ${MID}/ESCONT1.NRLIB
+ @ cp ${MID}/ESCONT1.NRLIB/code.o ${OUT}/ESCONT1.o
+
+@
+<<ESCONT1.NRLIB (NRLIB from MID)>>=
+${MID}/ESCONT1.NRLIB: ${MID}/ESCONT1.spad
+ @ echo 0 making ${MID}/ESCONT1.NRLIB from ${MID}/ESCONT1.spad
+ @ (cd ${MID} ; echo ')co ESCONT1.spad' | ${INTERPSYS} )
+
+@
+<<ESCONT1.spad (SPAD from IN)>>=
+${MID}/ESCONT1.spad: ${IN}/cont.spad.pamphlet
+ @ echo 0 making ${MID}/ESCONT1.spad from ${IN}/cont.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ESCONT1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ESCONT1 ExpertSystemContinuityPackage1" ${IN}/cont.spad.pamphlet >ESCONT1.spad )
+
+@
+<<cont.spad.dvi (DOC from IN)>>=
+${DOC}/cont.spad.dvi: ${IN}/cont.spad.pamphlet
+ @ echo 0 making ${DOC}/cont.spad.dvi from ${IN}/cont.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/cont.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} cont.spad ; \
+ rm -f ${DOC}/cont.spad.pamphlet ; \
+ rm -f ${DOC}/cont.spad.tex ; \
+ rm -f ${DOC}/cont.spad )
+
+@
+\subsection{coordsys.spad \cite{1}}
+<<coordsys.spad (SPAD from IN)>>=
+${MID}/coordsys.spad: ${IN}/coordsys.spad.pamphlet
+ @ echo 0 making ${MID}/coordsys.spad from ${IN}/coordsys.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/coordsys.spad.pamphlet >coordsys.spad )
+
+@
+<<COORDSYS.o (O from NRLIB)>>=
+${OUT}/COORDSYS.o: ${MID}/COORDSYS.NRLIB
+ @ echo 0 making ${OUT}/COORDSYS.o from ${MID}/COORDSYS.NRLIB
+ @ cp ${MID}/COORDSYS.NRLIB/code.o ${OUT}/COORDSYS.o
+
+@
+<<COORDSYS.NRLIB (NRLIB from MID)>>=
+${MID}/COORDSYS.NRLIB: ${MID}/COORDSYS.spad
+ @ echo 0 making ${MID}/COORDSYS.NRLIB from ${MID}/COORDSYS.spad
+ @ (cd ${MID} ; echo ')co COORDSYS.spad' | ${INTERPSYS} )
+
+@
+<<COORDSYS.spad (SPAD from IN)>>=
+${MID}/COORDSYS.spad: ${IN}/coordsys.spad.pamphlet
+ @ echo 0 making ${MID}/COORDSYS.spad from ${IN}/coordsys.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COORDSYS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COORDSYS CoordinateSystems" ${IN}/coordsys.spad.pamphlet >COORDSYS.spad )
+
+@
+<<coordsys.spad.dvi (DOC from IN)>>=
+${DOC}/coordsys.spad.dvi: ${IN}/coordsys.spad.pamphlet
+ @ echo 0 making ${DOC}/coordsys.spad.dvi from ${IN}/coordsys.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/coordsys.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} coordsys.spad ; \
+ rm -f ${DOC}/coordsys.spad.pamphlet ; \
+ rm -f ${DOC}/coordsys.spad.tex ; \
+ rm -f ${DOC}/coordsys.spad )
+
+@
+\subsection{cra.spad \cite{1}}
+<<cra.spad (SPAD from IN)>>=
+${MID}/cra.spad: ${IN}/cra.spad.pamphlet
+ @ echo 0 making ${MID}/cra.spad from ${IN}/cra.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/cra.spad.pamphlet >cra.spad )
+
+@
+<<CRAPACK.o (O from NRLIB)>>=
+${OUT}/CRAPACK.o: ${MID}/CRAPACK.NRLIB
+ @ echo 0 making ${OUT}/CRAPACK.o from ${MID}/CRAPACK.NRLIB
+ @ cp ${MID}/CRAPACK.NRLIB/code.o ${OUT}/CRAPACK.o
+
+@
+<<CRAPACK.NRLIB (NRLIB from MID)>>=
+${MID}/CRAPACK.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/CRAPACK.spad
+ @ echo 0 making ${MID}/CRAPACK.NRLIB from ${MID}/CRAPACK.spad
+ @ (cd ${MID} ; echo ')co CRAPACK.spad' | ${INTERPSYS} )
+
+@
+<<CRAPACK.spad (SPAD from IN)>>=
+${MID}/CRAPACK.spad: ${IN}/cra.spad.pamphlet
+ @ echo 0 making ${MID}/CRAPACK.spad from ${IN}/cra.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CRAPACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CRAPACK CRApackage" ${IN}/cra.spad.pamphlet >CRAPACK.spad )
+
+@
+<<cra.spad.dvi (DOC from IN)>>=
+${DOC}/cra.spad.dvi: ${IN}/cra.spad.pamphlet
+ @ echo 0 making ${DOC}/cra.spad.dvi from ${IN}/cra.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/cra.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} cra.spad ; \
+ rm -f ${DOC}/cra.spad.pamphlet ; \
+ rm -f ${DOC}/cra.spad.tex ; \
+ rm -f ${DOC}/cra.spad )
+
+@
+\subsection{crfp.spad \cite{1}}
+<<crfp.spad (SPAD from IN)>>=
+${MID}/crfp.spad: ${IN}/crfp.spad.pamphlet
+ @ echo 0 making ${MID}/crfp.spad from ${IN}/crfp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/crfp.spad.pamphlet >crfp.spad )
+
+@
+<<CRFP.o (O from NRLIB)>>=
+${OUT}/CRFP.o: ${MID}/CRFP.NRLIB
+ @ echo 0 making ${OUT}/CRFP.o from ${MID}/CRFP.NRLIB
+ @ cp ${MID}/CRFP.NRLIB/code.o ${OUT}/CRFP.o
+
+@
+<<CRFP.NRLIB (NRLIB from MID)>>=
+${MID}/CRFP.NRLIB: ${MID}/CRFP.spad
+ @ echo 0 making ${MID}/CRFP.NRLIB from ${MID}/CRFP.spad
+ @ (cd ${MID} ; echo ')co CRFP.spad' | ${INTERPSYS} )
+
+@
+<<CRFP.spad (SPAD from IN)>>=
+${MID}/CRFP.spad: ${IN}/crfp.spad.pamphlet
+ @ echo 0 making ${MID}/CRFP.spad from ${IN}/crfp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CRFP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CRFP ComplexRootFindingPackage" ${IN}/crfp.spad.pamphlet >CRFP.spad )
+
+@
+<<crfp.spad.dvi (DOC from IN)>>=
+${DOC}/crfp.spad.dvi: ${IN}/crfp.spad.pamphlet
+ @ echo 0 making ${DOC}/crfp.spad.dvi from ${IN}/crfp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/crfp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} crfp.spad ; \
+ rm -f ${DOC}/crfp.spad.pamphlet ; \
+ rm -f ${DOC}/crfp.spad.tex ; \
+ rm -f ${DOC}/crfp.spad )
+
+@
+\subsection{curve.spad \cite{1}}
+<<curve.spad (SPAD from IN)>>=
+${MID}/curve.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/curve.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/curve.spad.pamphlet >curve.spad )
+
+@
+<<ALGFF.o (O from NRLIB)>>=
+${OUT}/ALGFF.o: ${MID}/ALGFF.NRLIB
+ @ echo 0 making ${OUT}/ALGFF.o from ${MID}/ALGFF.NRLIB
+ @ cp ${MID}/ALGFF.NRLIB/code.o ${OUT}/ALGFF.o
+
+@
+<<ALGFF.NRLIB (NRLIB from MID)>>=
+${MID}/ALGFF.NRLIB: ${MID}/ALGFF.spad
+ @ echo 0 making ${MID}/ALGFF.NRLIB from ${MID}/ALGFF.spad
+ @ (cd ${MID} ; echo ')co ALGFF.spad' | ${INTERPSYS} )
+
+@
+<<ALGFF.spad (SPAD from IN)>>=
+${MID}/ALGFF.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/ALGFF.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGFF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ALGFF AlgebraicFunctionField" ${IN}/curve.spad.pamphlet >ALGFF.spad )
+
+@
+<<CHVAR.o (O from NRLIB)>>=
+${OUT}/CHVAR.o: ${MID}/CHVAR.NRLIB
+ @ echo 0 making ${OUT}/CHVAR.o from ${MID}/CHVAR.NRLIB
+ @ cp ${MID}/CHVAR.NRLIB/code.o ${OUT}/CHVAR.o
+
+@
+<<CHVAR.NRLIB (NRLIB from MID)>>=
+${MID}/CHVAR.NRLIB: ${MID}/CHVAR.spad
+ @ echo 0 making ${MID}/CHVAR.NRLIB from ${MID}/CHVAR.spad
+ @ (cd ${MID} ; echo ')co CHVAR.spad' | ${INTERPSYS} )
+
+@
+<<CHVAR.spad (SPAD from IN)>>=
+${MID}/CHVAR.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/CHVAR.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CHVAR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CHVAR ChangeOfVariable" ${IN}/curve.spad.pamphlet >CHVAR.spad )
+
+@
+<<FFCAT-.o (O from NRLIB)>>=
+${OUT}/FFCAT-.o: ${MID}/FFCAT.NRLIB
+ @ echo 0 making ${OUT}/FFCAT-.o from ${MID}/FFCAT-.NRLIB
+ @ cp ${MID}/FFCAT-.NRLIB/code.o ${OUT}/FFCAT-.o
+
+@
+<<FFCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/FFCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/FFCAT.spad
+ @ echo 0 making ${MID}/FFCAT-.NRLIB from ${MID}/FFCAT.spad
+ @ (cd ${MID} ; echo ')co FFCAT.spad' | ${INTERPSYS} )
+
+@
+<<FFCAT.o (O from NRLIB)>>=
+${OUT}/FFCAT.o: ${MID}/FFCAT.NRLIB
+ @ echo 0 making ${OUT}/FFCAT.o from ${MID}/FFCAT.NRLIB
+ @ cp ${MID}/FFCAT.NRLIB/code.o ${OUT}/FFCAT.o
+
+@
+<<FFCAT.NRLIB (NRLIB from MID)>>=
+${MID}/FFCAT.NRLIB: ${MID}/FFCAT.spad
+ @ echo 0 making ${MID}/FFCAT.NRLIB from ${MID}/FFCAT.spad
+ @ (cd ${MID} ; echo ')co FFCAT.spad' | ${INTERPSYS} )
+
+@
+<<FFCAT.spad (SPAD from IN)>>=
+${MID}/FFCAT.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/FFCAT.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FFCAT FunctionFieldCategory" ${IN}/curve.spad.pamphlet >FFCAT.spad )
+
+@
+<<FFCAT2.o (O from NRLIB)>>=
+${OUT}/FFCAT2.o: ${MID}/FFCAT2.NRLIB
+ @ echo 0 making ${OUT}/FFCAT2.o from ${MID}/FFCAT2.NRLIB
+ @ cp ${MID}/FFCAT2.NRLIB/code.o ${OUT}/FFCAT2.o
+
+@
+<<FFCAT2.NRLIB (NRLIB from MID)>>=
+${MID}/FFCAT2.NRLIB: ${MID}/FFCAT2.spad
+ @ echo 0 making ${MID}/FFCAT2.NRLIB from ${MID}/FFCAT2.spad
+ @ (cd ${MID} ; echo ')co FFCAT2.spad' | ${INTERPSYS} )
+
+@
+<<FFCAT2.spad (SPAD from IN)>>=
+${MID}/FFCAT2.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/FFCAT2.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFCAT2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFCAT2 FunctionFieldCategoryFunctions2" ${IN}/curve.spad.pamphlet >FFCAT2.spad )
+
+@
+<<MMAP.o (O from NRLIB)>>=
+${OUT}/MMAP.o: ${MID}/MMAP.NRLIB
+ @ echo 0 making ${OUT}/MMAP.o from ${MID}/MMAP.NRLIB
+ @ cp ${MID}/MMAP.NRLIB/code.o ${OUT}/MMAP.o
+
+@
+<<MMAP.NRLIB (NRLIB from MID)>>=
+${MID}/MMAP.NRLIB: ${MID}/MMAP.spad
+ @ echo 0 making ${MID}/MMAP.NRLIB from ${MID}/MMAP.spad
+ @ (cd ${MID} ; echo ')co MMAP.spad' | ${INTERPSYS} )
+
+@
+<<MMAP.spad (SPAD from IN)>>=
+${MID}/MMAP.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/MMAP.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MMAP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MMAP MultipleMap" ${IN}/curve.spad.pamphlet >MMAP.spad )
+
+@
+<<RADFF.o (O from NRLIB)>>=
+${OUT}/RADFF.o: ${MID}/RADFF.NRLIB
+ @ echo 0 making ${OUT}/RADFF.o from ${MID}/RADFF.NRLIB
+ @ cp ${MID}/RADFF.NRLIB/code.o ${OUT}/RADFF.o
+
+@
+<<RADFF.NRLIB (NRLIB from MID)>>=
+${MID}/RADFF.NRLIB: ${MID}/RADFF.spad
+ @ echo 0 making ${MID}/RADFF.NRLIB from ${MID}/RADFF.spad
+ @ (cd ${MID} ; echo ')co RADFF.spad' | ${INTERPSYS} )
+
+@
+<<RADFF.spad (SPAD from IN)>>=
+${MID}/RADFF.spad: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${MID}/RADFF.spad from ${IN}/curve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RADFF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RADFF RadicalFunctionField" ${IN}/curve.spad.pamphlet >RADFF.spad )
+
+@
+<<curve.spad.dvi (DOC from IN)>>=
+${DOC}/curve.spad.dvi: ${IN}/curve.spad.pamphlet
+ @ echo 0 making ${DOC}/curve.spad.dvi from ${IN}/curve.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/curve.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} curve.spad ; \
+ rm -f ${DOC}/curve.spad.pamphlet ; \
+ rm -f ${DOC}/curve.spad.tex ; \
+ rm -f ${DOC}/curve.spad )
+
+@
+\subsection{cycles.spad \cite{1}}
+<<cycles.spad (SPAD from IN)>>=
+${MID}/cycles.spad: ${IN}/cycles.spad.pamphlet
+ @ echo 0 making ${MID}/cycles.spad from ${IN}/cycles.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/cycles.spad.pamphlet >cycles.spad )
+
+@
+<<CYCLES.o (O from NRLIB)>>=
+${OUT}/CYCLES.o: ${MID}/CYCLES.NRLIB
+ @ echo 0 making ${OUT}/CYCLES.o from ${MID}/CYCLES.NRLIB
+ @ cp ${MID}/CYCLES.NRLIB/code.o ${OUT}/CYCLES.o
+
+@
+<<CYCLES.NRLIB (NRLIB from MID)>>=
+${MID}/CYCLES.NRLIB: ${MID}/CYCLES.spad
+ @ echo 0 making ${MID}/CYCLES.NRLIB from ${MID}/CYCLES.spad
+ @ (cd ${MID} ; echo ')co CYCLES.spad' | ${INTERPSYS} )
+
+@
+<<CYCLES.spad (SPAD from IN)>>=
+${MID}/CYCLES.spad: ${IN}/cycles.spad.pamphlet
+ @ echo 0 making ${MID}/CYCLES.spad from ${IN}/cycles.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CYCLES.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CYCLES CycleIndicators" ${IN}/cycles.spad.pamphlet >CYCLES.spad )
+
+@
+<<EVALCYC.o (O from NRLIB)>>=
+${OUT}/EVALCYC.o: ${MID}/EVALCYC.NRLIB
+ @ echo 0 making ${OUT}/EVALCYC.o from ${MID}/EVALCYC.NRLIB
+ @ cp ${MID}/EVALCYC.NRLIB/code.o ${OUT}/EVALCYC.o
+
+@
+<<EVALCYC.NRLIB (NRLIB from MID)>>=
+${MID}/EVALCYC.NRLIB: ${MID}/EVALCYC.spad
+ @ echo 0 making ${MID}/EVALCYC.NRLIB from ${MID}/EVALCYC.spad
+ @ (cd ${MID} ; echo ')co EVALCYC.spad' | ${INTERPSYS} )
+
+@
+<<EVALCYC.spad (SPAD from IN)>>=
+${MID}/EVALCYC.spad: ${IN}/cycles.spad.pamphlet
+ @ echo 0 making ${MID}/EVALCYC.spad from ${IN}/cycles.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EVALCYC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EVALCYC EvaluateCycleIndicators" ${IN}/cycles.spad.pamphlet >EVALCYC.spad )
+
+@
+<<cycles.spad.dvi (DOC from IN)>>=
+${DOC}/cycles.spad.dvi: ${IN}/cycles.spad.pamphlet
+ @ echo 0 making ${DOC}/cycles.spad.dvi from ${IN}/cycles.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/cycles.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} cycles.spad ; \
+ rm -f ${DOC}/cycles.spad.pamphlet ; \
+ rm -f ${DOC}/cycles.spad.tex ; \
+ rm -f ${DOC}/cycles.spad )
+
+@
+\subsection{cyclotom.spad \cite{1}}
+<<cyclotom.spad (SPAD from IN)>>=
+${MID}/cyclotom.spad: ${IN}/cyclotom.spad.pamphlet
+ @ echo 0 making ${MID}/cyclotom.spad from ${IN}/cyclotom.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/cyclotom.spad.pamphlet >cyclotom.spad )
+
+@
+<<CYCLOTOM.o (O from NRLIB)>>=
+${OUT}/CYCLOTOM.o: ${MID}/CYCLOTOM.NRLIB
+ @ echo 0 making ${OUT}/CYCLOTOM.o from ${MID}/CYCLOTOM.NRLIB
+ @ cp ${MID}/CYCLOTOM.NRLIB/code.o ${OUT}/CYCLOTOM.o
+
+@
+<<CYCLOTOM.NRLIB (NRLIB from MID)>>=
+${MID}/CYCLOTOM.NRLIB: ${MID}/CYCLOTOM.spad
+ @ echo 0 making ${MID}/CYCLOTOM.NRLIB from ${MID}/CYCLOTOM.spad
+ @ (cd ${MID} ; echo ')co CYCLOTOM.spad' | ${INTERPSYS} )
+
+@
+<<CYCLOTOM.spad (SPAD from IN)>>=
+${MID}/CYCLOTOM.spad: ${IN}/cyclotom.spad.pamphlet
+ @ echo 0 making ${MID}/CYCLOTOM.spad from ${IN}/cyclotom.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CYCLOTOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CYCLOTOM CyclotomicPolynomialPackage" ${IN}/cyclotom.spad.pamphlet >CYCLOTOM.spad )
+
+@
+<<cyclotom.spad.dvi (DOC from IN)>>=
+${DOC}/cyclotom.spad.dvi: ${IN}/cyclotom.spad.pamphlet
+ @ echo 0 making ${DOC}/cyclotom.spad.dvi from ${IN}/cyclotom.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/cyclotom.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} cyclotom.spad ; \
+ rm -f ${DOC}/cyclotom.spad.pamphlet ; \
+ rm -f ${DOC}/cyclotom.spad.tex ; \
+ rm -f ${DOC}/cyclotom.spad )
+
+@
+\subsection{d01agents.spad \cite{1}}
+<<d01agents.spad (SPAD from IN)>>=
+${MID}/d01agents.spad: ${IN}/d01agents.spad.pamphlet
+ @ echo 0 making ${MID}/d01agents.spad from ${IN}/d01agents.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d01agents.spad.pamphlet >d01agents.spad )
+
+@
+<<INTFTBL.o (O from NRLIB)>>=
+${OUT}/INTFTBL.o: ${MID}/INTFTBL.NRLIB
+ @ echo 0 making ${OUT}/INTFTBL.o from ${MID}/INTFTBL.NRLIB
+ @ cp ${MID}/INTFTBL.NRLIB/code.o ${OUT}/INTFTBL.o
+
+@
+<<INTFTBL.NRLIB (NRLIB from MID)>>=
+${MID}/INTFTBL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/INTFTBL.spad
+ @ echo 0 making ${MID}/INTFTBL.NRLIB from ${MID}/INTFTBL.spad
+ @ (cd ${MID} ; echo ')co INTFTBL.spad' | ${INTERPSYS} )
+
+@
+<<INTFTBL.spad (SPAD from IN)>>=
+${MID}/INTFTBL.spad: ${IN}/d01agents.spad.pamphlet
+ @ echo 0 making ${MID}/INTFTBL.spad from ${IN}/d01agents.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTFTBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain INTFTBL IntegrationFunctionsTable" ${IN}/d01agents.spad.pamphlet >INTFTBL.spad )
+
+@
+<<d01agents.spad.dvi (DOC from IN)>>=
+${DOC}/d01agents.spad.dvi: ${IN}/d01agents.spad.pamphlet
+ @ echo 0 making ${DOC}/d01agents.spad.dvi from ${IN}/d01agents.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d01agents.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d01agents.spad ; \
+ rm -f ${DOC}/d01agents.spad.pamphlet ; \
+ rm -f ${DOC}/d01agents.spad.tex ; \
+ rm -f ${DOC}/d01agents.spad )
+
+@
+\subsection{d01Package.spad \cite{1}}
+<<d01Package.spad (SPAD from IN)>>=
+${MID}/d01Package.spad: ${IN}/d01Package.spad.pamphlet
+ @ echo 0 making ${MID}/d01Package.spad from ${IN}/d01Package.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d01Package.spad.pamphlet >d01Package.spad )
+
+@
+<<INTPACK.o (O from NRLIB)>>=
+${OUT}/INTPACK.o: ${MID}/INTPACK.NRLIB
+ @ echo 0 making ${OUT}/INTPACK.o from ${MID}/INTPACK.NRLIB
+ @ cp ${MID}/INTPACK.NRLIB/code.o ${OUT}/INTPACK.o
+
+@
+<<INTPACK.NRLIB (NRLIB from MID)>>=
+${MID}/INTPACK.NRLIB: ${MID}/INTPACK.spad
+ @ echo 0 making ${MID}/INTPACK.NRLIB from ${MID}/INTPACK.spad
+ @ (cd ${MID} ; echo ')co INTPACK.spad' | ${INTERPSYS} )
+
+@
+<<INTPACK.spad (SPAD from IN)>>=
+${MID}/INTPACK.spad: ${IN}/d01Package.spad.pamphlet
+ @ echo 0 making ${MID}/INTPACK.spad from ${IN}/d01Package.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTPACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTPACK AnnaNumericalIntegrationPackage" ${IN}/d01Package.spad.pamphlet >INTPACK.spad )
+
+@
+<<d01Package.spad.dvi (DOC from IN)>>=
+${DOC}/d01Package.spad.dvi: ${IN}/d01Package.spad.pamphlet
+ @ echo 0 making ${DOC}/d01Package.spad.dvi from ${IN}/d01Package.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d01Package.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d01Package.spad ; \
+ rm -f ${DOC}/d01Package.spad.pamphlet ; \
+ rm -f ${DOC}/d01Package.spad.tex ; \
+ rm -f ${DOC}/d01Package.spad )
+
+@
+\subsection{d01routine.spad \cite{1}}
+<<d01routine.spad (SPAD from IN)>>=
+${MID}/d01routine.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/d01routine.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d01routine.spad.pamphlet >d01routine.spad )
+
+@
+<<D01AJFA.o (O from NRLIB)>>=
+${OUT}/D01AJFA.o: ${MID}/D01AJFA.NRLIB
+ @ echo 0 making ${OUT}/D01AJFA.o from ${MID}/D01AJFA.NRLIB
+ @ cp ${MID}/D01AJFA.NRLIB/code.o ${OUT}/D01AJFA.o
+
+@
+<<D01AJFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01AJFA.NRLIB: ${MID}/D01AJFA.spad
+ @ echo 0 making ${MID}/D01AJFA.NRLIB from ${MID}/D01AJFA.spad
+ @ (cd ${MID} ; echo ')co D01AJFA.spad' | ${INTERPSYS} )
+
+@
+<<D01AJFA.spad (SPAD from IN)>>=
+${MID}/D01AJFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01AJFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01AJFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01AJFA d01ajfAnnaType" ${IN}/d01routine.spad.pamphlet >D01AJFA.spad )
+
+@
+<<D01AKFA.o (O from NRLIB)>>=
+${OUT}/D01AKFA.o: ${MID}/D01AKFA.NRLIB
+ @ echo 0 making ${OUT}/D01AKFA.o from ${MID}/D01AKFA.NRLIB
+ @ cp ${MID}/D01AKFA.NRLIB/code.o ${OUT}/D01AKFA.o
+
+@
+<<D01AKFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01AKFA.NRLIB: ${MID}/D01AKFA.spad
+ @ echo 0 making ${MID}/D01AKFA.NRLIB from ${MID}/D01AKFA.spad
+ @ (cd ${MID} ; echo ')co D01AKFA.spad' | ${INTERPSYS} )
+
+@
+<<D01AKFA.spad (SPAD from IN)>>=
+${MID}/D01AKFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01AKFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01AKFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01AKFA d01akfAnnaType" ${IN}/d01routine.spad.pamphlet >D01AKFA.spad )
+
+@
+<<D01ALFA.o (O from NRLIB)>>=
+${OUT}/D01ALFA.o: ${MID}/D01ALFA.NRLIB
+ @ echo 0 making ${OUT}/D01ALFA.o from ${MID}/D01ALFA.NRLIB
+ @ cp ${MID}/D01ALFA.NRLIB/code.o ${OUT}/D01ALFA.o
+
+@
+<<D01ALFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01ALFA.NRLIB: ${MID}/D01ALFA.spad
+ @ echo 0 making ${MID}/D01ALFA.NRLIB from ${MID}/D01ALFA.spad
+ @ (cd ${MID} ; echo ')co D01ALFA.spad' | ${INTERPSYS} )
+
+@
+<<D01ALFA.spad (SPAD from IN)>>=
+${MID}/D01ALFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01ALFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01ALFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01ALFA d01alfAnnaType" ${IN}/d01routine.spad.pamphlet >D01ALFA.spad )
+
+@
+<<D01AMFA.o (O from NRLIB)>>=
+${OUT}/D01AMFA.o: ${MID}/D01AMFA.NRLIB
+ @ echo 0 making ${OUT}/D01AMFA.o from ${MID}/D01AMFA.NRLIB
+ @ cp ${MID}/D01AMFA.NRLIB/code.o ${OUT}/D01AMFA.o
+
+@
+<<D01AMFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01AMFA.NRLIB: ${MID}/D01AMFA.spad
+ @ echo 0 making ${MID}/D01AMFA.NRLIB from ${MID}/D01AMFA.spad
+ @ (cd ${MID} ; echo ')co D01AMFA.spad' | ${INTERPSYS} )
+
+@
+<<D01AMFA.spad (SPAD from IN)>>=
+${MID}/D01AMFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01AMFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01AMFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01AMFA d01amfAnnaType" ${IN}/d01routine.spad.pamphlet >D01AMFA.spad )
+
+@
+<<D01ANFA.o (O from NRLIB)>>=
+${OUT}/D01ANFA.o: ${MID}/D01ANFA.NRLIB
+ @ echo 0 making ${OUT}/D01ANFA.o from ${MID}/D01ANFA.NRLIB
+ @ cp ${MID}/D01ANFA.NRLIB/code.o ${OUT}/D01ANFA.o
+
+@
+<<D01ANFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01ANFA.NRLIB: ${MID}/D01ANFA.spad
+ @ echo 0 making ${MID}/D01ANFA.NRLIB from ${MID}/D01ANFA.spad
+ @ (cd ${MID} ; echo ')co D01ANFA.spad' | ${INTERPSYS} )
+
+@
+<<D01ANFA.spad (SPAD from IN)>>=
+${MID}/D01ANFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01ANFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01ANFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01ANFA d01anfAnnaType" ${IN}/d01routine.spad.pamphlet >D01ANFA.spad )
+
+@
+<<D01APFA.o (O from NRLIB)>>=
+${OUT}/D01APFA.o: ${MID}/D01APFA.NRLIB
+ @ echo 0 making ${OUT}/D01APFA.o from ${MID}/D01APFA.NRLIB
+ @ cp ${MID}/D01APFA.NRLIB/code.o ${OUT}/D01APFA.o
+
+@
+<<D01APFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01APFA.NRLIB: ${MID}/D01APFA.spad
+ @ echo 0 making ${MID}/D01APFA.NRLIB from ${MID}/D01APFA.spad
+ @ (cd ${MID} ; echo ')co D01APFA.spad' | ${INTERPSYS} )
+
+@
+<<D01APFA.spad (SPAD from IN)>>=
+${MID}/D01APFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01APFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01APFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01APFA d01apfAnnaType" ${IN}/d01routine.spad.pamphlet >D01APFA.spad )
+
+@
+<<D01AQFA.o (O from NRLIB)>>=
+${OUT}/D01AQFA.o: ${MID}/D01AQFA.NRLIB
+ @ echo 0 making ${OUT}/D01AQFA.o from ${MID}/D01AQFA.NRLIB
+ @ cp ${MID}/D01AQFA.NRLIB/code.o ${OUT}/D01AQFA.o
+
+@
+<<D01AQFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01AQFA.NRLIB: ${MID}/D01AQFA.spad
+ @ echo 0 making ${MID}/D01AQFA.NRLIB from ${MID}/D01AQFA.spad
+ @ (cd ${MID} ; echo ')co D01AQFA.spad' | ${INTERPSYS} )
+
+@
+<<D01AQFA.spad (SPAD from IN)>>=
+${MID}/D01AQFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01AQFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01AQFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01AQFA d01aqfAnnaType" ${IN}/d01routine.spad.pamphlet >D01AQFA.spad )
+
+@
+<<D01ASFA.o (O from NRLIB)>>=
+${OUT}/D01ASFA.o: ${MID}/D01ASFA.NRLIB
+ @ echo 0 making ${OUT}/D01ASFA.o from ${MID}/D01ASFA.NRLIB
+ @ cp ${MID}/D01ASFA.NRLIB/code.o ${OUT}/D01ASFA.o
+
+@
+<<D01ASFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01ASFA.NRLIB: ${MID}/D01ASFA.spad
+ @ echo 0 making ${MID}/D01ASFA.NRLIB from ${MID}/D01ASFA.spad
+ @ (cd ${MID} ; echo ')co D01ASFA.spad' | ${INTERPSYS} )
+
+@
+<<D01ASFA.spad (SPAD from IN)>>=
+${MID}/D01ASFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01ASFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01ASFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01ASFA d01asfAnnaType" ${IN}/d01routine.spad.pamphlet >D01ASFA.spad )
+
+@
+<<D01FCFA.o (O from NRLIB)>>=
+${OUT}/D01FCFA.o: ${MID}/D01FCFA.NRLIB
+ @ echo 0 making ${OUT}/D01FCFA.o from ${MID}/D01FCFA.NRLIB
+ @ cp ${MID}/D01FCFA.NRLIB/code.o ${OUT}/D01FCFA.o
+
+@
+<<D01FCFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01FCFA.NRLIB: ${MID}/D01FCFA.spad
+ @ echo 0 making ${MID}/D01FCFA.NRLIB from ${MID}/D01FCFA.spad
+ @ (cd ${MID} ; echo ')co D01FCFA.spad' | ${INTERPSYS} )
+
+@
+<<D01FCFA.spad (SPAD from IN)>>=
+${MID}/D01FCFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01FCFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01FCFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01FCFA d01fcfAnnaType" ${IN}/d01routine.spad.pamphlet >D01FCFA.spad )
+
+@
+<<D01GBFA.o (O from NRLIB)>>=
+${OUT}/D01GBFA.o: ${MID}/D01GBFA.NRLIB
+ @ echo 0 making ${OUT}/D01GBFA.o from ${MID}/D01GBFA.NRLIB
+ @ cp ${MID}/D01GBFA.NRLIB/code.o ${OUT}/D01GBFA.o
+
+@
+<<D01GBFA.NRLIB (NRLIB from MID)>>=
+${MID}/D01GBFA.NRLIB: ${MID}/D01GBFA.spad
+ @ echo 0 making ${MID}/D01GBFA.NRLIB from ${MID}/D01GBFA.spad
+ @ (cd ${MID} ; echo ')co D01GBFA.spad' | ${INTERPSYS} )
+
+@
+<<D01GBFA.spad (SPAD from IN)>>=
+${MID}/D01GBFA.spad: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${MID}/D01GBFA.spad from ${IN}/d01routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01GBFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01GBFA d01gbfAnnaType" ${IN}/d01routine.spad.pamphlet >D01GBFA.spad )
+
+@
+<<d01routine.spad.dvi (DOC from IN)>>=
+${DOC}/d01routine.spad.dvi: ${IN}/d01routine.spad.pamphlet
+ @ echo 0 making ${DOC}/d01routine.spad.dvi from ${IN}/d01routine.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d01routine.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d01routine.spad ; \
+ rm -f ${DOC}/d01routine.spad.pamphlet ; \
+ rm -f ${DOC}/d01routine.spad.tex ; \
+ rm -f ${DOC}/d01routine.spad )
+
+@
+\subsection{d01.spad \cite{1}}
+<<d01.spad (SPAD from IN)>>=
+${MID}/d01.spad: ${IN}/d01.spad.pamphlet
+ @ echo 0 making ${MID}/d01.spad from ${IN}/d01.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d01.spad.pamphlet >d01.spad )
+
+@
+<<NAGD01.o (O from NRLIB)>>=
+${OUT}/NAGD01.o: ${MID}/NAGD01.NRLIB
+ @ echo 0 making ${OUT}/NAGD01.o from ${MID}/NAGD01.NRLIB
+ @ cp ${MID}/NAGD01.NRLIB/code.o ${OUT}/NAGD01.o
+
+@
+<<NAGD01.NRLIB (NRLIB from MID)>>=
+${MID}/NAGD01.NRLIB: ${MID}/NAGD01.spad
+ @ echo 0 making ${MID}/NAGD01.NRLIB from ${MID}/NAGD01.spad
+ @ (cd ${MID} ; echo ')co NAGD01.spad' | ${INTERPSYS} )
+
+@
+<<NAGD01.spad (SPAD from IN)>>=
+${MID}/NAGD01.spad: ${IN}/d01.spad.pamphlet
+ @ echo 0 making ${MID}/NAGD01.spad from ${IN}/d01.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGD01.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGD01 NagIntegrationPackage" ${IN}/d01.spad.pamphlet >NAGD01.spad )
+
+@
+<<d01.spad.dvi (DOC from IN)>>=
+${DOC}/d01.spad.dvi: ${IN}/d01.spad.pamphlet
+ @ echo 0 making ${DOC}/d01.spad.dvi from ${IN}/d01.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d01.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d01.spad ; \
+ rm -f ${DOC}/d01.spad.pamphlet ; \
+ rm -f ${DOC}/d01.spad.tex ; \
+ rm -f ${DOC}/d01.spad )
+
+@
+\subsection{d01transform.spad \cite{1}}
+<<d01transform.spad (SPAD from IN)>>=
+${MID}/d01transform.spad: ${IN}/d01transform.spad.pamphlet
+ @ echo 0 making ${MID}/d01transform.spad from ${IN}/d01transform.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d01transform.spad.pamphlet >d01transform.spad )
+
+@
+<<D01TRNS.o (O from NRLIB)>>=
+${OUT}/D01TRNS.o: ${MID}/D01TRNS.NRLIB
+ @ echo 0 making ${OUT}/D01TRNS.o from ${MID}/D01TRNS.NRLIB
+ @ cp ${MID}/D01TRNS.NRLIB/code.o ${OUT}/D01TRNS.o
+
+@
+<<D01TRNS.NRLIB (NRLIB from MID)>>=
+${MID}/D01TRNS.NRLIB: ${MID}/D01TRNS.spad
+ @ echo 0 making ${MID}/D01TRNS.NRLIB from ${MID}/D01TRNS.spad
+ @ (cd ${MID} ; echo ')co D01TRNS.spad' | ${INTERPSYS} )
+
+@
+<<D01TRNS.spad (SPAD from IN)>>=
+${MID}/D01TRNS.spad: ${IN}/d01transform.spad.pamphlet
+ @ echo 0 making ${MID}/D01TRNS.spad from ${IN}/d01transform.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D01TRNS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D01TRNS d01TransformFunctionType" ${IN}/d01transform.spad.pamphlet >D01TRNS.spad )
+
+@
+<<d01transform.spad.dvi (DOC from IN)>>=
+${DOC}/d01transform.spad.dvi: ${IN}/d01transform.spad.pamphlet
+ @ echo 0 making ${DOC}/d01transform.spad.dvi from ${IN}/d01transform.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d01transform.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d01transform.spad ; \
+ rm -f ${DOC}/d01transform.spad.pamphlet ; \
+ rm -f ${DOC}/d01transform.spad.tex ; \
+ rm -f ${DOC}/d01transform.spad )
+
+@
+\subsection{d01weights.spad \cite{1}}
+<<d01weights.spad (SPAD from IN)>>=
+${MID}/d01weights.spad: ${IN}/d01weights.spad.pamphlet
+ @ echo 0 making ${MID}/d01weights.spad from ${IN}/d01weights.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d01weights.spad.pamphlet >d01weights.spad )
+
+@
+<<d01weights.spad.dvi (DOC from IN)>>=
+${DOC}/d01weights.spad.dvi: ${IN}/d01weights.spad.pamphlet
+ @ echo 0 making ${DOC}/d01weights.spad.dvi from ${IN}/d01weights.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d01weights.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d01weights.spad ; \
+ rm -f ${DOC}/d01weights.spad.pamphlet ; \
+ rm -f ${DOC}/d01weights.spad.tex ; \
+ rm -f ${DOC}/d01weights.spad )
+
+@
+\subsection{d02agents.spad \cite{1}}
+<<d02agents.spad (SPAD from IN)>>=
+${MID}/d02agents.spad: ${IN}/d02agents.spad.pamphlet
+ @ echo 0 making ${MID}/d02agents.spad from ${IN}/d02agents.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d02agents.spad.pamphlet >d02agents.spad )
+
+@
+<<D02AGNT.o (O from NRLIB)>>=
+${OUT}/D02AGNT.o: ${MID}/D02AGNT.NRLIB
+ @ echo 0 making ${OUT}/D02AGNT.o from ${MID}/D02AGNT.NRLIB
+ @ cp ${MID}/D02AGNT.NRLIB/code.o ${OUT}/D02AGNT.o
+
+@
+<<D02AGNT.NRLIB (NRLIB from MID)>>=
+${MID}/D02AGNT.NRLIB: ${MID}/D02AGNT.spad
+ @ echo 0 making ${MID}/D02AGNT.NRLIB from ${MID}/D02AGNT.spad
+ @ (cd ${MID} ; echo ')co D02AGNT.spad' | ${INTERPSYS} )
+
+@
+<<D02AGNT.spad (SPAD from IN)>>=
+${MID}/D02AGNT.spad: ${IN}/d02agents.spad.pamphlet
+ @ echo 0 making ${MID}/D02AGNT.spad from ${IN}/d02agents.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D02AGNT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package D02AGNT d02AgentsPackage" ${IN}/d02agents.spad.pamphlet >D02AGNT.spad )
+
+@
+<<ODEIFTBL.o (O from NRLIB)>>=
+${OUT}/ODEIFTBL.o: ${MID}/ODEIFTBL.NRLIB
+ @ echo 0 making ${OUT}/ODEIFTBL.o from ${MID}/ODEIFTBL.NRLIB
+ @ cp ${MID}/ODEIFTBL.NRLIB/code.o ${OUT}/ODEIFTBL.o
+
+@
+<<ODEIFTBL.NRLIB (NRLIB from MID)>>=
+${MID}/ODEIFTBL.NRLIB: ${MID}/ODEIFTBL.spad
+ @ echo 0 making ${MID}/ODEIFTBL.NRLIB from ${MID}/ODEIFTBL.spad
+ @ (cd ${MID} ; echo ')co ODEIFTBL.spad' | ${INTERPSYS} )
+
+@
+<<ODEIFTBL.spad (SPAD from IN)>>=
+${MID}/ODEIFTBL.spad: ${IN}/d02agents.spad.pamphlet
+ @ echo 0 making ${MID}/ODEIFTBL.spad from ${IN}/d02agents.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEIFTBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ODEIFTBL ODEIntensityFunctionsTable" ${IN}/d02agents.spad.pamphlet >ODEIFTBL.spad )
+
+@
+<<d02agents.spad.dvi (DOC from IN)>>=
+${DOC}/d02agents.spad.dvi: ${IN}/d02agents.spad.pamphlet
+ @ echo 0 making ${DOC}/d02agents.spad.dvi from ${IN}/d02agents.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d02agents.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d02agents.spad ; \
+ rm -f ${DOC}/d02agents.spad.pamphlet ; \
+ rm -f ${DOC}/d02agents.spad.tex ; \
+ rm -f ${DOC}/d02agents.spad )
+
+@
+\subsection{d02Package.spad \cite{1}}
+<<d02Package.spad (SPAD from IN)>>=
+${MID}/d02Package.spad: ${IN}/d02Package.spad.pamphlet
+ @ echo 0 making ${MID}/d02Package.spad from ${IN}/d02Package.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d02Package.spad.pamphlet >d02Package.spad )
+
+@
+<<ODEPACK.o (O from NRLIB)>>=
+${OUT}/ODEPACK.o: ${MID}/ODEPACK.NRLIB
+ @ echo 0 making ${OUT}/ODEPACK.o from ${MID}/ODEPACK.NRLIB
+ @ cp ${MID}/ODEPACK.NRLIB/code.o ${OUT}/ODEPACK.o
+
+@
+<<ODEPACK.NRLIB (NRLIB from MID)>>=
+${MID}/ODEPACK.NRLIB: ${MID}/ODEPACK.spad
+ @ echo 0 making ${MID}/ODEPACK.NRLIB from ${MID}/ODEPACK.spad
+ @ (cd ${MID} ; echo ')co ODEPACK.spad' | ${INTERPSYS} )
+
+@
+<<ODEPACK.spad (SPAD from IN)>>=
+${MID}/ODEPACK.spad: ${IN}/d02Package.spad.pamphlet
+ @ echo 0 making ${MID}/ODEPACK.spad from ${IN}/d02Package.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEPACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODEPACK AnnaOrdinaryDifferentialEquationPackage" ${IN}/d02Package.spad.pamphlet >ODEPACK.spad )
+
+@
+<<d02Package.spad.dvi (DOC from IN)>>=
+${DOC}/d02Package.spad.dvi: ${IN}/d02Package.spad.pamphlet
+ @ echo 0 making ${DOC}/d02Package.spad.dvi from ${IN}/d02Package.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d02Package.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d02Package.spad ; \
+ rm -f ${DOC}/d02Package.spad.pamphlet ; \
+ rm -f ${DOC}/d02Package.spad.tex ; \
+ rm -f ${DOC}/d02Package.spad )
+
+@
+\subsection{d02routine.spad \cite{1}}
+<<d02routine.spad (SPAD from IN)>>=
+${MID}/d02routine.spad: ${IN}/d02routine.spad.pamphlet
+ @ echo 0 making ${MID}/d02routine.spad from ${IN}/d02routine.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d02routine.spad.pamphlet >d02routine.spad )
+
+@
+<<D02BBFA.o (O from NRLIB)>>=
+${OUT}/D02BBFA.o: ${MID}/D02BBFA.NRLIB
+ @ echo 0 making ${OUT}/D02BBFA.o from ${MID}/D02BBFA.NRLIB
+ @ cp ${MID}/D02BBFA.NRLIB/code.o ${OUT}/D02BBFA.o
+
+@
+<<D02BBFA.NRLIB (NRLIB from MID)>>=
+${MID}/D02BBFA.NRLIB: ${MID}/D02BBFA.spad
+ @ echo 0 making ${MID}/D02BBFA.NRLIB from ${MID}/D02BBFA.spad
+ @ (cd ${MID} ; echo ')co D02BBFA.spad' | ${INTERPSYS} )
+
+@
+<<D02BBFA.spad (SPAD from IN)>>=
+${MID}/D02BBFA.spad: ${IN}/d02routine.spad.pamphlet
+ @ echo 0 making ${MID}/D02BBFA.spad from ${IN}/d02routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D02BBFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D02BBFA d02bbfAnnaType" ${IN}/d02routine.spad.pamphlet >D02BBFA.spad )
+
+@
+<<D02BHFA.o (O from NRLIB)>>=
+${OUT}/D02BHFA.o: ${MID}/D02BHFA.NRLIB
+ @ echo 0 making ${OUT}/D02BHFA.o from ${MID}/D02BHFA.NRLIB
+ @ cp ${MID}/D02BHFA.NRLIB/code.o ${OUT}/D02BHFA.o
+
+@
+<<D02BHFA.NRLIB (NRLIB from MID)>>=
+${MID}/D02BHFA.NRLIB: ${MID}/D02BHFA.spad
+ @ echo 0 making ${MID}/D02BHFA.NRLIB from ${MID}/D02BHFA.spad
+ @ (cd ${MID} ; echo ')co D02BHFA.spad' | ${INTERPSYS} )
+
+@
+<<D02BHFA.spad (SPAD from IN)>>=
+${MID}/D02BHFA.spad: ${IN}/d02routine.spad.pamphlet
+ @ echo 0 making ${MID}/D02BHFA.spad from ${IN}/d02routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D02BHFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D02BHFA d02bhfAnnaType" ${IN}/d02routine.spad.pamphlet >D02BHFA.spad )
+
+@
+<<D02CJFA.o (O from NRLIB)>>=
+${OUT}/D02CJFA.o: ${MID}/D02CJFA.NRLIB
+ @ echo 0 making ${OUT}/D02CJFA.o from ${MID}/D02CJFA.NRLIB
+ @ cp ${MID}/D02CJFA.NRLIB/code.o ${OUT}/D02CJFA.o
+
+@
+<<D02CJFA.NRLIB (NRLIB from MID)>>=
+${MID}/D02CJFA.NRLIB: ${MID}/D02CJFA.spad
+ @ echo 0 making ${MID}/D02CJFA.NRLIB from ${MID}/D02CJFA.spad
+ @ (cd ${MID} ; echo ')co D02CJFA.spad' | ${INTERPSYS} )
+
+@
+<<D02CJFA.spad (SPAD from IN)>>=
+${MID}/D02CJFA.spad: ${IN}/d02routine.spad.pamphlet
+ @ echo 0 making ${MID}/D02CJFA.spad from ${IN}/d02routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D02CJFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D02CJFA d02cjfAnnaType" ${IN}/d02routine.spad.pamphlet >D02CJFA.spad )
+
+@
+<<D02EJFA.o (O from NRLIB)>>=
+${OUT}/D02EJFA.o: ${MID}/D02EJFA.NRLIB
+ @ echo 0 making ${OUT}/D02EJFA.o from ${MID}/D02EJFA.NRLIB
+ @ cp ${MID}/D02EJFA.NRLIB/code.o ${OUT}/D02EJFA.o
+
+@
+<<D02EJFA.NRLIB (NRLIB from MID)>>=
+${MID}/D02EJFA.NRLIB: ${MID}/D02EJFA.spad
+ @ echo 0 making ${MID}/D02EJFA.NRLIB from ${MID}/D02EJFA.spad
+ @ (cd ${MID} ; echo ')co D02EJFA.spad' | ${INTERPSYS} )
+
+@
+<<D02EJFA.spad (SPAD from IN)>>=
+${MID}/D02EJFA.spad: ${IN}/d02routine.spad.pamphlet
+ @ echo 0 making ${MID}/D02EJFA.spad from ${IN}/d02routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D02EJFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D02EJFA d02ejfAnnaType" ${IN}/d02routine.spad.pamphlet >D02EJFA.spad )
+
+@
+<<d02routine.spad.dvi (DOC from IN)>>=
+${DOC}/d02routine.spad.dvi: ${IN}/d02routine.spad.pamphlet
+ @ echo 0 making ${DOC}/d02routine.spad.dvi from ${IN}/d02routine.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d02routine.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d02routine.spad ; \
+ rm -f ${DOC}/d02routine.spad.pamphlet ; \
+ rm -f ${DOC}/d02routine.spad.tex ; \
+ rm -f ${DOC}/d02routine.spad )
+
+@
+\subsection{d02.spad \cite{1}}
+<<d02.spad (SPAD from IN)>>=
+${MID}/d02.spad: ${IN}/d02.spad.pamphlet
+ @ echo 0 making ${MID}/d02.spad from ${IN}/d02.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d02.spad.pamphlet >d02.spad )
+
+@
+<<NAGD02.o (O from NRLIB)>>=
+${OUT}/NAGD02.o: ${MID}/NAGD02.NRLIB
+ @ echo 0 making ${OUT}/NAGD02.o from ${MID}/NAGD02.NRLIB
+ @ cp ${MID}/NAGD02.NRLIB/code.o ${OUT}/NAGD02.o
+
+@
+<<NAGD02.NRLIB (NRLIB from MID)>>=
+${MID}/NAGD02.NRLIB: ${MID}/NAGD02.spad
+ @ echo 0 making ${MID}/NAGD02.NRLIB from ${MID}/NAGD02.spad
+ @ (cd ${MID} ; echo ')co NAGD02.spad' | ${INTERPSYS} )
+
+@
+<<NAGD02.spad (SPAD from IN)>>=
+${MID}/NAGD02.spad: ${IN}/d02.spad.pamphlet
+ @ echo 0 making ${MID}/NAGD02.spad from ${IN}/d02.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGD02.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGD02 NagOrdinaryDifferentialEquationsPackage" ${IN}/d02.spad.pamphlet >NAGD02.spad )
+
+@
+<<d02.spad.dvi (DOC from IN)>>=
+${DOC}/d02.spad.dvi: ${IN}/d02.spad.pamphlet
+ @ echo 0 making ${DOC}/d02.spad.dvi from ${IN}/d02.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d02.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d02.spad ; \
+ rm -f ${DOC}/d02.spad.pamphlet ; \
+ rm -f ${DOC}/d02.spad.tex ; \
+ rm -f ${DOC}/d02.spad )
+
+@
+\subsection{d03agents.spad \cite{1}}
+<<d03agents.spad (SPAD from IN)>>=
+${MID}/d03agents.spad: ${IN}/d03agents.spad.pamphlet
+ @ echo 0 making ${MID}/d03agents.spad from ${IN}/d03agents.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d03agents.spad.pamphlet >d03agents.spad )
+
+@
+<<D03AGNT.o (O from NRLIB)>>=
+${OUT}/D03AGNT.o: ${MID}/D03AGNT.NRLIB
+ @ echo 0 making ${OUT}/D03AGNT.o from ${MID}/D03AGNT.NRLIB
+ @ cp ${MID}/D03AGNT.NRLIB/code.o ${OUT}/D03AGNT.o
+
+@
+<<D03AGNT.NRLIB (NRLIB from MID)>>=
+${MID}/D03AGNT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/D03AGNT.spad
+ @ echo 0 making ${MID}/D03AGNT.NRLIB from ${MID}/D03AGNT.spad
+ @ (cd ${MID} ; echo ')co D03AGNT.spad' | ${INTERPSYS} )
+
+@
+<<D03AGNT.spad (SPAD from IN)>>=
+${MID}/D03AGNT.spad: ${IN}/d03agents.spad.pamphlet
+ @ echo 0 making ${MID}/D03AGNT.spad from ${IN}/d03agents.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D03AGNT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package D03AGNT d03AgentsPackage" ${IN}/d03agents.spad.pamphlet >D03AGNT.spad )
+
+@
+<<d03agents.spad.dvi (DOC from IN)>>=
+${DOC}/d03agents.spad.dvi: ${IN}/d03agents.spad.pamphlet
+ @ echo 0 making ${DOC}/d03agents.spad.dvi from ${IN}/d03agents.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d03agents.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d03agents.spad ; \
+ rm -f ${DOC}/d03agents.spad.pamphlet ; \
+ rm -f ${DOC}/d03agents.spad.tex ; \
+ rm -f ${DOC}/d03agents.spad )
+
+@
+\subsection{d03Package.spad \cite{1}}
+<<d03Package.spad (SPAD from IN)>>=
+${MID}/d03Package.spad: ${IN}/d03Package.spad.pamphlet
+ @ echo 0 making ${MID}/d03Package.spad from ${IN}/d03Package.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d03Package.spad.pamphlet >d03Package.spad )
+
+@
+<<PDEPACK.o (O from NRLIB)>>=
+${OUT}/PDEPACK.o: ${MID}/PDEPACK.NRLIB
+ @ echo 0 making ${OUT}/PDEPACK.o from ${MID}/PDEPACK.NRLIB
+ @ cp ${MID}/PDEPACK.NRLIB/code.o ${OUT}/PDEPACK.o
+
+@
+<<PDEPACK.NRLIB (NRLIB from MID)>>=
+${MID}/PDEPACK.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PDEPACK.spad
+ @ echo 0 making ${MID}/PDEPACK.NRLIB from ${MID}/PDEPACK.spad
+ @ (cd ${MID} ; echo ')co PDEPACK.spad' | ${INTERPSYS} )
+
+@
+<<PDEPACK.spad (SPAD from IN)>>=
+${MID}/PDEPACK.spad: ${IN}/d03Package.spad.pamphlet
+ @ echo 0 making ${MID}/PDEPACK.spad from ${IN}/d03Package.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PDEPACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PDEPACK AnnaPartialDifferentialEquationPackage" ${IN}/d03Package.spad.pamphlet >PDEPACK.spad )
+
+@
+<<d03Package.spad.dvi (DOC from IN)>>=
+${DOC}/d03Package.spad.dvi: ${IN}/d03Package.spad.pamphlet
+ @ echo 0 making ${DOC}/d03Package.spad.dvi from ${IN}/d03Package.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d03Package.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d03Package.spad ; \
+ rm -f ${DOC}/d03Package.spad.pamphlet ; \
+ rm -f ${DOC}/d03Package.spad.tex ; \
+ rm -f ${DOC}/d03Package.spad )
+
+@
+\subsection{d03routine.spad \cite{1}}
+<<d03routine.spad (SPAD from IN)>>=
+${MID}/d03routine.spad: ${IN}/d03routine.spad.pamphlet
+ @ echo 0 making ${MID}/d03routine.spad from ${IN}/d03routine.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d03routine.spad.pamphlet >d03routine.spad )
+
+@
+<<D03EEFA.o (O from NRLIB)>>=
+${OUT}/D03EEFA.o: ${MID}/D03EEFA.NRLIB
+ @ echo 0 making ${OUT}/D03EEFA.o from ${MID}/D03EEFA.NRLIB
+ @ cp ${MID}/D03EEFA.NRLIB/code.o ${OUT}/D03EEFA.o
+
+@
+<<D03EEFA.NRLIB (NRLIB from MID)>>=
+${MID}/D03EEFA.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/D03EEFA.spad
+ @ echo 0 making ${MID}/D03EEFA.NRLIB from ${MID}/D03EEFA.spad
+ @ (cd ${MID} ; echo ')co D03EEFA.spad' | ${INTERPSYS} )
+
+@
+<<D03EEFA.spad (SPAD from IN)>>=
+${MID}/D03EEFA.spad: ${IN}/d03routine.spad.pamphlet
+ @ echo 0 making ${MID}/D03EEFA.spad from ${IN}/d03routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D03EEFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D03EEFA d03eefAnnaType" ${IN}/d03routine.spad.pamphlet >D03EEFA.spad )
+
+@
+<<D03FAFA.o (O from NRLIB)>>=
+${OUT}/D03FAFA.o: ${MID}/D03FAFA.NRLIB
+ @ echo 0 making ${OUT}/D03FAFA.o from ${MID}/D03FAFA.NRLIB
+ @ cp ${MID}/D03FAFA.NRLIB/code.o ${OUT}/D03FAFA.o
+
+@
+<<D03FAFA.NRLIB (NRLIB from MID)>>=
+${MID}/D03FAFA.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/D03FAFA.spad
+ @ echo 0 making ${MID}/D03FAFA.NRLIB from ${MID}/D03FAFA.spad
+ @ (cd ${MID} ; echo ')co D03FAFA.spad' | ${INTERPSYS} )
+
+@
+<<D03FAFA.spad (SPAD from IN)>>=
+${MID}/D03FAFA.spad: ${IN}/d03routine.spad.pamphlet
+ @ echo 0 making ${MID}/D03FAFA.spad from ${IN}/d03routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf D03FAFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain D03FAFA d03fafAnnaType" ${IN}/d03routine.spad.pamphlet >D03FAFA.spad )
+
+@
+<<d03routine.spad.dvi (DOC from IN)>>=
+${DOC}/d03routine.spad.dvi: ${IN}/d03routine.spad.pamphlet
+ @ echo 0 making ${DOC}/d03routine.spad.dvi from ${IN}/d03routine.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d03routine.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d03routine.spad ; \
+ rm -f ${DOC}/d03routine.spad.pamphlet ; \
+ rm -f ${DOC}/d03routine.spad.tex ; \
+ rm -f ${DOC}/d03routine.spad )
+
+@
+\subsection{d03.spad \cite{1}}
+<<d03.spad (SPAD from IN)>>=
+${MID}/d03.spad: ${IN}/d03.spad.pamphlet
+ @ echo 0 making ${MID}/d03.spad from ${IN}/d03.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/d03.spad.pamphlet >d03.spad )
+
+@
+<<NAGD03.o (O from NRLIB)>>=
+${OUT}/NAGD03.o: ${MID}/NAGD03.NRLIB
+ @ echo 0 making ${OUT}/NAGD03.o from ${MID}/NAGD03.NRLIB
+ @ cp ${MID}/NAGD03.NRLIB/code.o ${OUT}/NAGD03.o
+
+@
+<<NAGD03.NRLIB (NRLIB from MID)>>=
+${MID}/NAGD03.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/NAGD03.spad
+ @ echo 0 making ${MID}/NAGD03.NRLIB from ${MID}/NAGD03.spad
+ @ (cd ${MID} ; echo ')co NAGD03.spad' | ${INTERPSYS} )
+
+@
+<<NAGD03.spad (SPAD from IN)>>=
+${MID}/NAGD03.spad: ${IN}/d03.spad.pamphlet
+ @ echo 0 making ${MID}/NAGD03.spad from ${IN}/d03.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGD03.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGD03 NagPartialDifferentialEquationsPackage" ${IN}/d03.spad.pamphlet >NAGD03.spad )
+
+@
+<<d03.spad.dvi (DOC from IN)>>=
+${DOC}/d03.spad.dvi: ${IN}/d03.spad.pamphlet
+ @ echo 0 making ${DOC}/d03.spad.dvi from ${IN}/d03.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/d03.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} d03.spad ; \
+ rm -f ${DOC}/d03.spad.pamphlet ; \
+ rm -f ${DOC}/d03.spad.tex ; \
+ rm -f ${DOC}/d03.spad )
+
+@
+\subsection{ddfact.spad \cite{1}}
+<<ddfact.spad (SPAD from IN)>>=
+${MID}/ddfact.spad: ${IN}/ddfact.spad.pamphlet
+ @ echo 0 making ${MID}/ddfact.spad from ${IN}/ddfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ddfact.spad.pamphlet >ddfact.spad )
+
+@
+<<DDFACT.o (O from NRLIB)>>=
+${OUT}/DDFACT.o: ${MID}/DDFACT.NRLIB
+ @ echo 0 making ${OUT}/DDFACT.o from ${MID}/DDFACT.NRLIB
+ @ cp ${MID}/DDFACT.NRLIB/code.o ${OUT}/DDFACT.o
+
+@
+<<DDFACT.NRLIB (NRLIB from MID)>>=
+${MID}/DDFACT.NRLIB: ${MID}/DDFACT.spad
+ @ echo 0 making ${MID}/DDFACT.NRLIB from ${MID}/DDFACT.spad
+ @ (cd ${MID} ; echo ')co DDFACT.spad' | ${INTERPSYS} )
+
+@
+<<DDFACT.spad (SPAD from IN)>>=
+${MID}/DDFACT.spad: ${IN}/ddfact.spad.pamphlet
+ @ echo 0 making ${MID}/DDFACT.spad from ${IN}/ddfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DDFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DDFACT DistinctDegreeFactorize" ${IN}/ddfact.spad.pamphlet >DDFACT.spad )
+
+@
+<<ddfact.spad.dvi (DOC from IN)>>=
+${DOC}/ddfact.spad.dvi: ${IN}/ddfact.spad.pamphlet
+ @ echo 0 making ${DOC}/ddfact.spad.dvi from ${IN}/ddfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ddfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ddfact.spad ; \
+ rm -f ${DOC}/ddfact.spad.pamphlet ; \
+ rm -f ${DOC}/ddfact.spad.tex ; \
+ rm -f ${DOC}/ddfact.spad )
+
+@
+\subsection{defaults.spad \cite{1}}
+<<defaults.spad (SPAD from IN)>>=
+${MID}/defaults.spad: ${IN}/defaults.spad.pamphlet
+ @ echo 0 making ${MID}/defaults.spad from ${IN}/defaults.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/defaults.spad.pamphlet >defaults.spad )
+
+@
+<<FLASORT.o (O from NRLIB)>>=
+${OUT}/FLASORT.o: ${MID}/FLASORT.NRLIB
+ @ echo 0 making ${OUT}/FLASORT.o from ${MID}/FLASORT.NRLIB
+ @ cp ${MID}/FLASORT.NRLIB/code.o ${OUT}/FLASORT.o
+
+@
+<<FLASORT.NRLIB (NRLIB from MID)>>=
+${MID}/FLASORT.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/FLASORT.spad
+ @ echo 0 making ${MID}/FLASORT.NRLIB from ${MID}/FLASORT.spad
+ @ (cd ${MID} ; echo ')co FLASORT.spad' | ${INTERPSYS} )
+
+@
+<<FLASORT.spad (SPAD from IN)>>=
+${MID}/FLASORT.spad: ${IN}/defaults.spad.pamphlet
+ @ echo 0 making ${MID}/FLASORT.spad from ${IN}/defaults.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLASORT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FLASORT FiniteLinearAggregateSort" ${IN}/defaults.spad.pamphlet >FLASORT.spad )
+
+@
+<<REPDB.o (O from NRLIB)>>=
+${OUT}/REPDB.o: ${MID}/REPDB.NRLIB
+ @ echo 0 making ${OUT}/REPDB.o from ${MID}/REPDB.NRLIB
+ @ cp ${MID}/REPDB.NRLIB/code.o ${OUT}/REPDB.o
+
+@
+<<REPDB.NRLIB (NRLIB from MID)>>=
+${MID}/REPDB.NRLIB: ${MID}/REPDB.spad
+ @ echo 0 making ${MID}/REPDB.NRLIB from ${MID}/REPDB.spad
+ @ (cd ${MID} ; echo ')co REPDB.spad' | ${INTERPSYS} )
+
+@
+<<REPDB.spad (SPAD from IN)>>=
+${MID}/REPDB.spad: ${IN}/defaults.spad.pamphlet
+ @ echo 0 making ${MID}/REPDB.spad from ${IN}/defaults.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REPDB.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REPDB RepeatedDoubling" ${IN}/defaults.spad.pamphlet >REPDB.spad )
+
+@
+<<REPSQ.o (O from NRLIB)>>=
+${OUT}/REPSQ.o: ${MID}/REPSQ.NRLIB
+ @ echo 0 making ${OUT}/REPSQ.o from ${MID}/REPSQ.NRLIB
+ @ cp ${MID}/REPSQ.NRLIB/code.o ${OUT}/REPSQ.o
+
+@
+<<REPSQ.NRLIB (NRLIB from MID)>>=
+${MID}/REPSQ.NRLIB: ${MID}/REPSQ.spad
+ @ echo 0 making ${MID}/REPSQ.NRLIB from ${MID}/REPSQ.spad
+ @ (cd ${MID} ; echo ')co REPSQ.spad' | ${INTERPSYS} )
+
+@
+<<REPSQ.spad (SPAD from IN)>>=
+${MID}/REPSQ.spad: ${IN}/defaults.spad.pamphlet
+ @ echo 0 making ${MID}/REPSQ.spad from ${IN}/defaults.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REPSQ.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REPSQ RepeatedSquaring" ${IN}/defaults.spad.pamphlet >REPSQ.spad )
+
+@
+<<defaults.spad.dvi (DOC from IN)>>=
+${DOC}/defaults.spad.dvi: ${IN}/defaults.spad.pamphlet
+ @ echo 0 making ${DOC}/defaults.spad.dvi from ${IN}/defaults.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/defaults.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} defaults.spad ; \
+ rm -f ${DOC}/defaults.spad.pamphlet ; \
+ rm -f ${DOC}/defaults.spad.tex ; \
+ rm -f ${DOC}/defaults.spad )
+
+@
+\subsection{defintef.spad \cite{1}}
+<<defintef.spad (SPAD from IN)>>=
+${MID}/defintef.spad: ${IN}/defintef.spad.pamphlet
+ @ echo 0 making ${MID}/defintef.spad from ${IN}/defintef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/defintef.spad.pamphlet >defintef.spad )
+
+@
+<<DEFINTEF.o (O from NRLIB)>>=
+${OUT}/DEFINTEF.o: ${MID}/DEFINTEF.NRLIB
+ @ echo 0 making ${OUT}/DEFINTEF.o from ${MID}/DEFINTEF.NRLIB
+ @ cp ${MID}/DEFINTEF.NRLIB/code.o ${OUT}/DEFINTEF.o
+
+@
+<<DEFINTEF.NRLIB (NRLIB from MID)>>=
+${MID}/DEFINTEF.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DEFINTEF.spad
+ @ echo 0 making ${MID}/DEFINTEF.NRLIB from ${MID}/DEFINTEF.spad
+ @ (cd ${MID} ; echo ')co DEFINTEF.spad' | ${INTERPSYS} )
+
+@
+<<DEFINTEF.spad (SPAD from IN)>>=
+${MID}/DEFINTEF.spad: ${IN}/defintef.spad.pamphlet
+ @ echo 0 making ${MID}/DEFINTEF.spad from ${IN}/defintef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DEFINTEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DEFINTEF ElementaryFunctionDefiniteIntegration" ${IN}/defintef.spad.pamphlet >DEFINTEF.spad )
+
+@
+<<defintef.spad.dvi (DOC from IN)>>=
+${DOC}/defintef.spad.dvi: ${IN}/defintef.spad.pamphlet
+ @ echo 0 making ${DOC}/defintef.spad.dvi from ${IN}/defintef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/defintef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} defintef.spad ; \
+ rm -f ${DOC}/defintef.spad.pamphlet ; \
+ rm -f ${DOC}/defintef.spad.tex ; \
+ rm -f ${DOC}/defintef.spad )
+
+@
+\subsection{defintrf.spad \cite{1}}
+<<defintrf.spad (SPAD from IN)>>=
+${MID}/defintrf.spad: ${IN}/defintrf.spad.pamphlet
+ @ echo 0 making ${MID}/defintrf.spad from ${IN}/defintrf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/defintrf.spad.pamphlet >defintrf.spad )
+
+@
+<<DEFINTRF.o (O from NRLIB)>>=
+${OUT}/DEFINTRF.o: ${MID}/DEFINTRF.NRLIB
+ @ echo 0 making ${OUT}/DEFINTRF.o from ${MID}/DEFINTRF.NRLIB
+ @ cp ${MID}/DEFINTRF.NRLIB/code.o ${OUT}/DEFINTRF.o
+
+@
+<<DEFINTRF.NRLIB (NRLIB from MID)>>=
+${MID}/DEFINTRF.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DEFINTRF.spad
+ @ echo 0 making ${MID}/DEFINTRF.NRLIB from ${MID}/DEFINTRF.spad
+ @ (cd ${MID} ; echo ')co DEFINTRF.spad' | ${INTERPSYS} )
+
+@
+<<DEFINTRF.spad (SPAD from IN)>>=
+${MID}/DEFINTRF.spad: ${IN}/defintrf.spad.pamphlet
+ @ echo 0 making ${MID}/DEFINTRF.spad from ${IN}/defintrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DEFINTRF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DEFINTRF RationalFunctionDefiniteIntegration" ${IN}/defintrf.spad.pamphlet >DEFINTRF.spad )
+
+@
+<<DFINTTLS.o (O from NRLIB)>>=
+${OUT}/DFINTTLS.o: ${MID}/DFINTTLS.NRLIB
+ @ echo 0 making ${OUT}/DFINTTLS.o from ${MID}/DFINTTLS.NRLIB
+ @ cp ${MID}/DFINTTLS.NRLIB/code.o ${OUT}/DFINTTLS.o
+
+@
+<<DFINTTLS.NRLIB (NRLIB from MID)>>=
+${MID}/DFINTTLS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DFINTTLS.spad
+ @ echo 0 making ${MID}/DFINTTLS.NRLIB from ${MID}/DFINTTLS.spad
+ @ (cd ${MID} ; echo ')co DFINTTLS.spad' | ${INTERPSYS} )
+
+@
+<<DFINTTLS.spad (SPAD from IN)>>=
+${MID}/DFINTTLS.spad: ${IN}/defintrf.spad.pamphlet
+ @ echo 0 making ${MID}/DFINTTLS.spad from ${IN}/defintrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DFINTTLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DFINTTLS DefiniteIntegrationTools" ${IN}/defintrf.spad.pamphlet >DFINTTLS.spad )
+
+@
+<<defintrf.spad.dvi (DOC from IN)>>=
+${DOC}/defintrf.spad.dvi: ${IN}/defintrf.spad.pamphlet
+ @ echo 0 making ${DOC}/defintrf.spad.dvi from ${IN}/defintrf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/defintrf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} defintrf.spad ; \
+ rm -f ${DOC}/defintrf.spad.pamphlet ; \
+ rm -f ${DOC}/defintrf.spad.tex ; \
+ rm -f ${DOC}/defintrf.spad )
+
+@
+\subsection{degred.spad \cite{1}}
+<<degred.spad (SPAD from IN)>>=
+${MID}/degred.spad: ${IN}/degred.spad.pamphlet
+ @ echo 0 making ${MID}/degred.spad from ${IN}/degred.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/degred.spad.pamphlet >degred.spad )
+
+@
+<<DEGRED.o (O from NRLIB)>>=
+${OUT}/DEGRED.o: ${MID}/DEGRED.NRLIB
+ @ echo 0 making ${OUT}/DEGRED.o from ${MID}/DEGRED.NRLIB
+ @ cp ${MID}/DEGRED.NRLIB/code.o ${OUT}/DEGRED.o
+
+@
+<<DEGRED.NRLIB (NRLIB from MID)>>=
+${MID}/DEGRED.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DEGRED.spad
+ @ echo 0 making ${MID}/DEGRED.NRLIB from ${MID}/DEGRED.spad
+ @ (cd ${MID} ; echo ')co DEGRED.spad' | ${INTERPSYS} )
+
+@
+<<DEGRED.spad (SPAD from IN)>>=
+${MID}/DEGRED.spad: ${IN}/degred.spad.pamphlet
+ @ echo 0 making ${MID}/DEGRED.spad from ${IN}/degred.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DEGRED.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DEGRED DegreeReductionPackage" ${IN}/degred.spad.pamphlet >DEGRED.spad )
+
+@
+<<degred.spad.dvi (DOC from IN)>>=
+${DOC}/degred.spad.dvi: ${IN}/degred.spad.pamphlet
+ @ echo 0 making ${DOC}/degred.spad.dvi from ${IN}/degred.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/degred.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} degred.spad ; \
+ rm -f ${DOC}/degred.spad.pamphlet ; \
+ rm -f ${DOC}/degred.spad.tex ; \
+ rm -f ${DOC}/degred.spad )
+
+@
+\subsection{derham.spad \cite{1}}
+<<derham.spad (SPAD from IN)>>=
+${MID}/derham.spad: ${IN}/derham.spad.pamphlet
+ @ echo 0 making ${MID}/derham.spad from ${IN}/derham.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/derham.spad.pamphlet >derham.spad )
+
+@
+<<ANTISYM.o (O from NRLIB)>>=
+${OUT}/ANTISYM.o: ${MID}/ANTISYM.NRLIB
+ @ echo 0 making ${OUT}/ANTISYM.o from ${MID}/ANTISYM.NRLIB
+ @ cp ${MID}/ANTISYM.NRLIB/code.o ${OUT}/ANTISYM.o
+
+@
+<<ANTISYM.NRLIB (NRLIB from MID)>>=
+${MID}/ANTISYM.NRLIB: ${MID}/ANTISYM.spad
+ @ echo 0 making ${MID}/ANTISYM.NRLIB from ${MID}/ANTISYM.spad
+ @ (cd ${MID} ; echo ')co ANTISYM.spad' | ${INTERPSYS} )
+
+@
+<<ANTISYM.spad (SPAD from IN)>>=
+${MID}/ANTISYM.spad: ${IN}/derham.spad.pamphlet
+ @ echo 0 making ${MID}/ANTISYM.spad from ${IN}/derham.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ANTISYM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ANTISYM AntiSymm" ${IN}/derham.spad.pamphlet >ANTISYM.spad )
+
+@
+<<DERHAM.o (O from NRLIB)>>=
+${OUT}/DERHAM.o: ${MID}/DERHAM.NRLIB
+ @ echo 0 making ${OUT}/DERHAM.o from ${MID}/DERHAM.NRLIB
+ @ cp ${MID}/DERHAM.NRLIB/code.o ${OUT}/DERHAM.o
+
+@
+<<DERHAM.NRLIB (NRLIB from MID)>>=
+${MID}/DERHAM.NRLIB: ${MID}/DERHAM.spad
+ @ echo 0 making ${MID}/DERHAM.NRLIB from ${MID}/DERHAM.spad
+ @ (cd ${MID} ; echo ')co DERHAM.spad' | ${INTERPSYS} )
+
+@
+<<DERHAM.spad (SPAD from IN)>>=
+${MID}/DERHAM.spad: ${IN}/derham.spad.pamphlet
+ @ echo 0 making ${MID}/DERHAM.spad from ${IN}/derham.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DERHAM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DERHAM DeRhamComplex" ${IN}/derham.spad.pamphlet >DERHAM.spad )
+
+@
+<<EAB.o (O from NRLIB)>>=
+${OUT}/EAB.o: ${MID}/EAB.NRLIB
+ @ echo 0 making ${OUT}/EAB.o from ${MID}/EAB.NRLIB
+ @ cp ${MID}/EAB.NRLIB/code.o ${OUT}/EAB.o
+
+@
+<<EAB.NRLIB (NRLIB from MID)>>=
+${MID}/EAB.NRLIB: ${MID}/EAB.spad
+ @ echo 0 making ${MID}/EAB.NRLIB from ${MID}/EAB.spad
+ @ (cd ${MID} ; echo ')co EAB.spad' | ${INTERPSYS} )
+
+@
+<<EAB.spad (SPAD from IN)>>=
+${MID}/EAB.spad: ${IN}/derham.spad.pamphlet
+ @ echo 0 making ${MID}/EAB.spad from ${IN}/derham.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EAB ExtAlgBasis" ${IN}/derham.spad.pamphlet >EAB.spad )
+
+@
+<<LALG-.o (O from NRLIB)>>=
+${OUT}/LALG-.o: ${MID}/LALG.NRLIB
+ @ echo 0 making ${OUT}/LALG-.o from ${MID}/LALG-.NRLIB
+ @ cp ${MID}/LALG-.NRLIB/code.o ${OUT}/LALG-.o
+
+@
+<<LALG-.NRLIB (NRLIB from MID)>>=
+${MID}/LALG-.NRLIB: ${OUT}/TYPE.o ${MID}/LALG.spad
+ @ echo 0 making ${MID}/LALG-.NRLIB from ${MID}/LALG.spad
+ @ (cd ${MID} ; echo ')co LALG.spad' | ${INTERPSYS} )
+
+@
+<<LALG.o (O from NRLIB)>>=
+${OUT}/LALG.o: ${MID}/LALG.NRLIB
+ @ echo 0 making ${OUT}/LALG.o from ${MID}/LALG.NRLIB
+ @ cp ${MID}/LALG.NRLIB/code.o ${OUT}/LALG.o
+
+@
+<<LALG.NRLIB (NRLIB from MID)>>=
+${MID}/LALG.NRLIB: ${MID}/LALG.spad
+ @ echo 0 making ${MID}/LALG.NRLIB from ${MID}/LALG.spad
+ @ (cd ${MID} ; echo ')co LALG.spad' | ${INTERPSYS} )
+
+@
+<<LALG.spad (SPAD from IN)>>=
+${MID}/LALG.spad: ${IN}/derham.spad.pamphlet
+ @ echo 0 making ${MID}/LALG.spad from ${IN}/derham.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LALG LeftAlgebra" ${IN}/derham.spad.pamphlet >LALG.spad )
+
+@
+<<derham.spad.dvi (DOC from IN)>>=
+${DOC}/derham.spad.dvi: ${IN}/derham.spad.pamphlet
+ @ echo 0 making ${DOC}/derham.spad.dvi from ${IN}/derham.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/derham.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} derham.spad ; \
+ rm -f ${DOC}/derham.spad.pamphlet ; \
+ rm -f ${DOC}/derham.spad.tex ; \
+ rm -f ${DOC}/derham.spad )
+
+@
+\subsection{dhmatrix.spad \cite{1}}
+<<dhmatrix.spad (SPAD from IN)>>=
+${MID}/dhmatrix.spad: ${IN}/dhmatrix.spad.pamphlet
+ @ echo 0 making ${MID}/dhmatrix.spad from ${IN}/dhmatrix.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/dhmatrix.spad.pamphlet >dhmatrix.spad )
+
+@
+<<DHMATRIX.o (O from NRLIB)>>=
+${OUT}/DHMATRIX.o: ${MID}/DHMATRIX.NRLIB
+ @ echo 0 making ${OUT}/DHMATRIX.o from ${MID}/DHMATRIX.NRLIB
+ @ cp ${MID}/DHMATRIX.NRLIB/code.o ${OUT}/DHMATRIX.o
+
+@
+<<DHMATRIX.NRLIB (NRLIB from MID)>>=
+${MID}/DHMATRIX.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DHMATRIX.spad
+ @ echo 0 making ${MID}/DHMATRIX.NRLIB from ${MID}/DHMATRIX.spad
+ @ (cd ${MID} ; echo ')co DHMATRIX.spad' | ${INTERPSYS} )
+
+@
+<<DHMATRIX.spad (SPAD from IN)>>=
+${MID}/DHMATRIX.spad: ${IN}/dhmatrix.spad.pamphlet
+ @ echo 0 making ${MID}/DHMATRIX.spad from ${IN}/dhmatrix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DHMATRIX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DHMATRIX DenavitHartenbergMatrix" ${IN}/dhmatrix.spad.pamphlet >DHMATRIX.spad )
+
+@
+<<dhmatrix.spad.dvi (DOC from IN)>>=
+${DOC}/dhmatrix.spad.dvi: ${IN}/dhmatrix.spad.pamphlet
+ @ echo 0 making ${DOC}/dhmatrix.spad.dvi from ${IN}/dhmatrix.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/dhmatrix.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} dhmatrix.spad ; \
+ rm -f ${DOC}/dhmatrix.spad.pamphlet ; \
+ rm -f ${DOC}/dhmatrix.spad.tex ; \
+ rm -f ${DOC}/dhmatrix.spad )
+
+@
+\subsection{divisor.spad \cite{1}}
+<<divisor.spad (SPAD from IN)>>=
+${MID}/divisor.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/divisor.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/divisor.spad.pamphlet >divisor.spad )
+
+@
+<<FDIV2.o (O from NRLIB)>>=
+${OUT}/FDIV2.o: ${MID}/FDIV2.NRLIB
+ @ echo 0 making ${OUT}/FDIV2.o from ${MID}/FDIV2.NRLIB
+ @ cp ${MID}/FDIV2.NRLIB/code.o ${OUT}/FDIV2.o
+
+@
+<<FDIV2.NRLIB (NRLIB from MID)>>=
+${MID}/FDIV2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FDIV2.spad
+ @ echo 0 making ${MID}/FDIV2.NRLIB from ${MID}/FDIV2.spad
+ @ (cd ${MID} ; echo ')co FDIV2.spad' | ${INTERPSYS} )
+
+@
+<<FDIV2.spad (SPAD from IN)>>=
+${MID}/FDIV2.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/FDIV2.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FDIV2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FDIV2 FiniteDivisorFunctions2" ${IN}/divisor.spad.pamphlet >FDIV2.spad )
+
+@
+<<FDIV.o (O from NRLIB)>>=
+${OUT}/FDIV.o: ${MID}/FDIV.NRLIB
+ @ echo 0 making ${OUT}/FDIV.o from ${MID}/FDIV.NRLIB
+ @ cp ${MID}/FDIV.NRLIB/code.o ${OUT}/FDIV.o
+
+@
+<<FDIV.NRLIB (NRLIB from MID)>>=
+${MID}/FDIV.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FDIV.spad
+ @ echo 0 making ${MID}/FDIV.NRLIB from ${MID}/FDIV.spad
+ @ (cd ${MID} ; echo ')co FDIV.spad' | ${INTERPSYS} )
+
+@
+<<FDIV.spad (SPAD from IN)>>=
+${MID}/FDIV.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/FDIV.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FDIV.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FDIV FiniteDivisor" ${IN}/divisor.spad.pamphlet >FDIV.spad )
+
+@
+<<FDIVCAT-.o (O from NRLIB)>>=
+${OUT}/FDIVCAT-.o: ${MID}/FDIVCAT.NRLIB
+ @ echo 0 making ${OUT}/FDIVCAT-.o from ${MID}/FDIVCAT-.NRLIB
+ @ cp ${MID}/FDIVCAT-.NRLIB/code.o ${OUT}/FDIVCAT-.o
+
+@
+<<FDIVCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/FDIVCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/FDIVCAT.spad
+ @ echo 0 making ${MID}/FDIVCAT-.NRLIB from ${MID}/FDIVCAT.spad
+ @ (cd ${MID} ; echo ')co FDIVCAT.spad' | ${INTERPSYS} )
+
+@
+<<FDIVCAT.o (O from NRLIB)>>=
+${OUT}/FDIVCAT.o: ${MID}/FDIVCAT.NRLIB
+ @ echo 0 making ${OUT}/FDIVCAT.o from ${MID}/FDIVCAT.NRLIB
+ @ cp ${MID}/FDIVCAT.NRLIB/code.o ${OUT}/FDIVCAT.o
+
+@
+<<FDIVCAT.NRLIB (NRLIB from MID)>>=
+${MID}/FDIVCAT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FDIVCAT.spad
+ @ echo 0 making ${MID}/FDIVCAT.NRLIB from ${MID}/FDIVCAT.spad
+ @ (cd ${MID} ; echo ')co FDIVCAT.spad' | ${INTERPSYS} )
+
+@
+<<FDIVCAT.spad (SPAD from IN)>>=
+${MID}/FDIVCAT.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/FDIVCAT.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FDIVCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FDIVCAT FiniteDivisorCategory" ${IN}/divisor.spad.pamphlet >FDIVCAT.spad )
+
+@
+<<FRIDEAL.o (O from NRLIB)>>=
+${OUT}/FRIDEAL.o: ${MID}/FRIDEAL.NRLIB
+ @ echo 0 making ${OUT}/FRIDEAL.o from ${MID}/FRIDEAL.NRLIB
+ @ cp ${MID}/FRIDEAL.NRLIB/code.o ${OUT}/FRIDEAL.o
+
+@
+<<FRIDEAL.NRLIB (NRLIB from MID)>>=
+${MID}/FRIDEAL.NRLIB: ${MID}/FRIDEAL.spad
+ @ echo 0 making ${MID}/FRIDEAL.NRLIB from ${MID}/FRIDEAL.spad
+ @ (cd ${MID} ; echo ')co FRIDEAL.spad' | ${INTERPSYS} )
+
+@
+<<FRIDEAL.spad (SPAD from IN)>>=
+${MID}/FRIDEAL.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/FRIDEAL.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRIDEAL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FRIDEAL FractionalIdeal" ${IN}/divisor.spad.pamphlet >FRIDEAL.spad )
+
+@
+<<FRIDEAL2.o (O from NRLIB)>>=
+${OUT}/FRIDEAL2.o: ${MID}/FRIDEAL2.NRLIB
+ @ echo 0 making ${OUT}/FRIDEAL2.o from ${MID}/FRIDEAL2.NRLIB
+ @ cp ${MID}/FRIDEAL2.NRLIB/code.o ${OUT}/FRIDEAL2.o
+
+@
+<<FRIDEAL2.NRLIB (NRLIB from MID)>>=
+${MID}/FRIDEAL2.NRLIB: ${MID}/FRIDEAL2.spad
+ @ echo 0 making ${MID}/FRIDEAL2.NRLIB from ${MID}/FRIDEAL2.spad
+ @ (cd ${MID} ; echo ')co FRIDEAL2.spad' | ${INTERPSYS} )
+
+@
+<<FRIDEAL2.spad (SPAD from IN)>>=
+${MID}/FRIDEAL2.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/FRIDEAL2.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRIDEAL2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FRIDEAL2 FractionalIdealFunctions2" ${IN}/divisor.spad.pamphlet >FRIDEAL2.spad )
+
+@
+<<FRMOD.o (O from NRLIB)>>=
+${OUT}/FRMOD.o: ${MID}/FRMOD.NRLIB
+ @ echo 0 making ${OUT}/FRMOD.o from ${MID}/FRMOD.NRLIB
+ @ cp ${MID}/FRMOD.NRLIB/code.o ${OUT}/FRMOD.o
+
+@
+<<FRMOD.NRLIB (NRLIB from MID)>>=
+${MID}/FRMOD.NRLIB: ${MID}/FRMOD.spad
+ @ echo 0 making ${MID}/FRMOD.NRLIB from ${MID}/FRMOD.spad
+ @ (cd ${MID} ; echo ')co FRMOD.spad' | ${INTERPSYS} )
+
+@
+<<FRMOD.spad (SPAD from IN)>>=
+${MID}/FRMOD.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/FRMOD.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRMOD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FRMOD FramedModule" ${IN}/divisor.spad.pamphlet >FRMOD.spad )
+
+@
+<<HELLFDIV.o (O from NRLIB)>>=
+${OUT}/HELLFDIV.o: ${MID}/HELLFDIV.NRLIB
+ @ echo 0 making ${OUT}/HELLFDIV.o from ${MID}/HELLFDIV.NRLIB
+ @ cp ${MID}/HELLFDIV.NRLIB/code.o ${OUT}/HELLFDIV.o
+
+@
+<<HELLFDIV.NRLIB (NRLIB from MID)>>=
+${MID}/HELLFDIV.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/HELLFDIV.spad
+ @ echo 0 making ${MID}/HELLFDIV.NRLIB from ${MID}/HELLFDIV.spad
+ @ (cd ${MID} ; echo ')co HELLFDIV.spad' | ${INTERPSYS} )
+
+@
+<<HELLFDIV.spad (SPAD from IN)>>=
+${MID}/HELLFDIV.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/HELLFDIV.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HELLFDIV.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HELLFDIV HyperellipticFiniteDivisor" ${IN}/divisor.spad.pamphlet >HELLFDIV.spad )
+
+@
+<<MHROWRED.o (O from NRLIB)>>=
+${OUT}/MHROWRED.o: ${MID}/MHROWRED.NRLIB
+ @ echo 0 making ${OUT}/MHROWRED.o from ${MID}/MHROWRED.NRLIB
+ @ cp ${MID}/MHROWRED.NRLIB/code.o ${OUT}/MHROWRED.o
+
+@
+<<MHROWRED.NRLIB (NRLIB from MID)>>=
+${MID}/MHROWRED.NRLIB: ${MID}/MHROWRED.spad
+ @ echo 0 making ${MID}/MHROWRED.NRLIB from ${MID}/MHROWRED.spad
+ @ (cd ${MID} ; echo ')co MHROWRED.spad' | ${INTERPSYS} )
+
+@
+<<MHROWRED.spad (SPAD from IN)>>=
+${MID}/MHROWRED.spad: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${MID}/MHROWRED.spad from ${IN}/divisor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MHROWRED.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MHROWRED ModularHermitianRowReduction" ${IN}/divisor.spad.pamphlet >MHROWRED.spad )
+
+@
+<<divisor.spad.dvi (DOC from IN)>>=
+${DOC}/divisor.spad.dvi: ${IN}/divisor.spad.pamphlet
+ @ echo 0 making ${DOC}/divisor.spad.dvi from ${IN}/divisor.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/divisor.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} divisor.spad ; \
+ rm -f ${DOC}/divisor.spad.pamphlet ; \
+ rm -f ${DOC}/divisor.spad.tex ; \
+ rm -f ${DOC}/divisor.spad )
+
+@
+\subsection{dpolcat.spad \cite{1}}
+<<dpolcat.spad (SPAD from IN)>>=
+${MID}/dpolcat.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/dpolcat.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/dpolcat.spad.pamphlet >dpolcat.spad )
+
+@
+<<SDPOL.o (O from NRLIB)>>=
+${OUT}/SDPOL.o: ${MID}/SDPOL.NRLIB
+ @ echo 0 making ${OUT}/SDPOL.o from ${MID}/SDPOL.NRLIB
+ @ cp ${MID}/SDPOL.NRLIB/code.o ${OUT}/SDPOL.o
+
+@
+<<SDPOL.NRLIB (NRLIB from MID)>>=
+${MID}/SDPOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SDPOL.spad
+ @ echo 0 making ${MID}/SDPOL.NRLIB from ${MID}/SDPOL.spad
+ @ (cd ${MID} ; echo ')co SDPOL.spad' | ${INTERPSYS} )
+
+@
+<<SDPOL.spad (SPAD from IN)>>=
+${MID}/SDPOL.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/SDPOL.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SDPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SDPOL SequentialDifferentialPolynomial" ${IN}/dpolcat.spad.pamphlet >SDPOL.spad )
+
+@
+<<DSMP.o (O from NRLIB)>>=
+${OUT}/DSMP.o: ${MID}/DSMP.NRLIB
+ @ echo 0 making ${OUT}/DSMP.o from ${MID}/DSMP.NRLIB
+ @ cp ${MID}/DSMP.NRLIB/code.o ${OUT}/DSMP.o
+
+@
+<<DSMP.NRLIB (NRLIB from MID)>>=
+${MID}/DSMP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DSMP.spad
+ @ echo 0 making ${MID}/DSMP.NRLIB from ${MID}/DSMP.spad
+ @ (cd ${MID} ; echo ')co DSMP.spad' | ${INTERPSYS} )
+
+@
+<<DSMP.spad (SPAD from IN)>>=
+${MID}/DSMP.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/DSMP.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DSMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DSMP DifferentialSparseMultivariatePolynomial" ${IN}/dpolcat.spad.pamphlet >DSMP.spad )
+
+@
+<<DPOLCAT-.o (O from NRLIB)>>=
+${OUT}/DPOLCAT-.o: ${MID}/DPOLCAT.NRLIB
+ @ echo 0 making ${OUT}/DPOLCAT-.o from ${MID}/DPOLCAT-.NRLIB
+ @ cp ${MID}/DPOLCAT-.NRLIB/code.o ${OUT}/DPOLCAT-.o
+
+@
+<<DPOLCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/DPOLCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/DPOLCAT.spad
+ @ echo 0 making ${MID}/DPOLCAT-.NRLIB from ${MID}/DPOLCAT.spad
+ @ (cd ${MID} ; echo ')co DPOLCAT.spad' | ${INTERPSYS} )
+
+@
+<<DPOLCAT.o (O from NRLIB)>>=
+${OUT}/DPOLCAT.o: ${MID}/DPOLCAT.NRLIB
+ @ echo 0 making ${OUT}/DPOLCAT.o from ${MID}/DPOLCAT.NRLIB
+ @ cp ${MID}/DPOLCAT.NRLIB/code.o ${OUT}/DPOLCAT.o
+
+@
+<<DPOLCAT.NRLIB (NRLIB from MID)>>=
+${MID}/DPOLCAT.NRLIB: ${MID}/DPOLCAT.spad
+ @ echo 0 making ${MID}/DPOLCAT.NRLIB from ${MID}/DPOLCAT.spad
+ @ (cd ${MID} ; echo ')co DPOLCAT.spad' | ${INTERPSYS} )
+
+@
+<<DPOLCAT.spad (SPAD from IN)>>=
+${MID}/DPOLCAT.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/DPOLCAT.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DPOLCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DPOLCAT DifferentialPolynomialCategory" ${IN}/dpolcat.spad.pamphlet >DPOLCAT.spad )
+
+@
+<<DVARCAT-.o (O from NRLIB)>>=
+${OUT}/DVARCAT-.o: ${MID}/DVARCAT.NRLIB
+ @ echo 0 making ${OUT}/DVARCAT-.o from ${MID}/DVARCAT-.NRLIB
+ @ cp ${MID}/DVARCAT-.NRLIB/code.o ${OUT}/DVARCAT-.o
+
+@
+<<DVARCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/DVARCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/DVARCAT.spad
+ @ echo 0 making ${MID}/DVARCAT-.NRLIB from ${MID}/DVARCAT.spad
+ @ (cd ${MID} ; echo ')co DVARCAT.spad' | ${INTERPSYS} )
+
+@
+<<DVARCAT.o (O from NRLIB)>>=
+${OUT}/DVARCAT.o: ${MID}/DVARCAT.NRLIB
+ @ echo 0 making ${OUT}/DVARCAT.o from ${MID}/DVARCAT.NRLIB
+ @ cp ${MID}/DVARCAT.NRLIB/code.o ${OUT}/DVARCAT.o
+
+@
+<<DVARCAT.NRLIB (NRLIB from MID)>>=
+${MID}/DVARCAT.NRLIB: ${MID}/DVARCAT.spad
+ @ echo 0 making ${MID}/DVARCAT.NRLIB from ${MID}/DVARCAT.spad
+ @ (cd ${MID} ; echo ')co DVARCAT.spad' | ${INTERPSYS} )
+
+@
+<<DVARCAT.spad (SPAD from IN)>>=
+${MID}/DVARCAT.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/DVARCAT.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DVARCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DVARCAT DifferentialVariableCategory" ${IN}/dpolcat.spad.pamphlet >DVARCAT.spad )
+
+@
+<<ODPOL.o (O from NRLIB)>>=
+${OUT}/ODPOL.o: ${MID}/ODPOL.NRLIB
+ @ echo 0 making ${OUT}/ODPOL.o from ${MID}/ODPOL.NRLIB
+ @ cp ${MID}/ODPOL.NRLIB/code.o ${OUT}/ODPOL.o
+
+@
+<<ODPOL.NRLIB (NRLIB from MID)>>=
+${MID}/ODPOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ODPOL.spad
+ @ echo 0 making ${MID}/ODPOL.NRLIB from ${MID}/ODPOL.spad
+ @ (cd ${MID} ; echo ')co ODPOL.spad' | ${INTERPSYS} )
+
+@
+<<ODPOL.spad (SPAD from IN)>>=
+${MID}/ODPOL.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/ODPOL.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ODPOL OrderlyDifferentialPolynomial" ${IN}/dpolcat.spad.pamphlet >ODPOL.spad )
+
+@
+<<ODVAR.o (O from NRLIB)>>=
+${OUT}/ODVAR.o: ${MID}/ODVAR.NRLIB
+ @ echo 0 making ${OUT}/ODVAR.o from ${MID}/ODVAR.NRLIB
+ @ cp ${MID}/ODVAR.NRLIB/code.o ${OUT}/ODVAR.o
+
+@
+<<ODVAR.NRLIB (NRLIB from MID)>>=
+${MID}/ODVAR.NRLIB: ${MID}/ODVAR.spad
+ @ echo 0 making ${MID}/ODVAR.NRLIB from ${MID}/ODVAR.spad
+ @ (cd ${MID} ; echo ')co ODVAR.spad' | ${INTERPSYS} )
+
+@
+<<ODVAR.spad (SPAD from IN)>>=
+${MID}/ODVAR.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/ODVAR.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODVAR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ODVAR OrderlyDifferentialVariable" ${IN}/dpolcat.spad.pamphlet >ODVAR.spad )
+
+@
+<<SDVAR.o (O from NRLIB)>>=
+${OUT}/SDVAR.o: ${MID}/SDVAR.NRLIB
+ @ echo 0 making ${OUT}/SDVAR.o from ${MID}/SDVAR.NRLIB
+ @ cp ${MID}/SDVAR.NRLIB/code.o ${OUT}/SDVAR.o
+
+@
+<<SDVAR.NRLIB (NRLIB from MID)>>=
+${MID}/SDVAR.NRLIB: ${MID}/SDVAR.spad
+ @ echo 0 making ${MID}/SDVAR.NRLIB from ${MID}/SDVAR.spad
+ @ (cd ${MID} ; echo ')co SDVAR.spad' | ${INTERPSYS} )
+
+@
+<<SDVAR.spad (SPAD from IN)>>=
+${MID}/SDVAR.spad: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${MID}/SDVAR.spad from ${IN}/dpolcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SDVAR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SDVAR SequentialDifferentialVariable" ${IN}/dpolcat.spad.pamphlet >SDVAR.spad )
+
+@
+<<dpolcat.spad.dvi (DOC from IN)>>=
+${DOC}/dpolcat.spad.dvi: ${IN}/dpolcat.spad.pamphlet
+ @ echo 0 making ${DOC}/dpolcat.spad.dvi from ${IN}/dpolcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/dpolcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} dpolcat.spad ; \
+ rm -f ${DOC}/dpolcat.spad.pamphlet ; \
+ rm -f ${DOC}/dpolcat.spad.tex ; \
+ rm -f ${DOC}/dpolcat.spad )
+
+@
+\subsection{drawopt.spad \cite{1}}
+<<drawopt.spad (SPAD from IN)>>=
+${MID}/drawopt.spad: ${IN}/drawopt.spad.pamphlet
+ @ echo 0 making ${MID}/drawopt.spad from ${IN}/drawopt.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/drawopt.spad.pamphlet >drawopt.spad )
+
+@
+<<DROPT.o (O from NRLIB)>>=
+${OUT}/DROPT.o: ${MID}/DROPT.NRLIB
+ @ echo 0 making ${OUT}/DROPT.o from ${MID}/DROPT.NRLIB
+ @ cp ${MID}/DROPT.NRLIB/code.o ${OUT}/DROPT.o
+
+@
+<<DROPT.NRLIB (NRLIB from MID)>>=
+${MID}/DROPT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DROPT.spad
+ @ echo 0 making ${MID}/DROPT.NRLIB from ${MID}/DROPT.spad
+ @ (cd ${MID} ; echo ')co DROPT.spad' | ${INTERPSYS} )
+
+@
+<<DROPT.spad (SPAD from IN)>>=
+${MID}/DROPT.spad: ${IN}/drawopt.spad.pamphlet
+ @ echo 0 making ${MID}/DROPT.spad from ${IN}/drawopt.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DROPT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DROPT DrawOption" ${IN}/drawopt.spad.pamphlet >DROPT.spad )
+
+@
+<<DROPT0.o (O from NRLIB)>>=
+${OUT}/DROPT0.o: ${MID}/DROPT0.NRLIB
+ @ echo 0 making ${OUT}/DROPT0.o from ${MID}/DROPT0.NRLIB
+ @ cp ${MID}/DROPT0.NRLIB/code.o ${OUT}/DROPT0.o
+
+@
+<<DROPT0.NRLIB (NRLIB from MID)>>=
+${MID}/DROPT0.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DROPT0.spad
+ @ echo 0 making ${MID}/DROPT0.NRLIB from ${MID}/DROPT0.spad
+ @ (cd ${MID} ; echo ')co DROPT0.spad' | ${INTERPSYS} )
+
+@
+<<DROPT0.spad (SPAD from IN)>>=
+${MID}/DROPT0.spad: ${IN}/drawopt.spad.pamphlet
+ @ echo 0 making ${MID}/DROPT0.spad from ${IN}/drawopt.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DROPT0.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DROPT0 DrawOptionFunctions0" ${IN}/drawopt.spad.pamphlet >DROPT0.spad )
+
+@
+<<DROPT1.o (O from NRLIB)>>=
+${OUT}/DROPT1.o: ${MID}/DROPT1.NRLIB
+ @ echo 0 making ${OUT}/DROPT1.o from ${MID}/DROPT1.NRLIB
+ @ cp ${MID}/DROPT1.NRLIB/code.o ${OUT}/DROPT1.o
+
+@
+<<DROPT1.NRLIB (NRLIB from MID)>>=
+${MID}/DROPT1.NRLIB: ${OUT}/TYPE.o ${MID}/DROPT1.spad
+ @ echo 0 making ${MID}/DROPT1.NRLIB from ${MID}/DROPT1.spad
+ @ (cd ${MID} ; echo ')co DROPT1.spad' | ${INTERPSYS} )
+
+@
+<<DROPT1.spad (SPAD from IN)>>=
+${MID}/DROPT1.spad: ${IN}/drawopt.spad.pamphlet
+ @ echo 0 making ${MID}/DROPT1.spad from ${IN}/drawopt.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DROPT1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DROPT1 DrawOptionFunctions1" ${IN}/drawopt.spad.pamphlet >DROPT1.spad )
+
+@
+<<drawopt.spad.dvi (DOC from IN)>>=
+${DOC}/drawopt.spad.dvi: ${IN}/drawopt.spad.pamphlet
+ @ echo 0 making ${DOC}/drawopt.spad.dvi from ${IN}/drawopt.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/drawopt.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} drawopt.spad ; \
+ rm -f ${DOC}/drawopt.spad.pamphlet ; \
+ rm -f ${DOC}/drawopt.spad.tex ; \
+ rm -f ${DOC}/drawopt.spad )
+
+@
+\subsection{drawpak.spad \cite{1}}
+<<drawpak.spad (SPAD from IN)>>=
+${MID}/drawpak.spad: ${IN}/drawpak.spad.pamphlet
+ @ echo 0 making ${MID}/drawpak.spad from ${IN}/drawpak.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/drawpak.spad.pamphlet >drawpak.spad )
+
+@
+<<DRAWCX.o (O from NRLIB)>>=
+${OUT}/DRAWCX.o: ${MID}/DRAWCX.NRLIB
+ @ echo 0 making ${OUT}/DRAWCX.o from ${MID}/DRAWCX.NRLIB
+ @ cp ${MID}/DRAWCX.NRLIB/code.o ${OUT}/DRAWCX.o
+
+@
+<<DRAWCX.NRLIB (NRLIB from MID)>>=
+${MID}/DRAWCX.NRLIB: ${MID}/DRAWCX.spad
+ @ echo 0 making ${MID}/DRAWCX.NRLIB from ${MID}/DRAWCX.spad
+ @ (cd ${MID} ; echo ')co DRAWCX.spad' | ${INTERPSYS} )
+
+@
+<<DRAWCX.spad (SPAD from IN)>>=
+${MID}/DRAWCX.spad: ${IN}/drawpak.spad.pamphlet
+ @ echo 0 making ${MID}/DRAWCX.spad from ${IN}/drawpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DRAWCX.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DRAWCX DrawComplex" ${IN}/drawpak.spad.pamphlet >DRAWCX.spad )
+
+@
+<<drawpak.spad.dvi (DOC from IN)>>=
+${DOC}/drawpak.spad.dvi: ${IN}/drawpak.spad.pamphlet
+ @ echo 0 making ${DOC}/drawpak.spad.dvi from ${IN}/drawpak.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/drawpak.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} drawpak.spad ; \
+ rm -f ${DOC}/drawpak.spad.pamphlet ; \
+ rm -f ${DOC}/drawpak.spad.tex ; \
+ rm -f ${DOC}/drawpak.spad )
+
+@
+\subsection{draw.spad \cite{1}}
+<<draw.spad (SPAD from IN)>>=
+${MID}/draw.spad: ${IN}/draw.spad.pamphlet
+ @ echo 0 making ${MID}/draw.spad from ${IN}/draw.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/draw.spad.pamphlet >draw.spad )
+
+@
+<<DRAW.o (O from NRLIB)>>=
+${OUT}/DRAW.o: ${MID}/DRAW.NRLIB
+ @ echo 0 making ${OUT}/DRAW.o from ${MID}/DRAW.NRLIB
+ @ cp ${MID}/DRAW.NRLIB/code.o ${OUT}/DRAW.o
+
+@
+<<DRAW.NRLIB (NRLIB from MID)>>=
+${MID}/DRAW.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DRAW.spad
+ @ echo 0 making ${MID}/DRAW.NRLIB from ${MID}/DRAW.spad
+ @ (cd ${MID} ; echo ')co DRAW.spad' | ${INTERPSYS} )
+
+@
+<<DRAW.spad (SPAD from IN)>>=
+${MID}/DRAW.spad: ${IN}/draw.spad.pamphlet
+ @ echo 0 making ${MID}/DRAW.spad from ${IN}/draw.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DRAW.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DRAW TopLevelDrawFunctions" ${IN}/draw.spad.pamphlet >DRAW.spad )
+
+@
+<<DRAWCFUN.o (O from NRLIB)>>=
+${OUT}/DRAWCFUN.o: ${MID}/DRAWCFUN.NRLIB
+ @ echo 0 making ${OUT}/DRAWCFUN.o from ${MID}/DRAWCFUN.NRLIB
+ @ cp ${MID}/DRAWCFUN.NRLIB/code.o ${OUT}/DRAWCFUN.o
+
+@
+<<DRAWCFUN.NRLIB (NRLIB from MID)>>=
+${MID}/DRAWCFUN.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DRAWCFUN.spad
+ @ echo 0 making ${MID}/DRAWCFUN.NRLIB from ${MID}/DRAWCFUN.spad
+ @ (cd ${MID} ; echo ')co DRAWCFUN.spad' | ${INTERPSYS} )
+
+@
+<<DRAWCFUN.spad (SPAD from IN)>>=
+${MID}/DRAWCFUN.spad: ${IN}/draw.spad.pamphlet
+ @ echo 0 making ${MID}/DRAWCFUN.spad from ${IN}/draw.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DRAWCFUN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions" ${IN}/draw.spad.pamphlet >DRAWCFUN.spad )
+
+@
+<<DRAWCURV.o (O from NRLIB)>>=
+${OUT}/DRAWCURV.o: ${MID}/DRAWCURV.NRLIB
+ @ echo 0 making ${OUT}/DRAWCURV.o from ${MID}/DRAWCURV.NRLIB
+ @ cp ${MID}/DRAWCURV.NRLIB/code.o ${OUT}/DRAWCURV.o
+
+@
+<<DRAWCURV.NRLIB (NRLIB from MID)>>=
+${MID}/DRAWCURV.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DRAWCURV.spad
+ @ echo 0 making ${MID}/DRAWCURV.NRLIB from ${MID}/DRAWCURV.spad
+ @ (cd ${MID} ; echo ')co DRAWCURV.spad' | ${INTERPSYS} )
+
+@
+<<DRAWCURV.spad (SPAD from IN)>>=
+${MID}/DRAWCURV.spad: ${IN}/draw.spad.pamphlet
+ @ echo 0 making ${MID}/DRAWCURV.spad from ${IN}/draw.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DRAWCURV.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves" ${IN}/draw.spad.pamphlet >DRAWCURV.spad )
+
+@
+<<DRAWPT.o (O from NRLIB)>>=
+${OUT}/DRAWPT.o: ${MID}/DRAWPT.NRLIB
+ @ echo 0 making ${OUT}/DRAWPT.o from ${MID}/DRAWPT.NRLIB
+ @ cp ${MID}/DRAWPT.NRLIB/code.o ${OUT}/DRAWPT.o
+
+@
+<<DRAWPT.NRLIB (NRLIB from MID)>>=
+${MID}/DRAWPT.NRLIB: ${MID}/DRAWPT.spad
+ @ echo 0 making ${MID}/DRAWPT.NRLIB from ${MID}/DRAWPT.spad
+ @ (cd ${MID} ; echo ')co DRAWPT.spad' | ${INTERPSYS} )
+
+@
+<<DRAWPT.spad (SPAD from IN)>>=
+${MID}/DRAWPT.spad: ${IN}/draw.spad.pamphlet
+ @ echo 0 making ${MID}/DRAWPT.spad from ${IN}/draw.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DRAWPT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DRAWPT TopLevelDrawFunctionsForPoints" ${IN}/draw.spad.pamphlet >DRAWPT.spad )
+
+@
+<<draw.spad.dvi (DOC from IN)>>=
+${DOC}/draw.spad.dvi: ${IN}/draw.spad.pamphlet
+ @ echo 0 making ${DOC}/draw.spad.dvi from ${IN}/draw.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/draw.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} draw.spad ; \
+ rm -f ${DOC}/draw.spad.pamphlet ; \
+ rm -f ${DOC}/draw.spad.tex ; \
+ rm -f ${DOC}/draw.spad )
+
+@
+\subsection{e01.spad \cite{1}}
+<<e01.spad (SPAD from IN)>>=
+${MID}/e01.spad: ${IN}/e01.spad.pamphlet
+ @ echo 0 making ${MID}/e01.spad from ${IN}/e01.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/e01.spad.pamphlet >e01.spad )
+
+@
+<<NAGE01.o (O from NRLIB)>>=
+${OUT}/NAGE01.o: ${MID}/NAGE01.NRLIB
+ @ echo 0 making ${OUT}/NAGE01.o from ${MID}/NAGE01.NRLIB
+ @ cp ${MID}/NAGE01.NRLIB/code.o ${OUT}/NAGE01.o
+
+@
+<<NAGE01.NRLIB (NRLIB from MID)>>=
+${MID}/NAGE01.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/NAGE01.spad
+ @ echo 0 making ${MID}/NAGE01.NRLIB from ${MID}/NAGE01.spad
+ @ (cd ${MID} ; echo ')co NAGE01.spad' | ${INTERPSYS} )
+
+@
+<<NAGE01.spad (SPAD from IN)>>=
+${MID}/NAGE01.spad: ${IN}/e01.spad.pamphlet
+ @ echo 0 making ${MID}/NAGE01.spad from ${IN}/e01.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGE01.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGE01 NagInterpolationPackage" ${IN}/e01.spad.pamphlet >NAGE01.spad )
+
+@
+<<e01.spad.dvi (DOC from IN)>>=
+${DOC}/e01.spad.dvi: ${IN}/e01.spad.pamphlet
+ @ echo 0 making ${DOC}/e01.spad.dvi from ${IN}/e01.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/e01.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} e01.spad ; \
+ rm -f ${DOC}/e01.spad.pamphlet ; \
+ rm -f ${DOC}/e01.spad.tex ; \
+ rm -f ${DOC}/e01.spad )
+
+@
+\subsection{e02.spad \cite{1}}
+<<e02.spad (SPAD from IN)>>=
+${MID}/e02.spad: ${IN}/e02.spad.pamphlet
+ @ echo 0 making ${MID}/e02.spad from ${IN}/e02.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/e02.spad.pamphlet >e02.spad )
+
+@
+<<NAGE02.o (O from NRLIB)>>=
+${OUT}/NAGE02.o: ${MID}/NAGE02.NRLIB
+ @ echo 0 making ${OUT}/NAGE02.o from ${MID}/NAGE02.NRLIB
+ @ cp ${MID}/NAGE02.NRLIB/code.o ${OUT}/NAGE02.o
+
+@
+<<NAGE02.NRLIB (NRLIB from MID)>>=
+${MID}/NAGE02.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/NAGE02.spad
+ @ echo 0 making ${MID}/NAGE02.NRLIB from ${MID}/NAGE02.spad
+ @ (cd ${MID} ; echo ')co NAGE02.spad' | ${INTERPSYS} )
+
+@
+<<NAGE02.spad (SPAD from IN)>>=
+${MID}/NAGE02.spad: ${IN}/e02.spad.pamphlet
+ @ echo 0 making ${MID}/NAGE02.spad from ${IN}/e02.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGE02.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGE02 NagFittingPackage" ${IN}/e02.spad.pamphlet >NAGE02.spad )
+
+@
+<<e02.spad.dvi (DOC from IN)>>=
+${DOC}/e02.spad.dvi: ${IN}/e02.spad.pamphlet
+ @ echo 0 making ${DOC}/e02.spad.dvi from ${IN}/e02.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/e02.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} e02.spad ; \
+ rm -f ${DOC}/e02.spad.pamphlet ; \
+ rm -f ${DOC}/e02.spad.tex ; \
+ rm -f ${DOC}/e02.spad )
+
+@
+\subsection{e04agents.spad \cite{1}}
+<<e04agents.spad (SPAD from IN)>>=
+${MID}/e04agents.spad: ${IN}/e04agents.spad.pamphlet
+ @ echo 0 making ${MID}/e04agents.spad from ${IN}/e04agents.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/e04agents.spad.pamphlet >e04agents.spad )
+
+@
+<<E04AGNT.o (O from NRLIB)>>=
+${OUT}/E04AGNT.o: ${MID}/E04AGNT.NRLIB
+ @ echo 0 making ${OUT}/E04AGNT.o from ${MID}/E04AGNT.NRLIB
+ @ cp ${MID}/E04AGNT.NRLIB/code.o ${OUT}/E04AGNT.o
+
+@
+<<E04AGNT.NRLIB (NRLIB from MID)>>=
+${MID}/E04AGNT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/E04AGNT.spad
+ @ echo 0 making ${MID}/E04AGNT.NRLIB from ${MID}/E04AGNT.spad
+ @ (cd ${MID} ; echo ')co E04AGNT.spad' | ${INTERPSYS} )
+
+@
+<<E04AGNT.spad (SPAD from IN)>>=
+${MID}/E04AGNT.spad: ${IN}/e04agents.spad.pamphlet
+ @ echo 0 making ${MID}/E04AGNT.spad from ${IN}/e04agents.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04AGNT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package E04AGNT e04AgentsPackage" ${IN}/e04agents.spad.pamphlet >E04AGNT.spad )
+
+@
+<<e04agents.spad.dvi (DOC from IN)>>=
+${DOC}/e04agents.spad.dvi: ${IN}/e04agents.spad.pamphlet
+ @ echo 0 making ${DOC}/e04agents.spad.dvi from ${IN}/e04agents.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/e04agents.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} e04agents.spad ; \
+ rm -f ${DOC}/e04agents.spad.pamphlet ; \
+ rm -f ${DOC}/e04agents.spad.tex ; \
+ rm -f ${DOC}/e04agents.spad )
+
+@
+\subsection{e04Package.spad \cite{1}}
+<<e04Package.spad (SPAD from IN)>>=
+${MID}/e04Package.spad: ${IN}/e04Package.spad.pamphlet
+ @ echo 0 making ${MID}/e04Package.spad from ${IN}/e04Package.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/e04Package.spad.pamphlet >e04Package.spad )
+
+@
+<<OPTPACK.o (O from NRLIB)>>=
+${OUT}/OPTPACK.o: ${MID}/OPTPACK.NRLIB
+ @ echo 0 making ${OUT}/OPTPACK.o from ${MID}/OPTPACK.NRLIB
+ @ cp ${MID}/OPTPACK.NRLIB/code.o ${OUT}/OPTPACK.o
+
+@
+<<OPTPACK.NRLIB (NRLIB from MID)>>=
+${MID}/OPTPACK.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/OPTPACK.spad
+ @ echo 0 making ${MID}/OPTPACK.NRLIB from ${MID}/OPTPACK.spad
+ @ (cd ${MID} ; echo ')co OPTPACK.spad' | ${INTERPSYS} )
+
+@
+<<OPTPACK.spad (SPAD from IN)>>=
+${MID}/OPTPACK.spad: ${IN}/e04Package.spad.pamphlet
+ @ echo 0 making ${MID}/OPTPACK.spad from ${IN}/e04Package.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OPTPACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OPTPACK AnnaNumericalOptimizationPackage" ${IN}/e04Package.spad.pamphlet >OPTPACK.spad )
+
+@
+<<e04Package.spad.dvi (DOC from IN)>>=
+${DOC}/e04Package.spad.dvi: ${IN}/e04Package.spad.pamphlet
+ @ echo 0 making ${DOC}/e04Package.spad.dvi from ${IN}/e04Package.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/e04Package.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} e04Package.spad ; \
+ rm -f ${DOC}/e04Package.spad.pamphlet ; \
+ rm -f ${DOC}/e04Package.spad.tex ; \
+ rm -f ${DOC}/e04Package.spad )
+
+@
+\subsection{e04routine.spad \cite{1}}
+<<e04routine.spad (SPAD from IN)>>=
+${MID}/e04routine.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/e04routine.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/e04routine.spad.pamphlet >e04routine.spad )
+
+@
+<<E04DGFA.o (O from NRLIB)>>=
+${OUT}/E04DGFA.o: ${MID}/E04DGFA.NRLIB
+ @ echo 0 making ${OUT}/E04DGFA.o from ${MID}/E04DGFA.NRLIB
+ @ cp ${MID}/E04DGFA.NRLIB/code.o ${OUT}/E04DGFA.o
+
+@
+<<E04DGFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04DGFA.NRLIB: ${MID}/E04DGFA.spad
+ @ echo 0 making ${MID}/E04DGFA.NRLIB from ${MID}/E04DGFA.spad
+ @ (cd ${MID} ; echo ')co E04DGFA.spad' | ${INTERPSYS} )
+
+@
+<<E04DGFA.spad (SPAD from IN)>>=
+${MID}/E04DGFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04DGFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04DGFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04DGFA e04dgfAnnaType" ${IN}/e04routine.spad.pamphlet >E04DGFA.spad )
+
+@
+<<E04FDFA.o (O from NRLIB)>>=
+${OUT}/E04FDFA.o: ${MID}/E04FDFA.NRLIB
+ @ echo 0 making ${OUT}/E04FDFA.o from ${MID}/E04FDFA.NRLIB
+ @ cp ${MID}/E04FDFA.NRLIB/code.o ${OUT}/E04FDFA.o
+
+@
+<<E04FDFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04FDFA.NRLIB: ${MID}/E04FDFA.spad
+ @ echo 0 making ${MID}/E04FDFA.NRLIB from ${MID}/E04FDFA.spad
+ @ (cd ${MID} ; echo ')co E04FDFA.spad' | ${INTERPSYS} )
+
+@
+<<E04FDFA.spad (SPAD from IN)>>=
+${MID}/E04FDFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04FDFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04FDFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04FDFA e04fdfAnnaType" ${IN}/e04routine.spad.pamphlet >E04FDFA.spad )
+
+@
+<<E04JAFA.o (O from NRLIB)>>=
+${OUT}/E04JAFA.o: ${MID}/E04JAFA.NRLIB
+ @ echo 0 making ${OUT}/E04JAFA.o from ${MID}/E04JAFA.NRLIB
+ @ cp ${MID}/E04JAFA.NRLIB/code.o ${OUT}/E04JAFA.o
+
+@
+<<E04JAFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04JAFA.NRLIB: ${MID}/E04JAFA.spad
+ @ echo 0 making ${MID}/E04JAFA.NRLIB from ${MID}/E04JAFA.spad
+ @ (cd ${MID} ; echo ')co E04JAFA.spad' | ${INTERPSYS} )
+
+@
+<<E04JAFA.spad (SPAD from IN)>>=
+${MID}/E04JAFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04JAFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04JAFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04JAFA e04jafAnnaType" ${IN}/e04routine.spad.pamphlet >E04JAFA.spad )
+
+@
+<<E04GCFA.o (O from NRLIB)>>=
+${OUT}/E04GCFA.o: ${MID}/E04GCFA.NRLIB
+ @ echo 0 making ${OUT}/E04GCFA.o from ${MID}/E04GCFA.NRLIB
+ @ cp ${MID}/E04GCFA.NRLIB/code.o ${OUT}/E04GCFA.o
+
+@
+<<E04GCFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04GCFA.NRLIB: ${MID}/E04GCFA.spad
+ @ echo 0 making ${MID}/E04GCFA.NRLIB from ${MID}/E04GCFA.spad
+ @ (cd ${MID} ; echo ')co E04GCFA.spad' | ${INTERPSYS} )
+
+@
+<<E04GCFA.spad (SPAD from IN)>>=
+${MID}/E04GCFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04GCFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04GCFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04GCFA e04gcfAnnaType" ${IN}/e04routine.spad.pamphlet >E04GCFA.spad )
+
+@
+<<E04MBFA.o (O from NRLIB)>>=
+${OUT}/E04MBFA.o: ${MID}/E04MBFA.NRLIB
+ @ echo 0 making ${OUT}/E04MBFA.o from ${MID}/E04MBFA.NRLIB
+ @ cp ${MID}/E04MBFA.NRLIB/code.o ${OUT}/E04MBFA.o
+
+@
+<<E04MBFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04MBFA.NRLIB: ${MID}/E04MBFA.spad
+ @ echo 0 making ${MID}/E04MBFA.NRLIB from ${MID}/E04MBFA.spad
+ @ (cd ${MID} ; echo ')co E04MBFA.spad' | ${INTERPSYS} )
+
+@
+<<E04MBFA.spad (SPAD from IN)>>=
+${MID}/E04MBFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04MBFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04MBFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04MBFA e04mbfAnnaType" ${IN}/e04routine.spad.pamphlet >E04MBFA.spad )
+
+@
+<<E04NAFA.o (O from NRLIB)>>=
+${OUT}/E04NAFA.o: ${MID}/E04NAFA.NRLIB
+ @ echo 0 making ${OUT}/E04NAFA.o from ${MID}/E04NAFA.NRLIB
+ @ cp ${MID}/E04NAFA.NRLIB/code.o ${OUT}/E04NAFA.o
+
+@
+<<E04NAFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04NAFA.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/E04NAFA.spad
+ @ echo 0 making ${MID}/E04NAFA.NRLIB from ${MID}/E04NAFA.spad
+ @ (cd ${MID} ; echo ')co E04NAFA.spad' | ${INTERPSYS} )
+
+@
+<<E04NAFA.spad (SPAD from IN)>>=
+${MID}/E04NAFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04NAFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04NAFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04NAFA e04nafAnnaType" ${IN}/e04routine.spad.pamphlet >E04NAFA.spad )
+
+@
+<<E04UCFA.o (O from NRLIB)>>=
+${OUT}/E04UCFA.o: ${MID}/E04UCFA.NRLIB
+ @ echo 0 making ${OUT}/E04UCFA.o from ${MID}/E04UCFA.NRLIB
+ @ cp ${MID}/E04UCFA.NRLIB/code.o ${OUT}/E04UCFA.o
+
+@
+<<E04UCFA.NRLIB (NRLIB from MID)>>=
+${MID}/E04UCFA.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/E04UCFA.spad
+ @ echo 0 making ${MID}/E04UCFA.NRLIB from ${MID}/E04UCFA.spad
+ @ (cd ${MID} ; echo ')co E04UCFA.spad' | ${INTERPSYS} )
+
+@
+<<E04UCFA.spad (SPAD from IN)>>=
+${MID}/E04UCFA.spad: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${MID}/E04UCFA.spad from ${IN}/e04routine.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf E04UCFA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain E04UCFA e04ucfAnnaType" ${IN}/e04routine.spad.pamphlet >E04UCFA.spad )
+
+@
+<<e04routine.spad.dvi (DOC from IN)>>=
+${DOC}/e04routine.spad.dvi: ${IN}/e04routine.spad.pamphlet
+ @ echo 0 making ${DOC}/e04routine.spad.dvi from ${IN}/e04routine.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/e04routine.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} e04routine.spad ; \
+ rm -f ${DOC}/e04routine.spad.pamphlet ; \
+ rm -f ${DOC}/e04routine.spad.tex ; \
+ rm -f ${DOC}/e04routine.spad )
+
+@
+\subsection{e04.spad \cite{1}}
+<<e04.spad (SPAD from IN)>>=
+${MID}/e04.spad: ${IN}/e04.spad.pamphlet
+ @ echo 0 making ${MID}/e04.spad from ${IN}/e04.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/e04.spad.pamphlet >e04.spad )
+
+@
+<<NAGE04.o (O from NRLIB)>>=
+${OUT}/NAGE04.o: ${MID}/NAGE04.NRLIB
+ @ echo 0 making ${OUT}/NAGE04.o from ${MID}/NAGE04.NRLIB
+ @ cp ${MID}/NAGE04.NRLIB/code.o ${OUT}/NAGE04.o
+
+@
+<<NAGE04.NRLIB (NRLIB from MID)>>=
+${MID}/NAGE04.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/NAGE04.spad
+ @ echo 0 making ${MID}/NAGE04.NRLIB from ${MID}/NAGE04.spad
+ @ (cd ${MID} ; echo ')co NAGE04.spad' | ${INTERPSYS} )
+
+@
+<<NAGE04.spad (SPAD from IN)>>=
+${MID}/NAGE04.spad: ${IN}/e04.spad.pamphlet
+ @ echo 0 making ${MID}/NAGE04.spad from ${IN}/e04.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGE04.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGE04 NagOptimisationPackage" ${IN}/e04.spad.pamphlet >NAGE04.spad )
+
+@
+<<e04.spad.dvi (DOC from IN)>>=
+${DOC}/e04.spad.dvi: ${IN}/e04.spad.pamphlet
+ @ echo 0 making ${DOC}/e04.spad.dvi from ${IN}/e04.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/e04.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} e04.spad ; \
+ rm -f ${DOC}/e04.spad.pamphlet ; \
+ rm -f ${DOC}/e04.spad.tex ; \
+ rm -f ${DOC}/e04.spad )
+
+@
+\subsection{efstruc.spad \cite{1}}
+<<efstruc.spad (SPAD from IN)>>=
+${MID}/efstruc.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/efstruc.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/efstruc.spad.pamphlet >efstruc.spad )
+
+@
+<<CTRIGMNP.o (O from NRLIB)>>=
+${OUT}/CTRIGMNP.o: ${MID}/CTRIGMNP.NRLIB
+ @ echo 0 making ${OUT}/CTRIGMNP.o from ${MID}/CTRIGMNP.NRLIB
+ @ cp ${MID}/CTRIGMNP.NRLIB/code.o ${OUT}/CTRIGMNP.o
+
+@
+<<CTRIGMNP.NRLIB (NRLIB from MID)>>=
+${MID}/CTRIGMNP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/CTRIGMNP.spad
+ @ echo 0 making ${MID}/CTRIGMNP.NRLIB from ${MID}/CTRIGMNP.spad
+ @ (cd ${MID} ; echo ')co CTRIGMNP.spad' | ${INTERPSYS} )
+
+@
+<<CTRIGMNP.spad (SPAD from IN)>>=
+${MID}/CTRIGMNP.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/CTRIGMNP.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CTRIGMNP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CTRIGMNP ComplexTrigonometricManipulations" ${IN}/efstruc.spad.pamphlet >CTRIGMNP.spad )
+
+@
+<<EFSTRUC.o (O from NRLIB)>>=
+${OUT}/EFSTRUC.o: ${MID}/EFSTRUC.NRLIB
+ @ echo 0 making ${OUT}/EFSTRUC.o from ${MID}/EFSTRUC.NRLIB
+ @ cp ${MID}/EFSTRUC.NRLIB/code.o ${OUT}/EFSTRUC.o
+
+@
+<<EFSTRUC.NRLIB (NRLIB from MID)>>=
+${MID}/EFSTRUC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/EFSTRUC.spad
+ @ echo 0 making ${MID}/EFSTRUC.NRLIB from ${MID}/EFSTRUC.spad
+ @ (cd ${MID} ; echo ')co EFSTRUC.spad' | ${INTERPSYS} )
+
+@
+<<EFSTRUC.spad (SPAD from IN)>>=
+${MID}/EFSTRUC.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/EFSTRUC.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EFSTRUC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EFSTRUC ElementaryFunctionStructurePackage" ${IN}/efstruc.spad.pamphlet >EFSTRUC.spad )
+
+@
+<<ITRIGMNP.o (O from NRLIB)>>=
+${OUT}/ITRIGMNP.o: ${MID}/ITRIGMNP.NRLIB
+ @ echo 0 making ${OUT}/ITRIGMNP.o from ${MID}/ITRIGMNP.NRLIB
+ @ cp ${MID}/ITRIGMNP.NRLIB/code.o ${OUT}/ITRIGMNP.o
+
+@
+<<ITRIGMNP.NRLIB (NRLIB from MID)>>=
+${MID}/ITRIGMNP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ITRIGMNP.spad
+ @ echo 0 making ${MID}/ITRIGMNP.NRLIB from ${MID}/ITRIGMNP.spad
+ @ (cd ${MID} ; echo ')co ITRIGMNP.spad' | ${INTERPSYS} )
+
+@
+<<ITRIGMNP.spad (SPAD from IN)>>=
+${MID}/ITRIGMNP.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/ITRIGMNP.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ITRIGMNP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ITRIGMNP InnerTrigonometricManipulations" ${IN}/efstruc.spad.pamphlet >ITRIGMNP.spad )
+
+@
+<<SYMFUNC.o (O from NRLIB)>>=
+${OUT}/SYMFUNC.o: ${MID}/SYMFUNC.NRLIB
+ @ echo 0 making ${OUT}/SYMFUNC.o from ${MID}/SYMFUNC.NRLIB
+ @ cp ${MID}/SYMFUNC.NRLIB/code.o ${OUT}/SYMFUNC.o
+
+@
+<<SYMFUNC.NRLIB (NRLIB from MID)>>=
+${MID}/SYMFUNC.NRLIB: ${MID}/SYMFUNC.spad
+ @ echo 0 making ${MID}/SYMFUNC.NRLIB from ${MID}/SYMFUNC.spad
+ @ (cd ${MID} ; echo ')co SYMFUNC.spad' | ${INTERPSYS} )
+
+@
+<<SYMFUNC.spad (SPAD from IN)>>=
+${MID}/SYMFUNC.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/SYMFUNC.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYMFUNC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SYMFUNC SymmetricFunctions" ${IN}/efstruc.spad.pamphlet >SYMFUNC.spad )
+
+@
+<<TRIGMNIP.o (O from NRLIB)>>=
+${OUT}/TRIGMNIP.o: ${MID}/TRIGMNIP.NRLIB
+ @ echo 0 making ${OUT}/TRIGMNIP.o from ${MID}/TRIGMNIP.NRLIB
+ @ cp ${MID}/TRIGMNIP.NRLIB/code.o ${OUT}/TRIGMNIP.o
+
+@
+<<TRIGMNIP.NRLIB (NRLIB from MID)>>=
+${MID}/TRIGMNIP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/TRIGMNIP.spad
+ @ echo 0 making ${MID}/TRIGMNIP.NRLIB from ${MID}/TRIGMNIP.spad
+ @ (cd ${MID} ; echo ')co TRIGMNIP.spad' | ${INTERPSYS} )
+
+@
+<<TRIGMNIP.spad (SPAD from IN)>>=
+${MID}/TRIGMNIP.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/TRIGMNIP.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TRIGMNIP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TRIGMNIP TrigonometricManipulations" ${IN}/efstruc.spad.pamphlet >TRIGMNIP.spad )
+
+@
+<<TANEXP.o (O from NRLIB)>>=
+${OUT}/TANEXP.o: ${MID}/TANEXP.NRLIB
+ @ echo 0 making ${OUT}/TANEXP.o from ${MID}/TANEXP.NRLIB
+ @ cp ${MID}/TANEXP.NRLIB/code.o ${OUT}/TANEXP.o
+
+@
+<<TANEXP.NRLIB (NRLIB from MID)>>=
+${MID}/TANEXP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/TANEXP.spad
+ @ echo 0 making ${MID}/TANEXP.NRLIB from ${MID}/TANEXP.spad
+ @ (cd ${MID} ; echo ')co TANEXP.spad' | ${INTERPSYS} )
+
+@
+<<TANEXP.spad (SPAD from IN)>>=
+${MID}/TANEXP.spad: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${MID}/TANEXP.spad from ${IN}/efstruc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TANEXP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TANEXP TangentExpansions" ${IN}/efstruc.spad.pamphlet >TANEXP.spad )
+
+@
+<<efstruc.spad.dvi (DOC from IN)>>=
+${DOC}/efstruc.spad.dvi: ${IN}/efstruc.spad.pamphlet
+ @ echo 0 making ${DOC}/efstruc.spad.dvi from ${IN}/efstruc.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/efstruc.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} efstruc.spad ; \
+ rm -f ${DOC}/efstruc.spad.pamphlet ; \
+ rm -f ${DOC}/efstruc.spad.tex ; \
+ rm -f ${DOC}/efstruc.spad )
+
+@
+\subsection{efuls.spad \cite{1}}
+<<efuls.spad (SPAD from IN)>>=
+${MID}/efuls.spad: ${IN}/efuls.spad.pamphlet
+ @ echo 0 making ${MID}/efuls.spad from ${IN}/efuls.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/efuls.spad.pamphlet >efuls.spad )
+
+@
+<<EFULS.o (O from NRLIB)>>=
+${OUT}/EFULS.o: ${MID}/EFULS.NRLIB
+ @ echo 0 making ${OUT}/EFULS.o from ${MID}/EFULS.NRLIB
+ @ cp ${MID}/EFULS.NRLIB/code.o ${OUT}/EFULS.o
+
+@
+<<EFULS.NRLIB (NRLIB from MID)>>=
+${MID}/EFULS.NRLIB: ${MID}/EFULS.spad
+ @ echo 0 making ${MID}/EFULS.NRLIB from ${MID}/EFULS.spad
+ @ (cd ${MID} ; echo ')co EFULS.spad' | ${INTERPSYS} )
+
+@
+<<EFULS.spad (SPAD from IN)>>=
+${MID}/EFULS.spad: ${IN}/efuls.spad.pamphlet
+ @ echo 0 making ${MID}/EFULS.spad from ${IN}/efuls.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EFULS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EFULS ElementaryFunctionsUnivariateLaurentSeries" ${IN}/efuls.spad.pamphlet >EFULS.spad )
+
+@
+<<efuls.spad.dvi (DOC from IN)>>=
+${DOC}/efuls.spad.dvi: ${IN}/efuls.spad.pamphlet
+ @ echo 0 making ${DOC}/efuls.spad.dvi from ${IN}/efuls.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/efuls.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} efuls.spad ; \
+ rm -f ${DOC}/efuls.spad.pamphlet ; \
+ rm -f ${DOC}/efuls.spad.tex ; \
+ rm -f ${DOC}/efuls.spad )
+
+@
+\subsection{efupxs.spad \cite{1}}
+<<efupxs.spad (SPAD from IN)>>=
+${MID}/efupxs.spad: ${IN}/efupxs.spad.pamphlet
+ @ echo 0 making ${MID}/efupxs.spad from ${IN}/efupxs.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/efupxs.spad.pamphlet >efupxs.spad )
+
+@
+<<EFUPXS.o (O from NRLIB)>>=
+${OUT}/EFUPXS.o: ${MID}/EFUPXS.NRLIB
+ @ echo 0 making ${OUT}/EFUPXS.o from ${MID}/EFUPXS.NRLIB
+ @ cp ${MID}/EFUPXS.NRLIB/code.o ${OUT}/EFUPXS.o
+
+@
+<<EFUPXS.NRLIB (NRLIB from MID)>>=
+${MID}/EFUPXS.NRLIB: ${MID}/EFUPXS.spad
+ @ echo 0 making ${MID}/EFUPXS.NRLIB from ${MID}/EFUPXS.spad
+ @ (cd ${MID} ; echo ')co EFUPXS.spad' | ${INTERPSYS} )
+
+@
+<<EFUPXS.spad (SPAD from IN)>>=
+${MID}/EFUPXS.spad: ${IN}/efupxs.spad.pamphlet
+ @ echo 0 making ${MID}/EFUPXS.spad from ${IN}/efupxs.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EFUPXS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries" ${IN}/efupxs.spad.pamphlet >EFUPXS.spad )
+
+@
+<<efupxs.spad.dvi (DOC from IN)>>=
+${DOC}/efupxs.spad.dvi: ${IN}/efupxs.spad.pamphlet
+ @ echo 0 making ${DOC}/efupxs.spad.dvi from ${IN}/efupxs.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/efupxs.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} efupxs.spad ; \
+ rm -f ${DOC}/efupxs.spad.pamphlet ; \
+ rm -f ${DOC}/efupxs.spad.tex ; \
+ rm -f ${DOC}/efupxs.spad )
+
+@
+\subsection{eigen.spad \cite{1}}
+<<eigen.spad (SPAD from IN)>>=
+${MID}/eigen.spad: ${IN}/eigen.spad.pamphlet
+ @ echo 0 making ${MID}/eigen.spad from ${IN}/eigen.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/eigen.spad.pamphlet >eigen.spad )
+
+@
+<<CHARPOL.o (O from NRLIB)>>=
+${OUT}/CHARPOL.o: ${MID}/CHARPOL.NRLIB
+ @ echo 0 making ${OUT}/CHARPOL.o from ${MID}/CHARPOL.NRLIB
+ @ cp ${MID}/CHARPOL.NRLIB/code.o ${OUT}/CHARPOL.o
+
+@
+<<CHARPOL.NRLIB (NRLIB from MID)>>=
+${MID}/CHARPOL.NRLIB: ${MID}/CHARPOL.spad
+ @ echo 0 making ${MID}/CHARPOL.NRLIB from ${MID}/CHARPOL.spad
+ @ (cd ${MID} ; echo ')co CHARPOL.spad' | ${INTERPSYS} )
+
+@
+<<CHARPOL.spad (SPAD from IN)>>=
+${MID}/CHARPOL.spad: ${IN}/eigen.spad.pamphlet
+ @ echo 0 making ${MID}/CHARPOL.spad from ${IN}/eigen.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CHARPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CHARPOL CharacteristicPolynomialPackage" ${IN}/eigen.spad.pamphlet >CHARPOL.spad )
+
+@
+<<EP.o (O from NRLIB)>>=
+${OUT}/EP.o: ${MID}/EP.NRLIB
+ @ echo 0 making ${OUT}/EP.o from ${MID}/EP.NRLIB
+ @ cp ${MID}/EP.NRLIB/code.o ${OUT}/EP.o
+
+@
+<<EP.NRLIB (NRLIB from MID)>>=
+${MID}/EP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/EP.spad
+ @ echo 0 making ${MID}/EP.NRLIB from ${MID}/EP.spad
+ @ (cd ${MID} ; echo ')co EP.spad' | ${INTERPSYS} )
+
+@
+<<EP.spad (SPAD from IN)>>=
+${MID}/EP.spad: ${IN}/eigen.spad.pamphlet
+ @ echo 0 making ${MID}/EP.spad from ${IN}/eigen.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EP EigenPackage" ${IN}/eigen.spad.pamphlet >EP.spad )
+
+@
+<<eigen.spad.dvi (DOC from IN)>>=
+${DOC}/eigen.spad.dvi: ${IN}/eigen.spad.pamphlet
+ @ echo 0 making ${DOC}/eigen.spad.dvi from ${IN}/eigen.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/eigen.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} eigen.spad ; \
+ rm -f ${DOC}/eigen.spad.pamphlet ; \
+ rm -f ${DOC}/eigen.spad.tex ; \
+ rm -f ${DOC}/eigen.spad )
+
+@
+\subsection{elemntry.spad \cite{1}}
+<<elemntry.spad (SPAD from IN)>>=
+${MID}/elemntry.spad: ${IN}/elemntry.spad.pamphlet
+ @ echo 0 making ${MID}/elemntry.spad from ${IN}/elemntry.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/elemntry.spad.pamphlet >elemntry.spad )
+
+@
+<<EF.o (O from NRLIB)>>=
+${OUT}/EF.o: ${MID}/EF.NRLIB
+ @ echo 0 making ${OUT}/EF.o from ${MID}/EF.NRLIB
+ @ cp ${MID}/EF.NRLIB/code.o ${OUT}/EF.o
+
+@
+<<EF.NRLIB (NRLIB from MID)>>=
+${MID}/EF.NRLIB: ${MID}/EF.spad
+ @ echo 0 making ${MID}/EF.NRLIB from ${MID}/EF.spad
+ @ (cd ${MID} ; echo ')co EF.spad' | ${INTERPSYS} )
+
+@
+<<EF.spad (SPAD from IN)>>=
+${MID}/EF.spad: ${IN}/elemntry.spad.pamphlet
+ @ echo 0 making ${MID}/EF.spad from ${IN}/elemntry.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EF ElementaryFunction" ${IN}/elemntry.spad.pamphlet >EF.spad )
+
+@
+<<elemntry.spad.dvi (DOC from IN)>>=
+${DOC}/elemntry.spad.dvi: ${IN}/elemntry.spad.pamphlet
+ @ echo 0 making ${DOC}/elemntry.spad.dvi from ${IN}/elemntry.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/elemntry.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} elemntry.spad ; \
+ rm -f ${DOC}/elemntry.spad.pamphlet ; \
+ rm -f ${DOC}/elemntry.spad.tex ; \
+ rm -f ${DOC}/elemntry.spad )
+
+@
+\subsection{elfuts.spad \cite{1}}
+<<elfuts.spad (SPAD from IN)>>=
+${MID}/elfuts.spad: ${IN}/elfuts.spad.pamphlet
+ @ echo 0 making ${MID}/elfuts.spad from ${IN}/elfuts.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/elfuts.spad.pamphlet >elfuts.spad )
+
+@
+<<ELFUTS.o (O from NRLIB)>>=
+${OUT}/ELFUTS.o: ${MID}/ELFUTS.NRLIB
+ @ echo 0 making ${OUT}/ELFUTS.o from ${MID}/ELFUTS.NRLIB
+ @ cp ${MID}/ELFUTS.NRLIB/code.o ${OUT}/ELFUTS.o
+
+@
+<<ELFUTS.NRLIB (NRLIB from MID)>>=
+${MID}/ELFUTS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ELFUTS.spad
+ @ echo 0 making ${MID}/ELFUTS.NRLIB from ${MID}/ELFUTS.spad
+ @ (cd ${MID} ; echo ')co ELFUTS.spad' | ${INTERPSYS} )
+
+@
+<<ELFUTS.spad (SPAD from IN)>>=
+${MID}/ELFUTS.spad: ${IN}/elfuts.spad.pamphlet
+ @ echo 0 making ${MID}/ELFUTS.spad from ${IN}/elfuts.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ELFUTS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ELFUTS EllipticFunctionsUnivariateTaylorSeries" ${IN}/elfuts.spad.pamphlet >ELFUTS.spad )
+
+@
+
+<<elfuts.spad.dvi (DOC from IN)>>=
+${DOC}/elfuts.spad.dvi: ${IN}/elfuts.spad.pamphlet
+ @ echo 0 making ${DOC}/elfuts.spad.dvi from ${IN}/elfuts.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/elfuts.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} elfuts.spad ; \
+ rm -f ${DOC}/elfuts.spad.pamphlet ; \
+ rm -f ${DOC}/elfuts.spad.tex ; \
+ rm -f ${DOC}/elfuts.spad )
+
+@
+\subsection{equation1.spad \cite{1}}
+<<equation1.spad (SPAD from IN)>>=
+${MID}/equation1.spad: ${IN}/equation1.spad.pamphlet
+ @ echo 0 making ${MID}/equation1.spad from ${IN}/equation1.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/equation1.spad.pamphlet >equation1.spad )
+
+@
+<<EVALAB-.o (O from NRLIB)>>=
+${OUT}/EVALAB-.o: ${MID}/EVALAB.NRLIB
+ @ echo 0 making ${OUT}/EVALAB-.o from ${MID}/EVALAB-.NRLIB
+ @ cp ${MID}/EVALAB-.NRLIB/code.o ${OUT}/EVALAB-.o
+
+@
+<<EVALAB-.NRLIB (NRLIB from MID)>>=
+${MID}/EVALAB-.NRLIB: ${OUT}/TYPE.o ${MID}/EVALAB.spad
+ @ echo 0 making ${MID}/EVALAB-.NRLIB from ${MID}/EVALAB.spad
+ @ (cd ${MID} ; echo ')co EVALAB.spad' | ${INTERPSYS} )
+
+@
+<<EVALAB.o (O from NRLIB)>>=
+${OUT}/EVALAB.o: ${MID}/EVALAB.NRLIB
+ @ echo 0 making ${OUT}/EVALAB.o from ${MID}/EVALAB.NRLIB
+ @ cp ${MID}/EVALAB.NRLIB/code.o ${OUT}/EVALAB.o
+
+@
+<<EVALAB.NRLIB (NRLIB from MID)>>=
+${MID}/EVALAB.NRLIB: ${OUT}/TYPE.o ${MID}/EVALAB.spad
+ @ echo 0 making ${MID}/EVALAB.NRLIB from ${MID}/EVALAB.spad
+ @ (cd ${MID} ; echo ')co EVALAB.spad' | ${INTERPSYS} )
+
+@
+<<EVALAB.spad (SPAD from IN)>>=
+${MID}/EVALAB.spad: ${IN}/equation1.spad.pamphlet
+ @ echo 0 making ${MID}/EVALAB.spad from ${IN}/equation1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EVALAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category EVALAB Evalable" ${IN}/equation1.spad.pamphlet >EVALAB.spad )
+
+@
+<<IEVALAB-.o (O from NRLIB)>>=
+${OUT}/IEVALAB-.o: ${MID}/IEVALAB.NRLIB
+ @ echo 0 making ${OUT}/IEVALAB-.o from ${MID}/IEVALAB-.NRLIB
+ @ cp ${MID}/IEVALAB-.NRLIB/code.o ${OUT}/IEVALAB-.o
+
+@
+<<IEVALAB-.NRLIB (NRLIB from MID)>>=
+${MID}/IEVALAB-.NRLIB: ${OUT}/TYPE.o ${MID}/IEVALAB.spad
+ @ echo 0 making ${MID}/IEVALAB-.NRLIB from ${MID}/IEVALAB.spad
+ @ (cd ${MID} ; echo ')co IEVALAB.spad' | ${INTERPSYS} )
+
+@
+<<IEVALAB.o (O from NRLIB)>>=
+${OUT}/IEVALAB.o: ${MID}/IEVALAB.NRLIB
+ @ echo 0 making ${OUT}/IEVALAB.o from ${MID}/IEVALAB.NRLIB
+ @ cp ${MID}/IEVALAB.NRLIB/code.o ${OUT}/IEVALAB.o
+
+@
+<<IEVALAB.NRLIB (NRLIB from MID)>>=
+${MID}/IEVALAB.NRLIB: ${MID}/IEVALAB.spad
+ @ echo 0 making ${MID}/IEVALAB.NRLIB from ${MID}/IEVALAB.spad
+ @ (cd ${MID} ; echo ')co IEVALAB.spad' | ${INTERPSYS} )
+
+@
+<<IEVALAB.spad (SPAD from IN)>>=
+${MID}/IEVALAB.spad: ${IN}/equation1.spad.pamphlet
+ @ echo 0 making ${MID}/IEVALAB.spad from ${IN}/equation1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IEVALAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category IEVALAB InnerEvalable" ${IN}/equation1.spad.pamphlet >IEVALAB.spad )
+
+@
+<<equation1.spad.dvi (DOC from IN)>>=
+${DOC}/equation1.spad.dvi: ${IN}/equation1.spad.pamphlet
+ @ echo 0 making ${DOC}/equation1.spad.dvi from ${IN}/equation1.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/equation1.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} equation1.spad ; \
+ rm -f ${DOC}/equation1.spad.pamphlet ; \
+ rm -f ${DOC}/equation1.spad.tex ; \
+ rm -f ${DOC}/equation1.spad )
+
+@
+\subsection{equation2.spad \cite{1}}
+<<equation2.spad (SPAD from IN)>>=
+${MID}/equation2.spad: ${IN}/equation2.spad.pamphlet
+ @ echo 0 making ${MID}/equation2.spad from ${IN}/equation2.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/equation2.spad.pamphlet >equation2.spad )
+
+@
+<<EQ.o (O from NRLIB)>>=
+${OUT}/EQ.o: ${MID}/EQ.NRLIB
+ @ echo 0 making ${OUT}/EQ.o from ${MID}/EQ.NRLIB
+ @ cp ${MID}/EQ.NRLIB/code.o ${OUT}/EQ.o
+
+@
+<<EQ.NRLIB (NRLIB from MID)>>=
+${MID}/EQ.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/EQ.spad
+ @ echo 0 making ${MID}/EQ.NRLIB from ${MID}/EQ.spad
+ @ (cd ${MID} ; echo ')co EQ.spad' | ${INTERPSYS} )
+
+@
+<<EQ.spad (SPAD from IN)>>=
+${MID}/EQ.spad: ${IN}/equation2.spad.pamphlet
+ @ echo 0 making ${MID}/EQ.spad from ${IN}/equation2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EQ.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EQ Equation" ${IN}/equation2.spad.pamphlet >EQ.spad )
+
+@
+<<EQ2.o (O from NRLIB)>>=
+${OUT}/EQ2.o: ${MID}/EQ2.NRLIB
+ @ echo 0 making ${OUT}/EQ2.o from ${MID}/EQ2.NRLIB
+ @ cp ${MID}/EQ2.NRLIB/code.o ${OUT}/EQ2.o
+
+@
+<<EQ2.NRLIB (NRLIB from MID)>>=
+${MID}/EQ2.NRLIB: ${OUT}/TYPE.o ${MID}/EQ2.spad
+ @ echo 0 making ${MID}/EQ2.NRLIB from ${MID}/EQ2.spad
+ @ (cd ${MID} ; echo ')co EQ2.spad' | ${INTERPSYS} )
+
+@
+<<EQ2.spad (SPAD from IN)>>=
+${MID}/EQ2.spad: ${IN}/equation2.spad.pamphlet
+ @ echo 0 making ${MID}/EQ2.spad from ${IN}/equation2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EQ2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EQ2 EquationFunctions2" ${IN}/equation2.spad.pamphlet >EQ2.spad )
+
+@
+<<FEVALAB-.o (O from NRLIB)>>=
+${OUT}/FEVALAB-.o: ${MID}/FEVALAB.NRLIB
+ @ echo 0 making ${OUT}/FEVALAB-.o from ${MID}/FEVALAB-.NRLIB
+ @ cp ${MID}/FEVALAB-.NRLIB/code.o ${OUT}/FEVALAB-.o
+
+@
+<<FEVALAB-.NRLIB (NRLIB from MID)>>=
+${MID}/FEVALAB-.NRLIB: ${OUT}/TYPE.o ${MID}/FEVALAB.spad
+ @ echo 0 making ${MID}/FEVALAB-.NRLIB from ${MID}/FEVALAB.spad
+ @ (cd ${MID} ; echo ')co FEVALAB.spad' | ${INTERPSYS} )
+
+@
+<<FEVALAB.o (O from NRLIB)>>=
+${OUT}/FEVALAB.o: ${MID}/FEVALAB.NRLIB
+ @ echo 0 making ${OUT}/FEVALAB.o from ${MID}/FEVALAB.NRLIB
+ @ cp ${MID}/FEVALAB.NRLIB/code.o ${OUT}/FEVALAB.o
+
+@
+<<FEVALAB.NRLIB (NRLIB from MID)>>=
+${MID}/FEVALAB.NRLIB: ${OUT}/TYPE.o ${MID}/FEVALAB.spad
+ @ echo 0 making ${MID}/FEVALAB.NRLIB from ${MID}/FEVALAB.spad
+ @ (cd ${MID} ; echo ')co FEVALAB.spad' | ${INTERPSYS} )
+
+@
+<<FEVALAB.spad (SPAD from IN)>>=
+${MID}/FEVALAB.spad: ${IN}/equation2.spad.pamphlet
+ @ echo 0 making ${MID}/FEVALAB.spad from ${IN}/equation2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FEVALAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FEVALAB FullyEvalableOver" ${IN}/equation2.spad.pamphlet >FEVALAB.spad )
+
+@
+<<equation2.spad.dvi (DOC from IN)>>=
+${DOC}/equation2.spad.dvi: ${IN}/equation2.spad.pamphlet
+ @ echo 0 making ${DOC}/equation2.spad.dvi from ${IN}/equation2.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/equation2.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} equation2.spad ; \
+ rm -f ${DOC}/equation2.spad.pamphlet ; \
+ rm -f ${DOC}/equation2.spad.tex ; \
+ rm -f ${DOC}/equation2.spad )
+
+@
+\subsection{error.spad \cite{1}}
+<<error.spad (SPAD from IN)>>=
+${MID}/error.spad: ${IN}/error.spad.pamphlet
+ @ echo 0 making ${MID}/error.spad from ${IN}/error.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/error.spad.pamphlet >error.spad )
+
+@
+<<ERROR.o (O from NRLIB)>>=
+${OUT}/ERROR.o: ${MID}/ERROR.NRLIB
+ @ echo 0 making ${OUT}/ERROR.o from ${MID}/ERROR.NRLIB
+ @ cp ${MID}/ERROR.NRLIB/code.o ${OUT}/ERROR.o
+
+@
+<<ERROR.NRLIB (NRLIB from MID)>>=
+${MID}/ERROR.NRLIB: ${MID}/ERROR.spad
+ @ echo 0 making ${MID}/ERROR.NRLIB from ${MID}/ERROR.spad
+ @ (cd ${MID} ; echo ')co ERROR.spad' | ${INTERPSYS} )
+
+@
+<<ERROR.spad (SPAD from IN)>>=
+${MID}/ERROR.spad: ${IN}/error.spad.pamphlet
+ @ echo 0 making ${MID}/ERROR.spad from ${IN}/error.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ERROR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ERROR ErrorFunctions" ${IN}/error.spad.pamphlet >ERROR.spad )
+
+@
+<<error.spad.dvi (DOC from IN)>>=
+${DOC}/error.spad.dvi: ${IN}/error.spad.pamphlet
+ @ echo 0 making ${DOC}/error.spad.dvi from ${IN}/error.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/error.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} error.spad ; \
+ rm -f ${DOC}/error.spad.pamphlet ; \
+ rm -f ${DOC}/error.spad.tex ; \
+ rm -f ${DOC}/error.spad )
+
+@
+\subsection{expexpan.spad \cite{1}}
+<<expexpan.spad (SPAD from IN)>>=
+${MID}/expexpan.spad: ${IN}/expexpan.spad.pamphlet
+ @ echo 0 making ${MID}/expexpan.spad from ${IN}/expexpan.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/expexpan.spad.pamphlet >expexpan.spad )
+
+@
+<<EXPEXPAN.o (O from NRLIB)>>=
+${OUT}/EXPEXPAN.o: ${MID}/EXPEXPAN.NRLIB
+ @ echo 0 making ${OUT}/EXPEXPAN.o from ${MID}/EXPEXPAN.NRLIB
+ @ cp ${MID}/EXPEXPAN.NRLIB/code.o ${OUT}/EXPEXPAN.o
+
+@
+<<EXPEXPAN.NRLIB (NRLIB from MID)>>=
+${MID}/EXPEXPAN.NRLIB: ${MID}/EXPEXPAN.spad
+ @ echo 0 making ${MID}/EXPEXPAN.NRLIB from ${MID}/EXPEXPAN.spad
+ @ (cd ${MID} ; echo ')co EXPEXPAN.spad' | ${INTERPSYS} )
+
+@
+<<EXPEXPAN.spad (SPAD from IN)>>=
+${MID}/EXPEXPAN.spad: ${IN}/expexpan.spad.pamphlet
+ @ echo 0 making ${MID}/EXPEXPAN.spad from ${IN}/expexpan.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPEXPAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EXPEXPAN ExponentialExpansion" ${IN}/expexpan.spad.pamphlet >EXPEXPAN.spad )
+
+@
+<<EXPUPXS.o (O from NRLIB)>>=
+${OUT}/EXPUPXS.o: ${MID}/EXPUPXS.NRLIB
+ @ echo 0 making ${OUT}/EXPUPXS.o from ${MID}/EXPUPXS.NRLIB
+ @ cp ${MID}/EXPUPXS.NRLIB/code.o ${OUT}/EXPUPXS.o
+
+@
+<<EXPUPXS.NRLIB (NRLIB from MID)>>=
+${MID}/EXPUPXS.NRLIB: ${MID}/EXPUPXS.spad
+ @ echo 0 making ${MID}/EXPUPXS.NRLIB from ${MID}/EXPUPXS.spad
+ @ (cd ${MID} ; echo ')co EXPUPXS.spad' | ${INTERPSYS} )
+
+@
+<<EXPUPXS.spad (SPAD from IN)>>=
+${MID}/EXPUPXS.spad: ${IN}/expexpan.spad.pamphlet
+ @ echo 0 making ${MID}/EXPUPXS.spad from ${IN}/expexpan.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPUPXS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EXPUPXS ExponentialOfUnivariatePuiseuxSeries" ${IN}/expexpan.spad.pamphlet >EXPUPXS.spad )
+
+@
+<<UPXSSING.o (O from NRLIB)>>=
+${OUT}/UPXSSING.o: ${MID}/UPXSSING.NRLIB
+ @ echo 0 making ${OUT}/UPXSSING.o from ${MID}/UPXSSING.NRLIB
+ @ cp ${MID}/UPXSSING.NRLIB/code.o ${OUT}/UPXSSING.o
+
+@
+<<UPXSSING.NRLIB (NRLIB from MID)>>=
+${MID}/UPXSSING.NRLIB: ${MID}/UPXSSING.spad
+ @ echo 0 making ${MID}/UPXSSING.NRLIB from ${MID}/UPXSSING.spad
+ @ (cd ${MID} ; echo ')co UPXSSING.spad' | ${INTERPSYS} )
+
+@
+<<UPXSSING.spad (SPAD from IN)>>=
+${MID}/UPXSSING.spad: ${IN}/expexpan.spad.pamphlet
+ @ echo 0 making ${MID}/UPXSSING.spad from ${IN}/expexpan.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPXSSING.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain UPXSSING UnivariatePuiseuxSeriesWithExponentialSingularity" ${IN}/expexpan.spad.pamphlet >UPXSSING.spad )
+
+@
+<<expexpan.spad.dvi (DOC from IN)>>=
+${DOC}/expexpan.spad.dvi: ${IN}/expexpan.spad.pamphlet
+ @ echo 0 making ${DOC}/expexpan.spad.dvi from ${IN}/expexpan.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/expexpan.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} expexpan.spad ; \
+ rm -f ${DOC}/expexpan.spad.pamphlet ; \
+ rm -f ${DOC}/expexpan.spad.tex ; \
+ rm -f ${DOC}/expexpan.spad )
+
+@
+\subsection{exposed.lsp \cite{1}}
+<<exposed.lsp (SPAD from IN)>>=
+${MID}/exposed.lsp: ${IN}/exposed.lsp.pamphlet
+ @ echo 0 making ${MID}/exposed.lsp from ${IN}/exposed.lsp.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/exposed.lsp.pamphlet >exposed.lsp )
+
+@
+\subsection{exposed.lsp \cite{1}}
+<<exposed.lsp (LSP from IN)>>=
+${MID}/exposed.lsp: ${IN}/exposed.lsp.pamphlet
+ @ echo 0 making ${MID}/exposed.lsp from ${IN}/exposed.lsp.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/exposed.lsp.pamphlet >exposed.lsp )
+
+@
+<<exposed.lsp.dvi (DOC from IN)>>=
+${DOC}/exposed.lsp.dvi: ${IN}/exposed.lsp.pamphlet
+ @ echo 0 making ${DOC}/exposed.lsp.dvi from ${IN}/exposed.lsp.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/exposed.lsp.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} exposed.lsp ; \
+ rm -f ${DOC}/exposed.lsp.pamphlet ; \
+ rm -f ${DOC}/exposed.lsp.tex ; \
+ rm -f ${DOC}/exposed.lsp )
+
+@
+\subsection{expr2ups.spad \cite{1}}
+<<expr2ups.spad (SPAD from IN)>>=
+${MID}/expr2ups.spad: ${IN}/expr2ups.spad.pamphlet
+ @ echo 0 making ${MID}/expr2ups.spad from ${IN}/expr2ups.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/expr2ups.spad.pamphlet >expr2ups.spad )
+
+@
+<<EXPR2UPS.o (O from NRLIB)>>=
+${OUT}/EXPR2UPS.o: ${MID}/EXPR2UPS.NRLIB
+ @ echo 0 making ${OUT}/EXPR2UPS.o from ${MID}/EXPR2UPS.NRLIB
+ @ cp ${MID}/EXPR2UPS.NRLIB/code.o ${OUT}/EXPR2UPS.o
+
+@
+<<EXPR2UPS.NRLIB (NRLIB from MID)>>=
+${MID}/EXPR2UPS.NRLIB: ${MID}/EXPR2UPS.spad
+ @ echo 0 making ${MID}/EXPR2UPS.NRLIB from ${MID}/EXPR2UPS.spad
+ @ (cd ${MID} ; echo ')co EXPR2UPS.spad' | ${INTERPSYS} )
+
+@
+<<EXPR2UPS.spad (SPAD from IN)>>=
+${MID}/EXPR2UPS.spad: ${IN}/expr2ups.spad.pamphlet
+ @ echo 0 making ${MID}/EXPR2UPS.spad from ${IN}/expr2ups.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPR2UPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EXPR2UPS ExpressionToUnivariatePowerSeries" ${IN}/expr2ups.spad.pamphlet >EXPR2UPS.spad )
+
+@
+<<expr2ups.spad.dvi (DOC from IN)>>=
+${DOC}/expr2ups.spad.dvi: ${IN}/expr2ups.spad.pamphlet
+ @ echo 0 making ${DOC}/expr2ups.spad.dvi from ${IN}/expr2ups.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/expr2ups.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} expr2ups.spad ; \
+ rm -f ${DOC}/expr2ups.spad.pamphlet ; \
+ rm -f ${DOC}/expr2ups.spad.tex ; \
+ rm -f ${DOC}/expr2ups.spad )
+
+@
+\subsection{exprode.spad \cite{1}}
+<<exprode.spad (SPAD from IN)>>=
+${MID}/exprode.spad: ${IN}/exprode.spad.pamphlet
+ @ echo 0 making ${MID}/exprode.spad from ${IN}/exprode.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/exprode.spad.pamphlet >exprode.spad )
+
+@
+<<EXPRODE.o (O from NRLIB)>>=
+${OUT}/EXPRODE.o: ${MID}/EXPRODE.NRLIB
+ @ echo 0 making ${OUT}/EXPRODE.o from ${MID}/EXPRODE.NRLIB
+ @ cp ${MID}/EXPRODE.NRLIB/code.o ${OUT}/EXPRODE.o
+
+@
+<<EXPRODE.NRLIB (NRLIB from MID)>>=
+${MID}/EXPRODE.NRLIB: ${MID}/EXPRODE.spad
+ @ echo 0 making ${MID}/EXPRODE.NRLIB from ${MID}/EXPRODE.spad
+ @ (cd ${MID} ; echo ')co EXPRODE.spad' | ${INTERPSYS} )
+
+@
+<<EXPRODE.spad (SPAD from IN)>>=
+${MID}/EXPRODE.spad: ${IN}/exprode.spad.pamphlet
+ @ echo 0 making ${MID}/EXPRODE.spad from ${IN}/exprode.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPRODE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EXPRODE ExpressionSpaceODESolver" ${IN}/exprode.spad.pamphlet >EXPRODE.spad )
+
+@
+<<exprode.spad.dvi (DOC from IN)>>=
+${DOC}/exprode.spad.dvi: ${IN}/exprode.spad.pamphlet
+ @ echo 0 making ${DOC}/exprode.spad.dvi from ${IN}/exprode.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/exprode.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} exprode.spad ; \
+ rm -f ${DOC}/exprode.spad.pamphlet ; \
+ rm -f ${DOC}/exprode.spad.tex ; \
+ rm -f ${DOC}/exprode.spad )
+
+@
+\subsection{expr.spad \cite{1}}
+<<expr.spad (SPAD from IN)>>=
+${MID}/expr.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/expr.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/expr.spad.pamphlet >expr.spad )
+
+@
+<<EXPR.o (O from NRLIB)>>=
+${OUT}/EXPR.o: ${MID}/EXPR.NRLIB
+ @ echo 0 making ${OUT}/EXPR.o from ${MID}/EXPR.NRLIB
+ @ cp ${MID}/EXPR.NRLIB/code.o ${OUT}/EXPR.o
+
+@
+<<EXPR.NRLIB (NRLIB from MID)>>=
+${MID}/EXPR.NRLIB: ${MID}/EXPR.spad
+ @ echo 0 making ${MID}/EXPR.NRLIB from ${MID}/EXPR.spad
+ @ (cd ${MID} ; echo ')co EXPR.spad' | ${INTERPSYS} )
+
+@
+<<EXPR.spad (SPAD from IN)>>=
+${MID}/EXPR.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/EXPR.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EXPR Expression" ${IN}/expr.spad.pamphlet >EXPR.spad )
+
+@
+<<EXPR2.o (O from NRLIB)>>=
+${OUT}/EXPR2.o: ${MID}/EXPR2.NRLIB
+ @ echo 0 making ${OUT}/EXPR2.o from ${MID}/EXPR2.NRLIB
+ @ cp ${MID}/EXPR2.NRLIB/code.o ${OUT}/EXPR2.o
+
+@
+<<EXPR2.NRLIB (NRLIB from MID)>>=
+${MID}/EXPR2.NRLIB: ${MID}/EXPR2.spad
+ @ echo 0 making ${MID}/EXPR2.NRLIB from ${MID}/EXPR2.spad
+ @ (cd ${MID} ; echo ')co EXPR2.spad' | ${INTERPSYS} )
+
+@
+<<EXPR2.spad (SPAD from IN)>>=
+${MID}/EXPR2.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/EXPR2.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPR2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EXPR2 ExpressionFunctions2" ${IN}/expr.spad.pamphlet >EXPR2.spad )
+
+@
+<<HACKPI.o (O from NRLIB)>>=
+${OUT}/HACKPI.o: ${MID}/HACKPI.NRLIB
+ @ echo 0 making ${OUT}/HACKPI.o from ${MID}/HACKPI.NRLIB
+ @ cp ${MID}/HACKPI.NRLIB/code.o ${OUT}/HACKPI.o
+
+@
+<<HACKPI.NRLIB (NRLIB from MID)>>=
+${MID}/HACKPI.NRLIB: ${MID}/HACKPI.spad
+ @ echo 0 making ${MID}/HACKPI.NRLIB from ${MID}/HACKPI.spad
+ @ (cd ${MID} ; echo ')co HACKPI.spad' | ${INTERPSYS} )
+
+@
+<<HACKPI.spad (SPAD from IN)>>=
+${MID}/HACKPI.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/HACKPI.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HACKPI.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HACKPI Pi" ${IN}/expr.spad.pamphlet >HACKPI.spad )
+
+@
+<<PAN2EXPR.o (O from NRLIB)>>=
+${OUT}/PAN2EXPR.o: ${MID}/PAN2EXPR.NRLIB
+ @ echo 0 making ${OUT}/PAN2EXPR.o from ${MID}/PAN2EXPR.NRLIB
+ @ cp ${MID}/PAN2EXPR.NRLIB/code.o ${OUT}/PAN2EXPR.o
+
+@
+<<PAN2EXPR.NRLIB (NRLIB from MID)>>=
+${MID}/PAN2EXPR.NRLIB: ${MID}/PAN2EXPR.spad
+ @ echo 0 making ${MID}/PAN2EXPR.NRLIB from ${MID}/PAN2EXPR.spad
+ @ (cd ${MID} ; echo ')co PAN2EXPR.spad' | ${INTERPSYS} )
+
+@
+<<PAN2EXPR.spad (SPAD from IN)>>=
+${MID}/PAN2EXPR.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/PAN2EXPR.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PAN2EXPR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PAN2EXPR PolynomialAN2Expression" ${IN}/expr.spad.pamphlet >PAN2EXPR.spad )
+
+@
+<<PICOERCE.o (O from NRLIB)>>=
+${OUT}/PICOERCE.o: ${MID}/PICOERCE.NRLIB
+ @ echo 0 making ${OUT}/PICOERCE.o from ${MID}/PICOERCE.NRLIB
+ @ cp ${MID}/PICOERCE.NRLIB/code.o ${OUT}/PICOERCE.o
+
+@
+<<PICOERCE.NRLIB (NRLIB from MID)>>=
+${MID}/PICOERCE.NRLIB: ${MID}/PICOERCE.spad
+ @ echo 0 making ${MID}/PICOERCE.NRLIB from ${MID}/PICOERCE.spad
+ @ (cd ${MID} ; echo ')co PICOERCE.spad' | ${INTERPSYS} )
+
+@
+<<PICOERCE.spad (SPAD from IN)>>=
+${MID}/PICOERCE.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/PICOERCE.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PICOERCE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PICOERCE PiCoercions" ${IN}/expr.spad.pamphlet >PICOERCE.spad )
+
+@
+<<PMASS.o (O from NRLIB)>>=
+${OUT}/PMASS.o: ${MID}/PMASS.NRLIB
+ @ echo 0 making ${OUT}/PMASS.o from ${MID}/PMASS.NRLIB
+ @ cp ${MID}/PMASS.NRLIB/code.o ${OUT}/PMASS.o
+
+@
+<<PMASS.NRLIB (NRLIB from MID)>>=
+${MID}/PMASS.NRLIB: ${MID}/PMASS.spad
+ @ echo 0 making ${MID}/PMASS.NRLIB from ${MID}/PMASS.spad
+ @ (cd ${MID} ; echo ')co PMASS.spad' | ${INTERPSYS} )
+
+@
+<<PMASS.spad (SPAD from IN)>>=
+${MID}/PMASS.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/PMASS.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMASS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMASS PatternMatchAssertions" ${IN}/expr.spad.pamphlet >PMASS.spad )
+
+@
+<<PMASSFS.o (O from NRLIB)>>=
+${OUT}/PMASSFS.o: ${MID}/PMASSFS.NRLIB
+ @ echo 0 making ${OUT}/PMASSFS.o from ${MID}/PMASSFS.NRLIB
+ @ cp ${MID}/PMASSFS.NRLIB/code.o ${OUT}/PMASSFS.o
+
+@
+<<PMASSFS.NRLIB (NRLIB from MID)>>=
+${MID}/PMASSFS.NRLIB: ${MID}/PMASSFS.spad
+ @ echo 0 making ${MID}/PMASSFS.NRLIB from ${MID}/PMASSFS.spad
+ @ (cd ${MID} ; echo ')co PMASSFS.spad' | ${INTERPSYS} )
+
+@
+<<PMASSFS.spad (SPAD from IN)>>=
+${MID}/PMASSFS.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/PMASSFS.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMASSFS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMASSFS FunctionSpaceAssertions" ${IN}/expr.spad.pamphlet >PMASSFS.spad )
+
+@
+<<PMPRED.o (O from NRLIB)>>=
+${OUT}/PMPRED.o: ${MID}/PMPRED.NRLIB
+ @ echo 0 making ${OUT}/PMPRED.o from ${MID}/PMPRED.NRLIB
+ @ cp ${MID}/PMPRED.NRLIB/code.o ${OUT}/PMPRED.o
+
+@
+<<PMPRED.NRLIB (NRLIB from MID)>>=
+${MID}/PMPRED.NRLIB: ${MID}/PMPRED.spad
+ @ echo 0 making ${MID}/PMPRED.NRLIB from ${MID}/PMPRED.spad
+ @ (cd ${MID} ; echo ')co PMPRED.spad' | ${INTERPSYS} )
+
+@
+<<PMPRED.spad (SPAD from IN)>>=
+${MID}/PMPRED.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/PMPRED.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMPRED.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMPRED AttachPredicates" ${IN}/expr.spad.pamphlet >PMPRED.spad )
+
+@
+<<PMPREDFS.o (O from NRLIB)>>=
+${OUT}/PMPREDFS.o: ${MID}/PMPREDFS.NRLIB
+ @ echo 0 making ${OUT}/PMPREDFS.o from ${MID}/PMPREDFS.NRLIB
+ @ cp ${MID}/PMPREDFS.NRLIB/code.o ${OUT}/PMPREDFS.o
+
+@
+<<PMPREDFS.NRLIB (NRLIB from MID)>>=
+${MID}/PMPREDFS.NRLIB: ${MID}/PMPREDFS.spad
+ @ echo 0 making ${MID}/PMPREDFS.NRLIB from ${MID}/PMPREDFS.spad
+ @ (cd ${MID} ; echo ')co PMPREDFS.spad' | ${INTERPSYS} )
+
+@
+<<PMPREDFS.spad (SPAD from IN)>>=
+${MID}/PMPREDFS.spad: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${MID}/PMPREDFS.spad from ${IN}/expr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMPREDFS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMPREDFS FunctionSpaceAttachPredicates" ${IN}/expr.spad.pamphlet >PMPREDFS.spad )
+
+@
+<<expr.spad.dvi (DOC from IN)>>=
+${DOC}/expr.spad.dvi: ${IN}/expr.spad.pamphlet
+ @ echo 0 making ${DOC}/expr.spad.dvi from ${IN}/expr.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/expr.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} expr.spad ; \
+ rm -f ${DOC}/expr.spad.pamphlet ; \
+ rm -f ${DOC}/expr.spad.tex ; \
+ rm -f ${DOC}/expr.spad )
+
+@
+\subsection{f01.spad \cite{1}}
+<<f01.spad (SPAD from IN)>>=
+${MID}/f01.spad: ${IN}/f01.spad.pamphlet
+ @ echo 0 making ${MID}/f01.spad from ${IN}/f01.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/f01.spad.pamphlet >f01.spad )
+
+@
+<<NAGF01.o (O from NRLIB)>>=
+${OUT}/NAGF01.o: ${MID}/NAGF01.NRLIB
+ @ echo 0 making ${OUT}/NAGF01.o from ${MID}/NAGF01.NRLIB
+ @ cp ${MID}/NAGF01.NRLIB/code.o ${OUT}/NAGF01.o
+
+@
+<<NAGF01.NRLIB (NRLIB from MID)>>=
+${MID}/NAGF01.NRLIB: ${MID}/NAGF01.spad
+ @ echo 0 making ${MID}/NAGF01.NRLIB from ${MID}/NAGF01.spad
+ @ (cd ${MID} ; echo ')co NAGF01.spad' | ${INTERPSYS} )
+
+@
+<<NAGF01.spad (SPAD from IN)>>=
+${MID}/NAGF01.spad: ${IN}/f01.spad.pamphlet
+ @ echo 0 making ${MID}/NAGF01.spad from ${IN}/f01.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGF01.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGF01 NagMatrixOperationsPackage" ${IN}/f01.spad.pamphlet >NAGF01.spad )
+
+@
+<<f01.spad.dvi (DOC from IN)>>=
+${DOC}/f01.spad.dvi: ${IN}/f01.spad.pamphlet
+ @ echo 0 making ${DOC}/f01.spad.dvi from ${IN}/f01.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/f01.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} f01.spad ; \
+ rm -f ${DOC}/f01.spad.pamphlet ; \
+ rm -f ${DOC}/f01.spad.tex ; \
+ rm -f ${DOC}/f01.spad )
+
+@
+\subsection{f02.spad \cite{1}}
+<<f02.spad (SPAD from IN)>>=
+${MID}/f02.spad: ${IN}/f02.spad.pamphlet
+ @ echo 0 making ${MID}/f02.spad from ${IN}/f02.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/f02.spad.pamphlet >f02.spad )
+
+@
+<<NAGF02.o (O from NRLIB)>>=
+${OUT}/NAGF02.o: ${MID}/NAGF02.NRLIB
+ @ echo 0 making ${OUT}/NAGF02.o from ${MID}/NAGF02.NRLIB
+ @ cp ${MID}/NAGF02.NRLIB/code.o ${OUT}/NAGF02.o
+
+@
+<<NAGF02.NRLIB (NRLIB from MID)>>=
+${MID}/NAGF02.NRLIB: ${MID}/NAGF02.spad
+ @ echo 0 making ${MID}/NAGF02.NRLIB from ${MID}/NAGF02.spad
+ @ (cd ${MID} ; echo ')co NAGF02.spad' | ${INTERPSYS} )
+
+@
+<<NAGF02.spad (SPAD from IN)>>=
+${MID}/NAGF02.spad: ${IN}/f02.spad.pamphlet
+ @ echo 0 making ${MID}/NAGF02.spad from ${IN}/f02.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGF02.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGF02 NagEigenPackage" ${IN}/f02.spad.pamphlet >NAGF02.spad )
+
+@
+<<f02.spad.dvi (DOC from IN)>>=
+${DOC}/f02.spad.dvi: ${IN}/f02.spad.pamphlet
+ @ echo 0 making ${DOC}/f02.spad.dvi from ${IN}/f02.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/f02.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} f02.spad ; \
+ rm -f ${DOC}/f02.spad.pamphlet ; \
+ rm -f ${DOC}/f02.spad.tex ; \
+ rm -f ${DOC}/f02.spad )
+
+@
+\subsection{f04.spad \cite{1}}
+<<f04.spad (SPAD from IN)>>=
+${MID}/f04.spad: ${IN}/f04.spad.pamphlet
+ @ echo 0 making ${MID}/f04.spad from ${IN}/f04.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/f04.spad.pamphlet >f04.spad )
+
+@
+<<NAGF04.o (O from NRLIB)>>=
+${OUT}/NAGF04.o: ${MID}/NAGF04.NRLIB
+ @ echo 0 making ${OUT}/NAGF04.o from ${MID}/NAGF04.NRLIB
+ @ cp ${MID}/NAGF04.NRLIB/code.o ${OUT}/NAGF04.o
+
+@
+<<NAGF04.NRLIB (NRLIB from MID)>>=
+${MID}/NAGF04.NRLIB: ${MID}/NAGF04.spad
+ @ echo 0 making ${MID}/NAGF04.NRLIB from ${MID}/NAGF04.spad
+ @ (cd ${MID} ; echo ')co NAGF04.spad' | ${INTERPSYS} )
+
+@
+<<NAGF04.spad (SPAD from IN)>>=
+${MID}/NAGF04.spad: ${IN}/f04.spad.pamphlet
+ @ echo 0 making ${MID}/NAGF04.spad from ${IN}/f04.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGF04.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGF04 NagLinearEquationSolvingPackage" ${IN}/f04.spad.pamphlet >NAGF04.spad )
+
+@
+<<f04.spad.dvi (DOC from IN)>>=
+${DOC}/f04.spad.dvi: ${IN}/f04.spad.pamphlet
+ @ echo 0 making ${DOC}/f04.spad.dvi from ${IN}/f04.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/f04.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} f04.spad ; \
+ rm -f ${DOC}/f04.spad.pamphlet ; \
+ rm -f ${DOC}/f04.spad.tex ; \
+ rm -f ${DOC}/f04.spad )
+
+@
+\subsection{f07.spad \cite{1}}
+<<f07.spad (SPAD from IN)>>=
+${MID}/f07.spad: ${IN}/f07.spad.pamphlet
+ @ echo 0 making ${MID}/f07.spad from ${IN}/f07.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/f07.spad.pamphlet >f07.spad )
+
+@
+<<NAGF07.o (O from NRLIB)>>=
+${OUT}/NAGF07.o: ${MID}/NAGF07.NRLIB
+ @ echo 0 making ${OUT}/NAGF07.o from ${MID}/NAGF07.NRLIB
+ @ cp ${MID}/NAGF07.NRLIB/code.o ${OUT}/NAGF07.o
+
+@
+<<NAGF07.NRLIB (NRLIB from MID)>>=
+${MID}/NAGF07.NRLIB: ${MID}/NAGF07.spad
+ @ echo 0 making ${MID}/NAGF07.NRLIB from ${MID}/NAGF07.spad
+ @ (cd ${MID} ; echo ')co NAGF07.spad' | ${INTERPSYS} )
+
+@
+<<NAGF07.spad (SPAD from IN)>>=
+${MID}/NAGF07.spad: ${IN}/f07.spad.pamphlet
+ @ echo 0 making ${MID}/NAGF07.spad from ${IN}/f07.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGF07.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGF07 NagLapack" ${IN}/f07.spad.pamphlet >NAGF07.spad )
+
+@
+<<f07.spad.dvi (DOC from IN)>>=
+${DOC}/f07.spad.dvi: ${IN}/f07.spad.pamphlet
+ @ echo 0 making ${DOC}/f07.spad.dvi from ${IN}/f07.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/f07.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} f07.spad ; \
+ rm -f ${DOC}/f07.spad.pamphlet ; \
+ rm -f ${DOC}/f07.spad.tex ; \
+ rm -f ${DOC}/f07.spad )
+
+@
+\subsection{facutil.spad \cite{1}}
+<<facutil.spad (SPAD from IN)>>=
+${MID}/facutil.spad: ${IN}/facutil.spad.pamphlet
+ @ echo 0 making ${MID}/facutil.spad from ${IN}/facutil.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/facutil.spad.pamphlet >facutil.spad )
+
+@
+<<FACUTIL.o (O from NRLIB)>>=
+${OUT}/FACUTIL.o: ${MID}/FACUTIL.NRLIB
+ @ echo 0 making ${OUT}/FACUTIL.o from ${MID}/FACUTIL.NRLIB
+ @ cp ${MID}/FACUTIL.NRLIB/code.o ${OUT}/FACUTIL.o
+
+@
+<<FACUTIL.NRLIB (NRLIB from MID)>>=
+${MID}/FACUTIL.NRLIB: ${MID}/FACUTIL.spad
+ @ echo 0 making ${MID}/FACUTIL.NRLIB from ${MID}/FACUTIL.spad
+ @ (cd ${MID} ; echo ')co FACUTIL.spad' | ${INTERPSYS} )
+
+@
+<<FACUTIL.spad (SPAD from IN)>>=
+${MID}/FACUTIL.spad: ${IN}/facutil.spad.pamphlet
+ @ echo 0 making ${MID}/FACUTIL.spad from ${IN}/facutil.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FACUTIL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FACUTIL FactoringUtilities" ${IN}/facutil.spad.pamphlet >FACUTIL.spad )
+
+@
+<<PUSHVAR.o (O from NRLIB)>>=
+${OUT}/PUSHVAR.o: ${MID}/PUSHVAR.NRLIB
+ @ echo 0 making ${OUT}/PUSHVAR.o from ${MID}/PUSHVAR.NRLIB
+ @ cp ${MID}/PUSHVAR.NRLIB/code.o ${OUT}/PUSHVAR.o
+
+@
+<<PUSHVAR.NRLIB (NRLIB from MID)>>=
+${MID}/PUSHVAR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PUSHVAR.spad
+ @ echo 0 making ${MID}/PUSHVAR.NRLIB from ${MID}/PUSHVAR.spad
+ @ (cd ${MID} ; echo ')co PUSHVAR.spad' | ${INTERPSYS} )
+
+@
+<<PUSHVAR.spad (SPAD from IN)>>=
+${MID}/PUSHVAR.spad: ${IN}/facutil.spad.pamphlet
+ @ echo 0 making ${MID}/PUSHVAR.spad from ${IN}/facutil.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PUSHVAR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PUSHVAR PushVariables" ${IN}/facutil.spad.pamphlet >PUSHVAR.spad )
+
+@
+<<facutil.spad.dvi (DOC from IN)>>=
+${DOC}/facutil.spad.dvi: ${IN}/facutil.spad.pamphlet
+ @ echo 0 making ${DOC}/facutil.spad.dvi from ${IN}/facutil.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/facutil.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} facutil.spad ; \
+ rm -f ${DOC}/facutil.spad.pamphlet ; \
+ rm -f ${DOC}/facutil.spad.tex ; \
+ rm -f ${DOC}/facutil.spad )
+
+@
+\subsection{ffcat.spad \cite{1}}
+<<ffcat.spad (SPAD from IN)>>=
+${MID}/ffcat.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/ffcat.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffcat.spad.pamphlet >ffcat.spad )
+
+@
+<<DLP.o (O from NRLIB)>>=
+${OUT}/DLP.o: ${MID}/DLP.NRLIB
+ @ echo 0 making ${OUT}/DLP.o from ${MID}/DLP.NRLIB
+ @ cp ${MID}/DLP.NRLIB/code.o ${OUT}/DLP.o
+
+@
+<<DLP.NRLIB (NRLIB from MID)>>=
+${MID}/DLP.NRLIB: ${MID}/DLP.spad
+ @ echo 0 making ${MID}/DLP.NRLIB from ${MID}/DLP.spad
+ @ (cd ${MID} ; echo ')co DLP.spad' | ${INTERPSYS} )
+
+@
+<<DLP.spad (SPAD from IN)>>=
+${MID}/DLP.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/DLP.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DLP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DLP DiscreteLogarithmPackage" ${IN}/ffcat.spad.pamphlet >DLP.spad )
+
+@
+<<FAXF-.o (O from NRLIB)>>=
+${OUT}/FAXF-.o: ${MID}/FAXF.NRLIB
+ @ echo 0 making ${OUT}/FAXF-.o from ${MID}/FAXF-.NRLIB
+ @ cp ${MID}/FAXF-.NRLIB/code.o ${OUT}/FAXF-.o
+
+@
+<<FAXF-.NRLIB (NRLIB from MID)>>=
+${MID}/FAXF-.NRLIB: ${OUT}/TYPE.o ${MID}/FAXF.spad
+ @ echo 0 making ${MID}/FAXF-.NRLIB from ${MID}/FAXF.spad
+ @ (cd ${MID} ; echo ')co FAXF.spad' | ${INTERPSYS} )
+
+@
+<<FAXF.o (O from NRLIB)>>=
+${OUT}/FAXF.o: ${MID}/FAXF.NRLIB
+ @ echo 0 making ${OUT}/FAXF.o from ${MID}/FAXF.NRLIB
+ @ cp ${MID}/FAXF.NRLIB/code.o ${OUT}/FAXF.o
+
+@
+<<FAXF.NRLIB (NRLIB from MID)>>=
+${MID}/FAXF.NRLIB: ${MID}/FAXF.spad
+ @ echo 0 making ${MID}/FAXF.NRLIB from ${MID}/FAXF.spad
+ @ (cd ${MID} ; echo ')co FAXF.spad' | ${INTERPSYS} )
+
+@
+<<FAXF.spad (SPAD from IN)>>=
+${MID}/FAXF.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/FAXF.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FAXF.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FAXF FiniteAlgebraicExtensionField" ${IN}/ffcat.spad.pamphlet >FAXF.spad )
+
+@
+<<FFIELDC-.o (O from NRLIB)>>=
+${OUT}/FFIELDC-.o: ${MID}/FFIELDC.NRLIB
+ @ echo 0 making ${OUT}/FFIELDC-.o from ${MID}/FFIELDC-.NRLIB
+ @ cp ${MID}/FFIELDC-.NRLIB/code.o ${OUT}/FFIELDC-.o
+
+@
+<<FFIELDC-.NRLIB (NRLIB from MID)>>=
+${MID}/FFIELDC-.NRLIB: ${OUT}/TYPE.o ${MID}/FFIELDC.spad
+ @ echo 0 making ${MID}/FFIELDC-.NRLIB from ${MID}/FFIELDC.spad
+ @ (cd ${MID} ; echo ')co FFIELDC.spad' | ${INTERPSYS} )
+
+@
+<<FFIELDC.o (O from NRLIB)>>=
+${OUT}/FFIELDC.o: ${MID}/FFIELDC.NRLIB
+ @ echo 0 making ${OUT}/FFIELDC.o from ${MID}/FFIELDC.NRLIB
+ @ cp ${MID}/FFIELDC.NRLIB/code.o ${OUT}/FFIELDC.o
+
+@
+<<FFIELDC.NRLIB (NRLIB from MID)>>=
+${MID}/FFIELDC.NRLIB: ${MID}/FFIELDC.spad
+ @ echo 0 making ${MID}/FFIELDC.NRLIB from ${MID}/FFIELDC.spad
+ @ (cd ${MID} ; echo ')co FFIELDC.spad' | ${INTERPSYS} )
+
+@
+<<FFIELDC.spad (SPAD from IN)>>=
+${MID}/FFIELDC.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/FFIELDC.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFIELDC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FFIELDC FiniteFieldCategory" ${IN}/ffcat.spad.pamphlet >FFIELDC.spad )
+
+@
+<<FFIELDC-.o (BOOTSTRAP from MID)>>=
+${MID}/FFIELDC-.o: ${MID}/FFIELDC-.lsp
+ @ echo 0 making ${MID}/FFIELDC-.o from ${MID}/FFIELDC-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "FFIELDC-.lsp" :output-file "FFIELDC-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/FFIELDC-.o ${OUT}/FFIELDC-.o
+
+@
+<<FFIELDC-.lsp (LISP from IN)>>=
+${MID}/FFIELDC-.lsp: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/FFIELDC-.lsp from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFIELDC-.NRLIB ; \
+ rm -rf ${OUT}/FFIELDC-.o ; \
+ ${SPADBIN}/notangle -R"FFIELDC-.lsp BOOTSTRAP" ${IN}/ffcat.spad.pamphlet >FFIELDC-.lsp )
+
+@
+<<FFIELDC.o (BOOTSTRAP from MID)>>=
+${MID}/FFIELDC.o: ${MID}/FFIELDC.lsp
+ @ echo 0 making ${MID}/FFIELDC.o from ${MID}/FFIELDC.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "FFIELDC.lsp" :output-file "FFIELDC.o"))' | ${DEPSYS} )
+ @ cp ${MID}/FFIELDC.o ${OUT}/FFIELDC.o
+
+@
+<<FFIELDC.lsp (LISP from IN)>>=
+${MID}/FFIELDC.lsp: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/FFIELDC.lsp from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFIELDC.NRLIB ; \
+ rm -rf ${OUT}/FFIELDC.o ; \
+ ${SPADBIN}/notangle -R"FFIELDC.lsp BOOTSTRAP" ${IN}/ffcat.spad.pamphlet >FFIELDC.lsp )
+
+@
+<<FFSLPE.o (O from NRLIB)>>=
+${OUT}/FFSLPE.o: ${MID}/FFSLPE.NRLIB
+ @ echo 0 making ${OUT}/FFSLPE.o from ${MID}/FFSLPE.NRLIB
+ @ cp ${MID}/FFSLPE.NRLIB/code.o ${OUT}/FFSLPE.o
+
+@
+<<FFSLPE.NRLIB (NRLIB from MID)>>=
+${MID}/FFSLPE.NRLIB: ${MID}/FFSLPE.spad
+ @ echo 0 making ${MID}/FFSLPE.NRLIB from ${MID}/FFSLPE.spad
+ @ (cd ${MID} ; echo ')co FFSLPE.spad' | ${INTERPSYS} )
+
+@
+<<FFSLPE.spad (SPAD from IN)>>=
+${MID}/FFSLPE.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/FFSLPE.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFSLPE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFSLPE FiniteFieldSolveLinearPolynomialEquation" ${IN}/ffcat.spad.pamphlet >FFSLPE.spad )
+
+@
+<<FPC-.o (O from NRLIB)>>=
+${OUT}/FPC-.o: ${MID}/FPC.NRLIB
+ @ echo 0 making ${OUT}/FPC-.o from ${MID}/FPC-.NRLIB
+ @ cp ${MID}/FPC-.NRLIB/code.o ${OUT}/FPC-.o
+
+@
+<<FPC-.NRLIB (NRLIB from MID)>>=
+${MID}/FPC-.NRLIB: ${OUT}/TYPE.o ${MID}/FPC.spad
+ @ echo 0 making ${MID}/FPC-.NRLIB from ${MID}/FPC.spad
+ @ (cd ${MID} ; echo ')co FPC.spad' | ${INTERPSYS} )
+
+@
+<<FPC.o (O from NRLIB)>>=
+${OUT}/FPC.o: ${MID}/FPC.NRLIB
+ @ echo 0 making ${OUT}/FPC.o from ${MID}/FPC.NRLIB
+ @ cp ${MID}/FPC.NRLIB/code.o ${OUT}/FPC.o
+
+@
+<<FPC.NRLIB (NRLIB from MID)>>=
+${MID}/FPC.NRLIB: ${MID}/FPC.spad
+ @ echo 0 making ${MID}/FPC.NRLIB from ${MID}/FPC.spad
+ @ (cd ${MID} ; echo ')co FPC.spad' | ${INTERPSYS} )
+
+@
+<<FPC.spad (SPAD from IN)>>=
+${MID}/FPC.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/FPC.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FPC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FPC FieldOfPrimeCharacteristic" ${IN}/ffcat.spad.pamphlet >FPC.spad )
+
+@
+<<XF-.o (O from NRLIB)>>=
+${OUT}/XF-.o: ${MID}/XF.NRLIB
+ @ echo 0 making ${OUT}/XF-.o from ${MID}/XF-.NRLIB
+ @ cp ${MID}/XF-.NRLIB/code.o ${OUT}/XF-.o
+
+@
+<<XF-.NRLIB (NRLIB from MID)>>=
+${MID}/XF-.NRLIB: ${OUT}/TYPE.o ${MID}/XF.spad
+ @ echo 0 making ${MID}/XF-.NRLIB from ${MID}/XF.spad
+ @ (cd ${MID} ; echo ')co XF.spad' | ${INTERPSYS} )
+
+@
+<<XF.o (O from NRLIB)>>=
+${OUT}/XF.o: ${MID}/XF.NRLIB
+ @ echo 0 making ${OUT}/XF.o from ${MID}/XF.NRLIB
+ @ cp ${MID}/XF.NRLIB/code.o ${OUT}/XF.o
+
+@
+<<XF.NRLIB (NRLIB from MID)>>=
+${MID}/XF.NRLIB: ${MID}/XF.spad
+ @ echo 0 making ${MID}/XF.NRLIB from ${MID}/XF.spad
+ @ (cd ${MID} ; echo ')co XF.spad' | ${INTERPSYS} )
+
+@
+<<XF.spad (SPAD from IN)>>=
+${MID}/XF.spad: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${MID}/XF.spad from ${IN}/ffcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XF.NRLIB ; \
+ ${SPADBIN}/notangle -R"category XF ExtensionField" ${IN}/ffcat.spad.pamphlet >XF.spad )
+
+@
+<<ffcat.spad.dvi (DOC from IN)>>=
+${DOC}/ffcat.spad.dvi: ${IN}/ffcat.spad.pamphlet
+ @ echo 0 making ${DOC}/ffcat.spad.dvi from ${IN}/ffcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffcat.spad ; \
+ rm -f ${DOC}/ffcat.spad.pamphlet ; \
+ rm -f ${DOC}/ffcat.spad.tex ; \
+ rm -f ${DOC}/ffcat.spad )
+
+@
+\subsection{ffcg.spad \cite{1}}
+<<ffcg.spad (SPAD from IN)>>=
+${MID}/ffcg.spad: ${IN}/ffcg.spad.pamphlet
+ @ echo 0 making ${MID}/ffcg.spad from ${IN}/ffcg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffcg.spad.pamphlet >ffcg.spad )
+
+@
+<<FFCG.o (O from NRLIB)>>=
+${OUT}/FFCG.o: ${MID}/FFCG.NRLIB
+ @ echo 0 making ${OUT}/FFCG.o from ${MID}/FFCG.NRLIB
+ @ cp ${MID}/FFCG.NRLIB/code.o ${OUT}/FFCG.o
+
+@
+<<FFCG.NRLIB (NRLIB from MID)>>=
+${MID}/FFCG.NRLIB: ${MID}/FFCG.spad
+ @ echo 0 making ${MID}/FFCG.NRLIB from ${MID}/FFCG.spad
+ @ (cd ${MID} ; echo ')co FFCG.spad' | ${INTERPSYS} )
+
+@
+<<FFCG.spad (SPAD from IN)>>=
+${MID}/FFCG.spad: ${IN}/ffcg.spad.pamphlet
+ @ echo 0 making ${MID}/FFCG.spad from ${IN}/ffcg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFCG.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFCG FiniteFieldCyclicGroup" ${IN}/ffcg.spad.pamphlet >FFCG.spad )
+
+@
+<<FFCGP.o (O from NRLIB)>>=
+${OUT}/FFCGP.o: ${MID}/FFCGP.NRLIB
+ @ echo 0 making ${OUT}/FFCGP.o from ${MID}/FFCGP.NRLIB
+ @ cp ${MID}/FFCGP.NRLIB/code.o ${OUT}/FFCGP.o
+
+@
+<<FFCGP.NRLIB (NRLIB from MID)>>=
+${MID}/FFCGP.NRLIB: ${MID}/FFCGP.spad
+ @ echo 0 making ${MID}/FFCGP.NRLIB from ${MID}/FFCGP.spad
+ @ (cd ${MID} ; echo ')co FFCGP.spad' | ${INTERPSYS} )
+
+@
+<<FFCGP.spad (SPAD from IN)>>=
+${MID}/FFCGP.spad: ${IN}/ffcg.spad.pamphlet
+ @ echo 0 making ${MID}/FFCGP.spad from ${IN}/ffcg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFCGP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFCGP FiniteFieldCyclicGroupExtensionByPolynomial" ${IN}/ffcg.spad.pamphlet >FFCGP.spad )
+
+@
+<<FFCGX.o (O from NRLIB)>>=
+${OUT}/FFCGX.o: ${MID}/FFCGX.NRLIB
+ @ echo 0 making ${OUT}/FFCGX.o from ${MID}/FFCGX.NRLIB
+ @ cp ${MID}/FFCGX.NRLIB/code.o ${OUT}/FFCGX.o
+
+@
+<<FFCGX.NRLIB (NRLIB from MID)>>=
+${MID}/FFCGX.NRLIB: ${MID}/FFCGX.spad
+ @ echo 0 making ${MID}/FFCGX.NRLIB from ${MID}/FFCGX.spad
+ @ (cd ${MID} ; echo ')co FFCGX.spad' | ${INTERPSYS} )
+
+@
+<<FFCGX.spad (SPAD from IN)>>=
+${MID}/FFCGX.spad: ${IN}/ffcg.spad.pamphlet
+ @ echo 0 making ${MID}/FFCGX.spad from ${IN}/ffcg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFCGX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFCGX FiniteFieldCyclicGroupExtension" ${IN}/ffcg.spad.pamphlet >FFCGX.spad )
+
+@
+<<ffcg.spad.dvi (DOC from IN)>>=
+${DOC}/ffcg.spad.dvi: ${IN}/ffcg.spad.pamphlet
+ @ echo 0 making ${DOC}/ffcg.spad.dvi from ${IN}/ffcg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffcg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffcg.spad ; \
+ rm -f ${DOC}/ffcg.spad.pamphlet ; \
+ rm -f ${DOC}/ffcg.spad.tex ; \
+ rm -f ${DOC}/ffcg.spad )
+
+@
+\subsection{fff.spad \cite{1}}
+<<fff.spad (SPAD from IN)>>=
+${MID}/fff.spad: ${IN}/fff.spad.pamphlet
+ @ echo 0 making ${MID}/fff.spad from ${IN}/fff.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fff.spad.pamphlet >fff.spad )
+
+@
+<<FFF.o (O from NRLIB)>>=
+${OUT}/FFF.o: ${MID}/FFF.NRLIB
+ @ echo 0 making ${OUT}/FFF.o from ${MID}/FFF.NRLIB
+ @ cp ${MID}/FFF.NRLIB/code.o ${OUT}/FFF.o
+
+@
+<<FFF.NRLIB (NRLIB from MID)>>=
+${MID}/FFF.NRLIB: ${MID}/FFF.spad
+ @ echo 0 making ${MID}/FFF.NRLIB from ${MID}/FFF.spad
+ @ (cd ${MID} ; echo ')co FFF.spad' | ${INTERPSYS} )
+
+@
+<<FFF.spad (SPAD from IN)>>=
+${MID}/FFF.spad: ${IN}/fff.spad.pamphlet
+ @ echo 0 making ${MID}/FFF.spad from ${IN}/fff.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFF FiniteFieldFunctions" ${IN}/fff.spad.pamphlet >FFF.spad )
+
+@
+<<fff.spad.dvi (DOC from IN)>>=
+${DOC}/fff.spad.dvi: ${IN}/fff.spad.pamphlet
+ @ echo 0 making ${DOC}/fff.spad.dvi from ${IN}/fff.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fff.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fff.spad ; \
+ rm -f ${DOC}/fff.spad.pamphlet ; \
+ rm -f ${DOC}/fff.spad.tex ; \
+ rm -f ${DOC}/fff.spad )
+
+@
+\subsection{ffhom.spad \cite{1}}
+<<ffhom.spad (SPAD from IN)>>=
+${MID}/ffhom.spad: ${IN}/ffhom.spad.pamphlet
+ @ echo 0 making ${MID}/ffhom.spad from ${IN}/ffhom.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffhom.spad.pamphlet >ffhom.spad )
+
+@
+<<FFHOM.o (O from NRLIB)>>=
+${OUT}/FFHOM.o: ${MID}/FFHOM.NRLIB
+ @ echo 0 making ${OUT}/FFHOM.o from ${MID}/FFHOM.NRLIB
+ @ cp ${MID}/FFHOM.NRLIB/code.o ${OUT}/FFHOM.o
+
+@
+<<FFHOM.NRLIB (NRLIB from MID)>>=
+${MID}/FFHOM.NRLIB: ${MID}/FFHOM.spad
+ @ echo 0 making ${MID}/FFHOM.NRLIB from ${MID}/FFHOM.spad
+ @ (cd ${MID} ; echo ')co FFHOM.spad' | ${INTERPSYS} )
+
+@
+<<FFHOM.spad (SPAD from IN)>>=
+${MID}/FFHOM.spad: ${IN}/ffhom.spad.pamphlet
+ @ echo 0 making ${MID}/FFHOM.spad from ${IN}/ffhom.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFHOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFHOM FiniteFieldHomomorphisms" ${IN}/ffhom.spad.pamphlet >FFHOM.spad )
+
+@
+<<ffhom.spad.dvi (DOC from IN)>>=
+${DOC}/ffhom.spad.dvi: ${IN}/ffhom.spad.pamphlet
+ @ echo 0 making ${DOC}/ffhom.spad.dvi from ${IN}/ffhom.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffhom.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffhom.spad ; \
+ rm -f ${DOC}/ffhom.spad.pamphlet ; \
+ rm -f ${DOC}/ffhom.spad.tex ; \
+ rm -f ${DOC}/ffhom.spad )
+
+@
+\subsection{ffnb.spad \cite{1}}
+<<ffnb.spad (SPAD from IN)>>=
+${MID}/ffnb.spad: ${IN}/ffnb.spad.pamphlet
+ @ echo 0 making ${MID}/ffnb.spad from ${IN}/ffnb.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffnb.spad.pamphlet >ffnb.spad )
+
+@
+<<FFNB.o (O from NRLIB)>>=
+${OUT}/FFNB.o: ${MID}/FFNB.NRLIB
+ @ echo 0 making ${OUT}/FFNB.o from ${MID}/FFNB.NRLIB
+ @ cp ${MID}/FFNB.NRLIB/code.o ${OUT}/FFNB.o
+
+@
+<<FFNB.NRLIB (NRLIB from MID)>>=
+${MID}/FFNB.NRLIB: ${MID}/FFNB.spad
+ @ echo 0 making ${MID}/FFNB.NRLIB from ${MID}/FFNB.spad
+ @ (cd ${MID} ; echo ')co FFNB.spad' | ${INTERPSYS} )
+
+@
+<<FFNB.spad (SPAD from IN)>>=
+${MID}/FFNB.spad: ${IN}/ffnb.spad.pamphlet
+ @ echo 0 making ${MID}/FFNB.spad from ${IN}/ffnb.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFNB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFNB FiniteFieldNormalBasis" ${IN}/ffnb.spad.pamphlet >FFNB.spad )
+
+@
+<<FFNBP.o (O from NRLIB)>>=
+${OUT}/FFNBP.o: ${MID}/FFNBP.NRLIB
+ @ echo 0 making ${OUT}/FFNBP.o from ${MID}/FFNBP.NRLIB
+ @ cp ${MID}/FFNBP.NRLIB/code.o ${OUT}/FFNBP.o
+
+@
+<<FFNBP.NRLIB (NRLIB from MID)>>=
+${MID}/FFNBP.NRLIB: ${MID}/FFNBP.spad
+ @ echo 0 making ${MID}/FFNBP.NRLIB from ${MID}/FFNBP.spad
+ @ (cd ${MID} ; echo ')co FFNBP.spad' | ${INTERPSYS} )
+
+@
+<<FFNBP.spad (SPAD from IN)>>=
+${MID}/FFNBP.spad: ${IN}/ffnb.spad.pamphlet
+ @ echo 0 making ${MID}/FFNBP.spad from ${IN}/ffnb.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFNBP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFNBP FiniteFieldNormalBasisExtensionByPolynomial" ${IN}/ffnb.spad.pamphlet >FFNBP.spad )
+
+@
+<<FFNBX.o (O from NRLIB)>>=
+${OUT}/FFNBX.o: ${MID}/FFNBX.NRLIB
+ @ echo 0 making ${OUT}/FFNBX.o from ${MID}/FFNBX.NRLIB
+ @ cp ${MID}/FFNBX.NRLIB/code.o ${OUT}/FFNBX.o
+
+@
+<<FFNBX.NRLIB (NRLIB from MID)>>=
+${MID}/FFNBX.NRLIB: ${MID}/FFNBX.spad
+ @ echo 0 making ${MID}/FFNBX.NRLIB from ${MID}/FFNBX.spad
+ @ (cd ${MID} ; echo ')co FFNBX.spad' | ${INTERPSYS} )
+
+@
+<<FFNBX.spad (SPAD from IN)>>=
+${MID}/FFNBX.spad: ${IN}/ffnb.spad.pamphlet
+ @ echo 0 making ${MID}/FFNBX.spad from ${IN}/ffnb.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFNBX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFNBX FiniteFieldNormalBasisExtension" ${IN}/ffnb.spad.pamphlet >FFNBX.spad )
+
+@
+<<ffnb.spad.dvi (DOC from IN)>>=
+${DOC}/ffnb.spad.dvi: ${IN}/ffnb.spad.pamphlet
+ @ echo 0 making ${DOC}/ffnb.spad.dvi from ${IN}/ffnb.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffnb.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffnb.spad ; \
+ rm -f ${DOC}/ffnb.spad.pamphlet ; \
+ rm -f ${DOC}/ffnb.spad.tex ; \
+ rm -f ${DOC}/ffnb.spad )
+
+@
+\subsection{ffpoly2.spad \cite{1}}
+<<ffpoly2.spad (SPAD from IN)>>=
+${MID}/ffpoly2.spad: ${IN}/ffpoly2.spad.pamphlet
+ @ echo 0 making ${MID}/ffpoly2.spad from ${IN}/ffpoly2.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffpoly2.spad.pamphlet >ffpoly2.spad )
+
+@
+<<FFPOLY2.o (O from NRLIB)>>=
+${OUT}/FFPOLY2.o: ${MID}/FFPOLY2.NRLIB
+ @ echo 0 making ${OUT}/FFPOLY2.o from ${MID}/FFPOLY2.NRLIB
+ @ cp ${MID}/FFPOLY2.NRLIB/code.o ${OUT}/FFPOLY2.o
+
+@
+<<FFPOLY2.NRLIB (NRLIB from MID)>>=
+${MID}/FFPOLY2.NRLIB: ${MID}/FFPOLY2.spad
+ @ echo 0 making ${MID}/FFPOLY2.NRLIB from ${MID}/FFPOLY2.spad
+ @ (cd ${MID} ; echo ')co FFPOLY2.spad' | ${INTERPSYS} )
+
+@
+<<FFPOLY2.spad (SPAD from IN)>>=
+${MID}/FFPOLY2.spad: ${IN}/ffpoly2.spad.pamphlet
+ @ echo 0 making ${MID}/FFPOLY2.spad from ${IN}/ffpoly2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFPOLY2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFPOLY2 FiniteFieldPolynomialPackage2" ${IN}/ffpoly2.spad.pamphlet >FFPOLY2.spad )
+
+@
+<<ffpoly2.spad.dvi (DOC from IN)>>=
+${DOC}/ffpoly2.spad.dvi: ${IN}/ffpoly2.spad.pamphlet
+ @ echo 0 making ${DOC}/ffpoly2.spad.dvi from ${IN}/ffpoly2.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffpoly2.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffpoly2.spad ; \
+ rm -f ${DOC}/ffpoly2.spad.pamphlet ; \
+ rm -f ${DOC}/ffpoly2.spad.tex ; \
+ rm -f ${DOC}/ffpoly2.spad )
+
+@
+\subsection{ffpoly.spad \cite{1}}
+<<ffpoly.spad (SPAD from IN)>>=
+${MID}/ffpoly.spad: ${IN}/ffpoly.spad.pamphlet
+ @ echo 0 making ${MID}/ffpoly.spad from ${IN}/ffpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffpoly.spad.pamphlet >ffpoly.spad )
+
+@
+<<FFPOLY.o (O from NRLIB)>>=
+${OUT}/FFPOLY.o: ${MID}/FFPOLY.NRLIB
+ @ echo 0 making ${OUT}/FFPOLY.o from ${MID}/FFPOLY.NRLIB
+ @ cp ${MID}/FFPOLY.NRLIB/code.o ${OUT}/FFPOLY.o
+
+@
+<<FFPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/FFPOLY.NRLIB: ${MID}/FFPOLY.spad
+ @ echo 0 making ${MID}/FFPOLY.NRLIB from ${MID}/FFPOLY.spad
+ @ (cd ${MID} ; echo ')co FFPOLY.spad' | ${INTERPSYS} )
+
+@
+<<FFPOLY.spad (SPAD from IN)>>=
+${MID}/FFPOLY.spad: ${IN}/ffpoly.spad.pamphlet
+ @ echo 0 making ${MID}/FFPOLY.spad from ${IN}/ffpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFPOLY FiniteFieldPolynomialPackage" ${IN}/ffpoly.spad.pamphlet >FFPOLY.spad )
+
+@
+<<ffpoly.spad.dvi (DOC from IN)>>=
+${DOC}/ffpoly.spad.dvi: ${IN}/ffpoly.spad.pamphlet
+ @ echo 0 making ${DOC}/ffpoly.spad.dvi from ${IN}/ffpoly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffpoly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffpoly.spad ; \
+ rm -f ${DOC}/ffpoly.spad.pamphlet ; \
+ rm -f ${DOC}/ffpoly.spad.tex ; \
+ rm -f ${DOC}/ffpoly.spad )
+
+@
+\subsection{ffp.spad \cite{1}}
+<<ffp.spad (SPAD from IN)>>=
+${MID}/ffp.spad: ${IN}/ffp.spad.pamphlet
+ @ echo 0 making ${MID}/ffp.spad from ${IN}/ffp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffp.spad.pamphlet >ffp.spad )
+
+@
+<<IFF.o (O from NRLIB)>>=
+${OUT}/IFF.o: ${MID}/IFF.NRLIB
+ @ echo 0 making ${OUT}/IFF.o from ${MID}/IFF.NRLIB
+ @ cp ${MID}/IFF.NRLIB/code.o ${OUT}/IFF.o
+
+@
+<<IFF.NRLIB (NRLIB from MID)>>=
+${MID}/IFF.NRLIB: ${MID}/IFF.spad
+ @ echo 0 making ${MID}/IFF.NRLIB from ${MID}/IFF.spad
+ @ (cd ${MID} ; echo ')co IFF.spad' | ${INTERPSYS} )
+
+@
+<<IFF.spad (SPAD from IN)>>=
+${MID}/IFF.spad: ${IN}/ffp.spad.pamphlet
+ @ echo 0 making ${MID}/IFF.spad from ${IN}/ffp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IFF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IFF InnerFiniteField" ${IN}/ffp.spad.pamphlet >IFF.spad )
+
+@
+<<FF.o (O from NRLIB)>>=
+${OUT}/FF.o: ${MID}/FF.NRLIB
+ @ echo 0 making ${OUT}/FF.o from ${MID}/FF.NRLIB
+ @ cp ${MID}/FF.NRLIB/code.o ${OUT}/FF.o
+
+@
+<<FF.NRLIB (NRLIB from MID)>>=
+${MID}/FF.NRLIB: ${MID}/FF.spad
+ @ echo 0 making ${MID}/FF.NRLIB from ${MID}/FF.spad
+ @ (cd ${MID} ; echo ')co FF.spad' | ${INTERPSYS} )
+
+@
+<<FF.spad (SPAD from IN)>>=
+${MID}/FF.spad: ${IN}/ffp.spad.pamphlet
+ @ echo 0 making ${MID}/FF.spad from ${IN}/ffp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FF FiniteField" ${IN}/ffp.spad.pamphlet >FF.spad )
+
+@
+<<FFP.o (O from NRLIB)>>=
+${OUT}/FFP.o: ${MID}/FFP.NRLIB
+ @ echo 0 making ${OUT}/FFP.o from ${MID}/FFP.NRLIB
+ @ cp ${MID}/FFP.NRLIB/code.o ${OUT}/FFP.o
+
+@
+<<FFP.NRLIB (NRLIB from MID)>>=
+${MID}/FFP.NRLIB: ${MID}/FFP.spad
+ @ echo 0 making ${MID}/FFP.NRLIB from ${MID}/FFP.spad
+ @ (cd ${MID} ; echo ')co FFP.spad' | ${INTERPSYS} )
+
+@
+<<FFP.spad (SPAD from IN)>>=
+${MID}/FFP.spad: ${IN}/ffp.spad.pamphlet
+ @ echo 0 making ${MID}/FFP.spad from ${IN}/ffp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFP FiniteFieldExtensionByPolynomial" ${IN}/ffp.spad.pamphlet >FFP.spad )
+
+@
+<<FFX.o (O from NRLIB)>>=
+${OUT}/FFX.o: ${MID}/FFX.NRLIB
+ @ echo 0 making ${OUT}/FFX.o from ${MID}/FFX.NRLIB
+ @ cp ${MID}/FFX.NRLIB/code.o ${OUT}/FFX.o
+
+@
+<<FFX.NRLIB (NRLIB from MID)>>=
+${MID}/FFX.NRLIB: ${MID}/FFX.spad
+ @ echo 0 making ${MID}/FFX.NRLIB from ${MID}/FFX.spad
+ @ (cd ${MID} ; echo ')co FFX.spad' | ${INTERPSYS} )
+
+@
+<<FFX.spad (SPAD from IN)>>=
+${MID}/FFX.spad: ${IN}/ffp.spad.pamphlet
+ @ echo 0 making ${MID}/FFX.spad from ${IN}/ffp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FFX FiniteFieldExtension" ${IN}/ffp.spad.pamphlet >FFX.spad )
+
+@
+<<ffp.spad.dvi (DOC from IN)>>=
+${DOC}/ffp.spad.dvi: ${IN}/ffp.spad.pamphlet
+ @ echo 0 making ${DOC}/ffp.spad.dvi from ${IN}/ffp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffp.spad ; \
+ rm -f ${DOC}/ffp.spad.pamphlet ; \
+ rm -f ${DOC}/ffp.spad.tex ; \
+ rm -f ${DOC}/ffp.spad )
+
+@
+\subsection{ffrac.as \cite{1}}
+<<ffrac.as (SPAD from IN)>>=
+${MID}/ffrac.as: ${IN}/ffrac.as.pamphlet
+ @ echo 0 making ${MID}/ffrac.as from ${IN}/ffrac.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffrac.as.pamphlet >ffrac.as )
+
+@
+<<ffrac.as.dvi (DOC from IN)>>=
+${DOC}/ffrac.as.dvi: ${IN}/ffrac.as.pamphlet
+ @ echo 0 making ${DOC}/ffrac.as.dvi from ${IN}/ffrac.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffrac.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffrac.as ; \
+ rm -f ${DOC}/ffrac.as.pamphlet ; \
+ rm -f ${DOC}/ffrac.as.tex ; \
+ rm -f ${DOC}/ffrac.as )
+
+@
+\subsection{ffx.spad \cite{1}}
+<<ffx.spad (SPAD from IN)>>=
+${MID}/ffx.spad: ${IN}/ffx.spad.pamphlet
+ @ echo 0 making ${MID}/ffx.spad from ${IN}/ffx.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ffx.spad.pamphlet >ffx.spad )
+
+@
+<<IRREDFFX.o (O from NRLIB)>>=
+${OUT}/IRREDFFX.o: ${MID}/IRREDFFX.NRLIB
+ @ echo 0 making ${OUT}/IRREDFFX.o from ${MID}/IRREDFFX.NRLIB
+ @ cp ${MID}/IRREDFFX.NRLIB/code.o ${OUT}/IRREDFFX.o
+
+@
+<<IRREDFFX.NRLIB (NRLIB from MID)>>=
+${MID}/IRREDFFX.NRLIB: ${MID}/IRREDFFX.spad
+ @ echo 0 making ${MID}/IRREDFFX.NRLIB from ${MID}/IRREDFFX.spad
+ @ (cd ${MID} ; echo ')co IRREDFFX.spad' | ${INTERPSYS} )
+
+@
+<<IRREDFFX.spad (SPAD from IN)>>=
+${MID}/IRREDFFX.spad: ${IN}/ffx.spad.pamphlet
+ @ echo 0 making ${MID}/IRREDFFX.spad from ${IN}/ffx.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IRREDFFX.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IRREDFFX IrredPolyOverFiniteField" ${IN}/ffx.spad.pamphlet >IRREDFFX.spad )
+
+@
+<<ffx.spad.dvi (DOC from IN)>>=
+${DOC}/ffx.spad.dvi: ${IN}/ffx.spad.pamphlet
+ @ echo 0 making ${DOC}/ffx.spad.dvi from ${IN}/ffx.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ffx.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ffx.spad ; \
+ rm -f ${DOC}/ffx.spad.pamphlet ; \
+ rm -f ${DOC}/ffx.spad.tex ; \
+ rm -f ${DOC}/ffx.spad )
+
+@
+\subsection{files.spad \cite{1}}
+<<files.spad (SPAD from IN)>>=
+${MID}/files.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/files.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/files.spad.pamphlet >files.spad )
+
+@
+<<BINFILE.o (O from NRLIB)>>=
+${OUT}/BINFILE.o: ${MID}/BINFILE.NRLIB
+ @ echo 0 making ${OUT}/BINFILE.o from ${MID}/BINFILE.NRLIB
+ @ cp ${MID}/BINFILE.NRLIB/code.o ${OUT}/BINFILE.o
+
+@
+<<BINFILE.NRLIB (NRLIB from MID)>>=
+${MID}/BINFILE.NRLIB: ${MID}/BINFILE.spad
+ @ echo 0 making ${MID}/BINFILE.NRLIB from ${MID}/BINFILE.spad
+ @ (cd ${MID} ; echo ')co BINFILE.spad' | ${INTERPSYS} )
+
+@
+<<BINFILE.spad (SPAD from IN)>>=
+${MID}/BINFILE.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/BINFILE.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BINFILE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BINFILE BinaryFile" ${IN}/files.spad.pamphlet >BINFILE.spad )
+
+@
+<<FILE.o (O from NRLIB)>>=
+${OUT}/FILE.o: ${MID}/FILE.NRLIB
+ @ echo 0 making ${OUT}/FILE.o from ${MID}/FILE.NRLIB
+ @ cp ${MID}/FILE.NRLIB/code.o ${OUT}/FILE.o
+
+@
+<<FILE.NRLIB (NRLIB from MID)>>=
+${MID}/FILE.NRLIB: ${MID}/FILE.spad
+ @ echo 0 making ${MID}/FILE.NRLIB from ${MID}/FILE.spad
+ @ (cd ${MID} ; echo ')co FILE.spad' | ${INTERPSYS} )
+
+@
+<<FILE.spad (SPAD from IN)>>=
+${MID}/FILE.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/FILE.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FILE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FILE File" ${IN}/files.spad.pamphlet >FILE.spad )
+
+@
+<<FILECAT.o (O from NRLIB)>>=
+${OUT}/FILECAT.o: ${MID}/FILECAT.NRLIB
+ @ echo 0 making ${OUT}/FILECAT.o from ${MID}/FILECAT.NRLIB
+ @ cp ${MID}/FILECAT.NRLIB/code.o ${OUT}/FILECAT.o
+
+@
+<<FILECAT.NRLIB (NRLIB from MID)>>=
+${MID}/FILECAT.NRLIB: ${MID}/FILECAT.spad
+ @ echo 0 making ${MID}/FILECAT.NRLIB from ${MID}/FILECAT.spad
+ @ (cd ${MID} ; echo ')co FILECAT.spad' | ${INTERPSYS} )
+
+@
+<<FILECAT.spad (SPAD from IN)>>=
+${MID}/FILECAT.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/FILECAT.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FILECAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FILECAT FileCategory" ${IN}/files.spad.pamphlet >FILECAT.spad )
+
+@
+<<KAFILE.o (O from NRLIB)>>=
+${OUT}/KAFILE.o: ${MID}/KAFILE.NRLIB
+ @ echo 0 making ${OUT}/KAFILE.o from ${MID}/KAFILE.NRLIB
+ @ cp ${MID}/KAFILE.NRLIB/code.o ${OUT}/KAFILE.o
+
+@
+<<KAFILE.NRLIB (NRLIB from MID)>>=
+${MID}/KAFILE.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/KAFILE.spad
+ @ echo 0 making ${MID}/KAFILE.NRLIB from ${MID}/KAFILE.spad
+ @ (cd ${MID} ; echo ')co KAFILE.spad' | ${INTERPSYS} )
+
+@
+<<KAFILE.spad (SPAD from IN)>>=
+${MID}/KAFILE.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/KAFILE.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf KAFILE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain KAFILE KeyedAccessFile" ${IN}/files.spad.pamphlet >KAFILE.spad )
+
+@
+<<LIB.o (O from NRLIB)>>=
+${OUT}/LIB.o: ${MID}/LIB.NRLIB
+ @ echo 0 making ${OUT}/LIB.o from ${MID}/LIB.NRLIB
+ @ cp ${MID}/LIB.NRLIB/code.o ${OUT}/LIB.o
+
+@
+<<LIB.NRLIB (NRLIB from MID)>>=
+${MID}/LIB.NRLIB: ${MID}/LIB.spad
+ @ echo 0 making ${MID}/LIB.NRLIB from ${MID}/LIB.spad
+ @ (cd ${MID} ; echo ')co LIB.spad' | ${INTERPSYS} )
+
+@
+<<LIB.spad (SPAD from IN)>>=
+${MID}/LIB.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/LIB.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LIB Library" ${IN}/files.spad.pamphlet >LIB.spad )
+
+@
+<<TEXTFILE.o (O from NRLIB)>>=
+${OUT}/TEXTFILE.o: ${MID}/TEXTFILE.NRLIB
+ @ echo 0 making ${OUT}/TEXTFILE.o from ${MID}/TEXTFILE.NRLIB
+ @ cp ${MID}/TEXTFILE.NRLIB/code.o ${OUT}/TEXTFILE.o
+
+@
+<<TEXTFILE.NRLIB (NRLIB from MID)>>=
+${MID}/TEXTFILE.NRLIB: ${MID}/TEXTFILE.spad
+ @ echo 0 making ${MID}/TEXTFILE.NRLIB from ${MID}/TEXTFILE.spad
+ @ (cd ${MID} ; echo ')co TEXTFILE.spad' | ${INTERPSYS} )
+
+@
+<<TEXTFILE.spad (SPAD from IN)>>=
+${MID}/TEXTFILE.spad: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${MID}/TEXTFILE.spad from ${IN}/files.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TEXTFILE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TEXTFILE TextFile" ${IN}/files.spad.pamphlet >TEXTFILE.spad )
+
+@
+<<files.spad.dvi (DOC from IN)>>=
+${DOC}/files.spad.dvi: ${IN}/files.spad.pamphlet
+ @ echo 0 making ${DOC}/files.spad.dvi from ${IN}/files.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/files.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} files.spad ; \
+ rm -f ${DOC}/files.spad.pamphlet ; \
+ rm -f ${DOC}/files.spad.tex ; \
+ rm -f ${DOC}/files.spad )
+
+@
+\subsection{float.spad \cite{1}}
+<<float.spad (SPAD from IN)>>=
+${MID}/float.spad: ${IN}/float.spad.pamphlet
+ @ echo 0 making ${MID}/float.spad from ${IN}/float.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/float.spad.pamphlet >float.spad )
+
+@
+<<FLOAT.o (O from NRLIB)>>=
+${OUT}/FLOAT.o: ${MID}/FLOAT.NRLIB
+ @ echo 0 making ${OUT}/FLOAT.o from ${MID}/FLOAT.NRLIB
+ @ cp ${MID}/FLOAT.NRLIB/code.o ${OUT}/FLOAT.o
+
+@
+<<FLOAT.NRLIB (NRLIB from MID)>>=
+${MID}/FLOAT.NRLIB: ${MID}/FLOAT.spad
+ @ echo 0 making ${MID}/FLOAT.NRLIB from ${MID}/FLOAT.spad
+ @ (cd ${MID} ; echo ')co FLOAT.spad' | ${INTERPSYS} )
+
+@
+<<FLOAT.spad (SPAD from IN)>>=
+${MID}/FLOAT.spad: ${IN}/float.spad.pamphlet
+ @ echo 0 making ${MID}/FLOAT.spad from ${IN}/float.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLOAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FLOAT Float" ${IN}/float.spad.pamphlet >FLOAT.spad )
+
+@
+<<float.spad.dvi (DOC from IN)>>=
+${DOC}/float.spad.dvi: ${IN}/float.spad.pamphlet
+ @ echo 0 making ${DOC}/float.spad.dvi from ${IN}/float.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/float.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} float.spad ; \
+ rm -f ${DOC}/float.spad.pamphlet ; \
+ rm -f ${DOC}/float.spad.tex ; \
+ rm -f ${DOC}/float.spad )
+
+@
+\subsection{fmod.spad \cite{1}}
+<<fmod.spad (SPAD from IN)>>=
+${MID}/fmod.spad: ${IN}/fmod.spad.pamphlet
+ @ echo 0 making ${MID}/fmod.spad from ${IN}/fmod.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fmod.spad.pamphlet >fmod.spad )
+
+@
+<<ZMOD.o (O from NRLIB)>>=
+${OUT}/ZMOD.o: ${MID}/ZMOD.NRLIB
+ @ echo 0 making ${OUT}/ZMOD.o from ${MID}/ZMOD.NRLIB
+ @ cp ${MID}/ZMOD.NRLIB/code.o ${OUT}/ZMOD.o
+
+@
+<<ZMOD.NRLIB (NRLIB from MID)>>=
+${MID}/ZMOD.NRLIB: ${MID}/ZMOD.spad
+ @ echo 0 making ${MID}/ZMOD.NRLIB from ${MID}/ZMOD.spad
+ @ (cd ${MID} ; echo ')co ZMOD.spad' | ${INTERPSYS} )
+
+@
+<<ZMOD.spad (SPAD from IN)>>=
+${MID}/ZMOD.spad: ${IN}/fmod.spad.pamphlet
+ @ echo 0 making ${MID}/ZMOD.spad from ${IN}/fmod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ZMOD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ZMOD IntegerMod" ${IN}/fmod.spad.pamphlet >ZMOD.spad )
+
+@
+<<fmod.spad.dvi (DOC from IN)>>=
+${DOC}/fmod.spad.dvi: ${IN}/fmod.spad.pamphlet
+ @ echo 0 making ${DOC}/fmod.spad.dvi from ${IN}/fmod.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fmod.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fmod.spad ; \
+ rm -f ${DOC}/fmod.spad.pamphlet ; \
+ rm -f ${DOC}/fmod.spad.tex ; \
+ rm -f ${DOC}/fmod.spad )
+
+@
+\subsection{fname.spad \cite{1}}
+<<fname.spad (SPAD from IN)>>=
+${MID}/fname.spad: ${IN}/fname.spad.pamphlet
+ @ echo 0 making ${MID}/fname.spad from ${IN}/fname.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fname.spad.pamphlet >fname.spad )
+
+@
+<<FNAME.o (O from NRLIB)>>=
+${OUT}/FNAME.o: ${MID}/FNAME.NRLIB
+ @ echo 0 making ${OUT}/FNAME.o from ${MID}/FNAME.NRLIB
+ @ cp ${MID}/FNAME.NRLIB/code.o ${OUT}/FNAME.o
+
+@
+<<FNAME.NRLIB (NRLIB from MID)>>=
+${MID}/FNAME.NRLIB: ${MID}/FNAME.spad
+ @ echo 0 making ${MID}/FNAME.NRLIB from ${MID}/FNAME.spad
+ @ (cd ${MID} ; echo ')co FNAME.spad' | ${INTERPSYS} )
+
+@
+<<FNAME.spad (SPAD from IN)>>=
+${MID}/FNAME.spad: ${IN}/fname.spad.pamphlet
+ @ echo 0 making ${MID}/FNAME.spad from ${IN}/fname.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FNAME.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FNAME FileName" ${IN}/fname.spad.pamphlet >FNAME.spad )
+
+@
+<<FNCAT.o (O from NRLIB)>>=
+${OUT}/FNCAT.o: ${MID}/FNCAT.NRLIB
+ @ echo 0 making ${OUT}/FNCAT.o from ${MID}/FNCAT.NRLIB
+ @ cp ${MID}/FNCAT.NRLIB/code.o ${OUT}/FNCAT.o
+
+@
+<<FNCAT.NRLIB (NRLIB from MID)>>=
+${MID}/FNCAT.NRLIB: ${MID}/FNCAT.spad
+ @ echo 0 making ${MID}/FNCAT.NRLIB from ${MID}/FNCAT.spad
+ @ (cd ${MID} ; echo ')co FNCAT.spad' | ${INTERPSYS} )
+
+@
+<<FNCAT.spad (SPAD from IN)>>=
+${MID}/FNCAT.spad: ${IN}/fname.spad.pamphlet
+ @ echo 0 making ${MID}/FNCAT.spad from ${IN}/fname.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FNCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FNCAT FileNameCategory" ${IN}/fname.spad.pamphlet >FNCAT.spad )
+
+@
+<<fname.spad.dvi (DOC from IN)>>=
+${DOC}/fname.spad.dvi: ${IN}/fname.spad.pamphlet
+ @ echo 0 making ${DOC}/fname.spad.dvi from ${IN}/fname.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fname.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fname.spad ; \
+ rm -f ${DOC}/fname.spad.pamphlet ; \
+ rm -f ${DOC}/fname.spad.tex ; \
+ rm -f ${DOC}/fname.spad )
+
+@
+\subsection{fnla.spad \cite{1}}
+<<fnla.spad (SPAD from IN)>>=
+${MID}/fnla.spad: ${IN}/fnla.spad.pamphlet
+ @ echo 0 making ${MID}/fnla.spad from ${IN}/fnla.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fnla.spad.pamphlet >fnla.spad )
+
+@
+<<COMM.o (O from NRLIB)>>=
+${OUT}/COMM.o: ${MID}/COMM.NRLIB
+ @ echo 0 making ${OUT}/COMM.o from ${MID}/COMM.NRLIB
+ @ cp ${MID}/COMM.NRLIB/code.o ${OUT}/COMM.o
+
+@
+<<COMM.NRLIB (NRLIB from MID)>>=
+${MID}/COMM.NRLIB: ${MID}/COMM.spad
+ @ echo 0 making ${MID}/COMM.NRLIB from ${MID}/COMM.spad
+ @ (cd ${MID} ; echo ')co COMM.spad' | ${INTERPSYS} )
+
+@
+<<COMM.spad (SPAD from IN)>>=
+${MID}/COMM.spad: ${IN}/fnla.spad.pamphlet
+ @ echo 0 making ${MID}/COMM.spad from ${IN}/fnla.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain COMM Commutator" ${IN}/fnla.spad.pamphlet >COMM.spad )
+
+@
+<<FNLA.o (O from NRLIB)>>=
+${OUT}/FNLA.o: ${MID}/FNLA.NRLIB
+ @ echo 0 making ${OUT}/FNLA.o from ${MID}/FNLA.NRLIB
+ @ cp ${MID}/FNLA.NRLIB/code.o ${OUT}/FNLA.o
+
+@
+<<FNLA.NRLIB (NRLIB from MID)>>=
+${MID}/FNLA.NRLIB: ${MID}/FNLA.spad
+ @ echo 0 making ${MID}/FNLA.NRLIB from ${MID}/FNLA.spad
+ @ (cd ${MID} ; echo ')co FNLA.spad' | ${INTERPSYS} )
+
+@
+<<FNLA.spad (SPAD from IN)>>=
+${MID}/FNLA.spad: ${IN}/fnla.spad.pamphlet
+ @ echo 0 making ${MID}/FNLA.spad from ${IN}/fnla.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FNLA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FNLA FreeNilpotentLie" ${IN}/fnla.spad.pamphlet >FNLA.spad )
+
+@
+<<HB.o (O from NRLIB)>>=
+${OUT}/HB.o: ${MID}/HB.NRLIB
+ @ echo 0 making ${OUT}/HB.o from ${MID}/HB.NRLIB
+ @ cp ${MID}/HB.NRLIB/code.o ${OUT}/HB.o
+
+@
+<<HB.NRLIB (NRLIB from MID)>>=
+${MID}/HB.NRLIB: ${MID}/HB.spad
+ @ echo 0 making ${MID}/HB.NRLIB from ${MID}/HB.spad
+ @ (cd ${MID} ; echo ')co HB.spad' | ${INTERPSYS} )
+
+@
+<<HB.spad (SPAD from IN)>>=
+${MID}/HB.spad: ${IN}/fnla.spad.pamphlet
+ @ echo 0 making ${MID}/HB.spad from ${IN}/fnla.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HB.NRLIB ; \
+ ${SPADBIN}/notangle -R"package HB HallBasis" ${IN}/fnla.spad.pamphlet >HB.spad )
+
+@
+<<OSI.o (O from NRLIB)>>=
+${OUT}/OSI.o: ${MID}/OSI.NRLIB
+ @ echo 0 making ${OUT}/OSI.o from ${MID}/OSI.NRLIB
+ @ cp ${MID}/OSI.NRLIB/code.o ${OUT}/OSI.o
+
+@
+<<OSI.NRLIB (NRLIB from MID)>>=
+${MID}/OSI.NRLIB: ${MID}/OSI.spad
+ @ echo 0 making ${MID}/OSI.NRLIB from ${MID}/OSI.spad
+ @ (cd ${MID} ; echo ')co OSI.spad' | ${INTERPSYS} )
+
+@
+<<OSI.spad (SPAD from IN)>>=
+${MID}/OSI.spad: ${IN}/fnla.spad.pamphlet
+ @ echo 0 making ${MID}/OSI.spad from ${IN}/fnla.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OSI.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OSI OrdSetInts" ${IN}/fnla.spad.pamphlet >OSI.spad )
+
+@
+<<fnla.spad.dvi (DOC from IN)>>=
+${DOC}/fnla.spad.dvi: ${IN}/fnla.spad.pamphlet
+ @ echo 0 making ${DOC}/fnla.spad.dvi from ${IN}/fnla.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fnla.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fnla.spad ; \
+ rm -f ${DOC}/fnla.spad.pamphlet ; \
+ rm -f ${DOC}/fnla.spad.tex ; \
+ rm -f ${DOC}/fnla.spad )
+
+@
+\subsection{formula.spad \cite{1}}
+<<formula.spad (SPAD from IN)>>=
+${MID}/formula.spad: ${IN}/formula.spad.pamphlet
+ @ echo 0 making ${MID}/formula.spad from ${IN}/formula.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/formula.spad.pamphlet >formula.spad )
+
+@
+<<FORMULA.o (O from NRLIB)>>=
+${OUT}/FORMULA.o: ${MID}/FORMULA.NRLIB
+ @ echo 0 making ${OUT}/FORMULA.o from ${MID}/FORMULA.NRLIB
+ @ cp ${MID}/FORMULA.NRLIB/code.o ${OUT}/FORMULA.o
+
+@
+<<FORMULA.NRLIB (NRLIB from MID)>>=
+${MID}/FORMULA.NRLIB: ${MID}/FORMULA.spad
+ @ echo 0 making ${MID}/FORMULA.NRLIB from ${MID}/FORMULA.spad
+ @ (cd ${MID} ; echo ')co FORMULA.spad' | ${INTERPSYS} )
+
+@
+<<FORMULA.spad (SPAD from IN)>>=
+${MID}/FORMULA.spad: ${IN}/formula.spad.pamphlet
+ @ echo 0 making ${MID}/FORMULA.spad from ${IN}/formula.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORMULA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FORMULA ScriptFormulaFormat" ${IN}/formula.spad.pamphlet >FORMULA.spad )
+
+@
+<<FORMULA1.o (O from NRLIB)>>=
+${OUT}/FORMULA1.o: ${MID}/FORMULA1.NRLIB
+ @ echo 0 making ${OUT}/FORMULA1.o from ${MID}/FORMULA1.NRLIB
+ @ cp ${MID}/FORMULA1.NRLIB/code.o ${OUT}/FORMULA1.o
+
+@
+<<FORMULA1.NRLIB (NRLIB from MID)>>=
+${MID}/FORMULA1.NRLIB: ${MID}/FORMULA1.spad
+ @ echo 0 making ${MID}/FORMULA1.NRLIB from ${MID}/FORMULA1.spad
+ @ (cd ${MID} ; echo ')co FORMULA1.spad' | ${INTERPSYS} )
+
+@
+<<FORMULA1.spad (SPAD from IN)>>=
+${MID}/FORMULA1.spad: ${IN}/formula.spad.pamphlet
+ @ echo 0 making ${MID}/FORMULA1.spad from ${IN}/formula.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORMULA1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FORMULA1 ScriptFormulaFormat1" ${IN}/formula.spad.pamphlet >FORMULA1.spad )
+
+@
+<<formula.spad.dvi (DOC from IN)>>=
+${DOC}/formula.spad.dvi: ${IN}/formula.spad.pamphlet
+ @ echo 0 making ${DOC}/formula.spad.dvi from ${IN}/formula.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/formula.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} formula.spad ; \
+ rm -f ${DOC}/formula.spad.pamphlet ; \
+ rm -f ${DOC}/formula.spad.tex ; \
+ rm -f ${DOC}/formula.spad )
+
+@
+\subsection{fortcat.spad \cite{1}}
+<<fortcat.spad (SPAD from IN)>>=
+${MID}/fortcat.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/fortcat.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fortcat.spad.pamphlet >fortcat.spad )
+
+@
+<<FMTC.o (O from NRLIB)>>=
+${OUT}/FMTC.o: ${MID}/FMTC.NRLIB
+ @ echo 0 making ${OUT}/FMTC.o from ${MID}/FMTC.NRLIB
+ @ cp ${MID}/FMTC.NRLIB/code.o ${OUT}/FMTC.o
+
+@
+<<FMTC.NRLIB (NRLIB from MID)>>=
+${MID}/FMTC.NRLIB: ${MID}/FMTC.spad
+ @ echo 0 making ${MID}/FMTC.NRLIB from ${MID}/FMTC.spad
+ @ (cd ${MID} ; echo ')co FMTC.spad' | ${INTERPSYS} )
+
+@
+<<FMTC.spad (SPAD from IN)>>=
+${MID}/FMTC.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FMTC.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FMTC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FMTC FortranMachineTypeCategory" ${IN}/fortcat.spad.pamphlet >FMTC.spad )
+
+@
+<<FORTCAT.o (O from NRLIB)>>=
+${OUT}/FORTCAT.o: ${MID}/FORTCAT.NRLIB
+ @ echo 0 making ${OUT}/FORTCAT.o from ${MID}/FORTCAT.NRLIB
+ @ cp ${MID}/FORTCAT.NRLIB/code.o ${OUT}/FORTCAT.o
+
+@
+<<FORTCAT.NRLIB (NRLIB from MID)>>=
+${MID}/FORTCAT.NRLIB: ${OUT}/TYPE.o ${OUT}/KOERCE.o ${MID}/FORTCAT.spad
+ @ echo 0 making ${MID}/FORTCAT.NRLIB from ${MID}/FORTCAT.spad
+ @ (cd ${MID} ; echo ')co FORTCAT.spad' | ${INTERPSYS} )
+
+@
+<<FORTCAT.spad (SPAD from IN)>>=
+${MID}/FORTCAT.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FORTCAT.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORTCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FORTCAT FortranProgramCategory" ${IN}/fortcat.spad.pamphlet >FORTCAT.spad )
+
+@
+<<FORTFN.o (O from NRLIB)>>=
+${OUT}/FORTFN.o: ${MID}/FORTFN.NRLIB
+ @ echo 0 making ${OUT}/FORTFN.o from ${MID}/FORTFN.NRLIB
+ @ cp ${MID}/FORTFN.NRLIB/code.o ${OUT}/FORTFN.o
+
+@
+<<FORTFN.NRLIB (NRLIB from MID)>>=
+${MID}/FORTFN.NRLIB: ${OUT}/FORTCAT.o ${OUT}/TYPE.o ${OUT}/KOERCE.o \
+ ${MID}/FORTFN.spad
+ @ echo 0 making ${MID}/FORTFN.NRLIB from ${MID}/FORTFN.spad
+ @ (cd ${MID} ; echo ')co FORTFN.spad' | ${INTERPSYS} )
+
+@
+<<FORTFN.spad (SPAD from IN)>>=
+${MID}/FORTFN.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FORTFN.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORTFN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FORTFN FortranFunctionCategory" ${IN}/fortcat.spad.pamphlet >FORTFN.spad )
+
+@
+<<FVC.o (O from NRLIB)>>=
+${OUT}/FVC.o: ${MID}/FVC.NRLIB
+ @ echo 0 making ${OUT}/FVC.o from ${MID}/FVC.NRLIB
+ @ cp ${MID}/FVC.NRLIB/code.o ${OUT}/FVC.o
+
+@
+<<FVC.NRLIB (NRLIB from MID)>>=
+${MID}/FVC.NRLIB: ${OUT}/FORTCAT.o ${OUT}/TYPE.o ${OUT}/KOERCE.o \
+ ${MID}/FVC.spad
+ @ echo 0 making ${MID}/FVC.NRLIB from ${MID}/FVC.spad
+ @ (cd ${MID} ; echo ')co FVC.spad' | ${INTERPSYS} )
+
+@
+<<FVC.spad (SPAD from IN)>>=
+${MID}/FVC.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FVC.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FVC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FVC FortranVectorCategory" ${IN}/fortcat.spad.pamphlet >FVC.spad )
+
+@
+<<FVFUN.o (O from NRLIB)>>=
+${OUT}/FVFUN.o: ${MID}/FVFUN.NRLIB
+ @ echo 0 making ${OUT}/FVFUN.o from ${MID}/FVFUN.NRLIB
+ @ cp ${MID}/FVFUN.NRLIB/code.o ${OUT}/FVFUN.o
+
+@
+<<FVFUN.NRLIB (NRLIB from MID)>>=
+${MID}/FVFUN.NRLIB: ${OUT}/FORTCAT.o ${OUT}/TYPE.o ${OUT}/KOERCE.o \
+ ${MID}/FVFUN.spad
+ @ echo 0 making ${MID}/FVFUN.NRLIB from ${MID}/FVFUN.spad
+ @ (cd ${MID} ; echo ')co FVFUN.spad' | ${INTERPSYS} )
+
+@
+<<FVFUN.spad (SPAD from IN)>>=
+${MID}/FVFUN.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FVFUN.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FVFUN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FVFUN FortranVectorFunctionCategory" ${IN}/fortcat.spad.pamphlet >FVFUN.spad )
+
+@
+<<FMC.o (O from NRLIB)>>=
+${OUT}/FMC.o: ${MID}/FMC.NRLIB
+ @ echo 0 making ${OUT}/FMC.o from ${MID}/FMC.NRLIB
+ @ cp ${MID}/FMC.NRLIB/code.o ${OUT}/FMC.o
+
+@
+<<FMC.NRLIB (NRLIB from MID)>>=
+${MID}/FMC.NRLIB: ${OUT}/FORTCAT.o ${OUT}/TYPE.o ${OUT}/KOERCE.o \
+ ${MID}/FMC.spad
+ @ echo 0 making ${MID}/FMC.NRLIB from ${MID}/FMC.spad
+ @ (cd ${MID} ; echo ')co FMC.spad' | ${INTERPSYS} )
+
+@
+<<FMC.spad (SPAD from IN)>>=
+${MID}/FMC.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FMC.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FMC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FMC FortranMatrixCategory" ${IN}/fortcat.spad.pamphlet >FMC.spad )
+
+@
+<<FMFUN.o (O from NRLIB)>>=
+${OUT}/FMFUN.o: ${MID}/FMFUN.NRLIB
+ @ echo 0 making ${OUT}/FMFUN.o from ${MID}/FMFUN.NRLIB
+ @ cp ${MID}/FMFUN.NRLIB/code.o ${OUT}/FMFUN.o
+
+@
+<<FMFUN.NRLIB (NRLIB from MID)>>=
+${MID}/FMFUN.NRLIB: ${OUT}/FORTCAT.o ${OUT}/TYPE.o ${OUT}/KOERCE.o \
+ ${MID}/FMFUN.spad
+ @ echo 0 making ${MID}/FMFUN.NRLIB from ${MID}/FMFUN.spad
+ @ (cd ${MID} ; echo ')co FMFUN.spad' | ${INTERPSYS} )
+
+@
+<<FMFUN.spad (SPAD from IN)>>=
+${MID}/FMFUN.spad: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${MID}/FMFUN.spad from ${IN}/fortcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FMFUN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FMFUN FortranMatrixFunctionCategory" ${IN}/fortcat.spad.pamphlet >FMFUN.spad )
+
+@
+<<fortcat.spad.dvi (DOC from IN)>>=
+${DOC}/fortcat.spad.dvi: ${IN}/fortcat.spad.pamphlet
+ @ echo 0 making ${DOC}/fortcat.spad.dvi from ${IN}/fortcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fortcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fortcat.spad ; \
+ rm -f ${DOC}/fortcat.spad.pamphlet ; \
+ rm -f ${DOC}/fortcat.spad.tex ; \
+ rm -f ${DOC}/fortcat.spad )
+
+@
+\subsection{fortmac.spad \cite{1}}
+<<fortmac.spad (SPAD from IN)>>=
+${MID}/fortmac.spad: ${IN}/fortmac.spad.pamphlet
+ @ echo 0 making ${MID}/fortmac.spad from ${IN}/fortmac.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fortmac.spad.pamphlet >fortmac.spad )
+
+@
+<<MCMPLX.o (O from NRLIB)>>=
+${OUT}/MCMPLX.o: ${MID}/MCMPLX.NRLIB
+ @ echo 0 making ${OUT}/MCMPLX.o from ${MID}/MCMPLX.NRLIB
+ @ cp ${MID}/MCMPLX.NRLIB/code.o ${OUT}/MCMPLX.o
+
+@
+<<MCMPLX.NRLIB (NRLIB from MID)>>=
+${MID}/MCMPLX.NRLIB: ${MID}/MCMPLX.spad
+ @ echo 0 making ${MID}/MCMPLX.NRLIB from ${MID}/MCMPLX.spad
+ @ (cd ${MID} ; echo ')co MCMPLX.spad' | ${INTERPSYS} )
+
+@
+<<MCMPLX.spad (SPAD from IN)>>=
+${MID}/MCMPLX.spad: ${IN}/fortmac.spad.pamphlet
+ @ echo 0 making ${MID}/MCMPLX.spad from ${IN}/fortmac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MCMPLX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MCMPLX MachineComplex" ${IN}/fortmac.spad.pamphlet >MCMPLX.spad )
+
+@
+<<MFLOAT.o (O from NRLIB)>>=
+${OUT}/MFLOAT.o: ${MID}/MFLOAT.NRLIB
+ @ echo 0 making ${OUT}/MFLOAT.o from ${MID}/MFLOAT.NRLIB
+ @ cp ${MID}/MFLOAT.NRLIB/code.o ${OUT}/MFLOAT.o
+
+@
+<<MFLOAT.NRLIB (NRLIB from MID)>>=
+${MID}/MFLOAT.NRLIB: ${MID}/MFLOAT.spad
+ @ echo 0 making ${MID}/MFLOAT.NRLIB from ${MID}/MFLOAT.spad
+ @ (cd ${MID} ; echo ')co MFLOAT.spad' | ${INTERPSYS} )
+
+@
+<<MFLOAT.spad (SPAD from IN)>>=
+${MID}/MFLOAT.spad: ${IN}/fortmac.spad.pamphlet
+ @ echo 0 making ${MID}/MFLOAT.spad from ${IN}/fortmac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MFLOAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MFLOAT MachineFloat" ${IN}/fortmac.spad.pamphlet >MFLOAT.spad )
+
+@
+<<MINT.o (O from NRLIB)>>=
+${OUT}/MINT.o: ${MID}/MINT.NRLIB
+ @ echo 0 making ${OUT}/MINT.o from ${MID}/MINT.NRLIB
+ @ cp ${MID}/MINT.NRLIB/code.o ${OUT}/MINT.o
+
+@
+<<MINT.NRLIB (NRLIB from MID)>>=
+${MID}/MINT.NRLIB: ${MID}/MINT.spad
+ @ echo 0 making ${MID}/MINT.NRLIB from ${MID}/MINT.spad
+ @ (cd ${MID} ; echo ')co MINT.spad' | ${INTERPSYS} )
+
+@
+<<MINT.spad (SPAD from IN)>>=
+${MID}/MINT.spad: ${IN}/fortmac.spad.pamphlet
+ @ echo 0 making ${MID}/MINT.spad from ${IN}/fortmac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MINT MachineInteger" ${IN}/fortmac.spad.pamphlet >MINT.spad )
+
+@
+<<fortmac.spad.dvi (DOC from IN)>>=
+${DOC}/fortmac.spad.dvi: ${IN}/fortmac.spad.pamphlet
+ @ echo 0 making ${DOC}/fortmac.spad.dvi from ${IN}/fortmac.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fortmac.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fortmac.spad ; \
+ rm -f ${DOC}/fortmac.spad.pamphlet ; \
+ rm -f ${DOC}/fortmac.spad.tex ; \
+ rm -f ${DOC}/fortmac.spad )
+
+@
+\subsection{fortpak.spad \cite{1}}
+<<fortpak.spad (SPAD from IN)>>=
+${MID}/fortpak.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/fortpak.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fortpak.spad.pamphlet >fortpak.spad )
+
+@
+<<FCPAK1.o (O from NRLIB)>>=
+${OUT}/FCPAK1.o: ${MID}/FCPAK1.NRLIB
+ @ echo 0 making ${OUT}/FCPAK1.o from ${MID}/FCPAK1.NRLIB
+ @ cp ${MID}/FCPAK1.NRLIB/code.o ${OUT}/FCPAK1.o
+
+@
+<<FCPAK1.NRLIB (NRLIB from MID)>>=
+${MID}/FCPAK1.NRLIB: ${MID}/FCPAK1.spad
+ @ echo 0 making ${MID}/FCPAK1.NRLIB from ${MID}/FCPAK1.spad
+ @ (cd ${MID} ; echo ')co FCPAK1.spad' | ${INTERPSYS} )
+
+@
+<<FCPAK1.spad (SPAD from IN)>>=
+${MID}/FCPAK1.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/FCPAK1.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FCPAK1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FCPAK1 FortranCodePackage1" ${IN}/fortpak.spad.pamphlet >FCPAK1.spad )
+
+@
+<<FOP.o (O from NRLIB)>>=
+${OUT}/FOP.o: ${MID}/FOP.NRLIB
+ @ echo 0 making ${OUT}/FOP.o from ${MID}/FOP.NRLIB
+ @ cp ${MID}/FOP.NRLIB/code.o ${OUT}/FOP.o
+
+@
+<<FOP.NRLIB (NRLIB from MID)>>=
+${MID}/FOP.NRLIB: ${MID}/FOP.spad
+ @ echo 0 making ${MID}/FOP.NRLIB from ${MID}/FOP.spad
+ @ (cd ${MID} ; echo ')co FOP.spad' | ${INTERPSYS} )
+
+@
+<<FOP.spad (SPAD from IN)>>=
+${MID}/FOP.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/FOP.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FOP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FOP FortranOutputStackPackage" ${IN}/fortpak.spad.pamphlet >FOP.spad )
+
+@
+<<FORT.o (O from NRLIB)>>=
+${OUT}/FORT.o: ${MID}/FORT.NRLIB
+ @ echo 0 making ${OUT}/FORT.o from ${MID}/FORT.NRLIB
+ @ cp ${MID}/FORT.NRLIB/code.o ${OUT}/FORT.o
+
+@
+<<FORT.NRLIB (NRLIB from MID)>>=
+${MID}/FORT.NRLIB: ${MID}/FORT.spad
+ @ echo 0 making ${MID}/FORT.NRLIB from ${MID}/FORT.spad
+ @ (cd ${MID} ; echo ')co FORT.spad' | ${INTERPSYS} )
+
+@
+<<FORT.spad (SPAD from IN)>>=
+${MID}/FORT.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/FORT.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FORT FortranPackage" ${IN}/fortpak.spad.pamphlet >FORT.spad )
+
+@
+<<MCALCFN.o (O from NRLIB)>>=
+${OUT}/MCALCFN.o: ${MID}/MCALCFN.NRLIB
+ @ echo 0 making ${OUT}/MCALCFN.o from ${MID}/MCALCFN.NRLIB
+ @ cp ${MID}/MCALCFN.NRLIB/code.o ${OUT}/MCALCFN.o
+
+@
+<<MCALCFN.NRLIB (NRLIB from MID)>>=
+${MID}/MCALCFN.NRLIB: ${MID}/MCALCFN.spad
+ @ echo 0 making ${MID}/MCALCFN.NRLIB from ${MID}/MCALCFN.spad
+ @ (cd ${MID} ; echo ')co MCALCFN.spad' | ${INTERPSYS} )
+
+@
+<<MCALCFN.spad (SPAD from IN)>>=
+${MID}/MCALCFN.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/MCALCFN.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MCALCFN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MCALCFN MultiVariableCalculusFunctions" ${IN}/fortpak.spad.pamphlet >MCALCFN.spad )
+
+@
+<<NAGSP.o (O from NRLIB)>>=
+${OUT}/NAGSP.o: ${MID}/NAGSP.NRLIB
+ @ echo 0 making ${OUT}/NAGSP.o from ${MID}/NAGSP.NRLIB
+ @ cp ${MID}/NAGSP.NRLIB/code.o ${OUT}/NAGSP.o
+
+@
+<<NAGSP.NRLIB (NRLIB from MID)>>=
+${MID}/NAGSP.NRLIB: ${MID}/NAGSP.spad
+ @ echo 0 making ${MID}/NAGSP.NRLIB from ${MID}/NAGSP.spad
+ @ (cd ${MID} ; echo ')co NAGSP.spad' | ${INTERPSYS} )
+
+@
+<<NAGSP.spad (SPAD from IN)>>=
+${MID}/NAGSP.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/NAGSP.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGSP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGSP NAGLinkSupportPackage" ${IN}/fortpak.spad.pamphlet >NAGSP.spad )
+
+@
+<<TEMUTL.o (O from NRLIB)>>=
+${OUT}/TEMUTL.o: ${MID}/TEMUTL.NRLIB
+ @ echo 0 making ${OUT}/TEMUTL.o from ${MID}/TEMUTL.NRLIB
+ @ cp ${MID}/TEMUTL.NRLIB/code.o ${OUT}/TEMUTL.o
+
+@
+<<TEMUTL.NRLIB (NRLIB from MID)>>=
+${MID}/TEMUTL.NRLIB: ${MID}/TEMUTL.spad
+ @ echo 0 making ${MID}/TEMUTL.NRLIB from ${MID}/TEMUTL.spad
+ @ (cd ${MID} ; echo ')co TEMUTL.spad' | ${INTERPSYS} )
+
+@
+<<TEMUTL.spad (SPAD from IN)>>=
+${MID}/TEMUTL.spad: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${MID}/TEMUTL.spad from ${IN}/fortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TEMUTL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TEMUTL TemplateUtilities" ${IN}/fortpak.spad.pamphlet >TEMUTL.spad )
+
+@
+<<fortpak.spad.dvi (DOC from IN)>>=
+${DOC}/fortpak.spad.dvi: ${IN}/fortpak.spad.pamphlet
+ @ echo 0 making ${DOC}/fortpak.spad.dvi from ${IN}/fortpak.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fortpak.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fortpak.spad ; \
+ rm -f ${DOC}/fortpak.spad.pamphlet ; \
+ rm -f ${DOC}/fortpak.spad.tex ; \
+ rm -f ${DOC}/fortpak.spad )
+
+@
+\subsection{fortran.spad \cite{1}}
+<<fortran.spad (SPAD from IN)>>=
+${MID}/fortran.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/fortran.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fortran.spad.pamphlet >fortran.spad )
+
+@
+<<FC.o (O from NRLIB)>>=
+${OUT}/FC.o: ${MID}/FC.NRLIB
+ @ echo 0 making ${OUT}/FC.o from ${MID}/FC.NRLIB
+ @ cp ${MID}/FC.NRLIB/code.o ${OUT}/FC.o
+
+@
+<<FC.NRLIB (NRLIB from MID)>>=
+${MID}/FC.NRLIB: ${MID}/FC.spad
+ @ echo 0 making ${MID}/FC.NRLIB from ${MID}/FC.spad
+ @ (cd ${MID} ; echo ')co FC.spad' | ${INTERPSYS} )
+
+@
+<<FC.spad (SPAD from IN)>>=
+${MID}/FC.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/FC.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FC FortranCode" ${IN}/fortran.spad.pamphlet >FC.spad )
+
+@
+<<FEXPR.o (O from NRLIB)>>=
+${OUT}/FEXPR.o: ${MID}/FEXPR.NRLIB
+ @ echo 0 making ${OUT}/FEXPR.o from ${MID}/FEXPR.NRLIB
+ @ cp ${MID}/FEXPR.NRLIB/code.o ${OUT}/FEXPR.o
+
+@
+<<FEXPR.NRLIB (NRLIB from MID)>>=
+${MID}/FEXPR.NRLIB: ${MID}/FEXPR.spad
+ @ echo 0 making ${MID}/FEXPR.NRLIB from ${MID}/FEXPR.spad
+ @ (cd ${MID} ; echo ')co FEXPR.spad' | ${INTERPSYS} )
+
+@
+<<FEXPR.spad (SPAD from IN)>>=
+${MID}/FEXPR.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/FEXPR.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FEXPR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FEXPR FortranExpression" ${IN}/fortran.spad.pamphlet >FEXPR.spad )
+
+@
+<<FTEM.o (O from NRLIB)>>=
+${OUT}/FTEM.o: ${MID}/FTEM.NRLIB
+ @ echo 0 making ${OUT}/FTEM.o from ${MID}/FTEM.NRLIB
+ @ cp ${MID}/FTEM.NRLIB/code.o ${OUT}/FTEM.o
+
+@
+<<FTEM.NRLIB (NRLIB from MID)>>=
+${MID}/FTEM.NRLIB: ${MID}/FTEM.spad
+ @ echo 0 making ${MID}/FTEM.NRLIB from ${MID}/FTEM.spad
+ @ (cd ${MID} ; echo ')co FTEM.spad' | ${INTERPSYS} )
+
+@
+<<FTEM.spad (SPAD from IN)>>=
+${MID}/FTEM.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/FTEM.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FTEM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FTEM FortranTemplate" ${IN}/fortran.spad.pamphlet >FTEM.spad )
+
+@
+<<FORTRAN.o (O from NRLIB)>>=
+${OUT}/FORTRAN.o: ${MID}/FORTRAN.NRLIB
+ @ echo 0 making ${OUT}/FORTRAN.o from ${MID}/FORTRAN.NRLIB
+ @ cp ${MID}/FORTRAN.NRLIB/code.o ${OUT}/FORTRAN.o
+
+@
+<<FORTRAN.NRLIB (NRLIB from MID)>>=
+${MID}/FORTRAN.NRLIB: ${MID}/FORTRAN.spad
+ @ echo 0 making ${MID}/FORTRAN.NRLIB from ${MID}/FORTRAN.spad
+ @ (cd ${MID} ; echo ')co FORTRAN.spad' | ${INTERPSYS} )
+
+@
+<<FORTRAN.spad (SPAD from IN)>>=
+${MID}/FORTRAN.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/FORTRAN.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORTRAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FORTRAN FortranProgram" ${IN}/fortran.spad.pamphlet >FORTRAN.spad )
+
+@
+<<M3D.o (O from NRLIB)>>=
+${OUT}/M3D.o: ${MID}/M3D.NRLIB
+ @ echo 0 making ${OUT}/M3D.o from ${MID}/M3D.NRLIB
+ @ cp ${MID}/M3D.NRLIB/code.o ${OUT}/M3D.o
+
+@
+<<M3D.NRLIB (NRLIB from MID)>>=
+${MID}/M3D.NRLIB: ${MID}/M3D.spad
+ @ echo 0 making ${MID}/M3D.NRLIB from ${MID}/M3D.spad
+ @ (cd ${MID} ; echo ')co M3D.spad' | ${INTERPSYS} )
+
+@
+<<M3D.spad (SPAD from IN)>>=
+${MID}/M3D.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/M3D.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf M3D.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain M3D ThreeDimensionalMatrix" ${IN}/fortran.spad.pamphlet >M3D.spad )
+
+@
+<<RESULT.o (O from NRLIB)>>=
+${OUT}/RESULT.o: ${MID}/RESULT.NRLIB
+ @ echo 0 making ${OUT}/RESULT.o from ${MID}/RESULT.NRLIB
+ @ cp ${MID}/RESULT.NRLIB/code.o ${OUT}/RESULT.o
+
+@
+<<RESULT.NRLIB (NRLIB from MID)>>=
+${MID}/RESULT.NRLIB: ${MID}/RESULT.spad
+ @ echo 0 making ${MID}/RESULT.NRLIB from ${MID}/RESULT.spad
+ @ (cd ${MID} ; echo ')co RESULT.spad' | ${INTERPSYS} )
+
+@
+<<RESULT.spad (SPAD from IN)>>=
+${MID}/RESULT.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/RESULT.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RESULT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RESULT Result" ${IN}/fortran.spad.pamphlet >RESULT.spad )
+
+@
+<<SFORT.o (O from NRLIB)>>=
+${OUT}/SFORT.o: ${MID}/SFORT.NRLIB
+ @ echo 0 making ${OUT}/SFORT.o from ${MID}/SFORT.NRLIB
+ @ cp ${MID}/SFORT.NRLIB/code.o ${OUT}/SFORT.o
+
+@
+<<SFORT.NRLIB (NRLIB from MID)>>=
+${MID}/SFORT.NRLIB: ${MID}/SFORT.spad
+ @ echo 0 making ${MID}/SFORT.NRLIB from ${MID}/SFORT.spad
+ @ (cd ${MID} ; echo ')co SFORT.spad' | ${INTERPSYS} )
+
+@
+<<SFORT.spad (SPAD from IN)>>=
+${MID}/SFORT.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/SFORT.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SFORT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SFORT SimpleFortranProgram" ${IN}/fortran.spad.pamphlet >SFORT.spad )
+
+@
+<<SWITCH.o (O from NRLIB)>>=
+${OUT}/SWITCH.o: ${MID}/SWITCH.NRLIB
+ @ echo 0 making ${OUT}/SWITCH.o from ${MID}/SWITCH.NRLIB
+ @ cp ${MID}/SWITCH.NRLIB/code.o ${OUT}/SWITCH.o
+
+@
+<<SWITCH.NRLIB (NRLIB from MID)>>=
+${MID}/SWITCH.NRLIB: ${MID}/SWITCH.spad
+ @ echo 0 making ${MID}/SWITCH.NRLIB from ${MID}/SWITCH.spad
+ @ (cd ${MID} ; echo ')co SWITCH.spad' | ${INTERPSYS} )
+
+@
+<<SWITCH.spad (SPAD from IN)>>=
+${MID}/SWITCH.spad: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${MID}/SWITCH.spad from ${IN}/fortran.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SWITCH.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SWITCH Switch" ${IN}/fortran.spad.pamphlet >SWITCH.spad )
+
+@
+<<fortran.spad.dvi (DOC from IN)>>=
+${DOC}/fortran.spad.dvi: ${IN}/fortran.spad.pamphlet
+ @ echo 0 making ${DOC}/fortran.spad.dvi from ${IN}/fortran.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fortran.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fortran.spad ; \
+ rm -f ${DOC}/fortran.spad.pamphlet ; \
+ rm -f ${DOC}/fortran.spad.tex ; \
+ rm -f ${DOC}/fortran.spad )
+
+@
+\subsection{forttyp.spad \cite{1}}
+<<forttyp.spad (SPAD from IN)>>=
+${MID}/forttyp.spad: ${IN}/forttyp.spad.pamphlet
+ @ echo 0 making ${MID}/forttyp.spad from ${IN}/forttyp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/forttyp.spad.pamphlet >forttyp.spad )
+
+@
+<<FST.o (O from NRLIB)>>=
+${OUT}/FST.o: ${MID}/FST.NRLIB
+ @ echo 0 making ${OUT}/FST.o from ${MID}/FST.NRLIB
+ @ cp ${MID}/FST.NRLIB/code.o ${OUT}/FST.o
+
+@
+<<FST.NRLIB (NRLIB from MID)>>=
+${MID}/FST.NRLIB: ${MID}/FST.spad
+ @ echo 0 making ${MID}/FST.NRLIB from ${MID}/FST.spad
+ @ (cd ${MID} ; echo ')co FST.spad' | ${INTERPSYS} )
+
+@
+<<FST.spad (SPAD from IN)>>=
+${MID}/FST.spad: ${IN}/forttyp.spad.pamphlet
+ @ echo 0 making ${MID}/FST.spad from ${IN}/forttyp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FST.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FST FortranScalarType" ${IN}/forttyp.spad.pamphlet >FST.spad )
+
+@
+<<FT.o (O from NRLIB)>>=
+${OUT}/FT.o: ${MID}/FT.NRLIB
+ @ echo 0 making ${OUT}/FT.o from ${MID}/FT.NRLIB
+ @ cp ${MID}/FT.NRLIB/code.o ${OUT}/FT.o
+
+@
+<<FT.NRLIB (NRLIB from MID)>>=
+${MID}/FT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FT.spad
+ @ echo 0 making ${MID}/FT.NRLIB from ${MID}/FT.spad
+ @ (cd ${MID} ; echo ')co FT.spad' | ${INTERPSYS} )
+
+@
+<<FT.spad (SPAD from IN)>>=
+${MID}/FT.spad: ${IN}/forttyp.spad.pamphlet
+ @ echo 0 making ${MID}/FT.spad from ${IN}/forttyp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FT FortranType" ${IN}/forttyp.spad.pamphlet >FT.spad )
+
+@
+<<SYMS.o (O from NRLIB)>>=
+${OUT}/SYMS.o: ${MID}/SYMS.NRLIB
+ @ echo 0 making ${OUT}/SYMS.o from ${MID}/SYMS.NRLIB
+ @ cp ${MID}/SYMS.NRLIB/code.o ${OUT}/SYMS.o
+
+@
+<<SYMS.NRLIB (NRLIB from MID)>>=
+${MID}/SYMS.NRLIB: ${MID}/SYMS.spad
+ @ echo 0 making ${MID}/SYMS.NRLIB from ${MID}/SYMS.spad
+ @ (cd ${MID} ; echo ')co SYMS.spad' | ${INTERPSYS} )
+
+@
+<<SYMS.spad (SPAD from IN)>>=
+${MID}/SYMS.spad: ${IN}/forttyp.spad.pamphlet
+ @ echo 0 making ${MID}/SYMS.spad from ${IN}/forttyp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYMS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SYMS TheSymbolTable" ${IN}/forttyp.spad.pamphlet >SYMS.spad )
+
+@
+<<SYMTAB.o (O from NRLIB)>>=
+${OUT}/SYMTAB.o: ${MID}/SYMTAB.NRLIB
+ @ echo 0 making ${OUT}/SYMTAB.o from ${MID}/SYMTAB.NRLIB
+ @ cp ${MID}/SYMTAB.NRLIB/code.o ${OUT}/SYMTAB.o
+
+@
+<<SYMTAB.NRLIB (NRLIB from MID)>>=
+${MID}/SYMTAB.NRLIB: ${MID}/SYMTAB.spad
+ @ echo 0 making ${MID}/SYMTAB.NRLIB from ${MID}/SYMTAB.spad
+ @ (cd ${MID} ; echo ')co SYMTAB.spad' | ${INTERPSYS} )
+
+@
+<<SYMTAB.spad (SPAD from IN)>>=
+${MID}/SYMTAB.spad: ${IN}/forttyp.spad.pamphlet
+ @ echo 0 making ${MID}/SYMTAB.spad from ${IN}/forttyp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYMTAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SYMTAB SymbolTable" ${IN}/forttyp.spad.pamphlet >SYMTAB.spad )
+
+@
+<<forttyp.spad.dvi (DOC from IN)>>=
+${DOC}/forttyp.spad.dvi: ${IN}/forttyp.spad.pamphlet
+ @ echo 0 making ${DOC}/forttyp.spad.dvi from ${IN}/forttyp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/forttyp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} forttyp.spad ; \
+ rm -f ${DOC}/forttyp.spad.pamphlet ; \
+ rm -f ${DOC}/forttyp.spad.tex ; \
+ rm -f ${DOC}/forttyp.spad )
+
+@
+\subsection{fourier.spad \cite{1}}
+<<fourier.spad (SPAD from IN)>>=
+${MID}/fourier.spad: ${IN}/fourier.spad.pamphlet
+ @ echo 0 making ${MID}/fourier.spad from ${IN}/fourier.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fourier.spad.pamphlet >fourier.spad )
+
+@
+<<FCOMP.o (O from NRLIB)>>=
+${OUT}/FCOMP.o: ${MID}/FCOMP.NRLIB
+ @ echo 0 making ${OUT}/FCOMP.o from ${MID}/FCOMP.NRLIB
+ @ cp ${MID}/FCOMP.NRLIB/code.o ${OUT}/FCOMP.o
+
+@
+<<FCOMP.NRLIB (NRLIB from MID)>>=
+${MID}/FCOMP.NRLIB: ${MID}/FCOMP.spad
+ @ echo 0 making ${MID}/FCOMP.NRLIB from ${MID}/FCOMP.spad
+ @ (cd ${MID} ; echo ')co FCOMP.spad' | ${INTERPSYS} )
+
+@
+<<FCOMP.spad (SPAD from IN)>>=
+${MID}/FCOMP.spad: ${IN}/fourier.spad.pamphlet
+ @ echo 0 making ${MID}/FCOMP.spad from ${IN}/fourier.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FCOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FCOMP FourierComponent" ${IN}/fourier.spad.pamphlet >FCOMP.spad )
+
+@
+<<FSERIES.o (O from NRLIB)>>=
+${OUT}/FSERIES.o: ${MID}/FSERIES.NRLIB
+ @ echo 0 making ${OUT}/FSERIES.o from ${MID}/FSERIES.NRLIB
+ @ cp ${MID}/FSERIES.NRLIB/code.o ${OUT}/FSERIES.o
+
+@
+<<FSERIES.NRLIB (NRLIB from MID)>>=
+${MID}/FSERIES.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FSERIES.spad
+ @ echo 0 making ${MID}/FSERIES.NRLIB from ${MID}/FSERIES.spad
+ @ (cd ${MID} ; echo ')co FSERIES.spad' | ${INTERPSYS} )
+
+@
+<<FSERIES.spad (SPAD from IN)>>=
+${MID}/FSERIES.spad: ${IN}/fourier.spad.pamphlet
+ @ echo 0 making ${MID}/FSERIES.spad from ${IN}/fourier.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSERIES.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FSERIES FourierSeries" ${IN}/fourier.spad.pamphlet >FSERIES.spad )
+
+@
+<<fourier.spad.dvi (DOC from IN)>>=
+${DOC}/fourier.spad.dvi: ${IN}/fourier.spad.pamphlet
+ @ echo 0 making ${DOC}/fourier.spad.dvi from ${IN}/fourier.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fourier.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fourier.spad ; \
+ rm -f ${DOC}/fourier.spad.pamphlet ; \
+ rm -f ${DOC}/fourier.spad.tex ; \
+ rm -f ${DOC}/fourier.spad )
+
+@
+\subsection{fparfrac.spad \cite{1}}
+<<fparfrac.spad (SPAD from IN)>>=
+${MID}/fparfrac.spad: ${IN}/fparfrac.spad.pamphlet
+ @ echo 0 making ${MID}/fparfrac.spad from ${IN}/fparfrac.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fparfrac.spad.pamphlet >fparfrac.spad )
+
+@
+<<FPARFRAC.o (O from NRLIB)>>=
+${OUT}/FPARFRAC.o: ${MID}/FPARFRAC.NRLIB
+ @ echo 0 making ${OUT}/FPARFRAC.o from ${MID}/FPARFRAC.NRLIB
+ @ cp ${MID}/FPARFRAC.NRLIB/code.o ${OUT}/FPARFRAC.o
+
+@
+<<FPARFRAC.NRLIB (NRLIB from MID)>>=
+${MID}/FPARFRAC.NRLIB: ${MID}/FPARFRAC.spad
+ @ echo 0 making ${MID}/FPARFRAC.NRLIB from ${MID}/FPARFRAC.spad
+ @ (cd ${MID} ; echo ')co FPARFRAC.spad' | ${INTERPSYS} )
+
+@
+<<FPARFRAC.spad (SPAD from IN)>>=
+${MID}/FPARFRAC.spad: ${IN}/fparfrac.spad.pamphlet
+ @ echo 0 making ${MID}/FPARFRAC.spad from ${IN}/fparfrac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FPARFRAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FPARFRAC FullPartialFractionExpansion" ${IN}/fparfrac.spad.pamphlet >FPARFRAC.spad )
+
+@
+<<fparfrac.spad.dvi (DOC from IN)>>=
+${DOC}/fparfrac.spad.dvi: ${IN}/fparfrac.spad.pamphlet
+ @ echo 0 making ${DOC}/fparfrac.spad.dvi from ${IN}/fparfrac.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fparfrac.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fparfrac.spad ; \
+ rm -f ${DOC}/fparfrac.spad.pamphlet ; \
+ rm -f ${DOC}/fparfrac.spad.tex ; \
+ rm -f ${DOC}/fparfrac.spad )
+
+@
+\subsection{fraction.spad \cite{1}}
+<<fraction.spad (SPAD from IN)>>=
+${MID}/fraction.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/fraction.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fraction.spad.pamphlet >fraction.spad )
+
+@
+<<FRAC.o (O from NRLIB)>>=
+${OUT}/FRAC.o: ${MID}/FRAC.NRLIB
+ @ echo 0 making ${OUT}/FRAC.o from ${MID}/FRAC.NRLIB
+ @ cp ${MID}/FRAC.NRLIB/code.o ${OUT}/FRAC.o
+
+@
+<<FRAC.NRLIB (NRLIB from MID)>>=
+${MID}/FRAC.NRLIB: ${MID}/FRAC.spad
+ @ echo 0 making ${MID}/FRAC.NRLIB from ${MID}/FRAC.spad
+ @ (cd ${MID} ; echo ')co FRAC.spad' | ${INTERPSYS} )
+
+@
+<<FRAC.spad (SPAD from IN)>>=
+${MID}/FRAC.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/FRAC.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FRAC Fraction" ${IN}/fraction.spad.pamphlet >FRAC.spad )
+
+@
+<<FRAC2.o (O from NRLIB)>>=
+${OUT}/FRAC2.o: ${MID}/FRAC2.NRLIB
+ @ echo 0 making ${OUT}/FRAC2.o from ${MID}/FRAC2.NRLIB
+ @ cp ${MID}/FRAC2.NRLIB/code.o ${OUT}/FRAC2.o
+
+@
+<<FRAC2.NRLIB (NRLIB from MID)>>=
+${MID}/FRAC2.NRLIB: ${MID}/FRAC2.spad
+ @ echo 0 making ${MID}/FRAC2.NRLIB from ${MID}/FRAC2.spad
+ @ (cd ${MID} ; echo ')co FRAC2.spad' | ${INTERPSYS} )
+
+@
+<<FRAC2.spad (SPAD from IN)>>=
+${MID}/FRAC2.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/FRAC2.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRAC2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FRAC2 FractionFunctions2" ${IN}/fraction.spad.pamphlet >FRAC2.spad )
+
+@
+<<LA.o (O from NRLIB)>>=
+${OUT}/LA.o: ${MID}/LA.NRLIB
+ @ echo 0 making ${OUT}/LA.o from ${MID}/LA.NRLIB
+ @ cp ${MID}/LA.NRLIB/code.o ${OUT}/LA.o
+
+@
+<<LA.NRLIB (NRLIB from MID)>>=
+${MID}/LA.NRLIB: ${MID}/LA.spad
+ @ echo 0 making ${MID}/LA.NRLIB from ${MID}/LA.spad
+ @ (cd ${MID} ; echo ')co LA.spad' | ${INTERPSYS} )
+
+@
+<<LA.spad (SPAD from IN)>>=
+${MID}/LA.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/LA.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LA LocalAlgebra" ${IN}/fraction.spad.pamphlet >LA.spad )
+
+@
+<<LO.o (O from NRLIB)>>=
+${OUT}/LO.o: ${MID}/LO.NRLIB
+ @ echo 0 making ${OUT}/LO.o from ${MID}/LO.NRLIB
+ @ cp ${MID}/LO.NRLIB/code.o ${OUT}/LO.o
+
+@
+<<LO.NRLIB (NRLIB from MID)>>=
+${MID}/LO.NRLIB: ${MID}/LO.spad
+ @ echo 0 making ${MID}/LO.NRLIB from ${MID}/LO.spad
+ @ (cd ${MID} ; echo ')co LO.spad' | ${INTERPSYS} )
+
+@
+<<LO.spad (SPAD from IN)>>=
+${MID}/LO.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/LO.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LO.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LO Localize" ${IN}/fraction.spad.pamphlet >LO.spad )
+
+@
+<<LPEFRAC.o (O from NRLIB)>>=
+${OUT}/LPEFRAC.o: ${MID}/LPEFRAC.NRLIB
+ @ echo 0 making ${OUT}/LPEFRAC.o from ${MID}/LPEFRAC.NRLIB
+ @ cp ${MID}/LPEFRAC.NRLIB/code.o ${OUT}/LPEFRAC.o
+
+@
+<<LPEFRAC.NRLIB (NRLIB from MID)>>=
+${MID}/LPEFRAC.NRLIB: ${MID}/LPEFRAC.spad
+ @ echo 0 making ${MID}/LPEFRAC.NRLIB from ${MID}/LPEFRAC.spad
+ @ (cd ${MID} ; echo ')co LPEFRAC.spad' | ${INTERPSYS} )
+
+@
+<<LPEFRAC.spad (SPAD from IN)>>=
+${MID}/LPEFRAC.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/LPEFRAC.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LPEFRAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LPEFRAC LinearPolynomialEquationByFractions" ${IN}/fraction.spad.pamphlet >LPEFRAC.spad )
+
+@
+<<QFCAT-.o (O from NRLIB)>>=
+${OUT}/QFCAT-.o: ${MID}/QFCAT.NRLIB
+ @ echo 0 making ${OUT}/QFCAT-.o from ${MID}/QFCAT-.NRLIB
+ @ cp ${MID}/QFCAT-.NRLIB/code.o ${OUT}/QFCAT-.o
+
+@
+<<QFCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/QFCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/QFCAT.spad
+ @ echo 0 making ${MID}/QFCAT-.NRLIB from ${MID}/QFCAT.spad
+ @ (cd ${MID} ; echo ')co QFCAT.spad' | ${INTERPSYS} )
+
+@
+<<QFCAT.o (O from NRLIB)>>=
+${OUT}/QFCAT.o: ${MID}/QFCAT.NRLIB
+ @ echo 0 making ${OUT}/QFCAT.o from ${MID}/QFCAT.NRLIB
+ @ cp ${MID}/QFCAT.NRLIB/code.o ${OUT}/QFCAT.o
+
+@
+<<QFCAT.NRLIB (NRLIB from MID)>>=
+${MID}/QFCAT.NRLIB: ${MID}/QFCAT.spad
+ @ echo 0 making ${MID}/QFCAT.NRLIB from ${MID}/QFCAT.spad
+ @ (cd ${MID} ; echo ')co QFCAT.spad' | ${INTERPSYS} )
+
+@
+<<QFCAT.spad (SPAD from IN)>>=
+${MID}/QFCAT.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/QFCAT.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QFCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category QFCAT QuotientFieldCategory" ${IN}/fraction.spad.pamphlet >QFCAT.spad )
+
+@
+<<QFCAT-.o (BOOTSTRAP from MID)>>=
+${MID}/QFCAT-.o: ${MID}/QFCAT-.lsp
+ @ echo 0 making ${MID}/QFCAT-.o from ${MID}/QFCAT-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "QFCAT-.lsp" :output-file "QFCAT-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/QFCAT-.o ${OUT}/QFCAT-.o
+
+@
+<<QFCAT-.lsp (LISP from IN)>>=
+${MID}/QFCAT-.lsp: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/QFCAT-.lsp from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QFCAT-.NRLIB ; \
+ rm -rf ${OUT}/QFCAT-.o ; \
+ ${SPADBIN}/notangle -R"QFCAT-.lsp BOOTSTRAP" ${IN}/fraction.spad.pamphlet >QFCAT-.lsp )
+
+@
+<<QFCAT.o (BOOTSTRAP from MID)>>=
+${MID}/QFCAT.o: ${MID}/QFCAT.lsp
+ @ echo 0 making ${MID}/QFCAT.o from ${MID}/QFCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "QFCAT.lsp" :output-file "QFCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/QFCAT.o ${OUT}/QFCAT.o
+
+@
+<<QFCAT.lsp (LISP from IN)>>=
+${MID}/QFCAT.lsp: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/QFCAT.lsp from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QFCAT.NRLIB ; \
+ rm -rf ${OUT}/QFCAT.o ; \
+ ${SPADBIN}/notangle -R"QFCAT.lsp BOOTSTRAP" ${IN}/fraction.spad.pamphlet >QFCAT.lsp )
+
+@
+<<QFCAT2.o (O from NRLIB)>>=
+${OUT}/QFCAT2.o: ${MID}/QFCAT2.NRLIB
+ @ echo 0 making ${OUT}/QFCAT2.o from ${MID}/QFCAT2.NRLIB
+ @ cp ${MID}/QFCAT2.NRLIB/code.o ${OUT}/QFCAT2.o
+
+@
+<<QFCAT2.NRLIB (NRLIB from MID)>>=
+${MID}/QFCAT2.NRLIB: ${MID}/QFCAT2.spad
+ @ echo 0 making ${MID}/QFCAT2.NRLIB from ${MID}/QFCAT2.spad
+ @ (cd ${MID} ; echo ')co QFCAT2.spad' | ${INTERPSYS} )
+
+@
+<<QFCAT2.spad (SPAD from IN)>>=
+${MID}/QFCAT2.spad: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${MID}/QFCAT2.spad from ${IN}/fraction.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QFCAT2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package QFCAT2 QuotientFieldCategoryFunctions2" ${IN}/fraction.spad.pamphlet >QFCAT2.spad )
+
+@
+<<fraction.spad.dvi (DOC from IN)>>=
+${DOC}/fraction.spad.dvi: ${IN}/fraction.spad.pamphlet
+ @ echo 0 making ${DOC}/fraction.spad.dvi from ${IN}/fraction.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fraction.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fraction.spad ; \
+ rm -f ${DOC}/fraction.spad.pamphlet ; \
+ rm -f ${DOC}/fraction.spad.tex ; \
+ rm -f ${DOC}/fraction.spad )
+
+@
+\subsection{free.spad \cite{1}}
+<<free.spad (SPAD from IN)>>=
+${MID}/free.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/free.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/free.spad.pamphlet >free.spad )
+
+@
+<<FAGROUP.o (O from NRLIB)>>=
+${OUT}/FAGROUP.o: ${MID}/FAGROUP.NRLIB
+ @ echo 0 making ${OUT}/FAGROUP.o from ${MID}/FAGROUP.NRLIB
+ @ cp ${MID}/FAGROUP.NRLIB/code.o ${OUT}/FAGROUP.o
+
+@
+<<FAGROUP.NRLIB (NRLIB from MID)>>=
+${MID}/FAGROUP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FAGROUP.spad
+ @ echo 0 making ${MID}/FAGROUP.NRLIB from ${MID}/FAGROUP.spad
+ @ (cd ${MID} ; echo ')co FAGROUP.spad' | ${INTERPSYS} )
+
+@
+<<FAGROUP.spad (SPAD from IN)>>=
+${MID}/FAGROUP.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/FAGROUP.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FAGROUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FAGROUP FreeAbelianGroup" ${IN}/free.spad.pamphlet >FAGROUP.spad )
+
+@
+<<FAMONC.o (O from NRLIB)>>=
+${OUT}/FAMONC.o: ${MID}/FAMONC.NRLIB
+ @ echo 0 making ${OUT}/FAMONC.o from ${MID}/FAMONC.NRLIB
+ @ cp ${MID}/FAMONC.NRLIB/code.o ${OUT}/FAMONC.o
+
+@
+<<FAMONC.NRLIB (NRLIB from MID)>>=
+${MID}/FAMONC.NRLIB: ${OUT}/TYPE.o ${MID}/FAMONC.spad
+ @ echo 0 making ${MID}/FAMONC.NRLIB from ${MID}/FAMONC.spad
+ @ (cd ${MID} ; echo ')co FAMONC.spad' | ${INTERPSYS} )
+
+@
+<<FAMONC.spad (SPAD from IN)>>=
+${MID}/FAMONC.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/FAMONC.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FAMONC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FAMONC FreeAbelianMonoidCategory" ${IN}/free.spad.pamphlet >FAMONC.spad )
+
+@
+<<FGROUP.o (O from NRLIB)>>=
+${OUT}/FGROUP.o: ${MID}/FGROUP.NRLIB
+ @ echo 0 making ${OUT}/FGROUP.o from ${MID}/FGROUP.NRLIB
+ @ cp ${MID}/FGROUP.NRLIB/code.o ${OUT}/FGROUP.o
+
+@
+<<FGROUP.NRLIB (NRLIB from MID)>>=
+${MID}/FGROUP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FGROUP.spad
+ @ echo 0 making ${MID}/FGROUP.NRLIB from ${MID}/FGROUP.spad
+ @ (cd ${MID} ; echo ')co FGROUP.spad' | ${INTERPSYS} )
+
+@
+<<FGROUP.spad (SPAD from IN)>>=
+${MID}/FGROUP.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/FGROUP.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FGROUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FGROUP FreeGroup" ${IN}/free.spad.pamphlet >FGROUP.spad )
+
+@
+<<FAMONOID.o (O from NRLIB)>>=
+${OUT}/FAMONOID.o: ${MID}/FAMONOID.NRLIB
+ @ echo 0 making ${OUT}/FAMONOID.o from ${MID}/FAMONOID.NRLIB
+ @ cp ${MID}/FAMONOID.NRLIB/code.o ${OUT}/FAMONOID.o
+
+@
+<<FAMONOID.NRLIB (NRLIB from MID)>>=
+${MID}/FAMONOID.NRLIB: ${MID}/FAMONOID.spad
+ @ echo 0 making ${MID}/FAMONOID.NRLIB from ${MID}/FAMONOID.spad
+ @ (cd ${MID} ; echo ')co FAMONOID.spad' | ${INTERPSYS} )
+
+@
+<<FAMONOID.spad (SPAD from IN)>>=
+${MID}/FAMONOID.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/FAMONOID.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FAMONOID.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FAMONOID FreeAbelianMonoid" ${IN}/free.spad.pamphlet >FAMONOID.spad )
+
+@
+<<FMONOID.o (O from NRLIB)>>=
+${OUT}/FMONOID.o: ${MID}/FMONOID.NRLIB
+ @ echo 0 making ${OUT}/FMONOID.o from ${MID}/FMONOID.NRLIB
+ @ cp ${MID}/FMONOID.NRLIB/code.o ${OUT}/FMONOID.o
+
+@
+<<FMONOID.NRLIB (NRLIB from MID)>>=
+${MID}/FMONOID.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FMONOID.spad
+ @ echo 0 making ${MID}/FMONOID.NRLIB from ${MID}/FMONOID.spad
+ @ (cd ${MID} ; echo ')co FMONOID.spad' | ${INTERPSYS} )
+
+@
+<<FMONOID.spad (SPAD from IN)>>=
+${MID}/FMONOID.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/FMONOID.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FMONOID.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FMONOID FreeMonoid" ${IN}/free.spad.pamphlet >FMONOID.spad )
+
+@
+<<IFAMON.o (O from NRLIB)>>=
+${OUT}/IFAMON.o: ${MID}/IFAMON.NRLIB
+ @ echo 0 making ${OUT}/IFAMON.o from ${MID}/IFAMON.NRLIB
+ @ cp ${MID}/IFAMON.NRLIB/code.o ${OUT}/IFAMON.o
+
+@
+<<IFAMON.NRLIB (NRLIB from MID)>>=
+${MID}/IFAMON.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IFAMON.spad
+ @ echo 0 making ${MID}/IFAMON.NRLIB from ${MID}/IFAMON.spad
+ @ (cd ${MID} ; echo ')co IFAMON.spad' | ${INTERPSYS} )
+
+@
+<<IFAMON.spad (SPAD from IN)>>=
+${MID}/IFAMON.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/IFAMON.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IFAMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IFAMON InnerFreeAbelianMonoid" ${IN}/free.spad.pamphlet >IFAMON.spad )
+
+@
+<<LMOPS.o (O from NRLIB)>>=
+${OUT}/LMOPS.o: ${MID}/LMOPS.NRLIB
+ @ echo 0 making ${OUT}/LMOPS.o from ${MID}/LMOPS.NRLIB
+ @ cp ${MID}/LMOPS.NRLIB/code.o ${OUT}/LMOPS.o
+
+@
+<<LMOPS.NRLIB (NRLIB from MID)>>=
+${MID}/LMOPS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/LMOPS.spad
+ @ echo 0 making ${MID}/LMOPS.NRLIB from ${MID}/LMOPS.spad
+ @ (cd ${MID} ; echo ')co LMOPS.spad' | ${INTERPSYS} )
+
+@
+<<LMOPS.spad (SPAD from IN)>>=
+${MID}/LMOPS.spad: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${MID}/LMOPS.spad from ${IN}/free.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LMOPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LMOPS ListMonoidOps" ${IN}/free.spad.pamphlet >LMOPS.spad )
+
+@
+<<free.spad.dvi (DOC from IN)>>=
+${DOC}/free.spad.dvi: ${IN}/free.spad.pamphlet
+ @ echo 0 making ${DOC}/free.spad.dvi from ${IN}/free.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/free.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} free.spad ; \
+ rm -f ${DOC}/free.spad.pamphlet ; \
+ rm -f ${DOC}/free.spad.tex ; \
+ rm -f ${DOC}/free.spad )
+
+@
+\subsection{fr.spad \cite{1}}
+<<fr.spad (SPAD from IN)>>=
+${MID}/fr.spad: ${IN}/fr.spad.pamphlet
+ @ echo 0 making ${MID}/fr.spad from ${IN}/fr.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fr.spad.pamphlet >fr.spad )
+
+@
+<<FR.o (O from NRLIB)>>=
+${OUT}/FR.o: ${MID}/FR.NRLIB
+ @ echo 0 making ${OUT}/FR.o from ${MID}/FR.NRLIB
+ @ cp ${MID}/FR.NRLIB/code.o ${OUT}/FR.o
+
+@
+<<FR.NRLIB (NRLIB from MID)>>=
+${MID}/FR.NRLIB: ${MID}/FR.spad
+ @ echo 0 making ${MID}/FR.NRLIB from ${MID}/FR.spad
+ @ (cd ${MID} ; echo ')co FR.spad' | ${INTERPSYS} )
+
+@
+<<FR.spad (SPAD from IN)>>=
+${MID}/FR.spad: ${IN}/fr.spad.pamphlet
+ @ echo 0 making ${MID}/FR.spad from ${IN}/fr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FR Factored" ${IN}/fr.spad.pamphlet >FR.spad )
+
+@
+<<FR2.o (O from NRLIB)>>=
+${OUT}/FR2.o: ${MID}/FR2.NRLIB
+ @ echo 0 making ${OUT}/FR2.o from ${MID}/FR2.NRLIB
+ @ cp ${MID}/FR2.NRLIB/code.o ${OUT}/FR2.o
+
+@
+<<FR2.NRLIB (NRLIB from MID)>>=
+${MID}/FR2.NRLIB: ${MID}/FR2.spad
+ @ echo 0 making ${MID}/FR2.NRLIB from ${MID}/FR2.spad
+ @ (cd ${MID} ; echo ')co FR2.spad' | ${INTERPSYS} )
+
+@
+<<FR2.spad (SPAD from IN)>>=
+${MID}/FR2.spad: ${IN}/fr.spad.pamphlet
+ @ echo 0 making ${MID}/FR2.spad from ${IN}/fr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FR2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FR2 FactoredFunctions2" ${IN}/fr.spad.pamphlet >FR2.spad )
+
+@
+<<FRUTIL.o (O from NRLIB)>>=
+${OUT}/FRUTIL.o: ${MID}/FRUTIL.NRLIB
+ @ echo 0 making ${OUT}/FRUTIL.o from ${MID}/FRUTIL.NRLIB
+ @ cp ${MID}/FRUTIL.NRLIB/code.o ${OUT}/FRUTIL.o
+
+@
+<<FRUTIL.NRLIB (NRLIB from MID)>>=
+${MID}/FRUTIL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FRUTIL.spad
+ @ echo 0 making ${MID}/FRUTIL.NRLIB from ${MID}/FRUTIL.spad
+ @ (cd ${MID} ; echo ')co FRUTIL.spad' | ${INTERPSYS} )
+
+@
+<<FRUTIL.spad (SPAD from IN)>>=
+${MID}/FRUTIL.spad: ${IN}/fr.spad.pamphlet
+ @ echo 0 making ${MID}/FRUTIL.spad from ${IN}/fr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRUTIL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FRUTIL FactoredFunctionUtilities" ${IN}/fr.spad.pamphlet >FRUTIL.spad )
+
+@
+<<fr.spad.dvi (DOC from IN)>>=
+${DOC}/fr.spad.dvi: ${IN}/fr.spad.pamphlet
+ @ echo 0 making ${DOC}/fr.spad.dvi from ${IN}/fr.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fr.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fr.spad ; \
+ rm -f ${DOC}/fr.spad.pamphlet ; \
+ rm -f ${DOC}/fr.spad.tex ; \
+ rm -f ${DOC}/fr.spad )
+
+@
+\subsection{fs2expxp.spad \cite{1}}
+<<fs2expxp.spad (SPAD from IN)>>=
+${MID}/fs2expxp.spad: ${IN}/fs2expxp.spad.pamphlet
+ @ echo 0 making ${MID}/fs2expxp.spad from ${IN}/fs2expxp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fs2expxp.spad.pamphlet >fs2expxp.spad )
+
+@
+<<FS2EXPXP.o (O from NRLIB)>>=
+${OUT}/FS2EXPXP.o: ${MID}/FS2EXPXP.NRLIB
+ @ echo 0 making ${OUT}/FS2EXPXP.o from ${MID}/FS2EXPXP.NRLIB
+ @ cp ${MID}/FS2EXPXP.NRLIB/code.o ${OUT}/FS2EXPXP.o
+
+@
+<<FS2EXPXP.NRLIB (NRLIB from MID)>>=
+${MID}/FS2EXPXP.NRLIB: ${MID}/FS2EXPXP.spad
+ @ echo 0 making ${MID}/FS2EXPXP.NRLIB from ${MID}/FS2EXPXP.spad
+ @ (cd ${MID} ; echo ')co FS2EXPXP.spad' | ${INTERPSYS} )
+
+@
+<<FS2EXPXP.spad (SPAD from IN)>>=
+${MID}/FS2EXPXP.spad: ${IN}/fs2expxp.spad.pamphlet
+ @ echo 0 making ${MID}/FS2EXPXP.spad from ${IN}/fs2expxp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FS2EXPXP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FS2EXPXP FunctionSpaceToExponentialExpansion" ${IN}/fs2expxp.spad.pamphlet >FS2EXPXP.spad )
+
+@
+<<fs2expxp.spad.dvi (DOC from IN)>>=
+${DOC}/fs2expxp.spad.dvi: ${IN}/fs2expxp.spad.pamphlet
+ @ echo 0 making ${DOC}/fs2expxp.spad.dvi from ${IN}/fs2expxp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fs2expxp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fs2expxp.spad ; \
+ rm -f ${DOC}/fs2expxp.spad.pamphlet ; \
+ rm -f ${DOC}/fs2expxp.spad.tex ; \
+ rm -f ${DOC}/fs2expxp.spad )
+
+@
+\subsection{fs2ups.spad \cite{1}}
+<<fs2ups.spad (SPAD from IN)>>=
+${MID}/fs2ups.spad: ${IN}/fs2ups.spad.pamphlet
+ @ echo 0 making ${MID}/fs2ups.spad from ${IN}/fs2ups.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fs2ups.spad.pamphlet >fs2ups.spad )
+
+@
+<<FS2UPS.o (O from NRLIB)>>=
+${OUT}/FS2UPS.o: ${MID}/FS2UPS.NRLIB
+ @ echo 0 making ${OUT}/FS2UPS.o from ${MID}/FS2UPS.NRLIB
+ @ cp ${MID}/FS2UPS.NRLIB/code.o ${OUT}/FS2UPS.o
+
+@
+<<FS2UPS.NRLIB (NRLIB from MID)>>=
+${MID}/FS2UPS.NRLIB: ${MID}/FS2UPS.spad
+ @ echo 0 making ${MID}/FS2UPS.NRLIB from ${MID}/FS2UPS.spad
+ @ (cd ${MID} ; echo ')co FS2UPS.spad' | ${INTERPSYS} )
+
+@
+<<FS2UPS.spad (SPAD from IN)>>=
+${MID}/FS2UPS.spad: ${IN}/fs2ups.spad.pamphlet
+ @ echo 0 making ${MID}/FS2UPS.spad from ${IN}/fs2ups.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FS2UPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FS2UPS FunctionSpaceToUnivariatePowerSeries" ${IN}/fs2ups.spad.pamphlet >FS2UPS.spad )
+
+@
+<<fs2ups.spad.dvi (DOC from IN)>>=
+${DOC}/fs2ups.spad.dvi: ${IN}/fs2ups.spad.pamphlet
+ @ echo 0 making ${DOC}/fs2ups.spad.dvi from ${IN}/fs2ups.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fs2ups.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fs2ups.spad ; \
+ rm -f ${DOC}/fs2ups.spad.pamphlet ; \
+ rm -f ${DOC}/fs2ups.spad.tex ; \
+ rm -f ${DOC}/fs2ups.spad )
+
+@
+\subsection{fspace.spad \cite{1}}
+<<fspace.spad (SPAD from IN)>>=
+${MID}/fspace.spad: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/fspace.spad from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/fspace.spad.pamphlet >fspace.spad )
+
+@
+<<ES-.o (O from NRLIB)>>=
+${OUT}/ES-.o: ${MID}/ES.NRLIB
+ @ echo 0 making ${OUT}/ES-.o from ${MID}/ES-.NRLIB
+ @ cp ${MID}/ES-.NRLIB/code.o ${OUT}/ES-.o
+
+@
+<<ES-.NRLIB (NRLIB from MID)>>=
+${MID}/ES-.NRLIB: ${OUT}/TYPE.o ${MID}/ES.spad
+ @ echo 0 making ${MID}/ES-.NRLIB from ${MID}/ES.spad
+ @ (cd ${MID} ; echo ')co ES.spad' | ${INTERPSYS} )
+
+@
+<<ES.o (O from NRLIB)>>=
+${OUT}/ES.o: ${MID}/ES.NRLIB
+ @ echo 0 making ${OUT}/ES.o from ${MID}/ES.NRLIB
+ @ cp ${MID}/ES.NRLIB/code.o ${OUT}/ES.o
+
+@
+<<ES.NRLIB (NRLIB from MID)>>=
+${MID}/ES.NRLIB: ${MID}/ES.spad
+ @ echo 0 making ${MID}/ES.NRLIB from ${MID}/ES.spad
+ @ (cd ${MID} ; echo ')co ES.spad' | ${INTERPSYS} )
+
+@
+<<ES.spad (SPAD from IN)>>=
+${MID}/ES.spad: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/ES.spad from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ES.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ES ExpressionSpace" ${IN}/fspace.spad.pamphlet >ES.spad )
+
+@
+<<ES-.o (BOOTSTRAP from MID)>>=
+${MID}/ES-.o: ${MID}/ES-.lsp
+ @ echo 0 making ${MID}/ES-.o from ${MID}/ES-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ES-.lsp" :output-file "ES-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ES-.o ${OUT}/ES-.o
+
+@
+<<ES-.lsp (LISP from IN)>>=
+${MID}/ES-.lsp: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/ES-.lsp from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ES-.NRLIB ; \
+ rm -rf ${OUT}/ES-.o ; \
+ ${SPADBIN}/notangle -R"ES-.lsp BOOTSTRAP" ${IN}/fspace.spad.pamphlet >ES-.lsp )
+
+@
+<<ES.o (BOOTSTRAP from MID)>>=
+${MID}/ES.o: ${MID}/ES.lsp
+ @ echo 0 making ${MID}/ES.o from ${MID}/ES.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ES.lsp" :output-file "ES.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ES.o ${OUT}/ES.o
+
+@
+<<ES.lsp (LISP from IN)>>=
+${MID}/ES.lsp: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/ES.lsp from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ES.NRLIB ; \
+ rm -rf ${OUT}/ES.o ; \
+ ${SPADBIN}/notangle -R"ES.lsp BOOTSTRAP" ${IN}/fspace.spad.pamphlet >ES.lsp )
+
+@
+<<ES1.o (O from NRLIB)>>=
+${OUT}/ES1.o: ${MID}/ES1.NRLIB
+ @ echo 0 making ${OUT}/ES1.o from ${MID}/ES1.NRLIB
+ @ cp ${MID}/ES1.NRLIB/code.o ${OUT}/ES1.o
+
+@
+<<ES1.NRLIB (NRLIB from MID)>>=
+${MID}/ES1.NRLIB: ${MID}/ES1.spad
+ @ echo 0 making ${MID}/ES1.NRLIB from ${MID}/ES1.spad
+ @ (cd ${MID} ; echo ')co ES1.spad' | ${INTERPSYS} )
+
+@
+<<ES1.spad (SPAD from IN)>>=
+${MID}/ES1.spad: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/ES1.spad from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ES1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ES1 ExpressionSpaceFunctions1" ${IN}/fspace.spad.pamphlet >ES1.spad )
+
+@
+<<ES2.o (O from NRLIB)>>=
+${OUT}/ES2.o: ${MID}/ES2.NRLIB
+ @ echo 0 making ${OUT}/ES2.o from ${MID}/ES2.NRLIB
+ @ cp ${MID}/ES2.NRLIB/code.o ${OUT}/ES2.o
+
+@
+<<ES2.NRLIB (NRLIB from MID)>>=
+${MID}/ES2.NRLIB: ${MID}/ES2.spad
+ @ echo 0 making ${MID}/ES2.NRLIB from ${MID}/ES2.spad
+ @ (cd ${MID} ; echo ')co ES2.spad' | ${INTERPSYS} )
+
+@
+<<ES2.spad (SPAD from IN)>>=
+${MID}/ES2.spad: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/ES2.spad from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ES2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ES2 ExpressionSpaceFunctions2" ${IN}/fspace.spad.pamphlet >ES2.spad )
+
+@
+<<FS-.o (O from NRLIB)>>=
+${OUT}/FS-.o: ${MID}/FS.NRLIB
+ @ echo 0 making ${OUT}/FS-.o from ${MID}/FS-.NRLIB
+ @ cp ${MID}/FS-.NRLIB/code.o ${OUT}/FS-.o
+
+@
+<<FS-.NRLIB (NRLIB from MID)>>=
+${MID}/FS-.NRLIB: ${OUT}/TYPE.o ${MID}/FS.spad
+ @ echo 0 making ${MID}/FS-.NRLIB from ${MID}/FS.spad
+ @ (cd ${MID} ; echo ')co FS.spad' | ${INTERPSYS} )
+
+@
+<<FS.o (O from NRLIB)>>=
+${OUT}/FS.o: ${MID}/FS.NRLIB
+ @ echo 0 making ${OUT}/FS.o from ${MID}/FS.NRLIB
+ @ cp ${MID}/FS.NRLIB/code.o ${OUT}/FS.o
+
+@
+<<FS.NRLIB (NRLIB from MID)>>=
+${MID}/FS.NRLIB: ${MID}/FS.spad
+ @ echo 0 making ${MID}/FS.NRLIB from ${MID}/FS.spad
+ @ (cd ${MID} ; echo ')co FS.spad' | ${INTERPSYS} )
+
+@
+<<FS.spad (SPAD from IN)>>=
+${MID}/FS.spad: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/FS.spad from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FS FunctionSpace" ${IN}/fspace.spad.pamphlet >FS.spad )
+
+@
+<<FS2.o (O from NRLIB)>>=
+${OUT}/FS2.o: ${MID}/FS2.NRLIB
+ @ echo 0 making ${OUT}/FS2.o from ${MID}/FS2.NRLIB
+ @ cp ${MID}/FS2.NRLIB/code.o ${OUT}/FS2.o
+
+@
+<<FS2.NRLIB (NRLIB from MID)>>=
+${MID}/FS2.NRLIB: ${MID}/FS2.spad
+ @ echo 0 making ${MID}/FS2.NRLIB from ${MID}/FS2.spad
+ @ (cd ${MID} ; echo ')co FS2.spad' | ${INTERPSYS} )
+
+@
+<<FS2.spad (SPAD from IN)>>=
+${MID}/FS2.spad: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${MID}/FS2.spad from ${IN}/fspace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FS2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FS2 FunctionSpaceFunctions2" ${IN}/fspace.spad.pamphlet >FS2.spad )
+
+@
+<<fspace.spad.dvi (DOC from IN)>>=
+${DOC}/fspace.spad.dvi: ${IN}/fspace.spad.pamphlet
+ @ echo 0 making ${DOC}/fspace.spad.dvi from ${IN}/fspace.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/fspace.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} fspace.spad ; \
+ rm -f ${DOC}/fspace.spad.pamphlet ; \
+ rm -f ${DOC}/fspace.spad.tex ; \
+ rm -f ${DOC}/fspace.spad )
+
+@
+\subsection{funcpkgs.spad \cite{1}}
+<<funcpkgs.spad (SPAD from IN)>>=
+${MID}/funcpkgs.spad: ${IN}/funcpkgs.spad.pamphlet
+ @ echo 0 making ${MID}/funcpkgs.spad from ${IN}/funcpkgs.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/funcpkgs.spad.pamphlet >funcpkgs.spad )
+
+@
+<<FSUPFACT.o (O from NRLIB)>>=
+${OUT}/FSUPFACT.o: ${MID}/FSUPFACT.NRLIB
+ @ echo 0 making ${OUT}/FSUPFACT.o from ${MID}/FSUPFACT.NRLIB
+ @ cp ${MID}/FSUPFACT.NRLIB/code.o ${OUT}/FSUPFACT.o
+
+@
+<<FSUPFACT.NRLIB (NRLIB from MID)>>=
+${MID}/FSUPFACT.NRLIB: ${MID}/FSUPFACT.spad
+ @ echo 0 making ${MID}/FSUPFACT.NRLIB from ${MID}/FSUPFACT.spad
+ @ (cd ${MID} ; echo ')co FSUPFACT.spad' | ${INTERPSYS} )
+
+@
+<<FSUPFACT.spad (SPAD from IN)>>=
+${MID}/FSUPFACT.spad: ${IN}/funcpkgs.spad.pamphlet
+ @ echo 0 making ${MID}/FSUPFACT.spad from ${IN}/funcpkgs.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSUPFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSUPFACT FunctionSpaceUnivariatePolynomialFactor" ${IN}/funcpkgs.spad.pamphlet >FSUPFACT.spad )
+
+@
+<<funcpkgs.spad.dvi (DOC from IN)>>=
+${DOC}/funcpkgs.spad.dvi: ${IN}/funcpkgs.spad.pamphlet
+ @ echo 0 making ${DOC}/funcpkgs.spad.dvi from ${IN}/funcpkgs.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/funcpkgs.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} funcpkgs.spad ; \
+ rm -f ${DOC}/funcpkgs.spad.pamphlet ; \
+ rm -f ${DOC}/funcpkgs.spad.tex ; \
+ rm -f ${DOC}/funcpkgs.spad )
+
+@
+\subsection{functions.spad \cite{1}}
+<<functions.spad (SPAD from IN)>>=
+${MID}/functions.spad: ${IN}/functions.spad.pamphlet
+ @ echo 0 making ${MID}/functions.spad from ${IN}/functions.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/functions.spad.pamphlet >functions.spad )
+
+@
+<<BFUNCT.o (O from NRLIB)>>=
+${OUT}/BFUNCT.o: ${MID}/BFUNCT.NRLIB
+ @ echo 0 making ${OUT}/BFUNCT.o from ${MID}/BFUNCT.NRLIB
+ @ cp ${MID}/BFUNCT.NRLIB/code.o ${OUT}/BFUNCT.o
+
+@
+<<BFUNCT.NRLIB (NRLIB from MID)>>=
+${MID}/BFUNCT.NRLIB: ${MID}/BFUNCT.spad
+ @ echo 0 making ${MID}/BFUNCT.NRLIB from ${MID}/BFUNCT.spad
+ @ (cd ${MID} ; echo ')co BFUNCT.spad' | ${INTERPSYS} )
+
+@
+<<BFUNCT.spad (SPAD from IN)>>=
+${MID}/BFUNCT.spad: ${IN}/functions.spad.pamphlet
+ @ echo 0 making ${MID}/BFUNCT.spad from ${IN}/functions.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BFUNCT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BFUNCT BasicFunctions" ${IN}/functions.spad.pamphlet >BFUNCT.spad )
+
+@
+<<functions.spad.dvi (DOC from IN)>>=
+${DOC}/functions.spad.dvi: ${IN}/functions.spad.pamphlet
+ @ echo 0 making ${DOC}/functions.spad.dvi from ${IN}/functions.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/functions.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} functions.spad ; \
+ rm -f ${DOC}/functions.spad.pamphlet ; \
+ rm -f ${DOC}/functions.spad.tex ; \
+ rm -f ${DOC}/functions.spad )
+
+@
+\subsection{galfact.spad \cite{1}}
+<<galfact.spad (SPAD from IN)>>=
+${MID}/galfact.spad: ${IN}/galfact.spad.pamphlet
+ @ echo 0 making ${MID}/galfact.spad from ${IN}/galfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/galfact.spad.pamphlet >galfact.spad )
+
+@
+<<GALFACT.o (O from NRLIB)>>=
+${OUT}/GALFACT.o: ${MID}/GALFACT.NRLIB
+ @ echo 0 making ${OUT}/GALFACT.o from ${MID}/GALFACT.NRLIB
+ @ cp ${MID}/GALFACT.NRLIB/code.o ${OUT}/GALFACT.o
+
+@
+<<GALFACT.NRLIB (NRLIB from MID)>>=
+${MID}/GALFACT.NRLIB: ${MID}/GALFACT.spad
+ @ echo 0 making ${MID}/GALFACT.NRLIB from ${MID}/GALFACT.spad
+ @ (cd ${MID} ; echo ')co GALFACT.spad' | ${INTERPSYS} )
+
+@
+<<GALFACT.spad (SPAD from IN)>>=
+${MID}/GALFACT.spad: ${IN}/galfact.spad.pamphlet
+ @ echo 0 making ${MID}/GALFACT.spad from ${IN}/galfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GALFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GALFACT GaloisGroupFactorizer" ${IN}/galfact.spad.pamphlet >GALFACT.spad )
+
+@
+<<galfact.spad.dvi (DOC from IN)>>=
+${DOC}/galfact.spad.dvi: ${IN}/galfact.spad.pamphlet
+ @ echo 0 making ${DOC}/galfact.spad.dvi from ${IN}/galfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/galfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} galfact.spad ; \
+ rm -f ${DOC}/galfact.spad.pamphlet ; \
+ rm -f ${DOC}/galfact.spad.tex ; \
+ rm -f ${DOC}/galfact.spad )
+
+@
+\subsection{galfactu.spad \cite{1}}
+<<galfactu.spad (SPAD from IN)>>=
+${MID}/galfactu.spad: ${IN}/galfactu.spad.pamphlet
+ @ echo 0 making ${MID}/galfactu.spad from ${IN}/galfactu.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/galfactu.spad.pamphlet >galfactu.spad )
+
+@
+<<GALFACTU.o (O from NRLIB)>>=
+${OUT}/GALFACTU.o: ${MID}/GALFACTU.NRLIB
+ @ echo 0 making ${OUT}/GALFACTU.o from ${MID}/GALFACTU.NRLIB
+ @ cp ${MID}/GALFACTU.NRLIB/code.o ${OUT}/GALFACTU.o
+
+@
+<<GALFACTU.NRLIB (NRLIB from MID)>>=
+${MID}/GALFACTU.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GALFACTU.spad
+ @ echo 0 making ${MID}/GALFACTU.NRLIB from ${MID}/GALFACTU.spad
+ @ (cd ${MID} ; echo ')co GALFACTU.spad' | ${INTERPSYS} )
+
+@
+<<GALFACTU.spad (SPAD from IN)>>=
+${MID}/GALFACTU.spad: ${IN}/galfactu.spad.pamphlet
+ @ echo 0 making ${MID}/GALFACTU.spad from ${IN}/galfactu.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GALFACTU.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GALFACTU GaloisGroupFactorizationUtilities" ${IN}/galfactu.spad.pamphlet >GALFACTU.spad )
+
+@
+<<galfactu.spad.dvi (DOC from IN)>>=
+${DOC}/galfactu.spad.dvi: ${IN}/galfactu.spad.pamphlet
+ @ echo 0 making ${DOC}/galfactu.spad.dvi from ${IN}/galfactu.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/galfactu.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} galfactu.spad ; \
+ rm -f ${DOC}/galfactu.spad.pamphlet ; \
+ rm -f ${DOC}/galfactu.spad.tex ; \
+ rm -f ${DOC}/galfactu.spad )
+
+@
+\subsection{galpolyu.spad \cite{1}}
+<<galpolyu.spad (SPAD from IN)>>=
+${MID}/galpolyu.spad: ${IN}/galpolyu.spad.pamphlet
+ @ echo 0 making ${MID}/galpolyu.spad from ${IN}/galpolyu.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/galpolyu.spad.pamphlet >galpolyu.spad )
+
+@
+<<GALPOLYU.o (O from NRLIB)>>=
+${OUT}/GALPOLYU.o: ${MID}/GALPOLYU.NRLIB
+ @ echo 0 making ${OUT}/GALPOLYU.o from ${MID}/GALPOLYU.NRLIB
+ @ cp ${MID}/GALPOLYU.NRLIB/code.o ${OUT}/GALPOLYU.o
+
+@
+<<GALPOLYU.NRLIB (NRLIB from MID)>>=
+${MID}/GALPOLYU.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GALPOLYU.spad
+ @ echo 0 making ${MID}/GALPOLYU.NRLIB from ${MID}/GALPOLYU.spad
+ @ (cd ${MID} ; echo ')co GALPOLYU.spad' | ${INTERPSYS} )
+
+@
+<<GALPOLYU.spad (SPAD from IN)>>=
+${MID}/GALPOLYU.spad: ${IN}/galpolyu.spad.pamphlet
+ @ echo 0 making ${MID}/GALPOLYU.spad from ${IN}/galpolyu.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GALPOLYU.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GALPOLYU GaloisGroupPolynomialUtilities" ${IN}/galpolyu.spad.pamphlet >GALPOLYU.spad )
+
+@
+<<galpolyu.spad.dvi (DOC from IN)>>=
+${DOC}/galpolyu.spad.dvi: ${IN}/galpolyu.spad.pamphlet
+ @ echo 0 making ${DOC}/galpolyu.spad.dvi from ${IN}/galpolyu.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/galpolyu.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} galpolyu.spad ; \
+ rm -f ${DOC}/galpolyu.spad.pamphlet ; \
+ rm -f ${DOC}/galpolyu.spad.tex ; \
+ rm -f ${DOC}/galpolyu.spad )
+
+@
+\subsection{galutil.spad \cite{1}}
+<<galutil.spad (SPAD from IN)>>=
+${MID}/galutil.spad: ${IN}/galutil.spad.pamphlet
+ @ echo 0 making ${MID}/galutil.spad from ${IN}/galutil.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/galutil.spad.pamphlet >galutil.spad )
+
+@
+<<GALUTIL.o (O from NRLIB)>>=
+${OUT}/GALUTIL.o: ${MID}/GALUTIL.NRLIB
+ @ echo 0 making ${OUT}/GALUTIL.o from ${MID}/GALUTIL.NRLIB
+ @ cp ${MID}/GALUTIL.NRLIB/code.o ${OUT}/GALUTIL.o
+
+@
+<<GALUTIL.NRLIB (NRLIB from MID)>>=
+${MID}/GALUTIL.NRLIB: ${MID}/GALUTIL.spad
+ @ echo 0 making ${MID}/GALUTIL.NRLIB from ${MID}/GALUTIL.spad
+ @ (cd ${MID} ; echo ')co GALUTIL.spad' | ${INTERPSYS} )
+
+@
+<<GALUTIL.spad (SPAD from IN)>>=
+${MID}/GALUTIL.spad: ${IN}/galutil.spad.pamphlet
+ @ echo 0 making ${MID}/GALUTIL.spad from ${IN}/galutil.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GALUTIL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GALUTIL GaloisGroupUtilities" ${IN}/galutil.spad.pamphlet >GALUTIL.spad )
+
+@
+<<galutil.spad.dvi (DOC from IN)>>=
+${DOC}/galutil.spad.dvi: ${IN}/galutil.spad.pamphlet
+ @ echo 0 making ${DOC}/galutil.spad.dvi from ${IN}/galutil.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/galutil.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} galutil.spad ; \
+ rm -f ${DOC}/galutil.spad.pamphlet ; \
+ rm -f ${DOC}/galutil.spad.tex ; \
+ rm -f ${DOC}/galutil.spad )
+
+@
+\subsection{gaussfac.spad \cite{1}}
+<<gaussfac.spad (SPAD from IN)>>=
+${MID}/gaussfac.spad: ${IN}/gaussfac.spad.pamphlet
+ @ echo 0 making ${MID}/gaussfac.spad from ${IN}/gaussfac.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gaussfac.spad.pamphlet >gaussfac.spad )
+
+@
+<<GAUSSFAC.o (O from NRLIB)>>=
+${OUT}/GAUSSFAC.o: ${MID}/GAUSSFAC.NRLIB
+ @ echo 0 making ${OUT}/GAUSSFAC.o from ${MID}/GAUSSFAC.NRLIB
+ @ cp ${MID}/GAUSSFAC.NRLIB/code.o ${OUT}/GAUSSFAC.o
+
+@
+<<GAUSSFAC.NRLIB (NRLIB from MID)>>=
+${MID}/GAUSSFAC.NRLIB: ${MID}/GAUSSFAC.spad
+ @ echo 0 making ${MID}/GAUSSFAC.NRLIB from ${MID}/GAUSSFAC.spad
+ @ (cd ${MID} ; echo ')co GAUSSFAC.spad' | ${INTERPSYS} )
+
+@
+<<GAUSSFAC.spad (SPAD from IN)>>=
+${MID}/GAUSSFAC.spad: ${IN}/gaussfac.spad.pamphlet
+ @ echo 0 making ${MID}/GAUSSFAC.spad from ${IN}/gaussfac.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GAUSSFAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GAUSSFAC GaussianFactorizationPackage" ${IN}/gaussfac.spad.pamphlet >GAUSSFAC.spad )
+
+@
+<<gaussfac.spad.dvi (DOC from IN)>>=
+${DOC}/gaussfac.spad.dvi: ${IN}/gaussfac.spad.pamphlet
+ @ echo 0 making ${DOC}/gaussfac.spad.dvi from ${IN}/gaussfac.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gaussfac.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gaussfac.spad ; \
+ rm -f ${DOC}/gaussfac.spad.pamphlet ; \
+ rm -f ${DOC}/gaussfac.spad.tex ; \
+ rm -f ${DOC}/gaussfac.spad )
+
+@
+\subsection{gaussian.spad \cite{1}}
+<<gaussian.spad (SPAD from IN)>>=
+${MID}/gaussian.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/gaussian.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gaussian.spad.pamphlet >gaussian.spad )
+
+@
+<<CINTSLPE.o (O from NRLIB)>>=
+${OUT}/CINTSLPE.o: ${MID}/CINTSLPE.NRLIB
+ @ echo 0 making ${OUT}/CINTSLPE.o from ${MID}/CINTSLPE.NRLIB
+ @ cp ${MID}/CINTSLPE.NRLIB/code.o ${OUT}/CINTSLPE.o
+
+@
+<<CINTSLPE.NRLIB (NRLIB from MID)>>=
+${MID}/CINTSLPE.NRLIB: ${MID}/CINTSLPE.spad
+ @ echo 0 making ${MID}/CINTSLPE.NRLIB from ${MID}/CINTSLPE.spad
+ @ (cd ${MID} ; echo ')co CINTSLPE.spad' | ${INTERPSYS} )
+
+@
+<<CINTSLPE.spad (SPAD from IN)>>=
+${MID}/CINTSLPE.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/CINTSLPE.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CINTSLPE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation" ${IN}/gaussian.spad.pamphlet >CINTSLPE.spad )
+
+@
+<<COMPCAT-.o (O from NRLIB)>>=
+${OUT}/COMPCAT-.o: ${MID}/COMPCAT.NRLIB
+ @ echo 0 making ${OUT}/COMPCAT-.o from ${MID}/COMPCAT-.NRLIB
+ @ cp ${MID}/COMPCAT-.NRLIB/code.o ${OUT}/COMPCAT-.o
+
+@
+<<COMPCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/COMPCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/COMPCAT.spad
+ @ echo 0 making ${MID}/COMPCAT-.NRLIB from ${MID}/COMPCAT.spad
+ @ (cd ${MID} ; echo ')co COMPCAT.spad' | ${INTERPSYS} )
+
+@
+<<COMPCAT.o (O from NRLIB)>>=
+${OUT}/COMPCAT.o: ${MID}/COMPCAT.NRLIB
+ @ echo 0 making ${OUT}/COMPCAT.o from ${MID}/COMPCAT.NRLIB
+ @ cp ${MID}/COMPCAT.NRLIB/code.o ${OUT}/COMPCAT.o
+
+@
+<<COMPCAT.NRLIB (NRLIB from MID)>>=
+${MID}/COMPCAT.NRLIB: ${MID}/COMPCAT.spad
+ @ echo 0 making ${MID}/COMPCAT.NRLIB from ${MID}/COMPCAT.spad
+ @ (cd ${MID} ; echo ')co COMPCAT.spad' | ${INTERPSYS} )
+
+@
+<<COMPCAT.spad (SPAD from IN)>>=
+${MID}/COMPCAT.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/COMPCAT.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMPCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category COMPCAT ComplexCategory" ${IN}/gaussian.spad.pamphlet >COMPCAT.spad )
+
+@
+<<COMPFACT.o (O from NRLIB)>>=
+${OUT}/COMPFACT.o: ${MID}/COMPFACT.NRLIB
+ @ echo 0 making ${OUT}/COMPFACT.o from ${MID}/COMPFACT.NRLIB
+ @ cp ${MID}/COMPFACT.NRLIB/code.o ${OUT}/COMPFACT.o
+
+@
+<<COMPFACT.NRLIB (NRLIB from MID)>>=
+${MID}/COMPFACT.NRLIB: ${MID}/COMPFACT.spad
+ @ echo 0 making ${MID}/COMPFACT.NRLIB from ${MID}/COMPFACT.spad
+ @ (cd ${MID} ; echo ')co COMPFACT.spad' | ${INTERPSYS} )
+
+@
+<<COMPFACT.spad (SPAD from IN)>>=
+${MID}/COMPFACT.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/COMPFACT.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMPFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMPFACT ComplexFactorization" ${IN}/gaussian.spad.pamphlet >COMPFACT.spad )
+
+@
+<<COMPLEX.o (O from NRLIB)>>=
+${OUT}/COMPLEX.o: ${MID}/COMPLEX.NRLIB
+ @ echo 0 making ${OUT}/COMPLEX.o from ${MID}/COMPLEX.NRLIB
+ @ cp ${MID}/COMPLEX.NRLIB/code.o ${OUT}/COMPLEX.o
+
+@
+<<COMPLEX.NRLIB (NRLIB from MID)>>=
+${MID}/COMPLEX.NRLIB: ${MID}/COMPLEX.spad
+ @ echo 0 making ${MID}/COMPLEX.NRLIB from ${MID}/COMPLEX.spad
+ @ (cd ${MID} ; echo ')co COMPLEX.spad' | ${INTERPSYS} )
+
+@
+<<COMPLEX.spad (SPAD from IN)>>=
+${MID}/COMPLEX.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/COMPLEX.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMPLEX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain COMPLEX Complex" ${IN}/gaussian.spad.pamphlet >COMPLEX.spad )
+
+@
+<<COMPLEX2.o (O from NRLIB)>>=
+${OUT}/COMPLEX2.o: ${MID}/COMPLEX2.NRLIB
+ @ echo 0 making ${OUT}/COMPLEX2.o from ${MID}/COMPLEX2.NRLIB
+ @ cp ${MID}/COMPLEX2.NRLIB/code.o ${OUT}/COMPLEX2.o
+
+@
+<<COMPLEX2.NRLIB (NRLIB from MID)>>=
+${MID}/COMPLEX2.NRLIB: ${MID}/COMPLEX2.spad
+ @ echo 0 making ${MID}/COMPLEX2.NRLIB from ${MID}/COMPLEX2.spad
+ @ (cd ${MID} ; echo ')co COMPLEX2.spad' | ${INTERPSYS} )
+
+@
+<<COMPLEX2.spad (SPAD from IN)>>=
+${MID}/COMPLEX2.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/COMPLEX2.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMPLEX2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMPLEX2 ComplexFunctions2" ${IN}/gaussian.spad.pamphlet >COMPLEX2.spad )
+
+@
+<<COMPLPAT.o (O from NRLIB)>>=
+${OUT}/COMPLPAT.o: ${MID}/COMPLPAT.NRLIB
+ @ echo 0 making ${OUT}/COMPLPAT.o from ${MID}/COMPLPAT.NRLIB
+ @ cp ${MID}/COMPLPAT.NRLIB/code.o ${OUT}/COMPLPAT.o
+
+@
+<<COMPLPAT.NRLIB (NRLIB from MID)>>=
+${MID}/COMPLPAT.NRLIB: ${MID}/COMPLPAT.spad
+ @ echo 0 making ${MID}/COMPLPAT.NRLIB from ${MID}/COMPLPAT.spad
+ @ (cd ${MID} ; echo ')co COMPLPAT.spad' | ${INTERPSYS} )
+
+@
+<<COMPLPAT.spad (SPAD from IN)>>=
+${MID}/COMPLPAT.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/COMPLPAT.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMPLPAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMPLPAT ComplexPattern" ${IN}/gaussian.spad.pamphlet >COMPLPAT.spad )
+
+@
+<<CPMATCH.o (O from NRLIB)>>=
+${OUT}/CPMATCH.o: ${MID}/CPMATCH.NRLIB
+ @ echo 0 making ${OUT}/CPMATCH.o from ${MID}/CPMATCH.NRLIB
+ @ cp ${MID}/CPMATCH.NRLIB/code.o ${OUT}/CPMATCH.o
+
+@
+<<CPMATCH.NRLIB (NRLIB from MID)>>=
+${MID}/CPMATCH.NRLIB: ${MID}/CPMATCH.spad
+ @ echo 0 making ${MID}/CPMATCH.NRLIB from ${MID}/CPMATCH.spad
+ @ (cd ${MID} ; echo ')co CPMATCH.spad' | ${INTERPSYS} )
+
+@
+<<CPMATCH.spad (SPAD from IN)>>=
+${MID}/CPMATCH.spad: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${MID}/CPMATCH.spad from ${IN}/gaussian.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CPMATCH.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CPMATCH ComplexPatternMatch" ${IN}/gaussian.spad.pamphlet >CPMATCH.spad )
+
+@
+<<gaussian.spad.dvi (DOC from IN)>>=
+${DOC}/gaussian.spad.dvi: ${IN}/gaussian.spad.pamphlet
+ @ echo 0 making ${DOC}/gaussian.spad.dvi from ${IN}/gaussian.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gaussian.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gaussian.spad ; \
+ rm -f ${DOC}/gaussian.spad.pamphlet ; \
+ rm -f ${DOC}/gaussian.spad.tex ; \
+ rm -f ${DOC}/gaussian.spad )
+
+@
+\subsection{gbeuclid.spad \cite{1}}
+<<gbeuclid.spad (SPAD from IN)>>=
+${MID}/gbeuclid.spad: ${IN}/gbeuclid.spad.pamphlet
+ @ echo 0 making ${MID}/gbeuclid.spad from ${IN}/gbeuclid.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gbeuclid.spad.pamphlet >gbeuclid.spad )
+
+@
+<<GBEUCLID.o (O from NRLIB)>>=
+${OUT}/GBEUCLID.o: ${MID}/GBEUCLID.NRLIB
+ @ echo 0 making ${OUT}/GBEUCLID.o from ${MID}/GBEUCLID.NRLIB
+ @ cp ${MID}/GBEUCLID.NRLIB/code.o ${OUT}/GBEUCLID.o
+
+@
+<<GBEUCLID.NRLIB (NRLIB from MID)>>=
+${MID}/GBEUCLID.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GBEUCLID.spad
+ @ echo 0 making ${MID}/GBEUCLID.NRLIB from ${MID}/GBEUCLID.spad
+ @ (cd ${MID} ; echo ')co GBEUCLID.spad' | ${INTERPSYS} )
+
+@
+<<GBEUCLID.spad (SPAD from IN)>>=
+${MID}/GBEUCLID.spad: ${IN}/gbeuclid.spad.pamphlet
+ @ echo 0 making ${MID}/GBEUCLID.spad from ${IN}/gbeuclid.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GBEUCLID.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GBEUCLID EuclideanGroebnerBasisPackage" ${IN}/gbeuclid.spad.pamphlet >GBEUCLID.spad )
+
+@
+<<gbeuclid.spad.dvi (DOC from IN)>>=
+${DOC}/gbeuclid.spad.dvi: ${IN}/gbeuclid.spad.pamphlet
+ @ echo 0 making ${DOC}/gbeuclid.spad.dvi from ${IN}/gbeuclid.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gbeuclid.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gbeuclid.spad ; \
+ rm -f ${DOC}/gbeuclid.spad.pamphlet ; \
+ rm -f ${DOC}/gbeuclid.spad.tex ; \
+ rm -f ${DOC}/gbeuclid.spad )
+
+@
+\subsection{gbintern.spad \cite{1}}
+<<gbintern.spad (SPAD from IN)>>=
+${MID}/gbintern.spad: ${IN}/gbintern.spad.pamphlet
+ @ echo 0 making ${MID}/gbintern.spad from ${IN}/gbintern.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gbintern.spad.pamphlet >gbintern.spad )
+
+@
+<<GBINTERN.o (O from NRLIB)>>=
+${OUT}/GBINTERN.o: ${MID}/GBINTERN.NRLIB
+ @ echo 0 making ${OUT}/GBINTERN.o from ${MID}/GBINTERN.NRLIB
+ @ cp ${MID}/GBINTERN.NRLIB/code.o ${OUT}/GBINTERN.o
+
+@
+<<GBINTERN.NRLIB (NRLIB from MID)>>=
+${MID}/GBINTERN.NRLIB: ${MID}/GBINTERN.spad
+ @ echo 0 making ${MID}/GBINTERN.NRLIB from ${MID}/GBINTERN.spad
+ @ (cd ${MID} ; echo ')co GBINTERN.spad' | ${INTERPSYS} )
+
+@
+<<GBINTERN.spad (SPAD from IN)>>=
+${MID}/GBINTERN.spad: ${IN}/gbintern.spad.pamphlet
+ @ echo 0 making ${MID}/GBINTERN.spad from ${IN}/gbintern.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GBINTERN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GBINTERN GroebnerInternalPackage" ${IN}/gbintern.spad.pamphlet >GBINTERN.spad )
+
+@
+<<gbintern.spad.dvi (DOC from IN)>>=
+${DOC}/gbintern.spad.dvi: ${IN}/gbintern.spad.pamphlet
+ @ echo 0 making ${DOC}/gbintern.spad.dvi from ${IN}/gbintern.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gbintern.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gbintern.spad ; \
+ rm -f ${DOC}/gbintern.spad.pamphlet ; \
+ rm -f ${DOC}/gbintern.spad.tex ; \
+ rm -f ${DOC}/gbintern.spad )
+
+@
+\subsection{gb.spad \cite{1}}
+<<gb.spad (SPAD from IN)>>=
+${MID}/gb.spad: ${IN}/gb.spad.pamphlet
+ @ echo 0 making ${MID}/gb.spad from ${IN}/gb.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gb.spad.pamphlet >gb.spad )
+
+@
+<<GB.o (O from NRLIB)>>=
+${OUT}/GB.o: ${MID}/GB.NRLIB
+ @ echo 0 making ${OUT}/GB.o from ${MID}/GB.NRLIB
+ @ cp ${MID}/GB.NRLIB/code.o ${OUT}/GB.o
+
+@
+<<GB.NRLIB (NRLIB from MID)>>=
+${MID}/GB.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GB.spad
+ @ echo 0 making ${MID}/GB.NRLIB from ${MID}/GB.spad
+ @ (cd ${MID} ; echo ')co GB.spad' | ${INTERPSYS} )
+
+@
+<<GB.spad (SPAD from IN)>>=
+${MID}/GB.spad: ${IN}/gb.spad.pamphlet
+ @ echo 0 making ${MID}/GB.spad from ${IN}/gb.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GB.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GB GroebnerPackage" ${IN}/gb.spad.pamphlet >GB.spad )
+
+@
+<<gb.spad.dvi (DOC from IN)>>=
+${DOC}/gb.spad.dvi: ${IN}/gb.spad.pamphlet
+ @ echo 0 making ${DOC}/gb.spad.dvi from ${IN}/gb.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gb.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gb.spad ; \
+ rm -f ${DOC}/gb.spad.pamphlet ; \
+ rm -f ${DOC}/gb.spad.tex ; \
+ rm -f ${DOC}/gb.spad )
+
+@
+\subsection{gdirprod.spad \cite{1}}
+<<gdirprod.spad (SPAD from IN)>>=
+${MID}/gdirprod.spad: ${IN}/gdirprod.spad.pamphlet
+ @ echo 0 making ${MID}/gdirprod.spad from ${IN}/gdirprod.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gdirprod.spad.pamphlet >gdirprod.spad )
+
+@
+<<HDP.o (O from NRLIB)>>=
+${OUT}/HDP.o: ${MID}/HDP.NRLIB
+ @ echo 0 making ${OUT}/HDP.o from ${MID}/HDP.NRLIB
+ @ cp ${MID}/HDP.NRLIB/code.o ${OUT}/HDP.o
+
+@
+<<HDP.NRLIB (NRLIB from MID)>>=
+${MID}/HDP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/HDP.spad
+ @ echo 0 making ${MID}/HDP.NRLIB from ${MID}/HDP.spad
+ @ (cd ${MID} ; echo ')co HDP.spad' | ${INTERPSYS} )
+
+@
+<<HDP.spad (SPAD from IN)>>=
+${MID}/HDP.spad: ${IN}/gdirprod.spad.pamphlet
+ @ echo 0 making ${MID}/HDP.spad from ${IN}/gdirprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HDP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HDP HomogeneousDirectProduct" ${IN}/gdirprod.spad.pamphlet >HDP.spad )
+
+@
+<<ORDFUNS.o (O from NRLIB)>>=
+${OUT}/ORDFUNS.o: ${MID}/ORDFUNS.NRLIB
+ @ echo 0 making ${OUT}/ORDFUNS.o from ${MID}/ORDFUNS.NRLIB
+ @ cp ${MID}/ORDFUNS.NRLIB/code.o ${OUT}/ORDFUNS.o
+
+@
+<<ORDFUNS.NRLIB (NRLIB from MID)>>=
+${MID}/ORDFUNS.NRLIB: ${MID}/ORDFUNS.spad
+ @ echo 0 making ${MID}/ORDFUNS.NRLIB from ${MID}/ORDFUNS.spad
+ @ (cd ${MID} ; echo ')co ORDFUNS.spad' | ${INTERPSYS} )
+
+@
+<<ORDFUNS.spad (SPAD from IN)>>=
+${MID}/ORDFUNS.spad: ${IN}/gdirprod.spad.pamphlet
+ @ echo 0 making ${MID}/ORDFUNS.spad from ${IN}/gdirprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORDFUNS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ORDFUNS OrderingFunctions" ${IN}/gdirprod.spad.pamphlet >ORDFUNS.spad )
+
+@
+<<ODP.o (O from NRLIB)>>=
+${OUT}/ODP.o: ${MID}/ODP.NRLIB
+ @ echo 0 making ${OUT}/ODP.o from ${MID}/ODP.NRLIB
+ @ cp ${MID}/ODP.NRLIB/code.o ${OUT}/ODP.o
+
+@
+<<ODP.NRLIB (NRLIB from MID)>>=
+${MID}/ODP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ODP.spad
+ @ echo 0 making ${MID}/ODP.NRLIB from ${MID}/ODP.spad
+ @ (cd ${MID} ; echo ')co ODP.spad' | ${INTERPSYS} )
+
+@
+<<ODP.spad (SPAD from IN)>>=
+${MID}/ODP.spad: ${IN}/gdirprod.spad.pamphlet
+ @ echo 0 making ${MID}/ODP.spad from ${IN}/gdirprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ODP OrderedDirectProduct" ${IN}/gdirprod.spad.pamphlet >ODP.spad )
+
+@
+<<SHDP.o (O from NRLIB)>>=
+${OUT}/SHDP.o: ${MID}/SHDP.NRLIB
+ @ echo 0 making ${OUT}/SHDP.o from ${MID}/SHDP.NRLIB
+ @ cp ${MID}/SHDP.NRLIB/code.o ${OUT}/SHDP.o
+
+@
+<<SHDP.NRLIB (NRLIB from MID)>>=
+${MID}/SHDP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SHDP.spad
+ @ echo 0 making ${MID}/SHDP.NRLIB from ${MID}/SHDP.spad
+ @ (cd ${MID} ; echo ')co SHDP.spad' | ${INTERPSYS} )
+
+@
+<<SHDP.spad (SPAD from IN)>>=
+${MID}/SHDP.spad: ${IN}/gdirprod.spad.pamphlet
+ @ echo 0 making ${MID}/SHDP.spad from ${IN}/gdirprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SHDP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SHDP SplitHomogeneousDirectProduct" ${IN}/gdirprod.spad.pamphlet >SHDP.spad )
+
+@
+<<gdirprod.spad.dvi (DOC from IN)>>=
+${DOC}/gdirprod.spad.dvi: ${IN}/gdirprod.spad.pamphlet
+ @ echo 0 making ${DOC}/gdirprod.spad.dvi from ${IN}/gdirprod.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gdirprod.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gdirprod.spad ; \
+ rm -f ${DOC}/gdirprod.spad.pamphlet ; \
+ rm -f ${DOC}/gdirprod.spad.tex ; \
+ rm -f ${DOC}/gdirprod.spad )
+
+@
+\subsection{gdpoly.spad \cite{1}}
+<<gdpoly.spad (SPAD from IN)>>=
+${MID}/gdpoly.spad: ${IN}/gdpoly.spad.pamphlet
+ @ echo 0 making ${MID}/gdpoly.spad from ${IN}/gdpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gdpoly.spad.pamphlet >gdpoly.spad )
+
+@
+<<DMP.o (O from NRLIB)>>=
+${OUT}/DMP.o: ${MID}/DMP.NRLIB
+ @ echo 0 making ${OUT}/DMP.o from ${MID}/DMP.NRLIB
+ @ cp ${MID}/DMP.NRLIB/code.o ${OUT}/DMP.o
+
+@
+<<DMP.NRLIB (NRLIB from MID)>>=
+${MID}/DMP.NRLIB: ${MID}/DMP.spad
+ @ echo 0 making ${MID}/DMP.NRLIB from ${MID}/DMP.spad
+ @ (cd ${MID} ; echo ')co DMP.spad' | ${INTERPSYS} )
+
+@
+<<DMP.spad (SPAD from IN)>>=
+${MID}/DMP.spad: ${IN}/gdpoly.spad.pamphlet
+ @ echo 0 making ${MID}/DMP.spad from ${IN}/gdpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DMP DistributedMultivariatePolynomial" ${IN}/gdpoly.spad.pamphlet >DMP.spad )
+
+@
+<<GDMP.o (O from NRLIB)>>=
+${OUT}/GDMP.o: ${MID}/GDMP.NRLIB
+ @ echo 0 making ${OUT}/GDMP.o from ${MID}/GDMP.NRLIB
+ @ cp ${MID}/GDMP.NRLIB/code.o ${OUT}/GDMP.o
+
+@
+<<GDMP.NRLIB (NRLIB from MID)>>=
+${MID}/GDMP.NRLIB: ${MID}/GDMP.spad
+ @ echo 0 making ${MID}/GDMP.NRLIB from ${MID}/GDMP.spad
+ @ (cd ${MID} ; echo ')co GDMP.spad' | ${INTERPSYS} )
+
+@
+<<GDMP.spad (SPAD from IN)>>=
+${MID}/GDMP.spad: ${IN}/gdpoly.spad.pamphlet
+ @ echo 0 making ${MID}/GDMP.spad from ${IN}/gdpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GDMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GDMP GeneralDistributedMultivariatePolynomial" ${IN}/gdpoly.spad.pamphlet >GDMP.spad )
+
+@
+<<HDMP.o (O from NRLIB)>>=
+${OUT}/HDMP.o: ${MID}/HDMP.NRLIB
+ @ echo 0 making ${OUT}/HDMP.o from ${MID}/HDMP.NRLIB
+ @ cp ${MID}/HDMP.NRLIB/code.o ${OUT}/HDMP.o
+
+@
+<<HDMP.NRLIB (NRLIB from MID)>>=
+${MID}/HDMP.NRLIB: ${MID}/HDMP.spad
+ @ echo 0 making ${MID}/HDMP.NRLIB from ${MID}/HDMP.spad
+ @ (cd ${MID} ; echo ')co HDMP.spad' | ${INTERPSYS} )
+
+@
+<<HDMP.spad (SPAD from IN)>>=
+${MID}/HDMP.spad: ${IN}/gdpoly.spad.pamphlet
+ @ echo 0 making ${MID}/HDMP.spad from ${IN}/gdpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HDMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HDMP HomogeneousDistributedMultivariatePolynomial" ${IN}/gdpoly.spad.pamphlet >HDMP.spad )
+
+@
+<<gdpoly.spad.dvi (DOC from IN)>>=
+${DOC}/gdpoly.spad.dvi: ${IN}/gdpoly.spad.pamphlet
+ @ echo 0 making ${DOC}/gdpoly.spad.dvi from ${IN}/gdpoly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gdpoly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gdpoly.spad ; \
+ rm -f ${DOC}/gdpoly.spad.pamphlet ; \
+ rm -f ${DOC}/gdpoly.spad.tex ; \
+ rm -f ${DOC}/gdpoly.spad )
+
+@
+\subsection{geneez.spad \cite{1}}
+<<geneez.spad (SPAD from IN)>>=
+${MID}/geneez.spad: ${IN}/geneez.spad.pamphlet
+ @ echo 0 making ${MID}/geneez.spad from ${IN}/geneez.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/geneez.spad.pamphlet >geneez.spad )
+
+@
+<<GENEEZ.o (O from NRLIB)>>=
+${OUT}/GENEEZ.o: ${MID}/GENEEZ.NRLIB
+ @ echo 0 making ${OUT}/GENEEZ.o from ${MID}/GENEEZ.NRLIB
+ @ cp ${MID}/GENEEZ.NRLIB/code.o ${OUT}/GENEEZ.o
+
+@
+<<GENEEZ.NRLIB (NRLIB from MID)>>=
+${MID}/GENEEZ.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GENEEZ.spad
+ @ echo 0 making ${MID}/GENEEZ.NRLIB from ${MID}/GENEEZ.spad
+ @ (cd ${MID} ; echo ')co GENEEZ.spad' | ${INTERPSYS} )
+
+@
+<<GENEEZ.spad (SPAD from IN)>>=
+${MID}/GENEEZ.spad: ${IN}/geneez.spad.pamphlet
+ @ echo 0 making ${MID}/GENEEZ.spad from ${IN}/geneez.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GENEEZ.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GENEEZ GenExEuclid" ${IN}/geneez.spad.pamphlet >GENEEZ.spad )
+
+@
+<<geneez.spad.dvi (DOC from IN)>>=
+${DOC}/geneez.spad.dvi: ${IN}/geneez.spad.pamphlet
+ @ echo 0 making ${DOC}/geneez.spad.dvi from ${IN}/geneez.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/geneez.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} geneez.spad ; \
+ rm -f ${DOC}/geneez.spad.pamphlet ; \
+ rm -f ${DOC}/geneez.spad.tex ; \
+ rm -f ${DOC}/geneez.spad )
+
+@
+\subsection{generic.spad \cite{1}}
+<<generic.spad (SPAD from IN)>>=
+${MID}/generic.spad: ${IN}/generic.spad.pamphlet
+ @ echo 0 making ${MID}/generic.spad from ${IN}/generic.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/generic.spad.pamphlet >generic.spad )
+
+@
+<<CVMP.o (O from NRLIB)>>=
+${OUT}/CVMP.o: ${MID}/CVMP.NRLIB
+ @ echo 0 making ${OUT}/CVMP.o from ${MID}/CVMP.NRLIB
+ @ cp ${MID}/CVMP.NRLIB/code.o ${OUT}/CVMP.o
+
+@
+<<CVMP.NRLIB (NRLIB from MID)>>=
+${MID}/CVMP.NRLIB: ${MID}/CVMP.spad
+ @ echo 0 making ${MID}/CVMP.NRLIB from ${MID}/CVMP.spad
+ @ (cd ${MID} ; echo ')co CVMP.spad' | ${INTERPSYS} )
+
+@
+<<CVMP.spad (SPAD from IN)>>=
+${MID}/CVMP.spad: ${IN}/generic.spad.pamphlet
+ @ echo 0 making ${MID}/CVMP.spad from ${IN}/generic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CVMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CVMP CoerceVectorMatrixPackage" ${IN}/generic.spad.pamphlet >CVMP.spad )
+
+@
+<<GCNAALG.o (O from NRLIB)>>=
+${OUT}/GCNAALG.o: ${MID}/GCNAALG.NRLIB
+ @ echo 0 making ${OUT}/GCNAALG.o from ${MID}/GCNAALG.NRLIB
+ @ cp ${MID}/GCNAALG.NRLIB/code.o ${OUT}/GCNAALG.o
+
+@
+<<GCNAALG.NRLIB (NRLIB from MID)>>=
+${MID}/GCNAALG.NRLIB: ${MID}/GCNAALG.spad
+ @ echo 0 making ${MID}/GCNAALG.NRLIB from ${MID}/GCNAALG.spad
+ @ (cd ${MID} ; echo ')co GCNAALG.spad' | ${INTERPSYS} )
+
+@
+<<GCNAALG.spad (SPAD from IN)>>=
+${MID}/GCNAALG.spad: ${IN}/generic.spad.pamphlet
+ @ echo 0 making ${MID}/GCNAALG.spad from ${IN}/generic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GCNAALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GCNAALG GenericNonAssociativeAlgebra" ${IN}/generic.spad.pamphlet >GCNAALG.spad )
+
+@
+<<generic.spad.dvi (DOC from IN)>>=
+${DOC}/generic.spad.dvi: ${IN}/generic.spad.pamphlet
+ @ echo 0 making ${DOC}/generic.spad.dvi from ${IN}/generic.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/generic.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} generic.spad ; \
+ rm -f ${DOC}/generic.spad.pamphlet ; \
+ rm -f ${DOC}/generic.spad.tex ; \
+ rm -f ${DOC}/generic.spad )
+
+@
+\subsection{genufact.spad \cite{1}}
+<<genufact.spad (SPAD from IN)>>=
+${MID}/genufact.spad: ${IN}/genufact.spad.pamphlet
+ @ echo 0 making ${MID}/genufact.spad from ${IN}/genufact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/genufact.spad.pamphlet >genufact.spad )
+
+@
+<<GENUFACT.o (O from NRLIB)>>=
+${OUT}/GENUFACT.o: ${MID}/GENUFACT.NRLIB
+ @ echo 0 making ${OUT}/GENUFACT.o from ${MID}/GENUFACT.NRLIB
+ @ cp ${MID}/GENUFACT.NRLIB/code.o ${OUT}/GENUFACT.o
+
+@
+<<GENUFACT.NRLIB (NRLIB from MID)>>=
+${MID}/GENUFACT.NRLIB: ${MID}/GENUFACT.spad
+ @ echo 0 making ${MID}/GENUFACT.NRLIB from ${MID}/GENUFACT.spad
+ @ (cd ${MID} ; echo ')co GENUFACT.spad' | ${INTERPSYS} )
+
+@
+<<GENUFACT.spad (SPAD from IN)>>=
+${MID}/GENUFACT.spad: ${IN}/genufact.spad.pamphlet
+ @ echo 0 making ${MID}/GENUFACT.spad from ${IN}/genufact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GENUFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GENUFACT GenUFactorize" ${IN}/genufact.spad.pamphlet >GENUFACT.spad )
+
+@
+<<genufact.spad.dvi (DOC from IN)>>=
+${DOC}/genufact.spad.dvi: ${IN}/genufact.spad.pamphlet
+ @ echo 0 making ${DOC}/genufact.spad.dvi from ${IN}/genufact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/genufact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} genufact.spad ; \
+ rm -f ${DOC}/genufact.spad.pamphlet ; \
+ rm -f ${DOC}/genufact.spad.tex ; \
+ rm -f ${DOC}/genufact.spad )
+
+@
+\subsection{genups.spad \cite{1}}
+<<genups.spad (SPAD from IN)>>=
+${MID}/genups.spad: ${IN}/genups.spad.pamphlet
+ @ echo 0 making ${MID}/genups.spad from ${IN}/genups.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/genups.spad.pamphlet >genups.spad )
+
+@
+<<GENUPS.o (O from NRLIB)>>=
+${OUT}/GENUPS.o: ${MID}/GENUPS.NRLIB
+ @ echo 0 making ${OUT}/GENUPS.o from ${MID}/GENUPS.NRLIB
+ @ cp ${MID}/GENUPS.NRLIB/code.o ${OUT}/GENUPS.o
+
+@
+<<GENUPS.NRLIB (NRLIB from MID)>>=
+${MID}/GENUPS.NRLIB: ${MID}/GENUPS.spad
+ @ echo 0 making ${MID}/GENUPS.NRLIB from ${MID}/GENUPS.spad
+ @ (cd ${MID} ; echo ')co GENUPS.spad' | ${INTERPSYS} )
+
+@
+<<GENUPS.spad (SPAD from IN)>>=
+${MID}/GENUPS.spad: ${IN}/genups.spad.pamphlet
+ @ echo 0 making ${MID}/GENUPS.spad from ${IN}/genups.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GENUPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GENUPS GenerateUnivariatePowerSeries" ${IN}/genups.spad.pamphlet >GENUPS.spad )
+
+@
+<<genups.spad.dvi (DOC from IN)>>=
+${DOC}/genups.spad.dvi: ${IN}/genups.spad.pamphlet
+ @ echo 0 making ${DOC}/genups.spad.dvi from ${IN}/genups.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/genups.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} genups.spad ; \
+ rm -f ${DOC}/genups.spad.pamphlet ; \
+ rm -f ${DOC}/genups.spad.tex ; \
+ rm -f ${DOC}/genups.spad )
+
+@
+\subsection{ghensel.spad \cite{1}}
+<<ghensel.spad (SPAD from IN)>>=
+${MID}/ghensel.spad: ${IN}/ghensel.spad.pamphlet
+ @ echo 0 making ${MID}/ghensel.spad from ${IN}/ghensel.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ghensel.spad.pamphlet >ghensel.spad )
+
+@
+<<GHENSEL.o (O from NRLIB)>>=
+${OUT}/GHENSEL.o: ${MID}/GHENSEL.NRLIB
+ @ echo 0 making ${OUT}/GHENSEL.o from ${MID}/GHENSEL.NRLIB
+ @ cp ${MID}/GHENSEL.NRLIB/code.o ${OUT}/GHENSEL.o
+
+@
+<<GHENSEL.NRLIB (NRLIB from MID)>>=
+${MID}/GHENSEL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GHENSEL.spad
+ @ echo 0 making ${MID}/GHENSEL.NRLIB from ${MID}/GHENSEL.spad
+ @ (cd ${MID} ; echo ')co GHENSEL.spad' | ${INTERPSYS} )
+
+@
+<<GHENSEL.spad (SPAD from IN)>>=
+${MID}/GHENSEL.spad: ${IN}/ghensel.spad.pamphlet
+ @ echo 0 making ${MID}/GHENSEL.spad from ${IN}/ghensel.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GHENSEL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GHENSEL GeneralHenselPackage" ${IN}/ghensel.spad.pamphlet >GHENSEL.spad )
+
+@
+<<ghensel.spad.dvi (DOC from IN)>>=
+${DOC}/ghensel.spad.dvi: ${IN}/ghensel.spad.pamphlet
+ @ echo 0 making ${DOC}/ghensel.spad.dvi from ${IN}/ghensel.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ghensel.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ghensel.spad ; \
+ rm -f ${DOC}/ghensel.spad.pamphlet ; \
+ rm -f ${DOC}/ghensel.spad.tex ; \
+ rm -f ${DOC}/ghensel.spad )
+
+@
+\subsection{gpgcd.spad \cite{1}}
+<<gpgcd.spad (SPAD from IN)>>=
+${MID}/gpgcd.spad: ${IN}/gpgcd.spad.pamphlet
+ @ echo 0 making ${MID}/gpgcd.spad from ${IN}/gpgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gpgcd.spad.pamphlet >gpgcd.spad )
+
+@
+<<GENPGCD.o (O from NRLIB)>>=
+${OUT}/GENPGCD.o: ${MID}/GENPGCD.NRLIB
+ @ echo 0 making ${OUT}/GENPGCD.o from ${MID}/GENPGCD.NRLIB
+ @ cp ${MID}/GENPGCD.NRLIB/code.o ${OUT}/GENPGCD.o
+
+@
+<<GENPGCD.NRLIB (NRLIB from MID)>>=
+${MID}/GENPGCD.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GENPGCD.spad
+ @ echo 0 making ${MID}/GENPGCD.NRLIB from ${MID}/GENPGCD.spad
+ @ (cd ${MID} ; echo ')co GENPGCD.spad' | ${INTERPSYS} )
+
+@
+<<GENPGCD.spad (SPAD from IN)>>=
+${MID}/GENPGCD.spad: ${IN}/gpgcd.spad.pamphlet
+ @ echo 0 making ${MID}/GENPGCD.spad from ${IN}/gpgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GENPGCD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GENPGCD GeneralPolynomialGcdPackage" ${IN}/gpgcd.spad.pamphlet >GENPGCD.spad )
+
+@
+<<gpgcd.spad.dvi (DOC from IN)>>=
+${DOC}/gpgcd.spad.dvi: ${IN}/gpgcd.spad.pamphlet
+ @ echo 0 making ${DOC}/gpgcd.spad.dvi from ${IN}/gpgcd.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gpgcd.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gpgcd.spad ; \
+ rm -f ${DOC}/gpgcd.spad.pamphlet ; \
+ rm -f ${DOC}/gpgcd.spad.tex ; \
+ rm -f ${DOC}/gpgcd.spad )
+
+@
+\subsection{gpol.spad \cite{1}}
+<<gpol.spad (SPAD from IN)>>=
+${MID}/gpol.spad: ${IN}/gpol.spad.pamphlet
+ @ echo 0 making ${MID}/gpol.spad from ${IN}/gpol.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gpol.spad.pamphlet >gpol.spad )
+
+@
+<<LAUPOL.o (O from NRLIB)>>=
+${OUT}/LAUPOL.o: ${MID}/LAUPOL.NRLIB
+ @ echo 0 making ${OUT}/LAUPOL.o from ${MID}/LAUPOL.NRLIB
+ @ cp ${MID}/LAUPOL.NRLIB/code.o ${OUT}/LAUPOL.o
+
+@
+<<LAUPOL.NRLIB (NRLIB from MID)>>=
+${MID}/LAUPOL.NRLIB: ${MID}/LAUPOL.spad
+ @ echo 0 making ${MID}/LAUPOL.NRLIB from ${MID}/LAUPOL.spad
+ @ (cd ${MID} ; echo ')co LAUPOL.spad' | ${INTERPSYS} )
+
+@
+<<LAUPOL.spad (SPAD from IN)>>=
+${MID}/LAUPOL.spad: ${IN}/gpol.spad.pamphlet
+ @ echo 0 making ${MID}/LAUPOL.spad from ${IN}/gpol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LAUPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LAUPOL LaurentPolynomial" ${IN}/gpol.spad.pamphlet >LAUPOL.spad )
+
+@
+<<gpol.spad.dvi (DOC from IN)>>=
+${DOC}/gpol.spad.dvi: ${IN}/gpol.spad.pamphlet
+ @ echo 0 making ${DOC}/gpol.spad.dvi from ${IN}/gpol.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gpol.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gpol.spad ; \
+ rm -f ${DOC}/gpol.spad.pamphlet ; \
+ rm -f ${DOC}/gpol.spad.tex ; \
+ rm -f ${DOC}/gpol.spad )
+
+@
+\subsection{grdef.spad \cite{1}}
+<<grdef.spad (SPAD from IN)>>=
+${MID}/grdef.spad: ${IN}/grdef.spad.pamphlet
+ @ echo 0 making ${MID}/grdef.spad from ${IN}/grdef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/grdef.spad.pamphlet >grdef.spad )
+
+@
+<<GRDEF.o (O from NRLIB)>>=
+${OUT}/GRDEF.o: ${MID}/GRDEF.NRLIB
+ @ echo 0 making ${OUT}/GRDEF.o from ${MID}/GRDEF.NRLIB
+ @ cp ${MID}/GRDEF.NRLIB/code.o ${OUT}/GRDEF.o
+
+@
+<<GRDEF.NRLIB (NRLIB from MID)>>=
+${MID}/GRDEF.NRLIB: ${MID}/GRDEF.spad
+ @ echo 0 making ${MID}/GRDEF.NRLIB from ${MID}/GRDEF.spad
+ @ (cd ${MID} ; echo ')co GRDEF.spad' | ${INTERPSYS} )
+
+@
+<<GRDEF.spad (SPAD from IN)>>=
+${MID}/GRDEF.spad: ${IN}/grdef.spad.pamphlet
+ @ echo 0 making ${MID}/GRDEF.spad from ${IN}/grdef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GRDEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GRDEF GraphicsDefaults" ${IN}/grdef.spad.pamphlet >GRDEF.spad )
+
+@
+<<grdef.spad.dvi (DOC from IN)>>=
+${DOC}/grdef.spad.dvi: ${IN}/grdef.spad.pamphlet
+ @ echo 0 making ${DOC}/grdef.spad.dvi from ${IN}/grdef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/grdef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} grdef.spad ; \
+ rm -f ${DOC}/grdef.spad.pamphlet ; \
+ rm -f ${DOC}/grdef.spad.tex ; \
+ rm -f ${DOC}/grdef.spad )
+
+@
+\subsection{groebf.spad \cite{1}}
+<<groebf.spad (SPAD from IN)>>=
+${MID}/groebf.spad: ${IN}/groebf.spad.pamphlet
+ @ echo 0 making ${MID}/groebf.spad from ${IN}/groebf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/groebf.spad.pamphlet >groebf.spad )
+
+@
+<<GBF.o (O from NRLIB)>>=
+${OUT}/GBF.o: ${MID}/GBF.NRLIB
+ @ echo 0 making ${OUT}/GBF.o from ${MID}/GBF.NRLIB
+ @ cp ${MID}/GBF.NRLIB/code.o ${OUT}/GBF.o
+
+@
+<<GBF.NRLIB (NRLIB from MID)>>=
+${MID}/GBF.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GBF.spad
+ @ echo 0 making ${MID}/GBF.NRLIB from ${MID}/GBF.spad
+ @ (cd ${MID} ; echo ')co GBF.spad' | ${INTERPSYS} )
+
+@
+<<GBF.spad (SPAD from IN)>>=
+${MID}/GBF.spad: ${IN}/groebf.spad.pamphlet
+ @ echo 0 making ${MID}/GBF.spad from ${IN}/groebf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GBF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GBF GroebnerFactorizationPackage" ${IN}/groebf.spad.pamphlet >GBF.spad )
+
+@
+<<groebf.spad.dvi (DOC from IN)>>=
+${DOC}/groebf.spad.dvi: ${IN}/groebf.spad.pamphlet
+ @ echo 0 making ${DOC}/groebf.spad.dvi from ${IN}/groebf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/groebf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} groebf.spad ; \
+ rm -f ${DOC}/groebf.spad.pamphlet ; \
+ rm -f ${DOC}/groebf.spad.tex ; \
+ rm -f ${DOC}/groebf.spad )
+
+@
+\subsection{groebsol.spad \cite{1}}
+<<groebsol.spad (SPAD from IN)>>=
+${MID}/groebsol.spad: ${IN}/groebsol.spad.pamphlet
+ @ echo 0 making ${MID}/groebsol.spad from ${IN}/groebsol.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/groebsol.spad.pamphlet >groebsol.spad )
+
+@
+<<GROEBSOL.o (O from NRLIB)>>=
+${OUT}/GROEBSOL.o: ${MID}/GROEBSOL.NRLIB
+ @ echo 0 making ${OUT}/GROEBSOL.o from ${MID}/GROEBSOL.NRLIB
+ @ cp ${MID}/GROEBSOL.NRLIB/code.o ${OUT}/GROEBSOL.o
+
+@
+<<GROEBSOL.NRLIB (NRLIB from MID)>>=
+${MID}/GROEBSOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GROEBSOL.spad
+ @ echo 0 making ${MID}/GROEBSOL.NRLIB from ${MID}/GROEBSOL.spad
+ @ (cd ${MID} ; echo ')co GROEBSOL.spad' | ${INTERPSYS} )
+
+@
+<<GROEBSOL.spad (SPAD from IN)>>=
+${MID}/GROEBSOL.spad: ${IN}/groebsol.spad.pamphlet
+ @ echo 0 making ${MID}/GROEBSOL.spad from ${IN}/groebsol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GROEBSOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GROEBSOL GroebnerSolve" ${IN}/groebsol.spad.pamphlet >GROEBSOL.spad )
+
+@
+<<groebsol.spad.dvi (DOC from IN)>>=
+${DOC}/groebsol.spad.dvi: ${IN}/groebsol.spad.pamphlet
+ @ echo 0 making ${DOC}/groebsol.spad.dvi from ${IN}/groebsol.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/groebsol.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} groebsol.spad ; \
+ rm -f ${DOC}/groebsol.spad.pamphlet ; \
+ rm -f ${DOC}/groebsol.spad.tex ; \
+ rm -f ${DOC}/groebsol.spad )
+
+@
+\subsection{gseries.spad \cite{1}}
+<<gseries.spad (SPAD from IN)>>=
+${MID}/gseries.spad: ${IN}/gseries.spad.pamphlet
+ @ echo 0 making ${MID}/gseries.spad from ${IN}/gseries.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/gseries.spad.pamphlet >gseries.spad )
+
+@
+<<GSERIES.o (O from NRLIB)>>=
+${OUT}/GSERIES.o: ${MID}/GSERIES.NRLIB
+ @ echo 0 making ${OUT}/GSERIES.o from ${MID}/GSERIES.NRLIB
+ @ cp ${MID}/GSERIES.NRLIB/code.o ${OUT}/GSERIES.o
+
+@
+<<GSERIES.NRLIB (NRLIB from MID)>>=
+${MID}/GSERIES.NRLIB: ${MID}/GSERIES.spad
+ @ echo 0 making ${MID}/GSERIES.NRLIB from ${MID}/GSERIES.spad
+ @ (cd ${MID} ; echo ')co GSERIES.spad' | ${INTERPSYS} )
+
+@
+<<GSERIES.spad (SPAD from IN)>>=
+${MID}/GSERIES.spad: ${IN}/gseries.spad.pamphlet
+ @ echo 0 making ${MID}/GSERIES.spad from ${IN}/gseries.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GSERIES.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GSERIES GeneralUnivariatePowerSeries" ${IN}/gseries.spad.pamphlet >GSERIES.spad )
+
+@
+<<gseries.spad.dvi (DOC from IN)>>=
+${DOC}/gseries.spad.dvi: ${IN}/gseries.spad.pamphlet
+ @ echo 0 making ${DOC}/gseries.spad.dvi from ${IN}/gseries.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/gseries.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} gseries.spad ; \
+ rm -f ${DOC}/gseries.spad.pamphlet ; \
+ rm -f ${DOC}/gseries.spad.tex ; \
+ rm -f ${DOC}/gseries.spad )
+
+@
+\subsection{herm.as \cite{1}}
+<<herm.as (SPAD from IN)>>=
+${MID}/herm.as: ${IN}/herm.as.pamphlet
+ @ echo 0 making ${MID}/herm.as from ${IN}/herm.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/herm.as.pamphlet >herm.as )
+
+@
+<<herm.as.dvi (DOC from IN)>>=
+${DOC}/herm.as.dvi: ${IN}/herm.as.pamphlet
+ @ echo 0 making ${DOC}/herm.as.dvi from ${IN}/herm.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/herm.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} herm.as ; \
+ rm -f ${DOC}/herm.as.pamphlet ; \
+ rm -f ${DOC}/herm.as.tex ; \
+ rm -f ${DOC}/herm.as )
+
+@
+\subsection{ideal.spad \cite{1}}
+<<ideal.spad (SPAD from IN)>>=
+${MID}/ideal.spad: ${IN}/ideal.spad.pamphlet
+ @ echo 0 making ${MID}/ideal.spad from ${IN}/ideal.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ideal.spad.pamphlet >ideal.spad )
+
+@
+<<IDEAL.o (O from NRLIB)>>=
+${OUT}/IDEAL.o: ${MID}/IDEAL.NRLIB
+ @ echo 0 making ${OUT}/IDEAL.o from ${MID}/IDEAL.NRLIB
+ @ cp ${MID}/IDEAL.NRLIB/code.o ${OUT}/IDEAL.o
+
+@
+<<IDEAL.NRLIB (NRLIB from MID)>>=
+${MID}/IDEAL.NRLIB: ${MID}/IDEAL.spad
+ @ echo 0 making ${MID}/IDEAL.NRLIB from ${MID}/IDEAL.spad
+ @ (cd ${MID} ; echo ')co IDEAL.spad' | ${INTERPSYS} )
+
+@
+<<IDEAL.spad (SPAD from IN)>>=
+${MID}/IDEAL.spad: ${IN}/ideal.spad.pamphlet
+ @ echo 0 making ${MID}/IDEAL.spad from ${IN}/ideal.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDEAL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IDEAL PolynomialIdeals" ${IN}/ideal.spad.pamphlet >IDEAL.spad )
+
+@
+<<ideal.spad.dvi (DOC from IN)>>=
+${DOC}/ideal.spad.dvi: ${IN}/ideal.spad.pamphlet
+ @ echo 0 making ${DOC}/ideal.spad.dvi from ${IN}/ideal.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ideal.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ideal.spad ; \
+ rm -f ${DOC}/ideal.spad.pamphlet ; \
+ rm -f ${DOC}/ideal.spad.tex ; \
+ rm -f ${DOC}/ideal.spad )
+
+@
+\subsection{idecomp.spad \cite{1}}
+<<idecomp.spad (SPAD from IN)>>=
+${MID}/idecomp.spad: ${IN}/idecomp.spad.pamphlet
+ @ echo 0 making ${MID}/idecomp.spad from ${IN}/idecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/idecomp.spad.pamphlet >idecomp.spad )
+
+@
+<<IDECOMP.o (O from NRLIB)>>=
+${OUT}/IDECOMP.o: ${MID}/IDECOMP.NRLIB
+ @ echo 0 making ${OUT}/IDECOMP.o from ${MID}/IDECOMP.NRLIB
+ @ cp ${MID}/IDECOMP.NRLIB/code.o ${OUT}/IDECOMP.o
+
+@
+<<IDECOMP.NRLIB (NRLIB from MID)>>=
+${MID}/IDECOMP.NRLIB: ${MID}/IDECOMP.spad
+ @ echo 0 making ${MID}/IDECOMP.NRLIB from ${MID}/IDECOMP.spad
+ @ (cd ${MID} ; echo ')co IDECOMP.spad' | ${INTERPSYS} )
+
+@
+<<IDECOMP.spad (SPAD from IN)>>=
+${MID}/IDECOMP.spad: ${IN}/idecomp.spad.pamphlet
+ @ echo 0 making ${MID}/IDECOMP.spad from ${IN}/idecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDECOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IDECOMP IdealDecompositionPackage" ${IN}/idecomp.spad.pamphlet >IDECOMP.spad )
+
+@
+<<idecomp.spad.dvi (DOC from IN)>>=
+${DOC}/idecomp.spad.dvi: ${IN}/idecomp.spad.pamphlet
+ @ echo 0 making ${DOC}/idecomp.spad.dvi from ${IN}/idecomp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/idecomp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} idecomp.spad ; \
+ rm -f ${DOC}/idecomp.spad.pamphlet ; \
+ rm -f ${DOC}/idecomp.spad.tex ; \
+ rm -f ${DOC}/idecomp.spad )
+
+@
+\subsection{indexedp.spad \cite{1}}
+<<indexedp.spad (SPAD from IN)>>=
+${MID}/indexedp.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/indexedp.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/indexedp.spad.pamphlet >indexedp.spad )
+
+@
+<<IDPAG.o (O from NRLIB)>>=
+${OUT}/IDPAG.o: ${MID}/IDPAG.NRLIB
+ @ echo 0 making ${OUT}/IDPAG.o from ${MID}/IDPAG.NRLIB
+ @ cp ${MID}/IDPAG.NRLIB/code.o ${OUT}/IDPAG.o
+
+@
+<<IDPAG.NRLIB (NRLIB from MID)>>=
+${MID}/IDPAG.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IDPAG.spad
+ @ echo 0 making ${MID}/IDPAG.NRLIB from ${MID}/IDPAG.spad
+ @ (cd ${MID} ; echo ')co IDPAG.spad' | ${INTERPSYS} )
+
+@
+<<IDPAG.spad (SPAD from IN)>>=
+${MID}/IDPAG.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/IDPAG.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDPAG.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IDPAG IndexedDirectProductAbelianGroup" ${IN}/indexedp.spad.pamphlet >IDPAG.spad )
+
+@
+<<IDPAM.o (O from NRLIB)>>=
+${OUT}/IDPAM.o: ${MID}/IDPAM.NRLIB
+ @ echo 0 making ${OUT}/IDPAM.o from ${MID}/IDPAM.NRLIB
+ @ cp ${MID}/IDPAM.NRLIB/code.o ${OUT}/IDPAM.o
+
+@
+<<IDPAM.NRLIB (NRLIB from MID)>>=
+${MID}/IDPAM.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IDPAM.spad
+ @ echo 0 making ${MID}/IDPAM.NRLIB from ${MID}/IDPAM.spad
+ @ (cd ${MID} ; echo ')co IDPAM.spad' | ${INTERPSYS} )
+
+@
+<<IDPAM.spad (SPAD from IN)>>=
+${MID}/IDPAM.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/IDPAM.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDPAM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IDPAM IndexedDirectProductAbelianMonoid" ${IN}/indexedp.spad.pamphlet >IDPAM.spad )
+
+@
+<<IDPC.o (O from NRLIB)>>=
+${OUT}/IDPC.o: ${MID}/IDPC.NRLIB
+ @ echo 0 making ${OUT}/IDPC.o from ${MID}/IDPC.NRLIB
+ @ cp ${MID}/IDPC.NRLIB/code.o ${OUT}/IDPC.o
+
+@
+<<IDPC.NRLIB (NRLIB from MID)>>=
+${MID}/IDPC.NRLIB: ${MID}/IDPC.spad
+ @ echo 0 making ${MID}/IDPC.NRLIB from ${MID}/IDPC.spad
+ @ (cd ${MID} ; echo ')co IDPC.spad' | ${INTERPSYS} )
+
+@
+<<IDPC.spad (SPAD from IN)>>=
+${MID}/IDPC.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/IDPC.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDPC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category IDPC IndexedDirectProductCategory" ${IN}/indexedp.spad.pamphlet >IDPC.spad )
+
+@
+<<IDPO.o (O from NRLIB)>>=
+${OUT}/IDPO.o: ${MID}/IDPO.NRLIB
+ @ echo 0 making ${OUT}/IDPO.o from ${MID}/IDPO.NRLIB
+ @ cp ${MID}/IDPO.NRLIB/code.o ${OUT}/IDPO.o
+
+@
+<<IDPO.NRLIB (NRLIB from MID)>>=
+${MID}/IDPO.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IDPO.spad
+ @ echo 0 making ${MID}/IDPO.NRLIB from ${MID}/IDPO.spad
+ @ (cd ${MID} ; echo ')co IDPO.spad' | ${INTERPSYS} )
+
+@
+<<IDPO.spad (SPAD from IN)>>=
+${MID}/IDPO.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/IDPO.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDPO.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IDPO IndexedDirectProductObject" ${IN}/indexedp.spad.pamphlet >IDPO.spad )
+
+@
+<<IDPOAM.o (O from NRLIB)>>=
+${OUT}/IDPOAM.o: ${MID}/IDPOAM.NRLIB
+ @ echo 0 making ${OUT}/IDPOAM.o from ${MID}/IDPOAM.NRLIB
+ @ cp ${MID}/IDPOAM.NRLIB/code.o ${OUT}/IDPOAM.o
+
+@
+<<IDPOAM.NRLIB (NRLIB from MID)>>=
+${MID}/IDPOAM.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IDPOAM.spad
+ @ echo 0 making ${MID}/IDPOAM.NRLIB from ${MID}/IDPOAM.spad
+ @ (cd ${MID} ; echo ')co IDPOAM.spad' | ${INTERPSYS} )
+
+@
+<<IDPOAM.spad (SPAD from IN)>>=
+${MID}/IDPOAM.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/IDPOAM.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDPOAM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IDPOAM IndexedDirectProductOrderedAbelianMonoid" ${IN}/indexedp.spad.pamphlet >IDPOAM.spad )
+
+@
+<<IDPOAMS.o (O from NRLIB)>>=
+${OUT}/IDPOAMS.o: ${MID}/IDPOAMS.NRLIB
+ @ echo 0 making ${OUT}/IDPOAMS.o from ${MID}/IDPOAMS.NRLIB
+ @ cp ${MID}/IDPOAMS.NRLIB/code.o ${OUT}/IDPOAMS.o
+
+@
+<<IDPOAMS.NRLIB (NRLIB from MID)>>=
+${MID}/IDPOAMS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IDPOAMS.spad
+ @ echo 0 making ${MID}/IDPOAMS.NRLIB from ${MID}/IDPOAMS.spad
+ @ (cd ${MID} ; echo ')co IDPOAMS.spad' | ${INTERPSYS} )
+
+@
+<<IDPOAMS.spad (SPAD from IN)>>=
+${MID}/IDPOAMS.spad: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${MID}/IDPOAMS.spad from ${IN}/indexedp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IDPOAMS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IDPOAMS IndexedDirectProductOrderedAbelianMonoidSup" ${IN}/indexedp.spad.pamphlet >IDPOAMS.spad )
+
+@
+<<indexedp.spad.dvi (DOC from IN)>>=
+${DOC}/indexedp.spad.dvi: ${IN}/indexedp.spad.pamphlet
+ @ echo 0 making ${DOC}/indexedp.spad.dvi from ${IN}/indexedp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/indexedp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} indexedp.spad ; \
+ rm -f ${DOC}/indexedp.spad.pamphlet ; \
+ rm -f ${DOC}/indexedp.spad.tex ; \
+ rm -f ${DOC}/indexedp.spad )
+
+@
+\subsection{infprod.spad \cite{1}}
+<<infprod.spad (SPAD from IN)>>=
+${MID}/infprod.spad: ${IN}/infprod.spad.pamphlet
+ @ echo 0 making ${MID}/infprod.spad from ${IN}/infprod.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/infprod.spad.pamphlet >infprod.spad )
+
+@
+<<INFPROD0.o (O from NRLIB)>>=
+${OUT}/INFPROD0.o: ${MID}/INFPROD0.NRLIB
+ @ echo 0 making ${OUT}/INFPROD0.o from ${MID}/INFPROD0.NRLIB
+ @ cp ${MID}/INFPROD0.NRLIB/code.o ${OUT}/INFPROD0.o
+
+@
+<<INFPROD0.NRLIB (NRLIB from MID)>>=
+${MID}/INFPROD0.NRLIB: ${MID}/INFPROD0.spad
+ @ echo 0 making ${MID}/INFPROD0.NRLIB from ${MID}/INFPROD0.spad
+ @ (cd ${MID} ; echo ')co INFPROD0.spad' | ${INTERPSYS} )
+
+@
+<<INFPROD0.spad (SPAD from IN)>>=
+${MID}/INFPROD0.spad: ${IN}/infprod.spad.pamphlet
+ @ echo 0 making ${MID}/INFPROD0.spad from ${IN}/infprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INFPROD0.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INFPROD0 InfiniteProductCharacteristicZero" ${IN}/infprod.spad.pamphlet >INFPROD0.spad )
+
+@
+<<INPRODFF.o (O from NRLIB)>>=
+${OUT}/INPRODFF.o: ${MID}/INPRODFF.NRLIB
+ @ echo 0 making ${OUT}/INPRODFF.o from ${MID}/INPRODFF.NRLIB
+ @ cp ${MID}/INPRODFF.NRLIB/code.o ${OUT}/INPRODFF.o
+
+@
+<<INPRODFF.NRLIB (NRLIB from MID)>>=
+${MID}/INPRODFF.NRLIB: ${MID}/INPRODFF.spad
+ @ echo 0 making ${MID}/INPRODFF.NRLIB from ${MID}/INPRODFF.spad
+ @ (cd ${MID} ; echo ')co INPRODFF.spad' | ${INTERPSYS} )
+
+@
+<<INPRODFF.spad (SPAD from IN)>>=
+${MID}/INPRODFF.spad: ${IN}/infprod.spad.pamphlet
+ @ echo 0 making ${MID}/INPRODFF.spad from ${IN}/infprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INPRODFF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INPRODFF InfiniteProductFiniteField" ${IN}/infprod.spad.pamphlet >INPRODFF.spad )
+
+@
+<<INPRODPF.o (O from NRLIB)>>=
+${OUT}/INPRODPF.o: ${MID}/INPRODPF.NRLIB
+ @ echo 0 making ${OUT}/INPRODPF.o from ${MID}/INPRODPF.NRLIB
+ @ cp ${MID}/INPRODPF.NRLIB/code.o ${OUT}/INPRODPF.o
+
+@
+<<INPRODPF.NRLIB (NRLIB from MID)>>=
+${MID}/INPRODPF.NRLIB: ${MID}/INPRODPF.spad
+ @ echo 0 making ${MID}/INPRODPF.NRLIB from ${MID}/INPRODPF.spad
+ @ (cd ${MID} ; echo ')co INPRODPF.spad' | ${INTERPSYS} )
+
+@
+<<INPRODPF.spad (SPAD from IN)>>=
+${MID}/INPRODPF.spad: ${IN}/infprod.spad.pamphlet
+ @ echo 0 making ${MID}/INPRODPF.spad from ${IN}/infprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INPRODPF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INPRODPF InfiniteProductPrimeField" ${IN}/infprod.spad.pamphlet >INPRODPF.spad )
+
+@
+<<STINPROD.o (O from NRLIB)>>=
+${OUT}/STINPROD.o: ${MID}/STINPROD.NRLIB
+ @ echo 0 making ${OUT}/STINPROD.o from ${MID}/STINPROD.NRLIB
+ @ cp ${MID}/STINPROD.NRLIB/code.o ${OUT}/STINPROD.o
+
+@
+<<STINPROD.NRLIB (NRLIB from MID)>>=
+${MID}/STINPROD.NRLIB: ${MID}/STINPROD.spad
+ @ echo 0 making ${MID}/STINPROD.NRLIB from ${MID}/STINPROD.spad
+ @ (cd ${MID} ; echo ')co STINPROD.spad' | ${INTERPSYS} )
+
+@
+<<STINPROD.spad (SPAD from IN)>>=
+${MID}/STINPROD.spad: ${IN}/infprod.spad.pamphlet
+ @ echo 0 making ${MID}/STINPROD.spad from ${IN}/infprod.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STINPROD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STINPROD StreamInfiniteProduct" ${IN}/infprod.spad.pamphlet >STINPROD.spad )
+
+@
+<<infprod.spad.dvi (DOC from IN)>>=
+${DOC}/infprod.spad.dvi: ${IN}/infprod.spad.pamphlet
+ @ echo 0 making ${DOC}/infprod.spad.dvi from ${IN}/infprod.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/infprod.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} infprod.spad ; \
+ rm -f ${DOC}/infprod.spad.pamphlet ; \
+ rm -f ${DOC}/infprod.spad.tex ; \
+ rm -f ${DOC}/infprod.spad )
+
+@
+\subsection{intaf.spad \cite{1}}
+<<intaf.spad (SPAD from IN)>>=
+${MID}/intaf.spad: ${IN}/intaf.spad.pamphlet
+ @ echo 0 making ${MID}/intaf.spad from ${IN}/intaf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intaf.spad.pamphlet >intaf.spad )
+
+@
+<<INTAF.o (O from NRLIB)>>=
+${OUT}/INTAF.o: ${MID}/INTAF.NRLIB
+ @ echo 0 making ${OUT}/INTAF.o from ${MID}/INTAF.NRLIB
+ @ cp ${MID}/INTAF.NRLIB/code.o ${OUT}/INTAF.o
+
+@
+<<INTAF.NRLIB (NRLIB from MID)>>=
+${MID}/INTAF.NRLIB: ${MID}/INTAF.spad
+ @ echo 0 making ${MID}/INTAF.NRLIB from ${MID}/INTAF.spad
+ @ (cd ${MID} ; echo ')co INTAF.spad' | ${INTERPSYS} )
+
+@
+<<INTAF.spad (SPAD from IN)>>=
+${MID}/INTAF.spad: ${IN}/intaf.spad.pamphlet
+ @ echo 0 making ${MID}/INTAF.spad from ${IN}/intaf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTAF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTAF AlgebraicIntegration" ${IN}/intaf.spad.pamphlet >INTAF.spad )
+
+@
+<<INTG0.o (O from NRLIB)>>=
+${OUT}/INTG0.o: ${MID}/INTG0.NRLIB
+ @ echo 0 making ${OUT}/INTG0.o from ${MID}/INTG0.NRLIB
+ @ cp ${MID}/INTG0.NRLIB/code.o ${OUT}/INTG0.o
+
+@
+<<INTG0.NRLIB (NRLIB from MID)>>=
+${MID}/INTG0.NRLIB: ${MID}/INTG0.spad
+ @ echo 0 making ${MID}/INTG0.NRLIB from ${MID}/INTG0.spad
+ @ (cd ${MID} ; echo ')co INTG0.spad' | ${INTERPSYS} )
+
+@
+<<INTG0.spad (SPAD from IN)>>=
+${MID}/INTG0.spad: ${IN}/intaf.spad.pamphlet
+ @ echo 0 making ${MID}/INTG0.spad from ${IN}/intaf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTG0.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTG0 GenusZeroIntegration" ${IN}/intaf.spad.pamphlet >INTG0.spad )
+
+@
+<<INTPAF.o (O from NRLIB)>>=
+${OUT}/INTPAF.o: ${MID}/INTPAF.NRLIB
+ @ echo 0 making ${OUT}/INTPAF.o from ${MID}/INTPAF.NRLIB
+ @ cp ${MID}/INTPAF.NRLIB/code.o ${OUT}/INTPAF.o
+
+@
+<<INTPAF.NRLIB (NRLIB from MID)>>=
+${MID}/INTPAF.NRLIB: ${MID}/INTPAF.spad
+ @ echo 0 making ${MID}/INTPAF.NRLIB from ${MID}/INTPAF.spad
+ @ (cd ${MID} ; echo ')co INTPAF.spad' | ${INTERPSYS} )
+
+@
+<<INTPAF.spad (SPAD from IN)>>=
+${MID}/INTPAF.spad: ${IN}/intaf.spad.pamphlet
+ @ echo 0 making ${MID}/INTPAF.spad from ${IN}/intaf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTPAF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTPAF PureAlgebraicIntegration" ${IN}/intaf.spad.pamphlet >INTPAF.spad )
+
+@
+<<intaf.spad.dvi (DOC from IN)>>=
+${DOC}/intaf.spad.dvi: ${IN}/intaf.spad.pamphlet
+ @ echo 0 making ${DOC}/intaf.spad.dvi from ${IN}/intaf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intaf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intaf.spad ; \
+ rm -f ${DOC}/intaf.spad.pamphlet ; \
+ rm -f ${DOC}/intaf.spad.tex ; \
+ rm -f ${DOC}/intaf.spad )
+
+@
+\subsection{intalg.spad \cite{1}}
+<<intalg.spad (SPAD from IN)>>=
+${MID}/intalg.spad: ${IN}/intalg.spad.pamphlet
+ @ echo 0 making ${MID}/intalg.spad from ${IN}/intalg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intalg.spad.pamphlet >intalg.spad )
+
+@
+<<DBLRESP.o (O from NRLIB)>>=
+${OUT}/DBLRESP.o: ${MID}/DBLRESP.NRLIB
+ @ echo 0 making ${OUT}/DBLRESP.o from ${MID}/DBLRESP.NRLIB
+ @ cp ${MID}/DBLRESP.NRLIB/code.o ${OUT}/DBLRESP.o
+
+@
+<<DBLRESP.NRLIB (NRLIB from MID)>>=
+${MID}/DBLRESP.NRLIB: ${MID}/DBLRESP.spad
+ @ echo 0 making ${MID}/DBLRESP.NRLIB from ${MID}/DBLRESP.spad
+ @ (cd ${MID} ; echo ')co DBLRESP.spad' | ${INTERPSYS} )
+
+@
+<<DBLRESP.spad (SPAD from IN)>>=
+${MID}/DBLRESP.spad: ${IN}/intalg.spad.pamphlet
+ @ echo 0 making ${MID}/DBLRESP.spad from ${IN}/intalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DBLRESP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DBLRESP DoubleResultantPackage" ${IN}/intalg.spad.pamphlet >DBLRESP.spad )
+
+@
+<<INTALG.o (O from NRLIB)>>=
+${OUT}/INTALG.o: ${MID}/INTALG.NRLIB
+ @ echo 0 making ${OUT}/INTALG.o from ${MID}/INTALG.NRLIB
+ @ cp ${MID}/INTALG.NRLIB/code.o ${OUT}/INTALG.o
+
+@
+<<INTALG.NRLIB (NRLIB from MID)>>=
+${MID}/INTALG.NRLIB: ${MID}/INTALG.spad
+ @ echo 0 making ${MID}/INTALG.NRLIB from ${MID}/INTALG.spad
+ @ (cd ${MID} ; echo ')co INTALG.spad' | ${INTERPSYS} )
+
+@
+<<INTALG.spad (SPAD from IN)>>=
+${MID}/INTALG.spad: ${IN}/intalg.spad.pamphlet
+ @ echo 0 making ${MID}/INTALG.spad from ${IN}/intalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTALG AlgebraicIntegrate" ${IN}/intalg.spad.pamphlet >INTALG.spad )
+
+@
+<<INTHERAL.o (O from NRLIB)>>=
+${OUT}/INTHERAL.o: ${MID}/INTHERAL.NRLIB
+ @ echo 0 making ${OUT}/INTHERAL.o from ${MID}/INTHERAL.NRLIB
+ @ cp ${MID}/INTHERAL.NRLIB/code.o ${OUT}/INTHERAL.o
+
+@
+<<INTHERAL.NRLIB (NRLIB from MID)>>=
+${MID}/INTHERAL.NRLIB: ${MID}/INTHERAL.spad
+ @ echo 0 making ${MID}/INTHERAL.NRLIB from ${MID}/INTHERAL.spad
+ @ (cd ${MID} ; echo ')co INTHERAL.spad' | ${INTERPSYS} )
+
+@
+<<INTHERAL.spad (SPAD from IN)>>=
+${MID}/INTHERAL.spad: ${IN}/intalg.spad.pamphlet
+ @ echo 0 making ${MID}/INTHERAL.spad from ${IN}/intalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTHERAL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTHERAL AlgebraicHermiteIntegration" ${IN}/intalg.spad.pamphlet >INTHERAL.spad )
+
+@
+<<intalg.spad.dvi (DOC from IN)>>=
+${DOC}/intalg.spad.dvi: ${IN}/intalg.spad.pamphlet
+ @ echo 0 making ${DOC}/intalg.spad.dvi from ${IN}/intalg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intalg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intalg.spad ; \
+ rm -f ${DOC}/intalg.spad.pamphlet ; \
+ rm -f ${DOC}/intalg.spad.tex ; \
+ rm -f ${DOC}/intalg.spad )
+
+@
+\subsection{intaux.spad \cite{1}}
+<<intaux.spad (SPAD from IN)>>=
+${MID}/intaux.spad: ${IN}/intaux.spad.pamphlet
+ @ echo 0 making ${MID}/intaux.spad from ${IN}/intaux.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intaux.spad.pamphlet >intaux.spad )
+
+@
+<<IR.o (O from NRLIB)>>=
+${OUT}/IR.o: ${MID}/IR.NRLIB
+ @ echo 0 making ${OUT}/IR.o from ${MID}/IR.NRLIB
+ @ cp ${MID}/IR.NRLIB/code.o ${OUT}/IR.o
+
+@
+<<IR.NRLIB (NRLIB from MID)>>=
+${MID}/IR.NRLIB: ${MID}/IR.spad
+ @ echo 0 making ${MID}/IR.NRLIB from ${MID}/IR.spad
+ @ (cd ${MID} ; echo ')co IR.spad' | ${INTERPSYS} )
+
+@
+<<IR.spad (SPAD from IN)>>=
+${MID}/IR.spad: ${IN}/intaux.spad.pamphlet
+ @ echo 0 making ${MID}/IR.spad from ${IN}/intaux.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IR IntegrationResult" ${IN}/intaux.spad.pamphlet >IR.spad )
+
+@
+<<IR2.o (O from NRLIB)>>=
+${OUT}/IR2.o: ${MID}/IR2.NRLIB
+ @ echo 0 making ${OUT}/IR2.o from ${MID}/IR2.NRLIB
+ @ cp ${MID}/IR2.NRLIB/code.o ${OUT}/IR2.o
+
+@
+<<IR2.NRLIB (NRLIB from MID)>>=
+${MID}/IR2.NRLIB: ${MID}/IR2.spad
+ @ echo 0 making ${MID}/IR2.NRLIB from ${MID}/IR2.spad
+ @ (cd ${MID} ; echo ')co IR2.spad' | ${INTERPSYS} )
+
+@
+<<IR2.spad (SPAD from IN)>>=
+${MID}/IR2.spad: ${IN}/intaux.spad.pamphlet
+ @ echo 0 making ${MID}/IR2.spad from ${IN}/intaux.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IR2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IR2 IntegrationResultFunctions2" ${IN}/intaux.spad.pamphlet >IR2.spad )
+
+@
+<<intaux.spad.dvi (DOC from IN)>>=
+${DOC}/intaux.spad.dvi: ${IN}/intaux.spad.pamphlet
+ @ echo 0 making ${DOC}/intaux.spad.dvi from ${IN}/intaux.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intaux.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intaux.spad ; \
+ rm -f ${DOC}/intaux.spad.pamphlet ; \
+ rm -f ${DOC}/intaux.spad.tex ; \
+ rm -f ${DOC}/intaux.spad )
+
+@
+\subsection{intclos.spad \cite{1}}
+<<intclos.spad (SPAD from IN)>>=
+${MID}/intclos.spad: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${MID}/intclos.spad from ${IN}/intclos.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intclos.spad.pamphlet >intclos.spad )
+
+@
+<<IBATOOL.o (O from NRLIB)>>=
+${OUT}/IBATOOL.o: ${MID}/IBATOOL.NRLIB
+ @ echo 0 making ${OUT}/IBATOOL.o from ${MID}/IBATOOL.NRLIB
+ @ cp ${MID}/IBATOOL.NRLIB/code.o ${OUT}/IBATOOL.o
+
+@
+<<IBATOOL.NRLIB (NRLIB from MID)>>=
+${MID}/IBATOOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IBATOOL.spad
+ @ echo 0 making ${MID}/IBATOOL.NRLIB from ${MID}/IBATOOL.spad
+ @ (cd ${MID} ; echo ')co IBATOOL.spad' | ${INTERPSYS} )
+
+@
+<<IBATOOL.spad (SPAD from IN)>>=
+${MID}/IBATOOL.spad: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${MID}/IBATOOL.spad from ${IN}/intclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IBATOOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IBATOOL IntegralBasisTools" ${IN}/intclos.spad.pamphlet >IBATOOL.spad )
+
+@
+<<FFINTBAS.o (O from NRLIB)>>=
+${OUT}/FFINTBAS.o: ${MID}/FFINTBAS.NRLIB
+ @ echo 0 making ${OUT}/FFINTBAS.o from ${MID}/FFINTBAS.NRLIB
+ @ cp ${MID}/FFINTBAS.NRLIB/code.o ${OUT}/FFINTBAS.o
+
+@
+<<FFINTBAS.NRLIB (NRLIB from MID)>>=
+${MID}/FFINTBAS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FFINTBAS.spad
+ @ echo 0 making ${MID}/FFINTBAS.NRLIB from ${MID}/FFINTBAS.spad
+ @ (cd ${MID} ; echo ')co FFINTBAS.spad' | ${INTERPSYS} )
+
+@
+<<FFINTBAS.spad (SPAD from IN)>>=
+${MID}/FFINTBAS.spad: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${MID}/FFINTBAS.spad from ${IN}/intclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FFINTBAS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FFINTBAS FunctionFieldIntegralBasis" ${IN}/intclos.spad.pamphlet >FFINTBAS.spad )
+
+@
+<<NFINTBAS.o (O from NRLIB)>>=
+${OUT}/NFINTBAS.o: ${MID}/NFINTBAS.NRLIB
+ @ echo 0 making ${OUT}/NFINTBAS.o from ${MID}/NFINTBAS.NRLIB
+ @ cp ${MID}/NFINTBAS.NRLIB/code.o ${OUT}/NFINTBAS.o
+
+@
+<<NFINTBAS.NRLIB (NRLIB from MID)>>=
+${MID}/NFINTBAS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/NFINTBAS.spad
+ @ echo 0 making ${MID}/NFINTBAS.NRLIB from ${MID}/NFINTBAS.spad
+ @ (cd ${MID} ; echo ')co NFINTBAS.spad' | ${INTERPSYS} )
+
+@
+<<NFINTBAS.spad (SPAD from IN)>>=
+${MID}/NFINTBAS.spad: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${MID}/NFINTBAS.spad from ${IN}/intclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NFINTBAS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NFINTBAS NumberFieldIntegralBasis" ${IN}/intclos.spad.pamphlet >NFINTBAS.spad )
+
+@
+<<TRIMAT.o (O from NRLIB)>>=
+${OUT}/TRIMAT.o: ${MID}/TRIMAT.NRLIB
+ @ echo 0 making ${OUT}/TRIMAT.o from ${MID}/TRIMAT.NRLIB
+ @ cp ${MID}/TRIMAT.NRLIB/code.o ${OUT}/TRIMAT.o
+
+@
+<<TRIMAT.NRLIB (NRLIB from MID)>>=
+${MID}/TRIMAT.NRLIB: ${MID}/TRIMAT.spad
+ @ echo 0 making ${MID}/TRIMAT.NRLIB from ${MID}/TRIMAT.spad
+ @ (cd ${MID} ; echo ')co TRIMAT.spad' | ${INTERPSYS} )
+
+@
+<<TRIMAT.spad (SPAD from IN)>>=
+${MID}/TRIMAT.spad: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${MID}/TRIMAT.spad from ${IN}/intclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TRIMAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TRIMAT TriangularMatrixOperations" ${IN}/intclos.spad.pamphlet >TRIMAT.spad )
+
+@
+<<WFFINTBS.o (O from NRLIB)>>=
+${OUT}/WFFINTBS.o: ${MID}/WFFINTBS.NRLIB
+ @ echo 0 making ${OUT}/WFFINTBS.o from ${MID}/WFFINTBS.NRLIB
+ @ cp ${MID}/WFFINTBS.NRLIB/code.o ${OUT}/WFFINTBS.o
+
+@
+<<WFFINTBS.NRLIB (NRLIB from MID)>>=
+${MID}/WFFINTBS.NRLIB: ${MID}/WFFINTBS.spad
+ @ echo 0 making ${MID}/WFFINTBS.NRLIB from ${MID}/WFFINTBS.spad
+ @ (cd ${MID} ; echo ')co WFFINTBS.spad' | ${INTERPSYS} )
+
+@
+<<WFFINTBS.spad (SPAD from IN)>>=
+${MID}/WFFINTBS.spad: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${MID}/WFFINTBS.spad from ${IN}/intclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf WFFINTBS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package WFFINTBS WildFunctionFieldIntegralBasis" ${IN}/intclos.spad.pamphlet >WFFINTBS.spad )
+
+@
+<<intclos.spad.dvi (DOC from IN)>>=
+${DOC}/intclos.spad.dvi: ${IN}/intclos.spad.pamphlet
+ @ echo 0 making ${DOC}/intclos.spad.dvi from ${IN}/intclos.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intclos.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intclos.spad ; \
+ rm -f ${DOC}/intclos.spad.pamphlet ; \
+ rm -f ${DOC}/intclos.spad.tex ; \
+ rm -f ${DOC}/intclos.spad )
+
+@
+\subsection{intef.spad \cite{1}}
+<<intef.spad (SPAD from IN)>>=
+${MID}/intef.spad: ${IN}/intef.spad.pamphlet
+ @ echo 0 making ${MID}/intef.spad from ${IN}/intef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intef.spad.pamphlet >intef.spad )
+
+@
+<<INTEF.o (O from NRLIB)>>=
+${OUT}/INTEF.o: ${MID}/INTEF.NRLIB
+ @ echo 0 making ${OUT}/INTEF.o from ${MID}/INTEF.NRLIB
+ @ cp ${MID}/INTEF.NRLIB/code.o ${OUT}/INTEF.o
+
+@
+<<INTEF.NRLIB (NRLIB from MID)>>=
+${MID}/INTEF.NRLIB: ${MID}/INTEF.spad
+ @ echo 0 making ${MID}/INTEF.NRLIB from ${MID}/INTEF.spad
+ @ (cd ${MID} ; echo ')co INTEF.spad' | ${INTERPSYS} )
+
+@
+<<INTEF.spad (SPAD from IN)>>=
+${MID}/INTEF.spad: ${IN}/intef.spad.pamphlet
+ @ echo 0 making ${MID}/INTEF.spad from ${IN}/intef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTEF ElementaryIntegration" ${IN}/intef.spad.pamphlet >INTEF.spad )
+
+@
+<<intef.spad.dvi (DOC from IN)>>=
+${DOC}/intef.spad.dvi: ${IN}/intef.spad.pamphlet
+ @ echo 0 making ${DOC}/intef.spad.dvi from ${IN}/intef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intef.spad ; \
+ rm -f ${DOC}/intef.spad.pamphlet ; \
+ rm -f ${DOC}/intef.spad.tex ; \
+ rm -f ${DOC}/intef.spad )
+
+@
+\subsection{integer.spad \cite{1}}
+<<integer.spad (SPAD from IN)>>=
+${MID}/integer.spad: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/integer.spad from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/integer.spad.pamphlet >integer.spad )
+
+@
+<<INT.o (O from NRLIB)>>=
+${OUT}/INT.o: ${MID}/INT.NRLIB
+ @ echo 0 making ${OUT}/INT.o from ${MID}/INT.NRLIB
+ @ cp ${MID}/INT.NRLIB/code.o ${OUT}/INT.o
+
+@
+<<INT.NRLIB (NRLIB from MID)>>=
+${MID}/INT.NRLIB: ${MID}/INT.spad
+ @ echo 0 making ${MID}/INT.NRLIB from ${MID}/INT.spad
+ @ (cd ${MID} ; echo ')co INT.spad' | ${INTERPSYS} )
+
+@
+<<INT.spad (SPAD from IN)>>=
+${MID}/INT.spad: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/INT.spad from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain INT Integer" ${IN}/integer.spad.pamphlet >INT.spad )
+
+@
+<<INT.o (BOOTSTRAP from MID)>>=
+${MID}/INT.o: ${MID}/INT.lsp
+ @ echo 0 making ${MID}/INT.o from ${MID}/INT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "INT.lsp" :output-file "INT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/INT.o ${OUT}/INT.o
+
+@
+<<INT.lsp (LISP from IN)>>=
+${MID}/INT.lsp: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/INT.lsp from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INT.NRLIB ; \
+ rm -rf ${OUT}/INT.o ; \
+ ${SPADBIN}/notangle -R"INT.lsp BOOTSTRAP" ${IN}/integer.spad.pamphlet >INT.lsp )
+
+@
+<<INTSLPE.o (O from NRLIB)>>=
+${OUT}/INTSLPE.o: ${MID}/INTSLPE.NRLIB
+ @ echo 0 making ${OUT}/INTSLPE.o from ${MID}/INTSLPE.NRLIB
+ @ cp ${MID}/INTSLPE.NRLIB/code.o ${OUT}/INTSLPE.o
+
+@
+<<INTSLPE.NRLIB (NRLIB from MID)>>=
+${MID}/INTSLPE.NRLIB: ${MID}/INTSLPE.spad
+ @ echo 0 making ${MID}/INTSLPE.NRLIB from ${MID}/INTSLPE.spad
+ @ (cd ${MID} ; echo ')co INTSLPE.spad' | ${INTERPSYS} )
+
+@
+<<INTSLPE.spad (SPAD from IN)>>=
+${MID}/INTSLPE.spad: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/INTSLPE.spad from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTSLPE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTSLPE IntegerSolveLinearPolynomialEquation" ${IN}/integer.spad.pamphlet >INTSLPE.spad )
+
+@
+<<NNI.o (O from NRLIB)>>=
+${OUT}/NNI.o: ${MID}/NNI.NRLIB
+ @ echo 0 making ${OUT}/NNI.o from ${MID}/NNI.NRLIB
+ @ cp ${MID}/NNI.NRLIB/code.o ${OUT}/NNI.o
+
+@
+<<NNI.NRLIB (NRLIB from MID)>>=
+${MID}/NNI.NRLIB: ${OUT}/TYPE.o ${MID}/NNI.spad
+ @ echo 0 making ${MID}/NNI.NRLIB from ${MID}/NNI.spad
+ @ (cd ${MID} ; echo ')co NNI.spad' | ${INTERPSYS} )
+
+@
+<<NNI.spad (SPAD from IN)>>=
+${MID}/NNI.spad: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/NNI.spad from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NNI.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain NNI NonNegativeInteger" ${IN}/integer.spad.pamphlet >NNI.spad )
+
+@
+<<NNI.o (BOOTSTRAP from MID)>>=
+${MID}/NNI.o: ${MID}/NNI.lsp
+ @ echo 0 making ${MID}/NNI.o from ${MID}/NNI.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "NNI.lsp" :output-file "NNI.o"))' | ${DEPSYS} )
+ @ cp ${MID}/NNI.o ${OUT}/NNI.o
+
+@
+<<NNI.lsp (LISP from IN)>>=
+${MID}/NNI.lsp: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/NNI.lsp from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NNI.NRLIB ; \
+ rm -rf ${OUT}/NNI.o ; \
+ ${SPADBIN}/notangle -R"NNI.lsp BOOTSTRAP" ${IN}/integer.spad.pamphlet >NNI.lsp )
+
+@
+<<PI.o (O from NRLIB)>>=
+${OUT}/PI.o: ${MID}/PI.NRLIB
+ @ echo 0 making ${OUT}/PI.o from ${MID}/PI.NRLIB
+ @ cp ${MID}/PI.NRLIB/code.o ${OUT}/PI.o
+
+@
+<<PI.NRLIB (NRLIB from MID)>>=
+${MID}/PI.NRLIB: ${MID}/PI.spad
+ @ echo 0 making ${MID}/PI.NRLIB from ${MID}/PI.spad
+ @ (cd ${MID} ; echo ')co PI.spad' | ${INTERPSYS} )
+
+@
+<<PI.spad (SPAD from IN)>>=
+${MID}/PI.spad: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/PI.spad from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PI.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PI PositiveInteger" ${IN}/integer.spad.pamphlet >PI.spad )
+
+@
+<<PI.o (BOOTSTRAP from MID)>>=
+${MID}/PI.o: ${MID}/PI.lsp
+ @ echo 0 making ${MID}/PI.o from ${MID}/PI.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "PI.lsp" :output-file "PI.o"))' | ${DEPSYS} )
+ @ cp ${MID}/PI.o ${OUT}/PI.o
+
+@
+<<PI.lsp (LISP from IN)>>=
+${MID}/PI.lsp: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/PI.lsp from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PI.NRLIB ; \
+ rm -rf ${OUT}/PI.o ; \
+ ${SPADBIN}/notangle -R"PI.lsp BOOTSTRAP" ${IN}/integer.spad.pamphlet >PI.lsp )
+
+@
+<<ROMAN.o (O from NRLIB)>>=
+${OUT}/ROMAN.o: ${MID}/ROMAN.NRLIB
+ @ echo 0 making ${OUT}/ROMAN.o from ${MID}/ROMAN.NRLIB
+ @ cp ${MID}/ROMAN.NRLIB/code.o ${OUT}/ROMAN.o
+
+@
+<<ROMAN.NRLIB (NRLIB from MID)>>=
+${MID}/ROMAN.NRLIB: ${MID}/ROMAN.spad
+ @ echo 0 making ${MID}/ROMAN.NRLIB from ${MID}/ROMAN.spad
+ @ (cd ${MID} ; echo ')co ROMAN.spad' | ${INTERPSYS} )
+
+@
+<<ROMAN.spad (SPAD from IN)>>=
+${MID}/ROMAN.spad: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${MID}/ROMAN.spad from ${IN}/integer.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ROMAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ROMAN RomanNumeral" ${IN}/integer.spad.pamphlet >ROMAN.spad )
+
+@
+<<integer.spad.dvi (DOC from IN)>>=
+${DOC}/integer.spad.dvi: ${IN}/integer.spad.pamphlet
+ @ echo 0 making ${DOC}/integer.spad.dvi from ${IN}/integer.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/integer.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} integer.spad ; \
+ rm -f ${DOC}/integer.spad.pamphlet ; \
+ rm -f ${DOC}/integer.spad.tex ; \
+ rm -f ${DOC}/integer.spad )
+
+@
+\subsection{integrat.spad \cite{1}}
+<<integrat.spad (SPAD from IN)>>=
+${MID}/integrat.spad: ${IN}/integrat.spad.pamphlet
+ @ echo 0 making ${MID}/integrat.spad from ${IN}/integrat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/integrat.spad.pamphlet >integrat.spad )
+
+@
+<<FSCINT.o (O from NRLIB)>>=
+${OUT}/FSCINT.o: ${MID}/FSCINT.NRLIB
+ @ echo 0 making ${OUT}/FSCINT.o from ${MID}/FSCINT.NRLIB
+ @ cp ${MID}/FSCINT.NRLIB/code.o ${OUT}/FSCINT.o
+
+@
+<<FSCINT.NRLIB (NRLIB from MID)>>=
+${MID}/FSCINT.NRLIB: ${MID}/FSCINT.spad
+ @ echo 0 making ${MID}/FSCINT.NRLIB from ${MID}/FSCINT.spad
+ @ (cd ${MID} ; echo ')co FSCINT.spad' | ${INTERPSYS} )
+
+@
+<<FSCINT.spad (SPAD from IN)>>=
+${MID}/FSCINT.spad: ${IN}/integrat.spad.pamphlet
+ @ echo 0 making ${MID}/FSCINT.spad from ${IN}/integrat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSCINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSCINT FunctionSpaceComplexIntegration" ${IN}/integrat.spad.pamphlet >FSCINT.spad )
+
+@
+<<FSINT.o (O from NRLIB)>>=
+${OUT}/FSINT.o: ${MID}/FSINT.NRLIB
+ @ echo 0 making ${OUT}/FSINT.o from ${MID}/FSINT.NRLIB
+ @ cp ${MID}/FSINT.NRLIB/code.o ${OUT}/FSINT.o
+
+@
+<<FSINT.NRLIB (NRLIB from MID)>>=
+${MID}/FSINT.NRLIB: ${MID}/FSINT.spad
+ @ echo 0 making ${MID}/FSINT.NRLIB from ${MID}/FSINT.spad
+ @ (cd ${MID} ; echo ')co FSINT.spad' | ${INTERPSYS} )
+
+@
+<<FSINT.spad (SPAD from IN)>>=
+${MID}/FSINT.spad: ${IN}/integrat.spad.pamphlet
+ @ echo 0 making ${MID}/FSINT.spad from ${IN}/integrat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSINT FunctionSpaceIntegration" ${IN}/integrat.spad.pamphlet >FSINT.spad )
+
+@
+<<integrat.spad.dvi (DOC from IN)>>=
+${DOC}/integrat.spad.dvi: ${IN}/integrat.spad.pamphlet
+ @ echo 0 making ${DOC}/integrat.spad.dvi from ${IN}/integrat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/integrat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} integrat.spad ; \
+ rm -f ${DOC}/integrat.spad.pamphlet ; \
+ rm -f ${DOC}/integrat.spad.tex ; \
+ rm -f ${DOC}/integrat.spad )
+
+@
+\subsection{INTERP.EXPOSED \cite{1}}
+<<INTERP.EXPOSED (SPAD from IN)>>=
+${MID}/INTERP.EXPOSED: ${IN}/INTERP.EXPOSED.pamphlet
+ @ echo 0 making ${MID}/INTERP.EXPOSED from ${IN}/INTERP.EXPOSED.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/INTERP.EXPOSED.pamphlet >INTERP.EXPOSED )
+
+@
+<<INTERP.EXPOSED.dvi (DOC from IN)>>=
+${DOC}/INTERP.EXPOSED.dvi: ${IN}/INTERP.EXPOSED.pamphlet
+ @ echo 0 making ${DOC}/INTERP.EXPOSED.dvi from ${IN}/INTERP.EXPOSED.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/INTERP.EXPOSED.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} INTERP.EXPOSED ; \
+ rm -f ${DOC}/INTERP.EXPOSED.pamphlet ; \
+ rm -f ${DOC}/INTERP.EXPOSED.tex ; \
+ rm -f ${DOC}/INTERP.EXPOSED )
+
+@
+\subsection{interval.as \cite{1}}
+<<interval.as (SPAD from IN)>>=
+${MID}/interval.as: ${IN}/interval.as.pamphlet
+ @ echo 0 making ${MID}/interval.as from ${IN}/interval.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/interval.as.pamphlet >interval.as )
+
+@
+<<interval.as.dvi (DOC from IN)>>=
+${DOC}/interval.as.dvi: ${IN}/interval.as.pamphlet
+ @ echo 0 making ${DOC}/interval.as.dvi from ${IN}/interval.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/interval.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} interval.as ; \
+ rm -f ${DOC}/interval.as.pamphlet ; \
+ rm -f ${DOC}/interval.as.tex ; \
+ rm -f ${DOC}/interval.as )
+
+@
+\subsection{interval.spad \cite{1}}
+<<interval.spad (SPAD from IN)>>=
+${MID}/interval.spad: ${IN}/interval.spad.pamphlet
+ @ echo 0 making ${MID}/interval.spad from ${IN}/interval.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/interval.spad.pamphlet >interval.spad )
+
+@
+<<INTCAT.o (O from NRLIB)>>=
+${OUT}/INTCAT.o: ${MID}/INTCAT.NRLIB
+ @ echo 0 making ${OUT}/INTCAT.o from ${MID}/INTCAT.NRLIB
+ @ cp ${MID}/INTCAT.NRLIB/code.o ${OUT}/INTCAT.o
+
+@
+<<INTCAT.NRLIB (NRLIB from MID)>>=
+${MID}/INTCAT.NRLIB: ${MID}/INTCAT.spad
+ @ echo 0 making ${MID}/INTCAT.NRLIB from ${MID}/INTCAT.spad
+ @ (cd ${MID} ; echo ')co INTCAT.spad' | ${INTERPSYS} )
+
+@
+<<INTCAT.spad (SPAD from IN)>>=
+${MID}/INTCAT.spad: ${IN}/interval.spad.pamphlet
+ @ echo 0 making ${MID}/INTCAT.spad from ${IN}/interval.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category INTCAT IntervalCategory" ${IN}/interval.spad.pamphlet >INTCAT.spad )
+
+@
+<<INTRVL.o (O from NRLIB)>>=
+${OUT}/INTRVL.o: ${MID}/INTRVL.NRLIB
+ @ echo 0 making ${OUT}/INTRVL.o from ${MID}/INTRVL.NRLIB
+ @ cp ${MID}/INTRVL.NRLIB/code.o ${OUT}/INTRVL.o
+
+@
+<<INTRVL.NRLIB (NRLIB from MID)>>=
+${MID}/INTRVL.NRLIB: ${MID}/INTRVL.spad
+ @ echo 0 making ${MID}/INTRVL.NRLIB from ${MID}/INTRVL.spad
+ @ (cd ${MID} ; echo ')co INTRVL.spad' | ${INTERPSYS} )
+
+@
+<<INTRVL.spad (SPAD from IN)>>=
+${MID}/INTRVL.spad: ${IN}/interval.spad.pamphlet
+ @ echo 0 making ${MID}/INTRVL.spad from ${IN}/interval.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTRVL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain INTRVL Interval" ${IN}/interval.spad.pamphlet >INTRVL.spad )
+
+@
+<<interval.spad.dvi (DOC from IN)>>=
+${DOC}/interval.spad.dvi: ${IN}/interval.spad.pamphlet
+ @ echo 0 making ${DOC}/interval.spad.dvi from ${IN}/interval.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/interval.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} interval.spad ; \
+ rm -f ${DOC}/interval.spad.pamphlet ; \
+ rm -f ${DOC}/interval.spad.tex ; \
+ rm -f ${DOC}/interval.spad )
+
+@
+\subsection{intfact.spad \cite{1}}
+<<intfact.spad (SPAD from IN)>>=
+${MID}/intfact.spad: ${IN}/intfact.spad.pamphlet
+ @ echo 0 making ${MID}/intfact.spad from ${IN}/intfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intfact.spad.pamphlet >intfact.spad )
+
+@
+<<INTFACT.o (O from NRLIB)>>=
+${OUT}/INTFACT.o: ${MID}/INTFACT.NRLIB
+ @ echo 0 making ${OUT}/INTFACT.o from ${MID}/INTFACT.NRLIB
+ @ cp ${MID}/INTFACT.NRLIB/code.o ${OUT}/INTFACT.o
+
+@
+<<INTFACT.NRLIB (NRLIB from MID)>>=
+${MID}/INTFACT.NRLIB: ${MID}/INTFACT.spad
+ @ echo 0 making ${MID}/INTFACT.NRLIB from ${MID}/INTFACT.spad
+ @ (cd ${MID} ; echo ')co INTFACT.spad' | ${INTERPSYS} )
+
+@
+<<INTFACT.spad (SPAD from IN)>>=
+${MID}/INTFACT.spad: ${IN}/intfact.spad.pamphlet
+ @ echo 0 making ${MID}/INTFACT.spad from ${IN}/intfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTFACT IntegerFactorizationPackage" ${IN}/intfact.spad.pamphlet >INTFACT.spad )
+
+@
+<<IROOT.o (O from NRLIB)>>=
+${OUT}/IROOT.o: ${MID}/IROOT.NRLIB
+ @ echo 0 making ${OUT}/IROOT.o from ${MID}/IROOT.NRLIB
+ @ cp ${MID}/IROOT.NRLIB/code.o ${OUT}/IROOT.o
+
+@
+<<IROOT.NRLIB (NRLIB from MID)>>=
+${MID}/IROOT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IROOT.spad
+ @ echo 0 making ${MID}/IROOT.NRLIB from ${MID}/IROOT.spad
+ @ (cd ${MID} ; echo ')co IROOT.spad' | ${INTERPSYS} )
+
+@
+<<IROOT.spad (SPAD from IN)>>=
+${MID}/IROOT.spad: ${IN}/intfact.spad.pamphlet
+ @ echo 0 making ${MID}/IROOT.spad from ${IN}/intfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IROOT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IROOT IntegerRoots" ${IN}/intfact.spad.pamphlet >IROOT.spad )
+
+@
+<<PRIMES.o (O from NRLIB)>>=
+${OUT}/PRIMES.o: ${MID}/PRIMES.NRLIB
+ @ echo 0 making ${OUT}/PRIMES.o from ${MID}/PRIMES.NRLIB
+ @ cp ${MID}/PRIMES.NRLIB/code.o ${OUT}/PRIMES.o
+
+@
+<<PRIMES.NRLIB (NRLIB from MID)>>=
+${MID}/PRIMES.NRLIB: ${MID}/PRIMES.spad
+ @ echo 0 making ${MID}/PRIMES.NRLIB from ${MID}/PRIMES.spad
+ @ (cd ${MID} ; echo ')co PRIMES.spad' | ${INTERPSYS} )
+
+@
+<<PRIMES.spad (SPAD from IN)>>=
+${MID}/PRIMES.spad: ${IN}/intfact.spad.pamphlet
+ @ echo 0 making ${MID}/PRIMES.spad from ${IN}/intfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRIMES.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PRIMES IntegerPrimesPackage" ${IN}/intfact.spad.pamphlet >PRIMES.spad )
+
+@
+<<intfact.spad.dvi (DOC from IN)>>=
+${DOC}/intfact.spad.dvi: ${IN}/intfact.spad.pamphlet
+ @ echo 0 making ${DOC}/intfact.spad.dvi from ${IN}/intfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intfact.spad ; \
+ rm -f ${DOC}/intfact.spad.pamphlet ; \
+ rm -f ${DOC}/intfact.spad.tex ; \
+ rm -f ${DOC}/intfact.spad )
+
+@
+\subsection{intpm.spad \cite{1}}
+<<intpm.spad (SPAD from IN)>>=
+${MID}/intpm.spad: ${IN}/intpm.spad.pamphlet
+ @ echo 0 making ${MID}/intpm.spad from ${IN}/intpm.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intpm.spad.pamphlet >intpm.spad )
+
+@
+<<INTPM.o (O from NRLIB)>>=
+${OUT}/INTPM.o: ${MID}/INTPM.NRLIB
+ @ echo 0 making ${OUT}/INTPM.o from ${MID}/INTPM.NRLIB
+ @ cp ${MID}/INTPM.NRLIB/code.o ${OUT}/INTPM.o
+
+@
+<<INTPM.NRLIB (NRLIB from MID)>>=
+${MID}/INTPM.NRLIB: ${MID}/INTPM.spad
+ @ echo 0 making ${MID}/INTPM.NRLIB from ${MID}/INTPM.spad
+ @ (cd ${MID} ; echo ')co INTPM.spad' | ${INTERPSYS} )
+
+@
+<<INTPM.spad (SPAD from IN)>>=
+${MID}/INTPM.spad: ${IN}/intpm.spad.pamphlet
+ @ echo 0 making ${MID}/INTPM.spad from ${IN}/intpm.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTPM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTPM PatternMatchIntegration" ${IN}/intpm.spad.pamphlet >INTPM.spad )
+
+@
+<<intpm.spad.dvi (DOC from IN)>>=
+${DOC}/intpm.spad.dvi: ${IN}/intpm.spad.pamphlet
+ @ echo 0 making ${DOC}/intpm.spad.dvi from ${IN}/intpm.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intpm.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intpm.spad ; \
+ rm -f ${DOC}/intpm.spad.pamphlet ; \
+ rm -f ${DOC}/intpm.spad.tex ; \
+ rm -f ${DOC}/intpm.spad )
+
+@
+\subsection{intrf.spad \cite{1}}
+<<intrf.spad (SPAD from IN)>>=
+${MID}/intrf.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/intrf.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/intrf.spad.pamphlet >intrf.spad )
+
+@
+<<INTHERTR.o (O from NRLIB)>>=
+${OUT}/INTHERTR.o: ${MID}/INTHERTR.NRLIB
+ @ echo 0 making ${OUT}/INTHERTR.o from ${MID}/INTHERTR.NRLIB
+ @ cp ${MID}/INTHERTR.NRLIB/code.o ${OUT}/INTHERTR.o
+
+@
+<<INTHERTR.NRLIB (NRLIB from MID)>>=
+${MID}/INTHERTR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/INTHERTR.spad
+ @ echo 0 making ${MID}/INTHERTR.NRLIB from ${MID}/INTHERTR.spad
+ @ (cd ${MID} ; echo ')co INTHERTR.spad' | ${INTERPSYS} )
+
+@
+<<INTHERTR.spad (SPAD from IN)>>=
+${MID}/INTHERTR.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/INTHERTR.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTHERTR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTHERTR TranscendentalHermiteIntegration" ${IN}/intrf.spad.pamphlet >INTHERTR.spad )
+
+@
+<<INTRAT.o (O from NRLIB)>>=
+${OUT}/INTRAT.o: ${MID}/INTRAT.NRLIB
+ @ echo 0 making ${OUT}/INTRAT.o from ${MID}/INTRAT.NRLIB
+ @ cp ${MID}/INTRAT.NRLIB/code.o ${OUT}/INTRAT.o
+
+@
+<<INTRAT.NRLIB (NRLIB from MID)>>=
+${MID}/INTRAT.NRLIB: ${MID}/INTRAT.spad
+ @ echo 0 making ${MID}/INTRAT.NRLIB from ${MID}/INTRAT.spad
+ @ (cd ${MID} ; echo ')co INTRAT.spad' | ${INTERPSYS} )
+
+@
+<<INTRAT.spad (SPAD from IN)>>=
+${MID}/INTRAT.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/INTRAT.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTRAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTRAT RationalIntegration" ${IN}/intrf.spad.pamphlet >INTRAT.spad )
+
+@
+<<INTRF.o (O from NRLIB)>>=
+${OUT}/INTRF.o: ${MID}/INTRF.NRLIB
+ @ echo 0 making ${OUT}/INTRF.o from ${MID}/INTRF.NRLIB
+ @ cp ${MID}/INTRF.NRLIB/code.o ${OUT}/INTRF.o
+
+@
+<<INTRF.NRLIB (NRLIB from MID)>>=
+${MID}/INTRF.NRLIB: ${MID}/INTRF.spad
+ @ echo 0 making ${MID}/INTRF.NRLIB from ${MID}/INTRF.spad
+ @ (cd ${MID} ; echo ')co INTRF.spad' | ${INTERPSYS} )
+
+@
+<<INTRF.spad (SPAD from IN)>>=
+${MID}/INTRF.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/INTRF.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTRF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTRF RationalFunctionIntegration" ${IN}/intrf.spad.pamphlet >INTRF.spad )
+
+@
+<<INTTR.o (O from NRLIB)>>=
+${OUT}/INTTR.o: ${MID}/INTTR.NRLIB
+ @ echo 0 making ${OUT}/INTTR.o from ${MID}/INTTR.NRLIB
+ @ cp ${MID}/INTTR.NRLIB/code.o ${OUT}/INTTR.o
+
+@
+<<INTTR.NRLIB (NRLIB from MID)>>=
+${MID}/INTTR.NRLIB: ${MID}/INTTR.spad
+ @ echo 0 making ${MID}/INTTR.NRLIB from ${MID}/INTTR.spad
+ @ (cd ${MID} ; echo ')co INTTR.spad' | ${INTERPSYS} )
+
+@
+<<INTTR.spad (SPAD from IN)>>=
+${MID}/INTTR.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/INTTR.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTTR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTTR TranscendentalIntegration" ${IN}/intrf.spad.pamphlet >INTTR.spad )
+
+@
+<<MONOTOOL.o (O from NRLIB)>>=
+${OUT}/MONOTOOL.o: ${MID}/MONOTOOL.NRLIB
+ @ echo 0 making ${OUT}/MONOTOOL.o from ${MID}/MONOTOOL.NRLIB
+ @ cp ${MID}/MONOTOOL.NRLIB/code.o ${OUT}/MONOTOOL.o
+
+@
+<<MONOTOOL.NRLIB (NRLIB from MID)>>=
+${MID}/MONOTOOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MONOTOOL.spad
+ @ echo 0 making ${MID}/MONOTOOL.NRLIB from ${MID}/MONOTOOL.spad
+ @ (cd ${MID} ; echo ')co MONOTOOL.spad' | ${INTERPSYS} )
+
+@
+<<MONOTOOL.spad (SPAD from IN)>>=
+${MID}/MONOTOOL.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/MONOTOOL.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONOTOOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MONOTOOL MonomialExtensionTools" ${IN}/intrf.spad.pamphlet >MONOTOOL.spad )
+
+@
+<<SUBRESP.o (O from NRLIB)>>=
+${OUT}/SUBRESP.o: ${MID}/SUBRESP.NRLIB
+ @ echo 0 making ${OUT}/SUBRESP.o from ${MID}/SUBRESP.NRLIB
+ @ cp ${MID}/SUBRESP.NRLIB/code.o ${OUT}/SUBRESP.o
+
+@
+<<SUBRESP.NRLIB (NRLIB from MID)>>=
+${MID}/SUBRESP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SUBRESP.spad
+ @ echo 0 making ${MID}/SUBRESP.NRLIB from ${MID}/SUBRESP.spad
+ @ (cd ${MID} ; echo ')co SUBRESP.spad' | ${INTERPSYS} )
+
+@
+<<SUBRESP.spad (SPAD from IN)>>=
+${MID}/SUBRESP.spad: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${MID}/SUBRESP.spad from ${IN}/intrf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUBRESP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SUBRESP SubResultantPackage" ${IN}/intrf.spad.pamphlet >SUBRESP.spad )
+
+@
+<<intrf.spad.dvi (DOC from IN)>>=
+${DOC}/intrf.spad.dvi: ${IN}/intrf.spad.pamphlet
+ @ echo 0 making ${DOC}/intrf.spad.dvi from ${IN}/intrf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/intrf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} intrf.spad ; \
+ rm -f ${DOC}/intrf.spad.pamphlet ; \
+ rm -f ${DOC}/intrf.spad.tex ; \
+ rm -f ${DOC}/intrf.spad )
+
+@
+\subsection{invnode.as \cite{1}}
+<<invnode.as (SPAD from IN)>>=
+${MID}/invnode.as: ${IN}/invnode.as.pamphlet
+ @ echo 0 making ${MID}/invnode.as from ${IN}/invnode.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/invnode.as.pamphlet >invnode.as )
+
+@
+<<invnode.as.dvi (DOC from IN)>>=
+${DOC}/invnode.as.dvi: ${IN}/invnode.as.pamphlet
+ @ echo 0 making ${DOC}/invnode.as.dvi from ${IN}/invnode.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/invnode.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} invnode.as ; \
+ rm -f ${DOC}/invnode.as.pamphlet ; \
+ rm -f ${DOC}/invnode.as.tex ; \
+ rm -f ${DOC}/invnode.as )
+
+@
+\subsection{invrender.as \cite{1}}
+<<invrender.as (SPAD from IN)>>=
+${MID}/invrender.as: ${IN}/invrender.as.pamphlet
+ @ echo 0 making ${MID}/invrender.as from ${IN}/invrender.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/invrender.as.pamphlet >invrender.as )
+
+@
+<<invrender.as.dvi (DOC from IN)>>=
+${DOC}/invrender.as.dvi: ${IN}/invrender.as.pamphlet
+ @ echo 0 making ${DOC}/invrender.as.dvi from ${IN}/invrender.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/invrender.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} invrender.as ; \
+ rm -f ${DOC}/invrender.as.pamphlet ; \
+ rm -f ${DOC}/invrender.as.tex ; \
+ rm -f ${DOC}/invrender.as )
+
+@
+\subsection{invtypes.as \cite{1}}
+<<invtypes.as (SPAD from IN)>>=
+${MID}/invtypes.as: ${IN}/invtypes.as.pamphlet
+ @ echo 0 making ${MID}/invtypes.as from ${IN}/invtypes.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/invtypes.as.pamphlet >invtypes.as )
+
+@
+<<invtypes.as.dvi (DOC from IN)>>=
+${DOC}/invtypes.as.dvi: ${IN}/invtypes.as.pamphlet
+ @ echo 0 making ${DOC}/invtypes.as.dvi from ${IN}/invtypes.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/invtypes.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} invtypes.as ; \
+ rm -f ${DOC}/invtypes.as.pamphlet ; \
+ rm -f ${DOC}/invtypes.as.tex ; \
+ rm -f ${DOC}/invtypes.as )
+
+@
+\subsection{invutils.as \cite{1}}
+<<invutils.as (SPAD from IN)>>=
+${MID}/invutils.as: ${IN}/invutils.as.pamphlet
+ @ echo 0 making ${MID}/invutils.as from ${IN}/invutils.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/invutils.as.pamphlet >invutils.as )
+
+@
+<<invutils.as.dvi (DOC from IN)>>=
+${DOC}/invutils.as.dvi: ${IN}/invutils.as.pamphlet
+ @ echo 0 making ${DOC}/invutils.as.dvi from ${IN}/invutils.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/invutils.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} invutils.as ; \
+ rm -f ${DOC}/invutils.as.pamphlet ; \
+ rm -f ${DOC}/invutils.as.tex ; \
+ rm -f ${DOC}/invutils.as )
+
+@
+\subsection{irexpand.spad \cite{1}}
+<<irexpand.spad (SPAD from IN)>>=
+${MID}/irexpand.spad: ${IN}/irexpand.spad.pamphlet
+ @ echo 0 making ${MID}/irexpand.spad from ${IN}/irexpand.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/irexpand.spad.pamphlet >irexpand.spad )
+
+@
+<<IR2F.o (O from NRLIB)>>=
+${OUT}/IR2F.o: ${MID}/IR2F.NRLIB
+ @ echo 0 making ${OUT}/IR2F.o from ${MID}/IR2F.NRLIB
+ @ cp ${MID}/IR2F.NRLIB/code.o ${OUT}/IR2F.o
+
+@
+<<IR2F.NRLIB (NRLIB from MID)>>=
+${MID}/IR2F.NRLIB: ${MID}/IR2F.spad
+ @ echo 0 making ${MID}/IR2F.NRLIB from ${MID}/IR2F.spad
+ @ (cd ${MID} ; echo ')co IR2F.spad' | ${INTERPSYS} )
+
+@
+<<IR2F.spad (SPAD from IN)>>=
+${MID}/IR2F.spad: ${IN}/irexpand.spad.pamphlet
+ @ echo 0 making ${MID}/IR2F.spad from ${IN}/irexpand.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IR2F.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IR2F IntegrationResultToFunction" ${IN}/irexpand.spad.pamphlet >IR2F.spad )
+
+@
+<<IRRF2F.o (O from NRLIB)>>=
+${OUT}/IRRF2F.o: ${MID}/IRRF2F.NRLIB
+ @ echo 0 making ${OUT}/IRRF2F.o from ${MID}/IRRF2F.NRLIB
+ @ cp ${MID}/IRRF2F.NRLIB/code.o ${OUT}/IRRF2F.o
+
+@
+<<IRRF2F.NRLIB (NRLIB from MID)>>=
+${MID}/IRRF2F.NRLIB: ${MID}/IRRF2F.spad
+ @ echo 0 making ${MID}/IRRF2F.NRLIB from ${MID}/IRRF2F.spad
+ @ (cd ${MID} ; echo ')co IRRF2F.spad' | ${INTERPSYS} )
+
+@
+<<IRRF2F.spad (SPAD from IN)>>=
+${MID}/IRRF2F.spad: ${IN}/irexpand.spad.pamphlet
+ @ echo 0 making ${MID}/IRRF2F.spad from ${IN}/irexpand.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IRRF2F.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IRRF2F IntegrationResultRFToFunction" ${IN}/irexpand.spad.pamphlet >IRRF2F.spad )
+
+@
+<<irexpand.spad.dvi (DOC from IN)>>=
+${DOC}/irexpand.spad.dvi: ${IN}/irexpand.spad.pamphlet
+ @ echo 0 making ${DOC}/irexpand.spad.dvi from ${IN}/irexpand.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/irexpand.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} irexpand.spad ; \
+ rm -f ${DOC}/irexpand.spad.pamphlet ; \
+ rm -f ${DOC}/irexpand.spad.tex ; \
+ rm -f ${DOC}/irexpand.spad )
+
+@
+\subsection{irsn.spad \cite{1}}
+<<irsn.spad (SPAD from IN)>>=
+${MID}/irsn.spad: ${IN}/irsn.spad.pamphlet
+ @ echo 0 making ${MID}/irsn.spad from ${IN}/irsn.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/irsn.spad.pamphlet >irsn.spad )
+
+@
+<<IRSN.o (O from NRLIB)>>=
+${OUT}/IRSN.o: ${MID}/IRSN.NRLIB
+ @ echo 0 making ${OUT}/IRSN.o from ${MID}/IRSN.NRLIB
+ @ cp ${MID}/IRSN.NRLIB/code.o ${OUT}/IRSN.o
+
+@
+<<IRSN.NRLIB (NRLIB from MID)>>=
+${MID}/IRSN.NRLIB: ${MID}/IRSN.spad
+ @ echo 0 making ${MID}/IRSN.NRLIB from ${MID}/IRSN.spad
+ @ (cd ${MID} ; echo ')co IRSN.spad' | ${INTERPSYS} )
+
+@
+<<IRSN.spad (SPAD from IN)>>=
+${MID}/IRSN.spad: ${IN}/irsn.spad.pamphlet
+ @ echo 0 making ${MID}/IRSN.spad from ${IN}/irsn.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IRSN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IRSN IrrRepSymNatPackage" ${IN}/irsn.spad.pamphlet >IRSN.spad )
+
+@
+<<irsn.spad.dvi (DOC from IN)>>=
+${DOC}/irsn.spad.dvi: ${IN}/irsn.spad.pamphlet
+ @ echo 0 making ${DOC}/irsn.spad.dvi from ${IN}/irsn.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/irsn.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} irsn.spad ; \
+ rm -f ${DOC}/irsn.spad.pamphlet ; \
+ rm -f ${DOC}/irsn.spad.tex ; \
+ rm -f ${DOC}/irsn.spad )
+
+@
+\subsection{ituple.spad \cite{1}}
+<<ituple.spad (SPAD from IN)>>=
+${MID}/ituple.spad: ${IN}/ituple.spad.pamphlet
+ @ echo 0 making ${MID}/ituple.spad from ${IN}/ituple.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ituple.spad.pamphlet >ituple.spad )
+
+@
+<<ITFUN2.o (O from NRLIB)>>=
+${OUT}/ITFUN2.o: ${MID}/ITFUN2.NRLIB
+ @ echo 0 making ${OUT}/ITFUN2.o from ${MID}/ITFUN2.NRLIB
+ @ cp ${MID}/ITFUN2.NRLIB/code.o ${OUT}/ITFUN2.o
+
+@
+<<ITFUN2.NRLIB (NRLIB from MID)>>=
+${MID}/ITFUN2.NRLIB: ${OUT}/TYPE.o ${MID}/ITFUN2.spad
+ @ echo 0 making ${MID}/ITFUN2.NRLIB from ${MID}/ITFUN2.spad
+ @ (cd ${MID} ; echo ')co ITFUN2.spad' | ${INTERPSYS} )
+
+@
+<<ITFUN2.spad (SPAD from IN)>>=
+${MID}/ITFUN2.spad: ${IN}/ituple.spad.pamphlet
+ @ echo 0 making ${MID}/ITFUN2.spad from ${IN}/ituple.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ITFUN2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ITFUN2 InfiniteTupleFunctions2" ${IN}/ituple.spad.pamphlet >ITFUN2.spad )
+
+@
+<<ITFUN3.o (O from NRLIB)>>=
+${OUT}/ITFUN3.o: ${MID}/ITFUN3.NRLIB
+ @ echo 0 making ${OUT}/ITFUN3.o from ${MID}/ITFUN3.NRLIB
+ @ cp ${MID}/ITFUN3.NRLIB/code.o ${OUT}/ITFUN3.o
+
+@
+<<ITFUN3.NRLIB (NRLIB from MID)>>=
+${MID}/ITFUN3.NRLIB: ${OUT}/TYPE.o ${MID}/ITFUN3.spad
+ @ echo 0 making ${MID}/ITFUN3.NRLIB from ${MID}/ITFUN3.spad
+ @ (cd ${MID} ; echo ')co ITFUN3.spad' | ${INTERPSYS} )
+
+@
+<<ITFUN3.spad (SPAD from IN)>>=
+${MID}/ITFUN3.spad: ${IN}/ituple.spad.pamphlet
+ @ echo 0 making ${MID}/ITFUN3.spad from ${IN}/ituple.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ITFUN3.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ITFUN3 InfiniteTupleFunctions3" ${IN}/ituple.spad.pamphlet >ITFUN3.spad )
+
+@
+<<ITUPLE.o (O from NRLIB)>>=
+${OUT}/ITUPLE.o: ${MID}/ITUPLE.NRLIB
+ @ echo 0 making ${OUT}/ITUPLE.o from ${MID}/ITUPLE.NRLIB
+ @ cp ${MID}/ITUPLE.NRLIB/code.o ${OUT}/ITUPLE.o
+
+@
+<<ITUPLE.NRLIB (NRLIB from MID)>>=
+${MID}/ITUPLE.NRLIB: ${OUT}/KOERCE.o ${OUT}/TYPE.o ${MID}/ITUPLE.spad
+ @ echo 0 making ${MID}/ITUPLE.NRLIB from ${MID}/ITUPLE.spad
+ @ (cd ${MID} ; echo ')co ITUPLE.spad' | ${INTERPSYS} )
+
+@
+<<ITUPLE.spad (SPAD from IN)>>=
+${MID}/ITUPLE.spad: ${IN}/ituple.spad.pamphlet
+ @ echo 0 making ${MID}/ITUPLE.spad from ${IN}/ituple.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ITUPLE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ITUPLE InfiniteTuple" ${IN}/ituple.spad.pamphlet >ITUPLE.spad )
+
+@
+<<ituple.spad.dvi (DOC from IN)>>=
+${DOC}/ituple.spad.dvi: ${IN}/ituple.spad.pamphlet
+ @ echo 0 making ${DOC}/ituple.spad.dvi from ${IN}/ituple.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ituple.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ituple.spad ; \
+ rm -f ${DOC}/ituple.spad.pamphlet ; \
+ rm -f ${DOC}/ituple.spad.tex ; \
+ rm -f ${DOC}/ituple.spad )
+
+@
+\subsection{iviews.as \cite{1}}
+<<iviews.as (SPAD from IN)>>=
+${MID}/iviews.as: ${IN}/iviews.as.pamphlet
+ @ echo 0 making ${MID}/iviews.as from ${IN}/iviews.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/iviews.as.pamphlet >iviews.as )
+
+@
+<<iviews.as.dvi (DOC from IN)>>=
+${DOC}/iviews.as.dvi: ${IN}/iviews.as.pamphlet
+ @ echo 0 making ${DOC}/iviews.as.dvi from ${IN}/iviews.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/iviews.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} iviews.as ; \
+ rm -f ${DOC}/iviews.as.pamphlet ; \
+ rm -f ${DOC}/iviews.as.tex ; \
+ rm -f ${DOC}/iviews.as )
+
+@
+\subsection{kl.spad \cite{1}}
+<<kl.spad (SPAD from IN)>>=
+${MID}/kl.spad: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${MID}/kl.spad from ${IN}/kl.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/kl.spad.pamphlet >kl.spad )
+
+@
+<<CACHSET.o (O from NRLIB)>>=
+${OUT}/CACHSET.o: ${MID}/CACHSET.NRLIB
+ @ echo 0 making ${OUT}/CACHSET.o from ${MID}/CACHSET.NRLIB
+ @ cp ${MID}/CACHSET.NRLIB/code.o ${OUT}/CACHSET.o
+
+@
+<<CACHSET.NRLIB (NRLIB from MID)>>=
+${MID}/CACHSET.NRLIB: ${MID}/CACHSET.spad
+ @ echo 0 making ${MID}/CACHSET.NRLIB from ${MID}/CACHSET.spad
+ @ (cd ${MID} ; echo ')co CACHSET.spad' | ${INTERPSYS} )
+
+@
+<<CACHSET.spad (SPAD from IN)>>=
+${MID}/CACHSET.spad: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${MID}/CACHSET.spad from ${IN}/kl.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CACHSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"category CACHSET CachableSet" ${IN}/kl.spad.pamphlet >CACHSET.spad )
+
+@
+<<KERNEL.o (O from NRLIB)>>=
+${OUT}/KERNEL.o: ${MID}/KERNEL.NRLIB
+ @ echo 0 making ${OUT}/KERNEL.o from ${MID}/KERNEL.NRLIB
+ @ cp ${MID}/KERNEL.NRLIB/code.o ${OUT}/KERNEL.o
+
+@
+<<KERNEL.NRLIB (NRLIB from MID)>>=
+${MID}/KERNEL.NRLIB: ${MID}/KERNEL.spad
+ @ echo 0 making ${MID}/KERNEL.NRLIB from ${MID}/KERNEL.spad
+ @ (cd ${MID} ; echo ')co KERNEL.spad' | ${INTERPSYS} )
+
+@
+<<KERNEL.spad (SPAD from IN)>>=
+${MID}/KERNEL.spad: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${MID}/KERNEL.spad from ${IN}/kl.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf KERNEL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain KERNEL Kernel" ${IN}/kl.spad.pamphlet >KERNEL.spad )
+
+@
+<<KERNEL2.o (O from NRLIB)>>=
+${OUT}/KERNEL2.o: ${MID}/KERNEL2.NRLIB
+ @ echo 0 making ${OUT}/KERNEL2.o from ${MID}/KERNEL2.NRLIB
+ @ cp ${MID}/KERNEL2.NRLIB/code.o ${OUT}/KERNEL2.o
+
+@
+<<KERNEL2.NRLIB (NRLIB from MID)>>=
+${MID}/KERNEL2.NRLIB: ${MID}/KERNEL2.spad
+ @ echo 0 making ${MID}/KERNEL2.NRLIB from ${MID}/KERNEL2.spad
+ @ (cd ${MID} ; echo ')co KERNEL2.spad' | ${INTERPSYS} )
+
+@
+<<KERNEL2.spad (SPAD from IN)>>=
+${MID}/KERNEL2.spad: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${MID}/KERNEL2.spad from ${IN}/kl.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf KERNEL2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package KERNEL2 KernelFunctions2" ${IN}/kl.spad.pamphlet >KERNEL2.spad )
+
+@
+<<MKCHSET.o (O from NRLIB)>>=
+${OUT}/MKCHSET.o: ${MID}/MKCHSET.NRLIB
+ @ echo 0 making ${OUT}/MKCHSET.o from ${MID}/MKCHSET.NRLIB
+ @ cp ${MID}/MKCHSET.NRLIB/code.o ${OUT}/MKCHSET.o
+
+@
+<<MKCHSET.NRLIB (NRLIB from MID)>>=
+${MID}/MKCHSET.NRLIB: ${MID}/MKCHSET.spad
+ @ echo 0 making ${MID}/MKCHSET.NRLIB from ${MID}/MKCHSET.spad
+ @ (cd ${MID} ; echo ')co MKCHSET.spad' | ${INTERPSYS} )
+
+@
+<<MKCHSET.spad (SPAD from IN)>>=
+${MID}/MKCHSET.spad: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${MID}/MKCHSET.spad from ${IN}/kl.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MKCHSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MKCHSET MakeCachableSet" ${IN}/kl.spad.pamphlet >MKCHSET.spad )
+
+@
+<<SCACHE.o (O from NRLIB)>>=
+${OUT}/SCACHE.o: ${MID}/SCACHE.NRLIB
+ @ echo 0 making ${OUT}/SCACHE.o from ${MID}/SCACHE.NRLIB
+ @ cp ${MID}/SCACHE.NRLIB/code.o ${OUT}/SCACHE.o
+
+@
+<<SCACHE.NRLIB (NRLIB from MID)>>=
+${MID}/SCACHE.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SCACHE.spad
+ @ echo 0 making ${MID}/SCACHE.NRLIB from ${MID}/SCACHE.spad
+ @ (cd ${MID} ; echo ')co SCACHE.spad' | ${INTERPSYS} )
+
+@
+<<SCACHE.spad (SPAD from IN)>>=
+${MID}/SCACHE.spad: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${MID}/SCACHE.spad from ${IN}/kl.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SCACHE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SCACHE SortedCache" ${IN}/kl.spad.pamphlet >SCACHE.spad )
+
+@
+<<kl.spad.dvi (DOC from IN)>>=
+${DOC}/kl.spad.dvi: ${IN}/kl.spad.pamphlet
+ @ echo 0 making ${DOC}/kl.spad.dvi from ${IN}/kl.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/kl.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} kl.spad ; \
+ rm -f ${DOC}/kl.spad.pamphlet ; \
+ rm -f ${DOC}/kl.spad.tex ; \
+ rm -f ${DOC}/kl.spad )
+
+@
+\subsection{kovacic.spad \cite{1}}
+<<kovacic.spad (SPAD from IN)>>=
+${MID}/kovacic.spad: ${IN}/kovacic.spad.pamphlet
+ @ echo 0 making ${MID}/kovacic.spad from ${IN}/kovacic.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/kovacic.spad.pamphlet >kovacic.spad )
+
+@
+<<KOVACIC.o (O from NRLIB)>>=
+${OUT}/KOVACIC.o: ${MID}/KOVACIC.NRLIB
+ @ echo 0 making ${OUT}/KOVACIC.o from ${MID}/KOVACIC.NRLIB
+ @ cp ${MID}/KOVACIC.NRLIB/code.o ${OUT}/KOVACIC.o
+
+@
+<<KOVACIC.NRLIB (NRLIB from MID)>>=
+${MID}/KOVACIC.NRLIB: ${MID}/KOVACIC.spad
+ @ echo 0 making ${MID}/KOVACIC.NRLIB from ${MID}/KOVACIC.spad
+ @ (cd ${MID} ; echo ')co KOVACIC.spad' | ${INTERPSYS} )
+
+@
+<<KOVACIC.spad (SPAD from IN)>>=
+${MID}/KOVACIC.spad: ${IN}/kovacic.spad.pamphlet
+ @ echo 0 making ${MID}/KOVACIC.spad from ${IN}/kovacic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf KOVACIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package KOVACIC Kovacic" ${IN}/kovacic.spad.pamphlet >KOVACIC.spad )
+
+@
+<<kovacic.spad.dvi (DOC from IN)>>=
+${DOC}/kovacic.spad.dvi: ${IN}/kovacic.spad.pamphlet
+ @ echo 0 making ${DOC}/kovacic.spad.dvi from ${IN}/kovacic.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/kovacic.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} kovacic.spad ; \
+ rm -f ${DOC}/kovacic.spad.pamphlet ; \
+ rm -f ${DOC}/kovacic.spad.tex ; \
+ rm -f ${DOC}/kovacic.spad )
+
+@
+\subsection{laplace.spad \cite{1}}
+<<laplace.spad (SPAD from IN)>>=
+${MID}/laplace.spad: ${IN}/laplace.spad.pamphlet
+ @ echo 0 making ${MID}/laplace.spad from ${IN}/laplace.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/laplace.spad.pamphlet >laplace.spad )
+
+@
+<<INVLAPLA.o (O from NRLIB)>>=
+${OUT}/INVLAPLA.o: ${MID}/INVLAPLA.NRLIB
+ @ echo 0 making ${OUT}/INVLAPLA.o from ${MID}/INVLAPLA.NRLIB
+ @ cp ${MID}/INVLAPLA.NRLIB/code.o ${OUT}/INVLAPLA.o
+
+@
+<<INVLAPLA.NRLIB (NRLIB from MID)>>=
+${MID}/INVLAPLA.NRLIB: ${MID}/INVLAPLA.spad
+ @ echo 0 making ${MID}/INVLAPLA.NRLIB from ${MID}/INVLAPLA.spad
+ @ (cd ${MID} ; echo ')co INVLAPLA.spad' | ${INTERPSYS} )
+
+@
+<<INVLAPLA.spad (SPAD from IN)>>=
+${MID}/INVLAPLA.spad: ${IN}/laplace.spad.pamphlet
+ @ echo 0 making ${MID}/INVLAPLA.spad from ${IN}/laplace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INVLAPLA.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INVLAPLA InverseLaplaceTransform" ${IN}/laplace.spad.pamphlet >INVLAPLA.spad )
+
+@
+<<LAPLACE.o (O from NRLIB)>>=
+${OUT}/LAPLACE.o: ${MID}/LAPLACE.NRLIB
+ @ echo 0 making ${OUT}/LAPLACE.o from ${MID}/LAPLACE.NRLIB
+ @ cp ${MID}/LAPLACE.NRLIB/code.o ${OUT}/LAPLACE.o
+
+@
+<<LAPLACE.NRLIB (NRLIB from MID)>>=
+${MID}/LAPLACE.NRLIB: ${MID}/LAPLACE.spad
+ @ echo 0 making ${MID}/LAPLACE.NRLIB from ${MID}/LAPLACE.spad
+ @ (cd ${MID} ; echo ')co LAPLACE.spad' | ${INTERPSYS} )
+
+@
+<<LAPLACE.spad (SPAD from IN)>>=
+${MID}/LAPLACE.spad: ${IN}/laplace.spad.pamphlet
+ @ echo 0 making ${MID}/LAPLACE.spad from ${IN}/laplace.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LAPLACE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LAPLACE LaplaceTransform" ${IN}/laplace.spad.pamphlet >LAPLACE.spad )
+
+@
+<<laplace.spad.dvi (DOC from IN)>>=
+${DOC}/laplace.spad.dvi: ${IN}/laplace.spad.pamphlet
+ @ echo 0 making ${DOC}/laplace.spad.dvi from ${IN}/laplace.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/laplace.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} laplace.spad ; \
+ rm -f ${DOC}/laplace.spad.pamphlet ; \
+ rm -f ${DOC}/laplace.spad.tex ; \
+ rm -f ${DOC}/laplace.spad )
+
+@
+\subsection{laurent.spad \cite{1}}
+<<laurent.spad (SPAD from IN)>>=
+${MID}/laurent.spad: ${IN}/laurent.spad.pamphlet
+ @ echo 0 making ${MID}/laurent.spad from ${IN}/laurent.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/laurent.spad.pamphlet >laurent.spad )
+
+@
+<<ULS.o (O from NRLIB)>>=
+${OUT}/ULS.o: ${MID}/ULS.NRLIB
+ @ echo 0 making ${OUT}/ULS.o from ${MID}/ULS.NRLIB
+ @ cp ${MID}/ULS.NRLIB/code.o ${OUT}/ULS.o
+
+@
+<<ULS.NRLIB (NRLIB from MID)>>=
+${MID}/ULS.NRLIB: ${MID}/ULS.spad
+ @ echo 0 making ${MID}/ULS.NRLIB from ${MID}/ULS.spad
+ @ (cd ${MID} ; echo ')co ULS.spad' | ${INTERPSYS} )
+
+@
+<<ULS.spad (SPAD from IN)>>=
+${MID}/ULS.spad: ${IN}/laurent.spad.pamphlet
+ @ echo 0 making ${MID}/ULS.spad from ${IN}/laurent.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ULS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ULS UnivariateLaurentSeries" ${IN}/laurent.spad.pamphlet >ULS.spad )
+
+@
+<<ULSCCAT-.o (O from NRLIB)>>=
+${OUT}/ULSCCAT-.o: ${MID}/ULSCCAT.NRLIB
+ @ echo 0 making ${OUT}/ULSCCAT-.o from ${MID}/ULSCCAT-.NRLIB
+ @ cp ${MID}/ULSCCAT-.NRLIB/code.o ${OUT}/ULSCCAT-.o
+
+@
+<<ULSCCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/ULSCCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/ULSCCAT.spad
+ @ echo 0 making ${MID}/ULSCCAT-.NRLIB from ${MID}/ULSCCAT.spad
+ @ (cd ${MID} ; echo ')co ULSCCAT.spad' | ${INTERPSYS} )
+
+@
+<<ULSCCAT.o (O from NRLIB)>>=
+${OUT}/ULSCCAT.o: ${MID}/ULSCCAT.NRLIB
+ @ echo 0 making ${OUT}/ULSCCAT.o from ${MID}/ULSCCAT.NRLIB
+ @ cp ${MID}/ULSCCAT.NRLIB/code.o ${OUT}/ULSCCAT.o
+
+@
+<<ULSCCAT.NRLIB (NRLIB from MID)>>=
+${MID}/ULSCCAT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ULSCCAT.spad
+ @ echo 0 making ${MID}/ULSCCAT.NRLIB from ${MID}/ULSCCAT.spad
+ @ (cd ${MID} ; echo ')co ULSCCAT.spad' | ${INTERPSYS} )
+
+@
+<<ULSCCAT.spad (SPAD from IN)>>=
+${MID}/ULSCCAT.spad: ${IN}/laurent.spad.pamphlet
+ @ echo 0 making ${MID}/ULSCCAT.spad from ${IN}/laurent.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ULSCCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ULSCCAT UnivariateLaurentSeriesConstructorCategory" ${IN}/laurent.spad.pamphlet >ULSCCAT.spad )
+
+@
+<<ULSCONS.o (O from NRLIB)>>=
+${OUT}/ULSCONS.o: ${MID}/ULSCONS.NRLIB
+ @ echo 0 making ${OUT}/ULSCONS.o from ${MID}/ULSCONS.NRLIB
+ @ cp ${MID}/ULSCONS.NRLIB/code.o ${OUT}/ULSCONS.o
+
+@
+<<ULSCONS.NRLIB (NRLIB from MID)>>=
+${MID}/ULSCONS.NRLIB: ${MID}/ULSCONS.spad
+ @ echo 0 making ${MID}/ULSCONS.NRLIB from ${MID}/ULSCONS.spad
+ @ (cd ${MID} ; echo ')co ULSCONS.spad' | ${INTERPSYS} )
+
+@
+<<ULSCONS.spad (SPAD from IN)>>=
+${MID}/ULSCONS.spad: ${IN}/laurent.spad.pamphlet
+ @ echo 0 making ${MID}/ULSCONS.spad from ${IN}/laurent.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ULSCONS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ULSCONS UnivariateLaurentSeriesConstructor" ${IN}/laurent.spad.pamphlet >ULSCONS.spad )
+
+@
+<<ULS2.o (O from NRLIB)>>=
+${OUT}/ULS2.o: ${MID}/ULS2.NRLIB
+ @ echo 0 making ${OUT}/ULS2.o from ${MID}/ULS2.NRLIB
+ @ cp ${MID}/ULS2.NRLIB/code.o ${OUT}/ULS2.o
+
+@
+<<ULS2.NRLIB (NRLIB from MID)>>=
+${MID}/ULS2.NRLIB: ${MID}/ULS2.spad
+ @ echo 0 making ${MID}/ULS2.NRLIB from ${MID}/ULS2.spad
+ @ (cd ${MID} ; echo ')co ULS2.spad' | ${INTERPSYS} )
+
+@
+<<ULS2.spad (SPAD from IN)>>=
+${MID}/ULS2.spad: ${IN}/laurent.spad.pamphlet
+ @ echo 0 making ${MID}/ULS2.spad from ${IN}/laurent.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ULS2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ULS2 UnivariateLaurentSeriesFunctions2" ${IN}/laurent.spad.pamphlet >ULS2.spad )
+
+@
+<<laurent.spad.dvi (DOC from IN)>>=
+${DOC}/laurent.spad.dvi: ${IN}/laurent.spad.pamphlet
+ @ echo 0 making ${DOC}/laurent.spad.dvi from ${IN}/laurent.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/laurent.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} laurent.spad ; \
+ rm -f ${DOC}/laurent.spad.pamphlet ; \
+ rm -f ${DOC}/laurent.spad.tex ; \
+ rm -f ${DOC}/laurent.spad )
+
+@
+\subsection{leadcdet.spad \cite{1}}
+<<leadcdet.spad (SPAD from IN)>>=
+${MID}/leadcdet.spad: ${IN}/leadcdet.spad.pamphlet
+ @ echo 0 making ${MID}/leadcdet.spad from ${IN}/leadcdet.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/leadcdet.spad.pamphlet >leadcdet.spad )
+
+@
+<<LEADCDET.o (O from NRLIB)>>=
+${OUT}/LEADCDET.o: ${MID}/LEADCDET.NRLIB
+ @ echo 0 making ${OUT}/LEADCDET.o from ${MID}/LEADCDET.NRLIB
+ @ cp ${MID}/LEADCDET.NRLIB/code.o ${OUT}/LEADCDET.o
+
+@
+<<LEADCDET.NRLIB (NRLIB from MID)>>=
+${MID}/LEADCDET.NRLIB: ${MID}/LEADCDET.spad
+ @ echo 0 making ${MID}/LEADCDET.NRLIB from ${MID}/LEADCDET.spad
+ @ (cd ${MID} ; echo ')co LEADCDET.spad' | ${INTERPSYS} )
+
+@
+<<LEADCDET.spad (SPAD from IN)>>=
+${MID}/LEADCDET.spad: ${IN}/leadcdet.spad.pamphlet
+ @ echo 0 making ${MID}/LEADCDET.spad from ${IN}/leadcdet.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LEADCDET.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LEADCDET LeadingCoefDetermination" ${IN}/leadcdet.spad.pamphlet >LEADCDET.spad )
+
+@
+<<leadcdet.spad.dvi (DOC from IN)>>=
+${DOC}/leadcdet.spad.dvi: ${IN}/leadcdet.spad.pamphlet
+ @ echo 0 making ${DOC}/leadcdet.spad.dvi from ${IN}/leadcdet.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/leadcdet.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} leadcdet.spad ; \
+ rm -f ${DOC}/leadcdet.spad.pamphlet ; \
+ rm -f ${DOC}/leadcdet.spad.tex ; \
+ rm -f ${DOC}/leadcdet.spad )
+
+@
+\subsection{lie.spad \cite{1}}
+<<lie.spad (SPAD from IN)>>=
+${MID}/lie.spad: ${IN}/lie.spad.pamphlet
+ @ echo 0 making ${MID}/lie.spad from ${IN}/lie.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lie.spad.pamphlet >lie.spad )
+
+@
+<<JORDAN.o (O from NRLIB)>>=
+${OUT}/JORDAN.o: ${MID}/JORDAN.NRLIB
+ @ echo 0 making ${OUT}/JORDAN.o from ${MID}/JORDAN.NRLIB
+ @ cp ${MID}/JORDAN.NRLIB/code.o ${OUT}/JORDAN.o
+
+@
+<<JORDAN.NRLIB (NRLIB from MID)>>=
+${MID}/JORDAN.NRLIB: ${MID}/JORDAN.spad
+ @ echo 0 making ${MID}/JORDAN.NRLIB from ${MID}/JORDAN.spad
+ @ (cd ${MID} ; echo ')co JORDAN.spad' | ${INTERPSYS} )
+
+@
+<<JORDAN.spad (SPAD from IN)>>=
+${MID}/JORDAN.spad: ${IN}/lie.spad.pamphlet
+ @ echo 0 making ${MID}/JORDAN.spad from ${IN}/lie.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf JORDAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain JORDAN AssociatedJordanAlgebra" ${IN}/lie.spad.pamphlet >JORDAN.spad )
+
+@
+<<LIE.o (O from NRLIB)>>=
+${OUT}/LIE.o: ${MID}/LIE.NRLIB
+ @ echo 0 making ${OUT}/LIE.o from ${MID}/LIE.NRLIB
+ @ cp ${MID}/LIE.NRLIB/code.o ${OUT}/LIE.o
+
+@
+<<LIE.NRLIB (NRLIB from MID)>>=
+${MID}/LIE.NRLIB: ${MID}/LIE.spad
+ @ echo 0 making ${MID}/LIE.NRLIB from ${MID}/LIE.spad
+ @ (cd ${MID} ; echo ')co LIE.spad' | ${INTERPSYS} )
+
+@
+<<LIE.spad (SPAD from IN)>>=
+${MID}/LIE.spad: ${IN}/lie.spad.pamphlet
+ @ echo 0 making ${MID}/LIE.spad from ${IN}/lie.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LIE AssociatedLieAlgebra" ${IN}/lie.spad.pamphlet >LIE.spad )
+
+@
+<<LSQM.o (O from NRLIB)>>=
+${OUT}/LSQM.o: ${MID}/LSQM.NRLIB
+ @ echo 0 making ${OUT}/LSQM.o from ${MID}/LSQM.NRLIB
+ @ cp ${MID}/LSQM.NRLIB/code.o ${OUT}/LSQM.o
+
+@
+<<LSQM.NRLIB (NRLIB from MID)>>=
+${MID}/LSQM.NRLIB: ${MID}/LSQM.spad
+ @ echo 0 making ${MID}/LSQM.NRLIB from ${MID}/LSQM.spad
+ @ (cd ${MID} ; echo ')co LSQM.spad' | ${INTERPSYS} )
+
+@
+<<LSQM.spad (SPAD from IN)>>=
+${MID}/LSQM.spad: ${IN}/lie.spad.pamphlet
+ @ echo 0 making ${MID}/LSQM.spad from ${IN}/lie.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSQM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LSQM LieSquareMatrix" ${IN}/lie.spad.pamphlet >LSQM.spad )
+
+@
+<<lie.spad.dvi (DOC from IN)>>=
+${DOC}/lie.spad.dvi: ${IN}/lie.spad.pamphlet
+ @ echo 0 making ${DOC}/lie.spad.dvi from ${IN}/lie.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lie.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lie.spad ; \
+ rm -f ${DOC}/lie.spad.pamphlet ; \
+ rm -f ${DOC}/lie.spad.tex ; \
+ rm -f ${DOC}/lie.spad )
+
+@
+\subsection{limitps.spad \cite{1}}
+<<limitps.spad (SPAD from IN)>>=
+${MID}/limitps.spad: ${IN}/limitps.spad.pamphlet
+ @ echo 0 making ${MID}/limitps.spad from ${IN}/limitps.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/limitps.spad.pamphlet >limitps.spad )
+
+@
+<<LIMITPS.o (O from NRLIB)>>=
+${OUT}/LIMITPS.o: ${MID}/LIMITPS.NRLIB
+ @ echo 0 making ${OUT}/LIMITPS.o from ${MID}/LIMITPS.NRLIB
+ @ cp ${MID}/LIMITPS.NRLIB/code.o ${OUT}/LIMITPS.o
+
+@
+<<LIMITPS.NRLIB (NRLIB from MID)>>=
+${MID}/LIMITPS.NRLIB: ${MID}/LIMITPS.spad
+ @ echo 0 making ${MID}/LIMITPS.NRLIB from ${MID}/LIMITPS.spad
+ @ (cd ${MID} ; echo ')co LIMITPS.spad' | ${INTERPSYS} )
+
+@
+<<LIMITPS.spad (SPAD from IN)>>=
+${MID}/LIMITPS.spad: ${IN}/limitps.spad.pamphlet
+ @ echo 0 making ${MID}/LIMITPS.spad from ${IN}/limitps.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIMITPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LIMITPS PowerSeriesLimitPackage" ${IN}/limitps.spad.pamphlet >LIMITPS.spad )
+
+@
+<<limitps.spad.dvi (DOC from IN)>>=
+${DOC}/limitps.spad.dvi: ${IN}/limitps.spad.pamphlet
+ @ echo 0 making ${DOC}/limitps.spad.dvi from ${IN}/limitps.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/limitps.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} limitps.spad ; \
+ rm -f ${DOC}/limitps.spad.pamphlet ; \
+ rm -f ${DOC}/limitps.spad.tex ; \
+ rm -f ${DOC}/limitps.spad )
+
+@
+\subsection{lindep.spad \cite{1}}
+<<lindep.spad (SPAD from IN)>>=
+${MID}/lindep.spad: ${IN}/lindep.spad.pamphlet
+ @ echo 0 making ${MID}/lindep.spad from ${IN}/lindep.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lindep.spad.pamphlet >lindep.spad )
+
+@
+<<LINDEP.o (O from NRLIB)>>=
+${OUT}/LINDEP.o: ${MID}/LINDEP.NRLIB
+ @ echo 0 making ${OUT}/LINDEP.o from ${MID}/LINDEP.NRLIB
+ @ cp ${MID}/LINDEP.NRLIB/code.o ${OUT}/LINDEP.o
+
+@
+<<LINDEP.NRLIB (NRLIB from MID)>>=
+${MID}/LINDEP.NRLIB: ${MID}/LINDEP.spad
+ @ echo 0 making ${MID}/LINDEP.NRLIB from ${MID}/LINDEP.spad
+ @ (cd ${MID} ; echo ')co LINDEP.spad' | ${INTERPSYS} )
+
+@
+<<LINDEP.spad (SPAD from IN)>>=
+${MID}/LINDEP.spad: ${IN}/lindep.spad.pamphlet
+ @ echo 0 making ${MID}/LINDEP.spad from ${IN}/lindep.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LINDEP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LINDEP LinearDependence" ${IN}/lindep.spad.pamphlet >LINDEP.spad )
+
+@
+<<ZLINDEP.o (O from NRLIB)>>=
+${OUT}/ZLINDEP.o: ${MID}/ZLINDEP.NRLIB
+ @ echo 0 making ${OUT}/ZLINDEP.o from ${MID}/ZLINDEP.NRLIB
+ @ cp ${MID}/ZLINDEP.NRLIB/code.o ${OUT}/ZLINDEP.o
+
+@
+<<ZLINDEP.NRLIB (NRLIB from MID)>>=
+${MID}/ZLINDEP.NRLIB: ${MID}/ZLINDEP.spad
+ @ echo 0 making ${MID}/ZLINDEP.NRLIB from ${MID}/ZLINDEP.spad
+ @ (cd ${MID} ; echo ')co ZLINDEP.spad' | ${INTERPSYS} )
+
+@
+<<ZLINDEP.spad (SPAD from IN)>>=
+${MID}/ZLINDEP.spad: ${IN}/lindep.spad.pamphlet
+ @ echo 0 making ${MID}/ZLINDEP.spad from ${IN}/lindep.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ZLINDEP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ZLINDEP IntegerLinearDependence" ${IN}/lindep.spad.pamphlet >ZLINDEP.spad )
+
+@
+<<lindep.spad.dvi (DOC from IN)>>=
+${DOC}/lindep.spad.dvi: ${IN}/lindep.spad.pamphlet
+ @ echo 0 making ${DOC}/lindep.spad.dvi from ${IN}/lindep.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lindep.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lindep.spad ; \
+ rm -f ${DOC}/lindep.spad.pamphlet ; \
+ rm -f ${DOC}/lindep.spad.tex ; \
+ rm -f ${DOC}/lindep.spad )
+
+@
+\subsection{lingrob.spad \cite{1}}
+<<lingrob.spad (SPAD from IN)>>=
+${MID}/lingrob.spad: ${IN}/lingrob.spad.pamphlet
+ @ echo 0 making ${MID}/lingrob.spad from ${IN}/lingrob.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lingrob.spad.pamphlet >lingrob.spad )
+
+@
+<<LGROBP.o (O from NRLIB)>>=
+${OUT}/LGROBP.o: ${MID}/LGROBP.NRLIB
+ @ echo 0 making ${OUT}/LGROBP.o from ${MID}/LGROBP.NRLIB
+ @ cp ${MID}/LGROBP.NRLIB/code.o ${OUT}/LGROBP.o
+
+@
+<<LGROBP.NRLIB (NRLIB from MID)>>=
+${MID}/LGROBP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/LGROBP.spad
+ @ echo 0 making ${MID}/LGROBP.NRLIB from ${MID}/LGROBP.spad
+ @ (cd ${MID} ; echo ')co LGROBP.spad' | ${INTERPSYS} )
+
+@
+<<LGROBP.spad (SPAD from IN)>>=
+${MID}/LGROBP.spad: ${IN}/lingrob.spad.pamphlet
+ @ echo 0 making ${MID}/LGROBP.spad from ${IN}/lingrob.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LGROBP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LGROBP LinGroebnerPackage" ${IN}/lingrob.spad.pamphlet >LGROBP.spad )
+
+@
+<<lingrob.spad.dvi (DOC from IN)>>=
+${DOC}/lingrob.spad.dvi: ${IN}/lingrob.spad.pamphlet
+ @ echo 0 making ${DOC}/lingrob.spad.dvi from ${IN}/lingrob.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lingrob.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lingrob.spad ; \
+ rm -f ${DOC}/lingrob.spad.pamphlet ; \
+ rm -f ${DOC}/lingrob.spad.tex ; \
+ rm -f ${DOC}/lingrob.spad )
+
+@
+\subsection{liouv.spad \cite{1}}
+<<liouv.spad (SPAD from IN)>>=
+${MID}/liouv.spad: ${IN}/liouv.spad.pamphlet
+ @ echo 0 making ${MID}/liouv.spad from ${IN}/liouv.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/liouv.spad.pamphlet >liouv.spad )
+
+@
+<<LF.o (O from NRLIB)>>=
+${OUT}/LF.o: ${MID}/LF.NRLIB
+ @ echo 0 making ${OUT}/LF.o from ${MID}/LF.NRLIB
+ @ cp ${MID}/LF.NRLIB/code.o ${OUT}/LF.o
+
+@
+<<LF.NRLIB (NRLIB from MID)>>=
+${MID}/LF.NRLIB: ${MID}/LF.spad
+ @ echo 0 making ${MID}/LF.NRLIB from ${MID}/LF.spad
+ @ (cd ${MID} ; echo ')co LF.spad' | ${INTERPSYS} )
+
+@
+<<LF.spad (SPAD from IN)>>=
+${MID}/LF.spad: ${IN}/liouv.spad.pamphlet
+ @ echo 0 making ${MID}/LF.spad from ${IN}/liouv.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LF LiouvillianFunction" ${IN}/liouv.spad.pamphlet >LF.spad )
+
+@
+<<liouv.spad.dvi (DOC from IN)>>=
+${DOC}/liouv.spad.dvi: ${IN}/liouv.spad.pamphlet
+ @ echo 0 making ${DOC}/liouv.spad.dvi from ${IN}/liouv.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/liouv.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} liouv.spad ; \
+ rm -f ${DOC}/liouv.spad.pamphlet ; \
+ rm -f ${DOC}/liouv.spad.tex ; \
+ rm -f ${DOC}/liouv.spad )
+
+@
+\subsection{listgcd.spad \cite{1}}
+<<listgcd.spad (SPAD from IN)>>=
+${MID}/listgcd.spad: ${IN}/listgcd.spad.pamphlet
+ @ echo 0 making ${MID}/listgcd.spad from ${IN}/listgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/listgcd.spad.pamphlet >listgcd.spad )
+
+@
+<<HEUGCD.o (O from NRLIB)>>=
+${OUT}/HEUGCD.o: ${MID}/HEUGCD.NRLIB
+ @ echo 0 making ${OUT}/HEUGCD.o from ${MID}/HEUGCD.NRLIB
+ @ cp ${MID}/HEUGCD.NRLIB/code.o ${OUT}/HEUGCD.o
+
+@
+<<HEUGCD.NRLIB (NRLIB from MID)>>=
+${MID}/HEUGCD.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/HEUGCD.spad
+ @ echo 0 making ${MID}/HEUGCD.NRLIB from ${MID}/HEUGCD.spad
+ @ (cd ${MID} ; echo ')co HEUGCD.spad' | ${INTERPSYS} )
+
+@
+<<HEUGCD.spad (SPAD from IN)>>=
+${MID}/HEUGCD.spad: ${IN}/listgcd.spad.pamphlet
+ @ echo 0 making ${MID}/HEUGCD.spad from ${IN}/listgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HEUGCD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package HEUGCD HeuGcd" ${IN}/listgcd.spad.pamphlet >HEUGCD.spad )
+
+@
+<<listgcd.spad.dvi (DOC from IN)>>=
+${DOC}/listgcd.spad.dvi: ${IN}/listgcd.spad.pamphlet
+ @ echo 0 making ${DOC}/listgcd.spad.dvi from ${IN}/listgcd.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/listgcd.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} listgcd.spad ; \
+ rm -f ${DOC}/listgcd.spad.pamphlet ; \
+ rm -f ${DOC}/listgcd.spad.tex ; \
+ rm -f ${DOC}/listgcd.spad )
+
+@
+\subsection{list.spad \cite{1}}
+<<list.spad (SPAD from IN)>>=
+${MID}/list.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/list.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/list.spad.pamphlet >list.spad )
+
+@
+<<ILIST.o (O from NRLIB)>>=
+${OUT}/ILIST.o: ${MID}/ILIST.NRLIB
+ @ echo 0 making ${OUT}/ILIST.o from ${MID}/ILIST.NRLIB
+ @ cp ${MID}/ILIST.NRLIB/code.o ${OUT}/ILIST.o
+
+@
+<<ILIST.NRLIB (NRLIB from MID)>>=
+${MID}/ILIST.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ILIST.spad
+ @ echo 0 making ${MID}/ILIST.NRLIB from ${MID}/ILIST.spad
+ @ (cd ${MID} ; echo ')co ILIST.spad' | ${INTERPSYS} )
+
+@
+<<ILIST.spad (SPAD from IN)>>=
+${MID}/ILIST.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/ILIST.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ILIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ILIST IndexedList" ${IN}/list.spad.pamphlet >ILIST.spad )
+
+@
+<<ILIST.o (BOOTSTRAP from MID)>>=
+${MID}/ILIST.o: ${MID}/ILIST.lsp
+ @ echo 0 making ${MID}/ILIST.o from ${MID}/ILIST.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ILIST.lsp" :output-file "ILIST.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ILIST.o ${OUT}/ILIST.o
+
+@
+<<ILIST.lsp (LISP from IN)>>=
+${MID}/ILIST.lsp: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/ILIST.lsp from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ILIST.NRLIB ; \
+ rm -rf ${OUT}/ILIST.o ; \
+ ${SPADBIN}/notangle -R"ILIST.lsp BOOTSTRAP" ${IN}/list.spad.pamphlet >ILIST.lsp )
+
+@
+<<LIST.o (O from NRLIB)>>=
+${OUT}/LIST.o: ${MID}/LIST.NRLIB
+ @ echo 0 making ${OUT}/LIST.o from ${MID}/LIST.NRLIB
+ @ cp ${MID}/LIST.NRLIB/code.o ${OUT}/LIST.o
+
+@
+<<LIST.NRLIB (NRLIB from MID)>>=
+${MID}/LIST.NRLIB: ${MID}/LIST.spad
+ @ echo 0 making ${MID}/LIST.NRLIB from ${MID}/LIST.spad
+ @ (cd ${MID} ; echo ')co LIST.spad' | ${INTERPSYS} )
+
+@
+<<LIST.spad (SPAD from IN)>>=
+${MID}/LIST.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/LIST.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LIST List" ${IN}/list.spad.pamphlet >LIST.spad )
+
+@
+<<LIST.o (BOOTSTRAP from MID)>>=
+${MID}/LIST.o: ${MID}/LIST.lsp
+ @ echo 0 making ${MID}/LIST.o from ${MID}/LIST.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "LIST.lsp" :output-file "LIST.o"))' | ${DEPSYS} )
+ @ cp ${MID}/LIST.o ${OUT}/LIST.o
+
+@
+<<LIST.lsp (LISP from IN)>>=
+${MID}/LIST.lsp: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/LIST.lsp from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIST.NRLIB ; \
+ rm -rf ${OUT}/LIST.o ; \
+ ${SPADBIN}/notangle -R"LIST.lsp BOOTSTRAP" ${IN}/list.spad.pamphlet >LIST.lsp )
+
+@
+<<ALIST.o (O from NRLIB)>>=
+${OUT}/ALIST.o: ${MID}/ALIST.NRLIB
+ @ echo 0 making ${OUT}/ALIST.o from ${MID}/ALIST.NRLIB
+ @ cp ${MID}/ALIST.NRLIB/code.o ${OUT}/ALIST.o
+
+@
+<<ALIST.NRLIB (NRLIB from MID)>>=
+${MID}/ALIST.NRLIB: ${MID}/ALIST.spad
+ @ echo 0 making ${MID}/ALIST.NRLIB from ${MID}/ALIST.spad
+ @ (cd ${MID} ; echo ')co ALIST.spad' | ${INTERPSYS} )
+
+@
+<<ALIST.spad (SPAD from IN)>>=
+${MID}/ALIST.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/ALIST.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ALIST AssociationList" ${IN}/list.spad.pamphlet >ALIST.spad )
+
+@
+<<LIST2.o (O from NRLIB)>>=
+${OUT}/LIST2.o: ${MID}/LIST2.NRLIB
+ @ echo 0 making ${OUT}/LIST2.o from ${MID}/LIST2.NRLIB
+ @ cp ${MID}/LIST2.NRLIB/code.o ${OUT}/LIST2.o
+
+@
+<<LIST2.NRLIB (NRLIB from MID)>>=
+${MID}/LIST2.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/LIST2.spad
+ @ echo 0 making ${MID}/LIST2.NRLIB from ${MID}/LIST2.spad
+ @ (cd ${MID} ; echo ')co LIST2.spad' | ${INTERPSYS} )
+
+@
+<<LIST2.spad (SPAD from IN)>>=
+${MID}/LIST2.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/LIST2.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIST2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LIST2 ListFunctions2" ${IN}/list.spad.pamphlet >LIST2.spad )
+
+@
+<<LIST2MAP.o (O from NRLIB)>>=
+${OUT}/LIST2MAP.o: ${MID}/LIST2MAP.NRLIB
+ @ echo 0 making ${OUT}/LIST2MAP.o from ${MID}/LIST2MAP.NRLIB
+ @ cp ${MID}/LIST2MAP.NRLIB/code.o ${OUT}/LIST2MAP.o
+
+@
+<<LIST2MAP.NRLIB (NRLIB from MID)>>=
+${MID}/LIST2MAP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/LIST2MAP.spad
+ @ echo 0 making ${MID}/LIST2MAP.NRLIB from ${MID}/LIST2MAP.spad
+ @ (cd ${MID} ; echo ')co LIST2MAP.spad' | ${INTERPSYS} )
+
+@
+<<LIST2MAP.spad (SPAD from IN)>>=
+${MID}/LIST2MAP.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/LIST2MAP.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIST2MAP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LIST2MAP ListToMap" ${IN}/list.spad.pamphlet >LIST2MAP.spad )
+
+@
+<<LIST3.o (O from NRLIB)>>=
+${OUT}/LIST3.o: ${MID}/LIST3.NRLIB
+ @ echo 0 making ${OUT}/LIST3.o from ${MID}/LIST3.NRLIB
+ @ cp ${MID}/LIST3.NRLIB/code.o ${OUT}/LIST3.o
+
+@
+<<LIST3.NRLIB (NRLIB from MID)>>=
+${MID}/LIST3.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/LIST3.spad
+ @ echo 0 making ${MID}/LIST3.NRLIB from ${MID}/LIST3.spad
+ @ (cd ${MID} ; echo ')co LIST3.spad' | ${INTERPSYS} )
+
+@
+<<LIST3.spad (SPAD from IN)>>=
+${MID}/LIST3.spad: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${MID}/LIST3.spad from ${IN}/list.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIST3.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LIST3 ListFunctions3" ${IN}/list.spad.pamphlet >LIST3.spad )
+
+@
+<<list.spad.dvi (DOC from IN)>>=
+${DOC}/list.spad.dvi: ${IN}/list.spad.pamphlet
+ @ echo 0 making ${DOC}/list.spad.dvi from ${IN}/list.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/list.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} list.spad ; \
+ rm -f ${DOC}/list.spad.pamphlet ; \
+ rm -f ${DOC}/list.spad.tex ; \
+ rm -f ${DOC}/list.spad )
+
+@
+\subsection{lmdict.spad \cite{1}}
+<<lmdict.spad (SPAD from IN)>>=
+${MID}/lmdict.spad: ${IN}/lmdict.spad.pamphlet
+ @ echo 0 making ${MID}/lmdict.spad from ${IN}/lmdict.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lmdict.spad.pamphlet >lmdict.spad )
+
+@
+<<LMDICT.o (O from NRLIB)>>=
+${OUT}/LMDICT.o: ${MID}/LMDICT.NRLIB
+ @ echo 0 making ${OUT}/LMDICT.o from ${MID}/LMDICT.NRLIB
+ @ cp ${MID}/LMDICT.NRLIB/code.o ${OUT}/LMDICT.o
+
+@
+<<LMDICT.NRLIB (NRLIB from MID)>>=
+${MID}/LMDICT.NRLIB: ${MID}/LMDICT.spad
+ @ echo 0 making ${MID}/LMDICT.NRLIB from ${MID}/LMDICT.spad
+ @ (cd ${MID} ; echo ')co LMDICT.spad' | ${INTERPSYS} )
+
+@
+<<LMDICT.spad (SPAD from IN)>>=
+${MID}/LMDICT.spad: ${IN}/lmdict.spad.pamphlet
+ @ echo 0 making ${MID}/LMDICT.spad from ${IN}/lmdict.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LMDICT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LMDICT ListMultiDictionary" ${IN}/lmdict.spad.pamphlet >LMDICT.spad )
+
+@
+<<lmdict.spad.dvi (DOC from IN)>>=
+${DOC}/lmdict.spad.dvi: ${IN}/lmdict.spad.pamphlet
+ @ echo 0 making ${DOC}/lmdict.spad.dvi from ${IN}/lmdict.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lmdict.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lmdict.spad ; \
+ rm -f ${DOC}/lmdict.spad.pamphlet ; \
+ rm -f ${DOC}/lmdict.spad.tex ; \
+ rm -f ${DOC}/lmdict.spad )
+
+@
+\subsection{lodof.spad \cite{1}}
+<<lodof.spad (SPAD from IN)>>=
+${MID}/lodof.spad: ${IN}/lodof.spad.pamphlet
+ @ echo 0 making ${MID}/lodof.spad from ${IN}/lodof.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lodof.spad.pamphlet >lodof.spad )
+
+@
+<<ASSOCEQ.o (O from NRLIB)>>=
+${OUT}/ASSOCEQ.o: ${MID}/ASSOCEQ.NRLIB
+ @ echo 0 making ${OUT}/ASSOCEQ.o from ${MID}/ASSOCEQ.NRLIB
+ @ cp ${MID}/ASSOCEQ.NRLIB/code.o ${OUT}/ASSOCEQ.o
+
+@
+<<ASSOCEQ.NRLIB (NRLIB from MID)>>=
+${MID}/ASSOCEQ.NRLIB: ${MID}/ASSOCEQ.spad
+ @ echo 0 making ${MID}/ASSOCEQ.NRLIB from ${MID}/ASSOCEQ.spad
+ @ (cd ${MID} ; echo ')co ASSOCEQ.spad' | ${INTERPSYS} )
+
+@
+<<ASSOCEQ.spad (SPAD from IN)>>=
+${MID}/ASSOCEQ.spad: ${IN}/lodof.spad.pamphlet
+ @ echo 0 making ${MID}/ASSOCEQ.spad from ${IN}/lodof.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ASSOCEQ.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ASSOCEQ AssociatedEquations" ${IN}/lodof.spad.pamphlet >ASSOCEQ.spad )
+
+@
+<<LODOF.o (O from NRLIB)>>=
+${OUT}/LODOF.o: ${MID}/LODOF.NRLIB
+ @ echo 0 making ${OUT}/LODOF.o from ${MID}/LODOF.NRLIB
+ @ cp ${MID}/LODOF.NRLIB/code.o ${OUT}/LODOF.o
+
+@
+<<LODOF.NRLIB (NRLIB from MID)>>=
+${MID}/LODOF.NRLIB: ${MID}/LODOF.spad
+ @ echo 0 making ${MID}/LODOF.NRLIB from ${MID}/LODOF.spad
+ @ (cd ${MID} ; echo ')co LODOF.spad' | ${INTERPSYS} )
+
+@
+<<LODOF.spad (SPAD from IN)>>=
+${MID}/LODOF.spad: ${IN}/lodof.spad.pamphlet
+ @ echo 0 making ${MID}/LODOF.spad from ${IN}/lodof.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LODOF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LODOF LinearOrdinaryDifferentialOperatorFactorizer" ${IN}/lodof.spad.pamphlet >LODOF.spad )
+
+@
+<<PREASSOC.o (O from NRLIB)>>=
+${OUT}/PREASSOC.o: ${MID}/PREASSOC.NRLIB
+ @ echo 0 making ${OUT}/PREASSOC.o from ${MID}/PREASSOC.NRLIB
+ @ cp ${MID}/PREASSOC.NRLIB/code.o ${OUT}/PREASSOC.o
+
+@
+<<PREASSOC.NRLIB (NRLIB from MID)>>=
+${MID}/PREASSOC.NRLIB: ${MID}/PREASSOC.spad
+ @ echo 0 making ${MID}/PREASSOC.NRLIB from ${MID}/PREASSOC.spad
+ @ (cd ${MID} ; echo ')co PREASSOC.spad' | ${INTERPSYS} )
+
+@
+<<PREASSOC.spad (SPAD from IN)>>=
+${MID}/PREASSOC.spad: ${IN}/lodof.spad.pamphlet
+ @ echo 0 making ${MID}/PREASSOC.spad from ${IN}/lodof.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PREASSOC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PREASSOC PrecomputedAssociatedEquations" ${IN}/lodof.spad.pamphlet >PREASSOC.spad )
+
+@
+<<SETMN.o (O from NRLIB)>>=
+${OUT}/SETMN.o: ${MID}/SETMN.NRLIB
+ @ echo 0 making ${OUT}/SETMN.o from ${MID}/SETMN.NRLIB
+ @ cp ${MID}/SETMN.NRLIB/code.o ${OUT}/SETMN.o
+
+@
+<<SETMN.NRLIB (NRLIB from MID)>>=
+${MID}/SETMN.NRLIB: ${MID}/SETMN.spad
+ @ echo 0 making ${MID}/SETMN.NRLIB from ${MID}/SETMN.spad
+ @ (cd ${MID} ; echo ')co SETMN.spad' | ${INTERPSYS} )
+
+@
+<<SETMN.spad (SPAD from IN)>>=
+${MID}/SETMN.spad: ${IN}/lodof.spad.pamphlet
+ @ echo 0 making ${MID}/SETMN.spad from ${IN}/lodof.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SETMN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SETMN SetOfMIntegersInOneToN" ${IN}/lodof.spad.pamphlet >SETMN.spad )
+
+@
+<<lodof.spad.dvi (DOC from IN)>>=
+${DOC}/lodof.spad.dvi: ${IN}/lodof.spad.pamphlet
+ @ echo 0 making ${DOC}/lodof.spad.dvi from ${IN}/lodof.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lodof.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lodof.spad ; \
+ rm -f ${DOC}/lodof.spad.pamphlet ; \
+ rm -f ${DOC}/lodof.spad.tex ; \
+ rm -f ${DOC}/lodof.spad )
+
+@
+\subsection{lodop.spad \cite{1}}
+<<lodop.spad (SPAD from IN)>>=
+${MID}/lodop.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/lodop.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lodop.spad.pamphlet >lodop.spad )
+
+@
+<<DPMO.o (O from NRLIB)>>=
+${OUT}/DPMO.o: ${MID}/DPMO.NRLIB
+ @ echo 0 making ${OUT}/DPMO.o from ${MID}/DPMO.NRLIB
+ @ cp ${MID}/DPMO.NRLIB/code.o ${OUT}/DPMO.o
+
+@
+<<DPMO.NRLIB (NRLIB from MID)>>=
+${MID}/DPMO.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DPMO.spad
+ @ echo 0 making ${MID}/DPMO.NRLIB from ${MID}/DPMO.spad
+ @ (cd ${MID} ; echo ')co DPMO.spad' | ${INTERPSYS} )
+
+@
+<<DPMO.spad (SPAD from IN)>>=
+${MID}/DPMO.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/DPMO.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DPMO.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DPMO DirectProductModule" ${IN}/lodop.spad.pamphlet >DPMO.spad )
+
+@
+<<DPMM.o (O from NRLIB)>>=
+${OUT}/DPMM.o: ${MID}/DPMM.NRLIB
+ @ echo 0 making ${OUT}/DPMM.o from ${MID}/DPMM.NRLIB
+ @ cp ${MID}/DPMM.NRLIB/code.o ${OUT}/DPMM.o
+
+@
+<<DPMM.NRLIB (NRLIB from MID)>>=
+${MID}/DPMM.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DPMM.spad
+ @ echo 0 making ${MID}/DPMM.NRLIB from ${MID}/DPMM.spad
+ @ (cd ${MID} ; echo ')co DPMM.spad' | ${INTERPSYS} )
+
+@
+<<DPMM.spad (SPAD from IN)>>=
+${MID}/DPMM.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/DPMM.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DPMM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DPMM DirectProductMatrixModule" ${IN}/lodop.spad.pamphlet >DPMM.spad )
+
+@
+<<MLO.o (O from NRLIB)>>=
+${OUT}/MLO.o: ${MID}/MLO.NRLIB
+ @ echo 0 making ${OUT}/MLO.o from ${MID}/MLO.NRLIB
+ @ cp ${MID}/MLO.NRLIB/code.o ${OUT}/MLO.o
+
+@
+<<MLO.NRLIB (NRLIB from MID)>>=
+${MID}/MLO.NRLIB: ${MID}/MLO.spad
+ @ echo 0 making ${MID}/MLO.NRLIB from ${MID}/MLO.spad
+ @ (cd ${MID} ; echo ')co MLO.spad' | ${INTERPSYS} )
+
+@
+<<MLO.spad (SPAD from IN)>>=
+${MID}/MLO.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/MLO.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MLO.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MLO MonogenicLinearOperator" ${IN}/lodop.spad.pamphlet >MLO.spad )
+
+@
+<<NCODIV.o (O from NRLIB)>>=
+${OUT}/NCODIV.o: ${MID}/NCODIV.NRLIB
+ @ echo 0 making ${OUT}/NCODIV.o from ${MID}/NCODIV.NRLIB
+ @ cp ${MID}/NCODIV.NRLIB/code.o ${OUT}/NCODIV.o
+
+@
+<<NCODIV.NRLIB (NRLIB from MID)>>=
+${MID}/NCODIV.NRLIB: ${MID}/NCODIV.spad
+ @ echo 0 making ${MID}/NCODIV.NRLIB from ${MID}/NCODIV.spad
+ @ (cd ${MID} ; echo ')co NCODIV.spad' | ${INTERPSYS} )
+
+@
+<<NCODIV.spad (SPAD from IN)>>=
+${MID}/NCODIV.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/NCODIV.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NCODIV.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NCODIV NonCommutativeOperatorDivision" ${IN}/lodop.spad.pamphlet >NCODIV.spad )
+
+@
+<<ODR.o (O from NRLIB)>>=
+${OUT}/ODR.o: ${MID}/ODR.NRLIB
+ @ echo 0 making ${OUT}/ODR.o from ${MID}/ODR.NRLIB
+ @ cp ${MID}/ODR.NRLIB/code.o ${OUT}/ODR.o
+
+@
+<<ODR.NRLIB (NRLIB from MID)>>=
+${MID}/ODR.NRLIB: ${MID}/ODR.spad
+ @ echo 0 making ${MID}/ODR.NRLIB from ${MID}/ODR.spad
+ @ (cd ${MID} ; echo ')co ODR.spad' | ${INTERPSYS} )
+
+@
+<<ODR.spad (SPAD from IN)>>=
+${MID}/ODR.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/ODR.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ODR OrdinaryDifferentialRing" ${IN}/lodop.spad.pamphlet >ODR.spad )
+
+@
+<<OMLO.o (O from NRLIB)>>=
+${OUT}/OMLO.o: ${MID}/OMLO.NRLIB
+ @ echo 0 making ${OUT}/OMLO.o from ${MID}/OMLO.NRLIB
+ @ cp ${MID}/OMLO.NRLIB/code.o ${OUT}/OMLO.o
+
+@
+<<OMLO.NRLIB (NRLIB from MID)>>=
+${MID}/OMLO.NRLIB: ${MID}/OMLO.spad
+ @ echo 0 making ${MID}/OMLO.NRLIB from ${MID}/OMLO.spad
+ @ (cd ${MID} ; echo ')co OMLO.spad' | ${INTERPSYS} )
+
+@
+<<OMLO.spad (SPAD from IN)>>=
+${MID}/OMLO.spad: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${MID}/OMLO.spad from ${IN}/lodop.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMLO.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OMLO OppositeMonogenicLinearOperator" ${IN}/lodop.spad.pamphlet >OMLO.spad )
+
+@
+<<lodop.spad.dvi (DOC from IN)>>=
+${DOC}/lodop.spad.dvi: ${IN}/lodop.spad.pamphlet
+ @ echo 0 making ${DOC}/lodop.spad.dvi from ${IN}/lodop.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lodop.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lodop.spad ; \
+ rm -f ${DOC}/lodop.spad.pamphlet ; \
+ rm -f ${DOC}/lodop.spad.tex ; \
+ rm -f ${DOC}/lodop.spad )
+
+@
+\subsection{lodo.spad \cite{1}}
+<<lodo.spad (SPAD from IN)>>=
+${MID}/lodo.spad: ${IN}/lodo.spad.pamphlet
+ @ echo 0 making ${MID}/lodo.spad from ${IN}/lodo.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/lodo.spad.pamphlet >lodo.spad )
+
+@
+<<LODO1.o (O from NRLIB)>>=
+${OUT}/LODO1.o: ${MID}/LODO1.NRLIB
+ @ echo 0 making ${OUT}/LODO1.o from ${MID}/LODO1.NRLIB
+ @ cp ${MID}/LODO1.NRLIB/code.o ${OUT}/LODO1.o
+
+@
+<<LODO1.NRLIB (NRLIB from MID)>>=
+${MID}/LODO1.NRLIB: ${MID}/LODO1.spad
+ @ echo 0 making ${MID}/LODO1.NRLIB from ${MID}/LODO1.spad
+ @ (cd ${MID} ; echo ')co LODO1.spad' | ${INTERPSYS} )
+
+@
+<<LODO1.spad (SPAD from IN)>>=
+${MID}/LODO1.spad: ${IN}/lodo.spad.pamphlet
+ @ echo 0 making ${MID}/LODO1.spad from ${IN}/lodo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LODO1.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LODO1 LinearOrdinaryDifferentialOperator1" ${IN}/lodo.spad.pamphlet >LODO1.spad )
+
+@
+<<LODO2.o (O from NRLIB)>>=
+${OUT}/LODO2.o: ${MID}/LODO2.NRLIB
+ @ echo 0 making ${OUT}/LODO2.o from ${MID}/LODO2.NRLIB
+ @ cp ${MID}/LODO2.NRLIB/code.o ${OUT}/LODO2.o
+
+@
+<<LODO2.NRLIB (NRLIB from MID)>>=
+${MID}/LODO2.NRLIB: ${MID}/LODO2.spad
+ @ echo 0 making ${MID}/LODO2.NRLIB from ${MID}/LODO2.spad
+ @ (cd ${MID} ; echo ')co LODO2.spad' | ${INTERPSYS} )
+
+@
+<<LODO2.spad (SPAD from IN)>>=
+${MID}/LODO2.spad: ${IN}/lodo.spad.pamphlet
+ @ echo 0 making ${MID}/LODO2.spad from ${IN}/lodo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LODO2.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LODO2 LinearOrdinaryDifferentialOperator2" ${IN}/lodo.spad.pamphlet >LODO2.spad )
+
+@
+<<LODOCAT-.o (O from NRLIB)>>=
+${OUT}/LODOCAT-.o: ${MID}/LODOCAT.NRLIB
+ @ echo 0 making ${OUT}/LODOCAT-.o from ${MID}/LODOCAT-.NRLIB
+ @ cp ${MID}/LODOCAT-.NRLIB/code.o ${OUT}/LODOCAT-.o
+
+@
+<<LODOCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/LODOCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/LODOCAT.spad
+ @ echo 0 making ${MID}/LODOCAT-.NRLIB from ${MID}/LODOCAT.spad
+ @ (cd ${MID} ; echo ')co LODOCAT.spad' | ${INTERPSYS} )
+
+@
+<<LODOCAT.o (O from NRLIB)>>=
+${OUT}/LODOCAT.o: ${MID}/LODOCAT.NRLIB
+ @ echo 0 making ${OUT}/LODOCAT.o from ${MID}/LODOCAT.NRLIB
+ @ cp ${MID}/LODOCAT.NRLIB/code.o ${OUT}/LODOCAT.o
+
+@
+<<LODOCAT.NRLIB (NRLIB from MID)>>=
+${MID}/LODOCAT.NRLIB: ${MID}/LODOCAT.spad
+ @ echo 0 making ${MID}/LODOCAT.NRLIB from ${MID}/LODOCAT.spad
+ @ (cd ${MID} ; echo ')co LODOCAT.spad' | ${INTERPSYS} )
+
+@
+<<LODOCAT.spad (SPAD from IN)>>=
+${MID}/LODOCAT.spad: ${IN}/lodo.spad.pamphlet
+ @ echo 0 making ${MID}/LODOCAT.spad from ${IN}/lodo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LODOCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LODOCAT LinearOrdinaryDifferentialOperatorCategory" ${IN}/lodo.spad.pamphlet >LODOCAT.spad )
+
+@
+<<LODOOPS.o (O from NRLIB)>>=
+${OUT}/LODOOPS.o: ${MID}/LODOOPS.NRLIB
+ @ echo 0 making ${OUT}/LODOOPS.o from ${MID}/LODOOPS.NRLIB
+ @ cp ${MID}/LODOOPS.NRLIB/code.o ${OUT}/LODOOPS.o
+
+@
+<<LODOOPS.NRLIB (NRLIB from MID)>>=
+${MID}/LODOOPS.NRLIB: ${MID}/LODOOPS.spad
+ @ echo 0 making ${MID}/LODOOPS.NRLIB from ${MID}/LODOOPS.spad
+ @ (cd ${MID} ; echo ')co LODOOPS.spad' | ${INTERPSYS} )
+
+@
+<<LODOOPS.spad (SPAD from IN)>>=
+${MID}/LODOOPS.spad: ${IN}/lodo.spad.pamphlet
+ @ echo 0 making ${MID}/LODOOPS.spad from ${IN}/lodo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LODOOPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LODOOPS LinearOrdinaryDifferentialOperatorsOps" ${IN}/lodo.spad.pamphlet >LODOOPS.spad )
+
+@
+<<lodo.spad.dvi (DOC from IN)>>=
+${DOC}/lodo.spad.dvi: ${IN}/lodo.spad.pamphlet
+ @ echo 0 making ${DOC}/lodo.spad.dvi from ${IN}/lodo.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/lodo.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} lodo.spad ; \
+ rm -f ${DOC}/lodo.spad.pamphlet ; \
+ rm -f ${DOC}/lodo.spad.tex ; \
+ rm -f ${DOC}/lodo.spad )
+
+@
+\subsection{manip.spad \cite{1}}
+<<manip.spad (SPAD from IN)>>=
+${MID}/manip.spad: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${MID}/manip.spad from ${IN}/manip.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/manip.spad.pamphlet >manip.spad )
+
+@
+<<ALGMANIP.o (O from NRLIB)>>=
+${OUT}/ALGMANIP.o: ${MID}/ALGMANIP.NRLIB
+ @ echo 0 making ${OUT}/ALGMANIP.o from ${MID}/ALGMANIP.NRLIB
+ @ cp ${MID}/ALGMANIP.NRLIB/code.o ${OUT}/ALGMANIP.o
+
+@
+<<ALGMANIP.NRLIB (NRLIB from MID)>>=
+${MID}/ALGMANIP.NRLIB: ${MID}/ALGMANIP.spad
+ @ echo 0 making ${MID}/ALGMANIP.NRLIB from ${MID}/ALGMANIP.spad
+ @ (cd ${MID} ; echo ')co ALGMANIP.spad' | ${INTERPSYS} )
+
+@
+<<ALGMANIP.spad (SPAD from IN)>>=
+${MID}/ALGMANIP.spad: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${MID}/ALGMANIP.spad from ${IN}/manip.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGMANIP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ALGMANIP AlgebraicManipulations" ${IN}/manip.spad.pamphlet >ALGMANIP.spad )
+
+@
+<<FACTFUNC.o (O from NRLIB)>>=
+${OUT}/FACTFUNC.o: ${MID}/FACTFUNC.NRLIB
+ @ echo 0 making ${OUT}/FACTFUNC.o from ${MID}/FACTFUNC.NRLIB
+ @ cp ${MID}/FACTFUNC.NRLIB/code.o ${OUT}/FACTFUNC.o
+
+@
+<<FACTFUNC.NRLIB (NRLIB from MID)>>=
+${MID}/FACTFUNC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FACTFUNC.spad
+ @ echo 0 making ${MID}/FACTFUNC.NRLIB from ${MID}/FACTFUNC.spad
+ @ (cd ${MID} ; echo ')co FACTFUNC.spad' | ${INTERPSYS} )
+
+@
+<<FACTFUNC.spad (SPAD from IN)>>=
+${MID}/FACTFUNC.spad: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${MID}/FACTFUNC.spad from ${IN}/manip.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FACTFUNC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FACTFUNC FactoredFunctions" ${IN}/manip.spad.pamphlet >FACTFUNC.spad )
+
+@
+<<POLYROOT.o (O from NRLIB)>>=
+${OUT}/POLYROOT.o: ${MID}/POLYROOT.NRLIB
+ @ echo 0 making ${OUT}/POLYROOT.o from ${MID}/POLYROOT.NRLIB
+ @ cp ${MID}/POLYROOT.NRLIB/code.o ${OUT}/POLYROOT.o
+
+@
+<<POLYROOT.NRLIB (NRLIB from MID)>>=
+${MID}/POLYROOT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLYROOT.spad
+ @ echo 0 making ${MID}/POLYROOT.NRLIB from ${MID}/POLYROOT.spad
+ @ (cd ${MID} ; echo ')co POLYROOT.spad' | ${INTERPSYS} )
+
+@
+<<POLYROOT.spad (SPAD from IN)>>=
+${MID}/POLYROOT.spad: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${MID}/POLYROOT.spad from ${IN}/manip.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLYROOT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLYROOT PolynomialRoots" ${IN}/manip.spad.pamphlet >POLYROOT.spad )
+
+@
+<<SIMPAN.o (O from NRLIB)>>=
+${OUT}/SIMPAN.o: ${MID}/SIMPAN.NRLIB
+ @ echo 0 making ${OUT}/SIMPAN.o from ${MID}/SIMPAN.NRLIB
+ @ cp ${MID}/SIMPAN.NRLIB/code.o ${OUT}/SIMPAN.o
+
+@
+<<SIMPAN.NRLIB (NRLIB from MID)>>=
+${MID}/SIMPAN.NRLIB: ${MID}/SIMPAN.spad
+ @ echo 0 making ${MID}/SIMPAN.NRLIB from ${MID}/SIMPAN.spad
+ @ (cd ${MID} ; echo ')co SIMPAN.spad' | ${INTERPSYS} )
+
+@
+<<SIMPAN.spad (SPAD from IN)>>=
+${MID}/SIMPAN.spad: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${MID}/SIMPAN.spad from ${IN}/manip.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SIMPAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SIMPAN SimplifyAlgebraicNumberConvertPackage" ${IN}/manip.spad.pamphlet >SIMPAN.spad )
+
+@
+<<TRMANIP.o (O from NRLIB)>>=
+${OUT}/TRMANIP.o: ${MID}/TRMANIP.NRLIB
+ @ echo 0 making ${OUT}/TRMANIP.o from ${MID}/TRMANIP.NRLIB
+ @ cp ${MID}/TRMANIP.NRLIB/code.o ${OUT}/TRMANIP.o
+
+@
+<<TRMANIP.NRLIB (NRLIB from MID)>>=
+${MID}/TRMANIP.NRLIB: ${MID}/TRMANIP.spad
+ @ echo 0 making ${MID}/TRMANIP.NRLIB from ${MID}/TRMANIP.spad
+ @ (cd ${MID} ; echo ')co TRMANIP.spad' | ${INTERPSYS} )
+
+@
+<<TRMANIP.spad (SPAD from IN)>>=
+${MID}/TRMANIP.spad: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${MID}/TRMANIP.spad from ${IN}/manip.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TRMANIP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TRMANIP TranscendentalManipulations" ${IN}/manip.spad.pamphlet >TRMANIP.spad )
+
+@
+<<manip.spad.dvi (DOC from IN)>>=
+${DOC}/manip.spad.dvi: ${IN}/manip.spad.pamphlet
+ @ echo 0 making ${DOC}/manip.spad.dvi from ${IN}/manip.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/manip.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} manip.spad ; \
+ rm -f ${DOC}/manip.spad.pamphlet ; \
+ rm -f ${DOC}/manip.spad.tex ; \
+ rm -f ${DOC}/manip.spad )
+
+@
+\subsection{mappkg.spad \cite{1}}
+<<mappkg.spad (SPAD from IN)>>=
+${MID}/mappkg.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/mappkg.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mappkg.spad.pamphlet >mappkg.spad )
+
+@
+<<MAPHACK1.o (O from NRLIB)>>=
+${OUT}/MAPHACK1.o: ${MID}/MAPHACK1.NRLIB
+ @ echo 0 making ${OUT}/MAPHACK1.o from ${MID}/MAPHACK1.NRLIB
+ @ cp ${MID}/MAPHACK1.NRLIB/code.o ${OUT}/MAPHACK1.o
+
+@
+<<MAPHACK1.NRLIB (NRLIB from MID)>>=
+${MID}/MAPHACK1.NRLIB: ${MID}/MAPHACK1.spad
+ @ echo 0 making ${MID}/MAPHACK1.NRLIB from ${MID}/MAPHACK1.spad
+ @ (cd ${MID} ; echo ')co MAPHACK1.spad' | ${INTERPSYS} )
+
+@
+<<MAPHACK1.spad (SPAD from IN)>>=
+${MID}/MAPHACK1.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/MAPHACK1.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAPHACK1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MAPHACK1 MappingPackageInternalHacks1" ${IN}/mappkg.spad.pamphlet >MAPHACK1.spad )
+
+@
+<<MAPHACK2.o (O from NRLIB)>>=
+${OUT}/MAPHACK2.o: ${MID}/MAPHACK2.NRLIB
+ @ echo 0 making ${OUT}/MAPHACK2.o from ${MID}/MAPHACK2.NRLIB
+ @ cp ${MID}/MAPHACK2.NRLIB/code.o ${OUT}/MAPHACK2.o
+
+@
+<<MAPHACK2.NRLIB (NRLIB from MID)>>=
+${MID}/MAPHACK2.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/MAPHACK2.spad
+ @ echo 0 making ${MID}/MAPHACK2.NRLIB from ${MID}/MAPHACK2.spad
+ @ (cd ${MID} ; echo ')co MAPHACK2.spad' | ${INTERPSYS} )
+
+@
+<<MAPHACK2.spad (SPAD from IN)>>=
+${MID}/MAPHACK2.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/MAPHACK2.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAPHACK2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MAPHACK2 MappingPackageInternalHacks2" ${IN}/mappkg.spad.pamphlet >MAPHACK2.spad )
+
+@
+<<MAPHACK3.o (O from NRLIB)>>=
+${OUT}/MAPHACK3.o: ${MID}/MAPHACK3.NRLIB
+ @ echo 0 making ${OUT}/MAPHACK3.o from ${MID}/MAPHACK3.NRLIB
+ @ cp ${MID}/MAPHACK3.NRLIB/code.o ${OUT}/MAPHACK3.o
+
+@
+<<MAPHACK3.NRLIB (NRLIB from MID)>>=
+${MID}/MAPHACK3.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/MAPHACK3.spad
+ @ echo 0 making ${MID}/MAPHACK3.NRLIB from ${MID}/MAPHACK3.spad
+ @ (cd ${MID} ; echo ')co MAPHACK3.spad' | ${INTERPSYS} )
+
+@
+<<MAPHACK3.spad (SPAD from IN)>>=
+${MID}/MAPHACK3.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/MAPHACK3.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAPHACK3.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MAPHACK3 MappingPackageInternalHacks3" ${IN}/mappkg.spad.pamphlet >MAPHACK3.spad )
+
+@
+<<MAPPKG1.o (O from NRLIB)>>=
+${OUT}/MAPPKG1.o: ${MID}/MAPPKG1.NRLIB
+ @ echo 0 making ${OUT}/MAPPKG1.o from ${MID}/MAPPKG1.NRLIB
+ @ cp ${MID}/MAPPKG1.NRLIB/code.o ${OUT}/MAPPKG1.o
+
+@
+<<MAPPKG1.NRLIB (NRLIB from MID)>>=
+${MID}/MAPPKG1.NRLIB: ${MID}/MAPPKG1.spad
+ @ echo 0 making ${MID}/MAPPKG1.NRLIB from ${MID}/MAPPKG1.spad
+ @ (cd ${MID} ; echo ')co MAPPKG1.spad' | ${INTERPSYS} )
+
+@
+<<MAPPKG1.spad (SPAD from IN)>>=
+${MID}/MAPPKG1.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/MAPPKG1.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAPPKG1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MAPPKG1 MappingPackage1" ${IN}/mappkg.spad.pamphlet >MAPPKG1.spad )
+
+@
+<<MAPPKG2.o (O from NRLIB)>>=
+${OUT}/MAPPKG2.o: ${MID}/MAPPKG2.NRLIB
+ @ echo 0 making ${OUT}/MAPPKG2.o from ${MID}/MAPPKG2.NRLIB
+ @ cp ${MID}/MAPPKG2.NRLIB/code.o ${OUT}/MAPPKG2.o
+
+@
+<<MAPPKG2.NRLIB (NRLIB from MID)>>=
+${MID}/MAPPKG2.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/MAPPKG2.spad
+ @ echo 0 making ${MID}/MAPPKG2.NRLIB from ${MID}/MAPPKG2.spad
+ @ (cd ${MID} ; echo ')co MAPPKG2.spad' | ${INTERPSYS} )
+
+@
+<<MAPPKG2.spad (SPAD from IN)>>=
+${MID}/MAPPKG2.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/MAPPKG2.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAPPKG2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MAPPKG2 MappingPackage2" ${IN}/mappkg.spad.pamphlet >MAPPKG2.spad )
+
+@
+<<MAPPKG3.o (O from NRLIB)>>=
+${OUT}/MAPPKG3.o: ${MID}/MAPPKG3.NRLIB
+ @ echo 0 making ${OUT}/MAPPKG3.o from ${MID}/MAPPKG3.NRLIB
+ @ cp ${MID}/MAPPKG3.NRLIB/code.o ${OUT}/MAPPKG3.o
+
+@
+<<MAPPKG3.NRLIB (NRLIB from MID)>>=
+${MID}/MAPPKG3.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/MAPPKG3.spad
+ @ echo 0 making ${MID}/MAPPKG3.NRLIB from ${MID}/MAPPKG3.spad
+ @ (cd ${MID} ; echo ')co MAPPKG3.spad' | ${INTERPSYS} )
+
+@
+<<MAPPKG3.spad (SPAD from IN)>>=
+${MID}/MAPPKG3.spad: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${MID}/MAPPKG3.spad from ${IN}/mappkg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAPPKG3.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MAPPKG3 MappingPackage3" ${IN}/mappkg.spad.pamphlet >MAPPKG3.spad )
+
+@
+<<mappkg.spad.dvi (DOC from IN)>>=
+${DOC}/mappkg.spad.dvi: ${IN}/mappkg.spad.pamphlet
+ @ echo 0 making ${DOC}/mappkg.spad.dvi from ${IN}/mappkg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mappkg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mappkg.spad ; \
+ rm -f ${DOC}/mappkg.spad.pamphlet ; \
+ rm -f ${DOC}/mappkg.spad.tex ; \
+ rm -f ${DOC}/mappkg.spad )
+
+@
+\subsection{matcat.spad \cite{1}}
+<<matcat.spad (SPAD from IN)>>=
+${MID}/matcat.spad: ${IN}/matcat.spad.pamphlet
+ @ echo 0 making ${MID}/matcat.spad from ${IN}/matcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/matcat.spad.pamphlet >matcat.spad )
+
+@
+<<MATCAT-.o (O from NRLIB)>>=
+${OUT}/MATCAT-.o: ${MID}/MATCAT.NRLIB
+ @ echo 0 making ${OUT}/MATCAT-.o from ${MID}/MATCAT-.NRLIB
+ @ cp ${MID}/MATCAT-.NRLIB/code.o ${OUT}/MATCAT-.o
+
+@
+<<MATCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/MATCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/MATCAT.spad
+ @ echo 0 making ${MID}/MATCAT-.NRLIB from ${MID}/MATCAT.spad
+ @ (cd ${MID} ; echo ')co MATCAT.spad' | ${INTERPSYS} )
+
+@
+<<MATCAT.o (O from NRLIB)>>=
+${OUT}/MATCAT.o: ${MID}/MATCAT.NRLIB
+ @ echo 0 making ${OUT}/MATCAT.o from ${MID}/MATCAT.NRLIB
+ @ cp ${MID}/MATCAT.NRLIB/code.o ${OUT}/MATCAT.o
+
+@
+<<MATCAT.NRLIB (NRLIB from MID)>>=
+${MID}/MATCAT.NRLIB: ${MID}/MATCAT.spad
+ @ echo 0 making ${MID}/MATCAT.NRLIB from ${MID}/MATCAT.spad
+ @ (cd ${MID} ; echo ')co MATCAT.spad' | ${INTERPSYS} )
+
+@
+<<MATCAT.spad (SPAD from IN)>>=
+${MID}/MATCAT.spad: ${IN}/matcat.spad.pamphlet
+ @ echo 0 making ${MID}/MATCAT.spad from ${IN}/matcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MATCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MATCAT MatrixCategory" ${IN}/matcat.spad.pamphlet >MATCAT.spad )
+
+@
+<<RMATCAT-.o (O from NRLIB)>>=
+${OUT}/RMATCAT-.o: ${MID}/RMATCAT.NRLIB
+ @ echo 0 making ${OUT}/RMATCAT-.o from ${MID}/RMATCAT-.NRLIB
+ @ cp ${MID}/RMATCAT-.NRLIB/code.o ${OUT}/RMATCAT-.o
+
+@
+<<RMATCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/RMATCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/RMATCAT.spad
+ @ echo 0 making ${MID}/RMATCAT-.NRLIB from ${MID}/RMATCAT.spad
+ @ (cd ${MID} ; echo ')co RMATCAT.spad' | ${INTERPSYS} )
+
+@
+<<RMATCAT.o (O from NRLIB)>>=
+${OUT}/RMATCAT.o: ${MID}/RMATCAT.NRLIB
+ @ echo 0 making ${OUT}/RMATCAT.o from ${MID}/RMATCAT.NRLIB
+ @ cp ${MID}/RMATCAT.NRLIB/code.o ${OUT}/RMATCAT.o
+
+@
+<<RMATCAT.NRLIB (NRLIB from MID)>>=
+${MID}/RMATCAT.NRLIB: ${MID}/RMATCAT.spad
+ @ echo 0 making ${MID}/RMATCAT.NRLIB from ${MID}/RMATCAT.spad
+ @ (cd ${MID} ; echo ')co RMATCAT.spad' | ${INTERPSYS} )
+
+@
+<<RMATCAT.spad (SPAD from IN)>>=
+${MID}/RMATCAT.spad: ${IN}/matcat.spad.pamphlet
+ @ echo 0 making ${MID}/RMATCAT.spad from ${IN}/matcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RMATCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RMATCAT RectangularMatrixCategory" ${IN}/matcat.spad.pamphlet >RMATCAT.spad )
+
+@
+<<SMATCAT-.o (O from NRLIB)>>=
+${OUT}/SMATCAT-.o: ${MID}/SMATCAT.NRLIB
+ @ echo 0 making ${OUT}/SMATCAT-.o from ${MID}/SMATCAT-.NRLIB
+ @ cp ${MID}/SMATCAT-.NRLIB/code.o ${OUT}/SMATCAT-.o
+
+@
+<<SMATCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/SMATCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/SMATCAT.spad
+ @ echo 0 making ${MID}/SMATCAT-.NRLIB from ${MID}/SMATCAT.spad
+ @ (cd ${MID} ; echo ')co SMATCAT.spad' | ${INTERPSYS} )
+
+@
+<<SMATCAT.o (O from NRLIB)>>=
+${OUT}/SMATCAT.o: ${MID}/SMATCAT.NRLIB
+ @ echo 0 making ${OUT}/SMATCAT.o from ${MID}/SMATCAT.NRLIB
+ @ cp ${MID}/SMATCAT.NRLIB/code.o ${OUT}/SMATCAT.o
+
+@
+<<SMATCAT.NRLIB (NRLIB from MID)>>=
+${MID}/SMATCAT.NRLIB: ${MID}/SMATCAT.spad
+ @ echo 0 making ${MID}/SMATCAT.NRLIB from ${MID}/SMATCAT.spad
+ @ (cd ${MID} ; echo ')co SMATCAT.spad' | ${INTERPSYS} )
+
+@
+<<SMATCAT.spad (SPAD from IN)>>=
+${MID}/SMATCAT.spad: ${IN}/matcat.spad.pamphlet
+ @ echo 0 making ${MID}/SMATCAT.spad from ${IN}/matcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SMATCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SMATCAT SquareMatrixCategory" ${IN}/matcat.spad.pamphlet >SMATCAT.spad )
+
+@
+<<matcat.spad.dvi (DOC from IN)>>=
+${DOC}/matcat.spad.dvi: ${IN}/matcat.spad.pamphlet
+ @ echo 0 making ${DOC}/matcat.spad.dvi from ${IN}/matcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/matcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} matcat.spad ; \
+ rm -f ${DOC}/matcat.spad.pamphlet ; \
+ rm -f ${DOC}/matcat.spad.tex ; \
+ rm -f ${DOC}/matcat.spad )
+
+@
+\subsection{matfuns.spad \cite{1}}
+<<matfuns.spad (SPAD from IN)>>=
+${MID}/matfuns.spad: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${MID}/matfuns.spad from ${IN}/matfuns.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/matfuns.spad.pamphlet >matfuns.spad )
+
+@
+<<IMATLIN.o (O from NRLIB)>>=
+${OUT}/IMATLIN.o: ${MID}/IMATLIN.NRLIB
+ @ echo 0 making ${OUT}/IMATLIN.o from ${MID}/IMATLIN.NRLIB
+ @ cp ${MID}/IMATLIN.NRLIB/code.o ${OUT}/IMATLIN.o
+
+@
+<<IMATLIN.NRLIB (NRLIB from MID)>>=
+${MID}/IMATLIN.NRLIB: ${MID}/IMATLIN.spad
+ @ echo 0 making ${MID}/IMATLIN.NRLIB from ${MID}/IMATLIN.spad
+ @ (cd ${MID} ; echo ')co IMATLIN.spad' | ${INTERPSYS} )
+
+@
+<<IMATLIN.spad (SPAD from IN)>>=
+${MID}/IMATLIN.spad: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${MID}/IMATLIN.spad from ${IN}/matfuns.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IMATLIN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IMATLIN InnerMatrixLinearAlgebraFunctions" ${IN}/matfuns.spad.pamphlet >IMATLIN.spad )
+
+@
+<<IMATQF.o (O from NRLIB)>>=
+${OUT}/IMATQF.o: ${MID}/IMATQF.NRLIB
+ @ echo 0 making ${OUT}/IMATQF.o from ${MID}/IMATQF.NRLIB
+ @ cp ${MID}/IMATQF.NRLIB/code.o ${OUT}/IMATQF.o
+
+@
+<<IMATQF.NRLIB (NRLIB from MID)>>=
+${MID}/IMATQF.NRLIB: ${MID}/IMATQF.spad
+ @ echo 0 making ${MID}/IMATQF.NRLIB from ${MID}/IMATQF.spad
+ @ (cd ${MID} ; echo ')co IMATQF.spad' | ${INTERPSYS} )
+
+@
+<<IMATQF.spad (SPAD from IN)>>=
+${MID}/IMATQF.spad: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${MID}/IMATQF.spad from ${IN}/matfuns.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IMATQF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IMATQF InnerMatrixQuotientFieldFunctions" ${IN}/matfuns.spad.pamphlet >IMATQF.spad )
+
+@
+<<MATCAT2.o (O from NRLIB)>>=
+${OUT}/MATCAT2.o: ${MID}/MATCAT2.NRLIB
+ @ echo 0 making ${OUT}/MATCAT2.o from ${MID}/MATCAT2.NRLIB
+ @ cp ${MID}/MATCAT2.NRLIB/code.o ${OUT}/MATCAT2.o
+
+@
+<<MATCAT2.NRLIB (NRLIB from MID)>>=
+${MID}/MATCAT2.NRLIB: ${MID}/MATCAT2.spad
+ @ echo 0 making ${MID}/MATCAT2.NRLIB from ${MID}/MATCAT2.spad
+ @ (cd ${MID} ; echo ')co MATCAT2.spad' | ${INTERPSYS} )
+
+@
+<<MATCAT2.spad (SPAD from IN)>>=
+${MID}/MATCAT2.spad: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${MID}/MATCAT2.spad from ${IN}/matfuns.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MATCAT2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MATCAT2 MatrixCategoryFunctions2" ${IN}/matfuns.spad.pamphlet >MATCAT2.spad )
+
+@
+<<MATLIN.o (O from NRLIB)>>=
+${OUT}/MATLIN.o: ${MID}/MATLIN.NRLIB
+ @ echo 0 making ${OUT}/MATLIN.o from ${MID}/MATLIN.NRLIB
+ @ cp ${MID}/MATLIN.NRLIB/code.o ${OUT}/MATLIN.o
+
+@
+<<MATLIN.NRLIB (NRLIB from MID)>>=
+${MID}/MATLIN.NRLIB: ${MID}/MATLIN.spad
+ @ echo 0 making ${MID}/MATLIN.NRLIB from ${MID}/MATLIN.spad
+ @ (cd ${MID} ; echo ')co MATLIN.spad' | ${INTERPSYS} )
+
+@
+<<MATLIN.spad (SPAD from IN)>>=
+${MID}/MATLIN.spad: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${MID}/MATLIN.spad from ${IN}/matfuns.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MATLIN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MATLIN MatrixLinearAlgebraFunctions" ${IN}/matfuns.spad.pamphlet >MATLIN.spad )
+
+@
+<<RMCAT2.o (O from NRLIB)>>=
+${OUT}/RMCAT2.o: ${MID}/RMCAT2.NRLIB
+ @ echo 0 making ${OUT}/RMCAT2.o from ${MID}/RMCAT2.NRLIB
+ @ cp ${MID}/RMCAT2.NRLIB/code.o ${OUT}/RMCAT2.o
+
+@
+<<RMCAT2.NRLIB (NRLIB from MID)>>=
+${MID}/RMCAT2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/RMCAT2.spad
+ @ echo 0 making ${MID}/RMCAT2.NRLIB from ${MID}/RMCAT2.spad
+ @ (cd ${MID} ; echo ')co RMCAT2.spad' | ${INTERPSYS} )
+
+@
+<<RMCAT2.spad (SPAD from IN)>>=
+${MID}/RMCAT2.spad: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${MID}/RMCAT2.spad from ${IN}/matfuns.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RMCAT2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RMCAT2 RectangularMatrixCategoryFunctions2" ${IN}/matfuns.spad.pamphlet >RMCAT2.spad )
+
+@
+<<matfuns.spad.dvi (DOC from IN)>>=
+${DOC}/matfuns.spad.dvi: ${IN}/matfuns.spad.pamphlet
+ @ echo 0 making ${DOC}/matfuns.spad.dvi from ${IN}/matfuns.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/matfuns.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} matfuns.spad ; \
+ rm -f ${DOC}/matfuns.spad.pamphlet ; \
+ rm -f ${DOC}/matfuns.spad.tex ; \
+ rm -f ${DOC}/matfuns.spad )
+
+@
+\subsection{matrix.spad \cite{1}}
+<<matrix.spad (SPAD from IN)>>=
+${MID}/matrix.spad: ${IN}/matrix.spad.pamphlet
+ @ echo 0 making ${MID}/matrix.spad from ${IN}/matrix.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/matrix.spad.pamphlet >matrix.spad )
+
+@
+<<IMATRIX.o (O from NRLIB)>>=
+${OUT}/IMATRIX.o: ${MID}/IMATRIX.NRLIB
+ @ echo 0 making ${OUT}/IMATRIX.o from ${MID}/IMATRIX.NRLIB
+ @ cp ${MID}/IMATRIX.NRLIB/code.o ${OUT}/IMATRIX.o
+
+@
+<<IMATRIX.NRLIB (NRLIB from MID)>>=
+${MID}/IMATRIX.NRLIB: ${MID}/IMATRIX.spad
+ @ echo 0 making ${MID}/IMATRIX.NRLIB from ${MID}/IMATRIX.spad
+ @ (cd ${MID} ; echo ')co IMATRIX.spad' | ${INTERPSYS} )
+
+@
+<<IMATRIX.spad (SPAD from IN)>>=
+${MID}/IMATRIX.spad: ${IN}/matrix.spad.pamphlet
+ @ echo 0 making ${MID}/IMATRIX.spad from ${IN}/matrix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IMATRIX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IMATRIX IndexedMatrix" ${IN}/matrix.spad.pamphlet >IMATRIX.spad )
+
+@
+<<MATRIX.o (O from NRLIB)>>=
+${OUT}/MATRIX.o: ${MID}/MATRIX.NRLIB
+ @ echo 0 making ${OUT}/MATRIX.o from ${MID}/MATRIX.NRLIB
+ @ cp ${MID}/MATRIX.NRLIB/code.o ${OUT}/MATRIX.o
+
+@
+<<MATRIX.NRLIB (NRLIB from MID)>>=
+${MID}/MATRIX.NRLIB: ${MID}/MATRIX.spad
+ @ echo 0 making ${MID}/MATRIX.NRLIB from ${MID}/MATRIX.spad
+ @ (cd ${MID} ; echo ')co MATRIX.spad' | ${INTERPSYS} )
+
+@
+<<MATRIX.spad (SPAD from IN)>>=
+${MID}/MATRIX.spad: ${IN}/matrix.spad.pamphlet
+ @ echo 0 making ${MID}/MATRIX.spad from ${IN}/matrix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MATRIX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MATRIX Matrix" ${IN}/matrix.spad.pamphlet >MATRIX.spad )
+
+@
+<<RMATRIX.o (O from NRLIB)>>=
+${OUT}/RMATRIX.o: ${MID}/RMATRIX.NRLIB
+ @ echo 0 making ${OUT}/RMATRIX.o from ${MID}/RMATRIX.NRLIB
+ @ cp ${MID}/RMATRIX.NRLIB/code.o ${OUT}/RMATRIX.o
+
+@
+<<RMATRIX.NRLIB (NRLIB from MID)>>=
+${MID}/RMATRIX.NRLIB: ${MID}/RMATRIX.spad
+ @ echo 0 making ${MID}/RMATRIX.NRLIB from ${MID}/RMATRIX.spad
+ @ (cd ${MID} ; echo ')co RMATRIX.spad' | ${INTERPSYS} )
+
+@
+<<RMATRIX.spad (SPAD from IN)>>=
+${MID}/RMATRIX.spad: ${IN}/matrix.spad.pamphlet
+ @ echo 0 making ${MID}/RMATRIX.spad from ${IN}/matrix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RMATRIX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RMATRIX RectangularMatrix" ${IN}/matrix.spad.pamphlet >RMATRIX.spad )
+
+@
+<<SQMATRIX.o (O from NRLIB)>>=
+${OUT}/SQMATRIX.o: ${MID}/SQMATRIX.NRLIB
+ @ echo 0 making ${OUT}/SQMATRIX.o from ${MID}/SQMATRIX.NRLIB
+ @ cp ${MID}/SQMATRIX.NRLIB/code.o ${OUT}/SQMATRIX.o
+
+@
+<<SQMATRIX.NRLIB (NRLIB from MID)>>=
+${MID}/SQMATRIX.NRLIB: ${MID}/SQMATRIX.spad
+ @ echo 0 making ${MID}/SQMATRIX.NRLIB from ${MID}/SQMATRIX.spad
+ @ (cd ${MID} ; echo ')co SQMATRIX.spad' | ${INTERPSYS} )
+
+@
+<<SQMATRIX.spad (SPAD from IN)>>=
+${MID}/SQMATRIX.spad: ${IN}/matrix.spad.pamphlet
+ @ echo 0 making ${MID}/SQMATRIX.spad from ${IN}/matrix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SQMATRIX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SQMATRIX SquareMatrix" ${IN}/matrix.spad.pamphlet >SQMATRIX.spad )
+
+@
+<<matrix.spad.dvi (DOC from IN)>>=
+${DOC}/matrix.spad.dvi: ${IN}/matrix.spad.pamphlet
+ @ echo 0 making ${DOC}/matrix.spad.dvi from ${IN}/matrix.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/matrix.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} matrix.spad ; \
+ rm -f ${DOC}/matrix.spad.pamphlet ; \
+ rm -f ${DOC}/matrix.spad.tex ; \
+ rm -f ${DOC}/matrix.spad )
+
+@
+\subsection{matstor.spad \cite{1}}
+<<matstor.spad (SPAD from IN)>>=
+${MID}/matstor.spad: ${IN}/matstor.spad.pamphlet
+ @ echo 0 making ${MID}/matstor.spad from ${IN}/matstor.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/matstor.spad.pamphlet >matstor.spad )
+
+@
+<<MATSTOR.o (O from NRLIB)>>=
+${OUT}/MATSTOR.o: ${MID}/MATSTOR.NRLIB
+ @ echo 0 making ${OUT}/MATSTOR.o from ${MID}/MATSTOR.NRLIB
+ @ cp ${MID}/MATSTOR.NRLIB/code.o ${OUT}/MATSTOR.o
+
+@
+<<MATSTOR.NRLIB (NRLIB from MID)>>=
+${MID}/MATSTOR.NRLIB: ${MID}/MATSTOR.spad
+ @ echo 0 making ${MID}/MATSTOR.NRLIB from ${MID}/MATSTOR.spad
+ @ (cd ${MID} ; echo ')co MATSTOR.spad' | ${INTERPSYS} )
+
+@
+<<MATSTOR.spad (SPAD from IN)>>=
+${MID}/MATSTOR.spad: ${IN}/matstor.spad.pamphlet
+ @ echo 0 making ${MID}/MATSTOR.spad from ${IN}/matstor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MATSTOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MATSTOR StorageEfficientMatrixOperations" ${IN}/matstor.spad.pamphlet >MATSTOR.spad )
+
+@
+<<matstor.spad.dvi (DOC from IN)>>=
+${DOC}/matstor.spad.dvi: ${IN}/matstor.spad.pamphlet
+ @ echo 0 making ${DOC}/matstor.spad.dvi from ${IN}/matstor.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/matstor.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} matstor.spad ; \
+ rm -f ${DOC}/matstor.spad.pamphlet ; \
+ rm -f ${DOC}/matstor.spad.tex ; \
+ rm -f ${DOC}/matstor.spad )
+
+@
+\subsection{mesh.spad \cite{1}}
+<<mesh.spad (SPAD from IN)>>=
+${MID}/mesh.spad: ${IN}/mesh.spad.pamphlet
+ @ echo 0 making ${MID}/mesh.spad from ${IN}/mesh.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mesh.spad.pamphlet >mesh.spad )
+
+@
+<<MESH.o (O from NRLIB)>>=
+${OUT}/MESH.o: ${MID}/MESH.NRLIB
+ @ echo 0 making ${OUT}/MESH.o from ${MID}/MESH.NRLIB
+ @ cp ${MID}/MESH.NRLIB/code.o ${OUT}/MESH.o
+
+@
+<<MESH.NRLIB (NRLIB from MID)>>=
+${MID}/MESH.NRLIB: ${MID}/MESH.spad
+ @ echo 0 making ${MID}/MESH.NRLIB from ${MID}/MESH.spad
+ @ (cd ${MID} ; echo ')co MESH.spad' | ${INTERPSYS} )
+
+@
+<<MESH.spad (SPAD from IN)>>=
+${MID}/MESH.spad: ${IN}/mesh.spad.pamphlet
+ @ echo 0 making ${MID}/MESH.spad from ${IN}/mesh.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MESH.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MESH MeshCreationRoutinesForThreeDimensions" ${IN}/mesh.spad.pamphlet >MESH.spad )
+
+@
+<<mesh.spad.dvi (DOC from IN)>>=
+${DOC}/mesh.spad.dvi: ${IN}/mesh.spad.pamphlet
+ @ echo 0 making ${DOC}/mesh.spad.dvi from ${IN}/mesh.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mesh.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mesh.spad ; \
+ rm -f ${DOC}/mesh.spad.pamphlet ; \
+ rm -f ${DOC}/mesh.spad.tex ; \
+ rm -f ${DOC}/mesh.spad )
+
+@
+\subsection{mfinfact.spad \cite{1}}
+<<mfinfact.spad (SPAD from IN)>>=
+${MID}/mfinfact.spad: ${IN}/mfinfact.spad.pamphlet
+ @ echo 0 making ${MID}/mfinfact.spad from ${IN}/mfinfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mfinfact.spad.pamphlet >mfinfact.spad )
+
+@
+<<MFINFACT.o (O from NRLIB)>>=
+${OUT}/MFINFACT.o: ${MID}/MFINFACT.NRLIB
+ @ echo 0 making ${OUT}/MFINFACT.o from ${MID}/MFINFACT.NRLIB
+ @ cp ${MID}/MFINFACT.NRLIB/code.o ${OUT}/MFINFACT.o
+
+@
+<<MFINFACT.NRLIB (NRLIB from MID)>>=
+${MID}/MFINFACT.NRLIB: ${MID}/MFINFACT.spad
+ @ echo 0 making ${MID}/MFINFACT.NRLIB from ${MID}/MFINFACT.spad
+ @ (cd ${MID} ; echo ')co MFINFACT.spad' | ${INTERPSYS} )
+
+@
+<<MFINFACT.spad (SPAD from IN)>>=
+${MID}/MFINFACT.spad: ${IN}/mfinfact.spad.pamphlet
+ @ echo 0 making ${MID}/MFINFACT.spad from ${IN}/mfinfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MFINFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MFINFACT MultFiniteFactorize" ${IN}/mfinfact.spad.pamphlet >MFINFACT.spad )
+
+@
+<<mfinfact.spad.dvi (DOC from IN)>>=
+${DOC}/mfinfact.spad.dvi: ${IN}/mfinfact.spad.pamphlet
+ @ echo 0 making ${DOC}/mfinfact.spad.dvi from ${IN}/mfinfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mfinfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mfinfact.spad ; \
+ rm -f ${DOC}/mfinfact.spad.pamphlet ; \
+ rm -f ${DOC}/mfinfact.spad.tex ; \
+ rm -f ${DOC}/mfinfact.spad )
+
+@
+\subsection{misc.spad \cite{1}}
+<<misc.spad (SPAD from IN)>>=
+${MID}/misc.spad: ${IN}/misc.spad.pamphlet
+ @ echo 0 making ${MID}/misc.spad from ${IN}/misc.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/misc.spad.pamphlet >misc.spad )
+
+@
+<<SAOS.o (O from NRLIB)>>=
+${OUT}/SAOS.o: ${MID}/SAOS.NRLIB
+ @ echo 0 making ${OUT}/SAOS.o from ${MID}/SAOS.NRLIB
+ @ cp ${MID}/SAOS.NRLIB/code.o ${OUT}/SAOS.o
+
+@
+<<SAOS.NRLIB (NRLIB from MID)>>=
+${MID}/SAOS.NRLIB: ${MID}/SAOS.spad
+ @ echo 0 making ${MID}/SAOS.NRLIB from ${MID}/SAOS.spad
+ @ (cd ${MID} ; echo ')co SAOS.spad' | ${INTERPSYS} )
+
+@
+<<SAOS.spad (SPAD from IN)>>=
+${MID}/SAOS.spad: ${IN}/misc.spad.pamphlet
+ @ echo 0 making ${MID}/SAOS.spad from ${IN}/misc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SAOS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SAOS SingletonAsOrderedSet" ${IN}/misc.spad.pamphlet >SAOS.spad )
+
+@
+<<misc.spad.dvi (DOC from IN)>>=
+${DOC}/misc.spad.dvi: ${IN}/misc.spad.pamphlet
+ @ echo 0 making ${DOC}/misc.spad.dvi from ${IN}/misc.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/misc.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} misc.spad ; \
+ rm -f ${DOC}/misc.spad.pamphlet ; \
+ rm -f ${DOC}/misc.spad.tex ; \
+ rm -f ${DOC}/misc.spad )
+
+@
+\subsection{mkfunc.spad \cite{1}}
+<<mkfunc.spad (SPAD from IN)>>=
+${MID}/mkfunc.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/mkfunc.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mkfunc.spad.pamphlet >mkfunc.spad )
+
+@
+<<INFORM.o (O from NRLIB)>>=
+${OUT}/INFORM.o: ${MID}/INFORM.NRLIB
+ @ echo 0 making ${OUT}/INFORM.o from ${MID}/INFORM.NRLIB
+ @ cp ${MID}/INFORM.NRLIB/code.o ${OUT}/INFORM.o
+
+@
+<<INFORM.NRLIB (NRLIB from MID)>>=
+${MID}/INFORM.NRLIB: ${MID}/INFORM.spad
+ @ echo 0 making ${MID}/INFORM.NRLIB from ${MID}/INFORM.spad
+ @ (cd ${MID} ; echo ')co INFORM.spad' | ${INTERPSYS} )
+
+@
+<<INFORM.spad (SPAD from IN)>>=
+${MID}/INFORM.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/INFORM.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INFORM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain INFORM InputForm" ${IN}/mkfunc.spad.pamphlet >INFORM.spad )
+
+@
+<<INFORM1.o (O from NRLIB)>>=
+${OUT}/INFORM1.o: ${MID}/INFORM1.NRLIB
+ @ echo 0 making ${OUT}/INFORM1.o from ${MID}/INFORM1.NRLIB
+ @ cp ${MID}/INFORM1.NRLIB/code.o ${OUT}/INFORM1.o
+
+@
+<<INFORM1.NRLIB (NRLIB from MID)>>=
+${MID}/INFORM1.NRLIB: ${MID}/INFORM1.spad
+ @ echo 0 making ${MID}/INFORM1.NRLIB from ${MID}/INFORM1.spad
+ @ (cd ${MID} ; echo ')co INFORM1.spad' | ${INTERPSYS} )
+
+@
+<<INFORM1.spad (SPAD from IN)>>=
+${MID}/INFORM1.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/INFORM1.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INFORM1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INFORM1 InputFormFunctions1" ${IN}/mkfunc.spad.pamphlet >INFORM1.spad )
+
+@
+<<MKFLCFN.o (O from NRLIB)>>=
+${OUT}/MKFLCFN.o: ${MID}/MKFLCFN.NRLIB
+ @ echo 0 making ${OUT}/MKFLCFN.o from ${MID}/MKFLCFN.NRLIB
+ @ cp ${MID}/MKFLCFN.NRLIB/code.o ${OUT}/MKFLCFN.o
+
+@
+<<MKFLCFN.NRLIB (NRLIB from MID)>>=
+${MID}/MKFLCFN.NRLIB: ${MID}/MKFLCFN.spad
+ @ echo 0 making ${MID}/MKFLCFN.NRLIB from ${MID}/MKFLCFN.spad
+ @ (cd ${MID} ; echo ')co MKFLCFN.spad' | ${INTERPSYS} )
+
+@
+<<MKFLCFN.spad (SPAD from IN)>>=
+${MID}/MKFLCFN.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/MKFLCFN.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MKFLCFN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MKFLCFN MakeFloatCompiledFunction" ${IN}/mkfunc.spad.pamphlet >MKFLCFN.spad )
+
+@
+<<MKFUNC.o (O from NRLIB)>>=
+${OUT}/MKFUNC.o: ${MID}/MKFUNC.NRLIB
+ @ echo 0 making ${OUT}/MKFUNC.o from ${MID}/MKFUNC.NRLIB
+ @ cp ${MID}/MKFUNC.NRLIB/code.o ${OUT}/MKFUNC.o
+
+@
+<<MKFUNC.NRLIB (NRLIB from MID)>>=
+${MID}/MKFUNC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MKFUNC.spad
+ @ echo 0 making ${MID}/MKFUNC.NRLIB from ${MID}/MKFUNC.spad
+ @ (cd ${MID} ; echo ')co MKFUNC.spad' | ${INTERPSYS} )
+
+@
+<<MKFUNC.spad (SPAD from IN)>>=
+${MID}/MKFUNC.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/MKFUNC.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MKFUNC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MKFUNC MakeFunction" ${IN}/mkfunc.spad.pamphlet >MKFUNC.spad )
+
+@
+<<MKBCFUNC.o (O from NRLIB)>>=
+${OUT}/MKBCFUNC.o: ${MID}/MKBCFUNC.NRLIB
+ @ echo 0 making ${OUT}/MKBCFUNC.o from ${MID}/MKBCFUNC.NRLIB
+ @ cp ${MID}/MKBCFUNC.NRLIB/code.o ${OUT}/MKBCFUNC.o
+
+@
+<<MKBCFUNC.NRLIB (NRLIB from MID)>>=
+${MID}/MKBCFUNC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MKBCFUNC.spad
+ @ echo 0 making ${MID}/MKBCFUNC.NRLIB from ${MID}/MKBCFUNC.spad
+ @ (cd ${MID} ; echo ')co MKBCFUNC.spad' | ${INTERPSYS} )
+
+@
+<<MKBCFUNC.spad (SPAD from IN)>>=
+${MID}/MKBCFUNC.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/MKBCFUNC.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MKBCFUNC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MKBCFUNC MakeBinaryCompiledFunction" ${IN}/mkfunc.spad.pamphlet >MKBCFUNC.spad )
+
+@
+<<MKUCFUNC.o (O from NRLIB)>>=
+${OUT}/MKUCFUNC.o: ${MID}/MKUCFUNC.NRLIB
+ @ echo 0 making ${OUT}/MKUCFUNC.o from ${MID}/MKUCFUNC.NRLIB
+ @ cp ${MID}/MKUCFUNC.NRLIB/code.o ${OUT}/MKUCFUNC.o
+
+@
+<<MKUCFUNC.NRLIB (NRLIB from MID)>>=
+${MID}/MKUCFUNC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MKUCFUNC.spad
+ @ echo 0 making ${MID}/MKUCFUNC.NRLIB from ${MID}/MKUCFUNC.spad
+ @ (cd ${MID} ; echo ')co MKUCFUNC.spad' | ${INTERPSYS} )
+
+@
+<<MKUCFUNC.spad (SPAD from IN)>>=
+${MID}/MKUCFUNC.spad: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${MID}/MKUCFUNC.spad from ${IN}/mkfunc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MKUCFUNC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MKUCFUNC MakeUnaryCompiledFunction" ${IN}/mkfunc.spad.pamphlet >MKUCFUNC.spad )
+
+@
+<<mkfunc.spad.dvi (DOC from IN)>>=
+${DOC}/mkfunc.spad.dvi: ${IN}/mkfunc.spad.pamphlet
+ @ echo 0 making ${DOC}/mkfunc.spad.dvi from ${IN}/mkfunc.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mkfunc.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mkfunc.spad ; \
+ rm -f ${DOC}/mkfunc.spad.pamphlet ; \
+ rm -f ${DOC}/mkfunc.spad.tex ; \
+ rm -f ${DOC}/mkfunc.spad )
+
+@
+\subsection{mkrecord.spad \cite{1}}
+<<mkrecord.spad (SPAD from IN)>>=
+${MID}/mkrecord.spad: ${IN}/mkrecord.spad.pamphlet
+ @ echo 0 making ${MID}/mkrecord.spad from ${IN}/mkrecord.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mkrecord.spad.pamphlet >mkrecord.spad )
+
+@
+<<MKRECORD.o (O from NRLIB)>>=
+${OUT}/MKRECORD.o: ${MID}/MKRECORD.NRLIB
+ @ echo 0 making ${OUT}/MKRECORD.o from ${MID}/MKRECORD.NRLIB
+ @ cp ${MID}/MKRECORD.NRLIB/code.o ${OUT}/MKRECORD.o
+
+@
+<<MKRECORD.NRLIB (NRLIB from MID)>>=
+${MID}/MKRECORD.NRLIB: ${OUT}/TYPE.o ${MID}/MKRECORD.spad
+ @ echo 0 making ${MID}/MKRECORD.NRLIB from ${MID}/MKRECORD.spad
+ @ (cd ${MID} ; echo ')co MKRECORD.spad' | ${INTERPSYS} )
+
+@
+<<MKRECORD.spad (SPAD from IN)>>=
+${MID}/MKRECORD.spad: ${IN}/mkrecord.spad.pamphlet
+ @ echo 0 making ${MID}/MKRECORD.spad from ${IN}/mkrecord.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MKRECORD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MKRECORD MakeRecord" ${IN}/mkrecord.spad.pamphlet >MKRECORD.spad )
+
+@
+<<mkrecord.spad.dvi (DOC from IN)>>=
+${DOC}/mkrecord.spad.dvi: ${IN}/mkrecord.spad.pamphlet
+ @ echo 0 making ${DOC}/mkrecord.spad.dvi from ${IN}/mkrecord.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mkrecord.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mkrecord.spad ; \
+ rm -f ${DOC}/mkrecord.spad.pamphlet ; \
+ rm -f ${DOC}/mkrecord.spad.tex ; \
+ rm -f ${DOC}/mkrecord.spad )
+
+@
+\subsection{mlift.spad.jhd \cite{1}}
+<<mlift.spad.jhd (SPAD from IN)>>=
+${MID}/mlift.spad.jhd: ${IN}/mlift.spad.jhd.pamphlet
+ @ echo 0 making ${MID}/mlift.spad.jhd from ${IN}/mlift.spad.jhd.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mlift.spad.jhd.pamphlet >mlift.spad.jhd )
+
+@
+<<mlift.spad.jhd.dvi (DOC from IN)>>=
+${DOC}/mlift.spad.jhd.dvi: ${IN}/mlift.spad.jhd.pamphlet
+ @ echo 0 making ${DOC}/mlift.spad.jhd.dvi from ${IN}/mlift.spad.jhd.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mlift.spad.jhd.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mlift.spad.jhd ; \
+ rm -f ${DOC}/mlift.spad.jhd.pamphlet ; \
+ rm -f ${DOC}/mlift.spad.jhd.tex ; \
+ rm -f ${DOC}/mlift.spad.jhd )
+
+@
+\subsection{mlift.spad \cite{1}}
+<<mlift.spad (SPAD from IN)>>=
+${MID}/mlift.spad: ${IN}/mlift.spad.pamphlet
+ @ echo 0 making ${MID}/mlift.spad from ${IN}/mlift.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mlift.spad.pamphlet >mlift.spad )
+
+@
+<<MLIFT.o (O from NRLIB)>>=
+${OUT}/MLIFT.o: ${MID}/MLIFT.NRLIB
+ @ echo 0 making ${OUT}/MLIFT.o from ${MID}/MLIFT.NRLIB
+ @ cp ${MID}/MLIFT.NRLIB/code.o ${OUT}/MLIFT.o
+
+@
+<<MLIFT.NRLIB (NRLIB from MID)>>=
+${MID}/MLIFT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MLIFT.spad
+ @ echo 0 making ${MID}/MLIFT.NRLIB from ${MID}/MLIFT.spad
+ @ (cd ${MID} ; echo ')co MLIFT.spad' | ${INTERPSYS} )
+
+@
+<<MLIFT.spad (SPAD from IN)>>=
+${MID}/MLIFT.spad: ${IN}/mlift.spad.pamphlet
+ @ echo 0 making ${MID}/MLIFT.spad from ${IN}/mlift.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MLIFT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MLIFT MultivariateLifting" ${IN}/mlift.spad.pamphlet >MLIFT.spad )
+
+@
+<<mlift.spad.dvi (DOC from IN)>>=
+${DOC}/mlift.spad.dvi: ${IN}/mlift.spad.pamphlet
+ @ echo 0 making ${DOC}/mlift.spad.dvi from ${IN}/mlift.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mlift.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mlift.spad ; \
+ rm -f ${DOC}/mlift.spad.pamphlet ; \
+ rm -f ${DOC}/mlift.spad.tex ; \
+ rm -f ${DOC}/mlift.spad )
+
+@
+\subsection{moddfact.spad \cite{1}}
+<<moddfact.spad (SPAD from IN)>>=
+${MID}/moddfact.spad: ${IN}/moddfact.spad.pamphlet
+ @ echo 0 making ${MID}/moddfact.spad from ${IN}/moddfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/moddfact.spad.pamphlet >moddfact.spad )
+
+@
+<<MDDFACT.o (O from NRLIB)>>=
+${OUT}/MDDFACT.o: ${MID}/MDDFACT.NRLIB
+ @ echo 0 making ${OUT}/MDDFACT.o from ${MID}/MDDFACT.NRLIB
+ @ cp ${MID}/MDDFACT.NRLIB/code.o ${OUT}/MDDFACT.o
+
+@
+<<MDDFACT.NRLIB (NRLIB from MID)>>=
+${MID}/MDDFACT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MDDFACT.spad
+ @ echo 0 making ${MID}/MDDFACT.NRLIB from ${MID}/MDDFACT.spad
+ @ (cd ${MID} ; echo ')co MDDFACT.spad' | ${INTERPSYS} )
+
+@
+<<MDDFACT.spad (SPAD from IN)>>=
+${MID}/MDDFACT.spad: ${IN}/moddfact.spad.pamphlet
+ @ echo 0 making ${MID}/MDDFACT.spad from ${IN}/moddfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MDDFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MDDFACT ModularDistinctDegreeFactorizer" ${IN}/moddfact.spad.pamphlet >MDDFACT.spad )
+
+@
+<<moddfact.spad.dvi (DOC from IN)>>=
+${DOC}/moddfact.spad.dvi: ${IN}/moddfact.spad.pamphlet
+ @ echo 0 making ${DOC}/moddfact.spad.dvi from ${IN}/moddfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/moddfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} moddfact.spad ; \
+ rm -f ${DOC}/moddfact.spad.pamphlet ; \
+ rm -f ${DOC}/moddfact.spad.tex ; \
+ rm -f ${DOC}/moddfact.spad )
+
+@
+\subsection{modgcd.spad \cite{1}}
+<<modgcd.spad (SPAD from IN)>>=
+${MID}/modgcd.spad: ${IN}/modgcd.spad.pamphlet
+ @ echo 0 making ${MID}/modgcd.spad from ${IN}/modgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/modgcd.spad.pamphlet >modgcd.spad )
+
+@
+<<INMODGCD.o (O from NRLIB)>>=
+${OUT}/INMODGCD.o: ${MID}/INMODGCD.NRLIB
+ @ echo 0 making ${OUT}/INMODGCD.o from ${MID}/INMODGCD.NRLIB
+ @ cp ${MID}/INMODGCD.NRLIB/code.o ${OUT}/INMODGCD.o
+
+@
+<<INMODGCD.NRLIB (NRLIB from MID)>>=
+${MID}/INMODGCD.NRLIB: ${MID}/INMODGCD.spad
+ @ echo 0 making ${MID}/INMODGCD.NRLIB from ${MID}/INMODGCD.spad
+ @ (cd ${MID} ; echo ')co INMODGCD.spad' | ${INTERPSYS} )
+
+@
+<<INMODGCD.spad (SPAD from IN)>>=
+${MID}/INMODGCD.spad: ${IN}/modgcd.spad.pamphlet
+ @ echo 0 making ${MID}/INMODGCD.spad from ${IN}/modgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INMODGCD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INMODGCD InnerModularGcd" ${IN}/modgcd.spad.pamphlet >INMODGCD.spad )
+
+@
+<<modgcd.spad.dvi (DOC from IN)>>=
+${DOC}/modgcd.spad.dvi: ${IN}/modgcd.spad.pamphlet
+ @ echo 0 making ${DOC}/modgcd.spad.dvi from ${IN}/modgcd.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/modgcd.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} modgcd.spad ; \
+ rm -f ${DOC}/modgcd.spad.pamphlet ; \
+ rm -f ${DOC}/modgcd.spad.tex ; \
+ rm -f ${DOC}/modgcd.spad )
+
+@
+\subsection{modmonom.spad \cite{1}}
+<<modmonom.spad (SPAD from IN)>>=
+${MID}/modmonom.spad: ${IN}/modmonom.spad.pamphlet
+ @ echo 0 making ${MID}/modmonom.spad from ${IN}/modmonom.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/modmonom.spad.pamphlet >modmonom.spad )
+
+@
+<<GMODPOL.o (O from NRLIB)>>=
+${OUT}/GMODPOL.o: ${MID}/GMODPOL.NRLIB
+ @ echo 0 making ${OUT}/GMODPOL.o from ${MID}/GMODPOL.NRLIB
+ @ cp ${MID}/GMODPOL.NRLIB/code.o ${OUT}/GMODPOL.o
+
+@
+<<GMODPOL.NRLIB (NRLIB from MID)>>=
+${MID}/GMODPOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GMODPOL.spad
+ @ echo 0 making ${MID}/GMODPOL.NRLIB from ${MID}/GMODPOL.spad
+ @ (cd ${MID} ; echo ')co GMODPOL.spad' | ${INTERPSYS} )
+
+@
+<<GMODPOL.spad (SPAD from IN)>>=
+${MID}/GMODPOL.spad: ${IN}/modmonom.spad.pamphlet
+ @ echo 0 making ${MID}/GMODPOL.spad from ${IN}/modmonom.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GMODPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GMODPOL GeneralModulePolynomial" ${IN}/modmonom.spad.pamphlet >GMODPOL.spad )
+
+@
+<<MODMONOM.o (O from NRLIB)>>=
+${OUT}/MODMONOM.o: ${MID}/MODMONOM.NRLIB
+ @ echo 0 making ${OUT}/MODMONOM.o from ${MID}/MODMONOM.NRLIB
+ @ cp ${MID}/MODMONOM.NRLIB/code.o ${OUT}/MODMONOM.o
+
+@
+<<MODMONOM.NRLIB (NRLIB from MID)>>=
+${MID}/MODMONOM.NRLIB: ${MID}/MODMONOM.spad
+ @ echo 0 making ${MID}/MODMONOM.NRLIB from ${MID}/MODMONOM.spad
+ @ (cd ${MID} ; echo ')co MODMONOM.spad' | ${INTERPSYS} )
+
+@
+<<MODMONOM.spad (SPAD from IN)>>=
+${MID}/MODMONOM.spad: ${IN}/modmonom.spad.pamphlet
+ @ echo 0 making ${MID}/MODMONOM.spad from ${IN}/modmonom.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MODMONOM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MODMONOM ModuleMonomial" ${IN}/modmonom.spad.pamphlet >MODMONOM.spad )
+
+@
+<<modmonom.spad.dvi (DOC from IN)>>=
+${DOC}/modmonom.spad.dvi: ${IN}/modmonom.spad.pamphlet
+ @ echo 0 making ${DOC}/modmonom.spad.dvi from ${IN}/modmonom.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/modmonom.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} modmonom.spad ; \
+ rm -f ${DOC}/modmonom.spad.pamphlet ; \
+ rm -f ${DOC}/modmonom.spad.tex ; \
+ rm -f ${DOC}/modmonom.spad )
+
+@
+\subsection{modmon.spad \cite{1}}
+<<modmon.spad (SPAD from IN)>>=
+${MID}/modmon.spad: ${IN}/modmon.spad.pamphlet
+ @ echo 0 making ${MID}/modmon.spad from ${IN}/modmon.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/modmon.spad.pamphlet >modmon.spad )
+
+@
+<<MODMON.o (O from NRLIB)>>=
+${OUT}/MODMON.o: ${MID}/MODMON.NRLIB
+ @ echo 0 making ${OUT}/MODMON.o from ${MID}/MODMON.NRLIB
+ @ cp ${MID}/MODMON.NRLIB/code.o ${OUT}/MODMON.o
+
+@
+<<MODMON.NRLIB (NRLIB from MID)>>=
+${MID}/MODMON.NRLIB: ${MID}/MODMON.spad
+ @ echo 0 making ${MID}/MODMON.NRLIB from ${MID}/MODMON.spad
+ @ (cd ${MID} ; echo ')co MODMON.spad' | ${INTERPSYS} )
+
+@
+<<MODMON.spad (SPAD from IN)>>=
+${MID}/MODMON.spad: ${IN}/modmon.spad.pamphlet
+ @ echo 0 making ${MID}/MODMON.spad from ${IN}/modmon.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MODMON.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MODMON ModMonic" ${IN}/modmon.spad.pamphlet >MODMON.spad )
+
+@
+<<modmon.spad.dvi (DOC from IN)>>=
+${DOC}/modmon.spad.dvi: ${IN}/modmon.spad.pamphlet
+ @ echo 0 making ${DOC}/modmon.spad.dvi from ${IN}/modmon.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/modmon.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} modmon.spad ; \
+ rm -f ${DOC}/modmon.spad.pamphlet ; \
+ rm -f ${DOC}/modmon.spad.tex ; \
+ rm -f ${DOC}/modmon.spad )
+
+@
+\subsection{modring.spad \cite{1}}
+<<modring.spad (SPAD from IN)>>=
+${MID}/modring.spad: ${IN}/modring.spad.pamphlet
+ @ echo 0 making ${MID}/modring.spad from ${IN}/modring.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/modring.spad.pamphlet >modring.spad )
+
+@
+<<EMR.o (O from NRLIB)>>=
+${OUT}/EMR.o: ${MID}/EMR.NRLIB
+ @ echo 0 making ${OUT}/EMR.o from ${MID}/EMR.NRLIB
+ @ cp ${MID}/EMR.NRLIB/code.o ${OUT}/EMR.o
+
+@
+<<EMR.NRLIB (NRLIB from MID)>>=
+${MID}/EMR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/EMR.spad
+ @ echo 0 making ${MID}/EMR.NRLIB from ${MID}/EMR.spad
+ @ (cd ${MID} ; echo ')co EMR.spad' | ${INTERPSYS} )
+
+@
+<<EMR.spad (SPAD from IN)>>=
+${MID}/EMR.spad: ${IN}/modring.spad.pamphlet
+ @ echo 0 making ${MID}/EMR.spad from ${IN}/modring.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EMR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EMR EuclideanModularRing" ${IN}/modring.spad.pamphlet >EMR.spad )
+
+@
+<<MODFIELD.o (O from NRLIB)>>=
+${OUT}/MODFIELD.o: ${MID}/MODFIELD.NRLIB
+ @ echo 0 making ${OUT}/MODFIELD.o from ${MID}/MODFIELD.NRLIB
+ @ cp ${MID}/MODFIELD.NRLIB/code.o ${OUT}/MODFIELD.o
+
+@
+<<MODFIELD.NRLIB (NRLIB from MID)>>=
+${MID}/MODFIELD.NRLIB: ${MID}/MODFIELD.spad
+ @ echo 0 making ${MID}/MODFIELD.NRLIB from ${MID}/MODFIELD.spad
+ @ (cd ${MID} ; echo ')co MODFIELD.spad' | ${INTERPSYS} )
+
+@
+<<MODFIELD.spad (SPAD from IN)>>=
+${MID}/MODFIELD.spad: ${IN}/modring.spad.pamphlet
+ @ echo 0 making ${MID}/MODFIELD.spad from ${IN}/modring.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MODFIELD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MODFIELD ModularField" ${IN}/modring.spad.pamphlet >MODFIELD.spad )
+
+@
+<<MODRING.o (O from NRLIB)>>=
+${OUT}/MODRING.o: ${MID}/MODRING.NRLIB
+ @ echo 0 making ${OUT}/MODRING.o from ${MID}/MODRING.NRLIB
+ @ cp ${MID}/MODRING.NRLIB/code.o ${OUT}/MODRING.o
+
+@
+<<MODRING.NRLIB (NRLIB from MID)>>=
+${MID}/MODRING.NRLIB: ${MID}/MODRING.spad
+ @ echo 0 making ${MID}/MODRING.NRLIB from ${MID}/MODRING.spad
+ @ (cd ${MID} ; echo ')co MODRING.spad' | ${INTERPSYS} )
+
+@
+<<MODRING.spad (SPAD from IN)>>=
+${MID}/MODRING.spad: ${IN}/modring.spad.pamphlet
+ @ echo 0 making ${MID}/MODRING.spad from ${IN}/modring.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MODRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MODRING ModularRing" ${IN}/modring.spad.pamphlet >MODRING.spad )
+
+@
+<<modring.spad.dvi (DOC from IN)>>=
+${DOC}/modring.spad.dvi: ${IN}/modring.spad.pamphlet
+ @ echo 0 making ${DOC}/modring.spad.dvi from ${IN}/modring.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/modring.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} modring.spad ; \
+ rm -f ${DOC}/modring.spad.pamphlet ; \
+ rm -f ${DOC}/modring.spad.tex ; \
+ rm -f ${DOC}/modring.spad )
+
+@
+\subsection{moebius.spad \cite{1}}
+<<moebius.spad (SPAD from IN)>>=
+${MID}/moebius.spad: ${IN}/moebius.spad.pamphlet
+ @ echo 0 making ${MID}/moebius.spad from ${IN}/moebius.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/moebius.spad.pamphlet >moebius.spad )
+
+@
+<<MOEBIUS.o (O from NRLIB)>>=
+${OUT}/MOEBIUS.o: ${MID}/MOEBIUS.NRLIB
+ @ echo 0 making ${OUT}/MOEBIUS.o from ${MID}/MOEBIUS.NRLIB
+ @ cp ${MID}/MOEBIUS.NRLIB/code.o ${OUT}/MOEBIUS.o
+
+@
+<<MOEBIUS.NRLIB (NRLIB from MID)>>=
+${MID}/MOEBIUS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MOEBIUS.spad
+ @ echo 0 making ${MID}/MOEBIUS.NRLIB from ${MID}/MOEBIUS.spad
+ @ (cd ${MID} ; echo ')co MOEBIUS.spad' | ${INTERPSYS} )
+
+@
+<<MOEBIUS.spad (SPAD from IN)>>=
+${MID}/MOEBIUS.spad: ${IN}/moebius.spad.pamphlet
+ @ echo 0 making ${MID}/MOEBIUS.spad from ${IN}/moebius.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MOEBIUS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MOEBIUS MoebiusTransform" ${IN}/moebius.spad.pamphlet >MOEBIUS.spad )
+
+@
+<<moebius.spad.dvi (DOC from IN)>>=
+${DOC}/moebius.spad.dvi: ${IN}/moebius.spad.pamphlet
+ @ echo 0 making ${DOC}/moebius.spad.dvi from ${IN}/moebius.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/moebius.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} moebius.spad ; \
+ rm -f ${DOC}/moebius.spad.pamphlet ; \
+ rm -f ${DOC}/moebius.spad.tex ; \
+ rm -f ${DOC}/moebius.spad )
+
+@
+\subsection{mring.spad \cite{1}}
+<<mring.spad (SPAD from IN)>>=
+${MID}/mring.spad: ${IN}/mring.spad.pamphlet
+ @ echo 0 making ${MID}/mring.spad from ${IN}/mring.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mring.spad.pamphlet >mring.spad )
+
+@
+<<MRF2.o (O from NRLIB)>>=
+${OUT}/MRF2.o: ${MID}/MRF2.NRLIB
+ @ echo 0 making ${OUT}/MRF2.o from ${MID}/MRF2.NRLIB
+ @ cp ${MID}/MRF2.NRLIB/code.o ${OUT}/MRF2.o
+
+@
+<<MRF2.NRLIB (NRLIB from MID)>>=
+${MID}/MRF2.NRLIB: ${MID}/MRF2.spad
+ @ echo 0 making ${MID}/MRF2.NRLIB from ${MID}/MRF2.spad
+ @ (cd ${MID} ; echo ')co MRF2.spad' | ${INTERPSYS} )
+
+@
+<<MRF2.spad (SPAD from IN)>>=
+${MID}/MRF2.spad: ${IN}/mring.spad.pamphlet
+ @ echo 0 making ${MID}/MRF2.spad from ${IN}/mring.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MRF2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MRF2 MonoidRingFunctions2" ${IN}/mring.spad.pamphlet >MRF2.spad )
+
+@
+<<MRING.o (O from NRLIB)>>=
+${OUT}/MRING.o: ${MID}/MRING.NRLIB
+ @ echo 0 making ${OUT}/MRING.o from ${MID}/MRING.NRLIB
+ @ cp ${MID}/MRING.NRLIB/code.o ${OUT}/MRING.o
+
+@
+<<MRING.NRLIB (NRLIB from MID)>>=
+${MID}/MRING.NRLIB: ${MID}/MRING.spad
+ @ echo 0 making ${MID}/MRING.NRLIB from ${MID}/MRING.spad
+ @ (cd ${MID} ; echo ')co MRING.spad' | ${INTERPSYS} )
+
+@
+<<MRING.spad (SPAD from IN)>>=
+${MID}/MRING.spad: ${IN}/mring.spad.pamphlet
+ @ echo 0 making ${MID}/MRING.spad from ${IN}/mring.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MRING MonoidRing" ${IN}/mring.spad.pamphlet >MRING.spad )
+
+@
+<<mring.spad.dvi (DOC from IN)>>=
+${DOC}/mring.spad.dvi: ${IN}/mring.spad.pamphlet
+ @ echo 0 making ${DOC}/mring.spad.dvi from ${IN}/mring.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mring.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mring.spad ; \
+ rm -f ${DOC}/mring.spad.pamphlet ; \
+ rm -f ${DOC}/mring.spad.tex ; \
+ rm -f ${DOC}/mring.spad )
+
+@
+\subsection{mset.spad \cite{1}}
+<<mset.spad (SPAD from IN)>>=
+${MID}/mset.spad: ${IN}/mset.spad.pamphlet
+ @ echo 0 making ${MID}/mset.spad from ${IN}/mset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mset.spad.pamphlet >mset.spad )
+
+@
+<<MSET.o (O from NRLIB)>>=
+${OUT}/MSET.o: ${MID}/MSET.NRLIB
+ @ echo 0 making ${OUT}/MSET.o from ${MID}/MSET.NRLIB
+ @ cp ${MID}/MSET.NRLIB/code.o ${OUT}/MSET.o
+
+@
+<<MSET.NRLIB (NRLIB from MID)>>=
+${MID}/MSET.NRLIB: ${MID}/MSET.spad
+ @ echo 0 making ${MID}/MSET.NRLIB from ${MID}/MSET.spad
+ @ (cd ${MID} ; echo ')co MSET.spad' | ${INTERPSYS} )
+
+@
+<<MSET.spad (SPAD from IN)>>=
+${MID}/MSET.spad: ${IN}/mset.spad.pamphlet
+ @ echo 0 making ${MID}/MSET.spad from ${IN}/mset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MSET Multiset" ${IN}/mset.spad.pamphlet >MSET.spad )
+
+@
+<<mset.spad.dvi (DOC from IN)>>=
+${DOC}/mset.spad.dvi: ${IN}/mset.spad.pamphlet
+ @ echo 0 making ${DOC}/mset.spad.dvi from ${IN}/mset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mset.spad ; \
+ rm -f ${DOC}/mset.spad.pamphlet ; \
+ rm -f ${DOC}/mset.spad.tex ; \
+ rm -f ${DOC}/mset.spad )
+
+@
+\subsection{mts.spad \cite{1}}
+<<mts.spad (SPAD from IN)>>=
+${MID}/mts.spad: ${IN}/mts.spad.pamphlet
+ @ echo 0 making ${MID}/mts.spad from ${IN}/mts.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/mts.spad.pamphlet >mts.spad )
+
+@
+<<SMTS.o (O from NRLIB)>>=
+${OUT}/SMTS.o: ${MID}/SMTS.NRLIB
+ @ echo 0 making ${OUT}/SMTS.o from ${MID}/SMTS.NRLIB
+ @ cp ${MID}/SMTS.NRLIB/code.o ${OUT}/SMTS.o
+
+@
+<<SMTS.NRLIB (NRLIB from MID)>>=
+${MID}/SMTS.NRLIB: ${MID}/SMTS.spad
+ @ echo 0 making ${MID}/SMTS.NRLIB from ${MID}/SMTS.spad
+ @ (cd ${MID} ; echo ')co SMTS.spad' | ${INTERPSYS} )
+
+@
+<<SMTS.spad (SPAD from IN)>>=
+${MID}/SMTS.spad: ${IN}/mts.spad.pamphlet
+ @ echo 0 making ${MID}/SMTS.spad from ${IN}/mts.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SMTS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SMTS SparseMultivariateTaylorSeries" ${IN}/mts.spad.pamphlet >SMTS.spad )
+
+@
+<<TS.o (O from NRLIB)>>=
+${OUT}/TS.o: ${MID}/TS.NRLIB
+ @ echo 0 making ${OUT}/TS.o from ${MID}/TS.NRLIB
+ @ cp ${MID}/TS.NRLIB/code.o ${OUT}/TS.o
+
+@
+<<TS.NRLIB (NRLIB from MID)>>=
+${MID}/TS.NRLIB: ${MID}/TS.spad
+ @ echo 0 making ${MID}/TS.NRLIB from ${MID}/TS.spad
+ @ (cd ${MID} ; echo ')co TS.spad' | ${INTERPSYS} )
+
+@
+<<TS.spad (SPAD from IN)>>=
+${MID}/TS.spad: ${IN}/mts.spad.pamphlet
+ @ echo 0 making ${MID}/TS.spad from ${IN}/mts.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TS TaylorSeries" ${IN}/mts.spad.pamphlet >TS.spad )
+
+@
+<<mts.spad.dvi (DOC from IN)>>=
+${DOC}/mts.spad.dvi: ${IN}/mts.spad.pamphlet
+ @ echo 0 making ${DOC}/mts.spad.dvi from ${IN}/mts.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/mts.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} mts.spad ; \
+ rm -f ${DOC}/mts.spad.pamphlet ; \
+ rm -f ${DOC}/mts.spad.tex ; \
+ rm -f ${DOC}/mts.spad )
+
+@
+\subsection{multfact.spad \cite{1}}
+<<multfact.spad (SPAD from IN)>>=
+${MID}/multfact.spad: ${IN}/multfact.spad.pamphlet
+ @ echo 0 making ${MID}/multfact.spad from ${IN}/multfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/multfact.spad.pamphlet >multfact.spad )
+
+@
+<<ALGMFACT.o (O from NRLIB)>>=
+${OUT}/ALGMFACT.o: ${MID}/ALGMFACT.NRLIB
+ @ echo 0 making ${OUT}/ALGMFACT.o from ${MID}/ALGMFACT.NRLIB
+ @ cp ${MID}/ALGMFACT.NRLIB/code.o ${OUT}/ALGMFACT.o
+
+@
+<<ALGMFACT.NRLIB (NRLIB from MID)>>=
+${MID}/ALGMFACT.NRLIB: ${MID}/ALGMFACT.spad
+ @ echo 0 making ${MID}/ALGMFACT.NRLIB from ${MID}/ALGMFACT.spad
+ @ (cd ${MID} ; echo ')co ALGMFACT.spad' | ${INTERPSYS} )
+
+@
+<<ALGMFACT.spad (SPAD from IN)>>=
+${MID}/ALGMFACT.spad: ${IN}/multfact.spad.pamphlet
+ @ echo 0 making ${MID}/ALGMFACT.spad from ${IN}/multfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGMFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ALGMFACT AlgebraicMultFact" ${IN}/multfact.spad.pamphlet >ALGMFACT.spad )
+
+@
+<<INNMFACT.o (O from NRLIB)>>=
+${OUT}/INNMFACT.o: ${MID}/INNMFACT.NRLIB
+ @ echo 0 making ${OUT}/INNMFACT.o from ${MID}/INNMFACT.NRLIB
+ @ cp ${MID}/INNMFACT.NRLIB/code.o ${OUT}/INNMFACT.o
+
+@
+<<INNMFACT.NRLIB (NRLIB from MID)>>=
+${MID}/INNMFACT.NRLIB: ${MID}/INNMFACT.spad
+ @ echo 0 making ${MID}/INNMFACT.NRLIB from ${MID}/INNMFACT.spad
+ @ (cd ${MID} ; echo ')co INNMFACT.spad' | ${INTERPSYS} )
+
+@
+<<INNMFACT.spad (SPAD from IN)>>=
+${MID}/INNMFACT.spad: ${IN}/multfact.spad.pamphlet
+ @ echo 0 making ${MID}/INNMFACT.spad from ${IN}/multfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INNMFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INNMFACT InnerMultFact" ${IN}/multfact.spad.pamphlet >INNMFACT.spad )
+
+@
+<<MULTFACT.o (O from NRLIB)>>=
+${OUT}/MULTFACT.o: ${MID}/MULTFACT.NRLIB
+ @ echo 0 making ${OUT}/MULTFACT.o from ${MID}/MULTFACT.NRLIB
+ @ cp ${MID}/MULTFACT.NRLIB/code.o ${OUT}/MULTFACT.o
+
+@
+<<MULTFACT.NRLIB (NRLIB from MID)>>=
+${MID}/MULTFACT.NRLIB: ${MID}/MULTFACT.spad
+ @ echo 0 making ${MID}/MULTFACT.NRLIB from ${MID}/MULTFACT.spad
+ @ (cd ${MID} ; echo ')co MULTFACT.spad' | ${INTERPSYS} )
+
+@
+<<MULTFACT.spad (SPAD from IN)>>=
+${MID}/MULTFACT.spad: ${IN}/multfact.spad.pamphlet
+ @ echo 0 making ${MID}/MULTFACT.spad from ${IN}/multfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MULTFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MULTFACT MultivariateFactorize" ${IN}/multfact.spad.pamphlet >MULTFACT.spad )
+
+@
+<<multfact.spad.dvi (DOC from IN)>>=
+${DOC}/multfact.spad.dvi: ${IN}/multfact.spad.pamphlet
+ @ echo 0 making ${DOC}/multfact.spad.dvi from ${IN}/multfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/multfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} multfact.spad ; \
+ rm -f ${DOC}/multfact.spad.pamphlet ; \
+ rm -f ${DOC}/multfact.spad.tex ; \
+ rm -f ${DOC}/multfact.spad )
+
+@
+\subsection{multpoly.spad \cite{1}}
+<<multpoly.spad (SPAD from IN)>>=
+${MID}/multpoly.spad: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${MID}/multpoly.spad from ${IN}/multpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/multpoly.spad.pamphlet >multpoly.spad )
+
+@
+<<INDE.o (O from NRLIB)>>=
+${OUT}/INDE.o: ${MID}/INDE.NRLIB
+ @ echo 0 making ${OUT}/INDE.o from ${MID}/INDE.NRLIB
+ @ cp ${MID}/INDE.NRLIB/code.o ${OUT}/INDE.o
+
+@
+<<INDE.NRLIB (NRLIB from MID)>>=
+${MID}/INDE.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/INDE.spad
+ @ echo 0 making ${MID}/INDE.NRLIB from ${MID}/INDE.spad
+ @ (cd ${MID} ; echo ')co INDE.spad' | ${INTERPSYS} )
+
+@
+<<INDE.spad (SPAD from IN)>>=
+${MID}/INDE.spad: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${MID}/INDE.spad from ${IN}/multpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INDE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain INDE IndexedExponents" ${IN}/multpoly.spad.pamphlet >INDE.spad )
+
+@
+<<MPOLY.o (O from NRLIB)>>=
+${OUT}/MPOLY.o: ${MID}/MPOLY.NRLIB
+ @ echo 0 making ${OUT}/MPOLY.o from ${MID}/MPOLY.NRLIB
+ @ cp ${MID}/MPOLY.NRLIB/code.o ${OUT}/MPOLY.o
+
+@
+<<MPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/MPOLY.NRLIB: ${MID}/MPOLY.spad
+ @ echo 0 making ${MID}/MPOLY.NRLIB from ${MID}/MPOLY.spad
+ @ (cd ${MID} ; echo ')co MPOLY.spad' | ${INTERPSYS} )
+
+@
+<<MPOLY.spad (SPAD from IN)>>=
+${MID}/MPOLY.spad: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${MID}/MPOLY.spad from ${IN}/multpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MPOLY MultivariatePolynomial" ${IN}/multpoly.spad.pamphlet >MPOLY.spad )
+
+@
+<<POLY.o (O from NRLIB)>>=
+${OUT}/POLY.o: ${MID}/POLY.NRLIB
+ @ echo 0 making ${OUT}/POLY.o from ${MID}/POLY.NRLIB
+ @ cp ${MID}/POLY.NRLIB/code.o ${OUT}/POLY.o
+
+@
+<<POLY.NRLIB (NRLIB from MID)>>=
+${MID}/POLY.NRLIB: ${MID}/POLY.spad
+ @ echo 0 making ${MID}/POLY.NRLIB from ${MID}/POLY.spad
+ @ (cd ${MID} ; echo ')co POLY.spad' | ${INTERPSYS} )
+
+@
+<<POLY.spad (SPAD from IN)>>=
+${MID}/POLY.spad: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${MID}/POLY.spad from ${IN}/multpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain POLY Polynomial" ${IN}/multpoly.spad.pamphlet >POLY.spad )
+
+@
+<<POLY2.o (O from NRLIB)>>=
+${OUT}/POLY2.o: ${MID}/POLY2.NRLIB
+ @ echo 0 making ${OUT}/POLY2.o from ${MID}/POLY2.NRLIB
+ @ cp ${MID}/POLY2.NRLIB/code.o ${OUT}/POLY2.o
+
+@
+<<POLY2.NRLIB (NRLIB from MID)>>=
+${MID}/POLY2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLY2.spad
+ @ echo 0 making ${MID}/POLY2.NRLIB from ${MID}/POLY2.spad
+ @ (cd ${MID} ; echo ')co POLY2.spad' | ${INTERPSYS} )
+
+@
+<<POLY2.spad (SPAD from IN)>>=
+${MID}/POLY2.spad: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${MID}/POLY2.spad from ${IN}/multpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLY2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLY2 PolynomialFunctions2" ${IN}/multpoly.spad.pamphlet >POLY2.spad )
+
+@
+<<SMP.o (O from NRLIB)>>=
+${OUT}/SMP.o: ${MID}/SMP.NRLIB
+ @ echo 0 making ${OUT}/SMP.o from ${MID}/SMP.NRLIB
+ @ cp ${MID}/SMP.NRLIB/code.o ${OUT}/SMP.o
+
+@
+<<SMP.NRLIB (NRLIB from MID)>>=
+${MID}/SMP.NRLIB: ${MID}/SMP.spad
+ @ echo 0 making ${MID}/SMP.NRLIB from ${MID}/SMP.spad
+ @ (cd ${MID} ; echo ')co SMP.spad' | ${INTERPSYS} )
+
+@
+<<SMP.spad (SPAD from IN)>>=
+${MID}/SMP.spad: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${MID}/SMP.spad from ${IN}/multpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SMP SparseMultivariatePolynomial" ${IN}/multpoly.spad.pamphlet >SMP.spad )
+
+@
+<<multpoly.spad.dvi (DOC from IN)>>=
+${DOC}/multpoly.spad.dvi: ${IN}/multpoly.spad.pamphlet
+ @ echo 0 making ${DOC}/multpoly.spad.dvi from ${IN}/multpoly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/multpoly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} multpoly.spad ; \
+ rm -f ${DOC}/multpoly.spad.pamphlet ; \
+ rm -f ${DOC}/multpoly.spad.tex ; \
+ rm -f ${DOC}/multpoly.spad )
+
+@
+\subsection{multsqfr.spad \cite{1}}
+<<multsqfr.spad (SPAD from IN)>>=
+${MID}/multsqfr.spad: ${IN}/multsqfr.spad.pamphlet
+ @ echo 0 making ${MID}/multsqfr.spad from ${IN}/multsqfr.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/multsqfr.spad.pamphlet >multsqfr.spad )
+
+@
+<<MULTSQFR.o (O from NRLIB)>>=
+${OUT}/MULTSQFR.o: ${MID}/MULTSQFR.NRLIB
+ @ echo 0 making ${OUT}/MULTSQFR.o from ${MID}/MULTSQFR.NRLIB
+ @ cp ${MID}/MULTSQFR.NRLIB/code.o ${OUT}/MULTSQFR.o
+
+@
+<<MULTSQFR.NRLIB (NRLIB from MID)>>=
+${MID}/MULTSQFR.NRLIB: ${MID}/MULTSQFR.spad
+ @ echo 0 making ${MID}/MULTSQFR.NRLIB from ${MID}/MULTSQFR.spad
+ @ (cd ${MID} ; echo ')co MULTSQFR.spad' | ${INTERPSYS} )
+
+@
+<<MULTSQFR.spad (SPAD from IN)>>=
+${MID}/MULTSQFR.spad: ${IN}/multsqfr.spad.pamphlet
+ @ echo 0 making ${MID}/MULTSQFR.spad from ${IN}/multsqfr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MULTSQFR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MULTSQFR MultivariateSquareFree" ${IN}/multsqfr.spad.pamphlet >MULTSQFR.spad )
+
+@
+<<multsqfr.spad.dvi (DOC from IN)>>=
+${DOC}/multsqfr.spad.dvi: ${IN}/multsqfr.spad.pamphlet
+ @ echo 0 making ${DOC}/multsqfr.spad.dvi from ${IN}/multsqfr.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/multsqfr.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} multsqfr.spad ; \
+ rm -f ${DOC}/multsqfr.spad.pamphlet ; \
+ rm -f ${DOC}/multsqfr.spad.tex ; \
+ rm -f ${DOC}/multsqfr.spad )
+
+@
+\subsection{naalgc.spad \cite{1}}
+<<naalgc.spad (SPAD from IN)>>=
+${MID}/naalgc.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/naalgc.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/naalgc.spad.pamphlet >naalgc.spad )
+
+@
+<<FINAALG-.o (O from NRLIB)>>=
+${OUT}/FINAALG-.o: ${MID}/FINAALG.NRLIB
+ @ echo 0 making ${OUT}/FINAALG-.o from ${MID}/FINAALG-.NRLIB
+ @ cp ${MID}/FINAALG-.NRLIB/code.o ${OUT}/FINAALG-.o
+
+@
+<<FINAALG-.NRLIB (NRLIB from MID)>>=
+${MID}/FINAALG-.NRLIB: ${OUT}/TYPE.o ${MID}/FINAALG.spad
+ @ echo 0 making ${MID}/FINAALG-.NRLIB from ${MID}/FINAALG.spad
+ @ (cd ${MID} ; echo ')co FINAALG.spad' | ${INTERPSYS} )
+
+@
+<<FINAALG.o (O from NRLIB)>>=
+${OUT}/FINAALG.o: ${MID}/FINAALG.NRLIB
+ @ echo 0 making ${OUT}/FINAALG.o from ${MID}/FINAALG.NRLIB
+ @ cp ${MID}/FINAALG.NRLIB/code.o ${OUT}/FINAALG.o
+
+@
+<<FINAALG.NRLIB (NRLIB from MID)>>=
+${MID}/FINAALG.NRLIB: ${MID}/FINAALG.spad
+ @ echo 0 making ${MID}/FINAALG.NRLIB from ${MID}/FINAALG.spad
+ @ (cd ${MID} ; echo ')co FINAALG.spad' | ${INTERPSYS} )
+
+@
+<<FINAALG.spad (SPAD from IN)>>=
+${MID}/FINAALG.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/FINAALG.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FINAALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FINAALG FiniteRankNonAssociativeAlgebra" ${IN}/naalgc.spad.pamphlet >FINAALG.spad )
+
+@
+<<FRNAALG-.o (O from NRLIB)>>=
+${OUT}/FRNAALG-.o: ${MID}/FRNAALG.NRLIB
+ @ echo 0 making ${OUT}/FRNAALG-.o from ${MID}/FRNAALG-.NRLIB
+ @ cp ${MID}/FRNAALG-.NRLIB/code.o ${OUT}/FRNAALG-.o
+
+@
+<<FRNAALG-.NRLIB (NRLIB from MID)>>=
+${MID}/FRNAALG-.NRLIB: ${OUT}/TYPE.o ${MID}/FRNAALG.spad
+ @ echo 0 making ${MID}/FRNAALG-.NRLIB from ${MID}/FRNAALG.spad
+ @ (cd ${MID} ; echo ')co FRNAALG.spad' | ${INTERPSYS} )
+
+@
+<<FRNAALG.o (O from NRLIB)>>=
+${OUT}/FRNAALG.o: ${MID}/FRNAALG.NRLIB
+ @ echo 0 making ${OUT}/FRNAALG.o from ${MID}/FRNAALG.NRLIB
+ @ cp ${MID}/FRNAALG.NRLIB/code.o ${OUT}/FRNAALG.o
+
+@
+<<FRNAALG.NRLIB (NRLIB from MID)>>=
+${MID}/FRNAALG.NRLIB: ${MID}/FRNAALG.spad
+ @ echo 0 making ${MID}/FRNAALG.NRLIB from ${MID}/FRNAALG.spad
+ @ (cd ${MID} ; echo ')co FRNAALG.spad' | ${INTERPSYS} )
+
+@
+<<FRNAALG.spad (SPAD from IN)>>=
+${MID}/FRNAALG.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/FRNAALG.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRNAALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FRNAALG FramedNonAssociativeAlgebra" ${IN}/naalgc.spad.pamphlet >FRNAALG.spad )
+
+@
+<<MONAD-.o (O from NRLIB)>>=
+${OUT}/MONAD-.o: ${MID}/MONAD.NRLIB
+ @ echo 0 making ${OUT}/MONAD-.o from ${MID}/MONAD-.NRLIB
+ @ cp ${MID}/MONAD-.NRLIB/code.o ${OUT}/MONAD-.o
+
+@
+<<MONAD-.NRLIB (NRLIB from MID)>>=
+${MID}/MONAD-.NRLIB: ${OUT}/TYPE.o ${MID}/MONAD.spad
+ @ echo 0 making ${MID}/MONAD-.NRLIB from ${MID}/MONAD.spad
+ @ (cd ${MID} ; echo ')co MONAD.spad' | ${INTERPSYS} )
+
+@
+<<MONAD.o (O from NRLIB)>>=
+${OUT}/MONAD.o: ${MID}/MONAD.NRLIB
+ @ echo 0 making ${OUT}/MONAD.o from ${MID}/MONAD.NRLIB
+ @ cp ${MID}/MONAD.NRLIB/code.o ${OUT}/MONAD.o
+
+@
+<<MONAD.NRLIB (NRLIB from MID)>>=
+${MID}/MONAD.NRLIB: ${MID}/MONAD.spad
+ @ echo 0 making ${MID}/MONAD.NRLIB from ${MID}/MONAD.spad
+ @ (cd ${MID} ; echo ')co MONAD.spad' | ${INTERPSYS} )
+
+@
+<<MONAD.spad (SPAD from IN)>>=
+${MID}/MONAD.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/MONAD.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONAD.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MONAD Monad" ${IN}/naalgc.spad.pamphlet >MONAD.spad )
+
+@
+<<MONADWU-.o (O from NRLIB)>>=
+${OUT}/MONADWU-.o: ${MID}/MONADWU.NRLIB
+ @ echo 0 making ${OUT}/MONADWU-.o from ${MID}/MONADWU-.NRLIB
+ @ cp ${MID}/MONADWU-.NRLIB/code.o ${OUT}/MONADWU-.o
+
+@
+<<MONADWU-.NRLIB (NRLIB from MID)>>=
+${MID}/MONADWU-.NRLIB: ${OUT}/TYPE.o ${MID}/MONADWU.spad
+ @ echo 0 making ${MID}/MONADWU-.NRLIB from ${MID}/MONADWU.spad
+ @ (cd ${MID} ; echo ')co MONADWU.spad' | ${INTERPSYS} )
+
+@
+<<MONADWU.o (O from NRLIB)>>=
+${OUT}/MONADWU.o: ${MID}/MONADWU.NRLIB
+ @ echo 0 making ${OUT}/MONADWU.o from ${MID}/MONADWU.NRLIB
+ @ cp ${MID}/MONADWU.NRLIB/code.o ${OUT}/MONADWU.o
+
+@
+<<MONADWU.NRLIB (NRLIB from MID)>>=
+${MID}/MONADWU.NRLIB: ${MID}/MONADWU.spad
+ @ echo 0 making ${MID}/MONADWU.NRLIB from ${MID}/MONADWU.spad
+ @ (cd ${MID} ; echo ')co MONADWU.spad' | ${INTERPSYS} )
+
+@
+<<MONADWU.spad (SPAD from IN)>>=
+${MID}/MONADWU.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/MONADWU.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MONADWU.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MONADWU MonadWithUnit" ${IN}/naalgc.spad.pamphlet >MONADWU.spad )
+
+@
+<<NAALG-.o (O from NRLIB)>>=
+${OUT}/NAALG-.o: ${MID}/NAALG.NRLIB
+ @ echo 0 making ${OUT}/NAALG-.o from ${MID}/NAALG-.NRLIB
+ @ cp ${MID}/NAALG-.NRLIB/code.o ${OUT}/NAALG-.o
+
+@
+<<NAALG-.NRLIB (NRLIB from MID)>>=
+${MID}/NAALG-.NRLIB: ${OUT}/TYPE.o ${MID}/NAALG.spad
+ @ echo 0 making ${MID}/NAALG-.NRLIB from ${MID}/NAALG.spad
+ @ (cd ${MID} ; echo ')co NAALG.spad' | ${INTERPSYS} )
+
+@
+<<NAALG.o (O from NRLIB)>>=
+${OUT}/NAALG.o: ${MID}/NAALG.NRLIB
+ @ echo 0 making ${OUT}/NAALG.o from ${MID}/NAALG.NRLIB
+ @ cp ${MID}/NAALG.NRLIB/code.o ${OUT}/NAALG.o
+
+@
+<<NAALG.NRLIB (NRLIB from MID)>>=
+${MID}/NAALG.NRLIB: ${MID}/NAALG.spad
+ @ echo 0 making ${MID}/NAALG.NRLIB from ${MID}/NAALG.spad
+ @ (cd ${MID} ; echo ')co NAALG.spad' | ${INTERPSYS} )
+
+@
+<<NAALG.spad (SPAD from IN)>>=
+${MID}/NAALG.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/NAALG.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category NAALG NonAssociativeAlgebra" ${IN}/naalgc.spad.pamphlet >NAALG.spad )
+
+@
+<<NARNG-.o (O from NRLIB)>>=
+${OUT}/NARNG-.o: ${MID}/NARNG.NRLIB
+ @ echo 0 making ${OUT}/NARNG-.o from ${MID}/NARNG-.NRLIB
+ @ cp ${MID}/NARNG-.NRLIB/code.o ${OUT}/NARNG-.o
+
+@
+<<NARNG-.NRLIB (NRLIB from MID)>>=
+${MID}/NARNG-.NRLIB: ${OUT}/TYPE.o ${MID}/NARNG.spad
+ @ echo 0 making ${MID}/NARNG-.NRLIB from ${MID}/NARNG.spad
+ @ (cd ${MID} ; echo ')co NARNG.spad' | ${INTERPSYS} )
+
+@
+<<NARNG.o (O from NRLIB)>>=
+${OUT}/NARNG.o: ${MID}/NARNG.NRLIB
+ @ echo 0 making ${OUT}/NARNG.o from ${MID}/NARNG.NRLIB
+ @ cp ${MID}/NARNG.NRLIB/code.o ${OUT}/NARNG.o
+
+@
+<<NARNG.NRLIB (NRLIB from MID)>>=
+${MID}/NARNG.NRLIB: ${MID}/NARNG.spad
+ @ echo 0 making ${MID}/NARNG.NRLIB from ${MID}/NARNG.spad
+ @ (cd ${MID} ; echo ')co NARNG.spad' | ${INTERPSYS} )
+
+@
+<<NARNG.spad (SPAD from IN)>>=
+${MID}/NARNG.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/NARNG.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NARNG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category NARNG NonAssociativeRng" ${IN}/naalgc.spad.pamphlet >NARNG.spad )
+
+@
+<<NASRING-.o (O from NRLIB)>>=
+${OUT}/NASRING-.o: ${MID}/NASRING.NRLIB
+ @ echo 0 making ${OUT}/NASRING-.o from ${MID}/NASRING-.NRLIB
+ @ cp ${MID}/NASRING-.NRLIB/code.o ${OUT}/NASRING-.o
+
+@
+<<NASRING-.NRLIB (NRLIB from MID)>>=
+${MID}/NASRING-.NRLIB: ${OUT}/TYPE.o ${MID}/NASRING.spad
+ @ echo 0 making ${MID}/NASRING-.NRLIB from ${MID}/NASRING.spad
+ @ (cd ${MID} ; echo ')co NASRING.spad' | ${INTERPSYS} )
+
+@
+<<NASRING.o (O from NRLIB)>>=
+${OUT}/NASRING.o: ${MID}/NASRING.NRLIB
+ @ echo 0 making ${OUT}/NASRING.o from ${MID}/NASRING.NRLIB
+ @ cp ${MID}/NASRING.NRLIB/code.o ${OUT}/NASRING.o
+
+@
+<<NASRING.NRLIB (NRLIB from MID)>>=
+${MID}/NASRING.NRLIB: ${MID}/NASRING.spad
+ @ echo 0 making ${MID}/NASRING.NRLIB from ${MID}/NASRING.spad
+ @ (cd ${MID} ; echo ')co NASRING.spad' | ${INTERPSYS} )
+
+@
+<<NASRING.spad (SPAD from IN)>>=
+${MID}/NASRING.spad: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${MID}/NASRING.spad from ${IN}/naalgc.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NASRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"category NASRING NonAssociativeRing" ${IN}/naalgc.spad.pamphlet >NASRING.spad )
+
+@
+<<naalgc.spad.dvi (DOC from IN)>>=
+${DOC}/naalgc.spad.dvi: ${IN}/naalgc.spad.pamphlet
+ @ echo 0 making ${DOC}/naalgc.spad.dvi from ${IN}/naalgc.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/naalgc.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} naalgc.spad ; \
+ rm -f ${DOC}/naalgc.spad.pamphlet ; \
+ rm -f ${DOC}/naalgc.spad.tex ; \
+ rm -f ${DOC}/naalgc.spad )
+
+@
+\subsection{naalg.spad \cite{1}}
+<<naalg.spad (SPAD from IN)>>=
+${MID}/naalg.spad: ${IN}/naalg.spad.pamphlet
+ @ echo 0 making ${MID}/naalg.spad from ${IN}/naalg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/naalg.spad.pamphlet >naalg.spad )
+
+@
+<<ALGPKG.o (O from NRLIB)>>=
+${OUT}/ALGPKG.o: ${MID}/ALGPKG.NRLIB
+ @ echo 0 making ${OUT}/ALGPKG.o from ${MID}/ALGPKG.NRLIB
+ @ cp ${MID}/ALGPKG.NRLIB/code.o ${OUT}/ALGPKG.o
+
+@
+<<ALGPKG.NRLIB (NRLIB from MID)>>=
+${MID}/ALGPKG.NRLIB: ${MID}/ALGPKG.spad
+ @ echo 0 making ${MID}/ALGPKG.NRLIB from ${MID}/ALGPKG.spad
+ @ (cd ${MID} ; echo ')co ALGPKG.spad' | ${INTERPSYS} )
+
+@
+<<ALGPKG.spad (SPAD from IN)>>=
+${MID}/ALGPKG.spad: ${IN}/naalg.spad.pamphlet
+ @ echo 0 making ${MID}/ALGPKG.spad from ${IN}/naalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGPKG.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ALGPKG AlgebraPackage" ${IN}/naalg.spad.pamphlet >ALGPKG.spad )
+
+@
+<<ALGSC.o (O from NRLIB)>>=
+${OUT}/ALGSC.o: ${MID}/ALGSC.NRLIB
+ @ echo 0 making ${OUT}/ALGSC.o from ${MID}/ALGSC.NRLIB
+ @ cp ${MID}/ALGSC.NRLIB/code.o ${OUT}/ALGSC.o
+
+@
+<<ALGSC.NRLIB (NRLIB from MID)>>=
+${MID}/ALGSC.NRLIB: ${MID}/ALGSC.spad
+ @ echo 0 making ${MID}/ALGSC.NRLIB from ${MID}/ALGSC.spad
+ @ (cd ${MID} ; echo ')co ALGSC.spad' | ${INTERPSYS} )
+
+@
+<<ALGSC.spad (SPAD from IN)>>=
+${MID}/ALGSC.spad: ${IN}/naalg.spad.pamphlet
+ @ echo 0 making ${MID}/ALGSC.spad from ${IN}/naalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ALGSC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ALGSC AlgebraGivenByStructuralConstants" ${IN}/naalg.spad.pamphlet >ALGSC.spad )
+
+@
+<<FRNAAF2.o (O from NRLIB)>>=
+${OUT}/FRNAAF2.o: ${MID}/FRNAAF2.NRLIB
+ @ echo 0 making ${OUT}/FRNAAF2.o from ${MID}/FRNAAF2.NRLIB
+ @ cp ${MID}/FRNAAF2.NRLIB/code.o ${OUT}/FRNAAF2.o
+
+@
+<<FRNAAF2.NRLIB (NRLIB from MID)>>=
+${MID}/FRNAAF2.NRLIB: ${MID}/FRNAAF2.spad
+ @ echo 0 making ${MID}/FRNAAF2.NRLIB from ${MID}/FRNAAF2.spad
+ @ (cd ${MID} ; echo ')co FRNAAF2.spad' | ${INTERPSYS} )
+
+@
+<<FRNAAF2.spad (SPAD from IN)>>=
+${MID}/FRNAAF2.spad: ${IN}/naalg.spad.pamphlet
+ @ echo 0 making ${MID}/FRNAAF2.spad from ${IN}/naalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRNAAF2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FRNAAF2 FramedNonAssociativeAlgebraFunctions2" ${IN}/naalg.spad.pamphlet >FRNAAF2.spad )
+
+@
+<<SCPKG.o (O from NRLIB)>>=
+${OUT}/SCPKG.o: ${MID}/SCPKG.NRLIB
+ @ echo 0 making ${OUT}/SCPKG.o from ${MID}/SCPKG.NRLIB
+ @ cp ${MID}/SCPKG.NRLIB/code.o ${OUT}/SCPKG.o
+
+@
+<<SCPKG.NRLIB (NRLIB from MID)>>=
+${MID}/SCPKG.NRLIB: ${MID}/SCPKG.spad
+ @ echo 0 making ${MID}/SCPKG.NRLIB from ${MID}/SCPKG.spad
+ @ (cd ${MID} ; echo ')co SCPKG.spad' | ${INTERPSYS} )
+
+@
+<<SCPKG.spad (SPAD from IN)>>=
+${MID}/SCPKG.spad: ${IN}/naalg.spad.pamphlet
+ @ echo 0 making ${MID}/SCPKG.spad from ${IN}/naalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SCPKG.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SCPKG StructuralConstantsPackage" ${IN}/naalg.spad.pamphlet >SCPKG.spad )
+
+@
+<<naalg.spad.dvi (DOC from IN)>>=
+${DOC}/naalg.spad.dvi: ${IN}/naalg.spad.pamphlet
+ @ echo 0 making ${DOC}/naalg.spad.dvi from ${IN}/naalg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/naalg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} naalg.spad ; \
+ rm -f ${DOC}/naalg.spad.pamphlet ; \
+ rm -f ${DOC}/naalg.spad.tex ; \
+ rm -f ${DOC}/naalg.spad )
+
+@
+\subsection{ndftip.as \cite{1}}
+<<ndftip.as (SPAD from IN)>>=
+${MID}/ndftip.as: ${IN}/ndftip.as.pamphlet
+ @ echo 0 making ${MID}/ndftip.as from ${IN}/ndftip.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ndftip.as.pamphlet >ndftip.as )
+
+@
+<<ndftip.as.dvi (DOC from IN)>>=
+${DOC}/ndftip.as.dvi: ${IN}/ndftip.as.pamphlet
+ @ echo 0 making ${DOC}/ndftip.as.dvi from ${IN}/ndftip.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ndftip.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ndftip.as ; \
+ rm -f ${DOC}/ndftip.as.pamphlet ; \
+ rm -f ${DOC}/ndftip.as.tex ; \
+ rm -f ${DOC}/ndftip.as )
+
+@
+\subsection{nepip.as \cite{1}}
+<<nepip.as (SPAD from IN)>>=
+${MID}/nepip.as: ${IN}/nepip.as.pamphlet
+ @ echo 0 making ${MID}/nepip.as from ${IN}/nepip.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nepip.as.pamphlet >nepip.as )
+
+@
+<<nepip.as.dvi (DOC from IN)>>=
+${DOC}/nepip.as.dvi: ${IN}/nepip.as.pamphlet
+ @ echo 0 making ${DOC}/nepip.as.dvi from ${IN}/nepip.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nepip.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nepip.as ; \
+ rm -f ${DOC}/nepip.as.pamphlet ; \
+ rm -f ${DOC}/nepip.as.tex ; \
+ rm -f ${DOC}/nepip.as )
+
+@
+\subsection{newdata.spad \cite{1}}
+<<newdata.spad (SPAD from IN)>>=
+${MID}/newdata.spad: ${IN}/newdata.spad.pamphlet
+ @ echo 0 making ${MID}/newdata.spad from ${IN}/newdata.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/newdata.spad.pamphlet >newdata.spad )
+
+@
+<<IPRNTPK.o (O from NRLIB)>>=
+${OUT}/IPRNTPK.o: ${MID}/IPRNTPK.NRLIB
+ @ echo 0 making ${OUT}/IPRNTPK.o from ${MID}/IPRNTPK.NRLIB
+ @ cp ${MID}/IPRNTPK.NRLIB/code.o ${OUT}/IPRNTPK.o
+
+@
+<<IPRNTPK.NRLIB (NRLIB from MID)>>=
+${MID}/IPRNTPK.NRLIB: ${MID}/IPRNTPK.spad
+ @ echo 0 making ${MID}/IPRNTPK.NRLIB from ${MID}/IPRNTPK.spad
+ @ (cd ${MID} ; echo ')co IPRNTPK.spad' | ${INTERPSYS} )
+
+@
+<<IPRNTPK.spad (SPAD from IN)>>=
+${MID}/IPRNTPK.spad: ${IN}/newdata.spad.pamphlet
+ @ echo 0 making ${MID}/IPRNTPK.spad from ${IN}/newdata.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IPRNTPK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IPRNTPK InternalPrintPackage" ${IN}/newdata.spad.pamphlet >IPRNTPK.spad )
+
+@
+<<SPLNODE.o (O from NRLIB)>>=
+${OUT}/SPLNODE.o: ${MID}/SPLNODE.NRLIB
+ @ echo 0 making ${OUT}/SPLNODE.o from ${MID}/SPLNODE.NRLIB
+ @ cp ${MID}/SPLNODE.NRLIB/code.o ${OUT}/SPLNODE.o
+
+@
+<<SPLNODE.NRLIB (NRLIB from MID)>>=
+${MID}/SPLNODE.NRLIB: ${MID}/SPLNODE.spad
+ @ echo 0 making ${MID}/SPLNODE.NRLIB from ${MID}/SPLNODE.spad
+ @ (cd ${MID} ; echo ')co SPLNODE.spad' | ${INTERPSYS} )
+
+@
+<<SPLNODE.spad (SPAD from IN)>>=
+${MID}/SPLNODE.spad: ${IN}/newdata.spad.pamphlet
+ @ echo 0 making ${MID}/SPLNODE.spad from ${IN}/newdata.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SPLNODE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SPLNODE SplittingNode" ${IN}/newdata.spad.pamphlet >SPLNODE.spad )
+
+@
+<<SPLTREE.o (O from NRLIB)>>=
+${OUT}/SPLTREE.o: ${MID}/SPLTREE.NRLIB
+ @ echo 0 making ${OUT}/SPLTREE.o from ${MID}/SPLTREE.NRLIB
+ @ cp ${MID}/SPLTREE.NRLIB/code.o ${OUT}/SPLTREE.o
+
+@
+<<SPLTREE.NRLIB (NRLIB from MID)>>=
+${MID}/SPLTREE.NRLIB: ${MID}/SPLTREE.spad
+ @ echo 0 making ${MID}/SPLTREE.NRLIB from ${MID}/SPLTREE.spad
+ @ (cd ${MID} ; echo ')co SPLTREE.spad' | ${INTERPSYS} )
+
+@
+<<SPLTREE.spad (SPAD from IN)>>=
+${MID}/SPLTREE.spad: ${IN}/newdata.spad.pamphlet
+ @ echo 0 making ${MID}/SPLTREE.spad from ${IN}/newdata.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SPLTREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SPLTREE SplittingTree" ${IN}/newdata.spad.pamphlet >SPLTREE.spad )
+
+@
+<<TBCMPPK.o (O from NRLIB)>>=
+${OUT}/TBCMPPK.o: ${MID}/TBCMPPK.NRLIB
+ @ echo 0 making ${OUT}/TBCMPPK.o from ${MID}/TBCMPPK.NRLIB
+ @ cp ${MID}/TBCMPPK.NRLIB/code.o ${OUT}/TBCMPPK.o
+
+@
+<<TBCMPPK.NRLIB (NRLIB from MID)>>=
+${MID}/TBCMPPK.NRLIB: ${MID}/TBCMPPK.spad
+ @ echo 0 making ${MID}/TBCMPPK.NRLIB from ${MID}/TBCMPPK.spad
+ @ (cd ${MID} ; echo ')co TBCMPPK.spad' | ${INTERPSYS} )
+
+@
+<<TBCMPPK.spad (SPAD from IN)>>=
+${MID}/TBCMPPK.spad: ${IN}/newdata.spad.pamphlet
+ @ echo 0 making ${MID}/TBCMPPK.spad from ${IN}/newdata.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TBCMPPK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TBCMPPK TabulatedComputationPackage" ${IN}/newdata.spad.pamphlet >TBCMPPK.spad )
+
+@
+<<newdata.spad.dvi (DOC from IN)>>=
+${DOC}/newdata.spad.dvi: ${IN}/newdata.spad.pamphlet
+ @ echo 0 making ${DOC}/newdata.spad.dvi from ${IN}/newdata.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/newdata.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} newdata.spad ; \
+ rm -f ${DOC}/newdata.spad.pamphlet ; \
+ rm -f ${DOC}/newdata.spad.tex ; \
+ rm -f ${DOC}/newdata.spad )
+
+@
+\subsection{newpoint.spad \cite{1}}
+<<newpoint.spad (SPAD from IN)>>=
+${MID}/newpoint.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/newpoint.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/newpoint.spad.pamphlet >newpoint.spad )
+
+@
+<<COMPPROP.o (O from NRLIB)>>=
+${OUT}/COMPPROP.o: ${MID}/COMPPROP.NRLIB
+ @ echo 0 making ${OUT}/COMPPROP.o from ${MID}/COMPPROP.NRLIB
+ @ cp ${MID}/COMPPROP.NRLIB/code.o ${OUT}/COMPPROP.o
+
+@
+<<COMPPROP.NRLIB (NRLIB from MID)>>=
+${MID}/COMPPROP.NRLIB: ${MID}/COMPPROP.spad
+ @ echo 0 making ${MID}/COMPPROP.NRLIB from ${MID}/COMPPROP.spad
+ @ (cd ${MID} ; echo ')co COMPPROP.spad' | ${INTERPSYS} )
+
+@
+<<COMPPROP.spad (SPAD from IN)>>=
+${MID}/COMPPROP.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/COMPPROP.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMPPROP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain COMPPROP SubSpaceComponentProperty" ${IN}/newpoint.spad.pamphlet >COMPPROP.spad )
+
+@
+<<SUBSPACE.o (O from NRLIB)>>=
+${OUT}/SUBSPACE.o: ${MID}/SUBSPACE.NRLIB
+ @ echo 0 making ${OUT}/SUBSPACE.o from ${MID}/SUBSPACE.NRLIB
+ @ cp ${MID}/SUBSPACE.NRLIB/code.o ${OUT}/SUBSPACE.o
+
+@
+<<SUBSPACE.NRLIB (NRLIB from MID)>>=
+${MID}/SUBSPACE.NRLIB: ${MID}/SUBSPACE.spad
+ @ echo 0 making ${MID}/SUBSPACE.NRLIB from ${MID}/SUBSPACE.spad
+ @ (cd ${MID} ; echo ')co SUBSPACE.spad' | ${INTERPSYS} )
+
+@
+<<SUBSPACE.spad (SPAD from IN)>>=
+${MID}/SUBSPACE.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/SUBSPACE.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUBSPACE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SUBSPACE SubSpace" ${IN}/newpoint.spad.pamphlet >SUBSPACE.spad )
+
+@
+<<POINT.o (O from NRLIB)>>=
+${OUT}/POINT.o: ${MID}/POINT.NRLIB
+ @ echo 0 making ${OUT}/POINT.o from ${MID}/POINT.NRLIB
+ @ cp ${MID}/POINT.NRLIB/code.o ${OUT}/POINT.o
+
+@
+<<POINT.NRLIB (NRLIB from MID)>>=
+${MID}/POINT.NRLIB: ${MID}/POINT.spad
+ @ echo 0 making ${MID}/POINT.NRLIB from ${MID}/POINT.spad
+ @ (cd ${MID} ; echo ')co POINT.spad' | ${INTERPSYS} )
+
+@
+<<POINT.spad (SPAD from IN)>>=
+${MID}/POINT.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/POINT.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain POINT Point" ${IN}/newpoint.spad.pamphlet >POINT.spad )
+
+@
+<<PTCAT.o (O from NRLIB)>>=
+${OUT}/PTCAT.o: ${MID}/PTCAT.NRLIB
+ @ echo 0 making ${OUT}/PTCAT.o from ${MID}/PTCAT.NRLIB
+ @ cp ${MID}/PTCAT.NRLIB/code.o ${OUT}/PTCAT.o
+
+@
+<<PTCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PTCAT.NRLIB: ${MID}/PTCAT.spad
+ @ echo 0 making ${MID}/PTCAT.NRLIB from ${MID}/PTCAT.spad
+ @ (cd ${MID} ; echo ')co PTCAT.spad' | ${INTERPSYS} )
+
+@
+<<PTCAT.spad (SPAD from IN)>>=
+${MID}/PTCAT.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/PTCAT.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PTCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PTCAT PointCategory" ${IN}/newpoint.spad.pamphlet >PTCAT.spad )
+
+@
+<<PTFUNC2.o (O from NRLIB)>>=
+${OUT}/PTFUNC2.o: ${MID}/PTFUNC2.NRLIB
+ @ echo 0 making ${OUT}/PTFUNC2.o from ${MID}/PTFUNC2.NRLIB
+ @ cp ${MID}/PTFUNC2.NRLIB/code.o ${OUT}/PTFUNC2.o
+
+@
+<<PTFUNC2.NRLIB (NRLIB from MID)>>=
+${MID}/PTFUNC2.NRLIB: ${MID}/PTFUNC2.spad
+ @ echo 0 making ${MID}/PTFUNC2.NRLIB from ${MID}/PTFUNC2.spad
+ @ (cd ${MID} ; echo ')co PTFUNC2.spad' | ${INTERPSYS} )
+
+@
+<<PTFUNC2.spad (SPAD from IN)>>=
+${MID}/PTFUNC2.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/PTFUNC2.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PTFUNC2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PTFUNC2 PointFunctions2" ${IN}/newpoint.spad.pamphlet >PTFUNC2.spad )
+
+@
+<<PTPACK.o (O from NRLIB)>>=
+${OUT}/PTPACK.o: ${MID}/PTPACK.NRLIB
+ @ echo 0 making ${OUT}/PTPACK.o from ${MID}/PTPACK.NRLIB
+ @ cp ${MID}/PTPACK.NRLIB/code.o ${OUT}/PTPACK.o
+
+@
+<<PTPACK.NRLIB (NRLIB from MID)>>=
+${MID}/PTPACK.NRLIB: ${MID}/PTPACK.spad
+ @ echo 0 making ${MID}/PTPACK.NRLIB from ${MID}/PTPACK.spad
+ @ (cd ${MID} ; echo ')co PTPACK.spad' | ${INTERPSYS} )
+
+@
+<<PTPACK.spad (SPAD from IN)>>=
+${MID}/PTPACK.spad: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${MID}/PTPACK.spad from ${IN}/newpoint.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PTPACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PTPACK PointPackage" ${IN}/newpoint.spad.pamphlet >PTPACK.spad )
+
+@
+<<newpoint.spad.dvi (DOC from IN)>>=
+${DOC}/newpoint.spad.dvi: ${IN}/newpoint.spad.pamphlet
+ @ echo 0 making ${DOC}/newpoint.spad.dvi from ${IN}/newpoint.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/newpoint.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} newpoint.spad ; \
+ rm -f ${DOC}/newpoint.spad.pamphlet ; \
+ rm -f ${DOC}/newpoint.spad.tex ; \
+ rm -f ${DOC}/newpoint.spad )
+
+@
+\subsection{newpoly.spad \cite{1}}
+<<newpoly.spad (SPAD from IN)>>=
+${MID}/newpoly.spad: ${IN}/newpoly.spad.pamphlet
+ @ echo 0 making ${MID}/newpoly.spad from ${IN}/newpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/newpoly.spad.pamphlet >newpoly.spad )
+
+@
+<<NSMP.o (O from NRLIB)>>=
+${OUT}/NSMP.o: ${MID}/NSMP.NRLIB
+ @ echo 0 making ${OUT}/NSMP.o from ${MID}/NSMP.NRLIB
+ @ cp ${MID}/NSMP.NRLIB/code.o ${OUT}/NSMP.o
+
+@
+<<NSMP.NRLIB (NRLIB from MID)>>=
+${MID}/NSMP.NRLIB: ${MID}/NSMP.spad
+ @ echo 0 making ${MID}/NSMP.NRLIB from ${MID}/NSMP.spad
+ @ (cd ${MID} ; echo ')co NSMP.spad' | ${INTERPSYS} )
+
+@
+<<NSMP.spad (SPAD from IN)>>=
+${MID}/NSMP.spad: ${IN}/newpoly.spad.pamphlet
+ @ echo 0 making ${MID}/NSMP.spad from ${IN}/newpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NSMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain NSMP NewSparseMultivariatePolynomial" ${IN}/newpoly.spad.pamphlet >NSMP.spad )
+
+@
+<<NSUP.o (O from NRLIB)>>=
+${OUT}/NSUP.o: ${MID}/NSUP.NRLIB
+ @ echo 0 making ${OUT}/NSUP.o from ${MID}/NSUP.NRLIB
+ @ cp ${MID}/NSUP.NRLIB/code.o ${OUT}/NSUP.o
+
+@
+<<NSUP.NRLIB (NRLIB from MID)>>=
+${MID}/NSUP.NRLIB: ${MID}/NSUP.spad
+ @ echo 0 making ${MID}/NSUP.NRLIB from ${MID}/NSUP.spad
+ @ (cd ${MID} ; echo ')co NSUP.spad' | ${INTERPSYS} )
+
+@
+<<NSUP.spad (SPAD from IN)>>=
+${MID}/NSUP.spad: ${IN}/newpoly.spad.pamphlet
+ @ echo 0 making ${MID}/NSUP.spad from ${IN}/newpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NSUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain NSUP NewSparseUnivariatePolynomial" ${IN}/newpoly.spad.pamphlet >NSUP.spad )
+
+@
+<<NSUP2.o (O from NRLIB)>>=
+${OUT}/NSUP2.o: ${MID}/NSUP2.NRLIB
+ @ echo 0 making ${OUT}/NSUP2.o from ${MID}/NSUP2.NRLIB
+ @ cp ${MID}/NSUP2.NRLIB/code.o ${OUT}/NSUP2.o
+
+@
+<<NSUP2.NRLIB (NRLIB from MID)>>=
+${MID}/NSUP2.NRLIB: ${MID}/NSUP2.spad
+ @ echo 0 making ${MID}/NSUP2.NRLIB from ${MID}/NSUP2.spad
+ @ (cd ${MID} ; echo ')co NSUP2.spad' | ${INTERPSYS} )
+
+@
+<<NSUP2.spad (SPAD from IN)>>=
+${MID}/NSUP2.spad: ${IN}/newpoly.spad.pamphlet
+ @ echo 0 making ${MID}/NSUP2.spad from ${IN}/newpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NSUP2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NSUP2 NewSparseUnivariatePolynomialFunctions2" ${IN}/newpoly.spad.pamphlet >NSUP2.spad )
+
+@
+<<RPOLCAT-.o (O from NRLIB)>>=
+${OUT}/RPOLCAT-.o: ${MID}/RPOLCAT.NRLIB
+ @ echo 0 making ${OUT}/RPOLCAT-.o from ${MID}/RPOLCAT-.NRLIB
+ @ cp ${MID}/RPOLCAT-.NRLIB/code.o ${OUT}/RPOLCAT-.o
+
+@
+<<RPOLCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/RPOLCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/RPOLCAT.spad
+ @ echo 0 making ${MID}/RPOLCAT-.NRLIB from ${MID}/RPOLCAT.spad
+ @ (cd ${MID} ; echo ')co RPOLCAT.spad' | ${INTERPSYS} )
+
+@
+<<RPOLCAT.o (O from NRLIB)>>=
+${OUT}/RPOLCAT.o: ${MID}/RPOLCAT.NRLIB
+ @ echo 0 making ${OUT}/RPOLCAT.o from ${MID}/RPOLCAT.NRLIB
+ @ cp ${MID}/RPOLCAT.NRLIB/code.o ${OUT}/RPOLCAT.o
+
+@
+<<RPOLCAT.NRLIB (NRLIB from MID)>>=
+${MID}/RPOLCAT.NRLIB: ${MID}/RPOLCAT.spad
+ @ echo 0 making ${MID}/RPOLCAT.NRLIB from ${MID}/RPOLCAT.spad
+ @ (cd ${MID} ; echo ')co RPOLCAT.spad' | ${INTERPSYS} )
+
+@
+<<RPOLCAT.spad (SPAD from IN)>>=
+${MID}/RPOLCAT.spad: ${IN}/newpoly.spad.pamphlet
+ @ echo 0 making ${MID}/RPOLCAT.spad from ${IN}/newpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RPOLCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RPOLCAT RecursivePolynomialCategory" ${IN}/newpoly.spad.pamphlet >RPOLCAT.spad )
+
+@
+<<newpoly.spad.dvi (DOC from IN)>>=
+${DOC}/newpoly.spad.dvi: ${IN}/newpoly.spad.pamphlet
+ @ echo 0 making ${DOC}/newpoly.spad.dvi from ${IN}/newpoly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/newpoly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} newpoly.spad ; \
+ rm -f ${DOC}/newpoly.spad.pamphlet ; \
+ rm -f ${DOC}/newpoly.spad.tex ; \
+ rm -f ${DOC}/newpoly.spad )
+
+@
+\subsection{nlinsol.spad \cite{1}}
+<<nlinsol.spad (SPAD from IN)>>=
+${MID}/nlinsol.spad: ${IN}/nlinsol.spad.pamphlet
+ @ echo 0 making ${MID}/nlinsol.spad from ${IN}/nlinsol.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nlinsol.spad.pamphlet >nlinsol.spad )
+
+@
+<<NLINSOL.o (O from NRLIB)>>=
+${OUT}/NLINSOL.o: ${MID}/NLINSOL.NRLIB
+ @ echo 0 making ${OUT}/NLINSOL.o from ${MID}/NLINSOL.NRLIB
+ @ cp ${MID}/NLINSOL.NRLIB/code.o ${OUT}/NLINSOL.o
+
+@
+<<NLINSOL.NRLIB (NRLIB from MID)>>=
+${MID}/NLINSOL.NRLIB: ${MID}/NLINSOL.spad
+ @ echo 0 making ${MID}/NLINSOL.NRLIB from ${MID}/NLINSOL.spad
+ @ (cd ${MID} ; echo ')co NLINSOL.spad' | ${INTERPSYS} )
+
+@
+<<NLINSOL.spad (SPAD from IN)>>=
+${MID}/NLINSOL.spad: ${IN}/nlinsol.spad.pamphlet
+ @ echo 0 making ${MID}/NLINSOL.spad from ${IN}/nlinsol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NLINSOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NLINSOL NonLinearSolvePackage" ${IN}/nlinsol.spad.pamphlet >NLINSOL.spad )
+
+@
+<<RETSOL.o (O from NRLIB)>>=
+${OUT}/RETSOL.o: ${MID}/RETSOL.NRLIB
+ @ echo 0 making ${OUT}/RETSOL.o from ${MID}/RETSOL.NRLIB
+ @ cp ${MID}/RETSOL.NRLIB/code.o ${OUT}/RETSOL.o
+
+@
+<<RETSOL.NRLIB (NRLIB from MID)>>=
+${MID}/RETSOL.NRLIB: ${MID}/RETSOL.spad
+ @ echo 0 making ${MID}/RETSOL.NRLIB from ${MID}/RETSOL.spad
+ @ (cd ${MID} ; echo ')co RETSOL.spad' | ${INTERPSYS} )
+
+@
+<<RETSOL.spad (SPAD from IN)>>=
+${MID}/RETSOL.spad: ${IN}/nlinsol.spad.pamphlet
+ @ echo 0 making ${MID}/RETSOL.spad from ${IN}/nlinsol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RETSOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RETSOL RetractSolvePackage" ${IN}/nlinsol.spad.pamphlet >RETSOL.spad )
+
+@
+<<nlinsol.spad.dvi (DOC from IN)>>=
+${DOC}/nlinsol.spad.dvi: ${IN}/nlinsol.spad.pamphlet
+ @ echo 0 making ${DOC}/nlinsol.spad.dvi from ${IN}/nlinsol.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nlinsol.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nlinsol.spad ; \
+ rm -f ${DOC}/nlinsol.spad.pamphlet ; \
+ rm -f ${DOC}/nlinsol.spad.tex ; \
+ rm -f ${DOC}/nlinsol.spad )
+
+@
+\subsection{nlode.spad \cite{1}}
+<<nlode.spad (SPAD from IN)>>=
+${MID}/nlode.spad: ${IN}/nlode.spad.pamphlet
+ @ echo 0 making ${MID}/nlode.spad from ${IN}/nlode.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nlode.spad.pamphlet >nlode.spad )
+
+@
+<<NODE1.o (O from NRLIB)>>=
+${OUT}/NODE1.o: ${MID}/NODE1.NRLIB
+ @ echo 0 making ${OUT}/NODE1.o from ${MID}/NODE1.NRLIB
+ @ cp ${MID}/NODE1.NRLIB/code.o ${OUT}/NODE1.o
+
+@
+<<NODE1.NRLIB (NRLIB from MID)>>=
+${MID}/NODE1.NRLIB: ${MID}/NODE1.spad
+ @ echo 0 making ${MID}/NODE1.NRLIB from ${MID}/NODE1.spad
+ @ (cd ${MID} ; echo ')co NODE1.spad' | ${INTERPSYS} )
+
+@
+<<NODE1.spad (SPAD from IN)>>=
+${MID}/NODE1.spad: ${IN}/nlode.spad.pamphlet
+ @ echo 0 making ${MID}/NODE1.spad from ${IN}/nlode.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NODE1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NODE1 NonLinearFirstOrderODESolver" ${IN}/nlode.spad.pamphlet >NODE1.spad )
+
+@
+<<nlode.spad.dvi (DOC from IN)>>=
+${DOC}/nlode.spad.dvi: ${IN}/nlode.spad.pamphlet
+ @ echo 0 making ${DOC}/nlode.spad.dvi from ${IN}/nlode.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nlode.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nlode.spad ; \
+ rm -f ${DOC}/nlode.spad.pamphlet ; \
+ rm -f ${DOC}/nlode.spad.tex ; \
+ rm -f ${DOC}/nlode.spad )
+
+@
+\subsection{noptip.as \cite{1}}
+<<noptip.as (SPAD from IN)>>=
+${MID}/noptip.as: ${IN}/noptip.as.pamphlet
+ @ echo 0 making ${MID}/noptip.as from ${IN}/noptip.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/noptip.as.pamphlet >noptip.as )
+
+@
+<<noptip.as.dvi (DOC from IN)>>=
+${DOC}/noptip.as.dvi: ${IN}/noptip.as.pamphlet
+ @ echo 0 making ${DOC}/noptip.as.dvi from ${IN}/noptip.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/noptip.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} noptip.as ; \
+ rm -f ${DOC}/noptip.as.pamphlet ; \
+ rm -f ${DOC}/noptip.as.tex ; \
+ rm -f ${DOC}/noptip.as )
+
+@
+\subsection{npcoef.spad \cite{1}}
+<<npcoef.spad (SPAD from IN)>>=
+${MID}/npcoef.spad: ${IN}/npcoef.spad.pamphlet
+ @ echo 0 making ${MID}/npcoef.spad from ${IN}/npcoef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/npcoef.spad.pamphlet >npcoef.spad )
+
+@
+<<NPCOEF.o (O from NRLIB)>>=
+${OUT}/NPCOEF.o: ${MID}/NPCOEF.NRLIB
+ @ echo 0 making ${OUT}/NPCOEF.o from ${MID}/NPCOEF.NRLIB
+ @ cp ${MID}/NPCOEF.NRLIB/code.o ${OUT}/NPCOEF.o
+
+@
+<<NPCOEF.NRLIB (NRLIB from MID)>>=
+${MID}/NPCOEF.NRLIB: ${MID}/NPCOEF.spad
+ @ echo 0 making ${MID}/NPCOEF.NRLIB from ${MID}/NPCOEF.spad
+ @ (cd ${MID} ; echo ')co NPCOEF.spad' | ${INTERPSYS} )
+
+@
+<<NPCOEF.spad (SPAD from IN)>>=
+${MID}/NPCOEF.spad: ${IN}/npcoef.spad.pamphlet
+ @ echo 0 making ${MID}/NPCOEF.spad from ${IN}/npcoef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NPCOEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NPCOEF NPCoef" ${IN}/npcoef.spad.pamphlet >NPCOEF.spad )
+
+@
+<<npcoef.spad.dvi (DOC from IN)>>=
+${DOC}/npcoef.spad.dvi: ${IN}/npcoef.spad.pamphlet
+ @ echo 0 making ${DOC}/npcoef.spad.dvi from ${IN}/npcoef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/npcoef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} npcoef.spad ; \
+ rm -f ${DOC}/npcoef.spad.pamphlet ; \
+ rm -f ${DOC}/npcoef.spad.tex ; \
+ rm -f ${DOC}/npcoef.spad )
+
+@
+\subsection{nqip.as \cite{1}}
+<<nqip.as (SPAD from IN)>>=
+${MID}/nqip.as: ${IN}/nqip.as.pamphlet
+ @ echo 0 making ${MID}/nqip.as from ${IN}/nqip.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nqip.as.pamphlet >nqip.as )
+
+@
+<<nqip.as.dvi (DOC from IN)>>=
+${DOC}/nqip.as.dvi: ${IN}/nqip.as.pamphlet
+ @ echo 0 making ${DOC}/nqip.as.dvi from ${IN}/nqip.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nqip.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nqip.as ; \
+ rm -f ${DOC}/nqip.as.pamphlet ; \
+ rm -f ${DOC}/nqip.as.tex ; \
+ rm -f ${DOC}/nqip.as )
+
+@
+\subsection{nrc.as \cite{1}}
+<<nrc.as (SPAD from IN)>>=
+${MID}/nrc.as: ${IN}/nrc.as.pamphlet
+ @ echo 0 making ${MID}/nrc.as from ${IN}/nrc.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nrc.as.pamphlet >nrc.as )
+
+@
+<<nrc.as.dvi (DOC from IN)>>=
+${DOC}/nrc.as.dvi: ${IN}/nrc.as.pamphlet
+ @ echo 0 making ${DOC}/nrc.as.dvi from ${IN}/nrc.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nrc.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nrc.as ; \
+ rm -f ${DOC}/nrc.as.pamphlet ; \
+ rm -f ${DOC}/nrc.as.tex ; \
+ rm -f ${DOC}/nrc.as )
+
+@
+\subsection{nregset.spad \cite{1}}
+<<nregset.spad (SPAD from IN)>>=
+${MID}/nregset.spad: ${IN}/nregset.spad.pamphlet
+ @ echo 0 making ${MID}/nregset.spad from ${IN}/nregset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nregset.spad.pamphlet >nregset.spad )
+
+@
+<<nregset.spad.dvi (DOC from IN)>>=
+${DOC}/nregset.spad.dvi: ${IN}/nregset.spad.pamphlet
+ @ echo 0 making ${DOC}/nregset.spad.dvi from ${IN}/nregset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nregset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nregset.spad ; \
+ rm -f ${DOC}/nregset.spad.pamphlet ; \
+ rm -f ${DOC}/nregset.spad.tex ; \
+ rm -f ${DOC}/nregset.spad )
+
+@
+\subsection{nsfip.as \cite{1}}
+<<nsfip.as (SPAD from IN)>>=
+${MID}/nsfip.as: ${IN}/nsfip.as.pamphlet
+ @ echo 0 making ${MID}/nsfip.as from ${IN}/nsfip.as.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nsfip.as.pamphlet >nsfip.as )
+
+@
+<<nsfip.as.dvi (DOC from IN)>>=
+${DOC}/nsfip.as.dvi: ${IN}/nsfip.as.pamphlet
+ @ echo 0 making ${DOC}/nsfip.as.dvi from ${IN}/nsfip.as.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nsfip.as.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nsfip.as ; \
+ rm -f ${DOC}/nsfip.as.pamphlet ; \
+ rm -f ${DOC}/nsfip.as.tex ; \
+ rm -f ${DOC}/nsfip.as )
+
+@
+\subsection{nsregset.spad \cite{1}}
+<<nsregset.spad (SPAD from IN)>>=
+${MID}/nsregset.spad: ${IN}/nsregset.spad.pamphlet
+ @ echo 0 making ${MID}/nsregset.spad from ${IN}/nsregset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/nsregset.spad.pamphlet >nsregset.spad )
+
+@
+<<nsregset.spad.dvi (DOC from IN)>>=
+${DOC}/nsregset.spad.dvi: ${IN}/nsregset.spad.pamphlet
+ @ echo 0 making ${DOC}/nsregset.spad.dvi from ${IN}/nsregset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/nsregset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} nsregset.spad ; \
+ rm -f ${DOC}/nsregset.spad.pamphlet ; \
+ rm -f ${DOC}/nsregset.spad.tex ; \
+ rm -f ${DOC}/nsregset.spad )
+
+@
+\subsection{numeigen.spad \cite{1}}
+<<numeigen.spad (SPAD from IN)>>=
+${MID}/numeigen.spad: ${IN}/numeigen.spad.pamphlet
+ @ echo 0 making ${MID}/numeigen.spad from ${IN}/numeigen.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/numeigen.spad.pamphlet >numeigen.spad )
+
+@
+<<INEP.o (O from NRLIB)>>=
+${OUT}/INEP.o: ${MID}/INEP.NRLIB
+ @ echo 0 making ${OUT}/INEP.o from ${MID}/INEP.NRLIB
+ @ cp ${MID}/INEP.NRLIB/code.o ${OUT}/INEP.o
+
+@
+<<INEP.NRLIB (NRLIB from MID)>>=
+${MID}/INEP.NRLIB: ${MID}/INEP.spad
+ @ echo 0 making ${MID}/INEP.NRLIB from ${MID}/INEP.spad
+ @ (cd ${MID} ; echo ')co INEP.spad' | ${INTERPSYS} )
+
+@
+<<INEP.spad (SPAD from IN)>>=
+${MID}/INEP.spad: ${IN}/numeigen.spad.pamphlet
+ @ echo 0 making ${MID}/INEP.spad from ${IN}/numeigen.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INEP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INEP InnerNumericEigenPackage" ${IN}/numeigen.spad.pamphlet >INEP.spad )
+
+@
+<<NCEP.o (O from NRLIB)>>=
+${OUT}/NCEP.o: ${MID}/NCEP.NRLIB
+ @ echo 0 making ${OUT}/NCEP.o from ${MID}/NCEP.NRLIB
+ @ cp ${MID}/NCEP.NRLIB/code.o ${OUT}/NCEP.o
+
+@
+<<NCEP.NRLIB (NRLIB from MID)>>=
+${MID}/NCEP.NRLIB: ${MID}/NCEP.spad
+ @ echo 0 making ${MID}/NCEP.NRLIB from ${MID}/NCEP.spad
+ @ (cd ${MID} ; echo ')co NCEP.spad' | ${INTERPSYS} )
+
+@
+<<NCEP.spad (SPAD from IN)>>=
+${MID}/NCEP.spad: ${IN}/numeigen.spad.pamphlet
+ @ echo 0 making ${MID}/NCEP.spad from ${IN}/numeigen.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NCEP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NCEP NumericComplexEigenPackage" ${IN}/numeigen.spad.pamphlet >NCEP.spad )
+
+@
+<<NREP.o (O from NRLIB)>>=
+${OUT}/NREP.o: ${MID}/NREP.NRLIB
+ @ echo 0 making ${OUT}/NREP.o from ${MID}/NREP.NRLIB
+ @ cp ${MID}/NREP.NRLIB/code.o ${OUT}/NREP.o
+
+@
+<<NREP.NRLIB (NRLIB from MID)>>=
+${MID}/NREP.NRLIB: ${MID}/NREP.spad
+ @ echo 0 making ${MID}/NREP.NRLIB from ${MID}/NREP.spad
+ @ (cd ${MID} ; echo ')co NREP.spad' | ${INTERPSYS} )
+
+@
+<<NREP.spad (SPAD from IN)>>=
+${MID}/NREP.spad: ${IN}/numeigen.spad.pamphlet
+ @ echo 0 making ${MID}/NREP.spad from ${IN}/numeigen.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NREP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NREP NumericRealEigenPackage" ${IN}/numeigen.spad.pamphlet >NREP.spad )
+
+@
+<<numeigen.spad.dvi (DOC from IN)>>=
+${DOC}/numeigen.spad.dvi: ${IN}/numeigen.spad.pamphlet
+ @ echo 0 making ${DOC}/numeigen.spad.dvi from ${IN}/numeigen.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/numeigen.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} numeigen.spad ; \
+ rm -f ${DOC}/numeigen.spad.pamphlet ; \
+ rm -f ${DOC}/numeigen.spad.tex ; \
+ rm -f ${DOC}/numeigen.spad )
+
+@
+\subsection{numeric.spad \cite{1}}
+<<numeric.spad (SPAD from IN)>>=
+${MID}/numeric.spad: ${IN}/numeric.spad.pamphlet
+ @ echo 0 making ${MID}/numeric.spad from ${IN}/numeric.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/numeric.spad.pamphlet >numeric.spad )
+
+@
+<<DRAWHACK.o (O from NRLIB)>>=
+${OUT}/DRAWHACK.o: ${MID}/DRAWHACK.NRLIB
+ @ echo 0 making ${OUT}/DRAWHACK.o from ${MID}/DRAWHACK.NRLIB
+ @ cp ${MID}/DRAWHACK.NRLIB/code.o ${OUT}/DRAWHACK.o
+
+@
+<<DRAWHACK.NRLIB (NRLIB from MID)>>=
+${MID}/DRAWHACK.NRLIB: ${OUT}/CFCAT.o ${MID}/DRAWHACK.spad
+ @ echo 0 making ${MID}/DRAWHACK.NRLIB from ${MID}/DRAWHACK.spad
+ @ (cd ${MID} ; echo ')co DRAWHACK.spad' | ${INTERPSYS} )
+
+@
+<<DRAWHACK.spad (SPAD from IN)>>=
+${MID}/DRAWHACK.spad: ${IN}/numeric.spad.pamphlet
+ @ echo 0 making ${MID}/DRAWHACK.spad from ${IN}/numeric.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DRAWHACK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DRAWHACK DrawNumericHack" ${IN}/numeric.spad.pamphlet >DRAWHACK.spad )
+
+@
+<<NUMERIC.o (O from NRLIB)>>=
+${OUT}/NUMERIC.o: ${MID}/NUMERIC.NRLIB
+ @ echo 0 making ${OUT}/NUMERIC.o from ${MID}/NUMERIC.NRLIB
+ @ cp ${MID}/NUMERIC.NRLIB/code.o ${OUT}/NUMERIC.o
+
+@
+<<NUMERIC.NRLIB (NRLIB from MID)>>=
+${MID}/NUMERIC.NRLIB: ${MID}/NUMERIC.spad
+ @ echo 0 making ${MID}/NUMERIC.NRLIB from ${MID}/NUMERIC.spad
+ @ (cd ${MID} ; echo ')co NUMERIC.spad' | ${INTERPSYS} )
+
+@
+<<NUMERIC.spad (SPAD from IN)>>=
+${MID}/NUMERIC.spad: ${IN}/numeric.spad.pamphlet
+ @ echo 0 making ${MID}/NUMERIC.spad from ${IN}/numeric.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NUMERIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NUMERIC Numeric" ${IN}/numeric.spad.pamphlet >NUMERIC.spad )
+
+@
+<<numeric.spad.dvi (DOC from IN)>>=
+${DOC}/numeric.spad.dvi: ${IN}/numeric.spad.pamphlet
+ @ echo 0 making ${DOC}/numeric.spad.dvi from ${IN}/numeric.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/numeric.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} numeric.spad ; \
+ rm -f ${DOC}/numeric.spad.pamphlet ; \
+ rm -f ${DOC}/numeric.spad.tex ; \
+ rm -f ${DOC}/numeric.spad )
+
+@
+\subsection{numode.spad \cite{1}}
+<<numode.spad (SPAD from IN)>>=
+${MID}/numode.spad: ${IN}/numode.spad.pamphlet
+ @ echo 0 making ${MID}/numode.spad from ${IN}/numode.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/numode.spad.pamphlet >numode.spad )
+
+@
+<<NUMODE.o (O from NRLIB)>>=
+${OUT}/NUMODE.o: ${MID}/NUMODE.NRLIB
+ @ echo 0 making ${OUT}/NUMODE.o from ${MID}/NUMODE.NRLIB
+ @ cp ${MID}/NUMODE.NRLIB/code.o ${OUT}/NUMODE.o
+
+@
+<<NUMODE.NRLIB (NRLIB from MID)>>=
+${MID}/NUMODE.NRLIB: ${MID}/NUMODE.spad
+ @ echo 0 making ${MID}/NUMODE.NRLIB from ${MID}/NUMODE.spad
+ @ (cd ${MID} ; echo ')co NUMODE.spad' | ${INTERPSYS} )
+
+@
+<<NUMODE.spad (SPAD from IN)>>=
+${MID}/NUMODE.spad: ${IN}/numode.spad.pamphlet
+ @ echo 0 making ${MID}/NUMODE.spad from ${IN}/numode.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NUMODE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NUMODE NumericalOrdinaryDifferentialEquations" ${IN}/numode.spad.pamphlet >NUMODE.spad )
+
+@
+<<numode.spad.dvi (DOC from IN)>>=
+${DOC}/numode.spad.dvi: ${IN}/numode.spad.pamphlet
+ @ echo 0 making ${DOC}/numode.spad.dvi from ${IN}/numode.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/numode.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} numode.spad ; \
+ rm -f ${DOC}/numode.spad.pamphlet ; \
+ rm -f ${DOC}/numode.spad.tex ; \
+ rm -f ${DOC}/numode.spad )
+
+@
+\subsection{numquad.spad \cite{1}}
+<<numquad.spad (SPAD from IN)>>=
+${MID}/numquad.spad: ${IN}/numquad.spad.pamphlet
+ @ echo 0 making ${MID}/numquad.spad from ${IN}/numquad.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/numquad.spad.pamphlet >numquad.spad )
+
+@
+<<NUMQUAD.o (O from NRLIB)>>=
+${OUT}/NUMQUAD.o: ${MID}/NUMQUAD.NRLIB
+ @ echo 0 making ${OUT}/NUMQUAD.o from ${MID}/NUMQUAD.NRLIB
+ @ cp ${MID}/NUMQUAD.NRLIB/code.o ${OUT}/NUMQUAD.o
+
+@
+<<NUMQUAD.NRLIB (NRLIB from MID)>>=
+${MID}/NUMQUAD.NRLIB: ${MID}/NUMQUAD.spad
+ @ echo 0 making ${MID}/NUMQUAD.NRLIB from ${MID}/NUMQUAD.spad
+ @ (cd ${MID} ; echo ')co NUMQUAD.spad' | ${INTERPSYS} )
+
+@
+<<NUMQUAD.spad (SPAD from IN)>>=
+${MID}/NUMQUAD.spad: ${IN}/numquad.spad.pamphlet
+ @ echo 0 making ${MID}/NUMQUAD.spad from ${IN}/numquad.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NUMQUAD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NUMQUAD NumericalQuadrature" ${IN}/numquad.spad.pamphlet >NUMQUAD.spad )
+
+@
+<<numquad.spad.dvi (DOC from IN)>>=
+${DOC}/numquad.spad.dvi: ${IN}/numquad.spad.pamphlet
+ @ echo 0 making ${DOC}/numquad.spad.dvi from ${IN}/numquad.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/numquad.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} numquad.spad ; \
+ rm -f ${DOC}/numquad.spad.pamphlet ; \
+ rm -f ${DOC}/numquad.spad.tex ; \
+ rm -f ${DOC}/numquad.spad )
+
+@
+\subsection{numsolve.spad \cite{1}}
+<<numsolve.spad (SPAD from IN)>>=
+${MID}/numsolve.spad: ${IN}/numsolve.spad.pamphlet
+ @ echo 0 making ${MID}/numsolve.spad from ${IN}/numsolve.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/numsolve.spad.pamphlet >numsolve.spad )
+
+@
+<<FLOATCP.o (O from NRLIB)>>=
+${OUT}/FLOATCP.o: ${MID}/FLOATCP.NRLIB
+ @ echo 0 making ${OUT}/FLOATCP.o from ${MID}/FLOATCP.NRLIB
+ @ cp ${MID}/FLOATCP.NRLIB/code.o ${OUT}/FLOATCP.o
+
+@
+<<FLOATCP.NRLIB (NRLIB from MID)>>=
+${MID}/FLOATCP.NRLIB: ${MID}/FLOATCP.spad
+ @ echo 0 making ${MID}/FLOATCP.NRLIB from ${MID}/FLOATCP.spad
+ @ (cd ${MID} ; echo ')co FLOATCP.spad' | ${INTERPSYS} )
+
+@
+<<FLOATCP.spad (SPAD from IN)>>=
+${MID}/FLOATCP.spad: ${IN}/numsolve.spad.pamphlet
+ @ echo 0 making ${MID}/FLOATCP.spad from ${IN}/numsolve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLOATCP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FLOATCP FloatingComplexPackage" ${IN}/numsolve.spad.pamphlet >FLOATCP.spad )
+
+@
+<<FLOATRP.o (O from NRLIB)>>=
+${OUT}/FLOATRP.o: ${MID}/FLOATRP.NRLIB
+ @ echo 0 making ${OUT}/FLOATRP.o from ${MID}/FLOATRP.NRLIB
+ @ cp ${MID}/FLOATRP.NRLIB/code.o ${OUT}/FLOATRP.o
+
+@
+<<FLOATRP.NRLIB (NRLIB from MID)>>=
+${MID}/FLOATRP.NRLIB: ${OUT}/CFCAT.o ${MID}/FLOATRP.spad
+ @ echo 0 making ${MID}/FLOATRP.NRLIB from ${MID}/FLOATRP.spad
+ @ (cd ${MID} ; echo ')co FLOATRP.spad' | ${INTERPSYS} )
+
+@
+<<FLOATRP.spad (SPAD from IN)>>=
+${MID}/FLOATRP.spad: ${IN}/numsolve.spad.pamphlet
+ @ echo 0 making ${MID}/FLOATRP.spad from ${IN}/numsolve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLOATRP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FLOATRP FloatingRealPackage" ${IN}/numsolve.spad.pamphlet >FLOATRP.spad )
+
+@
+<<INFSP.o (O from NRLIB)>>=
+${OUT}/INFSP.o: ${MID}/INFSP.NRLIB
+ @ echo 0 making ${OUT}/INFSP.o from ${MID}/INFSP.NRLIB
+ @ cp ${MID}/INFSP.NRLIB/code.o ${OUT}/INFSP.o
+
+@
+<<INFSP.NRLIB (NRLIB from MID)>>=
+${MID}/INFSP.NRLIB: ${MID}/INFSP.spad
+ @ echo 0 making ${MID}/INFSP.NRLIB from ${MID}/INFSP.spad
+ @ (cd ${MID} ; echo ')co INFSP.spad' | ${INTERPSYS} )
+
+@
+<<INFSP.spad (SPAD from IN)>>=
+${MID}/INFSP.spad: ${IN}/numsolve.spad.pamphlet
+ @ echo 0 making ${MID}/INFSP.spad from ${IN}/numsolve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INFSP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INFSP InnerNumericFloatSolvePackage" ${IN}/numsolve.spad.pamphlet >INFSP.spad )
+
+@
+<<numsolve.spad.dvi (DOC from IN)>>=
+${DOC}/numsolve.spad.dvi: ${IN}/numsolve.spad.pamphlet
+ @ echo 0 making ${DOC}/numsolve.spad.dvi from ${IN}/numsolve.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/numsolve.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} numsolve.spad ; \
+ rm -f ${DOC}/numsolve.spad.pamphlet ; \
+ rm -f ${DOC}/numsolve.spad.tex ; \
+ rm -f ${DOC}/numsolve.spad )
+
+@
+\subsection{numtheor.spad \cite{1}}
+<<numtheor.spad (SPAD from IN)>>=
+${MID}/numtheor.spad: ${IN}/numtheor.spad.pamphlet
+ @ echo 0 making ${MID}/numtheor.spad from ${IN}/numtheor.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/numtheor.spad.pamphlet >numtheor.spad )
+
+@
+<<INTHEORY.o (O from NRLIB)>>=
+${OUT}/INTHEORY.o: ${MID}/INTHEORY.NRLIB
+ @ echo 0 making ${OUT}/INTHEORY.o from ${MID}/INTHEORY.NRLIB
+ @ cp ${MID}/INTHEORY.NRLIB/code.o ${OUT}/INTHEORY.o
+
+@
+<<INTHEORY.NRLIB (NRLIB from MID)>>=
+${MID}/INTHEORY.NRLIB: ${MID}/INTHEORY.spad
+ @ echo 0 making ${MID}/INTHEORY.NRLIB from ${MID}/INTHEORY.spad
+ @ (cd ${MID} ; echo ')co INTHEORY.spad' | ${INTERPSYS} )
+
+@
+<<INTHEORY.spad (SPAD from IN)>>=
+${MID}/INTHEORY.spad: ${IN}/numtheor.spad.pamphlet
+ @ echo 0 making ${MID}/INTHEORY.spad from ${IN}/numtheor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTHEORY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTHEORY IntegerNumberTheoryFunctions" ${IN}/numtheor.spad.pamphlet >INTHEORY.spad )
+
+@
+<<PNTHEORY.o (O from NRLIB)>>=
+${OUT}/PNTHEORY.o: ${MID}/PNTHEORY.NRLIB
+ @ echo 0 making ${OUT}/PNTHEORY.o from ${MID}/PNTHEORY.NRLIB
+ @ cp ${MID}/PNTHEORY.NRLIB/code.o ${OUT}/PNTHEORY.o
+
+@
+<<PNTHEORY.NRLIB (NRLIB from MID)>>=
+${MID}/PNTHEORY.NRLIB: ${MID}/PNTHEORY.spad
+ @ echo 0 making ${MID}/PNTHEORY.NRLIB from ${MID}/PNTHEORY.spad
+ @ (cd ${MID} ; echo ')co PNTHEORY.spad' | ${INTERPSYS} )
+
+@
+<<PNTHEORY.spad (SPAD from IN)>>=
+${MID}/PNTHEORY.spad: ${IN}/numtheor.spad.pamphlet
+ @ echo 0 making ${MID}/PNTHEORY.spad from ${IN}/numtheor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PNTHEORY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PNTHEORY PolynomialNumberTheoryFunctions" ${IN}/numtheor.spad.pamphlet >PNTHEORY.spad )
+
+@
+<<numtheor.spad.dvi (DOC from IN)>>=
+${DOC}/numtheor.spad.dvi: ${IN}/numtheor.spad.pamphlet
+ @ echo 0 making ${DOC}/numtheor.spad.dvi from ${IN}/numtheor.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/numtheor.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} numtheor.spad ; \
+ rm -f ${DOC}/numtheor.spad.pamphlet ; \
+ rm -f ${DOC}/numtheor.spad.tex ; \
+ rm -f ${DOC}/numtheor.spad )
+
+@
+\subsection{oct.spad \cite{1}}
+<<oct.spad (SPAD from IN)>>=
+${MID}/oct.spad: ${IN}/oct.spad.pamphlet
+ @ echo 0 making ${MID}/oct.spad from ${IN}/oct.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/oct.spad.pamphlet >oct.spad )
+
+@
+<<OC-.o (O from NRLIB)>>=
+${OUT}/OC-.o: ${MID}/OC.NRLIB
+ @ echo 0 making ${OUT}/OC-.o from ${MID}/OC-.NRLIB
+ @ cp ${MID}/OC-.NRLIB/code.o ${OUT}/OC-.o
+
+@
+<<OC-.NRLIB (NRLIB from MID)>>=
+${MID}/OC-.NRLIB: ${OUT}/TYPE.o ${MID}/OC.spad
+ @ echo 0 making ${MID}/OC-.NRLIB from ${MID}/OC.spad
+ @ (cd ${MID} ; echo ')co OC.spad' | ${INTERPSYS} )
+
+@
+<<OC.o (O from NRLIB)>>=
+${OUT}/OC.o: ${MID}/OC.NRLIB
+ @ echo 0 making ${OUT}/OC.o from ${MID}/OC.NRLIB
+ @ cp ${MID}/OC.NRLIB/code.o ${OUT}/OC.o
+
+@
+<<OC.NRLIB (NRLIB from MID)>>=
+${MID}/OC.NRLIB: ${MID}/OC.spad
+ @ echo 0 making ${MID}/OC.NRLIB from ${MID}/OC.spad
+ @ (cd ${MID} ; echo ')co OC.spad' | ${INTERPSYS} )
+
+@
+<<OC.spad (SPAD from IN)>>=
+${MID}/OC.spad: ${IN}/oct.spad.pamphlet
+ @ echo 0 making ${MID}/OC.spad from ${IN}/oct.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OC OctonionCategory" ${IN}/oct.spad.pamphlet >OC.spad )
+
+@
+<<OCT.o (O from NRLIB)>>=
+${OUT}/OCT.o: ${MID}/OCT.NRLIB
+ @ echo 0 making ${OUT}/OCT.o from ${MID}/OCT.NRLIB
+ @ cp ${MID}/OCT.NRLIB/code.o ${OUT}/OCT.o
+
+@
+<<OCT.NRLIB (NRLIB from MID)>>=
+${MID}/OCT.NRLIB: ${MID}/OCT.spad
+ @ echo 0 making ${MID}/OCT.NRLIB from ${MID}/OCT.spad
+ @ (cd ${MID} ; echo ')co OCT.spad' | ${INTERPSYS} )
+
+@
+<<OCT.spad (SPAD from IN)>>=
+${MID}/OCT.spad: ${IN}/oct.spad.pamphlet
+ @ echo 0 making ${MID}/OCT.spad from ${IN}/oct.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OCT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OCT Octonion" ${IN}/oct.spad.pamphlet >OCT.spad )
+
+@
+<<OCTCT2.o (O from NRLIB)>>=
+${OUT}/OCTCT2.o: ${MID}/OCTCT2.NRLIB
+ @ echo 0 making ${OUT}/OCTCT2.o from ${MID}/OCTCT2.NRLIB
+ @ cp ${MID}/OCTCT2.NRLIB/code.o ${OUT}/OCTCT2.o
+
+@
+<<OCTCT2.NRLIB (NRLIB from MID)>>=
+${MID}/OCTCT2.NRLIB: ${MID}/OCTCT2.spad
+ @ echo 0 making ${MID}/OCTCT2.NRLIB from ${MID}/OCTCT2.spad
+ @ (cd ${MID} ; echo ')co OCTCT2.spad' | ${INTERPSYS} )
+
+@
+<<OCTCT2.spad (SPAD from IN)>>=
+${MID}/OCTCT2.spad: ${IN}/oct.spad.pamphlet
+ @ echo 0 making ${MID}/OCTCT2.spad from ${IN}/oct.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OCTCT2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OCTCT2 OctonionCategoryFunctions2" ${IN}/oct.spad.pamphlet >OCTCT2.spad )
+
+@
+<<oct.spad.dvi (DOC from IN)>>=
+${DOC}/oct.spad.dvi: ${IN}/oct.spad.pamphlet
+ @ echo 0 making ${DOC}/oct.spad.dvi from ${IN}/oct.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/oct.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} oct.spad ; \
+ rm -f ${DOC}/oct.spad.pamphlet ; \
+ rm -f ${DOC}/oct.spad.tex ; \
+ rm -f ${DOC}/oct.spad )
+
+@
+\subsection{odealg.spad \cite{1}}
+<<odealg.spad (SPAD from IN)>>=
+${MID}/odealg.spad: ${IN}/odealg.spad.pamphlet
+ @ echo 0 making ${MID}/odealg.spad from ${IN}/odealg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/odealg.spad.pamphlet >odealg.spad )
+
+@
+<<ODEPAL.o (O from NRLIB)>>=
+${OUT}/ODEPAL.o: ${MID}/ODEPAL.NRLIB
+ @ echo 0 making ${OUT}/ODEPAL.o from ${MID}/ODEPAL.NRLIB
+ @ cp ${MID}/ODEPAL.NRLIB/code.o ${OUT}/ODEPAL.o
+
+@
+<<ODEPAL.NRLIB (NRLIB from MID)>>=
+${MID}/ODEPAL.NRLIB: ${MID}/ODEPAL.spad
+ @ echo 0 making ${MID}/ODEPAL.NRLIB from ${MID}/ODEPAL.spad
+ @ (cd ${MID} ; echo ')co ODEPAL.spad' | ${INTERPSYS} )
+
+@
+<<ODEPAL.spad (SPAD from IN)>>=
+${MID}/ODEPAL.spad: ${IN}/odealg.spad.pamphlet
+ @ echo 0 making ${MID}/ODEPAL.spad from ${IN}/odealg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEPAL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODEPAL PureAlgebraicLODE" ${IN}/odealg.spad.pamphlet >ODEPAL.spad )
+
+@
+<<ODERED.o (O from NRLIB)>>=
+${OUT}/ODERED.o: ${MID}/ODERED.NRLIB
+ @ echo 0 making ${OUT}/ODERED.o from ${MID}/ODERED.NRLIB
+ @ cp ${MID}/ODERED.NRLIB/code.o ${OUT}/ODERED.o
+
+@
+<<ODERED.NRLIB (NRLIB from MID)>>=
+${MID}/ODERED.NRLIB: ${MID}/ODERED.spad
+ @ echo 0 making ${MID}/ODERED.NRLIB from ${MID}/ODERED.spad
+ @ (cd ${MID} ; echo ')co ODERED.spad' | ${INTERPSYS} )
+
+@
+<<ODERED.spad (SPAD from IN)>>=
+${MID}/ODERED.spad: ${IN}/odealg.spad.pamphlet
+ @ echo 0 making ${MID}/ODERED.spad from ${IN}/odealg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODERED.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODERED ReduceLODE" ${IN}/odealg.spad.pamphlet >ODERED.spad )
+
+@
+<<ODESYS.o (O from NRLIB)>>=
+${OUT}/ODESYS.o: ${MID}/ODESYS.NRLIB
+ @ echo 0 making ${OUT}/ODESYS.o from ${MID}/ODESYS.NRLIB
+ @ cp ${MID}/ODESYS.NRLIB/code.o ${OUT}/ODESYS.o
+
+@
+<<ODESYS.NRLIB (NRLIB from MID)>>=
+${MID}/ODESYS.NRLIB: ${MID}/ODESYS.spad
+ @ echo 0 making ${MID}/ODESYS.NRLIB from ${MID}/ODESYS.spad
+ @ (cd ${MID} ; echo ')co ODESYS.spad' | ${INTERPSYS} )
+
+@
+<<ODESYS.spad (SPAD from IN)>>=
+${MID}/ODESYS.spad: ${IN}/odealg.spad.pamphlet
+ @ echo 0 making ${MID}/ODESYS.spad from ${IN}/odealg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODESYS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODESYS SystemODESolver" ${IN}/odealg.spad.pamphlet >ODESYS.spad )
+
+@
+<<odealg.spad.dvi (DOC from IN)>>=
+${DOC}/odealg.spad.dvi: ${IN}/odealg.spad.pamphlet
+ @ echo 0 making ${DOC}/odealg.spad.dvi from ${IN}/odealg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/odealg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} odealg.spad ; \
+ rm -f ${DOC}/odealg.spad.pamphlet ; \
+ rm -f ${DOC}/odealg.spad.tex ; \
+ rm -f ${DOC}/odealg.spad )
+
+@
+\subsection{odeef.spad \cite{1}}
+<<odeef.spad (SPAD from IN)>>=
+${MID}/odeef.spad: ${IN}/odeef.spad.pamphlet
+ @ echo 0 making ${MID}/odeef.spad from ${IN}/odeef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/odeef.spad.pamphlet >odeef.spad )
+
+@
+<<LODEEF.o (O from NRLIB)>>=
+${OUT}/LODEEF.o: ${MID}/LODEEF.NRLIB
+ @ echo 0 making ${OUT}/LODEEF.o from ${MID}/LODEEF.NRLIB
+ @ cp ${MID}/LODEEF.NRLIB/code.o ${OUT}/LODEEF.o
+
+@
+<<LODEEF.NRLIB (NRLIB from MID)>>=
+${MID}/LODEEF.NRLIB: ${MID}/LODEEF.spad
+ @ echo 0 making ${MID}/LODEEF.NRLIB from ${MID}/LODEEF.spad
+ @ (cd ${MID} ; echo ')co LODEEF.spad' | ${INTERPSYS} )
+
+@
+<<LODEEF.spad (SPAD from IN)>>=
+${MID}/LODEEF.spad: ${IN}/odeef.spad.pamphlet
+ @ echo 0 making ${MID}/LODEEF.spad from ${IN}/odeef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LODEEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LODEEF ElementaryFunctionLODESolver" ${IN}/odeef.spad.pamphlet >LODEEF.spad )
+
+@
+<<REDORDER.o (O from NRLIB)>>=
+${OUT}/REDORDER.o: ${MID}/REDORDER.NRLIB
+ @ echo 0 making ${OUT}/REDORDER.o from ${MID}/REDORDER.NRLIB
+ @ cp ${MID}/REDORDER.NRLIB/code.o ${OUT}/REDORDER.o
+
+@
+<<REDORDER.NRLIB (NRLIB from MID)>>=
+${MID}/REDORDER.NRLIB: ${MID}/REDORDER.spad
+ @ echo 0 making ${MID}/REDORDER.NRLIB from ${MID}/REDORDER.spad
+ @ (cd ${MID} ; echo ')co REDORDER.spad' | ${INTERPSYS} )
+
+@
+<<REDORDER.spad (SPAD from IN)>>=
+${MID}/REDORDER.spad: ${IN}/odeef.spad.pamphlet
+ @ echo 0 making ${MID}/REDORDER.spad from ${IN}/odeef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REDORDER.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REDORDER ReductionOfOrder" ${IN}/odeef.spad.pamphlet >REDORDER.spad )
+
+@
+<<odeef.spad.dvi (DOC from IN)>>=
+${DOC}/odeef.spad.dvi: ${IN}/odeef.spad.pamphlet
+ @ echo 0 making ${DOC}/odeef.spad.dvi from ${IN}/odeef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/odeef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} odeef.spad ; \
+ rm -f ${DOC}/odeef.spad.pamphlet ; \
+ rm -f ${DOC}/odeef.spad.tex ; \
+ rm -f ${DOC}/odeef.spad )
+
+@
+\subsection{oderf.spad \cite{1}}
+<<oderf.spad (SPAD from IN)>>=
+${MID}/oderf.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/oderf.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/oderf.spad.pamphlet >oderf.spad )
+
+@
+<<BALFACT.o (O from NRLIB)>>=
+${OUT}/BALFACT.o: ${MID}/BALFACT.NRLIB
+ @ echo 0 making ${OUT}/BALFACT.o from ${MID}/BALFACT.NRLIB
+ @ cp ${MID}/BALFACT.NRLIB/code.o ${OUT}/BALFACT.o
+
+@
+<<BALFACT.NRLIB (NRLIB from MID)>>=
+${MID}/BALFACT.NRLIB: ${MID}/BALFACT.spad
+ @ echo 0 making ${MID}/BALFACT.NRLIB from ${MID}/BALFACT.spad
+ @ (cd ${MID} ; echo ')co BALFACT.spad' | ${INTERPSYS} )
+
+@
+<<BALFACT.spad (SPAD from IN)>>=
+${MID}/BALFACT.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/BALFACT.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BALFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package BALFACT BalancedFactorisation" ${IN}/oderf.spad.pamphlet >BALFACT.spad )
+
+@
+<<BOUNDZRO.o (O from NRLIB)>>=
+${OUT}/BOUNDZRO.o: ${MID}/BOUNDZRO.NRLIB
+ @ echo 0 making ${OUT}/BOUNDZRO.o from ${MID}/BOUNDZRO.NRLIB
+ @ cp ${MID}/BOUNDZRO.NRLIB/code.o ${OUT}/BOUNDZRO.o
+
+@
+<<BOUNDZRO.NRLIB (NRLIB from MID)>>=
+${MID}/BOUNDZRO.NRLIB: ${MID}/BOUNDZRO.spad
+ @ echo 0 making ${MID}/BOUNDZRO.NRLIB from ${MID}/BOUNDZRO.spad
+ @ (cd ${MID} ; echo ')co BOUNDZRO.spad' | ${INTERPSYS} )
+
+@
+<<BOUNDZRO.spad (SPAD from IN)>>=
+${MID}/BOUNDZRO.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/BOUNDZRO.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BOUNDZRO.NRLIB ; \
+ ${SPADBIN}/notangle -R"package BOUNDZRO BoundIntegerRoots" ${IN}/oderf.spad.pamphlet >BOUNDZRO.spad )
+
+@
+<<ODECONST.o (O from NRLIB)>>=
+${OUT}/ODECONST.o: ${MID}/ODECONST.NRLIB
+ @ echo 0 making ${OUT}/ODECONST.o from ${MID}/ODECONST.NRLIB
+ @ cp ${MID}/ODECONST.NRLIB/code.o ${OUT}/ODECONST.o
+
+@
+<<ODECONST.NRLIB (NRLIB from MID)>>=
+${MID}/ODECONST.NRLIB: ${MID}/ODECONST.spad
+ @ echo 0 making ${MID}/ODECONST.NRLIB from ${MID}/ODECONST.spad
+ @ (cd ${MID} ; echo ')co ODECONST.spad' | ${INTERPSYS} )
+
+@
+<<ODECONST.spad (SPAD from IN)>>=
+${MID}/ODECONST.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/ODECONST.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODECONST.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODECONST ConstantLODE" ${IN}/oderf.spad.pamphlet >ODECONST.spad )
+
+@
+<<ODEINT.o (O from NRLIB)>>=
+${OUT}/ODEINT.o: ${MID}/ODEINT.NRLIB
+ @ echo 0 making ${OUT}/ODEINT.o from ${MID}/ODEINT.NRLIB
+ @ cp ${MID}/ODEINT.NRLIB/code.o ${OUT}/ODEINT.o
+
+@
+<<ODEINT.NRLIB (NRLIB from MID)>>=
+${MID}/ODEINT.NRLIB: ${MID}/ODEINT.spad
+ @ echo 0 making ${MID}/ODEINT.NRLIB from ${MID}/ODEINT.spad
+ @ (cd ${MID} ; echo ')co ODEINT.spad' | ${INTERPSYS} )
+
+@
+<<ODEINT.spad (SPAD from IN)>>=
+${MID}/ODEINT.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/ODEINT.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODEINT ODEIntegration" ${IN}/oderf.spad.pamphlet >ODEINT.spad )
+
+@
+<<ODEPRIM.o (O from NRLIB)>>=
+${OUT}/ODEPRIM.o: ${MID}/ODEPRIM.NRLIB
+ @ echo 0 making ${OUT}/ODEPRIM.o from ${MID}/ODEPRIM.NRLIB
+ @ cp ${MID}/ODEPRIM.NRLIB/code.o ${OUT}/ODEPRIM.o
+
+@
+<<ODEPRIM.NRLIB (NRLIB from MID)>>=
+${MID}/ODEPRIM.NRLIB: ${MID}/ODEPRIM.spad
+ @ echo 0 making ${MID}/ODEPRIM.NRLIB from ${MID}/ODEPRIM.spad
+ @ (cd ${MID} ; echo ')co ODEPRIM.spad' | ${INTERPSYS} )
+
+@
+<<ODEPRIM.spad (SPAD from IN)>>=
+${MID}/ODEPRIM.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/ODEPRIM.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEPRIM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODEPRIM PrimitiveRatDE" ${IN}/oderf.spad.pamphlet >ODEPRIM.spad )
+
+@
+<<ODERAT.o (O from NRLIB)>>=
+${OUT}/ODERAT.o: ${MID}/ODERAT.NRLIB
+ @ echo 0 making ${OUT}/ODERAT.o from ${MID}/ODERAT.NRLIB
+ @ cp ${MID}/ODERAT.NRLIB/code.o ${OUT}/ODERAT.o
+
+@
+<<ODERAT.NRLIB (NRLIB from MID)>>=
+${MID}/ODERAT.NRLIB: ${MID}/ODERAT.spad
+ @ echo 0 making ${MID}/ODERAT.NRLIB from ${MID}/ODERAT.spad
+ @ (cd ${MID} ; echo ')co ODERAT.spad' | ${INTERPSYS} )
+
+@
+<<ODERAT.spad (SPAD from IN)>>=
+${MID}/ODERAT.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/ODERAT.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODERAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODERAT RationalLODE" ${IN}/oderf.spad.pamphlet >ODERAT.spad )
+
+@
+<<ODETOOLS.o (O from NRLIB)>>=
+${OUT}/ODETOOLS.o: ${MID}/ODETOOLS.NRLIB
+ @ echo 0 making ${OUT}/ODETOOLS.o from ${MID}/ODETOOLS.NRLIB
+ @ cp ${MID}/ODETOOLS.NRLIB/code.o ${OUT}/ODETOOLS.o
+
+@
+<<ODETOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/ODETOOLS.NRLIB: ${MID}/ODETOOLS.spad
+ @ echo 0 making ${MID}/ODETOOLS.NRLIB from ${MID}/ODETOOLS.spad
+ @ (cd ${MID} ; echo ')co ODETOOLS.spad' | ${INTERPSYS} )
+
+@
+<<ODETOOLS.spad (SPAD from IN)>>=
+${MID}/ODETOOLS.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/ODETOOLS.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODETOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODETOOLS ODETools" ${IN}/oderf.spad.pamphlet >ODETOOLS.spad )
+
+@
+<<UTSODETL.o (O from NRLIB)>>=
+${OUT}/UTSODETL.o: ${MID}/UTSODETL.NRLIB
+ @ echo 0 making ${OUT}/UTSODETL.o from ${MID}/UTSODETL.NRLIB
+ @ cp ${MID}/UTSODETL.NRLIB/code.o ${OUT}/UTSODETL.o
+
+@
+<<UTSODETL.NRLIB (NRLIB from MID)>>=
+${MID}/UTSODETL.NRLIB: ${MID}/UTSODETL.spad
+ @ echo 0 making ${MID}/UTSODETL.NRLIB from ${MID}/UTSODETL.spad
+ @ (cd ${MID} ; echo ')co UTSODETL.spad' | ${INTERPSYS} )
+
+@
+<<UTSODETL.spad (SPAD from IN)>>=
+${MID}/UTSODETL.spad: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${MID}/UTSODETL.spad from ${IN}/oderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UTSODETL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UTSODETL UTSodetools" ${IN}/oderf.spad.pamphlet >UTSODETL.spad )
+
+@
+<<oderf.spad.dvi (DOC from IN)>>=
+${DOC}/oderf.spad.dvi: ${IN}/oderf.spad.pamphlet
+ @ echo 0 making ${DOC}/oderf.spad.dvi from ${IN}/oderf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/oderf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} oderf.spad ; \
+ rm -f ${DOC}/oderf.spad.pamphlet ; \
+ rm -f ${DOC}/oderf.spad.tex ; \
+ rm -f ${DOC}/oderf.spad )
+
+@
+\subsection{omcat.spad \cite{1}}
+<<omcat.spad (SPAD from IN)>>=
+${MID}/omcat.spad: ${IN}/omcat.spad.pamphlet
+ @ echo 0 making ${MID}/omcat.spad from ${IN}/omcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/omcat.spad.pamphlet >omcat.spad )
+
+@
+<<OM.o (O from NRLIB)>>=
+${OUT}/OM.o: ${MID}/OM.NRLIB
+ @ echo 0 making ${OUT}/OM.o from ${MID}/OM.NRLIB
+ @ cp ${MID}/OM.NRLIB/code.o ${OUT}/OM.o
+
+@
+<<OM.NRLIB (NRLIB from MID)>>=
+${MID}/OM.NRLIB: ${MID}/OM.spad
+ @ echo 0 making ${MID}/OM.NRLIB from ${MID}/OM.spad
+ @ (cd ${MID} ; echo ')co OM.spad' | ${INTERPSYS} )
+
+@
+<<OM.spad (SPAD from IN)>>=
+${MID}/OM.spad: ${IN}/omcat.spad.pamphlet
+ @ echo 0 making ${MID}/OM.spad from ${IN}/omcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OM.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OM OpenMath" ${IN}/omcat.spad.pamphlet >OM.spad )
+
+@
+<<omcat.spad.dvi (DOC from IN)>>=
+${DOC}/omcat.spad.dvi: ${IN}/omcat.spad.pamphlet
+ @ echo 0 making ${DOC}/omcat.spad.dvi from ${IN}/omcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/omcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} omcat.spad ; \
+ rm -f ${DOC}/omcat.spad.pamphlet ; \
+ rm -f ${DOC}/omcat.spad.tex ; \
+ rm -f ${DOC}/omcat.spad )
+
+@
+\subsection{omdev.spad \cite{1}}
+<<omdev.spad (SPAD from IN)>>=
+${MID}/omdev.spad: ${IN}/omdev.spad.pamphlet
+ @ echo 0 making ${MID}/omdev.spad from ${IN}/omdev.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/omdev.spad.pamphlet >omdev.spad )
+
+@
+<<OMENC.o (O from NRLIB)>>=
+${OUT}/OMENC.o: ${MID}/OMENC.NRLIB
+ @ echo 0 making ${OUT}/OMENC.o from ${MID}/OMENC.NRLIB
+ @ cp ${MID}/OMENC.NRLIB/code.o ${OUT}/OMENC.o
+
+@
+<<OMENC.NRLIB (NRLIB from MID)>>=
+${MID}/OMENC.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/OMENC.spad
+ @ echo 0 making ${MID}/OMENC.NRLIB from ${MID}/OMENC.spad
+ @ (cd ${MID} ; echo ')co OMENC.spad' | ${INTERPSYS} )
+
+@
+<<OMENC.spad (SPAD from IN)>>=
+${MID}/OMENC.spad: ${IN}/omdev.spad.pamphlet
+ @ echo 0 making ${MID}/OMENC.spad from ${IN}/omdev.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMENC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OMENC OpenMathEncoding" ${IN}/omdev.spad.pamphlet >OMENC.spad )
+
+@
+<<OMCONN.o (O from NRLIB)>>=
+${OUT}/OMCONN.o: ${MID}/OMCONN.NRLIB
+ @ echo 0 making ${OUT}/OMCONN.o from ${MID}/OMCONN.NRLIB
+ @ cp ${MID}/OMCONN.NRLIB/code.o ${OUT}/OMCONN.o
+
+@
+<<OMCONN.NRLIB (NRLIB from MID)>>=
+${MID}/OMCONN.NRLIB: ${MID}/OMCONN.spad
+ @ echo 0 making ${MID}/OMCONN.NRLIB from ${MID}/OMCONN.spad
+ @ (cd ${MID} ; echo ')co OMCONN.spad' | ${INTERPSYS} )
+
+@
+<<OMCONN.spad (SPAD from IN)>>=
+${MID}/OMCONN.spad: ${IN}/omdev.spad.pamphlet
+ @ echo 0 making ${MID}/OMCONN.spad from ${IN}/omdev.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMCONN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OMCONN OpenMathConnection" ${IN}/omdev.spad.pamphlet >OMCONN.spad )
+
+@
+<<OMDEV.o (O from NRLIB)>>=
+${OUT}/OMDEV.o: ${MID}/OMDEV.NRLIB
+ @ echo 0 making ${OUT}/OMDEV.o from ${MID}/OMDEV.NRLIB
+ @ cp ${MID}/OMDEV.NRLIB/code.o ${OUT}/OMDEV.o
+
+@
+<<OMDEV.NRLIB (NRLIB from MID)>>=
+${MID}/OMDEV.NRLIB: ${MID}/OMDEV.spad
+ @ echo 0 making ${MID}/OMDEV.NRLIB from ${MID}/OMDEV.spad
+ @ (cd ${MID} ; echo ')co OMDEV.spad' | ${INTERPSYS} )
+
+@
+<<OMDEV.spad (SPAD from IN)>>=
+${MID}/OMDEV.spad: ${IN}/omdev.spad.pamphlet
+ @ echo 0 making ${MID}/OMDEV.spad from ${IN}/omdev.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMDEV.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OMDEV OpenMathDevice" ${IN}/omdev.spad.pamphlet >OMDEV.spad )
+
+@
+<<OMPKG.o (O from NRLIB)>>=
+${OUT}/OMPKG.o: ${MID}/OMPKG.NRLIB
+ @ echo 0 making ${OUT}/OMPKG.o from ${MID}/OMPKG.NRLIB
+ @ cp ${MID}/OMPKG.NRLIB/code.o ${OUT}/OMPKG.o
+
+@
+<<OMPKG.NRLIB (NRLIB from MID)>>=
+${MID}/OMPKG.NRLIB: ${MID}/OMPKG.spad
+ @ echo 0 making ${MID}/OMPKG.NRLIB from ${MID}/OMPKG.spad
+ @ (cd ${MID} ; echo ')co OMPKG.spad' | ${INTERPSYS} )
+
+@
+<<OMPKG.spad (SPAD from IN)>>=
+${MID}/OMPKG.spad: ${IN}/omdev.spad.pamphlet
+ @ echo 0 making ${MID}/OMPKG.spad from ${IN}/omdev.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMPKG.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OMPKG OpenMathPackage" ${IN}/omdev.spad.pamphlet >OMPKG.spad )
+
+@
+<<omdev.spad.dvi (DOC from IN)>>=
+${DOC}/omdev.spad.dvi: ${IN}/omdev.spad.pamphlet
+ @ echo 0 making ${DOC}/omdev.spad.dvi from ${IN}/omdev.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/omdev.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} omdev.spad ; \
+ rm -f ${DOC}/omdev.spad.pamphlet ; \
+ rm -f ${DOC}/omdev.spad.tex ; \
+ rm -f ${DOC}/omdev.spad )
+
+@
+\subsection{omerror.spad \cite{1}}
+<<omerror.spad (SPAD from IN)>>=
+${MID}/omerror.spad: ${IN}/omerror.spad.pamphlet
+ @ echo 0 making ${MID}/omerror.spad from ${IN}/omerror.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/omerror.spad.pamphlet >omerror.spad )
+
+@
+<<OMERR.o (O from NRLIB)>>=
+${OUT}/OMERR.o: ${MID}/OMERR.NRLIB
+ @ echo 0 making ${OUT}/OMERR.o from ${MID}/OMERR.NRLIB
+ @ cp ${MID}/OMERR.NRLIB/code.o ${OUT}/OMERR.o
+
+@
+<<OMERR.NRLIB (NRLIB from MID)>>=
+${MID}/OMERR.NRLIB: ${MID}/OMERR.spad
+ @ echo 0 making ${MID}/OMERR.NRLIB from ${MID}/OMERR.spad
+ @ (cd ${MID} ; echo ')co OMERR.spad' | ${INTERPSYS} )
+
+@
+<<OMERR.spad (SPAD from IN)>>=
+${MID}/OMERR.spad: ${IN}/omerror.spad.pamphlet
+ @ echo 0 making ${MID}/OMERR.spad from ${IN}/omerror.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMERR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OMERR OpenMathError" ${IN}/omerror.spad.pamphlet >OMERR.spad )
+
+@
+<<OMERRK.o (O from NRLIB)>>=
+${OUT}/OMERRK.o: ${MID}/OMERRK.NRLIB
+ @ echo 0 making ${OUT}/OMERRK.o from ${MID}/OMERRK.NRLIB
+ @ cp ${MID}/OMERRK.NRLIB/code.o ${OUT}/OMERRK.o
+
+@
+<<OMERRK.NRLIB (NRLIB from MID)>>=
+${MID}/OMERRK.NRLIB: ${MID}/OMERRK.spad
+ @ echo 0 making ${MID}/OMERRK.NRLIB from ${MID}/OMERRK.spad
+ @ (cd ${MID} ; echo ')co OMERRK.spad' | ${INTERPSYS} )
+
+@
+<<OMERRK.spad (SPAD from IN)>>=
+${MID}/OMERRK.spad: ${IN}/omerror.spad.pamphlet
+ @ echo 0 making ${MID}/OMERRK.spad from ${IN}/omerror.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMERRK.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OMERRK OpenMathErrorKind" ${IN}/omerror.spad.pamphlet >OMERRK.spad )
+
+@
+<<omerror.spad.dvi (DOC from IN)>>=
+${DOC}/omerror.spad.dvi: ${IN}/omerror.spad.pamphlet
+ @ echo 0 making ${DOC}/omerror.spad.dvi from ${IN}/omerror.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/omerror.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} omerror.spad ; \
+ rm -f ${DOC}/omerror.spad.pamphlet ; \
+ rm -f ${DOC}/omerror.spad.tex ; \
+ rm -f ${DOC}/omerror.spad )
+
+@
+\subsection{omserver.spad \cite{1}}
+<<omserver.spad (SPAD from IN)>>=
+${MID}/omserver.spad: ${IN}/omserver.spad.pamphlet
+ @ echo 0 making ${MID}/omserver.spad from ${IN}/omserver.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/omserver.spad.pamphlet >omserver.spad )
+
+@
+<<OMSERVER.o (O from NRLIB)>>=
+${OUT}/OMSERVER.o: ${MID}/OMSERVER.NRLIB
+ @ echo 0 making ${OUT}/OMSERVER.o from ${MID}/OMSERVER.NRLIB
+ @ cp ${MID}/OMSERVER.NRLIB/code.o ${OUT}/OMSERVER.o
+
+@
+<<OMSERVER.NRLIB (NRLIB from MID)>>=
+${MID}/OMSERVER.NRLIB: ${MID}/OMSERVER.spad
+ @ echo 0 making ${MID}/OMSERVER.NRLIB from ${MID}/OMSERVER.spad
+ @ (cd ${MID} ; echo ')co OMSERVER.spad' | ${INTERPSYS} )
+
+@
+<<OMSERVER.spad (SPAD from IN)>>=
+${MID}/OMSERVER.spad: ${IN}/omserver.spad.pamphlet
+ @ echo 0 making ${MID}/OMSERVER.spad from ${IN}/omserver.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMSERVER.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OMSERVER OpenMathServerPackage" ${IN}/omserver.spad.pamphlet >OMSERVER.spad )
+
+@
+<<omserver.spad.dvi (DOC from IN)>>=
+${DOC}/omserver.spad.dvi: ${IN}/omserver.spad.pamphlet
+ @ echo 0 making ${DOC}/omserver.spad.dvi from ${IN}/omserver.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/omserver.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} omserver.spad ; \
+ rm -f ${DOC}/omserver.spad.pamphlet ; \
+ rm -f ${DOC}/omserver.spad.tex ; \
+ rm -f ${DOC}/omserver.spad )
+
+@
+\subsection{opalg.spad \cite{1}}
+<<opalg.spad (SPAD from IN)>>=
+${MID}/opalg.spad: ${IN}/opalg.spad.pamphlet
+ @ echo 0 making ${MID}/opalg.spad from ${IN}/opalg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/opalg.spad.pamphlet >opalg.spad )
+
+@
+<<MODOP.o (O from NRLIB)>>=
+${OUT}/MODOP.o: ${MID}/MODOP.NRLIB
+ @ echo 0 making ${OUT}/MODOP.o from ${MID}/MODOP.NRLIB
+ @ cp ${MID}/MODOP.NRLIB/code.o ${OUT}/MODOP.o
+
+@
+<<MODOP.NRLIB (NRLIB from MID)>>=
+${MID}/MODOP.NRLIB: ${MID}/MODOP.spad
+ @ echo 0 making ${MID}/MODOP.NRLIB from ${MID}/MODOP.spad
+ @ (cd ${MID} ; echo ')co MODOP.spad' | ${INTERPSYS} )
+
+@
+<<MODOP.spad (SPAD from IN)>>=
+${MID}/MODOP.spad: ${IN}/opalg.spad.pamphlet
+ @ echo 0 making ${MID}/MODOP.spad from ${IN}/opalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MODOP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MODOP ModuleOperator" ${IN}/opalg.spad.pamphlet >MODOP.spad )
+
+@
+<<OP.o (O from NRLIB)>>=
+${OUT}/OP.o: ${MID}/OP.NRLIB
+ @ echo 0 making ${OUT}/OP.o from ${MID}/OP.NRLIB
+ @ cp ${MID}/OP.NRLIB/code.o ${OUT}/OP.o
+
+@
+<<OP.NRLIB (NRLIB from MID)>>=
+${MID}/OP.NRLIB: ${MID}/OP.spad
+ @ echo 0 making ${MID}/OP.NRLIB from ${MID}/OP.spad
+ @ (cd ${MID} ; echo ')co OP.spad' | ${INTERPSYS} )
+
+@
+<<OP.spad (SPAD from IN)>>=
+${MID}/OP.spad: ${IN}/opalg.spad.pamphlet
+ @ echo 0 making ${MID}/OP.spad from ${IN}/opalg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OP Operator" ${IN}/opalg.spad.pamphlet >OP.spad )
+
+@
+<<opalg.spad.dvi (DOC from IN)>>=
+${DOC}/opalg.spad.dvi: ${IN}/opalg.spad.pamphlet
+ @ echo 0 making ${DOC}/opalg.spad.dvi from ${IN}/opalg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/opalg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} opalg.spad ; \
+ rm -f ${DOC}/opalg.spad.pamphlet ; \
+ rm -f ${DOC}/opalg.spad.tex ; \
+ rm -f ${DOC}/opalg.spad )
+
+@
+\subsection{openmath.spad \cite{1}}
+<<openmath.spad (SPAD from IN)>>=
+${MID}/openmath.spad: ${IN}/openmath.spad.pamphlet
+ @ echo 0 making ${MID}/openmath.spad from ${IN}/openmath.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/openmath.spad.pamphlet >openmath.spad )
+
+@
+<<OMEXPR.o (O from NRLIB)>>=
+${OUT}/OMEXPR.o: ${MID}/OMEXPR.NRLIB
+ @ echo 0 making ${OUT}/OMEXPR.o from ${MID}/OMEXPR.NRLIB
+ @ cp ${MID}/OMEXPR.NRLIB/code.o ${OUT}/OMEXPR.o
+
+@
+<<OMEXPR.NRLIB (NRLIB from MID)>>=
+${MID}/OMEXPR.NRLIB: ${MID}/OMEXPR.spad
+ @ echo 0 making ${MID}/OMEXPR.NRLIB from ${MID}/OMEXPR.spad
+ @ (cd ${MID} ; echo ')co OMEXPR.spad' | ${INTERPSYS} )
+
+@
+<<OMEXPR.spad (SPAD from IN)>>=
+${MID}/OMEXPR.spad: ${IN}/openmath.spad.pamphlet
+ @ echo 0 making ${MID}/OMEXPR.spad from ${IN}/openmath.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OMEXPR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OMEXPR ExpressionToOpenMath" ${IN}/openmath.spad.pamphlet >OMEXPR.spad )
+
+@
+<<openmath.spad.dvi (DOC from IN)>>=
+${DOC}/openmath.spad.dvi: ${IN}/openmath.spad.pamphlet
+ @ echo 0 making ${DOC}/openmath.spad.dvi from ${IN}/openmath.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/openmath.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} openmath.spad ; \
+ rm -f ${DOC}/openmath.spad.pamphlet ; \
+ rm -f ${DOC}/openmath.spad.tex ; \
+ rm -f ${DOC}/openmath.spad )
+
+@
+\subsection{op.spad \cite{1}}
+<<op.spad (SPAD from IN)>>=
+${MID}/op.spad: ${IN}/op.spad.pamphlet
+ @ echo 0 making ${MID}/op.spad from ${IN}/op.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/op.spad.pamphlet >op.spad )
+
+@
+<<BOP.o (O from NRLIB)>>=
+${OUT}/BOP.o: ${MID}/BOP.NRLIB
+ @ echo 0 making ${OUT}/BOP.o from ${MID}/BOP.NRLIB
+ @ cp ${MID}/BOP.NRLIB/code.o ${OUT}/BOP.o
+
+@
+<<BOP.NRLIB (NRLIB from MID)>>=
+${MID}/BOP.NRLIB: ${MID}/BOP.spad
+ @ echo 0 making ${MID}/BOP.NRLIB from ${MID}/BOP.spad
+ @ (cd ${MID} ; echo ')co BOP.spad' | ${INTERPSYS} )
+
+@
+<<BOP.spad (SPAD from IN)>>=
+${MID}/BOP.spad: ${IN}/op.spad.pamphlet
+ @ echo 0 making ${MID}/BOP.spad from ${IN}/op.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BOP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BOP BasicOperator" ${IN}/op.spad.pamphlet >BOP.spad )
+
+@
+<<BOP1.o (O from NRLIB)>>=
+${OUT}/BOP1.o: ${MID}/BOP1.NRLIB
+ @ echo 0 making ${OUT}/BOP1.o from ${MID}/BOP1.NRLIB
+ @ cp ${MID}/BOP1.NRLIB/code.o ${OUT}/BOP1.o
+
+@
+<<BOP1.NRLIB (NRLIB from MID)>>=
+${MID}/BOP1.NRLIB: ${MID}/BOP1.spad
+ @ echo 0 making ${MID}/BOP1.NRLIB from ${MID}/BOP1.spad
+ @ (cd ${MID} ; echo ')co BOP1.spad' | ${INTERPSYS} )
+
+@
+<<BOP1.spad (SPAD from IN)>>=
+${MID}/BOP1.spad: ${IN}/op.spad.pamphlet
+ @ echo 0 making ${MID}/BOP1.spad from ${IN}/op.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BOP1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package BOP1 BasicOperatorFunctions1" ${IN}/op.spad.pamphlet >BOP1.spad )
+
+@
+<<COMMONOP.o (O from NRLIB)>>=
+${OUT}/COMMONOP.o: ${MID}/COMMONOP.NRLIB
+ @ echo 0 making ${OUT}/COMMONOP.o from ${MID}/COMMONOP.NRLIB
+ @ cp ${MID}/COMMONOP.NRLIB/code.o ${OUT}/COMMONOP.o
+
+@
+<<COMMONOP.NRLIB (NRLIB from MID)>>=
+${MID}/COMMONOP.NRLIB: ${MID}/COMMONOP.spad
+ @ echo 0 making ${MID}/COMMONOP.NRLIB from ${MID}/COMMONOP.spad
+ @ (cd ${MID} ; echo ')co COMMONOP.spad' | ${INTERPSYS} )
+
+@
+<<COMMONOP.spad (SPAD from IN)>>=
+${MID}/COMMONOP.spad: ${IN}/op.spad.pamphlet
+ @ echo 0 making ${MID}/COMMONOP.spad from ${IN}/op.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMMONOP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMMONOP CommonOperators" ${IN}/op.spad.pamphlet >COMMONOP.spad )
+
+@
+<<op.spad.dvi (DOC from IN)>>=
+${DOC}/op.spad.dvi: ${IN}/op.spad.pamphlet
+ @ echo 0 making ${DOC}/op.spad.dvi from ${IN}/op.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/op.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} op.spad ; \
+ rm -f ${DOC}/op.spad.pamphlet ; \
+ rm -f ${DOC}/op.spad.tex ; \
+ rm -f ${DOC}/op.spad )
+
+@
+\subsection{ore.spad \cite{1}}
+<<ore.spad (SPAD from IN)>>=
+${MID}/ore.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/ore.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ore.spad.pamphlet >ore.spad )
+
+@
+<<APPLYORE.o (O from NRLIB)>>=
+${OUT}/APPLYORE.o: ${MID}/APPLYORE.NRLIB
+ @ echo 0 making ${OUT}/APPLYORE.o from ${MID}/APPLYORE.NRLIB
+ @ cp ${MID}/APPLYORE.NRLIB/code.o ${OUT}/APPLYORE.o
+
+@
+<<APPLYORE.NRLIB (NRLIB from MID)>>=
+${MID}/APPLYORE.NRLIB: ${MID}/APPLYORE.spad
+ @ echo 0 making ${MID}/APPLYORE.NRLIB from ${MID}/APPLYORE.spad
+ @ (cd ${MID} ; echo ')co APPLYORE.spad' | ${INTERPSYS} )
+
+@
+<<APPLYORE.spad (SPAD from IN)>>=
+${MID}/APPLYORE.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/APPLYORE.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf APPLYORE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package APPLYORE ApplyUnivariateSkewPolynomial" ${IN}/ore.spad.pamphlet >APPLYORE.spad )
+
+@
+<<AUTOMOR.o (O from NRLIB)>>=
+${OUT}/AUTOMOR.o: ${MID}/AUTOMOR.NRLIB
+ @ echo 0 making ${OUT}/AUTOMOR.o from ${MID}/AUTOMOR.NRLIB
+ @ cp ${MID}/AUTOMOR.NRLIB/code.o ${OUT}/AUTOMOR.o
+
+@
+<<AUTOMOR.NRLIB (NRLIB from MID)>>=
+${MID}/AUTOMOR.NRLIB: ${MID}/AUTOMOR.spad
+ @ echo 0 making ${MID}/AUTOMOR.NRLIB from ${MID}/AUTOMOR.spad
+ @ (cd ${MID} ; echo ')co AUTOMOR.spad' | ${INTERPSYS} )
+
+@
+<<AUTOMOR.spad (SPAD from IN)>>=
+${MID}/AUTOMOR.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/AUTOMOR.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf AUTOMOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain AUTOMOR Automorphism" ${IN}/ore.spad.pamphlet >AUTOMOR.spad )
+
+@
+<<OREPCAT-.o (O from NRLIB)>>=
+${OUT}/OREPCAT-.o: ${MID}/OREPCAT.NRLIB
+ @ echo 0 making ${OUT}/OREPCAT-.o from ${MID}/OREPCAT-.NRLIB
+ @ cp ${MID}/OREPCAT-.NRLIB/code.o ${OUT}/OREPCAT-.o
+
+@
+<<OREPCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/OREPCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/OREPCAT.spad
+ @ echo 0 making ${MID}/OREPCAT-.NRLIB from ${MID}/OREPCAT.spad
+ @ (cd ${MID} ; echo ')co OREPCAT.spad' | ${INTERPSYS} )
+
+@
+<<OREPCAT.o (O from NRLIB)>>=
+${OUT}/OREPCAT.o: ${MID}/OREPCAT.NRLIB
+ @ echo 0 making ${OUT}/OREPCAT.o from ${MID}/OREPCAT.NRLIB
+ @ cp ${MID}/OREPCAT.NRLIB/code.o ${OUT}/OREPCAT.o
+
+@
+<<OREPCAT.NRLIB (NRLIB from MID)>>=
+${MID}/OREPCAT.NRLIB: ${MID}/OREPCAT.spad
+ @ echo 0 making ${MID}/OREPCAT.NRLIB from ${MID}/OREPCAT.spad
+ @ (cd ${MID} ; echo ')co OREPCAT.spad' | ${INTERPSYS} )
+
+@
+<<OREPCAT.spad (SPAD from IN)>>=
+${MID}/OREPCAT.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/OREPCAT.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OREPCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category OREPCAT UnivariateSkewPolynomialCategory" ${IN}/ore.spad.pamphlet >OREPCAT.spad )
+
+@
+<<OREPCTO.o (O from NRLIB)>>=
+${OUT}/OREPCTO.o: ${MID}/OREPCTO.NRLIB
+ @ echo 0 making ${OUT}/OREPCTO.o from ${MID}/OREPCTO.NRLIB
+ @ cp ${MID}/OREPCTO.NRLIB/code.o ${OUT}/OREPCTO.o
+
+@
+<<OREPCTO.NRLIB (NRLIB from MID)>>=
+${MID}/OREPCTO.NRLIB: ${MID}/OREPCTO.spad
+ @ echo 0 making ${MID}/OREPCTO.NRLIB from ${MID}/OREPCTO.spad
+ @ (cd ${MID} ; echo ')co OREPCTO.spad' | ${INTERPSYS} )
+
+@
+<<OREPCTO.spad (SPAD from IN)>>=
+${MID}/OREPCTO.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/OREPCTO.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OREPCTO.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OREPCTO UnivariateSkewPolynomialCategoryOps" ${IN}/ore.spad.pamphlet >OREPCTO.spad )
+
+@
+<<ORESUP.o (O from NRLIB)>>=
+${OUT}/ORESUP.o: ${MID}/ORESUP.NRLIB
+ @ echo 0 making ${OUT}/ORESUP.o from ${MID}/ORESUP.NRLIB
+ @ cp ${MID}/ORESUP.NRLIB/code.o ${OUT}/ORESUP.o
+
+@
+<<ORESUP.NRLIB (NRLIB from MID)>>=
+${MID}/ORESUP.NRLIB: ${MID}/ORESUP.spad
+ @ echo 0 making ${MID}/ORESUP.NRLIB from ${MID}/ORESUP.spad
+ @ (cd ${MID} ; echo ')co ORESUP.spad' | ${INTERPSYS} )
+
+@
+<<ORESUP.spad (SPAD from IN)>>=
+${MID}/ORESUP.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/ORESUP.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORESUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ORESUP SparseUnivariateSkewPolynomial" ${IN}/ore.spad.pamphlet >ORESUP.spad )
+
+@
+<<OREUP.o (O from NRLIB)>>=
+${OUT}/OREUP.o: ${MID}/OREUP.NRLIB
+ @ echo 0 making ${OUT}/OREUP.o from ${MID}/OREUP.NRLIB
+ @ cp ${MID}/OREUP.NRLIB/code.o ${OUT}/OREUP.o
+
+@
+<<OREUP.NRLIB (NRLIB from MID)>>=
+${MID}/OREUP.NRLIB: ${MID}/OREUP.spad
+ @ echo 0 making ${MID}/OREUP.NRLIB from ${MID}/OREUP.spad
+ @ (cd ${MID} ; echo ')co OREUP.spad' | ${INTERPSYS} )
+
+@
+<<OREUP.spad (SPAD from IN)>>=
+${MID}/OREUP.spad: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${MID}/OREUP.spad from ${IN}/ore.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OREUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OREUP UnivariateSkewPolynomial" ${IN}/ore.spad.pamphlet >OREUP.spad )
+
+@
+<<ore.spad.dvi (DOC from IN)>>=
+${DOC}/ore.spad.dvi: ${IN}/ore.spad.pamphlet
+ @ echo 0 making ${DOC}/ore.spad.dvi from ${IN}/ore.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ore.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ore.spad ; \
+ rm -f ${DOC}/ore.spad.pamphlet ; \
+ rm -f ${DOC}/ore.spad.tex ; \
+ rm -f ${DOC}/ore.spad )
+
+@
+\subsection{outform.spad \cite{1}}
+<<outform.spad (SPAD from IN)>>=
+${MID}/outform.spad: ${IN}/outform.spad.pamphlet
+ @ echo 0 making ${MID}/outform.spad from ${IN}/outform.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/outform.spad.pamphlet >outform.spad )
+
+@
+<<NUMFMT.o (O from NRLIB)>>=
+${OUT}/NUMFMT.o: ${MID}/NUMFMT.NRLIB
+ @ echo 0 making ${OUT}/NUMFMT.o from ${MID}/NUMFMT.NRLIB
+ @ cp ${MID}/NUMFMT.NRLIB/code.o ${OUT}/NUMFMT.o
+
+@
+<<NUMFMT.NRLIB (NRLIB from MID)>>=
+${MID}/NUMFMT.NRLIB: ${MID}/NUMFMT.spad
+ @ echo 0 making ${MID}/NUMFMT.NRLIB from ${MID}/NUMFMT.spad
+ @ (cd ${MID} ; echo ')co NUMFMT.spad' | ${INTERPSYS} )
+
+@
+<<NUMFMT.spad (SPAD from IN)>>=
+${MID}/NUMFMT.spad: ${IN}/outform.spad.pamphlet
+ @ echo 0 making ${MID}/NUMFMT.spad from ${IN}/outform.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NUMFMT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NUMFMT NumberFormats" ${IN}/outform.spad.pamphlet >NUMFMT.spad )
+
+@
+<<OUTFORM.o (O from NRLIB)>>=
+${OUT}/OUTFORM.o: ${MID}/OUTFORM.NRLIB
+ @ echo 0 making ${OUT}/OUTFORM.o from ${MID}/OUTFORM.NRLIB
+ @ cp ${MID}/OUTFORM.NRLIB/code.o ${OUT}/OUTFORM.o
+
+@
+<<OUTFORM.NRLIB (NRLIB from MID)>>=
+${MID}/OUTFORM.NRLIB: ${MID}/OUTFORM.spad
+ @ echo 0 making ${MID}/OUTFORM.NRLIB from ${MID}/OUTFORM.spad
+ @ (cd ${MID} ; echo ')co OUTFORM.spad' | ${INTERPSYS} )
+
+@
+<<OUTFORM.spad (SPAD from IN)>>=
+${MID}/OUTFORM.spad: ${IN}/outform.spad.pamphlet
+ @ echo 0 making ${MID}/OUTFORM.spad from ${IN}/outform.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OUTFORM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OUTFORM OutputForm" ${IN}/outform.spad.pamphlet >OUTFORM.spad )
+
+@
+<<OUTFORM.o (BOOTSTRAP from MID)>>=
+${MID}/OUTFORM.o: ${MID}/OUTFORM.lsp
+ @ echo 0 making ${MID}/OUTFORM.o from ${MID}/OUTFORM.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "OUTFORM.lsp" :output-file "OUTFORM.o"))' | ${DEPSYS} )
+ @ cp ${MID}/OUTFORM.o ${OUT}/OUTFORM.o
+
+@
+<<OUTFORM.lsp (LISP from IN)>>=
+${MID}/OUTFORM.lsp: ${IN}/outform.spad.pamphlet
+ @ echo 0 making ${MID}/OUTFORM.lsp from ${IN}/outform.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OUTFORM.NRLIB ; \
+ rm -rf ${OUT}/OUTFORM.o ; \
+ ${SPADBIN}/notangle -R"OUTFORM.lsp BOOTSTRAP" ${IN}/outform.spad.pamphlet >OUTFORM.lsp )
+
+@
+<<outform.spad.dvi (DOC from IN)>>=
+${DOC}/outform.spad.dvi: ${IN}/outform.spad.pamphlet
+ @ echo 0 making ${DOC}/outform.spad.dvi from ${IN}/outform.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/outform.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} outform.spad ; \
+ rm -f ${DOC}/outform.spad.pamphlet ; \
+ rm -f ${DOC}/outform.spad.tex ; \
+ rm -f ${DOC}/outform.spad )
+
+@
+\subsection{out.spad \cite{1}}
+<<out.spad (SPAD from IN)>>=
+${MID}/out.spad: ${IN}/out.spad.pamphlet
+ @ echo 0 making ${MID}/out.spad from ${IN}/out.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/out.spad.pamphlet >out.spad )
+
+@
+<<DISPLAY.o (O from NRLIB)>>=
+${OUT}/DISPLAY.o: ${MID}/DISPLAY.NRLIB
+ @ echo 0 making ${OUT}/DISPLAY.o from ${MID}/DISPLAY.NRLIB
+ @ cp ${MID}/DISPLAY.NRLIB/code.o ${OUT}/DISPLAY.o
+
+@
+<<DISPLAY.NRLIB (NRLIB from MID)>>=
+${MID}/DISPLAY.NRLIB: ${MID}/DISPLAY.spad
+ @ echo 0 making ${MID}/DISPLAY.NRLIB from ${MID}/DISPLAY.spad
+ @ (cd ${MID} ; echo ')co DISPLAY.spad' | ${INTERPSYS} )
+
+@
+<<DISPLAY.spad (SPAD from IN)>>=
+${MID}/DISPLAY.spad: ${IN}/out.spad.pamphlet
+ @ echo 0 making ${MID}/DISPLAY.spad from ${IN}/out.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DISPLAY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DISPLAY DisplayPackage" ${IN}/out.spad.pamphlet >DISPLAY.spad )
+
+@
+<<OUT.o (O from NRLIB)>>=
+${OUT}/OUT.o: ${MID}/OUT.NRLIB
+ @ echo 0 making ${OUT}/OUT.o from ${MID}/OUT.NRLIB
+ @ cp ${MID}/OUT.NRLIB/code.o ${OUT}/OUT.o
+
+@
+<<OUT.NRLIB (NRLIB from MID)>>=
+${MID}/OUT.NRLIB: ${MID}/OUT.spad
+ @ echo 0 making ${MID}/OUT.NRLIB from ${MID}/OUT.spad
+ @ (cd ${MID} ; echo ')co OUT.spad' | ${INTERPSYS} )
+
+@
+<<OUT.spad (SPAD from IN)>>=
+${MID}/OUT.spad: ${IN}/out.spad.pamphlet
+ @ echo 0 making ${MID}/OUT.spad from ${IN}/out.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OUT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package OUT OutputPackage" ${IN}/out.spad.pamphlet >OUT.spad )
+
+@
+<<SPECOUT.o (O from NRLIB)>>=
+${OUT}/SPECOUT.o: ${MID}/SPECOUT.NRLIB
+ @ echo 0 making ${OUT}/SPECOUT.o from ${MID}/SPECOUT.NRLIB
+ @ cp ${MID}/SPECOUT.NRLIB/code.o ${OUT}/SPECOUT.o
+
+@
+<<SPECOUT.NRLIB (NRLIB from MID)>>=
+${MID}/SPECOUT.NRLIB: ${MID}/SPECOUT.spad
+ @ echo 0 making ${MID}/SPECOUT.NRLIB from ${MID}/SPECOUT.spad
+ @ (cd ${MID} ; echo ')co SPECOUT.spad' | ${INTERPSYS} )
+
+@
+<<SPECOUT.spad (SPAD from IN)>>=
+${MID}/SPECOUT.spad: ${IN}/out.spad.pamphlet
+ @ echo 0 making ${MID}/SPECOUT.spad from ${IN}/out.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SPECOUT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SPECOUT SpecialOutputPackage" ${IN}/out.spad.pamphlet >SPECOUT.spad )
+
+@
+<<out.spad.dvi (DOC from IN)>>=
+${DOC}/out.spad.dvi: ${IN}/out.spad.pamphlet
+ @ echo 0 making ${DOC}/out.spad.dvi from ${IN}/out.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/out.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} out.spad ; \
+ rm -f ${DOC}/out.spad.pamphlet ; \
+ rm -f ${DOC}/out.spad.tex ; \
+ rm -f ${DOC}/out.spad )
+
+@
+\subsection{pade.spad \cite{1}}
+<<pade.spad (SPAD from IN)>>=
+${MID}/pade.spad: ${IN}/pade.spad.pamphlet
+ @ echo 0 making ${MID}/pade.spad from ${IN}/pade.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pade.spad.pamphlet >pade.spad )
+
+@
+<<PADE.o (O from NRLIB)>>=
+${OUT}/PADE.o: ${MID}/PADE.NRLIB
+ @ echo 0 making ${OUT}/PADE.o from ${MID}/PADE.NRLIB
+ @ cp ${MID}/PADE.NRLIB/code.o ${OUT}/PADE.o
+
+@
+<<PADE.NRLIB (NRLIB from MID)>>=
+${MID}/PADE.NRLIB: ${MID}/PADE.spad
+ @ echo 0 making ${MID}/PADE.NRLIB from ${MID}/PADE.spad
+ @ (cd ${MID} ; echo ')co PADE.spad' | ${INTERPSYS} )
+
+@
+<<PADE.spad (SPAD from IN)>>=
+${MID}/PADE.spad: ${IN}/pade.spad.pamphlet
+ @ echo 0 making ${MID}/PADE.spad from ${IN}/pade.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PADE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PADE PadeApproximants" ${IN}/pade.spad.pamphlet >PADE.spad )
+
+@
+<<PADEPAC.o (O from NRLIB)>>=
+${OUT}/PADEPAC.o: ${MID}/PADEPAC.NRLIB
+ @ echo 0 making ${OUT}/PADEPAC.o from ${MID}/PADEPAC.NRLIB
+ @ cp ${MID}/PADEPAC.NRLIB/code.o ${OUT}/PADEPAC.o
+
+@
+<<PADEPAC.NRLIB (NRLIB from MID)>>=
+${MID}/PADEPAC.NRLIB: ${MID}/PADEPAC.spad
+ @ echo 0 making ${MID}/PADEPAC.NRLIB from ${MID}/PADEPAC.spad
+ @ (cd ${MID} ; echo ')co PADEPAC.spad' | ${INTERPSYS} )
+
+@
+<<PADEPAC.spad (SPAD from IN)>>=
+${MID}/PADEPAC.spad: ${IN}/pade.spad.pamphlet
+ @ echo 0 making ${MID}/PADEPAC.spad from ${IN}/pade.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PADEPAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PADEPAC PadeApproximantPackage" ${IN}/pade.spad.pamphlet >PADEPAC.spad )
+
+@
+<<pade.spad.dvi (DOC from IN)>>=
+${DOC}/pade.spad.dvi: ${IN}/pade.spad.pamphlet
+ @ echo 0 making ${DOC}/pade.spad.dvi from ${IN}/pade.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pade.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pade.spad ; \
+ rm -f ${DOC}/pade.spad.pamphlet ; \
+ rm -f ${DOC}/pade.spad.tex ; \
+ rm -f ${DOC}/pade.spad )
+
+@
+\subsection{padiclib.spad \cite{1}}
+<<padiclib.spad (SPAD from IN)>>=
+${MID}/padiclib.spad: ${IN}/padiclib.spad.pamphlet
+ @ echo 0 making ${MID}/padiclib.spad from ${IN}/padiclib.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/padiclib.spad.pamphlet >padiclib.spad )
+
+@
+<<IBACHIN.o (O from NRLIB)>>=
+${OUT}/IBACHIN.o: ${MID}/IBACHIN.NRLIB
+ @ echo 0 making ${OUT}/IBACHIN.o from ${MID}/IBACHIN.NRLIB
+ @ cp ${MID}/IBACHIN.NRLIB/code.o ${OUT}/IBACHIN.o
+
+@
+<<IBACHIN.NRLIB (NRLIB from MID)>>=
+${MID}/IBACHIN.NRLIB: ${MID}/IBACHIN.spad
+ @ echo 0 making ${MID}/IBACHIN.NRLIB from ${MID}/IBACHIN.spad
+ @ (cd ${MID} ; echo ')co IBACHIN.spad' | ${INTERPSYS} )
+
+@
+<<IBACHIN.spad (SPAD from IN)>>=
+${MID}/IBACHIN.spad: ${IN}/padiclib.spad.pamphlet
+ @ echo 0 making ${MID}/IBACHIN.spad from ${IN}/padiclib.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IBACHIN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IBACHIN ChineseRemainderToolsForIntegralBases" ${IN}/padiclib.spad.pamphlet >IBACHIN.spad )
+
+@
+<<IBPTOOLS.o (O from NRLIB)>>=
+${OUT}/IBPTOOLS.o: ${MID}/IBPTOOLS.NRLIB
+ @ echo 0 making ${OUT}/IBPTOOLS.o from ${MID}/IBPTOOLS.NRLIB
+ @ cp ${MID}/IBPTOOLS.NRLIB/code.o ${OUT}/IBPTOOLS.o
+
+@
+<<IBPTOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/IBPTOOLS.NRLIB: ${MID}/IBPTOOLS.spad
+ @ echo 0 making ${MID}/IBPTOOLS.NRLIB from ${MID}/IBPTOOLS.spad
+ @ (cd ${MID} ; echo ')co IBPTOOLS.spad' | ${INTERPSYS} )
+
+@
+<<IBPTOOLS.spad (SPAD from IN)>>=
+${MID}/IBPTOOLS.spad: ${IN}/padiclib.spad.pamphlet
+ @ echo 0 making ${MID}/IBPTOOLS.spad from ${IN}/padiclib.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IBPTOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package IBPTOOLS IntegralBasisPolynomialTools" ${IN}/padiclib.spad.pamphlet >IBPTOOLS.spad )
+
+@
+<<PWFFINTB.o (O from NRLIB)>>=
+${OUT}/PWFFINTB.o: ${MID}/PWFFINTB.NRLIB
+ @ echo 0 making ${OUT}/PWFFINTB.o from ${MID}/PWFFINTB.NRLIB
+ @ cp ${MID}/PWFFINTB.NRLIB/code.o ${OUT}/PWFFINTB.o
+
+@
+<<PWFFINTB.NRLIB (NRLIB from MID)>>=
+${MID}/PWFFINTB.NRLIB: ${MID}/PWFFINTB.spad
+ @ echo 0 making ${MID}/PWFFINTB.NRLIB from ${MID}/PWFFINTB.spad
+ @ (cd ${MID} ; echo ')co PWFFINTB.spad' | ${INTERPSYS} )
+
+@
+<<PWFFINTB.spad (SPAD from IN)>>=
+${MID}/PWFFINTB.spad: ${IN}/padiclib.spad.pamphlet
+ @ echo 0 making ${MID}/PWFFINTB.spad from ${IN}/padiclib.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PWFFINTB.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PWFFINTB PAdicWildFunctionFieldIntegralBasis" ${IN}/padiclib.spad.pamphlet >PWFFINTB.spad )
+
+@
+<<padiclib.spad.dvi (DOC from IN)>>=
+${DOC}/padiclib.spad.dvi: ${IN}/padiclib.spad.pamphlet
+ @ echo 0 making ${DOC}/padiclib.spad.dvi from ${IN}/padiclib.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/padiclib.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} padiclib.spad ; \
+ rm -f ${DOC}/padiclib.spad.pamphlet ; \
+ rm -f ${DOC}/padiclib.spad.tex ; \
+ rm -f ${DOC}/padiclib.spad )
+
+@
+\subsection{padic.spad \cite{1}}
+<<padic.spad (SPAD from IN)>>=
+${MID}/padic.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/padic.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/padic.spad.pamphlet >padic.spad )
+
+@
+<<BPADIC.o (O from NRLIB)>>=
+${OUT}/BPADIC.o: ${MID}/BPADIC.NRLIB
+ @ echo 0 making ${OUT}/BPADIC.o from ${MID}/BPADIC.NRLIB
+ @ cp ${MID}/BPADIC.NRLIB/code.o ${OUT}/BPADIC.o
+
+@
+<<BPADIC.NRLIB (NRLIB from MID)>>=
+${MID}/BPADIC.NRLIB: ${MID}/BPADIC.spad
+ @ echo 0 making ${MID}/BPADIC.NRLIB from ${MID}/BPADIC.spad
+ @ (cd ${MID} ; echo ')co BPADIC.spad' | ${INTERPSYS} )
+
+@
+<<BPADIC.spad (SPAD from IN)>>=
+${MID}/BPADIC.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/BPADIC.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BPADIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BPADIC BalancedPAdicInteger" ${IN}/padic.spad.pamphlet >BPADIC.spad )
+
+@
+<<BPADICRT.o (O from NRLIB)>>=
+${OUT}/BPADICRT.o: ${MID}/BPADICRT.NRLIB
+ @ echo 0 making ${OUT}/BPADICRT.o from ${MID}/BPADICRT.NRLIB
+ @ cp ${MID}/BPADICRT.NRLIB/code.o ${OUT}/BPADICRT.o
+
+@
+<<BPADICRT.NRLIB (NRLIB from MID)>>=
+${MID}/BPADICRT.NRLIB: ${MID}/BPADICRT.spad
+ @ echo 0 making ${MID}/BPADICRT.NRLIB from ${MID}/BPADICRT.spad
+ @ (cd ${MID} ; echo ')co BPADICRT.spad' | ${INTERPSYS} )
+
+@
+<<BPADICRT.spad (SPAD from IN)>>=
+${MID}/BPADICRT.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/BPADICRT.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BPADICRT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BPADICRT BalancedPAdicRational" ${IN}/padic.spad.pamphlet >BPADICRT.spad )
+
+@
+<<IPADIC.o (O from NRLIB)>>=
+${OUT}/IPADIC.o: ${MID}/IPADIC.NRLIB
+ @ echo 0 making ${OUT}/IPADIC.o from ${MID}/IPADIC.NRLIB
+ @ cp ${MID}/IPADIC.NRLIB/code.o ${OUT}/IPADIC.o
+
+@
+<<IPADIC.NRLIB (NRLIB from MID)>>=
+${MID}/IPADIC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/IPADIC.spad
+ @ echo 0 making ${MID}/IPADIC.NRLIB from ${MID}/IPADIC.spad
+ @ (cd ${MID} ; echo ')co IPADIC.spad' | ${INTERPSYS} )
+
+@
+<<IPADIC.spad (SPAD from IN)>>=
+${MID}/IPADIC.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/IPADIC.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IPADIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IPADIC InnerPAdicInteger" ${IN}/padic.spad.pamphlet >IPADIC.spad )
+
+@
+<<PADIC.o (O from NRLIB)>>=
+${OUT}/PADIC.o: ${MID}/PADIC.NRLIB
+ @ echo 0 making ${OUT}/PADIC.o from ${MID}/PADIC.NRLIB
+ @ cp ${MID}/PADIC.NRLIB/code.o ${OUT}/PADIC.o
+
+@
+<<PADIC.NRLIB (NRLIB from MID)>>=
+${MID}/PADIC.NRLIB: ${MID}/PADIC.spad
+ @ echo 0 making ${MID}/PADIC.NRLIB from ${MID}/PADIC.spad
+ @ (cd ${MID} ; echo ')co PADIC.spad' | ${INTERPSYS} )
+
+@
+<<PADIC.spad (SPAD from IN)>>=
+${MID}/PADIC.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/PADIC.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PADIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PADIC PAdicInteger" ${IN}/padic.spad.pamphlet >PADIC.spad )
+
+@
+<<PADICCT.o (O from NRLIB)>>=
+${OUT}/PADICCT.o: ${MID}/PADICCT.NRLIB
+ @ echo 0 making ${OUT}/PADICCT.o from ${MID}/PADICCT.NRLIB
+ @ cp ${MID}/PADICCT.NRLIB/code.o ${OUT}/PADICCT.o
+
+@
+<<PADICCT.NRLIB (NRLIB from MID)>>=
+${MID}/PADICCT.NRLIB: ${MID}/PADICCT.spad
+ @ echo 0 making ${MID}/PADICCT.NRLIB from ${MID}/PADICCT.spad
+ @ (cd ${MID} ; echo ')co PADICCT.spad' | ${INTERPSYS} )
+
+@
+<<PADICCT.spad (SPAD from IN)>>=
+${MID}/PADICCT.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/PADICCT.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PADICCT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PADICCT PAdicIntegerCategory" ${IN}/padic.spad.pamphlet >PADICCT.spad )
+
+@
+<<PADICRAT.o (O from NRLIB)>>=
+${OUT}/PADICRAT.o: ${MID}/PADICRAT.NRLIB
+ @ echo 0 making ${OUT}/PADICRAT.o from ${MID}/PADICRAT.NRLIB
+ @ cp ${MID}/PADICRAT.NRLIB/code.o ${OUT}/PADICRAT.o
+
+@
+<<PADICRAT.NRLIB (NRLIB from MID)>>=
+${MID}/PADICRAT.NRLIB: ${MID}/PADICRAT.spad
+ @ echo 0 making ${MID}/PADICRAT.NRLIB from ${MID}/PADICRAT.spad
+ @ (cd ${MID} ; echo ')co PADICRAT.spad' | ${INTERPSYS} )
+
+@
+<<PADICRAT.spad (SPAD from IN)>>=
+${MID}/PADICRAT.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/PADICRAT.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PADICRAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PADICRAT PAdicRational" ${IN}/padic.spad.pamphlet >PADICRAT.spad )
+
+@
+<<PADICRC.o (O from NRLIB)>>=
+${OUT}/PADICRC.o: ${MID}/PADICRC.NRLIB
+ @ echo 0 making ${OUT}/PADICRC.o from ${MID}/PADICRC.NRLIB
+ @ cp ${MID}/PADICRC.NRLIB/code.o ${OUT}/PADICRC.o
+
+@
+<<PADICRC.NRLIB (NRLIB from MID)>>=
+${MID}/PADICRC.NRLIB: ${MID}/PADICRC.spad
+ @ echo 0 making ${MID}/PADICRC.NRLIB from ${MID}/PADICRC.spad
+ @ (cd ${MID} ; echo ')co PADICRC.spad' | ${INTERPSYS} )
+
+@
+<<PADICRC.spad (SPAD from IN)>>=
+${MID}/PADICRC.spad: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${MID}/PADICRC.spad from ${IN}/padic.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PADICRC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PADICRC PAdicRationalConstructor" ${IN}/padic.spad.pamphlet >PADICRC.spad )
+
+@
+<<padic.spad.dvi (DOC from IN)>>=
+${DOC}/padic.spad.dvi: ${IN}/padic.spad.pamphlet
+ @ echo 0 making ${DOC}/padic.spad.dvi from ${IN}/padic.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/padic.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} padic.spad ; \
+ rm -f ${DOC}/padic.spad.pamphlet ; \
+ rm -f ${DOC}/padic.spad.tex ; \
+ rm -f ${DOC}/padic.spad )
+
+@
+\subsection{paramete.spad \cite{1}}
+<<paramete.spad (SPAD from IN)>>=
+${MID}/paramete.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/paramete.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/paramete.spad.pamphlet >paramete.spad )
+
+@
+<<PARPCURV.o (O from NRLIB)>>=
+${OUT}/PARPCURV.o: ${MID}/PARPCURV.NRLIB
+ @ echo 0 making ${OUT}/PARPCURV.o from ${MID}/PARPCURV.NRLIB
+ @ cp ${MID}/PARPCURV.NRLIB/code.o ${OUT}/PARPCURV.o
+
+@
+<<PARPCURV.NRLIB (NRLIB from MID)>>=
+${MID}/PARPCURV.NRLIB: ${MID}/PARPCURV.spad
+ @ echo 0 making ${MID}/PARPCURV.NRLIB from ${MID}/PARPCURV.spad
+ @ (cd ${MID} ; echo ')co PARPCURV.spad' | ${INTERPSYS} )
+
+@
+<<PARPCURV.spad (SPAD from IN)>>=
+${MID}/PARPCURV.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/PARPCURV.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARPCURV.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PARPCURV ParametricPlaneCurve" ${IN}/paramete.spad.pamphlet >PARPCURV.spad )
+
+@
+<<PARPC2.o (O from NRLIB)>>=
+${OUT}/PARPC2.o: ${MID}/PARPC2.NRLIB
+ @ echo 0 making ${OUT}/PARPC2.o from ${MID}/PARPC2.NRLIB
+ @ cp ${MID}/PARPC2.NRLIB/code.o ${OUT}/PARPC2.o
+
+@
+<<PARPC2.NRLIB (NRLIB from MID)>>=
+${MID}/PARPC2.NRLIB: ${MID}/PARPC2.spad
+ @ echo 0 making ${MID}/PARPC2.NRLIB from ${MID}/PARPC2.spad
+ @ (cd ${MID} ; echo ')co PARPC2.spad' | ${INTERPSYS} )
+
+@
+<<PARPC2.spad (SPAD from IN)>>=
+${MID}/PARPC2.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/PARPC2.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARPC2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PARPC2 ParametricPlaneCurveFunctions2" ${IN}/paramete.spad.pamphlet >PARPC2.spad )
+
+@
+<<PARSCURV.o (O from NRLIB)>>=
+${OUT}/PARSCURV.o: ${MID}/PARSCURV.NRLIB
+ @ echo 0 making ${OUT}/PARSCURV.o from ${MID}/PARSCURV.NRLIB
+ @ cp ${MID}/PARSCURV.NRLIB/code.o ${OUT}/PARSCURV.o
+
+@
+<<PARSCURV.NRLIB (NRLIB from MID)>>=
+${MID}/PARSCURV.NRLIB: ${MID}/PARSCURV.spad
+ @ echo 0 making ${MID}/PARSCURV.NRLIB from ${MID}/PARSCURV.spad
+ @ (cd ${MID} ; echo ')co PARSCURV.spad' | ${INTERPSYS} )
+
+@
+<<PARSCURV.spad (SPAD from IN)>>=
+${MID}/PARSCURV.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/PARSCURV.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARSCURV.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PARSCURV ParametricSpaceCurve" ${IN}/paramete.spad.pamphlet >PARSCURV.spad )
+
+@
+<<PARSC2.o (O from NRLIB)>>=
+${OUT}/PARSC2.o: ${MID}/PARSC2.NRLIB
+ @ echo 0 making ${OUT}/PARSC2.o from ${MID}/PARSC2.NRLIB
+ @ cp ${MID}/PARSC2.NRLIB/code.o ${OUT}/PARSC2.o
+
+@
+<<PARSC2.NRLIB (NRLIB from MID)>>=
+${MID}/PARSC2.NRLIB: ${MID}/PARSC2.spad
+ @ echo 0 making ${MID}/PARSC2.NRLIB from ${MID}/PARSC2.spad
+ @ (cd ${MID} ; echo ')co PARSC2.spad' | ${INTERPSYS} )
+
+@
+<<PARSC2.spad (SPAD from IN)>>=
+${MID}/PARSC2.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/PARSC2.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARSC2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PARSC2 ParametricSpaceCurveFunctions2" ${IN}/paramete.spad.pamphlet >PARSC2.spad )
+
+@
+<<PARSURF.o (O from NRLIB)>>=
+${OUT}/PARSURF.o: ${MID}/PARSURF.NRLIB
+ @ echo 0 making ${OUT}/PARSURF.o from ${MID}/PARSURF.NRLIB
+ @ cp ${MID}/PARSURF.NRLIB/code.o ${OUT}/PARSURF.o
+
+@
+<<PARSURF.NRLIB (NRLIB from MID)>>=
+${MID}/PARSURF.NRLIB: ${MID}/PARSURF.spad
+ @ echo 0 making ${MID}/PARSURF.NRLIB from ${MID}/PARSURF.spad
+ @ (cd ${MID} ; echo ')co PARSURF.spad' | ${INTERPSYS} )
+
+@
+<<PARSURF.spad (SPAD from IN)>>=
+${MID}/PARSURF.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/PARSURF.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARSURF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PARSURF ParametricSurface" ${IN}/paramete.spad.pamphlet >PARSURF.spad )
+
+@
+<<PARSU2.o (O from NRLIB)>>=
+${OUT}/PARSU2.o: ${MID}/PARSU2.NRLIB
+ @ echo 0 making ${OUT}/PARSU2.o from ${MID}/PARSU2.NRLIB
+ @ cp ${MID}/PARSU2.NRLIB/code.o ${OUT}/PARSU2.o
+
+@
+<<PARSU2.NRLIB (NRLIB from MID)>>=
+${MID}/PARSU2.NRLIB: ${MID}/PARSU2.spad
+ @ echo 0 making ${MID}/PARSU2.NRLIB from ${MID}/PARSU2.spad
+ @ (cd ${MID} ; echo ')co PARSU2.spad' | ${INTERPSYS} )
+
+@
+<<PARSU2.spad (SPAD from IN)>>=
+${MID}/PARSU2.spad: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${MID}/PARSU2.spad from ${IN}/paramete.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARSU2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PARSU2 ParametricSurfaceFunctions2" ${IN}/paramete.spad.pamphlet >PARSU2.spad )
+
+@
+<<paramete.spad.dvi (DOC from IN)>>=
+${DOC}/paramete.spad.dvi: ${IN}/paramete.spad.pamphlet
+ @ echo 0 making ${DOC}/paramete.spad.dvi from ${IN}/paramete.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/paramete.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} paramete.spad ; \
+ rm -f ${DOC}/paramete.spad.pamphlet ; \
+ rm -f ${DOC}/paramete.spad.tex ; \
+ rm -f ${DOC}/paramete.spad )
+
+@
+\subsection{partperm.spad \cite{1}}
+<<partperm.spad (SPAD from IN)>>=
+${MID}/partperm.spad: ${IN}/partperm.spad.pamphlet
+ @ echo 0 making ${MID}/partperm.spad from ${IN}/partperm.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/partperm.spad.pamphlet >partperm.spad )
+
+@
+<<PARTPERM.o (O from NRLIB)>>=
+${OUT}/PARTPERM.o: ${MID}/PARTPERM.NRLIB
+ @ echo 0 making ${OUT}/PARTPERM.o from ${MID}/PARTPERM.NRLIB
+ @ cp ${MID}/PARTPERM.NRLIB/code.o ${OUT}/PARTPERM.o
+
+@
+<<PARTPERM.NRLIB (NRLIB from MID)>>=
+${MID}/PARTPERM.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PARTPERM.spad
+ @ echo 0 making ${MID}/PARTPERM.NRLIB from ${MID}/PARTPERM.spad
+ @ (cd ${MID} ; echo ')co PARTPERM.spad' | ${INTERPSYS} )
+
+@
+<<PARTPERM.spad (SPAD from IN)>>=
+${MID}/PARTPERM.spad: ${IN}/partperm.spad.pamphlet
+ @ echo 0 making ${MID}/PARTPERM.spad from ${IN}/partperm.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PARTPERM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PARTPERM PartitionsAndPermutations" ${IN}/partperm.spad.pamphlet >PARTPERM.spad )
+
+@
+<<partperm.spad.dvi (DOC from IN)>>=
+${DOC}/partperm.spad.dvi: ${IN}/partperm.spad.pamphlet
+ @ echo 0 making ${DOC}/partperm.spad.dvi from ${IN}/partperm.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/partperm.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} partperm.spad ; \
+ rm -f ${DOC}/partperm.spad.pamphlet ; \
+ rm -f ${DOC}/partperm.spad.tex ; \
+ rm -f ${DOC}/partperm.spad )
+
+@
+\subsection{patmatch1.spad \cite{1}}
+<<patmatch1.spad (SPAD from IN)>>=
+${MID}/patmatch1.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/patmatch1.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/patmatch1.spad.pamphlet >patmatch1.spad )
+
+@
+<<FPATMAB.o (O from NRLIB)>>=
+${OUT}/FPATMAB.o: ${MID}/FPATMAB.NRLIB
+ @ echo 0 making ${OUT}/FPATMAB.o from ${MID}/FPATMAB.NRLIB
+ @ cp ${MID}/FPATMAB.NRLIB/code.o ${OUT}/FPATMAB.o
+
+@
+<<FPATMAB.NRLIB (NRLIB from MID)>>=
+${MID}/FPATMAB.NRLIB: ${MID}/FPATMAB.spad
+ @ echo 0 making ${MID}/FPATMAB.NRLIB from ${MID}/FPATMAB.spad
+ @ (cd ${MID} ; echo ')co FPATMAB.spad' | ${INTERPSYS} )
+
+@
+<<FPATMAB.spad (SPAD from IN)>>=
+${MID}/FPATMAB.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/FPATMAB.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FPATMAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FPATMAB FullyPatternMatchable" ${IN}/patmatch1.spad.pamphlet >FPATMAB.spad )
+
+@
+<<PATLRES.o (O from NRLIB)>>=
+${OUT}/PATLRES.o: ${MID}/PATLRES.NRLIB
+ @ echo 0 making ${OUT}/PATLRES.o from ${MID}/PATLRES.NRLIB
+ @ cp ${MID}/PATLRES.NRLIB/code.o ${OUT}/PATLRES.o
+
+@
+<<PATLRES.NRLIB (NRLIB from MID)>>=
+${MID}/PATLRES.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/PATLRES.spad
+ @ echo 0 making ${MID}/PATLRES.NRLIB from ${MID}/PATLRES.spad
+ @ (cd ${MID} ; echo ')co PATLRES.spad' | ${INTERPSYS} )
+
+@
+<<PATLRES.spad (SPAD from IN)>>=
+${MID}/PATLRES.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PATLRES.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATLRES.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PATLRES PatternMatchListResult" ${IN}/patmatch1.spad.pamphlet >PATLRES.spad )
+
+@
+<<PATMAB.o (O from NRLIB)>>=
+${OUT}/PATMAB.o: ${MID}/PATMAB.NRLIB
+ @ echo 0 making ${OUT}/PATMAB.o from ${MID}/PATMAB.NRLIB
+ @ cp ${MID}/PATMAB.NRLIB/code.o ${OUT}/PATMAB.o
+
+@
+<<PATMAB.NRLIB (NRLIB from MID)>>=
+${MID}/PATMAB.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/PATMAB.spad
+ @ echo 0 making ${MID}/PATMAB.NRLIB from ${MID}/PATMAB.spad
+ @ (cd ${MID} ; echo ')co PATMAB.spad' | ${INTERPSYS} )
+
+@
+<<PATMAB.spad (SPAD from IN)>>=
+${MID}/PATMAB.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PATMAB.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATMAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PATMAB PatternMatchable" ${IN}/patmatch1.spad.pamphlet >PATMAB.spad )
+
+@
+<<PATRES.o (O from NRLIB)>>=
+${OUT}/PATRES.o: ${MID}/PATRES.NRLIB
+ @ echo 0 making ${OUT}/PATRES.o from ${MID}/PATRES.NRLIB
+ @ cp ${MID}/PATRES.NRLIB/code.o ${OUT}/PATRES.o
+
+@
+<<PATRES.NRLIB (NRLIB from MID)>>=
+${MID}/PATRES.NRLIB: ${MID}/PATRES.spad
+ @ echo 0 making ${MID}/PATRES.NRLIB from ${MID}/PATRES.spad
+ @ (cd ${MID} ; echo ')co PATRES.spad' | ${INTERPSYS} )
+
+@
+<<PATRES.spad (SPAD from IN)>>=
+${MID}/PATRES.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PATRES.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATRES.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PATRES PatternMatchResult" ${IN}/patmatch1.spad.pamphlet >PATRES.spad )
+
+@
+<<PATRES2.o (O from NRLIB)>>=
+${OUT}/PATRES2.o: ${MID}/PATRES2.NRLIB
+ @ echo 0 making ${OUT}/PATRES2.o from ${MID}/PATRES2.NRLIB
+ @ cp ${MID}/PATRES2.NRLIB/code.o ${OUT}/PATRES2.o
+
+@
+<<PATRES2.NRLIB (NRLIB from MID)>>=
+${MID}/PATRES2.NRLIB: ${MID}/PATRES2.spad
+ @ echo 0 making ${MID}/PATRES2.NRLIB from ${MID}/PATRES2.spad
+ @ (cd ${MID} ; echo ')co PATRES2.spad' | ${INTERPSYS} )
+
+@
+<<PATRES2.spad (SPAD from IN)>>=
+${MID}/PATRES2.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PATRES2.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATRES2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PATRES2 PatternMatchResultFunctions2" ${IN}/patmatch1.spad.pamphlet >PATRES2.spad )
+
+@
+<<PMDOWN.o (O from NRLIB)>>=
+${OUT}/PMDOWN.o: ${MID}/PMDOWN.NRLIB
+ @ echo 0 making ${OUT}/PMDOWN.o from ${MID}/PMDOWN.NRLIB
+ @ cp ${MID}/PMDOWN.NRLIB/code.o ${OUT}/PMDOWN.o
+
+@
+<<PMDOWN.NRLIB (NRLIB from MID)>>=
+${MID}/PMDOWN.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PMDOWN.spad
+ @ echo 0 making ${MID}/PMDOWN.NRLIB from ${MID}/PMDOWN.spad
+ @ (cd ${MID} ; echo ')co PMDOWN.spad' | ${INTERPSYS} )
+
+@
+<<PMDOWN.spad (SPAD from IN)>>=
+${MID}/PMDOWN.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PMDOWN.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMDOWN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMDOWN PatternMatchPushDown" ${IN}/patmatch1.spad.pamphlet >PMDOWN.spad )
+
+@
+<<PMKERNEL.o (O from NRLIB)>>=
+${OUT}/PMKERNEL.o: ${MID}/PMKERNEL.NRLIB
+ @ echo 0 making ${OUT}/PMKERNEL.o from ${MID}/PMKERNEL.NRLIB
+ @ cp ${MID}/PMKERNEL.NRLIB/code.o ${OUT}/PMKERNEL.o
+
+@
+<<PMKERNEL.NRLIB (NRLIB from MID)>>=
+${MID}/PMKERNEL.NRLIB: ${MID}/PMKERNEL.spad
+ @ echo 0 making ${MID}/PMKERNEL.NRLIB from ${MID}/PMKERNEL.spad
+ @ (cd ${MID} ; echo ')co PMKERNEL.spad' | ${INTERPSYS} )
+
+@
+<<PMKERNEL.spad (SPAD from IN)>>=
+${MID}/PMKERNEL.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PMKERNEL.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMKERNEL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMKERNEL PatternMatchKernel" ${IN}/patmatch1.spad.pamphlet >PMKERNEL.spad )
+
+@
+<<PMLSAGG.o (O from NRLIB)>>=
+${OUT}/PMLSAGG.o: ${MID}/PMLSAGG.NRLIB
+ @ echo 0 making ${OUT}/PMLSAGG.o from ${MID}/PMLSAGG.NRLIB
+ @ cp ${MID}/PMLSAGG.NRLIB/code.o ${OUT}/PMLSAGG.o
+
+@
+<<PMLSAGG.NRLIB (NRLIB from MID)>>=
+${MID}/PMLSAGG.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PMLSAGG.spad
+ @ echo 0 making ${MID}/PMLSAGG.NRLIB from ${MID}/PMLSAGG.spad
+ @ (cd ${MID} ; echo ')co PMLSAGG.spad' | ${INTERPSYS} )
+
+@
+<<PMLSAGG.spad (SPAD from IN)>>=
+${MID}/PMLSAGG.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PMLSAGG.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMLSAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMLSAGG PatternMatchListAggregate" ${IN}/patmatch1.spad.pamphlet >PMLSAGG.spad )
+
+@
+<<PMSYM.o (O from NRLIB)>>=
+${OUT}/PMSYM.o: ${MID}/PMSYM.NRLIB
+ @ echo 0 making ${OUT}/PMSYM.o from ${MID}/PMSYM.NRLIB
+ @ cp ${MID}/PMSYM.NRLIB/code.o ${OUT}/PMSYM.o
+
+@
+<<PMSYM.NRLIB (NRLIB from MID)>>=
+${MID}/PMSYM.NRLIB: ${MID}/PMSYM.spad
+ @ echo 0 making ${MID}/PMSYM.NRLIB from ${MID}/PMSYM.spad
+ @ (cd ${MID} ; echo ')co PMSYM.spad' | ${INTERPSYS} )
+
+@
+<<PMSYM.spad (SPAD from IN)>>=
+${MID}/PMSYM.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PMSYM.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMSYM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMSYM PatternMatchSymbol" ${IN}/patmatch1.spad.pamphlet >PMSYM.spad )
+
+@
+<<PMTOOLS.o (O from NRLIB)>>=
+${OUT}/PMTOOLS.o: ${MID}/PMTOOLS.NRLIB
+ @ echo 0 making ${OUT}/PMTOOLS.o from ${MID}/PMTOOLS.NRLIB
+ @ cp ${MID}/PMTOOLS.NRLIB/code.o ${OUT}/PMTOOLS.o
+
+@
+<<PMTOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/PMTOOLS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PMTOOLS.spad
+ @ echo 0 making ${MID}/PMTOOLS.NRLIB from ${MID}/PMTOOLS.spad
+ @ (cd ${MID} ; echo ')co PMTOOLS.spad' | ${INTERPSYS} )
+
+@
+<<PMTOOLS.spad (SPAD from IN)>>=
+${MID}/PMTOOLS.spad: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${MID}/PMTOOLS.spad from ${IN}/patmatch1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMTOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMTOOLS PatternMatchTools" ${IN}/patmatch1.spad.pamphlet >PMTOOLS.spad )
+
+@
+<<patmatch1.spad.dvi (DOC from IN)>>=
+${DOC}/patmatch1.spad.dvi: ${IN}/patmatch1.spad.pamphlet
+ @ echo 0 making ${DOC}/patmatch1.spad.dvi from ${IN}/patmatch1.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/patmatch1.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} patmatch1.spad ; \
+ rm -f ${DOC}/patmatch1.spad.pamphlet ; \
+ rm -f ${DOC}/patmatch1.spad.tex ; \
+ rm -f ${DOC}/patmatch1.spad )
+
+@
+\subsection{patmatch2.spad \cite{1}}
+<<patmatch2.spad (SPAD from IN)>>=
+${MID}/patmatch2.spad: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${MID}/patmatch2.spad from ${IN}/patmatch2.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/patmatch2.spad.pamphlet >patmatch2.spad )
+
+@
+<<PATMATCH.o (O from NRLIB)>>=
+${OUT}/PATMATCH.o: ${MID}/PATMATCH.NRLIB
+ @ echo 0 making ${OUT}/PATMATCH.o from ${MID}/PATMATCH.NRLIB
+ @ cp ${MID}/PATMATCH.NRLIB/code.o ${OUT}/PATMATCH.o
+
+@
+<<PATMATCH.NRLIB (NRLIB from MID)>>=
+${MID}/PATMATCH.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PATMATCH.spad
+ @ echo 0 making ${MID}/PATMATCH.NRLIB from ${MID}/PATMATCH.spad
+ @ (cd ${MID} ; echo ')co PATMATCH.spad' | ${INTERPSYS} )
+
+@
+<<PATMATCH.spad (SPAD from IN)>>=
+${MID}/PATMATCH.spad: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${MID}/PATMATCH.spad from ${IN}/patmatch2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATMATCH.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PATMATCH PatternMatch" ${IN}/patmatch2.spad.pamphlet >PATMATCH.spad )
+
+@
+<<PMFS.o (O from NRLIB)>>=
+${OUT}/PMFS.o: ${MID}/PMFS.NRLIB
+ @ echo 0 making ${OUT}/PMFS.o from ${MID}/PMFS.NRLIB
+ @ cp ${MID}/PMFS.NRLIB/code.o ${OUT}/PMFS.o
+
+@
+<<PMFS.NRLIB (NRLIB from MID)>>=
+${MID}/PMFS.NRLIB: ${MID}/PMFS.spad
+ @ echo 0 making ${MID}/PMFS.NRLIB from ${MID}/PMFS.spad
+ @ (cd ${MID} ; echo ')co PMFS.spad' | ${INTERPSYS} )
+
+@
+<<PMFS.spad (SPAD from IN)>>=
+${MID}/PMFS.spad: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${MID}/PMFS.spad from ${IN}/patmatch2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMFS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMFS PatternMatchFunctionSpace" ${IN}/patmatch2.spad.pamphlet >PMFS.spad )
+
+@
+<<PMINS.o (O from NRLIB)>>=
+${OUT}/PMINS.o: ${MID}/PMINS.NRLIB
+ @ echo 0 making ${OUT}/PMINS.o from ${MID}/PMINS.NRLIB
+ @ cp ${MID}/PMINS.NRLIB/code.o ${OUT}/PMINS.o
+
+@
+<<PMINS.NRLIB (NRLIB from MID)>>=
+${MID}/PMINS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PMINS.spad
+ @ echo 0 making ${MID}/PMINS.NRLIB from ${MID}/PMINS.spad
+ @ (cd ${MID} ; echo ')co PMINS.spad' | ${INTERPSYS} )
+
+@
+<<PMINS.spad (SPAD from IN)>>=
+${MID}/PMINS.spad: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${MID}/PMINS.spad from ${IN}/patmatch2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMINS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMINS PatternMatchIntegerNumberSystem" ${IN}/patmatch2.spad.pamphlet >PMINS.spad )
+
+@
+<<PMPLCAT.o (O from NRLIB)>>=
+${OUT}/PMPLCAT.o: ${MID}/PMPLCAT.NRLIB
+ @ echo 0 making ${OUT}/PMPLCAT.o from ${MID}/PMPLCAT.NRLIB
+ @ cp ${MID}/PMPLCAT.NRLIB/code.o ${OUT}/PMPLCAT.o
+
+@
+<<PMPLCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PMPLCAT.NRLIB: ${MID}/PMPLCAT.spad
+ @ echo 0 making ${MID}/PMPLCAT.NRLIB from ${MID}/PMPLCAT.spad
+ @ (cd ${MID} ; echo ')co PMPLCAT.spad' | ${INTERPSYS} )
+
+@
+<<PMPLCAT.spad (SPAD from IN)>>=
+${MID}/PMPLCAT.spad: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${MID}/PMPLCAT.spad from ${IN}/patmatch2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMPLCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMPLCAT PatternMatchPolynomialCategory" ${IN}/patmatch2.spad.pamphlet >PMPLCAT.spad )
+
+@
+<<PMQFCAT.o (O from NRLIB)>>=
+${OUT}/PMQFCAT.o: ${MID}/PMQFCAT.NRLIB
+ @ echo 0 making ${OUT}/PMQFCAT.o from ${MID}/PMQFCAT.NRLIB
+ @ cp ${MID}/PMQFCAT.NRLIB/code.o ${OUT}/PMQFCAT.o
+
+@
+<<PMQFCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PMQFCAT.NRLIB: ${MID}/PMQFCAT.spad
+ @ echo 0 making ${MID}/PMQFCAT.NRLIB from ${MID}/PMQFCAT.spad
+ @ (cd ${MID} ; echo ')co PMQFCAT.spad' | ${INTERPSYS} )
+
+@
+<<PMQFCAT.spad (SPAD from IN)>>=
+${MID}/PMQFCAT.spad: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${MID}/PMQFCAT.spad from ${IN}/patmatch2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PMQFCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PMQFCAT PatternMatchQuotientFieldCategory" ${IN}/patmatch2.spad.pamphlet >PMQFCAT.spad )
+
+@
+<<patmatch2.spad.dvi (DOC from IN)>>=
+${DOC}/patmatch2.spad.dvi: ${IN}/patmatch2.spad.pamphlet
+ @ echo 0 making ${DOC}/patmatch2.spad.dvi from ${IN}/patmatch2.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/patmatch2.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} patmatch2.spad ; \
+ rm -f ${DOC}/patmatch2.spad.pamphlet ; \
+ rm -f ${DOC}/patmatch2.spad.tex ; \
+ rm -f ${DOC}/patmatch2.spad )
+
+@
+\subsection{pattern.spad \cite{1}}
+<<pattern.spad (SPAD from IN)>>=
+${MID}/pattern.spad: ${IN}/pattern.spad.pamphlet
+ @ echo 0 making ${MID}/pattern.spad from ${IN}/pattern.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pattern.spad.pamphlet >pattern.spad )
+
+@
+<<PATAB.o (O from NRLIB)>>=
+${OUT}/PATAB.o: ${MID}/PATAB.NRLIB
+ @ echo 0 making ${OUT}/PATAB.o from ${MID}/PATAB.NRLIB
+ @ cp ${MID}/PATAB.NRLIB/code.o ${OUT}/PATAB.o
+
+@
+<<PATAB.NRLIB (NRLIB from MID)>>=
+${MID}/PATAB.NRLIB: ${OUT}/KONVERT.o ${MID}/PATAB.spad
+ @ echo 0 making ${MID}/PATAB.NRLIB from ${MID}/PATAB.spad
+ @ (cd ${MID} ; echo ')co PATAB.spad' | ${INTERPSYS} )
+
+@
+<<PATAB.spad (SPAD from IN)>>=
+${MID}/PATAB.spad: ${IN}/pattern.spad.pamphlet
+ @ echo 0 making ${MID}/PATAB.spad from ${IN}/pattern.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATAB.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PATAB Patternable" ${IN}/pattern.spad.pamphlet >PATAB.spad )
+
+@
+<<PATTERN.o (O from NRLIB)>>=
+${OUT}/PATTERN.o: ${MID}/PATTERN.NRLIB
+ @ echo 0 making ${OUT}/PATTERN.o from ${MID}/PATTERN.NRLIB
+ @ cp ${MID}/PATTERN.NRLIB/code.o ${OUT}/PATTERN.o
+
+@
+<<PATTERN.NRLIB (NRLIB from MID)>>=
+${MID}/PATTERN.NRLIB: ${MID}/PATTERN.spad
+ @ echo 0 making ${MID}/PATTERN.NRLIB from ${MID}/PATTERN.spad
+ @ (cd ${MID} ; echo ')co PATTERN.spad' | ${INTERPSYS} )
+
+@
+<<PATTERN.spad (SPAD from IN)>>=
+${MID}/PATTERN.spad: ${IN}/pattern.spad.pamphlet
+ @ echo 0 making ${MID}/PATTERN.spad from ${IN}/pattern.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATTERN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PATTERN Pattern" ${IN}/pattern.spad.pamphlet >PATTERN.spad )
+
+@
+<<PATTERN1.o (O from NRLIB)>>=
+${OUT}/PATTERN1.o: ${MID}/PATTERN1.NRLIB
+ @ echo 0 making ${OUT}/PATTERN1.o from ${MID}/PATTERN1.NRLIB
+ @ cp ${MID}/PATTERN1.NRLIB/code.o ${OUT}/PATTERN1.o
+
+@
+<<PATTERN1.NRLIB (NRLIB from MID)>>=
+${MID}/PATTERN1.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PATTERN1.spad
+ @ echo 0 making ${MID}/PATTERN1.NRLIB from ${MID}/PATTERN1.spad
+ @ (cd ${MID} ; echo ')co PATTERN1.spad' | ${INTERPSYS} )
+
+@
+<<PATTERN1.spad (SPAD from IN)>>=
+${MID}/PATTERN1.spad: ${IN}/pattern.spad.pamphlet
+ @ echo 0 making ${MID}/PATTERN1.spad from ${IN}/pattern.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATTERN1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PATTERN1 PatternFunctions1" ${IN}/pattern.spad.pamphlet >PATTERN1.spad )
+
+@
+<<PATTERN2.o (O from NRLIB)>>=
+${OUT}/PATTERN2.o: ${MID}/PATTERN2.NRLIB
+ @ echo 0 making ${OUT}/PATTERN2.o from ${MID}/PATTERN2.NRLIB
+ @ cp ${MID}/PATTERN2.NRLIB/code.o ${OUT}/PATTERN2.o
+
+@
+<<PATTERN2.NRLIB (NRLIB from MID)>>=
+${MID}/PATTERN2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PATTERN2.spad
+ @ echo 0 making ${MID}/PATTERN2.NRLIB from ${MID}/PATTERN2.spad
+ @ (cd ${MID} ; echo ')co PATTERN2.spad' | ${INTERPSYS} )
+
+@
+<<PATTERN2.spad (SPAD from IN)>>=
+${MID}/PATTERN2.spad: ${IN}/pattern.spad.pamphlet
+ @ echo 0 making ${MID}/PATTERN2.spad from ${IN}/pattern.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PATTERN2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PATTERN2 PatternFunctions2" ${IN}/pattern.spad.pamphlet >PATTERN2.spad )
+
+@
+<<pattern.spad.dvi (DOC from IN)>>=
+${DOC}/pattern.spad.dvi: ${IN}/pattern.spad.pamphlet
+ @ echo 0 making ${DOC}/pattern.spad.dvi from ${IN}/pattern.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pattern.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pattern.spad ; \
+ rm -f ${DOC}/pattern.spad.pamphlet ; \
+ rm -f ${DOC}/pattern.spad.tex ; \
+ rm -f ${DOC}/pattern.spad )
+
+@
+\subsection{pcurve.spad \cite{1}}
+<<pcurve.spad (SPAD from IN)>>=
+${MID}/pcurve.spad: ${IN}/pcurve.spad.pamphlet
+ @ echo 0 making ${MID}/pcurve.spad from ${IN}/pcurve.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pcurve.spad.pamphlet >pcurve.spad )
+
+@
+<<PPCURVE.o (O from NRLIB)>>=
+${OUT}/PPCURVE.o: ${MID}/PPCURVE.NRLIB
+ @ echo 0 making ${OUT}/PPCURVE.o from ${MID}/PPCURVE.NRLIB
+ @ cp ${MID}/PPCURVE.NRLIB/code.o ${OUT}/PPCURVE.o
+
+@
+<<PPCURVE.NRLIB (NRLIB from MID)>>=
+${MID}/PPCURVE.NRLIB: ${OUT}/KOERCE.o ${MID}/PPCURVE.spad
+ @ echo 0 making ${MID}/PPCURVE.NRLIB from ${MID}/PPCURVE.spad
+ @ (cd ${MID} ; echo ')co PPCURVE.spad' | ${INTERPSYS} )
+
+@
+<<PPCURVE.spad (SPAD from IN)>>=
+${MID}/PPCURVE.spad: ${IN}/pcurve.spad.pamphlet
+ @ echo 0 making ${MID}/PPCURVE.spad from ${IN}/pcurve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PPCURVE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PPCURVE PlottablePlaneCurveCategory" ${IN}/pcurve.spad.pamphlet >PPCURVE.spad )
+
+@
+<<PSCURVE.o (O from NRLIB)>>=
+${OUT}/PSCURVE.o: ${MID}/PSCURVE.NRLIB
+ @ echo 0 making ${OUT}/PSCURVE.o from ${MID}/PSCURVE.NRLIB
+ @ cp ${MID}/PSCURVE.NRLIB/code.o ${OUT}/PSCURVE.o
+
+@
+<<PSCURVE.NRLIB (NRLIB from MID)>>=
+${MID}/PSCURVE.NRLIB: ${OUT}/KOERCE.o ${MID}/PSCURVE.spad
+ @ echo 0 making ${MID}/PSCURVE.NRLIB from ${MID}/PSCURVE.spad
+ @ (cd ${MID} ; echo ')co PSCURVE.spad' | ${INTERPSYS} )
+
+@
+<<PSCURVE.spad (SPAD from IN)>>=
+${MID}/PSCURVE.spad: ${IN}/pcurve.spad.pamphlet
+ @ echo 0 making ${MID}/PSCURVE.spad from ${IN}/pcurve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSCURVE.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PSCURVE PlottableSpaceCurveCategory" ${IN}/pcurve.spad.pamphlet >PSCURVE.spad )
+
+@
+<<pcurve.spad.dvi (DOC from IN)>>=
+${DOC}/pcurve.spad.dvi: ${IN}/pcurve.spad.pamphlet
+ @ echo 0 making ${DOC}/pcurve.spad.dvi from ${IN}/pcurve.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pcurve.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pcurve.spad ; \
+ rm -f ${DOC}/pcurve.spad.pamphlet ; \
+ rm -f ${DOC}/pcurve.spad.tex ; \
+ rm -f ${DOC}/pcurve.spad )
+
+@
+\subsection{pdecomp.spad \cite{1}}
+<<pdecomp.spad (SPAD from IN)>>=
+${MID}/pdecomp.spad: ${IN}/pdecomp.spad.pamphlet
+ @ echo 0 making ${MID}/pdecomp.spad from ${IN}/pdecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pdecomp.spad.pamphlet >pdecomp.spad )
+
+@
+<<PCOMP.o (O from NRLIB)>>=
+${OUT}/PCOMP.o: ${MID}/PCOMP.NRLIB
+ @ echo 0 making ${OUT}/PCOMP.o from ${MID}/PCOMP.NRLIB
+ @ cp ${MID}/PCOMP.NRLIB/code.o ${OUT}/PCOMP.o
+
+@
+<<PCOMP.NRLIB (NRLIB from MID)>>=
+${MID}/PCOMP.NRLIB: ${MID}/PCOMP.spad
+ @ echo 0 making ${MID}/PCOMP.NRLIB from ${MID}/PCOMP.spad
+ @ (cd ${MID} ; echo ')co PCOMP.spad' | ${INTERPSYS} )
+
+@
+<<PCOMP.spad (SPAD from IN)>>=
+${MID}/PCOMP.spad: ${IN}/pdecomp.spad.pamphlet
+ @ echo 0 making ${MID}/PCOMP.spad from ${IN}/pdecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PCOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PCOMP PolynomialComposition" ${IN}/pdecomp.spad.pamphlet >PCOMP.spad )
+
+@
+<<PDECOMP.o (O from NRLIB)>>=
+${OUT}/PDECOMP.o: ${MID}/PDECOMP.NRLIB
+ @ echo 0 making ${OUT}/PDECOMP.o from ${MID}/PDECOMP.NRLIB
+ @ cp ${MID}/PDECOMP.NRLIB/code.o ${OUT}/PDECOMP.o
+
+@
+<<PDECOMP.NRLIB (NRLIB from MID)>>=
+${MID}/PDECOMP.NRLIB: ${MID}/PDECOMP.spad
+ @ echo 0 making ${MID}/PDECOMP.NRLIB from ${MID}/PDECOMP.spad
+ @ (cd ${MID} ; echo ')co PDECOMP.spad' | ${INTERPSYS} )
+
+@
+<<PDECOMP.spad (SPAD from IN)>>=
+${MID}/PDECOMP.spad: ${IN}/pdecomp.spad.pamphlet
+ @ echo 0 making ${MID}/PDECOMP.spad from ${IN}/pdecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PDECOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PDECOMP PolynomialDecomposition" ${IN}/pdecomp.spad.pamphlet >PDECOMP.spad )
+
+@
+<<pdecomp.spad.dvi (DOC from IN)>>=
+${DOC}/pdecomp.spad.dvi: ${IN}/pdecomp.spad.pamphlet
+ @ echo 0 making ${DOC}/pdecomp.spad.dvi from ${IN}/pdecomp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pdecomp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pdecomp.spad ; \
+ rm -f ${DOC}/pdecomp.spad.pamphlet ; \
+ rm -f ${DOC}/pdecomp.spad.tex ; \
+ rm -f ${DOC}/pdecomp.spad )
+
+@
+\subsection{perman.spad \cite{1}}
+<<perman.spad (SPAD from IN)>>=
+${MID}/perman.spad: ${IN}/perman.spad.pamphlet
+ @ echo 0 making ${MID}/perman.spad from ${IN}/perman.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/perman.spad.pamphlet >perman.spad )
+
+@
+<<GRAY.o (O from NRLIB)>>=
+${OUT}/GRAY.o: ${MID}/GRAY.NRLIB
+ @ echo 0 making ${OUT}/GRAY.o from ${MID}/GRAY.NRLIB
+ @ cp ${MID}/GRAY.NRLIB/code.o ${OUT}/GRAY.o
+
+@
+<<GRAY.NRLIB (NRLIB from MID)>>=
+${MID}/GRAY.NRLIB: ${MID}/GRAY.spad
+ @ echo 0 making ${MID}/GRAY.NRLIB from ${MID}/GRAY.spad
+ @ (cd ${MID} ; echo ')co GRAY.spad' | ${INTERPSYS} )
+
+@
+<<GRAY.spad (SPAD from IN)>>=
+${MID}/GRAY.spad: ${IN}/perman.spad.pamphlet
+ @ echo 0 making ${MID}/GRAY.spad from ${IN}/perman.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GRAY.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GRAY GrayCode" ${IN}/perman.spad.pamphlet >GRAY.spad )
+
+@
+<<PERMAN.o (O from NRLIB)>>=
+${OUT}/PERMAN.o: ${MID}/PERMAN.NRLIB
+ @ echo 0 making ${OUT}/PERMAN.o from ${MID}/PERMAN.NRLIB
+ @ cp ${MID}/PERMAN.NRLIB/code.o ${OUT}/PERMAN.o
+
+@
+<<PERMAN.NRLIB (NRLIB from MID)>>=
+${MID}/PERMAN.NRLIB: ${MID}/PERMAN.spad
+ @ echo 0 making ${MID}/PERMAN.NRLIB from ${MID}/PERMAN.spad
+ @ (cd ${MID} ; echo ')co PERMAN.spad' | ${INTERPSYS} )
+
+@
+<<PERMAN.spad (SPAD from IN)>>=
+${MID}/PERMAN.spad: ${IN}/perman.spad.pamphlet
+ @ echo 0 making ${MID}/PERMAN.spad from ${IN}/perman.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PERMAN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PERMAN Permanent" ${IN}/perman.spad.pamphlet >PERMAN.spad )
+
+@
+<<perman.spad.dvi (DOC from IN)>>=
+${DOC}/perman.spad.dvi: ${IN}/perman.spad.pamphlet
+ @ echo 0 making ${DOC}/perman.spad.dvi from ${IN}/perman.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/perman.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} perman.spad ; \
+ rm -f ${DOC}/perman.spad.pamphlet ; \
+ rm -f ${DOC}/perman.spad.tex ; \
+ rm -f ${DOC}/perman.spad )
+
+@
+\subsection{permgrps.spad \cite{1}}
+<<permgrps.spad (SPAD from IN)>>=
+${MID}/permgrps.spad: ${IN}/permgrps.spad.pamphlet
+ @ echo 0 making ${MID}/permgrps.spad from ${IN}/permgrps.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/permgrps.spad.pamphlet >permgrps.spad )
+
+@
+<<PERMGRP.o (O from NRLIB)>>=
+${OUT}/PERMGRP.o: ${MID}/PERMGRP.NRLIB
+ @ echo 0 making ${OUT}/PERMGRP.o from ${MID}/PERMGRP.NRLIB
+ @ cp ${MID}/PERMGRP.NRLIB/code.o ${OUT}/PERMGRP.o
+
+@
+<<PERMGRP.NRLIB (NRLIB from MID)>>=
+${MID}/PERMGRP.NRLIB: ${MID}/PERMGRP.spad
+ @ echo 0 making ${MID}/PERMGRP.NRLIB from ${MID}/PERMGRP.spad
+ @ (cd ${MID} ; echo ')co PERMGRP.spad' | ${INTERPSYS} )
+
+@
+<<PERMGRP.spad (SPAD from IN)>>=
+${MID}/PERMGRP.spad: ${IN}/permgrps.spad.pamphlet
+ @ echo 0 making ${MID}/PERMGRP.spad from ${IN}/permgrps.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PERMGRP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PERMGRP PermutationGroup" ${IN}/permgrps.spad.pamphlet >PERMGRP.spad )
+
+@
+<<PGE.o (O from NRLIB)>>=
+${OUT}/PGE.o: ${MID}/PGE.NRLIB
+ @ echo 0 making ${OUT}/PGE.o from ${MID}/PGE.NRLIB
+ @ cp ${MID}/PGE.NRLIB/code.o ${OUT}/PGE.o
+
+@
+<<PGE.NRLIB (NRLIB from MID)>>=
+${MID}/PGE.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PGE.spad
+ @ echo 0 making ${MID}/PGE.NRLIB from ${MID}/PGE.spad
+ @ (cd ${MID} ; echo ')co PGE.spad' | ${INTERPSYS} )
+
+@
+<<PGE.spad (SPAD from IN)>>=
+${MID}/PGE.spad: ${IN}/permgrps.spad.pamphlet
+ @ echo 0 making ${MID}/PGE.spad from ${IN}/permgrps.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PGE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PGE PermutationGroupExamples" ${IN}/permgrps.spad.pamphlet >PGE.spad )
+
+@
+<<permgrps.spad.dvi (DOC from IN)>>=
+${DOC}/permgrps.spad.dvi: ${IN}/permgrps.spad.pamphlet
+ @ echo 0 making ${DOC}/permgrps.spad.dvi from ${IN}/permgrps.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/permgrps.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} permgrps.spad ; \
+ rm -f ${DOC}/permgrps.spad.pamphlet ; \
+ rm -f ${DOC}/permgrps.spad.tex ; \
+ rm -f ${DOC}/permgrps.spad )
+
+@
+\subsection{perm.spad \cite{1}}
+<<perm.spad (SPAD from IN)>>=
+${MID}/perm.spad: ${IN}/perm.spad.pamphlet
+ @ echo 0 making ${MID}/perm.spad from ${IN}/perm.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/perm.spad.pamphlet >perm.spad )
+
+@
+<<PERM.o (O from NRLIB)>>=
+${OUT}/PERM.o: ${MID}/PERM.NRLIB
+ @ echo 0 making ${OUT}/PERM.o from ${MID}/PERM.NRLIB
+ @ cp ${MID}/PERM.NRLIB/code.o ${OUT}/PERM.o
+
+@
+<<PERM.NRLIB (NRLIB from MID)>>=
+${MID}/PERM.NRLIB: ${MID}/PERM.spad
+ @ echo 0 making ${MID}/PERM.NRLIB from ${MID}/PERM.spad
+ @ (cd ${MID} ; echo ')co PERM.spad' | ${INTERPSYS} )
+
+@
+<<PERM.spad (SPAD from IN)>>=
+${MID}/PERM.spad: ${IN}/perm.spad.pamphlet
+ @ echo 0 making ${MID}/PERM.spad from ${IN}/perm.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PERM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PERM Permutation" ${IN}/perm.spad.pamphlet >PERM.spad )
+
+@
+<<PERMCAT.o (O from NRLIB)>>=
+${OUT}/PERMCAT.o: ${MID}/PERMCAT.NRLIB
+ @ echo 0 making ${OUT}/PERMCAT.o from ${MID}/PERMCAT.NRLIB
+ @ cp ${MID}/PERMCAT.NRLIB/code.o ${OUT}/PERMCAT.o
+
+@
+<<PERMCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PERMCAT.NRLIB: ${MID}/PERMCAT.spad
+ @ echo 0 making ${MID}/PERMCAT.NRLIB from ${MID}/PERMCAT.spad
+ @ (cd ${MID} ; echo ')co PERMCAT.spad' | ${INTERPSYS} )
+
+@
+<<PERMCAT.spad (SPAD from IN)>>=
+${MID}/PERMCAT.spad: ${IN}/perm.spad.pamphlet
+ @ echo 0 making ${MID}/PERMCAT.spad from ${IN}/perm.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PERMCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PERMCAT PermutationCategory" ${IN}/perm.spad.pamphlet >PERMCAT.spad )
+
+@
+<<perm.spad.dvi (DOC from IN)>>=
+${DOC}/perm.spad.dvi: ${IN}/perm.spad.pamphlet
+ @ echo 0 making ${DOC}/perm.spad.dvi from ${IN}/perm.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/perm.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} perm.spad ; \
+ rm -f ${DOC}/perm.spad.pamphlet ; \
+ rm -f ${DOC}/perm.spad.tex ; \
+ rm -f ${DOC}/perm.spad )
+
+@
+\subsection{pfbr.spad \cite{1}}
+<<pfbr.spad (SPAD from IN)>>=
+${MID}/pfbr.spad: ${IN}/pfbr.spad.pamphlet
+ @ echo 0 making ${MID}/pfbr.spad from ${IN}/pfbr.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pfbr.spad.pamphlet >pfbr.spad )
+
+@
+<<PFBR.o (O from NRLIB)>>=
+${OUT}/PFBR.o: ${MID}/PFBR.NRLIB
+ @ echo 0 making ${OUT}/PFBR.o from ${MID}/PFBR.NRLIB
+ @ cp ${MID}/PFBR.NRLIB/code.o ${OUT}/PFBR.o
+
+@
+<<PFBR.NRLIB (NRLIB from MID)>>=
+${MID}/PFBR.NRLIB: ${MID}/PFBR.spad
+ @ echo 0 making ${MID}/PFBR.NRLIB from ${MID}/PFBR.spad
+ @ (cd ${MID} ; echo ')co PFBR.spad' | ${INTERPSYS} )
+
+@
+<<PFBR.spad (SPAD from IN)>>=
+${MID}/PFBR.spad: ${IN}/pfbr.spad.pamphlet
+ @ echo 0 making ${MID}/PFBR.spad from ${IN}/pfbr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFBR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PFBR PolynomialFactorizationByRecursion" ${IN}/pfbr.spad.pamphlet >PFBR.spad )
+
+@
+<<PFBRU.o (O from NRLIB)>>=
+${OUT}/PFBRU.o: ${MID}/PFBRU.NRLIB
+ @ echo 0 making ${OUT}/PFBRU.o from ${MID}/PFBRU.NRLIB
+ @ cp ${MID}/PFBRU.NRLIB/code.o ${OUT}/PFBRU.o
+
+@
+<<PFBRU.NRLIB (NRLIB from MID)>>=
+${MID}/PFBRU.NRLIB: ${MID}/PFBRU.spad
+ @ echo 0 making ${MID}/PFBRU.NRLIB from ${MID}/PFBRU.spad
+ @ (cd ${MID} ; echo ')co PFBRU.spad' | ${INTERPSYS} )
+
+@
+<<PFBRU.spad (SPAD from IN)>>=
+${MID}/PFBRU.spad: ${IN}/pfbr.spad.pamphlet
+ @ echo 0 making ${MID}/PFBRU.spad from ${IN}/pfbr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFBRU.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PFBRU PolynomialFactorizationByRecursionUnivariate" ${IN}/pfbr.spad.pamphlet >PFBRU.spad )
+
+@
+<<pfbr.spad.dvi (DOC from IN)>>=
+${DOC}/pfbr.spad.dvi: ${IN}/pfbr.spad.pamphlet
+ @ echo 0 making ${DOC}/pfbr.spad.dvi from ${IN}/pfbr.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pfbr.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pfbr.spad ; \
+ rm -f ${DOC}/pfbr.spad.pamphlet ; \
+ rm -f ${DOC}/pfbr.spad.tex ; \
+ rm -f ${DOC}/pfbr.spad )
+
+@
+\subsection{pfo.spad \cite{1}}
+<<pfo.spad (SPAD from IN)>>=
+${MID}/pfo.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/pfo.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pfo.spad.pamphlet >pfo.spad )
+
+@
+<<FORDER.o (O from NRLIB)>>=
+${OUT}/FORDER.o: ${MID}/FORDER.NRLIB
+ @ echo 0 making ${OUT}/FORDER.o from ${MID}/FORDER.NRLIB
+ @ cp ${MID}/FORDER.NRLIB/code.o ${OUT}/FORDER.o
+
+@
+<<FORDER.NRLIB (NRLIB from MID)>>=
+${MID}/FORDER.NRLIB: ${MID}/FORDER.spad
+ @ echo 0 making ${MID}/FORDER.NRLIB from ${MID}/FORDER.spad
+ @ (cd ${MID} ; echo ')co FORDER.spad' | ${INTERPSYS} )
+
+@
+<<FORDER.spad (SPAD from IN)>>=
+${MID}/FORDER.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/FORDER.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FORDER.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FORDER FindOrderFinite" ${IN}/pfo.spad.pamphlet >FORDER.spad )
+
+@
+<<FSRED.o (O from NRLIB)>>=
+${OUT}/FSRED.o: ${MID}/FSRED.NRLIB
+ @ echo 0 making ${OUT}/FSRED.o from ${MID}/FSRED.NRLIB
+ @ cp ${MID}/FSRED.NRLIB/code.o ${OUT}/FSRED.o
+
+@
+<<FSRED.NRLIB (NRLIB from MID)>>=
+${MID}/FSRED.NRLIB: ${MID}/FSRED.spad
+ @ echo 0 making ${MID}/FSRED.NRLIB from ${MID}/FSRED.spad
+ @ (cd ${MID} ; echo ')co FSRED.spad' | ${INTERPSYS} )
+
+@
+<<FSRED.spad (SPAD from IN)>>=
+${MID}/FSRED.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/FSRED.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSRED.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSRED FunctionSpaceReduce" ${IN}/pfo.spad.pamphlet >FSRED.spad )
+
+@
+<<PFO.o (O from NRLIB)>>=
+${OUT}/PFO.o: ${MID}/PFO.NRLIB
+ @ echo 0 making ${OUT}/PFO.o from ${MID}/PFO.NRLIB
+ @ cp ${MID}/PFO.NRLIB/code.o ${OUT}/PFO.o
+
+@
+<<PFO.NRLIB (NRLIB from MID)>>=
+${MID}/PFO.NRLIB: ${MID}/PFO.spad
+ @ echo 0 making ${MID}/PFO.NRLIB from ${MID}/PFO.spad
+ @ (cd ${MID} ; echo ')co PFO.spad' | ${INTERPSYS} )
+
+@
+<<PFO.spad (SPAD from IN)>>=
+${MID}/PFO.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/PFO.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFO.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PFO PointsOfFiniteOrder" ${IN}/pfo.spad.pamphlet >PFO.spad )
+
+@
+<<PFOQ.o (O from NRLIB)>>=
+${OUT}/PFOQ.o: ${MID}/PFOQ.NRLIB
+ @ echo 0 making ${OUT}/PFOQ.o from ${MID}/PFOQ.NRLIB
+ @ cp ${MID}/PFOQ.NRLIB/code.o ${OUT}/PFOQ.o
+
+@
+<<PFOQ.NRLIB (NRLIB from MID)>>=
+${MID}/PFOQ.NRLIB: ${MID}/PFOQ.spad
+ @ echo 0 making ${MID}/PFOQ.NRLIB from ${MID}/PFOQ.spad
+ @ (cd ${MID} ; echo ')co PFOQ.spad' | ${INTERPSYS} )
+
+@
+<<PFOQ.spad (SPAD from IN)>>=
+${MID}/PFOQ.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/PFOQ.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFOQ.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PFOQ PointsOfFiniteOrderRational" ${IN}/pfo.spad.pamphlet >PFOQ.spad )
+
+@
+<<PFOTOOLS.o (O from NRLIB)>>=
+${OUT}/PFOTOOLS.o: ${MID}/PFOTOOLS.NRLIB
+ @ echo 0 making ${OUT}/PFOTOOLS.o from ${MID}/PFOTOOLS.NRLIB
+ @ cp ${MID}/PFOTOOLS.NRLIB/code.o ${OUT}/PFOTOOLS.o
+
+@
+<<PFOTOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/PFOTOOLS.NRLIB: ${MID}/PFOTOOLS.spad
+ @ echo 0 making ${MID}/PFOTOOLS.NRLIB from ${MID}/PFOTOOLS.spad
+ @ (cd ${MID} ; echo ')co PFOTOOLS.spad' | ${INTERPSYS} )
+
+@
+<<PFOTOOLS.spad (SPAD from IN)>>=
+${MID}/PFOTOOLS.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/PFOTOOLS.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFOTOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PFOTOOLS PointsOfFiniteOrderTools" ${IN}/pfo.spad.pamphlet >PFOTOOLS.spad )
+
+@
+<<RDIV.o (O from NRLIB)>>=
+${OUT}/RDIV.o: ${MID}/RDIV.NRLIB
+ @ echo 0 making ${OUT}/RDIV.o from ${MID}/RDIV.NRLIB
+ @ cp ${MID}/RDIV.NRLIB/code.o ${OUT}/RDIV.o
+
+@
+<<RDIV.NRLIB (NRLIB from MID)>>=
+${MID}/RDIV.NRLIB: ${MID}/RDIV.spad
+ @ echo 0 making ${MID}/RDIV.NRLIB from ${MID}/RDIV.spad
+ @ (cd ${MID} ; echo ')co RDIV.spad' | ${INTERPSYS} )
+
+@
+<<RDIV.spad (SPAD from IN)>>=
+${MID}/RDIV.spad: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${MID}/RDIV.spad from ${IN}/pfo.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RDIV.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RDIV ReducedDivisor" ${IN}/pfo.spad.pamphlet >RDIV.spad )
+
+@
+<<pfo.spad.dvi (DOC from IN)>>=
+${DOC}/pfo.spad.dvi: ${IN}/pfo.spad.pamphlet
+ @ echo 0 making ${DOC}/pfo.spad.dvi from ${IN}/pfo.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pfo.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pfo.spad ; \
+ rm -f ${DOC}/pfo.spad.pamphlet ; \
+ rm -f ${DOC}/pfo.spad.tex ; \
+ rm -f ${DOC}/pfo.spad )
+
+@
+\subsection{pfr.spad \cite{1}}
+<<pfr.spad (SPAD from IN)>>=
+${MID}/pfr.spad: ${IN}/pfr.spad.pamphlet
+ @ echo 0 making ${MID}/pfr.spad from ${IN}/pfr.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pfr.spad.pamphlet >pfr.spad )
+
+@
+<<PFR.o (O from NRLIB)>>=
+${OUT}/PFR.o: ${MID}/PFR.NRLIB
+ @ echo 0 making ${OUT}/PFR.o from ${MID}/PFR.NRLIB
+ @ cp ${MID}/PFR.NRLIB/code.o ${OUT}/PFR.o
+
+@
+<<PFR.NRLIB (NRLIB from MID)>>=
+${MID}/PFR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PFR.spad
+ @ echo 0 making ${MID}/PFR.NRLIB from ${MID}/PFR.spad
+ @ (cd ${MID} ; echo ')co PFR.spad' | ${INTERPSYS} )
+
+@
+<<PFR.spad (SPAD from IN)>>=
+${MID}/PFR.spad: ${IN}/pfr.spad.pamphlet
+ @ echo 0 making ${MID}/PFR.spad from ${IN}/pfr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PFR PartialFraction" ${IN}/pfr.spad.pamphlet >PFR.spad )
+
+@
+<<PFRPAC.o (O from NRLIB)>>=
+${OUT}/PFRPAC.o: ${MID}/PFRPAC.NRLIB
+ @ echo 0 making ${OUT}/PFRPAC.o from ${MID}/PFRPAC.NRLIB
+ @ cp ${MID}/PFRPAC.NRLIB/code.o ${OUT}/PFRPAC.o
+
+@
+<<PFRPAC.NRLIB (NRLIB from MID)>>=
+${MID}/PFRPAC.NRLIB: ${MID}/PFRPAC.spad
+ @ echo 0 making ${MID}/PFRPAC.NRLIB from ${MID}/PFRPAC.spad
+ @ (cd ${MID} ; echo ')co PFRPAC.spad' | ${INTERPSYS} )
+
+@
+<<PFRPAC.spad (SPAD from IN)>>=
+${MID}/PFRPAC.spad: ${IN}/pfr.spad.pamphlet
+ @ echo 0 making ${MID}/PFRPAC.spad from ${IN}/pfr.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PFRPAC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PFRPAC PartialFractionPackage" ${IN}/pfr.spad.pamphlet >PFRPAC.spad )
+
+@
+<<pfr.spad.dvi (DOC from IN)>>=
+${DOC}/pfr.spad.dvi: ${IN}/pfr.spad.pamphlet
+ @ echo 0 making ${DOC}/pfr.spad.dvi from ${IN}/pfr.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pfr.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pfr.spad ; \
+ rm -f ${DOC}/pfr.spad.pamphlet ; \
+ rm -f ${DOC}/pfr.spad.tex ; \
+ rm -f ${DOC}/pfr.spad )
+
+@
+\subsection{pf.spad \cite{1}}
+<<pf.spad (SPAD from IN)>>=
+${MID}/pf.spad: ${IN}/pf.spad.pamphlet
+ @ echo 0 making ${MID}/pf.spad from ${IN}/pf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pf.spad.pamphlet >pf.spad )
+
+@
+<<IPF.o (O from NRLIB)>>=
+${OUT}/IPF.o: ${MID}/IPF.NRLIB
+ @ echo 0 making ${OUT}/IPF.o from ${MID}/IPF.NRLIB
+ @ cp ${MID}/IPF.NRLIB/code.o ${OUT}/IPF.o
+
+@
+<<IPF.NRLIB (NRLIB from MID)>>=
+${MID}/IPF.NRLIB: ${MID}/IPF.spad
+ @ echo 0 making ${MID}/IPF.NRLIB from ${MID}/IPF.spad
+ @ (cd ${MID} ; echo ')co IPF.spad' | ${INTERPSYS} )
+
+@
+<<IPF.spad (SPAD from IN)>>=
+${MID}/IPF.spad: ${IN}/pf.spad.pamphlet
+ @ echo 0 making ${MID}/IPF.spad from ${IN}/pf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IPF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IPF InnerPrimeField" ${IN}/pf.spad.pamphlet >IPF.spad )
+
+@
+<<PF.o (O from NRLIB)>>=
+${OUT}/PF.o: ${MID}/PF.NRLIB
+ @ echo 0 making ${OUT}/PF.o from ${MID}/PF.NRLIB
+ @ cp ${MID}/PF.NRLIB/code.o ${OUT}/PF.o
+
+@
+<<PF.NRLIB (NRLIB from MID)>>=
+${MID}/PF.NRLIB: ${MID}/PF.spad
+ @ echo 0 making ${MID}/PF.NRLIB from ${MID}/PF.spad
+ @ (cd ${MID} ; echo ')co PF.spad' | ${INTERPSYS} )
+
+@
+<<PF.spad (SPAD from IN)>>=
+${MID}/PF.spad: ${IN}/pf.spad.pamphlet
+ @ echo 0 making ${MID}/PF.spad from ${IN}/pf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PF PrimeField" ${IN}/pf.spad.pamphlet >PF.spad )
+
+@
+<<pf.spad.dvi (DOC from IN)>>=
+${DOC}/pf.spad.dvi: ${IN}/pf.spad.pamphlet
+ @ echo 0 making ${DOC}/pf.spad.dvi from ${IN}/pf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pf.spad ; \
+ rm -f ${DOC}/pf.spad.pamphlet ; \
+ rm -f ${DOC}/pf.spad.tex ; \
+ rm -f ${DOC}/pf.spad )
+
+@
+\subsection{pgcd.spad \cite{1}}
+<<pgcd.spad (SPAD from IN)>>=
+${MID}/pgcd.spad: ${IN}/pgcd.spad.pamphlet
+ @ echo 0 making ${MID}/pgcd.spad from ${IN}/pgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pgcd.spad.pamphlet >pgcd.spad )
+
+@
+<<PGCD.o (O from NRLIB)>>=
+${OUT}/PGCD.o: ${MID}/PGCD.NRLIB
+ @ echo 0 making ${OUT}/PGCD.o from ${MID}/PGCD.NRLIB
+ @ cp ${MID}/PGCD.NRLIB/code.o ${OUT}/PGCD.o
+
+@
+<<PGCD.NRLIB (NRLIB from MID)>>=
+${MID}/PGCD.NRLIB: ${MID}/PGCD.spad
+ @ echo 0 making ${MID}/PGCD.NRLIB from ${MID}/PGCD.spad
+ @ (cd ${MID} ; echo ')co PGCD.spad' | ${INTERPSYS} )
+
+@
+<<PGCD.spad (SPAD from IN)>>=
+${MID}/PGCD.spad: ${IN}/pgcd.spad.pamphlet
+ @ echo 0 making ${MID}/PGCD.spad from ${IN}/pgcd.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PGCD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PGCD PolynomialGcdPackage" ${IN}/pgcd.spad.pamphlet >PGCD.spad )
+
+@
+<<pgcd.spad.dvi (DOC from IN)>>=
+${DOC}/pgcd.spad.dvi: ${IN}/pgcd.spad.pamphlet
+ @ echo 0 making ${DOC}/pgcd.spad.dvi from ${IN}/pgcd.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pgcd.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pgcd.spad ; \
+ rm -f ${DOC}/pgcd.spad.pamphlet ; \
+ rm -f ${DOC}/pgcd.spad.tex ; \
+ rm -f ${DOC}/pgcd.spad )
+
+@
+\subsection{pgrobner.spad \cite{1}}
+<<pgrobner.spad (SPAD from IN)>>=
+${MID}/pgrobner.spad: ${IN}/pgrobner.spad.pamphlet
+ @ echo 0 making ${MID}/pgrobner.spad from ${IN}/pgrobner.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pgrobner.spad.pamphlet >pgrobner.spad )
+
+@
+<<PGROEB.o (O from NRLIB)>>=
+${OUT}/PGROEB.o: ${MID}/PGROEB.NRLIB
+ @ echo 0 making ${OUT}/PGROEB.o from ${MID}/PGROEB.NRLIB
+ @ cp ${MID}/PGROEB.NRLIB/code.o ${OUT}/PGROEB.o
+
+@
+<<PGROEB.NRLIB (NRLIB from MID)>>=
+${MID}/PGROEB.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PGROEB.spad
+ @ echo 0 making ${MID}/PGROEB.NRLIB from ${MID}/PGROEB.spad
+ @ (cd ${MID} ; echo ')co PGROEB.spad' | ${INTERPSYS} )
+
+@
+<<PGROEB.spad (SPAD from IN)>>=
+${MID}/PGROEB.spad: ${IN}/pgrobner.spad.pamphlet
+ @ echo 0 making ${MID}/PGROEB.spad from ${IN}/pgrobner.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PGROEB.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PGROEB PolyGroebner" ${IN}/pgrobner.spad.pamphlet >PGROEB.spad )
+
+@
+<<pgrobner.spad.dvi (DOC from IN)>>=
+${DOC}/pgrobner.spad.dvi: ${IN}/pgrobner.spad.pamphlet
+ @ echo 0 making ${DOC}/pgrobner.spad.dvi from ${IN}/pgrobner.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pgrobner.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pgrobner.spad ; \
+ rm -f ${DOC}/pgrobner.spad.pamphlet ; \
+ rm -f ${DOC}/pgrobner.spad.tex ; \
+ rm -f ${DOC}/pgrobner.spad )
+
+@
+\subsection{pinterp.spad \cite{1}}
+<<pinterp.spad (SPAD from IN)>>=
+${MID}/pinterp.spad: ${IN}/pinterp.spad.pamphlet
+ @ echo 0 making ${MID}/pinterp.spad from ${IN}/pinterp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pinterp.spad.pamphlet >pinterp.spad )
+
+@
+<<PINTERP.o (O from NRLIB)>>=
+${OUT}/PINTERP.o: ${MID}/PINTERP.NRLIB
+ @ echo 0 making ${OUT}/PINTERP.o from ${MID}/PINTERP.NRLIB
+ @ cp ${MID}/PINTERP.NRLIB/code.o ${OUT}/PINTERP.o
+
+@
+<<PINTERP.NRLIB (NRLIB from MID)>>=
+${MID}/PINTERP.NRLIB: ${MID}/PINTERP.spad
+ @ echo 0 making ${MID}/PINTERP.NRLIB from ${MID}/PINTERP.spad
+ @ (cd ${MID} ; echo ')co PINTERP.spad' | ${INTERPSYS} )
+
+@
+<<PINTERP.spad (SPAD from IN)>>=
+${MID}/PINTERP.spad: ${IN}/pinterp.spad.pamphlet
+ @ echo 0 making ${MID}/PINTERP.spad from ${IN}/pinterp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PINTERP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PINTERP PolynomialInterpolation" ${IN}/pinterp.spad.pamphlet >PINTERP.spad )
+
+@
+<<PINTERPA.o (O from NRLIB)>>=
+${OUT}/PINTERPA.o: ${MID}/PINTERPA.NRLIB
+ @ echo 0 making ${OUT}/PINTERPA.o from ${MID}/PINTERPA.NRLIB
+ @ cp ${MID}/PINTERPA.NRLIB/code.o ${OUT}/PINTERPA.o
+
+@
+<<PINTERPA.NRLIB (NRLIB from MID)>>=
+${MID}/PINTERPA.NRLIB: ${MID}/PINTERPA.spad
+ @ echo 0 making ${MID}/PINTERPA.NRLIB from ${MID}/PINTERPA.spad
+ @ (cd ${MID} ; echo ')co PINTERPA.spad' | ${INTERPSYS} )
+
+@
+<<PINTERPA.spad (SPAD from IN)>>=
+${MID}/PINTERPA.spad: ${IN}/pinterp.spad.pamphlet
+ @ echo 0 making ${MID}/PINTERPA.spad from ${IN}/pinterp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PINTERPA.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PINTERPA PolynomialInterpolationAlgorithms" ${IN}/pinterp.spad.pamphlet >PINTERPA.spad )
+
+@
+<<pinterp.spad.dvi (DOC from IN)>>=
+${DOC}/pinterp.spad.dvi: ${IN}/pinterp.spad.pamphlet
+ @ echo 0 making ${DOC}/pinterp.spad.dvi from ${IN}/pinterp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pinterp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pinterp.spad ; \
+ rm -f ${DOC}/pinterp.spad.pamphlet ; \
+ rm -f ${DOC}/pinterp.spad.tex ; \
+ rm -f ${DOC}/pinterp.spad )
+
+@
+\subsection{pleqn.spad \cite{1}}
+<<pleqn.spad (SPAD from IN)>>=
+${MID}/pleqn.spad: ${IN}/pleqn.spad.pamphlet
+ @ echo 0 making ${MID}/pleqn.spad from ${IN}/pleqn.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pleqn.spad.pamphlet >pleqn.spad )
+
+@
+<<PLEQN.o (O from NRLIB)>>=
+${OUT}/PLEQN.o: ${MID}/PLEQN.NRLIB
+ @ echo 0 making ${OUT}/PLEQN.o from ${MID}/PLEQN.NRLIB
+ @ cp ${MID}/PLEQN.NRLIB/code.o ${OUT}/PLEQN.o
+
+@
+<<PLEQN.NRLIB (NRLIB from MID)>>=
+${MID}/PLEQN.NRLIB: ${MID}/PLEQN.spad
+ @ echo 0 making ${MID}/PLEQN.NRLIB from ${MID}/PLEQN.spad
+ @ (cd ${MID} ; echo ')co PLEQN.spad' | ${INTERPSYS} )
+
+@
+<<PLEQN.spad (SPAD from IN)>>=
+${MID}/PLEQN.spad: ${IN}/pleqn.spad.pamphlet
+ @ echo 0 making ${MID}/PLEQN.spad from ${IN}/pleqn.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PLEQN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PLEQN ParametricLinearEquations" ${IN}/pleqn.spad.pamphlet >PLEQN.spad )
+
+@
+<<pleqn.spad.dvi (DOC from IN)>>=
+${DOC}/pleqn.spad.dvi: ${IN}/pleqn.spad.pamphlet
+ @ echo 0 making ${DOC}/pleqn.spad.dvi from ${IN}/pleqn.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pleqn.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pleqn.spad ; \
+ rm -f ${DOC}/pleqn.spad.pamphlet ; \
+ rm -f ${DOC}/pleqn.spad.tex ; \
+ rm -f ${DOC}/pleqn.spad )
+
+@
+\subsection{plot3d.spad \cite{1}}
+<<plot3d.spad (SPAD from IN)>>=
+${MID}/plot3d.spad: ${IN}/plot3d.spad.pamphlet
+ @ echo 0 making ${MID}/plot3d.spad from ${IN}/plot3d.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/plot3d.spad.pamphlet >plot3d.spad )
+
+@
+<<PLOT3D.o (O from NRLIB)>>=
+${OUT}/PLOT3D.o: ${MID}/PLOT3D.NRLIB
+ @ echo 0 making ${OUT}/PLOT3D.o from ${MID}/PLOT3D.NRLIB
+ @ cp ${MID}/PLOT3D.NRLIB/code.o ${OUT}/PLOT3D.o
+
+@
+<<PLOT3D.NRLIB (NRLIB from MID)>>=
+${MID}/PLOT3D.NRLIB: ${MID}/PLOT3D.spad
+ @ echo 0 making ${MID}/PLOT3D.NRLIB from ${MID}/PLOT3D.spad
+ @ (cd ${MID} ; echo ')co PLOT3D.spad' | ${INTERPSYS} )
+
+@
+<<PLOT3D.spad (SPAD from IN)>>=
+${MID}/PLOT3D.spad: ${IN}/plot3d.spad.pamphlet
+ @ echo 0 making ${MID}/PLOT3D.spad from ${IN}/plot3d.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PLOT3D.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PLOT3D Plot3D" ${IN}/plot3d.spad.pamphlet >PLOT3D.spad )
+
+@
+<<plot3d.spad.dvi (DOC from IN)>>=
+${DOC}/plot3d.spad.dvi: ${IN}/plot3d.spad.pamphlet
+ @ echo 0 making ${DOC}/plot3d.spad.dvi from ${IN}/plot3d.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/plot3d.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} plot3d.spad ; \
+ rm -f ${DOC}/plot3d.spad.pamphlet ; \
+ rm -f ${DOC}/plot3d.spad.tex ; \
+ rm -f ${DOC}/plot3d.spad )
+
+@
+\subsection{plot.spad \cite{1}}
+<<plot.spad (SPAD from IN)>>=
+${MID}/plot.spad: ${IN}/plot.spad.pamphlet
+ @ echo 0 making ${MID}/plot.spad from ${IN}/plot.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/plot.spad.pamphlet >plot.spad )
+
+@
+<<PLOT1.o (O from NRLIB)>>=
+${OUT}/PLOT1.o: ${MID}/PLOT1.NRLIB
+ @ echo 0 making ${OUT}/PLOT1.o from ${MID}/PLOT1.NRLIB
+ @ cp ${MID}/PLOT1.NRLIB/code.o ${OUT}/PLOT1.o
+
+@
+<<PLOT1.NRLIB (NRLIB from MID)>>=
+${MID}/PLOT1.NRLIB: ${OUT}/KONVERT.o ${MID}/PLOT1.spad
+ @ echo 0 making ${MID}/PLOT1.NRLIB from ${MID}/PLOT1.spad
+ @ (cd ${MID} ; echo ')co PLOT1.spad' | ${INTERPSYS} )
+
+@
+<<PLOT1.spad (SPAD from IN)>>=
+${MID}/PLOT1.spad: ${IN}/plot.spad.pamphlet
+ @ echo 0 making ${MID}/PLOT1.spad from ${IN}/plot.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PLOT1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PLOT1 PlotFunctions1" ${IN}/plot.spad.pamphlet >PLOT1.spad )
+
+@
+<<PLOT.o (O from NRLIB)>>=
+${OUT}/PLOT.o: ${MID}/PLOT.NRLIB
+ @ echo 0 making ${OUT}/PLOT.o from ${MID}/PLOT.NRLIB
+ @ cp ${MID}/PLOT.NRLIB/code.o ${OUT}/PLOT.o
+
+@
+<<PLOT.NRLIB (NRLIB from MID)>>=
+${MID}/PLOT.NRLIB: ${OUT}/KONVERT.o ${MID}/PLOT.spad
+ @ echo 0 making ${MID}/PLOT.NRLIB from ${MID}/PLOT.spad
+ @ (cd ${MID} ; echo ')co PLOT.spad' | ${INTERPSYS} )
+
+@
+<<PLOT.spad (SPAD from IN)>>=
+${MID}/PLOT.spad: ${IN}/plot.spad.pamphlet
+ @ echo 0 making ${MID}/PLOT.spad from ${IN}/plot.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PLOT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PLOT Plot" ${IN}/plot.spad.pamphlet >PLOT.spad )
+
+@
+<<plot.spad.dvi (DOC from IN)>>=
+${DOC}/plot.spad.dvi: ${IN}/plot.spad.pamphlet
+ @ echo 0 making ${DOC}/plot.spad.dvi from ${IN}/plot.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/plot.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} plot.spad ; \
+ rm -f ${DOC}/plot.spad.pamphlet ; \
+ rm -f ${DOC}/plot.spad.tex ; \
+ rm -f ${DOC}/plot.spad )
+
+@
+\subsection{plottool.spad \cite{1}}
+<<plottool.spad (SPAD from IN)>>=
+${MID}/plottool.spad: ${IN}/plottool.spad.pamphlet
+ @ echo 0 making ${MID}/plottool.spad from ${IN}/plottool.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/plottool.spad.pamphlet >plottool.spad )
+
+@
+<<PLOTTOOL.o (O from NRLIB)>>=
+${OUT}/PLOTTOOL.o: ${MID}/PLOTTOOL.NRLIB
+ @ echo 0 making ${OUT}/PLOTTOOL.o from ${MID}/PLOTTOOL.NRLIB
+ @ cp ${MID}/PLOTTOOL.NRLIB/code.o ${OUT}/PLOTTOOL.o
+
+@
+<<PLOTTOOL.NRLIB (NRLIB from MID)>>=
+${MID}/PLOTTOOL.NRLIB: ${MID}/PLOTTOOL.spad
+ @ echo 0 making ${MID}/PLOTTOOL.NRLIB from ${MID}/PLOTTOOL.spad
+ @ (cd ${MID} ; echo ')co PLOTTOOL.spad' | ${INTERPSYS} )
+
+@
+<<PLOTTOOL.spad (SPAD from IN)>>=
+${MID}/PLOTTOOL.spad: ${IN}/plottool.spad.pamphlet
+ @ echo 0 making ${MID}/PLOTTOOL.spad from ${IN}/plottool.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PLOTTOOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PLOTTOOL PlotTools" ${IN}/plottool.spad.pamphlet >PLOTTOOL.spad )
+
+@
+<<plottool.spad.dvi (DOC from IN)>>=
+${DOC}/plottool.spad.dvi: ${IN}/plottool.spad.pamphlet
+ @ echo 0 making ${DOC}/plottool.spad.dvi from ${IN}/plottool.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/plottool.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} plottool.spad ; \
+ rm -f ${DOC}/plottool.spad.pamphlet ; \
+ rm -f ${DOC}/plottool.spad.tex ; \
+ rm -f ${DOC}/plottool.spad )
+
+@
+\subsection{polset.spad \cite{1}}
+<<polset.spad (SPAD from IN)>>=
+${MID}/polset.spad: ${IN}/polset.spad.pamphlet
+ @ echo 0 making ${MID}/polset.spad from ${IN}/polset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/polset.spad.pamphlet >polset.spad )
+
+@
+<<GPOLSET.o (O from NRLIB)>>=
+${OUT}/GPOLSET.o: ${MID}/GPOLSET.NRLIB
+ @ echo 0 making ${OUT}/GPOLSET.o from ${MID}/GPOLSET.NRLIB
+ @ cp ${MID}/GPOLSET.NRLIB/code.o ${OUT}/GPOLSET.o
+
+@
+<<GPOLSET.NRLIB (NRLIB from MID)>>=
+${MID}/GPOLSET.NRLIB: ${MID}/GPOLSET.spad
+ @ echo 0 making ${MID}/GPOLSET.NRLIB from ${MID}/GPOLSET.spad
+ @ (cd ${MID} ; echo ')co GPOLSET.spad' | ${INTERPSYS} )
+
+@
+<<GPOLSET.spad (SPAD from IN)>>=
+${MID}/GPOLSET.spad: ${IN}/polset.spad.pamphlet
+ @ echo 0 making ${MID}/GPOLSET.spad from ${IN}/polset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GPOLSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GPOLSET GeneralPolynomialSet" ${IN}/polset.spad.pamphlet >GPOLSET.spad )
+
+@
+<<PSETCAT-.o (O from NRLIB)>>=
+${OUT}/PSETCAT-.o: ${MID}/PSETCAT.NRLIB
+ @ echo 0 making ${OUT}/PSETCAT-.o from ${MID}/PSETCAT-.NRLIB
+ @ cp ${MID}/PSETCAT-.NRLIB/code.o ${OUT}/PSETCAT-.o
+
+@
+<<PSETCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/PSETCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/PSETCAT.spad
+ @ echo 0 making ${MID}/PSETCAT-.NRLIB from ${MID}/PSETCAT.spad
+ @ (cd ${MID} ; echo ')co PSETCAT.spad' | ${INTERPSYS} )
+
+@
+<<PSETCAT.o (O from NRLIB)>>=
+${OUT}/PSETCAT.o: ${MID}/PSETCAT.NRLIB
+ @ echo 0 making ${OUT}/PSETCAT.o from ${MID}/PSETCAT.NRLIB
+ @ cp ${MID}/PSETCAT.NRLIB/code.o ${OUT}/PSETCAT.o
+
+@
+<<PSETCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PSETCAT.NRLIB: ${MID}/PSETCAT.spad
+ @ echo 0 making ${MID}/PSETCAT.NRLIB from ${MID}/PSETCAT.spad
+ @ (cd ${MID} ; echo ')co PSETCAT.spad' | ${INTERPSYS} )
+
+@
+<<PSETCAT.spad (SPAD from IN)>>=
+${MID}/PSETCAT.spad: ${IN}/polset.spad.pamphlet
+ @ echo 0 making ${MID}/PSETCAT.spad from ${IN}/polset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSETCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PSETCAT PolynomialSetCategory" ${IN}/polset.spad.pamphlet >PSETCAT.spad )
+
+@
+<<PSETCAT-.o (BOOTSTRAP from MID)>>=
+${MID}/PSETCAT-.o: ${MID}/PSETCAT-.lsp
+ @ echo 0 making ${MID}/PSETCAT-.o from ${MID}/PSETCAT-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "PSETCAT-.lsp" :output-file "PSETCAT-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/PSETCAT-.o ${OUT}/PSETCAT-.o
+
+@
+<<PSETCAT-.lsp (LISP from IN)>>=
+${MID}/PSETCAT-.lsp: ${IN}/polset.spad.pamphlet
+ @ echo 0 making ${MID}/PSETCAT-.lsp from ${IN}/polset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSETCAT-.NRLIB ; \
+ rm -rf ${OUT}/PSETCAT-.o ; \
+ ${SPADBIN}/notangle -R"PSETCAT-.lsp BOOTSTRAP" ${IN}/polset.spad.pamphlet >PSETCAT-.lsp )
+
+@
+<<PSETCAT.o (BOOTSTRAP from MID)>>=
+${MID}/PSETCAT.o: ${MID}/PSETCAT.lsp
+ @ echo 0 making ${MID}/PSETCAT.o from ${MID}/PSETCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "PSETCAT.lsp" :output-file "PSETCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/PSETCAT.o ${OUT}/PSETCAT.o
+
+@
+<<PSETCAT.lsp (LISP from IN)>>=
+${MID}/PSETCAT.lsp: ${IN}/polset.spad.pamphlet
+ @ echo 0 making ${MID}/PSETCAT.lsp from ${IN}/polset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSETCAT.NRLIB ; \
+ rm -rf ${OUT}/PSETCAT.o ; \
+ ${SPADBIN}/notangle -R"PSETCAT.lsp BOOTSTRAP" ${IN}/polset.spad.pamphlet >PSETCAT.lsp )
+
+@
+<<polset.spad.dvi (DOC from IN)>>=
+${DOC}/polset.spad.dvi: ${IN}/polset.spad.pamphlet
+ @ echo 0 making ${DOC}/polset.spad.dvi from ${IN}/polset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/polset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} polset.spad ; \
+ rm -f ${DOC}/polset.spad.pamphlet ; \
+ rm -f ${DOC}/polset.spad.tex ; \
+ rm -f ${DOC}/polset.spad )
+
+@
+\subsection{poltopol.spad \cite{1}}
+<<poltopol.spad (SPAD from IN)>>=
+${MID}/poltopol.spad: ${IN}/poltopol.spad.pamphlet
+ @ echo 0 making ${MID}/poltopol.spad from ${IN}/poltopol.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/poltopol.spad.pamphlet >poltopol.spad )
+
+@
+<<MPC2.o (O from NRLIB)>>=
+${OUT}/MPC2.o: ${MID}/MPC2.NRLIB
+ @ echo 0 making ${OUT}/MPC2.o from ${MID}/MPC2.NRLIB
+ @ cp ${MID}/MPC2.NRLIB/code.o ${OUT}/MPC2.o
+
+@
+<<MPC2.NRLIB (NRLIB from MID)>>=
+${MID}/MPC2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MPC2.spad
+ @ echo 0 making ${MID}/MPC2.NRLIB from ${MID}/MPC2.spad
+ @ (cd ${MID} ; echo ')co MPC2.spad' | ${INTERPSYS} )
+
+@
+<<MPC2.spad (SPAD from IN)>>=
+${MID}/MPC2.spad: ${IN}/poltopol.spad.pamphlet
+ @ echo 0 making ${MID}/MPC2.spad from ${IN}/poltopol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MPC2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MPC2 MPolyCatFunctions2" ${IN}/poltopol.spad.pamphlet >MPC2.spad )
+
+@
+<<MPC3.o (O from NRLIB)>>=
+${OUT}/MPC3.o: ${MID}/MPC3.NRLIB
+ @ echo 0 making ${OUT}/MPC3.o from ${MID}/MPC3.NRLIB
+ @ cp ${MID}/MPC3.NRLIB/code.o ${OUT}/MPC3.o
+
+@
+<<MPC3.NRLIB (NRLIB from MID)>>=
+${MID}/MPC3.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/MPC3.spad
+ @ echo 0 making ${MID}/MPC3.NRLIB from ${MID}/MPC3.spad
+ @ (cd ${MID} ; echo ')co MPC3.spad' | ${INTERPSYS} )
+
+@
+<<MPC3.spad (SPAD from IN)>>=
+${MID}/MPC3.spad: ${IN}/poltopol.spad.pamphlet
+ @ echo 0 making ${MID}/MPC3.spad from ${IN}/poltopol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MPC3.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MPC3 MPolyCatFunctions3" ${IN}/poltopol.spad.pamphlet >MPC3.spad )
+
+@
+<<POLTOPOL.o (O from NRLIB)>>=
+${OUT}/POLTOPOL.o: ${MID}/POLTOPOL.NRLIB
+ @ echo 0 making ${OUT}/POLTOPOL.o from ${MID}/POLTOPOL.NRLIB
+ @ cp ${MID}/POLTOPOL.NRLIB/code.o ${OUT}/POLTOPOL.o
+
+@
+<<POLTOPOL.NRLIB (NRLIB from MID)>>=
+${MID}/POLTOPOL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLTOPOL.spad
+ @ echo 0 making ${MID}/POLTOPOL.NRLIB from ${MID}/POLTOPOL.spad
+ @ (cd ${MID} ; echo ')co POLTOPOL.spad' | ${INTERPSYS} )
+
+@
+<<POLTOPOL.spad (SPAD from IN)>>=
+${MID}/POLTOPOL.spad: ${IN}/poltopol.spad.pamphlet
+ @ echo 0 making ${MID}/POLTOPOL.spad from ${IN}/poltopol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLTOPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLTOPOL PolToPol" ${IN}/poltopol.spad.pamphlet >POLTOPOL.spad )
+
+@
+<<poltopol.spad.dvi (DOC from IN)>>=
+${DOC}/poltopol.spad.dvi: ${IN}/poltopol.spad.pamphlet
+ @ echo 0 making ${DOC}/poltopol.spad.dvi from ${IN}/poltopol.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/poltopol.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} poltopol.spad ; \
+ rm -f ${DOC}/poltopol.spad.pamphlet ; \
+ rm -f ${DOC}/poltopol.spad.tex ; \
+ rm -f ${DOC}/poltopol.spad )
+
+@
+\subsection{polycat.spad \cite{1}}
+<<polycat.spad (SPAD from IN)>>=
+${MID}/polycat.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/polycat.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/polycat.spad.pamphlet >polycat.spad )
+
+@
+<<AMR-.o (O from NRLIB)>>=
+${OUT}/AMR-.o: ${MID}/AMR.NRLIB
+ @ echo 0 making ${OUT}/AMR-.o from ${MID}/AMR-.NRLIB
+ @ cp ${MID}/AMR-.NRLIB/code.o ${OUT}/AMR-.o
+
+@
+<<AMR-.NRLIB (NRLIB from MID)>>=
+${MID}/AMR-.NRLIB: ${OUT}/TYPE.o ${MID}/AMR.spad
+ @ echo 0 making ${MID}/AMR-.NRLIB from ${MID}/AMR.spad
+ @ (cd ${MID} ; echo ')co AMR.spad' | ${INTERPSYS} )
+
+@
+<<AMR.o (O from NRLIB)>>=
+${OUT}/AMR.o: ${MID}/AMR.NRLIB
+ @ echo 0 making ${OUT}/AMR.o from ${MID}/AMR.NRLIB
+ @ cp ${MID}/AMR.NRLIB/code.o ${OUT}/AMR.o
+
+@
+<<AMR.NRLIB (NRLIB from MID)>>=
+${MID}/AMR.NRLIB: ${MID}/AMR.spad
+ @ echo 0 making ${MID}/AMR.NRLIB from ${MID}/AMR.spad
+ @ (cd ${MID} ; echo ')co AMR.spad' | ${INTERPSYS} )
+
+@
+<<AMR.spad (SPAD from IN)>>=
+${MID}/AMR.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/AMR.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf AMR.NRLIB ; \
+ ${SPADBIN}/notangle -R"category AMR AbelianMonoidRing" ${IN}/polycat.spad.pamphlet >AMR.spad )
+
+@
+<<COMMUPC.o (O from NRLIB)>>=
+${OUT}/COMMUPC.o: ${MID}/COMMUPC.NRLIB
+ @ echo 0 making ${OUT}/COMMUPC.o from ${MID}/COMMUPC.NRLIB
+ @ cp ${MID}/COMMUPC.NRLIB/code.o ${OUT}/COMMUPC.o
+
+@
+<<COMMUPC.NRLIB (NRLIB from MID)>>=
+${MID}/COMMUPC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/COMMUPC.spad
+ @ echo 0 making ${MID}/COMMUPC.NRLIB from ${MID}/COMMUPC.spad
+ @ (cd ${MID} ; echo ')co COMMUPC.spad' | ${INTERPSYS} )
+
+@
+<<COMMUPC.spad (SPAD from IN)>>=
+${MID}/COMMUPC.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/COMMUPC.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf COMMUPC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package COMMUPC CommuteUnivariatePolynomialCategory" ${IN}/polycat.spad.pamphlet >COMMUPC.spad )
+
+@
+<<FAMR-.o (O from NRLIB)>>=
+${OUT}/FAMR-.o: ${MID}/FAMR.NRLIB
+ @ echo 0 making ${OUT}/FAMR-.o from ${MID}/FAMR-.NRLIB
+ @ cp ${MID}/FAMR-.NRLIB/code.o ${OUT}/FAMR-.o
+
+@
+<<FAMR-.NRLIB (NRLIB from MID)>>=
+${MID}/FAMR-.NRLIB: ${OUT}/TYPE.o ${MID}/FAMR.spad
+ @ echo 0 making ${MID}/FAMR-.NRLIB from ${MID}/FAMR.spad
+ @ (cd ${MID} ; echo ')co FAMR.spad' | ${INTERPSYS} )
+
+@
+<<FAMR.o (O from NRLIB)>>=
+${OUT}/FAMR.o: ${MID}/FAMR.NRLIB
+ @ echo 0 making ${OUT}/FAMR.o from ${MID}/FAMR.NRLIB
+ @ cp ${MID}/FAMR.NRLIB/code.o ${OUT}/FAMR.o
+
+@
+<<FAMR.NRLIB (NRLIB from MID)>>=
+${MID}/FAMR.NRLIB: ${MID}/FAMR.spad
+ @ echo 0 making ${MID}/FAMR.NRLIB from ${MID}/FAMR.spad
+ @ (cd ${MID} ; echo ')co FAMR.spad' | ${INTERPSYS} )
+
+@
+<<FAMR.spad (SPAD from IN)>>=
+${MID}/FAMR.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/FAMR.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FAMR.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FAMR FiniteAbelianMonoidRing" ${IN}/polycat.spad.pamphlet >FAMR.spad )
+
+@
+<<POLYCAT-.o (O from NRLIB)>>=
+${OUT}/POLYCAT-.o: ${MID}/POLYCAT.NRLIB
+ @ echo 0 making ${OUT}/POLYCAT-.o from ${MID}/POLYCAT-.NRLIB
+ @ cp ${MID}/POLYCAT-.NRLIB/code.o ${OUT}/POLYCAT-.o
+
+@
+<<POLYCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/POLYCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/POLYCAT.spad
+ @ echo 0 making ${MID}/POLYCAT-.NRLIB from ${MID}/POLYCAT.spad
+ @ (cd ${MID} ; echo ')co POLYCAT.spad' | ${INTERPSYS} )
+
+@
+<<POLYCAT.o (O from NRLIB)>>=
+${OUT}/POLYCAT.o: ${MID}/POLYCAT.NRLIB
+ @ echo 0 making ${OUT}/POLYCAT.o from ${MID}/POLYCAT.NRLIB
+ @ cp ${MID}/POLYCAT.NRLIB/code.o ${OUT}/POLYCAT.o
+
+@
+<<POLYCAT.NRLIB (NRLIB from MID)>>=
+${MID}/POLYCAT.NRLIB: ${MID}/POLYCAT.spad
+ @ echo 0 making ${MID}/POLYCAT.NRLIB from ${MID}/POLYCAT.spad
+ @ (cd ${MID} ; echo ')co POLYCAT.spad' | ${INTERPSYS} )
+
+@
+<<POLYCAT.spad (SPAD from IN)>>=
+${MID}/POLYCAT.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/POLYCAT.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLYCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category POLYCAT PolynomialCategory" ${IN}/polycat.spad.pamphlet >POLYCAT.spad )
+
+@
+<<POLYCAT-.o (BOOTSTRAP from MID)>>=
+${MID}/POLYCAT-.o: ${MID}/POLYCAT-.lsp
+ @ echo 0 making ${MID}/POLYCAT-.o from ${MID}/POLYCAT-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "POLYCAT-.lsp" :output-file "POLYCAT-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/POLYCAT-.o ${OUT}/POLYCAT-.o
+
+@
+<<POLYCAT-.lsp (LISP from IN)>>=
+${MID}/POLYCAT-.lsp: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/POLYCAT-.lsp from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLYCAT-.NRLIB ; \
+ rm -rf ${OUT}/POLYCAT-.o ; \
+ ${SPADBIN}/notangle -R"POLYCAT-.lsp BOOTSTRAP" ${IN}/polycat.spad.pamphlet >POLYCAT-.lsp )
+
+@
+<<POLYCAT.o (BOOTSTRAP from MID)>>=
+${MID}/POLYCAT.o: ${MID}/POLYCAT.lsp
+ @ echo 0 making ${MID}/POLYCAT.o from ${MID}/POLYCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "POLYCAT.lsp" :output-file "POLYCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/POLYCAT.o ${OUT}/POLYCAT.o
+
+@
+<<POLYCAT.lsp (LISP from IN)>>=
+${MID}/POLYCAT.lsp: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/POLYCAT.lsp from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLYCAT.NRLIB ; \
+ rm -rf ${OUT}/POLYCAT.o ; \
+ ${SPADBIN}/notangle -R"POLYCAT.lsp BOOTSTRAP" ${IN}/polycat.spad.pamphlet >POLYCAT.lsp )
+
+@
+<<POLYLIFT.o (O from NRLIB)>>=
+${OUT}/POLYLIFT.o: ${MID}/POLYLIFT.NRLIB
+ @ echo 0 making ${OUT}/POLYLIFT.o from ${MID}/POLYLIFT.NRLIB
+ @ cp ${MID}/POLYLIFT.NRLIB/code.o ${OUT}/POLYLIFT.o
+
+@
+<<POLYLIFT.NRLIB (NRLIB from MID)>>=
+${MID}/POLYLIFT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLYLIFT.spad
+ @ echo 0 making ${MID}/POLYLIFT.NRLIB from ${MID}/POLYLIFT.spad
+ @ (cd ${MID} ; echo ')co POLYLIFT.spad' | ${INTERPSYS} )
+
+@
+<<POLYLIFT.spad (SPAD from IN)>>=
+${MID}/POLYLIFT.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/POLYLIFT.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLYLIFT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLYLIFT PolynomialCategoryLifting" ${IN}/polycat.spad.pamphlet >POLYLIFT.spad )
+
+@
+<<UPOLYC-.o (O from NRLIB)>>=
+${OUT}/UPOLYC-.o: ${MID}/UPOLYC.NRLIB
+ @ echo 0 making ${OUT}/UPOLYC-.o from ${MID}/UPOLYC-.NRLIB
+ @ cp ${MID}/UPOLYC-.NRLIB/code.o ${OUT}/UPOLYC-.o
+
+@
+<<UPOLYC-.NRLIB (NRLIB from MID)>>=
+${MID}/UPOLYC-.NRLIB: ${OUT}/TYPE.o ${MID}/UPOLYC.spad
+ @ echo 0 making ${MID}/UPOLYC-.NRLIB from ${MID}/UPOLYC.spad
+ @ (cd ${MID} ; echo ')co UPOLYC.spad' | ${INTERPSYS} )
+
+@
+<<UPOLYC.o (O from NRLIB)>>=
+${OUT}/UPOLYC.o: ${MID}/UPOLYC.NRLIB
+ @ echo 0 making ${OUT}/UPOLYC.o from ${MID}/UPOLYC.NRLIB
+ @ cp ${MID}/UPOLYC.NRLIB/code.o ${OUT}/UPOLYC.o
+
+@
+<<UPOLYC.NRLIB (NRLIB from MID)>>=
+${MID}/UPOLYC.NRLIB: ${MID}/UPOLYC.spad
+ @ echo 0 making ${MID}/UPOLYC.NRLIB from ${MID}/UPOLYC.spad
+ @ (cd ${MID} ; echo ')co UPOLYC.spad' | ${INTERPSYS} )
+
+@
+<<UPOLYC.spad (SPAD from IN)>>=
+${MID}/UPOLYC.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/UPOLYC.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPOLYC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category UPOLYC UnivariatePolynomialCategory" ${IN}/polycat.spad.pamphlet >UPOLYC.spad )
+
+@
+<<UPOLYC-.o (BOOTSTRAP from MID)>>=
+${MID}/UPOLYC-.o: ${MID}/UPOLYC-.lsp
+ @ echo 0 making ${MID}/UPOLYC-.o from ${MID}/UPOLYC-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "UPOLYC-.lsp" :output-file "UPOLYC-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/UPOLYC-.o ${OUT}/UPOLYC-.o
+
+@
+<<UPOLYC-.lsp (LISP from IN)>>=
+${MID}/UPOLYC-.lsp: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/UPOLYC-.lsp from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPOLYC-.NRLIB ; \
+ rm -rf ${OUT}/UPOLYC-.o ; \
+ ${SPADBIN}/notangle -R"UPOLYC-.lsp BOOTSTRAP" ${IN}/polycat.spad.pamphlet >UPOLYC-.lsp )
+
+@
+<<UPOLYC.o (BOOTSTRAP from MID)>>=
+${MID}/UPOLYC.o: ${MID}/UPOLYC.lsp
+ @ echo 0 making ${MID}/UPOLYC.o from ${MID}/UPOLYC.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "UPOLYC.lsp" :output-file "UPOLYC.o"))' | ${DEPSYS} )
+ @ cp ${MID}/UPOLYC.o ${OUT}/UPOLYC.o
+
+@
+<<UPOLYC.lsp (LISP from IN)>>=
+${MID}/UPOLYC.lsp: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/UPOLYC.lsp from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPOLYC.NRLIB ; \
+ rm -rf ${OUT}/UPOLYC.o ; \
+ ${SPADBIN}/notangle -R"UPOLYC.lsp BOOTSTRAP" ${IN}/polycat.spad.pamphlet >UPOLYC.lsp )
+
+@
+<<UPOLYC2.o (O from NRLIB)>>=
+${OUT}/UPOLYC2.o: ${MID}/UPOLYC2.NRLIB
+ @ echo 0 making ${OUT}/UPOLYC2.o from ${MID}/UPOLYC2.NRLIB
+ @ cp ${MID}/UPOLYC2.NRLIB/code.o ${OUT}/UPOLYC2.o
+
+@
+<<UPOLYC2.NRLIB (NRLIB from MID)>>=
+${MID}/UPOLYC2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UPOLYC2.spad
+ @ echo 0 making ${MID}/UPOLYC2.NRLIB from ${MID}/UPOLYC2.spad
+ @ (cd ${MID} ; echo ')co UPOLYC2.spad' | ${INTERPSYS} )
+
+@
+<<UPOLYC2.spad (SPAD from IN)>>=
+${MID}/UPOLYC2.spad: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${MID}/UPOLYC2.spad from ${IN}/polycat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPOLYC2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPOLYC2 UnivariatePolynomialCategoryFunctions2" ${IN}/polycat.spad.pamphlet >UPOLYC2.spad )
+
+@
+<<polycat.spad.dvi (DOC from IN)>>=
+${DOC}/polycat.spad.dvi: ${IN}/polycat.spad.pamphlet
+ @ echo 0 making ${DOC}/polycat.spad.dvi from ${IN}/polycat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/polycat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} polycat.spad ; \
+ rm -f ${DOC}/polycat.spad.pamphlet ; \
+ rm -f ${DOC}/polycat.spad.tex ; \
+ rm -f ${DOC}/polycat.spad )
+
+@
+\subsection{poly.spad \cite{1}}
+<<poly.spad (SPAD from IN)>>=
+${MID}/poly.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/poly.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/poly.spad.pamphlet >poly.spad )
+
+@
+<<FM.o (O from NRLIB)>>=
+${OUT}/FM.o: ${MID}/FM.NRLIB
+ @ echo 0 making ${OUT}/FM.o from ${MID}/FM.NRLIB
+ @ cp ${MID}/FM.NRLIB/code.o ${OUT}/FM.o
+
+@
+<<FM.NRLIB (NRLIB from MID)>>=
+${MID}/FM.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FM.spad
+ @ echo 0 making ${MID}/FM.NRLIB from ${MID}/FM.spad
+ @ (cd ${MID} ; echo ')co FM.spad' | ${INTERPSYS} )
+
+@
+<<FM.spad (SPAD from IN)>>=
+${MID}/FM.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/FM.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FM FreeModule" ${IN}/poly.spad.pamphlet >FM.spad )
+
+@
+<<POLY2UP.o (O from NRLIB)>>=
+${OUT}/POLY2UP.o: ${MID}/POLY2UP.NRLIB
+ @ echo 0 making ${OUT}/POLY2UP.o from ${MID}/POLY2UP.NRLIB
+ @ cp ${MID}/POLY2UP.NRLIB/code.o ${OUT}/POLY2UP.o
+
+@
+<<POLY2UP.NRLIB (NRLIB from MID)>>=
+${MID}/POLY2UP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLY2UP.spad
+ @ echo 0 making ${MID}/POLY2UP.NRLIB from ${MID}/POLY2UP.spad
+ @ (cd ${MID} ; echo ')co POLY2UP.spad' | ${INTERPSYS} )
+
+@
+<<POLY2UP.spad (SPAD from IN)>>=
+${MID}/POLY2UP.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/POLY2UP.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLY2UP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLY2UP PolynomialToUnivariatePolynomial" ${IN}/poly.spad.pamphlet >POLY2UP.spad )
+
+@
+<<PR.o (O from NRLIB)>>=
+${OUT}/PR.o: ${MID}/PR.NRLIB
+ @ echo 0 making ${OUT}/PR.o from ${MID}/PR.NRLIB
+ @ cp ${MID}/PR.NRLIB/code.o ${OUT}/PR.o
+
+@
+<<PR.NRLIB (NRLIB from MID)>>=
+${MID}/PR.NRLIB: ${MID}/PR.spad
+ @ echo 0 making ${MID}/PR.NRLIB from ${MID}/PR.spad
+ @ (cd ${MID} ; echo ')co PR.spad' | ${INTERPSYS} )
+
+@
+<<PR.spad (SPAD from IN)>>=
+${MID}/PR.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/PR.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PR PolynomialRing" ${IN}/poly.spad.pamphlet >PR.spad )
+
+@
+<<PSQFR.o (O from NRLIB)>>=
+${OUT}/PSQFR.o: ${MID}/PSQFR.NRLIB
+ @ echo 0 making ${OUT}/PSQFR.o from ${MID}/PSQFR.NRLIB
+ @ cp ${MID}/PSQFR.NRLIB/code.o ${OUT}/PSQFR.o
+
+@
+<<PSQFR.NRLIB (NRLIB from MID)>>=
+${MID}/PSQFR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PSQFR.spad
+ @ echo 0 making ${MID}/PSQFR.NRLIB from ${MID}/PSQFR.spad
+ @ (cd ${MID} ; echo ')co PSQFR.spad' | ${INTERPSYS} )
+
+@
+<<PSQFR.spad (SPAD from IN)>>=
+${MID}/PSQFR.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/PSQFR.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSQFR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PSQFR PolynomialSquareFree" ${IN}/poly.spad.pamphlet >PSQFR.spad )
+
+@
+<<SUP.o (O from NRLIB)>>=
+${OUT}/SUP.o: ${MID}/SUP.NRLIB
+ @ echo 0 making ${OUT}/SUP.o from ${MID}/SUP.NRLIB
+ @ cp ${MID}/SUP.NRLIB/code.o ${OUT}/SUP.o
+
+@
+<<SUP.NRLIB (NRLIB from MID)>>=
+${MID}/SUP.NRLIB: ${MID}/SUP.spad
+ @ echo 0 making ${MID}/SUP.NRLIB from ${MID}/SUP.spad
+ @ (cd ${MID} ; echo ')co SUP.spad' | ${INTERPSYS} )
+
+@
+<<SUP.spad (SPAD from IN)>>=
+${MID}/SUP.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/SUP.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SUP SparseUnivariatePolynomial" ${IN}/poly.spad.pamphlet >SUP.spad )
+
+@
+<<SUP2.o (O from NRLIB)>>=
+${OUT}/SUP2.o: ${MID}/SUP2.NRLIB
+ @ echo 0 making ${OUT}/SUP2.o from ${MID}/SUP2.NRLIB
+ @ cp ${MID}/SUP2.NRLIB/code.o ${OUT}/SUP2.o
+
+@
+<<SUP2.NRLIB (NRLIB from MID)>>=
+${MID}/SUP2.NRLIB: ${MID}/SUP2.spad
+ @ echo 0 making ${MID}/SUP2.NRLIB from ${MID}/SUP2.spad
+ @ (cd ${MID} ; echo ')co SUP2.spad' | ${INTERPSYS} )
+
+@
+<<SUP2.spad (SPAD from IN)>>=
+${MID}/SUP2.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/SUP2.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUP2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SUP2 SparseUnivariatePolynomialFunctions2" ${IN}/poly.spad.pamphlet >SUP2.spad )
+
+@
+<<UP.o (O from NRLIB)>>=
+${OUT}/UP.o: ${MID}/UP.NRLIB
+ @ echo 0 making ${OUT}/UP.o from ${MID}/UP.NRLIB
+ @ cp ${MID}/UP.NRLIB/code.o ${OUT}/UP.o
+
+@
+<<UP.NRLIB (NRLIB from MID)>>=
+${MID}/UP.NRLIB: ${MID}/UP.spad
+ @ echo 0 making ${MID}/UP.NRLIB from ${MID}/UP.spad
+ @ (cd ${MID} ; echo ')co UP.spad' | ${INTERPSYS} )
+
+@
+<<UP.spad (SPAD from IN)>>=
+${MID}/UP.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/UP.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain UP UnivariatePolynomial" ${IN}/poly.spad.pamphlet >UP.spad )
+
+@
+<<UPMP.o (O from NRLIB)>>=
+${OUT}/UPMP.o: ${MID}/UPMP.NRLIB
+ @ echo 0 making ${OUT}/UPMP.o from ${MID}/UPMP.NRLIB
+ @ cp ${MID}/UPMP.NRLIB/code.o ${OUT}/UPMP.o
+
+@
+<<UPMP.NRLIB (NRLIB from MID)>>=
+${MID}/UPMP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UPMP.spad
+ @ echo 0 making ${MID}/UPMP.NRLIB from ${MID}/UPMP.spad
+ @ (cd ${MID} ; echo ')co UPMP.spad' | ${INTERPSYS} )
+
+@
+<<UPMP.spad (SPAD from IN)>>=
+${MID}/UPMP.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/UPMP.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPMP UnivariatePolynomialMultiplicationPackage" ${IN}/poly.spad.pamphlet >UPMP.spad )
+
+@
+<<UP2.o (O from NRLIB)>>=
+${OUT}/UP2.o: ${MID}/UP2.NRLIB
+ @ echo 0 making ${OUT}/UP2.o from ${MID}/UP2.NRLIB
+ @ cp ${MID}/UP2.NRLIB/code.o ${OUT}/UP2.o
+
+@
+<<UP2.NRLIB (NRLIB from MID)>>=
+${MID}/UP2.NRLIB: ${MID}/UP2.spad
+ @ echo 0 making ${MID}/UP2.NRLIB from ${MID}/UP2.spad
+ @ (cd ${MID} ; echo ')co UP2.spad' | ${INTERPSYS} )
+
+@
+<<UP2.spad (SPAD from IN)>>=
+${MID}/UP2.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/UP2.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UP2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UP2 UnivariatePolynomialFunctions2" ${IN}/poly.spad.pamphlet >UP2.spad )
+
+@
+<<UPSQFREE.o (O from NRLIB)>>=
+${OUT}/UPSQFREE.o: ${MID}/UPSQFREE.NRLIB
+ @ echo 0 making ${OUT}/UPSQFREE.o from ${MID}/UPSQFREE.NRLIB
+ @ cp ${MID}/UPSQFREE.NRLIB/code.o ${OUT}/UPSQFREE.o
+
+@
+<<UPSQFREE.NRLIB (NRLIB from MID)>>=
+${MID}/UPSQFREE.NRLIB: ${MID}/UPSQFREE.spad
+ @ echo 0 making ${MID}/UPSQFREE.NRLIB from ${MID}/UPSQFREE.spad
+ @ (cd ${MID} ; echo ')co UPSQFREE.spad' | ${INTERPSYS} )
+
+@
+<<UPSQFREE.spad (SPAD from IN)>>=
+${MID}/UPSQFREE.spad: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${MID}/UPSQFREE.spad from ${IN}/poly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPSQFREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPSQFREE UnivariatePolynomialSquareFree" ${IN}/poly.spad.pamphlet >UPSQFREE.spad )
+
+@
+<<poly.spad.dvi (DOC from IN)>>=
+${DOC}/poly.spad.dvi: ${IN}/poly.spad.pamphlet
+ @ echo 0 making ${DOC}/poly.spad.dvi from ${IN}/poly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/poly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} poly.spad ; \
+ rm -f ${DOC}/poly.spad.pamphlet ; \
+ rm -f ${DOC}/poly.spad.tex ; \
+ rm -f ${DOC}/poly.spad )
+
+@
+\subsection{primelt.spad \cite{1}}
+<<primelt.spad (SPAD from IN)>>=
+${MID}/primelt.spad: ${IN}/primelt.spad.pamphlet
+ @ echo 0 making ${MID}/primelt.spad from ${IN}/primelt.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/primelt.spad.pamphlet >primelt.spad )
+
+@
+<<FSPRMELT.o (O from NRLIB)>>=
+${OUT}/FSPRMELT.o: ${MID}/FSPRMELT.NRLIB
+ @ echo 0 making ${OUT}/FSPRMELT.o from ${MID}/FSPRMELT.NRLIB
+ @ cp ${MID}/FSPRMELT.NRLIB/code.o ${OUT}/FSPRMELT.o
+
+@
+<<FSPRMELT.NRLIB (NRLIB from MID)>>=
+${MID}/FSPRMELT.NRLIB: ${MID}/FSPRMELT.spad
+ @ echo 0 making ${MID}/FSPRMELT.NRLIB from ${MID}/FSPRMELT.spad
+ @ (cd ${MID} ; echo ')co FSPRMELT.spad' | ${INTERPSYS} )
+
+@
+<<FSPRMELT.spad (SPAD from IN)>>=
+${MID}/FSPRMELT.spad: ${IN}/primelt.spad.pamphlet
+ @ echo 0 making ${MID}/FSPRMELT.spad from ${IN}/primelt.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FSPRMELT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FSPRMELT FunctionSpacePrimitiveElement" ${IN}/primelt.spad.pamphlet >FSPRMELT.spad )
+
+@
+<<PRIMELT.o (O from NRLIB)>>=
+${OUT}/PRIMELT.o: ${MID}/PRIMELT.NRLIB
+ @ echo 0 making ${OUT}/PRIMELT.o from ${MID}/PRIMELT.NRLIB
+ @ cp ${MID}/PRIMELT.NRLIB/code.o ${OUT}/PRIMELT.o
+
+@
+<<PRIMELT.NRLIB (NRLIB from MID)>>=
+${MID}/PRIMELT.NRLIB: ${MID}/PRIMELT.spad
+ @ echo 0 making ${MID}/PRIMELT.NRLIB from ${MID}/PRIMELT.spad
+ @ (cd ${MID} ; echo ')co PRIMELT.spad' | ${INTERPSYS} )
+
+@
+<<PRIMELT.spad (SPAD from IN)>>=
+${MID}/PRIMELT.spad: ${IN}/primelt.spad.pamphlet
+ @ echo 0 making ${MID}/PRIMELT.spad from ${IN}/primelt.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRIMELT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PRIMELT PrimitiveElement" ${IN}/primelt.spad.pamphlet >PRIMELT.spad )
+
+@
+<<primelt.spad.dvi (DOC from IN)>>=
+${DOC}/primelt.spad.dvi: ${IN}/primelt.spad.pamphlet
+ @ echo 0 making ${DOC}/primelt.spad.dvi from ${IN}/primelt.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/primelt.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} primelt.spad ; \
+ rm -f ${DOC}/primelt.spad.pamphlet ; \
+ rm -f ${DOC}/primelt.spad.tex ; \
+ rm -f ${DOC}/primelt.spad )
+
+@
+\subsection{print.spad \cite{1}}
+<<print.spad (SPAD from IN)>>=
+${MID}/print.spad: ${IN}/print.spad.pamphlet
+ @ echo 0 making ${MID}/print.spad from ${IN}/print.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/print.spad.pamphlet >print.spad )
+
+@
+<<PRINT.o (O from NRLIB)>>=
+${OUT}/PRINT.o: ${MID}/PRINT.NRLIB
+ @ echo 0 making ${OUT}/PRINT.o from ${MID}/PRINT.NRLIB
+ @ cp ${MID}/PRINT.NRLIB/code.o ${OUT}/PRINT.o
+
+@
+<<PRINT.NRLIB (NRLIB from MID)>>=
+${MID}/PRINT.NRLIB: ${MID}/PRINT.spad
+ @ echo 0 making ${MID}/PRINT.NRLIB from ${MID}/PRINT.spad
+ @ (cd ${MID} ; echo ')co PRINT.spad' | ${INTERPSYS} )
+
+@
+<<PRINT.spad (SPAD from IN)>>=
+${MID}/PRINT.spad: ${IN}/print.spad.pamphlet
+ @ echo 0 making ${MID}/PRINT.spad from ${IN}/print.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PRINT PrintPackage" ${IN}/print.spad.pamphlet >PRINT.spad )
+
+@
+<<print.spad.dvi (DOC from IN)>>=
+${DOC}/print.spad.dvi: ${IN}/print.spad.pamphlet
+ @ echo 0 making ${DOC}/print.spad.dvi from ${IN}/print.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/print.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} print.spad ; \
+ rm -f ${DOC}/print.spad.pamphlet ; \
+ rm -f ${DOC}/print.spad.tex ; \
+ rm -f ${DOC}/print.spad )
+
+@
+\subsection{product.spad \cite{1}}
+<<product.spad (SPAD from IN)>>=
+${MID}/product.spad: ${IN}/product.spad.pamphlet
+ @ echo 0 making ${MID}/product.spad from ${IN}/product.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/product.spad.pamphlet >product.spad )
+
+@
+<<PRODUCT.o (O from NRLIB)>>=
+${OUT}/PRODUCT.o: ${MID}/PRODUCT.NRLIB
+ @ echo 0 making ${OUT}/PRODUCT.o from ${MID}/PRODUCT.NRLIB
+ @ cp ${MID}/PRODUCT.NRLIB/code.o ${OUT}/PRODUCT.o
+
+@
+<<PRODUCT.NRLIB (NRLIB from MID)>>=
+${MID}/PRODUCT.NRLIB: ${MID}/PRODUCT.spad
+ @ echo 0 making ${MID}/PRODUCT.NRLIB from ${MID}/PRODUCT.spad
+ @ (cd ${MID} ; echo ')co PRODUCT.spad' | ${INTERPSYS} )
+
+@
+<<PRODUCT.spad (SPAD from IN)>>=
+${MID}/PRODUCT.spad: ${IN}/product.spad.pamphlet
+ @ echo 0 making ${MID}/PRODUCT.spad from ${IN}/product.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRODUCT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PRODUCT Product" ${IN}/product.spad.pamphlet >PRODUCT.spad )
+
+@
+<<product.spad.dvi (DOC from IN)>>=
+${DOC}/product.spad.dvi: ${IN}/product.spad.pamphlet
+ @ echo 0 making ${DOC}/product.spad.dvi from ${IN}/product.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/product.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} product.spad ; \
+ rm -f ${DOC}/product.spad.pamphlet ; \
+ rm -f ${DOC}/product.spad.tex ; \
+ rm -f ${DOC}/product.spad )
+
+@
+\subsection{prs.spad \cite{1}}
+<<prs.spad (SPAD from IN)>>=
+${MID}/prs.spad: ${IN}/prs.spad.pamphlet
+ @ echo 0 making ${MID}/prs.spad from ${IN}/prs.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/prs.spad.pamphlet >prs.spad )
+
+@
+<<PRS.o (O from NRLIB)>>=
+${OUT}/PRS.o: ${MID}/PRS.NRLIB
+ @ echo 0 making ${OUT}/PRS.o from ${MID}/PRS.NRLIB
+ @ cp ${MID}/PRS.NRLIB/code.o ${OUT}/PRS.o
+
+@
+<<PRS.NRLIB (NRLIB from MID)>>=
+${MID}/PRS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PRS.spad
+ @ echo 0 making ${MID}/PRS.NRLIB from ${MID}/PRS.spad
+ @ (cd ${MID} ; echo ')co PRS.spad' | ${INTERPSYS} )
+
+@
+<<PRS.spad (SPAD from IN)>>=
+${MID}/PRS.spad: ${IN}/prs.spad.pamphlet
+ @ echo 0 making ${MID}/PRS.spad from ${IN}/prs.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PRS PseudoRemainderSequence" ${IN}/prs.spad.pamphlet >PRS.spad )
+
+@
+<<prs.spad.dvi (DOC from IN)>>=
+${DOC}/prs.spad.dvi: ${IN}/prs.spad.pamphlet
+ @ echo 0 making ${DOC}/prs.spad.dvi from ${IN}/prs.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/prs.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} prs.spad ; \
+ rm -f ${DOC}/prs.spad.pamphlet ; \
+ rm -f ${DOC}/prs.spad.tex ; \
+ rm -f ${DOC}/prs.spad )
+
+@
+\subsection{prtition.spad \cite{1}}
+<<prtition.spad (SPAD from IN)>>=
+${MID}/prtition.spad: ${IN}/prtition.spad.pamphlet
+ @ echo 0 making ${MID}/prtition.spad from ${IN}/prtition.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/prtition.spad.pamphlet >prtition.spad )
+
+@
+<<SYMPOLY.o (O from NRLIB)>>=
+${OUT}/SYMPOLY.o: ${MID}/SYMPOLY.NRLIB
+ @ echo 0 making ${OUT}/SYMPOLY.o from ${MID}/SYMPOLY.NRLIB
+ @ cp ${MID}/SYMPOLY.NRLIB/code.o ${OUT}/SYMPOLY.o
+
+@
+<<SYMPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/SYMPOLY.NRLIB: ${MID}/SYMPOLY.spad
+ @ echo 0 making ${MID}/SYMPOLY.NRLIB from ${MID}/SYMPOLY.spad
+ @ (cd ${MID} ; echo ')co SYMPOLY.spad' | ${INTERPSYS} )
+
+@
+<<SYMPOLY.spad (SPAD from IN)>>=
+${MID}/SYMPOLY.spad: ${IN}/prtition.spad.pamphlet
+ @ echo 0 making ${MID}/SYMPOLY.spad from ${IN}/prtition.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYMPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SYMPOLY SymmetricPolynomial" ${IN}/prtition.spad.pamphlet >SYMPOLY.spad )
+
+@
+<<PRTITION.o (O from NRLIB)>>=
+${OUT}/PRTITION.o: ${MID}/PRTITION.NRLIB
+ @ echo 0 making ${OUT}/PRTITION.o from ${MID}/PRTITION.NRLIB
+ @ cp ${MID}/PRTITION.NRLIB/code.o ${OUT}/PRTITION.o
+
+@
+<<PRTITION.NRLIB (NRLIB from MID)>>=
+${MID}/PRTITION.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PRTITION.spad
+ @ echo 0 making ${MID}/PRTITION.NRLIB from ${MID}/PRTITION.spad
+ @ (cd ${MID} ; echo ')co PRTITION.spad' | ${INTERPSYS} )
+
+@
+<<PRTITION.spad (SPAD from IN)>>=
+${MID}/PRTITION.spad: ${IN}/prtition.spad.pamphlet
+ @ echo 0 making ${MID}/PRTITION.spad from ${IN}/prtition.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRTITION.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PRTITION Partition" ${IN}/prtition.spad.pamphlet >PRTITION.spad )
+
+@
+<<prtition.spad.dvi (DOC from IN)>>=
+${DOC}/prtition.spad.dvi: ${IN}/prtition.spad.pamphlet
+ @ echo 0 making ${DOC}/prtition.spad.dvi from ${IN}/prtition.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/prtition.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} prtition.spad ; \
+ rm -f ${DOC}/prtition.spad.pamphlet ; \
+ rm -f ${DOC}/prtition.spad.tex ; \
+ rm -f ${DOC}/prtition.spad )
+
+@
+\subsection{pscat.spad \cite{1}}
+<<pscat.spad (SPAD from IN)>>=
+${MID}/pscat.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/pscat.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pscat.spad.pamphlet >pscat.spad )
+
+@
+<<MTSCAT.o (O from NRLIB)>>=
+${OUT}/MTSCAT.o: ${MID}/MTSCAT.NRLIB
+ @ echo 0 making ${OUT}/MTSCAT.o from ${MID}/MTSCAT.NRLIB
+ @ cp ${MID}/MTSCAT.NRLIB/code.o ${OUT}/MTSCAT.o
+
+@
+<<MTSCAT.NRLIB (NRLIB from MID)>>=
+${MID}/MTSCAT.NRLIB: ${MID}/MTSCAT.spad
+ @ echo 0 making ${MID}/MTSCAT.NRLIB from ${MID}/MTSCAT.spad
+ @ (cd ${MID} ; echo ')co MTSCAT.spad' | ${INTERPSYS} )
+
+@
+<<MTSCAT.spad (SPAD from IN)>>=
+${MID}/MTSCAT.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/MTSCAT.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MTSCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category MTSCAT MultivariateTaylorSeriesCategory" ${IN}/pscat.spad.pamphlet >MTSCAT.spad )
+
+@
+<<MTSCAT.o (BOOTSTRAP from MID)>>=
+${MID}/MTSCAT.o: ${MID}/MTSCAT.lsp
+ @ echo 0 making ${MID}/MTSCAT.o from ${MID}/MTSCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "MTSCAT.lsp" :output-file "MTSCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/MTSCAT.o ${OUT}/MTSCAT.o
+
+@
+<<MTSCAT.lsp (LISP from IN)>>=
+${MID}/MTSCAT.lsp: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/MTSCAT.lsp from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MTSCAT.NRLIB ; \
+ rm -rf ${OUT}/MTSCAT.o ; \
+ ${SPADBIN}/notangle -R"MTSCAT.lsp BOOTSTRAP" ${IN}/pscat.spad.pamphlet >MTSCAT.lsp )
+
+@
+<<PSCAT-.o (O from NRLIB)>>=
+${OUT}/PSCAT-.o: ${MID}/PSCAT.NRLIB
+ @ echo 0 making ${OUT}/PSCAT-.o from ${MID}/PSCAT-.NRLIB
+ @ cp ${MID}/PSCAT-.NRLIB/code.o ${OUT}/PSCAT-.o
+
+@
+<<PSCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/PSCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/PSCAT.spad
+ @ echo 0 making ${MID}/PSCAT-.NRLIB from ${MID}/PSCAT.spad
+ @ (cd ${MID} ; echo ')co PSCAT.spad' | ${INTERPSYS} )
+
+@
+<<PSCAT.o (O from NRLIB)>>=
+${OUT}/PSCAT.o: ${MID}/PSCAT.NRLIB
+ @ echo 0 making ${OUT}/PSCAT.o from ${MID}/PSCAT.NRLIB
+ @ cp ${MID}/PSCAT.NRLIB/code.o ${OUT}/PSCAT.o
+
+@
+<<PSCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PSCAT.NRLIB: ${MID}/PSCAT.spad
+ @ echo 0 making ${MID}/PSCAT.NRLIB from ${MID}/PSCAT.spad
+ @ (cd ${MID} ; echo ')co PSCAT.spad' | ${INTERPSYS} )
+
+@
+<<PSCAT.spad (SPAD from IN)>>=
+${MID}/PSCAT.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/PSCAT.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PSCAT PowerSeriesCategory" ${IN}/pscat.spad.pamphlet >PSCAT.spad )
+
+@
+<<ULSCAT.o (O from NRLIB)>>=
+${OUT}/ULSCAT.o: ${MID}/ULSCAT.NRLIB
+ @ echo 0 making ${OUT}/ULSCAT.o from ${MID}/ULSCAT.NRLIB
+ @ cp ${MID}/ULSCAT.NRLIB/code.o ${OUT}/ULSCAT.o
+
+@
+<<ULSCAT.NRLIB (NRLIB from MID)>>=
+${MID}/ULSCAT.NRLIB: ${MID}/ULSCAT.spad
+ @ echo 0 making ${MID}/ULSCAT.NRLIB from ${MID}/ULSCAT.spad
+ @ (cd ${MID} ; echo ')co ULSCAT.spad' | ${INTERPSYS} )
+
+@
+<<ULSCAT.spad (SPAD from IN)>>=
+${MID}/ULSCAT.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/ULSCAT.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ULSCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ULSCAT UnivariateLaurentSeriesCategory" ${IN}/pscat.spad.pamphlet >ULSCAT.spad )
+
+@
+<<ULSCAT.o (BOOTSTRAP from MID)>>=
+${MID}/ULSCAT.o: ${MID}/ULSCAT.lsp
+ @ echo 0 making ${MID}/ULSCAT.o from ${MID}/ULSCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ULSCAT.lsp" :output-file "ULSCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ULSCAT.o ${OUT}/ULSCAT.o
+
+@
+<<ULSCAT.lsp (LISP from IN)>>=
+${MID}/ULSCAT.lsp: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/ULSCAT.lsp from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ULSCAT.NRLIB ; \
+ rm -rf ${OUT}/ULSCAT.o ; \
+ ${SPADBIN}/notangle -R"ULSCAT.lsp BOOTSTRAP" ${IN}/pscat.spad.pamphlet >ULSCAT.lsp )
+
+@
+<<UPSCAT-.o (O from NRLIB)>>=
+${OUT}/UPSCAT-.o: ${MID}/UPSCAT.NRLIB
+ @ echo 0 making ${OUT}/UPSCAT-.o from ${MID}/UPSCAT-.NRLIB
+ @ cp ${MID}/UPSCAT-.NRLIB/code.o ${OUT}/UPSCAT-.o
+
+@
+<<UPSCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/UPSCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/UPSCAT.spad
+ @ echo 0 making ${MID}/UPSCAT-.NRLIB from ${MID}/UPSCAT.spad
+ @ (cd ${MID} ; echo ')co UPSCAT.spad' | ${INTERPSYS} )
+
+@
+<<UPSCAT.o (O from NRLIB)>>=
+${OUT}/UPSCAT.o: ${MID}/UPSCAT.NRLIB
+ @ echo 0 making ${OUT}/UPSCAT.o from ${MID}/UPSCAT.NRLIB
+ @ cp ${MID}/UPSCAT.NRLIB/code.o ${OUT}/UPSCAT.o
+
+@
+<<UPSCAT.NRLIB (NRLIB from MID)>>=
+${MID}/UPSCAT.NRLIB: ${MID}/UPSCAT.spad
+ @ echo 0 making ${MID}/UPSCAT.NRLIB from ${MID}/UPSCAT.spad
+ @ (cd ${MID} ; echo ')co UPSCAT.spad' | ${INTERPSYS} )
+
+@
+<<UPSCAT.spad (SPAD from IN)>>=
+${MID}/UPSCAT.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/UPSCAT.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPSCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category UPSCAT UnivariatePowerSeriesCategory" ${IN}/pscat.spad.pamphlet >UPSCAT.spad )
+
+@
+<<UPXSCAT.o (O from NRLIB)>>=
+${OUT}/UPXSCAT.o: ${MID}/UPXSCAT.NRLIB
+ @ echo 0 making ${OUT}/UPXSCAT.o from ${MID}/UPXSCAT.NRLIB
+ @ cp ${MID}/UPXSCAT.NRLIB/code.o ${OUT}/UPXSCAT.o
+
+@
+<<UPXSCAT.NRLIB (NRLIB from MID)>>=
+${MID}/UPXSCAT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UPXSCAT.spad
+ @ echo 0 making ${MID}/UPXSCAT.NRLIB from ${MID}/UPXSCAT.spad
+ @ (cd ${MID} ; echo ')co UPXSCAT.spad' | ${INTERPSYS} )
+
+@
+<<UPXSCAT.spad (SPAD from IN)>>=
+${MID}/UPXSCAT.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/UPXSCAT.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPXSCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category UPXSCAT UnivariatePuiseuxSeriesCategory" ${IN}/pscat.spad.pamphlet >UPXSCAT.spad )
+
+@
+<<UTSCAT-.o (O from NRLIB)>>=
+${OUT}/UTSCAT-.o: ${MID}/UTSCAT.NRLIB
+ @ echo 0 making ${OUT}/UTSCAT-.o from ${MID}/UTSCAT-.NRLIB
+ @ cp ${MID}/UTSCAT-.NRLIB/code.o ${OUT}/UTSCAT-.o
+
+@
+<<UTSCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/UTSCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/UTSCAT.spad
+ @ echo 0 making ${MID}/UTSCAT-.NRLIB from ${MID}/UTSCAT.spad
+ @ (cd ${MID} ; echo ')co UTSCAT.spad' | ${INTERPSYS} )
+
+@
+<<UTSCAT.o (O from NRLIB)>>=
+${OUT}/UTSCAT.o: ${MID}/UTSCAT.NRLIB
+ @ echo 0 making ${OUT}/UTSCAT.o from ${MID}/UTSCAT.NRLIB
+ @ cp ${MID}/UTSCAT.NRLIB/code.o ${OUT}/UTSCAT.o
+
+@
+<<UTSCAT.NRLIB (NRLIB from MID)>>=
+${MID}/UTSCAT.NRLIB: ${MID}/UTSCAT.spad
+ @ echo 0 making ${MID}/UTSCAT.NRLIB from ${MID}/UTSCAT.spad
+ @ (cd ${MID} ; echo ')co UTSCAT.spad' | ${INTERPSYS} )
+
+@
+<<UTSCAT.spad (SPAD from IN)>>=
+${MID}/UTSCAT.spad: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${MID}/UTSCAT.spad from ${IN}/pscat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UTSCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category UTSCAT UnivariateTaylorSeriesCategory" ${IN}/pscat.spad.pamphlet >UTSCAT.spad )
+
+@
+<<pscat.spad.dvi (DOC from IN)>>=
+${DOC}/pscat.spad.dvi: ${IN}/pscat.spad.pamphlet
+ @ echo 0 making ${DOC}/pscat.spad.dvi from ${IN}/pscat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pscat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pscat.spad ; \
+ rm -f ${DOC}/pscat.spad.pamphlet ; \
+ rm -f ${DOC}/pscat.spad.tex ; \
+ rm -f ${DOC}/pscat.spad )
+
+@
+\subsection{pseudolin.spad \cite{1}}
+<<pseudolin.spad (SPAD from IN)>>=
+${MID}/pseudolin.spad: ${IN}/pseudolin.spad.pamphlet
+ @ echo 0 making ${MID}/pseudolin.spad from ${IN}/pseudolin.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/pseudolin.spad.pamphlet >pseudolin.spad )
+
+@
+<<PSEUDLIN.o (O from NRLIB)>>=
+${OUT}/PSEUDLIN.o: ${MID}/PSEUDLIN.NRLIB
+ @ echo 0 making ${OUT}/PSEUDLIN.o from ${MID}/PSEUDLIN.NRLIB
+ @ cp ${MID}/PSEUDLIN.NRLIB/code.o ${OUT}/PSEUDLIN.o
+
+@
+<<PSEUDLIN.NRLIB (NRLIB from MID)>>=
+${MID}/PSEUDLIN.NRLIB: ${MID}/PSEUDLIN.spad
+ @ echo 0 making ${MID}/PSEUDLIN.NRLIB from ${MID}/PSEUDLIN.spad
+ @ (cd ${MID} ; echo ')co PSEUDLIN.spad' | ${INTERPSYS} )
+
+@
+<<PSEUDLIN.spad (SPAD from IN)>>=
+${MID}/PSEUDLIN.spad: ${IN}/pseudolin.spad.pamphlet
+ @ echo 0 making ${MID}/PSEUDLIN.spad from ${IN}/pseudolin.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSEUDLIN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PSEUDLIN PseudoLinearNormalForm" ${IN}/pseudolin.spad.pamphlet >PSEUDLIN.spad )
+
+@
+<<pseudolin.spad.dvi (DOC from IN)>>=
+${DOC}/pseudolin.spad.dvi: ${IN}/pseudolin.spad.pamphlet
+ @ echo 0 making ${DOC}/pseudolin.spad.dvi from ${IN}/pseudolin.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/pseudolin.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} pseudolin.spad ; \
+ rm -f ${DOC}/pseudolin.spad.pamphlet ; \
+ rm -f ${DOC}/pseudolin.spad.tex ; \
+ rm -f ${DOC}/pseudolin.spad )
+
+@
+\subsection{ptranfn.spad \cite{1}}
+<<ptranfn.spad (SPAD from IN)>>=
+${MID}/ptranfn.spad: ${IN}/ptranfn.spad.pamphlet
+ @ echo 0 making ${MID}/ptranfn.spad from ${IN}/ptranfn.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ptranfn.spad.pamphlet >ptranfn.spad )
+
+@
+<<PTRANFN.o (O from NRLIB)>>=
+${OUT}/PTRANFN.o: ${MID}/PTRANFN.NRLIB
+ @ echo 0 making ${OUT}/PTRANFN.o from ${MID}/PTRANFN.NRLIB
+ @ cp ${MID}/PTRANFN.NRLIB/code.o ${OUT}/PTRANFN.o
+
+@
+<<PTRANFN.NRLIB (NRLIB from MID)>>=
+${MID}/PTRANFN.NRLIB: ${MID}/PTRANFN.spad
+ @ echo 0 making ${MID}/PTRANFN.NRLIB from ${MID}/PTRANFN.spad
+ @ (cd ${MID} ; echo ')co PTRANFN.spad' | ${INTERPSYS} )
+
+@
+<<PTRANFN.spad (SPAD from IN)>>=
+${MID}/PTRANFN.spad: ${IN}/ptranfn.spad.pamphlet
+ @ echo 0 making ${MID}/PTRANFN.spad from ${IN}/ptranfn.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PTRANFN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PTRANFN PartialTranscendentalFunctions" ${IN}/ptranfn.spad.pamphlet >PTRANFN.spad )
+
+@
+<<ptranfn.spad.dvi (DOC from IN)>>=
+${DOC}/ptranfn.spad.dvi: ${IN}/ptranfn.spad.pamphlet
+ @ echo 0 making ${DOC}/ptranfn.spad.dvi from ${IN}/ptranfn.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ptranfn.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ptranfn.spad ; \
+ rm -f ${DOC}/ptranfn.spad.pamphlet ; \
+ rm -f ${DOC}/ptranfn.spad.tex ; \
+ rm -f ${DOC}/ptranfn.spad )
+
+@
+\subsection{puiseux.spad \cite{1}}
+<<puiseux.spad (SPAD from IN)>>=
+${MID}/puiseux.spad: ${IN}/puiseux.spad.pamphlet
+ @ echo 0 making ${MID}/puiseux.spad from ${IN}/puiseux.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/puiseux.spad.pamphlet >puiseux.spad )
+
+@
+<<UPXS.o (O from NRLIB)>>=
+${OUT}/UPXS.o: ${MID}/UPXS.NRLIB
+ @ echo 0 making ${OUT}/UPXS.o from ${MID}/UPXS.NRLIB
+ @ cp ${MID}/UPXS.NRLIB/code.o ${OUT}/UPXS.o
+
+@
+<<UPXS.NRLIB (NRLIB from MID)>>=
+${MID}/UPXS.NRLIB: ${MID}/UPXS.spad
+ @ echo 0 making ${MID}/UPXS.NRLIB from ${MID}/UPXS.spad
+ @ (cd ${MID} ; echo ')co UPXS.spad' | ${INTERPSYS} )
+
+@
+<<UPXS.spad (SPAD from IN)>>=
+${MID}/UPXS.spad: ${IN}/puiseux.spad.pamphlet
+ @ echo 0 making ${MID}/UPXS.spad from ${IN}/puiseux.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPXS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain UPXS UnivariatePuiseuxSeries" ${IN}/puiseux.spad.pamphlet >UPXS.spad )
+
+@
+<<UPXSCCA-.o (O from NRLIB)>>=
+${OUT}/UPXSCCA-.o: ${MID}/UPXSCCA.NRLIB
+ @ echo 0 making ${OUT}/UPXSCCA-.o from ${MID}/UPXSCCA-.NRLIB
+ @ cp ${MID}/UPXSCCA-.NRLIB/code.o ${OUT}/UPXSCCA-.o
+
+@
+<<UPXSCCA-.NRLIB (NRLIB from MID)>>=
+${MID}/UPXSCCA-.NRLIB: ${OUT}/TYPE.o ${MID}/UPXSCCA.spad
+ @ echo 0 making ${MID}/UPXSCCA-.NRLIB from ${MID}/UPXSCCA.spad
+ @ (cd ${MID} ; echo ')co UPXSCCA.spad' | ${INTERPSYS} )
+
+@
+<<UPXSCCA.o (O from NRLIB)>>=
+${OUT}/UPXSCCA.o: ${MID}/UPXSCCA.NRLIB
+ @ echo 0 making ${OUT}/UPXSCCA.o from ${MID}/UPXSCCA.NRLIB
+ @ cp ${MID}/UPXSCCA.NRLIB/code.o ${OUT}/UPXSCCA.o
+
+@
+<<UPXSCCA.NRLIB (NRLIB from MID)>>=
+${MID}/UPXSCCA.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UPXSCCA.spad
+ @ echo 0 making ${MID}/UPXSCCA.NRLIB from ${MID}/UPXSCCA.spad
+ @ (cd ${MID} ; echo ')co UPXSCCA.spad' | ${INTERPSYS} )
+
+@
+<<UPXSCCA.spad (SPAD from IN)>>=
+${MID}/UPXSCCA.spad: ${IN}/puiseux.spad.pamphlet
+ @ echo 0 making ${MID}/UPXSCCA.spad from ${IN}/puiseux.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPXSCCA.NRLIB ; \
+ ${SPADBIN}/notangle -R"category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory" ${IN}/puiseux.spad.pamphlet >UPXSCCA.spad )
+
+@
+<<UPXSCONS.o (O from NRLIB)>>=
+${OUT}/UPXSCONS.o: ${MID}/UPXSCONS.NRLIB
+ @ echo 0 making ${OUT}/UPXSCONS.o from ${MID}/UPXSCONS.NRLIB
+ @ cp ${MID}/UPXSCONS.NRLIB/code.o ${OUT}/UPXSCONS.o
+
+@
+<<UPXSCONS.NRLIB (NRLIB from MID)>>=
+${MID}/UPXSCONS.NRLIB: ${MID}/UPXSCONS.spad
+ @ echo 0 making ${MID}/UPXSCONS.NRLIB from ${MID}/UPXSCONS.spad
+ @ (cd ${MID} ; echo ')co UPXSCONS.spad' | ${INTERPSYS} )
+
+@
+<<UPXSCONS.spad (SPAD from IN)>>=
+${MID}/UPXSCONS.spad: ${IN}/puiseux.spad.pamphlet
+ @ echo 0 making ${MID}/UPXSCONS.spad from ${IN}/puiseux.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPXSCONS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain UPXSCONS UnivariatePuiseuxSeriesConstructor" ${IN}/puiseux.spad.pamphlet >UPXSCONS.spad )
+
+@
+<<UPXS2.o (O from NRLIB)>>=
+${OUT}/UPXS2.o: ${MID}/UPXS2.NRLIB
+ @ echo 0 making ${OUT}/UPXS2.o from ${MID}/UPXS2.NRLIB
+ @ cp ${MID}/UPXS2.NRLIB/code.o ${OUT}/UPXS2.o
+
+@
+<<UPXS2.NRLIB (NRLIB from MID)>>=
+${MID}/UPXS2.NRLIB: ${MID}/UPXS2.spad
+ @ echo 0 making ${MID}/UPXS2.NRLIB from ${MID}/UPXS2.spad
+ @ (cd ${MID} ; echo ')co UPXS2.spad' | ${INTERPSYS} )
+
+@
+<<UPXS2.spad (SPAD from IN)>>=
+${MID}/UPXS2.spad: ${IN}/puiseux.spad.pamphlet
+ @ echo 0 making ${MID}/UPXS2.spad from ${IN}/puiseux.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPXS2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPXS2 UnivariatePuiseuxSeriesFunctions2" ${IN}/puiseux.spad.pamphlet >UPXS2.spad )
+
+@
+<<puiseux.spad.dvi (DOC from IN)>>=
+${DOC}/puiseux.spad.dvi: ${IN}/puiseux.spad.pamphlet
+ @ echo 0 making ${DOC}/puiseux.spad.dvi from ${IN}/puiseux.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/puiseux.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} puiseux.spad ; \
+ rm -f ${DOC}/puiseux.spad.pamphlet ; \
+ rm -f ${DOC}/puiseux.spad.tex ; \
+ rm -f ${DOC}/puiseux.spad )
+
+@
+\subsection{qalgset.spad \cite{1}}
+<<qalgset.spad (SPAD from IN)>>=
+${MID}/qalgset.spad: ${IN}/qalgset.spad.pamphlet
+ @ echo 0 making ${MID}/qalgset.spad from ${IN}/qalgset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/qalgset.spad.pamphlet >qalgset.spad )
+
+@
+<<QALGSET.o (O from NRLIB)>>=
+${OUT}/QALGSET.o: ${MID}/QALGSET.NRLIB
+ @ echo 0 making ${OUT}/QALGSET.o from ${MID}/QALGSET.NRLIB
+ @ cp ${MID}/QALGSET.NRLIB/code.o ${OUT}/QALGSET.o
+
+@
+<<QALGSET.NRLIB (NRLIB from MID)>>=
+${MID}/QALGSET.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/QALGSET.spad
+ @ echo 0 making ${MID}/QALGSET.NRLIB from ${MID}/QALGSET.spad
+ @ (cd ${MID} ; echo ')co QALGSET.spad' | ${INTERPSYS} )
+
+@
+<<QALGSET.spad (SPAD from IN)>>=
+${MID}/QALGSET.spad: ${IN}/qalgset.spad.pamphlet
+ @ echo 0 making ${MID}/QALGSET.spad from ${IN}/qalgset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QALGSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain QALGSET QuasiAlgebraicSet" ${IN}/qalgset.spad.pamphlet >QALGSET.spad )
+
+@
+<<QALGSET2.o (O from NRLIB)>>=
+${OUT}/QALGSET2.o: ${MID}/QALGSET2.NRLIB
+ @ echo 0 making ${OUT}/QALGSET2.o from ${MID}/QALGSET2.NRLIB
+ @ cp ${MID}/QALGSET2.NRLIB/code.o ${OUT}/QALGSET2.o
+
+@
+<<QALGSET2.NRLIB (NRLIB from MID)>>=
+${MID}/QALGSET2.NRLIB: ${MID}/QALGSET2.spad
+ @ echo 0 making ${MID}/QALGSET2.NRLIB from ${MID}/QALGSET2.spad
+ @ (cd ${MID} ; echo ')co QALGSET2.spad' | ${INTERPSYS} )
+
+@
+<<QALGSET2.spad (SPAD from IN)>>=
+${MID}/QALGSET2.spad: ${IN}/qalgset.spad.pamphlet
+ @ echo 0 making ${MID}/QALGSET2.spad from ${IN}/qalgset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QALGSET2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package QALGSET2 QuasiAlgebraicSet2" ${IN}/qalgset.spad.pamphlet >QALGSET2.spad )
+
+@
+<<qalgset.spad.dvi (DOC from IN)>>=
+${DOC}/qalgset.spad.dvi: ${IN}/qalgset.spad.pamphlet
+ @ echo 0 making ${DOC}/qalgset.spad.dvi from ${IN}/qalgset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/qalgset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} qalgset.spad ; \
+ rm -f ${DOC}/qalgset.spad.pamphlet ; \
+ rm -f ${DOC}/qalgset.spad.tex ; \
+ rm -f ${DOC}/qalgset.spad )
+
+@
+\subsection{quat.spad \cite{1}}
+<<quat.spad (SPAD from IN)>>=
+${MID}/quat.spad: ${IN}/quat.spad.pamphlet
+ @ echo 0 making ${MID}/quat.spad from ${IN}/quat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/quat.spad.pamphlet >quat.spad )
+
+@
+<<QUAT.o (O from NRLIB)>>=
+${OUT}/QUAT.o: ${MID}/QUAT.NRLIB
+ @ echo 0 making ${OUT}/QUAT.o from ${MID}/QUAT.NRLIB
+ @ cp ${MID}/QUAT.NRLIB/code.o ${OUT}/QUAT.o
+
+@
+<<QUAT.NRLIB (NRLIB from MID)>>=
+${MID}/QUAT.NRLIB: ${MID}/QUAT.spad
+ @ echo 0 making ${MID}/QUAT.NRLIB from ${MID}/QUAT.spad
+ @ (cd ${MID} ; echo ')co QUAT.spad' | ${INTERPSYS} )
+
+@
+<<QUAT.spad (SPAD from IN)>>=
+${MID}/QUAT.spad: ${IN}/quat.spad.pamphlet
+ @ echo 0 making ${MID}/QUAT.spad from ${IN}/quat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QUAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain QUAT Quaternion" ${IN}/quat.spad.pamphlet >QUAT.spad )
+
+@
+<<QUATCAT-.o (O from NRLIB)>>=
+${OUT}/QUATCAT-.o: ${MID}/QUATCAT.NRLIB
+ @ echo 0 making ${OUT}/QUATCAT-.o from ${MID}/QUATCAT-.NRLIB
+ @ cp ${MID}/QUATCAT-.NRLIB/code.o ${OUT}/QUATCAT-.o
+
+@
+<<QUATCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/QUATCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/QUATCAT.spad
+ @ echo 0 making ${MID}/QUATCAT-.NRLIB from ${MID}/QUATCAT.spad
+ @ (cd ${MID} ; echo ')co QUATCAT.spad' | ${INTERPSYS} )
+
+@
+<<QUATCAT.o (O from NRLIB)>>=
+${OUT}/QUATCAT.o: ${MID}/QUATCAT.NRLIB
+ @ echo 0 making ${OUT}/QUATCAT.o from ${MID}/QUATCAT.NRLIB
+ @ cp ${MID}/QUATCAT.NRLIB/code.o ${OUT}/QUATCAT.o
+
+@
+<<QUATCAT.NRLIB (NRLIB from MID)>>=
+${MID}/QUATCAT.NRLIB: ${MID}/QUATCAT.spad
+ @ echo 0 making ${MID}/QUATCAT.NRLIB from ${MID}/QUATCAT.spad
+ @ (cd ${MID} ; echo ')co QUATCAT.spad' | ${INTERPSYS} )
+
+@
+<<QUATCAT.spad (SPAD from IN)>>=
+${MID}/QUATCAT.spad: ${IN}/quat.spad.pamphlet
+ @ echo 0 making ${MID}/QUATCAT.spad from ${IN}/quat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QUATCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category QUATCAT QuaternionCategory" ${IN}/quat.spad.pamphlet >QUATCAT.spad )
+
+@
+<<QUATCT2.o (O from NRLIB)>>=
+${OUT}/QUATCT2.o: ${MID}/QUATCT2.NRLIB
+ @ echo 0 making ${OUT}/QUATCT2.o from ${MID}/QUATCT2.NRLIB
+ @ cp ${MID}/QUATCT2.NRLIB/code.o ${OUT}/QUATCT2.o
+
+@
+<<QUATCT2.NRLIB (NRLIB from MID)>>=
+${MID}/QUATCT2.NRLIB: ${MID}/QUATCT2.spad
+ @ echo 0 making ${MID}/QUATCT2.NRLIB from ${MID}/QUATCT2.spad
+ @ (cd ${MID} ; echo ')co QUATCT2.spad' | ${INTERPSYS} )
+
+@
+<<QUATCT2.spad (SPAD from IN)>>=
+${MID}/QUATCT2.spad: ${IN}/quat.spad.pamphlet
+ @ echo 0 making ${MID}/QUATCT2.spad from ${IN}/quat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf QUATCT2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package QUATCT2 QuaternionCategoryFunctions2" ${IN}/quat.spad.pamphlet >QUATCT2.spad )
+
+@
+<<quat.spad.dvi (DOC from IN)>>=
+${DOC}/quat.spad.dvi: ${IN}/quat.spad.pamphlet
+ @ echo 0 making ${DOC}/quat.spad.dvi from ${IN}/quat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/quat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} quat.spad ; \
+ rm -f ${DOC}/quat.spad.pamphlet ; \
+ rm -f ${DOC}/quat.spad.tex ; \
+ rm -f ${DOC}/quat.spad )
+
+@
+\subsection{radeigen.spad \cite{1}}
+<<radeigen.spad (SPAD from IN)>>=
+${MID}/radeigen.spad: ${IN}/radeigen.spad.pamphlet
+ @ echo 0 making ${MID}/radeigen.spad from ${IN}/radeigen.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/radeigen.spad.pamphlet >radeigen.spad )
+
+@
+<<REP.o (O from NRLIB)>>=
+${OUT}/REP.o: ${MID}/REP.NRLIB
+ @ echo 0 making ${OUT}/REP.o from ${MID}/REP.NRLIB
+ @ cp ${MID}/REP.NRLIB/code.o ${OUT}/REP.o
+
+@
+<<REP.NRLIB (NRLIB from MID)>>=
+${MID}/REP.NRLIB: ${MID}/REP.spad
+ @ echo 0 making ${MID}/REP.NRLIB from ${MID}/REP.spad
+ @ (cd ${MID} ; echo ')co REP.spad' | ${INTERPSYS} )
+
+@
+<<REP.spad (SPAD from IN)>>=
+${MID}/REP.spad: ${IN}/radeigen.spad.pamphlet
+ @ echo 0 making ${MID}/REP.spad from ${IN}/radeigen.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REP RadicalEigenPackage" ${IN}/radeigen.spad.pamphlet >REP.spad )
+
+@
+<<radeigen.spad.dvi (DOC from IN)>>=
+${DOC}/radeigen.spad.dvi: ${IN}/radeigen.spad.pamphlet
+ @ echo 0 making ${DOC}/radeigen.spad.dvi from ${IN}/radeigen.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/radeigen.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} radeigen.spad ; \
+ rm -f ${DOC}/radeigen.spad.pamphlet ; \
+ rm -f ${DOC}/radeigen.spad.tex ; \
+ rm -f ${DOC}/radeigen.spad )
+
+@
+\subsection{radix.spad \cite{1}}
+<<radix.spad (SPAD from IN)>>=
+${MID}/radix.spad: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${MID}/radix.spad from ${IN}/radix.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/radix.spad.pamphlet >radix.spad )
+
+@
+<<BINARY.o (O from NRLIB)>>=
+${OUT}/BINARY.o: ${MID}/BINARY.NRLIB
+ @ echo 0 making ${OUT}/BINARY.o from ${MID}/BINARY.NRLIB
+ @ cp ${MID}/BINARY.NRLIB/code.o ${OUT}/BINARY.o
+
+@
+<<BINARY.NRLIB (NRLIB from MID)>>=
+${MID}/BINARY.NRLIB: ${MID}/BINARY.spad
+ @ echo 0 making ${MID}/BINARY.NRLIB from ${MID}/BINARY.spad
+ @ (cd ${MID} ; echo ')co BINARY.spad' | ${INTERPSYS} )
+
+@
+<<BINARY.spad (SPAD from IN)>>=
+${MID}/BINARY.spad: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${MID}/BINARY.spad from ${IN}/radix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BINARY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BINARY BinaryExpansion" ${IN}/radix.spad.pamphlet >BINARY.spad )
+
+@
+<<DECIMAL.o (O from NRLIB)>>=
+${OUT}/DECIMAL.o: ${MID}/DECIMAL.NRLIB
+ @ echo 0 making ${OUT}/DECIMAL.o from ${MID}/DECIMAL.NRLIB
+ @ cp ${MID}/DECIMAL.NRLIB/code.o ${OUT}/DECIMAL.o
+
+@
+<<DECIMAL.NRLIB (NRLIB from MID)>>=
+${MID}/DECIMAL.NRLIB: ${MID}/DECIMAL.spad
+ @ echo 0 making ${MID}/DECIMAL.NRLIB from ${MID}/DECIMAL.spad
+ @ (cd ${MID} ; echo ')co DECIMAL.spad' | ${INTERPSYS} )
+
+@
+<<DECIMAL.spad (SPAD from IN)>>=
+${MID}/DECIMAL.spad: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${MID}/DECIMAL.spad from ${IN}/radix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DECIMAL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DECIMAL DecimalExpansion" ${IN}/radix.spad.pamphlet >DECIMAL.spad )
+
+@
+<<HEXADEC.o (O from NRLIB)>>=
+${OUT}/HEXADEC.o: ${MID}/HEXADEC.NRLIB
+ @ echo 0 making ${OUT}/HEXADEC.o from ${MID}/HEXADEC.NRLIB
+ @ cp ${MID}/HEXADEC.NRLIB/code.o ${OUT}/HEXADEC.o
+
+@
+<<HEXADEC.NRLIB (NRLIB from MID)>>=
+${MID}/HEXADEC.NRLIB: ${MID}/HEXADEC.spad
+ @ echo 0 making ${MID}/HEXADEC.NRLIB from ${MID}/HEXADEC.spad
+ @ (cd ${MID} ; echo ')co HEXADEC.spad' | ${INTERPSYS} )
+
+@
+<<HEXADEC.spad (SPAD from IN)>>=
+${MID}/HEXADEC.spad: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${MID}/HEXADEC.spad from ${IN}/radix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HEXADEC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HEXADEC HexadecimalExpansion" ${IN}/radix.spad.pamphlet >HEXADEC.spad )
+
+@
+<<RADIX.o (O from NRLIB)>>=
+${OUT}/RADIX.o: ${MID}/RADIX.NRLIB
+ @ echo 0 making ${OUT}/RADIX.o from ${MID}/RADIX.NRLIB
+ @ cp ${MID}/RADIX.NRLIB/code.o ${OUT}/RADIX.o
+
+@
+<<RADIX.NRLIB (NRLIB from MID)>>=
+${MID}/RADIX.NRLIB: ${MID}/RADIX.spad
+ @ echo 0 making ${MID}/RADIX.NRLIB from ${MID}/RADIX.spad
+ @ (cd ${MID} ; echo ')co RADIX.spad' | ${INTERPSYS} )
+
+@
+<<RADIX.spad (SPAD from IN)>>=
+${MID}/RADIX.spad: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${MID}/RADIX.spad from ${IN}/radix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RADIX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RADIX RadixExpansion" ${IN}/radix.spad.pamphlet >RADIX.spad )
+
+@
+<<RADUTIL.o (O from NRLIB)>>=
+${OUT}/RADUTIL.o: ${MID}/RADUTIL.NRLIB
+ @ echo 0 making ${OUT}/RADUTIL.o from ${MID}/RADUTIL.NRLIB
+ @ cp ${MID}/RADUTIL.NRLIB/code.o ${OUT}/RADUTIL.o
+
+@
+<<RADUTIL.NRLIB (NRLIB from MID)>>=
+${MID}/RADUTIL.NRLIB: ${MID}/RADUTIL.spad
+ @ echo 0 making ${MID}/RADUTIL.NRLIB from ${MID}/RADUTIL.spad
+ @ (cd ${MID} ; echo ')co RADUTIL.spad' | ${INTERPSYS} )
+
+@
+<<RADUTIL.spad (SPAD from IN)>>=
+${MID}/RADUTIL.spad: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${MID}/RADUTIL.spad from ${IN}/radix.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RADUTIL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RADUTIL RadixUtilities" ${IN}/radix.spad.pamphlet >RADUTIL.spad )
+
+@
+<<radix.spad.dvi (DOC from IN)>>=
+${DOC}/radix.spad.dvi: ${IN}/radix.spad.pamphlet
+ @ echo 0 making ${DOC}/radix.spad.dvi from ${IN}/radix.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/radix.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} radix.spad ; \
+ rm -f ${DOC}/radix.spad.pamphlet ; \
+ rm -f ${DOC}/radix.spad.tex ; \
+ rm -f ${DOC}/radix.spad )
+
+@
+\subsection{random.spad \cite{1}}
+<<random.spad (SPAD from IN)>>=
+${MID}/random.spad: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${MID}/random.spad from ${IN}/random.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/random.spad.pamphlet >random.spad )
+
+@
+<<INTBIT.o (O from NRLIB)>>=
+${OUT}/INTBIT.o: ${MID}/INTBIT.NRLIB
+ @ echo 0 making ${OUT}/INTBIT.o from ${MID}/INTBIT.NRLIB
+ @ cp ${MID}/INTBIT.NRLIB/code.o ${OUT}/INTBIT.o
+
+@
+<<INTBIT.NRLIB (NRLIB from MID)>>=
+${MID}/INTBIT.NRLIB: ${MID}/INTBIT.spad
+ @ echo 0 making ${MID}/INTBIT.NRLIB from ${MID}/INTBIT.spad
+ @ (cd ${MID} ; echo ')co INTBIT.spad' | ${INTERPSYS} )
+
+@
+<<INTBIT.spad (SPAD from IN)>>=
+${MID}/INTBIT.spad: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${MID}/INTBIT.spad from ${IN}/random.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTBIT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTBIT IntegerBits" ${IN}/random.spad.pamphlet >INTBIT.spad )
+
+@
+<<RANDSRC.o (O from NRLIB)>>=
+${OUT}/RANDSRC.o: ${MID}/RANDSRC.NRLIB
+ @ echo 0 making ${OUT}/RANDSRC.o from ${MID}/RANDSRC.NRLIB
+ @ cp ${MID}/RANDSRC.NRLIB/code.o ${OUT}/RANDSRC.o
+
+@
+<<RANDSRC.NRLIB (NRLIB from MID)>>=
+${MID}/RANDSRC.NRLIB: ${MID}/RANDSRC.spad
+ @ echo 0 making ${MID}/RANDSRC.NRLIB from ${MID}/RANDSRC.spad
+ @ (cd ${MID} ; echo ')co RANDSRC.spad' | ${INTERPSYS} )
+
+@
+<<RANDSRC.spad (SPAD from IN)>>=
+${MID}/RANDSRC.spad: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${MID}/RANDSRC.spad from ${IN}/random.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RANDSRC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RANDSRC RandomNumberSource" ${IN}/random.spad.pamphlet >RANDSRC.spad )
+
+@
+<<RDIST.o (O from NRLIB)>>=
+${OUT}/RDIST.o: ${MID}/RDIST.NRLIB
+ @ echo 0 making ${OUT}/RDIST.o from ${MID}/RDIST.NRLIB
+ @ cp ${MID}/RDIST.NRLIB/code.o ${OUT}/RDIST.o
+
+@
+<<RDIST.NRLIB (NRLIB from MID)>>=
+${MID}/RDIST.NRLIB: ${MID}/RDIST.spad
+ @ echo 0 making ${MID}/RDIST.NRLIB from ${MID}/RDIST.spad
+ @ (cd ${MID} ; echo ')co RDIST.spad' | ${INTERPSYS} )
+
+@
+<<RDIST.spad (SPAD from IN)>>=
+${MID}/RDIST.spad: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${MID}/RDIST.spad from ${IN}/random.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RDIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RDIST RandomDistributions" ${IN}/random.spad.pamphlet >RDIST.spad )
+
+@
+<<RFDIST.o (O from NRLIB)>>=
+${OUT}/RFDIST.o: ${MID}/RFDIST.NRLIB
+ @ echo 0 making ${OUT}/RFDIST.o from ${MID}/RFDIST.NRLIB
+ @ cp ${MID}/RFDIST.NRLIB/code.o ${OUT}/RFDIST.o
+
+@
+<<RFDIST.NRLIB (NRLIB from MID)>>=
+${MID}/RFDIST.NRLIB: ${MID}/RFDIST.spad
+ @ echo 0 making ${MID}/RFDIST.NRLIB from ${MID}/RFDIST.spad
+ @ (cd ${MID} ; echo ')co RFDIST.spad' | ${INTERPSYS} )
+
+@
+<<RFDIST.spad (SPAD from IN)>>=
+${MID}/RFDIST.spad: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${MID}/RFDIST.spad from ${IN}/random.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RFDIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RFDIST RandomFloatDistributions" ${IN}/random.spad.pamphlet >RFDIST.spad )
+
+@
+<<RIDIST.o (O from NRLIB)>>=
+${OUT}/RIDIST.o: ${MID}/RIDIST.NRLIB
+ @ echo 0 making ${OUT}/RIDIST.o from ${MID}/RIDIST.NRLIB
+ @ cp ${MID}/RIDIST.NRLIB/code.o ${OUT}/RIDIST.o
+
+@
+<<RIDIST.NRLIB (NRLIB from MID)>>=
+${MID}/RIDIST.NRLIB: ${MID}/RIDIST.spad
+ @ echo 0 making ${MID}/RIDIST.NRLIB from ${MID}/RIDIST.spad
+ @ (cd ${MID} ; echo ')co RIDIST.spad' | ${INTERPSYS} )
+
+@
+<<RIDIST.spad (SPAD from IN)>>=
+${MID}/RIDIST.spad: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${MID}/RIDIST.spad from ${IN}/random.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RIDIST.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RIDIST RandomIntegerDistributions" ${IN}/random.spad.pamphlet >RIDIST.spad )
+
+@
+<<random.spad.dvi (DOC from IN)>>=
+${DOC}/random.spad.dvi: ${IN}/random.spad.pamphlet
+ @ echo 0 making ${DOC}/random.spad.dvi from ${IN}/random.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/random.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} random.spad ; \
+ rm -f ${DOC}/random.spad.pamphlet ; \
+ rm -f ${DOC}/random.spad.tex ; \
+ rm -f ${DOC}/random.spad )
+
+@
+\subsection{ratfact.spad \cite{1}}
+<<ratfact.spad (SPAD from IN)>>=
+${MID}/ratfact.spad: ${IN}/ratfact.spad.pamphlet
+ @ echo 0 making ${MID}/ratfact.spad from ${IN}/ratfact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ratfact.spad.pamphlet >ratfact.spad )
+
+@
+<<RATFACT.o (O from NRLIB)>>=
+${OUT}/RATFACT.o: ${MID}/RATFACT.NRLIB
+ @ echo 0 making ${OUT}/RATFACT.o from ${MID}/RATFACT.NRLIB
+ @ cp ${MID}/RATFACT.NRLIB/code.o ${OUT}/RATFACT.o
+
+@
+<<RATFACT.NRLIB (NRLIB from MID)>>=
+${MID}/RATFACT.NRLIB: ${MID}/RATFACT.spad
+ @ echo 0 making ${MID}/RATFACT.NRLIB from ${MID}/RATFACT.spad
+ @ (cd ${MID} ; echo ')co RATFACT.spad' | ${INTERPSYS} )
+
+@
+<<RATFACT.spad (SPAD from IN)>>=
+${MID}/RATFACT.spad: ${IN}/ratfact.spad.pamphlet
+ @ echo 0 making ${MID}/RATFACT.spad from ${IN}/ratfact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RATFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RATFACT RationalFactorize" ${IN}/ratfact.spad.pamphlet >RATFACT.spad )
+
+@
+<<ratfact.spad.dvi (DOC from IN)>>=
+${DOC}/ratfact.spad.dvi: ${IN}/ratfact.spad.pamphlet
+ @ echo 0 making ${DOC}/ratfact.spad.dvi from ${IN}/ratfact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ratfact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ratfact.spad ; \
+ rm -f ${DOC}/ratfact.spad.pamphlet ; \
+ rm -f ${DOC}/ratfact.spad.tex ; \
+ rm -f ${DOC}/ratfact.spad )
+
+@
+\subsection{rdeef.spad \cite{1}}
+<<rdeef.spad (SPAD from IN)>>=
+${MID}/rdeef.spad: ${IN}/rdeef.spad.pamphlet
+ @ echo 0 making ${MID}/rdeef.spad from ${IN}/rdeef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rdeef.spad.pamphlet >rdeef.spad )
+
+@
+<<INTTOOLS.o (O from NRLIB)>>=
+${OUT}/INTTOOLS.o: ${MID}/INTTOOLS.NRLIB
+ @ echo 0 making ${OUT}/INTTOOLS.o from ${MID}/INTTOOLS.NRLIB
+ @ cp ${MID}/INTTOOLS.NRLIB/code.o ${OUT}/INTTOOLS.o
+
+@
+<<INTTOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/INTTOOLS.NRLIB: ${MID}/INTTOOLS.spad
+ @ echo 0 making ${MID}/INTTOOLS.NRLIB from ${MID}/INTTOOLS.spad
+ @ (cd ${MID} ; echo ')co INTTOOLS.spad' | ${INTERPSYS} )
+
+@
+<<INTTOOLS.spad (SPAD from IN)>>=
+${MID}/INTTOOLS.spad: ${IN}/rdeef.spad.pamphlet
+ @ echo 0 making ${MID}/INTTOOLS.spad from ${IN}/rdeef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTTOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTTOOLS IntegrationTools" ${IN}/rdeef.spad.pamphlet >INTTOOLS.spad )
+
+@
+<<RDEEF.o (O from NRLIB)>>=
+${OUT}/RDEEF.o: ${MID}/RDEEF.NRLIB
+ @ echo 0 making ${OUT}/RDEEF.o from ${MID}/RDEEF.NRLIB
+ @ cp ${MID}/RDEEF.NRLIB/code.o ${OUT}/RDEEF.o
+
+@
+<<RDEEF.NRLIB (NRLIB from MID)>>=
+${MID}/RDEEF.NRLIB: ${MID}/RDEEF.spad
+ @ echo 0 making ${MID}/RDEEF.NRLIB from ${MID}/RDEEF.spad
+ @ (cd ${MID} ; echo ')co RDEEF.spad' | ${INTERPSYS} )
+
+@
+<<RDEEF.spad (SPAD from IN)>>=
+${MID}/RDEEF.spad: ${IN}/rdeef.spad.pamphlet
+ @ echo 0 making ${MID}/RDEEF.spad from ${IN}/rdeef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RDEEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RDEEF ElementaryRischDE" ${IN}/rdeef.spad.pamphlet >RDEEF.spad )
+
+@
+<<rdeef.spad.dvi (DOC from IN)>>=
+${DOC}/rdeef.spad.dvi: ${IN}/rdeef.spad.pamphlet
+ @ echo 0 making ${DOC}/rdeef.spad.dvi from ${IN}/rdeef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rdeef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rdeef.spad ; \
+ rm -f ${DOC}/rdeef.spad.pamphlet ; \
+ rm -f ${DOC}/rdeef.spad.tex ; \
+ rm -f ${DOC}/rdeef.spad )
+
+@
+\subsection{rderf.spad \cite{1}}
+<<rderf.spad (SPAD from IN)>>=
+${MID}/rderf.spad: ${IN}/rderf.spad.pamphlet
+ @ echo 0 making ${MID}/rderf.spad from ${IN}/rderf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rderf.spad.pamphlet >rderf.spad )
+
+@
+<<RDETR.o (O from NRLIB)>>=
+${OUT}/RDETR.o: ${MID}/RDETR.NRLIB
+ @ echo 0 making ${OUT}/RDETR.o from ${MID}/RDETR.NRLIB
+ @ cp ${MID}/RDETR.NRLIB/code.o ${OUT}/RDETR.o
+
+@
+<<RDETR.NRLIB (NRLIB from MID)>>=
+${MID}/RDETR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/RDETR.spad
+ @ echo 0 making ${MID}/RDETR.NRLIB from ${MID}/RDETR.spad
+ @ (cd ${MID} ; echo ')co RDETR.spad' | ${INTERPSYS} )
+
+@
+<<RDETR.spad (SPAD from IN)>>=
+${MID}/RDETR.spad: ${IN}/rderf.spad.pamphlet
+ @ echo 0 making ${MID}/RDETR.spad from ${IN}/rderf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RDETR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RDETR TranscendentalRischDE" ${IN}/rderf.spad.pamphlet >RDETR.spad )
+
+@
+<<rderf.spad.dvi (DOC from IN)>>=
+${DOC}/rderf.spad.dvi: ${IN}/rderf.spad.pamphlet
+ @ echo 0 making ${DOC}/rderf.spad.dvi from ${IN}/rderf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rderf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rderf.spad ; \
+ rm -f ${DOC}/rderf.spad.pamphlet ; \
+ rm -f ${DOC}/rderf.spad.tex ; \
+ rm -f ${DOC}/rderf.spad )
+
+@
+\subsection{rdesys.spad \cite{1}}
+<<rdesys.spad (SPAD from IN)>>=
+${MID}/rdesys.spad: ${IN}/rdesys.spad.pamphlet
+ @ echo 0 making ${MID}/rdesys.spad from ${IN}/rdesys.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rdesys.spad.pamphlet >rdesys.spad )
+
+@
+<<RDEEFS.o (O from NRLIB)>>=
+${OUT}/RDEEFS.o: ${MID}/RDEEFS.NRLIB
+ @ echo 0 making ${OUT}/RDEEFS.o from ${MID}/RDEEFS.NRLIB
+ @ cp ${MID}/RDEEFS.NRLIB/code.o ${OUT}/RDEEFS.o
+
+@
+<<RDEEFS.NRLIB (NRLIB from MID)>>=
+${MID}/RDEEFS.NRLIB: ${MID}/RDEEFS.spad
+ @ echo 0 making ${MID}/RDEEFS.NRLIB from ${MID}/RDEEFS.spad
+ @ (cd ${MID} ; echo ')co RDEEFS.spad' | ${INTERPSYS} )
+
+@
+<<RDEEFS.spad (SPAD from IN)>>=
+${MID}/RDEEFS.spad: ${IN}/rdesys.spad.pamphlet
+ @ echo 0 making ${MID}/RDEEFS.spad from ${IN}/rdesys.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RDEEFS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RDEEFS ElementaryRischDESystem" ${IN}/rdesys.spad.pamphlet >RDEEFS.spad )
+
+@
+<<RDETRS.o (O from NRLIB)>>=
+${OUT}/RDETRS.o: ${MID}/RDETRS.NRLIB
+ @ echo 0 making ${OUT}/RDETRS.o from ${MID}/RDETRS.NRLIB
+ @ cp ${MID}/RDETRS.NRLIB/code.o ${OUT}/RDETRS.o
+
+@
+<<RDETRS.NRLIB (NRLIB from MID)>>=
+${MID}/RDETRS.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/RDETRS.spad
+ @ echo 0 making ${MID}/RDETRS.NRLIB from ${MID}/RDETRS.spad
+ @ (cd ${MID} ; echo ')co RDETRS.spad' | ${INTERPSYS} )
+
+@
+<<RDETRS.spad (SPAD from IN)>>=
+${MID}/RDETRS.spad: ${IN}/rdesys.spad.pamphlet
+ @ echo 0 making ${MID}/RDETRS.spad from ${IN}/rdesys.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RDETRS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RDETRS TranscendentalRischDESystem" ${IN}/rdesys.spad.pamphlet >RDETRS.spad )
+
+@
+<<rdesys.spad.dvi (DOC from IN)>>=
+${DOC}/rdesys.spad.dvi: ${IN}/rdesys.spad.pamphlet
+ @ echo 0 making ${DOC}/rdesys.spad.dvi from ${IN}/rdesys.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rdesys.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rdesys.spad ; \
+ rm -f ${DOC}/rdesys.spad.pamphlet ; \
+ rm -f ${DOC}/rdesys.spad.tex ; \
+ rm -f ${DOC}/rdesys.spad )
+
+@
+\subsection{real0q.spad \cite{1}}
+<<real0q.spad (SPAD from IN)>>=
+${MID}/real0q.spad: ${IN}/real0q.spad.pamphlet
+ @ echo 0 making ${MID}/real0q.spad from ${IN}/real0q.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/real0q.spad.pamphlet >real0q.spad )
+
+@
+<<REAL0Q.o (O from NRLIB)>>=
+${OUT}/REAL0Q.o: ${MID}/REAL0Q.NRLIB
+ @ echo 0 making ${OUT}/REAL0Q.o from ${MID}/REAL0Q.NRLIB
+ @ cp ${MID}/REAL0Q.NRLIB/code.o ${OUT}/REAL0Q.o
+
+@
+<<REAL0Q.NRLIB (NRLIB from MID)>>=
+${MID}/REAL0Q.NRLIB: ${MID}/REAL0Q.spad
+ @ echo 0 making ${MID}/REAL0Q.NRLIB from ${MID}/REAL0Q.spad
+ @ (cd ${MID} ; echo ')co REAL0Q.spad' | ${INTERPSYS} )
+
+@
+<<REAL0Q.spad (SPAD from IN)>>=
+${MID}/REAL0Q.spad: ${IN}/real0q.spad.pamphlet
+ @ echo 0 making ${MID}/REAL0Q.spad from ${IN}/real0q.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REAL0Q.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REAL0Q RealZeroPackageQ" ${IN}/real0q.spad.pamphlet >REAL0Q.spad )
+
+@
+<<real0q.spad.dvi (DOC from IN)>>=
+${DOC}/real0q.spad.dvi: ${IN}/real0q.spad.pamphlet
+ @ echo 0 making ${DOC}/real0q.spad.dvi from ${IN}/real0q.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/real0q.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} real0q.spad ; \
+ rm -f ${DOC}/real0q.spad.pamphlet ; \
+ rm -f ${DOC}/real0q.spad.tex ; \
+ rm -f ${DOC}/real0q.spad )
+
+@
+\subsection{realzero.spad \cite{1}}
+<<realzero.spad (SPAD from IN)>>=
+${MID}/realzero.spad: ${IN}/realzero.spad.pamphlet
+ @ echo 0 making ${MID}/realzero.spad from ${IN}/realzero.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/realzero.spad.pamphlet >realzero.spad )
+
+@
+<<REAL0.o (O from NRLIB)>>=
+${OUT}/REAL0.o: ${MID}/REAL0.NRLIB
+ @ echo 0 making ${OUT}/REAL0.o from ${MID}/REAL0.NRLIB
+ @ cp ${MID}/REAL0.NRLIB/code.o ${OUT}/REAL0.o
+
+@
+<<REAL0.NRLIB (NRLIB from MID)>>=
+${MID}/REAL0.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/REAL0.spad
+ @ echo 0 making ${MID}/REAL0.NRLIB from ${MID}/REAL0.spad
+ @ (cd ${MID} ; echo ')co REAL0.spad' | ${INTERPSYS} )
+
+@
+<<REAL0.spad (SPAD from IN)>>=
+${MID}/REAL0.spad: ${IN}/realzero.spad.pamphlet
+ @ echo 0 making ${MID}/REAL0.spad from ${IN}/realzero.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REAL0.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REAL0 RealZeroPackage" ${IN}/realzero.spad.pamphlet >REAL0.spad )
+
+@
+<<realzero.spad.dvi (DOC from IN)>>=
+${DOC}/realzero.spad.dvi: ${IN}/realzero.spad.pamphlet
+ @ echo 0 making ${DOC}/realzero.spad.dvi from ${IN}/realzero.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/realzero.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} realzero.spad ; \
+ rm -f ${DOC}/realzero.spad.pamphlet ; \
+ rm -f ${DOC}/realzero.spad.tex ; \
+ rm -f ${DOC}/realzero.spad )
+
+@
+\subsection{reclos.spad \cite{1}}
+<<reclos.spad (SPAD from IN)>>=
+${MID}/reclos.spad: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${MID}/reclos.spad from ${IN}/reclos.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/reclos.spad.pamphlet >reclos.spad )
+
+@
+<<POLUTIL.o (O from NRLIB)>>=
+${OUT}/POLUTIL.o: ${MID}/POLUTIL.NRLIB
+ @ echo 0 making ${OUT}/POLUTIL.o from ${MID}/POLUTIL.NRLIB
+ @ cp ${MID}/POLUTIL.NRLIB/code.o ${OUT}/POLUTIL.o
+
+@
+<<POLUTIL.NRLIB (NRLIB from MID)>>=
+${MID}/POLUTIL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLUTIL.spad
+ @ echo 0 making ${MID}/POLUTIL.NRLIB from ${MID}/POLUTIL.spad
+ @ (cd ${MID} ; echo ')co POLUTIL.spad' | ${INTERPSYS} )
+
+@
+<<POLUTIL.spad (SPAD from IN)>>=
+${MID}/POLUTIL.spad: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${MID}/POLUTIL.spad from ${IN}/reclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLUTIL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLUTIL RealPolynomialUtilitiesPackage" ${IN}/reclos.spad.pamphlet >POLUTIL.spad )
+
+@
+<<RCFIELD-.o (O from NRLIB)>>=
+${OUT}/RCFIELD-.o: ${MID}/RCFIELD.NRLIB
+ @ echo 0 making ${OUT}/RCFIELD-.o from ${MID}/RCFIELD-.NRLIB
+ @ cp ${MID}/RCFIELD-.NRLIB/code.o ${OUT}/RCFIELD-.o
+
+@
+<<RCFIELD-.NRLIB (NRLIB from MID)>>=
+${MID}/RCFIELD-.NRLIB: ${OUT}/TYPE.o ${MID}/RCFIELD.spad
+ @ echo 0 making ${MID}/RCFIELD-.NRLIB from ${MID}/RCFIELD.spad
+ @ (cd ${MID} ; echo ')co RCFIELD.spad' | ${INTERPSYS} )
+
+@
+<<RCFIELD.o (O from NRLIB)>>=
+${OUT}/RCFIELD.o: ${MID}/RCFIELD.NRLIB
+ @ echo 0 making ${OUT}/RCFIELD.o from ${MID}/RCFIELD.NRLIB
+ @ cp ${MID}/RCFIELD.NRLIB/code.o ${OUT}/RCFIELD.o
+
+@
+<<RCFIELD.NRLIB (NRLIB from MID)>>=
+${MID}/RCFIELD.NRLIB: ${MID}/RCFIELD.spad
+ @ echo 0 making ${MID}/RCFIELD.NRLIB from ${MID}/RCFIELD.spad
+ @ (cd ${MID} ; echo ')co RCFIELD.spad' | ${INTERPSYS} )
+
+@
+<<RCFIELD.spad (SPAD from IN)>>=
+${MID}/RCFIELD.spad: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${MID}/RCFIELD.spad from ${IN}/reclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RCFIELD.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RCFIELD RealClosedField" ${IN}/reclos.spad.pamphlet >RCFIELD.spad )
+
+@
+<<RECLOS.o (O from NRLIB)>>=
+${OUT}/RECLOS.o: ${MID}/RECLOS.NRLIB
+ @ echo 0 making ${OUT}/RECLOS.o from ${MID}/RECLOS.NRLIB
+ @ cp ${MID}/RECLOS.NRLIB/code.o ${OUT}/RECLOS.o
+
+@
+<<RECLOS.NRLIB (NRLIB from MID)>>=
+${MID}/RECLOS.NRLIB: ${MID}/RECLOS.spad
+ @ echo 0 making ${MID}/RECLOS.NRLIB from ${MID}/RECLOS.spad
+ @ (cd ${MID} ; echo ')co RECLOS.spad' | ${INTERPSYS} )
+
+@
+<<RECLOS.spad (SPAD from IN)>>=
+${MID}/RECLOS.spad: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${MID}/RECLOS.spad from ${IN}/reclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RECLOS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RECLOS RealClosure" ${IN}/reclos.spad.pamphlet >RECLOS.spad )
+
+@
+<<ROIRC.o (O from NRLIB)>>=
+${OUT}/ROIRC.o: ${MID}/ROIRC.NRLIB
+ @ echo 0 making ${OUT}/ROIRC.o from ${MID}/ROIRC.NRLIB
+ @ cp ${MID}/ROIRC.NRLIB/code.o ${OUT}/ROIRC.o
+
+@
+<<ROIRC.NRLIB (NRLIB from MID)>>=
+${MID}/ROIRC.NRLIB: ${MID}/ROIRC.spad
+ @ echo 0 making ${MID}/ROIRC.NRLIB from ${MID}/ROIRC.spad
+ @ (cd ${MID} ; echo ')co ROIRC.spad' | ${INTERPSYS} )
+
+@
+<<ROIRC.spad (SPAD from IN)>>=
+${MID}/ROIRC.spad: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${MID}/ROIRC.spad from ${IN}/reclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ROIRC.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ROIRC RightOpenIntervalRootCharacterization" ${IN}/reclos.spad.pamphlet >ROIRC.spad )
+
+@
+<<RRCC-.o (O from NRLIB)>>=
+${OUT}/RRCC-.o: ${MID}/RRCC.NRLIB
+ @ echo 0 making ${OUT}/RRCC-.o from ${MID}/RRCC-.NRLIB
+ @ cp ${MID}/RRCC-.NRLIB/code.o ${OUT}/RRCC-.o
+
+@
+<<RRCC-.NRLIB (NRLIB from MID)>>=
+${MID}/RRCC-.NRLIB: ${OUT}/TYPE.o ${MID}/RRCC.spad
+ @ echo 0 making ${MID}/RRCC-.NRLIB from ${MID}/RRCC.spad
+ @ (cd ${MID} ; echo ')co RRCC.spad' | ${INTERPSYS} )
+
+@
+<<RRCC.o (O from NRLIB)>>=
+${OUT}/RRCC.o: ${MID}/RRCC.NRLIB
+ @ echo 0 making ${OUT}/RRCC.o from ${MID}/RRCC.NRLIB
+ @ cp ${MID}/RRCC.NRLIB/code.o ${OUT}/RRCC.o
+
+@
+<<RRCC.NRLIB (NRLIB from MID)>>=
+${MID}/RRCC.NRLIB: ${MID}/RRCC.spad
+ @ echo 0 making ${MID}/RRCC.NRLIB from ${MID}/RRCC.spad
+ @ (cd ${MID} ; echo ')co RRCC.spad' | ${INTERPSYS} )
+
+@
+<<RRCC.spad (SPAD from IN)>>=
+${MID}/RRCC.spad: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${MID}/RRCC.spad from ${IN}/reclos.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RRCC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RRCC RealRootCharacterizationCategory" ${IN}/reclos.spad.pamphlet >RRCC.spad )
+
+@
+<<reclos.spad.dvi (DOC from IN)>>=
+${DOC}/reclos.spad.dvi: ${IN}/reclos.spad.pamphlet
+ @ echo 0 making ${DOC}/reclos.spad.dvi from ${IN}/reclos.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/reclos.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} reclos.spad ; \
+ rm -f ${DOC}/reclos.spad.pamphlet ; \
+ rm -f ${DOC}/reclos.spad.tex ; \
+ rm -f ${DOC}/reclos.spad )
+
+@
+\subsection{regset.spad \cite{1}}
+<<regset.spad (SPAD from IN)>>=
+${MID}/regset.spad: ${IN}/regset.spad.pamphlet
+ @ echo 0 making ${MID}/regset.spad from ${IN}/regset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/regset.spad.pamphlet >regset.spad )
+
+@
+<<RSETCAT-.o (O from NRLIB)>>=
+${OUT}/RSETCAT-.o: ${MID}/RSETCAT.NRLIB
+ @ echo 0 making ${OUT}/RSETCAT-.o from ${MID}/RSETCAT-.NRLIB
+ @ cp ${MID}/RSETCAT-.NRLIB/code.o ${OUT}/RSETCAT-.o
+
+@
+<<RSETCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/RSETCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/RSETCAT.spad
+ @ echo 0 making ${MID}/RSETCAT-.NRLIB from ${MID}/RSETCAT.spad
+ @ (cd ${MID} ; echo ')co RSETCAT.spad' | ${INTERPSYS} )
+
+@
+<<RSETCAT.o (O from NRLIB)>>=
+${OUT}/RSETCAT.o: ${MID}/RSETCAT.NRLIB
+ @ echo 0 making ${OUT}/RSETCAT.o from ${MID}/RSETCAT.NRLIB
+ @ cp ${MID}/RSETCAT.NRLIB/code.o ${OUT}/RSETCAT.o
+
+@
+<<RSETCAT.NRLIB (NRLIB from MID)>>=
+${MID}/RSETCAT.NRLIB: ${MID}/RSETCAT.spad
+ @ echo 0 making ${MID}/RSETCAT.NRLIB from ${MID}/RSETCAT.spad
+ @ (cd ${MID} ; echo ')co RSETCAT.spad' | ${INTERPSYS} )
+
+@
+<<RSETCAT.spad (SPAD from IN)>>=
+${MID}/RSETCAT.spad: ${IN}/regset.spad.pamphlet
+ @ echo 0 making ${MID}/RSETCAT.spad from ${IN}/regset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RSETCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RSETCAT RegularTriangularSetCategory" ${IN}/regset.spad.pamphlet >RSETCAT.spad )
+
+@
+<<regset.spad.dvi (DOC from IN)>>=
+${DOC}/regset.spad.dvi: ${IN}/regset.spad.pamphlet
+ @ echo 0 making ${DOC}/regset.spad.dvi from ${IN}/regset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/regset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} regset.spad ; \
+ rm -f ${DOC}/regset.spad.pamphlet ; \
+ rm -f ${DOC}/regset.spad.tex ; \
+ rm -f ${DOC}/regset.spad )
+
+@
+\subsection{rep1.spad \cite{1}}
+<<rep1.spad (SPAD from IN)>>=
+${MID}/rep1.spad: ${IN}/rep1.spad.pamphlet
+ @ echo 0 making ${MID}/rep1.spad from ${IN}/rep1.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rep1.spad.pamphlet >rep1.spad )
+
+@
+<<REP1.o (O from NRLIB)>>=
+${OUT}/REP1.o: ${MID}/REP1.NRLIB
+ @ echo 0 making ${OUT}/REP1.o from ${MID}/REP1.NRLIB
+ @ cp ${MID}/REP1.NRLIB/code.o ${OUT}/REP1.o
+
+@
+<<REP1.NRLIB (NRLIB from MID)>>=
+${MID}/REP1.NRLIB: ${MID}/REP1.spad
+ @ echo 0 making ${MID}/REP1.NRLIB from ${MID}/REP1.spad
+ @ (cd ${MID} ; echo ')co REP1.spad' | ${INTERPSYS} )
+
+@
+<<REP1.spad (SPAD from IN)>>=
+${MID}/REP1.spad: ${IN}/rep1.spad.pamphlet
+ @ echo 0 making ${MID}/REP1.spad from ${IN}/rep1.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REP1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REP1 RepresentationPackage1" ${IN}/rep1.spad.pamphlet >REP1.spad )
+
+@
+<<rep1.spad.dvi (DOC from IN)>>=
+${DOC}/rep1.spad.dvi: ${IN}/rep1.spad.pamphlet
+ @ echo 0 making ${DOC}/rep1.spad.dvi from ${IN}/rep1.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rep1.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rep1.spad ; \
+ rm -f ${DOC}/rep1.spad.pamphlet ; \
+ rm -f ${DOC}/rep1.spad.tex ; \
+ rm -f ${DOC}/rep1.spad )
+
+@
+\subsection{rep2.spad \cite{1}}
+<<rep2.spad (SPAD from IN)>>=
+${MID}/rep2.spad: ${IN}/rep2.spad.pamphlet
+ @ echo 0 making ${MID}/rep2.spad from ${IN}/rep2.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rep2.spad.pamphlet >rep2.spad )
+
+@
+<<REP2.o (O from NRLIB)>>=
+${OUT}/REP2.o: ${MID}/REP2.NRLIB
+ @ echo 0 making ${OUT}/REP2.o from ${MID}/REP2.NRLIB
+ @ cp ${MID}/REP2.NRLIB/code.o ${OUT}/REP2.o
+
+@
+<<REP2.NRLIB (NRLIB from MID)>>=
+${MID}/REP2.NRLIB: ${MID}/REP2.spad
+ @ echo 0 making ${MID}/REP2.NRLIB from ${MID}/REP2.spad
+ @ (cd ${MID} ; echo ')co REP2.spad' | ${INTERPSYS} )
+
+@
+<<REP2.spad (SPAD from IN)>>=
+${MID}/REP2.spad: ${IN}/rep2.spad.pamphlet
+ @ echo 0 making ${MID}/REP2.spad from ${IN}/rep2.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REP2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package REP2 RepresentationPackage2" ${IN}/rep2.spad.pamphlet >REP2.spad )
+
+@
+<<rep2.spad.dvi (DOC from IN)>>=
+${DOC}/rep2.spad.dvi: ${IN}/rep2.spad.pamphlet
+ @ echo 0 making ${DOC}/rep2.spad.dvi from ${IN}/rep2.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rep2.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rep2.spad ; \
+ rm -f ${DOC}/rep2.spad.pamphlet ; \
+ rm -f ${DOC}/rep2.spad.tex ; \
+ rm -f ${DOC}/rep2.spad )
+
+@
+\subsection{resring.spad \cite{1}}
+<<resring.spad (SPAD from IN)>>=
+${MID}/resring.spad: ${IN}/resring.spad.pamphlet
+ @ echo 0 making ${MID}/resring.spad from ${IN}/resring.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/resring.spad.pamphlet >resring.spad )
+
+@
+<<RESRING.o (O from NRLIB)>>=
+${OUT}/RESRING.o: ${MID}/RESRING.NRLIB
+ @ echo 0 making ${OUT}/RESRING.o from ${MID}/RESRING.NRLIB
+ @ cp ${MID}/RESRING.NRLIB/code.o ${OUT}/RESRING.o
+
+@
+<<RESRING.NRLIB (NRLIB from MID)>>=
+${MID}/RESRING.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/RESRING.spad
+ @ echo 0 making ${MID}/RESRING.NRLIB from ${MID}/RESRING.spad
+ @ (cd ${MID} ; echo ')co RESRING.spad' | ${INTERPSYS} )
+
+@
+<<RESRING.spad (SPAD from IN)>>=
+${MID}/RESRING.spad: ${IN}/resring.spad.pamphlet
+ @ echo 0 making ${MID}/RESRING.spad from ${IN}/resring.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RESRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RESRING ResidueRing" ${IN}/resring.spad.pamphlet >RESRING.spad )
+
+@
+<<resring.spad.dvi (DOC from IN)>>=
+${DOC}/resring.spad.dvi: ${IN}/resring.spad.pamphlet
+ @ echo 0 making ${DOC}/resring.spad.dvi from ${IN}/resring.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/resring.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} resring.spad ; \
+ rm -f ${DOC}/resring.spad.pamphlet ; \
+ rm -f ${DOC}/resring.spad.tex ; \
+ rm -f ${DOC}/resring.spad )
+
+@
+\subsection{retract.spad \cite{1}}
+<<retract.spad (SPAD from IN)>>=
+${MID}/retract.spad: ${IN}/retract.spad.pamphlet
+ @ echo 0 making ${MID}/retract.spad from ${IN}/retract.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/retract.spad.pamphlet >retract.spad )
+
+@
+<<FRETRCT-.o (O from NRLIB)>>=
+${OUT}/FRETRCT-.o: ${MID}/FRETRCT.NRLIB
+ @ echo 0 making ${OUT}/FRETRCT-.o from ${MID}/FRETRCT-.NRLIB
+ @ cp ${MID}/FRETRCT-.NRLIB/code.o ${OUT}/FRETRCT-.o
+
+@
+<<FRETRCT-.NRLIB (NRLIB from MID)>>=
+${MID}/FRETRCT-.NRLIB: ${OUT}/TYPE.o ${MID}/FRETRCT.spad
+ @ echo 0 making ${MID}/FRETRCT-.NRLIB from ${MID}/FRETRCT.spad
+ @ (cd ${MID} ; echo ')co FRETRCT.spad' | ${INTERPSYS} )
+
+@
+<<FRETRCT.o (O from NRLIB)>>=
+${OUT}/FRETRCT.o: ${MID}/FRETRCT.NRLIB
+ @ echo 0 making ${OUT}/FRETRCT.o from ${MID}/FRETRCT.NRLIB
+ @ cp ${MID}/FRETRCT.NRLIB/code.o ${OUT}/FRETRCT.o
+
+@
+<<FRETRCT.NRLIB (NRLIB from MID)>>=
+${MID}/FRETRCT.NRLIB: ${MID}/FRETRCT.spad
+ @ echo 0 making ${MID}/FRETRCT.NRLIB from ${MID}/FRETRCT.spad
+ @ (cd ${MID} ; echo ')co FRETRCT.spad' | ${INTERPSYS} )
+
+@
+<<FRETRCT.spad (SPAD from IN)>>=
+${MID}/FRETRCT.spad: ${IN}/retract.spad.pamphlet
+ @ echo 0 making ${MID}/FRETRCT.spad from ${IN}/retract.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FRETRCT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FRETRCT FullyRetractableTo" ${IN}/retract.spad.pamphlet >FRETRCT.spad )
+
+@
+<<INTRET.o (O from NRLIB)>>=
+${OUT}/INTRET.o: ${MID}/INTRET.NRLIB
+ @ echo 0 making ${OUT}/INTRET.o from ${MID}/INTRET.NRLIB
+ @ cp ${MID}/INTRET.NRLIB/code.o ${OUT}/INTRET.o
+
+@
+<<INTRET.NRLIB (NRLIB from MID)>>=
+${MID}/INTRET.NRLIB: ${OUT}/RETRACT.o ${MID}/INTRET.spad
+ @ echo 0 making ${MID}/INTRET.NRLIB from ${MID}/INTRET.spad
+ @ (cd ${MID} ; echo ')co INTRET.spad' | ${INTERPSYS} )
+
+@
+<<INTRET.spad (SPAD from IN)>>=
+${MID}/INTRET.spad: ${IN}/retract.spad.pamphlet
+ @ echo 0 making ${MID}/INTRET.spad from ${IN}/retract.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTRET.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INTRET IntegerRetractions" ${IN}/retract.spad.pamphlet >INTRET.spad )
+
+@
+<<RATRET.o (O from NRLIB)>>=
+${OUT}/RATRET.o: ${MID}/RATRET.NRLIB
+ @ echo 0 making ${OUT}/RATRET.o from ${MID}/RATRET.NRLIB
+ @ cp ${MID}/RATRET.NRLIB/code.o ${OUT}/RATRET.o
+
+@
+<<RATRET.NRLIB (NRLIB from MID)>>=
+${MID}/RATRET.NRLIB: ${MID}/RATRET.spad
+ @ echo 0 making ${MID}/RATRET.NRLIB from ${MID}/RATRET.spad
+ @ (cd ${MID} ; echo ')co RATRET.spad' | ${INTERPSYS} )
+
+@
+<<RATRET.spad (SPAD from IN)>>=
+${MID}/RATRET.spad: ${IN}/retract.spad.pamphlet
+ @ echo 0 making ${MID}/RATRET.spad from ${IN}/retract.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RATRET.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RATRET RationalRetractions" ${IN}/retract.spad.pamphlet >RATRET.spad )
+
+@
+<<retract.spad.dvi (DOC from IN)>>=
+${DOC}/retract.spad.dvi: ${IN}/retract.spad.pamphlet
+ @ echo 0 making ${DOC}/retract.spad.dvi from ${IN}/retract.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/retract.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} retract.spad ; \
+ rm -f ${DOC}/retract.spad.pamphlet ; \
+ rm -f ${DOC}/retract.spad.tex ; \
+ rm -f ${DOC}/retract.spad )
+
+@
+\subsection{rf.spad \cite{1}}
+<<rf.spad (SPAD from IN)>>=
+${MID}/rf.spad: ${IN}/rf.spad.pamphlet
+ @ echo 0 making ${MID}/rf.spad from ${IN}/rf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rf.spad.pamphlet >rf.spad )
+
+@
+<<POLYCATQ.o (O from NRLIB)>>=
+${OUT}/POLYCATQ.o: ${MID}/POLYCATQ.NRLIB
+ @ echo 0 making ${OUT}/POLYCATQ.o from ${MID}/POLYCATQ.NRLIB
+ @ cp ${MID}/POLYCATQ.NRLIB/code.o ${OUT}/POLYCATQ.o
+
+@
+<<POLYCATQ.NRLIB (NRLIB from MID)>>=
+${MID}/POLYCATQ.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/POLYCATQ.spad
+ @ echo 0 making ${MID}/POLYCATQ.NRLIB from ${MID}/POLYCATQ.spad
+ @ (cd ${MID} ; echo ')co POLYCATQ.spad' | ${INTERPSYS} )
+
+@
+<<POLYCATQ.spad (SPAD from IN)>>=
+${MID}/POLYCATQ.spad: ${IN}/rf.spad.pamphlet
+ @ echo 0 making ${MID}/POLYCATQ.spad from ${IN}/rf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf POLYCATQ.NRLIB ; \
+ ${SPADBIN}/notangle -R"package POLYCATQ PolynomialCategoryQuotientFunctions" ${IN}/rf.spad.pamphlet >POLYCATQ.spad )
+
+@
+<<RF.o (O from NRLIB)>>=
+${OUT}/RF.o: ${MID}/RF.NRLIB
+ @ echo 0 making ${OUT}/RF.o from ${MID}/RF.NRLIB
+ @ cp ${MID}/RF.NRLIB/code.o ${OUT}/RF.o
+
+@
+<<RF.NRLIB (NRLIB from MID)>>=
+${MID}/RF.NRLIB: ${MID}/RF.spad
+ @ echo 0 making ${MID}/RF.NRLIB from ${MID}/RF.spad
+ @ (cd ${MID} ; echo ')co RF.spad' | ${INTERPSYS} )
+
+@
+<<RF.spad (SPAD from IN)>>=
+${MID}/RF.spad: ${IN}/rf.spad.pamphlet
+ @ echo 0 making ${MID}/RF.spad from ${IN}/rf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RF RationalFunction" ${IN}/rf.spad.pamphlet >RF.spad )
+
+@
+<<rf.spad.dvi (DOC from IN)>>=
+${DOC}/rf.spad.dvi: ${IN}/rf.spad.pamphlet
+ @ echo 0 making ${DOC}/rf.spad.dvi from ${IN}/rf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rf.spad ; \
+ rm -f ${DOC}/rf.spad.pamphlet ; \
+ rm -f ${DOC}/rf.spad.tex ; \
+ rm -f ${DOC}/rf.spad )
+
+@
+\subsection{riccati.spad \cite{1}}
+<<riccati.spad (SPAD from IN)>>=
+${MID}/riccati.spad: ${IN}/riccati.spad.pamphlet
+ @ echo 0 making ${MID}/riccati.spad from ${IN}/riccati.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/riccati.spad.pamphlet >riccati.spad )
+
+@
+<<ODEPRRIC.o (O from NRLIB)>>=
+${OUT}/ODEPRRIC.o: ${MID}/ODEPRRIC.NRLIB
+ @ echo 0 making ${OUT}/ODEPRRIC.o from ${MID}/ODEPRRIC.NRLIB
+ @ cp ${MID}/ODEPRRIC.NRLIB/code.o ${OUT}/ODEPRRIC.o
+
+@
+<<ODEPRRIC.NRLIB (NRLIB from MID)>>=
+${MID}/ODEPRRIC.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ODEPRRIC.spad
+ @ echo 0 making ${MID}/ODEPRRIC.NRLIB from ${MID}/ODEPRRIC.spad
+ @ (cd ${MID} ; echo ')co ODEPRRIC.spad' | ${INTERPSYS} )
+
+@
+<<ODEPRRIC.spad (SPAD from IN)>>=
+${MID}/ODEPRRIC.spad: ${IN}/riccati.spad.pamphlet
+ @ echo 0 making ${MID}/ODEPRRIC.spad from ${IN}/riccati.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODEPRRIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODEPRRIC PrimitiveRatRicDE" ${IN}/riccati.spad.pamphlet >ODEPRRIC.spad )
+
+@
+<<ODERTRIC.o (O from NRLIB)>>=
+${OUT}/ODERTRIC.o: ${MID}/ODERTRIC.NRLIB
+ @ echo 0 making ${OUT}/ODERTRIC.o from ${MID}/ODERTRIC.NRLIB
+ @ cp ${MID}/ODERTRIC.NRLIB/code.o ${OUT}/ODERTRIC.o
+
+@
+<<ODERTRIC.NRLIB (NRLIB from MID)>>=
+${MID}/ODERTRIC.NRLIB: ${MID}/ODERTRIC.spad
+ @ echo 0 making ${MID}/ODERTRIC.NRLIB from ${MID}/ODERTRIC.spad
+ @ (cd ${MID} ; echo ')co ODERTRIC.spad' | ${INTERPSYS} )
+
+@
+<<ODERTRIC.spad (SPAD from IN)>>=
+${MID}/ODERTRIC.spad: ${IN}/riccati.spad.pamphlet
+ @ echo 0 making ${MID}/ODERTRIC.spad from ${IN}/riccati.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ODERTRIC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ODERTRIC RationalRicDE" ${IN}/riccati.spad.pamphlet >ODERTRIC.spad )
+
+@
+<<riccati.spad.dvi (DOC from IN)>>=
+${DOC}/riccati.spad.dvi: ${IN}/riccati.spad.pamphlet
+ @ echo 0 making ${DOC}/riccati.spad.dvi from ${IN}/riccati.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/riccati.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} riccati.spad ; \
+ rm -f ${DOC}/riccati.spad.pamphlet ; \
+ rm -f ${DOC}/riccati.spad.tex ; \
+ rm -f ${DOC}/riccati.spad )
+
+@
+\subsection{routines.spad \cite{1}}
+<<routines.spad (SPAD from IN)>>=
+${MID}/routines.spad: ${IN}/routines.spad.pamphlet
+ @ echo 0 making ${MID}/routines.spad from ${IN}/routines.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/routines.spad.pamphlet >routines.spad )
+
+@
+<<ATTRBUT.o (O from NRLIB)>>=
+${OUT}/ATTRBUT.o: ${MID}/ATTRBUT.NRLIB
+ @ echo 0 making ${OUT}/ATTRBUT.o from ${MID}/ATTRBUT.NRLIB
+ @ cp ${MID}/ATTRBUT.NRLIB/code.o ${OUT}/ATTRBUT.o
+
+@
+<<ATTRBUT.NRLIB (NRLIB from MID)>>=
+${MID}/ATTRBUT.NRLIB: ${MID}/ATTRBUT.spad
+ @ echo 0 making ${MID}/ATTRBUT.NRLIB from ${MID}/ATTRBUT.spad
+ @ (cd ${MID} ; echo ')co ATTRBUT.spad' | ${INTERPSYS} )
+
+@
+<<ATTRBUT.spad (SPAD from IN)>>=
+${MID}/ATTRBUT.spad: ${IN}/routines.spad.pamphlet
+ @ echo 0 making ${MID}/ATTRBUT.spad from ${IN}/routines.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ATTRBUT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ATTRBUT AttributeButtons" ${IN}/routines.spad.pamphlet >ATTRBUT.spad )
+
+@
+<<ROUTINE.o (O from NRLIB)>>=
+${OUT}/ROUTINE.o: ${MID}/ROUTINE.NRLIB
+ @ echo 0 making ${OUT}/ROUTINE.o from ${MID}/ROUTINE.NRLIB
+ @ cp ${MID}/ROUTINE.NRLIB/code.o ${OUT}/ROUTINE.o
+
+@
+<<ROUTINE.NRLIB (NRLIB from MID)>>=
+${MID}/ROUTINE.NRLIB: ${MID}/ROUTINE.spad
+ @ echo 0 making ${MID}/ROUTINE.NRLIB from ${MID}/ROUTINE.spad
+ @ (cd ${MID} ; echo ')co ROUTINE.spad' | ${INTERPSYS} )
+
+@
+<<ROUTINE.spad (SPAD from IN)>>=
+${MID}/ROUTINE.spad: ${IN}/routines.spad.pamphlet
+ @ echo 0 making ${MID}/ROUTINE.spad from ${IN}/routines.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ROUTINE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ROUTINE RoutinesTable" ${IN}/routines.spad.pamphlet >ROUTINE.spad )
+
+@
+<<routines.spad.dvi (DOC from IN)>>=
+${DOC}/routines.spad.dvi: ${IN}/routines.spad.pamphlet
+ @ echo 0 making ${DOC}/routines.spad.dvi from ${IN}/routines.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/routines.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} routines.spad ; \
+ rm -f ${DOC}/routines.spad.pamphlet ; \
+ rm -f ${DOC}/routines.spad.tex ; \
+ rm -f ${DOC}/routines.spad )
+
+@
+\subsection{rule.spad \cite{1}}
+<<rule.spad (SPAD from IN)>>=
+${MID}/rule.spad: ${IN}/rule.spad.pamphlet
+ @ echo 0 making ${MID}/rule.spad from ${IN}/rule.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/rule.spad.pamphlet >rule.spad )
+
+@
+<<APPRULE.o (O from NRLIB)>>=
+${OUT}/APPRULE.o: ${MID}/APPRULE.NRLIB
+ @ echo 0 making ${OUT}/APPRULE.o from ${MID}/APPRULE.NRLIB
+ @ cp ${MID}/APPRULE.NRLIB/code.o ${OUT}/APPRULE.o
+
+@
+<<APPRULE.NRLIB (NRLIB from MID)>>=
+${MID}/APPRULE.NRLIB: ${MID}/APPRULE.spad
+ @ echo 0 making ${MID}/APPRULE.NRLIB from ${MID}/APPRULE.spad
+ @ (cd ${MID} ; echo ')co APPRULE.spad' | ${INTERPSYS} )
+
+@
+<<APPRULE.spad (SPAD from IN)>>=
+${MID}/APPRULE.spad: ${IN}/rule.spad.pamphlet
+ @ echo 0 making ${MID}/APPRULE.spad from ${IN}/rule.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf APPRULE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package APPRULE ApplyRules" ${IN}/rule.spad.pamphlet >APPRULE.spad )
+
+@
+<<RULE.o (O from NRLIB)>>=
+${OUT}/RULE.o: ${MID}/RULE.NRLIB
+ @ echo 0 making ${OUT}/RULE.o from ${MID}/RULE.NRLIB
+ @ cp ${MID}/RULE.NRLIB/code.o ${OUT}/RULE.o
+
+@
+<<RULE.NRLIB (NRLIB from MID)>>=
+${MID}/RULE.NRLIB: ${MID}/RULE.spad
+ @ echo 0 making ${MID}/RULE.NRLIB from ${MID}/RULE.spad
+ @ (cd ${MID} ; echo ')co RULE.spad' | ${INTERPSYS} )
+
+@
+<<RULE.spad (SPAD from IN)>>=
+${MID}/RULE.spad: ${IN}/rule.spad.pamphlet
+ @ echo 0 making ${MID}/RULE.spad from ${IN}/rule.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RULE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RULE RewriteRule" ${IN}/rule.spad.pamphlet >RULE.spad )
+
+@
+<<RULESET.o (O from NRLIB)>>=
+${OUT}/RULESET.o: ${MID}/RULESET.NRLIB
+ @ echo 0 making ${OUT}/RULESET.o from ${MID}/RULESET.NRLIB
+ @ cp ${MID}/RULESET.NRLIB/code.o ${OUT}/RULESET.o
+
+@
+<<RULESET.NRLIB (NRLIB from MID)>>=
+${MID}/RULESET.NRLIB: ${MID}/RULESET.spad
+ @ echo 0 making ${MID}/RULESET.NRLIB from ${MID}/RULESET.spad
+ @ (cd ${MID} ; echo ')co RULESET.spad' | ${INTERPSYS} )
+
+@
+<<RULESET.spad (SPAD from IN)>>=
+${MID}/RULESET.spad: ${IN}/rule.spad.pamphlet
+ @ echo 0 making ${MID}/RULESET.spad from ${IN}/rule.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RULESET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RULESET Ruleset" ${IN}/rule.spad.pamphlet >RULESET.spad )
+
+@
+<<rule.spad.dvi (DOC from IN)>>=
+${DOC}/rule.spad.dvi: ${IN}/rule.spad.pamphlet
+ @ echo 0 making ${DOC}/rule.spad.dvi from ${IN}/rule.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/rule.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} rule.spad ; \
+ rm -f ${DOC}/rule.spad.pamphlet ; \
+ rm -f ${DOC}/rule.spad.tex ; \
+ rm -f ${DOC}/rule.spad )
+
+@
+\subsection{seg.spad \cite{1}}
+<<seg.spad (SPAD from IN)>>=
+${MID}/seg.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/seg.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/seg.spad.pamphlet >seg.spad )
+
+@
+<<INCRMAPS.o (O from NRLIB)>>=
+${OUT}/INCRMAPS.o: ${MID}/INCRMAPS.NRLIB
+ @ echo 0 making ${OUT}/INCRMAPS.o from ${MID}/INCRMAPS.NRLIB
+ @ cp ${MID}/INCRMAPS.NRLIB/code.o ${OUT}/INCRMAPS.o
+
+@
+<<INCRMAPS.NRLIB (NRLIB from MID)>>=
+${MID}/INCRMAPS.NRLIB: ${MID}/INCRMAPS.spad
+ @ echo 0 making ${MID}/INCRMAPS.NRLIB from ${MID}/INCRMAPS.spad
+ @ (cd ${MID} ; echo ')co INCRMAPS.spad' | ${INTERPSYS} )
+
+@
+<<INCRMAPS.spad (SPAD from IN)>>=
+${MID}/INCRMAPS.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/INCRMAPS.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INCRMAPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INCRMAPS IncrementingMaps" ${IN}/seg.spad.pamphlet >INCRMAPS.spad )
+
+@
+<<SEG.o (O from NRLIB)>>=
+${OUT}/SEG.o: ${MID}/SEG.NRLIB
+ @ echo 0 making ${OUT}/SEG.o from ${MID}/SEG.NRLIB
+ @ cp ${MID}/SEG.NRLIB/code.o ${OUT}/SEG.o
+
+@
+<<SEG.NRLIB (NRLIB from MID)>>=
+${MID}/SEG.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SEG.spad
+ @ echo 0 making ${MID}/SEG.NRLIB from ${MID}/SEG.spad
+ @ (cd ${MID} ; echo ')co SEG.spad' | ${INTERPSYS} )
+
+@
+<<SEG.spad (SPAD from IN)>>=
+${MID}/SEG.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/SEG.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEG.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SEG Segment" ${IN}/seg.spad.pamphlet >SEG.spad )
+
+@
+<<SEG2.o (O from NRLIB)>>=
+${OUT}/SEG2.o: ${MID}/SEG2.NRLIB
+ @ echo 0 making ${OUT}/SEG2.o from ${MID}/SEG2.NRLIB
+ @ cp ${MID}/SEG2.NRLIB/code.o ${OUT}/SEG2.o
+
+@
+<<SEG2.NRLIB (NRLIB from MID)>>=
+${MID}/SEG2.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SEG2.spad
+ @ echo 0 making ${MID}/SEG2.NRLIB from ${MID}/SEG2.spad
+ @ (cd ${MID} ; echo ')co SEG2.spad' | ${INTERPSYS} )
+
+@
+<<SEG2.spad (SPAD from IN)>>=
+${MID}/SEG2.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/SEG2.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEG2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SEG2 SegmentFunctions2" ${IN}/seg.spad.pamphlet >SEG2.spad )
+
+@
+<<SEGBIND.o (O from NRLIB)>>=
+${OUT}/SEGBIND.o: ${MID}/SEGBIND.NRLIB
+ @ echo 0 making ${OUT}/SEGBIND.o from ${MID}/SEGBIND.NRLIB
+ @ cp ${MID}/SEGBIND.NRLIB/code.o ${OUT}/SEGBIND.o
+
+@
+<<SEGBIND.NRLIB (NRLIB from MID)>>=
+${MID}/SEGBIND.NRLIB: ${MID}/SEGBIND.spad
+ @ echo 0 making ${MID}/SEGBIND.NRLIB from ${MID}/SEGBIND.spad
+ @ (cd ${MID} ; echo ')co SEGBIND.spad' | ${INTERPSYS} )
+
+@
+<<SEGBIND.spad (SPAD from IN)>>=
+${MID}/SEGBIND.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/SEGBIND.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEGBIND.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SEGBIND SegmentBinding" ${IN}/seg.spad.pamphlet >SEGBIND.spad )
+
+@
+<<SEGBIND2.o (O from NRLIB)>>=
+${OUT}/SEGBIND2.o: ${MID}/SEGBIND2.NRLIB
+ @ echo 0 making ${OUT}/SEGBIND2.o from ${MID}/SEGBIND2.NRLIB
+ @ cp ${MID}/SEGBIND2.NRLIB/code.o ${OUT}/SEGBIND2.o
+
+@
+<<SEGBIND2.NRLIB (NRLIB from MID)>>=
+${MID}/SEGBIND2.NRLIB: ${OUT}/TYPE.o ${MID}/SEGBIND2.spad
+ @ echo 0 making ${MID}/SEGBIND2.NRLIB from ${MID}/SEGBIND2.spad
+ @ (cd ${MID} ; echo ')co SEGBIND2.spad' | ${INTERPSYS} )
+
+@
+<<SEGBIND2.spad (SPAD from IN)>>=
+${MID}/SEGBIND2.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/SEGBIND2.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEGBIND2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SEGBIND2 SegmentBindingFunctions2" ${IN}/seg.spad.pamphlet >SEGBIND2.spad )
+
+@
+<<SEGCAT.o (O from NRLIB)>>=
+${OUT}/SEGCAT.o: ${MID}/SEGCAT.NRLIB
+ @ echo 0 making ${OUT}/SEGCAT.o from ${MID}/SEGCAT.NRLIB
+ @ cp ${MID}/SEGCAT.NRLIB/code.o ${OUT}/SEGCAT.o
+
+@
+<<SEGCAT.NRLIB (NRLIB from MID)>>=
+${MID}/SEGCAT.NRLIB: ${OUT}/TYPE.o ${MID}/SEGCAT.spad
+ @ echo 0 making ${MID}/SEGCAT.NRLIB from ${MID}/SEGCAT.spad
+ @ (cd ${MID} ; echo ')co SEGCAT.spad' | ${INTERPSYS} )
+
+@
+<<SEGCAT.spad (SPAD from IN)>>=
+${MID}/SEGCAT.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/SEGCAT.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEGCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SEGCAT SegmentCategory" ${IN}/seg.spad.pamphlet >SEGCAT.spad )
+
+@
+<<SEGXCAT.o (O from NRLIB)>>=
+${OUT}/SEGXCAT.o: ${MID}/SEGXCAT.NRLIB
+ @ echo 0 making ${OUT}/SEGXCAT.o from ${MID}/SEGXCAT.NRLIB
+ @ cp ${MID}/SEGXCAT.NRLIB/code.o ${OUT}/SEGXCAT.o
+
+@
+<<SEGXCAT.NRLIB (NRLIB from MID)>>=
+${MID}/SEGXCAT.NRLIB: ${OUT}/SEGCAT.o ${OUT}/TYPE.o ${MID}/SEGXCAT.spad
+ @ echo 0 making ${MID}/SEGXCAT.NRLIB from ${MID}/SEGXCAT.spad
+ @ (cd ${MID} ; echo ')co SEGXCAT.spad' | ${INTERPSYS} )
+
+@
+<<SEGXCAT.spad (SPAD from IN)>>=
+${MID}/SEGXCAT.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/SEGXCAT.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEGXCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SEGXCAT SegmentExpansionCategory" ${IN}/seg.spad.pamphlet >SEGXCAT.spad )
+
+@
+<<UNISEG.o (O from NRLIB)>>=
+${OUT}/UNISEG.o: ${MID}/UNISEG.NRLIB
+ @ echo 0 making ${OUT}/UNISEG.o from ${MID}/UNISEG.NRLIB
+ @ cp ${MID}/UNISEG.NRLIB/code.o ${OUT}/UNISEG.o
+
+@
+<<UNISEG.NRLIB (NRLIB from MID)>>=
+${MID}/UNISEG.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UNISEG.spad
+ @ echo 0 making ${MID}/UNISEG.NRLIB from ${MID}/UNISEG.spad
+ @ (cd ${MID} ; echo ')co UNISEG.spad' | ${INTERPSYS} )
+
+@
+<<UNISEG.spad (SPAD from IN)>>=
+${MID}/UNISEG.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/UNISEG.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UNISEG.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain UNISEG UniversalSegment" ${IN}/seg.spad.pamphlet >UNISEG.spad )
+
+@
+<<UNISEG2.o (O from NRLIB)>>=
+${OUT}/UNISEG2.o: ${MID}/UNISEG2.NRLIB
+ @ echo 0 making ${OUT}/UNISEG2.o from ${MID}/UNISEG2.NRLIB
+ @ cp ${MID}/UNISEG2.NRLIB/code.o ${OUT}/UNISEG2.o
+
+@
+<<UNISEG2.NRLIB (NRLIB from MID)>>=
+${MID}/UNISEG2.NRLIB: ${MID}/UNISEG2.spad
+ @ echo 0 making ${MID}/UNISEG2.NRLIB from ${MID}/UNISEG2.spad
+ @ (cd ${MID} ; echo ')co UNISEG2.spad' | ${INTERPSYS} )
+
+@
+<<UNISEG2.spad (SPAD from IN)>>=
+${MID}/UNISEG2.spad: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${MID}/UNISEG2.spad from ${IN}/seg.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UNISEG2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UNISEG2 UniversalSegmentFunctions2" ${IN}/seg.spad.pamphlet >UNISEG2.spad )
+
+@
+<<seg.spad.dvi (DOC from IN)>>=
+${DOC}/seg.spad.dvi: ${IN}/seg.spad.pamphlet
+ @ echo 0 making ${DOC}/seg.spad.dvi from ${IN}/seg.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/seg.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} seg.spad ; \
+ rm -f ${DOC}/seg.spad.pamphlet ; \
+ rm -f ${DOC}/seg.spad.tex ; \
+ rm -f ${DOC}/seg.spad )
+
+@
+\subsection{setorder.spad \cite{1}}
+<<setorder.spad (SPAD from IN)>>=
+${MID}/setorder.spad: ${IN}/setorder.spad.pamphlet
+ @ echo 0 making ${MID}/setorder.spad from ${IN}/setorder.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/setorder.spad.pamphlet >setorder.spad )
+
+@
+<<UDPO.o (O from NRLIB)>>=
+${OUT}/UDPO.o: ${MID}/UDPO.NRLIB
+ @ echo 0 making ${OUT}/UDPO.o from ${MID}/UDPO.NRLIB
+ @ cp ${MID}/UDPO.NRLIB/code.o ${OUT}/UDPO.o
+
+@
+<<UDPO.NRLIB (NRLIB from MID)>>=
+${MID}/UDPO.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UDPO.spad
+ @ echo 0 making ${MID}/UDPO.NRLIB from ${MID}/UDPO.spad
+ @ (cd ${MID} ; echo ')co UDPO.spad' | ${INTERPSYS} )
+
+@
+<<UDPO.spad (SPAD from IN)>>=
+${MID}/UDPO.spad: ${IN}/setorder.spad.pamphlet
+ @ echo 0 making ${MID}/UDPO.spad from ${IN}/setorder.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UDPO.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UDPO UserDefinedPartialOrdering" ${IN}/setorder.spad.pamphlet >UDPO.spad )
+
+@
+<<UDVO.o (O from NRLIB)>>=
+${OUT}/UDVO.o: ${MID}/UDVO.NRLIB
+ @ echo 0 making ${OUT}/UDVO.o from ${MID}/UDVO.NRLIB
+ @ cp ${MID}/UDVO.NRLIB/code.o ${OUT}/UDVO.o
+
+@
+<<UDVO.NRLIB (NRLIB from MID)>>=
+${MID}/UDVO.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UDVO.spad
+ @ echo 0 making ${MID}/UDVO.NRLIB from ${MID}/UDVO.spad
+ @ (cd ${MID} ; echo ')co UDVO.spad' | ${INTERPSYS} )
+
+@
+<<UDVO.spad (SPAD from IN)>>=
+${MID}/UDVO.spad: ${IN}/setorder.spad.pamphlet
+ @ echo 0 making ${MID}/UDVO.spad from ${IN}/setorder.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UDVO.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UDVO UserDefinedVariableOrdering" ${IN}/setorder.spad.pamphlet >UDVO.spad )
+
+@
+<<setorder.spad.dvi (DOC from IN)>>=
+${DOC}/setorder.spad.dvi: ${IN}/setorder.spad.pamphlet
+ @ echo 0 making ${DOC}/setorder.spad.dvi from ${IN}/setorder.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/setorder.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} setorder.spad ; \
+ rm -f ${DOC}/setorder.spad.pamphlet ; \
+ rm -f ${DOC}/setorder.spad.tex ; \
+ rm -f ${DOC}/setorder.spad )
+
+@
+\subsection{sets.spad \cite{1}}
+<<sets.spad (SPAD from IN)>>=
+${MID}/sets.spad: ${IN}/sets.spad.pamphlet
+ @ echo 0 making ${MID}/sets.spad from ${IN}/sets.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sets.spad.pamphlet >sets.spad )
+
+@
+<<SET.o (O from NRLIB)>>=
+${OUT}/SET.o: ${MID}/SET.NRLIB
+ @ echo 0 making ${OUT}/SET.o from ${MID}/SET.NRLIB
+ @ cp ${MID}/SET.NRLIB/code.o ${OUT}/SET.o
+
+@
+<<SET.NRLIB (NRLIB from MID)>>=
+${MID}/SET.NRLIB: ${MID}/SET.spad
+ @ echo 0 making ${MID}/SET.NRLIB from ${MID}/SET.spad
+ @ (cd ${MID} ; echo ')co SET.spad' | ${INTERPSYS} )
+
+@
+<<SET.spad (SPAD from IN)>>=
+${MID}/SET.spad: ${IN}/sets.spad.pamphlet
+ @ echo 0 making ${MID}/SET.spad from ${IN}/sets.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SET Set" ${IN}/sets.spad.pamphlet >SET.spad )
+
+@
+<<sets.spad.dvi (DOC from IN)>>=
+${DOC}/sets.spad.dvi: ${IN}/sets.spad.pamphlet
+ @ echo 0 making ${DOC}/sets.spad.dvi from ${IN}/sets.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sets.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sets.spad ; \
+ rm -f ${DOC}/sets.spad.pamphlet ; \
+ rm -f ${DOC}/sets.spad.tex ; \
+ rm -f ${DOC}/sets.spad )
+
+@
+\subsection{sex.spad \cite{1}}
+<<sex.spad (SPAD from IN)>>=
+${MID}/sex.spad: ${IN}/sex.spad.pamphlet
+ @ echo 0 making ${MID}/sex.spad from ${IN}/sex.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sex.spad.pamphlet >sex.spad )
+
+@
+<<SEX.o (O from NRLIB)>>=
+${OUT}/SEX.o: ${MID}/SEX.NRLIB
+ @ echo 0 making ${OUT}/SEX.o from ${MID}/SEX.NRLIB
+ @ cp ${MID}/SEX.NRLIB/code.o ${OUT}/SEX.o
+
+@
+<<SEX.NRLIB (NRLIB from MID)>>=
+${MID}/SEX.NRLIB: ${MID}/SEX.spad
+ @ echo 0 making ${MID}/SEX.NRLIB from ${MID}/SEX.spad
+ @ (cd ${MID} ; echo ')co SEX.spad' | ${INTERPSYS} )
+
+@
+<<SEX.spad (SPAD from IN)>>=
+${MID}/SEX.spad: ${IN}/sex.spad.pamphlet
+ @ echo 0 making ${MID}/SEX.spad from ${IN}/sex.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SEX SExpression" ${IN}/sex.spad.pamphlet >SEX.spad )
+
+@
+<<SEXCAT.o (O from NRLIB)>>=
+${OUT}/SEXCAT.o: ${MID}/SEXCAT.NRLIB
+ @ echo 0 making ${OUT}/SEXCAT.o from ${MID}/SEXCAT.NRLIB
+ @ cp ${MID}/SEXCAT.NRLIB/code.o ${OUT}/SEXCAT.o
+
+@
+<<SEXCAT.NRLIB (NRLIB from MID)>>=
+${MID}/SEXCAT.NRLIB: ${OUT}/BASTYPE.o ${OUT}/KOERCE.o ${MID}/SEXCAT.spad
+ @ echo 0 making ${MID}/SEXCAT.NRLIB from ${MID}/SEXCAT.spad
+ @ (cd ${MID} ; echo ')co SEXCAT.spad' | ${INTERPSYS} )
+
+@
+<<SEXCAT.spad (SPAD from IN)>>=
+${MID}/SEXCAT.spad: ${IN}/sex.spad.pamphlet
+ @ echo 0 making ${MID}/SEXCAT.spad from ${IN}/sex.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEXCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SEXCAT SExpressionCategory" ${IN}/sex.spad.pamphlet >SEXCAT.spad )
+
+@
+<<SEXOF.o (O from NRLIB)>>=
+${OUT}/SEXOF.o: ${MID}/SEXOF.NRLIB
+ @ echo 0 making ${OUT}/SEXOF.o from ${MID}/SEXOF.NRLIB
+ @ cp ${MID}/SEXOF.NRLIB/code.o ${OUT}/SEXOF.o
+
+@
+<<SEXOF.NRLIB (NRLIB from MID)>>=
+${MID}/SEXOF.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SEXOF.spad
+ @ echo 0 making ${MID}/SEXOF.NRLIB from ${MID}/SEXOF.spad
+ @ (cd ${MID} ; echo ')co SEXOF.spad' | ${INTERPSYS} )
+
+@
+<<SEXOF.spad (SPAD from IN)>>=
+${MID}/SEXOF.spad: ${IN}/sex.spad.pamphlet
+ @ echo 0 making ${MID}/SEXOF.spad from ${IN}/sex.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SEXOF.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SEXOF SExpressionOf" ${IN}/sex.spad.pamphlet >SEXOF.spad )
+
+@
+<<sex.spad.dvi (DOC from IN)>>=
+${DOC}/sex.spad.dvi: ${IN}/sex.spad.pamphlet
+ @ echo 0 making ${DOC}/sex.spad.dvi from ${IN}/sex.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sex.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sex.spad ; \
+ rm -f ${DOC}/sex.spad.pamphlet ; \
+ rm -f ${DOC}/sex.spad.tex ; \
+ rm -f ${DOC}/sex.spad )
+
+@
+\subsection{sf.spad \cite{1}}
+<<sf.spad (SPAD from IN)>>=
+${MID}/sf.spad: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/sf.spad from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sf.spad.pamphlet >sf.spad )
+
+@
+<<DFLOAT.o (O from NRLIB)>>=
+${OUT}/DFLOAT.o: ${MID}/DFLOAT.NRLIB
+ @ echo 0 making ${OUT}/DFLOAT.o from ${MID}/DFLOAT.NRLIB
+ @ cp ${MID}/DFLOAT.NRLIB/code.o ${OUT}/DFLOAT.o
+
+@
+<<DFLOAT.NRLIB (NRLIB from MID)>>=
+${MID}/DFLOAT.NRLIB: ${MID}/DFLOAT.spad
+ @ echo 0 making ${MID}/DFLOAT.NRLIB from ${MID}/DFLOAT.spad
+ @ (cd ${MID} ; echo ')co DFLOAT.spad' | ${INTERPSYS} )
+
+@
+<<DFLOAT.spad (SPAD from IN)>>=
+${MID}/DFLOAT.spad: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/DFLOAT.spad from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DFLOAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DFLOAT DoubleFloat" ${IN}/sf.spad.pamphlet >DFLOAT.spad )
+
+@
+<<DFLOAT.o (BOOTSTRAP from MID)>>=
+${MID}/DFLOAT.o: ${MID}/DFLOAT.lsp
+ @ echo 0 making ${MID}/DFLOAT.o from ${MID}/DFLOAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "DFLOAT.lsp" :output-file "DFLOAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/DFLOAT.o ${OUT}/DFLOAT.o
+
+@
+<<DFLOAT.lsp (LISP from IN)>>=
+${MID}/DFLOAT.lsp: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/DFLOAT.lsp from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DFLOAT.NRLIB ; \
+ rm -rf ${OUT}/DFLOAT.o ; \
+ ${SPADBIN}/notangle -R"DFLOAT.lsp BOOTSTRAP" ${IN}/sf.spad.pamphlet >DFLOAT.lsp )
+
+@
+<<FPS-.o (O from NRLIB)>>=
+${OUT}/FPS-.o: ${MID}/FPS.NRLIB
+ @ echo 0 making ${OUT}/FPS-.o from ${MID}/FPS-.NRLIB
+ @ cp ${MID}/FPS-.NRLIB/code.o ${OUT}/FPS-.o
+
+@
+<<FPS-.NRLIB (NRLIB from MID)>>=
+${MID}/FPS-.NRLIB: ${OUT}/TYPE.o ${MID}/FPS.spad
+ @ echo 0 making ${MID}/FPS-.NRLIB from ${MID}/FPS.spad
+ @ (cd ${MID} ; echo ')co FPS.spad' | ${INTERPSYS} )
+
+@
+<<FPS.o (O from NRLIB)>>=
+${OUT}/FPS.o: ${MID}/FPS.NRLIB
+ @ echo 0 making ${OUT}/FPS.o from ${MID}/FPS.NRLIB
+ @ cp ${MID}/FPS.NRLIB/code.o ${OUT}/FPS.o
+
+@
+<<FPS.NRLIB (NRLIB from MID)>>=
+${MID}/FPS.NRLIB: ${MID}/FPS.spad
+ @ echo 0 making ${MID}/FPS.NRLIB from ${MID}/FPS.spad
+ @ (cd ${MID} ; echo ')co FPS.spad' | ${INTERPSYS} )
+
+@
+<<FPS.spad (SPAD from IN)>>=
+${MID}/FPS.spad: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/FPS.spad from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FPS FloatingPointSystem" ${IN}/sf.spad.pamphlet >FPS.spad )
+
+@
+<<FPS-.o (BOOTSTRAP from MID)>>=
+${MID}/FPS-.o: ${MID}/FPS-.lsp
+ @ echo 0 making ${MID}/FPS-.o from ${MID}/FPS-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "FPS-.lsp" :output-file "FPS-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/FPS-.o ${OUT}/FPS-.o
+
+@
+<<FPS-.lsp (LISP from IN)>>=
+${MID}/FPS-.lsp: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/FPS-.lsp from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FPS-.NRLIB ; \
+ rm -rf ${OUT}/FPS-.o ; \
+ ${SPADBIN}/notangle -R"FPS-.lsp BOOTSTRAP" ${IN}/sf.spad.pamphlet >FPS-.lsp )
+
+@
+<<FPS.o (BOOTSTRAP from MID)>>=
+${MID}/FPS.o: ${MID}/FPS.lsp
+ @ echo 0 making ${MID}/FPS.o from ${MID}/FPS.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "FPS.lsp" :output-file "FPS.o"))' | ${DEPSYS} )
+ @ cp ${MID}/FPS.o ${OUT}/FPS.o
+
+@
+<<FPS.lsp (LISP from IN)>>=
+${MID}/FPS.lsp: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/FPS.lsp from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FPS.NRLIB ; \
+ rm -rf ${OUT}/FPS.o ; \
+ ${SPADBIN}/notangle -R"FPS.lsp BOOTSTRAP" ${IN}/sf.spad.pamphlet >FPS.lsp )
+
+@
+<<RADCAT-.o (O from NRLIB)>>=
+${OUT}/RADCAT-.o: ${MID}/RADCAT.NRLIB
+ @ echo 0 making ${OUT}/RADCAT-.o from ${MID}/RADCAT-.NRLIB
+ @ cp ${MID}/RADCAT-.NRLIB/code.o ${OUT}/RADCAT-.o
+
+@
+<<RADCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/RADCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/RADCAT.spad
+ @ echo 0 making ${MID}/RADCAT-.NRLIB from ${MID}/RADCAT.spad
+ @ (cd ${MID} ; echo ')co RADCAT.spad' | ${INTERPSYS} )
+
+@
+<<RADCAT.o (O from NRLIB)>>=
+${OUT}/RADCAT.o: ${MID}/RADCAT.NRLIB
+ @ echo 0 making ${OUT}/RADCAT.o from ${MID}/RADCAT.NRLIB
+ @ cp ${MID}/RADCAT.NRLIB/code.o ${OUT}/RADCAT.o
+
+@
+<<RADCAT.NRLIB (NRLIB from MID)>>=
+${MID}/RADCAT.NRLIB: ${MID}/RADCAT.spad
+ @ echo 0 making ${MID}/RADCAT.NRLIB from ${MID}/RADCAT.spad
+ @ (cd ${MID} ; echo ')co RADCAT.spad' | ${INTERPSYS} )
+
+@
+<<RADCAT.spad (SPAD from IN)>>=
+${MID}/RADCAT.spad: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/RADCAT.spad from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RADCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RADCAT RadicalCategory" ${IN}/sf.spad.pamphlet >RADCAT.spad )
+
+@
+<<REAL.o (O from NRLIB)>>=
+${OUT}/REAL.o: ${MID}/REAL.NRLIB
+ @ echo 0 making ${OUT}/REAL.o from ${MID}/REAL.NRLIB
+ @ cp ${MID}/REAL.NRLIB/code.o ${OUT}/REAL.o
+
+@
+<<REAL.NRLIB (NRLIB from MID)>>=
+${MID}/REAL.NRLIB: ${OUT}/KONVERT.o ${MID}/REAL.spad
+ @ echo 0 making ${MID}/REAL.NRLIB from ${MID}/REAL.spad
+ @ (cd ${MID} ; echo ')co REAL.spad' | ${INTERPSYS} )
+
+@
+<<REAL.spad (SPAD from IN)>>=
+${MID}/REAL.spad: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/REAL.spad from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf REAL.NRLIB ; \
+ ${SPADBIN}/notangle -R"category REAL RealConstant" ${IN}/sf.spad.pamphlet >REAL.spad )
+
+@
+<<RNS-.o (O from NRLIB)>>=
+${OUT}/RNS-.o: ${MID}/RNS.NRLIB
+ @ echo 0 making ${OUT}/RNS-.o from ${MID}/RNS-.NRLIB
+ @ cp ${MID}/RNS-.NRLIB/code.o ${OUT}/RNS-.o
+
+@
+<<RNS-.NRLIB (NRLIB from MID)>>=
+${MID}/RNS-.NRLIB: ${OUT}/TYPE.o ${MID}/RNS.spad
+ @ echo 0 making ${MID}/RNS-.NRLIB from ${MID}/RNS.spad
+ @ (cd ${MID} ; echo ')co RNS.spad' | ${INTERPSYS} )
+
+@
+<<RNS.o (O from NRLIB)>>=
+${OUT}/RNS.o: ${MID}/RNS.NRLIB
+ @ echo 0 making ${OUT}/RNS.o from ${MID}/RNS.NRLIB
+ @ cp ${MID}/RNS.NRLIB/code.o ${OUT}/RNS.o
+
+@
+<<RNS.NRLIB (NRLIB from MID)>>=
+${MID}/RNS.NRLIB: ${MID}/RNS.spad
+ @ echo 0 making ${MID}/RNS.NRLIB from ${MID}/RNS.spad
+ @ (cd ${MID} ; echo ')co RNS.spad' | ${INTERPSYS} )
+
+@
+<<RNS.spad (SPAD from IN)>>=
+${MID}/RNS.spad: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/RNS.spad from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RNS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category RNS RealNumberSystem" ${IN}/sf.spad.pamphlet >RNS.spad )
+
+@
+<<RNS-.o (BOOTSTRAP from MID)>>=
+${MID}/RNS-.o: ${MID}/RNS-.lsp
+ @ echo 0 making ${MID}/RNS-.o from ${MID}/RNS-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RNS-.lsp" :output-file "RNS-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RNS-.o ${OUT}/RNS-.o
+
+@
+<<RNS-.lsp (LISP from IN)>>=
+${MID}/RNS-.lsp: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/RNS-.lsp from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RNS-.NRLIB ; \
+ rm -rf ${OUT}/RNS-.o ; \
+ ${SPADBIN}/notangle -R"RNS-.lsp BOOTSTRAP" ${IN}/sf.spad.pamphlet >RNS-.lsp )
+
+@
+<<RNS.o (BOOTSTRAP from MID)>>=
+${MID}/RNS.o: ${MID}/RNS.lsp
+ @ echo 0 making ${MID}/RNS.o from ${MID}/RNS.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "RNS.lsp" :output-file "RNS.o"))' | ${DEPSYS} )
+ @ cp ${MID}/RNS.o ${OUT}/RNS.o
+
+@
+<<RNS.lsp (LISP from IN)>>=
+${MID}/RNS.lsp: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${MID}/RNS.lsp from ${IN}/sf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RNS.NRLIB ; \
+ rm -rf ${OUT}/RNS.o ; \
+ ${SPADBIN}/notangle -R"RNS.lsp BOOTSTRAP" ${IN}/sf.spad.pamphlet >RNS.lsp )
+
+@
+<<sf.spad.dvi (DOC from IN)>>=
+${DOC}/sf.spad.dvi: ${IN}/sf.spad.pamphlet
+ @ echo 0 making ${DOC}/sf.spad.dvi from ${IN}/sf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sf.spad ; \
+ rm -f ${DOC}/sf.spad.pamphlet ; \
+ rm -f ${DOC}/sf.spad.tex ; \
+ rm -f ${DOC}/sf.spad )
+
+@
+\subsection{sgcf.spad \cite{1}}
+<<sgcf.spad (SPAD from IN)>>=
+${MID}/sgcf.spad: ${IN}/sgcf.spad.pamphlet
+ @ echo 0 making ${MID}/sgcf.spad from ${IN}/sgcf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sgcf.spad.pamphlet >sgcf.spad )
+
+@
+<<SGCF.o (O from NRLIB)>>=
+${OUT}/SGCF.o: ${MID}/SGCF.NRLIB
+ @ echo 0 making ${OUT}/SGCF.o from ${MID}/SGCF.NRLIB
+ @ cp ${MID}/SGCF.NRLIB/code.o ${OUT}/SGCF.o
+
+@
+<<SGCF.NRLIB (NRLIB from MID)>>=
+${MID}/SGCF.NRLIB: ${MID}/SGCF.spad
+ @ echo 0 making ${MID}/SGCF.NRLIB from ${MID}/SGCF.spad
+ @ (cd ${MID} ; echo ')co SGCF.spad' | ${INTERPSYS} )
+
+@
+<<SGCF.spad (SPAD from IN)>>=
+${MID}/SGCF.spad: ${IN}/sgcf.spad.pamphlet
+ @ echo 0 making ${MID}/SGCF.spad from ${IN}/sgcf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SGCF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SGCF SymmetricGroupCombinatoricFunctions" ${IN}/sgcf.spad.pamphlet >SGCF.spad )
+
+@
+<<sgcf.spad.dvi (DOC from IN)>>=
+${DOC}/sgcf.spad.dvi: ${IN}/sgcf.spad.pamphlet
+ @ echo 0 making ${DOC}/sgcf.spad.dvi from ${IN}/sgcf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sgcf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sgcf.spad ; \
+ rm -f ${DOC}/sgcf.spad.pamphlet ; \
+ rm -f ${DOC}/sgcf.spad.tex ; \
+ rm -f ${DOC}/sgcf.spad )
+
+@
+\subsection{sign.spad \cite{1}}
+<<sign.spad (SPAD from IN)>>=
+${MID}/sign.spad: ${IN}/sign.spad.pamphlet
+ @ echo 0 making ${MID}/sign.spad from ${IN}/sign.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sign.spad.pamphlet >sign.spad )
+
+@
+<<INPSIGN.o (O from NRLIB)>>=
+${OUT}/INPSIGN.o: ${MID}/INPSIGN.NRLIB
+ @ echo 0 making ${OUT}/INPSIGN.o from ${MID}/INPSIGN.NRLIB
+ @ cp ${MID}/INPSIGN.NRLIB/code.o ${OUT}/INPSIGN.o
+
+@
+<<INPSIGN.NRLIB (NRLIB from MID)>>=
+${MID}/INPSIGN.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/INPSIGN.spad
+ @ echo 0 making ${MID}/INPSIGN.NRLIB from ${MID}/INPSIGN.spad
+ @ (cd ${MID} ; echo ')co INPSIGN.spad' | ${INTERPSYS} )
+
+@
+<<INPSIGN.spad (SPAD from IN)>>=
+${MID}/INPSIGN.spad: ${IN}/sign.spad.pamphlet
+ @ echo 0 making ${MID}/INPSIGN.spad from ${IN}/sign.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INPSIGN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package INPSIGN InnerPolySign" ${IN}/sign.spad.pamphlet >INPSIGN.spad )
+
+@
+<<LIMITRF.o (O from NRLIB)>>=
+${OUT}/LIMITRF.o: ${MID}/LIMITRF.NRLIB
+ @ echo 0 making ${OUT}/LIMITRF.o from ${MID}/LIMITRF.NRLIB
+ @ cp ${MID}/LIMITRF.NRLIB/code.o ${OUT}/LIMITRF.o
+
+@
+<<LIMITRF.NRLIB (NRLIB from MID)>>=
+${MID}/LIMITRF.NRLIB: ${MID}/LIMITRF.spad
+ @ echo 0 making ${MID}/LIMITRF.NRLIB from ${MID}/LIMITRF.spad
+ @ (cd ${MID} ; echo ')co LIMITRF.spad' | ${INTERPSYS} )
+
+@
+<<LIMITRF.spad (SPAD from IN)>>=
+${MID}/LIMITRF.spad: ${IN}/sign.spad.pamphlet
+ @ echo 0 making ${MID}/LIMITRF.spad from ${IN}/sign.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIMITRF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LIMITRF RationalFunctionLimitPackage" ${IN}/sign.spad.pamphlet >LIMITRF.spad )
+
+@
+<<SIGNRF.o (O from NRLIB)>>=
+${OUT}/SIGNRF.o: ${MID}/SIGNRF.NRLIB
+ @ echo 0 making ${OUT}/SIGNRF.o from ${MID}/SIGNRF.NRLIB
+ @ cp ${MID}/SIGNRF.NRLIB/code.o ${OUT}/SIGNRF.o
+
+@
+<<SIGNRF.NRLIB (NRLIB from MID)>>=
+${MID}/SIGNRF.NRLIB: ${MID}/SIGNRF.spad
+ @ echo 0 making ${MID}/SIGNRF.NRLIB from ${MID}/SIGNRF.spad
+ @ (cd ${MID} ; echo ')co SIGNRF.spad' | ${INTERPSYS} )
+
+@
+<<SIGNRF.spad (SPAD from IN)>>=
+${MID}/SIGNRF.spad: ${IN}/sign.spad.pamphlet
+ @ echo 0 making ${MID}/SIGNRF.spad from ${IN}/sign.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SIGNRF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SIGNRF RationalFunctionSign" ${IN}/sign.spad.pamphlet >SIGNRF.spad )
+
+@
+<<TOOLSIGN.o (O from NRLIB)>>=
+${OUT}/TOOLSIGN.o: ${MID}/TOOLSIGN.NRLIB
+ @ echo 0 making ${OUT}/TOOLSIGN.o from ${MID}/TOOLSIGN.NRLIB
+ @ cp ${MID}/TOOLSIGN.NRLIB/code.o ${OUT}/TOOLSIGN.o
+
+@
+<<TOOLSIGN.NRLIB (NRLIB from MID)>>=
+${MID}/TOOLSIGN.NRLIB: ${MID}/TOOLSIGN.spad
+ @ echo 0 making ${MID}/TOOLSIGN.NRLIB from ${MID}/TOOLSIGN.spad
+ @ (cd ${MID} ; echo ')co TOOLSIGN.spad' | ${INTERPSYS} )
+
+@
+<<TOOLSIGN.spad (SPAD from IN)>>=
+${MID}/TOOLSIGN.spad: ${IN}/sign.spad.pamphlet
+ @ echo 0 making ${MID}/TOOLSIGN.spad from ${IN}/sign.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TOOLSIGN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TOOLSIGN ToolsForSign" ${IN}/sign.spad.pamphlet >TOOLSIGN.spad )
+
+@
+<<sign.spad.dvi (DOC from IN)>>=
+${DOC}/sign.spad.dvi: ${IN}/sign.spad.pamphlet
+ @ echo 0 making ${DOC}/sign.spad.dvi from ${IN}/sign.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sign.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sign.spad ; \
+ rm -f ${DOC}/sign.spad.pamphlet ; \
+ rm -f ${DOC}/sign.spad.tex ; \
+ rm -f ${DOC}/sign.spad )
+
+@
+\subsection{si.spad \cite{1}}
+<<si.spad (SPAD from IN)>>=
+${MID}/si.spad: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${MID}/si.spad from ${IN}/si.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/si.spad.pamphlet >si.spad )
+
+@
+<<SINT.o (O from NRLIB)>>=
+${OUT}/SINT.o: ${MID}/SINT.NRLIB
+ @ echo 0 making ${OUT}/SINT.o from ${MID}/SINT.NRLIB
+ @ cp ${MID}/SINT.NRLIB/code.o ${OUT}/SINT.o
+
+@
+<<SINT.NRLIB (NRLIB from MID)>>=
+${MID}/SINT.NRLIB: ${MID}/SINT.spad
+ @ echo 0 making ${MID}/SINT.NRLIB from ${MID}/SINT.spad
+ @ (cd ${MID} ; echo ')co SINT.spad' | ${INTERPSYS} )
+
+@
+<<SINT.spad (SPAD from IN)>>=
+${MID}/SINT.spad: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${MID}/SINT.spad from ${IN}/si.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SINT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SINT SingleInteger" ${IN}/si.spad.pamphlet >SINT.spad )
+
+@
+<<SINT.o (BOOTSTRAP from MID)>>=
+${MID}/SINT.o: ${MID}/SINT.lsp
+ @ echo 0 making ${MID}/SINT.o from ${MID}/SINT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "SINT.lsp" :output-file "SINT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/SINT.o ${OUT}/SINT.o
+
+@
+<<SINT.lsp (LISP from IN)>>=
+${MID}/SINT.lsp: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${MID}/SINT.lsp from ${IN}/si.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SINT.NRLIB ; \
+ rm -rf ${OUT}/SINT.o ; \
+ ${SPADBIN}/notangle -R"SINT.lsp BOOTSTRAP" ${IN}/si.spad.pamphlet >SINT.lsp )
+
+@
+<<INS-.o (O from NRLIB)>>=
+${OUT}/INS-.o: ${MID}/INS.NRLIB
+ @ echo 0 making ${OUT}/INS-.o from ${MID}/INS-.NRLIB
+ @ cp ${MID}/INS-.NRLIB/code.o ${OUT}/INS-.o
+
+@
+<<INS-.NRLIB (NRLIB from MID)>>=
+${MID}/INS-.NRLIB: ${OUT}/TYPE.o ${MID}/INS.spad
+ @ echo 0 making ${MID}/INS-.NRLIB from ${MID}/INS.spad
+ @ (cd ${MID} ; echo ')co INS.spad' | ${INTERPSYS} )
+
+@
+<<INS.o (O from NRLIB)>>=
+${OUT}/INS.o: ${MID}/INS.NRLIB
+ @ echo 0 making ${OUT}/INS.o from ${MID}/INS.NRLIB
+ @ cp ${MID}/INS.NRLIB/code.o ${OUT}/INS.o
+
+@
+<<INS.NRLIB (NRLIB from MID)>>=
+${MID}/INS.NRLIB: ${MID}/INS.spad
+ @ echo 0 making ${MID}/INS.NRLIB from ${MID}/INS.spad
+ @ (cd ${MID} ; echo ')co INS.spad' | ${INTERPSYS} )
+
+@
+<<INS.spad (SPAD from IN)>>=
+${MID}/INS.spad: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${MID}/INS.spad from ${IN}/si.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INS.NRLIB ; \
+ ${SPADBIN}/notangle -R"category INS IntegerNumberSystem" ${IN}/si.spad.pamphlet >INS.spad )
+
+@
+<<INS-.o (BOOTSTRAP from MID)>>=
+${MID}/INS-.o: ${MID}/INS-.lsp
+ @ echo 0 making ${MID}/INS-.o from ${MID}/INS-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "INS-.lsp" :output-file "INS-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/INS-.o ${OUT}/INS-.o
+
+@
+<<INS-.lsp (LISP from IN)>>=
+${MID}/INS-.lsp: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${MID}/INS-.lsp from ${IN}/si.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INS-.NRLIB ; \
+ rm -rf ${OUT}/INS-.o ; \
+ ${SPADBIN}/notangle -R"INS-.lsp BOOTSTRAP" ${IN}/si.spad.pamphlet >INS-.lsp )
+
+@
+<<INS.o (BOOTSTRAP from MID)>>=
+${MID}/INS.o: ${MID}/INS.lsp
+ @ echo 0 making ${MID}/INS.o from ${MID}/INS.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "INS.lsp" :output-file "INS.o"))' | ${DEPSYS} )
+ @ cp ${MID}/INS.o ${OUT}/INS.o
+
+@
+<<INS.lsp (LISP from IN)>>=
+${MID}/INS.lsp: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${MID}/INS.lsp from ${IN}/si.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INS.NRLIB ; \
+ rm -rf ${OUT}/INS.o ; \
+ ${SPADBIN}/notangle -R"INS.lsp BOOTSTRAP" ${IN}/si.spad.pamphlet >INS.lsp )
+
+@
+<<si.spad.dvi (DOC from IN)>>=
+${DOC}/si.spad.dvi: ${IN}/si.spad.pamphlet
+ @ echo 0 making ${DOC}/si.spad.dvi from ${IN}/si.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/si.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} si.spad ; \
+ rm -f ${DOC}/si.spad.pamphlet ; \
+ rm -f ${DOC}/si.spad.tex ; \
+ rm -f ${DOC}/si.spad )
+
+@
+\subsection{smith.spad \cite{1}}
+<<smith.spad (SPAD from IN)>>=
+${MID}/smith.spad: ${IN}/smith.spad.pamphlet
+ @ echo 0 making ${MID}/smith.spad from ${IN}/smith.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/smith.spad.pamphlet >smith.spad )
+
+@
+<<SMITH.o (O from NRLIB)>>=
+${OUT}/SMITH.o: ${MID}/SMITH.NRLIB
+ @ echo 0 making ${OUT}/SMITH.o from ${MID}/SMITH.NRLIB
+ @ cp ${MID}/SMITH.NRLIB/code.o ${OUT}/SMITH.o
+
+@
+<<SMITH.NRLIB (NRLIB from MID)>>=
+${MID}/SMITH.NRLIB: ${MID}/SMITH.spad
+ @ echo 0 making ${MID}/SMITH.NRLIB from ${MID}/SMITH.spad
+ @ (cd ${MID} ; echo ')co SMITH.spad' | ${INTERPSYS} )
+
+@
+<<SMITH.spad (SPAD from IN)>>=
+${MID}/SMITH.spad: ${IN}/smith.spad.pamphlet
+ @ echo 0 making ${MID}/SMITH.spad from ${IN}/smith.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SMITH.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SMITH SmithNormalForm" ${IN}/smith.spad.pamphlet >SMITH.spad )
+
+@
+<<smith.spad.dvi (DOC from IN)>>=
+${DOC}/smith.spad.dvi: ${IN}/smith.spad.pamphlet
+ @ echo 0 making ${DOC}/smith.spad.dvi from ${IN}/smith.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/smith.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} smith.spad ; \
+ rm -f ${DOC}/smith.spad.pamphlet ; \
+ rm -f ${DOC}/smith.spad.tex ; \
+ rm -f ${DOC}/smith.spad )
+
+@
+\subsection{solvedio.spad \cite{1}}
+<<solvedio.spad (SPAD from IN)>>=
+${MID}/solvedio.spad: ${IN}/solvedio.spad.pamphlet
+ @ echo 0 making ${MID}/solvedio.spad from ${IN}/solvedio.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/solvedio.spad.pamphlet >solvedio.spad )
+
+@
+<<DIOSP.o (O from NRLIB)>>=
+${OUT}/DIOSP.o: ${MID}/DIOSP.NRLIB
+ @ echo 0 making ${OUT}/DIOSP.o from ${MID}/DIOSP.NRLIB
+ @ cp ${MID}/DIOSP.NRLIB/code.o ${OUT}/DIOSP.o
+
+@
+<<DIOSP.NRLIB (NRLIB from MID)>>=
+${MID}/DIOSP.NRLIB: ${MID}/DIOSP.spad
+ @ echo 0 making ${MID}/DIOSP.NRLIB from ${MID}/DIOSP.spad
+ @ (cd ${MID} ; echo ')co DIOSP.spad' | ${INTERPSYS} )
+
+@
+<<DIOSP.spad (SPAD from IN)>>=
+${MID}/DIOSP.spad: ${IN}/solvedio.spad.pamphlet
+ @ echo 0 making ${MID}/DIOSP.spad from ${IN}/solvedio.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIOSP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DIOSP DiophantineSolutionPackage" ${IN}/solvedio.spad.pamphlet >DIOSP.spad )
+
+@
+<<solvedio.spad.dvi (DOC from IN)>>=
+${DOC}/solvedio.spad.dvi: ${IN}/solvedio.spad.pamphlet
+ @ echo 0 making ${DOC}/solvedio.spad.dvi from ${IN}/solvedio.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/solvedio.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} solvedio.spad ; \
+ rm -f ${DOC}/solvedio.spad.pamphlet ; \
+ rm -f ${DOC}/solvedio.spad.tex ; \
+ rm -f ${DOC}/solvedio.spad )
+
+@
+\subsection{solvefor.spad \cite{1}}
+<<solvefor.spad (SPAD from IN)>>=
+${MID}/solvefor.spad: ${IN}/solvefor.spad.pamphlet
+ @ echo 0 making ${MID}/solvefor.spad from ${IN}/solvefor.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/solvefor.spad.pamphlet >solvefor.spad )
+
+@
+<<SOLVEFOR.o (O from NRLIB)>>=
+${OUT}/SOLVEFOR.o: ${MID}/SOLVEFOR.NRLIB
+ @ echo 0 making ${OUT}/SOLVEFOR.o from ${MID}/SOLVEFOR.NRLIB
+ @ cp ${MID}/SOLVEFOR.NRLIB/code.o ${OUT}/SOLVEFOR.o
+
+@
+<<SOLVEFOR.NRLIB (NRLIB from MID)>>=
+${MID}/SOLVEFOR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SOLVEFOR.spad
+ @ echo 0 making ${MID}/SOLVEFOR.NRLIB from ${MID}/SOLVEFOR.spad
+ @ (cd ${MID} ; echo ')co SOLVEFOR.spad' | ${INTERPSYS} )
+
+@
+<<SOLVEFOR.spad (SPAD from IN)>>=
+${MID}/SOLVEFOR.spad: ${IN}/solvefor.spad.pamphlet
+ @ echo 0 making ${MID}/SOLVEFOR.spad from ${IN}/solvefor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SOLVEFOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SOLVEFOR PolynomialSolveByFormulas" ${IN}/solvefor.spad.pamphlet >SOLVEFOR.spad )
+
+@
+<<solvefor.spad.dvi (DOC from IN)>>=
+${DOC}/solvefor.spad.dvi: ${IN}/solvefor.spad.pamphlet
+ @ echo 0 making ${DOC}/solvefor.spad.dvi from ${IN}/solvefor.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/solvefor.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} solvefor.spad ; \
+ rm -f ${DOC}/solvefor.spad.pamphlet ; \
+ rm -f ${DOC}/solvefor.spad.tex ; \
+ rm -f ${DOC}/solvefor.spad )
+
+@
+\subsection{solvelin.spad \cite{1}}
+<<solvelin.spad (SPAD from IN)>>=
+${MID}/solvelin.spad: ${IN}/solvelin.spad.pamphlet
+ @ echo 0 making ${MID}/solvelin.spad from ${IN}/solvelin.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/solvelin.spad.pamphlet >solvelin.spad )
+
+@
+<<LSMP.o (O from NRLIB)>>=
+${OUT}/LSMP.o: ${MID}/LSMP.NRLIB
+ @ echo 0 making ${OUT}/LSMP.o from ${MID}/LSMP.NRLIB
+ @ cp ${MID}/LSMP.NRLIB/code.o ${OUT}/LSMP.o
+
+@
+<<LSMP.NRLIB (NRLIB from MID)>>=
+${MID}/LSMP.NRLIB: ${MID}/LSMP.spad
+ @ echo 0 making ${MID}/LSMP.NRLIB from ${MID}/LSMP.spad
+ @ (cd ${MID} ; echo ')co LSMP.spad' | ${INTERPSYS} )
+
+@
+<<LSMP.spad (SPAD from IN)>>=
+${MID}/LSMP.spad: ${IN}/solvelin.spad.pamphlet
+ @ echo 0 making ${MID}/LSMP.spad from ${IN}/solvelin.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LSMP LinearSystemMatrixPackage" ${IN}/solvelin.spad.pamphlet >LSMP.spad )
+
+@
+<<LSMP1.o (O from NRLIB)>>=
+${OUT}/LSMP1.o: ${MID}/LSMP1.NRLIB
+ @ echo 0 making ${OUT}/LSMP1.o from ${MID}/LSMP1.NRLIB
+ @ cp ${MID}/LSMP1.NRLIB/code.o ${OUT}/LSMP1.o
+
+@
+<<LSMP1.NRLIB (NRLIB from MID)>>=
+${MID}/LSMP1.NRLIB: ${MID}/LSMP1.spad
+ @ echo 0 making ${MID}/LSMP1.NRLIB from ${MID}/LSMP1.spad
+ @ (cd ${MID} ; echo ')co LSMP1.spad' | ${INTERPSYS} )
+
+@
+<<LSMP1.spad (SPAD from IN)>>=
+${MID}/LSMP1.spad: ${IN}/solvelin.spad.pamphlet
+ @ echo 0 making ${MID}/LSMP1.spad from ${IN}/solvelin.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSMP1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LSMP1 LinearSystemMatrixPackage1" ${IN}/solvelin.spad.pamphlet >LSMP1.spad )
+
+@
+<<LSPP.o (O from NRLIB)>>=
+${OUT}/LSPP.o: ${MID}/LSPP.NRLIB
+ @ echo 0 making ${OUT}/LSPP.o from ${MID}/LSPP.NRLIB
+ @ cp ${MID}/LSPP.NRLIB/code.o ${OUT}/LSPP.o
+
+@
+<<LSPP.NRLIB (NRLIB from MID)>>=
+${MID}/LSPP.NRLIB: ${MID}/LSPP.spad
+ @ echo 0 making ${MID}/LSPP.NRLIB from ${MID}/LSPP.spad
+ @ (cd ${MID} ; echo ')co LSPP.spad' | ${INTERPSYS} )
+
+@
+<<LSPP.spad (SPAD from IN)>>=
+${MID}/LSPP.spad: ${IN}/solvelin.spad.pamphlet
+ @ echo 0 making ${MID}/LSPP.spad from ${IN}/solvelin.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LSPP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package LSPP LinearSystemPolynomialPackage" ${IN}/solvelin.spad.pamphlet >LSPP.spad )
+
+@
+<<solvelin.spad.dvi (DOC from IN)>>=
+${DOC}/solvelin.spad.dvi: ${IN}/solvelin.spad.pamphlet
+ @ echo 0 making ${DOC}/solvelin.spad.dvi from ${IN}/solvelin.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/solvelin.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} solvelin.spad ; \
+ rm -f ${DOC}/solvelin.spad.pamphlet ; \
+ rm -f ${DOC}/solvelin.spad.tex ; \
+ rm -f ${DOC}/solvelin.spad )
+
+@
+\subsection{solverad.spad \cite{1}}
+<<solverad.spad (SPAD from IN)>>=
+${MID}/solverad.spad: ${IN}/solverad.spad.pamphlet
+ @ echo 0 making ${MID}/solverad.spad from ${IN}/solverad.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/solverad.spad.pamphlet >solverad.spad )
+
+@
+<<SOLVERAD.o (O from NRLIB)>>=
+${OUT}/SOLVERAD.o: ${MID}/SOLVERAD.NRLIB
+ @ echo 0 making ${OUT}/SOLVERAD.o from ${MID}/SOLVERAD.NRLIB
+ @ cp ${MID}/SOLVERAD.NRLIB/code.o ${OUT}/SOLVERAD.o
+
+@
+<<SOLVERAD.NRLIB (NRLIB from MID)>>=
+${MID}/SOLVERAD.NRLIB: ${MID}/SOLVERAD.spad
+ @ echo 0 making ${MID}/SOLVERAD.NRLIB from ${MID}/SOLVERAD.spad
+ @ (cd ${MID} ; echo ')co SOLVERAD.spad' | ${INTERPSYS} )
+
+@
+<<SOLVERAD.spad (SPAD from IN)>>=
+${MID}/SOLVERAD.spad: ${IN}/solverad.spad.pamphlet
+ @ echo 0 making ${MID}/SOLVERAD.spad from ${IN}/solverad.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SOLVERAD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SOLVERAD RadicalSolvePackage" ${IN}/solverad.spad.pamphlet >SOLVERAD.spad )
+
+@
+<<solverad.spad.dvi (DOC from IN)>>=
+${DOC}/solverad.spad.dvi: ${IN}/solverad.spad.pamphlet
+ @ echo 0 making ${DOC}/solverad.spad.dvi from ${IN}/solverad.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/solverad.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} solverad.spad ; \
+ rm -f ${DOC}/solverad.spad.pamphlet ; \
+ rm -f ${DOC}/solverad.spad.tex ; \
+ rm -f ${DOC}/solverad.spad )
+
+@
+\subsection{sortpak.spad \cite{1}}
+<<sortpak.spad (SPAD from IN)>>=
+${MID}/sortpak.spad: ${IN}/sortpak.spad.pamphlet
+ @ echo 0 making ${MID}/sortpak.spad from ${IN}/sortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sortpak.spad.pamphlet >sortpak.spad )
+
+@
+<<SORTPAK.o (O from NRLIB)>>=
+${OUT}/SORTPAK.o: ${MID}/SORTPAK.NRLIB
+ @ echo 0 making ${OUT}/SORTPAK.o from ${MID}/SORTPAK.NRLIB
+ @ cp ${MID}/SORTPAK.NRLIB/code.o ${OUT}/SORTPAK.o
+
+@
+<<SORTPAK.NRLIB (NRLIB from MID)>>=
+${MID}/SORTPAK.NRLIB: ${MID}/SORTPAK.spad
+ @ echo 0 making ${MID}/SORTPAK.NRLIB from ${MID}/SORTPAK.spad
+ @ (cd ${MID} ; echo ')co SORTPAK.spad' | ${INTERPSYS} )
+
+@
+<<SORTPAK.spad (SPAD from IN)>>=
+${MID}/SORTPAK.spad: ${IN}/sortpak.spad.pamphlet
+ @ echo 0 making ${MID}/SORTPAK.spad from ${IN}/sortpak.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SORTPAK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SORTPAK SortPackage" ${IN}/sortpak.spad.pamphlet >SORTPAK.spad )
+
+@
+<<sortpak.spad.dvi (DOC from IN)>>=
+${DOC}/sortpak.spad.dvi: ${IN}/sortpak.spad.pamphlet
+ @ echo 0 making ${DOC}/sortpak.spad.dvi from ${IN}/sortpak.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sortpak.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sortpak.spad ; \
+ rm -f ${DOC}/sortpak.spad.pamphlet ; \
+ rm -f ${DOC}/sortpak.spad.tex ; \
+ rm -f ${DOC}/sortpak.spad )
+
+@
+\subsection{space.spad \cite{1}}
+<<space.spad (SPAD from IN)>>=
+${MID}/space.spad: ${IN}/space.spad.pamphlet
+ @ echo 0 making ${MID}/space.spad from ${IN}/space.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/space.spad.pamphlet >space.spad )
+
+@
+<<SPACEC.o (O from NRLIB)>>=
+${OUT}/SPACEC.o: ${MID}/SPACEC.NRLIB
+ @ echo 0 making ${OUT}/SPACEC.o from ${MID}/SPACEC.NRLIB
+ @ cp ${MID}/SPACEC.NRLIB/code.o ${OUT}/SPACEC.o
+
+@
+<<SPACEC.NRLIB (NRLIB from MID)>>=
+${MID}/SPACEC.NRLIB: ${MID}/SPACEC.spad
+ @ echo 0 making ${MID}/SPACEC.NRLIB from ${MID}/SPACEC.spad
+ @ (cd ${MID} ; echo ')co SPACEC.spad' | ${INTERPSYS} )
+
+@
+<<SPACEC.spad (SPAD from IN)>>=
+${MID}/SPACEC.spad: ${IN}/space.spad.pamphlet
+ @ echo 0 making ${MID}/SPACEC.spad from ${IN}/space.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SPACEC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SPACEC ThreeSpaceCategory" ${IN}/space.spad.pamphlet >SPACEC.spad )
+
+@
+<<SPACE3.o (O from NRLIB)>>=
+${OUT}/SPACE3.o: ${MID}/SPACE3.NRLIB
+ @ echo 0 making ${OUT}/SPACE3.o from ${MID}/SPACE3.NRLIB
+ @ cp ${MID}/SPACE3.NRLIB/code.o ${OUT}/SPACE3.o
+
+@
+<<SPACE3.NRLIB (NRLIB from MID)>>=
+${MID}/SPACE3.NRLIB: ${MID}/SPACE3.spad
+ @ echo 0 making ${MID}/SPACE3.NRLIB from ${MID}/SPACE3.spad
+ @ (cd ${MID} ; echo ')co SPACE3.spad' | ${INTERPSYS} )
+
+@
+<<SPACE3.spad (SPAD from IN)>>=
+${MID}/SPACE3.spad: ${IN}/space.spad.pamphlet
+ @ echo 0 making ${MID}/SPACE3.spad from ${IN}/space.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SPACE3.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SPACE3 ThreeSpace" ${IN}/space.spad.pamphlet >SPACE3.spad )
+
+@
+<<TOPSP.o (O from NRLIB)>>=
+${OUT}/TOPSP.o: ${MID}/TOPSP.NRLIB
+ @ echo 0 making ${OUT}/TOPSP.o from ${MID}/TOPSP.NRLIB
+ @ cp ${MID}/TOPSP.NRLIB/code.o ${OUT}/TOPSP.o
+
+@
+<<TOPSP.NRLIB (NRLIB from MID)>>=
+${MID}/TOPSP.NRLIB: ${MID}/TOPSP.spad
+ @ echo 0 making ${MID}/TOPSP.NRLIB from ${MID}/TOPSP.spad
+ @ (cd ${MID} ; echo ')co TOPSP.spad' | ${INTERPSYS} )
+
+@
+<<TOPSP.spad (SPAD from IN)>>=
+${MID}/TOPSP.spad: ${IN}/space.spad.pamphlet
+ @ echo 0 making ${MID}/TOPSP.spad from ${IN}/space.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TOPSP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TOPSP TopLevelThreeSpace" ${IN}/space.spad.pamphlet >TOPSP.spad )
+
+@
+<<space.spad.dvi (DOC from IN)>>=
+${DOC}/space.spad.dvi: ${IN}/space.spad.pamphlet
+ @ echo 0 making ${DOC}/space.spad.dvi from ${IN}/space.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/space.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} space.spad ; \
+ rm -f ${DOC}/space.spad.pamphlet ; \
+ rm -f ${DOC}/space.spad.tex ; \
+ rm -f ${DOC}/space.spad )
+
+@
+\subsection{special.spad \cite{1}}
+<<special.spad (SPAD from IN)>>=
+${MID}/special.spad: ${IN}/special.spad.pamphlet
+ @ echo 0 making ${MID}/special.spad from ${IN}/special.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/special.spad.pamphlet >special.spad )
+
+@
+<<DFSFUN.o (O from NRLIB)>>=
+${OUT}/DFSFUN.o: ${MID}/DFSFUN.NRLIB
+ @ echo 0 making ${OUT}/DFSFUN.o from ${MID}/DFSFUN.NRLIB
+ @ cp ${MID}/DFSFUN.NRLIB/code.o ${OUT}/DFSFUN.o
+
+@
+<<DFSFUN.NRLIB (NRLIB from MID)>>=
+${MID}/DFSFUN.NRLIB: ${MID}/DFSFUN.spad
+ @ echo 0 making ${MID}/DFSFUN.NRLIB from ${MID}/DFSFUN.spad
+ @ (cd ${MID} ; echo ')co DFSFUN.spad' | ${INTERPSYS} )
+
+@
+<<DFSFUN.spad (SPAD from IN)>>=
+${MID}/DFSFUN.spad: ${IN}/special.spad.pamphlet
+ @ echo 0 making ${MID}/DFSFUN.spad from ${IN}/special.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DFSFUN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DFSFUN DoubleFloatSpecialFunctions" ${IN}/special.spad.pamphlet >DFSFUN.spad )
+
+@
+<<NTPOLFN.o (O from NRLIB)>>=
+${OUT}/NTPOLFN.o: ${MID}/NTPOLFN.NRLIB
+ @ echo 0 making ${OUT}/NTPOLFN.o from ${MID}/NTPOLFN.NRLIB
+ @ cp ${MID}/NTPOLFN.NRLIB/code.o ${OUT}/NTPOLFN.o
+
+@
+<<NTPOLFN.NRLIB (NRLIB from MID)>>=
+${MID}/NTPOLFN.NRLIB: ${MID}/NTPOLFN.spad
+ @ echo 0 making ${MID}/NTPOLFN.NRLIB from ${MID}/NTPOLFN.spad
+ @ (cd ${MID} ; echo ')co NTPOLFN.spad' | ${INTERPSYS} )
+
+@
+<<NTPOLFN.spad (SPAD from IN)>>=
+${MID}/NTPOLFN.spad: ${IN}/special.spad.pamphlet
+ @ echo 0 making ${MID}/NTPOLFN.spad from ${IN}/special.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NTPOLFN.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NTPOLFN NumberTheoreticPolynomialFunctions" ${IN}/special.spad.pamphlet >NTPOLFN.spad )
+
+@
+<<ORTHPOL.o (O from NRLIB)>>=
+${OUT}/ORTHPOL.o: ${MID}/ORTHPOL.NRLIB
+ @ echo 0 making ${OUT}/ORTHPOL.o from ${MID}/ORTHPOL.NRLIB
+ @ cp ${MID}/ORTHPOL.NRLIB/code.o ${OUT}/ORTHPOL.o
+
+@
+<<ORTHPOL.NRLIB (NRLIB from MID)>>=
+${MID}/ORTHPOL.NRLIB: ${MID}/ORTHPOL.spad
+ @ echo 0 making ${MID}/ORTHPOL.NRLIB from ${MID}/ORTHPOL.spad
+ @ (cd ${MID} ; echo ')co ORTHPOL.spad' | ${INTERPSYS} )
+
+@
+<<ORTHPOL.spad (SPAD from IN)>>=
+${MID}/ORTHPOL.spad: ${IN}/special.spad.pamphlet
+ @ echo 0 making ${MID}/ORTHPOL.spad from ${IN}/special.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ORTHPOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ORTHPOL OrthogonalPolynomialFunctions" ${IN}/special.spad.pamphlet >ORTHPOL.spad )
+
+@
+<<special.spad.dvi (DOC from IN)>>=
+${DOC}/special.spad.dvi: ${IN}/special.spad.pamphlet
+ @ echo 0 making ${DOC}/special.spad.dvi from ${IN}/special.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/special.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} special.spad ; \
+ rm -f ${DOC}/special.spad.pamphlet ; \
+ rm -f ${DOC}/special.spad.tex ; \
+ rm -f ${DOC}/special.spad )
+
+@
+\subsection{sregset.spad \cite{1}}
+<<sregset.spad (SPAD from IN)>>=
+${MID}/sregset.spad: ${IN}/sregset.spad.pamphlet
+ @ echo 0 making ${MID}/sregset.spad from ${IN}/sregset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sregset.spad.pamphlet >sregset.spad )
+
+@
+<<sregset.spad.dvi (DOC from IN)>>=
+${DOC}/sregset.spad.dvi: ${IN}/sregset.spad.pamphlet
+ @ echo 0 making ${DOC}/sregset.spad.dvi from ${IN}/sregset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sregset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sregset.spad ; \
+ rm -f ${DOC}/sregset.spad.pamphlet ; \
+ rm -f ${DOC}/sregset.spad.tex ; \
+ rm -f ${DOC}/sregset.spad )
+
+@
+\subsection{s.spad \cite{1}}
+<<s.spad (SPAD from IN)>>=
+${MID}/s.spad: ${IN}/s.spad.pamphlet
+ @ echo 0 making ${MID}/s.spad from ${IN}/s.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/s.spad.pamphlet >s.spad )
+
+@
+<<NAGS.o (O from NRLIB)>>=
+${OUT}/NAGS.o: ${MID}/NAGS.NRLIB
+ @ echo 0 making ${OUT}/NAGS.o from ${MID}/NAGS.NRLIB
+ @ cp ${MID}/NAGS.NRLIB/code.o ${OUT}/NAGS.o
+
+@
+<<NAGS.NRLIB (NRLIB from MID)>>=
+${MID}/NAGS.NRLIB: ${MID}/NAGS.spad
+ @ echo 0 making ${MID}/NAGS.NRLIB from ${MID}/NAGS.spad
+ @ (cd ${MID} ; echo ')co NAGS.spad' | ${INTERPSYS} )
+
+@
+<<NAGS.spad (SPAD from IN)>>=
+${MID}/NAGS.spad: ${IN}/s.spad.pamphlet
+ @ echo 0 making ${MID}/NAGS.spad from ${IN}/s.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NAGS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NAGS NagSpecialFunctionsPackage" ${IN}/s.spad.pamphlet >NAGS.spad )
+
+@
+<<s.spad.dvi (DOC from IN)>>=
+${DOC}/s.spad.dvi: ${IN}/s.spad.pamphlet
+ @ echo 0 making ${DOC}/s.spad.dvi from ${IN}/s.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/s.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} s.spad ; \
+ rm -f ${DOC}/s.spad.pamphlet ; \
+ rm -f ${DOC}/s.spad.tex ; \
+ rm -f ${DOC}/s.spad )
+
+@
+\subsection{stream.spad \cite{1}}
+<<stream.spad (SPAD from IN)>>=
+${MID}/stream.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/stream.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/stream.spad.pamphlet >stream.spad )
+
+@
+<<CSTTOOLS.o (O from NRLIB)>>=
+${OUT}/CSTTOOLS.o: ${MID}/CSTTOOLS.NRLIB
+ @ echo 0 making ${OUT}/CSTTOOLS.o from ${MID}/CSTTOOLS.NRLIB
+ @ cp ${MID}/CSTTOOLS.NRLIB/code.o ${OUT}/CSTTOOLS.o
+
+@
+<<CSTTOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/CSTTOOLS.NRLIB: ${MID}/CSTTOOLS.spad
+ @ echo 0 making ${MID}/CSTTOOLS.NRLIB from ${MID}/CSTTOOLS.spad
+ @ (cd ${MID} ; echo ')co CSTTOOLS.spad' | ${INTERPSYS} )
+
+@
+<<CSTTOOLS.spad (SPAD from IN)>>=
+${MID}/CSTTOOLS.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/CSTTOOLS.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CSTTOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package CSTTOOLS CyclicStreamTools" ${IN}/stream.spad.pamphlet >CSTTOOLS.spad )
+
+@
+<<LZSTAGG-.o (O from NRLIB)>>=
+${OUT}/LZSTAGG-.o: ${MID}/LZSTAGG.NRLIB
+ @ echo 0 making ${OUT}/LZSTAGG-.o from ${MID}/LZSTAGG-.NRLIB
+ @ cp ${MID}/LZSTAGG-.NRLIB/code.o ${OUT}/LZSTAGG-.o
+
+@
+<<LZSTAGG-.NRLIB (NRLIB from MID)>>=
+${MID}/LZSTAGG-.NRLIB: ${OUT}/TYPE.o ${MID}/LZSTAGG.spad
+ @ echo 0 making ${MID}/LZSTAGG-.NRLIB from ${MID}/LZSTAGG.spad
+ @ (cd ${MID} ; echo ')co LZSTAGG.spad' | ${INTERPSYS} )
+
+@
+<<LZSTAGG.o (O from NRLIB)>>=
+${OUT}/LZSTAGG.o: ${MID}/LZSTAGG.NRLIB
+ @ echo 0 making ${OUT}/LZSTAGG.o from ${MID}/LZSTAGG.NRLIB
+ @ cp ${MID}/LZSTAGG.NRLIB/code.o ${OUT}/LZSTAGG.o
+
+@
+<<LZSTAGG.NRLIB (NRLIB from MID)>>=
+${MID}/LZSTAGG.NRLIB: ${MID}/LZSTAGG.spad
+ @ echo 0 making ${MID}/LZSTAGG.NRLIB from ${MID}/LZSTAGG.spad
+ @ (cd ${MID} ; echo ')co LZSTAGG.spad' | ${INTERPSYS} )
+
+@
+<<LZSTAGG.spad (SPAD from IN)>>=
+${MID}/LZSTAGG.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/LZSTAGG.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LZSTAGG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LZSTAGG LazyStreamAggregate" ${IN}/stream.spad.pamphlet >LZSTAGG.spad )
+
+@
+<<STREAM.o (O from NRLIB)>>=
+${OUT}/STREAM.o: ${MID}/STREAM.NRLIB
+ @ echo 0 making ${OUT}/STREAM.o from ${MID}/STREAM.NRLIB
+ @ cp ${MID}/STREAM.NRLIB/code.o ${OUT}/STREAM.o
+
+@
+<<STREAM.NRLIB (NRLIB from MID)>>=
+${MID}/STREAM.NRLIB: ${MID}/STREAM.spad
+ @ echo 0 making ${MID}/STREAM.NRLIB from ${MID}/STREAM.spad
+ @ (cd ${MID} ; echo ')co STREAM.spad' | ${INTERPSYS} )
+
+@
+<<STREAM.spad (SPAD from IN)>>=
+${MID}/STREAM.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/STREAM.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STREAM.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain STREAM Stream" ${IN}/stream.spad.pamphlet >STREAM.spad )
+
+@
+<<STREAM1.o (O from NRLIB)>>=
+${OUT}/STREAM1.o: ${MID}/STREAM1.NRLIB
+ @ echo 0 making ${OUT}/STREAM1.o from ${MID}/STREAM1.NRLIB
+ @ cp ${MID}/STREAM1.NRLIB/code.o ${OUT}/STREAM1.o
+
+@
+<<STREAM1.NRLIB (NRLIB from MID)>>=
+${MID}/STREAM1.NRLIB: ${OUT}/TYPE.o ${MID}/STREAM1.spad
+ @ echo 0 making ${MID}/STREAM1.NRLIB from ${MID}/STREAM1.spad
+ @ (cd ${MID} ; echo ')co STREAM1.spad' | ${INTERPSYS} )
+
+@
+<<STREAM1.spad (SPAD from IN)>>=
+${MID}/STREAM1.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/STREAM1.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STREAM1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STREAM1 StreamFunctions1" ${IN}/stream.spad.pamphlet >STREAM1.spad )
+
+@
+<<STREAM2.o (O from NRLIB)>>=
+${OUT}/STREAM2.o: ${MID}/STREAM2.NRLIB
+ @ echo 0 making ${OUT}/STREAM2.o from ${MID}/STREAM2.NRLIB
+ @ cp ${MID}/STREAM2.NRLIB/code.o ${OUT}/STREAM2.o
+
+@
+<<STREAM2.NRLIB (NRLIB from MID)>>=
+${MID}/STREAM2.NRLIB: ${OUT}/TYPE.o ${MID}/STREAM2.spad
+ @ echo 0 making ${MID}/STREAM2.NRLIB from ${MID}/STREAM2.spad
+ @ (cd ${MID} ; echo ')co STREAM2.spad' | ${INTERPSYS} )
+
+@
+<<STREAM2.spad (SPAD from IN)>>=
+${MID}/STREAM2.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/STREAM2.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STREAM2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STREAM2 StreamFunctions2" ${IN}/stream.spad.pamphlet >STREAM2.spad )
+
+@
+<<STREAM3.o (O from NRLIB)>>=
+${OUT}/STREAM3.o: ${MID}/STREAM3.NRLIB
+ @ echo 0 making ${OUT}/STREAM3.o from ${MID}/STREAM3.NRLIB
+ @ cp ${MID}/STREAM3.NRLIB/code.o ${OUT}/STREAM3.o
+
+@
+<<STREAM3.NRLIB (NRLIB from MID)>>=
+${MID}/STREAM3.NRLIB: ${OUT}/TYPE.o ${MID}/STREAM3.spad
+ @ echo 0 making ${MID}/STREAM3.NRLIB from ${MID}/STREAM3.spad
+ @ (cd ${MID} ; echo ')co STREAM3.spad' | ${INTERPSYS} )
+
+@
+<<STREAM3.spad (SPAD from IN)>>=
+${MID}/STREAM3.spad: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${MID}/STREAM3.spad from ${IN}/stream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STREAM3.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STREAM3 StreamFunctions3" ${IN}/stream.spad.pamphlet >STREAM3.spad )
+
+@
+<<stream.spad.dvi (DOC from IN)>>=
+${DOC}/stream.spad.dvi: ${IN}/stream.spad.pamphlet
+ @ echo 0 making ${DOC}/stream.spad.dvi from ${IN}/stream.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/stream.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} stream.spad ; \
+ rm -f ${DOC}/stream.spad.pamphlet ; \
+ rm -f ${DOC}/stream.spad.tex ; \
+ rm -f ${DOC}/stream.spad )
+
+@
+\subsection{string.spad \cite{1}}
+<<string.spad (SPAD from IN)>>=
+${MID}/string.spad: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/string.spad from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/string.spad.pamphlet >string.spad )
+
+@
+<<CCLASS.o (O from NRLIB)>>=
+${OUT}/CCLASS.o: ${MID}/CCLASS.NRLIB
+ @ echo 0 making ${OUT}/CCLASS.o from ${MID}/CCLASS.NRLIB
+ @ cp ${MID}/CCLASS.NRLIB/code.o ${OUT}/CCLASS.o
+
+@
+<<CCLASS.NRLIB (NRLIB from MID)>>=
+${MID}/CCLASS.NRLIB: ${MID}/CCLASS.spad
+ @ echo 0 making ${MID}/CCLASS.NRLIB from ${MID}/CCLASS.spad
+ @ (cd ${MID} ; echo ')co CCLASS.spad' | ${INTERPSYS} )
+
+@
+<<CCLASS.spad (SPAD from IN)>>=
+${MID}/CCLASS.spad: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/CCLASS.spad from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CCLASS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain CCLASS CharacterClass" ${IN}/string.spad.pamphlet >CCLASS.spad )
+
+@
+<<CHAR.o (O from NRLIB)>>=
+${OUT}/CHAR.o: ${MID}/CHAR.NRLIB
+ @ echo 0 making ${OUT}/CHAR.o from ${MID}/CHAR.NRLIB
+ @ cp ${MID}/CHAR.NRLIB/code.o ${OUT}/CHAR.o
+
+@
+<<CHAR.NRLIB (NRLIB from MID)>>=
+${MID}/CHAR.NRLIB: ${MID}/CHAR.spad
+ @ echo 0 making ${MID}/CHAR.NRLIB from ${MID}/CHAR.spad
+ @ (cd ${MID} ; echo ')co CHAR.spad' | ${INTERPSYS} )
+
+@
+<<CHAR.spad (SPAD from IN)>>=
+${MID}/CHAR.spad: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/CHAR.spad from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CHAR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain CHAR Character" ${IN}/string.spad.pamphlet >CHAR.spad )
+
+@
+<<CHAR.o (BOOTSTRAP from MID)>>=
+${MID}/CHAR.o: ${MID}/CHAR.lsp
+ @ echo 0 making ${MID}/CHAR.o from ${MID}/CHAR.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "CHAR.lsp" :output-file "CHAR.o"))' | ${DEPSYS} )
+ @ cp ${MID}/CHAR.o ${OUT}/CHAR.o
+
+@
+<<CHAR.lsp (LISP from IN)>>=
+${MID}/CHAR.lsp: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/CHAR.lsp from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CHAR.NRLIB ; \
+ rm -rf ${OUT}/CHAR.o ; \
+ ${SPADBIN}/notangle -R"CHAR.lsp BOOTSTRAP" ${IN}/string.spad.pamphlet >CHAR.lsp )
+
+@
+<<ISTRING.o (O from NRLIB)>>=
+${OUT}/ISTRING.o: ${MID}/ISTRING.NRLIB
+ @ echo 0 making ${OUT}/ISTRING.o from ${MID}/ISTRING.NRLIB
+ @ cp ${MID}/ISTRING.NRLIB/code.o ${OUT}/ISTRING.o
+
+@
+<<ISTRING.NRLIB (NRLIB from MID)>>=
+${MID}/ISTRING.NRLIB: ${MID}/ISTRING.spad
+ @ echo 0 making ${MID}/ISTRING.NRLIB from ${MID}/ISTRING.spad
+ @ (cd ${MID} ; echo ')co ISTRING.spad' | ${INTERPSYS} )
+
+@
+<<ISTRING.spad (SPAD from IN)>>=
+${MID}/ISTRING.spad: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/ISTRING.spad from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ISTRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ISTRING IndexedString" ${IN}/string.spad.pamphlet >ISTRING.spad )
+
+@
+<<ISTRING.o (BOOTSTRAP from MID)>>=
+${MID}/ISTRING.o: ${MID}/ISTRING.lsp
+ @ echo 0 making ${MID}/ISTRING.o from ${MID}/ISTRING.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "ISTRING.lsp" :output-file "ISTRING.o"))' | ${DEPSYS} )
+ @ cp ${MID}/ISTRING.o ${OUT}/ISTRING.o
+
+@
+<<ISTRING.lsp (LISP from IN)>>=
+${MID}/ISTRING.lsp: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/ISTRING.lsp from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ISTRING.NRLIB ; \
+ rm -rf ${OUT}/ISTRING.o ; \
+ ${SPADBIN}/notangle -R"ISTRING.lsp BOOTSTRAP" ${IN}/string.spad.pamphlet >ISTRING.lsp )
+
+@
+<<STRICAT.o (O from NRLIB)>>=
+${OUT}/STRICAT.o: ${MID}/STRICAT.NRLIB
+ @ echo 0 making ${OUT}/STRICAT.o from ${MID}/STRICAT.NRLIB
+ @ cp ${MID}/STRICAT.NRLIB/code.o ${OUT}/STRICAT.o
+
+@
+<<STRICAT.NRLIB (NRLIB from MID)>>=
+${MID}/STRICAT.NRLIB: ${MID}/STRICAT.spad
+ @ echo 0 making ${MID}/STRICAT.NRLIB from ${MID}/STRICAT.spad
+ @ (cd ${MID} ; echo ')co STRICAT.spad' | ${INTERPSYS} )
+
+@
+<<STRICAT.spad (SPAD from IN)>>=
+${MID}/STRICAT.spad: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/STRICAT.spad from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STRICAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category STRICAT StringCategory" ${IN}/string.spad.pamphlet >STRICAT.spad )
+
+@
+<<STRING.o (O from NRLIB)>>=
+${OUT}/STRING.o: ${MID}/STRING.NRLIB
+ @ echo 0 making ${OUT}/STRING.o from ${MID}/STRING.NRLIB
+ @ cp ${MID}/STRING.NRLIB/code.o ${OUT}/STRING.o
+
+@
+<<STRING.NRLIB (NRLIB from MID)>>=
+${MID}/STRING.NRLIB: ${MID}/STRING.spad
+ @ echo 0 making ${MID}/STRING.NRLIB from ${MID}/STRING.spad
+ @ (cd ${MID} ; echo ')co STRING.spad' | ${INTERPSYS} )
+
+@
+<<STRING.spad (SPAD from IN)>>=
+${MID}/STRING.spad: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${MID}/STRING.spad from ${IN}/string.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STRING.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain STRING String" ${IN}/string.spad.pamphlet >STRING.spad )
+
+@
+<<string.spad.dvi (DOC from IN)>>=
+${DOC}/string.spad.dvi: ${IN}/string.spad.pamphlet
+ @ echo 0 making ${DOC}/string.spad.dvi from ${IN}/string.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/string.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} string.spad ; \
+ rm -f ${DOC}/string.spad.pamphlet ; \
+ rm -f ${DOC}/string.spad.tex ; \
+ rm -f ${DOC}/string.spad )
+
+@
+\subsection{sttaylor.spad \cite{1}}
+<<sttaylor.spad (SPAD from IN)>>=
+${MID}/sttaylor.spad: ${IN}/sttaylor.spad.pamphlet
+ @ echo 0 making ${MID}/sttaylor.spad from ${IN}/sttaylor.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sttaylor.spad.pamphlet >sttaylor.spad )
+
+@
+<<STTAYLOR.o (O from NRLIB)>>=
+${OUT}/STTAYLOR.o: ${MID}/STTAYLOR.NRLIB
+ @ echo 0 making ${OUT}/STTAYLOR.o from ${MID}/STTAYLOR.NRLIB
+ @ cp ${MID}/STTAYLOR.NRLIB/code.o ${OUT}/STTAYLOR.o
+
+@
+<<STTAYLOR.NRLIB (NRLIB from MID)>>=
+${MID}/STTAYLOR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/STTAYLOR.spad
+ @ echo 0 making ${MID}/STTAYLOR.NRLIB from ${MID}/STTAYLOR.spad
+ @ (cd ${MID} ; echo ')co STTAYLOR.spad' | ${INTERPSYS} )
+
+@
+<<STTAYLOR.spad (SPAD from IN)>>=
+${MID}/STTAYLOR.spad: ${IN}/sttaylor.spad.pamphlet
+ @ echo 0 making ${MID}/STTAYLOR.spad from ${IN}/sttaylor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STTAYLOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STTAYLOR StreamTaylorSeriesOperations" ${IN}/sttaylor.spad.pamphlet >STTAYLOR.spad )
+
+@
+<<sttaylor.spad.dvi (DOC from IN)>>=
+${DOC}/sttaylor.spad.dvi: ${IN}/sttaylor.spad.pamphlet
+ @ echo 0 making ${DOC}/sttaylor.spad.dvi from ${IN}/sttaylor.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sttaylor.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sttaylor.spad ; \
+ rm -f ${DOC}/sttaylor.spad.pamphlet ; \
+ rm -f ${DOC}/sttaylor.spad.tex ; \
+ rm -f ${DOC}/sttaylor.spad )
+
+@
+\subsection{sttf.spad \cite{1}}
+<<sttf.spad (SPAD from IN)>>=
+${MID}/sttf.spad: ${IN}/sttf.spad.pamphlet
+ @ echo 0 making ${MID}/sttf.spad from ${IN}/sttf.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sttf.spad.pamphlet >sttf.spad )
+
+@
+<<STTF.o (O from NRLIB)>>=
+${OUT}/STTF.o: ${MID}/STTF.NRLIB
+ @ echo 0 making ${OUT}/STTF.o from ${MID}/STTF.NRLIB
+ @ cp ${MID}/STTF.NRLIB/code.o ${OUT}/STTF.o
+
+@
+<<STTF.NRLIB (NRLIB from MID)>>=
+${MID}/STTF.NRLIB: ${MID}/STTF.spad
+ @ echo 0 making ${MID}/STTF.NRLIB from ${MID}/STTF.spad
+ @ (cd ${MID} ; echo ')co STTF.spad' | ${INTERPSYS} )
+
+@
+<<STTF.spad (SPAD from IN)>>=
+${MID}/STTF.spad: ${IN}/sttf.spad.pamphlet
+ @ echo 0 making ${MID}/STTF.spad from ${IN}/sttf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STTF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STTF StreamTranscendentalFunctions" ${IN}/sttf.spad.pamphlet >STTF.spad )
+
+@
+<<STTFNC.o (O from NRLIB)>>=
+${OUT}/STTFNC.o: ${MID}/STTFNC.NRLIB
+ @ echo 0 making ${OUT}/STTFNC.o from ${MID}/STTFNC.NRLIB
+ @ cp ${MID}/STTFNC.NRLIB/code.o ${OUT}/STTFNC.o
+
+@
+<<STTFNC.NRLIB (NRLIB from MID)>>=
+${MID}/STTFNC.NRLIB: ${MID}/STTFNC.spad
+ @ echo 0 making ${MID}/STTFNC.NRLIB from ${MID}/STTFNC.spad
+ @ (cd ${MID} ; echo ')co STTFNC.spad' | ${INTERPSYS} )
+
+@
+<<STTFNC.spad (SPAD from IN)>>=
+${MID}/STTFNC.spad: ${IN}/sttf.spad.pamphlet
+ @ echo 0 making ${MID}/STTFNC.spad from ${IN}/sttf.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STTFNC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package STTFNC StreamTranscendentalFunctionsNonCommutative" ${IN}/sttf.spad.pamphlet >STTFNC.spad )
+
+@
+<<sttf.spad.dvi (DOC from IN)>>=
+${DOC}/sttf.spad.dvi: ${IN}/sttf.spad.pamphlet
+ @ echo 0 making ${DOC}/sttf.spad.dvi from ${IN}/sttf.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sttf.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sttf.spad ; \
+ rm -f ${DOC}/sttf.spad.pamphlet ; \
+ rm -f ${DOC}/sttf.spad.tex ; \
+ rm -f ${DOC}/sttf.spad )
+
+@
+\subsection{sturm.spad \cite{1}}
+<<sturm.spad (SPAD from IN)>>=
+${MID}/sturm.spad: ${IN}/sturm.spad.pamphlet
+ @ echo 0 making ${MID}/sturm.spad from ${IN}/sturm.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sturm.spad.pamphlet >sturm.spad )
+
+@
+<<SHP.o (O from NRLIB)>>=
+${OUT}/SHP.o: ${MID}/SHP.NRLIB
+ @ echo 0 making ${OUT}/SHP.o from ${MID}/SHP.NRLIB
+ @ cp ${MID}/SHP.NRLIB/code.o ${OUT}/SHP.o
+
+@
+<<SHP.NRLIB (NRLIB from MID)>>=
+${MID}/SHP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SHP.spad
+ @ echo 0 making ${MID}/SHP.NRLIB from ${MID}/SHP.spad
+ @ (cd ${MID} ; echo ')co SHP.spad' | ${INTERPSYS} )
+
+@
+<<SHP.spad (SPAD from IN)>>=
+${MID}/SHP.spad: ${IN}/sturm.spad.pamphlet
+ @ echo 0 making ${MID}/SHP.spad from ${IN}/sturm.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SHP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SHP SturmHabichtPackage" ${IN}/sturm.spad.pamphlet >SHP.spad )
+
+@
+<<sturm.spad.dvi (DOC from IN)>>=
+${DOC}/sturm.spad.dvi: ${IN}/sturm.spad.pamphlet
+ @ echo 0 making ${DOC}/sturm.spad.dvi from ${IN}/sturm.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sturm.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sturm.spad ; \
+ rm -f ${DOC}/sturm.spad.pamphlet ; \
+ rm -f ${DOC}/sturm.spad.tex ; \
+ rm -f ${DOC}/sturm.spad )
+
+@
+\subsection{suchthat.spad \cite{1}}
+<<suchthat.spad (SPAD from IN)>>=
+${MID}/suchthat.spad: ${IN}/suchthat.spad.pamphlet
+ @ echo 0 making ${MID}/suchthat.spad from ${IN}/suchthat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/suchthat.spad.pamphlet >suchthat.spad )
+
+@
+<<SUCH.o (O from NRLIB)>>=
+${OUT}/SUCH.o: ${MID}/SUCH.NRLIB
+ @ echo 0 making ${OUT}/SUCH.o from ${MID}/SUCH.NRLIB
+ @ cp ${MID}/SUCH.NRLIB/code.o ${OUT}/SUCH.o
+
+@
+<<SUCH.NRLIB (NRLIB from MID)>>=
+${MID}/SUCH.NRLIB: ${MID}/SUCH.spad
+ @ echo 0 making ${MID}/SUCH.NRLIB from ${MID}/SUCH.spad
+ @ (cd ${MID} ; echo ')co SUCH.spad' | ${INTERPSYS} )
+
+@
+<<SUCH.spad (SPAD from IN)>>=
+${MID}/SUCH.spad: ${IN}/suchthat.spad.pamphlet
+ @ echo 0 making ${MID}/SUCH.spad from ${IN}/suchthat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUCH.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SUCH SuchThat" ${IN}/suchthat.spad.pamphlet >SUCH.spad )
+
+@
+<<suchthat.spad.dvi (DOC from IN)>>=
+${DOC}/suchthat.spad.dvi: ${IN}/suchthat.spad.pamphlet
+ @ echo 0 making ${DOC}/suchthat.spad.dvi from ${IN}/suchthat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/suchthat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} suchthat.spad ; \
+ rm -f ${DOC}/suchthat.spad.pamphlet ; \
+ rm -f ${DOC}/suchthat.spad.tex ; \
+ rm -f ${DOC}/suchthat.spad )
+
+@
+\subsection{suls.spad \cite{1}}
+<<suls.spad (SPAD from IN)>>=
+${MID}/suls.spad: ${IN}/suls.spad.pamphlet
+ @ echo 0 making ${MID}/suls.spad from ${IN}/suls.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/suls.spad.pamphlet >suls.spad )
+
+@
+<<SULS.o (O from NRLIB)>>=
+${OUT}/SULS.o: ${MID}/SULS.NRLIB
+ @ echo 0 making ${OUT}/SULS.o from ${MID}/SULS.NRLIB
+ @ cp ${MID}/SULS.NRLIB/code.o ${OUT}/SULS.o
+
+@
+<<SULS.NRLIB (NRLIB from MID)>>=
+${MID}/SULS.NRLIB: ${MID}/SULS.spad
+ @ echo 0 making ${MID}/SULS.NRLIB from ${MID}/SULS.spad
+ @ (cd ${MID} ; echo ')co SULS.spad' | ${INTERPSYS} )
+
+@
+<<SULS.spad (SPAD from IN)>>=
+${MID}/SULS.spad: ${IN}/suls.spad.pamphlet
+ @ echo 0 making ${MID}/SULS.spad from ${IN}/suls.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SULS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SULS SparseUnivariateLaurentSeries" ${IN}/suls.spad.pamphlet >SULS.spad )
+
+@
+<<suls.spad.dvi (DOC from IN)>>=
+${DOC}/suls.spad.dvi: ${IN}/suls.spad.pamphlet
+ @ echo 0 making ${DOC}/suls.spad.dvi from ${IN}/suls.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/suls.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} suls.spad ; \
+ rm -f ${DOC}/suls.spad.pamphlet ; \
+ rm -f ${DOC}/suls.spad.tex ; \
+ rm -f ${DOC}/suls.spad )
+
+@
+\subsection{sum.spad \cite{1}}
+<<sum.spad (SPAD from IN)>>=
+${MID}/sum.spad: ${IN}/sum.spad.pamphlet
+ @ echo 0 making ${MID}/sum.spad from ${IN}/sum.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sum.spad.pamphlet >sum.spad )
+
+@
+<<GOSPER.o (O from NRLIB)>>=
+${OUT}/GOSPER.o: ${MID}/GOSPER.NRLIB
+ @ echo 0 making ${OUT}/GOSPER.o from ${MID}/GOSPER.NRLIB
+ @ cp ${MID}/GOSPER.NRLIB/code.o ${OUT}/GOSPER.o
+
+@
+<<GOSPER.NRLIB (NRLIB from MID)>>=
+${MID}/GOSPER.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GOSPER.spad
+ @ echo 0 making ${MID}/GOSPER.NRLIB from ${MID}/GOSPER.spad
+ @ (cd ${MID} ; echo ')co GOSPER.spad' | ${INTERPSYS} )
+
+@
+<<GOSPER.spad (SPAD from IN)>>=
+${MID}/GOSPER.spad: ${IN}/sum.spad.pamphlet
+ @ echo 0 making ${MID}/GOSPER.spad from ${IN}/sum.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GOSPER.NRLIB ; \
+ ${SPADBIN}/notangle -R"package GOSPER GosperSummationMethod" ${IN}/sum.spad.pamphlet >GOSPER.spad )
+
+@
+<<ISUMP.o (O from NRLIB)>>=
+${OUT}/ISUMP.o: ${MID}/ISUMP.NRLIB
+ @ echo 0 making ${OUT}/ISUMP.o from ${MID}/ISUMP.NRLIB
+ @ cp ${MID}/ISUMP.NRLIB/code.o ${OUT}/ISUMP.o
+
+@
+<<ISUMP.NRLIB (NRLIB from MID)>>=
+${MID}/ISUMP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/ISUMP.spad
+ @ echo 0 making ${MID}/ISUMP.NRLIB from ${MID}/ISUMP.spad
+ @ (cd ${MID} ; echo ')co ISUMP.spad' | ${INTERPSYS} )
+
+@
+<<ISUMP.spad (SPAD from IN)>>=
+${MID}/ISUMP.spad: ${IN}/sum.spad.pamphlet
+ @ echo 0 making ${MID}/ISUMP.spad from ${IN}/sum.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ISUMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ISUMP InnerPolySum" ${IN}/sum.spad.pamphlet >ISUMP.spad )
+
+@
+<<SUMRF.o (O from NRLIB)>>=
+${OUT}/SUMRF.o: ${MID}/SUMRF.NRLIB
+ @ echo 0 making ${OUT}/SUMRF.o from ${MID}/SUMRF.NRLIB
+ @ cp ${MID}/SUMRF.NRLIB/code.o ${OUT}/SUMRF.o
+
+@
+<<SUMRF.NRLIB (NRLIB from MID)>>=
+${MID}/SUMRF.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/SUMRF.spad
+ @ echo 0 making ${MID}/SUMRF.NRLIB from ${MID}/SUMRF.spad
+ @ (cd ${MID} ; echo ')co SUMRF.spad' | ${INTERPSYS} )
+
+@
+<<SUMRF.spad (SPAD from IN)>>=
+${MID}/SUMRF.spad: ${IN}/sum.spad.pamphlet
+ @ echo 0 making ${MID}/SUMRF.spad from ${IN}/sum.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUMRF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SUMRF RationalFunctionSum" ${IN}/sum.spad.pamphlet >SUMRF.spad )
+
+@
+<<sum.spad.dvi (DOC from IN)>>=
+${DOC}/sum.spad.dvi: ${IN}/sum.spad.pamphlet
+ @ echo 0 making ${DOC}/sum.spad.dvi from ${IN}/sum.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sum.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sum.spad ; \
+ rm -f ${DOC}/sum.spad.pamphlet ; \
+ rm -f ${DOC}/sum.spad.tex ; \
+ rm -f ${DOC}/sum.spad )
+
+@
+\subsection{sups.spad \cite{1}}
+<<sups.spad (SPAD from IN)>>=
+${MID}/sups.spad: ${IN}/sups.spad.pamphlet
+ @ echo 0 making ${MID}/sups.spad from ${IN}/sups.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/sups.spad.pamphlet >sups.spad )
+
+@
+<<ISUPS.o (O from NRLIB)>>=
+${OUT}/ISUPS.o: ${MID}/ISUPS.NRLIB
+ @ echo 0 making ${OUT}/ISUPS.o from ${MID}/ISUPS.NRLIB
+ @ cp ${MID}/ISUPS.NRLIB/code.o ${OUT}/ISUPS.o
+
+@
+<<ISUPS.NRLIB (NRLIB from MID)>>=
+${MID}/ISUPS.NRLIB: ${MID}/ISUPS.spad
+ @ echo 0 making ${MID}/ISUPS.NRLIB from ${MID}/ISUPS.spad
+ @ (cd ${MID} ; echo ')co ISUPS.spad' | ${INTERPSYS} )
+
+@
+<<ISUPS.spad (SPAD from IN)>>=
+${MID}/ISUPS.spad: ${IN}/sups.spad.pamphlet
+ @ echo 0 making ${MID}/ISUPS.spad from ${IN}/sups.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ISUPS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ISUPS InnerSparseUnivariatePowerSeries" ${IN}/sups.spad.pamphlet >ISUPS.spad )
+
+@
+<<sups.spad.dvi (DOC from IN)>>=
+${DOC}/sups.spad.dvi: ${IN}/sups.spad.pamphlet
+ @ echo 0 making ${DOC}/sups.spad.dvi from ${IN}/sups.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/sups.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} sups.spad ; \
+ rm -f ${DOC}/sups.spad.pamphlet ; \
+ rm -f ${DOC}/sups.spad.tex ; \
+ rm -f ${DOC}/sups.spad )
+
+@
+\subsection{supxs.spad \cite{1}}
+<<supxs.spad (SPAD from IN)>>=
+${MID}/supxs.spad: ${IN}/supxs.spad.pamphlet
+ @ echo 0 making ${MID}/supxs.spad from ${IN}/supxs.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/supxs.spad.pamphlet >supxs.spad )
+
+@
+<<SUPXS.o (O from NRLIB)>>=
+${OUT}/SUPXS.o: ${MID}/SUPXS.NRLIB
+ @ echo 0 making ${OUT}/SUPXS.o from ${MID}/SUPXS.NRLIB
+ @ cp ${MID}/SUPXS.NRLIB/code.o ${OUT}/SUPXS.o
+
+@
+<<SUPXS.NRLIB (NRLIB from MID)>>=
+${MID}/SUPXS.NRLIB: ${MID}/SUPXS.spad
+ @ echo 0 making ${MID}/SUPXS.NRLIB from ${MID}/SUPXS.spad
+ @ (cd ${MID} ; echo ')co SUPXS.spad' | ${INTERPSYS} )
+
+@
+<<SUPXS.spad (SPAD from IN)>>=
+${MID}/SUPXS.spad: ${IN}/supxs.spad.pamphlet
+ @ echo 0 making ${MID}/SUPXS.spad from ${IN}/supxs.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUPXS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SUPXS SparseUnivariatePuiseuxSeries" ${IN}/supxs.spad.pamphlet >SUPXS.spad )
+
+@
+<<supxs.spad.dvi (DOC from IN)>>=
+${DOC}/supxs.spad.dvi: ${IN}/supxs.spad.pamphlet
+ @ echo 0 making ${DOC}/supxs.spad.dvi from ${IN}/supxs.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/supxs.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} supxs.spad ; \
+ rm -f ${DOC}/supxs.spad.pamphlet ; \
+ rm -f ${DOC}/supxs.spad.tex ; \
+ rm -f ${DOC}/supxs.spad )
+
+@
+\subsection{suts.spad \cite{1}}
+<<suts.spad (SPAD from IN)>>=
+${MID}/suts.spad: ${IN}/suts.spad.pamphlet
+ @ echo 0 making ${MID}/suts.spad from ${IN}/suts.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/suts.spad.pamphlet >suts.spad )
+
+@
+<<SUTS.o (O from NRLIB)>>=
+${OUT}/SUTS.o: ${MID}/SUTS.NRLIB
+ @ echo 0 making ${OUT}/SUTS.o from ${MID}/SUTS.NRLIB
+ @ cp ${MID}/SUTS.NRLIB/code.o ${OUT}/SUTS.o
+
+@
+<<SUTS.NRLIB (NRLIB from MID)>>=
+${MID}/SUTS.NRLIB: ${MID}/SUTS.spad
+ @ echo 0 making ${MID}/SUTS.NRLIB from ${MID}/SUTS.spad
+ @ (cd ${MID} ; echo ')co SUTS.spad' | ${INTERPSYS} )
+
+@
+<<SUTS.spad (SPAD from IN)>>=
+${MID}/SUTS.spad: ${IN}/suts.spad.pamphlet
+ @ echo 0 making ${MID}/SUTS.spad from ${IN}/suts.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SUTS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SUTS SparseUnivariateTaylorSeries" ${IN}/suts.spad.pamphlet >SUTS.spad )
+
+@
+<<suts.spad.dvi (DOC from IN)>>=
+${DOC}/suts.spad.dvi: ${IN}/suts.spad.pamphlet
+ @ echo 0 making ${DOC}/suts.spad.dvi from ${IN}/suts.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/suts.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} suts.spad ; \
+ rm -f ${DOC}/suts.spad.pamphlet ; \
+ rm -f ${DOC}/suts.spad.tex ; \
+ rm -f ${DOC}/suts.spad )
+
+@
+\subsection{symbol.spad \cite{1}}
+<<symbol.spad (SPAD from IN)>>=
+${MID}/symbol.spad: ${IN}/symbol.spad.pamphlet
+ @ echo 0 making ${MID}/symbol.spad from ${IN}/symbol.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/symbol.spad.pamphlet >symbol.spad )
+
+@
+<<SYMBOL.o (O from NRLIB)>>=
+${OUT}/SYMBOL.o: ${MID}/SYMBOL.NRLIB
+ @ echo 0 making ${OUT}/SYMBOL.o from ${MID}/SYMBOL.NRLIB
+ @ cp ${MID}/SYMBOL.NRLIB/code.o ${OUT}/SYMBOL.o
+
+@
+<<SYMBOL.NRLIB (NRLIB from MID)>>=
+${MID}/SYMBOL.NRLIB: ${MID}/SYMBOL.spad
+ @ echo 0 making ${MID}/SYMBOL.NRLIB from ${MID}/SYMBOL.spad
+ @ (cd ${MID} ; echo ')co SYMBOL.spad' | ${INTERPSYS} )
+
+@
+<<SYMBOL.spad (SPAD from IN)>>=
+${MID}/SYMBOL.spad: ${IN}/symbol.spad.pamphlet
+ @ echo 0 making ${MID}/SYMBOL.spad from ${IN}/symbol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYMBOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain SYMBOL Symbol" ${IN}/symbol.spad.pamphlet >SYMBOL.spad )
+
+@
+<<SYMBOL.o (BOOTSTRAP from MID)>>=
+${MID}/SYMBOL.o: ${MID}/SYMBOL.lsp
+ @ echo 0 making ${MID}/SYMBOL.o from ${MID}/SYMBOL.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "SYMBOL.lsp" :output-file "SYMBOL.o"))' | ${DEPSYS} )
+ @ cp ${MID}/SYMBOL.o ${OUT}/SYMBOL.o
+
+@
+<<SYMBOL.lsp (LISP from IN)>>=
+${MID}/SYMBOL.lsp: ${IN}/symbol.spad.pamphlet
+ @ echo 0 making ${MID}/SYMBOL.lsp from ${IN}/symbol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYMBOL.NRLIB ; \
+ rm -rf ${OUT}/SYMBOL.o ; \
+ ${SPADBIN}/notangle -R"SYMBOL.lsp BOOTSTRAP" ${IN}/symbol.spad.pamphlet >SYMBOL.lsp )
+
+@
+<<symbol.spad.dvi (DOC from IN)>>=
+${DOC}/symbol.spad.dvi: ${IN}/symbol.spad.pamphlet
+ @ echo 0 making ${DOC}/symbol.spad.dvi from ${IN}/symbol.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/symbol.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} symbol.spad ; \
+ rm -f ${DOC}/symbol.spad.pamphlet ; \
+ rm -f ${DOC}/symbol.spad.tex ; \
+ rm -f ${DOC}/symbol.spad )
+
+@
+\subsection{syssolp.spad \cite{1}}
+<<syssolp.spad (SPAD from IN)>>=
+${MID}/syssolp.spad: ${IN}/syssolp.spad.pamphlet
+ @ echo 0 making ${MID}/syssolp.spad from ${IN}/syssolp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/syssolp.spad.pamphlet >syssolp.spad )
+
+@
+<<SYSSOLP.o (O from NRLIB)>>=
+${OUT}/SYSSOLP.o: ${MID}/SYSSOLP.NRLIB
+ @ echo 0 making ${OUT}/SYSSOLP.o from ${MID}/SYSSOLP.NRLIB
+ @ cp ${MID}/SYSSOLP.NRLIB/code.o ${OUT}/SYSSOLP.o
+
+@
+<<SYSSOLP.NRLIB (NRLIB from MID)>>=
+${MID}/SYSSOLP.NRLIB: ${MID}/SYSSOLP.spad
+ @ echo 0 making ${MID}/SYSSOLP.NRLIB from ${MID}/SYSSOLP.spad
+ @ (cd ${MID} ; echo ')co SYSSOLP.spad' | ${INTERPSYS} )
+
+@
+<<SYSSOLP.spad (SPAD from IN)>>=
+${MID}/SYSSOLP.spad: ${IN}/syssolp.spad.pamphlet
+ @ echo 0 making ${MID}/SYSSOLP.spad from ${IN}/syssolp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SYSSOLP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SYSSOLP SystemSolvePackage" ${IN}/syssolp.spad.pamphlet >SYSSOLP.spad )
+
+@
+<<syssolp.spad.dvi (DOC from IN)>>=
+${DOC}/syssolp.spad.dvi: ${IN}/syssolp.spad.pamphlet
+ @ echo 0 making ${DOC}/syssolp.spad.dvi from ${IN}/syssolp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/syssolp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} syssolp.spad ; \
+ rm -f ${DOC}/syssolp.spad.pamphlet ; \
+ rm -f ${DOC}/syssolp.spad.tex ; \
+ rm -f ${DOC}/syssolp.spad )
+
+@
+\subsection{system.spad \cite{1}}
+<<system.spad (SPAD from IN)>>=
+${MID}/system.spad: ${IN}/system.spad.pamphlet
+ @ echo 0 making ${MID}/system.spad from ${IN}/system.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/system.spad.pamphlet >system.spad )
+
+@
+<<MSYSCMD.o (O from NRLIB)>>=
+${OUT}/MSYSCMD.o: ${MID}/MSYSCMD.NRLIB
+ @ echo 0 making ${OUT}/MSYSCMD.o from ${MID}/MSYSCMD.NRLIB
+ @ cp ${MID}/MSYSCMD.NRLIB/code.o ${OUT}/MSYSCMD.o
+
+@
+<<MSYSCMD.NRLIB (NRLIB from MID)>>=
+${MID}/MSYSCMD.NRLIB: ${MID}/MSYSCMD.spad
+ @ echo 0 making ${MID}/MSYSCMD.NRLIB from ${MID}/MSYSCMD.spad
+ @ (cd ${MID} ; echo ')co MSYSCMD.spad' | ${INTERPSYS} )
+
+@
+<<MSYSCMD.spad (SPAD from IN)>>=
+${MID}/MSYSCMD.spad: ${IN}/system.spad.pamphlet
+ @ echo 0 making ${MID}/MSYSCMD.spad from ${IN}/system.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MSYSCMD.NRLIB ; \
+ ${SPADBIN}/notangle -R"package MSYSCMD MoreSystemCommands" ${IN}/system.spad.pamphlet >MSYSCMD.spad )
+
+@
+<<system.spad.dvi (DOC from IN)>>=
+${DOC}/system.spad.dvi: ${IN}/system.spad.pamphlet
+ @ echo 0 making ${DOC}/system.spad.dvi from ${IN}/system.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/system.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} system.spad ; \
+ rm -f ${DOC}/system.spad.pamphlet ; \
+ rm -f ${DOC}/system.spad.tex ; \
+ rm -f ${DOC}/system.spad )
+
+@
+\subsection{tableau.spad \cite{1}}
+<<tableau.spad (SPAD from IN)>>=
+${MID}/tableau.spad: ${IN}/tableau.spad.pamphlet
+ @ echo 0 making ${MID}/tableau.spad from ${IN}/tableau.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/tableau.spad.pamphlet >tableau.spad )
+
+@
+<<TABLBUMP.o (O from NRLIB)>>=
+${OUT}/TABLBUMP.o: ${MID}/TABLBUMP.NRLIB
+ @ echo 0 making ${OUT}/TABLBUMP.o from ${MID}/TABLBUMP.NRLIB
+ @ cp ${MID}/TABLBUMP.NRLIB/code.o ${OUT}/TABLBUMP.o
+
+@
+<<TABLBUMP.NRLIB (NRLIB from MID)>>=
+${MID}/TABLBUMP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/TABLBUMP.spad
+ @ echo 0 making ${MID}/TABLBUMP.NRLIB from ${MID}/TABLBUMP.spad
+ @ (cd ${MID} ; echo ')co TABLBUMP.spad' | ${INTERPSYS} )
+
+@
+<<TABLBUMP.spad (SPAD from IN)>>=
+${MID}/TABLBUMP.spad: ${IN}/tableau.spad.pamphlet
+ @ echo 0 making ${MID}/TABLBUMP.spad from ${IN}/tableau.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TABLBUMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TABLBUMP TableauxBumpers" ${IN}/tableau.spad.pamphlet >TABLBUMP.spad )
+
+@
+<<TABLEAU.o (O from NRLIB)>>=
+${OUT}/TABLEAU.o: ${MID}/TABLEAU.NRLIB
+ @ echo 0 making ${OUT}/TABLEAU.o from ${MID}/TABLEAU.NRLIB
+ @ cp ${MID}/TABLEAU.NRLIB/code.o ${OUT}/TABLEAU.o
+
+@
+<<TABLEAU.NRLIB (NRLIB from MID)>>=
+${MID}/TABLEAU.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/TABLEAU.spad
+ @ echo 0 making ${MID}/TABLEAU.NRLIB from ${MID}/TABLEAU.spad
+ @ (cd ${MID} ; echo ')co TABLEAU.spad' | ${INTERPSYS} )
+
+@
+<<TABLEAU.spad (SPAD from IN)>>=
+${MID}/TABLEAU.spad: ${IN}/tableau.spad.pamphlet
+ @ echo 0 making ${MID}/TABLEAU.spad from ${IN}/tableau.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TABLEAU.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TABLEAU Tableau" ${IN}/tableau.spad.pamphlet >TABLEAU.spad )
+
+@
+<<tableau.spad.dvi (DOC from IN)>>=
+${DOC}/tableau.spad.dvi: ${IN}/tableau.spad.pamphlet
+ @ echo 0 making ${DOC}/tableau.spad.dvi from ${IN}/tableau.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/tableau.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} tableau.spad ; \
+ rm -f ${DOC}/tableau.spad.pamphlet ; \
+ rm -f ${DOC}/tableau.spad.tex ; \
+ rm -f ${DOC}/tableau.spad )
+
+@
+\subsection{table.spad \cite{1}}
+<<table.spad (SPAD from IN)>>=
+${MID}/table.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/table.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/table.spad.pamphlet >table.spad )
+
+@
+<<EQTBL.o (O from NRLIB)>>=
+${OUT}/EQTBL.o: ${MID}/EQTBL.NRLIB
+ @ echo 0 making ${OUT}/EQTBL.o from ${MID}/EQTBL.NRLIB
+ @ cp ${MID}/EQTBL.NRLIB/code.o ${OUT}/EQTBL.o
+
+@
+<<EQTBL.NRLIB (NRLIB from MID)>>=
+${MID}/EQTBL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/EQTBL.spad
+ @ echo 0 making ${MID}/EQTBL.NRLIB from ${MID}/EQTBL.spad
+ @ (cd ${MID} ; echo ')co EQTBL.spad' | ${INTERPSYS} )
+
+@
+<<EQTBL.spad (SPAD from IN)>>=
+${MID}/EQTBL.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/EQTBL.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EQTBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EQTBL EqTable" ${IN}/table.spad.pamphlet >EQTBL.spad )
+
+@
+<<GSTBL.o (O from NRLIB)>>=
+${OUT}/GSTBL.o: ${MID}/GSTBL.NRLIB
+ @ echo 0 making ${OUT}/GSTBL.o from ${MID}/GSTBL.NRLIB
+ @ cp ${MID}/GSTBL.NRLIB/code.o ${OUT}/GSTBL.o
+
+@
+<<GSTBL.NRLIB (NRLIB from MID)>>=
+${MID}/GSTBL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/GSTBL.spad
+ @ echo 0 making ${MID}/GSTBL.NRLIB from ${MID}/GSTBL.spad
+ @ (cd ${MID} ; echo ')co GSTBL.spad' | ${INTERPSYS} )
+
+@
+<<GSTBL.spad (SPAD from IN)>>=
+${MID}/GSTBL.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/GSTBL.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GSTBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GSTBL GeneralSparseTable" ${IN}/table.spad.pamphlet >GSTBL.spad )
+
+@
+<<HASHTBL.o (O from NRLIB)>>=
+${OUT}/HASHTBL.o: ${MID}/HASHTBL.NRLIB
+ @ echo 0 making ${OUT}/HASHTBL.o from ${MID}/HASHTBL.NRLIB
+ @ cp ${MID}/HASHTBL.NRLIB/code.o ${OUT}/HASHTBL.o
+
+@
+<<HASHTBL.NRLIB (NRLIB from MID)>>=
+${MID}/HASHTBL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/HASHTBL.spad
+ @ echo 0 making ${MID}/HASHTBL.NRLIB from ${MID}/HASHTBL.spad
+ @ (cd ${MID} ; echo ')co HASHTBL.spad' | ${INTERPSYS} )
+
+@
+<<HASHTBL.spad (SPAD from IN)>>=
+${MID}/HASHTBL.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/HASHTBL.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HASHTBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain HASHTBL HashTable" ${IN}/table.spad.pamphlet >HASHTBL.spad )
+
+@
+<<INTABL.o (O from NRLIB)>>=
+${OUT}/INTABL.o: ${MID}/INTABL.NRLIB
+ @ echo 0 making ${OUT}/INTABL.o from ${MID}/INTABL.NRLIB
+ @ cp ${MID}/INTABL.NRLIB/code.o ${OUT}/INTABL.o
+
+@
+<<INTABL.NRLIB (NRLIB from MID)>>=
+${MID}/INTABL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/INTABL.spad
+ @ echo 0 making ${MID}/INTABL.NRLIB from ${MID}/INTABL.spad
+ @ (cd ${MID} ; echo ')co INTABL.spad' | ${INTERPSYS} )
+
+@
+<<INTABL.spad (SPAD from IN)>>=
+${MID}/INTABL.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/INTABL.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf INTABL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain INTABL InnerTable" ${IN}/table.spad.pamphlet >INTABL.spad )
+
+@
+<<STBL.o (O from NRLIB)>>=
+${OUT}/STBL.o: ${MID}/STBL.NRLIB
+ @ echo 0 making ${OUT}/STBL.o from ${MID}/STBL.NRLIB
+ @ cp ${MID}/STBL.NRLIB/code.o ${OUT}/STBL.o
+
+@
+<<STBL.NRLIB (NRLIB from MID)>>=
+${MID}/STBL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/STBL.spad
+ @ echo 0 making ${MID}/STBL.NRLIB from ${MID}/STBL.spad
+ @ (cd ${MID} ; echo ')co STBL.spad' | ${INTERPSYS} )
+
+@
+<<STBL.spad (SPAD from IN)>>=
+${MID}/STBL.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/STBL.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain STBL SparseTable" ${IN}/table.spad.pamphlet >STBL.spad )
+
+@
+<<STRTBL.o (O from NRLIB)>>=
+${OUT}/STRTBL.o: ${MID}/STRTBL.NRLIB
+ @ echo 0 making ${OUT}/STRTBL.o from ${MID}/STRTBL.NRLIB
+ @ cp ${MID}/STRTBL.NRLIB/code.o ${OUT}/STRTBL.o
+
+@
+<<STRTBL.NRLIB (NRLIB from MID)>>=
+${MID}/STRTBL.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/STRTBL.spad
+ @ echo 0 making ${MID}/STRTBL.NRLIB from ${MID}/STRTBL.spad
+ @ (cd ${MID} ; echo ')co STRTBL.spad' | ${INTERPSYS} )
+
+@
+<<STRTBL.spad (SPAD from IN)>>=
+${MID}/STRTBL.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/STRTBL.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf STRTBL.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain STRTBL StringTable" ${IN}/table.spad.pamphlet >STRTBL.spad )
+
+@
+<<TABLE.o (O from NRLIB)>>=
+${OUT}/TABLE.o: ${MID}/TABLE.NRLIB
+ @ echo 0 making ${OUT}/TABLE.o from ${MID}/TABLE.NRLIB
+ @ cp ${MID}/TABLE.NRLIB/code.o ${OUT}/TABLE.o
+
+@
+<<TABLE.NRLIB (NRLIB from MID)>>=
+${MID}/TABLE.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/TABLE.spad
+ @ echo 0 making ${MID}/TABLE.NRLIB from ${MID}/TABLE.spad
+ @ (cd ${MID} ; echo ')co TABLE.spad' | ${INTERPSYS} )
+
+@
+<<TABLE.spad (SPAD from IN)>>=
+${MID}/TABLE.spad: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${MID}/TABLE.spad from ${IN}/table.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TABLE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TABLE Table" ${IN}/table.spad.pamphlet >TABLE.spad )
+
+@
+<<table.spad.dvi (DOC from IN)>>=
+${DOC}/table.spad.dvi: ${IN}/table.spad.pamphlet
+ @ echo 0 making ${DOC}/table.spad.dvi from ${IN}/table.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/table.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} table.spad ; \
+ rm -f ${DOC}/table.spad.pamphlet ; \
+ rm -f ${DOC}/table.spad.tex ; \
+ rm -f ${DOC}/table.spad )
+
+@
+\subsection{taylor.spad \cite{1}}
+<<taylor.spad (SPAD from IN)>>=
+${MID}/taylor.spad: ${IN}/taylor.spad.pamphlet
+ @ echo 0 making ${MID}/taylor.spad from ${IN}/taylor.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/taylor.spad.pamphlet >taylor.spad )
+
+@
+<<ITAYLOR.o (O from NRLIB)>>=
+${OUT}/ITAYLOR.o: ${MID}/ITAYLOR.NRLIB
+ @ echo 0 making ${OUT}/ITAYLOR.o from ${MID}/ITAYLOR.NRLIB
+ @ cp ${MID}/ITAYLOR.NRLIB/code.o ${OUT}/ITAYLOR.o
+
+@
+<<ITAYLOR.NRLIB (NRLIB from MID)>>=
+${MID}/ITAYLOR.NRLIB: ${MID}/ITAYLOR.spad
+ @ echo 0 making ${MID}/ITAYLOR.NRLIB from ${MID}/ITAYLOR.spad
+ @ (cd ${MID} ; echo ')co ITAYLOR.spad' | ${INTERPSYS} )
+
+@
+<<ITAYLOR.spad (SPAD from IN)>>=
+${MID}/ITAYLOR.spad: ${IN}/taylor.spad.pamphlet
+ @ echo 0 making ${MID}/ITAYLOR.spad from ${IN}/taylor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ITAYLOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ITAYLOR InnerTaylorSeries" ${IN}/taylor.spad.pamphlet >ITAYLOR.spad )
+
+@
+<<UTS.o (O from NRLIB)>>=
+${OUT}/UTS.o: ${MID}/UTS.NRLIB
+ @ echo 0 making ${OUT}/UTS.o from ${MID}/UTS.NRLIB
+ @ cp ${MID}/UTS.NRLIB/code.o ${OUT}/UTS.o
+
+@
+<<UTS.NRLIB (NRLIB from MID)>>=
+${MID}/UTS.NRLIB: ${MID}/UTS.spad
+ @ echo 0 making ${MID}/UTS.NRLIB from ${MID}/UTS.spad
+ @ (cd ${MID} ; echo ')co UTS.spad' | ${INTERPSYS} )
+
+@
+<<UTS.spad (SPAD from IN)>>=
+${MID}/UTS.spad: ${IN}/taylor.spad.pamphlet
+ @ echo 0 making ${MID}/UTS.spad from ${IN}/taylor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UTS.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain UTS UnivariateTaylorSeries" ${IN}/taylor.spad.pamphlet >UTS.spad )
+
+@
+<<UTS2.o (O from NRLIB)>>=
+${OUT}/UTS2.o: ${MID}/UTS2.NRLIB
+ @ echo 0 making ${OUT}/UTS2.o from ${MID}/UTS2.NRLIB
+ @ cp ${MID}/UTS2.NRLIB/code.o ${OUT}/UTS2.o
+
+@
+<<UTS2.NRLIB (NRLIB from MID)>>=
+${MID}/UTS2.NRLIB: ${MID}/UTS2.spad
+ @ echo 0 making ${MID}/UTS2.NRLIB from ${MID}/UTS2.spad
+ @ (cd ${MID} ; echo ')co UTS2.spad' | ${INTERPSYS} )
+
+@
+<<UTS2.spad (SPAD from IN)>>=
+${MID}/UTS2.spad: ${IN}/taylor.spad.pamphlet
+ @ echo 0 making ${MID}/UTS2.spad from ${IN}/taylor.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UTS2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UTS2 UnivariateTaylorSeriesFunctions2" ${IN}/taylor.spad.pamphlet >UTS2.spad )
+
+@
+<<taylor.spad.dvi (DOC from IN)>>=
+${DOC}/taylor.spad.dvi: ${IN}/taylor.spad.pamphlet
+ @ echo 0 making ${DOC}/taylor.spad.dvi from ${IN}/taylor.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/taylor.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} taylor.spad ; \
+ rm -f ${DOC}/taylor.spad.pamphlet ; \
+ rm -f ${DOC}/taylor.spad.tex ; \
+ rm -f ${DOC}/taylor.spad )
+
+@
+\subsection{tex.spad \cite{1}}
+<<tex.spad (SPAD from IN)>>=
+${MID}/tex.spad: ${IN}/tex.spad.pamphlet
+ @ echo 0 making ${MID}/tex.spad from ${IN}/tex.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/tex.spad.pamphlet >tex.spad )
+
+@
+<<TEX.o (O from NRLIB)>>=
+${OUT}/TEX.o: ${MID}/TEX.NRLIB
+ @ echo 0 making ${OUT}/TEX.o from ${MID}/TEX.NRLIB
+ @ cp ${MID}/TEX.NRLIB/code.o ${OUT}/TEX.o
+
+@
+<<TEX.NRLIB (NRLIB from MID)>>=
+${MID}/TEX.NRLIB: ${MID}/TEX.spad
+ @ echo 0 making ${MID}/TEX.NRLIB from ${MID}/TEX.spad
+ @ (cd ${MID} ; echo ')co TEX.spad' | ${INTERPSYS} )
+
+@
+<<TEX.spad (SPAD from IN)>>=
+${MID}/TEX.spad: ${IN}/tex.spad.pamphlet
+ @ echo 0 making ${MID}/TEX.spad from ${IN}/tex.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TEX.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TEX TexFormat" ${IN}/tex.spad.pamphlet >TEX.spad )
+
+@
+<<TEX1.o (O from NRLIB)>>=
+${OUT}/TEX1.o: ${MID}/TEX1.NRLIB
+ @ echo 0 making ${OUT}/TEX1.o from ${MID}/TEX1.NRLIB
+ @ cp ${MID}/TEX1.NRLIB/code.o ${OUT}/TEX1.o
+
+@
+<<TEX1.NRLIB (NRLIB from MID)>>=
+${MID}/TEX1.NRLIB: ${MID}/TEX1.spad
+ @ echo 0 making ${MID}/TEX1.NRLIB from ${MID}/TEX1.spad
+ @ (cd ${MID} ; echo ')co TEX1.spad' | ${INTERPSYS} )
+
+@
+<<TEX1.spad (SPAD from IN)>>=
+${MID}/TEX1.spad: ${IN}/tex.spad.pamphlet
+ @ echo 0 making ${MID}/TEX1.spad from ${IN}/tex.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TEX1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TEX1 TexFormat1" ${IN}/tex.spad.pamphlet >TEX1.spad )
+
+@
+<<tex.spad.dvi (DOC from IN)>>=
+${DOC}/tex.spad.dvi: ${IN}/tex.spad.pamphlet
+ @ echo 0 making ${DOC}/tex.spad.dvi from ${IN}/tex.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/tex.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} tex.spad ; \
+ rm -f ${DOC}/tex.spad.pamphlet ; \
+ rm -f ${DOC}/tex.spad.tex ; \
+ rm -f ${DOC}/tex.spad )
+
+@
+\subsection{tools.spad \cite{1}}
+<<tools.spad (SPAD from IN)>>=
+${MID}/tools.spad: ${IN}/tools.spad.pamphlet
+ @ echo 0 making ${MID}/tools.spad from ${IN}/tools.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/tools.spad.pamphlet >tools.spad )
+
+@
+<<ESTOOLS.o (O from NRLIB)>>=
+${OUT}/ESTOOLS.o: ${MID}/ESTOOLS.NRLIB
+ @ echo 0 making ${OUT}/ESTOOLS.o from ${MID}/ESTOOLS.NRLIB
+ @ cp ${MID}/ESTOOLS.NRLIB/code.o ${OUT}/ESTOOLS.o
+
+@
+<<ESTOOLS.NRLIB (NRLIB from MID)>>=
+${MID}/ESTOOLS.NRLIB: ${MID}/ESTOOLS.spad
+ @ echo 0 making ${MID}/ESTOOLS.NRLIB from ${MID}/ESTOOLS.spad
+ @ (cd ${MID} ; echo ')co ESTOOLS.spad' | ${INTERPSYS} )
+
+@
+<<ESTOOLS.spad (SPAD from IN)>>=
+${MID}/ESTOOLS.spad: ${IN}/tools.spad.pamphlet
+ @ echo 0 making ${MID}/ESTOOLS.spad from ${IN}/tools.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ESTOOLS.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ESTOOLS ExpertSystemToolsPackage" ${IN}/tools.spad.pamphlet >ESTOOLS.spad )
+
+@
+<<ESTOOLS1.o (O from NRLIB)>>=
+${OUT}/ESTOOLS1.o: ${MID}/ESTOOLS1.NRLIB
+ @ echo 0 making ${OUT}/ESTOOLS1.o from ${MID}/ESTOOLS1.NRLIB
+ @ cp ${MID}/ESTOOLS1.NRLIB/code.o ${OUT}/ESTOOLS1.o
+
+@
+<<ESTOOLS1.NRLIB (NRLIB from MID)>>=
+${MID}/ESTOOLS1.NRLIB: ${MID}/ESTOOLS1.spad
+ @ echo 0 making ${MID}/ESTOOLS1.NRLIB from ${MID}/ESTOOLS1.spad
+ @ (cd ${MID} ; echo ')co ESTOOLS1.spad' | ${INTERPSYS} )
+
+@
+<<ESTOOLS1.spad (SPAD from IN)>>=
+${MID}/ESTOOLS1.spad: ${IN}/tools.spad.pamphlet
+ @ echo 0 making ${MID}/ESTOOLS1.spad from ${IN}/tools.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ESTOOLS1.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ESTOOLS1 ExpertSystemToolsPackage1" ${IN}/tools.spad.pamphlet >ESTOOLS1.spad )
+
+@
+<<ESTOOLS2.o (O from NRLIB)>>=
+${OUT}/ESTOOLS2.o: ${MID}/ESTOOLS2.NRLIB
+ @ echo 0 making ${OUT}/ESTOOLS2.o from ${MID}/ESTOOLS2.NRLIB
+ @ cp ${MID}/ESTOOLS2.NRLIB/code.o ${OUT}/ESTOOLS2.o
+
+@
+<<ESTOOLS2.NRLIB (NRLIB from MID)>>=
+${MID}/ESTOOLS2.NRLIB: ${MID}/ESTOOLS2.spad
+ @ echo 0 making ${MID}/ESTOOLS2.NRLIB from ${MID}/ESTOOLS2.spad
+ @ (cd ${MID} ; echo ')co ESTOOLS2.spad' | ${INTERPSYS} )
+
+@
+<<ESTOOLS2.spad (SPAD from IN)>>=
+${MID}/ESTOOLS2.spad: ${IN}/tools.spad.pamphlet
+ @ echo 0 making ${MID}/ESTOOLS2.spad from ${IN}/tools.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ESTOOLS2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package ESTOOLS2 ExpertSystemToolsPackage2" ${IN}/tools.spad.pamphlet >ESTOOLS2.spad )
+
+@
+<<tools.spad.dvi (DOC from IN)>>=
+${DOC}/tools.spad.dvi: ${IN}/tools.spad.pamphlet
+ @ echo 0 making ${DOC}/tools.spad.dvi from ${IN}/tools.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/tools.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} tools.spad ; \
+ rm -f ${DOC}/tools.spad.pamphlet ; \
+ rm -f ${DOC}/tools.spad.tex ; \
+ rm -f ${DOC}/tools.spad )
+
+@
+\subsection{transsolve.spad \cite{1}}
+<<transsolve.spad (SPAD from IN)>>=
+${MID}/transsolve.spad: ${IN}/transsolve.spad.pamphlet
+ @ echo 0 making ${MID}/transsolve.spad from ${IN}/transsolve.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/transsolve.spad.pamphlet >transsolve.spad )
+
+@
+<<SOLVESER.o (O from NRLIB)>>=
+${OUT}/SOLVESER.o: ${MID}/SOLVESER.NRLIB
+ @ echo 0 making ${OUT}/SOLVESER.o from ${MID}/SOLVESER.NRLIB
+ @ cp ${MID}/SOLVESER.NRLIB/code.o ${OUT}/SOLVESER.o
+
+@
+<<SOLVESER.NRLIB (NRLIB from MID)>>=
+${MID}/SOLVESER.NRLIB: ${MID}/SOLVESER.spad
+ @ echo 0 making ${MID}/SOLVESER.NRLIB from ${MID}/SOLVESER.spad
+ @ (cd ${MID} ; echo ')co SOLVESER.spad' | ${INTERPSYS} )
+
+@
+<<SOLVESER.spad (SPAD from IN)>>=
+${MID}/SOLVESER.spad: ${IN}/transsolve.spad.pamphlet
+ @ echo 0 making ${MID}/SOLVESER.spad from ${IN}/transsolve.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SOLVESER.NRLIB ; \
+ ${SPADBIN}/notangle -R"package SOLVESER TransSolvePackageService" ${IN}/transsolve.spad.pamphlet >SOLVESER.spad )
+
+@
+<<transsolve.spad.dvi (DOC from IN)>>=
+${DOC}/transsolve.spad.dvi: ${IN}/transsolve.spad.pamphlet
+ @ echo 0 making ${DOC}/transsolve.spad.dvi from ${IN}/transsolve.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/transsolve.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} transsolve.spad ; \
+ rm -f ${DOC}/transsolve.spad.pamphlet ; \
+ rm -f ${DOC}/transsolve.spad.tex ; \
+ rm -f ${DOC}/transsolve.spad )
+
+@
+\subsection{tree.spad \cite{1}}
+<<tree.spad (SPAD from IN)>>=
+${MID}/tree.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/tree.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/tree.spad.pamphlet >tree.spad )
+
+@
+<<BBTREE.o (O from NRLIB)>>=
+${OUT}/BBTREE.o: ${MID}/BBTREE.NRLIB
+ @ echo 0 making ${OUT}/BBTREE.o from ${MID}/BBTREE.NRLIB
+ @ cp ${MID}/BBTREE.NRLIB/code.o ${OUT}/BBTREE.o
+
+@
+<<BBTREE.NRLIB (NRLIB from MID)>>=
+${MID}/BBTREE.NRLIB: ${MID}/BBTREE.spad
+ @ echo 0 making ${MID}/BBTREE.NRLIB from ${MID}/BBTREE.spad
+ @ (cd ${MID} ; echo ')co BBTREE.spad' | ${INTERPSYS} )
+
+@
+<<BBTREE.spad (SPAD from IN)>>=
+${MID}/BBTREE.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/BBTREE.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BBTREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BBTREE BalancedBinaryTree" ${IN}/tree.spad.pamphlet >BBTREE.spad )
+
+@
+<<BSTREE.o (O from NRLIB)>>=
+${OUT}/BSTREE.o: ${MID}/BSTREE.NRLIB
+ @ echo 0 making ${OUT}/BSTREE.o from ${MID}/BSTREE.NRLIB
+ @ cp ${MID}/BSTREE.NRLIB/code.o ${OUT}/BSTREE.o
+
+@
+<<BSTREE.NRLIB (NRLIB from MID)>>=
+${MID}/BSTREE.NRLIB: ${MID}/BSTREE.spad
+ @ echo 0 making ${MID}/BSTREE.NRLIB from ${MID}/BSTREE.spad
+ @ (cd ${MID} ; echo ')co BSTREE.spad' | ${INTERPSYS} )
+
+@
+<<BSTREE.spad (SPAD from IN)>>=
+${MID}/BSTREE.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/BSTREE.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BSTREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BSTREE BinarySearchTree" ${IN}/tree.spad.pamphlet >BSTREE.spad )
+
+@
+<<BTCAT-.o (O from NRLIB)>>=
+${OUT}/BTCAT-.o: ${MID}/BTCAT.NRLIB
+ @ echo 0 making ${OUT}/BTCAT-.o from ${MID}/BTCAT-.NRLIB
+ @ cp ${MID}/BTCAT-.NRLIB/code.o ${OUT}/BTCAT-.o
+
+@
+<<BTCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/BTCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/BTCAT.spad
+ @ echo 0 making ${MID}/BTCAT-.NRLIB from ${MID}/BTCAT.spad
+ @ (cd ${MID} ; echo ')co BTCAT.spad' | ${INTERPSYS} )
+
+@
+<<BTCAT.o (O from NRLIB)>>=
+${OUT}/BTCAT.o: ${MID}/BTCAT.NRLIB
+ @ echo 0 making ${OUT}/BTCAT.o from ${MID}/BTCAT.NRLIB
+ @ cp ${MID}/BTCAT.NRLIB/code.o ${OUT}/BTCAT.o
+
+@
+<<BTCAT.NRLIB (NRLIB from MID)>>=
+${MID}/BTCAT.NRLIB: ${MID}/BTCAT.spad
+ @ echo 0 making ${MID}/BTCAT.NRLIB from ${MID}/BTCAT.spad
+ @ (cd ${MID} ; echo ')co BTCAT.spad' | ${INTERPSYS} )
+
+@
+<<BTCAT.spad (SPAD from IN)>>=
+${MID}/BTCAT.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/BTCAT.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BTCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category BTCAT BinaryTreeCategory" ${IN}/tree.spad.pamphlet >BTCAT.spad )
+
+@
+<<BTOURN.o (O from NRLIB)>>=
+${OUT}/BTOURN.o: ${MID}/BTOURN.NRLIB
+ @ echo 0 making ${OUT}/BTOURN.o from ${MID}/BTOURN.NRLIB
+ @ cp ${MID}/BTOURN.NRLIB/code.o ${OUT}/BTOURN.o
+
+@
+<<BTOURN.NRLIB (NRLIB from MID)>>=
+${MID}/BTOURN.NRLIB: ${MID}/BTOURN.spad
+ @ echo 0 making ${MID}/BTOURN.NRLIB from ${MID}/BTOURN.spad
+ @ (cd ${MID} ; echo ')co BTOURN.spad' | ${INTERPSYS} )
+
+@
+<<BTOURN.spad (SPAD from IN)>>=
+${MID}/BTOURN.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/BTOURN.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BTOURN.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BTOURN BinaryTournament" ${IN}/tree.spad.pamphlet >BTOURN.spad )
+
+@
+<<BTREE.o (O from NRLIB)>>=
+${OUT}/BTREE.o: ${MID}/BTREE.NRLIB
+ @ echo 0 making ${OUT}/BTREE.o from ${MID}/BTREE.NRLIB
+ @ cp ${MID}/BTREE.NRLIB/code.o ${OUT}/BTREE.o
+
+@
+<<BTREE.NRLIB (NRLIB from MID)>>=
+${MID}/BTREE.NRLIB: ${MID}/BTREE.spad
+ @ echo 0 making ${MID}/BTREE.NRLIB from ${MID}/BTREE.spad
+ @ (cd ${MID} ; echo ')co BTREE.spad' | ${INTERPSYS} )
+
+@
+<<BTREE.spad (SPAD from IN)>>=
+${MID}/BTREE.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/BTREE.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf BTREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain BTREE BinaryTree" ${IN}/tree.spad.pamphlet >BTREE.spad )
+
+@
+<<PENDTREE.o (O from NRLIB)>>=
+${OUT}/PENDTREE.o: ${MID}/PENDTREE.NRLIB
+ @ echo 0 making ${OUT}/PENDTREE.o from ${MID}/PENDTREE.NRLIB
+ @ cp ${MID}/PENDTREE.NRLIB/code.o ${OUT}/PENDTREE.o
+
+@
+<<PENDTREE.NRLIB (NRLIB from MID)>>=
+${MID}/PENDTREE.NRLIB: ${MID}/PENDTREE.spad
+ @ echo 0 making ${MID}/PENDTREE.NRLIB from ${MID}/PENDTREE.spad
+ @ (cd ${MID} ; echo ')co PENDTREE.spad' | ${INTERPSYS} )
+
+@
+<<PENDTREE.spad (SPAD from IN)>>=
+${MID}/PENDTREE.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/PENDTREE.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PENDTREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PENDTREE PendantTree" ${IN}/tree.spad.pamphlet >PENDTREE.spad )
+
+@
+<<TREE.o (O from NRLIB)>>=
+${OUT}/TREE.o: ${MID}/TREE.NRLIB
+ @ echo 0 making ${OUT}/TREE.o from ${MID}/TREE.NRLIB
+ @ cp ${MID}/TREE.NRLIB/code.o ${OUT}/TREE.o
+
+@
+<<TREE.NRLIB (NRLIB from MID)>>=
+${MID}/TREE.NRLIB: ${MID}/TREE.spad
+ @ echo 0 making ${MID}/TREE.NRLIB from ${MID}/TREE.spad
+ @ (cd ${MID} ; echo ')co TREE.spad' | ${INTERPSYS} )
+
+@
+<<TREE.spad (SPAD from IN)>>=
+${MID}/TREE.spad: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${MID}/TREE.spad from ${IN}/tree.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TREE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TREE Tree" ${IN}/tree.spad.pamphlet >TREE.spad )
+
+@
+<<tree.spad.dvi (DOC from IN)>>=
+${DOC}/tree.spad.dvi: ${IN}/tree.spad.pamphlet
+ @ echo 0 making ${DOC}/tree.spad.dvi from ${IN}/tree.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/tree.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} tree.spad ; \
+ rm -f ${DOC}/tree.spad.pamphlet ; \
+ rm -f ${DOC}/tree.spad.tex ; \
+ rm -f ${DOC}/tree.spad )
+
+@
+\subsection{trigcat.spad \cite{1}}
+<<trigcat.spad (SPAD from IN)>>=
+${MID}/trigcat.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/trigcat.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/trigcat.spad.pamphlet >trigcat.spad )
+
+@
+<<AHYP.o (O from NRLIB)>>=
+${OUT}/AHYP.o: ${MID}/AHYP.NRLIB
+ @ echo 0 making ${OUT}/AHYP.o from ${MID}/AHYP.NRLIB
+ @ cp ${MID}/AHYP.NRLIB/code.o ${OUT}/AHYP.o
+
+@
+<<AHYP.NRLIB (NRLIB from MID)>>=
+${MID}/AHYP.NRLIB: ${MID}/AHYP.spad
+ @ echo 0 making ${MID}/AHYP.NRLIB from ${MID}/AHYP.spad
+ @ (cd ${MID} ; echo ')co AHYP.spad' | ${INTERPSYS} )
+
+@
+<<AHYP.spad (SPAD from IN)>>=
+${MID}/AHYP.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/AHYP.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf AHYP.NRLIB ; \
+ ${SPADBIN}/notangle -R"category AHYP ArcHyperbolicFunctionCategory" ${IN}/trigcat.spad.pamphlet >AHYP.spad )
+
+@
+<<ATRIG-.o (O from NRLIB)>>=
+${OUT}/ATRIG-.o: ${MID}/ATRIG.NRLIB
+ @ echo 0 making ${OUT}/ATRIG-.o from ${MID}/ATRIG-.NRLIB
+ @ cp ${MID}/ATRIG-.NRLIB/code.o ${OUT}/ATRIG-.o
+
+@
+<<ATRIG-.NRLIB (NRLIB from MID)>>=
+${MID}/ATRIG-.NRLIB: ${OUT}/TYPE.o ${MID}/ATRIG.spad
+ @ echo 0 making ${MID}/ATRIG-.NRLIB from ${MID}/ATRIG.spad
+ @ (cd ${MID} ; echo ')co ATRIG.spad' | ${INTERPSYS} )
+
+@
+<<ATRIG.o (O from NRLIB)>>=
+${OUT}/ATRIG.o: ${MID}/ATRIG.NRLIB
+ @ echo 0 making ${OUT}/ATRIG.o from ${MID}/ATRIG.NRLIB
+ @ cp ${MID}/ATRIG.NRLIB/code.o ${OUT}/ATRIG.o
+
+@
+<<ATRIG.NRLIB (NRLIB from MID)>>=
+${MID}/ATRIG.NRLIB: ${MID}/ATRIG.spad
+ @ echo 0 making ${MID}/ATRIG.NRLIB from ${MID}/ATRIG.spad
+ @ (cd ${MID} ; echo ')co ATRIG.spad' | ${INTERPSYS} )
+
+@
+<<ATRIG.spad (SPAD from IN)>>=
+${MID}/ATRIG.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/ATRIG.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ATRIG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ATRIG ArcTrigonometricFunctionCategory" ${IN}/trigcat.spad.pamphlet >ATRIG.spad )
+
+@
+<<CFCAT.o (O from NRLIB)>>=
+${OUT}/CFCAT.o: ${MID}/CFCAT.NRLIB
+ @ echo 0 making ${OUT}/CFCAT.o from ${MID}/CFCAT.NRLIB
+ @ cp ${MID}/CFCAT.NRLIB/code.o ${OUT}/CFCAT.o
+
+@
+<<CFCAT.NRLIB (NRLIB from MID)>>=
+${MID}/CFCAT.NRLIB: ${MID}/CFCAT.spad
+ @ echo 0 making ${MID}/CFCAT.NRLIB from ${MID}/CFCAT.spad
+ @ (cd ${MID} ; echo ')co CFCAT.spad' | ${INTERPSYS} )
+
+@
+<<CFCAT.spad (SPAD from IN)>>=
+${MID}/CFCAT.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/CFCAT.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf CFCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category CFCAT CombinatorialFunctionCategory" ${IN}/trigcat.spad.pamphlet >CFCAT.spad )
+
+@
+<<ELEMFUN-.o (O from NRLIB)>>=
+${OUT}/ELEMFUN-.o: ${MID}/ELEMFUN.NRLIB
+ @ echo 0 making ${OUT}/ELEMFUN-.o from ${MID}/ELEMFUN-.NRLIB
+ @ cp ${MID}/ELEMFUN-.NRLIB/code.o ${OUT}/ELEMFUN-.o
+
+@
+<<ELEMFUN-.NRLIB (NRLIB from MID)>>=
+${MID}/ELEMFUN-.NRLIB: ${OUT}/TYPE.o ${MID}/ELEMFUN.spad
+ @ echo 0 making ${MID}/ELEMFUN-.NRLIB from ${MID}/ELEMFUN.spad
+ @ (cd ${MID} ; echo ')co ELEMFUN.spad' | ${INTERPSYS} )
+
+@
+<<ELEMFUN.o (O from NRLIB)>>=
+${OUT}/ELEMFUN.o: ${MID}/ELEMFUN.NRLIB
+ @ echo 0 making ${OUT}/ELEMFUN.o from ${MID}/ELEMFUN.NRLIB
+ @ cp ${MID}/ELEMFUN.NRLIB/code.o ${OUT}/ELEMFUN.o
+
+@
+<<ELEMFUN.NRLIB (NRLIB from MID)>>=
+${MID}/ELEMFUN.NRLIB: ${MID}/ELEMFUN.spad
+ @ echo 0 making ${MID}/ELEMFUN.NRLIB from ${MID}/ELEMFUN.spad
+ @ (cd ${MID} ; echo ')co ELEMFUN.spad' | ${INTERPSYS} )
+
+@
+<<ELEMFUN.spad (SPAD from IN)>>=
+${MID}/ELEMFUN.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/ELEMFUN.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ELEMFUN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category ELEMFUN ElementaryFunctionCategory" ${IN}/trigcat.spad.pamphlet >ELEMFUN.spad )
+
+@
+<<HYPCAT-.o (O from NRLIB)>>=
+${OUT}/HYPCAT-.o: ${MID}/HYPCAT.NRLIB
+ @ echo 0 making ${OUT}/HYPCAT-.o from ${MID}/HYPCAT-.NRLIB
+ @ cp ${MID}/HYPCAT-.NRLIB/code.o ${OUT}/HYPCAT-.o
+
+@
+<<HYPCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/HYPCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/HYPCAT.spad
+ @ echo 0 making ${MID}/HYPCAT-.NRLIB from ${MID}/HYPCAT.spad
+ @ (cd ${MID} ; echo ')co HYPCAT.spad' | ${INTERPSYS} )
+
+@
+<<HYPCAT.o (O from NRLIB)>>=
+${OUT}/HYPCAT.o: ${MID}/HYPCAT.NRLIB
+ @ echo 0 making ${OUT}/HYPCAT.o from ${MID}/HYPCAT.NRLIB
+ @ cp ${MID}/HYPCAT.NRLIB/code.o ${OUT}/HYPCAT.o
+
+@
+<<HYPCAT.NRLIB (NRLIB from MID)>>=
+${MID}/HYPCAT.NRLIB: ${MID}/HYPCAT.spad
+ @ echo 0 making ${MID}/HYPCAT.NRLIB from ${MID}/HYPCAT.spad
+ @ (cd ${MID} ; echo ')co HYPCAT.spad' | ${INTERPSYS} )
+
+@
+<<HYPCAT.spad (SPAD from IN)>>=
+${MID}/HYPCAT.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/HYPCAT.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf HYPCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category HYPCAT HyperbolicFunctionCategory" ${IN}/trigcat.spad.pamphlet >HYPCAT.spad )
+
+@
+<<LFCAT.o (O from NRLIB)>>=
+${OUT}/LFCAT.o: ${MID}/LFCAT.NRLIB
+ @ echo 0 making ${OUT}/LFCAT.o from ${MID}/LFCAT.NRLIB
+ @ cp ${MID}/LFCAT.NRLIB/code.o ${OUT}/LFCAT.o
+
+@
+<<LFCAT.NRLIB (NRLIB from MID)>>=
+${MID}/LFCAT.NRLIB: ${MID}/LFCAT.spad
+ @ echo 0 making ${MID}/LFCAT.NRLIB from ${MID}/LFCAT.spad
+ @ (cd ${MID} ; echo ')co LFCAT.spad' | ${INTERPSYS} )
+
+@
+<<LFCAT.spad (SPAD from IN)>>=
+${MID}/LFCAT.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/LFCAT.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LFCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LFCAT LiouvillianFunctionCategory" ${IN}/trigcat.spad.pamphlet >LFCAT.spad )
+
+@
+<<PRIMCAT.o (O from NRLIB)>>=
+${OUT}/PRIMCAT.o: ${MID}/PRIMCAT.NRLIB
+ @ echo 0 making ${OUT}/PRIMCAT.o from ${MID}/PRIMCAT.NRLIB
+ @ cp ${MID}/PRIMCAT.NRLIB/code.o ${OUT}/PRIMCAT.o
+
+@
+<<PRIMCAT.NRLIB (NRLIB from MID)>>=
+${MID}/PRIMCAT.NRLIB: ${MID}/PRIMCAT.spad
+ @ echo 0 making ${MID}/PRIMCAT.NRLIB from ${MID}/PRIMCAT.spad
+ @ (cd ${MID} ; echo ')co PRIMCAT.spad' | ${INTERPSYS} )
+
+@
+<<PRIMCAT.spad (SPAD from IN)>>=
+${MID}/PRIMCAT.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/PRIMCAT.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PRIMCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category PRIMCAT PrimitiveFunctionCategory" ${IN}/trigcat.spad.pamphlet >PRIMCAT.spad )
+
+@
+<<SPFCAT.o (O from NRLIB)>>=
+${OUT}/SPFCAT.o: ${MID}/SPFCAT.NRLIB
+ @ echo 0 making ${OUT}/SPFCAT.o from ${MID}/SPFCAT.NRLIB
+ @ cp ${MID}/SPFCAT.NRLIB/code.o ${OUT}/SPFCAT.o
+
+@
+<<SPFCAT.NRLIB (NRLIB from MID)>>=
+${MID}/SPFCAT.NRLIB: ${MID}/SPFCAT.spad
+ @ echo 0 making ${MID}/SPFCAT.NRLIB from ${MID}/SPFCAT.spad
+ @ (cd ${MID} ; echo ')co SPFCAT.spad' | ${INTERPSYS} )
+
+@
+<<SPFCAT.spad (SPAD from IN)>>=
+${MID}/SPFCAT.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/SPFCAT.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf SPFCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category SPFCAT SpecialFunctionCategory" ${IN}/trigcat.spad.pamphlet >SPFCAT.spad )
+
+@
+<<TRANFUN-.o (O from NRLIB)>>=
+${OUT}/TRANFUN-.o: ${MID}/TRANFUN.NRLIB
+ @ echo 0 making ${OUT}/TRANFUN-.o from ${MID}/TRANFUN-.NRLIB
+ @ cp ${MID}/TRANFUN-.NRLIB/code.o ${OUT}/TRANFUN-.o
+
+@
+<<TRANFUN-.NRLIB (NRLIB from MID)>>=
+${MID}/TRANFUN-.NRLIB: ${OUT}/TYPE.o ${MID}/TRANFUN.spad
+ @ echo 0 making ${MID}/TRANFUN-.NRLIB from ${MID}/TRANFUN.spad
+ @ (cd ${MID} ; echo ')co TRANFUN.spad' | ${INTERPSYS} )
+
+@
+<<TRANFUN.o (O from NRLIB)>>=
+${OUT}/TRANFUN.o: ${MID}/TRANFUN.NRLIB
+ @ echo 0 making ${OUT}/TRANFUN.o from ${MID}/TRANFUN.NRLIB
+ @ cp ${MID}/TRANFUN.NRLIB/code.o ${OUT}/TRANFUN.o
+
+@
+<<TRANFUN.NRLIB (NRLIB from MID)>>=
+${MID}/TRANFUN.NRLIB: ${MID}/TRANFUN.spad
+ @ echo 0 making ${MID}/TRANFUN.NRLIB from ${MID}/TRANFUN.spad
+ @ (cd ${MID} ; echo ')co TRANFUN.spad' | ${INTERPSYS} )
+
+@
+<<TRANFUN.spad (SPAD from IN)>>=
+${MID}/TRANFUN.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/TRANFUN.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TRANFUN.NRLIB ; \
+ ${SPADBIN}/notangle -R"category TRANFUN TranscendentalFunctionCategory" ${IN}/trigcat.spad.pamphlet >TRANFUN.spad )
+
+@
+<<TRIGCAT-.o (O from NRLIB)>>=
+${OUT}/TRIGCAT-.o: ${MID}/TRIGCAT.NRLIB
+ @ echo 0 making ${OUT}/TRIGCAT-.o from ${MID}/TRIGCAT-.NRLIB
+ @ cp ${MID}/TRIGCAT-.NRLIB/code.o ${OUT}/TRIGCAT-.o
+
+@
+<<TRIGCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/TRIGCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/TRIGCAT.spad
+ @ echo 0 making ${MID}/TRIGCAT-.NRLIB from ${MID}/TRIGCAT.spad
+ @ (cd ${MID} ; echo ')co TRIGCAT.spad' | ${INTERPSYS} )
+
+@
+<<TRIGCAT.o (O from NRLIB)>>=
+${OUT}/TRIGCAT.o: ${MID}/TRIGCAT.NRLIB
+ @ echo 0 making ${OUT}/TRIGCAT.o from ${MID}/TRIGCAT.NRLIB
+ @ cp ${MID}/TRIGCAT.NRLIB/code.o ${OUT}/TRIGCAT.o
+
+@
+<<TRIGCAT.NRLIB (NRLIB from MID)>>=
+${MID}/TRIGCAT.NRLIB: ${MID}/TRIGCAT.spad
+ @ echo 0 making ${MID}/TRIGCAT.NRLIB from ${MID}/TRIGCAT.spad
+ @ (cd ${MID} ; echo ')co TRIGCAT.spad' | ${INTERPSYS} )
+
+@
+<<TRIGCAT.spad (SPAD from IN)>>=
+${MID}/TRIGCAT.spad: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${MID}/TRIGCAT.spad from ${IN}/trigcat.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TRIGCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category TRIGCAT TrigonometricFunctionCategory" ${IN}/trigcat.spad.pamphlet >TRIGCAT.spad )
+
+@
+<<trigcat.spad.dvi (DOC from IN)>>=
+${DOC}/trigcat.spad.dvi: ${IN}/trigcat.spad.pamphlet
+ @ echo 0 making ${DOC}/trigcat.spad.dvi from ${IN}/trigcat.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/trigcat.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} trigcat.spad ; \
+ rm -f ${DOC}/trigcat.spad.pamphlet ; \
+ rm -f ${DOC}/trigcat.spad.tex ; \
+ rm -f ${DOC}/trigcat.spad )
+
+@
+\subsection{triset.spad \cite{1}}
+<<triset.spad (SPAD from IN)>>=
+${MID}/triset.spad: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/triset.spad from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/triset.spad.pamphlet >triset.spad )
+
+@
+<<GTSET.o (O from NRLIB)>>=
+${OUT}/GTSET.o: ${MID}/GTSET.NRLIB
+ @ echo 0 making ${OUT}/GTSET.o from ${MID}/GTSET.NRLIB
+ @ cp ${MID}/GTSET.NRLIB/code.o ${OUT}/GTSET.o
+
+@
+<<GTSET.NRLIB (NRLIB from MID)>>=
+${MID}/GTSET.NRLIB: ${MID}/GTSET.spad
+ @ echo 0 making ${MID}/GTSET.NRLIB from ${MID}/GTSET.spad
+ @ (cd ${MID} ; echo ')co GTSET.spad' | ${INTERPSYS} )
+
+@
+<<GTSET.spad (SPAD from IN)>>=
+${MID}/GTSET.spad: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/GTSET.spad from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GTSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GTSET GeneralTriangularSet" ${IN}/triset.spad.pamphlet >GTSET.spad )
+
+@
+<<PSETPK.o (O from NRLIB)>>=
+${OUT}/PSETPK.o: ${MID}/PSETPK.NRLIB
+ @ echo 0 making ${OUT}/PSETPK.o from ${MID}/PSETPK.NRLIB
+ @ cp ${MID}/PSETPK.NRLIB/code.o ${OUT}/PSETPK.o
+
+@
+<<PSETPK.NRLIB (NRLIB from MID)>>=
+${MID}/PSETPK.NRLIB: ${MID}/PSETPK.spad
+ @ echo 0 making ${MID}/PSETPK.NRLIB from ${MID}/PSETPK.spad
+ @ (cd ${MID} ; echo ')co PSETPK.spad' | ${INTERPSYS} )
+
+@
+<<PSETPK.spad (SPAD from IN)>>=
+${MID}/PSETPK.spad: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/PSETPK.spad from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PSETPK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package PSETPK PolynomialSetUtilitiesPackage" ${IN}/triset.spad.pamphlet >PSETPK.spad )
+
+@
+<<TSETCAT-.o (O from NRLIB)>>=
+${OUT}/TSETCAT-.o: ${MID}/TSETCAT.NRLIB
+ @ echo 0 making ${OUT}/TSETCAT-.o from ${MID}/TSETCAT-.NRLIB
+ @ cp ${MID}/TSETCAT-.NRLIB/code.o ${OUT}/TSETCAT-.o
+
+@
+<<TSETCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/TSETCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/TSETCAT.spad
+ @ echo 0 making ${MID}/TSETCAT-.NRLIB from ${MID}/TSETCAT.spad
+ @ (cd ${MID} ; echo ')co TSETCAT.spad' | ${INTERPSYS} )
+
+@
+<<TSETCAT.o (O from NRLIB)>>=
+${OUT}/TSETCAT.o: ${MID}/TSETCAT.NRLIB
+ @ echo 0 making ${OUT}/TSETCAT.o from ${MID}/TSETCAT.NRLIB
+ @ cp ${MID}/TSETCAT.NRLIB/code.o ${OUT}/TSETCAT.o
+
+@
+<<TSETCAT.NRLIB (NRLIB from MID)>>=
+${MID}/TSETCAT.NRLIB: ${MID}/TSETCAT.spad
+ @ echo 0 making ${MID}/TSETCAT.NRLIB from ${MID}/TSETCAT.spad
+ @ (cd ${MID} ; echo ')co TSETCAT.spad' | ${INTERPSYS} )
+
+@
+<<TSETCAT.spad (SPAD from IN)>>=
+${MID}/TSETCAT.spad: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/TSETCAT.spad from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TSETCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category TSETCAT TriangularSetCategory" ${IN}/triset.spad.pamphlet >TSETCAT.spad )
+
+@
+<<TSETCAT-.o (BOOTSTRAP from MID)>>=
+${MID}/TSETCAT-.o: ${MID}/TSETCAT-.lsp
+ @ echo 0 making ${MID}/TSETCAT-.o from ${MID}/TSETCAT-.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "TSETCAT-.lsp" :output-file "TSETCAT-.o"))' | ${DEPSYS} )
+ @ cp ${MID}/TSETCAT-.o ${OUT}/TSETCAT-.o
+
+@
+<<TSETCAT-.lsp (LISP from IN)>>=
+${MID}/TSETCAT-.lsp: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/TSETCAT-.lsp from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TSETCAT-.NRLIB ; \
+ rm -rf ${OUT}/TSETCAT-.o ; \
+ ${SPADBIN}/notangle -R"TSETCAT-.lsp BOOTSTRAP" ${IN}/triset.spad.pamphlet >TSETCAT-.lsp )
+
+@
+<<TSETCAT.o (BOOTSTRAP from MID)>>=
+${MID}/TSETCAT.o: ${MID}/TSETCAT.lsp
+ @ echo 0 making ${MID}/TSETCAT.o from ${MID}/TSETCAT.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "TSETCAT.lsp" :output-file "TSETCAT.o"))' | ${DEPSYS} )
+ @ cp ${MID}/TSETCAT.o ${OUT}/TSETCAT.o
+
+@
+<<TSETCAT.lsp (LISP from IN)>>=
+${MID}/TSETCAT.lsp: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/TSETCAT.lsp from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TSETCAT.NRLIB ; \
+ rm -rf ${OUT}/TSETCAT.o ; \
+ ${SPADBIN}/notangle -R"TSETCAT.lsp BOOTSTRAP" ${IN}/triset.spad.pamphlet >TSETCAT.lsp )
+
+<<WUTSET.o (O from NRLIB)>>=
+${OUT}/WUTSET.o: ${MID}/WUTSET.NRLIB
+ @ echo 0 making ${OUT}/WUTSET.o from ${MID}/WUTSET.NRLIB
+ @ cp ${MID}/WUTSET.NRLIB/code.o ${OUT}/WUTSET.o
+
+@
+<<WUTSET.NRLIB (NRLIB from MID)>>=
+${MID}/WUTSET.NRLIB: ${MID}/WUTSET.spad
+ @ echo 0 making ${MID}/WUTSET.NRLIB from ${MID}/WUTSET.spad
+ @ (cd ${MID} ; echo ')co WUTSET.spad' | ${INTERPSYS} )
+
+@
+<<WUTSET.spad (SPAD from IN)>>=
+${MID}/WUTSET.spad: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${MID}/WUTSET.spad from ${IN}/triset.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf WUTSET.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain WUTSET WuWenTsunTriangularSet" ${IN}/triset.spad.pamphlet >WUTSET.spad )
+
+@
+<<triset.spad.dvi (DOC from IN)>>=
+${DOC}/triset.spad.dvi: ${IN}/triset.spad.pamphlet
+ @ echo 0 making ${DOC}/triset.spad.dvi from ${IN}/triset.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/triset.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} triset.spad ; \
+ rm -f ${DOC}/triset.spad.pamphlet ; \
+ rm -f ${DOC}/triset.spad.tex ; \
+ rm -f ${DOC}/triset.spad )
+
+@
+\subsection{tube.spad \cite{1}}
+<<tube.spad (SPAD from IN)>>=
+${MID}/tube.spad: ${IN}/tube.spad.pamphlet
+ @ echo 0 making ${MID}/tube.spad from ${IN}/tube.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/tube.spad.pamphlet >tube.spad )
+
+@
+<<EXPRTUBE.o (O from NRLIB)>>=
+${OUT}/EXPRTUBE.o: ${MID}/EXPRTUBE.NRLIB
+ @ echo 0 making ${OUT}/EXPRTUBE.o from ${MID}/EXPRTUBE.NRLIB
+ @ cp ${MID}/EXPRTUBE.NRLIB/code.o ${OUT}/EXPRTUBE.o
+
+@
+<<EXPRTUBE.NRLIB (NRLIB from MID)>>=
+${MID}/EXPRTUBE.NRLIB: ${MID}/EXPRTUBE.spad
+ @ echo 0 making ${MID}/EXPRTUBE.NRLIB from ${MID}/EXPRTUBE.spad
+ @ (cd ${MID} ; echo ')co EXPRTUBE.spad' | ${INTERPSYS} )
+
+@
+<<EXPRTUBE.spad (SPAD from IN)>>=
+${MID}/EXPRTUBE.spad: ${IN}/tube.spad.pamphlet
+ @ echo 0 making ${MID}/EXPRTUBE.spad from ${IN}/tube.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXPRTUBE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package EXPRTUBE ExpressionTubePlot" ${IN}/tube.spad.pamphlet >EXPRTUBE.spad )
+
+@
+<<NUMTUBE.o (O from NRLIB)>>=
+${OUT}/NUMTUBE.o: ${MID}/NUMTUBE.NRLIB
+ @ echo 0 making ${OUT}/NUMTUBE.o from ${MID}/NUMTUBE.NRLIB
+ @ cp ${MID}/NUMTUBE.NRLIB/code.o ${OUT}/NUMTUBE.o
+
+@
+<<NUMTUBE.NRLIB (NRLIB from MID)>>=
+${MID}/NUMTUBE.NRLIB: ${MID}/NUMTUBE.spad
+ @ echo 0 making ${MID}/NUMTUBE.NRLIB from ${MID}/NUMTUBE.spad
+ @ (cd ${MID} ; echo ')co NUMTUBE.spad' | ${INTERPSYS} )
+
+@
+<<NUMTUBE.spad (SPAD from IN)>>=
+${MID}/NUMTUBE.spad: ${IN}/tube.spad.pamphlet
+ @ echo 0 making ${MID}/NUMTUBE.spad from ${IN}/tube.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NUMTUBE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NUMTUBE NumericTubePlot" ${IN}/tube.spad.pamphlet >NUMTUBE.spad )
+
+@
+<<TUBE.o (O from NRLIB)>>=
+${OUT}/TUBE.o: ${MID}/TUBE.NRLIB
+ @ echo 0 making ${OUT}/TUBE.o from ${MID}/TUBE.NRLIB
+ @ cp ${MID}/TUBE.NRLIB/code.o ${OUT}/TUBE.o
+
+@
+<<TUBE.NRLIB (NRLIB from MID)>>=
+${MID}/TUBE.NRLIB: ${MID}/TUBE.spad
+ @ echo 0 making ${MID}/TUBE.NRLIB from ${MID}/TUBE.spad
+ @ (cd ${MID} ; echo ')co TUBE.spad' | ${INTERPSYS} )
+
+@
+<<TUBE.spad (SPAD from IN)>>=
+${MID}/TUBE.spad: ${IN}/tube.spad.pamphlet
+ @ echo 0 making ${MID}/TUBE.spad from ${IN}/tube.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TUBE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain TUBE TubePlot" ${IN}/tube.spad.pamphlet >TUBE.spad )
+
+@
+<<TUBETOOL.o (O from NRLIB)>>=
+${OUT}/TUBETOOL.o: ${MID}/TUBETOOL.NRLIB
+ @ echo 0 making ${OUT}/TUBETOOL.o from ${MID}/TUBETOOL.NRLIB
+ @ cp ${MID}/TUBETOOL.NRLIB/code.o ${OUT}/TUBETOOL.o
+
+@
+<<TUBETOOL.NRLIB (NRLIB from MID)>>=
+${MID}/TUBETOOL.NRLIB: ${MID}/TUBETOOL.spad
+ @ echo 0 making ${MID}/TUBETOOL.NRLIB from ${MID}/TUBETOOL.spad
+ @ (cd ${MID} ; echo ')co TUBETOOL.spad' | ${INTERPSYS} )
+
+@
+<<TUBETOOL.spad (SPAD from IN)>>=
+${MID}/TUBETOOL.spad: ${IN}/tube.spad.pamphlet
+ @ echo 0 making ${MID}/TUBETOOL.spad from ${IN}/tube.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TUBETOOL.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TUBETOOL TubePlotTools" ${IN}/tube.spad.pamphlet >TUBETOOL.spad )
+
+@
+<<tube.spad.dvi (DOC from IN)>>=
+${DOC}/tube.spad.dvi: ${IN}/tube.spad.pamphlet
+ @ echo 0 making ${DOC}/tube.spad.dvi from ${IN}/tube.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/tube.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} tube.spad ; \
+ rm -f ${DOC}/tube.spad.pamphlet ; \
+ rm -f ${DOC}/tube.spad.tex ; \
+ rm -f ${DOC}/tube.spad )
+
+@
+\subsection{twofact.spad \cite{1}}
+<<twofact.spad (SPAD from IN)>>=
+${MID}/twofact.spad: ${IN}/twofact.spad.pamphlet
+ @ echo 0 making ${MID}/twofact.spad from ${IN}/twofact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/twofact.spad.pamphlet >twofact.spad )
+
+@
+<<NORMRETR.o (O from NRLIB)>>=
+${OUT}/NORMRETR.o: ${MID}/NORMRETR.NRLIB
+ @ echo 0 making ${OUT}/NORMRETR.o from ${MID}/NORMRETR.NRLIB
+ @ cp ${MID}/NORMRETR.NRLIB/code.o ${OUT}/NORMRETR.o
+
+@
+<<NORMRETR.NRLIB (NRLIB from MID)>>=
+${MID}/NORMRETR.NRLIB: ${MID}/NORMRETR.spad
+ @ echo 0 making ${MID}/NORMRETR.NRLIB from ${MID}/NORMRETR.spad
+ @ (cd ${MID} ; echo ')co NORMRETR.spad' | ${INTERPSYS} )
+
+@
+<<NORMRETR.spad (SPAD from IN)>>=
+${MID}/NORMRETR.spad: ${IN}/twofact.spad.pamphlet
+ @ echo 0 making ${MID}/NORMRETR.spad from ${IN}/twofact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf NORMRETR.NRLIB ; \
+ ${SPADBIN}/notangle -R"package NORMRETR NormRetractPackage" ${IN}/twofact.spad.pamphlet >NORMRETR.spad )
+
+@
+<<TWOFACT.o (O from NRLIB)>>=
+${OUT}/TWOFACT.o: ${MID}/TWOFACT.NRLIB
+ @ echo 0 making ${OUT}/TWOFACT.o from ${MID}/TWOFACT.NRLIB
+ @ cp ${MID}/TWOFACT.NRLIB/code.o ${OUT}/TWOFACT.o
+
+@
+<<TWOFACT.NRLIB (NRLIB from MID)>>=
+${MID}/TWOFACT.NRLIB: ${MID}/TWOFACT.spad
+ @ echo 0 making ${MID}/TWOFACT.NRLIB from ${MID}/TWOFACT.spad
+ @ (cd ${MID} ; echo ')co TWOFACT.spad' | ${INTERPSYS} )
+
+@
+<<TWOFACT.spad (SPAD from IN)>>=
+${MID}/TWOFACT.spad: ${IN}/twofact.spad.pamphlet
+ @ echo 0 making ${MID}/TWOFACT.spad from ${IN}/twofact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf TWOFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package TWOFACT TwoFactorize" ${IN}/twofact.spad.pamphlet >TWOFACT.spad )
+
+@
+<<twofact.spad.dvi (DOC from IN)>>=
+${DOC}/twofact.spad.dvi: ${IN}/twofact.spad.pamphlet
+ @ echo 0 making ${DOC}/twofact.spad.dvi from ${IN}/twofact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/twofact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} twofact.spad ; \
+ rm -f ${DOC}/twofact.spad.pamphlet ; \
+ rm -f ${DOC}/twofact.spad.tex ; \
+ rm -f ${DOC}/twofact.spad )
+
+@
+\subsection{unifact.spad \cite{1}}
+<<unifact.spad (SPAD from IN)>>=
+${MID}/unifact.spad: ${IN}/unifact.spad.pamphlet
+ @ echo 0 making ${MID}/unifact.spad from ${IN}/unifact.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/unifact.spad.pamphlet >unifact.spad )
+
+@
+<<UNIFACT.o (O from NRLIB)>>=
+${OUT}/UNIFACT.o: ${MID}/UNIFACT.NRLIB
+ @ echo 0 making ${OUT}/UNIFACT.o from ${MID}/UNIFACT.NRLIB
+ @ cp ${MID}/UNIFACT.NRLIB/code.o ${OUT}/UNIFACT.o
+
+@
+<<UNIFACT.NRLIB (NRLIB from MID)>>=
+${MID}/UNIFACT.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UNIFACT.spad
+ @ echo 0 making ${MID}/UNIFACT.NRLIB from ${MID}/UNIFACT.spad
+ @ (cd ${MID} ; echo ')co UNIFACT.spad' | ${INTERPSYS} )
+
+@
+<<UNIFACT.spad (SPAD from IN)>>=
+${MID}/UNIFACT.spad: ${IN}/unifact.spad.pamphlet
+ @ echo 0 making ${MID}/UNIFACT.spad from ${IN}/unifact.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UNIFACT.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UNIFACT UnivariateFactorize" ${IN}/unifact.spad.pamphlet >UNIFACT.spad )
+
+@
+<<unifact.spad.dvi (DOC from IN)>>=
+${DOC}/unifact.spad.dvi: ${IN}/unifact.spad.pamphlet
+ @ echo 0 making ${DOC}/unifact.spad.dvi from ${IN}/unifact.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/unifact.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} unifact.spad ; \
+ rm -f ${DOC}/unifact.spad.pamphlet ; \
+ rm -f ${DOC}/unifact.spad.tex ; \
+ rm -f ${DOC}/unifact.spad )
+
+@
+\subsection{updecomp.spad \cite{1}}
+<<updecomp.spad (SPAD from IN)>>=
+${MID}/updecomp.spad: ${IN}/updecomp.spad.pamphlet
+ @ echo 0 making ${MID}/updecomp.spad from ${IN}/updecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/updecomp.spad.pamphlet >updecomp.spad )
+
+@
+<<UPDECOMP.o (O from NRLIB)>>=
+${OUT}/UPDECOMP.o: ${MID}/UPDECOMP.NRLIB
+ @ echo 0 making ${OUT}/UPDECOMP.o from ${MID}/UPDECOMP.NRLIB
+ @ cp ${MID}/UPDECOMP.NRLIB/code.o ${OUT}/UPDECOMP.o
+
+@
+<<UPDECOMP.NRLIB (NRLIB from MID)>>=
+${MID}/UPDECOMP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UPDECOMP.spad
+ @ echo 0 making ${MID}/UPDECOMP.NRLIB from ${MID}/UPDECOMP.spad
+ @ (cd ${MID} ; echo ')co UPDECOMP.spad' | ${INTERPSYS} )
+
+@
+<<UPDECOMP.spad (SPAD from IN)>>=
+${MID}/UPDECOMP.spad: ${IN}/updecomp.spad.pamphlet
+ @ echo 0 making ${MID}/UPDECOMP.spad from ${IN}/updecomp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPDECOMP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPDECOMP UnivariatePolynomialDecompositionPackage" ${IN}/updecomp.spad.pamphlet >UPDECOMP.spad )
+
+@
+<<updecomp.spad.dvi (DOC from IN)>>=
+${DOC}/updecomp.spad.dvi: ${IN}/updecomp.spad.pamphlet
+ @ echo 0 making ${DOC}/updecomp.spad.dvi from ${IN}/updecomp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/updecomp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} updecomp.spad ; \
+ rm -f ${DOC}/updecomp.spad.pamphlet ; \
+ rm -f ${DOC}/updecomp.spad.tex ; \
+ rm -f ${DOC}/updecomp.spad )
+
+@
+\subsection{updivp.spad \cite{1}}
+<<updivp.spad (SPAD from IN)>>=
+${MID}/updivp.spad: ${IN}/updivp.spad.pamphlet
+ @ echo 0 making ${MID}/updivp.spad from ${IN}/updivp.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/updivp.spad.pamphlet >updivp.spad )
+
+@
+<<UPDIVP.o (O from NRLIB)>>=
+${OUT}/UPDIVP.o: ${MID}/UPDIVP.NRLIB
+ @ echo 0 making ${OUT}/UPDIVP.o from ${MID}/UPDIVP.NRLIB
+ @ cp ${MID}/UPDIVP.NRLIB/code.o ${OUT}/UPDIVP.o
+
+@
+<<UPDIVP.NRLIB (NRLIB from MID)>>=
+${MID}/UPDIVP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/UPDIVP.spad
+ @ echo 0 making ${MID}/UPDIVP.NRLIB from ${MID}/UPDIVP.spad
+ @ (cd ${MID} ; echo ')co UPDIVP.spad' | ${INTERPSYS} )
+
+@
+<<UPDIVP.spad (SPAD from IN)>>=
+${MID}/UPDIVP.spad: ${IN}/updivp.spad.pamphlet
+ @ echo 0 making ${MID}/UPDIVP.spad from ${IN}/updivp.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UPDIVP.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UPDIVP UnivariatePolynomialDivisionPackage" ${IN}/updivp.spad.pamphlet >UPDIVP.spad )
+
+@
+<<updivp.spad.dvi (DOC from IN)>>=
+${DOC}/updivp.spad.dvi: ${IN}/updivp.spad.pamphlet
+ @ echo 0 making ${DOC}/updivp.spad.dvi from ${IN}/updivp.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/updivp.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} updivp.spad ; \
+ rm -f ${DOC}/updivp.spad.pamphlet ; \
+ rm -f ${DOC}/updivp.spad.tex ; \
+ rm -f ${DOC}/updivp.spad )
+
+@
+\subsection{utsode.spad \cite{1}}
+<<utsode.spad (SPAD from IN)>>=
+${MID}/utsode.spad: ${IN}/utsode.spad.pamphlet
+ @ echo 0 making ${MID}/utsode.spad from ${IN}/utsode.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/utsode.spad.pamphlet >utsode.spad )
+
+@
+<<UTSODE.o (O from NRLIB)>>=
+${OUT}/UTSODE.o: ${MID}/UTSODE.NRLIB
+ @ echo 0 making ${OUT}/UTSODE.o from ${MID}/UTSODE.NRLIB
+ @ cp ${MID}/UTSODE.NRLIB/code.o ${OUT}/UTSODE.o
+
+@
+<<UTSODE.NRLIB (NRLIB from MID)>>=
+${MID}/UTSODE.NRLIB: ${MID}/UTSODE.spad
+ @ echo 0 making ${MID}/UTSODE.NRLIB from ${MID}/UTSODE.spad
+ @ (cd ${MID} ; echo ')co UTSODE.spad' | ${INTERPSYS} )
+
+@
+<<UTSODE.spad (SPAD from IN)>>=
+${MID}/UTSODE.spad: ${IN}/utsode.spad.pamphlet
+ @ echo 0 making ${MID}/UTSODE.spad from ${IN}/utsode.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf UTSODE.NRLIB ; \
+ ${SPADBIN}/notangle -R"package UTSODE UnivariateTaylorSeriesODESolver" ${IN}/utsode.spad.pamphlet >UTSODE.spad )
+
+@
+<<utsode.spad.dvi (DOC from IN)>>=
+${DOC}/utsode.spad.dvi: ${IN}/utsode.spad.pamphlet
+ @ echo 0 making ${DOC}/utsode.spad.dvi from ${IN}/utsode.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/utsode.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} utsode.spad ; \
+ rm -f ${DOC}/utsode.spad.pamphlet ; \
+ rm -f ${DOC}/utsode.spad.tex ; \
+ rm -f ${DOC}/utsode.spad )
+
+@
+\subsection{variable.spad \cite{1}}
+<<variable.spad (SPAD from IN)>>=
+${MID}/variable.spad: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${MID}/variable.spad from ${IN}/variable.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/variable.spad.pamphlet >variable.spad )
+
+@
+<<ANON.o (O from NRLIB)>>=
+${OUT}/ANON.o: ${MID}/ANON.NRLIB
+ @ echo 0 making ${OUT}/ANON.o from ${MID}/ANON.NRLIB
+ @ cp ${MID}/ANON.NRLIB/code.o ${OUT}/ANON.o
+
+@
+<<ANON.NRLIB (NRLIB from MID)>>=
+${MID}/ANON.NRLIB: ${MID}/ANON.spad
+ @ echo 0 making ${MID}/ANON.NRLIB from ${MID}/ANON.spad
+ @ (cd ${MID} ; echo ')co ANON.spad' | ${INTERPSYS} )
+
+@
+<<ANON.spad (SPAD from IN)>>=
+${MID}/ANON.spad: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${MID}/ANON.spad from ${IN}/variable.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf ANON.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain ANON AnonymousFunction" ${IN}/variable.spad.pamphlet >ANON.spad )
+
+@
+<<FUNCTION.o (O from NRLIB)>>=
+${OUT}/FUNCTION.o: ${MID}/FUNCTION.NRLIB
+ @ echo 0 making ${OUT}/FUNCTION.o from ${MID}/FUNCTION.NRLIB
+ @ cp ${MID}/FUNCTION.NRLIB/code.o ${OUT}/FUNCTION.o
+
+@
+<<FUNCTION.NRLIB (NRLIB from MID)>>=
+${MID}/FUNCTION.NRLIB: ${MID}/FUNCTION.spad
+ @ echo 0 making ${MID}/FUNCTION.NRLIB from ${MID}/FUNCTION.spad
+ @ (cd ${MID} ; echo ')co FUNCTION.spad' | ${INTERPSYS} )
+
+@
+<<FUNCTION.spad (SPAD from IN)>>=
+${MID}/FUNCTION.spad: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${MID}/FUNCTION.spad from ${IN}/variable.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FUNCTION.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FUNCTION FunctionCalled" ${IN}/variable.spad.pamphlet >FUNCTION.spad )
+
+@
+<<OVAR.o (O from NRLIB)>>=
+${OUT}/OVAR.o: ${MID}/OVAR.NRLIB
+ @ echo 0 making ${OUT}/OVAR.o from ${MID}/OVAR.NRLIB
+ @ cp ${MID}/OVAR.NRLIB/code.o ${OUT}/OVAR.o
+
+@
+<<OVAR.NRLIB (NRLIB from MID)>>=
+${MID}/OVAR.NRLIB: ${MID}/OVAR.spad
+ @ echo 0 making ${MID}/OVAR.NRLIB from ${MID}/OVAR.spad
+ @ (cd ${MID} ; echo ')co OVAR.spad' | ${INTERPSYS} )
+
+@
+<<OVAR.spad (SPAD from IN)>>=
+${MID}/OVAR.spad: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${MID}/OVAR.spad from ${IN}/variable.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OVAR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OVAR OrderedVariableList" ${IN}/variable.spad.pamphlet >OVAR.spad )
+
+@
+<<RULECOLD.o (O from NRLIB)>>=
+${OUT}/RULECOLD.o: ${MID}/RULECOLD.NRLIB
+ @ echo 0 making ${OUT}/RULECOLD.o from ${MID}/RULECOLD.NRLIB
+ @ cp ${MID}/RULECOLD.NRLIB/code.o ${OUT}/RULECOLD.o
+
+@
+<<RULECOLD.NRLIB (NRLIB from MID)>>=
+${MID}/RULECOLD.NRLIB: ${MID}/RULECOLD.spad
+ @ echo 0 making ${MID}/RULECOLD.NRLIB from ${MID}/RULECOLD.spad
+ @ (cd ${MID} ; echo ')co RULECOLD.spad' | ${INTERPSYS} )
+
+@
+<<RULECOLD.spad (SPAD from IN)>>=
+${MID}/RULECOLD.spad: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${MID}/RULECOLD.spad from ${IN}/variable.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RULECOLD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain RULECOLD RuleCalled" ${IN}/variable.spad.pamphlet >RULECOLD.spad )
+
+@
+<<VARIABLE.o (O from NRLIB)>>=
+${OUT}/VARIABLE.o: ${MID}/VARIABLE.NRLIB
+ @ echo 0 making ${OUT}/VARIABLE.o from ${MID}/VARIABLE.NRLIB
+ @ cp ${MID}/VARIABLE.NRLIB/code.o ${OUT}/VARIABLE.o
+
+@
+<<VARIABLE.NRLIB (NRLIB from MID)>>=
+${MID}/VARIABLE.NRLIB: ${MID}/VARIABLE.spad
+ @ echo 0 making ${MID}/VARIABLE.NRLIB from ${MID}/VARIABLE.spad
+ @ (cd ${MID} ; echo ')co VARIABLE.spad' | ${INTERPSYS} )
+
+@
+<<VARIABLE.spad (SPAD from IN)>>=
+${MID}/VARIABLE.spad: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${MID}/VARIABLE.spad from ${IN}/variable.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VARIABLE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain VARIABLE Variable" ${IN}/variable.spad.pamphlet >VARIABLE.spad )
+
+@
+<<variable.spad.dvi (DOC from IN)>>=
+${DOC}/variable.spad.dvi: ${IN}/variable.spad.pamphlet
+ @ echo 0 making ${DOC}/variable.spad.dvi from ${IN}/variable.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/variable.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} variable.spad ; \
+ rm -f ${DOC}/variable.spad.pamphlet ; \
+ rm -f ${DOC}/variable.spad.tex ; \
+ rm -f ${DOC}/variable.spad )
+
+@
+\subsection{vector.spad \cite{1}}
+<<vector.spad (SPAD from IN)>>=
+${MID}/vector.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/vector.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/vector.spad.pamphlet >vector.spad )
+
+@
+<<DIRPCAT-.o (O from NRLIB)>>=
+${OUT}/DIRPCAT-.o: ${MID}/DIRPCAT.NRLIB
+ @ echo 0 making ${OUT}/DIRPCAT-.o from ${MID}/DIRPCAT-.NRLIB
+ @ cp ${MID}/DIRPCAT-.NRLIB/code.o ${OUT}/DIRPCAT-.o
+
+@
+<<DIRPCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/DIRPCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/DIRPCAT.spad
+ @ echo 0 making ${MID}/DIRPCAT-.NRLIB from ${MID}/DIRPCAT.spad
+ @ (cd ${MID} ; echo ')co DIRPCAT.spad' | ${INTERPSYS} )
+
+@
+<<DIRPCAT.o (O from NRLIB)>>=
+${OUT}/DIRPCAT.o: ${MID}/DIRPCAT.NRLIB
+ @ echo 0 making ${OUT}/DIRPCAT.o from ${MID}/DIRPCAT.NRLIB
+ @ cp ${MID}/DIRPCAT.NRLIB/code.o ${OUT}/DIRPCAT.o
+
+@
+<<DIRPCAT.NRLIB (NRLIB from MID)>>=
+${MID}/DIRPCAT.NRLIB: ${MID}/DIRPCAT.spad
+ @ echo 0 making ${MID}/DIRPCAT.NRLIB from ${MID}/DIRPCAT.spad
+ @ (cd ${MID} ; echo ')co DIRPCAT.spad' | ${INTERPSYS} )
+
+@
+<<DIRPCAT.spad (SPAD from IN)>>=
+${MID}/DIRPCAT.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/DIRPCAT.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIRPCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category DIRPCAT DirectProductCategory" ${IN}/vector.spad.pamphlet >DIRPCAT.spad )
+
+@
+<<DIRPROD.o (O from NRLIB)>>=
+${OUT}/DIRPROD.o: ${MID}/DIRPROD.NRLIB
+ @ echo 0 making ${OUT}/DIRPROD.o from ${MID}/DIRPROD.NRLIB
+ @ cp ${MID}/DIRPROD.NRLIB/code.o ${OUT}/DIRPROD.o
+
+@
+<<DIRPROD.NRLIB (NRLIB from MID)>>=
+${MID}/DIRPROD.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/DIRPROD.spad
+ @ echo 0 making ${MID}/DIRPROD.NRLIB from ${MID}/DIRPROD.spad
+ @ (cd ${MID} ; echo ')co DIRPROD.spad' | ${INTERPSYS} )
+
+@
+<<DIRPROD.spad (SPAD from IN)>>=
+${MID}/DIRPROD.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/DIRPROD.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIRPROD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain DIRPROD DirectProduct" ${IN}/vector.spad.pamphlet >DIRPROD.spad )
+
+@
+<<DIRPROD2.o (O from NRLIB)>>=
+${OUT}/DIRPROD2.o: ${MID}/DIRPROD2.NRLIB
+ @ echo 0 making ${OUT}/DIRPROD2.o from ${MID}/DIRPROD2.NRLIB
+ @ cp ${MID}/DIRPROD2.NRLIB/code.o ${OUT}/DIRPROD2.o
+
+@
+<<DIRPROD2.NRLIB (NRLIB from MID)>>=
+${MID}/DIRPROD2.NRLIB: ${MID}/DIRPROD2.spad
+ @ echo 0 making ${MID}/DIRPROD2.NRLIB from ${MID}/DIRPROD2.spad
+ @ (cd ${MID} ; echo ')co DIRPROD2.spad' | ${INTERPSYS} )
+
+@
+<<DIRPROD2.spad (SPAD from IN)>>=
+${MID}/DIRPROD2.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/DIRPROD2.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf DIRPROD2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package DIRPROD2 DirectProductFunctions2" ${IN}/vector.spad.pamphlet >DIRPROD2.spad )
+
+@
+<<IVECTOR.o (O from NRLIB)>>=
+${OUT}/IVECTOR.o: ${MID}/IVECTOR.NRLIB
+ @ echo 0 making ${OUT}/IVECTOR.o from ${MID}/IVECTOR.NRLIB
+ @ cp ${MID}/IVECTOR.NRLIB/code.o ${OUT}/IVECTOR.o
+
+@
+<<IVECTOR.NRLIB (NRLIB from MID)>>=
+${MID}/IVECTOR.NRLIB: ${MID}/IVECTOR.spad
+ @ echo 0 making ${MID}/IVECTOR.NRLIB from ${MID}/IVECTOR.spad
+ @ (cd ${MID} ; echo ')co IVECTOR.spad' | ${INTERPSYS} )
+
+@
+<<IVECTOR.spad (SPAD from IN)>>=
+${MID}/IVECTOR.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/IVECTOR.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf IVECTOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain IVECTOR IndexedVector" ${IN}/vector.spad.pamphlet >IVECTOR.spad )
+
+@
+<<VECTCAT-.o (O from NRLIB)>>=
+${OUT}/VECTCAT-.o: ${MID}/VECTCAT.NRLIB
+ @ echo 0 making ${OUT}/VECTCAT-.o from ${MID}/VECTCAT-.NRLIB
+ @ cp ${MID}/VECTCAT-.NRLIB/code.o ${OUT}/VECTCAT-.o
+
+@
+<<VECTCAT-.NRLIB (NRLIB from MID)>>=
+${MID}/VECTCAT-.NRLIB: ${OUT}/TYPE.o ${MID}/VECTCAT.spad
+ @ echo 0 making ${MID}/VECTCAT-.NRLIB from ${MID}/VECTCAT.spad
+ @ (cd ${MID} ; echo ')co VECTCAT.spad' | ${INTERPSYS} )
+
+@
+<<VECTCAT.o (O from NRLIB)>>=
+${OUT}/VECTCAT.o: ${MID}/VECTCAT.NRLIB
+ @ echo 0 making ${OUT}/VECTCAT.o from ${MID}/VECTCAT.NRLIB
+ @ cp ${MID}/VECTCAT.NRLIB/code.o ${OUT}/VECTCAT.o
+
+@
+<<VECTCAT.NRLIB (NRLIB from MID)>>=
+${MID}/VECTCAT.NRLIB: ${MID}/VECTCAT.spad
+ @ echo 0 making ${MID}/VECTCAT.NRLIB from ${MID}/VECTCAT.spad
+ @ (cd ${MID} ; echo ')co VECTCAT.spad' | ${INTERPSYS} )
+
+@
+<<VECTCAT.spad (SPAD from IN)>>=
+${MID}/VECTCAT.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/VECTCAT.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VECTCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category VECTCAT VectorCategory" ${IN}/vector.spad.pamphlet >VECTCAT.spad )
+
+@
+<<VECTOR.o (O from NRLIB)>>=
+${OUT}/VECTOR.o: ${MID}/VECTOR.NRLIB
+ @ echo 0 making ${OUT}/VECTOR.o from ${MID}/VECTOR.NRLIB
+ @ cp ${MID}/VECTOR.NRLIB/code.o ${OUT}/VECTOR.o
+
+@
+<<VECTOR.NRLIB (NRLIB from MID)>>=
+${MID}/VECTOR.NRLIB: ${MID}/VECTOR.spad
+ @ echo 0 making ${MID}/VECTOR.NRLIB from ${MID}/VECTOR.spad
+ @ (cd ${MID} ; echo ')co VECTOR.spad' | ${INTERPSYS} )
+
+@
+<<VECTOR.spad (SPAD from IN)>>=
+${MID}/VECTOR.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/VECTOR.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VECTOR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain VECTOR Vector" ${IN}/boolean.spad.pamphlet >VECTOR.spad )
+
+@
+<<VECTOR.o (BOOTSTRAP from MID)>>=
+${MID}/VECTOR.o: ${MID}/VECTOR.lsp
+ @ echo 0 making ${MID}/VECTOR.o from ${MID}/VECTOR.lsp
+ @ (cd ${MID} ; \
+ echo '(progn (in-package (quote boot)) (compile-file "VECTOR.lsp" :output-file "VECTOR.o"))' | ${DEPSYS} )
+ @ cp ${MID}/VECTOR.o ${OUT}/VECTOR.o
+
+@
+<<VECTOR.lsp (LISP from IN)>>=
+${MID}/VECTOR.lsp: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/VECTOR.lsp from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VECTOR.NRLIB ; \
+ rm -rf ${OUT}/VECTOR.o ; \
+ ${SPADBIN}/notangle -R"VECTOR.lsp BOOTSTRAP" ${IN}/vector.spad.pamphlet >VECTOR.lsp )
+
+@
+<<VECTOR2.o (O from NRLIB)>>=
+${OUT}/VECTOR2.o: ${MID}/VECTOR2.NRLIB
+ @ echo 0 making ${OUT}/VECTOR2.o from ${MID}/VECTOR2.NRLIB
+ @ cp ${MID}/VECTOR2.NRLIB/code.o ${OUT}/VECTOR2.o
+
+@
+<<VECTOR2.NRLIB (NRLIB from MID)>>=
+${MID}/VECTOR2.NRLIB: ${MID}/VECTOR2.spad
+ @ echo 0 making ${MID}/VECTOR2.NRLIB from ${MID}/VECTOR2.spad
+ @ (cd ${MID} ; echo ')co VECTOR2.spad' | ${INTERPSYS} )
+
+@
+<<VECTOR2.spad (SPAD from IN)>>=
+${MID}/VECTOR2.spad: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${MID}/VECTOR2.spad from ${IN}/vector.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VECTOR2.NRLIB ; \
+ ${SPADBIN}/notangle -R"package VECTOR2 VectorFunctions2" ${IN}/vector.spad.pamphlet >VECTOR2.spad )
+
+@
+<<vector.spad.dvi (DOC from IN)>>=
+${DOC}/vector.spad.dvi: ${IN}/vector.spad.pamphlet
+ @ echo 0 making ${DOC}/vector.spad.dvi from ${IN}/vector.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/vector.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} vector.spad ; \
+ rm -f ${DOC}/vector.spad.pamphlet ; \
+ rm -f ${DOC}/vector.spad.tex ; \
+ rm -f ${DOC}/vector.spad )
+
+@
+\subsection{view2D.spad \cite{1}}
+<<view2D.spad (SPAD from IN)>>=
+${MID}/view2D.spad: ${IN}/view2D.spad.pamphlet
+ @ echo 0 making ${MID}/view2D.spad from ${IN}/view2D.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/view2D.spad.pamphlet >view2D.spad )
+
+@
+<<GRIMAGE.o (O from NRLIB)>>=
+${OUT}/GRIMAGE.o: ${MID}/GRIMAGE.NRLIB
+ @ echo 0 making ${OUT}/GRIMAGE.o from ${MID}/GRIMAGE.NRLIB
+ @ cp ${MID}/GRIMAGE.NRLIB/code.o ${OUT}/GRIMAGE.o
+
+@
+<<GRIMAGE.NRLIB (NRLIB from MID)>>=
+${MID}/GRIMAGE.NRLIB: ${MID}/GRIMAGE.spad
+ @ echo 0 making ${MID}/GRIMAGE.NRLIB from ${MID}/GRIMAGE.spad
+ @ (cd ${MID} ; echo ')co GRIMAGE.spad' | ${INTERPSYS} )
+
+@
+<<GRIMAGE.spad (SPAD from IN)>>=
+${MID}/GRIMAGE.spad: ${IN}/view2D.spad.pamphlet
+ @ echo 0 making ${MID}/GRIMAGE.spad from ${IN}/view2D.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf GRIMAGE.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain GRIMAGE GraphImage" ${IN}/view2D.spad.pamphlet >GRIMAGE.spad )
+
+@
+<<VIEW2D.o (O from NRLIB)>>=
+${OUT}/VIEW2D.o: ${MID}/VIEW2D.NRLIB
+ @ echo 0 making ${OUT}/VIEW2D.o from ${MID}/VIEW2D.NRLIB
+ @ cp ${MID}/VIEW2D.NRLIB/code.o ${OUT}/VIEW2D.o
+
+@
+<<VIEW2D.NRLIB (NRLIB from MID)>>=
+${MID}/VIEW2D.NRLIB: ${MID}/VIEW2D.spad
+ @ echo 0 making ${MID}/VIEW2D.NRLIB from ${MID}/VIEW2D.spad
+ @ (cd ${MID} ; echo ')co VIEW2D.spad' | ${INTERPSYS} )
+
+@
+<<VIEW2D.spad (SPAD from IN)>>=
+${MID}/VIEW2D.spad: ${IN}/view2D.spad.pamphlet
+ @ echo 0 making ${MID}/VIEW2D.spad from ${IN}/view2D.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VIEW2D.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain VIEW2D TwoDimensionalViewport" ${IN}/view2D.spad.pamphlet >VIEW2D.spad )
+
+@
+<<view2D.spad.dvi (DOC from IN)>>=
+${DOC}/view2D.spad.dvi: ${IN}/view2D.spad.pamphlet
+ @ echo 0 making ${DOC}/view2D.spad.dvi from ${IN}/view2D.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/view2D.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} view2D.spad ; \
+ rm -f ${DOC}/view2D.spad.pamphlet ; \
+ rm -f ${DOC}/view2D.spad.tex ; \
+ rm -f ${DOC}/view2D.spad )
+
+@
+\subsection{view3D.spad \cite{1}}
+<<view3D.spad (SPAD from IN)>>=
+${MID}/view3D.spad: ${IN}/view3D.spad.pamphlet
+ @ echo 0 making ${MID}/view3D.spad from ${IN}/view3D.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/view3D.spad.pamphlet >view3D.spad )
+
+@
+<<VIEW3D.o (O from NRLIB)>>=
+${OUT}/VIEW3D.o: ${MID}/VIEW3D.NRLIB
+ @ echo 0 making ${OUT}/VIEW3D.o from ${MID}/VIEW3D.NRLIB
+ @ cp ${MID}/VIEW3D.NRLIB/code.o ${OUT}/VIEW3D.o
+
+@
+<<VIEW3D.NRLIB (NRLIB from MID)>>=
+${MID}/VIEW3D.NRLIB: ${MID}/VIEW3D.spad
+ @ echo 0 making ${MID}/VIEW3D.NRLIB from ${MID}/VIEW3D.spad
+ @ (cd ${MID} ; echo ')co VIEW3D.spad' | ${INTERPSYS} )
+
+@
+<<VIEW3D.spad (SPAD from IN)>>=
+${MID}/VIEW3D.spad: ${IN}/view3D.spad.pamphlet
+ @ echo 0 making ${MID}/VIEW3D.spad from ${IN}/view3D.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VIEW3D.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain VIEW3D ThreeDimensionalViewport" ${IN}/view3D.spad.pamphlet >VIEW3D.spad )
+
+@
+<<view3D.spad.dvi (DOC from IN)>>=
+${DOC}/view3D.spad.dvi: ${IN}/view3D.spad.pamphlet
+ @ echo 0 making ${DOC}/view3D.spad.dvi from ${IN}/view3D.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/view3D.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} view3D.spad ; \
+ rm -f ${DOC}/view3D.spad.pamphlet ; \
+ rm -f ${DOC}/view3D.spad.tex ; \
+ rm -f ${DOC}/view3D.spad )
+
+@
+\subsection{viewDef.spad \cite{1}}
+<<viewDef.spad (SPAD from IN)>>=
+${MID}/viewDef.spad: ${IN}/viewDef.spad.pamphlet
+ @ echo 0 making ${MID}/viewDef.spad from ${IN}/viewDef.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/viewDef.spad.pamphlet >viewDef.spad )
+
+@
+<<VIEWDEF.o (O from NRLIB)>>=
+${OUT}/VIEWDEF.o: ${MID}/VIEWDEF.NRLIB
+ @ echo 0 making ${OUT}/VIEWDEF.o from ${MID}/VIEWDEF.NRLIB
+ @ cp ${MID}/VIEWDEF.NRLIB/code.o ${OUT}/VIEWDEF.o
+
+@
+<<VIEWDEF.NRLIB (NRLIB from MID)>>=
+${MID}/VIEWDEF.NRLIB: ${MID}/VIEWDEF.spad
+ @ echo 0 making ${MID}/VIEWDEF.NRLIB from ${MID}/VIEWDEF.spad
+ @ (cd ${MID} ; echo ')co VIEWDEF.spad' | ${INTERPSYS} )
+
+@
+<<VIEWDEF.spad (SPAD from IN)>>=
+${MID}/VIEWDEF.spad: ${IN}/viewDef.spad.pamphlet
+ @ echo 0 making ${MID}/VIEWDEF.spad from ${IN}/viewDef.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VIEWDEF.NRLIB ; \
+ ${SPADBIN}/notangle -R"package VIEWDEF ViewDefaultsPackage" ${IN}/viewDef.spad.pamphlet >VIEWDEF.spad )
+
+@
+<<viewDef.spad.dvi (DOC from IN)>>=
+${DOC}/viewDef.spad.dvi: ${IN}/viewDef.spad.pamphlet
+ @ echo 0 making ${DOC}/viewDef.spad.dvi from ${IN}/viewDef.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/viewDef.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} viewDef.spad ; \
+ rm -f ${DOC}/viewDef.spad.pamphlet ; \
+ rm -f ${DOC}/viewDef.spad.tex ; \
+ rm -f ${DOC}/viewDef.spad )
+
+@
+\subsection{viewpack.spad \cite{1}}
+<<viewpack.spad (SPAD from IN)>>=
+${MID}/viewpack.spad: ${IN}/viewpack.spad.pamphlet
+ @ echo 0 making ${MID}/viewpack.spad from ${IN}/viewpack.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/viewpack.spad.pamphlet >viewpack.spad )
+
+@
+<<VIEW.o (O from NRLIB)>>=
+${OUT}/VIEW.o: ${MID}/VIEW.NRLIB
+ @ echo 0 making ${OUT}/VIEW.o from ${MID}/VIEW.NRLIB
+ @ cp ${MID}/VIEW.NRLIB/code.o ${OUT}/VIEW.o
+
+@
+<<VIEW.NRLIB (NRLIB from MID)>>=
+${MID}/VIEW.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/VIEW.spad
+ @ echo 0 making ${MID}/VIEW.NRLIB from ${MID}/VIEW.spad
+ @ (cd ${MID} ; echo ')co VIEW.spad' | ${INTERPSYS} )
+
+@
+<<VIEW.spad (SPAD from IN)>>=
+${MID}/VIEW.spad: ${IN}/viewpack.spad.pamphlet
+ @ echo 0 making ${MID}/VIEW.spad from ${IN}/viewpack.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VIEW.NRLIB ; \
+ ${SPADBIN}/notangle -R"package VIEW ViewportPackage" ${IN}/viewpack.spad.pamphlet >VIEW.spad )
+
+@
+<<viewpack.spad.dvi (DOC from IN)>>=
+${DOC}/viewpack.spad.dvi: ${IN}/viewpack.spad.pamphlet
+ @ echo 0 making ${DOC}/viewpack.spad.dvi from ${IN}/viewpack.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/viewpack.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} viewpack.spad ; \
+ rm -f ${DOC}/viewpack.spad.pamphlet ; \
+ rm -f ${DOC}/viewpack.spad.tex ; \
+ rm -f ${DOC}/viewpack.spad )
+
+@
+\subsection{void.spad \cite{1}}
+<<void.spad (SPAD from IN)>>=
+${MID}/void.spad: ${IN}/void.spad.pamphlet
+ @ echo 0 making ${MID}/void.spad from ${IN}/void.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/void.spad.pamphlet >void.spad )
+
+@
+<<EXIT.o (O from NRLIB)>>=
+${OUT}/EXIT.o: ${MID}/EXIT.NRLIB
+ @ echo 0 making ${OUT}/EXIT.o from ${MID}/EXIT.NRLIB
+ @ cp ${MID}/EXIT.NRLIB/code.o ${OUT}/EXIT.o
+
+@
+<<EXIT.NRLIB (NRLIB from MID)>>=
+${MID}/EXIT.NRLIB: ${MID}/EXIT.spad
+ @ echo 0 making ${MID}/EXIT.NRLIB from ${MID}/EXIT.spad
+ @ (cd ${MID} ; echo ')co EXIT.spad' | ${INTERPSYS} )
+
+@
+<<EXIT.spad (SPAD from IN)>>=
+${MID}/EXIT.spad: ${IN}/void.spad.pamphlet
+ @ echo 0 making ${MID}/EXIT.spad from ${IN}/void.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf EXIT.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain EXIT Exit" ${IN}/void.spad.pamphlet >EXIT.spad )
+
+@
+<<RESLATC.o (O from NRLIB)>>=
+${OUT}/RESLATC.o: ${MID}/RESLATC.NRLIB
+ @ echo 0 making ${OUT}/RESLATC.o from ${MID}/RESLATC.NRLIB
+ @ cp ${MID}/RESLATC.NRLIB/code.o ${OUT}/RESLATC.o
+
+@
+<<RESLATC.NRLIB (NRLIB from MID)>>=
+${MID}/RESLATC.NRLIB: ${OUT}/TYPE.o ${MID}/RESLATC.spad
+ @ echo 0 making ${MID}/RESLATC.NRLIB from ${MID}/RESLATC.spad
+ @ (cd ${MID} ; echo ')co RESLATC.spad' | ${INTERPSYS} )
+
+@
+<<RESLATC.spad (SPAD from IN)>>=
+${MID}/RESLATC.spad: ${IN}/void.spad.pamphlet
+ @ echo 0 making ${MID}/RESLATC.spad from ${IN}/void.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf RESLATC.NRLIB ; \
+ ${SPADBIN}/notangle -R"package RESLATC ResolveLatticeCompletion" ${IN}/void.spad.pamphlet >RESLATC.spad )
+
+@
+<<VOID.o (O from NRLIB)>>=
+${OUT}/VOID.o: ${MID}/VOID.NRLIB
+ @ echo 0 making ${OUT}/VOID.o from ${MID}/VOID.NRLIB
+ @ cp ${MID}/VOID.NRLIB/code.o ${OUT}/VOID.o
+
+@
+<<VOID.NRLIB (NRLIB from MID)>>=
+${MID}/VOID.NRLIB: ${MID}/VOID.spad
+ @ echo 0 making ${MID}/VOID.NRLIB from ${MID}/VOID.spad
+ @ (cd ${MID} ; echo ')co VOID.spad' | ${INTERPSYS} )
+
+@
+<<VOID.spad (SPAD from IN)>>=
+${MID}/VOID.spad: ${IN}/void.spad.pamphlet
+ @ echo 0 making ${MID}/VOID.spad from ${IN}/void.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf VOID.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain VOID Void" ${IN}/void.spad.pamphlet >VOID.spad )
+
+@
+<<void.spad.dvi (DOC from IN)>>=
+${DOC}/void.spad.dvi: ${IN}/void.spad.pamphlet
+ @ echo 0 making ${DOC}/void.spad.dvi from ${IN}/void.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/void.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} void.spad ; \
+ rm -f ${DOC}/void.spad.pamphlet ; \
+ rm -f ${DOC}/void.spad.tex ; \
+ rm -f ${DOC}/void.spad )
+
+@
+\subsection{weier.spad \cite{1}}
+<<weier.spad (SPAD from IN)>>=
+${MID}/weier.spad: ${IN}/weier.spad.pamphlet
+ @ echo 0 making ${MID}/weier.spad from ${IN}/weier.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/weier.spad.pamphlet >weier.spad )
+
+@
+<<WEIER.o (O from NRLIB)>>=
+${OUT}/WEIER.o: ${MID}/WEIER.NRLIB
+ @ echo 0 making ${OUT}/WEIER.o from ${MID}/WEIER.NRLIB
+ @ cp ${MID}/WEIER.NRLIB/code.o ${OUT}/WEIER.o
+
+@
+<<WEIER.NRLIB (NRLIB from MID)>>=
+${MID}/WEIER.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/WEIER.spad
+ @ echo 0 making ${MID}/WEIER.NRLIB from ${MID}/WEIER.spad
+ @ (cd ${MID} ; echo ')co WEIER.spad' | ${INTERPSYS} )
+
+@
+<<WEIER.spad (SPAD from IN)>>=
+${MID}/WEIER.spad: ${IN}/weier.spad.pamphlet
+ @ echo 0 making ${MID}/WEIER.spad from ${IN}/weier.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf WEIER.NRLIB ; \
+ ${SPADBIN}/notangle -R"package WEIER WeierstrassPreparation" ${IN}/weier.spad.pamphlet >WEIER.spad )
+
+@
+<<weier.spad.dvi (DOC from IN)>>=
+${DOC}/weier.spad.dvi: ${IN}/weier.spad.pamphlet
+ @ echo 0 making ${DOC}/weier.spad.dvi from ${IN}/weier.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/weier.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} weier.spad ; \
+ rm -f ${DOC}/weier.spad.pamphlet ; \
+ rm -f ${DOC}/weier.spad.tex ; \
+ rm -f ${DOC}/weier.spad )
+
+@
+\subsection{wtpol.spad \cite{1}}
+<<wtpol.spad (SPAD from IN)>>=
+${MID}/wtpol.spad: ${IN}/wtpol.spad.pamphlet
+ @ echo 0 making ${MID}/wtpol.spad from ${IN}/wtpol.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/wtpol.spad.pamphlet >wtpol.spad )
+
+@
+<<OWP.o (O from NRLIB)>>=
+${OUT}/OWP.o: ${MID}/OWP.NRLIB
+ @ echo 0 making ${OUT}/OWP.o from ${MID}/OWP.NRLIB
+ @ cp ${MID}/OWP.NRLIB/code.o ${OUT}/OWP.o
+
+@
+<<OWP.NRLIB (NRLIB from MID)>>=
+${MID}/OWP.NRLIB: ${MID}/OWP.spad
+ @ echo 0 making ${MID}/OWP.NRLIB from ${MID}/OWP.spad
+ @ (cd ${MID} ; echo ')co OWP.spad' | ${INTERPSYS} )
+
+@
+<<OWP.spad (SPAD from IN)>>=
+${MID}/OWP.spad: ${IN}/wtpol.spad.pamphlet
+ @ echo 0 making ${MID}/OWP.spad from ${IN}/wtpol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OWP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OWP OrdinaryWeightedPolynomials" ${IN}/wtpol.spad.pamphlet >OWP.spad )
+
+@
+<<WP.o (O from NRLIB)>>=
+${OUT}/WP.o: ${MID}/WP.NRLIB
+ @ echo 0 making ${OUT}/WP.o from ${MID}/WP.NRLIB
+ @ cp ${MID}/WP.NRLIB/code.o ${OUT}/WP.o
+
+@
+<<WP.NRLIB (NRLIB from MID)>>=
+${MID}/WP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/WP.spad
+ @ echo 0 making ${MID}/WP.NRLIB from ${MID}/WP.spad
+ @ (cd ${MID} ; echo ')co WP.spad' | ${INTERPSYS} )
+
+@
+<<WP.spad (SPAD from IN)>>=
+${MID}/WP.spad: ${IN}/wtpol.spad.pamphlet
+ @ echo 0 making ${MID}/WP.spad from ${IN}/wtpol.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf WP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain WP WeightedPolynomials" ${IN}/wtpol.spad.pamphlet >WP.spad )
+
+@
+<<wtpol.spad.dvi (DOC from IN)>>=
+${DOC}/wtpol.spad.dvi: ${IN}/wtpol.spad.pamphlet
+ @ echo 0 making ${DOC}/wtpol.spad.dvi from ${IN}/wtpol.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/wtpol.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} wtpol.spad ; \
+ rm -f ${DOC}/wtpol.spad.pamphlet ; \
+ rm -f ${DOC}/wtpol.spad.tex ; \
+ rm -f ${DOC}/wtpol.spad )
+
+@
+\subsection{xlpoly.spad \cite{1}}
+<<xlpoly.spad (SPAD from IN)>>=
+${MID}/xlpoly.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/xlpoly.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/xlpoly.spad.pamphlet >xlpoly.spad )
+
+@
+<<FLALG.o (O from NRLIB)>>=
+${OUT}/FLALG.o: ${MID}/FLALG.NRLIB
+ @ echo 0 making ${OUT}/FLALG.o from ${MID}/FLALG.NRLIB
+ @ cp ${MID}/FLALG.NRLIB/code.o ${OUT}/FLALG.o
+
+@
+<<FLALG.NRLIB (NRLIB from MID)>>=
+${MID}/FLALG.NRLIB: ${MID}/FLALG.spad
+ @ echo 0 making ${MID}/FLALG.NRLIB from ${MID}/FLALG.spad
+ @ (cd ${MID} ; echo ')co FLALG.spad' | ${INTERPSYS} )
+
+@
+<<FLALG.spad (SPAD from IN)>>=
+${MID}/FLALG.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/FLALG.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FLALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FLALG FreeLieAlgebra" ${IN}/xlpoly.spad.pamphlet >FLALG.spad )
+
+@
+<<LEXP.o (O from NRLIB)>>=
+${OUT}/LEXP.o: ${MID}/LEXP.NRLIB
+ @ echo 0 making ${OUT}/LEXP.o from ${MID}/LEXP.NRLIB
+ @ cp ${MID}/LEXP.NRLIB/code.o ${OUT}/LEXP.o
+
+@
+<<LEXP.NRLIB (NRLIB from MID)>>=
+${MID}/LEXP.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/LEXP.spad
+ @ echo 0 making ${MID}/LEXP.NRLIB from ${MID}/LEXP.spad
+ @ (cd ${MID} ; echo ')co LEXP.spad' | ${INTERPSYS} )
+
+@
+<<LEXP.spad (SPAD from IN)>>=
+${MID}/LEXP.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/LEXP.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LEXP.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LEXP LieExponentials" ${IN}/xlpoly.spad.pamphlet >LEXP.spad )
+
+@
+<<LIECAT-.o (O from NRLIB)>>=
+${OUT}/LIECAT-.o: ${MID}/LIECAT.NRLIB
+ @ echo 0 making ${OUT}/LIECAT-.o from ${MID}/LIECAT-.NRLIB
+ @ cp ${MID}/LIECAT-.NRLIB/code.o ${OUT}/LIECAT-.o
+
+@
+<<LIECAT-.NRLIB (NRLIB from MID)>>=
+${MID}/LIECAT-.NRLIB: ${OUT}/TYPE.o ${MID}/LIECAT.spad
+ @ echo 0 making ${MID}/LIECAT-.NRLIB from ${MID}/LIECAT.spad
+ @ (cd ${MID} ; echo ')co LIECAT.spad' | ${INTERPSYS} )
+
+@
+<<LIECAT.o (O from NRLIB)>>=
+${OUT}/LIECAT.o: ${MID}/LIECAT.NRLIB
+ @ echo 0 making ${OUT}/LIECAT.o from ${MID}/LIECAT.NRLIB
+ @ cp ${MID}/LIECAT.NRLIB/code.o ${OUT}/LIECAT.o
+
+@
+<<LIECAT.NRLIB (NRLIB from MID)>>=
+${MID}/LIECAT.NRLIB: ${MID}/LIECAT.spad
+ @ echo 0 making ${MID}/LIECAT.NRLIB from ${MID}/LIECAT.spad
+ @ (cd ${MID} ; echo ')co LIECAT.spad' | ${INTERPSYS} )
+
+@
+<<LIECAT.spad (SPAD from IN)>>=
+${MID}/LIECAT.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/LIECAT.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LIECAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category LIECAT LieAlgebra" ${IN}/xlpoly.spad.pamphlet >LIECAT.spad )
+
+@
+<<LPOLY.o (O from NRLIB)>>=
+${OUT}/LPOLY.o: ${MID}/LPOLY.NRLIB
+ @ echo 0 making ${OUT}/LPOLY.o from ${MID}/LPOLY.NRLIB
+ @ cp ${MID}/LPOLY.NRLIB/code.o ${OUT}/LPOLY.o
+
+@
+<<LPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/LPOLY.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/LPOLY.spad
+ @ echo 0 making ${MID}/LPOLY.NRLIB from ${MID}/LPOLY.spad
+ @ (cd ${MID} ; echo ')co LPOLY.spad' | ${INTERPSYS} )
+
+@
+<<LPOLY.spad (SPAD from IN)>>=
+${MID}/LPOLY.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/LPOLY.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LPOLY LiePolynomial" ${IN}/xlpoly.spad.pamphlet >LPOLY.spad )
+
+@
+<<LWORD.o (O from NRLIB)>>=
+${OUT}/LWORD.o: ${MID}/LWORD.NRLIB
+ @ echo 0 making ${OUT}/LWORD.o from ${MID}/LWORD.NRLIB
+ @ cp ${MID}/LWORD.NRLIB/code.o ${OUT}/LWORD.o
+
+@
+<<LWORD.NRLIB (NRLIB from MID)>>=
+${MID}/LWORD.NRLIB: ${MID}/LWORD.spad
+ @ echo 0 making ${MID}/LWORD.NRLIB from ${MID}/LWORD.spad
+ @ (cd ${MID} ; echo ')co LWORD.spad' | ${INTERPSYS} )
+
+@
+<<LWORD.spad (SPAD from IN)>>=
+${MID}/LWORD.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/LWORD.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf LWORD.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain LWORD LyndonWord" ${IN}/xlpoly.spad.pamphlet >LWORD.spad )
+
+@
+<<MAGMA.o (O from NRLIB)>>=
+${OUT}/MAGMA.o: ${MID}/MAGMA.NRLIB
+ @ echo 0 making ${OUT}/MAGMA.o from ${MID}/MAGMA.NRLIB
+ @ cp ${MID}/MAGMA.NRLIB/code.o ${OUT}/MAGMA.o
+
+@
+<<MAGMA.NRLIB (NRLIB from MID)>>=
+${MID}/MAGMA.NRLIB: ${MID}/MAGMA.spad
+ @ echo 0 making ${MID}/MAGMA.NRLIB from ${MID}/MAGMA.spad
+ @ (cd ${MID} ; echo ')co MAGMA.spad' | ${INTERPSYS} )
+
+@
+<<MAGMA.spad (SPAD from IN)>>=
+${MID}/MAGMA.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/MAGMA.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf MAGMA.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain MAGMA Magma" ${IN}/xlpoly.spad.pamphlet >MAGMA.spad )
+
+@
+<<PBWLB.o (O from NRLIB)>>=
+${OUT}/PBWLB.o: ${MID}/PBWLB.NRLIB
+ @ echo 0 making ${OUT}/PBWLB.o from ${MID}/PBWLB.NRLIB
+ @ cp ${MID}/PBWLB.NRLIB/code.o ${OUT}/PBWLB.o
+
+@
+<<PBWLB.NRLIB (NRLIB from MID)>>=
+${MID}/PBWLB.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/PBWLB.spad
+ @ echo 0 making ${MID}/PBWLB.NRLIB from ${MID}/PBWLB.spad
+ @ (cd ${MID} ; echo ')co PBWLB.spad' | ${INTERPSYS} )
+
+@
+<<PBWLB.spad (SPAD from IN)>>=
+${MID}/PBWLB.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/PBWLB.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf PBWLB.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain PBWLB PoincareBirkhoffWittLyndonBasis" ${IN}/xlpoly.spad.pamphlet >PBWLB.spad )
+
+@
+<<XEXPPKG.o (O from NRLIB)>>=
+${OUT}/XEXPPKG.o: ${MID}/XEXPPKG.NRLIB
+ @ echo 0 making ${OUT}/XEXPPKG.o from ${MID}/XEXPPKG.NRLIB
+ @ cp ${MID}/XEXPPKG.NRLIB/code.o ${OUT}/XEXPPKG.o
+
+@
+<<XEXPPKG.NRLIB (NRLIB from MID)>>=
+${MID}/XEXPPKG.NRLIB: ${MID}/XEXPPKG.spad
+ @ echo 0 making ${MID}/XEXPPKG.NRLIB from ${MID}/XEXPPKG.spad
+ @ (cd ${MID} ; echo ')co XEXPPKG.spad' | ${INTERPSYS} )
+
+@
+<<XEXPPKG.spad (SPAD from IN)>>=
+${MID}/XEXPPKG.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XEXPPKG.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XEXPPKG.NRLIB ; \
+ ${SPADBIN}/notangle -R"package XEXPPKG XExponentialPackage" ${IN}/xlpoly.spad.pamphlet >XEXPPKG.spad )
+
+@
+<<XPBWPOLY.o (O from NRLIB)>>=
+${OUT}/XPBWPOLY.o: ${MID}/XPBWPOLY.NRLIB
+ @ echo 0 making ${OUT}/XPBWPOLY.o from ${MID}/XPBWPOLY.NRLIB
+ @ cp ${MID}/XPBWPOLY.NRLIB/code.o ${OUT}/XPBWPOLY.o
+
+@
+<<XPBWPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/XPBWPOLY.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/XPBWPOLY.spad
+ @ echo 0 making ${MID}/XPBWPOLY.NRLIB from ${MID}/XPBWPOLY.spad
+ @ (cd ${MID} ; echo ')co XPBWPOLY.spad' | ${INTERPSYS} )
+
+@
+<<XPBWPOLY.spad (SPAD from IN)>>=
+${MID}/XPBWPOLY.spad: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XPBWPOLY.spad from ${IN}/xlpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XPBWPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain XPBWPOLY XPBWPolynomial" ${IN}/xlpoly.spad.pamphlet >XPBWPOLY.spad )
+
+@
+<<xlpoly.spad.dvi (DOC from IN)>>=
+${DOC}/xlpoly.spad.dvi: ${IN}/xlpoly.spad.pamphlet
+ @ echo 0 making ${DOC}/xlpoly.spad.dvi from ${IN}/xlpoly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/xlpoly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} xlpoly.spad ; \
+ rm -f ${DOC}/xlpoly.spad.pamphlet ; \
+ rm -f ${DOC}/xlpoly.spad.tex ; \
+ rm -f ${DOC}/xlpoly.spad )
+
+@
+\subsection{xpoly.spad \cite{1}}
+<<xpoly.spad (SPAD from IN)>>=
+${MID}/xpoly.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/xpoly.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/xpoly.spad.pamphlet >xpoly.spad )
+
+@
+<<FMCAT.o (O from NRLIB)>>=
+${OUT}/FMCAT.o: ${MID}/FMCAT.NRLIB
+ @ echo 0 making ${OUT}/FMCAT.o from ${MID}/FMCAT.NRLIB
+ @ cp ${MID}/FMCAT.NRLIB/code.o ${OUT}/FMCAT.o
+
+@
+<<FMCAT.NRLIB (NRLIB from MID)>>=
+${MID}/FMCAT.NRLIB: ${MID}/FMCAT.spad
+ @ echo 0 making ${MID}/FMCAT.NRLIB from ${MID}/FMCAT.spad
+ @ (cd ${MID} ; echo ')co FMCAT.spad' | ${INTERPSYS} )
+
+@
+<<FMCAT.spad (SPAD from IN)>>=
+${MID}/FMCAT.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/FMCAT.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FMCAT.NRLIB ; \
+ ${SPADBIN}/notangle -R"category FMCAT FreeModuleCat" ${IN}/xpoly.spad.pamphlet >FMCAT.spad )
+
+@
+<<FM1.o (O from NRLIB)>>=
+${OUT}/FM1.o: ${MID}/FM1.NRLIB
+ @ echo 0 making ${OUT}/FM1.o from ${MID}/FM1.NRLIB
+ @ cp ${MID}/FM1.NRLIB/code.o ${OUT}/FM1.o
+
+@
+<<FM1.NRLIB (NRLIB from MID)>>=
+${MID}/FM1.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/FM1.spad
+ @ echo 0 making ${MID}/FM1.NRLIB from ${MID}/FM1.spad
+ @ (cd ${MID} ; echo ')co FM1.spad' | ${INTERPSYS} )
+
+@
+<<FM1.spad (SPAD from IN)>>=
+${MID}/FM1.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/FM1.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FM1.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain FM1 FreeModule1" ${IN}/xpoly.spad.pamphlet >FM1.spad )
+
+@
+<<OFMONOID.o (O from NRLIB)>>=
+${OUT}/OFMONOID.o: ${MID}/OFMONOID.NRLIB
+ @ echo 0 making ${OUT}/OFMONOID.o from ${MID}/OFMONOID.NRLIB
+ @ cp ${MID}/OFMONOID.NRLIB/code.o ${OUT}/OFMONOID.o
+
+@
+<<OFMONOID.NRLIB (NRLIB from MID)>>=
+${MID}/OFMONOID.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/OFMONOID.spad
+ @ echo 0 making ${MID}/OFMONOID.NRLIB from ${MID}/OFMONOID.spad
+ @ (cd ${MID} ; echo ')co OFMONOID.spad' | ${INTERPSYS} )
+
+@
+<<OFMONOID.spad (SPAD from IN)>>=
+${MID}/OFMONOID.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/OFMONOID.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf OFMONOID.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain OFMONOID OrderedFreeMonoid" ${IN}/xpoly.spad.pamphlet >OFMONOID.spad )
+
+@
+<<XALG.o (O from NRLIB)>>=
+${OUT}/XALG.o: ${MID}/XALG.NRLIB
+ @ echo 0 making ${OUT}/XALG.o from ${MID}/XALG.NRLIB
+ @ cp ${MID}/XALG.NRLIB/code.o ${OUT}/XALG.o
+
+@
+<<XALG.NRLIB (NRLIB from MID)>>=
+${MID}/XALG.NRLIB: ${MID}/XALG.spad
+ @ echo 0 making ${MID}/XALG.NRLIB from ${MID}/XALG.spad
+ @ (cd ${MID} ; echo ')co XALG.spad' | ${INTERPSYS} )
+
+@
+<<XALG.spad (SPAD from IN)>>=
+${MID}/XALG.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XALG.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category XALG XAlgebra" ${IN}/xpoly.spad.pamphlet >XALG.spad )
+
+@
+<<XDPOLY.o (O from NRLIB)>>=
+${OUT}/XDPOLY.o: ${MID}/XDPOLY.NRLIB
+ @ echo 0 making ${OUT}/XDPOLY.o from ${MID}/XDPOLY.NRLIB
+ @ cp ${MID}/XDPOLY.NRLIB/code.o ${OUT}/XDPOLY.o
+
+@
+<<XDPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/XDPOLY.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/XDPOLY.spad
+ @ echo 0 making ${MID}/XDPOLY.NRLIB from ${MID}/XDPOLY.spad
+ @ (cd ${MID} ; echo ')co XDPOLY.spad' | ${INTERPSYS} )
+
+@
+<<XDPOLY.spad (SPAD from IN)>>=
+${MID}/XDPOLY.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XDPOLY.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XDPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain XDPOLY XDistributedPolynomial" ${IN}/xpoly.spad.pamphlet >XDPOLY.spad )
+
+@
+<<XFALG.o (O from NRLIB)>>=
+${OUT}/XFALG.o: ${MID}/XFALG.NRLIB
+ @ echo 0 making ${OUT}/XFALG.o from ${MID}/XFALG.NRLIB
+ @ cp ${MID}/XFALG.NRLIB/code.o ${OUT}/XFALG.o
+
+@
+<<XFALG.NRLIB (NRLIB from MID)>>=
+${MID}/XFALG.NRLIB: ${MID}/XFALG.spad
+ @ echo 0 making ${MID}/XFALG.NRLIB from ${MID}/XFALG.spad
+ @ (cd ${MID} ; echo ')co XFALG.spad' | ${INTERPSYS} )
+
+@
+<<XFALG.spad (SPAD from IN)>>=
+${MID}/XFALG.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XFALG.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XFALG.NRLIB ; \
+ ${SPADBIN}/notangle -R"category XFALG XFreeAlgebra" ${IN}/xpoly.spad.pamphlet >XFALG.spad )
+
+@
+<<XPOLY.o (O from NRLIB)>>=
+${OUT}/XPOLY.o: ${MID}/XPOLY.NRLIB
+ @ echo 0 making ${OUT}/XPOLY.o from ${MID}/XPOLY.NRLIB
+ @ cp ${MID}/XPOLY.NRLIB/code.o ${OUT}/XPOLY.o
+
+@
+<<XPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/XPOLY.NRLIB: ${MID}/XPOLY.spad
+ @ echo 0 making ${MID}/XPOLY.NRLIB from ${MID}/XPOLY.spad
+ @ (cd ${MID} ; echo ')co XPOLY.spad' | ${INTERPSYS} )
+
+@
+<<XPOLY.spad (SPAD from IN)>>=
+${MID}/XPOLY.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XPOLY.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain XPOLY XPolynomial" ${IN}/xpoly.spad.pamphlet >XPOLY.spad )
+
+@
+<<XPOLYC.o (O from NRLIB)>>=
+${OUT}/XPOLYC.o: ${MID}/XPOLYC.NRLIB
+ @ echo 0 making ${OUT}/XPOLYC.o from ${MID}/XPOLYC.NRLIB
+ @ cp ${MID}/XPOLYC.NRLIB/code.o ${OUT}/XPOLYC.o
+
+@
+<<XPOLYC.NRLIB (NRLIB from MID)>>=
+${MID}/XPOLYC.NRLIB: ${MID}/XPOLYC.spad
+ @ echo 0 making ${MID}/XPOLYC.NRLIB from ${MID}/XPOLYC.spad
+ @ (cd ${MID} ; echo ')co XPOLYC.spad' | ${INTERPSYS} )
+
+@
+<<XPOLYC.spad (SPAD from IN)>>=
+${MID}/XPOLYC.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XPOLYC.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XPOLYC.NRLIB ; \
+ ${SPADBIN}/notangle -R"category XPOLYC XPolynomialsCat" ${IN}/xpoly.spad.pamphlet >XPOLYC.spad )
+
+@
+<<XPR.o (O from NRLIB)>>=
+${OUT}/XPR.o: ${MID}/XPR.NRLIB
+ @ echo 0 making ${OUT}/XPR.o from ${MID}/XPR.NRLIB
+ @ cp ${MID}/XPR.NRLIB/code.o ${OUT}/XPR.o
+
+@
+<<XPR.NRLIB (NRLIB from MID)>>=
+${MID}/XPR.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/XPR.spad
+ @ echo 0 making ${MID}/XPR.NRLIB from ${MID}/XPR.spad
+ @ (cd ${MID} ; echo ')co XPR.spad' | ${INTERPSYS} )
+
+@
+<<XPR.spad (SPAD from IN)>>=
+${MID}/XPR.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XPR.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XPR.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain XPR XPolynomialRing" ${IN}/xpoly.spad.pamphlet >XPR.spad )
+
+@
+<<XRPOLY.o (O from NRLIB)>>=
+${OUT}/XRPOLY.o: ${MID}/XRPOLY.NRLIB
+ @ echo 0 making ${OUT}/XRPOLY.o from ${MID}/XRPOLY.NRLIB
+ @ cp ${MID}/XRPOLY.NRLIB/code.o ${OUT}/XRPOLY.o
+
+@
+<<XRPOLY.NRLIB (NRLIB from MID)>>=
+${MID}/XRPOLY.NRLIB: ${OUT}/KONVERT.o ${OUT}/TYPE.o ${MID}/XRPOLY.spad
+ @ echo 0 making ${MID}/XRPOLY.NRLIB from ${MID}/XRPOLY.spad
+ @ (cd ${MID} ; echo ')co XRPOLY.spad' | ${INTERPSYS} )
+
+@
+<<XRPOLY.spad (SPAD from IN)>>=
+${MID}/XRPOLY.spad: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${MID}/XRPOLY.spad from ${IN}/xpoly.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf XRPOLY.NRLIB ; \
+ ${SPADBIN}/notangle -R"domain XRPOLY XRecursivePolynomial" ${IN}/xpoly.spad.pamphlet >XRPOLY.spad )
+
+@
+<<xpoly.spad.dvi (DOC from IN)>>=
+${DOC}/xpoly.spad.dvi: ${IN}/xpoly.spad.pamphlet
+ @ echo 0 making ${DOC}/xpoly.spad.dvi from ${IN}/xpoly.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/xpoly.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} xpoly.spad ; \
+ rm -f ${DOC}/xpoly.spad.pamphlet ; \
+ rm -f ${DOC}/xpoly.spad.tex ; \
+ rm -f ${DOC}/xpoly.spad )
+
+@
+\subsection{ystream.spad \cite{1}}
+<<ystream.spad (SPAD from IN)>>=
+${MID}/ystream.spad: ${IN}/ystream.spad.pamphlet
+ @ echo 0 making ${MID}/ystream.spad from ${IN}/ystream.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/ystream.spad.pamphlet >ystream.spad )
+
+@
+<<YSTREAM.o (O from NRLIB)>>=
+${OUT}/YSTREAM.o: ${MID}/YSTREAM.NRLIB
+ @ echo 0 making ${OUT}/YSTREAM.o from ${MID}/YSTREAM.NRLIB
+ @ cp ${MID}/YSTREAM.NRLIB/code.o ${OUT}/YSTREAM.o
+
+@
+<<YSTREAM.NRLIB (NRLIB from MID)>>=
+${MID}/YSTREAM.NRLIB: ${MID}/YSTREAM.spad
+ @ echo 0 making ${MID}/YSTREAM.NRLIB from ${MID}/YSTREAM.spad
+ @ (cd ${MID} ; echo ')co YSTREAM.spad' | ${INTERPSYS} )
+
+@
+<<YSTREAM.spad (SPAD from IN)>>=
+${MID}/YSTREAM.spad: ${IN}/ystream.spad.pamphlet
+ @ echo 0 making ${MID}/YSTREAM.spad from ${IN}/ystream.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf YSTREAM.NRLIB ; \
+ ${SPADBIN}/notangle -R"package YSTREAM ParadoxicalCombinatorsForStreams" ${IN}/ystream.spad.pamphlet >YSTREAM.spad )
+
+@
+<<ystream.spad.dvi (DOC from IN)>>=
+${DOC}/ystream.spad.dvi: ${IN}/ystream.spad.pamphlet
+ @ echo 0 making ${DOC}/ystream.spad.dvi from ${IN}/ystream.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/ystream.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} ystream.spad ; \
+ rm -f ${DOC}/ystream.spad.pamphlet ; \
+ rm -f ${DOC}/ystream.spad.tex ; \
+ rm -f ${DOC}/ystream.spad )
+
+@
+\subsection{zerodim.spad \cite{1}}
+<<zerodim.spad (SPAD from IN)>>=
+${MID}/zerodim.spad: ${IN}/zerodim.spad.pamphlet
+ @ echo 0 making ${MID}/zerodim.spad from ${IN}/zerodim.spad.pamphlet
+ @(cd ${MID} ; \
+ ${SPADBIN}/notangle ${IN}/zerodim.spad.pamphlet >zerodim.spad )
+
+@
+<<FGLMICPK.o (O from NRLIB)>>=
+${OUT}/FGLMICPK.o: ${MID}/FGLMICPK.NRLIB
+ @ echo 0 making ${OUT}/FGLMICPK.o from ${MID}/FGLMICPK.NRLIB
+ @ cp ${MID}/FGLMICPK.NRLIB/code.o ${OUT}/FGLMICPK.o
+
+@
+<<FGLMICPK.NRLIB (NRLIB from MID)>>=
+${MID}/FGLMICPK.NRLIB: ${MID}/FGLMICPK.spad
+ @ echo 0 making ${MID}/FGLMICPK.NRLIB from ${MID}/FGLMICPK.spad
+ @ (cd ${MID} ; echo ')co FGLMICPK.spad' | ${INTERPSYS} )
+
+@
+<<FGLMICPK.spad (SPAD from IN)>>=
+${MID}/FGLMICPK.spad: ${IN}/zerodim.spad.pamphlet
+ @ echo 0 making ${MID}/FGLMICPK.spad from ${IN}/zerodim.spad.pamphlet
+ @(cd ${MID} ; \
+ rm -rf FGLMICPK.NRLIB ; \
+ ${SPADBIN}/notangle -R"package FGLMICPK FGLMIfCanPackage" ${IN}/zerodim.spad.pamphlet >FGLMICPK.spad )
+
+@
+<<zerodim.spad.dvi (DOC from IN)>>=
+${DOC}/zerodim.spad.dvi: ${IN}/zerodim.spad.pamphlet
+ @ echo 0 making ${DOC}/zerodim.spad.dvi from ${IN}/zerodim.spad.pamphlet
+ @ (cd ${DOC} ; \
+ cp ${IN}/zerodim.spad.pamphlet ${DOC} ; \
+ ${SPADBIN}/document ${NOISE} zerodim.spad ; \
+ rm -f ${DOC}/zerodim.spad.pamphlet ; \
+ rm -f ${DOC}/zerodim.spad.tex ; \
+ rm -f ${DOC}/zerodim.spad )
+
+@
+
+<<original Makefile>>=
+## src/algebra Makeile
+# subparts:
+# db --- make databases for the current machine
+# db-win32 --- make databases for PCs
+
+IN= ${SRC}/algebra
+
+MID= ${INT}/algebra
+CENTER= ${INT}/lib/unix
+WIN32CENTER= ${INT}/lib/win32
+MAIL= ${MID}/libcheck
+
+OUT= ${MNT}/${SYS}/algebra
+
+WIN32OUT=${MNT}/win32/algebra
+
+LIB= ${INT}/lib
+
+DEPSYS= ${OBJ}/${SYS}/bin/depsys
+
+INTERPSYS= ${MNT}/${SYS}/bin/AXIOMsys
+WIN32INTERPSYS = ${MNT}/${SYS}/bin/AXIOMsys-win32
+AS= ibits.as
+
+cmd: ${CENTER} ${CENTER}/libdb.text
+ @ echo Building command.list
+ @ (cat ${CENTER}/libdb.text |sed -n "s/^o//p" |sed s\/\`\.\*\/\/p |sort -u > ${CENTER}/command.list )
+ @ (cat ${CENTER}/libdb.text |sed -n "s/^c//p" |sed s\/\`\.\*\/\/p |sort -u >> ${CENTER}/command.list )
+ @ (cat ${CENTER}/libdb.text |sed -n "s/^d//p" |sed s\/\`\.\*\/\/p |sort -u >> ${CENTER}/command.list )
+ @ (cat ${CENTER}/libdb.text |sed -n "s/^p//p" |sed s\/\`\.\*\/\/p |sort -u >> ${CENTER}/command.list )
+
+lib: ${OBJ}/${SYS}/etc/helpmake.o
+ @ echo checking libraries...
+ @ echo comparing dates ...
+ @ echo '(progn (let ((*package* (find-package "BOOT"))) (load "${OBJ}/${SYS}/etc/helpmake") (boot::makelib "${MID}" "${OUT}" "${LISP}" "${O}")) (${BYE}))' | ${DEPSYS}
+
+${OBJ}/${SYS}/etc/helpmake.${O} : ${SRC}/etc/helpmake.${LISP}
+ @ echo Rebuilding helpmake ...
+ @ (cd ${OBJ}/${SYS} ; \
+ echo '(progn (let ((*package* (find-package "BOOT"))) (compile-file "${SRC}/etc/helpmake.${LISP}" :output-file "${OBJ}/${SYS}/etc/helpmake.${O}"))) (${BYE})' | ${DEPSYS} )
+
+gloss: ${CENTER}
+ @ echo rebuilding glossary...
+ @ cp -p ${SRC}/doc/gloss.text ${CENTER}
+# buildGloss needs it in share/algebra
+ @ cp -p ${SRC}/doc/gloss.text ${SPD}/share/algebra
+ @ (cd ${MID} ; \
+ echo ')fin' >/tmp/tmp.input ; \
+ echo '(|oldCompilerAutoloadOnceTrigger|)' >>/tmp/tmp.input ; \
+ echo '(|browserAutoloadOnceTrigger|)' >>/tmp/tmp.input ; \
+ echo '(|buildGloss|)' >>/tmp/tmp.input ; \
+ echo '(bye)' >>/tmp/tmp.input ; \
+ cat /tmp/tmp.input | ${INTERPSYS} ; \
+ rm -f /tmp/tmp.input )
+ @ echo installing glosskey.text
+ @ mv ${MID}/glosskey.text ${CENTER}
+ @ echo installing glossdef.text
+ @ mv ${MID}/glossdef.text ${CENTER}
+ @ echo installing gloss.ht
+ @ cp -p ${MID}/gloss.ht ${SPD}/share/doc/hypertex/pages
+ @ cp -p ${MID}/gloss.ht ${INT}/paste
+ @ echo adding gloss.ht to ht database
+ @ htadd -s gloss.ht
+
+${CENTER} :
+ mkdir ${CENTER}
+
+${WIN32CENTER} :
+ mkdir ${WIN32CENTER}
+
+
+db: ${CENTER}
+ @ echo rebuilding databases...
+ @ cp -p ${SRC}/doc/gloss.text ${LIB}
+ @ cp -p ${SRC}/doc/topics.data ${MID}
+ @ echo rebuilding daase files
+ @ (cd ${MID} ; \
+ echo ')set out le 200' >/tmp/tmp.input ; \
+ echo ')fin' >>/tmp/tmp.input ; \
+ echo '(make-databases "" (QUOTE ("unix")))' >>/tmp/tmp.input ; \
+ echo '(bye)' >>/tmp/tmp.input ; \
+ cat /tmp/tmp.input | ${INTERPSYS} ; \
+ rm -f /tmp/tmp.input )
+ @ echo If all went well, go-ahead Mike and do a db-install as well !
+
+db-install:
+#
+# Now move everything to int/lib/unix
+#
+ @ echo moving ${MID}/unix/compress.daase to ${CENTER}/
+ @ mv ${MID}/unix/compress.daase ${CENTER}/
+#
+ @ echo moving ${MID}/unix/interp.daase to ${CENTER}/
+ @ mv ${MID}/unix/interp.daase ${CENTER}/
+#
+ @ echo moving ${MID}/unix/browse.daase to ${CENTER}/
+ @ mv ${MID}/unix/browse.daase ${CENTER}/
+#
+ @ echo moving ${MID}/unix/category.daase to ${CENTER}/
+ @ mv ${MID}/unix/category.daase ${CENTER}/
+#
+ @ echo moving ${MID}/unix/operation.daase to ${CENTER}/
+ @ mv ${MID}/unix/operation.daase ${CENTER}/
+#
+ @ echo moving ${MID}/unix/USERS.DAASE to ${CENTER}
+ @ rm -rf ${CENTER}/USERS.DAASE
+ @ mv ${MID}/unix/USERS.DAASE ${CENTER}
+#
+ @ echo moving ${MID}/unix/DEPENDENTS.DAASE to ${CENTER}
+ @ rm -rf ${CENTER}/DEPENDENTS.DAASE
+ @ mv ${MID}/unix/DEPENDENTS.DAASE ${CENTER}
+#
+ @ echo moving ${MID}/unix/libdb.text to ${CENTER}
+ @ mv ${MID}/unix/libdb.text ${CENTER}
+#
+ @ echo moving ${MID}/unix/comdb.text to ${CENTER}
+ @ mv ${MID}/unix/comdb.text ${CENTER}
+#
+ @ echo Now you need to promote the databases \(make PART=dbpromote\)
+ @ echo Then remake and promote the *.img files
+# @ echo rebuilding interpsys with the new database
+# @ touch ${OBJ}/${SYS}/interp/database.date
+# @ (cd ${SPD} ; ${MAKE} PART=interp)
+
+db-win32:
+ echo rebuilding databases...
+ cp -p ${IN}/INTERP.EXPOSED ${MID}
+ cp -p ${IN}/INTERP.EXPOSED ${WIN32CENTER}
+ cp -p ${SRC}/doc/gloss.text ${LIB}
+ cp -p ${SRC}/doc/topics.data ${MID}
+ echo rebuilding daase files
+ (cd ${MID} ; \
+ echo ')fin' >/tmp/tmp.input ; \
+ echo '(make-databases "-win32" (QUOTE ("win32")))' >>/tmp/tmp.input ; \
+ echo '(bye)' >>/tmp/tmp.input ; \
+ cat /tmp/tmp.input | ${WIN32INTERPSYS} ; \
+ rm -f /tmp/tmp.input )
+
+db-win32-install:
+ @ echo moving ${MID}/compress.daase-win32 to ${WIN32CENTER}/compress.daase
+ @ mv ${MID}/win32/compress.daase-win32 ${WIN32CENTER}/compress.daase
+ @ echo moving ${MID}/interp.daase-win32 to ${WIN32CENTER}/interp.daase
+ @ mv ${MID}/win32/interp.daase-win32 ${WIN32CENTER}/interp.daase
+ @ echo moving ${MID}/browse.daase-win32 to ${WIN32CENTER}/browse.daase-
+ @ mv ${MID}/win32/browse.daase-win32 ${WIN32CENTER}/browse.daase
+ @ echo moving ${MID}/category.daase-win32 to ${WIN32CENTER}/category.daase
+ @ mv ${MID}/win32/category.daase-win32 ${WIN32CENTER}/category.daase
+ @ echo moving ${MID}/operation.daase-win32 to ${WIN32CENTER}/operation.daase
+ @ mv ${MID}/win32/operation.daase-win32 ${WIN32CENTER}/operation.daase
+ @ echo installing libdb.text
+ @ mv ${MID}/win32/libdb.text ${WIN32CENTER}
+ @ echo installing comdb.text
+ @ mv ${MID}/win32/comdb.text ${WIN32CENTER}
+# @ echo installing glosskey.text
+# @ mv ${MID}/win32/glosskey.text ${WIN32CENTER}
+# @ echo installing glossdef.text
+# @ mv ${MID}/win32/glossdef.text ${WIN32CENTER}
+
+ibits.as: ${MID}/ibits.nrlib/ibits.l
+ @echo building ${MID}/ibits.o from ibits.as
+ @( cd ${MID} ; \
+ rm -rf ibits.nrlib ; \
+ mkdir ibits.nrlib ; \
+ cd ibits.nrlib ; \
+ asharp -Fl -Fasy ${SRC}/ibits.as )
+
+@
+<<*>>=
+
+<<layer0 bootstrap>>
+<<layer0>>
+<<layer1>>
+<<layer2>>
+<<layer3>>
+<<layer4>>
+<<layer5>>
+<<layer6>>
+<<layer7>>
+<<layer8>>
+<<layer9>>
+<<layer10>>
+<<layer11>>
+<<layer12>>
+<<layer13>>
+<<layer14>>
+<<layer15>>
+<<layer16>>
+<<layer17>>
+<<layer18>>
+<<layer19>>
+<<layer20>>
+<<layer21>>
+<<order>>
+
+all: src db
+#all: ${SUBPART}
+
+everything: check lib db cmd gloss
+ @ echo invoking make in `pwd` with parms:
+ @ echo SYS= ${SYS} LSP= ${LSP} PART= ${PART} SUBPART= ${SUBPART}
+ @ echo SPAD= ${SPAD} SRC= ${SRC} INT= ${INT}
+ @ echo OBJ= ${OBJ} MNT= ${MNT} O=${O} LISP=${LISP} BYE=${BYE}
+
+#src: ${AS}
+src: ${SPADFILES} ${ORDER}
+ @ echo Building NRLIBS from spad sources
+
+# @ (cd ${MID} ; \
+# echo '(progn (let ((*package* (find-package "BOOT"))) (boot::makespad "${MID}" "${MID}" "${LISP}")) (${BYE}))' | ${DEPSYS} )
+
+db:
+ @ echo rebuilding databases...
+ @ cp ${SRC}/doc/gloss.text ${MID}
+ @ cp ${SRC}/doc/topics.data ${MID}
+ @ (cd ${MID} ; echo ')lisp (make-databases "" nil)' | ${INTERPSYS} )
+
+check:
+ @ echo Checking that INTERP.EXPOSED and NRLIBs are consistent
+ @ (cd ${MID} ; \
+ echo '(progn (let ((*package* (find-package "BOOT"))) (boot::libcheck "${IN}" "${MID}" "${OUT}" "${MAIL}")) (${BYE}))' | ${DEPSYS} )
+
+
+document: ${DOCFILES}
+
+<<ACPLOT.o (O from NRLIB)>>
+<<ACPLOT.NRLIB (NRLIB from MID)>>
+<<ACPLOT.spad (SPAD from IN)>>
+
+<<REALSOLV.o (O from NRLIB)>>
+<<REALSOLV.NRLIB (NRLIB from MID)>>
+<<REALSOLV.spad (SPAD from IN)>>
+
+<<acplot.spad (SPAD from IN)>>
+<<acplot.spad.dvi (DOC from IN)>>
+
+<<FLAGG2.o (O from NRLIB)>>
+<<FLAGG2.NRLIB (NRLIB from MID)>>
+<<FLAGG2.spad (SPAD from IN)>>
+
+<<FSAGG2.o (O from NRLIB)>>
+<<FSAGG2.NRLIB (NRLIB from MID)>>
+<<FSAGG2.spad (SPAD from IN)>>
+
+<<aggcat2.spad (SPAD from IN)>>
+<<aggcat2.spad.dvi (DOC from IN)>>
+
+<<ALAGG.o (O from NRLIB)>>
+<<ALAGG.NRLIB (NRLIB from MID)>>
+<<ALAGG.spad (SPAD from IN)>>
+<<ALAGG.o (BOOTSTRAP from MID)>>
+<<ALAGG.lsp (LISP from IN)>>
+
+<<A1AGG-.o (O from NRLIB)>>
+<<A1AGG-.NRLIB (NRLIB from MID)>>
+<<A1AGG.o (O from NRLIB)>>
+<<A1AGG.NRLIB (NRLIB from MID)>>
+<<A1AGG.spad (SPAD from IN)>>
+
+<<AGG-.o (O from NRLIB)>>
+<<AGG-.NRLIB (NRLIB from MID)>>
+<<AGG.o (O from NRLIB)>>
+<<AGG.NRLIB (NRLIB from MID)>>
+<<AGG.spad (SPAD from IN)>>
+
+<<BGAGG-.o (O from NRLIB)>>
+<<BGAGG-.NRLIB (NRLIB from MID)>>
+<<BGAGG.o (O from NRLIB)>>
+<<BGAGG.NRLIB (NRLIB from MID)>>
+<<BGAGG.spad (SPAD from IN)>>
+
+<<BTAGG-.o (O from NRLIB)>>
+<<BTAGG-.NRLIB (NRLIB from MID)>>
+<<BTAGG.o (O from NRLIB)>>
+<<BTAGG.NRLIB (NRLIB from MID)>>
+<<BTAGG.spad (SPAD from IN)>>
+
+<<BRAGG-.o (O from NRLIB)>>
+<<BRAGG-.NRLIB (NRLIB from MID)>>
+<<BRAGG.o (O from NRLIB)>>
+<<BRAGG.NRLIB (NRLIB from MID)>>
+<<BRAGG.spad (SPAD from IN)>>
+
+<<CLAGG-.o (O from NRLIB)>>
+<<CLAGG-.NRLIB (NRLIB from MID)>>
+<<CLAGG.o (O from NRLIB)>>
+<<CLAGG.NRLIB (NRLIB from MID)>>
+<<CLAGG.spad (SPAD from IN)>>
+<<CLAGG-.o (BOOTSTRAP from MID)>>
+<<CLAGG-.lsp (LISP from IN)>>
+<<CLAGG.o (BOOTSTRAP from MID)>>
+<<CLAGG.lsp (LISP from IN)>>
+
+<<DIAGG-.o (O from NRLIB)>>
+<<DIAGG-.NRLIB (NRLIB from MID)>>
+<<DIAGG.o (O from NRLIB)>>
+<<DIAGG.NRLIB (NRLIB from MID)>>
+<<DIAGG.spad (SPAD from IN)>>
+
+<<DIOPS-.o (O from NRLIB)>>
+<<DIOPS-.NRLIB (NRLIB from MID)>>
+<<DIOPS.o (O from NRLIB)>>
+<<DIOPS.NRLIB (NRLIB from MID)>>
+<<DIOPS.spad (SPAD from IN)>>
+
+<<DLAGG.o (O from NRLIB)>>
+<<DLAGG.NRLIB (NRLIB from MID)>>
+<<DLAGG.spad (SPAD from IN)>>
+
+<<DQAGG.o (O from NRLIB)>>
+<<DQAGG.NRLIB (NRLIB from MID)>>
+<<DQAGG.spad (SPAD from IN)>>
+
+<<ELAGG-.o (O from NRLIB)>>
+<<ELAGG-.NRLIB (NRLIB from MID)>>
+<<ELAGG.o (O from NRLIB)>>
+<<ELAGG.NRLIB (NRLIB from MID)>>
+<<ELAGG.spad (SPAD from IN)>>
+
+<<ELTAGG-.o (O from NRLIB)>>
+<<ELTAGG-.NRLIB (NRLIB from MID)>>
+<<ELTAGG.o (O from NRLIB)>>
+<<ELTAGG.NRLIB (NRLIB from MID)>>
+<<ELTAGG.spad (SPAD from IN)>>
+
+<<ELTAB.o (O from NRLIB)>>
+<<ELTAB.NRLIB (NRLIB from MID)>>
+<<ELTAB.spad (SPAD from IN)>>
+
+<<FLAGG-.o (O from NRLIB)>>
+<<FLAGG-.NRLIB (NRLIB from MID)>>
+<<FLAGG.o (O from NRLIB)>>
+<<FLAGG.NRLIB (NRLIB from MID)>>
+<<FLAGG.spad (SPAD from IN)>>
+
+<<FSAGG-.o (O from NRLIB)>>
+<<FSAGG-.NRLIB (NRLIB from MID)>>
+<<FSAGG.o (O from NRLIB)>>
+<<FSAGG.NRLIB (NRLIB from MID)>>
+<<FSAGG.spad (SPAD from IN)>>
+
+<<MSETAGG.o (O from NRLIB)>>
+<<MSETAGG.NRLIB (NRLIB from MID)>>
+<<MSETAGG.spad (SPAD from IN)>>
+
+<<HOAGG-.o (O from NRLIB)>>
+<<HOAGG-.NRLIB (NRLIB from MID)>>
+<<HOAGG.o (O from NRLIB)>>
+<<HOAGG.NRLIB (NRLIB from MID)>>
+<<HOAGG.spad (SPAD from IN)>>
+<<HOAGG-.o (BOOTSTRAP from MID)>>
+<<HOAGG-.lsp (LISP from IN)>>
+<<HOAGG.o (BOOTSTRAP from MID)>>
+<<HOAGG.lsp (LISP from IN)>>
+
+<<IXAGG-.o (O from NRLIB)>>
+<<IXAGG-.NRLIB (NRLIB from MID)>>
+<<IXAGG.o (O from NRLIB)>>
+<<IXAGG.NRLIB (NRLIB from MID)>>
+<<IXAGG.spad (SPAD from IN)>>
+
+<<KDAGG-.o (O from NRLIB)>>
+<<KDAGG-.NRLIB (NRLIB from MID)>>
+<<KDAGG.o (O from NRLIB)>>
+<<KDAGG.NRLIB (NRLIB from MID)>>
+<<KDAGG.spad (SPAD from IN)>>
+
+<<LNAGG-.o (O from NRLIB)>>
+<<LNAGG-.NRLIB (NRLIB from MID)>>
+<<LNAGG.o (O from NRLIB)>>
+<<LNAGG.NRLIB (NRLIB from MID)>>
+<<LNAGG.spad (SPAD from IN)>>
+<<LNAGG-.o (BOOTSTRAP from MID)>>
+<<LNAGG-.lsp (LISP from IN)>>
+<<LNAGG.o (BOOTSTRAP from MID)>>
+<<LNAGG.lsp (LISP from IN)>>
+
+<<LSAGG-.o (O from NRLIB)>>
+<<LSAGG-.NRLIB (NRLIB from MID)>>
+<<LSAGG.o (O from NRLIB)>>
+<<LSAGG.NRLIB (NRLIB from MID)>>
+<<LSAGG.spad (SPAD from IN)>>
+<<LSAGG-.o (BOOTSTRAP from MID)>>
+<<LSAGG-.lsp (LISP from IN)>>
+<<LSAGG.o (BOOTSTRAP from MID)>>
+<<LSAGG.lsp (LISP from IN)>>
+
+<<MDAGG.o (O from NRLIB)>>
+<<MDAGG.NRLIB (NRLIB from MID)>>
+<<MDAGG.spad (SPAD from IN)>>
+
+<<OMSAGG.o (O from NRLIB)>>
+<<OMSAGG.NRLIB (NRLIB from MID)>>
+<<OMSAGG.spad (SPAD from IN)>>
+
+<<PRQAGG.o (O from NRLIB)>>
+<<PRQAGG.NRLIB (NRLIB from MID)>>
+<<PRQAGG.spad (SPAD from IN)>>
+
+<<QUAGG.o (O from NRLIB)>>
+<<QUAGG.NRLIB (NRLIB from MID)>>
+<<QUAGG.spad (SPAD from IN)>>
+
+<<RCAGG-.o (O from NRLIB)>>
+<<RCAGG-.NRLIB (NRLIB from MID)>>
+<<RCAGG.o (O from NRLIB)>>
+<<RCAGG.NRLIB (NRLIB from MID)>>
+<<RCAGG.spad (SPAD from IN)>>
+<<RCAGG-.o (BOOTSTRAP from MID)>>
+<<RCAGG-.lsp (LISP from IN)>>
+<<RCAGG.o (BOOTSTRAP from MID)>>
+<<RCAGG.lsp (LISP from IN)>>
+
+<<SETAGG-.o (O from NRLIB)>>
+<<SETAGG-.NRLIB (NRLIB from MID)>>
+<<SETAGG.o (O from NRLIB)>>
+<<SETAGG.NRLIB (NRLIB from MID)>>
+<<SETAGG.spad (SPAD from IN)>>
+<<SETAGG-.o (BOOTSTRAP from MID)>>
+<<SETAGG-.lsp (LISP from IN)>>
+<<SETAGG.o (BOOTSTRAP from MID)>>
+<<SETAGG.lsp (LISP from IN)>>
+
+<<SKAGG.o (O from NRLIB)>>
+<<SKAGG.NRLIB (NRLIB from MID)>>
+<<SKAGG.spad (SPAD from IN)>>
+
+<<SRAGG-.o (O from NRLIB)>>
+<<SRAGG-.NRLIB (NRLIB from MID)>>
+<<SRAGG.o (O from NRLIB)>>
+<<SRAGG.NRLIB (NRLIB from MID)>>
+<<SRAGG.spad (SPAD from IN)>>
+
+<<STAGG-.o (O from NRLIB)>>
+<<STAGG-.NRLIB (NRLIB from MID)>>
+<<STAGG.o (O from NRLIB)>>
+<<STAGG.NRLIB (NRLIB from MID)>>
+<<STAGG.spad (SPAD from IN)>>
+<<STAGG-.o (BOOTSTRAP from MID)>>
+<<STAGG-.lsp (LISP from IN)>>
+<<STAGG.o (BOOTSTRAP from MID)>>
+<<STAGG.lsp (LISP from IN)>>
+
+<<TBAGG-.o (O from NRLIB)>>
+<<TBAGG-.NRLIB (NRLIB from MID)>>
+<<TBAGG.o (O from NRLIB)>>
+<<TBAGG.NRLIB (NRLIB from MID)>>
+<<TBAGG.spad (SPAD from IN)>>
+
+<<URAGG-.o (O from NRLIB)>>
+<<URAGG-.NRLIB (NRLIB from MID)>>
+<<URAGG.o (O from NRLIB)>>
+<<URAGG.NRLIB (NRLIB from MID)>>
+<<URAGG.spad (SPAD from IN)>>
+<<URAGG-.o (BOOTSTRAP from MID)>>
+<<URAGG-.lsp (LISP from IN)>>
+<<URAGG.o (BOOTSTRAP from MID)>>
+<<URAGG.lsp (LISP from IN)>>
+
+<<aggcat.spad (SPAD from IN)>>
+<<aggcat.spad.dvi (DOC from IN)>>
+
+<<CPIMA.o (O from NRLIB)>>
+<<CPIMA.NRLIB (NRLIB from MID)>>
+<<CPIMA.spad (SPAD from IN)>>
+
+<<FINRALG-.o (O from NRLIB)>>
+<<FINRALG-.NRLIB (NRLIB from MID)>>
+<<FINRALG.o (O from NRLIB)>>
+<<FINRALG.NRLIB (NRLIB from MID)>>
+<<FINRALG.spad (SPAD from IN)>>
+
+<<FRAMALG-.o (O from NRLIB)>>
+<<FRAMALG-.NRLIB (NRLIB from MID)>>
+<<FRAMALG.o (O from NRLIB)>>
+<<FRAMALG.NRLIB (NRLIB from MID)>>
+<<FRAMALG.spad (SPAD from IN)>>
+
+<<MONOGEN-.o (O from NRLIB)>>
+<<MONOGEN-.NRLIB (NRLIB from MID)>>
+<<MONOGEN.o (O from NRLIB)>>
+<<MONOGEN.NRLIB (NRLIB from MID)>>
+<<MONOGEN.spad (SPAD from IN)>>
+
+<<NORMMA.o (O from NRLIB)>>
+<<NORMMA.NRLIB (NRLIB from MID)>>
+<<NORMMA.spad (SPAD from IN)>>
+
+<<algcat.spad (SPAD from IN)>>
+<<algcat.spad.dvi (DOC from IN)>>
+
+<<SAE.o (O from NRLIB)>>
+<<SAE.NRLIB (NRLIB from MID)>>
+<<SAE.spad (SPAD from IN)>>
+
+<<algext.spad (SPAD from IN)>>
+<<algext.spad.dvi (DOC from IN)>>
+
+<<ALGFACT.o (O from NRLIB)>>
+<<ALGFACT.NRLIB (NRLIB from MID)>>
+<<ALGFACT.spad (SPAD from IN)>>
+
+<<IALGFACT.o (O from NRLIB)>>
+<<IALGFACT.NRLIB (NRLIB from MID)>>
+<<IALGFACT.spad (SPAD from IN)>>
+
+<<RFFACT.o (O from NRLIB)>>
+<<RFFACT.NRLIB (NRLIB from MID)>>
+<<RFFACT.spad (SPAD from IN)>>
+
+<<SAEFACT.o (O from NRLIB)>>
+<<SAEFACT.NRLIB (NRLIB from MID)>>
+<<SAEFACT.spad (SPAD from IN)>>
+
+<<SAERFFC.o (O from NRLIB)>>
+<<SAERFFC.NRLIB (NRLIB from MID)>>
+<<SAERFFC.spad (SPAD from IN)>>
+
+<<algfact.spad (SPAD from IN)>>
+<<algfact.spad.dvi (DOC from IN)>>
+
+<<ACF-.o (O from NRLIB)>>
+<<ACF-.NRLIB (NRLIB from MID)>>
+<<ACF.o (O from NRLIB)>>
+<<ACF.NRLIB (NRLIB from MID)>>
+<<ACF.spad (SPAD from IN)>>
+
+<<ACFS-.o (O from NRLIB)>>
+<<ACFS-.NRLIB (NRLIB from MID)>>
+<<ACFS.o (O from NRLIB)>>
+<<ACFS.NRLIB (NRLIB from MID)>>
+<<ACFS.spad (SPAD from IN)>>
+
+<<AF.o (O from NRLIB)>>
+<<AF.NRLIB (NRLIB from MID)>>
+<<AF.spad (SPAD from IN)>>
+
+<<algfunc.spad (SPAD from IN)>>
+<<algfunc.spad.dvi (DOC from IN)>>
+
+<<GENMFACT.o (O from NRLIB)>>
+<<GENMFACT.NRLIB (NRLIB from MID)>>
+<<GENMFACT.spad (SPAD from IN)>>
+
+<<MPCPF.o (O from NRLIB)>>
+<<MPCPF.NRLIB (NRLIB from MID)>>
+<<MPCPF.spad (SPAD from IN)>>
+
+<<MPRFF.o (O from NRLIB)>>
+<<MPRFF.NRLIB (NRLIB from MID)>>
+<<MPRFF.spad (SPAD from IN)>>
+
+<<MRATFAC.o (O from NRLIB)>>
+<<MRATFAC.NRLIB (NRLIB from MID)>>
+<<MRATFAC.spad (SPAD from IN)>>
+
+<<RFFACTOR.o (O from NRLIB)>>
+<<RFFACTOR.NRLIB (NRLIB from MID)>>
+<<RFFACTOR.spad (SPAD from IN)>>
+
+<<SUPFRACF.o (O from NRLIB)>>
+<<SUPFRACF.NRLIB (NRLIB from MID)>>
+<<SUPFRACF.spad (SPAD from IN)>>
+
+<<allfact.spad (SPAD from IN)>>
+<<allfact.spad.dvi (DOC from IN)>>
+
+<<DBASE.o (O from NRLIB)>>
+<<DBASE.NRLIB (NRLIB from MID)>>
+<<DBASE.spad (SPAD from IN)>>
+
+<<DLIST.o (O from NRLIB)>>
+<<DLIST.NRLIB (NRLIB from MID)>>
+<<DLIST.spad (SPAD from IN)>>
+
+<<ICARD.o (O from NRLIB)>>
+<<ICARD.NRLIB (NRLIB from MID)>>
+<<ICARD.spad (SPAD from IN)>>
+
+<<MTHING.o (O from NRLIB)>>
+<<MTHING.NRLIB (NRLIB from MID)>>
+<<MTHING.spad (SPAD from IN)>>
+
+<<OPQUERY.o (O from NRLIB)>>
+<<OPQUERY.NRLIB (NRLIB from MID)>>
+<<OPQUERY.spad (SPAD from IN)>>
+
+<<QEQUAT.o (O from NRLIB)>>
+<<QEQUAT.NRLIB (NRLIB from MID)>>
+<<QEQUAT.spad (SPAD from IN)>>
+
+<<alql.spad (SPAD from IN)>>
+<<alql.spad.dvi (DOC from IN)>>
+
+<<NIPROB.o (O from NRLIB)>>
+<<NIPROB.NRLIB (NRLIB from MID)>>
+<<NIPROB.spad (SPAD from IN)>>
+
+<<NUMINT.o (O from NRLIB)>>
+<<NUMINT.NRLIB (NRLIB from MID)>>
+<<NUMINT.spad (SPAD from IN)>>
+
+<<ODECAT.o (O from NRLIB)>>
+<<ODECAT.NRLIB (NRLIB from MID)>>
+<<ODECAT.spad (SPAD from IN)>>
+
+<<ODEPROB.o (O from NRLIB)>>
+<<ODEPROB.NRLIB (NRLIB from MID)>>
+<<ODEPROB.spad (SPAD from IN)>>
+
+<<OPTPROB.o (O from NRLIB)>>
+<<OPTPROB.NRLIB (NRLIB from MID)>>
+<<OPTPROB.spad (SPAD from IN)>>
+
+<<PDECAT.o (O from NRLIB)>>
+<<PDECAT.NRLIB (NRLIB from MID)>>
+<<PDECAT.spad (SPAD from IN)>>
+
+<<PDEPROB.o (O from NRLIB)>>
+<<PDEPROB.NRLIB (NRLIB from MID)>>
+<<PDEPROB.spad (SPAD from IN)>>
+
+<<OPTCAT.o (O from NRLIB)>>
+<<OPTCAT.NRLIB (NRLIB from MID)>>
+<<OPTCAT.spad (SPAD from IN)>>
+
+<<annacat.spad (SPAD from IN)>>
+<<annacat.spad.dvi (DOC from IN)>>
+
+<<ANY.o (O from NRLIB)>>
+<<ANY.NRLIB (NRLIB from MID)>>
+<<ANY.spad (SPAD from IN)>>
+
+<<ANY1.o (O from NRLIB)>>
+<<ANY1.NRLIB (NRLIB from MID)>>
+<<ANY1.spad (SPAD from IN)>>
+
+<<NONE1.o (O from NRLIB)>>
+<<NONE1.NRLIB (NRLIB from MID)>>
+<<NONE1.spad (SPAD from IN)>>
+
+<<NONE.o (O from NRLIB)>>
+<<NONE.NRLIB (NRLIB from MID)>>
+<<NONE.spad (SPAD from IN)>>
+
+<<any.spad (SPAD from IN)>>
+<<any.spad.dvi (DOC from IN)>>
+
+<<ARRAY1.o (O from NRLIB)>>
+<<ARRAY1.NRLIB (NRLIB from MID)>>
+<<ARRAY1.spad (SPAD from IN)>>
+
+<<ARRAY12.o (O from NRLIB)>>
+<<ARRAY12.NRLIB (NRLIB from MID)>>
+<<ARRAY12.spad (SPAD from IN)>>
+
+<<FARRAY.o (O from NRLIB)>>
+<<FARRAY.NRLIB (NRLIB from MID)>>
+<<FARRAY.spad (SPAD from IN)>>
+
+<<IARRAY1.o (O from NRLIB)>>
+<<IARRAY1.NRLIB (NRLIB from MID)>>
+<<IARRAY1.spad (SPAD from IN)>>
+
+<<IFARRAY.o (O from NRLIB)>>
+<<IFARRAY.NRLIB (NRLIB from MID)>>
+<<IFARRAY.spad (SPAD from IN)>>
+
+<<PRIMARR.o (O from NRLIB)>>
+<<PRIMARR.NRLIB (NRLIB from MID)>>
+<<PRIMARR.spad (SPAD from IN)>>
+<<PRIMARR.o (BOOTSTRAP from MID)>>
+<<PRIMARR.lsp (LISP from IN)>>
+
+<<PRIMARR2.o (O from NRLIB)>>
+<<PRIMARR2.NRLIB (NRLIB from MID)>>
+<<PRIMARR2.spad (SPAD from IN)>>
+
+<<TUPLE.o (O from NRLIB)>>
+<<TUPLE.NRLIB (NRLIB from MID)>>
+<<TUPLE.spad (SPAD from IN)>>
+
+<<array1.spad (SPAD from IN)>>
+<<array1.spad.dvi (DOC from IN)>>
+
+<<ARRAY2.o (O from NRLIB)>>
+<<ARRAY2.NRLIB (NRLIB from MID)>>
+<<ARRAY2.spad (SPAD from IN)>>
+
+<<ARR2CAT-.o (O from NRLIB)>>
+<<ARR2CAT-.NRLIB (NRLIB from MID)>>
+<<ARR2CAT.o (O from NRLIB)>>
+<<ARR2CAT.NRLIB (NRLIB from MID)>>
+<<ARR2CAT.spad (SPAD from IN)>>
+
+<<IARRAY2.o (O from NRLIB)>>
+<<IARRAY2.NRLIB (NRLIB from MID)>>
+<<IARRAY2.spad (SPAD from IN)>>
+
+<<IIARRAY2.o (O from NRLIB)>>
+<<IIARRAY2.NRLIB (NRLIB from MID)>>
+<<IIARRAY2.spad (SPAD from IN)>>
+
+<<array2.spad (SPAD from IN)>>
+<<array2.spad.dvi (DOC from IN)>>
+
+<<ASP1.o (O from NRLIB)>>
+<<ASP1.NRLIB (NRLIB from MID)>>
+<<ASP1.spad (SPAD from IN)>>
+
+<<ASP10.o (O from NRLIB)>>
+<<ASP10.NRLIB (NRLIB from MID)>>
+<<ASP10.spad (SPAD from IN)>>
+
+<<ASP12.o (O from NRLIB)>>
+<<ASP12.NRLIB (NRLIB from MID)>>
+<<ASP12.spad (SPAD from IN)>>
+
+<<ASP19.o (O from NRLIB)>>
+<<ASP19.NRLIB (NRLIB from MID)>>
+<<ASP19.spad (SPAD from IN)>>
+
+<<ASP20.o (O from NRLIB)>>
+<<ASP20.NRLIB (NRLIB from MID)>>
+<<ASP20.spad (SPAD from IN)>>
+
+<<ASP24.o (O from NRLIB)>>
+<<ASP24.NRLIB (NRLIB from MID)>>
+<<ASP24.spad (SPAD from IN)>>
+
+<<ASP27.o (O from NRLIB)>>
+<<ASP27.NRLIB (NRLIB from MID)>>
+<<ASP27.spad (SPAD from IN)>>
+
+<<ASP28.o (O from NRLIB)>>
+<<ASP28.NRLIB (NRLIB from MID)>>
+<<ASP28.spad (SPAD from IN)>>
+
+<<ASP29.o (O from NRLIB)>>
+<<ASP29.NRLIB (NRLIB from MID)>>
+<<ASP29.spad (SPAD from IN)>>
+
+<<ASP30.o (O from NRLIB)>>
+<<ASP30.NRLIB (NRLIB from MID)>>
+<<ASP30.spad (SPAD from IN)>>
+
+<<ASP31.o (O from NRLIB)>>
+<<ASP31.NRLIB (NRLIB from MID)>>
+<<ASP31.spad (SPAD from IN)>>
+
+<<ASP33.o (O from NRLIB)>>
+<<ASP33.NRLIB (NRLIB from MID)>>
+<<ASP33.spad (SPAD from IN)>>
+
+<<ASP34.o (O from NRLIB)>>
+<<ASP34.NRLIB (NRLIB from MID)>>
+<<ASP34.spad (SPAD from IN)>>
+
+<<ASP35.o (O from NRLIB)>>
+<<ASP35.NRLIB (NRLIB from MID)>>
+<<ASP35.spad (SPAD from IN)>>
+
+<<ASP4.o (O from NRLIB)>>
+<<ASP4.NRLIB (NRLIB from MID)>>
+<<ASP4.spad (SPAD from IN)>>
+
+<<ASP41.o (O from NRLIB)>>
+<<ASP41.NRLIB (NRLIB from MID)>>
+<<ASP41.spad (SPAD from IN)>>
+
+<<ASP42.o (O from NRLIB)>>
+<<ASP42.NRLIB (NRLIB from MID)>>
+<<ASP42.spad (SPAD from IN)>>
+
+<<ASP49.o (O from NRLIB)>>
+<<ASP49.NRLIB (NRLIB from MID)>>
+<<ASP49.spad (SPAD from IN)>>
+
+<<ASP50.o (O from NRLIB)>>
+<<ASP50.NRLIB (NRLIB from MID)>>
+<<ASP50.spad (SPAD from IN)>>
+
+<<ASP55.o (O from NRLIB)>>
+<<ASP55.NRLIB (NRLIB from MID)>>
+<<ASP55.spad (SPAD from IN)>>
+
+<<ASP6.o (O from NRLIB)>>
+<<ASP6.NRLIB (NRLIB from MID)>>
+<<ASP6.spad (SPAD from IN)>>
+
+<<ASP7.o (O from NRLIB)>>
+<<ASP7.NRLIB (NRLIB from MID)>>
+<<ASP7.spad (SPAD from IN)>>
+
+<<ASP73.o (O from NRLIB)>>
+<<ASP73.NRLIB (NRLIB from MID)>>
+<<ASP73.spad (SPAD from IN)>>
+
+<<ASP74.o (O from NRLIB)>>
+<<ASP74.NRLIB (NRLIB from MID)>>
+<<ASP74.spad (SPAD from IN)>>
+
+<<ASP77.o (O from NRLIB)>>
+<<ASP77.NRLIB (NRLIB from MID)>>
+<<ASP77.spad (SPAD from IN)>>
+
+<<ASP78.o (O from NRLIB)>>
+<<ASP78.NRLIB (NRLIB from MID)>>
+<<ASP78.spad (SPAD from IN)>>
+
+<<ASP8.o (O from NRLIB)>>
+<<ASP8.NRLIB (NRLIB from MID)>>
+<<ASP8.spad (SPAD from IN)>>
+
+<<ASP80.o (O from NRLIB)>>
+<<ASP80.NRLIB (NRLIB from MID)>>
+<<ASP80.spad (SPAD from IN)>>
+
+<<ASP9.o (O from NRLIB)>>
+<<ASP9.NRLIB (NRLIB from MID)>>
+<<ASP9.spad (SPAD from IN)>>
+
+<<asp.spad (SPAD from IN)>>
+<<asp.spad.dvi (DOC from IN)>>
+
+<<ATTREG.o (O from NRLIB)>>
+<<ATTREG.NRLIB (NRLIB from MID)>>
+<<ATTREG.spad (SPAD from IN)>>
+
+<<attreg.spad (SPAD from IN)>>
+<<attreg.spad.dvi (DOC from IN)>>
+
+<<axtimer.as (SPAD from IN)>>
+<<axtimer.as.dvi (DOC from IN)>>
+
+<<ASTACK.o (O from NRLIB)>>
+<<ASTACK.NRLIB (NRLIB from MID)>>
+<<ASTACK.spad (SPAD from IN)>>
+
+<<DEQUEUE.o (O from NRLIB)>>
+<<DEQUEUE.NRLIB (NRLIB from MID)>>
+<<DEQUEUE.spad (SPAD from IN)>>
+
+<<HEAP.o (O from NRLIB)>>
+<<HEAP.NRLIB (NRLIB from MID)>>
+<<HEAP.spad (SPAD from IN)>>
+
+<<QUEUE.o (O from NRLIB)>>
+<<QUEUE.NRLIB (NRLIB from MID)>>
+<<QUEUE.spad (SPAD from IN)>>
+
+<<STACK.o (O from NRLIB)>>
+<<STACK.NRLIB (NRLIB from MID)>>
+<<STACK.spad (SPAD from IN)>>
+
+<<bags.spad (SPAD from IN)>>
+<<bags.spad.dvi (DOC from IN)>>
+
+<<BEZOUT.o (O from NRLIB)>>
+<<BEZOUT.NRLIB (NRLIB from MID)>>
+<<BEZOUT.spad (SPAD from IN)>>
+
+<<bezout.spad (SPAD from IN)>>
+<<bezout.spad.dvi (DOC from IN)>>
+
+<<BITS.o (O from NRLIB)>>
+<<BITS.NRLIB (NRLIB from MID)>>
+<<BITS.spad (SPAD from IN)>>
+
+<<BOOLEAN.o (O from NRLIB)>>
+<<BOOLEAN.NRLIB (NRLIB from MID)>>
+<<BOOLEAN.spad (SPAD from IN)>>
+<<BOOLEAN.o (BOOTSTRAP from MID)>>
+<<BOOLEAN.lsp (LISP from IN)>>
+
+<<IBITS.o (O from NRLIB)>>
+<<IBITS.NRLIB (NRLIB from MID)>>
+<<IBITS.spad (SPAD from IN)>>
+
+<<LOGIC-.o (O from NRLIB)>>
+<<LOGIC-.NRLIB (NRLIB from MID)>>
+<<LOGIC.o (O from NRLIB)>>
+<<LOGIC.NRLIB (NRLIB from MID)>>
+<<LOGIC.spad (SPAD from IN)>>
+
+<<REF.o (O from NRLIB)>>
+<<REF.NRLIB (NRLIB from MID)>>
+<<REF.spad (SPAD from IN)>>
+<<REF.o (BOOTSTRAP from MID)>>
+<<REF.lsp (LISP from IN)>>
+
+<<boolean.spad (SPAD from IN)>>
+<<boolean.spad.dvi (DOC from IN)>>
+
+<<BRILL.o (O from NRLIB)>>
+<<BRILL.NRLIB (NRLIB from MID)>>
+<<BRILL.spad (SPAD from IN)>>
+
+<<brill.spad (SPAD from IN)>>
+<<brill.spad.dvi (DOC from IN)>>
+
+<<NAGC02.o (O from NRLIB)>>
+<<NAGC02.NRLIB (NRLIB from MID)>>
+<<NAGC02.spad (SPAD from IN)>>
+
+<<c02.spad (SPAD from IN)>>
+<<c02.spad.dvi (DOC from IN)>>
+
+<<NAGC05.o (O from NRLIB)>>
+<<NAGC05.NRLIB (NRLIB from MID)>>
+<<NAGC05.spad (SPAD from IN)>>
+
+<<c05.spad (SPAD from IN)>>
+<<c05.spad.dvi (DOC from IN)>>
+
+<<NAGC06.o (O from NRLIB)>>
+<<NAGC06.NRLIB (NRLIB from MID)>>
+<<NAGC06.spad (SPAD from IN)>>
+
+<<c06.spad (SPAD from IN)>>
+<<c06.spad.dvi (DOC from IN)>>
+
+<<CARD.o (O from NRLIB)>>
+<<CARD.NRLIB (NRLIB from MID)>>
+<<CARD.spad (SPAD from IN)>>
+
+<<card.spad (SPAD from IN)>>
+<<card.spad.dvi (DOC from IN)>>
+
+<<CARTEN.o (O from NRLIB)>>
+<<CARTEN.NRLIB (NRLIB from MID)>>
+<<CARTEN.spad (SPAD from IN)>>
+
+<<CARTEN2.o (O from NRLIB)>>
+<<CARTEN2.NRLIB (NRLIB from MID)>>
+<<CARTEN2.spad (SPAD from IN)>>
+
+<<GRALG-.o (O from NRLIB)>>
+<<GRALG-.NRLIB (NRLIB from MID)>>
+<<GRALG.o (O from NRLIB)>>
+<<GRALG.NRLIB (NRLIB from MID)>>
+<<GRALG.spad (SPAD from IN)>>
+
+<<GRMOD-.o (O from NRLIB)>>
+<<GRMOD-.NRLIB (NRLIB from MID)>>
+<<GRMOD.o (O from NRLIB)>>
+<<GRMOD.NRLIB (NRLIB from MID)>>
+<<GRMOD.spad (SPAD from IN)>>
+
+<<carten.spad (SPAD from IN)>>
+<<carten.spad.dvi (DOC from IN)>>
+
+<<ABELGRP-.o (O from NRLIB)>>
+<<ABELGRP-.NRLIB (NRLIB from MID)>>
+<<ABELGRP.o (O from NRLIB)>>
+<<ABELGRP.NRLIB (NRLIB from MID)>>
+<<ABELGRP.spad (SPAD from IN)>>
+<<ABELGRP-.o (BOOTSTRAP from MID)>>
+<<ABELGRP-.lsp (LISP from IN)>>
+<<ABELGRP.o (BOOTSTRAP from MID)>>
+<<ABELGRP.lsp (LISP from IN)>>
+
+<<ABELMON-.o (O from NRLIB)>>
+<<ABELMON-.NRLIB (NRLIB from MID)>>
+<<ABELMON.o (O from NRLIB)>>
+<<ABELMON.NRLIB (NRLIB from MID)>>
+<<ABELMON.spad (SPAD from IN)>>
+<<ABELMON-.o (BOOTSTRAP from MID)>>
+<<ABELMON-.lsp (LISP from IN)>>
+<<ABELMON.o (BOOTSTRAP from MID)>>
+<<ABELMON.lsp (LISP from IN)>>
+
+<<ABELSG-.o (O from NRLIB)>>
+<<ABELSG-.NRLIB (NRLIB from MID)>>
+<<ABELSG.o (O from NRLIB)>>
+<<ABELSG.NRLIB (NRLIB from MID)>>
+<<ABELSG.spad (SPAD from IN)>>
+<<ABELSG-.o (BOOTSTRAP from MID)>>
+<<ABELSG-.lsp (LISP from IN)>>
+<<ABELSG.o (BOOTSTRAP from MID)>>
+<<ABELSG.lsp (LISP from IN)>>
+
+<<ALGEBRA-.o (O from NRLIB)>>
+<<ALGEBRA-.NRLIB (NRLIB from MID)>>
+<<ALGEBRA.o (O from NRLIB)>>
+<<ALGEBRA.NRLIB (NRLIB from MID)>>
+<<ALGEBRA.spad (SPAD from IN)>>
+
+<<BASTYPE-.o (O from NRLIB)>>
+<<BASTYPE-.NRLIB (NRLIB from MID)>>
+<<BASTYPE.o (O from NRLIB)>>
+<<BASTYPE.NRLIB (NRLIB from MID)>>
+<<BASTYPE.spad (SPAD from IN)>>
+
+<<BMODULE.o (O from NRLIB)>>
+<<BMODULE.NRLIB (NRLIB from MID)>>
+<<BMODULE.spad (SPAD from IN)>>
+
+<<CABMON.o (O from NRLIB)>>
+<<CABMON.NRLIB (NRLIB from MID)>>
+<<CABMON.spad (SPAD from IN)>>
+<<CABMON.o (BOOTSTRAP from MID)>>
+<<CABMON.lsp (LISP from IN)>>
+
+<<CHARNZ.o (O from NRLIB)>>
+<<CHARNZ.NRLIB (NRLIB from MID)>>
+<<CHARNZ.spad (SPAD from IN)>>
+
+<<CHARZ.o (O from NRLIB)>>
+<<CHARZ.NRLIB (NRLIB from MID)>>
+<<CHARZ.spad (SPAD from IN)>>
+
+<<COMRING.o (O from NRLIB)>>
+<<COMRING.NRLIB (NRLIB from MID)>>
+<<COMRING.spad (SPAD from IN)>>
+<<COMRING.o (BOOTSTRAP from MID)>>
+<<COMRING.lsp (LISP from IN)>>
+
+<<DIFEXT-.o (O from NRLIB)>>
+<<DIFEXT-.NRLIB (NRLIB from MID)>>
+<<DIFEXT.o (O from NRLIB)>>
+<<DIFEXT.NRLIB (NRLIB from MID)>>
+<<DIFEXT.spad (SPAD from IN)>>
+
+<<DIFRING-.o (O from NRLIB)>>
+<<DIFRING-.NRLIB (NRLIB from MID)>>
+<<DIFRING.o (O from NRLIB)>>
+<<DIFRING.NRLIB (NRLIB from MID)>>
+<<DIFRING.spad (SPAD from IN)>>
+<<DIFRING-.o (BOOTSTRAP from MID)>>
+<<DIFRING-.lsp (LISP from IN)>>
+<<DIFRING.o (BOOTSTRAP from MID)>>
+<<DIFRING.lsp (LISP from IN)>>
+
+<<DIVRING-.o (O from NRLIB)>>
+<<DIVRING-.NRLIB (NRLIB from MID)>>
+<<DIVRING.o (O from NRLIB)>>
+<<DIVRING.NRLIB (NRLIB from MID)>>
+<<DIVRING.spad (SPAD from IN)>>
+<<DIVRING-.o (BOOTSTRAP from MID)>>
+<<DIVRING-.lsp (LISP from IN)>>
+<<DIVRING.o (BOOTSTRAP from MID)>>
+<<DIVRING.lsp (LISP from IN)>>
+
+<<ENTIRER.o (O from NRLIB)>>
+<<ENTIRER.NRLIB (NRLIB from MID)>>
+<<ENTIRER.spad (SPAD from IN)>>
+<<ENTIRER.o (BOOTSTRAP from MID)>>
+<<ENTIRER.lsp (LISP from IN)>>
+
+<<EUCDOM-.o (O from NRLIB)>>
+<<EUCDOM-.NRLIB (NRLIB from MID)>>
+<<EUCDOM.o (O from NRLIB)>>
+<<EUCDOM.NRLIB (NRLIB from MID)>>
+<<EUCDOM.spad (SPAD from IN)>>
+<<EUCDOM-.o (BOOTSTRAP from MID)>>
+<<EUCDOM-.lsp (LISP from IN)>>
+<<EUCDOM.o (BOOTSTRAP from MID)>>
+<<EUCDOM.lsp (LISP from IN)>>
+
+<<FIELD-.o (O from NRLIB)>>
+<<FIELD-.NRLIB (NRLIB from MID)>>
+<<FIELD.o (O from NRLIB)>>
+<<FIELD.NRLIB (NRLIB from MID)>>
+<<FIELD.spad (SPAD from IN)>>
+
+<<FINITE.o (O from NRLIB)>>
+<<FINITE.NRLIB (NRLIB from MID)>>
+<<FINITE.spad (SPAD from IN)>>
+
+<<FLINEXP-.o (O from NRLIB)>>
+<<FLINEXP-.NRLIB (NRLIB from MID)>>
+<<FLINEXP.o (O from NRLIB)>>
+<<FLINEXP.NRLIB (NRLIB from MID)>>
+<<FLINEXP.spad (SPAD from IN)>>
+
+<<GCDDOM-.o (O from NRLIB)>>
+<<GCDDOM-.NRLIB (NRLIB from MID)>>
+<<GCDDOM.o (O from NRLIB)>>
+<<GCDDOM.NRLIB (NRLIB from MID)>>
+<<GCDDOM.spad (SPAD from IN)>>
+<<GCDDOM-.o (BOOTSTRAP from MID)>>
+<<GCDDOM-.lsp (LISP from IN)>>
+<<GCDDOM.o (BOOTSTRAP from MID)>>
+<<GCDDOM.lsp (LISP from IN)>>
+
+<<GROUP-.o (O from NRLIB)>>
+<<GROUP-.NRLIB (NRLIB from MID)>>
+<<GROUP.o (O from NRLIB)>>
+<<GROUP.NRLIB (NRLIB from MID)>>
+<<GROUP.spad (SPAD from IN)>>
+
+<<INTDOM-.o (O from NRLIB)>>
+<<INTDOM-.NRLIB (NRLIB from MID)>>
+<<INTDOM.o (O from NRLIB)>>
+<<INTDOM.NRLIB (NRLIB from MID)>>
+<<INTDOM.spad (SPAD from IN)>>
+<<INTDOM-.o (BOOTSTRAP from MID)>>
+<<INTDOM-.lsp (LISP from IN)>>
+<<INTDOM.o (BOOTSTRAP from MID)>>
+<<INTDOM.lsp (LISP from IN)>>
+
+<<LINEXP.o (O from NRLIB)>>
+<<LINEXP.NRLIB (NRLIB from MID)>>
+<<LINEXP.spad (SPAD from IN)>>
+
+<<LMODULE.o (O from NRLIB)>>
+<<LMODULE.NRLIB (NRLIB from MID)>>
+<<LMODULE.spad (SPAD from IN)>>
+
+<<MONOID-.o (O from NRLIB)>>
+<<MONOID-.NRLIB (NRLIB from MID)>>
+<<MONOID.o (O from NRLIB)>>
+<<MONOID.NRLIB (NRLIB from MID)>>
+<<MONOID.spad (SPAD from IN)>>
+<<MONOID-.o (BOOTSTRAP from MID)>>
+<<MONOID-.lsp (LISP from IN)>>
+<<MONOID.o (BOOTSTRAP from MID)>>
+<<MONOID.lsp (LISP from IN)>>
+
+<<MODULE-.o (O from NRLIB)>>
+<<MODULE-.NRLIB (NRLIB from MID)>>
+<<MODULE.o (O from NRLIB)>>
+<<MODULE.NRLIB (NRLIB from MID)>>
+<<MODULE.spad (SPAD from IN)>>
+
+<<OCAMON.o (O from NRLIB)>>
+<<OCAMON.NRLIB (NRLIB from MID)>>
+<<OCAMON.spad (SPAD from IN)>>
+
+<<OAGROUP.o (O from NRLIB)>>
+<<OAGROUP.NRLIB (NRLIB from MID)>>
+<<OAGROUP.spad (SPAD from IN)>>
+
+<<OAMON.o (O from NRLIB)>>
+<<OAMON.NRLIB (NRLIB from MID)>>
+<<OAMON.spad (SPAD from IN)>>
+
+<<OAMONS.o (O from NRLIB)>>
+<<OAMONS.NRLIB (NRLIB from MID)>>
+<<OAMONS.spad (SPAD from IN)>>
+
+<<OASGP.o (O from NRLIB)>>
+<<OASGP.NRLIB (NRLIB from MID)>>
+<<OASGP.spad (SPAD from IN)>>
+
+<<ORDFIN.o (O from NRLIB)>>
+<<ORDFIN.NRLIB (NRLIB from MID)>>
+<<ORDFIN.spad (SPAD from IN)>>
+
+<<OINTDOM.o (O from NRLIB)>>
+<<OINTDOM.NRLIB (NRLIB from MID)>>
+<<OINTDOM.spad (SPAD from IN)>>
+<<OINTDOM.o (BOOTSTRAP from MID)>>
+<<OINTDOM.lsp (LISP from IN)>>
+
+<<ORDMON.o (O from NRLIB)>>
+<<ORDMON.NRLIB (NRLIB from MID)>>
+<<ORDMON.spad (SPAD from IN)>>
+
+<<ORDRING-.o (O from NRLIB)>>
+<<ORDRING-.NRLIB (NRLIB from MID)>>
+<<ORDRING.o (O from NRLIB)>>
+<<ORDRING.NRLIB (NRLIB from MID)>>
+<<ORDRING.spad (SPAD from IN)>>
+<<ORDRING-.o (BOOTSTRAP from MID)>>
+<<ORDRING-.lsp (LISP from IN)>>
+<<ORDRING.o (BOOTSTRAP from MID)>>
+<<ORDRING.lsp (LISP from IN)>>
+
+<<ORDSET-.o (O from NRLIB)>>
+<<ORDSET-.NRLIB (NRLIB from MID)>>
+<<ORDSET.o (O from NRLIB)>>
+<<ORDSET.NRLIB (NRLIB from MID)>>
+<<ORDSET.spad (SPAD from IN)>>
+
+<<PDRING-.o (O from NRLIB)>>
+<<PDRING-.NRLIB (NRLIB from MID)>>
+<<PDRING.o (O from NRLIB)>>
+<<PDRING.NRLIB (NRLIB from MID)>>
+<<PDRING.spad (SPAD from IN)>>
+
+<<PFECAT-.o (O from NRLIB)>>
+<<PFECAT-.NRLIB (NRLIB from MID)>>
+<<PFECAT.o (O from NRLIB)>>
+<<PFECAT.NRLIB (NRLIB from MID)>>
+<<PFECAT.spad (SPAD from IN)>>
+
+<<PID.o (O from NRLIB)>>
+<<PID.NRLIB (NRLIB from MID)>>
+<<PID.spad (SPAD from IN)>>
+
+<<RMODULE.o (O from NRLIB)>>
+<<RMODULE.NRLIB (NRLIB from MID)>>
+<<RMODULE.spad (SPAD from IN)>>
+
+<<RING-.o (O from NRLIB)>>
+<<RING-.NRLIB (NRLIB from MID)>>
+<<RING.o (O from NRLIB)>>
+<<RING.NRLIB (NRLIB from MID)>>
+<<RING.spad (SPAD from IN)>>
+<<RING-.o (BOOTSTRAP from MID)>>
+<<RING-.lsp (LISP from IN)>>
+<<RING.o (BOOTSTRAP from MID)>>
+<<RING.lsp (LISP from IN)>>
+
+<<RNG.o (O from NRLIB)>>
+<<RNG.NRLIB (NRLIB from MID)>>
+<<RNG.spad (SPAD from IN)>>
+<<RNG.o (BOOTSTRAP from MID)>>
+<<RNG.lsp (LISP from IN)>>
+
+<<SETCAT-.o (O from NRLIB)>>
+<<SETCAT-.NRLIB (NRLIB from MID)>>
+<<SETCAT-.o (BOOTSTRAP from MID)>>
+<<SETCAT-.lsp (LISP from IN)>>
+
+<<SETCAT.o (O from NRLIB)>>
+<<SETCAT.NRLIB (NRLIB from MID)>>
+<<SETCAT.spad (SPAD from IN)>>
+<<SETCAT.o (BOOTSTRAP from MID)>>
+<<SETCAT.lsp (LISP from IN)>>
+
+<<SGROUP-.o (O from NRLIB)>>
+<<SGROUP-.NRLIB (NRLIB from MID)>>
+<<SGROUP.o (O from NRLIB)>>
+<<SGROUP.NRLIB (NRLIB from MID)>>
+<<SGROUP.spad (SPAD from IN)>>
+
+<<STEP.o (O from NRLIB)>>
+<<STEP.NRLIB (NRLIB from MID)>>
+<<STEP.spad (SPAD from IN)>>
+
+<<UFD-.o (O from NRLIB)>>
+<<UFD-.NRLIB (NRLIB from MID)>>
+<<UFD.o (O from NRLIB)>>
+<<UFD.NRLIB (NRLIB from MID)>>
+<<UFD.spad (SPAD from IN)>>
+<<UFD-.o (BOOTSTRAP from MID)>>
+<<UFD-.lsp (LISP from IN)>>
+<<UFD.o (BOOTSTRAP from MID)>>
+<<UFD.lsp (LISP from IN)>>
+
+<<VSPACE-.o (O from NRLIB)>>
+<<VSPACE-.NRLIB (NRLIB from MID)>>
+<<VSPACE.o (O from NRLIB)>>
+<<VSPACE.NRLIB (NRLIB from MID)>>
+<<VSPACE.spad (SPAD from IN)>>
+
+<<catdef.spad (SPAD from IN)>>
+<<catdef.spad.dvi (DOC from IN)>>
+
+<<CDEN.o (O from NRLIB)>>
+<<CDEN.NRLIB (NRLIB from MID)>>
+<<CDEN.spad (SPAD from IN)>>
+
+<<ICDEN.o (O from NRLIB)>>
+<<ICDEN.NRLIB (NRLIB from MID)>>
+<<ICDEN.spad (SPAD from IN)>>
+
+<<MCDEN.o (O from NRLIB)>>
+<<MCDEN.NRLIB (NRLIB from MID)>>
+<<MCDEN.spad (SPAD from IN)>>
+
+<<UPCDEN.o (O from NRLIB)>>
+<<UPCDEN.NRLIB (NRLIB from MID)>>
+<<UPCDEN.spad (SPAD from IN)>>
+
+<<cden.spad (SPAD from IN)>>
+<<cden.spad.dvi (DOC from IN)>>
+
+<<CLIF.o (O from NRLIB)>>
+<<CLIF.NRLIB (NRLIB from MID)>>
+<<CLIF.spad (SPAD from IN)>>
+
+<<QFORM.o (O from NRLIB)>>
+<<QFORM.NRLIB (NRLIB from MID)>>
+<<QFORM.spad (SPAD from IN)>>
+
+<<clifford.spad (SPAD from IN)>>
+<<clifford.spad.dvi (DOC from IN)>>
+
+<<CLIP.o (O from NRLIB)>>
+<<CLIP.NRLIB (NRLIB from MID)>>
+<<CLIP.spad (SPAD from IN)>>
+
+<<clip.spad (SPAD from IN)>>
+<<clip.spad.dvi (DOC from IN)>>
+
+<<CMPLXRT.o (O from NRLIB)>>
+<<CMPLXRT.NRLIB (NRLIB from MID)>>
+<<CMPLXRT.spad (SPAD from IN)>>
+
+<<cmplxrt.spad (SPAD from IN)>>
+<<cmplxrt.spad.dvi (DOC from IN)>>
+
+<<KOERCE.o (O from NRLIB)>>
+<<KOERCE.NRLIB (NRLIB from MID)>>
+<<KOERCE.spad (SPAD from IN)>>
+
+<<KONVERT.o (O from NRLIB)>>
+<<KONVERT.NRLIB (NRLIB from MID)>>
+<<KONVERT.spad (SPAD from IN)>>
+
+<<RETRACT-.o (O from NRLIB)>>
+<<RETRACT-.NRLIB (NRLIB from MID)>>
+<<RETRACT.o (O from NRLIB)>>
+<<RETRACT.NRLIB (NRLIB from MID)>>
+<<RETRACT.spad (SPAD from IN)>>
+
+<<TYPE.o (O from NRLIB)>>
+<<TYPE.NRLIB (NRLIB from MID)>>
+<<TYPE.spad (SPAD from IN)>>
+
+<<coerce.spad (SPAD from IN)>>
+<<coerce.spad.dvi (DOC from IN)>>
+
+<<COLOR.o (O from NRLIB)>>
+<<COLOR.NRLIB (NRLIB from MID)>>
+<<COLOR.spad (SPAD from IN)>>
+
+<<PALETTE.o (O from NRLIB)>>
+<<PALETTE.NRLIB (NRLIB from MID)>>
+<<PALETTE.spad (SPAD from IN)>>
+
+<<color.spad (SPAD from IN)>>
+<<color.spad.dvi (DOC from IN)>>
+
+<<COMBF.o (O from NRLIB)>>
+<<COMBF.NRLIB (NRLIB from MID)>>
+<<COMBF.spad (SPAD from IN)>>
+
+<<COMBOPC.o (O from NRLIB)>>
+<<COMBOPC.NRLIB (NRLIB from MID)>>
+<<COMBOPC.spad (SPAD from IN)>>
+
+<<FSPECF.o (O from NRLIB)>>
+<<FSPECF.NRLIB (NRLIB from MID)>>
+<<FSPECF.spad (SPAD from IN)>>
+
+<<SUMFS.o (O from NRLIB)>>
+<<SUMFS.NRLIB (NRLIB from MID)>>
+<<SUMFS.spad (SPAD from IN)>>
+
+<<combfunc.spad (SPAD from IN)>>
+<<combfunc.spad.dvi (DOC from IN)>>
+
+<<COMBINAT.o (O from NRLIB)>>
+<<COMBINAT.NRLIB (NRLIB from MID)>>
+<<COMBINAT.spad (SPAD from IN)>>
+
+<<combinat.spad (SPAD from IN)>>
+<<combinat.spad.dvi (DOC from IN)>>
+
+<<INFINITY.o (O from NRLIB)>>
+<<INFINITY.NRLIB (NRLIB from MID)>>
+<<INFINITY.spad (SPAD from IN)>>
+
+<<ONECOMP.o (O from NRLIB)>>
+<<ONECOMP.NRLIB (NRLIB from MID)>>
+<<ONECOMP.spad (SPAD from IN)>>
+
+<<ONECOMP2.o (O from NRLIB)>>
+<<ONECOMP2.NRLIB (NRLIB from MID)>>
+<<ONECOMP2.spad (SPAD from IN)>>
+
+<<ORDCOMP.o (O from NRLIB)>>
+<<ORDCOMP.NRLIB (NRLIB from MID)>>
+<<ORDCOMP.spad (SPAD from IN)>>
+
+<<ORDCOMP2.o (O from NRLIB)>>
+<<ORDCOMP2.NRLIB (NRLIB from MID)>>
+<<ORDCOMP2.spad (SPAD from IN)>>
+
+<<complet.spad (SPAD from IN)>>
+<<complet.spad.dvi (DOC from IN)>>
+
+<<AN.o (O from NRLIB)>>
+<<AN.NRLIB (NRLIB from MID)>>
+<<AN.spad (SPAD from IN)>>
+
+<<IAN.o (O from NRLIB)>>
+<<IAN.NRLIB (NRLIB from MID)>>
+<<IAN.spad (SPAD from IN)>>
+
+<<constant.spad (SPAD from IN)>>
+<<constant.spad.dvi (DOC from IN)>>
+
+<<CONTFRAC.o (O from NRLIB)>>
+<<CONTFRAC.NRLIB (NRLIB from MID)>>
+<<CONTFRAC.spad (SPAD from IN)>>
+
+<<NCNTFRAC.o (O from NRLIB)>>
+<<NCNTFRAC.NRLIB (NRLIB from MID)>>
+<<NCNTFRAC.spad (SPAD from IN)>>
+
+<<contfrac.spad (SPAD from IN)>>
+<<contfrac.spad.dvi (DOC from IN)>>
+
+<<ESCONT.o (O from NRLIB)>>
+<<ESCONT.NRLIB (NRLIB from MID)>>
+<<ESCONT.spad (SPAD from IN)>>
+
+<<ESCONT1.o (O from NRLIB)>>
+<<ESCONT1.NRLIB (NRLIB from MID)>>
+<<ESCONT1.spad (SPAD from IN)>>
+
+<<cont.spad (SPAD from IN)>>
+<<cont.spad.dvi (DOC from IN)>>
+
+<<COORDSYS.o (O from NRLIB)>>
+<<COORDSYS.NRLIB (NRLIB from MID)>>
+<<COORDSYS.spad (SPAD from IN)>>
+
+<<coordsys.spad (SPAD from IN)>>
+<<coordsys.spad.dvi (DOC from IN)>>
+
+<<CRAPACK.o (O from NRLIB)>>
+<<CRAPACK.NRLIB (NRLIB from MID)>>
+<<CRAPACK.spad (SPAD from IN)>>
+
+<<cra.spad (SPAD from IN)>>
+<<cra.spad.dvi (DOC from IN)>>
+
+<<CRFP.o (O from NRLIB)>>
+<<CRFP.NRLIB (NRLIB from MID)>>
+<<CRFP.spad (SPAD from IN)>>
+
+<<crfp.spad (SPAD from IN)>>
+<<crfp.spad.dvi (DOC from IN)>>
+
+<<ALGFF.o (O from NRLIB)>>
+<<ALGFF.NRLIB (NRLIB from MID)>>
+<<ALGFF.spad (SPAD from IN)>>
+
+<<CHVAR.o (O from NRLIB)>>
+<<CHVAR.NRLIB (NRLIB from MID)>>
+<<CHVAR.spad (SPAD from IN)>>
+
+<<FAXF-.o (O from NRLIB)>>
+<<FAXF-.NRLIB (NRLIB from MID)>>
+<<FAXF.o (O from NRLIB)>>
+<<FAXF.NRLIB (NRLIB from MID)>>
+<<FAXF.spad (SPAD from IN)>>
+
+<<FFCAT-.o (O from NRLIB)>>
+<<FFCAT-.NRLIB (NRLIB from MID)>>
+<<FFCAT.o (O from NRLIB)>>
+<<FFCAT.NRLIB (NRLIB from MID)>>
+<<FFCAT.spad (SPAD from IN)>>
+
+<<FFCAT2.o (O from NRLIB)>>
+<<FFCAT2.NRLIB (NRLIB from MID)>>
+<<FFCAT2.spad (SPAD from IN)>>
+
+<<MMAP.o (O from NRLIB)>>
+<<MMAP.NRLIB (NRLIB from MID)>>
+<<MMAP.spad (SPAD from IN)>>
+
+<<RADFF.o (O from NRLIB)>>
+<<RADFF.NRLIB (NRLIB from MID)>>
+<<RADFF.spad (SPAD from IN)>>
+
+<<curve.spad (SPAD from IN)>>
+<<curve.spad.dvi (DOC from IN)>>
+
+<<CYCLES.o (O from NRLIB)>>
+<<CYCLES.NRLIB (NRLIB from MID)>>
+<<CYCLES.spad (SPAD from IN)>>
+
+<<EVALCYC.o (O from NRLIB)>>
+<<EVALCYC.NRLIB (NRLIB from MID)>>
+<<EVALCYC.spad (SPAD from IN)>>
+
+<<cycles.spad (SPAD from IN)>>
+<<cycles.spad.dvi (DOC from IN)>>
+
+<<CYCLOTOM.o (O from NRLIB)>>
+<<CYCLOTOM.NRLIB (NRLIB from MID)>>
+<<CYCLOTOM.spad (SPAD from IN)>>
+
+<<cyclotom.spad (SPAD from IN)>>
+<<cyclotom.spad.dvi (DOC from IN)>>
+
+<<INTFTBL.o (O from NRLIB)>>
+<<INTFTBL.NRLIB (NRLIB from MID)>>
+<<INTFTBL.spad (SPAD from IN)>>
+
+<<d01agents.spad (SPAD from IN)>>
+<<d01agents.spad.dvi (DOC from IN)>>
+
+<<INTPACK.o (O from NRLIB)>>
+<<INTPACK.NRLIB (NRLIB from MID)>>
+<<INTPACK.spad (SPAD from IN)>>
+
+<<d01Package.spad (SPAD from IN)>>
+<<d01Package.spad.dvi (DOC from IN)>>
+
+<<D01AJFA.o (O from NRLIB)>>
+<<D01AJFA.NRLIB (NRLIB from MID)>>
+<<D01AJFA.spad (SPAD from IN)>>
+
+<<D01AKFA.o (O from NRLIB)>>
+<<D01AKFA.NRLIB (NRLIB from MID)>>
+<<D01AKFA.spad (SPAD from IN)>>
+
+<<D01ALFA.o (O from NRLIB)>>
+<<D01ALFA.NRLIB (NRLIB from MID)>>
+<<D01ALFA.spad (SPAD from IN)>>
+
+<<D01AMFA.o (O from NRLIB)>>
+<<D01AMFA.NRLIB (NRLIB from MID)>>
+<<D01AMFA.spad (SPAD from IN)>>
+
+<<D01ANFA.o (O from NRLIB)>>
+<<D01ANFA.NRLIB (NRLIB from MID)>>
+<<D01ANFA.spad (SPAD from IN)>>
+
+<<D01APFA.o (O from NRLIB)>>
+<<D01APFA.NRLIB (NRLIB from MID)>>
+<<D01APFA.spad (SPAD from IN)>>
+
+<<D01AQFA.o (O from NRLIB)>>
+<<D01AQFA.NRLIB (NRLIB from MID)>>
+<<D01AQFA.spad (SPAD from IN)>>
+
+<<D01ASFA.o (O from NRLIB)>>
+<<D01ASFA.NRLIB (NRLIB from MID)>>
+<<D01ASFA.spad (SPAD from IN)>>
+
+<<D01FCFA.o (O from NRLIB)>>
+<<D01FCFA.NRLIB (NRLIB from MID)>>
+<<D01FCFA.spad (SPAD from IN)>>
+
+<<D01GBFA.o (O from NRLIB)>>
+<<D01GBFA.NRLIB (NRLIB from MID)>>
+<<D01GBFA.spad (SPAD from IN)>>
+
+<<d01routine.spad (SPAD from IN)>>
+<<d01routine.spad.dvi (DOC from IN)>>
+
+<<NAGD01.o (O from NRLIB)>>
+<<NAGD01.NRLIB (NRLIB from MID)>>
+<<NAGD01.spad (SPAD from IN)>>
+
+<<d01.spad (SPAD from IN)>>
+<<d01.spad.dvi (DOC from IN)>>
+
+<<D01TRNS.o (O from NRLIB)>>
+<<D01TRNS.NRLIB (NRLIB from MID)>>
+<<D01TRNS.spad (SPAD from IN)>>
+
+<<d01transform.spad (SPAD from IN)>>
+<<d01transform.spad.dvi (DOC from IN)>>
+
+<<d01weights.spad (SPAD from IN)>>
+<<d01weights.spad.dvi (DOC from IN)>>
+
+<<D02AGNT.o (O from NRLIB)>>
+<<D02AGNT.NRLIB (NRLIB from MID)>>
+<<D02AGNT.spad (SPAD from IN)>>
+
+<<ODEIFTBL.o (O from NRLIB)>>
+<<ODEIFTBL.NRLIB (NRLIB from MID)>>
+<<ODEIFTBL.spad (SPAD from IN)>>
+
+<<d02agents.spad (SPAD from IN)>>
+<<d02agents.spad.dvi (DOC from IN)>>
+
+<<ODEPACK.o (O from NRLIB)>>
+<<ODEPACK.NRLIB (NRLIB from MID)>>
+<<ODEPACK.spad (SPAD from IN)>>
+
+<<d02Package.spad (SPAD from IN)>>
+<<d02Package.spad.dvi (DOC from IN)>>
+
+<<D02BBFA.o (O from NRLIB)>>
+<<D02BBFA.NRLIB (NRLIB from MID)>>
+<<D02BBFA.spad (SPAD from IN)>>
+
+<<D02BHFA.o (O from NRLIB)>>
+<<D02BHFA.NRLIB (NRLIB from MID)>>
+<<D02BHFA.spad (SPAD from IN)>>
+
+<<D02CJFA.o (O from NRLIB)>>
+<<D02CJFA.NRLIB (NRLIB from MID)>>
+<<D02CJFA.spad (SPAD from IN)>>
+
+<<D02EJFA.o (O from NRLIB)>>
+<<D02EJFA.NRLIB (NRLIB from MID)>>
+<<D02EJFA.spad (SPAD from IN)>>
+
+<<d02routine.spad (SPAD from IN)>>
+<<d02routine.spad.dvi (DOC from IN)>>
+
+<<NAGD02.o (O from NRLIB)>>
+<<NAGD02.NRLIB (NRLIB from MID)>>
+<<NAGD02.spad (SPAD from IN)>>
+
+<<d02.spad (SPAD from IN)>>
+<<d02.spad.dvi (DOC from IN)>>
+
+<<D03AGNT.o (O from NRLIB)>>
+<<D03AGNT.NRLIB (NRLIB from MID)>>
+<<D03AGNT.spad (SPAD from IN)>>
+
+<<d03agents.spad (SPAD from IN)>>
+<<d03agents.spad.dvi (DOC from IN)>>
+
+<<PDEPACK.o (O from NRLIB)>>
+<<PDEPACK.NRLIB (NRLIB from MID)>>
+<<PDEPACK.spad (SPAD from IN)>>
+
+<<d03Package.spad (SPAD from IN)>>
+<<d03Package.spad.dvi (DOC from IN)>>
+
+<<D03EEFA.o (O from NRLIB)>>
+<<D03EEFA.NRLIB (NRLIB from MID)>>
+<<D03EEFA.spad (SPAD from IN)>>
+
+<<D03FAFA.o (O from NRLIB)>>
+<<D03FAFA.NRLIB (NRLIB from MID)>>
+<<D03FAFA.spad (SPAD from IN)>>
+
+<<d03routine.spad (SPAD from IN)>>
+<<d03routine.spad.dvi (DOC from IN)>>
+
+<<NAGD03.o (O from NRLIB)>>
+<<NAGD03.NRLIB (NRLIB from MID)>>
+<<NAGD03.spad (SPAD from IN)>>
+
+<<d03.spad (SPAD from IN)>>
+<<d03.spad.dvi (DOC from IN)>>
+
+<<DDFACT.o (O from NRLIB)>>
+<<DDFACT.NRLIB (NRLIB from MID)>>
+<<DDFACT.spad (SPAD from IN)>>
+
+<<ddfact.spad (SPAD from IN)>>
+<<ddfact.spad.dvi (DOC from IN)>>
+
+<<FLASORT.o (O from NRLIB)>>
+<<FLASORT.NRLIB (NRLIB from MID)>>
+<<FLASORT.spad (SPAD from IN)>>
+
+<<REPDB.o (O from NRLIB)>>
+<<REPDB.NRLIB (NRLIB from MID)>>
+<<REPDB.spad (SPAD from IN)>>
+
+<<REPSQ.o (O from NRLIB)>>
+<<REPSQ.NRLIB (NRLIB from MID)>>
+<<REPSQ.spad (SPAD from IN)>>
+
+<<defaults.spad (SPAD from IN)>>
+<<defaults.spad.dvi (DOC from IN)>>
+
+<<DEFINTEF.o (O from NRLIB)>>
+<<DEFINTEF.NRLIB (NRLIB from MID)>>
+<<DEFINTEF.spad (SPAD from IN)>>
+
+<<defintef.spad (SPAD from IN)>>
+<<defintef.spad.dvi (DOC from IN)>>
+
+<<DEFINTRF.o (O from NRLIB)>>
+<<DEFINTRF.NRLIB (NRLIB from MID)>>
+<<DEFINTRF.spad (SPAD from IN)>>
+
+<<DFINTTLS.o (O from NRLIB)>>
+<<DFINTTLS.NRLIB (NRLIB from MID)>>
+<<DFINTTLS.spad (SPAD from IN)>>
+
+<<defintrf.spad (SPAD from IN)>>
+<<defintrf.spad.dvi (DOC from IN)>>
+
+<<DEGRED.o (O from NRLIB)>>
+<<DEGRED.NRLIB (NRLIB from MID)>>
+<<DEGRED.spad (SPAD from IN)>>
+
+<<degred.spad (SPAD from IN)>>
+<<degred.spad.dvi (DOC from IN)>>
+
+<<ANTISYM.o (O from NRLIB)>>
+<<ANTISYM.NRLIB (NRLIB from MID)>>
+<<ANTISYM.spad (SPAD from IN)>>
+
+<<DERHAM.o (O from NRLIB)>>
+<<DERHAM.NRLIB (NRLIB from MID)>>
+<<DERHAM.spad (SPAD from IN)>>
+
+<<EAB.o (O from NRLIB)>>
+<<EAB.NRLIB (NRLIB from MID)>>
+<<EAB.spad (SPAD from IN)>>
+
+<<LALG-.o (O from NRLIB)>>
+<<LALG-.NRLIB (NRLIB from MID)>>
+<<LALG.o (O from NRLIB)>>
+<<LALG.NRLIB (NRLIB from MID)>>
+<<LALG.spad (SPAD from IN)>>
+
+<<derham.spad (SPAD from IN)>>
+<<derham.spad.dvi (DOC from IN)>>
+
+<<DHMATRIX.o (O from NRLIB)>>
+<<DHMATRIX.NRLIB (NRLIB from MID)>>
+<<DHMATRIX.spad (SPAD from IN)>>
+
+<<dhmatrix.spad (SPAD from IN)>>
+<<dhmatrix.spad.dvi (DOC from IN)>>
+
+<<FDIV.o (O from NRLIB)>>
+<<FDIV.NRLIB (NRLIB from MID)>>
+<<FDIV.spad (SPAD from IN)>>
+
+<<FDIV2.o (O from NRLIB)>>
+<<FDIV2.NRLIB (NRLIB from MID)>>
+<<FDIV2.spad (SPAD from IN)>>
+
+<<FDIVCAT-.o (O from NRLIB)>>
+<<FDIVCAT-.NRLIB (NRLIB from MID)>>
+<<FDIVCAT.o (O from NRLIB)>>
+<<FDIVCAT.NRLIB (NRLIB from MID)>>
+<<FDIVCAT.spad (SPAD from IN)>>
+
+<<FRIDEAL.o (O from NRLIB)>>
+<<FRIDEAL.NRLIB (NRLIB from MID)>>
+<<FRIDEAL.spad (SPAD from IN)>>
+
+<<FRIDEAL2.o (O from NRLIB)>>
+<<FRIDEAL2.NRLIB (NRLIB from MID)>>
+<<FRIDEAL2.spad (SPAD from IN)>>
+
+<<FRMOD.o (O from NRLIB)>>
+<<FRMOD.NRLIB (NRLIB from MID)>>
+<<FRMOD.spad (SPAD from IN)>>
+
+<<HELLFDIV.o (O from NRLIB)>>
+<<HELLFDIV.NRLIB (NRLIB from MID)>>
+<<HELLFDIV.spad (SPAD from IN)>>
+
+<<MHROWRED.o (O from NRLIB)>>
+<<MHROWRED.NRLIB (NRLIB from MID)>>
+<<MHROWRED.spad (SPAD from IN)>>
+
+<<divisor.spad (SPAD from IN)>>
+<<divisor.spad.dvi (DOC from IN)>>
+
+<<DSMP.o (O from NRLIB)>>
+<<DSMP.NRLIB (NRLIB from MID)>>
+<<DSMP.spad (SPAD from IN)>>
+
+<<DPOLCAT-.o (O from NRLIB)>>
+<<DPOLCAT-.NRLIB (NRLIB from MID)>>
+<<DPOLCAT.o (O from NRLIB)>>
+<<DPOLCAT.NRLIB (NRLIB from MID)>>
+<<DPOLCAT.spad (SPAD from IN)>>
+
+<<DVARCAT-.o (O from NRLIB)>>
+<<DVARCAT-.NRLIB (NRLIB from MID)>>
+<<DVARCAT.o (O from NRLIB)>>
+<<DVARCAT.NRLIB (NRLIB from MID)>>
+<<DVARCAT.spad (SPAD from IN)>>
+
+<<ODPOL.o (O from NRLIB)>>
+<<ODPOL.NRLIB (NRLIB from MID)>>
+<<ODPOL.spad (SPAD from IN)>>
+
+<<ODVAR.o (O from NRLIB)>>
+<<ODVAR.NRLIB (NRLIB from MID)>>
+<<ODVAR.spad (SPAD from IN)>>
+
+<<SDPOL.o (O from NRLIB)>>
+<<SDPOL.NRLIB (NRLIB from MID)>>
+<<SDPOL.spad (SPAD from IN)>>
+
+<<SDVAR.o (O from NRLIB)>>
+<<SDVAR.NRLIB (NRLIB from MID)>>
+<<SDVAR.spad (SPAD from IN)>>
+
+<<dpolcat.spad (SPAD from IN)>>
+<<dpolcat.spad.dvi (DOC from IN)>>
+
+<<DROPT.o (O from NRLIB)>>
+<<DROPT.NRLIB (NRLIB from MID)>>
+<<DROPT.spad (SPAD from IN)>>
+
+<<DROPT0.o (O from NRLIB)>>
+<<DROPT0.NRLIB (NRLIB from MID)>>
+<<DROPT0.spad (SPAD from IN)>>
+
+<<DROPT1.o (O from NRLIB)>>
+<<DROPT1.NRLIB (NRLIB from MID)>>
+<<DROPT1.spad (SPAD from IN)>>
+
+<<drawopt.spad (SPAD from IN)>>
+<<drawopt.spad.dvi (DOC from IN)>>
+
+<<DRAWCX.o (O from NRLIB)>>
+<<DRAWCX.NRLIB (NRLIB from MID)>>
+<<DRAWCX.spad (SPAD from IN)>>
+
+<<drawpak.spad (SPAD from IN)>>
+<<drawpak.spad.dvi (DOC from IN)>>
+
+<<DRAW.o (O from NRLIB)>>
+<<DRAW.NRLIB (NRLIB from MID)>>
+<<DRAW.spad (SPAD from IN)>>
+
+<<DRAWCFUN.o (O from NRLIB)>>
+<<DRAWCFUN.NRLIB (NRLIB from MID)>>
+<<DRAWCFUN.spad (SPAD from IN)>>
+
+<<DRAWCURV.o (O from NRLIB)>>
+<<DRAWCURV.NRLIB (NRLIB from MID)>>
+<<DRAWCURV.spad (SPAD from IN)>>
+
+<<DRAWPT.o (O from NRLIB)>>
+<<DRAWPT.NRLIB (NRLIB from MID)>>
+<<DRAWPT.spad (SPAD from IN)>>
+
+<<draw.spad (SPAD from IN)>>
+<<draw.spad.dvi (DOC from IN)>>
+
+<<NAGE01.o (O from NRLIB)>>
+<<NAGE01.NRLIB (NRLIB from MID)>>
+<<NAGE01.spad (SPAD from IN)>>
+
+<<e01.spad (SPAD from IN)>>
+<<e01.spad.dvi (DOC from IN)>>
+
+<<NAGE02.o (O from NRLIB)>>
+<<NAGE02.NRLIB (NRLIB from MID)>>
+<<NAGE02.spad (SPAD from IN)>>
+
+<<e02.spad (SPAD from IN)>>
+<<e02.spad.dvi (DOC from IN)>>
+
+<<E04AGNT.o (O from NRLIB)>>
+<<E04AGNT.NRLIB (NRLIB from MID)>>
+<<E04AGNT.spad (SPAD from IN)>>
+
+<<e04agents.spad (SPAD from IN)>>
+<<e04agents.spad.dvi (DOC from IN)>>
+
+<<OPTPACK.o (O from NRLIB)>>
+<<OPTPACK.NRLIB (NRLIB from MID)>>
+<<OPTPACK.spad (SPAD from IN)>>
+
+<<e04Package.spad (SPAD from IN)>>
+<<e04Package.spad.dvi (DOC from IN)>>
+
+<<E04DGFA.o (O from NRLIB)>>
+<<E04DGFA.NRLIB (NRLIB from MID)>>
+<<E04DGFA.spad (SPAD from IN)>>
+
+<<E04FDFA.o (O from NRLIB)>>
+<<E04FDFA.NRLIB (NRLIB from MID)>>
+<<E04FDFA.spad (SPAD from IN)>>
+
+<<E04GCFA.o (O from NRLIB)>>
+<<E04GCFA.NRLIB (NRLIB from MID)>>
+<<E04GCFA.spad (SPAD from IN)>>
+
+<<E04JAFA.o (O from NRLIB)>>
+<<E04JAFA.NRLIB (NRLIB from MID)>>
+<<E04JAFA.spad (SPAD from IN)>>
+
+<<E04MBFA.o (O from NRLIB)>>
+<<E04MBFA.NRLIB (NRLIB from MID)>>
+<<E04MBFA.spad (SPAD from IN)>>
+
+<<E04NAFA.o (O from NRLIB)>>
+<<E04NAFA.NRLIB (NRLIB from MID)>>
+<<E04NAFA.spad (SPAD from IN)>>
+
+<<E04UCFA.o (O from NRLIB)>>
+<<E04UCFA.NRLIB (NRLIB from MID)>>
+<<E04UCFA.spad (SPAD from IN)>>
+
+<<e04routine.spad (SPAD from IN)>>
+<<e04routine.spad.dvi (DOC from IN)>>
+
+<<NAGE04.o (O from NRLIB)>>
+<<NAGE04.NRLIB (NRLIB from MID)>>
+<<NAGE04.spad (SPAD from IN)>>
+
+<<e04.spad (SPAD from IN)>>
+<<e04.spad.dvi (DOC from IN)>>
+
+<<CTRIGMNP.o (O from NRLIB)>>
+<<CTRIGMNP.NRLIB (NRLIB from MID)>>
+<<CTRIGMNP.spad (SPAD from IN)>>
+
+<<EFSTRUC.o (O from NRLIB)>>
+<<EFSTRUC.NRLIB (NRLIB from MID)>>
+<<EFSTRUC.spad (SPAD from IN)>>
+
+<<ITRIGMNP.o (O from NRLIB)>>
+<<ITRIGMNP.NRLIB (NRLIB from MID)>>
+<<ITRIGMNP.spad (SPAD from IN)>>
+
+<<SYMFUNC.o (O from NRLIB)>>
+<<SYMFUNC.NRLIB (NRLIB from MID)>>
+<<SYMFUNC.spad (SPAD from IN)>>
+
+<<TRIGMNIP.o (O from NRLIB)>>
+<<TRIGMNIP.NRLIB (NRLIB from MID)>>
+<<TRIGMNIP.spad (SPAD from IN)>>
+
+<<TANEXP.o (O from NRLIB)>>
+<<TANEXP.NRLIB (NRLIB from MID)>>
+<<TANEXP.spad (SPAD from IN)>>
+
+<<efstruc.spad (SPAD from IN)>>
+<<efstruc.spad.dvi (DOC from IN)>>
+
+<<EFULS.o (O from NRLIB)>>
+<<EFULS.NRLIB (NRLIB from MID)>>
+<<EFULS.spad (SPAD from IN)>>
+
+<<efuls.spad (SPAD from IN)>>
+<<efuls.spad.dvi (DOC from IN)>>
+
+<<EFUPXS.o (O from NRLIB)>>
+<<EFUPXS.NRLIB (NRLIB from MID)>>
+<<EFUPXS.spad (SPAD from IN)>>
+
+<<efupxs.spad (SPAD from IN)>>
+<<efupxs.spad.dvi (DOC from IN)>>
+
+<<CHARPOL.o (O from NRLIB)>>
+<<CHARPOL.NRLIB (NRLIB from MID)>>
+<<CHARPOL.spad (SPAD from IN)>>
+
+<<EP.o (O from NRLIB)>>
+<<EP.NRLIB (NRLIB from MID)>>
+<<EP.spad (SPAD from IN)>>
+
+<<eigen.spad (SPAD from IN)>>
+<<eigen.spad.dvi (DOC from IN)>>
+
+<<EF.o (O from NRLIB)>>
+<<EF.NRLIB (NRLIB from MID)>>
+<<EF.spad (SPAD from IN)>>
+
+<<elemntry.spad (SPAD from IN)>>
+<<elemntry.spad.dvi (DOC from IN)>>
+
+<<ELFUTS.o (O from NRLIB)>>
+<<ELFUTS.NRLIB (NRLIB from MID)>>
+<<ELFUTS.spad (SPAD from IN)>>
+
+<<elfuts.spad (SPAD from IN)>>
+<<elfuts.spad.dvi (DOC from IN)>>
+
+<<EVALAB-.o (O from NRLIB)>>
+<<EVALAB-.NRLIB (NRLIB from MID)>>
+<<EVALAB.o (O from NRLIB)>>
+<<EVALAB.NRLIB (NRLIB from MID)>>
+<<EVALAB.spad (SPAD from IN)>>
+
+<<IEVALAB-.o (O from NRLIB)>>
+<<IEVALAB-.NRLIB (NRLIB from MID)>>
+<<IEVALAB.o (O from NRLIB)>>
+<<IEVALAB.NRLIB (NRLIB from MID)>>
+<<IEVALAB.spad (SPAD from IN)>>
+
+<<equation1.spad (SPAD from IN)>>
+<<equation1.spad.dvi (DOC from IN)>>
+
+<<EQ.o (O from NRLIB)>>
+<<EQ.NRLIB (NRLIB from MID)>>
+<<EQ.spad (SPAD from IN)>>
+
+<<EQ2.o (O from NRLIB)>>
+<<EQ2.NRLIB (NRLIB from MID)>>
+<<EQ2.spad (SPAD from IN)>>
+
+<<FEVALAB-.o (O from NRLIB)>>
+<<FEVALAB-.NRLIB (NRLIB from MID)>>
+<<FEVALAB.o (O from NRLIB)>>
+<<FEVALAB.NRLIB (NRLIB from MID)>>
+<<FEVALAB.spad (SPAD from IN)>>
+
+<<equation2.spad (SPAD from IN)>>
+<<equation2.spad.dvi (DOC from IN)>>
+
+<<ERROR.o (O from NRLIB)>>
+<<ERROR.NRLIB (NRLIB from MID)>>
+<<ERROR.spad (SPAD from IN)>>
+
+<<error.spad (SPAD from IN)>>
+<<error.spad.dvi (DOC from IN)>>
+
+<<EXPEXPAN.o (O from NRLIB)>>
+<<EXPEXPAN.NRLIB (NRLIB from MID)>>
+<<EXPEXPAN.spad (SPAD from IN)>>
+
+<<EXPUPXS.o (O from NRLIB)>>
+<<EXPUPXS.NRLIB (NRLIB from MID)>>
+<<EXPUPXS.spad (SPAD from IN)>>
+
+<<UPXSSING.o (O from NRLIB)>>
+<<UPXSSING.NRLIB (NRLIB from MID)>>
+<<UPXSSING.spad (SPAD from IN)>>
+
+<<expexpan.spad (SPAD from IN)>>
+<<expexpan.spad.dvi (DOC from IN)>>
+
+<<exposed.lsp (SPAD from IN)>>
+<<exposed.lsp.dvi (DOC from IN)>>
+
+<<EXPR2UPS.o (O from NRLIB)>>
+<<EXPR2UPS.NRLIB (NRLIB from MID)>>
+<<EXPR2UPS.spad (SPAD from IN)>>
+
+<<expr2ups.spad (SPAD from IN)>>
+<<expr2ups.spad.dvi (DOC from IN)>>
+
+<<EXPRODE.o (O from NRLIB)>>
+<<EXPRODE.NRLIB (NRLIB from MID)>>
+<<EXPRODE.spad (SPAD from IN)>>
+
+<<exprode.spad (SPAD from IN)>>
+<<exprode.spad.dvi (DOC from IN)>>
+
+<<EXPR.o (O from NRLIB)>>
+<<EXPR.NRLIB (NRLIB from MID)>>
+<<EXPR.spad (SPAD from IN)>>
+
+<<EXPR2.o (O from NRLIB)>>
+<<EXPR2.NRLIB (NRLIB from MID)>>
+<<EXPR2.spad (SPAD from IN)>>
+
+<<HACKPI.o (O from NRLIB)>>
+<<HACKPI.NRLIB (NRLIB from MID)>>
+<<HACKPI.spad (SPAD from IN)>>
+
+<<PAN2EXPR.o (O from NRLIB)>>
+<<PAN2EXPR.NRLIB (NRLIB from MID)>>
+<<PAN2EXPR.spad (SPAD from IN)>>
+
+<<PICOERCE.o (O from NRLIB)>>
+<<PICOERCE.NRLIB (NRLIB from MID)>>
+<<PICOERCE.spad (SPAD from IN)>>
+
+<<PMASS.o (O from NRLIB)>>
+<<PMASS.NRLIB (NRLIB from MID)>>
+<<PMASS.spad (SPAD from IN)>>
+
+<<PMASSFS.o (O from NRLIB)>>
+<<PMASSFS.NRLIB (NRLIB from MID)>>
+<<PMASSFS.spad (SPAD from IN)>>
+
+<<PMPRED.o (O from NRLIB)>>
+<<PMPRED.NRLIB (NRLIB from MID)>>
+<<PMPRED.spad (SPAD from IN)>>
+
+<<PMPREDFS.o (O from NRLIB)>>
+<<PMPREDFS.NRLIB (NRLIB from MID)>>
+<<PMPREDFS.spad (SPAD from IN)>>
+
+<<expr.spad (SPAD from IN)>>
+<<expr.spad.dvi (DOC from IN)>>
+
+<<NAGF01.o (O from NRLIB)>>
+<<NAGF01.NRLIB (NRLIB from MID)>>
+<<NAGF01.spad (SPAD from IN)>>
+
+<<f01.spad (SPAD from IN)>>
+<<f01.spad.dvi (DOC from IN)>>
+
+<<NAGF02.o (O from NRLIB)>>
+<<NAGF02.NRLIB (NRLIB from MID)>>
+<<NAGF02.spad (SPAD from IN)>>
+
+<<f02.spad (SPAD from IN)>>
+<<f02.spad.dvi (DOC from IN)>>
+
+<<NAGF04.o (O from NRLIB)>>
+<<NAGF04.NRLIB (NRLIB from MID)>>
+<<NAGF04.spad (SPAD from IN)>>
+
+<<f04.spad (SPAD from IN)>>
+<<f04.spad.dvi (DOC from IN)>>
+
+<<NAGF07.o (O from NRLIB)>>
+<<NAGF07.NRLIB (NRLIB from MID)>>
+<<NAGF07.spad (SPAD from IN)>>
+
+<<f07.spad (SPAD from IN)>>
+<<f07.spad.dvi (DOC from IN)>>
+
+<<FACUTIL.o (O from NRLIB)>>
+<<FACUTIL.NRLIB (NRLIB from MID)>>
+<<FACUTIL.spad (SPAD from IN)>>
+
+<<PUSHVAR.o (O from NRLIB)>>
+<<PUSHVAR.NRLIB (NRLIB from MID)>>
+<<PUSHVAR.spad (SPAD from IN)>>
+
+<<facutil.spad (SPAD from IN)>>
+<<facutil.spad.dvi (DOC from IN)>>
+
+<<DLP.o (O from NRLIB)>>
+<<DLP.NRLIB (NRLIB from MID)>>
+<<DLP.spad (SPAD from IN)>>
+
+<<FFIELDC-.o (O from NRLIB)>>
+<<FFIELDC-.NRLIB (NRLIB from MID)>>
+<<FFIELDC.o (O from NRLIB)>>
+<<FFIELDC.NRLIB (NRLIB from MID)>>
+<<FFIELDC.spad (SPAD from IN)>>
+<<FFIELDC-.o (BOOTSTRAP from MID)>>
+<<FFIELDC-.lsp (LISP from IN)>>
+<<FFIELDC.o (BOOTSTRAP from MID)>>
+<<FFIELDC.lsp (LISP from IN)>>
+
+<<FFSLPE.o (O from NRLIB)>>
+<<FFSLPE.NRLIB (NRLIB from MID)>>
+<<FFSLPE.spad (SPAD from IN)>>
+
+<<FPC-.o (O from NRLIB)>>
+<<FPC-.NRLIB (NRLIB from MID)>>
+<<FPC.o (O from NRLIB)>>
+<<FPC.NRLIB (NRLIB from MID)>>
+<<FPC.spad (SPAD from IN)>>
+
+<<XF-.o (O from NRLIB)>>
+<<XF-.NRLIB (NRLIB from MID)>>
+<<XF.o (O from NRLIB)>>
+<<XF.NRLIB (NRLIB from MID)>>
+<<XF.spad (SPAD from IN)>>
+
+<<ffcat.spad (SPAD from IN)>>
+<<ffcat.spad.dvi (DOC from IN)>>
+
+<<FFCG.o (O from NRLIB)>>
+<<FFCG.NRLIB (NRLIB from MID)>>
+<<FFCG.spad (SPAD from IN)>>
+
+<<FFCGP.o (O from NRLIB)>>
+<<FFCGP.NRLIB (NRLIB from MID)>>
+<<FFCGP.spad (SPAD from IN)>>
+
+<<FFCGX.o (O from NRLIB)>>
+<<FFCGX.NRLIB (NRLIB from MID)>>
+<<FFCGX.spad (SPAD from IN)>>
+
+<<ffcg.spad (SPAD from IN)>>
+<<ffcg.spad.dvi (DOC from IN)>>
+
+<<FFF.o (O from NRLIB)>>
+<<FFF.NRLIB (NRLIB from MID)>>
+<<FFF.spad (SPAD from IN)>>
+
+<<fff.spad (SPAD from IN)>>
+<<fff.spad.dvi (DOC from IN)>>
+
+<<FFHOM.o (O from NRLIB)>>
+<<FFHOM.NRLIB (NRLIB from MID)>>
+<<FFHOM.spad (SPAD from IN)>>
+
+<<ffhom.spad (SPAD from IN)>>
+<<ffhom.spad.dvi (DOC from IN)>>
+
+<<FFNB.o (O from NRLIB)>>
+<<FFNB.NRLIB (NRLIB from MID)>>
+<<FFNB.spad (SPAD from IN)>>
+
+<<FFNBX.o (O from NRLIB)>>
+<<FFNBX.NRLIB (NRLIB from MID)>>
+<<FFNBX.spad (SPAD from IN)>>
+
+<<FFNBP.o (O from NRLIB)>>
+<<FFNBP.NRLIB (NRLIB from MID)>>
+<<FFNBP.spad (SPAD from IN)>>
+
+<<ffnb.spad (SPAD from IN)>>
+<<ffnb.spad.dvi (DOC from IN)>>
+
+<<FFPOLY2.o (O from NRLIB)>>
+<<FFPOLY2.NRLIB (NRLIB from MID)>>
+<<FFPOLY2.spad (SPAD from IN)>>
+
+<<ffpoly2.spad (SPAD from IN)>>
+<<ffpoly2.spad.dvi (DOC from IN)>>
+
+<<FFPOLY.o (O from NRLIB)>>
+<<FFPOLY.NRLIB (NRLIB from MID)>>
+<<FFPOLY.spad (SPAD from IN)>>
+
+<<ffpoly.spad (SPAD from IN)>>
+<<ffpoly.spad.dvi (DOC from IN)>>
+
+<<IFF.o (O from NRLIB)>>
+<<IFF.NRLIB (NRLIB from MID)>>
+<<IFF.spad (SPAD from IN)>>
+
+<<FF.o (O from NRLIB)>>
+<<FF.NRLIB (NRLIB from MID)>>
+<<FF.spad (SPAD from IN)>>
+
+<<FFP.o (O from NRLIB)>>
+<<FFP.NRLIB (NRLIB from MID)>>
+<<FFP.spad (SPAD from IN)>>
+
+<<FFX.o (O from NRLIB)>>
+<<FFX.NRLIB (NRLIB from MID)>>
+<<FFX.spad (SPAD from IN)>>
+
+<<ffp.spad (SPAD from IN)>>
+<<ffp.spad.dvi (DOC from IN)>>
+
+<<ffrac.as (SPAD from IN)>>
+<<ffrac.as.dvi (DOC from IN)>>
+
+<<IRREDFFX.o (O from NRLIB)>>
+<<IRREDFFX.NRLIB (NRLIB from MID)>>
+<<IRREDFFX.spad (SPAD from IN)>>
+
+<<ffx.spad (SPAD from IN)>>
+<<ffx.spad.dvi (DOC from IN)>>
+
+<<BINFILE.o (O from NRLIB)>>
+<<BINFILE.NRLIB (NRLIB from MID)>>
+<<BINFILE.spad (SPAD from IN)>>
+
+<<FILE.o (O from NRLIB)>>
+<<FILE.NRLIB (NRLIB from MID)>>
+<<FILE.spad (SPAD from IN)>>
+
+<<FILECAT.o (O from NRLIB)>>
+<<FILECAT.NRLIB (NRLIB from MID)>>
+<<FILECAT.spad (SPAD from IN)>>
+
+<<KAFILE.o (O from NRLIB)>>
+<<KAFILE.NRLIB (NRLIB from MID)>>
+<<KAFILE.spad (SPAD from IN)>>
+
+<<LIB.o (O from NRLIB)>>
+<<LIB.NRLIB (NRLIB from MID)>>
+<<LIB.spad (SPAD from IN)>>
+
+<<TEXTFILE.o (O from NRLIB)>>
+<<TEXTFILE.NRLIB (NRLIB from MID)>>
+<<TEXTFILE.spad (SPAD from IN)>>
+
+<<files.spad (SPAD from IN)>>
+<<files.spad.dvi (DOC from IN)>>
+
+<<FLOAT.o (O from NRLIB)>>
+<<FLOAT.NRLIB (NRLIB from MID)>>
+<<FLOAT.spad (SPAD from IN)>>
+
+<<float.spad (SPAD from IN)>>
+<<float.spad.dvi (DOC from IN)>>
+
+<<ZMOD.o (O from NRLIB)>>
+<<ZMOD.NRLIB (NRLIB from MID)>>
+<<ZMOD.spad (SPAD from IN)>>
+
+<<fmod.spad (SPAD from IN)>>
+<<fmod.spad.dvi (DOC from IN)>>
+
+<<FNAME.o (O from NRLIB)>>
+<<FNAME.NRLIB (NRLIB from MID)>>
+<<FNAME.spad (SPAD from IN)>>
+
+<<FNCAT.o (O from NRLIB)>>
+<<FNCAT.NRLIB (NRLIB from MID)>>
+<<FNCAT.spad (SPAD from IN)>>
+
+<<fname.spad (SPAD from IN)>>
+<<fname.spad.dvi (DOC from IN)>>
+
+<<COMM.o (O from NRLIB)>>
+<<COMM.NRLIB (NRLIB from MID)>>
+<<COMM.spad (SPAD from IN)>>
+
+<<FNLA.o (O from NRLIB)>>
+<<FNLA.NRLIB (NRLIB from MID)>>
+<<FNLA.spad (SPAD from IN)>>
+
+<<HB.o (O from NRLIB)>>
+<<HB.NRLIB (NRLIB from MID)>>
+<<HB.spad (SPAD from IN)>>
+
+<<OSI.o (O from NRLIB)>>
+<<OSI.NRLIB (NRLIB from MID)>>
+<<OSI.spad (SPAD from IN)>>
+
+<<fnla.spad (SPAD from IN)>>
+<<fnla.spad.dvi (DOC from IN)>>
+
+<<FORMULA.o (O from NRLIB)>>
+<<FORMULA.NRLIB (NRLIB from MID)>>
+<<FORMULA.spad (SPAD from IN)>>
+
+<<FORMULA1.o (O from NRLIB)>>
+<<FORMULA1.NRLIB (NRLIB from MID)>>
+<<FORMULA1.spad (SPAD from IN)>>
+
+<<formula.spad (SPAD from IN)>>
+<<formula.spad.dvi (DOC from IN)>>
+
+<<FMTC.o (O from NRLIB)>>
+<<FMTC.NRLIB (NRLIB from MID)>>
+<<FMTC.spad (SPAD from IN)>>
+
+<<FORTCAT.o (O from NRLIB)>>
+<<FORTCAT.NRLIB (NRLIB from MID)>>
+<<FORTCAT.spad (SPAD from IN)>>
+
+<<FORTFN.o (O from NRLIB)>>
+<<FORTFN.NRLIB (NRLIB from MID)>>
+<<FORTFN.spad (SPAD from IN)>>
+
+<<FVC.o (O from NRLIB)>>
+<<FVC.NRLIB (NRLIB from MID)>>
+<<FVC.spad (SPAD from IN)>>
+
+<<FVFUN.o (O from NRLIB)>>
+<<FVFUN.NRLIB (NRLIB from MID)>>
+<<FVFUN.spad (SPAD from IN)>>
+
+<<FMC.o (O from NRLIB)>>
+<<FMC.NRLIB (NRLIB from MID)>>
+<<FMC.spad (SPAD from IN)>>
+
+<<FMFUN.o (O from NRLIB)>>
+<<FMFUN.NRLIB (NRLIB from MID)>>
+<<FMFUN.spad (SPAD from IN)>>
+
+<<fortcat.spad (SPAD from IN)>>
+<<fortcat.spad.dvi (DOC from IN)>>
+
+<<MCMPLX.o (O from NRLIB)>>
+<<MCMPLX.NRLIB (NRLIB from MID)>>
+<<MCMPLX.spad (SPAD from IN)>>
+
+<<MFLOAT.o (O from NRLIB)>>
+<<MFLOAT.NRLIB (NRLIB from MID)>>
+<<MFLOAT.spad (SPAD from IN)>>
+
+<<MINT.o (O from NRLIB)>>
+<<MINT.NRLIB (NRLIB from MID)>>
+<<MINT.spad (SPAD from IN)>>
+
+<<fortmac.spad (SPAD from IN)>>
+<<fortmac.spad.dvi (DOC from IN)>>
+
+<<FCPAK1.o (O from NRLIB)>>
+<<FCPAK1.NRLIB (NRLIB from MID)>>
+<<FCPAK1.spad (SPAD from IN)>>
+
+<<FOP.o (O from NRLIB)>>
+<<FOP.NRLIB (NRLIB from MID)>>
+<<FOP.spad (SPAD from IN)>>
+
+<<FORT.o (O from NRLIB)>>
+<<FORT.NRLIB (NRLIB from MID)>>
+<<FORT.spad (SPAD from IN)>>
+
+<<MCALCFN.o (O from NRLIB)>>
+<<MCALCFN.NRLIB (NRLIB from MID)>>
+<<MCALCFN.spad (SPAD from IN)>>
+
+<<NAGSP.o (O from NRLIB)>>
+<<NAGSP.NRLIB (NRLIB from MID)>>
+<<NAGSP.spad (SPAD from IN)>>
+
+<<TEMUTL.o (O from NRLIB)>>
+<<TEMUTL.NRLIB (NRLIB from MID)>>
+<<TEMUTL.spad (SPAD from IN)>>
+
+<<fortpak.spad (SPAD from IN)>>
+<<fortpak.spad.dvi (DOC from IN)>>
+
+<<FC.o (O from NRLIB)>>
+<<FC.NRLIB (NRLIB from MID)>>
+<<FC.spad (SPAD from IN)>>
+
+<<FEXPR.o (O from NRLIB)>>
+<<FEXPR.NRLIB (NRLIB from MID)>>
+<<FEXPR.spad (SPAD from IN)>>
+
+<<FTEM.o (O from NRLIB)>>
+<<FTEM.NRLIB (NRLIB from MID)>>
+<<FTEM.spad (SPAD from IN)>>
+
+<<FORTRAN.o (O from NRLIB)>>
+<<FORTRAN.NRLIB (NRLIB from MID)>>
+<<FORTRAN.spad (SPAD from IN)>>
+
+<<M3D.o (O from NRLIB)>>
+<<M3D.NRLIB (NRLIB from MID)>>
+<<M3D.spad (SPAD from IN)>>
+
+<<RESULT.o (O from NRLIB)>>
+<<RESULT.NRLIB (NRLIB from MID)>>
+<<RESULT.spad (SPAD from IN)>>
+
+<<SWITCH.o (O from NRLIB)>>
+<<SWITCH.NRLIB (NRLIB from MID)>>
+<<SWITCH.spad (SPAD from IN)>>
+
+<<SFORT.o (O from NRLIB)>>
+<<SFORT.NRLIB (NRLIB from MID)>>
+<<SFORT.spad (SPAD from IN)>>
+
+<<fortran.spad (SPAD from IN)>>
+<<fortran.spad.dvi (DOC from IN)>>
+
+<<FST.o (O from NRLIB)>>
+<<FST.NRLIB (NRLIB from MID)>>
+<<FST.spad (SPAD from IN)>>
+
+<<FT.o (O from NRLIB)>>
+<<FT.NRLIB (NRLIB from MID)>>
+<<FT.spad (SPAD from IN)>>
+
+<<SYMS.o (O from NRLIB)>>
+<<SYMS.NRLIB (NRLIB from MID)>>
+<<SYMS.spad (SPAD from IN)>>
+
+<<SYMTAB.o (O from NRLIB)>>
+<<SYMTAB.NRLIB (NRLIB from MID)>>
+<<SYMTAB.spad (SPAD from IN)>>
+
+<<forttyp.spad (SPAD from IN)>>
+<<forttyp.spad.dvi (DOC from IN)>>
+
+<<FCOMP.o (O from NRLIB)>>
+<<FCOMP.NRLIB (NRLIB from MID)>>
+<<FCOMP.spad (SPAD from IN)>>
+
+<<FSERIES.o (O from NRLIB)>>
+<<FSERIES.NRLIB (NRLIB from MID)>>
+<<FSERIES.spad (SPAD from IN)>>
+
+<<fourier.spad (SPAD from IN)>>
+<<fourier.spad.dvi (DOC from IN)>>
+
+<<FPARFRAC.o (O from NRLIB)>>
+<<FPARFRAC.NRLIB (NRLIB from MID)>>
+<<FPARFRAC.spad (SPAD from IN)>>
+
+<<fparfrac.spad (SPAD from IN)>>
+<<fparfrac.spad.dvi (DOC from IN)>>
+
+<<FRAC.o (O from NRLIB)>>
+<<FRAC.NRLIB (NRLIB from MID)>>
+<<FRAC.spad (SPAD from IN)>>
+
+<<FRAC2.o (O from NRLIB)>>
+<<FRAC2.NRLIB (NRLIB from MID)>>
+<<FRAC2.spad (SPAD from IN)>>
+
+<<LA.o (O from NRLIB)>>
+<<LA.NRLIB (NRLIB from MID)>>
+<<LA.spad (SPAD from IN)>>
+
+<<LO.o (O from NRLIB)>>
+<<LO.NRLIB (NRLIB from MID)>>
+<<LO.spad (SPAD from IN)>>
+
+<<LPEFRAC.o (O from NRLIB)>>
+<<LPEFRAC.NRLIB (NRLIB from MID)>>
+<<LPEFRAC.spad (SPAD from IN)>>
+
+<<QFCAT-.o (O from NRLIB)>>
+<<QFCAT-.NRLIB (NRLIB from MID)>>
+<<QFCAT.o (O from NRLIB)>>
+<<QFCAT.NRLIB (NRLIB from MID)>>
+<<QFCAT.spad (SPAD from IN)>>
+<<QFCAT-.o (BOOTSTRAP from MID)>>
+<<QFCAT-.lsp (LISP from IN)>>
+<<QFCAT.o (BOOTSTRAP from MID)>>
+<<QFCAT.lsp (LISP from IN)>>
+
+<<QFCAT2.o (O from NRLIB)>>
+<<QFCAT2.NRLIB (NRLIB from MID)>>
+<<QFCAT2.spad (SPAD from IN)>>
+
+<<fraction.spad (SPAD from IN)>>
+<<fraction.spad.dvi (DOC from IN)>>
+
+<<FAGROUP.o (O from NRLIB)>>
+<<FAGROUP.NRLIB (NRLIB from MID)>>
+<<FAGROUP.spad (SPAD from IN)>>
+
+<<FAMONC.o (O from NRLIB)>>
+<<FAMONC.NRLIB (NRLIB from MID)>>
+<<FAMONC.spad (SPAD from IN)>>
+
+<<FAMONOID.o (O from NRLIB)>>
+<<FAMONOID.NRLIB (NRLIB from MID)>>
+<<FAMONOID.spad (SPAD from IN)>>
+
+<<FGROUP.o (O from NRLIB)>>
+<<FGROUP.NRLIB (NRLIB from MID)>>
+<<FGROUP.spad (SPAD from IN)>>
+
+<<FMONOID.o (O from NRLIB)>>
+<<FMONOID.NRLIB (NRLIB from MID)>>
+<<FMONOID.spad (SPAD from IN)>>
+
+<<IFAMON.o (O from NRLIB)>>
+<<IFAMON.NRLIB (NRLIB from MID)>>
+<<IFAMON.spad (SPAD from IN)>>
+
+<<LMOPS.o (O from NRLIB)>>
+<<LMOPS.NRLIB (NRLIB from MID)>>
+<<LMOPS.spad (SPAD from IN)>>
+
+<<free.spad (SPAD from IN)>>
+<<free.spad.dvi (DOC from IN)>>
+
+<<FR.o (O from NRLIB)>>
+<<FR.NRLIB (NRLIB from MID)>>
+<<FR.spad (SPAD from IN)>>
+
+<<FR2.o (O from NRLIB)>>
+<<FR2.NRLIB (NRLIB from MID)>>
+<<FR2.spad (SPAD from IN)>>
+
+<<FRUTIL.o (O from NRLIB)>>
+<<FRUTIL.NRLIB (NRLIB from MID)>>
+<<FRUTIL.spad (SPAD from IN)>>
+
+<<fr.spad (SPAD from IN)>>
+<<fr.spad.dvi (DOC from IN)>>
+
+<<FS2EXPXP.o (O from NRLIB)>>
+<<FS2EXPXP.NRLIB (NRLIB from MID)>>
+<<FS2EXPXP.spad (SPAD from IN)>>
+
+<<fs2expxp.spad (SPAD from IN)>>
+<<fs2expxp.spad.dvi (DOC from IN)>>
+
+<<FS2UPS.o (O from NRLIB)>>
+<<FS2UPS.NRLIB (NRLIB from MID)>>
+<<FS2UPS.spad (SPAD from IN)>>
+
+<<fs2ups.spad (SPAD from IN)>>
+<<fs2ups.spad.dvi (DOC from IN)>>
+
+<<ES-.o (O from NRLIB)>>
+<<ES-.NRLIB (NRLIB from MID)>>
+<<ES.o (O from NRLIB)>>
+<<ES.NRLIB (NRLIB from MID)>>
+<<ES.spad (SPAD from IN)>>
+<<ES-.o (BOOTSTRAP from MID)>>
+<<ES-.lsp (LISP from IN)>>
+<<ES.o (BOOTSTRAP from MID)>>
+<<ES.lsp (LISP from IN)>>
+
+<<ES1.o (O from NRLIB)>>
+<<ES1.NRLIB (NRLIB from MID)>>
+<<ES1.spad (SPAD from IN)>>
+
+<<ES2.o (O from NRLIB)>>
+<<ES2.NRLIB (NRLIB from MID)>>
+<<ES2.spad (SPAD from IN)>>
+
+<<FS-.o (O from NRLIB)>>
+<<FS-.NRLIB (NRLIB from MID)>>
+<<FS.o (O from NRLIB)>>
+<<FS.NRLIB (NRLIB from MID)>>
+<<FS.spad (SPAD from IN)>>
+
+<<FS2.o (O from NRLIB)>>
+<<FS2.NRLIB (NRLIB from MID)>>
+<<FS2.spad (SPAD from IN)>>
+
+<<fspace.spad (SPAD from IN)>>
+<<fspace.spad.dvi (DOC from IN)>>
+
+<<FSUPFACT.o (O from NRLIB)>>
+<<FSUPFACT.NRLIB (NRLIB from MID)>>
+<<FSUPFACT.spad (SPAD from IN)>>
+
+<<funcpkgs.spad (SPAD from IN)>>
+<<funcpkgs.spad.dvi (DOC from IN)>>
+
+<<BFUNCT.o (O from NRLIB)>>
+<<BFUNCT.NRLIB (NRLIB from MID)>>
+<<BFUNCT.spad (SPAD from IN)>>
+
+<<functions.spad (SPAD from IN)>>
+<<functions.spad.dvi (DOC from IN)>>
+
+<<GALFACT.o (O from NRLIB)>>
+<<GALFACT.NRLIB (NRLIB from MID)>>
+<<GALFACT.spad (SPAD from IN)>>
+
+<<galfact.spad (SPAD from IN)>>
+<<galfact.spad.dvi (DOC from IN)>>
+
+<<GALFACTU.o (O from NRLIB)>>
+<<GALFACTU.NRLIB (NRLIB from MID)>>
+<<GALFACTU.spad (SPAD from IN)>>
+
+<<galfactu.spad (SPAD from IN)>>
+<<galfactu.spad.dvi (DOC from IN)>>
+
+<<GALPOLYU.o (O from NRLIB)>>
+<<GALPOLYU.NRLIB (NRLIB from MID)>>
+<<GALPOLYU.spad (SPAD from IN)>>
+
+<<galpolyu.spad (SPAD from IN)>>
+<<galpolyu.spad.dvi (DOC from IN)>>
+
+<<GALUTIL.o (O from NRLIB)>>
+<<GALUTIL.NRLIB (NRLIB from MID)>>
+<<GALUTIL.spad (SPAD from IN)>>
+
+<<galutil.spad (SPAD from IN)>>
+<<galutil.spad.dvi (DOC from IN)>>
+
+<<GAUSSFAC.o (O from NRLIB)>>
+<<GAUSSFAC.NRLIB (NRLIB from MID)>>
+<<GAUSSFAC.spad (SPAD from IN)>>
+
+<<gaussfac.spad (SPAD from IN)>>
+<<gaussfac.spad.dvi (DOC from IN)>>
+
+<<CINTSLPE.o (O from NRLIB)>>
+<<CINTSLPE.NRLIB (NRLIB from MID)>>
+<<CINTSLPE.spad (SPAD from IN)>>
+
+<<COMPCAT-.o (O from NRLIB)>>
+<<COMPCAT-.NRLIB (NRLIB from MID)>>
+<<COMPCAT.o (O from NRLIB)>>
+<<COMPCAT.NRLIB (NRLIB from MID)>>
+<<COMPCAT.spad (SPAD from IN)>>
+
+<<COMPFACT.o (O from NRLIB)>>
+<<COMPFACT.NRLIB (NRLIB from MID)>>
+<<COMPFACT.spad (SPAD from IN)>>
+
+<<COMPLEX.o (O from NRLIB)>>
+<<COMPLEX.NRLIB (NRLIB from MID)>>
+<<COMPLEX.spad (SPAD from IN)>>
+
+<<COMPLEX2.o (O from NRLIB)>>
+<<COMPLEX2.NRLIB (NRLIB from MID)>>
+<<COMPLEX2.spad (SPAD from IN)>>
+
+<<COMPLPAT.o (O from NRLIB)>>
+<<COMPLPAT.NRLIB (NRLIB from MID)>>
+<<COMPLPAT.spad (SPAD from IN)>>
+
+<<CPMATCH.o (O from NRLIB)>>
+<<CPMATCH.NRLIB (NRLIB from MID)>>
+<<CPMATCH.spad (SPAD from IN)>>
+
+<<gaussian.spad (SPAD from IN)>>
+<<gaussian.spad.dvi (DOC from IN)>>
+
+<<GBEUCLID.o (O from NRLIB)>>
+<<GBEUCLID.NRLIB (NRLIB from MID)>>
+<<GBEUCLID.spad (SPAD from IN)>>
+
+<<gbeuclid.spad (SPAD from IN)>>
+<<gbeuclid.spad.dvi (DOC from IN)>>
+
+<<GBINTERN.o (O from NRLIB)>>
+<<GBINTERN.NRLIB (NRLIB from MID)>>
+<<GBINTERN.spad (SPAD from IN)>>
+
+<<gbintern.spad (SPAD from IN)>>
+<<gbintern.spad.dvi (DOC from IN)>>
+
+<<GB.o (O from NRLIB)>>
+<<GB.NRLIB (NRLIB from MID)>>
+<<GB.spad (SPAD from IN)>>
+
+<<gb.spad (SPAD from IN)>>
+<<gb.spad.dvi (DOC from IN)>>
+
+<<HDP.o (O from NRLIB)>>
+<<HDP.NRLIB (NRLIB from MID)>>
+<<HDP.spad (SPAD from IN)>>
+
+<<ODP.o (O from NRLIB)>>
+<<ODP.NRLIB (NRLIB from MID)>>
+<<ODP.spad (SPAD from IN)>>
+
+<<ORDFUNS.o (O from NRLIB)>>
+<<ORDFUNS.NRLIB (NRLIB from MID)>>
+<<ORDFUNS.spad (SPAD from IN)>>
+
+<<SHDP.o (O from NRLIB)>>
+<<SHDP.NRLIB (NRLIB from MID)>>
+<<SHDP.spad (SPAD from IN)>>
+
+<<gdirprod.spad (SPAD from IN)>>
+<<gdirprod.spad.dvi (DOC from IN)>>
+
+<<DMP.o (O from NRLIB)>>
+<<DMP.NRLIB (NRLIB from MID)>>
+<<DMP.spad (SPAD from IN)>>
+
+<<GDMP.o (O from NRLIB)>>
+<<GDMP.NRLIB (NRLIB from MID)>>
+<<GDMP.spad (SPAD from IN)>>
+
+<<HDMP.o (O from NRLIB)>>
+<<HDMP.NRLIB (NRLIB from MID)>>
+<<HDMP.spad (SPAD from IN)>>
+
+<<gdpoly.spad (SPAD from IN)>>
+<<gdpoly.spad.dvi (DOC from IN)>>
+
+<<GENEEZ.o (O from NRLIB)>>
+<<GENEEZ.NRLIB (NRLIB from MID)>>
+<<GENEEZ.spad (SPAD from IN)>>
+
+<<geneez.spad (SPAD from IN)>>
+<<geneez.spad.dvi (DOC from IN)>>
+
+<<CVMP.o (O from NRLIB)>>
+<<CVMP.NRLIB (NRLIB from MID)>>
+<<CVMP.spad (SPAD from IN)>>
+
+<<GCNAALG.o (O from NRLIB)>>
+<<GCNAALG.NRLIB (NRLIB from MID)>>
+<<GCNAALG.spad (SPAD from IN)>>
+
+<<generic.spad (SPAD from IN)>>
+<<generic.spad.dvi (DOC from IN)>>
+
+<<GENUFACT.o (O from NRLIB)>>
+<<GENUFACT.NRLIB (NRLIB from MID)>>
+<<GENUFACT.spad (SPAD from IN)>>
+
+<<genufact.spad (SPAD from IN)>>
+<<genufact.spad.dvi (DOC from IN)>>
+
+<<GENUPS.o (O from NRLIB)>>
+<<GENUPS.NRLIB (NRLIB from MID)>>
+<<GENUPS.spad (SPAD from IN)>>
+
+<<genups.spad (SPAD from IN)>>
+<<genups.spad.dvi (DOC from IN)>>
+
+<<GHENSEL.o (O from NRLIB)>>
+<<GHENSEL.NRLIB (NRLIB from MID)>>
+<<GHENSEL.spad (SPAD from IN)>>
+
+<<ghensel.spad (SPAD from IN)>>
+<<ghensel.spad.dvi (DOC from IN)>>
+
+<<GENPGCD.o (O from NRLIB)>>
+<<GENPGCD.NRLIB (NRLIB from MID)>>
+<<GENPGCD.spad (SPAD from IN)>>
+
+<<gpgcd.spad (SPAD from IN)>>
+<<gpgcd.spad.dvi (DOC from IN)>>
+
+<<LAUPOL.o (O from NRLIB)>>
+<<LAUPOL.NRLIB (NRLIB from MID)>>
+<<LAUPOL.spad (SPAD from IN)>>
+
+<<gpol.spad (SPAD from IN)>>
+<<gpol.spad.dvi (DOC from IN)>>
+
+<<GRDEF.o (O from NRLIB)>>
+<<GRDEF.NRLIB (NRLIB from MID)>>
+<<GRDEF.spad (SPAD from IN)>>
+
+<<grdef.spad (SPAD from IN)>>
+<<grdef.spad.dvi (DOC from IN)>>
+
+<<GBF.o (O from NRLIB)>>
+<<GBF.NRLIB (NRLIB from MID)>>
+<<GBF.spad (SPAD from IN)>>
+
+<<groebf.spad (SPAD from IN)>>
+<<groebf.spad.dvi (DOC from IN)>>
+
+<<GROEBSOL.o (O from NRLIB)>>
+<<GROEBSOL.NRLIB (NRLIB from MID)>>
+<<GROEBSOL.spad (SPAD from IN)>>
+
+<<groebsol.spad (SPAD from IN)>>
+<<groebsol.spad.dvi (DOC from IN)>>
+
+<<GSERIES.o (O from NRLIB)>>
+<<GSERIES.NRLIB (NRLIB from MID)>>
+<<GSERIES.spad (SPAD from IN)>>
+
+<<gseries.spad (SPAD from IN)>>
+<<gseries.spad.dvi (DOC from IN)>>
+
+<<herm.as (SPAD from IN)>>
+<<herm.as.dvi (DOC from IN)>>
+
+<<IDEAL.o (O from NRLIB)>>
+<<IDEAL.NRLIB (NRLIB from MID)>>
+<<IDEAL.spad (SPAD from IN)>>
+
+<<ideal.spad (SPAD from IN)>>
+<<ideal.spad.dvi (DOC from IN)>>
+
+<<IDECOMP.o (O from NRLIB)>>
+<<IDECOMP.NRLIB (NRLIB from MID)>>
+<<IDECOMP.spad (SPAD from IN)>>
+
+<<idecomp.spad (SPAD from IN)>>
+<<idecomp.spad.dvi (DOC from IN)>>
+
+<<IDPAG.o (O from NRLIB)>>
+<<IDPAG.NRLIB (NRLIB from MID)>>
+<<IDPAG.spad (SPAD from IN)>>
+
+<<IDPAM.o (O from NRLIB)>>
+<<IDPAM.NRLIB (NRLIB from MID)>>
+<<IDPAM.spad (SPAD from IN)>>
+
+<<IDPC.o (O from NRLIB)>>
+<<IDPC.NRLIB (NRLIB from MID)>>
+<<IDPC.spad (SPAD from IN)>>
+
+<<IDPO.o (O from NRLIB)>>
+<<IDPO.NRLIB (NRLIB from MID)>>
+<<IDPO.spad (SPAD from IN)>>
+
+<<IDPOAM.o (O from NRLIB)>>
+<<IDPOAM.NRLIB (NRLIB from MID)>>
+<<IDPOAM.spad (SPAD from IN)>>
+
+<<IDPOAMS.o (O from NRLIB)>>
+<<IDPOAMS.NRLIB (NRLIB from MID)>>
+<<IDPOAMS.spad (SPAD from IN)>>
+
+<<indexedp.spad (SPAD from IN)>>
+<<indexedp.spad.dvi (DOC from IN)>>
+
+<<INFPROD0.o (O from NRLIB)>>
+<<INFPROD0.NRLIB (NRLIB from MID)>>
+<<INFPROD0.spad (SPAD from IN)>>
+
+<<INPRODFF.o (O from NRLIB)>>
+<<INPRODFF.NRLIB (NRLIB from MID)>>
+<<INPRODFF.spad (SPAD from IN)>>
+
+<<INPRODPF.o (O from NRLIB)>>
+<<INPRODPF.NRLIB (NRLIB from MID)>>
+<<INPRODPF.spad (SPAD from IN)>>
+
+<<STINPROD.o (O from NRLIB)>>
+<<STINPROD.NRLIB (NRLIB from MID)>>
+<<STINPROD.spad (SPAD from IN)>>
+
+<<infprod.spad (SPAD from IN)>>
+<<infprod.spad.dvi (DOC from IN)>>
+
+<<INTAF.o (O from NRLIB)>>
+<<INTAF.NRLIB (NRLIB from MID)>>
+<<INTAF.spad (SPAD from IN)>>
+
+<<INTG0.o (O from NRLIB)>>
+<<INTG0.NRLIB (NRLIB from MID)>>
+<<INTG0.spad (SPAD from IN)>>
+
+<<INTPAF.o (O from NRLIB)>>
+<<INTPAF.NRLIB (NRLIB from MID)>>
+<<INTPAF.spad (SPAD from IN)>>
+
+<<intaf.spad (SPAD from IN)>>
+<<intaf.spad.dvi (DOC from IN)>>
+
+<<DBLRESP.o (O from NRLIB)>>
+<<DBLRESP.NRLIB (NRLIB from MID)>>
+<<DBLRESP.spad (SPAD from IN)>>
+
+<<INTALG.o (O from NRLIB)>>
+<<INTALG.NRLIB (NRLIB from MID)>>
+<<INTALG.spad (SPAD from IN)>>
+
+<<INTHERAL.o (O from NRLIB)>>
+<<INTHERAL.NRLIB (NRLIB from MID)>>
+<<INTHERAL.spad (SPAD from IN)>>
+
+<<intalg.spad (SPAD from IN)>>
+<<intalg.spad.dvi (DOC from IN)>>
+
+<<IR.o (O from NRLIB)>>
+<<IR.NRLIB (NRLIB from MID)>>
+<<IR.spad (SPAD from IN)>>
+
+<<IR2.o (O from NRLIB)>>
+<<IR2.NRLIB (NRLIB from MID)>>
+<<IR2.spad (SPAD from IN)>>
+
+<<intaux.spad (SPAD from IN)>>
+<<intaux.spad.dvi (DOC from IN)>>
+
+<<IBATOOL.o (O from NRLIB)>>
+<<IBATOOL.NRLIB (NRLIB from MID)>>
+<<IBATOOL.spad (SPAD from IN)>>
+
+<<FFINTBAS.o (O from NRLIB)>>
+<<FFINTBAS.NRLIB (NRLIB from MID)>>
+<<FFINTBAS.spad (SPAD from IN)>>
+
+<<NFINTBAS.o (O from NRLIB)>>
+<<NFINTBAS.NRLIB (NRLIB from MID)>>
+<<NFINTBAS.spad (SPAD from IN)>>
+
+<<TRIMAT.o (O from NRLIB)>>
+<<TRIMAT.NRLIB (NRLIB from MID)>>
+<<TRIMAT.spad (SPAD from IN)>>
+
+<<WFFINTBS.o (O from NRLIB)>>
+<<WFFINTBS.NRLIB (NRLIB from MID)>>
+<<WFFINTBS.spad (SPAD from IN)>>
+
+<<intclos.spad (SPAD from IN)>>
+<<intclos.spad.dvi (DOC from IN)>>
+
+<<INTEF.o (O from NRLIB)>>
+<<INTEF.NRLIB (NRLIB from MID)>>
+<<INTEF.spad (SPAD from IN)>>
+
+<<intef.spad (SPAD from IN)>>
+<<intef.spad.dvi (DOC from IN)>>
+
+<<INT.o (O from NRLIB)>>
+<<INT.NRLIB (NRLIB from MID)>>
+<<INT.spad (SPAD from IN)>>
+<<INT.o (BOOTSTRAP from MID)>>
+<<INT.lsp (LISP from IN)>>
+
+<<INTSLPE.o (O from NRLIB)>>
+<<INTSLPE.NRLIB (NRLIB from MID)>>
+<<INTSLPE.spad (SPAD from IN)>>
+
+<<NNI.o (O from NRLIB)>>
+<<NNI.NRLIB (NRLIB from MID)>>
+<<NNI.spad (SPAD from IN)>>
+<<NNI.o (BOOTSTRAP from MID)>>
+<<NNI.lsp (LISP from IN)>>
+
+<<PI.o (O from NRLIB)>>
+<<PI.NRLIB (NRLIB from MID)>>
+<<PI.spad (SPAD from IN)>>
+<<PI.o (BOOTSTRAP from MID)>>
+<<PI.lsp (LISP from IN)>>
+
+<<ROMAN.o (O from NRLIB)>>
+<<ROMAN.NRLIB (NRLIB from MID)>>
+<<ROMAN.spad (SPAD from IN)>>
+
+<<integer.spad (SPAD from IN)>>
+<<integer.spad.dvi (DOC from IN)>>
+
+<<FSCINT.o (O from NRLIB)>>
+<<FSCINT.NRLIB (NRLIB from MID)>>
+<<FSCINT.spad (SPAD from IN)>>
+
+<<FSINT.o (O from NRLIB)>>
+<<FSINT.NRLIB (NRLIB from MID)>>
+<<FSINT.spad (SPAD from IN)>>
+
+<<integrat.spad (SPAD from IN)>>
+<<integrat.spad.dvi (DOC from IN)>>
+
+<<INTERP.EXPOSED (SPAD from IN)>>
+<<INTERP.EXPOSED.dvi (DOC from IN)>>
+
+<<interval.as (SPAD from IN)>>
+<<interval.as.dvi (DOC from IN)>>
+
+<<INTCAT.o (O from NRLIB)>>
+<<INTCAT.NRLIB (NRLIB from MID)>>
+<<INTCAT.spad (SPAD from IN)>>
+
+<<INTRVL.o (O from NRLIB)>>
+<<INTRVL.NRLIB (NRLIB from MID)>>
+<<INTRVL.spad (SPAD from IN)>>
+
+<<interval.spad (SPAD from IN)>>
+<<interval.spad.dvi (DOC from IN)>>
+
+<<INTFACT.o (O from NRLIB)>>
+<<INTFACT.NRLIB (NRLIB from MID)>>
+<<INTFACT.spad (SPAD from IN)>>
+
+<<IROOT.o (O from NRLIB)>>
+<<IROOT.NRLIB (NRLIB from MID)>>
+<<IROOT.spad (SPAD from IN)>>
+
+<<PRIMES.o (O from NRLIB)>>
+<<PRIMES.NRLIB (NRLIB from MID)>>
+<<PRIMES.spad (SPAD from IN)>>
+
+<<intfact.spad (SPAD from IN)>>
+<<intfact.spad.dvi (DOC from IN)>>
+
+<<INTPM.o (O from NRLIB)>>
+<<INTPM.NRLIB (NRLIB from MID)>>
+<<INTPM.spad (SPAD from IN)>>
+
+<<intpm.spad (SPAD from IN)>>
+<<intpm.spad.dvi (DOC from IN)>>
+
+<<INTHERTR.o (O from NRLIB)>>
+<<INTHERTR.NRLIB (NRLIB from MID)>>
+<<INTHERTR.spad (SPAD from IN)>>
+
+<<INTRAT.o (O from NRLIB)>>
+<<INTRAT.NRLIB (NRLIB from MID)>>
+<<INTRAT.spad (SPAD from IN)>>
+
+<<INTRF.o (O from NRLIB)>>
+<<INTRF.NRLIB (NRLIB from MID)>>
+<<INTRF.spad (SPAD from IN)>>
+
+<<INTTR.o (O from NRLIB)>>
+<<INTTR.NRLIB (NRLIB from MID)>>
+<<INTTR.spad (SPAD from IN)>>
+
+<<MONOTOOL.o (O from NRLIB)>>
+<<MONOTOOL.NRLIB (NRLIB from MID)>>
+<<MONOTOOL.spad (SPAD from IN)>>
+
+<<SUBRESP.o (O from NRLIB)>>
+<<SUBRESP.NRLIB (NRLIB from MID)>>
+<<SUBRESP.spad (SPAD from IN)>>
+
+<<intrf.spad (SPAD from IN)>>
+<<intrf.spad.dvi (DOC from IN)>>
+
+<<invnode.as (SPAD from IN)>>
+<<invnode.as.dvi (DOC from IN)>>
+
+<<invrender.as (SPAD from IN)>>
+<<invrender.as.dvi (DOC from IN)>>
+
+<<invtypes.as (SPAD from IN)>>
+<<invtypes.as.dvi (DOC from IN)>>
+
+<<invutils.as (SPAD from IN)>>
+<<invutils.as.dvi (DOC from IN)>>
+
+<<IR2F.o (O from NRLIB)>>
+<<IR2F.NRLIB (NRLIB from MID)>>
+<<IR2F.spad (SPAD from IN)>>
+
+<<IRRF2F.o (O from NRLIB)>>
+<<IRRF2F.NRLIB (NRLIB from MID)>>
+<<IRRF2F.spad (SPAD from IN)>>
+
+<<irexpand.spad (SPAD from IN)>>
+<<irexpand.spad.dvi (DOC from IN)>>
+
+<<IRSN.o (O from NRLIB)>>
+<<IRSN.NRLIB (NRLIB from MID)>>
+<<IRSN.spad (SPAD from IN)>>
+
+<<irsn.spad (SPAD from IN)>>
+<<irsn.spad.dvi (DOC from IN)>>
+
+<<ITFUN2.o (O from NRLIB)>>
+<<ITFUN2.NRLIB (NRLIB from MID)>>
+<<ITFUN2.spad (SPAD from IN)>>
+
+<<ITFUN3.o (O from NRLIB)>>
+<<ITFUN3.NRLIB (NRLIB from MID)>>
+<<ITFUN3.spad (SPAD from IN)>>
+
+<<ITUPLE.o (O from NRLIB)>>
+<<ITUPLE.NRLIB (NRLIB from MID)>>
+<<ITUPLE.spad (SPAD from IN)>>
+
+<<ituple.spad (SPAD from IN)>>
+<<ituple.spad.dvi (DOC from IN)>>
+
+<<iviews.as (SPAD from IN)>>
+<<iviews.as.dvi (DOC from IN)>>
+
+<<CACHSET.o (O from NRLIB)>>
+<<CACHSET.NRLIB (NRLIB from MID)>>
+<<CACHSET.spad (SPAD from IN)>>
+
+<<KERNEL.o (O from NRLIB)>>
+<<KERNEL.NRLIB (NRLIB from MID)>>
+<<KERNEL.spad (SPAD from IN)>>
+
+<<KERNEL2.o (O from NRLIB)>>
+<<KERNEL2.NRLIB (NRLIB from MID)>>
+<<KERNEL2.spad (SPAD from IN)>>
+
+<<MKCHSET.o (O from NRLIB)>>
+<<MKCHSET.NRLIB (NRLIB from MID)>>
+<<MKCHSET.spad (SPAD from IN)>>
+
+<<SCACHE.o (O from NRLIB)>>
+<<SCACHE.NRLIB (NRLIB from MID)>>
+<<SCACHE.spad (SPAD from IN)>>
+
+<<kl.spad (SPAD from IN)>>
+<<kl.spad.dvi (DOC from IN)>>
+
+<<KOVACIC.o (O from NRLIB)>>
+<<KOVACIC.NRLIB (NRLIB from MID)>>
+<<KOVACIC.spad (SPAD from IN)>>
+
+<<kovacic.spad (SPAD from IN)>>
+<<kovacic.spad.dvi (DOC from IN)>>
+
+<<INVLAPLA.o (O from NRLIB)>>
+<<INVLAPLA.NRLIB (NRLIB from MID)>>
+<<INVLAPLA.spad (SPAD from IN)>>
+
+<<LAPLACE.o (O from NRLIB)>>
+<<LAPLACE.NRLIB (NRLIB from MID)>>
+<<LAPLACE.spad (SPAD from IN)>>
+
+<<laplace.spad (SPAD from IN)>>
+<<laplace.spad.dvi (DOC from IN)>>
+
+<<ULS.o (O from NRLIB)>>
+<<ULS.NRLIB (NRLIB from MID)>>
+<<ULS.spad (SPAD from IN)>>
+
+<<ULSCCAT-.o (O from NRLIB)>>
+<<ULSCCAT-.NRLIB (NRLIB from MID)>>
+<<ULSCCAT.o (O from NRLIB)>>
+<<ULSCCAT.NRLIB (NRLIB from MID)>>
+<<ULSCCAT.spad (SPAD from IN)>>
+
+<<ULSCONS.o (O from NRLIB)>>
+<<ULSCONS.NRLIB (NRLIB from MID)>>
+<<ULSCONS.spad (SPAD from IN)>>
+
+<<ULS2.o (O from NRLIB)>>
+<<ULS2.NRLIB (NRLIB from MID)>>
+<<ULS2.spad (SPAD from IN)>>
+
+<<laurent.spad (SPAD from IN)>>
+<<laurent.spad.dvi (DOC from IN)>>
+
+<<LEADCDET.o (O from NRLIB)>>
+<<LEADCDET.NRLIB (NRLIB from MID)>>
+<<LEADCDET.spad (SPAD from IN)>>
+
+<<leadcdet.spad (SPAD from IN)>>
+<<leadcdet.spad.dvi (DOC from IN)>>
+
+<<JORDAN.o (O from NRLIB)>>
+<<JORDAN.NRLIB (NRLIB from MID)>>
+<<JORDAN.spad (SPAD from IN)>>
+
+<<LIE.o (O from NRLIB)>>
+<<LIE.NRLIB (NRLIB from MID)>>
+<<LIE.spad (SPAD from IN)>>
+
+<<LSQM.o (O from NRLIB)>>
+<<LSQM.NRLIB (NRLIB from MID)>>
+<<LSQM.spad (SPAD from IN)>>
+
+<<lie.spad (SPAD from IN)>>
+<<lie.spad.dvi (DOC from IN)>>
+
+<<LIMITPS.o (O from NRLIB)>>
+<<LIMITPS.NRLIB (NRLIB from MID)>>
+<<LIMITPS.spad (SPAD from IN)>>
+
+<<limitps.spad (SPAD from IN)>>
+<<limitps.spad.dvi (DOC from IN)>>
+
+<<LINDEP.o (O from NRLIB)>>
+<<LINDEP.NRLIB (NRLIB from MID)>>
+<<LINDEP.spad (SPAD from IN)>>
+
+<<ZLINDEP.o (O from NRLIB)>>
+<<ZLINDEP.NRLIB (NRLIB from MID)>>
+<<ZLINDEP.spad (SPAD from IN)>>
+
+<<lindep.spad (SPAD from IN)>>
+<<lindep.spad.dvi (DOC from IN)>>
+
+<<LGROBP.o (O from NRLIB)>>
+<<LGROBP.NRLIB (NRLIB from MID)>>
+<<LGROBP.spad (SPAD from IN)>>
+
+<<lingrob.spad (SPAD from IN)>>
+<<lingrob.spad.dvi (DOC from IN)>>
+
+<<LF.o (O from NRLIB)>>
+<<LF.NRLIB (NRLIB from MID)>>
+<<LF.spad (SPAD from IN)>>
+
+<<liouv.spad (SPAD from IN)>>
+<<liouv.spad.dvi (DOC from IN)>>
+
+<<HEUGCD.o (O from NRLIB)>>
+<<HEUGCD.NRLIB (NRLIB from MID)>>
+<<HEUGCD.spad (SPAD from IN)>>
+
+<<listgcd.spad (SPAD from IN)>>
+<<listgcd.spad.dvi (DOC from IN)>>
+
+<<ILIST.o (O from NRLIB)>>
+<<ILIST.NRLIB (NRLIB from MID)>>
+<<ILIST.spad (SPAD from IN)>>
+<<ILIST.o (BOOTSTRAP from MID)>>
+<<ILIST.lsp (LISP from IN)>>
+
+<<LIST.o (O from NRLIB)>>
+<<LIST.NRLIB (NRLIB from MID)>>
+<<LIST.spad (SPAD from IN)>>
+<<LIST.o (BOOTSTRAP from MID)>>
+<<LIST.lsp (LISP from IN)>>
+
+<<ALIST.o (O from NRLIB)>>
+<<ALIST.NRLIB (NRLIB from MID)>>
+<<ALIST.spad (SPAD from IN)>>
+
+<<LIST2.o (O from NRLIB)>>
+<<LIST2.NRLIB (NRLIB from MID)>>
+<<LIST2.spad (SPAD from IN)>>
+
+<<LIST2MAP.o (O from NRLIB)>>
+<<LIST2MAP.NRLIB (NRLIB from MID)>>
+<<LIST2MAP.spad (SPAD from IN)>>
+
+<<LIST3.o (O from NRLIB)>>
+<<LIST3.NRLIB (NRLIB from MID)>>
+<<LIST3.spad (SPAD from IN)>>
+
+<<list.spad (SPAD from IN)>>
+<<list.spad.dvi (DOC from IN)>>
+
+<<LMDICT.o (O from NRLIB)>>
+<<LMDICT.NRLIB (NRLIB from MID)>>
+<<LMDICT.spad (SPAD from IN)>>
+
+<<lmdict.spad (SPAD from IN)>>
+<<lmdict.spad.dvi (DOC from IN)>>
+
+<<ASSOCEQ.o (O from NRLIB)>>
+<<ASSOCEQ.NRLIB (NRLIB from MID)>>
+<<ASSOCEQ.spad (SPAD from IN)>>
+
+<<LODOF.o (O from NRLIB)>>
+<<LODOF.NRLIB (NRLIB from MID)>>
+<<LODOF.spad (SPAD from IN)>>
+
+<<PREASSOC.o (O from NRLIB)>>
+<<PREASSOC.NRLIB (NRLIB from MID)>>
+<<PREASSOC.spad (SPAD from IN)>>
+
+<<SETMN.o (O from NRLIB)>>
+<<SETMN.NRLIB (NRLIB from MID)>>
+<<SETMN.spad (SPAD from IN)>>
+
+<<lodof.spad (SPAD from IN)>>
+<<lodof.spad.dvi (DOC from IN)>>
+
+<<DPMO.o (O from NRLIB)>>
+<<DPMO.NRLIB (NRLIB from MID)>>
+<<DPMO.spad (SPAD from IN)>>
+
+<<DPMM.o (O from NRLIB)>>
+<<DPMM.NRLIB (NRLIB from MID)>>
+<<DPMM.spad (SPAD from IN)>>
+
+<<MLO.o (O from NRLIB)>>
+<<MLO.NRLIB (NRLIB from MID)>>
+<<MLO.spad (SPAD from IN)>>
+
+<<NCODIV.o (O from NRLIB)>>
+<<NCODIV.NRLIB (NRLIB from MID)>>
+<<NCODIV.spad (SPAD from IN)>>
+
+<<ODR.o (O from NRLIB)>>
+<<ODR.NRLIB (NRLIB from MID)>>
+<<ODR.spad (SPAD from IN)>>
+
+<<OMLO.o (O from NRLIB)>>
+<<OMLO.NRLIB (NRLIB from MID)>>
+<<OMLO.spad (SPAD from IN)>>
+
+<<lodop.spad (SPAD from IN)>>
+<<lodop.spad.dvi (DOC from IN)>>
+
+<<LODO1.o (O from NRLIB)>>
+<<LODO1.NRLIB (NRLIB from MID)>>
+<<LODO1.spad (SPAD from IN)>>
+
+<<LODO2.o (O from NRLIB)>>
+<<LODO2.NRLIB (NRLIB from MID)>>
+<<LODO2.spad (SPAD from IN)>>
+
+<<LODOCAT-.o (O from NRLIB)>>
+<<LODOCAT-.NRLIB (NRLIB from MID)>>
+<<LODOCAT.o (O from NRLIB)>>
+<<LODOCAT.NRLIB (NRLIB from MID)>>
+<<LODOCAT.spad (SPAD from IN)>>
+
+<<LODOOPS.o (O from NRLIB)>>
+<<LODOOPS.NRLIB (NRLIB from MID)>>
+<<LODOOPS.spad (SPAD from IN)>>
+
+<<lodo.spad (SPAD from IN)>>
+<<lodo.spad.dvi (DOC from IN)>>
+
+<<FACTFUNC.o (O from NRLIB)>>
+<<FACTFUNC.NRLIB (NRLIB from MID)>>
+<<FACTFUNC.spad (SPAD from IN)>>
+
+<<ALGMANIP.o (O from NRLIB)>>
+<<ALGMANIP.NRLIB (NRLIB from MID)>>
+<<ALGMANIP.spad (SPAD from IN)>>
+
+<<POLYROOT.o (O from NRLIB)>>
+<<POLYROOT.NRLIB (NRLIB from MID)>>
+<<POLYROOT.spad (SPAD from IN)>>
+
+<<SIMPAN.o (O from NRLIB)>>
+<<SIMPAN.NRLIB (NRLIB from MID)>>
+<<SIMPAN.spad (SPAD from IN)>>
+
+<<TRMANIP.o (O from NRLIB)>>
+<<TRMANIP.NRLIB (NRLIB from MID)>>
+<<TRMANIP.spad (SPAD from IN)>>
+
+<<manip.spad (SPAD from IN)>>
+<<manip.spad.dvi (DOC from IN)>>
+
+<<MAPHACK1.o (O from NRLIB)>>
+<<MAPHACK1.NRLIB (NRLIB from MID)>>
+<<MAPHACK1.spad (SPAD from IN)>>
+
+<<MAPHACK2.o (O from NRLIB)>>
+<<MAPHACK2.NRLIB (NRLIB from MID)>>
+<<MAPHACK2.spad (SPAD from IN)>>
+
+<<MAPHACK3.o (O from NRLIB)>>
+<<MAPHACK3.NRLIB (NRLIB from MID)>>
+<<MAPHACK3.spad (SPAD from IN)>>
+
+<<MAPPKG1.o (O from NRLIB)>>
+<<MAPPKG1.NRLIB (NRLIB from MID)>>
+<<MAPPKG1.spad (SPAD from IN)>>
+
+<<MAPPKG2.o (O from NRLIB)>>
+<<MAPPKG2.NRLIB (NRLIB from MID)>>
+<<MAPPKG2.spad (SPAD from IN)>>
+
+<<MAPPKG3.o (O from NRLIB)>>
+<<MAPPKG3.NRLIB (NRLIB from MID)>>
+<<MAPPKG3.spad (SPAD from IN)>>
+
+<<mappkg.spad (SPAD from IN)>>
+<<mappkg.spad.dvi (DOC from IN)>>
+
+<<MATCAT-.o (O from NRLIB)>>
+<<MATCAT-.NRLIB (NRLIB from MID)>>
+<<MATCAT.o (O from NRLIB)>>
+<<MATCAT.NRLIB (NRLIB from MID)>>
+<<MATCAT.spad (SPAD from IN)>>
+
+<<RMATCAT-.o (O from NRLIB)>>
+<<RMATCAT-.NRLIB (NRLIB from MID)>>
+<<RMATCAT.o (O from NRLIB)>>
+<<RMATCAT.NRLIB (NRLIB from MID)>>
+<<RMATCAT.spad (SPAD from IN)>>
+
+<<SMATCAT-.o (O from NRLIB)>>
+<<SMATCAT-.NRLIB (NRLIB from MID)>>
+<<SMATCAT.o (O from NRLIB)>>
+<<SMATCAT.NRLIB (NRLIB from MID)>>
+<<SMATCAT.spad (SPAD from IN)>>
+
+<<matcat.spad (SPAD from IN)>>
+<<matcat.spad.dvi (DOC from IN)>>
+
+<<IMATLIN.o (O from NRLIB)>>
+<<IMATLIN.NRLIB (NRLIB from MID)>>
+<<IMATLIN.spad (SPAD from IN)>>
+
+<<IMATQF.o (O from NRLIB)>>
+<<IMATQF.NRLIB (NRLIB from MID)>>
+<<IMATQF.spad (SPAD from IN)>>
+
+<<MATCAT2.o (O from NRLIB)>>
+<<MATCAT2.NRLIB (NRLIB from MID)>>
+<<MATCAT2.spad (SPAD from IN)>>
+
+<<MATLIN.o (O from NRLIB)>>
+<<MATLIN.NRLIB (NRLIB from MID)>>
+<<MATLIN.spad (SPAD from IN)>>
+
+<<RMCAT2.o (O from NRLIB)>>
+<<RMCAT2.NRLIB (NRLIB from MID)>>
+<<RMCAT2.spad (SPAD from IN)>>
+
+<<matfuns.spad (SPAD from IN)>>
+<<matfuns.spad.dvi (DOC from IN)>>
+
+<<IMATRIX.o (O from NRLIB)>>
+<<IMATRIX.NRLIB (NRLIB from MID)>>
+<<IMATRIX.spad (SPAD from IN)>>
+
+<<MATRIX.o (O from NRLIB)>>
+<<MATRIX.NRLIB (NRLIB from MID)>>
+<<MATRIX.spad (SPAD from IN)>>
+
+<<RMATRIX.o (O from NRLIB)>>
+<<RMATRIX.NRLIB (NRLIB from MID)>>
+<<RMATRIX.spad (SPAD from IN)>>
+
+<<SQMATRIX.o (O from NRLIB)>>
+<<SQMATRIX.NRLIB (NRLIB from MID)>>
+<<SQMATRIX.spad (SPAD from IN)>>
+
+<<matrix.spad (SPAD from IN)>>
+<<matrix.spad.dvi (DOC from IN)>>
+
+<<MATSTOR.o (O from NRLIB)>>
+<<MATSTOR.NRLIB (NRLIB from MID)>>
+<<MATSTOR.spad (SPAD from IN)>>
+
+<<matstor.spad (SPAD from IN)>>
+<<matstor.spad.dvi (DOC from IN)>>
+
+<<MESH.o (O from NRLIB)>>
+<<MESH.NRLIB (NRLIB from MID)>>
+<<MESH.spad (SPAD from IN)>>
+
+<<mesh.spad (SPAD from IN)>>
+<<mesh.spad.dvi (DOC from IN)>>
+
+<<MFINFACT.o (O from NRLIB)>>
+<<MFINFACT.NRLIB (NRLIB from MID)>>
+<<MFINFACT.spad (SPAD from IN)>>
+
+<<mfinfact.spad (SPAD from IN)>>
+<<mfinfact.spad.dvi (DOC from IN)>>
+
+<<SAOS.o (O from NRLIB)>>
+<<SAOS.NRLIB (NRLIB from MID)>>
+<<SAOS.spad (SPAD from IN)>>
+
+<<misc.spad (SPAD from IN)>>
+<<misc.spad.dvi (DOC from IN)>>
+
+<<INFORM.o (O from NRLIB)>>
+<<INFORM.NRLIB (NRLIB from MID)>>
+<<INFORM.spad (SPAD from IN)>>
+
+<<INFORM1.o (O from NRLIB)>>
+<<INFORM1.NRLIB (NRLIB from MID)>>
+<<INFORM1.spad (SPAD from IN)>>
+
+<<MKFLCFN.o (O from NRLIB)>>
+<<MKFLCFN.NRLIB (NRLIB from MID)>>
+<<MKFLCFN.spad (SPAD from IN)>>
+
+<<MKFUNC.o (O from NRLIB)>>
+<<MKFUNC.NRLIB (NRLIB from MID)>>
+<<MKFUNC.spad (SPAD from IN)>>
+
+<<MKBCFUNC.o (O from NRLIB)>>
+<<MKBCFUNC.NRLIB (NRLIB from MID)>>
+<<MKBCFUNC.spad (SPAD from IN)>>
+
+<<MKUCFUNC.o (O from NRLIB)>>
+<<MKUCFUNC.NRLIB (NRLIB from MID)>>
+<<MKUCFUNC.spad (SPAD from IN)>>
+
+<<mkfunc.spad (SPAD from IN)>>
+<<mkfunc.spad.dvi (DOC from IN)>>
+
+<<MKRECORD.o (O from NRLIB)>>
+<<MKRECORD.NRLIB (NRLIB from MID)>>
+<<MKRECORD.spad (SPAD from IN)>>
+
+<<mkrecord.spad (SPAD from IN)>>
+<<mkrecord.spad.dvi (DOC from IN)>>
+
+<<mlift.spad.jhd.dvi (DOC from IN)>>
+
+<<MLIFT.o (O from NRLIB)>>
+<<MLIFT.NRLIB (NRLIB from MID)>>
+<<MLIFT.spad (SPAD from IN)>>
+
+<<mlift.spad (SPAD from IN)>>
+<<mlift.spad.dvi (DOC from IN)>>
+
+<<MDDFACT.o (O from NRLIB)>>
+<<MDDFACT.NRLIB (NRLIB from MID)>>
+<<MDDFACT.spad (SPAD from IN)>>
+
+<<moddfact.spad (SPAD from IN)>>
+<<moddfact.spad.dvi (DOC from IN)>>
+
+<<INMODGCD.o (O from NRLIB)>>
+<<INMODGCD.NRLIB (NRLIB from MID)>>
+<<INMODGCD.spad (SPAD from IN)>>
+
+<<modgcd.spad (SPAD from IN)>>
+<<modgcd.spad.dvi (DOC from IN)>>
+
+<<GMODPOL.o (O from NRLIB)>>
+<<GMODPOL.NRLIB (NRLIB from MID)>>
+<<GMODPOL.spad (SPAD from IN)>>
+
+<<MODMONOM.o (O from NRLIB)>>
+<<MODMONOM.NRLIB (NRLIB from MID)>>
+<<MODMONOM.spad (SPAD from IN)>>
+
+<<modmonom.spad (SPAD from IN)>>
+<<modmonom.spad.dvi (DOC from IN)>>
+
+<<MODMON.o (O from NRLIB)>>
+<<MODMON.NRLIB (NRLIB from MID)>>
+<<MODMON.spad (SPAD from IN)>>
+
+<<modmon.spad (SPAD from IN)>>
+<<modmon.spad.dvi (DOC from IN)>>
+
+<<EMR.o (O from NRLIB)>>
+<<EMR.NRLIB (NRLIB from MID)>>
+<<EMR.spad (SPAD from IN)>>
+
+<<MODFIELD.o (O from NRLIB)>>
+<<MODFIELD.NRLIB (NRLIB from MID)>>
+<<MODFIELD.spad (SPAD from IN)>>
+
+<<MODRING.o (O from NRLIB)>>
+<<MODRING.NRLIB (NRLIB from MID)>>
+<<MODRING.spad (SPAD from IN)>>
+
+<<modring.spad (SPAD from IN)>>
+<<modring.spad.dvi (DOC from IN)>>
+
+<<MOEBIUS.o (O from NRLIB)>>
+<<MOEBIUS.NRLIB (NRLIB from MID)>>
+<<MOEBIUS.spad (SPAD from IN)>>
+
+<<moebius.spad (SPAD from IN)>>
+<<moebius.spad.dvi (DOC from IN)>>
+
+<<MRF2.o (O from NRLIB)>>
+<<MRF2.NRLIB (NRLIB from MID)>>
+<<MRF2.spad (SPAD from IN)>>
+
+<<MRING.o (O from NRLIB)>>
+<<MRING.NRLIB (NRLIB from MID)>>
+<<MRING.spad (SPAD from IN)>>
+
+<<mring.spad (SPAD from IN)>>
+<<mring.spad.dvi (DOC from IN)>>
+
+<<MSET.o (O from NRLIB)>>
+<<MSET.NRLIB (NRLIB from MID)>>
+<<MSET.spad (SPAD from IN)>>
+
+<<mset.spad (SPAD from IN)>>
+<<mset.spad.dvi (DOC from IN)>>
+
+<<SMTS.o (O from NRLIB)>>
+<<SMTS.NRLIB (NRLIB from MID)>>
+<<SMTS.spad (SPAD from IN)>>
+
+<<TS.o (O from NRLIB)>>
+<<TS.NRLIB (NRLIB from MID)>>
+<<TS.spad (SPAD from IN)>>
+
+<<mts.spad (SPAD from IN)>>
+<<mts.spad.dvi (DOC from IN)>>
+
+<<ALGMFACT.o (O from NRLIB)>>
+<<ALGMFACT.NRLIB (NRLIB from MID)>>
+<<ALGMFACT.spad (SPAD from IN)>>
+
+<<INNMFACT.o (O from NRLIB)>>
+<<INNMFACT.NRLIB (NRLIB from MID)>>
+<<INNMFACT.spad (SPAD from IN)>>
+
+<<MULTFACT.o (O from NRLIB)>>
+<<MULTFACT.NRLIB (NRLIB from MID)>>
+<<MULTFACT.spad (SPAD from IN)>>
+
+<<multfact.spad (SPAD from IN)>>
+<<multfact.spad.dvi (DOC from IN)>>
+
+<<INDE.o (O from NRLIB)>>
+<<INDE.NRLIB (NRLIB from MID)>>
+<<INDE.spad (SPAD from IN)>>
+
+<<MPOLY.o (O from NRLIB)>>
+<<MPOLY.NRLIB (NRLIB from MID)>>
+<<MPOLY.spad (SPAD from IN)>>
+
+<<POLY.o (O from NRLIB)>>
+<<POLY.NRLIB (NRLIB from MID)>>
+<<POLY.spad (SPAD from IN)>>
+
+<<POLY2.o (O from NRLIB)>>
+<<POLY2.NRLIB (NRLIB from MID)>>
+<<POLY2.spad (SPAD from IN)>>
+
+<<SMP.o (O from NRLIB)>>
+<<SMP.NRLIB (NRLIB from MID)>>
+<<SMP.spad (SPAD from IN)>>
+
+<<multpoly.spad (SPAD from IN)>>
+<<multpoly.spad.dvi (DOC from IN)>>
+
+<<MULTSQFR.o (O from NRLIB)>>
+<<MULTSQFR.NRLIB (NRLIB from MID)>>
+<<MULTSQFR.spad (SPAD from IN)>>
+
+<<multsqfr.spad (SPAD from IN)>>
+<<multsqfr.spad.dvi (DOC from IN)>>
+
+<<FINAALG-.o (O from NRLIB)>>
+<<FINAALG-.NRLIB (NRLIB from MID)>>
+<<FINAALG.o (O from NRLIB)>>
+<<FINAALG.NRLIB (NRLIB from MID)>>
+<<FINAALG.spad (SPAD from IN)>>
+
+<<FRNAALG-.o (O from NRLIB)>>
+<<FRNAALG-.NRLIB (NRLIB from MID)>>
+<<FRNAALG.o (O from NRLIB)>>
+<<FRNAALG.NRLIB (NRLIB from MID)>>
+<<FRNAALG.spad (SPAD from IN)>>
+
+<<MONAD-.o (O from NRLIB)>>
+<<MONAD-.NRLIB (NRLIB from MID)>>
+<<MONAD.o (O from NRLIB)>>
+<<MONAD.NRLIB (NRLIB from MID)>>
+<<MONAD.spad (SPAD from IN)>>
+
+<<MONADWU-.o (O from NRLIB)>>
+<<MONADWU-.NRLIB (NRLIB from MID)>>
+<<MONADWU.o (O from NRLIB)>>
+<<MONADWU.NRLIB (NRLIB from MID)>>
+<<MONADWU.spad (SPAD from IN)>>
+
+<<NAALG-.o (O from NRLIB)>>
+<<NAALG-.NRLIB (NRLIB from MID)>>
+<<NAALG.o (O from NRLIB)>>
+<<NAALG.NRLIB (NRLIB from MID)>>
+<<NAALG.spad (SPAD from IN)>>
+
+<<NARNG-.o (O from NRLIB)>>
+<<NARNG-.NRLIB (NRLIB from MID)>>
+<<NARNG.o (O from NRLIB)>>
+<<NARNG.NRLIB (NRLIB from MID)>>
+<<NARNG.spad (SPAD from IN)>>
+
+<<NASRING-.o (O from NRLIB)>>
+<<NASRING-.NRLIB (NRLIB from MID)>>
+<<NASRING.o (O from NRLIB)>>
+<<NASRING.NRLIB (NRLIB from MID)>>
+<<NASRING.spad (SPAD from IN)>>
+
+<<naalgc.spad (SPAD from IN)>>
+<<naalgc.spad.dvi (DOC from IN)>>
+
+<<ALGPKG.o (O from NRLIB)>>
+<<ALGPKG.NRLIB (NRLIB from MID)>>
+<<ALGPKG.spad (SPAD from IN)>>
+
+<<ALGSC.o (O from NRLIB)>>
+<<ALGSC.NRLIB (NRLIB from MID)>>
+<<ALGSC.spad (SPAD from IN)>>
+
+<<FRNAAF2.o (O from NRLIB)>>
+<<FRNAAF2.NRLIB (NRLIB from MID)>>
+<<FRNAAF2.spad (SPAD from IN)>>
+
+<<SCPKG.o (O from NRLIB)>>
+<<SCPKG.NRLIB (NRLIB from MID)>>
+<<SCPKG.spad (SPAD from IN)>>
+
+<<naalg.spad (SPAD from IN)>>
+<<naalg.spad.dvi (DOC from IN)>>
+
+<<ndftip.as (SPAD from IN)>>
+<<ndftip.as.dvi (DOC from IN)>>
+
+<<nepip.as (SPAD from IN)>>
+<<nepip.as.dvi (DOC from IN)>>
+
+<<IPRNTPK.o (O from NRLIB)>>
+<<IPRNTPK.NRLIB (NRLIB from MID)>>
+<<IPRNTPK.spad (SPAD from IN)>>
+
+<<SPLNODE.o (O from NRLIB)>>
+<<SPLNODE.NRLIB (NRLIB from MID)>>
+<<SPLNODE.spad (SPAD from IN)>>
+
+<<SPLTREE.o (O from NRLIB)>>
+<<SPLTREE.NRLIB (NRLIB from MID)>>
+<<SPLTREE.spad (SPAD from IN)>>
+
+<<TBCMPPK.o (O from NRLIB)>>
+<<TBCMPPK.NRLIB (NRLIB from MID)>>
+<<TBCMPPK.spad (SPAD from IN)>>
+
+<<newdata.spad (SPAD from IN)>>
+<<newdata.spad.dvi (DOC from IN)>>
+
+<<COMPPROP.o (O from NRLIB)>>
+<<COMPPROP.NRLIB (NRLIB from MID)>>
+<<COMPPROP.spad (SPAD from IN)>>
+
+<<SUBSPACE.o (O from NRLIB)>>
+<<SUBSPACE.NRLIB (NRLIB from MID)>>
+<<SUBSPACE.spad (SPAD from IN)>>
+
+<<POINT.o (O from NRLIB)>>
+<<POINT.NRLIB (NRLIB from MID)>>
+<<POINT.spad (SPAD from IN)>>
+
+<<PTCAT.o (O from NRLIB)>>
+<<PTCAT.NRLIB (NRLIB from MID)>>
+<<PTCAT.spad (SPAD from IN)>>
+
+<<PTFUNC2.o (O from NRLIB)>>
+<<PTFUNC2.NRLIB (NRLIB from MID)>>
+<<PTFUNC2.spad (SPAD from IN)>>
+
+<<PTPACK.o (O from NRLIB)>>
+<<PTPACK.NRLIB (NRLIB from MID)>>
+<<PTPACK.spad (SPAD from IN)>>
+
+<<newpoint.spad (SPAD from IN)>>
+<<newpoint.spad.dvi (DOC from IN)>>
+
+<<NSMP.o (O from NRLIB)>>
+<<NSMP.NRLIB (NRLIB from MID)>>
+<<NSMP.spad (SPAD from IN)>>
+
+<<NSUP.o (O from NRLIB)>>
+<<NSUP.NRLIB (NRLIB from MID)>>
+<<NSUP.spad (SPAD from IN)>>
+
+<<NSUP2.o (O from NRLIB)>>
+<<NSUP2.NRLIB (NRLIB from MID)>>
+<<NSUP2.spad (SPAD from IN)>>
+
+<<RPOLCAT-.o (O from NRLIB)>>
+<<RPOLCAT-.NRLIB (NRLIB from MID)>>
+<<RPOLCAT.o (O from NRLIB)>>
+<<RPOLCAT.NRLIB (NRLIB from MID)>>
+<<RPOLCAT.spad (SPAD from IN)>>
+
+<<newpoly.spad (SPAD from IN)>>
+<<newpoly.spad.dvi (DOC from IN)>>
+
+<<NLINSOL.o (O from NRLIB)>>
+<<NLINSOL.NRLIB (NRLIB from MID)>>
+<<NLINSOL.spad (SPAD from IN)>>
+
+<<RETSOL.o (O from NRLIB)>>
+<<RETSOL.NRLIB (NRLIB from MID)>>
+<<RETSOL.spad (SPAD from IN)>>
+
+<<nlinsol.spad (SPAD from IN)>>
+<<nlinsol.spad.dvi (DOC from IN)>>
+
+<<NODE1.o (O from NRLIB)>>
+<<NODE1.NRLIB (NRLIB from MID)>>
+<<NODE1.spad (SPAD from IN)>>
+
+<<nlode.spad (SPAD from IN)>>
+<<nlode.spad.dvi (DOC from IN)>>
+
+<<noptip.as (SPAD from IN)>>
+<<noptip.as.dvi (DOC from IN)>>
+
+<<NPCOEF.o (O from NRLIB)>>
+<<NPCOEF.NRLIB (NRLIB from MID)>>
+<<NPCOEF.spad (SPAD from IN)>>
+
+<<npcoef.spad (SPAD from IN)>>
+<<npcoef.spad.dvi (DOC from IN)>>
+
+<<nqip.as (SPAD from IN)>>
+<<nqip.as.dvi (DOC from IN)>>
+
+<<nrc.as (SPAD from IN)>>
+<<nrc.as.dvi (DOC from IN)>>
+
+<<nregset.spad (SPAD from IN)>>
+<<nregset.spad.dvi (DOC from IN)>>
+
+<<nsfip.as (SPAD from IN)>>
+<<nsfip.as.dvi (DOC from IN)>>
+
+<<nsregset.spad (SPAD from IN)>>
+<<nsregset.spad.dvi (DOC from IN)>>
+
+<<INEP.o (O from NRLIB)>>
+<<INEP.NRLIB (NRLIB from MID)>>
+<<INEP.spad (SPAD from IN)>>
+
+<<NCEP.o (O from NRLIB)>>
+<<NCEP.NRLIB (NRLIB from MID)>>
+<<NCEP.spad (SPAD from IN)>>
+
+<<NREP.o (O from NRLIB)>>
+<<NREP.NRLIB (NRLIB from MID)>>
+<<NREP.spad (SPAD from IN)>>
+
+<<numeigen.spad (SPAD from IN)>>
+<<numeigen.spad.dvi (DOC from IN)>>
+
+<<DRAWHACK.o (O from NRLIB)>>
+<<DRAWHACK.NRLIB (NRLIB from MID)>>
+<<DRAWHACK.spad (SPAD from IN)>>
+
+<<NUMERIC.o (O from NRLIB)>>
+<<NUMERIC.NRLIB (NRLIB from MID)>>
+<<NUMERIC.spad (SPAD from IN)>>
+
+<<numeric.spad (SPAD from IN)>>
+<<numeric.spad.dvi (DOC from IN)>>
+
+<<NUMODE.o (O from NRLIB)>>
+<<NUMODE.NRLIB (NRLIB from MID)>>
+<<NUMODE.spad (SPAD from IN)>>
+
+<<numode.spad (SPAD from IN)>>
+<<numode.spad.dvi (DOC from IN)>>
+
+<<NUMQUAD.o (O from NRLIB)>>
+<<NUMQUAD.NRLIB (NRLIB from MID)>>
+<<NUMQUAD.spad (SPAD from IN)>>
+
+<<numquad.spad (SPAD from IN)>>
+<<numquad.spad.dvi (DOC from IN)>>
+
+<<FLOATCP.o (O from NRLIB)>>
+<<FLOATCP.NRLIB (NRLIB from MID)>>
+<<FLOATCP.spad (SPAD from IN)>>
+
+<<FLOATRP.o (O from NRLIB)>>
+<<FLOATRP.NRLIB (NRLIB from MID)>>
+<<FLOATRP.spad (SPAD from IN)>>
+
+<<INFSP.o (O from NRLIB)>>
+<<INFSP.NRLIB (NRLIB from MID)>>
+<<INFSP.spad (SPAD from IN)>>
+
+<<numsolve.spad (SPAD from IN)>>
+<<numsolve.spad.dvi (DOC from IN)>>
+
+<<INTHEORY.o (O from NRLIB)>>
+<<INTHEORY.NRLIB (NRLIB from MID)>>
+<<INTHEORY.spad (SPAD from IN)>>
+
+<<PNTHEORY.o (O from NRLIB)>>
+<<PNTHEORY.NRLIB (NRLIB from MID)>>
+<<PNTHEORY.spad (SPAD from IN)>>
+
+<<numtheor.spad (SPAD from IN)>>
+<<numtheor.spad.dvi (DOC from IN)>>
+
+<<OC-.o (O from NRLIB)>>
+<<OC-.NRLIB (NRLIB from MID)>>
+<<OC.o (O from NRLIB)>>
+<<OC.NRLIB (NRLIB from MID)>>
+<<OC.spad (SPAD from IN)>>
+
+<<OCT.o (O from NRLIB)>>
+<<OCT.NRLIB (NRLIB from MID)>>
+<<OCT.spad (SPAD from IN)>>
+
+<<OCTCT2.o (O from NRLIB)>>
+<<OCTCT2.NRLIB (NRLIB from MID)>>
+<<OCTCT2.spad (SPAD from IN)>>
+
+<<oct.spad (SPAD from IN)>>
+<<oct.spad.dvi (DOC from IN)>>
+
+<<ODEPAL.o (O from NRLIB)>>
+<<ODEPAL.NRLIB (NRLIB from MID)>>
+<<ODEPAL.spad (SPAD from IN)>>
+
+<<ODERED.o (O from NRLIB)>>
+<<ODERED.NRLIB (NRLIB from MID)>>
+<<ODERED.spad (SPAD from IN)>>
+
+<<ODESYS.o (O from NRLIB)>>
+<<ODESYS.NRLIB (NRLIB from MID)>>
+<<ODESYS.spad (SPAD from IN)>>
+
+<<odealg.spad (SPAD from IN)>>
+<<odealg.spad.dvi (DOC from IN)>>
+
+<<LODEEF.o (O from NRLIB)>>
+<<LODEEF.NRLIB (NRLIB from MID)>>
+<<LODEEF.spad (SPAD from IN)>>
+
+<<REDORDER.o (O from NRLIB)>>
+<<REDORDER.NRLIB (NRLIB from MID)>>
+<<REDORDER.spad (SPAD from IN)>>
+
+<<odeef.spad (SPAD from IN)>>
+<<odeef.spad.dvi (DOC from IN)>>
+
+<<BALFACT.o (O from NRLIB)>>
+<<BALFACT.NRLIB (NRLIB from MID)>>
+<<BALFACT.spad (SPAD from IN)>>
+
+<<BOUNDZRO.o (O from NRLIB)>>
+<<BOUNDZRO.NRLIB (NRLIB from MID)>>
+<<BOUNDZRO.spad (SPAD from IN)>>
+
+<<ODECONST.o (O from NRLIB)>>
+<<ODECONST.NRLIB (NRLIB from MID)>>
+<<ODECONST.spad (SPAD from IN)>>
+
+<<ODEINT.o (O from NRLIB)>>
+<<ODEINT.NRLIB (NRLIB from MID)>>
+<<ODEINT.spad (SPAD from IN)>>
+
+<<ODEPRIM.o (O from NRLIB)>>
+<<ODEPRIM.NRLIB (NRLIB from MID)>>
+<<ODEPRIM.spad (SPAD from IN)>>
+
+<<ODERAT.o (O from NRLIB)>>
+<<ODERAT.NRLIB (NRLIB from MID)>>
+<<ODERAT.spad (SPAD from IN)>>
+
+<<ODETOOLS.o (O from NRLIB)>>
+<<ODETOOLS.NRLIB (NRLIB from MID)>>
+<<ODETOOLS.spad (SPAD from IN)>>
+
+<<UTSODETL.o (O from NRLIB)>>
+<<UTSODETL.NRLIB (NRLIB from MID)>>
+<<UTSODETL.spad (SPAD from IN)>>
+
+<<oderf.spad (SPAD from IN)>>
+<<oderf.spad.dvi (DOC from IN)>>
+
+<<OM.o (O from NRLIB)>>
+<<OM.NRLIB (NRLIB from MID)>>
+<<OM.spad (SPAD from IN)>>
+
+<<omcat.spad (SPAD from IN)>>
+<<omcat.spad.dvi (DOC from IN)>>
+
+<<OMCONN.o (O from NRLIB)>>
+<<OMCONN.NRLIB (NRLIB from MID)>>
+<<OMCONN.spad (SPAD from IN)>>
+
+<<OMDEV.o (O from NRLIB)>>
+<<OMDEV.NRLIB (NRLIB from MID)>>
+<<OMDEV.spad (SPAD from IN)>>
+
+<<OMENC.o (O from NRLIB)>>
+<<OMENC.NRLIB (NRLIB from MID)>>
+<<OMENC.spad (SPAD from IN)>>
+
+<<OMPKG.o (O from NRLIB)>>
+<<OMPKG.NRLIB (NRLIB from MID)>>
+<<OMPKG.spad (SPAD from IN)>>
+
+<<omdev.spad (SPAD from IN)>>
+<<omdev.spad.dvi (DOC from IN)>>
+
+<<OMERR.o (O from NRLIB)>>
+<<OMERR.NRLIB (NRLIB from MID)>>
+<<OMERR.spad (SPAD from IN)>>
+
+<<OMERRK.o (O from NRLIB)>>
+<<OMERRK.NRLIB (NRLIB from MID)>>
+<<OMERRK.spad (SPAD from IN)>>
+
+<<omerror.spad (SPAD from IN)>>
+<<omerror.spad.dvi (DOC from IN)>>
+
+<<OMSERVER.o (O from NRLIB)>>
+<<OMSERVER.NRLIB (NRLIB from MID)>>
+<<OMSERVER.spad (SPAD from IN)>>
+
+<<omserver.spad (SPAD from IN)>>
+<<omserver.spad.dvi (DOC from IN)>>
+
+<<MODOP.o (O from NRLIB)>>
+<<MODOP.NRLIB (NRLIB from MID)>>
+<<MODOP.spad (SPAD from IN)>>
+
+<<OP.o (O from NRLIB)>>
+<<OP.NRLIB (NRLIB from MID)>>
+<<OP.spad (SPAD from IN)>>
+
+<<opalg.spad (SPAD from IN)>>
+<<opalg.spad.dvi (DOC from IN)>>
+
+<<OMEXPR.o (O from NRLIB)>>
+<<OMEXPR.NRLIB (NRLIB from MID)>>
+<<OMEXPR.spad (SPAD from IN)>>
+
+<<openmath.spad (SPAD from IN)>>
+<<openmath.spad.dvi (DOC from IN)>>
+
+<<BOP.o (O from NRLIB)>>
+<<BOP.NRLIB (NRLIB from MID)>>
+<<BOP.spad (SPAD from IN)>>
+
+<<BOP1.o (O from NRLIB)>>
+<<BOP1.NRLIB (NRLIB from MID)>>
+<<BOP1.spad (SPAD from IN)>>
+
+<<COMMONOP.o (O from NRLIB)>>
+<<COMMONOP.NRLIB (NRLIB from MID)>>
+<<COMMONOP.spad (SPAD from IN)>>
+
+<<op.spad (SPAD from IN)>>
+<<op.spad.dvi (DOC from IN)>>
+
+<<APPLYORE.o (O from NRLIB)>>
+<<APPLYORE.NRLIB (NRLIB from MID)>>
+<<APPLYORE.spad (SPAD from IN)>>
+
+<<AUTOMOR.o (O from NRLIB)>>
+<<AUTOMOR.NRLIB (NRLIB from MID)>>
+<<AUTOMOR.spad (SPAD from IN)>>
+
+<<OREPCAT-.o (O from NRLIB)>>
+<<OREPCAT-.NRLIB (NRLIB from MID)>>
+<<OREPCAT.o (O from NRLIB)>>
+<<OREPCAT.NRLIB (NRLIB from MID)>>
+<<OREPCAT.spad (SPAD from IN)>>
+
+<<OREPCTO.o (O from NRLIB)>>
+<<OREPCTO.NRLIB (NRLIB from MID)>>
+<<OREPCTO.spad (SPAD from IN)>>
+
+<<ORESUP.o (O from NRLIB)>>
+<<ORESUP.NRLIB (NRLIB from MID)>>
+<<ORESUP.spad (SPAD from IN)>>
+
+<<OREUP.o (O from NRLIB)>>
+<<OREUP.NRLIB (NRLIB from MID)>>
+<<OREUP.spad (SPAD from IN)>>
+
+<<ore.spad (SPAD from IN)>>
+<<ore.spad.dvi (DOC from IN)>>
+
+<<NUMFMT.o (O from NRLIB)>>
+<<NUMFMT.NRLIB (NRLIB from MID)>>
+<<NUMFMT.spad (SPAD from IN)>>
+
+<<OUTFORM.o (O from NRLIB)>>
+<<OUTFORM.NRLIB (NRLIB from MID)>>
+<<OUTFORM.spad (SPAD from IN)>>
+<<OUTFORM.o (BOOTSTRAP from MID)>>
+<<OUTFORM.lsp (LISP from IN)>>
+
+<<outform.spad (SPAD from IN)>>
+<<outform.spad.dvi (DOC from IN)>>
+
+<<DISPLAY.o (O from NRLIB)>>
+<<DISPLAY.NRLIB (NRLIB from MID)>>
+<<DISPLAY.spad (SPAD from IN)>>
+
+<<OUT.o (O from NRLIB)>>
+<<OUT.NRLIB (NRLIB from MID)>>
+<<OUT.spad (SPAD from IN)>>
+
+<<SPECOUT.o (O from NRLIB)>>
+<<SPECOUT.NRLIB (NRLIB from MID)>>
+<<SPECOUT.spad (SPAD from IN)>>
+
+<<out.spad (SPAD from IN)>>
+<<out.spad.dvi (DOC from IN)>>
+
+<<PADE.o (O from NRLIB)>>
+<<PADE.NRLIB (NRLIB from MID)>>
+<<PADE.spad (SPAD from IN)>>
+
+<<PADEPAC.o (O from NRLIB)>>
+<<PADEPAC.NRLIB (NRLIB from MID)>>
+<<PADEPAC.spad (SPAD from IN)>>
+
+<<pade.spad (SPAD from IN)>>
+<<pade.spad.dvi (DOC from IN)>>
+
+<<IBACHIN.o (O from NRLIB)>>
+<<IBACHIN.NRLIB (NRLIB from MID)>>
+<<IBACHIN.spad (SPAD from IN)>>
+
+<<IBPTOOLS.o (O from NRLIB)>>
+<<IBPTOOLS.NRLIB (NRLIB from MID)>>
+<<IBPTOOLS.spad (SPAD from IN)>>
+
+<<PWFFINTB.o (O from NRLIB)>>
+<<PWFFINTB.NRLIB (NRLIB from MID)>>
+<<PWFFINTB.spad (SPAD from IN)>>
+
+<<padiclib.spad (SPAD from IN)>>
+<<padiclib.spad.dvi (DOC from IN)>>
+
+<<BPADIC.o (O from NRLIB)>>
+<<BPADIC.NRLIB (NRLIB from MID)>>
+<<BPADIC.spad (SPAD from IN)>>
+
+<<BPADICRT.o (O from NRLIB)>>
+<<BPADICRT.NRLIB (NRLIB from MID)>>
+<<BPADICRT.spad (SPAD from IN)>>
+
+<<IPADIC.o (O from NRLIB)>>
+<<IPADIC.NRLIB (NRLIB from MID)>>
+<<IPADIC.spad (SPAD from IN)>>
+
+<<PADIC.o (O from NRLIB)>>
+<<PADIC.NRLIB (NRLIB from MID)>>
+<<PADIC.spad (SPAD from IN)>>
+
+<<PADICCT.o (O from NRLIB)>>
+<<PADICCT.NRLIB (NRLIB from MID)>>
+<<PADICCT.spad (SPAD from IN)>>
+
+<<PADICRAT.o (O from NRLIB)>>
+<<PADICRAT.NRLIB (NRLIB from MID)>>
+<<PADICRAT.spad (SPAD from IN)>>
+
+<<PADICRC.o (O from NRLIB)>>
+<<PADICRC.NRLIB (NRLIB from MID)>>
+<<PADICRC.spad (SPAD from IN)>>
+
+<<padic.spad (SPAD from IN)>>
+<<padic.spad.dvi (DOC from IN)>>
+
+<<PARPCURV.o (O from NRLIB)>>
+<<PARPCURV.NRLIB (NRLIB from MID)>>
+<<PARPCURV.spad (SPAD from IN)>>
+
+<<PARPC2.o (O from NRLIB)>>
+<<PARPC2.NRLIB (NRLIB from MID)>>
+<<PARPC2.spad (SPAD from IN)>>
+
+<<PARSCURV.o (O from NRLIB)>>
+<<PARSCURV.NRLIB (NRLIB from MID)>>
+<<PARSCURV.spad (SPAD from IN)>>
+
+<<PARSC2.o (O from NRLIB)>>
+<<PARSC2.NRLIB (NRLIB from MID)>>
+<<PARSC2.spad (SPAD from IN)>>
+
+<<PARSURF.o (O from NRLIB)>>
+<<PARSURF.NRLIB (NRLIB from MID)>>
+<<PARSURF.spad (SPAD from IN)>>
+
+<<PARSU2.o (O from NRLIB)>>
+<<PARSU2.NRLIB (NRLIB from MID)>>
+<<PARSU2.spad (SPAD from IN)>>
+
+<<paramete.spad (SPAD from IN)>>
+<<paramete.spad.dvi (DOC from IN)>>
+
+<<PARTPERM.o (O from NRLIB)>>
+<<PARTPERM.NRLIB (NRLIB from MID)>>
+<<PARTPERM.spad (SPAD from IN)>>
+
+<<partperm.spad (SPAD from IN)>>
+<<partperm.spad.dvi (DOC from IN)>>
+
+<<FPATMAB.o (O from NRLIB)>>
+<<FPATMAB.NRLIB (NRLIB from MID)>>
+<<FPATMAB.spad (SPAD from IN)>>
+
+<<PATLRES.o (O from NRLIB)>>
+<<PATLRES.NRLIB (NRLIB from MID)>>
+<<PATLRES.spad (SPAD from IN)>>
+
+<<PATMAB.o (O from NRLIB)>>
+<<PATMAB.NRLIB (NRLIB from MID)>>
+<<PATMAB.spad (SPAD from IN)>>
+
+<<PATRES.o (O from NRLIB)>>
+<<PATRES.NRLIB (NRLIB from MID)>>
+<<PATRES.spad (SPAD from IN)>>
+
+<<PATRES2.o (O from NRLIB)>>
+<<PATRES2.NRLIB (NRLIB from MID)>>
+<<PATRES2.spad (SPAD from IN)>>
+
+<<PMDOWN.o (O from NRLIB)>>
+<<PMDOWN.NRLIB (NRLIB from MID)>>
+<<PMDOWN.spad (SPAD from IN)>>
+
+<<PMKERNEL.o (O from NRLIB)>>
+<<PMKERNEL.NRLIB (NRLIB from MID)>>
+<<PMKERNEL.spad (SPAD from IN)>>
+
+<<PMLSAGG.o (O from NRLIB)>>
+<<PMLSAGG.NRLIB (NRLIB from MID)>>
+<<PMLSAGG.spad (SPAD from IN)>>
+
+<<PMSYM.o (O from NRLIB)>>
+<<PMSYM.NRLIB (NRLIB from MID)>>
+<<PMSYM.spad (SPAD from IN)>>
+
+<<PMTOOLS.o (O from NRLIB)>>
+<<PMTOOLS.NRLIB (NRLIB from MID)>>
+<<PMTOOLS.spad (SPAD from IN)>>
+
+<<patmatch1.spad (SPAD from IN)>>
+<<patmatch1.spad.dvi (DOC from IN)>>
+
+<<PATMATCH.o (O from NRLIB)>>
+<<PATMATCH.NRLIB (NRLIB from MID)>>
+<<PATMATCH.spad (SPAD from IN)>>
+
+<<PMFS.o (O from NRLIB)>>
+<<PMFS.NRLIB (NRLIB from MID)>>
+<<PMFS.spad (SPAD from IN)>>
+
+<<PMINS.o (O from NRLIB)>>
+<<PMINS.NRLIB (NRLIB from MID)>>
+<<PMINS.spad (SPAD from IN)>>
+
+<<PMPLCAT.o (O from NRLIB)>>
+<<PMPLCAT.NRLIB (NRLIB from MID)>>
+<<PMPLCAT.spad (SPAD from IN)>>
+
+<<PMQFCAT.o (O from NRLIB)>>
+<<PMQFCAT.NRLIB (NRLIB from MID)>>
+<<PMQFCAT.spad (SPAD from IN)>>
+
+<<patmatch2.spad (SPAD from IN)>>
+<<patmatch2.spad.dvi (DOC from IN)>>
+
+<<PATAB.o (O from NRLIB)>>
+<<PATAB.NRLIB (NRLIB from MID)>>
+<<PATAB.spad (SPAD from IN)>>
+
+<<PATTERN.o (O from NRLIB)>>
+<<PATTERN.NRLIB (NRLIB from MID)>>
+<<PATTERN.spad (SPAD from IN)>>
+
+<<PATTERN1.o (O from NRLIB)>>
+<<PATTERN1.NRLIB (NRLIB from MID)>>
+<<PATTERN1.spad (SPAD from IN)>>
+
+<<PATTERN2.o (O from NRLIB)>>
+<<PATTERN2.NRLIB (NRLIB from MID)>>
+<<PATTERN2.spad (SPAD from IN)>>
+
+<<pattern.spad (SPAD from IN)>>
+<<pattern.spad.dvi (DOC from IN)>>
+
+<<PPCURVE.o (O from NRLIB)>>
+<<PPCURVE.NRLIB (NRLIB from MID)>>
+<<PPCURVE.spad (SPAD from IN)>>
+
+<<PSCURVE.o (O from NRLIB)>>
+<<PSCURVE.NRLIB (NRLIB from MID)>>
+<<PSCURVE.spad (SPAD from IN)>>
+
+<<pcurve.spad (SPAD from IN)>>
+<<pcurve.spad.dvi (DOC from IN)>>
+
+<<PCOMP.o (O from NRLIB)>>
+<<PCOMP.NRLIB (NRLIB from MID)>>
+<<PCOMP.spad (SPAD from IN)>>
+
+<<PDECOMP.o (O from NRLIB)>>
+<<PDECOMP.NRLIB (NRLIB from MID)>>
+<<PDECOMP.spad (SPAD from IN)>>
+
+<<pdecomp.spad (SPAD from IN)>>
+<<pdecomp.spad.dvi (DOC from IN)>>
+
+<<GRAY.o (O from NRLIB)>>
+<<GRAY.NRLIB (NRLIB from MID)>>
+<<GRAY.spad (SPAD from IN)>>
+
+<<PERMAN.o (O from NRLIB)>>
+<<PERMAN.NRLIB (NRLIB from MID)>>
+<<PERMAN.spad (SPAD from IN)>>
+
+<<perman.spad (SPAD from IN)>>
+<<perman.spad.dvi (DOC from IN)>>
+
+<<PERMGRP.o (O from NRLIB)>>
+<<PERMGRP.NRLIB (NRLIB from MID)>>
+<<PERMGRP.spad (SPAD from IN)>>
+
+<<PGE.o (O from NRLIB)>>
+<<PGE.NRLIB (NRLIB from MID)>>
+<<PGE.spad (SPAD from IN)>>
+
+<<permgrps.spad (SPAD from IN)>>
+<<permgrps.spad.dvi (DOC from IN)>>
+
+<<PERM.o (O from NRLIB)>>
+<<PERM.NRLIB (NRLIB from MID)>>
+<<PERM.spad (SPAD from IN)>>
+
+<<PERMCAT.o (O from NRLIB)>>
+<<PERMCAT.NRLIB (NRLIB from MID)>>
+<<PERMCAT.spad (SPAD from IN)>>
+
+<<perm.spad (SPAD from IN)>>
+<<perm.spad.dvi (DOC from IN)>>
+
+<<PFBR.o (O from NRLIB)>>
+<<PFBR.NRLIB (NRLIB from MID)>>
+<<PFBR.spad (SPAD from IN)>>
+
+<<PFBRU.o (O from NRLIB)>>
+<<PFBRU.NRLIB (NRLIB from MID)>>
+<<PFBRU.spad (SPAD from IN)>>
+
+<<pfbr.spad (SPAD from IN)>>
+<<pfbr.spad.dvi (DOC from IN)>>
+
+<<FORDER.o (O from NRLIB)>>
+<<FORDER.NRLIB (NRLIB from MID)>>
+<<FORDER.spad (SPAD from IN)>>
+
+<<FSRED.o (O from NRLIB)>>
+<<FSRED.NRLIB (NRLIB from MID)>>
+<<FSRED.spad (SPAD from IN)>>
+
+<<PFO.o (O from NRLIB)>>
+<<PFO.NRLIB (NRLIB from MID)>>
+<<PFO.spad (SPAD from IN)>>
+
+<<PFOQ.o (O from NRLIB)>>
+<<PFOQ.NRLIB (NRLIB from MID)>>
+<<PFOQ.spad (SPAD from IN)>>
+
+<<PFOTOOLS.o (O from NRLIB)>>
+<<PFOTOOLS.NRLIB (NRLIB from MID)>>
+<<PFOTOOLS.spad (SPAD from IN)>>
+
+<<RDIV.o (O from NRLIB)>>
+<<RDIV.NRLIB (NRLIB from MID)>>
+<<RDIV.spad (SPAD from IN)>>
+
+<<pfo.spad (SPAD from IN)>>
+<<pfo.spad.dvi (DOC from IN)>>
+
+<<PFR.o (O from NRLIB)>>
+<<PFR.NRLIB (NRLIB from MID)>>
+<<PFR.spad (SPAD from IN)>>
+
+<<PFRPAC.o (O from NRLIB)>>
+<<PFRPAC.NRLIB (NRLIB from MID)>>
+<<PFRPAC.spad (SPAD from IN)>>
+
+<<pfr.spad (SPAD from IN)>>
+<<pfr.spad.dvi (DOC from IN)>>
+
+<<IPF.o (O from NRLIB)>>
+<<IPF.NRLIB (NRLIB from MID)>>
+<<IPF.spad (SPAD from IN)>>
+
+<<PF.o (O from NRLIB)>>
+<<PF.NRLIB (NRLIB from MID)>>
+<<PF.spad (SPAD from IN)>>
+
+<<pf.spad (SPAD from IN)>>
+<<pf.spad.dvi (DOC from IN)>>
+
+<<PGCD.o (O from NRLIB)>>
+<<PGCD.NRLIB (NRLIB from MID)>>
+<<PGCD.spad (SPAD from IN)>>
+
+<<pgcd.spad (SPAD from IN)>>
+<<pgcd.spad.dvi (DOC from IN)>>
+
+<<PGROEB.o (O from NRLIB)>>
+<<PGROEB.NRLIB (NRLIB from MID)>>
+<<PGROEB.spad (SPAD from IN)>>
+
+<<pgrobner.spad (SPAD from IN)>>
+<<pgrobner.spad.dvi (DOC from IN)>>
+
+<<PINTERP.o (O from NRLIB)>>
+<<PINTERP.NRLIB (NRLIB from MID)>>
+<<PINTERP.spad (SPAD from IN)>>
+
+<<PINTERPA.o (O from NRLIB)>>
+<<PINTERPA.NRLIB (NRLIB from MID)>>
+<<PINTERPA.spad (SPAD from IN)>>
+
+<<pinterp.spad (SPAD from IN)>>
+<<pinterp.spad.dvi (DOC from IN)>>
+
+<<PLEQN.o (O from NRLIB)>>
+<<PLEQN.NRLIB (NRLIB from MID)>>
+<<PLEQN.spad (SPAD from IN)>>
+
+<<pleqn.spad (SPAD from IN)>>
+<<pleqn.spad.dvi (DOC from IN)>>
+
+<<PLOT3D.o (O from NRLIB)>>
+<<PLOT3D.NRLIB (NRLIB from MID)>>
+<<PLOT3D.spad (SPAD from IN)>>
+
+<<plot3d.spad (SPAD from IN)>>
+<<plot3d.spad.dvi (DOC from IN)>>
+
+<<PLOT1.o (O from NRLIB)>>
+<<PLOT1.NRLIB (NRLIB from MID)>>
+<<PLOT1.spad (SPAD from IN)>>
+
+<<PLOT.o (O from NRLIB)>>
+<<PLOT.NRLIB (NRLIB from MID)>>
+<<PLOT.spad (SPAD from IN)>>
+
+<<plot.spad (SPAD from IN)>>
+<<plot.spad.dvi (DOC from IN)>>
+
+<<PLOTTOOL.o (O from NRLIB)>>
+<<PLOTTOOL.NRLIB (NRLIB from MID)>>
+<<PLOTTOOL.spad (SPAD from IN)>>
+
+<<plottool.spad (SPAD from IN)>>
+<<plottool.spad.dvi (DOC from IN)>>
+
+<<GPOLSET.o (O from NRLIB)>>
+<<GPOLSET.NRLIB (NRLIB from MID)>>
+<<GPOLSET.spad (SPAD from IN)>>
+
+<<PSETCAT-.o (O from NRLIB)>>
+<<PSETCAT-.NRLIB (NRLIB from MID)>>
+<<PSETCAT.o (O from NRLIB)>>
+<<PSETCAT.NRLIB (NRLIB from MID)>>
+<<PSETCAT.spad (SPAD from IN)>>
+<<PSETCAT-.o (BOOTSTRAP from MID)>>
+<<PSETCAT-.lsp (LISP from IN)>>
+<<PSETCAT.o (BOOTSTRAP from MID)>>
+<<PSETCAT.lsp (LISP from IN)>>
+
+<<polset.spad (SPAD from IN)>>
+<<polset.spad.dvi (DOC from IN)>>
+
+<<MPC2.o (O from NRLIB)>>
+<<MPC2.NRLIB (NRLIB from MID)>>
+<<MPC2.spad (SPAD from IN)>>
+
+<<MPC3.o (O from NRLIB)>>
+<<MPC3.NRLIB (NRLIB from MID)>>
+<<MPC3.spad (SPAD from IN)>>
+
+<<POLTOPOL.o (O from NRLIB)>>
+<<POLTOPOL.NRLIB (NRLIB from MID)>>
+<<POLTOPOL.spad (SPAD from IN)>>
+
+<<poltopol.spad (SPAD from IN)>>
+<<poltopol.spad.dvi (DOC from IN)>>
+
+<<AMR-.o (O from NRLIB)>>
+<<AMR-.NRLIB (NRLIB from MID)>>
+<<AMR.o (O from NRLIB)>>
+<<AMR.NRLIB (NRLIB from MID)>>
+<<AMR.spad (SPAD from IN)>>
+
+<<COMMUPC.o (O from NRLIB)>>
+<<COMMUPC.NRLIB (NRLIB from MID)>>
+<<COMMUPC.spad (SPAD from IN)>>
+
+<<FAMR-.o (O from NRLIB)>>
+<<FAMR-.NRLIB (NRLIB from MID)>>
+<<FAMR.o (O from NRLIB)>>
+<<FAMR.NRLIB (NRLIB from MID)>>
+<<FAMR.spad (SPAD from IN)>>
+
+<<POLYCAT-.o (O from NRLIB)>>
+<<POLYCAT-.NRLIB (NRLIB from MID)>>
+<<POLYCAT.o (O from NRLIB)>>
+<<POLYCAT.NRLIB (NRLIB from MID)>>
+<<POLYCAT.spad (SPAD from IN)>>
+<<POLYCAT-.o (BOOTSTRAP from MID)>>
+<<POLYCAT-.lsp (LISP from IN)>>
+<<POLYCAT.o (BOOTSTRAP from MID)>>
+<<POLYCAT.lsp (LISP from IN)>>
+
+<<POLYLIFT.o (O from NRLIB)>>
+<<POLYLIFT.NRLIB (NRLIB from MID)>>
+<<POLYLIFT.spad (SPAD from IN)>>
+
+<<UPOLYC-.o (O from NRLIB)>>
+<<UPOLYC-.NRLIB (NRLIB from MID)>>
+<<UPOLYC.o (O from NRLIB)>>
+<<UPOLYC.NRLIB (NRLIB from MID)>>
+<<UPOLYC.spad (SPAD from IN)>>
+<<UPOLYC-.o (BOOTSTRAP from MID)>>
+<<UPOLYC-.lsp (LISP from IN)>>
+<<UPOLYC.o (BOOTSTRAP from MID)>>
+<<UPOLYC.lsp (LISP from IN)>>
+
+<<polycat.spad (SPAD from IN)>>
+<<polycat.spad.dvi (DOC from IN)>>
+
+<<FM.o (O from NRLIB)>>
+<<FM.NRLIB (NRLIB from MID)>>
+<<FM.spad (SPAD from IN)>>
+
+<<POLY2UP.o (O from NRLIB)>>
+<<POLY2UP.NRLIB (NRLIB from MID)>>
+<<POLY2UP.spad (SPAD from IN)>>
+
+<<PR.o (O from NRLIB)>>
+<<PR.NRLIB (NRLIB from MID)>>
+<<PR.spad (SPAD from IN)>>
+
+<<PSQFR.o (O from NRLIB)>>
+<<PSQFR.NRLIB (NRLIB from MID)>>
+<<PSQFR.spad (SPAD from IN)>>
+
+<<SUP.o (O from NRLIB)>>
+<<SUP.NRLIB (NRLIB from MID)>>
+<<SUP.spad (SPAD from IN)>>
+
+<<SUP2.o (O from NRLIB)>>
+<<SUP2.NRLIB (NRLIB from MID)>>
+<<SUP2.spad (SPAD from IN)>>
+
+<<UPMP.o (O from NRLIB)>>
+<<UPMP.NRLIB (NRLIB from MID)>>
+<<UPMP.spad (SPAD from IN)>>
+
+<<UPOLYC2.o (O from NRLIB)>>
+<<UPOLYC2.NRLIB (NRLIB from MID)>>
+<<UPOLYC2.spad (SPAD from IN)>>
+
+<<UP.o (O from NRLIB)>>
+<<UP.NRLIB (NRLIB from MID)>>
+<<UP.spad (SPAD from IN)>>
+
+<<UP2.o (O from NRLIB)>>
+<<UP2.NRLIB (NRLIB from MID)>>
+<<UP2.spad (SPAD from IN)>>
+
+<<UPSQFREE.o (O from NRLIB)>>
+<<UPSQFREE.NRLIB (NRLIB from MID)>>
+<<UPSQFREE.spad (SPAD from IN)>>
+
+<<poly.spad (SPAD from IN)>>
+<<poly.spad.dvi (DOC from IN)>>
+
+<<FSPRMELT.o (O from NRLIB)>>
+<<FSPRMELT.NRLIB (NRLIB from MID)>>
+<<FSPRMELT.spad (SPAD from IN)>>
+
+<<PRIMELT.o (O from NRLIB)>>
+<<PRIMELT.NRLIB (NRLIB from MID)>>
+<<PRIMELT.spad (SPAD from IN)>>
+
+<<primelt.spad (SPAD from IN)>>
+<<primelt.spad.dvi (DOC from IN)>>
+
+<<PRINT.o (O from NRLIB)>>
+<<PRINT.NRLIB (NRLIB from MID)>>
+<<PRINT.spad (SPAD from IN)>>
+
+<<print.spad (SPAD from IN)>>
+<<print.spad.dvi (DOC from IN)>>
+
+<<PRODUCT.o (O from NRLIB)>>
+<<PRODUCT.NRLIB (NRLIB from MID)>>
+<<PRODUCT.spad (SPAD from IN)>>
+
+<<product.spad (SPAD from IN)>>
+<<product.spad.dvi (DOC from IN)>>
+
+<<PRS.o (O from NRLIB)>>
+<<PRS.NRLIB (NRLIB from MID)>>
+<<PRS.spad (SPAD from IN)>>
+
+<<prs.spad (SPAD from IN)>>
+<<prs.spad.dvi (DOC from IN)>>
+
+<<SYMPOLY.o (O from NRLIB)>>
+<<SYMPOLY.NRLIB (NRLIB from MID)>>
+<<SYMPOLY.spad (SPAD from IN)>>
+
+<<PRTITION.o (O from NRLIB)>>
+<<PRTITION.NRLIB (NRLIB from MID)>>
+<<PRTITION.spad (SPAD from IN)>>
+
+<<prtition.spad (SPAD from IN)>>
+<<prtition.spad.dvi (DOC from IN)>>
+
+<<MTSCAT.o (O from NRLIB)>>
+<<MTSCAT.NRLIB (NRLIB from MID)>>
+<<MTSCAT.spad (SPAD from IN)>>
+<<MTSCAT.o (BOOTSTRAP from MID)>>
+<<MTSCAT.lsp (LISP from IN)>>
+
+<<PSCAT-.o (O from NRLIB)>>
+<<PSCAT-.NRLIB (NRLIB from MID)>>
+<<PSCAT.o (O from NRLIB)>>
+<<PSCAT.NRLIB (NRLIB from MID)>>
+<<PSCAT.spad (SPAD from IN)>>
+
+<<ULSCAT.o (O from NRLIB)>>
+<<ULSCAT.NRLIB (NRLIB from MID)>>
+<<ULSCAT.spad (SPAD from IN)>>
+<<ULSCAT.o (BOOTSTRAP from MID)>>
+<<ULSCAT.lsp (LISP from IN)>>
+
+<<UPSCAT-.o (O from NRLIB)>>
+<<UPSCAT-.NRLIB (NRLIB from MID)>>
+<<UPSCAT.o (O from NRLIB)>>
+<<UPSCAT.NRLIB (NRLIB from MID)>>
+<<UPSCAT.spad (SPAD from IN)>>
+
+<<UPXSCAT.o (O from NRLIB)>>
+<<UPXSCAT.NRLIB (NRLIB from MID)>>
+<<UPXSCAT.spad (SPAD from IN)>>
+
+<<UTSCAT-.o (O from NRLIB)>>
+<<UTSCAT-.NRLIB (NRLIB from MID)>>
+<<UTSCAT.o (O from NRLIB)>>
+<<UTSCAT.NRLIB (NRLIB from MID)>>
+<<UTSCAT.spad (SPAD from IN)>>
+
+<<pscat.spad (SPAD from IN)>>
+<<pscat.spad.dvi (DOC from IN)>>
+
+<<PSEUDLIN.o (O from NRLIB)>>
+<<PSEUDLIN.NRLIB (NRLIB from MID)>>
+<<PSEUDLIN.spad (SPAD from IN)>>
+
+<<pseudolin.spad (SPAD from IN)>>
+<<pseudolin.spad.dvi (DOC from IN)>>
+
+<<PTRANFN.o (O from NRLIB)>>
+<<PTRANFN.NRLIB (NRLIB from MID)>>
+<<PTRANFN.spad (SPAD from IN)>>
+
+<<ptranfn.spad (SPAD from IN)>>
+<<ptranfn.spad.dvi (DOC from IN)>>
+
+<<UPXS.o (O from NRLIB)>>
+<<UPXS.NRLIB (NRLIB from MID)>>
+<<UPXS.spad (SPAD from IN)>>
+
+<<UPXSCCA-.o (O from NRLIB)>>
+<<UPXSCCA-.NRLIB (NRLIB from MID)>>
+<<UPXSCCA.o (O from NRLIB)>>
+<<UPXSCCA.NRLIB (NRLIB from MID)>>
+<<UPXSCCA.spad (SPAD from IN)>>
+
+<<UPXSCONS.o (O from NRLIB)>>
+<<UPXSCONS.NRLIB (NRLIB from MID)>>
+<<UPXSCONS.spad (SPAD from IN)>>
+
+<<UPXS2.o (O from NRLIB)>>
+<<UPXS2.NRLIB (NRLIB from MID)>>
+<<UPXS2.spad (SPAD from IN)>>
+
+<<puiseux.spad (SPAD from IN)>>
+<<puiseux.spad.dvi (DOC from IN)>>
+
+<<QALGSET.o (O from NRLIB)>>
+<<QALGSET.NRLIB (NRLIB from MID)>>
+<<QALGSET.spad (SPAD from IN)>>
+
+<<QALGSET2.o (O from NRLIB)>>
+<<QALGSET2.NRLIB (NRLIB from MID)>>
+<<QALGSET2.spad (SPAD from IN)>>
+
+<<qalgset.spad (SPAD from IN)>>
+<<qalgset.spad.dvi (DOC from IN)>>
+
+<<QUAT.o (O from NRLIB)>>
+<<QUAT.NRLIB (NRLIB from MID)>>
+<<QUAT.spad (SPAD from IN)>>
+
+<<QUATCAT-.o (O from NRLIB)>>
+<<QUATCAT-.NRLIB (NRLIB from MID)>>
+<<QUATCAT.o (O from NRLIB)>>
+<<QUATCAT.NRLIB (NRLIB from MID)>>
+<<QUATCAT.spad (SPAD from IN)>>
+
+<<QUATCT2.o (O from NRLIB)>>
+<<QUATCT2.NRLIB (NRLIB from MID)>>
+<<QUATCT2.spad (SPAD from IN)>>
+
+<<quat.spad (SPAD from IN)>>
+<<quat.spad.dvi (DOC from IN)>>
+
+<<REP.o (O from NRLIB)>>
+<<REP.NRLIB (NRLIB from MID)>>
+<<REP.spad (SPAD from IN)>>
+
+<<radeigen.spad (SPAD from IN)>>
+<<radeigen.spad.dvi (DOC from IN)>>
+
+<<BINARY.o (O from NRLIB)>>
+<<BINARY.NRLIB (NRLIB from MID)>>
+<<BINARY.spad (SPAD from IN)>>
+
+<<DECIMAL.o (O from NRLIB)>>
+<<DECIMAL.NRLIB (NRLIB from MID)>>
+<<DECIMAL.spad (SPAD from IN)>>
+
+<<HEXADEC.o (O from NRLIB)>>
+<<HEXADEC.NRLIB (NRLIB from MID)>>
+<<HEXADEC.spad (SPAD from IN)>>
+
+<<RADIX.o (O from NRLIB)>>
+<<RADIX.NRLIB (NRLIB from MID)>>
+<<RADIX.spad (SPAD from IN)>>
+
+<<RADUTIL.o (O from NRLIB)>>
+<<RADUTIL.NRLIB (NRLIB from MID)>>
+<<RADUTIL.spad (SPAD from IN)>>
+
+<<radix.spad (SPAD from IN)>>
+<<radix.spad.dvi (DOC from IN)>>
+
+<<INTBIT.o (O from NRLIB)>>
+<<INTBIT.NRLIB (NRLIB from MID)>>
+<<INTBIT.spad (SPAD from IN)>>
+
+<<RANDSRC.o (O from NRLIB)>>
+<<RANDSRC.NRLIB (NRLIB from MID)>>
+<<RANDSRC.spad (SPAD from IN)>>
+
+<<RDIST.o (O from NRLIB)>>
+<<RDIST.NRLIB (NRLIB from MID)>>
+<<RDIST.spad (SPAD from IN)>>
+
+<<RFDIST.o (O from NRLIB)>>
+<<RFDIST.NRLIB (NRLIB from MID)>>
+<<RFDIST.spad (SPAD from IN)>>
+
+<<RIDIST.o (O from NRLIB)>>
+<<RIDIST.NRLIB (NRLIB from MID)>>
+<<RIDIST.spad (SPAD from IN)>>
+
+<<random.spad (SPAD from IN)>>
+<<random.spad.dvi (DOC from IN)>>
+
+<<RATFACT.o (O from NRLIB)>>
+<<RATFACT.NRLIB (NRLIB from MID)>>
+<<RATFACT.spad (SPAD from IN)>>
+
+<<ratfact.spad (SPAD from IN)>>
+<<ratfact.spad.dvi (DOC from IN)>>
+
+<<INTTOOLS.o (O from NRLIB)>>
+<<INTTOOLS.NRLIB (NRLIB from MID)>>
+<<INTTOOLS.spad (SPAD from IN)>>
+
+<<RDEEF.o (O from NRLIB)>>
+<<RDEEF.NRLIB (NRLIB from MID)>>
+<<RDEEF.spad (SPAD from IN)>>
+
+<<rdeef.spad (SPAD from IN)>>
+<<rdeef.spad.dvi (DOC from IN)>>
+
+<<RDETR.o (O from NRLIB)>>
+<<RDETR.NRLIB (NRLIB from MID)>>
+<<RDETR.spad (SPAD from IN)>>
+
+<<rderf.spad (SPAD from IN)>>
+<<rderf.spad.dvi (DOC from IN)>>
+
+<<RDEEFS.o (O from NRLIB)>>
+<<RDEEFS.NRLIB (NRLIB from MID)>>
+<<RDEEFS.spad (SPAD from IN)>>
+
+<<RDETRS.o (O from NRLIB)>>
+<<RDETRS.NRLIB (NRLIB from MID)>>
+<<RDETRS.spad (SPAD from IN)>>
+
+<<rdesys.spad (SPAD from IN)>>
+<<rdesys.spad.dvi (DOC from IN)>>
+
+<<REAL0Q.o (O from NRLIB)>>
+<<REAL0Q.NRLIB (NRLIB from MID)>>
+<<REAL0Q.spad (SPAD from IN)>>
+
+<<real0q.spad (SPAD from IN)>>
+<<real0q.spad.dvi (DOC from IN)>>
+
+<<REAL0.o (O from NRLIB)>>
+<<REAL0.NRLIB (NRLIB from MID)>>
+<<REAL0.spad (SPAD from IN)>>
+
+<<realzero.spad (SPAD from IN)>>
+<<realzero.spad.dvi (DOC from IN)>>
+
+<<POLUTIL.o (O from NRLIB)>>
+<<POLUTIL.NRLIB (NRLIB from MID)>>
+<<POLUTIL.spad (SPAD from IN)>>
+
+<<RCFIELD-.o (O from NRLIB)>>
+<<RCFIELD-.NRLIB (NRLIB from MID)>>
+<<RCFIELD.o (O from NRLIB)>>
+<<RCFIELD.NRLIB (NRLIB from MID)>>
+<<RCFIELD.spad (SPAD from IN)>>
+
+<<RECLOS.o (O from NRLIB)>>
+<<RECLOS.NRLIB (NRLIB from MID)>>
+<<RECLOS.spad (SPAD from IN)>>
+
+<<ROIRC.o (O from NRLIB)>>
+<<ROIRC.NRLIB (NRLIB from MID)>>
+<<ROIRC.spad (SPAD from IN)>>
+
+<<RRCC-.o (O from NRLIB)>>
+<<RRCC-.NRLIB (NRLIB from MID)>>
+<<RRCC.o (O from NRLIB)>>
+<<RRCC.NRLIB (NRLIB from MID)>>
+<<RRCC.spad (SPAD from IN)>>
+
+<<reclos.spad (SPAD from IN)>>
+<<reclos.spad.dvi (DOC from IN)>>
+
+<<RSETCAT-.o (O from NRLIB)>>
+<<RSETCAT-.NRLIB (NRLIB from MID)>>
+<<RSETCAT.o (O from NRLIB)>>
+<<RSETCAT.NRLIB (NRLIB from MID)>>
+<<RSETCAT.spad (SPAD from IN)>>
+
+<<regset.spad (SPAD from IN)>>
+<<regset.spad.dvi (DOC from IN)>>
+
+<<REP1.o (O from NRLIB)>>
+<<REP1.NRLIB (NRLIB from MID)>>
+<<REP1.spad (SPAD from IN)>>
+
+<<rep1.spad (SPAD from IN)>>
+<<rep1.spad.dvi (DOC from IN)>>
+
+<<REP2.o (O from NRLIB)>>
+<<REP2.NRLIB (NRLIB from MID)>>
+<<REP2.spad (SPAD from IN)>>
+
+<<rep2.spad (SPAD from IN)>>
+<<rep2.spad.dvi (DOC from IN)>>
+
+<<RESRING.o (O from NRLIB)>>
+<<RESRING.NRLIB (NRLIB from MID)>>
+<<RESRING.spad (SPAD from IN)>>
+
+<<resring.spad (SPAD from IN)>>
+<<resring.spad.dvi (DOC from IN)>>
+
+<<FRETRCT-.o (O from NRLIB)>>
+<<FRETRCT-.NRLIB (NRLIB from MID)>>
+<<FRETRCT.o (O from NRLIB)>>
+<<FRETRCT.NRLIB (NRLIB from MID)>>
+<<FRETRCT.spad (SPAD from IN)>>
+
+<<INTRET.o (O from NRLIB)>>
+<<INTRET.NRLIB (NRLIB from MID)>>
+<<INTRET.spad (SPAD from IN)>>
+
+<<RATRET.o (O from NRLIB)>>
+<<RATRET.NRLIB (NRLIB from MID)>>
+<<RATRET.spad (SPAD from IN)>>
+
+<<retract.spad (SPAD from IN)>>
+<<retract.spad.dvi (DOC from IN)>>
+
+<<POLYCATQ.o (O from NRLIB)>>
+<<POLYCATQ.NRLIB (NRLIB from MID)>>
+<<POLYCATQ.spad (SPAD from IN)>>
+
+<<RF.o (O from NRLIB)>>
+<<RF.NRLIB (NRLIB from MID)>>
+<<RF.spad (SPAD from IN)>>
+
+<<rf.spad (SPAD from IN)>>
+<<rf.spad.dvi (DOC from IN)>>
+
+<<ODEPRRIC.o (O from NRLIB)>>
+<<ODEPRRIC.NRLIB (NRLIB from MID)>>
+<<ODEPRRIC.spad (SPAD from IN)>>
+
+<<ODERTRIC.o (O from NRLIB)>>
+<<ODERTRIC.NRLIB (NRLIB from MID)>>
+<<ODERTRIC.spad (SPAD from IN)>>
+
+<<riccati.spad (SPAD from IN)>>
+<<riccati.spad.dvi (DOC from IN)>>
+
+<<ATTRBUT.o (O from NRLIB)>>
+<<ATTRBUT.NRLIB (NRLIB from MID)>>
+<<ATTRBUT.spad (SPAD from IN)>>
+
+<<ROUTINE.o (O from NRLIB)>>
+<<ROUTINE.NRLIB (NRLIB from MID)>>
+<<ROUTINE.spad (SPAD from IN)>>
+
+<<routines.spad (SPAD from IN)>>
+<<routines.spad.dvi (DOC from IN)>>
+
+<<APPRULE.o (O from NRLIB)>>
+<<APPRULE.NRLIB (NRLIB from MID)>>
+<<APPRULE.spad (SPAD from IN)>>
+
+<<RULE.o (O from NRLIB)>>
+<<RULE.NRLIB (NRLIB from MID)>>
+<<RULE.spad (SPAD from IN)>>
+
+<<RULESET.o (O from NRLIB)>>
+<<RULESET.NRLIB (NRLIB from MID)>>
+<<RULESET.spad (SPAD from IN)>>
+
+<<rule.spad (SPAD from IN)>>
+<<rule.spad.dvi (DOC from IN)>>
+
+<<INCRMAPS.o (O from NRLIB)>>
+<<INCRMAPS.NRLIB (NRLIB from MID)>>
+<<INCRMAPS.spad (SPAD from IN)>>
+
+<<SEG.o (O from NRLIB)>>
+<<SEG.NRLIB (NRLIB from MID)>>
+<<SEG.spad (SPAD from IN)>>
+
+<<SEG2.o (O from NRLIB)>>
+<<SEG2.NRLIB (NRLIB from MID)>>
+<<SEG2.spad (SPAD from IN)>>
+
+<<SEGBIND.o (O from NRLIB)>>
+<<SEGBIND.NRLIB (NRLIB from MID)>>
+<<SEGBIND.spad (SPAD from IN)>>
+
+<<SEGBIND2.o (O from NRLIB)>>
+<<SEGBIND2.NRLIB (NRLIB from MID)>>
+<<SEGBIND2.spad (SPAD from IN)>>
+
+<<SEGCAT.o (O from NRLIB)>>
+<<SEGCAT.NRLIB (NRLIB from MID)>>
+<<SEGCAT.spad (SPAD from IN)>>
+
+<<SEGXCAT.o (O from NRLIB)>>
+<<SEGXCAT.NRLIB (NRLIB from MID)>>
+<<SEGXCAT.spad (SPAD from IN)>>
+
+<<UNISEG.o (O from NRLIB)>>
+<<UNISEG.NRLIB (NRLIB from MID)>>
+<<UNISEG.spad (SPAD from IN)>>
+
+<<UNISEG2.o (O from NRLIB)>>
+<<UNISEG2.NRLIB (NRLIB from MID)>>
+<<UNISEG2.spad (SPAD from IN)>>
+
+<<seg.spad (SPAD from IN)>>
+<<seg.spad.dvi (DOC from IN)>>
+
+<<UDPO.o (O from NRLIB)>>
+<<UDPO.NRLIB (NRLIB from MID)>>
+<<UDPO.spad (SPAD from IN)>>
+
+<<UDVO.o (O from NRLIB)>>
+<<UDVO.NRLIB (NRLIB from MID)>>
+<<UDVO.spad (SPAD from IN)>>
+
+<<setorder.spad (SPAD from IN)>>
+<<setorder.spad.dvi (DOC from IN)>>
+
+<<SET.o (O from NRLIB)>>
+<<SET.NRLIB (NRLIB from MID)>>
+<<SET.spad (SPAD from IN)>>
+
+<<sets.spad (SPAD from IN)>>
+<<sets.spad.dvi (DOC from IN)>>
+
+<<SEX.o (O from NRLIB)>>
+<<SEX.NRLIB (NRLIB from MID)>>
+<<SEX.spad (SPAD from IN)>>
+
+<<SEXCAT.o (O from NRLIB)>>
+<<SEXCAT.NRLIB (NRLIB from MID)>>
+<<SEXCAT.spad (SPAD from IN)>>
+
+<<SEXOF.o (O from NRLIB)>>
+<<SEXOF.NRLIB (NRLIB from MID)>>
+<<SEXOF.spad (SPAD from IN)>>
+
+<<sex.spad (SPAD from IN)>>
+<<sex.spad.dvi (DOC from IN)>>
+
+<<DFLOAT.o (O from NRLIB)>>
+<<DFLOAT.NRLIB (NRLIB from MID)>>
+<<DFLOAT.spad (SPAD from IN)>>
+<<DFLOAT.o (BOOTSTRAP from MID)>>
+<<DFLOAT.lsp (LISP from IN)>>
+
+<<FPS-.o (O from NRLIB)>>
+<<FPS-.NRLIB (NRLIB from MID)>>
+<<FPS.o (O from NRLIB)>>
+<<FPS.NRLIB (NRLIB from MID)>>
+<<FPS.spad (SPAD from IN)>>
+<<FPS-.o (BOOTSTRAP from MID)>>
+<<FPS-.lsp (LISP from IN)>>
+<<FPS.o (BOOTSTRAP from MID)>>
+<<FPS.lsp (LISP from IN)>>
+
+<<RADCAT-.o (O from NRLIB)>>
+<<RADCAT-.NRLIB (NRLIB from MID)>>
+<<RADCAT.o (O from NRLIB)>>
+<<RADCAT.NRLIB (NRLIB from MID)>>
+<<RADCAT.spad (SPAD from IN)>>
+
+<<REAL.o (O from NRLIB)>>
+<<REAL.NRLIB (NRLIB from MID)>>
+<<REAL.spad (SPAD from IN)>>
+
+<<RNS-.o (O from NRLIB)>>
+<<RNS-.NRLIB (NRLIB from MID)>>
+<<RNS.o (O from NRLIB)>>
+<<RNS.NRLIB (NRLIB from MID)>>
+<<RNS.spad (SPAD from IN)>>
+<<RNS-.o (BOOTSTRAP from MID)>>
+<<RNS-.lsp (LISP from IN)>>
+<<RNS.o (BOOTSTRAP from MID)>>
+<<RNS.lsp (LISP from IN)>>
+
+<<sf.spad (SPAD from IN)>>
+<<sf.spad.dvi (DOC from IN)>>
+
+<<SGCF.o (O from NRLIB)>>
+<<SGCF.NRLIB (NRLIB from MID)>>
+<<SGCF.spad (SPAD from IN)>>
+
+<<sgcf.spad (SPAD from IN)>>
+<<sgcf.spad.dvi (DOC from IN)>>
+
+<<INPSIGN.o (O from NRLIB)>>
+<<INPSIGN.NRLIB (NRLIB from MID)>>
+<<INPSIGN.spad (SPAD from IN)>>
+
+<<LIMITRF.o (O from NRLIB)>>
+<<LIMITRF.NRLIB (NRLIB from MID)>>
+<<LIMITRF.spad (SPAD from IN)>>
+
+<<SIGNRF.o (O from NRLIB)>>
+<<SIGNRF.NRLIB (NRLIB from MID)>>
+<<SIGNRF.spad (SPAD from IN)>>
+
+<<TOOLSIGN.o (O from NRLIB)>>
+<<TOOLSIGN.NRLIB (NRLIB from MID)>>
+<<TOOLSIGN.spad (SPAD from IN)>>
+
+<<sign.spad (SPAD from IN)>>
+<<sign.spad.dvi (DOC from IN)>>
+
+<<SINT.o (O from NRLIB)>>
+<<SINT.NRLIB (NRLIB from MID)>>
+<<SINT.spad (SPAD from IN)>>
+<<SINT.o (BOOTSTRAP from MID)>>
+<<SINT.lsp (LISP from IN)>>
+
+<<INS-.o (O from NRLIB)>>
+<<INS-.NRLIB (NRLIB from MID)>>
+<<INS.o (O from NRLIB)>>
+<<INS.NRLIB (NRLIB from MID)>>
+<<INS.spad (SPAD from IN)>>
+<<INS-.o (BOOTSTRAP from MID)>>
+<<INS-.lsp (LISP from IN)>>
+<<INS.o (BOOTSTRAP from MID)>>
+<<INS.lsp (LISP from IN)>>
+
+<<si.spad (SPAD from IN)>>
+<<si.spad.dvi (DOC from IN)>>
+
+<<SMITH.o (O from NRLIB)>>
+<<SMITH.NRLIB (NRLIB from MID)>>
+<<SMITH.spad (SPAD from IN)>>
+
+<<smith.spad (SPAD from IN)>>
+<<smith.spad.dvi (DOC from IN)>>
+
+<<DIOSP.o (O from NRLIB)>>
+<<DIOSP.NRLIB (NRLIB from MID)>>
+<<DIOSP.spad (SPAD from IN)>>
+
+<<solvedio.spad (SPAD from IN)>>
+<<solvedio.spad.dvi (DOC from IN)>>
+
+<<SOLVEFOR.o (O from NRLIB)>>
+<<SOLVEFOR.NRLIB (NRLIB from MID)>>
+<<SOLVEFOR.spad (SPAD from IN)>>
+
+<<solvefor.spad (SPAD from IN)>>
+<<solvefor.spad.dvi (DOC from IN)>>
+
+<<LSMP.o (O from NRLIB)>>
+<<LSMP.NRLIB (NRLIB from MID)>>
+<<LSMP.spad (SPAD from IN)>>
+
+<<LSMP1.o (O from NRLIB)>>
+<<LSMP1.NRLIB (NRLIB from MID)>>
+<<LSMP1.spad (SPAD from IN)>>
+
+<<LSPP.o (O from NRLIB)>>
+<<LSPP.NRLIB (NRLIB from MID)>>
+<<LSPP.spad (SPAD from IN)>>
+
+<<solvelin.spad (SPAD from IN)>>
+<<solvelin.spad.dvi (DOC from IN)>>
+
+<<SOLVERAD.o (O from NRLIB)>>
+<<SOLVERAD.NRLIB (NRLIB from MID)>>
+<<SOLVERAD.spad (SPAD from IN)>>
+
+<<solverad.spad (SPAD from IN)>>
+<<solverad.spad.dvi (DOC from IN)>>
+
+<<SORTPAK.o (O from NRLIB)>>
+<<SORTPAK.NRLIB (NRLIB from MID)>>
+<<SORTPAK.spad (SPAD from IN)>>
+
+<<sortpak.spad (SPAD from IN)>>
+<<sortpak.spad.dvi (DOC from IN)>>
+
+<<SPACEC.o (O from NRLIB)>>
+<<SPACEC.NRLIB (NRLIB from MID)>>
+<<SPACEC.spad (SPAD from IN)>>
+
+<<SPACE3.o (O from NRLIB)>>
+<<SPACE3.NRLIB (NRLIB from MID)>>
+<<SPACE3.spad (SPAD from IN)>>
+
+<<TOPSP.o (O from NRLIB)>>
+<<TOPSP.NRLIB (NRLIB from MID)>>
+<<TOPSP.spad (SPAD from IN)>>
+
+<<space.spad (SPAD from IN)>>
+<<space.spad.dvi (DOC from IN)>>
+
+<<DFSFUN.o (O from NRLIB)>>
+<<DFSFUN.NRLIB (NRLIB from MID)>>
+<<DFSFUN.spad (SPAD from IN)>>
+
+<<NTPOLFN.o (O from NRLIB)>>
+<<NTPOLFN.NRLIB (NRLIB from MID)>>
+<<NTPOLFN.spad (SPAD from IN)>>
+
+<<ORTHPOL.o (O from NRLIB)>>
+<<ORTHPOL.NRLIB (NRLIB from MID)>>
+<<ORTHPOL.spad (SPAD from IN)>>
+
+<<special.spad (SPAD from IN)>>
+<<special.spad.dvi (DOC from IN)>>
+
+<<sregset.spad (SPAD from IN)>>
+<<sregset.spad.dvi (DOC from IN)>>
+
+<<NAGS.o (O from NRLIB)>>
+<<NAGS.NRLIB (NRLIB from MID)>>
+<<NAGS.spad (SPAD from IN)>>
+
+<<s.spad (SPAD from IN)>>
+<<s.spad.dvi (DOC from IN)>>
+
+<<CSTTOOLS.o (O from NRLIB)>>
+<<CSTTOOLS.NRLIB (NRLIB from MID)>>
+<<CSTTOOLS.spad (SPAD from IN)>>
+
+<<LZSTAGG-.o (O from NRLIB)>>
+<<LZSTAGG-.NRLIB (NRLIB from MID)>>
+<<LZSTAGG.o (O from NRLIB)>>
+<<LZSTAGG.NRLIB (NRLIB from MID)>>
+<<LZSTAGG.spad (SPAD from IN)>>
+
+<<STREAM.o (O from NRLIB)>>
+<<STREAM.NRLIB (NRLIB from MID)>>
+<<STREAM.spad (SPAD from IN)>>
+
+<<STREAM1.o (O from NRLIB)>>
+<<STREAM1.NRLIB (NRLIB from MID)>>
+<<STREAM1.spad (SPAD from IN)>>
+
+<<STREAM2.o (O from NRLIB)>>
+<<STREAM2.NRLIB (NRLIB from MID)>>
+<<STREAM2.spad (SPAD from IN)>>
+
+<<STREAM3.o (O from NRLIB)>>
+<<STREAM3.NRLIB (NRLIB from MID)>>
+<<STREAM3.spad (SPAD from IN)>>
+
+<<stream.spad (SPAD from IN)>>
+<<stream.spad.dvi (DOC from IN)>>
+
+<<CCLASS.o (O from NRLIB)>>
+<<CCLASS.NRLIB (NRLIB from MID)>>
+<<CCLASS.spad (SPAD from IN)>>
+
+<<CHAR.o (O from NRLIB)>>
+<<CHAR.NRLIB (NRLIB from MID)>>
+<<CHAR.spad (SPAD from IN)>>
+<<CHAR.o (BOOTSTRAP from MID)>>
+<<CHAR.lsp (LISP from IN)>>
+
+<<ISTRING.o (O from NRLIB)>>
+<<ISTRING.NRLIB (NRLIB from MID)>>
+<<ISTRING.spad (SPAD from IN)>>
+<<ISTRING.o (BOOTSTRAP from MID)>>
+<<ISTRING.lsp (LISP from IN)>>
+
+<<STRICAT.o (O from NRLIB)>>
+<<STRICAT.NRLIB (NRLIB from MID)>>
+<<STRICAT.spad (SPAD from IN)>>
+
+<<STRING.o (O from NRLIB)>>
+<<STRING.NRLIB (NRLIB from MID)>>
+<<STRING.spad (SPAD from IN)>>
+
+<<string.spad (SPAD from IN)>>
+<<string.spad.dvi (DOC from IN)>>
+
+<<STTAYLOR.o (O from NRLIB)>>
+<<STTAYLOR.NRLIB (NRLIB from MID)>>
+<<STTAYLOR.spad (SPAD from IN)>>
+
+<<sttaylor.spad (SPAD from IN)>>
+<<sttaylor.spad.dvi (DOC from IN)>>
+
+<<STTF.o (O from NRLIB)>>
+<<STTF.NRLIB (NRLIB from MID)>>
+<<STTF.spad (SPAD from IN)>>
+
+<<STTFNC.o (O from NRLIB)>>
+<<STTFNC.NRLIB (NRLIB from MID)>>
+<<STTFNC.spad (SPAD from IN)>>
+
+<<sttf.spad (SPAD from IN)>>
+<<sttf.spad.dvi (DOC from IN)>>
+
+<<SHP.o (O from NRLIB)>>
+<<SHP.NRLIB (NRLIB from MID)>>
+<<SHP.spad (SPAD from IN)>>
+
+<<sturm.spad (SPAD from IN)>>
+<<sturm.spad.dvi (DOC from IN)>>
+
+<<SUCH.o (O from NRLIB)>>
+<<SUCH.NRLIB (NRLIB from MID)>>
+<<SUCH.spad (SPAD from IN)>>
+
+<<suchthat.spad (SPAD from IN)>>
+<<suchthat.spad.dvi (DOC from IN)>>
+
+<<SULS.o (O from NRLIB)>>
+<<SULS.NRLIB (NRLIB from MID)>>
+<<SULS.spad (SPAD from IN)>>
+
+<<suls.spad (SPAD from IN)>>
+<<suls.spad.dvi (DOC from IN)>>
+
+<<GOSPER.o (O from NRLIB)>>
+<<GOSPER.NRLIB (NRLIB from MID)>>
+<<GOSPER.spad (SPAD from IN)>>
+
+<<ISUMP.o (O from NRLIB)>>
+<<ISUMP.NRLIB (NRLIB from MID)>>
+<<ISUMP.spad (SPAD from IN)>>
+
+<<SUMRF.o (O from NRLIB)>>
+<<SUMRF.NRLIB (NRLIB from MID)>>
+<<SUMRF.spad (SPAD from IN)>>
+
+<<sum.spad (SPAD from IN)>>
+<<sum.spad.dvi (DOC from IN)>>
+
+<<ISUPS.o (O from NRLIB)>>
+<<ISUPS.NRLIB (NRLIB from MID)>>
+<<ISUPS.spad (SPAD from IN)>>
+
+<<sups.spad (SPAD from IN)>>
+<<sups.spad.dvi (DOC from IN)>>
+
+<<SUPXS.o (O from NRLIB)>>
+<<SUPXS.NRLIB (NRLIB from MID)>>
+<<SUPXS.spad (SPAD from IN)>>
+
+<<supxs.spad (SPAD from IN)>>
+<<supxs.spad.dvi (DOC from IN)>>
+
+<<SUTS.o (O from NRLIB)>>
+<<SUTS.NRLIB (NRLIB from MID)>>
+<<SUTS.spad (SPAD from IN)>>
+
+<<suts.spad (SPAD from IN)>>
+<<suts.spad.dvi (DOC from IN)>>
+
+<<SYMBOL.o (O from NRLIB)>>
+<<SYMBOL.NRLIB (NRLIB from MID)>>
+<<SYMBOL.spad (SPAD from IN)>>
+<<SYMBOL.o (BOOTSTRAP from MID)>>
+<<SYMBOL.lsp (LISP from IN)>>
+
+<<symbol.spad (SPAD from IN)>>
+<<symbol.spad.dvi (DOC from IN)>>
+
+<<SYSSOLP.o (O from NRLIB)>>
+<<SYSSOLP.NRLIB (NRLIB from MID)>>
+<<SYSSOLP.spad (SPAD from IN)>>
+
+<<syssolp.spad (SPAD from IN)>>
+<<syssolp.spad.dvi (DOC from IN)>>
+
+<<MSYSCMD.o (O from NRLIB)>>
+<<MSYSCMD.NRLIB (NRLIB from MID)>>
+<<MSYSCMD.spad (SPAD from IN)>>
+
+<<system.spad (SPAD from IN)>>
+<<system.spad.dvi (DOC from IN)>>
+
+<<TABLBUMP.o (O from NRLIB)>>
+<<TABLBUMP.NRLIB (NRLIB from MID)>>
+<<TABLBUMP.spad (SPAD from IN)>>
+
+<<TABLEAU.o (O from NRLIB)>>
+<<TABLEAU.NRLIB (NRLIB from MID)>>
+<<TABLEAU.spad (SPAD from IN)>>
+
+<<tableau.spad (SPAD from IN)>>
+<<tableau.spad.dvi (DOC from IN)>>
+
+<<EQTBL.o (O from NRLIB)>>
+<<EQTBL.NRLIB (NRLIB from MID)>>
+<<EQTBL.spad (SPAD from IN)>>
+
+<<GSTBL.o (O from NRLIB)>>
+<<GSTBL.NRLIB (NRLIB from MID)>>
+<<GSTBL.spad (SPAD from IN)>>
+
+<<HASHTBL.o (O from NRLIB)>>
+<<HASHTBL.NRLIB (NRLIB from MID)>>
+<<HASHTBL.spad (SPAD from IN)>>
+
+<<INTABL.o (O from NRLIB)>>
+<<INTABL.NRLIB (NRLIB from MID)>>
+<<INTABL.spad (SPAD from IN)>>
+
+<<STBL.o (O from NRLIB)>>
+<<STBL.NRLIB (NRLIB from MID)>>
+<<STBL.spad (SPAD from IN)>>
+
+<<STRTBL.o (O from NRLIB)>>
+<<STRTBL.NRLIB (NRLIB from MID)>>
+<<STRTBL.spad (SPAD from IN)>>
+
+<<TABLE.o (O from NRLIB)>>
+<<TABLE.NRLIB (NRLIB from MID)>>
+<<TABLE.spad (SPAD from IN)>>
+
+<<table.spad (SPAD from IN)>>
+<<table.spad.dvi (DOC from IN)>>
+
+<<ITAYLOR.o (O from NRLIB)>>
+<<ITAYLOR.NRLIB (NRLIB from MID)>>
+<<ITAYLOR.spad (SPAD from IN)>>
+
+<<UTS.o (O from NRLIB)>>
+<<UTS.NRLIB (NRLIB from MID)>>
+<<UTS.spad (SPAD from IN)>>
+
+<<UTS2.o (O from NRLIB)>>
+<<UTS2.NRLIB (NRLIB from MID)>>
+<<UTS2.spad (SPAD from IN)>>
+
+<<taylor.spad (SPAD from IN)>>
+<<taylor.spad.dvi (DOC from IN)>>
+
+<<TEX.o (O from NRLIB)>>
+<<TEX.NRLIB (NRLIB from MID)>>
+<<TEX.spad (SPAD from IN)>>
+
+<<TEX1.o (O from NRLIB)>>
+<<TEX1.NRLIB (NRLIB from MID)>>
+<<TEX1.spad (SPAD from IN)>>
+
+<<tex.spad (SPAD from IN)>>
+<<tex.spad.dvi (DOC from IN)>>
+
+<<ESTOOLS.o (O from NRLIB)>>
+<<ESTOOLS.NRLIB (NRLIB from MID)>>
+<<ESTOOLS.spad (SPAD from IN)>>
+
+<<ESTOOLS1.o (O from NRLIB)>>
+<<ESTOOLS1.NRLIB (NRLIB from MID)>>
+<<ESTOOLS1.spad (SPAD from IN)>>
+
+<<ESTOOLS2.o (O from NRLIB)>>
+<<ESTOOLS2.NRLIB (NRLIB from MID)>>
+<<ESTOOLS2.spad (SPAD from IN)>>
+
+<<tools.spad (SPAD from IN)>>
+<<tools.spad.dvi (DOC from IN)>>
+
+<<SOLVESER.o (O from NRLIB)>>
+<<SOLVESER.NRLIB (NRLIB from MID)>>
+<<SOLVESER.spad (SPAD from IN)>>
+
+<<transsolve.spad (SPAD from IN)>>
+<<transsolve.spad.dvi (DOC from IN)>>
+
+<<BBTREE.o (O from NRLIB)>>
+<<BBTREE.NRLIB (NRLIB from MID)>>
+<<BBTREE.spad (SPAD from IN)>>
+
+<<BSTREE.o (O from NRLIB)>>
+<<BSTREE.NRLIB (NRLIB from MID)>>
+<<BSTREE.spad (SPAD from IN)>>
+
+<<BTCAT-.o (O from NRLIB)>>
+<<BTCAT-.NRLIB (NRLIB from MID)>>
+<<BTCAT.o (O from NRLIB)>>
+<<BTCAT.NRLIB (NRLIB from MID)>>
+<<BTCAT.spad (SPAD from IN)>>
+
+<<BTOURN.o (O from NRLIB)>>
+<<BTOURN.NRLIB (NRLIB from MID)>>
+<<BTOURN.spad (SPAD from IN)>>
+
+<<BTREE.o (O from NRLIB)>>
+<<BTREE.NRLIB (NRLIB from MID)>>
+<<BTREE.spad (SPAD from IN)>>
+
+<<PENDTREE.o (O from NRLIB)>>
+<<PENDTREE.NRLIB (NRLIB from MID)>>
+<<PENDTREE.spad (SPAD from IN)>>
+
+<<TREE.o (O from NRLIB)>>
+<<TREE.NRLIB (NRLIB from MID)>>
+<<TREE.spad (SPAD from IN)>>
+
+<<tree.spad (SPAD from IN)>>
+<<tree.spad.dvi (DOC from IN)>>
+
+<<AHYP.o (O from NRLIB)>>
+<<AHYP.NRLIB (NRLIB from MID)>>
+<<AHYP.spad (SPAD from IN)>>
+
+<<ATRIG-.o (O from NRLIB)>>
+<<ATRIG-.NRLIB (NRLIB from MID)>>
+<<ATRIG.o (O from NRLIB)>>
+<<ATRIG.NRLIB (NRLIB from MID)>>
+<<ATRIG.spad (SPAD from IN)>>
+
+<<CFCAT.o (O from NRLIB)>>
+<<CFCAT.NRLIB (NRLIB from MID)>>
+<<CFCAT.spad (SPAD from IN)>>
+
+<<ELEMFUN-.o (O from NRLIB)>>
+<<ELEMFUN-.NRLIB (NRLIB from MID)>>
+<<ELEMFUN.o (O from NRLIB)>>
+<<ELEMFUN.NRLIB (NRLIB from MID)>>
+<<ELEMFUN.spad (SPAD from IN)>>
+
+<<LFCAT.o (O from NRLIB)>>
+<<LFCAT.NRLIB (NRLIB from MID)>>
+<<LFCAT.spad (SPAD from IN)>>
+
+<<HYPCAT-.o (O from NRLIB)>>
+<<HYPCAT-.NRLIB (NRLIB from MID)>>
+<<HYPCAT.o (O from NRLIB)>>
+<<HYPCAT.NRLIB (NRLIB from MID)>>
+<<HYPCAT.spad (SPAD from IN)>>
+
+<<PRIMCAT.o (O from NRLIB)>>
+<<PRIMCAT.NRLIB (NRLIB from MID)>>
+<<PRIMCAT.spad (SPAD from IN)>>
+
+<<SPFCAT.o (O from NRLIB)>>
+<<SPFCAT.NRLIB (NRLIB from MID)>>
+<<SPFCAT.spad (SPAD from IN)>>
+
+<<TRANFUN-.o (O from NRLIB)>>
+<<TRANFUN-.NRLIB (NRLIB from MID)>>
+<<TRANFUN.o (O from NRLIB)>>
+<<TRANFUN.NRLIB (NRLIB from MID)>>
+<<TRANFUN.spad (SPAD from IN)>>
+
+<<TRIGCAT-.o (O from NRLIB)>>
+<<TRIGCAT-.NRLIB (NRLIB from MID)>>
+<<TRIGCAT.o (O from NRLIB)>>
+<<TRIGCAT.NRLIB (NRLIB from MID)>>
+<<TRIGCAT.spad (SPAD from IN)>>
+
+<<trigcat.spad (SPAD from IN)>>
+<<trigcat.spad.dvi (DOC from IN)>>
+
+<<GTSET.o (O from NRLIB)>>
+<<GTSET.NRLIB (NRLIB from MID)>>
+<<GTSET.spad (SPAD from IN)>>
+
+<<PSETPK.o (O from NRLIB)>>
+<<PSETPK.NRLIB (NRLIB from MID)>>
+<<PSETPK.spad (SPAD from IN)>>
+
+<<TSETCAT-.o (O from NRLIB)>>
+<<TSETCAT-.NRLIB (NRLIB from MID)>>
+<<TSETCAT.o (O from NRLIB)>>
+<<TSETCAT.NRLIB (NRLIB from MID)>>
+<<TSETCAT.spad (SPAD from IN)>>
+<<TSETCAT-.o (BOOTSTRAP from MID)>>
+<<TSETCAT-.lsp (LISP from IN)>>
+<<TSETCAT.o (BOOTSTRAP from MID)>>
+<<TSETCAT.lsp (LISP from IN)>>
+
+<<WUTSET.o (O from NRLIB)>>
+<<WUTSET.NRLIB (NRLIB from MID)>>
+<<WUTSET.spad (SPAD from IN)>>
+
+<<triset.spad (SPAD from IN)>>
+<<triset.spad.dvi (DOC from IN)>>
+
+<<EXPRTUBE.o (O from NRLIB)>>
+<<EXPRTUBE.NRLIB (NRLIB from MID)>>
+<<EXPRTUBE.spad (SPAD from IN)>>
+
+<<NUMTUBE.o (O from NRLIB)>>
+<<NUMTUBE.NRLIB (NRLIB from MID)>>
+<<NUMTUBE.spad (SPAD from IN)>>
+
+<<TUBE.o (O from NRLIB)>>
+<<TUBE.NRLIB (NRLIB from MID)>>
+<<TUBE.spad (SPAD from IN)>>
+
+<<TUBETOOL.o (O from NRLIB)>>
+<<TUBETOOL.NRLIB (NRLIB from MID)>>
+<<TUBETOOL.spad (SPAD from IN)>>
+
+<<tube.spad (SPAD from IN)>>
+<<tube.spad.dvi (DOC from IN)>>
+
+<<NORMRETR.o (O from NRLIB)>>
+<<NORMRETR.NRLIB (NRLIB from MID)>>
+<<NORMRETR.spad (SPAD from IN)>>
+
+<<TWOFACT.o (O from NRLIB)>>
+<<TWOFACT.NRLIB (NRLIB from MID)>>
+<<TWOFACT.spad (SPAD from IN)>>
+
+<<twofact.spad (SPAD from IN)>>
+<<twofact.spad.dvi (DOC from IN)>>
+
+<<UNIFACT.o (O from NRLIB)>>
+<<UNIFACT.NRLIB (NRLIB from MID)>>
+<<UNIFACT.spad (SPAD from IN)>>
+
+<<unifact.spad (SPAD from IN)>>
+<<unifact.spad.dvi (DOC from IN)>>
+
+<<UPDECOMP.o (O from NRLIB)>>
+<<UPDECOMP.NRLIB (NRLIB from MID)>>
+<<UPDECOMP.spad (SPAD from IN)>>
+
+<<updecomp.spad (SPAD from IN)>>
+<<updecomp.spad.dvi (DOC from IN)>>
+
+<<UPDIVP.o (O from NRLIB)>>
+<<UPDIVP.NRLIB (NRLIB from MID)>>
+<<UPDIVP.spad (SPAD from IN)>>
+
+<<updivp.spad (SPAD from IN)>>
+<<updivp.spad.dvi (DOC from IN)>>
+
+<<UTSODE.o (O from NRLIB)>>
+<<UTSODE.NRLIB (NRLIB from MID)>>
+<<UTSODE.spad (SPAD from IN)>>
+
+<<utsode.spad (SPAD from IN)>>
+<<utsode.spad.dvi (DOC from IN)>>
+
+<<ANON.o (O from NRLIB)>>
+<<ANON.NRLIB (NRLIB from MID)>>
+<<ANON.spad (SPAD from IN)>>
+
+<<FUNCTION.o (O from NRLIB)>>
+<<FUNCTION.NRLIB (NRLIB from MID)>>
+<<FUNCTION.spad (SPAD from IN)>>
+
+<<OVAR.o (O from NRLIB)>>
+<<OVAR.NRLIB (NRLIB from MID)>>
+<<OVAR.spad (SPAD from IN)>>
+
+<<RULECOLD.o (O from NRLIB)>>
+<<RULECOLD.NRLIB (NRLIB from MID)>>
+<<RULECOLD.spad (SPAD from IN)>>
+
+<<VARIABLE.o (O from NRLIB)>>
+<<VARIABLE.NRLIB (NRLIB from MID)>>
+<<VARIABLE.spad (SPAD from IN)>>
+
+<<variable.spad (SPAD from IN)>>
+<<variable.spad.dvi (DOC from IN)>>
+
+<<DIRPCAT-.o (O from NRLIB)>>
+<<DIRPCAT-.NRLIB (NRLIB from MID)>>
+<<DIRPCAT.o (O from NRLIB)>>
+<<DIRPCAT.NRLIB (NRLIB from MID)>>
+<<DIRPCAT.spad (SPAD from IN)>>
+
+<<DIRPROD.o (O from NRLIB)>>
+<<DIRPROD.NRLIB (NRLIB from MID)>>
+<<DIRPROD.spad (SPAD from IN)>>
+
+<<DIRPROD2.o (O from NRLIB)>>
+<<DIRPROD2.NRLIB (NRLIB from MID)>>
+<<DIRPROD2.spad (SPAD from IN)>>
+
+<<IVECTOR.o (O from NRLIB)>>
+<<IVECTOR.NRLIB (NRLIB from MID)>>
+<<IVECTOR.spad (SPAD from IN)>>
+
+<<VECTCAT-.o (O from NRLIB)>>
+<<VECTCAT-.NRLIB (NRLIB from MID)>>
+<<VECTCAT.o (O from NRLIB)>>
+<<VECTCAT.NRLIB (NRLIB from MID)>>
+<<VECTCAT.spad (SPAD from IN)>>
+
+<<VECTOR.o (O from NRLIB)>>
+<<VECTOR.NRLIB (NRLIB from MID)>>
+<<VECTOR.spad (SPAD from IN)>>
+<<VECTOR.o (BOOTSTRAP from MID)>>
+<<VECTOR.lsp (LISP from IN)>>
+
+<<VECTOR2.o (O from NRLIB)>>
+<<VECTOR2.NRLIB (NRLIB from MID)>>
+<<VECTOR2.spad (SPAD from IN)>>
+
+<<vector.spad (SPAD from IN)>>
+<<vector.spad.dvi (DOC from IN)>>
+
+<<GRIMAGE.o (O from NRLIB)>>
+<<GRIMAGE.NRLIB (NRLIB from MID)>>
+<<GRIMAGE.spad (SPAD from IN)>>
+
+<<VIEW2D.o (O from NRLIB)>>
+<<VIEW2D.NRLIB (NRLIB from MID)>>
+<<VIEW2D.spad (SPAD from IN)>>
+
+<<view2D.spad (SPAD from IN)>>
+<<view2D.spad.dvi (DOC from IN)>>
+
+<<VIEW3D.o (O from NRLIB)>>
+<<VIEW3D.NRLIB (NRLIB from MID)>>
+<<VIEW3D.spad (SPAD from IN)>>
+
+<<view3D.spad (SPAD from IN)>>
+<<view3D.spad.dvi (DOC from IN)>>
+
+<<VIEWDEF.o (O from NRLIB)>>
+<<VIEWDEF.NRLIB (NRLIB from MID)>>
+<<VIEWDEF.spad (SPAD from IN)>>
+
+<<viewDef.spad (SPAD from IN)>>
+<<viewDef.spad.dvi (DOC from IN)>>
+
+<<VIEW.o (O from NRLIB)>>
+<<VIEW.NRLIB (NRLIB from MID)>>
+<<VIEW.spad (SPAD from IN)>>
+
+<<viewpack.spad (SPAD from IN)>>
+<<viewpack.spad.dvi (DOC from IN)>>
+
+<<EXIT.o (O from NRLIB)>>
+<<EXIT.NRLIB (NRLIB from MID)>>
+<<EXIT.spad (SPAD from IN)>>
+
+<<RESLATC.o (O from NRLIB)>>
+<<RESLATC.NRLIB (NRLIB from MID)>>
+<<RESLATC.spad (SPAD from IN)>>
+
+<<VOID.o (O from NRLIB)>>
+<<VOID.NRLIB (NRLIB from MID)>>
+<<VOID.spad (SPAD from IN)>>
+
+<<void.spad (SPAD from IN)>>
+<<void.spad.dvi (DOC from IN)>>
+
+<<WEIER.o (O from NRLIB)>>
+<<WEIER.NRLIB (NRLIB from MID)>>
+<<WEIER.spad (SPAD from IN)>>
+
+<<weier.spad (SPAD from IN)>>
+<<weier.spad.dvi (DOC from IN)>>
+
+<<OWP.o (O from NRLIB)>>
+<<OWP.NRLIB (NRLIB from MID)>>
+<<OWP.spad (SPAD from IN)>>
+
+<<WP.o (O from NRLIB)>>
+<<WP.NRLIB (NRLIB from MID)>>
+<<WP.spad (SPAD from IN)>>
+
+<<wtpol.spad (SPAD from IN)>>
+<<wtpol.spad.dvi (DOC from IN)>>
+
+<<FLALG.o (O from NRLIB)>>
+<<FLALG.NRLIB (NRLIB from MID)>>
+<<FLALG.spad (SPAD from IN)>>
+
+<<LEXP.o (O from NRLIB)>>
+<<LEXP.NRLIB (NRLIB from MID)>>
+<<LEXP.spad (SPAD from IN)>>
+
+<<LIECAT-.o (O from NRLIB)>>
+<<LIECAT-.NRLIB (NRLIB from MID)>>
+<<LIECAT.o (O from NRLIB)>>
+<<LIECAT.NRLIB (NRLIB from MID)>>
+<<LIECAT.spad (SPAD from IN)>>
+
+<<LPOLY.o (O from NRLIB)>>
+<<LPOLY.NRLIB (NRLIB from MID)>>
+<<LPOLY.spad (SPAD from IN)>>
+
+<<LWORD.o (O from NRLIB)>>
+<<LWORD.NRLIB (NRLIB from MID)>>
+<<LWORD.spad (SPAD from IN)>>
+
+<<MAGMA.o (O from NRLIB)>>
+<<MAGMA.NRLIB (NRLIB from MID)>>
+<<MAGMA.spad (SPAD from IN)>>
+
+<<PBWLB.o (O from NRLIB)>>
+<<PBWLB.NRLIB (NRLIB from MID)>>
+<<PBWLB.spad (SPAD from IN)>>
+
+<<XEXPPKG.o (O from NRLIB)>>
+<<XEXPPKG.NRLIB (NRLIB from MID)>>
+<<XEXPPKG.spad (SPAD from IN)>>
+
+<<XPBWPOLY.o (O from NRLIB)>>
+<<XPBWPOLY.NRLIB (NRLIB from MID)>>
+<<XPBWPOLY.spad (SPAD from IN)>>
+
+<<xlpoly.spad (SPAD from IN)>>
+<<xlpoly.spad.dvi (DOC from IN)>>
+
+<<FMCAT.o (O from NRLIB)>>
+<<FMCAT.NRLIB (NRLIB from MID)>>
+<<FMCAT.spad (SPAD from IN)>>
+
+<<FM1.o (O from NRLIB)>>
+<<FM1.NRLIB (NRLIB from MID)>>
+<<FM1.spad (SPAD from IN)>>
+
+<<OFMONOID.o (O from NRLIB)>>
+<<OFMONOID.NRLIB (NRLIB from MID)>>
+<<OFMONOID.spad (SPAD from IN)>>
+
+<<XALG.o (O from NRLIB)>>
+<<XALG.NRLIB (NRLIB from MID)>>
+<<XALG.spad (SPAD from IN)>>
+
+<<XDPOLY.o (O from NRLIB)>>
+<<XDPOLY.NRLIB (NRLIB from MID)>>
+<<XDPOLY.spad (SPAD from IN)>>
+
+<<XFALG.o (O from NRLIB)>>
+<<XFALG.NRLIB (NRLIB from MID)>>
+<<XFALG.spad (SPAD from IN)>>
+
+<<XPOLY.o (O from NRLIB)>>
+<<XPOLY.NRLIB (NRLIB from MID)>>
+<<XPOLY.spad (SPAD from IN)>>
+
+<<XPOLYC.o (O from NRLIB)>>
+<<XPOLYC.NRLIB (NRLIB from MID)>>
+<<XPOLYC.spad (SPAD from IN)>>
+
+<<XPR.o (O from NRLIB)>>
+<<XPR.NRLIB (NRLIB from MID)>>
+<<XPR.spad (SPAD from IN)>>
+
+<<XRPOLY.o (O from NRLIB)>>
+<<XRPOLY.NRLIB (NRLIB from MID)>>
+<<XRPOLY.spad (SPAD from IN)>>
+
+<<xpoly.spad (SPAD from IN)>>
+<<xpoly.spad.dvi (DOC from IN)>>
+
+<<YSTREAM.o (O from NRLIB)>>
+<<YSTREAM.NRLIB (NRLIB from MID)>>
+<<YSTREAM.spad (SPAD from IN)>>
+
+<<ystream.spad (SPAD from IN)>>
+<<ystream.spad.dvi (DOC from IN)>>
+
+<<FGLMICPK.o (O from NRLIB)>>
+<<FGLMICPK.NRLIB (NRLIB from MID)>>
+<<FGLMICPK.spad (SPAD from IN)>>
+
+<<zerodim.spad (SPAD from IN)>>
+<<zerodim.spad.dvi (DOC from IN)>>
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/Makefile.in b/src/algebra/Makefile.in
new file mode 100644
index 00000000..ff37dad4
--- /dev/null
+++ b/src/algebra/Makefile.in
@@ -0,0 +1,1151 @@
+
+IN=$(srcdir)
+OUT=$(axiom_targetdir)/algebra
+DOC=$(axiom_target_docdir)/src/algebra
+OUTSRC=$(axiom_target_srcdir)/algebra
+INPUT=../input
+
+EXTRACT_BOOTSTRAP_FILE = \
+ $(axiom_build_document) --output=$@ --tangle="$@ BOOTSTRAP" $<
+
+
+DEPSYS= ../interp/depsys$(EXEEXT)
+
+
+INTERPSYS = \
+ AXIOM="$(AXIOM)" \
+ DAASE="$(axiom_src_datadir)" \
+ ../interp/interpsys$(EXEEXT)
+
+
+SPADFILES= \
+ ${OUTSRC}/acplot.spad ${OUTSRC}/aggcat2.spad ${OUTSRC}/aggcat.spad \
+ ${OUTSRC}/algcat.spad ${OUTSRC}/algext.spad ${OUTSRC}/algfact.spad \
+ ${OUTSRC}/algfunc.spad ${OUTSRC}/allfact.spad ${OUTSRC}/alql.spad \
+ ${OUTSRC}/annacat.spad ${OUTSRC}/any.spad ${OUTSRC}/array1.spad \
+ ${OUTSRC}/array2.spad ${OUTSRC}/asp.spad ${OUTSRC}/attreg.spad \
+ ${OUTSRC}/bags.spad ${OUTSRC}/bezout.spad ${OUTSRC}/boolean.spad \
+ ${OUTSRC}/brill.spad \
+ ${OUTSRC}/c02.spad ${OUTSRC}/c05.spad ${OUTSRC}/c06.spad \
+ ${OUTSRC}/card.spad ${OUTSRC}/carten.spad ${OUTSRC}/catdef.spad \
+ ${OUTSRC}/cden.spad ${OUTSRC}/clifford.spad ${OUTSRC}/clip.spad \
+ ${OUTSRC}/cmplxrt.spad ${OUTSRC}/coerce.spad ${OUTSRC}/color.spad \
+ ${OUTSRC}/combfunc.spad ${OUTSRC}/combinat.spad ${OUTSRC}/complet.spad \
+ ${OUTSRC}/constant.spad ${OUTSRC}/contfrac.spad ${OUTSRC}/cont.spad \
+ ${OUTSRC}/coordsys.spad ${OUTSRC}/cra.spad ${OUTSRC}/crfp.spad \
+ ${OUTSRC}/curve.spad ${OUTSRC}/cycles.spad ${OUTSRC}/cyclotom.spad \
+ ${OUTSRC}/d01agents.spad ${OUTSRC}/d01Package.spad \
+ ${OUTSRC}/d01routine.spad ${OUTSRC}/d01.spad ${OUTSRC}/d01transform.spad \
+ ${OUTSRC}/d01weights.spad ${OUTSRC}/d02agents.spad \
+ ${OUTSRC}/d02Package.spad ${OUTSRC}/d02routine.spad ${OUTSRC}/d02.spad \
+ ${OUTSRC}/d03agents.spad ${OUTSRC}/d03Package.spad \
+ ${OUTSRC}/d03routine.spad ${OUTSRC}/d03.spad ${OUTSRC}/ddfact.spad \
+ ${OUTSRC}/defaults.spad ${OUTSRC}/defintef.spad ${OUTSRC}/defintrf.spad \
+ ${OUTSRC}/degred.spad ${OUTSRC}/derham.spad ${OUTSRC}/dhmatrix.spad \
+ ${OUTSRC}/divisor.spad ${OUTSRC}/dpolcat.spad ${OUTSRC}/drawopt.spad \
+ ${OUTSRC}/drawpak.spad ${OUTSRC}/draw.spad \
+ ${OUTSRC}/e01.spad ${OUTSRC}/e02.spad ${OUTSRC}/e04agents.spad \
+ ${OUTSRC}/e04Package.spad ${OUTSRC}/e04routine.spad ${OUTSRC}/e04.spad \
+ ${OUTSRC}/efstruc.spad ${OUTSRC}/efuls.spad ${OUTSRC}/efupxs.spad \
+ ${OUTSRC}/eigen.spad ${OUTSRC}/elemntry.spad ${OUTSRC}/elfuts.spad \
+ ${OUTSRC}/equation1.spad ${OUTSRC}/equation2.spad ${OUTSRC}/error.spad \
+ ${OUTSRC}/expexpan.spad ${OUTSRC}/expr2ups.spad \
+ ${OUTSRC}/exprode.spad ${OUTSRC}/expr.spad \
+ ${OUTSRC}/f01.spad ${OUTSRC}/f02.spad ${OUTSRC}/f04.spad \
+ ${OUTSRC}/f07.spad ${OUTSRC}/facutil.spad ${OUTSRC}/ffcat.spad \
+ ${OUTSRC}/ffcg.spad ${OUTSRC}/fff.spad ${OUTSRC}/ffhom.spad \
+ ${OUTSRC}/ffnb.spad ${OUTSRC}/ffpoly2.spad ${OUTSRC}/ffpoly.spad \
+ ${OUTSRC}/ffp.spad ${OUTSRC}/ffx.spad \
+ ${OUTSRC}/files.spad ${OUTSRC}/float.spad ${OUTSRC}/fmod.spad \
+ ${OUTSRC}/fname.spad ${OUTSRC}/fnla.spad ${OUTSRC}/formula.spad \
+ ${OUTSRC}/fortcat.spad ${OUTSRC}/fortmac.spad ${OUTSRC}/fortpak.spad \
+ ${OUTSRC}/fortran.spad ${OUTSRC}/forttyp.spad ${OUTSRC}/fourier.spad \
+ ${OUTSRC}/fparfrac.spad ${OUTSRC}/fraction.spad ${OUTSRC}/free.spad \
+ ${OUTSRC}/fr.spad ${OUTSRC}/fs2expxp.spad ${OUTSRC}/fs2ups.spad \
+ ${OUTSRC}/fspace.spad ${OUTSRC}/funcpkgs.spad ${OUTSRC}/functions.spad \
+ ${OUTSRC}/galfact.spad ${OUTSRC}/galfactu.spad ${OUTSRC}/galpolyu.spad \
+ ${OUTSRC}/galutil.spad ${OUTSRC}/gaussfac.spad ${OUTSRC}/gaussian.spad \
+ ${OUTSRC}/gbeuclid.spad ${OUTSRC}/gbintern.spad ${OUTSRC}/gb.spad \
+ ${OUTSRC}/gdirprod.spad ${OUTSRC}/gdpoly.spad ${OUTSRC}/geneez.spad \
+ ${OUTSRC}/generic.spad ${OUTSRC}/genufact.spad ${OUTSRC}/genups.spad \
+ ${OUTSRC}/ghensel.spad ${OUTSRC}/gpgcd.spad ${OUTSRC}/gpol.spad \
+ ${OUTSRC}/grdef.spad ${OUTSRC}/groebf.spad ${OUTSRC}/groebsol.spad \
+ ${OUTSRC}/gseries.spad \
+ ${OUTSRC}/ideal.spad ${OUTSRC}/idecomp.spad ${OUTSRC}/indexedp.spad \
+ ${OUTSRC}/infprod.spad ${OUTSRC}/intaf.spad ${OUTSRC}/intalg.spad \
+ ${OUTSRC}/intaux.spad ${OUTSRC}/intclos.spad ${OUTSRC}/intef.spad \
+ ${OUTSRC}/integer.spad ${OUTSRC}/integrat.spad \
+ ${OUTSRC}/interval.spad \
+ ${OUTSRC}/intfact.spad ${OUTSRC}/intpm.spad \
+ ${OUTSRC}/intrf.spad \
+ ${OUTSRC}/irexpand.spad \
+ ${OUTSRC}/irsn.spad ${OUTSRC}/ituple.spad \
+ ${OUTSRC}/kl.spad ${OUTSRC}/kovacic.spad \
+ ${OUTSRC}/laplace.spad ${OUTSRC}/laurent.spad ${OUTSRC}/leadcdet.spad \
+ ${OUTSRC}/lie.spad ${OUTSRC}/limitps.spad ${OUTSRC}/lindep.spad \
+ ${OUTSRC}/lingrob.spad ${OUTSRC}/liouv.spad ${OUTSRC}/listgcd.spad \
+ ${OUTSRC}/list.spad ${OUTSRC}/lmdict.spad ${OUTSRC}/lodof.spad \
+ ${OUTSRC}/lodop.spad ${OUTSRC}/lodo.spad \
+ ${OUTSRC}/manip.spad ${OUTSRC}/mappkg.spad ${OUTSRC}/matcat.spad \
+ ${OUTSRC}/matfuns.spad ${OUTSRC}/matrix.spad ${OUTSRC}/matstor.spad \
+ ${OUTSRC}/mesh.spad ${OUTSRC}/mfinfact.spad ${OUTSRC}/misc.spad \
+ ${OUTSRC}/mkfunc.spad ${OUTSRC}/mkrecord.spad \
+ ${OUTSRC}/mlift.spad ${OUTSRC}/moddfact.spad ${OUTSRC}/modgcd.spad \
+ ${OUTSRC}/modmonom.spad ${OUTSRC}/modmon.spad ${OUTSRC}/modring.spad \
+ ${OUTSRC}/moebius.spad ${OUTSRC}/mring.spad ${OUTSRC}/mset.spad \
+ ${OUTSRC}/mts.spad ${OUTSRC}/multfact.spad ${OUTSRC}/multpoly.spad \
+ ${OUTSRC}/multsqfr.spad \
+ ${OUTSRC}/naalgc.spad ${OUTSRC}/naalg.spad \
+ ${OUTSRC}/newdata.spad ${OUTSRC}/newpoint.spad \
+ ${OUTSRC}/newpoly.spad ${OUTSRC}/nlinsol.spad ${OUTSRC}/nlode.spad \
+ ${OUTSRC}/npcoef.spad \
+ ${OUTSRC}/nregset.spad \
+ ${OUTSRC}/nsregset.spad ${OUTSRC}/numeigen.spad ${OUTSRC}/numeric.spad \
+ ${OUTSRC}/numode.spad ${OUTSRC}/numquad.spad ${OUTSRC}/numsolve.spad \
+ ${OUTSRC}/numtheor.spad \
+ ${OUTSRC}/oct.spad ${OUTSRC}/odealg.spad ${OUTSRC}/odeef.spad \
+ ${OUTSRC}/oderf.spad ${OUTSRC}/omcat.spad ${OUTSRC}/omdev.spad \
+ ${OUTSRC}/omerror.spad ${OUTSRC}/omserver.spad ${OUTSRC}/opalg.spad \
+ ${OUTSRC}/openmath.spad ${OUTSRC}/op.spad ${OUTSRC}/ore.spad \
+ ${OUTSRC}/outform.spad ${OUTSRC}/out.spad \
+ ${OUTSRC}/pade.spad ${OUTSRC}/padiclib.spad ${OUTSRC}/padic.spad \
+ ${OUTSRC}/paramete.spad ${OUTSRC}/partperm.spad ${OUTSRC}/patmatch1.spad \
+ ${OUTSRC}/patmatch2.spad ${OUTSRC}/pattern.spad ${OUTSRC}/pcurve.spad \
+ ${OUTSRC}/pdecomp.spad ${OUTSRC}/perman.spad ${OUTSRC}/permgrps.spad \
+ ${OUTSRC}/perm.spad ${OUTSRC}/pfbr.spad ${OUTSRC}/pfo.spad \
+ ${OUTSRC}/pfr.spad ${OUTSRC}/pf.spad ${OUTSRC}/pgcd.spad \
+ ${OUTSRC}/pgrobner.spad ${OUTSRC}/pinterp.spad ${OUTSRC}/pleqn.spad \
+ ${OUTSRC}/plot3d.spad ${OUTSRC}/plot.spad ${OUTSRC}/plottool.spad \
+ ${OUTSRC}/polset.spad ${OUTSRC}/poltopol.spad ${OUTSRC}/polycat.spad \
+ ${OUTSRC}/poly.spad ${OUTSRC}/primelt.spad ${OUTSRC}/print.spad \
+ ${OUTSRC}/product.spad ${OUTSRC}/prs.spad ${OUTSRC}/prtition.spad \
+ ${OUTSRC}/pscat.spad ${OUTSRC}/pseudolin.spad ${OUTSRC}/ptranfn.spad \
+ ${OUTSRC}/puiseux.spad \
+ ${OUTSRC}/qalgset.spad ${OUTSRC}/quat.spad \
+ ${OUTSRC}/radeigen.spad ${OUTSRC}/radix.spad ${OUTSRC}/random.spad \
+ ${OUTSRC}/ratfact.spad ${OUTSRC}/rdeef.spad ${OUTSRC}/rderf.spad \
+ ${OUTSRC}/rdesys.spad ${OUTSRC}/real0q.spad ${OUTSRC}/realzero.spad \
+ ${OUTSRC}/reclos.spad ${OUTSRC}/regset.spad ${OUTSRC}/rep1.spad \
+ ${OUTSRC}/rep2.spad ${OUTSRC}/resring.spad ${OUTSRC}/retract.spad \
+ ${OUTSRC}/rf.spad ${OUTSRC}/riccati.spad ${OUTSRC}/rinterp.spad \
+ ${OUTSRC}/routines.spad \
+ ${OUTSRC}/rule.spad \
+ ${OUTSRC}/seg.spad ${OUTSRC}/setorder.spad ${OUTSRC}/sets.spad \
+ ${OUTSRC}/sex.spad ${OUTSRC}/sf.spad ${OUTSRC}/sgcf.spad \
+ ${OUTSRC}/sign.spad ${OUTSRC}/si.spad ${OUTSRC}/smith.spad \
+ ${OUTSRC}/solvedio.spad ${OUTSRC}/solvefor.spad ${OUTSRC}/solvelin.spad \
+ ${OUTSRC}/solverad.spad ${OUTSRC}/sortpak.spad ${OUTSRC}/space.spad \
+ ${OUTSRC}/special.spad ${OUTSRC}/sregset.spad ${OUTSRC}/s.spad \
+ ${OUTSRC}/stream.spad ${OUTSRC}/string.spad ${OUTSRC}/sttaylor.spad \
+ ${OUTSRC}/sttf.spad ${OUTSRC}/sturm.spad ${OUTSRC}/suchthat.spad \
+ ${OUTSRC}/suls.spad ${OUTSRC}/sum.spad ${OUTSRC}/sups.spad \
+ ${OUTSRC}/supxs.spad ${OUTSRC}/suts.spad ${OUTSRC}/symbol.spad \
+ ${OUTSRC}/syssolp.spad ${OUTSRC}/system.spad \
+ ${OUTSRC}/tableau.spad ${OUTSRC}/table.spad ${OUTSRC}/taylor.spad \
+ ${OUTSRC}/tex.spad ${OUTSRC}/tools.spad ${OUTSRC}/transsolve.spad \
+ ${OUTSRC}/tree.spad ${OUTSRC}/trigcat.spad ${OUTSRC}/triset.spad \
+ ${OUTSRC}/tube.spad ${OUTSRC}/twofact.spad \
+ ${OUTSRC}/unifact.spad ${OUTSRC}/updecomp.spad ${OUTSRC}/updivp.spad \
+ ${OUTSRC}/utsode.spad \
+ ${OUTSRC}/variable.spad ${OUTSRC}/vector.spad ${OUTSRC}/view2D.spad \
+ ${OUTSRC}/view3D.spad ${OUTSRC}/viewDef.spad ${OUTSRC}/viewpack.spad \
+ ${OUTSRC}/void.spad \
+ ${OUTSRC}/weier.spad ${OUTSRC}/wtpol.spad \
+ ${OUTSRC}/xlpoly.spad ${OUTSRC}/xpoly.spad \
+ ${OUTSRC}/ystream.spad \
+ ${OUTSRC}/zerodim.spad
+
+
+ALDORFILES= \
+ axtimer.as \
+ ffrac.as \
+ herm.as \
+ interval.as \
+ invnode.as \
+ invrender.as \
+ invtypes.as \
+ invutils.as \
+ iviews.as \
+ ndftip.as \
+ nepip.as \
+ noptip.as nqip.as \
+ nrc.as nsfip.as
+
+
+DOCFILES= \
+ ${DOC}/acplot.spad.dvi ${DOC}/aggcat2.spad.dvi ${DOC}/aggcat.spad.dvi \
+ ${DOC}/algcat.spad.dvi ${DOC}/algext.spad.dvi ${DOC}/algfact.spad.dvi \
+ ${DOC}/algfunc.spad.dvi ${DOC}/allfact.spad.dvi ${DOC}/alql.spad.dvi \
+ ${DOC}/annacat.spad.dvi ${DOC}/any.spad.dvi ${DOC}/array1.spad.dvi \
+ ${DOC}/array2.spad.dvi ${DOC}/asp.spad.dvi ${DOC}/attreg.spad.dvi \
+ ${DOC}/axtimer.as.dvi \
+ ${DOC}/bags.spad.dvi ${DOC}/bezout.spad.dvi ${DOC}/boolean.spad.dvi \
+ ${DOC}/brill.spad.dvi \
+ ${DOC}/c02.spad.dvi ${DOC}/c05.spad.dvi ${DOC}/c06.spad.dvi \
+ ${DOC}/card.spad.dvi ${DOC}/carten.spad.dvi ${DOC}/catdef.spad.dvi \
+ ${DOC}/cden.spad.dvi ${DOC}/clifford.spad.dvi ${DOC}/clip.spad.dvi \
+ ${DOC}/cmplxrt.spad.dvi ${DOC}/coerce.spad.dvi ${DOC}/color.spad.dvi \
+ ${DOC}/combfunc.spad.dvi ${DOC}/combinat.spad.dvi ${DOC}/complet.spad.dvi \
+ ${DOC}/constant.spad.dvi ${DOC}/contfrac.spad.dvi ${DOC}/cont.spad.dvi \
+ ${DOC}/coordsys.spad.dvi ${DOC}/cra.spad.dvi ${DOC}/crfp.spad.dvi \
+ ${DOC}/curve.spad.dvi ${DOC}/cycles.spad.dvi ${DOC}/cyclotom.spad.dvi \
+ ${DOC}/d01agents.spad.dvi ${DOC}/d01Package.spad.dvi \
+ ${DOC}/d01routine.spad.dvi ${DOC}/d01.spad.dvi ${DOC}/d01transform.spad.dvi \
+ ${DOC}/d01weights.spad.dvi ${DOC}/d02agents.spad.dvi \
+ ${DOC}/d02Package.spad.dvi ${DOC}/d02routine.spad.dvi ${DOC}/d02.spad.dvi \
+ ${DOC}/d03agents.spad.dvi ${DOC}/d03Package.spad.dvi \
+ ${DOC}/d03routine.spad.dvi ${DOC}/d03.spad.dvi ${DOC}/ddfact.spad.dvi \
+ ${DOC}/defaults.spad.dvi ${DOC}/defintef.spad.dvi ${DOC}/defintrf.spad.dvi \
+ ${DOC}/degred.spad.dvi ${DOC}/derham.spad.dvi ${DOC}/dhmatrix.spad.dvi \
+ ${DOC}/divisor.spad.dvi ${DOC}/dpolcat.spad.dvi ${DOC}/drawopt.spad.dvi \
+ ${DOC}/drawpak.spad.dvi ${DOC}/draw.spad.dvi \
+ ${DOC}/e01.spad.dvi ${DOC}/e02.spad.dvi ${DOC}/e04agents.spad.dvi \
+ ${DOC}/e04Package.spad.dvi ${DOC}/e04routine.spad.dvi ${DOC}/e04.spad.dvi \
+ ${DOC}/efstruc.spad.dvi ${DOC}/efuls.spad.dvi ${DOC}/efupxs.spad.dvi \
+ ${DOC}/eigen.spad.dvi ${DOC}/elemntry.spad.dvi ${DOC}/elfuts.spad.dvi \
+ ${DOC}/equation1.spad.dvi ${DOC}/equation2.spad.dvi ${DOC}/error.spad.dvi \
+ ${DOC}/expexpan.spad.dvi ${DOC}/exposed.lsp.dvi ${DOC}/expr2ups.spad.dvi \
+ ${DOC}/exprode.spad.dvi ${DOC}/expr.spad.dvi \
+ ${DOC}/f01.spad.dvi ${DOC}/f02.spad.dvi ${DOC}/f04.spad.dvi \
+ ${DOC}/f07.spad.dvi ${DOC}/facutil.spad.dvi ${DOC}/ffcat.spad.dvi \
+ ${DOC}/ffcg.spad.dvi ${DOC}/fff.spad.dvi ${DOC}/ffhom.spad.dvi \
+ ${DOC}/ffnb.spad.dvi ${DOC}/ffpoly2.spad.dvi ${DOC}/ffpoly.spad.dvi \
+ ${DOC}/ffp.spad.dvi ${DOC}/ffrac.as.dvi ${DOC}/ffx.spad.dvi \
+ ${DOC}/files.spad.dvi ${DOC}/float.spad.dvi ${DOC}/fmod.spad.dvi \
+ ${DOC}/fname.spad.dvi ${DOC}/fnla.spad.dvi ${DOC}/formula.spad.dvi \
+ ${DOC}/fortcat.spad.dvi ${DOC}/fortmac.spad.dvi ${DOC}/fortpak.spad.dvi \
+ ${DOC}/fortran.spad.dvi ${DOC}/forttyp.spad.dvi ${DOC}/fourier.spad.dvi \
+ ${DOC}/fparfrac.spad.dvi ${DOC}/fraction.spad.dvi ${DOC}/free.spad.dvi \
+ ${DOC}/fr.spad.dvi ${DOC}/fs2expxp.spad.dvi ${DOC}/fs2ups.spad.dvi \
+ ${DOC}/fspace.spad.dvi ${DOC}/funcpkgs.spad.dvi ${DOC}/functions.spad.dvi \
+ ${DOC}/galfact.spad.dvi ${DOC}/galfactu.spad.dvi ${DOC}/galpolyu.spad.dvi \
+ ${DOC}/galutil.spad.dvi ${DOC}/gaussfac.spad.dvi ${DOC}/gaussian.spad.dvi \
+ ${DOC}/gbeuclid.spad.dvi ${DOC}/gbintern.spad.dvi ${DOC}/gb.spad.dvi \
+ ${DOC}/gdirprod.spad.dvi ${DOC}/gdpoly.spad.dvi ${DOC}/geneez.spad.dvi \
+ ${DOC}/generic.spad.dvi ${DOC}/genufact.spad.dvi ${DOC}/genups.spad.dvi \
+ ${DOC}/ghensel.spad.dvi ${DOC}/gpgcd.spad.dvi ${DOC}/gpol.spad.dvi \
+ ${DOC}/grdef.spad.dvi ${DOC}/groebf.spad.dvi ${DOC}/groebsol.spad.dvi \
+ ${DOC}/gseries.spad.dvi \
+ ${DOC}/herm.as.dvi \
+ ${DOC}/ideal.spad.dvi ${DOC}/idecomp.spad.dvi ${DOC}/indexedp.spad.dvi \
+ ${DOC}/infprod.spad.dvi ${DOC}/intaf.spad.dvi ${DOC}/intalg.spad.dvi \
+ ${DOC}/intaux.spad.dvi ${DOC}/intclos.spad.dvi ${DOC}/intef.spad.dvi \
+ ${DOC}/integer.spad.dvi ${DOC}/integrat.spad.dvi \
+ ${DOC}/interval.as.dvi ${DOC}/interval.spad.dvi \
+ ${DOC}/intfact.spad.dvi ${DOC}/intpm.spad.dvi \
+ ${DOC}/intrf.spad.dvi ${DOC}/invnode.as.dvi ${DOC}/invrender.as.dvi \
+ ${DOC}/invtypes.as.dvi ${DOC}/invutils.as.dvi ${DOC}/irexpand.spad.dvi \
+ ${DOC}/irsn.spad.dvi ${DOC}/ituple.spad.dvi ${DOC}/iviews.as.dvi \
+ ${DOC}/kl.spad.dvi ${DOC}/kovacic.spad.dvi \
+ ${DOC}/laplace.spad.dvi ${DOC}/laurent.spad.dvi ${DOC}/leadcdet.spad.dvi \
+ ${DOC}/lie.spad.dvi ${DOC}/limitps.spad.dvi ${DOC}/lindep.spad.dvi \
+ ${DOC}/lingrob.spad.dvi ${DOC}/liouv.spad.dvi ${DOC}/listgcd.spad.dvi \
+ ${DOC}/list.spad.dvi ${DOC}/lmdict.spad.dvi ${DOC}/lodof.spad.dvi \
+ ${DOC}/lodop.spad.dvi ${DOC}/lodo.spad.dvi \
+ ${DOC}/manip.spad.dvi ${DOC}/mappkg.spad.dvi ${DOC}/matcat.spad.dvi \
+ ${DOC}/matfuns.spad.dvi ${DOC}/matrix.spad.dvi ${DOC}/matstor.spad.dvi \
+ ${DOC}/mesh.spad.dvi ${DOC}/mfinfact.spad.dvi ${DOC}/misc.spad.dvi \
+ ${DOC}/mkfunc.spad.dvi ${DOC}/mkrecord.spad.dvi ${DOC}/mlift.spad.jhd.dvi \
+ ${DOC}/mlift.spad.dvi ${DOC}/moddfact.spad.dvi ${DOC}/modgcd.spad.dvi \
+ ${DOC}/modmonom.spad.dvi ${DOC}/modmon.spad.dvi ${DOC}/modring.spad.dvi \
+ ${DOC}/moebius.spad.dvi ${DOC}/mring.spad.dvi ${DOC}/mset.spad.dvi \
+ ${DOC}/mts.spad.dvi ${DOC}/multfact.spad.dvi ${DOC}/multpoly.spad.dvi \
+ ${DOC}/multsqfr.spad.dvi \
+ ${DOC}/naalgc.spad.dvi ${DOC}/naalg.spad.dvi ${DOC}/ndftip.as.dvi \
+ ${DOC}/nepip.as.dvi ${DOC}/newdata.spad.dvi ${DOC}/newpoint.spad.dvi \
+ ${DOC}/newpoly.spad.dvi ${DOC}/nlinsol.spad.dvi ${DOC}/nlode.spad.dvi \
+ ${DOC}/noptip.as.dvi ${DOC}/npcoef.spad.dvi ${DOC}/nqip.as.dvi \
+ ${DOC}/nrc.as.dvi ${DOC}/nregset.spad.dvi ${DOC}/nsfip.as.dvi \
+ ${DOC}/nsregset.spad.dvi ${DOC}/numeigen.spad.dvi ${DOC}/numeric.spad.dvi \
+ ${DOC}/numode.spad.dvi ${DOC}/numquad.spad.dvi ${DOC}/numsolve.spad.dvi \
+ ${DOC}/numtheor.spad.dvi \
+ ${DOC}/oct.spad.dvi ${DOC}/odealg.spad.dvi ${DOC}/odeef.spad.dvi \
+ ${DOC}/oderf.spad.dvi ${DOC}/omcat.spad.dvi ${DOC}/omdev.spad.dvi \
+ ${DOC}/omerror.spad.dvi ${DOC}/omserver.spad.dvi ${DOC}/opalg.spad.dvi \
+ ${DOC}/openmath.spad.dvi ${DOC}/op.spad.dvi ${DOC}/ore.spad.dvi \
+ ${DOC}/outform.spad.dvi ${DOC}/out.spad.dvi \
+ ${DOC}/pade.spad.dvi ${DOC}/padiclib.spad.dvi ${DOC}/padic.spad.dvi \
+ ${DOC}/paramete.spad.dvi ${DOC}/partperm.spad.dvi ${DOC}/patmatch1.spad.dvi \
+ ${DOC}/patmatch2.spad.dvi ${DOC}/pattern.spad.dvi ${DOC}/pcurve.spad.dvi \
+ ${DOC}/pdecomp.spad.dvi ${DOC}/perman.spad.dvi ${DOC}/permgrps.spad.dvi \
+ ${DOC}/perm.spad.dvi ${DOC}/pfbr.spad.dvi ${DOC}/pfo.spad.dvi \
+ ${DOC}/pfr.spad.dvi ${DOC}/pf.spad.dvi ${DOC}/pgcd.spad.dvi \
+ ${DOC}/pgrobner.spad.dvi ${DOC}/pinterp.spad.dvi ${DOC}/pleqn.spad.dvi \
+ ${DOC}/plot3d.spad.dvi ${DOC}/plot.spad.dvi ${DOC}/plottool.spad.dvi \
+ ${DOC}/polset.spad.dvi ${DOC}/poltopol.spad.dvi ${DOC}/polycat.spad.dvi \
+ ${DOC}/poly.spad.dvi ${DOC}/primelt.spad.dvi ${DOC}/print.spad.dvi \
+ ${DOC}/product.spad.dvi ${DOC}/prs.spad.dvi ${DOC}/prtition.spad.dvi \
+ ${DOC}/pscat.spad.dvi ${DOC}/pseudolin.spad.dvi ${DOC}/ptranfn.spad.dvi \
+ ${DOC}/puiseux.spad.dvi \
+ ${DOC}/qalgset.spad.dvi ${DOC}/quat.spad.dvi \
+ ${DOC}/radeigen.spad.dvi ${DOC}/radix.spad.dvi ${DOC}/random.spad.dvi \
+ ${DOC}/ratfact.spad.dvi ${DOC}/rdeef.spad.dvi ${DOC}/rderf.spad.dvi \
+ ${DOC}/rdesys.spad.dvi ${DOC}/real0q.spad.dvi ${DOC}/realzero.spad.dvi \
+ ${DOC}/reclos.spad.dvi ${DOC}/regset.spad.dvi ${DOC}/rep1.spad.dvi \
+ ${DOC}/rep2.spad.dvi ${DOC}/resring.spad.dvi ${DOC}/retract.spad.dvi \
+ ${DOC}/rf.spad.dvi ${DOC}/riccati.spad.dvi ${DOC}/rinterp.spad.dvi \
+ ${DOC}/routines.spad.dvi \
+ ${DOC}/rule.spad.dvi \
+ ${DOC}/seg.spad.dvi ${DOC}/setorder.spad.dvi ${DOC}/sets.spad.dvi \
+ ${DOC}/sex.spad.dvi ${DOC}/sf.spad.dvi ${DOC}/sgcf.spad.dvi \
+ ${DOC}/sign.spad.dvi ${DOC}/si.spad.dvi ${DOC}/smith.spad.dvi \
+ ${DOC}/solvedio.spad.dvi ${DOC}/solvefor.spad.dvi ${DOC}/solvelin.spad.dvi \
+ ${DOC}/solverad.spad.dvi ${DOC}/sortpak.spad.dvi ${DOC}/space.spad.dvi \
+ ${DOC}/special.spad.dvi ${DOC}/sregset.spad.dvi ${DOC}/s.spad.dvi \
+ ${DOC}/stream.spad.dvi ${DOC}/string.spad.dvi ${DOC}/sttaylor.spad.dvi \
+ ${DOC}/sttf.spad.dvi ${DOC}/sturm.spad.dvi ${DOC}/suchthat.spad.dvi \
+ ${DOC}/suls.spad.dvi ${DOC}/sum.spad.dvi ${DOC}/sups.spad.dvi \
+ ${DOC}/supxs.spad.dvi ${DOC}/suts.spad.dvi ${DOC}/symbol.spad.dvi \
+ ${DOC}/syssolp.spad.dvi ${DOC}/system.spad.dvi \
+ ${DOC}/tableau.spad.dvi ${DOC}/table.spad.dvi ${DOC}/taylor.spad.dvi \
+ ${DOC}/tex.spad.dvi ${DOC}/tools.spad.dvi ${DOC}/transsolve.spad.dvi \
+ ${DOC}/tree.spad.dvi ${DOC}/trigcat.spad.dvi ${DOC}/triset.spad.dvi \
+ ${DOC}/tube.spad.dvi ${DOC}/twofact.spad.dvi \
+ ${DOC}/unifact.spad.dvi ${DOC}/updecomp.spad.dvi ${DOC}/updivp.spad.dvi \
+ ${DOC}/utsode.spad.dvi \
+ ${DOC}/variable.spad.dvi ${DOC}/vector.spad.dvi ${DOC}/view2D.spad.dvi \
+ ${DOC}/view3D.spad.dvi ${DOC}/viewDef.spad.dvi ${DOC}/viewpack.spad.dvi \
+ ${DOC}/void.spad.dvi \
+ ${DOC}/weier.spad.dvi ${DOC}/wtpol.spad.dvi \
+ ${DOC}/xlpoly.spad.dvi ${DOC}/xpoly.spad.dvi \
+ ${DOC}/ystream.spad.dvi \
+ ${DOC}/zerodim.spad.dvi
+
+
+TESTS=${INPUT}/INTHEORY.input ${INPUT}/VIEW2D.input ${INPUT}/TESTFR.input
+
+
+subdir = src/algebra/
+
+# The list of objects necessary to bootstrap the whole algebra library.
+axiom_algebra_layer_strap_objects = \
+ strap/ABELGRP.o strap/ABELGRP-.o strap/ABELMON.o strap/ABELMON-.o \
+ strap/ABELSG.o strap/ABELSG-.o strap/ALAGG.o strap/BOOLEAN.o \
+ strap/CABMON.o strap/CHAR.o strap/CLAGG.o strap/CLAGG-.o \
+ strap/COMRING.o strap/DFLOAT.o strap/DIFRING.o strap/DIFRING-.o \
+ strap/DIVRING.o strap/DIVRING-.o strap/ENTIRER.o strap/ES.o \
+ strap/ES-.o strap/EUCDOM.o strap/EUCDOM-.o strap/FFIELDC.o \
+ strap/FFIELDC-.o strap/FPS.o strap/FPS-.o strap/GCDDOM.o \
+ strap/GCDDOM-.o strap/HOAGG.o strap/HOAGG-.o strap/ILIST.o \
+ strap/INS.o strap/INS-.o strap/INT.o strap/INTDOM.o \
+ strap/INTDOM-.o strap/ISTRING.o strap/LIST.o strap/LNAGG.o \
+ strap/LNAGG-.o strap/LSAGG.o strap/LSAGG-.o strap/MONOID.o \
+ strap/MONOID-.o strap/MTSCAT.o strap/NNI.o strap/OINTDOM.o \
+ strap/ORDRING.o strap/ORDRING-.o strap/OUTFORM.o strap/PI.o \
+ strap/PRIMARR.o strap/POLYCAT.o strap/POLYCAT-.o strap/PSETCAT.o \
+ strap/PSETCAT-.o strap/QFCAT.o strap/QFCAT-.o strap/RCAGG.o \
+ strap/RCAGG-.o strap/REF.o strap/RING.o strap/RING-.o \
+ strap/RNG.o strap/RNS.o strap/RNS-.o strap/SETAGG.o \
+ strap/SETAGG-.o strap/SETCAT.o strap/SETCAT-.o strap/SINT.o \
+ strap/STAGG.o strap/STAGG-.o strap/SYMBOL.o strap/TSETCAT.o \
+ strap/TSETCAT-.o strap/UFD.o strap/UFD-.o strap/ULSCAT.o \
+ strap/UPOLYC.o strap/UPOLYC-.o strap/URAGG.o strap/URAGG-.o \
+ strap/VECTOR.o
+
+
+axiom_algebra_bootstrap = \
+ ABELGRP.o ABELGRP-.o ABELMON.o ABELMON-.o \
+ ABELSG.o ABELSG-.o ALAGG.o BOOLEAN.o \
+ CABMON.o CHAR.o CLAGG.o CLAGG-.o \
+ COMRING.o DFLOAT.o DIFRING.o DIFRING-.o \
+ DIVRING.o DIVRING-.o ENTIRER.o ES.o \
+ ES-.o EUCDOM.o EUCDOM-.o FFIELDC.o \
+ FFIELDC-.o FPS.o FPS-.o GCDDOM.o \
+ GCDDOM-.o HOAGG.o HOAGG-.o ILIST.o \
+ INS.o INS-.o INT.o INTDOM.o \
+ INTDOM-.o ISTRING.o LIST.o LNAGG.o \
+ LNAGG-.o LSAGG.o LSAGG-.o MONOID.o \
+ MONOID-.o MTSCAT.o NNI.o OINTDOM.o \
+ ORDRING.o ORDRING-.o OUTFORM.o PI.o \
+ PRIMARR.o POLYCAT.o POLYCAT-.o PSETCAT.o \
+ PSETCAT-.o QFCAT.o QFCAT-.o RCAGG.o \
+ RCAGG-.o REF.o RING.o RING-.o \
+ RNG.o RNS.o RNS-.o SETAGG.o \
+ SETAGG-.o SETCAT.o SETCAT-.o SINT.o \
+ STAGG.o STAGG-.o SYMBOL.o TSETCAT.o \
+ TSETCAT-.o UFD.o UFD-.o ULSCAT.o \
+ UPOLYC.o UPOLYC-.o URAGG.o URAGG-.o \
+ VECTOR.o
+
+axiom_algebra_bootstrap_nrlibs = \
+ $(axiom_algebra_bootstrap:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_bootstrap_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_bootstrap))
+
+axiom_algebra_layer_0 = \
+ AHYP.o ATTREG.o CFCAT.o ELTAB.o \
+ KOERCE.o KONVERT.o MSYSCMD.o ODEIFTBL.o \
+ OM.o OMCONN.o OMDEV.o OUT.o \
+ PRIMCAT.o PRINT.o PTRANFN.o SPFCAT.o \
+ TYPE.o
+
+axiom_algebra_layer_0_nrlibs = \
+ $(axiom_algebra_layer_0:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_0_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_0))
+axiom_algebra_layer_1 = \
+ ANY1.o COMBOPC.o DROPT1.o EQ2.o \
+ FORTCAT.o ITFUN2.o ITFUN3.o ITUPLE.o \
+ MKBCFUNC.o MKRECORD.o MKUCFUNC.o NONE1.o \
+ PATAB.o PLOT1.o PPCURVE.o PSCURVE.o \
+ REAL.o RESLATC.o RETRACT.o RETRACT-.o \
+ SEGBIND2.o SEGCAT.o STREAM1.o STREAM2.o \
+ STREAM3.o
+
+axiom_algebra_layer_1_nrlibs = \
+ $(axiom_algebra_layer_1:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_1_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_1))
+axiom_algebra_layer_2 = \
+ FMC.o FMFUN.o FORTFN.o FVC.o \
+ FVFUN.o INTRET.o SEGXCAT.o
+
+axiom_algebra_layer_2_nrlibs = \
+ $(axiom_algebra_layer_2:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_2_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_2))
+axiom_algebra_layer_3 = \
+ AGG.o AGG-.o BASTYPE.o BASTYPE-.o \
+ GRDEF.o LIST3.o MKFUNC.o
+
+axiom_algebra_layer_3_nrlibs = \
+ $(axiom_algebra_layer_3:.$(OBJEXT=./NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_3_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_3))
+axiom_algebra_layer_4 = \
+ ANON.o COLOR.o COMM.o COMPPROP.o \
+ ELTAGG.o ELTAGG-.o ESCONT1.o EXIT.o \
+ FAMONC.o FILECAT.o FINITE.o FNCAT.o \
+ FORMULA1.o IDPC.o IEVALAB.o IEVALAB-.o \
+ INTBIT.o LMODULE.o LOGIC.o LOGIC-.o \
+ MAPHACK1.o MAPHACK2.o MAPHACK3.o MAPPKG1.o \
+ MAPPKG2.o MAPPKG3.o MONAD.o MONAD-.o \
+ NIPROB.o NONE.o NUMINT.o ODECAT.o \
+ ODEPROB.o OMENC.o ONECOMP2.o OPTCAT.o \
+ OPTPROB.o ORDSET.o ORDSET-.o PALETTE.o \
+ PARPCURV.o PARPC2.o PARSCURV.o PARSC2.o \
+ PARSURF.o PARSU2.o PATMAB.o PATRES2.o \
+ PATTERN1.o PDECAT.o PDEPROB.o REPSQ.o \
+ REPDB.o RFDIST.o RIDIST.o RMODULE.o \
+ SEXCAT.o SGROUP.o SGROUP-.o SPACEC.o \
+ SPLNODE.o STEP.o SUCH.o TEX1.o \
+ UDVO.o YSTREAM.o
+
+axiom_algebra_layer_4_nrlibs = \
+ $(axiom_algebra_layer_4:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_4_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_4))
+axiom_algebra_layer_5 = \
+ ATRIG.o ATRIG-.o BMODULE.o CACHSET.o \
+ CHARNZ.o CHARZ.o DVARCAT.o DVARCAT-.o \
+ ELEMFUN.o ELEMFUN-.o ESTOOLS2.o EVALAB.o \
+ EVALAB-.o FCOMP.o FEVALAB.o FEVALAB-.o \
+ FPATMAB.o GROUP.o GROUP-.o IDPAM.o \
+ IDPO.o INCRMAPS.o IXAGG.o IXAGG-.o \
+ KERNEL2.o LALG.o LALG-.o LINEXP.o \
+ MODMONOM.o MONADWU.o MONADWU-.o MRF2.o \
+ NARNG.o NARNG-.o NSUP2.o OASGP.o \
+ ODVAR.o OPQUERY.o ORDFIN.o ORDMON.o \
+ PATMATCH.o PERMCAT.o PDRING.o PDRING-.o \
+ SDVAR.o SUP2.o TRIGCAT.o TRIGCAT-.o \
+ ULS2.o UP2.o
+
+axiom_algebra_layer_5_nrlibs = \
+ $(axiom_algebra_layer_5:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_5_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_5))
+axiom_algebra_layer_6 = \
+ AUTOMOR.o BGAGG.o BGAGG-.o BRAGG.o \
+ BRAGG-.o CARTEN2.o CHARPOL.o COMPLEX2.o \
+ DIFEXT.o DIFEXT-.o DLAGG.o ELAGG.o \
+ ELAGG-.o ES1.o ES2.o GRMOD.o \
+ GRMOD-.o HYPCAT.o HYPCAT-.o MKCHSET.o \
+ MODRING.o MODULE.o MODULE-.o NASRING.o \
+ NASRING-.o OAMON.o SORTPAK.o ZMOD.o
+
+axiom_algebra_layer_6_nrlibs = \
+ $(axiom_algebra_layer_6:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_6_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_6))
+axiom_algebra_layer_7 = \
+ ALGEBRA.o ALGEBRA-.o BTCAT.o BTCAT-.o \
+ FMCAT.o IDPOAM.o IFAMON.o GRALG.o \
+ GRALG-.o OCAMON.o PRQAGG.o QUAGG.o \
+ SKAGG.o
+
+axiom_algebra_layer_7_nrlibs = \
+ $(axiom_algebra_layer_7:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_7_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_7))
+axiom_algebra_layer_8 = \
+ BSTREE.o BTOURN.o CARD.o DRAWHACK.o \
+ DQAGG.o FACTFUNC.o FMTC.o FR2.o \
+ FRAC2.o FRUTIL.o ITAYLOR.o MLO.o \
+ NAALG.o NAALG-.o OAGROUP.o OAMONS.o \
+ OP.o ORDCOMP2.o PID.o RANDSRC.o \
+ UNISEG2.o XALG.o
+
+axiom_algebra_layer_8_nrlibs = \
+ $(axiom_algebra_layer_8:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_8_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_8))
+axiom_algebra_layer_9 = \
+ AMR.o AMR-.o DEGRED.o DLP.o \
+ EAB.o ESTOOLS1.o FAGROUP.o FAMONOID.o \
+ FIELD.o FIELD-.o FLAGG.o FLAGG-.o \
+ FLINEXP.o FLINEXP-.o FRETRCT.o FRETRCT-.o \
+ FSERIES.o FT.o IDPAG.o IDPOAMS.o \
+ INFINITY.o LA.o OMLO.o ORTHPOL.o \
+ PRODUCT.o PADICCT.o PMPRED.o PMASS.o \
+ PTFUNC2.o RADCAT.o RADCAT-.o RATRET.o \
+ RADUTIL.o UPXS2.o XFALG.o ZLINDEP.o
+
+axiom_algebra_layer_9_nrlibs = \
+ $(axiom_algebra_layer_9:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_9_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_9))
+axiom_algebra_layer_10 = \
+ A1AGG.o A1AGG-.o ARR2CAT.o ARR2CAT-.o \
+ ASP34.o BBTREE.o BFUNCT.o BPADIC.o \
+ BTREE.o CRAPACK.o DEQUEUE.o DLIST.o \
+ DRAWCX.o D01GBFA.o D02EJFA.o D03FAFA.o \
+ DRAWPT.o FAMR.o FAMR-.o FLASORT.o \
+ FLAGG2.o FGROUP.o FM.o FM1.o \
+ FPC.o FPC-.o FMONOID.o INDE.o \
+ IPADIC.o IROOT.o IR2.o LEXP.o \
+ LIECAT.o LIECAT-.o LIST2.o LIST2MAP.o \
+ LMOPS.o LZSTAGG.o LZSTAGG-.o MAGMA.o \
+ MESH.o MOEBIUS.o MODFIELD.o MODOP.o \
+ MRING.o MTHING.o NCNTFRAC.o NCODIV.o \
+ NUMTUBE.o ODR.o OFMONOID.o ONECOMP.o \
+ ORDCOMP.o OREPCAT.o OREPCAT-.o OWP.o \
+ PADIC.o PATTERN2.o PATLRES.o PARTPERM.o \
+ PBWLB.o PENDTREE.o PGE.o PGROEB.o \
+ PINTERP.o PLOTTOOL.o PFR.o PMDOWN.o \
+ PRTITION.o PMINS.o PMLSAGG.o PMTOOLS.o \
+ PSCAT.o PSCAT-.o QFORM.o QUEUE.o \
+ SCACHE.o SEG.o SEG2.o SEXOF.o \
+ STACK.o STTAYLOR.o TABLBUMP.o TABLEAU.o \
+ TOPSP.o TRANFUN.o TRANFUN-.o TUBE.o \
+ UDPO.o UNISEG.o VIEW.o VSPACE.o \
+ VSPACE-.o XPOLYC.o XPR.o
+
+axiom_algebra_layer_10_nrlibs = \
+ $(axiom_algebra_layer_10:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_10_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_10))
+axiom_algebra_layer_11 = \
+ APPLYORE.o ARRAY1.o ARRAY12.o ARRAY2.o \
+ ASTACK.o BTAGG.o BTAGG-.o COMBINAT.o \
+ CSTTOOLS.o D01FCFA.o E04MBFA.o FARRAY.o \
+ FLALG.o GALUTIL.o HEAP.o IARRAY1.o \
+ IARRAY2.o IFARRAY.o INTCAT.o INTHEORY.o \
+ IRREDFFX.o LFCAT.o LODOCAT.o LODOCAT-.o \
+ LWORD.o MATCAT.o MATCAT-.o MATSTOR.o \
+ ORESUP.o OREPCTO.o OREUP.o PLOT3D.o \
+ PR.o PREASSOC.o PRIMARR2.o REDORDER.o \
+ SRAGG.o SRAGG-.o STREAM.o SYMPOLY.o \
+ TS.o TUPLE.o UPSCAT.o UPSCAT-.o \
+ VECTCAT.o VECTCAT-.o XDPOLY.o XEXPPKG.o \
+ XF.o XF-.o XPBWPOLY.o XPOLY.o \
+ XRPOLY.o
+
+axiom_algebra_layer_11_nrlibs = \
+ $(axiom_algebra_layer_11:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_11_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_11))
+axiom_algebra_layer_12 = \
+ BITS.o DIRPROD2.o IMATRIX.o IVECTOR.o \
+ LPOLY.o LSMP.o LSMP1.o MATCAT2.o \
+ PTCAT.o STRICAT.o TRIMAT.o
+
+axiom_algebra_layer_12_nrlibs = \
+ $(axiom_algebra_layer_12:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_12_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_12))
+axiom_algebra_layer_13 = \
+ ASSOCEQ.o CARTEN.o CLIF.o CLIP.o \
+ COORDSYS.o DBASE.o DHMATRIX.o DIOSP.o \
+ DIRPCAT.o DIRPCAT-.o D02BBFA.o D02BHFA.o \
+ D02CJFA.o FAXF.o FAXF-.o FFPOLY2.o \
+ FNLA.o GRAY.o HB.o IRSN.o \
+ MCALCFN.o MHROWRED.o NUMODE.o NUMQUAD.o \
+ ODESYS.o ODETOOLS.o ORDFUNS.o PERMAN.o \
+ PFECAT.o PFECAT-.o POINT.o PSEUDLIN.o \
+ PTPACK.o REP2.o SETMN.o SEX.o \
+ STRING.o SYMFUNC.o VECTOR2.o
+
+axiom_algebra_layer_13_nrlibs = \
+ $(axiom_algebra_layer_13:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_13_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_13))
+axiom_algebra_layer_14 = \
+ ASP1.o ASP10.o ASP24.o ASP4.o \
+ ASP50.o ASP6.o ASP73.o BALFACT.o \
+ BEZOUT.o BINARY.o BINFILE.o BOUNDZRO.o \
+ BPADICRT.o BRILL.o CDEN.o CHVAR.o \
+ COMMUPC.o CONTFRAC.o CVMP.o CYCLOTOM.o \
+ CYCLES.o DDFACT.o DECIMAL.o DIOPS.o \
+ DIOPS-.o DIRPROD.o DISPLAY.o DMP.o \
+ DPMO.o DPOLCAT.o DPOLCAT-.o D01AJFA.o \
+ D01AKFA.o D01ALFA.o D01AMFA.o D01APFA.o \
+ D01AQFA.o EMR.o EQ.o ERROR.o \
+ EVALCYC.o E04DGFA.o E04FDFA.o E04GCFA.o \
+ E04JAFA.o FACUTIL.o FF.o FFCG.o \
+ FFCGX.o FFHOM.o FFNB.o FFNBX.o \
+ FFPOLY.o FFX.o FFSLPE.o FGLMICPK.o \
+ FILE.o FINAALG.o FINAALG-.o FINRALG.o \
+ FINRALG-.o FFF.o FLOATRP.o FNAME.o \
+ FOP.o FORMULA.o FORT.o FRAC.o \
+ FTEM.o GENEEZ.o GENMFACT.o GENPGCD.o \
+ GALFACTU.o GALPOLYU.o GB.o GBEUCLID.o \
+ GBF.o GBINTERN.o GHENSEL.o GMODPOL.o \
+ GOSPER.o GRIMAGE.o GROEBSOL.o HDMP.o \
+ HDP.o HEXADEC.o HEUGCD.o IBPTOOLS.o \
+ IFF.o IBITS.o ICARD.o ICDEN.o \
+ IDECOMP.o IIARRAY2.o IMATLIN.o IMATQF.o \
+ INMODGCD.o INNMFACT.o INPSIGN.o INTHERTR.o \
+ INTRAT.o INTRF.o INTSLPE.o INTTR.o \
+ ISUMP.o LAUPOL.o LEADCDET.o LGROBP.o \
+ LIMITRF.o LINDEP.o LO.o LPEFRAC.o \
+ LSPP.o MATLIN.o MCDEN.o MDDFACT.o \
+ MFINFACT.o MFLOAT.o MINT.o MLIFT.o \
+ MMAP.o MODMON.o MONOTOOL.o MPCPF.o \
+ MPC2.o MPC3.o MPOLY.o MPRFF.o \
+ MRATFAC.o MULTSQFR.o NORMRETR.o NPCOEF.o \
+ NSUP.o NTPOLFN.o ODP.o ODEPRIM.o \
+ ODEPRRIC.o OMPKG.o OMSERVER.o PADEPAC.o \
+ PADICRAT.o PADICRC.o PCOMP.o PDECOMP.o \
+ PF.o PFBR.o PFBRU.o PFOTOOLS.o \
+ PFRPAC.o PGCD.o PINTERPA.o PLEQN.o \
+ PMPLCAT.o PMQFCAT.o PNTHEORY.o POLUTIL.o \
+ POLTOPOL.o POLYCATQ.o POLYLIFT.o POLYROOT.o \
+ POLY2.o POLY2UP.o PRS.o PSQFR.o \
+ PUSHVAR.o QALGSET.o QFCAT2.o RADIX.o \
+ RATFACT.o RCFIELD.o RCFIELD-.o RDETR.o \
+ RDETRS.o REAL0.o REAL0Q.o REALSOLV.o \
+ RESRING.o RETSOL.o RF.o RFFACTOR.o \
+ RMATCAT.o RMATCAT-.o RRCC.o RRCC-.o \
+ SCPKG.o SHDP.o SHP.o SIGNRF.o \
+ SMITH.o SMP.o SMTS.o SOLVEFOR.o \
+ SPLTREE.o STINPROD.o STTFNC.o SUBRESP.o \
+ SUMRF.o SUP.o SUPFRACF.o TANEXP.o \
+ TEMUTL.o TEX.o TEXTFILE.o TREE.o \
+ TWOFACT.o UNIFACT.o UP.o UPCDEN.o \
+ UPDECOMP.o UPDIVP.o UPMP.o UPOLYC2.o \
+ UPXSCAT.o UPSQFREE.o VIEWDEF.o VIEW2D.o \
+ VOID.o WEIER.o WP.o
+
+axiom_algebra_layer_14_nrlibs = \
+ $(axiom_algebra_layer_14:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_14_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_14))
+axiom_algebra_layer_15 = \
+ DIAGG.o DIAGG-.o DSMP.o EXPUPXS.o \
+ FRAMALG.o FRAMALG-.o MDAGG.o ODPOL.o \
+ PLOT.o RMCAT2.o ROIRC.o SDPOL.o \
+ SMATCAT.o SMATCAT-.o TUBETOOL.o UPXSCCA.o \
+ UPXSCCA-.o
+
+axiom_algebra_layer_15_nrlibis = \
+ $(axiom_algebra_layer_15:.$(OBJEXT)=.NRLIBS/code.$(OBJEXT))
+
+axiom_algebra_layer_15_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_15))
+axiom_algebra_layer_16 = \
+ DPMM.o EFUPXS.o FFINTBAS.o FRIDEAL.o \
+ FRIDEAL2.o FRMOD.o FSAGG.o FSAGG-.o \
+ IBATOOL.o INTFACT.o KDAGG.o KDAGG-.o \
+ MSETAGG.o MONOGEN.o MONOGEN-.o NFINTBAS.o \
+ SPACE3.o
+
+axiom_algebra_layer_16_nrlibs = \
+ $(axiom_algebra_layer_16:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_16_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_16))
+axiom_algebra_layer_17 = \
+ CCLASS.o FSAGG2.o GALFACT.o IALGFACT.o \
+ IBACHIN.o NORMMA.o ODERED.o OMSAGG.o \
+ PERM.o PERMGRP.o PRIMES.o PWFFINTB.o \
+ RDIST.o SAE.o SAEFACT.o SAERFFC.o \
+ SGCF.o TBAGG.o TBAGG-.o VIEW3D.o
+
+axiom_algebra_layer_17_nrlibs = \
+ $(axiom_algebra_layer_17:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_17_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_17))
+axiom_algebra_layer_18 = \
+ ALIST.o EQTBL.o GSTBL.o HASHTBL.o \
+ INTABL.o INTFTBL.o INTPACK.o IPF.o \
+ KAFILE.o PATRES.o STBL.o STRTBL.o \
+ TABLE.o TBCMPPK.o
+
+axiom_algebra_layer_18_nrlibs = \
+ $(axiom_algebra_layer_18:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_18_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_18))
+axiom_algebra_layer_19 = \
+ ACF.o ACF-.o ACPLOT.o ANTISYM.o \
+ ANY.o ASP12.o ASP27.o ASP28.o \
+ ASP33.o ASP49.o ASP55.o ASP7.o \
+ ASP78.o ASP8.o ASP9.o ATTRBUT.o \
+ BOP.o BOP1.o COMMONOP.o COMPCAT.o \
+ COMPCAT-.o DRAW.o DRAWCFUN.o DROPT.o \
+ DROPT0.o D01ANFA.o D01ASFA.o D03AGNT.o \
+ EP.o E04AGNT.o FCPAK1.o FEXPR.o \
+ FFCAT.o FFCAT-.o FFCGP.o FFNBP.o \
+ FFP.o FLOAT.o FPARFRAC.o FR.o \
+ FRNAALG.o FRNAALG-.o FS.o FS-.o \
+ FST.o FUNCTION.o GDMP.o HACKPI.o \
+ IDEAL.o INFORM.o INFORM1.o IPRNTPK.o \
+ IR.o ISUPS.o KERNEL.o LIB.o \
+ LMDICT.o LODOOPS.o MATRIX.o MKFLCFN.o \
+ MSET.o M3D.o NAGC02.o NAGC05.o \
+ NAGC06.o NAGD03.o NAGE01.o NAGE02.o \
+ NAGE04.o NAGF07.o NAGS.o NAGSP.o \
+ NREP.o NUMFMT.o OC.o OC-.o \
+ ODEPACK.o ODERAT.o OMERR.o OMERRK.o \
+ OPTPACK.o OSI.o PATTERN.o OVAR.o \
+ PMKERNEL.o PMSYM.o POLY.o PRIMELT.o \
+ QALGSET2.o QEQUAT.o RECLOS.o REP1.o \
+ RESULT.o QUATCAT.o QUATCAT-.o RFFACT.o \
+ RMATRIX.o ROMAN.o ROUTINE.o RPOLCAT.o \
+ RPOLCAT-.o RULECOLD.o SAOS.o SEGBIND.o \
+ SET.o SPECOUT.o SQMATRIX.o SWITCH.o \
+ SYMS.o SYMTAB.o SYSSOLP.o UTSCAT.o \
+ UTSCAT-.o VARIABLE.o WFFINTBS.o
+
+axiom_algebra_layer_19_nrlibs = \
+ $(axiom_algebra_layer_19:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_19_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_19))
+axiom_algebra_layer_20 = \
+ ACFS.o ACFS-.o AF.o ALGFACT.o \
+ ALGFF.o ALGMANIP.o ALGMFACT.o ALGPKG.o \
+ ALGSC.o AN.o APPRULE.o ASP19.o \
+ ASP20.o ASP30.o ASP31.o ASP35.o \
+ ASP41.o ASP42.o ASP74.o ASP77.o \
+ ASP80.o CINTSLPE.o COMPFACT.o COMPLEX.o \
+ COMPLPAT.o CMPLXRT.o CPMATCH.o CRFP.o \
+ CTRIGMNP.o D01WGTS.o D02AGNT.o D03EEFA.o \
+ DBLRESP.o DERHAM.o DFSFUN.o DRAWCURV.o \
+ E04NAFA.o E04UCFA.o EF.o EFSTRUC.o \
+ ELFUTS.o ESTOOLS.o EXPEXPAN.o EXPRODE.o \
+ EXPRTUBE.o EXPR2.o FC.o FDIVCAT.o \
+ FDIVCAT-.o FDIV2.o FFCAT2.o FLOATCP.o \
+ FORDER.o FORTRAN.o FSRED.o FSUPFACT.o \
+ FRNAAF2.o FSPECF.o FS2.o FS2UPS.o \
+ GAUSSFAC.o GCNAALG.o GENUFACT.o GENUPS.o \
+ GTSET.o GPOLSET.o IAN.o INEP.o \
+ INFPROD0.o INFSP.o INPRODFF.o INPRODPF.o \
+ INTAF.o INTALG.o INTEF.o INTG0.o \
+ INTHERAL.o INTPAF.o INTPM.o INTTOOLS.o \
+ ITRIGMNP.o JORDAN.o KOVACIC.o LF.o \
+ LIE.o LODOF.o LSQM.o OMEXPR.o \
+ MCMPLX.o MULTFACT.o NAGD01.o NAGD02.o \
+ NAGF01.o NAGF02.o NAGF04.o NCEP.o \
+ NLINSOL.o NSMP.o NUMERIC.o OCT.o \
+ OCTCT2.o ODEPAL.o ODERTRIC.o PADE.o \
+ PAN2EXPR.o PDEPACK.o PFO.o PFOQ.o \
+ PICOERCE.o PMASSFS.o PMFS.o PMPREDFS.o \
+ PSETPK.o QUAT.o QUATCT2.o RADFF.o \
+ RDEEF.o RDEEFS.o RDIV.o RSETCAT.o \
+ RSETCAT-.o RULE.o RULESET.o SIMPAN.o \
+ SFORT.o SOLVESER.o SUMFS.o SUTS.o \
+ TOOLSIGN.o TRIGMNIP.o TRMANIP.o ULSCCAT.o \
+ ULSCCAT-.o UPXSSING.o UTSODE.o UTSODETL.o \
+ UTS2.o WUTSET.o
+
+axiom_algebra_layer_20_nrlibs = \
+ $(axiom_algebra_layer_20:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_20_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_20))
+axiom_algebra_layer_21 = \
+ DEFINTEF.o DFINTTLS.o DEFINTRF.o D01TRNS.o \
+ EFULS.o ESCONT.o EXPR.o EXPR2UPS.o \
+ FDIV.o FSCINT.o FSINT.o FS2EXPXP.o \
+ GSERIES.o HELLFDIV.o INVLAPLA.o IR2F.o \
+ IRRF2F.o LAPLACE.o LIMITPS.o LODEEF.o \
+ NODE1.o ODECONST.o ODEINT.o REP.o \
+ SOLVERAD.o SULS.o SUPXS.o ULS.o \
+ ULSCONS.o UPXS.o UPXSCONS.o UTS.o
+
+axiom_algebra_layer_21_nrlibs = \
+ $(axiom_algebra_layer_21:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_21_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_21))
+axiom_algebra_layer_22 = \
+ ASP29.o COMBF.o D01AGNT.o FSPRMELT.o \
+ INBFF.o LODO.o LODO1.o LODO2.o \
+ NTSCAT.o REGSET.o RGCHAIN.o RSETGCD.o \
+ RSDCMPK.o SFRTCAT.o SIGNEF.o SNTSCAT.o \
+ SOLVETRA.o SRDCMPK.o SREGSET.o STTF.o \
+ SUBSPACE.o ZDSOLVE.o
+
+axiom_algebra_layer_22_nrlibs = \
+ $(axiom_algebra_layer_22:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_22_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_22))
+axiom_algebra_layer_23 = \
+ CPIMA.o IRURPK.o LAZM3PK.o LEXTRIPK.o \
+ NORMPK.o QCMPACK.o RURPK.o SFRGCD.o \
+ SFQCMPK.o INTRVL.o ODEEF.o
+
+axiom_algebra_layer_23_nrlibs = \
+ $(axiom_algebra_layer_23:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_23_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_23))
+axiom_algebra_layer_user = RINTERP.o
+
+axiom_algebra_layer_user_nrlibs = \
+ $(axiom_algebra_layer_user:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_user_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_user))
+
+# The algebra build is not yet ready for parallel build.
+.NOTPARALLEL:
+
+.PHONY: all all-algebra mkdir-output-directory
+all: all-ax
+
+all-ax all-algebra: stamp
+ @ echo finished $(builddir)
+
+stamp: mkdir-output-directory ${SPADFILES} bootstrap-stamp ${TESTS}
+ -rm -f stamp
+ $(STAMP) stamp
+
+mkdir-output-directory:
+ $(mkinstalldirs) $(OUTSRC)
+
+everything: check lib db cmd gloss
+ @ echo 4303 invoking make in `pwd` with parms:
+ @ echo SYS= ${SYS} LSP= ${LSP}
+ @ echo MNT= ${MNT} LISP=${LISP} BYE=${BYE}
+
+check:
+ @ echo 4305 Checking that INTERP.EXPOSED and NRLIBs are consistent
+ @ echo 4306 libcheck needs to use exposed.lsp, not INTERP.EXPOSED
+
+
+
+
+${OUT}/%.o: %.NRLIB/code.o
+ cp $*.NRLIB/code.o ${OUT}/$*.o
+
+
+.PRECIOUS: %.NRLIB/code.o
+%.NRLIB/code.o: %.spad
+ @ rm -rf $*.NRLIB
+ echo ")co $*.spad" | ${INTERPSYS}
+# Compile bootstrap file to machine object code, and the result
+# immediately available for AXIOMsys consumption.
+strap/%.o: %.lsp
+ $(DEPSYS) -- --compile --output=$@ $<
+ cp $@ ${OUT}
+
+$(OUTSRC)/%.spad: mk-target-src-algabra-dir
+
+${OUTSRC}/%.spad: $(srcdir)/%.spad.pamphlet
+ $(axiom_build_document) --tangle --output=$@ $<
+
+.PHONY: mk-target-src-algabra-dir
+mk-target-src-algabra-dir:
+ @ [ -d $(OUTSRC) ] || $(mkinstalldirs) $(OUTSRC)
+
+.PRECIOUS: $(builddir)/%.tex
+.PRECIOUS: $(builddir)/%.dvi
+
+$(DOC)/%.dvi: mk-target-doc-dir
+
+.PHONY: mk-target-doc-dir
+mk-target-doc-dir:
+ @ [ -d $(DOC) ] || $(mkinstalldirs) $(DOC)
+
+$(DOC)/%.dvi: $(builddir)/%.dvi
+ $(INSTALL_DATA) $< $@
+
+$(builddir)/%.dvi: $(axiom_build_texdir)/diagrams.tex \
+ $(axiom_build_texdir)/axiom.sty
+
+$(builddir)/%.dvi: $(builddir)/%.tex
+ $(axiom_build_document) --latex $<
+
+$(builddir)/%.tex: $(srcdir)/%.pamphlet
+ $(axiom_build_document) --weave --output=$@ $<
+
+$(axiom_build_texdir)/diagrams.tex: $(axiom_src_docdir)/diagrams.tex
+ $(INSTALL_DATA) $< $@
+
+
+
+${INPUT}/TESTFR.input: $(srcdir)/fr.spad.pamphlet
+ $(axiom_build_document) --tangle='TEST FR' --output=$@ $<
+
+${INPUT}/INTHEORY.input: $(srcdir)/numtheor.spad.pamphlet
+ $(axiom_build_document) --tangle='TEST INTHEORY' --output=$@ $<
+
+${INPUT}/VIEW2D.input: $(srcdir)/view2D.spad.pamphlet
+ $(axiom_build_document) --tangle='TEST VIEW2D' --output=$@ $<
+
+
+${DOC}/diagrams.tex: $(axiom_src_docdir)/diagrams.tex
+ $(INSTALL_DATA) $< $@
+
+$(axiom_algebra_layer_0_objects): strap-stamp
+$(axiom_algebra_layer_1_objects): 0-stamp
+$(axiom_algebra_layer_2_objects): 1-stamp
+$(axiom_algebra_layer_3_objects): 2-stamp
+$(axiom_algebra_layer_4_objects): 3-stamp
+$(axiom_algebra_layer_5_objects): 4-stamp
+$(axiom_algebra_layer_6_objects): 5-stamp
+$(axiom_algebra_layer_7_objects): 6-stamp
+$(axiom_algebra_layer_8_objects): 7-stamp
+$(axiom_algebra_layer_9_objects): 8-stamp
+$(axiom_algebra_layer_10_objects): 9-stamp
+$(axiom_algebra_layer_11_objects): 10-stamp
+$(axiom_algebra_layer_12_objects): 11-stamp
+$(axiom_algebra_layer_13_objects): 12-stamp
+$(axiom_algebra_layer_14_objects): 13-stamp
+$(axiom_algebra_layer_15_objects): 14-stamp
+$(axiom_algebra_layer_16_objects): 15-stamp
+$(axiom_algebra_layer_17_objects): 16-stamp
+$(axiom_algebra_layer_18_objects): 17-stamp
+$(axiom_algebra_layer_19_objects): 18-stamp
+$(axiom_algebra_layer_20_objects): 19-stamp
+$(axiom_algebra_layer_21_objects): 20-stamp
+$(axiom_algebra_layer_22_objects): 21-stamp
+$(axiom_algebra_layer_23_objects): 22-stamp
+$(axiom_algebra_layer_user_objects): 23-stamp
+$(axiom_algebra_bootstrap_objects): user-stamp
+
+strap-stamp: $(axiom_algebra_layer_strap_objects)
+ @ rm -f strap-stamp
+ @ $(STAMP) strap-stamp
+ @ echo =====================================
+ @ echo === algebra bootstrap complete ======
+ @ echo =====================================
+
+0-stamp: strap-stamp $(axiom_algebra_layer_0_objects)
+ @ rm -f 0-stamp
+ @ $(STAMP) 0-stamp
+ @ echo ==================================
+ @ echo === layer 0 of 23 complete ======
+ @ echo ==================================
+
+1-stamp: 0-stamp $(axiom_algebra_layer_1_objects)
+ @ rm -f 1-stamp
+ @ $(STAMP) 1-stamp
+ @ echo ==================================
+ @ echo === layer 1 of 23 complete ======
+ @ echo ==================================
+
+2-stamp: 1-stamp $(axiom_algebra_layer_2_objects)
+ @ rm -f 2-stamp
+ @ $(STAMP) 2-stamp
+ @ echo ==================================
+ @ echo === layer 2 of 23 complete ======
+ @ echo ==================================
+
+3-stamp: 2-stamp $(axiom_algebra_layer_3_objects)
+ @ rm -f 3-stamp
+ @ $(STAMP) 3-stamp
+ @ echo ==================================
+ @ echo === layer 3 of 23 complete ======
+ @ echo ==================================
+
+4-stamp: 3-stamp $(axiom_algebra_layer_4_objects)
+ @ rm -f 4-stamp
+ @ $(STAMP) 4-stamp
+ @ echo ==================================
+ @ echo === layer 4 of 23 complete ======
+ @ echo ==================================
+
+5-stamp: 4-stamp $(axiom_algebra_layer_5_objects)
+ @ rm -f 5-stamp
+ @ $(STAMP) 5-stamp
+ @ echo ==================================
+ @ echo === layer 5 of 23 complete ======
+ @ echo ==================================
+
+6-stamp: 5-stamp $(axiom_algebra_layer_6_objects)
+ @ rm -f 6-stamp
+ @ $(STAMP) 6-stamp
+ @ echo ==================================
+ @ echo === layer 6 of 23 complete ======
+ @ echo ==================================
+
+7-stamp: 6-stamp $(axiom_algebra_layer_7_objects)
+ @ rm -f 7-stamp
+ @ $(STAMP) 7-stamp
+ @ echo ==================================
+ @ echo === layer 7 of 23 complete ======
+ @ echo ==================================
+
+8-stamp: 7-stamp $(axiom_algebra_layer_8_objects)
+ @ rm -f 8-stamp
+ @ $(STAMP) 8-stamp
+ @ echo ==================================
+ @ echo === layer 8 of 23 complete ======
+ @ echo ==================================
+
+9-stamp: 8-stamp $(axiom_algebra_layer_9_objects)
+ @ rm -f 9-stamp
+ @ $(STAMP) 9-stamp
+ @ echo ==================================
+ @ echo === layer 9 of 23 complete ======
+ @ echo ==================================
+
+10-stamp: 9-stamp $(axiom_algebra_layer_10_objects)
+ @ rm -f 10-stamp
+ @ $(STAMP) 10-stamp
+ @ echo ==================================
+ @ echo === layer 10 of 23 complete ======
+ @ echo ==================================
+
+11-stamp: 10-stamp $(axiom_algebra_layer_11_objects)
+ @ rm -f 11-stamp
+ @ $(STAMP) 11-stamp
+ @ echo ==================================
+ @ echo === layer 11 of 23 complete ======
+ @ echo ==================================
+
+12-stamp: 11-stamp $(axiom_algebra_layer_12_objects)
+ @ rm -f 12-stamp
+ @ $(STAMP) 12-stamp
+ @ echo ==================================
+ @ echo === layer 12 of 23 complete ======
+ @ echo ==================================
+
+13-stamp: 12-stamp $(axiom_algebra_layer_13_objects)
+ @ rm -f 13-stamp
+ @ $(STAMP) 13-stamp
+ @ echo ==================================
+ @ echo === layer 13 of 23 complete ======
+ @ echo ==================================
+
+14-stamp: 13-stamp $(axiom_algebra_layer_14_objects)
+ @ rm -f 14-stamp
+ @ $(STAMP) 14-stamp
+ @ echo ==================================
+ @ echo === layer 14 of 23 complete ======
+ @ echo ==================================
+
+15-stamp: 14-stamp $(axiom_algebra_layer_15_objects)
+ @ rm -f 15-stamp
+ @ $(STAMP) 15-stamp
+ @ echo ==================================
+ @ echo === layer 15 of 23 complete ======
+ @ echo ==================================
+
+16-stamp: 15-stamp $(axiom_algebra_layer_16_objects)
+ @ rm -f 16-stamp
+ @ $(STAMP) 16-stamp
+ @ echo ==================================
+ @ echo === layer 16 of 23 complete ======
+ @ echo ==================================
+
+17-stamp: 16-stamp $(axiom_algebra_layer_17_objects)
+ @ rm -f 17-stamp
+ @ $(STAMP) 17-stamp
+ @ echo ==================================
+ @ echo === layer 17 of 23 complete ======
+ @ echo ==================================
+
+18-stamp: 17-stamp $(axiom_algebra_layer_18_objects)
+ @ rm -f 18-stamp
+ @ $(STAMP) 18-stamp
+ @ echo ==================================
+ @ echo === layer 18 of 23 complete ======
+ @ echo ==================================
+
+19-stamp: 18-stamp $(axiom_algebra_layer_19_objects)
+ @ rm -f 19-stamp
+ @ $(STAMP) 19-stamp
+ @ echo ==================================
+ @ echo === layer 19 of 23 complete ======
+ @ echo ==================================
+
+20-stamp: 19-stamp $(axiom_algebra_layer_20_objects)
+ @ rm -f 20-stamp
+ @ $(STAMP) 20-stamp
+ @ echo ==================================
+ @ echo === layer 20 of 23 complete ======
+ @ echo ==================================
+
+21-stamp: 20-stamp $(axiom_algebra_layer_21_objects)
+ @ rm -f 21-stamp
+ @ $(STAMP) 21-stamp
+ @ echo ==================================
+ @ echo === layer 21 of 23 complete ======
+ @ echo ==================================
+
+22-stamp: 21-stamp $(axiom_algebra_layer_22_objects)
+ @ rm -f 22-stamp
+ @ $(STAMP) 22-stamp
+ @ echo ==================================
+ @ echo === layer 22 of 23 complete ======
+ @ echo ==================================
+
+23-stamp: 22-stamp $(axiom_algebra_layer_23_objects)
+ @ rm -f 23-stamp
+ @ $(STAMP) 23-stamp
+ @ echo ==================================
+ @ echo === layer 23 of 23 complete ======
+ @ echo ==================================
+
+user-stamp: 23-stamp $(axiom_algebra_layer_user_objects)
+ @ rm -f user-stamp
+ @ $(STAMP) user-stamp
+
+
+# bootstrap-pre: user-stamp $(axiom_algebra_bootstrap_nrlibs)
+# $(axiom_algebra_bootstrap_nrlibs): user-stamp
+
+# bootstrap-post: bootstrap-pre $(axiom_algebra_bootstrap_objects)
+
+bootstrap-stamp: $(axiom_algebra_bootstrap_objects)
+ @ rm -f bootstrap-stamp
+ @ $(STAMP) bootstrap-stamp
+ @ echo ==================================
+ @ echo === algebra complete ======
+ @ echo ==================================
+
+mostlyclean-local:
+ @ -rm -f $(OUT)/*.$(OBJEXT)
+ @ -rm -rf *.NRLIB
+
+clean-local: mostlyclean-local
+
+distclean-local: clean-local
+
+include extract-lisp-files.mk
+include extract-spad.mk
+
+.NOTPARALLEL:
+
diff --git a/src/algebra/Makefile.pamphlet b/src/algebra/Makefile.pamphlet
new file mode 100644
index 00000000..7e36a81e
--- /dev/null
+++ b/src/algebra/Makefile.pamphlet
@@ -0,0 +1,2305 @@
+%% Oh Emacs, this is a -*- Makefile -*-, so give me tabs.
+\documentclass{article}
+\usepackage{axiom}
+
+\title{\$SPAD/src/algebra Makefile}
+\author{Timothy Daly \and Gabriel Dos~Reis}
+
+\begin{document}
+\maketitle
+
+\begin{abstract}
+\end{abstract}
+\eject
+
+\tableofcontents
+\eject
+
+\section{Adding new algebra}
+
+This is a complex process by its very nature. Developers and Maintainers
+who undertake the process need to understand quite a lot of detail. The
+ultimate steps to add algebra are tedious but simple. Note that only
+algebra code that gets shipped with the system needs to undergo this
+process. User code can be compiled once the distributed algebra exists
+and does not need either this Makefile or this installation process.
+
+NOTE: If you add new algebra to this file you must also update
+
+\File{src/algebra/exposed.lsp.pamphlet}
+
+otherwise the new algebra won't be loaded by the interpreter when needed.
+
+Since understanding is the key to making correct changes to this file
+I'll work on explaining the details of why things need to exist.
+
+The first idea that you need to understand is the overall process
+of adding algebra code. Lets assume that you have a brand new spad
+file, called \File{foo.spad} containing a simple domain [[BAR]]. The
+steps in the process of adding this file are:
+\begin{enumerate}
+\item Find out where the algebra code lives in the lattice.
+
+You do this by
+\begin{enumerate}
+\item starting a new interpsys session
+\item collecting all the names of the algebra files BAR requires
+\item determining which layer each of the required files resides
+\item determine the highest layer (e.g. 14) that contains the required files
+\end{enumerate}
+
+\item insert the documentation into the next layer (e.g. 15)
+\item insert the [[\${OUT}/BAR.o]] file into the layer's file list
+\end{enumerate}
+
+\section{Rebuilding the algebra from scratch}
+
+Compile order is important. Here we try to define the ordered lattice
+of spad file dependencies. However this is, in reality, a graph rather
+than a lattice. In order to break cycles in this graph we explicitly
+cache a few of the intermediate generated lisp code for certain files.
+These are marked throughout (both here and in the various pamphlet
+files) with the word {\bf BOOTSTRAP}.
+
+If we take a cycle such as [[RING]] we discover that in order to
+compile the spad code we must load the compiled definition of [[RING]].
+In this case we must compile the cached lisp code before we try to
+compile the spad file.
+
+The cycle for [[SETCAT]] is longer consisting of: [[SETCAT]] needs
+{\bf SINT} needs {\bf UFD} needs {\bf GCDDOM} needs {\bf COMRING} needs
+{\bf RING} needs {\bf RNG} needs {\bf ABELGRP} needs {\bf CABMON} needs
+{\bf ABELMON} needs {\bf ABELSG} needs {\bf SETCAT}.
+
+It is highly recommended that you try to become a developer of Axiom
+and read the archived mailing lists before you decide to change a
+cached file. In the fullness of time we will rewrite the whole algebra
+structure into a proper lattice if possible. Alternatively we'll
+reimplement the compiler to handle graphs. Or deeply adopt the
+extensible domains. Whatever we do will be much discussed (and cause
+much disgust) around the campfire. If you come up with a brilliant
+plan that gets adopted we'll even inscribe your name on a log and add
+it to the fire.
+
+In the code that follows we find the categories, packages and domains
+that compile with no dependencies and call this set ``layer 0''. Next
+we find the categories, packages and domains that will compile using
+only ``layer 0'' code and call this ``layer 1''. We walk up the
+lattice in this fashion adding layers. Note that at layer 3 this
+process runs into cycles and we create the ``layer 3 bootstrap''
+stanzas before continuing upward.
+
+\section{The Algebra Lattice Layers}
+
+\subsection{Layer 0 Bootstrap}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+si.spad.pamphlet (INS SINT)
+\end{verbatim}
+
+Note well that none of the algebra stanzas should include these
+files in the preconditions otherwise we have an infinite compile
+loop. These files are originally bootstrapped from lisp code
+when we build the system for the first time but they are
+forcibly recompiled at the end of the build so they reflect
+current code (just in case someone changes the spad code but
+does not re-cache the generated lisp). If you add these files
+as preconditions (note that they are all in the \File{strap/}
+directory rather than the {\bf OUT} directory like everything
+else) then the final recompile will invalidate all of the
+rest of the algebra targets which will get rebuilt again causing
+these targets to be out of date. The rest of the loop is left
+up to the student.
+
+The bootstrap process works because first we ask for the compiled
+lisp code stanzas (the \File{strap/BAR.o} files), THEN we ask for
+the final algebra code stanzas (the [[\${OUT}/BAR.o]] files). This
+is a very subtle point so think it through carefully. Notice that
+this is the only layer calling for \File{strap/} files. All other
+layers call for [[\${OUT}]] files. If you break this the world
+will no longer compile so don't change it if you don't understand it.
+
+\begin{verbatim}
+LAYER0BOOTSTRAP=${OUT}/XPR.o
+\end{verbatim}
+
+<<layer0 bootstrap>>=
+# The list of objects necessary to bootstrap the whole algebra library.
+axiom_algebra_layer_strap_objects = \
+ strap/ABELGRP.o strap/ABELGRP-.o strap/ABELMON.o strap/ABELMON-.o \
+ strap/ABELSG.o strap/ABELSG-.o strap/ALAGG.o strap/BOOLEAN.o \
+ strap/CABMON.o strap/CHAR.o strap/CLAGG.o strap/CLAGG-.o \
+ strap/COMRING.o strap/DFLOAT.o strap/DIFRING.o strap/DIFRING-.o \
+ strap/DIVRING.o strap/DIVRING-.o strap/ENTIRER.o strap/ES.o \
+ strap/ES-.o strap/EUCDOM.o strap/EUCDOM-.o strap/FFIELDC.o \
+ strap/FFIELDC-.o strap/FPS.o strap/FPS-.o strap/GCDDOM.o \
+ strap/GCDDOM-.o strap/HOAGG.o strap/HOAGG-.o strap/ILIST.o \
+ strap/INS.o strap/INS-.o strap/INT.o strap/INTDOM.o \
+ strap/INTDOM-.o strap/ISTRING.o strap/LIST.o strap/LNAGG.o \
+ strap/LNAGG-.o strap/LSAGG.o strap/LSAGG-.o strap/MONOID.o \
+ strap/MONOID-.o strap/MTSCAT.o strap/NNI.o strap/OINTDOM.o \
+ strap/ORDRING.o strap/ORDRING-.o strap/OUTFORM.o strap/PI.o \
+ strap/PRIMARR.o strap/POLYCAT.o strap/POLYCAT-.o strap/PSETCAT.o \
+ strap/PSETCAT-.o strap/QFCAT.o strap/QFCAT-.o strap/RCAGG.o \
+ strap/RCAGG-.o strap/REF.o strap/RING.o strap/RING-.o \
+ strap/RNG.o strap/RNS.o strap/RNS-.o strap/SETAGG.o \
+ strap/SETAGG-.o strap/SETCAT.o strap/SETCAT-.o strap/SINT.o \
+ strap/STAGG.o strap/STAGG-.o strap/SYMBOL.o strap/TSETCAT.o \
+ strap/TSETCAT-.o strap/UFD.o strap/UFD-.o strap/ULSCAT.o \
+ strap/UPOLYC.o strap/UPOLYC-.o strap/URAGG.o strap/URAGG-.o \
+ strap/VECTOR.o
+
+@
+<<layer0 copy>>=
+
+axiom_algebra_bootstrap = \
+ ABELGRP.o ABELGRP-.o ABELMON.o ABELMON-.o \
+ ABELSG.o ABELSG-.o ALAGG.o BOOLEAN.o \
+ CABMON.o CHAR.o CLAGG.o CLAGG-.o \
+ COMRING.o DFLOAT.o DIFRING.o DIFRING-.o \
+ DIVRING.o DIVRING-.o ENTIRER.o ES.o \
+ ES-.o EUCDOM.o EUCDOM-.o FFIELDC.o \
+ FFIELDC-.o FPS.o FPS-.o GCDDOM.o \
+ GCDDOM-.o HOAGG.o HOAGG-.o ILIST.o \
+ INS.o INS-.o INT.o INTDOM.o \
+ INTDOM-.o ISTRING.o LIST.o LNAGG.o \
+ LNAGG-.o LSAGG.o LSAGG-.o MONOID.o \
+ MONOID-.o MTSCAT.o NNI.o OINTDOM.o \
+ ORDRING.o ORDRING-.o OUTFORM.o PI.o \
+ PRIMARR.o POLYCAT.o POLYCAT-.o PSETCAT.o \
+ PSETCAT-.o QFCAT.o QFCAT-.o RCAGG.o \
+ RCAGG-.o REF.o RING.o RING-.o \
+ RNG.o RNS.o RNS-.o SETAGG.o \
+ SETAGG-.o SETCAT.o SETCAT-.o SINT.o \
+ STAGG.o STAGG-.o SYMBOL.o TSETCAT.o \
+ TSETCAT-.o UFD.o UFD-.o ULSCAT.o \
+ UPOLYC.o UPOLYC-.o URAGG.o URAGG-.o \
+ VECTOR.o
+
+axiom_algebra_bootstrap_nrlibs = \
+ $(axiom_algebra_bootstrap:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_bootstrap_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_bootstrap))
+@
+
+\subsection{Layer 0}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+attreg.spad.pamphlet (ATTREG)
+dhmatrix.spad.pamphlet (DHMATRIX)
+omcat.spad.pamphlet (OM)
+print.spad.pamphlet (PRINT)
+ptranfn.spad.pamphlet (PTRANFN)
+system.spad.pamphlet (MSYSCMD)
+\end{verbatim}
+
+<<layer0>>=
+
+axiom_algebra_layer_0 = \
+ AHYP.o ATTREG.o CFCAT.o ELTAB.o \
+ KOERCE.o KONVERT.o MSYSCMD.o ODEIFTBL.o \
+ OM.o OMCONN.o OMDEV.o OUT.o \
+ PRIMCAT.o PRINT.o PTRANFN.o SPFCAT.o \
+ TYPE.o
+
+axiom_algebra_layer_0_nrlibs = \
+ $(axiom_algebra_layer_0:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_0_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_0))
+@
+
+\subsection{Layer 1}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+ituple.spad.pamphlet (ITFUN2 ITFUN3 ITUPLE)
+mkrecord.spad.pamphlet (MKRECORD)
+pcurve.spad.pamphlet (PPCURVE PSCURVE)
+coerce.spad.pamphlet (TYPE KOERCE KONVERT RETRACT)
+\end{verbatim}
+
+<<layer1>>=
+axiom_algebra_layer_1 = \
+ ANY1.o COMBOPC.o DROPT1.o EQ2.o \
+ FORTCAT.o ITFUN2.o ITFUN3.o ITUPLE.o \
+ MKBCFUNC.o MKRECORD.o MKUCFUNC.o NONE1.o \
+ PATAB.o PLOT1.o PPCURVE.o PSCURVE.o \
+ REAL.o RESLATC.o RETRACT.o RETRACT-.o \
+ SEGBIND2.o SEGCAT.o STREAM1.o STREAM2.o \
+ STREAM3.o
+
+axiom_algebra_layer_1_nrlibs = \
+ $(axiom_algebra_layer_1:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_1_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_1))
+@
+
+\subsection{Layer 2}
+
+\subsubsection{Completed spad files}
+
+<<layer2>>=
+axiom_algebra_layer_2 = \
+ FMC.o FMFUN.o FORTFN.o FVC.o \
+ FVFUN.o INTRET.o SEGXCAT.o
+
+axiom_algebra_layer_2_nrlibs = \
+ $(axiom_algebra_layer_2:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_2_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_2))
+@
+
+\subsection{Layer 3}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+grdef.spad.pamphlet (GRDEF)
+\end{verbatim}
+
+<<layer3>>=
+axiom_algebra_layer_3 = \
+ AGG.o AGG-.o BASTYPE.o BASTYPE-.o \
+ GRDEF.o LIST3.o MKFUNC.o
+
+axiom_algebra_layer_3_nrlibs = \
+ $(axiom_algebra_layer_3:.$(OBJEXT=./NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_3_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_3))
+@
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+annacat.spad.pamphlet (NIPROB ODEPROB PDEPROB OPTPROB NUMINT ODECAT PDECAT
+ OPTCAT)
+color.spad.pamphlet (COLOR PALETTE)
+mappkg.spad.pamphlet (MAPHACK1 MAPHACK2 MAPHACK3 MAPPKG1 MAPPKG2 MAPPKG3)
+paramete.spad.pamphlet (PARPCURV PARPC2 PARSCURV PARSC2 PARSURF PARSU2
+suchthat.spad.pamphlet (SUCH)
+ystream.spad.pamphlet (YSTREAM)
+\end{verbatim}
+
+<<layer4>>=
+axiom_algebra_layer_4 = \
+ ANON.o COLOR.o COMM.o COMPPROP.o \
+ ELTAGG.o ELTAGG-.o ESCONT1.o EXIT.o \
+ FAMONC.o FILECAT.o FINITE.o FNCAT.o \
+ FORMULA1.o IDPC.o IEVALAB.o IEVALAB-.o \
+ INTBIT.o LMODULE.o LOGIC.o LOGIC-.o \
+ MAPHACK1.o MAPHACK2.o MAPHACK3.o MAPPKG1.o \
+ MAPPKG2.o MAPPKG3.o MONAD.o MONAD-.o \
+ NIPROB.o NONE.o NUMINT.o ODECAT.o \
+ ODEPROB.o OMENC.o ONECOMP2.o OPTCAT.o \
+ OPTPROB.o ORDSET.o ORDSET-.o PALETTE.o \
+ PARPCURV.o PARPC2.o PARSCURV.o PARSC2.o \
+ PARSURF.o PARSU2.o PATMAB.o PATRES2.o \
+ PATTERN1.o PDECAT.o PDEPROB.o REPSQ.o \
+ REPDB.o RFDIST.o RIDIST.o RMODULE.o \
+ SEXCAT.o SGROUP.o SGROUP-.o SPACEC.o \
+ SPLNODE.o STEP.o SUCH.o TEX1.o \
+ UDVO.o YSTREAM.o
+
+axiom_algebra_layer_4_nrlibs = \
+ $(axiom_algebra_layer_4:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_4_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_4))
+@
+
+\subsection{Layer 5}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+equation1.spad.pamphlet (EVALAB IEVALAB)
+\end{verbatim}
+
+<<layer5>>=
+axiom_algebra_layer_5 = \
+ ATRIG.o ATRIG-.o BMODULE.o CACHSET.o \
+ CHARNZ.o CHARZ.o DVARCAT.o DVARCAT-.o \
+ ELEMFUN.o ELEMFUN-.o ESTOOLS2.o EVALAB.o \
+ EVALAB-.o FCOMP.o FEVALAB.o FEVALAB-.o \
+ FPATMAB.o GROUP.o GROUP-.o IDPAM.o \
+ IDPO.o INCRMAPS.o IXAGG.o IXAGG-.o \
+ KERNEL2.o LALG.o LALG-.o LINEXP.o \
+ MODMONOM.o MONADWU.o MONADWU-.o MRF2.o \
+ NARNG.o NARNG-.o NSUP2.o OASGP.o \
+ ODVAR.o OPQUERY.o ORDFIN.o ORDMON.o \
+ PATMATCH.o PERMCAT.o PDRING.o PDRING-.o \
+ SDVAR.o SUP2.o TRIGCAT.o TRIGCAT-.o \
+ ULS2.o UP2.o
+
+axiom_algebra_layer_5_nrlibs = \
+ $(axiom_algebra_layer_5:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_5_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_5))
+@
+
+\subsection{Layer6}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+fmod.spad.pamphlet (ZMOD)
+sortpak.spad.pamphlet (SORTPAK)
+\end{verbatim}
+
+<<layer6>>=
+axiom_algebra_layer_6 = \
+ AUTOMOR.o BGAGG.o BGAGG-.o BRAGG.o \
+ BRAGG-.o CARTEN2.o CHARPOL.o COMPLEX2.o \
+ DIFEXT.o DIFEXT-.o DLAGG.o ELAGG.o \
+ ELAGG-.o ES1.o ES2.o GRMOD.o \
+ GRMOD-.o HYPCAT.o HYPCAT-.o MKCHSET.o \
+ MODRING.o MODULE.o MODULE-.o NASRING.o \
+ NASRING-.o OAMON.o SORTPAK.o ZMOD.o
+
+axiom_algebra_layer_6_nrlibs = \
+ $(axiom_algebra_layer_6:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_6_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_6))
+@
+
+\subsection{Layer7}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+\end{verbatim}
+
+<<layer7>>=
+axiom_algebra_layer_7 = \
+ ALGEBRA.o ALGEBRA-.o BTCAT.o BTCAT-.o \
+ FMCAT.o IDPOAM.o IFAMON.o GRALG.o \
+ GRALG-.o OCAMON.o PRQAGG.o QUAGG.o \
+ SKAGG.o
+
+axiom_algebra_layer_7_nrlibs = \
+ $(axiom_algebra_layer_7:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_7_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_7))
+@
+
+\subsection{Layer8}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+card.spad.pamphlet (CARD)
+fortcat.spad.pamphlet (FORTFN FMC FORTCAT FVC FMTC FMFUN FVFUN)
+\end{verbatim}
+
+<<layer8>>=
+axiom_algebra_layer_8 = \
+ BSTREE.o BTOURN.o CARD.o DRAWHACK.o \
+ DQAGG.o FACTFUNC.o FMTC.o FR2.o \
+ FRAC2.o FRUTIL.o ITAYLOR.o MLO.o \
+ NAALG.o NAALG-.o OAGROUP.o OAMONS.o \
+ OP.o ORDCOMP2.o PID.o RANDSRC.o \
+ UNISEG2.o XALG.o
+
+axiom_algebra_layer_8_nrlibs = \
+ $(axiom_algebra_layer_8:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_8_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_8))
+@
+
+\subsection{Layer9}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+degred.spad.pamphlet (DEGRED)
+indexedp.spad.pamphlet (IDPC IDPO IDPAM IDPOAM IDPOAMS IDPAG)
+product.spad.pamphlet (PRODUCT)
+retract.spad.pamphlet (RETRACT FRETRCT RATRET)
+sf.spad.pamphlet (REAL RADCAT RNS FPS DFLOAT)
+\end{verbatim}
+
+<<layer9>>=
+axiom_algebra_layer_9 = \
+ AMR.o AMR-.o DEGRED.o DLP.o \
+ EAB.o ESTOOLS1.o FAGROUP.o FAMONOID.o \
+ FIELD.o FIELD-.o FLAGG.o FLAGG-.o \
+ FLINEXP.o FLINEXP-.o FRETRCT.o FRETRCT-.o \
+ FSERIES.o FT.o IDPAG.o IDPOAMS.o \
+ INFINITY.o LA.o OMLO.o ORTHPOL.o \
+ PRODUCT.o PADICCT.o PMPRED.o PMASS.o \
+ PTFUNC2.o RADCAT.o RADCAT-.o RATRET.o \
+ RADUTIL.o UPXS2.o XFALG.o ZLINDEP.o
+
+axiom_algebra_layer_9_nrlibs = \
+ $(axiom_algebra_layer_9:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_9_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_9))
+@
+
+\subsection{Layer10}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+complet.spad.pamphlet (ORDCOMP ORDCOMP2 ONECOMP ONECOMP2 INFINITY)
+cra.spad.pamphlet (CRAPACK)
+defaults.spad.pamphlet (REPSQ REPDB FLASORT)
+drawpak.spad.pamphlet (DRAWCX)
+free.spad.pamphlet (LMOPS FMONOID FGROUP FAMONC IFAMON FAMONOID FAGROUP)
+fourier.spad.pamphlet (FCOMP FSERIES)
+functions.spad.pamphlet (BFUNCT)
+mesh.spad.pamphlet (MESH)
+moebius.spad.pamphlet (MOEBIUS)
+mring.spad.pamphlet (MRING MRF2)
+opalg.spad.pamphlet (MODOP OP)
+partperm.spad.pamphlet (PARTPERM)
+pgrobner.spad.pamphlet (PGROEB)
+plottool.spad.pamphlet (PLOTTOOL)
+setorder.spad.pamphlet (UDPO UDVO)
+sttaylor.spad.pamphlet (STTAYLOR)
+tableau.spad.pamphlet (TABLBUMP TABLEAU)
+viewpack.spad.pamphlet (VIEW)
+\end{verbatim}
+
+<<layer10>>=
+axiom_algebra_layer_10 = \
+ A1AGG.o A1AGG-.o ARR2CAT.o ARR2CAT-.o \
+ ASP34.o BBTREE.o BFUNCT.o BPADIC.o \
+ BTREE.o CRAPACK.o DEQUEUE.o DLIST.o \
+ DRAWCX.o D01GBFA.o D02EJFA.o D03FAFA.o \
+ DRAWPT.o FAMR.o FAMR-.o FLASORT.o \
+ FLAGG2.o FGROUP.o FM.o FM1.o \
+ FPC.o FPC-.o FMONOID.o INDE.o \
+ IPADIC.o IROOT.o IR2.o LEXP.o \
+ LIECAT.o LIECAT-.o LIST2.o LIST2MAP.o \
+ LMOPS.o LZSTAGG.o LZSTAGG-.o MAGMA.o \
+ MESH.o MOEBIUS.o MODFIELD.o MODOP.o \
+ MRING.o MTHING.o NCNTFRAC.o NCODIV.o \
+ NUMTUBE.o ODR.o OFMONOID.o ONECOMP.o \
+ ORDCOMP.o OREPCAT.o OREPCAT-.o OWP.o \
+ PADIC.o PATTERN2.o PATLRES.o PARTPERM.o \
+ PBWLB.o PENDTREE.o PGE.o PGROEB.o \
+ PINTERP.o PLOTTOOL.o PFR.o PMDOWN.o \
+ PRTITION.o PMINS.o PMLSAGG.o PMTOOLS.o \
+ PSCAT.o PSCAT-.o QFORM.o QUEUE.o \
+ SCACHE.o SEG.o SEG2.o SEXOF.o \
+ STACK.o STTAYLOR.o TABLBUMP.o TABLEAU.o \
+ TOPSP.o TRANFUN.o TRANFUN-.o TUBE.o \
+ UDPO.o UNISEG.o VIEW.o VSPACE.o \
+ VSPACE-.o XPOLYC.o XPR.o
+
+axiom_algebra_layer_10_nrlibs = \
+ $(axiom_algebra_layer_10:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_10_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_10))
+@
+
+\subsection{Layer11}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+array1.spad.pamphlet (PRIMARR PRIMARR2 TUPLE IFARRAY FARRAY IARRAY1 ARRAY1
+ ARRAY12)
+bags.spad.pamphlet (STACK ASTACK QUEUE DEQUEUE HEAP)
+combinat.spad.pamphlet (COMBINAT)
+ffx.spad.pamphlet (IRREDFFX)
+galutil.spad.pamphlet (GALUTIL)
+matstor.spad.pamphlet (MATSTOR)
+ore.spad.pamphlet (OREPCAT APPLYORE AUTOMOR OREPCTO ORESUP OREUP)
+plot3d.spad.pamphlet (PLOT3D)
+prtition.spad.pamphlet (PRTITION SYMPOLY)
+stream.spad.pamphlet (LZSTAGG CSTTOOLS STREAM STREAM1 STREAM2 STREAM3)
+trigcat.spad.pamphlet (ELEMFUN AHYP ATRIG HYPCAT TRANFUN TRIGCAT PRIMCAT
+ LFCAT CFCAT SPFCAT)
+xlpoly.spad.pamphlet (MAGMA LWORD LIECAT FLALG XEXPPKG LPOLY PBWLB XPBWPOLY
+ LEXP)
+xpoly.spad.pamphlet (OFMONOID FMCAT FM1 XALG XFALG XPOLYC XPR XDPOLY XRPOLY
+ XPOLY)
+\end{verbatim}
+
+<<layer11>>=
+axiom_algebra_layer_11 = \
+ APPLYORE.o ARRAY1.o ARRAY12.o ARRAY2.o \
+ ASTACK.o BTAGG.o BTAGG-.o COMBINAT.o \
+ CSTTOOLS.o D01FCFA.o E04MBFA.o FARRAY.o \
+ FLALG.o GALUTIL.o HEAP.o IARRAY1.o \
+ IARRAY2.o IFARRAY.o INTCAT.o INTHEORY.o \
+ IRREDFFX.o LFCAT.o LODOCAT.o LODOCAT-.o \
+ LWORD.o MATCAT.o MATCAT-.o MATSTOR.o \
+ ORESUP.o OREPCTO.o OREUP.o PLOT3D.o \
+ PR.o PREASSOC.o PRIMARR2.o REDORDER.o \
+ SRAGG.o SRAGG-.o STREAM.o SYMPOLY.o \
+ TS.o TUPLE.o UPSCAT.o UPSCAT-.o \
+ VECTCAT.o VECTCAT-.o XDPOLY.o XEXPPKG.o \
+ XF.o XF-.o XPBWPOLY.o XPOLY.o \
+ XRPOLY.o
+
+axiom_algebra_layer_11_nrlibs = \
+ $(axiom_algebra_layer_11:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_11_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_11))
+@
+
+\subsection{Layer12}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+\end{verbatim}
+
+<<layer12>>=
+axiom_algebra_layer_12 = \
+ BITS.o DIRPROD2.o IMATRIX.o IVECTOR.o \
+ LPOLY.o LSMP.o LSMP1.o MATCAT2.o \
+ PTCAT.o STRICAT.o TRIMAT.o
+
+axiom_algebra_layer_12_nrlibs = \
+ $(axiom_algebra_layer_12:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_12_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_12))
+@
+
+\subsection{Layer13}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+carten.spad.pamphlet (GRMOD GRALG CARTEN CARTEN2)
+catdef.spad.pamphlet (ABELGRP ABELMON ABELSG ALGEBRA BASTYPE BMODULE CABMON
+ CHARNZ CHARZ COMRING DIFRING DIFEXT DIVRING ENTIRER
+ EUCDOM FIELD FINITE FLINEXP GCDDOM GROUP INTDOM LMODULE
+ LINEXP MODULE MONOID OAGROUP OAMON OAMONS OASGP OCAMON
+ ORDFIN OINTDOM ORDMON ORDRING ORDSET PDRING PFECAT PID
+ RMODULE RING RNG SGROUP SETCAT STEP UFD VSPACE)
+clifford.spad.pamphlet (QFORM CLIF)
+clip.spad.pamphlet (CLIP)
+coordsys.spad.pamphlet (COORDSYS)
+dhmatrix.spad.pamphlet (DHMATRIX)
+d02routine.spad.pamphlet (D02BBFA D02BHFA D02CJFA D02EJFA)
+ffpoly2.spad.pamphlet (FFPOLY2)
+irsn.spad.pamphlet (IRSN)
+numode.spad.pamphlet (NUMODE)
+numquad.spad.pamphlet (NUMQUAD)
+perman.spad.pamphlet (GRAY PERMAN)
+pseudolin.spad.pamphlet (PSEUDLIN)
+rep2.spad.pamphlet (REP2)
+sex.spad.pamphlet (SEXCAT SEXOF SEX)
+solvedio.spad.pamphlet (DIOSP)
+\end{verbatim}
+
+<<layer13>>=
+axiom_algebra_layer_13 = \
+ ASSOCEQ.o CARTEN.o CLIF.o CLIP.o \
+ COORDSYS.o DBASE.o DHMATRIX.o DIOSP.o \
+ DIRPCAT.o DIRPCAT-.o D02BBFA.o D02BHFA.o \
+ D02CJFA.o FAXF.o FAXF-.o FFPOLY2.o \
+ FNLA.o GRAY.o HB.o IRSN.o \
+ MCALCFN.o MHROWRED.o NUMODE.o NUMQUAD.o \
+ ODESYS.o ODETOOLS.o ORDFUNS.o PERMAN.o \
+ PFECAT.o PFECAT-.o POINT.o PSEUDLIN.o \
+ PTPACK.o REP2.o SETMN.o SEX.o \
+ STRING.o SYMFUNC.o VECTOR2.o
+
+axiom_algebra_layer_13_nrlibs = \
+ $(axiom_algebra_layer_13:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_13_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_13))
+@
+
+\subsection{Layer14}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+allfact.spad.pamphlet (MRATFAC MPRFF MPCPF GENMFACT RFFACTOR SUPFRACF)
+array2.spad.pamphlet (ARR2CAT IIARRAY2 IARRAY2 ARRAY2)
+bezout.spad.pamphlet (BEZOUT)
+boolean.spad.pamphlet (REF LOGIC BOOLEAN IBITS BITS)
+brill.spad.pamphlet (BRILL)
+cden.spad.pamphlet (ICDEN CDEN UPCDEN MCDEN)
+contfrac.spad.pamphlet (CONTFRAC NCNTFRAC)
+cycles.spad.pamphlet (CYCLES EVALCYC)
+cyclotom.spad.pamphlet (CYCLOTOM)
+ddfact.spad.pamphlet (DDFACT)
+equation2.spad.pamphlet (EQ EQ2 FEVALAB)
+error.spad.pamphlet (ERROR)
+facutil.spad.pamphlet (FACUTIL PUSHVAR)
+ffcat.spad.pamphlet (FPC XF FAXF DLP FFIELDC FFSLPE)
+fff.spad.pamphlet (FFF)
+ffhom.spad.pamphlet (FFHOM)
+ffpoly.spad.pamphlet (FFPOLY)
+fname.spad.pamphlet (FNCAT FNAME)
+formula.spad.pamphlet (FORMULA FORMULA1)
+fraction.spad.pamphlet (LO LA QFCAT QFCAT2 FRAC LPEFRAC FRAC2)
+galfactu.spad.pamphlet (GALFACTU)
+galpolyu.spad.pamphlet (GALPOLYU)
+gb.spad.pamphlet (GB)
+gbeuclid.spad.pamphlet (GBEUCLID)
+gbintern.spad.pamphlet (GBINTERN)
+gdirprod.spad.pamphlet (ORDFUNS ODP HDP SHDP)
+geneez.spad.pamphlet (GENEEZ)
+ghensel.spad.pamphlet (GHENSEL)
+gpgcd.spad.pamphlet (GENPGCD)
+gpol.spad.pamphlet (LAUPOL)
+groebf.spad.pamphlet (GBF)
+groebsol.spad.pamphlet (GROEBSOL)
+intrf.spad.pamphlet (SUBRESP MONOTOOL INTHERTR INTTR INTRAT INTRF)
+idecomp.spad.pamphlet (IDECOMP)
+leadcdet.spad.pamphlet (LEADCDET)
+lindep.spad.pamphlet (LINDEP ZLINDEP)
+lingrob.spad.pamphlet (LGROBP)
+listgcd.spad.pamphlet (HEUGCD)
+matfuns.spad.pamphlet (IMATLIN MATCAT2 RMCAT2 IMATQF MATLIN)
+mfinfact.spad.pamphlet (MFINFACT)
+mlift.spad.pamphlet (MLIST)
+moddfact.spad.pamphlet (MDDFACT)
+modmon.spad.pamphlet (MODMON)
+modring.spad.pamphlet (MODRING EMR MODFIELD)
+mts.spad.pamphlet (SMTS TS)
+multsqfr.spad.pamphlet (MULTSQFR)
+newpoint.spad.pamphlet (PTCAT POINT COMPPROP SUBSPACE PTPACK PTFUNC2)
+numtheor.spad.pamphlet (INTHEORY PNTHEORY)
+npcoef.spad.pamphlet (NPCOEF)
+omdev.spad.pamphlet (OMENC OMDEV OMCONN OMPKG)
+omserver.spad.pamphlet (OMSERVER)
+padic.spad.pamphlet (PADICCT IPADIC PADIC BPADIC PADICRC PADICRAT BPADICRT)
+pdecomp.spad.pamphlet (PCOMP PDECOMP)
+pfbr.spad.pamphlet (PFBRU PFBR)
+pfr.spad.pamphlet (PFR PFRPAC)
+pgcd.spad.pamphlet (PGCD)
+pinterp.spad.pamphlet (PINTERPA PINTERP)
+pleqn.spad.pamphlet (PLEQN)
+poltopol.spad.pamphlet (MPC2 MPC3 POLTOPOL)
+poly.spad.pamphlet (FM PR SUP SUP2 UP UP2 POLY2UP UPSQFREE PSQFR UPMP)
+polycat.spad.pamphlet (AMR FAMR POLYCAT POLYLIFT UPOLYC UPOLYC2 COMMUPC)
+prs.spad.pamphlet (PRS)
+radix.spad.pamphlet (RADIX BINARY DECIMAL HEXADEC RADUTIL)
+ratfact.spad.pamphlet (RATFACT)
+rderf.spad.pamphlet (RDETR)
+realzero.spad.pamphlet (REAL0)
+real0q.spad.pamphlet (REAL0Q)
+resring.spad.pamphlet (RESRING)
+rf.spad.pamphlet (POLYCATQ RF)
+solvefor.spad.pamphlet (SOLVEFOR)
+solvelin.spad.pamphlet (LSMP LSMP1 LSPP)
+smith.spad.pamphlet (SMITH)
+sttf.spad.pamphlet (STTF STTFNC)
+sturm.spad.pamphlet (SHP)
+sum.spad.pamphlet (ISUMP GOSPER SUMRF)
+tex.spad.pamphlet (TEX)
+tree.spad.pamphlet (TREE BTCAT BTREE BSTREE BTOURN BBTREE PENDTREE)
+twofact.spad.pamphlet (NORMRETR TWOFACT)
+unifact.spad.pamphlet (UNIFACT)
+updecomp.spad.pamphlet (UPDECOMP)
+updivp.spad.pamphlet (UPDIVP)
+viewDef.spad.pamphlet (VIEWDEF)
+vector.spad.pamphlet (VECTCAT IVECTOR VECTOR VECTOR2 DIRPCAT DIRPROD DIRPROD2)
+view2D.spad.pamphlet (GRIMAGE VIEW2D)
+void.spad.pamphlet (VOID EXIT)
+weier.spad.pamphlet (WEIER)
+wtpol.spad.pamphlet (WP OWP)
+\end{verbatim}
+
+<<layer14>>=
+axiom_algebra_layer_14 = \
+ ASP1.o ASP10.o ASP24.o ASP4.o \
+ ASP50.o ASP6.o ASP73.o BALFACT.o \
+ BEZOUT.o BINARY.o BINFILE.o BOUNDZRO.o \
+ BPADICRT.o BRILL.o CDEN.o CHVAR.o \
+ COMMUPC.o CONTFRAC.o CVMP.o CYCLOTOM.o \
+ CYCLES.o DDFACT.o DECIMAL.o DIOPS.o \
+ DIOPS-.o DIRPROD.o DISPLAY.o DMP.o \
+ DPMO.o DPOLCAT.o DPOLCAT-.o D01AJFA.o \
+ D01AKFA.o D01ALFA.o D01AMFA.o D01APFA.o \
+ D01AQFA.o EMR.o EQ.o ERROR.o \
+ EVALCYC.o E04DGFA.o E04FDFA.o E04GCFA.o \
+ E04JAFA.o FACUTIL.o FF.o FFCG.o \
+ FFCGX.o FFHOM.o FFNB.o FFNBX.o \
+ FFPOLY.o FFX.o FFSLPE.o FGLMICPK.o \
+ FILE.o FINAALG.o FINAALG-.o FINRALG.o \
+ FINRALG-.o FFF.o FLOATRP.o FNAME.o \
+ FOP.o FORMULA.o FORT.o FRAC.o \
+ FTEM.o GENEEZ.o GENMFACT.o GENPGCD.o \
+ GALFACTU.o GALPOLYU.o GB.o GBEUCLID.o \
+ GBF.o GBINTERN.o GHENSEL.o GMODPOL.o \
+ GOSPER.o GRIMAGE.o GROEBSOL.o HDMP.o \
+ HDP.o HEXADEC.o HEUGCD.o IBPTOOLS.o \
+ IFF.o IBITS.o ICARD.o ICDEN.o \
+ IDECOMP.o IIARRAY2.o IMATLIN.o IMATQF.o \
+ INMODGCD.o INNMFACT.o INPSIGN.o INTHERTR.o \
+ INTRAT.o INTRF.o INTSLPE.o INTTR.o \
+ ISUMP.o LAUPOL.o LEADCDET.o LGROBP.o \
+ LIMITRF.o LINDEP.o LO.o LPEFRAC.o \
+ LSPP.o MATLIN.o MCDEN.o MDDFACT.o \
+ MFINFACT.o MFLOAT.o MINT.o MLIFT.o \
+ MMAP.o MODMON.o MONOTOOL.o MPCPF.o \
+ MPC2.o MPC3.o MPOLY.o MPRFF.o \
+ MRATFAC.o MULTSQFR.o NORMRETR.o NPCOEF.o \
+ NSUP.o NTPOLFN.o ODP.o ODEPRIM.o \
+ ODEPRRIC.o OMPKG.o OMSERVER.o PADEPAC.o \
+ PADICRAT.o PADICRC.o PCOMP.o PDECOMP.o \
+ PF.o PFBR.o PFBRU.o PFOTOOLS.o \
+ PFRPAC.o PGCD.o PINTERPA.o PLEQN.o \
+ PMPLCAT.o PMQFCAT.o PNTHEORY.o POLUTIL.o \
+ POLTOPOL.o POLYCATQ.o POLYLIFT.o POLYROOT.o \
+ POLY2.o POLY2UP.o PRS.o PSQFR.o \
+ PUSHVAR.o QALGSET.o QFCAT2.o RADIX.o \
+ RATFACT.o RCFIELD.o RCFIELD-.o RDETR.o \
+ RDETRS.o REAL0.o REAL0Q.o REALSOLV.o \
+ RESRING.o RETSOL.o RF.o RFFACTOR.o \
+ RMATCAT.o RMATCAT-.o RRCC.o RRCC-.o \
+ SCPKG.o SHDP.o SHP.o SIGNRF.o \
+ SMITH.o SMP.o SMTS.o SOLVEFOR.o \
+ SPLTREE.o STINPROD.o STTFNC.o SUBRESP.o \
+ SUMRF.o SUP.o SUPFRACF.o TANEXP.o \
+ TEMUTL.o TEX.o TEXTFILE.o TREE.o \
+ TWOFACT.o UNIFACT.o UP.o UPCDEN.o \
+ UPDECOMP.o UPDIVP.o UPMP.o UPOLYC2.o \
+ UPXSCAT.o UPSQFREE.o VIEWDEF.o VIEW2D.o \
+ VOID.o WEIER.o WP.o
+
+axiom_algebra_layer_14_nrlibs = \
+ $(axiom_algebra_layer_14:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_14_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_14))
+@
+
+\subsection{Layer15}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+dpolcat.spad.pamphlet (DVARCAT ODVAR SDVAR DPOLCAT DSMP ODPOL SDPOL)
+matcat.spad.pamphlet (MATCAT RMATCAT SMATCAT)
+plot.spad.pamphlet (PLOT PLOT1)
+\end{verbatim}
+
+<<layer15>>=
+axiom_algebra_layer_15 = \
+ DIAGG.o DIAGG-.o DSMP.o EXPUPXS.o \
+ FRAMALG.o FRAMALG-.o MDAGG.o ODPOL.o \
+ PLOT.o RMCAT2.o ROIRC.o SDPOL.o \
+ SMATCAT.o SMATCAT-.o TUBETOOL.o UPXSCCA.o \
+ UPXSCCA-.o
+
+axiom_algebra_layer_15_nrlibis = \
+ $(axiom_algebra_layer_15:.$(OBJEXT)=.NRLIBS/code.$(OBJEXT))
+
+axiom_algebra_layer_15_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_15))
+@
+
+\subsection{Layer16}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+efupxs.spad.pamphlet (EFUPXS)
+lodop.spad.pamphlet (MLO OMLO NCODIV ODR DPMO DPMM)
+space.spad.pamphlet (SPACEC SPACE3 TOPSP)
+\end{verbatim}
+
+<<layer16>>=
+axiom_algebra_layer_16 = \
+ DPMM.o EFUPXS.o FFINTBAS.o FRIDEAL.o \
+ FRIDEAL2.o FRMOD.o FSAGG.o FSAGG-.o \
+ IBATOOL.o INTFACT.o KDAGG.o KDAGG-.o \
+ MSETAGG.o MONOGEN.o MONOGEN-.o NFINTBAS.o \
+ SPACE3.o
+
+axiom_algebra_layer_16_nrlibs = \
+ $(axiom_algebra_layer_16:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_16_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_16))
+@
+
+\subsection{Layer17}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+algext.spad.pamphlet (SAE)
+aggcat.spad.pamphlet (AGG HOAGG CLAGG BGAGG SKAGG QUAGG DQAGG PRQAGG DIOPS
+ DIAGG MDAGG SETAGG FSAGG MSETAGG OMSAGG KDAGG ELTAB
+ ELTAGG ISAGG TBAGG RCAGG BRAGG DLAGG URAGG STAGG LNAGG
+ FLAGG A1AGG ELAGG LSAGG ALAGG SRAGG BTAGG ITAGG)
+aggcat2.spad.pamphlet (FLAGG2 FSAGG2)
+galfact.spad.pamphlet (GALFACT)
+intfact.spad.pamphlet (PRIMES IROOT INTFACT)
+padiclib.spad.pamphlet (IBPTOOLS IBACHIN PWFFINTB)
+perm.spad.pamphlet (PERMCAT PERM)
+permgrps.spad.pamphlet (PERMGRP PGE)
+random.spad.pamphlet (RANDSRC RDIST INTBIT RIDIST RFDIST)
+sgcf.spad.pamphlet (SGCF)
+string.spad.pamphlet (CHAR CCLASS ISTRING STRING STRICAT)
+view3D.spad.pamphlet (VIEW3D)
+\end{verbatim}
+
+<<layer17>>=
+axiom_algebra_layer_17 = \
+ CCLASS.o FSAGG2.o GALFACT.o IALGFACT.o \
+ IBACHIN.o NORMMA.o ODERED.o OMSAGG.o \
+ PERM.o PERMGRP.o PRIMES.o PWFFINTB.o \
+ RDIST.o SAE.o SAEFACT.o SAERFFC.o \
+ SGCF.o TBAGG.o TBAGG-.o VIEW3D.o
+
+axiom_algebra_layer_17_nrlibs = \
+ $(axiom_algebra_layer_17:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_17_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_17))
+@
+
+\subsection{Layer18}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+d01Package.spad.pamphlet (INTPACK)
+list.spad.pamphlet (ILIST LIST LIST2 LIST3 LIST2MAP ALIST)
+pf.spad.pamphlet (IPF PF)
+table.spad.pamphlet (HASHTBL INTABL TABLE EQTBL STRTBL GSTBL STBL)
+\end{verbatim}
+
+<<layer18>>=
+axiom_algebra_layer_18 = \
+ ALIST.o EQTBL.o GSTBL.o HASHTBL.o \
+ INTABL.o INTFTBL.o INTPACK.o IPF.o \
+ KAFILE.o PATRES.o STBL.o STRTBL.o \
+ TABLE.o TBCMPPK.o
+
+axiom_algebra_layer_18_nrlibs = \
+ $(axiom_algebra_layer_18:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_18_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_18))
+@
+
+\subsection{Layer19}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+acplot.spad.pamphlet (REALSOLV ACPLOT)
+alql.spad.pamphlet (DLIST ICARD DBASE QEQUAT MTHING OPQUERY)
+any.spad.pamphlet (NONE NONE1 ANY ANY1)
+c02.spad.pamphlet (NAGC02)
+c05.spad.pamphlet (NAGC05)
+c06.spad.pamphlet (NAGC06)
+d01routine.spad.pamphlet (D01AJFA D01AKFA D01AMFA D01APFA D01AQFA D01ALFA
+ D01ANFA D01ASFA D01GBFA D01FCFA)
+d02Package.spad.pamphlet (ODEPACK)
+d03agents.spad.pamphlet (D03AGNT)
+d03Package.spad.pamphlet (PDEPACK)
+drawopt.spad.pamphlet (DROPT DROPT1 DROPT0)
+eigen.spad.pamphlet (EP CHARPOL)
+e01.spad.pamphlet (NAGE01)
+e02.spad.pamphlet (NAGE02)
+e04.spad.pamphlet (NAGE04)
+e04agents.spad.pamphlet (E04AGNT)
+e04Package.spad.pamphlet (OPTPACK)
+ffcg.spad.pamphlet (FFCGP FFCGX FFCG)
+ffp.spad.pamphlet (FFP FFX IFF FF)
+files.spad.pamphlet (FILECAT FILE TEXTFILE BINFILE KAFILE LIB)
+float.spad.pamphlet (FLOAT)
+fnla.spad.pamphlet (OSI COMM HB FNLA)
+fortpak.spad.pamphlet (FCPAK1 NAGSP FORT FOP TEMUTL MCALCFN)
+forttyp.spad.pamphlet (FST FT SYMTAB SYMS)
+fparfrac.spad.pamphlet (FPARFRAC)
+fr.spad.pamphlet (FR FRUTIL FR2)
+f07.spad.pamphlet (NAGF07)
+gdpoly.spad.pamphlet (GDMP DMP HDMP)
+ideal.spad.pamphlet (IDEAL)
+intaux.spad.pamphlet (IR IR2)
+intclos.spad.pamphlet (TRIMAT IBATOOL FFINTBAS WFFINTBS NFINTBAS)
+integer.spad.pamphlet (INTSLPE INT NNI PI ROMAN)
+kl.spad.pamphlet (CACHSET SCACHE MKCHSET KERNEL KERNEL2)
+lmdict.spad.pamphlet (LMDICT)
+matrix.spad.pamphlet (IMATRIX MATRIX RMATRIX SQMATRIX)
+misc.spad.pamphlet (SAOS)
+mkfunc.spad.pamphlet (INFORM INFORM1 MKFUNC MKUCFUNC MKBCFUNC MKFLCFN)
+modgcd.spad.pamphlet (INMODGCD)
+mset.spad.pamphlet (MSET)
+multpoly.spad.pamphlet (POLY POLY2 MPOLY SMP INDE)
+naalgc.spad.pamphlet (MONAD MONADWU NARNG NASRING NAALG FINAALG FRNAALG)
+newdata.spad.pamphlet (IPRNTPK TBCMPPK SPLNODE SPLTREE)
+omerror.spad.pamphlet (OMERRK OMERR)
+op.spad.pamphlet (BOP BOP1 COMMONOP)
+out.spad.pamphlet (OUT SPECOUT DISPLAY)
+outform.spad.pamphlet (NUMFMT OUTFORM)
+patmatch1.spad.pamphlet (PATRES PATRES2 PATLRES PATMAB FPATMAB PMSYM PMKERNEL
+ PMDOWN PMTOOLS PMLSAGG)
+pattern.spad.pamphlet (PATTERN PATTERN1 PATTERN2 PATAB)
+pscat.spad.pamphlet (PSCAT UPSCAT UTSCAT ULSCAT UPXSCAT MTSCAT)
+qalgset.spad.pamphlet (QALGSET QALGSET2)
+reclos.spad.pamphlet (POLUTIL RRCC RCFIELD ROIRC RECLOS)
+rep1.spad.pamphlet (REP1)
+routines.spad.pamphlet (ROUTINE ATTRBUT)
+s.spad.pamphlet (NAGS)
+seg.spad.pamphlet (SEGCAT SEGXCAT SEG SEG2 SEGBIND SETBIND2 UNISEG UNISEG2
+ INCRMAPS)
+sets.spad.pamphlet (SET)
+sups.spad.pamphlet (ISUPS)
+syssolp.spad.pamphlet (SYSSOLP)
+variable.spad.pamphlet (OVAR VARIABLE RULECOLD FUNCTION ANON)
+\end{verbatim}
+
+<<layer19>>=
+axiom_algebra_layer_19 = \
+ ACF.o ACF-.o ACPLOT.o ANTISYM.o \
+ ANY.o ASP12.o ASP27.o ASP28.o \
+ ASP33.o ASP49.o ASP55.o ASP7.o \
+ ASP78.o ASP8.o ASP9.o ATTRBUT.o \
+ BOP.o BOP1.o COMMONOP.o COMPCAT.o \
+ COMPCAT-.o DRAW.o DRAWCFUN.o DROPT.o \
+ DROPT0.o D01ANFA.o D01ASFA.o D03AGNT.o \
+ EP.o E04AGNT.o FCPAK1.o FEXPR.o \
+ FFCAT.o FFCAT-.o FFCGP.o FFNBP.o \
+ FFP.o FLOAT.o FPARFRAC.o FR.o \
+ FRNAALG.o FRNAALG-.o FS.o FS-.o \
+ FST.o FUNCTION.o GDMP.o HACKPI.o \
+ IDEAL.o INFORM.o INFORM1.o IPRNTPK.o \
+ IR.o ISUPS.o KERNEL.o LIB.o \
+ LMDICT.o LODOOPS.o MATRIX.o MKFLCFN.o \
+ MSET.o M3D.o NAGC02.o NAGC05.o \
+ NAGC06.o NAGD03.o NAGE01.o NAGE02.o \
+ NAGE04.o NAGF07.o NAGS.o NAGSP.o \
+ NREP.o NUMFMT.o OC.o OC-.o \
+ ODEPACK.o ODERAT.o OMERR.o OMERRK.o \
+ OPTPACK.o OSI.o PATTERN.o OVAR.o \
+ PMKERNEL.o PMSYM.o POLY.o PRIMELT.o \
+ QALGSET2.o QEQUAT.o RECLOS.o REP1.o \
+ RESULT.o QUATCAT.o QUATCAT-.o RFFACT.o \
+ RMATRIX.o ROMAN.o ROUTINE.o RPOLCAT.o \
+ RPOLCAT-.o RULECOLD.o SAOS.o SEGBIND.o \
+ SET.o SPECOUT.o SQMATRIX.o SWITCH.o \
+ SYMS.o SYMTAB.o SYSSOLP.o UTSCAT.o \
+ UTSCAT-.o VARIABLE.o WFFINTBS.o
+
+axiom_algebra_layer_19_nrlibs = \
+ $(axiom_algebra_layer_19:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_19_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_19))
+@
+
+\subsection{Layer20}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+algfact.spad.pamphlet (IALGFACT SAEFACT RFFACT SAERFFC ALGFACT)
+algfunc.spad.pamphlet (ACF ACFS AF)
+asp.spad.pamphlet (ASP1 ASP10 ASP12 ASP19 ASP20 ASP24 ASP27 ASP28 ASP29 ASP30
+ ASP31 ASP33 ASP34 ASP35 ASP4 ASP41 ASP42 ASP49 ASP50 ASP55
+ ASP6 ASP7 ASP73 ASP74 ASP77 ASP78 ASP8 ASP80 ASP9)
+constant.spad.pamphlet (IAN AN)
+cmplxrt.spad.pamphlet (CMPLXRT)
+crfp.spad.pamphlet (CRFP)
+curve.spad.pamphlet (FFCAT MMAP FFCAT2 CHAVAR RDFF ALGFF)
+derham.spad.pamphlet (LALG EAB ANTISYM DERHAM)
+draw.spad.pamphlet (DRAWCFUN DRAW DRAWCURV DRAWPT)
+d01.spad.pamphlet (NAGD01)
+efstruc.spad.pamphlet (SYMFUNC TANEXP EFSTRUC ITRIGMNP TRIGMNIP CTRIGMNP)
+elemntry.spad.pamphlet (EF)
+elfuts.spad.pamphlet (ELFUTS)
+expexpan.spad.pamphlet (EXPUPXS UPXSSING EXPEXPAN)
+exprode.spad.pamphlet (EXPRODE)
+e04routine.spad.pamphlet (E04DFGA E04FDFA E04GCFA E04JAFA E04MBFA E04NAFA
+ E04UCFA)
+f01.spad.pamphlet (NAGF01)
+f02.spad.pamphlet (NAGF02)
+f04.spad.pamphlet (NAGF04)
+fortmac.spad.pamphlet (MINT MFLOAT MCMPLX)
+fortran.spad.pamphlet (RESULT FC FORTRAN M3D SFORT SWITCH FTEM FEXPR)
+fspace.spad.pamphlet (ES ES1 ES2 FS FS2)
+fs2ups.spad.pamphlet (FS2UPS)
+funcpkgs.spad.pamphlet (FSUPFACT)
+gaussfac.spad.pamphlet (GAUSSFAC)
+gaussian.spad.pamphlet (COMPCAT COMPLPAT CPMATCH COMPLEX COMPLEX2 COMPFACT
+ CINTSLPE)
+generic.spad.pamphlet (GCNAALG CVMP)
+genufact.spad.pamphlet (GENUFACT)
+genups.spad.pamphlet (GENUPS)
+infprod.spad.pamphlet (STINPROD INFPROD0 INPRODPF INPRODFF)
+intaf.spad.pamphlet (INTG0 INTPAF INTAF)
+intalg.spad.pamphlet (DBLRESP INTHERAL INTALG)
+intef.spad.pamphlet (INTEF)
+intpm.spad.pamphlet (INTPM)
+kovacic.spad.pamphlet (KOVACIC)
+lie.spad.pamphlet (LIE JORDAN LSQM)
+liouv.spad.pamphlet (LF)
+lodof.spad.pamphlet (SETMN PREASSOC ASSOCEQ LODOF)
+manip.spad.pamphlet (FACTFUNC POLYROOT ALGMANIP SIMPAN TRMANIP)
+multfact.spad.pamphlet (INNMFACT MULTFACT ALGMFACT)
+naalg.spad.pamphlet (ALGSC SCPKG ALGPKG FRNAAF2)
+newpoly.spad.pamphlet (NSUP NSUP2 RPOLCAT NSMP)
+nlinsol.spad.pamphlet (RETSOL NLINSOL)
+numeigen.spad.pamphlet (IFSPRMELT.oNEP NREP NCEP)
+numeric.spad.pamphlet (NUMERIC DRAWHACK)
+numsolve.spad.pamphlet (INFSP FLOATRP FLOATCP)
+oct.spad.pamphlet (OC OCT OCTCT2)
+odealg.spad.pamphlet (ODESYS ODERED ODEPAL)
+openmath.spad.pamphlet (OMEXPR)
+pade.spad.pamphlet (PADEPAC PADE)
+patmatch2.spad.pamphlet (PMINS PMQFCAT PMPLCT PMFS PATMATCH)
+pfo.spad.pamphlet (FORDER RDIV PFOTOOLS PFOQ FSRED PFO)
+polset.spad.pamphlet (PSETCAT GPOLSET)
+primelt.spad.pamphlet (PRIMELT FSPRMELT)
+quat.spad.pamphlet (QUATCAT QUAT QUATCT2)
+rdeef.spad.pamphlet (INTTOOLS RDEEF)
+rdesys.spad.pamphlet (RDETRS RDEEFS)
+riccati.spad.pamphlet (ODEPRRIC ODERTRIC)
+rule.spad.pamphlet (RULE APPRULE RULESET)
+sign.spad.pamphlet (TOOLSIGN INPSIGN SIGNRF LIMITRF)
+special.spad.pamphlet (DFSFUN ORTHPOL NTPOLFN)
+suts.spad.pamphlet (SUTS)
+tools.spad.pamphlet (ESTOOLS ESTOOLS1 ESTOOLS2)
+triset.spad.pamphlet (TSETCAT GTSET PSETPK)
+tube.spad.pamphlet (TUBE TUBETOOL EXPRTUBE NUMTUBE)
+utsode.spad.pamphlet (UTSODE)
+\end{verbatim}
+
+<<layer20>>=
+axiom_algebra_layer_20 = \
+ ACFS.o ACFS-.o AF.o ALGFACT.o \
+ ALGFF.o ALGMANIP.o ALGMFACT.o ALGPKG.o \
+ ALGSC.o AN.o APPRULE.o ASP19.o \
+ ASP20.o ASP30.o ASP31.o ASP35.o \
+ ASP41.o ASP42.o ASP74.o ASP77.o \
+ ASP80.o CINTSLPE.o COMPFACT.o COMPLEX.o \
+ COMPLPAT.o CMPLXRT.o CPMATCH.o CRFP.o \
+ CTRIGMNP.o D01WGTS.o D02AGNT.o D03EEFA.o \
+ DBLRESP.o DERHAM.o DFSFUN.o DRAWCURV.o \
+ E04NAFA.o E04UCFA.o EF.o EFSTRUC.o \
+ ELFUTS.o ESTOOLS.o EXPEXPAN.o EXPRODE.o \
+ EXPRTUBE.o EXPR2.o FC.o FDIVCAT.o \
+ FDIVCAT-.o FDIV2.o FFCAT2.o FLOATCP.o \
+ FORDER.o FORTRAN.o FSRED.o FSUPFACT.o \
+ FRNAAF2.o FSPECF.o FS2.o FS2UPS.o \
+ GAUSSFAC.o GCNAALG.o GENUFACT.o GENUPS.o \
+ GTSET.o GPOLSET.o IAN.o INEP.o \
+ INFPROD0.o INFSP.o INPRODFF.o INPRODPF.o \
+ INTAF.o INTALG.o INTEF.o INTG0.o \
+ INTHERAL.o INTPAF.o INTPM.o INTTOOLS.o \
+ ITRIGMNP.o JORDAN.o KOVACIC.o LF.o \
+ LIE.o LODOF.o LSQM.o OMEXPR.o \
+ MCMPLX.o MULTFACT.o NAGD01.o NAGD02.o \
+ NAGF01.o NAGF02.o NAGF04.o NCEP.o \
+ NLINSOL.o NSMP.o NUMERIC.o OCT.o \
+ OCTCT2.o ODEPAL.o ODERTRIC.o PADE.o \
+ PAN2EXPR.o PDEPACK.o PFO.o PFOQ.o \
+ PICOERCE.o PMASSFS.o PMFS.o PMPREDFS.o \
+ PSETPK.o QUAT.o QUATCT2.o RADFF.o \
+ RDEEF.o RDEEFS.o RDIV.o RSETCAT.o \
+ RSETCAT-.o RULE.o RULESET.o SIMPAN.o \
+ SFORT.o SOLVESER.o SUMFS.o SUTS.o \
+ TOOLSIGN.o TRIGMNIP.o TRMANIP.o ULSCCAT.o \
+ ULSCCAT-.o UPXSSING.o UTSODE.o UTSODETL.o \
+ UTS2.o WUTSET.o
+
+axiom_algebra_layer_20_nrlibs = \
+ $(axiom_algebra_layer_20:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_20_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_20))
+@
+
+\subsection{Layer21}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+cont.spad.pamphlet (ESCONT ESCONT1)
+ddfact.spad.pamphlet (DDFACT)
+defintef.spad.pamphlet (DEFINTEF)
+defintrf.spad.pamphlet (DFINTTLS DEFINTRF)
+divisor.spad.pamphlet (FRIDEAL FRIDEAL2 MHROWRED FRMOD FDIVCAT HELLFDIV FDIV
+ FDIV2)
+d01transform.spad.pamphlet (D01TRNS)
+efuls.spad.pamphlet (EFULS)
+expr.spad.pamphlet (EXPR PAN2EXPR EXPR2 PMPREDFS PMASSFS PMPRED PMASS HACKPI
+ PICOERCE)
+expr2ups.spad.pamphlet (EXPR2UPS)
+fs2expxp.spad.pamphlet (FS2EXPXP)
+gseries.spad.pamphlet (GSERIES)
+integrat.spad.pamphlet (FSCINT FSINT)
+irexpand.spad.pamphlet (IR2F IRRF2F)
+laplace.spad.pamphlet (LAPLACE INVLAPLA)
+laurent.spad.pamphlet (ULSCCAT ULSCONS ULS USL2)
+nlode.spad.pamphlet (NODE1)
+oderf.spad.pamphlet (BALFACT BOUNDZRO ODEPRIM UTSODETL ODERAT ODETOOLS ODEINT
+ ODECONST)
+puiseux.spad.pamphlet (UPXSCCA UPXSCONS UPXS UPXS2)
+radeigen.spad.pamphlet (REP)
+solverad.spad.pamphlet (SOLVERAD)
+suls.spad.pamphlet (SULS)
+supxs.spad.pamphlet (SUPXS)
+taylor.spad.pamphlet (ITAYLOR UTS UTS2)
+\end{verbatim}
+
+<<layer21>>=
+axiom_algebra_layer_21 = \
+ DEFINTEF.o DFINTTLS.o DEFINTRF.o D01TRNS.o \
+ EFULS.o ESCONT.o EXPR.o EXPR2UPS.o \
+ FDIV.o FSCINT.o FSINT.o FS2EXPXP.o \
+ GSERIES.o HELLFDIV.o INVLAPLA.o IR2F.o \
+ IRRF2F.o LAPLACE.o LIMITPS.o LODEEF.o \
+ NODE1.o ODECONST.o ODEINT.o REP.o \
+ SOLVERAD.o SULS.o SUPXS.o ULS.o \
+ ULSCONS.o UPXS.o UPXSCONS.o UTS.o
+
+axiom_algebra_layer_21_nrlibs = \
+ $(axiom_algebra_layer_21:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_21_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_21))
+@
+
+\subsection{Layer22}
+
+\subsubsection{Completed spad files}
+
+\begin{verbatim}
+asp.spad.pamphlet (ASP29)
+combfunc.spad.pamphlet (COMBF)
+d01agents.spad.pamphlet (D01AGNT SNTSCAT)
+ffnb.spad.pamphlet (INBFF)
+limitps.spad.pamphlet (SIGNEF)
+lodo.spad.pamphlet (LODO LODO1 LODO2)
+newpoint.spad.pamphlet (SUBSPACE)
+nregset.spad.pamphlet (NTSCAT)
+primelt.spad.pamphlet (FSPRMELT)
+regset.spad.pamphlet (REGSET RSETGCD RSDCMPK)
+sregset.spad.pamphlet (SFRTCAT SRDCMPK SREGSET)
+sttf.spad.pamphlet (STTF)
+transsolve.spad.pamphlet (SOLVETRA)
+zerodim.spad.pamphlet (RGCHAIN ZDSOLVE)
+\end{verbatim}
+\subsection{Layer21}
+<<layer22>>=
+axiom_algebra_layer_22 = \
+ ASP29.o COMBF.o D01AGNT.o FSPRMELT.o \
+ INBFF.o LODO.o LODO1.o LODO2.o \
+ NTSCAT.o REGSET.o RGCHAIN.o RSETGCD.o \
+ RSDCMPK.o SFRTCAT.o SIGNEF.o SNTSCAT.o \
+ SOLVETRA.o SRDCMPK.o SREGSET.o STTF.o \
+ SUBSPACE.o ZDSOLVE.o
+
+axiom_algebra_layer_22_nrlibs = \
+ $(axiom_algebra_layer_22:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_22_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_22))
+@
+
+\subsection{Final layer spad files}
+
+These files have not yet been fully analyzed for dependencies but
+have added in alphabetical order in this final layer. This
+ordering is apparently adequate.
+
+These files all depend on layer22.
+\begin{verbatim}
+algcat.spad.pamphlet (CPIMA)
+nregset.spad.pamphlet (NORMPK)
+nsregset.spad.pamphlet (LAZM3PK)
+regset.spad.pamphlet (QCMPACK)
+sregset.spad.pamphlet (SFRGCD SFQCMPK)
+zerodim.spad.pamphlet (LEXTRIPK IRURPK RURPK)
+\end{verbatim}
+
+<<layer23>>=
+axiom_algebra_layer_23 = \
+ CPIMA.o IRURPK.o LAZM3PK.o LEXTRIPK.o \
+ NORMPK.o QCMPACK.o RURPK.o SFRGCD.o \
+ SFQCMPK.o INTRVL.o ODEEF.o
+
+axiom_algebra_layer_23_nrlibs = \
+ $(axiom_algebra_layer_23:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_23_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_23))
+@
+
+\subsection{User Layer for newly added algebra}
+
+Rather than classify newly created algebra into the existing type lattice
+we add it here.
+<<USERLAYER>>=
+axiom_algebra_layer_user = RINTERP.o
+
+axiom_algebra_layer_user_nrlibs = \
+ $(axiom_algebra_layer_user:.$(OBJEXT)=.NRLIB/code.$(OBJEXT))
+
+axiom_algebra_layer_user_objects = \
+ $(addprefix $(OUT)/, $(axiom_algebra_layer_user))
+@
+
+\section{Broken Files}
+
+These files are Aldor files
+\begin{verbatim}
+axtimer.as Timer
+iviews.as InventorRenderPackage IVREND
+ffrac.as FormalFraction FORMAL
+iviews.as InventorViewPort IVVIEW
+iviews.as InventorDataSink IVDATA
+herm.as PackedHermitianSequence PACKED
+nsfip.as NagSpecialFunctionsInterfacePackage NAGSPE
+nrc.as NagResultChecks NAGRES
+nqip.as NagQuadratureInterfacePackage NAGQUA
+noptip.as NagOptimizationInterfacePackage NAGOPT
+nepip.as NagEigenInterfacePackage NAGEIG
+ndftip.as NagDiscreteFourierTransformInterfacePackage NAGDIS
+\end{verbatim}
+
+These domains are referenced but don't exist
+\begin{verbatim}
+OBJECT
+\end{verbatim}
+
+\section{The Environment}
+
+\subsection{The working directories}
+
+We define 5 directories for this build. The{\bf IN} directory
+contains the pamphlet files for the algebra. These are expanded
+into the{\bf MID} directory as either .spad or .as files. The
+.spad files are compiled by the native spad internal compiler.
+The .as files are compiled using the Aldor compiler. The output
+of the compilation has two purposes. Part of the information is
+used to build various database files (daase files). The other
+part is executable code which is placed in the {\bf OUT}
+directory. When invoked as ``make document'' we construct
+the .dvi files in the{\bf DOC} directory.
+
+The [[OUTSRC=$(axiom_target_srcdir)/algebra]] subdirectory contains the
+algebra source files extracted from the pamphlet files. These sources
+allow the end user to change the algebra if needed.
+
+<<environment>>=
+
+IN=$(srcdir)
+OUT=$(axiom_targetdir)/algebra
+DOC=$(axiom_target_docdir)/src/algebra
+OUTSRC=$(axiom_target_srcdir)/algebra
+INPUT=../input
+
+EXTRACT_BOOTSTRAP_FILE = \
+ $(axiom_build_document) --output=$@ --tangle="$@ BOOTSTRAP" $<
+
+@
+
+\subsection{The depsys variable}
+
+The {\bf depsys} image is the compile-time environment for boot and lisp
+files.
+
+<<environment>>=
+
+DEPSYS= ../interp/depsys$(EXEEXT)
+
+@
+
+\subsection{The interpsys variable}
+The {\bf interpsys} image is the compile-time environment for algebra
+files.
+
+<<environment>>=
+
+INTERPSYS = \
+ AXIOM="$(AXIOM)" \
+ DAASE="$(axiom_src_datadir)" \
+ ../interp/interpsys$(EXEEXT)
+
+@
+
+\subsection{The SPADFILES list}
+Note that we have excluded {\bf mlift.spad.jhd} from this list.
+We need to figure out which mlift.spad to keep.
+
+<<environment>>=
+
+SPADFILES= \
+ ${OUTSRC}/acplot.spad ${OUTSRC}/aggcat2.spad ${OUTSRC}/aggcat.spad \
+ ${OUTSRC}/algcat.spad ${OUTSRC}/algext.spad ${OUTSRC}/algfact.spad \
+ ${OUTSRC}/algfunc.spad ${OUTSRC}/allfact.spad ${OUTSRC}/alql.spad \
+ ${OUTSRC}/annacat.spad ${OUTSRC}/any.spad ${OUTSRC}/array1.spad \
+ ${OUTSRC}/array2.spad ${OUTSRC}/asp.spad ${OUTSRC}/attreg.spad \
+ ${OUTSRC}/bags.spad ${OUTSRC}/bezout.spad ${OUTSRC}/boolean.spad \
+ ${OUTSRC}/brill.spad \
+ ${OUTSRC}/c02.spad ${OUTSRC}/c05.spad ${OUTSRC}/c06.spad \
+ ${OUTSRC}/card.spad ${OUTSRC}/carten.spad ${OUTSRC}/catdef.spad \
+ ${OUTSRC}/cden.spad ${OUTSRC}/clifford.spad ${OUTSRC}/clip.spad \
+ ${OUTSRC}/cmplxrt.spad ${OUTSRC}/coerce.spad ${OUTSRC}/color.spad \
+ ${OUTSRC}/combfunc.spad ${OUTSRC}/combinat.spad ${OUTSRC}/complet.spad \
+ ${OUTSRC}/constant.spad ${OUTSRC}/contfrac.spad ${OUTSRC}/cont.spad \
+ ${OUTSRC}/coordsys.spad ${OUTSRC}/cra.spad ${OUTSRC}/crfp.spad \
+ ${OUTSRC}/curve.spad ${OUTSRC}/cycles.spad ${OUTSRC}/cyclotom.spad \
+ ${OUTSRC}/d01agents.spad ${OUTSRC}/d01Package.spad \
+ ${OUTSRC}/d01routine.spad ${OUTSRC}/d01.spad ${OUTSRC}/d01transform.spad \
+ ${OUTSRC}/d01weights.spad ${OUTSRC}/d02agents.spad \
+ ${OUTSRC}/d02Package.spad ${OUTSRC}/d02routine.spad ${OUTSRC}/d02.spad \
+ ${OUTSRC}/d03agents.spad ${OUTSRC}/d03Package.spad \
+ ${OUTSRC}/d03routine.spad ${OUTSRC}/d03.spad ${OUTSRC}/ddfact.spad \
+ ${OUTSRC}/defaults.spad ${OUTSRC}/defintef.spad ${OUTSRC}/defintrf.spad \
+ ${OUTSRC}/degred.spad ${OUTSRC}/derham.spad ${OUTSRC}/dhmatrix.spad \
+ ${OUTSRC}/divisor.spad ${OUTSRC}/dpolcat.spad ${OUTSRC}/drawopt.spad \
+ ${OUTSRC}/drawpak.spad ${OUTSRC}/draw.spad \
+ ${OUTSRC}/e01.spad ${OUTSRC}/e02.spad ${OUTSRC}/e04agents.spad \
+ ${OUTSRC}/e04Package.spad ${OUTSRC}/e04routine.spad ${OUTSRC}/e04.spad \
+ ${OUTSRC}/efstruc.spad ${OUTSRC}/efuls.spad ${OUTSRC}/efupxs.spad \
+ ${OUTSRC}/eigen.spad ${OUTSRC}/elemntry.spad ${OUTSRC}/elfuts.spad \
+ ${OUTSRC}/equation1.spad ${OUTSRC}/equation2.spad ${OUTSRC}/error.spad \
+ ${OUTSRC}/expexpan.spad ${OUTSRC}/expr2ups.spad \
+ ${OUTSRC}/exprode.spad ${OUTSRC}/expr.spad \
+ ${OUTSRC}/f01.spad ${OUTSRC}/f02.spad ${OUTSRC}/f04.spad \
+ ${OUTSRC}/f07.spad ${OUTSRC}/facutil.spad ${OUTSRC}/ffcat.spad \
+ ${OUTSRC}/ffcg.spad ${OUTSRC}/fff.spad ${OUTSRC}/ffhom.spad \
+ ${OUTSRC}/ffnb.spad ${OUTSRC}/ffpoly2.spad ${OUTSRC}/ffpoly.spad \
+ ${OUTSRC}/ffp.spad ${OUTSRC}/ffx.spad \
+ ${OUTSRC}/files.spad ${OUTSRC}/float.spad ${OUTSRC}/fmod.spad \
+ ${OUTSRC}/fname.spad ${OUTSRC}/fnla.spad ${OUTSRC}/formula.spad \
+ ${OUTSRC}/fortcat.spad ${OUTSRC}/fortmac.spad ${OUTSRC}/fortpak.spad \
+ ${OUTSRC}/fortran.spad ${OUTSRC}/forttyp.spad ${OUTSRC}/fourier.spad \
+ ${OUTSRC}/fparfrac.spad ${OUTSRC}/fraction.spad ${OUTSRC}/free.spad \
+ ${OUTSRC}/fr.spad ${OUTSRC}/fs2expxp.spad ${OUTSRC}/fs2ups.spad \
+ ${OUTSRC}/fspace.spad ${OUTSRC}/funcpkgs.spad ${OUTSRC}/functions.spad \
+ ${OUTSRC}/galfact.spad ${OUTSRC}/galfactu.spad ${OUTSRC}/galpolyu.spad \
+ ${OUTSRC}/galutil.spad ${OUTSRC}/gaussfac.spad ${OUTSRC}/gaussian.spad \
+ ${OUTSRC}/gbeuclid.spad ${OUTSRC}/gbintern.spad ${OUTSRC}/gb.spad \
+ ${OUTSRC}/gdirprod.spad ${OUTSRC}/gdpoly.spad ${OUTSRC}/geneez.spad \
+ ${OUTSRC}/generic.spad ${OUTSRC}/genufact.spad ${OUTSRC}/genups.spad \
+ ${OUTSRC}/ghensel.spad ${OUTSRC}/gpgcd.spad ${OUTSRC}/gpol.spad \
+ ${OUTSRC}/grdef.spad ${OUTSRC}/groebf.spad ${OUTSRC}/groebsol.spad \
+ ${OUTSRC}/gseries.spad \
+ ${OUTSRC}/ideal.spad ${OUTSRC}/idecomp.spad ${OUTSRC}/indexedp.spad \
+ ${OUTSRC}/infprod.spad ${OUTSRC}/intaf.spad ${OUTSRC}/intalg.spad \
+ ${OUTSRC}/intaux.spad ${OUTSRC}/intclos.spad ${OUTSRC}/intef.spad \
+ ${OUTSRC}/integer.spad ${OUTSRC}/integrat.spad \
+ ${OUTSRC}/interval.spad \
+ ${OUTSRC}/intfact.spad ${OUTSRC}/intpm.spad \
+ ${OUTSRC}/intrf.spad \
+ ${OUTSRC}/irexpand.spad \
+ ${OUTSRC}/irsn.spad ${OUTSRC}/ituple.spad \
+ ${OUTSRC}/kl.spad ${OUTSRC}/kovacic.spad \
+ ${OUTSRC}/laplace.spad ${OUTSRC}/laurent.spad ${OUTSRC}/leadcdet.spad \
+ ${OUTSRC}/lie.spad ${OUTSRC}/limitps.spad ${OUTSRC}/lindep.spad \
+ ${OUTSRC}/lingrob.spad ${OUTSRC}/liouv.spad ${OUTSRC}/listgcd.spad \
+ ${OUTSRC}/list.spad ${OUTSRC}/lmdict.spad ${OUTSRC}/lodof.spad \
+ ${OUTSRC}/lodop.spad ${OUTSRC}/lodo.spad \
+ ${OUTSRC}/manip.spad ${OUTSRC}/mappkg.spad ${OUTSRC}/matcat.spad \
+ ${OUTSRC}/matfuns.spad ${OUTSRC}/matrix.spad ${OUTSRC}/matstor.spad \
+ ${OUTSRC}/mesh.spad ${OUTSRC}/mfinfact.spad ${OUTSRC}/misc.spad \
+ ${OUTSRC}/mkfunc.spad ${OUTSRC}/mkrecord.spad \
+ ${OUTSRC}/mlift.spad ${OUTSRC}/moddfact.spad ${OUTSRC}/modgcd.spad \
+ ${OUTSRC}/modmonom.spad ${OUTSRC}/modmon.spad ${OUTSRC}/modring.spad \
+ ${OUTSRC}/moebius.spad ${OUTSRC}/mring.spad ${OUTSRC}/mset.spad \
+ ${OUTSRC}/mts.spad ${OUTSRC}/multfact.spad ${OUTSRC}/multpoly.spad \
+ ${OUTSRC}/multsqfr.spad \
+ ${OUTSRC}/naalgc.spad ${OUTSRC}/naalg.spad \
+ ${OUTSRC}/newdata.spad ${OUTSRC}/newpoint.spad \
+ ${OUTSRC}/newpoly.spad ${OUTSRC}/nlinsol.spad ${OUTSRC}/nlode.spad \
+ ${OUTSRC}/npcoef.spad \
+ ${OUTSRC}/nregset.spad \
+ ${OUTSRC}/nsregset.spad ${OUTSRC}/numeigen.spad ${OUTSRC}/numeric.spad \
+ ${OUTSRC}/numode.spad ${OUTSRC}/numquad.spad ${OUTSRC}/numsolve.spad \
+ ${OUTSRC}/numtheor.spad \
+ ${OUTSRC}/oct.spad ${OUTSRC}/odealg.spad ${OUTSRC}/odeef.spad \
+ ${OUTSRC}/oderf.spad ${OUTSRC}/omcat.spad ${OUTSRC}/omdev.spad \
+ ${OUTSRC}/omerror.spad ${OUTSRC}/omserver.spad ${OUTSRC}/opalg.spad \
+ ${OUTSRC}/openmath.spad ${OUTSRC}/op.spad ${OUTSRC}/ore.spad \
+ ${OUTSRC}/outform.spad ${OUTSRC}/out.spad \
+ ${OUTSRC}/pade.spad ${OUTSRC}/padiclib.spad ${OUTSRC}/padic.spad \
+ ${OUTSRC}/paramete.spad ${OUTSRC}/partperm.spad ${OUTSRC}/patmatch1.spad \
+ ${OUTSRC}/patmatch2.spad ${OUTSRC}/pattern.spad ${OUTSRC}/pcurve.spad \
+ ${OUTSRC}/pdecomp.spad ${OUTSRC}/perman.spad ${OUTSRC}/permgrps.spad \
+ ${OUTSRC}/perm.spad ${OUTSRC}/pfbr.spad ${OUTSRC}/pfo.spad \
+ ${OUTSRC}/pfr.spad ${OUTSRC}/pf.spad ${OUTSRC}/pgcd.spad \
+ ${OUTSRC}/pgrobner.spad ${OUTSRC}/pinterp.spad ${OUTSRC}/pleqn.spad \
+ ${OUTSRC}/plot3d.spad ${OUTSRC}/plot.spad ${OUTSRC}/plottool.spad \
+ ${OUTSRC}/polset.spad ${OUTSRC}/poltopol.spad ${OUTSRC}/polycat.spad \
+ ${OUTSRC}/poly.spad ${OUTSRC}/primelt.spad ${OUTSRC}/print.spad \
+ ${OUTSRC}/product.spad ${OUTSRC}/prs.spad ${OUTSRC}/prtition.spad \
+ ${OUTSRC}/pscat.spad ${OUTSRC}/pseudolin.spad ${OUTSRC}/ptranfn.spad \
+ ${OUTSRC}/puiseux.spad \
+ ${OUTSRC}/qalgset.spad ${OUTSRC}/quat.spad \
+ ${OUTSRC}/radeigen.spad ${OUTSRC}/radix.spad ${OUTSRC}/random.spad \
+ ${OUTSRC}/ratfact.spad ${OUTSRC}/rdeef.spad ${OUTSRC}/rderf.spad \
+ ${OUTSRC}/rdesys.spad ${OUTSRC}/real0q.spad ${OUTSRC}/realzero.spad \
+ ${OUTSRC}/reclos.spad ${OUTSRC}/regset.spad ${OUTSRC}/rep1.spad \
+ ${OUTSRC}/rep2.spad ${OUTSRC}/resring.spad ${OUTSRC}/retract.spad \
+ ${OUTSRC}/rf.spad ${OUTSRC}/riccati.spad ${OUTSRC}/rinterp.spad \
+ ${OUTSRC}/routines.spad \
+ ${OUTSRC}/rule.spad \
+ ${OUTSRC}/seg.spad ${OUTSRC}/setorder.spad ${OUTSRC}/sets.spad \
+ ${OUTSRC}/sex.spad ${OUTSRC}/sf.spad ${OUTSRC}/sgcf.spad \
+ ${OUTSRC}/sign.spad ${OUTSRC}/si.spad ${OUTSRC}/smith.spad \
+ ${OUTSRC}/solvedio.spad ${OUTSRC}/solvefor.spad ${OUTSRC}/solvelin.spad \
+ ${OUTSRC}/solverad.spad ${OUTSRC}/sortpak.spad ${OUTSRC}/space.spad \
+ ${OUTSRC}/special.spad ${OUTSRC}/sregset.spad ${OUTSRC}/s.spad \
+ ${OUTSRC}/stream.spad ${OUTSRC}/string.spad ${OUTSRC}/sttaylor.spad \
+ ${OUTSRC}/sttf.spad ${OUTSRC}/sturm.spad ${OUTSRC}/suchthat.spad \
+ ${OUTSRC}/suls.spad ${OUTSRC}/sum.spad ${OUTSRC}/sups.spad \
+ ${OUTSRC}/supxs.spad ${OUTSRC}/suts.spad ${OUTSRC}/symbol.spad \
+ ${OUTSRC}/syssolp.spad ${OUTSRC}/system.spad \
+ ${OUTSRC}/tableau.spad ${OUTSRC}/table.spad ${OUTSRC}/taylor.spad \
+ ${OUTSRC}/tex.spad ${OUTSRC}/tools.spad ${OUTSRC}/transsolve.spad \
+ ${OUTSRC}/tree.spad ${OUTSRC}/trigcat.spad ${OUTSRC}/triset.spad \
+ ${OUTSRC}/tube.spad ${OUTSRC}/twofact.spad \
+ ${OUTSRC}/unifact.spad ${OUTSRC}/updecomp.spad ${OUTSRC}/updivp.spad \
+ ${OUTSRC}/utsode.spad \
+ ${OUTSRC}/variable.spad ${OUTSRC}/vector.spad ${OUTSRC}/view2D.spad \
+ ${OUTSRC}/view3D.spad ${OUTSRC}/viewDef.spad ${OUTSRC}/viewpack.spad \
+ ${OUTSRC}/void.spad \
+ ${OUTSRC}/weier.spad ${OUTSRC}/wtpol.spad \
+ ${OUTSRC}/xlpoly.spad ${OUTSRC}/xpoly.spad \
+ ${OUTSRC}/ystream.spad \
+ ${OUTSRC}/zerodim.spad
+
+@
+
+\subsection{The ALDORFILES list}
+<<environment>>=
+
+ALDORFILES= \
+ axtimer.as \
+ ffrac.as \
+ herm.as \
+ interval.as \
+ invnode.as \
+ invrender.as \
+ invtypes.as \
+ invutils.as \
+ iviews.as \
+ ndftip.as \
+ nepip.as \
+ noptip.as nqip.as \
+ nrc.as nsfip.as
+
+@
+
+\subsection{The DOCFILES list}
+<<environment>>=
+
+DOCFILES= \
+ ${DOC}/acplot.spad.dvi ${DOC}/aggcat2.spad.dvi ${DOC}/aggcat.spad.dvi \
+ ${DOC}/algcat.spad.dvi ${DOC}/algext.spad.dvi ${DOC}/algfact.spad.dvi \
+ ${DOC}/algfunc.spad.dvi ${DOC}/allfact.spad.dvi ${DOC}/alql.spad.dvi \
+ ${DOC}/annacat.spad.dvi ${DOC}/any.spad.dvi ${DOC}/array1.spad.dvi \
+ ${DOC}/array2.spad.dvi ${DOC}/asp.spad.dvi ${DOC}/attreg.spad.dvi \
+ ${DOC}/axtimer.as.dvi \
+ ${DOC}/bags.spad.dvi ${DOC}/bezout.spad.dvi ${DOC}/boolean.spad.dvi \
+ ${DOC}/brill.spad.dvi \
+ ${DOC}/c02.spad.dvi ${DOC}/c05.spad.dvi ${DOC}/c06.spad.dvi \
+ ${DOC}/card.spad.dvi ${DOC}/carten.spad.dvi ${DOC}/catdef.spad.dvi \
+ ${DOC}/cden.spad.dvi ${DOC}/clifford.spad.dvi ${DOC}/clip.spad.dvi \
+ ${DOC}/cmplxrt.spad.dvi ${DOC}/coerce.spad.dvi ${DOC}/color.spad.dvi \
+ ${DOC}/combfunc.spad.dvi ${DOC}/combinat.spad.dvi ${DOC}/complet.spad.dvi \
+ ${DOC}/constant.spad.dvi ${DOC}/contfrac.spad.dvi ${DOC}/cont.spad.dvi \
+ ${DOC}/coordsys.spad.dvi ${DOC}/cra.spad.dvi ${DOC}/crfp.spad.dvi \
+ ${DOC}/curve.spad.dvi ${DOC}/cycles.spad.dvi ${DOC}/cyclotom.spad.dvi \
+ ${DOC}/d01agents.spad.dvi ${DOC}/d01Package.spad.dvi \
+ ${DOC}/d01routine.spad.dvi ${DOC}/d01.spad.dvi ${DOC}/d01transform.spad.dvi \
+ ${DOC}/d01weights.spad.dvi ${DOC}/d02agents.spad.dvi \
+ ${DOC}/d02Package.spad.dvi ${DOC}/d02routine.spad.dvi ${DOC}/d02.spad.dvi \
+ ${DOC}/d03agents.spad.dvi ${DOC}/d03Package.spad.dvi \
+ ${DOC}/d03routine.spad.dvi ${DOC}/d03.spad.dvi ${DOC}/ddfact.spad.dvi \
+ ${DOC}/defaults.spad.dvi ${DOC}/defintef.spad.dvi ${DOC}/defintrf.spad.dvi \
+ ${DOC}/degred.spad.dvi ${DOC}/derham.spad.dvi ${DOC}/dhmatrix.spad.dvi \
+ ${DOC}/divisor.spad.dvi ${DOC}/dpolcat.spad.dvi ${DOC}/drawopt.spad.dvi \
+ ${DOC}/drawpak.spad.dvi ${DOC}/draw.spad.dvi \
+ ${DOC}/e01.spad.dvi ${DOC}/e02.spad.dvi ${DOC}/e04agents.spad.dvi \
+ ${DOC}/e04Package.spad.dvi ${DOC}/e04routine.spad.dvi ${DOC}/e04.spad.dvi \
+ ${DOC}/efstruc.spad.dvi ${DOC}/efuls.spad.dvi ${DOC}/efupxs.spad.dvi \
+ ${DOC}/eigen.spad.dvi ${DOC}/elemntry.spad.dvi ${DOC}/elfuts.spad.dvi \
+ ${DOC}/equation1.spad.dvi ${DOC}/equation2.spad.dvi ${DOC}/error.spad.dvi \
+ ${DOC}/expexpan.spad.dvi ${DOC}/exposed.lsp.dvi ${DOC}/expr2ups.spad.dvi \
+ ${DOC}/exprode.spad.dvi ${DOC}/expr.spad.dvi \
+ ${DOC}/f01.spad.dvi ${DOC}/f02.spad.dvi ${DOC}/f04.spad.dvi \
+ ${DOC}/f07.spad.dvi ${DOC}/facutil.spad.dvi ${DOC}/ffcat.spad.dvi \
+ ${DOC}/ffcg.spad.dvi ${DOC}/fff.spad.dvi ${DOC}/ffhom.spad.dvi \
+ ${DOC}/ffnb.spad.dvi ${DOC}/ffpoly2.spad.dvi ${DOC}/ffpoly.spad.dvi \
+ ${DOC}/ffp.spad.dvi ${DOC}/ffrac.as.dvi ${DOC}/ffx.spad.dvi \
+ ${DOC}/files.spad.dvi ${DOC}/float.spad.dvi ${DOC}/fmod.spad.dvi \
+ ${DOC}/fname.spad.dvi ${DOC}/fnla.spad.dvi ${DOC}/formula.spad.dvi \
+ ${DOC}/fortcat.spad.dvi ${DOC}/fortmac.spad.dvi ${DOC}/fortpak.spad.dvi \
+ ${DOC}/fortran.spad.dvi ${DOC}/forttyp.spad.dvi ${DOC}/fourier.spad.dvi \
+ ${DOC}/fparfrac.spad.dvi ${DOC}/fraction.spad.dvi ${DOC}/free.spad.dvi \
+ ${DOC}/fr.spad.dvi ${DOC}/fs2expxp.spad.dvi ${DOC}/fs2ups.spad.dvi \
+ ${DOC}/fspace.spad.dvi ${DOC}/funcpkgs.spad.dvi ${DOC}/functions.spad.dvi \
+ ${DOC}/galfact.spad.dvi ${DOC}/galfactu.spad.dvi ${DOC}/galpolyu.spad.dvi \
+ ${DOC}/galutil.spad.dvi ${DOC}/gaussfac.spad.dvi ${DOC}/gaussian.spad.dvi \
+ ${DOC}/gbeuclid.spad.dvi ${DOC}/gbintern.spad.dvi ${DOC}/gb.spad.dvi \
+ ${DOC}/gdirprod.spad.dvi ${DOC}/gdpoly.spad.dvi ${DOC}/geneez.spad.dvi \
+ ${DOC}/generic.spad.dvi ${DOC}/genufact.spad.dvi ${DOC}/genups.spad.dvi \
+ ${DOC}/ghensel.spad.dvi ${DOC}/gpgcd.spad.dvi ${DOC}/gpol.spad.dvi \
+ ${DOC}/grdef.spad.dvi ${DOC}/groebf.spad.dvi ${DOC}/groebsol.spad.dvi \
+ ${DOC}/gseries.spad.dvi \
+ ${DOC}/herm.as.dvi \
+ ${DOC}/ideal.spad.dvi ${DOC}/idecomp.spad.dvi ${DOC}/indexedp.spad.dvi \
+ ${DOC}/infprod.spad.dvi ${DOC}/intaf.spad.dvi ${DOC}/intalg.spad.dvi \
+ ${DOC}/intaux.spad.dvi ${DOC}/intclos.spad.dvi ${DOC}/intef.spad.dvi \
+ ${DOC}/integer.spad.dvi ${DOC}/integrat.spad.dvi \
+ ${DOC}/interval.as.dvi ${DOC}/interval.spad.dvi \
+ ${DOC}/intfact.spad.dvi ${DOC}/intpm.spad.dvi \
+ ${DOC}/intrf.spad.dvi ${DOC}/invnode.as.dvi ${DOC}/invrender.as.dvi \
+ ${DOC}/invtypes.as.dvi ${DOC}/invutils.as.dvi ${DOC}/irexpand.spad.dvi \
+ ${DOC}/irsn.spad.dvi ${DOC}/ituple.spad.dvi ${DOC}/iviews.as.dvi \
+ ${DOC}/kl.spad.dvi ${DOC}/kovacic.spad.dvi \
+ ${DOC}/laplace.spad.dvi ${DOC}/laurent.spad.dvi ${DOC}/leadcdet.spad.dvi \
+ ${DOC}/lie.spad.dvi ${DOC}/limitps.spad.dvi ${DOC}/lindep.spad.dvi \
+ ${DOC}/lingrob.spad.dvi ${DOC}/liouv.spad.dvi ${DOC}/listgcd.spad.dvi \
+ ${DOC}/list.spad.dvi ${DOC}/lmdict.spad.dvi ${DOC}/lodof.spad.dvi \
+ ${DOC}/lodop.spad.dvi ${DOC}/lodo.spad.dvi \
+ ${DOC}/manip.spad.dvi ${DOC}/mappkg.spad.dvi ${DOC}/matcat.spad.dvi \
+ ${DOC}/matfuns.spad.dvi ${DOC}/matrix.spad.dvi ${DOC}/matstor.spad.dvi \
+ ${DOC}/mesh.spad.dvi ${DOC}/mfinfact.spad.dvi ${DOC}/misc.spad.dvi \
+ ${DOC}/mkfunc.spad.dvi ${DOC}/mkrecord.spad.dvi ${DOC}/mlift.spad.jhd.dvi \
+ ${DOC}/mlift.spad.dvi ${DOC}/moddfact.spad.dvi ${DOC}/modgcd.spad.dvi \
+ ${DOC}/modmonom.spad.dvi ${DOC}/modmon.spad.dvi ${DOC}/modring.spad.dvi \
+ ${DOC}/moebius.spad.dvi ${DOC}/mring.spad.dvi ${DOC}/mset.spad.dvi \
+ ${DOC}/mts.spad.dvi ${DOC}/multfact.spad.dvi ${DOC}/multpoly.spad.dvi \
+ ${DOC}/multsqfr.spad.dvi \
+ ${DOC}/naalgc.spad.dvi ${DOC}/naalg.spad.dvi ${DOC}/ndftip.as.dvi \
+ ${DOC}/nepip.as.dvi ${DOC}/newdata.spad.dvi ${DOC}/newpoint.spad.dvi \
+ ${DOC}/newpoly.spad.dvi ${DOC}/nlinsol.spad.dvi ${DOC}/nlode.spad.dvi \
+ ${DOC}/noptip.as.dvi ${DOC}/npcoef.spad.dvi ${DOC}/nqip.as.dvi \
+ ${DOC}/nrc.as.dvi ${DOC}/nregset.spad.dvi ${DOC}/nsfip.as.dvi \
+ ${DOC}/nsregset.spad.dvi ${DOC}/numeigen.spad.dvi ${DOC}/numeric.spad.dvi \
+ ${DOC}/numode.spad.dvi ${DOC}/numquad.spad.dvi ${DOC}/numsolve.spad.dvi \
+ ${DOC}/numtheor.spad.dvi \
+ ${DOC}/oct.spad.dvi ${DOC}/odealg.spad.dvi ${DOC}/odeef.spad.dvi \
+ ${DOC}/oderf.spad.dvi ${DOC}/omcat.spad.dvi ${DOC}/omdev.spad.dvi \
+ ${DOC}/omerror.spad.dvi ${DOC}/omserver.spad.dvi ${DOC}/opalg.spad.dvi \
+ ${DOC}/openmath.spad.dvi ${DOC}/op.spad.dvi ${DOC}/ore.spad.dvi \
+ ${DOC}/outform.spad.dvi ${DOC}/out.spad.dvi \
+ ${DOC}/pade.spad.dvi ${DOC}/padiclib.spad.dvi ${DOC}/padic.spad.dvi \
+ ${DOC}/paramete.spad.dvi ${DOC}/partperm.spad.dvi ${DOC}/patmatch1.spad.dvi \
+ ${DOC}/patmatch2.spad.dvi ${DOC}/pattern.spad.dvi ${DOC}/pcurve.spad.dvi \
+ ${DOC}/pdecomp.spad.dvi ${DOC}/perman.spad.dvi ${DOC}/permgrps.spad.dvi \
+ ${DOC}/perm.spad.dvi ${DOC}/pfbr.spad.dvi ${DOC}/pfo.spad.dvi \
+ ${DOC}/pfr.spad.dvi ${DOC}/pf.spad.dvi ${DOC}/pgcd.spad.dvi \
+ ${DOC}/pgrobner.spad.dvi ${DOC}/pinterp.spad.dvi ${DOC}/pleqn.spad.dvi \
+ ${DOC}/plot3d.spad.dvi ${DOC}/plot.spad.dvi ${DOC}/plottool.spad.dvi \
+ ${DOC}/polset.spad.dvi ${DOC}/poltopol.spad.dvi ${DOC}/polycat.spad.dvi \
+ ${DOC}/poly.spad.dvi ${DOC}/primelt.spad.dvi ${DOC}/print.spad.dvi \
+ ${DOC}/product.spad.dvi ${DOC}/prs.spad.dvi ${DOC}/prtition.spad.dvi \
+ ${DOC}/pscat.spad.dvi ${DOC}/pseudolin.spad.dvi ${DOC}/ptranfn.spad.dvi \
+ ${DOC}/puiseux.spad.dvi \
+ ${DOC}/qalgset.spad.dvi ${DOC}/quat.spad.dvi \
+ ${DOC}/radeigen.spad.dvi ${DOC}/radix.spad.dvi ${DOC}/random.spad.dvi \
+ ${DOC}/ratfact.spad.dvi ${DOC}/rdeef.spad.dvi ${DOC}/rderf.spad.dvi \
+ ${DOC}/rdesys.spad.dvi ${DOC}/real0q.spad.dvi ${DOC}/realzero.spad.dvi \
+ ${DOC}/reclos.spad.dvi ${DOC}/regset.spad.dvi ${DOC}/rep1.spad.dvi \
+ ${DOC}/rep2.spad.dvi ${DOC}/resring.spad.dvi ${DOC}/retract.spad.dvi \
+ ${DOC}/rf.spad.dvi ${DOC}/riccati.spad.dvi ${DOC}/rinterp.spad.dvi \
+ ${DOC}/routines.spad.dvi \
+ ${DOC}/rule.spad.dvi \
+ ${DOC}/seg.spad.dvi ${DOC}/setorder.spad.dvi ${DOC}/sets.spad.dvi \
+ ${DOC}/sex.spad.dvi ${DOC}/sf.spad.dvi ${DOC}/sgcf.spad.dvi \
+ ${DOC}/sign.spad.dvi ${DOC}/si.spad.dvi ${DOC}/smith.spad.dvi \
+ ${DOC}/solvedio.spad.dvi ${DOC}/solvefor.spad.dvi ${DOC}/solvelin.spad.dvi \
+ ${DOC}/solverad.spad.dvi ${DOC}/sortpak.spad.dvi ${DOC}/space.spad.dvi \
+ ${DOC}/special.spad.dvi ${DOC}/sregset.spad.dvi ${DOC}/s.spad.dvi \
+ ${DOC}/stream.spad.dvi ${DOC}/string.spad.dvi ${DOC}/sttaylor.spad.dvi \
+ ${DOC}/sttf.spad.dvi ${DOC}/sturm.spad.dvi ${DOC}/suchthat.spad.dvi \
+ ${DOC}/suls.spad.dvi ${DOC}/sum.spad.dvi ${DOC}/sups.spad.dvi \
+ ${DOC}/supxs.spad.dvi ${DOC}/suts.spad.dvi ${DOC}/symbol.spad.dvi \
+ ${DOC}/syssolp.spad.dvi ${DOC}/system.spad.dvi \
+ ${DOC}/tableau.spad.dvi ${DOC}/table.spad.dvi ${DOC}/taylor.spad.dvi \
+ ${DOC}/tex.spad.dvi ${DOC}/tools.spad.dvi ${DOC}/transsolve.spad.dvi \
+ ${DOC}/tree.spad.dvi ${DOC}/trigcat.spad.dvi ${DOC}/triset.spad.dvi \
+ ${DOC}/tube.spad.dvi ${DOC}/twofact.spad.dvi \
+ ${DOC}/unifact.spad.dvi ${DOC}/updecomp.spad.dvi ${DOC}/updivp.spad.dvi \
+ ${DOC}/utsode.spad.dvi \
+ ${DOC}/variable.spad.dvi ${DOC}/vector.spad.dvi ${DOC}/view2D.spad.dvi \
+ ${DOC}/view3D.spad.dvi ${DOC}/viewDef.spad.dvi ${DOC}/viewpack.spad.dvi \
+ ${DOC}/void.spad.dvi \
+ ${DOC}/weier.spad.dvi ${DOC}/wtpol.spad.dvi \
+ ${DOC}/xlpoly.spad.dvi ${DOC}/xpoly.spad.dvi \
+ ${DOC}/ystream.spad.dvi \
+ ${DOC}/zerodim.spad.dvi
+
+@
+
+\section{Test Cases}
+
+<<environment>>=
+
+TESTS=${INPUT}/INTHEORY.input ${INPUT}/VIEW2D.input ${INPUT}/TESTFR.input
+
+@
+
+<<testrules>>=
+
+${INPUT}/TESTFR.input: $(srcdir)/fr.spad.pamphlet
+ $(axiom_build_document) --tangle='TEST FR' --output=$@ $<
+
+${INPUT}/INTHEORY.input: $(srcdir)/numtheor.spad.pamphlet
+ $(axiom_build_document) --tangle='TEST INTHEORY' --output=$@ $<
+
+${INPUT}/VIEW2D.input: $(srcdir)/view2D.spad.pamphlet
+ $(axiom_build_document) --tangle='TEST VIEW2D' --output=$@ $<
+
+@
+
+\section{The Makefile Stanzas}
+
+A [[spad]] pamphlet can contain many Axiom [[categories]], [[domains]], and
+[[packages]].
+
+For the purpose of explanation we assume that the pamphlet file is
+named [[foo.spad.pamphlet]]. It contains the domains [[BAR]], [[BAX]],
+and [[BAZ]]. Thus there will be a subsection named [[foo.spad]].
+
+Since pamphlet files (e.g. [[foo.spad.pamphlet]] contain a spad file
+e.g. [[foo.spad]], it follows that every subsection contains a Makefile
+stanza that extract the [[foo.spad]] file using [[notangle]].
+
+Since pamphlet files are intended as documents it follows that each
+subsection contains a Makefile stanza that extracts a [[dvi]] file
+using [[noweave]].
+
+We could have a category, domain, or package that is in
+the ``bootstrap'' list. Bootstrap spad files contain their generated
+lisp code in special sections. The way bootstrapping works is that
+we extract the lisp code and compile it rather than extracting the
+spad code. We do this because we need the domain to exist before we
+can compile the domain. Some domains depend on themselves directly.
+Some domains depend on themselves thru a long chain of other domains.
+In either case we can't compile the domain until it exists so we
+cache the generated lisp code and, when we need to bootstrap the
+domain, we compile the raw lisp rather than the spad.
+
+This will only happen when the system is built from scratch. Once
+the system has been built the bootstrap code is no longer executed
+and these algebra files will appear as normal algebra files. That
+means that once the system has been built once only the last three
+rules will ever be executed. The first two rules happen when the
+system is built from scratch.
+
+A 5 stanza group for this case performs the following functions:
+\begin{enumerate}
+\item extract the lisp [[BAR.lsp]] from the pamphlet [[foo.spad.pamphlet]]
+\item compile and copy the bootstrap lisp to the final algebra directory
+\item extract the bootstrap [[BAR.lsp]] from the spad file [[foo.spad]]
+\item compile the extracted [[BAR]] domain
+\item copy the compiled [[BAR]] to the final algebra directory
+\end{enumerate}
+
+The subtle point here occurs in the first item. The bootstrap code
+group (in the [[layer0 bootstrap]] code chunk above) asks for the
+compiled [[.o]] files in the \File{strap/} directory. Essentially this
+code group calls for intermediate compiled files. This triggers the
+bootstrap stanzas (items 1 and 2 above). All of the other layer
+chunks ask for compiled code in the [[\${OUT}]] directory which is
+the final algebra directory.
+
+The bootstrap process works because first we ask for the compiled
+lisp code stanzas (the \File{strap/BAR.o} files), THEN we ask for
+the final algebra code stanzas (the [[\${OUT}/BAR.o]] files). This
+is a very subtle point so think it through carefully. The layer0
+bootstrap list is the only file list that calls for \File{strap/} files.
+All other layers ask for [[\${OUT}]] files. Make sure you
+understand this before you change things. If you break it the
+world will no longer compile.
+
+So we have a 3 stanza group for normal files, a 3+2 (5) stanza
+group for normal files with default code, and a 3+2 (5) stanza
+group for normal files that need to be bootstrapped. There is
+another combination that occurs, namely bootstrap code that
+also contains default code which gives a 3+2+2+2 (9) stanza case.
+(see TSETCAT for an example. Be sure to read the items in reverse order).
+
+A 9 stanza group for this case performs the following functions:
+\begin{enumerate}
+\item extract the bootstrap \File{BAR.lsp} from the \File{foo.spad.pamphlet}
+\item compile the bootstrap \File{BAR.lsp} to the \File{strap/} directory
+\item extract the bootstrap \File{BAR-.lsp} from the \File{foo.spad.pamphlet}
+\item compile the bootstrap \File{BAR-.lsp} to the \File{strap/} directory
+\item extract the spad \File{BAR.spad} from the pamphlet
+ \File{foo.spad.pamphlet}
+\item compile the extracted \File{BAR.spad} domain (to get [[BAR.o]])
+\item copy the \File{BAR.o} to the final algebra directory
+\item compile the extracted \File{BAR-.spad} domain (to get [[BAR-.o]])
+\item copy the [[BAR-.o]] to the final algebra directory
+\end{enumerate}
+
+As you can see this is just the combination of the two possible 5
+stanza case. We just have to deal with the [[BAR-]] both in regular
+and bootstrap files. The first four stanzas will only happen when
+the system is built from scratch. Once the system is built these
+four rules no longer apply and these stanzas effectively act like
+the 5 stanza rules above.
+
+I'm sure all of this seems confusing but it is very stylized code.
+Basically you need to figure out which kind of stanza group you need,
+copy an existing stanza group, and do a correct renaming of the parts.
+The decision tree looks something like:
+\begin{verbatim}
+IF (you have a regular spad domain)
+ THEN use a 3 stanza form (see YSTREAM)
+IF (you have a default spad domain (it generates [[-]] files)) AND
+ (it does not require bootstrapping)
+ THEN use the first 5 stanza form explained above (see LIECAT)
+IF (you have a normal spad domain) AND
+ (it requires bootstrapping)
+ THEN use the second 5 stanza form explained above (see VECTOR)
+IF (you have a default spad domain (it generates [[-]] files)) AND
+ (it requires bootstrapping)
+ THEN use the 9 stanza form explained above (see TSETCAT)
+\end{verbatim}
+
+\section{Generic Make Rules}
+
+The idea is to use generic rules to try to cut down the size of this file.
+
+This Makefile works very hard to cache
+intermediate results in order to minimize the re-build time. The cached
+files are kept in the current build and \File{strap/} directories.
+If one of these
+files disappears but the original pamphlet file is unchanged we only
+need to rebuild the intermediate file. These rule will attempt to do
+that and they succeed however these are intermediate files created by
+implicit rules so they would normally be deleted. To prevent the removal
+the NRLIB directory and its contents, the files are marked as .PRECIOUS.
+
+The output of the compile step is saved in a file of the same name
+and extension .out in the \${MID} directory. These files are useful for
+deriving the dependencies by scanning the ``Loading ...'' messages.
+
+<<genericDotOfiles>>=
+
+${OUT}/%.o: %.NRLIB/code.o
+ cp $*.NRLIB/code.o ${OUT}/$*.o
+
+@
+
+<<genericNRLIBfiles>>=
+
+.PRECIOUS: %.NRLIB/code.o
+%.NRLIB/code.o: %.spad
+ @ rm -rf $*.NRLIB
+ echo ")co $*.spad" | ${INTERPSYS}
+@
+
+<<genericBOOTSTRAPfiles>>=
+# Compile bootstrap file to machine object code, and the result
+# immediately available for AXIOMsys consumption.
+strap/%.o: %.lsp
+ $(DEPSYS) -- --compile --output=$@ $<
+ cp $@ ${OUT}
+@
+
+<<genericSPADfiles>>=
+
+$(OUTSRC)/%.spad: mk-target-src-algabra-dir
+
+${OUTSRC}/%.spad: $(srcdir)/%.spad.pamphlet
+ $(axiom_build_document) --tangle --output=$@ $<
+
+.PHONY: mk-target-src-algabra-dir
+mk-target-src-algabra-dir:
+ @ [ -d $(OUTSRC) ] || $(mkinstalldirs) $(OUTSRC)
+
+@
+<<genericDOCfiles>>=
+.PRECIOUS: $(builddir)/%.tex
+.PRECIOUS: $(builddir)/%.dvi
+
+$(DOC)/%.dvi: mk-target-doc-dir
+
+.PHONY: mk-target-doc-dir
+mk-target-doc-dir:
+ @ [ -d $(DOC) ] || $(mkinstalldirs) $(DOC)
+
+$(DOC)/%.dvi: $(builddir)/%.dvi
+ $(INSTALL_DATA) $< $@
+
+$(builddir)/%.dvi: $(axiom_build_texdir)/diagrams.tex \
+ $(axiom_build_texdir)/axiom.sty
+
+$(builddir)/%.dvi: $(builddir)/%.tex
+ $(axiom_build_document) --latex $<
+
+$(builddir)/%.tex: $(srcdir)/%.pamphlet
+ $(axiom_build_document) --weave --output=$@ $<
+
+$(axiom_build_texdir)/diagrams.tex: $(axiom_src_docdir)/diagrams.tex
+ $(INSTALL_DATA) $< $@
+@
+<<genericRules>>=
+
+<<genericDotOfiles>>
+<<genericNRLIBfiles>>
+<<genericBOOTSTRAPfiles>>
+<<genericSPADfiles>>
+<<genericDOCfiles>>
+
+@
+<<diagrams.tex (OUT from IN)>>=
+
+${DOC}/diagrams.tex: $(axiom_src_docdir)/diagrams.tex
+ $(INSTALL_DATA) $< $@
+
+@
+
+\section{Pamphlet file structure}
+
+Because the individual .spad files are grouped into higher-level
+algebra pamphlet files, the rules for extracting them are coded
+below as simple ``awk'' scripts that are called when the Makefile
+is constructed.
+
+There are, at present, 3 kinds of algebra files to be handled.
+First we have [[.as]] files which use the [[aldor]] compiler.
+These are ignored here as the compiler is not yet integrated.
+
+Second, there are the bootstrap files. These files live within
+their respective pamphlet files and are "captured" lisp code.
+These are necessary to create the algebra. See the
+[[src/algebra/Makefile.pamphlet]] for details.
+
+Third, there are 3 "types" of algebra which are all treated
+the same at compile time, namely the "domain", "category", and
+"package" algebra.
+
+\subsection{Finding the algebra code}
+
+NOTE: This construct is now moved to configure time. Update.
+
+Step 1 is to scan all of the algebra pamphlet files for the
+chunk names which contain the string "domain", "package", or
+"category". This is done using egrep (same as grep -E, which
+means that the pattern is an extended regular expression) because
+extended regular expressions allows the use of alternatives
+written as (domain|package|category). Thus the command
+\begin{verbatim}
+ egrep '@<<(domain|package|category) .*>>=' *.spad.pamphlet
+\end{verbatim}
+will scan the algebra files looking for special chunknames.
+Axiom's chunk names are written in a stylized form so that each
+algebra chunk name begins with one of those three symbols. Thus
+in zerodim.spad.pamphlet the LexTriangularPackage chunkname is:
+\begin{verbatim}
+@<<package LEXTRIPK LexTriangularPackage>>
+\end{verbatim}
+so this egrep will generate an output line, prefixed by the filename
+that looks like:
+\begin{verbatim}
+zerodim.spad.pamphlet:@<<package LEXTRIPK LexTriangularPackage>>=
+\end{verbatim}
+There can be many lines of output per pamphlet file, one for
+each domain, package and category cod chunk contained in the file.
+
+Step 2 is an [[awk]] command line.
+
+\subsection{Write the Makefile stanzas for the algebra files}
+
+NOTE: This construct is now moved to configure time.
+
+[awk] processes each line of the [[egrep]] output.
+
+The awk script uses [[-F:]] which is a flag that says that a [[:]] is
+the field separator. As a result the \$1 and \$2 in the awk script
+refer to the parts of the egrep output that come before and after the
+[[:]] respectively.
+
+The variable [[chunk]] is assigned the actual chunk name minus
+the @<< and >>= delimiters. In the example given above this will become
+\begin{verbatim}
+package LEXTRIPK LexTriangularPackage
+\end{verbatim}
+The call to [[split]] splits the chunk into parts separated
+by spaces. Thus
+\begin{verbatim}
+ part[1]=package
+ part[2]=LEXTRIPK
+ part[3]=LexTriangularPackage
+\end{verbatim}
+The variable [[spadfile]] in the above example is set to
+\begin{verbatim}
+${MID}/LEXTRIPK.spad
+\end{verbatim}
+Finally, in the domain example given above we print two lines.
+The first line is the Makefile stanza header which depends on the
+original [[zerodim.spad.pamphlet]] file.
+
+The second line is the body of the makefile stanza which calls
+notangle to extract the algebra from the original pamphlet using
+the chunk name and writes it to the intermediate subdirectory. In
+the case above this would resolve to [[\${MID}/LEXTRIPK.spad]].
+
+For the line given above it outputs the following:
+\begin{verbatim}
+${MID}/LEXTRIPK.spad: $(srcdir)/zerodim.spad.pamphlet
+ $(axiom_build_document) --tangle='package LEXTRIPK LexTriangularPackage' --output=$@ $<
+\end{verbatim}
+
+\subsection{Find the algebra bootstrap code}
+
+Step 3 works like step 1 above except that we are looking for
+chunk names that have the "BOOTSTRAP" string. The output will look like:
+\begin{verbatim}
+vector.spad.pamphlet:@<<VECTOR.lsp BOOTSTRAP>>=
+\end{verbatim}
+This output, which can consist of many lines per input file is piped
+into [[awk]].
+
+The process is the same way as described above except that
+there are only two parts to the chunk names
+\begin{verbatim}
+ part[1]=VECTOR.lsp
+ part[2]=BOOTSTRAP
+\end{verbatim}
+The [[lspfile]] variable is assigned
+\begin{verbatim}
+${MID}/VECTOR.lsp
+\end{verbatim}
+Finally we output two lines:
+\begin{verbatim}
+${MID}/vector.spad.pamphlet: $(srcdir)/vector.spad.pamphlet
+ $(axiom_build_document) --tangle='VECTOR.lsp BOOTSTRAP' --output=$@ $<
+\end{verbatim}
+
+The first line is the stanza head and creates a dependence between
+the intermediate file, in this case [[int/algebra/VECTOR.lsp]] and
+the input file [[src/algebra/vector.spad.pamphlet]]
+
+The second line calls [[notangle]] to extract the required chunk
+from the source file.
+
+\section{Stage markers}
+
+We output these as each stage completes.
+<<stages>>=
+$(axiom_algebra_layer_0_objects): strap-stamp
+$(axiom_algebra_layer_1_objects): 0-stamp
+$(axiom_algebra_layer_2_objects): 1-stamp
+$(axiom_algebra_layer_3_objects): 2-stamp
+$(axiom_algebra_layer_4_objects): 3-stamp
+$(axiom_algebra_layer_5_objects): 4-stamp
+$(axiom_algebra_layer_6_objects): 5-stamp
+$(axiom_algebra_layer_7_objects): 6-stamp
+$(axiom_algebra_layer_8_objects): 7-stamp
+$(axiom_algebra_layer_9_objects): 8-stamp
+$(axiom_algebra_layer_10_objects): 9-stamp
+$(axiom_algebra_layer_11_objects): 10-stamp
+$(axiom_algebra_layer_12_objects): 11-stamp
+$(axiom_algebra_layer_13_objects): 12-stamp
+$(axiom_algebra_layer_14_objects): 13-stamp
+$(axiom_algebra_layer_15_objects): 14-stamp
+$(axiom_algebra_layer_16_objects): 15-stamp
+$(axiom_algebra_layer_17_objects): 16-stamp
+$(axiom_algebra_layer_18_objects): 17-stamp
+$(axiom_algebra_layer_19_objects): 18-stamp
+$(axiom_algebra_layer_20_objects): 19-stamp
+$(axiom_algebra_layer_21_objects): 20-stamp
+$(axiom_algebra_layer_22_objects): 21-stamp
+$(axiom_algebra_layer_23_objects): 22-stamp
+$(axiom_algebra_layer_user_objects): 23-stamp
+$(axiom_algebra_bootstrap_objects): user-stamp
+
+strap-stamp: $(axiom_algebra_layer_strap_objects)
+ @ rm -f strap-stamp
+ @ $(STAMP) strap-stamp
+ @ echo =====================================
+ @ echo === algebra bootstrap complete ======
+ @ echo =====================================
+
+0-stamp: strap-stamp $(axiom_algebra_layer_0_objects)
+ @ rm -f 0-stamp
+ @ $(STAMP) 0-stamp
+ @ echo ==================================
+ @ echo === layer 0 of 23 complete ======
+ @ echo ==================================
+
+1-stamp: 0-stamp $(axiom_algebra_layer_1_objects)
+ @ rm -f 1-stamp
+ @ $(STAMP) 1-stamp
+ @ echo ==================================
+ @ echo === layer 1 of 23 complete ======
+ @ echo ==================================
+
+2-stamp: 1-stamp $(axiom_algebra_layer_2_objects)
+ @ rm -f 2-stamp
+ @ $(STAMP) 2-stamp
+ @ echo ==================================
+ @ echo === layer 2 of 23 complete ======
+ @ echo ==================================
+
+3-stamp: 2-stamp $(axiom_algebra_layer_3_objects)
+ @ rm -f 3-stamp
+ @ $(STAMP) 3-stamp
+ @ echo ==================================
+ @ echo === layer 3 of 23 complete ======
+ @ echo ==================================
+
+4-stamp: 3-stamp $(axiom_algebra_layer_4_objects)
+ @ rm -f 4-stamp
+ @ $(STAMP) 4-stamp
+ @ echo ==================================
+ @ echo === layer 4 of 23 complete ======
+ @ echo ==================================
+
+5-stamp: 4-stamp $(axiom_algebra_layer_5_objects)
+ @ rm -f 5-stamp
+ @ $(STAMP) 5-stamp
+ @ echo ==================================
+ @ echo === layer 5 of 23 complete ======
+ @ echo ==================================
+
+6-stamp: 5-stamp $(axiom_algebra_layer_6_objects)
+ @ rm -f 6-stamp
+ @ $(STAMP) 6-stamp
+ @ echo ==================================
+ @ echo === layer 6 of 23 complete ======
+ @ echo ==================================
+
+7-stamp: 6-stamp $(axiom_algebra_layer_7_objects)
+ @ rm -f 7-stamp
+ @ $(STAMP) 7-stamp
+ @ echo ==================================
+ @ echo === layer 7 of 23 complete ======
+ @ echo ==================================
+
+8-stamp: 7-stamp $(axiom_algebra_layer_8_objects)
+ @ rm -f 8-stamp
+ @ $(STAMP) 8-stamp
+ @ echo ==================================
+ @ echo === layer 8 of 23 complete ======
+ @ echo ==================================
+
+9-stamp: 8-stamp $(axiom_algebra_layer_9_objects)
+ @ rm -f 9-stamp
+ @ $(STAMP) 9-stamp
+ @ echo ==================================
+ @ echo === layer 9 of 23 complete ======
+ @ echo ==================================
+
+10-stamp: 9-stamp $(axiom_algebra_layer_10_objects)
+ @ rm -f 10-stamp
+ @ $(STAMP) 10-stamp
+ @ echo ==================================
+ @ echo === layer 10 of 23 complete ======
+ @ echo ==================================
+
+11-stamp: 10-stamp $(axiom_algebra_layer_11_objects)
+ @ rm -f 11-stamp
+ @ $(STAMP) 11-stamp
+ @ echo ==================================
+ @ echo === layer 11 of 23 complete ======
+ @ echo ==================================
+
+12-stamp: 11-stamp $(axiom_algebra_layer_12_objects)
+ @ rm -f 12-stamp
+ @ $(STAMP) 12-stamp
+ @ echo ==================================
+ @ echo === layer 12 of 23 complete ======
+ @ echo ==================================
+
+13-stamp: 12-stamp $(axiom_algebra_layer_13_objects)
+ @ rm -f 13-stamp
+ @ $(STAMP) 13-stamp
+ @ echo ==================================
+ @ echo === layer 13 of 23 complete ======
+ @ echo ==================================
+
+14-stamp: 13-stamp $(axiom_algebra_layer_14_objects)
+ @ rm -f 14-stamp
+ @ $(STAMP) 14-stamp
+ @ echo ==================================
+ @ echo === layer 14 of 23 complete ======
+ @ echo ==================================
+
+15-stamp: 14-stamp $(axiom_algebra_layer_15_objects)
+ @ rm -f 15-stamp
+ @ $(STAMP) 15-stamp
+ @ echo ==================================
+ @ echo === layer 15 of 23 complete ======
+ @ echo ==================================
+
+16-stamp: 15-stamp $(axiom_algebra_layer_16_objects)
+ @ rm -f 16-stamp
+ @ $(STAMP) 16-stamp
+ @ echo ==================================
+ @ echo === layer 16 of 23 complete ======
+ @ echo ==================================
+
+17-stamp: 16-stamp $(axiom_algebra_layer_17_objects)
+ @ rm -f 17-stamp
+ @ $(STAMP) 17-stamp
+ @ echo ==================================
+ @ echo === layer 17 of 23 complete ======
+ @ echo ==================================
+
+18-stamp: 17-stamp $(axiom_algebra_layer_18_objects)
+ @ rm -f 18-stamp
+ @ $(STAMP) 18-stamp
+ @ echo ==================================
+ @ echo === layer 18 of 23 complete ======
+ @ echo ==================================
+
+19-stamp: 18-stamp $(axiom_algebra_layer_19_objects)
+ @ rm -f 19-stamp
+ @ $(STAMP) 19-stamp
+ @ echo ==================================
+ @ echo === layer 19 of 23 complete ======
+ @ echo ==================================
+
+20-stamp: 19-stamp $(axiom_algebra_layer_20_objects)
+ @ rm -f 20-stamp
+ @ $(STAMP) 20-stamp
+ @ echo ==================================
+ @ echo === layer 20 of 23 complete ======
+ @ echo ==================================
+
+21-stamp: 20-stamp $(axiom_algebra_layer_21_objects)
+ @ rm -f 21-stamp
+ @ $(STAMP) 21-stamp
+ @ echo ==================================
+ @ echo === layer 21 of 23 complete ======
+ @ echo ==================================
+
+22-stamp: 21-stamp $(axiom_algebra_layer_22_objects)
+ @ rm -f 22-stamp
+ @ $(STAMP) 22-stamp
+ @ echo ==================================
+ @ echo === layer 22 of 23 complete ======
+ @ echo ==================================
+
+23-stamp: 22-stamp $(axiom_algebra_layer_23_objects)
+ @ rm -f 23-stamp
+ @ $(STAMP) 23-stamp
+ @ echo ==================================
+ @ echo === layer 23 of 23 complete ======
+ @ echo ==================================
+
+user-stamp: 23-stamp $(axiom_algebra_layer_user_objects)
+ @ rm -f user-stamp
+ @ $(STAMP) user-stamp
+
+
+# bootstrap-pre: user-stamp $(axiom_algebra_bootstrap_nrlibs)
+# $(axiom_algebra_bootstrap_nrlibs): user-stamp
+
+# bootstrap-post: bootstrap-pre $(axiom_algebra_bootstrap_objects)
+
+bootstrap-stamp: $(axiom_algebra_bootstrap_objects)
+ @ rm -f bootstrap-stamp
+ @ $(STAMP) bootstrap-stamp
+ @ echo ==================================
+ @ echo === algebra complete ======
+ @ echo ==================================
+@
+
+\section{The Makefile}
+
+<<*>>=
+<<environment>>
+
+subdir = src/algebra/
+
+<<layer0 bootstrap>>
+<<layer0 copy>>
+<<layer0>>
+<<layer1>>
+<<layer2>>
+<<layer3>>
+<<layer4>>
+<<layer5>>
+<<layer6>>
+<<layer7>>
+<<layer8>>
+<<layer9>>
+<<layer10>>
+<<layer11>>
+<<layer12>>
+<<layer13>>
+<<layer14>>
+<<layer15>>
+<<layer16>>
+<<layer17>>
+<<layer18>>
+<<layer19>>
+<<layer20>>
+<<layer21>>
+<<layer22>>
+<<layer23>>
+<<USERLAYER>>
+
+# The algebra build is not yet ready for parallel build.
+.NOTPARALLEL:
+
+.PHONY: all all-algebra mkdir-output-directory
+all: all-ax
+
+all-ax all-algebra: stamp
+ @ echo finished $(builddir)
+
+stamp: mkdir-output-directory ${SPADFILES} bootstrap-stamp ${TESTS}
+ -rm -f stamp
+ $(STAMP) stamp
+
+mkdir-output-directory:
+ $(mkinstalldirs) $(OUTSRC)
+
+everything: check lib db cmd gloss
+ @ echo 4303 invoking make in `pwd` with parms:
+ @ echo SYS= ${SYS} LSP= ${LSP}
+ @ echo MNT= ${MNT} LISP=${LISP} BYE=${BYE}
+
+check:
+ @ echo 4305 Checking that INTERP.EXPOSED and NRLIBs are consistent
+ @ echo 4306 libcheck needs to use exposed.lsp, not INTERP.EXPOSED
+
+
+<<genericRules>>
+
+<<testrules>>
+<<diagrams.tex (OUT from IN)>>
+<<stages>>
+
+mostlyclean-local:
+ @ -rm -f $(OUT)/*.$(OBJEXT)
+ @ -rm -rf *.NRLIB
+
+clean-local: mostlyclean-local
+
+distclean-local: clean-local
+
+include extract-lisp-files.mk
+include extract-spad.mk
+
+.NOTPARALLEL:
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/acplot.spad.pamphlet b/src/algebra/acplot.spad.pamphlet
new file mode 100644
index 00000000..fa57e414
--- /dev/null
+++ b/src/algebra/acplot.spad.pamphlet
@@ -0,0 +1,1241 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra acplot.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REALSOLV RealSolvePackage}
+<<package REALSOLV RealSolvePackage>>=
+)abbrev package REALSOLV RealSolvePackage
+
+RealSolvePackage(): Exports == Implementation where
+ ++ This package provides numerical solutions of systems of polynomial
+ ++ equations for use in ACPLOT.
+ I ==> Integer
+ IE ==> IndexedExponents Symbol
+ L ==> List
+ NF ==> Float
+ P ==> Polynomial
+ RN ==> Fraction Integer
+ SE ==> Symbol
+ RFI ==> Fraction Polynomial Integer
+ LIFT ==> PolynomialCategoryLifting(IE,SE,RN,P RN,RFI)
+ SOLV ==> FloatingRealPackage Float
+
+ Exports ==> with
+ solve: (P RN,NF) -> L NF
+ ++ solve(p,eps) finds the real zeroes of a
+ ++ univariate rational polynomial p with precision eps.
+ solve: (P I,NF) -> L NF
+ ++ solve(p,eps) finds the real zeroes of a univariate
+ ++ integer polynomial p with precision eps.
+ realSolve: (L P I,L SE,NF) -> L L NF
+ ++ realSolve(lp,lv,eps) = compute the list of the real
+ ++ solutions of the list lp of polynomials with integer
+ ++ coefficients with respect to the variables in lv,
+ ++ with precision eps.
+
+ Implementation ==> add
+
+ prn2rfi: P RN -> RFI
+ prn2rfi p ==
+ map(#1 :: RFI,(numer(#1) :: RFI)/(denom(#1) :: RFI),p)$LIFT
+
+ pi2rfi: P I -> RFI
+ pi2rfi p == p :: RFI
+
+ solve(p:P RN,eps:NF) == realRoots(prn2rfi p,eps)$SOLV
+
+ solve(p:P I,eps:NF) ==
+ realRoots(p :: RFI,eps)$SOLV
+
+ realSolve(lp,lv,eps) ==
+ realRoots(map(pi2rfi,lp)$ListFunctions2(P I,RFI),lv,eps)$SOLV
+
+@
+\section{domain ACPLOT PlaneAlgebraicCurvePlot}
+<<domain ACPLOT PlaneAlgebraicCurvePlot>>=
+--% PlaneAlgebraicCurvePlot
+++ Plot a NON-SINGULAR plane algebraic curve p(x,y) = 0.
+++ Author: Clifton J. Williamson
+++ Date Created: Fall 1988
+++ Date Last Updated: 27 April 1990
+++ Keywords: algebraic curve, non-singular, plot
+++ Examples:
+++ References:
+
+)abbrev domain ACPLOT PlaneAlgebraicCurvePlot
+
+PlaneAlgebraicCurvePlot():Exports == Implementation where
+ B ==> Boolean
+ OUT ==> OutputForm
+ SE ==> Symbol
+ L ==> List
+ SEG ==> Segment
+ I ==> Integer
+ PI ==> PositiveInteger
+ RN ==> Fraction Integer
+ NF ==> Float
+ SF ==> DoubleFloat
+ P ==> Polynomial
+ UP ==> UnivariatePolynomial
+ SUP ==> SparseUnivariatePolynomial
+ FR ==> Factored
+ Pt ==> Point DoubleFloat
+ BoundaryPts ==> Record(left: L Pt,_
+ right: L Pt,_
+ bottom: L Pt,_
+ top: L Pt)
+ NewPtInfo ==> Record(newPt: Pt,_
+ type: String)
+ Corners ==> Record(minXVal: SF,_
+ maxXVal: SF,_
+ minYVal: SF,_
+ maxYVal: SF)
+ kinte ==> solve$RealSolvePackage()
+ rsolve ==> realSolve$RealSolvePackage()
+
+ Exports ==> PlottablePlaneCurveCategory with
+
+ makeSketch:(P I,SE,SE,SEG RN,SEG RN) -> %
+ ++ makeSketch(p,x,y,a..b,c..d) creates an ACPLOT of the
+ ++ curve \spad{p = 0} in the region {\em a <= x <= b, c <= y <= d}.
+ ++ More specifically, 'makeSketch' plots a non-singular algebraic curve
+ ++ \spad{p = 0} in an rectangular region {\em xMin <= x <= xMax},
+ ++ {\em yMin <= y <= yMax}. The user inputs
+ ++ \spad{makeSketch(p,x,y,xMin..xMax,yMin..yMax)}.
+ ++ Here p is a polynomial in the variables x and y with
+ ++ integer coefficients (p belongs to the domain
+ ++ \spad{Polynomial Integer}). The case
+ ++ where p is a polynomial in only one of the variables is
+ ++ allowed. The variables x and y are input to specify the
+ ++ the coordinate axes. The horizontal axis is the x-axis and
+ ++ the vertical axis is the y-axis. The rational numbers
+ ++ xMin,...,yMax specify the boundaries of the region in
+ ++ which the curve is to be plotted.
+ refine:(%,SF) -> %
+ ++ refine(p,x) \undocumented{}
+
+ Implementation ==> add
+
+ import PointPackage DoubleFloat
+ import Plot
+ import RealSolvePackage
+
+ singValBetween?:(SF,SF,L SF) -> B
+ segmentInfo:(SF -> SF,SF,SF,L SF,L SF,L SF,SF,SF) -> _
+ Record(seg:SEG SF,left: SF,lowerVals: L SF,upperVals:L SF)
+ swapCoords:Pt -> Pt
+ samePlottedPt?:(Pt,Pt) -> B
+ findPtOnList:(Pt,L Pt) -> Union(Pt,"failed")
+ makeCorners:(SF,SF,SF,SF) -> Corners
+ getXMin: Corners -> SF
+ getXMax: Corners -> SF
+ getYMin: Corners -> SF
+ getYMax: Corners -> SF
+ SFPolyToUPoly:P SF -> SUP SF
+ RNPolyToUPoly:P RN -> SUP RN
+ coerceCoefsToSFs:P I -> P SF
+ coerceCoefsToRNs:P I -> P RN
+ RNtoSF:RN -> SF
+ RNtoNF:RN -> NF
+ SFtoNF:SF -> NF
+ listPtsOnHorizBdry:(P RN,SE,RN,NF,NF) -> L Pt
+ listPtsOnVertBdry:(P RN,SE,RN,NF,NF) -> L Pt
+ listPtsInRect:(L L NF,NF,NF,NF,NF) -> L Pt
+ ptsSuchThat?:(L L NF,L NF -> B) -> B
+ inRect?:(L NF,NF,NF,NF,NF) -> B
+ onHorzSeg?:(L NF,NF,NF,NF) -> B
+ onVertSeg?:(L NF,NF,NF,NF) -> B
+ newX:(L L NF,L L NF,NF,NF,NF,RN,RN) -> RN
+ newY:(L L NF,L L NF,NF,NF,NF,RN,RN) -> RN
+ makeOneVarSketch:(P I,SE,SE,RN,RN,RN,RN,SE) -> %
+ makeLineSketch:(P I,SE,SE,RN,RN,RN,RN) -> %
+ makeRatFcnSketch:(P I,SE,SE,RN,RN,RN,RN,SE) -> %
+ makeGeneralSketch:(P I,SE,SE,RN,RN,RN,RN) -> %
+ traceBranches:(P SF,P SF,P SF,SE,SE,Corners,SF,SF,PI,_
+ L Pt,BoundaryPts) -> L L Pt
+ dummyFirstPt:(Pt,P SF,P SF,SE,SE,L Pt,L Pt,L Pt,L Pt) -> Pt
+ listPtsOnSegment:(P SF,P SF,P SF,SE,SE,Pt,Pt,Corners,_
+ SF,SF,PI,L Pt,L Pt) -> L L Pt
+ listPtsOnLoop:(P SF,P SF,P SF,SE,SE,Pt,Corners,_
+ SF,SF,PI,L Pt,L Pt) -> L L Pt
+ computeNextPt:(P SF,P SF,P SF,SE,SE,Pt,Pt,Corners,_
+ SF,SF,PI,L Pt,L Pt) -> NewPtInfo
+ newtonApprox:(SUP SF, SF, SF, PI) -> Union(SF, "failed")
+
+--% representation
+
+ Rep := Record(poly : P I,_
+ xVar : SE,_
+ yVar : SE,_
+ minXVal : RN,_
+ maxXVal : RN,_
+ minYVal : RN,_
+ maxYVal : RN,_
+ bdryPts : BoundaryPts,_
+ hTanPts : L Pt,_
+ vTanPts : L Pt,_
+ branches: L L Pt)
+
+--% global constants
+
+ EPSILON : NF := .000001 -- precision to which realSolve finds roots
+ PLOTERR : SF := float(1,-3,10)
+ -- maximum allowable difference in each coordinate when
+ -- determining if 2 plotted points are equal
+
+--% global flags
+
+ NADA : String := "nothing in particular"
+ BDRY : String := "boundary point"
+ CRIT : String := "critical point"
+ BOTTOM : String := "bottom"
+ TOP : String := "top"
+
+--% hacks
+
+ NFtoSF: NF -> SF
+ NFtoSF x == 0 + convert(x)$NF
+
+--% points
+ makePt: (SF,SF) -> Pt
+ makePt(xx,yy) == point(l : L SF := [xx,yy])
+
+ swapCoords(pt) == makePt(yCoord pt,xCoord pt)
+
+ samePlottedPt?(p0,p1) ==
+ -- determines if p1 lies in a square with side 2 PLOTERR
+ -- centered at p0
+ x0 := xCoord p0; y0 := yCoord p0
+ x1 := xCoord p1; y1 := yCoord p1
+ (abs(x1-x0) < PLOTERR) and (abs(y1-y0) < PLOTERR)
+
+ findPtOnList(pt,pointList) ==
+ for point in pointList repeat
+ samePlottedPt?(pt,point) => return point
+ "failed"
+
+--% corners
+
+ makeCorners(xMinSF,xMaxSF,yMinSF,yMaxSF) ==
+ [xMinSF,xMaxSF,yMinSF,yMaxSF]
+
+ getXMin(corners) == corners.minXVal
+ getXMax(corners) == corners.maxXVal
+ getYMin(corners) == corners.minYVal
+ getYMax(corners) == corners.maxYVal
+
+--% coercions
+
+ SFPolyToUPoly(p) ==
+ -- 'p' is of type Polynomial, but has only one variable
+ zero? p => 0
+ monomial(leadingCoefficient p,totalDegree p) +
+ SFPolyToUPoly(reductum p)
+
+ RNPolyToUPoly(p) ==
+ -- 'p' is of type Polynomial, but has only one variable
+ zero? p => 0
+ monomial(leadingCoefficient p,totalDegree p) +
+ RNPolyToUPoly(reductum p)
+
+ coerceCoefsToSFs(p) ==
+ -- coefficients of 'p' are coerced to be DoubleFloat's
+ map(coerce,p)$PolynomialFunctions2(I,SF)
+
+ coerceCoefsToRNs(p) ==
+ -- coefficients of 'p' are coerced to be DoubleFloat's
+ map(coerce,p)$PolynomialFunctions2(I,RN)
+
+ RNtoSF(r) == coerce(r)@SF
+ RNtoNF(r) == coerce(r)@NF
+ SFtoNF(x) == convert(x)@NF
+
+--% computation of special points
+
+ listPtsOnHorizBdry(pRN,y,y0,xMinNF,xMaxNF) ==
+ -- strict inequality here: corners on vertical boundary
+ pointList : L Pt := nil()
+ ySF := RNtoSF(y0)
+ f := eval(pRN,y,y0)
+ roots : L NF := kinte(f,EPSILON)
+ for root in roots repeat
+ if (xMinNF < root) and (root < xMaxNF) then
+ pointList := cons(makePt(NFtoSF root, ySF), pointList)
+ pointList
+
+ listPtsOnVertBdry(pRN,x,x0,yMinNF,yMaxNF) ==
+ pointList : L Pt := nil()
+ xSF := RNtoSF(x0)
+ f := eval(pRN,x,x0)
+ roots : L NF := kinte(f,EPSILON)
+ for root in roots repeat
+ if (yMinNF <= root) and (root <= yMaxNF) then
+ pointList := cons(makePt(xSF, NFtoSF root), pointList)
+ pointList
+
+ listPtsInRect(points,xMin,xMax,yMin,yMax) ==
+ pointList : L Pt := nil()
+ for point in points repeat
+ xx := first point; yy := second point
+ if (xMin<=xx) and (xx<=xMax) and (yMin<=yy) and (yy<=yMax) then
+ pointList := cons(makePt(NFtoSF xx,NFtoSF yy),pointList)
+ pointList
+
+ ptsSuchThat?(points,pred) ==
+ for point in points repeat
+ if pred point then return true
+ false
+
+ inRect?(point,xMinNF,xMaxNF,yMinNF,yMaxNF) ==
+ xx := first point; yy := second point
+ xMinNF <= xx and xx <= xMaxNF and yMinNF <= yy and yy <= yMaxNF
+
+ onHorzSeg?(point,xMinNF,xMaxNF,yNF) ==
+ xx := first point; yy := second point
+ yy = yNF and xMinNF <= xx and xx <= xMaxNF
+
+ onVertSeg?(point,yMinNF,yMaxNF,xNF) ==
+ xx := first point; yy := second point
+ xx = xNF and yMinNF <= yy and yy <= yMaxNF
+
+ newX(vtanPts,singPts,yMinNF,yMaxNF,xNF,xRN,horizInc) ==
+ xNewNF := xNF + RNtoNF horizInc
+ xRtNF := max(xNF,xNewNF); xLftNF := min(xNF,xNewNF)
+-- ptsSuchThat?(singPts,inRect?(#1,xLftNF,xRtNF,yMinNF,yMaxNF)) =>
+ foo : L NF -> B := inRect?(#1,xLftNF,xRtNF,yMinNF,yMaxNF)
+ ptsSuchThat?(singPts,foo) =>
+ newX(vtanPts,singPts,yMinNF,yMaxNF,xNF,xRN,horizInc/2::RN)
+-- ptsSuchThat?(vtanPts,onVertSeg?(#1,yMinNF,yMaxNF,xNewNF)) =>
+ goo : L NF -> B := onVertSeg?(#1,yMinNF,yMaxNF,xNewNF)
+ ptsSuchThat?(vtanPts,goo) =>
+ newX(vtanPts,singPts,yMinNF,yMaxNF,xNF,xRN,horizInc/2::RN)
+ xRN + horizInc
+
+ newY(htanPts,singPts,xMinNF,xMaxNF,yNF,yRN,vertInc) ==
+ yNewNF := yNF + RNtoNF vertInc
+ yTopNF := max(yNF,yNewNF); yBotNF := min(yNF,yNewNF)
+-- ptsSuchThat?(singPts,inRect?(#1,xMinNF,xMaxNF,yBotNF,yTopNF)) =>
+ foo : L NF -> B := inRect?(#1,xMinNF,xMaxNF,yBotNF,yTopNF)
+ ptsSuchThat?(singPts,foo) =>
+ newY(htanPts,singPts,xMinNF,xMaxNF,yNF,yRN,vertInc/2::RN)
+-- ptsSuchThat?(htanPts,onHorzSeg?(#1,xMinNF,xMaxNF,yNewNF)) =>
+ goo : L NF -> B := onHorzSeg?(#1,xMinNF,xMaxNF,yNewNF)
+ ptsSuchThat?(htanPts,goo) =>
+ newY(htanPts,singPts,xMinNF,xMaxNF,yNF,yRN,vertInc/2::RN)
+ yRN + vertInc
+
+--% creation of sketches
+
+ makeSketch(p,x,y,xRange,yRange) ==
+ xMin := lo xRange; xMax := hi xRange
+ yMin := lo yRange; yMax := hi yRange
+ -- test input for consistency
+ xMax <= xMin =>
+ error "makeSketch: bad range for first variable"
+ yMax <= yMin =>
+ error "makeSketch: bad range for second variable"
+ varList := variables p
+ # varList > 2 =>
+ error "makeSketch: polynomial in more than 2 variables"
+ # varList = 0 =>
+ error "makeSketch: constant polynomial"
+ -- polynomial in 1 variable
+ # varList = 1 =>
+ (not member?(x,varList)) and (not member?(y,varList)) =>
+ error "makeSketch: bad variables"
+ makeOneVarSketch(p,x,y,xMin,xMax,yMin,yMax,first varList)
+ -- polynomial in 2 variables
+ (not member?(x,varList)) or (not member?(y,varList)) =>
+ error "makeSketch: bad variables"
+ totalDegree p = 1 =>
+ makeLineSketch(p,x,y,xMin,xMax,yMin,yMax)
+ -- polynomial is linear in one variable
+ -- y is a rational function of x
+ degree(p,y) = 1 =>
+ makeRatFcnSketch(p,x,y,xMin,xMax,yMin,yMax,y)
+ -- x is a rational function of y
+ degree(p,x) = 1 =>
+ makeRatFcnSketch(p,x,y,xMin,xMax,yMin,yMax,x)
+ -- the general case
+ makeGeneralSketch(p,x,y,xMin,xMax,yMin,yMax)
+
+--% special cases
+
+ makeOneVarSketch(p,x,y,xMin,xMax,yMin,yMax,var) ==
+ -- the case where 'p' is a polynomial in only one variable
+ -- the graph consists of horizontal or vertical lines
+ if var = x then
+ minVal := RNtoNF xMin
+ maxVal := RNtoNF xMax
+ else
+ minVal := RNtoNF yMin
+ maxVal := RNtoNF yMax
+ lf : L Pt := nil(); rt : L Pt := nil()
+ bt : L Pt := nil(); tp : L Pt := nil()
+ htans : L Pt := nil(); vtans : L Pt := nil()
+ bran : L L Pt := nil()
+ roots := kinte(p,EPSILON)
+ sketchRoots : L SF := nil()
+ for root in roots repeat
+ if (minVal <= root) and (root <= maxVal) then
+ sketchRoots := cons(NFtoSF root,sketchRoots)
+ null sketchRoots =>
+ [p,x,y,xMin,xMax,yMin,yMax,[lf,rt,bt,tp],htans,vtans,bran]
+ if var = x then
+ yMinSF := RNtoSF yMin; yMaxSF := RNtoSF yMax
+ for rootSF in sketchRoots repeat
+ tp := cons(pt1 := makePt(rootSF,yMaxSF),tp)
+ bt := cons(pt2 := makePt(rootSF,yMinSF),bt)
+ branch : L Pt := [pt1,pt2]
+ bran := cons(branch,bran)
+ else
+ xMinSF := RNtoSF xMin; xMaxSF := RNtoSF xMax
+ for rootSF in sketchRoots repeat
+ rt := cons(pt1 := makePt(xMaxSF,rootSF),rt)
+ lf := cons(pt2 := makePt(xMinSF,rootSF),lf)
+ branch : L Pt := [pt1,pt2]
+ bran := cons(branch,bran)
+ [p,x,y,xMin,xMax,yMin,yMax,[lf,rt,bt,tp],htans,vtans,bran]
+
+ makeLineSketch(p,x,y,xMin,xMax,yMin,yMax) ==
+ -- the case where p(x,y) = a x + b y + c with a ^= 0, b ^= 0
+ -- this is a line which is neither vertical nor horizontal
+ xMinSF := RNtoSF xMin; xMaxSF := RNtoSF xMax
+ yMinSF := RNtoSF yMin; yMaxSF := RNtoSF yMax
+ -- determine the coefficients a, b, and c
+ a := ground(coefficient(p,x,1)) :: SF
+ b := ground(coefficient(p,y,1)) :: SF
+ c := ground(coefficient(coefficient(p,x,0),y,0)) :: SF
+ lf : L Pt := nil(); rt : L Pt := nil()
+ bt : L Pt := nil(); tp : L Pt := nil()
+ htans : L Pt := nil(); vtans : L Pt := nil()
+ branch : L Pt := nil(); bran : L L Pt := nil()
+ -- compute x coordinate of point on line with y = yMin
+ xBottom := (- b*yMinSF - c)/a
+ -- compute x coordinate of point on line with y = yMax
+ xTop := (- b*yMaxSF - c)/a
+ -- compute y coordinate of point on line with x = xMin
+ yLeft := (- a*xMinSF - c)/b
+ -- compute y coordinate of point on line with x = xMax
+ yRight := (- a*xMaxSF - c)/b
+ -- determine which of the above 4 points are in the region
+ -- to be plotted and list them as a branch
+ if (xMinSF < xBottom) and (xBottom < xMaxSF) then
+ bt := cons(pt := makePt(xBottom,yMinSF),bt)
+ branch := cons(pt,branch)
+ if (xMinSF < xTop) and (xTop < xMaxSF) then
+ tp := cons(pt := makePt(xTop,yMaxSF),tp)
+ branch := cons(pt,branch)
+ if (yMinSF <= yLeft) and (yLeft <= yMaxSF) then
+ lf := cons(pt := makePt(xMinSF,yLeft),lf)
+ branch := cons(pt,branch)
+ if (yMinSF <= yRight) and (yRight <= yMaxSF) then
+ rt := cons(pt := makePt(xMaxSF,yRight),rt)
+ branch := cons(pt,branch)
+ bran := cons(branch,bran)
+ [p,x,y,xMin,xMax,yMin,yMax,[lf,rt,bt,tp],htans,vtans,bran]
+
+ singValBetween?(xCurrent,xNext,xSingList) ==
+ for xVal in xSingList repeat
+ (xCurrent < xVal) and (xVal < xNext) => return true
+ false
+
+ segmentInfo(f,lo,hi,botList,topList,singList,minSF,maxSF) ==
+ repeat
+ -- 'current' is the smallest element of 'topList' and 'botList'
+ -- 'currentFrom' records the list from which it was taken
+ if null topList then
+ if null botList then
+ return [segment(lo,hi),hi,nil(),nil()]
+ else
+ current := first botList
+ botList := rest botList
+ currentFrom := BOTTOM
+ else
+ if null botList then
+ current := first topList
+ topList := rest topList
+ currentFrom := TOP
+ else
+ bot := first botList
+ top := first topList
+ if bot < top then
+ current := bot
+ botList := rest botList
+ currentFrom := BOTTOM
+ else
+ current := top
+ topList := rest topList
+ currentFrom := TOP
+ -- 'nxt' is the next smallest element of 'topList'
+ -- and 'botList'
+ -- 'nextFrom' records the list from which it was taken
+ if null topList then
+ if null botList then
+ return [segment(lo,hi),hi,nil(),nil()]
+ else
+ nxt := first botList
+ botList := rest botList
+ nextFrom := BOTTOM
+ else
+ if null botList then
+ nxt := first topList
+ topList := rest topList
+ nextFrom := TOP
+ else
+ bot := first botList
+ top := first topList
+ if bot < top then
+ nxt := bot
+ botList := rest botList
+ nextFrom := BOTTOM
+ else
+ nxt := top
+ topList := rest topList
+ nextFrom := TOP
+ if currentFrom = nextFrom then
+ if singValBetween?(current,nxt,singList) then
+ return [segment(lo,current),nxt,botList,topList]
+ else
+ val := f((nxt - current)/2::SF)
+ if (val <= minSF) or (val >= maxSF) then
+ return [segment(lo,current),nxt,botList,topList]
+ else
+ if singValBetween?(current,nxt,singList) then
+ return [segment(lo,current),nxt,botList,topList]
+
+ makeRatFcnSketch(p,x,y,xMin,xMax,yMin,yMax,depVar) ==
+ -- the case where p(x,y) is linear in x or y
+ -- Thus, one variable is a rational function of the other.
+ -- Therefore, we may use the 2-dimensional function plotting
+ -- package. The only problem is determining the intervals on
+ -- on which the function is to be plotted.
+ --!! corners: e.g. upper left corner is on graph with y' > 0
+ factoredP := p :: FR P I
+ numberOfFactors(factoredP) > 1 =>
+ error "reducible polynomial" --!! sketch each factor
+ dpdx := differentiate(p,x)
+ dpdy := differentiate(p,y)
+ pRN := coerceCoefsToRNs p
+ xMinSF := RNtoSF xMin; xMaxSF := RNtoSF xMax
+ yMinSF := RNtoSF yMin; yMaxSF := RNtoSF yMax
+ xMinNF := RNtoNF xMin; xMaxNF := RNtoNF xMax
+ yMinNF := RNtoNF yMin; yMaxNF := RNtoNF yMax
+ -- 'p' is of degree 1 in the variable 'depVar'.
+ -- Thus, 'depVar' is a rational function of the other variable.
+ num := -coefficient(p,depVar,0)
+ den := coefficient(p,depVar,1)
+ numUPolySF := SFPolyToUPoly(coerceCoefsToSFs(num))
+ denUPolySF := SFPolyToUPoly(coerceCoefsToSFs(den))
+ -- this is the rational function
+ f : SF -> SF := elt(numUPolySF,#1)/elt(denUPolySF,#1)
+ -- values of the dependent and independent variables
+ if depVar = x then
+ indVarMin := yMin; indVarMax := yMax
+ indVarMinNF := yMinNF; indVarMaxNF := yMaxNF
+ indVarMinSF := yMinSF; indVarMaxSF := yMaxSF
+ depVarMin := xMin; depVarMax := xMax
+ depVarMinSF := xMinSF; depVarMaxSF := xMaxSF
+ else
+ indVarMin := xMin; indVarMax := xMax
+ indVarMinNF := xMinNF; indVarMaxNF := xMaxNF
+ indVarMinSF := xMinSF; indVarMaxSF := xMaxSF
+ depVarMin := yMin; depVarMax := yMax
+ depVarMinSF := yMinSF; depVarMaxSF := yMaxSF
+ -- Create lists of critical points.
+ htanPts := rsolve([p,dpdx],[x,y],EPSILON)
+ vtanPts := rsolve([p,dpdy],[x,y],EPSILON)
+ htans := listPtsInRect(htanPts,xMinNF,xMaxNF,yMinNF,yMaxNF)
+ vtans := listPtsInRect(vtanPts,xMinNF,xMaxNF,yMinNF,yMaxNF)
+ -- Create lists which will contain boundary points.
+ lf : L Pt := nil(); rt : L Pt := nil()
+ bt : L Pt := nil(); tp : L Pt := nil()
+ -- Determine values of the independent variable at the which
+ -- the rational function has a pole as well as the values of
+ -- the independent variable for which there is a point on the
+ -- upper or lower boundary.
+ singList : L SF :=
+ roots : L NF := kinte(den,EPSILON)
+ outList : L SF := nil()
+ for root in roots repeat
+ if (indVarMinNF < root) and (root < indVarMaxNF) then
+ outList := cons(NFtoSF root,outList)
+ sort(#1 < #2,outList)
+ topList : L SF :=
+ roots : L NF := kinte(eval(pRN,depVar,depVarMax),EPSILON)
+ outList : L SF := nil()
+ for root in roots repeat
+ if (indVarMinNF < root) and (root < indVarMaxNF) then
+ outList := cons(NFtoSF root,outList)
+ sort(#1 < #2,outList)
+ botList : L SF :=
+ roots : L NF := kinte(eval(pRN,depVar,depVarMin),EPSILON)
+ outList : L SF := nil()
+ for root in roots repeat
+ if (indVarMinNF < root) and (root < indVarMaxNF) then
+ outList := cons(NFtoSF root,outList)
+ sort(#1 < #2,outList)
+ -- We wish to determine if the graph has points on the 'left'
+ -- and 'right' boundaries, so we compute the value of the
+ -- rational function at the lefthand and righthand values of
+ -- the dependent variable. If the function has a singularity
+ -- on the left or right boundary, then 'leftVal' or 'rightVal'
+ -- is given a dummy valuewhich will convince the program that
+ -- there is no point on the left or right boundary.
+ denUPolyRN := RNPolyToUPoly(coerceCoefsToRNs(den))
+ if elt(denUPolyRN,indVarMin) = 0$RN then
+ leftVal := depVarMinSF - (abs(depVarMinSF) + 1$SF)
+ else
+ leftVal := f(indVarMinSF)
+ if elt(denUPolyRN,indVarMax) = 0$RN then
+ rightVal := depVarMinSF - (abs(depVarMinSF) + 1$SF)
+ else
+ rightVal := f(indVarMaxSF)
+ -- Now put boundary points on the appropriate lists.
+ if depVar = x then
+ if (xMinSF < leftVal) and (leftVal < xMaxSF) then
+ bt := cons(makePt(leftVal,yMinSF),bt)
+ if (xMinSF < rightVal) and (rightVal < xMaxSF) then
+ tp := cons(makePt(rightVal,yMaxSF),tp)
+ for val in botList repeat
+ lf := cons(makePt(xMinSF,val),lf)
+ for val in topList repeat
+ rt := cons(makePt(xMaxSF,val),rt)
+ else
+ if (yMinSF < leftVal) and (leftVal < yMaxSF) then
+ lf := cons(makePt(xMinSF,leftVal),lf)
+ if (yMinSF < rightVal) and (rightVal < yMaxSF) then
+ rt := cons(makePt(xMaxSF,rightVal),rt)
+ for val in botList repeat
+ bt := cons(makePt(val,yMinSF),bt)
+ for val in topList repeat
+ tp := cons(makePt(val,yMaxSF),tp)
+ bran : L L Pt := nil()
+ -- Determine segments on which the rational function is to
+ -- be plotted.
+ if (depVarMinSF < leftVal) and (leftVal < depVarMaxSF) then
+ lo := indVarMinSF
+ else
+ if null topList then
+ if null botList then
+ return [p,x,y,xMin,xMax,yMin,yMax,[lf,rt,bt,tp],_
+ htans,vtans,bran]
+ else
+ lo := first botList
+ botList := rest botList
+ else
+ if null botList then
+ lo := first topList
+ topList := rest topList
+ else
+ bot := first botList
+ top := first topList
+ if bot < top then
+ lo := bot
+ botList := rest botList
+ else
+ lo := top
+ topList := rest topList
+ hi := 0$SF -- @#$%^&* compiler
+ if (depVarMinSF < rightVal) and (rightVal < depVarMaxSF) then
+ hi := indVarMaxSF
+ else
+ if null topList then
+ if null botList then
+ error "makeRatFcnSketch: plot domain"
+ else
+ hi := last botList
+ botList := remove(hi,botList)
+ else
+ if null botList then
+ hi := last topList
+ topList := remove(hi,topList)
+ else
+ bot := last botList
+ top := last topList
+ if bot > top then
+ hi := bot
+ botList := remove(hi,botList)
+ else
+ hi := top
+ topList := remove(hi,topList)
+ if (depVar = x) then
+ (minSF := xMinSF; maxSF := xMaxSF)
+ else
+ (minSF := yMinSF; maxSF := yMaxSF)
+ segList : L SEG SF := nil()
+ repeat
+ segInfo := segmentInfo(f,lo,hi,botList,topList,singList,_
+ minSF,maxSF)
+ segList := cons(segInfo.seg,segList)
+ lo := segInfo.left
+ botList := segInfo.lowerVals
+ topList := segInfo.upperVals
+ if lo = hi then break
+ for segment in segList repeat
+ RFPlot : Plot := plot(f,segment)
+ curve := first(listBranches(RFPlot))
+ if depVar = y then
+ bran := cons(curve,bran)
+ else
+ bran := cons(map(swapCoords,curve),bran)
+ [p,x,y,xMin,xMax,yMin,yMax,[lf,rt,bt,tp],htans,vtans,bran]
+
+--% the general case
+
+ makeGeneralSketch(pol,x,y,xMin,xMax,yMin,yMax) ==
+ --!! corners of region should not be on curve
+ --!! enlarge region if necessary
+ factoredPol := pol :: FR P I
+ numberOfFactors(factoredPol) > 1 =>
+ error "reducible polynomial" --!! sketch each factor
+ p := nthFactor(factoredPol,1)
+ dpdx := differentiate(p,x); dpdy := differentiate(p,y)
+ xMinNF := RNtoNF xMin; xMaxNF := RNtoNF xMax
+ yMinNF := RNtoNF yMin; yMaxNF := RNtoNF yMax
+ -- compute singular points; error if singularities in region
+ singPts := rsolve([p,dpdx,dpdy],[x,y],EPSILON)
+-- ptsSuchThat?(singPts,inRect?(#1,xMinNF,xMaxNF,yMinNF,yMaxNF)) =>
+ foo : L NF -> B := inRect?(#1,xMinNF,xMaxNF,yMinNF,yMaxNF)
+ ptsSuchThat?(singPts,foo) =>
+ error "singular pts in region of sketch"
+ -- compute critical points
+ htanPts := rsolve([p,dpdx],[x,y],EPSILON)
+ vtanPts := rsolve([p,dpdy],[x,y],EPSILON)
+ critPts := append(htanPts,vtanPts)
+ -- if there are critical points on the boundary, then enlarge
+ -- the region, but be sure that the new region does not contain
+ -- any singular points
+ hInc : RN := (1/20) * (xMax - xMin)
+ vInc : RN := (1/20) * (yMax - yMin)
+-- if ptsSuchThat?(critPts,onVertSeg?(#1,yMinNF,yMaxNF,xMinNF)) then
+ foo : L NF -> B := onVertSeg?(#1,yMinNF,yMaxNF,xMinNF)
+ if ptsSuchThat?(critPts,foo) then
+ xMin := newX(critPts,singPts,yMinNF,yMaxNF,xMinNF,xMin,-hInc)
+ xMinNF := RNtoNF xMin
+-- if ptsSuchThat?(critPts,onVertSeg?(#1,yMinNF,yMaxNF,xMaxNF)) then
+ foo : L NF -> B := onVertSeg?(#1,yMinNF,yMaxNF,xMaxNF)
+ if ptsSuchThat?(critPts,foo) then
+ xMax := newX(critPts,singPts,yMinNF,yMaxNF,xMaxNF,xMax,hInc)
+ xMaxNF := RNtoNF xMax
+-- if ptsSuchThat?(critPts,onHorzSeg?(#1,xMinNF,xMaxNF,yMinNF)) then
+ foo : L NF -> B := onHorzSeg?(#1,xMinNF,xMaxNF,yMinNF)
+ if ptsSuchThat?(critPts,foo) then
+ yMin := newY(critPts,singPts,xMinNF,xMaxNF,yMinNF,yMin,-vInc)
+ yMinNF := RNtoNF yMin
+-- if ptsSuchThat?(critPts,onHorzSeg?(#1,xMinNF,xMaxNF,yMaxNF)) then
+ foo : L NF -> B := onHorzSeg?(#1,xMinNF,xMaxNF,yMaxNF)
+ if ptsSuchThat?(critPts,foo) then
+ yMax := newY(critPts,singPts,xMinNF,xMaxNF,yMaxNF,yMax,vInc)
+ yMaxNF := RNtoNF yMax
+ htans := listPtsInRect(htanPts,xMinNF,xMaxNF,yMinNF,yMaxNF)
+ vtans := listPtsInRect(vtanPts,xMinNF,xMaxNF,yMinNF,yMaxNF)
+ crits := append(htans,vtans)
+ -- conversions to DoubleFloats
+ xMinSF := RNtoSF xMin; xMaxSF := RNtoSF xMax
+ yMinSF := RNtoSF yMin; yMaxSF := RNtoSF yMax
+ corners := makeCorners(xMinSF,xMaxSF,yMinSF,yMaxSF)
+ pSF := coerceCoefsToSFs p
+ dpdxSF := coerceCoefsToSFs dpdx
+ dpdySF := coerceCoefsToSFs dpdy
+ delta := min((xMaxSF - xMinSF)/25,(yMaxSF - yMinSF)/25)
+ err := min(delta/100,PLOTERR/100)
+ bound : PI := 10
+ -- compute points on the boundary
+ pRN := coerceCoefsToRNs(p)
+ lf : L Pt := listPtsOnVertBdry(pRN,x,xMin,yMinNF,yMaxNF)
+ rt : L Pt := listPtsOnVertBdry(pRN,x,xMax,yMinNF,yMaxNF)
+ bt : L Pt := listPtsOnHorizBdry(pRN,y,yMin,xMinNF,xMaxNF)
+ tp : L Pt := listPtsOnHorizBdry(pRN,y,yMax,xMinNF,xMaxNF)
+ bdPts : BoundaryPts := [lf,rt,bt,tp]
+ bran := traceBranches(pSF,dpdxSF,dpdySF,x,y,corners,delta,err,_
+ bound,crits,bdPts)
+ [p,x,y,xMin,xMax,yMin,yMax,bdPts,htans,vtans,bran]
+
+ refine(plot,stepFraction) ==
+ p := plot.poly; x := plot.xVar; y := plot.yVar
+ dpdx := differentiate(p,x); dpdy := differentiate(p,y)
+ pSF := coerceCoefsToSFs p
+ dpdxSF := coerceCoefsToSFs dpdx
+ dpdySF := coerceCoefsToSFs dpdy
+ xMin := plot.minXVal; xMax := plot.maxXVal
+ yMin := plot.minYVal; yMax := plot.maxYVal
+ xMinSF := RNtoSF xMin; xMaxSF := RNtoSF xMax
+ yMinSF := RNtoSF yMin; yMaxSF := RNtoSF yMax
+ corners := makeCorners(xMinSF,xMaxSF,yMinSF,yMaxSF)
+ pSF := coerceCoefsToSFs p
+ dpdxSF := coerceCoefsToSFs dpdx
+ dpdySF := coerceCoefsToSFs dpdy
+ delta :=
+ stepFraction * min((xMaxSF - xMinSF)/25,(yMaxSF - yMinSF)/25)
+ err := min(delta/100,PLOTERR/100)
+ bound : PI := 10
+ crits := append(plot.hTanPts,plot.vTanPts)
+ bdPts := plot.bdryPts
+ bran := traceBranches(pSF,dpdxSF,dpdySF,x,y,corners,delta,err,_
+ bound,crits,bdPts)
+ htans := plot.hTanPts; vtans := plot.vTanPts
+ [p,x,y,xMin,xMax,yMin,yMax,bdPts,htans,vtans,bran]
+
+ traceBranches(pSF,dpdxSF,dpdySF,x,y,corners,delta,err,bound,_
+ crits,bdPts) ==
+ -- for boundary points, trace curve from boundary to boundary
+ -- add the branch to the list of branches
+ -- update list of boundary points by deleting first and last
+ -- points on this branch
+ -- update list of critical points by deleting any critical
+ -- points which were plotted
+ lf := bdPts.left; rt := bdPts.right
+ tp := bdPts.top ; bt := bdPts.bottom
+ bdry := append(append(lf,rt),append(bt,tp))
+ bran : L L Pt := nil()
+ while not null bdry repeat
+ pt := first bdry
+ p0 := dummyFirstPt(pt,dpdxSF,dpdySF,x,y,lf,rt,bt,tp)
+ segInfo := listPtsOnSegment(pSF,dpdxSF,dpdySF,x,y,p0,pt,_
+ corners,delta,err,bound,crits,bdry)
+ bran := cons(first segInfo,bran)
+ crits := second segInfo
+ bdry := third segInfo
+ -- trace loops beginning and ending with critical points
+ -- add the branch to the list of branches
+ -- update list of critical points by deleting any critical
+ -- points which were plotted
+ while not null crits repeat
+ pt := first crits
+ segInfo := listPtsOnLoop(pSF,dpdxSF,dpdySF,x,y,pt,_
+ corners,delta,err,bound,crits,bdry)
+ bran := cons(first segInfo,bran)
+ crits := second segInfo
+ bran
+
+ dummyFirstPt(p1,dpdxSF,dpdySF,x,y,lf,rt,bt,tp) ==
+ -- The function 'computeNextPt' requires 2 points, p0 and p1.
+ -- When computing the second point on a branch which starts
+ -- on the boundary, we use the boundary point as p1 and the
+ -- 'dummy' point returned by this function as p0.
+ x1 := xCoord p1; y1 := yCoord p1
+ zero := 0$SF; one := 1$SF
+ px := ground(eval(dpdxSF,[x,y],[x1,y1]))
+ py := ground(eval(dpdySF,[x,y],[x1,y1]))
+ if px * py < zero then -- positive slope at p1
+ member?(p1,lf) or member?(p1,bt) =>
+ makePt(x1 - one,y1 - one)
+ makePt(x1 + one,y1 + one)
+ else
+ member?(p1,lf) or member?(p1,tp) =>
+ makePt(x1 - one,y1 + one)
+ makePt(x1 + one,y1 - one)
+
+ listPtsOnSegment(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ delta,err,bound,crits,bdry) ==
+ -- p1 is a boundary point; p0 is a 'dummy' point
+ bdry := remove(p1,bdry)
+ pointList : L Pt := [p1]
+ ptInfo := computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ delta,err,bound,crits,bdry)
+ p2 := ptInfo.newPt
+ ptInfo.type = BDRY =>
+ bdry := remove(p2,bdry)
+ pointList := cons(p2,pointList)
+ [pointList,crits,bdry]
+ if ptInfo.type = CRIT then crits := remove(p2,crits)
+ pointList := cons(p2,pointList)
+ repeat
+ pt0 := second pointList; pt1 := first pointList
+ ptInfo := computeNextPt(pSF,dpdxSF,dpdySF,x,y,pt0,pt1,corners,_
+ delta,err,bound,crits,bdry)
+ p2 := ptInfo.newPt
+ ptInfo.type = BDRY =>
+ bdry := remove(p2,bdry)
+ pointList := cons(p2,pointList)
+ return [pointList,crits,bdry]
+ if ptInfo.type = CRIT then crits := remove(p2,crits)
+ pointList := cons(p2,pointList)
+ --!! delete next line (compiler bug)
+ [pointList,crits,bdry]
+
+
+ listPtsOnLoop(pSF,dpdxSF,dpdySF,x,y,p1,corners,_
+ delta,err,bound,crits,bdry) ==
+ x1 := xCoord p1; y1 := yCoord p1
+ px := ground(eval(dpdxSF,[x,y],[x1,y1]))
+ py := ground(eval(dpdySF,[x,y],[x1,y1]))
+ p0 := makePt(x1 - 1$SF,y1 - 1$SF)
+ pointList : L Pt := [p1]
+ ptInfo := computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ delta,err,bound,crits,bdry)
+ p2 := ptInfo.newPt
+ ptInfo.type = BDRY =>
+ error "boundary reached while on loop"
+ if ptInfo.type = CRIT then
+ p1 = p2 =>
+ error "first and second points on loop are identical"
+ crits := remove(p2,crits)
+ pointList := cons(p2,pointList)
+ repeat
+ pt0 := second pointList; pt1 := first pointList
+ ptInfo := computeNextPt(pSF,dpdxSF,dpdySF,x,y,pt0,pt1,corners,_
+ delta,err,bound,crits,bdry)
+ p2 := ptInfo.newPt
+ ptInfo.type = BDRY =>
+ error "boundary reached while on loop"
+ if ptInfo.type = CRIT then
+ crits := remove(p2,crits)
+ p1 = p2 =>
+ pointList := cons(p2,pointList)
+ return [pointList,crits,bdry]
+ pointList := cons(p2,pointList)
+ --!! delete next line (compiler bug)
+ [pointList,crits,bdry]
+
+ computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ delta,err,bound,crits,bdry) ==
+ -- p0=(x0,y0) and p1=(x1,y1) are the last two points on the curve.
+ -- The function computes the next point on the curve.
+ -- The function determines if the next point is a critical point
+ -- or a boundary point.
+ -- The function returns a record of the form
+ -- Record(newPt:Pt,type:String).
+ -- If the new point is a boundary point, then 'type' is
+ -- "boundary point" and 'newPt' is a boundary point to be
+ -- deleted from the list of boundary points yet to be plotted.
+ -- Similarly, if the new point is a critical point, then 'type' is
+ -- "critical point" and 'newPt' is a critical point to be
+ -- deleted from the list of critical points yet to be plotted.
+ -- If the new point is neither a critical point nor a boundary
+ -- point, then 'type' is "nothing in particular".
+ xMinSF := getXMin corners; xMaxSF := getXMax corners
+ yMinSF := getYMin corners; yMaxSF := getYMax corners
+ x0 := xCoord p0; y0 := yCoord p0
+ x1 := xCoord p1; y1 := yCoord p1
+ px := ground(eval(dpdxSF,[x,y],[x1,y1]))
+ py := ground(eval(dpdySF,[x,y],[x1,y1]))
+ -- let m be the slope of the tangent line at p1
+ -- if |m| < 1, we will increment the x-coordinate by delta
+ -- (indicated by 'incVar = x'), find an approximate
+ -- y-coordinate using the tangent line, then find the actual
+ -- y-coordinate using a Newton iteration
+ if abs(py) > abs(px) then
+ incVar0 := incVar := x
+ deltaX := (if x1 > x0 then delta else -delta)
+ x2Approx := x1 + deltaX
+ y2Approx := y1 + (-px/py)*deltaX
+ -- if |m| >= 1, we interchange the roles of the x- and y-
+ -- coordinates
+ else
+ incVar0 := incVar := y
+ deltaY := (if y1 > y0 then delta else -delta)
+ x2Approx := x1 + (-py/px)*deltaY
+ y2Approx := y1 + deltaY
+ lookingFor := NADA
+ -- See if (x2Approx,y2Approx) is out of bounds.
+ -- If so, find where the line segment connecting (x1,y1) and
+ -- (x2Approx,y2Approx) intersects the boundary and use this
+ -- point as (x2Approx,y2Approx).
+ -- If the resulting point is on the left or right boundary,
+ -- we will now consider x as the 'incremented variable' and we
+ -- will compute the y-coordinate using a Newton iteration.
+ -- Similarly, if the point is on the top or bottom boundary,
+ -- we will consider y as the 'incremented variable' and we
+ -- will compute the x-coordinate using a Newton iteration.
+ if x2Approx >= xMaxSF then
+ incVar := x
+ lookingFor := BDRY
+ x2Approx := xMaxSF
+ y2Approx := y1 + (-px/py)*(x2Approx - x1)
+ else
+ if x2Approx <= xMinSF then
+ incVar := x
+ lookingFor := BDRY
+ x2Approx := xMinSF
+ y2Approx := y1 + (-px/py)*(x2Approx - x1)
+ if y2Approx >= yMaxSF then
+ incVar := y
+ lookingFor := BDRY
+ y2Approx := yMaxSF
+ x2Approx := x1 + (-py/px)*(y2Approx - y1)
+ else
+ if y2Approx <= yMinSF then
+ incVar := y
+ lookingFor := BDRY
+ y2Approx := yMinSF
+ x2Approx := x1 + (-py/px)*(y2Approx - y1)
+ -- set xLo = min(x1,x2Approx), xHi = max(x1,x2Approx)
+ -- set yLo = min(y1,y2Approx), yHi = max(y1,y2Approx)
+ if x1 < x2Approx then
+ xLo := x1
+ xHi := x2Approx
+ else
+ xLo := x2Approx
+ xHi := x1
+ if y1 < y2Approx then
+ yLo := y1
+ yHi := y2Approx
+ else
+ yLo := y2Approx
+ yHi := y1
+ -- check for critical points (x*,y*) with x* between
+ -- x1 and x2Approx or y* between y1 and y2Approx
+ -- store values of x2Approx and y2Approx
+ x2Approxx := x2Approx
+ y2Approxx := y2Approx
+ -- xPointList will contain all critical points (x*,y*)
+ -- with x* between x1 and x2Approx
+ xPointList : L Pt := nil()
+ -- yPointList will contain all critical points (x*,y*)
+ -- with y* between y1 and y2Approx
+ yPointList : L Pt := nil()
+ for pt in crits repeat
+ xx := xCoord pt; yy := yCoord pt
+ -- if x1 = x2Approx, then p1 is a point with horizontal
+ -- tangent line
+ -- in this case, we don't want critical points with
+ -- x-coordinate x1
+ if xx = x2Approx and not (xx = x1) then
+ if min(abs(yy-yLo),abs(yy-yHi)) < delta then
+ xPointList := cons(pt,xPointList)
+ if ((xLo < xx) and (xx < xHi)) then
+ if min(abs(yy-yLo),abs(yy-yHi)) < delta then
+ xPointList := cons(pt,nil())
+ x2Approx := xx
+ if xx < x1 then xLo := xx else xHi := xx
+ -- if y1 = y2Approx, then p1 is a point with vertical
+ -- tangent line
+ -- in this case, we don't want critical points with
+ -- y-coordinate y1
+ if yy = y2Approx and not (yy = y1) then
+ yPointList := cons(pt,yPointList)
+ if ((yLo < yy) and (yy < yHi)) then
+ if min(abs(xx-xLo),abs(xx-xHi)) < delta then
+ yPointList := cons(pt,nil())
+ y2Approx := yy
+ if yy < y1 then yLo := yy else yHi := yy
+ -- points in both xPointList and yPointList
+ if (not null xPointList) and (not null yPointList) then
+ xPointList = yPointList =>
+ -- this implies that the lists have only one point
+ incVar := incVar0
+ if incVar = x then
+ y2Approx := y1 + (-px/py)*(x2Approx - x1)
+ else
+ x2Approx := x1 + (-py/px)*(y2Approx - y1)
+ lookingFor := CRIT -- proceed
+ incVar0 = x =>
+ -- first try Newton iteration with 'y' as incremented variable
+ x2Temp := x1 + (-py/px)*(y2Approx - y1)
+ f := SFPolyToUPoly(eval(pSF,y,y2Approx))
+ x2New := newtonApprox(f,x2Temp,err,bound)
+ x2New case "failed" =>
+ y2Approx := y1 + (-px/py)*(x2Approx - x1)
+ incVar := x
+ lookingFor := CRIT -- proceed
+ y2Temp := y1 + (-px/py)*(x2Approx - x1)
+ f := SFPolyToUPoly(eval(pSF,x,x2Approx))
+ y2New := newtonApprox(f,y2Temp,err,bound)
+ y2New case "failed" =>
+ return computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ abs((x2Approx-x1)/2),err,bound,crits,bdry)
+ pt1 := makePt(x2Approx,y2New :: SF)
+ pt2 := makePt(x2New :: SF,y2Approx)
+ critPt1 := findPtOnList(pt1,crits)
+ critPt2 := findPtOnList(pt2,crits)
+ (critPt1 case "failed") and (critPt2 case "failed") =>
+ abs(x2Approx - x1) > abs(x2Temp - x1) =>
+ return [pt1,NADA]
+ return [pt2,NADA]
+ (critPt1 case "failed") =>
+ return [critPt2::Pt,CRIT]
+ (critPt2 case "failed") =>
+ return [critPt1::Pt,CRIT]
+ abs(x2Approx - x1) > abs(x2Temp - x1) =>
+ return [critPt2::Pt,CRIT]
+ return [critPt1::Pt,CRIT]
+ y2Temp := y1 + (-px/py)*(x2Approx - x1)
+ f := SFPolyToUPoly(eval(pSF,x,x2Approx))
+ y2New := newtonApprox(f,y2Temp,err,bound)
+ y2New case "failed" =>
+ x2Approx := x1 + (-py/px)*(y2Approx - y1)
+ incVar := y
+ lookingFor := CRIT -- proceed
+ x2Temp := x1 + (-py/px)*(y2Approx - y1)
+ f := SFPolyToUPoly(eval(pSF,y,y2Approx))
+ x2New := newtonApprox(f,x2Temp,err,bound)
+ x2New case "failed" =>
+ return computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ abs((y2Approx-y1)/2),err,bound,crits,bdry)
+ pt1 := makePt(x2Approx,y2New :: SF)
+ pt2 := makePt(x2New :: SF,y2Approx)
+ critPt1 := findPtOnList(pt1,crits)
+ critPt2 := findPtOnList(pt2,crits)
+ (critPt1 case "failed") and (critPt2 case "failed") =>
+ abs(y2Approx - y1) > abs(y2Temp - y1) =>
+ return [pt2,NADA]
+ return [pt1,NADA]
+ (critPt1 case "failed") =>
+ return [critPt2::Pt,CRIT]
+ (critPt2 case "failed") =>
+ return [critPt1::Pt,CRIT]
+ abs(y2Approx - y1) > abs(y2Temp - y1) =>
+ return [critPt1::Pt,CRIT]
+ return [critPt2::Pt,CRIT]
+ if (not null xPointList) and (null yPointList) then
+ y2Approx := y1 + (-px/py)*(x2Approx - x1)
+ incVar0 = x =>
+ incVar := x
+ lookingFor := CRIT -- proceed
+ f := SFPolyToUPoly(eval(pSF,x,x2Approx))
+ y2New := newtonApprox(f,y2Approx,err,bound)
+ y2New case "failed" =>
+ x2Approx := x2Approxx
+ y2Approx := y2Approxx -- proceed
+ pt := makePt(x2Approx,y2New::SF)
+ critPt := findPtOnList(pt,crits)
+ critPt case "failed" =>
+ return [pt,NADA]
+ return [critPt :: Pt,CRIT]
+ if (null xPointList) and (not null yPointList) then
+ x2Approx := x1 + (-py/px)*(y2Approx - y1)
+ incVar0 = y =>
+ incVar := y
+ lookingFor := CRIT -- proceed
+ f := SFPolyToUPoly(eval(pSF,y,y2Approx))
+ x2New := newtonApprox(f,x2Approx,err,bound)
+ x2New case "failed" =>
+ x2Approx := x2Approxx
+ y2Approx := y2Approxx -- proceed
+ pt := makePt(x2New::SF,y2Approx)
+ critPt := findPtOnList(pt,crits)
+ critPt case "failed" =>
+ return [pt,NADA]
+ return [critPt :: Pt,CRIT]
+ if incVar = x then
+ x2 := x2Approx
+ f := SFPolyToUPoly(eval(pSF,x,x2))
+ y2New := newtonApprox(f,y2Approx,err,bound)
+ y2New case "failed" =>
+ return computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ abs((x2-x1)/2),err,bound,crits,bdry)
+ y2 := y2New :: SF
+ else
+ y2 := y2Approx
+ f := SFPolyToUPoly(eval(pSF,y,y2))
+ x2New := newtonApprox(f,x2Approx,err,bound)
+ x2New case "failed" =>
+ return computeNextPt(pSF,dpdxSF,dpdySF,x,y,p0,p1,corners,_
+ abs((y2-y1)/2),err,bound,crits,bdry)
+ x2 := x2New :: SF
+ pt := makePt(x2,y2)
+ --!! check that 'pt' is not out of bounds
+ -- check if you've gotten a critical or boundary point
+ lookingFor = NADA =>
+ [pt,lookingFor]
+ lookingFor = BDRY =>
+ bdryPt := findPtOnList(pt,bdry)
+ bdryPt case "failed" =>
+ error "couldn't find boundary point"
+ [bdryPt :: Pt,BDRY]
+ critPt := findPtOnList(pt,crits)
+ critPt case "failed" =>
+ [pt,NADA]
+ [critPt :: Pt,CRIT]
+
+--% Newton iterations
+
+ newtonApprox(f,a0,err,bound) ==
+ -- Newton iteration to approximate a root of the polynomial 'f'
+ -- using an initial approximation of 'a0'
+ -- Newton iteration terminates when consecutive approximations
+ -- are within 'err' of each other
+ -- returns "failed" if this has not been achieved after 'bound'
+ -- iterations
+ Df := differentiate f
+ oldApprox := a0
+ newApprox := a0 - elt(f,a0)/elt(Df,a0)
+ i : PI := 1
+ while abs(newApprox - oldApprox) > err repeat
+ i = bound => return "failed"
+ oldApprox := newApprox
+ newApprox := oldApprox - elt(f,oldApprox)/elt(Df,oldApprox)
+ i := i+1
+ newApprox
+
+--% graphics output
+
+ listBranches(acplot) == acplot.branches
+
+--% terminal output
+
+ coerce(acplot:%) ==
+ pp := acplot.poly :: OUT
+ xx := acplot.xVar :: OUT
+ yy := acplot.yVar :: OUT
+ xLo := acplot.minXVal :: OUT
+ xHi := acplot.maxXVal :: OUT
+ yLo := acplot.minYVal :: OUT
+ yHi := acplot.maxYVal :: OUT
+ zip := message(" = 0")
+ com := message(", ")
+ les := message(" <= ")
+ l : L OUT :=
+ [pp,zip,com,xLo,les,xx,les,xHi,com,yLo,les,yy,les,yHi]
+ f : L OUT := nil()
+ for branch in acplot.branches repeat
+ ll : L OUT := [p :: OUT for p in branch]
+ f := cons(vconcat ll,f)
+ ff := vconcat(hconcat l,vconcat f)
+ vconcat(message "ACPLOT",ff)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REALSOLV RealSolvePackage>>
+<<domain ACPLOT PlaneAlgebraicCurvePlot>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/aggcat.spad.pamphlet b/src/algebra/aggcat.spad.pamphlet
new file mode 100644
index 00000000..1363c020
--- /dev/null
+++ b/src/algebra/aggcat.spad.pamphlet
@@ -0,0 +1,3227 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra aggcat.spad}
+\author{Michael Monagan, Manuel Bronstein, Richard Jenks, Stephen Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category AGG Aggregate}
+<<category AGG Aggregate>>=
+
+)abbrev category AGG Aggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The notion of aggregate serves to model any data structure aggregate,
+++ designating any collection of objects,
+++ with heterogenous or homogeneous members,
+++ with a finite or infinite number
+++ of members, explicitly or implicitly represented.
+++ An aggregate can in principle
+++ represent everything from a string of characters to abstract sets such
+++ as "the set of x satisfying relation {\em r(x)}"
+++ An attribute \spadatt{finiteAggregate} is used to assert that a domain
+++ has a finite number of elements.
+Aggregate: Category == Type with
+ eq?: (%,%) -> Boolean
+ ++ eq?(u,v) tests if u and v are same objects.
+ copy: % -> %
+ ++ copy(u) returns a top-level (non-recursive) copy of u.
+ ++ Note: for collections, \axiom{copy(u) == [x for x in u]}.
+ empty: () -> %
+ ++ empty()$D creates an aggregate of type D with 0 elements.
+ ++ Note: The {\em $D} can be dropped if understood by context,
+ ++ e.g. \axiom{u: D := empty()}.
+ empty?: % -> Boolean
+ ++ empty?(u) tests if u has 0 elements.
+ less?: (%,NonNegativeInteger) -> Boolean
+ ++ less?(u,n) tests if u has less than n elements.
+ more?: (%,NonNegativeInteger) -> Boolean
+ ++ more?(u,n) tests if u has greater than n elements.
+ size?: (%,NonNegativeInteger) -> Boolean
+ ++ size?(u,n) tests if u has exactly n elements.
+ sample: constant -> % ++ sample yields a value of type %
+ if % has finiteAggregate then
+ "#": % -> NonNegativeInteger ++ # u returns the number of items in u.
+ add
+ eq?(a,b) == EQ(a,b)$Lisp
+ sample() == empty()
+ if % has finiteAggregate then
+ empty? a == #a = 0
+ less?(a,n) == #a < n
+ more?(a,n) == #a > n
+ size?(a,n) == #a = n
+
+@
+\section{category HOAGG HomogeneousAggregate}
+<<category HOAGG HomogeneousAggregate>>=
+)abbrev category HOAGG HomogeneousAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991, May 1995
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A homogeneous aggregate is an aggregate of elements all of the
+++ same type.
+++ In the current system, all aggregates are homogeneous.
+++ Two attributes characterize classes of aggregates.
+++ Aggregates from domains with attribute \spadatt{finiteAggregate}
+++ have a finite number of members.
+++ Those with attribute \spadatt{shallowlyMutable} allow an element
+++ to be modified or updated without changing its overall value.
+HomogeneousAggregate(S:Type): Category == Aggregate with
+ if S has SetCategory then SetCategory
+ if S has SetCategory then
+ if S has Evalable S then Evalable S
+ map : (S->S,%) -> %
+ ++ map(f,u) returns a copy of u with each element x replaced by f(x).
+ ++ For collections, \axiom{map(f,u) = [f(x) for x in u]}.
+ if % has shallowlyMutable then
+ map_!: (S->S,%) -> %
+ ++ map!(f,u) destructively replaces each element x of u by \axiom{f(x)}.
+ if % has finiteAggregate then
+ any?: (S->Boolean,%) -> Boolean
+ ++ any?(p,u) tests if \axiom{p(x)} is true for any element x of u.
+ ++ Note: for collections,
+ ++ \axiom{any?(p,u) = reduce(or,map(f,u),false,true)}.
+ every?: (S->Boolean,%) -> Boolean
+ ++ every?(f,u) tests if p(x) is true for all elements x of u.
+ ++ Note: for collections,
+ ++ \axiom{every?(p,u) = reduce(and,map(f,u),true,false)}.
+ count: (S->Boolean,%) -> NonNegativeInteger
+ ++ count(p,u) returns the number of elements x in u
+ ++ such that \axiom{p(x)} is true. For collections,
+ ++ \axiom{count(p,u) = reduce(+,[1 for x in u | p(x)],0)}.
+ parts: % -> List S
+ ++ parts(u) returns a list of the consecutive elements of u.
+ ++ For collections, \axiom{parts([x,y,...,z]) = (x,y,...,z)}.
+ members: % -> List S
+ ++ members(u) returns a list of the consecutive elements of u.
+ ++ For collections, \axiom{parts([x,y,...,z]) = (x,y,...,z)}.
+ if S has SetCategory then
+ count: (S,%) -> NonNegativeInteger
+ ++ count(x,u) returns the number of occurrences of x in u.
+ ++ For collections, \axiom{count(x,u) = reduce(+,[x=y for y in u],0)}.
+ member?: (S,%) -> Boolean
+ ++ member?(x,u) tests if x is a member of u.
+ ++ For collections,
+ ++ \axiom{member?(x,u) = reduce(or,[x=y for y in u],false)}.
+ add
+ if S has Evalable S then
+ eval(u:%,l:List Equation S):% == map(eval(#1,l),u)
+ if % has finiteAggregate then
+ #c == # parts c
+ any?(f, c) == _or/[f x for x in parts c]
+ every?(f, c) == _and/[f x for x in parts c]
+ count(f:S -> Boolean, c:%) == _+/[1 for x in parts c | f x]
+ members x == parts x
+ if S has SetCategory then
+ count(s:S, x:%) == count(s = #1, x)
+ member?(e, c) == any?(e = #1,c)
+ x = y ==
+ size?(x, #y) and _and/[a = b for a in parts x for b in parts y]
+ coerce(x:%):OutputForm ==
+ bracket
+ commaSeparate [a::OutputForm for a in parts x]$List(OutputForm)
+
+@
+\section{HOAGG.lsp BOOTSTRAP}
+{\bf HOAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf HOAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf HOAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<HOAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |HomogeneousAggregate;CAT| (QUOTE NIL))
+
+(SETQ |HomogeneousAggregate;AL| (QUOTE NIL))
+
+(DEFUN |HomogeneousAggregate| (#1=#:G82375)
+ (LET (#2=#:G82376)
+ (COND
+ ((SETQ #2# (|assoc| (|devaluate| #1#) |HomogeneousAggregate;AL|))
+ (CDR #2#))
+ (T
+ (SETQ |HomogeneousAggregate;AL|
+ (|cons5|
+ (CONS (|devaluate| #1#) (SETQ #2# (|HomogeneousAggregate;| #1#)))
+ |HomogeneousAggregate;AL|))
+ #2#))))
+
+(DEFUN |HomogeneousAggregate;| (|t#1|)
+ (PROG (#1=#:G82374)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|)))
+ (COND
+ (|HomogeneousAggregate;CAT|)
+ ((QUOTE T)
+ (LETT |HomogeneousAggregate;CAT|
+ (|Join|
+ (|Aggregate|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|map| (|$| (|Mapping| |t#1| |t#1|) |$|)) T)
+ ((|map!| (|$| (|Mapping| |t#1| |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |shallowlyMutable|)))
+ ((|any?|
+ ((|Boolean|) (|Mapping| (|Boolean|) |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|every?|
+ ((|Boolean|) (|Mapping| (|Boolean|) |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|count|
+ ((|NonNegativeInteger|)
+ (|Mapping| (|Boolean|) |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|parts| ((|List| |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|members| ((|List| |t#1|) |$|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|)))
+ ((|count| ((|NonNegativeInteger|) |t#1| |$|))
+ (AND
+ (|has| |t#1| (|SetCategory|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|))))
+ ((|member?| ((|Boolean|) |t#1| |$|))
+ (AND
+ (|has| |t#1| (|SetCategory|))
+ (|has| |$| (ATTRIBUTE |finiteAggregate|))))))
+ (QUOTE (
+ ((|SetCategory|) (|has| |t#1| (|SetCategory|)))
+ ((|Evalable| |t#1|)
+ (AND
+ (|has| |t#1| (|Evalable| |t#1|))
+ (|has| |t#1| (|SetCategory|))))))
+ (QUOTE (
+ (|Boolean|)
+ (|NonNegativeInteger|)
+ (|List| |t#1|)))
+ NIL))
+ . #2=(|HomogeneousAggregate|))))) . #2#)
+ (SETELT #1# 0
+ (LIST (QUOTE |HomogeneousAggregate|) (|devaluate| |t#1|)))))))
+
+@
+\section{HOAGG-.lsp BOOTSTRAP}
+{\bf HOAGG-} depends on {\bf HOAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf HOAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf HOAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<HOAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |HOAGG-;eval;ALA;1| (|u| |l| |$|) (SPADCALL (CONS (FUNCTION |HOAGG-;eval;ALA;1!0|) (VECTOR |$| |l|)) |u| (QREFELT |$| 11)))
+
+(DEFUN |HOAGG-;eval;ALA;1!0| (|#1| |$$|) (SPADCALL |#1| (QREFELT |$$| 1) (QREFELT (QREFELT |$$| 0) 9)))
+
+(DEFUN |HOAGG-;#;ANni;2| (|c| |$|) (LENGTH (SPADCALL |c| (QREFELT |$| 14))))
+
+(DEFUN |HOAGG-;any?;MAB;3| (|f| |c| |$|) (PROG (|x| #1=#:G82396 #2=#:G82393 #3=#:G82391 #4=#:G82392) (RETURN (SEQ (PROGN (LETT #4# NIL |HOAGG-;any?;MAB;3|) (SEQ (LETT |x| NIL |HOAGG-;any?;MAB;3|) (LETT #1# (SPADCALL |c| (QREFELT |$| 14)) |HOAGG-;any?;MAB;3|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |HOAGG-;any?;MAB;3|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |HOAGG-;any?;MAB;3|) (COND (#4# (LETT #3# (COND (#3# (QUOTE T)) ((QUOTE T) #2#)) |HOAGG-;any?;MAB;3|)) ((QUOTE T) (PROGN (LETT #3# #2# |HOAGG-;any?;MAB;3|) (LETT #4# (QUOTE T) |HOAGG-;any?;MAB;3|))))))) (LETT #1# (CDR #1#) |HOAGG-;any?;MAB;3|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |HOAGG-;every?;MAB;4| (|f| |c| |$|) (PROG (|x| #1=#:G82401 #2=#:G82399 #3=#:G82397 #4=#:G82398) (RETURN (SEQ (PROGN (LETT #4# NIL |HOAGG-;every?;MAB;4|) (SEQ (LETT |x| NIL |HOAGG-;every?;MAB;4|) (LETT #1# (SPADCALL |c| (QREFELT |$| 14)) |HOAGG-;every?;MAB;4|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |HOAGG-;every?;MAB;4|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |HOAGG-;every?;MAB;4|) (COND (#4# (LETT #3# (COND (#3# #2#) ((QUOTE T) (QUOTE NIL))) |HOAGG-;every?;MAB;4|)) ((QUOTE T) (PROGN (LETT #3# #2# |HOAGG-;every?;MAB;4|) (LETT #4# (QUOTE T) |HOAGG-;every?;MAB;4|))))))) (LETT #1# (CDR #1#) |HOAGG-;every?;MAB;4|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE T))))))))
+
+(DEFUN |HOAGG-;count;MANni;5| (|f| |c| |$|) (PROG (|x| #1=#:G82406 #2=#:G82404 #3=#:G82402 #4=#:G82403) (RETURN (SEQ (PROGN (LETT #4# NIL |HOAGG-;count;MANni;5|) (SEQ (LETT |x| NIL |HOAGG-;count;MANni;5|) (LETT #1# (SPADCALL |c| (QREFELT |$| 14)) |HOAGG-;count;MANni;5|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |HOAGG-;count;MANni;5|) NIL)) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |x| |f|) (PROGN (LETT #2# 1 |HOAGG-;count;MANni;5|) (COND (#4# (LETT #3# (|+| #3# #2#) |HOAGG-;count;MANni;5|)) ((QUOTE T) (PROGN (LETT #3# #2# |HOAGG-;count;MANni;5|) (LETT #4# (QUOTE T) |HOAGG-;count;MANni;5|))))))))) (LETT #1# (CDR #1#) |HOAGG-;count;MANni;5|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) 0)))))))
+
+(DEFUN |HOAGG-;members;AL;6| (|x| |$|) (SPADCALL |x| (QREFELT |$| 14)))
+
+(DEFUN |HOAGG-;count;SANni;7| (|s| |x| |$|) (SPADCALL (CONS (FUNCTION |HOAGG-;count;SANni;7!0|) (VECTOR |$| |s|)) |x| (QREFELT |$| 24)))
+
+(DEFUN |HOAGG-;count;SANni;7!0| (|#1| |$$|) (SPADCALL (QREFELT |$$| 1) |#1| (QREFELT (QREFELT |$$| 0) 23)))
+
+(DEFUN |HOAGG-;member?;SAB;8| (|e| |c| |$|) (SPADCALL (CONS (FUNCTION |HOAGG-;member?;SAB;8!0|) (VECTOR |$| |e|)) |c| (QREFELT |$| 26)))
+
+(DEFUN |HOAGG-;member?;SAB;8!0| (|#1| |$$|) (SPADCALL (QREFELT |$$| 1) |#1| (QREFELT (QREFELT |$$| 0) 23)))
+
+(DEFUN |HOAGG-;=;2AB;9| (|x| |y| |$|) (PROG (|b| #1=#:G82416 |a| #2=#:G82415 #3=#:G82412 #4=#:G82410 #5=#:G82411) (RETURN (SEQ (COND ((SPADCALL |x| (SPADCALL |y| (QREFELT |$| 28)) (QREFELT |$| 29)) (PROGN (LETT #5# NIL |HOAGG-;=;2AB;9|) (SEQ (LETT |b| NIL |HOAGG-;=;2AB;9|) (LETT #1# (SPADCALL |y| (QREFELT |$| 14)) |HOAGG-;=;2AB;9|) (LETT |a| NIL |HOAGG-;=;2AB;9|) (LETT #2# (SPADCALL |x| (QREFELT |$| 14)) |HOAGG-;=;2AB;9|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |a| (CAR #2#) |HOAGG-;=;2AB;9|) NIL) (ATOM #1#) (PROGN (LETT |b| (CAR #1#) |HOAGG-;=;2AB;9|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #3# (SPADCALL |a| |b| (QREFELT |$| 23)) |HOAGG-;=;2AB;9|) (COND (#5# (LETT #4# (COND (#4# #3#) ((QUOTE T) (QUOTE NIL))) |HOAGG-;=;2AB;9|)) ((QUOTE T) (PROGN (LETT #4# #3# |HOAGG-;=;2AB;9|) (LETT #5# (QUOTE T) |HOAGG-;=;2AB;9|))))))) (LETT #2# (PROG1 (CDR #2#) (LETT #1# (CDR #1#) |HOAGG-;=;2AB;9|)) |HOAGG-;=;2AB;9|) (GO G190) G191 (EXIT NIL)) (COND (#5# #4#) ((QUOTE T) (QUOTE T))))) ((QUOTE T) (QUOTE NIL)))))))
+
+(DEFUN |HOAGG-;coerce;AOf;10| (|x| |$|) (PROG (#1=#:G82420 |a| #2=#:G82421) (RETURN (SEQ (SPADCALL (SPADCALL (PROGN (LETT #1# NIL |HOAGG-;coerce;AOf;10|) (SEQ (LETT |a| NIL |HOAGG-;coerce;AOf;10|) (LETT #2# (SPADCALL |x| (QREFELT |$| 14)) |HOAGG-;coerce;AOf;10|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |a| (CAR #2#) |HOAGG-;coerce;AOf;10|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |a| (QREFELT |$| 32)) #1#) |HOAGG-;coerce;AOf;10|))) (LETT #2# (CDR #2#) |HOAGG-;coerce;AOf;10|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 34)) (QREFELT |$| 35))))))
+
+(DEFUN |HomogeneousAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|HomogeneousAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |HomogeneousAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 38) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |finiteAggregate|)) (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)) (|HasCategory| |#2| (LIST (QUOTE |Evalable|) (|devaluate| |#2|))) (|HasCategory| |#2| (QUOTE (|SetCategory|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 3) (QSETREFV |$| 12 (CONS (|dispatchFunction| |HOAGG-;eval;ALA;1|) |$|)))) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 16 (CONS (|dispatchFunction| |HOAGG-;#;ANni;2|) |$|)) (QSETREFV |$| 19 (CONS (|dispatchFunction| |HOAGG-;any?;MAB;3|) |$|)) (QSETREFV |$| 20 (CONS (|dispatchFunction| |HOAGG-;every?;MAB;4|) |$|)) (QSETREFV |$| 21 (CONS (|dispatchFunction| |HOAGG-;count;MANni;5|) |$|)) (QSETREFV |$| 22 (CONS (|dispatchFunction| |HOAGG-;members;AL;6|) |$|)) (COND ((|testBitVector| |pv$| 4) (PROGN (QSETREFV |$| 25 (CONS (|dispatchFunction| |HOAGG-;count;SANni;7|) |$|)) (QSETREFV |$| 27 (CONS (|dispatchFunction| |HOAGG-;member?;SAB;8|) |$|)) (QSETREFV |$| 30 (CONS (|dispatchFunction| |HOAGG-;=;2AB;9|) |$|)) (QSETREFV |$| 36 (CONS (|dispatchFunction| |HOAGG-;coerce;AOf;10|) |$|)))))))) |$|))))
+
+(MAKEPROP (QUOTE |HomogeneousAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|List| 37) (0 . |eval|) (|Mapping| 7 7) (6 . |map|) (12 . |eval|) (|List| 7) (18 . |parts|) (|NonNegativeInteger|) (23 . |#|) (|Boolean|) (|Mapping| 17 7) (28 . |any?|) (34 . |every?|) (40 . |count|) (46 . |members|) (51 . |=|) (57 . |count|) (63 . |count|) (69 . |any?|) (75 . |member?|) (81 . |#|) (86 . |size?|) (92 . |=|) (|OutputForm|) (98 . |coerce|) (|List| |$|) (103 . |commaSeparate|) (108 . |bracket|) (113 . |coerce|) (|Equation| 7))) (QUOTE #(|members| 118 |member?| 123 |every?| 129 |eval| 135 |count| 141 |coerce| 153 |any?| 158 |=| 164 |#| 170)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 36 (QUOTE (2 7 0 0 8 9 2 6 0 10 0 11 2 0 0 0 8 12 1 6 13 0 14 1 0 15 0 16 2 0 17 18 0 19 2 0 17 18 0 20 2 0 15 18 0 21 1 0 13 0 22 2 7 17 0 0 23 2 6 15 18 0 24 2 0 15 7 0 25 2 6 17 18 0 26 2 0 17 7 0 27 1 6 15 0 28 2 6 17 0 15 29 2 0 17 0 0 30 1 7 31 0 32 1 31 0 33 34 1 31 0 0 35 1 0 31 0 36 1 0 13 0 22 2 0 17 7 0 27 2 0 17 18 0 20 2 0 0 0 8 12 2 0 15 7 0 25 2 0 15 18 0 21 1 0 31 0 36 2 0 17 18 0 19 2 0 17 0 0 30 1 0 15 0 16)))))) (QUOTE |lookupComplete|)))
+@
+\section{category CLAGG Collection}
+<<category CLAGG Collection>>=
+)abbrev category CLAGG Collection
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A collection is a homogeneous aggregate which can built from
+++ list of members. The operation used to build the aggregate is
+++ generically named \spadfun{construct}. However, each collection
+++ provides its own special function with the same name as the
+++ data type, except with an initial lower case letter, e.g.
+++ \spadfun{list} for \spadtype{List},
+++ \spadfun{flexibleArray} for \spadtype{FlexibleArray}, and so on.
+Collection(S:Type): Category == HomogeneousAggregate(S) with
+ construct: List S -> %
+ ++ \axiom{construct(x,y,...,z)} returns the collection of elements \axiom{x,y,...,z}
+ ++ ordered as given. Equivalently written as \axiom{[x,y,...,z]$D}, where
+ ++ D is the domain. D may be omitted for those of type List.
+ find: (S->Boolean, %) -> Union(S, "failed")
+ ++ find(p,u) returns the first x in u such that \axiom{p(x)} is true, and
+ ++ "failed" otherwise.
+ if % has finiteAggregate then
+ reduce: ((S,S)->S,%) -> S
+ ++ reduce(f,u) reduces the binary operation f across u. For example,
+ ++ if u is \axiom{[x,y,...,z]} then \axiom{reduce(f,u)} returns \axiom{f(..f(f(x,y),...),z)}.
+ ++ Note: if u has one element x, \axiom{reduce(f,u)} returns x.
+ ++ Error: if u is empty.
+ reduce: ((S,S)->S,%,S) -> S
+ ++ reduce(f,u,x) reduces the binary operation f across u, where x is
+ ++ the identity operation of f.
+ ++ Same as \axiom{reduce(f,u)} if u has 2 or more elements.
+ ++ Returns \axiom{f(x,y)} if u has one element y,
+ ++ x if u is empty.
+ ++ For example, \axiom{reduce(+,u,0)} returns the
+ ++ sum of the elements of u.
+ remove: (S->Boolean,%) -> %
+ ++ remove(p,u) returns a copy of u removing all elements x such that
+ ++ \axiom{p(x)} is true.
+ ++ Note: \axiom{remove(p,u) == [x for x in u | not p(x)]}.
+ select: (S->Boolean,%) -> %
+ ++ select(p,u) returns a copy of u containing only those elements such
+ ++ \axiom{p(x)} is true.
+ ++ Note: \axiom{select(p,u) == [x for x in u | p(x)]}.
+ if S has SetCategory then
+ reduce: ((S,S)->S,%,S,S) -> S
+ ++ reduce(f,u,x,z) reduces the binary operation f across u, stopping
+ ++ when an "absorbing element" z is encountered.
+ ++ As for \axiom{reduce(f,u,x)}, x is the identity operation of f.
+ ++ Same as \axiom{reduce(f,u,x)} when u contains no element z.
+ ++ Thus the third argument x is returned when u is empty.
+ remove: (S,%) -> %
+ ++ remove(x,u) returns a copy of u with all
+ ++ elements \axiom{y = x} removed.
+ ++ Note: \axiom{remove(y,c) == [x for x in c | x ^= y]}.
+ removeDuplicates: % -> %
+ ++ removeDuplicates(u) returns a copy of u with all duplicates removed.
+ if S has ConvertibleTo InputForm then ConvertibleTo InputForm
+ add
+ if % has finiteAggregate then
+ #c == # parts c
+ count(f:S -> Boolean, c:%) == _+/[1 for x in parts c | f x]
+ any?(f, c) == _or/[f x for x in parts c]
+ every?(f, c) == _and/[f x for x in parts c]
+ find(f:S -> Boolean, c:%) == find(f, parts c)
+ reduce(f:(S,S)->S, x:%) == reduce(f, parts x)
+ reduce(f:(S,S)->S, x:%, s:S) == reduce(f, parts x, s)
+ remove(f:S->Boolean, x:%) ==
+ construct remove(f, parts x)
+ select(f:S->Boolean, x:%) ==
+ construct select(f, parts x)
+
+ if S has SetCategory then
+ remove(s:S, x:%) == remove(#1 = s, x)
+ reduce(f:(S,S)->S, x:%, s1:S, s2:S) == reduce(f, parts x, s1, s2)
+ removeDuplicates(x) == construct removeDuplicates parts x
+
+@
+\section{CLAGG.lsp BOOTSTRAP}
+{\bf CLAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf CLAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf CLAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<CLAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |Collection;CAT| (QUOTE NIL))
+
+(SETQ |Collection;AL| (QUOTE NIL))
+
+(DEFUN |Collection| (#1=#:G82618) (LET (#2=#:G82619) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |Collection;AL|)) (CDR #2#)) (T (SETQ |Collection;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|Collection;| #1#))) |Collection;AL|)) #2#))))
+
+(DEFUN |Collection;| (|t#1|) (PROG (#1=#:G82617) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|Collection;CAT|) ((QUOTE T) (LETT |Collection;CAT| (|Join| (|HomogeneousAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|construct| (|$| (|List| |t#1|))) T) ((|find| ((|Union| |t#1| "failed") (|Mapping| (|Boolean|) |t#1|) |$|)) T) ((|reduce| (|t#1| (|Mapping| |t#1| |t#1| |t#1|) |$|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|reduce| (|t#1| (|Mapping| |t#1| |t#1| |t#1|) |$| |t#1|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|remove| (|$| (|Mapping| (|Boolean|) |t#1|) |$|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|select| (|$| (|Mapping| (|Boolean|) |t#1|) |$|)) (|has| |$| (ATTRIBUTE |finiteAggregate|))) ((|reduce| (|t#1| (|Mapping| |t#1| |t#1| |t#1|) |$| |t#1| |t#1|)) (AND (|has| |t#1| (|SetCategory|)) (|has| |$| (ATTRIBUTE |finiteAggregate|)))) ((|remove| (|$| |t#1| |$|)) (AND (|has| |t#1| (|SetCategory|)) (|has| |$| (ATTRIBUTE |finiteAggregate|)))) ((|removeDuplicates| (|$| |$|)) (AND (|has| |t#1| (|SetCategory|)) (|has| |$| (ATTRIBUTE |finiteAggregate|)))))) (QUOTE (((|ConvertibleTo| (|InputForm|)) (|has| |t#1| (|ConvertibleTo| (|InputForm|)))))) (QUOTE ((|List| |t#1|))) NIL)) . #2=(|Collection|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |Collection|) (|devaluate| |t#1|)))))))
+@
+\section{CLAGG-.lsp BOOTSTRAP}
+{\bf CLAGG-} depends on {\bf CLAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf CLAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf CLAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<CLAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |CLAGG-;#;ANni;1| (|c| |$|) (LENGTH (SPADCALL |c| (QREFELT |$| 9))))
+
+(DEFUN |CLAGG-;count;MANni;2| (|f| |c| |$|) (PROG (|x| #1=#:G82637 #2=#:G82634 #3=#:G82632 #4=#:G82633) (RETURN (SEQ (PROGN (LETT #4# NIL |CLAGG-;count;MANni;2|) (SEQ (LETT |x| NIL |CLAGG-;count;MANni;2|) (LETT #1# (SPADCALL |c| (QREFELT |$| 9)) |CLAGG-;count;MANni;2|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |CLAGG-;count;MANni;2|) NIL)) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |x| |f|) (PROGN (LETT #2# 1 |CLAGG-;count;MANni;2|) (COND (#4# (LETT #3# (|+| #3# #2#) |CLAGG-;count;MANni;2|)) ((QUOTE T) (PROGN (LETT #3# #2# |CLAGG-;count;MANni;2|) (LETT #4# (QUOTE T) |CLAGG-;count;MANni;2|))))))))) (LETT #1# (CDR #1#) |CLAGG-;count;MANni;2|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) 0)))))))
+
+(DEFUN |CLAGG-;any?;MAB;3| (|f| |c| |$|) (PROG (|x| #1=#:G82642 #2=#:G82640 #3=#:G82638 #4=#:G82639) (RETURN (SEQ (PROGN (LETT #4# NIL |CLAGG-;any?;MAB;3|) (SEQ (LETT |x| NIL |CLAGG-;any?;MAB;3|) (LETT #1# (SPADCALL |c| (QREFELT |$| 9)) |CLAGG-;any?;MAB;3|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |CLAGG-;any?;MAB;3|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |CLAGG-;any?;MAB;3|) (COND (#4# (LETT #3# (COND (#3# (QUOTE T)) ((QUOTE T) #2#)) |CLAGG-;any?;MAB;3|)) ((QUOTE T) (PROGN (LETT #3# #2# |CLAGG-;any?;MAB;3|) (LETT #4# (QUOTE T) |CLAGG-;any?;MAB;3|))))))) (LETT #1# (CDR #1#) |CLAGG-;any?;MAB;3|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |CLAGG-;every?;MAB;4| (|f| |c| |$|) (PROG (|x| #1=#:G82647 #2=#:G82645 #3=#:G82643 #4=#:G82644) (RETURN (SEQ (PROGN (LETT #4# NIL |CLAGG-;every?;MAB;4|) (SEQ (LETT |x| NIL |CLAGG-;every?;MAB;4|) (LETT #1# (SPADCALL |c| (QREFELT |$| 9)) |CLAGG-;every?;MAB;4|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |x| (CAR #1#) |CLAGG-;every?;MAB;4|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |x| |f|) |CLAGG-;every?;MAB;4|) (COND (#4# (LETT #3# (COND (#3# #2#) ((QUOTE T) (QUOTE NIL))) |CLAGG-;every?;MAB;4|)) ((QUOTE T) (PROGN (LETT #3# #2# |CLAGG-;every?;MAB;4|) (LETT #4# (QUOTE T) |CLAGG-;every?;MAB;4|))))))) (LETT #1# (CDR #1#) |CLAGG-;every?;MAB;4|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (QUOTE T))))))))
+
+(DEFUN |CLAGG-;find;MAU;5| (|f| |c| |$|) (SPADCALL |f| (SPADCALL |c| (QREFELT |$| 9)) (QREFELT |$| 18)))
+
+(DEFUN |CLAGG-;reduce;MAS;6| (|f| |x| |$|) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 21)))
+
+(DEFUN |CLAGG-;reduce;MA2S;7| (|f| |x| |s| |$|) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) |s| (QREFELT |$| 23)))
+
+(DEFUN |CLAGG-;remove;M2A;8| (|f| |x| |$|) (SPADCALL (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 25)) (QREFELT |$| 26)))
+
+(DEFUN |CLAGG-;select;M2A;9| (|f| |x| |$|) (SPADCALL (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 28)) (QREFELT |$| 26)))
+
+(DEFUN |CLAGG-;remove;S2A;10| (|s| |x| |$|) (SPADCALL (CONS (FUNCTION |CLAGG-;remove;S2A;10!0|) (VECTOR |$| |s|)) |x| (QREFELT |$| 31)))
+
+(DEFUN |CLAGG-;remove;S2A;10!0| (|#1| |$$|) (SPADCALL |#1| (QREFELT |$$| 1) (QREFELT (QREFELT |$$| 0) 30)))
+
+(DEFUN |CLAGG-;reduce;MA3S;11| (|f| |x| |s1| |s2| |$|) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 9)) |s1| |s2| (QREFELT |$| 33)))
+
+(DEFUN |CLAGG-;removeDuplicates;2A;12| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 35)) (QREFELT |$| 26)))
+
+(DEFUN |Collection&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|Collection&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |Collection&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 37) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#2| (QUOTE (|ConvertibleTo| (|InputForm|)))) (|HasCategory| |#2| (QUOTE (|SetCategory|))) (|HasAttribute| |#1| (QUOTE |finiteAggregate|)))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 3) (PROGN (QSETREFV |$| 11 (CONS (|dispatchFunction| |CLAGG-;#;ANni;1|) |$|)) (QSETREFV |$| 13 (CONS (|dispatchFunction| |CLAGG-;count;MANni;2|) |$|)) (QSETREFV |$| 15 (CONS (|dispatchFunction| |CLAGG-;any?;MAB;3|) |$|)) (QSETREFV |$| 16 (CONS (|dispatchFunction| |CLAGG-;every?;MAB;4|) |$|)) (QSETREFV |$| 19 (CONS (|dispatchFunction| |CLAGG-;find;MAU;5|) |$|)) (QSETREFV |$| 22 (CONS (|dispatchFunction| |CLAGG-;reduce;MAS;6|) |$|)) (QSETREFV |$| 24 (CONS (|dispatchFunction| |CLAGG-;reduce;MA2S;7|) |$|)) (QSETREFV |$| 27 (CONS (|dispatchFunction| |CLAGG-;remove;M2A;8|) |$|)) (QSETREFV |$| 29 (CONS (|dispatchFunction| |CLAGG-;select;M2A;9|) |$|)) (COND ((|testBitVector| |pv$| 2) (PROGN (QSETREFV |$| 32 (CONS (|dispatchFunction| |CLAGG-;remove;S2A;10|) |$|)) (QSETREFV |$| 34 (CONS (|dispatchFunction| |CLAGG-;reduce;MA3S;11|) |$|)) (QSETREFV |$| 36 (CONS (|dispatchFunction| |CLAGG-;removeDuplicates;2A;12|) |$|)))))))) |$|))))
+
+(MAKEPROP (QUOTE |Collection&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|List| 7) (0 . |parts|) (|NonNegativeInteger|) (5 . |#|) (|Mapping| 14 7) (10 . |count|) (|Boolean|) (16 . |any?|) (22 . |every?|) (|Union| 7 (QUOTE "failed")) (28 . |find|) (34 . |find|) (|Mapping| 7 7 7) (40 . |reduce|) (46 . |reduce|) (52 . |reduce|) (59 . |reduce|) (66 . |remove|) (72 . |construct|) (77 . |remove|) (83 . |select|) (89 . |select|) (95 . |=|) (101 . |remove|) (107 . |remove|) (113 . |reduce|) (121 . |reduce|) (129 . |removeDuplicates|) (134 . |removeDuplicates|))) (QUOTE #(|select| 139 |removeDuplicates| 145 |remove| 150 |reduce| 162 |find| 183 |every?| 189 |count| 195 |any?| 201 |#| 207)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 36 (QUOTE (1 6 8 0 9 1 0 10 0 11 2 0 10 12 0 13 2 0 14 12 0 15 2 0 14 12 0 16 2 8 17 12 0 18 2 0 17 12 0 19 2 8 7 20 0 21 2 0 7 20 0 22 3 8 7 20 0 7 23 3 0 7 20 0 7 24 2 8 0 12 0 25 1 6 0 8 26 2 0 0 12 0 27 2 8 0 12 0 28 2 0 0 12 0 29 2 7 14 0 0 30 2 6 0 12 0 31 2 0 0 7 0 32 4 8 7 20 0 7 7 33 4 0 7 20 0 7 7 34 1 8 0 0 35 1 0 0 0 36 2 0 0 12 0 29 1 0 0 0 36 2 0 0 7 0 32 2 0 0 12 0 27 4 0 7 20 0 7 7 34 3 0 7 20 0 7 24 2 0 7 20 0 22 2 0 17 12 0 19 2 0 14 12 0 16 2 0 10 12 0 13 2 0 14 12 0 15 1 0 10 0 11)))))) (QUOTE |lookupComplete|)))
+@
+\section{category BGAGG BagAggregate}
+<<category BGAGG BagAggregate>>=
+)abbrev category BGAGG BagAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A bag aggregate is an aggregate for which one can insert and extract objects,
+++ and where the order in which objects are inserted determines the order
+++ of extraction.
+++ Examples of bags are stacks, queues, and dequeues.
+BagAggregate(S:Type): Category == HomogeneousAggregate S with
+ shallowlyMutable
+ ++ shallowlyMutable means that elements of bags may be destructively changed.
+ bag: List S -> %
+ ++ bag([x,y,...,z]) creates a bag with elements x,y,...,z.
+ extract_!: % -> S
+ ++ extract!(u) destructively removes a (random) item from bag u.
+ insert_!: (S,%) -> %
+ ++ insert!(x,u) inserts item x into bag u.
+ inspect: % -> S
+ ++ inspect(u) returns an (random) element from a bag.
+ add
+ bag(l) ==
+ x:=empty()
+ for s in l repeat x:=insert_!(s,x)
+ x
+
+@
+\section{category SKAGG StackAggregate}
+<<category SKAGG StackAggregate>>=
+)abbrev category SKAGG StackAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A stack is a bag where the last item inserted is the first item extracted.
+StackAggregate(S:Type): Category == BagAggregate S with
+ finiteAggregate
+ push_!: (S,%) -> S
+ ++ push!(x,s) pushes x onto stack s, i.e. destructively changing s
+ ++ so as to have a new first (top) element x.
+ ++ Afterwards, pop!(s) produces x and pop!(s) produces the original s.
+ pop_!: % -> S
+ ++ pop!(s) returns the top element x, destructively removing x from s.
+ ++ Note: Use \axiom{top(s)} to obtain x without removing it from s.
+ ++ Error: if s is empty.
+ top: % -> S
+ ++ top(s) returns the top element x from s; s remains unchanged.
+ ++ Note: Use \axiom{pop!(s)} to obtain x and remove it from s.
+ depth: % -> NonNegativeInteger
+ ++ depth(s) returns the number of elements of stack s.
+ ++ Note: \axiom{depth(s) = #s}.
+
+
+@
+\section{category QUAGG QueueAggregate}
+<<category QUAGG QueueAggregate>>=
+)abbrev category QUAGG QueueAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A queue is a bag where the first item inserted is the first item extracted.
+QueueAggregate(S:Type): Category == BagAggregate S with
+ finiteAggregate
+ enqueue_!: (S, %) -> S
+ ++ enqueue!(x,q) inserts x into the queue q at the back end.
+ dequeue_!: % -> S
+ ++ dequeue! s destructively extracts the first (top) element from queue q.
+ ++ The element previously second in the queue becomes the first element.
+ ++ Error: if q is empty.
+ rotate_!: % -> %
+ ++ rotate! q rotates queue q so that the element at the front of
+ ++ the queue goes to the back of the queue.
+ ++ Note: rotate! q is equivalent to enqueue!(dequeue!(q)).
+ length: % -> NonNegativeInteger
+ ++ length(q) returns the number of elements in the queue.
+ ++ Note: \axiom{length(q) = #q}.
+ front: % -> S
+ ++ front(q) returns the element at the front of the queue.
+ ++ The queue q is unchanged by this operation.
+ ++ Error: if q is empty.
+ back: % -> S
+ ++ back(q) returns the element at the back of the queue.
+ ++ The queue q is unchanged by this operation.
+ ++ Error: if q is empty.
+
+@
+\section{category DQAGG DequeueAggregate}
+<<category DQAGG DequeueAggregate>>=
+)abbrev category DQAGG DequeueAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A dequeue is a doubly ended stack, that is, a bag where first items
+++ inserted are the first items extracted, at either the front or the back end
+++ of the data structure.
+DequeueAggregate(S:Type):
+ Category == Join(StackAggregate S,QueueAggregate S) with
+ dequeue: () -> %
+ ++ dequeue()$D creates an empty dequeue of type D.
+ dequeue: List S -> %
+ ++ dequeue([x,y,...,z]) creates a dequeue with first (top or front)
+ ++ element x, second element y,...,and last (bottom or back) element z.
+ height: % -> NonNegativeInteger
+ ++ height(d) returns the number of elements in dequeue d.
+ ++ Note: \axiom{height(d) = # d}.
+ top_!: % -> S
+ ++ top!(d) returns the element at the top (front) of the dequeue.
+ bottom_!: % -> S
+ ++ bottom!(d) returns the element at the bottom (back) of the dequeue.
+ insertTop_!: (S,%) -> S
+ ++ insertTop!(x,d) destructively inserts x into the dequeue d, that is,
+ ++ at the top (front) of the dequeue.
+ ++ The element previously at the top of the dequeue becomes the
+ ++ second in the dequeue, and so on.
+ insertBottom_!: (S,%) -> S
+ ++ insertBottom!(x,d) destructively inserts x into the dequeue d
+ ++ at the bottom (back) of the dequeue.
+ extractTop_!: % -> S
+ ++ extractTop!(d) destructively extracts the top (front) element
+ ++ from the dequeue d.
+ ++ Error: if d is empty.
+ extractBottom_!: % -> S
+ ++ extractBottom!(d) destructively extracts the bottom (back) element
+ ++ from the dequeue d.
+ ++ Error: if d is empty.
+ reverse_!: % -> %
+ ++ reverse!(d) destructively replaces d by its reverse dequeue, i.e.
+ ++ the top (front) element is now the bottom (back) element, and so on.
+
+@
+\section{category PRQAGG PriorityQueueAggregate}
+<<category PRQAGG PriorityQueueAggregate>>=
+)abbrev category PRQAGG PriorityQueueAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A priority queue is a bag of items from an ordered set where the item
+++ extracted is always the maximum element.
+PriorityQueueAggregate(S:OrderedSet): Category == BagAggregate S with
+ finiteAggregate
+ max: % -> S
+ ++ max(q) returns the maximum element of priority queue q.
+ merge: (%,%) -> %
+ ++ merge(q1,q2) returns combines priority queues q1 and q2 to return
+ ++ a single priority queue q.
+ merge_!: (%,%) -> %
+ ++ merge!(q,q1) destructively changes priority queue q to include the
+ ++ values from priority queue q1.
+
+@
+\section{category DIOPS DictionaryOperations}
+<<category DIOPS DictionaryOperations>>=
+)abbrev category DIOPS DictionaryOperations
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This category is a collection of operations common to both
+++ categories \spadtype{Dictionary} and \spadtype{MultiDictionary}
+DictionaryOperations(S:SetCategory): Category ==
+ Join(BagAggregate S, Collection(S)) with
+ dictionary: () -> %
+ ++ dictionary()$D creates an empty dictionary of type D.
+ dictionary: List S -> %
+ ++ dictionary([x,y,...,z]) creates a dictionary consisting of
+ ++ entries \axiom{x,y,...,z}.
+-- insert: (S,%) -> S ++ insert an entry
+-- member?: (S,%) -> Boolean ++ search for an entry
+-- remove_!: (S,%,NonNegativeInteger) -> %
+-- ++ remove!(x,d,n) destructively changes dictionary d by removing
+-- ++ up to n entries y such that \axiom{y = x}.
+-- remove_!: (S->Boolean,%,NonNegativeInteger) -> %
+-- ++ remove!(p,d,n) destructively changes dictionary d by removing
+-- ++ up to n entries x such that \axiom{p(x)} is true.
+ if % has finiteAggregate then
+ remove_!: (S,%) -> %
+ ++ remove!(x,d) destructively changes dictionary d by removing
+ ++ all entries y such that \axiom{y = x}.
+ remove_!: (S->Boolean,%) -> %
+ ++ remove!(p,d) destructively changes dictionary d by removeing
+ ++ all entries x such that \axiom{p(x)} is true.
+ select_!: (S->Boolean,%) -> %
+ ++ select!(p,d) destructively changes dictionary d by removing
+ ++ all entries x such that \axiom{p(x)} is not true.
+ add
+ construct l == dictionary l
+ dictionary() == empty()
+ if % has finiteAggregate then
+ copy d == dictionary parts d
+ coerce(s:%):OutputForm ==
+ prefix("dictionary"@String :: OutputForm,
+ [x::OutputForm for x in parts s])
+
+@
+\section{category DIAGG Dictionary}
+<<category DIAGG Dictionary>>=
+)abbrev category DIAGG Dictionary
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A dictionary is an aggregate in which entries can be inserted,
+++ searched for and removed. Duplicates are thrown away on insertion.
+++ This category models the usual notion of dictionary which involves
+++ large amounts of data where copying is impractical.
+++ Principal operations are thus destructive (non-copying) ones.
+Dictionary(S:SetCategory): Category ==
+ DictionaryOperations S add
+ dictionary l ==
+ d := dictionary()
+ for x in l repeat insert_!(x, d)
+ d
+
+ if % has finiteAggregate then
+ -- remove(f:S->Boolean,t:%) == remove_!(f, copy t)
+ -- select(f, t) == select_!(f, copy t)
+ select_!(f, t) == remove_!(not f #1, t)
+
+ --extract_! d ==
+ -- empty? d => error "empty dictionary"
+ -- remove_!(x := first parts d, d, 1)
+ -- x
+
+ s = t ==
+ eq?(s,t) => true
+ #s ^= #t => false
+ _and/[member?(x, t) for x in parts s]
+
+ remove_!(f:S->Boolean, t:%) ==
+ for m in parts t repeat if f m then remove_!(m, t)
+ t
+
+@
+\section{category MDAGG MultiDictionary}
+<<category MDAGG MultiDictionary>>=
+)abbrev category MDAGG MultiDictionary
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A multi-dictionary is a dictionary which may contain duplicates.
+++ As for any dictionary, its size is assumed large so that
+++ copying (non-destructive) operations are generally to be avoided.
+MultiDictionary(S:SetCategory): Category == DictionaryOperations S with
+-- count: (S,%) -> NonNegativeInteger ++ multiplicity count
+ insert_!: (S,%,NonNegativeInteger) -> %
+ ++ insert!(x,d,n) destructively inserts n copies of x into dictionary d.
+-- remove_!: (S,%,NonNegativeInteger) -> %
+-- ++ remove!(x,d,n) destructively removes (up to) n copies of x from
+-- ++ dictionary d.
+ removeDuplicates_!: % -> %
+ ++ removeDuplicates!(d) destructively removes any duplicate values
+ ++ in dictionary d.
+ duplicates: % -> List Record(entry:S,count:NonNegativeInteger)
+ ++ duplicates(d) returns a list of values which have duplicates in d
+-- ++ duplicates(d) returns a list of ++ duplicates iterator
+-- to become duplicates: % -> Iterator(D,D)
+
+@
+\section{category SETAGG SetAggregate}
+<<category SETAGG SetAggregate>>=
+)abbrev category SETAGG SetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: 14 Oct, 1993 by RSS
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A set category lists a collection of set-theoretic operations
+++ useful for both finite sets and multisets.
+++ Note however that finite sets are distinct from multisets.
+++ Although the operations defined for set categories are
+++ common to both, the relationship between the two cannot
+++ be described by inclusion or inheritance.
+SetAggregate(S:SetCategory):
+ Category == Join(SetCategory, Collection(S)) with
+ partiallyOrderedSet
+ "<" : (%, %) -> Boolean
+ ++ s < t returns true if all elements of set aggregate s are also
+ ++ elements of set aggregate t.
+ brace : () -> %
+ ++ brace()$D (otherwise written {}$D)
+ ++ creates an empty set aggregate of type D.
+ ++ This form is considered obsolete. Use \axiomFun{set} instead.
+ brace : List S -> %
+ ++ brace([x,y,...,z])
+ ++ creates a set aggregate containing items x,y,...,z.
+ ++ This form is considered obsolete. Use \axiomFun{set} instead.
+ set : () -> %
+ ++ set()$D creates an empty set aggregate of type D.
+ set : List S -> %
+ ++ set([x,y,...,z]) creates a set aggregate containing items x,y,...,z.
+ intersect: (%, %) -> %
+ ++ intersect(u,v) returns the set aggregate w consisting of
+ ++ elements common to both set aggregates u and v.
+ ++ Note: equivalent to the notation (not currently supported)
+ ++ {x for x in u | member?(x,v)}.
+ difference : (%, %) -> %
+ ++ difference(u,v) returns the set aggregate w consisting of
+ ++ elements in set aggregate u but not in set aggregate v.
+ ++ If u and v have no elements in common, \axiom{difference(u,v)}
+ ++ returns a copy of u.
+ ++ Note: equivalent to the notation (not currently supported)
+ ++ \axiom{{x for x in u | not member?(x,v)}}.
+ difference : (%, S) -> %
+ ++ difference(u,x) returns the set aggregate u with element x removed.
+ ++ If u does not contain x, a copy of u is returned.
+ ++ Note: \axiom{difference(s, x) = difference(s, {x})}.
+ symmetricDifference : (%, %) -> %
+ ++ symmetricDifference(u,v) returns the set aggregate of elements x which
+ ++ are members of set aggregate u or set aggregate v but not both.
+ ++ If u and v have no elements in common, \axiom{symmetricDifference(u,v)}
+ ++ returns a copy of u.
+ ++ Note: \axiom{symmetricDifference(u,v) = union(difference(u,v),difference(v,u))}
+ subset? : (%, %) -> Boolean
+ ++ subset?(u,v) tests if u is a subset of v.
+ ++ Note: equivalent to
+ ++ \axiom{reduce(and,{member?(x,v) for x in u},true,false)}.
+ union : (%, %) -> %
+ ++ union(u,v) returns the set aggregate of elements which are members
+ ++ of either set aggregate u or v.
+ union : (%, S) -> %
+ ++ union(u,x) returns the set aggregate u with the element x added.
+ ++ If u already contains x, \axiom{union(u,x)} returns a copy of u.
+ union : (S, %) -> %
+ ++ union(x,u) returns the set aggregate u with the element x added.
+ ++ If u already contains x, \axiom{union(x,u)} returns a copy of u.
+ add
+ symmetricDifference(x, y) == union(difference(x, y), difference(y, x))
+ union(s:%, x:S) == union(s, {x})
+ union(x:S, s:%) == union(s, {x})
+ difference(s:%, x:S) == difference(s, {x})
+
+@
+\section{SETAGG.lsp BOOTSTRAP}
+{\bf SETAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf SETAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf SETAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SETAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |SetAggregate;CAT| (QUOTE NIL))
+
+(SETQ |SetAggregate;AL| (QUOTE NIL))
+
+(DEFUN |SetAggregate| (#1=#:G83200) (LET (#2=#:G83201) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |SetAggregate;AL|)) (CDR #2#)) (T (SETQ |SetAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|SetAggregate;| #1#))) |SetAggregate;AL|)) #2#))))
+
+(DEFUN |SetAggregate;| (|t#1|) (PROG (#1=#:G83199) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|SetAggregate;CAT|) ((QUOTE T) (LETT |SetAggregate;CAT| (|Join| (|SetCategory|) (|Collection| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|<| ((|Boolean|) |$| |$|)) T) ((|brace| (|$|)) T) ((|brace| (|$| (|List| |t#1|))) T) ((|set| (|$|)) T) ((|set| (|$| (|List| |t#1|))) T) ((|intersect| (|$| |$| |$|)) T) ((|difference| (|$| |$| |$|)) T) ((|difference| (|$| |$| |t#1|)) T) ((|symmetricDifference| (|$| |$| |$|)) T) ((|subset?| ((|Boolean|) |$| |$|)) T) ((|union| (|$| |$| |$|)) T) ((|union| (|$| |$| |t#1|)) T) ((|union| (|$| |t#1| |$|)) T))) (QUOTE ((|partiallyOrderedSet| T))) (QUOTE ((|Boolean|) (|List| |t#1|))) NIL)) . #2=(|SetAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |SetAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{SETAGG-.lsp BOOTSTRAP}
+{\bf SETAGG-} depends on {\bf SETAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf SETAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf SETAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SETAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |SETAGG-;symmetricDifference;3A;1| (|x| |y| |$|) (SPADCALL (SPADCALL |x| |y| (QREFELT |$| 8)) (SPADCALL |y| |x| (QREFELT |$| 8)) (QREFELT |$| 9)))
+
+(DEFUN |SETAGG-;union;ASA;2| (|s| |x| |$|) (SPADCALL |s| (SPADCALL (LIST |x|) (QREFELT |$| 12)) (QREFELT |$| 9)))
+
+(DEFUN |SETAGG-;union;S2A;3| (|x| |s| |$|) (SPADCALL |s| (SPADCALL (LIST |x|) (QREFELT |$| 12)) (QREFELT |$| 9)))
+
+(DEFUN |SETAGG-;difference;ASA;4| (|s| |x| |$|) (SPADCALL |s| (SPADCALL (LIST |x|) (QREFELT |$| 12)) (QREFELT |$| 8)))
+
+(DEFUN |SetAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|SetAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |SetAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 16) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) |$|))))
+
+(MAKEPROP (QUOTE |SetAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |difference|) (6 . |union|) |SETAGG-;symmetricDifference;3A;1| (|List| 7) (12 . |brace|) |SETAGG-;union;ASA;2| |SETAGG-;union;S2A;3| |SETAGG-;difference;ASA;4|)) (QUOTE #(|union| 17 |symmetricDifference| 29 |difference| 35)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 15 (QUOTE (2 6 0 0 0 8 2 6 0 0 0 9 1 6 0 11 12 2 0 0 7 0 14 2 0 0 0 7 13 2 0 0 0 0 10 2 0 0 0 7 15)))))) (QUOTE |lookupComplete|)))
+@
+\section{category FSAGG FiniteSetAggregate}
+<<category FSAGG FiniteSetAggregate>>=
+)abbrev category FSAGG FiniteSetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: 14 Oct, 1993 by RSS
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A finite-set aggregate models the notion of a finite set, that is,
+++ a collection of elements characterized by membership, but not
+++ by order or multiplicity.
+++ See \spadtype{Set} for an example.
+FiniteSetAggregate(S:SetCategory): Category ==
+ Join(Dictionary S, SetAggregate S) with
+ finiteAggregate
+ cardinality: % -> NonNegativeInteger
+ ++ cardinality(u) returns the number of elements of u.
+ ++ Note: \axiom{cardinality(u) = #u}.
+ if S has Finite then
+ Finite
+ complement: % -> %
+ ++ complement(u) returns the complement of the set u,
+ ++ i.e. the set of all values not in u.
+ universe: () -> %
+ ++ universe()$D returns the universal set for finite set aggregate D.
+ if S has OrderedSet then
+ max: % -> S
+ ++ max(u) returns the largest element of aggregate u.
+ min: % -> S
+ ++ min(u) returns the smallest element of aggregate u.
+
+ add
+ s < t == #s < #t and s = intersect(s,t)
+ s = t == #s = #t and empty? difference(s,t)
+ brace l == construct l
+ set l == construct l
+ cardinality s == #s
+ construct l == (s := set(); for x in l repeat insert_!(x,s); s)
+ count(x:S, s:%) == (member?(x, s) => 1; 0)
+ subset?(s, t) == #s < #t and _and/[member?(x, t) for x in parts s]
+
+ coerce(s:%):OutputForm ==
+ brace [x::OutputForm for x in parts s]$List(OutputForm)
+
+ intersect(s, t) ==
+ i := {}
+ for x in parts s | member?(x, t) repeat insert_!(x, i)
+ i
+
+ difference(s:%, t:%) ==
+ m := copy s
+ for x in parts t repeat remove_!(x, m)
+ m
+
+ symmetricDifference(s, t) ==
+ d := copy s
+ for x in parts t repeat
+ if member?(x, s) then remove_!(x, d) else insert_!(x, d)
+ d
+
+ union(s:%, t:%) ==
+ u := copy s
+ for x in parts t repeat insert_!(x, u)
+ u
+
+ if S has Finite then
+ universe() == {index(i::PositiveInteger) for i in 1..size()$S}
+ complement s == difference(universe(), s )
+ size() == 2 ** size()$S
+ index i == {index(j::PositiveInteger)$S for j in 1..size()$S | bit?(i-1,j-1)}
+ random() == index((random()$Integer rem (size()$% + 1))::PositiveInteger)
+
+ lookup s ==
+ n:PositiveInteger := 1
+ for x in parts s repeat n := n + 2 ** ((lookup(x) - 1)::NonNegativeInteger)
+ n
+
+ if S has OrderedSet then
+ max s ==
+ empty?(l := parts s) => error "Empty set"
+ reduce("max", l)
+
+ min s ==
+ empty?(l := parts s) => error "Empty set"
+ reduce("min", l)
+
+@
+\section{category MSETAGG MultisetAggregate}
+<<category MSETAGG MultisetAggregate>>=
+)abbrev category MSETAGG MultisetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A multi-set aggregate is a set which keeps track of the multiplicity
+++ of its elements.
+MultisetAggregate(S:SetCategory):
+ Category == Join(MultiDictionary S, SetAggregate S)
+
+@
+\section{category OMSAGG OrderedMultisetAggregate}
+<<category OMSAGG OrderedMultisetAggregate>>=
+)abbrev category OMSAGG OrderedMultisetAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An ordered-multiset aggregate is a multiset built over an ordered set S
+++ so that the relative sizes of its entries can be assessed.
+++ These aggregates serve as models for priority queues.
+OrderedMultisetAggregate(S:OrderedSet): Category ==
+ Join(MultisetAggregate S,PriorityQueueAggregate S) with
+ -- max: % -> S ++ smallest entry in the set
+ -- duplicates: % -> List Record(entry:S,count:NonNegativeInteger)
+ ++ to become an in order iterator
+ -- parts: % -> List S ++ in order iterator
+ min: % -> S
+ ++ min(u) returns the smallest entry in the multiset aggregate u.
+
+@
+\section{category KDAGG KeyedDictionary}
+<<category KDAGG KeyedDictionary>>=
+)abbrev category KDAGG KeyedDictionary
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A keyed dictionary is a dictionary of key-entry pairs for which there is
+++ a unique entry for each key.
+KeyedDictionary(Key:SetCategory, Entry:SetCategory): Category ==
+ Dictionary Record(key:Key,entry:Entry) with
+ key?: (Key, %) -> Boolean
+ ++ key?(k,t) tests if k is a key in table t.
+ keys: % -> List Key
+ ++ keys(t) returns the list the keys in table t.
+ -- to become keys: % -> Key* and keys: % -> Iterator(Entry,Entry)
+ remove_!: (Key, %) -> Union(Entry,"failed")
+ ++ remove!(k,t) searches the table t for the key k removing
+ ++ (and return) the entry if there.
+ ++ If t has no such key, \axiom{remove!(k,t)} returns "failed".
+ search: (Key, %) -> Union(Entry,"failed")
+ ++ search(k,t) searches the table t for the key k,
+ ++ returning the entry stored in t for key k.
+ ++ If t has no such key, \axiom{search(k,t)} returns "failed".
+ add
+ key?(k, t) == search(k, t) case Entry
+
+ member?(p, t) ==
+ r := search(p.key, t)
+ r case Entry and r::Entry = p.entry
+
+ if % has finiteAggregate then
+ keys t == [x.key for x in parts t]
+
+@
+\section{category ELTAB Eltable}
+<<category ELTAB Eltable>>=
+)abbrev category ELTAB Eltable
+++ Author: Michael Monagan; revised by Manuel Bronstein and Manuel Bronstein
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An eltable over domains D and I is a structure which can be viewed
+++ as a function from D to I.
+++ Examples of eltable structures range from data structures, e.g. those
+++ of type \spadtype{List}, to algebraic structures, e.g. \spadtype{Polynomial}.
+Eltable(S:SetCategory, Index:Type): Category == with
+ elt : (%, S) -> Index
+ ++ elt(u,i) (also written: u . i) returns the element of u indexed by i.
+ ++ Error: if i is not an index of u.
+
+@
+\section{category ELTAGG EltableAggregate}
+<<category ELTAGG EltableAggregate>>=
+)abbrev category ELTAGG EltableAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An eltable aggregate is one which can be viewed as a function.
+++ For example, the list \axiom{[1,7,4]} can applied to 0,1, and 2 respectively
+++ will return the integers 1,7, and 4; thus this list may be viewed
+++ as mapping 0 to 1, 1 to 7 and 2 to 4. In general, an aggregate
+++ can map members of a domain {\em Dom} to an image domain {\em Im}.
+EltableAggregate(Dom:SetCategory, Im:Type): Category ==
+-- This is separated from Eltable
+-- and series won't have to support qelt's and setelt's.
+ Eltable(Dom, Im) with
+ elt : (%, Dom, Im) -> Im
+ ++ elt(u, x, y) applies u to x if x is in the domain of u,
+ ++ and returns y otherwise.
+ ++ For example, if u is a polynomial in \axiom{x} over the rationals,
+ ++ \axiom{elt(u,n,0)} may define the coefficient of \axiom{x}
+ ++ to the power n, returning 0 when n is out of range.
+ qelt: (%, Dom) -> Im
+ ++ qelt(u, x) applies \axiom{u} to \axiom{x} without checking whether
+ ++ \axiom{x} is in the domain of \axiom{u}. If \axiom{x} is not in the
+ ++ domain of \axiom{u} a memory-access violation may occur. If a check
+ ++ on whether \axiom{x} is in the domain of \axiom{u} is required, use
+ ++ the function \axiom{elt}.
+ if % has shallowlyMutable then
+ setelt : (%, Dom, Im) -> Im
+ ++ setelt(u,x,y) sets the image of x to be y under u,
+ ++ assuming x is in the domain of u.
+ ++ Error: if x is not in the domain of u.
+ -- this function will soon be renamed as setelt!.
+ qsetelt_!: (%, Dom, Im) -> Im
+ ++ qsetelt!(u,x,y) sets the image of \axiom{x} to be \axiom{y} under
+ ++ \axiom{u}, without checking that \axiom{x} is in the domain of
+ ++ \axiom{u}.
+ ++ If such a check is required use the function \axiom{setelt}.
+ add
+ qelt(a, x) == elt(a, x)
+ if % has shallowlyMutable then
+ qsetelt_!(a, x, y) == (a.x := y)
+
+@
+\section{category IXAGG IndexedAggregate}
+<<category IXAGG IndexedAggregate>>=
+)abbrev category IXAGG IndexedAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An indexed aggregate is a many-to-one mapping of indices to entries.
+++ For example, a one-dimensional-array is an indexed aggregate where
+++ the index is an integer. Also, a table is an indexed aggregate
+++ where the indices and entries may have any type.
+IndexedAggregate(Index: SetCategory, Entry: Type): Category ==
+ Join(HomogeneousAggregate(Entry), EltableAggregate(Index, Entry)) with
+ entries: % -> List Entry
+ ++ entries(u) returns a list of all the entries of aggregate u
+ ++ in no assumed order.
+ -- to become entries: % -> Entry* and entries: % -> Iterator(Entry,Entry)
+ index?: (Index,%) -> Boolean
+ ++ index?(i,u) tests if i is an index of aggregate u.
+ indices: % -> List Index
+ ++ indices(u) returns a list of indices of aggregate u in no
+ ++ particular order.
+ -- to become indices: % -> Index* and indices: % -> Iterator(Index,Index).
+-- map: ((Entry,Entry)->Entry,%,%,Entry) -> %
+-- ++ exists c = map(f,a,b,x), i:Index where
+-- ++ c.i = f(a(i,x),b(i,x)) | index?(i,a) or index?(i,b)
+ if Entry has SetCategory and % has finiteAggregate then
+ entry?: (Entry,%) -> Boolean
+ ++ entry?(x,u) tests if x equals \axiom{u . i} for some index i.
+ if Index has OrderedSet then
+ maxIndex: % -> Index
+ ++ maxIndex(u) returns the maximum index i of aggregate u.
+ ++ Note: in general,
+ ++ \axiom{maxIndex(u) = reduce(max,[i for i in indices u])};
+ ++ if u is a list, \axiom{maxIndex(u) = #u}.
+ minIndex: % -> Index
+ ++ minIndex(u) returns the minimum index i of aggregate u.
+ ++ Note: in general,
+ ++ \axiom{minIndex(a) = reduce(min,[i for i in indices a])};
+ ++ for lists, \axiom{minIndex(a) = 1}.
+ first : % -> Entry
+ ++ first(u) returns the first element x of u.
+ ++ Note: for collections, \axiom{first([x,y,...,z]) = x}.
+ ++ Error: if u is empty.
+
+ if % has shallowlyMutable then
+ fill_!: (%,Entry) -> %
+ ++ fill!(u,x) replaces each entry in aggregate u by x.
+ ++ The modified u is returned as value.
+ swap_!: (%,Index,Index) -> Void
+ ++ swap!(u,i,j) interchanges elements i and j of aggregate u.
+ ++ No meaningful value is returned.
+ add
+ elt(a, i, x) == (index?(i, a) => qelt(a, i); x)
+
+ if % has finiteAggregate then
+ entries x == parts x
+ if Entry has SetCategory then
+ entry?(x, a) == member?(x, a)
+
+ if Index has OrderedSet then
+ maxIndex a == "max"/indices(a)
+ minIndex a == "min"/indices(a)
+ first a == a minIndex a
+
+ if % has shallowlyMutable then
+ map(f, a) == map_!(f, copy a)
+
+ map_!(f, a) ==
+ for i in indices a repeat qsetelt_!(a, i, f qelt(a, i))
+ a
+
+ fill_!(a, x) ==
+ for i in indices a repeat qsetelt_!(a, i, x)
+ a
+
+ swap_!(a, i, j) ==
+ t := a.i
+ qsetelt_!(a, i, a.j)
+ qsetelt_!(a, j, t)
+ void
+
+@
+\section{category TBAGG TableAggregate}
+<<category TBAGG TableAggregate>>=
+)abbrev category TBAGG TableAggregate
+++ Author: Michael Monagan, Stephen Watt; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A table aggregate is a model of a table, i.e. a discrete many-to-one
+++ mapping from keys to entries.
+TableAggregate(Key:SetCategory, Entry:SetCategory): Category ==
+ Join(KeyedDictionary(Key,Entry),IndexedAggregate(Key,Entry)) with
+ setelt: (%,Key,Entry) -> Entry -- setelt_! later
+ ++ setelt(t,k,e) (also written \axiom{t.k := e}) is equivalent
+ ++ to \axiom{(insert([k,e],t); e)}.
+ table: () -> %
+ ++ table()$T creates an empty table of type T.
+ table: List Record(key:Key,entry:Entry) -> %
+ ++ table([x,y,...,z]) creates a table consisting of entries
+ ++ \axiom{x,y,...,z}.
+ -- to become table: Record(key:Key,entry:Entry)* -> %
+ map: ((Entry, Entry) -> Entry, %, %) -> %
+ ++ map(fn,t1,t2) creates a new table t from given tables t1 and t2 with
+ ++ elements fn(x,y) where x and y are corresponding elements from t1
+ ++ and t2 respectively.
+ add
+ table() == empty()
+ table l == dictionary l
+-- empty() == dictionary()
+
+ insert_!(p, t) == (t(p.key) := p.entry; t)
+ indices t == keys t
+
+ coerce(t:%):OutputForm ==
+ prefix("table"::OutputForm,
+ [k::OutputForm = (t.k)::OutputForm for k in keys t])
+
+ elt(t, k) ==
+ (r := search(k, t)) case Entry => r::Entry
+ error "key not in table"
+
+ elt(t, k, e) ==
+ (r := search(k, t)) case Entry => r::Entry
+ e
+
+ map_!(f, t) ==
+ for k in keys t repeat t.k := f t.k
+ t
+
+ map(f:(Entry, Entry) -> Entry, s:%, t:%) ==
+ z := table()
+ for k in keys s | key?(k, t) repeat z.k := f(s.k, t.k)
+ z
+
+-- map(f, s, t, x) ==
+-- z := table()
+-- for k in keys s repeat z.k := f(s.k, t(k, x))
+-- for k in keys t | not key?(k, s) repeat z.k := f(t.k, x)
+-- z
+
+ if % has finiteAggregate then
+ parts(t:%):List Record(key:Key,entry:Entry) == [[k, t.k] for k in keys t]
+ parts(t:%):List Entry == [t.k for k in keys t]
+ entries(t:%):List Entry == parts(t)
+
+ s:% = t:% ==
+ eq?(s,t) => true
+ #s ^= #t => false
+ for k in keys s repeat
+ (e := search(k, t)) case "failed" or (e::Entry) ^= s.k => false
+ true
+
+ map(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry), t: %): % ==
+ z := table()
+ for k in keys t repeat
+ ke: Record(key:Key,entry:Entry) := f [k, t.k]
+ z ke.key := ke.entry
+ z
+ map_!(f: Record(key:Key,entry:Entry)->Record(key:Key,entry:Entry), t: %): % ==
+ lke: List Record(key:Key,entry:Entry) := nil()
+ for k in keys t repeat
+ lke := cons(f [k, remove_!(k,t)::Entry], lke)
+ for ke in lke repeat
+ t ke.key := ke.entry
+ t
+
+ inspect(t: %): Record(key:Key,entry:Entry) ==
+ ks := keys t
+ empty? ks => error "Cannot extract from an empty aggregate"
+ [first ks, t first ks]
+
+ find(f: Record(key:Key,entry:Entry)->Boolean, t:%): Union(Record(key:Key,entry:Entry), "failed") ==
+ for ke in parts(t)@List(Record(key:Key,entry:Entry)) repeat if f ke then return ke
+ "failed"
+
+ index?(k: Key, t: %): Boolean ==
+ search(k,t) case Entry
+
+ remove_!(x:Record(key:Key,entry:Entry), t:%) ==
+ if member?(x, t) then remove_!(x.key, t)
+ t
+ extract_!(t: %): Record(key:Key,entry:Entry) ==
+ k: Record(key:Key,entry:Entry) := inspect t
+ remove_!(k.key, t)
+ k
+
+ any?(f: Entry->Boolean, t: %): Boolean ==
+ for k in keys t | f t k repeat return true
+ false
+ every?(f: Entry->Boolean, t: %): Boolean ==
+ for k in keys t | not f t k repeat return false
+ true
+ count(f: Entry->Boolean, t: %): NonNegativeInteger ==
+ tally: NonNegativeInteger := 0
+ for k in keys t | f t k repeat tally := tally + 1
+ tally
+
+@
+\section{category RCAGG RecursiveAggregate}
+<<category RCAGG RecursiveAggregate>>=
+)abbrev category RCAGG RecursiveAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A recursive aggregate over a type S is a model for a
+++ a directed graph containing values of type S.
+++ Recursively, a recursive aggregate is a {\em node}
+++ consisting of a \spadfun{value} from S and 0 or more \spadfun{children}
+++ which are recursive aggregates.
+++ A node with no children is called a \spadfun{leaf} node.
+++ A recursive aggregate may be cyclic for which some operations as noted
+++ may go into an infinite loop.
+RecursiveAggregate(S:Type): Category == HomogeneousAggregate(S) with
+ children: % -> List %
+ ++ children(u) returns a list of the children of aggregate u.
+ -- should be % -> %* and also needs children: % -> Iterator(S,S)
+ nodes: % -> List %
+ ++ nodes(u) returns a list of all of the nodes of aggregate u.
+ -- to become % -> %* and also nodes: % -> Iterator(S,S)
+ leaf?: % -> Boolean
+ ++ leaf?(u) tests if u is a terminal node.
+ value: % -> S
+ ++ value(u) returns the value of the node u.
+ elt: (%,"value") -> S
+ ++ elt(u,"value") (also written: \axiom{a. value}) is
+ ++ equivalent to \axiom{value(a)}.
+ cyclic?: % -> Boolean
+ ++ cyclic?(u) tests if u has a cycle.
+ leaves: % -> List S
+ ++ leaves(t) returns the list of values in obtained by visiting the
+ ++ nodes of tree \axiom{t} in left-to-right order.
+ distance: (%,%) -> Integer
+ ++ distance(u,v) returns the path length (an integer) from node u to v.
+ if S has SetCategory then
+ child?: (%,%) -> Boolean
+ ++ child?(u,v) tests if node u is a child of node v.
+ node?: (%,%) -> Boolean
+ ++ node?(u,v) tests if node u is contained in node v
+ ++ (either as a child, a child of a child, etc.).
+ if % has shallowlyMutable then
+ setchildren_!: (%,List %)->%
+ ++ setchildren!(u,v) replaces the current children of node u
+ ++ with the members of v in left-to-right order.
+ setelt: (%,"value",S) -> S
+ ++ setelt(a,"value",x) (also written \axiom{a . value := x})
+ ++ is equivalent to \axiom{setvalue!(a,x)}
+ setvalue_!: (%,S) -> S
+ ++ setvalue!(u,x) sets the value of node u to x.
+ add
+ elt(x,"value") == value x
+ if % has shallowlyMutable then
+ setelt(x,"value",y) == setvalue_!(x,y)
+ if S has SetCategory then
+ child?(x,l) == member?(x,children(l))
+
+@
+\section{RCAGG.lsp BOOTSTRAP}
+{\bf RCAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf RCAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf RCAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RCAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |RecursiveAggregate;CAT| (QUOTE NIL))
+
+(SETQ |RecursiveAggregate;AL| (QUOTE NIL))
+
+(DEFUN |RecursiveAggregate| (#1=#:G84501) (LET (#2=#:G84502) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |RecursiveAggregate;AL|)) (CDR #2#)) (T (SETQ |RecursiveAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|RecursiveAggregate;| #1#))) |RecursiveAggregate;AL|)) #2#))))
+
+(DEFUN |RecursiveAggregate;| (|t#1|) (PROG (#1=#:G84500) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|RecursiveAggregate;CAT|) ((QUOTE T) (LETT |RecursiveAggregate;CAT| (|Join| (|HomogeneousAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|children| ((|List| |$|) |$|)) T) ((|nodes| ((|List| |$|) |$|)) T) ((|leaf?| ((|Boolean|) |$|)) T) ((|value| (|t#1| |$|)) T) ((|elt| (|t#1| |$| "value")) T) ((|cyclic?| ((|Boolean|) |$|)) T) ((|leaves| ((|List| |t#1|) |$|)) T) ((|distance| ((|Integer|) |$| |$|)) T) ((|child?| ((|Boolean|) |$| |$|)) (|has| |t#1| (|SetCategory|))) ((|node?| ((|Boolean|) |$| |$|)) (|has| |t#1| (|SetCategory|))) ((|setchildren!| (|$| |$| (|List| |$|))) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|t#1| |$| "value" |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setvalue!| (|t#1| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))))) NIL (QUOTE ((|List| |$|) (|Boolean|) (|Integer|) (|List| |t#1|))) NIL)) . #2=(|RecursiveAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |RecursiveAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{RCAGG-.lsp BOOTSTRAP}
+{\bf RCAGG-} depends on {\bf RCAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf RCAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf RCAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RCAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |RCAGG-;elt;AvalueS;1| (|x| G84515 |$|) (SPADCALL |x| (QREFELT |$| 8)))
+
+(DEFUN |RCAGG-;setelt;Avalue2S;2| (|x| G84517 |y| |$|) (SPADCALL |x| |y| (QREFELT |$| 11)))
+
+(DEFUN |RCAGG-;child?;2AB;3| (|x| |l| |$|) (SPADCALL |x| (SPADCALL |l| (QREFELT |$| 14)) (QREFELT |$| 17)))
+
+(DEFUN |RecursiveAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|RecursiveAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |RecursiveAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 19) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)) (|HasCategory| |#2| (QUOTE (|SetCategory|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 1) (QSETREFV |$| 12 (CONS (|dispatchFunction| |RCAGG-;setelt;Avalue2S;2|) |$|)))) (COND ((|testBitVector| |pv$| 2) (QSETREFV |$| 18 (CONS (|dispatchFunction| |RCAGG-;child?;2AB;3|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |RecursiveAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |value|) (QUOTE "value") |RCAGG-;elt;AvalueS;1| (5 . |setvalue!|) (11 . |setelt|) (|List| |$|) (18 . |children|) (|Boolean|) (|List| 6) (23 . |member?|) (29 . |child?|))) (QUOTE #(|setelt| 35 |elt| 42 |child?| 48)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 18 (QUOTE (1 6 7 0 8 2 6 7 0 7 11 3 0 7 0 9 7 12 1 6 13 0 14 2 16 15 6 0 17 2 0 15 0 0 18 3 0 7 0 9 7 12 2 0 7 0 9 10 2 0 15 0 0 18)))))) (QUOTE |lookupComplete|)))
+@
+\section{category BRAGG BinaryRecursiveAggregate}
+<<category BRAGG BinaryRecursiveAggregate>>=
+)abbrev category BRAGG BinaryRecursiveAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A binary-recursive aggregate has 0, 1 or 2 children and
+++ serves as a model for a binary tree or a doubly-linked aggregate structure
+BinaryRecursiveAggregate(S:Type):Category == RecursiveAggregate S with
+ -- needs preorder, inorder and postorder iterators
+ left: % -> %
+ ++ left(u) returns the left child.
+ elt: (%,"left") -> %
+ ++ elt(u,"left") (also written: \axiom{a . left}) is
+ ++ equivalent to \axiom{left(a)}.
+ right: % -> %
+ ++ right(a) returns the right child.
+ elt: (%,"right") -> %
+ ++ elt(a,"right") (also written: \axiom{a . right})
+ ++ is equivalent to \axiom{right(a)}.
+ if % has shallowlyMutable then
+ setelt: (%,"left",%) -> %
+ ++ setelt(a,"left",b) (also written \axiom{a . left := b}) is equivalent
+ ++ to \axiom{setleft!(a,b)}.
+ setleft_!: (%,%) -> %
+ ++ setleft!(a,b) sets the left child of \axiom{a} to be b.
+ setelt: (%,"right",%) -> %
+ ++ setelt(a,"right",b) (also written \axiom{b . right := b})
+ ++ is equivalent to \axiom{setright!(a,b)}.
+ setright_!: (%,%) -> %
+ ++ setright!(a,x) sets the right child of t to be x.
+ add
+ cycleMax ==> 1000
+
+ elt(x,"left") == left x
+ elt(x,"right") == right x
+ leaf? x == empty? x or empty? left x and empty? right x
+ leaves t ==
+ empty? t => empty()$List(S)
+ leaf? t => [value t]
+ concat(leaves left t,leaves right t)
+ nodes x ==
+ l := empty()$List(%)
+ empty? x => l
+ concat(nodes left x,concat([x],nodes right x))
+ children x ==
+ l := empty()$List(%)
+ empty? x => l
+ empty? left x => [right x]
+ empty? right x => [left x]
+ [left x, right x]
+ if % has SetAggregate(S) and S has SetCategory then
+ node?(u,v) ==
+ empty? v => false
+ u = v => true
+ for y in children v repeat node?(u,y) => return true
+ false
+ x = y ==
+ empty?(x) => empty?(y)
+ empty?(y) => false
+ value x = value y and left x = left y and right x = right y
+ if % has finiteAggregate then
+ member?(x,u) ==
+ empty? u => false
+ x = value u => true
+ member?(x,left u) or member?(x,right u)
+
+ if S has SetCategory then
+ coerce(t:%): OutputForm ==
+ empty? t => "[]"::OutputForm
+ v := value(t):: OutputForm
+ empty? left t =>
+ empty? right t => v
+ r := coerce(right t)@OutputForm
+ bracket ["."::OutputForm, v, r]
+ l := coerce(left t)@OutputForm
+ r :=
+ empty? right t => "."::OutputForm
+ coerce(right t)@OutputForm
+ bracket [l, v, r]
+
+ if % has finiteAggregate then
+ aggCount: (%,NonNegativeInteger) -> NonNegativeInteger
+ #x == aggCount(x,0)
+ aggCount(x,k) ==
+ empty? x => 0
+ k := k + 1
+ k = cycleMax and cyclic? x => error "cyclic tree"
+ for y in children x repeat k := aggCount(y,k)
+ k
+
+ isCycle?: (%, List %) -> Boolean
+ eqMember?: (%, List %) -> Boolean
+ cyclic? x == not empty? x and isCycle?(x,empty()$(List %))
+ isCycle?(x,acc) ==
+ empty? x => false
+ eqMember?(x,acc) => true
+ for y in children x | not empty? y repeat
+ isCycle?(y,acc) => return true
+ false
+ eqMember?(y,l) ==
+ for x in l repeat eq?(x,y) => return true
+ false
+ if % has shallowlyMutable then
+ setelt(x,"left",b) == setleft_!(x,b)
+ setelt(x,"right",b) == setright_!(x,b)
+
+@
+\section{category DLAGG DoublyLinkedAggregate}
+<<category DLAGG DoublyLinkedAggregate>>=
+)abbrev category DLAGG DoublyLinkedAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A doubly-linked aggregate serves as a model for a doubly-linked
+++ list, that is, a list which can has links to both next and previous
+++ nodes and thus can be efficiently traversed in both directions.
+DoublyLinkedAggregate(S:Type): Category == RecursiveAggregate S with
+ last: % -> S
+ ++ last(l) returns the last element of a doubly-linked aggregate l.
+ ++ Error: if l is empty.
+ head: % -> %
+ ++ head(l) returns the first element of a doubly-linked aggregate l.
+ ++ Error: if l is empty.
+ tail: % -> %
+ ++ tail(l) returns the doubly-linked aggregate l starting at
+ ++ its second element.
+ ++ Error: if l is empty.
+ previous: % -> %
+ ++ previous(l) returns the doubly-link list beginning with its previous
+ ++ element.
+ ++ Error: if l has no previous element.
+ ++ Note: \axiom{next(previous(l)) = l}.
+ next: % -> %
+ ++ next(l) returns the doubly-linked aggregate beginning with its next
+ ++ element.
+ ++ Error: if l has no next element.
+ ++ Note: \axiom{next(l) = rest(l)} and \axiom{previous(next(l)) = l}.
+ if % has shallowlyMutable then
+ concat_!: (%,%) -> %
+ ++ concat!(u,v) destructively concatenates doubly-linked aggregate v to the end of doubly-linked aggregate u.
+ setprevious_!: (%,%) -> %
+ ++ setprevious!(u,v) destructively sets the previous node of doubly-linked aggregate u to v, returning v.
+ setnext_!: (%,%) -> %
+ ++ setnext!(u,v) destructively sets the next node of doubly-linked aggregate u to v, returning v.
+
+@
+\section{category URAGG UnaryRecursiveAggregate}
+<<category URAGG UnaryRecursiveAggregate>>=
+)abbrev category URAGG UnaryRecursiveAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A unary-recursive aggregate is a one where nodes may have either
+++ 0 or 1 children.
+++ This aggregate models, though not precisely, a linked
+++ list possibly with a single cycle.
+++ A node with one children models a non-empty list, with the
+++ \spadfun{value} of the list designating the head, or \spadfun{first}, of the
+++ list, and the child designating the tail, or \spadfun{rest}, of the list.
+++ A node with no child then designates the empty list.
+++ Since these aggregates are recursive aggregates, they may be cyclic.
+UnaryRecursiveAggregate(S:Type): Category == RecursiveAggregate S with
+ concat: (%,%) -> %
+ ++ concat(u,v) returns an aggregate w consisting of the elements of u
+ ++ followed by the elements of v.
+ ++ Note: \axiom{v = rest(w,#a)}.
+ concat: (S,%) -> %
+ ++ concat(x,u) returns aggregate consisting of x followed by
+ ++ the elements of u.
+ ++ Note: if \axiom{v = concat(x,u)} then \axiom{x = first v}
+ ++ and \axiom{u = rest v}.
+ first: % -> S
+ ++ first(u) returns the first element of u
+ ++ (equivalently, the value at the current node).
+ elt: (%,"first") -> S
+ ++ elt(u,"first") (also written: \axiom{u . first}) is equivalent to first u.
+ first: (%,NonNegativeInteger) -> %
+ ++ first(u,n) returns a copy of the first n (\axiom{n >= 0}) elements of u.
+ rest: % -> %
+ ++ rest(u) returns an aggregate consisting of all but the first
+ ++ element of u
+ ++ (equivalently, the next node of u).
+ elt: (%,"rest") -> %
+ ++ elt(%,"rest") (also written: \axiom{u.rest}) is
+ ++ equivalent to \axiom{rest u}.
+ rest: (%,NonNegativeInteger) -> %
+ ++ rest(u,n) returns the \axiom{n}th (n >= 0) node of u.
+ ++ Note: \axiom{rest(u,0) = u}.
+ last: % -> S
+ ++ last(u) resturn the last element of u.
+ ++ Note: for lists, \axiom{last(u) = u . (maxIndex u) = u . (# u - 1)}.
+ elt: (%,"last") -> S
+ ++ elt(u,"last") (also written: \axiom{u . last}) is equivalent to last u.
+ last: (%,NonNegativeInteger) -> %
+ ++ last(u,n) returns a copy of the last n (\axiom{n >= 0}) nodes of u.
+ ++ Note: \axiom{last(u,n)} is a list of n elements.
+ tail: % -> %
+ ++ tail(u) returns the last node of u.
+ ++ Note: if u is \axiom{shallowlyMutable},
+ ++ \axiom{setrest(tail(u),v) = concat(u,v)}.
+ second: % -> S
+ ++ second(u) returns the second element of u.
+ ++ Note: \axiom{second(u) = first(rest(u))}.
+ third: % -> S
+ ++ third(u) returns the third element of u.
+ ++ Note: \axiom{third(u) = first(rest(rest(u)))}.
+ cycleEntry: % -> %
+ ++ cycleEntry(u) returns the head of a top-level cycle contained in
+ ++ aggregate u, or \axiom{empty()} if none exists.
+ cycleLength: % -> NonNegativeInteger
+ ++ cycleLength(u) returns the length of a top-level cycle
+ ++ contained in aggregate u, or 0 is u has no such cycle.
+ cycleTail: % -> %
+ ++ cycleTail(u) returns the last node in the cycle, or
+ ++ empty if none exists.
+ if % has shallowlyMutable then
+ concat_!: (%,%) -> %
+ ++ concat!(u,v) destructively concatenates v to the end of u.
+ ++ Note: \axiom{concat!(u,v) = setlast_!(u,v)}.
+ concat_!: (%,S) -> %
+ ++ concat!(u,x) destructively adds element x to the end of u.
+ ++ Note: \axiom{concat!(a,x) = setlast!(a,[x])}.
+ cycleSplit_!: % -> %
+ ++ cycleSplit!(u) splits the aggregate by dropping off the cycle.
+ ++ The value returned is the cycle entry, or nil if none exists.
+ ++ For example, if \axiom{w = concat(u,v)} is the cyclic list where v is
+ ++ the head of the cycle, \axiom{cycleSplit!(w)} will drop v off w thus
+ ++ destructively changing w to u, and returning v.
+ setfirst_!: (%,S) -> S
+ ++ setfirst!(u,x) destructively changes the first element of a to x.
+ setelt: (%,"first",S) -> S
+ ++ setelt(u,"first",x) (also written: \axiom{u.first := x}) is
+ ++ equivalent to \axiom{setfirst!(u,x)}.
+ setrest_!: (%,%) -> %
+ ++ setrest!(u,v) destructively changes the rest of u to v.
+ setelt: (%,"rest",%) -> %
+ ++ setelt(u,"rest",v) (also written: \axiom{u.rest := v}) is equivalent to
+ ++ \axiom{setrest!(u,v)}.
+ setlast_!: (%,S) -> S
+ ++ setlast!(u,x) destructively changes the last element of u to x.
+ setelt: (%,"last",S) -> S
+ ++ setelt(u,"last",x) (also written: \axiom{u.last := b})
+ ++ is equivalent to \axiom{setlast!(u,v)}.
+ split_!: (%,Integer) -> %
+ ++ split!(u,n) splits u into two aggregates: \axiom{v = rest(u,n)}
+ ++ and \axiom{w = first(u,n)}, returning \axiom{v}.
+ ++ Note: afterwards \axiom{rest(u,n)} returns \axiom{empty()}.
+ add
+ cycleMax ==> 1000
+
+ findCycle: % -> %
+
+ elt(x, "first") == first x
+ elt(x, "last") == last x
+ elt(x, "rest") == rest x
+ second x == first rest x
+ third x == first rest rest x
+ cyclic? x == not empty? x and not empty? findCycle x
+ last x == first tail x
+
+ nodes x ==
+ l := empty()$List(%)
+ while not empty? x repeat
+ l := concat(x, l)
+ x := rest x
+ reverse_! l
+
+ children x ==
+ l := empty()$List(%)
+ empty? x => l
+ concat(rest x,l)
+
+ leaf? x == empty? x
+
+ value x ==
+ empty? x => error "value of empty object"
+ first x
+
+ less?(l, n) ==
+ i := n::Integer
+ while i > 0 and not empty? l repeat (l := rest l; i := i - 1)
+ i > 0
+
+ more?(l, n) ==
+ i := n::Integer
+ while i > 0 and not empty? l repeat (l := rest l; i := i - 1)
+ zero?(i) and not empty? l
+
+ size?(l, n) ==
+ i := n::Integer
+ while not empty? l and i > 0 repeat (l := rest l; i := i - 1)
+ empty? l and zero? i
+
+ #x ==
+ for k in 0.. while not empty? x repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ x := rest x
+ k
+
+ tail x ==
+ empty? x => error "empty list"
+ y := rest x
+ for k in 0.. while not empty? y repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ y := rest(x := y)
+ x
+
+ findCycle x ==
+ y := rest x
+ while not empty? y repeat
+ if eq?(x, y) then return x
+ x := rest x
+ y := rest y
+ if empty? y then return y
+ if eq?(x, y) then return y
+ y := rest y
+ y
+
+ cycleTail x ==
+ empty?(y := x := cycleEntry x) => x
+ z := rest x
+ while not eq?(x,z) repeat (y := z; z := rest z)
+ y
+
+ cycleEntry x ==
+ empty? x => x
+ empty?(y := findCycle x) => y
+ z := rest y
+ for l in 1.. while not eq?(y,z) repeat z := rest z
+ y := x
+ for k in 1..l repeat y := rest y
+ while not eq?(x,y) repeat (x := rest x; y := rest y)
+ x
+
+ cycleLength x ==
+ empty? x => 0
+ empty?(x := findCycle x) => 0
+ y := rest x
+ for k in 1.. while not eq?(x,y) repeat y := rest y
+ k
+
+ rest(x, n) ==
+ for i in 1..n repeat
+ empty? x => error "Index out of range"
+ x := rest x
+ x
+
+ if % has finiteAggregate then
+ last(x, n) ==
+ n > (m := #x) => error "index out of range"
+ copy rest(x, (m - n)::NonNegativeInteger)
+
+ if S has SetCategory then
+ x = y ==
+ eq?(x, y) => true
+ for k in 0.. while not empty? x and not empty? y repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ first x ^= first y => return false
+ x := rest x
+ y := rest y
+ empty? x and empty? y
+
+ node?(u, v) ==
+ for k in 0.. while not empty? v repeat
+ u = v => return true
+ k = cycleMax and cyclic? v => error "cyclic list"
+ v := rest v
+ u=v
+
+ if % has shallowlyMutable then
+ setelt(x, "first", a) == setfirst_!(x, a)
+ setelt(x, "last", a) == setlast_!(x, a)
+ setelt(x, "rest", a) == setrest_!(x, a)
+ concat(x:%, y:%) == concat_!(copy x, y)
+
+ setlast_!(x, s) ==
+ empty? x => error "setlast: empty list"
+ setfirst_!(tail x, s)
+ s
+
+ setchildren_!(u,lv) ==
+ #lv=1 => setrest_!(u, first lv)
+ error "wrong number of children specified"
+
+ setvalue_!(u,s) == setfirst_!(u,s)
+
+ split_!(p, n) ==
+ n < 1 => error "index out of range"
+ p := rest(p, (n - 1)::NonNegativeInteger)
+ q := rest p
+ setrest_!(p, empty())
+ q
+
+ cycleSplit_! x ==
+ empty?(y := cycleEntry x) or eq?(x, y) => y
+ z := rest x
+ while not eq?(z, y) repeat (x := z; z := rest z)
+ setrest_!(x, empty())
+ y
+
+@
+\section{URAGG.lsp BOOTSTRAP}
+{\bf URAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf URAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf URAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<URAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |UnaryRecursiveAggregate;CAT| (QUOTE NIL))
+
+(SETQ |UnaryRecursiveAggregate;AL| (QUOTE NIL))
+
+(DEFUN |UnaryRecursiveAggregate| (#1=#:G84596) (LET (#2=#:G84597) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |UnaryRecursiveAggregate;AL|)) (CDR #2#)) (T (SETQ |UnaryRecursiveAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|UnaryRecursiveAggregate;| #1#))) |UnaryRecursiveAggregate;AL|)) #2#))))
+
+(DEFUN |UnaryRecursiveAggregate;| (|t#1|) (PROG (#1=#:G84595) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|UnaryRecursiveAggregate;CAT|) ((QUOTE T) (LETT |UnaryRecursiveAggregate;CAT| (|Join| (|RecursiveAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|concat| (|$| |$| |$|)) T) ((|concat| (|$| |t#1| |$|)) T) ((|first| (|t#1| |$|)) T) ((|elt| (|t#1| |$| "first")) T) ((|first| (|$| |$| (|NonNegativeInteger|))) T) ((|rest| (|$| |$|)) T) ((|elt| (|$| |$| "rest")) T) ((|rest| (|$| |$| (|NonNegativeInteger|))) T) ((|last| (|t#1| |$|)) T) ((|elt| (|t#1| |$| "last")) T) ((|last| (|$| |$| (|NonNegativeInteger|))) T) ((|tail| (|$| |$|)) T) ((|second| (|t#1| |$|)) T) ((|third| (|t#1| |$|)) T) ((|cycleEntry| (|$| |$|)) T) ((|cycleLength| ((|NonNegativeInteger|) |$|)) T) ((|cycleTail| (|$| |$|)) T) ((|concat!| (|$| |$| |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|concat!| (|$| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|cycleSplit!| (|$| |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setfirst!| (|t#1| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|t#1| |$| "first" |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setrest!| (|$| |$| |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|$| |$| "rest" |$|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setlast!| (|t#1| |$| |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|setelt| (|t#1| |$| "last" |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))) ((|split!| (|$| |$| (|Integer|))) (|has| |$| (ATTRIBUTE |shallowlyMutable|))))) NIL (QUOTE ((|Integer|) (|NonNegativeInteger|))) NIL)) . #2=(|UnaryRecursiveAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |UnaryRecursiveAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{URAGG-.lsp BOOTSTRAP}
+{\bf URAGG-} depends on {\bf URAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf URAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf URAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<URAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |URAGG-;elt;AfirstS;1| (|x| G84610 |$|) (SPADCALL |x| (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;elt;AlastS;2| (|x| G84612 |$|) (SPADCALL |x| (QREFELT |$| 11)))
+
+(DEFUN |URAGG-;elt;ArestA;3| (|x| G84614 |$|) (SPADCALL |x| (QREFELT |$| 14)))
+
+(DEFUN |URAGG-;second;AS;4| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 14)) (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;third;AS;5| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 14)) (QREFELT |$| 14)) (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;cyclic?;AB;6| (|x| |$|) (COND ((OR (SPADCALL |x| (QREFELT |$| 20)) (SPADCALL (|URAGG-;findCycle| |x| |$|) (QREFELT |$| 20))) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |URAGG-;last;AS;7| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 22)) (QREFELT |$| 8)))
+
+(DEFUN |URAGG-;nodes;AL;8| (|x| |$|) (PROG (|l|) (RETURN (SEQ (LETT |l| NIL |URAGG-;nodes;AL;8|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |l| (CONS |x| |l|) |URAGG-;nodes;AL;8|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;nodes;AL;8|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (NREVERSE |l|))))))
+
+(DEFUN |URAGG-;children;AL;9| (|x| |$|) (PROG (|l|) (RETURN (SEQ (LETT |l| NIL |URAGG-;children;AL;9|) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 20)) |l|) ((QUOTE T) (CONS (SPADCALL |x| (QREFELT |$| 14)) |l|))))))))
+
+(DEFUN |URAGG-;leaf?;AB;10| (|x| |$|) (SPADCALL |x| (QREFELT |$| 20)))
+
+(DEFUN |URAGG-;value;AS;11| (|x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "value of empty object")) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 8)))))
+
+(DEFUN |URAGG-;less?;ANniB;12| (|l| |n| |$|) (PROG (|i|) (RETURN (SEQ (LETT |i| |n| |URAGG-;less?;ANniB;12|) (SEQ G190 (COND ((NULL (COND ((|<| 0 |i|) (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL)))) (GO G191))) (SEQ (LETT |l| (SPADCALL |l| (QREFELT |$| 14)) |URAGG-;less?;ANniB;12|) (EXIT (LETT |i| (|-| |i| 1) |URAGG-;less?;ANniB;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (|<| 0 |i|))))))
+
+(DEFUN |URAGG-;more?;ANniB;13| (|l| |n| |$|) (PROG (|i|) (RETURN (SEQ (LETT |i| |n| |URAGG-;more?;ANniB;13|) (SEQ G190 (COND ((NULL (COND ((|<| 0 |i|) (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL)))) (GO G191))) (SEQ (LETT |l| (SPADCALL |l| (QREFELT |$| 14)) |URAGG-;more?;ANniB;13|) (EXIT (LETT |i| (|-| |i| 1) |URAGG-;more?;ANniB;13|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((ZEROP |i|) (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |URAGG-;size?;ANniB;14| (|l| |n| |$|) (PROG (|i|) (RETURN (SEQ (LETT |i| |n| |URAGG-;size?;ANniB;14|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |l| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (|<| 0 |i|)))) (GO G191))) (SEQ (LETT |l| (SPADCALL |l| (QREFELT |$| 14)) |URAGG-;size?;ANniB;14|) (EXIT (LETT |i| (|-| |i| 1) |URAGG-;size?;ANniB;14|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |l| (QREFELT |$| 20)) (ZEROP |i|)) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |URAGG-;#;ANni;15| (|x| |$|) (PROG (|k|) (RETURN (SEQ (SEQ (LETT |k| 0 |URAGG-;#;ANni;15|) G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;#;ANni;15|))) (LETT |k| (QSADD1 |k|) |URAGG-;#;ANni;15|) (GO G190) G191 (EXIT NIL)) (EXIT |k|)))))
+
+(DEFUN |URAGG-;tail;2A;16| (|x| |$|) (PROG (|k| |y|) (RETURN (SEQ (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "empty list")) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;tail;2A;16|) (SEQ (LETT |k| 0 |URAGG-;tail;2A;16|) G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (EXIT (LETT |y| (SPADCALL (LETT |x| |y| |URAGG-;tail;2A;16|) (QREFELT |$| 14)) |URAGG-;tail;2A;16|))) (LETT |k| (QSADD1 |k|) |URAGG-;tail;2A;16|) (GO G190) G191 (EXIT NIL)) (EXIT |x|))))))))
+
+(DEFUN |URAGG-;findCycle| (|x| |$|) (PROG (#1=#:G84667 |y|) (RETURN (SEQ (EXIT (SEQ (LETT |y| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;findCycle|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (PROGN (LETT #1# |x| |URAGG-;findCycle|) (GO #1#)))) (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;findCycle|) (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;findCycle|) (COND ((SPADCALL |y| (QREFELT |$| 20)) (PROGN (LETT #1# |y| |URAGG-;findCycle|) (GO #1#)))) (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (PROGN (LETT #1# |y| |URAGG-;findCycle|) (GO #1#)))) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;findCycle|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|))) #1# (EXIT #1#)))))
+
+(DEFUN |URAGG-;cycleTail;2A;18| (|x| |$|) (PROG (|y| |z|) (RETURN (SEQ (COND ((SPADCALL (LETT |y| (LETT |x| (SPADCALL |x| (QREFELT |$| 37)) |URAGG-;cycleTail;2A;18|) |URAGG-;cycleTail;2A;18|) (QREFELT |$| 20)) |x|) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleTail;2A;18|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| |z| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |y| |z| |URAGG-;cycleTail;2A;18|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 14)) |URAGG-;cycleTail;2A;18|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|))))))))
+
+(DEFUN |URAGG-;cycleEntry;2A;19| (|x| |$|) (PROG (|l| |z| |k| |y|) (RETURN (SEQ (COND ((SPADCALL |x| (QREFELT |$| 20)) |x|) ((SPADCALL (LETT |y| (|URAGG-;findCycle| |x| |$|) |URAGG-;cycleEntry;2A;19|) (QREFELT |$| 20)) |y|) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|) (SEQ (LETT |l| 1 |URAGG-;cycleEntry;2A;19|) G190 (COND ((NULL (COND ((SPADCALL |y| |z| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|))) (LETT |l| (QSADD1 |l|) |URAGG-;cycleEntry;2A;19|) (GO G190) G191 (EXIT NIL)) (LETT |y| |x| |URAGG-;cycleEntry;2A;19|) (SEQ (LETT |k| 1 |URAGG-;cycleEntry;2A;19|) G190 (COND ((QSGREATERP |k| |l|) (GO G191))) (SEQ (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|))) (LETT |k| (QSADD1 |k|) |URAGG-;cycleEntry;2A;19|) (GO G190) G191 (EXIT NIL)) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleEntry;2A;19|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|))))))))
+
+(DEFUN |URAGG-;cycleLength;ANni;20| (|x| |$|) (PROG (|k| |y|) (RETURN (SEQ (COND ((OR (SPADCALL |x| (QREFELT |$| 20)) (SPADCALL (LETT |x| (|URAGG-;findCycle| |x| |$|) |URAGG-;cycleLength;ANni;20|) (QREFELT |$| 20))) 0) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleLength;ANni;20|) (SEQ (LETT |k| 1 |URAGG-;cycleLength;ANni;20|) G190 (COND ((NULL (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;cycleLength;ANni;20|))) (LETT |k| (QSADD1 |k|) |URAGG-;cycleLength;ANni;20|) (GO G190) G191 (EXIT NIL)) (EXIT |k|))))))))
+
+(DEFUN |URAGG-;rest;ANniA;21| (|x| |n| |$|) (PROG (|i|) (RETURN (SEQ (SEQ (LETT |i| 1 |URAGG-;rest;ANniA;21|) G190 (COND ((QSGREATERP |i| |n|) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "Index out of range")) ((QUOTE T) (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;rest;ANniA;21|))))) (LETT |i| (QSADD1 |i|) |URAGG-;rest;ANniA;21|) (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |URAGG-;last;ANniA;22| (|x| |n| |$|) (PROG (|m| #1=#:G84694) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 42)) |URAGG-;last;ANniA;22|) (EXIT (COND ((|<| |m| |n|) (|error| "index out of range")) ((QUOTE T) (SPADCALL (SPADCALL |x| (PROG1 (LETT #1# (|-| |m| |n|) |URAGG-;last;ANniA;22|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 43)) (QREFELT |$| 44)))))))))
+
+(DEFUN |URAGG-;=;2AB;23| (|x| |y| |$|) (PROG (|k| #1=#:G84705) (RETURN (SEQ (EXIT (COND ((SPADCALL |x| |y| (QREFELT |$| 36)) (QUOTE T)) ((QUOTE T) (SEQ (SEQ (LETT |k| 0 |URAGG-;=;2AB;23|) G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 20)) (SPADCALL |y| (QREFELT |$| 20))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (COND ((NULL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (SPADCALL |y| (QREFELT |$| 8)) (QREFELT |$| 46))) (EXIT (PROGN (LETT #1# (QUOTE NIL) |URAGG-;=;2AB;23|) (GO #1#))))) (LETT |x| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;=;2AB;23|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 14)) |URAGG-;=;2AB;23|))) (LETT |k| (QSADD1 |k|) |URAGG-;=;2AB;23|) (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 20)) (SPADCALL |y| (QREFELT |$| 20))) ((QUOTE T) (QUOTE NIL)))))))) #1# (EXIT #1#)))))
+
+(DEFUN |URAGG-;node?;2AB;24| (|u| |v| |$|) (PROG (|k| #1=#:G84711) (RETURN (SEQ (EXIT (SEQ (SEQ (LETT |k| 0 |URAGG-;node?;2AB;24|) G190 (COND ((NULL (COND ((SPADCALL |v| (QREFELT |$| 20)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |u| |v| (QREFELT |$| 48)) (PROGN (LETT #1# (QUOTE T) |URAGG-;node?;2AB;24|) (GO #1#))) ((QUOTE T) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |v| (QREFELT |$| 33)) (EXIT (|error| "cyclic list")))))) (EXIT (LETT |v| (SPADCALL |v| (QREFELT |$| 14)) |URAGG-;node?;2AB;24|))))))) (LETT |k| (QSADD1 |k|) |URAGG-;node?;2AB;24|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |u| |v| (QREFELT |$| 48))))) #1# (EXIT #1#)))))
+
+(DEFUN |URAGG-;setelt;Afirst2S;25| (|x| G84713 |a| |$|) (SPADCALL |x| |a| (QREFELT |$| 50)))
+
+(DEFUN |URAGG-;setelt;Alast2S;26| (|x| G84715 |a| |$|) (SPADCALL |x| |a| (QREFELT |$| 52)))
+
+(DEFUN |URAGG-;setelt;Arest2A;27| (|x| G84717 |a| |$|) (SPADCALL |x| |a| (QREFELT |$| 54)))
+
+(DEFUN |URAGG-;concat;3A;28| (|x| |y| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 44)) |y| (QREFELT |$| 56)))
+
+(DEFUN |URAGG-;setlast!;A2S;29| (|x| |s| |$|) (SEQ (COND ((SPADCALL |x| (QREFELT |$| 20)) (|error| "setlast: empty list")) ((QUOTE T) (SEQ (SPADCALL (SPADCALL |x| (QREFELT |$| 22)) |s| (QREFELT |$| 50)) (EXIT |s|))))))
+
+(DEFUN |URAGG-;setchildren!;ALA;30| (|u| |lv| |$|) (COND ((EQL (LENGTH |lv|) 1) (SPADCALL |u| (|SPADfirst| |lv|) (QREFELT |$| 54))) ((QUOTE T) (|error| "wrong number of children specified"))))
+
+(DEFUN |URAGG-;setvalue!;A2S;31| (|u| |s| |$|) (SPADCALL |u| |s| (QREFELT |$| 50)))
+
+(DEFUN |URAGG-;split!;AIA;32| (|p| |n| |$|) (PROG (#1=#:G84725 |q|) (RETURN (SEQ (COND ((|<| |n| 1) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |p| (SPADCALL |p| (PROG1 (LETT #1# (|-| |n| 1) |URAGG-;split!;AIA;32|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 43)) |URAGG-;split!;AIA;32|) (LETT |q| (SPADCALL |p| (QREFELT |$| 14)) |URAGG-;split!;AIA;32|) (SPADCALL |p| (SPADCALL (QREFELT |$| 61)) (QREFELT |$| 54)) (EXIT |q|))))))))
+
+(DEFUN |URAGG-;cycleSplit!;2A;33| (|x| |$|) (PROG (|y| |z|) (RETURN (SEQ (COND ((OR (SPADCALL (LETT |y| (SPADCALL |x| (QREFELT |$| 37)) |URAGG-;cycleSplit!;2A;33|) (QREFELT |$| 20)) (SPADCALL |x| |y| (QREFELT |$| 36))) |y|) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |x| (QREFELT |$| 14)) |URAGG-;cycleSplit!;2A;33|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |z| |y| (QREFELT |$| 36)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |x| |z| |URAGG-;cycleSplit!;2A;33|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 14)) |URAGG-;cycleSplit!;2A;33|))) NIL (GO G190) G191 (EXIT NIL)) (SPADCALL |x| (SPADCALL (QREFELT |$| 61)) (QREFELT |$| 54)) (EXIT |y|))))))))
+
+(DEFUN |UnaryRecursiveAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|UnaryRecursiveAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |UnaryRecursiveAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 66) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasAttribute| |#1| (QUOTE |finiteAggregate|)) (QSETREFV |$| 45 (CONS (|dispatchFunction| |URAGG-;last;ANniA;22|) |$|)))) (COND ((|HasCategory| |#2| (QUOTE (|SetCategory|))) (PROGN (QSETREFV |$| 47 (CONS (|dispatchFunction| |URAGG-;=;2AB;23|) |$|)) (QSETREFV |$| 49 (CONS (|dispatchFunction| |URAGG-;node?;2AB;24|) |$|))))) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 51 (CONS (|dispatchFunction| |URAGG-;setelt;Afirst2S;25|) |$|)) (QSETREFV |$| 53 (CONS (|dispatchFunction| |URAGG-;setelt;Alast2S;26|) |$|)) (QSETREFV |$| 55 (CONS (|dispatchFunction| |URAGG-;setelt;Arest2A;27|) |$|)) (QSETREFV |$| 57 (CONS (|dispatchFunction| |URAGG-;concat;3A;28|) |$|)) (QSETREFV |$| 58 (CONS (|dispatchFunction| |URAGG-;setlast!;A2S;29|) |$|)) (QSETREFV |$| 59 (CONS (|dispatchFunction| |URAGG-;setchildren!;ALA;30|) |$|)) (QSETREFV |$| 60 (CONS (|dispatchFunction| |URAGG-;setvalue!;A2S;31|) |$|)) (QSETREFV |$| 63 (CONS (|dispatchFunction| |URAGG-;split!;AIA;32|) |$|)) (QSETREFV |$| 64 (CONS (|dispatchFunction| |URAGG-;cycleSplit!;2A;33|) |$|))))) |$|))))
+
+(MAKEPROP (QUOTE |UnaryRecursiveAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |first|) (QUOTE "first") |URAGG-;elt;AfirstS;1| (5 . |last|) (QUOTE "last") |URAGG-;elt;AlastS;2| (10 . |rest|) (QUOTE "rest") |URAGG-;elt;ArestA;3| |URAGG-;second;AS;4| |URAGG-;third;AS;5| (|Boolean|) (15 . |empty?|) |URAGG-;cyclic?;AB;6| (20 . |tail|) |URAGG-;last;AS;7| (|List| |$|) |URAGG-;nodes;AL;8| |URAGG-;children;AL;9| |URAGG-;leaf?;AB;10| |URAGG-;value;AS;11| (|NonNegativeInteger|) |URAGG-;less?;ANniB;12| |URAGG-;more?;ANniB;13| |URAGG-;size?;ANniB;14| (25 . |cyclic?|) |URAGG-;#;ANni;15| |URAGG-;tail;2A;16| (30 . |eq?|) (36 . |cycleEntry|) |URAGG-;cycleTail;2A;18| |URAGG-;cycleEntry;2A;19| |URAGG-;cycleLength;ANni;20| |URAGG-;rest;ANniA;21| (41 . |#|) (46 . |rest|) (52 . |copy|) (57 . |last|) (63 . |=|) (69 . |=|) (75 . |=|) (81 . |node?|) (87 . |setfirst!|) (93 . |setelt|) (100 . |setlast!|) (106 . |setelt|) (113 . |setrest!|) (119 . |setelt|) (126 . |concat!|) (132 . |concat|) (138 . |setlast!|) (144 . |setchildren!|) (150 . |setvalue!|) (156 . |empty|) (|Integer|) (160 . |split!|) (166 . |cycleSplit!|) (QUOTE "value"))) (QUOTE #(|value| 171 |third| 176 |tail| 181 |split!| 186 |size?| 192 |setvalue!| 198 |setlast!| 204 |setelt| 210 |setchildren!| 231 |second| 237 |rest| 242 |nodes| 248 |node?| 253 |more?| 259 |less?| 265 |leaf?| 271 |last| 276 |elt| 287 |cyclic?| 305 |cycleTail| 310 |cycleSplit!| 315 |cycleLength| 320 |cycleEntry| 325 |concat| 330 |children| 336 |=| 341 |#| 347)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 64 (QUOTE (1 6 7 0 8 1 6 7 0 11 1 6 0 0 14 1 6 19 0 20 1 6 0 0 22 1 6 19 0 33 2 6 19 0 0 36 1 6 0 0 37 1 6 29 0 42 2 6 0 0 29 43 1 6 0 0 44 2 0 0 0 29 45 2 7 19 0 0 46 2 0 19 0 0 47 2 6 19 0 0 48 2 0 19 0 0 49 2 6 7 0 7 50 3 0 7 0 9 7 51 2 6 7 0 7 52 3 0 7 0 12 7 53 2 6 0 0 0 54 3 0 0 0 15 0 55 2 6 0 0 0 56 2 0 0 0 0 57 2 0 7 0 7 58 2 0 0 0 24 59 2 0 7 0 7 60 0 6 0 61 2 0 0 0 62 63 1 0 0 0 64 1 0 7 0 28 1 0 7 0 18 1 0 0 0 35 2 0 0 0 62 63 2 0 19 0 29 32 2 0 7 0 7 60 2 0 7 0 7 58 3 0 7 0 12 7 53 3 0 0 0 15 0 55 3 0 7 0 9 7 51 2 0 0 0 24 59 1 0 7 0 17 2 0 0 0 29 41 1 0 24 0 25 2 0 19 0 0 49 2 0 19 0 29 31 2 0 19 0 29 30 1 0 19 0 27 2 0 0 0 29 45 1 0 7 0 23 2 0 7 0 12 13 2 0 0 0 15 16 2 0 7 0 9 10 1 0 19 0 21 1 0 0 0 38 1 0 0 0 64 1 0 29 0 40 1 0 0 0 39 2 0 0 0 0 57 1 0 24 0 26 2 0 19 0 0 47 1 0 29 0 34)))))) (QUOTE |lookupComplete|)))
+@
+\section{category STAGG StreamAggregate}
+<<category STAGG StreamAggregate>>=
+)abbrev category STAGG StreamAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A stream aggregate is a linear aggregate which possibly has an infinite
+++ number of elements. A basic domain constructor which builds stream
+++ aggregates is \spadtype{Stream}. From streams, a number of infinite
+++ structures such power series can be built. A stream aggregate may
+++ also be infinite since it may be cyclic.
+++ For example, see \spadtype{DecimalExpansion}.
+StreamAggregate(S:Type): Category ==
+ Join(UnaryRecursiveAggregate S, LinearAggregate S) with
+ explicitlyFinite?: % -> Boolean
+ ++ explicitlyFinite?(s) tests if the stream has a finite
+ ++ number of elements, and false otherwise.
+ ++ Note: for many datatypes, \axiom{explicitlyFinite?(s) = not possiblyInfinite?(s)}.
+ possiblyInfinite?: % -> Boolean
+ ++ possiblyInfinite?(s) tests if the stream s could possibly
+ ++ have an infinite number of elements.
+ ++ Note: for many datatypes, \axiom{possiblyInfinite?(s) = not explictlyFinite?(s)}.
+ add
+ c2: (%, %) -> S
+
+ explicitlyFinite? x == not cyclic? x
+ possiblyInfinite? x == cyclic? x
+ first(x, n) == construct [c2(x, x := rest x) for i in 1..n]
+
+ c2(x, r) ==
+ empty? x => error "Index out of range"
+ first x
+
+ elt(x:%, i:Integer) ==
+ i := i - minIndex x
+ (i < 0) or empty?(x := rest(x, i::NonNegativeInteger)) => error "index out of range"
+ first x
+
+ elt(x:%, i:UniversalSegment(Integer)) ==
+ l := lo(i) - minIndex x
+ l < 0 => error "index out of range"
+ not hasHi i => copy(rest(x, l::NonNegativeInteger))
+ (h := hi(i) - minIndex x) < l => empty()
+ first(rest(x, l::NonNegativeInteger), (h - l + 1)::NonNegativeInteger)
+
+ if % has shallowlyMutable then
+ concat(x:%, y:%) == concat_!(copy x, y)
+
+ concat l ==
+ empty? l => empty()
+ concat_!(copy first l, concat rest l)
+
+ map_!(f, l) ==
+ y := l
+ while not empty? l repeat
+ setfirst_!(l, f first l)
+ l := rest l
+ y
+
+ fill_!(x, s) ==
+ y := x
+ while not empty? y repeat (setfirst_!(y, s); y := rest y)
+ x
+
+ setelt(x:%, i:Integer, s:S) ==
+ i := i - minIndex x
+ (i < 0) or empty?(x := rest(x,i::NonNegativeInteger)) => error "index out of range"
+ setfirst_!(x, s)
+
+ setelt(x:%, i:UniversalSegment(Integer), s:S) ==
+ (l := lo(i) - minIndex x) < 0 => error "index out of range"
+ h := if hasHi i then hi(i) - minIndex x else maxIndex x
+ h < l => s
+ y := rest(x, l::NonNegativeInteger)
+ z := rest(y, (h - l + 1)::NonNegativeInteger)
+ while not eq?(y, z) repeat (setfirst_!(y, s); y := rest y)
+ s
+
+ concat_!(x:%, y:%) ==
+ empty? x => y
+ setrest_!(tail x, y)
+ x
+
+@
+\section{STAGG.lsp BOOTSTRAP}
+{\bf STAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf STAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf STAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<STAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |StreamAggregate;CAT| (QUOTE NIL))
+
+(SETQ |StreamAggregate;AL| (QUOTE NIL))
+
+(DEFUN |StreamAggregate| (#1=#:G87035) (LET (#2=#:G87036) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |StreamAggregate;AL|)) (CDR #2#)) (T (SETQ |StreamAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|StreamAggregate;| #1#))) |StreamAggregate;AL|)) #2#))))
+
+(DEFUN |StreamAggregate;| (|t#1|) (PROG (#1=#:G87034) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|StreamAggregate;CAT|) ((QUOTE T) (LETT |StreamAggregate;CAT| (|Join| (|UnaryRecursiveAggregate| (QUOTE |t#1|)) (|LinearAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|explicitlyFinite?| ((|Boolean|) |$|)) T) ((|possiblyInfinite?| ((|Boolean|) |$|)) T))) NIL (QUOTE ((|Boolean|))) NIL)) . #2=(|StreamAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |StreamAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{STAGG-.lsp BOOTSTRAP}
+{\bf STAGG-} depends on {\bf STAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf STAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf STAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<STAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |STAGG-;explicitlyFinite?;AB;1| (|x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 9)) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |STAGG-;possiblyInfinite?;AB;2| (|x| |$|) (SPADCALL |x| (QREFELT |$| 9)))
+
+(DEFUN |STAGG-;first;ANniA;3| (|x| |n| |$|) (PROG (#1=#:G87053 |i|) (RETURN (SEQ (SPADCALL (PROGN (LETT #1# NIL |STAGG-;first;ANniA;3|) (SEQ (LETT |i| 1 |STAGG-;first;ANniA;3|) G190 (COND ((QSGREATERP |i| |n|) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (|STAGG-;c2| |x| (LETT |x| (SPADCALL |x| (QREFELT |$| 12)) |STAGG-;first;ANniA;3|) |$|) #1#) |STAGG-;first;ANniA;3|))) (LETT |i| (QSADD1 |i|) |STAGG-;first;ANniA;3|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 14))))))
+
+(DEFUN |STAGG-;c2| (|x| |r| |$|) (COND ((SPADCALL |x| (QREFELT |$| 17)) (|error| "Index out of range")) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 18)))))
+
+(DEFUN |STAGG-;elt;AIS;5| (|x| |i| |$|) (PROG (#1=#:G87056) (RETURN (SEQ (LETT |i| (|-| |i| (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;elt;AIS;5|) (COND ((OR (|<| |i| 0) (SPADCALL (LETT |x| (SPADCALL |x| (PROG1 (LETT #1# |i| |STAGG-;elt;AIS;5|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) |STAGG-;elt;AIS;5|) (QREFELT |$| 17))) (EXIT (|error| "index out of range")))) (EXIT (SPADCALL |x| (QREFELT |$| 18)))))))
+
+(DEFUN |STAGG-;elt;AUsA;6| (|x| |i| |$|) (PROG (|l| #1=#:G87060 |h| #2=#:G87062 #3=#:G87063) (RETURN (SEQ (LETT |l| (|-| (SPADCALL |i| (QREFELT |$| 24)) (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;elt;AUsA;6|) (EXIT (COND ((|<| |l| 0) (|error| "index out of range")) ((NULL (SPADCALL |i| (QREFELT |$| 25))) (SPADCALL (SPADCALL |x| (PROG1 (LETT #1# |l| |STAGG-;elt;AUsA;6|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) (QREFELT |$| 26))) ((QUOTE T) (SEQ (LETT |h| (|-| (SPADCALL |i| (QREFELT |$| 27)) (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;elt;AUsA;6|) (EXIT (COND ((|<| |h| |l|) (SPADCALL (QREFELT |$| 28))) ((QUOTE T) (SPADCALL (SPADCALL |x| (PROG1 (LETT #2# |l| |STAGG-;elt;AUsA;6|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) (QREFELT |$| 21)) (PROG1 (LETT #3# (|+| (|-| |h| |l|) 1) |STAGG-;elt;AUsA;6|) (|check-subtype| (|>=| #3# 0) (QUOTE (|NonNegativeInteger|)) #3#)) (QREFELT |$| 29)))))))))))))
+
+(DEFUN |STAGG-;concat;3A;7| (|x| |y| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 26)) |y| (QREFELT |$| 31)))
+
+(DEFUN |STAGG-;concat;LA;8| (|l| |$|) (COND ((NULL |l|) (SPADCALL (QREFELT |$| 28))) ((QUOTE T) (SPADCALL (SPADCALL (|SPADfirst| |l|) (QREFELT |$| 26)) (SPADCALL (CDR |l|) (QREFELT |$| 34)) (QREFELT |$| 31)))))
+
+(DEFUN |STAGG-;map!;M2A;9| (|f| |l| |$|) (PROG (|y|) (RETURN (SEQ (LETT |y| |l| |STAGG-;map!;M2A;9|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |l| (QREFELT |$| 17)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |l| (SPADCALL (SPADCALL |l| (QREFELT |$| 18)) |f|) (QREFELT |$| 36)) (EXIT (LETT |l| (SPADCALL |l| (QREFELT |$| 12)) |STAGG-;map!;M2A;9|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|)))))
+
+(DEFUN |STAGG-;fill!;ASA;10| (|x| |s| |$|) (PROG (|y|) (RETURN (SEQ (LETT |y| |x| |STAGG-;fill!;ASA;10|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 17)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |y| |s| (QREFELT |$| 36)) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 12)) |STAGG-;fill!;ASA;10|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |STAGG-;setelt;AI2S;11| (|x| |i| |s| |$|) (PROG (#1=#:G87081) (RETURN (SEQ (LETT |i| (|-| |i| (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;setelt;AI2S;11|) (COND ((OR (|<| |i| 0) (SPADCALL (LETT |x| (SPADCALL |x| (PROG1 (LETT #1# |i| |STAGG-;setelt;AI2S;11|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) |STAGG-;setelt;AI2S;11|) (QREFELT |$| 17))) (EXIT (|error| "index out of range")))) (EXIT (SPADCALL |x| |s| (QREFELT |$| 36)))))))
+
+(DEFUN |STAGG-;setelt;AUs2S;12| (|x| |i| |s| |$|) (PROG (|l| |h| #1=#:G87086 #2=#:G87087 |z| |y|) (RETURN (SEQ (LETT |l| (|-| (SPADCALL |i| (QREFELT |$| 24)) (SPADCALL |x| (QREFELT |$| 20))) |STAGG-;setelt;AUs2S;12|) (EXIT (COND ((|<| |l| 0) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |h| (COND ((SPADCALL |i| (QREFELT |$| 25)) (|-| (SPADCALL |i| (QREFELT |$| 27)) (SPADCALL |x| (QREFELT |$| 20)))) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 41)))) |STAGG-;setelt;AUs2S;12|) (EXIT (COND ((|<| |h| |l|) |s|) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# |l| |STAGG-;setelt;AUs2S;12|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 21)) |STAGG-;setelt;AUs2S;12|) (LETT |z| (SPADCALL |y| (PROG1 (LETT #2# (|+| (|-| |h| |l|) 1) |STAGG-;setelt;AUs2S;12|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) (QREFELT |$| 21)) |STAGG-;setelt;AUs2S;12|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| |z| (QREFELT |$| 42)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |y| |s| (QREFELT |$| 36)) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 12)) |STAGG-;setelt;AUs2S;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |s|)))))))))))))
+
+(DEFUN |STAGG-;concat!;3A;13| (|x| |y| |$|) (SEQ (COND ((SPADCALL |x| (QREFELT |$| 17)) |y|) ((QUOTE T) (SEQ (SPADCALL (SPADCALL |x| (QREFELT |$| 44)) |y| (QREFELT |$| 45)) (EXIT |x|))))))
+
+(DEFUN |StreamAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|StreamAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |StreamAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 51) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasAttribute| |#1| (QUOTE |shallowlyMutable|)) (PROGN (QSETREFV |$| 32 (CONS (|dispatchFunction| |STAGG-;concat;3A;7|) |$|)) (QSETREFV |$| 35 (CONS (|dispatchFunction| |STAGG-;concat;LA;8|) |$|)) (QSETREFV |$| 38 (CONS (|dispatchFunction| |STAGG-;map!;M2A;9|) |$|)) (QSETREFV |$| 39 (CONS (|dispatchFunction| |STAGG-;fill!;ASA;10|) |$|)) (QSETREFV |$| 40 (CONS (|dispatchFunction| |STAGG-;setelt;AI2S;11|) |$|)) (QSETREFV |$| 43 (CONS (|dispatchFunction| |STAGG-;setelt;AUs2S;12|) |$|)) (QSETREFV |$| 46 (CONS (|dispatchFunction| |STAGG-;concat!;3A;13|) |$|))))) |$|))))
+
+(MAKEPROP (QUOTE |StreamAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|Boolean|) (0 . |cyclic?|) |STAGG-;explicitlyFinite?;AB;1| |STAGG-;possiblyInfinite?;AB;2| (5 . |rest|) (|List| 7) (10 . |construct|) (|NonNegativeInteger|) |STAGG-;first;ANniA;3| (15 . |empty?|) (20 . |first|) (|Integer|) (25 . |minIndex|) (30 . |rest|) |STAGG-;elt;AIS;5| (|UniversalSegment| 19) (36 . |lo|) (41 . |hasHi|) (46 . |copy|) (51 . |hi|) (56 . |empty|) (60 . |first|) |STAGG-;elt;AUsA;6| (66 . |concat!|) (72 . |concat|) (|List| |$|) (78 . |concat|) (83 . |concat|) (88 . |setfirst!|) (|Mapping| 7 7) (94 . |map!|) (100 . |fill!|) (106 . |setelt|) (113 . |maxIndex|) (118 . |eq?|) (124 . |setelt|) (131 . |tail|) (136 . |setrest!|) (142 . |concat!|) (QUOTE "rest") (QUOTE "last") (QUOTE "first") (QUOTE "value"))) (QUOTE #(|setelt| 148 |possiblyInfinite?| 162 |map!| 167 |first| 173 |fill!| 179 |explicitlyFinite?| 185 |elt| 190 |concat!| 202 |concat| 208)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 46 (QUOTE (1 6 8 0 9 1 6 0 0 12 1 6 0 13 14 1 6 8 0 17 1 6 7 0 18 1 6 19 0 20 2 6 0 0 15 21 1 23 19 0 24 1 23 8 0 25 1 6 0 0 26 1 23 19 0 27 0 6 0 28 2 6 0 0 15 29 2 6 0 0 0 31 2 0 0 0 0 32 1 6 0 33 34 1 0 0 33 35 2 6 7 0 7 36 2 0 0 37 0 38 2 0 0 0 7 39 3 0 7 0 19 7 40 1 6 19 0 41 2 6 8 0 0 42 3 0 7 0 23 7 43 1 6 0 0 44 2 6 0 0 0 45 2 0 0 0 0 46 3 0 7 0 19 7 40 3 0 7 0 23 7 43 1 0 8 0 11 2 0 0 37 0 38 2 0 0 0 15 16 2 0 0 0 7 39 1 0 8 0 10 2 0 7 0 19 22 2 0 0 0 23 30 2 0 0 0 0 46 1 0 0 33 35 2 0 0 0 0 32)))))) (QUOTE |lookupComplete|)))
+@
+\section{category LNAGG LinearAggregate}
+<<category LNAGG LinearAggregate>>=
+)abbrev category LNAGG LinearAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A linear aggregate is an aggregate whose elements are indexed by integers.
+++ Examples of linear aggregates are strings, lists, and
+++ arrays.
+++ Most of the exported operations for linear aggregates are non-destructive
+++ but are not always efficient for a particular aggregate.
+++ For example, \spadfun{concat} of two lists needs only to copy its first
+++ argument, whereas \spadfun{concat} of two arrays needs to copy both arguments.
+++ Most of the operations exported here apply to infinite objects (e.g. streams)
+++ as well to finite ones.
+++ For finite linear aggregates, see \spadtype{FiniteLinearAggregate}.
+LinearAggregate(S:Type): Category ==
+ Join(IndexedAggregate(Integer, S), Collection(S)) with
+ new : (NonNegativeInteger,S) -> %
+ ++ new(n,x) returns \axiom{fill!(new n,x)}.
+ concat: (%,S) -> %
+ ++ concat(u,x) returns aggregate u with additional element x at the end.
+ ++ Note: for lists, \axiom{concat(u,x) == concat(u,[x])}
+ concat: (S,%) -> %
+ ++ concat(x,u) returns aggregate u with additional element at the front.
+ ++ Note: for lists: \axiom{concat(x,u) == concat([x],u)}.
+ concat: (%,%) -> %
+ ++ concat(u,v) returns an aggregate consisting of the elements of u
+ ++ followed by the elements of v.
+ ++ Note: if \axiom{w = concat(u,v)} then \axiom{w.i = u.i for i in indices u}
+ ++ and \axiom{w.(j + maxIndex u) = v.j for j in indices v}.
+ concat: List % -> %
+ ++ concat(u), where u is a lists of aggregates \axiom{[a,b,...,c]}, returns
+ ++ a single aggregate consisting of the elements of \axiom{a}
+ ++ followed by those
+ ++ of b followed ... by the elements of c.
+ ++ Note: \axiom{concat(a,b,...,c) = concat(a,concat(b,...,c))}.
+ map: ((S,S)->S,%,%) -> %
+ ++ map(f,u,v) returns a new collection w with elements \axiom{z = f(x,y)}
+ ++ for corresponding elements x and y from u and v.
+ ++ Note: for linear aggregates, \axiom{w.i = f(u.i,v.i)}.
+ elt: (%,UniversalSegment(Integer)) -> %
+ ++ elt(u,i..j) (also written: \axiom{a(i..j)}) returns the aggregate of
+ ++ elements \axiom{u} for k from i to j in that order.
+ ++ Note: in general, \axiom{a.s = [a.k for i in s]}.
+ delete: (%,Integer) -> %
+ ++ delete(u,i) returns a copy of u with the \axiom{i}th element deleted.
+ ++ Note: for lists, \axiom{delete(a,i) == concat(a(0..i - 1),a(i + 1,..))}.
+ delete: (%,UniversalSegment(Integer)) -> %
+ ++ delete(u,i..j) returns a copy of u with the \axiom{i}th through
+ ++ \axiom{j}th element deleted.
+ ++ Note: \axiom{delete(a,i..j) = concat(a(0..i-1),a(j+1..))}.
+ insert: (S,%,Integer) -> %
+ ++ insert(x,u,i) returns a copy of u having x as its \axiom{i}th element.
+ ++ Note: \axiom{insert(x,a,k) = concat(concat(a(0..k-1),x),a(k..))}.
+ insert: (%,%,Integer) -> %
+ ++ insert(v,u,k) returns a copy of u having v inserted beginning at the
+ ++ \axiom{i}th element.
+ ++ Note: \axiom{insert(v,u,k) = concat( u(0..k-1), v, u(k..) )}.
+ if % has shallowlyMutable then setelt: (%,UniversalSegment(Integer),S) -> S
+ ++ setelt(u,i..j,x) (also written: \axiom{u(i..j) := x}) destructively
+ ++ replaces each element in the segment \axiom{u(i..j)} by x.
+ ++ The value x is returned.
+ ++ Note: u is destructively change so
+ ++ that \axiom{u.k := x for k in i..j};
+ ++ its length remains unchanged.
+ add
+ indices a == [i for i in minIndex a .. maxIndex a]
+ index?(i, a) == i >= minIndex a and i <= maxIndex a
+ concat(a:%, x:S) == concat(a, new(1, x))
+ concat(x:S, y:%) == concat(new(1, x), y)
+ insert(x:S, a:%, i:Integer) == insert(new(1, x), a, i)
+ if % has finiteAggregate then
+ maxIndex l == #l - 1 + minIndex l
+
+--if % has shallowlyMutable then new(n, s) == fill_!(new n, s)
+
+@
+\section{LNAGG.lsp BOOTSTRAP}
+{\bf LNAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LNAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LNAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LNAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |LinearAggregate;CAT| (QUOTE NIL))
+
+(SETQ |LinearAggregate;AL| (QUOTE NIL))
+
+(DEFUN |LinearAggregate| (#1=#:G85818) (LET (#2=#:G85819) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |LinearAggregate;AL|)) (CDR #2#)) (T (SETQ |LinearAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|LinearAggregate;| #1#))) |LinearAggregate;AL|)) #2#))))
+
+(DEFUN |LinearAggregate;| (|t#1|) (PROG (#1=#:G85817) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (|sublisV| (PAIR (QUOTE (#2=#:G85816)) (LIST (QUOTE (|Integer|)))) (COND (|LinearAggregate;CAT|) ((QUOTE T) (LETT |LinearAggregate;CAT| (|Join| (|IndexedAggregate| (QUOTE #2#) (QUOTE |t#1|)) (|Collection| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|new| (|$| (|NonNegativeInteger|) |t#1|)) T) ((|concat| (|$| |$| |t#1|)) T) ((|concat| (|$| |t#1| |$|)) T) ((|concat| (|$| |$| |$|)) T) ((|concat| (|$| (|List| |$|))) T) ((|map| (|$| (|Mapping| |t#1| |t#1| |t#1|) |$| |$|)) T) ((|elt| (|$| |$| (|UniversalSegment| (|Integer|)))) T) ((|delete| (|$| |$| (|Integer|))) T) ((|delete| (|$| |$| (|UniversalSegment| (|Integer|)))) T) ((|insert| (|$| |t#1| |$| (|Integer|))) T) ((|insert| (|$| |$| |$| (|Integer|))) T) ((|setelt| (|t#1| |$| (|UniversalSegment| (|Integer|)) |t#1|)) (|has| |$| (ATTRIBUTE |shallowlyMutable|))))) NIL (QUOTE ((|UniversalSegment| (|Integer|)) (|Integer|) (|List| |$|) (|NonNegativeInteger|))) NIL)) . #3=(|LinearAggregate|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |LinearAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{LNAGG-.lsp BOOTSTRAP}
+{\bf LNAGG-} depends on {\bf LNAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LNAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LNAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LNAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |LNAGG-;indices;AL;1| (|a| |$|) (PROG (#1=#:G85833 |i| #2=#:G85834) (RETURN (SEQ (PROGN (LETT #1# NIL |LNAGG-;indices;AL;1|) (SEQ (LETT |i| (SPADCALL |a| (QREFELT |$| 9)) |LNAGG-;indices;AL;1|) (LETT #2# (SPADCALL |a| (QREFELT |$| 10)) |LNAGG-;indices;AL;1|) G190 (COND ((|>| |i| #2#) (GO G191))) (SEQ (EXIT (LETT #1# (CONS |i| #1#) |LNAGG-;indices;AL;1|))) (LETT |i| (|+| |i| 1) |LNAGG-;indices;AL;1|) (GO G190) G191 (EXIT (NREVERSE0 #1#))))))))
+
+(DEFUN |LNAGG-;index?;IAB;2| (|i| |a| |$|) (COND ((OR (|<| |i| (SPADCALL |a| (QREFELT |$| 9))) (|<| (SPADCALL |a| (QREFELT |$| 10)) |i|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |LNAGG-;concat;ASA;3| (|a| |x| |$|) (SPADCALL |a| (SPADCALL 1 |x| (QREFELT |$| 16)) (QREFELT |$| 17)))
+
+(DEFUN |LNAGG-;concat;S2A;4| (|x| |y| |$|) (SPADCALL (SPADCALL 1 |x| (QREFELT |$| 16)) |y| (QREFELT |$| 17)))
+
+(DEFUN |LNAGG-;insert;SAIA;5| (|x| |a| |i| |$|) (SPADCALL (SPADCALL 1 |x| (QREFELT |$| 16)) |a| |i| (QREFELT |$| 20)))
+
+(DEFUN |LNAGG-;maxIndex;AI;6| (|l| |$|) (|+| (|-| (SPADCALL |l| (QREFELT |$| 22)) 1) (SPADCALL |l| (QREFELT |$| 9))))
+
+(DEFUN |LinearAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|LinearAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |LinearAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 25) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasAttribute| |#1| (QUOTE |shallowlyMutable|)))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasAttribute| |#1| (QUOTE |finiteAggregate|)) (QSETREFV |$| 23 (CONS (|dispatchFunction| |LNAGG-;maxIndex;AI;6|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |LinearAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|Integer|) (0 . |minIndex|) (5 . |maxIndex|) (|List| 8) |LNAGG-;indices;AL;1| (|Boolean|) |LNAGG-;index?;IAB;2| (|NonNegativeInteger|) (10 . |new|) (16 . |concat|) |LNAGG-;concat;ASA;3| |LNAGG-;concat;S2A;4| (22 . |insert|) |LNAGG-;insert;SAIA;5| (29 . |#|) (34 . |maxIndex|) (|List| |$|))) (QUOTE #(|maxIndex| 39 |insert| 44 |indices| 51 |index?| 56 |concat| 62)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 23 (QUOTE (1 6 8 0 9 1 6 8 0 10 2 6 0 15 7 16 2 6 0 0 0 17 3 6 0 0 0 8 20 1 6 15 0 22 1 0 8 0 23 1 0 8 0 23 3 0 0 7 0 8 21 1 0 11 0 12 2 0 13 8 0 14 2 0 0 0 7 18 2 0 0 7 0 19)))))) (QUOTE |lookupComplete|)))
+@
+\section{category FLAGG FiniteLinearAggregate}
+<<category FLAGG FiniteLinearAggregate>>=
+)abbrev category FLAGG FiniteLinearAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A finite linear aggregate is a linear aggregate of finite length.
+++ The finite property of the aggregate adds several exports to the
+++ list of exports from \spadtype{LinearAggregate} such as
+++ \spadfun{reverse}, \spadfun{sort}, and so on.
+FiniteLinearAggregate(S:Type): Category == LinearAggregate S with
+ finiteAggregate
+ merge: ((S,S)->Boolean,%,%) -> %
+ ++ merge(p,a,b) returns an aggregate c which merges \axiom{a} and b.
+ ++ The result is produced by examining each element x of \axiom{a} and y
+ ++ of b successively. If \axiom{p(x,y)} is true, then x is inserted into
+ ++ the result; otherwise y is inserted. If x is chosen, the next element
+ ++ of \axiom{a} is examined, and so on. When all the elements of one
+ ++ aggregate are examined, the remaining elements of the other
+ ++ are appended.
+ ++ For example, \axiom{merge(<,[1,3],[2,7,5])} returns \axiom{[1,2,3,7,5]}.
+ reverse: % -> %
+ ++ reverse(a) returns a copy of \axiom{a} with elements in reverse order.
+ sort: ((S,S)->Boolean,%) -> %
+ ++ sort(p,a) returns a copy of \axiom{a} sorted using total ordering predicate p.
+ sorted?: ((S,S)->Boolean,%) -> Boolean
+ ++ sorted?(p,a) tests if \axiom{a} is sorted according to predicate p.
+ position: (S->Boolean, %) -> Integer
+ ++ position(p,a) returns the index i of the first x in \axiom{a} such that
+ ++ \axiom{p(x)} is true, and \axiom{minIndex(a) - 1} if there is no such x.
+ if S has SetCategory then
+ position: (S, %) -> Integer
+ ++ position(x,a) returns the index i of the first occurrence of x in a,
+ ++ and \axiom{minIndex(a) - 1} if there is no such x.
+ position: (S,%,Integer) -> Integer
+ ++ position(x,a,n) returns the index i of the first occurrence of x in
+ ++ \axiom{a} where \axiom{i >= n}, and \axiom{minIndex(a) - 1} if no such x is found.
+ if S has OrderedSet then
+ OrderedSet
+ merge: (%,%) -> %
+ ++ merge(u,v) merges u and v in ascending order.
+ ++ Note: \axiom{merge(u,v) = merge(<=,u,v)}.
+ sort: % -> %
+ ++ sort(u) returns an u with elements in ascending order.
+ ++ Note: \axiom{sort(u) = sort(<=,u)}.
+ sorted?: % -> Boolean
+ ++ sorted?(u) tests if the elements of u are in ascending order.
+ if % has shallowlyMutable then
+ copyInto_!: (%,%,Integer) -> %
+ ++ copyInto!(u,v,i) returns aggregate u containing a copy of
+ ++ v inserted at element i.
+ reverse_!: % -> %
+ ++ reverse!(u) returns u with its elements in reverse order.
+ sort_!: ((S,S)->Boolean,%) -> %
+ ++ sort!(p,u) returns u with its elements ordered by p.
+ if S has OrderedSet then sort_!: % -> %
+ ++ sort!(u) returns u with its elements in ascending order.
+ add
+ if S has SetCategory then
+ position(x:S, t:%) == position(x, t, minIndex t)
+
+ if S has OrderedSet then
+-- sorted? l == sorted?(_<$S, l)
+ sorted? l == sorted?(#1 < #2 or #1 = #2, l)
+ merge(x, y) == merge(_<$S, x, y)
+ sort l == sort(_<$S, l)
+
+ if % has shallowlyMutable then
+ reverse x == reverse_! copy x
+ sort(f, l) == sort_!(f, copy l)
+ reverse x == reverse_! copy x
+
+ if S has OrderedSet then
+ sort_! l == sort_!(_<$S, l)
+
+@
+\section{category A1AGG OneDimensionalArrayAggregate}
+<<category A1AGG OneDimensionalArrayAggregate>>=
+)abbrev category A1AGG OneDimensionalArrayAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ One-dimensional-array aggregates serves as models for one-dimensional arrays.
+++ Categorically, these aggregates are finite linear aggregates
+++ with the \spadatt{shallowlyMutable} property, that is, any component of
+++ the array may be changed without affecting the
+++ identity of the overall array.
+++ Array data structures are typically represented by a fixed area in storage and
+++ therefore cannot efficiently grow or shrink on demand as can list structures
+++ (see however \spadtype{FlexibleArray} for a data structure which
+++ is a cross between a list and an array).
+++ Iteration over, and access to, elements of arrays is extremely fast
+++ (and often can be optimized to open-code).
+++ Insertion and deletion however is generally slow since an entirely new
+++ data structure must be created for the result.
+OneDimensionalArrayAggregate(S:Type): Category ==
+ FiniteLinearAggregate S with shallowlyMutable
+ add
+ parts x == [qelt(x, i) for i in minIndex x .. maxIndex x]
+ sort_!(f, a) == quickSort(f, a)$FiniteLinearAggregateSort(S, %)
+
+ any?(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ f qelt(a, i) => return true
+ false
+
+ every?(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ not(f qelt(a, i)) => return false
+ true
+
+ position(f:S -> Boolean, a:%) ==
+ for i in minIndex a .. maxIndex a repeat
+ f qelt(a, i) => return i
+ minIndex(a) - 1
+
+ find(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ f qelt(a, i) => return qelt(a, i)
+ "failed"
+
+ count(f:S->Boolean, a:%) ==
+ n:NonNegativeInteger := 0
+ for i in minIndex a .. maxIndex a repeat
+ if f(qelt(a, i)) then n := n+1
+ n
+
+ map_!(f, a) ==
+ for i in minIndex a .. maxIndex a repeat
+ qsetelt_!(a, i, f qelt(a, i))
+ a
+
+ setelt(a:%, s:UniversalSegment(Integer), x:S) ==
+ l := lo s; h := if hasHi s then hi s else maxIndex a
+ l < minIndex a or h > maxIndex a => error "index out of range"
+ for k in l..h repeat qsetelt_!(a, k, x)
+ x
+
+ reduce(f, a) ==
+ empty? a => error "cannot reduce an empty aggregate"
+ r := qelt(a, m := minIndex a)
+ for k in m+1 .. maxIndex a repeat r := f(r, qelt(a, k))
+ r
+
+ reduce(f, a, identity) ==
+ for k in minIndex a .. maxIndex a repeat
+ identity := f(identity, qelt(a, k))
+ identity
+
+ if S has SetCategory then
+ reduce(f, a, identity,absorber) ==
+ for k in minIndex a .. maxIndex a while identity ^= absorber
+ repeat identity := f(identity, qelt(a, k))
+ identity
+
+-- this is necessary since new has disappeared.
+ stupidnew: (NonNegativeInteger, %, %) -> %
+ stupidget: List % -> S
+-- a and b are not both empty if n > 0
+ stupidnew(n, a, b) ==
+ zero? n => empty()
+ new(n, (empty? a => qelt(b, minIndex b); qelt(a, minIndex a)))
+-- at least one element of l must be non-empty
+ stupidget l ==
+ for a in l repeat
+ not empty? a => return first a
+ error "Should not happen"
+
+ map(f, a, b) ==
+ m := max(minIndex a, minIndex b)
+ n := min(maxIndex a, maxIndex b)
+ l := max(0, n - m + 1)::NonNegativeInteger
+ c := stupidnew(l, a, b)
+ for i in minIndex(c).. for j in m..n repeat
+ qsetelt_!(c, i, f(qelt(a, j), qelt(b, j)))
+ c
+
+-- map(f, a, b, x) ==
+-- m := min(minIndex a, minIndex b)
+-- n := max(maxIndex a, maxIndex b)
+-- l := (n - m + 1)::NonNegativeInteger
+-- c := new l
+-- for i in minIndex(c).. for j in m..n repeat
+-- qsetelt_!(c, i, f(a(j, x), b(j, x)))
+-- c
+
+ merge(f, a, b) ==
+ r := stupidnew(#a + #b, a, b)
+ i := minIndex a
+ m := maxIndex a
+ j := minIndex b
+ n := maxIndex b
+ for k in minIndex(r).. while i <= m and j <= n repeat
+ if f(qelt(a, i), qelt(b, j)) then
+ qsetelt_!(r, k, qelt(a, i))
+ i := i+1
+ else
+ qsetelt_!(r, k, qelt(b, j))
+ j := j+1
+ for k in k.. for i in i..m repeat qsetelt_!(r, k, elt(a, i))
+ for k in k.. for j in j..n repeat qsetelt_!(r, k, elt(b, j))
+ r
+
+ elt(a:%, s:UniversalSegment(Integer)) ==
+ l := lo s
+ h := if hasHi s then hi s else maxIndex a
+ l < minIndex a or h > maxIndex a => error "index out of range"
+ r := stupidnew(max(0, h - l + 1)::NonNegativeInteger, a, a)
+ for k in minIndex r.. for i in l..h repeat
+ qsetelt_!(r, k, qelt(a, i))
+ r
+
+ insert(a:%, b:%, i:Integer) ==
+ m := minIndex b
+ n := maxIndex b
+ i < m or i > n => error "index out of range"
+ y := stupidnew(#a + #b, a, b)
+ for k in minIndex y.. for j in m..i-1 repeat
+ qsetelt_!(y, k, qelt(b, j))
+ for k in k.. for j in minIndex a .. maxIndex a repeat
+ qsetelt_!(y, k, qelt(a, j))
+ for k in k.. for j in i..n repeat qsetelt_!(y, k, qelt(b, j))
+ y
+
+ copy x ==
+ y := stupidnew(#x, x, x)
+ for i in minIndex x .. maxIndex x for j in minIndex y .. repeat
+ qsetelt_!(y, j, qelt(x, i))
+ y
+
+ copyInto_!(y, x, s) ==
+ s < minIndex y or s + #x > maxIndex y + 1 =>
+ error "index out of range"
+ for i in minIndex x .. maxIndex x for j in s.. repeat
+ qsetelt_!(y, j, qelt(x, i))
+ y
+
+ construct l ==
+-- a := new(#l)
+ empty? l => empty()
+ a := new(#l, first l)
+ for i in minIndex(a).. for x in l repeat qsetelt_!(a, i, x)
+ a
+
+ delete(a:%, s:UniversalSegment(Integer)) ==
+ l := lo s; h := if hasHi s then hi s else maxIndex a
+ l < minIndex a or h > maxIndex a => error "index out of range"
+ h < l => copy a
+ r := stupidnew((#a - h + l - 1)::NonNegativeInteger, a, a)
+ for k in minIndex(r).. for i in minIndex a..l-1 repeat
+ qsetelt_!(r, k, qelt(a, i))
+ for k in k.. for i in h+1 .. maxIndex a repeat
+ qsetelt_!(r, k, qelt(a, i))
+ r
+
+ delete(x:%, i:Integer) ==
+ i < minIndex x or i > maxIndex x => error "index out of range"
+ y := stupidnew((#x - 1)::NonNegativeInteger, x, x)
+ for i in minIndex(y).. for j in minIndex x..i-1 repeat
+ qsetelt_!(y, i, qelt(x, j))
+ for i in i .. for j in i+1 .. maxIndex x repeat
+ qsetelt_!(y, i, qelt(x, j))
+ y
+
+ reverse_! x ==
+ m := minIndex x
+ n := maxIndex x
+ for i in 0..((n-m) quo 2) repeat swap_!(x, m+i, n-i)
+ x
+
+ concat l ==
+ empty? l => empty()
+ n := _+/[#a for a in l]
+ i := minIndex(r := new(n, stupidget l))
+ for a in l repeat
+ copyInto_!(r, a, i)
+ i := i + #a
+ r
+
+ sorted?(f, a) ==
+ for i in minIndex(a)..maxIndex(a)-1 repeat
+ not f(qelt(a, i), qelt(a, i + 1)) => return false
+ true
+
+ concat(x:%, y:%) ==
+ z := stupidnew(#x + #y, x, y)
+ copyInto_!(z, x, i := minIndex z)
+ copyInto_!(z, y, i + #x)
+ z
+
+ if S has SetCategory then
+ x = y ==
+ #x ^= #y => false
+ for i in minIndex x .. maxIndex x repeat
+ not(qelt(x, i) = qelt(y, i)) => return false
+ true
+
+ coerce(r:%):OutputForm ==
+ bracket commaSeparate
+ [qelt(r, k)::OutputForm for k in minIndex r .. maxIndex r]
+
+ position(x:S, t:%, s:Integer) ==
+ n := maxIndex t
+ s < minIndex t or s > n => error "index out of range"
+ for k in s..n repeat
+ qelt(t, k) = x => return k
+ minIndex(t) - 1
+
+ if S has OrderedSet then
+ a < b ==
+ for i in minIndex a .. maxIndex a
+ for j in minIndex b .. maxIndex b repeat
+ qelt(a, i) ^= qelt(b, j) => return a.i < b.j
+ #a < #b
+
+
+@
+\section{category ELAGG ExtensibleLinearAggregate}
+<<category ELAGG ExtensibleLinearAggregate>>=
+)abbrev category ELAGG ExtensibleLinearAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An extensible aggregate is one which allows insertion and deletion of entries.
+++ These aggregates are models of lists and streams which are represented
+++ by linked structures so as to make insertion, deletion, and
+++ concatenation efficient. However, access to elements of these
+++ extensible aggregates is generally slow since access is made from the end.
+++ See \spadtype{FlexibleArray} for an exception.
+ExtensibleLinearAggregate(S:Type):Category == LinearAggregate S with
+ shallowlyMutable
+ concat_!: (%,S) -> %
+ ++ concat!(u,x) destructively adds element x to the end of u.
+ concat_!: (%,%) -> %
+ ++ concat!(u,v) destructively appends v to the end of u.
+ ++ v is unchanged
+ delete_!: (%,Integer) -> %
+ ++ delete!(u,i) destructively deletes the \axiom{i}th element of u.
+ delete_!: (%,UniversalSegment(Integer)) -> %
+ ++ delete!(u,i..j) destructively deletes elements u.i through u.j.
+ remove_!: (S->Boolean,%) -> %
+ ++ remove!(p,u) destructively removes all elements x of
+ ++ u such that \axiom{p(x)} is true.
+ insert_!: (S,%,Integer) -> %
+ ++ insert!(x,u,i) destructively inserts x into u at position i.
+ insert_!: (%,%,Integer) -> %
+ ++ insert!(v,u,i) destructively inserts aggregate v into u at position i.
+ merge_!: ((S,S)->Boolean,%,%) -> %
+ ++ merge!(p,u,v) destructively merges u and v using predicate p.
+ select_!: (S->Boolean,%) -> %
+ ++ select!(p,u) destructively changes u by keeping only values x such that
+ ++ \axiom{p(x)}.
+ if S has SetCategory then
+ remove_!: (S,%) -> %
+ ++ remove!(x,u) destructively removes all values x from u.
+ removeDuplicates_!: % -> %
+ ++ removeDuplicates!(u) destructively removes duplicates from u.
+ if S has OrderedSet then merge_!: (%,%) -> %
+ ++ merge!(u,v) destructively merges u and v in ascending order.
+ add
+ delete(x:%, i:Integer) == delete_!(copy x, i)
+ delete(x:%, i:UniversalSegment(Integer)) == delete_!(copy x, i)
+ remove(f:S -> Boolean, x:%) == remove_!(f, copy x)
+ insert(s:S, x:%, i:Integer) == insert_!(s, copy x, i)
+ insert(w:%, x:%, i:Integer) == insert_!(copy w, copy x, i)
+ select(f, x) == select_!(f, copy x)
+ concat(x:%, y:%) == concat_!(copy x, y)
+ concat(x:%, y:S) == concat_!(copy x, new(1, y))
+ concat_!(x:%, y:S) == concat_!(x, new(1, y))
+ if S has SetCategory then
+ remove(s:S, x:%) == remove_!(s, copy x)
+ remove_!(s:S, x:%) == remove_!(#1 = s, x)
+ removeDuplicates(x:%) == removeDuplicates_!(copy x)
+
+ if S has OrderedSet then
+ merge_!(x, y) == merge_!(_<$S, x, y)
+
+@
+\section{category LSAGG ListAggregate}
+<<category LSAGG ListAggregate>>=
+)abbrev category LSAGG ListAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A list aggregate is a model for a linked list data structure.
+++ A linked list is a versatile
+++ data structure. Insertion and deletion are efficient and
+++ searching is a linear operation.
+ListAggregate(S:Type): Category == Join(StreamAggregate S,
+ FiniteLinearAggregate S, ExtensibleLinearAggregate S) with
+ list: S -> %
+ ++ list(x) returns the list of one element x.
+ add
+ cycleMax ==> 1000
+
+ mergeSort: ((S, S) -> Boolean, %, Integer) -> %
+
+ sort_!(f, l) == mergeSort(f, l, #l)
+ list x == concat(x, empty())
+ reduce(f, x) ==
+ empty? x => error "reducing over an empty list needs the 3 argument form"
+ reduce(f, rest x, first x)
+ merge(f, p, q) == merge_!(f, copy p, copy q)
+
+ select_!(f, x) ==
+ while not empty? x and not f first x repeat x := rest x
+ empty? x => x
+ y := x
+ z := rest y
+ while not empty? z repeat
+ if f first z then (y := z; z := rest z)
+ else (z := rest z; setrest_!(y, z))
+ x
+
+ merge_!(f, p, q) ==
+ empty? p => q
+ empty? q => p
+ eq?(p, q) => error "cannot merge a list into itself"
+ if f(first p, first q)
+ then (r := t := p; p := rest p)
+ else (r := t := q; q := rest q)
+ while not empty? p and not empty? q repeat
+ if f(first p, first q)
+ then (setrest_!(t, p); t := p; p := rest p)
+ else (setrest_!(t, q); t := q; q := rest q)
+ setrest_!(t, if empty? p then q else p)
+ r
+
+ insert_!(s:S, x:%, i:Integer) ==
+ i < (m := minIndex x) => error "index out of range"
+ i = m => concat(s, x)
+ y := rest(x, (i - 1 - m)::NonNegativeInteger)
+ z := rest y
+ setrest_!(y, concat(s, z))
+ x
+
+ insert_!(w:%, x:%, i:Integer) ==
+ i < (m := minIndex x) => error "index out of range"
+ i = m => concat_!(w, x)
+ y := rest(x, (i - 1 - m)::NonNegativeInteger)
+ z := rest y
+ setrest_!(y, w)
+ concat_!(y, z)
+ x
+
+ remove_!(f:S -> Boolean, x:%) ==
+ while not empty? x and f first x repeat x := rest x
+ empty? x => x
+ p := x
+ q := rest x
+ while not empty? q repeat
+ if f first q then q := setrest_!(p, rest q)
+ else (p := q; q := rest q)
+ x
+
+ delete_!(x:%, i:Integer) ==
+ i < (m := minIndex x) => error "index out of range"
+ i = m => rest x
+ y := rest(x, (i - 1 - m)::NonNegativeInteger)
+ setrest_!(y, rest(y, 2))
+ x
+
+ delete_!(x:%, i:UniversalSegment(Integer)) ==
+ (l := lo i) < (m := minIndex x) => error "index out of range"
+ h := if hasHi i then hi i else maxIndex x
+ h < l => x
+ l = m => rest(x, (h + 1 - m)::NonNegativeInteger)
+ t := rest(x, (l - 1 - m)::NonNegativeInteger)
+ setrest_!(t, rest(t, (h - l + 2)::NonNegativeInteger))
+ x
+
+ find(f, x) ==
+ while not empty? x and not f first x repeat x := rest x
+ empty? x => "failed"
+ first x
+
+ position(f:S -> Boolean, x:%) ==
+ for k in minIndex(x).. while not empty? x and not f first x repeat
+ x := rest x
+ empty? x => minIndex(x) - 1
+ k
+
+ mergeSort(f, p, n) ==
+ if n = 2 and f(first rest p, first p) then p := reverse_! p
+ n < 3 => p
+ l := (n quo 2)::NonNegativeInteger
+ q := split_!(p, l)
+ p := mergeSort(f, p, l)
+ q := mergeSort(f, q, n - l)
+ merge_!(f, p, q)
+
+ sorted?(f, l) ==
+ empty? l => true
+ p := rest l
+ while not empty? p repeat
+ not f(first l, first p) => return false
+ p := rest(l := p)
+ true
+
+ reduce(f, x, i) ==
+ r := i
+ while not empty? x repeat (r := f(r, first x); x := rest x)
+ r
+
+ if S has SetCategory then
+ reduce(f, x, i,a) ==
+ r := i
+ while not empty? x and r ^= a repeat
+ r := f(r, first x)
+ x := rest x
+ r
+
+ new(n, s) ==
+ l := empty()
+ for k in 1..n repeat l := concat(s, l)
+ l
+
+ map(f, x, y) ==
+ z := empty()
+ while not empty? x and not empty? y repeat
+ z := concat(f(first x, first y), z)
+ x := rest x
+ y := rest y
+ reverse_! z
+
+-- map(f, x, y, d) ==
+-- z := empty()
+-- while not empty? x and not empty? y repeat
+-- z := concat(f(first x, first y), z)
+-- x := rest x
+-- y := rest y
+-- z := reverseInPlace z
+-- if not empty? x then
+-- z := concat_!(z, map(f(#1, d), x))
+-- if not empty? y then
+-- z := concat_!(z, map(f(d, #1), y))
+-- z
+
+ reverse_! x ==
+ empty? x => x
+ empty?(y := rest x) => x
+ setrest_!(x, empty())
+ while not empty? y repeat
+ z := rest y
+ setrest_!(y, x)
+ x := y
+ y := z
+ x
+
+ copy x ==
+ y := empty()
+ for k in 0.. while not empty? x repeat
+ k = cycleMax and cyclic? x => error "cyclic list"
+ y := concat(first x, y)
+ x := rest x
+ reverse_! y
+
+ copyInto_!(y, x, s) ==
+ s < (m := minIndex y) => error "index out of range"
+ z := rest(y, (s - m)::NonNegativeInteger)
+ while not empty? z and not empty? x repeat
+ setfirst_!(z, first x)
+ x := rest x
+ z := rest z
+ y
+
+ if S has SetCategory then
+ position(w, x, s) ==
+ s < (m := minIndex x) => error "index out of range"
+ x := rest(x, (s - m)::NonNegativeInteger)
+ for k in s.. while not empty? x and w ^= first x repeat
+ x := rest x
+ empty? x => minIndex x - 1
+ k
+
+ removeDuplicates_! l ==
+ p := l
+ while not empty? p repeat
+ p := setrest_!(p, remove_!(#1 = first p, rest p))
+ l
+
+ if S has OrderedSet then
+ x < y ==
+ while not empty? x and not empty? y repeat
+ first x ^= first y => return(first x < first y)
+ x := rest x
+ y := rest y
+ empty? x => not empty? y
+ false
+
+@
+\section{LSAGG.lsp BOOTSTRAP}
+{\bf LSAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LSAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LSAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LSAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |ListAggregate;CAT| (QUOTE NIL))
+
+(SETQ |ListAggregate;AL| (QUOTE NIL))
+
+(DEFUN |ListAggregate| (#1=#:G87500) (LET (#2=#:G87501) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |ListAggregate;AL|)) (CDR #2#)) (T (SETQ |ListAggregate;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|ListAggregate;| #1#))) |ListAggregate;AL|)) #2#))))
+
+(DEFUN |ListAggregate;| (|t#1|) (PROG (#1=#:G87499) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|ListAggregate;CAT|) ((QUOTE T) (LETT |ListAggregate;CAT| (|Join| (|StreamAggregate| (QUOTE |t#1|)) (|FiniteLinearAggregate| (QUOTE |t#1|)) (|ExtensibleLinearAggregate| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|list| (|$| |t#1|)) T))) NIL (QUOTE NIL) NIL)) . #2=(|ListAggregate|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |ListAggregate|) (|devaluate| |t#1|)))))))
+@
+\section{LSAGG-.lsp BOOTSTRAP}
+{\bf LSAGG-} depends on {\bf LSAGG}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf LSAGG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf LSAGG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LSAGG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |LSAGG-;sort!;M2A;1| (|f| |l| |$|) (|LSAGG-;mergeSort| |f| |l| (SPADCALL |l| (QREFELT |$| 9)) |$|))
+
+(DEFUN |LSAGG-;list;SA;2| (|x| |$|) (SPADCALL |x| (SPADCALL (QREFELT |$| 12)) (QREFELT |$| 13)))
+
+(DEFUN |LSAGG-;reduce;MAS;3| (|f| |x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 16)) (|error| "reducing over an empty list needs the 3 argument form")) ((QUOTE T) (SPADCALL |f| (SPADCALL |x| (QREFELT |$| 17)) (SPADCALL |x| (QREFELT |$| 18)) (QREFELT |$| 20)))))
+
+(DEFUN |LSAGG-;merge;M3A;4| (|f| |p| |q| |$|) (SPADCALL |f| (SPADCALL |p| (QREFELT |$| 22)) (SPADCALL |q| (QREFELT |$| 22)) (QREFELT |$| 23)))
+
+(DEFUN |LSAGG-;select!;M2A;5| (|f| |x| |$|) (PROG (|y| |z|) (RETURN (SEQ (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) |x|) ((QUOTE T) (SEQ (LETT |y| |x| |LSAGG-;select!;M2A;5|) (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |z| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (SPADCALL |z| (QREFELT |$| 18)) |f|) (SEQ (LETT |y| |z| |LSAGG-;select!;M2A;5|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|)))) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |z| (QREFELT |$| 17)) |LSAGG-;select!;M2A;5|) (EXIT (SPADCALL |y| |z| (QREFELT |$| 25)))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;merge!;M3A;6| (|f| |p| |q| |$|) (PROG (|r| |t|) (RETURN (SEQ (COND ((SPADCALL |p| (QREFELT |$| 16)) |q|) ((SPADCALL |q| (QREFELT |$| 16)) |p|) ((SPADCALL |p| |q| (QREFELT |$| 28)) (|error| "cannot merge a list into itself")) ((QUOTE T) (SEQ (COND ((SPADCALL (SPADCALL |p| (QREFELT |$| 18)) (SPADCALL |q| (QREFELT |$| 18)) |f|) (SEQ (LETT |r| (LETT |t| |p| |LSAGG-;merge!;M3A;6|) |LSAGG-;merge!;M3A;6|) (EXIT (LETT |p| (SPADCALL |p| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|)))) ((QUOTE T) (SEQ (LETT |r| (LETT |t| |q| |LSAGG-;merge!;M3A;6|) |LSAGG-;merge!;M3A;6|) (EXIT (LETT |q| (SPADCALL |q| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|))))) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |p| (QREFELT |$| 16)) (SPADCALL |q| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (SPADCALL |p| (QREFELT |$| 18)) (SPADCALL |q| (QREFELT |$| 18)) |f|) (SEQ (SPADCALL |t| |p| (QREFELT |$| 25)) (LETT |t| |p| |LSAGG-;merge!;M3A;6|) (EXIT (LETT |p| (SPADCALL |p| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|)))) ((QUOTE T) (SEQ (SPADCALL |t| |q| (QREFELT |$| 25)) (LETT |t| |q| |LSAGG-;merge!;M3A;6|) (EXIT (LETT |q| (SPADCALL |q| (QREFELT |$| 17)) |LSAGG-;merge!;M3A;6|))))))) NIL (GO G190) G191 (EXIT NIL)) (SPADCALL |t| (COND ((SPADCALL |p| (QREFELT |$| 16)) |q|) ((QUOTE T) |p|)) (QREFELT |$| 25)) (EXIT |r|))))))))
+
+(DEFUN |LSAGG-;insert!;SAIA;7| (|s| |x| |i| |$|) (PROG (|m| #1=#:G87547 |y| |z|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;insert!;SAIA;7|) (EXIT (COND ((|<| |i| |m|) (|error| "index out of range")) ((EQL |i| |m|) (SPADCALL |s| |x| (QREFELT |$| 13))) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# (|-| (|-| |i| 1) |m|) |LSAGG-;insert!;SAIA;7|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;insert!;SAIA;7|) (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;insert!;SAIA;7|) (SPADCALL |y| (SPADCALL |s| |z| (QREFELT |$| 13)) (QREFELT |$| 25)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;insert!;2AIA;8| (|w| |x| |i| |$|) (PROG (|m| #1=#:G87551 |y| |z|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;insert!;2AIA;8|) (EXIT (COND ((|<| |i| |m|) (|error| "index out of range")) ((EQL |i| |m|) (SPADCALL |w| |x| (QREFELT |$| 34))) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# (|-| (|-| |i| 1) |m|) |LSAGG-;insert!;2AIA;8|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;insert!;2AIA;8|) (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;insert!;2AIA;8|) (SPADCALL |y| |w| (QREFELT |$| 25)) (SPADCALL |y| |z| (QREFELT |$| 34)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;remove!;M2A;9| (|f| |x| |$|) (PROG (|p| |q|) (RETURN (SEQ (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;remove!;M2A;9|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) |x|) ((QUOTE T) (SEQ (LETT |p| |x| |LSAGG-;remove!;M2A;9|) (LETT |q| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;remove!;M2A;9|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |q| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (SPADCALL |q| (QREFELT |$| 18)) |f|) (LETT |q| (SPADCALL |p| (SPADCALL |q| (QREFELT |$| 17)) (QREFELT |$| 25)) |LSAGG-;remove!;M2A;9|)) ((QUOTE T) (SEQ (LETT |p| |q| |LSAGG-;remove!;M2A;9|) (EXIT (LETT |q| (SPADCALL |q| (QREFELT |$| 17)) |LSAGG-;remove!;M2A;9|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;delete!;AIA;10| (|x| |i| |$|) (PROG (|m| #1=#:G87564 |y|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;delete!;AIA;10|) (EXIT (COND ((|<| |i| |m|) (|error| "index out of range")) ((EQL |i| |m|) (SPADCALL |x| (QREFELT |$| 17))) ((QUOTE T) (SEQ (LETT |y| (SPADCALL |x| (PROG1 (LETT #1# (|-| (|-| |i| 1) |m|) |LSAGG-;delete!;AIA;10|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;delete!;AIA;10|) (SPADCALL |y| (SPADCALL |y| 2 (QREFELT |$| 32)) (QREFELT |$| 25)) (EXIT |x|)))))))))
+
+(DEFUN |LSAGG-;delete!;AUsA;11| (|x| |i| |$|) (PROG (|l| |m| |h| #1=#:G87569 #2=#:G87570 |t| #3=#:G87571) (RETURN (SEQ (LETT |l| (SPADCALL |i| (QREFELT |$| 39)) |LSAGG-;delete!;AUsA;11|) (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;delete!;AUsA;11|) (EXIT (COND ((|<| |l| |m|) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |h| (COND ((SPADCALL |i| (QREFELT |$| 40)) (SPADCALL |i| (QREFELT |$| 41))) ((QUOTE T) (SPADCALL |x| (QREFELT |$| 42)))) |LSAGG-;delete!;AUsA;11|) (EXIT (COND ((|<| |h| |l|) |x|) ((EQL |l| |m|) (SPADCALL |x| (PROG1 (LETT #1# (|-| (|+| |h| 1) |m|) |LSAGG-;delete!;AUsA;11|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32))) ((QUOTE T) (SEQ (LETT |t| (SPADCALL |x| (PROG1 (LETT #2# (|-| (|-| |l| 1) |m|) |LSAGG-;delete!;AUsA;11|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) (QREFELT |$| 32)) |LSAGG-;delete!;AUsA;11|) (SPADCALL |t| (SPADCALL |t| (PROG1 (LETT #3# (|+| (|-| |h| |l|) 2) |LSAGG-;delete!;AUsA;11|) (|check-subtype| (|>=| #3# 0) (QUOTE (|NonNegativeInteger|)) #3#)) (QREFELT |$| 32)) (QREFELT |$| 25)) (EXIT |x|)))))))))))))
+
+(DEFUN |LSAGG-;find;MAU;12| (|f| |x| |$|) (SEQ (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;find;MAU;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (CONS 1 "failed")) ((QUOTE T) (CONS 0 (SPADCALL |x| (QREFELT |$| 18))))))))
+
+(DEFUN |LSAGG-;position;MAI;13| (|f| |x| |$|) (PROG (|k|) (RETURN (SEQ (SEQ (LETT |k| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;position;MAI;13|) G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |f|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;position;MAI;13|))) (LETT |k| (|+| |k| 1) |LSAGG-;position;MAI;13|) (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (|-| (SPADCALL |x| (QREFELT |$| 31)) 1)) ((QUOTE T) |k|)))))))
+
+(DEFUN |LSAGG-;mergeSort| (|f| |p| |n| |$|) (PROG (#1=#:G87593 |l| |q|) (RETURN (SEQ (COND ((EQL |n| 2) (COND ((SPADCALL (SPADCALL (SPADCALL |p| (QREFELT |$| 17)) (QREFELT |$| 18)) (SPADCALL |p| (QREFELT |$| 18)) |f|) (LETT |p| (SPADCALL |p| (QREFELT |$| 47)) |LSAGG-;mergeSort|))))) (EXIT (COND ((|<| |n| 3) |p|) ((QUOTE T) (SEQ (LETT |l| (PROG1 (LETT #1# (QUOTIENT2 |n| 2) |LSAGG-;mergeSort|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) |LSAGG-;mergeSort|) (LETT |q| (SPADCALL |p| |l| (QREFELT |$| 48)) |LSAGG-;mergeSort|) (LETT |p| (|LSAGG-;mergeSort| |f| |p| |l| |$|) |LSAGG-;mergeSort|) (LETT |q| (|LSAGG-;mergeSort| |f| |q| (|-| |n| |l|) |$|) |LSAGG-;mergeSort|) (EXIT (SPADCALL |f| |p| |q| (QREFELT |$| 23)))))))))))
+
+(DEFUN |LSAGG-;sorted?;MAB;15| (|f| |l| |$|) (PROG (#1=#:G87603 |p|) (RETURN (SEQ (EXIT (COND ((SPADCALL |l| (QREFELT |$| 16)) (QUOTE T)) ((QUOTE T) (SEQ (LETT |p| (SPADCALL |l| (QREFELT |$| 17)) |LSAGG-;sorted?;MAB;15|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |p| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((NULL (SPADCALL (SPADCALL |l| (QREFELT |$| 18)) (SPADCALL |p| (QREFELT |$| 18)) |f|)) (PROGN (LETT #1# (QUOTE NIL) |LSAGG-;sorted?;MAB;15|) (GO #1#))) ((QUOTE T) (LETT |p| (SPADCALL (LETT |l| |p| |LSAGG-;sorted?;MAB;15|) (QREFELT |$| 17)) |LSAGG-;sorted?;MAB;15|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (QUOTE T)))))) #1# (EXIT #1#)))))
+
+(DEFUN |LSAGG-;reduce;MA2S;16| (|f| |x| |i| |$|) (PROG (|r|) (RETURN (SEQ (LETT |r| |i| |LSAGG-;reduce;MA2S;16|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |r| (SPADCALL |r| (SPADCALL |x| (QREFELT |$| 18)) |f|) |LSAGG-;reduce;MA2S;16|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;reduce;MA2S;16|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |r|)))))
+
+(DEFUN |LSAGG-;reduce;MA3S;17| (|f| |x| |i| |a| |$|) (PROG (|r|) (RETURN (SEQ (LETT |r| |i| |LSAGG-;reduce;MA3S;17|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |r| |a| (QREFELT |$| 51))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |r| (SPADCALL |r| (SPADCALL |x| (QREFELT |$| 18)) |f|) |LSAGG-;reduce;MA3S;17|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;reduce;MA3S;17|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |r|)))))
+
+(DEFUN |LSAGG-;new;NniSA;18| (|n| |s| |$|) (PROG (|k| |l|) (RETURN (SEQ (LETT |l| (SPADCALL (QREFELT |$| 12)) |LSAGG-;new;NniSA;18|) (SEQ (LETT |k| 1 |LSAGG-;new;NniSA;18|) G190 (COND ((QSGREATERP |k| |n|) (GO G191))) (SEQ (EXIT (LETT |l| (SPADCALL |s| |l| (QREFELT |$| 13)) |LSAGG-;new;NniSA;18|))) (LETT |k| (QSADD1 |k|) |LSAGG-;new;NniSA;18|) (GO G190) G191 (EXIT NIL)) (EXIT |l|)))))
+
+(DEFUN |LSAGG-;map;M3A;19| (|f| |x| |y| |$|) (PROG (|z|) (RETURN (SEQ (LETT |z| (SPADCALL (QREFELT |$| 12)) |LSAGG-;map;M3A;19|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |y| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |z| (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) (SPADCALL |y| (QREFELT |$| 18)) |f|) |z| (QREFELT |$| 13)) |LSAGG-;map;M3A;19|) (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;map;M3A;19|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;map;M3A;19|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |z| (QREFELT |$| 47)))))))
+
+(DEFUN |LSAGG-;reverse!;2A;20| (|x| |$|) (PROG (|z| |y|) (RETURN (SEQ (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL (LETT |y| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;reverse!;2A;20|) (QREFELT |$| 16))) |x|) ((QUOTE T) (SEQ (SPADCALL |x| (SPADCALL (QREFELT |$| 12)) (QREFELT |$| 25)) (SEQ G190 (COND ((NULL (COND ((SPADCALL |y| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |z| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;reverse!;2A;20|) (SPADCALL |y| |x| (QREFELT |$| 25)) (LETT |x| |y| |LSAGG-;reverse!;2A;20|) (EXIT (LETT |y| |z| |LSAGG-;reverse!;2A;20|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |x|))))))))
+
+(DEFUN |LSAGG-;copy;2A;21| (|x| |$|) (PROG (|k| |y|) (RETURN (SEQ (LETT |y| (SPADCALL (QREFELT |$| 12)) |LSAGG-;copy;2A;21|) (SEQ (LETT |k| 0 |LSAGG-;copy;2A;21|) G190 (COND ((NULL (COND ((SPADCALL |x| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQL |k| 1000) (COND ((SPADCALL |x| (QREFELT |$| 56)) (EXIT (|error| "cyclic list")))))) (LETT |y| (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) |y| (QREFELT |$| 13)) |LSAGG-;copy;2A;21|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;copy;2A;21|))) (LETT |k| (QSADD1 |k|) |LSAGG-;copy;2A;21|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |y| (QREFELT |$| 47)))))))
+
+(DEFUN |LSAGG-;copyInto!;2AIA;22| (|y| |x| |s| |$|) (PROG (|m| #1=#:G87636 |z|) (RETURN (SEQ (LETT |m| (SPADCALL |y| (QREFELT |$| 31)) |LSAGG-;copyInto!;2AIA;22|) (EXIT (COND ((|<| |s| |m|) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |z| (SPADCALL |y| (PROG1 (LETT #1# (|-| |s| |m|) |LSAGG-;copyInto!;2AIA;22|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;copyInto!;2AIA;22|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |z| (QREFELT |$| 16)) (SPADCALL |x| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |z| (SPADCALL |x| (QREFELT |$| 18)) (QREFELT |$| 58)) (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;copyInto!;2AIA;22|) (EXIT (LETT |z| (SPADCALL |z| (QREFELT |$| 17)) |LSAGG-;copyInto!;2AIA;22|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |y|)))))))))
+
+(DEFUN |LSAGG-;position;SA2I;23| (|w| |x| |s| |$|) (PROG (|m| #1=#:G87644 |k|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 31)) |LSAGG-;position;SA2I;23|) (EXIT (COND ((|<| |s| |m|) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |x| (SPADCALL |x| (PROG1 (LETT #1# (|-| |s| |m|) |LSAGG-;position;SA2I;23|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |LSAGG-;position;SA2I;23|) (SEQ (LETT |k| |s| |LSAGG-;position;SA2I;23|) G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |w| (SPADCALL |x| (QREFELT |$| 18)) (QREFELT |$| 51))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;position;SA2I;23|))) (LETT |k| (|+| |k| 1) |LSAGG-;position;SA2I;23|) (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (|-| (SPADCALL |x| (QREFELT |$| 31)) 1)) ((QUOTE T) |k|)))))))))))
+
+(DEFUN |LSAGG-;removeDuplicates!;2A;24| (|l| |$|) (PROG (|p|) (RETURN (SEQ (LETT |p| |l| |LSAGG-;removeDuplicates!;2A;24|) (SEQ G190 (COND ((NULL (COND ((SPADCALL |p| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |p| (SPADCALL |p| (SPADCALL (CONS (FUNCTION |LSAGG-;removeDuplicates!;2A;24!0|) (VECTOR |$| |p|)) (SPADCALL |p| (QREFELT |$| 17)) (QREFELT |$| 61)) (QREFELT |$| 25)) |LSAGG-;removeDuplicates!;2A;24|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |l|)))))
+
+(DEFUN |LSAGG-;removeDuplicates!;2A;24!0| (|#1| |$$|) (PROG (|$|) (LETT |$| (QREFELT |$$| 0) |LSAGG-;removeDuplicates!;2A;24|) (RETURN (PROGN (SPADCALL |#1| (SPADCALL (QREFELT |$$| 1) (QREFELT |$| 18)) (QREFELT |$| 51))))))
+
+(DEFUN |LSAGG-;<;2AB;25| (|x| |y| |$|) (PROG (#1=#:G87662) (RETURN (SEQ (EXIT (SEQ (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |x| (QREFELT |$| 16)) (SPADCALL |y| (QREFELT |$| 16))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((NULL (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) (SPADCALL |y| (QREFELT |$| 18)) (QREFELT |$| 51))) (PROGN (LETT #1# (SPADCALL (SPADCALL |x| (QREFELT |$| 18)) (SPADCALL |y| (QREFELT |$| 18)) (QREFELT |$| 63)) |LSAGG-;<;2AB;25|) (GO #1#))) ((QUOTE T) (SEQ (LETT |x| (SPADCALL |x| (QREFELT |$| 17)) |LSAGG-;<;2AB;25|) (EXIT (LETT |y| (SPADCALL |y| (QREFELT |$| 17)) |LSAGG-;<;2AB;25|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((SPADCALL |x| (QREFELT |$| 16)) (COND ((SPADCALL |y| (QREFELT |$| 16)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) ((QUOTE T) (QUOTE NIL)))))) #1# (EXIT #1#)))))
+
+(DEFUN |ListAggregate&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|ListAggregate&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |ListAggregate&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 66) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|HasCategory| |#2| (QUOTE (|SetCategory|))) (QSETREFV |$| 52 (CONS (|dispatchFunction| |LSAGG-;reduce;MA3S;17|) |$|)))) (COND ((|HasCategory| |#2| (QUOTE (|SetCategory|))) (PROGN (QSETREFV |$| 60 (CONS (|dispatchFunction| |LSAGG-;position;SA2I;23|) |$|)) (QSETREFV |$| 62 (CONS (|dispatchFunction| |LSAGG-;removeDuplicates!;2A;24|) |$|))))) (COND ((|HasCategory| |#2| (QUOTE (|OrderedSet|))) (QSETREFV |$| 64 (CONS (|dispatchFunction| |LSAGG-;<;2AB;25|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |ListAggregate&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|NonNegativeInteger|) (0 . |#|) (|Mapping| 15 7 7) |LSAGG-;sort!;M2A;1| (5 . |empty|) (9 . |concat|) |LSAGG-;list;SA;2| (|Boolean|) (15 . |empty?|) (20 . |rest|) (25 . |first|) (|Mapping| 7 7 7) (30 . |reduce|) |LSAGG-;reduce;MAS;3| (37 . |copy|) (42 . |merge!|) |LSAGG-;merge;M3A;4| (49 . |setrest!|) (|Mapping| 15 7) |LSAGG-;select!;M2A;5| (55 . |eq?|) |LSAGG-;merge!;M3A;6| (|Integer|) (61 . |minIndex|) (66 . |rest|) |LSAGG-;insert!;SAIA;7| (72 . |concat!|) |LSAGG-;insert!;2AIA;8| |LSAGG-;remove!;M2A;9| |LSAGG-;delete!;AIA;10| (|UniversalSegment| 30) (78 . |lo|) (83 . |hasHi|) (88 . |hi|) (93 . |maxIndex|) |LSAGG-;delete!;AUsA;11| (|Union| 7 (QUOTE "failed")) |LSAGG-;find;MAU;12| |LSAGG-;position;MAI;13| (98 . |reverse!|) (103 . |split!|) |LSAGG-;sorted?;MAB;15| |LSAGG-;reduce;MA2S;16| (109 . |=|) (115 . |reduce|) |LSAGG-;new;NniSA;18| |LSAGG-;map;M3A;19| |LSAGG-;reverse!;2A;20| (123 . |cyclic?|) |LSAGG-;copy;2A;21| (128 . |setfirst!|) |LSAGG-;copyInto!;2AIA;22| (134 . |position|) (141 . |remove!|) (147 . |removeDuplicates!|) (152 . |<|) (158 . |<|) (|Mapping| 7 7))) (QUOTE #(|sorted?| 164 |sort!| 170 |select!| 176 |reverse!| 182 |removeDuplicates!| 187 |remove!| 192 |reduce| 198 |position| 219 |new| 232 |merge!| 238 |merge| 245 |map| 252 |list| 259 |insert!| 264 |find| 278 |delete!| 284 |copyInto!| 296 |copy| 303 |<| 308)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 64 (QUOTE (1 6 8 0 9 0 6 0 12 2 6 0 7 0 13 1 6 15 0 16 1 6 0 0 17 1 6 7 0 18 3 6 7 19 0 7 20 1 6 0 0 22 3 6 0 10 0 0 23 2 6 0 0 0 25 2 6 15 0 0 28 1 6 30 0 31 2 6 0 0 8 32 2 6 0 0 0 34 1 38 30 0 39 1 38 15 0 40 1 38 30 0 41 1 6 30 0 42 1 6 0 0 47 2 6 0 0 30 48 2 7 15 0 0 51 4 0 7 19 0 7 7 52 1 6 15 0 56 2 6 7 0 7 58 3 0 30 7 0 30 60 2 6 0 26 0 61 1 0 0 0 62 2 7 15 0 0 63 2 0 15 0 0 64 2 0 15 10 0 49 2 0 0 10 0 11 2 0 0 26 0 27 1 0 0 0 55 1 0 0 0 62 2 0 0 26 0 36 3 0 7 19 0 7 50 4 0 7 19 0 7 7 52 2 0 7 19 0 21 2 0 30 26 0 46 3 0 30 7 0 30 60 2 0 0 8 7 53 3 0 0 10 0 0 29 3 0 0 10 0 0 24 3 0 0 19 0 0 54 1 0 0 7 14 3 0 0 7 0 30 33 3 0 0 0 0 30 35 2 0 44 26 0 45 2 0 0 0 38 43 2 0 0 0 30 37 3 0 0 0 0 30 59 1 0 0 0 57 2 0 15 0 0 64)))))) (QUOTE |lookupComplete|)))
+@
+\section{category ALAGG AssociationListAggregate}
+<<category ALAGG AssociationListAggregate>>=
+)abbrev category ALAGG AssociationListAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An association list is a list of key entry pairs which may be viewed
+++ as a table. It is a poor mans version of a table:
+++ searching for a key is a linear operation.
+AssociationListAggregate(Key:SetCategory,Entry:SetCategory): Category ==
+ Join(TableAggregate(Key, Entry), ListAggregate Record(key:Key,entry:Entry)) with
+ assoc: (Key, %) -> Union(Record(key:Key,entry:Entry), "failed")
+ ++ assoc(k,u) returns the element x in association list u stored
+ ++ with key k, or "failed" if u has no key k.
+
+@
+\section{ALAGG.lsp BOOTSTRAP}
+{\bf ALAGG} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ALAGG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ALAGG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ALAGG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |AssociationListAggregate;CAT| (QUOTE NIL))
+
+(SETQ |AssociationListAggregate;AL| (QUOTE NIL))
+
+(DEFUN |AssociationListAggregate| (|&REST| #1=#:G88404 |&AUX| #2=#:G88402) (DSETQ #2# #1#) (LET (#3=#:G88403) (COND ((SETQ #3# (|assoc| (|devaluateList| #2#) |AssociationListAggregate;AL|)) (CDR #3#)) (T (SETQ |AssociationListAggregate;AL| (|cons5| (CONS (|devaluateList| #2#) (SETQ #3# (APPLY (FUNCTION |AssociationListAggregate;|) #2#))) |AssociationListAggregate;AL|)) #3#))))
+
+(DEFUN |AssociationListAggregate;| (|t#1| |t#2|) (PROG (#1=#:G88401) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1| |t#2|)) (LIST (|devaluate| |t#1|) (|devaluate| |t#2|))) (|sublisV| (PAIR (QUOTE (#2=#:G88400)) (LIST (QUOTE (|Record| (|:| |key| |t#1|) (|:| |entry| |t#2|))))) (COND (|AssociationListAggregate;CAT|) ((QUOTE T) (LETT |AssociationListAggregate;CAT| (|Join| (|TableAggregate| (QUOTE |t#1|) (QUOTE |t#2|)) (|ListAggregate| (QUOTE #2#)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|assoc| ((|Union| (|Record| (|:| |key| |t#1|) (|:| |entry| |t#2|)) "failed") |t#1| |$|)) T))) NIL (QUOTE NIL) NIL)) . #3=(|AssociationListAggregate|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |AssociationListAggregate|) (|devaluate| |t#1|) (|devaluate| |t#2|)))))))
+@
+\section{category SRAGG StringAggregate}
+<<category SRAGG StringAggregate>>=
+)abbrev category SRAGG StringAggregate
+++ Author: Stephen Watt and Michael Monagan. revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A string aggregate is a category for strings, that is,
+++ one dimensional arrays of characters.
+StringAggregate: Category == OneDimensionalArrayAggregate Character with
+ lowerCase : % -> %
+ ++ lowerCase(s) returns the string with all characters in lower case.
+ lowerCase_!: % -> %
+ ++ lowerCase!(s) destructively replaces the alphabetic characters
+ ++ in s by lower case.
+ upperCase : % -> %
+ ++ upperCase(s) returns the string with all characters in upper case.
+ upperCase_!: % -> %
+ ++ upperCase!(s) destructively replaces the alphabetic characters
+ ++ in s by upper case characters.
+ prefix? : (%, %) -> Boolean
+ ++ prefix?(s,t) tests if the string s is the initial substring of t.
+ ++ Note: \axiom{prefix?(s,t) == reduce(and,[s.i = t.i for i in 0..maxIndex s])}.
+ suffix? : (%, %) -> Boolean
+ ++ suffix?(s,t) tests if the string s is the final substring of t.
+ ++ Note: \axiom{suffix?(s,t) == reduce(and,[s.i = t.(n - m + i) for i in 0..maxIndex s])}
+ ++ where m and n denote the maxIndex of s and t respectively.
+ substring?: (%, %, Integer) -> Boolean
+ ++ substring?(s,t,i) tests if s is a substring of t beginning at
+ ++ index i.
+ ++ Note: \axiom{substring?(s,t,0) = prefix?(s,t)}.
+ match: (%, %, Character) -> NonNegativeInteger
+ ++ match(p,s,wc) tests if pattern \axiom{p} matches subject \axiom{s}
+ ++ where \axiom{wc} is a wild card character. If no match occurs,
+ ++ the index \axiom{0} is returned; otheriwse, the value returned
+ ++ is the first index of the first character in the subject matching
+ ++ the subject (excluding that matched by an initial wild-card).
+ ++ For example, \axiom{match("*to*","yorktown","*")} returns \axiom{5}
+ ++ indicating a successful match starting at index \axiom{5} of
+ ++ \axiom{"yorktown"}.
+ match?: (%, %, Character) -> Boolean
+ ++ match?(s,t,c) tests if s matches t except perhaps for
+ ++ multiple and consecutive occurrences of character c.
+ ++ Typically c is the blank character.
+ replace : (%, UniversalSegment(Integer), %) -> %
+ ++ replace(s,i..j,t) replaces the substring \axiom{s(i..j)} of s by string t.
+ position : (%, %, Integer) -> Integer
+ ++ position(s,t,i) returns the position j of the substring s in string t,
+ ++ where \axiom{j >= i} is required.
+ position : (CharacterClass, %, Integer) -> Integer
+ ++ position(cc,t,i) returns the position \axiom{j >= i} in t of
+ ++ the first character belonging to cc.
+ coerce : Character -> %
+ ++ coerce(c) returns c as a string s with the character c.
+
+ split: (%, Character) -> List %
+ ++ split(s,c) returns a list of substrings delimited by character c.
+ split: (%, CharacterClass) -> List %
+ ++ split(s,cc) returns a list of substrings delimited by characters in cc.
+
+ trim: (%, Character) -> %
+ ++ trim(s,c) returns s with all characters c deleted from right
+ ++ and left ends.
+ ++ For example, \axiom{trim(" abc ", char " ")} returns \axiom{"abc"}.
+ trim: (%, CharacterClass) -> %
+ ++ trim(s,cc) returns s with all characters in cc deleted from right
+ ++ and left ends.
+ ++ For example, \axiom{trim("(abc)", charClass "()")} returns \axiom{"abc"}.
+ leftTrim: (%, Character) -> %
+ ++ leftTrim(s,c) returns s with all leading characters c deleted.
+ ++ For example, \axiom{leftTrim(" abc ", char " ")} returns \axiom{"abc "}.
+ leftTrim: (%, CharacterClass) -> %
+ ++ leftTrim(s,cc) returns s with all leading characters in cc deleted.
+ ++ For example, \axiom{leftTrim("(abc)", charClass "()")} returns \axiom{"abc)"}.
+ rightTrim: (%, Character) -> %
+ ++ rightTrim(s,c) returns s with all trailing occurrences of c deleted.
+ ++ For example, \axiom{rightTrim(" abc ", char " ")} returns \axiom{" abc"}.
+ rightTrim: (%, CharacterClass) -> %
+ ++ rightTrim(s,cc) returns s with all trailing occurences of
+ ++ characters in cc deleted.
+ ++ For example, \axiom{rightTrim("(abc)", charClass "()")} returns \axiom{"(abc"}.
+ elt: (%, %) -> %
+ ++ elt(s,t) returns the concatenation of s and t. It is provided to
+ ++ allow juxtaposition of strings to work as concatenation.
+ ++ For example, \axiom{"smoo" "shed"} returns \axiom{"smooshed"}.
+ add
+ trim(s: %, c: Character) == leftTrim(rightTrim(s, c), c)
+ trim(s: %, cc: CharacterClass) == leftTrim(rightTrim(s, cc), cc)
+
+ lowerCase s == lowerCase_! copy s
+ upperCase s == upperCase_! copy s
+ prefix?(s, t) == substring?(s, t, minIndex t)
+ coerce(c:Character):% == new(1, c)
+ elt(s:%, t:%): % == concat(s,t)$%
+
+@
+\section{category BTAGG BitAggregate}
+<<category BTAGG BitAggregate>>=
+)abbrev category BTAGG BitAggregate
+++ Author: Michael Monagan; revised by Manuel Bronstein and Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: April 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The bit aggregate category models aggregates representing large
+++ quantities of Boolean data.
+BitAggregate(): Category ==
+ Join(OrderedSet, Logic, OneDimensionalArrayAggregate Boolean) with
+ "not": % -> %
+ ++ not(b) returns the logical {\em not} of bit aggregate
+ ++ \axiom{b}.
+ "^" : % -> %
+ ++ ^ b returns the logical {\em not} of bit aggregate
+ ++ \axiom{b}.
+ nand : (%, %) -> %
+ ++ nand(a,b) returns the logical {\em nand} of bit aggregates \axiom{a}
+ ++ and \axiom{b}.
+ nor : (%, %) -> %
+ ++ nor(a,b) returns the logical {\em nor} of bit aggregates \axiom{a} and
+ ++ \axiom{b}.
+ _and : (%, %) -> %
+ ++ a and b returns the logical {\em and} of bit aggregates \axiom{a} and
+ ++ \axiom{b}.
+ _or : (%, %) -> %
+ ++ a or b returns the logical {\em or} of bit aggregates \axiom{a} and
+ ++ \axiom{b}.
+ xor : (%, %) -> %
+ ++ xor(a,b) returns the logical {\em exclusive-or} of bit aggregates
+ ++ \axiom{a} and \axiom{b}.
+
+ add
+ not v == map(_not, v)
+ _^ v == map(_not, v)
+ _~(v) == map(_~, v)
+ _/_\(v, u) == map(_/_\, v, u)
+ _\_/(v, u) == map(_\_/, v, u)
+ nand(v, u) == map(nand, v, u)
+ nor(v, u) == map(nor, v, u)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category AGG Aggregate>>
+<<category HOAGG HomogeneousAggregate>>
+<<category CLAGG Collection>>
+<<category BGAGG BagAggregate>>
+<<category SKAGG StackAggregate>>
+<<category QUAGG QueueAggregate>>
+<<category DQAGG DequeueAggregate>>
+<<category PRQAGG PriorityQueueAggregate>>
+<<category DIOPS DictionaryOperations>>
+<<category DIAGG Dictionary>>
+<<category MDAGG MultiDictionary>>
+<<category SETAGG SetAggregate>>
+<<category FSAGG FiniteSetAggregate>>
+<<category MSETAGG MultisetAggregate>>
+<<category OMSAGG OrderedMultisetAggregate>>
+<<category KDAGG KeyedDictionary>>
+<<category ELTAB Eltable>>
+<<category ELTAGG EltableAggregate>>
+<<category IXAGG IndexedAggregate>>
+<<category TBAGG TableAggregate>>
+<<category RCAGG RecursiveAggregate>>
+<<category BRAGG BinaryRecursiveAggregate>>
+<<category DLAGG DoublyLinkedAggregate>>
+<<category URAGG UnaryRecursiveAggregate>>
+<<category STAGG StreamAggregate>>
+<<category LNAGG LinearAggregate>>
+<<category FLAGG FiniteLinearAggregate>>
+<<category A1AGG OneDimensionalArrayAggregate>>
+<<category ELAGG ExtensibleLinearAggregate>>
+<<category LSAGG ListAggregate>>
+<<category ALAGG AssociationListAggregate>>
+<<category SRAGG StringAggregate>>
+<<category BTAGG BitAggregate>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/aggcat2.spad.pamphlet b/src/algebra/aggcat2.spad.pamphlet
new file mode 100644
index 00000000..6a4c57be
--- /dev/null
+++ b/src/algebra/aggcat2.spad.pamphlet
@@ -0,0 +1,223 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra aggcat2.spad}
+\author{Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FLAGG2 FiniteLinearAggregateFunctions2}
+<<package FLAGG2 FiniteLinearAggregateFunctions2>>=
+)abbrev package FLAGG2 FiniteLinearAggregateFunctions2
+--% FiniteLinearAggregateFunctions2
+
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: ???
+++ Description:
+++ FiniteLinearAggregateFunctions2 provides functions involving two
+++ FiniteLinearAggregates where the underlying domains might be
+++ different. An example of this might be creating a list of rational
+++ numbers by mapping a function across a list of integers where the
+++ function divides each integer by 1000.
+
+FiniteLinearAggregateFunctions2(S, A, R, B):
+ Exports == Implementation where
+ S, R: Type
+ A : FiniteLinearAggregate S
+ B : FiniteLinearAggregate R
+
+ Exports ==> with
+ map : (S -> R, A) -> B ++ map(f,a) applies function f to each member of aggregate
+ ++ \spad{a} resulting in a new aggregate over a
+ ++ possibly different underlying domain.
+
+ reduce : ((S, R) -> R, A, R) -> R ++ reduce(f,a,r) applies function f to each
+ ++ successive element of the
+ ++ aggregate \spad{a} and an accumulant initialized to r.
+ ++ For example,
+ ++ \spad{reduce(_+$Integer,[1,2,3],0)}
+ ++ does \spad{3+(2+(1+0))}. Note: third argument r
+ ++ may be regarded as the
+ ++ identity element for the function f.
+
+ scan : ((S, R) -> R, A, R) -> B ++ scan(f,a,r) successively applies
+ ++ \spad{reduce(f,x,r)} to more and more leading sub-aggregates
+ ++ x of aggregrate \spad{a}.
+ ++ More precisely, if \spad{a} is \spad{[a1,a2,...]}, then
+ ++ \spad{scan(f,a,r)} returns
+ ++ \spad{[reduce(f,[a1],r),reduce(f,[a1,a2],r),...]}.
+
+ Implementation ==> add
+ if A has ListAggregate(S) then -- A is a list-oid
+ reduce(fn, l, ident) ==
+ empty? l => ident
+ reduce(fn, rest l, fn(first l, ident))
+
+ if B has ListAggregate(R) or not(B has shallowlyMutable) then
+ -- A is a list-oid, and B is either list-oids or not mutable
+ map(f, l) == construct [f s for s in entries l]
+
+ scan(fn, l, ident) ==
+ empty? l => empty()
+ val := fn(first l, ident)
+ concat(val, scan(fn, rest l, val))
+
+ else -- A is a list-oid, B a mutable array-oid
+ map(f, l) ==
+ i := minIndex(w := new(#l,NIL$Lisp)$B)
+ for a in entries l repeat (qsetelt_!(w, i, f a); i := inc i)
+ w
+
+ scan(fn, l, ident) ==
+ i := minIndex(w := new(#l,NIL$Lisp)$B)
+ vl := ident
+ for a in entries l repeat
+ vl := qsetelt_!(w, i, fn(a, vl))
+ i := inc i
+ w
+
+ else -- A is an array-oid
+ reduce(fn, v, ident) ==
+ val := ident
+ for i in minIndex v .. maxIndex v repeat
+ val := fn(qelt(v, i), val)
+ val
+
+ if B has ListAggregate(R) then -- A is an array-oid, B a list-oid
+ map(f, v) ==
+ construct [f qelt(v, i) for i in minIndex v .. maxIndex v]
+
+ scan(fn, v, ident) ==
+ w := empty()$B
+ for i in minIndex v .. maxIndex v repeat
+ ident := fn(qelt(v, i), ident)
+ w := concat(ident, w)
+ reverse_! w
+
+ else -- A and B are array-oid's
+ if B has shallowlyMutable then -- B is also mutable
+ map(f, v) ==
+ w := new(#v,NIL$Lisp)$B
+ for i in minIndex w .. maxIndex w repeat
+ qsetelt_!(w, i, f qelt(v, i))
+ w
+
+ scan(fn, v, ident) ==
+ w := new(#v,NIL$Lisp)$B
+ vl := ident
+ for i in minIndex v .. maxIndex v repeat
+ vl := qsetelt_!(w, i, fn(qelt(v, i), vl))
+ w
+
+ else -- B non mutable array-oid
+ map(f, v) ==
+ construct [f qelt(v, i) for i in minIndex v .. maxIndex v]
+
+ scan(fn, v, ident) ==
+ w := empty()$B
+ for i in minIndex v .. maxIndex v repeat
+ ident := fn(qelt(v, i), ident)
+ w := concat(w, ident)
+ w
+
+@
+\section{package FSAGG2 FiniteSetAggregateFunctions2}
+<<package FSAGG2 FiniteSetAggregateFunctions2>>=
+)abbrev package FSAGG2 FiniteSetAggregateFunctions2
+
+--% FiniteSetAggregateFunctions2
+
+++ Author: Robert S. Sutor
+++ Date Created: 15 May 1990
+++ Date Last Updated: 14 Oct 1993
+++ Description:
+++ FiniteSetAggregateFunctions2 provides functions involving two
+++ finite set aggregates where the underlying domains might be
+++ different. An example of this is to create a set of rational
+++ numbers by mapping a function across a set of integers, where the
+++ function divides each integer by 1000.
+
+FiniteSetAggregateFunctions2(S, A, R, B): Exports == Implementation where
+ S, R: SetCategory
+ A : FiniteSetAggregate S
+ B : FiniteSetAggregate R
+
+ Exports ==> with
+ map : (S -> R, A) -> B ++ map(f,a) applies function f to each member of
+ ++ aggregate \spad{a}, creating a new aggregate with
+ ++ a possibly different underlying domain.
+
+ reduce : ((S, R) -> R, A, R) -> R ++ reduce(f,a,r) applies function f to each
+ ++ successive element of the aggregate \spad{a} and an
+ ++ accumulant initialised to r.
+ ++ For example,
+ ++ \spad{reduce(_+$Integer,[1,2,3],0)}
+ ++ does a \spad{3+(2+(1+0))}.
+ ++ Note: third argument r may be regarded
+ ++ as an identity element for the function.
+
+ scan : ((S, R) -> R, A, R) -> B ++ scan(f,a,r) successively applies \spad{reduce(f,x,r)}
+ ++ to more and more leading sub-aggregates x of
+ ++ aggregate \spad{a}.
+ ++ More precisely, if \spad{a} is \spad{[a1,a2,...]}, then
+ ++ \spad{scan(f,a,r)} returns
+ ++ \spad {[reduce(f,[a1],r),reduce(f,[a1,a2],r),...]}.
+
+ Implementation ==> add
+ map(fn, a) ==
+ set(map(fn, parts a)$ListFunctions2(S, R))$B
+ reduce(fn, a, ident) ==
+ reduce(fn, parts a, ident)$ListFunctions2(S, R)
+ scan(fn, a, ident) ==
+ set(scan(fn, parts a, ident)$ListFunctions2(S, R))$B
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FLAGG2 FiniteLinearAggregateFunctions2>>
+<<package FSAGG2 FiniteSetAggregateFunctions2>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/algcat.spad.pamphlet b/src/algebra/algcat.spad.pamphlet
new file mode 100644
index 00000000..5c028319
--- /dev/null
+++ b/src/algebra/algcat.spad.pamphlet
@@ -0,0 +1,382 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra algcat.spad}
+\author{Barry Trager, Claude Quitte, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category FINRALG FiniteRankAlgebra}
+<<category FINRALG FiniteRankAlgebra>>=
+)abbrev category FINRALG FiniteRankAlgebra
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A FiniteRankAlgebra is an algebra over a commutative ring R which
+++ is a free R-module of finite rank.
+
+FiniteRankAlgebra(R:CommutativeRing, UP:UnivariatePolynomialCategory R):
+ Category == Algebra R with
+ rank : () -> PositiveInteger
+ ++ rank() returns the rank of the algebra.
+ regularRepresentation : (% , Vector %) -> Matrix R
+ ++ regularRepresentation(a,basis) returns the matrix of the
+ ++ linear map defined by left multiplication by \spad{a} with respect
+ ++ to the basis \spad{basis}.
+ trace : % -> R
+ ++ trace(a) returns the trace of the regular representation
+ ++ of \spad{a} with respect to any basis.
+ norm : % -> R
+ ++ norm(a) returns the determinant of the regular representation
+ ++ of \spad{a} with respect to any basis.
+ coordinates : (%, Vector %) -> Vector R
+ ++ coordinates(a,basis) returns the coordinates of \spad{a} with
+ ++ respect to the basis \spad{basis}.
+ coordinates : (Vector %, Vector %) -> Matrix R
+ ++ coordinates([v1,...,vm], basis) returns the coordinates of the
+ ++ vi's with to the basis \spad{basis}. The coordinates of vi are
+ ++ contained in the ith row of the matrix returned by this
+ ++ function.
+ represents : (Vector R, Vector %) -> %
+ ++ represents([a1,..,an],[v1,..,vn]) returns \spad{a1*v1 + ... + an*vn}.
+ discriminant : Vector % -> R
+ ++ discriminant([v1,..,vn]) returns
+ ++ \spad{determinant(traceMatrix([v1,..,vn]))}.
+ traceMatrix : Vector % -> Matrix R
+ ++ traceMatrix([v1,..,vn]) is the n-by-n matrix ( Tr(vi * vj) )
+ characteristicPolynomial: % -> UP
+ ++ characteristicPolynomial(a) returns the characteristic
+ ++ polynomial of the regular representation of \spad{a} with respect
+ ++ to any basis.
+ if R has Field then minimalPolynomial : % -> UP
+ ++ minimalPolynomial(a) returns the minimal polynomial of \spad{a}.
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+
+ add
+
+ discriminant v == determinant traceMatrix v
+
+ coordinates(v:Vector %, b:Vector %) ==
+ m := new(#v, #b, 0)$Matrix(R)
+ for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
+ setRow_!(m, j, coordinates(qelt(v, i), b))
+ m
+
+ represents(v, b) ==
+ m := minIndex v - 1
+ _+/[v(i+m) * b(i+m) for i in 1..rank()]
+
+ traceMatrix v ==
+ matrix [[trace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
+ for i in minIndex v .. maxIndex v]$List(List R)
+
+ regularRepresentation(x, b) ==
+ m := minIndex b - 1
+ matrix
+ [parts coordinates(x*b(i+m),b) for i in 1..rank()]$List(List R)
+
+@
+\section{category FRAMALG FramedAlgebra}
+<<category FRAMALG FramedAlgebra>>=
+)abbrev category FRAMALG FramedAlgebra
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A \spadtype{FramedAlgebra} is a \spadtype{FiniteRankAlgebra} together
+++ with a fixed R-module basis.
+
+FramedAlgebra(R:CommutativeRing, UP:UnivariatePolynomialCategory R):
+ Category == FiniteRankAlgebra(R, UP) with
+ --operations
+ basis : () -> Vector %
+ ++ basis() returns the fixed R-module basis.
+ coordinates : % -> Vector R
+ ++ coordinates(a) returns the coordinates of \spad{a} with respect to the
+ ++ fixed R-module basis.
+ coordinates : Vector % -> Matrix R
+ ++ 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 R -> %
+ ++ represents([a1,..,an]) returns \spad{a1*v1 + ... + an*vn}, where
+ ++ v1, ..., vn are the elements of the fixed basis.
+ convert : % -> Vector R
+ ++ convert(a) returns the coordinates of \spad{a} with respect to the
+ ++ fixed R-module basis.
+ convert : Vector R -> %
+ ++ convert([a1,..,an]) returns \spad{a1*v1 + ... + an*vn}, where
+ ++ v1, ..., vn are the elements of the fixed basis.
+ traceMatrix : () -> Matrix R
+ ++ traceMatrix() is the n-by-n matrix ( \spad{Tr(vi * vj)} ), where
+ ++ v1, ..., vn are the elements of the fixed basis.
+ discriminant : () -> R
+ ++ discriminant() = determinant(traceMatrix()).
+ regularRepresentation : % -> Matrix R
+ ++ regularRepresentation(a) returns the matrix of the linear
+ ++ map defined by left multiplication by \spad{a} with respect
+ ++ to the fixed basis.
+ --attributes
+ --separable <=> discriminant() ^= 0
+ add
+ convert(x:%):Vector(R) == coordinates(x)
+ convert(v:Vector R):% == represents(v)
+ traceMatrix() == traceMatrix basis()
+ discriminant() == discriminant basis()
+ regularRepresentation x == regularRepresentation(x, basis())
+ coordinates x == coordinates(x, basis())
+ represents x == represents(x, basis())
+
+ coordinates(v:Vector %) ==
+ m := new(#v, rank(), 0)$Matrix(R)
+ for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
+ setRow_!(m, j, coordinates qelt(v, i))
+ m
+
+ regularRepresentation x ==
+ m := new(n := rank(), n, 0)$Matrix(R)
+ b := basis()
+ for i in minIndex b .. maxIndex b for j in minRowIndex m .. repeat
+ setRow_!(m, j, coordinates(x * qelt(b, i)))
+ m
+
+ characteristicPolynomial x ==
+ mat00 := (regularRepresentation x)
+ mat0 := map(#1 :: UP,mat00)$MatrixCategoryFunctions2(R, Vector R,
+ Vector R, Matrix R, UP, Vector UP,Vector UP, Matrix UP)
+ mat1 : Matrix UP := scalarMatrix(rank(),monomial(1,1)$UP)
+ determinant(mat1 - mat0)
+
+ if R has Field then
+ -- depends on the ordering of results from nullSpace, also see FFP
+ minimalPolynomial(x:%):UP ==
+ y:%:=1
+ n:=rank()
+ m:Matrix R:=zero(n,n+1)
+ for i in 1..n+1 repeat
+ setColumn_!(m,i,coordinates(y))
+ y:=y*x
+ v:=first nullSpace(m)
+ +/[monomial(v.(i+1),i) for i in 0..#v-1]
+
+@
+\section{category MONOGEN MonogenicAlgebra}
+<<category MONOGEN MonogenicAlgebra>>=
+)abbrev category MONOGEN MonogenicAlgebra
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A \spadtype{MonogenicAlgebra} is an algebra of finite rank which
+++ can be generated by a single element.
+
+MonogenicAlgebra(R:CommutativeRing, UP:UnivariatePolynomialCategory R):
+ Category ==
+ Join(FramedAlgebra(R, UP), CommutativeRing, ConvertibleTo UP,
+ FullyRetractableTo R, FullyLinearlyExplicitRingOver R) with
+ generator : () -> %
+ ++ generator() returns the generator for this domain.
+ definingPolynomial: () -> UP
+ ++ definingPolynomial() returns the minimal polynomial which
+ ++ \spad{generator()} satisfies.
+ reduce : UP -> %
+ ++ reduce(up) converts the univariate polynomial up to an algebra
+ ++ element, reducing by the \spad{definingPolynomial()} if necessary.
+ convert : UP -> %
+ ++ convert(up) converts the univariate polynomial up to an algebra
+ ++ element, reducing by the \spad{definingPolynomial()} if necessary.
+ lift : % -> UP
+ ++ lift(z) returns a minimal degree univariate polynomial up such that
+ ++ \spad{z=reduce up}.
+ if R has Finite then Finite
+ if R has Field then
+ Field
+ DifferentialExtension R
+ reduce : Fraction UP -> Union(%, "failed")
+ ++ reduce(frac) converts the fraction frac to an algebra element.
+ derivationCoordinates: (Vector %, R -> R) -> Matrix R
+ ++ derivationCoordinates(b, ') returns M such that \spad{b' = M b}.
+ if R has FiniteFieldCategory then FiniteFieldCategory
+ add
+ convert(x:%):UP == lift x
+ convert(p:UP):% == reduce p
+ generator() == reduce monomial(1, 1)$UP
+ norm x == resultant(definingPolynomial(), lift x)
+ retract(x:%):R == retract lift x
+ retractIfCan(x:%):Union(R, "failed") == retractIfCan lift x
+
+ basis() ==
+ [reduce monomial(1,i)$UP for i in 0..(rank()-1)::NonNegativeInteger]
+
+ characteristicPolynomial(x:%):UP ==
+ characteristicPolynomial(x)$CharacteristicPolynomialInMonogenicalAlgebra(R,UP,%)
+
+ if R has Finite then
+ size() == size()$R ** rank()
+ random() == represents [random()$R for i in 1..rank()]$Vector(R)
+
+ if R has Field then
+ reduce(x:Fraction UP) == reduce(numer x) exquo reduce(denom x)
+
+ differentiate(x:%, d:R -> R) ==
+ p := definingPolynomial()
+ yprime := - reduce(map(d, p)) / reduce(differentiate p)
+ reduce(map(d, lift x)) + yprime * reduce differentiate lift x
+
+ derivationCoordinates(b, d) ==
+ coordinates(map(differentiate(#1, d), b), b)
+
+ recip x ==
+ (bc := extendedEuclidean(lift x, definingPolynomial(), 1))
+ case "failed" => "failed"
+ reduce(bc.coef1)
+
+@
+\section{package CPIMA CharacteristicPolynomialInMonogenicalAlgebra}
+<<package CPIMA CharacteristicPolynomialInMonogenicalAlgebra>>=
+)abbrev package CPIMA CharacteristicPolynomialInMonogenicalAlgebra
+++ Author: Claude Quitte
+++ Date Created: 10/12/93
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package implements characteristicPolynomials for monogenic algebras
+++ using resultants
+CharacteristicPolynomialInMonogenicalAlgebra(R : CommutativeRing,
+ PolR : UnivariatePolynomialCategory(R),
+ E : MonogenicAlgebra(R, PolR)): with
+ characteristicPolynomial : E -> PolR
+ ++ characteristicPolynomial(e) returns the characteristic polynomial
+ ++ of e using resultants
+
+ == add
+ Pol ==> SparseUnivariatePolynomial
+
+ import UnivariatePolynomialCategoryFunctions2(R, PolR, PolR, Pol(PolR))
+ XtoY(Q : PolR) : Pol(PolR) == map(monomial(#1, 0), Q)
+
+ P : Pol(PolR) := XtoY(definingPolynomial()$E)
+ X : Pol(PolR) := monomial(monomial(1, 1)$PolR, 0)
+
+ characteristicPolynomial(x : E) : PolR ==
+ Qx : PolR := lift(x)
+ -- on utilise le fait que resultant_Y (P(Y), X - Qx(Y))
+ return resultant(P, X - XtoY(Qx))
+
+@
+\section{package NORMMA NormInMonogenicAlgebra}
+<<package NORMMA NormInMonogenicAlgebra>>=
+)abbrev package NORMMA NormInMonogenicAlgebra
+++ Author: Manuel Bronstein
+++ Date Created: 23 February 1995
+++ Date Last Updated: 23 February 1995
+++ Basic Functions: norm
+++ Description:
+++ This package implements the norm of a polynomial with coefficients
+++ in a monogenic algebra (using resultants)
+
+NormInMonogenicAlgebra(R, PolR, E, PolE): Exports == Implementation where
+ R: GcdDomain
+ PolR: UnivariatePolynomialCategory R
+ E: MonogenicAlgebra(R, PolR)
+ PolE: UnivariatePolynomialCategory E
+
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> with
+ norm: PolE -> PolR
+ ++ norm q returns the norm of q,
+ ++ i.e. the product of all the conjugates of q.
+
+ Implementation ==> add
+ import UnivariatePolynomialCategoryFunctions2(R, PolR, PolR, SUP PolR)
+
+ PolR2SUP: PolR -> SUP PolR
+ PolR2SUP q == map(#1::PolR, q)
+
+ defpol := PolR2SUP(definingPolynomial()$E)
+
+ norm q ==
+ p:SUP PolR := 0
+ while q ~= 0 repeat
+ p := p + monomial(1,degree q)$PolR * PolR2SUP lift leadingCoefficient q
+ q := reductum q
+ primitivePart resultant(p, defpol)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category FINRALG FiniteRankAlgebra>>
+<<category FRAMALG FramedAlgebra>>
+<<category MONOGEN MonogenicAlgebra>>
+<<package CPIMA CharacteristicPolynomialInMonogenicalAlgebra>>
+<<package NORMMA NormInMonogenicAlgebra>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/algext.spad.pamphlet b/src/algebra/algext.spad.pamphlet
new file mode 100644
index 00000000..30e51529
--- /dev/null
+++ b/src/algebra/algext.spad.pamphlet
@@ -0,0 +1,235 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra algext.spad}
+\author{Barry Trager, Manuel Bronstein, Clifton Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SAE SimpleAlgebraicExtension}
+<<domain SAE SimpleAlgebraicExtension>>=
+)abbrev domain SAE SimpleAlgebraicExtension
+++ Algebraic extension of a ring by a single polynomial
+++ Author: Barry Trager, Manuel Bronstein, Clifton Williamson
+++ Date Created: 1986
+++ Date Last Updated: 9 May 1994
+++ Description:
+++ Domain which represents simple algebraic extensions of arbitrary
+++ rings. The first argument to the domain, R, is the underlying ring,
+++ the second argument is a domain of univariate polynomials over K,
+++ while the last argument specifies the defining minimal polynomial.
+++ The elements of the domain are canonically represented as polynomials
+++ of degree less than that of the minimal polynomial with coefficients
+++ in R. The second argument is both the type of the third argument and
+++ the underlying representation used by \spadtype{SAE} itself.
+++ Keywords: ring, algebraic, extension
+++ Example: )r SAE INPUT
+
+SimpleAlgebraicExtension(R:CommutativeRing,
+ UP:UnivariatePolynomialCategory R, M:UP): MonogenicAlgebra(R, UP) == add
+ --sqFr(pb): FactorS(Poly) from UnivPolySquareFree(Poly)
+
+ --degree(M) > 0 and M must be monic if R is not a field.
+ if (r := recip leadingCoefficient M) case "failed" then
+ error "Modulus cannot be made monic"
+ Rep := UP
+ x,y :$
+ c: R
+
+ mkDisc : Boolean -> Void
+ mkDiscMat: Boolean -> Void
+
+ M := r::R * M
+ d := degree M
+ d1 := subtractIfCan(d,1)::NonNegativeInteger
+ discmat:Matrix(R) := zero(d, d)
+ nodiscmat?:Reference(Boolean) := ref true
+ disc:Reference(R) := ref 0
+ nodisc?:Reference(Boolean) := ref true
+ bsis := [monomial(1, i)$Rep for i in 0..d1]$Vector(Rep)
+
+ if R has Finite then
+ size == size$R ** d
+ random == represents([random()$R for i in 0..d1])
+ 0 == 0$Rep
+ 1 == 1$Rep
+ c * x == c *$Rep x
+ n:Integer * x == n *$Rep x
+ coerce(n:Integer):$ == coerce(n)$Rep
+ coerce(c) == monomial(c,0)$Rep
+ coerce(x):OutputForm == coerce(x)$Rep
+ lift(x) == x pretend Rep
+ reduce(p:UP):$ == (monicDivide(p,M)$Rep).remainder
+ x = y == x =$Rep y
+ x + y == x +$Rep y
+ - x == -$Rep x
+ x * y == reduce((x *$Rep y) pretend UP)
+ coordinates(x) == [coefficient(lift(x),i) for i in 0..d1]
+ represents(vect) == +/[monomial(vect.(i+1),i) for i in 0..d1]
+ definingPolynomial() == M
+ characteristic() == characteristic()$R
+ rank() == d::PositiveInteger
+ basis() == copy(bsis@Vector(Rep) pretend Vector($))
+ --!! I inserted 'copy' in the definition of 'basis' -- cjw 7/19/91
+
+ if R has Field then
+ minimalPolynomial x == squareFreePart characteristicPolynomial x
+
+ if R has Field then
+ coordinates(x:$,bas: Vector $) ==
+ (m := inverse transpose coordinates bas) case "failed" =>
+ error "coordinates: second argument must be a basis"
+ (m :: Matrix R) * coordinates(x)
+
+ else if R has IntegralDomain then
+ coordinates(x:$,bas: Vector $) ==
+ -- we work over the quotient field of R to invert a matrix
+ qf := Fraction R
+ imatqf := InnerMatrixQuotientFieldFunctions(R,Vector R,Vector R,_
+ Matrix R,qf,Vector qf,Vector qf,Matrix qf)
+ mat := transpose coordinates bas
+ (m := inverse(mat)$imatqf) case "failed" =>
+ error "coordinates: second argument must be a basis"
+ coordsQF := map(#1 :: qf,coordinates x)$VectorFunctions2(R,qf)
+ -- here are the coordinates as elements of the quotient field:
+ vecQF := (m :: Matrix qf) * coordsQF
+ vec : Vector R := new(d,0)
+ for i in 1..d repeat
+ xi := qelt(vecQF,i)
+ denom(xi) = 1 => qsetelt_!(vec,i,numer xi)
+ error "coordinates: coordinates are not integral over ground ring"
+ vec
+
+ reducedSystem(m:Matrix $):Matrix(R) ==
+ reducedSystem(map(lift, m)$MatrixCategoryFunctions2($, Vector $,
+ Vector $, Matrix $, UP, Vector UP, Vector UP, Matrix UP))
+
+ reducedSystem(m:Matrix $, v:Vector $):Record(mat:Matrix R,vec:Vector R) ==
+ reducedSystem(map(lift, m)$MatrixCategoryFunctions2($, Vector $,
+ Vector $, Matrix $, UP, Vector UP, Vector UP, Matrix UP),
+ map(lift, v)$VectorFunctions2($, UP))
+
+ discriminant() ==
+ if nodisc?() then mkDisc false
+ disc()
+
+ mkDisc b ==
+ nodisc?() := b
+ disc() := discriminant M
+ void
+
+ traceMatrix() ==
+ if nodiscmat?() then mkDiscMat false
+ discmat
+
+ mkDiscMat b ==
+ nodiscmat?() := b
+ mr := minRowIndex discmat; mc := minColIndex discmat
+ for i in 0..d1 repeat
+ for j in 0..d1 repeat
+ qsetelt_!(discmat,mr + i,mc + j,trace reduce monomial(1,i + j))
+ void
+
+ trace x == --this could be coded perhaps more efficiently
+ xn := x; ans := coefficient(lift xn, 0)
+ for n in 1..d1 repeat
+ (xn := generator() * xn; ans := coefficient(lift xn, n) + ans)
+ ans
+
+ if R has Finite then
+ index k ==
+ i:Integer := k rem size()
+ p:Integer := size()$R
+ ans:$ := 0
+ for j in 0.. while i > 0 repeat
+ h := i rem p
+ -- index(p) = 0$R
+ if h ^= 0 then
+ -- here was a bug: "index" instead of
+ -- "coerce", otherwise it wouldn't work for
+ -- Rings R where "coerce: I-> R" is not surjective
+ a := index(h :: PositiveInteger)$R
+ ans := ans + reduce monomial(a, j)
+ i := i quo p
+ ans
+ lookup(z : $) : PositiveInteger ==
+ -- z = index lookup z, n = lookup index n
+ -- the answer is merely the Horner evaluation of the
+ -- representation with the size of R (as integers).
+ zero?(z) => size()$$ pretend PositiveInteger
+ p : Integer := size()$R
+ co : Integer := lookup(leadingCoefficient z)$R
+ n : NonNegativeInteger := degree(z)
+ while not zero?(z := reductum z) repeat
+ co := co * p ** ((n - (n := degree z)) pretend
+ NonNegativeInteger) + lookup(leadingCoefficient z)$R
+ n = 0 => co pretend PositiveInteger
+ (co * p ** n) pretend PositiveInteger
+
+--
+-- KA:=BasicPolynomialFunctions(Poly)
+-- minPoly(x) ==
+-- ffe:= SqFr(resultant(M::KA, KA.var - lift(x)::KA)).fs.first
+-- ffe.flag = "SQFR" => ffe.f
+-- mdeg:= (degree(ffe.f) // K.characteristic)::Integer
+-- mat:= Zero()::Matrix<mdeg+1,deg+mdeg+1>(K)
+-- xi:=L.1; setelt(mat,1,1,K.1); setelt(mat,1,(deg+1),K.1)
+-- for i in 1..mdeg repeat
+-- xi:= x * xi; xp:= lift(xi)
+-- while xp ^= KA.0 repeat
+-- setelt(mat,(mdeg+1),(degree(xp)+1),LeadingCoef(xp))
+-- xp:=reductum(xp)
+-- setelt(mat,(mdeg+1),(deg+i+1),K.1)
+-- EchelonLastRow(mat)
+-- if and/(elt(mat,(i+1),j) = K.0 for j in 1..deg)
+-- then return unitNormal(+/(elt(mat,(i+1),(deg+j+1))*(B::KA)**j
+-- for j in 0..i)).a
+-- ffe.f
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SAE SimpleAlgebraicExtension>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/algfact.spad.pamphlet b/src/algebra/algfact.spad.pamphlet
new file mode 100644
index 00000000..3e90bb50
--- /dev/null
+++ b/src/algebra/algfact.spad.pamphlet
@@ -0,0 +1,346 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra algfact.spad}
+\author{Patrizia Gianni, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IALGFACT InnerAlgFactor}
+<<package IALGFACT InnerAlgFactor>>=
+)abbrev package IALGFACT InnerAlgFactor
+++ Factorisation in a simple algebraic extension
+++ Author: Patrizia Gianni
+++ Date Created: ???
+++ Date Last Updated: 20 Jul 1988
+++ Description:
+++ Factorization of univariate polynomials with coefficients in an
+++ algebraic extension of a field over which we can factor UP's;
+++ Keywords: factorization, algebraic extension, univariate polynomial
+
+InnerAlgFactor(F, UP, AlExt, AlPol): Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ AlPol: UnivariatePolynomialCategory AlExt
+ AlExt : Join(Field, CharacteristicZero, MonogenicAlgebra(F,UP))
+ NUP ==> SparseUnivariatePolynomial UP
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ FR ==> Factored UP
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+
+ Exports ==> with
+ factor: (AlPol, UP -> FR) -> Factored AlPol
+ ++ factor(p, f) returns a prime factorisation of p;
+ ++ f is a factorisation map for elements of UP;
+
+ Implementation ==> add
+ pnorm : AlPol -> UP
+ convrt : AlPol -> NUP
+ change : UP -> AlPol
+ perturbfactor: (AlPol, Z, UP -> FR) -> List AlPol
+ irrfactor : (AlPol, Z, UP -> FR) -> List AlPol
+
+
+ perturbfactor(f, k, fact) ==
+ pol := monomial(1$AlExt,1)-
+ monomial(reduce monomial(k::F,1)$UP ,0)
+ newf := elt(f, pol)
+ lsols := irrfactor(newf, k, fact)
+ pol := monomial(1, 1) +
+ monomial(reduce monomial(k::F,1)$UP,0)
+ [elt(pp, pol) for pp in lsols]
+
+ --- factorize the square-free parts of f ---
+ irrfactor(f, k, fact) ==
+ degree(f) =$N 1 => [f]
+ newf := f
+ nn := pnorm f
+ --newval:RN:=1
+ --pert:=false
+ --if ^ SqFr? nn then
+ -- pert:=true
+ -- newterm:=perturb(f)
+ -- newf:=newterm.ppol
+ -- newval:=newterm.pval
+ -- nn:=newterm.nnorm
+ listfact := factors fact nn
+ #listfact =$N 1 =>
+ first(listfact).exponent =$Z 1 => [f]
+ perturbfactor(f, k + 1, fact)
+ listerm:List(AlPol):= []
+ for pelt in listfact repeat
+ g := gcd(change(pelt.factor), newf)
+ newf := (newf exquo g)::AlPol
+ listerm :=
+ pelt.exponent =$Z 1 => cons(g, listerm)
+ append(perturbfactor(g, k + 1, fact), listerm)
+ listerm
+
+ factor(f, fact) ==
+ sqf := squareFree f
+ unit(sqf) * _*/[_*/[primeFactor(pol, sqterm.exponent)
+ for pol in irrfactor(sqterm.factor, 0, fact)]
+ for sqterm in factors sqf]
+
+ p := definingPolynomial()$AlExt
+ newp := map(#1::UP, p)$UPCF2(F, UP, UP, NUP)
+
+ pnorm q == resultant(convrt q, newp)
+ change q == map(coerce, q)$UPCF2(F,UP,AlExt,AlPol)
+
+ convrt q ==
+ swap(map(lift, q)$UPCF2(AlExt, AlPol,
+ UP, NUP))$CommuteUnivariatePolynomialCategory(F, UP, NUP)
+
+@
+\section{package SAEFACT SimpleAlgebraicExtensionAlgFactor}
+<<package SAEFACT SimpleAlgebraicExtensionAlgFactor>>=
+)abbrev package SAEFACT SimpleAlgebraicExtensionAlgFactor
+++ Factorisation in a simple algebraic extension;
+++ Author: Patrizia Gianni
+++ Date Created: ???
+++ Date Last Updated: ???
+++ Description:
+++ Factorization of univariate polynomials with coefficients in an
+++ algebraic extension of the rational numbers (\spadtype{Fraction Integer}).
+++ Keywords: factorization, algebraic extension, univariate polynomial
+
+SimpleAlgebraicExtensionAlgFactor(UP,SAE,UPA):Exports==Implementation where
+ UP : UnivariatePolynomialCategory Fraction Integer
+ SAE : Join(Field, CharacteristicZero,
+ MonogenicAlgebra(Fraction Integer, UP))
+ UPA: UnivariatePolynomialCategory SAE
+
+ Exports ==> with
+ factor: UPA -> Factored UPA
+ ++ factor(p) returns a prime factorisation of p.
+
+ Implementation ==> add
+ factor q ==
+ factor(q, factor$RationalFactorize(UP)
+ )$InnerAlgFactor(Fraction Integer, UP, SAE, UPA)
+
+@
+\section{package RFFACT RationalFunctionFactor}
+<<package RFFACT RationalFunctionFactor>>=
+)abbrev package RFFACT RationalFunctionFactor
+++ Factorisation in UP FRAC POLY INT
+++ Author: Patrizia Gianni
+++ Date Created: ???
+++ Date Last Updated: ???
+++ Description:
+++ Factorization of univariate polynomials with coefficients which
+++ are rational functions with integer coefficients.
+
+RationalFunctionFactor(UP): Exports == Implementation where
+ UP: UnivariatePolynomialCategory Fraction Polynomial Integer
+
+ SE ==> Symbol
+ P ==> Polynomial Integer
+ RF ==> Fraction P
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+ Exports ==> with
+ factor: UP -> Factored UP
+ ++ factor(p) returns a prime factorisation of p.
+
+ Implementation ==> add
+ likuniv: (P, SE, P) -> UP
+
+ dummy := new()$SE
+
+ likuniv(p, x, d) ==
+ map(#1 / d, univariate(p, x))$UPCF2(P,SparseUnivariatePolynomial P,
+ RF, UP)
+
+ factor p ==
+ d := denom(q := elt(p,dummy::P :: RF))
+ map(likuniv(#1,dummy,d),
+ factor(numer q)$MultivariateFactorize(SE,
+ IndexedExponents SE,Integer,P))$FactoredFunctions2(P, UP)
+
+@
+\section{package SAERFFC SAERationalFunctionAlgFactor}
+<<package SAERFFC SAERationalFunctionAlgFactor>>=
+)abbrev package SAERFFC SAERationalFunctionAlgFactor
+++ Factorisation in UP SAE FRAC POLY INT
+++ Author: Patrizia Gianni
+++ Date Created: ???
+++ Date Last Updated: ???
+++ Description:
+++ Factorization of univariate polynomials with coefficients in an
+++ algebraic extension of \spadtype{Fraction Polynomial Integer}.
+++ Keywords: factorization, algebraic extension, univariate polynomial
+
+SAERationalFunctionAlgFactor(UP, SAE, UPA): Exports == Implementation where
+ UP : UnivariatePolynomialCategory Fraction Polynomial Integer
+ SAE : Join(Field, CharacteristicZero,
+ MonogenicAlgebra(Fraction Polynomial Integer, UP))
+ UPA: UnivariatePolynomialCategory SAE
+
+ Exports ==> with
+ factor: UPA -> Factored UPA
+ ++ factor(p) returns a prime factorisation of p.
+
+ Implementation ==> add
+ factor q ==
+ factor(q, factor$RationalFunctionFactor(UP)
+ )$InnerAlgFactor(Fraction Polynomial Integer, UP, SAE, UPA)
+
+@
+\section{package ALGFACT AlgFactor}
+<<package ALGFACT AlgFactor>>=
+)abbrev package ALGFACT AlgFactor
+++ Factorization of UP AN;
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: ???
+++ Description:
+++ Factorization of univariate polynomials with coefficients in
+++ \spadtype{AlgebraicNumber}.
+
+AlgFactor(UP): Exports == Implementation where
+ UP: UnivariatePolynomialCategory AlgebraicNumber
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Integer
+ AN ==> AlgebraicNumber
+ K ==> Kernel AN
+ UPQ ==> SparseUnivariatePolynomial Q
+ SUP ==> SparseUnivariatePolynomial AN
+ FR ==> Factored UP
+
+ Exports ==> with
+ factor: (UP, List AN) -> FR
+ ++ factor(p, [a1,...,an]) returns a prime factorisation of p
+ ++ over the field generated by its coefficients and a1,...,an.
+ factor: UP -> FR
+ ++ factor(p) returns a prime factorisation of p
+ ++ over the field generated by its coefficients.
+ split : UP -> FR
+ ++ split(p) returns a prime factorisation of p
+ ++ over its splitting field.
+ doublyTransitive?: UP -> Boolean
+ ++ doublyTransitive?(p) is true if p is irreducible over
+ ++ over the field K generated by its coefficients, and
+ ++ if \spad{p(X) / (X - a)} is irreducible over
+ ++ \spad{K(a)} where \spad{p(a) = 0}.
+
+ Implementation ==> add
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, Z, SparseMultivariatePolynomial(Z, K), AN)
+
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+ fact : (UP, List K) -> FR
+ ifactor : (SUP, List K) -> Factored SUP
+ extend : (UP, Z) -> FR
+ allk : List AN -> List K
+ downpoly: UP -> UPQ
+ liftpoly: UPQ -> UP
+ irred? : UP -> Boolean
+
+ allk l == removeDuplicates concat [kernels x for x in l]
+ liftpoly p == map(#1::AN, p)$UPCF2(Q, UPQ, AN, UP)
+ downpoly p == map(retract(#1)@Q, p)$UPCF2(AN, UP ,Q, UPQ)
+ ifactor(p,l) == (fact(p pretend UP, l)) pretend Factored(SUP)
+ factor p == fact(p, allk coefficients p)
+
+ factor(p, l) ==
+ fact(p, allk removeDuplicates concat(l, coefficients p))
+
+ split p ==
+ fp := factor p
+ unit(fp) *
+ _*/[extend(fc.factor, fc.exponent) for fc in factors fp]
+
+ extend(p, n) ==
+-- one? degree p => primeFactor(p, n)
+ (degree p = 1) => primeFactor(p, n)
+ q := monomial(1, 1)$UP - zeroOf(p pretend SUP)::UP
+ primeFactor(q, n) * split((p exquo q)::UP) ** (n::N)
+
+ doublyTransitive? p ==
+ irred? p and irred?((p exquo
+ (monomial(1, 1)$UP - zeroOf(p pretend SUP)::UP))::UP)
+
+ irred? p ==
+ fp := factor p
+-- one? numberOfFactors fp and one? nthExponent(fp, 1)
+ (numberOfFactors fp = 1) and (nthExponent(fp, 1) = 1)
+
+ fact(p, l) ==
+-- one? degree p => primeFactor(p, 1)
+ (degree p = 1) => primeFactor(p, 1)
+ empty? l =>
+ dr := factor(downpoly p)$RationalFactorize(UPQ)
+ (liftpoly unit dr) *
+ _*/[primeFactor(liftpoly dc.factor,dc.exponent)
+ for dc in factors dr]
+ q := minPoly(alpha := "max"/l)$AN
+ newl := remove(alpha = #1, l)
+ sae := SimpleAlgebraicExtension(AN, SUP, q)
+ ups := SparseUnivariatePolynomial sae
+ fr := factor(map(reduce univariate(#1, alpha, q),
+ p)$UPCF2(AN, UP, sae, ups),
+ ifactor(#1, newl))$InnerAlgFactor(AN, SUP, sae, ups)
+ newalpha := alpha::AN
+ map((lift(#1)$sae) newalpha, unit fr)$UPCF2(sae, ups, AN, UP) *
+ _*/[primeFactor(map((lift(#1)$sae) newalpha,
+ fc.factor)$UPCF2(sae, ups, AN, UP),
+ fc.exponent) for fc in factors fr]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package IALGFACT InnerAlgFactor>>
+<<package SAEFACT SimpleAlgebraicExtensionAlgFactor>>
+<<package RFFACT RationalFunctionFactor>>
+<<package SAERFFC SAERationalFunctionAlgFactor>>
+<<package ALGFACT AlgFactor>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/algfunc.spad.pamphlet b/src/algebra/algfunc.spad.pamphlet
new file mode 100644
index 00000000..163734e3
--- /dev/null
+++ b/src/algebra/algfunc.spad.pamphlet
@@ -0,0 +1,577 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra algfunc.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ACF AlgebraicallyClosedField}
+<<category ACF AlgebraicallyClosedField>>=
+)abbrev category ACF AlgebraicallyClosedField
+++ Author: Manuel Bronstein
+++ Date Created: 22 Mar 1988
+++ Date Last Updated: 27 November 1991
+++ Description:
+++ Model for algebraically closed fields.
+++ Keywords: algebraic, closure, field.
+
+AlgebraicallyClosedField(): Category == Join(Field,RadicalCategory) with
+ rootOf: Polynomial $ -> $
+ ++ rootOf(p) returns y such that \spad{p(y) = 0}.
+ ++ Error: if p has more than one variable y.
+ rootOf: SparseUnivariatePolynomial $ -> $
+ ++ rootOf(p) returns y such that \spad{p(y) = 0}.
+ rootOf: (SparseUnivariatePolynomial $, Symbol) -> $
+ ++ rootOf(p, y) returns y such that \spad{p(y) = 0}.
+ ++ The object returned displays as \spad{'y}.
+ rootsOf: Polynomial $ -> List $
+ ++ rootsOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ Note: the returned symbols y1,...,yn are bound in the
+ ++ interpreter to respective root values.
+ ++ Error: if p has more than one variable y.
+ rootsOf: SparseUnivariatePolynomial $ -> List $
+ ++ rootsOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ Note: the returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ rootsOf: (SparseUnivariatePolynomial $, Symbol) -> List $
+ ++ rootsOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0};
+ ++ The returned roots display as \spad{'y1},...,\spad{'yn}.
+ ++ Note: the returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ zeroOf: Polynomial $ -> $
+ ++ zeroOf(p) returns y such that \spad{p(y) = 0}.
+ ++ If possible, y is expressed in terms of radicals.
+ ++ Otherwise it is an implicit algebraic quantity.
+ ++ Error: if p has more than one variable y.
+ zeroOf: SparseUnivariatePolynomial $ -> $
+ ++ zeroOf(p) returns y such that \spad{p(y) = 0};
+ ++ if possible, y is expressed in terms of radicals.
+ ++ Otherwise it is an implicit algebraic quantity.
+ zeroOf: (SparseUnivariatePolynomial $, Symbol) -> $
+ ++ zeroOf(p, y) returns y such that \spad{p(y) = 0};
+ ++ if possible, y is expressed in terms of radicals.
+ ++ Otherwise it is an implicit algebraic quantity which
+ ++ displays as \spad{'y}.
+ zerosOf: Polynomial $ -> List $
+ ++ zerosOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ The yi's are expressed in radicals if possible.
+ ++ Otherwise they are implicit algebraic quantities.
+ ++ The returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ ++ Error: if p has more than one variable y.
+ zerosOf: SparseUnivariatePolynomial $ -> List $
+ ++ zerosOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ The yi's are expressed in radicals if possible, and otherwise
+ ++ as implicit algebraic quantities.
+ ++ The returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ zerosOf: (SparseUnivariatePolynomial $, Symbol) -> List $
+ ++ zerosOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ The yi's are expressed in radicals if possible, and otherwise
+ ++ as implicit algebraic quantities
+ ++ which display as \spad{'yi}.
+ ++ The returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ add
+ SUP ==> SparseUnivariatePolynomial $
+
+ assign : (Symbol, $) -> $
+ allroots: (SUP, Symbol, (SUP, Symbol) -> $) -> List $
+ binomialRoots: (SUP, Symbol, (SUP, Symbol) -> $) -> List $
+
+ zeroOf(p:SUP) == assign(x := new(), zeroOf(p, x))
+ rootOf(p:SUP) == assign(x := new(), rootOf(p, x))
+ zerosOf(p:SUP) == zerosOf(p, new())
+ rootsOf(p:SUP) == rootsOf(p, new())
+ rootsOf(p:SUP, y:Symbol) == allroots(p, y, rootOf)
+ zerosOf(p:SUP, y:Symbol) == allroots(p, y, zeroOf)
+ assign(x, f) == (assignSymbol(x, f, $)$Lisp; f)
+
+ zeroOf(p:Polynomial $) ==
+ empty?(l := variables p) => error "zeroOf: constant polynomial"
+ zeroOf(univariate p, first l)
+
+ rootOf(p:Polynomial $) ==
+ empty?(l := variables p) => error "rootOf: constant polynomial"
+ rootOf(univariate p, first l)
+
+ zerosOf(p:Polynomial $) ==
+ empty?(l := variables p) => error "zerosOf: constant polynomial"
+ zerosOf(univariate p, first l)
+
+ rootsOf(p:Polynomial $) ==
+ empty?(l := variables p) => error "rootsOf: constant polynomial"
+ rootsOf(univariate p, first l)
+
+ zeroOf(p:SUP, y:Symbol) ==
+ zero?(d := degree p) => error "zeroOf: constant polynomial"
+ zero? coefficient(p, 0) => 0
+ a := leadingCoefficient p
+ d = 2 =>
+ b := coefficient(p, 1)
+ (sqrt(b**2 - 4 * a * coefficient(p, 0)) - b) / (2 * a)
+ (r := retractIfCan(reductum p)@Union($,"failed")) case "failed" =>
+ rootOf(p, y)
+ nthRoot(- (r::$ / a), d)
+
+ binomialRoots(p, y, fn) ==
+ -- p = a * x**n + b
+ alpha := assign(x := new(y)$Symbol, fn(p, x))
+-- one?(n := degree p) => [ alpha ]
+ ((n := degree p) = 1) => [ alpha ]
+ cyclo := cyclotomic(n, monomial(1,1)$SUP)$NumberTheoreticPolynomialFunctions(SUP)
+ beta := assign(x := new(y)$Symbol, fn(cyclo, x))
+ [alpha*beta**i for i in 0..(n-1)::NonNegativeInteger]
+
+ import PolynomialDecomposition(SUP,$)
+
+ allroots(p, y, fn) ==
+ zero? p => error "allroots: polynomial must be nonzero"
+ zero? coefficient(p,0) =>
+ concat(0, allroots(p quo monomial(1,1), y, fn))
+ zero?(p1:=reductum p) => empty()
+ zero? reductum p1 => binomialRoots(p, y, fn)
+ decompList := decompose(p)
+ # decompList > 1 =>
+ h := last decompList
+ g := leftFactor(p,h) :: SUP
+ groots := allroots(g, y, fn)
+ "append"/[allroots(h-r::SUP, y, fn) for r in groots]
+ ans := nil()$List($)
+ while not ground? p repeat
+ alpha := assign(x := new(y)$Symbol, fn(p, x))
+ q := monomial(1, 1)$SUP - alpha::SUP
+ if not zero?(p alpha) then
+ p := p quo q
+ ans := concat(alpha, ans)
+ else while zero?(p alpha) repeat
+ p := (p exquo q)::SUP
+ ans := concat(alpha, ans)
+ reverse_! ans
+
+@
+\section{category ACFS AlgebraicallyClosedFunctionSpace}
+<<category ACFS AlgebraicallyClosedFunctionSpace>>=
+)abbrev category ACFS AlgebraicallyClosedFunctionSpace
+++ Author: Manuel Bronstein
+++ Date Created: 31 October 1988
+++ Date Last Updated: 7 October 1991
+++ Description:
+++ Model for algebraically closed function spaces.
+++ Keywords: algebraic, closure, field.
+AlgebraicallyClosedFunctionSpace(R:Join(OrderedSet, IntegralDomain)):
+ Category == Join(AlgebraicallyClosedField, FunctionSpace R) with
+ rootOf : $ -> $
+ ++ rootOf(p) returns y such that \spad{p(y) = 0}.
+ ++ Error: if p has more than one variable y.
+ rootsOf: $ -> List $
+ ++ rootsOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0};
+ ++ Note: the returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ ++ Error: if p has more than one variable y.
+ rootOf : ($, Symbol) -> $
+ ++ rootOf(p,y) returns y such that \spad{p(y) = 0}.
+ ++ The object returned displays as \spad{'y}.
+ rootsOf: ($, Symbol) -> List $
+ ++ rootsOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0};
+ ++ The returned roots display as \spad{'y1},...,\spad{'yn}.
+ ++ Note: the returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ zeroOf : $ -> $
+ ++ zeroOf(p) returns y such that \spad{p(y) = 0}.
+ ++ The value y is expressed in terms of radicals if possible,and otherwise
+ ++ as an implicit algebraic quantity.
+ ++ Error: if p has more than one variable.
+ zerosOf: $ -> List $
+ ++ zerosOf(p) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ The yi's are expressed in radicals if possible.
+ ++ The returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ ++ Error: if p has more than one variable.
+ zeroOf : ($, Symbol) -> $
+ ++ zeroOf(p, y) returns y such that \spad{p(y) = 0}.
+ ++ The value y is expressed in terms of radicals if possible,and otherwise
+ ++ as an implicit algebraic quantity
+ ++ which displays as \spad{'y}.
+ zerosOf: ($, Symbol) -> List $
+ ++ zerosOf(p, y) returns \spad{[y1,...,yn]} such that \spad{p(yi) = 0}.
+ ++ The yi's are expressed in radicals if possible, and otherwise
+ ++ as implicit algebraic quantities
+ ++ which display as \spad{'yi}.
+ ++ The returned symbols y1,...,yn are bound in the interpreter
+ ++ to respective root values.
+ add
+ rootOf(p:$) ==
+ empty?(l := variables p) => error "rootOf: constant expression"
+ rootOf(p, first l)
+
+ rootsOf(p:$) ==
+ empty?(l := variables p) => error "rootsOf: constant expression"
+ rootsOf(p, first l)
+
+ zeroOf(p:$) ==
+ empty?(l := variables p) => error "zeroOf: constant expression"
+ zeroOf(p, first l)
+
+ zerosOf(p:$) ==
+ empty?(l := variables p) => error "zerosOf: constant expression"
+ zerosOf(p, first l)
+
+ zeroOf(p:$, x:Symbol) ==
+ n := numer(f := univariate(p, kernel(x)$Kernel($)))
+ degree denom f > 0 => error "zeroOf: variable appears in denom"
+ degree n = 0 => error "zeroOf: constant expression"
+ zeroOf(n, x)
+
+ rootOf(p:$, x:Symbol) ==
+ n := numer(f := univariate(p, kernel(x)$Kernel($)))
+ degree denom f > 0 => error "roofOf: variable appears in denom"
+ degree n = 0 => error "rootOf: constant expression"
+ rootOf(n, x)
+
+ zerosOf(p:$, x:Symbol) ==
+ n := numer(f := univariate(p, kernel(x)$Kernel($)))
+ degree denom f > 0 => error "zerosOf: variable appears in denom"
+ degree n = 0 => empty()
+ zerosOf(n, x)
+
+ rootsOf(p:$, x:Symbol) ==
+ n := numer(f := univariate(p, kernel(x)$Kernel($)))
+ degree denom f > 0 => error "roofsOf: variable appears in denom"
+ degree n = 0 => empty()
+ rootsOf(n, x)
+
+ rootsOf(p:SparseUnivariatePolynomial $, y:Symbol) ==
+ (r := retractIfCan(p)@Union($,"failed")) case $ => rootsOf(r::$,y)
+ rootsOf(p, y)$AlgebraicallyClosedField_&($)
+
+ zerosOf(p:SparseUnivariatePolynomial $, y:Symbol) ==
+ (r := retractIfCan(p)@Union($,"failed")) case $ => zerosOf(r::$,y)
+ zerosOf(p, y)$AlgebraicallyClosedField_&($)
+
+ zeroOf(p:SparseUnivariatePolynomial $, y:Symbol) ==
+ (r := retractIfCan(p)@Union($,"failed")) case $ => zeroOf(r::$, y)
+ zeroOf(p, y)$AlgebraicallyClosedField_&($)
+
+@
+\section{package AF AlgebraicFunction}
+\subsection{hackroot(x, n)}
+This used to read:
+\begin{verbatim}
+ hackroot(x, n) ==
+ (n = 1) or (x = 1) => x
+ (x ^= -1) and (((num := numer x) = 1) or (num = -1)) =>
+ inv hackroot((num * denom x)::F, n)
+ (x = -1) and n = 4 =>
+ ((-1::F) ** (1::Q / 2::Q) + 1) / ((2::F) ** (1::Q / 2::Q))
+ kernel(oproot, [x, n::F])
+
+@
+\end{verbatim}
+but the condition is wrong. For example, if $x$ is negative then
+$x=-1/2$ would pass the
+test and give $$1/(-2)^(1/n) \ne (-1/2)^(1/n)$$
+<<hackroot(x, n)>>=
+ hackroot(x, n) ==
+ (n = 1) or (x = 1) => x
+ (((dx := denom x) ^= 1) and
+ ((rx := retractIfCan(dx)@Union(Integer,"failed")) case Integer) and
+ positive?(rx))
+ => hackroot((numer x)::F, n)/hackroot(rx::Integer::F, n)
+ (x = -1) and n = 4 =>
+ ((-1::F) ** (1::Q / 2::Q) + 1) / ((2::F) ** (1::Q / 2::Q))
+ kernel(oproot, [x, n::F])
+
+@
+<<package AF AlgebraicFunction>>=
+)abbrev package AF AlgebraicFunction
+++ Author: Manuel Bronstein
+++ Date Created: 21 March 1988
+++ Date Last Updated: 11 November 1993
+++ Description:
+++ This package provides algebraic functions over an integral domain.
+++ Keywords: algebraic, function.
+
+AlgebraicFunction(R, F): Exports == Implementation where
+ R: Join(OrderedSet, IntegralDomain)
+ F: FunctionSpace R
+
+ SE ==> Symbol
+ Z ==> Integer
+ Q ==> Fraction Z
+ OP ==> BasicOperator
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ UPR ==> SparseUnivariatePolynomial R
+ ALGOP ==> "%alg"
+ SPECIALDISP ==> "%specialDisp"
+ SPECIALDIFF ==> "%specialDiff"
+
+ Exports ==> with
+ rootOf : (UP, SE) -> F
+ ++ rootOf(p, y) returns y such that \spad{p(y) = 0}.
+ ++ The object returned displays as \spad{'y}.
+ operator: OP -> OP
+ ++ operator(op) returns a copy of \spad{op} with the domain-dependent
+ ++ properties appropriate for \spad{F}.
+ ++ Error: if op is not an algebraic operator, that is,
+ ++ an nth root or implicit algebraic operator.
+ belong? : OP -> Boolean
+ ++ belong?(op) is true if \spad{op} is an algebraic operator, that is,
+ ++ an nth root or implicit algebraic operator.
+ inrootof: (UP, F) -> F
+ ++ inrootof(p, x) should be a non-exported function.
+ -- un-export when the compiler accepts conditional local functions!
+ droot : List F -> OutputForm
+ ++ droot(l) should be a non-exported function.
+ -- un-export when the compiler accepts conditional local functions!
+ if R has RetractableTo Integer then
+ "**" : (F, Q) -> F
+ ++ x ** q is \spad{x} raised to the rational power \spad{q}.
+ minPoly: K -> UP
+ ++ minPoly(k) returns the defining polynomial of \spad{k}.
+ definingPolynomial: F -> F
+ ++ definingPolynomial(f) returns the defining polynomial of \spad{f}
+ ++ as an element of \spad{F}.
+ ++ Error: if f is not a kernel.
+ iroot : (R, Z) -> F
+ ++ iroot(p, n) should be a non-exported function.
+ -- un-export when the compiler accepts conditional local functions!
+
+ Implementation ==> add
+ ialg : List F -> F
+ dvalg: (List F, SE) -> F
+ dalg : List F -> OutputForm
+
+ opalg := operator("rootOf"::Symbol)$CommonOperators
+ oproot := operator("nthRoot"::Symbol)$CommonOperators
+
+ belong? op == has?(op, ALGOP)
+ dalg l == second(l)::OutputForm
+
+ rootOf(p, x) ==
+ k := kernel(x)$K
+ (r := retractIfCan(p)@Union(F, "failed")) case "failed" =>
+ inrootof(p, k::F)
+ n := numer(f := univariate(r::F, k))
+ degree denom f > 0 => error "roofOf: variable appears in denom"
+ inrootof(n, k::F)
+
+ dvalg(l, x) ==
+ p := numer univariate(first l, retract(second l)@K)
+ alpha := kernel(opalg, l)
+ - (map(differentiate(#1, x), p) alpha) / ((differentiate p) alpha)
+
+ ialg l ==
+ f := univariate(p := first l, retract(x := second l)@K)
+ degree denom f > 0 => error "roofOf: variable appears in denom"
+ inrootof(numer f, x)
+
+ operator op ==
+ is?(op, "rootOf"::Symbol) => opalg
+ is?(op, "nthRoot"::Symbol) => oproot
+ error "Unknown operator"
+
+ if R has AlgebraicallyClosedField then
+ UP2R: UP -> Union(UPR, "failed")
+
+ inrootof(q, x) ==
+ monomial? q => 0
+
+ (d := degree q) <= 0 => error "rootOf: constant polynomial"
+-- one? d=> - leadingCoefficient(reductum q) / leadingCoefficient q
+ (d = 1) => - leadingCoefficient(reductum q) / leadingCoefficient q
+ ((rx := retractIfCan(x)@Union(SE, "failed")) case SE) and
+ ((r := UP2R q) case UPR) => rootOf(r::UPR, rx::SE)::F
+ kernel(opalg, [q x, x])
+
+ UP2R p ==
+ ans:UPR := 0
+ while p ^= 0 repeat
+ (r := retractIfCan(leadingCoefficient p)@Union(R, "failed"))
+ case "failed" => return "failed"
+ ans := ans + monomial(r::R, degree p)
+ p := reductum p
+ ans
+
+ else
+ inrootof(q, x) ==
+ monomial? q => 0
+ (d := degree q) <= 0 => error "rootOf: constant polynomial"
+-- one? d => - leadingCoefficient(reductum q) /leadingCoefficient q
+ (d = 1) => - leadingCoefficient(reductum q) /leadingCoefficient q
+ kernel(opalg, [q x, x])
+
+ evaluate(opalg, ialg)$BasicOperatorFunctions1(F)
+ setProperty(opalg, SPECIALDIFF,
+ dvalg@((List F, SE) -> F) pretend None)
+ setProperty(opalg, SPECIALDISP,
+ dalg@(List F -> OutputForm) pretend None)
+
+ if R has RetractableTo Integer then
+ import PolynomialRoots(IndexedExponents K, K, R, P, F)
+
+ dumvar := "%%var"::Symbol::F
+
+ lzero : List F -> F
+ dvroot : List F -> F
+ inroot : List F -> F
+ hackroot: (F, Z) -> F
+ inroot0 : (F, Z, Boolean, Boolean) -> F
+
+ lzero l == 0
+
+ droot l ==
+ x := first(l)::OutputForm
+ (n := retract(second l)@Z) = 2 => root x
+ root(x, n::OutputForm)
+
+ dvroot l ==
+ n := retract(second l)@Z
+ (first(l) ** ((1 - n) / n)) / (n::F)
+
+ x ** q ==
+ qr := divide(numer q, denom q)
+ x ** qr.quotient * inroot([x, (denom q)::F]) ** qr.remainder
+
+<<hackroot(x, n)>>
+
+ inroot l ==
+ zero?(n := retract(second l)@Z) => error "root: exponent = 0"
+-- one?(x := first l) or one? n => x
+ ((x := first l) = 1) or (n = 1) => x
+ (r := retractIfCan(x)@Union(R,"failed")) case R => iroot(r::R,n)
+ (u := isExpt(x, oproot)) case Record(var:K, exponent:Z) =>
+ pr := u::Record(var:K, exponent:Z)
+ (first argument(pr.var)) **
+ (pr.exponent /$Fraction(Z)
+ (n * retract(second argument(pr.var))@Z))
+ inroot0(x, n, false, false)
+
+-- removes powers of positive integers from numer and denom
+-- num? or den? is true if numer or denom already processed
+ inroot0(x, n, num?, den?) ==
+ rn:Union(Z, "failed") := (num? => "failed"; retractIfCan numer x)
+ rd:Union(Z, "failed") := (den? => "failed"; retractIfCan denom x)
+ (rn case Z) and (rd case Z) =>
+ rec := qroot(rn::Z / rd::Z, n::NonNegativeInteger)
+ rec.coef * hackroot(rec.radicand, rec.exponent)
+ rn case Z =>
+ rec := qroot(rn::Z::Fraction(Z), n::NonNegativeInteger)
+ rec.coef * inroot0((rec.radicand**(n exquo rec.exponent)::Z)
+ / (denom(x)::F), n, true, den?)
+ rd case Z =>
+ rec := qroot(rd::Z::Fraction(Z), n::NonNegativeInteger)
+ inroot0((numer(x)::F) /
+ (rec.radicand ** (n exquo rec.exponent)::Z),
+ n, num?, true) / rec.coef
+ hackroot(x, n)
+
+ if R has AlgebraicallyClosedField then iroot(r, n) == nthRoot(r, n)::F
+ else
+ iroot0: (R, Z) -> F
+
+ if R has RadicalCategory then
+ if R has imaginary:() -> R then iroot(r, n) == nthRoot(r, n)::F
+ else
+ iroot(r, n) ==
+ odd? n or r >= 0 => nthRoot(r, n)::F
+ iroot0(r, n)
+
+ else iroot(r, n) == iroot0(r, n)
+
+ iroot0(r, n) ==
+ rec := rroot(r, n::NonNegativeInteger)
+ rec.coef * hackroot(rec.radicand, rec.exponent)
+
+ definingPolynomial x ==
+ (r := retractIfCan(x)@Union(K, "failed")) case K =>
+ is?(k := r::K, opalg) => first argument k
+ is?(k, oproot) =>
+ dumvar ** retract(second argument k)@Z - first argument k
+ dumvar - x
+ dumvar - x
+
+ minPoly k ==
+ is?(k, opalg) =>
+ numer univariate(first argument k,
+ retract(second argument k)@K)
+ is?(k, oproot) =>
+ monomial(1,retract(second argument k)@Z :: NonNegativeInteger)
+ - first(argument k)::UP
+ monomial(1, 1) - k::F::UP
+
+ evaluate(oproot, inroot)$BasicOperatorFunctions1(F)
+ derivative(oproot, [dvroot, lzero])
+
+ else -- R is not retractable to Integer
+ droot l ==
+ x := first(l)::OutputForm
+ (n := second l) = 2::F => root x
+ root(x, n::OutputForm)
+
+ minPoly k ==
+ is?(k, opalg) =>
+ numer univariate(first argument k,
+ retract(second argument k)@K)
+ monomial(1, 1) - k::F::UP
+
+ setProperty(oproot, SPECIALDISP,
+ droot@(List F -> OutputForm) pretend None)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl fspace ALGFUNC expr
+
+<<category ACF AlgebraicallyClosedField>>
+<<category ACFS AlgebraicallyClosedFunctionSpace>>
+<<package AF AlgebraicFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/allfact.spad.pamphlet b/src/algebra/allfact.spad.pamphlet
new file mode 100644
index 00000000..ccc9497d
--- /dev/null
+++ b/src/algebra/allfact.spad.pamphlet
@@ -0,0 +1,486 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra allfact.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MRATFAC MRationalFactorize}
+<<package MRATFAC MRationalFactorize>>=
+)abbrev package MRATFAC MRationalFactorize
+++ Author: P. Gianni
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: MultivariateFactorize
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: MRationalFactorize contains the factor function for multivariate
+++ polynomials over the quotient field of a ring R such that the package
+++ MultivariateFactorize can factor multivariate polynomials over R.
+
+
+MRationalFactorize(E,OV,R,P) : C == T
+ where
+ E : OrderedAbelianMonoidSup
+ OV : OrderedSet
+ R : Join(EuclideanDomain, CharacteristicZero) -- with factor over R[x]
+ FR ==> Fraction R
+ P : PolynomialCategory(FR,E,OV)
+ MPR ==> SparseMultivariatePolynomial(R,OV)
+ SUP ==> SparseUnivariatePolynomial
+
+ C == with
+ factor : P -> Factored P
+ ++ factor(p) factors the multivariate polynomial p with coefficients
+ ++ which are fractions of elements of R.
+
+ T == add
+ IE ==> IndexedExponents OV
+ PCLFRR ==> PolynomialCategoryLifting(E,OV,FR,P,MPR)
+ PCLRFR ==> PolynomialCategoryLifting(IE,OV,R,MPR,P)
+ MFACT ==> MultivariateFactorize(OV,IE,R,MPR)
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+ numer1(c:FR): MPR == (numer c) :: MPR
+ numer2(pol:P) : MPR == map(coerce,numer1,pol)$PCLFRR
+ coerce1(d:R) : P == (d::FR)::P
+ coerce2(pp:MPR) :P == map(coerce,coerce1,pp)$PCLRFR
+
+ factor(p:P) : Factored P ==
+ pden:R:=lcm([denom c for c in coefficients p])
+ pol :P:= (pden::FR)*p
+ ipol:MPR:= map(coerce,numer1,pol)$PCLFRR
+ ffact:=(factor ipol)$MFACT
+ (1/pden)*map(coerce,coerce1,(unit ffact))$PCLRFR *
+ _*/[primeFactor(map(coerce,coerce1,u.factor)$PCLRFR,
+ u.exponent) for u in factors ffact]
+
+@
+\section{package MPRFF MPolyCatRationalFunctionFactorizer}
+<<package MPRFF MPolyCatRationalFunctionFactorizer>>=
+)abbrev package MPRFF MPolyCatRationalFunctionFactorizer
+++ Author: P. Gianni
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package exports a factor operation for multivariate polynomials
+++ with coefficients which are rational functions over
+++ some ring R over which we can factor. It is used internally by packages
+++ such as primary decomposition which need to work with polynomials
+++ with rational function coefficients, i.e. themselves fractions of
+++ polynomials.
+
+MPolyCatRationalFunctionFactorizer(E,OV,R,PRF) : C == T
+ where
+ R : IntegralDomain
+ F ==> Fraction Polynomial R
+ RN ==> Fraction Integer
+ E : OrderedAbelianMonoidSup
+ OV : OrderedSet with
+ convert : % -> Symbol
+ ++ convert(x) converts x to a symbol
+ PRF : PolynomialCategory(F,E,OV)
+ NNI ==> NonNegativeInteger
+ P ==> Polynomial R
+ ISE ==> IndexedExponents SE
+ SE ==> Symbol
+ UP ==> SparseUnivariatePolynomial P
+ UF ==> SparseUnivariatePolynomial F
+ UPRF ==> SparseUnivariatePolynomial PRF
+ QuoForm ==> Record(sup:P,inf:P)
+
+ C == with
+ totalfract : PRF -> QuoForm
+ ++ totalfract(prf) takes a polynomial whose coefficients are
+ ++ themselves fractions of polynomials and returns a record
+ ++ containing the numerator and denominator resulting from
+ ++ putting prf over a common denominator.
+ pushdown : (PRF,OV) -> PRF
+ ++ pushdown(prf,var) pushes all top level occurences of the
+ ++ variable var into the coefficient domain for the polynomial prf.
+ pushdterm : (UPRF,OV) -> PRF
+ ++ pushdterm(monom,var) pushes all top level occurences of the
+ ++ variable var into the coefficient domain for the monomial monom.
+ pushup : (PRF,OV) -> PRF
+ ++ pushup(prf,var) raises all occurences of the
+ ++ variable var in the coefficients of the polynomial prf
+ ++ back to the polynomial level.
+ pushucoef : (UP,OV) -> PRF
+ ++ pushucoef(upoly,var) converts the anonymous univariate
+ ++ polynomial upoly to a polynomial in var over rational functions.
+ pushuconst : (F,OV) -> PRF
+ ++ pushuconst(r,var) takes a rational function and raises
+ ++ all occurances of the variable var to the polynomial level.
+ factor : PRF -> Factored PRF
+ ++ factor(prf) factors a polynomial with rational function
+ ++ coefficients.
+
+ --- Local Functions ----
+ T == add
+
+ ---- factorization of p ----
+ factor(p:PRF) : Factored PRF ==
+ truelist:List OV :=variables p
+ tp:=totalfract(p)
+ nump:P:= tp.sup
+ denp:F:=inv(tp.inf ::F)
+ ffact : List(Record(irr:PRF,pow:Integer))
+ flist:Factored P
+ if R is Fraction Integer then
+ flist:=
+ ((factor nump)$MRationalFactorize(ISE,SE,Integer,P))
+ pretend (Factored P)
+ else
+ if R has FiniteFieldCategory then
+ flist:= ((factor nump)$MultFiniteFactorize(SE,ISE,R,P))
+ pretend (Factored P)
+
+ else
+ if R has Field then error "not done yet"
+
+ else
+ if R has CharacteristicZero then
+ flist:= ((factor nump)$MultivariateFactorize(SE,ISE,R,P))
+ pretend (Factored P)
+ else error "can't happen"
+ ffact:=[[u.factor::F::PRF,u.exponent] for u in factors flist]
+ fcont:=(unit flist)::F::PRF
+ for x in truelist repeat
+ fcont:=pushup(fcont,x)
+ ffact:=[[pushup(ff.irr,x),ff.pow] for ff in ffact]
+ (denp*fcont)*(_*/[primeFactor(ff.irr,ff.pow) for ff in ffact])
+
+
+-- the following functions are used to "push" x in the coefficient ring -
+
+ ---- push x in the coefficient domain for a polynomial ----
+ pushdown(g:PRF,x:OV) : PRF ==
+ ground? g => g
+ rf:PRF:=0$PRF
+ ug:=univariate(g,x)
+ while ug^=0 repeat
+ rf:=rf+pushdterm(ug,x)
+ ug := reductum ug
+ rf
+
+ ---- push x in the coefficient domain for a term ----
+ pushdterm(t:UPRF,x:OV):PRF ==
+ n:=degree(t)
+ cf:=monomial(1,convert x,n)$P :: F
+ cf * leadingCoefficient t
+
+ ---- push back the variable ----
+ pushup(f:PRF,x:OV) :PRF ==
+ ground? f => pushuconst(retract f,x)
+ v:=mainVariable(f)::OV
+ g:=univariate(f,v)
+ multivariate(map(pushup(#1,x),g),v)
+
+ ---- push x back from the coefficient domain ----
+ pushuconst(r:F,x:OV):PRF ==
+ xs:SE:=convert x
+ degree(denom r,xs)>0 => error "bad polynomial form"
+ inv((denom r)::F)*pushucoef(univariate(numer r,xs),x)
+
+
+ pushucoef(c:UP,x:OV):PRF ==
+ c = 0 => 0
+ monomial((leadingCoefficient c)::F::PRF,x,degree c) +
+ pushucoef(reductum c,x)
+
+
+ ---- write p with a common denominator ----
+
+ totalfract(p:PRF) : QuoForm ==
+ p=0 => [0$P,1$P]$QuoForm
+ for x in variables p repeat p:=pushdown(p,x)
+ g:F:=retract p
+ [numer g,denom g]$QuoForm
+
+@
+\section{package MPCPF MPolyCatPolyFactorizer}
+<<package MPCPF MPolyCatPolyFactorizer>>=
+)abbrev package MPCPF MPolyCatPolyFactorizer
+++ Author: P. Gianni
+++ Date Created:
+++ Date Last Updated: March 1995
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package exports a factor operation for multivariate polynomials
+++ with coefficients which are polynomials over
+++ some ring R over which we can factor. It is used internally by packages
+++ such as the solve package which need to work with polynomials in a specific
+++ set of variables with coefficients which are polynomials in all the other
+++ variables.
+
+MPolyCatPolyFactorizer(E,OV,R,PPR) : C == T
+ where
+ R : EuclideanDomain
+ E : OrderedAbelianMonoidSup
+ -- following type is required by PushVariables
+ OV : OrderedSet with
+ convert : % -> Symbol
+ ++ convert(x) converts x to a symbol
+ variable: Symbol -> Union(%, "failed")
+ ++ variable(s) makes an element from symbol s or fails.
+ PR ==> Polynomial R
+ PPR : PolynomialCategory(PR,E,OV)
+ NNI ==> NonNegativeInteger
+ ISY ==> IndexedExponents Symbol
+ SE ==> Symbol
+ UP ==> SparseUnivariatePolynomial PR
+ UPPR ==> SparseUnivariatePolynomial PPR
+
+ C == with
+ factor : PPR -> Factored PPR
+ ++ factor(p) factors a polynomial with polynomial
+ ++ coefficients.
+
+ --- Local Functions ----
+ T == add
+
+ import PushVariables(R,E,OV,PPR)
+
+ ---- factorization of p ----
+ factor(p:PPR) : Factored PPR ==
+ ground? p => nilFactor(p,1)
+ c := content p
+ p := (p exquo c)::PPR
+ vars:List OV :=variables p
+ g:PR:=retract pushdown(p, vars)
+ flist := factor(g)$GeneralizedMultivariateFactorize(Symbol,ISY,R,R,PR)
+ ffact : List(Record(irr:PPR,pow:Integer))
+ ffact:=[[pushup(u.factor::PPR,vars),u.exponent] for u in factors flist]
+ fcont:=(unit flist)::PPR
+ nilFactor(c*fcont,1)*(_*/[primeFactor(ff.irr,ff.pow) for ff in ffact])
+
+@
+\section{package GENMFACT GeneralizedMultivariateFactorize}
+<<package GENMFACT GeneralizedMultivariateFactorize>>=
+)abbrev package GENMFACT GeneralizedMultivariateFactorize
+++ Author: P. Gianni
+++ Date Created: 1983
+++ Date Last Updated: Sept. 1990
+++ Basic Functions:
+++ Related Constructors: MultFiniteFactorize, AlgebraicMultFact, MultivariateFactorize
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is the top level package for doing multivariate factorization
+++ over basic domains like \spadtype{Integer} or \spadtype{Fraction Integer}.
+
+GeneralizedMultivariateFactorize(OV,E,S,R,P) : C == T
+ where
+ R : IntegralDomain
+ -- with factor on R[x]
+ S : IntegralDomain
+ OV : OrderedSet with
+ convert : % -> Symbol
+ ++ convert(x) converts x to a symbol
+ variable: Symbol -> Union(%, "failed")
+ ++ variable(s) makes an element from symbol s or fails.
+ E : OrderedAbelianMonoidSup
+ P : PolynomialCategory(R,E,OV)
+
+ C == with
+ factor : P -> Factored P
+ ++ factor(p) factors the multivariate polynomial p over its coefficient
+ ++ domain
+
+ T == add
+ factor(p:P) : Factored P ==
+ R has FiniteFieldCategory => factor(p)$MultFiniteFactorize(OV,E,R,P)
+ R is Polynomial(S) and S has EuclideanDomain =>
+ factor(p)$MPolyCatPolyFactorizer(E,OV,S,P)
+ R is Fraction(S) and S has CharacteristicZero and
+ S has EuclideanDomain =>
+ factor(p)$MRationalFactorize(E,OV,S,P)
+ R is Fraction Polynomial S =>
+ factor(p)$MPolyCatRationalFunctionFactorizer(E,OV,S,P)
+ R has CharacteristicZero and R has EuclideanDomain =>
+ factor(p)$MultivariateFactorize(OV,E,R,P)
+ squareFree p
+
+@
+\section{package RFFACTOR RationalFunctionFactorizer}
+<<package RFFACTOR RationalFunctionFactorizer>>=
+)abbrev package RFFACTOR RationalFunctionFactorizer
+++ Author: P. Gianni
+++ Date Created:
+++ Date Last Updated: March 1995
+++ Basic Functions:
+++ Related Constructors: Fraction, Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{RationalFunctionFactorizer} contains the factor function
+++ (called factorFraction) which factors fractions of polynomials by factoring
+++ the numerator and denominator. Since any non zero fraction is a unit
+++ the usual factor operation will just return the original fraction.
+
+RationalFunctionFactorizer(R) : C == T
+ where
+ R : EuclideanDomain -- R with factor for R[X]
+ P ==> Polynomial R
+ FP ==> Fraction P
+ SE ==> Symbol
+
+ C == with
+ factorFraction : FP -> Fraction Factored(P)
+ ++ factorFraction(r) factors the numerator and the denominator of
+ ++ the polynomial fraction r.
+ T == add
+
+ factorFraction(p:FP) : Fraction Factored(P) ==
+ R is Fraction Integer =>
+ MR:=MRationalFactorize(IndexedExponents SE,SE,
+ Integer,P)
+ (factor(numer p)$MR)/ (factor(denom p)$MR)
+
+ R has FiniteFieldCategory =>
+ FF:=MultFiniteFactorize(SE,IndexedExponents SE,R,P)
+ (factor(numer p))$FF/(factor(denom p))$FF
+
+ R has CharacteristicZero =>
+ MFF:=MultivariateFactorize(SE,IndexedExponents SE,R,P)
+ (factor(numer p))$MFF/(factor(denom p))$MFF
+ error "case not handled"
+
+@
+\section{package SUPFRACF SupFractionFactorizer}
+<<package SUPFRACF SupFractionFactorizer>>=
+)abbrev package SUPFRACF SupFractionFactorizer
+++ Author: P. Gianni
+++ Date Created: October 1993
+++ Date Last Updated: March 1995
+++ Basic Functions:
+++ Related Constructors: MultivariateFactorize
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: SupFractionFactorize
+++ contains the factor function for univariate
+++ polynomials over the quotient field of a ring S such that the package
+++ MultivariateFactorize works for S
+
+SupFractionFactorizer(E,OV,R,P) : C == T
+ where
+ E : OrderedAbelianMonoidSup
+ OV : OrderedSet
+ R : GcdDomain
+ P : PolynomialCategory(R,E,OV)
+ FP ==> Fraction P
+ SUP ==> SparseUnivariatePolynomial
+
+ C == with
+ factor : SUP FP -> Factored SUP FP
+ ++ factor(p) factors the univariate polynomial p with coefficients
+ ++ which are fractions of polynomials over R.
+ squareFree : SUP FP -> Factored SUP FP
+ ++ squareFree(p) returns the square-free factorization of the univariate polynomial p with coefficients
+ ++ which are fractions of polynomials over R. Each factor has no repeated roots and the factors are
+ ++ pairwise relatively prime.
+
+ T == add
+ MFACT ==> MultivariateFactorize(OV,E,R,P)
+ MSQFR ==> MultivariateSquareFree(E,OV,R,P)
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+ factor(p:SUP FP) : Factored SUP FP ==
+ p=0 => 0
+ R has CharacteristicZero and R has EuclideanDomain =>
+ pden : P := lcm [denom c for c in coefficients p]
+ pol : SUP FP := (pden::FP)*p
+ ipol: SUP P := map(numer,pol)$UPCF2(FP,SUP FP,P,SUP P)
+ ffact: Factored SUP P := 0
+ ffact := factor(ipol)$MFACT
+ makeFR((1/pden * map(coerce,unit ffact)$UPCF2(P,SUP P,FP,SUP FP)),
+ [["prime",map(coerce,u.factor)$UPCF2(P,SUP P,FP,SUP FP),
+ u.exponent] for u in factors ffact])
+ squareFree p
+
+ squareFree(p:SUP FP) : Factored SUP FP ==
+ p=0 => 0
+ pden : P := lcm [denom c for c in coefficients p]
+ pol : SUP FP := (pden::FP)*p
+ ipol: SUP P := map(numer,pol)$UPCF2(FP,SUP FP,P,SUP P)
+ ffact: Factored SUP P := 0
+ if R has CharacteristicZero and R has EuclideanDomain then
+ ffact := squareFree(ipol)$MSQFR
+ else ffact := squareFree(ipol)
+ makeFR((1/pden * map(coerce,unit ffact)$UPCF2(P,SUP P,FP,SUP FP)),
+ [["sqfr",map(coerce,u.factor)$UPCF2(P,SUP P,FP,SUP FP),
+ u.exponent] for u in factors ffact])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MRATFAC MRationalFactorize>>
+<<package MPRFF MPolyCatRationalFunctionFactorizer>>
+<<package MPCPF MPolyCatPolyFactorizer>>
+<<package GENMFACT GeneralizedMultivariateFactorize>>
+<<package RFFACTOR RationalFunctionFactorizer>>
+<<package SUPFRACF SupFractionFactorizer>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/alql.spad.pamphlet b/src/algebra/alql.spad.pamphlet
new file mode 100644
index 00000000..5865b39e
--- /dev/null
+++ b/src/algebra/alql.spad.pamphlet
@@ -0,0 +1,265 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra alql.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain DLIST DataList}
+<<domain DLIST DataList>>=
+)abbrev domain DLIST DataList
+++ This domain provides some nice functions on lists
+DataList(S:OrderedSet) : Exports == Implementation where
+ Exports == ListAggregate(S) with
+ coerce: List S -> %
+ ++ coerce(l) creates a datalist from l
+ coerce: % -> List S
+ ++ coerce(x) returns the list of elements in x
+ datalist: List S -> %
+ ++ datalist(l) creates a datalist from l
+ elt: (%,"unique") -> %
+ ++ \axiom{l.unique} returns \axiom{l} with duplicates removed.
+ ++ Note: \axiom{l.unique = removeDuplicates(l)}.
+ elt: (%,"sort") -> %
+ ++ \axiom{l.sort} returns \axiom{l} with elements sorted.
+ ++ Note: \axiom{l.sort = sort(l)}
+ elt: (%,"count") -> NonNegativeInteger
+ ++ \axiom{l."count"} returns the number of elements in \axiom{l}.
+ Implementation == List(S) add
+ elt(x,"unique") == removeDuplicates(x)
+ elt(x,"sort") == sort(x)
+ elt(x,"count") == #x
+ coerce(x:List S) == x pretend %
+ coerce(x:%):List S == x pretend (List S)
+ coerce(x:%): OutputForm == (x :: List S) :: OutputForm
+ datalist(x:List S) == x::%
+
+@
+\section{domain ICARD IndexCard}
+<<domain ICARD IndexCard>>=
+)abbrev domain ICARD IndexCard
+++ This domain implements a container of information
+++ about the AXIOM library
+IndexCard() : Exports == Implementation where
+ Exports == OrderedSet with
+ elt: (%,Symbol) -> String
+ ++ elt(ic,s) selects a particular field from \axiom{ic}. Valid fields
+ ++ are \axiom{name, nargs, exposed, type, abbreviation, kind, origin,
+ ++ params, condition, doc}.
+ display: % -> Void
+ ++ display(ic) prints a summary of the information contained in \axiom{ic}.
+ fullDisplay: % -> Void
+ ++ fullDisplay(ic) prints all of the information contained in \axiom{ic}.
+ coerce: String -> %
+ ++ coerce(s) converts \axiom{s} into an \axiom{IndexCard}. Warning: if
+ ++ \axiom{s} is not of the right format then an error will occur when using
+ ++ it.
+ Implementation == add
+ x<y==(x pretend String) < (y pretend String)
+ x=y==(x pretend String) = (y pretend String)
+ display(x) ==
+ name : OutputForm := dbName(x)$Lisp
+ type : OutputForm := dbPart(x,4,1$Lisp)$Lisp
+ output(hconcat(name,hconcat(" : ",type)))$OutputPackage
+ fullDisplay(x) ==
+ name : OutputForm := dbName(x)$Lisp
+ type : OutputForm := dbPart(x,4,1$Lisp)$Lisp
+ origin:OutputForm := hconcat(alqlGetOrigin(x$Lisp)$Lisp,alqlGetParams(x$Lisp)$Lisp)
+ fromPart : OutputForm := hconcat(" from ",origin)
+ condition : String := dbPart(x,6,1$Lisp)$Lisp
+ ifPart : OutputForm :=
+ condition = "" => empty()
+ hconcat(" if ",condition::OutputForm)
+ exposed? : String := SUBSTRING(dbPart(x,3,1)$Lisp,0,1)$Lisp
+ exposedPart : OutputForm :=
+ exposed? = "n" => " (unexposed)"
+ empty()
+ firstPart := hconcat(name,hconcat(" : ",type))
+ secondPart := hconcat(fromPart,hconcat(ifPart,exposedPart))
+ output(hconcat(firstPart,secondPart))$OutputPackage
+ coerce(s:String): % == (s pretend %)
+ coerce(x): OutputForm == (x pretend String)::OutputForm
+ elt(x,sel) ==
+ s := PNAME(sel)$Lisp pretend String
+ s = "name" => dbName(x)$Lisp
+ s = "nargs" => dbPart(x,2,1$Lisp)$Lisp
+ s = "exposed" => SUBSTRING(dbPart(x,3,1)$Lisp,0,1)$Lisp
+ s = "type" => dbPart(x,4,1$Lisp)$Lisp
+ s = "abbreviation" => dbPart(x,5,1$Lisp)$Lisp
+ s = "kind" => alqlGetKindString(x)$Lisp
+ s = "origin" => alqlGetOrigin(x)$Lisp
+ s = "params" => alqlGetParams(x)$Lisp
+ s = "condition" => dbPart(x,6,1$Lisp)$Lisp
+ s = "doc" => dbComments(x)$Lisp
+ error "unknown selector"
+
+@
+\section{domain DBASE Database}
+<<domain DBASE Database>>=
+)abbrev domain DBASE Database
+++ This domain implements a simple view of a database whose fields are
+++ indexed by symbols
+Database(S): Exports == Implementation where
+ S: OrderedSet with
+ elt: (%,Symbol) -> String
+ ++ elt(x,s) returns an element of x indexed by s
+ display: % -> Void
+ ++ display(x) displays x in some form
+ fullDisplay: % -> Void
+ ++ fullDisplay(x) displays x in detail
+ Exports == SetCategory with
+ elt: (%,QueryEquation) -> %
+ ++ elt(db,q) returns all elements of \axiom{db} which satisfy \axiom{q}.
+ elt: (%,Symbol) -> DataList String
+ ++ elt(db,s) returns the \axiom{s} field of each element of \axiom{db}.
+ _+: (%,%) -> %
+ ++ db1+db2 returns the merge of databases db1 and db2
+ _-: (%,%) -> %
+ ++ db1-db2 returns the difference of databases db1 and db2 i.e. consisting
+ ++ of elements in db1 but not in db2
+ coerce: List S -> %
+ ++ coerce(l) makes a database out of a list
+ display: % -> Void
+ ++ display(db) prints a summary line for each entry in \axiom{db}.
+ fullDisplay: % -> Void
+ ++ fullDisplay(db) prints full details of each entry in \axiom{db}.
+ fullDisplay: (%,PositiveInteger,PositiveInteger) -> Void
+ ++ fullDisplay(db,start,end ) prints full details of entries in the range
+ ++ \axiom{start..end} in \axiom{db}.
+ Implementation == List S add
+ s: Symbol
+ Rep := List S
+ coerce(u: List S):% == u@%
+ elt(data: %,s: Symbol) == [x.s for x in data] :: DataList(String)
+ elt(data: %,eq: QueryEquation) ==
+ field := variable eq
+ val := value eq
+ [x for x in data | stringMatches?(val,x.field)$Lisp]
+ x+y==removeDuplicates_! merge(x,y)
+ x-y==mergeDifference(copy(x::Rep),y::Rep)$MergeThing(S)
+ coerce(data): OutputForm == (#data):: OutputForm
+ display(data) == for x in data repeat display x
+ fullDisplay(data) == for x in data repeat fullDisplay x
+ fullDisplay(data,n,m) == for x in data for i in 1..m repeat
+ if i >= n then fullDisplay x
+
+@
+\section{domain QEQUAT QueryEquation}
+<<domain QEQUAT QueryEquation>>=
+)abbrev domain QEQUAT QueryEquation
+++ This domain implements simple database queries
+QueryEquation(): Exports == Implementation where
+ Exports == CoercibleTo(OutputForm) with
+ equation: (Symbol,String) -> %
+ ++ equation(s,"a") creates a new equation.
+ variable: % -> Symbol
+ ++ variable(q) returns the variable (i.e. left hand side) of \axiom{q}.
+ value: % -> String
+ ++ value(q) returns the value (i.e. right hand side) of \axiom{q}.
+ Implementation == add
+ Rep := Record(var:Symbol, val:String)
+ coerce(u) == coerce(u.var)$Symbol = coerce(u.val)$String
+ equation(x,s) == [x,s]
+ variable q == q.var
+ value q == q.val
+
+@
+\section{package MTHING MergeThing}
+<<package MTHING MergeThing>>=
+)abbrev package MTHING MergeThing
+++ This package exports tools for merging lists
+MergeThing(S:OrderedSet): Exports == Implementation where
+ Exports == with
+ mergeDifference: (List(S),List(S)) -> List(S)
+ ++ mergeDifference(l1,l2) returns a list of elements in l1 not present in l2.
+ ++ Assumes lists are ordered and all x in l2 are also in l1.
+ Implementation == add
+ mergeDifference1: (List S,S,List S) -> List S
+ mergeDifference(x,y) ==
+ null x or null y => x
+ mergeDifference1(x,y.first,y.rest)
+ x.first=y.first => x.rest
+ x
+ mergeDifference1(x,fy,ry) ==
+ rx := x
+ while not null rx repeat
+ rx := rx.rest
+ frx := rx.first
+ while fy < frx repeat
+ null ry => return x
+ fy := first ry
+ ry := rest ry
+ frx = fy =>
+ x.rest := rx.rest
+ null ry => return x
+ fy := ry.first
+ ry := ry.rest
+ x := rx
+
+@
+\section{package OPQUERY OperationsQuery}
+<<package OPQUERY OperationsQuery>>=
+)abbrev package OPQUERY OperationsQuery
+++ This package exports tools to create AXIOM Library information databases.
+OperationsQuery(): Exports == Implementation where
+ Exports == with
+ getDatabase: String -> Database(IndexCard)
+ ++ getDatabase("char") returns a list of appropriate entries in the
+ ++ browser database. The legal values for "char" are "o" (operations),
+ ++ "k" (constructors), "d" (domains), "c" (categories) or "p" (packages).
+ Implementation == add
+ getDatabase(s) == getBrowseDatabase(s)$Lisp
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain DLIST DataList>>
+<<domain ICARD IndexCard>>
+<<domain DBASE Database>>
+<<domain QEQUAT QueryEquation>>
+<<package MTHING MergeThing>>
+<<package OPQUERY OperationsQuery>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/annacat.spad.pamphlet b/src/algebra/annacat.spad.pamphlet
new file mode 100644
index 00000000..70d5af6c
--- /dev/null
+++ b/src/algebra/annacat.spad.pamphlet
@@ -0,0 +1,504 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra annacat.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain NIPROB NumericalIntegrationProblem}
+<<domain NIPROB NumericalIntegrationProblem>>=
+)abbrev domain NIPROB NumericalIntegrationProblem
+++ Author: Brian Dupee
+++ Date Created: December 1997
+++ Date Last Updated: December 1997
+++ Basic Operations: coerce, retract
+++ Related Constructors: Union
+++ Description:
+++ \axiomType{NumericalIntegrationProblem} is a \axiom{domain}
+++ for the representation of Numerical Integration problems for use
+++ by ANNA.
+++
+++ The representation is a Union of two record types - one for integration of
+++ a function of one variable:
+++
+++ \axiomType{Record}(var:\axiomType{Symbol},
+++ fn:\axiomType{Expression DoubleFloat},
+++ range:\axiomType{Segment OrderedCompletion DoubleFloat},
+++ abserr:\axiomType{DoubleFloat},
+++ relerr:\axiomType{DoubleFloat},)
+++
+++ and one for multivariate integration:
+++
+++ \axiomType{Record}(fn:\axiomType{Expression DoubleFloat},
+++ range:\axiomType{List Segment OrderedCompletion DoubleFloat},
+++ abserr:\axiomType{DoubleFloat},
+++ relerr:\axiomType{DoubleFloat},).
+++
+
+EDFA ==> Expression DoubleFloat
+SOCDFA ==> Segment OrderedCompletion DoubleFloat
+DFA ==> DoubleFloat
+NIAA ==> Record(var:Symbol,fn:EDFA,range:SOCDFA,abserr:DFA,relerr:DFA)
+MDNIAA ==> Record(fn:EDFA,range:List SOCDFA,abserr:DFA,relerr:DFA)
+
+NumericalIntegrationProblem():SetCategory with
+ coerce: NIAA -> %
+ ++ coerce(x) \undocumented{}
+ coerce: MDNIAA -> %
+ ++ coerce(x) \undocumented{}
+ coerce: Union(nia:NIAA,mdnia:MDNIAA) -> %
+ ++ coerce(x) \undocumented{}
+ coerce: % -> OutputForm
+ ++ coerce(x) \undocumented{}
+ retract: % -> Union(nia:NIAA,mdnia:MDNIAA)
+ ++ retract(x) \undocumented{}
+
+ ==
+
+ add
+ Rep := Union(nia:NIAA,mdnia:MDNIAA)
+
+ coerce(s:NIAA) == [s]
+ coerce(s:MDNIAA) == [s]
+ coerce(s:Union(nia:NIAA,mdnia:MDNIAA)) == s
+ coerce(x:%):OutputForm ==
+ (x) case nia => (x.nia)::OutputForm
+ (x.mdnia)::OutputForm
+ retract(x:%):Union(nia:NIAA,mdnia:MDNIAA) ==
+ (x) case nia => [x.nia]
+ [x.mdnia]
+
+@
+\section{domain ODEPROB NumericalODEProblem}
+<<domain ODEPROB NumericalODEProblem>>=
+)abbrev domain ODEPROB NumericalODEProblem
+++ Author: Brian Dupee
+++ Date Created: December 1997
+++ Date Last Updated: December 1997
+++ Basic Operations: coerce, retract
+++ Related Constructors: Union
+++ Description:
+++ \axiomType{NumericalODEProblem} is a \axiom{domain}
+++ for the representation of Numerical ODE problems for use
+++ by ANNA.
+++
+++ The representation is of type:
+++
+++ \axiomType{Record}(xinit:\axiomType{DoubleFloat},
+++ xend:\axiomType{DoubleFloat},
+++ fn:\axiomType{Vector Expression DoubleFloat},
+++ yinit:\axiomType{List DoubleFloat},intvals:\axiomType{List DoubleFloat},
+++ g:\axiomType{Expression DoubleFloat},abserr:\axiomType{DoubleFloat},
+++ relerr:\axiomType{DoubleFloat})
+++
+
+DFB ==> DoubleFloat
+VEDFB ==> Vector Expression DoubleFloat
+LDFB ==> List DoubleFloat
+EDFB ==> Expression DoubleFloat
+ODEAB ==> Record(xinit:DFB,xend:DFB,fn:VEDFB,yinit:LDFB,intvals:LDFB,g:EDFB,abserr:DFB,relerr:DFB)
+NumericalODEProblem():SetCategory with
+
+ coerce: ODEAB -> %
+ ++ coerce(x) \undocumented{}
+ coerce: % -> OutputForm
+ ++ coerce(x) \undocumented{}
+ retract: % -> ODEAB
+ ++ retract(x) \undocumented{}
+
+ ==
+
+ add
+ Rep := ODEAB
+
+ coerce(s:ODEAB) == s
+ coerce(x:%):OutputForm ==
+ (retract(x))::OutputForm
+ retract(x:%):ODEAB == x :: Rep
+
+@
+\section{domain PDEPROB NumericalPDEProblem}
+<<domain PDEPROB NumericalPDEProblem>>=
+)abbrev domain PDEPROB NumericalPDEProblem
+++ Author: Brian Dupee
+++ Date Created: December 1997
+++ Date Last Updated: December 1997
+++ Basic Operations: coerce, retract
+++ Related Constructors: Union
+++ Description:
+++ \axiomType{NumericalPDEProblem} is a \axiom{domain}
+++ for the representation of Numerical PDE problems for use
+++ by ANNA.
+++
+++ The representation is of type:
+++
+++ \axiomType{Record}(pde:\axiomType{List Expression DoubleFloat},
+++ constraints:\axiomType{List PDEC},
+++ f:\axiomType{List List Expression DoubleFloat},
+++ st:\axiomType{String},
+++ tol:\axiomType{DoubleFloat})
+++
+++ where \axiomType{PDEC} is of type:
+++
+++ \axiomType{Record}(start:\axiomType{DoubleFloat},
+++ finish:\axiomType{DoubleFloat},
+++ grid:\axiomType{NonNegativeInteger},
+++ boundaryType:\axiomType{Integer},
+++ dStart:\axiomType{Matrix DoubleFloat},
+++ dFinish:\axiomType{Matrix DoubleFloat})
+++
+
+DFC ==> DoubleFloat
+NNIC ==> NonNegativeInteger
+INTC ==> Integer
+MDFC ==> Matrix DoubleFloat
+PDECC ==> Record(start:DFC, finish:DFC, grid:NNIC, boundaryType:INTC,
+ dStart:MDFC, dFinish:MDFC)
+LEDFC ==> List Expression DoubleFloat
+PDEBC ==> Record(pde:LEDFC, constraints:List PDECC, f:List LEDFC,
+ st:String, tol:DFC)
+NumericalPDEProblem():SetCategory with
+
+ coerce: PDEBC -> %
+ ++ coerce(x) \undocumented{}
+ coerce: % -> OutputForm
+ ++ coerce(x) \undocumented{}
+ retract: % -> PDEBC
+ ++ retract(x) \undocumented{}
+
+ ==
+
+ add
+ Rep := PDEBC
+
+ coerce(s:PDEBC) == s
+ coerce(x:%):OutputForm ==
+ (retract(x))::OutputForm
+ retract(x:%):PDEBC == x :: Rep
+
+@
+\section{domain OPTPROB NumericalOptimizationProblem}
+<<domain OPTPROB NumericalOptimizationProblem>>=
+)abbrev domain OPTPROB NumericalOptimizationProblem
+++ Author: Brian Dupee
+++ Date Created: December 1997
+++ Date Last Updated: December 1997
+++ Basic Operations: coerce, retract
+++ Related Constructors: Union
+++ Description:
+++ \axiomType{NumericalOptimizationProblem} is a \axiom{domain}
+++ for the representation of Numerical Optimization problems for use
+++ by ANNA.
+++
+++ The representation is a Union of two record types - one for otimization of
+++ a single function of one or more variables:
+++
+++ \axiomType{Record}(
+++ fn:\axiomType{Expression DoubleFloat},
+++ init:\axiomType{List DoubleFloat},
+++ lb:\axiomType{List OrderedCompletion DoubleFloat},
+++ cf:\axiomType{List Expression DoubleFloat},
+++ ub:\axiomType{List OrderedCompletion DoubleFloat})
+++
+++ and one for least-squares problems i.e. optimization of a set of
+++ observations of a data set:
+++
+++ \axiomType{Record}(lfn:\axiomType{List Expression DoubleFloat},
+++ init:\axiomType{List DoubleFloat}).
+++
+
+LDFD ==> List DoubleFloat
+LEDFD ==> List Expression DoubleFloat
+LSAD ==> Record(lfn:LEDFD, init:LDFD)
+UNOALSAD ==> Union(noa:NOAD,lsa:LSAD)
+EDFD ==> Expression DoubleFloat
+LOCDFD ==> List OrderedCompletion DoubleFloat
+NOAD ==> Record(fn:EDFD, init:LDFD, lb:LOCDFD, cf:LEDFD, ub:LOCDFD)
+NumericalOptimizationProblem():SetCategory with
+
+ coerce: NOAD -> %
+ ++ coerce(x) \undocumented{}
+ coerce: LSAD -> %
+ ++ coerce(x) \undocumented{}
+ coerce: UNOALSAD -> %
+ ++ coerce(x) \undocumented{}
+ coerce: % -> OutputForm
+ ++ coerce(x) \undocumented{}
+ retract: % -> UNOALSAD
+ ++ retract(x) \undocumented{}
+
+ ==
+
+ add
+ Rep := UNOALSAD
+
+ coerce(s:NOAD) == [s]
+ coerce(s:LSAD) == [s]
+ coerce(x:UNOALSAD) == x
+ coerce(x:%):OutputForm ==
+ (x) case noa => (x.noa)::OutputForm
+ (x.lsa)::OutputForm
+ retract(x:%):UNOALSAD ==
+ (x) case noa => [x.noa]
+ [x.lsa]
+
+@
+\section{category NUMINT NumericalIntegrationCategory}
+<<category NUMINT NumericalIntegrationCategory>>=
+)abbrev category NUMINT NumericalIntegrationCategory
+++ Author: Brian Dupee
+++ Date Created: February 1994
+++ Date Last Updated: March 1996
+++ Description:
+++ \axiomType{NumericalIntegrationCategory} is the \axiom{category} for
+++ describing the set of Numerical Integration \axiom{domains} with
+++ \axiomFun{measure} and \axiomFun{numericalIntegration}.
+
+EDFE ==> Expression DoubleFloat
+SOCDFE ==> Segment OrderedCompletion DoubleFloat
+DFE ==> DoubleFloat
+NIAE ==> Record(var:Symbol,fn:EDFE,range:SOCDFE,abserr:DFE,relerr:DFE)
+MDNIAE ==> Record(fn:EDFE,range:List SOCDFE,abserr:DFE,relerr:DFE)
+NumericalIntegrationCategory(): Category == SetCategory with
+
+ measure:(RoutinesTable,NIAE)->Record(measure:Float,explanations:String,extra:Result)
+ ++ measure(R,args) calculates an estimate of the ability of a particular
+ ++ method to solve a problem.
+ ++
+ ++ This method may be either a specific NAG routine or a strategy (such
+ ++ as transforming the function from one which is difficult to one which
+ ++ is easier to solve).
+ ++
+ ++ It will call whichever agents are needed to perform analysis on the
+ ++ problem in order to calculate the measure. There is a parameter,
+ ++ labelled \axiom{sofar}, which would contain the best compatibility
+ ++ found so far.
+
+ numericalIntegration: (NIAE, Result) -> Result
+ ++ numericalIntegration(args,hints) performs the integration of the
+ ++ function given the strategy or method returned by \axiomFun{measure}.
+
+ measure:(RoutinesTable,MDNIAE)->Record(measure:Float,explanations:String,extra:Result)
+ ++ measure(R,args) calculates an estimate of the ability of a particular
+ ++ method to solve a problem.
+ ++
+ ++ This method may be either a specific NAG routine or a strategy (such
+ ++ as transforming the function from one which is difficult to one which
+ ++ is easier to solve).
+ ++
+ ++ It will call whichever agents are needed to perform analysis on the
+ ++ problem in order to calculate the measure. There is a parameter,
+ ++ labelled \axiom{sofar}, which would contain the best compatibility
+ ++ found so far.
+
+ numericalIntegration: (MDNIAE, Result) -> Result
+ ++ numericalIntegration(args,hints) performs the integration of the
+ ++ function given the strategy or method returned by \axiomFun{measure}.
+
+@
+\section{category ODECAT OrdinaryDifferentialEquationsSolverCategory}
+<<category ODECAT OrdinaryDifferentialEquationsSolverCategory>>=
+)abbrev category ODECAT OrdinaryDifferentialEquationsSolverCategory
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: June 1995
+++ Basic Operations:
+++ Description:
+++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} is the
+++ \axiom{category} for describing the set of ODE solver \axiom{domains}
+++ with \axiomFun{measure} and \axiomFun{ODEsolve}.
+
+DFF ==> DoubleFloat
+VEDFF ==> Vector Expression DoubleFloat
+LDFF ==> List DoubleFloat
+EDFF ==> Expression DoubleFloat
+ODEAF ==> Record(xinit:DFF,xend:DFF,fn:VEDFF,yinit:LDFF,intvals:LDFF,g:EDFF,abserr:DFF,relerr:DFF)
+OrdinaryDifferentialEquationsSolverCategory(): Category == SetCategory with
+
+ measure:(RoutinesTable,ODEAF) -> Record(measure:Float,explanations:String)
+ ++ measure(R,args) calculates an estimate of the ability of a particular
+ ++ method to solve a problem.
+ ++
+ ++ This method may be either a specific NAG routine or a strategy (such
+ ++ as transforming the function from one which is difficult to one which
+ ++ is easier to solve).
+ ++
+ ++ It will call whichever agents are needed to perform analysis on the
+ ++ problem in order to calculate the measure. There is a parameter,
+ ++ labelled \axiom{sofar}, which would contain the best compatibility
+ ++ found so far.
+
+ ODESolve: ODEAF -> Result
+ ++ ODESolve(args) performs the integration of the
+ ++ function given the strategy or method returned by \axiomFun{measure}.
+
+@
+\section{category PDECAT PartialDifferentialEquationsSolverCategory}
+<<category PDECAT PartialDifferentialEquationsSolverCategory>>=
+)abbrev category PDECAT PartialDifferentialEquationsSolverCategory
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: June 1995
+++ Basic Operations:
+++ Description:
+++ \axiomType{PartialDifferentialEquationsSolverCategory} is the
+++ \axiom{category} for describing the set of PDE solver \axiom{domains}
+++ with \axiomFun{measure} and \axiomFun{PDEsolve}.
+
+-- PDEA ==> Record(xmin:F,xmax:F,ymin:F,ymax:F,ngx:NNI,ngy:NNI,_
+-- pde:List Expression Float, bounds:List List Expression Float,_
+-- st:String, tol:DF)
+
+-- measure:(RoutinesTable,PDEA) -> Record(measure:F,explanations:String)
+-- ++ measure(R,args) calculates an estimate of the ability of a particular
+-- ++ method to solve a problem.
+-- ++
+-- ++ This method may be either a specific NAG routine or a strategy (such
+-- ++ as transforming the function from one which is difficult to one which
+-- ++ is easier to solve).
+-- ++
+-- ++ It will call whichever agents are needed to perform analysis on the
+-- ++ problem in order to calculate the measure. There is a parameter,
+-- ++ labelled \axiom{sofar}, which would contain the best compatibility
+-- ++ found so far.
+
+-- PDESolve: PDEA -> Result
+-- ++ PDESolve(args) performs the integration of the
+-- ++ function given the strategy or method returned by \axiomFun{measure}.
+
+DFG ==> DoubleFloat
+NNIG ==> NonNegativeInteger
+INTG ==> Integer
+MDFG ==> Matrix DoubleFloat
+PDECG ==> Record(start:DFG, finish:DFG, grid:NNIG, boundaryType:INTG,
+ dStart:MDFG, dFinish:MDFG)
+LEDFG ==> List Expression DoubleFloat
+PDEBG ==> Record(pde:LEDFG, constraints:List PDECG, f:List LEDFG,
+ st:String, tol:DFG)
+PartialDifferentialEquationsSolverCategory(): Category == SetCategory with
+
+ measure:(RoutinesTable,PDEBG) -> Record(measure:Float,explanations:String)
+ ++ measure(R,args) calculates an estimate of the ability of a particular
+ ++ method to solve a problem.
+ ++
+ ++ This method may be either a specific NAG routine or a strategy (such
+ ++ as transforming the function from one which is difficult to one which
+ ++ is easier to solve).
+ ++
+ ++ It will call whichever agents are needed to perform analysis on the
+ ++ problem in order to calculate the measure. There is a parameter,
+ ++ labelled \axiom{sofar}, which would contain the best compatibility
+ ++ found so far.
+
+ PDESolve: PDEBG -> Result
+ ++ PDESolve(args) performs the integration of the
+ ++ function given the strategy or method returned by \axiomFun{measure}.
+
+@
+\section{category OPTCAT NumericalOptimizationCategory}
+<<category OPTCAT NumericalOptimizationCategory>>=
+)abbrev category OPTCAT NumericalOptimizationCategory
+++ Author: Brian Dupee
+++ Date Created: January 1996
+++ Date Last Updated: March 1996
+++ Description:
+++ \axiomType{NumericalOptimizationCategory} is the \axiom{category} for
+++ describing the set of Numerical Optimization \axiom{domains} with
+++ \axiomFun{measure} and \axiomFun{optimize}.
+
+LDFH ==> List DoubleFloat
+LEDFH ==> List Expression DoubleFloat
+LSAH ==> Record(lfn:LEDFH, init:LDFH)
+EDFH ==> Expression DoubleFloat
+LOCDFH ==> List OrderedCompletion DoubleFloat
+NOAH ==> Record(fn:EDFH, init:LDFH, lb:LOCDFH, cf:LEDFH, ub:LOCDFH)
+NumericalOptimizationCategory(): Category == SetCategory with
+ measure:(RoutinesTable,NOAH)->Record(measure:Float,explanations:String)
+ ++ measure(R,args) calculates an estimate of the ability of a particular
+ ++ method to solve an optimization problem.
+ ++
+ ++ This method may be either a specific NAG routine or a strategy (such
+ ++ as transforming the function from one which is difficult to one which
+ ++ is easier to solve).
+ ++
+ ++ It will call whichever agents are needed to perform analysis on the
+ ++ problem in order to calculate the measure. There is a parameter,
+ ++ labelled \axiom{sofar}, which would contain the best compatibility
+ ++ found so far.
+
+ measure:(RoutinesTable,LSAH)->Record(measure:Float,explanations:String)
+ ++ measure(R,args) calculates an estimate of the ability of a particular
+ ++ method to solve an optimization problem.
+ ++
+ ++ This method may be either a specific NAG routine or a strategy (such
+ ++ as transforming the function from one which is difficult to one which
+ ++ is easier to solve).
+ ++
+ ++ It will call whichever agents are needed to perform analysis on the
+ ++ problem in order to calculate the measure. There is a parameter,
+ ++ labelled \axiom{sofar}, which would contain the best compatibility
+ ++ found so far.
+
+ numericalOptimization:LSAH -> Result
+ ++ numericalOptimization(args) performs the optimization of the
+ ++ function given the strategy or method returned by \axiomFun{measure}.
+
+ numericalOptimization:NOAH -> Result
+ ++ numericalOptimization(args) performs the optimization of the
+ ++ function given the strategy or method returned by \axiomFun{measure}.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain NIPROB NumericalIntegrationProblem>>
+<<domain ODEPROB NumericalODEProblem>>
+<<domain PDEPROB NumericalPDEProblem>>
+<<domain OPTPROB NumericalOptimizationProblem>>
+<<category NUMINT NumericalIntegrationCategory>>
+<<category ODECAT OrdinaryDifferentialEquationsSolverCategory>>
+<<category PDECAT PartialDifferentialEquationsSolverCategory>>
+<<category OPTCAT NumericalOptimizationCategory>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/any.spad.pamphlet b/src/algebra/any.spad.pamphlet
new file mode 100644
index 00000000..cabeec66
--- /dev/null
+++ b/src/algebra/any.spad.pamphlet
@@ -0,0 +1,241 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra any.spad}
+\author{Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain NONE None}
+<<domain NONE None>>=
+)abbrev domain NONE None
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Functions: coerce
+++ Related Constructors: NoneFunctions1
+++ Also See: Any
+++ AMS Classification:
+++ Keywords: none, empty
+++ Description:
+++ \spadtype{None} implements a type with no objects. It is mainly
+++ used in technical situations where such a thing is needed (e.g.
+++ the interpreter and some of the internal \spadtype{Expression}
+++ code).
+
+None():SetCategory == add
+ coerce(none:%):OutputForm == "NONE" :: OutputForm
+ x:% = y:% == EQ(x,y)$Lisp
+
+@
+\section{package NONE1 NoneFunctions1}
+<<package NONE1 NoneFunctions1>>=
+)abbrev package NONE1 NoneFunctions1
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Functions: coerce
+++ Related Constructors: None
+++ Also See:
+++ AMS Classification:
+++ Keywords:
+++ Description:
+++ \spadtype{NoneFunctions1} implements functions on \spadtype{None}.
+++ It particular it includes a particulary dangerous coercion from
+++ any other type to \spadtype{None}.
+
+NoneFunctions1(S:Type): Exports == Implementation where
+ Exports ==> with
+ coerce: S -> None
+ ++ coerce(x) changes \spad{x} into an object of type
+ ++ \spadtype{None}.
+
+ Implementation ==> add
+ coerce(s:S):None == s pretend None
+
+@
+\section{domain ANY Any}
+<<domain ANY Any>>=
+)abbrev domain ANY Any
+++ Author: Robert S. Sutor
+++ Date Created:
+++ Change History:
+++ Basic Functions: any, domainOf, objectOf, dom, obj, showTypeInOutput
+++ Related Constructors: AnyFunctions1
+++ Also See: None
+++ AMS Classification:
+++ Keywords:
+++ Description:
+++ \spadtype{Any} implements a type that packages up objects and their
+++ types in objects of \spadtype{Any}. Roughly speaking that means
+++ that if \spad{s : S} then when converted to \spadtype{Any}, the new
+++ object will include both the original object and its type. This is
+++ a way of converting arbitrary objects into a single type without
+++ losing any of the original information. Any object can be converted
+++ to one of \spadtype{Any}.
+
+Any(): SetCategory with
+ any : (SExpression, None) -> %
+ ++ any(type,object) is a technical function for creating
+ ++ an object of \spadtype{Any}. Arugment \spad{type} is a \spadgloss{LISP} form
+ ++ for the type of \spad{object}.
+ domainOf : % -> OutputForm
+ ++ domainOf(a) returns a printable form of the type of the
+ ++ original object that was converted to \spadtype{Any}.
+ objectOf : % -> OutputForm
+ ++ objectOf(a) returns a printable form of the
+ ++ original object that was converted to \spadtype{Any}.
+ dom : % -> SExpression
+ ++ dom(a) returns a \spadgloss{LISP} form of the type of the
+ ++ original object that was converted to \spadtype{Any}.
+ obj : % -> None
+ ++ obj(a) essentially returns the original object that was
+ ++ converted to \spadtype{Any} except that the type is forced
+ ++ to be \spadtype{None}.
+ showTypeInOutput: Boolean -> String
+ ++ showTypeInOutput(bool) affects the way objects of
+ ++ \spadtype{Any} are displayed. If \spad{bool} is true
+ ++ then the type of the original object that was converted
+ ++ to \spadtype{Any} will be printed. If \spad{bool} is
+ ++ false, it will not be printed.
+
+ == add
+ Rep := Record(dm: SExpression, ob: None)
+
+ printTypeInOutputP:Reference(Boolean) := ref false
+
+ obj x == x.ob
+ dom x == x.dm
+ domainOf x == x.dm pretend OutputForm
+ x = y == (x.dm = y.dm) and EQ(x.ob, y.ob)$Lisp
+
+ objectOf(x : %) : OutputForm ==
+ spad2BootCoerce(x.ob, x.dm,
+ list("OutputForm"::Symbol)$List(Symbol))$Lisp
+
+ showTypeInOutput(b : Boolean) : String ==
+ printTypeInOutputP := ref b
+ b=> "Type of object will be displayed in output of a member of Any"
+ "Type of object will not be displayed in output of a member of Any"
+
+ coerce(x):OutputForm ==
+ obj1 : OutputForm := objectOf x
+ not deref printTypeInOutputP => obj1
+ dom1 :=
+ p:Symbol := prefix2String(devaluate(x.dm)$Lisp)$Lisp
+ atom?(p pretend SExpression) => list(p)$List(Symbol)
+ list(p)$Symbol
+ hconcat cons(obj1,
+ cons(":"::OutputForm, [a::OutputForm for a in dom1]))
+
+ any(domain, object) ==
+ (isValidType(domain)$Lisp)@Boolean => [domain, object]
+ domain := devaluate(domain)$Lisp
+ (isValidType(domain)$Lisp)@Boolean => [domain, object]
+ error "function any must have a domain as first argument"
+
+@
+\section{package ANY1 AnyFunctions1}
+<<package ANY1 AnyFunctions1>>=
+)abbrev package ANY1 AnyFunctions1
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Functions: coerce, retractIfCan, retractable?, retract
+++ Related Constructors: Any
+++ Also See:
+++ AMS Classification:
+++ Keywords:
+++ Description:
+++ \spadtype{AnyFunctions1} implements several utility functions for
+++ working with \spadtype{Any}. These functions are used to go back
+++ and forth between objects of \spadtype{Any} and objects of other
+++ types.
+
+AnyFunctions1(S:Type): with
+ coerce : S -> Any
+ ++ coerce(s) creates an object of \spadtype{Any} from the
+ ++ object \spad{s} of type \spad{S}.
+ retractIfCan: Any -> Union(S, "failed")
+ ++ retractIfCan(a) tries change \spad{a} into an object
+ ++ of type \spad{S}. If it can, then such an object is
+ ++ returned. Otherwise, "failed" is returned.
+ retractable?: Any -> Boolean
+ ++ retractable?(a) tests if \spad{a} can be converted
+ ++ into an object of type \spad{S}.
+ retract : Any -> S
+ ++ retract(a) tries to convert \spad{a} into an object of
+ ++ type \spad{S}. If possible, it returns the object.
+ ++ Error: if no such retraction is possible.
+
+ == add
+ import NoneFunctions1(S)
+
+ Sexpr:SExpression := devaluate(S)$Lisp
+
+ retractable? a == dom(a) = Sexpr
+ coerce(s:S):Any == any(Sexpr, s::None)
+
+ retractIfCan a ==
+ retractable? a => obj(a) pretend S
+ "failed"
+
+ retract a ==
+ retractable? a => obj(a) pretend S
+ error "Cannot retract value."
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Any and None complete the type lattice. They are also used in the
+-- interpreter in various situations. For example, it is always possible
+-- to resolve two types in the interpreter because at worst the answer
+-- may be Any.
+
+<<domain NONE None>>
+<<package NONE1 NoneFunctions1>>
+<<domain ANY Any>>
+<<package ANY1 AnyFunctions1>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/array1.spad.pamphlet b/src/algebra/array1.spad.pamphlet
new file mode 100644
index 00000000..0812a849
--- /dev/null
+++ b/src/algebra/array1.spad.pamphlet
@@ -0,0 +1,606 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra array1.spad}
+\author{Michael Monagan, Stephen Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PRIMARR PrimitiveArray}
+<<domain PRIMARR PrimitiveArray>>=
+)abbrev domain PRIMARR PrimitiveArray
+++ This provides a fast array type with no bound checking on elt's.
+++ Minimum index is 0 in this type, cannot be changed
+PrimitiveArray(S:Type): OneDimensionalArrayAggregate S == add
+ Qmax ==> QVMAXINDEX$Lisp
+ Qsize ==> QVSIZE$Lisp
+-- Qelt ==> QVELT$Lisp
+-- Qsetelt ==> QSETVELT$Lisp
+ Qelt ==> ELT$Lisp
+ Qsetelt ==> SETELT$Lisp
+ Qnew ==> GETREFV$Lisp
+
+ #x == Qsize x
+ minIndex x == 0
+ empty() == Qnew(0$Lisp)
+ new(n, x) == fill_!(Qnew n, x)
+ qelt(x, i) == Qelt(x, i)
+ elt(x:%, i:Integer) == Qelt(x, i)
+ qsetelt_!(x, i, s) == Qsetelt(x, i, s)
+ setelt(x:%, i:Integer, s:S) == Qsetelt(x, i, s)
+ fill_!(x, s) == (for i in 0..Qmax x repeat Qsetelt(x, i, s); x)
+
+@
+\section{PRIMARR.lsp BOOTSTRAP}
+{\bf PRIMARR} depends on itself.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf PRIMARR} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf PRIMARR.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<PRIMARR.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |PRIMARR;#;$Nni;1|) (QUOTE |SPADreplace|) (QUOTE QVSIZE))
+
+(DEFUN |PRIMARR;#;$Nni;1| (|x| |$|) (QVSIZE |x|))
+
+(PUT (QUOTE |PRIMARR;minIndex;$I;2|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) 0)))
+
+(DEFUN |PRIMARR;minIndex;$I;2| (|x| |$|) 0)
+
+(PUT (QUOTE |PRIMARR;empty;$;3|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (GETREFV 0))))
+
+(DEFUN |PRIMARR;empty;$;3| (|$|) (GETREFV 0))
+
+(DEFUN |PRIMARR;new;NniS$;4| (|n| |x| |$|) (SPADCALL (GETREFV |n|) |x| (QREFELT |$| 12)))
+
+(PUT (QUOTE |PRIMARR;qelt;$IS;5|) (QUOTE |SPADreplace|) (QUOTE ELT))
+
+(DEFUN |PRIMARR;qelt;$IS;5| (|x| |i| |$|) (ELT |x| |i|))
+
+(PUT (QUOTE |PRIMARR;elt;$IS;6|) (QUOTE |SPADreplace|) (QUOTE ELT))
+
+(DEFUN |PRIMARR;elt;$IS;6| (|x| |i| |$|) (ELT |x| |i|))
+
+(PUT (QUOTE |PRIMARR;qsetelt!;$I2S;7|) (QUOTE |SPADreplace|) (QUOTE SETELT))
+
+(DEFUN |PRIMARR;qsetelt!;$I2S;7| (|x| |i| |s| |$|) (SETELT |x| |i| |s|))
+
+(PUT (QUOTE |PRIMARR;setelt;$I2S;8|) (QUOTE |SPADreplace|) (QUOTE SETELT))
+
+(DEFUN |PRIMARR;setelt;$I2S;8| (|x| |i| |s| |$|) (SETELT |x| |i| |s|))
+
+(DEFUN |PRIMARR;fill!;$S$;9| (|x| |s| |$|) (PROG (|i| #1=#:G82338) (RETURN (SEQ (SEQ (LETT |i| 0 |PRIMARR;fill!;$S$;9|) (LETT #1# (QVMAXINDEX |x|) |PRIMARR;fill!;$S$;9|) G190 (COND ((QSGREATERP |i| #1#) (GO G191))) (SEQ (EXIT (SETELT |x| |i| |s|))) (LETT |i| (QSADD1 |i|) |PRIMARR;fill!;$S$;9|) (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |PrimitiveArray| (#1=#:G82348) (PROG NIL (RETURN (PROG (#2=#:G82349) (RETURN (COND ((LETT #2# (|lassocShiftWithFunction| (LIST (|devaluate| #1#)) (HGET |$ConstructorCache| (QUOTE |PrimitiveArray|)) (QUOTE |domainEqualList|)) |PrimitiveArray|) (|CDRwithIncrement| #2#)) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (|PrimitiveArray;| #1#) (LETT #2# T |PrimitiveArray|)) (COND ((NOT #2#) (HREM |$ConstructorCache| (QUOTE |PrimitiveArray|))))))))))))
+
+(DEFUN |PrimitiveArray;| (|#1|) (PROG (|DV$1| |dv$| |$| #1=#:G82347 |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #2=(|PrimitiveArray|)) (LETT |dv$| (LIST (QUOTE |PrimitiveArray|) |DV$1|) . #2#) (LETT |$| (GETREFV 35) . #2#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#1| (QUOTE (|SetCategory|))) (|HasCategory| |#1| (QUOTE (|ConvertibleTo| (|InputForm|)))) (LETT #1# (|HasCategory| |#1| (QUOTE (|OrderedSet|))) . #2#) (OR #1# (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (|HasCategory| (|Integer|) (QUOTE (|OrderedSet|))) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (OR (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) #1#) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|))))))) . #2#)) (|haddProp| |$ConstructorCache| (QUOTE |PrimitiveArray|) (LIST |DV$1|) (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) |$|))))
+
+(MAKEPROP (QUOTE |PrimitiveArray|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|NonNegativeInteger|) |PRIMARR;#;$Nni;1| (|Integer|) |PRIMARR;minIndex;$I;2| |PRIMARR;empty;$;3| |PRIMARR;fill!;$S$;9| |PRIMARR;new;NniS$;4| |PRIMARR;qelt;$IS;5| |PRIMARR;elt;$IS;6| |PRIMARR;qsetelt!;$I2S;7| |PRIMARR;setelt;$I2S;8| (|Mapping| 6 6 6) (|Boolean|) (|List| 6) (|Equation| 6) (|List| 21) (|Mapping| 19 6) (|Mapping| 19 6 6) (|UniversalSegment| 9) (|Void|) (|Mapping| 6 6) (|InputForm|) (|OutputForm|) (|String|) (|SingleInteger|) (|List| |$|) (|Union| 6 (QUOTE "failed")) (|List| 9))) (QUOTE #(|~=| 0 |swap!| 6 |sorted?| 13 |sort!| 24 |sort| 35 |size?| 46 |setelt| 52 |select| 66 |sample| 72 |reverse!| 76 |reverse| 81 |removeDuplicates| 86 |remove| 91 |reduce| 103 |qsetelt!| 124 |qelt| 131 |position| 137 |parts| 156 |new| 161 |more?| 167 |minIndex| 173 |min| 178 |merge| 184 |members| 197 |member?| 202 |maxIndex| 208 |max| 213 |map!| 219 |map| 225 |less?| 238 |latex| 244 |insert| 249 |indices| 263 |index?| 268 |hash| 274 |first| 279 |find| 284 |fill!| 290 |every?| 296 |eval| 302 |eq?| 328 |entry?| 334 |entries| 340 |empty?| 345 |empty| 350 |elt| 354 |delete| 373 |count| 385 |copyInto!| 397 |copy| 404 |convert| 409 |construct| 414 |concat| 419 |coerce| 442 |any?| 447 |>=| 453 |>| 459 |=| 465 |<=| 471 |<| 477 |#| 483)) (QUOTE ((|shallowlyMutable| . 0) (|finiteAggregate| . 0))) (CONS (|makeByteWordVec2| 7 (QUOTE (0 0 0 0 0 0 3 0 0 7 4 0 0 7 1 2 4))) (CONS (QUOTE #(|OneDimensionalArrayAggregate&| |FiniteLinearAggregate&| |LinearAggregate&| |IndexedAggregate&| |Collection&| |HomogeneousAggregate&| |OrderedSet&| |Aggregate&| |EltableAggregate&| |Evalable&| |SetCategory&| NIL NIL |InnerEvalable&| NIL NIL |BasicType&|)) (CONS (QUOTE #((|OneDimensionalArrayAggregate| 6) (|FiniteLinearAggregate| 6) (|LinearAggregate| 6) (|IndexedAggregate| 9 6) (|Collection| 6) (|HomogeneousAggregate| 6) (|OrderedSet|) (|Aggregate|) (|EltableAggregate| 9 6) (|Evalable| 6) (|SetCategory|) (|Type|) (|Eltable| 9 6) (|InnerEvalable| 6 6) (|CoercibleTo| 29) (|ConvertibleTo| 28) (|BasicType|))) (|makeByteWordVec2| 34 (QUOTE (2 1 19 0 0 1 3 0 26 0 9 9 1 1 3 19 0 1 2 0 19 24 0 1 1 3 0 0 1 2 0 0 24 0 1 1 3 0 0 1 2 0 0 24 0 1 2 0 19 0 7 1 3 0 6 0 25 6 1 3 0 6 0 9 6 17 2 0 0 23 0 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 1 0 0 1 2 1 0 6 0 1 2 0 0 23 0 1 4 1 6 18 0 6 6 1 3 0 6 18 0 6 1 2 0 6 18 0 1 3 0 6 0 9 6 16 2 0 6 0 9 14 2 1 9 6 0 1 3 1 9 6 0 9 1 2 0 9 23 0 1 1 0 20 0 1 2 0 0 7 6 13 2 0 19 0 7 1 1 5 9 0 10 2 3 0 0 0 1 2 3 0 0 0 1 3 0 0 24 0 0 1 1 0 20 0 1 2 1 19 6 0 1 1 5 9 0 1 2 3 0 0 0 1 2 0 0 27 0 1 3 0 0 18 0 0 1 2 0 0 27 0 1 2 0 19 0 7 1 1 1 30 0 1 3 0 0 0 0 9 1 3 0 0 6 0 9 1 1 0 34 0 1 2 0 19 9 0 1 1 1 31 0 1 1 5 6 0 1 2 0 33 23 0 1 2 0 0 0 6 12 2 0 19 23 0 1 3 6 0 0 20 20 1 2 6 0 0 21 1 3 6 0 0 6 6 1 2 6 0 0 22 1 2 0 19 0 0 1 2 1 19 6 0 1 1 0 20 0 1 1 0 19 0 1 0 0 0 11 2 0 0 0 25 1 2 0 6 0 9 15 3 0 6 0 9 6 1 2 0 0 0 9 1 2 0 0 0 25 1 2 1 7 6 0 1 2 0 7 23 0 1 3 0 0 0 0 9 1 1 0 0 0 1 1 2 28 0 1 1 0 0 20 1 1 0 0 32 1 2 0 0 6 0 1 2 0 0 0 0 1 2 0 0 0 6 1 1 1 29 0 1 2 0 19 23 0 1 2 3 19 0 0 1 2 3 19 0 0 1 2 1 19 0 0 1 2 3 19 0 0 1 2 3 19 0 0 1 1 0 7 0 8)))))) (QUOTE |lookupComplete|)))
+@
+\section{package PRIMARR2 PrimitiveArrayFunctions2}
+<<package PRIMARR2 PrimitiveArrayFunctions2>>=
+)abbrev package PRIMARR2 PrimitiveArrayFunctions2
+++ This package provides tools for operating on primitive arrays
+++ with unary and binary functions involving different underlying types
+PrimitiveArrayFunctions2(A, B): Exports == Implementation where
+ A, B: Type
+
+ VA ==> PrimitiveArray A
+ VB ==> PrimitiveArray B
+ O2 ==> FiniteLinearAggregateFunctions2(A, VA, B, VB)
+ Exports ==> with
+ scan : ((A, B) -> B, VA, B) -> VB
+ ++ scan(f,a,r) successively applies
+ ++ \spad{reduce(f,x,r)} to more and more leading sub-arrays
+ ++ x of primitive array \spad{a}.
+ ++ More precisely, if \spad{a} is \spad{[a1,a2,...]}, then
+ ++ \spad{scan(f,a,r)} returns
+ ++ \spad{[reduce(f,[a1],r),reduce(f,[a1,a2],r),...]}.
+ reduce : ((A, B) -> B, VA, B) -> B
+ ++ reduce(f,a,r) applies function f to each
+ ++ successive element of the
+ ++ primitive array \spad{a} and an accumulant initialized to r.
+ ++ For example,
+ ++ \spad{reduce(_+$Integer,[1,2,3],0)}
+ ++ does \spad{3+(2+(1+0))}. Note: third argument r
+ ++ may be regarded as the
+ ++ identity element for the function f.
+ map : (A -> B, VA) -> VB
+ ++ map(f,a) applies function f to each member of primitive array
+ ++ \spad{a} resulting in a new primitive array over a
+ ++ possibly different underlying domain.
+
+ Implementation ==> add
+ map(f, v) == map(f, v)$O2
+ scan(f, v, b) == scan(f, v, b)$O2
+ reduce(f, v, b) == reduce(f, v, b)$O2
+
+@
+\section{domain TUPLE Tuple}
+<<domain TUPLE Tuple>>=
+)abbrev domain TUPLE Tuple
+++ This domain is used to interface with the interpreter's notion
+++ of comma-delimited sequences of values.
+Tuple(S:Type): CoercibleTo(PrimitiveArray S) with
+ coerce: PrimitiveArray S -> %
+ ++ coerce(a) makes a tuple from primitive array a
+ select: (%, NonNegativeInteger) -> S
+ ++ select(x,n) returns the n-th element of tuple x.
+ ++ tuples are 0-based
+ length: % -> NonNegativeInteger
+ ++ length(x) returns the number of elements in tuple x
+ if S has SetCategory then SetCategory
+ == add
+ Rep := Record(len : NonNegativeInteger, elts : PrimitiveArray S)
+
+ coerce(x: PrimitiveArray S): % == [#x, x]
+ coerce(x:%): PrimitiveArray(S) == x.elts
+ length x == x.len
+
+ select(x, n) ==
+ n >= x.len => error "Index out of bounds"
+ x.elts.n
+
+ if S has SetCategory then
+ x = y == (x.len = y.len) and (x.elts =$PrimitiveArray(S) y.elts)
+ coerce(x : %): OutputForm ==
+ paren [(x.elts.i)::OutputForm
+ for i in minIndex x.elts .. maxIndex x.elts]$List(OutputForm)
+
+@
+\section{domain IFARRAY IndexedFlexibleArray}
+<<domain IFARRAY IndexedFlexibleArray>>=
+)abbrev domain IFARRAY IndexedFlexibleArray
+++ Author: Michael Monagan July/87, modified SMW June/91
+++ A FlexibleArray is the notion of an array intended to allow for growth
+++ at the end only. Hence the following efficient operations
+++ \spad{append(x,a)} meaning append item x at the end of the array \spad{a}
+++ \spad{delete(a,n)} meaning delete the last item from the array \spad{a}
+++ Flexible arrays support the other operations inherited from
+++ \spadtype{ExtensibleLinearAggregate}. However, these are not efficient.
+++ Flexible arrays combine the \spad{O(1)} access time property of arrays
+++ with growing and shrinking at the end in \spad{O(1)} (average) time.
+++ This is done by using an ordinary array which may have zero or more
+++ empty slots at the end. When the array becomes full it is copied
+++ into a new larger (50% larger) array. Conversely, when the array
+++ becomes less than 1/2 full, it is copied into a smaller array.
+++ Flexible arrays provide for an efficient implementation of many
+++ data structures in particular heaps, stacks and sets.
+
+IndexedFlexibleArray(S:Type, mn: Integer): Exports == Implementation where
+ A ==> PrimitiveArray S
+ I ==> Integer
+ N ==> NonNegativeInteger
+ U ==> UniversalSegment Integer
+ Exports ==
+ Join(OneDimensionalArrayAggregate S,ExtensibleLinearAggregate S) with
+ flexibleArray : List S -> %
+ ++ flexibleArray(l) creates a flexible array from the list of elements l
+ physicalLength : % -> NonNegativeInteger
+ ++ physicalLength(x) returns the number of elements x can accomodate before growing
+ physicalLength_!: (%, I) -> %
+ ++ physicalLength!(x,n) changes the physical length of x to be n and returns the new array.
+ shrinkable: Boolean -> Boolean
+ ++ shrinkable(b) sets the shrinkable attribute of flexible arrays to b and returns the previous value
+ Implementation == add
+ Rep := Record(physLen:I, logLen:I, f:A)
+ shrinkable? : Boolean := true
+ growAndFill : (%, I, S) -> %
+ growWith : (%, I, S) -> %
+ growAdding : (%, I, %) -> %
+ shrink: (%, I) -> %
+ newa : (N, A) -> A
+
+ physicalLength(r) == (r.physLen) pretend NonNegativeInteger
+ physicalLength_!(r, n) ==
+ r.physLen = 0 => error "flexible array must be non-empty"
+ growWith(r, n, r.f.0)
+
+ empty() == [0, 0, empty()]
+ #r == (r.logLen)::N
+ fill_!(r, x) == (fill_!(r.f, x); r)
+ maxIndex r == r.logLen - 1 + mn
+ minIndex r == mn
+ new(n, a) == [n, n, new(n, a)]
+
+ shrinkable(b) ==
+ oldval := shrinkable?
+ shrinkable? := b
+ oldval
+
+ flexibleArray l ==
+ n := #l
+ n = 0 => empty()
+ x := l.1
+ a := new(n,x)
+ for i in mn + 1..mn + n-1 for y in rest l repeat a.i := y
+ a
+
+ -- local utility operations
+ newa(n, a) ==
+ zero? n => empty()
+ new(n, a.0)
+
+ growAdding(r, b, s) ==
+ b = 0 => r
+ #r > 0 => growAndFill(r, b, (r.f).0)
+ #s > 0 => growAndFill(r, b, (s.f).0)
+ error "no default filler element"
+
+ growAndFill(r, b, x) ==
+ (r.logLen := r.logLen + b) <= r.physLen => r
+ -- enlarge by 50% + b
+ n := r.physLen + r.physLen quo 2 + 1
+ if r.logLen > n then n := r.logLen
+ growWith(r, n, x)
+
+ growWith(r, n, x) ==
+ y := new(n::N, x)$PrimitiveArray(S)
+ a := r.f
+ for k in 0 .. r.physLen-1 repeat y.k := a.k
+ r.physLen := n
+ r.f := y
+ r
+
+ shrink(r, i) ==
+ r.logLen := r.logLen - i
+ negative?(n := r.logLen) => error "internal bug in flexible array"
+ 2*n+2 > r.physLen => r
+ not shrinkable? => r
+ if n < r.logLen then error "cannot shrink flexible array to indicated size"
+ n = 0 => empty()
+ r.physLen := n
+ y := newa(n::N, a := r.f)
+ for k in 0 .. n-1 repeat y.k := a.k
+ r.f := y
+ r
+
+ copy r ==
+ n := #r
+ a := r.f
+ v := newa(n, a := r.f)
+ for k in 0..n-1 repeat v.k := a.k
+ [n, n, v]
+
+
+ elt(r:%, i:I) ==
+ i < mn or i >= r.logLen + mn =>
+ error "index out of range"
+ r.f.(i-mn)
+
+ setelt(r:%, i:I, x:S) ==
+ i < mn or i >= r.logLen + mn =>
+ error "index out of range"
+ r.f.(i-mn) := x
+
+ -- operations inherited from extensible aggregate
+ merge(g, a, b) == merge_!(g, copy a, b)
+ concat(x:S, r:%) == insert_!(x, r, mn)
+
+ concat_!(r:%, x:S) ==
+ growAndFill(r, 1, x)
+ r.f.(r.logLen-1) := x
+ r
+
+ concat_!(a:%, b:%) ==
+ if eq?(a, b) then b := copy b
+ n := #a
+ growAdding(a, #b, b)
+ copyInto_!(a, b, n + mn)
+
+ remove_!(g:(S->Boolean), a:%) ==
+ k:I := 0
+ for i in 0..maxIndex a - mn repeat
+ if not g(a.i) then (a.k := a.i; k := k+1)
+ shrink(a, #a - k)
+
+ delete_!(r:%, i1:I) ==
+ i := i1 - mn
+ i < 0 or i > r.logLen => error "index out of range"
+ for k in i..r.logLen-2 repeat r.f.k := r.f.(k+1)
+ shrink(r, 1)
+
+ delete_!(r:%, i:U) ==
+ l := lo i - mn; m := maxIndex r - mn
+ h := (hasHi i => hi i - mn; m)
+ l < 0 or h > m => error "index out of range"
+ for j in l.. for k in h+1..m repeat r.f.j := r.f.k
+ shrink(r, max(0,h-l+1))
+
+ insert_!(x:S, r:%, i1:I):% ==
+ i := i1 - mn
+ n := r.logLen
+ i < 0 or i > n => error "index out of range"
+ growAndFill(r, 1, x)
+ for k in n-1 .. i by -1 repeat r.f.(k+1) := r.f.k
+ r.f.i := x
+ r
+
+ insert_!(a:%, b:%, i1:I):% ==
+ i := i1 - mn
+ if eq?(a, b) then b := copy b
+ m := #a; n := #b
+ i < 0 or i > n => error "index out of range"
+ growAdding(b, m, a)
+ for k in n-1 .. i by -1 repeat b.f.(m+k) := b.f.k
+ for k in m-1 .. 0 by -1 repeat b.f.(i+k) := a.f.k
+ b
+
+ merge_!(g, a, b) ==
+ m := #a; n := #b; growAdding(a, n, b)
+ for i in m-1..0 by -1 for j in m+n-1.. by -1 repeat a.f.j := a.f.i
+ i := n; j := 0
+ for k in 0.. while i < n+m and j < n repeat
+ if g(a.f.i,b.f.j) then (a.f.k := a.f.i; i := i+1)
+ else (a.f.k := b.f.j; j := j+1)
+ for k in k.. for j in j..n-1 repeat a.f.k := b.f.j
+ a
+
+ select_!(g:(S->Boolean), a:%) ==
+ k:I := 0
+ for i in 0..maxIndex a - mn repeat if g(a.f.i) then (a.f.k := a.f.i;k := k+1)
+ shrink(a, #a - k)
+
+ if S has SetCategory then
+ removeDuplicates_! a ==
+ ct := #a
+ ct < 2 => a
+
+ i := mn
+ nlim := mn + ct
+ nlim0 := nlim
+ while i < nlim repeat
+ j := i+1
+ for k in j..nlim-1 | a.k ^= a.i repeat
+ a.j := a.k
+ j := j+1
+ nlim := j
+ i := i+1
+ nlim ^= nlim0 => delete_!(a, i..)
+ a
+
+@
+\section{domain FARRAY FlexibleArray}
+<<domain FARRAY FlexibleArray>>=
+)abbrev domain FARRAY FlexibleArray
+++ A FlexibleArray is the notion of an array intended to allow for growth
+++ at the end only. Hence the following efficient operations
+++ \spad{append(x,a)} meaning append item x at the end of the array \spad{a}
+++ \spad{delete(a,n)} meaning delete the last item from the array \spad{a}
+++ Flexible arrays support the other operations inherited from
+++ \spadtype{ExtensibleLinearAggregate}. However, these are not efficient.
+++ Flexible arrays combine the \spad{O(1)} access time property of arrays
+++ with growing and shrinking at the end in \spad{O(1)} (average) time.
+++ This is done by using an ordinary array which may have zero or more
+++ empty slots at the end. When the array becomes full it is copied
+++ into a new larger (50% larger) array. Conversely, when the array
+++ becomes less than 1/2 full, it is copied into a smaller array.
+++ Flexible arrays provide for an efficient implementation of many
+++ data structures in particular heaps, stacks and sets.
+
+FlexibleArray(S: Type) == Implementation where
+ ARRAYMININDEX ==> 1 -- if you want to change this, be my guest
+ Implementation ==> IndexedFlexibleArray(S, ARRAYMININDEX)
+-- Join(OneDimensionalArrayAggregate S, ExtensibleLinearAggregate S)
+
+@
+\section{domain IARRAY1 IndexedOneDimensionalArray}
+<<domain IARRAY1 IndexedOneDimensionalArray>>=
+)abbrev domain IARRAY1 IndexedOneDimensionalArray
+++ Author Micheal Monagan Aug/87
+++ This is the basic one dimensional array data type.
+
+IndexedOneDimensionalArray(S:Type, mn:Integer):
+ OneDimensionalArrayAggregate S == add
+ Qmax ==> QVMAXINDEX$Lisp
+ Qsize ==> QVSIZE$Lisp
+-- Qelt ==> QVELT$Lisp
+-- Qsetelt ==> QSETVELT$Lisp
+ Qelt ==> ELT$Lisp
+ Qsetelt ==> SETELT$Lisp
+-- Qelt1 ==> QVELT_-1$Lisp
+-- Qsetelt1 ==> QSETVELT_-1$Lisp
+ Qnew ==> GETREFV$Lisp
+ I ==> Integer
+
+ #x == Qsize x
+ fill_!(x, s) == (for i in 0..Qmax x repeat Qsetelt(x, i, s); x)
+ minIndex x == mn
+
+ empty() == Qnew(0$Lisp)
+ new(n, s) == fill_!(Qnew n,s)
+
+ map_!(f, s1) ==
+ n:Integer := Qmax(s1)
+ n < 0 => s1
+ for i in 0..n repeat Qsetelt(s1, i, f(Qelt(s1,i)))
+ s1
+
+ map(f, s1) ==
+ n:Integer := Qmax(s1)
+ n < 0 => s1
+ ss2:% := Qnew(n+1)
+ for i in 0..n repeat Qsetelt(ss2, i, f(Qelt(s1,i)))
+ ss2
+
+ map(f, a, b) ==
+ maxind:Integer := min(Qmax a, Qmax b)
+ maxind < 0 => empty()
+ c:% := Qnew(maxind+1)
+ for i in 0..maxind repeat
+ Qsetelt(c, i, f(Qelt(a,i),Qelt(b,i)))
+ c
+
+ if zero? mn then
+ qelt(x, i) == Qelt(x, i)
+ qsetelt_!(x, i, s) == Qsetelt(x, i, s)
+
+ elt(x:%, i:I) ==
+ negative? i or i > maxIndex(x) => error "index out of range"
+ qelt(x, i)
+
+ setelt(x:%, i:I, s:S) ==
+ negative? i or i > maxIndex(x) => error "index out of range"
+ qsetelt_!(x, i, s)
+
+-- else if one? mn then
+ else if (mn = 1) then
+ maxIndex x == Qsize x
+ qelt(x, i) == Qelt(x, i-1)
+ qsetelt_!(x, i, s) == Qsetelt(x, i-1, s)
+
+ elt(x:%, i:I) ==
+ QSLESSP(i,1$Lisp)$Lisp or QSLESSP(Qsize x,i)$Lisp =>
+ error "index out of range"
+ Qelt(x, i-1)
+
+ setelt(x:%, i:I, s:S) ==
+ QSLESSP(i,1$Lisp)$Lisp or QSLESSP(Qsize x,i)$Lisp =>
+ error "index out of range"
+ Qsetelt(x, i-1, s)
+
+ else
+ qelt(x, i) == Qelt(x, i - mn)
+ qsetelt_!(x, i, s) == Qsetelt(x, i - mn, s)
+
+ elt(x:%, i:I) ==
+ i < mn or i > maxIndex(x) => error "index out of range"
+ qelt(x, i)
+
+ setelt(x:%, i:I, s:S) ==
+ i < mn or i > maxIndex(x) => error "index out of range"
+ qsetelt_!(x, i, s)
+
+@
+\section{domain ARRAY1 OneDimensionalArray}
+<<domain ARRAY1 OneDimensionalArray>>=
+)abbrev domain ARRAY1 OneDimensionalArray
+++ This is the domain of 1-based one dimensional arrays
+
+OneDimensionalArray(S:Type): Exports == Implementation where
+ ARRAYMININDEX ==> 1 -- if you want to change this, be my guest
+ Exports == OneDimensionalArrayAggregate S with
+ oneDimensionalArray: List S -> %
+ ++ oneDimensionalArray(l) creates an array from a list of elements l
+ oneDimensionalArray: (NonNegativeInteger, S) -> %
+ ++ oneDimensionalArray(n,s) creates an array from n copies of element s
+ Implementation == IndexedOneDimensionalArray(S, ARRAYMININDEX) add
+ oneDimensionalArray(u) ==
+ n := #u
+ n = 0 => empty()
+ a := new(n, first u)
+ for i in 2..n for x in rest u repeat a.i := x
+ a
+ oneDimensionalArray(n,s) == new(n,s)
+
+@
+\section{package ARRAY12 OneDimensionalArrayFunctions2}
+<<package ARRAY12 OneDimensionalArrayFunctions2>>=
+)abbrev package ARRAY12 OneDimensionalArrayFunctions2
+++ This package provides tools for operating on one-dimensional arrays
+++ with unary and binary functions involving different underlying types
+OneDimensionalArrayFunctions2(A, B): Exports == Implementation where
+ A, B: Type
+
+ VA ==> OneDimensionalArray A
+ VB ==> OneDimensionalArray B
+ O2 ==> FiniteLinearAggregateFunctions2(A, VA, B, VB)
+
+ Exports ==> with
+ scan : ((A, B) -> B, VA, B) -> VB
+ ++ scan(f,a,r) successively applies
+ ++ \spad{reduce(f,x,r)} to more and more leading sub-arrays
+ ++ x of one-dimensional array \spad{a}.
+ ++ More precisely, if \spad{a} is \spad{[a1,a2,...]}, then
+ ++ \spad{scan(f,a,r)} returns
+ ++ \spad{[reduce(f,[a1],r),reduce(f,[a1,a2],r),...]}.
+ reduce : ((A, B) -> B, VA, B) -> B
+ ++ reduce(f,a,r) applies function f to each
+ ++ successive element of the
+ ++ one-dimensional array \spad{a} and an accumulant initialized to r.
+ ++ For example,
+ ++ \spad{reduce(_+$Integer,[1,2,3],0)}
+ ++ does \spad{3+(2+(1+0))}. Note: third argument r
+ ++ may be regarded as the
+ ++ identity element for the function f.
+ map : (A -> B, VA) -> VB
+ ++ map(f,a) applies function f to each member of one-dimensional array
+ ++ \spad{a} resulting in a new one-dimensional array over a
+ ++ possibly different underlying domain.
+
+ Implementation ==> add
+ map(f, v) == map(f, v)$O2
+ scan(f, v, b) == scan(f, v, b)$O2
+ reduce(f, v, b) == reduce(f, v, b)$O2
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PRIMARR PrimitiveArray>>
+<<package PRIMARR2 PrimitiveArrayFunctions2>>
+<<domain TUPLE Tuple>>
+<<domain IFARRAY IndexedFlexibleArray>>
+<<domain FARRAY FlexibleArray>>
+<<domain IARRAY1 IndexedOneDimensionalArray>>
+<<domain ARRAY1 OneDimensionalArray>>
+<<package ARRAY12 OneDimensionalArrayFunctions2>>
+
+--%% TupleFunctions2
+--TupleFunctions2(A:Type, B:Type): with
+-- map: (A -> B, Tuple A) -> Tuple B
+-- == add
+-- map(f, t) ==
+-- p:PrimitiveArray(B) := new length t
+-- for i in minIndex p .. maxIndex p repeat
+-- p.i := f select(t, i)
+-- p::Tuple(B)
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/array2.spad.pamphlet b/src/algebra/array2.spad.pamphlet
new file mode 100644
index 00000000..ef540c42
--- /dev/null
+++ b/src/algebra/array2.spad.pamphlet
@@ -0,0 +1,451 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra array2.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ARR2CAT TwoDimensionalArrayCategory}
+<<category ARR2CAT TwoDimensionalArrayCategory>>=
+)abbrev category ARR2CAT TwoDimensionalArrayCategory
+++ Two dimensional array categories and domains
+++ Author:
+++ Date Created: 27 October 1989
+++ Date Last Updated: 27 June 1990
+++ Keywords: array, data structure
+++ Examples:
+++ References:
+TwoDimensionalArrayCategory(R,Row,Col): Category == Definition where
+ ++ TwoDimensionalArrayCategory is a general array category which
+ ++ allows different representations and indexing schemes.
+ ++ Rows and columns may be extracted with rows returned as objects
+ ++ of type Row and columns returned as objects of type Col.
+ ++ The index of the 'first' row may be obtained by calling the
+ ++ function 'minRowIndex'. The index of the 'first' column may
+ ++ be obtained by calling the function 'minColIndex'. The index of
+ ++ the first element of a 'Row' is the same as the index of the
+ ++ first column in an array and vice versa.
+ R : Type
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+
+ Definition == HomogeneousAggregate(R) with
+
+ shallowlyMutable
+ ++ one may destructively alter arrays
+
+ finiteAggregate
+ ++ two-dimensional arrays are finite
+
+--% Array creation
+
+ new: (NonNegativeInteger,NonNegativeInteger,R) -> %
+ ++ new(m,n,r) is an m-by-n array all of whose entries are r
+ fill_!: (%,R) -> %
+ ++ fill!(m,r) fills m with r's
+
+--% Size inquiries
+
+ minRowIndex : % -> Integer
+ ++ minRowIndex(m) returns the index of the 'first' row of the array m
+ maxRowIndex : % -> Integer
+ ++ maxRowIndex(m) returns the index of the 'last' row of the array m
+ minColIndex : % -> Integer
+ ++ minColIndex(m) returns the index of the 'first' column of the array m
+ maxColIndex : % -> Integer
+ ++ maxColIndex(m) returns the index of the 'last' column of the array m
+ nrows : % -> NonNegativeInteger
+ ++ nrows(m) returns the number of rows in the array m
+ ncols : % -> NonNegativeInteger
+ ++ ncols(m) returns the number of columns in the array m
+
+--% Part extractions
+
+ elt: (%,Integer,Integer) -> R
+ ++ elt(m,i,j) returns the element in the ith row and jth
+ ++ column of the array m
+ ++ error check to determine if indices are in proper ranges
+ qelt: (%,Integer,Integer) -> R
+ ++ qelt(m,i,j) returns the element in the ith row and jth
+ ++ column of the array m
+ ++ NO error check to determine if indices are in proper ranges
+ elt: (%,Integer,Integer,R) -> R
+ ++ elt(m,i,j,r) returns the element in the ith row and jth
+ ++ column of the array m, if m has an ith row and a jth column,
+ ++ and returns r otherwise
+ row: (%,Integer) -> Row
+ ++ row(m,i) returns the ith row of m
+ ++ error check to determine if index is in proper ranges
+ column: (%,Integer) -> Col
+ ++ column(m,j) returns the jth column of m
+ ++ error check to determine if index is in proper ranges
+ parts: % -> List R
+ ++ parts(m) returns a list of the elements of m in row major order
+
+--% Part assignments
+
+ setelt: (%,Integer,Integer,R) -> R
+ -- will become setelt_!
+ ++ setelt(m,i,j,r) sets the element in the ith row and jth
+ ++ column of m to r
+ ++ error check to determine if indices are in proper ranges
+ qsetelt_!: (%,Integer,Integer,R) -> R
+ ++ qsetelt!(m,i,j,r) sets the element in the ith row and jth
+ ++ column of m to r
+ ++ NO error check to determine if indices are in proper ranges
+ setRow_!: (%,Integer,Row) -> %
+ ++ setRow!(m,i,v) sets to ith row of m to v
+ setColumn_!: (%,Integer,Col) -> %
+ ++ setColumn!(m,j,v) sets to jth column of m to v
+
+--% Map and Zip
+
+ map: (R -> R,%) -> %
+ ++ map(f,a) returns \spad{b}, where \spad{b(i,j) = f(a(i,j))} for all \spad{i, j}
+ map_!: (R -> R,%) -> %
+ ++ map!(f,a) assign \spad{a(i,j)} to \spad{f(a(i,j))} for all \spad{i, j}
+ map:((R,R) -> R,%,%) -> %
+ ++ map(f,a,b) returns \spad{c}, where \spad{c(i,j) = f(a(i,j),b(i,j))}
+ ++ for all \spad{i, j}
+ map:((R,R) -> R,%,%,R) -> %
+ ++ map(f,a,b,r) returns \spad{c}, where \spad{c(i,j) = f(a(i,j),b(i,j))} when both
+ ++ \spad{a(i,j)} and \spad{b(i,j)} exist;
+ ++ else \spad{c(i,j) = f(r, b(i,j))} when \spad{a(i,j)} does not exist;
+ ++ else \spad{c(i,j) = f(a(i,j),r)} when \spad{b(i,j)} does not exist;
+ ++ otherwise \spad{c(i,j) = f(r,r)}.
+
+ add
+
+--% Predicates
+
+ any?(f,m) ==
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ f(qelt(m,i,j)) => return true
+ false
+
+ every?(f,m) ==
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ not f(qelt(m,i,j)) => return false
+ true
+
+ size?(m,n) == nrows(m) * ncols(m) = n
+ less?(m,n) == nrows(m) * ncols(m) < n
+ more?(m,n) == nrows(m) * ncols(m) > n
+
+--% Size inquiries
+
+ # m == nrows(m) * ncols(m)
+
+--% Part extractions
+
+ elt(m,i,j,r) ==
+ i < minRowIndex(m) or i > maxRowIndex(m) => r
+ j < minColIndex(m) or j > maxColIndex(m) => r
+ qelt(m,i,j)
+
+ count(f:R -> Boolean,m:%) ==
+ num : NonNegativeInteger := 0
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ if f(qelt(m,i,j)) then num := num + 1
+ num
+
+ parts m ==
+ entryList : List R := nil()
+ for i in maxRowIndex(m)..minRowIndex(m) by -1 repeat
+ for j in maxColIndex(m)..minColIndex(m) by -1 repeat
+ entryList := concat(qelt(m,i,j),entryList)
+ entryList
+
+--% Creation
+
+ copy m ==
+ ans := new(nrows m,ncols m,NIL$Lisp)
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ qsetelt_!(ans,i,j,qelt(m,i,j))
+ ans
+
+ fill_!(m,r) ==
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ qsetelt_!(m,i,j,r)
+ m
+
+ map(f,m) ==
+ ans := new(nrows m,ncols m,NIL$Lisp)
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ qsetelt_!(ans,i,j,f(qelt(m,i,j)))
+ ans
+
+ map_!(f,m) ==
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ qsetelt_!(m,i,j,f(qelt(m,i,j)))
+ m
+
+ map(f,m,n) ==
+ (nrows(m) ^= nrows(n)) or (ncols(m) ^= ncols(n)) =>
+ error "map: arguments must have same dimensions"
+ ans := new(nrows m,ncols m,NIL$Lisp)
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ qsetelt_!(ans,i,j,f(qelt(m,i,j),qelt(n,i,j)))
+ ans
+
+ map(f,m,n,r) ==
+ maxRow := max(maxRowIndex m,maxRowIndex n)
+ maxCol := max(maxColIndex m,maxColIndex n)
+ ans := new(max(nrows m,nrows n),max(ncols m,ncols n),NIL$Lisp)
+ for i in minRowIndex(m)..maxRow repeat
+ for j in minColIndex(m)..maxCol repeat
+ qsetelt_!(ans,i,j,f(elt(m,i,j,r),elt(n,i,j,r)))
+ ans
+
+ setRow_!(m,i,v) ==
+ i < minRowIndex(m) or i > maxRowIndex(m) =>
+ error "setRow!: index out of range"
+ for j in minColIndex(m)..maxColIndex(m) _
+ for k in minIndex(v)..maxIndex(v) repeat
+ qsetelt_!(m,i,j,v.k)
+ m
+
+ setColumn_!(m,j,v) ==
+ j < minColIndex(m) or j > maxColIndex(m) =>
+ error "setColumn!: index out of range"
+ for i in minRowIndex(m)..maxRowIndex(m) _
+ for k in minIndex(v)..maxIndex(v) repeat
+ qsetelt_!(m,i,j,v.k)
+ m
+
+ if R has _= : (R,R) -> Boolean then
+
+ m = n ==
+ eq?(m,n) => true
+ (nrows(m) ^= nrows(n)) or (ncols(m) ^= ncols(n)) => false
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ not (qelt(m,i,j) = qelt(n,i,j)) => return false
+ true
+
+ member?(r,m) ==
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ qelt(m,i,j) = r => return true
+ false
+
+ count(r:R,m:%) == count(#1 = r,m)
+
+ if Row has shallowlyMutable then
+
+ row(m,i) ==
+ i < minRowIndex(m) or i > maxRowIndex(m) =>
+ error "row: index out of range"
+ v : Row := new(ncols m,NIL$Lisp)
+ for j in minColIndex(m)..maxColIndex(m) _
+ for k in minIndex(v)..maxIndex(v) repeat
+ qsetelt_!(v,k,qelt(m,i,j))
+ v
+
+ if Col has shallowlyMutable then
+
+ column(m,j) ==
+ j < minColIndex(m) or j > maxColIndex(m) =>
+ error "column: index out of range"
+ v : Col := new(nrows m,NIL$Lisp)
+ for i in minRowIndex(m)..maxRowIndex(m) _
+ for k in minIndex(v)..maxIndex(v) repeat
+ qsetelt_!(v,k,qelt(m,i,j))
+ v
+
+ if R has CoercibleTo(OutputForm) then
+
+ coerce(m:%) ==
+ l : List List OutputForm
+ l := [[qelt(m,i,j) :: OutputForm _
+ for j in minColIndex(m)..maxColIndex(m)] _
+ for i in minRowIndex(m)..maxRowIndex(m)]
+ matrix l
+
+@
+\section{domain IIARRAY2 InnerIndexedTwoDimensionalArray}
+<<domain IIARRAY2 InnerIndexedTwoDimensionalArray>>=
+)abbrev domain IIARRAY2 InnerIndexedTwoDimensionalArray
+InnerIndexedTwoDimensionalArray(R,mnRow,mnCol,Row,Col):_
+ Exports == Implementation where
+ ++ This is an internal type which provides an implementation of
+ ++ 2-dimensional arrays as PrimitiveArray's of PrimitiveArray's.
+ R : Type
+ mnRow, mnCol : Integer
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+
+ Exports ==> TwoDimensionalArrayCategory(R,Row,Col)
+
+ Implementation ==> add
+
+ Rep := PrimitiveArray PrimitiveArray R
+
+--% Predicates
+
+ empty? m == empty?(m)$Rep
+
+--% Primitive array creation
+
+ empty() == empty()$Rep
+
+ new(rows,cols,a) ==
+ rows = 0 =>
+ error "new: arrays with zero rows are not supported"
+-- cols = 0 =>
+-- error "new: arrays with zero columns are not supported"
+ arr : PrimitiveArray PrimitiveArray R := new(rows,empty())
+ for i in minIndex(arr)..maxIndex(arr) repeat
+ qsetelt_!(arr,i,new(cols,a))
+ arr
+
+--% Size inquiries
+
+ minRowIndex m == mnRow
+ minColIndex m == mnCol
+ maxRowIndex m == nrows m + mnRow - 1
+ maxColIndex m == ncols m + mnCol - 1
+
+ nrows m == (# m)$Rep
+
+ ncols m ==
+ empty? m => 0
+ # m(minIndex(m)$Rep)
+
+--% Part selection/assignment
+
+ qelt(m,i,j) ==
+ qelt(qelt(m,i - minRowIndex m)$Rep,j - minColIndex m)
+
+ elt(m:%,i:Integer,j:Integer) ==
+ i < minRowIndex(m) or i > maxRowIndex(m) =>
+ error "elt: index out of range"
+ j < minColIndex(m) or j > maxColIndex(m) =>
+ error "elt: index out of range"
+ qelt(m,i,j)
+
+ qsetelt_!(m,i,j,r) ==
+ setelt(qelt(m,i - minRowIndex m)$Rep,j - minColIndex m,r)
+
+ setelt(m:%,i:Integer,j:Integer,r:R) ==
+ i < minRowIndex(m) or i > maxRowIndex(m) =>
+ error "setelt: index out of range"
+ j < minColIndex(m) or j > maxColIndex(m) =>
+ error "setelt: index out of range"
+ qsetelt_!(m,i,j,r)
+
+ if R has SetCategory then
+ latex(m : %) : String ==
+ s : String := "\left[ \begin{array}{"
+ j : Integer
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ s := concat(s,"c")$String
+ s := concat(s,"} ")$String
+ i : Integer
+ for i in minRowIndex(m)..maxRowIndex(m) repeat
+ for j in minColIndex(m)..maxColIndex(m) repeat
+ s := concat(s, latex(qelt(m,i,j))$R)$String
+ if j < maxColIndex(m) then s := concat(s, " & ")$String
+ if i < maxRowIndex(m) then s := concat(s, " \\ ")$String
+ concat(s, "\end{array} \right]")$String
+
+@
+\section{domain IARRAY2 IndexedTwoDimensionalArray}
+<<domain IARRAY2 IndexedTwoDimensionalArray>>=
+)abbrev domain IARRAY2 IndexedTwoDimensionalArray
+IndexedTwoDimensionalArray(R,mnRow,mnCol):Exports == Implementation where
+ ++ An IndexedTwoDimensionalArray is a 2-dimensional array where
+ ++ the minimal row and column indices are parameters of the type.
+ ++ Rows and columns are returned as IndexedOneDimensionalArray's with
+ ++ minimal indices matching those of the IndexedTwoDimensionalArray.
+ ++ The index of the 'first' row may be obtained by calling the
+ ++ function 'minRowIndex'. The index of the 'first' column may
+ ++ be obtained by calling the function 'minColIndex'. The index of
+ ++ the first element of a 'Row' is the same as the index of the
+ ++ first column in an array and vice versa.
+ R : Type
+ mnRow, mnCol : Integer
+ Row ==> IndexedOneDimensionalArray(R,mnCol)
+ Col ==> IndexedOneDimensionalArray(R,mnRow)
+
+ Exports ==> TwoDimensionalArrayCategory(R,Row,Col)
+
+ Implementation ==>
+ InnerIndexedTwoDimensionalArray(R,mnRow,mnCol,Row,Col)
+
+@
+\section{domain ARRAY2 TwoDimensionalArray}
+<<domain ARRAY2 TwoDimensionalArray>>=
+)abbrev domain ARRAY2 TwoDimensionalArray
+TwoDimensionalArray(R):Exports == Implementation where
+ ++ A TwoDimensionalArray is a two dimensional array with
+ ++ 1-based indexing for both rows and columns.
+ R : Type
+ Row ==> OneDimensionalArray R
+ Col ==> OneDimensionalArray R
+
+ Exports ==> TwoDimensionalArrayCategory(R,Row,Col) with
+ shallowlyMutable
+ ++ One may destructively alter TwoDimensionalArray's.
+
+ Implementation ==> InnerIndexedTwoDimensionalArray(R,1,1,Row,Col)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category ARR2CAT TwoDimensionalArrayCategory>>
+<<domain IIARRAY2 InnerIndexedTwoDimensionalArray>>
+<<domain IARRAY2 IndexedTwoDimensionalArray>>
+<<domain ARRAY2 TwoDimensionalArray>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/asp.spad.pamphlet b/src/algebra/asp.spad.pamphlet
new file mode 100644
index 00000000..7899fb39
--- /dev/null
+++ b/src/algebra/asp.spad.pamphlet
@@ -0,0 +1,4295 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra asp.spad}
+\author{Mike Dewar, Grant Keady, Godfrey Nolan}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ASP1 Asp1}
+<<domain ASP1 Asp1>>=
+)abbrev domain ASP1 Asp1
+++ Author: Mike Dewar, Grant Keady, Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranFunctionCategory, FortranProgramCategory.
+++ Description:
+++\spadtype{Asp1} produces Fortran for Type 1 ASPs, needed for various
+++NAG routines. Type 1 ASPs take a univariate expression (in the symbol
+++X) and turn it into a Fortran Function like the following:
+++\begin{verbatim}
+++ DOUBLE PRECISION FUNCTION F(X)
+++ DOUBLE PRECISION X
+++ F=DSIN(X)
+++ RETURN
+++ END
+++\end{verbatim}
+
+
+Asp1(name): Exports == Implementation where
+ name : Symbol
+
+ FEXPR ==> FortranExpression
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+
+ Exports ==> FortranFunctionCategory with
+ coerce : FEXPR(['X],[],MachineFloat) -> $
+ ++coerce(f) takes an object from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns it into an ASP.
+
+ Implementation ==> add
+
+ -- Build Symbol Table for Rep
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal()$FT,syms)$SYMTAB
+ real : FST := "real"::FST
+
+ Rep := FortranProgram(name,[real]$Union(fst:FST,void:"void"),[X],syms)
+
+ retract(u:FRAC POLY INT):$ == (retract(u)@FEXPR(['X],[],MachineFloat))::$
+ retractIfCan(u:FRAC POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR(['X],[],MachineFloat),"failed")
+ foo := retractIfCan(u)$FEXPR(['X],[],MachineFloat)
+ foo case "failed" => "failed"
+ foo::FEXPR(['X],[],MachineFloat)::$
+
+ retract(u:FRAC POLY FLOAT):$ == (retract(u)@FEXPR(['X],[],MachineFloat))::$
+ retractIfCan(u:FRAC POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR(['X],[],MachineFloat),"failed")
+ foo := retractIfCan(u)$FEXPR(['X],[],MachineFloat)
+ foo case "failed" => "failed"
+ foo::FEXPR(['X],[],MachineFloat)::$
+
+ retract(u:EXPR FLOAT):$ == (retract(u)@FEXPR(['X],[],MachineFloat))::$
+ retractIfCan(u:EXPR FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR(['X],[],MachineFloat),"failed")
+ foo := retractIfCan(u)$FEXPR(['X],[],MachineFloat)
+ foo case "failed" => "failed"
+ foo::FEXPR(['X],[],MachineFloat)::$
+
+ retract(u:EXPR INT):$ == (retract(u)@FEXPR(['X],[],MachineFloat))::$
+ retractIfCan(u:EXPR INT):Union($,"failed") ==
+ foo : Union(FEXPR(['X],[],MachineFloat),"failed")
+ foo := retractIfCan(u)$FEXPR(['X],[],MachineFloat)
+ foo case "failed" => "failed"
+ foo::FEXPR(['X],[],MachineFloat)::$
+
+ retract(u:POLY FLOAT):$ == (retract(u)@FEXPR(['X],[],MachineFloat))::$
+ retractIfCan(u:POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR(['X],[],MachineFloat),"failed")
+ foo := retractIfCan(u)$FEXPR(['X],[],MachineFloat)
+ foo case "failed" => "failed"
+ foo::FEXPR(['X],[],MachineFloat)::$
+
+ retract(u:POLY INT):$ == (retract(u)@FEXPR(['X],[],MachineFloat))::$
+ retractIfCan(u:POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR(['X],[],MachineFloat),"failed")
+ foo := retractIfCan(u)$FEXPR(['X],[],MachineFloat)
+ foo case "failed" => "failed"
+ foo::FEXPR(['X],[],MachineFloat)::$
+
+ coerce(u:FEXPR(['X],[],MachineFloat)):$ ==
+ coerce((u::Expression(MachineFloat))$FEXPR(['X],[],MachineFloat))$Rep
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP10 Asp10}
+<<domain ASP10 Asp10>>=
+)abbrev domain ASP10 Asp10
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{ASP10} produces Fortran for Type 10 ASPs, needed for NAG routine
+++\axiomOpFrom{d02kef}{d02Package}. This ASP computes the values of a set of functions, for example:
+++\begin{verbatim}
+++ SUBROUTINE COEFFN(P,Q,DQDL,X,ELAM,JINT)
+++ DOUBLE PRECISION ELAM,P,Q,X,DQDL
+++ INTEGER JINT
+++ P=1.0D0
+++ Q=((-1.0D0*X**3)+ELAM*X*X-2.0D0)/(X*X)
+++ DQDL=1.0D0
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp10(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ EXF ==> Expression Float
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FEXPR ==> FortranExpression(['JINT,'X,'ELAM],[],MFLOAT)
+ MFLOAT ==> MachineFloat
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : Vector FEXPR -> %
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : FST := "real"::FST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(P,fortranReal()$FT,syms)$SYMTAB
+ declare!(Q,fortranReal()$FT,syms)$SYMTAB
+ declare!(DQDL,fortranReal()$FT,syms)$SYMTAB
+ declare!(X,fortranReal()$FT,syms)$SYMTAB
+ declare!(ELAM,fortranReal()$FT,syms)$SYMTAB
+ declare!(JINT,fortranInteger()$FT,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$Union(fst:FST,void:"void"),
+ [P,Q,DQDL,X,ELAM,JINT],syms)
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ coerce(c:FortranCode):% == coerce(c)$Rep
+
+ coerce(r:RSFC):% == coerce(r)$Rep
+
+ coerce(c:List FortranCode):% == coerce(c)$Rep
+
+ -- To help the poor old compiler!
+ localAssign(s:Symbol,u:Expression MFLOAT):FortranCode ==
+ assign(s,u)$FortranCode
+
+ coerce(u:Vector FEXPR):% ==
+ import Vector FEXPR
+ not (#u = 3) => error "Incorrect Dimension For Vector"
+ ([localAssign(P,elt(u,1)::Expression MFLOAT),_
+ localAssign(Q,elt(u,2)::Expression MFLOAT),_
+ localAssign(DQDL,elt(u,3)::Expression MFLOAT),_
+ returns()$FortranCode ]$List(FortranCode))::Rep
+
+ coerce(u:%):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP12 Asp12}
+<<domain ASP12 Asp12>>=
+)abbrev domain ASP12 Asp12
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Oct 1993
+++ Date Last Updated: 18 March 1994
+++ 21 June 1994 Changed print to printStatement
+++ Related Constructors:
+++ Description:
+++\spadtype{Asp12} produces Fortran for Type 12 ASPs, needed for NAG routine
+++\axiomOpFrom{d02kef}{d02Package} etc., for example:
+++\begin{verbatim}
+++ SUBROUTINE MONIT (MAXIT,IFLAG,ELAM,FINFO)
+++ DOUBLE PRECISION ELAM,FINFO(15)
+++ INTEGER MAXIT,IFLAG
+++ IF(MAXIT.EQ.-1)THEN
+++ PRINT*,"Output from Monit"
+++ ENDIF
+++ PRINT*,MAXIT,IFLAG,ELAM,(FINFO(I),I=1,4)
+++ RETURN
+++ END
+++\end{verbatim}
+Asp12(name): Exports == Implementation where
+ name : Symbol
+
+ O ==> OutputForm
+ S ==> Symbol
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ EXI ==> Expression Integer
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ U ==> Union(I: Expression Integer,F: Expression Float,_
+ CF: Expression Complex Float,switch:Switch)
+ UFST ==> Union(fst:FST,void:"void")
+
+ Exports ==> FortranProgramCategory with
+ outputAsFortran:() -> Void
+ ++outputAsFortran() generates the default code for \spadtype{ASP12}.
+
+ Implementation ==> add
+
+ import FC
+ import Switch
+
+ real : FST := "real"::FST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(MAXIT,fortranInteger()$FT,syms)$SYMTAB
+ declare!(IFLAG,fortranInteger()$FT,syms)$SYMTAB
+ declare!(ELAM,fortranReal()$FT,syms)$SYMTAB
+ fType : FT := construct([real]$UFST,["15"::Symbol],false)$FT
+ declare!(FINFO,fType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,[MAXIT,IFLAG,ELAM,FINFO],syms)
+
+ -- eqn : O := (I::O)=(1@Integer::EXI::O)
+ code:=([cond(EQ([MAXIT@S::EXI]$U,[-1::EXI]$U),
+ printStatement(["_"Output from Monit_""::O])),
+ printStatement([MAXIT::O,IFLAG::O,ELAM::O,subscript("(FINFO"::S,[I::O])::O,"I=1"::S::O,"4)"::S::O]), -- YUCK!
+ returns()]$List(FortranCode))::Rep
+
+ coerce(u:%):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u:%):Void == outputAsFortran(u)$Rep
+ outputAsFortran():Void == outputAsFortran(code)$Rep
+
+@
+\section{domain ASP19 Asp19}
+<<domain ASP19 Asp19>>=
+)abbrev domain ASP19 Asp19
+++ Author: Mike Dewar, Godfrey Nolan, Grant Keady
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp19} produces Fortran for Type 19 ASPs, evaluating a set of
+++functions and their jacobian at a given point, for example:
+++\begin{verbatim}
+++ SUBROUTINE LSFUN2(M,N,XC,FVECC,FJACC,LJC)
+++ DOUBLE PRECISION FVECC(M),FJACC(LJC,N),XC(N)
+++ INTEGER M,N,LJC
+++ INTEGER I,J
+++ DO 25003 I=1,LJC
+++ DO 25004 J=1,N
+++ FJACC(I,J)=0.0D0
+++25004 CONTINUE
+++25003 CONTINUE
+++ FVECC(1)=((XC(1)-0.14D0)*XC(3)+(15.0D0*XC(1)-2.1D0)*XC(2)+1.0D0)/(
+++ &XC(3)+15.0D0*XC(2))
+++ FVECC(2)=((XC(1)-0.18D0)*XC(3)+(7.0D0*XC(1)-1.26D0)*XC(2)+1.0D0)/(
+++ &XC(3)+7.0D0*XC(2))
+++ FVECC(3)=((XC(1)-0.22D0)*XC(3)+(4.333333333333333D0*XC(1)-0.953333
+++ &3333333333D0)*XC(2)+1.0D0)/(XC(3)+4.333333333333333D0*XC(2))
+++ FVECC(4)=((XC(1)-0.25D0)*XC(3)+(3.0D0*XC(1)-0.75D0)*XC(2)+1.0D0)/(
+++ &XC(3)+3.0D0*XC(2))
+++ FVECC(5)=((XC(1)-0.29D0)*XC(3)+(2.2D0*XC(1)-0.6379999999999999D0)*
+++ &XC(2)+1.0D0)/(XC(3)+2.2D0*XC(2))
+++ FVECC(6)=((XC(1)-0.32D0)*XC(3)+(1.666666666666667D0*XC(1)-0.533333
+++ &3333333333D0)*XC(2)+1.0D0)/(XC(3)+1.666666666666667D0*XC(2))
+++ FVECC(7)=((XC(1)-0.35D0)*XC(3)+(1.285714285714286D0*XC(1)-0.45D0)*
+++ &XC(2)+1.0D0)/(XC(3)+1.285714285714286D0*XC(2))
+++ FVECC(8)=((XC(1)-0.39D0)*XC(3)+(XC(1)-0.39D0)*XC(2)+1.0D0)/(XC(3)+
+++ &XC(2))
+++ FVECC(9)=((XC(1)-0.37D0)*XC(3)+(XC(1)-0.37D0)*XC(2)+1.285714285714
+++ &286D0)/(XC(3)+XC(2))
+++ FVECC(10)=((XC(1)-0.58D0)*XC(3)+(XC(1)-0.58D0)*XC(2)+1.66666666666
+++ &6667D0)/(XC(3)+XC(2))
+++ FVECC(11)=((XC(1)-0.73D0)*XC(3)+(XC(1)-0.73D0)*XC(2)+2.2D0)/(XC(3)
+++ &+XC(2))
+++ FVECC(12)=((XC(1)-0.96D0)*XC(3)+(XC(1)-0.96D0)*XC(2)+3.0D0)/(XC(3)
+++ &+XC(2))
+++ FVECC(13)=((XC(1)-1.34D0)*XC(3)+(XC(1)-1.34D0)*XC(2)+4.33333333333
+++ &3333D0)/(XC(3)+XC(2))
+++ FVECC(14)=((XC(1)-2.1D0)*XC(3)+(XC(1)-2.1D0)*XC(2)+7.0D0)/(XC(3)+X
+++ &C(2))
+++ FVECC(15)=((XC(1)-4.39D0)*XC(3)+(XC(1)-4.39D0)*XC(2)+15.0D0)/(XC(3
+++ &)+XC(2))
+++ FJACC(1,1)=1.0D0
+++ FJACC(1,2)=-15.0D0/(XC(3)**2+30.0D0*XC(2)*XC(3)+225.0D0*XC(2)**2)
+++ FJACC(1,3)=-1.0D0/(XC(3)**2+30.0D0*XC(2)*XC(3)+225.0D0*XC(2)**2)
+++ FJACC(2,1)=1.0D0
+++ FJACC(2,2)=-7.0D0/(XC(3)**2+14.0D0*XC(2)*XC(3)+49.0D0*XC(2)**2)
+++ FJACC(2,3)=-1.0D0/(XC(3)**2+14.0D0*XC(2)*XC(3)+49.0D0*XC(2)**2)
+++ FJACC(3,1)=1.0D0
+++ FJACC(3,2)=((-0.1110223024625157D-15*XC(3))-4.333333333333333D0)/(
+++ &XC(3)**2+8.666666666666666D0*XC(2)*XC(3)+18.77777777777778D0*XC(2)
+++ &**2)
+++ FJACC(3,3)=(0.1110223024625157D-15*XC(2)-1.0D0)/(XC(3)**2+8.666666
+++ &666666666D0*XC(2)*XC(3)+18.77777777777778D0*XC(2)**2)
+++ FJACC(4,1)=1.0D0
+++ FJACC(4,2)=-3.0D0/(XC(3)**2+6.0D0*XC(2)*XC(3)+9.0D0*XC(2)**2)
+++ FJACC(4,3)=-1.0D0/(XC(3)**2+6.0D0*XC(2)*XC(3)+9.0D0*XC(2)**2)
+++ FJACC(5,1)=1.0D0
+++ FJACC(5,2)=((-0.1110223024625157D-15*XC(3))-2.2D0)/(XC(3)**2+4.399
+++ &999999999999D0*XC(2)*XC(3)+4.839999999999998D0*XC(2)**2)
+++ FJACC(5,3)=(0.1110223024625157D-15*XC(2)-1.0D0)/(XC(3)**2+4.399999
+++ &999999999D0*XC(2)*XC(3)+4.839999999999998D0*XC(2)**2)
+++ FJACC(6,1)=1.0D0
+++ FJACC(6,2)=((-0.2220446049250313D-15*XC(3))-1.666666666666667D0)/(
+++ &XC(3)**2+3.333333333333333D0*XC(2)*XC(3)+2.777777777777777D0*XC(2)
+++ &**2)
+++ FJACC(6,3)=(0.2220446049250313D-15*XC(2)-1.0D0)/(XC(3)**2+3.333333
+++ &333333333D0*XC(2)*XC(3)+2.777777777777777D0*XC(2)**2)
+++ FJACC(7,1)=1.0D0
+++ FJACC(7,2)=((-0.5551115123125783D-16*XC(3))-1.285714285714286D0)/(
+++ &XC(3)**2+2.571428571428571D0*XC(2)*XC(3)+1.653061224489796D0*XC(2)
+++ &**2)
+++ FJACC(7,3)=(0.5551115123125783D-16*XC(2)-1.0D0)/(XC(3)**2+2.571428
+++ &571428571D0*XC(2)*XC(3)+1.653061224489796D0*XC(2)**2)
+++ FJACC(8,1)=1.0D0
+++ FJACC(8,2)=-1.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(8,3)=-1.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(9,1)=1.0D0
+++ FJACC(9,2)=-1.285714285714286D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)*
+++ &*2)
+++ FJACC(9,3)=-1.285714285714286D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)*
+++ &*2)
+++ FJACC(10,1)=1.0D0
+++ FJACC(10,2)=-1.666666666666667D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)
+++ &**2)
+++ FJACC(10,3)=-1.666666666666667D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)
+++ &**2)
+++ FJACC(11,1)=1.0D0
+++ FJACC(11,2)=-2.2D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(11,3)=-2.2D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(12,1)=1.0D0
+++ FJACC(12,2)=-3.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(12,3)=-3.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(13,1)=1.0D0
+++ FJACC(13,2)=-4.333333333333333D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)
+++ &**2)
+++ FJACC(13,3)=-4.333333333333333D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)
+++ &**2)
+++ FJACC(14,1)=1.0D0
+++ FJACC(14,2)=-7.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(14,3)=-7.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(15,1)=1.0D0
+++ FJACC(15,2)=-15.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ FJACC(15,3)=-15.0D0/(XC(3)**2+2.0D0*XC(2)*XC(3)+XC(2)**2)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp19(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FC))
+ FSTU ==> Union(fst:FST,void:"void")
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ MFLOAT ==> MachineFloat
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ MF2 ==> MatrixCategoryFunctions2(FEXPR,VEC FEXPR,VEC FEXPR,Matrix FEXPR,EXPR MFLOAT,VEC EXPR MFLOAT,VEC EXPR MFLOAT,Matrix EXPR MFLOAT)
+ FEXPR ==> FortranExpression([],['XC],MFLOAT)
+ S ==> Symbol
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : FSTU := ["real"::FST]$FSTU
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(M,fortranInteger()$FT,syms)$SYMTAB
+ declare!(N,fortranInteger()$FT,syms)$SYMTAB
+ declare!(LJC,fortranInteger()$FT,syms)$SYMTAB
+ xcType : FT := construct(real,[N],false)$FT
+ declare!(XC,xcType,syms)$SYMTAB
+ fveccType : FT := construct(real,[M],false)$FT
+ declare!(FVECC,fveccType,syms)$SYMTAB
+ fjaccType : FT := construct(real,[LJC,N],false)$FT
+ declare!(FJACC,fjaccType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,[M,N,XC,FVECC,FJACC,LJC],syms)
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ -- Take a symbol, pull of the script and turn it into an integer!!
+ o2int(u:S):Integer ==
+ o : OutputForm := first elt(scripts(u)$S,sub)
+ o pretend Integer
+
+ -- To help the poor old compiler!
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign1(s:S,j:Matrix FEXPR):FC ==
+ j' : Matrix EXPR MFLOAT := map(fexpr2expr,j)$MF2
+ assign(s,j')$FC
+
+ localAssign2(s:S,j:VEC FEXPR):FC ==
+ j' : VEC EXPR MFLOAT := map(fexpr2expr,j)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,j')$FC
+
+ coerce(u:VEC FEXPR):$ ==
+ -- First zero the Jacobian matrix in case we miss some derivatives which
+ -- are zero.
+ import POLY INT
+ seg1 : Segment (POLY INT) := segment(1::(POLY INT),LJC@S::(POLY INT))
+ seg2 : Segment (POLY INT) := segment(1::(POLY INT),N@S::(POLY INT))
+ s1 : SegmentBinding POLY INT := equation(I@S,seg1)
+ s2 : SegmentBinding POLY INT := equation(J@S,seg2)
+ as : FC := assign(FJACC,[I@S::(POLY INT),J@S::(POLY INT)],0.0::EXPR FLOAT)
+ clear : FC := forLoop(s1,forLoop(s2,as))
+ j:Integer
+ x:S := XC::S
+ pu:List(S) := []
+ -- Work out which variables appear in the expressions
+ for e in entries(u) repeat
+ pu := setUnion(pu,variables(e)$FEXPR)
+ scriptList : List Integer := map(o2int,pu)$ListFunctions2(S,Integer)
+ -- This should be the maximum XC_n which occurs (there may be others
+ -- which don't):
+ n:Integer := reduce(max,scriptList)$List(Integer)
+ p:List(S) := []
+ for j in 1..n repeat p:= cons(subscript(x,[j::OutputForm])$S,p)
+ p:= reverse(p)
+ jac:Matrix(FEXPR) := _
+ jacobian(u,p)$MultiVariableCalculusFunctions(S,FEXPR,VEC FEXPR,List(S))
+ c1:FC := localAssign2(FVECC,u)
+ c2:FC := localAssign1(FJACC,jac)
+ [clear,c1,c2,returns()]$List(FC)::$
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP20 Asp20}
+<<domain ASP20 Asp20>>=
+)abbrev domain ASP20 Asp20
+++ Author: Mike Dewar and Godfrey Nolan and Grant Keady
+++ Date Created: Dec 1993
+++ Date Last Updated: 21 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp20} produces Fortran for Type 20 ASPs, for example:
+++\begin{verbatim}
+++ SUBROUTINE QPHESS(N,NROWH,NCOLH,JTHCOL,HESS,X,HX)
+++ DOUBLE PRECISION HX(N),X(N),HESS(NROWH,NCOLH)
+++ INTEGER JTHCOL,N,NROWH,NCOLH
+++ HX(1)=2.0D0*X(1)
+++ HX(2)=2.0D0*X(2)
+++ HX(3)=2.0D0*X(4)+2.0D0*X(3)
+++ HX(4)=2.0D0*X(4)+2.0D0*X(3)
+++ HX(5)=2.0D0*X(5)
+++ HX(6)=(-2.0D0*X(7))+(-2.0D0*X(6))
+++ HX(7)=(-2.0D0*X(7))+(-2.0D0*X(6))
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp20(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ PI ==> PositiveInteger
+ UFST ==> Union(fst:FST,void:"void")
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ MAT ==> Matrix
+ VF2 ==> VectorFunctions2
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression([],['X,'HESS],MFLOAT)
+ O ==> OutputForm
+ M2 ==> MatrixCategoryFunctions2
+ MF2a ==> M2(FRAC POLY INT,VEC FRAC POLY INT,VEC FRAC POLY INT,
+ MAT FRAC POLY INT,FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2b ==> M2(FRAC POLY FLOAT,VEC FRAC POLY FLOAT,VEC FRAC POLY FLOAT,
+ MAT FRAC POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2c ==> M2(POLY INT,VEC POLY INT,VEC POLY INT,MAT POLY INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2d ==> M2(POLY FLOAT,VEC POLY FLOAT,VEC POLY FLOAT,
+ MAT POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2e ==> M2(EXPR INT,VEC EXPR INT,VEC EXPR INT,MAT EXPR INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2f ==> M2(EXPR FLOAT,VEC EXPR FLOAT,VEC EXPR FLOAT,
+ MAT EXPR FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+
+
+ Exports ==> FortranMatrixFunctionCategory with
+ coerce: MAT FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ declare!(NROWH,fortranInteger(),syms)$SYMTAB
+ declare!(NCOLH,fortranInteger(),syms)$SYMTAB
+ declare!(JTHCOL,fortranInteger(),syms)$SYMTAB
+ hessType : FT := construct(real,[NROWH,NCOLH],false)$FT
+ declare!(HESS,hessType,syms)$SYMTAB
+ xType : FT := construct(real,[N],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ declare!(HX,xType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,
+ [N,NROWH,NCOLH,JTHCOL,HESS,X,HX],syms)
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ -- To help the poor old compiler!
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign(s:Symbol,j:VEC FEXPR):FortranCode ==
+ j' : VEC EXPR MFLOAT := map(fexpr2expr,j)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,j')$FortranCode
+
+ coerce(u:MAT FEXPR):$ ==
+ j:Integer
+ x:Symbol := X::Symbol
+ n := nrows(u)::PI
+ p:VEC FEXPR := [retract(subscript(x,[j::O])$Symbol)@FEXPR for j in 1..n]
+ prod:VEC FEXPR := u*p
+ ([localAssign(HX,prod),returns()$FortranCode]$List(FortranCode))::$
+
+ retract(u:MAT FRAC POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2a
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2a
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT FRAC POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2b
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2b
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2e
+ v::$
+
+ retractIfCan(u:MAT EXPR INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2e
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2f
+ v::$
+
+ retractIfCan(u:MAT EXPR FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2f
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2c
+ v::$
+
+ retractIfCan(u:MAT POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2c
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2d
+ v::$
+
+ retractIfCan(u:MAT POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2d
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ coerce(u:$):O == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP24 Asp24}
+<<domain ASP24 Asp24>>=
+)abbrev domain ASP24 Asp24
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 21 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp24} produces Fortran for Type 24 ASPs which evaluate a
+++multivariate function at a point (needed for NAG routine \axiomOpFrom{e04jaf}{e04Package}), for example:
+++\begin{verbatim}
+++ SUBROUTINE FUNCT1(N,XC,FC)
+++ DOUBLE PRECISION FC,XC(N)
+++ INTEGER N
+++ FC=10.0D0*XC(4)**4+(-40.0D0*XC(1)*XC(4)**3)+(60.0D0*XC(1)**2+5
+++ &.0D0)*XC(4)**2+((-10.0D0*XC(3))+(-40.0D0*XC(1)**3))*XC(4)+16.0D0*X
+++ &C(3)**4+(-32.0D0*XC(2)*XC(3)**3)+(24.0D0*XC(2)**2+5.0D0)*XC(3)**2+
+++ &(-8.0D0*XC(2)**3*XC(3))+XC(2)**4+100.0D0*XC(2)**2+20.0D0*XC(1)*XC(
+++ &2)+10.0D0*XC(1)**4+XC(1)**2
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp24(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FSTU ==> Union(fst:FST,void:"void")
+ FEXPR ==> FortranExpression([],['XC],MachineFloat)
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+
+ Exports ==> FortranFunctionCategory with
+ coerce : FEXPR -> $
+ ++ coerce(f) takes an object from the appropriate instantiation of
+ ++ \spadtype{FortranExpression} and turns it into an ASP.
+
+
+ Implementation ==> add
+
+
+ real : FSTU := ["real"::FST]$FSTU
+ syms : SYMTAB := empty()
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ xcType : FT := construct(real,[N::Symbol],false)$FT
+ declare!(XC,xcType,syms)$SYMTAB
+ declare!(FC,fortranReal(),syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,[N,XC,FC],syms)
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:FEXPR):$ ==
+ coerce(assign(FC,u::Expression(MachineFloat))$FortranCode)$Rep
+
+ retract(u:FRAC POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:FRAC POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:EXPR FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:EXPR INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP27 Asp27}
+<<domain ASP27 Asp27>>=
+)abbrev domain ASP27 Asp27
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Nov 1993
+++ Date Last Updated: 27 April 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp27} produces Fortran for Type 27 ASPs, needed for NAG routine
+++\axiomOpFrom{f02fjf}{f02Package} ,for example:
+++\begin{verbatim}
+++ FUNCTION DOT(IFLAG,N,Z,W,RWORK,LRWORK,IWORK,LIWORK)
+++ DOUBLE PRECISION W(N),Z(N),RWORK(LRWORK)
+++ INTEGER N,LIWORK,IFLAG,LRWORK,IWORK(LIWORK)
+++ DOT=(W(16)+(-0.5D0*W(15)))*Z(16)+((-0.5D0*W(16))+W(15)+(-0.5D0*W(1
+++ &4)))*Z(15)+((-0.5D0*W(15))+W(14)+(-0.5D0*W(13)))*Z(14)+((-0.5D0*W(
+++ &14))+W(13)+(-0.5D0*W(12)))*Z(13)+((-0.5D0*W(13))+W(12)+(-0.5D0*W(1
+++ &1)))*Z(12)+((-0.5D0*W(12))+W(11)+(-0.5D0*W(10)))*Z(11)+((-0.5D0*W(
+++ &11))+W(10)+(-0.5D0*W(9)))*Z(10)+((-0.5D0*W(10))+W(9)+(-0.5D0*W(8))
+++ &)*Z(9)+((-0.5D0*W(9))+W(8)+(-0.5D0*W(7)))*Z(8)+((-0.5D0*W(8))+W(7)
+++ &+(-0.5D0*W(6)))*Z(7)+((-0.5D0*W(7))+W(6)+(-0.5D0*W(5)))*Z(6)+((-0.
+++ &5D0*W(6))+W(5)+(-0.5D0*W(4)))*Z(5)+((-0.5D0*W(5))+W(4)+(-0.5D0*W(3
+++ &)))*Z(4)+((-0.5D0*W(4))+W(3)+(-0.5D0*W(2)))*Z(3)+((-0.5D0*W(3))+W(
+++ &2)+(-0.5D0*W(1)))*Z(2)+((-0.5D0*W(2))+W(1))*Z(1)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp27(name): Exports == Implementation where
+ name : Symbol
+
+ O ==> OutputForm
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ UFST ==> Union(fst:FST,void:"void")
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ EXPR ==> Expression
+ MAT ==> Matrix
+ MFLOAT ==> MachineFloat
+
+
+
+ Exports == FortranMatrixCategory
+
+ Implementation == add
+
+
+ real : UFST := ["real"::FST]$UFST
+ integer : UFST := ["integer"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(IFLAG,fortranInteger(),syms)$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ declare!(LRWORK,fortranInteger(),syms)$SYMTAB
+ declare!(LIWORK,fortranInteger(),syms)$SYMTAB
+ zType : FT := construct(real,[N],false)$FT
+ declare!(Z,zType,syms)$SYMTAB
+ declare!(W,zType,syms)$SYMTAB
+ rType : FT := construct(real,[LRWORK],false)$FT
+ declare!(RWORK,rType,syms)$SYMTAB
+ iType : FT := construct(integer,[LIWORK],false)$FT
+ declare!(IWORK,iType,syms)$SYMTAB
+ Rep := FortranProgram(name,real,
+ [IFLAG,N,Z,W,RWORK,LRWORK,IWORK,LIWORK],syms)
+
+ -- To help the poor old compiler!
+ localCoerce(u:Symbol):EXPR(MFLOAT) == coerce(u)$EXPR(MFLOAT)
+
+ coerce (u:MAT MFLOAT):$ ==
+ Ws: Symbol := W
+ Zs: Symbol := Z
+ code : List FC
+ l:EXPR MFLOAT := "+"/ _
+ [("+"/[localCoerce(elt(Ws,[j::O])$Symbol) * u(j,i)_
+ for j in 1..nrows(u)::PI])_
+ *localCoerce(elt(Zs,[i::O])$Symbol) for i in 1..ncols(u)::PI]
+ c := assign(name,l)$FC
+ code := [c,returns()]$List(FC)
+ code::$
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP28 Asp28}
+<<domain ASP28 Asp28>>=
+)abbrev domain ASP28 Asp28
+++ Author: Mike Dewar
+++ Date Created: 21 March 1994
+++ Date Last Updated: 28 April 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp28} produces Fortran for Type 28 ASPs, used in NAG routine
+++\axiomOpFrom{f02fjf}{f02Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE IMAGE(IFLAG,N,Z,W,RWORK,LRWORK,IWORK,LIWORK)
+++ DOUBLE PRECISION Z(N),W(N),IWORK(LRWORK),RWORK(LRWORK)
+++ INTEGER N,LIWORK,IFLAG,LRWORK
+++ W(1)=0.01707454969713436D0*Z(16)+0.001747395874954051D0*Z(15)+0.00
+++ &2106973900813502D0*Z(14)+0.002957434991769087D0*Z(13)+(-0.00700554
+++ &0882865317D0*Z(12))+(-0.01219194009813166D0*Z(11))+0.0037230647365
+++ &3087D0*Z(10)+0.04932374658377151D0*Z(9)+(-0.03586220812223305D0*Z(
+++ &8))+(-0.04723268012114625D0*Z(7))+(-0.02434652144032987D0*Z(6))+0.
+++ &2264766947290192D0*Z(5)+(-0.1385343580686922D0*Z(4))+(-0.116530050
+++ &8238904D0*Z(3))+(-0.2803531651057233D0*Z(2))+1.019463911841327D0*Z
+++ &(1)
+++ W(2)=0.0227345011107737D0*Z(16)+0.008812321197398072D0*Z(15)+0.010
+++ &94012210519586D0*Z(14)+(-0.01764072463999744D0*Z(13))+(-0.01357136
+++ &72105995D0*Z(12))+0.00157466157362272D0*Z(11)+0.05258889186338282D
+++ &0*Z(10)+(-0.01981532388243379D0*Z(9))+(-0.06095390688679697D0*Z(8)
+++ &)+(-0.04153119955569051D0*Z(7))+0.2176561076571465D0*Z(6)+(-0.0532
+++ &5555586632358D0*Z(5))+(-0.1688977368984641D0*Z(4))+(-0.32440166056
+++ &67343D0*Z(3))+0.9128222941872173D0*Z(2)+(-0.2419652703415429D0*Z(1
+++ &))
+++ W(3)=0.03371198197190302D0*Z(16)+0.02021603150122265D0*Z(15)+(-0.0
+++ &06607305534689702D0*Z(14))+(-0.03032392238968179D0*Z(13))+0.002033
+++ &305231024948D0*Z(12)+0.05375944956767728D0*Z(11)+(-0.0163213312502
+++ &9967D0*Z(10))+(-0.05483186562035512D0*Z(9))+(-0.04901428822579872D
+++ &0*Z(8))+0.2091097927887612D0*Z(7)+(-0.05760560341383113D0*Z(6))+(-
+++ &0.1236679206156403D0*Z(5))+(-0.3523683853026259D0*Z(4))+0.88929961
+++ &32269974D0*Z(3)+(-0.2995429545781457D0*Z(2))+(-0.02986582812574917
+++ &D0*Z(1))
+++ W(4)=0.05141563713660119D0*Z(16)+0.005239165960779299D0*Z(15)+(-0.
+++ &01623427735779699D0*Z(14))+(-0.01965809746040371D0*Z(13))+0.054688
+++ &97337339577D0*Z(12)+(-0.014224695935687D0*Z(11))+(-0.0505181779315
+++ &6355D0*Z(10))+(-0.04353074206076491D0*Z(9))+0.2012230497530726D0*Z
+++ &(8)+(-0.06630874514535952D0*Z(7))+(-0.1280829963720053D0*Z(6))+(-0
+++ &.305169742604165D0*Z(5))+0.8600427128450191D0*Z(4)+(-0.32415033802
+++ &68184D0*Z(3))+(-0.09033531980693314D0*Z(2))+0.09089205517109111D0*
+++ &Z(1)
+++ W(5)=0.04556369767776375D0*Z(16)+(-0.001822737697581869D0*Z(15))+(
+++ &-0.002512226501941856D0*Z(14))+0.02947046460707379D0*Z(13)+(-0.014
+++ &45079632086177D0*Z(12))+(-0.05034242196614937D0*Z(11))+(-0.0376966
+++ &3291725935D0*Z(10))+0.2171103102175198D0*Z(9)+(-0.0824949256021352
+++ &4D0*Z(8))+(-0.1473995209288945D0*Z(7))+(-0.315042193418466D0*Z(6))
+++ &+0.9591623347824002D0*Z(5)+(-0.3852396953763045D0*Z(4))+(-0.141718
+++ &5427288274D0*Z(3))+(-0.03423495461011043D0*Z(2))+0.319820917706851
+++ &6D0*Z(1)
+++ W(6)=0.04015147277405744D0*Z(16)+0.01328585741341559D0*Z(15)+0.048
+++ &26082005465965D0*Z(14)+(-0.04319641116207706D0*Z(13))+(-0.04931323
+++ &319055762D0*Z(12))+(-0.03526886317505474D0*Z(11))+0.22295383396730
+++ &01D0*Z(10)+(-0.07375317649315155D0*Z(9))+(-0.1589391311991561D0*Z(
+++ &8))+(-0.328001910890377D0*Z(7))+0.952576555482747D0*Z(6)+(-0.31583
+++ &09975786731D0*Z(5))+(-0.1846882042225383D0*Z(4))+(-0.0703762046700
+++ &4427D0*Z(3))+0.2311852964327382D0*Z(2)+0.04254083491825025D0*Z(1)
+++ W(7)=0.06069778964023718D0*Z(16)+0.06681263884671322D0*Z(15)+(-0.0
+++ &2113506688615768D0*Z(14))+(-0.083996867458326D0*Z(13))+(-0.0329843
+++ &8523869648D0*Z(12))+0.2276878326327734D0*Z(11)+(-0.067356038933017
+++ &95D0*Z(10))+(-0.1559813965382218D0*Z(9))+(-0.3363262957694705D0*Z(
+++ &8))+0.9442791158560948D0*Z(7)+(-0.3199955249404657D0*Z(6))+(-0.136
+++ &2463839920727D0*Z(5))+(-0.1006185171570586D0*Z(4))+0.2057504515015
+++ &423D0*Z(3)+(-0.02065879269286707D0*Z(2))+0.03160990266745513D0*Z(1
+++ &)
+++ W(8)=0.126386868896738D0*Z(16)+0.002563370039476418D0*Z(15)+(-0.05
+++ &581757739455641D0*Z(14))+(-0.07777893205900685D0*Z(13))+0.23117338
+++ &45834199D0*Z(12)+(-0.06031581134427592D0*Z(11))+(-0.14805474755869
+++ &52D0*Z(10))+(-0.3364014128402243D0*Z(9))+0.9364014128402244D0*Z(8)
+++ &+(-0.3269452524413048D0*Z(7))+(-0.1396841886557241D0*Z(6))+(-0.056
+++ &1733845834199D0*Z(5))+0.1777789320590069D0*Z(4)+(-0.04418242260544
+++ &359D0*Z(3))+(-0.02756337003947642D0*Z(2))+0.07361313110326199D0*Z(
+++ &1)
+++ W(9)=0.07361313110326199D0*Z(16)+(-0.02756337003947642D0*Z(15))+(-
+++ &0.04418242260544359D0*Z(14))+0.1777789320590069D0*Z(13)+(-0.056173
+++ &3845834199D0*Z(12))+(-0.1396841886557241D0*Z(11))+(-0.326945252441
+++ &3048D0*Z(10))+0.9364014128402244D0*Z(9)+(-0.3364014128402243D0*Z(8
+++ &))+(-0.1480547475586952D0*Z(7))+(-0.06031581134427592D0*Z(6))+0.23
+++ &11733845834199D0*Z(5)+(-0.07777893205900685D0*Z(4))+(-0.0558175773
+++ &9455641D0*Z(3))+0.002563370039476418D0*Z(2)+0.126386868896738D0*Z(
+++ &1)
+++ W(10)=0.03160990266745513D0*Z(16)+(-0.02065879269286707D0*Z(15))+0
+++ &.2057504515015423D0*Z(14)+(-0.1006185171570586D0*Z(13))+(-0.136246
+++ &3839920727D0*Z(12))+(-0.3199955249404657D0*Z(11))+0.94427911585609
+++ &48D0*Z(10)+(-0.3363262957694705D0*Z(9))+(-0.1559813965382218D0*Z(8
+++ &))+(-0.06735603893301795D0*Z(7))+0.2276878326327734D0*Z(6)+(-0.032
+++ &98438523869648D0*Z(5))+(-0.083996867458326D0*Z(4))+(-0.02113506688
+++ &615768D0*Z(3))+0.06681263884671322D0*Z(2)+0.06069778964023718D0*Z(
+++ &1)
+++ W(11)=0.04254083491825025D0*Z(16)+0.2311852964327382D0*Z(15)+(-0.0
+++ &7037620467004427D0*Z(14))+(-0.1846882042225383D0*Z(13))+(-0.315830
+++ &9975786731D0*Z(12))+0.952576555482747D0*Z(11)+(-0.328001910890377D
+++ &0*Z(10))+(-0.1589391311991561D0*Z(9))+(-0.07375317649315155D0*Z(8)
+++ &)+0.2229538339673001D0*Z(7)+(-0.03526886317505474D0*Z(6))+(-0.0493
+++ &1323319055762D0*Z(5))+(-0.04319641116207706D0*Z(4))+0.048260820054
+++ &65965D0*Z(3)+0.01328585741341559D0*Z(2)+0.04015147277405744D0*Z(1)
+++ W(12)=0.3198209177068516D0*Z(16)+(-0.03423495461011043D0*Z(15))+(-
+++ &0.1417185427288274D0*Z(14))+(-0.3852396953763045D0*Z(13))+0.959162
+++ &3347824002D0*Z(12)+(-0.315042193418466D0*Z(11))+(-0.14739952092889
+++ &45D0*Z(10))+(-0.08249492560213524D0*Z(9))+0.2171103102175198D0*Z(8
+++ &)+(-0.03769663291725935D0*Z(7))+(-0.05034242196614937D0*Z(6))+(-0.
+++ &01445079632086177D0*Z(5))+0.02947046460707379D0*Z(4)+(-0.002512226
+++ &501941856D0*Z(3))+(-0.001822737697581869D0*Z(2))+0.045563697677763
+++ &75D0*Z(1)
+++ W(13)=0.09089205517109111D0*Z(16)+(-0.09033531980693314D0*Z(15))+(
+++ &-0.3241503380268184D0*Z(14))+0.8600427128450191D0*Z(13)+(-0.305169
+++ &742604165D0*Z(12))+(-0.1280829963720053D0*Z(11))+(-0.0663087451453
+++ &5952D0*Z(10))+0.2012230497530726D0*Z(9)+(-0.04353074206076491D0*Z(
+++ &8))+(-0.05051817793156355D0*Z(7))+(-0.014224695935687D0*Z(6))+0.05
+++ &468897337339577D0*Z(5)+(-0.01965809746040371D0*Z(4))+(-0.016234277
+++ &35779699D0*Z(3))+0.005239165960779299D0*Z(2)+0.05141563713660119D0
+++ &*Z(1)
+++ W(14)=(-0.02986582812574917D0*Z(16))+(-0.2995429545781457D0*Z(15))
+++ &+0.8892996132269974D0*Z(14)+(-0.3523683853026259D0*Z(13))+(-0.1236
+++ &679206156403D0*Z(12))+(-0.05760560341383113D0*Z(11))+0.20910979278
+++ &87612D0*Z(10)+(-0.04901428822579872D0*Z(9))+(-0.05483186562035512D
+++ &0*Z(8))+(-0.01632133125029967D0*Z(7))+0.05375944956767728D0*Z(6)+0
+++ &.002033305231024948D0*Z(5)+(-0.03032392238968179D0*Z(4))+(-0.00660
+++ &7305534689702D0*Z(3))+0.02021603150122265D0*Z(2)+0.033711981971903
+++ &02D0*Z(1)
+++ W(15)=(-0.2419652703415429D0*Z(16))+0.9128222941872173D0*Z(15)+(-0
+++ &.3244016605667343D0*Z(14))+(-0.1688977368984641D0*Z(13))+(-0.05325
+++ &555586632358D0*Z(12))+0.2176561076571465D0*Z(11)+(-0.0415311995556
+++ &9051D0*Z(10))+(-0.06095390688679697D0*Z(9))+(-0.01981532388243379D
+++ &0*Z(8))+0.05258889186338282D0*Z(7)+0.00157466157362272D0*Z(6)+(-0.
+++ &0135713672105995D0*Z(5))+(-0.01764072463999744D0*Z(4))+0.010940122
+++ &10519586D0*Z(3)+0.008812321197398072D0*Z(2)+0.0227345011107737D0*Z
+++ &(1)
+++ W(16)=1.019463911841327D0*Z(16)+(-0.2803531651057233D0*Z(15))+(-0.
+++ &1165300508238904D0*Z(14))+(-0.1385343580686922D0*Z(13))+0.22647669
+++ &47290192D0*Z(12)+(-0.02434652144032987D0*Z(11))+(-0.04723268012114
+++ &625D0*Z(10))+(-0.03586220812223305D0*Z(9))+0.04932374658377151D0*Z
+++ &(8)+0.00372306473653087D0*Z(7)+(-0.01219194009813166D0*Z(6))+(-0.0
+++ &07005540882865317D0*Z(5))+0.002957434991769087D0*Z(4)+0.0021069739
+++ &00813502D0*Z(3)+0.001747395874954051D0*Z(2)+0.01707454969713436D0*
+++ &Z(1)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp28(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ EXPR ==> Expression
+ MFLOAT ==> MachineFloat
+ VEC ==> Vector
+ UFST ==> Union(fst:FST,void:"void")
+ MAT ==> Matrix
+
+ Exports == FortranMatrixCategory
+
+ Implementation == add
+
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()
+ declare!(IFLAG,fortranInteger(),syms)$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ declare!(LRWORK,fortranInteger(),syms)$SYMTAB
+ declare!(LIWORK,fortranInteger(),syms)$SYMTAB
+ xType : FT := construct(real,[N],false)$FT
+ declare!(Z,xType,syms)$SYMTAB
+ declare!(W,xType,syms)$SYMTAB
+ rType : FT := construct(real,[LRWORK],false)$FT
+ declare!(RWORK,rType,syms)$SYMTAB
+ iType : FT := construct(real,[LIWORK],false)$FT
+ declare!(IWORK,rType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,
+ [IFLAG,N,Z,W,RWORK,LRWORK,IWORK,LIWORK],syms)
+
+ -- To help the poor old compiler!
+ localCoerce(u:Symbol):EXPR(MFLOAT) == coerce(u)$EXPR(MFLOAT)
+
+ coerce (u:MAT MFLOAT):$ ==
+ Zs: Symbol := Z
+ code : List FC
+ r: List EXPR MFLOAT
+ r := ["+"/[u(j,i)*localCoerce(elt(Zs,[i::OutputForm])$Symbol)_
+ for i in 1..ncols(u)$MAT(MFLOAT)::PI]_
+ for j in 1..nrows(u)$MAT(MFLOAT)::PI]
+ code := [assign(W@Symbol,vector(r)$VEC(EXPR MFLOAT)),returns()]$List(FC)
+ code::$
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP29 Asp29}
+<<domain ASP29 Asp29>>=
+)abbrev domain ASP29 Asp29
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Nov 1993
+++ Date Last Updated: 18 March 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp29} produces Fortran for Type 29 ASPs, needed for NAG routine
+++\axiomOpFrom{f02fjf}{f02Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE MONIT(ISTATE,NEXTIT,NEVALS,NEVECS,K,F,D)
+++ DOUBLE PRECISION D(K),F(K)
+++ INTEGER K,NEXTIT,NEVALS,NVECS,ISTATE
+++ CALL F02FJZ(ISTATE,NEXTIT,NEVALS,NEVECS,K,F,D)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp29(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ FSTU ==> Union(fst:FST,void:"void")
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ EXF ==> Expression Float
+ EXI ==> Expression Integer
+ VEF ==> Vector Expression Float
+ VEI ==> Vector Expression Integer
+ MEI ==> Matrix Expression Integer
+ MEF ==> Matrix Expression Float
+ UEXPR ==> Union(I: Expression Integer,F: Expression Float,_
+ CF: Expression Complex Float)
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+
+ Exports == FortranProgramCategory with
+ outputAsFortran:() -> Void
+ ++outputAsFortran() generates the default code for \spadtype{ASP29}.
+
+
+ Implementation == add
+
+ import FST
+ import FT
+ import FC
+ import SYMTAB
+
+ real : FSTU := ["real"::FST]$FSTU
+ integer : FSTU := ["integer"::FST]$FSTU
+ syms : SYMTAB := empty()
+ declare!(ISTATE,fortranInteger(),syms)
+ declare!(NEXTIT,fortranInteger(),syms)
+ declare!(NEVALS,fortranInteger(),syms)
+ declare!(NVECS,fortranInteger(),syms)
+ declare!(K,fortranInteger(),syms)
+ kType : FT := construct(real,[K],false)$FT
+ declare!(F,kType,syms)
+ declare!(D,kType,syms)
+ Rep := FortranProgram(name,["void"]$FSTU,
+ [ISTATE,NEXTIT,NEVALS,NEVECS,K,F,D],syms)
+
+
+ outputAsFortran():Void ==
+ callOne := call("F02FJZ(ISTATE,NEXTIT,NEVALS,NEVECS,K,F,D)")
+ code : List FC := [callOne,returns()]$List(FC)
+ outputAsFortran(coerce(code)@Rep)$Rep
+
+@
+\section{domain ASP30 Asp30}
+<<domain ASP30 Asp30>>=
+)abbrev domain ASP30 Asp30
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Nov 1993
+++ Date Last Updated: 28 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp30} produces Fortran for Type 30 ASPs, needed for NAG routine
+++\axiomOpFrom{f04qaf}{f04Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE APROD(MODE,M,N,X,Y,RWORK,LRWORK,IWORK,LIWORK)
+++ DOUBLE PRECISION X(N),Y(M),RWORK(LRWORK)
+++ INTEGER M,N,LIWORK,IFAIL,LRWORK,IWORK(LIWORK),MODE
+++ DOUBLE PRECISION A(5,5)
+++ EXTERNAL F06PAF
+++ A(1,1)=1.0D0
+++ A(1,2)=0.0D0
+++ A(1,3)=0.0D0
+++ A(1,4)=-1.0D0
+++ A(1,5)=0.0D0
+++ A(2,1)=0.0D0
+++ A(2,2)=1.0D0
+++ A(2,3)=0.0D0
+++ A(2,4)=0.0D0
+++ A(2,5)=-1.0D0
+++ A(3,1)=0.0D0
+++ A(3,2)=0.0D0
+++ A(3,3)=1.0D0
+++ A(3,4)=-1.0D0
+++ A(3,5)=0.0D0
+++ A(4,1)=-1.0D0
+++ A(4,2)=0.0D0
+++ A(4,3)=-1.0D0
+++ A(4,4)=4.0D0
+++ A(4,5)=-1.0D0
+++ A(5,1)=0.0D0
+++ A(5,2)=-1.0D0
+++ A(5,3)=0.0D0
+++ A(5,4)=-1.0D0
+++ A(5,5)=4.0D0
+++ IF(MODE.EQ.1)THEN
+++ CALL F06PAF('N',M,N,1.0D0,A,M,X,1,1.0D0,Y,1)
+++ ELSEIF(MODE.EQ.2)THEN
+++ CALL F06PAF('T',M,N,1.0D0,A,M,Y,1,1.0D0,X,1)
+++ ENDIF
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp30(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ UFST ==> Union(fst:FST,void:"void")
+ MAT ==> Matrix
+ MFLOAT ==> MachineFloat
+ EXI ==> Expression Integer
+ UEXPR ==> Union(I:Expression Integer,F:Expression Float,_
+ CF:Expression Complex Float,switch:Switch)
+ S ==> Symbol
+
+ Exports == FortranMatrixCategory
+
+ Implementation == add
+
+ import FC
+ import FT
+ import Switch
+
+ real : UFST := ["real"::FST]$UFST
+ integer : UFST := ["integer"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(MODE,fortranInteger()$FT,syms)$SYMTAB
+ declare!(M,fortranInteger()$FT,syms)$SYMTAB
+ declare!(N,fortranInteger()$FT,syms)$SYMTAB
+ declare!(LRWORK,fortranInteger()$FT,syms)$SYMTAB
+ declare!(LIWORK,fortranInteger()$FT,syms)$SYMTAB
+ xType : FT := construct(real,[N],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ yType : FT := construct(real,[M],false)$FT
+ declare!(Y,yType,syms)$SYMTAB
+ rType : FT := construct(real,[LRWORK],false)$FT
+ declare!(RWORK,rType,syms)$SYMTAB
+ iType : FT := construct(integer,[LIWORK],false)$FT
+ declare!(IWORK,iType,syms)$SYMTAB
+ declare!(IFAIL,fortranInteger()$FT,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,
+ [MODE,M,N,X,Y,RWORK,LRWORK,IWORK,LIWORK],syms)
+
+ coerce(a:MAT MFLOAT):$ ==
+ locals : SYMTAB := empty()
+ numRows := nrows(a) :: Polynomial Integer
+ numCols := ncols(a) :: Polynomial Integer
+ declare!(A,[real,[numRows,numCols],false]$FT,locals)
+ declare!(F06PAF@S,construct(["void"]$UFST,[]@List(S),true)$FT,locals)
+ ptA:UEXPR := [("MODE"::S)::EXI]
+ ptB:UEXPR := [1::EXI]
+ ptC:UEXPR := [2::EXI]
+ sw1 : Switch := EQ(ptA,ptB)$Switch
+ sw2 : Switch := EQ(ptA,ptC)$Switch
+ callOne := call("F06PAF('N',M,N,1.0D0,A,M,X,1,1.0D0,Y,1)")
+ callTwo := call("F06PAF('T',M,N,1.0D0,A,M,Y,1,1.0D0,X,1)")
+ c : FC := cond(sw1,callOne,cond(sw2,callTwo))
+ code : List FC := [assign(A,a),c,returns()]
+ ([locals,code]$RSFC)::$
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP31 Asp31}
+<<domain ASP31 Asp31>>=
+)abbrev domain ASP31 Asp31
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 22 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranMatrixFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp31} produces Fortran for Type 31 ASPs, needed for NAG routine
+++\axiomOpFrom{d02ejf}{d02Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE PEDERV(X,Y,PW)
+++ DOUBLE PRECISION X,Y(*)
+++ DOUBLE PRECISION PW(3,3)
+++ PW(1,1)=-0.03999999999999999D0
+++ PW(1,2)=10000.0D0*Y(3)
+++ PW(1,3)=10000.0D0*Y(2)
+++ PW(2,1)=0.03999999999999999D0
+++ PW(2,2)=(-10000.0D0*Y(3))+(-60000000.0D0*Y(2))
+++ PW(2,3)=-10000.0D0*Y(2)
+++ PW(3,1)=0.0D0
+++ PW(3,2)=60000000.0D0*Y(2)
+++ PW(3,3)=0.0D0
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp31(name): Exports == Implementation where
+ name : Symbol
+
+ O ==> OutputForm
+ FST ==> FortranScalarType
+ UFST ==> Union(fst:FST,void:"void")
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['X],['Y],MFLOAT)
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ MAT ==> Matrix
+ VF2 ==> VectorFunctions2
+ MF2 ==> MatrixCategoryFunctions2(FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR,
+ EXPR MFLOAT,VEC EXPR MFLOAT,VEC EXPR MFLOAT,MAT EXPR MFLOAT)
+
+
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()
+ declare!(X,fortranReal(),syms)$SYMTAB
+ yType : FT := construct(real,["*"::Symbol],false)$FT
+ declare!(Y,yType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,[X,Y,PW],syms)
+
+ -- To help the poor old compiler!
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign(s:Symbol,j:MAT FEXPR):FC ==
+ j' : MAT EXPR MFLOAT := map(fexpr2expr,j)$MF2
+ assign(s,j')$FC
+
+ makeXList(n:Integer):List(Symbol) ==
+ j:Integer
+ y:Symbol := Y::Symbol
+ p:List(Symbol) := []
+ for j in 1 .. n repeat p:= cons(subscript(y,[j::OutputForm])$Symbol,p)
+ p:= reverse(p)
+
+ coerce(u:VEC FEXPR):$ ==
+ dimension := #u::Polynomial Integer
+ locals : SYMTAB := empty()
+ declare!(PW,[real,[dimension,dimension],false]$FT,locals)$SYMTAB
+ n:Integer := maxIndex(u)$VEC(FEXPR)
+ p:List(Symbol) := makeXList(n)
+ jac: MAT FEXPR := jacobian(u,p)$MultiVariableCalculusFunctions(_
+ Symbol,FEXPR ,VEC FEXPR,List(Symbol))
+ code : List FC := [localAssign(PW,jac),returns()$FC]$List(FC)
+ ([locals,code]$RSFC)::$
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ coerce(u:$):O == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP33 Asp33}
+<<domain ASP33 Asp33>>=
+)abbrev domain ASP33 Asp33
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Nov 1993
+++ Date Last Updated: 30 March 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory.
+++ Description:
+++\spadtype{Asp33} produces Fortran for Type 33 ASPs, needed for NAG routine
+++\axiomOpFrom{d02kef}{d02Package}. The code is a dummy ASP:
+++\begin{verbatim}
+++ SUBROUTINE REPORT(X,V,JINT)
+++ DOUBLE PRECISION V(3),X
+++ INTEGER JINT
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp33(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ UFST ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+
+ Exports ==> FortranProgramCategory with
+ outputAsFortran:() -> Void
+ ++outputAsFortran() generates the default code for \spadtype{ASP33}.
+
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()
+ declare!(JINT,fortranInteger(),syms)$SYMTAB
+ declare!(X,fortranReal(),syms)$SYMTAB
+ vType : FT := construct(real,["3"::Symbol],false)$FT
+ declare!(V,vType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,[X,V,JINT],syms)
+
+ outputAsFortran():Void ==
+ outputAsFortran( (returns()$FortranCode)::Rep )$Rep
+
+ outputAsFortran(u):Void == outputAsFortran(u)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+@
+\section{domain ASP34 Asp34}
+<<domain ASP34 Asp34>>=
+)abbrev domain ASP34 Asp34
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Nov 1993
+++ Date Last Updated: 14 June 1994 (Themos Tsikas)
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp34} produces Fortran for Type 34 ASPs, needed for NAG routine
+++\axiomOpFrom{f04mbf}{f04Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE MSOLVE(IFLAG,N,X,Y,RWORK,LRWORK,IWORK,LIWORK)
+++ DOUBLE PRECISION RWORK(LRWORK),X(N),Y(N)
+++ INTEGER I,J,N,LIWORK,IFLAG,LRWORK,IWORK(LIWORK)
+++ DOUBLE PRECISION W1(3),W2(3),MS(3,3)
+++ IFLAG=-1
+++ MS(1,1)=2.0D0
+++ MS(1,2)=1.0D0
+++ MS(1,3)=0.0D0
+++ MS(2,1)=1.0D0
+++ MS(2,2)=2.0D0
+++ MS(2,3)=1.0D0
+++ MS(3,1)=0.0D0
+++ MS(3,2)=1.0D0
+++ MS(3,3)=2.0D0
+++ CALL F04ASF(MS,N,X,N,Y,W1,W2,IFLAG)
+++ IFLAG=-IFLAG
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp34(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ UFST ==> Union(fst:FST,void:"void")
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ EXI ==> Expression Integer
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+
+ Exports == FortranMatrixCategory
+
+ Implementation == add
+
+ real : UFST := ["real"::FST]$UFST
+ integer : UFST := ["integer"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(IFLAG,fortranInteger(),syms)$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ xType : FT := construct(real,[N],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ declare!(Y,xType,syms)$SYMTAB
+ declare!(LRWORK,fortranInteger(),syms)$SYMTAB
+ declare!(LIWORK,fortranInteger(),syms)$SYMTAB
+ rType : FT := construct(real,[LRWORK],false)$FT
+ declare!(RWORK,rType,syms)$SYMTAB
+ iType : FT := construct(integer,[LIWORK],false)$FT
+ declare!(IWORK,iType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,
+ [IFLAG,N,X,Y,RWORK,LRWORK,IWORK,LIWORK],syms)
+
+ -- To help the poor old compiler
+ localAssign(s:Symbol,u:EXI):FC == assign(s,u)$FC
+
+ coerce(u:Matrix MachineFloat):$ ==
+ dimension := nrows(u) ::Polynomial Integer
+ locals : SYMTAB := empty()$SYMTAB
+ declare!(I,fortranInteger(),syms)$SYMTAB
+ declare!(J,fortranInteger(),syms)$SYMTAB
+ declare!(W1,[real,[dimension],false]$FT,locals)$SYMTAB
+ declare!(W2,[real,[dimension],false]$FT,locals)$SYMTAB
+ declare!(MS,[real,[dimension,dimension],false]$FT,locals)$SYMTAB
+ assign1 : FC := localAssign(IFLAG@Symbol,(-1)@EXI)
+ call : FC := call("F04ASF(MS,N,X,N,Y,W1,W2,IFLAG)")$FC
+ assign2 : FC := localAssign(IFLAG::Symbol,-(IFLAG@Symbol::EXI))
+ assign3 : FC := assign(MS,u)$FC
+ code : List FC := [assign1,assign3,call,assign2,returns()]$List(FC)
+ ([locals,code]$RSFC)::$
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP35 Asp35}
+<<domain ASP35 Asp35>>=
+)abbrev domain ASP35 Asp35
+++ Author: Mike Dewar, Godfrey Nolan, Grant Keady
+++ Date Created: Mar 1993
+++ Date Last Updated: 22 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp35} produces Fortran for Type 35 ASPs, needed for NAG routines
+++\axiomOpFrom{c05pbf}{c05Package}, \axiomOpFrom{c05pcf}{c05Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE FCN(N,X,FVEC,FJAC,LDFJAC,IFLAG)
+++ DOUBLE PRECISION X(N),FVEC(N),FJAC(LDFJAC,N)
+++ INTEGER LDFJAC,N,IFLAG
+++ IF(IFLAG.EQ.1)THEN
+++ FVEC(1)=(-1.0D0*X(2))+X(1)
+++ FVEC(2)=(-1.0D0*X(3))+2.0D0*X(2)
+++ FVEC(3)=3.0D0*X(3)
+++ ELSEIF(IFLAG.EQ.2)THEN
+++ FJAC(1,1)=1.0D0
+++ FJAC(1,2)=-1.0D0
+++ FJAC(1,3)=0.0D0
+++ FJAC(2,1)=0.0D0
+++ FJAC(2,2)=2.0D0
+++ FJAC(2,3)=-1.0D0
+++ FJAC(3,1)=0.0D0
+++ FJAC(3,2)=0.0D0
+++ FJAC(3,3)=3.0D0
+++ ENDIF
+++ END
+++\end{verbatim}
+
+Asp35(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ UFST ==> Union(fst:FST,void:"void")
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ MAT ==> Matrix
+ VF2 ==> VectorFunctions2
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression([],['X],MFLOAT)
+ MF2 ==> MatrixCategoryFunctions2(FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR,
+ EXPR MFLOAT,VEC EXPR MFLOAT,VEC EXPR MFLOAT,MAT EXPR MFLOAT)
+ SWU ==> Union(I:Expression Integer,F:Expression Float,
+ CF:Expression Complex Float,switch:Switch)
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ xType : FT := construct(real,[N],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ declare!(FVEC,xType,syms)$SYMTAB
+ declare!(LDFJAC,fortranInteger(),syms)$SYMTAB
+ jType : FT := construct(real,[LDFJAC,N],false)$FT
+ declare!(FJAC,jType,syms)$SYMTAB
+ declare!(IFLAG,fortranInteger(),syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,[N,X,FVEC,FJAC,LDFJAC,IFLAG],syms)
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ makeXList(n:Integer):List(Symbol) ==
+ x:Symbol := X::Symbol
+ [subscript(x,[j::OutputForm])$Symbol for j in 1..n]
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign1(s:Symbol,j:MAT FEXPR):FC ==
+ j' : MAT EXPR MFLOAT := map(fexpr2expr,j)$MF2
+ assign(s,j')$FC
+
+ localAssign2(s:Symbol,j:VEC FEXPR):FC ==
+ j' : VEC EXPR MFLOAT := map(fexpr2expr,j)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,j')$FC
+
+ coerce(u:VEC FEXPR):$ ==
+ n:Integer := maxIndex(u)
+ p:List(Symbol) := makeXList(n)
+ jac: MAT FEXPR := jacobian(u,p)$MultiVariableCalculusFunctions(_
+ Symbol,FEXPR,VEC FEXPR,List(Symbol))
+ assf:FC := localAssign2(FVEC,u)
+ assj:FC := localAssign1(FJAC,jac)
+ iflag:SWU := [IFLAG@Symbol::EXPR(INT)]$SWU
+ sw1:Switch := EQ(iflag,[1::EXPR(INT)]$SWU)
+ sw2:Switch := EQ(iflag,[2::EXPR(INT)]$SWU)
+ cond(sw1,assf,cond(sw2,assj)$FC)$FC::$
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP4 Asp4}
+<<domain ASP4 Asp4>>=
+)abbrev domain ASP4 Asp4
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp4} produces Fortran for Type 4 ASPs, which take an expression
+++in X(1) .. X(NDIM) and produce a real function of the form:
+++\begin{verbatim}
+++ DOUBLE PRECISION FUNCTION FUNCTN(NDIM,X)
+++ DOUBLE PRECISION X(NDIM)
+++ INTEGER NDIM
+++ FUNCTN=(4.0D0*X(1)*X(3)**2*DEXP(2.0D0*X(1)*X(3)))/(X(4)**2+(2.0D0*
+++ &X(2)+2.0D0)*X(4)+X(2)**2+2.0D0*X(2)+1.0D0)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp4(name): Exports == Implementation where
+ name : Symbol
+
+ FEXPR ==> FortranExpression([],['X],MachineFloat)
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FSTU ==> Union(fst:FST,void:"void")
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+
+ Exports ==> FortranFunctionCategory with
+ coerce : FEXPR -> $
+ ++coerce(f) takes an object from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns it into an ASP.
+
+ Implementation ==> add
+
+ real : FSTU := ["real"::FST]$FSTU
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(NDIM,fortranInteger(),syms)$SYMTAB
+ xType : FT := construct(real,[NDIM],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ Rep := FortranProgram(name,real,[NDIM,X],syms)
+
+ retract(u:FRAC POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ foo::FEXPR::$
+
+ retract(u:FRAC POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ foo::FEXPR::$
+
+ retract(u:EXPR FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ foo::FEXPR::$
+
+ retract(u:EXPR INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ foo::FEXPR::$
+
+ retract(u:POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ foo::FEXPR::$
+
+ retract(u:POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ foo::FEXPR::$
+
+ coerce(u:FEXPR):$ ==
+ coerce((u::Expression(MachineFloat))$FEXPR)$Rep
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP41 Asp41}
+<<domain ASP41 Asp41>>=
+)abbrev domain ASP41 Asp41
+++ Author: Mike Dewar, Godfrey Nolan
+++ Date Created:
+++ Date Last Updated: 29 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranFunctionCategory, FortranProgramCategory.
+++ Description:
+++\spadtype{Asp41} produces Fortran for Type 41 ASPs, needed for NAG
+++routines \axiomOpFrom{d02raf}{d02Package} and \axiomOpFrom{d02saf}{d02Package}
+++in particular. These ASPs are in fact
+++three Fortran routines which return a vector of functions, and their
+++derivatives wrt Y(i) and also a continuation parameter EPS, for example:
+++\begin{verbatim}
+++ SUBROUTINE FCN(X,EPS,Y,F,N)
+++ DOUBLE PRECISION EPS,F(N),X,Y(N)
+++ INTEGER N
+++ F(1)=Y(2)
+++ F(2)=Y(3)
+++ F(3)=(-1.0D0*Y(1)*Y(3))+2.0D0*EPS*Y(2)**2+(-2.0D0*EPS)
+++ RETURN
+++ END
+++ SUBROUTINE JACOBF(X,EPS,Y,F,N)
+++ DOUBLE PRECISION EPS,F(N,N),X,Y(N)
+++ INTEGER N
+++ F(1,1)=0.0D0
+++ F(1,2)=1.0D0
+++ F(1,3)=0.0D0
+++ F(2,1)=0.0D0
+++ F(2,2)=0.0D0
+++ F(2,3)=1.0D0
+++ F(3,1)=-1.0D0*Y(3)
+++ F(3,2)=4.0D0*EPS*Y(2)
+++ F(3,3)=-1.0D0*Y(1)
+++ RETURN
+++ END
+++ SUBROUTINE JACEPS(X,EPS,Y,F,N)
+++ DOUBLE PRECISION EPS,F(N),X,Y(N)
+++ INTEGER N
+++ F(1)=0.0D0
+++ F(2)=0.0D0
+++ F(3)=2.0D0*Y(2)**2-2.0D0
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp41(nameOne,nameTwo,nameThree): Exports == Implementation where
+ nameOne : Symbol
+ nameTwo : Symbol
+ nameThree : Symbol
+
+ D ==> differentiate
+ FST ==> FortranScalarType
+ UFST ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['X,'EPS],['Y],MFLOAT)
+ S ==> Symbol
+ MF2 ==> MatrixCategoryFunctions2(FEXPR,VEC FEXPR,VEC FEXPR,Matrix FEXPR,
+ EXPR MFLOAT,VEC EXPR MFLOAT,VEC EXPR MFLOAT,Matrix EXPR MFLOAT)
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+ real : UFST := ["real"::FST]$UFST
+
+ symOne : SYMTAB := empty()$SYMTAB
+ declare!(N,fortranInteger(),symOne)$SYMTAB
+ declare!(X,fortranReal(),symOne)$SYMTAB
+ declare!(EPS,fortranReal(),symOne)$SYMTAB
+ yType : FT := construct(real,[N],false)$FT
+ declare!(Y,yType,symOne)$SYMTAB
+ declare!(F,yType,symOne)$SYMTAB
+
+ symTwo : SYMTAB := empty()$SYMTAB
+ declare!(N,fortranInteger(),symTwo)$SYMTAB
+ declare!(X,fortranReal(),symTwo)$SYMTAB
+ declare!(EPS,fortranReal(),symTwo)$SYMTAB
+ declare!(Y,yType,symTwo)$SYMTAB
+ fType : FT := construct(real,[N,N],false)$FT
+ declare!(F,fType,symTwo)$SYMTAB
+
+ symThree : SYMTAB := empty()$SYMTAB
+ declare!(N,fortranInteger(),symThree)$SYMTAB
+ declare!(X,fortranReal(),symThree)$SYMTAB
+ declare!(EPS,fortranReal(),symThree)$SYMTAB
+ declare!(Y,yType,symThree)$SYMTAB
+ declare!(F,yType,symThree)$SYMTAB
+
+ R1:=FortranProgram(nameOne,["void"]$UFST,[X,EPS,Y,F,N],symOne)
+ R2:=FortranProgram(nameTwo,["void"]$UFST,[X,EPS,Y,F,N],symTwo)
+ R3:=FortranProgram(nameThree,["void"]$UFST,[X,EPS,Y,F,N],symThree)
+ Rep := Record(f:R1,fJacob:R2,eJacob:R3)
+ Fsym:Symbol:=coerce "F"
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign1(s:S,j:Matrix FEXPR):FC ==
+ j' : Matrix EXPR MFLOAT := map(fexpr2expr,j)$MF2
+ assign(s,j')$FC
+
+ localAssign2(s:S,j:VEC FEXPR):FC ==
+ j' : VEC EXPR MFLOAT := map(fexpr2expr,j)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,j')$FC
+
+ makeCodeOne(u:VEC FEXPR):FortranCode ==
+ -- simple assign
+ localAssign2(Fsym,u)
+
+ makeCodeThree(u:VEC FEXPR):FortranCode ==
+ -- compute jacobian wrt to eps
+ jacEps:VEC FEXPR := [D(v,EPS) for v in entries(u)]$VEC(FEXPR)
+ makeCodeOne(jacEps)
+
+ makeYList(n:Integer):List(Symbol) ==
+ j:Integer
+ y:Symbol := Y::Symbol
+ p:List(Symbol) := []
+ [subscript(y,[j::OutputForm])$Symbol for j in 1..n]
+
+ makeCodeTwo(u:VEC FEXPR):FortranCode ==
+ -- compute jacobian wrt to f
+ n:Integer := maxIndex(u)$VEC(FEXPR)
+ p:List(Symbol) := makeYList(n)
+ jac:Matrix(FEXPR) := _
+ jacobian(u,p)$MultiVariableCalculusFunctions(S,FEXPR,VEC FEXPR,List(S))
+ localAssign1(Fsym,jac)
+
+ coerce(u:VEC FEXPR):$ ==
+ aF:FortranCode := makeCodeOne(u)
+ bF:FortranCode := makeCodeTwo(u)
+ cF:FortranCode := makeCodeThree(u)
+ -- add returns() to complete subroutines
+ aLF:List(FortranCode) := [aF,returns()$FortranCode]$List(FortranCode)
+ bLF:List(FortranCode) := [bF,returns()$FortranCode]$List(FortranCode)
+ cLF:List(FortranCode) := [cF,returns()$FortranCode]$List(FortranCode)
+ [coerce(aLF)$R1,coerce(bLF)$R2,coerce(cLF)$R3]
+
+ coerce(u:$):OutputForm ==
+ bracket commaSeparate
+ [nameOne::OutputForm,nameTwo::OutputForm,nameThree::OutputForm]
+
+ outputAsFortran(u:$):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran elt(u,f)$Rep
+ outputAsFortran elt(u,fJacob)$Rep
+ outputAsFortran elt(u,eJacob)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP42 Asp42}
+<<domain ASP42 Asp42>>=
+)abbrev domain ASP42 Asp42
+++ Author: Mike Dewar, Godfrey Nolan
+++ Date Created:
+++ Date Last Updated: 29 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranFunctionCategory, FortranProgramCategory.
+++ Description:
+++\spadtype{Asp42} produces Fortran for Type 42 ASPs, needed for NAG
+++routines \axiomOpFrom{d02raf}{d02Package} and \axiomOpFrom{d02saf}{d02Package}
+++in particular. These ASPs are in fact
+++three Fortran routines which return a vector of functions, and their
+++derivatives wrt Y(i) and also a continuation parameter EPS, for example:
+++\begin{verbatim}
+++ SUBROUTINE G(EPS,YA,YB,BC,N)
+++ DOUBLE PRECISION EPS,YA(N),YB(N),BC(N)
+++ INTEGER N
+++ BC(1)=YA(1)
+++ BC(2)=YA(2)
+++ BC(3)=YB(2)-1.0D0
+++ RETURN
+++ END
+++ SUBROUTINE JACOBG(EPS,YA,YB,AJ,BJ,N)
+++ DOUBLE PRECISION EPS,YA(N),AJ(N,N),BJ(N,N),YB(N)
+++ INTEGER N
+++ AJ(1,1)=1.0D0
+++ AJ(1,2)=0.0D0
+++ AJ(1,3)=0.0D0
+++ AJ(2,1)=0.0D0
+++ AJ(2,2)=1.0D0
+++ AJ(2,3)=0.0D0
+++ AJ(3,1)=0.0D0
+++ AJ(3,2)=0.0D0
+++ AJ(3,3)=0.0D0
+++ BJ(1,1)=0.0D0
+++ BJ(1,2)=0.0D0
+++ BJ(1,3)=0.0D0
+++ BJ(2,1)=0.0D0
+++ BJ(2,2)=0.0D0
+++ BJ(2,3)=0.0D0
+++ BJ(3,1)=0.0D0
+++ BJ(3,2)=1.0D0
+++ BJ(3,3)=0.0D0
+++ RETURN
+++ END
+++ SUBROUTINE JACGEP(EPS,YA,YB,BCEP,N)
+++ DOUBLE PRECISION EPS,YA(N),YB(N),BCEP(N)
+++ INTEGER N
+++ BCEP(1)=0.0D0
+++ BCEP(2)=0.0D0
+++ BCEP(3)=0.0D0
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp42(nameOne,nameTwo,nameThree): Exports == Implementation where
+ nameOne : Symbol
+ nameTwo : Symbol
+ nameThree : Symbol
+
+ D ==> differentiate
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ FP ==> FortranProgram
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ UFST ==> Union(fst:FST,void:"void")
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['EPS],['YA,'YB],MFLOAT)
+ S ==> Symbol
+ MF2 ==> MatrixCategoryFunctions2(FEXPR,VEC FEXPR,VEC FEXPR,Matrix FEXPR,
+ EXPR MFLOAT,VEC EXPR MFLOAT,VEC EXPR MFLOAT,Matrix EXPR MFLOAT)
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+ real : UFST := ["real"::FST]$UFST
+
+ symOne : SYMTAB := empty()$SYMTAB
+ declare!(EPS,fortranReal(),symOne)$SYMTAB
+ declare!(N,fortranInteger(),symOne)$SYMTAB
+ yType : FT := construct(real,[N],false)$FT
+ declare!(YA,yType,symOne)$SYMTAB
+ declare!(YB,yType,symOne)$SYMTAB
+ declare!(BC,yType,symOne)$SYMTAB
+
+ symTwo : SYMTAB := empty()$SYMTAB
+ declare!(EPS,fortranReal(),symTwo)$SYMTAB
+ declare!(N,fortranInteger(),symTwo)$SYMTAB
+ declare!(YA,yType,symTwo)$SYMTAB
+ declare!(YB,yType,symTwo)$SYMTAB
+ ajType : FT := construct(real,[N,N],false)$FT
+ declare!(AJ,ajType,symTwo)$SYMTAB
+ declare!(BJ,ajType,symTwo)$SYMTAB
+
+ symThree : SYMTAB := empty()$SYMTAB
+ declare!(EPS,fortranReal(),symThree)$SYMTAB
+ declare!(N,fortranInteger(),symThree)$SYMTAB
+ declare!(YA,yType,symThree)$SYMTAB
+ declare!(YB,yType,symThree)$SYMTAB
+ declare!(BCEP,yType,symThree)$SYMTAB
+
+ rt := ["void"]$UFST
+ R1:=FortranProgram(nameOne,rt,[EPS,YA,YB,BC,N],symOne)
+ R2:=FortranProgram(nameTwo,rt,[EPS,YA,YB,AJ,BJ,N],symTwo)
+ R3:=FortranProgram(nameThree,rt,[EPS,YA,YB,BCEP,N],symThree)
+ Rep := Record(g:R1,gJacob:R2,geJacob:R3)
+ BCsym:Symbol:=coerce "BC"
+ AJsym:Symbol:=coerce "AJ"
+ BJsym:Symbol:=coerce "BJ"
+ BCEPsym:Symbol:=coerce "BCEP"
+
+ makeList(n:Integer,s:Symbol):List(Symbol) ==
+ j:Integer
+ p:List(Symbol) := []
+ for j in 1 .. n repeat p:= cons(subscript(s,[j::OutputForm])$Symbol,p)
+ reverse(p)
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign1(s:S,j:Matrix FEXPR):FC ==
+ j' : Matrix EXPR MFLOAT := map(fexpr2expr,j)$MF2
+ assign(s,j')$FC
+
+ localAssign2(s:S,j:VEC FEXPR):FC ==
+ j' : VEC EXPR MFLOAT := map(fexpr2expr,j)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,j')$FC
+
+ makeCodeOne(u:VEC FEXPR):FortranCode ==
+ -- simple assign
+ localAssign2(BCsym,u)
+
+ makeCodeTwo(u:VEC FEXPR):List(FortranCode) ==
+ -- compute jacobian wrt to ya
+ n:Integer := maxIndex(u)
+ p:List(Symbol) := makeList(n,YA::Symbol)
+ jacYA:Matrix(FEXPR) := _
+ jacobian(u,p)$MultiVariableCalculusFunctions(S,FEXPR,VEC FEXPR,List(S))
+ -- compute jacobian wrt to yb
+ p:List(Symbol) := makeList(n,YB::Symbol)
+ jacYB: Matrix(FEXPR) := _
+ jacobian(u,p)$MultiVariableCalculusFunctions(S,FEXPR,VEC FEXPR,List(S))
+ -- assign jacobians to AJ & BJ
+ [localAssign1(AJsym,jacYA),localAssign1(BJsym,jacYB),returns()$FC]$List(FC)
+
+ makeCodeThree(u:VEC FEXPR):FortranCode ==
+ -- compute jacobian wrt to eps
+ jacEps:VEC FEXPR := [D(v,EPS) for v in entries u]$VEC(FEXPR)
+ localAssign2(BCEPsym,jacEps)
+
+ coerce(u:VEC FEXPR):$ ==
+ aF:FortranCode := makeCodeOne(u)
+ bF:List(FortranCode) := makeCodeTwo(u)
+ cF:FortranCode := makeCodeThree(u)
+ -- add returns() to complete subroutines
+ aLF:List(FortranCode) := [aF,returns()$FC]$List(FortranCode)
+ cLF:List(FortranCode) := [cF,returns()$FC]$List(FortranCode)
+ [coerce(aLF)$R1,coerce(bF)$R2,coerce(cLF)$R3]
+
+ coerce(u:$) : OutputForm ==
+ bracket commaSeparate
+ [nameOne::OutputForm,nameTwo::OutputForm,nameThree::OutputForm]
+
+ outputAsFortran(u:$):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran elt(u,g)$Rep
+ outputAsFortran elt(u,gJacob)$Rep
+ outputAsFortran elt(u,geJacob)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP49 Asp49}
+<<domain ASP49 Asp49>>=
+)abbrev domain ASP49 Asp49
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 23 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp49} produces Fortran for Type 49 ASPs, needed for NAG routines
+++\axiomOpFrom{e04dgf}{e04Package}, \axiomOpFrom{e04ucf}{e04Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE OBJFUN(MODE,N,X,OBJF,OBJGRD,NSTATE,IUSER,USER)
+++ DOUBLE PRECISION X(N),OBJF,OBJGRD(N),USER(*)
+++ INTEGER N,IUSER(*),MODE,NSTATE
+++ OBJF=X(4)*X(9)+((-1.0D0*X(5))+X(3))*X(8)+((-1.0D0*X(3))+X(1))*X(7)
+++ &+(-1.0D0*X(2)*X(6))
+++ OBJGRD(1)=X(7)
+++ OBJGRD(2)=-1.0D0*X(6)
+++ OBJGRD(3)=X(8)+(-1.0D0*X(7))
+++ OBJGRD(4)=X(9)
+++ OBJGRD(5)=-1.0D0*X(8)
+++ OBJGRD(6)=-1.0D0*X(2)
+++ OBJGRD(7)=(-1.0D0*X(3))+X(1)
+++ OBJGRD(8)=(-1.0D0*X(5))+X(3)
+++ OBJGRD(9)=X(4)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp49(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ UFST ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FC))
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression([],['X],MFLOAT)
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ S ==> Symbol
+
+ Exports ==> FortranFunctionCategory with
+ coerce : FEXPR -> $
+ ++coerce(f) takes an object from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns it into an ASP.
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ integer : UFST := ["integer"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(MODE,fortranInteger(),syms)$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ xType : FT := construct(real,[N::S],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ declare!(OBJF,fortranReal(),syms)$SYMTAB
+ declare!(OBJGRD,xType,syms)$SYMTAB
+ declare!(NSTATE,fortranInteger(),syms)$SYMTAB
+ iuType : FT := construct(integer,["*"::S],false)$FT
+ declare!(IUSER,iuType,syms)$SYMTAB
+ uType : FT := construct(real,["*"::S],false)$FT
+ declare!(USER,uType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,
+ [MODE,N,X,OBJF,OBJGRD,NSTATE,IUSER,USER],syms)
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign(s:S,j:VEC FEXPR):FC ==
+ j' : VEC EXPR MFLOAT := map(fexpr2expr,j)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,j')$FC
+
+ coerce(u:FEXPR):$ ==
+ vars:List(S) := variables(u)
+ grd:VEC FEXPR := gradient(u,vars)$MultiVariableCalculusFunctions(_
+ S,FEXPR,VEC FEXPR,List(S))
+ code : List(FC) := [assign(OBJF@S,fexpr2expr u)$FC,_
+ localAssign(OBJGRD@S,grd),_
+ returns()$FC]
+ code::$
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:FRAC POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:FRAC POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:EXPR FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:EXPR INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+@
+\section{domain ASP50 Asp50}
+<<domain ASP50 Asp50>>=
+)abbrev domain ASP50 Asp50
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 23 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp50} produces Fortran for Type 50 ASPs, needed for NAG routine
+++\axiomOpFrom{e04fdf}{e04Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE LSFUN1(M,N,XC,FVECC)
+++ DOUBLE PRECISION FVECC(M),XC(N)
+++ INTEGER I,M,N
+++ FVECC(1)=((XC(1)-2.4D0)*XC(3)+(15.0D0*XC(1)-36.0D0)*XC(2)+1.0D0)/(
+++ &XC(3)+15.0D0*XC(2))
+++ FVECC(2)=((XC(1)-2.8D0)*XC(3)+(7.0D0*XC(1)-19.6D0)*XC(2)+1.0D0)/(X
+++ &C(3)+7.0D0*XC(2))
+++ FVECC(3)=((XC(1)-3.2D0)*XC(3)+(4.333333333333333D0*XC(1)-13.866666
+++ &66666667D0)*XC(2)+1.0D0)/(XC(3)+4.333333333333333D0*XC(2))
+++ FVECC(4)=((XC(1)-3.5D0)*XC(3)+(3.0D0*XC(1)-10.5D0)*XC(2)+1.0D0)/(X
+++ &C(3)+3.0D0*XC(2))
+++ FVECC(5)=((XC(1)-3.9D0)*XC(3)+(2.2D0*XC(1)-8.579999999999998D0)*XC
+++ &(2)+1.0D0)/(XC(3)+2.2D0*XC(2))
+++ FVECC(6)=((XC(1)-4.199999999999999D0)*XC(3)+(1.666666666666667D0*X
+++ &C(1)-7.0D0)*XC(2)+1.0D0)/(XC(3)+1.666666666666667D0*XC(2))
+++ FVECC(7)=((XC(1)-4.5D0)*XC(3)+(1.285714285714286D0*XC(1)-5.7857142
+++ &85714286D0)*XC(2)+1.0D0)/(XC(3)+1.285714285714286D0*XC(2))
+++ FVECC(8)=((XC(1)-4.899999999999999D0)*XC(3)+(XC(1)-4.8999999999999
+++ &99D0)*XC(2)+1.0D0)/(XC(3)+XC(2))
+++ FVECC(9)=((XC(1)-4.699999999999999D0)*XC(3)+(XC(1)-4.6999999999999
+++ &99D0)*XC(2)+1.285714285714286D0)/(XC(3)+XC(2))
+++ FVECC(10)=((XC(1)-6.8D0)*XC(3)+(XC(1)-6.8D0)*XC(2)+1.6666666666666
+++ &67D0)/(XC(3)+XC(2))
+++ FVECC(11)=((XC(1)-8.299999999999999D0)*XC(3)+(XC(1)-8.299999999999
+++ &999D0)*XC(2)+2.2D0)/(XC(3)+XC(2))
+++ FVECC(12)=((XC(1)-10.6D0)*XC(3)+(XC(1)-10.6D0)*XC(2)+3.0D0)/(XC(3)
+++ &+XC(2))
+++ FVECC(13)=((XC(1)-1.34D0)*XC(3)+(XC(1)-1.34D0)*XC(2)+4.33333333333
+++ &3333D0)/(XC(3)+XC(2))
+++ FVECC(14)=((XC(1)-2.1D0)*XC(3)+(XC(1)-2.1D0)*XC(2)+7.0D0)/(XC(3)+X
+++ &C(2))
+++ FVECC(15)=((XC(1)-4.39D0)*XC(3)+(XC(1)-4.39D0)*XC(2)+15.0D0)/(XC(3
+++ &)+XC(2))
+++ END
+++\end{verbatim}
+
+Asp50(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ UFST ==> Union(fst:FST,void:"void")
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ FEXPR ==> FortranExpression([],['XC],MFLOAT)
+ MFLOAT ==> MachineFloat
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(M,fortranInteger(),syms)$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ xcType : FT := construct(real,[N],false)$FT
+ declare!(XC,xcType,syms)$SYMTAB
+ fveccType : FT := construct(real,[M],false)$FT
+ declare!(FVECC,fveccType,syms)$SYMTAB
+ declare!(I,fortranInteger(),syms)$SYMTAB
+ tType : FT := construct(real,[M,N],false)$FT
+-- declare!(TC,tType,syms)$SYMTAB
+-- declare!(Y,fveccType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST, [M,N,XC,FVECC],syms)
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ coerce(u:VEC FEXPR):$ ==
+ u' : VEC EXPR MFLOAT := map(fexpr2expr,u)$VF2(FEXPR,EXPR MFLOAT)
+ assign(FVECC,u')$FortranCode::$
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP55 Asp55}
+<<domain ASP55 Asp55>>=
+)abbrev domain ASP55 Asp55
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: June 1993
+++ Date Last Updated: 23 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp55} produces Fortran for Type 55 ASPs, needed for NAG routines
+++\axiomOpFrom{e04dgf}{e04Package} and \axiomOpFrom{e04ucf}{e04Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE CONFUN(MODE,NCNLN,N,NROWJ,NEEDC,X,C,CJAC,NSTATE,IUSER
+++ &,USER)
+++ DOUBLE PRECISION C(NCNLN),X(N),CJAC(NROWJ,N),USER(*)
+++ INTEGER N,IUSER(*),NEEDC(NCNLN),NROWJ,MODE,NCNLN,NSTATE
+++ IF(NEEDC(1).GT.0)THEN
+++ C(1)=X(6)**2+X(1)**2
+++ CJAC(1,1)=2.0D0*X(1)
+++ CJAC(1,2)=0.0D0
+++ CJAC(1,3)=0.0D0
+++ CJAC(1,4)=0.0D0
+++ CJAC(1,5)=0.0D0
+++ CJAC(1,6)=2.0D0*X(6)
+++ ENDIF
+++ IF(NEEDC(2).GT.0)THEN
+++ C(2)=X(2)**2+(-2.0D0*X(1)*X(2))+X(1)**2
+++ CJAC(2,1)=(-2.0D0*X(2))+2.0D0*X(1)
+++ CJAC(2,2)=2.0D0*X(2)+(-2.0D0*X(1))
+++ CJAC(2,3)=0.0D0
+++ CJAC(2,4)=0.0D0
+++ CJAC(2,5)=0.0D0
+++ CJAC(2,6)=0.0D0
+++ ENDIF
+++ IF(NEEDC(3).GT.0)THEN
+++ C(3)=X(3)**2+(-2.0D0*X(1)*X(3))+X(2)**2+X(1)**2
+++ CJAC(3,1)=(-2.0D0*X(3))+2.0D0*X(1)
+++ CJAC(3,2)=2.0D0*X(2)
+++ CJAC(3,3)=2.0D0*X(3)+(-2.0D0*X(1))
+++ CJAC(3,4)=0.0D0
+++ CJAC(3,5)=0.0D0
+++ CJAC(3,6)=0.0D0
+++ ENDIF
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp55(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ FSTU ==> Union(fst:FST,void:"void")
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ S ==> Symbol
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ MAT ==> Matrix
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression([],['X],MFLOAT)
+ MF2 ==> MatrixCategoryFunctions2(FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR,
+ EXPR MFLOAT,VEC EXPR MFLOAT,VEC EXPR MFLOAT,MAT EXPR MFLOAT)
+ SWU ==> Union(I:Expression Integer,F:Expression Float,
+ CF:Expression Complex Float,switch:Switch)
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : FSTU := ["real"::FST]$FSTU
+ integer : FSTU := ["integer"::FST]$FSTU
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(MODE,fortranInteger(),syms)$SYMTAB
+ declare!(NCNLN,fortranInteger(),syms)$SYMTAB
+ declare!(N,fortranInteger(),syms)$SYMTAB
+ declare!(NROWJ,fortranInteger(),syms)$SYMTAB
+ needcType : FT := construct(integer,[NCNLN::Symbol],false)$FT
+ declare!(NEEDC,needcType,syms)$SYMTAB
+ xType : FT := construct(real,[N::Symbol],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ cType : FT := construct(real,[NCNLN::Symbol],false)$FT
+ declare!(C,cType,syms)$SYMTAB
+ cjacType : FT := construct(real,[NROWJ::Symbol,N::Symbol],false)$FT
+ declare!(CJAC,cjacType,syms)$SYMTAB
+ declare!(NSTATE,fortranInteger(),syms)$SYMTAB
+ iuType : FT := construct(integer,["*"::Symbol],false)$FT
+ declare!(IUSER,iuType,syms)$SYMTAB
+ uType : FT := construct(real,["*"::Symbol],false)$FT
+ declare!(USER,uType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,
+ [MODE,NCNLN,N,NROWJ,NEEDC,X,C,CJAC,NSTATE,IUSER,USER],syms)
+
+ -- Take a symbol, pull of the script and turn it into an integer!!
+ o2int(u:S):Integer ==
+ o : OutputForm := first elt(scripts(u)$S,sub)
+ o pretend Integer
+
+ localAssign(s:Symbol,dim:List POLY INT,u:FEXPR):FC ==
+ assign(s,dim,(u::EXPR MFLOAT)$FEXPR)$FC
+
+ makeCond(index:INT,fun:FEXPR,jac:VEC FEXPR):FC ==
+ needc : EXPR INT := (subscript(NEEDC,[index::OutputForm])$S)::EXPR(INT)
+ sw : Switch := GT([needc]$SWU,[0::EXPR(INT)]$SWU)$Switch
+ ass : List FC := [localAssign(CJAC,[index::POLY INT,i::POLY INT],jac.i)_
+ for i in 1..maxIndex(jac)]
+ cond(sw,block([localAssign(C,[index::POLY INT],fun),:ass])$FC)$FC
+
+ coerce(u:VEC FEXPR):$ ==
+ ncnln:Integer := maxIndex(u)
+ x:S := X::S
+ pu:List(S) := []
+ -- Work out which variables appear in the expressions
+ for e in entries(u) repeat
+ pu := setUnion(pu,variables(e)$FEXPR)
+ scriptList : List Integer := map(o2int,pu)$ListFunctions2(S,Integer)
+ -- This should be the maximum X_n which occurs (there may be others
+ -- which don't):
+ n:Integer := reduce(max,scriptList)$List(Integer)
+ p:List(S) := []
+ for j in 1..n repeat p:= cons(subscript(x,[j::OutputForm])$S,p)
+ p:= reverse(p)
+ jac:MAT FEXPR := _
+ jacobian(u,p)$MultiVariableCalculusFunctions(S,FEXPR,VEC FEXPR,List(S))
+ code : List FC := [makeCond(j,u.j,row(jac,j)) for j in 1..ncnln]
+ [:code,returns()$FC]::$
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP6 Asp6}
+<<domain ASP6 Asp6>>=
+)abbrev domain ASP6 Asp6
+++ Author: Mike Dewar and Godfrey Nolan and Grant Keady
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp6} produces Fortran for Type 6 ASPs, needed for NAG routines
+++\axiomOpFrom{c05nbf}{c05Package}, \axiomOpFrom{c05ncf}{c05Package}.
+++These represent vectors of functions of X(i) and look like:
+++\begin{verbatim}
+++ SUBROUTINE FCN(N,X,FVEC,IFLAG)
+++ DOUBLE PRECISION X(N),FVEC(N)
+++ INTEGER N,IFLAG
+++ FVEC(1)=(-2.0D0*X(2))+(-2.0D0*X(1)**2)+3.0D0*X(1)+1.0D0
+++ FVEC(2)=(-2.0D0*X(3))+(-2.0D0*X(2)**2)+3.0D0*X(2)+(-1.0D0*X(1))+1.
+++ &0D0
+++ FVEC(3)=(-2.0D0*X(4))+(-2.0D0*X(3)**2)+3.0D0*X(3)+(-1.0D0*X(2))+1.
+++ &0D0
+++ FVEC(4)=(-2.0D0*X(5))+(-2.0D0*X(4)**2)+3.0D0*X(4)+(-1.0D0*X(3))+1.
+++ &0D0
+++ FVEC(5)=(-2.0D0*X(6))+(-2.0D0*X(5)**2)+3.0D0*X(5)+(-1.0D0*X(4))+1.
+++ &0D0
+++ FVEC(6)=(-2.0D0*X(7))+(-2.0D0*X(6)**2)+3.0D0*X(6)+(-1.0D0*X(5))+1.
+++ &0D0
+++ FVEC(7)=(-2.0D0*X(8))+(-2.0D0*X(7)**2)+3.0D0*X(7)+(-1.0D0*X(6))+1.
+++ &0D0
+++ FVEC(8)=(-2.0D0*X(9))+(-2.0D0*X(8)**2)+3.0D0*X(8)+(-1.0D0*X(7))+1.
+++ &0D0
+++ FVEC(9)=(-2.0D0*X(9)**2)+3.0D0*X(9)+(-1.0D0*X(8))+1.0D0
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp6(name): Exports == Implementation where
+ name : Symbol
+
+ FEXPR ==> FortranExpression([],['X],MFLOAT)
+ MFLOAT ==> MachineFloat
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ UFST ==> Union(fst:FST,void:"void")
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+
+ Exports == FortranVectorFunctionCategory with
+ coerce: Vector FEXPR -> %
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation == add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(N,fortranInteger()$FT,syms)$SYMTAB
+ xType : FT := construct(real,[N],false)$FT
+ declare!(X,xType,syms)$SYMTAB
+ declare!(FVEC,xType,syms)$SYMTAB
+ declare!(IFLAG,fortranInteger()$FT,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$Union(fst:FST,void:"void"),
+ [N,X,FVEC,IFLAG],syms)
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VectorFunctions2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VectorFunctions2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VectorFunctions2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VectorFunctions2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VectorFunctions2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT ==
+ (u::EXPR MFLOAT)$FEXPR
+
+ coerce(u:VEC FEXPR):% ==
+ v : VEC EXPR MFLOAT
+ v := map(fexpr2expr,u)$VF2(FEXPR,EXPR MFLOAT)
+ ([assign(FVEC,v)$FortranCode,returns()$FortranCode]$List(FortranCode))::$
+
+ coerce(c:List FortranCode):% == coerce(c)$Rep
+
+ coerce(r:RSFC):% == coerce(r)$Rep
+
+ coerce(c:FortranCode):% == coerce(c)$Rep
+
+ coerce(u:%):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP7 Asp7}
+<<domain ASP7 Asp7>>=
+)abbrev domain ASP7 Asp7
+++ Author: Mike Dewar and Godfrey Nolan and Grant Keady
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp7} produces Fortran for Type 7 ASPs, needed for NAG routines
+++\axiomOpFrom{d02bbf}{d02Package}, \axiomOpFrom{d02gaf}{d02Package}.
+++These represent a vector of functions of the scalar X and
+++the array Z, and look like:
+++\begin{verbatim}
+++ SUBROUTINE FCN(X,Z,F)
+++ DOUBLE PRECISION F(*),X,Z(*)
+++ F(1)=DTAN(Z(3))
+++ F(2)=((-0.03199999999999999D0*DCOS(Z(3))*DTAN(Z(3)))+(-0.02D0*Z(2)
+++ &**2))/(Z(2)*DCOS(Z(3)))
+++ F(3)=-0.03199999999999999D0/(X*Z(2)**2)
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp7(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['X],['Y],MFLOAT)
+ UFST ==> Union(fst:FST,void:"void")
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : Vector FEXPR -> %
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal(),syms)$SYMTAB
+ yType : FT := construct(real,["*"::Symbol],false)$FT
+ declare!(Y,yType,syms)$SYMTAB
+ declare!(F,yType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,[X,Y,F],syms)
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT ==
+ (u::EXPR MFLOAT)$FEXPR
+
+ coerce(u:Vector FEXPR ):% ==
+ v : Vector EXPR MFLOAT
+ v:=map(fexpr2expr,u)$VF2(FEXPR,EXPR MFLOAT)
+ ([assign(F,v)$FortranCode,returns()$FortranCode]$List(FortranCode))::%
+
+ coerce(c:List FortranCode):% == coerce(c)$Rep
+
+ coerce(r:RSFC):% == coerce(r)$Rep
+
+ coerce(c:FortranCode):% == coerce(c)$Rep
+
+ coerce(u:%):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{domain ASP73 Asp73}
+<<domain ASP73 Asp73>>=
+)abbrev domain ASP73 Asp73
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 30 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp73} produces Fortran for Type 73 ASPs, needed for NAG routine
+++\axiomOpFrom{d03eef}{d03Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE PDEF(X,Y,ALPHA,BETA,GAMMA,DELTA,EPSOLN,PHI,PSI)
+++ DOUBLE PRECISION ALPHA,EPSOLN,PHI,X,Y,BETA,DELTA,GAMMA,PSI
+++ ALPHA=DSIN(X)
+++ BETA=Y
+++ GAMMA=X*Y
+++ DELTA=DCOS(X)*DSIN(Y)
+++ EPSOLN=Y+X
+++ PHI=X
+++ PSI=Y
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp73(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+ FEXPR ==> FortranExpression(['X,'Y],[],MachineFloat)
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal(),syms) $SYMTAB
+ declare!(Y,fortranReal(),syms) $SYMTAB
+ declare!(ALPHA,fortranReal(),syms)$SYMTAB
+ declare!(BETA,fortranReal(),syms) $SYMTAB
+ declare!(GAMMA,fortranReal(),syms) $SYMTAB
+ declare!(DELTA,fortranReal(),syms) $SYMTAB
+ declare!(EPSOLN,fortranReal(),syms) $SYMTAB
+ declare!(PHI,fortranReal(),syms) $SYMTAB
+ declare!(PSI,fortranReal(),syms) $SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,
+ [X,Y,ALPHA,BETA,GAMMA,DELTA,EPSOLN,PHI,PSI],syms)
+
+ -- To help the poor compiler!
+ localAssign(u:Symbol,v:FEXPR):FortranCode ==
+ assign(u,(v::EXPR MachineFloat)$FEXPR)$FortranCode
+
+ coerce(u:VEC FEXPR):$ ==
+ maxIndex(u) ^= 7 => error "Vector is not of dimension 7"
+ [localAssign(ALPHA@Symbol,elt(u,1)),_
+ localAssign(BETA@Symbol,elt(u,2)),_
+ localAssign(GAMMA@Symbol,elt(u,3)),_
+ localAssign(DELTA@Symbol,elt(u,4)),_
+ localAssign(EPSOLN@Symbol,elt(u,5)),_
+ localAssign(PHI@Symbol,elt(u,6)),_
+ localAssign(PSI@Symbol,elt(u,7)),_
+ returns()$FortranCode]$List(FortranCode)::$
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP74 Asp74}
+<<domain ASP74 Asp74>>=
+)abbrev domain ASP74 Asp74
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Oct 1993
+++ Date Last Updated: 30 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranScalarFunctionCategory, FortranProgramCategory.
+++ Description:
+++\spadtype{Asp74} produces Fortran for Type 74 ASPs, needed for NAG routine
+++\axiomOpFrom{d03eef}{d03Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE BNDY(X,Y,A,B,C,IBND)
+++ DOUBLE PRECISION A,B,C,X,Y
+++ INTEGER IBND
+++ IF(IBND.EQ.0)THEN
+++ A=0.0D0
+++ B=1.0D0
+++ C=-1.0D0*DSIN(X)
+++ ELSEIF(IBND.EQ.1)THEN
+++ A=1.0D0
+++ B=0.0D0
+++ C=DSIN(X)*DSIN(Y)
+++ ELSEIF(IBND.EQ.2)THEN
+++ A=1.0D0
+++ B=0.0D0
+++ C=DSIN(X)*DSIN(Y)
+++ ELSEIF(IBND.EQ.3)THEN
+++ A=0.0D0
+++ B=1.0D0
+++ C=-1.0D0*DSIN(Y)
+++ ENDIF
+++ END
+++\end{verbatim}
+
+Asp74(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ FC ==> FortranCode
+ PI ==> PositiveInteger
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['X,'Y],[],MFLOAT)
+ U ==> Union(I: Expression Integer,F: Expression Float,_
+ CF: Expression Complex Float,switch:Switch)
+ VEC ==> Vector
+ MAT ==> Matrix
+ M2 ==> MatrixCategoryFunctions2
+ MF2a ==> M2(FRAC POLY INT,VEC FRAC POLY INT,VEC FRAC POLY INT,
+ MAT FRAC POLY INT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2b ==> M2(FRAC POLY FLOAT,VEC FRAC POLY FLOAT,VEC FRAC POLY FLOAT,
+ MAT FRAC POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2c ==> M2(POLY INT,VEC POLY INT,VEC POLY INT,MAT POLY INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2d ==> M2(POLY FLOAT,VEC POLY FLOAT,VEC POLY FLOAT,
+ MAT POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2e ==> M2(EXPR INT,VEC EXPR INT,VEC EXPR INT,MAT EXPR INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2f ==> M2(EXPR FLOAT,VEC EXPR FLOAT,VEC EXPR FLOAT,
+ MAT EXPR FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+
+ Exports ==> FortranMatrixFunctionCategory with
+ coerce : MAT FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal(),syms)$SYMTAB
+ declare!(Y,fortranReal(),syms)$SYMTAB
+ declare!(A,fortranReal(),syms)$SYMTAB
+ declare!(B,fortranReal(),syms)$SYMTAB
+ declare!(C,fortranReal(),syms)$SYMTAB
+ declare!(IBND,fortranInteger(),syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,[X,Y,A,B,C,IBND],syms)
+
+ -- To help the poor compiler!
+ localAssign(u:Symbol,v:FEXPR):FC == assign(u,(v::EXPR MFLOAT)$FEXPR)$FC
+
+ coerce(u:MAT FEXPR):$ ==
+ (nrows(u) ^= 4 or ncols(u) ^= 3) => error "Not a 4X3 matrix"
+ flag:U := [IBND@Symbol::EXPR INT]$U
+ pt0:U := [0::EXPR INT]$U
+ pt1:U := [1::EXPR INT]$U
+ pt2:U := [2::EXPR INT]$U
+ pt3:U := [3::EXPR INT]$U
+ sw1: Switch := EQ(flag,pt0)$Switch
+ sw2: Switch := EQ(flag,pt1)$Switch
+ sw3: Switch := EQ(flag,pt2)$Switch
+ sw4: Switch := EQ(flag,pt3)$Switch
+ a11 : FC := localAssign(A,u(1,1))
+ a12 : FC := localAssign(B,u(1,2))
+ a13 : FC := localAssign(C,u(1,3))
+ a21 : FC := localAssign(A,u(2,1))
+ a22 : FC := localAssign(B,u(2,2))
+ a23 : FC := localAssign(C,u(2,3))
+ a31 : FC := localAssign(A,u(3,1))
+ a32 : FC := localAssign(B,u(3,2))
+ a33 : FC := localAssign(C,u(3,3))
+ a41 : FC := localAssign(A,u(4,1))
+ a42 : FC := localAssign(B,u(4,2))
+ a43 : FC := localAssign(C,u(4,3))
+ c : FC := cond(sw1,block([a11,a12,a13])$FC,
+ cond(sw2,block([a21,a22,a23])$FC,
+ cond(sw3,block([a31,a32,a33])$FC,
+ cond(sw4,block([a41,a42,a43])$FC)$FC)$FC)$FC)$FC
+ c::$
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:MAT FRAC POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2a
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2a
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT FRAC POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2b
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2b
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2e
+ v::$
+
+ retractIfCan(u:MAT EXPR INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2e
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2f
+ v::$
+
+ retractIfCan(u:MAT EXPR FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2f
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2c
+ v::$
+
+ retractIfCan(u:MAT POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2c
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2d
+ v::$
+
+ retractIfCan(u:MAT POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2d
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+@
+\section{domain ASP77 Asp77}
+<<domain ASP77 Asp77>>=
+)abbrev domain ASP77 Asp77
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 30 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranMatrixFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp77} produces Fortran for Type 77 ASPs, needed for NAG routine
+++\axiomOpFrom{d02gbf}{d02Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE FCNF(X,F)
+++ DOUBLE PRECISION X
+++ DOUBLE PRECISION F(2,2)
+++ F(1,1)=0.0D0
+++ F(1,2)=1.0D0
+++ F(2,1)=0.0D0
+++ F(2,2)=-10.0D0
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp77(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FC))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['X],[],MFLOAT)
+ VEC ==> Vector
+ MAT ==> Matrix
+ M2 ==> MatrixCategoryFunctions2
+ MF2 ==> M2(FEXPR,VEC FEXPR,VEC FEXPR,Matrix FEXPR,EXPR MFLOAT,
+ VEC EXPR MFLOAT,VEC EXPR MFLOAT,Matrix EXPR MFLOAT)
+ MF2a ==> M2(FRAC POLY INT,VEC FRAC POLY INT,VEC FRAC POLY INT,
+ MAT FRAC POLY INT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2b ==> M2(FRAC POLY FLOAT,VEC FRAC POLY FLOAT,VEC FRAC POLY FLOAT,
+ MAT FRAC POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2c ==> M2(POLY INT,VEC POLY INT,VEC POLY INT,MAT POLY INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2d ==> M2(POLY FLOAT,VEC POLY FLOAT,VEC POLY FLOAT,
+ MAT POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2e ==> M2(EXPR INT,VEC EXPR INT,VEC EXPR INT,MAT EXPR INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2f ==> M2(EXPR FLOAT,VEC EXPR FLOAT,VEC EXPR FLOAT,
+ MAT EXPR FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+
+
+ Exports ==> FortranMatrixFunctionCategory with
+ coerce : MAT FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : FSTU := ["real"::FST]$FSTU
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal(),syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,[X,F],syms)
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ localAssign(s:Symbol,j:MAT FEXPR):FortranCode ==
+ j' : MAT EXPR MFLOAT := map(fexpr2expr,j)$MF2
+ assign(s,j')$FortranCode
+
+ coerce(u:MAT FEXPR):$ ==
+ dimension := nrows(u)::POLY(INT)
+ locals : SYMTAB := empty()
+ declare!(F,[real,[dimension,dimension]$List(POLY(INT)),false]$FT,locals)
+ code : List FC := [localAssign(F,u),returns()$FC]
+ ([locals,code]$RSFC)::$
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:MAT FRAC POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2a
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2a
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT FRAC POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2b
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2b
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2e
+ v::$
+
+ retractIfCan(u:MAT EXPR INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2e
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2f
+ v::$
+
+ retractIfCan(u:MAT EXPR FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2f
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2c
+ v::$
+
+ retractIfCan(u:MAT POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2c
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2d
+ v::$
+
+ retractIfCan(u:MAT POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2d
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+@
+\section{domain ASP78 Asp78}
+<<domain ASP78 Asp78>>=
+)abbrev domain ASP78 Asp78
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 30 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp78} produces Fortran for Type 78 ASPs, needed for NAG routine
+++\axiomOpFrom{d02gbf}{d02Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE FCNG(X,G)
+++ DOUBLE PRECISION G(*),X
+++ G(1)=0.0D0
+++ G(2)=0.0D0
+++ END
+++\end{verbatim}
+
+Asp78(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FC))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ VEC ==> Vector
+ VF2 ==> VectorFunctions2
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['X],[],MFLOAT)
+
+ Exports ==> FortranVectorFunctionCategory with
+ coerce : VEC FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : FSTU := ["real"::FST]$FSTU
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal(),syms)$SYMTAB
+ gType : FT := construct(real,["*"::Symbol],false)$FT
+ declare!(G,gType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU,[X,G],syms)
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ coerce(u:VEC FEXPR):$ ==
+ u' : VEC EXPR MFLOAT := map(fexpr2expr,u)$VF2(FEXPR,EXPR MFLOAT)
+ (assign(G,u')$FC)::$
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ coerce(c:List FC):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FC):$ == coerce(c)$Rep
+
+ retract(u:VEC FRAC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC FRAC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(FRAC POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC EXPR FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(EXPR FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC EXPR FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(EXPR FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY INT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY INT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY INT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY INT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+ retract(u:VEC POLY FLOAT):$ ==
+ v : VEC FEXPR := map(retract,u)$VF2(POLY FLOAT,FEXPR)
+ v::$
+
+ retractIfCan(u:VEC POLY FLOAT):Union($,"failed") ==
+ v:Union(VEC FEXPR,"failed"):=map(retractIfCan,u)$VF2(POLY FLOAT,FEXPR)
+ v case "failed" => "failed"
+ (v::VEC FEXPR)::$
+
+@
+\section{domain ASP8 Asp8}
+<<domain ASP8 Asp8>>=
+)abbrev domain ASP8 Asp8
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: 11 February 1994
+++ Date Last Updated: 18 March 1994
+++ 31 May 1994 to use alternative interface. MCD
+++ 30 June 1994 to handle the end condition correctly. MCD
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp8} produces Fortran for Type 8 ASPs, needed for NAG routine
+++\axiomOpFrom{d02bbf}{d02Package}. This ASP prints intermediate values of the computed solution of
+++an ODE and might look like:
+++\begin{verbatim}
+++ SUBROUTINE OUTPUT(XSOL,Y,COUNT,M,N,RESULT,FORWRD)
+++ DOUBLE PRECISION Y(N),RESULT(M,N),XSOL
+++ INTEGER M,N,COUNT
+++ LOGICAL FORWRD
+++ DOUBLE PRECISION X02ALF,POINTS(8)
+++ EXTERNAL X02ALF
+++ INTEGER I
+++ POINTS(1)=1.0D0
+++ POINTS(2)=2.0D0
+++ POINTS(3)=3.0D0
+++ POINTS(4)=4.0D0
+++ POINTS(5)=5.0D0
+++ POINTS(6)=6.0D0
+++ POINTS(7)=7.0D0
+++ POINTS(8)=8.0D0
+++ COUNT=COUNT+1
+++ DO 25001 I=1,N
+++ RESULT(COUNT,I)=Y(I)
+++25001 CONTINUE
+++ IF(COUNT.EQ.M)THEN
+++ IF(FORWRD)THEN
+++ XSOL=X02ALF()
+++ ELSE
+++ XSOL=-X02ALF()
+++ ENDIF
+++ ELSE
+++ XSOL=POINTS(COUNT)
+++ ENDIF
+++ END
+++\end{verbatim}
+
+Asp8(name): Exports == Implementation where
+ name : Symbol
+
+ O ==> OutputForm
+ S ==> Symbol
+ FST ==> FortranScalarType
+ UFST ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ EX ==> Expression Integer
+ MFLOAT ==> MachineFloat
+ EXPR ==> Expression
+ PI ==> Polynomial Integer
+ EXU ==> Union(I: EXPR Integer,F: EXPR Float,CF: EXPR Complex Float,
+ switch: Switch)
+
+ Exports ==> FortranVectorCategory
+
+ Implementation ==> add
+
+ real : UFST := ["real"::FST]$UFST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!([COUNT,M,N],fortranInteger(),syms)$SYMTAB
+ declare!(XSOL,fortranReal(),syms)$SYMTAB
+ yType : FT := construct(real,[N],false)$FT
+ declare!(Y,yType,syms)$SYMTAB
+ declare!(FORWRD,fortranLogical(),syms)$SYMTAB
+ declare!(RESULT,construct(real,[M,N],false)$FT,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$UFST,[XSOL,Y,COUNT,M,N,RESULT,FORWRD],syms)
+
+ coerce(c:List FC):% == coerce(c)$Rep
+
+ coerce(r:RSFC):% == coerce(r)$Rep
+
+ coerce(c:FC):% == coerce(c)$Rep
+
+ coerce(u:%):O == coerce(u)$Rep
+
+ outputAsFortran(u:%):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+
+ f2ex(u:MFLOAT):EXPR MFLOAT == (u::EXPR MFLOAT)$EXPR(MFLOAT)
+
+ coerce(points:Vector MFLOAT):% ==
+ import PI
+ import EXPR Integer
+ -- Create some extra declarations
+ locals : SYMTAB := empty()$SYMTAB
+ nPol : PI := "N"::S::PI
+ iPol : PI := "I"::S::PI
+ countPol : PI := "COUNT"::S::PI
+ pointsDim : PI := max(#points,1)::PI
+ declare!(POINTS,[real,[pointsDim],false]$FT,locals)$SYMTAB
+ declare!(X02ALF,[real,[],true]$FT,locals)$SYMTAB
+ -- Now build up the code fragments
+ index : SegmentBinding PI := equation(I@S,1::PI..nPol)$SegmentBinding(PI)
+ ySym : EX := (subscript("Y"::S,[I::O])$S)::EX
+ loop := forLoop(index,assign(RESULT,[countPol,iPol],ySym)$FC)$FC
+ v:Vector EXPR MFLOAT
+ v := map(f2ex,points)$VectorFunctions2(MFLOAT,EXPR MFLOAT)
+ assign1 : FC := assign(POINTS,v)$FC
+ countExp: EX := COUNT@S::EX
+ newValue: EX := 1 + countExp
+ assign2 : FC := assign(COUNT,newValue)$FC
+ newSymbol : S := subscript(POINTS,[COUNT]@List(O))$S
+ assign3 : FC := assign(XSOL, newSymbol::EX )$FC
+ fphuge : EX := kernel(operator X02ALF,empty()$List(EX))
+ assign4 : FC := assign(XSOL, fphuge)$FC
+ assign5 : FC := assign(XSOL, -fphuge)$FC
+ innerCond : FC := cond("FORWRD"::Symbol::Switch,assign4,assign5)
+ mExp : EX := M@S::EX
+ endCase : FC := cond(EQ([countExp]$EXU,[mExp]$EXU)$Switch,innerCond,assign3)
+ code := [assign1, assign2, loop, endCase]$List(FC)
+ ([locals,code]$RSFC)::%
+
+@
+\section{domain ASP80 Asp80}
+<<domain ASP80 Asp80>>=
+)abbrev domain ASP80 Asp80
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: Oct 1993
+++ Date Last Updated: 30 March 1994
+++ 6 October 1994
+++ Related Constructors: FortranMatrixFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp80} produces Fortran for Type 80 ASPs, needed for NAG routine
+++\axiomOpFrom{d02kef}{d02Package}, for example:
+++\begin{verbatim}
+++ SUBROUTINE BDYVAL(XL,XR,ELAM,YL,YR)
+++ DOUBLE PRECISION ELAM,XL,YL(3),XR,YR(3)
+++ YL(1)=XL
+++ YL(2)=2.0D0
+++ YR(1)=1.0D0
+++ YR(2)=-1.0D0*DSQRT(XR+(-1.0D0*ELAM))
+++ RETURN
+++ END
+++\end{verbatim}
+
+Asp80(name): Exports == Implementation where
+ name : Symbol
+
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+ FT ==> FortranType
+ FC ==> FortranCode
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+ MFLOAT ==> MachineFloat
+ FEXPR ==> FortranExpression(['XL,'XR,'ELAM],[],MFLOAT)
+ VEC ==> Vector
+ MAT ==> Matrix
+ VF2 ==> VectorFunctions2
+ M2 ==> MatrixCategoryFunctions2
+ MF2a ==> M2(FRAC POLY INT,VEC FRAC POLY INT,VEC FRAC POLY INT,
+ MAT FRAC POLY INT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2b ==> M2(FRAC POLY FLOAT,VEC FRAC POLY FLOAT,VEC FRAC POLY FLOAT,
+ MAT FRAC POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2c ==> M2(POLY INT,VEC POLY INT,VEC POLY INT,MAT POLY INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2d ==> M2(POLY FLOAT,VEC POLY FLOAT,VEC POLY FLOAT,
+ MAT POLY FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2e ==> M2(EXPR INT,VEC EXPR INT,VEC EXPR INT,MAT EXPR INT,
+ FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+ MF2f ==> M2(EXPR FLOAT,VEC EXPR FLOAT,VEC EXPR FLOAT,
+ MAT EXPR FLOAT, FEXPR,VEC FEXPR,VEC FEXPR,MAT FEXPR)
+
+ Exports ==> FortranMatrixFunctionCategory with
+ coerce : MAT FEXPR -> $
+ ++coerce(f) takes objects from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns them into an ASP.
+
+ Implementation ==> add
+
+ real : FSTU := ["real"::FST]$FSTU
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(XL,fortranReal(),syms)$SYMTAB
+ declare!(XR,fortranReal(),syms)$SYMTAB
+ declare!(ELAM,fortranReal(),syms)$SYMTAB
+ yType : FT := construct(real,["3"::Symbol],false)$FT
+ declare!(YL,yType,syms)$SYMTAB
+ declare!(YR,yType,syms)$SYMTAB
+ Rep := FortranProgram(name,["void"]$FSTU, [XL,XR,ELAM,YL,YR],syms)
+
+ fexpr2expr(u:FEXPR):EXPR MFLOAT == coerce(u)$FEXPR
+
+ vecAssign(s:Symbol,u:VEC FEXPR):FC ==
+ u' : VEC EXPR MFLOAT := map(fexpr2expr,u)$VF2(FEXPR,EXPR MFLOAT)
+ assign(s,u')$FC
+
+ coerce(u:MAT FEXPR):$ ==
+ [vecAssign(YL,row(u,1)),vecAssign(YR,row(u,2)),returns()$FC]$List(FC)::$
+
+ coerce(c:List FortranCode):$ == coerce(c)$Rep
+
+ coerce(r:RSFC):$ == coerce(r)$Rep
+
+ coerce(c:FortranCode):$ == coerce(c)$Rep
+
+ coerce(u:$):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+ retract(u:MAT FRAC POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2a
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2a
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT FRAC POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2b
+ v::$
+
+ retractIfCan(u:MAT FRAC POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2b
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2e
+ v::$
+
+ retractIfCan(u:MAT EXPR INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2e
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT EXPR FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2f
+ v::$
+
+ retractIfCan(u:MAT EXPR FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2f
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY INT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2c
+ v::$
+
+ retractIfCan(u:MAT POLY INT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2c
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+ retract(u:MAT POLY FLOAT):$ ==
+ v : MAT FEXPR := map(retract,u)$MF2d
+ v::$
+
+ retractIfCan(u:MAT POLY FLOAT):Union($,"failed") ==
+ v:Union(MAT FEXPR,"failed"):=map(retractIfCan,u)$MF2d
+ v case "failed" => "failed"
+ (v::MAT FEXPR)::$
+
+@
+\section{domain ASP9 Asp9}
+<<domain ASP9 Asp9>>=
+)abbrev domain ASP9 Asp9
+++ Author: Mike Dewar, Grant Keady and Godfrey Nolan
+++ Date Created: Mar 1993
+++ Date Last Updated: 18 March 1994
+++ 12 July 1994 added COMMON blocks for d02cjf, d02ejf
+++ 6 October 1994
+++ Related Constructors: FortranVectorFunctionCategory, FortranProgramCategory
+++ Description:
+++\spadtype{Asp9} produces Fortran for Type 9 ASPs, needed for NAG routines
+++\axiomOpFrom{d02bhf}{d02Package}, \axiomOpFrom{d02cjf}{d02Package}, \axiomOpFrom{d02ejf}{d02Package}.
+++These ASPs represent a function of a scalar X and a vector Y, for example:
+++\begin{verbatim}
+++ DOUBLE PRECISION FUNCTION G(X,Y)
+++ DOUBLE PRECISION X,Y(*)
+++ G=X+Y(1)
+++ RETURN
+++ END
+++\end{verbatim}
+++If the user provides a constant value for G, then extra information is added
+++via COMMON blocks used by certain routines. This specifies that the value
+++returned by G in this case is to be ignored.
+
+Asp9(name): Exports == Implementation where
+ name : Symbol
+
+ FEXPR ==> FortranExpression(['X],['Y],MFLOAT)
+ MFLOAT ==> MachineFloat
+ FC ==> FortranCode
+ FST ==> FortranScalarType
+ FT ==> FortranType
+ SYMTAB ==> SymbolTable
+ RSFC ==> Record(localSymbols:SymbolTable,code:List(FortranCode))
+ UFST ==> Union(fst:FST,void:"void")
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ EXPR ==> Expression
+ INT ==> Integer
+ FLOAT ==> Float
+
+ Exports ==> FortranFunctionCategory with
+ coerce : FEXPR -> %
+ ++coerce(f) takes an object from the appropriate instantiation of
+ ++\spadtype{FortranExpression} and turns it into an ASP.
+
+ Implementation ==> add
+
+ real : FST := "real"::FST
+ syms : SYMTAB := empty()$SYMTAB
+ declare!(X,fortranReal()$FT,syms)$SYMTAB
+ yType : FT := construct([real]$UFST,["*"::Symbol],false)$FT
+ declare!(Y,yType,syms)$SYMTAB
+ Rep := FortranProgram(name,[real]$UFST,[X,Y],syms)
+
+ retract(u:FRAC POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:FRAC POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:FRAC POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:EXPR FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:EXPR INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:EXPR INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:POLY FLOAT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY FLOAT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ retract(u:POLY INT):$ == (retract(u)@FEXPR)::$
+ retractIfCan(u:POLY INT):Union($,"failed") ==
+ foo : Union(FEXPR,"failed")
+ foo := retractIfCan(u)$FEXPR
+ foo case "failed" => "failed"
+ (foo::FEXPR)::$
+
+ coerce(u:FEXPR):% ==
+ expr : Expression MachineFloat := (u::Expression(MachineFloat))$FEXPR
+ (retractIfCan(u)@Union(MFLOAT,"failed"))$FEXPR case "failed" =>
+ coerce(expr)$Rep
+ locals : SYMTAB := empty()
+ charType : FT := construct(["character"::FST]$UFST,[6::POLY(INT)],false)$FT
+ declare!([CHDUM1,CHDUM2,GOPT1,CHDUM,GOPT2],charType,locals)$SYMTAB
+ common1 := common(CD02EJ,[CHDUM1,CHDUM2,GOPT1] )$FC
+ common2 := common(AD02CJ,[CHDUM,GOPT2] )$FC
+ assign1 := assign(GOPT1,"NOGOPT")$FC
+ assign2 := assign(GOPT2,"NOGOPT")$FC
+ result := assign(name,expr)$FC
+ code : List FC := [common1,common2,assign1,assign2,result]
+ ([locals,code]$RSFC)::Rep
+
+ coerce(c:List FortranCode):% == coerce(c)$Rep
+
+ coerce(r:RSFC):% == coerce(r)$Rep
+
+ coerce(c:FortranCode):% == coerce(c)$Rep
+
+ coerce(u:%):OutputForm == coerce(u)$Rep
+
+ outputAsFortran(u):Void ==
+ p := checkPrecision()$NAGLinkSupportPackage
+ outputAsFortran(u)$Rep
+ p => restorePrecision()$NAGLinkSupportPackage
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ASP1 Asp1>>
+<<domain ASP10 Asp10>>
+<<domain ASP12 Asp12>>
+<<domain ASP19 Asp19>>
+<<domain ASP20 Asp20>>
+<<domain ASP24 Asp24>>
+<<domain ASP27 Asp27>>
+<<domain ASP28 Asp28>>
+<<domain ASP29 Asp29>>
+<<domain ASP30 Asp30>>
+<<domain ASP31 Asp31>>
+<<domain ASP33 Asp33>>
+<<domain ASP34 Asp34>>
+<<domain ASP35 Asp35>>
+<<domain ASP4 Asp4>>
+<<domain ASP41 Asp41>>
+<<domain ASP42 Asp42>>
+<<domain ASP49 Asp49>>
+<<domain ASP50 Asp50>>
+<<domain ASP55 Asp55>>
+<<domain ASP6 Asp6>>
+<<domain ASP7 Asp7>>
+<<domain ASP73 Asp73>>
+<<domain ASP74 Asp74>>
+<<domain ASP77 Asp77>>
+<<domain ASP78 Asp78>>
+<<domain ASP8 Asp8>>
+<<domain ASP80 Asp80>>
+<<domain ASP9 Asp9>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/attreg.spad.pamphlet b/src/algebra/attreg.spad.pamphlet
new file mode 100644
index 00000000..221d387a
--- /dev/null
+++ b/src/algebra/attreg.spad.pamphlet
@@ -0,0 +1,127 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra attreg.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ATTREG AttributeRegistry}
+<<category ATTREG AttributeRegistry>>=
+)abbrev category ATTREG AttributeRegistry
+
+++ This category exports the attributes in the AXIOM Library
+AttributeRegistry(): Category == with
+ finiteAggregate
+ ++ \spad{finiteAggregate} is true if it is an aggregate with a
+ ++ finite number of elements.
+ commutative("*")
+ ++ \spad{commutative("*")} is true if it has an operation
+ ++ \spad{"*": (D,D) -> D} which is commutative.
+ shallowlyMutable
+ ++ \spad{shallowlyMutable} is true if its values
+ ++ have immediate components that are updateable (mutable).
+ ++ Note: the properties of any component domain are irrevelant to the
+ ++ \spad{shallowlyMutable} proper.
+ unitsKnown
+ ++ \spad{unitsKnown} is true if a monoid (a multiplicative semigroup
+ ++ with a 1) has \spad{unitsKnown} means that
+ ++ the operation \spadfun{recip} can only return "failed"
+ ++ if its argument is not a unit.
+ leftUnitary
+ ++ \spad{leftUnitary} is true if \spad{1 * x = x} for all x.
+ rightUnitary
+ ++ \spad{rightUnitary} is true if \spad{x * 1 = x} for all x.
+ noZeroDivisors
+ ++ \spad{noZeroDivisors} is true if \spad{x * y \~~= 0} implies
+ ++ both x and y are non-zero.
+ canonicalUnitNormal
+ ++ \spad{canonicalUnitNormal} is true if we can choose a canonical
+ ++ representative for each class of associate elements, that is
+ ++ \spad{associates?(a,b)} returns true if and only if
+ ++ \spad{unitCanonical(a) = unitCanonical(b)}.
+ canonicalsClosed
+ ++ \spad{canonicalsClosed} is true if
+ ++ \spad{unitCanonical(a)*unitCanonical(b) = unitCanonical(a*b)}.
+ arbitraryPrecision
+ ++ \spad{arbitraryPrecision} means the user can set the
+ ++ precision for subsequent calculations.
+ partiallyOrderedSet
+ ++ \spad{partiallyOrderedSet} is true if
+ ++ a set with \spadop{<} which is transitive,
+ ++ but \spad{not(a < b or a = b)}
+ ++ does not necessarily imply \spad{b<a}.
+ central
+ ++ \spad{central} is true if, given an algebra over a ring R,
+ ++ the image of R is the center
+ ++ of the algebra, i.e. the set of members of the algebra which commute
+ ++ with all others is precisely the image of R in the algebra.
+ noetherian
+ ++ \spad{noetherian} is true if all of its ideals are finitely generated.
+ additiveValuation
+ ++ \spad{additiveValuation} implies
+ ++ \spad{euclideanSize(a*b)=euclideanSize(a)+euclideanSize(b)}.
+ multiplicativeValuation
+ ++ \spad{multiplicativeValuation} implies
+ ++ \spad{euclideanSize(a*b)=euclideanSize(a)*euclideanSize(b)}.
+ NullSquare
+ ++ \axiom{NullSquare} means that \axiom{[x,x] = 0} holds.
+ ++ See \axiomType{LieAlgebra}.
+ JacobiIdentity
+ ++ \axiom{JacobiIdentity} means that
+ ++ \axiom{[x,[y,z]]+[y,[z,x]]+[z,[x,y]] = 0} holds.
+ ++ See \axiomType{LieAlgebra}.
+ canonical
+ ++ \spad{canonical} is true if and only if distinct elements have
+ ++ distinct data structures. For example, a domain of mathematical objects
+ ++ which has the \spad{canonical} attribute means that two objects
+ ++ are mathematically
+ ++ equal if and only if their data structures are equal.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category ATTREG AttributeRegistry>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/axtimer.as.pamphlet b/src/algebra/axtimer.as.pamphlet
new file mode 100644
index 00000000..b05a3aab
--- /dev/null
+++ b/src/algebra/axtimer.as.pamphlet
@@ -0,0 +1,191 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra axtimer.as}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+--------------------------------------------------------------------------------
+--
+-- BasicMath: timer.as --- Objects for tracking time
+--
+--------------------------------------------------------------------------------
+--
+
+-- ToDo: Write so that start!(x) ; start!(x) ; stop!(x); stop!(x) works.
+
+#include "axiom.as"
+
+Z ==> Integer;
+
+Duration ==> Record(hours: Z, mins: Z, seconds: Z, milliseconds: Z);
+
++++ Timer
++++ History: 22/5/94 Original version by MB.
++++ 9/4/97 [Peter Broadbery] incorporated into Basicmath.
++++ 7/8/97 [PAB] Hacked into axiom.
++++ Timer is a type whose elements are stopwatch timers, which can be used
++++ to time precisely various sections of code.
++++ The precision can be up to 1 millisecond but depends on the operating system.
++++ The times returned are CPU times used by the process that created the timer.
+
+Timer: BasicType with {
+ HMS: Z -> Duration;
+ ++ Returns (h, m, s, u) where n milliseconds is equal
+ ++ to h hours, m minutes, s seconds and u milliseconds.
+ read: % -> Z;
+ ++ Reads the timer t without stopping it.
+ ++ Returns the total accumulated time in milliseconds by all
+ ++ the start/stop cycles since t was created or last reset.
+ ++ If t is running, the time since the last start is added in,
+ ++ and t is not stopped or affected.
+ reset!: % -> %;
+ ++ Resets the timer t to 0 and stops it if it is running.
+ ++Returns the timer t after it is reset.
+ start!: % -> Z;
+ ++ Starts or restarts t, without resetting it to 0,
+ ++ It has no effect on t if it is already running.
+ ++ Returns 0 if t was already running, the absolute time at which
+ ++ the start/restart was done otherwise.
+ stop!: % -> Z;
+ ++ Stops t without resetting it to 0.
+ ++ It has no effect on t if it is not running.
+ ++ Returns the elapsed time in milliseconds since the last time t
+ ++ was restarted, 0 if t was not running.
+ timer: () -> %;
+ ++ Creates a timer, set to 0 and stopped.
+ ++ Returns the timer that has been created.
+
+ coerce: % -> OutputForm;
+#if 0
+ gcTimer: () -> %;
+ ++ Returns the system garbage collection timer.
+ ++ Do not use for other purposes!
+#endif
+} == add {
+ -- time = total accumulated time since created or reset
+ -- start = absolute time of last start
+ -- running? = true if currently running, false if currently stopped
+ Rep ==> Record(time:Z, start:Z, running?:Boolean);
+ import {
+ BOOT_:_:GET_-INTERNAL_-RUN_-TIME: () -> Integer;
+ } from Foreign Lisp;
+ cpuTime(): Integer == BOOT_:_:GET_-INTERNAL_-RUN_-TIME();
+
+ import from Rep, Z, Boolean;
+
+ timer():% == per [0, 0, false];
+
+ read(t:%):Z == {
+ rec := rep t;
+ ans := rec.time;
+ if rec.running? then ans := ans + cpuTime() - rec.start;
+ ans
+ }
+
+ stop!(t:%):Z == {
+ local ans:Z;
+ rec := rep t;
+ if rec.running? then {
+ ans := cpuTime() - rec.start;
+ rec.time := rec.time + ans;
+ rec.running? := false
+ }
+ else ans := 0;
+ ans
+ }
+
+ start!(t:%):Z == {
+ local ans:Z;
+ rec := rep t;
+ if not(rec.running?) then {
+ rec.start := ans := cpuTime();
+ rec.running? := true;
+ }
+ else ans := 0;
+ ans
+ }
+
+ reset!(t:%):% == {
+ rec := rep t;
+ rec.time := rec.start := 0;
+ rec.running? := false;
+ t
+ }
+
+ HMS(m:Z): Duration == {
+ import from Record(quotient: Integer, remainder: Integer);
+ (h, m) := explode divide(m, 3600000);
+ (m, s) := explode divide(m, 60000);
+ (s, l) := explode divide(s, 1000);
+ [h, m, s, l]
+ }
+
+#if 0
+ import {
+ gcTimer: () -> Pointer;
+ } from Foreign C;
+
+ gcTimer(): % == (gcTimer())@Pointer pretend %;
+#endif
+ coerce(x: %): OutputForm == {
+ import from List OutputForm;
+ assign(name: String, val: OutputForm): OutputForm == {
+ import from Symbol;
+ blankSeparate [outputForm(name::Symbol), outputForm("="::Symbol), val];
+ }
+ state: Symbol := coerce(if rep(x).running? then "on" else "off");
+ bracket [outputForm("Timer:"::Symbol),
+ commaSeparate [assign("state", outputForm state),
+ assign("value", (read x)::OutputForm)]];
+ }
+
+ (a: %) = (b: %): Boolean == error "No equality for Timers";
+}
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/bags.spad.pamphlet b/src/algebra/bags.spad.pamphlet
new file mode 100644
index 00000000..8e1c3356
--- /dev/null
+++ b/src/algebra/bags.spad.pamphlet
@@ -0,0 +1,329 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra bags.spad}
+\author{Michael Monagan, Stephen Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain STACK Stack}
+<<domain STACK Stack>>=
+)abbrev domain STACK Stack
+++ Author: Michael Monagan and Stephen Watt
+++ Date Created:June 86 and July 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+
+++ Linked List implementation of a Stack
+--% Dequeue and Heap data types
+
+Stack(S:SetCategory): StackAggregate S with
+ stack: List S -> %
+ ++ stack([x,y,...,z]) creates a stack with first (top)
+ ++ element x, second element y,...,and last element z.
+ == add
+ Rep := Reference List S
+ s = t == deref s = deref t
+ coerce(d:%): OutputForm == bracket [e::OutputForm for e in deref d]
+ copy s == ref copy deref s
+ depth s == # deref s
+ # s == depth s
+ pop_! (s:%):S ==
+ empty? s => error "empty stack"
+ e := first deref s
+ setref(s,rest deref s)
+ e
+ extract_! (s:%):S == pop_! s
+ top (s:%):S ==
+ empty? s => error "empty stack"
+ first deref s
+ inspect s == top s
+ push_!(e,s) == (setref(s,cons(e,deref s));e)
+ insert_!(e:S,s:%):% == (push_!(e,s);s)
+ empty() == ref nil()$List(S)
+ empty? s == null deref s
+ stack s == ref copy s
+
+@
+\section{domain ASTACK ArrayStack}
+<<domain ASTACK ArrayStack>>=
+)abbrev domain ASTACK ArrayStack
+++ Author: Michael Monagan and Stephen Watt
+++ Date Created:June 86 and July 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+
+++ A stack represented as a flexible array.
+--% Dequeue and Heap data types
+
+ArrayStack(S:SetCategory): StackAggregate(S) with
+ arrayStack: List S -> %
+ ++ arrayStack([x,y,...,z]) creates an array stack with first (top)
+ ++ element x, second element y,...,and last element z.
+ == add
+ Rep := IndexedFlexibleArray(S,0)
+
+ -- system operations
+ # s == _#(s)$Rep
+ s = t == s =$Rep t
+ copy s == copy(s)$Rep
+ coerce(d):OutputForm ==
+ empty? d => empty()$(List S) ::OutputForm
+ [(d.i::OutputForm) for i in 0..#d-1] ::OutputForm
+
+ -- stack operations
+ depth s == # s
+ empty? s == empty?(s)$Rep
+ extract_! s == pop_! s
+ insert_!(e,s) == (push_!(e,s);s)
+ push_!(e,s) == (concat(e,s); e)
+ pop_! s ==
+ if empty? s then error "empty stack"
+ m := maxIndex s
+ r := s.m
+ delete_!(s,m)
+ r
+ top s == if empty? s then error "empty stack" else s.maxIndex(s)
+ arrayStack l == construct(l)$Rep
+ empty() == new(0,0 pretend S)
+
+@
+\section{domain QUEUE Queue}
+<<domain QUEUE Queue>>=
+)abbrev domain QUEUE Queue
+++ Author: Michael Monagan and Stephen Watt
+++ Date Created:June 86 and July 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+
+++ Linked List implementation of a Queue
+--% Dequeue and Heap data types
+
+Queue(S:SetCategory): QueueAggregate S with
+ queue: List S -> %
+ ++ queue([x,y,...,z]) creates a queue with first (top)
+ ++ element x, second element y,...,and last (bottom) element z.
+ == Stack S add
+ Rep := Reference List S
+ lastTail==> LAST$Lisp
+ enqueue_!(e,q) ==
+ if null deref q then setref(q, list e)
+ else lastTail.(deref q).rest := list e
+ e
+ insert_!(e,q) == (enqueue_!(e,q);q)
+ dequeue_! q ==
+ empty? q => error "empty queue"
+ e := first deref q
+ setref(q,rest deref q)
+ e
+ extract_! q == dequeue_! q
+ rotate_! q == if empty? q then q else (enqueue_!(dequeue_! q,q); q)
+ length q == # deref q
+ front q == if empty? q then error "empty queue" else first deref q
+ inspect q == front q
+ back q == if empty? q then error "empty queue" else last deref q
+ queue q == ref copy q
+
+@
+\section{domain DEQUEUE Dequeue}
+<<domain DEQUEUE Dequeue>>=
+)abbrev domain DEQUEUE Dequeue
+++ Author: Michael Monagan and Stephen Watt
+++ Date Created:June 86 and July 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+
+++ Linked list implementation of a Dequeue
+--% Dequeue and Heap data types
+
+Dequeue(S:SetCategory): DequeueAggregate S with
+ dequeue: List S -> %
+ ++ dequeue([x,y,...,z]) creates a dequeue with first (top or front)
+ ++ element x, second element y,...,and last (bottom or back) element z.
+ == Queue S add
+ Rep := Reference List S
+ bottom_! d ==
+ if empty? d then error "empty dequeue" else last deref d
+ dequeue d == ref copy d
+ extractBottom_! d ==
+ if empty? d then error "empty dequeue"
+ p := deref d
+ n := maxIndex p
+ n = 1 =>
+ r := first p
+ setref(d,[])
+ r
+ q := rest(p,(n-2)::NonNegativeInteger)
+ r := first rest q
+ q.rest := []
+ r
+ extractTop_! d ==
+ e := top d
+ setref(d,rest deref d)
+ e
+ height d == # deref d
+ insertTop_!(e,d) == (setref(d,cons(e,deref d)); e)
+ lastTail==> LAST$Lisp
+ insertBottom_!(e,d) ==
+ if empty? d then setref(d, list e)
+ else lastTail.(deref d).rest := list e
+ e
+ top d == if empty? d then error "empty dequeue" else first deref d
+ reverse_! d == (setref(d,reverse deref d); d)
+
+@
+\section{domain HEAP Heap}
+<<domain HEAP Heap>>=
+)abbrev domain HEAP Heap
+++ Author: Michael Monagan and Stephen Watt
+++ Date Created:June 86 and July 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+
+++ Heap implemented in a flexible array to allow for insertions
+++ Complexity: O(log n) insertion, extraction and O(n) construction
+--% Dequeue and Heap data types
+
+Heap(S:OrderedSet): Exports == Implementation where
+ Exports == PriorityQueueAggregate S with
+ heap : List S -> %
+ ++ heap(ls) creates a heap of elements consisting of the
+ ++ elements of ls.
+ Implementation == IndexedFlexibleArray(S,0) add
+ Rep := IndexedFlexibleArray( S,0)
+ empty() == empty()$Rep
+ heap l ==
+ n := #l
+ h := empty()
+ n = 0 => h
+ for x in l repeat insert_!(x,h)
+ h
+ siftUp: (%,Integer,Integer) -> Void
+ siftUp(r,i,n) ==
+ -- assertion 0 <= i < n
+ t := r.i
+ while (j := 2*i+1) < n repeat
+ if (k := j+1) < n and r.j < r.k then j := k
+ if t < r.j then (r.i := r.j; r.j := t; i := j) else leave
+
+ extract_! r ==
+ -- extract the maximum from the heap O(log n)
+ n := #r :: Integer
+ n = 0 => error "empty heap"
+ t := r(0)
+ r(0) := r(n-1)
+ delete_!(r,n-1)
+ n = 1 => t
+ siftUp(r,0,n-1)
+ t
+
+ insert_!(x,r) ==
+ -- Williams' insertion algorithm O(log n)
+ j := (#r) :: Integer
+ r:=concat_!(r,concat(x,empty()$Rep))
+ while j > 0 repeat
+ i := (j-1) quo 2
+ if r(i) >= x then leave
+ r(j) := r(i)
+ j := i
+ r(j):=x
+ r
+
+ max r == if #r = 0 then error "empty heap" else r.0
+ inspect r == max r
+
+ makeHeap(r:%):% ==
+ -- Floyd's heap construction algorithm O(n)
+ n := #r
+ for k in n quo 2 -1 .. 0 by -1 repeat siftUp(r,k,n)
+ r
+ bag l == makeHeap construct(l)$Rep
+ merge(a,b) == makeHeap concat(a,b)
+ merge_!(a,b) == makeHeap concat_!(a,b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain STACK Stack>>
+<<domain ASTACK ArrayStack>>
+<<domain QUEUE Queue>>
+<<domain DEQUEUE Dequeue>>
+<<domain HEAP Heap>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/bezout.spad.pamphlet b/src/algebra/bezout.spad.pamphlet
new file mode 100644
index 00000000..7f6b5400
--- /dev/null
+++ b/src/algebra/bezout.spad.pamphlet
@@ -0,0 +1,206 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra bezout.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package BEZOUT BezoutMatrix}
+<<package BEZOUT BezoutMatrix>>=
+)abbrev package BEZOUT BezoutMatrix
+++ Author: Clifton J. Williamson
+++ Date Created: 2 August 1988
+++ Date Last Updated: 3 November 1993
+++ Basic Operations: bezoutMatrix, bezoutResultant, bezoutDiscriminant
+++ Related Domains
+++ Also See:
+++ AMS Classifiactions:
+++ Keywords: Bezout matrix, resultant, discriminant
+++ Examples:
+++ Reference: Knuth, The Art of Computer Programming, 2nd edition,
+++ Vol. 2, p. 619, problem 12.
+++ Description:
+++ \spadtype{BezoutMatrix} contains functions for computing resultants and
+++ discriminants using Bezout matrices.
+
+BezoutMatrix(R,UP,M,Row,Col): Exports == Implementation where
+ R : Ring
+ UP : UnivariatePolynomialCategory R
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+ M : MatrixCategory(R,Row,Col)
+ I ==> Integer
+ lc ==> leadingCoefficient
+
+ Exports ==> with
+ sylvesterMatrix: (UP,UP) -> M
+ ++ sylvesterMatrix(p,q) returns the Sylvester matrix for the two
+ ++ polynomials p and q.
+ bezoutMatrix: (UP,UP) -> M
+ ++ bezoutMatrix(p,q) returns the Bezout matrix for the two
+ ++ polynomials p and q.
+
+ if R has commutative("*") then
+ bezoutResultant: (UP,UP) -> R
+ ++ bezoutResultant(p,q) computes the resultant of the two
+ ++ polynomials p and q by computing the determinant of a Bezout matrix.
+
+ bezoutDiscriminant: UP -> R
+ ++ bezoutDiscriminant(p) computes the discriminant of a polynomial p
+ ++ by computing the determinant of a Bezout matrix.
+
+ Implementation ==> add
+
+ sylvesterMatrix(p,q) ==
+ n1 := degree p; n2 := degree q; n := n1 + n2
+ sylmat : M := new(n,n,0)
+ minR := minRowIndex sylmat; minC := minColIndex sylmat
+ maxR := maxRowIndex sylmat; maxC := maxColIndex sylmat
+ p0 := p
+ -- fill in coefficients of 'p'
+ while not zero? p0 repeat
+ coef := lc p0; deg := degree p0; p0 := reductum p0
+ -- put bk = coef(p,k) in sylmat(minR + i,minC + i + (n1 - k))
+ for i in 0..n2 - 1 repeat
+ qsetelt_!(sylmat,minR + i,minC + n1 - deg + i,coef)
+ q0 := q
+ -- fill in coefficients of 'q'
+ while not zero? q0 repeat
+ coef := lc q0; deg := degree q0; q0 := reductum q0
+ for i in 0..n1-1 repeat
+ qsetelt_!(sylmat,minR + n2 + i,minC + n2 - deg + i,coef)
+ sylmat
+
+ bezoutMatrix(p,q) ==
+ -- This function computes the Bezout matrix for 'p' and 'q'.
+ -- See Knuth, The Art of Computer Programming, Vol. 2, p. 619, # 12.
+ -- One must have deg(p) >= deg(q), so the arguments are reversed
+ -- if this is not the case.
+ n1 := degree p; n2 := degree q; n := n1 + n2
+ n1 < n2 => bezoutMatrix(q,p)
+ m1 : I := n1 - 1; m2 : I := n2 - 1; m : I := n - 1
+ -- 'sylmat' will be a matrix consisting of the first n1 columns
+ -- of the standard Sylvester matrix for 'p' and 'q'
+ sylmat : M := new(n,n1,0)
+ minR := minRowIndex sylmat; minC := minColIndex sylmat
+ maxR := maxRowIndex sylmat; maxC := maxColIndex sylmat
+ p0 := p
+ -- fill in coefficients of 'p'
+ while not ground? p0 repeat
+ coef := lc p0; deg := degree p0; p0 := reductum p0
+ -- put bk = coef(p,k) in sylmat(minR + i,minC + i + (n1 - k))
+ -- for i = 0...
+ -- quit when i > m2 or when i + (n1 - k) > m1, whichever happens first
+ for i in 0..min(m2,deg - 1) repeat
+ qsetelt_!(sylmat,minR + i,minC + n1 - deg + i,coef)
+ q0 := q
+ -- fill in coefficients of 'q'
+ while not zero? q0 repeat
+ coef := lc q0; deg := degree q0; q0 := reductum q0
+ -- put ak = coef(q,k) in sylmat(minR + n1 + i,minC + i + (n2 - k))
+ -- for i = 0...
+ -- quit when i > m1 or when i + (n2 - k) > m1, whichever happens first
+ -- since n2 - k >= 0, we quit when i + (n2 - k) > m1
+ for i in 0..(deg + n1 - n2 - 1) repeat
+ qsetelt_!(sylmat,minR + n2 + i,minC + n2 - deg + i,coef)
+ -- 'bezmat' will be the 'Bezout matrix' as described in Knuth
+ bezmat : M := new(n1,n1,0)
+ for i in 0..m2 repeat
+ -- replace A_i by (b_0 A_i + ... + b_{n_2-1-i} A_{n_2 - 1}) -
+ -- (a_0 B_i + ... + a_{n_2-1-i} B_{n_2-1}), as in Knuth
+ bound : I := n2 - i; q0 := q
+ while not zero? q0 repeat
+ deg := degree q0
+ if (deg < bound) then
+ -- add b_deg A_{n_2 - deg} to the new A_i
+ coef := lc q0
+ for k in minC..maxC repeat
+ c := coef * qelt(sylmat,minR + m2 - i - deg,k) +
+ qelt(bezmat,minR + m2 - i,k)
+ qsetelt_!(bezmat,minR + m2 - i,k,c)
+ q0 := reductum q0
+ p0 := p
+ while not zero? p0 repeat
+ deg := degree p0
+ if deg < bound then
+ coef := lc p0
+ -- subtract a_deg B_{n_2 - deg} from the new A_i
+ for k in minC..maxC repeat
+ c := -coef * qelt(sylmat,minR + m - i - deg,k) +
+ qelt(bezmat,minR + m2 - i,k)
+ qsetelt_!(bezmat,minR + m2 - i,k,c)
+ p0 := reductum p0
+ for i in n2..m1 repeat for k in minC..maxC repeat
+ qsetelt_!(bezmat,minR + i,k,qelt(sylmat,minR + i,k))
+ bezmat
+
+ if R has commutative("*") then
+
+ bezoutResultant(f,g) == determinant bezoutMatrix(f,g)
+
+ if R has IntegralDomain then
+
+ bezoutDiscriminant f ==
+ degMod4 := (degree f) rem 4
+ (degMod4 = 0) or (degMod4 = 1) =>
+ (bezoutResultant(f,differentiate f) exquo (lc f)) :: R
+ -((bezoutResultant(f,differentiate f) exquo (lc f)) :: R)
+
+ else
+
+ bezoutDiscriminant f ==
+ lc f = 1 =>
+ degMod4 := (degree f) rem 4
+ (degMod4 = 0) or (degMod4 = 1) =>
+ bezoutResultant(f,differentiate f)
+ -bezoutResultant(f,differentiate f)
+ error "bezoutDiscriminant: leading coefficient must be 1"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package BEZOUT BezoutMatrix>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/boolean.spad.pamphlet b/src/algebra/boolean.spad.pamphlet
new file mode 100644
index 00000000..84632fa5
--- /dev/null
+++ b/src/algebra/boolean.spad.pamphlet
@@ -0,0 +1,587 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra boolean.spad}
+\author{Stephen M. Watt, Michael Monagan}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain REF Reference}
+<<domain REF Reference>>=
+)abbrev domain REF Reference
+++ Author: Stephen M. Watt
+++ Date Created:
+++ Change History:
+++ Basic Operations: deref, elt, ref, setelt, setref, =
+++ Related Constructors:
+++ Keywords: reference
+++ Description: \spadtype{Reference} is for making a changeable instance
+++ of something.
+
+Reference(S:Type): Type with
+ ref : S -> %
+ ++ ref(n) creates a pointer (reference) to the object n.
+ elt : % -> S
+ ++ elt(n) returns the object n.
+ setelt: (%, S) -> S
+ ++ setelt(n,m) changes the value of the object n to m.
+ -- alternates for when bugs don't allow the above
+ deref : % -> S
+ ++ deref(n) is equivalent to \spad{elt(n)}.
+ setref: (%, S) -> S
+ ++ setref(n,m) same as \spad{setelt(n,m)}.
+ _= : (%, %) -> Boolean
+ ++ a=b tests if \spad{a} and b are equal.
+ if S has SetCategory then SetCategory
+
+ == add
+ Rep := Record(value: S)
+
+ p = q == EQ(p, q)$Lisp
+ ref v == [v]
+ elt p == p.value
+ setelt(p, v) == p.value := v
+ deref p == p.value
+ setref(p, v) == p.value := v
+
+ if S has SetCategory then
+ coerce p ==
+ prefix(message("ref"@String), [p.value::OutputForm])
+
+@
+\section{REF.lsp BOOTSTRAP}
+{\bf REF} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf REF} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf REF.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<REF.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |REF;=;2$B;1|) (QUOTE |SPADreplace|) (QUOTE EQ))
+
+(DEFUN |REF;=;2$B;1| (|p| |q| |$|) (EQ |p| |q|))
+
+(PUT (QUOTE |REF;ref;S$;2|) (QUOTE |SPADreplace|) (QUOTE LIST))
+
+(DEFUN |REF;ref;S$;2| (|v| |$|) (LIST |v|))
+
+(PUT (QUOTE |REF;elt;$S;3|) (QUOTE |SPADreplace|) (QUOTE QCAR))
+
+(DEFUN |REF;elt;$S;3| (|p| |$|) (QCAR |p|))
+
+(DEFUN |REF;setelt;$2S;4| (|p| |v| |$|) (PROGN (RPLACA |p| |v|) (QCAR |p|)))
+
+(PUT (QUOTE |REF;deref;$S;5|) (QUOTE |SPADreplace|) (QUOTE QCAR))
+
+(DEFUN |REF;deref;$S;5| (|p| |$|) (QCAR |p|))
+
+(DEFUN |REF;setref;$2S;6| (|p| |v| |$|) (PROGN (RPLACA |p| |v|) (QCAR |p|)))
+
+(DEFUN |REF;coerce;$Of;7| (|p| |$|) (SPADCALL (SPADCALL "ref" (QREFELT |$| 17)) (LIST (SPADCALL (QCAR |p|) (QREFELT |$| 18))) (QREFELT |$| 20)))
+
+(DEFUN |Reference| (#1=#:G82336) (PROG NIL (RETURN (PROG (#2=#:G82337) (RETURN (COND ((LETT #2# (|lassocShiftWithFunction| (LIST (|devaluate| #1#)) (HGET |$ConstructorCache| (QUOTE |Reference|)) (QUOTE |domainEqualList|)) |Reference|) (|CDRwithIncrement| #2#)) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (|Reference;| #1#) (LETT #2# T |Reference|)) (COND ((NOT #2#) (HREM |$ConstructorCache| (QUOTE |Reference|))))))))))))
+
+(DEFUN |Reference;| (|#1|) (PROG (|DV$1| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|Reference|)) (LETT |dv$| (LIST (QUOTE |Reference|) |DV$1|) . #1#) (LETT |$| (GETREFV 23) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#1| (QUOTE (|SetCategory|))))) . #1#)) (|haddProp| |$ConstructorCache| (QUOTE |Reference|) (LIST |DV$1|) (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 (|Record| (|:| |value| |#1|))) (COND ((|testBitVector| |pv$| 1) (QSETREFV |$| 21 (CONS (|dispatchFunction| |REF;coerce;$Of;7|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |Reference|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (QUOTE |Rep|) (|Boolean|) |REF;=;2$B;1| |REF;ref;S$;2| |REF;elt;$S;3| |REF;setelt;$2S;4| |REF;deref;$S;5| |REF;setref;$2S;6| (|String|) (|OutputForm|) (0 . |message|) (5 . |coerce|) (|List| |$|) (10 . |prefix|) (16 . |coerce|) (|SingleInteger|))) (QUOTE #(|~=| 21 |setref| 27 |setelt| 33 |ref| 39 |latex| 44 |hash| 49 |elt| 54 |deref| 59 |coerce| 64 |=| 69)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE (1 0 1 1))) (CONS (QUOTE #(|SetCategory&| NIL |BasicType&| NIL)) (CONS (QUOTE #((|SetCategory|) (|Type|) (|BasicType|) (|CoercibleTo| 16))) (|makeByteWordVec2| 22 (QUOTE (1 16 0 15 17 1 6 16 0 18 2 16 0 0 19 20 1 0 16 0 21 2 1 8 0 0 1 2 0 6 0 6 14 2 0 6 0 6 12 1 0 0 6 10 1 1 15 0 1 1 1 22 0 1 1 0 6 0 11 1 0 6 0 13 1 1 16 0 21 2 0 8 0 0 9)))))) (QUOTE |lookupComplete|)))
+@
+\section{category LOGIC Logic}
+<<category LOGIC Logic>>=
+)abbrev category LOGIC Logic
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: ~, /\, \/
+++ Related Constructors:
+++ Keywords: boolean
+++ Description:
+++ `Logic' provides the basic operations for lattices,
+++ e.g., boolean algebra.
+
+
+Logic: Category == BasicType with
+ _~: % -> %
+ ++ ~(x) returns the logical complement of x.
+ _/_\: (%, %) -> %
+ ++ \spadignore { /\ }returns the logical `meet', e.g. `and'.
+ _\_/: (%, %) -> %
+ ++ \spadignore{ \/ } returns the logical `join', e.g. `or'.
+ add
+ _\_/(x: %,y: %) == _~( _/_\(_~(x), _~(y)))
+
+@
+\section{domain BOOLEAN Boolean}
+<<domain BOOLEAN Boolean>>=
+)abbrev domain BOOLEAN Boolean
+++ Author: Stephen M. Watt
+++ Date Created:
+++ Change History:
+++ Basic Operations: true, false, not, and, or, xor, nand, nor, implies, ^
+++ Related Constructors:
+++ Keywords: boolean
+++ Description: \spadtype{Boolean} is the elementary logic with 2 values:
+++ true and false
+
+Boolean(): Join(OrderedSet, Finite, Logic, ConvertibleTo InputForm) with
+ true : constant -> %
+ ++ true is a logical constant.
+ false : constant -> %
+ ++ false is a logical constant.
+ _^ : % -> %
+ ++ ^ n returns the negation of n.
+ _not : % -> %
+ ++ not n returns the negation of n.
+ _and : (%, %) -> %
+ ++ a and b returns the logical {\em and} of Boolean \spad{a} and b.
+ _or : (%, %) -> %
+ ++ a or b returns the logical inclusive {\em or}
+ ++ of Boolean \spad{a} and b.
+ xor : (%, %) -> %
+ ++ xor(a,b) returns the logical exclusive {\em or}
+ ++ of Boolean \spad{a} and b.
+ nand : (%, %) -> %
+ ++ nand(a,b) returns the logical negation of \spad{a} and b.
+ nor : (%, %) -> %
+ ++ nor(a,b) returns the logical negation of \spad{a} or b.
+ implies: (%, %) -> %
+ ++ implies(a,b) returns the logical implication
+ ++ of Boolean \spad{a} and b.
+ test: % -> Boolean
+ ++ test(b) returns b and is provided for compatibility with the new compiler.
+ == add
+ nt: % -> %
+
+ test a == a pretend Boolean
+
+ nt b == (b pretend Boolean => false; true)
+ true == EQ(2,2)$Lisp --well, 1 is rather special
+ false == NIL$Lisp
+ sample() == true
+ not b == (test b => false; true)
+ _^ b == (test b => false; true)
+ _~ b == (test b => false; true)
+ _and(a, b) == (test a => b; false)
+ _/_\(a, b) == (test a => b; false)
+ _or(a, b) == (test a => true; b)
+ _\_/(a, b) == (test a => true; b)
+ xor(a, b) == (test a => nt b; b)
+ nor(a, b) == (test a => false; nt b)
+ nand(a, b) == (test a => nt b; true)
+ a = b == BooleanEquality(a, b)$Lisp
+ implies(a, b) == (test a => b; true)
+ a < b == (test b => not(test a);false)
+
+ size() == 2
+ index i ==
+ even?(i::Integer) => false
+ true
+ lookup a ==
+ a pretend Boolean => 1
+ 2
+ random() ==
+ even?(random()$Integer) => false
+ true
+
+ convert(x:%):InputForm ==
+ x pretend Boolean => convert("true"::Symbol)
+ convert("false"::Symbol)
+
+ coerce(x:%):OutputForm ==
+ x pretend Boolean => message "true"
+ message "false"
+
+@
+\section{BOOLEAN.lsp}
+{\bf BOOLEAN} depends on
+{\bf ORDSET} which depends on
+{\bf SETCAT} which depends on
+{\bf BASTYPE} which depends on
+{\bf BOOLEAN}. We need to break this cycle to build the algebra.
+So we keep a cached copy of the translated BOOLEAN domain which
+we can write into the {\bf MID} directory. We compile the lisp
+code and copy the {\bf BOOLEAN.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+<<BOOLEAN.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT
+ (QUOTE |BOOLEAN;test;2$;1|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|a|) |a|)))
+
+(DEFUN |BOOLEAN;test;2$;1| (|a| |$|) |a|)
+
+(DEFUN |BOOLEAN;nt| (|b| |$|)
+ (COND (|b| (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(PUT
+ (QUOTE |BOOLEAN;true;$;3|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL (QUOTE T))))
+
+(DEFUN |BOOLEAN;true;$;3| (|$|)
+ (QUOTE T))
+
+(PUT
+ (QUOTE |BOOLEAN;false;$;4|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL NIL)))
+
+(DEFUN |BOOLEAN;false;$;4| (|$|) NIL)
+
+(DEFUN |BOOLEAN;not;2$;5| (|b| |$|)
+ (COND
+ (|b| (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |BOOLEAN;^;2$;6| (|b| |$|)
+ (COND
+ (|b| (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |BOOLEAN;~;2$;7| (|b| |$|)
+ (COND
+ (|b| (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |BOOLEAN;and;3$;8| (|a| |b| |$|)
+ (COND
+ (|a| |b|)
+ ((QUOTE T) (QUOTE NIL))))
+
+(DEFUN |BOOLEAN;/\\;3$;9| (|a| |b| |$|)
+ (COND
+ (|a| |b|)
+ ((QUOTE T) (QUOTE NIL))))
+
+(DEFUN |BOOLEAN;or;3$;10| (|a| |b| |$|)
+ (COND
+ (|a| (QUOTE T))
+ ((QUOTE T) |b|)))
+
+(DEFUN |BOOLEAN;\\/;3$;11| (|a| |b| |$|)
+ (COND
+ (|a| (QUOTE T))
+ ((QUOTE T) |b|)))
+
+(DEFUN |BOOLEAN;xor;3$;12| (|a| |b| |$|)
+ (COND
+ (|a| (|BOOLEAN;nt| |b| |$|))
+ ((QUOTE T) |b|)))
+
+(DEFUN |BOOLEAN;nor;3$;13| (|a| |b| |$|)
+ (COND
+ (|a| (QUOTE NIL))
+ ((QUOTE T) (|BOOLEAN;nt| |b| |$|))))
+
+(DEFUN |BOOLEAN;nand;3$;14| (|a| |b| |$|)
+ (COND
+ (|a| (|BOOLEAN;nt| |b| |$|))
+ ((QUOTE T) (QUOTE T))))
+
+(PUT
+ (QUOTE |BOOLEAN;=;3$;15|)
+ (QUOTE |SPADreplace|)
+ (QUOTE |BooleanEquality|))
+
+(DEFUN |BOOLEAN;=;3$;15| (|a| |b| |$|)
+ (|BooleanEquality| |a| |b|))
+
+(DEFUN |BOOLEAN;implies;3$;16| (|a| |b| |$|)
+ (COND
+ (|a| |b|)
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |BOOLEAN;<;3$;17| (|a| |b| |$|)
+ (COND
+ (|b|
+ (COND
+ (|a| (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ ((QUOTE T) (QUOTE NIL))))
+
+(PUT
+ (QUOTE |BOOLEAN;size;Nni;18|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL 2)))
+
+(DEFUN |BOOLEAN;size;Nni;18| (|$|) 2)
+
+(DEFUN |BOOLEAN;index;Pi$;19| (|i| |$|)
+ (COND
+ ((SPADCALL |i| (QREFELT |$| 26)) (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |BOOLEAN;lookup;$Pi;20| (|a| |$|)
+ (COND
+ (|a| 1)
+ ((QUOTE T) 2)))
+
+(DEFUN |BOOLEAN;random;$;21| (|$|)
+ (COND
+ ((SPADCALL (|random|) (QREFELT |$| 26)) (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |BOOLEAN;convert;$If;22| (|x| |$|)
+ (COND
+ (|x| (SPADCALL (SPADCALL "true" (QREFELT |$| 33)) (QREFELT |$| 35)))
+ ((QUOTE T)
+ (SPADCALL (SPADCALL "false" (QREFELT |$| 33)) (QREFELT |$| 35)))))
+
+(DEFUN |BOOLEAN;coerce;$Of;23| (|x| |$|)
+ (COND
+ (|x| (SPADCALL "true" (QREFELT |$| 38)))
+ ((QUOTE T) (SPADCALL "false" (QREFELT |$| 38)))))
+
+(DEFUN |Boolean| NIL
+ (PROG NIL
+ (RETURN
+ (PROG (#1=#:G82461)
+ (RETURN
+ (COND
+ ((LETT #1#
+ (HGET |$ConstructorCache| (QUOTE |Boolean|))
+ |Boolean|)
+ (|CDRwithIncrement| (CDAR #1#)))
+ ((QUOTE T)
+ (|UNWIND-PROTECT|
+ (PROG1
+ (CDDAR
+ (HPUT
+ |$ConstructorCache|
+ (QUOTE |Boolean|)
+ (LIST (CONS NIL (CONS 1 (|Boolean;|))))))
+ (LETT #1# T |Boolean|))
+ (COND
+ ((NOT #1#)
+ (HREM |$ConstructorCache| (QUOTE |Boolean|))))))))))))
+
+(DEFUN |Boolean;| NIL
+ (PROG (|dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |dv$| (QUOTE (|Boolean|)) . #1=(|Boolean|))
+ (LETT |$| (GETREFV 41) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|haddProp| |$ConstructorCache| (QUOTE |Boolean|) NIL (CONS 1 |$|))
+ (|stuffDomainSlots| |$|) |$|))))
+
+(MAKEPROP
+ (QUOTE |Boolean|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|Boolean|)
+ |BOOLEAN;test;2$;1|
+ (CONS IDENTITY
+ (FUNCALL (|dispatchFunction| |BOOLEAN;true;$;3|) |$|))
+ (CONS IDENTITY
+ (FUNCALL (|dispatchFunction| |BOOLEAN;false;$;4|) |$|))
+ |BOOLEAN;not;2$;5|
+ |BOOLEAN;^;2$;6|
+ |BOOLEAN;~;2$;7|
+ |BOOLEAN;and;3$;8|
+ |BOOLEAN;/\\;3$;9|
+ |BOOLEAN;or;3$;10|
+ |BOOLEAN;\\/;3$;11|
+ |BOOLEAN;xor;3$;12|
+ |BOOLEAN;nor;3$;13|
+ |BOOLEAN;nand;3$;14|
+ |BOOLEAN;=;3$;15|
+ |BOOLEAN;implies;3$;16|
+ |BOOLEAN;<;3$;17|
+ (|NonNegativeInteger|)
+ |BOOLEAN;size;Nni;18|
+ (|Integer|)
+ (0 . |even?|)
+ (|PositiveInteger|)
+ |BOOLEAN;index;Pi$;19|
+ |BOOLEAN;lookup;$Pi;20|
+ |BOOLEAN;random;$;21|
+ (|String|)
+ (|Symbol|)
+ (5 . |coerce|)
+ (|InputForm|)
+ (10 . |convert|)
+ |BOOLEAN;convert;$If;22|
+ (|OutputForm|)
+ (15 . |message|)
+ |BOOLEAN;coerce;$Of;23|
+ (|SingleInteger|)))
+ (QUOTE
+ #(|~=| 20 |~| 26 |xor| 31 |true| 37 |test| 41 |size| 46 |random| 50
+ |or| 54 |not| 60 |nor| 65 |nand| 71 |min| 77 |max| 83 |lookup| 89
+ |latex| 94 |index| 99 |implies| 104 |hash| 110 |false| 115
+ |convert| 119 |coerce| 124 |and| 129 |^| 135 |\\/| 140 |>=| 146
+ |>| 152 |=| 158 |<=| 164 |<| 170 |/\\| 176))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0 0)))
+ (CONS
+ (QUOTE
+ #(|OrderedSet&| NIL |Logic&| |SetCategory&| NIL |BasicType&| NIL))
+ (CONS
+ (QUOTE
+ #((|OrderedSet|)
+ (|Finite|)
+ (|Logic|)
+ (|SetCategory|)
+ (|ConvertibleTo| 34)
+ (|BasicType|)
+ (|CoercibleTo| 37)))
+ (|makeByteWordVec2|
+ 40
+ (QUOTE
+ (1 25 6 0 26 1 32 0 31 33 1 34 0 32 35 1 37 0 31 38 2 0 6 0 0
+ 1 1 0 0 0 12 2 0 0 0 0 17 0 0 0 8 1 0 6 0 7 0 0 23 24 0 0 0
+ 30 2 0 0 0 0 15 1 0 0 0 10 2 0 0 0 0 18 2 0 0 0 0 19 2 0 0 0
+ 0 1 2 0 0 0 0 1 1 0 27 0 29 1 0 31 0 1 1 0 0 27 28 2 0 0 0 0
+ 21 1 0 40 0 1 0 0 0 9 1 0 34 0 36 1 0 37 0 39 2 0 0 0 0 13 1
+ 0 0 0 11 2 0 0 0 0 16 2 0 6 0 0 1 2 0 6 0 0 1 2 0 6 0 0 20 2
+ 0 6 0 0 1 2 0 6 0 0 22 2 0 0 0 0 14))))))
+ (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |Boolean|) (QUOTE NILADIC) T)
+
+@
+\section{domain IBITS IndexedBits}
+<<domain IBITS IndexedBits>>=
+)abbrev domain IBITS IndexedBits
+++ Author: Stephen Watt and Michael Monagan
+++ Date Created:
+++ July 86
+++ Change History:
+++ Oct 87
+++ Basic Operations: range
+++ Related Constructors:
+++ Keywords: indexed bits
+++ Description: \spadtype{IndexedBits} is a domain to compactly represent
+++ large quantities of Boolean data.
+
+IndexedBits(mn:Integer): BitAggregate() with
+ -- temporaries until parser gets better
+ Not: % -> %
+ ++ Not(n) returns the bit-by-bit logical {\em Not} of n.
+ Or : (%, %) -> %
+ ++ Or(n,m) returns the bit-by-bit logical {\em Or} of
+ ++ n and m.
+ And: (%, %) -> %
+ ++ And(n,m) returns the bit-by-bit logical {\em And} of
+ ++ n and m.
+ == add
+
+ range: (%, Integer) -> Integer
+ --++ range(j,i) returnes the range i of the boolean j.
+
+ minIndex u == mn
+
+ range(v, i) ==
+ i >= 0 and i < #v => i
+ error "Index out of range"
+
+ coerce(v):OutputForm ==
+ t:Character := char "1"
+ f:Character := char "0"
+ s := new(#v, space()$Character)$String
+ for i in minIndex(s)..maxIndex(s) for j in mn.. repeat
+ s.i := if v.j then t else f
+ s::OutputForm
+
+ new(n, b) == BVEC_-MAKE_-FULL(n,TRUTH_-TO_-BIT(b)$Lisp)$Lisp
+ empty() == BVEC_-MAKE_-FULL(0,0)$Lisp
+ copy v == BVEC_-COPY(v)$Lisp
+ #v == BVEC_-SIZE(v)$Lisp
+ v = u == BVEC_-EQUAL(v, u)$Lisp
+ v < u == BVEC_-GREATER(u, v)$Lisp
+ _and(u, v) == (#v=#u => BVEC_-AND(v,u)$Lisp; map("and",v,u))
+ _or(u, v) == (#v=#u => BVEC_-OR(v, u)$Lisp; map("or", v,u))
+ xor(v,u) == (#v=#u => BVEC_-XOR(v,u)$Lisp; map("xor",v,u))
+ setelt(v:%, i:Integer, f:Boolean) ==
+ BVEC_-SETELT(v, range(v, i-mn), TRUTH_-TO_-BIT(f)$Lisp)$Lisp
+ elt(v:%, i:Integer) ==
+ BIT_-TO_-TRUTH(BVEC_-ELT(v, range(v, i-mn))$Lisp)$Lisp
+
+ Not v == BVEC_-NOT(v)$Lisp
+ And(u, v) == (#v=#u => BVEC_-AND(v,u)$Lisp; map("and",v,u))
+ Or(u, v) == (#v=#u => BVEC_-OR(v, u)$Lisp; map("or", v,u))
+
+@
+\section{domain BITS Bits}
+<<domain BITS Bits>>=
+)abbrev domain BITS Bits
+++ Author: Stephen M. Watt
+++ Date Created:
+++ Change History:
+++ Basic Operations: And, Not, Or
+++ Related Constructors:
+++ Keywords: bits
+++ Description: \spadtype{Bits} provides logical functions for Indexed Bits.
+
+Bits(): Exports == Implementation where
+ Exports == BitAggregate() with
+ bits: (NonNegativeInteger, Boolean) -> %
+ ++ bits(n,b) creates bits with n values of b
+ Implementation == IndexedBits(1) add
+ bits(n,b) == new(n,b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain REF Reference>>
+<<category LOGIC Logic>>
+<<domain BOOLEAN Boolean>>
+<<domain IBITS IndexedBits>>
+<<domain BITS Bits>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/brill.spad.pamphlet b/src/algebra/brill.spad.pamphlet
new file mode 100644
index 00000000..ae69e86c
--- /dev/null
+++ b/src/algebra/brill.spad.pamphlet
@@ -0,0 +1,161 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra brill.spad}
+\author{Frederic Lehobey, James H. Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package BRILL BrillhartTests}
+<<package BRILL BrillhartTests>>=
+)abbrev package BRILL BrillhartTests
+++ Author: Frederic Lehobey, James H. Davenport
+++ Date Created: 28 June 1994
+++ Date Last Updated: 11 July 1997
+++ Basic Operations: brillhartIrreducible?
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: factorization
+++ Examples:
+++ References:
+++ [1] John Brillhart, Note on Irreducibility Testing,
+++ Mathematics of Computation, vol. 35, num. 35, Oct. 1980, 1379-1381
+++ [2] James Davenport, On Brillhart Irreducibility. To appear.
+++ [3] John Brillhart, On the Euler and Bernoulli polynomials,
+++ J. Reine Angew. Math., v. 234, (1969), pp. 45-64
+
+BrillhartTests(UP): Exports == Implementation where
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ UP: UnivariatePolynomialCategory Z
+
+ Exports ==> with
+ brillhartIrreducible?: UP -> Boolean -- See [1]
+ ++ brillhartIrreducible?(p) returns \spad{true} if p can be shown to be
+ ++ irreducible by a remark of Brillhart, \spad{false} is inconclusive.
+ brillhartIrreducible?: (UP,Boolean) -> Boolean -- See [1]
+ ++ brillhartIrreducible?(p,noLinears) returns \spad{true} if p can be
+ ++ shown to be irreducible by a remark of Brillhart, \spad{false} else.
+ ++ If noLinears is \spad{true}, we are being told p has no linear factors
+ ++ \spad{false} does not mean that p is reducible.
+ brillhartTrials: () -> N
+ ++ brillhartTrials() returns the number of tests in
+ ++ \spadfun{brillhartIrreducible?}.
+ brillhartTrials: N -> N
+ ++ brillhartTrials(n) sets to n the number of tests in
+ ++ \spadfun{brillhartIrreducible?} and returns the previous value.
+ noLinearFactor?: UP -> Boolean -- See [3] p. 47
+ ++ noLinearFactor?(p) returns \spad{true} if p can be shown to have no
+ ++ linear factor by a theorem of Lehmer, \spad{false} else. I insist on
+ ++ the fact that \spad{false} does not mean that p has a linear factor.
+
+ Implementation ==> add
+
+ import GaloisGroupFactorizationUtilities(Z,UP,Float)
+
+ squaredPolynomial(p:UP):Boolean ==
+ d := degree p
+ d = 0 => true
+ odd? d => false
+ squaredPolynomial reductum p
+
+ primeEnough?(n:Z,b:Z):Boolean ==
+ -- checks if n is prime, with the possible exception of
+ -- factors whose product is at most b
+ import Float
+ bb: Float := b::Float
+ for i in 2..b repeat
+ while (d:= n exquo i) case Integer repeat
+ n:=d::Integer
+ bb:=bb / i::Float
+ bb < 1$Float => return false
+ --- we over-divided, so it can't be prime
+ prime? n
+
+ brillharttrials: N := 6
+ brillhartTrials():N == brillharttrials
+
+ brillhartTrials(n:N):N ==
+ (brillharttrials,n) := (n,brillharttrials)
+ n
+
+ brillhartIrreducible?(p:UP):Boolean ==
+ brillhartIrreducible?(p,noLinearFactor? p)
+
+ brillhartIrreducible?(p:UP,noLinears:Boolean):Boolean == -- See [1]
+ zero? brillharttrials => false
+ origBound := (largeEnough := rootBound(p)+1)
+ -- see remarks 2 and 4
+ even0 := even? coefficient(p,0)
+ even1 := even? p(1)
+ polyx2 := squaredPolynomial(p)
+ prime? p(largeEnough) => true
+ not polyx2 and prime? p(-largeEnough) => true
+-- one? brillharttrials => false
+ (brillharttrials = 1) => false
+ largeEnough := largeEnough+1
+ primeEnough?(p(largeEnough),if noLinears then 4 else 2) => true
+ not polyx2 and
+ primeEnough?(p(-largeEnough),if noLinears then 4 else 2) => true
+ if odd? largeEnough then
+ if even0 then largeEnough := largeEnough+1
+ else
+ if even1 then largeEnough := largeEnough+1
+ count :=(if polyx2 then 2 else 1)*(brillharttrials-2)+largeEnough
+ for i in (largeEnough+1)..count repeat
+ small := if noLinears then (i-origBound)**2 else (i-origBound)
+ primeEnough?(p(i),small) => return true
+ not polyx2 and primeEnough?(p(-i),small) => return true
+ false
+
+ noLinearFactor?(p:UP):Boolean ==
+ (odd? leadingCoefficient p) and (odd? coefficient(p,0)) and (odd? p(1))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package BRILL BrillhartTests>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/c02.spad.pamphlet b/src/algebra/c02.spad.pamphlet
new file mode 100644
index 00000000..f51481a0
--- /dev/null
+++ b/src/algebra/c02.spad.pamphlet
@@ -0,0 +1,130 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra c02.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGC02 NagPolynomialRootsPackage}
+<<package NAGC02 NagPolynomialRootsPackage>>=
+)abbrev package NAGC02 NagPolynomialRootsPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:27 1994
+++Description:
+++This package uses the NAG Library to compute the zeros of a
+++polynomial with real or complex coefficients.
+++See \downlink{Manual Page}{manpageXXc02}.
+
+NagPolynomialRootsPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ c02aff : (Matrix DoubleFloat,Integer,Boolean,Integer) -> Result
+ ++ c02aff(a,n,scale,ifail)
+ ++ finds all the roots of a complex polynomial equation,
+ ++ using a variant of Laguerre's Method.
+ ++ See \downlink{Manual Page}{manpageXXc02aff}.
+ c02agf : (Matrix DoubleFloat,Integer,Boolean,Integer) -> Result
+ ++ c02agf(a,n,scale,ifail)
+ ++ finds all the roots of a real polynomial equation, using a
+ ++ variant of Laguerre's Method.
+ ++ See \downlink{Manual Page}{manpageXXc02agf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Matrix DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(Boolean)
+
+
+ c02aff(aArg:Matrix DoubleFloat,nArg:Integer,scaleArg:Boolean,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c02aff",_
+ ["n"::S,"scale"::S,"ifail"::S,"a"::S,"z"::S,"w"::S]$Lisp,_
+ ["z"::S,"w"::S]$Lisp,_
+ [["double"::S,["a"::S,2$Lisp,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp_
+ ,["z"::S,2$Lisp,"n"::S]$Lisp,["w"::S,["*"::S,["+"::S,"n"::S,1$Lisp]$Lisp,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["logical"::S,"scale"::S]$Lisp_
+ ]$Lisp,_
+ ["z"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,scaleArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+
+
+ c02agf(aArg:Matrix DoubleFloat,nArg:Integer,scaleArg:Boolean,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c02agf",_
+ ["n"::S,"scale"::S,"ifail"::S,"a"::S,"z"::S,"w"::S]$Lisp,_
+ ["z"::S,"w"::S]$Lisp,_
+ [["double"::S,["a"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp_
+ ,["z"::S,2$Lisp,"n"::S]$Lisp,["w"::S,["*"::S,["+"::S,"n"::S,1$Lisp]$Lisp,2$Lisp]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["logical"::S,"scale"::S]$Lisp_
+ ]$Lisp,_
+ ["z"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,scaleArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGC02 NagPolynomialRootsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/c05.spad.pamphlet b/src/algebra/c05.spad.pamphlet
new file mode 100644
index 00000000..61e2337c
--- /dev/null
+++ b/src/algebra/c05.spad.pamphlet
@@ -0,0 +1,176 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra c05.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGC05 NagRootFindingPackage}
+<<package NAGC05 NagRootFindingPackage>>=
+)abbrev package NAGC05 NagRootFindingPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:28 1994
+++Description:
+++This package uses the NAG Library to calculate real zeros of
+++continuous real functions of one or more variables. (Complex
+++equations must be expressed in terms of the equivalent larger
+++system of real equations.)
+++See \downlink{Manual Page}{manpageXXc05}.
+
+NagRootFindingPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ c05adf : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ Integer,Union(fn:FileName,fp:Asp1(F))) -> Result
+ ++ c05adf(a,b,eps,eta,ifail,f)
+ ++ locates a zero of a continuous function in a given
+ ++ interval by a combination of the methods of linear interpolation,
+ ++ extrapolation and bisection.
+ ++ See \downlink{Manual Page}{manpageXXc05adf}.
+ c05nbf : (Integer,Integer,Matrix DoubleFloat,DoubleFloat,_
+ Integer,Union(fn:FileName,fp:Asp6(FCN))) -> Result
+ ++ c05nbf(n,lwa,x,xtol,ifail,fcn)
+ ++ is an easy-to-use routine to find a solution of a system
+ ++ of nonlinear equations by a modification of the Powell hybrid
+ ++ method.
+ ++ See \downlink{Manual Page}{manpageXXc05nbf}.
+ c05pbf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ DoubleFloat,Integer,Union(fn:FileName,fp:Asp35(FCN))) -> Result
+ ++ c05pbf(n,ldfjac,lwa,x,xtol,ifail,fcn)
+ ++ is an easy-to-use routine to find a solution of a system
+ ++ of nonlinear equations by a modification of the Powell hybrid
+ ++ method. The user must provide the Jacobian.
+ ++ See \downlink{Manual Page}{manpageXXc05pbf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import FortranPackage
+ import Union(fn:FileName,fp:Asp1(F))
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Integer)
+
+
+ c05adf(aArg:DoubleFloat,bArg:DoubleFloat,epsArg:DoubleFloat,_
+ etaArg:DoubleFloat,ifailArg:Integer,fArg:Union(fn:FileName,fp:Asp1(F))): Result ==
+ pushFortranOutputStack(fFilename := aspFilename "f")$FOP
+ if fArg case fn
+ then outputAsFortran(fArg.fn)
+ else outputAsFortran(fArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fFilename]$Lisp,_
+ "c05adf",_
+ ["a"::S,"b"::S,"eps"::S,"eta"::S,"x"::S_
+ ,"ifail"::S,"f"::S]$Lisp,_
+ ["x"::S,"f"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"eps"::S,"eta"::S_
+ ,"x"::S,"f"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,epsArg::Any,etaArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c05nbf(nArg:Integer,lwaArg:Integer,xArg:Matrix DoubleFloat,_
+ xtolArg:DoubleFloat,ifailArg:Integer,fcnArg:Union(fn:FileName,fp:Asp6(FCN))): Result ==
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fcnFilename]$Lisp,_
+ "c05nbf",_
+ ["n"::S,"lwa"::S,"xtol"::S,"ifail"::S,"fcn"::S_
+ ,"fvec"::S,"x"::S,"wa"::S]$Lisp,_
+ ["fvec"::S,"wa"::S,"fcn"::S]$Lisp,_
+ [["double"::S,["fvec"::S,"n"::S]$Lisp,["x"::S,"n"::S]$Lisp_
+ ,"xtol"::S,["wa"::S,"lwa"::S]$Lisp,"fcn"::S]$Lisp_
+ ,["integer"::S,"n"::S,"lwa"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["fvec"::S,"x"::S,"xtol"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,lwaArg::Any,xtolArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c05pbf(nArg:Integer,ldfjacArg:Integer,lwaArg:Integer,_
+ xArg:Matrix DoubleFloat,xtolArg:DoubleFloat,ifailArg:Integer,_
+ fcnArg:Union(fn:FileName,fp:Asp35(FCN))): Result ==
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fcnFilename]$Lisp,_
+ "c05pbf",_
+ ["n"::S,"ldfjac"::S,"lwa"::S,"xtol"::S,"ifail"::S_
+ ,"fcn"::S,"fvec"::S,"fjac"::S,"x"::S,"wa"::S]$Lisp,_
+ ["fvec"::S,"fjac"::S,"wa"::S,"fcn"::S]$Lisp,_
+ [["double"::S,["fvec"::S,"n"::S]$Lisp,["fjac"::S,"ldfjac"::S,"n"::S]$Lisp_
+ ,["x"::S,"n"::S]$Lisp,"xtol"::S,["wa"::S,"lwa"::S]$Lisp,"fcn"::S]$Lisp_
+ ,["integer"::S,"n"::S,"ldfjac"::S,"lwa"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["fvec"::S,"fjac"::S,"x"::S,"xtol"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ldfjacArg::Any,lwaArg::Any,xtolArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGC05 NagRootFindingPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/c06.spad.pamphlet b/src/algebra/c06.spad.pamphlet
new file mode 100644
index 00000000..be504dde
--- /dev/null
+++ b/src/algebra/c06.spad.pamphlet
@@ -0,0 +1,339 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra c06.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGC06 NagSeriesSummationPackage}
+<<package NAGC06 NagSeriesSummationPackage>>=
+)abbrev package NAGC06 NagSeriesSummationPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:30 1994
+++Description:
+++This package uses the NAG Library to calculate the discrete Fourier
+++transform of a sequence of real or complex data values, and
+++applies it to calculate convolutions and correlations.
+++See \downlink{Manual Page}{manpageXXc06}.
+
+NagSeriesSummationPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ c06eaf : (Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ c06eaf(n,x,ifail)
+ ++ calculates the discrete Fourier transform of a sequence of
+ ++ n real data values. (No extra workspace required.)
+ ++ See \downlink{Manual Page}{manpageXXc06eaf}.
+ c06ebf : (Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ c06ebf(n,x,ifail)
+ ++ calculates the discrete Fourier transform of a Hermitian
+ ++ sequence of n complex data values. (No extra workspace required.)
+ ++ See \downlink{Manual Page}{manpageXXc06ebf}.
+ c06ecf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ c06ecf(n,x,y,ifail)
+ ++ calculates the discrete Fourier transform of a sequence of
+ ++ n complex data values. (No extra workspace required.)
+ ++ See \downlink{Manual Page}{manpageXXc06ecf}.
+ c06ekf : (Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Integer) -> Result
+ ++ c06ekf(job,n,x,y,ifail)
+ ++ calculates the circular convolution of two
+ ++ real vectors of period n. No extra workspace is required.
+ ++ See \downlink{Manual Page}{manpageXXc06ekf}.
+ c06fpf : (Integer,Integer,String,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ c06fpf(m,n,init,x,trig,ifail)
+ ++ computes the discrete Fourier transforms of m sequences,
+ ++ each containing n real data values. This routine is designed to
+ ++ be particularly efficient on vector processors.
+ ++ See \downlink{Manual Page}{manpageXXc06fpf}.
+ c06fqf : (Integer,Integer,String,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ c06fqf(m,n,init,x,trig,ifail)
+ ++ computes the discrete Fourier transforms of m Hermitian
+ ++ sequences, each containing n complex data values. This routine is
+ ++ designed to be particularly efficient on vector processors.
+ ++ See \downlink{Manual Page}{manpageXXc06fqf}.
+ c06frf : (Integer,Integer,String,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ c06frf(m,n,init,x,y,trig,ifail)
+ ++ computes the discrete Fourier transforms of m sequences,
+ ++ each containing n complex data values. This routine is designed
+ ++ to be particularly efficient on vector processors.
+ ++ See \downlink{Manual Page}{manpageXXc06frf}.
+ c06fuf : (Integer,Integer,String,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ c06fuf(m,n,init,x,y,trigm,trign,ifail)
+ ++ computes the two-dimensional discrete Fourier transform of
+ ++ a bivariate sequence of complex data values. This routine is
+ ++ designed to be particularly efficient on vector processors.
+ ++ See \downlink{Manual Page}{manpageXXc06fuf}.
+ c06gbf : (Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ c06gbf(n,x,ifail)
+ ++ forms the complex conjugate of n
+ ++ data values.
+ ++ See \downlink{Manual Page}{manpageXXc06gbf}.
+ c06gcf : (Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ c06gcf(n,y,ifail)
+ ++ forms the complex conjugate of a sequence of n data
+ ++ values.
+ ++ See \downlink{Manual Page}{manpageXXc06gcf}.
+ c06gqf : (Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ c06gqf(m,n,x,ifail)
+ ++ forms the complex conjugates,
+ ++ each containing n data values.
+ ++ See \downlink{Manual Page}{manpageXXc06gqf}.
+ c06gsf : (Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ c06gsf(m,n,x,ifail)
+ ++ takes m Hermitian sequences, each containing n data
+ ++ values, and forms the real and imaginary parts of the m
+ ++ corresponding complex sequences.
+ ++ See \downlink{Manual Page}{manpageXXc06gsf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(String)
+ import AnyFunctions1(Matrix DoubleFloat)
+
+
+ c06eaf(nArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06eaf",_
+ ["n"::S,"ifail"::S,"x"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+
+ c06ebf(nArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06ebf",_
+ ["n"::S,"ifail"::S,"x"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06ecf(nArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06ecf",_
+ ["n"::S,"ifail"::S,"x"::S,"y"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["y"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"y"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,xArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06ekf(jobArg:Integer,nArg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06ekf",_
+ ["job"::S,"n"::S,"ifail"::S,"x"::S,"y"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["y"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"job"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"y"::S,"ifail"::S]$Lisp,_
+ [([jobArg::Any,nArg::Any,ifailArg::Any,xArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06fpf(mArg:Integer,nArg:Integer,initArg:String,_
+ xArg:Matrix DoubleFloat,trigArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06fpf",_
+ ["m"::S,"n"::S,"init"::S,"ifail"::S,"x"::S,"trig"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["x"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp_
+ ,["trig"::S,["*"::S,2$Lisp,"n"::S]$Lisp]$Lisp,["work"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"init"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"trig"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,initArg::Any,ifailArg::Any,xArg::Any,trigArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06fqf(mArg:Integer,nArg:Integer,initArg:String,_
+ xArg:Matrix DoubleFloat,trigArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06fqf",_
+ ["m"::S,"n"::S,"init"::S,"ifail"::S,"x"::S,"trig"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["x"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp_
+ ,["trig"::S,["*"::S,2$Lisp,"n"::S]$Lisp]$Lisp,["work"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"init"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"trig"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,initArg::Any,ifailArg::Any,xArg::Any,trigArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06frf(mArg:Integer,nArg:Integer,initArg:String,_
+ xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,trigArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06frf",_
+ ["m"::S,"n"::S,"init"::S,"ifail"::S,"x"::S,"y"::S,"trig"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["x"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp_
+ ,["y"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp,["trig"::S,["*"::S,2$Lisp,"n"::S]$Lisp]$Lisp,["work"::S,["*"::S,["*"::S,2$Lisp,"m"::S]$Lisp,"n"::S]$Lisp]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"init"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"y"::S,"trig"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,initArg::Any,ifailArg::Any,xArg::Any,yArg::Any,trigArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06fuf(mArg:Integer,nArg:Integer,initArg:String,_
+ xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,trigmArg:Matrix DoubleFloat,_
+ trignArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06fuf",_
+ ["m"::S,"n"::S,"init"::S,"ifail"::S,"x"::S,"y"::S,"trigm"::S,"trign"::S,"work"::S_
+ ]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["x"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp_
+ ,["y"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp,["trigm"::S,["*"::S,2$Lisp,"m"::S]$Lisp]$Lisp,["trign"::S,["*"::S,2$Lisp,"n"::S]$Lisp]$Lisp_
+ ,["work"::S,["*"::S,["*"::S,2$Lisp,"m"::S]$Lisp,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"init"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"y"::S,"trigm"::S,"trign"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,initArg::Any,ifailArg::Any,xArg::Any,yArg::Any,trigmArg::Any,trignArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06gbf(nArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06gbf",_
+ ["n"::S,"ifail"::S,"x"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06gcf(nArg:Integer,yArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06gcf",_
+ ["n"::S,"ifail"::S,"y"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["y"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["y"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06gqf(mArg:Integer,nArg:Integer,xArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06gqf",_
+ ["m"::S,"n"::S,"ifail"::S,"x"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["x"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ c06gsf(mArg:Integer,nArg:Integer,xArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "c06gsf",_
+ ["m"::S,"n"::S,"ifail"::S,"x"::S,"u"::S,"v"::S]$Lisp,_
+ ["u"::S,"v"::S]$Lisp,_
+ [["double"::S,["x"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp_
+ ,["u"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp,["v"::S,["*"::S,"m"::S,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["u"::S,"v"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGC06 NagSeriesSummationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/card.spad.pamphlet b/src/algebra/card.spad.pamphlet
new file mode 100644
index 00000000..a1585083
--- /dev/null
+++ b/src/algebra/card.spad.pamphlet
@@ -0,0 +1,206 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra card.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain CARD CardinalNumber}
+<<domain CARD CardinalNumber>>=
+)abbrev domain CARD CardinalNumber
+++ Author: S.M. Watt
+++ Date Created: June 1986
+++ Date Last Updated: May 1990
+++ Basic Operations: Aleph, +, -, *, **
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: cardinal number, transfinite arithmetic
+++ Examples:
+++ References:
+++ Goedel, "The consistency of the continuum hypothesis",
+++ Ann. Math. Studies, Princeton Univ. Press, 1940
+++ Description:
+++ Members of the domain CardinalNumber are values indicating the
+++ cardinality of sets, both finite and infinite. Arithmetic operations
+++ are defined on cardinal numbers as follows.
+++
+++ If \spad{x = #X} and \spad{y = #Y} then
+++ \spad{x+y = #(X+Y)} \tab{30}disjoint union
+++ \spad{x-y = #(X-Y)} \tab{30}relative complement
+++ \spad{x*y = #(X*Y)} \tab{30}cartesian product
+++ \spad{x**y = #(X**Y)} \tab{30}\spad{X**Y = \{g| g:Y->X\}}
+++
+++ The non-negative integers have a natural construction as cardinals
+++ \spad{0 = #\{\}}, \spad{1 = \{0\}}, \spad{2 = \{0, 1\}}, ..., \spad{n = \{i| 0 <= i < n\}}.
+++
+++ That \spad{0} acts as a zero for the multiplication of cardinals is
+++ equivalent to the axiom of choice.
+++
+++ The generalized continuum hypothesis asserts
+++ \center{\spad{2**Aleph i = Aleph(i+1)}}
+++ and is independent of the axioms of set theory [Goedel 1940].
+++
+++ Three commonly encountered cardinal numbers are
+++ \spad{a = #Z} \tab{30}countable infinity
+++ \spad{c = #R} \tab{30}the continuum
+++ \spad{f = #\{g| g:[0,1]->R\}}
+++
+++ In this domain, these values are obtained using
+++ \spad{a := Aleph 0}, \spad{c := 2**a}, \spad{f := 2**c}.
+++
+CardinalNumber: Join(OrderedSet, AbelianMonoid, Monoid,
+ RetractableTo NonNegativeInteger) with
+ commutative "*"
+ ++ a domain D has \spad{commutative("*")} if it has an operation
+ ++ \spad{"*": (D,D) -> D} which is commutative.
+ "-": (%,%) -> Union(%,"failed")
+ ++ \spad{x - y} returns an element z such that \spad{z+y=x} or "failed"
+ ++ if no such element exists.
+ "**": (%, %) -> %
+ ++ \spad{x**y} returns \spad{#(X**Y)} where \spad{X**Y} is defined
+ ++ as \spad{\{g| g:Y->X\}}.
+
+ Aleph: NonNegativeInteger -> %
+ ++ Aleph(n) provides the named (infinite) cardinal number.
+
+ finite?: % -> Boolean
+ ++ finite?(\spad{a}) determines whether
+ ++ \spad{a} is a finite cardinal,
+ ++ i.e. an integer.
+
+ countable?: % -> Boolean
+ ++ countable?(\spad{a}) determines
+ ++ whether \spad{a} is a countable cardinal,
+ ++ i.e. an integer or \spad{Aleph 0}.
+
+ generalizedContinuumHypothesisAssumed?: () -> Boolean
+ ++ generalizedContinuumHypothesisAssumed?()
+ ++ tests if the hypothesis is currently assumed.
+
+ generalizedContinuumHypothesisAssumed: Boolean -> Boolean
+ ++ generalizedContinuumHypothesisAssumed(bool)
+ ++ is used to dictate whether the hypothesis is to be assumed.
+ == add
+ NNI ==> NonNegativeInteger
+ FINord ==> -1
+ DUMMYval ==> -1
+
+ Rep := Record(order: Integer, ival: Integer)
+
+ GCHypothesis: Reference(Boolean) := ref false
+
+ -- Creation
+ 0 == [FINord, 0]
+ 1 == [FINord, 1]
+ coerce(n:NonNegativeInteger):% == [FINord, n]
+ Aleph n == [n, DUMMYval]
+
+ -- Output
+ ALEPHexpr := "Aleph"::OutputForm
+
+ coerce(x: %): OutputForm ==
+ x.order = FINord => (x.ival)::OutputForm
+ prefix(ALEPHexpr, [(x.order)::OutputForm])
+
+ -- Manipulation
+ x = y ==
+ x.order ^= y.order => false
+ finite? x => x.ival = y.ival
+ true -- equal transfinites
+ x < y ==
+ x.order < y.order => true
+ x.order > y.order => false
+ finite? x => x.ival < y.ival
+ false -- equal transfinites
+ x:% + y:% ==
+ finite? x and finite? y => [FINord, x.ival+y.ival]
+ max(x, y)
+ x - y ==
+ x < y => "failed"
+ finite? x => [FINord, x.ival-y.ival]
+ x > y => x
+ "failed" -- equal transfinites
+ x:% * y:% ==
+ finite? x and finite? y => [FINord, x.ival*y.ival]
+ x = 0 or y = 0 => 0
+ max(x, y)
+ n:NonNegativeInteger * x:% ==
+ finite? x => [FINord, n*x.ival]
+ n = 0 => 0
+ x
+ x**y ==
+ y = 0 =>
+ x ^= 0 => 1
+ error "0**0 not defined for cardinal numbers."
+ finite? y =>
+ not finite? x => x
+ [FINord,x.ival**(y.ival):NNI]
+ x = 0 => 0
+ x = 1 => 1
+ GCHypothesis() => [max(x.order-1, y.order) + 1, DUMMYval]
+ error "Transfinite exponentiation only implemented under GCH"
+
+ finite? x == x.order = FINord
+ countable? x == x.order < 1
+
+ retract(x:%):NonNegativeInteger ==
+ finite? x => (x.ival)::NNI
+ error "Not finite"
+
+ retractIfCan(x:%):Union(NonNegativeInteger, "failed") ==
+ finite? x => (x.ival)::NNI
+ "failed"
+
+ -- State manipulation
+ generalizedContinuumHypothesisAssumed?() == GCHypothesis()
+ generalizedContinuumHypothesisAssumed b == (GCHypothesis() := b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain CARD CardinalNumber>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/carten.spad.pamphlet b/src/algebra/carten.spad.pamphlet
new file mode 100644
index 00000000..0f1d2952
--- /dev/null
+++ b/src/algebra/carten.spad.pamphlet
@@ -0,0 +1,684 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra carten.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category GRMOD GradedModule}
+<<category GRMOD GradedModule>>=
+)abbrev category GRMOD GradedModule
+++ Author: Stephen M. Watt
+++ Date Created: May 20, 1991
+++ Date Last Updated: May 20, 1991
+++ Basic Operations: +, *, degree
+++ Related Domains: CartesianTensor(n,dim,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: graded module, tensor, multi-linear algebra
+++ Examples:
+++ References: Algebra 2d Edition, MacLane and Birkhoff, MacMillan 1979
+++ Description:
+++ GradedModule(R,E) denotes ``E-graded R-module'', i.e. collection of
+++ R-modules indexed by an abelian monoid E.
+++ An element \spad{g} of \spad{G[s]} for some specific \spad{s} in \spad{E}
+++ is said to be an element of \spad{G} with {\em degree} \spad{s}.
+++ Sums are defined in each module \spad{G[s]} so two elements of \spad{G}
+++ have a sum if they have the same degree.
+++
+++ Morphisms can be defined and composed by degree to give the
+++ mathematical category of graded modules.
+
+GradedModule(R: CommutativeRing, E: AbelianMonoid): Category ==
+ SetCategory with
+ degree: % -> E
+ ++ degree(g) names the degree of g. The set of all elements
+ ++ of a given degree form an R-module.
+ 0: constant -> %
+ ++ 0 denotes the zero of degree 0.
+ _*: (R, %) -> %
+ ++ r*g is left module multiplication.
+ _*: (%, R) -> %
+ ++ g*r is right module multiplication.
+
+ _-: % -> %
+ ++ -g is the additive inverse of g in the module of elements
+ ++ of the same grade as g.
+ _+: (%, %) -> %
+ ++ g+h is the sum of g and h in the module of elements of
+ ++ the same degree as g and h. Error: if g and h
+ ++ have different degrees.
+ _-: (%, %) -> %
+ ++ g-h is the difference of g and h in the module of elements of
+ ++ the same degree as g and h. Error: if g and h
+ ++ have different degrees.
+ add
+ (x: %) - (y: %) == x+(-y)
+
+@
+\section{category GRALG GradedAlgebra}
+<<category GRALG GradedAlgebra>>=
+)abbrev category GRALG GradedAlgebra
+++ Author: Stephen M. Watt
+++ Date Created: May 20, 1991
+++ Date Last Updated: May 20, 1991
+++ Basic Operations: +, *, degree
+++ Related Domains: CartesianTensor(n,dim,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: graded module, tensor, multi-linear algebra
+++ Examples:
+++ References: Encyclopedic Dictionary of Mathematics, MIT Press, 1977
+++ Description:
+++ GradedAlgebra(R,E) denotes ``E-graded R-algebra''.
+++ A graded algebra is a graded module together with a degree preserving
+++ R-linear map, called the {\em product}.
+++
+++ The name ``product'' is written out in full so inner and outer products
+++ with the same mapping type can be distinguished by name.
+
+GradedAlgebra(R: CommutativeRing, E: AbelianMonoid): Category ==
+ Join(GradedModule(R, E),RetractableTo(R)) with
+ 1: constant -> %
+ ++ 1 is the identity for \spad{product}.
+ product: (%, %) -> %
+ ++ product(a,b) is the degree-preserving R-linear product:
+ ++
+ ++ \spad{degree product(a,b) = degree a + degree b}
+ ++ \spad{product(a1+a2,b) = product(a1,b) + product(a2,b)}
+ ++ \spad{product(a,b1+b2) = product(a,b1) + product(a,b2)}
+ ++ \spad{product(r*a,b) = product(a,r*b) = r*product(a,b)}
+ ++ \spad{product(a,product(b,c)) = product(product(a,b),c)}
+ add
+ if not (R is %) then
+ 0: % == (0$R)::%
+ 1: % == 1$R::%
+ (r: R)*(x: %) == product(r::%, x)
+ (x: %)*(r: R) == product(x, r::%)
+
+@
+\section{domain CARTEN CartesianTensor}
+<<domain CARTEN CartesianTensor>>=
+)abbrev domain CARTEN CartesianTensor
+++ Author: Stephen M. Watt
+++ Date Created: December 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: tensor, graded algebra
+++ Examples:
+++ References:
+++ Description:
+++ CartesianTensor(minix,dim,R) provides Cartesian tensors with
+++ components belonging to a commutative ring R. These tensors
+++ can have any number of indices. Each index takes values from
+++ \spad{minix} to \spad{minix + dim - 1}.
+
+CartesianTensor(minix, dim, R): Exports == Implementation where
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ DP ==> DirectProduct
+ SM ==> SquareMatrix
+
+ minix: Integer
+ dim: NNI
+ R: CommutativeRing
+
+ Exports ==> Join(GradedAlgebra(R, NNI), GradedModule(I, NNI)) with
+
+ coerce: DP(dim, R) -> %
+ ++ coerce(v) views a vector as a rank 1 tensor.
+ coerce: SM(dim, R) -> %
+ ++ coerce(m) views a matrix as a rank 2 tensor.
+
+ coerce: List R -> %
+ ++ coerce([r_1,...,r_dim]) allows tensors to be constructed
+ ++ using lists.
+
+ coerce: List % -> %
+ ++ coerce([t_1,...,t_dim]) allows tensors to be constructed
+ ++ using lists.
+
+ rank: % -> NNI
+ ++ rank(t) returns the tensorial rank of t (that is, the
+ ++ number of indices). This is the same as the graded module
+ ++ degree.
+
+ elt: (%) -> R
+ ++ elt(t) gives the component of a rank 0 tensor.
+ elt: (%, I) -> R
+ ++ elt(t,i) gives a component of a rank 1 tensor.
+ elt: (%, I, I) -> R
+ ++ elt(t,i,j) gives a component of a rank 2 tensor.
+ elt: (%, I, I, I) -> R
+ ++ elt(t,i,j,k) gives a component of a rank 3 tensor.
+ elt: (%, I, I, I, I) -> R
+ ++ elt(t,i,j,k,l) gives a component of a rank 4 tensor.
+
+ elt: (%, List I) -> R
+ ++ elt(t,[i1,...,iN]) gives a component of a rank \spad{N} tensor.
+
+ -- This specializes the documentation from GradedAlgebra.
+ product: (%,%) -> %
+ ++ product(s,t) is the outer product of the tensors s and t.
+ ++ For example, if \spad{r = product(s,t)} for rank 2 tensors s and t,
+ ++ then \spad{r} is a rank 4 tensor given by
+ ++ \spad{r(i,j,k,l) = s(i,j)*t(k,l)}.
+
+ "*": (%, %) -> %
+ ++ s*t is the inner product of the tensors s and t which contracts
+ ++ the last index of s with the first index of t, i.e.
+ ++ \spad{t*s = contract(t,rank t, s, 1)}
+ ++ \spad{t*s = sum(k=1..N, t[i1,..,iN,k]*s[k,j1,..,jM])}
+ ++ This is compatible with the use of \spad{M*v} to denote
+ ++ the matrix-vector inner product.
+
+ contract: (%, Integer, %, Integer) -> %
+ ++ contract(t,i,s,j) is the inner product of tenors s and t
+ ++ which sums along the \spad{k1}-th index of
+ ++ t and the \spad{k2}-th index of s.
+ ++ For example, if \spad{r = contract(s,2,t,1)} for rank 3 tensors
+ ++ rank 3 tensors \spad{s} and \spad{t}, then \spad{r} is
+ ++ the rank 4 \spad{(= 3 + 3 - 2)} tensor given by
+ ++ \spad{r(i,j,k,l) = sum(h=1..dim,s(i,h,j)*t(h,k,l))}.
+
+ contract: (%, Integer, Integer) -> %
+ ++ contract(t,i,j) is the contraction of tensor t which
+ ++ sums along the \spad{i}-th and \spad{j}-th indices.
+ ++ For example, if
+ ++ \spad{r = contract(t,1,3)} for a rank 4 tensor t, then
+ ++ \spad{r} is the rank 2 \spad{(= 4 - 2)} tensor given by
+ ++ \spad{r(i,j) = sum(h=1..dim,t(h,i,h,j))}.
+
+ transpose: % -> %
+ ++ transpose(t) exchanges the first and last indices of t.
+ ++ For example, if \spad{r = transpose(t)} for a rank 4 tensor t, then
+ ++ \spad{r} is the rank 4 tensor given by
+ ++ \spad{r(i,j,k,l) = t(l,j,k,i)}.
+
+ transpose: (%, Integer, Integer) -> %
+ ++ transpose(t,i,j) exchanges the \spad{i}-th and \spad{j}-th indices of t.
+ ++ For example, if \spad{r = transpose(t,2,3)} for a rank 4 tensor t, then
+ ++ \spad{r} is the rank 4 tensor given by
+ ++ \spad{r(i,j,k,l) = t(i,k,j,l)}.
+
+ reindex: (%, List Integer) -> %
+ ++ reindex(t,[i1,...,idim]) permutes the indices of t.
+ ++ For example, if \spad{r = reindex(t, [4,1,2,3])}
+ ++ for a rank 4 tensor t,
+ ++ then \spad{r} is the rank for tensor given by
+ ++ \spad{r(i,j,k,l) = t(l,i,j,k)}.
+
+ kroneckerDelta: () -> %
+ ++ kroneckerDelta() is the rank 2 tensor defined by
+ ++ \spad{kroneckerDelta()(i,j)}
+ ++ \spad{= 1 if i = j}
+ ++ \spad{= 0 if i \^= j}
+
+ leviCivitaSymbol: () -> %
+ ++ leviCivitaSymbol() is the rank \spad{dim} tensor defined by
+ ++ \spad{leviCivitaSymbol()(i1,...idim) = +1/0/-1}
+ ++ if \spad{i1,...,idim} is an even/is nota /is an odd permutation
+ ++ of \spad{minix,...,minix+dim-1}.
+ ravel: % -> List R
+ ++ ravel(t) produces a list of components from a tensor such that
+ ++ \spad{unravel(ravel(t)) = t}.
+
+ unravel: List R -> %
+ ++ unravel(t) produces a tensor from a list of
+ ++ components such that
+ ++ \spad{unravel(ravel(t)) = t}.
+
+ sample: () -> %
+ ++ sample() returns an object of type %.
+
+ Implementation ==> add
+
+ PERM ==> Vector Integer -- 1-based entries from 1..n
+ INDEX ==> Vector Integer -- 1-based entries from minix..minix+dim-1
+
+
+ get ==> elt$Rep
+ set_! ==> setelt$Rep
+
+ -- Use row-major order:
+ -- x[h,i,j] <-> x[(h-minix)*dim**2+(i-minix)*dim+(j-minix)]
+
+ Rep := IndexedVector(R,0)
+
+ n: Integer
+ r,s: R
+ x,y,z: %
+
+ ---- Local stuff
+ dim2: NNI := dim**2
+ dim3: NNI := dim**3
+ dim4: NNI := dim**4
+
+ sample()==kroneckerDelta()$%
+ int2index(n: Integer, indv: INDEX): INDEX ==
+ n < 0 => error "Index error (too small)"
+ rnk := #indv
+ for i in 1..rnk repeat
+ qr := divide(n, dim)
+ n := qr.quotient
+ indv.((rnk-i+1) pretend NNI) := qr.remainder + minix
+ n ^= 0 => error "Index error (too big)"
+ indv
+
+ index2int(indv: INDEX): Integer ==
+ n: I := 0
+ for i in 1..#indv repeat
+ ix := indv.i - minix
+ ix<0 or ix>dim-1 => error "Index error (out of range)"
+ n := dim*n + ix
+ n
+
+ lengthRankOrElse(v: Integer): NNI ==
+ v = 1 => 0
+ v = dim => 1
+ v = dim2 => 2
+ v = dim3 => 3
+ v = dim4 => 4
+ rx := 0
+ while v ^= 0 repeat
+ qr := divide(v, dim)
+ v := qr.quotient
+ if v ^= 0 then
+ qr.remainder ^= 0 => error "Rank is not a whole number"
+ rx := rx + 1
+ rx
+
+ -- l must be a list of the numbers 1..#l
+ mkPerm(n: NNI, l: List Integer): PERM ==
+ #l ^= n =>
+ error "The list is not a permutation."
+ p: PERM := new(n, 0)
+ seen: Vector Boolean := new(n, false)
+ for i in 1..n for e in l repeat
+ e < 1 or e > n => error "The list is not a permutation."
+ p.i := e
+ seen.e := true
+ for e in 1..n repeat
+ not seen.e => error "The list is not a permutation."
+ p
+
+ -- permute s according to p into result t.
+ permute_!(t: INDEX, s: INDEX, p: PERM): INDEX ==
+ for i in 1..#p repeat t.i := s.(p.i)
+ t
+
+ -- permsign!(v) = 1, 0, or -1 according as
+ -- v is an even, is not, or is an odd permutation of minix..minix+#v-1.
+ permsign_!(v: INDEX): Integer ==
+ -- sum minix..minix+#v-1.
+ maxix := minix+#v-1
+ psum := (((maxix+1)*maxix - minix*(minix-1)) exquo 2)::Integer
+ -- +/v ^= psum => 0
+ n := 0
+ for i in 1..#v repeat n := n + v.i
+ n ^= psum => 0
+ -- Bubble sort! This is pretty grotesque.
+ totTrans: Integer := 0
+ nTrans: Integer := 1
+ while nTrans ^= 0 repeat
+ nTrans := 0
+ for i in 1..#v-1 for j in 2..#v repeat
+ if v.i > v.j then
+ nTrans := nTrans + 1
+ e := v.i; v.i := v.j; v.j := e
+ totTrans := totTrans + nTrans
+ for i in 1..dim repeat
+ if v.i ^= minix+i-1 then return 0
+ odd? totTrans => -1
+ 1
+
+
+ ---- Exported functions
+ ravel x ==
+ [get(x,i) for i in 0..#x-1]
+
+ unravel l ==
+ -- lengthRankOrElse #l gives sytnax error
+ nz: NNI := # l
+ lengthRankOrElse nz
+ z := new(nz, 0)
+ for i in 0..nz-1 for r in l repeat set_!(z, i, r)
+ z
+
+ kroneckerDelta() ==
+ z := new(dim2, 0)
+ for i in 1..dim for zi in 0.. by (dim+1) repeat set_!(z, zi, 1)
+ z
+ leviCivitaSymbol() ==
+ nz := dim**dim
+ z := new(nz, 0)
+ indv: INDEX := new(dim, 0)
+ for i in 0..nz-1 repeat
+ set_!(z, i, permsign_!(int2index(i, indv))::R)
+ z
+
+ -- from GradedModule
+ degree x ==
+ rank x
+
+ rank x ==
+ n := #x
+ lengthRankOrElse n
+
+ elt(x) ==
+ #x ^= 1 => error "Index error (the rank is not 0)"
+ get(x,0)
+ elt(x, i: I) ==
+ #x ^= dim => error "Index error (the rank is not 1)"
+ get(x,(i-minix))
+ elt(x, i: I, j: I) ==
+ #x ^= dim2 => error "Index error (the rank is not 2)"
+ get(x,(dim*(i-minix) + (j-minix)))
+ elt(x, i: I, j: I, k: I) ==
+ #x ^= dim3 => error "Index error (the rank is not 3)"
+ get(x,(dim2*(i-minix) + dim*(j-minix) + (k-minix)))
+ elt(x, i: I, j: I, k: I, l: I) ==
+ #x ^= dim4 => error "Index error (the rank is not 4)"
+ get(x,(dim3*(i-minix) + dim2*(j-minix) + dim*(k-minix) + (l-minix)))
+
+ elt(x, i: List I) ==
+ #i ^= rank x => error "Index error (wrong rank)"
+ n: I := 0
+ for ii in i repeat
+ ix := ii - minix
+ ix<0 or ix>dim-1 => error "Index error (out of range)"
+ n := dim*n + ix
+ get(x,n)
+
+ coerce(lr: List R): % ==
+ #lr ^= dim => error "Incorrect number of components"
+ z := new(dim, 0)
+ for r in lr for i in 0..dim-1 repeat set_!(z, i, r)
+ z
+ coerce(lx: List %): % ==
+ #lx ^= dim => error "Incorrect number of slices"
+ rx := rank first lx
+ for x in lx repeat
+ rank x ^= rx => error "Inhomogeneous slice ranks"
+ nx := # first lx
+ z := new(dim * nx, 0)
+ for x in lx for offz in 0.. by nx repeat
+ for i in 0..nx-1 repeat set_!(z, offz + i, get(x,i))
+ z
+
+ retractIfCan(x:%):Union(R,"failed") ==
+ zero? rank(x) => x()
+ "failed"
+ Outf ==> OutputForm
+
+ mkOutf(x:%, i0:I, rnk:NNI): Outf ==
+ odd? rnk =>
+ rnk1 := (rnk-1) pretend NNI
+ nskip := dim**rnk1
+ [mkOutf(x, i0+nskip*i, rnk1) for i in 0..dim-1]::Outf
+ rnk = 0 =>
+ get(x,i0)::Outf
+ rnk1 := (rnk-2) pretend NNI
+ nskip := dim**rnk1
+ matrix [[mkOutf(x, i0+nskip*(dim*i + j), rnk1)
+ for j in 0..dim-1] for i in 0..dim-1]
+ coerce(x): Outf ==
+ mkOutf(x, 0, rank x)
+
+ 0 == 0$R::Rep
+ 1 == 1$R::Rep
+
+ --coerce(n: I): % == new(1, n::R)
+ coerce(r: R): % == new(1,r)
+
+ coerce(v: DP(dim,R)): % ==
+ z := new(dim, 0)
+ for i in 0..dim-1 for j in minIndex v .. maxIndex v repeat
+ set_!(z, i, v.j)
+ z
+ coerce(m: SM(dim,R)): % ==
+ z := new(dim**2, 0)
+ offz := 0
+ for i in 0..dim-1 repeat
+ for j in 0..dim-1 repeat
+ set_!(z, offz + j, m(i+1,j+1))
+ offz := offz + dim
+ z
+
+ x = y ==
+ #x ^= #y => false
+ for i in 0..#x-1 repeat
+ if get(x,i) ^= get(y,i) then return false
+ true
+ x + y ==
+ #x ^= #y => error "Rank mismatch"
+ -- z := [xi + yi for xi in x for yi in y]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, get(x,i) + get(y,i))
+ z
+ x - y ==
+ #x ^= #y => error "Rank mismatch"
+ -- [xi - yi for xi in x for yi in y]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, get(x,i) - get(y,i))
+ z
+ - x ==
+ -- [-xi for xi in x]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, -get(x,i))
+ z
+ n * x ==
+ -- [n * xi for xi in x]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, n * get(x,i))
+ z
+ x * n ==
+ -- [n * xi for xi in x]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, n* get(x,i)) -- Commutative!!
+ z
+ r * x ==
+ -- [r * xi for xi in x]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, r * get(x,i))
+ z
+ x * r ==
+ -- [xi*r for xi in x]
+ z := new(#x, 0)
+ for i in 0..#x-1 repeat set_!(z, i, r* get(x,i)) -- Commutative!!
+ z
+ product(x, y) ==
+ nx := #x; ny := #y
+ z := new(nx * ny, 0)
+ for i in 0..nx-1 for ioff in 0.. by ny repeat
+ for j in 0..ny-1 repeat
+ set_!(z, ioff + j, get(x,i) * get(y,j))
+ z
+ x * y ==
+ rx := rank x
+ ry := rank y
+ rx = 0 => get(x,0) * y
+ ry = 0 => x * get(y,0)
+ contract(x, rx, y, 1)
+
+ contract(x, i, j) ==
+ rx := rank x
+ i < 1 or i > rx or j < 1 or j > rx or i = j =>
+ error "Improper index for contraction"
+ if i > j then (i,j) := (j,i)
+
+ rl:= (rx- j) pretend NNI; nl:= dim**rl; zol:= 1; xol:= zol
+ rm:= (j-i-1) pretend NNI; nm:= dim**rm; zom:= nl; xom:= zom*dim
+ rh:= (i - 1) pretend NNI; nh:= dim**rh; zoh:= nl*nm
+ xoh:= zoh*dim**2
+ xok := nl*(1 + nm*dim)
+ z := new(nl*nm*nh, 0)
+ for h in 1..nh _
+ for xh in 0.. by xoh for zh in 0.. by zoh repeat
+ for m in 1..nm _
+ for xm in xh.. by xom for zm in zh.. by zom repeat
+ for l in 1..nl _
+ for xl in xm.. by xol for zl in zm.. by zol repeat
+ set_!(z, zl, 0)
+ for k in 1..dim for xk in xl.. by xok repeat
+ set_!(z, zl, get(z,zl) + get(x,xk))
+ z
+
+ contract(x, i, y, j) ==
+ rx := rank x
+ ry := rank y
+
+ i < 1 or i > rx or j < 1 or j > ry =>
+ error "Improper index for contraction"
+
+ rly:= (ry-j) pretend NNI; nly:= dim**rly; oly:= 1; zoly:= 1
+ rhy:= (j -1) pretend NNI; nhy:= dim**rhy
+ ohy:= nly*dim; zohy:= zoly*nly
+ rlx:= (rx-i) pretend NNI; nlx:= dim**rlx
+ olx:= 1; zolx:= zohy*nhy
+ rhx:= (i -1) pretend NNI; nhx:= dim**rhx
+ ohx:= nlx*dim; zohx:= zolx*nlx
+
+ z := new(nlx*nhx*nly*nhy, 0)
+
+ for dxh in 1..nhx _
+ for xh in 0.. by ohx for zhx in 0.. by zohx repeat
+ for dxl in 1..nlx _
+ for xl in xh.. by olx for zlx in zhx.. by zolx repeat
+ for dyh in 1..nhy _
+ for yh in 0.. by ohy for zhy in zlx.. by zohy repeat
+ for dyl in 1..nly _
+ for yl in yh.. by oly for zly in zhy.. by zoly repeat
+ set_!(z, zly, 0)
+ for k in 1..dim _
+ for xk in xl.. by nlx for yk in yl.. by nly repeat
+ set_!(z, zly, get(z,zly)+get(x,xk)*get(y,yk))
+ z
+
+ transpose x ==
+ transpose(x, 1, rank x)
+ transpose(x, i, j) ==
+ rx := rank x
+ i < 1 or i > rx or j < 1 or j > rx or i = j =>
+ error "Improper indicies for transposition"
+ if i > j then (i,j) := (j,i)
+
+ rl:= (rx- j) pretend NNI; nl:= dim**rl; zol:= 1; zoi := zol*nl
+ rm:= (j-i-1) pretend NNI; nm:= dim**rm; zom:= nl*dim; zoj := zom*nm
+ rh:= (i - 1) pretend NNI; nh:= dim**rh; zoh:= nl*nm*dim**2
+ z := new(#x, 0)
+ for h in 1..nh for zh in 0.. by zoh repeat _
+ for m in 1..nm for zm in zh.. by zom repeat _
+ for l in 1..nl for zl in zm.. by zol repeat _
+ for p in 1..dim _
+ for zp in zl.. by zoi for xp in zl.. by zoj repeat
+ for q in 1..dim _
+ for zq in zp.. by zoj for xq in xp.. by zoi repeat
+ set_!(z, zq, get(x,xq))
+ z
+
+ reindex(x, l) ==
+ nx := #x
+ z: % := new(nx, 0)
+
+ rx := rank x
+ p := mkPerm(rx, l)
+ xiv: INDEX := new(rx, 0)
+ ziv: INDEX := new(rx, 0)
+
+ -- Use permutation
+ for i in 0..#x-1 repeat
+ pi := index2int(permute_!(ziv, int2index(i,xiv),p))
+ set_!(z, pi, get(x,i))
+ z
+
+@
+\section{package CARTEN2 CartesianTensorFunctions2}
+<<package CARTEN2 CartesianTensorFunctions2>>=
+)abbrev package CARTEN2 CartesianTensorFunctions2
+++ Author: Stephen M. Watt
+++ Date Created: December 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations: reshape, map
+++ Related Domains: CartesianTensor
+++ Also See:
+++ AMS Classifications:
+++ Keywords: tensor
+++ Examples:
+++ References:
+++ Description:
+++ This package provides functions to enable conversion of tensors
+++ given conversion of the components.
+
+CartesianTensorFunctions2(minix, dim, S, T): CTPcat == CTPdef where
+ minix: Integer
+ dim: NonNegativeInteger
+ S, T: CommutativeRing
+ CS ==> CartesianTensor(minix, dim, S)
+ CT ==> CartesianTensor(minix, dim, T)
+
+ CTPcat == with
+ reshape: (List T, CS) -> CT
+ ++ reshape(lt,ts) organizes the list of components lt into
+ ++ a tensor with the same shape as ts.
+ map: (S->T, CS) -> CT
+ ++ map(f,ts) does a componentwise conversion of the tensor ts
+ ++ to a tensor with components of type T.
+ CTPdef == add
+ reshape(l, s) == unravel l
+ map(f, s) == unravel [f e for e in ravel s]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category GRMOD GradedModule>>
+<<category GRALG GradedAlgebra>>
+<<domain CARTEN CartesianTensor>>
+<<package CARTEN2 CartesianTensorFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/catdef.spad.pamphlet b/src/algebra/catdef.spad.pamphlet
new file mode 100644
index 00000000..a6ec3810
--- /dev/null
+++ b/src/algebra/catdef.spad.pamphlet
@@ -0,0 +1,4565 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra catdef.spad}
+\author{James Davenport, Lalo Gonzalez-Vega}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ABELGRP AbelianGroup}
+<<category ABELGRP AbelianGroup>>=
+)abbrev category ABELGRP AbelianGroup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The class of abelian groups, i.e. additive monoids where
+++ each element has an additive inverse.
+++
+++ Axioms:
+++ \spad{-(-x) = x}
+++ \spad{x+(-x) = 0}
+-- following domain must be compiled with subsumption disabled
+AbelianGroup(): Category == CancellationAbelianMonoid with
+ --operations
+ "-": % -> % ++ -x is the additive inverse of x.
+ "-": (%,%) -> % ++ x-y is the difference of x and y
+ ++ i.e. \spad{x + (-y)}.
+ -- subsumes the partial subtraction from previous
+ "*": (Integer,%) -> % ++ n*x is the product of x by the integer n.
+ add
+ (x:% - y:%):% == x+(-y)
+ subtractIfCan(x:%, y:%):Union(%, "failed") == (x-y) :: Union(%,"failed")
+ n:NonNegativeInteger * x:% == (n::Integer) * x
+ import RepeatedDoubling(%)
+ if not (% has Ring) then
+ n:Integer * x:% ==
+ zero? n => 0
+ n>0 => double(n pretend PositiveInteger,x)
+ double((-n) pretend PositiveInteger,-x)
+
+@
+\section{ABELGRP.lsp BOOTSTRAP}
+{\bf ABELGRP} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf ABELGRP} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf ABELGRP.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ABELGRP.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |AbelianGroup;AL| (QUOTE NIL))
+
+(DEFUN |AbelianGroup| NIL
+ (LET (#:G82664)
+ (COND
+ (|AbelianGroup;AL|)
+ (T (SETQ |AbelianGroup;AL| (|AbelianGroup;|))))))
+
+(DEFUN |AbelianGroup;| NIL
+ (PROG (#1=#:G82662)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|CancellationAbelianMonoid|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|-| (|$| |$|)) T)
+ ((|-| (|$| |$| |$|)) T)
+ ((|*| (|$| (|Integer|) |$|)) T)))
+ NIL
+ (QUOTE ((|Integer|)))
+ NIL))
+ |AbelianGroup|)
+ (SETELT #1# 0 (QUOTE (|AbelianGroup|)))))))
+
+(MAKEPROP (QUOTE |AbelianGroup|) (QUOTE NILADIC) T)
+
+@
+\section{ABELGRP-.lsp BOOTSTRAP}
+{\bf ABELGRP-} depends on a chain of files.
+We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ABELGRP-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ABELGRP-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ABELGRP-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |ABELGRP-;-;3S;1| (|x| |y| |$|)
+ (SPADCALL |x| (SPADCALL |y| (QREFELT |$| 7)) (QREFELT |$| 8)))
+
+(DEFUN |ABELGRP-;subtractIfCan;2SU;2| (|x| |y| |$|)
+ (CONS 0 (SPADCALL |x| |y| (QREFELT |$| 10))))
+
+(DEFUN |ABELGRP-;*;Nni2S;3| (|n| |x| |$|)
+ (SPADCALL |n| |x| (QREFELT |$| 14)))
+
+(DEFUN |ABELGRP-;*;I2S;4| (|n| |x| |$|)
+ (COND
+ ((ZEROP |n|) (|spadConstant| |$| 17))
+ ((|<| 0 |n|) (SPADCALL |n| |x| (QREFELT |$| 20)))
+ ((QUOTE T)
+ (SPADCALL (|-| |n|) (SPADCALL |x| (QREFELT |$| 7)) (QREFELT |$| 20)))))
+
+(DEFUN |AbelianGroup&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|AbelianGroup&|))
+ (LETT |dv$| (LIST (QUOTE |AbelianGroup&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 22) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ (COND
+ ((|HasCategory| |#1| (QUOTE (|Ring|))))
+ ((QUOTE T)
+ (QSETREFV |$| 21
+ (CONS (|dispatchFunction| |ABELGRP-;*;I2S;4|) |$|))))
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |AbelianGroup&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |-|)
+ (5 . |+|)
+ |ABELGRP-;-;3S;1|
+ (11 . |-|)
+ (|Union| |$| (QUOTE "failed"))
+ |ABELGRP-;subtractIfCan;2SU;2|
+ (|Integer|)
+ (17 . |*|)
+ (|NonNegativeInteger|)
+ |ABELGRP-;*;Nni2S;3|
+ (23 . |Zero|)
+ (|PositiveInteger|)
+ (|RepeatedDoubling| 6)
+ (27 . |double|)
+ (33 . |*|)))
+ (QUOTE #(|subtractIfCan| 39 |-| 45 |*| 51))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 21
+ (QUOTE (1 6 0 0 7 2 6 0 0 0 8 2 6 0 0 0 10 2 6 0 13 0 14 0 6 0 17
+ 2 19 6 18 6 20 2 0 0 13 0 21 2 0 11 0 0 12 2 0 0 0 0 9 2
+ 0 0 13 0 21 2 0 0 15 0 16))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category ABELMON AbelianMonoid}
+<<category ABELMON AbelianMonoid>>=
+)abbrev category ABELMON AbelianMonoid
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The class of multiplicative monoids, i.e. semigroups with an
+++ additive identity element.
+++
+++ Axioms:
+++ \spad{leftIdentity("+":(%,%)->%,0)}\tab{30}\spad{ 0+x=x }
+++ \spad{rightIdentity("+":(%,%)->%,0)}\tab{30}\spad{ x+0=x }
+-- following domain must be compiled with subsumption disabled
+-- define SourceLevelSubset to be EQUAL
+AbelianMonoid(): Category == AbelianSemiGroup with
+ --operations
+ 0: constant -> %
+ ++ 0 is the additive identity element.
+ sample: constant -> %
+ ++ sample yields a value of type %
+ zero?: % -> Boolean
+ ++ zero?(x) tests if x is equal to 0.
+ "*": (NonNegativeInteger,%) -> %
+ ++ n * x is left-multiplication by a non negative integer
+ add
+ import RepeatedDoubling(%)
+ zero? x == x = 0
+ n:PositiveInteger * x:% == (n::NonNegativeInteger) * x
+ sample() == 0
+ if not (% has Ring) then
+ n:NonNegativeInteger * x:% ==
+ zero? n => 0
+ double(n pretend PositiveInteger,x)
+
+@
+\section{ABELMON.lsp BOOTSTRAP}
+{\bf ABELMON} which needs
+{\bf ABELSG} which needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON}.
+We break this chain with {\bf ABELMON.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ABELMON}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ABELMON.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ABELMON.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |AbelianMonoid;AL| (QUOTE NIL))
+
+(DEFUN |AbelianMonoid| NIL
+ (LET (#:G82597)
+ (COND
+ (|AbelianMonoid;AL|)
+ (T (SETQ |AbelianMonoid;AL| (|AbelianMonoid;|))))))
+
+(DEFUN |AbelianMonoid;| NIL
+ (PROG (#1=#:G82595)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|AbelianSemiGroup|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|Zero| (|$|) |constant|) T)
+ ((|sample| (|$|) |constant|) T)
+ ((|zero?| ((|Boolean|) |$|)) T)
+ ((|*| (|$| (|NonNegativeInteger|) |$|)) T)))
+ NIL
+ (QUOTE ((|NonNegativeInteger|) (|Boolean|)))
+ NIL))
+ |AbelianMonoid|)
+ (SETELT #1# 0 (QUOTE (|AbelianMonoid|)))))))
+
+(MAKEPROP (QUOTE |AbelianMonoid|) (QUOTE NILADIC) T)
+
+@
+\section{ABELMON-.lsp BOOTSTRAP}
+{\bf ABELMON-} which needs
+{\bf ABELSG} which needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON-}.
+We break this chain with {\bf ABELMON-.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ABELMON-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ABELMON-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ABELMON-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |ABELMON-;zero?;SB;1| (|x| |$|)
+ (SPADCALL |x| (|spadConstant| |$| 7) (QREFELT |$| 9)))
+
+(DEFUN |ABELMON-;*;Pi2S;2| (|n| |x| |$|)
+ (SPADCALL |n| |x| (QREFELT |$| 12)))
+
+(DEFUN |ABELMON-;sample;S;3| (|$|)
+ (|spadConstant| |$| 7))
+
+(DEFUN |ABELMON-;*;Nni2S;4| (|n| |x| |$|)
+ (COND
+ ((ZEROP |n|) (|spadConstant| |$| 7))
+ ((QUOTE T) (SPADCALL |n| |x| (QREFELT |$| 17)))))
+
+(DEFUN |AbelianMonoid&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|AbelianMonoid&|))
+ (LETT |dv$| (LIST (QUOTE |AbelianMonoid&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 19) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ (COND
+ ((|HasCategory| |#1| (QUOTE (|Ring|))))
+ ((QUOTE T)
+ (QSETREFV |$| 18
+ (CONS (|dispatchFunction| |ABELMON-;*;Nni2S;4|) |$|)))) |$|))))
+
+(MAKEPROP
+ (QUOTE |AbelianMonoid&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |Zero|)
+ (|Boolean|)
+ (4 . |=|)
+ |ABELMON-;zero?;SB;1|
+ (|NonNegativeInteger|)
+ (10 . |*|)
+ (|PositiveInteger|)
+ |ABELMON-;*;Pi2S;2|
+ |ABELMON-;sample;S;3|
+ (|RepeatedDoubling| 6)
+ (16 . |double|)
+ (22 . |*|)))
+ (QUOTE #(|zero?| 28 |sample| 33 |*| 37))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 18
+ (QUOTE (0 6 0 7 2 6 8 0 0 9 2 6 0 11 0 12 2 16 6 13 6 17 2 0 0 11
+ 0 18 1 0 8 0 10 0 0 0 15 2 0 0 11 0 18 2 0 0 13 0 14))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category ABELSG AbelianSemiGroup}
+<<category ABELSG AbelianSemiGroup>>=
+)abbrev category ABELSG AbelianSemiGroup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ the class of all additive (commutative) semigroups, i.e.
+++ a set with a commutative and associative operation \spadop{+}.
+++
+++ Axioms:
+++ \spad{associative("+":(%,%)->%)}\tab{30}\spad{ (x+y)+z = x+(y+z) }
+++ \spad{commutative("+":(%,%)->%)}\tab{30}\spad{ x+y = y+x }
+AbelianSemiGroup(): Category == SetCategory with
+ --operations
+ "+": (%,%) -> % ++ x+y computes the sum of x and y.
+ "*": (PositiveInteger,%) -> %
+ ++ n*x computes the left-multiplication of x by the positive integer n.
+ ++ This is equivalent to adding x to itself n times.
+ add
+ import RepeatedDoubling(%)
+ if not (% has Ring) then
+ n:PositiveInteger * x:% == double(n,x)
+
+@
+\section{ABELSG.lsp BOOTSTRAP}
+{\bf ABELSG} needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON} which needs
+{\bf ABELSG}.
+We break this chain with {\bf ABELSG.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ABELSG}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ABELSG.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ABELSG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |AbelianSemiGroup;AL| (QUOTE NIL))
+
+(DEFUN |AbelianSemiGroup| NIL
+ (LET (#:G82568)
+ (COND
+ (|AbelianSemiGroup;AL|)
+ (T (SETQ |AbelianSemiGroup;AL| (|AbelianSemiGroup;|))))))
+
+(DEFUN |AbelianSemiGroup;| NIL
+ (PROG (#1=#:G82566)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|SetCategory|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|+| (|$| |$| |$|)) T)
+ ((|*| (|$| (|PositiveInteger|) |$|)) T)))
+ NIL
+ (QUOTE ((|PositiveInteger|)))
+ NIL))
+ |AbelianSemiGroup|)
+ (SETELT #1# 0 (QUOTE (|AbelianSemiGroup|)))))))
+
+(MAKEPROP (QUOTE |AbelianSemiGroup|) (QUOTE NILADIC) T)
+@
+\section{ABELSG-.lsp BOOTSTRAP}
+{\bf ABELSG-} needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON} which needs
+{\bf ABELSG-}.
+We break this chain with {\bf ABELSG-.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ABELSG-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ABELSG-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ABELSG-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |ABELSG-;*;Pi2S;1| (|n| |x| |$|) (SPADCALL |n| |x| (QREFELT |$| 9)))
+
+(DEFUN |AbelianSemiGroup&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|AbelianSemiGroup&|))
+ (LETT |dv$| (LIST (QUOTE |AbelianSemiGroup&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 11) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ (COND
+ ((|HasCategory| |#1| (QUOTE (|Ring|))))
+ ((QUOTE T)
+ (QSETREFV |$| 10
+ (CONS (|dispatchFunction| |ABELSG-;*;Pi2S;1|) |$|))))
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |AbelianSemiGroup&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|PositiveInteger|)
+ (|RepeatedDoubling| 6)
+ (0 . |double|)
+ (6 . |*|)))
+ (QUOTE #(|*| 12))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 10
+ (QUOTE (2 8 6 7 6 9 2 0 0 7 0 10 2 0 0 7 0 10))))))
+ (QUOTE |lookupComplete|)))
+@
+\section{category ALGEBRA Algebra}
+<<category ALGEBRA Algebra>>=
+)abbrev category ALGEBRA Algebra
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of associative algebras (modules which are themselves rings).
+++
+++ Axioms:
+++ \spad{(b+c)::% = (b::%) + (c::%)}
+++ \spad{(b*c)::% = (b::%) * (c::%)}
+++ \spad{(1::R)::% = 1::%}
+++ \spad{b*x = (b::%)*x}
+++ \spad{r*(a*b) = (r*a)*b = a*(r*b)}
+Algebra(R:CommutativeRing): Category ==
+ Join(Ring, Module R) with
+ --operations
+ coerce: R -> %
+ ++ coerce(r) maps the ring element r to a member of the algebra.
+ add
+ coerce(x:R):% == x * 1$%
+
+@
+\section{category BASTYPE BasicType}
+<<category BASTYPE BasicType>>=
+)abbrev category BASTYPE BasicType
+--% BasicType
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{BasicType} is the basic category for describing a collection
+++ of elements with \spadop{=} (equality).
+BasicType(): Category == with
+ "=": (%,%) -> Boolean ++ x=y tests if x and y are equal.
+ "~=": (%,%) -> Boolean ++ x~=y tests if x and y are not equal.
+ add
+ _~_=(x:%,y:%) : Boolean == not(x=y)
+
+@
+\section{category BMODULE BiModule}
+<<category BMODULE BiModule>>=
+)abbrev category BMODULE BiModule
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A \spadtype{BiModule} is both a left and right module with respect
+++ to potentially different rings.
+++
+++ Axiom:
+++ \spad{ r*(x*s) = (r*x)*s }
+BiModule(R:Ring,S:Ring):Category ==
+ Join(LeftModule(R),RightModule(S)) with
+ leftUnitary ++ \spad{1 * x = x}
+ rightUnitary ++ \spad{x * 1 = x}
+
+@
+\section{category CABMON CancellationAbelianMonoid}
+<<category CABMON CancellationAbelianMonoid>>=
+)abbrev category CABMON CancellationAbelianMonoid
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References: Davenport & Trager I
+++ Description:
+++ This is an \spadtype{AbelianMonoid} with the cancellation property, i.e.
+++ \spad{ a+b = a+c => b=c }.
+++ This is formalised by the partial subtraction operator,
+++ which satisfies the axioms listed below:
+++
+++ Axioms:
+++ \spad{c = a+b <=> c-b = a}
+CancellationAbelianMonoid(): Category == AbelianMonoid with
+ --operations
+ subtractIfCan: (%,%) -> Union(%,"failed")
+ ++ subtractIfCan(x, y) returns an element z such that \spad{z+y=x}
+ ++ or "failed" if no such element exists.
+
+@
+\section{CABMON.lsp BOOTSTRAP}
+{\bf CABMON} which needs
+{\bf ABELMON} which needs
+{\bf ABELSG} which needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON}.
+We break this chain with {\bf CABMON.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf CABMON}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf CABMON.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<CABMON.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |CancellationAbelianMonoid;AL| (QUOTE NIL))
+
+(DEFUN |CancellationAbelianMonoid| NIL
+ (LET (#:G82646)
+ (COND
+ (|CancellationAbelianMonoid;AL|)
+ (T
+ (SETQ
+ |CancellationAbelianMonoid;AL|
+ (|CancellationAbelianMonoid;|))))))
+
+(DEFUN |CancellationAbelianMonoid;| NIL
+ (PROG (#1=#:G82644)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|AbelianMonoid|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (((|subtractIfCan| ((|Union| |$| "failed") |$| |$|)) T)))
+ NIL
+ (QUOTE NIL)
+ NIL))
+ |CancellationAbelianMonoid|)
+ (SETELT #1# 0 (QUOTE (|CancellationAbelianMonoid|)))))))
+
+(MAKEPROP (QUOTE |CancellationAbelianMonoid|) (QUOTE NILADIC) T)
+
+@
+\section{category CHARNZ CharacteristicNonZero}
+<<category CHARNZ CharacteristicNonZero>>=
+)abbrev category CHARNZ CharacteristicNonZero
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Rings of Characteristic Non Zero
+CharacteristicNonZero():Category == Ring with
+ charthRoot: % -> Union(%,"failed")
+ ++ charthRoot(x) returns the pth root of x
+ ++ where p is the characteristic of the ring.
+
+@
+\section{category CHARZ CharacteristicZero}
+<<category CHARZ CharacteristicZero>>=
+)abbrev category CHARZ CharacteristicZero
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Rings of Characteristic Zero.
+CharacteristicZero():Category == Ring
+
+@
+\section{category COMRING CommutativeRing}
+<<category COMRING CommutativeRing>>=
+)abbrev category COMRING CommutativeRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of commutative rings with unity, i.e. rings where
+++ \spadop{*} is commutative, and which have a multiplicative identity.
+++ element.
+--CommutativeRing():Category == Join(Ring,BiModule(%:Ring,%:Ring)) with
+CommutativeRing():Category == Join(Ring,BiModule(%,%)) with
+ commutative("*") ++ multiplication is commutative.
+
+@
+\section{COMRING.lsp BOOTSTRAP}
+{\bf COMRING} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf COMRING}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf COMRING.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<COMRING.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |CommutativeRing;AL| (QUOTE NIL))
+
+(DEFUN |CommutativeRing| NIL
+ (LET (#:G82892)
+ (COND
+ (|CommutativeRing;AL|)
+ (T (SETQ |CommutativeRing;AL| (|CommutativeRing;|))))))
+
+(DEFUN |CommutativeRing;| NIL
+ (PROG (#1=#:G82890)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|Ring|)
+ (|BiModule| (QUOTE |$|) (QUOTE |$|))
+ (|mkCategory|
+ (QUOTE |package|)
+ NIL
+ (QUOTE (((|commutative| "*") T)))
+ (QUOTE NIL)
+ NIL))
+ |CommutativeRing|)
+ (SETELT #1# 0 (QUOTE (|CommutativeRing|)))))))
+
+(MAKEPROP (QUOTE |CommutativeRing|) (QUOTE NILADIC) T)
+
+@
+\section{category DIFRING DifferentialRing}
+<<category DIFRING DifferentialRing>>=
+)abbrev category DIFRING DifferentialRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An ordinary differential ring, that is, a ring with an operation
+++ \spadfun{differentiate}.
+++
+++ Axioms:
+++ \spad{differentiate(x+y) = differentiate(x)+differentiate(y)}
+++ \spad{differentiate(x*y) = x*differentiate(y) + differentiate(x)*y}
+
+DifferentialRing(): Category == Ring with
+ differentiate: % -> %
+ ++ differentiate(x) returns the derivative of x.
+ ++ This function is a simple differential operator
+ ++ where no variable needs to be specified.
+ D: % -> %
+ ++ D(x) returns the derivative of x.
+ ++ This function is a simple differential operator
+ ++ where no variable needs to be specified.
+ differentiate: (%, NonNegativeInteger) -> %
+ ++ differentiate(x, n) returns the n-th derivative of x.
+ D: (%, NonNegativeInteger) -> %
+ ++ D(x, n) returns the n-th derivative of x.
+ add
+ D r == differentiate r
+ differentiate(r, n) ==
+ for i in 1..n repeat r := differentiate r
+ r
+ D(r,n) == differentiate(r,n)
+
+@
+\section{DIFRING.lsp BOOTSTRAP}
+{\bf DIFRING} needs {\bf INT} which needs {\bf DIFRING}.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf DIFRING} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf DIFRING.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<DIFRING.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |DifferentialRing;AL| (QUOTE NIL))
+
+(DEFUN |DifferentialRing| NIL
+ (LET (#:G84565)
+ (COND
+ (|DifferentialRing;AL|)
+ (T (SETQ |DifferentialRing;AL| (|DifferentialRing;|))))))
+
+(DEFUN |DifferentialRing;| NIL
+ (PROG (#1=#:G84563)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|Ring|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE
+ (((|differentiate| (|$| |$|)) T)
+ ((D (|$| |$|)) T)
+ ((|differentiate| (|$| |$| (|NonNegativeInteger|))) T)
+ ((D (|$| |$| (|NonNegativeInteger|))) T)))
+ NIL
+ (QUOTE ((|NonNegativeInteger|)))
+ NIL))
+ |DifferentialRing|)
+ (SETELT #1# 0 (QUOTE (|DifferentialRing|)))))))
+
+(MAKEPROP (QUOTE |DifferentialRing|) (QUOTE NILADIC) T)
+
+@
+\section{DIFRING-.lsp BOOTSTRAP}
+{\bf DIFRING-} needs {\bf DIFRING}.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf DIFRING-} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf DIFRING-.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<DIFRING-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |DIFRING-;D;2S;1| (|r| |$|)
+ (SPADCALL |r| (QREFELT |$| 7)))
+
+(DEFUN |DIFRING-;differentiate;SNniS;2| (|r| |n| |$|)
+ (PROG (|i|)
+ (RETURN
+ (SEQ
+ (SEQ
+ (LETT |i| 1 |DIFRING-;differentiate;SNniS;2|)
+ G190
+ (COND ((QSGREATERP |i| |n|) (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT |r|
+ (SPADCALL |r| (QREFELT |$| 7))
+ |DIFRING-;differentiate;SNniS;2|)))
+ (LETT |i| (QSADD1 |i|) |DIFRING-;differentiate;SNniS;2|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |r|)))))
+
+(DEFUN |DIFRING-;D;SNniS;3| (|r| |n| |$|)
+ (SPADCALL |r| |n| (QREFELT |$| 11)))
+
+(DEFUN |DifferentialRing&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|DifferentialRing&|))
+ (LETT |dv$| (LIST (QUOTE |DifferentialRing&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 13) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |DifferentialRing&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |differentiate|)
+ |DIFRING-;D;2S;1|
+ (|NonNegativeInteger|)
+ |DIFRING-;differentiate;SNniS;2|
+ (5 . |differentiate|)
+ |DIFRING-;D;SNniS;3|))
+ (QUOTE #(|differentiate| 11 D 17))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 12
+ (QUOTE
+ (1 6 0 0 7 2 6 0 0 9 11 2 0 0 0 9 10 2 0 0 0 9 12 1 0 0 0 8))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category DIFEXT DifferentialExtension}
+<<category DIFEXT DifferentialExtension>>=
+)abbrev category DIFEXT DifferentialExtension
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Differential extensions of a ring R.
+++ Given a differentiation on R, extend it to a differentiation on %.
+
+DifferentialExtension(R:Ring): Category == Ring with
+ --operations
+ differentiate: (%, R -> R) -> %
+ ++ differentiate(x, deriv) differentiates x extending
+ ++ the derivation deriv on R.
+ differentiate: (%, R -> R, NonNegativeInteger) -> %
+ ++ differentiate(x, deriv, n) differentiate x n times
+ ++ using a derivation which extends deriv on R.
+ D: (%, R -> R) -> %
+ ++ D(x, deriv) differentiates x extending
+ ++ the derivation deriv on R.
+ D: (%, R -> R, NonNegativeInteger) -> %
+ ++ D(x, deriv, n) differentiate x n times
+ ++ using a derivation which extends deriv on R.
+ if R has DifferentialRing then DifferentialRing
+ if R has PartialDifferentialRing(Symbol) then
+ PartialDifferentialRing(Symbol)
+ add
+ differentiate(x:%, derivation: R -> R, n:NonNegativeInteger):% ==
+ for i in 1..n repeat x := differentiate(x, derivation)
+ x
+ D(x:%, derivation: R -> R) == differentiate(x, derivation)
+ D(x:%, derivation: R -> R, n:NonNegativeInteger) ==
+ differentiate(x, derivation, n)
+
+ if R has DifferentialRing then
+ differentiate x == differentiate(x, differentiate$R)
+
+ if R has PartialDifferentialRing Symbol then
+ differentiate(x:%, v:Symbol):% ==
+ differentiate(x, differentiate(#1, v)$R)
+
+@
+\section{category DIVRING DivisionRing}
+<<category DIVRING DivisionRing>>=
+)abbrev category DIVRING DivisionRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A division ring (sometimes called a skew field),
+++ i.e. a not necessarily commutative ring where
+++ all non-zero elements have multiplicative inverses.
+
+DivisionRing(): Category ==
+ Join(EntireRing, Algebra Fraction Integer) with
+ "**": (%,Integer) -> %
+ ++ x**n returns x raised to the integer power n.
+ "^" : (%,Integer) -> %
+ ++ x^n returns x raised to the integer power n.
+ inv : % -> %
+ ++ inv x returns the multiplicative inverse of x.
+ ++ Error: if x is 0.
+-- Q-algebra is a lie, should be conditional on characteristic 0,
+-- but knownInfo cannot handle the following commented
+-- if % has CharacteristicZero then Algebra Fraction Integer
+ add
+ n: Integer
+ x: %
+ _^(x:%, n:Integer):% == x ** n
+ import RepeatedSquaring(%)
+ x ** n: Integer ==
+ zero? n => 1
+ zero? x =>
+ n<0 => error "division by zero"
+ x
+ n<0 =>
+ expt(inv x,(-n) pretend PositiveInteger)
+ expt(x,n pretend PositiveInteger)
+-- if % has CharacteristicZero() then
+ q:Fraction(Integer) * x:% == numer(q) * inv(denom(q)::%) * x
+
+@
+\section{DIVRING.lsp BOOTSTRAP}
+{\bf DIVRING} depends on {\bf QFCAT} which eventually depends on
+{\bf DIVRING}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf DIVRING}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf DIVRING.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<DIVRING.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |DivisionRing;AL| (QUOTE NIL))
+
+(DEFUN |DivisionRing| NIL
+ (LET (#:G84035)
+ (COND
+ (|DivisionRing;AL|)
+ (T (SETQ |DivisionRing;AL| (|DivisionRing;|))))))
+
+(DEFUN |DivisionRing;| NIL
+ (PROG (#1=#:G84033)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR
+ (QUOTE (#2=#:G84032))
+ (LIST (QUOTE (|Fraction| (|Integer|)))))
+ (|Join|
+ (|EntireRing|)
+ (|Algebra| (QUOTE #2#))
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|**| (|$| |$| (|Integer|))) T)
+ ((|^| (|$| |$| (|Integer|))) T)
+ ((|inv| (|$| |$|)) T)))
+ NIL
+ (QUOTE ((|Integer|)))
+ NIL)))
+ |DivisionRing|)
+ (SETELT #1# 0 (QUOTE (|DivisionRing|)))))))
+
+(MAKEPROP (QUOTE |DivisionRing|) (QUOTE NILADIC) T)
+
+@
+\section{DIVRING-.lsp BOOTSTRAP}
+{\bf DIVRING-} depends on {\bf DIVRING}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf DIVRING-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf DIVRING-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<DIVRING-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |DIVRING-;^;SIS;1| (|x| |n| |$|)
+ (SPADCALL |x| |n| (QREFELT |$| 8)))
+
+(DEFUN |DIVRING-;**;SIS;2| (|x| |n| |$|)
+ (COND
+ ((ZEROP |n|) (|spadConstant| |$| 10))
+ ((SPADCALL |x| (QREFELT |$| 12))
+ (COND
+ ((|<| |n| 0) (|error| "division by zero"))
+ ((QUOTE T) |x|)))
+ ((|<| |n| 0)
+ (SPADCALL (SPADCALL |x| (QREFELT |$| 14)) (|-| |n|) (QREFELT |$| 17)))
+ ((QUOTE T) (SPADCALL |x| |n| (QREFELT |$| 17)))))
+
+(DEFUN |DIVRING-;*;F2S;3| (|q| |x| |$|)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |q| (QREFELT |$| 20))
+ (SPADCALL
+ (SPADCALL (SPADCALL |q| (QREFELT |$| 21)) (QREFELT |$| 22))
+ (QREFELT |$| 14))
+ (QREFELT |$| 23))
+ |x|
+ (QREFELT |$| 24)))
+
+(DEFUN |DivisionRing&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|DivisionRing&|))
+ (LETT |dv$| (LIST (QUOTE |DivisionRing&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 27) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |DivisionRing&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|Integer|)
+ (0 . |**|)
+ |DIVRING-;^;SIS;1|
+ (6 . |One|)
+ (|Boolean|)
+ (10 . |zero?|)
+ (15 . |Zero|)
+ (19 . |inv|)
+ (|PositiveInteger|)
+ (|RepeatedSquaring| 6)
+ (24 . |expt|)
+ |DIVRING-;**;SIS;2|
+ (|Fraction| 7)
+ (30 . |numer|)
+ (35 . |denom|)
+ (40 . |coerce|)
+ (45 . |*|)
+ (51 . |*|)
+ |DIVRING-;*;F2S;3|
+ (|NonNegativeInteger|)))
+ (QUOTE #(|^| 57 |**| 63 |*| 69))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 25
+ (QUOTE
+ (2 6 0 0 7 8 0 6 0 10 1 6 11 0 12 0 6 0 13 1 6 0 0 14 2 16 6
+ 6 15 17 1 19 7 0 20 1 19 7 0 21 1 6 0 7 22 2 6 0 7 0 23 2 6
+ 0 0 0 24 2 0 0 0 7 9 2 0 0 0 7 18 2 0 0 19 0 25))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category ENTIRER EntireRing}
+<<category ENTIRER EntireRing>>=
+)abbrev category ENTIRER EntireRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Entire Rings (non-commutative Integral Domains), i.e. a ring
+++ not necessarily commutative which has no zero divisors.
+++
+++ Axioms:
+++ \spad{ab=0 => a=0 or b=0} -- known as noZeroDivisors
+++ \spad{not(1=0)}
+--EntireRing():Category == Join(Ring,BiModule(%:Ring,%:Ring)) with
+EntireRing():Category == Join(Ring,BiModule(%,%)) with
+ noZeroDivisors ++ if a product is zero then one of the factors
+ ++ must be zero.
+
+@
+\section{ENTIRER.lsp BOOTSTRAP}
+{\bf ENTIRER} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ENTIRER}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ENTIRER.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ENTIRER.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |EntireRing;AL| (QUOTE NIL))
+
+(DEFUN |EntireRing| NIL
+ (LET (#:G82841)
+ (COND
+ (|EntireRing;AL|)
+ (T (SETQ |EntireRing;AL| (|EntireRing;|))))))
+
+(DEFUN |EntireRing;| NIL
+ (PROG (#1=#:G82839)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|Ring|)
+ (|BiModule| (QUOTE |$|) (QUOTE |$|))
+ (|mkCategory|
+ (QUOTE |package|)
+ NIL
+ (QUOTE ((|noZeroDivisors| T)))
+ (QUOTE NIL)
+ NIL))
+ |EntireRing|)
+ (SETELT #1# 0 (QUOTE (|EntireRing|)))))))
+
+(MAKEPROP (QUOTE |EntireRing|) (QUOTE NILADIC) T)
+
+@
+\section{category EUCDOM EuclideanDomain}
+<<category EUCDOM EuclideanDomain>>=
+)abbrev category EUCDOM EuclideanDomain
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A constructive euclidean domain, i.e. one can divide producing
+++ a quotient and a remainder where the remainder is either zero
+++ or is smaller (\spadfun{euclideanSize}) than the divisor.
+++
+++ Conditional attributes:
+++ multiplicativeValuation\tab{25}\spad{Size(a*b)=Size(a)*Size(b)}
+++ additiveValuation\tab{25}\spad{Size(a*b)=Size(a)+Size(b)}
+
+EuclideanDomain(): Category == PrincipalIdealDomain with
+ --operations
+ sizeLess?: (%,%) -> Boolean
+ ++ sizeLess?(x,y) tests whether x is strictly
+ ++ smaller than y with respect to the \spadfunFrom{euclideanSize}{EuclideanDomain}.
+ euclideanSize: % -> NonNegativeInteger
+ ++ euclideanSize(x) returns the euclidean size of the element x.
+ ++ Error: if x is zero.
+ divide: (%,%) -> Record(quotient:%,remainder:%)
+ ++ divide(x,y) divides x by y producing a record containing a
+ ++ \spad{quotient} and \spad{remainder},
+ ++ where the remainder is smaller (see \spadfunFrom{sizeLess?}{EuclideanDomain})
+ ++ than the divisor y.
+ "quo" : (%,%) -> %
+ ++ x quo y is the same as \spad{divide(x,y).quotient}.
+ ++ See \spadfunFrom{divide}{EuclideanDomain}.
+ "rem": (%,%) -> %
+ ++ x rem y is the same as \spad{divide(x,y).remainder}.
+ ++ See \spadfunFrom{divide}{EuclideanDomain}.
+ extendedEuclidean: (%,%) -> Record(coef1:%,coef2:%,generator:%)
+ -- formerly called princIdeal
+ ++ extendedEuclidean(x,y) returns a record rec where
+ ++ \spad{rec.coef1*x+rec.coef2*y = rec.generator} and
+ ++ rec.generator is a gcd of x and y.
+ ++ The gcd is unique only
+ ++ up to associates if \spadatt{canonicalUnitNormal} is not asserted.
+ ++ \spadfun{principalIdeal} provides a version of this operation
+ ++ which accepts an arbitrary length list of arguments.
+ extendedEuclidean: (%,%,%) -> Union(Record(coef1:%,coef2:%),"failed")
+ -- formerly called expressIdealElt
+ ++ extendedEuclidean(x,y,z) either returns a record rec
+ ++ where \spad{rec.coef1*x+rec.coef2*y=z} or returns "failed"
+ ++ if z cannot be expressed as a linear combination of x and y.
+ multiEuclidean: (List %,%) -> Union(List %,"failed")
+ ++ multiEuclidean([f1,...,fn],z) returns a list of coefficients
+ ++ \spad{[a1, ..., an]} such that
+ ++ \spad{ z / prod fi = sum aj/fj}.
+ ++ If no such list of coefficients exists, "failed" is returned.
+ add
+ -- declarations
+ x,y,z: %
+ l: List %
+ -- definitions
+ sizeLess?(x,y) ==
+ zero? y => false
+ zero? x => true
+ euclideanSize(x)<euclideanSize(y)
+ x quo y == divide(x,y).quotient --divide must be user-supplied
+ x rem y == divide(x,y).remainder
+ x exquo y ==
+ zero? y => "failed"
+ qr:=divide(x,y)
+ zero?(qr.remainder) => qr.quotient
+ "failed"
+ gcd(x,y) == --Euclidean Algorithm
+ x:=unitCanonical x
+ y:=unitCanonical y
+ while not zero? y repeat
+ (x,y):= (y,x rem y)
+ y:=unitCanonical y -- this doesn't affect the
+ -- correctness of Euclid's algorithm,
+ -- but
+ -- a) may improve performance
+ -- b) ensures gcd(x,y)=gcd(y,x)
+ -- if canonicalUnitNormal
+ x
+ IdealElt ==> Record(coef1:%,coef2:%,generator:%)
+ unitNormalizeIdealElt(s:IdealElt):IdealElt ==
+ (u,c,a):=unitNormal(s.generator)
+-- one? a => s
+ (a = 1) => s
+ [a*s.coef1,a*s.coef2,c]$IdealElt
+ extendedEuclidean(x,y) == --Extended Euclidean Algorithm
+ s1:=unitNormalizeIdealElt([1$%,0$%,x]$IdealElt)
+ s2:=unitNormalizeIdealElt([0$%,1$%,y]$IdealElt)
+ zero? y => s1
+ zero? x => s2
+ while not zero?(s2.generator) repeat
+ qr:= divide(s1.generator, s2.generator)
+ s3:=[s1.coef1 - qr.quotient * s2.coef1,
+ s1.coef2 - qr.quotient * s2.coef2, qr.remainder]$IdealElt
+ s1:=s2
+ s2:=unitNormalizeIdealElt s3
+ if not(zero?(s1.coef1)) and not sizeLess?(s1.coef1,y)
+ then
+ qr:= divide(s1.coef1,y)
+ s1.coef1:= qr.remainder
+ s1.coef2:= s1.coef2 + qr.quotient * x
+ s1 := unitNormalizeIdealElt s1
+ s1
+
+ TwoCoefs ==> Record(coef1:%,coef2:%)
+ extendedEuclidean(x,y,z) ==
+ zero? z => [0,0]$TwoCoefs
+ s:= extendedEuclidean(x,y)
+ (w:= z exquo s.generator) case "failed" => "failed"
+ zero? y =>
+ [s.coef1 * w, s.coef2 * w]$TwoCoefs
+ qr:= divide((s.coef1 * w), y)
+ [qr.remainder, s.coef2 * w + qr.quotient * x]$TwoCoefs
+ principalIdeal l ==
+ l = [] => error "empty list passed to principalIdeal"
+ rest l = [] =>
+ uca:=unitNormal(first l)
+ [[uca.unit],uca.canonical]
+ rest rest l = [] =>
+ u:= extendedEuclidean(first l,second l)
+ [[u.coef1, u.coef2], u.generator]
+ v:=principalIdeal rest l
+ u:= extendedEuclidean(first l,v.generator)
+ [[u.coef1,:[u.coef2*vv for vv in v.coef]],u.generator]
+ expressIdealMember(l,z) ==
+ z = 0 => [0 for v in l]
+ pid := principalIdeal l
+ (q := z exquo (pid.generator)) case "failed" => "failed"
+ [q*v for v in pid.coef]
+ multiEuclidean(l,z) ==
+ n := #l
+ zero? n => error "empty list passed to multiEuclidean"
+ n = 1 => [z]
+ l1 := copy l
+ l2 := split!(l1, n quo 2)
+ u:= extendedEuclidean(*/l1, */l2, z)
+ u case "failed" => "failed"
+ v1 := multiEuclidean(l1,u.coef2)
+ v1 case "failed" => "failed"
+ v2 := multiEuclidean(l2,u.coef1)
+ v2 case "failed" => "failed"
+ concat(v1,v2)
+
+@
+\section{EUCDOM.lsp BOOTSTRAP}
+{\bf EUCDOM} depends on {\bf INT} which depends on {\bf EUCDOM}.
+We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf EUCDOM}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf EUCDOM.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+\subsection{The Lisp Implementation}
+\subsubsection{EUCDOM;VersionCheck}
+This implements the bootstrap code for {\bf EuclideanDomain}.
+The call to {\bf VERSIONCHECK} is a legacy check to ensure that
+we did not load algebra code from a previous system version (which
+would not run due to major surgical changes in the system) without
+recompiling.
+<<EUCDOM;VersionCheck>>=
+(|/VERSIONCHECK| 2)
+
+@
+\subsubsection{The Domain Cache Variable}
+We create a variable which is formed by concatenating the string
+``{\bf ;AL}'' to the domain name forming, in this case,
+``{\bf EuclideanDomain;AL}''. The variable has the initial value
+at load time of a list of one element, {\bf NIL}. This list is
+a data structure that will be modified to hold an executable
+function. This function is created the first time the domain is
+used which it replaces the {\bf NIL}.
+<<EuclideanDomain;AL>>=
+(SETQ |EuclideanDomain;AL| (QUOTE NIL))
+
+@
+\subsubsection{The Domain Function}
+When you call a domain the code is pretty simple at the top
+level. This code will check to see if this domain has ever been
+used. It does this by checking the value of the cached domain
+variable (which is the domain name {\bf EuclideanDomain} concatenated
+with the string ``{\bf ;AL}'' to form the cache variable name which
+is {\bf EuclideanDomain;AL}).
+
+If this value is NIL we have never executed this function
+before. If it is not NIL we have executed this function before and
+we need only return the cached function which was stored in the
+cache variable.
+
+If this is the first time this function is called, the cache
+variable is NIL and we execute the other branch of the conditional.
+This calls a function which
+\begin{enumerate}
+\item creates a procedure
+\item returns the procedure as a value.
+\end{enumerate}
+This procedure replaces the cached variable {\bf EuclideanDomain;AL}
+value so it will be non-NIL the second time this domain is used.
+Thus the work of building the domain only happens once.
+
+If this function has never been called before we call the
+<<EuclideanDomain>>=
+(DEFUN |EuclideanDomain| NIL
+ (LET (#:G83585)
+ (COND
+ (|EuclideanDomain;AL|)
+ (T (SETQ |EuclideanDomain;AL| (|EuclideanDomain;|))))))
+
+@
+\subsubsection{The First Call Domain Function}
+<<EuclideanDomain;>>=
+(DEFUN |EuclideanDomain;| NIL
+ (PROG (#1=#:G83583)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|PrincipalIdealDomain|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|sizeLess?| ((|Boolean|) |$| |$|)) T)
+ ((|euclideanSize| ((|NonNegativeInteger|) |$|)) T)
+ ((|divide|
+ ((|Record|
+ (|:| |quotient| |$|)
+ (|:| |remainder| |$|))
+ |$| |$|)) T)
+ ((|quo| (|$| |$| |$|)) T)
+ ((|rem| (|$| |$| |$|)) T)
+ ((|extendedEuclidean|
+ ((|Record|
+ (|:| |coef1| |$|)
+ (|:| |coef2| |$|)
+ (|:| |generator| |$|))
+ |$| |$|)) T)
+ ((|extendedEuclidean|
+ ((|Union|
+ (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|))
+ "failed")
+ |$| |$| |$|)) T)
+ ((|multiEuclidean|
+ ((|Union|
+ (|List| |$|)
+ "failed")
+ (|List| |$|) |$|)) T)))
+ NIL
+ (QUOTE ((|List| |$|) (|NonNegativeInteger|) (|Boolean|)))
+ NIL))
+ |EuclideanDomain|)
+ (SETELT #1# 0 (QUOTE (|EuclideanDomain|)))))))
+
+@
+\subsubsection{EUCDOM;MAKEPROP}
+<<EUCDOM;MAKEPROP>>=
+(MAKEPROP (QUOTE |EuclideanDomain|) (QUOTE NILADIC) T)
+
+@
+<<EUCDOM.lsp BOOTSTRAP>>=
+<<EUCDOM;VersionCheck>>
+<<EuclideanDomain;AL>>
+<<EuclideanDomain>>
+<<EuclideanDomain;>>
+<<EUCDOM;MAKEPROP>>
+@
+\section{EUCDOM-.lsp BOOTSTRAP}
+{\bf EUCDOM-} depends on {\bf EUCDOM}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf EUCDOM-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf EUCDOM-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+\subsection{The Lisp Implementation}
+\subsubsection{EUCDOM-;VersionCheck}
+This implements the bootstrap code for {\bf EuclideanDomain}.
+The call to {\bf VERSIONCHECK} is a legacy check to ensure that
+we did not load algebra code from a previous system version (which
+would not run due to major surgical changes in the system) without
+recompiling.
+<<EUCDOM-;VersionCheck>>=
+(|/VERSIONCHECK| 2)
+
+@
+\subsubsection{EUCDOM-;sizeLess?;2SB;1}
+<<EUCDOM-;sizeLess?;2SB;1>>=
+(DEFUN |EUCDOM-;sizeLess?;2SB;1| (|x| |y| |$|)
+ (COND
+ ((SPADCALL |y| (QREFELT |$| 8)) (QUOTE NIL))
+ ((SPADCALL |x| (QREFELT |$| 8)) (QUOTE T))
+ ((QUOTE T)
+ (|<| (SPADCALL |x| (QREFELT |$| 10)) (SPADCALL |y| (QREFELT |$| 10))))))
+
+@
+
+\subsubsection{EUCDOM-;quo;3S;2}
+<<EUCDOM-;quo;3S;2>>=
+(DEFUN |EUCDOM-;quo;3S;2| (|x| |y| |$|)
+ (QCAR (SPADCALL |x| |y| (QREFELT |$| 13))))
+
+@
+\subsubsection{EUCDOM-;rem;3S;3}
+<<EUCDOM-;rem;3S;3>>=
+(DEFUN |EUCDOM-;rem;3S;3| (|x| |y| |$|)
+ (QCDR (SPADCALL |x| |y| (QREFELT |$| 13))))
+
+@
+\subsubsection{EUCDOM-;exquo;2SU;4}
+<<EUCDOM-;exquo;2SU;4>>=
+(DEFUN |EUCDOM-;exquo;2SU;4| (|x| |y| |$|)
+ (PROG (|qr|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |y| (QREFELT |$| 8)) (CONS 1 "failed"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |qr|
+ (SPADCALL |x| |y| (QREFELT |$| 13))
+ |EUCDOM-;exquo;2SU;4|)
+ (EXIT
+ (COND
+ ((SPADCALL (QCDR |qr|) (QREFELT |$| 8)) (CONS 0 (QCAR |qr|)))
+ ((QUOTE T) (CONS 1 "failed")))))))))))
+
+@
+\subsubsection{EUCDOM-;gcd;3S;5}
+<<EUCDOM-;gcd;3S;5>>=
+(DEFUN |EUCDOM-;gcd;3S;5| (|x| |y| |$|)
+ (PROG (|#G13| |#G14|)
+ (RETURN
+ (SEQ
+ (LETT |x| (SPADCALL |x| (QREFELT |$| 18)) |EUCDOM-;gcd;3S;5|)
+ (LETT |y| (SPADCALL |y| (QREFELT |$| 18)) |EUCDOM-;gcd;3S;5|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL |y| (QREFELT |$| 8)) (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (PROGN
+ (LETT |#G13| |y| |EUCDOM-;gcd;3S;5|)
+ (LETT |#G14| (SPADCALL |x| |y| (QREFELT |$| 19)) |EUCDOM-;gcd;3S;5|)
+ (LETT |x| |#G13| |EUCDOM-;gcd;3S;5|)
+ (LETT |y| |#G14| |EUCDOM-;gcd;3S;5|))
+ (EXIT
+ (LETT |y| (SPADCALL |y| (QREFELT |$| 18)) |EUCDOM-;gcd;3S;5|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |x|)))))
+
+@
+\subsubsection{EUCDOM-;unitNormalizeIdealElt}
+<<EUCDOM-;unitNormalizeIdealElt>>=
+(DEFUN |EUCDOM-;unitNormalizeIdealElt| (|s| |$|)
+ (PROG (|#G16| |u| |c| |a|)
+ (RETURN
+ (SEQ
+ (PROGN
+ (LETT |#G16| (SPADCALL (QVELT |s| 2) (QREFELT |$| 22)) |EUCDOM-;unitNormalizeIdealElt|)
+ (LETT |u| (QVELT |#G16| 0) |EUCDOM-;unitNormalizeIdealElt|)
+ (LETT |c| (QVELT |#G16| 1) |EUCDOM-;unitNormalizeIdealElt|)
+ (LETT |a| (QVELT |#G16| 2) |EUCDOM-;unitNormalizeIdealElt|)
+ |#G16|)
+ (EXIT
+ (COND
+ ((SPADCALL |a| (QREFELT |$| 23)) |s|)
+ ((QUOTE T)
+ (VECTOR
+ (SPADCALL |a| (QVELT |s| 0) (QREFELT |$| 24))
+ (SPADCALL |a| (QVELT |s| 1) (QREFELT |$| 24))
+ |c|))))))))
+
+@
+\subsubsection{EUCDOM-;extendedEuclidean;2SR;7}
+<<EUCDOM-;extendedEuclidean;2SR;7>>=
+(DEFUN |EUCDOM-;extendedEuclidean;2SR;7| (|x| |y| |$|)
+ (PROG (|s3| |s2| |qr| |s1|)
+ (RETURN
+ (SEQ
+ (LETT |s1|
+ (|EUCDOM-;unitNormalizeIdealElt|
+ (VECTOR (|spadConstant| |$| 25) (|spadConstant| |$| 26) |x|) |$|)
+ |EUCDOM-;extendedEuclidean;2SR;7|)
+ (LETT |s2|
+ (|EUCDOM-;unitNormalizeIdealElt|
+ (VECTOR (|spadConstant| |$| 26) (|spadConstant| |$| 25) |y|) |$|)
+ |EUCDOM-;extendedEuclidean;2SR;7|)
+ (EXIT
+ (COND
+ ((SPADCALL |y| (QREFELT |$| 8)) |s1|)
+ ((SPADCALL |x| (QREFELT |$| 8)) |s2|)
+ ((QUOTE T)
+ (SEQ
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL (QVELT |s2| 2) (QREFELT |$| 8))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |qr|
+ (SPADCALL (QVELT |s1| 2) (QVELT |s2| 2) (QREFELT |$| 13))
+ |EUCDOM-;extendedEuclidean;2SR;7|)
+ (LETT |s3|
+ (VECTOR
+ (SPADCALL
+ (QVELT |s1| 0)
+ (SPADCALL
+ (QCAR |qr|)
+ (QVELT |s2| 0)
+ (QREFELT |$| 24))
+ (QREFELT |$| 27))
+ (SPADCALL
+ (QVELT |s1| 1)
+ (SPADCALL
+ (QCAR |qr|)
+ (QVELT |s2| 1)
+ (QREFELT |$| 24))
+ (QREFELT |$| 27))
+ (QCDR |qr|))
+ |EUCDOM-;extendedEuclidean;2SR;7|)
+ (LETT |s1| |s2| |EUCDOM-;extendedEuclidean;2SR;7|)
+ (EXIT
+ (LETT |s2|
+ (|EUCDOM-;unitNormalizeIdealElt| |s3| |$|)
+ |EUCDOM-;extendedEuclidean;2SR;7|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ ((NULL (SPADCALL (QVELT |s1| 0) (QREFELT |$| 8)))
+ (COND
+ ((NULL (SPADCALL (QVELT |s1| 0) |y| (QREFELT |$| 28)))
+ (SEQ
+ (LETT |qr|
+ (SPADCALL (QVELT |s1| 0) |y| (QREFELT |$| 13))
+ |EUCDOM-;extendedEuclidean;2SR;7|)
+ (QSETVELT |s1| 0 (QCDR |qr|))
+ (QSETVELT |s1| 1
+ (SPADCALL
+ (QVELT |s1| 1)
+ (SPADCALL (QCAR |qr|) |x| (QREFELT |$| 24))
+ (QREFELT |$| 29)))
+ (EXIT
+ (LETT |s1|
+ (|EUCDOM-;unitNormalizeIdealElt| |s1| |$|)
+ |EUCDOM-;extendedEuclidean;2SR;7|)))))))
+ (EXIT |s1|)))))))))
+
+@
+\subsubsection{EUCDOM-;extendedEuclidean;3SU;8}
+<<EUCDOM-;extendedEuclidean;3SU;8>>=
+(DEFUN |EUCDOM-;extendedEuclidean;3SU;8| (|x| |y| |z| |$|)
+ (PROG (|s| |w| |qr|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |z| (QREFELT |$| 8))
+ (CONS 0 (CONS (|spadConstant| |$| 26) (|spadConstant| |$| 26))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |s|
+ (SPADCALL |x| |y| (QREFELT |$| 32))
+ |EUCDOM-;extendedEuclidean;3SU;8|)
+ (LETT |w|
+ (SPADCALL |z| (QVELT |s| 2) (QREFELT |$| 33))
+ |EUCDOM-;extendedEuclidean;3SU;8|)
+ (EXIT
+ (COND
+ ((QEQCAR |w| 1) (CONS 1 "failed"))
+ ((SPADCALL |y| (QREFELT |$| 8))
+ (CONS 0
+ (CONS
+ (SPADCALL (QVELT |s| 0) (QCDR |w|) (QREFELT |$| 24))
+ (SPADCALL (QVELT |s| 1) (QCDR |w|) (QREFELT |$| 24)))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |qr|
+ (SPADCALL
+ (SPADCALL (QVELT |s| 0) (QCDR |w|) (QREFELT |$| 24))
+ |y|
+ (QREFELT |$| 13))
+ |EUCDOM-;extendedEuclidean;3SU;8|)
+ (EXIT
+ (CONS
+ 0
+ (CONS
+ (QCDR |qr|)
+ (SPADCALL
+ (SPADCALL
+ (QVELT |s| 1)
+ (QCDR |w|)
+ (QREFELT |$| 24))
+ (SPADCALL
+ (QCAR |qr|)
+ |x|
+ (QREFELT |$| 24))
+ (QREFELT |$| 29))))))))))))))))
+
+@
+\subsubsection{EUCDOM-;principalIdeal;LR;9}
+<<EUCDOM-;principalIdeal;LR;9>>=
+(DEFUN |EUCDOM-;principalIdeal;LR;9| (|l| |$|)
+ (PROG (|uca| |v| |u| #1=#:G83663 |vv| #2=#:G83664)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |l| NIL (QREFELT |$| 38))
+ (|error| "empty list passed to principalIdeal"))
+ ((SPADCALL (CDR |l|) NIL (QREFELT |$| 38))
+ (SEQ
+ (LETT |uca|
+ (SPADCALL (|SPADfirst| |l|) (QREFELT |$| 22))
+ |EUCDOM-;principalIdeal;LR;9|)
+ (EXIT (CONS (LIST (QVELT |uca| 0)) (QVELT |uca| 1)))))
+ ((SPADCALL (CDR (CDR |l|)) NIL (QREFELT |$| 38))
+ (SEQ
+ (LETT |u|
+ (SPADCALL
+ (|SPADfirst| |l|)
+ (SPADCALL |l| (QREFELT |$| 39))
+ (QREFELT |$| 32))
+ |EUCDOM-;principalIdeal;LR;9|)
+ (EXIT
+ (CONS (LIST (QVELT |u| 0) (QVELT |u| 1)) (QVELT |u| 2)))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |v|
+ (SPADCALL (CDR |l|) (QREFELT |$| 42))
+ |EUCDOM-;principalIdeal;LR;9|)
+ (LETT |u|
+ (SPADCALL (|SPADfirst| |l|) (QCDR |v|) (QREFELT |$| 32))
+ |EUCDOM-;principalIdeal;LR;9|)
+ (EXIT
+ (CONS
+ (CONS
+ (QVELT |u| 0)
+ (PROGN
+ (LETT #1# NIL |EUCDOM-;principalIdeal;LR;9|)
+ (SEQ
+ (LETT |vv| NIL |EUCDOM-;principalIdeal;LR;9|)
+ (LETT #2# (QCAR |v|) |EUCDOM-;principalIdeal;LR;9|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |vv|
+ (CAR #2#)
+ |EUCDOM-;principalIdeal;LR;9|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS
+ (SPADCALL
+ (QVELT |u| 1)
+ |vv|
+ (QREFELT |$| 24))
+ #1#)
+ |EUCDOM-;principalIdeal;LR;9|)))
+ (LETT #2# (CDR #2#) |EUCDOM-;principalIdeal;LR;9|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#)))))
+ (QVELT |u| 2))))))))))
+@
+\subsubsection{EUCDOM-;expressIdealMember;LSU;10}
+<<EUCDOM-;expressIdealMember;LSU;10>>=
+(DEFUN |EUCDOM-;expressIdealMember;LSU;10| (|l| |z| |$|)
+ (PROG (#1=#:G83681 #2=#:G83682 |pid| |q| #3=#:G83679 |v| #4=#:G83680)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |z| (|spadConstant| |$| 26) (QREFELT |$| 44))
+ (CONS
+ 0
+ (PROGN
+ (LETT #1# NIL |EUCDOM-;expressIdealMember;LSU;10|)
+ (SEQ
+ (LETT |v| NIL |EUCDOM-;expressIdealMember;LSU;10|)
+ (LETT #2# |l| |EUCDOM-;expressIdealMember;LSU;10|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |v|
+ (CAR #2#)
+ |EUCDOM-;expressIdealMember;LSU;10|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS (|spadConstant| |$| 26) #1#)
+ |EUCDOM-;expressIdealMember;LSU;10|)))
+ (LETT #2# (CDR #2#) |EUCDOM-;expressIdealMember;LSU;10|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |pid|
+ (SPADCALL |l| (QREFELT |$| 42))
+ |EUCDOM-;expressIdealMember;LSU;10|)
+ (LETT |q|
+ (SPADCALL |z| (QCDR |pid|) (QREFELT |$| 33))
+ |EUCDOM-;expressIdealMember;LSU;10|)
+ (EXIT
+ (COND
+ ((QEQCAR |q| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS
+ 0
+ (PROGN
+ (LETT #3# NIL |EUCDOM-;expressIdealMember;LSU;10|)
+ (SEQ
+ (LETT |v| NIL |EUCDOM-;expressIdealMember;LSU;10|)
+ (LETT #4# (QCAR |pid|) |EUCDOM-;expressIdealMember;LSU;10|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |v|
+ (CAR #4#)
+ |EUCDOM-;expressIdealMember;LSU;10|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #3#
+ (CONS
+ (SPADCALL (QCDR |q|) |v| (QREFELT |$| 24))
+ #3#)
+ |EUCDOM-;expressIdealMember;LSU;10|)))
+ (LETT #4#
+ (CDR #4#)
+ |EUCDOM-;expressIdealMember;LSU;10|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #3#)))))))))))))))
+
+@
+\subsubsection{EUCDOM-;multiEuclidean;LSU;11}
+<<EUCDOM-;multiEuclidean;LSU;11>>=
+(DEFUN |EUCDOM-;multiEuclidean;LSU;11| (|l| |z| |$|)
+ (PROG (|n| |l1| |l2| #1=#:G83565 #2=#:G83702 #3=#:G83688 #4=#:G83686
+ #5=#:G83687 #6=#:G83566 #7=#:G83701 #8=#:G83691 #9=#:G83689
+ #10=#:G83690 |u| |v1| |v2|)
+ (RETURN
+ (SEQ
+ (LETT |n| (LENGTH |l|) |EUCDOM-;multiEuclidean;LSU;11|)
+ (EXIT
+ (COND
+ ((ZEROP |n|) (|error| "empty list passed to multiEuclidean"))
+ ((EQL |n| 1) (CONS 0 (LIST |z|)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |l1|
+ (SPADCALL |l| (QREFELT |$| 47))
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (LETT |l2|
+ (SPADCALL |l1| (QUOTIENT2 |n| 2) (QREFELT |$| 49))
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (LETT |u|
+ (SPADCALL
+ (PROGN
+ (LETT #5# NIL |EUCDOM-;multiEuclidean;LSU;11|)
+ (SEQ
+ (LETT #1# NIL |EUCDOM-;multiEuclidean;LSU;11|)
+ (LETT #2# |l1| |EUCDOM-;multiEuclidean;LSU;11|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT #1#
+ (CAR #2#)
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (PROGN
+ (LETT #3# #1# |EUCDOM-;multiEuclidean;LSU;11|)
+ (COND
+ (#5#
+ (LETT #4#
+ (SPADCALL #4# #3# (QREFELT |$| 24))
+ |EUCDOM-;multiEuclidean;LSU;11|))
+ ((QUOTE T)
+ (PROGN
+ (LETT #4#
+ #3#
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (LETT #5#
+ (QUOTE T)
+ |EUCDOM-;multiEuclidean;LSU;11|)))))))
+ (LETT #2# (CDR #2#) |EUCDOM-;multiEuclidean;LSU;11|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND (#5# #4#) ((QUOTE T) (|spadConstant| |$| 25))))
+ (PROGN
+ (LETT #10# NIL |EUCDOM-;multiEuclidean;LSU;11|)
+ (SEQ
+ (LETT #6# NIL |EUCDOM-;multiEuclidean;LSU;11|)
+ (LETT #7# |l2| |EUCDOM-;multiEuclidean;LSU;11|)
+ G190
+ (COND
+ ((OR
+ (ATOM #7#)
+ (PROGN
+ (LETT #6#
+ (CAR #7#)
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (PROGN
+ (LETT #8# #6# |EUCDOM-;multiEuclidean;LSU;11|)
+ (COND
+ (#10#
+ (LETT #9#
+ (SPADCALL #9# #8# (QREFELT |$| 24))
+ |EUCDOM-;multiEuclidean;LSU;11|))
+ ((QUOTE T)
+ (PROGN
+ (LETT #9#
+ #8#
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (LETT #10#
+ (QUOTE T)
+ |EUCDOM-;multiEuclidean;LSU;11|)))))))
+ (LETT #7# (CDR #7#) |EUCDOM-;multiEuclidean;LSU;11|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ (#10# #9#)
+ ((QUOTE T) (|spadConstant| |$| 25))))
+ |z|
+ (QREFELT |$| 50))
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (EXIT
+ (COND
+ ((QEQCAR |u| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |v1|
+ (SPADCALL |l1| (QCDR (QCDR |u|)) (QREFELT |$| 51))
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (EXIT
+ (COND
+ ((QEQCAR |v1| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |v2|
+ (SPADCALL
+ |l2|
+ (QCAR (QCDR |u|))
+ (QREFELT |$| 51))
+ |EUCDOM-;multiEuclidean;LSU;11|)
+ (EXIT
+ (COND
+ ((QEQCAR |v2| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS
+ 0
+ (SPADCALL
+ (QCDR |v1|)
+ (QCDR |v2|)
+ (QREFELT |$| 52))))))))))))))))))))))
+
+@
+\subsubsection{EuclideanDomain\&}
+<<EuclideanDomainAmp>>=
+(DEFUN |EuclideanDomain&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|EuclideanDomain&|))
+ (LETT |dv$| (LIST (QUOTE |EuclideanDomain&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 54) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+@
+\subsubsection{EUCDOM-;MAKEPROP}
+<<EUCDOM-;MAKEPROP>>=
+(MAKEPROP
+ (QUOTE |EuclideanDomain&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|Boolean|)
+ (0 . |zero?|)
+ (|NonNegativeInteger|)
+ (5 . |euclideanSize|)
+ |EUCDOM-;sizeLess?;2SB;1|
+ (|Record| (|:| |quotient| |$|) (|:| |remainder| |$|))
+ (10 . |divide|)
+ |EUCDOM-;quo;3S;2|
+ |EUCDOM-;rem;3S;3|
+ (|Union| |$| (QUOTE "failed"))
+ |EUCDOM-;exquo;2SU;4|
+ (16 . |unitCanonical|)
+ (21 . |rem|)
+ |EUCDOM-;gcd;3S;5|
+ (|Record| (|:| |unit| |$|) (|:| |canonical| |$|) (|:| |associate| |$|))
+ (27 . |unitNormal|)
+ (32 . |one?|)
+ (37 . |*|)
+ (43 . |One|)
+ (47 . |Zero|)
+ (51 . |-|)
+ (57 . |sizeLess?|)
+ (63 . |+|)
+ (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|) (|:| |generator| |$|))
+ |EUCDOM-;extendedEuclidean;2SR;7|
+ (69 . |extendedEuclidean|)
+ (75 . |exquo|)
+ (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|))
+ (|Union| 34 (QUOTE "failed"))
+ |EUCDOM-;extendedEuclidean;3SU;8|
+ (|List| 6)
+ (81 . |=|)
+ (87 . |second|)
+ (|Record| (|:| |coef| 41) (|:| |generator| |$|))
+ (|List| |$|)
+ (92 . |principalIdeal|)
+ |EUCDOM-;principalIdeal;LR;9|
+ (97 . |=|)
+ (|Union| 41 (QUOTE "failed"))
+ |EUCDOM-;expressIdealMember;LSU;10|
+ (103 . |copy|)
+ (|Integer|)
+ (108 . |split!|)
+ (114 . |extendedEuclidean|)
+ (121 . |multiEuclidean|)
+ (127 . |concat|)
+ |EUCDOM-;multiEuclidean;LSU;11|))
+ (QUOTE
+ #(|sizeLess?| 133 |rem| 139 |quo| 145 |principalIdeal| 151
+ |multiEuclidean| 156 |gcd| 162 |extendedEuclidean| 168 |exquo| 181
+ |expressIdealMember| 187))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 53
+ (QUOTE
+ (1 6 7 0 8 1 6 9 0 10 2 6 12 0 0 13 1 6 0 0 18 2 6 0 0 0 19 1 6
+ 21 0 22 1 6 7 0 23 2 6 0 0 0 24 0 6 0 25 0 6 0 26 2 6 0 0 0 27
+ 2 6 7 0 0 28 2 6 0 0 0 29 2 6 30 0 0 32 2 6 16 0 0 33 2 37 7 0
+ 0 38 1 37 6 0 39 1 6 40 41 42 2 6 7 0 0 44 1 37 0 0 47 2 37 0 0
+ 48 49 3 6 35 0 0 0 50 2 6 45 41 0 51 2 37 0 0 0 52 2 0 7 0 0 11
+ 2 0 0 0 0 15 2 0 0 0 0 14 1 0 40 41 43 2 0 45 41 0 53 2 0 0 0 0
+ 20 3 0 35 0 0 0 36 2 0 30 0 0 31 2 0 16 0 0 17 2 0 45 41 0
+ 46))))))
+ (QUOTE |lookupComplete|)))
+
+@
+<<EUCDOM-.lsp BOOTSTRAP>>=
+
+<<EUCDOM-;VersionCheck>>
+<<EUCDOM-;sizeLess?;2SB;1>>
+<<EUCDOM-;quo;3S;2>>
+<<EUCDOM-;rem;3S;3>>
+<<EUCDOM-;exquo;2SU;4>>
+<<EUCDOM-;gcd;3S;5>>
+<<EUCDOM-;unitNormalizeIdealElt>>
+<<EUCDOM-;extendedEuclidean;2SR;7>>
+<<EUCDOM-;extendedEuclidean;3SU;8>>
+<<EUCDOM-;principalIdeal;LR;9>>
+<<EUCDOM-;expressIdealMember;LSU;10>>
+<<EUCDOM-;multiEuclidean;LSU;11>>
+<<EuclideanDomainAmp>>
+<<EUCDOM-;MAKEPROP>>
+@
+\section{category FIELD Field}
+<<category FIELD Field>>=
+)abbrev category FIELD Field
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of commutative fields, i.e. commutative rings
+++ where all non-zero elements have multiplicative inverses.
+++ The \spadfun{factor} operation while trivial is useful to have defined.
+++
+++ Axioms:
+++ \spad{a*(b/a) = b}
+++ \spad{inv(a) = 1/a}
+
+Field(): Category == Join(EuclideanDomain,UniqueFactorizationDomain,
+ DivisionRing) with
+ --operations
+ "/": (%,%) -> %
+ ++ x/y divides the element x by the element y.
+ ++ Error: if y is 0.
+ canonicalUnitNormal ++ either 0 or 1.
+ canonicalsClosed ++ since \spad{0*0=0}, \spad{1*1=1}
+ add
+ --declarations
+ x,y: %
+ n: Integer
+ -- definitions
+ UCA ==> Record(unit:%,canonical:%,associate:%)
+ unitNormal(x) ==
+ if zero? x then [1$%,0$%,1$%]$UCA else [x,1$%,inv(x)]$UCA
+ unitCanonical(x) == if zero? x then x else 1
+ associates?(x,y) == if zero? x then zero? y else not(zero? y)
+ inv x ==((u:=recip x) case "failed" => error "not invertible"; u)
+ x exquo y == (y=0 => "failed"; x / y)
+ gcd(x,y) == 1
+ euclideanSize(x) == 0
+ prime? x == false
+ squareFree x == x::Factored(%)
+ factor x == x::Factored(%)
+ x / y == (zero? y => error "catdef: division by zero"; x * inv(y))
+ divide(x,y) == [x / y,0]
+
+@
+\section{category FINITE Finite}
+<<category FINITE Finite>>=
+)abbrev category FINITE Finite
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of domains composed of a finite set of elements.
+++ We include the functions \spadfun{lookup} and \spadfun{index} to give a bijection
+++ between the finite set and an initial segment of positive integers.
+++
+++ Axioms:
+++ \spad{lookup(index(n)) = n}
+++ \spad{index(lookup(s)) = s}
+
+Finite(): Category == SetCategory with
+ --operations
+ size: () -> NonNegativeInteger
+ ++ size() returns the number of elements in the set.
+ index: PositiveInteger -> %
+ ++ index(i) takes a positive integer i less than or equal
+ ++ to \spad{size()} and
+ ++ returns the \spad{i}-th element of the set. This operation establishs a bijection
+ ++ between the elements of the finite set and \spad{1..size()}.
+ lookup: % -> PositiveInteger
+ ++ lookup(x) returns a positive integer such that
+ ++ \spad{x = index lookup x}.
+ random: () -> %
+ ++ random() returns a random element from the set.
+
+@
+\section{category FLINEXP FullyLinearlyExplicitRingOver}
+<<category FLINEXP FullyLinearlyExplicitRingOver>>=
+)abbrev category FLINEXP FullyLinearlyExplicitRingOver
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ S is \spadtype{FullyLinearlyExplicitRingOver R} means that S is a
+++ \spadtype{LinearlyExplicitRingOver R} and, in addition, if R is a
+++ \spadtype{LinearlyExplicitRingOver Integer}, then so is S
+FullyLinearlyExplicitRingOver(R:Ring):Category ==
+ LinearlyExplicitRingOver R with
+ if (R has LinearlyExplicitRingOver Integer) then
+ LinearlyExplicitRingOver Integer
+ add
+ if not(R is Integer) then
+ if (R has LinearlyExplicitRingOver Integer) then
+ reducedSystem(m:Matrix %):Matrix(Integer) ==
+ reducedSystem(reducedSystem(m)@Matrix(R))
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix(Integer), vec:Vector(Integer)) ==
+ rec := reducedSystem(m, v)@Record(mat:Matrix R, vec:Vector R)
+ reducedSystem(rec.mat, rec.vec)
+
+@
+\section{category GCDDOM GcdDomain}
+<<category GCDDOM GcdDomain>>=
+)abbrev category GCDDOM GcdDomain
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References: Davenport & Trager 1
+++ Description:
+++ This category describes domains where
+++ \spadfun{gcd} can be computed but where there is no guarantee
+++ of the existence of \spadfun{factor} operation for factorisation into irreducibles.
+++ However, if such a \spadfun{factor} operation exist, factorization will be
+++ unique up to order and units.
+
+GcdDomain(): Category == IntegralDomain with
+ --operations
+ gcd: (%,%) -> %
+ ++ gcd(x,y) returns the greatest common divisor of x and y.
+ -- gcd(x,y) = gcd(y,x) in the presence of canonicalUnitNormal,
+ -- but not necessarily elsewhere
+ gcd: List(%) -> %
+ ++ gcd(l) returns the common gcd of the elements in the list l.
+ lcm: (%,%) -> %
+ ++ lcm(x,y) returns the least common multiple of x and y.
+ -- lcm(x,y) = lcm(y,x) in the presence of canonicalUnitNormal,
+ -- but not necessarily elsewhere
+ lcm: List(%) -> %
+ ++ lcm(l) returns the least common multiple of the elements of the list l.
+ gcdPolynomial: (SparseUnivariatePolynomial %, SparseUnivariatePolynomial %) ->
+ SparseUnivariatePolynomial %
+ ++ gcdPolynomial(p,q) returns the greatest common divisor (gcd) of
+ ++ univariate polynomials over the domain
+ add
+ lcm(x: %,y: %) ==
+ y = 0 => 0
+ x = 0 => 0
+ LCM : Union(%,"failed") := y exquo gcd(x,y)
+ LCM case % => x * LCM
+ error "bad gcd in lcm computation"
+ lcm(l:List %) == reduce(lcm,l,1,0)
+ gcd(l:List %) == reduce(gcd,l,0,1)
+ SUP ==> SparseUnivariatePolynomial
+ gcdPolynomial(p1,p2) ==
+ zero? p1 => unitCanonical p2
+ zero? p2 => unitCanonical p1
+ c1:= content(p1); c2:= content(p2)
+ p1:= (p1 exquo c1)::SUP %
+ p2:= (p2 exquo c2)::SUP %
+ if (e1:=minimumDegree p1) > 0 then p1:=(p1 exquo monomial(1,e1))::SUP %
+ if (e2:=minimumDegree p2) > 0 then p2:=(p2 exquo monomial(1,e2))::SUP %
+ e1:=min(e1,e2); c1:=gcd(c1,c2)
+ p1:=
+ degree p1 = 0 or degree p2 = 0 => monomial(c1,0)
+ p:= subResultantGcd(p1,p2)
+ degree p = 0 => monomial(c1,0)
+ c2:= gcd(leadingCoefficient p1,leadingCoefficient p2)
+ unitCanonical(c1 * primitivePart(((c2*p) exquo leadingCoefficient p)::SUP %))
+ zero? e1 => p1
+ monomial(1,e1)*p1
+
+@
+\section{GCDDOM.lsp BOOTSTRAP}
+{\bf GCDDOM} needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON} which needs
+{\bf ABELSG} which needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM}.
+We break this chain with {\bf GCDDOM.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf GCDDOM}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf GCDDOM.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<GCDDOM.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |GcdDomain;AL| (QUOTE NIL))
+
+(DEFUN |GcdDomain| NIL
+ (LET (#:G83171)
+ (COND
+ (|GcdDomain;AL|)
+ (T (SETQ |GcdDomain;AL| (|GcdDomain;|))))))
+
+(DEFUN |GcdDomain;| NIL
+ (PROG (#1=#:G83169)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|IntegralDomain|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|gcd| (|$| |$| |$|)) T)
+ ((|gcd| (|$| (|List| |$|))) T)
+ ((|lcm| (|$| |$| |$|)) T)
+ ((|lcm| (|$| (|List| |$|))) T)
+ ((|gcdPolynomial|
+ ((|SparseUnivariatePolynomial| |$|)
+ (|SparseUnivariatePolynomial| |$|)
+ (|SparseUnivariatePolynomial| |$|)))
+ T)))
+ NIL
+ (QUOTE ((|SparseUnivariatePolynomial| |$|) (|List| |$|)))
+ NIL))
+ |GcdDomain|)
+ (SETELT #1# 0 (QUOTE (|GcdDomain|)))))))
+
+(MAKEPROP (QUOTE |GcdDomain|) (QUOTE NILADIC) T)
+
+@
+\section{GCDDOM-.lsp BOOTSTRAP}
+{\bf GCDDOM-} depends on {\bf GCDDOM}.
+We break this chain with {\bf GCDDOM-.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf GCDDOM-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf GCDDOM-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<GCDDOM-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |GCDDOM-;lcm;3S;1| (|x| |y| |$|)
+ (PROG (LCM)
+ (RETURN
+ (SEQ
+ (COND
+ ((OR
+ (SPADCALL |y| (|spadConstant| |$| 7) (QREFELT |$| 9))
+ (SPADCALL |x| (|spadConstant| |$| 7) (QREFELT |$| 9)))
+ (|spadConstant| |$| 7))
+ ((QUOTE T)
+ (SEQ
+ (LETT LCM
+ (SPADCALL |y|
+ (SPADCALL |x| |y| (QREFELT |$| 10))
+ (QREFELT |$| 12))
+ |GCDDOM-;lcm;3S;1|)
+ (EXIT
+ (COND
+ ((QEQCAR LCM 0) (SPADCALL |x| (QCDR LCM) (QREFELT |$| 13)))
+ ((QUOTE T) (|error| "bad gcd in lcm computation")))))))))))
+
+(DEFUN |GCDDOM-;lcm;LS;2| (|l| |$|)
+ (SPADCALL
+ (ELT |$| 15)
+ |l|
+ (|spadConstant| |$| 16)
+ (|spadConstant| |$| 7)
+ (QREFELT |$| 19)))
+
+(DEFUN |GCDDOM-;gcd;LS;3| (|l| |$|)
+ (SPADCALL
+ (ELT |$| 10)
+ |l|
+ (|spadConstant| |$| 7)
+ (|spadConstant| |$| 16)
+ (QREFELT |$| 19)))
+
+(DEFUN |GCDDOM-;gcdPolynomial;3Sup;4| (|p1| |p2| |$|)
+ (PROG (|e2| |e1| |c1| |p| |c2| #1=#:G83191)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |p1| (QREFELT |$| 24)) (SPADCALL |p2| (QREFELT |$| 25)))
+ ((SPADCALL |p2| (QREFELT |$| 24)) (SPADCALL |p1| (QREFELT |$| 25)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |c1|
+ (SPADCALL |p1| (QREFELT |$| 26))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (LETT |c2|
+ (SPADCALL |p2| (QREFELT |$| 26))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (LETT |p1|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p1| |c1| (QREFELT |$| 27))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (QCDR #1#)
+ (|check-union|
+ (QEQCAR #1# 0)
+ (|SparseUnivariatePolynomial| (QREFELT |$| 6))
+ #1#))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (LETT |p2|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p2| |c2| (QREFELT |$| 27))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (QCDR #1#)
+ (|check-union|
+ (QEQCAR #1# 0)
+ (|SparseUnivariatePolynomial| (QREFELT |$| 6))
+ #1#))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (SEQ
+ (LETT |e1|
+ (SPADCALL |p1| (QREFELT |$| 29))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (EXIT
+ (COND
+ ((|<| 0 |e1|)
+ (LETT |p1|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p1|
+ (SPADCALL
+ (|spadConstant| |$| 16) |e1| (QREFELT |$| 32))
+ (QREFELT |$| 33))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (QCDR #1#)
+ (|check-union|
+ (QEQCAR #1# 0)
+ (|SparseUnivariatePolynomial| (QREFELT |$| 6))
+ #1#))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)))))
+ (SEQ
+ (LETT |e2|
+ (SPADCALL |p2| (QREFELT |$| 29))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (EXIT
+ (COND
+ ((|<| 0 |e2|)
+ (LETT |p2|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p2|
+ (SPADCALL
+ (|spadConstant| |$| 16)
+ |e2|
+ (QREFELT |$| 32))
+ (QREFELT |$| 33))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (QCDR #1#)
+ (|check-union|
+ (QEQCAR #1# 0)
+ (|SparseUnivariatePolynomial| (QREFELT |$| 6))
+ #1#))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)))))
+ (LETT |e1|
+ (MIN |e1| |e2|)
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (LETT |c1|
+ (SPADCALL |c1| |c2| (QREFELT |$| 10))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (LETT |p1|
+ (COND
+ ((OR
+ (EQL (SPADCALL |p1| (QREFELT |$| 34)) 0)
+ (EQL (SPADCALL |p2| (QREFELT |$| 34)) 0))
+ (SPADCALL |c1| 0 (QREFELT |$| 32)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |p|
+ (SPADCALL |p1| |p2| (QREFELT |$| 35))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (EXIT
+ (COND
+ ((EQL (SPADCALL |p| (QREFELT |$| 34)) 0)
+ (SPADCALL |c1| 0 (QREFELT |$| 32)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |c2|
+ (SPADCALL
+ (SPADCALL |p1| (QREFELT |$| 36))
+ (SPADCALL |p2| (QREFELT |$| 36))
+ (QREFELT |$| 10))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (EXIT
+ (SPADCALL
+ (SPADCALL |c1|
+ (SPADCALL
+ (PROG2
+ (LETT #1#
+ (SPADCALL
+ (SPADCALL
+ |c2|
+ |p|
+ (QREFELT |$| 37))
+ (SPADCALL |p| (QREFELT |$| 36))
+ (QREFELT |$| 27))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (QCDR #1#)
+ (|check-union|
+ (QEQCAR #1# 0)
+ (|SparseUnivariatePolynomial|
+ (QREFELT |$| 6))
+ #1#))
+ (QREFELT |$| 38))
+ (QREFELT |$| 37))
+ (QREFELT |$| 25))))))))))
+ |GCDDOM-;gcdPolynomial;3Sup;4|)
+ (EXIT (COND ((ZEROP |e1|) |p1|) ((QUOTE T) (SPADCALL (SPADCALL (|spadConstant| |$| 16) |e1| (QREFELT |$| 32)) |p1| (QREFELT |$| 39))))))))))))
+
+(DEFUN |GcdDomain&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|GcdDomain&|))
+ (LETT |dv$| (LIST (QUOTE |GcdDomain&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 42) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |GcdDomain&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |Zero|)
+ (|Boolean|)
+ (4 . |=|)
+ (10 . |gcd|)
+ (|Union| |$| (QUOTE "failed"))
+ (16 . |exquo|)
+ (22 . |*|)
+ |GCDDOM-;lcm;3S;1|
+ (28 . |lcm|)
+ (34 . |One|)
+ (|Mapping| 6 6 6)
+ (|List| 6)
+ (38 . |reduce|)
+ (|List| |$|)
+ |GCDDOM-;lcm;LS;2|
+ |GCDDOM-;gcd;LS;3|
+ (|SparseUnivariatePolynomial| 6)
+ (46 . |zero?|)
+ (51 . |unitCanonical|)
+ (56 . |content|)
+ (61 . |exquo|)
+ (|NonNegativeInteger|)
+ (67 . |minimumDegree|)
+ (72 . |Zero|)
+ (76 . |One|)
+ (80 . |monomial|)
+ (86 . |exquo|)
+ (92 . |degree|)
+ (97 . |subResultantGcd|)
+ (103 . |leadingCoefficient|)
+ (108 . |*|)
+ (114 . |primitivePart|)
+ (119 . |*|)
+ (|SparseUnivariatePolynomial| |$|)
+ |GCDDOM-;gcdPolynomial;3Sup;4|))
+ (QUOTE #(|lcm| 125 |gcdPolynomial| 136 |gcd| 142))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 41
+ (QUOTE (0 6 0 7 2 6 8 0 0 9 2 6 0 0 0 10 2 6 11 0 0 12 2 6 0 0 0
+ 13 2 6 0 0 0 15 0 6 0 16 4 18 6 17 0 6 6 19 1 23 8 0 24
+ 1 23 0 0 25 1 23 6 0 26 2 23 11 0 6 27 1 23 28 0 29 0 23
+ 0 30 0 23 0 31 2 23 0 6 28 32 2 23 11 0 0 33 1 23 28 0
+ 34 2 23 0 0 0 35 1 23 6 0 36 2 23 0 6 0 37 1 23 0 0 38 2
+ 23 0 0 0 39 1 0 0 20 21 2 0 0 0 0 14 2 0 40 40 40 41 1 0
+ 0 20 22))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category GROUP Group}
+<<category GROUP Group>>=
+)abbrev category GROUP Group
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The class of multiplicative groups, i.e. monoids with
+++ multiplicative inverses.
+++
+++ Axioms:
+++ \spad{leftInverse("*":(%,%)->%,inv)}\tab{30}\spad{ inv(x)*x = 1 }
+++ \spad{rightInverse("*":(%,%)->%,inv)}\tab{30}\spad{ x*inv(x) = 1 }
+Group(): Category == Monoid with
+ --operations
+ inv: % -> % ++ inv(x) returns the inverse of x.
+ "/": (%,%) -> % ++ x/y is the same as x times the inverse of y.
+ "**": (%,Integer) -> % ++ x**n returns x raised to the integer power n.
+ "^": (%,Integer) -> % ++ x^n returns x raised to the integer power n.
+ unitsKnown ++ unitsKnown asserts that recip only returns
+ ++ "failed" for non-units.
+ conjugate: (%,%) -> %
+ ++ conjugate(p,q) computes \spad{inv(q) * p * q}; this is 'right action
+ ++ by conjugation'.
+ commutator: (%,%) -> %
+ ++ commutator(p,q) computes \spad{inv(p) * inv(q) * p * q}.
+ add
+ import RepeatedSquaring(%)
+ x:% / y:% == x*inv(y)
+ recip(x:%) == inv(x)
+ _^(x:%, n:Integer):% == x ** n
+ x:% ** n:Integer ==
+ zero? n => 1
+ n<0 => expt(inv(x),(-n) pretend PositiveInteger)
+ expt(x,n pretend PositiveInteger)
+ conjugate(p,q) == inv(q) * p * q
+ commutator(p,q) == inv(p) * inv(q) * p * q
+
+@
+\section{category INTDOM IntegralDomain}
+<<category INTDOM IntegralDomain>>=
+)abbrev category INTDOM IntegralDomain
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References: Davenport & Trager I
+++ Description:
+++ The category of commutative integral domains, i.e. commutative
+++ rings with no zero divisors.
+++
+++ Conditional attributes:
+++ canonicalUnitNormal\tab{20}the canonical field is the same for all associates
+++ canonicalsClosed\tab{20}the product of two canonicals is itself canonical
+
+IntegralDomain(): Category ==
+-- Join(CommutativeRing, Algebra(%:CommutativeRing), EntireRing) with
+ Join(CommutativeRing, Algebra(%), EntireRing) with
+ --operations
+ "exquo": (%,%) -> Union(%,"failed")
+ ++ exquo(a,b) either returns an element c such that
+ ++ \spad{c*b=a} or "failed" if no such element can be found.
+ unitNormal: % -> Record(unit:%,canonical:%,associate:%)
+ ++ unitNormal(x) tries to choose a canonical element
+ ++ from the associate class of x.
+ ++ The attribute canonicalUnitNormal, if asserted, means that
+ ++ the "canonical" element is the same across all associates of x
+ ++ if \spad{unitNormal(x) = [u,c,a]} then
+ ++ \spad{u*c = x}, \spad{a*u = 1}.
+ unitCanonical: % -> %
+ ++ \spad{unitCanonical(x)} returns \spad{unitNormal(x).canonical}.
+ associates?: (%,%) -> Boolean
+ ++ associates?(x,y) tests whether x and y are associates, i.e.
+ ++ differ by a unit factor.
+ unit?: % -> Boolean
+ ++ unit?(x) tests whether x is a unit, i.e. is invertible.
+ add
+ -- declaration
+ x,y: %
+ -- definitions
+ UCA ==> Record(unit:%,canonical:%,associate:%)
+ if not (% has Field) then
+ unitNormal(x) == [1$%,x,1$%]$UCA -- the non-canonical definition
+ unitCanonical(x) == unitNormal(x).canonical -- always true
+ recip(x) == if zero? x then "failed" else _exquo(1$%,x)
+ unit?(x) == (recip x case "failed" => false; true)
+ if % has canonicalUnitNormal then
+ associates?(x,y) ==
+ (unitNormal x).canonical = (unitNormal y).canonical
+ else
+ associates?(x,y) ==
+ zero? x => zero? y
+ zero? y => false
+ x exquo y case "failed" => false
+ y exquo x case "failed" => false
+ true
+
+@
+\section{INTDOM.lsp BOOTSTRAP}
+{\bf INTDOM} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf INTDOM}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf INTDOM.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<INTDOM.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |IntegralDomain;AL| (QUOTE NIL))
+
+(DEFUN |IntegralDomain| NIL
+ (LET (#:G83060)
+ (COND
+ (|IntegralDomain;AL|)
+ (T (SETQ |IntegralDomain;AL| (|IntegralDomain;|))))))
+
+(DEFUN |IntegralDomain;| NIL
+ (PROG (#1=#:G83058)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|CommutativeRing|)
+ (|Algebra| (QUOTE |$|))
+ (|EntireRing|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|exquo| ((|Union| |$| "failed") |$| |$|)) T)
+ ((|unitNormal|
+ ((|Record|
+ (|:| |unit| |$|)
+ (|:| |canonical| |$|)
+ (|:| |associate| |$|)) |$|)) T)
+ ((|unitCanonical| (|$| |$|)) T)
+ ((|associates?| ((|Boolean|) |$| |$|)) T)
+ ((|unit?| ((|Boolean|) |$|)) T)))
+ NIL
+ (QUOTE ((|Boolean|)))
+ NIL))
+ |IntegralDomain|)
+ (SETELT #1# 0 (QUOTE (|IntegralDomain|)))))))
+
+(MAKEPROP (QUOTE |IntegralDomain|) (QUOTE NILADIC) T)
+
+@
+\section{INTDOM-.lsp BOOTSTRAP}
+{\bf INTDOM-} depends on {\bf INTDOM}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf INTDOM-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf INTDOM-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<INTDOM-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |INTDOM-;unitNormal;SR;1| (|x| |$|)
+ (VECTOR (|spadConstant| |$| 7) |x| (|spadConstant| |$| 7)))
+
+(DEFUN |INTDOM-;unitCanonical;2S;2| (|x| |$|)
+ (QVELT (SPADCALL |x| (QREFELT |$| 10)) 1))
+
+(DEFUN |INTDOM-;recip;SU;3| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 13)) (CONS 1 "failed"))
+ ((QUOTE T) (SPADCALL (|spadConstant| |$| 7) |x| (QREFELT |$| 15)))))
+
+(DEFUN |INTDOM-;unit?;SB;4| (|x| |$|)
+ (COND
+ ((QEQCAR (SPADCALL |x| (QREFELT |$| 17)) 1) (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |INTDOM-;associates?;2SB;5| (|x| |y| |$|)
+ (SPADCALL
+ (QVELT (SPADCALL |x| (QREFELT |$| 10)) 1)
+ (QVELT (SPADCALL |y| (QREFELT |$| 10)) 1)
+ (QREFELT |$| 19)))
+
+(DEFUN |INTDOM-;associates?;2SB;6| (|x| |y| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 13)) (SPADCALL |y| (QREFELT |$| 13)))
+ ((OR
+ (SPADCALL |y| (QREFELT |$| 13))
+ (OR
+ (QEQCAR (SPADCALL |x| |y| (QREFELT |$| 15)) 1)
+ (QEQCAR (SPADCALL |y| |x| (QREFELT |$| 15)) 1)))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |IntegralDomain&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|IntegralDomain&|))
+ (LETT |dv$| (LIST (QUOTE |IntegralDomain&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 21) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ (COND
+ ((|HasCategory| |#1| (QUOTE (|Field|))))
+ ((QUOTE T)
+ (QSETREFV |$| 9
+ (CONS (|dispatchFunction| |INTDOM-;unitNormal;SR;1|) |$|))))
+ (COND
+ ((|HasAttribute| |#1| (QUOTE |canonicalUnitNormal|))
+ (QSETREFV |$| 20
+ (CONS (|dispatchFunction| |INTDOM-;associates?;2SB;5|) |$|)))
+ ((QUOTE T)
+ (QSETREFV |$| 20
+ (CONS (|dispatchFunction| |INTDOM-;associates?;2SB;6|) |$|))))
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |IntegralDomain&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |One|)
+ (|Record| (|:| |unit| |$|) (|:| |canonical| |$|) (|:| |associate| |$|))
+ (4 . |unitNormal|)
+ (9 . |unitNormal|)
+ |INTDOM-;unitCanonical;2S;2|
+ (|Boolean|)
+ (14 . |zero?|)
+ (|Union| |$| (QUOTE "failed"))
+ (19 . |exquo|)
+ |INTDOM-;recip;SU;3|
+ (25 . |recip|)
+ |INTDOM-;unit?;SB;4|
+ (30 . |=|)
+ (36 . |associates?|)))
+ (QUOTE
+ #(|unitNormal| 42 |unitCanonical| 47 |unit?| 52 |recip| 57
+ |associates?| 62))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 20
+ (QUOTE
+ (0 6 0 7 1 0 8 0 9 1 6 8 0 10 1 6 12 0 13 2 6 14 0 0 15 1 6 14
+ 0 17 2 6 12 0 0 19 2 0 12 0 0 20 1 0 8 0 9 1 0 0 0 11 1 0 12 0
+ 18 1 0 14 0 16 2 0 12 0 0 20))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category LMODULE LeftModule}
+<<category LMODULE LeftModule>>=
+)abbrev category LMODULE LeftModule
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of left modules over an rng (ring not necessarily with unit).
+++ This is an abelian group which supports left multiplation by elements of
+++ the rng.
+++
+++ Axioms:
+++ \spad{ (a*b)*x = a*(b*x) }
+++ \spad{ (a+b)*x = (a*x)+(b*x) }
+++ \spad{ a*(x+y) = (a*x)+(a*y) }
+LeftModule(R:Rng):Category == AbelianGroup with
+ --operations
+ "*": (R,%) -> % ++ r*x returns the left multiplication of the module element x
+ ++ by the ring element r.
+
+@
+\section{category LINEXP LinearlyExplicitRingOver}
+<<category LINEXP LinearlyExplicitRingOver>>=
+)abbrev category LINEXP LinearlyExplicitRingOver
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ An extension ring with an explicit linear dependence test.
+LinearlyExplicitRingOver(R:Ring): Category == Ring with
+ reducedSystem: Matrix % -> Matrix R
+ ++ reducedSystem(A) returns a matrix B such that \spad{A x = 0} and \spad{B x = 0}
+ ++ have the same solutions in R.
+ reducedSystem: (Matrix %,Vector %) -> Record(mat:Matrix R,vec:Vector R)
+ ++ reducedSystem(A, v) returns a matrix B and a vector w such that
+ ++ \spad{A x = v} and \spad{B x = w} have the same solutions in R.
+
+@
+\section{category MODULE Module}
+<<category MODULE Module>>=
+)abbrev category MODULE Module
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of modules over a commutative ring.
+++
+++ Axioms:
+++ \spad{1*x = x}
+++ \spad{(a*b)*x = a*(b*x)}
+++ \spad{(a+b)*x = (a*x)+(b*x)}
+++ \spad{a*(x+y) = (a*x)+(a*y)}
+Module(R:CommutativeRing): Category == BiModule(R,R)
+ add
+ if not(R is %) then x:%*r:R == r*x
+
+@
+\section{category MONOID Monoid}
+<<category MONOID Monoid>>=
+)abbrev category MONOID Monoid
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The class of multiplicative monoids, i.e. semigroups with a
+++ multiplicative identity element.
+++
+++ Axioms:
+++ \spad{leftIdentity("*":(%,%)->%,1)}\tab{30}\spad{1*x=x}
+++ \spad{rightIdentity("*":(%,%)->%,1)}\tab{30}\spad{x*1=x}
+++
+++ Conditional attributes:
+++ unitsKnown\tab{15}\spadfun{recip} only returns "failed" on non-units
+Monoid(): Category == SemiGroup with
+ --operations
+ 1: constant -> % ++ 1 is the multiplicative identity.
+ sample: constant -> % ++ sample yields a value of type %
+ one?: % -> Boolean ++ one?(x) tests if x is equal to 1.
+ "**": (%,NonNegativeInteger) -> % ++ x**n returns the repeated product
+ ++ of x n times, i.e. exponentiation.
+ "^" : (%,NonNegativeInteger) -> % ++ x^n returns the repeated product
+ ++ of x n times, i.e. exponentiation.
+ recip: % -> Union(%,"failed")
+ ++ recip(x) tries to compute the multiplicative inverse for x
+ ++ or "failed" if it cannot find the inverse (see unitsKnown).
+ add
+ import RepeatedSquaring(%)
+ _^(x:%, n:NonNegativeInteger):% == x ** n
+ one? x == x = 1
+ sample() == 1
+ recip x ==
+-- one? x => x
+ (x = 1) => x
+ "failed"
+ x:% ** n:NonNegativeInteger ==
+ zero? n => 1
+ expt(x,n pretend PositiveInteger)
+
+@
+\section{MONOID.lsp BOOTSTRAP}
+{\bf MONOID} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf MONOID}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf MONOID.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<MONOID.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |Monoid;AL| (QUOTE NIL))
+
+(DEFUN |Monoid| NIL
+ (LET (#:G82434)
+ (COND
+ (|Monoid;AL|)
+ (T (SETQ |Monoid;AL| (|Monoid;|))))))
+
+(DEFUN |Monoid;| NIL
+ (PROG (#1=#:G82432)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|SemiGroup|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|One| (|$|) |constant|) T)
+ ((|sample| (|$|) |constant|) T)
+ ((|one?| ((|Boolean|) |$|)) T)
+ ((|**| (|$| |$| (|NonNegativeInteger|))) T)
+ ((|^| (|$| |$| (|NonNegativeInteger|))) T)
+ ((|recip| ((|Union| |$| "failed") |$|)) T)))
+ NIL
+ (QUOTE ((|NonNegativeInteger|) (|Boolean|)))
+ NIL))
+ |Monoid|)
+ (SETELT #1# 0 (QUOTE (|Monoid|)))))))
+
+(MAKEPROP (QUOTE |Monoid|) (QUOTE NILADIC) T)
+
+@
+\section{MONOID-.lsp BOOTSTRAP}
+{\bf MONOID-} depends on {\bf MONOID}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf MONOID-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf MONOID-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<MONOID-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |MONOID-;^;SNniS;1| (|x| |n| |$|)
+ (SPADCALL |x| |n| (QREFELT |$| 8)))
+
+(DEFUN |MONOID-;one?;SB;2| (|x| |$|)
+ (SPADCALL |x| (|spadConstant| |$| 10) (QREFELT |$| 12)))
+
+(DEFUN |MONOID-;sample;S;3| (|$|)
+ (|spadConstant| |$| 10))
+
+(DEFUN |MONOID-;recip;SU;4| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 15)) (CONS 0 |x|))
+ ((QUOTE T) (CONS 1 "failed"))))
+
+(DEFUN |MONOID-;**;SNniS;5| (|x| |n| |$|)
+ (COND
+ ((ZEROP |n|) (|spadConstant| |$| 10))
+ ((QUOTE T) (SPADCALL |x| |n| (QREFELT |$| 20)))))
+
+(DEFUN |Monoid&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|Monoid&|))
+ (LETT |dv$| (LIST (QUOTE |Monoid&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 22) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |Monoid&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|NonNegativeInteger|)
+ (0 . |**|)
+ |MONOID-;^;SNniS;1|
+ (6 . |One|)
+ (|Boolean|)
+ (10 . |=|)
+ |MONOID-;one?;SB;2|
+ |MONOID-;sample;S;3|
+ (16 . |one?|)
+ (|Union| |$| (QUOTE "failed"))
+ |MONOID-;recip;SU;4|
+ (|PositiveInteger|)
+ (|RepeatedSquaring| 6)
+ (21 . |expt|)
+ |MONOID-;**;SNniS;5|))
+ (QUOTE #(|sample| 27 |recip| 31 |one?| 36 |^| 41 |**| 47))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 21
+ (QUOTE
+ (2 6 0 0 7 8 0 6 0 10 2 6 11 0 0 12 1 6 11 0 15 2 19 6 6 18 20
+ 0 0 0 14 1 0 16 0 17 1 0 11 0 13 2 0 0 0 7 9 2 0 0 0 7 21))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category OAGROUP OrderedAbelianGroup}
+<<category OAGROUP OrderedAbelianGroup>>=
+)abbrev category OAGROUP OrderedAbelianGroup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered sets which are also abelian groups, such that the addition preserves
+++ the ordering.
+
+OrderedAbelianGroup(): Category ==
+ Join(OrderedCancellationAbelianMonoid, AbelianGroup)
+
+@
+\section{category OAMON OrderedAbelianMonoid}
+<<category OAMON OrderedAbelianMonoid>>=
+)abbrev category OAMON OrderedAbelianMonoid
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered sets which are also abelian monoids, such that the addition
+++ preserves the ordering.
+
+OrderedAbelianMonoid(): Category ==
+ Join(OrderedAbelianSemiGroup, AbelianMonoid)
+
+@
+\section{category OAMONS OrderedAbelianMonoidSup}
+<<category OAMONS OrderedAbelianMonoidSup>>=
+)abbrev category OAMONS OrderedAbelianMonoidSup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain is an OrderedAbelianMonoid with a \spadfun{sup} operation added.
+++ The purpose of the \spadfun{sup} operator in this domain is to act as a supremum
+++ with respect to the partial order imposed by \spadop{-}, rather than with respect to
+++ the total \spad{>} order (since that is "max").
+++
+++ Axioms:
+++ \spad{sup(a,b)-a \~~= "failed"}
+++ \spad{sup(a,b)-b \~~= "failed"}
+++ \spad{x-a \~~= "failed" and x-b \~~= "failed" => x >= sup(a,b)}
+
+OrderedAbelianMonoidSup(): Category == OrderedCancellationAbelianMonoid with
+ --operation
+ sup: (%,%) -> %
+ ++ sup(x,y) returns the least element from which both
+ ++ x and y can be subtracted.
+
+@
+\section{category OASGP OrderedAbelianSemiGroup}
+<<category OASGP OrderedAbelianSemiGroup>>=
+)abbrev category OASGP OrderedAbelianSemiGroup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered sets which are also abelian semigroups, such that the addition
+++ preserves the ordering.
+++ \spad{ x < y => x+z < y+z}
+
+OrderedAbelianSemiGroup(): Category == Join(OrderedSet, AbelianMonoid)
+
+@
+\section{category OCAMON OrderedCancellationAbelianMonoid}
+<<category OCAMON OrderedCancellationAbelianMonoid>>=
+)abbrev category OCAMON OrderedCancellationAbelianMonoid
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered sets which are also abelian cancellation monoids, such that the addition
+++ preserves the ordering.
+
+OrderedCancellationAbelianMonoid(): Category ==
+ Join(OrderedAbelianMonoid, CancellationAbelianMonoid)
+
+@
+\section{category ORDFIN OrderedFinite}
+<<category ORDFIN OrderedFinite>>=
+)abbrev category ORDFIN OrderedFinite
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered finite sets.
+
+OrderedFinite(): Category == Join(OrderedSet, Finite)
+
+@
+\section{category OINTDOM OrderedIntegralDomain}
+<<category OINTDOM OrderedIntegralDomain>>=
+)abbrev category OINTDOM OrderedIntegralDomain
+++ Author: JH Davenport (after L Gonzalez-Vega)
+++ Date Created: 30.1.96
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ The category of ordered commutative integral domains, where ordering
+++ and the arithmetic operations are compatible
+++
+
+OrderedIntegralDomain(): Category ==
+ Join(IntegralDomain, OrderedRing)
+
+@
+\section{OINTDOM.lsp BOOTSTRAP}
+{\bf OINTDOM} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf OINTDOM}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf OINTDOM.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<OINTDOM.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |OrderedIntegralDomain;AL| (QUOTE NIL))
+
+(DEFUN |OrderedIntegralDomain| NIL
+ (LET (#:G84531)
+ (COND
+ (|OrderedIntegralDomain;AL|)
+ (T (SETQ |OrderedIntegralDomain;AL| (|OrderedIntegralDomain;|))))))
+
+(DEFUN |OrderedIntegralDomain;| NIL
+ (PROG (#1=#:G84529)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join| (|IntegralDomain|) (|OrderedRing|)) |OrderedIntegralDomain|)
+ (SETELT #1# 0 (QUOTE (|OrderedIntegralDomain|)))))))
+
+(MAKEPROP (QUOTE |OrderedIntegralDomain|) (QUOTE NILADIC) T)
+
+@
+\section{category ORDMON OrderedMonoid}
+<<category ORDMON OrderedMonoid>>=
+)abbrev category ORDMON OrderedMonoid
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered sets which are also monoids, such that multiplication
+++ preserves the ordering.
+++
+++ Axioms:
+++ \spad{x < y => x*z < y*z}
+++ \spad{x < y => z*x < z*y}
+
+OrderedMonoid(): Category == Join(OrderedSet, Monoid)
+
+@
+\section{category ORDRING OrderedRing}
+<<category ORDRING OrderedRing>>=
+)abbrev category ORDRING OrderedRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Ordered sets which are also rings, that is, domains where the ring
+++ operations are compatible with the ordering.
+++
+++ Axiom:
+++ \spad{0<a and b<c => ab< ac}
+
+OrderedRing(): Category == Join(OrderedAbelianGroup,Ring,Monoid) with
+ positive?: % -> Boolean
+ ++ positive?(x) tests whether x is strictly greater than 0.
+ negative?: % -> Boolean
+ ++ negative?(x) tests whether x is strictly less than 0.
+ sign : % -> Integer
+ ++ sign(x) is 1 if x is positive, -1 if x is negative, 0 if x equals 0.
+ abs : % -> %
+ ++ abs(x) returns the absolute value of x.
+ add
+ positive? x == x>0
+ negative? x == x<0
+ sign x ==
+ positive? x => 1
+ negative? x => -1
+ zero? x => 0
+ error "x satisfies neither positive?, negative? or zero?"
+ abs x ==
+ positive? x => x
+ negative? x => -x
+ zero? x => 0
+ error "x satisfies neither positive?, negative? or zero?"
+
+@
+\section{ORDRING.lsp BOOTSTRAP}
+{\bf ORDRING} depends on {\bf INT}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ORDRING}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ORDRING.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Technically I can't justify this bootstrap stanza based on the lattice
+since {\bf INT} is already bootstrapped. However using {\bf INT} naked
+generates a "value stack overflow" error suggesting an infinite recursive
+loop. This code is here to experiment with breaking that loop.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ORDRING.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |OrderedRing;AL| (QUOTE NIL))
+
+(DEFUN |OrderedRing| NIL
+ (LET (#:G84457)
+ (COND
+ (|OrderedRing;AL|)
+ (T (SETQ |OrderedRing;AL| (|OrderedRing;|))))))
+
+(DEFUN |OrderedRing;| NIL
+ (PROG (#1=#:G84455)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|OrderedAbelianGroup|)
+ (|Ring|)
+ (|Monoid|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|positive?| ((|Boolean|) |$|)) T)
+ ((|negative?| ((|Boolean|) |$|)) T)
+ ((|sign| ((|Integer|) |$|)) T)
+ ((|abs| (|$| |$|)) T)))
+ NIL
+ (QUOTE ((|Integer|) (|Boolean|)))
+ NIL))
+ |OrderedRing|)
+ (SETELT #1# 0 (QUOTE (|OrderedRing|)))))))
+
+(MAKEPROP (QUOTE |OrderedRing|) (QUOTE NILADIC) T)
+
+@
+\section{ORDRING-.lsp BOOTSTRAP}
+{\bf ORDRING-} depends on {\bf ORDRING}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ORDRING-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ORDRING-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ORDRING-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |ORDRING-;positive?;SB;1| (|x| |$|)
+ (SPADCALL (|spadConstant| |$| 7) |x| (QREFELT |$| 9)))
+
+(DEFUN |ORDRING-;negative?;SB;2| (|x| |$|)
+ (SPADCALL |x| (|spadConstant| |$| 7) (QREFELT |$| 9)))
+
+(DEFUN |ORDRING-;sign;SI;3| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 12)) 1)
+ ((SPADCALL |x| (QREFELT |$| 13)) -1)
+ ((SPADCALL |x| (QREFELT |$| 15)) 0)
+ ((QUOTE T)
+ (|error| "x satisfies neither positive?, negative? or zero?"))))
+
+(DEFUN |ORDRING-;abs;2S;4| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 12)) |x|)
+ ((SPADCALL |x| (QREFELT |$| 13)) (SPADCALL |x| (QREFELT |$| 18)))
+ ((SPADCALL |x| (QREFELT |$| 15)) (|spadConstant| |$| 7))
+ ((QUOTE T)
+ (|error| "x satisfies neither positive?, negative? or zero?"))))
+
+(DEFUN |OrderedRing&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|OrderedRing&|))
+ (LETT |dv$| (LIST (QUOTE |OrderedRing&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 20) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |OrderedRing&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |Zero|)
+ (|Boolean|)
+ (4 . |<|)
+ |ORDRING-;positive?;SB;1|
+ |ORDRING-;negative?;SB;2|
+ (10 . |positive?|)
+ (15 . |negative?|)
+ (20 . |One|)
+ (24 . |zero?|)
+ (|Integer|)
+ |ORDRING-;sign;SI;3|
+ (29 . |-|)
+ |ORDRING-;abs;2S;4|))
+ (QUOTE #(|sign| 34 |positive?| 39 |negative?| 44 |abs| 49))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 19
+ (QUOTE
+ (0 6 0 7 2 6 8 0 0 9 1 6 8 0 12 1 6 8 0 13 0 6 0 14 1 6 8 0 15
+ 1 6 0 0 18 1 0 16 0 17 1 0 8 0 10 1 0 8 0 11 1 0 0 0 19))))))
+ (QUOTE |lookupComplete|)))
+@
+\section{category ORDSET OrderedSet}
+<<category ORDSET OrderedSet>>=
+)abbrev category ORDSET OrderedSet
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The class of totally ordered sets, that is, sets such that for each pair of elements \spad{(a,b)}
+++ exactly one of the following relations holds \spad{a<b or a=b or b<a}
+++ and the relation is transitive, i.e. \spad{a<b and b<c => a<c}.
+
+OrderedSet(): Category == SetCategory with
+ --operations
+ "<": (%,%) -> Boolean
+ ++ x < y is a strict total ordering on the elements of the set.
+ ">": (%, %) -> Boolean
+ ++ x > y is a greater than test.
+ ">=": (%, %) -> Boolean
+ ++ x >= y is a greater than or equal test.
+ "<=": (%, %) -> Boolean
+ ++ x <= y is a less than or equal test.
+
+ max: (%,%) -> %
+ ++ max(x,y) returns the maximum of x and y relative to "<".
+ min: (%,%) -> %
+ ++ min(x,y) returns the minimum of x and y relative to "<".
+ add
+ --declarations
+ x,y: %
+ --definitions
+ -- These really ought to become some sort of macro
+ max(x,y) ==
+ x > y => x
+ y
+ min(x,y) ==
+ x > y => y
+ x
+ ((x: %) > (y: %)) : Boolean == y < x
+ ((x: %) >= (y: %)) : Boolean == not (x < y)
+ ((x: %) <= (y: %)) : Boolean == not (y < x)
+
+@
+\section{category PDRING PartialDifferentialRing}
+<<category PDRING PartialDifferentialRing>>=
+)abbrev category PDRING PartialDifferentialRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A partial differential ring with differentiations indexed by a parameter type S.
+++
+++ Axioms:
+++ \spad{differentiate(x+y,e) = differentiate(x,e)+differentiate(y,e)}
+++ \spad{differentiate(x*y,e) = x*differentiate(y,e) + differentiate(x,e)*y}
+
+PartialDifferentialRing(S:SetCategory): Category == Ring with
+ differentiate: (%, S) -> %
+ ++ differentiate(x,v) computes the partial derivative of x
+ ++ with respect to v.
+ differentiate: (%, List S) -> %
+ ++ differentiate(x,[s1,...sn]) computes successive partial derivatives,
+ ++ i.e. \spad{differentiate(...differentiate(x, s1)..., sn)}.
+ differentiate: (%, S, NonNegativeInteger) -> %
+ ++ differentiate(x, s, n) computes multiple partial derivatives, i.e.
+ ++ n-th derivative of x with respect to s.
+ differentiate: (%, List S, List NonNegativeInteger) -> %
+ ++ differentiate(x, [s1,...,sn], [n1,...,nn]) computes
+ ++ multiple partial derivatives, i.e.
+ D: (%, S) -> %
+ ++ D(x,v) computes the partial derivative of x
+ ++ with respect to v.
+ D: (%, List S) -> %
+ ++ D(x,[s1,...sn]) computes successive partial derivatives,
+ ++ i.e. \spad{D(...D(x, s1)..., sn)}.
+ D: (%, S, NonNegativeInteger) -> %
+ ++ D(x, s, n) computes multiple partial derivatives, i.e.
+ ++ n-th derivative of x with respect to s.
+ D: (%, List S, List NonNegativeInteger) -> %
+ ++ D(x, [s1,...,sn], [n1,...,nn]) computes
+ ++ multiple partial derivatives, i.e.
+ ++ \spad{D(...D(x, s1, n1)..., sn, nn)}.
+ add
+ differentiate(r:%, l:List S) ==
+ for s in l repeat r := differentiate(r, s)
+ r
+
+ differentiate(r:%, s:S, n:NonNegativeInteger) ==
+ for i in 1..n repeat r := differentiate(r, s)
+ r
+
+ differentiate(r:%, ls:List S, ln:List NonNegativeInteger) ==
+ for s in ls for n in ln repeat r := differentiate(r, s, n)
+ r
+
+ D(r:%, v:S) == differentiate(r,v)
+ D(r:%, lv:List S) == differentiate(r,lv)
+ D(r:%, v:S, n:NonNegativeInteger) == differentiate(r,v,n)
+ D(r:%, lv:List S, ln:List NonNegativeInteger) == differentiate(r, lv, ln)
+
+@
+\section{category PFECAT PolynomialFactorizationExplicit}
+<<category PFECAT PolynomialFactorizationExplicit>>=
+)abbrev category PFECAT PolynomialFactorizationExplicit
+++ Author: James Davenport
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is the category of domains that know "enough" about
+++ themselves in order to factor univariate polynomials over themselves.
+++ This will be used in future releases for supporting factorization
+++ over finitely generated coefficient fields, it is not yet available
+++ in the current release of axiom.
+
+PolynomialFactorizationExplicit(): Category == Definition where
+ P ==> SparseUnivariatePolynomial %
+ Definition ==>
+ UniqueFactorizationDomain with
+ -- operations
+ squareFreePolynomial: P -> Factored(P)
+ ++ squareFreePolynomial(p) returns the
+ ++ square-free factorization of the
+ ++ univariate polynomial p.
+ factorPolynomial: P -> Factored(P)
+ ++ factorPolynomial(p) returns the factorization
+ ++ into irreducibles of the univariate polynomial p.
+ factorSquareFreePolynomial: P -> Factored(P)
+ ++ factorSquareFreePolynomial(p) factors the
+ ++ univariate polynomial p into irreducibles
+ ++ where p is known to be square free
+ ++ and primitive with respect to its main variable.
+ gcdPolynomial: (P, P) -> P
+ ++ gcdPolynomial(p,q) returns the gcd of the univariate
+ ++ polynomials p qnd q.
+ -- defaults to Euclidean, but should be implemented via
+ -- modular or p-adic methods.
+ solveLinearPolynomialEquation: (List P, P) -> Union(List P,"failed")
+ ++ solveLinearPolynomialEquation([f1, ..., fn], g)
+ ++ (where the fi are relatively prime to each other)
+ ++ returns a list of ai such that
+ ++ \spad{g/prod fi = sum ai/fi}
+ ++ or returns "failed" if no such list of ai's exists.
+ if % has CharacteristicNonZero then
+ conditionP: Matrix % -> Union(Vector %,"failed")
+ ++ conditionP(m) returns a vector of elements, not all zero,
+ ++ whose \spad{p}-th powers (p is the characteristic of the domain)
+ ++ are a solution of the homogenous linear system represented
+ ++ by m, or "failed" is there is no such vector.
+ charthRoot: % -> Union(%,"failed")
+ ++ charthRoot(r) returns the \spad{p}-th root of r, or "failed"
+ ++ if none exists in the domain.
+ -- this is a special case of conditionP, but often the one we want
+ add
+ gcdPolynomial(f,g) ==
+ zero? f => g
+ zero? g => f
+ cf:=content f
+ if not one? cf then f:=(f exquo cf)::P
+ cg:=content g
+ if not one? cg then g:=(g exquo cg)::P
+ ans:=subResultantGcd(f,g)$P
+ gcd(cf,cg)*(ans exquo content ans)::P
+ if % has CharacteristicNonZero then
+ charthRoot f ==
+ -- to take p'th root of f, solve the system X-fY=0,
+ -- so solution is [x,y]
+ -- with x^p=X and y^p=Y, then (x/y)^p = f
+ zero? f => 0
+ m:Matrix % := matrix [[1,-f]]
+ ans:= conditionP m
+ ans case "failed" => "failed"
+ (ans.1) exquo (ans.2)
+ if % has Field then
+ solveLinearPolynomialEquation(lf,g) ==
+ multiEuclidean(lf,g)$P
+ else solveLinearPolynomialEquation(lf,g) ==
+ LPE ==> LinearPolynomialEquationByFractions %
+ solveLinearPolynomialEquationByFractions(lf,g)$LPE
+
+@
+\section{category PID PrincipalIdealDomain}
+<<category PID PrincipalIdealDomain>>=
+)abbrev category PID PrincipalIdealDomain
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of constructive principal ideal domains, i.e.
+++ where a single generator can be constructively found for
+++ any ideal given by a finite set of generators.
+++ Note that this constructive definition only implies that
+++ finitely generated ideals are principal. It is not clear
+++ what we would mean by an infinitely generated ideal.
+
+PrincipalIdealDomain(): Category == GcdDomain with
+ --operations
+ principalIdeal: List % -> Record(coef:List %,generator:%)
+ ++ principalIdeal([f1,...,fn]) returns a record whose
+ ++ generator component is a generator of the ideal
+ ++ generated by \spad{[f1,...,fn]} whose coef component satisfies
+ ++ \spad{generator = sum (input.i * coef.i)}
+ expressIdealMember: (List %,%) -> Union(List %,"failed")
+ ++ expressIdealMember([f1,...,fn],h) returns a representation
+ ++ of h as a linear combination of the fi or "failed" if h
+ ++ is not in the ideal generated by the fi.
+
+@
+\section{category RMODULE RightModule}
+<<category RMODULE RightModule>>=
+)abbrev category RMODULE RightModule
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of right modules over an rng (ring not necessarily with unit).
+++ This is an abelian group which supports right multiplation by elements of
+++ the rng.
+++
+++ Axioms:
+++ \spad{ x*(a*b) = (x*a)*b }
+++ \spad{ x*(a+b) = (x*a)+(x*b) }
+++ \spad{ (x+y)*x = (x*a)+(y*a) }
+RightModule(R:Rng):Category == AbelianGroup with
+ --operations
+ "*": (%,R) -> % ++ x*r returns the right multiplication of the module element x
+ ++ by the ring element r.
+
+@
+\section{category RING Ring}
+<<category RING Ring>>=
+)abbrev category RING Ring
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of rings with unity, always associative, but
+++ not necessarily commutative.
+
+--Ring(): Category == Join(Rng,Monoid,LeftModule(%:Rng)) with
+Ring(): Category == Join(Rng,Monoid,LeftModule(%)) with
+ --operations
+ characteristic: () -> NonNegativeInteger
+ ++ characteristic() returns the characteristic of the ring
+ ++ this is the smallest positive integer n such that
+ ++ \spad{n*x=0} for all x in the ring, or zero if no such n
+ ++ exists.
+ --We can not make this a constant, since some domains are mutable
+ coerce: Integer -> %
+ ++ coerce(i) converts the integer i to a member of the given domain.
+-- recip: % -> Union(%,"failed") -- inherited from Monoid
+ unitsKnown
+ ++ recip truly yields
+ ++ reciprocal or "failed" if not a unit.
+ ++ Note: \spad{recip(0) = "failed"}.
+ add
+ n:Integer
+ coerce(n) == n * 1$%
+
+@
+\section{RING.lsp BOOTSTRAP}
+{\bf RING} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf RING}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf RING.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RING.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |Ring;AL| (QUOTE NIL))
+
+(DEFUN |Ring| NIL
+ (LET (#:G82789)
+ (COND
+ (|Ring;AL|)
+ (T (SETQ |Ring;AL| (|Ring;|))))))
+
+(DEFUN |Ring;| NIL
+ (PROG (#1=#:G82787)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|Rng|)
+ (|Monoid|)
+ (|LeftModule| (QUOTE |$|))
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|characteristic| ((|NonNegativeInteger|))) T)
+ ((|coerce| (|$| (|Integer|))) T)))
+ (QUOTE ((|unitsKnown| T)))
+ (QUOTE ((|Integer|) (|NonNegativeInteger|)))
+ NIL))
+ |Ring|)
+ (SETELT #1# 0 (QUOTE (|Ring|)))))))
+
+(MAKEPROP (QUOTE |Ring|) (QUOTE NILADIC) T)
+
+@
+\section{RING-.lsp BOOTSTRAP}
+{\bf RING-} depends on {\bf RING}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf RING-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf RING-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RING-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |RING-;coerce;IS;1| (|n| |$|)
+ (SPADCALL |n| (|spadConstant| |$| 7) (QREFELT |$| 9)))
+
+(DEFUN |Ring&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|Ring&|))
+ (LETT |dv$| (LIST (QUOTE |Ring&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 12) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |Ring&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (0 . |One|)
+ (|Integer|)
+ (4 . |*|)
+ |RING-;coerce;IS;1|
+ (|OutputForm|)))
+ (QUOTE #(|coerce| 10))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 10 (QUOTE (0 6 0 7 2 6 0 8 0 9 1 0 0 8 10))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category RNG Rng}
+<<category RNG Rng>>=
+)abbrev category RNG Rng
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of associative rings, not necessarily commutative, and not
+++ necessarily with a 1. This is a combination of an abelian group
+++ and a semigroup, with multiplication distributing over addition.
+++
+++ Axioms:
+++ \spad{ x*(y+z) = x*y + x*z}
+++ \spad{ (x+y)*z = x*z + y*z }
+++
+++ Conditional attributes:
+++ \spadnoZeroDivisors\tab{25}\spad{ ab = 0 => a=0 or b=0}
+Rng(): Category == Join(AbelianGroup,SemiGroup)
+
+@
+\section{RNG.lsp BOOTSTRAP}
+{\bf RNG} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf RNG} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf RNG.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RNG.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |Rng;AL| (QUOTE NIL))
+
+(DEFUN |Rng| NIL
+ (LET (#:G82722)
+ (COND
+ (|Rng;AL|)
+ (T (SETQ |Rng;AL| (|Rng;|))))))
+
+(DEFUN |Rng;| NIL
+ (PROG (#1=#:G82720)
+ (RETURN
+ (PROG1
+ (LETT #1# (|Join| (|AbelianGroup|) (|SemiGroup|)) |Rng|)
+ (SETELT #1# 0 (QUOTE (|Rng|)))))))
+
+(MAKEPROP (QUOTE |Rng|) (QUOTE NILADIC) T)
+
+@
+\section{category SGROUP SemiGroup}
+<<category SGROUP SemiGroup>>=
+)abbrev category SGROUP SemiGroup
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ the class of all multiplicative semigroups, i.e. a set
+++ with an associative operation \spadop{*}.
+++
+++ Axioms:
+++ \spad{associative("*":(%,%)->%)}\tab{30}\spad{ (x*y)*z = x*(y*z)}
+++
+++ Conditional attributes:
+++ \spad{commutative("*":(%,%)->%)}\tab{30}\spad{ x*y = y*x }
+SemiGroup(): Category == SetCategory with
+ --operations
+ "*": (%,%) -> % ++ x*y returns the product of x and y.
+ "**": (%,PositiveInteger) -> % ++ x**n returns the repeated product
+ ++ of x n times, i.e. exponentiation.
+ "^": (%,PositiveInteger) -> % ++ x^n returns the repeated product
+ ++ of x n times, i.e. exponentiation.
+ add
+ import RepeatedSquaring(%)
+ x:% ** n:PositiveInteger == expt(x,n)
+ _^(x:%, n:PositiveInteger):% == x ** n
+
+@
+\section{category SETCAT SetCategory}
+<<category SETCAT SetCategory>>=
+)abbrev category SETCAT SetCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ 09/09/92 RSS added latex and hash
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{SetCategory} is the basic category for describing a collection
+++ of elements with \spadop{=} (equality) and \spadfun{coerce} to output form.
+++
+++ Conditional Attributes:
+++ canonical\tab{15}data structure equality is the same as \spadop{=}
+SetCategory(): Category == Join(BasicType,CoercibleTo OutputForm) with
+ --operations
+ hash: % -> SingleInteger ++ hash(s) calculates a hash code for s.
+ latex: % -> String ++ latex(s) returns a LaTeX-printable output
+ ++ representation of s.
+ add
+ hash(s : %): SingleInteger == 0$SingleInteger
+ latex(s : %): String == "\mbox{\bf Unimplemented}"
+
+@
+\section{SETCAT.lsp BOOTSTRAP}
+{\bf SETCAT} needs
+{\bf SINT} which needs
+{\bf UFD} which needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON} which needs
+{\bf ABELSG} which needs
+{\bf SETCAT}. We break this chain with {\bf SETCAT.lsp} which we
+cache here. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf SETCAT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf SETCAT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SETCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |SetCategory;AL| (QUOTE NIL))
+
+(DEFUN |SetCategory| NIL
+ (LET (#:G82359)
+ (COND
+ (|SetCategory;AL|)
+ (T (SETQ |SetCategory;AL| (|SetCategory;|))))))
+
+(DEFUN |SetCategory;| NIL
+ (PROG (#1=#:G82357)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR
+ (QUOTE (#2=#:G82356))
+ (LIST (QUOTE (|OutputForm|))))
+ (|Join|
+ (|BasicType|)
+ (|CoercibleTo| (QUOTE #2#))
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|hash| ((|SingleInteger|) |$|)) T)
+ ((|latex| ((|String|) |$|)) T)))
+ NIL
+ (QUOTE ((|String|) (|SingleInteger|)))
+ NIL)))
+ |SetCategory|)
+ (SETELT #1# 0 (QUOTE (|SetCategory|)))))))
+
+(MAKEPROP (QUOTE |SetCategory|) (QUOTE NILADIC) T)
+
+@
+\section{SETCAT-.lsp BOOTSTRAP}
+{\bf SETCAT-} is the implementation of the operations exported
+by {\bf SETCAT}. It comes into existance whenever {\bf SETCAT}
+gets compiled by Axiom. However this will not happen at the
+lisp level so we also cache this information here. See the
+explanation under the {\bf SETCAT.lsp} section for more details.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SETCAT-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT
+ (QUOTE |SETCAT-;hash;SSi;1|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|s|) 0)))
+
+(DEFUN |SETCAT-;hash;SSi;1| (|s| |$|) 0)
+
+(PUT
+ (QUOTE |SETCAT-;latex;SS;2|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|s|) "\\mbox{\\bf Unimplemented}")))
+
+(DEFUN |SETCAT-;latex;SS;2| (|s| |$|)
+ "\\mbox{\\bf Unimplemented}")
+
+(DEFUN |SetCategory&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|SetCategory&|))
+ (LETT |dv$| (LIST (QUOTE |SetCategory&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 11) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |SetCategory&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|SingleInteger|)
+ |SETCAT-;hash;SSi;1|
+ (|String|)
+ |SETCAT-;latex;SS;2|))
+ (QUOTE
+ #(|latex| 0 |hash| 5))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2|
+ 10
+ (QUOTE (1 0 9 0 10 1 0 7 0 8))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category STEP StepThrough}
+<<category STEP StepThrough>>=
+)abbrev category STEP StepThrough
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A class of objects which can be 'stepped through'.
+++ Repeated applications of \spadfun{nextItem} is guaranteed never to
+++ return duplicate items and only return "failed" after exhausting
+++ all elements of the domain.
+++ This assumes that the sequence starts with \spad{init()}.
+++ For infinite domains, repeated application
+++ of \spadfun{nextItem} is not required to reach all possible domain elements
+++ starting from any initial element.
+++
+++ Conditional attributes:
+++ infinite\tab{15}repeated \spad{nextItem}'s are never "failed".
+StepThrough(): Category == SetCategory with
+ --operations
+ init: constant -> %
+ ++ init() chooses an initial object for stepping.
+ nextItem: % -> Union(%,"failed")
+ ++ nextItem(x) returns the next item, or "failed" if domain is exhausted.
+
+@
+\section{category UFD UniqueFactorizationDomain}
+<<category UFD UniqueFactorizationDomain>>=
+)abbrev category UFD UniqueFactorizationDomain
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A constructive unique factorization domain, i.e. where
+++ we can constructively factor members into a product of
+++ a finite number of irreducible elements.
+
+UniqueFactorizationDomain(): Category == GcdDomain with
+ --operations
+ prime?: % -> Boolean
+ ++ prime?(x) tests if x can never be written as the product of two
+ ++ non-units of the ring,
+ ++ i.e., x is an irreducible element.
+ squareFree : % -> Factored(%)
+ ++ squareFree(x) returns the square-free factorization of x
+ ++ i.e. such that the factors are pairwise relatively prime
+ ++ and each has multiple prime factors.
+ squareFreePart: % -> %
+ ++ squareFreePart(x) returns a product of prime factors of
+ ++ x each taken with multiplicity one.
+ factor: % -> Factored(%)
+ ++ factor(x) returns the factorization of x into irreducibles.
+ add
+ squareFreePart x ==
+ unit(s := squareFree x) * _*/[f.factor for f in factors s]
+
+ prime? x == # factorList factor x = 1
+
+@
+\section{UFD.lsp BOOTSTRAP}
+{\bf UFD} needs
+{\bf GCDDOM} which needs
+{\bf COMRING} which needs
+{\bf RING} which needs
+{\bf RNG} which needs
+{\bf ABELGRP} which needs
+{\bf CABMON} which needs
+{\bf ABELMON} which needs
+{\bf ABELSG} which needs
+{\bf SETCAT} which needs
+{\bf SINT} which needs
+{\bf UFD}.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf UFD} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf UFD.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<UFD.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |UniqueFactorizationDomain;AL| (QUOTE NIL))
+
+(DEFUN |UniqueFactorizationDomain| NIL
+ (LET (#:G83334)
+ (COND
+ (|UniqueFactorizationDomain;AL|)
+ (T
+ (SETQ
+ |UniqueFactorizationDomain;AL|
+ (|UniqueFactorizationDomain;|))))))
+
+(DEFUN |UniqueFactorizationDomain;| NIL
+ (PROG (#1=#:G83332)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|GcdDomain|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|prime?| ((|Boolean|) |$|)) T)
+ ((|squareFree| ((|Factored| |$|) |$|)) T)
+ ((|squareFreePart| (|$| |$|)) T)
+ ((|factor| ((|Factored| |$|) |$|)) T)))
+ NIL
+ (QUOTE ((|Factored| |$|) (|Boolean|)))
+ NIL))
+ |UniqueFactorizationDomain|)
+ (SETELT #1# 0 (QUOTE (|UniqueFactorizationDomain|)))))))
+
+(MAKEPROP (QUOTE |UniqueFactorizationDomain|) (QUOTE NILADIC) T)
+
+@
+\section{UFD-.lsp BOOTSTRAP}
+{\bf UFD-} needs {\bf UFD}.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf UFD-} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf UFD-.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<UFD-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |UFD-;squareFreePart;2S;1| (|x| |$|)
+ (PROG (|s| |f| #1=#:G83349 #2=#:G83347 #3=#:G83345 #4=#:G83346)
+ (RETURN
+ (SEQ
+ (SPADCALL
+ (SPADCALL
+ (LETT |s|
+ (SPADCALL |x| (QREFELT |$| 8))
+ |UFD-;squareFreePart;2S;1|)
+ (QREFELT |$| 10))
+ (PROGN
+ (LETT #4# NIL |UFD-;squareFreePart;2S;1|)
+ (SEQ
+ (LETT |f| NIL |UFD-;squareFreePart;2S;1|)
+ (LETT #1#
+ (SPADCALL |s| (QREFELT |$| 13))
+ |UFD-;squareFreePart;2S;1|)
+ G190
+ (COND
+ ((OR
+ (ATOM #1#)
+ (PROGN
+ (LETT |f| (CAR #1#) |UFD-;squareFreePart;2S;1|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (PROGN
+ (LETT #2# (QCAR |f|) |UFD-;squareFreePart;2S;1|)
+ (COND
+ (#4#
+ (LETT #3#
+ (SPADCALL #3# #2# (QREFELT |$| 14))
+ |UFD-;squareFreePart;2S;1|))
+ ((QUOTE T)
+ (PROGN
+ (LETT #3# #2# |UFD-;squareFreePart;2S;1|)
+ (LETT #4# (QUOTE T) |UFD-;squareFreePart;2S;1|)))))))
+ (LETT #1# (CDR #1#) |UFD-;squareFreePart;2S;1|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ (#4# #3#)
+ ((QUOTE T) (|spadConstant| |$| 15))))
+ (QREFELT |$| 14))))))
+
+(DEFUN |UFD-;prime?;SB;2| (|x| |$|)
+ (EQL
+ (LENGTH (SPADCALL (SPADCALL |x| (QREFELT |$| 17)) (QREFELT |$| 21))) 1))
+
+(DEFUN |UniqueFactorizationDomain&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|UniqueFactorizationDomain&|))
+ (LETT |dv$| (LIST (QUOTE |UniqueFactorizationDomain&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 24) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |UniqueFactorizationDomain&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|Factored| |$|)
+ (0 . |squareFree|)
+ (|Factored| 6)
+ (5 . |unit|)
+ (|Record| (|:| |factor| 6) (|:| |exponent| (|Integer|)))
+ (|List| 11)
+ (10 . |factors|)
+ (15 . |*|)
+ (21 . |One|)
+ |UFD-;squareFreePart;2S;1|
+ (25 . |factor|)
+ (|Union| (QUOTE "nil") (QUOTE "sqfr") (QUOTE "irred") (QUOTE "prime"))
+ (|Record| (|:| |flg| 18) (|:| |fctr| 6) (|:| |xpnt| (|Integer|)))
+ (|List| 19)
+ (30 . |factorList|)
+ (|Boolean|)
+ |UFD-;prime?;SB;2|))
+ (QUOTE #(|squareFreePart| 35 |prime?| 40))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 23
+ (QUOTE
+ (1 6 7 0 8 1 9 6 0 10 1 9 12 0 13 2 6 0 0 0 14 0 6 0 15 1 6 7
+ 0 17 1 9 20 0 21 1 0 0 0 16 1 0 22 0 23))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category VSPACE VectorSpace}
+<<category VSPACE VectorSpace>>=
+)abbrev category VSPACE VectorSpace
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Vector Spaces (not necessarily finite dimensional) over a field.
+
+VectorSpace(S:Field): Category == Module(S) with
+ "/" : (%, S) -> %
+ ++ x/y divides the vector x by the scalar y.
+ dimension: () -> CardinalNumber
+ ++ dimension() returns the dimensionality of the vector space.
+ add
+ (v:% / s:S):% == inv(s) * v
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category BASTYPE BasicType>>
+<<category SETCAT SetCategory>>
+<<category STEP StepThrough>>
+<<category SGROUP SemiGroup>>
+<<category MONOID Monoid>>
+<<category GROUP Group>>
+<<category ABELSG AbelianSemiGroup>>
+<<category ABELMON AbelianMonoid>>
+<<category CABMON CancellationAbelianMonoid>>
+<<category ABELGRP AbelianGroup>>
+<<category RNG Rng>>
+<<category LMODULE LeftModule>>
+<<category RMODULE RightModule>>
+<<category RING Ring>>
+<<category BMODULE BiModule>>
+<<category ENTIRER EntireRing>>
+<<category CHARZ CharacteristicZero>>
+<<category CHARNZ CharacteristicNonZero>>
+<<category COMRING CommutativeRing>>
+<<category MODULE Module>>
+<<category ALGEBRA Algebra>>
+<<category LINEXP LinearlyExplicitRingOver>>
+<<category FLINEXP FullyLinearlyExplicitRingOver>>
+<<category INTDOM IntegralDomain>>
+<<category GCDDOM GcdDomain>>
+<<category UFD UniqueFactorizationDomain>>
+<<category PFECAT PolynomialFactorizationExplicit>>
+<<category PID PrincipalIdealDomain>>
+<<category EUCDOM EuclideanDomain>>
+<<category DIVRING DivisionRing>>
+<<category FIELD Field>>
+<<category FINITE Finite>>
+<<category VSPACE VectorSpace>>
+<<category ORDSET OrderedSet>>
+<<category ORDFIN OrderedFinite>>
+<<category ORDMON OrderedMonoid>>
+<<category OASGP OrderedAbelianSemiGroup>>
+<<category OAMON OrderedAbelianMonoid>>
+<<category OCAMON OrderedCancellationAbelianMonoid>>
+<<category OAGROUP OrderedAbelianGroup>>
+<<category ORDRING OrderedRing>>
+<<category OINTDOM OrderedIntegralDomain>>
+<<category OAMONS OrderedAbelianMonoidSup>>
+<<category DIFRING DifferentialRing>>
+<<category PDRING PartialDifferentialRing>>
+<<category DIFEXT DifferentialExtension>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/cden.spad.pamphlet b/src/algebra/cden.spad.pamphlet
new file mode 100644
index 00000000..55d3e924
--- /dev/null
+++ b/src/algebra/cden.spad.pamphlet
@@ -0,0 +1,238 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra cden.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ICDEN InnerCommonDenominator}
+<<package ICDEN InnerCommonDenominator>>=
+)abbrev package ICDEN InnerCommonDenominator
+--% InnerCommonDenominator
+++ Author: Manuel Bronstein
+++ Date Created: 2 May 1988
+++ Date Last Updated: 22 Nov 1989
+++ Description: InnerCommonDenominator provides functions to compute
+++ the common denominator of a finite linear aggregate of elements
+++ of the quotient field of an integral domain.
+++ Keywords: gcd, quotient, common, denominator.
+InnerCommonDenominator(R, Q, A, B): Exports == Implementation where
+ R: IntegralDomain
+ Q: QuotientFieldCategory R
+ A: FiniteLinearAggregate R
+ B: FiniteLinearAggregate Q
+
+ Exports ==> with
+ commonDenominator: B -> R
+ ++ commonDenominator([q1,...,qn]) returns a common denominator
+ ++ d for q1,...,qn.
+ clearDenominator : B -> A
+ ++ clearDenominator([q1,...,qn]) returns \spad{[p1,...,pn]} such that
+ ++ \spad{qi = pi/d} where d is a common denominator for the qi's.
+ splitDenominator : B -> Record(num: A, den: R)
+ ++ splitDenominator([q1,...,qn]) returns
+ ++ \spad{[[p1,...,pn], d]} such that
+ ++ \spad{qi = pi/d} and d is a common denominator for the qi's.
+
+ Implementation ==> add
+ import FiniteLinearAggregateFunctions2(Q, B, R, A)
+
+ clearDenominator l ==
+ d := commonDenominator l
+ map(numer(d * #1), l)
+
+ splitDenominator l ==
+ d := commonDenominator l
+ [map(numer(d * #1), l), d]
+
+ if R has GcdDomain then
+ commonDenominator l == reduce(lcm, map(denom, l),1)
+ else
+ commonDenominator l == reduce("*", map(denom, l), 1)
+
+@
+\section{package CDEN CommonDenominator}
+<<package CDEN CommonDenominator>>=
+)abbrev package CDEN CommonDenominator
+--% CommonDenominator
+++ Author: Manuel Bronstein
+++ Date Created: 2 May 1988
+++ Date Last Updated: 22 Nov 1989
+++ Description: CommonDenominator provides functions to compute the
+++ common denominator of a finite linear aggregate of elements of
+++ the quotient field of an integral domain.
+++ Keywords: gcd, quotient, common, denominator.
+CommonDenominator(R, Q, A): Exports == Implementation where
+ R: IntegralDomain
+ Q: QuotientFieldCategory R
+ A: FiniteLinearAggregate Q
+
+ Exports ==> with
+ commonDenominator: A -> R
+ ++ commonDenominator([q1,...,qn]) returns a common denominator
+ ++ d for q1,...,qn.
+ clearDenominator : A -> A
+ ++ clearDenominator([q1,...,qn]) returns \spad{[p1,...,pn]} such that
+ ++ \spad{qi = pi/d} where d is a common denominator for the qi's.
+ splitDenominator : A -> Record(num: A, den: R)
+ ++ splitDenominator([q1,...,qn]) returns
+ ++ \spad{[[p1,...,pn], d]} such that
+ ++ \spad{qi = pi/d} and d is a common denominator for the qi's.
+
+ Implementation ==> add
+ clearDenominator l ==
+ d := commonDenominator l
+ map(numer(d * #1)::Q, l)
+
+ splitDenominator l ==
+ d := commonDenominator l
+ [map(numer(d * #1)::Q, l), d]
+
+ if R has GcdDomain then
+ qlcm: (Q, Q) -> Q
+
+ qlcm(a, b) == lcm(numer a, numer b)::Q
+ commonDenominator l == numer reduce(qlcm, map(denom(#1)::Q, l), 1)
+ else
+ commonDenominator l == numer reduce("*", map(denom(#1)::Q, l), 1)
+
+@
+\section{package UPCDEN UnivariatePolynomialCommonDenominator}
+<<package UPCDEN UnivariatePolynomialCommonDenominator>>=
+)abbrev package UPCDEN UnivariatePolynomialCommonDenominator
+--% UnivariatePolynomialCommonDenominator
+++ Author: Manuel Bronstein
+++ Date Created: 2 May 1988
+++ Date Last Updated: 22 Feb 1990
+++ Description: UnivariatePolynomialCommonDenominator provides
+++ functions to compute the common denominator of the coefficients of
+++ univariate polynomials over the quotient field of a gcd domain.
+++ Keywords: gcd, quotient, common, denominator, polynomial.
+
+UnivariatePolynomialCommonDenominator(R, Q, UP): Exports == Impl where
+ R : IntegralDomain
+ Q : QuotientFieldCategory R
+ UP: UnivariatePolynomialCategory Q
+
+ Exports ==> with
+ commonDenominator: UP -> R
+ ++ commonDenominator(q) returns a common denominator d for
+ ++ the coefficients of q.
+ clearDenominator : UP -> UP
+ ++ clearDenominator(q) returns p such that \spad{q = p/d} where d is
+ ++ a common denominator for the coefficients of q.
+ splitDenominator : UP -> Record(num: UP, den: R)
+ ++ splitDenominator(q) returns \spad{[p, d]} such that \spad{q = p/d} and d
+ ++ is a common denominator for the coefficients of q.
+
+ Impl ==> add
+ import CommonDenominator(R, Q, List Q)
+
+ commonDenominator p == commonDenominator coefficients p
+
+ clearDenominator p ==
+ d := commonDenominator p
+ map(numer(d * #1)::Q, p)
+
+ splitDenominator p ==
+ d := commonDenominator p
+ [map(numer(d * #1)::Q, p), d]
+
+@
+\section{package MCDEN MatrixCommonDenominator}
+<<package MCDEN MatrixCommonDenominator>>=
+)abbrev package MCDEN MatrixCommonDenominator
+--% MatrixCommonDenominator
+++ Author: Manuel Bronstein
+++ Date Created: 2 May 1988
+++ Date Last Updated: 20 Jul 1990
+++ Description: MatrixCommonDenominator provides functions to
+++ compute the common denominator of a matrix of elements of the
+++ quotient field of an integral domain.
+++ Keywords: gcd, quotient, matrix, common, denominator.
+MatrixCommonDenominator(R, Q): Exports == Implementation where
+ R: IntegralDomain
+ Q: QuotientFieldCategory R
+
+ VR ==> Vector R
+ VQ ==> Vector Q
+
+ Exports ==> with
+ commonDenominator: Matrix Q -> R
+ ++ commonDenominator(q) returns a common denominator d for
+ ++ the elements of q.
+ clearDenominator : Matrix Q -> Matrix R
+ ++ clearDenominator(q) returns p such that \spad{q = p/d} where d is
+ ++ a common denominator for the elements of q.
+ splitDenominator : Matrix Q -> Record(num: Matrix R, den: R)
+ ++ splitDenominator(q) returns \spad{[p, d]} such that \spad{q = p/d} and d
+ ++ is a common denominator for the elements of q.
+
+ Implementation ==> add
+ import ListFunctions2(Q, R)
+ import MatrixCategoryFunctions2(Q,VQ,VQ,Matrix Q,R,VR,VR,Matrix R)
+
+ clearDenominator m ==
+ d := commonDenominator m
+ map(numer(d * #1), m)
+
+ splitDenominator m ==
+ d := commonDenominator m
+ [map(numer(d * #1), m), d]
+
+ if R has GcdDomain then
+ commonDenominator m == lcm map(denom, parts m)
+ else
+ commonDenominator m == reduce("*",map(denom, parts m),1)$List(R)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ICDEN InnerCommonDenominator>>
+<<package CDEN CommonDenominator>>
+<<package UPCDEN UnivariatePolynomialCommonDenominator>>
+<<package MCDEN MatrixCommonDenominator>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/clifford.spad.pamphlet b/src/algebra/clifford.spad.pamphlet
new file mode 100644
index 00000000..eeec3b36
--- /dev/null
+++ b/src/algebra/clifford.spad.pamphlet
@@ -0,0 +1,533 @@
+\documentclass{article}
+\usepackage{axiom}
+\usepackage{amssymb}
+\input{diagrams.tex}
+\begin{document}
+\title{\$SPAD/src/algebra clifford.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain QFORM QuadraticForm}
+<<domain QFORM QuadraticForm>>=
+)abbrev domain QFORM QuadraticForm
+++ Author: Stephen M. Watt
+++ Date Created: August 1988
+++ Date Last Updated: May 17, 1991
+++ Basic Operations: quadraticForm, elt
+++ Related Domains: Matrix, SquareMatrix
+++ Also See:
+++ AMS Classifications:
+++ Keywords: quadratic form
+++ Examples:
+++ References:
+++
+++ Description:
+++ This domain provides modest support for quadratic forms.
+QuadraticForm(n, K): T == Impl where
+ n: PositiveInteger
+ K: Field
+ SM ==> SquareMatrix
+ V ==> DirectProduct
+
+ T ==> AbelianGroup with
+ quadraticForm: SM(n, K) -> %
+ ++ quadraticForm(m) creates a quadratic form from a symmetric,
+ ++ square matrix m.
+ matrix: % -> SM(n, K)
+ ++ matrix(qf) creates a square matrix from the quadratic form qf.
+ elt: (%, V(n, K)) -> K
+ ++ elt(qf,v) evaluates the quadratic form qf on the vector v,
+ ++ producing a scalar.
+
+ Impl ==> SM(n,K) add
+ Rep := SM(n,K)
+
+ quadraticForm m ==
+ not symmetric? m =>
+ error "quadraticForm requires a symmetric matrix"
+ m::%
+ matrix q == q pretend SM(n,K)
+ elt(q,v) == dot(v, (matrix q * v))
+
+@
+\section{domain CLIF CliffordAlgebra\cite{7,12}}
+\subsection{Vector (linear) spaces}
+This information is originally from Paul Leopardi's presentation on
+the {\sl Introduction to Clifford Algebras} and is included here as
+an outline with his permission. Further details are based on the book
+by Doran and Lasenby called {\sl Geometric Algebra for Physicists}.
+
+Consider the various kinds of products that can occur between vectors.
+There are scalar and vector products from 3D geometry. There are the
+complex and quaterion products. There is also
+the {\sl outer} or {\sl exterior} product.
+
+Vector addition commutes:
+\[a + b = b + a\]
+Vector addtion is associative:
+\[a + (b + c) = (a + b) + c\]
+The identity vector exists:
+\[a + 0 = a\]
+Every vector has an inverse:
+\[a + (-a) = 0\]
+
+If we consider vectors to be directed line segments, thus establishing
+a geometric meaning for a vector, then each of these properties has a
+geometric meaning.
+
+A multiplication operator exists between scalars and vectors with
+the properties:
+\[\lambda(a + b) = \lambda a + \lambda b\]
+\[(\lambda + \mu)a = \lambda a + \mu a\]
+\[(\lambda\mu)a = \lambda(\mu a)\]
+\[{\rm If\ }1\lambda = \lambda{\rm\ for\ all\ scalars\ }\lambda
+{\rm\ then\ }1a=a{\rm\ for\ all\ vectors\ }a\]
+
+These properties completely define a vector (linear) space. The
+$+$ operation for scalar arithmetic is not the same as the $+$
+operation for vectors.
+
+{\bf Definition: Isomorphic} The vector space $A$ is isomorphic to
+the vector space $B$ if their exists a one-to-one correspondence
+between their elements which preserves sums and there is a one-to-one
+correspondence between the scalars which preserves sums and products.
+
+{\bf Definition: Subspace} Vector space $B$ is a subspace of vector
+space $A$ if all of the elements of $B$ are contained in $A$ and
+they share the same scalars.
+
+{\bf Definition: Linear Combination} Given vectors $a_1,\ldots,a_n$
+the vector $b$ is a linear combination of the vectors if we can find
+scalars $\lambda_i$ such that
+\[b = \lambda_1 a_1+\ldots+\lambda_n a_n = \sum_{k=1}^n \lambda_i a_i\]
+
+{\bf Definition: Linearly Independent} If there exists scalars $\lambda_i$
+such that
+\[\lambda_1 a_1 + \ldots + \lambda_n a_n = 0\]
+and at least one of the $\lambda_i$ is not zero
+then the vectors $a_1,\ldots,a_n$ are linearly dependent. If no such
+scalars exist then the vectors are linearly independent.
+
+{\bf Definition: Span} If every vector can be written as a linear
+combination of a fixed set of vectors $a_1,\ldots,a_n$ then this set
+of vectors is said to span the vector space.
+
+{\bf Definition: Basis} If a set of vectors $a_1,\ldots,a_n$ is linearly
+independent and spans a vector space $A$ then the vectors form a basis
+for $A$.
+
+{\bf Definition: Dimension} The dimension of a vector space is the
+number of basis elements, which is unique since all bases of a
+vector space have the same number of elements.
+\subsection{Quadratic Forms\cite{1}}
+For vector space $\mathbb{V}$ over field $\mathbb{F}$, characteristic
+$\ne 2$:
+\begin{list}{}
+\item Map $f:\mathbb{V} \rightarrow \mathbb{F}$, with
+$$f(\lambda x)=\lambda^2f(x),\forall \lambda \in \mathbb{F}, x \in \mathbb{V}$$
+\item $f(x) = b(x,x)$, where
+$$b:\mathbb{V}{\rm\ x\ }\mathbb{V} \rightarrow \mathbb{F}{\rm\ ,given\ by\ }$$
+$$b(x,y):=\frac{1}{2}(f(x+y)-f(x)=f(y))$$
+is a symmetric bilinear form
+\end{list}
+\subsection{Quadratic spaces, Clifford Maps\cite{1,2}}
+\begin{list}{}
+\item A quadratic space is the pair($\mathbb{V}$,$f$), where $f$ is a
+quadratic form on $\mathbb{V}$
+\item A Clifford map is a vector space homomorphism
+$$\rho : \mathbb{V} \rightarrow \mathbb{A}$$
+where $\mathbb{A}$ is an associated algebra, and
+$$(\rho v)^2 = f(v),{\rm\ \ \ } \forall v \in \mathbb{V}$$
+\end{list}
+\subsection{Universal Clifford algebras\cite{1}}
+\begin{list}{}
+\item The {\sl universal Clifford algebra} $Cl(f)$ for the quadratic space
+$(\mathbb{V},f)$ is the algebra generated by the image of the Clifford
+map $\phi_f$ such that $Cl(f)$ is the universal initial object such
+that $\forall$ suitable algebra $\mathbb{A}$ with Clifford map
+$\phi_{\mathbb{A}} \exists$ a homomorphism
+$$P_\mathbb{A}:Cl(f) \rightarrow \mathbb{A}$$
+$$\rho_\mathbb{A} = P_\mathbb{A}\circ\rho_f$$
+\end{list}
+\subsection{Real Clifford algebras $\mathbb{R}_{p,q}$\cite{2}}
+\begin{list}{}
+\item The real quadratic space $\mathbb{R}^{p,q}$ is $\mathbb{R}^{p+q}$ with
+$$\phi(x):=-\sum_{k:=-q}^{-1}{x_k^2}+\sum_{k=1}^p{x_k^2}$$
+\item For each $p,q \in \mathbb{N}$, the real universal Clifford algebra
+for $\mathbb{R}^{p,q}$ is called $\mathbb{R}_{p,q}$
+\item $\mathbb{R}_{p,q}$ is isomorphic to some matrix algebra over one of:
+$\mathbb{R}$,$\mathbb{R}\oplus\mathbb{R}$,$\mathbb{C}$,
+$\mathbb{H}$,$\mathbb{H}\oplus\mathbb{H}$
+\item For example, $\mathbb{R}_{1,1} \cong \mathbb{R}(2)$
+\end{list}
+\subsection{Notation for integer sets}
+\begin{list}{}
+\item For $S \subseteq \mathbb{Z}$, define
+$$\sum_{k \in S}{f_k}:=\sum_{k={\rm min\ }S, k \in S}^{{\rm max\ } S}{f_k}$$
+$$\prod_{k \in S}{f_k}:=\prod_{k={\rm min\ }S, k \in S}^{{\rm max\ } S}{f_k}$$
+$$\mathbb{P}(S):={\rm\ the\ }\ power\ set\ {\rm\ of\ }S$$
+\item For $m \le n \in \mathbb{Z}$, define
+$$\zeta(m,n):=\{m,m+1,\ldots,n-1,n\}\backslash\{0\}$$
+\end{list}
+\subsection{Frames for Clifford algebras\cite{9,10,11}}
+\begin{list}{}
+\item A {\sl frame} is an ordered basis $(\gamma_{-q},\ldots,\gamma_p)$
+for $\mathbb{R}^{p,q}$ which puts a quadratic form into the canonical
+form $\phi$
+\item For $p,q \in \mathbb{N}$, embed the frame for $\mathbb{R}^{p,q}$
+into $\mathbb{R}_{p,q}$ via the maps
+$$\gamma:\zeta(-q,p) \rightarrow \mathbb{R}^{p,q}$$
+$$\rho:\mathbb{R}^{p,q} \rightarrow \mathbb{R}_{p,q}$$
+$$(\rho\gamma k)^2 = \phi\gamma k = {\rm\ sgn\ }k$$
+\end{list}
+\subsection{Real frame groups\cite{5,6}}
+\begin{list}{}
+\item For $p,q \in \mathbb{N}$, define the real {\sl frame group} $\mathbb{G}_{p,q}$
+via the map
+$$g:\zeta(-q,p) \rightarrow \mathbb{G}_{p,q}$$
+with generators and relations
+$$\langle \mu,g_k | \mu g_k = g_k \mu,{\rm\ \ \ }\mu^2 = 1,$$
+$$(g_k)^2 =
+\left\{
+\begin{array}{lcc}
+\mu,&{\rm\ \ }&{\rm\ if\ }k < 0\\
+1&{\rm\ \ }&{\rm\ if\ }k > 0
+\end{array}
+\right.$$
+$$g_kg_m = \mu g_mg_k{\rm\ \ \ }\forall k \ne m\rangle$$
+\end{list}
+\subsection{Canonical products\cite{1,3,4}}
+\begin{list}{}
+\item The real frame group $\mathbb{G}_{p,q}$ has order $2^{p+q+1}$
+\item Each member $w$ can be expressed as the canonically ordered product
+$$w=\mu^a\prod_{k \in T}{g_k}$$
+$$\ =\mu^a\prod_{k=-q,k\ne0}^p{g_k^{b_k}}$$
+where $T \subseteq \zeta(-q,p),a,b_k \in \{0,1\}$
+\end{list}
+\subsection{Clifford algebra of frame group\cite{1,4,5,6}}
+\begin{list}{}
+\item For $p,q \in \mathbb{N}$ embed $\mathbb{G}_{p,q}$ into
+$\mathbb{R}_{p,q}$ via the map
+$$\alpha \mathbb{G}_{p,q} \rightarrow \mathbb{R}_{p,q}$$
+$$\alpha 1 := 1,{\rm\ \ \ \ \ } \alpha\mu := -1$$
+$$\alpha g_k := \rho\gamma_k, {\rm \ \ \ \ \ }
+\alpha(gh) := (\alpha g)(\alpha h)$$
+\item Define {\sl basis elements} via the map
+$$e:\mathbb{P}\zeta(-q,p) \rightarrow \mathbb{R}_{p,q},
+{\rm \ \ \ \ \ }e_T := \alpha \prod_{k \in T}{g_k}$$
+\item Each $a \in \mathbb{R}_{p,q}$ can be expressed as
+$$a = \sum_{T \subseteq \zeta(-q,p)}{a_T e_T}$$
+\end{list}
+\subsection{Neutral matrix representations\cite{1,2,8}}
+The {\sl representation map} $P_m$ and {\sl representation matrix} $R_m$
+make the following diagram commute:
+\begin{diagram}
+\mathbb{R}_{m,m} & \rTo^{coord} & \mathbb{R}^{4^m}\\
+\dTo^{P_m} & & \dTo_{R_m}\\
+\mathbb{R}(2^m) & \rTo_{reshape} & \mathbb{R}^{4^m}\\
+\end{diagram}
+<<domain CLIF CliffordAlgebra>>=
+)abbrev domain CLIF CliffordAlgebra
+++ Author: Stephen M. Watt
+++ Date Created: August 1988
+++ Date Last Updated: May 17, 1991
+++ Basic Operations: wholeRadix, fractRadix, wholeRagits, fractRagits
+++ Related Domains: QuadraticForm, Quaternion, Complex
+++ Also See:
+++ AMS Classifications:
+++ Keywords: clifford algebra, grassman algebra, spin algebra
+++ Examples:
+++ References:
+++
+++ Description:
+++ CliffordAlgebra(n, K, Q) defines a vector space of dimension \spad{2**n}
+++ over K, given a quadratic form Q on \spad{K**n}.
+++
+++ If \spad{e[i]}, \spad{1<=i<=n} is a basis for \spad{K**n} then
+++ 1, \spad{e[i]} (\spad{1<=i<=n}), \spad{e[i1]*e[i2]}
+++ (\spad{1<=i1<i2<=n}),...,\spad{e[1]*e[2]*..*e[n]}
+++ is a basis for the Clifford Algebra.
+++
+++ The algebra is defined by the relations
+++ \spad{e[i]*e[j] = -e[j]*e[i]} (\spad{i \~~= j}),
+++ \spad{e[i]*e[i] = Q(e[i])}
+++
+++ Examples of Clifford Algebras are: gaussians, quaternions, exterior
+++ algebras and spin algebras.
+
+CliffordAlgebra(n, K, Q): T == Impl where
+ n: PositiveInteger
+ K: Field
+ Q: QuadraticForm(n, K)
+
+ PI ==> PositiveInteger
+ NNI==> NonNegativeInteger
+
+ T ==> Join(Ring, Algebra(K), VectorSpace(K)) with
+ e: PI -> %
+ ++ e(n) produces the appropriate unit element.
+ monomial: (K, List PI) -> %
+ ++ monomial(c,[i1,i2,...,iN]) produces the value given by
+ ++ \spad{c*e(i1)*e(i2)*...*e(iN)}.
+ coefficient: (%, List PI) -> K
+ ++ coefficient(x,[i1,i2,...,iN]) extracts the coefficient of
+ ++ \spad{e(i1)*e(i2)*...*e(iN)} in x.
+ recip: % -> Union(%, "failed")
+ ++ recip(x) computes the multiplicative inverse of x or "failed"
+ ++ if x is not invertible.
+
+ Impl ==> add
+ Qeelist := [Q unitVector(i::PositiveInteger) for i in 1..n]
+ dim := 2**n
+
+ Rep := PrimitiveArray K
+
+ New ==> new(dim, 0$K)$Rep
+
+ x, y, z: %
+ c: K
+ m: Integer
+
+ characteristic() == characteristic()$K
+ dimension() == dim::CardinalNumber
+
+ x = y ==
+ for i in 0..dim-1 repeat
+ if x.i ^= y.i then return false
+ true
+
+ x + y == (z := New; for i in 0..dim-1 repeat z.i := x.i + y.i; z)
+ x - y == (z := New; for i in 0..dim-1 repeat z.i := x.i - y.i; z)
+ - x == (z := New; for i in 0..dim-1 repeat z.i := - x.i; z)
+ m * x == (z := New; for i in 0..dim-1 repeat z.i := m*x.i; z)
+ c * x == (z := New; for i in 0..dim-1 repeat z.i := c*x.i; z)
+
+ 0 == New
+ 1 == (z := New; z.0 := 1; z)
+ coerce(m): % == (z := New; z.0 := m::K; z)
+ coerce(c): % == (z := New; z.0 := c; z)
+
+ e b ==
+ b::NNI > n => error "No such basis element"
+ iz := 2**((b-1)::NNI)
+ z := New; z.iz := 1; z
+
+ -- The ei*ej products could instead be precomputed in
+ -- a (2**n)**2 multiplication table.
+ addMonomProd(c1: K, b1: NNI, c2: K, b2: NNI, z: %): % ==
+ c := c1 * c2
+ bz := b2
+ for i in 0..n-1 | bit?(b1,i) repeat
+ -- Apply rule ei*ej = -ej*ei for i^=j
+ k := 0
+ for j in i+1..n-1 | bit?(b1, j) repeat k := k+1
+ for j in 0..i-1 | bit?(bz, j) repeat k := k+1
+ if odd? k then c := -c
+ -- Apply rule ei**2 = Q(ei)
+ if bit?(bz,i) then
+ c := c * Qeelist.(i+1)
+ bz:= (bz - 2**i)::NNI
+ else
+ bz:= bz + 2**i
+ z.bz := z.bz + c
+ z
+
+ x * y ==
+ z := New
+ for ix in 0..dim-1 repeat
+ if x.ix ^= 0 then for iy in 0..dim-1 repeat
+ if y.iy ^= 0 then addMonomProd(x.ix,ix,y.iy,iy,z)
+ z
+
+ canonMonom(c: K, lb: List PI): Record(coef: K, basel: NNI) ==
+ -- 0. Check input
+ for b in lb repeat b > n => error "No such basis element"
+
+ -- 1. Apply identity ei*ej = -ej*ei, i^=j.
+ -- The Rep assumes n is small so bubble sort is ok.
+ -- Using bubble sort keeps the exchange info obvious.
+ wasordered := false
+ exchanges := 0
+ while not wasordered repeat
+ wasordered := true
+ for i in 1..#lb-1 repeat
+ if lb.i > lb.(i+1) then
+ t := lb.i; lb.i := lb.(i+1); lb.(i+1) := t
+ exchanges := exchanges + 1
+ wasordered := false
+ if odd? exchanges then c := -c
+
+ -- 2. Prepare the basis element
+ -- Apply identity ei*ei = Q(ei).
+ bz := 0
+ for b in lb repeat
+ bn := (b-1)::NNI
+ if bit?(bz, bn) then
+ c := c * Qeelist bn
+ bz:= ( bz - 2**bn )::NNI
+ else
+ bz:= bz + 2**bn
+ [c, bz::NNI]
+
+ monomial(c, lb) ==
+ r := canonMonom(c, lb)
+ z := New
+ z r.basel := r.coef
+ z
+ coefficient(z, lb) ==
+ r := canonMonom(1, lb)
+ r.coef = 0 => error "Cannot take coef of 0"
+ z r.basel/r.coef
+
+ Ex ==> OutputForm
+
+ coerceMonom(c: K, b: NNI): Ex ==
+ b = 0 => c::Ex
+ ml := [sub("e"::Ex, i::Ex) for i in 1..n | bit?(b,i-1)]
+ be := reduce("*", ml)
+ c = 1 => be
+ c::Ex * be
+ coerce(x): Ex ==
+ tl := [coerceMonom(x.i,i) for i in 0..dim-1 | x.i^=0]
+ null tl => "0"::Ex
+ reduce("+", tl)
+
+
+ localPowerSets(j:NNI): List(List(PI)) ==
+ l: List List PI := list []
+ j = 0 => l
+ Sm := localPowerSets((j-1)::NNI)
+ Sn: List List PI := []
+ for x in Sm repeat Sn := cons(cons(j pretend PI, x),Sn)
+ append(Sn, Sm)
+
+ powerSets(j:NNI):List List PI == map(reverse, localPowerSets j)
+
+ Pn:List List PI := powerSets(n)
+
+ recip(x: %): Union(%, "failed") ==
+ one:% := 1
+ -- tmp:c := x*yC - 1$C
+ rhsEqs : List K := []
+ lhsEqs: List List K := []
+ lhsEqi: List K
+ for pi in Pn repeat
+ rhsEqs := cons(coefficient(one, pi), rhsEqs)
+
+ lhsEqi := []
+ for pj in Pn repeat
+ lhsEqi := cons(coefficient(x*monomial(1,pj),pi),lhsEqi)
+ lhsEqs := cons(reverse(lhsEqi),lhsEqs)
+ ans := particularSolution(matrix(lhsEqs),
+ vector(rhsEqs))$LinearSystemMatrixPackage(K, Vector K, Vector K, Matrix K)
+ ans case "failed" => "failed"
+ ansP := parts(ans)
+ ansC:% := 0
+ for pj in Pn repeat
+ cj:= first ansP
+ ansP := rest ansP
+ ansC := ansC + cj*monomial(1,pj)
+ ansC
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain QFORM QuadraticForm>>
+<<domain CLIF CliffordAlgebra>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} Lounesto, P.
+"Clifford algebras and spinors",
+2nd edition, Cambridge University Press (2001)
+\bibitem{2} Porteous, I.,
+"Clifford algebras and the classical groups",
+Cambridge University Press (1995)
+Van Nostrand Reinhold, (1969)
+\bibitem{3} Bergdolt, G.
+"Orthonormal basis sets in Clifford algebras",
+in \cite{16} (1996)
+\bibitem{4} Dorst, Leo,
+"Honing geometric algebra for its use in the computer sciences",
+pp127-152 from \cite{15} (2001)
+\bibitem{5} Braden, H.W.,
+"N-dimensional spinors: Their properties in terms of finite groups",
+American Institute of Physics,
+J. Math. Phys. 26(4), April 1985
+\bibitem{6} Lam, T.Y. and Smith, Tara L.,
+"On the Clifford-Littlewood-Eckmann groups: a new look at periodicity mod 8",
+Rocky Mountains Journal of Mathematics, vol 19, no. 3, (Summer 1989)
+\bibitem{7} Leopardi, Paul "Quick Introduction to Clifford Algebras"\\
+{\bf http://web.maths.unsw.edu.au/~leopardi/clifford-2003-06-05.pdf}
+\bibitem{8} Cartan, Elie and Study, Eduard
+"Nombres Complexes",
+Encyclopaedia Sciences Math\'ematique, \'edition fran\c caise, 15, (1908),
+d'apr\`es l'article allemand de Eduard Study, pp329-468. Reproduced as
+pp107-246 of \cite{17}
+\bibitem{9} Hestenes, David and Sobczyck, Garret
+"Clifford algebra to geometric calculus: a unified language for
+mathematics and physics", D. Reidel, (1984)
+\bibitem{10} Wene, G.P.,
+"The Idempotent structure of an infinite dimensional Clifford algebra",
+pp161-164 of \cite{13} (1995)
+\bibitem{11} Ashdown, M.
+"GA Package for Maple V",\\
+http://www.mrao.cam.ac.uk/~clifford/software/GA/GAhelp5.html
+\bibitem{12} Doran, Chris and Lasenby, Anthony,
+"Geometric Algebra for Physicists"
+Cambridge University Press (2003) ISBN 0-521-48022-1
+\bibitem{13} Micali, A., Boudet, R., Helmstetter, J. (eds),
+"Clifford algebras and their applications in mathematical physics:
+proceedings of second workshop held at Montpellier, France, 1989",
+Kluwer Academic Publishers (1992)
+\bibitem{14} Porteous, I.,
+"Topological geometry"
+Van Nostrand Reinhold, (1969)
+\bibitem{15} Sommer, G. (editor),
+"Geometric Computing with Clifford Algebras",
+Springer, (2001)
+\bibitem{16} Ablamowicz, R., Lounesto, P., Parra, J.M. (eds)
+"Clifford algebras with numeric and symbolic computations",
+Birkh\"auser (1996)
+\bibitem{17} Cartan, Elie and Montel, P. (eds),
+"\OE uvres Compl\`etes" Gauthier-Villars, (1953)
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/clip.spad.pamphlet b/src/algebra/clip.spad.pamphlet
new file mode 100644
index 00000000..04f9f42a
--- /dev/null
+++ b/src/algebra/clip.spad.pamphlet
@@ -0,0 +1,341 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra clip.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package CLIP TwoDimensionalPlotClipping}
+<<package CLIP TwoDimensionalPlotClipping>>=
+)abbrev package CLIP TwoDimensionalPlotClipping
+++ Automatic clipping for 2-dimensional plots
+++ Author: Clifton J. Williamson
+++ Date Created: 22 December 1989
+++ Date Last Updated: 10 July 1990
+++ Keywords: plot, singularity
+++ Examples:
+++ References:
+
+TwoDimensionalPlotClipping(): Exports == Implementation where
+ ++ The purpose of this package is to provide reasonable plots of
+ ++ functions with singularities.
+ B ==> Boolean
+ L ==> List
+ SEG ==> Segment
+ RN ==> Fraction Integer
+ SF ==> DoubleFloat
+ Pt ==> Point DoubleFloat
+ PLOT ==> Plot
+ CLIPPED ==> Record(brans: L L Pt,xValues: SEG SF,yValues: SEG SF)
+
+ Exports ==> with
+ clip: PLOT -> CLIPPED
+ ++ clip(p) performs two-dimensional clipping on a plot, p, from
+ ++ the domain \spadtype{Plot} for the graph of one variable,
+ ++ \spad{y = f(x)}; the default parameters \spad{1/4} for the fraction
+ ++ and \spad{5/1} for the scale are used in the \spadfun{clip} function.
+ clip: (PLOT,RN,RN) -> CLIPPED
+ ++ clip(p,frac,sc) performs two-dimensional clipping on a plot, p,
+ ++ from the domain \spadtype{Plot} for the graph of one variable
+ ++ \spad{y = f(x)}; the fraction parameter is specified by \spad{frac}
+ ++ and the scale parameter is specified by \spad{sc} for use in the
+ ++ \spadfun{clip} function.
+ clipParametric: PLOT -> CLIPPED
+ ++ clipParametric(p) performs two-dimensional clipping on a plot,
+ ++ p, from the domain \spadtype{Plot} for the parametric curve
+ ++ \spad{x = f(t)}, \spad{y = g(t)}; the default parameters \spad{1/2}
+ ++ for the fraction and \spad{5/1} for the scale are used in the
+ ++ \fakeAxiomFun{iClipParametric} subroutine, which is called by this
+ ++ function.
+ clipParametric: (PLOT,RN,RN) -> CLIPPED
+ ++ clipParametric(p,frac,sc) performs two-dimensional clipping on a
+ ++ plot, p, from the domain \spadtype{Plot} for the parametric curve
+ ++ \spad{x = f(t)}, \spad{y = g(t)}; the fraction parameter is
+ ++ specified by \spad{frac} and the scale parameter is specified
+ ++ by \spad{sc} for use in the \fakeAxiomFun{iClipParametric} subroutine,
+ ++ which is called by this function.
+ clipWithRanges: (L L Pt,SF,SF,SF,SF) -> CLIPPED
+ ++ clipWithRanges(pointLists,xMin,xMax,yMin,yMax) performs clipping
+ ++ on a list of lists of points, \spad{pointLists}. Clipping is
+ ++ done within the specified ranges of \spad{xMin}, \spad{xMax} and
+ ++ \spad{yMin}, \spad{yMax}. This function is used internally by
+ ++ the \fakeAxiomFun{iClipParametric} subroutine in this package.
+ clip: L Pt -> CLIPPED
+ ++ clip(l) performs two-dimensional clipping on a curve l, which is
+ ++ a list of points; the default parameters \spad{1/2} for the
+ ++ fraction and \spad{5/1} for the scale are used in the
+ ++ \fakeAxiomFun{iClipParametric} subroutine, which is called by this
+ ++ function.
+ clip: L L Pt -> CLIPPED
+ ++ clip(ll) performs two-dimensional clipping on a list of lists
+ ++ of points, \spad{ll}; the default parameters \spad{1/2} for
+ ++ the fraction and \spad{5/1} for the scale are used in the
+ ++ \fakeAxiomFun{iClipParametric} subroutine, which is called by this
+ ++ function.
+
+ Implementation ==> add
+ import PointPackage(DoubleFloat)
+ import ListFunctions2(Point DoubleFloat,DoubleFloat)
+
+ point:(SF,SF) -> Pt
+ intersectWithHorizLine:(SF,SF,SF,SF,SF) -> Pt
+ intersectWithVertLine:(SF,SF,SF,SF,SF) -> Pt
+ intersectWithBdry:(SF,SF,SF,SF,Pt,Pt) -> Pt
+ discardAndSplit: (L Pt,Pt -> B,SF,SF,SF,SF) -> L L Pt
+ norm: Pt -> SF
+ iClipParametric: (L L Pt,RN,RN) -> CLIPPED
+ findPt: L L Pt -> Union(Pt,"failed")
+ Fnan?: SF ->Boolean
+ Pnan?:Pt ->Boolean
+
+ Fnan? x == x~=x
+ Pnan? p == any?(Fnan?,p)
+
+ iClipParametric(pointLists,fraction,scale) ==
+ -- error checks and special cases
+ (fraction < 0) or (fraction > 1) =>
+ error "clipDraw: fraction should be between 0 and 1"
+ empty? pointLists => [nil(),segment(0,0),segment(0,0)]
+ -- put all points together , sort them according to norm
+ sortedList := sort(norm(#1) < norm(#2),select(not Pnan? #1,concat pointLists))
+ empty? sortedList => [nil(),segment(0,0),segment(0,0)]
+ n := # sortedList
+ num := numer fraction
+ den := denom fraction
+ clipNum := (n * num) quo den
+ lastN := n - 1 - clipNum
+ firstPt := first sortedList
+ xMin : SF := xCoord firstPt
+ xMax : SF := xCoord firstPt
+ yMin : SF := yCoord firstPt
+ yMax : SF := yCoord firstPt
+ -- calculate min/max for the first (1-fraction)*N points
+ -- this contracts the range
+ -- this unnecessarily clips monotonic functions (step-function, x^(high power),etc.)
+ for k in 0..lastN for pt in rest sortedList repeat
+ xMin := min(xMin,xCoord pt)
+ xMax := max(xMax,xCoord pt)
+ yMin := min(yMin,yCoord pt)
+ yMax := max(yMax,yCoord pt)
+ xDiff := xMax - xMin; yDiff := yMax - yMin
+ xDiff = 0 =>
+ yDiff = 0 =>
+ [pointLists,segment(xMin-1,xMax+1),segment(yMin-1,yMax+1)]
+ [pointLists,segment(xMin-1,xMax+1),segment(yMin,yMax)]
+ yDiff = 0 =>
+ [pointLists,segment(xMin,xMax),segment(yMin-1,yMax+1)]
+ numm := numer scale; denn := denom scale
+ -- now expand the range by scale
+ xMin := xMin - (numm :: SF) * xDiff / (denn :: SF)
+ xMax := xMax + (numm :: SF) * xDiff / (denn :: SF)
+ yMin := yMin - (numm :: SF) * yDiff / (denn :: SF)
+ yMax := yMax + (numm :: SF) * yDiff / (denn :: SF)
+ -- clip with the calculated range
+ newclip:=clipWithRanges(pointLists,xMin,xMax,yMin,yMax)
+ -- if we split the lists use the new clip
+ # (newclip.brans) > # pointLists => newclip
+ -- calculate extents
+ xs :L SF:= map (xCoord,sortedList)
+ ys :L SF:= map (yCoord,sortedList)
+ xMin :SF :=reduce (min,xs)
+ yMin :SF :=reduce (min,ys)
+ xMax :SF :=reduce (max,xs)
+ yMax :SF :=reduce (max,ys)
+ xseg:SEG SF :=xMin..xMax
+ yseg:SEG SF :=yMin..yMax
+ -- return original
+ [pointLists,xseg,yseg]@CLIPPED
+
+
+
+
+ point(xx,yy) == point(l : L SF := [xx,yy])
+
+ intersectWithHorizLine(x1,y1,x2,y2,yy) ==
+ x1 = x2 => point(x1,yy)
+ point(x1 + (x2 - x1)*(yy - y1)/(y2 - y1),yy)
+
+ intersectWithVertLine(x1,y1,x2,y2,xx) ==
+ y1 = y2 => point(xx,y1)
+ point(xx,y1 + (y2 - y1)*(xx - x1)/(x2 - x1))
+
+ intersectWithBdry(xMin,xMax,yMin,yMax,pt1,pt2) ==
+ -- pt1 is in rectangle, pt2 is not
+ x1 := xCoord pt1; y1 := yCoord pt1
+ x2 := xCoord pt2; y2 := yCoord pt2
+ if y2 > yMax then
+ pt2 := intersectWithHorizLine(x1,y1,x2,y2,yMax)
+ x2 := xCoord pt2; y2 := yCoord pt2
+ if y2 < yMin then
+ pt2 := intersectWithHorizLine(x1,y1,x2,y2,yMin)
+ x2 := xCoord pt2; y2 := yCoord pt2
+ if x2 > xMax then
+ pt2 := intersectWithVertLine(x1,y1,x2,y2,xMax)
+ x2 := xCoord pt2; y2 := yCoord pt2
+ if x2 < xMin then
+ pt2 := intersectWithVertLine(x1,y1,x2,y2,xMin)
+ pt2
+
+ discardAndSplit(pointList,pred,xMin,xMax,yMin,yMax) ==
+ ans : L L Pt := nil()
+ list : L Pt := nil()
+ lastPt? : B := false
+ lastPt : Pt := point(0,0)
+ while not empty? pointList repeat
+ pt := first pointList
+ pointList := rest pointList
+ pred(pt) =>
+ if (empty? list) and lastPt? then
+ bdryPt := intersectWithBdry(xMin,xMax,yMin,yMax,pt,lastPt)
+ -- print bracket [ coerce bdryPt ,coerce pt ]
+ --list := cons(bdryPt,list)
+ list := cons(pt,list)
+ if not empty? list then
+ bdryPt := intersectWithBdry(xMin,xMax,yMin,yMax,first list,pt)
+ -- print bracket [ coerce bdryPt,coerce first list]
+ --list := cons(bdryPt,list)
+ ans := cons( list,ans)
+ lastPt := pt
+ lastPt? := true
+ list := nil()
+ empty? list => ans
+ reverse_! cons(reverse_! list,ans)
+
+ clip(plot,fraction,scale) ==
+-- sayBrightly([" clip: "::OutputForm]$List(OutputForm))$Lisp
+ (fraction < 0) or (fraction > 1/2) =>
+ error "clipDraw: fraction should be between 0 and 1/2"
+ xVals := xRange plot
+ empty?(pointLists := listBranches plot) =>
+ [nil(),xVals,segment(0,0)]
+ more?(pointLists := listBranches plot,1) =>
+ error "clipDraw: plot has more than one branch"
+ empty?(pointList := first pointLists) =>
+ [nil(),xVals,segment(0,0)]
+ sortedList := sort(yCoord(#1) < yCoord(#2),pointList)
+ n := # sortedList; num := numer fraction; den := denom fraction
+ clipNum := (n * num) quo den
+ -- throw out points with large and small y-coordinates
+ yMin := yCoord(sortedList.clipNum)
+ yMax := yCoord(sortedList.(n - 1 - clipNum))
+ if Fnan? yMin then yMin : SF := 0
+ if Fnan? yMax then yMax : SF := 0
+ (yDiff := yMax - yMin) = 0 =>
+ [pointLists,xRange plot,segment(yMin - 1,yMax + 1)]
+ numm := numer scale; denn := denom scale
+ xMin := lo xVals; xMax := hi xVals
+ yMin := yMin - (numm :: SF) * yDiff / (denn :: SF)
+ yMax := yMax + (numm :: SF) * yDiff / (denn :: SF)
+ lists := discardAndSplit(pointList,_
+ (yCoord(#1) < yMax) and (yCoord(#1) > yMin),xMin,xMax,yMin,yMax)
+ yMin := yCoord(sortedList.clipNum)
+ yMax := yCoord(sortedList.(n - 1 - clipNum))
+ if Fnan? yMin then yMin : SF := 0
+ if Fnan? yMax then yMax : SF := 0
+ for list in lists repeat
+ for pt in list repeat
+ if not Fnan?(yCoord pt) then
+ yMin := min(yMin,yCoord pt)
+ yMax := max(yMax,yCoord pt)
+ [lists,xVals,segment(yMin,yMax)]
+
+ clip(plot:PLOT) == clip(plot,1/4,5/1)
+
+ norm(pt) ==
+ x := xCoord(pt); y := yCoord(pt)
+ if Fnan? x then
+ if Fnan? y then
+ r:SF := 0
+ else
+ r:SF := y**2
+ else
+ if Fnan? y then
+ r:SF := x**2
+ else
+ r:SF := x**2 + y**2
+ r
+
+ findPt lists ==
+ for list in lists repeat
+ not empty? list =>
+ for p in list repeat
+ not Pnan? p => return p
+ "failed"
+
+ clipWithRanges(pointLists,xMin,xMax,yMin,yMax) ==
+ lists : L L Pt := nil()
+ for pointList in pointLists repeat
+ lists := concat(lists,discardAndSplit(pointList,_
+ (xCoord(#1) <= xMax) and (xCoord(#1) >= xMin) and _
+ (yCoord(#1) <= yMax) and (yCoord(#1) >= yMin), _
+ xMin,xMax,yMin,yMax))
+ (pt := findPt lists) case "failed" =>
+ [nil(),segment(0,0),segment(0,0)]
+ firstPt := pt :: Pt
+ xMin : SF := xCoord firstPt; xMax : SF := xCoord firstPt
+ yMin : SF := yCoord firstPt; yMax : SF := yCoord firstPt
+ for list in lists repeat
+ for pt in list repeat
+ if not Pnan? pt then
+ xMin := min(xMin,xCoord pt)
+ xMax := max(xMax,xCoord pt)
+ yMin := min(yMin,yCoord pt)
+ yMax := max(yMax,yCoord pt)
+ [lists,segment(xMin,xMax),segment(yMin,yMax)]
+
+ clipParametric(plot,fraction,scale) ==
+ iClipParametric(listBranches plot,fraction,scale)
+
+ clipParametric plot == clipParametric(plot,1/2,5/1)
+
+ clip(l: L Pt) == iClipParametric(list l,1/2,5/1)
+ clip(l: L L Pt) == iClipParametric(l,1/2,5/1)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package CLIP TwoDimensionalPlotClipping>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/cmplxrt.spad.pamphlet b/src/algebra/cmplxrt.spad.pamphlet
new file mode 100644
index 00000000..5cd1072e
--- /dev/null
+++ b/src/algebra/cmplxrt.spad.pamphlet
@@ -0,0 +1,117 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra cmplxrt.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package CMPLXRT ComplexRootPackage}
+<<package CMPLXRT ComplexRootPackage>>=
+)abbrev package CMPLXRT ComplexRootPackage
+++ Author: P. Gianni
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Complex, Float, Fraction, UnivariatePolynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides functions complexZeros
+++ for finding the complex zeros
+++ of univariate polynomials with complex rational number coefficients.
+++ The results are to any user specified precision and are returned
+++ as either complex rational number or complex floating point numbers
+++ depending on the type of the second argument which specifies the
+++ precision.
+
+-- Packages for the computation of complex roots of
+-- univariate polynomials with rational or gaussian coefficients.
+
+-- Simplified version, the old original based on Gebauer's solver is
+-- in ocmplxrt spad
+RN ==> Fraction Integer
+I ==> Integer
+NF ==> Float
+
+ComplexRootPackage(UP,Par) : T == C where
+ UP : UnivariatePolynomialCategory Complex Integer
+ Par : Join(Field, OrderedRing) -- will be Float or RN
+ CP ==> Complex Par
+ PCI ==> Polynomial Complex Integer
+
+ T == with
+ complexZeros:(UP,Par) -> List CP
+ ++ complexZeros(poly, eps) finds the complex zeros of the
+ ++ univariate polynomial poly to precision eps with
+ ++ solutions returned as complex floats or rationals
+ ++ depending on the type of eps.
+
+ C == add
+ complexZeros(p:UP,eps:Par):List CP ==
+ x1:Symbol():=new()
+ x2:Symbol():=new()
+ vv:Symbol():=new()
+ lpf:=factors factor(p)$ComplexFactorization(I,UP)
+ ris:List CP:=empty()
+ for pf in lpf repeat
+ pp:=pf.factor pretend SparseUnivariatePolynomial Complex Integer
+ q:PCI :=multivariate(pp,vv)
+ q:=eval(q,vv,x1::PCI+complex(0,1)*(x2::PCI))
+ p1:=map(real,q)$PolynomialFunctions2(Complex I,I)
+ p2:=map(imag,q)$PolynomialFunctions2(Complex I,I)
+ lz:=innerSolve([p1,p2],[],[x1,x2],
+ eps)$InnerNumericFloatSolvePackage(I,Par,Par)
+ ris:=append([complex(first z,second z) for z in lz],ris)
+ ris
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package CMPLXRT ComplexRootPackage>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/coerce.spad.pamphlet b/src/algebra/coerce.spad.pamphlet
new file mode 100644
index 00000000..3ad352b6
--- /dev/null
+++ b/src/algebra/coerce.spad.pamphlet
@@ -0,0 +1,125 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra coerce.spad}
+\author{Richard Jenks, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category TYPE Type}
+<<category TYPE Type>>=
+)abbrev category TYPE Type
+++ The new fundamental Type (keeping Object for 1.5 as well)
+++ Author: Richard Jenks
+++ Date Created: 14 May 1992
+++ Date Last Updated: 14 May 1992
+++ Description: The fundamental Type;
+Type(): Category == with nil
+
+@
+\section{category KOERCE CoercibleTo}
+<<category KOERCE CoercibleTo>>=
+)abbrev category KOERCE CoercibleTo
+++ Category for coerce
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description:
+++ A is coercible to B means any element of A can automatically be
+++ converted into an element of B by the interpreter.
+CoercibleTo(S:Type): Category == with
+ coerce: % -> S
+ ++ coerce(a) transforms a into an element of S.
+
+@
+\section{category KONVERT ConvertibleTo}
+<<category KONVERT ConvertibleTo>>=
+)abbrev category KONVERT ConvertibleTo
+++ Category for convert
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description:
+++ A is convertible to B means any element of A
+++ can be converted into an element of B,
+++ but not automatically by the interpreter.
+ConvertibleTo(S:Type): Category == with
+ convert: % -> S
+ ++ convert(a) transforms a into an element of S.
+
+@
+\section{category RETRACT RetractableTo}
+<<category RETRACT RetractableTo>>=
+)abbrev category RETRACT RetractableTo
+++ Category for retract
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description:
+++ A is retractable to B means that some elementsif A can be converted
+++ into elements of B and any element of B can be converted into an
+++ element of A.
+RetractableTo(S: Type): Category == with
+ coerce: S -> %
+ ++ coerce(a) transforms a into an element of %.
+ retractIfCan: % -> Union(S,"failed")
+ ++ retractIfCan(a) transforms a into an element of S if possible.
+ ++ Returns "failed" if a cannot be made into an element of S.
+ retract: % -> S
+ ++ retract(a) transforms a into an element of S if possible.
+ ++ Error: if a cannot be made into an element of S.
+ add
+ retract(s) ==
+ (u:=retractIfCan s) case "failed" => error "not retractable"
+ u
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category TYPE Type>>
+<<category KOERCE CoercibleTo>>
+<<category KONVERT ConvertibleTo>>
+<<category RETRACT RetractableTo>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/color.spad.pamphlet b/src/algebra/color.spad.pamphlet
new file mode 100644
index 00000000..56801bff
--- /dev/null
+++ b/src/algebra/color.spad.pamphlet
@@ -0,0 +1,202 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra color.spad}
+\author{Jim Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain COLOR Color}
+<<domain COLOR Color>>=
+)abbrev domain COLOR Color
+++ Author: Jim Wen
+++ Date Created: 10 May 1989
+++ Date Last Updated: 19 Mar 1991 by Jon Steinbach
+++ Basic Operations: red, yellow, green, blue, hue, numberOfHues, color, +, *, =
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: Color() specifies a domain of 27 colors provided in the
+++ \Language{} system (the colors mix additively).
+
+
+Color(): Exports == Implementation where
+ I ==> Integer
+ PI ==> PositiveInteger
+ SF ==> DoubleFloat
+
+ Exports ==> AbelianSemiGroup with
+ "*" : (PI, %) -> %
+ ++ s * c, returns the color c, whose weighted shade has been scaled by s.
+ "*" : (SF, %) -> %
+ ++ s * c, returns the color c, whose weighted shade has been scaled by s.
+ "+" : (%, %) -> %
+ ++ c1 + c2 additively mixes the two colors c1 and c2.
+ red : () -> %
+ ++ red() returns the position of the red hue from total hues.
+ yellow : () -> %
+ ++ yellow() returns the position of the yellow hue from total hues.
+ green : () -> %
+ ++ green() returns the position of the green hue from total hues.
+ blue : () -> %
+ ++ blue() returns the position of the blue hue from total hues.
+ hue : % -> I
+ ++ hue(c) returns the hue index of the indicated color c.
+ numberOfHues : () -> PI
+ ++ numberOfHues() returns the number of total hues, set in totalHues.
+ color : Integer -> %
+ ++ color(i) returns a color of the indicated hue i.
+
+ Implementation ==> add
+ totalHues ==> 27 --see (header.h file) for the current number
+
+ Rep := Record(hue:I, weight:SF)
+
+
+ f:SF * c:% ==
+ -- s * c returns the color c, whose weighted shade has been scaled by s
+ zero? f => c
+ -- 0 is the identitly function...or maybe an error is better?
+ [c.hue, f * c.weight]
+
+ x + y ==
+ x.hue = y.hue => [x.hue, x.weight + y.weight]
+ if y.weight > x.weight then -- let x be color with bigger weight
+ c := x
+ x := y
+ y := c
+ diff := x.hue - y.hue
+ if (xHueSmaller:= (diff < 0)) then diff := -diff
+ if (moreThanHalf:=(diff > totalHues quo 2)) then diff := totalHues-diff
+ offset : I := wholePart(round (diff::SF/(2::SF)**(x.weight/y.weight)) )
+ if (xHueSmaller and ^moreThanHalf) or (^xHueSmaller and moreThanHalf) then
+ ans := x.hue + offset
+ else
+ ans := x.hue - offset
+ if (ans < 0) then ans := totalHues + ans
+ else if (ans > totalHues) then ans := ans - totalHues
+ [ans,1]
+
+ x = y == (x.hue = y.hue) and (x.weight = y.weight)
+ red() == [1,1]
+ yellow() == [11::I,1]
+ green() == [14::I,1]
+ blue() == [22::I,1]
+ sample() == red()
+ hue c == c.hue
+ i:PositiveInteger * c:% == i::SF * c
+ numberOfHues() == totalHues
+
+ color i ==
+ if (i<0) or (i>totalHues) then
+ error concat("Color should be in the range 1..",totalHues::String)
+ [i::I, 1]
+
+ coerce(c:%):OutputForm ==
+ hconcat ["Hue: "::OutputForm, (c.hue)::OutputForm,
+ " Weight: "::OutputForm, (c.weight)::OutputForm]
+
+@
+\section{domain PALETTE Palette}
+<<domain PALETTE Palette>>=
+)abbrev domain PALETTE Palette
+++ Author: Jim Wen
+++ Date Created: May 10th 1989
+++ Date Last Updated: Jan 19th 1990
+++ Basic Operations: dark, dim, bright, pastel, light, hue, shade, coerce
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: dim,bright,pastel,coerce
+++ References:
+++ Description: This domain describes four groups of color shades (palettes).
+
+Palette(): Exports == Implementation where
+ I ==> Integer
+ C ==> Color
+ SHADE ==> ["Dark","Dim","Bright","Pastel","Light"]
+
+ Exports ==> SetCategory with
+ dark : C -> %
+ ++ dark(c) sets the shade of the indicated hue of c to it's lowest value.
+ dim : C -> %
+ ++ dim(c) sets the shade of a hue, c, above dark, but below bright.
+ bright : C -> %
+ ++ bright(c) sets the shade of a hue, c, above dim, but below pastel.
+ pastel : C -> %
+ ++ pastel(c) sets the shade of a hue, c, above bright, but below light.
+ light : C -> %
+ ++ light(c) sets the shade of a hue, c, to it's highest value.
+ hue : % -> C
+ ++ hue(p) returns the hue field of the indicated palette p.
+ shade : % -> I
+ ++ shade(p) returns the shade index of the indicated palette p.
+ coerce : C -> %
+ ++ coerce(c) sets the average shade for the palette to that of the
+ ++ indicated color c.
+
+ Implementation ==> add
+ Rep := Record(shadeField:I, hueField:C)
+
+ dark c == [1,c]
+ dim c == [2,c]
+ bright c == [3,c]
+ pastel c == [4,c]
+ light c == [5,c]
+ hue p == p.hueField
+ shade p == p.shadeField
+ sample() == bright(sample())
+ coerce(c:Color):% == bright c
+ coerce(p:%):OutputForm ==
+ hconcat ["[",coerce(p.hueField),"] from the ",SHADE.(p.shadeField)," palette"]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain COLOR Color>>
+<<domain PALETTE Palette>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/combfunc.spad.pamphlet b/src/algebra/combfunc.spad.pamphlet
new file mode 100644
index 00000000..ffbf5887
--- /dev/null
+++ b/src/algebra/combfunc.spad.pamphlet
@@ -0,0 +1,913 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra combfunc.spad}
+\author{Manuel Bronstein, Martin Rubey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category COMBOPC CombinatorialOpsCategory}
+<<category COMBOPC CombinatorialOpsCategory>>=
+)abbrev category COMBOPC CombinatorialOpsCategory
+++ Category for summations and products
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 22 February 1993 (JHD/BMT)
+++ Description:
+++ CombinatorialOpsCategory is the category obtaining by adjoining
+++ summations and products to the usual combinatorial operations;
+CombinatorialOpsCategory(): Category ==
+ CombinatorialFunctionCategory with
+ factorials : $ -> $
+ ++ factorials(f) rewrites the permutations and binomials in f
+ ++ in terms of factorials;
+ factorials : ($, Symbol) -> $
+ ++ factorials(f, x) rewrites the permutations and binomials in f
+ ++ involving x in terms of factorials;
+ summation : ($, Symbol) -> $
+ ++ summation(f(n), n) returns the formal sum S(n) which verifies
+ ++ S(n+1) - S(n) = f(n);
+ summation : ($, SegmentBinding $) -> $
+ ++ summation(f(n), n = a..b) returns f(a) + ... + f(b) as a
+ ++ formal sum;
+ product : ($, Symbol) -> $
+ ++ product(f(n), n) returns the formal product P(n) which verifies
+ ++ P(n+1)/P(n) = f(n);
+ product : ($, SegmentBinding $) -> $
+ ++ product(f(n), n = a..b) returns f(a) * ... * f(b) as a
+ ++ formal product;
+
+@
+The latest change allows Axiom to reduce
+\begin{verbatim}
+ sum(1/i,i=1..n)-sum(1/i,i=1..n)
+\end{verbatim}
+to reduce to zero.
+<<package COMBF CombinatorialFunction>>=
+)abbrev package COMBF CombinatorialFunction
+++ Provides the usual combinatorial functions
+++ Author: Manuel Bronstein, Martin Rubey
+++ Date Created: 2 Aug 1988
+++ Date Last Updated: 30 October 2005
+++ Description:
+++ Provides combinatorial functions over an integral domain.
+++ Keywords: combinatorial, function, factorial.
+++ Examples: )r COMBF INPUT
+
+
+
+CombinatorialFunction(R, F): Exports == Implementation where
+ R: Join(OrderedSet, IntegralDomain)
+ F: FunctionSpace R
+
+ OP ==> BasicOperator
+ K ==> Kernel F
+ SE ==> Symbol
+ O ==> OutputForm
+ SMP ==> SparseMultivariatePolynomial(R, K)
+ Z ==> Integer
+
+ POWER ==> "%power"::Symbol
+ OPEXP ==> "exp"::Symbol
+ SPECIALDIFF ==> "%specialDiff"
+ SPECIALDISP ==> "%specialDisp"
+ SPECIALEQUAL ==> "%specialEqual"
+
+ Exports ==> with
+ belong? : OP -> Boolean
+ ++ belong?(op) is true if op is a combinatorial operator;
+ operator : OP -> OP
+ ++ operator(op) returns a copy of op with the domain-dependent
+ ++ properties appropriate for F;
+ ++ error if op is not a combinatorial operator;
+ "**" : (F, F) -> F
+ ++ a ** b is the formal exponential a**b;
+ binomial : (F, F) -> F
+ ++ binomial(n, r) returns the number of subsets of r objects
+ ++ taken among n objects, i.e. n!/(r! * (n-r)!);
+ permutation: (F, F) -> F
+ ++ permutation(n, r) returns the number of permutations of
+ ++ n objects taken r at a time, i.e. n!/(n-r)!;
+ factorial : F -> F
+ ++ factorial(n) returns the factorial of n, i.e. n!;
+ factorials : F -> F
+ ++ factorials(f) rewrites the permutations and binomials in f
+ ++ in terms of factorials;
+ factorials : (F, SE) -> F
+ ++ factorials(f, x) rewrites the permutations and binomials in f
+ ++ involving x in terms of factorials;
+ summation : (F, SE) -> F
+ ++ summation(f(n), n) returns the formal sum S(n) which verifies
+ ++ S(n+1) - S(n) = f(n);
+ summation : (F, SegmentBinding F) -> F
+ ++ summation(f(n), n = a..b) returns f(a) + ... + f(b) as a
+ ++ formal sum;
+ product : (F, SE) -> F
+ ++ product(f(n), n) returns the formal product P(n) which verifies
+ ++ P(n+1)/P(n) = f(n);
+ product : (F, SegmentBinding F) -> F
+ ++ product(f(n), n = a..b) returns f(a) * ... * f(b) as a
+ ++ formal product;
+ iifact : F -> F
+ ++ iifact(x) should be local but conditional;
+ iibinom : List F -> F
+ ++ iibinom(l) should be local but conditional;
+ iiperm : List F -> F
+ ++ iiperm(l) should be local but conditional;
+ iipow : List F -> F
+ ++ iipow(l) should be local but conditional;
+ iidsum : List F -> F
+ ++ iidsum(l) should be local but conditional;
+ iidprod : List F -> F
+ ++ iidprod(l) should be local but conditional;
+ ipow : List F -> F
+ ++ ipow(l) should be local but conditional;
+
+ Implementation ==> add
+ ifact : F -> F
+ iiipow : List F -> F
+ iperm : List F -> F
+ ibinom : List F -> F
+ isum : List F -> F
+ idsum : List F -> F
+ iprod : List F -> F
+ idprod : List F -> F
+ dsum : List F -> O
+ ddsum : List F -> O
+ dprod : List F -> O
+ ddprod : List F -> O
+ equalsumprod : (K, K) -> Boolean
+ equaldsumprod : (K, K) -> Boolean
+ fourth : List F -> F
+ dvpow1 : List F -> F
+ dvpow2 : List F -> F
+ summand : List F -> F
+ dvsum : (List F, SE) -> F
+ dvdsum : (List F, SE) -> F
+ dvprod : (List F, SE) -> F
+ dvdprod : (List F, SE) -> F
+ facts : (F, List SE) -> F
+ K2fact : (K, List SE) -> F
+ smpfact : (SMP, List SE) -> F
+
+ dummy == new()$SE :: F
+@
+This macro will be used in [[product]] and [[summation]], both the $5$ and $3$
+argument forms. It is used to introduce a dummy variable in place of the
+summation index within the summands. This in turn is necessary to keep the
+indexing variable local, circumventing problems, for example, with
+differentiation.
+
+This works if we don't accidently use such a symbol as a bound of summation or
+product.
+
+Note that up to [[patch--25]] this used to read
+\begin{verbatim}
+ dummy := new()$SE :: F
+\end{verbatim}
+thus introducing the same dummy variable for all products and summations, which
+caused nested products and summations to fail. (Issue~\#72)
+
+<<package COMBF CombinatorialFunction>>=
+ opfact := operator("factorial"::Symbol)$CommonOperators
+ opperm := operator("permutation"::Symbol)$CommonOperators
+ opbinom := operator("binomial"::Symbol)$CommonOperators
+ opsum := operator("summation"::Symbol)$CommonOperators
+ opdsum := operator("%defsum"::Symbol)$CommonOperators
+ opprod := operator("product"::Symbol)$CommonOperators
+ opdprod := operator("%defprod"::Symbol)$CommonOperators
+ oppow := operator(POWER::Symbol)$CommonOperators
+
+ factorial x == opfact x
+ binomial(x, y) == opbinom [x, y]
+ permutation(x, y) == opperm [x, y]
+
+ import F
+ import Kernel F
+
+ number?(x:F):Boolean ==
+ if R has RetractableTo(Z) then
+ ground?(x) or
+ ((retractIfCan(x)@Union(Fraction(Z),"failed")) case Fraction(Z))
+ else
+ ground?(x)
+
+ x ** y ==
+ -- Do some basic simplifications
+ is?(x,POWER) =>
+ args : List F := argument first kernels x
+ not(#args = 2) => error "Too many arguments to **"
+ number?(first args) and number?(y) =>
+ oppow [first(args)**y, second args]
+ oppow [first args, (second args)* y]
+ -- Generic case
+ exp : Union(Record(val:F,exponent:Z),"failed") := isPower x
+ exp case Record(val:F,exponent:Z) =>
+ expr := exp::Record(val:F,exponent:Z)
+ oppow [expr.val, (expr.exponent)*y]
+ oppow [x, y]
+
+ belong? op == has?(op, "comb")
+ fourth l == third rest l
+ dvpow1 l == second(l) * first(l) ** (second l - 1)
+ factorials x == facts(x, variables x)
+ factorials(x, v) == facts(x, [v])
+ facts(x, l) == smpfact(numer x, l) / smpfact(denom x, l)
+ summand l == eval(first l, retract(second l)@K, third l)
+
+ product(x:F, i:SE) ==
+ dm := dummy
+ opprod [eval(x, k := kernel(i)$K, dm), dm, k::F]
+
+ summation(x:F, i:SE) ==
+ dm := dummy
+ opsum [eval(x, k := kernel(i)$K, dm), dm, k::F]
+
+@
+These two operations return the product or the sum as unevaluated operators. A
+dummy variable is introduced to make the indexing variable \lq local\rq.
+
+<<package COMBF CombinatorialFunction>>=
+ dvsum(l, x) ==
+ opsum [differentiate(first l, x), second l, third l]
+
+ dvdsum(l, x) ==
+ x = retract(y := third l)@SE => 0
+ if member?(x, variables(h := third rest rest l)) or
+ member?(x, variables(g := third rest l)) then
+ error "a sum cannot be differentiated with respect to a bound"
+ else
+ opdsum [differentiate(first l, x), second l, y, g, h]
+
+@
+The above two operations implement differentiation of sums with and without
+bounds. Note that the function
+$$n\mapsto\sum_{k=1}^n f(k,n)$$
+is well defined only for integral values of $n$ greater than or equal to zero.
+There is not even consensus how to define this function for $n<0$. Thus, it is
+not differentiable. Therefore, we need to check whether we erroneously are
+differentiating with respect to the upper bound or the lower bound, where the
+same reasoning holds.
+
+Differentiating a sum with respect to its indexing variable correctly gives
+zero. This is due to the introduction of dummy variables in the internal
+representation of a sum: the operator [[%defsum]] takes 5 arguments, namely
+
+\begin{enumerate}
+\item the summands, where each occurrence of the indexing variable is replaced
+ by
+\item the dummy variable,
+\item the indexing variable,
+\item the lower bound, and
+\item the upper bound.
+\end{enumerate}
+
+Note that up to [[patch--40]] the following incorrect code was used, which
+tried to parallel the known rules for integration: (Issue~\#180)
+
+\begin{verbatim}
+ dvdsum(l, x) ==
+ x = retract(y := third l)@SE => 0
+ k := retract(d := second l)@K
+ differentiate(h := third rest rest l,x) * eval(f := first l, k, h)
+ - differentiate(g := third rest l, x) * eval(f, k, g)
+ + opdsum [differentiate(f, x), d, y, g, h]
+\end{verbatim}
+
+Up to [[patch--45]] a similar mistake could be found in the code for
+differentiation of formal sums, which read
+\begin{verbatim}
+ dvsum(l, x) ==
+ k := retract(second l)@K
+ differentiate(third l, x) * summand l
+ + opsum [differentiate(first l, x), second l, third l]
+\end{verbatim}
+
+<<package COMBF CombinatorialFunction>>=
+ dvprod(l, x) ==
+ dm := retract(dummy)@SE
+ f := eval(first l, retract(second l)@K, dm::F)
+ p := product(f, dm)
+
+ opsum [differentiate(first l, x)/first l * p, second l, third l]
+
+
+ dvdprod(l, x) ==
+ x = retract(y := third l)@SE => 0
+ if member?(x, variables(h := third rest rest l)) or
+ member?(x, variables(g := third rest l)) then
+ error "a product cannot be differentiated with respect to a bound"
+ else
+ opdsum cons(differentiate(first l, x)/first l, rest l) * opdprod l
+
+@
+The above two operations implement differentiation of products with and without
+bounds. Note again, that we cannot even properly define products with bounds
+that are not integral.
+
+To differentiate the product, we use Leibniz rule:
+$$\frac{d}{dx}\prod_{i=a}^b f(i,x) =
+ \sum_{i=a}^b \frac{\frac{d}{dx} f(i,x)}{f(i,x)}\prod_{i=a}^b f(i,x)
+$$
+
+There is one situation where this definition might produce wrong results,
+namely when the product is zero, but axiom failed to recognize it: in this
+case,
+$$
+ \frac{d}{dx} f(i,x)/f(i,x)
+$$
+is undefined for some $i$. However, I was not able to come up with an
+example. The alternative definition
+$$
+ \frac{d}{dx}\prod_{i=a}^b f(i,x) =
+ \sum_{i=a}^b \left(\frac{d}{dx} f(i,x)\right)\prod_{j=a,j\neq i}^b f(j,x)
+$$
+has the slight (display) problem that we would have to come up with a new index
+variable, which looks very ugly. Furthermore, it seems to me that more
+simplifications will occur with the first definition.
+
+<<TEST COMBF>>=
+ f := operator 'f
+ D(product(f(i,x),i=1..m),x)
+@
+
+Note that up to [[patch--45]] these functions did not exist and products were
+differentiated according to the usual chain rule, which gave incorrect
+results. (Issue~\#211)
+
+<<package COMBF CombinatorialFunction>>=
+ dprod l ==
+ prod(summand(l)::O, third(l)::O)
+
+ ddprod l ==
+ prod(summand(l)::O, third(l)::O = fourth(l)::O, fourth(rest l)::O)
+
+ dsum l ==
+ sum(summand(l)::O, third(l)::O)
+
+ ddsum l ==
+ sum(summand(l)::O, third(l)::O = fourth(l)::O, fourth(rest l)::O)
+
+@
+These four operations handle the conversion of sums and products to
+[[OutputForm]]. Note that up to [[patch--45]] the definitions for sums and
+products without bounds were missing and output was illegible.
+
+<<package COMBF CombinatorialFunction>>=
+ equalsumprod(s1, s2) ==
+ l1 := argument s1
+ l2 := argument s2
+
+ (eval(first l1, retract(second l1)@K, second l2) = first l2)
+
+ equaldsumprod(s1, s2) ==
+ l1 := argument s1
+ l2 := argument s2
+
+ ((third rest l1 = third rest l2) and
+ (third rest rest l1 = third rest rest l2) and
+ (eval(first l1, retract(second l1)@K, second l2) = first l2))
+
+@
+The preceding two operations handle the testing for equality of sums and
+products. This functionality was missing up to [[patch--45]]. (Issue~\#213) The
+corresponding property [[%specialEqual]] set below is checked in
+[[Kernel]]. Note that we can assume that the operators are equal, since this is
+checked in [[Kernel]] itself.
+<<package COMBF CombinatorialFunction>>=
+ product(x:F, s:SegmentBinding F) ==
+ k := kernel(variable s)$K
+ dm := dummy
+ opdprod [eval(x,k,dm), dm, k::F, lo segment s, hi segment s]
+
+ summation(x:F, s:SegmentBinding F) ==
+ k := kernel(variable s)$K
+ dm := dummy
+ opdsum [eval(x,k,dm), dm, k::F, lo segment s, hi segment s]
+
+@
+These two operations return the product or the sum as unevaluated operators. A
+dummy variable is introduced to make the indexing variable \lq local\rq.
+
+<<package COMBF CombinatorialFunction>>=
+ smpfact(p, l) ==
+ map(K2fact(#1, l), #1::F, p)$PolynomialCategoryLifting(
+ IndexedExponents K, K, R, SMP, F)
+
+ K2fact(k, l) ==
+ empty? [v for v in variables(kf := k::F) | member?(v, l)] => kf
+ empty?(args:List F := [facts(a, l) for a in argument k]) => kf
+ is?(k, opperm) =>
+ factorial(n := first args) / factorial(n - second args)
+ is?(k, opbinom) =>
+ n := first args
+ p := second args
+ factorial(n) / (factorial(p) * factorial(n-p))
+ (operator k) args
+
+ operator op ==
+ is?(op, "factorial"::Symbol) => opfact
+ is?(op, "permutation"::Symbol) => opperm
+ is?(op, "binomial"::Symbol) => opbinom
+ is?(op, "summation"::Symbol) => opsum
+ is?(op, "%defsum"::Symbol) => opdsum
+ is?(op, "product"::Symbol) => opprod
+ is?(op, "%defprod"::Symbol) => opdprod
+ is?(op, POWER) => oppow
+ error "Not a combinatorial operator"
+
+ iprod l ==
+ zero? first l => 0
+-- one? first l => 1
+ (first l = 1) => 1
+ kernel(opprod, l)
+
+ isum l ==
+ zero? first l => 0
+ kernel(opsum, l)
+
+ idprod l ==
+ member?(retract(second l)@SE, variables first l) =>
+ kernel(opdprod, l)
+ first(l) ** (fourth rest l - fourth l + 1)
+
+ idsum l ==
+ member?(retract(second l)@SE, variables first l) =>
+ kernel(opdsum, l)
+ first(l) * (fourth rest l - fourth l + 1)
+
+ ifact x ==
+-- zero? x or one? x => 1
+ zero? x or (x = 1) => 1
+ kernel(opfact, x)
+
+ ibinom l ==
+ n := first l
+ ((p := second l) = 0) or (p = n) => 1
+-- one? p or (p = n - 1) => n
+ (p = 1) or (p = n - 1) => n
+ kernel(opbinom, l)
+
+ iperm l ==
+ zero? second l => 1
+ kernel(opperm, l)
+
+ if R has RetractableTo Z then
+ iidsum l ==
+ (r1:=retractIfCan(fourth l)@Union(Z,"failed"))
+ case "failed" or
+ (r2:=retractIfCan(fourth rest l)@Union(Z,"failed"))
+ case "failed" or
+ (k:=retractIfCan(second l)@Union(K,"failed")) case "failed"
+ => idsum l
+ +/[eval(first l,k::K,i::F) for i in r1::Z .. r2::Z]
+
+ iidprod l ==
+ (r1:=retractIfCan(fourth l)@Union(Z,"failed"))
+ case "failed" or
+ (r2:=retractIfCan(fourth rest l)@Union(Z,"failed"))
+ case "failed" or
+ (k:=retractIfCan(second l)@Union(K,"failed")) case "failed"
+ => idprod l
+ */[eval(first l,k::K,i::F) for i in r1::Z .. r2::Z]
+
+ iiipow l ==
+ (u := isExpt(x := first l, OPEXP)) case "failed" => kernel(oppow, l)
+ rec := u::Record(var: K, exponent: Z)
+ y := first argument(rec.var)
+ (r := retractIfCan(y)@Union(Fraction Z, "failed")) case
+ "failed" => kernel(oppow, l)
+ (operator(rec.var)) (rec.exponent * y * second l)
+
+ if F has RadicalCategory then
+ ipow l ==
+ (r := retractIfCan(second l)@Union(Fraction Z,"failed"))
+ case "failed" => iiipow l
+ first(l) ** (r::Fraction(Z))
+ else
+ ipow l ==
+ (r := retractIfCan(second l)@Union(Z, "failed"))
+ case "failed" => iiipow l
+ first(l) ** (r::Z)
+
+ else
+ ipow l ==
+ zero?(x := first l) =>
+ zero? second l => error "0 ** 0"
+ 0
+-- one? x or zero?(n := second l) => 1
+ (x = 1) or zero?(n: F := second l) => 1
+-- one? n => x
+ (n = 1) => x
+ (u := isExpt(x, OPEXP)) case "failed" => kernel(oppow, l)
+ rec := u::Record(var: K, exponent: Z)
+-- one?(y := first argument(rec.var)) or y = -1 =>
+ ((y := first argument(rec.var))=1) or y = -1 =>
+ (operator(rec.var)) (rec.exponent * y * n)
+ kernel(oppow, l)
+
+ if R has CombinatorialFunctionCategory then
+ iifact x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => ifact x
+ factorial(r::R)::F
+
+ iiperm l ==
+ (r1 := retractIfCan(first l)@Union(R,"failed")) case "failed" or
+ (r2 := retractIfCan(second l)@Union(R,"failed")) case "failed"
+ => iperm l
+ permutation(r1::R, r2::R)::F
+
+ if R has RetractableTo(Z) and F has Algebra(Fraction(Z)) then
+ iibinom l ==
+ (s:=retractIfCan(first l-second l)@Union(R,"failed")) case R and
+ (t:=retractIfCan(s)@Union(Z,"failed")) case Z and s>0=>
+ ans:=1::F
+ for i in 1..t repeat
+ ans:=ans*(second l+i::R::F)
+ (1/factorial t) * ans
+ (r1 := retractIfCan(first l)@Union(R,"failed")) case "failed" or
+ (r2 := retractIfCan(second l)@Union(R,"failed")) case "failed"
+ => ibinom l
+ binomial(r1::R, r2::R)::F
+
+ else
+ iibinom l ==
+ (r1 := retractIfCan(first l)@Union(R,"failed")) case "failed" or
+ (r2 := retractIfCan(second l)@Union(R,"failed")) case "failed"
+ => ibinom l
+ binomial(r1::R, r2::R)::F
+
+ else
+ iifact x == ifact x
+ iibinom l == ibinom l
+ iiperm l == iperm l
+
+ if R has ElementaryFunctionCategory then
+ iipow l ==
+ (r1:=retractIfCan(first l)@Union(R,"failed")) case "failed" or
+ (r2:=retractIfCan(second l)@Union(R,"failed")) case "failed"
+ => ipow l
+ (r1::R ** r2::R)::F
+ else
+ iipow l == ipow l
+
+ if F has ElementaryFunctionCategory then
+ dvpow2 l == if zero?(first l) then
+ 0
+ else
+ log(first l) * first(l) ** second(l)
+
+@
+This operation implements the differentiation of the power operator [[%power]]
+with respect to its second argument, i.e., the exponent. It uses the formula
+$$\frac{d}{dx} g(y)^x = \frac{d}{dx} e^{x\log g(y)} = \log g(y) g(y)^x.$$
+
+If $g(y)$ equals zero, this formula is not valid, since the logarithm is not
+defined there. Although strictly speaking $0^x$ is not differentiable at zero,
+we return zero for convenience.
+
+Note that up to [[patch--25]] this used to read
+\begin{verbatim}
+ if F has ElementaryFunctionCategory then
+ dvpow2 l == log(first l) * first(l) ** second(l)
+\end{verbatim}
+which caused differentiating $0^x$ to fail. (Issue~\#19)
+
+<<package COMBF CombinatorialFunction>>=
+ evaluate(opfact, iifact)$BasicOperatorFunctions1(F)
+ evaluate(oppow, iipow)
+ evaluate(opperm, iiperm)
+ evaluate(opbinom, iibinom)
+ evaluate(opsum, isum)
+ evaluate(opdsum, iidsum)
+ evaluate(opprod, iprod)
+ evaluate(opdprod, iidprod)
+ derivative(oppow, [dvpow1, dvpow2])
+ setProperty(opsum, SPECIALDIFF, dvsum@((List F, SE) -> F) pretend None)
+ setProperty(opdsum, SPECIALDIFF, dvdsum@((List F, SE)->F) pretend None)
+ setProperty(opprod, SPECIALDIFF, dvprod@((List F, SE)->F) pretend None)
+ setProperty(opdprod, SPECIALDIFF, dvdprod@((List F, SE)->F) pretend None)
+@
+The last four properties define special differentiation rules for sums and
+products. Note that up to [[patch--45]] the rules for products were missing.
+Thus products were differentiated according the usual chain-rule, which gave
+incorrect results.
+
+<<package COMBF CombinatorialFunction>>=
+ setProperty(opsum, SPECIALDISP, dsum@(List F -> O) pretend None)
+ setProperty(opdsum, SPECIALDISP, ddsum@(List F -> O) pretend None)
+ setProperty(opprod, SPECIALDISP, dprod@(List F -> O) pretend None)
+ setProperty(opdprod, SPECIALDISP, ddprod@(List F -> O) pretend None)
+ setProperty(opsum, SPECIALEQUAL, equalsumprod@((K,K) -> Boolean) pretend None)
+ setProperty(opdsum, SPECIALEQUAL, equaldsumprod@((K,K) -> Boolean) pretend None)
+ setProperty(opprod, SPECIALEQUAL, equalsumprod@((K,K) -> Boolean) pretend None)
+ setProperty(opdprod, SPECIALEQUAL, equaldsumprod@((K,K) -> Boolean) pretend None)
+
+@
+Finally, we set the properties for displaying sums and products and testing for
+equality.
+
+
+\section{package FSPECF FunctionalSpecialFunction}
+<<package FSPECF FunctionalSpecialFunction>>=
+)abbrev package FSPECF FunctionalSpecialFunction
+++ Provides the special functions
+++ Author: Manuel Bronstein
+++ Date Created: 18 Apr 1989
+++ Date Last Updated: 4 October 1993
+++ Description: Provides some special functions over an integral domain.
+++ Keywords: special, function.
+FunctionalSpecialFunction(R, F): Exports == Implementation where
+ R: Join(OrderedSet, IntegralDomain)
+ F: FunctionSpace R
+
+ OP ==> BasicOperator
+ K ==> Kernel F
+ SE ==> Symbol
+
+ Exports ==> with
+ belong? : OP -> Boolean
+ ++ belong?(op) is true if op is a special function operator;
+ operator: OP -> OP
+ ++ operator(op) returns a copy of op with the domain-dependent
+ ++ properties appropriate for F;
+ ++ error if op is not a special function operator
+ abs : F -> F
+ ++ abs(f) returns the absolute value operator applied to f
+ Gamma : F -> F
+ ++ Gamma(f) returns the formal Gamma function applied to f
+ Gamma : (F,F) -> F
+ ++ Gamma(a,x) returns the incomplete Gamma function applied to a and x
+ Beta: (F,F) -> F
+ ++ Beta(x,y) returns the beta function applied to x and y
+ digamma: F->F
+ ++ digamma(x) returns the digamma function applied to x
+ polygamma: (F,F) ->F
+ ++ polygamma(x,y) returns the polygamma function applied to x and y
+ besselJ: (F,F) -> F
+ ++ besselJ(x,y) returns the besselj function applied to x and y
+ besselY: (F,F) -> F
+ ++ besselY(x,y) returns the bessely function applied to x and y
+ besselI: (F,F) -> F
+ ++ besselI(x,y) returns the besseli function applied to x and y
+ besselK: (F,F) -> F
+ ++ besselK(x,y) returns the besselk function applied to x and y
+ airyAi: F -> F
+ ++ airyAi(x) returns the airyai function applied to x
+ airyBi: F -> F
+ ++ airyBi(x) returns the airybi function applied to x
+
+ iiGamma : F -> F
+ ++ iiGamma(x) should be local but conditional;
+ iiabs : F -> F
+ ++ iiabs(x) should be local but conditional;
+
+ Implementation ==> add
+ iabs : F -> F
+ iGamma: F -> F
+
+ opabs := operator("abs"::Symbol)$CommonOperators
+ opGamma := operator("Gamma"::Symbol)$CommonOperators
+ opGamma2 := operator("Gamma2"::Symbol)$CommonOperators
+ opBeta := operator("Beta"::Symbol)$CommonOperators
+ opdigamma := operator("digamma"::Symbol)$CommonOperators
+ oppolygamma := operator("polygamma"::Symbol)$CommonOperators
+ opBesselJ := operator("besselJ"::Symbol)$CommonOperators
+ opBesselY := operator("besselY"::Symbol)$CommonOperators
+ opBesselI := operator("besselI"::Symbol)$CommonOperators
+ opBesselK := operator("besselK"::Symbol)$CommonOperators
+ opAiryAi := operator("airyAi"::Symbol)$CommonOperators
+ opAiryBi := operator("airyBi"::Symbol)$CommonOperators
+
+ abs x == opabs x
+ Gamma(x) == opGamma(x)
+ Gamma(a,x) == opGamma2(a,x)
+ Beta(x,y) == opBeta(x,y)
+ digamma x == opdigamma(x)
+ polygamma(k,x)== oppolygamma(k,x)
+ besselJ(a,x) == opBesselJ(a,x)
+ besselY(a,x) == opBesselY(a,x)
+ besselI(a,x) == opBesselI(a,x)
+ besselK(a,x) == opBesselK(a,x)
+ airyAi(x) == opAiryAi(x)
+ airyBi(x) == opAiryBi(x)
+
+ belong? op == has?(op, "special")
+
+ operator op ==
+ is?(op, "abs"::Symbol) => opabs
+ is?(op, "Gamma"::Symbol) => opGamma
+ is?(op, "Gamma2"::Symbol) => opGamma2
+ is?(op, "Beta"::Symbol) => opBeta
+ is?(op, "digamma"::Symbol) => opdigamma
+ is?(op, "polygamma"::Symbol)=> oppolygamma
+ is?(op, "besselJ"::Symbol) => opBesselJ
+ is?(op, "besselY"::Symbol) => opBesselY
+ is?(op, "besselI"::Symbol) => opBesselI
+ is?(op, "besselK"::Symbol) => opBesselK
+ is?(op, "airyAi"::Symbol) => opAiryAi
+ is?(op, "airyBi"::Symbol) => opAiryBi
+
+ error "Not a special operator"
+
+ -- Could put more unconditional special rules for other functions here
+ iGamma x ==
+-- one? x => x
+ (x = 1) => x
+ kernel(opGamma, x)
+
+ iabs x ==
+ zero? x => 0
+ is?(x, opabs) => x
+ x < 0 => kernel(opabs, -x)
+ kernel(opabs, x)
+
+ -- Could put more conditional special rules for other functions here
+
+ if R has abs : R -> R then
+ iiabs x ==
+ (r := retractIfCan(x)@Union(Fraction Polynomial R, "failed"))
+ case "failed" => iabs x
+ f := r::Fraction Polynomial R
+ (a := retractIfCan(numer f)@Union(R, "failed")) case "failed" or
+ (b := retractIfCan(denom f)@Union(R,"failed")) case "failed" => iabs x
+ abs(a::R)::F / abs(b::R)::F
+
+ else iiabs x == iabs x
+
+ if R has SpecialFunctionCategory then
+ iiGamma x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iGamma x
+ Gamma(r::R)::F
+
+ else
+ if R has RetractableTo Integer then
+ iiGamma x ==
+ (r := retractIfCan(x)@Union(Integer, "failed")) case Integer
+ and (r::Integer >= 1) => factorial(r::Integer - 1)::F
+ iGamma x
+ else
+ iiGamma x == iGamma x
+
+ -- Default behaviour is to build a kernel
+ evaluate(opGamma, iiGamma)$BasicOperatorFunctions1(F)
+ evaluate(opabs, iiabs)$BasicOperatorFunctions1(F)
+
+ import Fraction Integer
+ ahalf: F := recip(2::F)::F
+ athird: F := recip(2::F)::F
+ twothirds: F := 2*recip(3::F)::F
+
+ lzero(l: List F): F == 0
+
+ iBesselJGrad(l: List F): F ==
+ n := first l; x := second l
+ ahalf * (besselJ (n-1,x) - besselJ (n+1,x))
+ iBesselYGrad(l: List F): F ==
+ n := first l; x := second l
+ ahalf * (besselY (n-1,x) - besselY (n+1,x))
+ iBesselIGrad(l: List F): F ==
+ n := first l; x := second l
+ ahalf * (besselI (n-1,x) + besselI (n+1,x))
+ iBesselKGrad(l: List F): F ==
+ n := first l; x := second l
+ ahalf * (besselK (n-1,x) + besselK (n+1,x))
+ ipolygammaGrad(l: List F): F ==
+ n := first l; x := second l
+ polygamma(n+1, x)
+ iBetaGrad1(l: List F): F ==
+ x := first l; y := second l
+ Beta(x,y)*(digamma x - digamma(x+y))
+ iBetaGrad2(l: List F): F ==
+ x := first l; y := second l
+ Beta(x,y)*(digamma y - digamma(x+y))
+
+ if F has ElementaryFunctionCategory then
+ iGamma2Grad(l: List F):F ==
+ a := first l; x := second l
+ - x ** (a - 1) * exp(-x)
+ derivative(opGamma2, [lzero, iGamma2Grad])
+
+ derivative(opabs, abs(#1) * inv(#1))
+ derivative(opGamma, digamma #1 * Gamma #1)
+ derivative(opBeta, [iBetaGrad1, iBetaGrad2])
+ derivative(opdigamma, polygamma(1, #1))
+ derivative(oppolygamma, [lzero, ipolygammaGrad])
+ derivative(opBesselJ, [lzero, iBesselJGrad])
+ derivative(opBesselY, [lzero, iBesselYGrad])
+ derivative(opBesselI, [lzero, iBesselIGrad])
+ derivative(opBesselK, [lzero, iBesselKGrad])
+
+@
+\section{package SUMFS FunctionSpaceSum}
+<<package SUMFS FunctionSpaceSum>>=
+)abbrev package SUMFS FunctionSpaceSum
+++ Top-level sum function
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 19 April 1991
+++ Description: computes sums of top-level expressions;
+FunctionSpaceSum(R, F): Exports == Implementation where
+ R: Join(IntegralDomain, OrderedSet,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F: Join(FunctionSpace R, CombinatorialOpsCategory,
+ AlgebraicallyClosedField, TranscendentalFunctionCategory)
+
+ SE ==> Symbol
+ K ==> Kernel F
+
+ Exports ==> with
+ sum: (F, SE) -> F
+ ++ sum(a(n), n) returns A(n) such that A(n+1) - A(n) = a(n);
+ sum: (F, SegmentBinding F) -> F
+ ++ sum(f(n), n = a..b) returns f(a) + f(a+1) + ... + f(b);
+
+ Implementation ==> add
+ import ElementaryFunctionStructurePackage(R, F)
+ import GosperSummationMethod(IndexedExponents K, K, R,
+ SparseMultivariatePolynomial(R, K), F)
+
+ innersum: (F, K) -> Union(F, "failed")
+ notRF? : (F, K) -> Boolean
+ newk : () -> K
+
+ newk() == kernel(new()$SE)
+
+ sum(x:F, s:SegmentBinding F) ==
+ k := kernel(variable s)@K
+ (u := innersum(x, k)) case "failed" => summation(x, s)
+ eval(u::F, k, 1 + hi segment s) - eval(u::F, k, lo segment s)
+
+ sum(x:F, v:SE) ==
+ (u := innersum(x, kernel(v)@K)) case "failed" => summation(x,v)
+ u::F
+
+ notRF?(f, k) ==
+ for kk in tower f repeat
+ member?(k, tower(kk::F)) and (symbolIfCan(kk) case "failed") =>
+ return true
+ false
+
+ innersum(x, k) ==
+ zero? x => 0
+ notRF?(f := normalize(x / (x1 := eval(x, k, k::F - 1))), k) =>
+ "failed"
+ (u := GospersMethod(f, k, newk)) case "failed" => "failed"
+ x1 * eval(u::F, k, k::F - 1)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl function funcpkgs manip algfunc
+-- elemntry constant funceval COMBFUNC fe
+
+<<category COMBOPC CombinatorialOpsCategory>>
+<<package COMBF CombinatorialFunction>>
+<<package FSPECF FunctionalSpecialFunction>>
+<<package SUMFS FunctionSpaceSum>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/combinat.spad.pamphlet b/src/algebra/combinat.spad.pamphlet
new file mode 100644
index 00000000..55765dc4
--- /dev/null
+++ b/src/algebra/combinat.spad.pamphlet
@@ -0,0 +1,201 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra combinat.spad}
+\author{Martin Brock, Robert Sutor, Michael Monagan}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package COMBINAT IntegerCombinatoricFunctions}
+<<package COMBINAT IntegerCombinatoricFunctions>>=
+)abbrev package COMBINAT IntegerCombinatoricFunctions
+++ Authors: Martin Brock, Robert Sutor, Michael Monagan
+++ Date Created: June 1987
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: integer, combinatoric function
+++ Examples:
+++ References:
+++ Description:
+++ The \spadtype{IntegerCombinatoricFunctions} package provides some
+++ standard functions in combinatorics.
+Z ==> Integer
+N ==> NonNegativeInteger
+SUP ==> SparseUnivariatePolynomial
+
+IntegerCombinatoricFunctions(I:IntegerNumberSystem): with
+ binomial: (I, I) -> I
+ ++ \spad{binomial(n,r)} returns the binomial coefficient
+ ++ \spad{C(n,r) = n!/(r! (n-r)!)}, where \spad{n >= r >= 0}.
+ ++ This is the number of combinations of n objects taken r at a time.
+ factorial: I -> I
+ ++ \spad{factorial(n)} returns \spad{n!}. this is the product of all
+ ++ integers between 1 and n (inclusive).
+ ++ Note: \spad{0!} is defined to be 1.
+ multinomial: (I, List I) -> I
+ ++ \spad{multinomial(n,[m1,m2,...,mk])} returns the multinomial
+ ++ coefficient \spad{n!/(m1! m2! ... mk!)}.
+ partition: I -> I
+ ++ \spad{partition(n)} returns the number of partitions of the integer n.
+ ++ This is the number of distinct ways that n can be written as
+ ++ a sum of positive integers.
+ permutation: (I, I) -> I
+ ++ \spad{permutation(n)} returns \spad{!P(n,r) = n!/(n-r)!}. This is
+ ++ the number of permutations of n objects taken r at a time.
+ stirling1: (I, I) -> I
+ ++ \spad{stirling1(n,m)} returns the Stirling number of the first kind
+ ++ denoted \spad{S[n,m]}.
+ stirling2: (I, I) -> I
+ ++ \spad{stirling2(n,m)} returns the Stirling number of the second kind
+ ++ denoted \spad{SS[n,m]}.
+ == add
+ F : Record(Fn:I, Fv:I) := [0,1]
+ B : Record(Bn:I, Bm:I, Bv:I) := [0,0,0]
+ S : Record(Sn:I, Sp:SUP I) := [0,0]
+ P : IndexedFlexibleArray(I,0) := new(1,1)$IndexedFlexibleArray(I,0)
+
+ partition n ==
+ -- This is the number of ways of expressing n as a sum of positive
+ -- integers, without regard to order. For example partition 5 = 7
+ -- since 5 = 1+1+1+1+1 = 1+1+1+2 = 1+2+2 = 1+1+3 = 1+4 = 2+3 = 5 .
+ -- Uses O(sqrt n) term recurrence from Abramowitz & Stegun pp. 825
+ -- p(n) = sum (-1)**k p(n-j) where 0 < j := (3*k**2+-k) quo 2 <= n
+ minIndex(P) ^= 0 => error "Partition: must have minIndex of 0"
+ m := #P
+ n < 0 => error "partition is not defined for negative integers"
+ n < m::I => P(convert(n)@Z)
+ concat_!(P, new((convert(n+1)@Z - m)::N,0)$IndexedFlexibleArray(I,0))
+ for i in m..convert(n)@Z repeat
+ s:I := 1
+ t:I := 0
+ for k in 1.. repeat
+ l := (3*k*k-k) quo 2
+ l > i => leave
+ u := l+k
+ t := t + s * P(convert(i-l)@Z)
+ u > i => leave
+ t := t + s * P(convert(i-u)@Z)
+ s := -s
+ P.i := t
+ P(convert(n)@Z)
+
+ factorial n ==
+ s,f,t : I
+ n < 0 => error "factorial not defined for negative integers"
+ if n <= F.Fn then s := f := 1 else (s, f) := F
+ for k in convert(s+1)@Z .. convert(n)@Z by 2 repeat
+ if k::I = n then t := n else t := k::I * (k+1)::I
+ f := t * f
+ F.Fn := n
+ F.Fv := f
+
+ binomial(n, m) ==
+ s,b:I
+ n < 0 or m < 0 or m > n => 0
+ m = 0 => 1
+ n < 2*m => binomial(n, n-m)
+ (s,b) := (0,1)
+ if B.Bn = n then
+ B.Bm = m+1 =>
+ b := (B.Bv * (m+1)) quo (n-m)
+ B.Bn := n
+ B.Bm := m
+ return(B.Bv := b)
+ if m >= B.Bm then (s := B.Bm; b := B.Bv) else (s,b) := (0,1)
+ for k in convert(s+1)@Z .. convert(m)@Z repeat
+ b := (b*(n-k::I+1)) quo k::I
+ B.Bn := n
+ B.Bm := m
+ B.Bv := b
+
+ multinomial(n, m) ==
+ for t in m repeat t < 0 => return 0
+ n < _+/m => 0
+ s:I := 1
+ for t in m repeat s := s * factorial t
+ factorial n quo s
+
+ permutation(n, m) ==
+ t:I
+ m < 0 or n < m => 0
+ m := n-m
+ p:I := 1
+ for k in convert(m+1)@Z .. convert(n)@Z by 2 repeat
+ if k::I = n then t := n else t := (k*(k+1))::I
+ p := p * t
+ p
+
+ stirling1(n, m) ==
+ -- Definition: (-1)**(n-m) S[n,m] is the number of
+ -- permutations of n symbols which have m cycles.
+ n < 0 or m < 1 or m > n => 0
+ m = n => 1
+ S.Sn = n => coefficient(S.Sp, convert(m)@Z :: N)
+ x := monomial(1, 1)$SUP(I)
+ S.Sn := n
+ S.Sp := x
+ for k in 1 .. convert(n-1)@Z repeat S.Sp := S.Sp * (x - k::SUP(I))
+ coefficient(S.Sp, convert(m)@Z :: N)
+
+ stirling2(n, m) ==
+ -- definition: SS[n,m] is the number of ways of partitioning
+ -- a set of n elements into m non-empty subsets
+ n < 0 or m < 1 or m > n => 0
+ m = 1 or n = m => 1
+ s:I := if odd? m then -1 else 1
+ t:I := 0
+ for k in 1..convert(m)@Z repeat
+ s := -s
+ t := t + s * binomial(m, k::I) * k::I ** (convert(n)@Z :: N)
+ t quo factorial m
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package COMBINAT IntegerCombinatoricFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/complet.spad.pamphlet b/src/algebra/complet.spad.pamphlet
new file mode 100644
index 00000000..2dc03ae7
--- /dev/null
+++ b/src/algebra/complet.spad.pamphlet
@@ -0,0 +1,377 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra complet.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ORDCOMP OrderedCompletion}
+<<domain ORDCOMP OrderedCompletion>>=
+)abbrev domain ORDCOMP OrderedCompletion
+++ Completion with + and - infinity
+++ Author: Manuel Bronstein
+++ Description: Adjunction of two real infinites quantities to a set.
+++ Date Created: 4 Oct 1989
+++ Date Last Updated: 1 Nov 1989
+OrderedCompletion(R:SetCategory): Exports == Implementation where
+ B ==> Boolean
+
+ Exports ==> Join(SetCategory, FullyRetractableTo R) with
+ plusInfinity : () -> % ++ plusInfinity() returns +infinity.
+ minusInfinity: () -> % ++ minusInfinity() returns -infinity.
+ finite? : % -> B
+ ++ finite?(x) tests if x is finite.
+ infinite? : % -> B
+ ++ infinite?(x) tests if x is +infinity or -infinity,
+ whatInfinity : % -> SingleInteger
+ ++ whatInfinity(x) returns 0 if x is finite,
+ ++ 1 if x is +infinity, and -1 if x is -infinity.
+ if R has AbelianGroup then AbelianGroup
+ if R has OrderedRing then OrderedRing
+ if R has IntegerNumberSystem then
+ rational?: % -> Boolean
+ ++ rational?(x) tests if x is a finite rational number.
+ rational : % -> Fraction Integer
+ ++ rational(x) returns x as a finite rational number.
+ ++ Error: if x cannot be so converted.
+ rationalIfCan: % -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(x) returns x as a finite rational number if
+ ++ it is one and "failed" otherwise.
+
+ Implementation ==> add
+ Rep := Union(fin:R, inf:B) -- true = +infinity, false = -infinity
+
+ coerce(r:R):% == [r]
+ retract(x:%):R == (x case fin => x.fin; error "Not finite")
+ finite? x == x case fin
+ infinite? x == x case inf
+ plusInfinity() == [true]
+ minusInfinity() == [false]
+
+ retractIfCan(x:%):Union(R, "failed") ==
+ x case fin => x.fin
+ "failed"
+
+ coerce(x:%):OutputForm ==
+ x case fin => (x.fin)::OutputForm
+ e := "infinity"::OutputForm
+ x.inf => empty() + e
+ - e
+
+ whatInfinity x ==
+ x case fin => 0
+ x.inf => 1
+ -1
+
+ x = y ==
+ x case inf =>
+ y case inf => not xor(x.inf, y.inf)
+ false
+ y case inf => false
+ x.fin = y.fin
+
+ if R has AbelianGroup then
+ 0 == [0$R]
+
+ n:Integer * x:% ==
+ x case inf =>
+ n > 0 => x
+ n < 0 => [not(x.inf)]
+ error "Undefined product"
+ [n * x.fin]
+
+ - x ==
+ x case inf => [not(x.inf)]
+ [- (x.fin)]
+
+ x + y ==
+ x case inf =>
+ y case fin => x
+ xor(x.inf, y.inf) => error "Undefined sum"
+ x
+ y case inf => y
+ [x.fin + y.fin]
+
+ if R has OrderedRing then
+ fininf: (B, R) -> %
+
+ 1 == [1$R]
+ characteristic() == characteristic()$R
+
+ fininf(b, r) ==
+ r > 0 => [b]
+ r < 0 => [not b]
+ error "Undefined product"
+
+ x:% * y:% ==
+ x case inf =>
+ y case inf =>
+ xor(x.inf, y.inf) => minusInfinity()
+ plusInfinity()
+ fininf(x.inf, y.fin)
+ y case inf => fininf(y.inf, x.fin)
+ [x.fin * y.fin]
+
+ recip x ==
+ x case inf => 0
+ (u := recip(x.fin)) case "failed" => "failed"
+ [u::R]
+
+ x < y ==
+ x case inf =>
+ y case inf =>
+ xor(x.inf, y.inf) => y.inf
+ false
+ not(x.inf)
+ y case inf => y.inf
+ x.fin < y.fin
+
+ if R has IntegerNumberSystem then
+ rational? x == finite? x
+ rational x == rational(retract(x)@R)
+
+ rationalIfCan x ==
+ (r:= retractIfCan(x)@Union(R,"failed")) case "failed" =>"failed"
+ rational(r::R)
+
+@
+\section{package ORDCOMP2 OrderedCompletionFunctions2}
+<<package ORDCOMP2 OrderedCompletionFunctions2>>=
+)abbrev package ORDCOMP2 OrderedCompletionFunctions2
+++ Lifting of maps to ordered completions
+++ Author: Manuel Bronstein
+++ Description: Lifting of maps to ordered completions.
+++ Date Created: 4 Oct 1989
+++ Date Last Updated: 4 Oct 1989
+OrderedCompletionFunctions2(R, S): Exports == Implementation where
+ R, S: SetCategory
+
+ ORR ==> OrderedCompletion R
+ ORS ==> OrderedCompletion S
+
+ Exports ==> with
+ map: (R -> S, ORR) -> ORS
+ ++ map(f, r) lifts f and applies it to r, assuming that
+ ++ f(plusInfinity) = plusInfinity and that
+ ++ f(minusInfinity) = minusInfinity.
+ map: (R -> S, ORR, ORS, ORS) -> ORS
+ ++ map(f, r, p, m) lifts f and applies it to r, assuming that
+ ++ f(plusInfinity) = p and that f(minusInfinity) = m.
+
+ Implementation ==> add
+ map(f, r) == map(f, r, plusInfinity(), minusInfinity())
+
+ map(f, r, p, m) ==
+ zero?(n := whatInfinity r) => (f retract r)::ORS
+-- one? n => p
+ (n = 1) => p
+ m
+
+@
+\section{domain ONECOMP OnePointCompletion}
+<<domain ONECOMP OnePointCompletion>>=
+)abbrev domain ONECOMP OnePointCompletion
+++ Completion with infinity
+++ Author: Manuel Bronstein
+++ Description: Adjunction of a complex infinity to a set.
+++ Date Created: 4 Oct 1989
+++ Date Last Updated: 1 Nov 1989
+OnePointCompletion(R:SetCategory): Exports == Implementation where
+ B ==> Boolean
+
+ Exports ==> Join(SetCategory, FullyRetractableTo R) with
+ infinity : () -> %
+ ++ infinity() returns infinity.
+ finite? : % -> B
+ ++ finite?(x) tests if x is finite.
+ infinite?: % -> B
+ ++ infinite?(x) tests if x is infinite.
+ if R has AbelianGroup then AbelianGroup
+ if R has OrderedRing then OrderedRing
+ if R has IntegerNumberSystem then
+ rational?: % -> Boolean
+ ++ rational?(x) tests if x is a finite rational number.
+ rational : % -> Fraction Integer
+ ++ rational(x) returns x as a finite rational number.
+ ++ Error: if x is not a rational number.
+ rationalIfCan: % -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(x) returns x as a finite rational number if
+ ++ it is one, "failed" otherwise.
+
+ Implementation ==> add
+ Rep := Union(R, "infinity")
+
+ coerce(r:R):% == r
+ retract(x:%):R == (x case R => x::R; error "Not finite")
+ finite? x == x case R
+ infinite? x == x case "infinity"
+ infinity() == "infinity"
+ retractIfCan(x:%):Union(R, "failed") == (x case R => x::R; "failed")
+
+ coerce(x:%):OutputForm ==
+ x case "infinity" => "infinity"::OutputForm
+ x::R::OutputForm
+
+ x = y ==
+ x case "infinity" => y case "infinity"
+ y case "infinity" => false
+ x::R = y::R
+
+ if R has AbelianGroup then
+ 0 == 0$R
+
+ n:Integer * x:% ==
+ x case "infinity" =>
+ zero? n => error "Undefined product"
+ infinity()
+ n * x::R
+
+ - x ==
+ x case "infinity" => error "Undefined inverse"
+ - (x::R)
+
+ x + y ==
+ x case "infinity" => x
+ y case "infinity" => y
+ x::R + y::R
+
+ if R has OrderedRing then
+ fininf: R -> %
+
+ 1 == 1$R
+ characteristic() == characteristic()$R
+
+ fininf r ==
+ zero? r => error "Undefined product"
+ infinity()
+
+ x:% * y:% ==
+ x case "infinity" =>
+ y case "infinity" => y
+ fininf(y::R)
+ y case "infinity" => fininf(x::R)
+ x::R * y::R
+
+ recip x ==
+ x case "infinity" => 0
+ zero?(x::R) => infinity()
+ (u := recip(x::R)) case "failed" => "failed"
+ u::R::%
+
+ x < y ==
+ x case "infinity" => false -- do not change the order
+ y case "infinity" => true -- of those two tests
+ x::R < y::R
+
+ if R has IntegerNumberSystem then
+ rational? x == finite? x
+ rational x == rational(retract(x)@R)
+
+ rationalIfCan x ==
+ (r:= retractIfCan(x)@Union(R,"failed")) case "failed" =>"failed"
+ rational(r::R)
+
+@
+\section{package ONECOMP2 OnePointCompletionFunctions2}
+<<package ONECOMP2 OnePointCompletionFunctions2>>=
+)abbrev package ONECOMP2 OnePointCompletionFunctions2
+++ Lifting of maps to one-point completions
+++ Author: Manuel Bronstein
+++ Description: Lifting of maps to one-point completions.
+++ Date Created: 4 Oct 1989
+++ Date Last Updated: 4 Oct 1989
+OnePointCompletionFunctions2(R, S): Exports == Implementation where
+ R, S: SetCategory
+
+ OPR ==> OnePointCompletion R
+ OPS ==> OnePointCompletion S
+
+ Exports ==> with
+ map: (R -> S, OPR) -> OPS
+ ++ map(f, r) lifts f and applies it to r, assuming that
+ ++ f(infinity) = infinity.
+ map: (R -> S, OPR, OPS) -> OPS
+ ++ map(f, r, i) lifts f and applies it to r, assuming that
+ ++ f(infinity) = i.
+
+ Implementation ==> add
+ map(f, r) == map(f, r, infinity())
+
+ map(f, r, i) ==
+ (u := retractIfCan r) case R => (f(u::R))::OPS
+ i
+
+@
+\section{package INFINITY Infinity}
+<<package INFINITY Infinity>>=
+)abbrev package INFINITY Infinity
+++ Top-level infinity
+++ Author: Manuel Bronstein
+++ Description: Default infinity signatures for the interpreter;
+++ Date Created: 4 Oct 1989
+++ Date Last Updated: 4 Oct 1989
+Infinity(): with
+ infinity : () -> OnePointCompletion Integer
+ ++ infinity() returns infinity.
+ plusInfinity : () -> OrderedCompletion Integer
+ ++ plusInfinity() returns plusIinfinity.
+ minusInfinity: () -> OrderedCompletion Integer
+ ++ minusInfinity() returns minusInfinity.
+ == add
+ infinity() == infinity()$OnePointCompletion(Integer)
+ plusInfinity() == plusInfinity()$OrderedCompletion(Integer)
+ minusInfinity() == minusInfinity()$OrderedCompletion(Integer)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ORDCOMP OrderedCompletion>>
+<<package ORDCOMP2 OrderedCompletionFunctions2>>
+<<domain ONECOMP OnePointCompletion>>
+<<package ONECOMP2 OnePointCompletionFunctions2>>
+<<package INFINITY Infinity>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/constant.spad.pamphlet b/src/algebra/constant.spad.pamphlet
new file mode 100644
index 00000000..8cab8cc9
--- /dev/null
+++ b/src/algebra/constant.spad.pamphlet
@@ -0,0 +1,243 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra constant.spad}
+\author{Manuel Bronstein, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain IAN InnerAlgebraicNumber}
+<<domain IAN InnerAlgebraicNumber>>=
+)abbrev domain IAN InnerAlgebraicNumber
+++ Algebraic closure of the rational numbers
+++ Author: Manuel Bronstein
+++ Date Created: 22 March 1988
+++ Date Last Updated: 4 October 1995 (JHD)
+++ Description: Algebraic closure of the rational numbers.
+++ Keywords: algebraic, number.
+InnerAlgebraicNumber(): Exports == Implementation where
+ Z ==> Integer
+ FE ==> Expression Z
+ K ==> Kernel %
+ P ==> SparseMultivariatePolynomial(Z, K)
+ ALGOP ==> "%alg"
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> 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
+ Implementation ==> FE add
+
+ Rep := FE
+
+ -- private
+ mainRatDenom(f:%):% ==
+ ratDenom(f::Rep::FE)$AlgebraicManipulations(Integer, FE)::Rep::%
+-- mv:= mainVariable denom f
+-- mv case "failed" => f
+-- algv:=mv::K
+-- q:=univariate(f, algv, minPoly(algv))$PolynomialCategoryQuotientFunctions(IndexedExponents K,K,Integer,P,%)
+-- q(algv::%)
+
+ 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(#1::%,univariate(p,k))$SparseUnivariatePolynomialFunctions2(P,%)
+ -- public
+ a,b:%
+ differentiate(x:%):% == 0
+ zero? a == zero? numer a
+-- one? a == one? numer a and one? denom 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(#1::SUP %,minPoly k)$SparseUnivariatePolynomialFunctions2(%,SUP %)
+ f:=findDenominator z
+ zz:=map(makeUnivariate(numer #1,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(#1::Float, x pretend FE)$ExpressionFunctions2(Z,Float)
+
+ convert(x:%):DoubleFloat ==
+ retract map(#1::DoubleFloat,
+ x pretend FE)$ExpressionFunctions2(Z, DoubleFloat)
+
+ convert(x:%):Complex(Float) ==
+ retract map(#1::Complex(Float),
+ x pretend FE)$ExpressionFunctions2(Z, Complex Float)
+
+@
+\section{domain AN AlgebraicNumber}
+<<domain AN AlgebraicNumber>>=
+)abbrev domain AN AlgebraicNumber
+++ Algebraic closure of the rational numbers
+++ Author: James Davenport
+++ Date Created: 9 October 1995
+++ Date Last Updated: 10 October 1995 (JHD)
+++ Description: Algebraic closure of the rational numbers, with mathematical =
+++ Keywords: algebraic, number.
+AlgebraicNumber(): Exports == Implementation where
+ Z ==> Integer
+ P ==> SparseMultivariatePolynomial(Z, Kernel %)
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> 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.
+ 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
+ Implementation ==> InnerAlgebraicNumber add
+ Rep:=InnerAlgebraicNumber
+ a,b:%
+ zero? a == trueEqual(a::Rep,0::Rep)
+ one? a == trueEqual(a::Rep,1::Rep)
+ a=b == trueEqual((a-b)::Rep,0::Rep)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain IAN InnerAlgebraicNumber>>
+<<domain AN AlgebraicNumber>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/cont.spad.pamphlet b/src/algebra/cont.spad.pamphlet
new file mode 100644
index 00000000..5183d276
--- /dev/null
+++ b/src/algebra/cont.spad.pamphlet
@@ -0,0 +1,357 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra cont.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ESCONT ExpertSystemContinuityPackage}
+<<package ESCONT ExpertSystemContinuityPackage>>=
+)abbrev package ESCONT ExpertSystemContinuityPackage
+++ Author: Brian Dupee
+++ Date Created: May 1994
+++ Date Last Updated: June 1995
+++ Basic Operations: problemPoints, singularitiesOf, zerosOf
+++ Related Constructors:
+++ Description:
+++ ExpertSystemContinuityPackage is a package of functions for the use of domains
+++ belonging to the category \axiomType{NumericalIntegration}.
+
+ExpertSystemContinuityPackage(): E == I where
+ EF2 ==> ExpressionFunctions2
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ PFI ==> Polynomial Fraction Integer
+ DF ==> DoubleFloat
+ LDF ==> List DoubleFloat
+ EDF ==> Expression DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ SDF ==> Stream DoubleFloat
+ SS ==> Stream String
+ EEDF ==> Equation Expression DoubleFloat
+ LEDF ==> List Expression DoubleFloat
+ KEDF ==> Kernel Expression DoubleFloat
+ LKEDF ==> List Kernel Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ FPDF ==> Fraction Polynomial DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ UP ==> UnivariatePolynomial
+ BO ==> BasicOperator
+ RS ==> Record(zeros: SDF,ones: SDF,singularities: SDF)
+
+ E ==> with
+
+ getlo : SOCDF -> DF
+ ++ getlo(u) gets the \axiomType{DoubleFloat} equivalent of
+ ++ the first endpoint of the range \axiom{u}
+ gethi : SOCDF -> DF
+ ++ gethi(u) gets the \axiomType{DoubleFloat} equivalent of
+ ++ the second endpoint of the range \axiom{u}
+ functionIsFracPolynomial?: NIA -> Boolean
+ ++ functionIsFracPolynomial?(args) tests whether the function
+ ++ can be retracted to \axiomType{Fraction(Polynomial(DoubleFloat))}
+ problemPoints:(EDF,Symbol,SOCDF) -> List DF
+ ++ problemPoints(f,var,range) returns a list of possible problem points
+ ++ by looking at the zeros of the denominator of the function \spad{f}
+ ++ if it can be retracted to \axiomType{Polynomial(DoubleFloat)}.
+ zerosOf:(EDF,List Symbol,SOCDF) -> SDF
+ ++ zerosOf(e,vars,range) returns a list of points
+ ++ (\axiomType{Doublefloat}) at which a NAG fortran version of \spad{e}
+ ++ will most likely produce an error.
+ singularitiesOf: (EDF,List Symbol,SOCDF) -> SDF
+ ++ singularitiesOf(e,vars,range) returns a list of points
+ ++ (\axiomType{Doublefloat}) at which a NAG fortran
+ ++ version of \spad{e} will most likely produce
+ ++ an error. This includes those points which evaluate to 0/0.
+ singularitiesOf: (Vector EDF,List Symbol,SOCDF) -> SDF
+ ++ singularitiesOf(v,vars,range) returns a list of points
+ ++ (\axiomType{Doublefloat}) at which a NAG fortran
+ ++ version of \spad{v} will most likely produce
+ ++ an error. This includes those points which evaluate to 0/0.
+ polynomialZeros:(PFI,Symbol,SOCDF) -> LDF
+ ++ polynomialZeros(fn,var,range) calculates the real zeros of the
+ ++ polynomial which are contained in the given interval. It returns
+ ++ a list of points (\axiomType{Doublefloat}) for which the univariate
+ ++ polynomial \spad{fn} is zero.
+ df2st:DF -> String
+ ++ df2st(n) coerces a \axiomType{DoubleFloat} to \axiomType{String}
+ ldf2lst:LDF -> List String
+ ++ ldf2lst(ln) coerces a List of \axiomType{DoubleFloat} to
+ ++ \axiomType{List}(\axiomType{String})
+ sdf2lst:SDF -> List String
+ ++ sdf2lst(ln) coerces a Stream of \axiomType{DoubleFloat} to
+ ++ \axiomType{List}(\axiomType{String})
+
+ I ==> ExpertSystemToolsPackage add
+
+ import ExpertSystemToolsPackage
+
+ functionIsPolynomial?(args:NIA):Boolean ==
+ -- tests whether the function can be retracted to a polynomial
+ (retractIfCan(args.fn)@Union(PDF,"failed"))$EDF case PDF
+
+ isPolynomial?(f:EDF):Boolean ==
+ -- tests whether the function can be retracted to a polynomial
+ (retractIfCan(f)@Union(PDF,"failed"))$EDF case PDF
+
+ isConstant?(f:EDF):Boolean ==
+ -- tests whether the function can be retracted to a constant (DoubleFloat)
+ (retractIfCan(f)@Union(DF,"failed"))$EDF case DF
+
+ denominatorIsPolynomial?(args:NIA):Boolean ==
+ -- tests if the denominator can be retracted to polynomial
+ a:= copy args
+ a.fn:=denominator(args.fn)
+ (functionIsPolynomial?(a))@Boolean
+
+ denIsPolynomial?(f:EDF):Boolean ==
+ -- tests if the denominator can be retracted to polynomial
+ (isPolynomial?(denominator f))@Boolean
+
+ listInRange(l:LDF,range:SOCDF):LDF ==
+ -- returns a list with only those elements internal to the range range
+ [t for t in l | in?(t,range)]
+
+ loseUntil(l:SDF,a:DF):SDF ==
+ empty?(l)$SDF => l
+ f := first(l)$SDF
+ (abs(f) <= abs(a)) => loseUntil(rest(l)$SDF,a)
+ l
+
+ retainUntil(l:SDF,a:DF,b:DF,flag:Boolean):SDF ==
+ empty?(l)$SDF => l
+ f := first(l)$SDF
+ (in?(f)$ExpertSystemContinuityPackage1(a,b)) =>
+ concat(f,retainUntil(rest(l),a,b,false))
+ flag => empty()$SDF
+ retainUntil(rest(l),a,b,true)
+
+ streamInRange(l:SDF,range:SOCDF):SDF ==
+ -- returns a stream with only those elements internal to the range range
+ a := getlo(range := dfRange(range))
+ b := gethi(range)
+ explicitlyFinite?(l) =>
+ select(in?$ExpertSystemContinuityPackage1(a,b),l)$SDF
+ negative?(a*b) => retainUntil(l,a,b,false)
+ negative?(a) =>
+ l := loseUntil(l,b)
+ retainUntil(l,a,b,false)
+ l := loseUntil(l,a)
+ retainUntil(l,a,b,false)
+
+ getStream(n:Symbol,s:String):SDF ==
+ import RS
+ entry?(n,bfKeys()$BasicFunctions)$(List(Symbol)) =>
+ c := bfEntry(n)$BasicFunctions
+ (s = "zeros")@Boolean => c.zeros
+ (s = "singularities")@Boolean => c.singularities
+ (s = "ones")@Boolean => c.ones
+ empty()$SDF
+
+ polynomialZeros(fn:PFI,var:Symbol,range:SOCDF):LDF ==
+ up := unmakeSUP(univariate(fn)$PFI)$UP(var,FI)
+ range := dfRange(range)
+ r:Record(left:FI,right:FI) := [df2fi(getlo(range)), df2fi(gethi(range))]
+ ans:List(Record(left:FI,right:FI)) :=
+ realZeros(up,r,1/1000000000000000000)$RealZeroPackageQ(UP(var,FI))
+ listInRange(dflist(ans),range)
+
+ functionIsFracPolynomial?(args:NIA):Boolean ==
+ -- tests whether the function can be retracted to a fraction
+ -- where both numerator and denominator are polynomial
+ (retractIfCan(args.fn)@Union(FPDF,"failed"))$EDF case FPDF
+
+ problemPoints(f:EDF,var:Symbol,range:SOCDF):LDF ==
+ (denIsPolynomial?(f))@Boolean =>
+ c := retract(edf2efi(denominator(f)))@PFI
+ polynomialZeros(c,var,range)
+ empty()$LDF
+
+ zerosOf(e:EDF,vars:List Symbol,range:SOCDF):SDF ==
+ (u := isQuotient(e)) case EDF =>
+ singularitiesOf(u,vars,range)
+ k := kernels(e)$EDF
+ ((nk := # k) = 0)@Boolean => empty()$SDF -- constant found.
+ (nk = 1)@Boolean => -- single expression found.
+ ker := first(k)$LKEDF
+ n := name(operator(ker)$KEDF)$BO
+ entry?(n,vars) => -- polynomial found.
+ c := retract(edf2efi(e))@PFI
+ coerce(polynomialZeros(c,n,range))$SDF
+ a := first(argument(ker)$KEDF)$LEDF
+ (not (n = log :: Symbol)@Boolean) and ((w := isPlus a) case LEDF) =>
+ var:Symbol := first(variables(a))
+ c:EDF := w.2
+ c1:EDF := w.1
+-- entry?(c1,[b::EDF for b in vars]) and (one?(# vars)) =>
+ entry?(c1,[b::EDF for b in vars]) and ((# vars) = 1) =>
+ c2:DF := edf2df c
+ c3 := c2 :: OCDF
+ varEdf := var :: EDF
+ varEqn := equation(varEdf,c1-c)$EEDF
+ range2 := (lo(range)+c3)..(hi(range)+c3)
+ s := zerosOf(subst(e,varEqn)$EDF,vars,range2)
+ st := map(#1-c2,s)$StreamFunctions2(DF,DF)
+ streamInRange(st,range)
+ zerosOf(a,vars,range)
+ (t := isPlus(e)$EDF) case LEDF => -- constant + expression
+ # t > 2 => empty()$SDF
+ entry?(a,[b::EDF for b in vars]) => -- finds entries like sqrt(x)
+ st := getStream(n,"ones")
+ o := edf2df(second(t)$LEDF)
+-- one?(o) or one?(-o) => -- is it like (f(x) -/+ 1)
+ (o = 1) or (-o = 1) => -- is it like (f(x) -/+ 1)
+ st := map(-#1/o,st)$StreamFunctions2(DF,DF)
+ streamInRange(st,range)
+ empty()$SDF
+ empty()$SDF
+ entry?(a,[b::EDF for b in vars]) => -- finds entries like sqrt(x)
+ st := getStream(n,"zeros")
+ streamInRange(st,range)
+ (n = tan :: Symbol)@Boolean =>
+ concat([zerosOf(a,vars,range),singularitiesOf(a,vars,range)])
+ (n = sin :: Symbol)@Boolean =>
+ concat([zerosOf(a,vars,range),singularitiesOf(a,vars,range)])
+ empty()$SDF
+ (t := isPlus(e)$EDF) case LEDF => empty()$SDF -- INCOMPLETE!!!
+ (v := isTimes(e)$EDF) case LEDF =>
+ concat([zerosOf(u,vars,range) for u in v])
+ empty()$SDF
+
+ singularitiesOf(e:EDF,vars:List Symbol,range:SOCDF):SDF ==
+ (u := isQuotient(e)) case EDF =>
+ zerosOf(u,vars,range)
+ (t := isPlus e) case LEDF =>
+ concat([singularitiesOf(u,vars,range) for u in t])
+ (v := isTimes e) case LEDF =>
+ concat([singularitiesOf(u,vars,range) for u in v])
+ (k := mainKernel e) case KEDF =>
+ n := name(operator k)
+ entry?(n,vars) => coerce(problemPoints(e,n,range))$SDF
+ a:EDF := (argument k).1
+ (not (n = log :: Symbol)@Boolean) and ((w := isPlus a) case LEDF) =>
+ var:Symbol := first(variables(a))
+ c:EDF := w.2
+ c1:EDF := w.1
+-- entry?(c1,[b::EDF for b in vars]) and (one?(# vars)) =>
+ entry?(c1,[b::EDF for b in vars]) and ((# vars) = 1) =>
+ c2:DF := edf2df c
+ c3 := c2 :: OCDF
+ varEdf := var :: EDF
+ varEqn := equation(varEdf,c1-c)$EEDF
+ range2 := (lo(range)+c3)..(hi(range)+c3)
+ s := singularitiesOf(subst(e,varEqn)$EDF,vars,range2)
+ st := map(#1-c2,s)$StreamFunctions2(DF,DF)
+ streamInRange(st,range)
+ singularitiesOf(a,vars,range)
+ entry?(a,[b::EDF for b in vars]) =>
+ st := getStream(n,"singularities")
+ streamInRange(st,range)
+ (n = log :: Symbol)@Boolean =>
+ concat([zerosOf(a,vars,range),singularitiesOf(a,vars,range)])
+ singularitiesOf(a,vars,range)
+ empty()$SDF
+
+ singularitiesOf(v:VEDF,vars:List Symbol,range:SOCDF):SDF ==
+ ls := [singularitiesOf(u,vars,range) for u in entries(v)$VEDF]
+ concat(ls)$SDF
+
+@
+\section{package ESCONT1 ExpertSystemContinuityPackage1}
+<<package ESCONT1 ExpertSystemContinuityPackage1>>=
+)abbrev package ESCONT1 ExpertSystemContinuityPackage1
+++ Author: Brian Dupee
+++ Date Created: May 1994
+++ Date Last Updated: June 1995
+++ Basic Operations: problemPoints, singularitiesOf, zerosOf
+++ Related Constructors:
+++ Description:
+++ ExpertSystemContinuityPackage1 exports a function to check range inclusion
+
+ExpertSystemContinuityPackage1(A:DF,B:DF): E == I where
+ EF2 ==> ExpressionFunctions2
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ PFI ==> Polynomial Fraction Integer
+ DF ==> DoubleFloat
+ LDF ==> List DoubleFloat
+ EDF ==> Expression DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ SDF ==> Stream DoubleFloat
+ SS ==> Stream String
+ EEDF ==> Equation Expression DoubleFloat
+ LEDF ==> List Expression DoubleFloat
+ KEDF ==> Kernel Expression DoubleFloat
+ LKEDF ==> List Kernel Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ FPDF ==> Fraction Polynomial DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ UP ==> UnivariatePolynomial
+ BO ==> BasicOperator
+ RS ==> Record(zeros: SDF,ones: SDF,singularities: SDF)
+
+ E ==> with
+
+ in?:DF -> Boolean
+ ++ in?(p) tests whether point p is internal to the range [\spad{A..B}]
+
+ I ==> add
+
+ in?(p:DF):Boolean ==
+ a:Boolean := (p < B)$DF
+ b:Boolean := (A < p)$DF
+ (a and b)@Boolean
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ESCONT ExpertSystemContinuityPackage>>
+<<package ESCONT1 ExpertSystemContinuityPackage1>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/contfrac.spad.pamphlet b/src/algebra/contfrac.spad.pamphlet
new file mode 100644
index 00000000..2261d76c
--- /dev/null
+++ b/src/algebra/contfrac.spad.pamphlet
@@ -0,0 +1,425 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra contfrac.spad}
+\author{Stephen M. Watt, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain CONTFRAC ContinuedFraction}
+<<domain CONTFRAC ContinuedFraction>>=
+)abbrev domain CONTFRAC ContinuedFraction
+++ Author: Stephen M. Watt
+++ Date Created: January 1987
+++ Change History:
+++ 11 April 1990
+++ 7 October 1991 -- SMW: Treat whole part specially. Added comments.
+++ Basic Operations:
+++ (Field), (Algebra),
+++ approximants, complete, continuedFraction, convergents, denominators,
+++ extend, numerators, partialDenominators, partialNumerators,
+++ partialQuotients, reducedContinuedFraction, reducedForm, wholePart
+++ Related Constructors:
+++ Also See: Fraction
+++ AMS Classifications: 11A55 11J70 11K50 11Y65 30B70 40A15
+++ Keywords: continued fraction, convergent
+++ References:
+++ Description: \spadtype{ContinuedFraction} implements general
+++ continued fractions. This version is not restricted to simple,
+++ finite fractions and uses the \spadtype{Stream} as a
+++ representation. The arithmetic functions assume that the
+++ approximants alternate below/above the convergence point.
+++ This is enforced by ensuring the partial numerators and partial
+++ denominators are greater than 0 in the Euclidean domain view of \spad{R}
+++ (i.e. \spad{sizeLess?(0, x)}).
+
+
+ContinuedFraction(R): Exports == Implementation where
+ R : EuclideanDomain
+ Q ==> Fraction R
+ MT ==> MoebiusTransform Q
+ OUT ==> OutputForm
+
+ Exports ==> Join(Algebra R,Algebra Q,Field) with
+ continuedFraction: Q -> %
+ ++ continuedFraction(r) converts the fraction \spadvar{r} with
+ ++ components of type \spad{R} to a continued fraction over
+ ++ \spad{R}.
+
+ continuedFraction: (R, Stream R, Stream R) -> %
+ ++ continuedFraction(b0,a,b) constructs a continued fraction in
+ ++ the following way: if \spad{a = [a1,a2,...]} and \spad{b =
+ ++ [b1,b2,...]} then the result is the continued fraction
+ ++ \spad{b0 + a1/(b1 + a2/(b2 + ...))}.
+
+ reducedContinuedFraction: (R, Stream R) -> %
+ ++ reducedContinuedFraction(b0,b) constructs a continued
+ ++ fraction in the following way: if \spad{b = [b1,b2,...]}
+ ++ then the result is the continued fraction \spad{b0 + 1/(b1 +
+ ++ 1/(b2 + ...))}. That is, the result is the same as
+ ++ \spad{continuedFraction(b0,[1,1,1,...],[b1,b2,b3,...])}.
+
+ partialNumerators: % -> Stream R
+ ++ partialNumerators(x) extracts the numerators in \spadvar{x}.
+ ++ That is, if \spad{x = continuedFraction(b0, [a1,a2,a3,...],
+ ++ [b1,b2,b3,...])}, then \spad{partialNumerators(x) =
+ ++ [a1,a2,a3,...]}.
+
+ partialDenominators: % -> Stream R
+ ++ partialDenominators(x) extracts the denominators in
+ ++ \spadvar{x}. That is, if \spad{x = continuedFraction(b0,
+ ++ [a1,a2,a3,...], [b1,b2,b3,...])}, then
+ ++ \spad{partialDenominators(x) = [b1,b2,b3,...]}.
+
+ partialQuotients: % -> Stream R
+ ++ partialQuotients(x) extracts the partial quotients in
+ ++ \spadvar{x}. That is, if \spad{x = continuedFraction(b0,
+ ++ [a1,a2,a3,...], [b1,b2,b3,...])}, then
+ ++ \spad{partialQuotients(x) = [b0,b1,b2,b3,...]}.
+
+ wholePart: % -> R
+ ++ wholePart(x) extracts the whole part of \spadvar{x}. That
+ ++ is, if \spad{x = continuedFraction(b0, [a1,a2,a3,...],
+ ++ [b1,b2,b3,...])}, then \spad{wholePart(x) = b0}.
+
+ reducedForm: % -> %
+ ++ reducedForm(x) puts the continued fraction \spadvar{x} in
+ ++ reduced form, i.e. the function returns an equivalent
+ ++ continued fraction of the form
+ ++ \spad{continuedFraction(b0,[1,1,1,...],[b1,b2,b3,...])}.
+
+ approximants: % -> Stream Q
+ ++ approximants(x) returns the stream of approximants of the
+ ++ continued fraction \spadvar{x}. If the continued fraction is
+ ++ finite, then the stream will be infinite and periodic with
+ ++ period 1.
+
+ convergents: % -> Stream Q
+ ++ convergents(x) returns the stream of the convergents of the
+ ++ continued fraction \spadvar{x}. If the continued fraction is
+ ++ finite, then the stream will be finite.
+
+ numerators: % -> Stream R
+ ++ numerators(x) returns the stream of numerators of the
+ ++ approximants of the continued fraction \spadvar{x}. If the
+ ++ continued fraction is finite, then the stream will be finite.
+
+ denominators: % -> Stream R
+ ++ denominators(x) returns the stream of denominators of the
+ ++ approximants of the continued fraction \spadvar{x}. If the
+ ++ continued fraction is finite, then the stream will be finite.
+
+ extend: (%,Integer) -> %
+ ++ extend(x,n) causes the first \spadvar{n} entries in the
+ ++ continued fraction \spadvar{x} to be computed. Normally
+ ++ entries are only computed as needed.
+
+ complete: % -> %
+ ++ complete(x) causes all entries in \spadvar{x} to be computed.
+ ++ Normally entries are only computed as needed. If \spadvar{x}
+ ++ is an infinite continued fraction, a user-initiated interrupt is
+ ++ necessary to stop the computation.
+
+ Implementation ==> add
+
+ -- isOrdered ==> R is Integer
+ isOrdered ==> R has OrderedRing and R has multiplicativeValuation
+ canReduce? ==> isOrdered or R has additiveValuation
+
+ Rec ==> Record(num: R, den: R)
+ Str ==> Stream Rec
+ Rep := Record(value: Record(whole: R, fract: Str), reduced?: Boolean)
+
+ import Str
+
+ genFromSequence: Stream Q -> %
+ genReducedForm: (Q, Stream Q, MT) -> Stream Rec
+ genFractionA: (Stream R,Stream R) -> Stream Rec
+ genFractionB: (Stream R,Stream R) -> Stream Rec
+ genNumDen: (R,R, Stream Rec) -> Stream R
+
+ genApproximants: (R,R,R,R,Stream Rec) -> Stream Q
+ genConvergents: (R,R,R,R,Stream Rec) -> Stream Q
+ iGenApproximants: (R,R,R,R,Stream Rec) -> Stream Q
+ iGenConvergents: (R,R,R,R,Stream Rec) -> Stream Q
+
+ reducedForm c ==
+ c.reduced? => c
+ explicitlyFinite? c.value.fract =>
+ continuedFraction last complete convergents c
+ canReduce? => genFromSequence approximants c
+ error "Reduced form not defined for this continued fraction."
+
+ eucWhole(a: Q): R == numer a quo denom a
+
+ eucWhole0(a: Q): R ==
+ isOrdered =>
+ n := numer a
+ d := denom a
+ q := n quo d
+ r := n - q*d
+ if r < 0 then q := q - 1
+ q
+ eucWhole a
+
+ x = y ==
+ x := reducedForm x
+ y := reducedForm y
+
+ x.value.whole ^= y.value.whole => false
+
+ xl := x.value.fract; yl := y.value.fract
+
+ while not empty? xl and not empty? yl repeat
+ frst.xl.den ^= frst.yl.den => return false
+ xl := rst xl; yl := rst yl
+ empty? xl and empty? yl
+
+ continuedFraction q == q :: %
+
+ if isOrdered then
+ continuedFraction(wh,nums,dens) == [[wh,genFractionA(nums,dens)],false]
+
+ genFractionA(nums,dens) ==
+ empty? nums or empty? dens => empty()
+ n := frst nums
+ d := frst dens
+ n < 0 => error "Numerators must be greater than 0."
+ d < 0 => error "Denominators must be greater than 0."
+ concat([n,d]$Rec, delay genFractionA(rst nums,rst dens))
+ else
+ continuedFraction(wh,nums,dens) == [[wh,genFractionB(nums,dens)],false]
+
+ genFractionB(nums,dens) ==
+ empty? nums or empty? dens => empty()
+ n := frst nums
+ d := frst dens
+ concat([n,d]$Rec, delay genFractionB(rst nums,rst dens))
+
+ reducedContinuedFraction(wh,dens) ==
+ continuedFraction(wh, repeating [1], dens)
+
+ coerce(n:Integer):% == [[n::R,empty()], true]
+ coerce(r:R):% == [[r, empty()], true]
+
+ coerce(a: Q): % ==
+ wh := eucWhole0 a
+ fr := a - wh::Q
+ zero? fr => [[wh, empty()], true]
+
+ l : List Rec := empty()
+ n := numer fr
+ d := denom fr
+ while not zero? d repeat
+ qr := divide(n,d)
+ l := concat([1,qr.quotient],l)
+ n := d
+ d := qr.remainder
+ [[wh, construct rest reverse_! l], true]
+
+ characteristic() == characteristic()$Q
+
+
+ genFromSequence apps ==
+ lo := first apps; apps := rst apps
+ hi := first apps; apps := rst apps
+ while eucWhole0 lo ^= eucWhole0 hi repeat
+ lo := first apps; apps := rst apps
+ hi := first apps; apps := rst apps
+ wh := eucWhole0 lo
+ [[wh, genReducedForm(wh::Q, apps, moebius(1,0,0,1))], canReduce?]
+
+ genReducedForm(wh0, apps, mt) ==
+ lo: Q := first apps - wh0; apps := rst apps
+ hi: Q := first apps - wh0; apps := rst apps
+ lo = hi and zero? eval(mt, lo) => empty()
+ mt := recip mt
+ wlo := eucWhole eval(mt, lo)
+ whi := eucWhole eval(mt, hi)
+ while wlo ^= whi repeat
+ wlo := eucWhole eval(mt, first apps - wh0); apps := rst apps
+ whi := eucWhole eval(mt, first apps - wh0); apps := rst apps
+ concat([1,wlo], delay genReducedForm(wh0, apps, shift(mt, -wlo::Q)))
+
+ wholePart c == c.value.whole
+ partialNumerators c == map(#1.num, c.value.fract)$StreamFunctions2(Rec,R)
+ partialDenominators c == map(#1.den, c.value.fract)$StreamFunctions2(Rec,R)
+ partialQuotients c == concat(c.value.whole, partialDenominators c)
+
+ approximants c ==
+ empty? c.value.fract => repeating [c.value.whole::Q]
+ genApproximants(1,0,c.value.whole,1,c.value.fract)
+ convergents c ==
+ empty? c.value.fract => concat(c.value.whole::Q, empty())
+ genConvergents (1,0,c.value.whole,1,c.value.fract)
+ numerators c ==
+ empty? c.value.fract => concat(c.value.whole, empty())
+ genNumDen(1,c.value.whole,c.value.fract)
+ denominators c ==
+ genNumDen(0,1,c.value.fract)
+
+ extend(x,n) == (extend(x.value.fract,n); x)
+ complete(x) == (complete(x.value.fract); x)
+
+ iGenApproximants(pm2,qm2,pm1,qm1,fr) == delay
+ nd := frst fr
+ pm := nd.num*pm2 + nd.den*pm1
+ qm := nd.num*qm2 + nd.den*qm1
+ genApproximants(pm1,qm1,pm,qm,rst fr)
+
+ genApproximants(pm2,qm2,pm1,qm1,fr) ==
+ empty? fr => repeating [pm1/qm1]
+ concat(pm1/qm1,iGenApproximants(pm2,qm2,pm1,qm1,fr))
+
+ iGenConvergents(pm2,qm2,pm1,qm1,fr) == delay
+ nd := frst fr
+ pm := nd.num*pm2 + nd.den*pm1
+ qm := nd.num*qm2 + nd.den*qm1
+ genConvergents(pm1,qm1,pm,qm,rst fr)
+
+ genConvergents(pm2,qm2,pm1,qm1,fr) ==
+ empty? fr => concat(pm1/qm1, empty())
+ concat(pm1/qm1,iGenConvergents(pm2,qm2,pm1,qm1,fr))
+
+ genNumDen(m2,m1,fr) ==
+ empty? fr => concat(m1,empty())
+ concat(m1,delay genNumDen(m1,m2*frst(fr).num + m1*frst(fr).den,rst fr))
+
+ gen ==> genFromSequence
+ apx ==> approximants
+
+ c, d: %
+ a: R
+ q: Q
+ n: Integer
+
+ 0 == (0$R) :: %
+ 1 == (1$R) :: %
+
+ c + d == genFromSequence map(#1 + #2, apx c, apx d)
+ c - d == genFromSequence map(#1 - #2, apx c, rest apx d)
+ - c == genFromSequence map( - #1, rest apx c)
+ c * d == genFromSequence map(#1 * #2, apx c, apx d)
+ a * d == genFromSequence map( a * #1, apx d)
+ q * d == genFromSequence map( q * #1, apx d)
+ n * d == genFromSequence map( n * #1, apx d)
+ c / d == genFromSequence map(#1 / #2, apx c, rest apx d)
+ recip c ==(c = 0 => "failed";
+ genFromSequence map( 1 / #1, rest apx c))
+
+ showAll?: () -> Boolean
+ showAll?() ==
+ NULL(_$streamsShowAll$Lisp)$Lisp => false
+ true
+
+ zagRec(t:Rec):OUT == zag(t.num :: OUT,t.den :: OUT)
+
+ coerce(c:%): OUT ==
+ wh := c.value.whole
+ fr := c.value.fract
+ empty? fr => wh :: OUT
+ count : NonNegativeInteger := _$streamCount$Lisp
+ l : List OUT := empty()
+ for n in 1..count while not empty? fr repeat
+ l := concat(zagRec frst fr,l)
+ fr := rst fr
+ if showAll?() then
+ for n in (count + 1).. while explicitEntries? fr repeat
+ l := concat(zagRec frst fr,l)
+ fr := rst fr
+ if not explicitlyEmpty? fr then l := concat("..." :: OUT,l)
+ l := reverse_! l
+ e := reduce("+",l)
+ zero? wh => e
+ (wh :: OUT) + e
+
+@
+\section{package NCNTFRAC NumericContinuedFraction}
+<<package NCNTFRAC NumericContinuedFraction>>=
+)abbrev package NCNTFRAC NumericContinuedFraction
+++ Author: Clifton J. Williamson
+++ Date Created: 12 April 1990
+++ Change History:
+++ Basic Operations: continuedFraction
+++ Related Constructors: ContinuedFraction, Float
+++ Also See: Fraction
+++ AMS Classifications: 11J70 11A55 11K50 11Y65 30B70 40A15
+++ Keywords: continued fraction
+++ References:
+++ Description: \spadtype{NumericContinuedFraction} provides functions
+++ for converting floating point numbers to continued fractions.
+
+NumericContinuedFraction(F): Exports == Implementation where
+ F : FloatingPointSystem
+ CFC ==> ContinuedFraction Integer
+ I ==> Integer
+ ST ==> Stream I
+
+ Exports ==> with
+ continuedFraction: F -> CFC
+ ++ continuedFraction(f) converts the floating point number
+ ++ \spad{f} to a reduced continued fraction.
+
+ Implementation ==> add
+
+ cfc: F -> ST
+ cfc(a) == delay
+ aa := wholePart a
+ zero?(b := a - (aa :: F)) => concat(aa,empty()$ST)
+ concat(aa,cfc inv b)
+
+ continuedFraction a ==
+ aa := wholePart a
+ zero?(b := a - (aa :: F)) =>
+ reducedContinuedFraction(aa,empty()$ST)
+ if negative? b then (aa := aa - 1; b := b + 1)
+ reducedContinuedFraction(aa,cfc inv b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain CONTFRAC ContinuedFraction>>
+<<package NCNTFRAC NumericContinuedFraction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/coordsys.spad.pamphlet b/src/algebra/coordsys.spad.pamphlet
new file mode 100644
index 00000000..1dc91964
--- /dev/null
+++ b/src/algebra/coordsys.spad.pamphlet
@@ -0,0 +1,240 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra coordsys.spad}
+\author{Jim Wen, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package COORDSYS CoordinateSystems}
+<<package COORDSYS CoordinateSystems>>=
+)abbrev package COORDSYS CoordinateSystems
+++ Author: Jim Wen
+++ Date Created: 12 March 1990
+++ Date Last Updated: 19 June 1990, Clifton J. Williamson
+++ Basic Operations: cartesian, polar, cylindrical, spherical, parabolic, elliptic,
+++ parabolicCylindrical, paraboloidal, ellipticCylindrical, prolateSpheroidal,
+++ oblateSpheroidal, bipolar, bipolarCylindrical, toroidal, conical
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: CoordinateSystems provides coordinate transformation functions
+++ for plotting. Functions in this package return conversion functions
+++ which take points expressed in other coordinate systems and return points
+++ with the corresponding Cartesian coordinates.
+
+CoordinateSystems(R): Exports == Implementation where
+
+ R : Join(Field,TranscendentalFunctionCategory,RadicalCategory)
+ Pt ==> Point R
+
+ Exports ==> with
+ cartesian : Pt -> Pt
+ ++ cartesian(pt) returns the Cartesian coordinates of point pt.
+ polar: Pt -> Pt
+ ++ polar(pt) transforms pt from polar coordinates to Cartesian
+ ++ coordinates: the function produced will map the point \spad{(r,theta)}
+ ++ to \spad{x = r * cos(theta)} , \spad{y = r * sin(theta)}.
+ cylindrical: Pt -> Pt
+ ++ cylindrical(pt) transforms pt from polar coordinates to Cartesian
+ ++ coordinates: the function produced will map the point \spad{(r,theta,z)}
+ ++ to \spad{x = r * cos(theta)}, \spad{y = r * sin(theta)}, \spad{z}.
+ spherical: Pt -> Pt
+ ++ spherical(pt) transforms pt from spherical coordinates to Cartesian
+ ++ coordinates: the function produced will map the point \spad{(r,theta,phi)}
+ ++ to \spad{x = r*sin(phi)*cos(theta)}, \spad{y = r*sin(phi)*sin(theta)},
+ ++ \spad{z = r*cos(phi)}.
+ parabolic: Pt -> Pt
+ ++ parabolic(pt) transforms pt from parabolic coordinates to Cartesian
+ ++ coordinates: the function produced will map the point \spad{(u,v)} to
+ ++ \spad{x = 1/2*(u**2 - v**2)}, \spad{y = u*v}.
+ parabolicCylindrical: Pt -> Pt
+ ++ parabolicCylindrical(pt) transforms pt from parabolic cylindrical
+ ++ coordinates to Cartesian coordinates: the function produced will
+ ++ map the point \spad{(u,v,z)} to \spad{x = 1/2*(u**2 - v**2)},
+ ++ \spad{y = u*v}, \spad{z}.
+ paraboloidal: Pt -> Pt
+ ++ paraboloidal(pt) transforms pt from paraboloidal coordinates to
+ ++ Cartesian coordinates: the function produced will map the point
+ ++ \spad{(u,v,phi)} to \spad{x = u*v*cos(phi)}, \spad{y = u*v*sin(phi)},
+ ++ \spad{z = 1/2 * (u**2 - v**2)}.
+ elliptic: R -> (Pt -> Pt)
+ ++ elliptic(a) transforms from elliptic coordinates to Cartesian
+ ++ coordinates: \spad{elliptic(a)} is a function which will map the
+ ++ point \spad{(u,v)} to \spad{x = a*cosh(u)*cos(v)}, \spad{y = a*sinh(u)*sin(v)}.
+ ellipticCylindrical: R -> (Pt -> Pt)
+ ++ ellipticCylindrical(a) transforms from elliptic cylindrical coordinates
+ ++ to Cartesian coordinates: \spad{ellipticCylindrical(a)} is a function
+ ++ which will map the point \spad{(u,v,z)} to \spad{x = a*cosh(u)*cos(v)},
+ ++ \spad{y = a*sinh(u)*sin(v)}, \spad{z}.
+ prolateSpheroidal: R -> (Pt -> Pt)
+ ++ prolateSpheroidal(a) transforms from prolate spheroidal coordinates to
+ ++ Cartesian coordinates: \spad{prolateSpheroidal(a)} is a function
+ ++ which will map the point \spad{(xi,eta,phi)} to
+ ++ \spad{x = a*sinh(xi)*sin(eta)*cos(phi)}, \spad{y = a*sinh(xi)*sin(eta)*sin(phi)},
+ ++ \spad{z = a*cosh(xi)*cos(eta)}.
+ oblateSpheroidal: R -> (Pt -> Pt)
+ ++ oblateSpheroidal(a) transforms from oblate spheroidal coordinates to
+ ++ Cartesian coordinates: \spad{oblateSpheroidal(a)} is a function which
+ ++ will map the point \spad{(xi,eta,phi)} to \spad{x = a*sinh(xi)*sin(eta)*cos(phi)},
+ ++ \spad{y = a*sinh(xi)*sin(eta)*sin(phi)}, \spad{z = a*cosh(xi)*cos(eta)}.
+ bipolar: R -> (Pt -> Pt)
+ ++ bipolar(a) transforms from bipolar coordinates to Cartesian coordinates:
+ ++ \spad{bipolar(a)} is a function which will map the point \spad{(u,v)} to
+ ++ \spad{x = a*sinh(v)/(cosh(v)-cos(u))}, \spad{y = a*sin(u)/(cosh(v)-cos(u))}.
+ bipolarCylindrical: R -> (Pt -> Pt)
+ ++ bipolarCylindrical(a) transforms from bipolar cylindrical coordinates
+ ++ to Cartesian coordinates: \spad{bipolarCylindrical(a)} is a function which
+ ++ will map the point \spad{(u,v,z)} to \spad{x = a*sinh(v)/(cosh(v)-cos(u))},
+ ++ \spad{y = a*sin(u)/(cosh(v)-cos(u))}, \spad{z}.
+ toroidal: R -> (Pt -> Pt)
+ ++ toroidal(a) transforms from toroidal coordinates to Cartesian
+ ++ coordinates: \spad{toroidal(a)} is a function which will map the point
+ ++ \spad{(u,v,phi)} to \spad{x = a*sinh(v)*cos(phi)/(cosh(v)-cos(u))},
+ ++ \spad{y = a*sinh(v)*sin(phi)/(cosh(v)-cos(u))}, \spad{z = a*sin(u)/(cosh(v)-cos(u))}.
+ conical: (R,R) -> (Pt -> Pt)
+ ++ conical(a,b) transforms from conical coordinates to Cartesian coordinates:
+ ++ \spad{conical(a,b)} is a function which will map the point \spad{(lambda,mu,nu)} to
+ ++ \spad{x = lambda*mu*nu/(a*b)},
+ ++ \spad{y = lambda/a*sqrt((mu**2-a**2)*(nu**2-a**2)/(a**2-b**2))},
+ ++ \spad{z = lambda/b*sqrt((mu**2-b**2)*(nu**2-b**2)/(b**2-a**2))}.
+
+ Implementation ==> add
+
+ cartesian pt ==
+ -- we just want to interpret the cartesian coordinates
+ -- from the first N elements of the point - so the
+ -- identity function will do
+ pt
+
+ polar pt0 ==
+ pt := copy pt0
+ r := elt(pt0,1); theta := elt(pt0,2)
+ pt.1 := r * cos(theta); pt.2 := r * sin(theta)
+ pt
+
+ cylindrical pt0 == polar pt0
+ -- apply polar transformation to first 2 coordinates
+
+ spherical pt0 ==
+ pt := copy pt0
+ r := elt(pt0,1); theta := elt(pt0,2); phi := elt(pt0,3)
+ pt.1 := r * sin(phi) * cos(theta); pt.2 := r * sin(phi) * sin(theta)
+ pt.3 := r * cos(phi)
+ pt
+
+ parabolic pt0 ==
+ pt := copy pt0
+ u := elt(pt0,1); v := elt(pt0,2)
+ pt.1 := (u*u - v*v)/(2::R) ; pt.2 := u*v
+ pt
+
+ parabolicCylindrical pt0 == parabolic pt0
+ -- apply parabolic transformation to first 2 coordinates
+
+ paraboloidal pt0 ==
+ pt := copy pt0
+ u := elt(pt0,1); v := elt(pt0,2); phi := elt(pt0,3)
+ pt.1 := u*v*cos(phi); pt.2 := u*v*sin(phi); pt.3 := (u*u - v*v)/(2::R)
+ pt
+
+ elliptic a ==
+ pt := copy(#1)
+ u := elt(#1,1); v := elt(#1,2)
+ pt.1 := a*cosh(u)*cos(v); pt.2 := a*sinh(u)*sin(v)
+ pt
+
+ ellipticCylindrical a == elliptic a
+ -- apply elliptic transformation to first 2 coordinates
+
+ prolateSpheroidal a ==
+ pt := copy(#1)
+ xi := elt(#1,1); eta := elt(#1,2); phi := elt(#1,3)
+ pt.1 := a*sinh(xi)*sin(eta)*cos(phi)
+ pt.2 := a*sinh(xi)*sin(eta)*sin(phi)
+ pt.3 := a*cosh(xi)*cos(eta)
+ pt
+
+ oblateSpheroidal a ==
+ pt := copy(#1)
+ xi := elt(#1,1); eta := elt(#1,2); phi := elt(#1,3)
+ pt.1 := a*sinh(xi)*sin(eta)*cos(phi)
+ pt.2 := a*cosh(xi)*cos(eta)*sin(phi)
+ pt.3 := a*sinh(xi)*sin(eta)
+ pt
+
+ bipolar a ==
+ pt := copy(#1)
+ u := elt(#1,1); v := elt(#1,2)
+ pt.1 := a*sinh(v)/(cosh(v)-cos(u))
+ pt.2 := a*sin(u)/(cosh(v)-cos(u))
+ pt
+
+ bipolarCylindrical a == bipolar a
+ -- apply bipolar transformation to first 2 coordinates
+
+ toroidal a ==
+ pt := copy(#1)
+ u := elt(#1,1); v := elt(#1,2); phi := elt(#1,3)
+ pt.1 := a*sinh(v)*cos(phi)/(cosh(v)-cos(u))
+ pt.2 := a*sinh(v)*sin(phi)/(cosh(v)-cos(u))
+ pt.3 := a*sin(u)/(cosh(v)-cos(u))
+ pt
+
+ conical(a,b) ==
+ pt := copy(#1)
+ lambda := elt(#1,1); mu := elt(#1,2); nu := elt(#1,3)
+ pt.1 := lambda*mu*nu/(a*b)
+ pt.2 := lambda/a*sqrt((mu**2-a**2)*(nu**2-a**2)/(a**2-b**2))
+ pt.3 := lambda/b*sqrt((mu**2-b**2)*(nu**2-b**2)/(b**2-a**2))
+ pt
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package COORDSYS CoordinateSystems>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/cra.spad.pamphlet b/src/algebra/cra.spad.pamphlet
new file mode 100644
index 00000000..640170d9
--- /dev/null
+++ b/src/algebra/cra.spad.pamphlet
@@ -0,0 +1,131 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra cra.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package CRAPACK CRApackage}
+<<package CRAPACK CRApackage>>=
+)abbrev package CRAPACK CRApackage
+
+++ This package \undocumented{}
+CRApackage(R:EuclideanDomain): Exports == Implementation where
+ Exports == with
+ modTree: (R,List R) -> List R
+ ++ modTree(r,l) \undocumented{}
+ chineseRemainder: (List R, List R) -> R
+ ++ chineseRemainder(lv,lm) returns a value \axiom{v} such that, if
+ ++ x is \axiom{lv.i} modulo \axiom{lm.i} for all \axiom{i}, then
+ ++ x is \axiom{v} modulo \axiom{lm(1)*lm(2)*...*lm(n)}.
+ chineseRemainder: (List List R, List R) -> List R
+ ++ chineseRemainder(llv,lm) returns a list of values, each of which
+ ++ corresponds to the Chinese remainder of the associated element of
+ ++ \axiom{llv} and axiom{lm}. This is more efficient than applying
+ ++ chineseRemainder several times.
+ multiEuclideanTree: (List R, R) -> List R
+ ++ multiEuclideanTree(l,r) \undocumented{}
+ Implementation == add
+
+ BB:=BalancedBinaryTree(R)
+ x:BB
+
+ -- Definition for modular reduction mapping with several moduli
+ modTree(a,lm) ==
+ t := balancedBinaryTree(#lm, 0$R)
+ setleaves_!(t,lm)
+ mapUp_!(t,"*")
+ leaves mapDown_!(t, a, "rem")
+
+ chineseRemainder(lv:List(R), lm:List(R)):R ==
+ #lm ^= #lv => error "lists of moduli and values not of same length"
+ x := balancedBinaryTree(#lm, 0$R)
+ x := setleaves_!(x, lm)
+ mapUp_!(x,"*")
+ y := balancedBinaryTree(#lm, 1$R)
+ y := mapUp_!(copy y,x,#1 * #4 + #2 * #3)
+ (u := extendedEuclidean(value y, value x,1)) case "failed" =>
+ error "moduli not relatively prime"
+ inv := u . coef1
+ linv := modTree(inv, lm)
+ l := [(u*v) rem m for v in lv for u in linv for m in lm]
+ y := setleaves_!(y,l)
+ value(mapUp_!(y, x, #1 * #4 + #2 * #3)) rem value(x)
+
+ chineseRemainder(llv:List List(R), lm:List(R)):List(R) ==
+ x := balancedBinaryTree(#lm, 0$R)
+ x := setleaves_!(x, lm)
+ mapUp_!(x,"*")
+ y := balancedBinaryTree(#lm, 1$R)
+ y := mapUp_!(copy y,x,#1 * #4 + #2 * #3)
+ (u := extendedEuclidean(value y, value x,1)) case "failed" =>
+ error "moduli not relatively prime"
+ inv := u . coef1
+ linv := modTree(inv, lm)
+ retVal:List(R) := []
+ for lv in llv repeat
+ l := [(u3*v) rem m for v in lv for u3 in linv for m in lm]
+ y := setleaves!(y,l)
+ retVal := cons(value(mapUp!(y, x, #1*#4+#2*#3)) rem value(x),retVal)
+ reverse retVal
+
+ extEuclidean: (R, R, R) -> List R
+ extEuclidean(a, b, c) ==
+ u := extendedEuclidean(a, b, c)
+ u case "failed" => error [c, " not spanned by ", a, " and ",b]
+ [u.coef2, u.coef1]
+
+ multiEuclideanTree(fl, rhs) ==
+ x := balancedBinaryTree(#fl, rhs)
+ x := setleaves_!(x, fl)
+ mapUp_!(x,"*")
+ leaves mapDown_!(x, rhs, extEuclidean)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package CRAPACK CRApackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/crfp.spad.pamphlet b/src/algebra/crfp.spad.pamphlet
new file mode 100644
index 00000000..d3bb5b83
--- /dev/null
+++ b/src/algebra/crfp.spad.pamphlet
@@ -0,0 +1,643 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra crfp.spad}
+\author{Johannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package CRFP ComplexRootFindingPackage}
+<<package CRFP ComplexRootFindingPackage>>=
+)abbrev package CRFP ComplexRootFindingPackage
+++ Author: J. Grabmeier
+++ Date Created: 31 January 1991
+++ Date Last Updated: 12 April 1991
+++ Basic Operations: factor, pleskenSplit
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: complex zeros, roots
+++ References: J. Grabmeier: On Plesken's root finding algorithm,
+++ in preparation
+++ A. Schoenhage: The fundamental theorem of algebra in terms of computational
+++ complexity, preliminary report, Univ. Tuebingen, 1982
+++ Description:
+++ \spadtype{ComplexRootFindingPackage} provides functions to
+++ find all roots of a polynomial p over the complex number by
+++ using Plesken's idea to calculate in the polynomial ring
+++ modulo f and employing the Chinese Remainder Theorem.
+++ In this first version, the precision (see \spadfunFrom{digits}{Float})
+++ is not increased when this is necessary to
+++ avoid rounding errors. Hence it is the user's responsibility to
+++ increase the precision if necessary.
+++ Note also, if this package is called with e.g. \spadtype{Fraction Integer},
+++ the precise calculations could require a lot of time.
+++ Also note that evaluating the zeros is not necessarily a good check
+++ whether the result is correct: already evaluation can cause
+++ rounding errors.
+ComplexRootFindingPackage(R, UP): public == private where
+ -- R : Join(Field, OrderedRing, CharacteristicZero)
+ -- Float not in CharacteristicZero !|
+ R : Join(Field, OrderedRing)
+ UP : UnivariatePolynomialCategory Complex R
+
+ C ==> Complex R
+ FR ==> Factored
+ I ==> Integer
+ L ==> List
+ FAE ==> Record(factors : L UP, error : R)
+ NNI ==> NonNegativeInteger
+ OF ==> OutputForm
+ ICF ==> IntegerCombinatoricFunctions(I)
+
+ public ==> with
+ complexZeros : UP -> L C
+ ++ complexZeros(p) tries to determine all complex zeros
+ ++ of the polynomial p with accuracy given by the package
+ ++ constant {\em globalEps} which you may change by
+ ++ {\em setErrorBound}.
+ complexZeros : (UP, R) -> L C
+ ++ complexZeros(p, eps) tries to determine all complex zeros
+ ++ of the polynomial p with accuracy given by {\em eps}.
+ divisorCascade : (UP,UP, Boolean) -> L FAE
+ ++ divisorCascade(p,tp) assumes that degree of polynomial {\em tp}
+ ++ is smaller than degree of polynomial p, both monic.
+ ++ A sequence of divisions are calculated
+ ++ using the remainder, made monic, as divisor
+ ++ for the the next division. The result contains also the error of the
+ ++ factorizations, i.e. the norm of the remainder polynomial.
+ ++ If {\em info} is {\em true}, then information messages are issued.
+ divisorCascade : (UP,UP) -> L FAE
+ ++ divisorCascade(p,tp) assumes that degree of polynomial {\em tp}
+ ++ is smaller than degree of polynomial p, both monic.
+ ++ A sequence of divisions is calculated
+ ++ using the remainder, made monic, as divisor
+ ++ for the the next division. The result contains also the error of the
+ ++ factorizations, i.e. the norm of the remainder polynomial.
+ factor: (UP,R,Boolean) -> FR UP
+ ++ factor(p, eps, info) tries to factor p into linear factors
+ ++ with error atmost {\em eps}. An overall error bound
+ ++ {\em eps0} is determined and iterated tree-like calls
+ ++ to {\em pleskenSplit} are used to get the factorization.
+ ++ If {\em info} is {\em true}, then information messages are given.
+ factor: (UP,R) -> FR UP
+ ++ factor(p, eps) tries to factor p into linear factors
+ ++ with error atmost {\em eps}. An overall error bound
+ ++ {\em eps0} is determined and iterated tree-like calls
+ ++ to {\em pleskenSplit} are used to get the factorization.
+ factor: UP -> FR UP
+ ++ factor(p) tries to factor p into linear factors
+ ++ with error atmost {\em globalEps}, the internal error bound,
+ ++ which can be set by {\em setErrorBound}. An overall error bound
+ ++ {\em eps0} is determined and iterated tree-like calls
+ ++ to {\em pleskenSplit} are used to get the factorization.
+ graeffe : UP -> UP
+ ++ graeffe p determines q such that \spad{q(-z**2) = p(z)*p(-z)}.
+ ++ Note that the roots of q are the squares of the roots of p.
+ norm : UP -> R
+ ++ norm(p) determines sum of absolute values of coefficients
+ ++ Note: this function depends on \spadfunFrom{abs}{Complex}.
+ pleskenSplit: (UP, R, Boolean) -> FR UP
+ ++ pleskenSplit(poly,eps,info) determines a start polynomial {\em start}
+ ++ by using "startPolynomial then it increases the exponent
+ ++ n of {\em start ** n mod poly} to get an approximate factor of
+ ++ {\em poly}, in general of degree "degree poly -1". Then a divisor
+ ++ cascade is calculated and the best splitting is chosen, as soon
+ ++ as the error is small enough.
+ --++ In a later version we plan
+ --++ to use the whole information to get a split into more than 2
+ --++ factors.
+ ++ If {\em info} is {\em true}, then information messages are issued.
+ pleskenSplit: (UP, R) -> FR UP
+ ++ pleskenSplit(poly, eps) determines a start polynomial {\em start}\
+ ++ by using "startPolynomial then it increases the exponent
+ ++ n of {\em start ** n mod poly} to get an approximate factor of
+ ++ {\em poly}, in general of degree "degree poly -1". Then a divisor
+ ++ cascade is calculated and the best splitting is chosen, as soon
+ ++ as the error is small enough.
+ --++ In a later version we plan
+ --++ to use the whole information to get a split into more than 2
+ --++ factors.
+ reciprocalPolynomial: UP -> UP
+ ++ reciprocalPolynomial(p) calulates a polynomial which has exactly
+ ++ the inverses of the non-zero roots of p as roots, and the same
+ ++ number of 0-roots.
+ rootRadius: (UP,R) -> R
+ ++ rootRadius(p,errQuot) calculates the root radius of p with a
+ ++ maximal error quotient of {\em errQuot}.
+ rootRadius: UP -> R
+ ++ rootRadius(p) calculates the root radius of p with a
+ ++ maximal error quotient of {\em 1+globalEps}, where
+ ++ {\em globalEps} is the internal error bound, which can be
+ ++ set by {\em setErrorBound}.
+ schwerpunkt: UP -> C
+ ++ schwerpunkt(p) determines the 'Schwerpunkt' of the roots of the
+ ++ polynomial p of degree n, i.e. the center of gravity, which is
+ ++ {\em coeffient of \spad{x**(n-1)}} divided by
+ ++ {\em n times coefficient of \spad{x**n}}.
+ setErrorBound : R -> R
+ ++ setErrorBound(eps) changes the internal error bound,
+ -- by default being {\em 10 ** (-20)} to eps, if R is
+ ++ by default being {\em 10 ** (-3)} to eps, if R is
+ ++ a member in the category \spadtype{QuotientFieldCategory Integer}.
+ ++ The internal {\em globalDigits} is set to
+ -- {\em ceiling(1/r)**2*10} being {\em 10**41} by default.
+ ++ {\em ceiling(1/r)**2*10} being {\em 10**7} by default.
+ startPolynomial: UP -> Record(start: UP, factors: FR UP)
+ ++ startPolynomial(p) uses the ideas of Schoenhage's
+ ++ variant of Graeffe's method to construct circles which separate
+ ++ roots to get a good start polynomial, i.e. one whose
+ ++ image under the Chinese Remainder Isomorphism has both entries
+ ++ of norm smaller and greater or equal to 1. In case the
+ ++ roots are found during internal calculations.
+ ++ The corresponding factors
+ ++ are in {\em factors} which are otherwise 1.
+
+ private ==> add
+
+
+ Rep := ModMonic(C, UP)
+
+ -- constants
+ c : C
+ r : R
+ --globalDigits : I := 10 ** 41
+ globalDigits : I := 10 ** 7
+ globalEps : R :=
+ --a : R := (1000000000000000000000 :: I) :: R
+ a : R := (1000 :: I) :: R
+ 1/a
+ emptyLine : OF := " "
+ dashes : OF := center "---------------------------------------------------"
+ dots : OF := center "..................................................."
+ one : R := 1$R
+ two : R := 2 * one
+ ten : R := 10 * one
+ eleven : R := 11 * one
+ weakEps := eleven/ten
+ --invLog2 : R := 1/log10 (2*one)
+
+ -- signatures of local functions
+
+ absC : C -> R
+ --
+ absR : R -> R
+ --
+ calculateScale : UP -> R
+ --
+ makeMonic : UP -> UP
+ -- 'makeMonic p' divides 'p' by the leading coefficient,
+ -- to guarantee new leading coefficient to be 1$R we cannot
+ -- simply divide the leading monomial by the leading coefficient
+ -- because of possible rounding errors
+ min: (FAE, FAE) -> FAE
+ -- takes factorization with smaller error
+ nthRoot : (R, NNI) -> R
+ -- nthRoot(r,n) determines an approximation to the n-th
+ -- root of r, if \spadtype{R} has {\em ?**?: (R,Fraction Integer)->R}
+ -- we use this, otherwise we use {\em approxNthRoot} via
+ -- \spadtype{Integer}
+ shift: (UP,C) -> UP
+ -- shift(p,c) changes p(x) into p(x+c), thereby modifying the
+ -- roots u_j of p to the roots (u_j - c) of shift(p,c)
+ scale: (UP,C) -> UP
+ -- scale(p,c) changes p(x) into p(cx), thereby modifying the
+ -- roots u_j of p to the roots ((1/c) u_j) of scale(p,c)
+
+
+ -- implementation of exported functions
+
+
+ complexZeros(p,eps) ==
+ --r1 : R := rootRadius(p,weakEps)
+ --eps0 : R = r1 * nthRoot(eps, degree p)
+ -- right now we are content with
+ eps0 : R := eps/(ten ** degree p)
+ facs : FR UP := factor(p,eps0)
+ [-coefficient(linfac.factor,0) for linfac in factors facs]
+
+ complexZeros p == complexZeros(p,globalEps)
+ setErrorBound r ==
+ r <= 0 => error "setErrorBound: need error bound greater 0"
+ globalEps := r
+ if R has QuotientFieldCategory Integer then
+ rd : Integer := ceiling(1/r)
+ globalDigits := rd * rd * 10
+ lof : List OF := _
+ ["setErrorBound: internal digits set to",globalDigits::OF]
+ print hconcat lof
+ messagePrint "setErrorBound: internal error bound set to"
+ globalEps
+
+ pleskenSplit(poly,eps,info) ==
+ p := makeMonic poly
+ fp : FR UP
+ if not zero? (md := minimumDegree p) then
+ fp : FR UP := irreducibleFactor(monomial(1,1)$UP,md)$(FR UP)
+ p := p quo monomial(1,md)$UP
+ sP : Record(start: UP, factors: FR UP) := startPolynomial p
+ fp : FR UP := sP.factors
+-- if not one? fp then
+ if not (fp = 1) then
+ qr: Record(quotient: UP, remainder: UP):= divide(p,makeMonic expand fp)
+ p := qr.quotient
+ st := sP.start
+ zero? degree st => fp
+ -- we calculate in ModMonic(C, UP),
+ -- next line defines the polynomial, which is used for reducing
+ setPoly p
+ nm : R := eps
+ split : FAE
+ sR : Rep := st :: Rep
+ psR : Rep := sR ** (degree poly)
+
+ notFoundSplit : Boolean := true
+ while notFoundSplit repeat
+ -- if info then
+ -- lof : L OF := ["not successfull, new exponent:", nn::OF]
+ -- print hconcat lof
+ psR := psR * psR * sR -- exponent (2*d +1)
+ -- be careful, too large exponent results in rounding errors
+ -- tp is the first approximation of a divisor of poly:
+ tp : UP := lift psR
+ zero? degree tp =>
+ if info then print "we leave as we got constant factor"
+ nilFactor(poly,1)$(FR UP)
+ -- this was the case where we don't find a non-trivial factorization
+ -- we refine tp by repeated polynomial division and hope that
+ -- the norm of the remainder gets small from time to time
+ splits : L FAE := divisorCascade(p, makeMonic tp, info)
+ split := reduce(min,splits)
+ notFoundSplit := (eps <= split.error)
+
+ for fac in split.factors repeat
+ fp :=
+-- one? degree fac => fp * nilFactor(fac,1)$(FR UP)
+ (degree fac = 1) => fp * nilFactor(fac,1)$(FR UP)
+ fp * irreducibleFactor(fac,1)$(FR UP)
+ fp
+
+ startPolynomial p == -- assume minimumDegree is 0
+ --print (p :: OF)
+ fp : FR UP := 1
+-- one? degree p =>
+ (degree p = 1) =>
+ p := makeMonic p
+ [p,irreducibleFactor(p,1)]
+ startPoly : UP := monomial(1,1)$UP
+ eps : R := weakEps -- 10 per cent errors allowed
+ r1 : R := rootRadius(p, eps)
+ rd : R := 1/rootRadius(reciprocalPolynomial p, eps)
+ (r1 > (2::R)) and (rd < 1/(2::R)) => [startPoly,fp] -- unit circle splitting!
+ -- otherwise the norms of the roots are too closed so we
+ -- take the center of gravity as new origin:
+ u : C := schwerpunkt p
+ startPoly := startPoly-monomial(u,0)
+ p := shift(p,-u)
+ -- determine new rootRadius:
+ r1 : R := rootRadius(p, eps)
+ startPoly := startPoly/(r1::C)
+ -- use one of the 4 points r1*zeta, where zeta is a 4th root of unity
+ -- as new origin, this could be changed to an arbitrary list
+ -- of elements of norm 1.
+ listOfCenters : L C := [complex(r1,0), complex(0,r1), _
+ complex(-r1,0), complex(0,-r1)]
+ lp : L UP := [shift(p,v) for v in listOfCenters]
+ -- next we check if one of these centers is a root
+ centerIsRoot : Boolean := false
+ for i in 1..maxIndex lp repeat
+ if (mD := minimumDegree lp.i) > 0 then
+ pp : UP := monomial(1,1)-monomial(listOfCenters.i-u,0)
+ centerIsRoot := true
+ fp := fp * irreducibleFactor(pp,mD)
+ centerIsRoot =>
+ p := shift(p,u) quo expand fp
+ --print (p::OF)
+ zero? degree p => [p,fp]
+ sP:= startPolynomial(p)
+ [sP.start,fp]
+ -- choose the best one w.r.t. maximal quotient of norm of largest
+ -- root and norm of smallest root
+ lpr1 : L R := [rootRadius(q,eps) for q in lp]
+ lprd : L R := [1/rootRadius(reciprocalPolynomial q,eps) for q in lp]
+ -- later we should check here of an rd is smaller than globalEps
+ lq : L R := []
+ for i in 1..maxIndex lpr1 repeat
+ lq := cons(lpr1.i/lprd.i, lq)
+ --lq : L R := [(l/s)::R for l in lpr1 for s in lprd])
+ lq := reverse lq
+ po := position(reduce(max,lq),lq)
+ --p := lp.po
+ --lrr : L R := [rootRadius(p,i,1+eps) for i in 2..(degree(p)-1)]
+ --lrr := concat(concat(lpr1.po,lrr),lprd.po)
+ --lu : L R := [(lrr.i + lrr.(i+1))/2 for i in 1..(maxIndex(lrr)-1)]
+ [startPoly - monomial(listOfCenters.po,0),fp]
+
+ norm p ==
+ -- reduce(_+$R,map(absC,coefficients p))
+ nm : R := 0
+ for c in coefficients p repeat
+ nm := nm + absC c
+ nm
+
+ pleskenSplit(poly,eps) == pleskenSplit(poly,eps,false)
+
+ graeffe p ==
+ -- If p = ao x**n + a1 x**(n-1) + ... + a<n-1> x + an
+ -- and q = bo x**n + b1 x**(n-1) + ... + b<n-1> x + bn
+ -- are such that q(-x**2) = p(x)p(-x), then
+ -- bk := ak**2 + 2 * ((-1) * a<k-1>*a<k+1> + ... +
+ -- (-1)**l * a<l>*a<l>) where l = min(k, n-k).
+ -- graeffe(p) constructs q using these identities.
+ n : NNI := degree p
+ aForth : L C := []
+ for k in 0..n repeat -- aForth = [a0, a1, ..., a<n-1>, an]
+ aForth := cons(coefficient(p, k::NNI), aForth)
+ aBack : L C := [] -- after k steps
+ -- aBack = [ak, a<k-1>, ..., a1, a0]
+ gp : UP := 0$UP
+ for k in 0..n repeat
+ ak : C := first aForth
+ aForth := rest aForth
+ aForthCopy : L C := aForth -- we iterate over aForth and
+ aBackCopy : L C := aBack -- aBack but do not want to
+ -- destroy them
+ sum : C := 0
+ const : I := -1 -- after i steps const = (-1)**i
+ for aminus in aBack for aplus in aForth repeat
+ -- after i steps aminus = a<k-i> and aplus = a<k+i>
+ sum := sum + const * aminus * aplus
+ aForthCopy := rest aForthCopy
+ aBackCopy := rest aBackCopy
+ const := -const
+ gp := gp + monomial(ak*ak + 2 * sum, (n-k)::NNI)
+ aBack := cons(ak, aBack)
+ gp
+
+
+
+ rootRadius(p,errorQuotient) ==
+ errorQuotient <= 1$R =>
+ error "rootRadius: second Parameter must be greater than 1"
+ pp : UP := p
+ rho : R := calculateScale makeMonic pp
+ rR : R := rho
+ pp := makeMonic scale(pp,complex(rho,0$R))
+ expo : NNI := 1
+ d : NNI := degree p
+ currentError: R := nthRoot(2::R, 2)
+ currentError := d*20*currentError
+ while nthRoot(currentError, expo) >= errorQuotient repeat
+ -- if info then print (expo :: OF)
+ pp := graeffe pp
+ rho := calculateScale pp
+ expo := 2 * expo
+ rR := nthRoot(rho, expo) * rR
+ pp := makeMonic scale(pp,complex(rho,0$R))
+ rR
+
+ rootRadius(p) == rootRadius(p, 1+globalEps)
+
+ schwerpunkt p ==
+ zero? p => 0$C
+ zero? (d := degree p) => error _
+ "schwerpunkt: non-zero const. polynomial has no roots and no schwerpunkt"
+ -- coeffient of x**d and x**(d-1)
+ lC : C := coefficient(p,d) -- ^= 0
+ nC : C := coefficient(p,(d-1) pretend NNI)
+ (denom := recip ((d::I::C)*lC)) case "failed" => error "schwerpunkt: _
+ degree * leadingCoefficient not invertible in ring of coefficients"
+ - (nC*(denom::C))
+
+ reciprocalPolynomial p ==
+ zero? p => 0
+ d : NNI := degree p
+ md : NNI := d+minimumDegree p
+ lm : L UP := [monomial(coefficient(p,i),(md-i) :: NNI) for i in 0..d]
+ sol := reduce(_+, lm)
+
+ divisorCascade(p, tp, info) ==
+ lfae : L FAE := nil()
+ for i in 1..degree tp while (degree tp > 0) repeat
+ -- USE monicDivide !!!
+ qr : Record(quotient: UP, remainder: UP) := divide(p,tp)
+ factor1 : UP := tp
+ factor2 : UP := makeMonic qr.quotient
+ -- refinement of tp:
+ tp := qr.remainder
+ nm : R := norm tp
+ listOfFactors : L UP := cons(factor2,nil()$(L UP))
+ listOfFactors := cons(factor1,listOfFactors)
+ lfae := cons( [listOfFactors,nm], lfae)
+ if info then
+ --lof : L OF := [i :: OF,"-th division:"::OF]
+ --print center box hconcat lof
+ print emptyLine
+ lof : L OF := ["error polynomial has degree " ::OF,_
+ (degree tp)::OF, " and norm " :: OF, nm :: OF]
+ print center hconcat lof
+ lof : L OF := ["degrees of factors:" ::OF,_
+ (degree factor1)::OF," ", (degree factor2)::OF]
+ print center hconcat lof
+ if info then print emptyLine
+ reverse lfae
+
+ divisorCascade(p, tp) == divisorCascade(p, tp, false)
+
+ factor(poly,eps) == factor(poly,eps,false)
+ factor(p) == factor(p, globalEps)
+
+ factor(poly,eps,info) ==
+ result : FR UP := coerce monomial(leadingCoefficient poly,0)
+ d : NNI := degree poly
+ --should be
+ --den : R := (d::I)::R * two**(d::Integer) * norm poly
+ --eps0 : R := eps / den
+ -- for now only
+ eps0 : R := eps / (ten*ten)
+-- one? d => irreducibleFactor(poly,1)$(FR UP)
+ (d = 1) => irreducibleFactor(poly,1)$(FR UP)
+ listOfFactors : L Record(factor: UP,exponent: I) :=_
+ list [makeMonic poly,1]
+ if info then
+ lof : L OF := [dashes,dots,"list of Factors:",dots,listOfFactors::OF, _
+ dashes, "list of Linear Factors:", dots, result::OF, _
+ dots,dashes]
+ print vconcat lof
+ while not null listOfFactors repeat
+ p : UP := (first listOfFactors).factor
+ exponentOfp : I := (first listOfFactors).exponent
+ listOfFactors := rest listOfFactors
+ if info then
+ lof : L OF := ["just now we try to split the polynomial:",p::OF]
+ print vconcat lof
+ split : FR UP := pleskenSplit(p, eps0, info)
+-- one? numberOfFactors split =>
+ (numberOfFactors split = 1) =>
+ -- in a later version we will change error bound and
+ -- accuracy here to deal this case as well
+ lof : L OF := ["factor: couldn't split factor",_
+ center(p :: OF), "with required error bound"]
+ print vconcat lof
+ result := result * nilFactor(p, exponentOfp)
+ -- now we got 2 good factors of p, we drop p and continue
+ -- with the factors, if they are not linear, or put a
+ -- linear factor to the result
+ for rec in factors(split)$(FR UP) repeat
+ newFactor : UP := rec.factor
+ expOfFactor := exponentOfp * rec.exponent
+-- one? degree newFactor =>
+ (degree newFactor = 1) =>
+ result := result * nilFactor(newFactor,expOfFactor)
+ listOfFactors:=cons([newFactor,expOfFactor],_
+ listOfFactors)
+ result
+
+ -- implementation of local functions
+
+ absC c == nthRoot(norm(c)$C,2)
+ absR r ==
+ r < 0 => -r
+ r
+ min(fae1,fae2) ==
+ fae2.error < fae1.error => fae2
+ fae1
+ calculateScale p ==
+ d := degree p
+ maxi :R := 0
+ for j in 1..d for cof in rest coefficients p repeat
+ -- here we need abs: R -> R
+ rc : R := absR real cof
+ ic : R := absR imag cof
+ locmax: R := max(rc,ic)
+ maxi := max( nthRoot( locmax/(binomial(d,j)$ICF::R), j), maxi)
+ -- Maybe I should use some type of logarithm for the following:
+ maxi = 0$R => error("Internal Error: scale cannot be 0")
+ rho :R := one
+ rho < maxi =>
+ while rho < maxi repeat rho := ten * rho
+ rho / ten
+ while maxi < rho repeat rho := rho / ten
+ rho = 0 => one
+ rho
+ makeMonic p ==
+ p = 0 => p
+ monomial(1,degree p)$UP + (reductum p)/(leadingCoefficient p)
+
+ scale(p, c) ==
+ -- eval(p,cx) is missing !!
+ eq : Equation UP := equation(monomial(1,1), monomial(c,1))
+ eval(p,eq)
+ -- improvement?: direct calculation of the new coefficients
+
+ shift(p,c) ==
+ rhs : UP := monomial(1,1) + monomial(c,0)
+ eq : Equation UP := equation(monomial(1,1), rhs)
+ eval(p,eq)
+ -- improvement?: direct calculation of the new coefficients
+
+ nthRoot(r,n) ==
+ R has RealNumberSystem => r ** (1/n)
+ R has QuotientFieldCategory Integer =>
+ den : I := approxNthRoot(globalDigits * denom r ,n)$IntegerRoots(I)
+ num : I := approxNthRoot(globalDigits * numer r ,n)$IntegerRoots(I)
+ num/den
+ -- the following doesn't compile
+ --R has coerce: % -> Fraction Integer =>
+ -- q : Fraction Integer := coerce(r)@Fraction(Integer)
+ -- den : I := approxNthRoot(globalDigits * denom q ,n)$IntegerRoots(I)
+ -- num : I := approxNthRoot(globalDigits * numer q ,n)$IntegerRoots(I)
+ -- num/den
+ r -- this is nonsense, perhaps a Newton iteration for x**n-r here
+
+)fin
+ -- for late use:
+
+ graeffe2 p ==
+ -- substitute x by -x :
+ eq : Equation UP := equation(monomial(1,1), monomial(-1$C,1))
+ pp : UP := p*eval(p,eq)
+ gp : UP := 0$UP
+ while pp ^= 0 repeat
+ i:NNI := (degree pp) quo (2::NNI)
+ coef:C:=
+ even? i => leadingCoefficient pp
+ - leadingCoefficient pp
+ gp := gp + monomial(coef,i)
+ pp := reductum pp
+ gp
+ shift2(p,c) ==
+ d := degree p
+ cc : C := 1
+ coef := List C := [cc := c * cc for i in 1..d]
+ coef := cons(1,coef)
+ coef := [coefficient(p,i)*coef.(1+i) for i in 0..d]
+ res : UP := 0
+ for j in 0..d repeat
+ cc := 0
+ for i in j..d repeat
+ cc := cc + coef.i * (binomial(i,j)$ICF :: R)
+ res := res + monomial(cc,j)$UP
+ res
+ scale2(p,c) ==
+ d := degree p
+ cc : C := 1
+ coef := List C := [cc := c * cc for i in 1..d]
+ coef := cons(1,coef)
+ coef := [coefficient(p,i)*coef.(i+1) for i in 0..d]
+ res : UP := 0
+ for i in 0..d repeat res := res + monomial(coef.(i+1),i)$UP
+ res
+ scale2: (UP,C) -> UP
+ shift2: (UP,C) -> UP
+ graeffe2 : UP -> UP
+ ++ graeffe2 p determines q such that \spad{q(-z**2) = p(z)*p(-z)}.
+ ++ Note that the roots of q are the squares of the roots of p.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package CRFP ComplexRootFindingPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/curve.spad.pamphlet b/src/algebra/curve.spad.pamphlet
new file mode 100644
index 00000000..5ca9495b
--- /dev/null
+++ b/src/algebra/curve.spad.pamphlet
@@ -0,0 +1,946 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra curve.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category FFCAT FunctionFieldCategory}
+<<category FFCAT FunctionFieldCategory>>=
+)abbrev category FFCAT FunctionFieldCategory
+++ Function field of a curve
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 19 Mai 1993
+++ Description: This category is a model for the function field of a
+++ plane algebraic curve.
+++ Keywords: algebraic, curve, function, field.
+FunctionFieldCategory(F, UP, UPUP): Category == Definition where
+ F : UniqueFactorizationDomain
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+
+ Z ==> Integer
+ Q ==> Fraction F
+ P ==> Polynomial F
+ RF ==> Fraction UP
+ QF ==> Fraction UPUP
+ SY ==> Symbol
+ REC ==> Record(num:$, den:UP, derivden:UP, gd:UP)
+
+ Definition ==> MonogenicAlgebra(RF, UPUP) with
+ numberOfComponents : () -> NonNegativeInteger
+ ++ numberOfComponents() returns the number of absolutely irreducible
+ ++ components.
+ genus : () -> NonNegativeInteger
+ ++ genus() returns the genus of one absolutely irreducible component
+ absolutelyIrreducible? : () -> Boolean
+ ++ absolutelyIrreducible?() tests if the curve absolutely irreducible?
+ rationalPoint? : (F, F) -> Boolean
+ ++ rationalPoint?(a, b) tests if \spad{(x=a,y=b)} is on the curve.
+ branchPointAtInfinity? : () -> Boolean
+ ++ branchPointAtInfinity?() tests if there is a branch point at infinity.
+ branchPoint? : F -> Boolean
+ ++ branchPoint?(a) tests whether \spad{x = a} is a branch point.
+ branchPoint? : UP -> Boolean
+ ++ branchPoint?(p) tests whether \spad{p(x) = 0} is a branch point.
+ singularAtInfinity? : () -> Boolean
+ ++ singularAtInfinity?() tests if there is a singularity at infinity.
+ singular? : F -> Boolean
+ ++ singular?(a) tests whether \spad{x = a} is singular.
+ singular? : UP -> Boolean
+ ++ singular?(p) tests whether \spad{p(x) = 0} is singular.
+ ramifiedAtInfinity? : () -> Boolean
+ ++ ramifiedAtInfinity?() tests if infinity is ramified.
+ ramified? : F -> Boolean
+ ++ ramified?(a) tests whether \spad{x = a} is ramified.
+ ramified? : UP -> Boolean
+ ++ ramified?(p) tests whether \spad{p(x) = 0} is ramified.
+ integralBasis : () -> Vector $
+ ++ integralBasis() returns the integral basis for the curve.
+ integralBasisAtInfinity: () -> Vector $
+ ++ integralBasisAtInfinity() returns the local integral basis at infinity.
+ integralAtInfinity? : $ -> Boolean
+ ++ integralAtInfinity?() tests if f is locally integral at infinity.
+ integral? : $ -> Boolean
+ ++ integral?() tests if f is integral over \spad{k[x]}.
+ complementaryBasis : Vector $ -> Vector $
+ ++ complementaryBasis(b1,...,bn) returns the complementary basis
+ ++ \spad{(b1',...,bn')} of \spad{(b1,...,bn)}.
+ normalizeAtInfinity : Vector $ -> Vector $
+ ++ normalizeAtInfinity(v) makes v normal at infinity.
+ reduceBasisAtInfinity : Vector $ -> Vector $
+ ++ reduceBasisAtInfinity(b1,...,bn) returns \spad{(x**i * bj)}
+ ++ for all i,j such that \spad{x**i*bj} is locally integral at infinity.
+ integralMatrix : () -> Matrix RF
+ ++ integralMatrix() returns M such that
+ ++ \spad{(w1,...,wn) = M (1, y, ..., y**(n-1))},
+ ++ where \spad{(w1,...,wn)} is the integral basis of
+ ++ \spadfunFrom{integralBasis}{FunctionFieldCategory}.
+ inverseIntegralMatrix : () -> Matrix RF
+ ++ inverseIntegralMatrix() returns M such that
+ ++ \spad{M (w1,...,wn) = (1, y, ..., y**(n-1))}
+ ++ where \spad{(w1,...,wn)} is the integral basis of
+ ++ \spadfunFrom{integralBasis}{FunctionFieldCategory}.
+ integralMatrixAtInfinity : () -> Matrix RF
+ ++ integralMatrixAtInfinity() returns M such that
+ ++ \spad{(v1,...,vn) = M (1, y, ..., y**(n-1))}
+ ++ where \spad{(v1,...,vn)} is the local integral basis at infinity
+ ++ returned by \spad{infIntBasis()}.
+ inverseIntegralMatrixAtInfinity: () -> Matrix RF
+ ++ inverseIntegralMatrixAtInfinity() returns M such
+ ++ that \spad{M (v1,...,vn) = (1, y, ..., y**(n-1))}
+ ++ where \spad{(v1,...,vn)} is the local integral basis at infinity
+ ++ returned by \spad{infIntBasis()}.
+ yCoordinates : $ -> Record(num:Vector(UP), den:UP)
+ ++ yCoordinates(f) returns \spad{[[A1,...,An], D]} such that
+ ++ \spad{f = (A1 + A2 y +...+ An y**(n-1)) / D}.
+ represents : (Vector UP, UP) -> $
+ ++ represents([A0,...,A(n-1)],D) returns
+ ++ \spad{(A0 + A1 y +...+ A(n-1)*y**(n-1))/D}.
+ integralCoordinates : $ -> Record(num:Vector(UP), den:UP)
+ ++ integralCoordinates(f) returns \spad{[[A1,...,An], D]} such that
+ ++ \spad{f = (A1 w1 +...+ An wn) / D} where \spad{(w1,...,wn)} is the
+ ++ integral basis returned by \spad{integralBasis()}.
+ integralRepresents : (Vector UP, UP) -> $
+ ++ integralRepresents([A1,...,An], D) returns
+ ++ \spad{(A1 w1+...+An wn)/D}
+ ++ where \spad{(w1,...,wn)} is the integral
+ ++ basis of \spad{integralBasis()}.
+ integralDerivationMatrix:(UP -> UP) -> Record(num:Matrix(UP),den:UP)
+ ++ integralDerivationMatrix(d) extends the derivation d from UP to $
+ ++ and returns (M, Q) such that the i^th row of M divided by Q form
+ ++ the coordinates of \spad{d(wi)} with respect to \spad{(w1,...,wn)}
+ ++ where \spad{(w1,...,wn)} is the integral basis returned
+ ++ by integralBasis().
+ integral? : ($, F) -> Boolean
+ ++ integral?(f, a) tests whether f is locally integral at \spad{x = a}.
+ integral? : ($, UP) -> Boolean
+ ++ integral?(f, p) tests whether f is locally integral at \spad{p(x) = 0}.
+ differentiate : ($, UP -> UP) -> $
+ ++ differentiate(x, d) extends the derivation d from UP to $ and
+ ++ applies it to x.
+ represents : (Vector UP, UP) -> $
+ ++ represents([A0,...,A(n-1)],D) returns
+ ++ \spad{(A0 + A1 y +...+ A(n-1)*y**(n-1))/D}.
+ primitivePart : $ -> $
+ ++ primitivePart(f) removes the content of the denominator and
+ ++ the common content of the numerator of f.
+ elt : ($, F, F) -> F
+ ++ elt(f,a,b) or f(a, b) returns the value of f at the point \spad{(x = a, y = b)}
+ ++ if it is not singular.
+ elliptic : () -> Union(UP, "failed")
+ ++ elliptic() returns \spad{p(x)} if the curve is the elliptic
+ ++ defined by \spad{y**2 = p(x)}, "failed" otherwise.
+ hyperelliptic : () -> Union(UP, "failed")
+ ++ hyperelliptic() returns \spad{p(x)} if the curve is the hyperelliptic
+ ++ defined by \spad{y**2 = p(x)}, "failed" otherwise.
+ algSplitSimple : ($, UP -> UP) -> REC
+ ++ algSplitSimple(f, D) returns \spad{[h,d,d',g]} such that \spad{f=h/d},
+ ++ \spad{h} is integral at all the normal places w.r.t. \spad{D},
+ ++ \spad{d' = Dd}, \spad{g = gcd(d, discriminant())} and \spad{D}
+ ++ is the derivation to use. \spad{f} must have at most simple finite
+ ++ poles.
+ if F has Field then
+ nonSingularModel: SY -> List Polynomial F
+ ++ nonSingularModel(u) returns the equations in u1,...,un of
+ ++ an affine non-singular model for the curve.
+ if F has Finite then
+ rationalPoints: () -> List List F
+ ++ rationalPoints() returns the list of all the affine rational points.
+
+ add
+ import InnerCommonDenominator(UP, RF, Vector UP, Vector RF)
+ import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
+
+ repOrder: (Matrix RF, Z) -> Z
+ Q2RF : Q -> RF
+ infOrder: RF -> Z
+ infValue: RF -> Fraction F
+ intvalue: (Vector UP, F, F) -> F
+ rfmonom : Z -> RF
+ kmin : (Matrix RF,Vector Q) -> Union(Record(pos:Z,km:Z),"failed")
+
+ Q2RF q == numer(q)::UP / denom(q)::UP
+ infOrder f == (degree denom f)::Z - (degree numer f)::Z
+ integral? f == ground?(integralCoordinates(f).den)
+ integral?(f:$, a:F) == (integralCoordinates(f).den)(a) ^= 0
+-- absolutelyIrreducible? == one? numberOfComponents()
+ absolutelyIrreducible? == numberOfComponents() = 1
+ yCoordinates f == splitDenominator coordinates f
+
+ hyperelliptic() ==
+ degree(f := definingPolynomial()) ^= 2 => "failed"
+ (u:=retractIfCan(reductum f)@Union(RF,"failed")) case "failed" => "failed"
+ (v := retractIfCan(-(u::RF) / leadingCoefficient f)@Union(UP, "failed"))
+ case "failed" => "failed"
+ odd? degree(p := v::UP) => p
+ "failed"
+
+ algSplitSimple(f, derivation) ==
+ cd := splitDenominator lift f
+ dd := (cd.den exquo (g := gcd(cd.den, derivation(cd.den))))::UP
+ [reduce(inv(g::RF) * cd.num), dd, derivation dd,
+ gcd(dd, retract(discriminant())@UP)]
+
+ elliptic() ==
+ (u := hyperelliptic()) case "failed" => "failed"
+ degree(p := u::UP) = 3 => p
+ "failed"
+
+ rationalPoint?(x, y) ==
+ zero?((definingPolynomial() (y::UP::RF)) (x::UP::RF))
+
+ if F has Field then
+ import PolyGroebner(F)
+ import MatrixCommonDenominator(UP, RF)
+
+ UP2P : (UP, P) -> P
+ UPUP2P: (UPUP, P, P) -> P
+
+ UP2P(p, x) ==
+ (map(#1::P, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
+ P, SparseUnivariatePolynomial P)) x
+
+ UPUP2P(p, x, y) ==
+ (map(UP2P(retract(#1)@UP, x),
+ p)$UnivariatePolynomialCategoryFunctions2(RF, UPUP,
+ P, SparseUnivariatePolynomial P)) y
+
+ nonSingularModel u ==
+ d := commonDenominator(coordinates(w := integralBasis()))::RF
+ vars := [concat(string u, string i)::SY for i in 1..(n := #w)]
+ x := "%%dummy1"::SY
+ y := "%%dummy2"::SY
+ select_!(zero?(degree(#1, x)) and zero?(degree(#1, y)),
+ lexGroebner([v::P - UPUP2P(lift(d * w.i), x::P, y::P)
+ for v in vars for i in 1..n], concat([x, y], vars)))
+
+ if F has Finite then
+ ispoint: (UPUP, F, F) -> List F
+
+-- must use the 'elt function explicitely or the compiler takes 45 mins
+-- on that function MB 5/90
+-- still takes ages : I split the expression up. JHD 6/Aug/90
+ ispoint(p, x, y) ==
+ jhd:RF:=p(y::UP::RF)
+ zero?(jhd (x::UP::RF)) => [x, y]
+ empty()
+
+ rationalPoints() ==
+ p := definingPolynomial()
+ concat [[pt for y in 1..size()$F | not empty?(pt :=
+ ispoint(p, index(x::PositiveInteger)$F,
+ index(y::PositiveInteger)$F))]$List(List F)
+ for x in 1..size()$F]$List(List(List F))
+
+ intvalue(v, x, y) ==
+ singular? x => error "Point is singular"
+ mini := minIndex(w := integralBasis())
+ rec := yCoordinates(+/[qelt(v, i)::RF * qelt(w, i)
+ for i in mini .. maxIndex w])
+ n := +/[(qelt(rec.num, i) x) *
+ (y ** ((i - mini)::NonNegativeInteger))
+ for i in mini .. maxIndex w]
+ zero?(d := (rec.den) x) =>
+ zero? n => error "0/0 -- cannot compute value yet"
+ error "Shouldn't happen"
+ (n exquo d)::F
+
+ elt(f, x, y) ==
+ rec := integralCoordinates f
+ n := intvalue(rec.num, x, y)
+ zero?(d := (rec.den) x) =>
+ zero? n => error "0/0 -- cannot compute value yet"
+ error "Function has a pole at the given point"
+ (n exquo d)::F
+
+ primitivePart f ==
+ cd := yCoordinates f
+ d := gcd([content qelt(cd.num, i)
+ for i in minIndex(cd.num) .. maxIndex(cd.num)]$List(F))
+ * primitivePart(cd.den)
+ represents [qelt(cd.num, i) / d
+ for i in minIndex(cd.num) .. maxIndex(cd.num)]$Vector(RF)
+
+ reduceBasisAtInfinity b ==
+ x := monomial(1, 1)$UP ::RF
+ concat([[f for j in 0.. while
+ integralAtInfinity?(f := x**j * qelt(b, i))]$Vector($)
+ for i in minIndex b .. maxIndex b]$List(Vector $))
+
+ complementaryBasis b ==
+ m := inverse(traceMatrix b)::Matrix(RF)
+ [represents row(m, i) for i in minRowIndex m .. maxRowIndex m]
+
+ integralAtInfinity? f ==
+ not any?(infOrder(#1) < 0,
+ coordinates(f) * inverseIntegralMatrixAtInfinity())$Vector(RF)
+
+ numberOfComponents() ==
+ count(integralAtInfinity?, integralBasis())$Vector($)
+
+ represents(v:Vector UP, d:UP) ==
+ represents
+ [qelt(v, i) / d for i in minIndex v .. maxIndex v]$Vector(RF)
+
+ genus() ==
+ ds := discriminant()
+ d := degree(retract(ds)@UP) + infOrder(ds * determinant(
+ integralMatrixAtInfinity() * inverseIntegralMatrix()) ** 2)
+ dd := (((d exquo 2)::Z - rank()) exquo numberOfComponents())::Z
+ (dd + 1)::NonNegativeInteger
+
+ repOrder(m, i) ==
+ nostart:Boolean := true
+ ans:Z := 0
+ r := row(m, i)
+ for j in minIndex r .. maxIndex r | qelt(r, j) ^= 0 repeat
+ ans :=
+ nostart => (nostart := false; infOrder qelt(r, j))
+ min(ans, infOrder qelt(r,j))
+ nostart => error "Null row"
+ ans
+
+ infValue f ==
+ zero? f => 0
+ (n := infOrder f) > 0 => 0
+ zero? n =>
+ (leadingCoefficient numer f) / (leadingCoefficient denom f)
+ error "f not locally integral at infinity"
+
+ rfmonom n ==
+ n < 0 => inv(monomial(1, (-n)::NonNegativeInteger)$UP :: RF)
+ monomial(1, n::NonNegativeInteger)$UP :: RF
+
+ kmin(m, v) ==
+ nostart:Boolean := true
+ k:Z := 0
+ ii := minRowIndex m - (i0 := minIndex v)
+ for i in minIndex v .. maxIndex v | qelt(v, i) ^= 0 repeat
+ nk := repOrder(m, i + ii)
+ if nostart then (nostart := false; k := nk; i0 := i)
+ else
+ if nk < k then (k := nk; i0 := i)
+ nostart => "failed"
+ [i0, k]
+
+ normalizeAtInfinity w ==
+ ans := copy w
+ infm := inverseIntegralMatrixAtInfinity()
+ mhat := zero(rank(), rank())$Matrix(RF)
+ ii := minIndex w - minRowIndex mhat
+ repeat
+ m := coordinates(ans) * infm
+ r := [rfmonom repOrder(m, i)
+ for i in minRowIndex m .. maxRowIndex m]$Vector(RF)
+ for i in minRowIndex m .. maxRowIndex m repeat
+ for j in minColIndex m .. maxColIndex m repeat
+ qsetelt_!(mhat, i, j, qelt(r, i + ii) * qelt(m, i, j))
+ sol := first nullSpace transpose map(infValue,
+ mhat)$MatrixCategoryFunctions2(RF, Vector RF, Vector RF,
+ Matrix RF, Q, Vector Q, Vector Q, Matrix Q)
+ (pr := kmin(m, sol)) case "failed" => return ans
+ qsetelt_!(ans, pr.pos,
+ +/[Q2RF(qelt(sol, i)) * rfmonom(repOrder(m, i - ii) - pr.km)
+ * qelt(ans, i) for i in minIndex sol .. maxIndex sol])
+
+ integral?(f:$, p:UP) ==
+ (r:=retractIfCan(p)@Union(F,"failed")) case F => integral?(f,r::F)
+ (integralCoordinates(f).den exquo p) case "failed"
+
+ differentiate(f:$, d:UP -> UP) ==
+ differentiate(f, differentiate(#1, d)$RF)
+
+@
+\section{package MMAP MultipleMap}
+<<package MMAP MultipleMap>>=
+)abbrev package MMAP MultipleMap
+++ Lifting a map through 2 levels of polynomials
+++ Author: Manuel Bronstein
+++ Date Created: May 1988
+++ Date Last Updated: 11 Jul 1990
+++ Description: Lifting of a map through 2 levels of polynomials;
+MultipleMap(R1,UP1,UPUP1,R2,UP2,UPUP2): Exports == Implementation where
+ R1 : IntegralDomain
+ UP1 : UnivariatePolynomialCategory R1
+ UPUP1: UnivariatePolynomialCategory Fraction UP1
+ R2 : IntegralDomain
+ UP2 : UnivariatePolynomialCategory R2
+ UPUP2: UnivariatePolynomialCategory Fraction UP2
+
+ Q1 ==> Fraction UP1
+ Q2 ==> Fraction UP2
+
+ Exports ==> with
+ map: (R1 -> R2, UPUP1) -> UPUP2
+ ++ map(f, p) lifts f to the domain of p then applies it to p.
+
+ Implementation ==> add
+ import UnivariatePolynomialCategoryFunctions2(R1, UP1, R2, UP2)
+
+ rfmap: (R1 -> R2, Q1) -> Q2
+
+ rfmap(f, q) == map(f, numer q) / map(f, denom q)
+
+ map(f, p) ==
+ map(rfmap(f, #1),
+ p)$UnivariatePolynomialCategoryFunctions2(Q1, UPUP1, Q2, UPUP2)
+
+@
+\section{package FFCAT2 FunctionFieldCategoryFunctions2}
+<<package FFCAT2 FunctionFieldCategoryFunctions2>>=
+)abbrev package FFCAT2 FunctionFieldCategoryFunctions2
+++ Lifts a map from rings to function fields over them
+++ Author: Manuel Bronstein
+++ Date Created: May 1988
+++ Date Last Updated: 26 Jul 1988
+++ Description: Lifts a map from rings to function fields over them.
+FunctionFieldCategoryFunctions2(R1, UP1, UPUP1, F1, R2, UP2, UPUP2, F2):
+ Exports == Implementation where
+ R1 : UniqueFactorizationDomain
+ UP1 : UnivariatePolynomialCategory R1
+ UPUP1: UnivariatePolynomialCategory Fraction UP1
+ F1 : FunctionFieldCategory(R1, UP1, UPUP1)
+ R2 : UniqueFactorizationDomain
+ UP2 : UnivariatePolynomialCategory R2
+ UPUP2: UnivariatePolynomialCategory Fraction UP2
+ F2 : FunctionFieldCategory(R2, UP2, UPUP2)
+
+ Exports ==> with
+ map: (R1 -> R2, F1) -> F2
+ ++ map(f, p) lifts f to F1 and applies it to p.
+
+ Implementation ==> add
+ map(f, f1) ==
+ reduce(map(f, lift f1)$MultipleMap(R1, UP1, UPUP1, R2, UP2, UPUP2))
+
+@
+\section{package CHVAR ChangeOfVariable}
+<<package CHVAR ChangeOfVariable>>=
+)abbrev package CHVAR ChangeOfVariable
+++ Sends a point to infinity
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 22 Feb 1990
+++ Description:
+++ Tools to send a point to infinity on an algebraic curve.
+ChangeOfVariable(F, UP, UPUP): Exports == Implementation where
+ F : UniqueFactorizationDomain
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Z
+ RF ==> Fraction UP
+
+ Exports ==> with
+ mkIntegral: UPUP -> Record(coef:RF, poly:UPUP)
+ ++ mkIntegral(p(x,y)) returns \spad{[c(x), q(x,z)]} such that
+ ++ \spad{z = c * y} is integral.
+ ++ The algebraic relation between x and y is \spad{p(x, y) = 0}.
+ ++ The algebraic relation between x and z is \spad{q(x, z) = 0}.
+ radPoly : UPUP -> Union(Record(radicand:RF, deg:N), "failed")
+ ++ radPoly(p(x, y)) returns \spad{[c(x), n]} if p is of the form
+ ++ \spad{y**n - c(x)}, "failed" otherwise.
+ rootPoly : (RF, N) -> Record(exponent: N, coef:RF, radicand:UP)
+ ++ rootPoly(g, n) returns \spad{[m, c, P]} such that
+ ++ \spad{c * g ** (1/n) = P ** (1/m)}
+ ++ thus if \spad{y**n = g}, then \spad{z**m = P}
+ ++ where \spad{z = c * y}.
+ goodPoint : (UPUP,UPUP) -> F
+ ++ goodPoint(p, q) returns an integer a such that a is neither
+ ++ a pole of \spad{p(x,y)} nor a branch point of \spad{q(x,y) = 0}.
+ eval : (UPUP, RF, RF) -> UPUP
+ ++ eval(p(x,y), f(x), g(x)) returns \spad{p(f(x), y * g(x))}.
+ chvar : (UPUP,UPUP) -> Record(func:UPUP,poly:UPUP,c1:RF,c2:RF,deg:N)
+ ++ chvar(f(x,y), p(x,y)) returns
+ ++ \spad{[g(z,t), q(z,t), c1(z), c2(z), n]}
+ ++ such that under the change of variable
+ ++ \spad{x = c1(z)}, \spad{y = t * c2(z)},
+ ++ one gets \spad{f(x,y) = g(z,t)}.
+ ++ The algebraic relation between x and y is \spad{p(x, y) = 0}.
+ ++ The algebraic relation between z and t is \spad{q(z, t) = 0}.
+
+ Implementation ==> add
+ import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
+
+ algPoly : UPUP -> Record(coef:RF, poly:UPUP)
+ RPrim : (UP, UP, UPUP) -> Record(coef:RF, poly:UPUP)
+ good? : (F, UP, UP) -> Boolean
+ infIntegral?: (UPUP, UPUP) -> Boolean
+
+ eval(p, x, y) == map(#1 x, p) monomial(y, 1)
+ good?(a, p, q) == p(a) ^= 0 and q(a) ^= 0
+
+ algPoly p ==
+ ground?(a:= retract(leadingCoefficient(q:=clearDenominator p))@UP)
+ => RPrim(1, a, q)
+ c := d := squareFreePart a
+ q := clearDenominator q monomial(inv(d::RF), 1)
+ while not ground?(a := retract(leadingCoefficient q)@UP) repeat
+ c := c * (d := gcd(a, d))
+ q := clearDenominator q monomial(inv(d::RF), 1)
+ RPrim(c, a, q)
+
+ RPrim(c, a, q) ==
+-- one? a => [c::RF, q]
+ (a = 1) => [c::RF, q]
+ [(a * c)::RF, clearDenominator q monomial(inv(a::RF), 1)]
+
+-- always makes the algebraic integral, but does not send a point to infinity
+-- if the integrand does not have a pole there (in the case of an nth-root)
+ chvar(f, modulus) ==
+ r1 := mkIntegral modulus
+ f1 := f monomial(r1inv := inv(r1.coef), 1)
+ infIntegral?(f1, r1.poly) =>
+ [f1, r1.poly, monomial(1,1)$UP :: RF,r1inv,degree(retract(r1.coef)@UP)]
+ x := (a:= goodPoint(f1,r1.poly))::UP::RF + inv(monomial(1,1)::RF)
+ r2c:= retract((r2 := mkIntegral map(#1 x, r1.poly)).coef)@UP
+ t := inv((monomial(1, 1)$UP - a::UP)::RF)
+ [- inv(monomial(1, 2)$UP :: RF) * eval(f1, x, inv(r2.coef)),
+ r2.poly, t, r1.coef * r2c t, degree r2c]
+
+-- returns true if y is an n-th root, and it can be guaranteed that p(x,y)dx
+-- is integral at infinity
+-- expects y to be integral.
+ infIntegral?(p, modulus) ==
+ (r := radPoly modulus) case "failed" => false
+ ninv := inv(r.deg::Q)
+ degy:Q := degree(retract(r.radicand)@UP) * ninv
+ degp:Q := 0
+ while p ^= 0 repeat
+ c := leadingCoefficient p
+ degp := max(degp,
+ (2 + degree(numer c)::Z - degree(denom c)::Z)::Q + degree(p) * degy)
+ p := reductum p
+ degp <= ninv
+
+ mkIntegral p ==
+ (r := radPoly p) case "failed" => algPoly p
+ rp := rootPoly(r.radicand, r.deg)
+ [rp.coef, monomial(1, rp.exponent)$UPUP - rp.radicand::RF::UPUP]
+
+ goodPoint(p, modulus) ==
+ q :=
+ (r := radPoly modulus) case "failed" =>
+ retract(resultant(modulus, differentiate modulus))@UP
+ retract(r.radicand)@UP
+ d := commonDenominator p
+ for i in 0.. repeat
+ good?(a := i::F, q, d) => return a
+ good?(-a, q, d) => return -a
+
+ radPoly p ==
+ (r := retractIfCan(reductum p)@Union(RF, "failed")) case "failed"
+ => "failed"
+ [- (r::RF), degree p]
+
+-- we have y**m = g(x) = n(x)/d(x), so if we can write
+-- (n(x) * d(x)**(m-1)) ** (1/m) = c(x) * P(x) ** (1/n)
+-- then z**q = P(x) where z = (d(x) / c(x)) * y
+ rootPoly(g, m) ==
+ zero? g => error "Should not happen"
+ pr := nthRoot(squareFree((numer g) * (d := denom g) ** (m-1)::N),
+ m)$FactoredFunctions(UP)
+ [pr.exponent, d / pr.coef, */(pr.radicand)]
+
+@
+\section{domain RADFF RadicalFunctionField}
+<<domain RADFF RadicalFunctionField>>=
+)abbrev domain RADFF RadicalFunctionField
+++ Function field defined by y**n = f(x)
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 27 July 1993
+++ Keywords: algebraic, curve, radical, function, field.
+++ Description: Function field defined by y**n = f(x);
+++ Examples: )r RADFF INPUT
+RadicalFunctionField(F, UP, UPUP, radicnd, n): Exports == Impl where
+ F : UniqueFactorizationDomain
+ UP : UnivariatePolynomialCategory F
+ UPUP : UnivariatePolynomialCategory Fraction UP
+ radicnd : Fraction UP
+ n : NonNegativeInteger
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ QF ==> Fraction UPUP
+ UP2 ==> SparseUnivariatePolynomial UP
+ REC ==> Record(factor:UP, exponent:Z)
+ MOD ==> monomial(1, n)$UPUP - radicnd::UPUP
+ INIT ==> if (deref brandNew?) then startUp false
+
+ Exports ==> FunctionFieldCategory(F, UP, UPUP)
+
+ Impl ==> SimpleAlgebraicExtension(RF, UPUP, MOD) add
+ import ChangeOfVariable(F, UP, UPUP)
+ import InnerCommonDenominator(UP, RF, Vector UP, Vector RF)
+ import UnivariatePolynomialCategoryFunctions2(RF, UPUP, UP, UP2)
+
+ diag : Vector RF -> Vector $
+ startUp : Boolean -> Void
+ fullVector : (Factored UP, N) -> PrimitiveArray UP
+ iBasis : (UP, N) -> Vector UP
+ inftyBasis : (RF, N) -> Vector RF
+ basisvec : () -> Vector RF
+ char0StartUp: () -> Void
+ charPStartUp: () -> Void
+ getInfBasis : () -> Void
+ radcand : () -> UP
+ charPintbas : (UPUP, RF, Vector RF, Vector RF) -> Void
+
+ brandNew?:Reference(Boolean) := ref true
+ discPoly:Reference(RF) := ref(0$RF)
+ newrad:Reference(UP) := ref(0$UP)
+ n1 := (n - 1)::N
+ modulus := MOD
+ ibasis:Vector(RF) := new(n, 0)
+ invibasis:Vector(RF) := new(n, 0)
+ infbasis:Vector(RF) := new(n, 0)
+ invinfbasis:Vector(RF):= new(n, 0)
+ mini := minIndex ibasis
+
+ discriminant() == (INIT; discPoly())
+ radcand() == (INIT; newrad())
+ integralBasis() == (INIT; diag ibasis)
+ integralBasisAtInfinity() == (INIT; diag infbasis)
+ basisvec() == (INIT; ibasis)
+ integralMatrix() == diagonalMatrix basisvec()
+ integralMatrixAtInfinity() == (INIT; diagonalMatrix infbasis)
+ inverseIntegralMatrix() == (INIT; diagonalMatrix invibasis)
+ inverseIntegralMatrixAtInfinity()==(INIT;diagonalMatrix invinfbasis)
+ definingPolynomial() == modulus
+ ramified?(point:F) == zero?(radcand() point)
+ branchPointAtInfinity?() == (degree(radcand()) exquo n) case "failed"
+ elliptic() == (n = 2 and degree(radcand()) = 3 => radcand(); "failed")
+ hyperelliptic() == (n=2 and odd? degree(radcand()) => radcand(); "failed")
+ diag v == [reduce monomial(qelt(v,i+mini), i) for i in 0..n1]
+
+ integralRepresents(v, d) ==
+ ib := basisvec()
+ represents
+ [qelt(ib, i) * (qelt(v, i) /$RF d) for i in mini .. maxIndex ib]
+
+ integralCoordinates f ==
+ v := coordinates f
+ ib := basisvec()
+ splitDenominator
+ [qelt(v,i) / qelt(ib,i) for i in mini .. maxIndex ib]$Vector(RF)
+
+ integralDerivationMatrix d ==
+ dlogp := differentiate(radicnd, d) / (n * radicnd)
+ v := basisvec()
+ cd := splitDenominator(
+ [(i - mini) * dlogp + differentiate(qelt(v, i), d) / qelt(v, i)
+ for i in mini..maxIndex v]$Vector(RF))
+ [diagonalMatrix(cd.num), cd.den]
+
+-- return (d0,...,d(n-1)) s.t. (1/d0, y/d1,...,y**(n-1)/d(n-1))
+-- is an integral basis for the curve y**d = p
+-- requires that p has no factor of multiplicity >= d
+ iBasis(p, d) ==
+ pl := fullVector(squareFree p, d)
+ d1 := (d - 1)::N
+ [*/[pl.j ** ((i * j) quo d) for j in 0..d1] for i in 0..d1]
+
+-- returns a vector [a0,a1,...,a_{m-1}] of length m such that
+-- p = a0^0 a1^1 ... a_{m-1}^{m-1}
+ fullVector(p, m) ==
+ ans:PrimitiveArray(UP) := new(m, 0)
+ ans.0 := unit p
+ l := factors p
+ for i in 1..maxIndex ans repeat
+ ans.i :=
+ (u := find(#1.exponent = i, l)) case "failed" => 1
+ (u::REC).factor
+ ans
+
+-- return (f0,...,f(n-1)) s.t. (f0, y f1,..., y**(n-1) f(n-1))
+-- is a local integral basis at infinity for the curve y**d = p
+ inftyBasis(p, m) ==
+ rt := rootPoly(p(x := inv(monomial(1, 1)$UP :: RF)), m)
+ m ^= rt.exponent =>
+ error "Curve not irreducible after change of variable 0 -> infinity"
+ a := (rt.coef) x
+ b:RF := 1
+ v := iBasis(rt.radicand, m)
+ w:Vector(RF) := new(m, 0)
+ for i in mini..maxIndex v repeat
+ qsetelt_!(w, i, b / ((qelt(v, i)::RF) x))
+ b := b * a
+ w
+
+ charPintbas(p, c, v, w) ==
+ degree(p) ^= n => error "charPintbas: should not happen"
+ q:UP2 := map(retract(#1)@UP, p)
+ ib := integralBasis()$FunctionFieldIntegralBasis(UP, UP2,
+ SimpleAlgebraicExtension(UP, UP2, q))
+ not diagonal?(ib.basis)=> error "charPintbas: integral basis not diagonal"
+ a:RF := 1
+ for i in minRowIndex(ib.basis) .. maxRowIndex(ib.basis)
+ for j in minColIndex(ib.basis) .. maxColIndex(ib.basis)
+ for k in mini .. maxIndex v repeat
+ qsetelt_!(v, k, (qelt(ib.basis, i, j) / ib.basisDen) * a)
+ qsetelt_!(w, k, qelt(ib.basisInv, i, j) * inv a)
+ a := a * c
+ void
+
+ charPStartUp() ==
+ r := mkIntegral modulus
+ charPintbas(r.poly, r.coef, ibasis, invibasis)
+ x := inv(monomial(1, 1)$UP :: RF)
+ invmod := monomial(1, n)$UPUP - (radicnd x)::UPUP
+ r := mkIntegral invmod
+ charPintbas(r.poly, (r.coef) x, infbasis, invinfbasis)
+
+ startUp b ==
+ brandNew?() := b
+ if zero?(p := characteristic()$F) or p > n then char0StartUp()
+ else charPStartUp()
+ dsc:RF := ((-1)$Z ** ((n *$N n1) quo 2::N) * (n::Z)**n)$Z *
+ radicnd ** n1 *
+ */[qelt(ibasis, i) ** 2 for i in mini..maxIndex ibasis]
+ discPoly() := primitivePart(numer dsc) / denom(dsc)
+ void
+
+ char0StartUp() ==
+ rp := rootPoly(radicnd, n)
+ rp.exponent ^= n => error "RadicalFunctionField: curve is not irreducible"
+ newrad() := rp.radicand
+ ib := iBasis(newrad(), n)
+ infb := inftyBasis(radicnd, n)
+ invden:RF := 1
+ for i in mini..maxIndex ib repeat
+ qsetelt_!(invibasis, i, a := qelt(ib, i) * invden)
+ qsetelt_!(ibasis, i, inv a)
+ invden := invden / rp.coef -- always equals 1/rp.coef**(i-mini)
+ qsetelt_!(infbasis, i, a := qelt(infb, i))
+ qsetelt_!(invinfbasis, i, inv a)
+ void
+
+ ramified?(p:UP) ==
+ (r := retractIfCan(p)@Union(F, "failed")) case F =>
+ singular?(r::F)
+ (radcand() exquo p) case UP
+
+ singular?(p:UP) ==
+ (r := retractIfCan(p)@Union(F, "failed")) case F =>
+ singular?(r::F)
+ (radcand() exquo(p**2)) case UP
+
+ branchPoint?(p:UP) ==
+ (r := retractIfCan(p)@Union(F, "failed")) case F =>
+ branchPoint?(r::F)
+ ((q := (radcand() exquo p)) case UP) and
+ ((q::UP exquo p) case "failed")
+
+ singular?(point:F) ==
+ zero?(radcand() point) and
+ zero?(((radcand() exquo (monomial(1,1)$UP-point::UP))::UP) point)
+
+ branchPoint?(point:F) ==
+ zero?(radcand() point) and not
+ zero?(((radcand() exquo (monomial(1,1)$UP-point::UP))::UP) point)
+
+@
+\section{domain ALGFF AlgebraicFunctionField}
+<<domain ALGFF AlgebraicFunctionField>>=
+)abbrev domain ALGFF AlgebraicFunctionField
+++ Function field defined by f(x, y) = 0
+++ Author: Manuel Bronstein
+++ Date Created: 3 May 1988
+++ Date Last Updated: 24 Jul 1990
+++ Keywords: algebraic, curve, function, field.
+++ Description: Function field defined by f(x, y) = 0.
+++ Examples: )r ALGFF INPUT
+AlgebraicFunctionField(F, UP, UPUP, modulus): Exports == Impl where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ UPUP : UnivariatePolynomialCategory Fraction UP
+ modulus: UPUP
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ QF ==> Fraction UPUP
+ UP2 ==> SparseUnivariatePolynomial UP
+ SAE ==> SimpleAlgebraicExtension(RF, UPUP, modulus)
+ INIT ==> if (deref brandNew?) then startUp false
+
+ Exports ==> FunctionFieldCategory(F, UP, UPUP) with
+ knownInfBasis: N -> Void
+ ++ knownInfBasis(n) \undocumented{}
+
+ Impl ==> SAE add
+ import ChangeOfVariable(F, UP, UPUP)
+ import InnerCommonDenominator(UP, RF, Vector UP, Vector RF)
+ import MatrixCommonDenominator(UP, RF)
+ import UnivariatePolynomialCategoryFunctions2(RF, UPUP, UP, UP2)
+
+ startUp : Boolean -> Void
+ vect : Matrix RF -> Vector $
+ getInfBasis: () -> Void
+
+ brandNew?:Reference(Boolean) := ref true
+ infBr?:Reference(Boolean) := ref true
+ discPoly:Reference(RF) := ref 0
+ n := degree modulus
+ n1 := (n - 1)::N
+ ibasis:Matrix(RF) := zero(n, n)
+ invibasis:Matrix(RF) := copy ibasis
+ infbasis:Matrix(RF) := copy ibasis
+ invinfbasis:Matrix(RF):= copy ibasis
+
+ branchPointAtInfinity?() == (INIT; infBr?())
+ discriminant() == (INIT; discPoly())
+ integralBasis() == (INIT; vect ibasis)
+ integralBasisAtInfinity() == (INIT; vect infbasis)
+ integralMatrix() == (INIT; ibasis)
+ inverseIntegralMatrix() == (INIT; invibasis)
+ integralMatrixAtInfinity() == (INIT; infbasis)
+ branchPoint?(a:F) == zero?((retract(discriminant())@UP) a)
+ definingPolynomial() == modulus
+ inverseIntegralMatrixAtInfinity() == (INIT; invinfbasis)
+
+ vect m ==
+ [represents row(m, i) for i in minRowIndex m .. maxRowIndex m]
+
+ integralCoordinates f ==
+ splitDenominator(coordinates(f) * inverseIntegralMatrix())
+
+ knownInfBasis d ==
+ if deref brandNew? then
+ alpha := [monomial(1, d * i)$UP :: RF for i in 0..n1]$Vector(RF)
+ ib := diagonalMatrix
+ [inv qelt(alpha, i) for i in minIndex alpha .. maxIndex alpha]
+ invib := diagonalMatrix alpha
+ for i in minRowIndex ib .. maxRowIndex ib repeat
+ for j in minColIndex ib .. maxColIndex ib repeat
+ infbasis(i, j) := qelt(ib, i, j)
+ invinfbasis(i, j) := invib(i, j)
+ void
+
+ getInfBasis() ==
+ x := inv(monomial(1, 1)$UP :: RF)
+ invmod := map(#1 x, modulus)
+ r := mkIntegral invmod
+ degree(r.poly) ^= n => error "Should not happen"
+ ninvmod:UP2 := map(retract(#1)@UP, r.poly)
+ alpha := [(r.coef ** i) x for i in 0..n1]$Vector(RF)
+ invalpha := [inv qelt(alpha, i)
+ for i in minIndex alpha .. maxIndex alpha]$Vector(RF)
+ invib := integralBasis()$FunctionFieldIntegralBasis(UP, UP2,
+ SimpleAlgebraicExtension(UP, UP2, ninvmod))
+ for i in minRowIndex ibasis .. maxRowIndex ibasis repeat
+ for j in minColIndex ibasis .. maxColIndex ibasis repeat
+ infbasis(i, j) := ((invib.basis)(i,j) / invib.basisDen) x
+ invinfbasis(i, j) := ((invib.basisInv) (i, j)) x
+ ib2 := infbasis * diagonalMatrix alpha
+ invib2 := diagonalMatrix(invalpha) * invinfbasis
+ for i in minRowIndex ib2 .. maxRowIndex ib2 repeat
+ for j in minColIndex ibasis .. maxColIndex ibasis repeat
+ infbasis(i, j) := qelt(ib2, i, j)
+ invinfbasis(i, j) := invib2(i, j)
+ void
+
+ startUp b ==
+ brandNew?() := b
+ nmod:UP2 := map(retract, modulus)
+ ib := integralBasis()$FunctionFieldIntegralBasis(UP, UP2,
+ SimpleAlgebraicExtension(UP, UP2, nmod))
+ for i in minRowIndex ibasis .. maxRowIndex ibasis repeat
+ for j in minColIndex ibasis .. maxColIndex ibasis repeat
+ qsetelt_!(ibasis, i, j, (ib.basis)(i, j) / ib.basisDen)
+ invibasis(i, j) := ((ib.basisInv) (i, j))::RF
+ if zero?(infbasis(minRowIndex infbasis, minColIndex infbasis))
+ then getInfBasis()
+ ib2 := coordinates normalizeAtInfinity vect ibasis
+ invib2 := inverse(ib2)::Matrix(RF)
+ for i in minRowIndex ib2 .. maxRowIndex ib2 repeat
+ for j in minColIndex ib2 .. maxColIndex ib2 repeat
+ ibasis(i, j) := qelt(ib2, i, j)
+ invibasis(i, j) := invib2(i, j)
+ dsc := resultant(modulus, differentiate modulus)
+ dsc0 := dsc * determinant(infbasis) ** 2
+ degree(numer dsc0) > degree(denom dsc0) =>error "Shouldn't happen"
+ infBr?() := degree(numer dsc0) < degree(denom dsc0)
+ dsc := dsc * determinant(ibasis) ** 2
+ discPoly() := primitivePart(numer dsc) / denom(dsc)
+ void
+
+ integralDerivationMatrix d ==
+ w := integralBasis()
+ splitDenominator(coordinates([differentiate(w.i, d)
+ for i in minIndex w .. maxIndex w]$Vector($))
+ * inverseIntegralMatrix())
+
+ integralRepresents(v, d) ==
+ represents(coordinates(represents(v, d)) * integralMatrix())
+
+ branchPoint?(p:UP) ==
+ INIT
+ (r:=retractIfCan(p)@Union(F,"failed")) case F =>branchPoint?(r::F)
+ not ground? gcd(retract(discriminant())@UP, p)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf CURVE curvepkg divisor pfo
+-- intalg intaf efstruc rdeef intef irexpand integrat
+
+<<category FFCAT FunctionFieldCategory>>
+<<package MMAP MultipleMap>>
+<<package FFCAT2 FunctionFieldCategoryFunctions2>>
+<<package CHVAR ChangeOfVariable>>
+<<domain RADFF RadicalFunctionField>>
+<<domain ALGFF AlgebraicFunctionField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/cycles.spad.pamphlet b/src/algebra/cycles.spad.pamphlet
new file mode 100644
index 00000000..d5747f52
--- /dev/null
+++ b/src/algebra/cycles.spad.pamphlet
@@ -0,0 +1,323 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra cycles.spad}
+\author{William Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package CYCLES CycleIndicators}
+<<package CYCLES CycleIndicators>>=
+)abbrev package CYCLES CycleIndicators
+++ Polya-Redfield enumeration by cycle indices.
+++ Author: William H. Burge
+++ Date Created: 1986
+++ Date Last Updated: 11 Feb 1992
+++ Keywords:Polya, Redfield, enumeration
+++ Examples:
+++ References: J.H.Redfield, 'The Theory of Group-Reduced Distributions',
+++ American J. Math., 49 (1927) 433-455.
+++ G.Polya, 'Kombinatorische Anzahlbestimmungen fur Gruppen,
+++ Graphen und chemische Verbindungen', Acta Math. 68
+++ (1937) 145-254.
+++ Description: Enumeration by cycle indices.
+CycleIndicators: Exports == Implementation where
+ I ==> Integer
+ L ==> List
+ B ==> Boolean
+ SPOL ==> SymmetricPolynomial
+ PTN ==> Partition
+ RN ==> Fraction Integer
+ FR ==> Factored Integer
+ h ==> complete
+ s ==> powerSum
+ --a ==> elementary
+ alt ==> alternating
+ cyc ==> cyclic
+ dih ==> dihedral
+ ev == eval
+ Exports ==> with
+
+ complete: I -> SPOL RN
+ ++\spad{complete n} is the \spad{n} th complete homogeneous
+ ++ symmetric function expressed in terms of power sums.
+ ++ Alternatively it is the cycle index of the symmetric
+ ++ group of degree n.
+
+ powerSum: I -> SPOL RN
+ ++\spad{powerSum n} is the \spad{n} th power sum symmetric
+ ++ function.
+
+ elementary: I -> SPOL RN
+ ++\spad{elementary n} is the \spad{n} th elementary symmetric
+ ++ function expressed in terms of power sums.
+
+ -- s2h: I -> SPOL RN--s to h
+
+ alternating: I -> SPOL RN
+ ++\spad{alternating n} is the cycle index of the
+ ++ alternating group of degree n.
+
+ cyclic: I -> SPOL RN --cyclic group
+ ++\spad{cyclic n} is the cycle index of the
+ ++ cyclic group of degree n.
+
+ dihedral: I -> SPOL RN --dihedral group
+ ++\spad{dihedral n} is the cycle index of the
+ ++ dihedral group of degree n.
+
+ graphs: I -> SPOL RN
+ ++\spad{graphs n} is the cycle index of the group induced on
+ ++ the edges of a graph by applying the symmetric function to the
+ ++ n nodes.
+
+ cap: (SPOL RN,SPOL RN) -> RN
+ ++\spad{cap(s1,s2)}, introduced by Redfield,
+ ++ is the scalar product of two cycle indices.
+
+ cup: (SPOL RN,SPOL RN) -> SPOL RN
+ ++\spad{cup(s1,s2)}, introduced by Redfield,
+ ++ is the scalar product of two cycle indices, in which the
+ ++ power sums are retained to produce a cycle index.
+
+ eval: SPOL RN -> RN
+ ++\spad{eval s} is the sum of the coefficients of a cycle index.
+
+ wreath: (SPOL RN,SPOL RN) -> SPOL RN
+ ++\spad{wreath(s1,s2)} is the cycle index of the wreath product
+ ++ of the two groups whose cycle indices are \spad{s1} and
+ ++ \spad{s2}.
+
+ SFunction:L I -> SPOL RN
+ ++\spad{SFunction(li)} is the S-function of the partition \spad{li}
+ ++ expressed in terms of power sum symmetric functions.
+
+ skewSFunction:(L I,L I) -> SPOL RN
+ ++\spad{skewSFunction(li1,li2)} is the S-function
+ ++ of the partition difference \spad{li1 - li2}
+ ++ expressed in terms of power sum symmetric functions.
+
+ Implementation ==> add
+ import PartitionsAndPermutations
+ import IntegerNumberTheoryFunctions
+
+ trm: PTN -> SPOL RN
+ trm pt == monomial(inv(pdct(pt) :: RN),pt)
+
+ list: Stream L I -> L L I
+ list st == entries complete st
+
+ complete i ==
+ if i=0
+ then 1
+ else if i<0
+ then 0
+ else
+ _+/[trm(partition pt) for pt in list(partitions i)]
+
+
+ even?: L I -> B
+ even? li == even?( #([i for i in li | even? i]))
+
+ alt i ==
+ 2 * _+/[trm(partition li) for li in list(partitions i) | even? li]
+ elementary i ==
+ if i=0
+ then 1
+ else if i<0
+ then 0
+ else
+ _+/[(spol := trm(partition pt); even? pt => spol; -spol)
+ for pt in list(partitions i)]
+
+ divisors: I -> L I
+ divisors n ==
+ b := factors(n :: FR)
+ c := concat(1,"append"/
+ [[a.factor**j for j in 1..a.exponent] for a in b]);
+ if #(b) = 1 then c else concat(n,c)
+
+ ss: (I,I) -> SPOL RN
+ ss(n,m) ==
+ li : L I := [n for j in 1..m]
+ monomial(1,partition li)
+
+ s n == ss(n,1)
+
+ cyc n ==
+ n = 1 => s 1
+ _+/[(eulerPhi(i) / n) * ss(i,numer(n/i)) for i in divisors n]
+
+ dih n ==
+ k := n quo 2
+ odd? n => (1/2) * cyc n + (1/2) * ss(2,k) * s 1
+ (1/2) * cyc n + (1/4) * ss(2,k) + (1/4) * ss(2,k-1) * ss(1,2)
+
+ trm2: L I -> SPOL RN
+ trm2 li ==
+ lli := powers(li)$PTN
+ xx := 1/(pdct partition li)
+ prod : SPOL RN := 1
+ for ll in lli repeat
+ ll0 := first ll; ll1 := second ll
+ k := ll0 quo 2
+ c :=
+ odd? ll0 => ss(ll0,ll1 * k)
+ ss(k,ll1) * ss(ll0,ll1 * (k - 1))
+ c := c * ss(ll0,ll0 * ((ll1*(ll1 - 1)) quo 2))
+ prod2 : SPOL RN := 1
+ for r in lli | first(r) < ll0 repeat
+ r0 := first r; r1 := second r
+ prod2 := ss(lcm(r0,ll0),gcd(r0,ll0) * r1 * ll1) * prod2
+ prod := c * prod2 * prod
+ xx * prod
+
+ graphs n == _+/[trm2 li for li in list(partitions n)]
+
+ cupp: (PTN,SPOL RN) -> SPOL RN
+ cupp(pt,spol) ==
+ zero? spol => 0
+ (dg := degree spol) < pt => 0
+ dg = pt => (pdct pt) * monomial(leadingCoefficient spol,dg)
+ cupp(pt,reductum spol)
+
+ cup(spol1,spol2) ==
+ zero? spol1 => 0
+ p := leadingCoefficient(spol1) * cupp(degree spol1,spol2)
+ p + cup(reductum spol1,spol2)
+
+ ev spol ==
+ zero? spol => 0
+ leadingCoefficient(spol) + ev(reductum spol)
+
+ cap(spol1,spol2) == ev cup(spol1,spol2)
+
+ mtpol: (I,SPOL RN) -> SPOL RN
+ mtpol(n,spol)==
+ zero? spol => 0
+ deg := partition [n*k for k in (degree spol)::L(I)]
+ monomial(leadingCoefficient spol,deg) + mtpol(n,reductum spol)
+
+ fn2: I -> SPOL RN
+ evspol: ((I -> SPOL RN),SPOL RN) -> SPOL RN
+ evspol(fn2,spol) ==
+ zero? spol => 0
+ lc := leadingCoefficient spol
+ prod := _*/[fn2 i for i in (degree spol)::L(I)]
+ lc * prod + evspol(fn2,reductum spol)
+
+ wreath(spol1,spol2) == evspol(mtpol(#1,spol2),spol1)
+
+ hh: I -> SPOL RN --symmetric group
+ hh n == if n=0 then 1 else if n<0 then 0 else h n
+ SFunction li==
+ a:Matrix SPOL RN:=matrix [[hh(k -j+i) for k in li for j in 1..#li]
+ for i in 1..#li]
+ determinant a
+
+ roundup:(L I,L I)-> L I
+ roundup(li1,li2)==
+ #li1 > #li2 => roundup(li1,concat(li2,0))
+ li2
+
+ skewSFunction(li1,li2)==
+ #li1 < #li2 =>
+ error "skewSFunction: partition1 does not include partition2"
+ li2:=roundup (li1,li2)
+ a:Matrix SPOL RN:=matrix [[hh(k-li2.i-j+i)
+ for k in li1 for j in 1..#li1] for i in 1..#li1]
+ determinant a
+
+@
+\section{package EVALCYC EvaluateCycleIndicators}
+<<package EVALCYC EvaluateCycleIndicators>>=
+)abbrev package EVALCYC EvaluateCycleIndicators
+++ Author: William H. Burge
+++ Date Created: 1986
+++ Date Last Updated: Feb 1992
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: This package is to be used in conjuction with
+++ the CycleIndicators package. It provides an evaluation
+++ function for SymmetricPolynomials.
+EvaluateCycleIndicators(F):T==C where
+ F:Algebra Fraction Integer
+ I==>Integer
+ L==>List
+ SPOL==SymmetricPolynomial
+ RN==>Fraction Integer
+ PR==>Polynomial(RN)
+ PTN==>Partition()
+ lc ==> leadingCoefficient
+ red ==> reductum
+ T== with
+ eval:((I->F),SPOL RN)->F
+ ++\spad{eval(f,s)} evaluates the cycle index s by applying
+ ++ the function f to each integer in a monomial partition,
+ ++ forms their product and sums the results over all monomials.
+ C== add
+ evp:((I->F),PTN)->F
+ fn:I->F
+ pt:PTN
+ spol:SPOL RN
+ i:I
+ evp(fn, pt)== _*/[fn i for i in pt::(L I)]
+
+ eval(fn,spol)==
+ if spol=0
+ then 0
+ else ((lc spol)* evp(fn,degree spol)) + eval(fn,red spol)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package CYCLES CycleIndicators>>
+<<package EVALCYC EvaluateCycleIndicators>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/cyclotom.spad.pamphlet b/src/algebra/cyclotom.spad.pamphlet
new file mode 100644
index 00000000..1d8c77df
--- /dev/null
+++ b/src/algebra/cyclotom.spad.pamphlet
@@ -0,0 +1,109 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra cyclotom.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package CYCLOTOM CyclotomicPolynomialPackage}
+<<package CYCLOTOM CyclotomicPolynomialPackage>>=
+)abbrev package CYCLOTOM CyclotomicPolynomialPackage
+++ This package \undocumented{}
+CyclotomicPolynomialPackage: public == private where
+ SUP ==> SparseUnivariatePolynomial(Integer)
+ LSUP ==> List(SUP)
+ NNI ==> NonNegativeInteger
+ FR ==> Factored SUP
+ IFP ==> IntegerFactorizationPackage Integer
+
+ public == with
+ cyclotomicDecomposition: Integer -> LSUP
+ ++ cyclotomicDecomposition(n) \undocumented{}
+ cyclotomic: Integer -> SUP
+ ++ cyclotomic(n) \undocumented{}
+ cyclotomicFactorization: Integer -> FR
+ ++ cyclotomicFactorization(n) \undocumented{}
+
+ private == add
+ cyclotomic(n:Integer): SUP ==
+ x,y,z,l: SUP
+ g := factors factor(n)$IFP
+ --Now, for each prime in the factorization apply recursion
+ l := monomial(1,1) - monomial(1,0)
+ for u in g repeat
+ l := (monicDivide(multiplyExponents(l,u.factor::NNI),l)).quotient
+ if u.exponent>1 then
+ l := multiplyExponents(l,((u.factor)**((u.exponent-1)::NNI))::NNI)
+ l
+
+ cyclotomicDecomposition(n:Integer):LSUP ==
+ x,y,z: SUP
+ l,ll,m: LSUP
+ rr: Integer
+ g := factors factor(n)$IFP
+ l := [monomial(1,1) - monomial(1,0)]
+ --Now, for each prime in the factorization apply recursion
+ for u in g repeat
+ m := [(monicDivide(
+ multiplyExponents(z,u.factor::NNI),z)).quotient for z in l]
+ for rr in 1..(u.exponent-1) repeat
+ l := append(l,m)
+ m := [multiplyExponents(z,u.factor::NNI) for z in m]
+ l := append(l,m)
+ l
+
+ cyclotomicFactorization(n:Integer):FR ==
+ f : SUP
+ fr : FR := 1$FR
+ for f in cyclotomicDecomposition(n) repeat
+ fr := fr * primeFactor(f,1$Integer)
+ fr
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package CYCLOTOM CyclotomicPolynomialPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d01.spad.pamphlet b/src/algebra/d01.spad.pamphlet
new file mode 100644
index 00000000..d3770e1b
--- /dev/null
+++ b/src/algebra/d01.spad.pamphlet
@@ -0,0 +1,447 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d01.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGD01 NagIntegrationPackage}
+<<package NAGD01 NagIntegrationPackage>>=
+)abbrev package NAGD01 NagIntegrationPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:37 1994
+++Description:
+++This package uses the NAG Library to calculate the numerical value of
+++definite integrals in one or more dimensions and to evaluate
+++weights and abscissae of integration rules.
+++See \downlink{Manual Page}{manpageXXd01}.
+
+NagIntegrationPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ d01ajf : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(F))) -> Result
+ ++ d01ajf(a,b,epsabs,epsrel,lw,liw,ifail,f)
+ ++ is a general-purpose integrator which calculates an
+ ++ approximation to the integral of a function f(x) over a finite
+ ++ interval [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01ajf}.
+ d01akf : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(F))) -> Result
+ ++ d01akf(a,b,epsabs,epsrel,lw,liw,ifail,f)
+ ++ is an adaptive integrator, especially suited to
+ ++ oscillating, non-singular integrands, which calculates an
+ ++ approximation to the integral of a function f(x) over a finite
+ ++ interval [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01akf}.
+ d01alf : (DoubleFloat,DoubleFloat,Integer,Matrix DoubleFloat,_
+ DoubleFloat,DoubleFloat,Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(F))) -> Result
+ ++ d01alf(a,b,npts,points,epsabs,epsrel,lw,liw,ifail,f)
+ ++ is a general purpose integrator which calculates an
+ ++ approximation to the integral of a function f(x) over a finite
+ ++ interval [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01alf}.
+ d01amf : (DoubleFloat,Integer,DoubleFloat,DoubleFloat,_
+ Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(F))) -> Result
+ ++ d01amf(bound,inf,epsabs,epsrel,lw,liw,ifail,f)
+ ++ calculates an approximation to the integral of a function
+ ++ f(x) over an infinite or semi-infinite interval [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01amf}.
+ d01anf : (DoubleFloat,DoubleFloat,DoubleFloat,Integer,_
+ DoubleFloat,DoubleFloat,Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(G))) -> Result
+ ++ d01anf(a,b,omega,key,epsabs,epsrel,lw,liw,ifail,g)
+ ++ calculates an approximation to the sine or the cosine
+ ++ transform of a function g over [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01anf}.
+ d01apf : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ Integer,DoubleFloat,DoubleFloat,Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(G))) -> Result
+ ++ d01apf(a,b,alfa,beta,key,epsabs,epsrel,lw,liw,ifail,g)
+ ++ is an adaptive integrator which calculates an
+ ++ approximation to the integral of a function g(x)w(x) over a
+ ++ finite interval [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01apf}.
+ d01aqf : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ DoubleFloat,Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(G))) -> Result
+ ++ d01aqf(a,b,c,epsabs,epsrel,lw,liw,ifail,g)
+ ++ calculates an approximation to the Hilbert transform of a
+ ++ function g(x) over [a,b]:
+ ++ See \downlink{Manual Page}{manpageXXd01aqf}.
+ d01asf : (DoubleFloat,DoubleFloat,Integer,DoubleFloat,_
+ Integer,Integer,Integer,Integer,Union(fn:FileName,fp:Asp1(G))) -> Result
+ ++ d01asf(a,omega,key,epsabs,limlst,lw,liw,ifail,g)
+ ++ calculates an approximation to the sine or the cosine
+ ++ transform of a function g over [a,infty):
+ ++ See \downlink{Manual Page}{manpageXXd01asf}.
+ d01bbf : (DoubleFloat,DoubleFloat,Integer,Integer,_
+ Integer,Integer) -> Result
+ ++ d01bbf(a,b,itype,n,gtype,ifail)
+ ++ returns the weight appropriate to a
+ ++ Gaussian quadrature.
+ ++ The formulae provided are Gauss-Legendre, Gauss-Rational, Gauss-
+ ++ Laguerre and Gauss-Hermite.
+ ++ See \downlink{Manual Page}{manpageXXd01bbf}.
+ d01fcf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer,_
+ DoubleFloat,Integer,Integer,Integer,Union(fn:FileName,fp:Asp4(FUNCTN))) -> Result
+ ++ d01fcf(ndim,a,b,maxpts,eps,lenwrk,minpts,ifail,functn)
+ ++ attempts to evaluate a multi-dimensional integral (up to
+ ++ 15 dimensions), with constant and finite limits, to a specified
+ ++ relative accuracy, using an adaptive subdivision strategy.
+ ++ See \downlink{Manual Page}{manpageXXd01fcf}.
+ d01gaf : (Matrix DoubleFloat,Matrix DoubleFloat,Integer,Integer) -> Result
+ ++ d01gaf(x,y,n,ifail)
+ ++ integrates a function which is specified numerically at
+ ++ four or more points, over the whole of its specified range, using
+ ++ third-order finite-difference formulae with error estimates,
+ ++ according to a method due to Gill and Miller.
+ ++ See \downlink{Manual Page}{manpageXXd01gaf}.
+ d01gbf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer,_
+ DoubleFloat,Integer,Integer,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp4(FUNCTN))) -> Result
+ ++ d01gbf(ndim,a,b,maxcls,eps,lenwrk,mincls,wrkstr,ifail,functn)
+ ++ returns an approximation to the integral of a function
+ ++ over a hyper-rectangular region, using a Monte Carlo method. An
+ ++ approximate relative error estimate is also returned. This
+ ++ routine is suitable for low accuracy work.
+ ++ See \downlink{Manual Page}{manpageXXd01gbf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import FortranPackage
+ import Union(fn:FileName,fp:Asp1(F))
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(Matrix DoubleFloat)
+
+
+ d01ajf(aArg:DoubleFloat,bArg:DoubleFloat,epsabsArg:DoubleFloat,_
+ epsrelArg:DoubleFloat,lwArg:Integer,liwArg:Integer,_
+ ifailArg:Integer,fArg:Union(fn:FileName,fp:Asp1(F))): Result ==
+ pushFortranOutputStack(fFilename := aspFilename "f")$FOP
+ if fArg case fn
+ then outputAsFortran(fArg.fn)
+ else outputAsFortran(fArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fFilename]$Lisp,_
+ "d01ajf",_
+ ["a"::S,"b"::S,"epsabs"::S,"epsrel"::S,"lw"::S_
+ ,"liw"::S,"result"::S,"abserr"::S,"ifail"::S,"f"::S_
+ ,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"f"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"epsabs"::S,"epsrel"::S_
+ ,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"f"::S]$Lisp_
+ ,["integer"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01akf(aArg:DoubleFloat,bArg:DoubleFloat,epsabsArg:DoubleFloat,_
+ epsrelArg:DoubleFloat,lwArg:Integer,liwArg:Integer,_
+ ifailArg:Integer,fArg:Union(fn:FileName,fp:Asp1(F))): Result ==
+ pushFortranOutputStack(fFilename := aspFilename "f")$FOP
+ if fArg case fn
+ then outputAsFortran(fArg.fn)
+ else outputAsFortran(fArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fFilename]$Lisp,_
+ "d01akf",_
+ ["a"::S,"b"::S,"epsabs"::S,"epsrel"::S,"lw"::S_
+ ,"liw"::S,"result"::S,"abserr"::S,"ifail"::S,"f"::S_
+ ,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"f"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"epsabs"::S,"epsrel"::S_
+ ,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"f"::S]$Lisp_
+ ,["integer"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01alf(aArg:DoubleFloat,bArg:DoubleFloat,nptsArg:Integer,_
+ pointsArg:Matrix DoubleFloat,epsabsArg:DoubleFloat,epsrelArg:DoubleFloat,_
+ lwArg:Integer,liwArg:Integer,ifailArg:Integer,_
+ fArg:Union(fn:FileName,fp:Asp1(F))): Result ==
+ pushFortranOutputStack(fFilename := aspFilename "f")$FOP
+ if fArg case fn
+ then outputAsFortran(fArg.fn)
+ else outputAsFortran(fArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fFilename]$Lisp,_
+ "d01alf",_
+ ["a"::S,"b"::S,"npts"::S,"epsabs"::S,"epsrel"::S_
+ ,"lw"::S,"liw"::S,"result"::S,"abserr"::S,"ifail"::S_
+ ,"f"::S,"points"::S,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"f"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,["points"::S,"*"::S]$Lisp_
+ ,"epsabs"::S,"epsrel"::S,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"f"::S]$Lisp_
+ ,["integer"::S,"npts"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,nptsArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any,pointsArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01amf(boundArg:DoubleFloat,infArg:Integer,epsabsArg:DoubleFloat,_
+ epsrelArg:DoubleFloat,lwArg:Integer,liwArg:Integer,_
+ ifailArg:Integer,fArg:Union(fn:FileName,fp:Asp1(F))): Result ==
+ pushFortranOutputStack(fFilename := aspFilename "f")$FOP
+ if fArg case fn
+ then outputAsFortran(fArg.fn)
+ else outputAsFortran(fArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fFilename]$Lisp,_
+ "d01amf",_
+ ["bound"::S,"inf"::S,"epsabs"::S,"epsrel"::S,"lw"::S_
+ ,"liw"::S,"result"::S,"abserr"::S,"ifail"::S,"f"::S_
+ ,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"f"::S]$Lisp,_
+ [["double"::S,"bound"::S,"epsabs"::S,"epsrel"::S_
+ ,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"f"::S]$Lisp_
+ ,["integer"::S,"inf"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([boundArg::Any,infArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01anf(aArg:DoubleFloat,bArg:DoubleFloat,omegaArg:DoubleFloat,_
+ keyArg:Integer,epsabsArg:DoubleFloat,epsrelArg:DoubleFloat,_
+ lwArg:Integer,liwArg:Integer,ifailArg:Integer,_
+ gArg:Union(fn:FileName,fp:Asp1(G))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename]$Lisp,_
+ "d01anf",_
+ ["a"::S,"b"::S,"omega"::S,"key"::S,"epsabs"::S_
+ ,"epsrel"::S,"lw"::S,"liw"::S,"result"::S,"abserr"::S_
+ ,"ifail"::S,"g"::S,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"g"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"omega"::S,"epsabs"::S_
+ ,"epsrel"::S,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"g"::S]$Lisp_
+ ,["integer"::S,"key"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,omegaArg::Any,keyArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01apf(aArg:DoubleFloat,bArg:DoubleFloat,alfaArg:DoubleFloat,_
+ betaArg:DoubleFloat,keyArg:Integer,epsabsArg:DoubleFloat,_
+ epsrelArg:DoubleFloat,lwArg:Integer,liwArg:Integer,_
+ ifailArg:Integer,gArg:Union(fn:FileName,fp:Asp1(G))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename]$Lisp,_
+ "d01apf",_
+ ["a"::S,"b"::S,"alfa"::S,"beta"::S,"key"::S_
+ ,"epsabs"::S,"epsrel"::S,"lw"::S,"liw"::S,"result"::S_
+ ,"abserr"::S,"ifail"::S,"g"::S,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"g"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"alfa"::S,"beta"::S_
+ ,"epsabs"::S,"epsrel"::S,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"g"::S]$Lisp_
+ ,["integer"::S,"key"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,alfaArg::Any,betaArg::Any,keyArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01aqf(aArg:DoubleFloat,bArg:DoubleFloat,cArg:DoubleFloat,_
+ epsabsArg:DoubleFloat,epsrelArg:DoubleFloat,lwArg:Integer,_
+ liwArg:Integer,ifailArg:Integer,gArg:Union(fn:FileName,fp:Asp1(G))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename]$Lisp,_
+ "d01aqf",_
+ ["a"::S,"b"::S,"c"::S,"epsabs"::S,"epsrel"::S_
+ ,"lw"::S,"liw"::S,"result"::S,"abserr"::S,"ifail"::S_
+ ,"g"::S,"w"::S,"iw"::S]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"g"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"c"::S,"epsabs"::S_
+ ,"epsrel"::S,"result"::S,"abserr"::S,["w"::S,"lw"::S]$Lisp,"g"::S]$Lisp_
+ ,["integer"::S,"lw"::S,"liw"::S,["iw"::S,"liw"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"w"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,cArg::Any,epsabsArg::Any,epsrelArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01asf(aArg:DoubleFloat,omegaArg:DoubleFloat,keyArg:Integer,_
+ epsabsArg:DoubleFloat,limlstArg:Integer,lwArg:Integer,_
+ liwArg:Integer,ifailArg:Integer,gArg:Union(fn:FileName,fp:Asp1(G))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename]$Lisp,_
+ "d01asf",_
+ ["a"::S,"omega"::S,"key"::S,"epsabs"::S,"limlst"::S_
+ ,"lw"::S,"liw"::S,"result"::S,"abserr"::S,"lst"::S_
+ ,"ifail"::S,"g"::S,"erlst"::S,"rslst"::S,"ierlst"::S,"iw"::S,"w"::S_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"lst"::S,"erlst"::S,"rslst"::S,"ierlst"::S,"iw"::S,"w"::S,"g"::S]$Lisp,_
+ [["double"::S,"a"::S,"omega"::S,"epsabs"::S_
+ ,"result"::S,"abserr"::S,["erlst"::S,"limlst"::S]$Lisp,["rslst"::S,"limlst"::S]$Lisp,["w"::S,"lw"::S]$Lisp,"g"::S]$Lisp_
+ ,["integer"::S,"key"::S,"limlst"::S,"lw"::S_
+ ,"liw"::S,"lst"::S,["ierlst"::S,"limlst"::S]$Lisp,["iw"::S,"liw"::S]$Lisp,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"abserr"::S,"lst"::S,"erlst"::S,"rslst"::S,"ierlst"::S,"iw"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,omegaArg::Any,keyArg::Any,epsabsArg::Any,limlstArg::Any,lwArg::Any,liwArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01bbf(aArg:DoubleFloat,bArg:DoubleFloat,itypeArg:Integer,_
+ nArg:Integer,gtypeArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "d01bbf",_
+ ["a"::S,"b"::S,"itype"::S,"n"::S,"gtype"::S_
+ ,"ifail"::S,"weight"::S,"abscis"::S]$Lisp,_
+ ["weight"::S,"abscis"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,["weight"::S,"n"::S]$Lisp_
+ ,["abscis"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"itype"::S,"n"::S,"gtype"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["weight"::S,"abscis"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,itypeArg::Any,nArg::Any,gtypeArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01fcf(ndimArg:Integer,aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,_
+ maxptsArg:Integer,epsArg:DoubleFloat,lenwrkArg:Integer,_
+ minptsArg:Integer,ifailArg:Integer,functnArg:Union(fn:FileName,fp:Asp4(FUNCTN))): Result ==
+ pushFortranOutputStack(functnFilename := aspFilename "functn")$FOP
+ if functnArg case fn
+ then outputAsFortran(functnArg.fn)
+ else outputAsFortran(functnArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([functnFilename]$Lisp,_
+ "d01fcf",_
+ ["ndim"::S,"maxpts"::S,"eps"::S,"lenwrk"::S,"acc"::S_
+ ,"finval"::S,"minpts"::S,"ifail"::S,"functn"::S,"a"::S,"b"::S,"wrkstr"::S]$Lisp,_
+ ["acc"::S,"finval"::S,"wrkstr"::S,"functn"::S]$Lisp,_
+ [["double"::S,["a"::S,"ndim"::S]$Lisp,["b"::S,"ndim"::S]$Lisp_
+ ,"eps"::S,"acc"::S,"finval"::S,["wrkstr"::S,"lenwrk"::S]$Lisp,"functn"::S]$Lisp_
+ ,["integer"::S,"ndim"::S,"maxpts"::S,"lenwrk"::S_
+ ,"minpts"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["acc"::S,"finval"::S,"minpts"::S,"ifail"::S]$Lisp,_
+ [([ndimArg::Any,maxptsArg::Any,epsArg::Any,lenwrkArg::Any,minptsArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01gaf(xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,nArg:Integer,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "d01gaf",_
+ ["n"::S,"ans"::S,"er"::S,"ifail"::S,"x"::S,"y"::S]$Lisp,_
+ ["ans"::S,"er"::S]$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["y"::S,"n"::S]$Lisp_
+ ,"ans"::S,"er"::S]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["ans"::S,"er"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,xArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d01gbf(ndimArg:Integer,aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,_
+ maxclsArg:Integer,epsArg:DoubleFloat,lenwrkArg:Integer,_
+ minclsArg:Integer,wrkstrArg:Matrix DoubleFloat,ifailArg:Integer,_
+ functnArg:Union(fn:FileName,fp:Asp4(FUNCTN))): Result ==
+ pushFortranOutputStack(functnFilename := aspFilename "functn")$FOP
+ if functnArg case fn
+ then outputAsFortran(functnArg.fn)
+ else outputAsFortran(functnArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([functnFilename]$Lisp,_
+ "d01gbf",_
+ ["ndim"::S,"maxcls"::S,"eps"::S,"lenwrk"::S,"acc"::S_
+ ,"finest"::S,"mincls"::S,"ifail"::S,"functn"::S,"a"::S,"b"::S,"wrkstr"::S]$Lisp,_
+ ["acc"::S,"finest"::S,"functn"::S]$Lisp,_
+ [["double"::S,["a"::S,"ndim"::S]$Lisp,["b"::S,"ndim"::S]$Lisp_
+ ,"eps"::S,"acc"::S,"finest"::S,["wrkstr"::S,"lenwrk"::S]$Lisp,"functn"::S]$Lisp_
+ ,["integer"::S,"ndim"::S,"maxcls"::S,"lenwrk"::S_
+ ,"mincls"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["acc"::S,"finest"::S,"mincls"::S,"wrkstr"::S,"ifail"::S]$Lisp,_
+ [([ndimArg::Any,maxclsArg::Any,epsArg::Any,lenwrkArg::Any,minclsArg::Any,ifailArg::Any,aArg::Any,bArg::Any,wrkstrArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGD01 NagIntegrationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d01Package.spad.pamphlet b/src/algebra/d01Package.spad.pamphlet
new file mode 100644
index 00000000..7ee374d2
--- /dev/null
+++ b/src/algebra/d01Package.spad.pamphlet
@@ -0,0 +1,559 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d01Package.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTPACK AnnaNumericalIntegrationPackage}
+<<package INTPACK AnnaNumericalIntegrationPackage>>=
+)abbrev package INTPACK AnnaNumericalIntegrationPackage
+++ Author: Brian Dupee
+++ Date Created: August 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: integrate, measure
+++ Related Constructors: Result, RoutinesTable
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \axiomType{AnnaNumericalIntegrationPackage} is a \axiom{package}
+++ of functions for the \axiom{category} \axiomType{NumericalIntegrationCategory}
+++ with \axiom{measure}, and \axiom{integrate}.
+EDF ==> Expression DoubleFloat
+DF ==> DoubleFloat
+EF ==> Expression Float
+F ==> Float
+INT ==> Integer
+SOCDF ==> Segment OrderedCompletion DoubleFloat
+OCDF ==> OrderedCompletion DoubleFloat
+SBOCF ==> SegmentBinding OrderedCompletion Float
+LSOCF ==> List Segment OrderedCompletion Float
+SOCF ==> Segment OrderedCompletion Float
+OCF ==> OrderedCompletion Float
+LS ==> List Symbol
+S ==> Symbol
+LST ==> List String
+ST ==> String
+RT ==> RoutinesTable
+NIA ==> Record(var:S, fn:EDF, range:SOCDF, abserr:DF, relerr:DF)
+MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+IFL ==> List(Record(ifail:Integer,instruction:String))
+Entry ==> Record(chapter:String, type:String, domainName: String,
+ defaultMin:F, measure:F, failList:IFL, explList:List String)
+Measure ==> Record(measure:F, name:ST, explanations:LST, extra:Result)
+
+
+AnnaNumericalIntegrationPackage(): with
+
+ integrate: (EF,SOCF,F,F,RT) -> Result
+ ++ integrate(exp, a..b, epsrel, routines) is a top level ANNA function
+ ++ to integrate an expression, {\tt exp}, over a given range {\tt a}
+ ++ to {\tt b} to the required absolute and relative accuracy using
+ ++ the routines available in the RoutinesTable provided.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory}
+ ++ to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+ integrate: NumericalIntegrationProblem -> Result
+ ++ integrate(IntegrationProblem) is a top level ANNA function
+ ++ to integrate an expression over a given range or ranges
+ ++ to the required absolute and relative accuracy.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+
+ integrate: (EF,SOCF,F,F) -> Result
+ ++ integrate(exp, a..b, epsabs, epsrel) is a top level ANNA function
+ ++ to integrate an expression, {\tt exp}, over a given range {\tt a}
+ ++ to {\tt b} to the required absolute and relative accuracy.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+
+ integrate: (EF,SOCF,F) -> Result
+ ++ integrate(exp, a..b, epsrel) is a top level ANNA
+ ++ function to integrate an expression, {\tt exp}, over a given
+ ++ range {\tt a} to {\tt b} to the required relative accuracy.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+ ++
+ ++ If epsrel = 0, a default absolute accuracy is used.
+
+ integrate: (EF,SOCF) -> Result
+ ++ integrate(exp, a..b) is a top
+ ++ level ANNA function to integrate an expression, {\tt exp},
+ ++ over a given range {\tt a} to {\tt b}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+ ++
+ ++ Default values for the absolute and relative error are used.
+
+ integrate:(EF,LSOCF) -> Result
+ ++ integrate(exp, [a..b,c..d,...]) is a top
+ ++ level ANNA function to integrate a multivariate expression, {\tt exp},
+ ++ over a given set of ranges.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+ ++
+ ++ Default values for the absolute and relative error are used.
+
+ integrate:(EF,LSOCF,F) -> Result
+ ++ integrate(exp, [a..b,c..d,...], epsrel) is a top
+ ++ level ANNA function to integrate a multivariate expression, {\tt exp},
+ ++ over a given set of ranges to the required relative
+ ++ accuracy.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+ ++
+ ++ If epsrel = 0, a default absolute accuracy is used.
+
+ integrate:(EF,LSOCF,F,F) -> Result
+ ++ integrate(exp, [a..b,c..d,...], epsabs, epsrel) is a top
+ ++ level ANNA function to integrate a multivariate expression, {\tt exp},
+ ++ over a given set of ranges to the required absolute and relative
+ ++ accuracy.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+
+ integrate:(EF,LSOCF,F,F,RT) -> Result
+ ++ integrate(exp, [a..b,c..d,...], epsabs, epsrel, routines) is a top
+ ++ level ANNA function to integrate a multivariate expression, {\tt exp},
+ ++ over a given set of ranges to the required absolute and relative
+ ++ accuracy, using the routines available in the RoutinesTable provided.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.
+
+ measure:NumericalIntegrationProblem -> Measure
+ ++ measure(prob) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine for solving the numerical integration
+ ++ problem defined by \axiom{prob}.
+ ++
+ ++ It calls each \axiom{domain} of \axiom{category}
+ ++ \axiomType{NumericalIntegrationCategory} in turn to calculate all measures
+ ++ and returns the best
+ ++ i.e. the name of the most appropriate domain and any other relevant
+ ++ information.
+ measure:(NumericalIntegrationProblem,RT) -> Measure
+ ++ measure(prob,R) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical integration
+ ++ problem defined by \axiom{prob}.
+ ++
+ ++ It calls each \axiom{domain} listed in \axiom{R} of \axiom{category}
+ ++ \axiomType{NumericalIntegrationCategory} in turn to calculate all measures
+ ++ and returns the best
+ ++ i.e. the name of the most appropriate domain and any other relevant
+ ++ information.
+ integrate:(EF,SBOCF,ST) -> Union(Result,"failed")
+ ++ integrate(exp, x = a..b, "numerical") is a top level ANNA function to
+ ++ integrate an expression, {\tt exp}, over a given range, {\tt a}
+ ++ to {\tt b}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.\newline
+ ++
+ ++ Default values for the absolute and relative error are used.
+ ++
+ ++ It is an error of the last argument is not {\tt "numerical"}.
+ integrate:(EF,SBOCF,S) -> Union(Result,"failed")
+ ++ integrate(exp, x = a..b, numerical) is a top level ANNA function to
+ ++ integrate an expression, {\tt exp}, over a given range, {\tt a}
+ ++ to {\tt b}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalIntegrationCategory} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ It then performs the integration of the given expression
+ ++ on that \axiom{domain}.\newline
+ ++
+ ++ Default values for the absolute and relative error are used.
+ ++
+ ++ It is an error if the last argument is not {\tt numerical}.
+
+ == add
+
+ zeroMeasure: Measure -> Result
+ scriptedVariables?: MDNIA -> Boolean
+ preAnalysis:(Union(nia:NIA,mdnia:MDNIA),RT) -> RT
+ measureSpecific:(ST,RT,Union(nia:NIA,mdnia:MDNIA)) -> Record(measure:F,explanations:LST,extra:Result)
+ changeName:(Result,ST) -> Result
+ recoverAfterFail:(Union(nia:NIA,mdnia:MDNIA),RT,Measure,INT,Result) -> Record(a:Result,b:Measure)
+ better?:(Result,Result) -> Boolean
+ integrateConstant:(EF,SOCF) -> Result
+ integrateConstantList: (EF,LSOCF) -> Result
+ integrateArgs:(NumericalIntegrationProblem,RT) -> Result
+ integrateSpecific:(Union(nia:NIA,mdnia:MDNIA),ST,Result) -> Result
+
+ import ExpertSystemToolsPackage
+
+ integrateConstantList(exp:EF,ras:LSOCF):Result ==
+ c:OCF := ((retract(exp)@F)$EF)::OCF
+ b := [hi(j)-lo(j) for j in ras]
+ c := c*reduce((#1)*(#2),b)
+ a := coerce(c)$AnyFunctions1(OCF)
+ text := coerce("Constant Function")$AnyFunctions1(ST)
+ construct([[result@S,a],[method@S,text]])$Result
+
+ integrateConstant(exp:EF,ra:SOCF):Result ==
+ c := (retract(exp)@F)$EF
+ r:OCF := (c::OCF)*(hi(ra)-lo(ra))
+ a := coerce(r)$AnyFunctions1(OCF)
+ text := coerce("Constant Function")$AnyFunctions1(ST)
+ construct([[result@S,a],[method@S,text]])$Result
+
+ zeroMeasure(m:Measure):Result ==
+ a := coerce(0$DF)$AnyFunctions1(DF)
+ text := coerce("Constant Function")$AnyFunctions1(String)
+ r := construct([[result@Symbol,a],[method@Symbol,text]])$Result
+ concat(measure2Result m,r)$ExpertSystemToolsPackage
+
+ scriptedVariables?(mdnia:MDNIA):Boolean ==
+ vars:List Symbol := variables(mdnia.fn)$EDF
+ var1 := first(vars)$(List Symbol)
+ not scripted?(var1) => false
+ name1 := name(var1)$Symbol
+ for i in 2..# vars repeat
+ not ((scripted?(vars.i)$Symbol) and (name1 = name(vars.i)$Symbol)) =>
+ return false
+ true
+
+ preAnalysis(args:Union(nia:NIA,mdnia:MDNIA),t:RT):RT ==
+ import RT
+ r:RT := selectIntegrationRoutines t
+ args case nia =>
+ arg:NIA := args.nia
+ rangeIsFinite(arg)$d01AgentsPackage case finite =>
+ selectFiniteRoutines r
+ selectNonFiniteRoutines r
+ selectMultiDimensionalRoutines r
+
+ changeName(ans:Result,name:ST):Result ==
+ sy:S := coerce(name "Answer")$S
+ anyAns:Any := coerce(ans)$AnyFunctions1(Result)
+ construct([[sy,anyAns]])$Result
+
+ measureSpecific(name:ST,R:RT,args:Union(nia:NIA,mdnia:MDNIA)):
+ Record(measure:F,explanations:ST,extra:Result) ==
+ args case nia =>
+ arg:NIA := args.nia
+ name = "d01ajfAnnaType" => measure(R,arg)$d01ajfAnnaType
+ name = "d01akfAnnaType" => measure(R,arg)$d01akfAnnaType
+ name = "d01alfAnnaType" => measure(R,arg)$d01alfAnnaType
+ name = "d01amfAnnaType" => measure(R,arg)$d01amfAnnaType
+ name = "d01anfAnnaType" => measure(R,arg)$d01anfAnnaType
+ name = "d01apfAnnaType" => measure(R,arg)$d01apfAnnaType
+ name = "d01aqfAnnaType" => measure(R,arg)$d01aqfAnnaType
+ name = "d01asfAnnaType" => measure(R,arg)$d01asfAnnaType
+ name = "d01TransformFunctionType" =>
+ measure(R,arg)$d01TransformFunctionType
+ error("measureSpecific","invalid type name: " name)$ErrorFunctions
+ args case mdnia =>
+ arg2:MDNIA := args.mdnia
+ name = "d01gbfAnnaType" => measure(R,arg2)$d01gbfAnnaType
+ name = "d01fcfAnnaType" => measure(R,arg2)$d01fcfAnnaType
+ error("measureSpecific","invalid type name: " name)$ErrorFunctions
+ error("measureSpecific","invalid type name")$ErrorFunctions
+
+ measure(a:NumericalIntegrationProblem,R:RT):Measure ==
+ args:Union(nia:NIA,mdnia:MDNIA) := retract(a)$NumericalIntegrationProblem
+ sofar := 0$F
+ best := "none" :: ST
+ routs := copy R
+ routs := preAnalysis(args,routs)
+ empty?(routs)$RT =>
+ error("measure", "no routines found")$ErrorFunctions
+ rout := inspect(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ meth:LST := ["Trying " e.type " integration routines"]
+ ext := empty()$Result
+ for i in 1..# routs repeat
+ rout := extract!(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ n := e.domainName
+ if e.defaultMin > sofar then
+ m := measureSpecific(n,R,args)
+ if m.measure > sofar then
+ sofar := m.measure
+ best := n
+ ext := concat(m.extra,ext)$ExpertSystemToolsPackage
+ str:LST := [string(rout.key)$S "measure: " outputMeasure(m.measure)
+ " - " m.explanations]
+ else
+ str:LST := [string(rout.key)$S " is no better than other routines"]
+ meth := append(meth,str)$LST
+ [sofar,best,meth,ext]
+
+ measure(a:NumericalIntegrationProblem):Measure ==
+ measure(a,routines()$RT)
+
+ integrateSpecific(args:Union(nia:NIA,mdnia:MDNIA),n:ST,ex:Result):Result ==
+ args case nia =>
+ arg:NIA := args.nia
+ n = "d01ajfAnnaType" => numericalIntegration(arg,ex)$d01ajfAnnaType
+ n = "d01TransformFunctionType" =>
+ numericalIntegration(arg,ex)$d01TransformFunctionType
+ n = "d01amfAnnaType" => numericalIntegration(arg,ex)$d01amfAnnaType
+ n = "d01apfAnnaType" => numericalIntegration(arg,ex)$d01apfAnnaType
+ n = "d01aqfAnnaType" => numericalIntegration(arg,ex)$d01aqfAnnaType
+ n = "d01alfAnnaType" => numericalIntegration(arg,ex)$d01alfAnnaType
+ n = "d01akfAnnaType" => numericalIntegration(arg,ex)$d01akfAnnaType
+ n = "d01anfAnnaType" => numericalIntegration(arg,ex)$d01anfAnnaType
+ n = "d01asfAnnaType" => numericalIntegration(arg,ex)$d01asfAnnaType
+ error("integrateSpecific","invalid type name: " n)$ErrorFunctions
+ args case mdnia =>
+ arg2:MDNIA := args.mdnia
+ n = "d01gbfAnnaType" => numericalIntegration(arg2,ex)$d01gbfAnnaType
+ n = "d01fcfAnnaType" => numericalIntegration(arg2,ex)$d01fcfAnnaType
+ error("integrateSpecific","invalid type name: " n)$ErrorFunctions
+ error("integrateSpecific","invalid type name: " n)$ErrorFunctions
+
+ better?(r:Result,s:Result):Boolean ==
+ a1 := search("abserr"::S,r)$Result
+ a1 case "failed" => false
+ abserr1 := retract(a1)$AnyFunctions1(DF)
+ negative?(abserr1) => false
+ a2 := search("abserr"::S,s)$Result
+ a2 case "failed" => true
+ abserr2 := retract(a2)$AnyFunctions1(DF)
+ negative?(abserr2) => true
+ (abserr1 < abserr2) -- true if r.abserr better than s.abserr
+
+ recoverAfterFail(n:Union(nia:NIA,mdnia:MDNIA),routs:RT,m:Measure,iint:INT,
+ r:Result):Record(a:Result,b:Measure) ==
+ bestName := m.name
+ while positive?(iint) repeat
+ routineName := m.name
+ s := recoverAfterFail(routs,routineName(1..6),iint)$RoutinesTable
+ s case "failed" => iint := 0
+ if s = "changeEps" then
+ nn := n.nia
+ zero?(nn.abserr) =>
+ nn.abserr := 1.0e-8 :: DF
+ m := measure(n::NumericalIntegrationProblem,routs)
+ zero?(m.measure) => iint := 0
+ r := integrateSpecific(n,m.name,m.extra)
+ iint := 0
+ rn := routineName(1..6)
+ buttVal := getButtonValue(rn,"functionEvaluations")$AttributeButtons
+ if (s = "incrFunEvals") and (buttVal < 0.8) then
+ increase(rn,"functionEvaluations")$AttributeButtons
+ if s = "increase tolerance" then
+ (n.nia).relerr := (n.nia).relerr*(10.0::DF)
+ if s = "decrease tolerance" then
+ (n.nia).relerr := (n.nia).relerr/(10.0::DF)
+ fl := coerce(s)$AnyFunctions1(ST)
+ flrec:Record(key:S,entry:Any):=[failure@S,fl]
+ m2 := measure(n::NumericalIntegrationProblem,routs)
+ zero?(m2.measure) => iint := 0
+ r2:Result := integrateSpecific(n,m2.name,m2.extra)
+ better?(r,r2) =>
+ m.name := m2.name
+ insert!(flrec,r)$Result
+ bestName := m2.name
+ m := m2
+ insert!(flrec,r2)$Result
+ r := concat(r2,changeName(r,routineName))$ExpertSystemToolsPackage
+ iany := search(ifail@S,r2)$Result
+ iany case "failed" => iint := 0
+ iint := retract(iany)$AnyFunctions1(INT)
+ m.name := bestName
+ [r,m]
+
+ integrateArgs(prob:NumericalIntegrationProblem,t:RT):Result ==
+ args:Union(nia:NIA,mdnia:MDNIA) := retract(prob)$NumericalIntegrationProblem
+ routs := copy(t)$RT
+ if args case mdnia then
+ arg := args.mdnia
+ v := (# variables(arg.fn))
+ not scriptedVariables?(arg) =>
+ error("MultiDimensionalNumericalIntegrationPackage",
+ "invalid variable names")$ErrorFunctions
+ (v ~= # arg.range)@Boolean =>
+ error("MultiDimensionalNumericalIntegrationPackage",
+ "number of variables do not match number of ranges")$ErrorFunctions
+ m := measure(prob,routs)
+ zero?(m.measure) => zeroMeasure m
+ r := integrateSpecific(args,m.name,m.extra)
+ iany := search(ifail@S,r)$Result
+ iint := 0$INT
+ if (iany case Any) then
+ iint := retract(iany)$AnyFunctions1(INT)
+ if positive?(iint) then
+ tu:Record(a:Result,b:Measure) := recoverAfterFail(args,routs,m,iint,r)
+ r := tu.a
+ m := tu.b
+ r := concat(measure2Result m,r)$ExpertSystemToolsPackage
+ n := m.name
+ nn:ST :=
+ (# n > 14) => "d01transform"
+ n(1..6)
+ expl := getExplanations(routs,nn)$RoutinesTable
+ expla := coerce(expl)$AnyFunctions1(LST)
+ explaa:Record(key:Symbol,entry:Any) := ["explanations"::Symbol,expla]
+ r := concat(construct([explaa]),r)
+ args case nia =>
+ att := showAttributes(args.nia)$IntegrationFunctionsTable
+ att case "failed" => r
+ concat(att2Result att,r)$ExpertSystemToolsPackage
+ r
+
+ integrate(args:NumericalIntegrationProblem):Result ==
+ integrateArgs(args,routines()$RT)
+
+ integrate(exp:EF,ra:SOCF,epsabs:F,epsrel:F,r:RT):Result ==
+ Var:LS := variables(exp)$EF
+ empty?(Var)$LS => integrateConstant(exp,ra)
+ args:NIA := [first(Var)$LS,ef2edf exp,socf2socdf ra,f2df epsabs,f2df epsrel]
+ integrateArgs(args::NumericalIntegrationProblem,r)
+
+ integrate(exp:EF,ra:SOCF,epsabs:F,epsrel:F):Result ==
+ integrate(exp,ra,epsabs,epsrel,routines()$RT)
+
+ integrate(exp:EF,ra:SOCF,err:F):Result ==
+ positive?(err)$F => integrate(exp,ra,0$F,err)
+ integrate(exp,ra,1.0E-5,err)
+
+ integrate(exp:EF,ra:SOCF):Result == integrate(exp,ra,0$F,1.0E-5)
+
+ integrate(exp:EF,sb:SBOCF, st:ST) ==
+ st = "numerical" => integrate(exp,segment sb)
+ "failed"
+
+ integrate(exp:EF,sb:SBOCF, s:S) ==
+ s = (numerical::Symbol) => integrate(exp,segment sb)
+ "failed"
+
+ integrate(exp:EF,ra:LSOCF,epsabs:F,epsrel:F,r:RT):Result ==
+ vars := variables(exp)$EF
+ empty?(vars)$LS => integrateConstantList(exp,ra)
+ args:MDNIA := [ef2edf exp,convert ra,f2df epsabs,f2df epsrel]
+ integrateArgs(args::NumericalIntegrationProblem,r)
+
+ integrate(exp:EF,ra:LSOCF,epsabs:F,epsrel:F):Result ==
+ integrate(exp,ra,epsabs,epsrel,routines()$RT)
+
+ integrate(exp:EF,ra:LSOCF,epsrel:F):Result ==
+ zero? epsrel => integrate(exp,ra,1.0e-6,epsrel)
+ integrate(exp,ra,0$F,epsrel)
+
+ integrate(exp:EF,ra:LSOCF):Result == integrate(exp,ra,1.0e-4)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INTPACK AnnaNumericalIntegrationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d01agents.spad.pamphlet b/src/algebra/d01agents.spad.pamphlet
new file mode 100644
index 00000000..60aec7a2
--- /dev/null
+++ b/src/algebra/d01agents.spad.pamphlet
@@ -0,0 +1,430 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d01agents.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain INTFTBL IntegrationFunctionsTable}
+<<domain INTFTBL IntegrationFunctionsTable>>=
+)abbrev domain INTFTBL IntegrationFunctionsTable
+++ Author: Brian Dupee
+++ Date Created: March 1995
+++ Date Last Updated: June 1995
+++ Description:
+++
+IntegrationFunctionsTable(): E == I where
+ EF2 ==> ExpressionFunctions2
+ EFI ==> Expression Fraction Integer
+ FI ==> Fraction Integer
+ LEDF ==> List Expression DoubleFloat
+ KEDF ==> Kernel Expression DoubleFloat
+ EEDF ==> Equation Expression DoubleFloat
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ ST ==> String
+ LST ==> List String
+ SI ==> SingleInteger
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+ OCEDF ==> OrderedCompletion Expression DoubleFloat
+ EOCEFI ==> Equation OrderedCompletion Expression Fraction Integer
+ OCEFI ==> OrderedCompletion Expression Fraction Integer
+ OCFI ==> OrderedCompletion Fraction Integer
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ CTYPE ==> Union(continuous: "Continuous at the end points",
+ lowerSingular: "There is a singularity at the lower end point",
+ upperSingular: "There is a singularity at the upper end point",
+ bothSingular: "There are singularities at both end points",
+ notEvaluated: "End point continuity not yet evaluated")
+ RTYPE ==> Union(finite: "The range is finite",
+ lowerInfinite: "The bottom of range is infinite",
+ upperInfinite: "The top of range is infinite",
+ bothInfinite: "Both top and bottom points are infinite",
+ notEvaluated: "Range not yet evaluated")
+ STYPE ==> Union(str:SDF,
+ notEvaluated:"Internal singularities not yet evaluated")
+ ATT ==> Record(endPointContinuity:CTYPE,
+ singularitiesStream:STYPE,range:RTYPE)
+ ROA ==> Record(key:NIA,entry:ATT)
+
+ E ==> with
+
+ showTheFTable:() -> $
+ ++ showTheFTable() returns the current table of functions.
+ clearTheFTable : () -> Void
+ ++ clearTheFTable() clears the current table of functions.
+ keys : $ -> List(NIA)
+ ++ keys(f) returns the list of keys of f
+ fTable: List Record(key:NIA,entry:ATT) -> $
+ ++ fTable(l) creates a functions table from the elements of l.
+ insert!:Record(key:NIA,entry:ATT) -> $
+ ++ insert!(r) inserts an entry r into theIFTable
+ showAttributes:NIA -> Union(ATT,"failed")
+ ++ showAttributes(x) \undocumented{}
+ entries : $ -> List Record(key:NIA,entry:ATT)
+ ++ entries(x) \undocumented{}
+ entry:NIA -> ATT
+ ++ entry(n) \undocumented{}
+ I ==> add
+
+ Rep := Table(NIA,ATT)
+ import Rep
+
+ theFTable:$ := empty()$Rep
+
+ showTheFTable():$ ==
+ theFTable
+
+ clearTheFTable():Void ==
+ theFTable := empty()$Rep
+ void()$Void
+
+ fTable(l:List Record(key:NIA,entry:ATT)):$ ==
+ theFTable := table(l)$Rep
+
+ insert!(r:Record(key:NIA,entry:ATT)):$ ==
+ insert!(r,theFTable)$Rep
+
+ keys(t:$):List NIA ==
+ keys(t)$Rep
+
+ showAttributes(k:NIA):Union(ATT,"failed") ==
+ search(k,theFTable)$Rep
+
+ entries(t:$):List Record(key:NIA,entry:ATT) ==
+ members(t)$Rep
+
+ entry(k:NIA):ATT ==
+ qelt(theFTable,k)$Rep
+
+@
+\section{package D01AGNT d01AgentsPackage}
+<<package D01AGNT d01AgentsPackage>>=
+)abbrev package D01AGNT d01AgentsPackage
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: rangeIsFinite, functionIsContinuousAtEndPoints,
+++ functionIsOscillatory
+++ Description:
+++ \axiomType{d01AgentsPackage} is a package of numerical agents to be used
+++ to investigate attributes of an input function so as to decide the
+++ \axiomFun{measure} of an appropriate numerical integration routine.
+++ It contains functions \axiomFun{rangeIsFinite} to test the input range and
+++ \axiomFun{functionIsContinuousAtEndPoints} to check for continuity at
+++ the end points of the range.
+
+
+d01AgentsPackage(): E == I where
+ EF2 ==> ExpressionFunctions2
+ EFI ==> Expression Fraction Integer
+ FI ==> Fraction Integer
+ LEDF ==> List Expression DoubleFloat
+ KEDF ==> Kernel Expression DoubleFloat
+ EEDF ==> Equation Expression DoubleFloat
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ ST ==> String
+ LST ==> List String
+ SI ==> SingleInteger
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+ OCEDF ==> OrderedCompletion Expression DoubleFloat
+ EOCEFI ==> Equation OrderedCompletion Expression Fraction Integer
+ OCEFI ==> OrderedCompletion Expression Fraction Integer
+ OCFI ==> OrderedCompletion Fraction Integer
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ CTYPE ==> Union(continuous: "Continuous at the end points",
+ lowerSingular: "There is a singularity at the lower end point",
+ upperSingular: "There is a singularity at the upper end point",
+ bothSingular: "There are singularities at both end points",
+ notEvaluated: "End point continuity not yet evaluated")
+ RTYPE ==> Union(finite: "The range is finite",
+ lowerInfinite: "The bottom of range is infinite",
+ upperInfinite: "The top of range is infinite",
+ bothInfinite: "Both top and bottom points are infinite",
+ notEvaluated: "Range not yet evaluated")
+ STYPE ==> Union(str:SDF,
+ notEvaluated:"Internal singularities not yet evaluated")
+ ATT ==> Record(endPointContinuity:CTYPE,
+ singularitiesStream:STYPE,range:RTYPE)
+ ROA ==> Record(key:NIA,entry:ATT)
+
+ E ==> with
+
+ rangeIsFinite : NIA -> RTYPE
+ ++ rangeIsFinite(args) tests the endpoints of \spad{args.range} for
+ ++ infinite end points.
+ functionIsContinuousAtEndPoints: NIA -> CTYPE
+ ++ functionIsContinuousAtEndPoints(args) uses power series limits
+ ++ to check for problems at the end points of the range of \spad{args}.
+ getlo : SOCDF -> DF
+ ++ getlo(x) gets the \axiomType{DoubleFloat} equivalent of
+ ++ the first endpoint of the range \axiom{x}
+ gethi : SOCDF -> DF
+ ++ gethi(x) gets the \axiomType{DoubleFloat} equivalent of
+ ++ the second endpoint of the range \axiom{x}
+ functionIsOscillatory:NIA -> F
+ ++ functionIsOscillatory(a) tests whether the function \spad{a.fn}
+ ++ has many zeros of its derivative.
+ problemPoints: (EDF, Symbol, SOCDF) -> List DF
+ ++ problemPoints(f,var,range) returns a list of possible problem points
+ ++ by looking at the zeros of the denominator of the function if it
+ ++ can be retracted to \axiomType{Polynomial DoubleFloat}.
+ singularitiesOf:NIA -> SDF
+ ++ singularitiesOf(args) returns a list of potential
+ ++ singularities of the function within the given range
+ df2st:DF -> String
+ ++ df2st(n) coerces a \axiomType{DoubleFloat} to \axiomType{String}
+ ldf2lst:LDF -> LST
+ ++ ldf2lst(ln) coerces a List of \axiomType{DoubleFloat} to \axiomType{List String}
+ sdf2lst:SDF -> LST
+ ++ sdf2lst(ln) coerces a Stream of \axiomType{DoubleFloat} to \axiomType{List String}
+ commaSeparate:LST -> ST
+ ++ commaSeparate(l) produces a comma separated string from a
+ ++ list of strings.
+ changeName:(Symbol,Symbol,Result) -> Result
+ ++ changeName(s,t,r) changes the name of item \axiom{s} in \axiom{r}
+ ++ to \axiom{t}.
+
+ I ==> ExpertSystemContinuityPackage add
+
+ import ExpertSystemToolsPackage
+ import ExpertSystemContinuityPackage
+
+ -- local functions
+ ocdf2ocefi : OCDF -> OCEFI
+ rangeOfArgument : (KEDF, NIA) -> DF
+ continuousAtPoint? : (EFI,EOCEFI) -> Boolean
+ rand:(SOCDF,INT) -> LDF
+ eval:(EDF,Symbol,LDF) -> LDF
+ numberOfSignChanges:LDF -> INT
+ rangeIsFiniteFunction:NIA -> RTYPE
+ functionIsContinuousAtEndPointsFunction:NIA -> CTYPE
+
+ changeName(s:Symbol,t:Symbol,r:Result):Result ==
+ a := remove!(s,r)$Result
+ a case Any =>
+ insert!([t,a],r)$Result
+ r
+ r
+
+ commaSeparate(l:LST):ST ==
+ empty?(l)$LST => ""
+-- one?(#(l)) => concat(l)$ST
+ (#(l) = 1) => concat(l)$ST
+ f := first(l)$LST
+ t := [concat([", ",l.i])$ST for i in 2..#(l)]
+ concat(f,concat(t)$ST)$ST
+
+ rand(seg:SOCDF,n:INT):LDF ==
+ -- produced a sorted list of random numbers in the given range
+ l:DF := getlo seg
+ s:DF := (gethi seg) - l
+ seed:INT := random()$INT
+ dseed:DF := seed :: DF
+ r:LDF := [(((random(seed)$INT) :: DF)*s/dseed + l) for i in 1..n]
+ sort(r)$LDF
+
+ eval(f:EDF,var:Symbol,l:LDF):LDF ==
+ empty?(l)$LDF => [0$DF]
+ ve := var::EDF
+ [retract(eval(f,equation(ve,u::EDF)$EEDF)$EDF)@DF for u in l]
+
+ numberOfSignChanges(l:LDF):INT ==
+ -- calculates the number of sign changes in a list
+ a := 0$INT
+ empty?(l)$LDF => 0
+ for i in 2..# l repeat
+ if negative?(l.i*l.(i-1)) then
+ a := a + 1
+ a
+
+ rangeOfArgument(k: KEDF, args:NIA): DF ==
+ Args := copy args
+ Args.fn := arg := first(argument(k)$KEDF)$LEDF
+ functionIsContinuousAtEndPoints(Args) case continuous =>
+ r:SOCDF := args.range
+ low:EDF := (getlo r) :: EDF
+ high:EDF := (gethi r) :: EDF
+ eql := equation(a := args.var :: EDF, low)$EEDF
+ eqh := equation(a, high)$EEDF
+ e1 := (numeric(eval(arg,eql)$EDF)$Numeric(DF)) :: DF
+ e2 := (numeric(eval(arg,eqh)$EDF)$Numeric(DF)) :: DF
+ e2-e1
+ 0$DF
+
+ ocdf2ocefi(r:OCDF):OCEFI ==
+ finite?(r)$OCDF => (edf2efi(((retract(r)@DF)$OCDF)::EDF))::OCEFI
+ r pretend OCEFI
+
+ continuousAtPoint?(f:EFI,e:EOCEFI):Boolean ==
+ (l := limit(f,e)$PowerSeriesLimitPackage(FI,EFI)) case OCEFI =>
+ finite?(l :: OCEFI)
+ -- if the left hand limit equals the right hand limit, or if neither
+ -- side has a limit at this point, the return type of limit() is
+ -- Union(Ordered Completion Expression Fraction Integer,"failed")
+ false
+
+ -- exported functions
+
+ rangeIsFiniteFunction(args:NIA): RTYPE ==
+ -- rangeIsFinite(x) tests the endpoints of x.range for infinite
+ -- end points.
+ -- [-inf, inf] => 4
+ -- [ x , inf] => 3
+ -- [-inf, x ] => 1
+ -- [ x , y ] => 0
+ fr:SI := (3::SI * whatInfinity(hi(args.range))$OCDF
+ - whatInfinity(lo(args.range))$OCDF)
+ fr = 0 => ["The range is finite"]
+ fr = 1 => ["The bottom of range is infinite"]
+ fr = 3 => ["The top of range is infinite"]
+ fr = 4 => ["Both top and bottom points are infinite"]
+ error("rangeIsFinite",["this is not a valid range"])$ErrorFunctions
+
+ rangeIsFinite(args:NIA): RTYPE ==
+ nia := copy args
+ (t := showAttributes(nia)$IntegrationFunctionsTable) case ATT =>
+ s := coerce(t)@ATT
+ s.range case notEvaluated =>
+ s.range := rangeIsFiniteFunction(nia)
+ r:ROA := [nia,s]
+ insert!(r)$IntegrationFunctionsTable
+ s.range
+ s.range
+ a:ATT := [["End point continuity not yet evaluated"],
+ ["Internal singularities not yet evaluated"],
+ e:=rangeIsFiniteFunction(nia)]
+ r:ROA := [nia,a]
+ insert!(r)$IntegrationFunctionsTable
+ e
+
+ functionIsContinuousAtEndPointsFunction(args:NIA):CTYPE ==
+
+ v := args.var :: EFI :: OCEFI
+ high:OCEFI := ocdf2ocefi(hi(args.range))
+ low:OCEFI := ocdf2ocefi(lo(args.range))
+ f := edf2efi(args.fn)
+ l:Boolean := continuousAtPoint?(f,equation(v,low)$EOCEFI)
+ h:Boolean := continuousAtPoint?(f,equation(v,high)$EOCEFI)
+ l and h => ["Continuous at the end points"]
+ l => ["There is a singularity at the upper end point"]
+ h => ["There is a singularity at the lower end point"]
+ ["There are singularities at both end points"]
+
+ functionIsContinuousAtEndPoints(args:NIA): CTYPE ==
+ nia := copy args
+ (t := showAttributes(nia)$IntegrationFunctionsTable) case ATT =>
+ s := coerce(t)@ATT
+ s.endPointContinuity case notEvaluated =>
+ s.endPointContinuity := functionIsContinuousAtEndPointsFunction(nia)
+ r:ROA := [nia,s]
+ insert!(r)$IntegrationFunctionsTable
+ s.endPointContinuity
+ s.endPointContinuity
+ a:ATT := [e:=functionIsContinuousAtEndPointsFunction(nia),
+ ["Internal singularities not yet evaluated"],
+ ["Range not yet evaluated"]]
+ r:ROA := [nia,a]
+ insert!(r)$IntegrationFunctionsTable
+ e
+
+ functionIsOscillatory(a:NIA):F ==
+
+ args := copy a
+ k := tower(numerator args.fn)$EDF
+ p:F := pi()$F
+ for i in 1..# k repeat
+ is?(ker := k.i, sin :: Symbol) =>
+ ra := convert(rangeOfArgument(ker,args))@F
+ ra > 2*p => return (ra/p)
+ is?(ker, cos :: Symbol) =>
+ ra := convert(rangeOfArgument(ker,args))@F
+ ra > 2*p => return (ra/p)
+ l:LDF := rand(args.range,30)
+ l := eval(args.fn,args.var,l)
+ numberOfSignChanges(l) :: F
+
+ singularitiesOf(args:NIA):SDF ==
+ nia := copy args
+ (t := showAttributes(nia)$IntegrationFunctionsTable) case ATT =>
+ s:ATT := coerce(t)@ATT
+ p:STYPE := s.singularitiesStream
+ p case str => p.str
+ e:SDF := singularitiesOf(nia.fn,[nia.var],nia.range)
+ if not empty?(e) then
+ if less?(e,10)$SDF then extend(e,10)$SDF
+ s.singularitiesStream := [e]
+ r:ROA := [nia,s]
+ insert!(r)$IntegrationFunctionsTable
+ e
+ e:=singularitiesOf(nia.fn,[nia.var],nia.range)
+ if not empty?(e) then
+ if less?(e,10)$SDF then extend(e,10)$SDF
+ a:ATT := [["End point continuity not yet evaluated"],[e],
+ ["Range not yet evaluated"]]
+ r:ROA := [nia,a]
+ insert!(r)$IntegrationFunctionsTable
+ e
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain INTFTBL IntegrationFunctionsTable>>
+<<package D01AGNT d01AgentsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d01routine.spad.pamphlet b/src/algebra/d01routine.spad.pamphlet
new file mode 100644
index 00000000..6daf17fd
--- /dev/null
+++ b/src/algebra/d01routine.spad.pamphlet
@@ -0,0 +1,751 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d01routine.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain D01AJFA d01ajfAnnaType}
+<<domain D01AJFA d01ajfAnnaType>>=
+)abbrev domain D01AJFA d01ajfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01ajfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01AJF, a general numerical integration routine which
+++ can handle some singularities in the input function. The function
+++ \axiomFun{measure} measures the usefulness of the routine D01AJF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01ajfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, NagIntegrationPackage, d01AgentsPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ pp:SDF := singularitiesOf(args)
+ not (empty?(pp)$SDF) =>
+ [0.1,"d01ajf: There is a possible problem at the following point(s): "
+ commaSeparate(sdf2lst(pp)) ,ext]
+ [getMeasure(R,d01ajf :: S)$RT,
+ "The general routine d01ajf is our default",ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ ArgsFn := map(convert(#1)$DF,args.fn)$EF2(DF,Float)
+ b:Float := getButtonValue("d01ajf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ f : Union(fn:FileName,fp:Asp1(F)) := [retract(ArgsFn)$Asp1(F)]
+ d01ajf(getlo(args.range),gethi(args.range),args.abserr,args.relerr,4*iw,iw,-1,f)
+
+@
+\section{domain D01AKFA d01akfAnnaType}
+<<domain D01AKFA d01akfAnnaType>>=
+)abbrev domain D01AKFA d01akfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01akfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01AKF, a numerical integration routine which is
+++ is suitable for oscillating, non-singular functions. The function
+++ \axiomFun{measure} measures the usefulness of the routine D01AKF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01akfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ pp:SDF := singularitiesOf(args)
+ not (empty?(pp)$SDF) =>
+ [0.0,"d01akf: There is a possible problem at the following point(s): "
+ commaSeparate(sdf2lst(pp)) ,ext]
+ o:Float := functionIsOscillatory(args)
+ one := 1.0
+ m:Float := (getMeasure(R,d01akf@S)$RT)*(one-one/(one+sqrt(o)))**2
+ m > 0.8 => [m,"d01akf: The expression shows much oscillation",ext]
+ m > 0.6 => [m,"d01akf: The expression shows some oscillation",ext]
+ m > 0.5 => [m,"d01akf: The expression shows little oscillation",ext]
+ [m,"d01akf: The expression shows little or no oscillation",ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ ArgsFn := map(convert(#1)$DF,args.fn)$EF2(DF,Float)
+ b:Float := getButtonValue("d01akf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ f : Union(fn:FileName,fp:Asp1(F)) := [retract(ArgsFn)$Asp1(F)]
+ d01akf(getlo(args.range),gethi(args.range),args.abserr,args.relerr,4*iw,iw,-1,f)
+
+@
+\section{domain D01AMFA d01amfAnnaType}
+<<domain D01AMFA d01amfAnnaType>>=
+)abbrev domain D01AMFA d01amfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01amfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01AMF, a general numerical integration routine which
+++ can handle infinite or semi-infinite range of the input function. The
+++ function \axiomFun{measure} measures the usefulness of the routine D01AMF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01amfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ Range:=rangeIsFinite(args)
+ pp:SDF := singularitiesOf(args)
+ not (empty?(pp)$SDF) =>
+ [0.0,"d01amf: There is a possible problem at the following point(s): "
+ commaSeparate(sdf2lst(pp)), ext]
+ [getMeasure(R,d01amf@S)$RT, "d01amf is a reasonable choice if the "
+ "integral is infinite or semi-infinite and d01transform cannot "
+ "do better than using general routines",ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ r:INT
+ bound:DF
+ ArgsFn := map(convert(#1)$DF,args.fn)$EF2(DF,Float)
+ b:Float := getButtonValue("d01amf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 150*fEvals
+ f : Union(fn:FileName,fp:Asp1(F)) := [retract(ArgsFn)$Asp1(F)]
+ Range:=rangeIsFinite(args)
+ if (Range case upperInfinite) then
+ bound := getlo(args.range)
+ r := 1
+ else if (Range case lowerInfinite) then
+ bound := gethi(args.range)
+ r := -1
+ else
+ bound := 0$DF
+ r := 2
+ d01amf(bound,r,args.abserr,args.relerr,4*iw,iw,-1,f)
+
+@
+\section{domain D01APFA d01apfAnnaType}
+<<domain D01APFA d01apfAnnaType>>=
+)abbrev domain D01APFA d01apfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01apfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01APF, a general numerical integration routine which
+++ can handle end point singularities of the algebraico-logarithmic form
+++ w(x) = (x-a)^c * (b-x)^d. The
+++ function \axiomFun{measure} measures the usefulness of the routine D01APF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01apfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, NagIntegrationPackage, d01AgentsPackage, d01WeightsPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ d := (c := 0$DF)
+ if ((a := exprHasAlgebraicWeight(args)) case LDF) then
+ if (a.1 > -1) then c := a.1
+ if (a.2 > -1) then d := a.2
+ l:INT := exprHasLogarithmicWeights(args)
+-- (zero? c) and (zero? d) and (one? l) =>
+ (zero? c) and (zero? d) and (l = 1) =>
+ [0.0,"d01apf: A suitable singularity has not been found", ext]
+ out:LDF := [c,d,l :: DF]
+ outany:Any := coerce(out)$AnyFunctions1(LDF)
+ ex:Record(key:S,entry:Any) := [d01apfextra@S,outany]
+ ext := insert!(ex,ext)$Result
+ st:ST := "Recommended is d01apf with c = " df2st(c) ", d = "
+ df2st(d) " and l = " string(l)$ST
+ [getMeasure(R,d01apf@S)$RT, st, ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+
+ Var:EDF := coerce(args.var)$EDF
+ la:Any := coerce(search((d01apfextra@S),hints)$Result)@Any
+ list:LDF := retract(la)$AnyFunctions1(LDF)
+ Fac1:EDF := (Var - (getlo(args.range) :: EDF))$EDF
+ Fac2:EDF := ((gethi(args.range) :: EDF) - Var)$EDF
+ c := first(list)$LDF
+ d := second(list)$LDF
+ l := (retract(third(list)$LDF)@INT)$DF
+ thebiz:EDF := (Fac1**(c :: EDF))*(Fac2**(d :: EDF))
+ if l > 1 then
+ if l = 2 then
+ thebiz := thebiz*log(Fac1)
+ else if l = 3 then
+ thebiz := thebiz*log(Fac2)
+ else
+ thebiz := thebiz*log(Fac1)*log(Fac2)
+ Fn := (args.fn/thebiz)$EDF
+ ArgsFn := map(convert(#1)$DF,Fn)$EF2(DF,Float)
+ b:Float := getButtonValue("d01apf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ f : Union(fn:FileName,fp:Asp1(G)) := [retract(ArgsFn)$Asp1(G)]
+ d01apf(getlo(args.range),gethi(args.range),c,d,l,args.abserr,args.relerr,4*iw,iw,-1,f)
+
+@
+\section{domain D01AQFA d01aqfAnnaType}
+<<domain D01AQFA d01aqfAnnaType>>=
+)abbrev domain D01AQFA d01aqfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01aqfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01AQF, a general numerical integration routine which
+++ can solve an integral of the form \newline
+++ \centerline{\inputbitmap{/home/bjd/Axiom/anna/hypertex/bitmaps/d01aqf.xbm}}
+++ The function \axiomFun{measure} measures the usefulness of the routine
+++ D01AQF for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01aqfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ Den := denominator(args.fn)
+-- one? Den =>
+ (Den = 1) =>
+ [0.0,"d01aqf: A suitable weight function has not been found", ext]
+ listOfZeros:LDF := problemPoints(args.fn,args.var,args.range)
+ numberOfZeros := (#(listOfZeros))$LDF
+ zero?(numberOfZeros) =>
+ [0.0,"d01aqf: A suitable weight function has not been found", ext]
+ numberOfZeros = 1 =>
+ s:SDF := singularitiesOf(args)
+ more?(s,1)$SDF =>
+ [0.0,"d01aqf: Too many singularities have been found", ext]
+ cFloat:Float := (convert(first(listOfZeros)$LDF)@Float)$DF
+ cString:ST := (convert(cFloat)@ST)$Float
+ lany:Any := coerce(listOfZeros)$AnyFunctions1(LDF)
+ ex:Record(key:S,entry:Any) := [d01aqfextra@S,lany]
+ ext := insert!(ex,ext)$Result
+ [getMeasure(R,d01aqf@S)$RT, "Recommended is d01aqf with the "
+ "hilbertian weight function of 1/(x-c) where c = " cString, ext]
+ [0.0,"d01aqf: More than one factor has been found and so does not "
+ "have a suitable weight function",ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ Args := copy args
+ ca:Any := coerce(search((d01aqfextra@S),hints)$Result)@Any
+ c:DF := first(retract(ca)$AnyFunctions1(LDF))$LDF
+ ci:FI := df2fi(c)$ExpertSystemToolsPackage
+ Var:EFI := Args.var :: EFI
+ Gx:EFI := (Var-(ci::EFI))*(edf2efi(Args.fn)$ExpertSystemToolsPackage)
+ ArgsFn := map(convert(#1)$FI,Gx)$EF2(FI,Float)
+ b:Float := getButtonValue("d01aqf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ f : Union(fn:FileName,fp:Asp1(G)) := [retract(ArgsFn)$Asp1(G)]
+ d01aqf(getlo(Args.range),gethi(Args.range),c,Args.abserr,Args.relerr,4*iw,iw,-1,f)
+
+@
+\section{domain D01ALFA d01alfAnnaType}
+<<domain D01ALFA d01alfAnnaType>>=
+)abbrev domain D01ALFA d01alfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01alfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01ALF, a general numerical integration routine which
+++ can handle a list of singularities. The
+++ function \axiomFun{measure} measures the usefulness of the routine D01ALF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01alfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ streamOfZeros:SDF := singularitiesOf(args)
+ listOfZeros:LST := removeDuplicates!(sdf2lst(streamOfZeros))
+ numberOfZeros:INT := # listOfZeros
+ (numberOfZeros > 15)@Boolean =>
+ [0.0,"d01alf: The list of singularities is too long", ext]
+ positive?(numberOfZeros) =>
+ l:LDF := entries(complete(streamOfZeros)$SDF)$SDF
+ lany:Any := coerce(l)$AnyFunctions1(LDF)
+ ex:Record(key:S,entry:Any) := [d01alfextra@S,lany]
+ ext := insert!(ex,ext)$Result
+ st:ST := "Recommended is d01alf with the singularities "
+ commaSeparate(listOfZeros)
+ m :=
+-- one?(numberOfZeros) => 0.4
+ (numberOfZeros = 1) => 0.4
+ getMeasure(R,d01alf@S)$RT
+ [m, st, ext]
+ [0.0, "d01alf: A list of suitable singularities has not been found", ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ la:Any := coerce(search((d01alfextra@S),hints)$Result)@Any
+ listOfZeros:LDF := retract(la)$AnyFunctions1(LDF)
+ l:= removeDuplicates(listOfZeros)$LDF
+ n:Integer := (#(l))$List(DF)
+ M:Matrix DF := matrix([l])$(Matrix DF)
+ b:Float := getButtonValue("d01alf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ ArgsFn := map(convert(#1)$DF,args.fn)$EF2(DF,Float)
+ f : Union(fn:FileName,fp:Asp1(F)) := [retract(ArgsFn)$Asp1(F)]
+ d01alf(getlo(args.range),gethi(args.range),n,M,args.abserr,args.relerr,2*n*iw,n*iw,-1,f)
+
+@
+\section{domain D01ANFA d01anfAnnaType}
+<<domain D01ANFA d01anfAnnaType>>=
+)abbrev domain D01ANFA d01anfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01anfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01ANF, a numerical integration routine which can
+++ handle weight functions of the form cos(\omega x) or sin(\omega x). The
+++ function \axiomFun{measure} measures the usefulness of the routine D01ANF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01anfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01WeightsPackage, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ weight:Union(Record(op:BOP,w:DF),"failed") :=
+ exprHasWeightCosWXorSinWX(args)
+ weight case "failed" =>
+ [0.0,"d01anf: A suitable weight has not been found", ext]
+ weight case Record(op:BOP,w:DF) =>
+ wany := coerce(weight)$AnyFunctions1(Record(op:BOP,w:DF))
+ ex:Record(key:S,entry:Any) := [d01anfextra@S,wany]
+ ext := insert!(ex,ext)$Result
+ ws:ST := string(name(weight.op)$BOP)$S "(" df2st(weight.w)
+ string(args.var)$S ")"
+ [getMeasure(R,d01anf@S)$RT,
+ "d01anf: The expression has a suitable weight:- " ws, ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ a:INT
+ r:Any := coerce(search((d01anfextra@S),hints)$Result)@Any
+ rec:Record(op:BOP,w:DF) := retract(r)$AnyFunctions1(Record(op:BOP,w:DF))
+ Var := args.var :: EDF
+ o:BOP := rec.op
+ den:EDF := o((rec.w*Var)$EDF)
+ Argsfn:EDF := args.fn/den
+ if (name(o) = cos@S)@Boolean then a := 1
+ else a := 2
+ b:Float := getButtonValue("d01anf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ ArgsFn := map(convert(#1)$DF,Argsfn)$EF2(DF,Float)
+ f : Union(fn:FileName,fp:Asp1(G)) := [retract(ArgsFn)$Asp1(G)]
+ d01anf(getlo(args.range),gethi(args.range),rec.w,a,args.abserr,args.relerr,4*iw,iw,-1,f)
+
+@
+\section{domain D01ASFA d01asfAnnaType}
+<<domain D01ASFA d01asfAnnaType>>=
+)abbrev domain D01ASFA d01asfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01asfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01ASF, a numerical integration routine which can
+++ handle weight functions of the form cos(\omega x) or sin(\omega x) on an
+++ semi-infinite range. The
+++ function \axiomFun{measure} measures the usefulness of the routine D01ASF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01asfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01WeightsPackage, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:NIA) ==
+ ext:Result := empty()$Result
+ Range := rangeIsFinite(args)
+ not(Range case upperInfinite) =>
+ [0.0,"d01asf is not a suitable routine for infinite integrals",ext]
+ weight: Union(Record(op:BOP,w:DF),"failed") :=
+ exprHasWeightCosWXorSinWX(args)
+ weight case "failed" =>
+ [0.0,"d01asf: A suitable weight has not been found", ext]
+ weight case Record(op:BOP,w:DF) =>
+ wany := coerce(weight)$AnyFunctions1(Record(op:BOP,w:DF))
+ ex:Record(key:S,entry:Any) := [d01asfextra@S,wany]
+ ext := insert!(ex,ext)$Result
+ ws:ST := string(name(weight.op)$BOP)$S "(" df2st(weight.w)
+ string(args.var)$S ")"
+ [getMeasure(R,d01asf@S)$RT,
+ "d01asf: A suitable weight has been found:- " ws, ext]
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ i:INT
+ r:Any := coerce(search((d01asfextra@S),hints)$Result)@Any
+ rec:Record(op:BOP,w:DF) := retract(r)$AnyFunctions1(Record(op:BOP,w:DF))
+ Var := args.var :: EDF
+ o:BOP := rec.op
+ den:EDF := o((rec.w*Var)$EDF)
+ Argsfn:EDF := args.fn/den
+ if (name(o) = cos@S)@Boolean then i := 1
+ else i := 2
+ b:Float := getButtonValue("d01asf","functionEvaluations")$AttributeButtons
+ fEvals:INT := wholePart exp(1.1513*(1.0/(2.0*(1.0-b))))
+ iw:INT := 75*fEvals
+ ArgsFn := map(convert(#1)$DF,Argsfn)$EF2(DF,Float)
+ f : Union(fn:FileName,fp:Asp1(G)) := [retract(ArgsFn)$Asp1(G)]
+ err :=
+ positive?(args.abserr) => args.abserr
+ args.relerr
+ d01asf(getlo(args.range),rec.w,i,err,50,4*iw,2*iw,-1,f)
+
+@
+\section{domain D01GBFA d01gbfAnnaType}
+<<domain D01GBFA d01gbfAnnaType>>=
+)abbrev domain D01GBFA d01gbfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01gbfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01GBF, a numerical integration routine which can
+++ handle multi-dimensional quadrature over a finite region. The
+++ function \axiomFun{measure} measures the usefulness of the routine D01GBF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01gbfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:MDNIA) ==
+ ext:Result := empty()$Result
+ (rel := args.relerr) < 0.01 :: DF =>
+ [0.1, "d01gbf: The relative error requirement is too small",ext]
+ segs := args.range
+ vars := variables(args.fn)$EDF
+ for i in 1..# vars repeat
+ nia:NIA := [vars.i,args.fn,segs.i,args.abserr,rel]
+ not rangeIsFinite(nia) case finite => return
+ [0.0,"d01gbf is not a suitable routine for infinite integrals",ext]
+ [getMeasure(R,d01gbf@S)$RT, "Recommended is d01gbf", ext]
+
+ numericalIntegration(args:MDNIA,hints:Result) ==
+ import Integer
+ segs := args.range
+ dim:INT := # segs
+ low:Matrix DF := matrix([[getlo(segs.i) for i in 1..dim]])$(Matrix DF)
+ high:Matrix DF := matrix([[gethi(segs.i) for i in 1..dim]])$(Matrix DF)
+ b:Float := getButtonValue("d01gbf","functionEvaluations")$AttributeButtons
+ a:Float:= exp(1.1513*(1.0/(2.0*(1.0-b))))
+ maxcls:INT := 1500*(dim+1)*(fEvals:INT := wholePart(a))
+ mincls:INT := 300*fEvals
+ c:Float := nthRoot((maxcls::Float)/4.0,dim)$Float
+ lenwrk:INT := 3*dim*(d:INT := wholePart(c))+10*dim
+ wrkstr:Matrix DF := matrix([[0$DF for i in 1..lenwrk]])$(Matrix DF)
+ ArgsFn := map(convert(#1)$DF,args.fn)$EF2(DF,Float)
+ f : Union(fn:FileName,fp:Asp4(FUNCTN)) := [retract(ArgsFn)$Asp4(FUNCTN)]
+ out:Result := d01gbf(dim,low,high,maxcls,args.relerr,lenwrk,mincls,wrkstr,-1,f)
+ changeName(finest@Symbol,result@Symbol,out)
+
+@
+\section{domain D01FCFA d01fcfAnnaType}
+<<domain D01FCFA d01fcfAnnaType>>=
+)abbrev domain D01FCFA d01fcfAnnaType
+++ Author: Brian Dupee
+++ Date Created: March 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{d01fcfAnnaType} is a domain of \axiomType{NumericalIntegrationCategory}
+++ for the NAG routine D01FCF, a numerical integration routine which can
+++ handle multi-dimensional quadrature over a finite region. The
+++ function \axiomFun{measure} measures the usefulness of the routine D01GBF
+++ for the given problem. The function \axiomFun{numericalIntegration}
+++ performs the integration by using \axiomType{NagIntegrationPackage}.
+
+d01fcfAnnaType(): NumericalIntegrationCategory == Result add
+ EF2 ==> ExpressionFunctions2
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ MDNIA ==> Record(fn:EDF,range:List SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ S ==> Symbol
+ ST ==> String
+ LST ==> List String
+ RT ==> RoutinesTable
+ Rep:=Result
+ import Rep, d01AgentsPackage, NagIntegrationPackage
+
+ measure(R:RT,args:MDNIA) ==
+ ext:Result := empty()$Result
+ segs := args.range
+ vars := variables(args.fn)$EDF
+ for i in 1..# vars repeat
+ nia:NIA := [vars.i,args.fn,segs.i,args.abserr,args.relerr]
+ not rangeIsFinite(nia) case finite => return
+ [0.0,"d01fcf is not a suitable routine for infinite integrals",ext]
+ [getMeasure(R,d01fcf@S)$RT, "Recommended is d01fcf", ext]
+
+ numericalIntegration(args:MDNIA,hints:Result) ==
+ import Integer
+ segs := args.range
+ dim := # segs
+ err := args.relerr
+ low:Matrix DF := matrix([[getlo(segs.i) for i in 1..dim]])$(Matrix DF)
+ high:Matrix DF := matrix([[gethi(segs.i) for i in 1..dim]])$(Matrix DF)
+ b:Float := getButtonValue("d01fcf","functionEvaluations")$AttributeButtons
+ a:Float:= exp(1.1513*(1.0/(2.0*(1.0-b))))
+ alpha:INT := 2**dim+2*dim**2+2*dim+1
+ d:Float := max(1.e-3,nthRoot(convert(err)@Float,4))$Float
+ minpts:INT := (fEvals := wholePart(a))*wholePart(alpha::Float/d)
+ maxpts:INT := 5*minpts
+ lenwrk:INT := (dim+2)*(1+(33*fEvals))
+ ArgsFn := map(convert(#1)$DF,args.fn)$EF2(DF,Float)
+ f : Union(fn:FileName,fp:Asp4(FUNCTN)) := [retract(ArgsFn)$Asp4(FUNCTN)]
+ out:Result := d01fcf(dim,low,high,maxpts,err,lenwrk,minpts,-1,f)
+ changeName(finval@Symbol,result@Symbol,out)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain D01AJFA d01ajfAnnaType>>
+<<domain D01AKFA d01akfAnnaType>>
+<<domain D01AMFA d01amfAnnaType>>
+<<domain D01AQFA d01aqfAnnaType>>
+<<domain D01APFA d01apfAnnaType>>
+<<domain D01ALFA d01alfAnnaType>>
+<<domain D01ANFA d01anfAnnaType>>
+<<domain D01ASFA d01asfAnnaType>>
+<<domain D01GBFA d01gbfAnnaType>>
+<<domain D01FCFA d01fcfAnnaType>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d01transform.spad.pamphlet b/src/algebra/d01transform.spad.pamphlet
new file mode 100644
index 00000000..6866ac9b
--- /dev/null
+++ b/src/algebra/d01transform.spad.pamphlet
@@ -0,0 +1,212 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d01transform.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain D01TRNS d01TransformFunctionType}
+<<domain D01TRNS d01TransformFunctionType>>=
+)abbrev domain D01TRNS d01TransformFunctionType
+++ Author: Brian Dupee
+++ Date Created: April 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, numericalIntegration
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ Since an infinite integral cannot be evaluated numerically
+++ it is necessary to transform the integral onto finite ranges.
+++ \axiomType{d01TransformFunctionType} uses the mapping \spad{x -> 1/x}
+++ and contains the functions \axiomFun{measure} and
+++ \axiomFun{numericalIntegration}.
+EDF ==> Expression DoubleFloat
+EEDF ==> Equation Expression DoubleFloat
+FI ==> Fraction Integer
+EFI ==> Expression Fraction Integer
+EEFI ==> Equation Expression Fraction Integer
+EF2 ==> ExpressionFunctions2
+DF ==> DoubleFloat
+F ==> Float
+SOCDF ==> Segment OrderedCompletion DoubleFloat
+OCDF ==> OrderedCompletion DoubleFloat
+NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+INT ==> Integer
+PI ==> PositiveInteger
+HINT ==> Record(str:String,fn:EDF,range:SOCDF,ext:Result)
+S ==> Symbol
+ST ==> String
+LST ==> List String
+Measure ==> Record(measure:F,explanations:ST,extra:Result)
+MS ==> Record(measure:F,name:ST,explanations:LST,extra:Result)
+
+d01TransformFunctionType():NumericalIntegrationCategory == Result add
+ Rep:=Result
+ import d01AgentsPackage,Rep
+
+ rec2any(re:Record(str:ST,fn:EDF,range:SOCDF)):Any ==
+ coerce(re)$AnyFunctions1(Record(str:ST,fn:EDF,range:SOCDF))
+
+ changeName(ans:Result,name:ST):Result ==
+ sy:S := coerce(name "Answer")$S
+ anyAns:Any := coerce(ans)$AnyFunctions1(Result)
+ construct([[sy,anyAns]])$Result
+
+ getIntegral(args:NIA,hint:HINT) : Result ==
+ Args := copy args
+ Args.fn := hint.fn
+ Args.range := hint.range
+ integrate(Args::NumericalIntegrationProblem)$AnnaNumericalIntegrationPackage
+
+ transformFunction(args:NIA) : NIA ==
+ Args := copy args
+ Var := Args.var :: EFI -- coerce Symbol to EFI
+ NewVar:EFI := inv(Var)$EFI -- invert it
+ VarEqn:EEFI:=equation(Var,NewVar)$EEFI -- turn it into an equation
+ Afn:EFI := edf2efi(Args.fn)$ExpertSystemToolsPackage
+ Afn := subst(Afn,VarEqn)$EFI -- substitute into function
+ Var2:EFI := Var**2
+ Afn:= simplify(Afn/Var2)$TranscendentalManipulations(FI,EFI)
+ Args.fn:= map(convert(#1)$FI,Afn)$EF2(FI,DF)
+ Args
+
+ doit(seg:SOCDF,args:NIA):MS ==
+ Args := copy args
+ Args.range := seg
+ measure(Args::NumericalIntegrationProblem)$AnnaNumericalIntegrationPackage
+
+ transform(c:Boolean,args:NIA):Measure ==
+ if c then
+ l := coerce(recip(lo(args.range)))@OCDF
+ Seg:SOCDF := segment(0$OCDF,l)
+ else
+ h := coerce(recip(hi(args.range)))@OCDF
+ Seg:SOCDF := segment(h,0$OCDF)
+ Args := transformFunction(args)
+ m:MS := doit(Seg,Args)
+ out1:ST :=
+ "The recommendation is to transform the function and use " m.name
+ out2:List(HINT) := [[m.name,Args.fn,Seg,m.extra]]
+ out2Any:Any := coerce(out2)$AnyFunctions1(List(HINT))
+ ex:Record(key:S,entry:Any) := [d01transformextra@S,out2Any]
+ extr:Result := construct([ex])$Result
+ [m.measure,out1,extr]
+
+ split(c:PI,args:NIA):Measure ==
+ Args := copy args
+ Args.relerr := Args.relerr/2
+ Args.abserr := Args.abserr/2
+ if (c = 1)@Boolean then
+ seg1:SOCDF := segment(-1$OCDF,1$OCDF)
+ else if (c = 2)@Boolean then
+ seg1 := segment(lo(Args.range),1$OCDF)
+ else
+ seg1 := segment(-1$OCDF,hi(Args.range))
+ m1:MS := doit(seg1,Args)
+ Args := transformFunction Args
+ if (c = 2)@Boolean then
+ seg2:SOCDF := segment(0$OCDF,1$OCDF)
+ else if (c = 3)@Boolean then
+ seg2 := segment(-1$OCDF,0$OCDF)
+ else seg2 := seg1
+ m2:MS := doit(seg2,Args)
+ m1m:F := m1.measure
+ m2m:F := m2.measure
+ m:F := m1m*m2m/((m1m*m2m)+(1.0-m1m)*(1.0-m2m))
+ out1:ST := "The recommendation is to transform the function and use "
+ m1.name " and " m2.name
+ out2:List(HINT) :=
+ [[m1.name,args.fn,seg1,m1.extra],[m2.name,Args.fn,seg2,m2.extra]]
+ out2Any:Any := coerce(out2)$AnyFunctions1(List(HINT))
+ ex:Record(key:S,entry:Any) := [d01transformextra@S,out2Any]
+ extr:Result := construct([ex])$Result
+ [m,out1,extr]
+
+ measure(R:RoutinesTable,args:NIA) ==
+ Range:=rangeIsFinite(args)
+ Range case bothInfinite => split(1,args)
+ Range case upperInfinite =>
+ positive?(lo(args.range))$OCDF =>
+ transform(true,args)
+ split(2,args)
+ Range case lowerInfinite =>
+ negative?(hi(args.range))$OCDF =>
+ transform(false,args)
+ split(3,args)
+
+ numericalIntegration(args:NIA,hints:Result) ==
+ mainResult:DF := mainAbserr:DF := 0$DF
+ ans:Result := empty()$Result
+ hla:Any := coerce(search((d01transformextra@S),hints)$Result)@Any
+ hintList := retract(hla)$AnyFunctions1(List(HINT))
+ methodName:ST := empty()$ST
+ repeat
+ if (empty?(hintList)$(List(HINT)))
+ then leave
+ item := first(hintList)$List(HINT)
+ a:Result := getIntegral(args,item)
+ anyRes := coerce(search((result@S),a)$Result)@Any
+ midResult := retract(anyRes)$AnyFunctions1(DF)
+ anyErr := coerce(search((abserr pretend S),a)$Result)@Any
+ midAbserr := retract(anyErr)$AnyFunctions1(DF)
+ mainResult := mainResult+midResult
+ mainAbserr := mainAbserr+midAbserr
+ if (methodName = item.str)@Boolean then
+ methodName := concat([item.str,"1"])$ST
+ else
+ methodName := item.str
+ ans := concat(ans,changeName(a,methodName))$ExpertSystemToolsPackage
+ hintList := rest(hintList)$(List(HINT))
+ anyResult := coerce(mainResult)$AnyFunctions1(DF)
+ anyAbserr := coerce(mainAbserr)$AnyFunctions1(DF)
+ recResult:Record(key:S,entry:Any):=[result@S,anyResult]
+ recAbserr:Record(key:S,entry:Any):=[abserr pretend S,anyAbserr]
+ insert!(recAbserr,insert!(recResult,ans))$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain D01TRNS d01TransformFunctionType>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d01weights.spad.pamphlet b/src/algebra/d01weights.spad.pamphlet
new file mode 100644
index 00000000..7f41244f
--- /dev/null
+++ b/src/algebra/d01weights.spad.pamphlet
@@ -0,0 +1,311 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d01weights.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package D01WGTS d01WeightsPackage}
+<<package D01WGTS d01WeightsPackage>>=
+)abbrev package D01WGTS d01WeightsPackage
+++ Author: Brian Dupee
+++ Date Created: July 1994
+++ Date Last Updated: January 1998 (Bug fix - exprHasListOfWeightsCosWXorSinWX)
+++ Basic Operations: exprHasWeightCosWXorSinWX, exprHasAlgebraicWeight,
+++ exprHasLogarithmicWeights
+++ Description:
+++ \axiom{d01WeightsPackage} is a package for functions used to investigate
+++ whether a function can be divided into a simpler function and a weight
+++ function. The types of weights investigated are those giving rise to
+++ end-point singularities of the algebraico-logarithmic type, and
+++ trigonometric weights.
+d01WeightsPackage(): E == I where
+ LEDF ==> List Expression DoubleFloat
+ KEDF ==> Kernel Expression DoubleFloat
+ LKEDF ==> List Kernel Expression DoubleFloat
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ FI ==> Fraction Integer
+ LDF ==> List DoubleFloat
+ DF ==> DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+ NIA ==> Record(var:Symbol,fn:EDF,range:SOCDF,abserr:DF,relerr:DF)
+ INT ==> Integer
+ BOP ==> BasicOperator
+ URBODF ==> Union(Record(op:BasicOperator,w:DF),"failed")
+ LURBODF ==> List(Union(Record(op:BasicOperator,w:DF), "failed"))
+
+ E ==> with
+ exprHasWeightCosWXorSinWX:NIA -> URBODF
+ ++ \axiom{exprHasWeightCosWXorSinWX} looks for trigonometric
+ ++ weights in an expression of the form \axiom{cos \omega x} or
+ ++ \axiom{sin \omega x}, returning the value of \omega
+ ++ (\notequal 1) and the operator.
+ exprHasAlgebraicWeight:NIA -> Union(LDF,"failed")
+ ++ \axiom{exprHasAlgebraicWeight} looks for algebraic weights
+ ++ giving rise to singularities of the function at the end-points.
+ exprHasLogarithmicWeights:NIA -> INT
+ ++ \axiom{exprHasLogarithmicWeights} looks for logarithmic weights
+ ++ giving rise to singularities of the function at the end-points.
+
+
+
+ I ==> add
+ score:(EDF,EDF) -> FI
+ kernelIsLog:KEDF -> Boolean
+ functionIsPolynomial?:EDF -> Boolean
+ functionIsNthRoot?:(EDF,EDF) -> Boolean
+ functionIsQuotient:EDF -> Union(EDF,"failed")
+ findCommonFactor:LEDF -> Union(LEDF,"failed")
+ findAlgebraicWeight:(NIA,EDF) -> Union(DF,"failed")
+ exprHasListOfWeightsCosWXorSinWX:(EDF,Symbol) -> LURBODF
+ exprOfFormCosWXorSinWX:(EDF,Symbol) -> URBODF
+ bestWeight:LURBODF -> URBODF
+ weightIn?:(URBODF,LURBODF) -> Boolean
+ inRest?:(EDF,LEDF)->Boolean
+ factorIn?:(EDF,LEDF)->Boolean
+ voo?:(EDF,EDF)->Boolean
+
+ kernelIsLog(k:KEDF):Boolean ==
+ (name k = (log :: Symbol))@Boolean
+
+ factorIn?(a:EDF,l:LEDF):Boolean ==
+ for i in 1..# l repeat
+ (a = l.i)@Boolean => return true
+ false
+
+ voo?(b:EDF,a:EDF):Boolean ==
+ (voo:=isTimes(b)) case LEDF and factorIn?(a,voo)
+
+ inRest?(a:EDF,l:LEDF):Boolean ==
+ every?( voo?(#1,a) ,l)
+
+ findCommonFactor(l:LEDF):Union(LEDF,"failed") ==
+ empty?(l)$LEDF => "failed"
+ f := first(l)$LEDF
+ r := rest(l)$LEDF
+ (t := isTimes(f)$EDF) case LEDF =>
+ pos:=select(inRest?(#1,r),t)
+ empty?(pos) => "failed"
+ pos
+ "failed"
+
+ exprIsLogarithmicWeight(f:EDF,Var:EDF,a:EDF,b:EDF):INT ==
+ ans := 0$INT
+ k := tower(f)$EDF
+ lf := select(kernelIsLog,k)$LKEDF
+ empty?(lf)$LKEDF => ans
+ for i in 1..# lf repeat
+ arg := argument lf.i
+ if (arg.1 = (Var - a)) then
+ ans := ans + 1
+ else if (arg.1 = (b - Var)) then
+ ans := ans + 2
+ ans
+
+ exprHasLogarithmicWeights(args:NIA):INT ==
+ ans := 1$INT
+ a := getlo(args.range)$d01AgentsPackage :: EDF
+ b := gethi(args.range)$d01AgentsPackage :: EDF
+ Var := args.var :: EDF
+ (l := isPlus numerator args.fn) case LEDF =>
+ (cf := findCommonFactor l) case LEDF =>
+ for j in 1..# cf repeat
+ ans := ans + exprIsLogarithmicWeight(cf.j,Var,a,b)
+ ans
+ ans
+ ans := ans + exprIsLogarithmicWeight(args.fn,Var,a,b)
+
+ functionIsQuotient(expr:EDF):Union(EDF,"failed") ==
+ (k := mainKernel expr) case KEDF =>
+ expr = inv(f := k :: KEDF :: EDF)$EDF => f
+-- one?(numerator expr) => denominator expr
+ (numerator expr = 1) => denominator expr
+ "failed"
+ "failed"
+
+ functionIsPolynomial?(f:EDF):Boolean ==
+ (retractIfCan(f)@Union(PDF,"failed"))$EDF case PDF
+
+ functionIsNthRoot?(f:EDF,e:EDF):Boolean ==
+ (m := mainKernel f) case "failed" => false
+-- (one?(# (kernels f)))
+ ((# (kernels f)) = 1)
+ and (name operator m = (nthRoot :: Symbol))@Boolean
+ and (((argument m).1 = e)@Boolean)
+
+ score(f:EDF,e:EDF):FI ==
+ ans := 0$FI
+ (t := isTimes f) case LEDF =>
+ for i in 1..# t repeat
+ ans := ans + score(t.i,e)
+ ans
+ (q := functionIsQuotient f) case EDF =>
+ ans := ans - score(q,e)
+ functionIsPolynomial? f =>
+ g:EDF := f/e
+ if functionIsPolynomial? g then
+ ans := 1+score(g,e)
+ else
+ ans
+ (l := isPlus f) case LEDF =>
+ (cf := findCommonFactor l) case LEDF =>
+ factor := 1$EDF
+ for i in 1..# cf repeat
+ factor := factor*cf.i
+ ans := ans + score(f/factor,e) + score(factor,e)
+ ans
+ functionIsNthRoot?(f,e) =>
+ (p := isPower f) case "failed" => ans
+ exp := p.exponent
+ m := mainKernel f
+ m case KEDF =>
+ arg := argument m
+ a:INT := (retract(arg.2)@INT)$EDF
+ exp / a
+ ans
+ ans
+
+ findAlgebraicWeight(args:NIA,e:EDF):Union(DF,"failed") ==
+ zero?(s := score(args.fn,e)) => "failed"
+ s :: DF
+
+ exprHasAlgebraicWeight(args:NIA):Union(LDF,"failed") ==
+ (f := functionIsContinuousAtEndPoints(args)$d01AgentsPackage)
+ case continuous =>"failed"
+ Var := args.var :: EDF
+ a := getlo(args.range)$d01AgentsPackage :: EDF
+ b := gethi(args.range)$d01AgentsPackage :: EDF
+ A := Var - a
+ B := b - Var
+ f case lowerSingular =>
+ (h := findAlgebraicWeight(args,A)) case "failed" => "failed"
+ [h,0]
+ f case upperSingular =>
+ (g := findAlgebraicWeight(args,B)) case "failed" => "failed"
+ [0,g]
+ h := findAlgebraicWeight(args,A)
+ g := findAlgebraicWeight(args,B)
+ r := (h case "failed")
+ s := (g case "failed")
+ (r) and (s) => "failed"
+ r => [0,coerce(g)@DF]
+ s => [coerce(h)@DF,0]
+ [coerce(h)@DF,coerce(g)@DF]
+
+ exprOfFormCosWXorSinWX(f:EDF,var:Symbol): URBODF ==
+ l:LKEDF := kernels(f)$EDF
+-- one?((# l)$LKEDF)$INT =>
+ # l = 1 =>
+ a:LEDF := argument(e:KEDF := first(l)$LKEDF)$KEDF
+ empty?(a) => "failed"
+ m:Union(LEDF,"failed") := isTimes(first(a)$LEDF)$EDF
+ m case LEDF => -- if it is a list, it will have at least two elements
+ is?(second(m)$LEDF,var)$EDF =>
+ omega:DF := retract(first(m)$LEDF)@DF
+ o:BOP := operator(n:Symbol:=name(e)$KEDF)$BOP
+ (n = cos@Symbol)@Boolean => [o,omega]
+ (n = sin@Symbol)@Boolean => [o,omega]
+ "failed"
+ "failed"
+ "failed"
+ "failed"
+
+ exprHasListOfWeightsCosWXorSinWX(f:EDF,var:Symbol): LURBODF ==
+ (e := isTimes(f)$EDF) case LEDF =>
+ [exprOfFormCosWXorSinWX(u,var) for u in e]
+ empty?(k := kernels f) => ["failed"]
+ ((first(k)::EDF) = f) =>
+ [exprOfFormCosWXorSinWX(f,var)]
+ ["failed"]
+
+ bestWeight(l:LURBODF): URBODF ==
+ empty?(l)$LURBODF => "failed"
+ best := first(l)$LURBODF -- best is first in list
+ empty?(rest(l)$LURBODF) => best
+ for i in 2..# l repeat -- unless next is better
+ r:URBODF := l.i
+ if r case "failed" then leave
+ else if best case "failed" then
+ best := r
+ else if r.w > best.w then
+ best := r
+ best
+
+ weightIn?(weight:URBODF,listOfWeights:LURBODF):Boolean ==
+ n := # listOfWeights
+ for i in 1..n repeat -- cycle through list
+ (weight = listOfWeights.i)@Boolean => return true -- return when found
+ false
+
+ exprHasWeightCosWXorSinWX(args:NIA):URBODF ==
+ ans := empty()$LURBODF
+ f:EDF := numerator(args.fn)$EDF
+ (t:Union(LEDF,"failed") := isPlus(f)) case "failed" =>
+ bestWeight(exprHasListOfWeightsCosWXorSinWX(f,args.var))
+ if t case LEDF then
+ e1 := first(t)$LEDF
+ le1:LURBODF := exprHasListOfWeightsCosWXorSinWX(e1,args.var)
+ le1 := [u for u in le1 | (not (u case "failed"))]
+ empty?(le1)$LURBODF => "failed"
+ test := true
+ for i in 1..# le1 repeat
+ le1i:URBODF := le1.i
+ for j in 2..# t repeat
+ if test then
+ tj:LURBODF := exprHasListOfWeightsCosWXorSinWX(t.j,args.var)
+ test := weightIn?(le1i,tj)
+ if test then
+ ans := concat([le1i],ans)
+ bestWeight ans
+ else "failed"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package D01WGTS d01WeightsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d02.spad.pamphlet b/src/algebra/d02.spad.pamphlet
new file mode 100644
index 00000000..2b4e3d2b
--- /dev/null
+++ b/src/algebra/d02.spad.pamphlet
@@ -0,0 +1,483 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d02.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGD02 NagOrdinaryDifferentialEquationsPackage}
+<<package NAGD02 NagOrdinaryDifferentialEquationsPackage>>=
+)abbrev package NAGD02 NagOrdinaryDifferentialEquationsPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Mon Jun 20 17:56:33 1994
+++Description:
+++This package uses the NAG Library to calculate the numerical solution of ordinary
+++differential equations. There are two main types of problem,
+++those in which all boundary conditions are specified at one point
+++(initial-value problems), and those in which the boundary
+++conditions are distributed between two or more points (boundary-
+++value problems and eigenvalue problems). Routines are available
+++for initial-value problems, two-point boundary-value problems and
+++Sturm-Liouville eigenvalue problems.
+++See \downlink{Manual Page}{manpageXXd02}.
+NagOrdinaryDifferentialEquationsPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ d02bbf : (DoubleFloat,Integer,Integer,Integer,_
+ DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Union(fn:FileName,fp:Asp7(FCN)),Union(fn:FileName,fp:Asp8(OUTPUT))) -> Result
+ ++ d02bbf(xend,m,n,irelab,x,y,tol,ifail,fcn,output)
+ ++ integrates a system of first-order ordinary differential
+ ++ equations over an interval with suitable initial conditions,
+ ++ using a Runge-Kutta-Merson method, and returns the solution at
+ ++ points specified by the user.
+ ++ See \downlink{Manual Page}{manpageXXd02bbf}.
+ d02bhf : (DoubleFloat,Integer,Integer,DoubleFloat,_
+ DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Union(fn:FileName,fp:Asp9(G)),Union(fn:FileName,fp:Asp7(FCN))) -> Result
+ ++ d02bhf(xend,n,irelab,hmax,x,y,tol,ifail,g,fcn)
+ ++ integrates a system of first-order ordinary differential
+ ++ equations over an interval with suitable initial conditions,
+ ++ using a Runge-Kutta-Merson method, until a user-specified
+ ++ function of the solution is zero.
+ ++ See \downlink{Manual Page}{manpageXXd02bhf}.
+ d02cjf : (DoubleFloat,Integer,Integer,DoubleFloat,_
+ String,DoubleFloat,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp9(G)),Union(fn:FileName,fp:Asp7(FCN)),Union(fn:FileName,fp:Asp8(OUTPUT))) -> Result
+ ++ d02cjf(xend,m,n,tol,relabs,x,y,ifail,g,fcn,output)
+ ++ integrates a system of first-order ordinary differential
+ ++ equations over a range with suitable initial conditions, using a
+ ++ variable-order, variable-step Adams method until a user-specified
+ ++ function, if supplied, of the solution is zero, and returns the
+ ++ solution at points specified by the user, if desired.
+ ++ See \downlink{Manual Page}{manpageXXd02cjf}.
+ d02ejf : (DoubleFloat,Integer,Integer,String,_
+ Integer,DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Union(fn:FileName,fp:Asp9(G)),Union(fn:FileName,fp:Asp7(FCN)),Union(fn:FileName,fp:Asp31(PEDERV)),Union(fn:FileName,fp:Asp8(OUTPUT))) -> Result
+ ++ d02ejf(xend,m,n,relabs,iw,x,y,tol,ifail,g,fcn,pederv,output)
+ ++ integrates a stiff system of first-order ordinary
+ ++ differential equations over an interval with suitable initial
+ ++ conditions, using a variable-order, variable-step method
+ ++ implementing the Backward Differentiation Formulae (BDF), until a
+ ++ user-specified function, if supplied, of the solution is zero,
+ ++ and returns the solution at points specified by the user, if
+ ++ desired.
+ ++ See \downlink{Manual Page}{manpageXXd02ejf}.
+ d02gaf : (Matrix DoubleFloat,Matrix DoubleFloat,Integer,DoubleFloat,_
+ DoubleFloat,DoubleFloat,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Integer,Union(fn:FileName,fp:Asp7(FCN))) -> Result
+ ++ d02gaf(u,v,n,a,b,tol,mnp,lw,liw,x,np,ifail,fcn)
+ ++ solves the two-point boundary-value problem with assigned
+ ++ boundary values for a system of ordinary differential equations,
+ ++ using a deferred correction technique and a Newton iteration.
+ ++ See \downlink{Manual Page}{manpageXXd02gaf}.
+ d02gbf : (DoubleFloat,DoubleFloat,Integer,DoubleFloat,_
+ Integer,Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Integer,Union(fn:FileName,fp:Asp77(FCNF)),Union(fn:FileName,fp:Asp78(FCNG))) -> Result
+ ++ d02gbf(a,b,n,tol,mnp,lw,liw,c,d,gam,x,np,ifail,fcnf,fcng)
+ ++ solves a general linear two-point boundary value problem
+ ++ for a system of ordinary differential equations using a deferred
+ ++ correction technique.
+ ++ See \downlink{Manual Page}{manpageXXd02gbf}.
+ d02kef : (Matrix DoubleFloat,Integer,Integer,DoubleFloat,_
+ Integer,Integer,DoubleFloat,DoubleFloat,Matrix DoubleFloat,Integer,Integer,Union(fn:FileName,fp:Asp10(COEFFN)),Union(fn:FileName,fp:Asp80(BDYVAL))) -> Result
+ ++ d02kef(xpoint,m,k,tol,maxfun,match,elam,delam,hmax,maxit,ifail,coeffn,bdyval)
+ ++ finds a specified eigenvalue of a regular singular second-
+ ++ order Sturm-Liouville system on a finite or infinite range, using
+ ++ a Pruefer transformation and a shooting method. It also reports
+ ++ values of the eigenfunction and its derivatives. Provision is
+ ++ made for discontinuities in the coefficient functions or their
+ ++ derivatives.
+ ++ See \downlink{Manual Page}{manpageXXd02kef}.
+ ++ ASP domains Asp12 and Asp33 are used to supply default
+ ++ subroutines for the MONIT and REPORT arguments via their \axiomOp{outputAsFortran} operation.
+ d02kef : (Matrix DoubleFloat,Integer,Integer,DoubleFloat,_
+ Integer,Integer,DoubleFloat,DoubleFloat,Matrix DoubleFloat,Integer,Integer,Union(fn:FileName,fp:Asp10(COEFFN)),Union(fn:FileName,fp:Asp80(BDYVAL)),FileName,FileName) -> Result
+ ++ d02kef(xpoint,m,k,tol,maxfun,match,elam,delam,hmax,maxit,ifail,coeffn,bdyval,monit,report)
+ ++ finds a specified eigenvalue of a regular singular second-
+ ++ order Sturm-Liouville system on a finite or infinite range, using
+ ++ a Pruefer transformation and a shooting method. It also reports
+ ++ values of the eigenfunction and its derivatives. Provision is
+ ++ made for discontinuities in the coefficient functions or their
+ ++ derivatives.
+ ++ See \downlink{Manual Page}{manpageXXd02kef}.
+ ++ Files \spad{monit} and \spad{report} will be used to define the subroutines for the
+ ++ MONIT and REPORT arguments.
+ ++ See \downlink{Manual Page}{manpageXXd02gbf}.
+ d02raf : (Integer,Integer,Integer,Integer,_
+ DoubleFloat,Integer,Integer,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Union(fn:FileName,fp:Asp41(FCN,JACOBF,JACEPS)),Union(fn:FileName,fp:Asp42(G,JACOBG,JACGEP))) -> Result
+ ++ d02raf(n,mnp,numbeg,nummix,tol,init,iy,ijac,lwork,liwork,np,x,y,deleps,ifail,fcn,g)
+ ++ solves the two-point boundary-value problem with general
+ ++ boundary conditions for a system of ordinary differential
+ ++ equations, using a deferred correction technique and Newton
+ ++ iteration.
+ ++ See \downlink{Manual Page}{manpageXXd02raf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import FortranPackage
+ import Union(fn:FileName,fp:Asp7(FCN))
+ import Union(fn:FileName,fp:Asp8(OUTPUT))
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(String)
+ import AnyFunctions1(Matrix DoubleFloat)
+
+
+ d02bbf(xendArg:DoubleFloat,mArg:Integer,nArg:Integer,_
+ irelabArg:Integer,xArg:DoubleFloat,yArg:Matrix DoubleFloat,_
+ tolArg:DoubleFloat,ifailArg:Integer,fcnArg:Union(fn:FileName,fp:Asp7(FCN)),_
+ outputArg:Union(fn:FileName,fp:Asp8(OUTPUT))): Result ==
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(outputFilename := aspFilename "output")$FOP
+ if outputArg case fn
+ then outputAsFortran(outputArg.fn)
+ else outputAsFortran(outputArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fcnFilename, outputFilename]$Lisp,_
+ "d02bbf",_
+ ["xend"::S,"m"::S,"n"::S,"irelab"::S,"x"::S_
+ ,"tol"::S,"ifail"::S,"fcn"::S,"output"::S,"result"::S,"y"::S,"w"::S]$Lisp,_
+ ["result"::S,"w"::S,"fcn"::S,"output"::S]$Lisp,_
+ [["double"::S,"xend"::S,["result"::S,"m"::S,"n"::S]$Lisp_
+ ,"x"::S,["y"::S,"n"::S]$Lisp,"tol"::S,["w"::S,"n"::S,7$Lisp]$Lisp,"fcn"::S,"output"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"irelab"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"x"::S,"y"::S,"tol"::S,"ifail"::S]$Lisp,_
+ [([xendArg::Any,mArg::Any,nArg::Any,irelabArg::Any,xArg::Any,tolArg::Any,ifailArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02bhf(xendArg:DoubleFloat,nArg:Integer,irelabArg:Integer,_
+ hmaxArg:DoubleFloat,xArg:DoubleFloat,yArg:Matrix DoubleFloat,_
+ tolArg:DoubleFloat,ifailArg:Integer,gArg:Union(fn:FileName,fp:Asp9(G)),_
+ fcnArg:Union(fn:FileName,fp:Asp7(FCN))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename,fcnFilename]$Lisp,_
+ "d02bhf",_
+ ["xend"::S,"n"::S,"irelab"::S,"hmax"::S,"x"::S_
+ ,"tol"::S,"ifail"::S,"g"::S,"fcn"::S,"y"::S,"w"::S]$Lisp,_
+ ["w"::S,"g"::S,"fcn"::S]$Lisp,_
+ [["double"::S,"xend"::S,"hmax"::S,"x"::S,["y"::S,"n"::S]$Lisp_
+ ,"tol"::S,["w"::S,"n"::S,7$Lisp]$Lisp,"g"::S,"fcn"::S]$Lisp_
+ ,["integer"::S,"n"::S,"irelab"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"y"::S,"tol"::S,"ifail"::S]$Lisp,_
+ [([xendArg::Any,nArg::Any,irelabArg::Any,hmaxArg::Any,xArg::Any,tolArg::Any,ifailArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02cjf(xendArg:DoubleFloat,mArg:Integer,nArg:Integer,_
+ tolArg:DoubleFloat,relabsArg:String,xArg:DoubleFloat,_
+ yArg:Matrix DoubleFloat,ifailArg:Integer,gArg:Union(fn:FileName,fp:Asp9(G)),_
+ fcnArg:Union(fn:FileName,fp:Asp7(FCN)),outputArg:Union(fn:FileName,fp:Asp8(OUTPUT))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(outputFilename := aspFilename "output")$FOP
+ if outputArg case fn
+ then outputAsFortran(outputArg.fn)
+ else outputAsFortran(outputArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename,fcnFilename,outputFilename]$Lisp,_
+ "d02cjf",_
+ ["xend"::S,"m"::S,"n"::S,"tol"::S,"relabs"::S_
+ ,"x"::S,"ifail"::S,"g"::S,"fcn"::S,"output"::S_
+ ,"result"::S,"y"::S,"w"::S]$Lisp,_
+ ["result"::S,"w"::S,"g"::S,"fcn"::S,"output"::S]$Lisp,_
+ [["double"::S,"xend"::S,"tol"::S,["result"::S,"m"::S,"n"::S]$Lisp_
+ ,"x"::S,["y"::S,"n"::S]$Lisp,["w"::S,["+"::S,["*"::S,21$Lisp,"n"::S]$Lisp,28$Lisp]$Lisp]$Lisp,"g"::S_
+ ,"fcn"::S,"output"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"relabs"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"x"::S,"y"::S,"ifail"::S]$Lisp,_
+ [([xendArg::Any,mArg::Any,nArg::Any,tolArg::Any,relabsArg::Any,xArg::Any,ifailArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02ejf(xendArg:DoubleFloat,mArg:Integer,nArg:Integer,_
+ relabsArg:String,iwArg:Integer,xArg:DoubleFloat,_
+ yArg:Matrix DoubleFloat,tolArg:DoubleFloat,ifailArg:Integer,_
+ gArg:Union(fn:FileName,fp:Asp9(G)),fcnArg:Union(fn:FileName,fp:Asp7(FCN)),pedervArg:Union(fn:FileName,fp:Asp31(PEDERV)),_
+ outputArg:Union(fn:FileName,fp:Asp8(OUTPUT))): Result ==
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(pedervFilename := aspFilename "pederv")$FOP
+ if pedervArg case fn
+ then outputAsFortran(pedervArg.fn)
+ else outputAsFortran(pedervArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(outputFilename := aspFilename "output")$FOP
+ if outputArg case fn
+ then outputAsFortran(outputArg.fn)
+ else outputAsFortran(outputArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([gFilename,fcnFilename,pedervFilename,outputFilename]$Lisp,_
+ "d02ejf",_
+ ["xend"::S,"m"::S,"n"::S,"relabs"::S,"iw"::S_
+ ,"x"::S,"tol"::S,"ifail"::S,"g"::S,"fcn"::S_
+ ,"pederv"::S,"output"::S,"result"::S,"y"::S,"w"::S]$Lisp,_
+ ["result"::S,"w"::S,"g"::S,"fcn"::S,"pederv"::S,"output"::S]$Lisp,_
+ [["double"::S,"xend"::S,["result"::S,"m"::S,"n"::S]$Lisp_
+ ,"x"::S,["y"::S,"n"::S]$Lisp,"tol"::S,["w"::S,"iw"::S]$Lisp,"g"::S,"fcn"::S,"pederv"::S,"output"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"iw"::S,"ifail"::S_
+ ]$Lisp_
+ ,["character"::S,"relabs"::S]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"x"::S,"y"::S,"tol"::S,"ifail"::S]$Lisp,_
+ [([xendArg::Any,mArg::Any,nArg::Any,relabsArg::Any,iwArg::Any,xArg::Any,tolArg::Any,ifailArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02gaf(uArg:Matrix DoubleFloat,vArg:Matrix DoubleFloat,nArg:Integer,_
+ aArg:DoubleFloat,bArg:DoubleFloat,tolArg:DoubleFloat,_
+ mnpArg:Integer,lwArg:Integer,liwArg:Integer,_
+ xArg:Matrix DoubleFloat,npArg:Integer,ifailArg:Integer,_
+ fcnArg:Union(fn:FileName,fp:Asp7(FCN))): Result ==
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fcnFilename]$Lisp,_
+ "d02gaf",_
+ ["n"::S,"a"::S,"b"::S,"tol"::S,"mnp"::S_
+ ,"lw"::S,"liw"::S,"np"::S,"ifail"::S,"fcn"::S_
+ ,"u"::S,"v"::S,"y"::S,"x"::S,"w"::S_
+ ,"iw"::S]$Lisp,_
+ ["y"::S,"w"::S,"iw"::S,"fcn"::S]$Lisp,_
+ [["double"::S,["u"::S,"n"::S,2$Lisp]$Lisp,["v"::S,"n"::S,2$Lisp]$Lisp_
+ ,"a"::S,"b"::S,"tol"::S,["y"::S,"n"::S,"mnp"::S]$Lisp,["x"::S,"mnp"::S]$Lisp,["w"::S,"lw"::S]$Lisp_
+ ,"fcn"::S]$Lisp_
+ ,["integer"::S,"n"::S,"mnp"::S,"lw"::S,"liw"::S_
+ ,"np"::S,"ifail"::S,["iw"::S,"liw"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["y"::S,"x"::S,"np"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,aArg::Any,bArg::Any,tolArg::Any,mnpArg::Any,lwArg::Any,liwArg::Any,npArg::Any,ifailArg::Any,uArg::Any,vArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02gbf(aArg:DoubleFloat,bArg:DoubleFloat,nArg:Integer,_
+ tolArg:DoubleFloat,mnpArg:Integer,lwArg:Integer,_
+ liwArg:Integer,cArg:Matrix DoubleFloat,dArg:Matrix DoubleFloat,_
+ gamArg:Matrix DoubleFloat,xArg:Matrix DoubleFloat,npArg:Integer,_
+ ifailArg:Integer,fcnfArg:Union(fn:FileName,fp:Asp77(FCNF)),fcngArg:Union(fn:FileName,fp:Asp78(FCNG))): Result ==
+ pushFortranOutputStack(fcnfFilename := aspFilename "fcnf")$FOP
+ if fcnfArg case fn
+ then outputAsFortran(fcnfArg.fn)
+ else outputAsFortran(fcnfArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(fcngFilename := aspFilename "fcng")$FOP
+ if fcngArg case fn
+ then outputAsFortran(fcngArg.fn)
+ else outputAsFortran(fcngArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fcnfFilename,fcngFilename]$Lisp,_
+ "d02gbf",_
+ ["a"::S,"b"::S,"n"::S,"tol"::S,"mnp"::S_
+ ,"lw"::S,"liw"::S,"np"::S,"ifail"::S,"fcnf"::S_
+ ,"fcng"::S,"y"::S,"c"::S,"d"::S,"gam"::S,"x"::S_
+ ,"w"::S,"iw"::S]$Lisp,_
+ ["y"::S,"w"::S,"iw"::S,"fcnf"::S,"fcng"::S]$Lisp,_
+ [["double"::S,"a"::S,"b"::S,"tol"::S,["y"::S,"n"::S,"mnp"::S]$Lisp_
+ ,["c"::S,"n"::S,"n"::S]$Lisp,["d"::S,"n"::S,"n"::S]$Lisp,["gam"::S,"n"::S]$Lisp,["x"::S,"mnp"::S]$Lisp_
+ ,["w"::S,"lw"::S]$Lisp,"fcnf"::S,"fcng"::S]$Lisp_
+ ,["integer"::S,"n"::S,"mnp"::S,"lw"::S,"liw"::S_
+ ,"np"::S,"ifail"::S,["iw"::S,"liw"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["y"::S,"c"::S,"d"::S,"gam"::S,"x"::S,"np"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,bArg::Any,nArg::Any,tolArg::Any,mnpArg::Any,lwArg::Any,liwArg::Any,npArg::Any,ifailArg::Any,cArg::Any,dArg::Any,gamArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02kef(xpointArg:Matrix DoubleFloat,mArg:Integer,kArg:Integer,_
+ tolArg:DoubleFloat,maxfunArg:Integer,matchArg:Integer,_
+ elamArg:DoubleFloat,delamArg:DoubleFloat,hmaxArg:Matrix DoubleFloat,_
+ maxitArg:Integer,ifailArg:Integer,coeffnArg:Union(fn:FileName,fp:Asp10(COEFFN)),_
+ bdyvalArg:Union(fn:FileName,fp:Asp80(BDYVAL))): Result ==
+ pushFortranOutputStack(coeffnFilename := aspFilename "coeffn")$FOP
+ if coeffnArg case fn
+ then outputAsFortran(coeffnArg.fn)
+ else outputAsFortran(coeffnArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(bdyvalFilename := aspFilename "bdyval")$FOP
+ if bdyvalArg case fn
+ then outputAsFortran(bdyvalArg.fn)
+ else outputAsFortran(bdyvalArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(monitFilename := aspFilename "monit")$FOP
+ outputAsFortran()$Asp12(MONIT)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(reportFilename := aspFilename "report")$FOP
+ outputAsFortran()$Asp33(REPORT)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([coeffnFilename,bdyvalFilename,monitFilename,reportFilename]$Lisp,_
+ "d02kef",_
+ ["m"::S,"k"::S,"tol"::S,"maxfun"::S,"match"::S_
+ ,"elam"::S,"delam"::S,"maxit"::S,"ifail"::S,"coeffn"::S_
+ ,"bdyval"::S,"monit"::S,"report"::S,"xpoint"::S,"hmax"::S]$Lisp,_
+ ["coeffn"::S,"bdyval"::S,"monit"::S,"report"::S]$Lisp,_
+ [["double"::S,["xpoint"::S,"m"::S]$Lisp,"tol"::S_
+ ,"elam"::S,"delam"::S,["hmax"::S,2$Lisp,"m"::S]$Lisp,"coeffn"::S,"bdyval"::S,"monit"::S,"report"::S]$Lisp_
+ ,["integer"::S,"m"::S,"k"::S,"maxfun"::S,"match"::S_
+ ,"maxit"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["match"::S,"elam"::S,"delam"::S,"hmax"::S,"maxit"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,kArg::Any,tolArg::Any,maxfunArg::Any,matchArg::Any,elamArg::Any,delamArg::Any,maxitArg::Any,ifailArg::Any,xpointArg::Any,hmaxArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02kef(xpointArg:Matrix DoubleFloat,mArg:Integer,kArg:Integer,_
+ tolArg:DoubleFloat,maxfunArg:Integer,matchArg:Integer,_
+ elamArg:DoubleFloat,delamArg:DoubleFloat,hmaxArg:Matrix DoubleFloat,_
+ maxitArg:Integer,ifailArg:Integer,coeffnArg:Union(fn:FileName,fp:Asp10(COEFFN)),_
+ bdyvalArg:Union(fn:FileName,fp:Asp80(BDYVAL)),monitArg:FileName,reportArg:FileName): Result ==
+ pushFortranOutputStack(coeffnFilename := aspFilename "coeffn")$FOP
+ if coeffnArg case fn
+ then outputAsFortran(coeffnArg.fn)
+ else outputAsFortran(coeffnArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(bdyvalFilename := aspFilename "bdyval")$FOP
+ if bdyvalArg case fn
+ then outputAsFortran(bdyvalArg.fn)
+ else outputAsFortran(bdyvalArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(monitFilename := aspFilename "monit")$FOP
+ outputAsFortran(monitArg)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(reportFilename := aspFilename "report")$FOP
+ outputAsFortran(reportArg)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([coeffnFilename,bdyvalFilename,monitFilename,reportFilename]$Lisp,_
+ "d02kef",_
+ ["m"::S,"k"::S,"tol"::S,"maxfun"::S,"match"::S_
+ ,"elam"::S,"delam"::S,"maxit"::S,"ifail"::S,"coeffn"::S_
+ ,"bdyval"::S,"monit"::S,"report"::S,"xpoint"::S,"hmax"::S]$Lisp,_
+ ["coeffn"::S,"bdyval"::S,"monit"::S,"report"::S]$Lisp,_
+ [["double"::S,["xpoint"::S,"m"::S]$Lisp,"tol"::S_
+ ,"elam"::S,"delam"::S,["hmax"::S,2$Lisp,"m"::S]$Lisp,"coeffn"::S,"bdyval"::S,"monit"::S,"report"::S]$Lisp_
+ ,["integer"::S,"m"::S,"k"::S,"maxfun"::S,"match"::S_
+ ,"maxit"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["match"::S,"elam"::S,"delam"::S,"hmax"::S,"maxit"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,kArg::Any,tolArg::Any,maxfunArg::Any,matchArg::Any,elamArg::Any,delamArg::Any,maxitArg::Any,ifailArg::Any,xpointArg::Any,hmaxArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d02raf(nArg:Integer,mnpArg:Integer,numbegArg:Integer,_
+ nummixArg:Integer,tolArg:DoubleFloat,initArg:Integer,_
+ iyArg:Integer,ijacArg:Integer,lworkArg:Integer,_
+ liworkArg:Integer,npArg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,delepsArg:DoubleFloat,ifailArg:Integer,_
+ fcnArg:Union(fn:FileName,fp:Asp41(FCN,JACOBF,JACEPS)),gArg:Union(fn:FileName,fp:Asp42(G,JACOBG,JACGEP))): Result ==
+ pushFortranOutputStack(fcnFilename := aspFilename "fcn")$FOP
+ if fcnArg case fn
+ then outputAsFortran(fcnArg.fn)
+ else outputAsFortran(fcnArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(gFilename := aspFilename "g")$FOP
+ if gArg case fn
+ then outputAsFortran(gArg.fn)
+ else outputAsFortran(gArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([fcnFilename,gFilename]$Lisp,_
+ "d02raf",_
+ ["n"::S,"mnp"::S,"numbeg"::S,"nummix"::S,"tol"::S_
+ ,"init"::S,"iy"::S,"ijac"::S,"lwork"::S,"liwork"::S_
+ ,"np"::S,"deleps"::S,"ifail"::S,"fcn"::S,"g"::S_
+ ,"abt"::S,"x"::S,"y"::S,"work"::S,"iwork"::S_
+ ]$Lisp,_
+ ["abt"::S,"work"::S,"iwork"::S,"fcn"::S,"g"::S]$Lisp,_
+ [["double"::S,"tol"::S,["abt"::S,"n"::S]$Lisp_
+ ,["x"::S,"mnp"::S]$Lisp,["y"::S,"iy"::S,"mnp"::S]$Lisp,"deleps"::S,["work"::S,"lwork"::S]$Lisp,"fcn"::S,"g"::S]$Lisp_
+ ,["integer"::S,"n"::S,"mnp"::S,"numbeg"::S_
+ ,"nummix"::S,"init"::S,"iy"::S,"ijac"::S,"lwork"::S,"liwork"::S,"np"::S,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["abt"::S,"np"::S,"x"::S,"y"::S,"deleps"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,mnpArg::Any,numbegArg::Any,nummixArg::Any,tolArg::Any,initArg::Any,iyArg::Any,ijacArg::Any,lworkArg::Any,liworkArg::Any,npArg::Any,delepsArg::Any,ifailArg::Any,xArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGD02 NagOrdinaryDifferentialEquationsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d02Package.spad.pamphlet b/src/algebra/d02Package.spad.pamphlet
new file mode 100644
index 00000000..35d581e9
--- /dev/null
+++ b/src/algebra/d02Package.spad.pamphlet
@@ -0,0 +1,457 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d02Package.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ODEPACK AnnaOrdinaryDifferentialEquationPackage}
+<<package ODEPACK AnnaOrdinaryDifferentialEquationPackage>>=
+)abbrev package ODEPACK AnnaOrdinaryDifferentialEquationPackage
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: December 1997
+++ Basic Operations: solve, measure
+++ Description:
+++ \axiomType{AnnaOrdinaryDifferentialEquationPackage} is a \axiom{package}
+++ of functions for the \axiom{category} \axiomType{OrdinaryDifferentialEquationsSolverCategory}
+++ with \axiom{measure}, and \axiom{solve}.
+++
+EDF ==> Expression DoubleFloat
+LDF ==> List DoubleFloat
+MDF ==> Matrix DoubleFloat
+DF ==> DoubleFloat
+FI ==> Fraction Integer
+EFI ==> Expression Fraction Integer
+SOCDF ==> Segment OrderedCompletion DoubleFloat
+VEDF ==> Vector Expression DoubleFloat
+VEF ==> Vector Expression Float
+EF ==> Expression Float
+LF ==> List Float
+F ==> Float
+VDF ==> Vector DoubleFloat
+VMF ==> Vector MachineFloat
+MF ==> MachineFloat
+LS ==> List Symbol
+ST ==> String
+LST ==> List String
+INT ==> Integer
+RT ==> RoutinesTable
+ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,_
+ g:EDF,abserr:DF,relerr:DF)
+IFL ==> List(Record(ifail:Integer,instruction:String))
+Entry ==> Record(chapter:String, type:String, domainName: String,
+ defaultMin:F, measure:F, failList:IFL, explList:LST)
+Measure ==> Record(measure:F,name:String, explanations:List String)
+
+AnnaOrdinaryDifferentialEquationPackage(): with
+ solve:(NumericalODEProblem) -> Result
+ ++ solve(odeProblem) is a top level ANNA function to solve numerically a
+ ++ system of ordinary differential equations i.e. equations for the
+ ++ derivatives Y[1]'..Y[n]' defined in terms of X,Y[1]..Y[n], together
+ ++ with starting values for X and Y[1]..Y[n] (called the initial
+ ++ conditions), a final value of X, an accuracy requirement and any
+ ++ intermediate points at which the result is required.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory}
+ ++ to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(NumericalODEProblem,RT) -> Result
+ ++ solve(odeProblem,R) is a top level ANNA function to solve numerically a
+ ++ system of ordinary differential equations i.e. equations for the
+ ++ derivatives Y[1]'..Y[n]' defined in terms of X,Y[1]..Y[n], together
+ ++ with starting values for X and Y[1]..Y[n] (called the initial
+ ++ conditions), a final value of X, an accuracy requirement and any
+ ++ intermediate points at which the result is required.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(VEF,F,F,LF) -> Result
+ ++ solve(f,xStart,xEnd,yInitial) is a top level ANNA function to solve numerically a
+ ++ system of ordinary differential equations i.e. equations for the
+ ++ derivatives Y[1]'..Y[n]' defined in terms of X,Y[1]..Y[n], together
+ ++ with a starting value for X and Y[1]..Y[n] (called the initial
+ ++ conditions) and a final value of X. A default value
+ ++ is used for the accuracy requirement.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(VEF,F,F,LF,F) -> Result
+ ++ solve(f,xStart,xEnd,yInitial,tol) is a top level ANNA function to solve
+ ++ numerically a system of ordinary differential equations, \axiom{f}, i.e.
+ ++ equations for the derivatives Y[1]'..Y[n]' defined in terms
+ ++ of X,Y[1]..Y[n] from \axiom{xStart} to \axiom{xEnd} with the initial
+ ++ values for Y[1]..Y[n] (\axiom{yInitial}) to a tolerance \axiom{tol}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(VEF,F,F,LF,EF,F) -> Result
+ ++ solve(f,xStart,xEnd,yInitial,G,tol) is a top level ANNA function to solve
+ ++ numerically a system of ordinary differential equations, \axiom{f}, i.e.
+ ++ equations for the derivatives Y[1]'..Y[n]' defined in terms
+ ++ of X,Y[1]..Y[n] from \axiom{xStart} to \axiom{xEnd} with the initial
+ ++ values for Y[1]..Y[n] (\axiom{yInitial}) to a tolerance \axiom{tol}.
+ ++ The calculation will stop if the function G(X,Y[1],..,Y[n]) evaluates to zero before
+ ++ X = xEnd.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(VEF,F,F,LF,LF,F) -> Result
+ ++ solve(f,xStart,xEnd,yInitial,intVals,tol) is a top level ANNA function to solve
+ ++ numerically a system of ordinary differential equations, \axiom{f}, i.e.
+ ++ equations for the derivatives Y[1]'..Y[n]' defined in terms
+ ++ of X,Y[1]..Y[n] from \axiom{xStart} to \axiom{xEnd} with the initial
+ ++ values for Y[1]..Y[n] (\axiom{yInitial}) to a tolerance \axiom{tol}.
+ ++ The values of Y[1]..Y[n] will be output for the values of X in
+ ++ \axiom{intVals}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(VEF,F,F,LF,EF,LF,F) -> Result
+ ++ solve(f,xStart,xEnd,yInitial,G,intVals,tol) is a top level ANNA function to solve
+ ++ numerically a system of ordinary differential equations, \axiom{f}, i.e.
+ ++ equations for the derivatives Y[1]'..Y[n]' defined in terms
+ ++ of X,Y[1]..Y[n] from \axiom{xStart} to \axiom{xEnd} with the initial
+ ++ values for Y[1]..Y[n] (\axiom{yInitial}) to a tolerance \axiom{tol}.
+ ++ The values of Y[1]..Y[n] will be output for the values of X in
+ ++ \axiom{intVals}. The calculation will stop if the function
+ ++ G(X,Y[1],..,Y[n]) evaluates to zero before X = xEnd.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ solve:(VEF,F,F,LF,EF,LF,F,F) -> Result
+ ++ solve(f,xStart,xEnd,yInitial,G,intVals,epsabs,epsrel) is a top level ANNA function to solve
+ ++ numerically a system of ordinary differential equations, \axiom{f}, i.e.
+ ++ equations for the derivatives Y[1]'..Y[n]' defined in terms
+ ++ of X,Y[1]..Y[n] from \axiom{xStart} to \axiom{xEnd} with the initial
+ ++ values for Y[1]..Y[n] (\axiom{yInitial}) to an absolute error
+ ++ requirement \axiom{epsabs} and relative error \axiom{epsrel}.
+ ++ The values of Y[1]..Y[n] will be output for the values of X in
+ ++ \axiom{intVals}. The calculation will stop if the function
+ ++ G(X,Y[1],..,Y[n]) evaluates to zero before X = xEnd.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} contained in
+ ++ the table of routines \axiom{R} to get the name and other
+ ++ relevant information of the the (domain of the) numerical
+ ++ routine likely to be the most appropriate,
+ ++ i.e. have the best \axiom{measure}.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of ODE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ measure:(NumericalODEProblem) -> Measure
+ ++ measure(prob) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical ODE
+ ++ problem defined by \axiom{prob}.
+ ++
+ ++ It calls each \axiom{domain} of \axiom{category}
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} in turn to
+ ++ calculate all measures and returns the best i.e. the name of
+ ++ the most appropriate domain and any other relevant information.
+ ++ It predicts the likely most effective NAG numerical
+ ++ Library routine to solve the input set of ODEs
+ ++ by checking various attributes of the system of ODEs and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ measure:(NumericalODEProblem,RT) -> Measure
+ ++ measure(prob,R) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical ODE
+ ++ problem defined by \axiom{prob}.
+ ++
+ ++ It calls each \axiom{domain} listed in \axiom{R} of \axiom{category}
+ ++ \axiomType{OrdinaryDifferentialEquationsSolverCategory} in turn to
+ ++ calculate all measures and returns the best i.e. the name of
+ ++ the most appropriate domain and any other relevant information.
+ ++ It predicts the likely most effective NAG numerical
+ ++ Library routine to solve the input set of ODEs
+ ++ by checking various attributes of the system of ODEs and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+
+ == add
+
+ import ODEA,NumericalODEProblem
+
+ f2df:F -> DF
+ ef2edf:EF -> EDF
+ preAnalysis:(ODEA,RT) -> RT
+ zeroMeasure:Measure -> Result
+ measureSpecific:(ST,RT,ODEA) -> Record(measure:F,explanations:ST)
+ solveSpecific:(ODEA,ST) -> Result
+ changeName:(Result,ST) -> Result
+ recoverAfterFail:(ODEA,RT,Measure,Integer,Result) -> Record(a:Result,b:Measure)
+
+ f2df(f:F):DF == (convert(f)@DF)$F
+
+ ef2edf(f:EF):EDF == map(f2df,f)$ExpressionFunctions2(F,DF)
+
+ preAnalysis(args:ODEA,t:RT):RT ==
+ rt := selectODEIVPRoutines(t)$RT
+ if positive?(# variables(args.g)) then
+ changeMeasure(rt,d02bbf@Symbol,getMeasure(rt,d02bbf@Symbol)*0.8)
+ if positive?(# args.intvals) then
+ changeMeasure(rt,d02bhf@Symbol,getMeasure(rt,d02bhf@Symbol)*0.8)
+ rt
+
+ zeroMeasure(m:Measure):Result ==
+ a := coerce(0$F)$AnyFunctions1(F)
+ text := coerce("Zero Measure")$AnyFunctions1(ST)
+ r := construct([[result@Symbol,a],[method@Symbol,text]])$Result
+ concat(measure2Result m,r)$ExpertSystemToolsPackage
+
+ measureSpecific(name:ST,R:RT,ode:ODEA):Record(measure:F,explanations:ST) ==
+ name = "d02bbfAnnaType" => measure(R,ode)$d02bbfAnnaType
+ name = "d02bhfAnnaType" => measure(R,ode)$d02bhfAnnaType
+ name = "d02cjfAnnaType" => measure(R,ode)$d02cjfAnnaType
+ name = "d02ejfAnnaType" => measure(R,ode)$d02ejfAnnaType
+ error("measureSpecific","invalid type name: " name)$ErrorFunctions
+
+ measure(Ode:NumericalODEProblem,R:RT):Measure ==
+ ode:ODEA := retract(Ode)$NumericalODEProblem
+ sofar := 0$F
+ best := "none" :: ST
+ routs := copy R
+ routs := preAnalysis(ode,routs)
+ empty?(routs)$RT =>
+ error("measure", "no routines found")$ErrorFunctions
+ rout := inspect(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ meth := empty()$LST
+ for i in 1..# routs repeat
+ rout := extract!(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ n := e.domainName
+ if e.defaultMin > sofar then
+ m := measureSpecific(n,R,ode)
+ if m.measure > sofar then
+ sofar := m.measure
+ best := n
+ str:LST := [string(rout.key)$Symbol "measure: "
+ outputMeasure(m.measure)$ExpertSystemToolsPackage " - "
+ m.explanations]
+ else
+ str := [string(rout.key)$Symbol " is no better than other routines"]
+ meth := append(meth,str)$LST
+ [sofar,best,meth]
+
+ measure(ode:NumericalODEProblem):Measure == measure(ode,routines()$RT)
+
+ solveSpecific(ode:ODEA,n:ST):Result ==
+ n = "d02bbfAnnaType" => ODESolve(ode)$d02bbfAnnaType
+ n = "d02bhfAnnaType" => ODESolve(ode)$d02bhfAnnaType
+ n = "d02cjfAnnaType" => ODESolve(ode)$d02cjfAnnaType
+ n = "d02ejfAnnaType" => ODESolve(ode)$d02ejfAnnaType
+ error("solveSpecific","invalid type name: " n)$ErrorFunctions
+
+ changeName(ans:Result,name:ST):Result ==
+ sy:Symbol := coerce(name "Answer")$Symbol
+ anyAns:Any := coerce(ans)$AnyFunctions1(Result)
+ construct([[sy,anyAns]])$Result
+
+ recoverAfterFail(ode:ODEA,routs:RT,m:Measure,iint:Integer,r:Result):
+ Record(a:Result,b:Measure) ==
+ while positive?(iint) repeat
+ routineName := m.name
+ s := recoverAfterFail(routs,routineName(1..6),iint)$RT
+ s case "failed" => iint := 0
+ if s = "increase tolerance" then
+ ode.relerr := ode.relerr*(10.0::DF)
+ ode.abserr := ode.abserr*(10.0::DF)
+ if s = "decrease tolerance" then
+ ode.relerr := ode.relerr/(10.0::DF)
+ ode.abserr := ode.abserr/(10.0::DF)
+ (s = "no action")@Boolean => iint := 0
+ fl := coerce(s)$AnyFunctions1(ST)
+ flrec:Record(key:Symbol,entry:Any):=[failure@Symbol,fl]
+ m2 := measure(ode::NumericalODEProblem,routs)
+ zero?(m2.measure) => iint := 0
+ r2:Result := solveSpecific(ode,m2.name)
+ m := m2
+ insert!(flrec,r2)$Result
+ r := concat(r2,changeName(r,routineName))$ExpertSystemToolsPackage
+ iany := search(ifail@Symbol,r2)$Result
+ iany case "failed" => iint := 0
+ iint := retract(iany)$AnyFunctions1(Integer)
+ [r,m]
+
+ solve(Ode:NumericalODEProblem,t:RT):Result ==
+ ode:ODEA := retract(Ode)$NumericalODEProblem
+ routs := copy(t)$RT
+ m := measure(Ode,routs)
+ zero?(m.measure) => zeroMeasure m
+ r := solveSpecific(ode,n := m.name)
+ iany := search(ifail@Symbol,r)$Result
+ iint := 0$Integer
+ if (iany case Any) then
+ iint := retract(iany)$AnyFunctions1(Integer)
+ if positive?(iint) then
+ tu:Record(a:Result,b:Measure) := recoverAfterFail(ode,routs,m,iint,r)
+ r := tu.a
+ m := tu.b
+ r := concat(measure2Result m,r)$ExpertSystemToolsPackage
+ expl := getExplanations(routs,n(1..6))$RoutinesTable
+ expla := coerce(expl)$AnyFunctions1(LST)
+ explaa:Record(key:Symbol,entry:Any) := ["explanations"::Symbol,expla]
+ r := concat(construct([explaa]),r)
+ iflist := showIntensityFunctions(ode)$ODEIntensityFunctionsTable
+ iflist case "failed" => r
+ concat(iflist2Result iflist, r)$ExpertSystemToolsPackage
+
+ solve(ode:NumericalODEProblem):Result == solve(ode,routines()$RT)
+
+ solve(f:VEF,xStart:F,xEnd:F,yInitial:LF,G:EF,intVals:LF,epsabs:F,epsrel:F):Result ==
+ d:ODEA := [f2df xStart,f2df xEnd,vector([ef2edf e for e in members f])$VEDF,
+ [f2df i for i in yInitial], [f2df j for j in intVals],
+ ef2edf G,f2df epsabs,f2df epsrel]
+ solve(d::NumericalODEProblem,routines()$RT)
+
+ solve(f:VEF,xStart:F,xEnd:F,yInitial:LF,G:EF,intVals:LF,tol:F):Result ==
+ solve(f,xStart,xEnd,yInitial,G,intVals,tol,tol)
+
+ solve(f:VEF,xStart:F,xEnd:F,yInitial:LF,intVals:LF,tol:F):Result ==
+ solve(f,xStart,xEnd,yInitial,1$EF,intVals,tol)
+
+ solve(f:VEF,xStart:F,xEnd:F,y:LF,G:EF,tol:F):Result ==
+ solve(f,xStart,xEnd,y,G,empty()$LF,tol)
+
+ solve(f:VEF,xStart:F,xEnd:F,yInitial:LF,tol:F):Result ==
+ solve(f,xStart,xEnd,yInitial,1$EF,empty()$LF,tol)
+
+ solve(f:VEF,xStart:F,xEnd:F,yInitial:LF):Result == solve(f,xStart,xEnd,yInitial,1.0e-4)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ODEPACK AnnaOrdinaryDifferentialEquationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d02agents.spad.pamphlet b/src/algebra/d02agents.spad.pamphlet
new file mode 100644
index 00000000..d3e18ec4
--- /dev/null
+++ b/src/algebra/d02agents.spad.pamphlet
@@ -0,0 +1,424 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d02agents.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ODEIFTBL ODEIntensityFunctionsTable}
+<<domain ODEIFTBL ODEIntensityFunctionsTable>>=
+)abbrev domain ODEIFTBL ODEIntensityFunctionsTable
+++ Author: Brian Dupee
+++ Date Created: May 1994
+++ Date Last Updated: January 1996
+++ Basic Operations: showTheIFTable, insert!
+++ Description:
+++ \axiom{ODEIntensityFunctionsTable()} provides a dynamic table and a set of
+++ functions to store details found out about sets of ODE's.
+
+ODEIntensityFunctionsTable(): E == I where
+ LEDF ==> List Expression DoubleFloat
+ LEEDF ==> List Equation Expression DoubleFloat
+ EEDF ==> Equation Expression DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ MEDF ==> Matrix Expression DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ EDF ==> Expression DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ INT ==> Integer
+ CDF ==> Complex DoubleFloat
+ LDF ==> List DoubleFloat
+ LF ==> List Float
+ S ==> Symbol
+ LS ==> List Symbol
+ MFI ==> Matrix Fraction Integer
+ LFI ==> List Fraction Integer
+ FI ==> Fraction Integer
+ ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,g:EDF,abserr:DF,relerr:DF)
+ ON ==> Record(additions:INT,multiplications:INT,exponentiations:INT,functionCalls:INT)
+ RVE ==> Record(val:EDF,exponent:INT)
+ RSS ==> Record(stiffnessFactor:F,stabilityFactor:F)
+ ATT ==> Record(stiffness:F,stability:F,expense:F,accuracy:F,intermediateResults:F)
+ ROA ==> Record(key:ODEA,entry:ATT)
+
+ E ==> with
+ showTheIFTable:() -> $
+ ++ showTheIFTable() returns the current table of intensity functions.
+ clearTheIFTable : () -> Void
+ ++ clearTheIFTable() clears the current table of intensity functions.
+ keys : $ -> List(ODEA)
+ ++ keys(tab) returns the list of keys of f
+ iFTable: List Record(key:ODEA,entry:ATT) -> $
+ ++ iFTable(l) creates an intensity-functions table from the elements
+ ++ of l.
+ insert!:Record(key:ODEA,entry:ATT) -> $
+ ++ insert!(r) inserts an entry r into theIFTable
+ showIntensityFunctions:ODEA -> Union(ATT,"failed")
+ ++ showIntensityFunctions(k) returns the entries in the
+ ++ table of intensity functions k.
+
+ I ==> add
+ Rep := Table(ODEA,ATT)
+ import Rep
+
+ theIFTable:$ := empty()$Rep
+
+ showTheIFTable():$ ==
+ theIFTable
+
+ clearTheIFTable():Void ==
+ theIFTable := empty()$Rep
+ void()$Void
+
+ iFTable(l:List Record(key:ODEA,entry:ATT)):$ ==
+ theIFTable := table(l)$Rep
+
+ insert!(r:Record(key:ODEA,entry:ATT)):$ ==
+ insert!(r,theIFTable)$Rep
+
+ keys(t:$):List ODEA ==
+ keys(t)$Rep
+
+ showIntensityFunctions(k:ODEA):Union(ATT,"failed") ==
+ search(k,theIFTable)$Rep
+
+@
+\section{package D02AGNT d02AgentsPackage}
+<<package D02AGNT d02AgentsPackage>>=
+)abbrev package D02AGNT d02AgentsPackage
+++ Author: Brian Dupee
+++ Date Created: May 1994
+++ Date Last Updated: January 1997
+++ Basic Operations: stiffnessFactor, jacobian
+++ Description:
+++ \axiom{d02AgentsPackage} contains a set of computational agents
+++ for use with Ordinary Differential Equation solvers.
+d02AgentsPackage(): E == I where
+ LEDF ==> List Expression DoubleFloat
+ LEEDF ==> List Equation Expression DoubleFloat
+ EEDF ==> Equation Expression DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ MEDF ==> Matrix Expression DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ EDF ==> Expression DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ INT ==> Integer
+ CDF ==> Complex DoubleFloat
+ LDF ==> List DoubleFloat
+ LF ==> List Float
+ S ==> Symbol
+ LS ==> List Symbol
+ MFI ==> Matrix Fraction Integer
+ LFI ==> List Fraction Integer
+ FI ==> Fraction Integer
+ ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,g:EDF,abserr:DF,relerr:DF)
+ ON ==> Record(additions:INT,multiplications:INT,exponentiations:INT,functionCalls:INT)
+ RVE ==> Record(val:EDF,exponent:INT)
+ RSS ==> Record(stiffnessFactor:F,stabilityFactor:F)
+ ATT ==> Record(stiffness:F,stability:F,expense:F,accuracy:F,intermediateResults:F)
+ ROA ==> Record(key:ODEA,entry:ATT)
+
+ E ==> with
+ combineFeatureCompatibility: (F,F) -> F
+ ++ combineFeatureCompatibility(C1,C2) is for interacting attributes
+ combineFeatureCompatibility: (F,LF) -> F
+ ++ combineFeatureCompatibility(C1,L) is for interacting attributes
+ sparsityIF: MEDF -> F
+ ++ sparsityIF(m) calculates the sparsity of a jacobian matrix
+ jacobian: (VEDF,LS) -> MEDF
+ ++ jacobian(v,w) is a local function to make a jacobian matrix
+ eval: (MEDF,LS,VEDF) -> MEDF
+ ++ eval(mat,symbols,values) evaluates a multivariable matrix at given values
+ ++ for each of a list of variables
+ stiffnessAndStabilityFactor: MEDF -> RSS
+ ++ stiffnessAndStabilityFactor(me) calculates the stability and
+ ++ stiffness factor of a system of first-order differential equations
+ ++ (by evaluating the maximum difference in the real parts of the
+ ++ negative eigenvalues of the jacobian of the system for which O(10)
+ ++ equates to mildly stiff wheras stiffness ratios of O(10^6) are not
+ ++ uncommon) and whether the system is likely to show any oscillations
+ ++ (identified by the closeness to the imaginary axis of the complex
+ ++ eigenvalues of the jacobian).
+ stiffnessAndStabilityOfODEIF:ODEA -> RSS
+ ++ stiffnessAndStabilityOfODEIF(ode) calculates the intensity values
+ ++ of stiffness of a system of first-order differential equations
+ ++ (by evaluating the maximum difference in the real parts of the
+ ++ negative eigenvalues of the jacobian of the system for which O(10)
+ ++ equates to mildly stiff wheras stiffness ratios of O(10^6) are not
+ ++ uncommon) and whether the system is likely to show any oscillations
+ ++ (identified by the closeness to the imaginary axis of the complex
+ ++ eigenvalues of the jacobian).
+ ++
+ ++ It returns two values in the range [0,1].
+ systemSizeIF:ODEA -> F
+ ++ systemSizeIF(ode) returns the intensity value of the size of
+ ++ the system of ODEs. 20 equations corresponds to the neutral
+ ++ value. It returns a value in the range [0,1].
+ expenseOfEvaluationIF:ODEA -> F
+ ++ expenseOfEvaluationIF(o) returns the intensity value of the
+ ++ cost of evaluating the input ODE. This is in terms of the number
+ ++ of ``operational units''. It returns a value in the range
+ ++ [0,1].\newline\indent{20}
+ ++ 400 ``operation units'' -> 0.75 \newline
+ ++ 200 ``operation units'' -> 0.5 \newline
+ ++ 83 ``operation units'' -> 0.25 \newline\indent{15}
+ ++ exponentiation = 4 units , function calls = 10 units.
+ accuracyIF:ODEA -> F
+ ++ accuracyIF(o) returns the intensity value of the accuracy
+ ++ requirements of the input ODE. A request of accuracy of 10^-6
+ ++ corresponds to the neutral intensity. It returns a value
+ ++ in the range [0,1].
+ intermediateResultsIF:ODEA -> F
+ ++ intermediateResultsIF(o) returns a value corresponding to the
+ ++ required number of intermediate results required and, therefore,
+ ++ an indication of how much this would affect the step-length of the
+ ++ calculation. It returns a value in the range [0,1].
+
+ I ==> add
+
+ import ExpertSystemToolsPackage
+
+ accuracyFactor:ODEA -> F
+ expenseOfEvaluation:ODEA -> F
+ eval1:(LEDF,LEEDF) -> LEDF
+ stiffnessAndStabilityOfODE:ODEA -> RSS
+ intermediateResultsFactor:ODEA -> F
+ leastStabilityAngle:(LDF,LDF) -> F
+
+ intermediateResultsFactor(ode:ODEA):F ==
+ resultsRequirement := #(ode.intvals)
+ (1.0-exp(-(resultsRequirement::F)/50.0)$F)
+
+ intermediateResultsIF(o:ODEA):F ==
+ ode := copy o
+ (t := showIntensityFunctions(ode)$ODEIntensityFunctionsTable) case ATT =>
+ s := coerce(t)@ATT
+ negative?(s.intermediateResults)$F =>
+ s.intermediateResults := intermediateResultsFactor(ode)
+ r:ROA := [ode,s]
+ insert!(r)$ODEIntensityFunctionsTable
+ s.intermediateResults
+ s.intermediateResults
+ a:ATT := [-1.0,-1.0,-1.0,-1.0,e:=intermediateResultsFactor(ode)]
+ r:ROA := [ode,a]
+ insert!(r)$ODEIntensityFunctionsTable
+ e
+
+ accuracyFactor(ode:ODEA):F ==
+ accuracyRequirements := convert(ode.abserr)@F
+ if zero?(accuracyRequirements) then
+ accuracyRequirements := convert(ode.relerr)@F
+ val := inv(accuracyRequirements)$F
+ n := log10(val)$F
+ (1.0-exp(-(n/(2.0))**2/(15.0))$F)
+
+ accuracyIF(o:ODEA):F ==
+ ode := copy o
+ (t := showIntensityFunctions(ode)$ODEIntensityFunctionsTable) case ATT =>
+ s := coerce(t)@ATT
+ negative?(s.accuracy)$F =>
+ s.accuracy := accuracyFactor(ode)
+ r:ROA := [ode,s]
+ insert!(r)$ODEIntensityFunctionsTable
+ s.accuracy
+ s.accuracy
+ a:ATT := [-1.0,-1.0,-1.0,e:=accuracyFactor(ode),-1.0]
+ r:ROA := [ode,a]
+ insert!(r)$ODEIntensityFunctionsTable
+ e
+
+ systemSizeIF(ode:ODEA):F ==
+ n := #(ode.fn)
+ (1.0-exp((-n::F/75.0))$F)
+
+ expenseOfEvaluation(o:ODEA):F ==
+ -- expense of evaluation of an ODE -- <0.3 inexpensive - 0.5 neutral - >0.7 very expensive
+ -- 400 `operation units' -> 0.75
+ -- 200 `operation units' -> 0.5
+ -- 83 `operation units' -> 0.25
+ -- ** = 4 units , function calls = 10 units.
+ ode := copy o.fn
+ expenseOfEvaluation(ode)
+
+ expenseOfEvaluationIF(o:ODEA):F ==
+ ode := copy o
+ (t := showIntensityFunctions(ode)$ODEIntensityFunctionsTable) case ATT =>
+ s := coerce(t)@ATT
+ negative?(s.expense)$F =>
+ s.expense := expenseOfEvaluation(ode)
+ r:ROA := [ode,s]
+ insert!(r)$ODEIntensityFunctionsTable
+ s.expense
+ s.expense
+ a:ATT := [-1.0,-1.0,e:=expenseOfEvaluation(ode),-1.0,-1.0]
+ r:ROA := [ode,a]
+ insert!(r)$ODEIntensityFunctionsTable
+ e
+
+ leastStabilityAngle(realPartsList:LDF,imagPartsList:LDF):F ==
+ complexList := [complex(u,v)$CDF for u in realPartsList for v in imagPartsList]
+ argumentList := [abs((abs(argument(u)$CDF)$DF)-(pi()$DF)/2)$DF for u in complexList]
+ sortedArgumentList := sort(argumentList)$LDF
+ list := [u for u in sortedArgumentList | not zero?(u) ]
+ empty?(list)$LDF => 0$F
+ convert(first(list)$LDF)@F
+
+ stiffnessAndStabilityFactor(me:MEDF):RSS ==
+
+ -- search first for real eigenvalues of the jacobian (symbolically)
+ -- if the system isn't too big
+ r:INT := ncols(me)$MEDF
+ b:Boolean := ((# me) < 150)
+ if b then
+ mc:MFI := map(edf2fi,me)$ExpertSystemToolsPackage2(EDF,FI)
+ e:LFI := realEigenvalues(mc,1/100)$NumericRealEigenPackage(FI)
+ b := ((# e) >= r-1)@Boolean
+ b =>
+ -- if all the eigenvalues are real, find negative ones
+ e := sort(neglist(e)$ExpertSystemToolsPackage1(FI))
+ -- if there are two or more, calculate stiffness ratio
+ ((n:=#e)>1)@Boolean => [coerce(e.1/e.n)@F,0$F]
+ -- otherwise stiffness not present
+ [0$F,0$F]
+
+ md:MDF := map(edf2df,me)$ExpertSystemToolsPackage2(EDF,DF)
+
+ -- otherwise calculate numerically the complex eigenvalues
+ -- using NAG routine f02aff.
+
+ res:Result := f02aff(r,r,md,-1)$NagEigenPackage
+ realParts:Union(Any,"failed") := search(rr::Symbol,res)$Result
+ realParts case "failed" => [0$F,0$F]
+ realPartsMatrix:MDF := retract(realParts)$AnyFunctions1(MDF) -- array === matrix
+ imagParts:Union(Any,"failed") := search(ri::Symbol,res)$Result
+ imagParts case "failed" => [0$F,0$F]
+ imagPartsMatrix:MDF := retract(imagParts)$AnyFunctions1(MDF) -- array === matrix
+ imagPartsList:LDF := members(imagPartsMatrix)$MDF
+ realPartsList:LDF := members(realPartsMatrix)$MDF
+ stabilityAngle := leastStabilityAngle(realPartsList,imagPartsList)
+ negRealPartsList := sort(neglist(realPartsList)$ExpertSystemToolsPackage1(DF))
+ empty?(negRealPartsList)$LDF => [0$F,stabilityAngle]
+ ((n:=#negRealPartsList)>1)@Boolean =>
+ out := convert(negRealPartsList.1/negRealPartsList.n)@F
+ [out,stabilityAngle] -- calculate stiffness ratio
+ [-convert(negRealPartsList.1)@F,stabilityAngle]
+
+ eval1(l:LEDF,e:LEEDF):LEDF ==
+ [eval(u,e)$EDF for u in l]
+
+ eval(mat:MEDF,symbols:LS,values:VEDF):MEDF ==
+ l := listOfLists(mat)
+ ledf := entries(values)$VEDF
+ e := [equation(u::EDF,v)$EEDF for u in symbols for v in ledf]
+ l := [eval1(w,e) for w in l]
+ matrix l
+
+ combineFeatureCompatibility(C1:F,C2:F):F ==
+
+ -- C1 C2
+ -- s(C1,C2) = -----------------------
+ -- C1 C2 + (1 - C1)(1 - C2)
+
+ C1*C2/((C1*C2)+(1$F-C1)*(1$F-C2))
+
+ combineFeatureCompatibility(C1:F,L:LF):F ==
+
+ empty?(L)$LF => C1
+ C2 := combineFeatureCompatibility(C1,first(L)$LF)
+ combineFeatureCompatibility(C2,rest(L)$LF)
+
+ jacobian(v:VEDF,w:LS):Matrix EDF ==
+ jacobian(v,w)$MultiVariableCalculusFunctions(S,EDF,VEDF,LS)
+
+ sparsityIF(m:Matrix EDF):F ==
+ l:LEDF :=parts m
+ z:LEDF := [u for u in l | zero?(u)$EDF]
+ ((#z)::F/(#l)::F)
+
+ sum(a:EDF,b:EDF):EDF == a+b
+
+ stiffnessAndStabilityOfODE(ode:ODEA):RSS ==
+ odefns := copy ode.fn
+ ls:LS := [subscript(Y,[coerce(n)])$Symbol for n in 1..# odefns]
+ yvals := copy ode.yinit
+ for i in 1..#yvals repeat
+ zero?(yvals.i) => yvals.i := 0.1::DF
+ yexpr := [coerce(v)@EDF for v in yvals]
+ yv:VEDF := vector(yexpr)
+ j1:MEDF := jacobian(odefns,ls)
+ ej1:MEDF := eval(j1,ls,yv)
+ ej1 := eval(ej1,variables(reduce(sum,members(ej1)$MEDF)),vector([(ode.xinit)::EDF]))
+ ssf := stiffnessAndStabilityFactor(ej1)
+ stability := 1.0-sqrt((ssf.stabilityFactor)*(2.0)/(pi()$F))
+ stiffness := (1.0)-exp(-(ssf.stiffnessFactor)/(500.0))
+ [stiffness,stability]
+
+ stiffnessAndStabilityOfODEIF(ode:ODEA):RSS ==
+ odefn := copy ode
+ (t := showIntensityFunctions(odefn)$ODEIntensityFunctionsTable) case ATT =>
+ s:ATT := coerce(t)@ATT
+ negative?(s.stiffness)$F =>
+ ssf:RSS := stiffnessAndStabilityOfODE(odefn)
+ s := [ssf.stiffnessFactor,ssf.stabilityFactor,s.expense,
+ s.accuracy,s.intermediateResults]
+ r:ROA := [odefn,s]
+ insert!(r)$ODEIntensityFunctionsTable
+ ssf
+ [s.stiffness,s.stability]
+ ssf:RSS := stiffnessAndStabilityOfODE(odefn)
+ s:ATT := [ssf.stiffnessFactor,ssf.stabilityFactor,-1.0,-1.0,-1.0]
+ r:ROA := [odefn,s]
+ insert!(r)$ODEIntensityFunctionsTable
+ ssf
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ODEIFTBL ODEIntensityFunctionsTable>>
+<<package D02AGNT d02AgentsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d02routine.spad.pamphlet b/src/algebra/d02routine.spad.pamphlet
new file mode 100644
index 00000000..106f29bc
--- /dev/null
+++ b/src/algebra/d02routine.spad.pamphlet
@@ -0,0 +1,424 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d02routine.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain D02BBFA d02bbfAnnaType}
+<<domain D02BBFA d02bbfAnnaType>>=
+)abbrev domain D02BBFA d02bbfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: January 1996
+++ Basic Operations:
+++ Description:
+++ \axiomType{d02bbfAnnaType} is a domain of
+++ \axiomType{OrdinaryDifferentialEquationsInitialValueProblemSolverCategory}
+++ for the NAG routine D02BBF, a ODE routine which uses an
+++ Runge-Kutta method to solve a system of differential
+++ equations. The function \axiomFun{measure} measures the
+++ usefulness of the routine D02BBF for the given problem. The
+++ function \axiomFun{ODESolve} performs the integration by using
+++ \axiomType{NagOrdinaryDifferentialEquationsPackage}.
+
+
+d02bbfAnnaType():OrdinaryDifferentialEquationsSolverCategory == Result add -- Runge Kutta
+
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ EF ==> Expression Float
+ VDF ==> Vector DoubleFloat
+ VMF ==> Vector MachineFloat
+ MF ==> MachineFloat
+ ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,_
+ g:EDF,abserr:DF,relerr:DF)
+ RSS ==> Record(stiffnessFactor:F,stabilityFactor:F)
+ INT ==> Integer
+ EF2 ==> ExpressionFunctions2
+
+ import d02AgentsPackage, NagOrdinaryDifferentialEquationsPackage
+ import AttributeButtons
+
+ accuracyCF(ode:ODEA):F ==
+ b := getButtonValue("d02bbf","accuracy")$AttributeButtons
+ accuracyIntensityValue := combineFeatureCompatibility(b,accuracyIF(ode))
+ accuracyIntensityValue > 0.999 => 0$F
+ 0.8*exp(-((10*accuracyIntensityValue)**3)$F/266)$F
+
+ stiffnessCF(stiffnessIntensityValue:F):F ==
+ b := getButtonValue("d02bbf","stiffness")$AttributeButtons
+ 0.5*exp(-(2*combineFeatureCompatibility(b,stiffnessIntensityValue))**2)$F
+
+ stabilityCF(stabilityIntensityValue:F):F ==
+ b := getButtonValue("d02bbf","stability")$AttributeButtons
+ 0.5 * cos(combineFeatureCompatibility(b,stabilityIntensityValue))$F
+
+ expenseOfEvaluationCF(ode:ODEA):F ==
+ b := getButtonValue("d02bbf","expense")$AttributeButtons
+ expenseOfEvaluationIntensityValue :=
+ combineFeatureCompatibility(b,expenseOfEvaluationIF(ode))
+ 0.35+0.2*exp(-(2.0*expenseOfEvaluationIntensityValue)**3)$F
+
+ measure(R:RoutinesTable,args:ODEA) ==
+ m := getMeasure(R,d02bbf :: Symbol)$RoutinesTable
+ ssf := stiffnessAndStabilityOfODEIF args
+ m := combineFeatureCompatibility(m,[accuracyCF(args),
+ stiffnessCF(ssf.stiffnessFactor),
+ expenseOfEvaluationCF(args),
+ stabilityCF(ssf.stabilityFactor)])
+ [m,"Runge-Kutta Merson method"]
+
+ ODESolve(ode:ODEA) ==
+ i:LDF := ode.intvals
+ M := inc(# i)$INT
+ irelab := 0$INT
+ if positive?(a := ode.abserr) then
+ inc(irelab)$INT
+ if positive?(r := ode.relerr) then
+ inc(irelab)$INT
+ if positive?(a+r) then
+ tol:DF := a + r
+ else
+ tol := float(1,-4,10)$DF
+ asp7:Union(fn:FileName,fp:Asp7(FCN)) :=
+ [retract(vedf2vef(ode.fn)$ExpertSystemToolsPackage)$Asp7(FCN)]
+ asp8:Union(fn:FileName,fp:Asp8(OUTPUT)) :=
+ [coerce(ldf2vmf(i)$ExpertSystemToolsPackage)$Asp8(OUTPUT)]
+ d02bbf(ode.xend,M,# ode.fn,irelab,ode.xinit,matrix([ode.yinit])$MDF,
+ tol,-1,asp7,asp8)
+
+@
+\section{domain D02BHFA d02bhfAnnaType}
+<<domain D02BHFA d02bhfAnnaType>>=
+)abbrev domain D02BHFA d02bhfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: January 1996
+++ Basic Operations:
+++ Description:
+++ \axiomType{d02bhfAnnaType} is a domain of
+++ \axiomType{OrdinaryDifferentialEquationsInitialValueProblemSolverCategory}
+++ for the NAG routine D02BHF, a ODE routine which uses an
+++ Runge-Kutta method to solve a system of differential
+++ equations. The function \axiomFun{measure} measures the
+++ usefulness of the routine D02BHF for the given problem. The
+++ function \axiomFun{ODESolve} performs the integration by using
+++ \axiomType{NagOrdinaryDifferentialEquationsPackage}.
+
+d02bhfAnnaType():OrdinaryDifferentialEquationsSolverCategory == Result add -- Runge Kutta
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ EF ==> Expression Float
+ VDF ==> Vector DoubleFloat
+ VMF ==> Vector MachineFloat
+ MF ==> MachineFloat
+ ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,_
+ g:EDF,abserr:DF,relerr:DF)
+ RSS ==> Record(stiffnessFactor:F,stabilityFactor:F)
+ INT ==> Integer
+ EF2 ==> ExpressionFunctions2
+
+ import d02AgentsPackage, NagOrdinaryDifferentialEquationsPackage
+ import AttributeButtons
+
+ accuracyCF(ode:ODEA):F ==
+ b := getButtonValue("d02bhf","accuracy")$AttributeButtons
+ accuracyIntensityValue := combineFeatureCompatibility(b,accuracyIF(ode))
+ accuracyIntensityValue > 0.999 => 0$F
+ 0.8*exp(-((10*accuracyIntensityValue)**3)$F/266)$F
+
+ stiffnessCF(stiffnessIntensityValue:F):F ==
+ b := getButtonValue("d02bhf","stiffness")$AttributeButtons
+ 0.5*exp(-(2*combineFeatureCompatibility(b,stiffnessIntensityValue))**2)$F
+
+ stabilityCF(stabilityIntensityValue:F):F ==
+ b := getButtonValue("d02bhf","stability")$AttributeButtons
+ 0.5 * cos(combineFeatureCompatibility(b,stabilityIntensityValue))$F
+
+ expenseOfEvaluationCF(ode:ODEA):F ==
+ b := getButtonValue("d02bhf","expense")$AttributeButtons
+ expenseOfEvaluationIntensityValue :=
+ combineFeatureCompatibility(b,expenseOfEvaluationIF(ode))
+ 0.35+0.2*exp(-(2.0*expenseOfEvaluationIntensityValue)**3)$F
+
+ measure(R:RoutinesTable,args:ODEA) ==
+ m := getMeasure(R,d02bhf :: Symbol)$RoutinesTable
+ ssf := stiffnessAndStabilityOfODEIF args
+ m := combineFeatureCompatibility(m,[accuracyCF(args),
+ stiffnessCF(ssf.stiffnessFactor),
+ expenseOfEvaluationCF(args),
+ stabilityCF(ssf.stabilityFactor)])
+ [m,"Runge-Kutta Merson method"]
+
+ ODESolve(ode:ODEA) ==
+ irelab := 0$INT
+ if positive?(a := ode.abserr) then
+ inc(irelab)$INT
+ if positive?(r := ode.relerr) then
+ inc(irelab)$INT
+ if positive?(a+r) then
+ tol := max(a,r)$DF
+ else
+ tol:DF := float(1,-4,10)$DF
+ asp7:Union(fn:FileName,fp:Asp7(FCN)) :=
+ [retract(e:VEF := vedf2vef(ode.fn)$ExpertSystemToolsPackage)$Asp7(FCN)]
+ asp9:Union(fn:FileName,fp:Asp9(G)) :=
+ [retract(edf2ef(ode.g)$ExpertSystemToolsPackage)$Asp9(G)]
+ d02bhf(ode.xend,# e,irelab,0$DF,ode.xinit,matrix([ode.yinit])$MDF,
+ tol,-1,asp9,asp7)
+
+@
+\section{domain D02CJFA d02cjfAnnaType}
+<<domain D02CJFA d02cjfAnnaType>>=
+)abbrev domain D02CJFA d02cjfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: January 1996
+++ Basic Operations:
+++ Description:
+++ \axiomType{d02cjfAnnaType} is a domain of
+++ \axiomType{OrdinaryDifferentialEquationsInitialValueProblemSolverCategory}
+++ for the NAG routine D02CJF, a ODE routine which uses an
+++ Adams-Moulton-Bashworth method to solve a system of differential
+++ equations. The function \axiomFun{measure} measures the
+++ usefulness of the routine D02CJF for the given problem. The
+++ function \axiomFun{ODESolve} performs the integration by using
+++ \axiomType{NagOrdinaryDifferentialEquationsPackage}.
+
+d02cjfAnnaType():OrdinaryDifferentialEquationsSolverCategory == Result add -- Adams
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ EF ==> Expression Float
+ VDF ==> Vector DoubleFloat
+ VMF ==> Vector MachineFloat
+ MF ==> MachineFloat
+ ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,_
+ g:EDF,abserr:DF,relerr:DF)
+ RSS ==> Record(stiffnessFactor:F,stabilityFactor:F)
+ INT ==> Integer
+ EF2 ==> ExpressionFunctions2
+
+ import d02AgentsPackage, NagOrdinaryDifferentialEquationsPackage
+
+ accuracyCF(ode:ODEA):F ==
+ b := getButtonValue("d02cjf","accuracy")$AttributeButtons
+ accuracyIntensityValue := combineFeatureCompatibility(b,accuracyIF(ode))
+ accuracyIntensityValue > 0.9999 => 0$F
+ 0.6*(cos(accuracyIntensityValue*(pi()$F)/2)$F)**0.755
+
+ stiffnessCF(ode:ODEA):F ==
+ b := getButtonValue("d02cjf","stiffness")$AttributeButtons
+ ssf := stiffnessAndStabilityOfODEIF ode
+ stiffnessIntensityValue :=
+ combineFeatureCompatibility(b,ssf.stiffnessFactor)
+ 0.5*exp(-(1.1*stiffnessIntensityValue)**3)$F
+
+ measure(R:RoutinesTable,args:ODEA) ==
+ m := getMeasure(R,d02cjf :: Symbol)$RoutinesTable
+ m := combineFeatureCompatibility(m,[accuracyCF(args), stiffnessCF(args)])
+ [m,"Adams method"]
+
+ ODESolve(ode:ODEA) ==
+ i:LDF := ode.intvals
+ if empty?(i) then
+ i := [ode.xend]
+ M := inc(# i)$INT
+ if positive?((a := ode.abserr)*(r := ode.relerr))$DF then
+ ire:String := "D"
+ else
+ if positive?(a) then
+ ire:String := "A"
+ else
+ ire:String := "R"
+ tol := max(a,r)$DF
+ asp7:Union(fn:FileName,fp:Asp7(FCN)) :=
+ [retract(e:VEF := vedf2vef(ode.fn)$ExpertSystemToolsPackage)$Asp7(FCN)]
+ asp8:Union(fn:FileName,fp:Asp8(OUTPUT)) :=
+ [coerce(ldf2vmf(i)$ExpertSystemToolsPackage)$Asp8(OUTPUT)]
+ asp9:Union(fn:FileName,fp:Asp9(G)) :=
+ [retract(edf2ef(ode.g)$ExpertSystemToolsPackage)$Asp9(G)]
+ d02cjf(ode.xend,M,# e,tol,ire,ode.xinit,matrix([ode.yinit])$MDF,
+ -1,asp9,asp7,asp8)
+
+@
+\section{domain D02EJFA d02ejfAnnaType}
+<<domain D02EJFA d02ejfAnnaType>>=
+)abbrev domain D02EJFA d02ejfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: January 1996
+++ Basic Operations:
+++ Description:
+++ \axiomType{d02ejfAnnaType} is a domain of
+++ \axiomType{OrdinaryDifferentialEquationsInitialValueProblemSolverCategory}
+++ for the NAG routine D02EJF, a ODE routine which uses a backward
+++ differentiation formulae method to handle a stiff system
+++ of differential equations. The function \axiomFun{measure} measures
+++ the usefulness of the routine D02EJF for the given problem. The
+++ function \axiomFun{ODESolve} performs the integration by using
+++ \axiomType{NagOrdinaryDifferentialEquationsPackage}.
+
+d02ejfAnnaType():OrdinaryDifferentialEquationsSolverCategory == Result add -- BDF "Stiff"
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ FI ==> Fraction Integer
+ EFI ==> Expression Fraction Integer
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ EF ==> Expression Float
+ VDF ==> Vector DoubleFloat
+ VMF ==> Vector MachineFloat
+ MF ==> MachineFloat
+ ODEA ==> Record(xinit:DF,xend:DF,fn:VEDF,yinit:LDF,intvals:LDF,_
+ g:EDF,abserr:DF,relerr:DF)
+ RSS ==> Record(stiffnessFactor:F,stabilityFactor:F)
+ INT ==> Integer
+ EF2 ==> ExpressionFunctions2
+
+ import d02AgentsPackage, NagOrdinaryDifferentialEquationsPackage
+
+ accuracyCF(ode:ODEA):F ==
+ b := getButtonValue("d02ejf","accuracy")$AttributeButtons
+ accuracyIntensityValue := combineFeatureCompatibility(b,accuracyIF(ode))
+ accuracyIntensityValue > 0.999 => 0$F
+ 0.5*exp(-((10*accuracyIntensityValue)**3)$F/250)$F
+
+ intermediateResultsCF(ode:ODEA):F ==
+ intermediateResultsIntensityValue := intermediateResultsIF(ode)
+ i := 0.5 * exp(-(intermediateResultsIntensityValue/1.649)**3)$F
+ a := accuracyCF(ode)
+ i+(0.5-i)*(0.5-a)
+
+ stabilityCF(ode:ODEA):F ==
+ b := getButtonValue("d02ejf","stability")$AttributeButtons
+ ssf := stiffnessAndStabilityOfODEIF ode
+ stabilityIntensityValue :=
+ combineFeatureCompatibility(b,ssf.stabilityFactor)
+ 0.68 - 0.5 * exp(-(stabilityIntensityValue)**3)$F
+
+ expenseOfEvaluationCF(ode:ODEA):F ==
+ b := getButtonValue("d02ejf","expense")$AttributeButtons
+ expenseOfEvaluationIntensityValue :=
+ combineFeatureCompatibility(b,expenseOfEvaluationIF(ode))
+ 0.5 * exp(-(1.7*expenseOfEvaluationIntensityValue)**3)$F
+
+ systemSizeCF(args:ODEA):F ==
+ (1$F - systemSizeIF(args))/2.0
+
+ measure(R:RoutinesTable,args:ODEA) ==
+ arg := copy args
+ m := getMeasure(R,d02ejf :: Symbol)$RoutinesTable
+ m := combineFeatureCompatibility(m,[intermediateResultsCF(arg),
+ accuracyCF(arg),
+ systemSizeCF(arg),
+ expenseOfEvaluationCF(arg),
+ stabilityCF(arg)])
+ [m,"BDF method for Stiff Systems"]
+
+ ODESolve(ode:ODEA) ==
+ i:LDF := ode.intvals
+ m := inc(# i)$INT
+ if positive?((a := ode.abserr)*(r := ode.relerr))$DF then
+ ire:String := "D"
+ else
+ if positive?(a) then
+ ire:String := "A"
+ else
+ ire:String := "R"
+ if positive?(a+r)$DF then
+ tol := max(a,r)$DF
+ else
+ tol := float(1,-4,10)$DF
+ asp7:Union(fn:FileName,fp:Asp7(FCN)) :=
+ [retract(e:VEF := vedf2vef(ode.fn)$ExpertSystemToolsPackage)$Asp7(FCN)]
+ asp31:Union(fn:FileName,fp:Asp31(PEDERV)) :=
+ [retract(e)$Asp31(PEDERV)]
+ asp8:Union(fn:FileName,fp:Asp8(OUTPUT)) :=
+ [coerce(ldf2vmf(i)$ExpertSystemToolsPackage)$Asp8(OUTPUT)]
+ asp9:Union(fn:FileName,fp:Asp9(G)) :=
+ [retract(edf2ef(ode.g)$ExpertSystemToolsPackage)$Asp9(G)]
+ n:INT := # ode.yinit
+ iw:INT := (12+n)*n+50
+ ans := d02ejf(ode.xend,m,n,ire,iw,ode.xinit,matrix([ode.yinit])$MDF,
+ tol,-1,asp9,asp7,asp31,asp8)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain D02BBFA d02bbfAnnaType>>
+<<domain D02BHFA d02bhfAnnaType>>
+<<domain D02CJFA d02cjfAnnaType>>
+<<domain D02EJFA d02ejfAnnaType>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d03.spad.pamphlet b/src/algebra/d03.spad.pamphlet
new file mode 100644
index 00000000..9f4e0cb8
--- /dev/null
+++ b/src/algebra/d03.spad.pamphlet
@@ -0,0 +1,195 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d03.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGD03 NagPartialDifferentialEquationsPackage}
+<<package NAGD03 NagPartialDifferentialEquationsPackage>>=
+)abbrev package NAGD03 NagPartialDifferentialEquationsPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:51 1994
+++Description:
+++This package uses the NAG Library to solve partial
+++differential equations.
+++See \downlink{Manual Page}{manpageXXd03}.
+NagPartialDifferentialEquationsPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ d03edf : (Integer,Integer,Integer,Integer,_
+ DoubleFloat,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ d03edf(ngx,ngy,lda,maxit,acc,iout,a,rhs,ub,ifail)
+ ++ solves seven-diagonal systems of linear equations which
+ ++ arise from the discretization of an elliptic partial differential
+ ++ equation on a rectangular region. This routine uses a multigrid
+ ++ technique.
+ ++ See \downlink{Manual Page}{manpageXXd03edf}.
+ d03eef : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ Integer,Integer,Integer,String,Integer,Union(fn:FileName,fp:Asp73(PDEF)),Union(fn:FileName,fp:Asp74(BNDY))) -> Result
+ ++ d03eef(xmin,xmax,ymin,ymax,ngx,ngy,lda,scheme,ifail,pdef,bndy)
+ ++ discretizes a second order elliptic partial differential
+ ++ equation (PDE) on a rectangular region.
+ ++ See \downlink{Manual Page}{manpageXXd03eef}.
+ d03faf : (DoubleFloat,DoubleFloat,Integer,Integer,_
+ Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,DoubleFloat,Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,DoubleFloat,Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Integer,Integer,ThreeDimensionalMatrix DoubleFloat,Integer) -> Result
+ ++ d03faf(xs,xf,l,lbdcnd,bdxs,bdxf,ys,yf,m,mbdcnd,bdys,bdyf,zs,zf,n,nbdcnd,bdzs,bdzf,lambda,ldimf,mdimf,lwrk,f,ifail)
+ ++ solves the Helmholtz equation in Cartesian co-ordinates in
+ ++ three dimensions using the standard seven-point finite difference
+ ++ approximation. This routine is designed to be particularly
+ ++ efficient on vector processors.
+ ++ See \downlink{Manual Page}{manpageXXd03faf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(String)
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(ThreeDimensionalMatrix DoubleFloat)
+ import FortranPackage
+ import Union(fn:FileName,fp:Asp73(PDEF))
+ import Union(fn:FileName,fp:Asp74(BNDY))
+
+
+
+
+ d03edf(ngxArg:Integer,ngyArg:Integer,ldaArg:Integer,_
+ maxitArg:Integer,accArg:DoubleFloat,ioutArg:Integer,_
+ aArg:Matrix DoubleFloat,rhsArg:Matrix DoubleFloat,ubArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "d03edf",_
+ ["ngx"::S,"ngy"::S,"lda"::S,"maxit"::S,"acc"::S_
+ ,"iout"::S,"numit"::S,"ifail"::S,"us"::S,"u"::S,"a"::S,"rhs"::S,"ub"::S_
+ ]$Lisp,_
+ ["us"::S,"u"::S,"numit"::S]$Lisp,_
+ [["double"::S,"acc"::S,["us"::S,"lda"::S]$Lisp_
+ ,["u"::S,"lda"::S]$Lisp,["a"::S,"lda"::S,7$Lisp]$Lisp,["rhs"::S,"lda"::S]$Lisp,["ub"::S,["*"::S,"ngx"::S,"ngy"::S]$Lisp]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"ngx"::S,"ngy"::S,"lda"::S,"maxit"::S_
+ ,"iout"::S,"numit"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["us"::S,"u"::S,"numit"::S,"a"::S,"rhs"::S,"ub"::S,"ifail"::S]$Lisp,_
+ [([ngxArg::Any,ngyArg::Any,ldaArg::Any,maxitArg::Any,accArg::Any,ioutArg::Any,ifailArg::Any,aArg::Any,rhsArg::Any,ubArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d03eef(xminArg:DoubleFloat,xmaxArg:DoubleFloat,yminArg:DoubleFloat,_
+ ymaxArg:DoubleFloat,ngxArg:Integer,ngyArg:Integer,_
+ ldaArg:Integer,schemeArg:String,ifailArg:Integer,_
+ pdefArg:Union(fn:FileName,fp:Asp73(PDEF)),bndyArg:Union(fn:FileName,fp:Asp74(BNDY))): Result ==
+ pushFortranOutputStack(pdefFilename := aspFilename "pdef")$FOP
+ if pdefArg case fn
+ then outputAsFortran(pdefArg.fn)
+ else outputAsFortran(pdefArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(bndyFilename := aspFilename "bndy")$FOP
+ if bndyArg case fn
+ then outputAsFortran(bndyArg.fn)
+ else outputAsFortran(bndyArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([pdefFilename,bndyFilename]$Lisp,_
+ "d03eef",_
+ ["xmin"::S,"xmax"::S,"ymin"::S,"ymax"::S,"ngx"::S_
+ ,"ngy"::S,"lda"::S,"scheme"::S,"ifail"::S,"pdef"::S_
+ ,"bndy"::S,"a"::S,"rhs"::S]$Lisp,_
+ ["a"::S,"rhs"::S,"pdef"::S,"bndy"::S]$Lisp,_
+ [["double"::S,"xmin"::S,"xmax"::S,"ymin"::S_
+ ,"ymax"::S,["a"::S,"lda"::S,7$Lisp]$Lisp,["rhs"::S,"lda"::S]$Lisp,"pdef"::S,"bndy"::S]$Lisp_
+ ,["integer"::S,"ngx"::S,"ngy"::S,"lda"::S,"ifail"::S_
+ ]$Lisp_
+ ,["character"::S,"scheme"::S]$Lisp_
+ ]$Lisp,_
+ ["a"::S,"rhs"::S,"ifail"::S]$Lisp,_
+ [([xminArg::Any,xmaxArg::Any,yminArg::Any,ymaxArg::Any,ngxArg::Any,ngyArg::Any,ldaArg::Any,schemeArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ d03faf(xsArg:DoubleFloat,xfArg:DoubleFloat,lArg:Integer,_
+ lbdcndArg:Integer,bdxsArg:Matrix DoubleFloat,bdxfArg:Matrix DoubleFloat,_
+ ysArg:DoubleFloat,yfArg:DoubleFloat,mArg:Integer,_
+ mbdcndArg:Integer,bdysArg:Matrix DoubleFloat,bdyfArg:Matrix DoubleFloat,_
+ zsArg:DoubleFloat,zfArg:DoubleFloat,nArg:Integer,_
+ nbdcndArg:Integer,bdzsArg:Matrix DoubleFloat,bdzfArg:Matrix DoubleFloat,_
+ lambdaArg:DoubleFloat,ldimfArg:Integer,mdimfArg:Integer,_
+ lwrkArg:Integer,fArg:ThreeDimensionalMatrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "d03faf",_
+ ["xs"::S,"xf"::S,"l"::S,"lbdcnd"::S,"ys"::S_
+ ,"yf"::S,"m"::S,"mbdcnd"::S,"zs"::S,"zf"::S_
+ ,"n"::S,"nbdcnd"::S,"lambda"::S,"ldimf"::S,"mdimf"::S_
+ ,"lwrk"::S,"pertrb"::S,"ifail"::S,"bdxs"::S,"bdxf"::S,"bdys"::S,"bdyf"::S,"bdzs"::S_
+ ,"bdzf"::S,"f"::S,"w"::S]$Lisp,_
+ ["pertrb"::S,"w"::S]$Lisp,_
+ [["double"::S,"xs"::S,"xf"::S,["bdxs"::S,"mdimf"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp_
+ ,["bdxf"::S,"mdimf"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp,"ys"::S,"yf"::S,["bdys"::S,"ldimf"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp_
+ ,["bdyf"::S,"ldimf"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp,"zs"::S_
+ ,"zf"::S,["bdzs"::S,"ldimf"::S,["+"::S,"m"::S,1$Lisp]$Lisp]$Lisp,["bdzf"::S,"ldimf"::S,["+"::S,"m"::S,1$Lisp]$Lisp]$Lisp_
+ ,"lambda"::S,"pertrb"::S,["f"::S,"ldimf"::S,"mdimf"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp,["w"::S,"lwrk"::S]$Lisp]$Lisp_
+ ,["integer"::S,"l"::S,"lbdcnd"::S,"m"::S,"mbdcnd"::S_
+ ,"n"::S,"nbdcnd"::S,"ldimf"::S,"mdimf"::S,"lwrk"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["pertrb"::S,"f"::S,"ifail"::S]$Lisp,_
+ [([xsArg::Any,xfArg::Any,lArg::Any,lbdcndArg::Any,ysArg::Any,yfArg::Any,mArg::Any,mbdcndArg::Any,zsArg::Any,zfArg::Any,nArg::Any,nbdcndArg::Any,lambdaArg::Any,ldimfArg::Any,mdimfArg::Any,lwrkArg::Any,ifailArg::Any,bdxsArg::Any,bdxfArg::Any,bdysArg::Any,bdyfArg::Any,bdzsArg::Any,bdzfArg::Any,fArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGD03 NagPartialDifferentialEquationsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d03Package.spad.pamphlet b/src/algebra/d03Package.spad.pamphlet
new file mode 100644
index 00000000..7a0a146f
--- /dev/null
+++ b/src/algebra/d03Package.spad.pamphlet
@@ -0,0 +1,307 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d03Package.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PDEPACK AnnaPartialDifferentialEquationPackage}
+<<package PDEPACK AnnaPartialDifferentialEquationPackage>>=
+)abbrev package PDEPACK AnnaPartialDifferentialEquationPackage
+++ Author: Brian Dupee
+++ Date Created: June 1996
+++ Date Last Updated: December 1997
+++ Basic Operations:
+++ Description: AnnaPartialDifferentialEquationPackage is an uncompleted
+++ package for the interface to NAG PDE routines. It has been realised that
+++ a new approach to solving PDEs will need to be created.
+++
+LEDF ==> List Expression DoubleFloat
+EDF ==> Expression DoubleFloat
+LDF ==> List DoubleFloat
+MDF ==> Matrix DoubleFloat
+DF ==> DoubleFloat
+LEF ==> List Expression Float
+EF ==> Expression Float
+MEF ==> Matrix Expression Float
+LF ==> List Float
+F ==> Float
+LS ==> List Symbol
+ST ==> String
+LST ==> List String
+INT ==> Integer
+NNI ==> NonNegativeInteger
+RT ==> RoutinesTable
+PDEC ==> Record(start:DF, finish:DF, grid:NNI, boundaryType:INT,
+ dStart:MDF, dFinish:MDF)
+PDEB ==> Record(pde:LEDF, constraints:List PDEC,
+ f:List LEDF, st:ST, tol:DF)
+IFL ==> List(Record(ifail:INT,instruction:ST))
+Entry ==> Record(chapter:ST, type:ST, domainName: ST,
+ defaultMin:F, measure:F, failList:IFL, explList:LST)
+Measure ==> Record(measure:F,name:ST, explanations:LST)
+
+AnnaPartialDifferentialEquationPackage(): with
+ solve:(NumericalPDEProblem) -> Result
+ ++ solve(PDEProblem) is a top level ANNA function to solve numerically a system
+ ++ of partial differential equations.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of PDE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ ++
+ ++ ** At the moment, only Second Order Elliptic Partial Differential
+ ++ Equations are solved **
+ solve:(NumericalPDEProblem,RT) -> Result
+ ++ solve(PDEProblem,routines) is a top level ANNA function to solve numerically a system
+ ++ of partial differential equations.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of PDE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ ++
+ ++ ** At the moment, only Second Order Elliptic Partial Differential
+ ++ Equations are solved **
+ solve:(F,F,F,F,NNI,NNI,LEF,List LEF,ST,DF) -> Result
+ ++ solve(xmin,ymin,xmax,ymax,ngx,ngy,pde,bounds,st,tol) is a top level
+ ++ ANNA function to solve numerically a system of partial differential
+ ++ equations. This is defined as a list of coefficients (\axiom{pde}),
+ ++ a grid (\axiom{xmin}, \axiom{ymin}, \axiom{xmax}, \axiom{ymax},
+ ++ \axiom{ngx}, \axiom{ngy}), the boundary values (\axiom{bounds}) and a
+ ++ tolerance requirement (\axiom{tol}). There is also a parameter
+ ++ (\axiom{st}) which should contain the value "elliptic" if the PDE is
+ ++ known to be elliptic, or "unknown" if it is uncertain. This causes the
+ ++ routine to check whether the PDE is elliptic.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of PDE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ ++
+ ++ ** At the moment, only Second Order Elliptic Partial Differential
+ ++ Equations are solved **
+ solve:(F,F,F,F,NNI,NNI,LEF,List LEF,ST) -> Result
+ ++ solve(xmin,ymin,xmax,ymax,ngx,ngy,pde,bounds,st) is a top level
+ ++ ANNA function to solve numerically a system of partial differential
+ ++ equations. This is defined as a list of coefficients (\axiom{pde}),
+ ++ a grid (\axiom{xmin}, \axiom{ymin}, \axiom{xmax}, \axiom{ymax},
+ ++ \axiom{ngx}, \axiom{ngy}) and the boundary values (\axiom{bounds}).
+ ++ A default value for tolerance is used. There is also a parameter
+ ++ (\axiom{st}) which should contain the value "elliptic" if the PDE is
+ ++ known to be elliptic, or "unknown" if it is uncertain. This causes the
+ ++ routine to check whether the PDE is elliptic.
+ ++
+ ++ The method used to perform the numerical
+ ++ process will be one of the routines contained in the NAG numerical
+ ++ Library. The function predicts the likely most effective routine
+ ++ by checking various attributes of the system of PDE's and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ ++
+ ++ It then calls the resulting `best' routine.
+ ++
+ ++ ** At the moment, only Second Order Elliptic Partial Differential
+ ++ Equations are solved **
+ measure:(NumericalPDEProblem) -> Measure
+ ++ measure(prob) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical PDE
+ ++ problem defined by \axiom{prob}.
+ ++
+ ++ It calls each \axiom{domain} of \axiom{category}
+ ++ \axiomType{PartialDifferentialEquationsSolverCategory} in turn to
+ ++ calculate all measures and returns the best i.e. the name of
+ ++ the most appropriate domain and any other relevant information.
+ ++ It predicts the likely most effective NAG numerical
+ ++ Library routine to solve the input set of PDEs
+ ++ by checking various attributes of the system of PDEs and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+ measure:(NumericalPDEProblem,RT) -> Measure
+ ++ measure(prob,R) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical PDE
+ ++ problem defined by \axiom{prob}.
+ ++
+ ++ It calls each \axiom{domain} listed in \axiom{R} of \axiom{category}
+ ++ \axiomType{PartialDifferentialEquationsSolverCategory} in turn to
+ ++ calculate all measures and returns the best i.e. the name of
+ ++ the most appropriate domain and any other relevant information.
+ ++ It predicts the likely most effective NAG numerical
+ ++ Library routine to solve the input set of PDEs
+ ++ by checking various attributes of the system of PDEs and calculating
+ ++ a measure of compatibility of each routine to these attributes.
+
+
+ == add
+
+ import PDEB, d03AgentsPackage, ExpertSystemToolsPackage, NumericalPDEProblem
+
+ zeroMeasure:Measure -> Result
+ measureSpecific:(ST,RT,PDEB) -> Record(measure:F,explanations:ST)
+ solveSpecific:(PDEB,ST) -> Result
+ changeName:(Result,ST) -> Result
+ recoverAfterFail:(PDEB,RT,Measure,Integer,Result) -> Record(a:Result,b:Measure)
+
+ zeroMeasure(m:Measure):Result ==
+ a := coerce(0$F)$AnyFunctions1(F)
+ text := coerce("No available routine appears appropriate")$AnyFunctions1(ST)
+ r := construct([[result@Symbol,a],[method@Symbol,text]])$Result
+ concat(measure2Result m,r)$ExpertSystemToolsPackage
+
+ measureSpecific(name:ST,R:RT,p:PDEB):Record(measure:F,explanations:ST) ==
+ name = "d03eefAnnaType" => measure(R,p)$d03eefAnnaType
+ --name = "d03fafAnnaType" => measure(R,p)$d03fafAnnaType
+ error("measureSpecific","invalid type name: " name)$ErrorFunctions
+
+ measure(P:NumericalPDEProblem,R:RT):Measure ==
+ p:PDEB := retract(P)$NumericalPDEProblem
+ sofar := 0$F
+ best := "none" :: ST
+ routs := copy R
+ routs := selectPDERoutines(routs)$RT
+ empty?(routs)$RT =>
+ error("measure", "no routines found")$ErrorFunctions
+ rout := inspect(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ meth := empty()$LST
+ for i in 1..# routs repeat
+ rout := extract!(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ n := e.domainName
+ if e.defaultMin > sofar then
+ m := measureSpecific(n,R,p)
+ if m.measure > sofar then
+ sofar := m.measure
+ best := n
+ str:LST := [string(rout.key)$Symbol "measure: "
+ outputMeasure(m.measure)$ExpertSystemToolsPackage " - "
+ m.explanations]
+ else
+ str := [string(rout.key)$Symbol " is no better than other routines"]
+ meth := append(meth,str)$LST
+ [sofar,best,meth]
+
+ measure(P:NumericalPDEProblem):Measure == measure(P,routines()$RT)
+
+ solveSpecific(p:PDEB,n:ST):Result ==
+ n = "d03eefAnnaType" => PDESolve(p)$d03eefAnnaType
+ --n = "d03fafAnnaType" => PDESolve(p)$d03fafAnnaType
+ error("solveSpecific","invalid type name: " n)$ErrorFunctions
+
+ changeName(ans:Result,name:ST):Result ==
+ sy:Symbol := coerce(name "Answer")$Symbol
+ anyAns:Any := coerce(ans)$AnyFunctions1(Result)
+ construct([[sy,anyAns]])$Result
+
+ recoverAfterFail(p:PDEB,routs:RT,m:Measure,iint:Integer,r:Result):
+ Record(a:Result,b:Measure) ==
+ while positive?(iint) repeat
+ routineName := m.name
+ s := recoverAfterFail(routs,routineName(1..6),iint)$RT
+ s case "failed" => iint := 0
+ (s = "no action")@Boolean => iint := 0
+ fl := coerce(s)$AnyFunctions1(ST)
+ flrec:Record(key:Symbol,entry:Any):=[failure@Symbol,fl]
+ m2 := measure(p::NumericalPDEProblem,routs)
+ zero?(m2.measure) => iint := 0
+ r2:Result := solveSpecific(p,m2.name)
+ m := m2
+ insert!(flrec,r2)$Result
+ r := concat(r2,changeName(r,routineName))$ExpertSystemToolsPackage
+ iany := search(ifail@Symbol,r2)$Result
+ iany case "failed" => iint := 0
+ iint := retract(iany)$AnyFunctions1(Integer)
+ [r,m]
+
+ solve(P:NumericalPDEProblem,t:RT):Result ==
+ routs := copy(t)$RT
+ m := measure(P,routs)
+ p:PDEB := retract(P)$NumericalPDEProblem
+ zero?(m.measure) => zeroMeasure m
+ r := solveSpecific(p,n := m.name)
+ iany := search(ifail@Symbol,r)$Result
+ iint := 0$Integer
+ if (iany case Any) then
+ iint := retract(iany)$AnyFunctions1(Integer)
+ if positive?(iint) then
+ tu:Record(a:Result,b:Measure) := recoverAfterFail(p,routs,m,iint,r)
+ r := tu.a
+ m := tu.b
+ expl := getExplanations(routs,n(1..6))$RoutinesTable
+ expla := coerce(expl)$AnyFunctions1(LST)
+ explaa:Record(key:Symbol,entry:Any) := ["explanations"::Symbol,expla]
+ r := concat(construct([explaa]),r)
+ concat(measure2Result m,r)$ExpertSystemToolsPackage
+
+ solve(P:NumericalPDEProblem):Result == solve(P,routines()$RT)
+
+ solve(xmi:F,xma:F,ymi:F,yma:F,nx:NNI,ny:NNI,pe:LEF,bo:List
+ LEF,s:ST,to:DF):Result ==
+ cx:PDEC := [f2df xmi, f2df xma, nx, 1, empty()$MDF, empty()$MDF]
+ cy:PDEC := [f2df ymi, f2df yma, ny, 1, empty()$MDF, empty()$MDF]
+ p:PDEB := [[ef2edf e for e in pe],[cx,cy],
+ [[ef2edf u for u in w] for w in bo],s,to]
+ solve(p::NumericalPDEProblem,routines()$RT)
+
+ solve(xmi:F,xma:F,ymi:F,yma:F,nx:NNI,ny:NNI,pe:LEF,bo:List
+ LEF,s:ST):Result ==
+ solve(xmi,xma,ymi,yma,nx,ny,pe,bo,s,0.0001::DF)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PDEPACK AnnaPartialDifferentialEquationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d03agents.spad.pamphlet b/src/algebra/d03agents.spad.pamphlet
new file mode 100644
index 00000000..3c7b57c4
--- /dev/null
+++ b/src/algebra/d03agents.spad.pamphlet
@@ -0,0 +1,147 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d03agents.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package D03AGNT d03AgentsPackage}
+<<package D03AGNT d03AgentsPackage>>=
+)abbrev package D03AGNT d03AgentsPackage
+++ Author: Brian Dupee
+++ Date Created: May 1994
+++ Date Last Updated: December 1997
+++ Basic Operations:
+++ Description:
+++ \axiom{d03AgentsPackage} contains a set of computational agents
+++ for use with Partial Differential Equation solvers.
+LEDF ==> List Expression DoubleFloat
+EDF ==> Expression DoubleFloat
+MDF ==> Matrix DoubleFloat
+DF ==> DoubleFloat
+F ==> Float
+INT ==> Integer
+NNI ==> NonNegativeInteger
+EEDF ==> Equation Expression DoubleFloat
+LEEDF ==> List Equation Expression DoubleFloat
+LDF ==> List DoubleFloat
+LOCDF ==> List OrderedCompletion DoubleFloat
+OCDF ==> OrderedCompletion DoubleFloat
+LS ==> List Symbol
+PDEC ==> Record(start:DF, finish:DF, grid:NNI, boundaryType:INT,
+ dStart:MDF, dFinish:MDF)
+PDEB ==> Record(pde:LEDF, constraints:List PDEC,
+ f:List LEDF, st:String, tol:DF)
+NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+
+d03AgentsPackage(): E == I where
+ E ==> with
+ varList:(Symbol,NonNegativeInteger) -> LS
+ ++ varList(s,n) \undocumented{}
+ subscriptedVariables:EDF -> EDF
+ ++ subscriptedVariables(e) \undocumented{}
+ central?:(DF,DF,LEDF) -> Boolean
+ ++ central?(f,g,l) \undocumented{}
+ elliptic?:PDEB -> Boolean
+ ++ elliptic?(r) \undocumented{}
+
+ I ==> add
+
+ import ExpertSystemToolsPackage
+
+ sum(a:EDF,b:EDF):EDF == a+b
+
+ varList(s:Symbol,n:NonNegativeInteger):LS ==
+ [subscript(s,[t::OutputForm]) for t in expand([1..n])$Segment(Integer)]
+
+ subscriptedVariables(e:EDF):EDF ==
+ oldVars:List Symbol := variables(e)
+ o := [a :: EDF for a in oldVars]
+ newVars := varList(X::Symbol,# oldVars)
+ n := [b :: EDF for b in newVars]
+ subst(e,[a=b for a in o for b in n])
+
+ central?(x:DF,y:DF,p:LEDF):Boolean ==
+ ls := variables(reduce(sum,p))
+ le := [equation(u::EDF,v)$EEDF for u in ls for v in [x::EDF,y::EDF]]
+ l := [eval(u,le)$EDF for u in p]
+ max(l.4,l.5) < 20 * max(l.1,max(l.2,l.3))
+
+ elliptic?(args:PDEB):Boolean ==
+ (args.st)="elliptic" => true
+ p := args.pde
+ xcon:PDEC := first(args.constraints)
+ ycon:PDEC := second(args.constraints)
+ xs := xcon.start
+ ys := ycon.start
+ xf := xcon.finish
+ yf := ycon.finish
+ xstart:DF := ((xf-xs)/2)$DF
+ ystart:DF := ((yf-ys)/2)$DF
+ optStart:LDF := [xstart,ystart]
+ lower:LOCDF := [xs::OCDF,ys::OCDF]
+ upper:LOCDF := [xf::OCDF,yf::OCDF]
+ v := variables(e := 4*first(p)*third(p)-(second(p))**2)
+ eq := subscriptedVariables(e)
+ noa:NOA :=
+-- one?(# v) =>
+ (# v) = 1 =>
+ ((first v) = X@Symbol) =>
+ [eq,[xstart],[xs::OCDF],empty()$LEDF,[xf::OCDF]]
+ [eq,[ystart],[ys::OCDF],empty()$LEDF,[yf::OCDF]]
+ [eq,optStart,lower,empty()$LEDF,upper]
+ ell := optimize(noa::NumericalOptimizationProblem)$AnnaNumericalOptimizationPackage
+ o:Union(Any,"failed") := search(objf::Symbol,ell)$Result
+ o case "failed" => false
+ ob := o :: Any
+ obj:DF := retract(ob)$AnyFunctions1(DF)
+ positive?(obj)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package D03AGNT d03AgentsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/d03routine.spad.pamphlet b/src/algebra/d03routine.spad.pamphlet
new file mode 100644
index 00000000..cd7a10c8
--- /dev/null
+++ b/src/algebra/d03routine.spad.pamphlet
@@ -0,0 +1,164 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra d03routine.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain D03EEFA d03eefAnnaType}
+<<domain D03EEFA d03eefAnnaType>>=
+)abbrev domain D03EEFA d03eefAnnaType
+++ Author: Brian Dupee
+++ Date Created: June 1996
+++ Date Last Updated: June 1996
+++ Basic Operations:
+++ Description:
+++ \axiomType{d03eefAnnaType} is a domain of
+++ \axiomType{PartialDifferentialEquationsSolverCategory}
+++ for the NAG routines D03EEF/D03EDF.
+d03eefAnnaType():PartialDifferentialEquationsSolverCategory == Result add -- 2D Elliptic PDE
+ LEDF ==> List Expression DoubleFloat
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ FI ==> Fraction Integer
+ VEF ==> Vector Expression Float
+ EF ==> Expression Float
+ MEF ==> Matrix Expression Float
+ NNI ==> NonNegativeInteger
+ INT ==> Integer
+ PDEC ==> Record(start:DF, finish:DF, grid:NNI, boundaryType:INT,
+ dStart:MDF, dFinish:MDF)
+ PDEB ==> Record(pde:LEDF, constraints:List PDEC,
+ f:List LEDF, st:String, tol:DF)
+
+ import d03AgentsPackage, NagPartialDifferentialEquationsPackage
+ import ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:PDEB) ==
+ (# (args.constraints) > 2)@Boolean =>
+ [0$F,"d03eef/d03edf is unsuitable for PDEs of order more than 2"]
+ elliptic?(args) =>
+ m := getMeasure(R,d03eef :: Symbol)$RoutinesTable
+ [m,"d03eef/d03edf is suitable"]
+ [0$F,"d03eef/d03edf is unsuitable for hyperbolic or parabolic PDEs"]
+
+ PDESolve(args:PDEB) ==
+ xcon := first(args.constraints)
+ ycon := second(args.constraints)
+ nx := xcon.grid
+ ny := ycon.grid
+ p := args.pde
+ x1 := xcon.start
+ x2 := xcon.finish
+ y1 := ycon.start
+ y2 := ycon.finish
+ lda := ((4*(nx+1)*(ny+1)+2) quo 3)$INT
+ scheme:String :=
+ central?((x2-x1)/2,(y2-y1)/2,args.pde) => "C"
+ "U"
+ asp73:Union(fn:FileName,fp:Asp73(PDEF)) :=
+ [retract(vector([edf2ef u for u in p])$VEF)$Asp73(PDEF)]
+ asp74:Union(fn:FileName,fp:Asp74(BNDY)) :=
+ [retract(matrix([[edf2ef v for v in w] for w in args.f])$MEF)$Asp74(BNDY)]
+ fde := d03eef(x1,x2,y1,y2,nx,ny,lda,scheme,-1,asp73,asp74)
+ ub := new(1,nx*ny,0$DF)$MDF
+ A := search(a::Symbol,fde)$Result
+ A case "failed" => empty()$Result
+ AA := A::Any
+ fdea := retract(AA)$AnyFunctions1(MDF)
+ r := search(rhs::Symbol,fde)$Result
+ r case "failed" => empty()$Result
+ rh := r::Any
+ fderhs := retract(rh)$AnyFunctions1(MDF)
+ d03edf(nx,ny,lda,15,args.tol,0,fdea,fderhs,ub,-1)
+
+@
+\section{domain D03FAFA d03fafAnnaType}
+<<domain D03FAFA d03fafAnnaType>>=
+)abbrev domain D03FAFA d03fafAnnaType
+++ Author: Brian Dupee
+++ Date Created: July 1996
+++ Date Last Updated: July 1996
+++ Basic Operations:
+++ Description:
+++ \axiomType{d03fafAnnaType} is a domain of
+++ \axiomType{PartialDifferentialEquationsSolverCategory}
+++ for the NAG routine D03FAF.
+d03fafAnnaType():PartialDifferentialEquationsSolverCategory == Result add -- 3D Helmholtz PDE
+ LEDF ==> List Expression DoubleFloat
+ EDF ==> Expression DoubleFloat
+ LDF ==> List DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ FI ==> Fraction Integer
+ VEF ==> Vector Expression Float
+ EF ==> Expression Float
+ MEF ==> Matrix Expression Float
+ NNI ==> NonNegativeInteger
+ INT ==> Integer
+ PDEC ==> Record(start:DF, finish:DF, grid:NNI, boundaryType:INT,
+ dStart:MDF, dFinish:MDF)
+ PDEB ==> Record(pde:LEDF, constraints:List PDEC,
+ f:List LEDF, st:String, tol:DF)
+
+ import d03AgentsPackage, NagPartialDifferentialEquationsPackage
+ import ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:PDEB) ==
+ (# (args.constraints) < 3)@Boolean =>
+ [0$F,"d03faf is unsuitable for PDEs of order other than 3"]
+ [0$F,"d03faf isn't finished"]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain D03EEFA d03eefAnnaType>>
+<<domain D03FAFA d03fafAnnaType>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ddfact.spad.pamphlet b/src/algebra/ddfact.spad.pamphlet
new file mode 100644
index 00000000..3871a8b8
--- /dev/null
+++ b/src/algebra/ddfact.spad.pamphlet
@@ -0,0 +1,309 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ddfact.spad}
+\author{Patrizia Gianni, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DDFACT DistinctDegreeFactorize}
+<<package DDFACT DistinctDegreeFactorize>>=
+)abbrev package DDFACT DistinctDegreeFactorize
+++ Author: P. Gianni, B.Trager
+++ Date Created: 1983
+++ Date Last Updated: 22 November 1993
+++ Basic Functions: factor, irreducible?
+++ Related Constructors: PrimeField, FiniteField
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Package for the factorization of a univariate polynomial with
+++ coefficients in a finite field. The algorithm used is the
+++ "distinct degree" algorithm of Cantor-Zassenhaus, modified
+++ to use trace instead of the norm and a table for computing
+++ Frobenius as suggested by Naudin and Quitte .
+
+DistinctDegreeFactorize(F,FP): C == T
+ where
+ F : FiniteFieldCategory
+ FP : UnivariatePolynomialCategory(F)
+
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FFE ==> Record(flg:fUnion, fctr:FP, xpnt:Integer)
+ NNI == NonNegativeInteger
+ Z == Integer
+ fact == Record(deg : NNI,prod : FP)
+ ParFact == Record(irr:FP,pow:Z)
+ FinalFact == Record(cont:F,factors:List(ParFact))
+
+ C == with
+ factor : FP -> Factored FP
+ ++ factor(p) produces the complete factorization of the polynomial p.
+ factorSquareFree : FP -> Factored FP
+ ++ factorSquareFree(p) produces the complete factorization of the
+ ++ square free polynomial p.
+ distdfact : (FP,Boolean) -> FinalFact
+ ++ distdfact(p,sqfrflag) produces the complete factorization
+ ++ of the polynomial p returning an internal data structure.
+ ++ If argument sqfrflag is true, the polynomial is assumed square free.
+ separateDegrees : FP -> List fact
+ ++ separateDegrees(p) splits the square free polynomial p into
+ ++ factors each of which is a product of irreducibles of the same degree.
+ separateFactors : List fact -> List FP
+ ++ separateFactors(lfact) takes the list produced by
+ ++ \spadfunFrom{separateDegrees}{DistinctDegreeFactorization}
+ ++ and produces the complete list of factors.
+ exptMod : (FP,NNI,FP) -> FP
+ ++ exptMod(u,k,v) raises the polynomial u to the kth power
+ ++ modulo the polynomial v.
+ trace2PowMod : (FP,NNI,FP) -> FP
+ ++ trace2PowMod(u,k,v) produces the sum of \spad{u**(2**i)} for i running
+ ++ from 1 to k all computed modulo the polynomial v.
+ tracePowMod : (FP,NNI,FP) -> FP
+ ++ tracePowMod(u,k,v) produces the sum of \spad{u**(q**i)}
+ ++ for i running and q= size F
+ irreducible? : FP -> Boolean
+ ++ irreducible?(p) tests whether the polynomial p is irreducible.
+
+
+ T == add
+ --declarations
+ D:=ModMonic(F,FP)
+ import UnivariatePolynomialSquareFree(F,FP)
+
+ --local functions
+ notSqFr : (FP,FP -> List(FP)) -> List(ParFact)
+ ddffact : FP -> List(FP)
+ ddffact1 : (FP,Boolean) -> List fact
+ ranpol : NNI -> FP
+
+ charF : Boolean := characteristic()$F = 2
+
+ --construct a random polynomial of random degree < d
+ ranpol(d:NNI):FP ==
+ k1: NNI := 0
+ while k1 = 0 repeat k1 := random d
+ -- characteristic F = 2
+ charF =>
+ u:=0$FP
+ for j in 1..k1 repeat u:=u+monomial(random()$F,j)
+ u
+ u := monomial(1,k1)
+ for j in 0..k1-1 repeat u:=u+monomial(random()$F,j)
+ u
+
+ notSqFr(m:FP,appl: FP->List(FP)):List(ParFact) ==
+ factlist : List(ParFact) :=empty()
+ llf : List FFE
+ fln :List(FP) := empty()
+ if (lcm:=leadingCoefficient m)^=1 then m:=(inv lcm)*m
+ llf:= factorList(squareFree(m))
+ for lf in llf repeat
+ d1:= lf.xpnt
+ pol := lf.fctr
+ if (lcp:=leadingCoefficient pol)^=1 then pol := (inv lcp)*pol
+ degree pol=1 => factlist:=cons([pol,d1]$ParFact,factlist)
+ fln := appl(pol)
+ factlist :=append([[pf,d1]$ParFact for pf in fln],factlist)
+ factlist
+
+ -- compute u**k mod v (requires call to setPoly of multiple of v)
+ -- characteristic not equal 2
+ exptMod(u:FP,k:NNI,v:FP):FP == (reduce(u)$D**k):FP rem v
+
+ -- compute u**k mod v (requires call to setPoly of multiple of v)
+ -- characteristic equal 2
+ trace2PowMod(u:FP,k:NNI,v:FP):FP ==
+ uu:=u
+ for i in 1..k repeat uu:=(u+uu*uu) rem v
+ uu
+
+ -- compute u+u**q+..+u**(q**k) mod v
+ -- (requires call to setPoly of multiple of v) where q=size< F
+ tracePowMod(u:FP,k:NNI,v:FP):FP ==
+ u1 :D :=reduce(u)$D
+ uu : D := u1
+ for i in 1..k repeat uu:=(u1+frobenius uu)
+ (lift uu) rem v
+
+ -- compute u**(1+q+..+q**k) rem v where q=#F
+ -- (requires call to setPoly of multiple of v)
+ -- frobenius map is used
+ normPowMod(u:FP,k:NNI,v:FP):FP ==
+ u1 :D :=reduce(u)$D
+ uu : D := u1
+ for i in 1..k repeat uu:=(u1*frobenius uu)
+ (lift uu) rem v
+
+ --find the factorization of m as product of factors each containing
+ --terms of equal degree .
+ -- if testirr=true the function returns the first factor found
+ ddffact1(m:FP,testirr:Boolean):List(fact) ==
+ p:=size$F
+ dg:NNI :=0
+ ddfact:List(fact):=empty()
+ --evaluation of x**p mod m
+ k1:NNI
+ u:= m
+ du := degree u
+ setPoly u
+ mon: FP := monomial(1,1)
+ v := mon
+ for k1 in 1.. while k1 <= (du quo 2) repeat
+ v := lift frobenius reduce(v)$D
+ g := gcd(v-mon,u)
+ dg := degree g
+ dg =0 => "next k1"
+ if leadingCoefficient g ^=1 then g := (inv leadingCoefficient g)*g
+ ddfact := cons([k1,g]$fact,ddfact)
+ testirr => return ddfact
+ u := u quo g
+ du := degree u
+ du = 0 => return ddfact
+ setPoly u
+ cons([du,u]$fact,ddfact)
+
+ -- test irreducibility
+ irreducible?(m:FP):Boolean ==
+ mf:fact:=first ddffact1(m,true)
+ degree m = mf.deg
+
+ --export ddfact1
+ separateDegrees(m:FP):List(fact) == ddffact1(m,false)
+
+ --find the complete factorization of m, using the result of ddfact1
+ separateFactors(distf : List fact) :List FP ==
+ ddfact := distf
+ n1:Integer
+ p1:=size()$F
+ if charF then n1:=length(p1)-1
+ newaux,aux,ris : List FP
+ ris := empty()
+ t,fprod : FP
+ for ffprod in ddfact repeat
+ fprod := ffprod.prod
+ d := ffprod.deg
+ degree fprod = d => ris := cons(fprod,ris)
+ aux:=[fprod]
+ setPoly fprod
+ while ^(empty? aux) repeat
+ t := ranpol(2*d)
+ if charF then t:=trace2PowMod(t,(n1*d-1)::NNI,fprod)
+ else t:=exptMod(tracePowMod(t,(d-1)::NNI,fprod),
+ (p1 quo 2)::NNI,fprod)-1$FP
+ newaux:=empty()
+ for u in aux repeat
+ g := gcd(u,t)
+ dg:= degree g
+ dg=0 or dg = degree u => newaux:=cons(u,newaux)
+ v := u quo g
+ if dg=d then ris := cons(inv(leadingCoefficient g)*g,ris)
+ else newaux := cons(g,newaux)
+ if degree v=d then ris := cons(inv(leadingCoefficient v)*v,ris)
+ else newaux := cons(v,newaux)
+ aux:=newaux
+ ris
+
+ --distinct degree algorithm for monic ,square-free polynomial
+ ddffact(m:FP):List(FP)==
+ ddfact:=ddffact1(m,false)
+ empty? ddfact => [m]
+ separateFactors ddfact
+
+ --factorize a general polynomial with distinct degree algorithm
+ --if test=true no check is executed on square-free
+ distdfact(m:FP,test:Boolean):FinalFact ==
+ factlist: List(ParFact):= empty()
+ fln : List(FP) :=empty()
+
+ --make m monic
+ if (lcm := leadingCoefficient m) ^=1 then m := (inv lcm)*m
+
+ --is x**d factor of m?
+ if (d := minimumDegree m)>0 then
+ m := (monicDivide (m,monomial(1,d))).quotient
+ factlist := [[monomial(1,1),d]$ParFact]
+ d:=degree m
+
+ --is m constant?
+ d=0 => [lcm,factlist]$FinalFact
+
+ --is m linear?
+ d=1 => [lcm,cons([m,d]$ParFact,factlist)]$FinalFact
+
+ --m is square-free
+ test =>
+ fln := ddffact m
+ factlist := append([[pol,1]$ParFact for pol in fln],factlist)
+ [lcm,factlist]$FinalFact
+
+ --factorize the monic,square-free terms
+ factlist:= append(notSqFr(m,ddffact),factlist)
+ [lcm,factlist]$FinalFact
+
+ --factorize the polynomial m
+ factor(m:FP) ==
+ m = 0 => 0
+ flist := distdfact(m,false)
+ makeFR(flist.cont::FP,[["prime",u.irr,u.pow]$FFE
+ for u in flist.factors])
+
+
+ --factorize the square free polynomial m
+ factorSquareFree(m:FP) ==
+ m = 0 => 0
+ flist := distdfact(m,true)
+ makeFR(flist.cont::FP,[["prime",u.irr,u.pow]$FFE
+ for u in flist.factors])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+--The Berlekamp package for the finite factorization is in FINFACT.
+
+<<package DDFACT DistinctDegreeFactorize>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/defaults.spad.pamphlet b/src/algebra/defaults.spad.pamphlet
new file mode 100644
index 00000000..f4c99786
--- /dev/null
+++ b/src/algebra/defaults.spad.pamphlet
@@ -0,0 +1,221 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra defaults.spad}
+\author{Michael Monagan}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REPSQ RepeatedSquaring}
+<<package REPSQ RepeatedSquaring>>=
+)abbrev package REPSQ RepeatedSquaring
+++ Repeated Squaring
+++ Description:
+++ Implements exponentiation by repeated squaring
+++ RelatedOperations: expt
+-- the following package is only instantiated over %
+-- thus shouldn't be cached. We prevent it
+-- from being cached by declaring it to be mutableDomains
+
+)bo PUSH('RepeatedSquaring, $mutableDomains)
+
+RepeatedSquaring(S): Exports == Implementation where
+ S: SetCategory with
+ "*":(%,%)->%
+ ++ x*y returns the product of x and y
+ Exports == with
+ expt: (S,PositiveInteger) -> S
+ ++ expt(r, i) computes r**i by repeated squaring
+ Implementation == add
+ x: S
+ n: PositiveInteger
+ expt(x, n) ==
+-- one? n => x
+ (n = 1) => x
+ odd?(n)$Integer=> x * expt(x*x,shift(n,-1) pretend PositiveInteger)
+ expt(x*x,shift(n,-1) pretend PositiveInteger)
+
+@
+\section{package REPDB RepeatedDoubling}
+<<package REPDB RepeatedDoubling>>=
+)abbrev package REPDB RepeatedDoubling
+++ Repeated Doubling
+++ Integer multiplication by repeated doubling.
+++ Description:
+++ Implements multiplication by repeated addition
+++ RelatedOperations: *
+
+-- the following package is only instantiated over %
+-- thus shouldn't be cached. We prevent it
+-- from being cached by declaring it to be mutableDomains
+
+)bo PUSH('RepeatedDoubling, $mutableDomains)
+
+RepeatedDoubling(S):Exports ==Implementation where
+ S: SetCategory with
+ "+":(%,%)->%
+ ++ x+y returns the sum of x and y
+ Exports == with
+ double: (PositiveInteger,S) -> S
+ ++ double(i, r) multiplies r by i using repeated doubling.
+ Implementation == add
+ x: S
+ n: PositiveInteger
+ double(n,x) ==
+-- one? n => x
+ (n = 1) => x
+ odd?(n)$Integer =>
+ x + double(shift(n,-1) pretend PositiveInteger,(x+x))
+ double(shift(n,-1) pretend PositiveInteger,(x+x))
+
+@
+\section{package FLASORT FiniteLinearAggregateSort}
+<<package FLASORT FiniteLinearAggregateSort>>=
+)abbrev package FLASORT FiniteLinearAggregateSort
+++ FiniteLinearAggregateSort
+++ Sort package (in-place) for shallowlyMutable Finite Linear Aggregates
+++ Author: Michael Monagan Sep/88
+++ RelatedOperations: sort
+++ Description:
+++ This package exports 3 sorting algorithms which work over
+++ FiniteLinearAggregates.
+-- the following package is only instantiated over %
+-- thus shouldn't be cached. We prevent it
+-- from being cached by declaring it to be mutableDomains
+
+)bo PUSH('FiniteLinearAggregateSort, $mutableDomains)
+
+FiniteLinearAggregateSort(S, V): Exports == Implementation where
+ S: Type
+ V: FiniteLinearAggregate(S) with shallowlyMutable
+
+ B ==> Boolean
+ I ==> Integer
+
+ Exports ==> with
+ quickSort: ((S, S) -> B, V) -> V
+ ++ quickSort(f, agg) sorts the aggregate agg with the ordering function
+ ++ f using the quicksort algorithm.
+ heapSort : ((S, S) -> B, V) -> V
+ ++ heapSort(f, agg) sorts the aggregate agg with the ordering function
+ ++ f using the heapsort algorithm.
+ shellSort: ((S, S) -> B, V) -> V
+ ++ shellSort(f, agg) sorts the aggregate agg with the ordering function
+ ++ f using the shellSort algorithm.
+
+ Implementation ==> add
+ siftUp : ((S, S) -> B, V, I, I) -> Void
+ partition: ((S, S) -> B, V, I, I, I) -> I
+ QuickSort: ((S, S) -> B, V, I, I) -> V
+
+ quickSort(l, r) == QuickSort(l, r, minIndex r, maxIndex r)
+
+ siftUp(l, r, i, n) ==
+ t := qelt(r, i)
+ while (j := 2*i+1) < n repeat
+ if (k := j+1) < n and l(qelt(r, j), qelt(r, k)) then j := k
+ if l(t,qelt(r,j)) then
+ qsetelt_!(r, i, qelt(r, j))
+ qsetelt_!(r, j, t)
+ i := j
+ else leave
+
+ heapSort(l, r) ==
+ not zero? minIndex r => error "not implemented"
+ n := (#r)::I
+ for k in shift(n,-1) - 1 .. 0 by -1 repeat siftUp(l, r, k, n)
+ for k in n-1 .. 1 by -1 repeat
+ swap_!(r, 0, k)
+ siftUp(l, r, 0, k)
+ r
+
+ partition(l, r, i, j, k) ==
+ -- partition r[i..j] such that r.s <= r.k <= r.t
+ x := qelt(r, k)
+ t := qelt(r, i)
+ qsetelt_!(r, k, qelt(r, j))
+ while i < j repeat
+ if l(x,t) then
+ qsetelt_!(r, j, t)
+ j := j-1
+ t := qsetelt_!(r, i, qelt(r, j))
+ else (i := i+1; t := qelt(r, i))
+ qsetelt_!(r, j, x)
+ j
+
+ QuickSort(l, r, i, j) ==
+ n := j - i
+-- if one? n and l(qelt(r, j), qelt(r, i)) then swap_!(r, i, j)
+ if (n = 1) and l(qelt(r, j), qelt(r, i)) then swap_!(r, i, j)
+ n < 2 => return r
+ -- for the moment split at the middle item
+ k := partition(l, r, i, j, i + shift(n,-1))
+ QuickSort(l, r, i, k - 1)
+ QuickSort(l, r, k + 1, j)
+
+ shellSort(l, r) ==
+ m := minIndex r
+ n := maxIndex r
+ -- use Knuths gap sequence: 1,4,13,40,121,...
+ g := 1
+ while g <= (n-m) repeat g := 3*g+1
+ g := g quo 3
+ while g > 0 repeat
+ for i in m+g..n repeat
+ j := i-g
+ while j >= m and l(qelt(r, j+g), qelt(r, j)) repeat
+ swap_!(r,j,j+g)
+ j := j-g
+ g := g quo 3
+ r
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REPSQ RepeatedSquaring>>
+<<package REPDB RepeatedDoubling>>
+<<package FLASORT FiniteLinearAggregateSort>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/defintef.spad.pamphlet b/src/algebra/defintef.spad.pamphlet
new file mode 100644
index 00000000..d76f8a01
--- /dev/null
+++ b/src/algebra/defintef.spad.pamphlet
@@ -0,0 +1,267 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra defintef.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DEFINTEF ElementaryFunctionDefiniteIntegration}
+<<package DEFINTEF ElementaryFunctionDefiniteIntegration>>=
+)abbrev package DEFINTEF ElementaryFunctionDefiniteIntegration
+++ Definite integration of elementary functions.
+++ Author: Manuel Bronstein
+++ Date Created: 14 April 1992
+++ Date Last Updated: 2 February 1993
+++ Description:
+++ \spadtype{ElementaryFunctionDefiniteIntegration}
+++ provides functions to compute definite
+++ integrals of elementary functions.
+ElementaryFunctionDefiniteIntegration(R, F): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
+ AlgebraicallyClosedFunctionSpace R)
+
+ B ==> Boolean
+ SE ==> Symbol
+ Z ==> Integer
+ P ==> SparseMultivariatePolynomial(R, K)
+ K ==> Kernel F
+ UP ==> SparseUnivariatePolynomial F
+ OFE ==> OrderedCompletion F
+ U ==> Union(f1:OFE, f2:List OFE, fail:"failed", pole:"potentialPole")
+
+ Exports ==> with
+ integrate: (F, SegmentBinding OFE) -> U
+ ++ integrate(f, x = a..b) returns the integral of
+ ++ \spad{f(x)dx} from a to b.
+ ++ Error: if f has a pole for x between a and b.
+ integrate: (F, SegmentBinding OFE, String) -> U
+ ++ integrate(f, x = a..b, "noPole") returns the
+ ++ integral of \spad{f(x)dx} from a to b.
+ ++ If it is not possible to check whether f has a pole for x
+ ++ between a and b (because of parameters), then this function
+ ++ will assume that f has no such pole.
+ ++ Error: if f has a pole for x between a and b or
+ ++ if the last argument is not "noPole".
+ innerint: (F, SE, OFE, OFE, B) -> U
+ ++ innerint(f, x, a, b, ignore?) should be local but conditional
+
+ Implementation ==> add
+ import ElementaryFunctionSign(R, F)
+ import DefiniteIntegrationTools(R, F)
+ import FunctionSpaceIntegration(R, F)
+
+ polyIfCan : (P, K) -> Union(UP, "failed")
+ int : (F, SE, OFE, OFE, B) -> U
+ nopole : (F, SE, K, OFE, OFE) -> U
+ checkFor0 : (P, K, OFE, OFE) -> Union(B, "failed")
+ checkSMP : (P, SE, K, OFE, OFE) -> Union(B, "failed")
+ checkForPole: (F, SE, K, OFE, OFE) -> Union(B, "failed")
+ posit : (F, SE, K, OFE, OFE) -> Union(B, "failed")
+ negat : (F, SE, K, OFE, OFE) -> Union(B, "failed")
+ moreThan : (OFE, Fraction Z) -> Union(B, "failed")
+
+ if R has Join(ConvertibleTo Pattern Integer, PatternMatchable Integer)
+ and F has SpecialFunctionCategory then
+ import PatternMatchIntegration(R, F)
+
+ innerint(f, x, a, b, ignor?) ==
+ ((u := int(f, x, a, b, ignor?)) case f1) or (u case f2)
+ or ((v := pmintegrate(f, x, a, b)) case "failed") => u
+ [v::F::OFE]
+
+ else
+ innerint(f, x, a, b, ignor?) == int(f, x, a, b, ignor?)
+
+ integrate(f:F, s:SegmentBinding OFE) ==
+ innerint(f, variable s, lo segment s, hi segment s, false)
+
+ integrate(f:F, s:SegmentBinding OFE, str:String) ==
+ innerint(f, variable s, lo segment s, hi segment s, ignore? str)
+
+ int(f, x, a, b, ignor?) ==
+ a = b => [0::OFE]
+ k := kernel(x)@Kernel(F)
+ (z := checkForPole(f, x, k, a, b)) case "failed" =>
+ ignor? => nopole(f, x, k, a, b)
+ ["potentialPole"]
+ z::B => error "integrate: pole in path of integration"
+ nopole(f, x, k, a, b)
+
+ checkForPole(f, x, k, a, b) ==
+ ((u := checkFor0(d := denom f, k, a, b)) case "failed") or (u::B) => u
+ ((u := checkSMP(d, x, k, a, b)) case "failed") or (u::B) => u
+ checkSMP(numer f, x, k, a, b)
+
+-- true if p has a zero between a and b exclusive
+ checkFor0(p, x, a, b) ==
+ (u := polyIfCan(p, x)) case UP => checkForZero(u::UP, a, b, false)
+ (v := isTimes p) case List(P) =>
+ for t in v::List(P) repeat
+ ((w := checkFor0(t, x, a, b)) case "failed") or (w::B) => return w
+ false
+ (r := retractIfCan(p)@Union(K, "failed")) case "failed" => "failed"
+ k := r::K
+-- functions with no real zeros
+ is?(k, "exp"::SE) or is?(k, "acot"::SE) or is?(k, "cosh"::SE) => false
+-- special case for log
+ is?(k, "log"::SE) =>
+ (w := moreThan(b, 1)) case "failed" or not(w::B) => w
+ moreThan(-a, -1)
+ "failed"
+
+-- returns true if a > b, false if a < b, "failed" if can't decide
+ moreThan(a, b) ==
+ (r := retractIfCan(a)@Union(F, "failed")) case "failed" => -- infinite
+ whatInfinity(a) > 0
+ (u := retractIfCan(r::F)@Union(Fraction Z, "failed")) case "failed" =>
+ "failed"
+ u::Fraction(Z) > b
+
+-- true if p has a pole between a and b
+ checkSMP(p, x, k, a, b) ==
+ (u := polyIfCan(p, k)) case UP => false
+ (v := isTimes p) case List(P) =>
+ for t in v::List(P) repeat
+ ((w := checkSMP(t, x, k, a, b)) case "failed") or (w::B) => return w
+ false
+ (v := isPlus p) case List(P) =>
+ n := 0 -- number of summand having a pole
+ for t in v::List(P) repeat
+ (w := checkSMP(t, x, k, a, b)) case "failed" => return w
+ if w::B then n := n + 1
+ zero? n => false -- no summand has a pole
+-- one? n => true -- only one summand has a pole
+ (n = 1) => true -- only one summand has a pole
+ "failed" -- at least 2 summands have a pole
+ (r := retractIfCan(p)@Union(K, "failed")) case "failed" => "failed"
+ kk := r::K
+ -- nullary operators have no poles
+ nullary? operator kk => false
+ f := first argument kk
+ -- functions which are defined over all the reals:
+ is?(kk, "exp"::SE) or is?(kk, "sin"::SE) or is?(kk, "cos"::SE)
+ or is?(kk, "sinh"::SE) or is?(kk, "cosh"::SE) or is?(kk, "tanh"::SE)
+ or is?(kk, "sech"::SE) or is?(kk, "atan"::SE) or is?(kk, "acot"::SE)
+ or is?(kk, "asinh"::SE) => checkForPole(f, x, k, a, b)
+ -- functions which are defined on (-1,+1):
+ is?(kk, "asin"::SE) or is?(kk, "acos"::SE) or is?(kk, "atanh"::SE) =>
+ ((w := checkForPole(f, x, k, a, b)) case "failed") or (w::B) => w
+ ((w := posit(f - 1, x, k, a, b)) case "failed") or (w::B) => w
+ negat(f + 1, x, k, a, b)
+ -- functions which are defined on (+1, +infty):
+ is?(kk, "acosh"::SE) =>
+ ((w := checkForPole(f, x, k, a, b)) case "failed") or (w::B) => w
+ negat(f - 1, x, k, a, b)
+ -- functions which are defined on (0, +infty):
+ is?(kk, "log"::SE) =>
+ ((w := checkForPole(f, x, k, a, b)) case "failed") or (w::B) => w
+ negat(f, x, k, a, b)
+ "failed"
+
+-- returns true if it is certain that f takes at least one strictly positive
+-- value for x in (a,b), false if it is certain that f takes no strictly
+-- positive value in (a,b), "failed" otherwise
+-- f must be known to have no poles in (a,b)
+ posit(f, x, k, a, b) ==
+ z :=
+ (r := retractIfCan(a)@Union(F, "failed")) case "failed" => sign(f, x, a)
+ sign(f, x, r::F, "right")
+ (b1 := z case Z) and z::Z > 0 => true
+ z :=
+ (r := retractIfCan(b)@Union(F, "failed")) case "failed" => sign(f, x, b)
+ sign(f, x, r::F, "left")
+ (b2 := z case Z) and z::Z > 0 => true
+ b1 and b2 =>
+ ((w := checkFor0(numer f, k, a, b)) case "failed") or (w::B) => "failed"
+ false
+ "failed"
+
+-- returns true if it is certain that f takes at least one strictly negative
+-- value for x in (a,b), false if it is certain that f takes no strictly
+-- negative value in (a,b), "failed" otherwise
+-- f must be known to have no poles in (a,b)
+ negat(f, x, k, a, b) ==
+ z :=
+ (r := retractIfCan(a)@Union(F, "failed")) case "failed" => sign(f, x, a)
+ sign(f, x, r::F, "right")
+ (b1 := z case Z) and z::Z < 0 => true
+ z :=
+ (r := retractIfCan(b)@Union(F, "failed")) case "failed" => sign(f, x, b)
+ sign(f, x, r::F, "left")
+ (b2 := z case Z) and z::Z < 0 => true
+ b1 and b2 =>
+ ((w := checkFor0(numer f, k, a, b)) case "failed") or (w::B) => "failed"
+ false
+ "failed"
+
+-- returns a UP if p is only a poly w.r.t. the kernel x
+ polyIfCan(p, x) ==
+ q := univariate(p, x)
+ ans:UP := 0
+ while q ^= 0 repeat
+ member?(x, tower(c := leadingCoefficient(q)::F)) => return "failed"
+ ans := ans + monomial(c, degree q)
+ q := reductum q
+ ans
+
+-- integrate f for x between a and b assuming that f has no pole in between
+ nopole(f, x, k, a, b) ==
+ (u := integrate(f, x)) case F =>
+ (v := computeInt(k, u::F, a, b, false)) case "failed" => ["failed"]
+ [v::OFE]
+ ans := empty()$List(OFE)
+ for g in u::List(F) repeat
+ (v := computeInt(k, g, a, b, false)) case "failed" => return ["failed"]
+ ans := concat_!(ans, [v::OFE])
+ [ans]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DEFINTEF ElementaryFunctionDefiniteIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/defintrf.spad.pamphlet b/src/algebra/defintrf.spad.pamphlet
new file mode 100644
index 00000000..097192a5
--- /dev/null
+++ b/src/algebra/defintrf.spad.pamphlet
@@ -0,0 +1,398 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra defintrf.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DFINTTLS DefiniteIntegrationTools}
+<<package DFINTTLS DefiniteIntegrationTools>>=
+)abbrev package DFINTTLS DefiniteIntegrationTools
+++ Tools for definite integration
+++ Author: Manuel Bronstein
+++ Date Created: 15 April 1992
+++ Date Last Updated: 24 February 1993
+++ Description:
+++ \spadtype{DefiniteIntegrationTools} provides common tools used
+++ by the definite integration of both rational and elementary functions.
+DefiniteIntegrationTools(R, F): Exports == Implementation where
+ R : Join(GcdDomain, OrderedSet, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory,
+ AlgebraicallyClosedFunctionSpace R)
+
+ B ==> Boolean
+ Z ==> Integer
+ Q ==> Fraction Z
+ SE ==> Symbol
+ P ==> Polynomial R
+ RF ==> Fraction P
+ UP ==> SparseUnivariatePolynomial F
+ K ==> Kernel F
+ OFE ==> OrderedCompletion F
+ UPZ ==> SparseUnivariatePolynomial Z
+ UPQ ==> SparseUnivariatePolynomial Q
+ REC ==> Record(left:Q, right:Q)
+ REC2==> Record(endpoint:Q, dir:Z)
+ U ==> Union(fin:REC, halfinf:REC2, all:"all", failed:"failed")
+ IGNOR ==> "noPole"
+
+ Exports ==> with
+ ignore?: String -> B
+ ++ ignore?(s) is true if s is the string that tells the integrator
+ ++ to assume that the function has no pole in the integration interval.
+ computeInt: (K, F, OFE, OFE, B) -> Union(OFE, "failed")
+ ++ computeInt(x, g, a, b, eval?) returns the integral of \spad{f} for x
+ ++ between a and b, assuming that g is an indefinite integral of
+ ++ \spad{f} and \spad{f} has no pole between a and b.
+ ++ If \spad{eval?} is true, then \spad{g} can be evaluated safely
+ ++ at \spad{a} and \spad{b}, provided that they are finite values.
+ ++ Otherwise, limits must be computed.
+ checkForZero: (P, SE, OFE, OFE, B) -> Union(B, "failed")
+ ++ checkForZero(p, x, a, b, incl?) is true if p has a zero for x between
+ ++ a and b, false otherwise, "failed" if this cannot be determined.
+ ++ Check for a and b inclusive if incl? is true, exclusive otherwise.
+ checkForZero: (UP, OFE, OFE, B) -> Union(B, "failed")
+ ++ checkForZero(p, a, b, incl?) is true if p has a zero between
+ ++ a and b, false otherwise, "failed" if this cannot be determined.
+ ++ Check for a and b inclusive if incl? is true, exclusive otherwise.
+
+ Implementation ==> add
+ import RealZeroPackage UPZ
+ import InnerPolySign(F, UP)
+ import ElementaryFunctionSign(R, F)
+ import PowerSeriesLimitPackage(R, F)
+ import UnivariatePolynomialCommonDenominator(Z, Q, UPQ)
+
+ mkLogPos : F -> F
+ keeprec? : (Q, REC) -> B
+ negative : F -> Union(B, "failed")
+ mkKerPos : K -> Union(F, "positive")
+ posRoot : (UP, B) -> Union(B, "failed")
+ realRoot : UP -> Union(B, "failed")
+ var : UP -> Union(Z, "failed")
+ maprat : UP -> Union(UPZ, "failed")
+ variation : (UP, F) -> Union(Z, "failed")
+ infeval : (UP, OFE) -> Union(F, "failed")
+ checkHalfAx : (UP, F, Z, B) -> Union(B, "failed")
+ findLimit : (F, K, OFE, String, B) -> Union(OFE, "failed")
+ checkBudan : (UP, OFE, OFE, B) -> Union(B, "failed")
+ checkDeriv : (UP, OFE, OFE) -> Union(B, "failed")
+ sameSign : (UP, OFE, OFE) -> Union(B, "failed")
+ intrat : (OFE, OFE) -> U
+ findRealZero: (UPZ, U, B) -> List REC
+
+ variation(p, a) == var p(monomial(1, 1)$UP - a::UP)
+ keeprec?(a, rec) == (a > rec.right) or (a < rec.left)
+
+ checkHalfAx(p, a, d, incl?) ==
+ posRoot(p(d * (monomial(1, 1)$UP - a::UP)), incl?)
+
+ ignore? str ==
+ str = IGNOR => true
+ error "integrate: last argument must be 'noPole'"
+
+ computeInt(k, f, a, b, eval?) ==
+ is?(f, "integral"::SE) => "failed"
+ if not eval? then f := mkLogPos f
+ ((ib := findLimit(f, k, b, "left", eval?)) case "failed") or
+ ((ia := findLimit(f, k, a, "right", eval?)) case "failed") => "failed"
+ infinite?(ia::OFE) and (ia::OFE = ib::OFE) => "failed"
+ ib::OFE - ia::OFE
+
+ findLimit(f, k, a, dir, eval?) ==
+ r := retractIfCan(a)@Union(F, "failed")
+ r case F =>
+ eval? => mkLogPos(eval(f, k, r::F))::OFE
+ (u := limit(f, equation(k::F, r::F), dir)) case OFE => u::OFE
+ "failed"
+ (u := limit(f, equation(k::F::OFE, a))) case OFE => u::OFE
+ "failed"
+
+ mkLogPos f ==
+ lk := empty()$List(K)
+ lv := empty()$List(F)
+ for k in kernels f | is?(k, "log"::SE) repeat
+ if (v := mkKerPos k) case F then
+ lk := concat(k, lk)
+ lv := concat(v::F, lv)
+ eval(f, lk, lv)
+
+ mkKerPos k ==
+ (u := negative(f := first argument k)) case "failed" =>
+ log(f**2) / (2::F)
+ u::B => log(-f)
+ "positive"
+
+ negative f ==
+ (u := sign f) case "failed" => "failed"
+ u::Z < 0
+
+ checkForZero(p, x, a, b, incl?) ==
+ checkForZero(
+ map(#1::F, univariate(p, x))$SparseUnivariatePolynomialFunctions2(P, F),
+ a, b, incl?)
+
+ checkForZero(q, a, b, incl?) ==
+ ground? q => false
+ (d := maprat q) case UPZ and not((i := intrat(a, b)) case failed) =>
+ not empty? findRealZero(d::UPZ, i, incl?)
+ (u := checkBudan(q, a, b, incl?)) case "failed" =>
+ incl? => checkDeriv(q, a, b)
+ "failed"
+ u::B
+
+ maprat p ==
+ ans:UPQ := 0
+ while p ^= 0 repeat
+ (r := retractIfCan(c := leadingCoefficient p)@Union(Q,"failed"))
+ case "failed" => return "failed"
+ ans := ans + monomial(r::Q, degree p)
+ p := reductum p
+ map(numer,(splitDenominator ans).num
+ )$SparseUnivariatePolynomialFunctions2(Q, Z)
+
+ intrat(a, b) ==
+ (n := whatInfinity a) ^= 0 =>
+ (r := retractIfCan(b)@Union(F,"failed")) case "failed" => ["all"]
+ (q := retractIfCan(r::F)@Union(Q, "failed")) case "failed" =>
+ ["failed"]
+ [[q::Q, n]]
+ (q := retractIfCan(retract(a)@F)@Union(Q,"failed")) case "failed"
+ => ["failed"]
+ (n := whatInfinity b) ^= 0 => [[q::Q, n]]
+ (t := retractIfCan(retract(b)@F)@Union(Q,"failed")) case "failed"
+ => ["failed"]
+ [[q::Q, t::Q]]
+
+ findRealZero(p, i, incl?) ==
+ i case fin =>
+ l := realZeros(p, r := i.fin)
+ incl? => l
+ select_!(keeprec?(r.left, #1) and keeprec?(r.right, #1), l)
+ i case all => realZeros p
+ i case halfinf =>
+ empty?(l := realZeros p) => empty()
+ bounds:REC :=
+ i.halfinf.dir > 0 => [i.halfinf.endpoint, "max"/[t.right for t in l]]
+ ["min"/[t.left for t in l], i.halfinf.endpoint]
+ l := [u::REC for t in l | (u := refine(p, t, bounds)) case REC]
+ incl? => l
+ select_!(keeprec?(i.halfinf.endpoint, #1), l)
+ error "findRealZero: should not happpen"
+
+ checkBudan(p, a, b, incl?) ==
+ r := retractIfCan(b)@Union(F, "failed")
+ (n := whatInfinity a) ^= 0 =>
+ r case "failed" => realRoot p
+ checkHalfAx(p, r::F, n, incl?)
+ (za? := zero? p(aa := retract(a)@F)) and incl? => true
+ (n := whatInfinity b) ^= 0 => checkHalfAx(p, aa, n, incl?)
+ (zb? := zero? p(bb := r::F)) and incl? => true
+ (va := variation(p, aa)) case "failed" or
+ (vb := variation(p, bb)) case "failed" => "failed"
+ m:Z := 0
+ if za? then m := inc m
+ if zb? then m := inc m
+ odd?(v := va::Z - vb::Z) => -- p has an odd number of roots
+ incl? or even? m => true
+-- one? v => false
+ (v = 1) => false
+ "failed"
+ zero? v => false -- p has no roots
+-- one? m => true -- p has an even number > 0 of roots
+ (m = 1) => true -- p has an even number > 0 of roots
+ "failed"
+
+ checkDeriv(p, a, b) ==
+ (r := retractIfCan(p)@Union(F, "failed")) case F => zero?(r::F)
+ (s := sameSign(p, a, b)) case "failed" => "failed"
+ s::B => -- p has the same nonzero sign at a and b
+ (u := checkDeriv(differentiate p,a,b)) case "failed" => "failed"
+ u::B => "failed"
+ false
+ true
+
+ realRoot p ==
+ (b := posRoot(p, true)) case "failed" => "failed"
+ b::B => true
+ posRoot(p(p - monomial(1, 1)$UP), true)
+
+ sameSign(p, a, b) ==
+ (ea := infeval(p, a)) case "failed" => "failed"
+ (eb := infeval(p, b)) case "failed" => "failed"
+ (s := sign(ea::F * eb::F)) case "failed" => "failed"
+ s::Z > 0
+
+-- returns true if p has a positive root. Include 0 is incl0? is true
+ posRoot(p, incl0?) ==
+ (z0? := zero?(coefficient(p, 0))) and incl0? => true
+ (v := var p) case "failed" => "failed"
+ odd?(v::Z) => -- p has an odd number of positive roots
+ incl0? or not(z0?) => true
+-- one?(v::Z) => false
+ (v::Z) = 1 => false
+ "failed"
+ zero?(v::Z) => false -- p has no positive roots
+ z0? => true -- p has an even number > 0 of positive roots
+ "failed"
+
+ infeval(p, a) ==
+ zero?(n := whatInfinity a) => p(retract(a)@F)
+ (u := signAround(p, n, sign)) case "failed" => "failed"
+ u::Z::F
+
+ var q ==
+ i:Z := 0
+ (lastCoef := negative leadingCoefficient q) case "failed" =>
+ "failed"
+ while ((q := reductum q) ^= 0) repeat
+ (next := negative leadingCoefficient q) case "failed" =>
+ return "failed"
+ if ((not(lastCoef::B)) and next::B) or
+ ((not(next::B)) and lastCoef::B) then i := i + 1
+ lastCoef := next
+ i
+
+@
+\section{package DEFINTRF RationalFunctionDefiniteIntegration}
+<<package DEFINTRF RationalFunctionDefiniteIntegration>>=
+)abbrev package DEFINTRF RationalFunctionDefiniteIntegration
+++ Definite integration of rational functions.
+++ Author: Manuel Bronstein
+++ Date Created: 2 October 1989
+++ Date Last Updated: 2 February 1993
+++ Description:
+++ \spadtype{RationalFunctionDefiniteIntegration} provides functions to
+++ compute definite integrals of rational functions.
+
+
+RationalFunctionDefiniteIntegration(R): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+
+ SE ==> Symbol
+ RF ==> Fraction Polynomial R
+ FE ==> Expression R
+ ORF ==> OrderedCompletion RF
+ OFE ==> OrderedCompletion FE
+ U ==> Union(f1:OFE, f2:List OFE, fail:"failed", pole:"potentialPole")
+
+ Exports ==> with
+ integrate: (RF, SegmentBinding OFE) -> U
+ ++ integrate(f, x = a..b) returns the integral of
+ ++ \spad{f(x)dx} from a to b.
+ ++ Error: if f has a pole for x between a and b.
+ integrate: (RF, SegmentBinding OFE, String) -> U
+ ++ integrate(f, x = a..b, "noPole") returns the
+ ++ integral of \spad{f(x)dx} from a to b.
+ ++ If it is not possible to check whether f has a pole for x
+ ++ between a and b (because of parameters), then this function
+ ++ will assume that f has no such pole.
+ ++ Error: if f has a pole for x between a and b or
+ ++ if the last argument is not "noPole".
+-- the following two are contained in the above, but they are for the
+-- interpreter... DO NOT COMMENT OUT UNTIL THE INTERPRETER IS BETTER!
+ integrate: (RF, SegmentBinding ORF) -> U
+ ++ integrate(f, x = a..b) returns the integral of
+ ++ \spad{f(x)dx} from a to b.
+ ++ Error: if f has a pole for x between a and b.
+ integrate: (RF, SegmentBinding ORF, String) -> U
+ ++ integrate(f, x = a..b, "noPole") returns the
+ ++ integral of \spad{f(x)dx} from a to b.
+ ++ If it is not possible to check whether f has a pole for x
+ ++ between a and b (because of parameters), then this function
+ ++ will assume that f has no such pole.
+ ++ Error: if f has a pole for x between a and b or
+ ++ if the last argument is not "noPole".
+
+ Implementation ==> add
+ import DefiniteIntegrationTools(R, FE)
+ import IntegrationResultRFToFunction(R)
+ import OrderedCompletionFunctions2(RF, FE)
+
+ int : (RF, SE, OFE, OFE, Boolean) -> U
+ nopole: (RF, SE, OFE, OFE) -> U
+
+ integrate(f:RF, s:SegmentBinding OFE) ==
+ int(f, variable s, lo segment s, hi segment s, false)
+
+ nopole(f, x, a, b) ==
+ k := kernel(x)@Kernel(FE)
+ (u := integrate(f, x)) case FE =>
+ (v := computeInt(k, u::FE, a, b, true)) case "failed" => ["failed"]
+ [v::OFE]
+ ans := empty()$List(OFE)
+ for g in u::List(FE) repeat
+ (v := computeInt(k, g, a, b, true)) case "failed" => return ["failed"]
+ ans := concat_!(ans, [v::OFE])
+ [ans]
+
+ integrate(f:RF, s:SegmentBinding ORF) ==
+ int(f, variable s, map(#1::FE, lo segment s),
+ map(#1::FE, hi segment s), false)
+
+ integrate(f:RF, s:SegmentBinding ORF, str:String) ==
+ int(f, variable s, map(#1::FE, lo segment s),
+ map(#1::FE, hi segment s), ignore? str)
+
+ integrate(f:RF, s:SegmentBinding OFE, str:String) ==
+ int(f, variable s, lo segment s, hi segment s, ignore? str)
+
+ int(f, x, a, b, ignor?) ==
+ a = b => [0::OFE]
+ (z := checkForZero(denom f, x, a, b, true)) case "failed" =>
+ ignor? => nopole(f, x, a, b)
+ ["potentialPole"]
+ z::Boolean => error "integrate: pole in path of integration"
+ nopole(f, x, a, b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DFINTTLS DefiniteIntegrationTools>>
+<<package DEFINTRF RationalFunctionDefiniteIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/degred.spad.pamphlet b/src/algebra/degred.spad.pamphlet
new file mode 100644
index 00000000..dd903291
--- /dev/null
+++ b/src/algebra/degred.spad.pamphlet
@@ -0,0 +1,99 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra degred.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DEGRED DegreeReductionPackage}
+<<package DEGRED DegreeReductionPackage>>=
+)abbrev package DEGRED DegreeReductionPackage
+++ This package \undocumented{}
+DegreeReductionPackage(R1, R2): Cat == Capsule where
+ R1: Ring
+ R2: Join(IntegralDomain,OrderedSet)
+
+ I ==> Integer
+ PI ==> PositiveInteger
+ UP ==> SparseUnivariatePolynomial
+ RE ==> Expression R2
+
+ Cat == with
+ reduce: UP R1 -> Record(pol: UP R1, deg: PI)
+ ++ reduce(p) \undocumented{}
+ expand: (RE, PI) -> List RE
+ ++ expand(f,n) \undocumented{}
+
+ Capsule == add
+
+
+ degrees(u: UP R1): List Integer ==
+ l: List Integer := []
+ while u ^= 0 repeat
+ l := concat(degree u,l)
+ u := reductum u
+ l
+ reduce(u: UP R1) ==
+ g := "gcd"/[d for d in degrees u]
+ u := divideExponents(u, g:PI)::(UP R1)
+ [u, g:PI]
+
+ import Fraction Integer
+
+ rootOfUnity(j:I,n:I):RE ==
+ j = 0 => 1
+ arg:RE := 2*j*pi()/(n::RE)
+ cos arg + (-1)**(1/2) * sin arg
+
+ expand(s, g) ==
+ g = 1 => [s]
+ [rootOfUnity(i,g)*s**(1/g) for i in 0..g-1]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DEGRED DegreeReductionPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/derham.spad.pamphlet b/src/algebra/derham.spad.pamphlet
new file mode 100644
index 00000000..eb06ae86
--- /dev/null
+++ b/src/algebra/derham.spad.pamphlet
@@ -0,0 +1,468 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra derham.spad}
+\author{Larry A. Lambe}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category LALG LeftAlgebra}
+<<category LALG LeftAlgebra>>=
+)abbrev category LALG LeftAlgebra
+++ Author: Larry A. Lambe
+++ Date : 03/01/89; revised 03/17/89; revised 12/02/90.
+++ Description: The category of all left algebras over an arbitrary
+++ ring.
+LeftAlgebra(R:Ring): Category == Join(Ring, LeftModule R) with
+ --operations
+ coerce: R -> %
+ ++ coerce(r) returns r * 1 where 1 is the identity of the
+ ++ left algebra.
+ add
+ coerce(x:R):% == x * 1$%
+
+@
+\section{domain EAB ExtAlgBasis}
+<<domain EAB ExtAlgBasis>>=
+)abbrev domain EAB ExtAlgBasis
+--% ExtAlgBasis
+++ Author: Larry Lambe
+++ Date created: 03/14/89
+++ Description:
+++ A domain used in the construction of the exterior algebra on a set
+++ X over a ring R. This domain represents the set of all ordered
+++ subsets of the set X, assumed to be in correspondance with
+++ {1,2,3, ...}. The ordered subsets are themselves ordered
+++ lexicographically and are in bijective correspondance with an ordered
+++ basis of the exterior algebra. In this domain we are dealing strictly
+++ with the exponents of basis elements which can only be 0 or 1.
+-- Thus we really have L({0,1}).
+++
+++ The multiplicative identity element of the exterior algebra corresponds
+++ to the empty subset of X. A coerce from List Integer to an
+++ ordered basis element is provided to allow the convenient input of
+++ expressions. Another exported function forgets the ordered structure
+++ and simply returns the list corresponding to an ordered subset.
+
+ExtAlgBasis(): Export == Implement where
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+
+ Export == OrderedSet with
+ coerce : L I -> %
+ ++ coerce(l) converts a list of 0's and 1's into a basis
+ ++ element, where 1 (respectively 0) designates that the
+ ++ variable of the corresponding index of l is (respectively, is not)
+ ++ present.
+ ++ Error: if an element of l is not 0 or 1.
+ degree : % -> NNI
+ ++ degree(x) gives the numbers of 1's in x, i.e., the number
+ ++ of non-zero exponents in the basis element that x represents.
+ exponents : % -> L I
+ ++ exponents(x) converts a domain element into a list of zeros
+ ++ and ones corresponding to the exponents in the basis element
+ ++ that x represents.
+-- subscripts : % -> L I
+ -- subscripts(x) looks at the exponents in x and converts
+ -- them to the proper subscripts
+ Nul : NNI -> %
+ ++ Nul() gives the basis element 1 for the algebra generated
+ ++ by n generators.
+
+ Implement == add
+ Rep := L I
+ x,y : %
+
+ x = y == x =$Rep y
+
+ x < y ==
+ null x => not null y
+ null y => false
+ first x = first y => rest x < rest y
+ first x > first y
+
+ coerce(li:(L I)) ==
+ for x in li repeat
+ if x ^= 1 and x ^= 0 then error "coerce: values can only be 0 and 1"
+ li
+
+ degree x == (_+/x)::NNI
+
+ exponents x == copy(x @ Rep)
+
+-- subscripts x ==
+-- cntr:I := 1
+-- result: L I := []
+-- for j in x repeat
+-- if j = 1 then result := cons(cntr,result)
+-- cntr:=cntr+1
+-- reverse_! result
+
+ Nul n == [0 for i in 1..n]
+
+ coerce x == coerce(x @ Rep)$(L I)
+
+@
+\section{domain ANTISYM AntiSymm}
+<<domain ANTISYM AntiSymm>>=
+)abbrev domain ANTISYM AntiSymm
+++ Author: Larry A. Lambe
+++ Date : 01/26/91.
+++ Revised : 30 Nov 94
+++
+++ based on AntiSymmetric '89
+++
+++ Needs: ExtAlgBasis, FreeModule(Ring,OrderedSet), LALG, LALG-
+++
+++ Description: The domain of antisymmetric polynomials.
+
+
+AntiSymm(R:Ring, lVar:List Symbol): Export == Implement where
+ LALG ==> LeftAlgebra
+ FMR ==> FM(R,EAB)
+ FM ==> FreeModule
+ I ==> Integer
+ L ==> List
+ EAB ==> ExtAlgBasis -- these are exponents of basis elements in order
+ NNI ==> NonNegativeInteger
+ O ==> OutputForm
+ base ==> k
+ coef ==> c
+ Term ==> Record(k:EAB,c:R)
+
+ Export == Join(LALG(R), RetractableTo(R)) with
+ leadingCoefficient : % -> R
+ ++ leadingCoefficient(p) returns the leading
+ ++ coefficient of antisymmetric polynomial p.
+-- leadingSupport : % -> EAB
+ leadingBasisTerm : % -> %
+ ++ leadingBasisTerm(p) returns the leading
+ ++ basis term of antisymmetric polynomial p.
+ reductum : % -> %
+ ++ reductum(p), where p is an antisymmetric polynomial,
+ ++ returns p minus the leading
+ ++ term of p if p has at least two terms, and 0 otherwise.
+ coefficient : (%,%) -> R
+ ++ coefficient(p,u) returns the coefficient of
+ ++ the term in p containing the basis term u if such
+ ++ a term exists, and 0 otherwise.
+ ++ Error: if the second argument u is not a basis element.
+ generator : NNI -> %
+ ++ generator(n) returns the nth multiplicative generator,
+ ++ a basis term.
+ exp : L I -> %
+ ++ exp([i1,...in]) returns \spad{u_1\^{i_1} ... u_n\^{i_n}}
+ homogeneous? : % -> Boolean
+ ++ homogeneous?(p) tests if all of the terms of
+ ++ p have the same degree.
+ retractable? : % -> Boolean
+ ++ retractable?(p) tests if p is a 0-form,
+ ++ i.e., if degree(p) = 0.
+ degree : % -> NNI
+ ++ degree(p) returns the homogeneous degree of p.
+ map : (R -> R, %) -> %
+ ++ map(f,p) changes each coefficient of p by the
+ ++ application of f.
+
+
+-- 1 corresponds to the empty monomial Nul = [0,...,0]
+-- from EAB. In terms of the exterior algebra on X,
+-- it corresponds to the identity element which lives
+-- in homogeneous degree 0.
+
+ Implement == FMR add
+ Rep := L Term
+ x,y : EAB
+ a,b : %
+ r : R
+ m : I
+
+ dim := #lVar
+
+ 1 == [[ Nul(dim)$EAB, 1$R ]]
+
+ coefficient(a,u) ==
+ not null u.rest => error "2nd argument must be a basis element"
+ x := u.first.base
+ for t in a repeat
+ if t.base = x then return t.coef
+ if t.base < x then return 0
+ 0
+
+ retractable?(a) ==
+ null a or (a.first.k = Nul(dim))
+
+ retractIfCan(a):Union(R,"failed") ==
+ null a => 0$R
+ a.first.k = Nul(dim) => leadingCoefficient a
+ "failed"
+
+ retract(a):R ==
+ null a => 0$R
+ leadingCoefficient a
+
+ homogeneous? a ==
+ null a => true
+ siz := _+/exponents(a.first.base)
+ for ta in reductum a repeat
+ _+/exponents(ta.base) ^= siz => return false
+ true
+
+ degree a ==
+ null a => 0$NNI
+ homogeneous? a => (_+/exponents(a.first.base)) :: NNI
+ error "not a homogeneous element"
+
+ zo : (I,I) -> L I
+ zo(p,q) ==
+ p = 0 => [1,q]
+ q = 0 => [1,1]
+ [0,0]
+
+ getsgn : (EAB,EAB) -> I
+ getsgn(x,y) ==
+ sgn:I := 0
+ xx:L I := exponents x
+ yy:L I := exponents y
+ for i in 1 .. (dim-1) repeat
+ xx := rest xx
+ sgn := sgn + (_+/xx)*yy.i
+ sgn rem 2 = 0 => 1
+ -1
+
+ Nalpha: (EAB,EAB) -> L I
+ Nalpha(x,y) ==
+ i:I := 1
+ dum2:L I := [0 for i in 1..dim]
+ for j in 1..dim repeat
+ dum:=zo((exponents x).j,(exponents y).j)
+ (i:= i*dum.1) = 0 => leave
+ dum2.j := dum.2
+ i = 0 => cons(i, dum2)
+ cons(getsgn(x,y), dum2)
+
+ a * b ==
+ null a => 0
+ null b => 0
+ ((null a.rest) and (a.first.k = Nul(dim))) => a.first.c * b
+ ((null b.rest) and (b.first.k = Nul(dim))) => b.first.c * a
+ z:% := 0
+ for tb in b repeat
+ for ta in a repeat
+ stuff:=Nalpha(ta.base,tb.base)
+ r:=first(stuff)*ta.coef*tb.coef
+ if r ^= 0 then z := z + [[rest(stuff)::EAB, r]]
+ z
+
+ coerce(r):% ==
+ r = 0 => 0
+ [ [Nul(dim), r] ]
+
+ coerce(m):% ==
+ m = 0 => 0
+ [ [Nul(dim), m::R] ]
+
+ characteristic() == characteristic()$R
+
+ generator(j) ==
+ -- j < 1 or j > dim => error "your subscript is out of range"
+ -- error will be generated by dum.j if out of range
+ dum:L I := [0 for i in 1..dim]
+ dum.j:=1
+ [[dum::EAB, 1::R]]
+
+ exp(li:(L I)) == [[li::EAB, 1]]
+
+ leadingBasisTerm a ==
+ [[a.first.k, 1]]
+
+ displayList:EAB -> O
+ displayList(x):O ==
+ le: L I := exponents(x)$EAB
+-- reduce(_*,[(lVar.i)::O for i in 1..dim | le.i = 1])$L(O)
+-- reduce(_*,[(lVar.i)::O for i in 1..dim | one?(le.i)])$L(O)
+ reduce(_*,[(lVar.i)::O for i in 1..dim | ((le.i) = 1)])$L(O)
+
+ makeTerm:(R,EAB) -> O
+ makeTerm(r,x) ==
+ -- we know that r ^= 0
+ x = Nul(dim)$EAB => r::O
+-- one? r => displayList(x)
+ (r = 1) => displayList(x)
+-- r = 1 => displayList(x)
+-- r = 0 => 0$I::O
+-- x = Nul(dim)$EAB => r::O
+ r::O * displayList(x)
+
+ coerce(a):O ==
+ zero? a => 0$I::O
+ null rest(a @ Rep) =>
+ t := first(a @ Rep)
+ makeTerm(t.coef,t.base)
+ reduce(_+,[makeTerm(t.coef,t.base) for t in (a @ Rep)])$L(O)
+
+@
+\section{domain DERHAM DeRhamComplex}
+<<domain DERHAM DeRhamComplex>>=
+)abbrev domain DERHAM DeRhamComplex
+++ Author: Larry A. Lambe
+++ Date : 01/26/91.
+++ Revised : 12/01/91.
+++
+++ based on code from '89 (AntiSymmetric)
+++
+++ Needs: LeftAlgebra, ExtAlgBasis, FreeMod(Ring,OrderedSet)
+++
+++ Description: The deRham complex of Euclidean space, that is, the
+++ class of differential forms of arbitary degree over a coefficient ring.
+++ See Flanders, Harley, Differential Forms, With Applications to the Physical
+++ Sciences, New York, Academic Press, 1963.
+
+DeRhamComplex(CoefRing,listIndVar:List Symbol): Export == Implement where
+ CoefRing : Join(Ring, OrderedSet)
+ ASY ==> AntiSymm(R,listIndVar)
+ DIFRING ==> DifferentialRing
+ LALG ==> LeftAlgebra
+ FMR ==> FreeMod(R,EAB)
+ I ==> Integer
+ L ==> List
+ EAB ==> ExtAlgBasis -- these are exponents of basis elements in order
+ NNI ==> NonNegativeInteger
+ O ==> OutputForm
+ R ==> Expression(CoefRing)
+
+ Export == Join(LALG(R), RetractableTo(R)) with
+ leadingCoefficient : % -> R
+ ++ leadingCoefficient(df) returns the leading
+ ++ coefficient of differential form df.
+ leadingBasisTerm : % -> %
+ ++ leadingBasisTerm(df) returns the leading
+ ++ basis term of differential form df.
+ reductum : % -> %
+ ++ reductum(df), where df is a differential form,
+ ++ returns df minus the leading
+ ++ term of df if df has two or more terms, and
+ ++ 0 otherwise.
+ coefficient : (%,%) -> R
+ ++ coefficient(df,u), where df is a differential form,
+ ++ returns the coefficient of df containing the basis term u
+ ++ if such a term exists, and 0 otherwise.
+ generator : NNI -> %
+ ++ generator(n) returns the nth basis term for a differential form.
+ homogeneous? : % -> Boolean
+ ++ homogeneous?(df) tests if all of the terms of
+ ++ differential form df have the same degree.
+ retractable? : % -> Boolean
+ ++ retractable?(df) tests if differential form df is a 0-form,
+ ++ i.e., if degree(df) = 0.
+ degree : % -> I
+ ++ degree(df) returns the homogeneous degree of differential form df.
+ map : (R -> R, %) -> %
+ ++ map(f,df) replaces each coefficient x of differential
+ ++ form df by \spad{f(x)}.
+ totalDifferential : R -> %
+ ++ totalDifferential(x) returns the total differential
+ ++ (gradient) form for element x.
+ exteriorDifferential : % -> %
+ ++ exteriorDifferential(df) returns the exterior
+ ++ derivative (gradient, curl, divergence, ...) of
+ ++ the differential form df.
+
+ Implement == ASY add
+ Rep := ASY
+
+ dim := #listIndVar
+
+ totalDifferential(f) ==
+ divs:=[differentiate(f,listIndVar.i)*generator(i)$ASY for i in 1..dim]
+ reduce("+",divs)
+
+ termDiff : (R, %) -> %
+ termDiff(r,e) ==
+ totalDifferential(r) * e
+
+ exteriorDifferential(x) ==
+ x = 0 => 0
+ termDiff(leadingCoefficient(x)$Rep,leadingBasisTerm x) + exteriorDifferential(reductum x)
+
+ lv := [concat("d",string(liv))$String::Symbol for liv in listIndVar]
+
+ displayList:EAB -> O
+ displayList(x):O ==
+ le: L I := exponents(x)$EAB
+-- reduce(_*,[(lv.i)::O for i in 1..dim | le.i = 1])$L(O)
+-- reduce(_*,[(lv.i)::O for i in 1..dim | one?(le.i)])$L(O)
+ reduce(_*,[(lv.i)::O for i in 1..dim | ((le.i) = 1)])$L(O)
+
+ makeTerm:(R,EAB) -> O
+ makeTerm(r,x) ==
+ -- we know that r ^= 0
+ x = Nul(dim)$EAB => r::O
+-- one? r => displayList(x)
+ (r = 1) => displayList(x)
+-- r = 1 => displayList(x)
+ r::O * displayList(x)
+
+ terms : % -> List Record(k: EAB, c: R)
+ terms(a) ==
+ -- it is the case that there are at least two terms in a
+ a pretend List Record(k: EAB, c: R)
+
+ coerce(a):O ==
+ a = 0$Rep => 0$I::O
+ ta := terms a
+-- reductum(a) = 0$Rep => makeTerm(leadingCoefficient a, a.first.k)
+ null ta.rest => makeTerm(ta.first.c, ta.first.k)
+ reduce(_+,[makeTerm(t.c,t.k) for t in ta])$L(O)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category LALG LeftAlgebra>>
+<<domain EAB ExtAlgBasis>>
+<<domain ANTISYM AntiSymm>>
+<<domain DERHAM DeRhamComplex>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/dhmatrix.spad.pamphlet b/src/algebra/dhmatrix.spad.pamphlet
new file mode 100644
index 00000000..5c075992
--- /dev/null
+++ b/src/algebra/dhmatrix.spad.pamphlet
@@ -0,0 +1,1741 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra dhmatrix.spad}
+\author{Richard Paul and Timothy Daly}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\mathchardef\bigp="3250
+\mathchardef\bigq="3251
+\mathchardef\bigslash="232C
+\section{Homogeneous Transformations}
+The study of robot manipulation is concerned with the relationship between
+objects, and between objects and manipulators. In this chapter we will
+develop the representation necessary to describe these relationships. Similar
+problems of representation have already been solved in the field of computer
+graphics, where the relationship between objects must also be described.
+Homogeneous transformations are used in this field and in computer vision
+[Duda] [Robserts63] [Roberts65]. These transformations were employed by
+Denavit to describe linkages [Denavit] and are now used to describe
+manipulators [Pieper] [Paul72] [Paul77b].
+
+We will first establish notation for vectors and planes and then introduce
+transformations on them. These transformations consist primarily of
+translation and rotation. We will then show that these transformations
+can also be considered as coordinate frames in which to represent
+objects, including the manipulator. The inverse transformation will
+then be introduced. A later section describes the general rotation
+transformation representing a rotation about a vector. An algorithm is
+then described to find the equivalent axis and angle of rotations
+represented by any given transformation. A brief section on stretching
+and scaling transforms is included together with a section on the
+perspective transformation. The chapter concludes with a section on
+transformation equations.
+
+\section{Notation}
+
+In describing the relationship between objects we will make use of
+point vectors, planes, and coordinate frames. Point vectors are
+denoted by lower case, bold face characters. Planes are denoted by
+script characters, and coordinate frames by upper case, bold face
+characters. For example:
+
+\begin{tabular}{ll}
+vectors & {\bf v}, {\bf x1}, {\bf x} \\
+planes & $\bigp$, $\bigq$ \\
+coordinate frames & {\bf I}, {\bf A}, {\bf CONV}\\
+\end{tabular}\\
+
+We will use point vectors, planes, and coordinate frames as variables
+which have associated values. For example, a point vector has as value
+its three Cartesian coordinate components.
+
+If we wish to describe a point in space, which we will call {\sl p},
+with respect to a coordinate frame {\bf E}, we will use a vector which
+we will call {\bf v}. We will write this as
+
+$$^E{\bf v}$$
+
+\noindent
+The leading superscript describes the defining coordinate frame.
+
+We might also wish to describe this same point, {\sl p}, with respect
+to a different coordinate frame, for example {\bf H}, using a vector
+{\bf w} as
+
+$$^H{\bf w}$$
+
+\noindent
+{\bf v} and {\bf w} are two vectors which probably have different
+component values and ${\bf v} \ne {\bf w}$ even though both vectors
+describe the same point {\sl p}. The case might also exist of a vector
+{\bf a} describing a point 3 inches above any frame
+
+$${^{F^1}}{\bf a}\qquad {^{F^2}}{\bf a}$$
+
+\noindent
+In this case the vectors are identical but describe different
+points. Frequently, the defining frame will be obvious from the text
+and the superscripts will be left off. In many cases the name of the
+vector will be the same as the name of the object described, for
+example, the tip of a pin might be described by a vector {\bf tip}
+with respect to a frame {\bf BASE} as
+
+$${^{BASE}}{\bf tip}$$
+
+\noindent
+If it were obvious from the text that we were describing the vector
+with respect to {\bf BASE} then we might simply write
+
+$${\bf tip}$$
+
+If we also wish to describe this point with respect to another
+coordinate frame say, {\bf HAND}, then we must use another vector to
+describe this relationship, for example
+
+$${^{HAND}{\bf tv}}$$
+
+\noindent
+${^{HAND}{\bf tv}}$ and {\bf tip} both describe the same feature but
+have different values. In order to refer to individual components of
+coordinate frames, point vectors, or planes, we add subscripts to
+indicate the particular component. For example, the vector
+${^{HAND}{\bf tv}}$ has components ${^{HAND}{\bf tv}}_{\bf x}$,
+${^{HAND}{\bf tv}}_{\bf y}$, ${^{HAND}{\bf tv}}_{\bf z}$.
+
+\section{Vectors}
+
+The homogeneous coordinate representation of objects in $n$-space
+is an $(n + 1)$-space entity such that a particular perspective
+projection recreates the $n$-space. This can also be viewed as the
+addition of an extra coordinate to each vector, a scale factor, such
+that the vector has the same meaning if each component, including the
+scale factor, is multiplied by a constant.
+
+A point vector
+
+$${\bf v} = a{\bf i} + b{\bf j} + c{\bf k}\eqno(1.1)$$
+
+\noindent
+where {\bf i}, {\bf j}, and {\bf k} are unit vectors along the $x$,
+$y$, and $z$ coordinate axes, respectively, is represented in
+homogeneous coordinates as a column matrix
+
+$${\bf v} = \left[\matrix{{\bf x}\cr
+ {\bf y}\cr
+ {\bf z}\cr
+ {\bf w}\cr}
+ \right]\eqno(1.2)$$
+
+\noindent
+where
+
+$${{\bf a} = {\bf x}/{\bf w}}$$
+$${{\bf b} = {\bf y}/{\bf w}}\eqno(1.3)$$
+$${{\bf c} = {\bf z}/{\bf w}}$$
+
+\noindent
+Thus the vector $3{\bf i} + 4{\bf j} + 5{\bf k}$ can be represented as
+$[3,4,5,1]^{\rm T}$ or as $[6,8,10,2]^{\rm T}$ or again
+as $[-30,-40,-50,-10]^{\rm T}$,
+etc. The superscript $T$ indicates the transpose of the row vector
+into a column vector. The vector at the origin, the null vector, is
+represented as $[0,0,0,n]^{\rm T}$ where $n$ is any non-zero scale
+factor. The vector $[0,0,0,0]^{\rm T}$ is undefined. Vectors of the form
+$[a,b,c,0]^{\rm T}$ represent vectors at infinity and are used to represent
+directions; the addition of any other finite vector does not change
+their value in any way.
+
+We will also make use of the vector dot and cross products. Given two
+vectors
+
+$${\bf a} = a_x{\bf i} + a_y{\bf j} + a_z{\bf k}\eqno(1.4)$$
+$${\bf b} = b_x{\bf i} + b_y{\bf j} + b_z{\bf k}$$
+
+\noindent
+we define the vector dot product, indicated by ``$\cdot$'' as
+
+$${\bf a} \cdot {\bf b} = {a_x}{b_x} + {a_y}{b_y} + {a_z}{b_z}\eqno(1.5)$$
+
+\noindent
+The dot product of two vectors is a scalar. The cross product,
+indicated by an ``$\times$'', is another vector perpendicular to the
+plane formed by the vectors of the product and is defined by
+
+$${\bf a} \times {\bf b} = ({a_y}{b_z} - {a_z}{b_y}){\bf i} +
+ ({a_z}{b_x} - {a_x}{b_z}){\bf j} +
+ ({a_x}{b_y} - {a_y}{b_x}){\bf k}\eqno(1.6)$$
+
+\noindent
+This definition is easily remembered as the expansion of the
+determinant
+
+$${\bf a} \times {\bf b} =
+ \left|\matrix{{\bf i}&{\bf j}&{\bf k}\cr
+ {a_x}&{a_y}&{a_z}\cr
+ {b_x}&{b_y}&{b_z}\cr}\right|\eqno(1.7)$$
+
+\section{Planes}
+A plane is represented as a row matrix
+
+$$\bigp=[a,b,c,d]\eqno(1.8)$$
+
+\noindent
+such that if a point {\bf v} lies in a plane $\bigp$ the matrix
+product
+
+$$\bigp{\bf v} = 0\eqno(1.9)$$
+
+\noindent
+or in expanded form
+
+$$xa + yb + zc + wd = 0\eqno(1.10)$$
+
+\noindent
+If we define a constant
+
+$$m = +\sqrt{a^2 + b^2 + c^2}\eqno(1.11)$$
+
+\noindent
+and divide Equation 1.10 by $wm$ we obtain
+
+$${x\over w}{a\over m} + {y\over w}{b\over m} + {z\over w}{c\over m}
+ = -{d\over m}\eqno(1.12)$$
+
+\noindent
+The left hand side of Equation 1.12 is the vector dot product of two
+vectors $(x/w){\bf i} + (y/w){\bf j} + (z/w){\bf k}$ and
+$(a/m){\bf i} + (b/m){\bf j} + (c/m){\bf k}$ and represents the
+directed distance of the point
+$(x/w){\bf i} + (y/w){\bf j} + (z/w){\bf k}$ along the vector\\
+$(a/m){\bf i} + (b/m){\bf j} + (c/m){\bf k}$. The vector
+$(a/m){\bf i} + (b/m){\bf j} + (c/m){\bf k}$ can be interpreted as the
+outward pointing normal of a plane situated a distance $-d/m$ from the
+origin in the direction of the normal. Thus a plane $\bigp$ parallel
+to the $x$,$y$ plane, one unit along the $z$ axis, is represented as
+
+$${\rm {\ \ \ \ \ \ \ \ \ }} \bigp = [0,0,1,-1]\eqno(1.13)$$
+$${\rm {or\ as\ \ \ }} \bigp = [0,0,2,-2]\eqno(1.14)$$
+$${\rm {\ \ \ \ \ or\ as\ \ \ }} \bigp = [0,0,-100,100]\eqno(1.15)$$
+
+\noindent
+A point ${\bf v} = [10,20,1,1]$ should lie in this plane
+
+$$[0,0,-100,100]\left[\matrix{10\cr
+ 20\cr
+ 1\cr
+ 1\cr}
+ \right]
+ = 0\eqno(1.16)$$
+
+\noindent
+or
+
+$$[0,0,1,-1]\left[\matrix{ -5\cr
+ -10\cr
+ -.5\cr
+ -.5\cr}
+ \right]
+ = 0\eqno(1.17)$$
+
+\noindent
+The point ${\bf v} = [0,0,2,1]$ lies above the plane
+
+$$[0,0,2,-2]\left[\matrix{0\cr
+ 0\cr
+ 2\cr
+ 1\cr}
+ \right]
+ = 2\eqno(1.18)$$
+
+and $\bigp{\bf v}$ is indeed positive, indicating that the point is
+outside the plane in the direction of the outward pointing normal. A
+point ${\bf v} = [0,0,0,1]$ lies below the plane
+
+$$[0,0,1,-1]\left[\matrix{0\cr
+ 0\cr
+ 0\cr
+ 1\cr}
+ \right]
+ = -1\eqno(1.19)$$
+
+\noindent
+The plane $[0,0,0,0]$ is undefined.
+
+\section{Transformations}
+
+\noindent
+A transformation of the space {\bf H} is a 4x4 matrix and can
+represent translation, rotation, stretching, and perspective
+transformations. Given a point {\bf u}, its transformation {\bf v} is
+represented by the matrix product
+
+$${\bf v} = {\bf H}{\bf u}\eqno(1.20)$$
+
+\noindent
+The corresponding plane transformation $\bigp$ to $\bigq$ is
+
+$$\bigq = \bigp{\bf H^{-1}}\eqno(1.21)$$
+
+\noindent
+as we requre that the condition
+
+$$\bigq{\bf v} = \bigp{\bf u}\eqno(1.22)$$
+
+\noindent
+is invariant under all transformations. To verify this we substitute
+from Equations 1.20 and 1.21 into the left hand side of 1.22 and we
+obtain on the right hand side ${\bf H^{-1}}{\bf H}$ which is the
+identity matrix {\bf I}
+
+$$\bigp{\bf H^{-1}}{\bf H}{\bf u} = \bigp{\bf u}\eqno(1.23)$$
+
+\section{Translation Transformation}
+
+\noindent
+The transformation {\bf H} corresponding to a translation by a vector
+$a{\bf i} + b{\bf j} + c{\bf k}$ is
+
+$${\bf H} = {\bf Trans(a,b,c)} =
+ \left[\matrix{1&0&0&a\cr
+ 0&1&0&b\cr
+ 0&0&1&c\cr
+ 0&0&0&1\cr}
+ \right]\eqno(1.24)$$
+
+\noindent
+Given a vector ${\bf u} = [x,y,z,w]^{\rm T}$ the transformed vector {\bf v}
+is given by
+
+$${\bf H} = {\bf Trans(a,b,c)} =
+ \left[\matrix{1&0&0&a\cr
+ 0&1&0&b\cr
+ 0&0&1&c\cr
+ 0&0&0&1\cr}
+ \right]
+ \left[\matrix{x\cr
+ y\cr
+ z\cr
+ w\cr}
+ \right]\eqno(1.25)$$
+
+$${\bf v} = \left[\matrix{x + aw\cr
+ y + bw\cr
+ z + cw\cr
+ w\cr}
+ \right]
+ = \left[\matrix{x/w + a\cr
+ y/w + b\cr
+ z/w + c\cr
+ 1\cr}
+ \right]\eqno(1.26)$$
+
+\noindent
+The translation may also be interpreted as the addition of the two
+vectors $(x/w){\bf i} + (y/w){\bf j} + (z/w){\bf k}$ and
+$a{\bf i} + b{\bf j} + c{\bf k}$.
+
+Every element of a transformation matrix may be multiplied by a
+non-zero constant without changing the transformation, in the same
+manner as points and planes. Consider the vector $2{\bf i} + 3{\bf j}
++ 2{\bf k}$ translated by, or added to\\
+4{\bf i} - 3{\bf j} + 7{\bf k}
+
+$$\left[\matrix{6\cr
+ 0\cr
+ 9\cr
+ 1\cr}
+ \right] =
+ \left[\matrix{1 & 0 & 0 & 4\cr
+ 0 & 1 & 0 & -3\cr
+ 0 & 0 & 1 & 7\cr
+ 0 & 0 & 0 & 1\cr}
+ \right]
+ \left[\matrix{2\cr
+ 3\cr
+ 2\cr
+ 1\cr}
+ \right]\eqno(1.27)$$
+
+\noindent
+If we multiply the transmation matrix elements by, say, -5, and the
+vector elements by 2, we obtain
+
+$$\left[\matrix{-60\cr
+ 0\cr
+ -90\cr
+ -10\cr}
+ \right] =
+ \left[\matrix{-5 & 0 & 0 & -20\cr
+ 0 & -5 & 0 & 15\cr
+ 0 & 0 & -5 & -35\cr
+ 0 & 0 & 0 & -5\cr}
+ \right]
+ \left[\matrix{4\cr
+ 6\cr
+ 4\cr
+ 2\cr}
+ \right]\eqno(1.28)$$
+
+\noindent
+which corresponds to the vector $[6,0,9,1]^{\rm T}$ as before. The point
+$[2,3,2,1]$ lies in the plane $[1,0,0,-2]$
+
+$$[1,0,0,-2]\left[\matrix{2\cr
+ 3\cr
+ 2\cr
+ 1\cr}
+ \right] = 0\eqno(1.29)$$
+
+\noindent
+The transformed point is, as we have already found, $[6,0,9,1]^{\rm T}$. We
+will now compute the transformed plane. The inverse of the transform
+is
+
+$$\left[\matrix{1 & 0 & 0 & -4\cr
+ 0 & 1 & 0 & 3\cr
+ 0 & 0 & 1 & -7\cr
+ 0 & 0 & 0 & 1\cr}\right]$$
+
+\noindent
+and the transformed plane
+
+$$[1\ 0\ 0\ -6] = [1\ 0\ 0\ -2]\left[\matrix{1 & 0 & 0 & -4\cr
+ 0 & 1 & 0 & 3\cr
+ 0 & 0 & 1 & -7\cr
+ 0 & 0 & 0 & 1\cr}
+ \right]\eqno(1.30)$$
+
+\noindent
+Once again the transformed point lies in the transformed plane
+
+$$[1\ 0\ 0\ -6] \left[\matrix{6\cr
+ 0\cr
+ 9\cr
+ 1\cr}\right] = 0\eqno(1.31)$$
+
+The general translation operation can be represented in Axiom as
+
+<<translate>>=
+ translate(x,y,z) ==
+ matrix(_
+ [[1,0,0,x],_
+ [0,1,0,y],_
+ [0,0,1,z],_
+ [0,0,0,1]])
+@
+\section{Rotation Transformations}
+
+\noindent
+The transformations corresponding to rotations about the $x$, $y$, and
+$z$ axes by an angle $\theta$ are
+
+$${\bf Rot(x,\theta)} =
+ \left[\matrix{1 & 0 & 0 & 0\cr
+ 0 & {cos\ \theta} & {-sin\ \theta} & 0\cr
+ 0 & {sin\ \theta} & {cos\ \theta} & 0\cr
+ 0 & 0 & 0 & 1}\right]
+ \eqno(1.32)$$
+
+Rotations can be described in Axiom as functions that return
+matrices. We can define a function for each of the rotation matrices
+that correspond to the rotations about each axis. Note that the
+sine and cosine functions in Axiom expect their argument to be in
+radians rather than degrees. This conversion is
+
+$$radians = {{degrees * \pi}\over{180}}$$
+
+\noindent
+The Axiom code for ${\bf Rot(x,degree)}$ is
+
+<<rotatex>>=
+ rotatex(degree) ==
+ angle := degree * pi() / 180::R
+ cosAngle := cos(angle)
+ sinAngle := sin(angle)
+ matrix(_
+ [[1, 0, 0, 0], _
+ [0, cosAngle, -sinAngle, 0], _
+ [0, sinAngle, cosAngle, 0], _
+ [0, 0, 0, 1]])
+@
+
+$${\bf Rot(y,\theta)} =
+ \left[\matrix{{cos\ \theta} & 0 & {sin\ \theta} & 0\cr
+ 0 & 1 & 0 & 0\cr
+ {-sin\ \theta} & 0 & {cos\ \theta} & 0\cr
+ 0 & 0 & 0 & 1\cr}\right]
+ \eqno(1.33)$$
+
+\noindent
+The Axiom code for ${\bf Rot(y,degree)}$ is
+
+<<rotatey>>=
+ rotatey(degree) ==
+ angle := degree * pi() / 180::R
+ cosAngle := cos(angle)
+ sinAngle := sin(angle)
+ matrix(_
+ [[ cosAngle, 0, sinAngle, 0], _
+ [ 0, 1, 0, 0], _
+ [-sinAngle, 0, cosAngle, 0], _
+ [ 0, 0, 0, 1]])
+@
+
+$${\bf Rot(z,\theta)} =
+ \left[\matrix{{cos\ \theta} & {-sin\ \theta} & 0 & 0\cr
+ {sin\ \theta} & {cos\ \theta} & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}\right]
+ \eqno(1.34)$$
+
+\noindent
+And the Axiom code for ${\bf Rot(z,degree)}$ is
+
+<<rotatez>>=
+ rotatez(degree) ==
+ angle := degree * pi() / 180::R
+ cosAngle := cos(angle)
+ sinAngle := sin(angle)
+ matrix(_
+ [[cosAngle, -sinAngle, 0, 0], _
+ [sinAngle, cosAngle, 0, 0], _
+ [ 0, 0, 1, 0], _
+ [ 0, 0, 0, 1]])
+@
+\noindent
+Let us interpret these rotations by means of an example. Given a point
+${\bf u} = 7{\bf i} + 3{\bf j} + 2{\bf k}$ what is the effect of
+rotating it $90^\circ$ about the ${\bf z}$ axis to ${\bf v}$? The
+transform is obtained from Equation 1.34 with $sin\ \theta = 1$ and
+$cos\ \theta = 0$.
+
+$$\left[\matrix{-3\cr
+ 7\cr
+ 2\cr
+ 1\cr}
+ \right] =
+ \left[\matrix{0 & -1 & 0 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1\cr}
+ \right]
+ \left[\matrix{7\cr
+ 3\cr
+ 2\cr
+ 1\cr}
+ \right]\eqno(1.35)$$
+
+\noindent
+Let us now rotate {\bf v} $90^\circ$ about the $y$ axis to
+{\bf w}. The transform is obtained from Equation 1.33 and we have
+
+$$\left[\matrix{2\cr
+ 7\cr
+ 3\cr
+ 1\cr}
+ \right] =
+ \left[\matrix{ 0 & 0 & 1 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ -1 & 0 & 0 & 0\cr
+ 0 & 0 & 0 & 1\cr}
+ \right]
+ \left[\matrix{-3\cr
+ 7\cr
+ 2\cr
+ 1\cr}
+ \right]\eqno(1.36)$$
+
+\noindent
+If we combine these two rotations we have
+
+$${\rm \ \ \ \ \ \ \ } {\bf v} = {\bf Rot(z,90)}{\bf u}\eqno(1.37)$$
+
+$${\rm and\ \ \ } {\bf w} = {\bf Rot(y,90)}{\bf v}\eqno(1.38)$$
+
+\noindent
+Substituting for {\bf v} from Equation 1.37 into Equation 1.38 we
+obtain
+
+$${\bf w} = {\bf Rot(y,90)}\ {\bf Rot(z,90)}\ {\bf u}\eqno(1.39)$$
+
+$${\bf Rot(y,90)}\ {\bf Rot(z,90)} =
+ \left[\matrix{ 0 & 0 & 1 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ -1 & 0 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{0 & -1 & 0 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.40)$$
+
+$${\bf Rot(y,90)}\ {\bf Rot(z,90)} =
+ \left[\matrix{0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.41)$$
+
+\noindent
+thus
+
+$${\bf w} = \left[\matrix{2\cr
+ 7\cr
+ 3\cr
+ 1}\right]
+ = \left[\matrix{0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}\right]
+ \left[\matrix{7\cr
+ 3\cr
+ 2\cr
+ 1}\right]\eqno(1.42)$$
+
+\noindent
+as we obtained before.
+
+If we reverse the order of rotations and first rotate $90^\circ$ about
+the $y$ axis and then $90^\circ$ about the $z$ axis, we obtain a
+different position
+
+$${\bf Rot(z,90)}{\bf Rot(y,90)} =
+ \left[\matrix{0 & -1 & 0 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{ 0 & 0 & 1 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ -1 & 0 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ = \left[\matrix{ 0 & -1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ -1 & 0 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.43)$$
+
+\noindent
+and the point {\bf u} transforms into {\bf w} as
+
+$$\left[\matrix{-3\cr
+ 2\cr
+ -7\cr
+ 1}
+ \right]
+ = \left[\matrix{ 0 & -1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ -1 & 0 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{7\cr
+ 3\cr
+ 2\cr
+ 1}
+ \right]\eqno(1.44)$$
+
+\noindent
+We should expect this, as matrix multiplication is noncommutative.
+
+$${\bf A}{\bf B} \ne {\bf B}{\bf A}\eqno(1.45)$$
+
+We will now combine the original rotation with a translation
+$4{\bf i}-3{\bf j}+7{\bf k}$. We obtain the translation from Equation
+1.27 and the rotation from Equation 1.41. The matrix expression is
+
+$${\bf Trans(4,-3,7)}{\bf Rot(y,90)}{\bf Rot(z,90)}
+ = \left[\matrix{1 & 0 & 0 & 4\cr
+ 0 & 1 & 0 & -3\cr
+ 0 & 0 & 1 & 7\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ = \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & -3\cr
+ 0 & 1 & 0 & 7\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.46)$$
+
+\noindent
+and our point ${\bf w} = 7{\bf i}+3{\bf j}+2{\bf k}$ transforms into
+{\bf x} as
+
+$$\left[\matrix{ 6\cr
+ 4\cr
+ 10\cr
+ 1}
+ \right]
+ = \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & -3\cr
+ 0 & 1 & 0 & 7\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{7\cr
+ 3\cr
+ 2\cr
+ 1}
+ \right]\eqno(1.47)$$
+
+\section{Coordinate Frames}
+
+\noindent
+We can interpret the elements of the homogeneous transformation as
+four vectors describing a second coordinate frame. The vector
+$[0,0,0,1]^{\rm T}$ lies at the origin of the second coordinate frame. Its
+transformation corresponds to the right hand column of the
+transformation matrix. Consider the transform in Equation 1.47
+
+$$\left[\matrix{ 4\cr
+ -3\cr
+ 7\cr
+ 1}
+ \right]
+ = \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & -3\cr
+ 0 & 1 & 0 & 7\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{0\cr
+ 0\cr
+ 0\cr
+ 1}
+ \right]\eqno(1.48)$$
+
+\noindent
+The transform of the null vector is $[4,-3,7,1]^{\rm T}$, the right
+hand column. If we transform vectors corresponding to unit vectors
+along the $x$, $y$, and $z$ axes, we obtain $[4,-2,7,1]^{\rm T}$,
+$[4,-3,8,1]^{\rm T}$, and $[5,-3,7,1]^{\rm T}$, respectively. Those
+four vectors form a coordinate frame.
+
+The direction of these unit vectors is formed by subtracting the
+vector representing the origin of this coordinate frame and extending
+the vectors to infinity by reducing their scale factors to zero. The
+direction of the $x$, $y$, and $z$ axes of this frame are
+$[0,1,0,0]^{\rm T}$, $[0,0,1,0]^{\rm T}$, and $[1,0,0,0]^{\rm T}$,
+respectively. These direction vectors correspond to the first three
+columns of the transformation matrix. The transformation matrix thus
+describes the three axis directions and the position of the origin of
+a coordinate frame rotated and translated away from the reference
+coordinate frame. When a vector is transformed, as in Equation 1.47,
+the original vector can be considered as a vector described in the
+coordinate frame. The transformed vector is the same vector described
+with respect to the reference coordinate frame.
+
+\section{Relative Transformations}
+
+\noindent
+The rotations and translations we have been describing have all been
+made with respect to the fixed reference coordinate frame. Thus, in
+the example given,
+
+$${\bf Trans(4,-3,7)}{\bf Rot(y,90)}{\bf Rot(z,90)}
+ = \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & -3\cr
+ 0 & 1 & 0 & 7\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.49)$$
+
+\noindent
+the frame is first rotated around the reference $z$ axis by
+$90^\circ$, then rotated $90^\circ$ around the reference $y$ axis, and
+finally translated by $4{\bf i}-3{\bf j}+7{\bf k}$. We may also
+interpret the operation in the reverse order, from left to right, as
+follows: the object is first translated by
+$4{\bf i}-3{\bf j}+7{\bf k}$; it is then rotated $90^\circ$ around the
+current frames axes, which in this case are the same as the reference
+axes; it is then rotated $90^\circ$ about the newly rotated (current)
+frames axes.
+
+In general, if we postmultiply a transform representing a frame by a
+second transformation describing a rotation and/or translation, we
+make that translation and/or rotation with respect to the frame axes
+described by the first transformation. If we premultiply the frame
+transformation by a transformation representing a translation and/or
+rotation, then that translation and/or rotation is made with respect to
+the base reference coordinate frame. Thus, given a frame {\bf C} and a
+transformation {\bf T}, corresponding to a rotation of $90^\circ$
+about the $z$ axis, and a translation of 10 units in the $x$
+direction, we obtain a new position {\bf X} when the change is made in
+the base coordinates ${\bf X} = {\bf T} {\bf C}$
+
+$$\left[\matrix{0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & 20\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ = \left[\matrix{0 & -1 & 0 & 10\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{1 & 0 & 0 & 20\cr
+ 0 & 0 & -1 & 10\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.50)$$
+
+\noindent
+and a new position {\bf Y} when the change is made relative to the
+frame axes as ${\bf Y} = {\bf C} {\bf T}$
+
+$$\left[\matrix{0 & -1 & 0 & 30\cr
+ 0 & 0 & -1 & 10\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ = \left[\matrix{1 & 0 & 0 & 20\cr
+ 0 & 0 & -1 & 10\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{0 & -1 & 0 & 10\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.51)$$
+
+\section{Objects}
+
+\noindent
+Transformations are used to describe the position and orientation of
+objects. An object is described by six points with respect to a
+coordinate frame fixed in the object.
+
+If we rotate the object $90^\circ$ about the $z$ axis and then
+$90^\circ$ about the $y$ axis, followed by a translation of four units
+in the $x$ direction, we can describe the transformation as
+
+$${\bf Trans(4,0,0)}{\bf Rot(y,90)}{\bf Rot(z,90)} =
+ \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.52)$$
+
+\noindent
+The transformation matrix represents the operation of rotation and
+translation on a coordinate frame originally aligned with the
+reference coordinate frame. We may transform the six points of the
+object as
+
+$$\left[\matrix{4 & 4 & 6 & 6 & 4 & 4\cr
+ 1 & -1 & -1 & 1 & 1 & -1\cr
+ 0 & 0 & 0 & 0 & 4 & 4\cr
+ 1 & 1 & 1 & 1 & 1 & 1}
+ \right]
+ = \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{1 & -1 & -1 & 1 & 1 & -1\cr
+ 0 & 0 & 0 & 0 & 4 & 4\cr
+ 0 & 0 & 2 & 2 & 0 & 0\cr
+ 1 & 1 & 1 & 1 & 1 & 1}
+ \right]\eqno(1.53)$$
+
+It can be seen that the object described bears the same fixed
+relationship to its coordinate frame, whose position and orientation
+are described by the transformation. Given an object described by a
+reference coordinate frame, and a transformation representing the
+position and orientation of the object's axes, the object can be
+simply reconstructed, without the necessity of transforming all the
+points, by noting the direction and orientation of key features with
+respect to the describing frame's coordinate axes. By drawing the
+transformed coordinate frame, the object can be related to the new
+axis directions.
+
+\section{Inverse Transformations}
+
+\noindent
+We are now in a position to develop the inverse transformation as the
+transform which carries the transformed coordinate frame back to the
+original frame. This is simply the description of the reference
+coordinate frame with respect to the transformed frame. Suppose the
+direction of the reference frame $x$ axis is $[0,0,1,0]^{\rm T}$ with
+respect to the transformed frame. The $y$ and $z$ axes are
+$[1,0,0,0]^{\rm T}$ and $[0,1,0,0]^{\rm T}$, respectively. The
+location of the origin is $[0,0,-4,1]^{\rm T}$ with respect to the
+transformed frame and thus the inverse transformation is
+
+$${\bf T^{-1}} = \left[\matrix{0 & 1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & -4\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.54)$$
+
+\noindent
+That this is indeed the tranform inverse is easily verifyed by
+multiplying it by the transform {\bf T} to obtain the identity
+transform
+
+$$\left[\matrix{1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ = \left[\matrix{0 & 1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & -4\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{0 & 0 & 1 & 4\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.55)$$
+
+\noindent
+In general, given a transform with elements
+
+$${\bf T} = \left[\matrix{n_x & o_x & a_x & p_x\cr
+ n_y & o_y & a_y & p_y\cr
+ n_z & o_z & a_z & p_z\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.56)$$
+
+\noindent
+then the inverse is
+
+$${\bf T^{-1}} = \left[\matrix{n_x & n_y & n_z & -{\bf p} \cdot {\bf n}\cr
+ o_x & o_y & o_z & -{\bf p} \cdot {\bf o}\cr
+ a_x & a_y & a_z & -{\bf p} \cdot {\bf a}\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.57)$$
+
+\noindent
+where {\bf p}, {\bf n}, {\bf o}, and {\bf a} are the four column
+vectors and ``$\cdot$'' represents the vector dot product. This result
+is easily verified by postmultiplying Equation 1.56 by Equation 1.57.
+
+\section{General Rotation Transformation}
+
+\noindent
+We state the rotation transformations for rotations about the $x$,
+$y$, and $z$ axes (Equations 1.32, 1.33 and 1.34). These
+transformations have a simple geometric interpretation. For example,
+in the case of a rotation about the $z$ axis, the column representing
+the $z$ axis will remain constant, while the column elements
+representing the $x$ and $y$ axes will vary.
+
+\noindent
+We will now develop the transformation matrix representing a rotation
+around an arbitrary vector {\bf k} located at the origin. In order to
+do this we will imagine that {\bf k} is the $z$ axis unit vector of a
+coordinate frame {\bf C}
+
+$${\bf C} = \left[\matrix{n_x & o_x & a_x & p_x\cr
+ n_y & o_y & a_y & p_y\cr
+ n_z & o_z & a_z & p_z\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.58)$$
+
+$${\bf k} = a_x{\bf i} + a_y{\bf j} + a_z{\bf k}\eqno(1.59)$$
+
+\noindent
+Rotating around the vector {\bf k} is then equivalent to rotating
+around the $z$ axis of the frame {\bf C}.
+
+$${\bf Rot(k,\theta)} = {\bf Rot(^C{\bf z},\theta)}\eqno(1.60)$$
+
+\noindent
+If we are given a frame {\bf T} described with respect to the
+reference coordinate frame, we can find a frame {\bf X} which
+describes the same frame with respect to frame {\bf C} as
+
+$${\bf T} = {\bf C} {\bf X}\eqno(1.61)$$
+
+\noindent
+where {\bf X} describes the position of {\bf T} with respect to frame
+{\bf C}. Solving for {\bf X} we obtain
+
+$${\bf X} = {\bf C^{-1}} {\bf T}\eqno(1.62)$$
+
+\noindent
+Rotation {\bf T} around {\bf k} is equivalent to rotating {\bf X}
+around the $z$ axis of frame {\bf C}
+
+$${\bf Rot(k,\theta)} {\bf T}
+ = {\bf C} {\bf Rot(z,\theta)} {\bf X}\eqno(1.63)$$
+
+$${\bf Rot(k,\theta)} {\bf T}
+ = {\bf C} {\bf Rot(z,\theta)} {\bf C^{-1}} {\bf T}.\eqno(1.64)$$
+
+\noindent
+Thus
+
+$${\bf Rot(k,\theta)}
+ = {\bf C} {\bf Rot(z,\theta)} {\bf C^{-1}}\eqno(1.65)$$
+
+\noindent
+However, we have only {\bf k}, the $z$ axis of the frame {\bf C}. By
+expanding equation 1.65 we will discover that
+${\bf C} {\bf Rot(z,\theta)} {\bf C^{-1}}$ is a function of {\bf k}
+only.
+
+Multiplying ${\bf Rot(z,\theta)}$ on the right by ${\bf C^{-1}}$ we
+obtain
+
+$${\bf Rot(z,\theta)} {\bf C^{-1}}
+ = \left[\matrix{cos \theta & -sin \theta & 0 & 0\cr
+ sin \theta & cos \theta & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{n_x & n_y & n_z & 0\cr
+ o_x & o_x & o_z & 0\cr
+ a_x & a_y & a_z & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]$$
+
+$$ = \left[\matrix{n_x cos \theta - o_x sin \theta &
+ n_y cos \theta - o_y sin \theta &
+ n_z cos \theta - o_z sin \theta & 0\cr
+ n_x sin \theta + o_x cos \theta &
+ n_y sin \theta + o_y cos \theta &
+ n_z sin \theta + o_z cos \theta & 0\cr
+ a_x & a_y & a_z & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.66)$$
+
+\noindent
+premultiplying by
+
+$${\bf C} = \left[\matrix{n_x & o_x & a_x & 0\cr
+ n_y & o_y & a_y & 0\cr
+ n_z & o_z & a_z & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.67)$$
+
+\noindent
+we obtain ${\bf C} {\bf Rot(z,\theta)} {\bf C^{-1}}$
+
+$$\left[\matrix{
+n_x n_x cos \theta - n_x o_x sin \theta + n_x o_x sin \theta + o_x o_x
+cos \theta + a_x a_x\cr
+n_y n_x cos \theta - n_y o_x sin \theta + n_x o_y sin \theta + o_x o_y
+cos \theta + a_y a_x\cr
+n_z n_x cos \theta - n_z o_x sin \theta + n_x o_z sin \theta + o_x o_z
+cos \theta + a_z a_x\cr
+0}
+\right.$$
+
+$$\matrix{
+n_x n_y cos \theta - n_x o_y sin \theta + n_y o_x sin \theta + o_y o_x
+cos \theta + a_x a_y\cr
+n_y n_y cos \theta - n_y o_y sin \theta + n_y o_y sin \theta + o_y o_y
+cos \theta + a_y a_y\cr
+n_z n_y cos \theta - n_z o_y sin \theta + n_y o_z sin \theta + o_y o_z
+cos \theta + a_z a_y\cr
+0}\eqno(1.68)$$
+
+$$\left.\matrix{
+n_x n_z cos \theta - n_x o_z sin \theta + n_z o_x sin \theta + o_z o_x
+cos \theta + a_x a_x & 0\cr
+n_y n_z cos \theta - n_y o_z sin \theta + n_z o_y sin \theta + o_z o_y
+cos \theta + a_y a_z & 0\cr
+n_z n_z cos \theta - n_z o_z sin \theta + n_z o_z sin \theta + o_z o_z
+cos \theta + a_z a_z & 0\cr
+0 & 1}
+\right]$$
+
+\noindent
+Simplifying, using the following relationships:\\
+the dot product of any row or column of {\bf C} with any other row or
+column is zero, as the vectors are orthogonal;\\
+the dot product of any row or column of {\bf C} with itself is {\bf 1}
+as the vectors are of unit magnitude;\\
+the $z$ unit vector is the vector cross product of the $x$ and $y$
+vectors or
+$${\bf a} = {\bf n} \times {\bf o}\eqno(1.69)$$
+
+\noindent
+which has components
+
+$$a_x = n_y o_z - n_z o_y$$
+$$a_y = n_z o_x - n_x o_z$$
+$$a_z = n_x o_y - n_y o_x$$
+
+\noindent
+the versine, abbreviated ${\bf vers \ \theta}$, is defined as
+${\bf vers \ \theta} = (1 - cos \ \theta)$,
+${k_x = a_x}$, ${k_y = a_y}$ and ${k_z = a_z}$.
+We obtain ${\bf Rot(k,\theta)} =$
+$$\left[\matrix{
+k_x k_x vers \theta + cos \theta &
+k_y k_x vers \theta - k_z sin \theta &
+k_z k_x vers \theta + k_y sin \theta &
+0\cr
+k_x k_y vers \theta + k_z sin \theta &
+k_y k_y vers \theta + cos \theta &
+k_z k_y vers \theta - k_x sin \theta &
+0\cr
+k_x k_z vers \theta - k_y sin \theta &
+k_y k_z vers \theta + k_x sin \theta &
+k_z k_z vers \theta + cos \theta &
+0\cr
+0 & 0 & 0 & 1}
+\right]\eqno(1.70)$$
+
+\noindent
+This is an important result and should be thoroughly understood before
+proceeding further.
+
+From this general rotation transformation we can obtain each of the
+elementary rotation transforms. For example ${\bf Rot(x,\theta)}$ is
+${\bf Rot(k,\theta)}$ where ${k_x = 1}$, ${k_y = 0}$, and
+${k_z = 0}$. Substituting these values of {\bf k} into Equation 1.70
+we obtain
+
+$${\bf Rot(x,\theta)} =
+\left[\matrix{1 & 0 & 0 & 0\cr
+ 0 & cos \theta & -sin \theta & 0\cr
+ 0 & sin \theta & cos \theta & 0\cr
+ 0 & 0 & 0 & 1}
+\right]\eqno(1.71)$$
+
+\noindent
+as before.
+
+\section{Equivalent Angle and Axis of Rotation}
+
+\noindent
+Given any arbitrary rotational transformation, we can use Equation
+1.70 to obtain an axis about which an equivalent rotation $\theta$ is
+made as follows. Given a rotational transformation {\bf R}
+
+$${\bf R} =
+\left[\matrix{n_x & o_x & a_x & 0\cr
+ n_y & o_y & a_y & 0\cr
+ n_z & o_z & a_z & 0\cr
+ 0 & 0 & 0 & 1}
+\right]\eqno(1.72)$$
+
+\noindent
+we may equate {\bf R} to {\bf Rot(k,$\theta$)}
+
+$$\left[\matrix{n_x & o_x & a_x & 0\cr
+ n_y & o_y & a_y & 0\cr
+ n_z & o_z & a_z & 0\cr
+ 0 & 0 & 0 & 1}
+ \right] = $$
+$$\left[\matrix{
+k_x k_x vers \theta + cos \theta &
+k_y k_x vers \theta - k_z sin \theta &
+k_z k_x vers \theta + k_y sin \theta &
+0\cr
+k_x k_y vers \theta + k_z sin \theta &
+k_y k_y vers \theta + cos \theta &
+k_z k_y vers \theta - k_x sin \theta &
+0\cr
+k_x k_z vers \theta - k_y sin \theta &
+k_y k_z vers \theta + k_x sin \theta &
+k_z k_z vers \theta + cos \theta &
+0\cr
+0 & 0 & 0 & 1}
+\right]\eqno(1.73)$$
+
+\noindent
+Summing the diagonal terms of Equation 1.73 we obtain
+
+$$n_x+o_y+a_z+1=
+k_x^2 vers \theta + cos \theta +
+k_y^2 vers \theta + cos \theta +
+k_z^2 vers \theta + cos \theta + 1\eqno(1.74)$$
+
+$$\left.\matrix{ n_x+o_y+a_z & = &
+ (k_x^2+k_y^2+k_z^2)vers \theta + 3 cos \theta\cr
+ & = & 1 + 2 cos \theta}
+ \right.\eqno(1.75)$$
+
+\noindent
+and the cosine of the angle of rotation is
+
+$$cos \theta = {1\over 2}(n_x+o_y+a_z-1)\eqno(1.76)$$
+
+\noindent
+Differencing pairs of off-diagonal terms in Equation 1.73 we obtain
+
+$$o_z - a_y = 2 k_x sin \theta\eqno(1.77)$$
+$$a_x - n_z = 2 k_y sin \theta\eqno(1.78)$$
+$$n_y - o_x = 2 k_z sin \theta\eqno(1.79)$$
+
+\noindent
+Squaring and adding Equations 1.77-1.79 we obtain an expression for
+$sin \theta$
+
+$$(o_z - a_y)^2 + (a_x - n_z)^2 + (n_y - o_x)^2
+ = 4 sin^2 \theta\eqno(1.80)$$
+
+\noindent
+and the sine of the angle of rotation is
+
+$$sin \ \theta =
+ \pm {1\over 2} \sqrt{(o_z - a_y)^2 + (a_x - n_z)^2 + (n_y - o_x)^2}
+ \eqno(1.81)$$
+
+\noindent
+We may define the rotation to be positive about the vector {\bf k}
+such that $0 \leq \theta \leq 180^\circ$. In this case the $+$ sign
+is appropriate in Equation 1.81 and thus the angle of rotation
+$\theta$ is uniquely defined as
+
+$$tan \ \theta =
+ {\sqrt{(o_z - a_y)^2 + (a_x - n_z)^2 + (n_y - o_x)^2}
+ \over
+ {(n_x + o_y + a_z -1)}}\eqno(1.82)$$
+
+\noindent
+The components of {\bf k} may be obtained from Equations 1.77-1.79 as
+
+$$k_x = {{o_z - a_y}\over{2 sin \theta}}\eqno(1.83)$$
+$$k_y = {{a_x - n_z}\over{2 sin \theta}}\eqno(1.84)$$
+$$k_z = {{n_y - o_x}\over{2 sin \theta}}\eqno(1.85)$$
+
+When the angle of rotation is very small, the axis of rotation is
+physically not well defined due to the small magnitude of both
+numerator and denominator in Equations 1.83-1.85. If the resulting
+angle is small, the vector {\bf k} should be renormalized to ensure
+that $\left|{\bf k}\right| = 1$. When the angle of rotation approaches
+$180^\circ$ the vector {\bf k} is once again poorly defined by
+Equation 1.83-1.85 as the magnitude of the sine is again
+decreasing. The axis of rotation is, however, physically well defined
+in this case. When $\theta < 150^\circ$, the denominator of
+Equations 1.83-1.85 is less than 1. As the angle increases to
+$180^\circ$ the rapidly decreasing magnitude of both numerator and
+denominator leads to considerable inaccuracies in the determination of
+{\bf k}. At $\theta = 180^\circ$, Equations 1.83-1.85 are of the form
+$0/0$, yielding no information at all about a physically well defined
+vector {\bf k}. If the angle of rotation is greater than $90^\circ$,
+then we must follow a different approach in determining {\bf
+k}. Equating the diagonal elements of Equation 1.73 we obtain
+
+$$k_x^2 vers \theta + cos \theta = n_x\eqno(1.86)$$
+$$k_y^2 vers \theta + cos \theta = o_y\eqno(1.87)$$
+$$k_z^2 vers \theta + cos \theta = a_z\eqno(1.88)$$
+
+Substituting for $cos \theta$ and $vers \theta$ from Equation 1.76 and
+solving for the elements of {\bf k} we obtain further
+
+$$k_x =
+ \pm \sqrt{{{n_x - cos \theta}\over{1 - cos \theta}}}\eqno(1.89)$$
+$$k_y =
+ \pm \sqrt{{{o_y - cos \theta}\over{1 - cos \theta}}}\eqno(1.90)$$
+$$k_z =
+ \pm \sqrt{{{a_z - cos \theta}\over{1 - cos \theta}}}\eqno(1.91)$$
+
+\noindent
+The largest component of {\bf k} defined by Equations 1.89-1.91
+corresponds to the most positive component of $n_x$, $o_y$, and
+$a_z$. For this largest element, the sign of the radical can be
+obtained from Equations 1.77-1.79. As the sine of the angle of
+rotation $\theta$ must be positive, then the sign of the component of
+{\bf k} defined by Equations 1.77-1.79 must be the same as the sign of
+the left hand side of these equations. Thus we may combine Equations
+1.89-1.91 with the information contained in Equations 1.77-1.79 as
+follows
+
+$$k_x = sgn(o_z-a_y)\sqrt{{{(n_x-cos \theta)}
+ \over
+ {1-cos \theta}}}\eqno(1.92)$$
+
+$$k_y = sgn(a_x-n_z)\sqrt{{{(o_y-cos \theta)}
+ \over
+ {1-cos \theta}}}\eqno(1.93)$$
+
+$$k_z = sgn(n_y-o_x)\sqrt{{{(a_z-cos \theta)}
+ \over
+ {1-cos \theta}}}\eqno(1.94)$$
+
+\noindent
+where $sgn(e) = +1$ if $e \ge 0$ and $sgn(e) = -1$ if $e \le 0$.
+
+Only the largest element of {\bf k} is determined from Equations
+1.92-1.94, corresponding to the most positive element of $n_x$, $o_y$,
+and $a_z$. The remaining elements are more accurately determined by
+the following equations formed by summing pairs of off-diagonal
+elements of Equation 1.73
+
+$$n_y + o_x = 2 k_x k_y vers \theta\eqno(1.95)$$
+$$o_z + a_y = 2 k_y k_z vers \theta\eqno(1.96)$$
+$$n_z + a_x = 2 k_z k_x vers \theta\eqno(1.97)$$
+
+\noindent
+If $k_x$ is largest then
+
+$$k_y = {{n_y + o_x}\over{2 k_x vers \theta}}
+ {\rm \ \ \ \ \ from \ Equation \ 1.95}\eqno(1.98)$$
+
+$$k_z = {{a_x + n_z}\over{2 k_x vers \theta}}
+ {\rm \ \ \ \ \ from \ Equation \ 1.97}\eqno(1.99)$$
+
+\noindent
+If $k_y$ is largest then
+
+$$k_x = {{n_y + o_x}\over{2 k_y vers \theta}}
+ {\rm \ \ \ \ \ from \ Equation \ 1.95}\eqno(1.100)$$
+
+$$k_z = {{o_z + a_y}\over{2 k_y vers \theta}}
+ {\rm \ \ \ \ \ from \ Equation \ 1.96}\eqno(1.101)$$
+
+\noindent
+If $k_z$ is largest then
+
+$$k_x = {{a_x + n_z}\over{2 k_z vers \theta}}
+ {\rm \ \ \ \ \ from \ Equation \ 1.97}\eqno(1.102)$$
+
+$$k_y = {{o_z + a_y}\over{2 k_z vers \theta}}
+ {\rm \ \ \ \ \ from \ Equation \ 1.96}\eqno(1.103)$$
+
+\section{Example 1.1}
+
+\noindent
+Determine the equivalent axis and angle of rotation for the matrix
+given in Equations 1.41
+
+$${\bf Rot(y,90)}{\bf Rot(z,90)}
+ = \left[\matrix{0 & 0 & 1 & 0\cr
+ 1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.104)$$
+
+\noindent
+We first determine ${\bf cos \ \theta}$ from Equation 1.76
+
+$$cos \theta = {{1}\over{2}}(0 + 0 + 0 - 1)
+ = -{{1}\over{2}}\eqno(1.105)$$
+
+\noindent
+and $sin \ \theta$ from Equation 1.81
+
+$$sin \theta = {{1}\over{2}}\sqrt{(1-0)^2+(1-0)^2+(1-0)^2}
+ = {{\sqrt3}\over{2}}\eqno(1.106)$$
+
+\noindent
+Thus
+
+$$\theta = tan^{-1}\left({{\sqrt3}\over{2}}
+ \raise15pt\hbox{$\bigslash$}
+ {{-1}\over{2}}\right)
+ = 120^\circ\eqno(1.107)$$
+
+\noindent
+As $\theta > 90$, we determine the largest component of {\bf k}
+corresponding to the largest element on the diagonal. As all diagonal
+elements are equal in this example we may pick any one. We will pick
+$k_x$ given by Equation 1.92
+
+$$k_x = +\sqrt{(0 + {{1}\over{2}})
+ \raise15pt\hbox{$\bigslash$}
+ (1 + {{1}\over{2}})}
+ = {{1}\over{\sqrt{3}}}\eqno(1.108)$$
+
+\noindent
+As we have determined $k_x$ we may now determine $k_y$ and $k_z$ from
+Equations 1.98 and 1.99, respectively
+
+$$k_y = {{1+0}\over{\sqrt{3}}} = {{1}\over{\sqrt{3}}}\eqno(1.109)$$
+
+$$k_z = {{1+0}\over{\sqrt{3}}} = {{1}\over{\sqrt{3}}}\eqno(1.110)$$
+
+\noindent
+In summary, then
+
+$${\bf Rot(y,90)}{\bf Rot(z,90)} = {\bf Rot(k,120)}\eqno(1.111)$$
+
+\noindent
+where
+
+$${\bf k} = {{1}\over{\sqrt{3}}} {\bf i}
+ + {{1}\over{\sqrt{3}}} {\bf j}
+ + {{1}\over{\sqrt{3}}} {\bf k}\eqno(1.112)$$
+
+Any combination of rotations is always equivalent to a single rotation
+about some axis {\bf k} by an angle $\theta$, an important result
+that we will make use of later.
+
+\section{Stretching and Scaling}
+
+A transform {\bf T}
+
+$${\bf T} = \left[\matrix{a & 0 & 0 & 0\cr
+ 0 & b & 0 & 0\cr
+ 0 & 0 & c & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.113)$$
+
+\noindent
+will stretch objects uniformly along the $x$ axis by a factor $a$,
+along the $y$ axis by a factor $b$, and along the $z$ axis by a factor
+$c$. Consider any point on an object $x{\bf i}+y{\bf j}+z{\bf k}$; its
+tranform is
+
+$$\left[\matrix{ax\cr
+ by\cr
+ cz\cr
+ 1}
+ \right]
+ = \left[\matrix{a & 0 & 0 & 0\cr
+ 0 & b & 0 & 0\cr
+ 0 & 0 & c & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]
+ \left[\matrix{x\cr
+ y\cr
+ z\cr
+ 1}
+ \right]\eqno(1.114)$$
+
+\noindent
+indicating stretching as stated. Thus a cube could be transformed into
+a rectangular parallelepiped by such a transform.
+
+The Axiom code to perform this scale change is:
+
+<<scale>>=
+ scale(scalex, scaley, scalez) ==
+ matrix(_
+ [[scalex, 0 ,0 , 0], _
+ [0 , scaley ,0 , 0], _
+ [0 , 0, scalez, 0], _
+ [0 , 0, 0 , 1]])
+@
+\noindent
+The transform {\bf S} where
+
+$${\bf S} = \left[\matrix{s & 0 & 0 & 0\cr
+ 0 & s & 0 & 0\cr
+ 0 & 0 & s & 0\cr
+ 0 & 0 & 0 & 1}
+ \right]\eqno(1.115)$$
+
+\noindent
+will scale any object by the factor $s$.
+
+\section{Perspective Transformations}
+
+\noindent
+Consider the image formed of an object by a simple lens.
+
+The axis of the lens is along the $y$ axis for convenience. An object
+point $x$,$y$,$z$ is imaged at $x^\prime$,$y^\prime$,$z^\prime$ if the
+lens has a focal length $f$ ($f$ is considered positive). $y^\prime$
+represents the image distance and varies with object distance $y$. If
+we plot points on a plane perpendicular to the $y$ axis located at
+$y^\prime$ (the film plane in a camera), then a perspective image is
+formed.
+
+We will first obtain values of $x^\prime$, $y^\prime$, and $z^\prime$,
+then introduce a perspective transformation and show that the same
+values are obtained.
+
+Based on the fact that a ray passing through the center of the lens is
+undeviated we may write
+
+$${\rm \ \ \ \ \ }{{z}\over{y}} = {{z^\prime}\over{y^\prime}}\eqno(1.116)$$
+
+$${\rm and\ } {{x}\over{y}} = {{x^\prime}\over{y^\prime}}\eqno(1.117)$$
+
+Based on the additional fact that a ray parallel to the lens axis
+passes through the focal point $f$, we may write
+
+$${\rm \ \ \ \ \ }{{z}\over{f}}
+ = {{z^\prime}\over{y^\prime + f}}\eqno(1.118)$$
+
+$${\rm and\ } {{x}\over{f}}
+ = {{x^\prime}\over{y^\prime + f}}\eqno(1.119)$$
+
+\noindent
+Notice that $x^\prime$, $y^\prime$, and $z^\prime$ are negative and
+that $f$ is positive. Eliminating $y^\prime$ between Equations 1.116
+and 1.118 we obtain
+
+$${{z}\over{f}}
+ = {{z^\prime}\over{({{z^\prime y}\over{z}} + f)}}\eqno(1.120)$$
+
+\noindent
+and solving for $z^\prime$ we obtain the result
+
+$$z^\prime = {{z}\over{(1 - {{y}\over{f}})}}\eqno(1.121)$$
+
+\noindent
+Working with Equations 1.117 and 1.119 we can similarly obtain
+
+$$x^\prime = {{x}\over{(1 - {{y}\over{f}})}}\eqno(1.122)$$
+
+\noindent
+In order to obtain the image distance $y^\prime$ we rewrite Equations
+1.116 and 1.118 as
+
+$${{z}\over{z^\prime}} = {{y}\over{y^\prime}}\eqno(1.123)$$
+
+\noindent
+and
+
+$${{z}\over{z^\prime}} = {{f}\over{y^\prime + f}}\eqno(1.124)$$
+
+\noindent
+thus
+
+$${{y}\over{y^\prime}} = {{f}\over{y^\prime + f}}\eqno(1.125)$$
+
+\noindent
+and solving for $y^\prime$ we obtain the result
+
+$$y^\prime = {{y}\over{(1-{{y}\over{f}})}}\eqno(1.126)$$
+
+The homogeneous transformation {\bf P} which produces the same result
+is
+
+$${\bf P} = \left[\matrix{1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & -{{1}\over{f}} & 0 & 1}
+ \right]\eqno(1.127)$$
+
+\noindent
+as any point $x{\bf i}+y{\bf j}+z{\bf k}$ transforms as
+
+$$\left[\matrix{x\cr
+ y\cr
+ z\cr
+ {1 - {{{y}\over{f}}}}}
+ \right]
+ = \left[\matrix{1 & 0 & 0 & 0\cr
+ 0 & 1 & 0 & 0\cr
+ 0 & 0 & 1 & 0\cr
+ 0 & -{{1}\over{f}} & 0 & 1}
+ \right]
+ \left[\matrix{x\cr
+ y\cr
+ z\cr
+ 1}
+ \right]\eqno(1.128)$$
+
+\noindent
+The image point $x^\prime$, $y^\prime$,, $z^\prime$, obtained by
+dividing through by the weight factor $(1 - {{y}\over{f}})$, is
+
+$${{x}\over{(1 - {{y}\over{f}})}}{\bf i} +
+ {{y}\over{(1 - {{y}\over{f}})}}{\bf j} +
+ {{z}\over{(1 - {{y}\over{f}})}}{\bf k} \eqno(1.129)$$
+
+\noindent
+This is the same result that we obtained above.
+
+A transform similar to {\bf P} but with $-{{1}\over{f}}$ at the bottom
+of the first column produces a perspective transformation along the
+$x$ axis. If the $-{{1}\over{f}}$ term is in the third column then the
+projection is along the $z$ axis.
+
+\section{Transform Equations}
+
+\noindent We will frequently be required to deal with transform
+equations in which a coordinate frame is described in two or more
+ways. A manipulator is positioned with respect to base coordinates by
+a transform {\bf Z}. The end of the manipulator is described by a
+transform $^Z{\bf T}_6$, and the end effector is described by
+$^{T_6}{\bf E}$. An object is positioned with respect to base
+coordinates by a transform {\bf B}, and finally the manipulator end
+effector is positioned with respect to the object by $^B{\bf G}$. We
+have two descriptions of the position of the end effector, one with
+respect to the object and one with respect to the manipulator. As both
+positions are the same, we may equate the two descriptions
+
+$${\bf Z}{^Z{\bf T}_6}{^{T_6}{\bf E}}
+ = {\bf B}{^B{\bf G}}\eqno(1.130)$$
+
+If we wish to solve Equation 1.130 for the manipulator transform
+${\bf T}_6$ we must premultiply Equation 1.130 by ${\bf Z}^{-1}$ and
+postmultiply by ${\bf E}^{-1}$ to obtain
+
+$${\bf T}_6
+ = {{\bf Z}^{-1}} {\bf B} {\bf G} {{\bf E}^{-1}}\eqno(1.131)$$
+
+\noindent
+As a further example, consider that the position of the object {\bf B}
+is unknown, but that the manipulator is moved such that the end
+effector is positioned over the object correctly. We may then solve
+for {\bf B} from Equation 1.130 by postmultiplying by ${\bf G}^{-1}$.
+
+$${\bf B} = {\bf Z}{{\bf T}_6}{\bf E}{{\bf G}^{-1}}\eqno(1.133)$$
+
+\section{Summary}
+
+\noindent
+Homogeneous transformations may be readily used to describe the
+positions and orientations of coordinate frames in space. If a
+coordinate frame is embedded in an object then the position and
+orientation of the object are also readily described.
+
+The description of object A in terms of object B by means of a
+homogeneous transformation may be inverted to obtain the description
+of object B in terms of object A. This is not a property of a simple
+vector description of the relative displacement of one object with
+respect to another.
+
+Transformations may be interpreted as a product of rotation and
+translation transformations. If they are intrepreted from left to
+right, then the rotations and translations are in terms of the
+currently defined coordinate frame. If they are interpreted from right
+to left, then the rotations and translations are described with
+respect to the reference coordinate frame.
+
+Homogeneous transformations describe coordinate frames in terms of
+rectangular components, which are the sines and cosines of
+angles. This description may be related to rotations in which case the
+description is in terms of a vector and angle of rotation.
+
+\section{Denavit-Hartenberg Matrices}
+<<domain DHMATRIX DenavitHartenbergMatrix>>=
+--Copyright The Numerical Algorithms Group Limited 1991.
+
+++ 4x4 Matrices for coordinate transformations
+++ Author: Timothy Daly
+++ Date Created: June 26, 1991
+++ Date Last Updated: 26 June 1991
+++ Description:
+++ This package contains functions to create 4x4 matrices
+++ useful for rotating and transforming coordinate systems.
+++ These matrices are useful for graphics and robotics.
+++ (Reference: Robot Manipulators Richard Paul MIT Press 1981)
+
+
+)abbrev domain DHMATRIX DenavitHartenbergMatrix
+
+--% DHMatrix
+
+DenavitHartenbergMatrix(R): Exports == Implementation where
+ ++ A Denavit-Hartenberg Matrix is a 4x4 Matrix of the form:
+ ++ \spad{nx ox ax px}
+ ++ \spad{ny oy ay py}
+ ++ \spad{nz oz az pz}
+ ++ \spad{0 0 0 1}
+ ++ (n, o, and a are the direction cosines)
+ R : Join(Field, TranscendentalFunctionCategory)
+
+-- for the implementation of dhmatrix
+ minrow ==> 1
+ mincolumn ==> 1
+--
+ nx ==> x(1,1)::R
+ ny ==> x(2,1)::R
+ nz ==> x(3,1)::R
+ ox ==> x(1,2)::R
+ oy ==> x(2,2)::R
+ oz ==> x(3,2)::R
+ ax ==> x(1,3)::R
+ ay ==> x(2,3)::R
+ az ==> x(3,3)::R
+ px ==> x(1,4)::R
+ py ==> x(2,4)::R
+ pz ==> x(3,4)::R
+ row ==> Vector(R)
+ col ==> Vector(R)
+ radians ==> pi()/180
+
+ Exports ==> MatrixCategory(R,row,col) with
+ "*": (%, Point R) -> Point R
+ ++ t*p applies the dhmatrix t to point p
+ identity: () -> %
+ ++ identity() create the identity dhmatrix
+ rotatex: R -> %
+ ++ rotatex(r) returns a dhmatrix for rotation about axis X for r degrees
+ rotatey: R -> %
+ ++ rotatey(r) returns a dhmatrix for rotation about axis Y for r degrees
+ rotatez: R -> %
+ ++ rotatez(r) returns a dhmatrix for rotation about axis Z for r degrees
+ scale: (R,R,R) -> %
+ ++ scale(sx,sy,sz) returns a dhmatrix for scaling in the X, Y and Z
+ ++ directions
+ translate: (R,R,R) -> %
+ ++ translate(X,Y,Z) returns a dhmatrix for translation by X, Y, and Z
+
+ Implementation ==> Matrix(R) add
+
+ identity() == matrix([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]])
+
+-- inverse(x) == (inverse(x pretend (Matrix R))$Matrix(R)) pretend %
+-- dhinverse(x) == matrix( _
+-- [[nx,ny,nz,-(px*nx+py*ny+pz*nz)],_
+-- [ox,oy,oz,-(px*ox+py*oy+pz*oz)],_
+-- [ax,ay,az,-(px*ax+py*ay+pz*az)],_
+-- [ 0, 0, 0, 1]])
+
+ d * p ==
+ v := p pretend Vector R
+ v := concat(v, 1$R)
+ v := d * v
+ point ([v.1, v.2, v.3]$List(R))
+
+<<rotatex>>
+
+<<rotatey>>
+
+<<rotatez>>
+
+<<scale>>
+
+<<translate>>
+
+@
+\section{License}
+<<license>>=
+--Portions Copyright (c) Richard Paul
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain DHMATRIX DenavitHartenbergMatrix>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} Paul, Richard,
+{\sl Robot Manipulators},
+MIT Press, Cambridge, Mass.,
+(1981)
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/divisor.spad.pamphlet b/src/algebra/divisor.spad.pamphlet
new file mode 100644
index 00000000..1d402c7b
--- /dev/null
+++ b/src/algebra/divisor.spad.pamphlet
@@ -0,0 +1,1009 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra divisor.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FRIDEAL FractionalIdeal}
+<<domain FRIDEAL FractionalIdeal>>=
+)abbrev domain FRIDEAL FractionalIdeal
+++ Author: Manuel Bronstein
+++ Date Created: 27 Jan 1989
+++ Date Last Updated: 30 July 1993
+++ Keywords: ideal, algebra, module.
+++ Examples: )r FRIDEAL INPUT
+++ Description: Fractional ideals in a framed algebra.
+FractionalIdeal(R, F, UP, A): Exports == Implementation where
+ R : EuclideanDomain
+ F : QuotientFieldCategory R
+ UP: UnivariatePolynomialCategory F
+ A : Join(FramedAlgebra(F, UP), RetractableTo F)
+
+ VF ==> Vector F
+ VA ==> Vector A
+ UPA ==> SparseUnivariatePolynomial A
+ QF ==> Fraction UP
+
+ Exports ==> Group with
+ ideal : VA -> %
+ ++ ideal([f1,...,fn]) returns the ideal \spad{(f1,...,fn)}.
+ basis : % -> VA
+ ++ basis((f1,...,fn)) returns the vector \spad{[f1,...,fn]}.
+ norm : % -> F
+ ++ norm(I) returns the norm of the ideal I.
+ numer : % -> VA
+ ++ numer(1/d * (f1,...,fn)) = the vector \spad{[f1,...,fn]}.
+ denom : % -> R
+ ++ denom(1/d * (f1,...,fn)) returns d.
+ minimize: % -> %
+ ++ minimize(I) returns a reduced set of generators for \spad{I}.
+ randomLC: (NonNegativeInteger, VA) -> A
+ ++ randomLC(n,x) should be local but conditional.
+
+ Implementation ==> add
+ import CommonDenominator(R, F, VF)
+ import MatrixCommonDenominator(UP, QF)
+ import InnerCommonDenominator(R, F, List R, List F)
+ import MatrixCategoryFunctions2(F, Vector F, Vector F, Matrix F,
+ UP, Vector UP, Vector UP, Matrix UP)
+ import MatrixCategoryFunctions2(UP, Vector UP, Vector UP,
+ Matrix UP, F, Vector F, Vector F, Matrix F)
+ import MatrixCategoryFunctions2(UP, Vector UP, Vector UP,
+ Matrix UP, QF, Vector QF, Vector QF, Matrix QF)
+
+ Rep := Record(num:VA, den:R)
+
+ poly : % -> UPA
+ invrep : Matrix F -> A
+ upmat : (A, NonNegativeInteger) -> Matrix UP
+ summat : % -> Matrix UP
+ num2O : VA -> OutputForm
+ agcd : List A -> R
+ vgcd : VF -> R
+ mkIdeal : (VA, R) -> %
+ intIdeal: (List A, R) -> %
+ ret? : VA -> Boolean
+ tryRange: (NonNegativeInteger, VA, R, %) -> Union(%, "failed")
+
+ 1 == [[1]$VA, 1]
+ numer i == i.num
+ denom i == i.den
+ mkIdeal(v, d) == [v, d]
+ invrep m == represents(transpose(m) * coordinates(1$A))
+ upmat(x, i) == map(monomial(#1, i)$UP, regularRepresentation x)
+ ret? v == any?(retractIfCan(#1)@Union(F,"failed") case F, v)
+ x = y == denom(x) = denom(y) and numer(x) = numer(y)
+ agcd l == reduce("gcd", [vgcd coordinates a for a in l]$List(R), 0)
+
+ norm i ==
+ ("gcd"/[retract(u)@R for u in coefficients determinant summat i])
+ / denom(i) ** rank()$A
+
+ tryRange(range, nm, nrm, i) ==
+ for j in 0..10 repeat
+ a := randomLC(10 * range, nm)
+ unit? gcd((retract(norm a)@R exquo nrm)::R, nrm) =>
+ return intIdeal([nrm::F::A, a], denom i)
+ "failed"
+
+ summat i ==
+ m := minIndex(v := numer i)
+ reduce("+",
+ [upmat(qelt(v, j + m), j) for j in 0..#v-1]$List(Matrix UP))
+
+ inv i ==
+ m := inverse(map(#1::QF, summat i))::Matrix(QF)
+ cd := splitDenominator(denom(i)::F::UP::QF * m)
+ cd2 := splitDenominator coefficients(cd.den)
+ invd:= cd2.den / reduce("gcd", cd2.num)
+ d := reduce("max", [degree p for p in parts(cd.num)])
+ ideal
+ [invd * invrep map(coefficient(#1, j), cd.num) for j in 0..d]$VA
+
+ ideal v ==
+ d := reduce("lcm", [commonDenominator coordinates qelt(v, i)
+ for i in minIndex v .. maxIndex v]$List(R))
+ intIdeal([d::F * qelt(v, i) for i in minIndex v .. maxIndex v], d)
+
+ intIdeal(l, d) ==
+ lr := empty()$List(R)
+ nr := empty()$List(A)
+ for x in removeDuplicates l repeat
+ if (u := retractIfCan(x)@Union(F, "failed")) case F
+ then lr := concat(retract(u::F)@R, lr)
+ else nr := concat(x, nr)
+ r := reduce("gcd", lr, 0)
+ g := agcd nr
+ a := (r quo (b := gcd(gcd(d, r), g)))::F::A
+ d := d quo b
+ r ^= 0 and ((g exquo r) case R) => mkIdeal([a], d)
+ invb := inv(b::F)
+ va:VA := [invb * m for m in nr]
+ zero? a => mkIdeal(va, d)
+ mkIdeal(concat(a, va), d)
+
+ vgcd v ==
+ reduce("gcd",
+ [retract(v.i)@R for i in minIndex v .. maxIndex v]$List(R))
+
+ poly i ==
+ m := minIndex(v := numer i)
+ +/[monomial(qelt(v, i + m), i) for i in 0..#v-1]
+
+ i1 * i2 ==
+ intIdeal(coefficients(poly i1 * poly i2), denom i1 * denom i2)
+
+ i:$ ** m:Integer ==
+ m < 0 => inv(i) ** (-m)
+ n := m::NonNegativeInteger
+ v := numer i
+ intIdeal([qelt(v, j) ** n for j in minIndex v .. maxIndex v],
+ denom(i) ** n)
+
+ num2O v ==
+ paren [qelt(v, i)::OutputForm
+ for i in minIndex v .. maxIndex v]$List(OutputForm)
+
+ basis i ==
+ v := numer i
+ d := inv(denom(i)::F)
+ [d * qelt(v, j) for j in minIndex v .. maxIndex v]
+
+ coerce(i:$):OutputForm ==
+ nm := num2O numer i
+-- one? denom i => nm
+ (denom i = 1) => nm
+ (1::Integer::OutputForm) / (denom(i)::OutputForm) * nm
+
+ if F has Finite then
+ randomLC(m, v) ==
+ +/[random()$F * qelt(v, j) for j in minIndex v .. maxIndex v]
+ else
+ randomLC(m, v) ==
+ +/[(random()$Integer rem m::Integer) * qelt(v, j)
+ for j in minIndex v .. maxIndex v]
+
+ minimize i ==
+ n := (#(nm := numer i))
+-- one?(n) or (n < 3 and ret? nm) => i
+ (n = 1) or (n < 3 and ret? nm) => i
+ nrm := retract(norm mkIdeal(nm, 1))@R
+ for range in 1..5 repeat
+ (u := tryRange(range, nm, nrm, i)) case $ => return(u::$)
+ i
+
+@
+\section{package FRIDEAL2 FractionalIdealFunctions2}
+<<package FRIDEAL2 FractionalIdealFunctions2>>=
+)abbrev package FRIDEAL2 FractionalIdealFunctions2
+++ Lifting of morphisms to fractional ideals.
+++ Author: Manuel Bronstein
+++ Date Created: 1 Feb 1989
+++ Date Last Updated: 27 Feb 1990
+++ Keywords: ideal, algebra, module.
+FractionalIdealFunctions2(R1, F1, U1, A1, R2, F2, U2, A2):
+ Exports == Implementation where
+ R1, R2: EuclideanDomain
+ F1: QuotientFieldCategory R1
+ U1: UnivariatePolynomialCategory F1
+ A1: Join(FramedAlgebra(F1, U1), RetractableTo F1)
+ F2: QuotientFieldCategory R2
+ U2: UnivariatePolynomialCategory F2
+ A2: Join(FramedAlgebra(F2, U2), RetractableTo F2)
+
+ Exports ==> with
+ map: (R1 -> R2, FractionalIdeal(R1, F1, U1, A1)) ->
+ FractionalIdeal(R2, F2, U2, A2)
+ ++ map(f,i) \undocumented{}
+
+ Implementation ==> add
+ fmap: (F1 -> F2, A1) -> A2
+
+ fmap(f, a) ==
+ v := coordinates a
+ represents
+ [f qelt(v, i) for i in minIndex v .. maxIndex v]$Vector(F2)
+
+ map(f, i) ==
+ b := basis i
+ ideal [fmap(f(numer #1) / f(denom #1), qelt(b, j))
+ for j in minIndex b .. maxIndex b]$Vector(A2)
+
+@
+\section{package MHROWRED ModularHermitianRowReduction}
+<<package MHROWRED ModularHermitianRowReduction>>=
+)abbrev package MHROWRED ModularHermitianRowReduction
+++ Modular hermitian row reduction.
+++ Author: Manuel Bronstein
+++ Date Created: 22 February 1989
+++ Date Last Updated: 24 November 1993
+++ Keywords: matrix, reduction.
+-- should be moved into matrix whenever possible
+ModularHermitianRowReduction(R): Exports == Implementation where
+ R: EuclideanDomain
+
+ Z ==> Integer
+ V ==> Vector R
+ M ==> Matrix R
+ REC ==> Record(val:R, cl:Z, rw:Z)
+
+ Exports ==> with
+ rowEch : M -> M
+ ++ rowEch(m) computes a modular row-echelon form of m, finding
+ ++ an appropriate modulus.
+ rowEchelon : (M, R) -> M
+ ++ rowEchelon(m, d) computes a modular row-echelon form mod d of
+ ++ [d ]
+ ++ [ d ]
+ ++ [ . ]
+ ++ [ d]
+ ++ [ M ]
+ ++ where \spad{M = m mod d}.
+ rowEchLocal : (M, R) -> M
+ ++ rowEchLocal(m,p) computes a modular row-echelon form of m, finding
+ ++ an appropriate modulus over a local ring where p is the only prime.
+ rowEchelonLocal: (M, R, R) -> M
+ ++ rowEchelonLocal(m, d, p) computes the row-echelon form of m
+ ++ concatenated with d times the identity matrix
+ ++ over a local ring where p is the only prime.
+ normalizedDivide: (R, R) -> Record(quotient:R, remainder:R)
+ ++ normalizedDivide(n,d) returns a normalized quotient and
+ ++ remainder such that consistently unique representatives
+ ++ for the residue class are chosen, e.g. positive remainders
+
+
+
+ Implementation ==> add
+ order : (R, R) -> Z
+ vconc : (M, R) -> M
+ non0 : (V, Z) -> Union(REC, "failed")
+ nonzero?: V -> Boolean
+ mkMat : (M, List Z) -> M
+ diagSubMatrix: M -> Union(Record(val:R, mat:M), "failed")
+ determinantOfMinor: M -> R
+ enumerateBinomial: (List Z, Z, Z) -> List Z
+
+ nonzero? v == any?(#1 ^= 0, v)
+
+-- returns [a, i, rown] if v = [0,...,0,a,0,...,0]
+-- where a <> 0 and i is the index of a, "failed" otherwise.
+ non0(v, rown) ==
+ ans:REC
+ allZero:Boolean := true
+ for i in minIndex v .. maxIndex v repeat
+ if qelt(v, i) ^= 0 then
+ if allZero then
+ allZero := false
+ ans := [qelt(v, i), i, rown]
+ else return "failed"
+ allZero => "failed"
+ ans
+
+-- returns a matrix made from the non-zero rows of x whose row number
+-- is not in l
+ mkMat(x, l) ==
+ empty?(ll := [parts row(x, i)
+ for i in minRowIndex x .. maxRowIndex x |
+ (not member?(i, l)) and nonzero? row(x, i)]$List(List R)) =>
+ zero(1, ncols x)
+ matrix ll
+
+-- returns [m, d] where m = x with the zero rows and the rows of
+-- the diagonal of d removed, if x has a diagonal submatrix of d's,
+-- "failed" otherwise.
+ diagSubMatrix x ==
+ l := [u::REC for i in minRowIndex x .. maxRowIndex x |
+ (u := non0(row(x, i), i)) case REC]
+ for a in removeDuplicates([r.val for r in l]$List(R)) repeat
+ {[r.cl for r in l | r.val = a]$List(Z)}$Set(Z) =
+ {[z for z in minColIndex x .. maxColIndex x]$List(Z)}$Set(Z)
+ => return [a, mkMat(x, [r.rw for r in l | a = r.val])]
+ "failed"
+
+-- returns a non-zero determinant of a minor of x of rank equal to
+-- the number of columns of x, if there is one, 0 otherwise
+ determinantOfMinor x ==
+-- do not compute a modulus for square matrices, since this is as expensive
+-- as the Hermite reduction itself
+ (nr := nrows x) <= (nc := ncols x) => 0
+ lc := [i for i in minColIndex x .. maxColIndex x]$List(Integer)
+ lr := [i for i in minRowIndex x .. maxRowIndex x]$List(Integer)
+ for i in 1..(n := binomial(nr, nc)) repeat
+ (d := determinant x(enumerateBinomial(lr, nc, i), lc)) ^= 0 =>
+ j := i + 1 + (random()$Z rem (n - i))
+ return gcd(d, determinant x(enumerateBinomial(lr, nc, j), lc))
+ 0
+
+-- returns the i-th selection of m elements of l = (a1,...,an),
+-- /n\
+-- where 1 <= i <= | |
+-- \m/
+ enumerateBinomial(l, m, i) ==
+ m1 := minIndex l - 1
+ zero?(m := m - 1) => [l(m1 + i)]
+ for j in 1..(n := #l) repeat
+ i <= (b := binomial(n - j, m)) =>
+ return concat(l(m1 + j), enumerateBinomial(rest(l, j), m, i))
+ i := i - b
+ error "Should not happen"
+
+ rowEch x ==
+ (u := diagSubMatrix x) case "failed" =>
+ zero?(d := determinantOfMinor x) => rowEchelon x
+ rowEchelon(x, d)
+ rowEchelon(u.mat, u.val)
+
+ vconc(y, m) ==
+ vertConcat(diagonalMatrix new(ncols y, m)$V, map(#1 rem m, y))
+
+ order(m, p) ==
+ zero? m => -1
+ for i in 0.. repeat
+ (mm := m exquo p) case "failed" => return i
+ m := mm::R
+
+ if R has IntegerNumberSystem then
+ normalizedDivide(n:R, d:R):Record(quotient:R, remainder:R) ==
+ qr := divide(n, d)
+ qr.remainder >= 0 => qr
+ d > 0 =>
+ qr.remainder := qr.remainder + d
+ qr.quotient := qr.quotient - 1
+ qr
+ qr.remainder := qr.remainder - d
+ qr.quotient := qr.quotient + 1
+ qr
+ else
+ normalizedDivide(n:R, d:R):Record(quotient:R, remainder:R) ==
+ divide(n, d)
+
+ rowEchLocal(x,p) ==
+ (u := diagSubMatrix x) case "failed" =>
+ zero?(d := determinantOfMinor x) => rowEchelon x
+ rowEchelonLocal(x, d, p)
+ rowEchelonLocal(u.mat, u.val, p)
+
+ rowEchelonLocal(y, m, p) ==
+ m := p**(order(m,p)::NonNegativeInteger)
+ x := vconc(y, m)
+ nrows := maxRowIndex x
+ ncols := maxColIndex x
+ minr := i := minRowIndex x
+ for j in minColIndex x .. ncols repeat
+ if i > nrows then leave x
+ rown := minr - 1
+ pivord : Integer
+ npivord : Integer
+ for k in i .. nrows repeat
+ qelt(x,k,j) = 0 => "next k"
+ npivord := order(qelt(x,k,j),p)
+ (rown = minr - 1) or (npivord < pivord) =>
+ rown := k
+ pivord := npivord
+ rown = minr - 1 => "enuf"
+ x := swapRows_!(x, i, rown)
+ (a, b, d) := extendedEuclidean(qelt(x,i,j), m)
+ qsetelt_!(x,i,j,d)
+ pivot := d
+ for k in j+1 .. ncols repeat
+ qsetelt_!(x,i,k, a * qelt(x,i,k) rem m)
+ for k in i+1 .. nrows repeat
+ zero? qelt(x,k,j) => "next k"
+ q := (qelt(x,k,j) exquo pivot) :: R
+ for k1 in j+1 .. ncols repeat
+ v2 := (qelt(x,k,k1) - q * qelt(x,i,k1)) rem m
+ qsetelt_!(x, k, k1, v2)
+ qsetelt_!(x, k, j, 0)
+ for k in minr .. i-1 repeat
+ zero? qelt(x,k,j) => "enuf"
+ qr := normalizedDivide(qelt(x,k,j), pivot)
+ qsetelt_!(x,k,j, qr.remainder)
+ for k1 in j+1 .. ncols x repeat
+ qsetelt_!(x,k,k1,
+ (qelt(x,k,k1) - qr.quotient * qelt(x,i,k1)) rem m)
+ i := i+1
+ x
+
+ if R has Field then
+ rowEchelon(y, m) == rowEchelon vconc(y, m)
+
+ else
+
+ rowEchelon(y, m) ==
+ x := vconc(y, m)
+ nrows := maxRowIndex x
+ ncols := maxColIndex x
+ minr := i := minRowIndex x
+ for j in minColIndex x .. ncols repeat
+ if i > nrows then leave
+ rown := minr - 1
+ for k in i .. nrows repeat
+ if (qelt(x,k,j) ^= 0) and ((rown = minr - 1) or
+ sizeLess?(qelt(x,k,j), qelt(x,rown,j))) then rown := k
+ rown = minr - 1 => "next j"
+ x := swapRows_!(x, i, rown)
+ for k in i+1 .. nrows repeat
+ zero? qelt(x,k,j) => "next k"
+ (a, b, d) := extendedEuclidean(qelt(x,i,j), qelt(x,k,j))
+ (b1, a1) :=
+ ((qelt(x,i,j) exquo d)::R, (qelt(x,k,j) exquo d)::R)
+ -- a*b1+a1*b = 1
+ for k1 in j+1 .. ncols repeat
+ v1 := (a * qelt(x,i,k1) + b * qelt(x,k,k1)) rem m
+ v2 := (b1 * qelt(x,k,k1) - a1 * qelt(x,i,k1)) rem m
+ qsetelt_!(x, i, k1, v1)
+ qsetelt_!(x, k, k1, v2)
+ qsetelt_!(x, i, j, d)
+ qsetelt_!(x, k, j, 0)
+ un := unitNormal qelt(x,i,j)
+ qsetelt_!(x,i,j,un.canonical)
+ if un.associate ^= 1 then for jj in (j+1)..ncols repeat
+ qsetelt_!(x,i,jj,un.associate * qelt(x,i,jj))
+
+ xij := qelt(x,i,j)
+ for k in minr .. i-1 repeat
+ zero? qelt(x,k,j) => "next k"
+ qr := normalizedDivide(qelt(x,k,j), xij)
+ qsetelt_!(x,k,j, qr.remainder)
+ for k1 in j+1 .. ncols x repeat
+ qsetelt_!(x,k,k1,
+ (qelt(x,k,k1) - qr.quotient * qelt(x,i,k1)) rem m)
+ i := i+1
+ x
+
+@
+\section{domain FRMOD FramedModule}
+<<domain FRMOD FramedModule>>=
+)abbrev domain FRMOD FramedModule
+++ Author: Manuel Bronstein
+++ Date Created: 27 Jan 1989
+++ Date Last Updated: 24 Jul 1990
+++ Keywords: ideal, algebra, module.
+++ Examples: )r FRIDEAL INPUT
+++ Description: Module representation of fractional ideals.
+FramedModule(R, F, UP, A, ibasis): Exports == Implementation where
+ R : EuclideanDomain
+ F : QuotientFieldCategory R
+ UP : UnivariatePolynomialCategory F
+ A : FramedAlgebra(F, UP)
+ ibasis: Vector A
+
+ VR ==> Vector R
+ VF ==> Vector F
+ VA ==> Vector A
+ M ==> Matrix F
+
+ Exports ==> Monoid with
+ basis : % -> VA
+ ++ basis((f1,...,fn)) = the vector \spad{[f1,...,fn]}.
+ norm : % -> F
+ ++ norm(f) returns the norm of the module f.
+ module: VA -> %
+ ++ module([f1,...,fn]) = the module generated by \spad{(f1,...,fn)}
+ ++ over R.
+ if A has RetractableTo F then
+ module: FractionalIdeal(R, F, UP, A) -> %
+ ++ module(I) returns I viewed has a module over R.
+
+ Implementation ==> add
+ import MatrixCommonDenominator(R, F)
+ import ModularHermitianRowReduction(R)
+
+ Rep := VA
+
+ iflag?:Reference(Boolean) := ref true
+ wflag?:Reference(Boolean) := ref true
+ imat := new(#ibasis, #ibasis, 0)$M
+ wmat := new(#ibasis, #ibasis, 0)$M
+
+ rowdiv : (VR, R) -> VF
+ vectProd : (VA, VA) -> VA
+ wmatrix : VA -> M
+ W2A : VF -> A
+ intmat : () -> M
+ invintmat : () -> M
+ getintmat : () -> Boolean
+ getinvintmat: () -> Boolean
+
+ 1 == ibasis
+ module(v:VA) == v
+ basis m == m pretend VA
+ rowdiv(r, f) == [r.i / f for i in minIndex r..maxIndex r]
+ coerce(m:%):OutputForm == coerce(basis m)$VA
+ W2A v == represents(v * intmat())
+ wmatrix v == coordinates(v) * invintmat()
+
+ getinvintmat() ==
+ m := inverse(intmat())::M
+ for i in minRowIndex m .. maxRowIndex m repeat
+ for j in minColIndex m .. maxColIndex m repeat
+ imat(i, j) := qelt(m, i, j)
+ false
+
+ getintmat() ==
+ m := coordinates ibasis
+ for i in minRowIndex m .. maxRowIndex m repeat
+ for j in minColIndex m .. maxColIndex m repeat
+ wmat(i, j) := qelt(m, i, j)
+ false
+
+ invintmat() ==
+ if iflag?() then iflag?() := getinvintmat()
+ imat
+
+ intmat() ==
+ if wflag?() then wflag?() := getintmat()
+ wmat
+
+ vectProd(v1, v2) ==
+ k := minIndex(v := new(#v1 * #v2, 0)$VA)
+ for i in minIndex v1 .. maxIndex v1 repeat
+ for j in minIndex v2 .. maxIndex v2 repeat
+ qsetelt_!(v, k, qelt(v1, i) * qelt(v2, j))
+ k := k + 1
+ v pretend VA
+
+ norm m ==
+ #(basis m) ^= #ibasis => error "Module not of rank n"
+ determinant(coordinates(basis m) * invintmat())
+
+ m1 * m2 ==
+ m := rowEch((cd := splitDenominator wmatrix(
+ vectProd(basis m1, basis m2))).num)
+ module [u for i in minRowIndex m .. maxRowIndex m |
+ (u := W2A rowdiv(row(m, i), cd.den)) ^= 0]$VA
+
+ if A has RetractableTo F then
+ module(i:FractionalIdeal(R, F, UP, A)) ==
+ module(basis i) * module(ibasis)
+
+@
+\section{category FDIVCAT FiniteDivisorCategory}
+<<category FDIVCAT FiniteDivisorCategory>>=
+)abbrev category FDIVCAT FiniteDivisorCategory
+++ Category for finite rational divisors on a curve
+++ Author: Manuel Bronstein
+++ Date Created: 19 May 1993
+++ Date Last Updated: 19 May 1993
+++ Description:
+++ This category describes finite rational divisors on a curve, that
+++ is finite formal sums SUM(n * P) where the n's are integers and the
+++ P's are finite rational points on the curve.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r FDIV INPUT
+FiniteDivisorCategory(F, UP, UPUP, R): Category == Result where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ ID ==> FractionalIdeal(UP, Fraction UP, UPUP, R)
+
+ Result ==> AbelianGroup with
+ ideal : % -> ID
+ ++ ideal(D) returns the ideal corresponding to a divisor D.
+ divisor : ID -> %
+ ++ divisor(I) makes a divisor D from an ideal I.
+ divisor : R -> %
+ ++ divisor(g) returns the divisor of the function g.
+ divisor : (F, F) -> %
+ ++ divisor(a, b) makes the divisor P: \spad{(x = a, y = b)}.
+ ++ Error: if P is singular.
+ divisor : (F, F, Integer) -> %
+ ++ divisor(a, b, n) makes the divisor
+ ++ \spad{nP} where P: \spad{(x = a, y = b)}.
+ ++ P is allowed to be singular if n is a multiple of the rank.
+ decompose : % -> Record(id:ID, principalPart: R)
+ ++ decompose(d) returns \spad{[id, f]} where \spad{d = (id) + div(f)}.
+ reduce : % -> %
+ ++ reduce(D) converts D to some reduced form (the reduced forms can
+ ++ be differents in different implementations).
+ principal? : % -> Boolean
+ ++ principal?(D) tests if the argument is the divisor of a function.
+ generator : % -> Union(R, "failed")
+ ++ generator(d) returns f if \spad{(f) = d},
+ ++ "failed" if d is not principal.
+ divisor : (R, UP, UP, UP, F) -> %
+ ++ divisor(h, d, d', g, r) returns the sum of all the finite points
+ ++ where \spad{h/d} has residue \spad{r}.
+ ++ \spad{h} must be integral.
+ ++ \spad{d} must be squarefree.
+ ++ \spad{d'} is some derivative of \spad{d} (not necessarily dd/dx).
+ ++ \spad{g = gcd(d,discriminant)} contains the ramified zeros of \spad{d}
+ add
+ principal? d == generator(d) case R
+
+@
+\section{domain HELLFDIV HyperellipticFiniteDivisor}
+<<domain HELLFDIV HyperellipticFiniteDivisor>>=
+)abbrev domain HELLFDIV HyperellipticFiniteDivisor
+++ Finite rational divisors on an hyperelliptic curve
+++ Author: Manuel Bronstein
+++ Date Created: 19 May 1993
+++ Date Last Updated: 20 July 1998
+++ Description:
+++ This domains implements finite rational divisors on an hyperelliptic curve,
+++ that is finite formal sums SUM(n * P) where the n's are integers and the
+++ P's are finite rational points on the curve.
+++ The equation of the curve must be y^2 = f(x) and f must have odd degree.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r FDIV INPUT
+HyperellipticFiniteDivisor(F, UP, UPUP, R): Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ O ==> OutputForm
+ Z ==> Integer
+ RF ==> Fraction UP
+ ID ==> FractionalIdeal(UP, RF, UPUP, R)
+ ERR ==> error "divisor: incomplete implementation for hyperelliptic curves"
+
+ Exports ==> FiniteDivisorCategory(F, UP, UPUP, R)
+
+ Implementation ==> add
+ if (uhyper:Union(UP, "failed") := hyperelliptic()$R) case "failed" then
+ error "HyperellipticFiniteDivisor: curve must be hyperelliptic"
+
+-- we use the semi-reduced representation from D.Cantor, "Computing in the
+-- Jacobian of a HyperellipticCurve", Mathematics of Computation, vol 48,
+-- no.177, January 1987, 95-101.
+-- The representation [a,b,f] for D means D = [a,b] + div(f)
+-- and [a,b] is a semi-reduced representative on the Jacobian
+ Rep := Record(center:UP, polyPart:UP, principalPart:R, reduced?:Boolean)
+
+ hyper:UP := uhyper::UP
+ gen:Z := ((degree(hyper)::Z - 1) exquo 2)::Z -- genus of the curve
+ dvd:O := "div"::Symbol::O
+ zer:O := 0::Z::O
+
+ makeDivisor : (UP, UP, R) -> %
+ intReduc : (R, UP) -> R
+ princ? : % -> Boolean
+ polyIfCan : R -> Union(UP, "failed")
+ redpolyIfCan : (R, UP) -> Union(UP, "failed")
+ intReduce : (R, UP) -> R
+ mkIdeal : (UP, UP) -> ID
+ reducedTimes : (Z, UP, UP) -> %
+ reducedDouble: (UP, UP) -> %
+
+ 0 == divisor(1$R)
+ divisor(g:R) == [1, 0, g, true]
+ makeDivisor(a, b, g) == [a, b, g, false]
+-- princ? d == one?(d.center) and zero?(d.polyPart)
+ princ? d == (d.center = 1) and zero?(d.polyPart)
+ ideal d == ideal([d.principalPart]) * mkIdeal(d.center, d.polyPart)
+ decompose d == [ideal makeDivisor(d.center, d.polyPart, 1), d.principalPart]
+ mkIdeal(a, b) == ideal [a::RF::R, reduce(monomial(1, 1)$UPUP - b::RF::UPUP)]
+
+-- keep the sum reduced if d1 and d2 are both reduced at the start
+ d1 + d2 ==
+ a1 := d1.center; a2 := d2.center
+ b1 := d1.polyPart; b2 := d2.polyPart
+ rec := principalIdeal [a1, a2, b1 + b2]
+ d := rec.generator
+ h := rec.coef -- d = h1 a1 + h2 a2 + h3(b1 + b2)
+ a := ((a1 * a2) exquo d**2)::UP
+ b:UP:= first(h) * a1 * b2
+ b := b + second(h) * a2 * b1
+ b := b + third(h) * (b1*b2 + hyper)
+ b := (b exquo d)::UP rem a
+ dd := makeDivisor(a, b, d::RF * d1.principalPart * d2.principalPart)
+ d1.reduced? and d2.reduced? => reduce dd
+ dd
+
+-- if is cheaper to keep on reducing as we exponentiate if d is already reduced
+ n:Z * d:% ==
+ zero? n => 0
+ n < 0 => (-n) * (-d)
+ divisor(d.principalPart ** n) + divisor(mkIdeal(d.center,d.polyPart) ** n)
+
+ divisor(i:ID) ==
+-- one?(n := #(v := basis minimize i)) => divisor v minIndex v
+ (n := #(v := basis minimize i)) = 1 => divisor v minIndex v
+ n ^= 2 => ERR
+ a := v minIndex v
+ h := v maxIndex v
+ (u := polyIfCan a) case UP =>
+ (w := redpolyIfCan(h, u::UP)) case UP => makeDivisor(u::UP, w::UP, 1)
+ ERR
+ (u := polyIfCan h) case UP =>
+ (w := redpolyIfCan(a, u::UP)) case UP => makeDivisor(u::UP, w::UP, 1)
+ ERR
+ ERR
+
+ polyIfCan a ==
+ (u := retractIfCan(a)@Union(RF, "failed")) case "failed" => "failed"
+ (v := retractIfCan(u::RF)@Union(UP, "failed")) case "failed" => "failed"
+ v::UP
+
+ redpolyIfCan(h, a) ==
+ degree(p := lift h) ^= 1 => "failed"
+ q := - coefficient(p, 0) / coefficient(p, 1)
+ rec := extendedEuclidean(denom q, a)
+ not ground?(rec.generator) => "failed"
+ ((numer(q) * rec.coef1) exquo rec.generator)::UP rem a
+
+ coerce(d:%):O ==
+ r := bracket [d.center::O, d.polyPart::O]
+ g := prefix(dvd, [d.principalPart::O])
+-- z := one?(d.principalPart)
+ z := (d.principalPart = 1)
+ princ? d => (z => zer; g)
+ z => r
+ r + g
+
+ reduce d ==
+ d.reduced? => d
+ degree(a := d.center) <= gen => (d.reduced? := true; d)
+ b := d.polyPart
+ a0 := ((hyper - b**2) exquo a)::UP
+ b0 := (-b) rem a0
+ g := d.principalPart * reduce(b::RF::UPUP-monomial(1,1)$UPUP) / a0::RF::R
+ reduce makeDivisor(a0, b0, g)
+
+ generator d ==
+ d := reduce d
+ princ? d => d.principalPart
+ "failed"
+
+ - d ==
+ a := d.center
+ makeDivisor(a, - d.polyPart, inv(a::RF * d.principalPart))
+
+ d1 = d2 ==
+ d1 := reduce d1
+ d2 := reduce d2
+ d1.center = d2.center and d1.polyPart = d2.polyPart
+ and d1.principalPart = d2.principalPart
+
+ divisor(a, b) ==
+ x := monomial(1, 1)$UP
+ not ground? gcd(d := x - a::UP, retract(discriminant())@UP) =>
+ error "divisor: point is singular"
+ makeDivisor(d, b::UP, 1)
+
+ intReduce(h, b) ==
+ v := integralCoordinates(h).num
+ integralRepresents(
+ [qelt(v, i) rem b for i in minIndex v .. maxIndex v], 1)
+
+-- with hyperelliptic curves, it is cheaper to keep divisors in reduced form
+ divisor(h, a, dp, g, r) ==
+ h := h - (r * dp)::RF::R
+ a := gcd(a, retract(norm h)@UP)
+ h := intReduce(h, a)
+ if not ground? gcd(g, a) then h := intReduce(h ** rank(), a)
+ hh := lift h
+ b := - coefficient(hh, 0) / coefficient(hh, 1)
+ rec := extendedEuclidean(denom b, a)
+ not ground?(rec.generator) => ERR
+ bb := ((numer(b) * rec.coef1) exquo rec.generator)::UP rem a
+ reduce makeDivisor(a, bb, 1)
+
+@
+\section{domain FDIV FiniteDivisor}
+<<domain FDIV FiniteDivisor>>=
+)abbrev domain FDIV FiniteDivisor
+++ Finite rational divisors on a curve
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 29 July 1993
+++ Description:
+++ This domains implements finite rational divisors on a curve, that
+++ is finite formal sums SUM(n * P) where the n's are integers and the
+++ P's are finite rational points on the curve.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r FDIV INPUT
+FiniteDivisor(F, UP, UPUP, R): Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ N ==> NonNegativeInteger
+ RF ==> Fraction UP
+ ID ==> FractionalIdeal(UP, RF, UPUP, R)
+
+ Exports ==> FiniteDivisorCategory(F, UP, UPUP, R) with
+ finiteBasis: % -> Vector R
+ ++ finiteBasis(d) returns a basis for d as a module over {\em K[x]}.
+ lSpaceBasis: % -> Vector R
+ ++ lSpaceBasis(d) returns a basis for \spad{L(d) = {f | (f) >= -d}}
+ ++ as a module over \spad{K[x]}.
+
+ Implementation ==> add
+ if hyperelliptic()$R case UP then
+ Rep := HyperellipticFiniteDivisor(F, UP, UPUP, R)
+
+ 0 == 0$Rep
+ coerce(d:$):OutputForm == coerce(d)$Rep
+ d1 = d2 == d1 =$Rep d2
+ n * d == n *$Rep d
+ d1 + d2 == d1 +$Rep d2
+ - d == -$Rep d
+ ideal d == ideal(d)$Rep
+ reduce d == reduce(d)$Rep
+ generator d == generator(d)$Rep
+ decompose d == decompose(d)$Rep
+ divisor(i:ID) == divisor(i)$Rep
+ divisor(f:R) == divisor(f)$Rep
+ divisor(a, b) == divisor(a, b)$Rep
+ divisor(a, b, n) == divisor(a, b, n)$Rep
+ divisor(h, d, dp, g, r) == divisor(h, d, dp, g, r)$Rep
+
+ else
+ Rep := Record(id:ID, fbasis:Vector(R))
+
+ import CommonDenominator(UP, RF, Vector RF)
+ import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
+
+ makeDivisor : (UP, UPUP, UP) -> %
+ intReduce : (R, UP) -> R
+
+ ww := integralBasis()$R
+
+ 0 == [1, empty()]
+ divisor(i:ID) == [i, empty()]
+ divisor(f:R) == divisor ideal [f]
+ coerce(d:%):OutputForm == ideal(d)::OutputForm
+ ideal d == d.id
+ decompose d == [ideal d, 1]
+ d1 = d2 == basis(ideal d1) = basis(ideal d2)
+ n * d == divisor(ideal(d) ** n)
+ d1 + d2 == divisor(ideal d1 * ideal d2)
+ - d == divisor inv ideal d
+ divisor(h, d, dp, g, r) == makeDivisor(d, lift h - (r * dp)::RF::UPUP, g)
+
+ intReduce(h, b) ==
+ v := integralCoordinates(h).num
+ integralRepresents(
+ [qelt(v, i) rem b for i in minIndex v .. maxIndex v], 1)
+
+ divisor(a, b) ==
+ x := monomial(1, 1)$UP
+ not ground? gcd(d := x - a::UP, retract(discriminant())@UP) =>
+ error "divisor: point is singular"
+ makeDivisor(d, monomial(1, 1)$UPUP - b::UP::RF::UPUP, 1)
+
+ divisor(a, b, n) ==
+ not(ground? gcd(d := monomial(1, 1)$UP - a::UP,
+ retract(discriminant())@UP)) and
+ ((n exquo rank()) case "failed") =>
+ error "divisor: point is singular"
+ m:N :=
+ n < 0 => (-n)::N
+ n::N
+ g := makeDivisor(d**m,(monomial(1,1)$UPUP - b::UP::RF::UPUP)**m,1)
+ n < 0 => -g
+ g
+
+ reduce d ==
+ (i := minimize(j := ideal d)) = j => d
+ #(n := numer i) ^= 2 => divisor i
+ cd := splitDenominator lift n(1 + minIndex n)
+ b := gcd(cd.den * retract(retract(n minIndex n)@RF)@UP,
+ retract(norm reduce(cd.num))@UP)
+ e := cd.den * denom i
+ divisor ideal([(b / e)::R,
+ reduce map((retract(#1)@UP rem b) / e, cd.num)]$Vector(R))
+
+ finiteBasis d ==
+ if empty?(d.fbasis) then
+ d.fbasis := normalizeAtInfinity
+ basis module(ideal d)$FramedModule(UP, RF, UPUP, R, ww)
+ d.fbasis
+
+ generator d ==
+ bsis := finiteBasis d
+ for i in minIndex bsis .. maxIndex bsis repeat
+ integralAtInfinity? qelt(bsis, i) =>
+ return primitivePart qelt(bsis,i)
+ "failed"
+
+ lSpaceBasis d ==
+ map_!(primitivePart, reduceBasisAtInfinity finiteBasis(-d))
+
+-- b = center, hh = integral function, g = gcd(b, discriminant)
+ makeDivisor(b, hh, g) ==
+ b := gcd(b, retract(norm(h := reduce hh))@UP)
+ h := intReduce(h, b)
+ if not ground? gcd(g, b) then h := intReduce(h ** rank(), b)
+ divisor ideal [b::RF::R, h]$Vector(R)
+
+@
+\section{package FDIV2 FiniteDivisorFunctions2}
+<<package FDIV2 FiniteDivisorFunctions2>>=
+)abbrev package FDIV2 FiniteDivisorFunctions2
+++ Lift a map to finite divisors.
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 19 May 1993
+FiniteDivisorFunctions2(R1, UP1, UPUP1, F1, R2, UP2, UPUP2, F2):
+ Exports == Implementation where
+ R1 : Field
+ UP1 : UnivariatePolynomialCategory R1
+ UPUP1: UnivariatePolynomialCategory Fraction UP1
+ F1 : FunctionFieldCategory(R1, UP1, UPUP1)
+ R2 : Field
+ UP2 : UnivariatePolynomialCategory R2
+ UPUP2: UnivariatePolynomialCategory Fraction UP2
+ F2 : FunctionFieldCategory(R2, UP2, UPUP2)
+
+ Exports ==> with
+ map: (R1 -> R2, FiniteDivisor(R1, UP1, UPUP1, F1)) ->
+ FiniteDivisor(R2, UP2, UPUP2, F2)
+ ++ map(f,d) \undocumented{}
+
+ Implementation ==> add
+ import UnivariatePolynomialCategoryFunctions2(R1,UP1,R2,UP2)
+ import FunctionFieldCategoryFunctions2(R1,UP1,UPUP1,F1,R2,UP2,UPUP2,F2)
+ import FractionalIdealFunctions2(UP1, Fraction UP1, UPUP1, F1,
+ UP2, Fraction UP2, UPUP2, F2)
+
+ map(f, d) ==
+ rec := decompose d
+ divisor map(f, rec.principalPart) + divisor map(map(f, #1), rec.id)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the algebraic integration world should be compiled
+-- in the following order:
+--
+-- curve DIVISOR reduc pfo intalg int
+
+<<domain FRIDEAL FractionalIdeal>>
+<<package FRIDEAL2 FractionalIdealFunctions2>>
+<<package MHROWRED ModularHermitianRowReduction>>
+<<domain FRMOD FramedModule>>
+<<category FDIVCAT FiniteDivisorCategory>>
+<<domain HELLFDIV HyperellipticFiniteDivisor>>
+<<domain FDIV FiniteDivisor>>
+<<package FDIV2 FiniteDivisorFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/dpolcat.spad.pamphlet b/src/algebra/dpolcat.spad.pamphlet
new file mode 100644
index 00000000..2a170259
--- /dev/null
+++ b/src/algebra/dpolcat.spad.pamphlet
@@ -0,0 +1,591 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra dpolcat.spad}
+\author{William Sit}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category DVARCAT DifferentialVariableCategory}
+<<category DVARCAT DifferentialVariableCategory>>=
+)abbrev category DVARCAT DifferentialVariableCategory
+++ Author: William Sit
+++ Date Created: 19 July 1990
+++ Date Last Updated: 13 September 1991
+++ Basic Operations:
+++ Related Constructors:DifferentialPolynomialCategory
+++ See Also:OrderedDifferentialVariable,
+++ SequentialDifferentialVariable,
+++ DifferentialSparseMultivariatePolynomial.
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, ranking, order, weight
+++ References:Ritt, J.F. "Differential Algebra" (Dover, 1950).
+++ Description:
+++ \spadtype{DifferentialVariableCategory} constructs the
+++ set of derivatives of a given set of
+++ (ordinary) differential indeterminates.
+++ If x,...,y is an ordered set of differential indeterminates,
+++ and the prime notation is used for differentiation, then
+++ the set of derivatives (including
+++ zero-th order) of the differential indeterminates is
+++ x,\spad{x'},\spad{x''},..., y,\spad{y'},\spad{y''},...
+++ (Note: in the interpreter, the n-th derivative of y is displayed as
+++ y with a subscript n.) This set is
+++ viewed as a set of algebraic indeterminates, totally ordered in a
+++ way compatible with differentiation and the given order on the
+++ differential indeterminates. Such a total order is called a
+++ ranking of the differential indeterminates.
+++
+++ A domain in this category is needed to construct a differential
+++ polynomial domain. Differential polynomials are ordered
+++ by a ranking on the derivatives, and by an order (extending the
+++ ranking) on
+++ on the set of differential monomials. One may thus associate
+++ a domain in this category with a ranking of the differential
+++ indeterminates, just as one associates a domain in the category
+++ \spadtype{OrderedAbelianMonoidSup} with an ordering of the set of
+++ monomials in a set of algebraic indeterminates. The ranking
+++ is specified through the binary relation \spadfun{<}.
+++ For example, one may define
+++ one derivative to be less than another by lexicographically comparing
+++ first the \spadfun{order}, then the given order of the differential
+++ indeterminates appearing in the derivatives. This is the default
+++ implementation.
+++
+++ The notion of weight generalizes that of degree. A
+++ polynomial domain may be made into a graded ring
+++ if a weight function is given on the set of indeterminates,
+++ Very often, a grading is the first step in ordering the set of
+++ monomials. For differential polynomial domains, this
+++ constructor provides a function \spadfun{weight}, which
+++ allows the assignment of a non-negative number to each derivative of a
+++ differential indeterminate. For example, one may define
+++ the weight of a derivative to be simply its \spadfun{order}
+++ (this is the default assignment).
+++ This weight function can then be extended to the set of
+++ all differential polynomials, providing a graded ring
+++ structure.
+DifferentialVariableCategory(S:OrderedSet): Category ==
+ Join(OrderedSet, RetractableTo S) with
+ -- Examples:
+ -- v:=makeVariable('s,5)
+ makeVariable : (S, NonNegativeInteger) -> $
+ ++ makeVariable(s, n) returns the n-th derivative of a
+ ++ differential indeterminate s as an algebraic indeterminate.
+ -- Example: makeVariable('s, 5)
+ order : $ -> NonNegativeInteger
+ ++ order(v) returns n if v is the n-th derivative of any
+ ++ differential indeterminate.
+ -- Example: order(v)
+ variable : $ -> S
+ ++ variable(v) returns s if v is any derivative of the differential
+ ++ indeterminate s.
+ -- Example: variable(v)
+ -- default implementation using above primitives --
+
+ weight : $ -> NonNegativeInteger
+ ++ weight(v) returns the weight of the derivative v.
+ -- Example: weight(v)
+ differentiate : $ -> $
+ ++ differentiate(v) returns the derivative of v.
+ -- Example: differentiate(v)
+ differentiate : ($, NonNegativeInteger) -> $
+ ++ differentiate(v, n) returns the n-th derivative of v.
+ -- Example: differentiate(v,2)
+ coerce : S -> $
+ ++ coerce(s) returns s, viewed as the zero-th order derivative of s.
+ -- Example: coerce('s); differentiate(%,5)
+ add
+ import NumberFormats
+ coerce (s:S):$ == makeVariable(s, 0)
+ differentiate v == differentiate(v, 1)
+ differentiate(v, n) == makeVariable(variable v, n + order v)
+ retractIfCan v == (zero?(order v) => variable v; "failed")
+ v = u == (variable v = variable u) and (order v = order u)
+
+ coerce(v:$):OutputForm ==
+ a := variable(v)::OutputForm
+ zero?(nn := order v) => a
+ sub(a, outputForm nn)
+ retract v ==
+ zero?(order v) => variable v
+ error "Not retractable"
+ v < u ==
+ -- the ranking below is orderly, and is the default --
+ order v = order u => variable v < variable u
+ order v < order u
+ weight v == order v
+ -- the default weight is just the order
+
+@
+\section{domain ODVAR OrderlyDifferentialVariable}
+<<domain ODVAR OrderlyDifferentialVariable>>=
+)abbrev domain ODVAR OrderlyDifferentialVariable
+++ Author: William Sit
+++ Date Created: 19 July 1990
+++ Date Last Updated: 13 September 1991
+++ Basic Operations:differentiate, order, variable,<
+++ Related Domains: OrderedVariableList,
+++ SequentialDifferentialVariable.
+++ See Also: DifferentialVariableCategory
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, orderly ranking.
+++ References:Kolchin, E.R. "Differential Algebra and Algebraic Groups"
+++ (Academic Press, 1973).
+++ Description:
+++ \spadtype{OrderlyDifferentialVariable} adds a commonly used orderly
+++ ranking to the set of derivatives of an ordered list of differential
+++ indeterminates. An orderly ranking is a ranking \spadfun{<} of the
+++ derivatives with the property that for two derivatives u and v,
+++ u \spadfun{<} v if the \spadfun{order} of u is less than that
+++ of v.
+++ This domain belongs to \spadtype{DifferentialVariableCategory}. It
+++ defines \spadfun{weight} to be just \spadfun{order}, and it
+++ defines an orderly ranking \spadfun{<} on derivatives u via the
+++ lexicographic order on the pair
+++ (\spadfun{order}(u), \spadfun{variable}(u)).
+OrderlyDifferentialVariable(S:OrderedSet):DifferentialVariableCategory(S)
+ == add
+ Rep := Record(var:S, ord:NonNegativeInteger)
+ makeVariable(s,n) == [s, n]
+ variable v == v.var
+ order v == v.ord
+
+@
+\section{domain SDVAR SequentialDifferentialVariable}
+<<domain SDVAR SequentialDifferentialVariable>>=
+)abbrev domain SDVAR SequentialDifferentialVariable
+++ Author: William Sit
+++ Date Created: 19 July 1990
+++ Date Last Updated: 13 September 1991
+++ Basic Operations:differentiate, order, variable, <
+++ Related Domains: OrderedVariableList,
+++ OrderlyDifferentialVariable.
+++ See Also:DifferentialVariableCategory
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, sequential ranking.
+++ References:Kolchin, E.R. "Differential Algebra and Algebraic Groups"
+++ (Academic Press, 1973).
+++ Description:
+++ \spadtype{OrderlyDifferentialVariable} adds a commonly used sequential
+++ ranking to the set of derivatives of an ordered list of differential
+++ indeterminates. A sequential ranking is a ranking \spadfun{<} of the
+++ derivatives with the property that for any derivative v,
+++ there are only a finite number of derivatives u with u \spadfun{<} v.
+++ This domain belongs to \spadtype{DifferentialVariableCategory}. It
+++ defines \spadfun{weight} to be just \spadfun{order}, and it
+++ defines a sequential ranking \spadfun{<} on derivatives u by the
+++ lexicographic order on the pair
+++ (\spadfun{variable}(u), \spadfun{order}(u)).
+
+SequentialDifferentialVariable(S:OrderedSet):DifferentialVariableCategory(S)
+ == add
+ Rep := Record(var:S, ord:NonNegativeInteger)
+ makeVariable(s,n) == [s, n]
+ variable v == v.var
+ order v == v.ord
+ v < u ==
+ variable v = variable u => order v < order u
+ variable v < variable u
+
+@
+\section{category DPOLCAT DifferentialPolynomialCategory}
+<<category DPOLCAT DifferentialPolynomialCategory>>=
+)abbrev category DPOLCAT DifferentialPolynomialCategory
+++ Author: William Sit
+++ Date Created: 19 July 1990
+++ Date Last Updated: 13 September 1991
+++ Basic Operations:PolynomialCategory
+++ Related Constructors:DifferentialVariableCategory
+++ See Also:
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, ranking, differential polynomials,
+++ order, weight, leader, separant, initial, isobaric
+++ References:Kolchin, E.R. "Differential Algebra and Algebraic Groups"
+++ (Academic Press, 1973).
+++ Description:
+++ \spadtype{DifferentialPolynomialCategory} is a category constructor
+++ specifying basic functions in an ordinary differential polynomial
+++ ring with a given ordered set of differential indeterminates.
+++ In addition, it implements defaults for the basic functions.
+++ The functions \spadfun{order} and \spadfun{weight} are extended
+++ from the set of derivatives of differential indeterminates
+++ to the set of differential polynomials. Other operations
+++ provided on differential polynomials are
+++ \spadfun{leader}, \spadfun{initial},
+++ \spadfun{separant}, \spadfun{differentialVariables}, and
+++ \spadfun{isobaric?}. Furthermore, if the ground ring is
+++ a differential ring, then evaluation (substitution
+++ of differential indeterminates by elements of the ground ring
+++ or by differential polynomials) is
+++ provided by \spadfun{eval}.
+++ A convenient way of referencing derivatives is provided by
+++ the functions \spadfun{makeVariable}.
+++
+++ To construct a domain using this constructor, one needs
+++ to provide a ground ring R, an ordered set S of differential
+++ indeterminates, a ranking V on the set of derivatives
+++ of the differential indeterminates, and a set E of
+++ exponents in bijection with the set of differential monomials
+++ in the given differential indeterminates.
+++
+
+DifferentialPolynomialCategory(R:Ring,S:OrderedSet,
+ V:DifferentialVariableCategory S, E:OrderedAbelianMonoidSup):
+ Category ==
+ Join(PolynomialCategory(R,E,V),
+ DifferentialExtension R, RetractableTo S) with
+ -- Examples:
+ -- s:=makeVariable('s)
+ -- p:= 3*(s 1)**2 + s*(s 2)**3
+ -- all functions below have default implementations
+ -- using primitives from V
+
+ makeVariable: S -> (NonNegativeInteger -> $)
+ ++ makeVariable(s) views s as a differential
+ ++ indeterminate, in such a way that the n-th
+ ++ derivative of s may be simply referenced as z.n
+ ++ where z :=makeVariable(s).
+ ++ Note: In the interpreter, z is
+ ++ given as an internal map, which may be ignored.
+ -- Example: makeVariable('s); %.5
+
+ differentialVariables: $ -> List S
+ ++ differentialVariables(p) returns a list of differential
+ ++ indeterminates occurring in a differential polynomial p.
+ order : ($, S) -> NonNegativeInteger
+ ++ order(p,s) returns the order of the differential
+ ++ polynomial p in differential indeterminate s.
+ order : $ -> NonNegativeInteger
+ ++ order(p) returns the order of the differential polynomial p,
+ ++ which is the maximum number of differentiations of a
+ ++ differential indeterminate, among all those appearing in p.
+ degree: ($, S) -> NonNegativeInteger
+ ++ degree(p, s) returns the maximum degree of
+ ++ the differential polynomial p viewed as a differential polynomial
+ ++ in the differential indeterminate s alone.
+ weights: $ -> List NonNegativeInteger
+ ++ weights(p) returns a list of weights of differential monomials
+ ++ appearing in differential polynomial p.
+ weight: $ -> NonNegativeInteger
+ ++ weight(p) returns the maximum weight of all differential monomials
+ ++ appearing in the differential polynomial p.
+ weights: ($, S) -> List NonNegativeInteger
+ ++ weights(p, s) returns a list of
+ ++ weights of differential monomials
+ ++ appearing in the differential polynomial p when p is viewed
+ ++ as a differential polynomial in the differential indeterminate s
+ ++ alone.
+ weight: ($, S) -> NonNegativeInteger
+ ++ weight(p, s) returns the maximum weight of all differential
+ ++ monomials appearing in the differential polynomial p
+ ++ when p is viewed as a differential polynomial in
+ ++ the differential indeterminate s alone.
+ isobaric?: $ -> Boolean
+ ++ isobaric?(p) returns true if every differential monomial appearing
+ ++ in the differential polynomial p has same weight,
+ ++ and returns false otherwise.
+ leader: $ -> V
+ ++ leader(p) returns the derivative of the highest rank
+ ++ appearing in the differential polynomial p
+ ++ Note: an error occurs if p is in the ground ring.
+ initial:$ -> $
+ ++ initial(p) returns the
+ ++ leading coefficient when the differential polynomial p
+ ++ is written as a univariate polynomial in its leader.
+ separant:$ -> $
+ ++ separant(p) returns the
+ ++ partial derivative of the differential polynomial p
+ ++ with respect to its leader.
+ if R has DifferentialRing then
+ InnerEvalable(S, R)
+ InnerEvalable(S, $)
+ Evalable $
+ makeVariable: $ -> (NonNegativeInteger -> $)
+ ++ makeVariable(p) views p as an element of a differential
+ ++ ring, in such a way that the n-th
+ ++ derivative of p may be simply referenced as z.n
+ ++ where z := makeVariable(p).
+ ++ Note: In the interpreter, z is
+ ++ given as an internal map, which may be ignored.
+ -- Example: makeVariable(p); %.5; makeVariable(%**2); %.2
+
+ add
+ p:$
+ s:S
+ makeVariable s == makeVariable(s,#1)::$
+
+ if R has IntegralDomain then
+ differentiate(p:$, d:R -> R) ==
+ ans:$ := 0
+ l := variables p
+ while (u:=retractIfCan(p)@Union(R, "failed")) case "failed" repeat
+ t := leadingMonomial p
+ lc := leadingCoefficient t
+ ans := ans + d(lc)::$ * (t exquo lc)::$
+ + +/[differentiate(t, v) * (differentiate v)::$ for v in l]
+ p := reductum p
+ ans + d(u::R)::$
+
+ order (p:$):NonNegativeInteger ==
+ ground? p => 0
+ "max"/[order v for v in variables p]
+ order (p:$,s:S):NonNegativeInteger ==
+ ground? p => 0
+ empty? (vv:= [order v for v in variables p | (variable v) = s ]) =>0
+ "max"/vv
+
+ degree (p, s) ==
+ d:NonNegativeInteger:=0
+ for lp in monomials p repeat
+ lv:= [v for v in variables lp | (variable v) = s ]
+ if not empty? lv then d:= max(d, +/degree(lp, lv))
+ d
+
+ weights p ==
+ ws:List NonNegativeInteger := nil
+ empty? (mp:=monomials p) => ws
+ for lp in mp repeat
+ lv:= variables lp
+ if not empty? lv then
+ dv:= degree(lp, lv)
+ w:=+/[(weight v) * d for v in lv for d in dv]$(List NonNegativeInteger)
+ ws:= concat(ws, w)
+ ws
+ weight p ==
+ empty? (ws:=weights p) => 0
+ "max"/ws
+
+ weights (p, s) ==
+ ws:List NonNegativeInteger := nil
+ empty?(mp:=monomials p) => ws
+ for lp in mp repeat
+ lv:= [v for v in variables lp | (variable v) = s ]
+ if not empty? lv then
+ dv:= degree(lp, lv)
+ w:=+/[(weight v) * d for v in lv for d in dv]$(List NonNegativeInteger)
+ ws:= concat(ws, w)
+ ws
+ weight (p,s) ==
+ empty? (ws:=weights(p,s)) => 0
+ "max"/ws
+
+ isobaric? p == (# removeDuplicates weights p) = 1
+
+ leader p == -- depends on the ranking
+ vl:= variables p
+ -- it's not enough just to look at leadingMonomial p
+ -- the term-ordering need not respect the ranking
+ empty? vl => error "leader is not defined "
+ "max"/vl
+ initial p == leadingCoefficient univariate(p,leader p)
+ separant p == differentiate(p, leader p)
+
+ coerce(s:S):$ == s::V::$
+
+ retractIfCan(p:$):Union(S, "failed") ==
+ (v := retractIfCan(p)@Union(V,"failed")) case "failed" => "failed"
+ retractIfCan(v::V)
+
+ differentialVariables p ==
+ removeDuplicates [variable v for v in variables p]
+
+ if R has DifferentialRing then
+
+ makeVariable p == differentiate(p, #1)
+
+ eval(p:$, sl:List S, rl:List R) ==
+ ordp:= order p
+ vl := concat [[makeVariable(s,j)$V for j in 0..ordp]
+ for s in sl]$List(List V)
+ rrl:=nil$List(R)
+ for r in rl repeat
+ t:= r
+ rrl:= concat(rrl,
+ concat(r, [t := differentiate t for i in 1..ordp]))
+ eval(p, vl, rrl)
+
+ eval(p:$, sl:List S, rl:List $) ==
+ ordp:= order p
+ vl := concat [[makeVariable(s,j)$V for j in 0..ordp]
+ for s in sl]$List(List V)
+ rrl:=nil$List($)
+ for r in rl repeat
+ t:=r
+ rrl:=concat(rrl,
+ concat(r, [t:=differentiate t for i in 1..ordp]))
+ eval(p, vl, rrl)
+ eval(p:$, l:List Equation $) ==
+ eval(p, [retract(lhs e)@S for e in l]$List(S),
+ [rhs e for e in l]$List($))
+
+@
+\section{domain DSMP DifferentialSparseMultivariatePolynomial}
+<<domain DSMP DifferentialSparseMultivariatePolynomial>>=
+)abbrev domain DSMP DifferentialSparseMultivariatePolynomial
+++ Author: William Sit
+++ Date Created: 19 July 1990
+++ Date Last Updated: 13 September 1991
+++ Basic Operations:DifferentialPolynomialCategory
+++ Related Constructors:
+++ See Also:
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, ranking, differential polynomials,
+++ order, weight, leader, separant, initial, isobaric
+++ References:Kolchin, E.R. "Differential Algebra and Algebraic Groups"
+++ (Academic Press, 1973).
+++ Description:
+++ \spadtype{DifferentialSparseMultivariatePolynomial} implements
+++ an ordinary differential polynomial ring by combining a
+++ domain belonging to the category \spadtype{DifferentialVariableCategory}
+++ with the domain \spadtype{SparseMultivariatePolynomial}.
+++
+
+DifferentialSparseMultivariatePolynomial(R, S, V):
+ Exports == Implementation where
+ R: Ring
+ S: OrderedSet
+ V: DifferentialVariableCategory S
+ E ==> IndexedExponents(V)
+ PC ==> PolynomialCategory(R,IndexedExponents(V),V)
+ PCL ==> PolynomialCategoryLifting
+ P ==> SparseMultivariatePolynomial(R, V)
+ SUP ==> SparseUnivariatePolynomial
+ SMP ==> SparseMultivariatePolynomial(R, S)
+
+ Exports ==> Join(DifferentialPolynomialCategory(R,S,V,E),
+ RetractableTo SMP)
+
+ Implementation ==> P add
+ retractIfCan(p:$):Union(SMP, "failed") ==
+ zero? order p =>
+ map(retract(#1)@S :: SMP, #1::SMP, p)$PCL(
+ IndexedExponents V, V, R, $, SMP)
+ "failed"
+
+ coerce(p:SMP):$ ==
+ map(#1::V::$, #1::$, p)$PCL(IndexedExponents S, S, R, SMP, $)
+
+@
+\section{domain ODPOL OrderlyDifferentialPolynomial}
+<<domain ODPOL OrderlyDifferentialPolynomial>>=
+)abbrev domain ODPOL OrderlyDifferentialPolynomial
+++ Author: William Sit
+++ Date Created: 24 September, 1991
+++ Date Last Updated: 7 February, 1992
+++ Basic Operations:DifferentialPolynomialCategory
+++ Related Constructors: DifferentialSparseMultivariatePolynomial
+++ See Also:
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, ranking, differential polynomials,
+++ order, weight, leader, separant, initial, isobaric
+++ References:Kolchin, E.R. "Differential Algebra and Algebraic Groups"
+++ (Academic Press, 1973).
+++ Description:
+++ \spadtype{OrderlyDifferentialPolynomial} implements
+++ an ordinary differential polynomial ring in arbitrary number
+++ of differential indeterminates, with coefficients in a
+++ ring. The ranking on the differential indeterminate is orderly.
+++ This is analogous to the domain \spadtype{Polynomial}.
+++
+
+OrderlyDifferentialPolynomial(R):
+ Exports == Implementation where
+ R: Ring
+ S ==> Symbol
+ V ==> OrderlyDifferentialVariable S
+ E ==> IndexedExponents(V)
+ SMP ==> SparseMultivariatePolynomial(R, S)
+ Exports ==> Join(DifferentialPolynomialCategory(R,S,V,E),
+ RetractableTo SMP)
+
+ Implementation ==> DifferentialSparseMultivariatePolynomial(R,S,V)
+
+@
+\section{domain SDPOL SequentialDifferentialPolynomial}
+<<domain SDPOL SequentialDifferentialPolynomial>>=
+)abbrev domain SDPOL SequentialDifferentialPolynomial
+++ Author: William Sit
+++ Date Created: 24 September, 1991
+++ Date Last Updated: 7 February, 1992
+++ Basic Operations:DifferentialPolynomialCategory
+++ Related Constructors: DifferentialSparseMultivariatePolynomial
+++ See Also:
+++ AMS Classifications:12H05
+++ Keywords: differential indeterminates, ranking, differential polynomials,
+++ order, weight, leader, separant, initial, isobaric
+++ References:Kolchin, E.R. "Differential Algebra and Algebraic Groups"
+++ (Academic Press, 1973).
+++ Description:
+++ \spadtype{SequentialDifferentialPolynomial} implements
+++ an ordinary differential polynomial ring in arbitrary number
+++ of differential indeterminates, with coefficients in a
+++ ring. The ranking on the differential indeterminate is sequential.
+++
+
+SequentialDifferentialPolynomial(R):
+ Exports == Implementation where
+ R: Ring
+ S ==> Symbol
+ V ==> SequentialDifferentialVariable S
+ E ==> IndexedExponents(V)
+ SMP ==> SparseMultivariatePolynomial(R, S)
+ Exports ==> Join(DifferentialPolynomialCategory(R,S,V,E),
+ RetractableTo SMP)
+
+ Implementation ==> DifferentialSparseMultivariatePolynomial(R,S,V)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category DVARCAT DifferentialVariableCategory>>
+<<domain ODVAR OrderlyDifferentialVariable>>
+<<domain SDVAR SequentialDifferentialVariable>>
+<<category DPOLCAT DifferentialPolynomialCategory>>
+<<domain DSMP DifferentialSparseMultivariatePolynomial>>
+<<domain ODPOL OrderlyDifferentialPolynomial>>
+<<domain SDPOL SequentialDifferentialPolynomial>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/draw.spad.pamphlet b/src/algebra/draw.spad.pamphlet
new file mode 100644
index 00000000..de5dc3e3
--- /dev/null
+++ b/src/algebra/draw.spad.pamphlet
@@ -0,0 +1,1200 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra draw.spad}
+\author{Clifton J. Williamson, Scott Morrison, Jon Steinbach, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions}
+<<package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions>>=
+)abbrev package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions
+++ Author: Clifton J. Williamson
+++ Date Created: 22 June 1990
+++ Date Last Updated: January 1992 by Scott Morrison
+++ Basic Operations: draw, recolor
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TopLevelDrawFunctionsForCompiledFunctions provides top level
+++ functions for drawing graphics of expressions.
+TopLevelDrawFunctionsForCompiledFunctions():
+ Exports == Implementation where
+ ANY1 ==> AnyFunctions1
+ B ==> Boolean
+ F ==> Float
+ L ==> List
+ SEG ==> Segment Float
+ SF ==> DoubleFloat
+ DROP ==> DrawOption
+ PLOT ==> Plot
+ PPC ==> ParametricPlaneCurve(SF -> SF)
+ PSC ==> ParametricSpaceCurve(SF -> SF)
+ PSF ==> ParametricSurface((SF,SF) -> SF)
+ Pt ==> Point SF
+ PSFUN ==> (SF, SF) -> Pt
+ PCFUN ==> SF -> Pt
+ SPACE3 ==> ThreeSpace(SF)
+ VIEW2 ==> TwoDimensionalViewport
+ VIEW3 ==> ThreeDimensionalViewport
+
+ Exports ==> with
+
+--% Two Dimensional Function Plots
+
+ draw: (SF -> SF,SEG,L DROP) -> VIEW2
+ ++ draw(f,a..b,l) draws the graph of \spad{y = f(x)} as x
+ ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}.
+ ++ The options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ draw: (SF -> SF,SEG) -> VIEW2
+ ++ draw(f,a..b) draws the graph of \spad{y = f(x)} as x
+ ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}.
+
+--% Parametric Plane Curves
+
+ draw: (PPC,SEG,L DROP) -> VIEW2
+ ++ draw(curve(f,g),a..b,l) draws the graph of the parametric
+ ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)}.
+ ++ The options contained in the list l of the domain \spad{DrawOption}
+ ++ are applied.
+ draw: (PPC,SEG) -> VIEW2
+ ++ draw(curve(f,g),a..b) draws the graph of the parametric
+ ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)}.
+
+--% Parametric Space Curves
+
+ draw: (PSC,SEG,L DROP) -> VIEW3
+ ++ draw(curve(f,g,h),a..b,l) draws the graph of the parametric
+ ++ curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from
+ ++ \spad{min(a,b)} to \spad{max(a,b)}.
+ ++ The options contained in the list l of the domain
+ ++ \spad{DrawOption} are applied.
+ draw: (PSC,SEG) -> VIEW3
+ ++ draw(curve(f,g,h),a..b,l) draws the graph of the parametric
+ ++ curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from
+ ++ \spad{min(a,b)} to \spad{max(a,b)}.
+ draw: (PCFUN,SEG,L DROP) -> VIEW3
+ ++ draw(f,a..b,l) draws the graph of the parametric
+ ++ curve \spad{f} as t ranges from
+ ++ \spad{min(a,b)} to \spad{max(a,b)}.
+ ++ The options contained in the list l of the domain
+ ++ \spad{DrawOption} are applied.
+ draw: (PCFUN,SEG) -> VIEW3
+ ++ draw(f,a..b,l) draws the graph of the parametric
+ ++ curve \spad{f} as t ranges from
+ ++ \spad{min(a,b)} to \spad{max(a,b)}.
+
+ makeObject: (PSC,SEG,L DROP) -> SPACE3
+ ++ makeObject(curve(f,g,h),a..b,l) returns a space of the
+ ++ domain \spadtype{ThreeSpace} which contains the graph of the
+ ++ parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from
+ ++ \spad{min(a,b)} to \spad{max(a,b)};
+ ++ The options contained in the list l of the domain
+ ++ \spad{DrawOption} are applied.
+ makeObject: (PSC,SEG) -> SPACE3
+ ++ makeObject(sp,curve(f,g,h),a..b) returns the space \spad{sp}
+ ++ of the domain \spadtype{ThreeSpace} with the addition of the graph
+ ++ of the parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t
+ ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}.
+ makeObject: (PCFUN,SEG,L DROP) -> SPACE3
+ ++ makeObject(curve(f,g,h),a..b,l) returns a space of the
+ ++ domain \spadtype{ThreeSpace} which contains the graph of the
+ ++ parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t ranges from
+ ++ \spad{min(a,b)} to \spad{max(a,b)}.
+ ++ The options contained in the list l of the domain
+ ++ \spad{DrawOption} are applied.
+ makeObject: (PCFUN,SEG) -> SPACE3
+ ++ makeObject(sp,curve(f,g,h),a..b) returns the space \spad{sp}
+ ++ of the domain \spadtype{ThreeSpace} with the addition of the graph
+ ++ of the parametric curve \spad{x = f(t), y = g(t), z = h(t)} as t
+ ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}.
+
+--% Three Dimensional Function Plots
+
+ draw: ((SF,SF) -> SF,SEG,SEG,L DROP) -> VIEW3
+ ++ draw(f,a..b,c..d,l) draws the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}.
+ ++ and the options contained in the list l of the domain
+ ++ \spad{DrawOption} are applied.
+ draw: ((SF,SF) -> SF,SEG,SEG) -> VIEW3
+ ++ draw(f,a..b,c..d) draws the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}.
+ makeObject: ((SF,SF) -> SF,SEG,SEG,L DROP) -> SPACE3
+ ++ makeObject(f,a..b,c..d,l) returns a space of the domain
+ ++ \spadtype{ThreeSpace} which contains the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}, and the options contained in the
+ ++ list l of the domain \spad{DrawOption} are applied.
+ makeObject: ((SF,SF) -> SF,SEG,SEG) -> SPACE3
+ ++ makeObject(f,a..b,c..d) returns a space of the domain
+ ++ \spadtype{ThreeSpace} which contains the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}.
+
+--% Parametric Surfaces
+
+ draw: (PSFUN, SEG, SEG, L DROP) -> VIEW3
+ ++ draw(f,a..b,c..d) draws the
+ ++ graph of the parametric surface \spad{f(u,v)}
+ ++ as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}.
+ ++ The options contained in the
+ ++ list l of the domain \spad{DrawOption} are applied.
+ draw: (PSFUN, SEG, SEG) -> VIEW3
+ ++ draw(f,a..b,c..d) draws the
+ ++ graph of the parametric surface \spad{f(u,v)}
+ ++ as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}
+ ++ The options contained in the list
+ ++ l of the domain \spad{DrawOption} are applied.
+ makeObject: (PSFUN, SEG, SEG, L DROP) -> SPACE3
+ ++ makeObject(f,a..b,c..d,l) returns a
+ ++ space of the domain \spadtype{ThreeSpace} which contains the
+ ++ graph of the parametric surface \spad{f(u,v)}
+ ++ as u ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)};
+ ++ The options contained in the
+ ++ list l of the domain \spad{DrawOption} are applied.
+ makeObject: (PSFUN, SEG, SEG) -> SPACE3
+ ++ makeObject(f,a..b,c..d,l) returns a
+ ++ space of the domain \spadtype{ThreeSpace} which contains the
+ ++ graph of the parametric surface \spad{f(u,v)}
+ ++ as u ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}.
+ draw: (PSF,SEG,SEG,L DROP) -> VIEW3
+ ++ draw(surface(f,g,h),a..b,c..d) draws the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)};
+ ++ The options contained in the
+ ++ list l of the domain \spad{DrawOption} are applied.
+ draw: (PSF,SEG,SEG) -> VIEW3
+ ++ draw(surface(f,g,h),a..b,c..d) draws the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)};
+ makeObject: (PSF,SEG,SEG,L DROP) -> SPACE3
+ ++ makeObject(surface(f,g,h),a..b,c..d,l) returns a
+ ++ space of the domain \spadtype{ThreeSpace} which contains the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}.
+ ++ The options contained in the
+ ++ list l of the domain \spad{DrawOption} are applied.
+ makeObject: (PSF,SEG,SEG) -> SPACE3
+ ++ makeObject(surface(f,g,h),a..b,c..d,l) returns a
+ ++ space of the domain \spadtype{ThreeSpace} which contains the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)} and v ranges from \spad{min(c,d)} to \spad{max(c,d)}.
+ recolor: ((SF,SF) -> Pt,(SF,SF,SF) -> SF) -> ((SF,SF) -> Pt)
+ ++ recolor(), uninteresting to top level user; exported in order to
+ ++ compile package.
+
+ Implementation ==> add
+ --!! I have had to work my way around the following bug in the compiler:
+ --!! When a local variable is given a mapping as a value, e.g.
+ --!! foo : SF -> SF := makeFloatFunction(f,t),
+ --!! the compiler cannot distinguish that local variable from a local
+ --!! function defined elsewhere in the package. Thus, when 'foo' is
+ --!! passed to a function, e.g.
+ --!! bird := fcn(foo),
+ --!! foo will often be compiled as |DRAW;foo| rather than |foo|. This,
+ --!! of course, causes a run-time error.
+ --!! To avoid this problem, local variables are not given mappings as
+ --!! values, but rather (singleton) lists of mappings. The first element
+ --!! of the list can always be extracted and everything goes through
+ --!! as before. There is no major loss in efficiency, as the computation
+ --!! of points will always dominate the computation time.
+ --!! - cjw, 22 June MCMXC
+
+ import PLOT
+ import TwoDimensionalPlotClipping
+ import GraphicsDefaults
+ import ViewportPackage
+ import ThreeDimensionalViewport
+ import DrawOptionFunctions0
+ import MakeFloatCompiledFunction(Ex)
+ import MeshCreationRoutinesForThreeDimensions
+ import SegmentFunctions2(SF,Float)
+ import ViewDefaultsPackage
+ import AnyFunctions1(Pt -> Pt)
+ import AnyFunctions1((SF,SF,SF) -> SF)
+ import DrawOptionFunctions0
+ import SPACE3
+
+ EXTOVARERROR : String := _
+ "draw: when specifying function, left hand side must be a variable"
+ SMALLRANGEERROR : String := _
+ "draw: range is in interval with only one point"
+ DEPVARERROR : String := _
+ "draw: independent variable appears on lhs of function definition"
+
+------------------------------------------------------------------------
+-- 2D - draw's
+------------------------------------------------------------------------
+
+ drawToScaleRanges: (Segment SF,Segment SF) -> L SEG
+ drawToScaleRanges(xVals,yVals) ==
+ -- warning: assumes window is square
+ xHi := convert(hi xVals)@Float; xLo := convert(lo xVals)@Float
+ yHi := convert(hi yVals)@Float; yLo := convert(lo yVals)@Float
+ xDiff := xHi - xLo; yDiff := yHi - yLo
+ pad := abs(yDiff - xDiff)/2
+ yDiff > xDiff =>
+ [segment(xLo - pad,xHi + pad),map(convert(#1)@Float,yVals)]
+ [map(convert(#1)@Float,xVals),segment(yLo - pad,yHi + pad)]
+
+ drawPlot: (PLOT,L DROP) -> VIEW2
+ drawPlot(plot,l) ==
+ branches := listBranches plot
+ xRange := xRange plot; yRange := yRange plot
+ -- process clipping information
+ if (cl := option(l,"clipSegment" :: Symbol)) case "failed" then
+ if clipBoolean(l,clipPointsDefault()) then
+ clipInfo :=
+ parametric? plot => clipParametric plot
+ clip plot
+ branches := clipInfo.brans
+ xRange := clipInfo.xValues; yRange := clipInfo.yValues
+ else
+ "No explicit user-specified clipping"
+ else
+ segList := retract(cl :: Any)$ANY1(L SEG)
+ empty? segList =>
+ error "draw: you may specify at least 1 segment for 2D clipping"
+ more?(segList,2) =>
+ error "draw: you may specify at most 2 segments for 2D clipping"
+ xLo : SF := 0; xHi : SF := 0; yLo : SF := 0; yHi : SF := 0
+ if empty? rest segList then
+ xLo := lo xRange; xHi := hi xRange
+ yRangeF := first segList
+ yLo := convert(lo yRangeF)@SF; yHi := convert(hi yRangeF)@SF
+ else
+ xRangeF := first segList
+ xLo := convert(lo xRangeF)@SF; xHi := convert(hi xRangeF)@SF
+ yRangeF := second segList
+ yLo := convert(lo yRangeF)@SF; yHi := convert(hi yRangeF)@SF
+ clipInfo := clipWithRanges(branches,xLo,xHi,yLo,yHi)
+ branches := clipInfo.brans
+ xRange := clipInfo.xValues; yRange := clipInfo.yValues
+ -- process scaling information
+ if toScale(l,drawToScale()) then
+ scaledRanges := drawToScaleRanges(xRange,yRange)
+ -- add scaled ranges to list of options
+ l := concat(ranges scaledRanges,l)
+ else
+ xRangeFloat : SEG := map(convert(#1)@Float,xRange)
+ yRangeFloat : SEG := map(convert(#1)@Float,yRange)
+ -- add ranges to list of options
+ l := concat(ranges(ll : L SEG := [xRangeFloat,yRangeFloat]),l)
+ -- process color information
+ ptCol := pointColorPalette(l,pointColorDefault())
+ crCol := curveColorPalette(l,lineColorDefault())
+ -- draw
+ drawCurves(branches,ptCol,crCol,pointSizeDefault(),l)
+
+ normalize: SEG -> Segment SF
+ normalize seg ==
+ -- normalize [a,b]:
+ -- error if a = b, returns [a,b] if a < b, returns [b,a] if b > a
+ a := convert(lo seg)@SF; b := convert(hi seg)@SF
+ a = b => error SMALLRANGEERROR
+ a < b => segment(a,b)
+ segment(b,a)
+
+--% functions for creation of maps SF -> Point SF (two dimensional)
+
+ myTrap1: (SF-> SF, SF) -> SF
+ myTrap1(ff:SF-> SF, f:SF):SF ==
+ s := trapNumericErrors(ff(f))$Lisp :: Union(SF, "failed")
+ s case "failed" => _$NaNvalue$Lisp
+ r:=s::SF
+ r >max()$SF or r < min()$SF => _$NaNvalue$Lisp
+ r
+
+ makePt2: (SF,SF) -> Point SF
+ makePt2(x,y) == point(l : List SF := [x,y])
+
+--% Two Dimensional Function Plots
+
+ draw(f:SF -> SF,seg:SEG,l:L DROP) ==
+ -- set adaptive plotting off or on
+ oldAdaptive := adaptive?()$PLOT
+ setAdaptive(adaptive(l,oldAdaptive))$PLOT
+ -- create function SF -> Point SF
+ ff : L(SF -> Point SF) := [makePt2(myTrap1(f,#1),#1)]
+ -- process change of coordinates
+ if (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ -- default coordinate transformation
+ ff := [makePt2(#1,myTrap1(f,#1))]
+ else
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ ff := [(first cc)((first ff)(#1))]
+ -- create PLOT
+ pl := pointPlot(first ff,normalize seg)
+ -- reset adaptive plotting
+ setAdaptive(oldAdaptive)$PLOT
+ -- draw
+ drawPlot(pl,l)
+
+ draw(f:SF -> SF,seg:SEG) == draw(f,seg,nil())
+
+--% Parametric Plane Curves
+
+ draw(ppc:PPC,seg:SEG,l:L DROP) ==
+ -- set adaptive plotting off or on
+ oldAdaptive := adaptive?()$PLOT
+ setAdaptive(adaptive(l,oldAdaptive))$PLOT
+ -- create function SF -> Point SF
+ f := coordinate(ppc,1); g := coordinate(ppc,2)
+ fcn : L(SF -> Pt) := [makePt2(myTrap1(f,#1),myTrap1(g,#1))]
+ -- process change of coordinates
+ if not (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ fcn := [(first cc)((first fcn)(#1))]
+ -- create PLOT
+ pl := pointPlot(first fcn,normalize seg)
+ -- reset adaptive plotting
+ setAdaptive(oldAdaptive)$PLOT
+ -- draw
+ drawPlot(pl,l)
+
+ draw(ppc:PPC,seg:SEG) == draw(ppc,seg,nil())
+
+------------------------------------------------------------------------
+-- 3D - Curves
+------------------------------------------------------------------------
+
+--% functions for creation of maps SF -> Point SF (three dimensional)
+
+ makePt4: (SF,SF,SF,SF) -> Point SF
+ makePt4(x,y,z,c) == point(l : List SF := [x,y,z,c])
+
+--% Parametric Space Curves
+
+ id: SF -> SF
+ id x == x
+
+ zCoord: (SF,SF,SF) -> SF
+ zCoord(x,y,z) == z
+
+ colorPoints: (List List Pt,(SF,SF,SF) -> SF) -> List List Pt
+ colorPoints(llp,func) ==
+ for lp in llp repeat for p in lp repeat
+ p.4 := func(p.1,p.2,p.3)
+ llp
+
+ makeObject(psc:PSC,seg:SEG,l:L DROP) ==
+ sp := space l
+ -- obtain dependent variable and coordinate functions
+ f := coordinate(psc,1); g := coordinate(psc,2); h := coordinate(psc,3)
+ -- create function SF -> Point SF with default or user-specified
+ -- color function
+ fcn : L(SF -> Pt) := [makePt4(myTrap1(f,#1),myTrap1(g,#1),myTrap1(h,#1),_
+ myTrap1(id,#1))]
+ pointsColored? : Boolean := false
+ if not (c1 := option(l,"colorFunction1" :: Symbol)) case "failed" then
+ pointsColored? := true
+ fcn := [makePt4(myTrap1(f,#1),myTrap1(g,#1),myTrap1(h,#1),_
+ retract(c1 :: Any)$ANY1(SF -> SF)(#1))]
+ -- process change of coordinates
+ if not (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ fcn := [(first cc)((first fcn)(#1))]
+ -- create PLOT
+ pl := pointPlot(first fcn,normalize seg)$Plot3D
+ -- create ThreeSpace
+ s := sp
+ -- draw Tube
+-- print(pl::OutputForm)
+ option?(l,"tubeRadius" :: Symbol) =>
+ pts := tubePoints(l,8)
+ rad := convert(tubeRadius(l,0.25))@DoubleFloat
+ tub := tube(pl,rad,pts)$NumericTubePlot(Plot3D)
+ loops := listLoops tub
+ -- color points if this has not been done already
+ if not pointsColored? then
+ if (c3 := option(l,"colorFunction3" :: Symbol)) case "failed"
+ then colorPoints(loops,zCoord) -- default color function
+ else colorPoints(loops,retract(c3 :: Any)$ANY1((SF,SF,SF) -> SF))
+ mesh(s,loops,false,false)
+ s
+ -- draw curve
+ br := listBranches pl
+ for b in br repeat curve(s,b)
+ s
+
+ makeObject(psc:PCFUN,seg:SEG,l:L DROP) ==
+ sp := space l
+ -- create function SF -> Point SF with default or user-specified
+ -- color function
+ fcn : L(SF -> Pt) := [psc]
+ pointsColored? : Boolean := false
+ if not (c1 := option(l,"colorFunction1" :: Symbol)) case "failed" then
+ pointsColored? := true
+ fcn := [concat(psc(#1), retract(c1 :: Any)$ANY1(SF -> SF)(#1))]
+ -- process change of coordinates
+ if not (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ fcn := [(first cc)((first fcn)(#1))]
+ -- create PLOT
+ pl := pointPlot(first fcn,normalize seg)$Plot3D
+ -- create ThreeSpace
+ s := sp
+ -- draw Tube
+ option?(l,"tubeRadius" :: Symbol) =>
+ pts := tubePoints(l,8)
+ rad := convert(tubeRadius(l,0.25))@DoubleFloat
+ tub := tube(pl,rad,pts)$NumericTubePlot(Plot3D)
+ loops := listLoops tub
+ -- color points if this has not been done already
+ mesh(s,loops,false,false)
+ s
+ -- draw curve
+ br := listBranches pl
+ for b in br repeat curve(s,b)
+ s
+
+ makeObject(psc:PSC,seg:SEG) ==
+ makeObject(psc,seg,nil())
+
+ makeObject(psc:PCFUN,seg:SEG) ==
+ makeObject(psc,seg,nil())
+
+ draw(psc:PSC,seg:SEG,l:L DROP) ==
+ sp := makeObject(psc,seg,l)
+ makeViewport3D(sp, l)
+
+ draw(psc:PSC,seg:SEG) ==
+ draw(psc,seg,nil())
+
+ draw(psc:PCFUN,seg:SEG,l:L DROP) ==
+ sp := makeObject(psc,seg,l)
+ makeViewport3D(sp, l)
+
+ draw(psc:PCFUN,seg:SEG) ==
+ draw(psc,seg,nil())
+
+------------------------------------------------------------------------
+-- 3D - Surfaces
+------------------------------------------------------------------------
+
+ myTrap2: ((SF, SF) -> SF, SF, SF) -> SF
+ myTrap2(ff:(SF, SF) -> SF, u:SF, v:SF):SF ==
+ s := trapNumericErrors(ff(u, v))$Lisp :: Union(SF, "failed")
+ s case "failed" => _$NaNvalue$Lisp
+ r:SF := s::SF
+ r >max()$SF or r < min()$SF => _$NaNvalue$Lisp
+ r
+
+ recolor(ptFunc,colFunc) ==
+ pt := ptFunc(#1,#2)
+ pt.4 := colFunc(pt.1,pt.2,pt.3)
+ pt
+
+ xCoord: (SF,SF) -> SF
+ xCoord(x,y) == x
+
+--% Three Dimensional Function Plots
+
+ makeObject(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG,l:L DROP) ==
+ sp := space l
+ -- process color function of two variables
+ col2 : L((SF,SF) -> SF) := [xCoord] -- dummy color function
+ pointsColored? : Boolean := false
+ if not (c2 := option(l,"colorFunction2" :: Symbol)) case "failed" then
+ pointsColored? := true
+ col2 := [retract(c2 :: Any)$ANY1((SF,SF) -> SF)]
+ fcn : L((SF,SF) -> Pt) :=
+ [makePt4(myTrap2(f,#1,#2),#1,#2,(first col2)(#1,#2))]
+ -- process change of coordinates
+ if (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ -- default coordinate transformation
+ fcn := [makePt4(#1,#2,myTrap2(f,#1,#2),(first col2)(#1,#2))]
+ else
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ fcn := [(first cc)((first fcn)(#1,#2))]
+ -- process color function of three variables, if there was no
+ -- color function of two variables
+ if not pointsColored? then
+ c := option(l,"colorFunction3" :: Symbol)
+ fcn :=
+ c case "failed" => [recolor((first fcn),zCoord)]
+ [recolor((first fcn),retract(c :: Any)$ANY1((SF,SF,SF) -> SF))]
+ -- create mesh
+ mesh := meshPar2Var(sp,first fcn,normalize xSeg,normalize ySeg,l)
+ mesh
+
+ makeObject(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG) ==
+ makeObject(f,xSeg,ySeg,nil())
+
+ draw(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG,l:L DROP) ==
+ sp := makeObject(f, xSeg, ySeg, l)
+ makeViewport3D(sp, l)
+
+ draw(f:(SF,SF) -> SF,xSeg:SEG,ySeg:SEG) ==
+ draw(f,xSeg,ySeg,nil())
+
+--% parametric surface
+
+ makeObject(s:PSF,uSeg:SEG,vSeg:SEG,l:L DROP) ==
+ sp := space l
+ -- create functions from expressions
+ f : L((SF,SF) -> SF) := [coordinate(s,1)]
+ g : L((SF,SF) -> SF) := [coordinate(s,2)]
+ h : L((SF,SF) -> SF) := [coordinate(s,3)]
+ -- process color function of two variables
+ col2 : L((SF,SF) -> SF) := [xCoord] -- dummy color function
+ pointsColored? : Boolean := false
+ if not (c2 := option(l,"colorFunction2" :: Symbol)) case "failed" then
+ pointsColored? := true
+ col2 := [retract(c2 :: Any)$ANY1((SF,SF) -> SF)]
+ fcn : L((SF,SF) -> Pt) :=
+ [makePt4(myTrap2((first f),#1,#2),myTrap2((first g),#1,#2),myTrap2((first h),#1,#2),_
+ myTrap2((first col2),#1,#2))]
+ -- process change of coordinates
+ if not (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ fcn := [(first cc)((first fcn)(#1,#2))]
+ -- process color function of three variables, if there was no
+ -- color function of two variables
+ if not pointsColored? then
+ col3 : L((SF,SF,SF) -> SF) := [zCoord] -- default color function
+ if not (c := option(l,"colorFunction3" :: Symbol)) case "failed" then
+ col3 := [retract(c :: Any)$ANY1((SF,SF,SF) -> SF)]
+ fcn := [recolor((first fcn),(first col3))]
+ -- create mesh
+ mesh := meshPar2Var(sp,first fcn,normalize uSeg,normalize vSeg,l)
+ mesh
+
+ makeObject(s:PSFUN,uSeg:SEG,vSeg:SEG,l:L DROP) ==
+ sp := space l
+ -- process color function of two variables
+ col2 : L((SF,SF) -> SF) := [xCoord] -- dummy color function
+ pointsColored? : Boolean := false
+ if not (c2 := option(l,"colorFunction2" :: Symbol)) case "failed" then
+ pointsColored? := true
+ col2 := [retract(c2 :: Any)$ANY1((SF,SF) -> SF)]
+ fcn : L((SF,SF) -> Pt) :=
+ pointsColored? => [concat(s(#1, #2), (first col2)(#1, #2))]
+ [s]
+ -- process change of coordinates
+ if not (c := option(l,"coordinates" :: Symbol)) case "failed" then
+ cc : L(Pt -> Pt) := [retract(c :: Any)$ANY1(Pt -> Pt)]
+ fcn := [(first cc)((first fcn)(#1,#2))]
+ -- create mesh
+ mesh := meshPar2Var(sp,first fcn,normalize uSeg,normalize vSeg,l)
+ mesh
+
+ makeObject(s:PSF,uSeg:SEG,vSeg:SEG) ==
+ makeObject(s,uSeg,vSeg,nil())
+
+ draw(s:PSF,uSeg:SEG,vSeg:SEG,l:L DROP) ==
+ -- draw
+ mesh := makeObject(s,uSeg,vSeg,l)
+ makeViewport3D(mesh,l)
+
+ draw(s:PSF,uSeg:SEG,vSeg:SEG) ==
+ draw(s,uSeg,vSeg,nil())
+
+ makeObject(s:PSFUN,uSeg:SEG,vSeg:SEG) ==
+ makeObject(s,uSeg,vSeg,nil())
+
+ draw(s:PSFUN,uSeg:SEG,vSeg:SEG,l:L DROP) ==
+ -- draw
+ mesh := makeObject(s,uSeg,vSeg,l)
+ makeViewport3D(mesh,l)
+
+ draw(s:PSFUN,uSeg:SEG,vSeg:SEG) ==
+ draw(s,uSeg,vSeg,nil())
+
+@
+\section{package DRAW TopLevelDrawFunctions}
+<<package DRAW TopLevelDrawFunctions>>=
+)abbrev package DRAW TopLevelDrawFunctions
+++ Author: Clifton J. Williamson
+++ Date Created: 23 January 1990
+++ Date Last Updated: October 1991 by Jon Steinbach
+++ Basic Operations: draw
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TopLevelDrawFunctions provides top level functions for
+++ drawing graphics of expressions.
+TopLevelDrawFunctions(Ex:Join(ConvertibleTo InputForm,SetCategory)):
+ Exports == Implementation where
+ B ==> Boolean
+ BIND ==> SegmentBinding Float
+ L ==> List
+ SF ==> DoubleFloat
+ DROP ==> DrawOption
+
+ PPC ==> ParametricPlaneCurve Ex
+ PPCF ==> ParametricPlaneCurve(SF -> SF)
+ PSC ==> ParametricSpaceCurve Ex
+ PSCF ==> ParametricSpaceCurve(SF -> SF)
+ PSF ==> ParametricSurface Ex
+ PSFF ==> ParametricSurface((SF,SF) -> SF)
+ SPACE3 ==> ThreeSpace(SF)
+ VIEW2 ==> TwoDimensionalViewport
+ VIEW3 ==> ThreeDimensionalViewport
+
+ Exports ==> with
+
+--% Two Dimensional Function Plots
+
+ draw: (Ex,BIND,L DROP) -> VIEW2
+ ++ draw(f(x),x = a..b,l) draws the graph of \spad{y = f(x)} as x
+ ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{f(x)} is the
+ ++ default title, and the options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ draw: (Ex,BIND) -> VIEW2
+ ++ draw(f(x),x = a..b) draws the graph of \spad{y = f(x)} as x
+ ++ ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{f(x)} appears
+ ++ in the title bar.
+
+--% Parametric Plane Curves
+
+ draw: (PPC,BIND,L DROP) -> VIEW2
+ ++ draw(curve(f(t),g(t)),t = a..b,l) draws the graph of the parametric
+ ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)}; \spad{(f(t),g(t))} is the default title, and the
+ ++ options contained in the list l of the domain \spad{DrawOption}
+ ++ are applied.
+ draw: (PPC,BIND) -> VIEW2
+ ++ draw(curve(f(t),g(t)),t = a..b) draws the graph of the parametric
+ ++ curve \spad{x = f(t), y = g(t)} as t ranges from \spad{min(a,b)} to
+ ++ \spad{max(a,b)}; \spad{(f(t),g(t))} appears in the title bar.
+
+--% Parametric Space Curves
+
+ draw: (PSC,BIND,L DROP) -> VIEW3
+ ++ draw(curve(f(t),g(t),h(t)),t = a..b,l) draws the graph of the
+ ++ parametric curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)}
+ ++ as t ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)}
+ ++ is the default title, and the options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ draw: (PSC,BIND) -> VIEW3
+ ++ draw(curve(f(t),g(t),h(t)),t = a..b) draws the graph of the parametric
+ ++ curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)} as t ranges
+ ++ from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)} is the default
+ ++ title.
+ makeObject: (PSC,BIND,L DROP) -> SPACE3
+ ++ makeObject(curve(f(t),g(t),h(t)),t = a..b,l) returns a space of
+ ++ the domain \spadtype{ThreeSpace} which contains the graph of the
+ ++ parametric curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)}
+ ++ as t ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)}
+ ++ is the default title, and the options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ makeObject: (PSC,BIND) -> SPACE3
+ ++ makeObject(curve(f(t),g(t),h(t)),t = a..b) returns a space of the
+ ++ domain \spadtype{ThreeSpace} which contains the graph of the
+ ++ parametric curve \spad{x = f(t)}, \spad{y = g(t)}, \spad{z = h(t)}
+ ++ as t ranges from \spad{min(a,b)} to \spad{max(a,b)}; \spad{h(t)} is
+ ++ the default title.
+
+--% Three Dimensional Function Plots
+
+ draw: (Ex,BIND,BIND,L DROP) -> VIEW3
+ ++ draw(f(x,y),x = a..b,y = c..d,l) draws the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} is the default
+ ++ title, and the options contained in the list l of the domain
+ ++ \spad{DrawOption} are applied.
+ draw: (Ex,BIND,BIND) -> VIEW3
+ ++ draw(f(x,y),x = a..b,y = c..d) draws the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} appears in the title bar.
+ makeObject: (Ex,BIND,BIND,L DROP) -> SPACE3
+ ++ makeObject(f(x,y),x = a..b,y = c..d,l) returns a space of the
+ ++ domain \spadtype{ThreeSpace} which contains the graph of
+ ++ \spad{z = f(x,y)} as x ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and y ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)}
+ ++ is the default title, and the options contained in the list l of the
+ ++ domain \spad{DrawOption} are applied.
+ makeObject: (Ex,BIND,BIND) -> SPACE3
+ ++ makeObject(f(x,y),x = a..b,y = c..d) returns a space of the domain
+ ++ \spadtype{ThreeSpace} which contains the graph of \spad{z = f(x,y)}
+ ++ as x ranges from \spad{min(a,b)} to \spad{max(a,b)} and y ranges from
+ ++ \spad{min(c,d)} to \spad{max(c,d)}; \spad{f(x,y)} appears as the
+ ++ default title.
+
+--% Parametric Surfaces
+
+ draw: (PSF,BIND,BIND,L DROP) -> VIEW3
+ ++ draw(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d,l) draws the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)}
+ ++ is the default title, and the options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ draw: (PSF,BIND,BIND) -> VIEW3
+ ++ draw(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d) draws the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} is
+ ++ the default title.
+ makeObject: (PSF,BIND,BIND,L DROP) -> SPACE3
+ ++ makeObject(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d,l) returns
+ ++ a space of the domain \spadtype{ThreeSpace} which contains the graph
+ ++ of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} is
+ ++ the default title, and the options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ makeObject: (PSF,BIND,BIND) -> SPACE3
+ ++ makeObject(surface(f(u,v),g(u,v),h(u,v)),u = a..b,v = c..d) returns
+ ++ a space of the domain \spadtype{ThreeSpace} which contains the
+ ++ graph of the parametric surface \spad{x = f(u,v)}, \spad{y = g(u,v)},
+ ++ \spad{z = h(u,v)} as u ranges from \spad{min(a,b)} to \spad{max(a,b)}
+ ++ and v ranges from \spad{min(c,d)} to \spad{max(c,d)}; \spad{h(t)} is
+ ++ the default title.
+
+ Implementation ==> add
+ import TopLevelDrawFunctionsForCompiledFunctions
+ import MakeFloatCompiledFunction(Ex)
+ import ParametricPlaneCurve(SF -> SF)
+ import ParametricSpaceCurve(SF -> SF)
+ import ParametricSurface((SF,SF) -> SF)
+ import ThreeSpace(SF)
+
+------------------------------------------------------------------------
+-- 2D - draw's (given by formulae)
+------------------------------------------------------------------------
+
+--% Two Dimensional Function Plots
+
+ draw(f:Ex,bind:BIND,l:L DROP) ==
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM2D",l)
+ else l := concat(title s,l)
+ -- call 'draw'
+ draw(makeFloatFunction(f,variable bind),segment bind,l)
+
+ draw(f:Ex,bind:BIND) == draw(f,bind,nil())
+
+--% Parametric Plane Curves
+
+ draw(ppc:PPC,bind:BIND,l:L DROP) ==
+ f := coordinate(ppc,1); g := coordinate(ppc,2)
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM2D",l)
+ else l := concat(title s,l)
+ -- create curve with functions as coordinates
+ curve : PPCF := curve(makeFloatFunction(f,variable bind),_
+ makeFloatFunction(g,variable bind))$PPCF
+ -- call 'draw'
+ draw(curve,segment bind,l)
+
+ draw(ppc:PPC,bind:BIND) == draw(ppc,bind,nil())
+
+------------------------------------------------------------------------
+-- 3D - Curves (given by formulas)
+------------------------------------------------------------------------
+
+ makeObject(psc:PSC,tBind:BIND,l:L DROP) ==
+ -- obtain dependent variable and coordinate functions
+ t := variable tBind; tSeg := segment tBind
+ f := coordinate(psc,1); g := coordinate(psc,2); h := coordinate(psc,3)
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM3D",l)
+ else l := concat(title s,l)
+ -- indicate draw style if necessary
+ if not option?(l,"style" :: Symbol) then
+ l := concat(style unparse(convert(f)@InputForm),l)
+ -- create curve with functions as coordinates
+ curve : PSCF := curve(makeFloatFunction(f,t),_
+ makeFloatFunction(g,t),_
+ makeFloatFunction(h,t))
+ -- call 'draw'
+ makeObject(curve,tSeg,l)
+
+ makeObject(psc:PSC,tBind:BIND) ==
+ makeObject(psc,tBind,nil())
+
+ draw(psc:PSC,tBind:BIND,l:L DROP) ==
+ -- obtain dependent variable and coordinate functions
+ t := variable tBind; tSeg := segment tBind
+ f := coordinate(psc,1); g := coordinate(psc,2); h := coordinate(psc,3)
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM3D",l)
+ else l := concat(title s,l)
+ -- indicate draw style if necessary
+ if not option?(l,"style" :: Symbol) then
+ l := concat(style unparse(convert(f)@InputForm),l)
+ -- create curve with functions as coordinates
+ curve : PSCF := curve(makeFloatFunction(f,t),_
+ makeFloatFunction(g,t),_
+ makeFloatFunction(h,t))
+ -- call 'draw'
+ draw(curve,tSeg,l)
+
+ draw(psc:PSC,tBind:BIND) ==
+ draw(psc,tBind,nil())
+
+------------------------------------------------------------------------
+-- 3D - Surfaces (given by formulas)
+------------------------------------------------------------------------
+
+--% Three Dimensional Function Plots
+
+ makeObject(f:Ex,xBind:BIND,yBind:BIND,l:L DROP) ==
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM3D",l)
+ else l := concat(title s,l)
+ -- indicate draw style if necessary
+ if not option?(l,"style" :: Symbol) then
+ l := concat(style unparse(convert(f)@InputForm),l)
+ -- obtain dependent variables and their ranges
+ x := variable xBind; xSeg := segment xBind
+ y := variable yBind; ySeg := segment yBind
+ -- call 'draw'
+ makeObject(makeFloatFunction(f,x,y),xSeg,ySeg,l)
+
+ makeObject(f:Ex,xBind:BIND,yBind:BIND) ==
+ makeObject(f,xBind,yBind,nil())
+
+ draw(f:Ex,xBind:BIND,yBind:BIND,l:L DROP) ==
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM3D",l)
+ else l := concat(title s,l)
+ -- indicate draw style if necessary
+ if not option?(l,"style" :: Symbol) then
+ l := concat(style unparse(convert(f)@InputForm),l)
+ -- obtain dependent variables and their ranges
+ x := variable xBind; xSeg := segment xBind
+ y := variable yBind; ySeg := segment yBind
+ -- call 'draw'
+ draw(makeFloatFunction(f,x,y),xSeg,ySeg,l)
+
+ draw(f:Ex,xBind:BIND,yBind:BIND) ==
+ draw(f,xBind,yBind,nil())
+
+--% parametric surface
+
+ makeObject(s:PSF,uBind:BIND,vBind:BIND,l:L DROP) ==
+ f := coordinate(s,1); g := coordinate(s,2); h := coordinate(s,3)
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM3D",l)
+ else l := concat(title s,l)
+ if not option?(l,"style" :: Symbol) then
+ l := concat(style unparse(convert(f)@InputForm),l)
+ u := variable uBind; uSeg := segment uBind
+ v := variable vBind; vSeg := segment vBind
+ surf : PSFF := surface(makeFloatFunction(f,u,v),_
+ makeFloatFunction(g,u,v),_
+ makeFloatFunction(h,u,v))
+ makeObject(surf,uSeg,vSeg,l)
+
+ makeObject(s:PSF,uBind:BIND,vBind:BIND) ==
+ makeObject(s,uBind,vBind,nil())
+
+ draw(s:PSF,uBind:BIND,vBind:BIND,l:L DROP) ==
+ f := coordinate(s,1); g := coordinate(s,2); h := coordinate(s,3)
+ -- create title if necessary
+ if not option?(l,"title" :: Symbol) then
+ s:String := unparse(convert(f)@InputForm)
+ if sayLength(s)$DisplayPackage > 50 then
+ l := concat(title "AXIOM3D",l)
+ else l := concat(title s,l)
+ -- indicate draw style if necessary
+ if not option?(l,"style" :: Symbol) then
+ l := concat(style unparse(convert(f)@InputForm),l)
+ -- obtain dependent variables and their ranges
+ u := variable uBind; uSeg := segment uBind
+ v := variable vBind; vSeg := segment vBind
+ -- create surface with functions as coordinates
+ surf : PSFF := surface(makeFloatFunction(f,u,v),_
+ makeFloatFunction(g,u,v),_
+ makeFloatFunction(h,u,v))
+ -- call 'draw'
+ draw(surf,uSeg,vSeg,l)
+
+ draw(s:PSF,uBind:BIND,vBind:BIND) ==
+ draw(s,uBind,vBind,nil())
+
+@
+\section{package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves}
+<<package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves>>=
+)abbrev package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves
+++ Author: Clifton J. Williamson
+++ Date Created: 26 June 1990
+++ Date Last Updated: October 1991 by Jon Steinbach
+++ Basic Operations: draw
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TopLevelDrawFunctionsForAlgebraicCurves provides top level
+++ functions for drawing non-singular algebraic curves.
+
+TopLevelDrawFunctionsForAlgebraicCurves(R,Ex): Exports == Implementation where
+ R : Join(IntegralDomain, OrderedSet, RetractableTo Integer)
+ Ex : FunctionSpace(R)
+
+ ANY1 ==> AnyFunctions1
+ DROP ==> DrawOption
+ EQ ==> Equation
+ F ==> Float
+ FRAC ==> Fraction
+ I ==> Integer
+ L ==> List
+ P ==> Polynomial
+ RN ==> Fraction Integer
+ SEG ==> Segment
+ SY ==> Symbol
+ VIEW2 ==> TwoDimensionalViewport
+
+ Exports ==> with
+
+ draw: (EQ Ex,SY,SY,L DROP) -> VIEW2
+ ++ draw(f(x,y) = g(x,y),x,y,l) draws the graph of a polynomial
+ ++ equation. The list l of draw options must specify a region
+ ++ in the plane in which the curve is to sketched.
+
+ Implementation ==> add
+ import ViewportPackage
+ import PlaneAlgebraicCurvePlot
+ import ViewDefaultsPackage
+ import GraphicsDefaults
+ import DrawOptionFunctions0
+ import SegmentFunctions2(RN,F)
+ import SegmentFunctions2(F,RN)
+ import AnyFunctions1(L SEG RN)
+
+ drawToScaleRanges: (SEG F,SEG F) -> L SEG F
+ drawToScaleRanges(xVals,yVals) ==
+ -- warning: assumes window is square
+ xHi := hi xVals; xLo := lo xVals
+ yHi := hi yVals; yLo := lo yVals
+ xDiff := xHi - xLo; yDiff := yHi - yLo
+ pad := abs(yDiff - xDiff)/2
+ yDiff > xDiff =>
+ [segment(xLo - pad,xHi + pad),yVals]
+ [xVals,segment(yLo - pad,yHi + pad)]
+
+ intConvert: R -> I
+ intConvert r ==
+ (nn := retractIfCan(r)@Union(I,"failed")) case "failed" =>
+ error "draw: polynomial must have rational coefficients"
+ nn :: I
+
+ polyEquation: EQ Ex -> P I
+ polyEquation eq ==
+ ff := lhs(eq) - rhs(eq)
+ (r := retractIfCan(ff)@Union(FRAC P R,"failed")) case "failed" =>
+ error "draw: not a polynomial equation"
+ rat := r :: FRAC P R
+ retractIfCan(denom rat)@Union(R,"failed") case "failed" =>
+ error "draw: non-constant denominator"
+ map(intConvert,numer rat)$PolynomialFunctions2(R,I)
+
+ draw(eq,x,y,l) ==
+ -- obtain polynomial equation
+ p := polyEquation eq
+ -- extract ranges from option list
+ floatRange := option(l,"rangeFloat" :: Symbol)
+ ratRange := option(l,"rangeRat" :: Symbol)
+ (floatRange case "failed") and (ratRange case "failed") =>
+ error "draw: you must specify ranges for an implicit plot"
+ ranges : L SEG RN := nil() -- dummy value
+ floatRanges : L SEG F := nil() -- dummy value
+ xRange : SEG RN := segment(0,0) -- dummy value
+ yRange : SEG RN := segment(0,0) -- dummy value
+ xRangeFloat : SEG F := segment(0,0) -- dummy value
+ yRangeFloat : SEG F := segment(0,0) -- dummy value
+ if not ratRange case "failed" then
+ ranges := retract(ratRange :: Any)$ANY1(L SEG RN)
+ not size?(ranges,2) => error "draw: you must specify two ranges"
+ xRange := first ranges; yRange := second ranges
+ xRangeFloat := map(convert(#1)@Float,xRange)@(SEG F)
+ yRangeFloat := map(convert(#1)@Float,yRange)@(SEG F)
+ floatRanges := [xRangeFloat,yRangeFloat]
+ else
+ floatRanges := retract(floatRange :: Any)$ANY1(L SEG F)
+ not size?(floatRanges,2) =>
+ error "draw: you must specify two ranges"
+ xRangeFloat := first floatRanges
+ yRangeFloat := second floatRanges
+ xRange := map(retract(#1)@RN,xRangeFloat)@(SEG RN)
+ yRange := map(retract(#1)@RN,yRangeFloat)@(SEG RN)
+ ranges := [xRange,yRange]
+ -- create curve plot
+ acplot := makeSketch(p,x,y,xRange,yRange)
+ -- process scaling information
+ if toScale(l,drawToScale()) then
+ scaledRanges := drawToScaleRanges(xRangeFloat,yRangeFloat)
+ -- add scaled ranges to list of options
+ l := concat(ranges scaledRanges,l)
+ else
+ -- add ranges to list of options
+ l := concat(ranges floatRanges,l)
+ -- process color information
+ ptCol := pointColorPalette(l,pointColorDefault())
+ crCol := curveColorPalette(l,lineColorDefault())
+ -- draw
+ drawCurves(listBranches acplot,ptCol,crCol,pointSizeDefault(),l)
+
+@
+\section{package DRAWPT TopLevelDrawFunctionsForPoints}
+<<package DRAWPT TopLevelDrawFunctionsForPoints>>=
+)abbrev package DRAWPT TopLevelDrawFunctionsForPoints
+++ Author: Mike Dewar
+++ Date Created: 24 May 1995
+++ Date Last Updated: 25 November 1996
+++ Basic Operations: draw
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TopLevelDrawFunctionsForPoints provides top level functions for
+++ drawing curves and surfaces described by sets of points.
+
+TopLevelDrawFunctionsForPoints(): Exports == Implementation where
+
+ DROP ==> DrawOption
+ L ==> List
+ SF ==> DoubleFloat
+ Pt ==> Point SF
+ VIEW2 ==> TwoDimensionalViewport
+ VIEW3 ==> ThreeDimensionalViewport
+
+ Exports ==> with
+ draw: (L SF,L SF) -> VIEW2
+ ++ draw(lx,ly) plots the curve constructed of points (x,y) for x
+ ++ in \spad{lx} for y in \spad{ly}.
+ draw: (L SF,L SF,L DROP) -> VIEW2
+ ++ draw(lx,ly,l) plots the curve constructed of points (x,y) for x
+ ++ in \spad{lx} for y in \spad{ly}.
+ ++ The options contained in the list l of
+ ++ the domain \spad{DrawOption} are applied.
+ draw: (L Pt) -> VIEW2
+ ++ draw(lp) plots the curve constructed from the list of points lp.
+ draw: (L Pt,L DROP) -> VIEW2
+ ++ draw(lp,l) plots the curve constructed from the list of points lp.
+ ++ The options contained in the list l of the domain \spad{DrawOption}
+ ++ are applied.
+ draw: (L SF, L SF, L SF) -> VIEW3
+ ++ draw(lx,ly,lz) draws the surface constructed by projecting the values
+ ++ in the \axiom{lz} list onto the rectangular grid formed by the
+ ++ \axiom{lx X ly}.
+ draw: (L SF, L SF, L SF, L DROP) -> VIEW3
+ ++ draw(lx,ly,lz,l) draws the surface constructed by projecting the values
+ ++ in the \axiom{lz} list onto the rectangular grid formed by the
+ ++ The options contained in the list l of the domain \spad{DrawOption}
+ ++ are applied.
+
+ Implementation ==> add
+
+ draw(lp:L Pt,l:L DROP):VIEW2 ==
+ makeViewport2D(makeGraphImage([lp])$GraphImage,l)$VIEW2
+
+ draw(lp:L Pt):VIEW2 == draw(lp,[])
+
+ draw(lx: L SF, ly: L SF, l:L DROP):VIEW2 ==
+ draw([point([x,y])$Pt for x in lx for y in ly],l)
+
+ draw(lx: L SF, ly: L SF):VIEW2 == draw(lx,ly,[])
+
+ draw(x:L SF,y:L SF,z:L SF):VIEW3 == draw(x,y,z,[])
+
+ draw(x:L SF,y:L SF,z:L SF,l:L DROP):VIEW3 ==
+ m : Integer := #x
+ zero? m => error "No X values"
+ n : Integer := #y
+ zero? n => error "No Y values"
+ zLen : Integer := #z
+ zLen ~= (m*n) =>
+ zLen > (m*n) => error "Too many Z-values to fit grid"
+ error "Not enough Z-values to fit grid"
+ points : L L Pt := []
+ for j in n..1 by -1 repeat
+ row : L Pt := []
+ for i in m..1 by -1 repeat
+ zval := (j-1)*m+i
+ row := cons(point([x.i,y.j,z.zval,z.zval]),row)
+ points := cons(row,points)
+ makeViewport3D(mesh points,l)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DRAWCFUN TopLevelDrawFunctionsForCompiledFunctions>>
+<<package DRAW TopLevelDrawFunctions>>
+<<package DRAWCURV TopLevelDrawFunctionsForAlgebraicCurves>>
+<<package DRAWPT TopLevelDrawFunctionsForPoints>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/drawopt.spad.pamphlet b/src/algebra/drawopt.spad.pamphlet
new file mode 100644
index 00000000..3e5658aa
--- /dev/null
+++ b/src/algebra/drawopt.spad.pamphlet
@@ -0,0 +1,458 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra drawopt.spad}
+\author{Stephen M. Watt, Jim Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain DROPT DrawOption}
+<<domain DROPT DrawOption>>=
+)abbrev domain DROPT DrawOption
+++ Author: Stephen Watt
+++ Date Created: 1 March 1990
+++ Date Last Updated: 31 Oct 1990, Jim Wen
+++ Basic Operations: adaptive, clip, title, style, toScale, coordinates,
+++ pointColor, curveColor, colorFunction, tubeRadius, range, ranges,
+++ var1Steps, var2Steps, tubePoints, unit
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: DrawOption allows the user to specify defaults for the
+++ creation and rendering of plots.
+
+DrawOption(): Exports == Implementation where
+ RANGE ==> List Segment Float
+ UNIT ==> List Float
+ PAL ==> Palette
+ POINT ==> Point(DoubleFloat)
+ SEG ==> Segment Float
+ SF ==> DoubleFloat
+ SPACE3 ==> ThreeSpace(DoubleFloat)
+ VIEWPT ==> Record( theta:SF, phi:SF, scale:SF, scaleX:SF, scaleY:SF, scaleZ:SF, deltaX:SF, deltaY:SF )
+
+ Exports ==> SetCategory with
+ adaptive : Boolean -> %
+ ++ adaptive(b) turns adaptive 2D plotting on if b is true, or off if b is
+ ++ false. This option is expressed in the form \spad{adaptive == b}.
+ clip : Boolean -> %
+ ++ clip(b) turns 2D clipping on if b is true, or off if b is false. This option
+ ++ is expressed in the form \spad{clip == b}.
+ viewpoint : VIEWPT -> %
+ ++ viewpoint(vp) creates a viewpoint data structure corresponding to the list
+ ++ of values. The values are interpreted as [theta, phi, scale, scaleX, scaleY,
+ ++ scaleZ, deltaX, deltaY]. This option is expressed in the form
+ ++ \spad{viewpoint == ls}.
+ title : String -> %
+ ++ title(s) specifies a title for a plot by the indicated string s. This option
+ ++ is expressed in the form \spad{title == s}.
+ style : String -> %
+ ++ style(s) specifies the drawing style in which the graph will be plotted
+ ++ by the indicated string s. This option is expressed in the form \spad{style == s}.
+ toScale : Boolean -> %
+ ++ toScale(b) specifies whether or not a plot is to be drawn to scale;
+ ++ if b is true it is drawn to scale, if b is false it is not. This option
+ ++ is expressed in the form \spad{toScale == b}.
+
+ clip : List SEG -> %
+ ++ clip([l]) provides ranges for user-defined clipping as specified
+ ++ in the list l. This option is expressed in the form \spad{clip == [l]}.
+ coordinates : (POINT -> POINT) -> %
+ ++ coordinates(p) specifies a change of coordinate systems of point p.
+ ++ This option is expressed in the form \spad{coordinates == p}.
+ pointColor : Float -> %
+ ++ pointColor(v) specifies a color, v, for 2D graph points. This option
+ ++ is expressed in the form \spad{pointColor == v}.
+ pointColor : PAL -> %
+ ++ pointColor(p) specifies a color index for 2D graph points from the spadcolors
+ ++ palette p. This option is expressed in the form \spad{pointColor == p}.
+ curveColor : Float -> %
+ ++ curveColor(v) specifies a color, v, for 2D graph curves. This option is expressed
+ ++ in the form \spad{curveColor == v}.
+ curveColor : PAL -> %
+ ++ curveColor(p) specifies a color index for 2D graph curves from the
+ ++ spadcolors palette p. This option is expressed in the form \spad{curveColor ==p}.
+ colorFunction : (SF -> SF) -> %
+ ++ colorFunction(f(z)) specifies the color based upon the z-component of
+ ++ three dimensional plots. This option is expressed in the form \spad{colorFunction == f(z)}.
+ colorFunction : ((SF,SF) -> SF) -> %
+ ++ colorFunction(f(u,v)) specifies the color for three dimensional plots
+ ++ as a function based upon the two parametric variables. This option is expressed
+ ++ in the form \spad{colorFunction == f(u,v)}.
+ colorFunction : ((SF,SF,SF) -> SF) -> %
+ ++ colorFunction(f(x,y,z)) specifies the color for three dimensional
+ ++ plots as a function of x, y, and z coordinates. This option is expressed in the
+ ++ form \spad{colorFunction == f(x,y,z)}.
+ tubeRadius : Float -> %
+ ++ tubeRadius(r) specifies a radius, r, for a tube plot around a 3D curve;
+ ++ is expressed in the form \spad{tubeRadius == 4}.
+ range : List SEG -> %
+ ++ range([l]) provides a user-specified range l. This option is expressed in the
+ ++ form \spad{range == [l]}.
+ range : List Segment Fraction Integer -> %
+ ++ range([i]) provides a user-specified range i. This option is expressed in the
+ ++ form \spad{range == [i]}.
+
+ ranges : RANGE -> %
+ ++ ranges(l) provides a list of user-specified ranges l. This option is expressed
+ ++ in the form \spad{ranges == l}.
+ space : SPACE3 -> %
+ ++ space specifies the space into which we will draw. If none is given
+ ++ then a new space is created.
+ var1Steps : PositiveInteger -> %
+ ++ var1Steps(n) indicates the number of subdivisions, n, of the first
+ ++ range variable. This option is expressed in the form \spad{var1Steps == n}.
+ var2Steps : PositiveInteger -> %
+ ++ var2Steps(n) indicates the number of subdivisions, n, of the second
+ ++ range variable. This option is expressed in the form \spad{var2Steps == n}.
+ tubePoints : PositiveInteger -> %
+ ++ tubePoints(n) specifies the number of points, n, defining the circle
+ ++ which creates the tube around a 3D curve, the default is 6. This option is
+ ++ expressed in the form \spad{tubePoints == n}.
+ coord : (POINT->POINT) -> %
+ ++ coord(p) specifies a change of coordinates of point p. This option is expressed
+ ++ in the form \spad{coord == p}.
+ unit : UNIT -> %
+ ++ unit(lf) will mark off the units according to the indicated list lf.
+ ++ This option is expressed in the form \spad{unit == [f1,f2]}.
+ option : (List %, Symbol) -> Union(Any, "failed")
+ ++ option() is not to be used at the top level;
+ ++ option determines internally which drawing options are indicated in
+ ++ a draw command.
+ option?: (List %, Symbol) -> Boolean
+ ++ option?() is not to be used at the top level;
+ ++ option? internally returns true for drawing options which are
+ ++ indicated in a draw command, or false for those which are not.
+ Implementation ==> add
+ import AnyFunctions1(String)
+ import AnyFunctions1(Segment Float)
+ import AnyFunctions1(VIEWPT)
+ import AnyFunctions1(List Segment Float)
+ import AnyFunctions1(List Segment Fraction Integer)
+ import AnyFunctions1(List Integer)
+ import AnyFunctions1(PositiveInteger)
+ import AnyFunctions1(Boolean)
+ import AnyFunctions1(RANGE)
+ import AnyFunctions1(UNIT)
+ import AnyFunctions1(Float)
+ import AnyFunctions1(POINT -> POINT)
+ import AnyFunctions1(SF -> SF)
+ import AnyFunctions1((SF,SF) -> SF)
+ import AnyFunctions1((SF,SF,SF) -> SF)
+ import AnyFunctions1(POINT)
+ import AnyFunctions1(PAL)
+ import AnyFunctions1(SPACE3)
+
+ Rep := Record(keyword:Symbol, value:Any)
+
+ length:List SEG -> NonNegativeInteger
+ -- these lists will become tuples in a later version
+ length tup == # tup
+
+ lengthR:List Segment Fraction Integer -> NonNegativeInteger
+ -- these lists will become tuples in a later version
+ lengthR tup == # tup
+
+ lengthI:List Integer -> NonNegativeInteger
+ -- these lists will become tuples in a later version
+ lengthI tup == # tup
+
+ viewpoint vp ==
+ ["viewpoint"::Symbol, vp::Any]
+
+ title s == ["title"::Symbol, s::Any]
+ style s == ["style"::Symbol, s::Any]
+ toScale b == ["toScale"::Symbol, b::Any]
+ clip(b:Boolean) == ["clipBoolean"::Symbol, b::Any]
+ adaptive b == ["adaptive"::Symbol, b::Any]
+
+ pointColor(x:Float) == ["pointColorFloat"::Symbol, x::Any]
+ pointColor(c:PAL) == ["pointColorPalette"::Symbol, c::Any]
+ curveColor(x:Float) == ["curveColorFloat"::Symbol, x::Any]
+ curveColor(c:PAL) == ["curveColorPalette"::Symbol, c::Any]
+ colorFunction(f:SF -> SF) == ["colorFunction1"::Symbol, f::Any]
+ colorFunction(f:(SF,SF) -> SF) == ["colorFunction2"::Symbol, f::Any]
+ colorFunction(f:(SF,SF,SF) -> SF) == ["colorFunction3"::Symbol, f::Any]
+ clip(tup:List SEG) ==
+ length tup > 3 =>
+ error "clip: at most 3 segments may be specified"
+ ["clipSegment"::Symbol, tup::Any]
+ coordinates f == ["coordinates"::Symbol, f::Any]
+ tubeRadius x == ["tubeRadius"::Symbol, x::Any]
+ range(tup:List Segment Float) ==
+ ((n := length tup) > 3) =>
+ error "range: at most 3 segments may be specified"
+ n < 2 =>
+ error "range: at least 2 segments may be specified"
+ ["rangeFloat"::Symbol, tup::Any]
+ range(tup:List Segment Fraction Integer) ==
+ ((n := lengthR tup) > 3) =>
+ error "range: at most 3 segments may be specified"
+ n < 2 =>
+ error "range: at least 2 segments may be specified"
+ ["rangeRat"::Symbol, tup::Any]
+
+ ranges s == ["ranges"::Symbol, s::Any]
+ space s == ["space"::Symbol, s::Any]
+ var1Steps s == ["var1Steps"::Symbol, s::Any]
+ var2Steps s == ["var2Steps"::Symbol, s::Any]
+ tubePoints s == ["tubePoints"::Symbol, s::Any]
+ coord s == ["coord"::Symbol, s::Any]
+ unit s == ["unit"::Symbol, s::Any]
+ coerce(x:%):OutputForm == x.keyword::OutputForm = x.value::OutputForm
+ x:% = y:% == x.keyword = y.keyword and x.value = y.value
+
+ option?(l, s) ==
+ for x in l repeat
+ x.keyword = s => return true
+ false
+
+ option(l, s) ==
+ for x in l repeat
+ x.keyword = s => return(x.value)
+ "failed"
+
+@
+\section{package DROPT1 DrawOptionFunctions1}
+<<package DROPT1 DrawOptionFunctions1>>=
+)abbrev package DROPT1 DrawOptionFunctions1
+++ This package \undocumented{}
+DrawOptionFunctions1(S:Type): Exports == Implementation where
+ RANGE ==> List Segment Float
+ UNIT ==> List Float
+ PAL ==> Palette
+ POINT ==> Point(DoubleFloat)
+ SEG ==> Segment Float
+ SF ==> DoubleFloat
+ SPACE3 ==> ThreeSpace(DoubleFloat)
+ VIEWPT ==> Record( theta:SF, phi:SF, scale:SF, scaleX:SF, scaleY:SF, scaleZ:SF, deltaX:SF, deltaY:SF )
+
+ Exports ==> with
+ option: (List DrawOption, Symbol) -> Union(S, "failed")
+ ++ option(l,s) determines whether the indicated drawing option, s,
+ ++ is contained in the list of drawing options, l, which is defined
+ ++ by the draw command.
+ Implementation ==> add
+ option(l, s) ==
+ (u := option(l, s)@Union(Any, "failed")) case "failed" => "failed"
+ retract(u::Any)$AnyFunctions1(S)
+
+@
+\section{package DROPT0 DrawOptionFunctions0}
+<<package DROPT0 DrawOptionFunctions0>>=
+)abbrev package DROPT0 DrawOptionFunctions0
+-- The functions here are not in DrawOptions since they are not
+-- visible to the interpreter.
+++ This package \undocumented{}
+DrawOptionFunctions0(): Exports == Implementation where
+ RANGE ==> List Segment Float
+ UNIT ==> List Float
+ PAL ==> Palette
+ POINT ==> Point(DoubleFloat)
+ SEG ==> Segment Float
+ SF ==> DoubleFloat
+ SPACE3 ==> ThreeSpace(DoubleFloat)
+ VIEWPT ==> Record( theta:SF, phi:SF, scale:SF, scaleX:SF, scaleY:SF, scaleZ:SF, deltaX:SF, deltaY:SF )
+
+ Exports ==> with
+ adaptive: (List DrawOption, Boolean) -> Boolean
+ ++ adaptive(l,b) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{adaptive}.
+ ++ If the option does not exist the value, b is returned.
+ clipBoolean: (List DrawOption, Boolean) -> Boolean
+ ++ clipBoolean(l,b) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{clipBoolean}.
+ ++ If the option does not exist the value, b is returned.
+ viewpoint: (List DrawOption, VIEWPT) -> VIEWPT
+ ++ viewpoint(l,ls) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{viewpoint}.
+ ++ IF the option does not exist, the value ls is returned.
+ title: (List DrawOption, String) -> String
+ ++ title(l,s) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{title}.
+ ++ If the option does not exist the value, s is returned.
+ style: (List DrawOption, String) -> String
+ ++ style(l,s) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{style}.
+ ++ If the option does not exist the value, s is returned.
+ toScale: (List DrawOption, Boolean) -> Boolean
+ ++ toScale(l,b) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{toScale}.
+ ++ If the option does not exist the value, b is returned.
+
+ pointColorPalette: (List DrawOption,PAL) -> PAL
+ ++ pointColorPalette(l,p) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{pointColorPalette}.
+ ++ If the option does not exist the value, p is returned.
+ curveColorPalette: (List DrawOption,PAL) -> PAL
+ ++ curveColorPalette(l,p) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{curveColorPalette}.
+ ++ If the option does not exist the value, p is returned.
+
+ ranges: (List DrawOption, RANGE) -> RANGE
+ ++ ranges(l,r) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{ranges}.
+ ++ If the option does not exist the value, r is returned.
+ var1Steps: (List DrawOption, PositiveInteger) -> PositiveInteger
+ ++ var1Steps(l,n) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{var1Steps}.
+ ++ If the option does not exist the value, n is returned.
+ var2Steps: (List DrawOption, PositiveInteger) -> PositiveInteger
+ ++ var2Steps(l,n) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{var2Steps}.
+ ++ If the option does not exist the value, n is returned.
+ space: (List DrawOption) -> SPACE3
+ ++ space(l) takes a list of draw options, l, and checks to see
+ ++ if it contains the option \spad{space}. If the the option
+ ++ doesn't exist, then an empty space is returned.
+ tubePoints : (List DrawOption, PositiveInteger) -> PositiveInteger
+ ++ tubePoints(l,n) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{tubePoints}.
+ ++ If the option does not exist the value, n is returned.
+ tubeRadius : (List DrawOption, Float) -> Float
+ ++ tubeRadius(l,n) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{tubeRadius}.
+ ++ If the option does not exist the value, n is returned.
+ coord: (List DrawOption, (POINT->POINT)) -> (POINT->POINT)
+ ++ coord(l,p) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{coord}.
+ ++ If the option does not exist the value, p is returned.
+ units: (List DrawOption, UNIT) -> UNIT
+ ++ units(l,u) takes the list of draw options, l, and checks
+ ++ the list to see if it contains the option \spad{unit}.
+ ++ If the option does not exist the value, u is returned.
+
+ Implementation ==> add
+ adaptive(l,s) ==
+ (u := option(l, "adaptive"::Symbol)$DrawOptionFunctions1(Boolean))
+ case "failed" => s
+ u::Boolean
+
+ clipBoolean(l,s) ==
+ (u := option(l, "clipBoolean"::Symbol)$DrawOptionFunctions1(Boolean))
+ case "failed" => s
+ u::Boolean
+
+ title(l, s) ==
+ (u := option(l, "title"::Symbol)$DrawOptionFunctions1(String))
+ case "failed" => s
+ u::String
+
+ viewpoint(l, vp) ==
+ (u := option(l, "viewpoint"::Symbol)$DrawOptionFunctions1(VIEWPT))
+ case "failed" => vp
+ u::VIEWPT
+
+ style(l, s) ==
+ (u := option(l, "style"::Symbol)$DrawOptionFunctions1(String))
+ case "failed" => s
+ u::String
+
+ toScale(l,s) ==
+ (u := option(l, "toScale"::Symbol)$DrawOptionFunctions1(Boolean))
+ case "failed" => s
+ u::Boolean
+
+ pointColorPalette(l,s) ==
+ (u := option(l, "pointColorPalette"::Symbol)$DrawOptionFunctions1(PAL))
+ case "failed" => s
+ u::PAL
+
+ curveColorPalette(l,s) ==
+ (u := option(l, "curveColorPalette"::Symbol)$DrawOptionFunctions1(PAL))
+ case "failed" => s
+ u::PAL
+
+
+
+ ranges(l, s) ==
+ (u := option(l, "ranges"::Symbol)$DrawOptionFunctions1(RANGE))
+ case "failed" => s
+ u::RANGE
+
+ space(l) ==
+ (u := option(l, "space"::Symbol)$DrawOptionFunctions1(SPACE3))
+ case "failed" => create3Space()$SPACE3
+ u::SPACE3
+
+ var1Steps(l,s) ==
+ (u := option(l, "var1Steps"::Symbol)$DrawOptionFunctions1(PositiveInteger))
+ case "failed" => s
+ u::PositiveInteger
+
+ var2Steps(l,s) ==
+ (u := option(l, "var2Steps"::Symbol)$DrawOptionFunctions1(PositiveInteger))
+ case "failed" => s
+ u::PositiveInteger
+
+ tubePoints(l,s) ==
+ (u := option(l, "tubePoints"::Symbol)$DrawOptionFunctions1(PositiveInteger))
+ case "failed" => s
+ u::PositiveInteger
+
+ tubeRadius(l,s) ==
+ (u := option(l, "tubeRadius"::Symbol)$DrawOptionFunctions1(Float))
+ case "failed" => s
+ u::Float
+
+ coord(l,s) ==
+ (u := option(l, "coord"::Symbol)$DrawOptionFunctions1(POINT->POINT))
+ case "failed" => s
+ u::(POINT->POINT)
+
+ units(l,s) ==
+ (u := option(l, "unit"::Symbol)$DrawOptionFunctions1(UNIT))
+ case "failed" => s
+ u::UNIT
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain DROPT DrawOption>>
+<<package DROPT1 DrawOptionFunctions1>>
+<<package DROPT0 DrawOptionFunctions0>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/drawpak.spad.pamphlet b/src/algebra/drawpak.spad.pamphlet
new file mode 100644
index 00000000..6166fa75
--- /dev/null
+++ b/src/algebra/drawpak.spad.pamphlet
@@ -0,0 +1,226 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra drawpak.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DRAWCX DrawComplex}
+<<package DRAWCX DrawComplex>>=
+)abbrev package DRAWCX DrawComplex
+++ Description: \axiomType{DrawComplex} provides some facilities
+++ for drawing complex functions.
+C ==> Complex DoubleFloat
+S ==> Segment DoubleFloat
+PC ==> Record(rr:SF, th:SF)
+INT ==> Integer
+SF ==> DoubleFloat
+NNI ==> NonNegativeInteger
+VIEW3D ==> ThreeDimensionalViewport
+ARRAY2 ==> TwoDimensionalArray
+
+DrawComplex(): Exports == Implementation where
+ Exports == with
+ drawComplex: (C -> C,S,S,Boolean) -> VIEW3D
+ ++ drawComplex(f,rRange,iRange,arrows?)
+ ++ draws a complex function as a height field.
+ ++ It uses the complex norm as the height and the complex argument as the color.
+ ++ It will optionally draw arrows on the surface indicating the direction
+ ++ of the complex value.\newline
+ ++ Sample call:
+ ++ \spad{f z == exp(1/z)}
+ ++ \spad{drawComplex(f, 0.3..3, 0..2*%pi, false)}
+ ++ Parameter descriptions:
+ ++ f: the function to draw
+ ++ rRange : the range of the real values
+ ++ iRange : the range of imaginary values
+ ++ arrows? : a flag indicating whether to draw the phase arrows for f
+ ++ Call the functions \axiomFunFrom{setRealSteps}{DrawComplex} and
+ ++ \axiomFunFrom{setImagSteps}{DrawComplex} to change the
+ ++ number of steps used in each direction.
+ drawComplexVectorField: (C -> C,S,S) -> VIEW3D
+ ++ drawComplexVectorField(f,rRange,iRange)
+ ++ draws a complex vector field using arrows on the \spad{x--y} plane.
+ ++ These vector fields should be viewed from the top by pressing the
+ ++ "XY" translate button on the 3-d viewport control panel.\newline
+ ++ Sample call:
+ ++ \spad{f z == sin z}
+ ++ \spad{drawComplexVectorField(f, -2..2, -2..2)}
+ ++ Parameter descriptions:
+ ++ f : the function to draw
+ ++ rRange : the range of the real values
+ ++ iRange : the range of the imaginary values
+ ++ Call the functions \axiomFunFrom{setRealSteps}{DrawComplex} and
+ ++ \axiomFunFrom{setImagSteps}{DrawComplex} to change the
+ ++ number of steps used in each direction.
+ setRealSteps: INT -> INT
+ ++ setRealSteps(i)
+ ++ sets to i the number of steps to use in the real direction
+ ++ when drawing complex functions. Returns i.
+ setImagSteps: INT -> INT
+ ++ setImagSteps(i)
+ ++ sets to i the number of steps to use in the imaginary direction
+ ++ when drawing complex functions. Returns i.
+ setClipValue: SF-> SF
+ ++ setClipValue(x)
+ ++ sets to x the maximum value to plot when drawing complex functions. Returns x.
+ Implementation == add
+ -- relative size of the arrow head compared to the length of the arrow
+ arrowScale : SF := (0.125)::SF
+ arrowAngle: SF := pi()-pi()/(20::SF) -- angle of the arrow head
+ realSteps: INT := 11 -- the number of steps in the real direction
+ imagSteps: INT := 11 -- the number of steps in the imaginary direction
+ clipValue: SF := 10::SF -- the maximum length of a vector to draw
+
+
+ -- Add an arrow head to a line segment, which starts at 'p1', ends at 'p2',
+ -- has length 'len', and and angle 'arg'. We pass 'len' and 'arg' as
+ -- arguments since thet were already computed by the calling program
+ makeArrow(p1:Point SF, p2:Point SF, len: SF, arg:SF):List List Point SF ==
+ c1 := cos(arg + arrowAngle)
+ s1 := sin(arg + arrowAngle)
+ c2 := cos(arg - arrowAngle)
+ s2 := sin(arg - arrowAngle)
+ p3 := point [p2.1 + c1*arrowScale*len, p2.2 + s1*arrowScale*len,
+ p2.3, p2.4]
+ p4 := point [p2.1 + c2*arrowScale*len, p2.2 + s2*arrowScale*len,
+ p2.3, p2.4]
+ [[p1, p2, p3], [p2, p4]]
+
+ -- clip a value in the interval (-clip...clip)
+ clipFun(x:SF):SF ==
+ min(max(x, -clipValue), clipValue)
+
+ drawComplex(f, realRange, imagRange, arrows?) ==
+ delReal := (hi(realRange) - lo(realRange))/realSteps::SF
+ delImag := (hi(imagRange) - lo(imagRange))/imagSteps::SF
+ funTable: ARRAY2(PC) :=
+ new((realSteps::NNI)+1, (imagSteps::NNI)+1, [0,0]$PC)
+ real := lo(realRange)
+ for i in 1..realSteps+1 repeat
+ imag := lo(imagRange)
+ for j in 1..imagSteps+1 repeat
+ z := f complex(real, imag)
+ funTable(i,j) := [clipFun(sqrt norm z), argument(z)]$PC
+ imag := imag + delImag
+ real := real + delReal
+ llp := empty()$(List List Point SF)
+ real := lo(realRange)
+ for i in 1..realSteps+1 repeat
+ imag := lo(imagRange)
+ lp := empty()$(List Point SF)
+ for j in 1..imagSteps+1 repeat
+ p := point [real, imag, funTable(i,j).rr, funTable(i,j).th]
+ lp := cons(p, lp)
+ imag := imag + delImag
+ real := real + delReal
+ llp := cons(lp, llp)
+ space := mesh(llp)$(ThreeSpace SF)
+ if arrows? then
+ real := lo(realRange)
+ for i in 1..realSteps+1 repeat
+ imag := lo(imagRange)
+ for j in 1..imagSteps+1 repeat
+ arg := funTable(i,j).th
+ p1 := point [real,imag, funTable(i,j).rr, arg]
+ len := delReal*2.0::SF
+ p2 := point [p1.1 + len*cos(arg), p1.2 + len*sin(arg),
+ p1.3, p1.4]
+ arrow := makeArrow(p1, p2, len, arg)
+ for a in arrow repeat curve(space, a)$(ThreeSpace SF)
+ imag := imag + delImag
+ real := real + delReal
+ makeViewport3D(space, "Complex Function")$VIEW3D
+
+ drawComplexVectorField(f, realRange, imagRange): VIEW3D ==
+ -- compute the steps size of the grid
+ delReal := (hi(realRange) - lo(realRange))/realSteps::SF
+ delImag := (hi(imagRange) - lo(imagRange))/imagSteps::SF
+ -- create the space to hold the arrows
+ space := create3Space()$(ThreeSpace SF)
+ real := lo(realRange)
+ for i in 1..realSteps+1 repeat
+ imag := lo(imagRange)
+ for j in 1..imagSteps+1 repeat
+ -- compute the function
+ z := f complex(real, imag)
+ -- get the direction of the arrow
+ arg := argument z
+ -- get the length of the arrow
+ len := clipFun(sqrt norm z)
+ -- create point at the base of the arrow
+ p1 := point [real, imag, 0::SF, arg]
+ -- scale the arrow length so it isn't too long
+ scaleLen := delReal * len
+ -- create the point at the top of the arrow
+ p2 := point [p1.1 + scaleLen*cos(arg), p1.2 + scaleLen*sin(arg),
+ 0::SF, arg]
+ -- make the pointer at the top of the arrow
+ arrow := makeArrow(p1, p2, scaleLen, arg)
+ -- add the line segments in the arrow to the space
+ for a in arrow repeat curve(space, a)$(ThreeSpace SF)
+ imag := imag + delImag
+ real := real + delReal
+ -- draw the vector feild
+ makeViewport3D(space, "Complex Vector Field")$VIEW3D
+
+ -- set the number of steps to use in the real direction
+ setRealSteps(n) ==
+ realSteps := n
+
+ -- set the number of steps to use in the imaginary direction
+ setImagSteps(n) ==
+ imagSteps := n
+
+ -- set the maximum value to plot
+ setClipValue clip ==
+ clipValue := clip
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DRAWCX DrawComplex>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/e01.spad.pamphlet b/src/algebra/e01.spad.pamphlet
new file mode 100644
index 00000000..9ad62c8c
--- /dev/null
+++ b/src/algebra/e01.spad.pamphlet
@@ -0,0 +1,329 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra e01.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGE01 NagInterpolationPackage}
+<<package NAGE01 NagInterpolationPackage>>=
+)abbrev package NAGE01 NagInterpolationPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:53 1994
+++Description:
+++This package uses the NAG Library to calculate the interpolation of a function of
+++one or two variables. When provided with the value of the
+++function (and possibly one or more of its lowest-order
+++derivatives) at each of a number of values of the variable(s),
+++the routines provide either an interpolating function or an
+++interpolated value. For some of the interpolating functions,
+++there are supporting routines to evaluate, differentiate or
+++integrate them.
+++See \downlink{Manual Page}{manpageXXe01}.
+
+
+NagInterpolationPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ e01baf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer,_
+ Integer,Integer) -> Result
+ ++ e01baf(m,x,y,lck,lwrk,ifail)
+ ++ determines a cubic spline to a given set of
+ ++ data.
+ ++ See \downlink{Manual Page}{manpageXXe01baf}.
+ e01bef : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e01bef(n,x,f,ifail)
+ ++ computes a monotonicity-preserving piecewise cubic Hermite
+ ++ interpolant to a set of data points.
+ ++ See \downlink{Manual Page}{manpageXXe01bef}.
+ e01bff : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ e01bff(n,x,f,d,m,px,ifail)
+ ++ evaluates a piecewise cubic Hermite interpolant at a set
+ ++ of points.
+ ++ See \downlink{Manual Page}{manpageXXe01bff}.
+ e01bgf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ e01bgf(n,x,f,d,m,px,ifail)
+ ++ evaluates a piecewise cubic Hermite interpolant and its
+ ++ first derivative at a set of points.
+ ++ See \downlink{Manual Page}{manpageXXe01bgf}.
+ e01bhf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ e01bhf(n,x,f,d,a,b,ifail)
+ ++ evaluates the definite integral of a piecewise cubic
+ ++ Hermite interpolant over the interval [a,b].
+ ++ See \downlink{Manual Page}{manpageXXe01bhf}.
+ e01daf : (Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ e01daf(mx,my,x,y,f,ifail)
+ ++ computes a bicubic spline interpolating surface through a
+ ++ set of data values, given on a rectangular grid in the x-y plane.
+ ++ See \downlink{Manual Page}{manpageXXe01daf}.
+ e01saf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Integer) -> Result
+ ++ e01saf(m,x,y,f,ifail)
+ ++ generates a two-dimensional surface interpolating a set of
+ ++ scattered data points, using the method of Renka and Cline.
+ ++ See \downlink{Manual Page}{manpageXXe01saf}.
+ e01sbf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Matrix Integer,Matrix DoubleFloat,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ e01sbf(m,x,y,f,triang,grads,px,py,ifail)
+ ++ evaluates at a given point the two-dimensional interpolant
+ ++ function computed by E01SAF.
+ ++ See \downlink{Manual Page}{manpageXXe01sbf}.
+ e01sef : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Integer,Integer,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ e01sef(m,x,y,f,nw,nq,rnw,rnq,ifail)
+ ++ generates a two-dimensional surface interpolating a set of
+ ++ scattered data points, using a modified Shepard method.
+ ++ See \downlink{Manual Page}{manpageXXe01sef}.
+ e01sff : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,_
+ DoubleFloat,Matrix DoubleFloat,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ e01sff(m,x,y,f,rnw,fnodes,px,py,ifail)
+ ++ evaluates at a given point the two-dimensional
+ ++ interpolating function computed by E01SEF.
+ ++ See \downlink{Manual Page}{manpageXXe01sff}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Matrix Integer)
+ import AnyFunctions1(DoubleFloat)
+
+
+ e01baf(mArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ lckArg:Integer,lwrkArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01baf",_
+ ["m"::S,"lck"::S,"lwrk"::S,"ifail"::S,"x"::S,"y"::S,"lamda"::S,"c"::S,"wrk"::S_
+ ]$Lisp,_
+ ["lamda"::S,"c"::S,"wrk"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["lamda"::S,"lck"::S]$Lisp,["c"::S,"lck"::S]$Lisp,["wrk"::S,"lwrk"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"lck"::S,"lwrk"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["lamda"::S,"c"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,lckArg::Any,lwrkArg::Any,ifailArg::Any,xArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01bef(nArg:Integer,xArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01bef",_
+ ["n"::S,"ifail"::S,"x"::S,"f"::S,"d"::S]$Lisp,_
+ ["d"::S]$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["f"::S,"n"::S]$Lisp_
+ ,["d"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["d"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,ifailArg::Any,xArg::Any,fArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01bff(nArg:Integer,xArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,_
+ dArg:Matrix DoubleFloat,mArg:Integer,pxArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01bff",_
+ ["n"::S,"m"::S,"ifail"::S,"x"::S,"f"::S,"d"::S,"px"::S,"pf"::S_
+ ]$Lisp,_
+ ["pf"::S]$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["f"::S,"n"::S]$Lisp_
+ ,["d"::S,"n"::S]$Lisp,["px"::S,"m"::S]$Lisp,["pf"::S,"m"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"m"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["pf"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,mArg::Any,ifailArg::Any,xArg::Any,fArg::Any,dArg::Any,pxArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01bgf(nArg:Integer,xArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,_
+ dArg:Matrix DoubleFloat,mArg:Integer,pxArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01bgf",_
+ ["n"::S,"m"::S,"ifail"::S,"x"::S,"f"::S,"d"::S,"px"::S,"pf"::S_
+ ,"pd"::S]$Lisp,_
+ ["pf"::S,"pd"::S]$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["f"::S,"n"::S]$Lisp_
+ ,["d"::S,"n"::S]$Lisp,["px"::S,"m"::S]$Lisp,["pf"::S,"m"::S]$Lisp,["pd"::S,"m"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"m"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["pf"::S,"pd"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,mArg::Any,ifailArg::Any,xArg::Any,fArg::Any,dArg::Any,pxArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01bhf(nArg:Integer,xArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,_
+ dArg:Matrix DoubleFloat,aArg:DoubleFloat,bArg:DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01bhf",_
+ ["n"::S,"a"::S,"b"::S,"pint"::S,"ifail"::S_
+ ,"x"::S,"f"::S,"d"::S]$Lisp,_
+ ["pint"::S]$Lisp,_
+ [["double"::S,["x"::S,"n"::S]$Lisp,["f"::S,"n"::S]$Lisp_
+ ,["d"::S,"n"::S]$Lisp,"a"::S,"b"::S,"pint"::S]$Lisp_
+ ,["integer"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["pint"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,aArg::Any,bArg::Any,ifailArg::Any,xArg::Any,fArg::Any,dArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01daf(mxArg:Integer,myArg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01daf",_
+ ["mx"::S,"my"::S,"px"::S,"py"::S,"ifail"::S_
+ ,"x"::S,"y"::S,"f"::S,"lamda"::S,"mu"::S_
+ ,"c"::S,"wrk"::S]$Lisp,_
+ ["px"::S,"py"::S,"lamda"::S,"mu"::S,"c"::S,"wrk"::S]$Lisp,_
+ [["double"::S,["x"::S,"mx"::S]$Lisp,["y"::S,"my"::S]$Lisp_
+ ,["f"::S,["*"::S,"mx"::S,"my"::S]$Lisp]$Lisp,["lamda"::S,["+"::S,"mx"::S,4$Lisp]$Lisp]$Lisp,["mu"::S,["+"::S,"mx"::S,4$Lisp]$Lisp]$Lisp_
+ ,["c"::S,["*"::S,"mx"::S,"my"::S]$Lisp]$Lisp,["wrk"::S,["*"::S,["+"::S,"mx"::S,6$Lisp]$Lisp,["+"::S,"my"::S,6$Lisp]$Lisp]$Lisp]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"mx"::S,"my"::S,"px"::S,"py"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["px"::S,"py"::S,"lamda"::S,"mu"::S,"c"::S,"ifail"::S]$Lisp,_
+ [([mxArg::Any,myArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01saf(mArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ fArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01saf",_
+ ["m"::S,"ifail"::S,"x"::S,"y"::S,"f"::S,"triang"::S,"grads"::S_
+ ]$Lisp,_
+ ["triang"::S,"grads"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["f"::S,"m"::S]$Lisp,["grads"::S,2$Lisp,"m"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,["triang"::S,["*"::S,7$Lisp,"m"::S]$Lisp]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["triang"::S,"grads"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01sbf(mArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ fArg:Matrix DoubleFloat,triangArg:Matrix Integer,gradsArg:Matrix DoubleFloat,_
+ pxArg:DoubleFloat,pyArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01sbf",_
+ ["m"::S,"px"::S,"py"::S,"pf"::S,"ifail"::S_
+ ,"x"::S,"y"::S,"f"::S,"triang"::S,"grads"::S_
+ ]$Lisp,_
+ ["pf"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["f"::S,"m"::S]$Lisp,["grads"::S,2$Lisp,"m"::S]$Lisp,"px"::S,"py"::S,"pf"::S]$Lisp_
+ ,["integer"::S,"m"::S,["triang"::S,["*"::S,7$Lisp,"m"::S]$Lisp]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["pf"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,pxArg::Any,pyArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any,triangArg::Any,gradsArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01sef(mArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ fArg:Matrix DoubleFloat,nwArg:Integer,nqArg:Integer,_
+ rnwArg:DoubleFloat,rnqArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01sef",_
+ ["m"::S,"nw"::S,"nq"::S,"minnq"::S,"rnw"::S_
+ ,"rnq"::S,"ifail"::S,"x"::S,"y"::S,"f"::S,"fnodes"::S,"wrk"::S_
+ ]$Lisp,_
+ ["fnodes"::S,"minnq"::S,"wrk"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["f"::S,"m"::S]$Lisp,["fnodes"::S,["*"::S,5$Lisp,"m"::S]$Lisp]$Lisp,"rnw"::S,"rnq"::S,["wrk"::S,["*"::S,6$Lisp,"m"::S]$Lisp]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"nw"::S,"nq"::S,"minnq"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["fnodes"::S,"minnq"::S,"rnw"::S,"rnq"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nwArg::Any,nqArg::Any,rnwArg::Any,rnqArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e01sff(mArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ fArg:Matrix DoubleFloat,rnwArg:DoubleFloat,fnodesArg:Matrix DoubleFloat,_
+ pxArg:DoubleFloat,pyArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e01sff",_
+ ["m"::S,"rnw"::S,"px"::S,"py"::S,"pf"::S_
+ ,"ifail"::S,"x"::S,"y"::S,"f"::S,"fnodes"::S]$Lisp,_
+ ["pf"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["f"::S,"m"::S]$Lisp,"rnw"::S,["fnodes"::S,["*"::S,5$Lisp,"m"::S]$Lisp]$Lisp,"px"::S,"py"::S,"pf"::S]$Lisp_
+ ,["integer"::S,"m"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["pf"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,rnwArg::Any,pxArg::Any,pyArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any,fnodesArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGE01 NagInterpolationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/e02.spad.pamphlet b/src/algebra/e02.spad.pamphlet
new file mode 100644
index 00000000..e09dfcae
--- /dev/null
+++ b/src/algebra/e02.spad.pamphlet
@@ -0,0 +1,588 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra e02.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGE02 NagFittingPackage}
+<<package NAGE02 NagFittingPackage>>=
+)abbrev package NAGE02 NagFittingPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:44:59 1994
+++Description:
+++This package uses the NAG Library to find a
+++function which approximates a set of data points. Typically the
+++data contain random errors, as of experimental measurement, which
+++need to be smoothed out. To seek an approximation to the data, it
+++is first necessary to specify for the approximating function a
+++mathematical form (a polynomial, for example) which contains a
+++number of unspecified coefficients: the appropriate fitting
+++routine then derives for the coefficients the values which
+++provide the best fit of that particular form. The package deals
+++mainly with curve and surface fitting (i.e., fitting with
+++functions of one and of two variables) when a polynomial or a
+++cubic spline is used as the fitting function, since these cover
+++the most common needs. However, fitting with other functions
+++and/or more variables can be undertaken by means of general
+++linear or nonlinear routines (some of which are contained in
+++other packages) depending on whether the coefficients in the
+++function occur linearly or nonlinearly. Cases where a graph
+++rather than a set of data points is given can be treated simply
+++by first reading a suitable set of points from the graph.
+++The package also contains routines for evaluating,
+++differentiating and integrating polynomial and spline curves and
+++surfaces, once the numerical values of their coefficients have
+++been determined.
+++See \downlink{Manual Page}{manpageXXe02}.
+
+
+NagFittingPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ e02adf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02adf(m,kplus1,nrows,x,y,w,ifail)
+ ++ computes weighted least-squares polynomial approximations
+ ++ to an arbitrary set of data points.
+ ++ See \downlink{Manual Page}{manpageXXe02adf}.
+ e02aef : (Integer,Matrix DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ e02aef(nplus1,a,xcap,ifail)
+ ++ evaluates a polynomial from its Chebyshev-series
+ ++ representation.
+ ++ See \downlink{Manual Page}{manpageXXe02aef}.
+ e02agf : (Integer,Integer,Integer,DoubleFloat,_
+ DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Matrix Integer,Integer,Integer,Integer) -> Result
+ ++ e02agf(m,kplus1,nrows,xmin,xmax,x,y,w,mf,xf,yf,lyf,ip,lwrk,liwrk,ifail)
+ ++ computes constrained weighted least-squares polynomial
+ ++ approximations in Chebyshev-series form to an arbitrary set of
+ ++ data points. The values of the approximations and any number of
+ ++ their derivatives can be specified at selected points.
+ ++ See \downlink{Manual Page}{manpageXXe02agf}.
+ e02ahf : (Integer,DoubleFloat,DoubleFloat,Matrix DoubleFloat,_
+ Integer,Integer,Integer,Integer,Integer) -> Result
+ ++ e02ahf(np1,xmin,xmax,a,ia1,la,iadif1,ladif,ifail)
+ ++ determines the coefficients in the Chebyshev-series
+ ++ representation of the derivative of a polynomial given in
+ ++ Chebyshev-series form.
+ ++ See \downlink{Manual Page}{manpageXXe02ahf}.
+ e02ajf : (Integer,DoubleFloat,DoubleFloat,Matrix DoubleFloat,_
+ Integer,Integer,DoubleFloat,Integer,Integer,Integer) -> Result
+ ++ e02ajf(np1,xmin,xmax,a,ia1,la,qatm1,iaint1,laint,ifail)
+ ++ determines the coefficients in the Chebyshev-series
+ ++ representation of the indefinite integral of a polynomial given
+ ++ in Chebyshev-series form.
+ ++ See \downlink{Manual Page}{manpageXXe02ajf}.
+ e02akf : (Integer,DoubleFloat,DoubleFloat,Matrix DoubleFloat,_
+ Integer,Integer,DoubleFloat,Integer) -> Result
+ ++ e02akf(np1,xmin,xmax,a,ia1,la,x,ifail)
+ ++ evaluates a polynomial from its Chebyshev-series
+ ++ representation, allowing an arbitrary index increment for
+ ++ accessing the array of coefficients.
+ ++ See \downlink{Manual Page}{manpageXXe02akf}.
+ e02baf : (Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02baf(m,ncap7,x,y,w,lamda,ifail)
+ ++ computes a weighted least-squares approximation to an
+ ++ arbitrary set of data points by a cubic splines
+ ++ prescribed by the user. Cubic spline can also be
+ ++ carried out.
+ ++ See \downlink{Manual Page}{manpageXXe02baf}.
+ e02bbf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,_
+ Integer) -> Result
+ ++ e02bbf(ncap7,lamda,c,x,ifail)
+ ++ evaluates a cubic spline representation.
+ ++ See \downlink{Manual Page}{manpageXXe02bbf}.
+ e02bcf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,_
+ Integer,Integer) -> Result
+ ++ e02bcf(ncap7,lamda,c,x,left,ifail)
+ ++ evaluates a cubic spline and its first three derivatives
+ ++ from its B-spline representation.
+ ++ See \downlink{Manual Page}{manpageXXe02bcf}.
+ e02bdf : (Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02bdf(ncap7,lamda,c,ifail)
+ ++ computes the definite integral from its
+ ++ B-spline representation.
+ ++ See \downlink{Manual Page}{manpageXXe02bdf}.
+ e02bef : (String,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Matrix DoubleFloat,DoubleFloat,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Matrix DoubleFloat,Matrix Integer) -> Result
+ ++ e02bef(start,m,x,y,w,s,nest,lwrk,n,lamda,ifail,wrk,iwrk)
+ ++ computes a cubic spline approximation to an arbitrary set
+ ++ of data points. The knot are located
+ ++ automatically, but a single parameter must be specified to
+ ++ control the trade-off between closeness of fit and smoothness of
+ ++ fit.
+ ++ See \downlink{Manual Page}{manpageXXe02bef}.
+ e02daf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix Integer,Integer,Integer,Integer,DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02daf(m,px,py,x,y,f,w,mu,point,npoint,nc,nws,eps,lamda,ifail)
+ ++ forms a minimal, weighted least-squares bicubic spline
+ ++ surface fit with prescribed knots to a given set of data points.
+ ++ See \downlink{Manual Page}{manpageXXe02daf}.
+ e02dcf : (String,Integer,Matrix DoubleFloat,Integer,_
+ Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix Integer,Integer) -> Result
+ ++ e02dcf(start,mx,x,my,y,f,s,nxest,nyest,lwrk,liwrk,nx,lamda,ny,mu,wrk,iwrk,ifail)
+ ++ computes a bicubic spline approximation to a set of data
+ ++ values, given on a rectangular grid in the x-y plane. The knots
+ ++ of the spline are located automatically, but a single parameter
+ ++ must be specified to control the trade-off between closeness of
+ ++ fit and smoothness of fit.
+ ++ See \downlink{Manual Page}{manpageXXe02dcf}.
+ e02ddf : (String,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,DoubleFloat,Integer,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02ddf(start,m,x,y,f,w,s,nxest,nyest,lwrk,liwrk,nx,lamda,ny,mu,wrk,ifail)
+ ++ computes a bicubic spline approximation to a set of
+ ++ scattered data are located
+ ++ automatically, but a single parameter must be specified to
+ ++ control the trade-off between closeness of fit and smoothness of
+ ++ fit.
+ ++ See \downlink{Manual Page}{manpageXXe02ddf}.
+ e02def : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02def(m,px,py,x,y,lamda,mu,c,ifail)
+ ++ calculates values of a bicubic spline
+ ++ representation.
+ ++ See \downlink{Manual Page}{manpageXXe02def}.
+ e02dff : (Integer,Integer,Integer,Integer,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Integer,Integer) -> Result
+ ++ e02dff(mx,my,px,py,x,y,lamda,mu,c,lwrk,liwrk,ifail)
+ ++ calculates values of a bicubic spline
+ ++ representation. The spline is evaluated at all points on a
+ ++ rectangular grid.
+ ++ See \downlink{Manual Page}{manpageXXe02dff}.
+ e02gaf : (Integer,Integer,Integer,DoubleFloat,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ e02gaf(m,la,nplus2,toler,a,b,ifail)
+ ++ calculates an l solution to an over-determined system of
+ ++ 1
+ ++ linear equations.
+ ++ See \downlink{Manual Page}{manpageXXe02gaf}.
+ e02zaf : (Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Integer,Integer) -> Result
+ ++ e02zaf(px,py,lamda,mu,m,x,y,npoint,nadres,ifail)
+ ++ sorts two-dimensional data into rectangular panels.
+ ++ See \downlink{Manual Page}{manpageXXe02zaf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Matrix Integer)
+ import AnyFunctions1(String)
+
+
+ e02adf(mArg:Integer,kplus1Arg:Integer,nrowsArg:Integer,_
+ xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,wArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02adf",_
+ ["m"::S,"kplus1"::S,"nrows"::S,"ifail"::S,"x"::S,"y"::S,"w"::S,"a"::S,"s"::S_
+ ,"work1"::S,"work2"::S]$Lisp,_
+ ["a"::S,"s"::S,"work1"::S,"work2"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["w"::S,"m"::S]$Lisp,["a"::S,"nrows"::S,"kplus1"::S]$Lisp,["s"::S,"kplus1"::S]$Lisp,["work1"::S,["*"::S,3$Lisp,"m"::S]$Lisp]$Lisp_
+ ,["work2"::S,["*"::S,2$Lisp,"kplus1"::S]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"kplus1"::S,"nrows"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["a"::S,"s"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,kplus1Arg::Any,nrowsArg::Any,ifailArg::Any,xArg::Any,yArg::Any,wArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02aef(nplus1Arg:Integer,aArg:Matrix DoubleFloat,xcapArg:DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02aef",_
+ ["nplus1"::S,"xcap"::S,"p"::S,"ifail"::S,"a"::S]$Lisp,_
+ ["p"::S]$Lisp,_
+ [["double"::S,["a"::S,"nplus1"::S]$Lisp,"xcap"::S_
+ ,"p"::S]$Lisp_
+ ,["integer"::S,"nplus1"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["p"::S,"ifail"::S]$Lisp,_
+ [([nplus1Arg::Any,xcapArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02agf(mArg:Integer,kplus1Arg:Integer,nrowsArg:Integer,_
+ xminArg:DoubleFloat,xmaxArg:DoubleFloat,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,wArg:Matrix DoubleFloat,mfArg:Integer,_
+ xfArg:Matrix DoubleFloat,yfArg:Matrix DoubleFloat,lyfArg:Integer,_
+ ipArg:Matrix Integer,lwrkArg:Integer,liwrkArg:Integer,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02agf",_
+ ["m"::S,"kplus1"::S,"nrows"::S,"xmin"::S,"xmax"::S_
+ ,"mf"::S,"lyf"::S,"lwrk"::S,"liwrk"::S,"np1"::S_
+ ,"ifail"::S,"x"::S,"y"::S,"w"::S,"xf"::S,"yf"::S_
+ ,"ip"::S,"a"::S,"s"::S,"wrk"::S,"iwrk"::S_
+ ]$Lisp,_
+ ["a"::S,"s"::S,"np1"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ [["double"::S,"xmin"::S,"xmax"::S,["x"::S,"m"::S]$Lisp_
+ ,["y"::S,"m"::S]$Lisp,["w"::S,"m"::S]$Lisp,["xf"::S,"mf"::S]$Lisp,["yf"::S,"lyf"::S]$Lisp,["a"::S,"nrows"::S,"kplus1"::S]$Lisp_
+ ,["s"::S,"kplus1"::S]$Lisp,["wrk"::S,"lwrk"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"kplus1"::S,"nrows"::S_
+ ,"mf"::S,"lyf"::S,["ip"::S,"mf"::S]$Lisp,"lwrk"::S,"liwrk"::S,"np1"::S,"ifail"::S,["iwrk"::S,"liwrk"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["a"::S,"s"::S,"np1"::S,"wrk"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,kplus1Arg::Any,nrowsArg::Any,xminArg::Any,xmaxArg::Any,mfArg::Any,lyfArg::Any,lwrkArg::Any,liwrkArg::Any,ifailArg::Any,xArg::Any,yArg::Any,wArg::Any,xfArg::Any,yfArg::Any,ipArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02ahf(np1Arg:Integer,xminArg:DoubleFloat,xmaxArg:DoubleFloat,_
+ aArg:Matrix DoubleFloat,ia1Arg:Integer,laArg:Integer,_
+ iadif1Arg:Integer,ladifArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02ahf",_
+ ["np1"::S,"xmin"::S,"xmax"::S,"ia1"::S,"la"::S_
+ ,"iadif1"::S,"ladif"::S,"patm1"::S,"ifail"::S,"a"::S,"adif"::S]$Lisp,_
+ ["patm1"::S,"adif"::S]$Lisp,_
+ [["double"::S,"xmin"::S,"xmax"::S,["a"::S,"la"::S]$Lisp_
+ ,"patm1"::S,["adif"::S,"ladif"::S]$Lisp]$Lisp_
+ ,["integer"::S,"np1"::S,"ia1"::S,"la"::S,"iadif1"::S_
+ ,"ladif"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["patm1"::S,"adif"::S,"ifail"::S]$Lisp,_
+ [([np1Arg::Any,xminArg::Any,xmaxArg::Any,ia1Arg::Any,laArg::Any,iadif1Arg::Any,ladifArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02ajf(np1Arg:Integer,xminArg:DoubleFloat,xmaxArg:DoubleFloat,_
+ aArg:Matrix DoubleFloat,ia1Arg:Integer,laArg:Integer,_
+ qatm1Arg:DoubleFloat,iaint1Arg:Integer,laintArg:Integer,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02ajf",_
+ ["np1"::S,"xmin"::S,"xmax"::S,"ia1"::S,"la"::S_
+ ,"qatm1"::S,"iaint1"::S,"laint"::S,"ifail"::S,"a"::S,"aint"::S]$Lisp,_
+ ["aint"::S]$Lisp,_
+ [["double"::S,"xmin"::S,"xmax"::S,["a"::S,"la"::S]$Lisp_
+ ,"qatm1"::S,["aint"::S,"laint"::S]$Lisp]$Lisp_
+ ,["integer"::S,"np1"::S,"ia1"::S,"la"::S,"iaint1"::S_
+ ,"laint"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["aint"::S,"ifail"::S]$Lisp,_
+ [([np1Arg::Any,xminArg::Any,xmaxArg::Any,ia1Arg::Any,laArg::Any,qatm1Arg::Any,iaint1Arg::Any,laintArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02akf(np1Arg:Integer,xminArg:DoubleFloat,xmaxArg:DoubleFloat,_
+ aArg:Matrix DoubleFloat,ia1Arg:Integer,laArg:Integer,_
+ xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02akf",_
+ ["np1"::S,"xmin"::S,"xmax"::S,"ia1"::S,"la"::S_
+ ,"x"::S,"result"::S,"ifail"::S,"a"::S]$Lisp,_
+ ["result"::S]$Lisp,_
+ [["double"::S,"xmin"::S,"xmax"::S,["a"::S,"la"::S]$Lisp_
+ ,"x"::S,"result"::S]$Lisp_
+ ,["integer"::S,"np1"::S,"ia1"::S,"la"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["result"::S,"ifail"::S]$Lisp,_
+ [([np1Arg::Any,xminArg::Any,xmaxArg::Any,ia1Arg::Any,laArg::Any,xArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02baf(mArg:Integer,ncap7Arg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,wArg:Matrix DoubleFloat,lamdaArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02baf",_
+ ["m"::S,"ncap7"::S,"ss"::S,"ifail"::S,"x"::S,"y"::S,"w"::S,"c"::S,"lamda"::S_
+ ,"work1"::S,"work2"::S]$Lisp,_
+ ["c"::S,"ss"::S,"work1"::S,"work2"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["w"::S,"m"::S]$Lisp,["c"::S,"ncap7"::S]$Lisp,"ss"::S,["lamda"::S,"ncap7"::S]$Lisp,["work1"::S,"m"::S]$Lisp_
+ ,["work2"::S,["*"::S,4$Lisp,"ncap7"::S]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"ncap7"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"ss"::S,"lamda"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,ncap7Arg::Any,ifailArg::Any,xArg::Any,yArg::Any,wArg::Any,lamdaArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02bbf(ncap7Arg:Integer,lamdaArg:Matrix DoubleFloat,cArg:Matrix DoubleFloat,_
+ xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02bbf",_
+ ["ncap7"::S,"x"::S,"s"::S,"ifail"::S,"lamda"::S,"c"::S]$Lisp,_
+ ["s"::S]$Lisp,_
+ [["double"::S,["lamda"::S,"ncap7"::S]$Lisp_
+ ,["c"::S,"ncap7"::S]$Lisp,"x"::S,"s"::S]$Lisp_
+ ,["integer"::S,"ncap7"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s"::S,"ifail"::S]$Lisp,_
+ [([ncap7Arg::Any,xArg::Any,ifailArg::Any,lamdaArg::Any,cArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02bcf(ncap7Arg:Integer,lamdaArg:Matrix DoubleFloat,cArg:Matrix DoubleFloat,_
+ xArg:DoubleFloat,leftArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02bcf",_
+ ["ncap7"::S,"x"::S,"left"::S,"ifail"::S,"lamda"::S,"c"::S,"s"::S]$Lisp,_
+ ["s"::S]$Lisp,_
+ [["double"::S,["lamda"::S,"ncap7"::S]$Lisp_
+ ,["c"::S,"ncap7"::S]$Lisp,"x"::S,["s"::S,4$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"ncap7"::S,"left"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["s"::S,"ifail"::S]$Lisp,_
+ [([ncap7Arg::Any,xArg::Any,leftArg::Any,ifailArg::Any,lamdaArg::Any,cArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02bdf(ncap7Arg:Integer,lamdaArg:Matrix DoubleFloat,cArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02bdf",_
+ ["ncap7"::S,"defint"::S,"ifail"::S,"lamda"::S,"c"::S]$Lisp,_
+ ["defint"::S]$Lisp,_
+ [["double"::S,["lamda"::S,"ncap7"::S]$Lisp_
+ ,["c"::S,"ncap7"::S]$Lisp,"defint"::S]$Lisp_
+ ,["integer"::S,"ncap7"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["defint"::S,"ifail"::S]$Lisp,_
+ [([ncap7Arg::Any,ifailArg::Any,lamdaArg::Any,cArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02bef(startArg:String,mArg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,wArg:Matrix DoubleFloat,sArg:DoubleFloat,_
+ nestArg:Integer,lwrkArg:Integer,nArg:Integer,_
+ lamdaArg:Matrix DoubleFloat,ifailArg:Integer,wrkArg:Matrix DoubleFloat,_
+ iwrkArg:Matrix Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02bef",_
+ ["start"::S,"m"::S,"s"::S,"nest"::S,"lwrk"::S_
+ ,"fp"::S,"n"::S,"ifail"::S,"x"::S,"y"::S,"w"::S,"c"::S,"lamda"::S_
+ ,"wrk"::S,"iwrk"::S]$Lisp,_
+ ["c"::S,"fp"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["w"::S,"m"::S]$Lisp,"s"::S,["c"::S,"nest"::S]$Lisp,"fp"::S,["lamda"::S,"nest"::S]$Lisp,["wrk"::S,"lwrk"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"nest"::S,"lwrk"::S,"n"::S_
+ ,"ifail"::S,["iwrk"::S,"nest"::S]$Lisp]$Lisp_
+ ,["character"::S,"start"::S]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"fp"::S,"n"::S,"lamda"::S,"ifail"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ [([startArg::Any,mArg::Any,sArg::Any,nestArg::Any,lwrkArg::Any,nArg::Any,ifailArg::Any,xArg::Any,yArg::Any,wArg::Any,lamdaArg::Any,wrkArg::Any,iwrkArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02daf(mArg:Integer,pxArg:Integer,pyArg:Integer,_
+ xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,_
+ wArg:Matrix DoubleFloat,muArg:Matrix DoubleFloat,pointArg:Matrix Integer,_
+ npointArg:Integer,ncArg:Integer,nwsArg:Integer,_
+ epsArg:DoubleFloat,lamdaArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02daf",_
+ ["m"::S,"px"::S,"py"::S,"npoint"::S,"nc"::S_
+ ,"nws"::S,"eps"::S,"sigma"::S,"rank"::S,"ifail"::S_
+ ,"x"::S,"y"::S,"f"::S,"w"::S,"mu"::S_
+ ,"point"::S,"dl"::S,"c"::S,"lamda"::S,"ws"::S_
+ ]$Lisp,_
+ ["dl"::S,"c"::S,"sigma"::S,"rank"::S,"ws"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["f"::S,"m"::S]$Lisp,["w"::S,"m"::S]$Lisp,["mu"::S,"py"::S]$Lisp,"eps"::S,["dl"::S,"nc"::S]$Lisp,["c"::S,"nc"::S]$Lisp_
+ ,"sigma"::S,["lamda"::S,"px"::S]$Lisp,["ws"::S,"nws"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"px"::S,"py"::S,["point"::S,"npoint"::S]$Lisp_
+ ,"npoint"::S,"nc"::S,"nws"::S,"rank"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["dl"::S,"c"::S,"sigma"::S,"rank"::S,"lamda"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,pxArg::Any,pyArg::Any,npointArg::Any,ncArg::Any,nwsArg::Any,epsArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any,wArg::Any,muArg::Any,pointArg::Any,lamdaArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02dcf(startArg:String,mxArg:Integer,xArg:Matrix DoubleFloat,_
+ myArg:Integer,yArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,_
+ sArg:DoubleFloat,nxestArg:Integer,nyestArg:Integer,_
+ lwrkArg:Integer,liwrkArg:Integer,nxArg:Integer,_
+ lamdaArg:Matrix DoubleFloat,nyArg:Integer,muArg:Matrix DoubleFloat,_
+ wrkArg:Matrix DoubleFloat,iwrkArg:Matrix Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02dcf",_
+ ["start"::S,"mx"::S,"my"::S,"s"::S,"nxest"::S_
+ ,"nyest"::S,"lwrk"::S,"liwrk"::S,"fp"::S,"nx"::S_
+ ,"ny"::S,"ifail"::S,"x"::S,"y"::S,"f"::S,"c"::S,"lamda"::S_
+ ,"mu"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ ["c"::S,"fp"::S]$Lisp,_
+ [["double"::S,["x"::S,"mx"::S]$Lisp,["y"::S,"my"::S]$Lisp_
+ ,["f"::S,["*"::S,"mx"::S,"my"::S]$Lisp]$Lisp,"s"::S,["c"::S,["*"::S,["-"::S,"nxest"::S,4$Lisp]$Lisp,["-"::S,"nyest"::S,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ,"fp"::S,["lamda"::S,"nxest"::S]$Lisp,["mu"::S,"nyest"::S]$Lisp,["wrk"::S,"lwrk"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"mx"::S,"my"::S,"nxest"::S,"nyest"::S_
+ ,"lwrk"::S,"liwrk"::S,"nx"::S,"ny"::S,["iwrk"::S,"liwrk"::S]$Lisp,"ifail"::S]$Lisp_
+ ,["character"::S,"start"::S]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"fp"::S,"nx"::S,"lamda"::S,"ny"::S,"mu"::S,"wrk"::S,"iwrk"::S,"ifail"::S]$Lisp,_
+ [([startArg::Any,mxArg::Any,myArg::Any,sArg::Any,nxestArg::Any,nyestArg::Any,lwrkArg::Any,liwrkArg::Any,nxArg::Any,nyArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any,lamdaArg::Any,muArg::Any,wrkArg::Any,iwrkArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02ddf(startArg:String,mArg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,fArg:Matrix DoubleFloat,wArg:Matrix DoubleFloat,_
+ sArg:DoubleFloat,nxestArg:Integer,nyestArg:Integer,_
+ lwrkArg:Integer,liwrkArg:Integer,nxArg:Integer,_
+ lamdaArg:Matrix DoubleFloat,nyArg:Integer,muArg:Matrix DoubleFloat,_
+ wrkArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02ddf",_
+ ["start"::S,"m"::S,"s"::S,"nxest"::S,"nyest"::S_
+ ,"lwrk"::S,"liwrk"::S,"fp"::S,"rank"::S,"nx"::S_
+ ,"ny"::S,"ifail"::S,"x"::S,"y"::S,"f"::S,"w"::S,"c"::S_
+ ,"iwrk"::S,"lamda"::S,"mu"::S,"wrk"::S]$Lisp,_
+ ["c"::S,"fp"::S,"rank"::S,"iwrk"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["f"::S,"m"::S]$Lisp,["w"::S,"m"::S]$Lisp,"s"::S,["c"::S,["*"::S,["-"::S,"nxest"::S,4$Lisp]$Lisp,["-"::S,"nyest"::S,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ,"fp"::S,["lamda"::S,"nxest"::S]$Lisp,["mu"::S,"nyest"::S]$Lisp,["wrk"::S,"lwrk"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"nxest"::S,"nyest"::S_
+ ,"lwrk"::S,"liwrk"::S,"rank"::S,["iwrk"::S,"liwrk"::S]$Lisp,"nx"::S,"ny"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"start"::S]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"fp"::S,"rank"::S,"iwrk"::S,"nx"::S,"lamda"::S,"ny"::S,"mu"::S,"wrk"::S,"ifail"::S]$Lisp,_
+ [([startArg::Any,mArg::Any,sArg::Any,nxestArg::Any,nyestArg::Any,lwrkArg::Any,liwrkArg::Any,nxArg::Any,nyArg::Any,ifailArg::Any,xArg::Any,yArg::Any,fArg::Any,wArg::Any,lamdaArg::Any,muArg::Any,wrkArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02def(mArg:Integer,pxArg:Integer,pyArg:Integer,_
+ xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,lamdaArg:Matrix DoubleFloat,_
+ muArg:Matrix DoubleFloat,cArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02def",_
+ ["m"::S,"px"::S,"py"::S,"ifail"::S,"x"::S,"y"::S,"lamda"::S,"mu"::S,"c"::S_
+ ,"ff"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ ["ff"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ [["double"::S,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp_
+ ,["lamda"::S,"px"::S]$Lisp,["mu"::S,"py"::S]$Lisp,["c"::S,["*"::S,["-"::S,"px"::S,4$Lisp]$Lisp,["-"::S,"py"::S,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ,["ff"::S,"m"::S]$Lisp,["wrk"::S,["-"::S,"py"::S,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"px"::S,"py"::S,"ifail"::S_
+ ,["iwrk"::S,["-"::S,"py"::S,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["ff"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,pxArg::Any,pyArg::Any,ifailArg::Any,xArg::Any,yArg::Any,lamdaArg::Any,muArg::Any,cArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02dff(mxArg:Integer,myArg:Integer,pxArg:Integer,_
+ pyArg:Integer,xArg:Matrix DoubleFloat,yArg:Matrix DoubleFloat,_
+ lamdaArg:Matrix DoubleFloat,muArg:Matrix DoubleFloat,cArg:Matrix DoubleFloat,_
+ lwrkArg:Integer,liwrkArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02dff",_
+ ["mx"::S,"my"::S,"px"::S,"py"::S,"lwrk"::S_
+ ,"liwrk"::S,"ifail"::S,"x"::S,"y"::S,"lamda"::S,"mu"::S,"c"::S_
+ ,"ff"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ ["ff"::S,"wrk"::S,"iwrk"::S]$Lisp,_
+ [["double"::S,["x"::S,"mx"::S]$Lisp,["y"::S,"my"::S]$Lisp_
+ ,["lamda"::S,"px"::S]$Lisp,["mu"::S,"py"::S]$Lisp,["c"::S,["*"::S,["-"::S,"px"::S,4$Lisp]$Lisp,["-"::S,"py"::S,4$Lisp]$Lisp]$Lisp]$Lisp_
+ ,["ff"::S,["*"::S,"mx"::S,"my"::S]$Lisp]$Lisp,["wrk"::S,"lwrk"::S]$Lisp]$Lisp_
+ ,["integer"::S,"mx"::S,"my"::S,"px"::S,"py"::S_
+ ,"lwrk"::S,"liwrk"::S,"ifail"::S,["iwrk"::S,"liwrk"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["ff"::S,"ifail"::S]$Lisp,_
+ [([mxArg::Any,myArg::Any,pxArg::Any,pyArg::Any,lwrkArg::Any,liwrkArg::Any,ifailArg::Any,xArg::Any,yArg::Any,lamdaArg::Any,muArg::Any,cArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02gaf(mArg:Integer,laArg:Integer,nplus2Arg:Integer,_
+ tolerArg:DoubleFloat,aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02gaf",_
+ ["m"::S,"la"::S,"nplus2"::S,"toler"::S,"resid"::S_
+ ,"irank"::S,"iter"::S,"ifail"::S,"x"::S,"a"::S,"b"::S,"iwork"::S]$Lisp,_
+ ["x"::S,"resid"::S,"irank"::S,"iter"::S,"iwork"::S]$Lisp,_
+ [["double"::S,"toler"::S,["x"::S,"nplus2"::S]$Lisp_
+ ,"resid"::S,["a"::S,"la"::S,"nplus2"::S]$Lisp,["b"::S,"m"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"la"::S,"nplus2"::S,"irank"::S_
+ ,"iter"::S,"ifail"::S,["iwork"::S,"m"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"resid"::S,"irank"::S,"iter"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,laArg::Any,nplus2Arg::Any,tolerArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e02zaf(pxArg:Integer,pyArg:Integer,lamdaArg:Matrix DoubleFloat,_
+ muArg:Matrix DoubleFloat,mArg:Integer,xArg:Matrix DoubleFloat,_
+ yArg:Matrix DoubleFloat,npointArg:Integer,nadresArg:Integer,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e02zaf",_
+ ["px"::S,"py"::S,"m"::S,"npoint"::S,"nadres"::S_
+ ,"ifail"::S,"lamda"::S,"mu"::S,"x"::S,"y"::S,"point"::S_
+ ,"adres"::S]$Lisp,_
+ ["point"::S,"adres"::S]$Lisp,_
+ [["double"::S,["lamda"::S,"px"::S]$Lisp,["mu"::S,"py"::S]$Lisp_
+ ,["x"::S,"m"::S]$Lisp,["y"::S,"m"::S]$Lisp]$Lisp_
+ ,["integer"::S,"px"::S,"py"::S,"m"::S,"npoint"::S_
+ ,"nadres"::S,["point"::S,"npoint"::S]$Lisp,"ifail"::S,["adres"::S,"nadres"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["point"::S,"ifail"::S]$Lisp,_
+ [([pxArg::Any,pyArg::Any,mArg::Any,npointArg::Any,nadresArg::Any,ifailArg::Any,lamdaArg::Any,muArg::Any,xArg::Any,yArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGE02 NagFittingPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/e04.spad.pamphlet b/src/algebra/e04.spad.pamphlet
new file mode 100644
index 00000000..e0f482f8
--- /dev/null
+++ b/src/algebra/e04.spad.pamphlet
@@ -0,0 +1,397 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra e04.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGE04 NagOptimisationPackage}
+<<package NAGE04 NagOptimisationPackage>>=
+)abbrev package NAGE04 NagOptimisationPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:45:09 1994
+++Description:
+++This package uses the NAG Library to perform optimization.
+++An optimization problem involves minimizing a function (called
+++the objective function) of several variables, possibly subject to
+++restrictions on the values of the variables defined by a set of
+++constraint functions. The routines in the NAG Foundation Library
+++are concerned with function minimization only, since the problem
+++of maximizing a given function can be transformed into a
+++minimization problem simply by multiplying the function by -1.
+++See \downlink{Manual Page}{manpageXXe04}.
+NagOptimisationPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ e04dgf : (Integer,DoubleFloat,DoubleFloat,Integer,_
+ DoubleFloat,Boolean,DoubleFloat,DoubleFloat,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp49(OBJFUN))) -> Result
+ ++ e04dgf(n,es,fu,it,lin,list,ma,op,pr,sta,sto,ve,x,ifail,objfun)
+ ++ minimizes an unconstrained nonlinear function of several
+ ++ variables using a pre-conditioned, limited memory quasi-Newton
+ ++ conjugate gradient method. First derivatives are required. The
+ ++ routine is intended for use on large scale problems.
+ ++ See \downlink{Manual Page}{manpageXXe04dgf}.
+ e04fdf : (Integer,Integer,Integer,Integer,_
+ Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp50(LSFUN1))) -> Result
+ ++ e04fdf(m,n,liw,lw,x,ifail,lsfun1)
+ ++ is an easy-to-use algorithm for finding an unconstrained
+ ++ minimum of a sum of squares of m nonlinear functions in n
+ ++ variables (m>=n). No derivatives are required.
+ ++ See \downlink{Manual Page}{manpageXXe04fdf}.
+ e04gcf : (Integer,Integer,Integer,Integer,_
+ Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp19(LSFUN2))) -> Result
+ ++ e04gcf(m,n,liw,lw,x,ifail,lsfun2)
+ ++ is an easy-to-use quasi-Newton algorithm for finding an
+ ++ unconstrained minimum of m nonlinear
+ ++ functions in n variables (m>=n). First derivatives are required.
+ ++ See \downlink{Manual Page}{manpageXXe04gcf}.
+ e04jaf : (Integer,Integer,Integer,Integer,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp24(FUNCT1))) -> Result
+ ++ e04jaf(n,ibound,liw,lw,bl,bu,x,ifail,funct1)
+ ++ is an easy-to-use quasi-Newton algorithm for finding a
+ ++ minimum of a function F(x ,x ,...,x ), subject to fixed upper and
+ ++ 1 2 n
+ ++ lower bounds of the independent variables x ,x ,...,x , using
+ ++ 1 2 n
+ ++ function values only.
+ ++ See \downlink{Manual Page}{manpageXXe04jaf}.
+ e04mbf : (Integer,Integer,Integer,Integer,_
+ Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Boolean,Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ e04mbf(itmax,msglvl,n,nclin,nctotl,nrowa,a,bl,bu,cvec,linobj,liwork,lwork,x,ifail)
+ ++ is an easy-to-use routine for solving linear programming
+ ++ problems, or for finding a feasible point for such problems. It
+ ++ is not intended for large sparse problems.
+ ++ See \downlink{Manual Page}{manpageXXe04mbf}.
+ e04naf : (Integer,Integer,Integer,Integer,_
+ Integer,Integer,Integer,Integer,DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Boolean,Boolean,Boolean,Integer,Integer,Matrix DoubleFloat,Matrix Integer,Integer,Union(fn:FileName,fp:Asp20(QPHESS))) -> Result
+ ++ e04naf(itmax,msglvl,n,nclin,nctotl,nrowa,nrowh,ncolh,bigbnd,a,bl,bu,cvec,featol,hess,cold,lpp,orthog,liwork,lwork,x,istate,ifail,qphess)
+ ++ is a comprehensive
+ ++ programming (QP) or linear programming (LP) problems. It is not
+ ++ intended for large sparse problems.
+ ++ See \downlink{Manual Page}{manpageXXe04naf}.
+ e04ucf : (Integer,Integer,Integer,Integer,_
+ Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Integer,Boolean,DoubleFloat,Integer,DoubleFloat,DoubleFloat,Boolean,DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,Boolean,Integer,Integer,Integer,Integer,Integer,DoubleFloat,DoubleFloat,DoubleFloat,Integer,Integer,Integer,Integer,Integer,Matrix Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp55(CONFUN)),Union(fn:FileName,fp:Asp49(OBJFUN))) -> Result
+ ++ e04ucf(n,nclin,ncnln,nrowa,nrowj,nrowr,a,bl,bu,liwork,lwork,sta,cra,der,fea,fun,hes,infb,infs,linf,lint,list,maji,majp,mini,minp,mon,nonf,opt,ste,stao,stac,stoo,stoc,ve,istate,cjac,clamda,r,x,ifail,confun,objfun)
+ ++ is designed to minimize an arbitrary smooth function
+ ++ subject to constraints on the
+ ++ variables, linear constraints.
+ ++ (E04UCF may be used for unconstrained, bound-constrained and
+ ++ linearly constrained optimization.) The user must provide
+ ++ subroutines that define the objective and constraint functions
+ ++ and as many of their first partial derivatives as possible.
+ ++ Unspecified derivatives are approximated by finite differences.
+ ++ All matrices are treated as dense, and hence E04UCF is not
+ ++ intended for large sparse problems.
+ ++ See \downlink{Manual Page}{manpageXXe04ucf}.
+ e04ycf : (Integer,Integer,Integer,DoubleFloat,_
+ Matrix DoubleFloat,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ e04ycf(job,m,n,fsumsq,s,lv,v,ifail)
+ ++ returns estimates of elements of the variance
+ ++ matrix of the estimated regression coefficients for a nonlinear
+ ++ least squares problem. The estimates are derived from the
+ ++ Jacobian of the function f(x) at the solution.
+ ++ See \downlink{Manual Page}{manpageXXe04ycf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import FortranPackage
+ import Union(fn:FileName,fp:Asp49(OBJFUN))
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Boolean)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Matrix Integer)
+
+
+ e04dgf(nArg:Integer,esArg:DoubleFloat,fuArg:DoubleFloat,_
+ itArg:Integer,linArg:DoubleFloat,listArg:Boolean,_
+ maArg:DoubleFloat,opArg:DoubleFloat,prArg:Integer,_
+ staArg:Integer,stoArg:Integer,veArg:Integer,_
+ xArg:Matrix DoubleFloat,ifailArg:Integer,objfunArg:Union(fn:FileName,fp:Asp49(OBJFUN))): Result ==
+ pushFortranOutputStack(objfunFilename := aspFilename "objfun")$FOP
+ if objfunArg case fn
+ then outputAsFortran(objfunArg.fn)
+ else outputAsFortran(objfunArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([objfunFilename]$Lisp,_
+ "e04dgf",_
+ ["n"::S,"es"::S,"fu"::S,"it"::S,"lin"::S_
+ ,"list"::S,"ma"::S,"op"::S,"pr"::S,"sta"::S_
+ ,"sto"::S,"ve"::S,"iter"::S,"objf"::S,"ifail"::S_
+ ,"objfun"::S,"objgrd"::S,"x"::S,"iwork"::S,"work"::S,"iuser"::S_
+ ,"user"::S]$Lisp,_
+ ["iter"::S,"objf"::S,"objgrd"::S,"iwork"::S,"work"::S,"iuser"::S,"user"::S,"objfun"::S]$Lisp,_
+ [["double"::S,"es"::S,"fu"::S,"lin"::S,"ma"::S_
+ ,"op"::S,"objf"::S,["objgrd"::S,"n"::S]$Lisp,["x"::S,"n"::S]$Lisp,["work"::S,["*"::S,13$Lisp,"n"::S]$Lisp]$Lisp,["user"::S,"*"::S]$Lisp_
+ ,"objfun"::S]$Lisp_
+ ,["integer"::S,"n"::S,"it"::S,"pr"::S,"sta"::S_
+ ,"sto"::S,"ve"::S,"iter"::S,"ifail"::S,["iwork"::S,["+"::S,"n"::S,1$Lisp]$Lisp]$Lisp,["iuser"::S,"*"::S]$Lisp]$Lisp_
+ ,["logical"::S,"list"::S]$Lisp_
+ ]$Lisp,_
+ ["iter"::S,"objf"::S,"objgrd"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,esArg::Any,fuArg::Any,itArg::Any,linArg::Any,listArg::Any,maArg::Any,opArg::Any,prArg::Any,staArg::Any,stoArg::Any,veArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04fdf(mArg:Integer,nArg:Integer,liwArg:Integer,_
+ lwArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer,_
+ lsfun1Arg:Union(fn:FileName,fp:Asp50(LSFUN1))): Result ==
+ pushFortranOutputStack(lsfun1Filename := aspFilename "lsfun1")$FOP
+ if lsfun1Arg case fn
+ then outputAsFortran(lsfun1Arg.fn)
+ else outputAsFortran(lsfun1Arg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([lsfun1Filename]$Lisp,_
+ "e04fdf",_
+ ["m"::S,"n"::S,"liw"::S,"lw"::S,"fsumsq"::S_
+ ,"ifail"::S,"lsfun1"::S,"w"::S,"x"::S,"iw"::S]$Lisp,_
+ ["fsumsq"::S,"w"::S,"iw"::S,"lsfun1"::S]$Lisp,_
+ [["double"::S,"fsumsq"::S,["w"::S,"lw"::S]$Lisp_
+ ,["x"::S,"n"::S]$Lisp,"lsfun1"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"liw"::S,"lw"::S_
+ ,"ifail"::S,["iw"::S,"liw"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["fsumsq"::S,"w"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,liwArg::Any,lwArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04gcf(mArg:Integer,nArg:Integer,liwArg:Integer,_
+ lwArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer,_
+ lsfun2Arg:Union(fn:FileName,fp:Asp19(LSFUN2))): Result ==
+ pushFortranOutputStack(lsfun2Filename := aspFilename "lsfun2")$FOP
+ if lsfun2Arg case fn
+ then outputAsFortran(lsfun2Arg.fn)
+ else outputAsFortran(lsfun2Arg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([lsfun2Filename]$Lisp,_
+ "e04gcf",_
+ ["m"::S,"n"::S,"liw"::S,"lw"::S,"fsumsq"::S_
+ ,"ifail"::S,"lsfun2"::S,"w"::S,"x"::S,"iw"::S]$Lisp,_
+ ["fsumsq"::S,"w"::S,"iw"::S,"lsfun2"::S]$Lisp,_
+ [["double"::S,"fsumsq"::S,["w"::S,"lw"::S]$Lisp_
+ ,["x"::S,"n"::S]$Lisp,"lsfun2"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"liw"::S,"lw"::S_
+ ,"ifail"::S,["iw"::S,"liw"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["fsumsq"::S,"w"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,liwArg::Any,lwArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04jaf(nArg:Integer,iboundArg:Integer,liwArg:Integer,_
+ lwArg:Integer,blArg:Matrix DoubleFloat,buArg:Matrix DoubleFloat,_
+ xArg:Matrix DoubleFloat,ifailArg:Integer,funct1Arg:Union(fn:FileName,fp:Asp24(FUNCT1))): Result ==
+ pushFortranOutputStack(funct1Filename := aspFilename "funct1")$FOP
+ if funct1Arg case fn
+ then outputAsFortran(funct1Arg.fn)
+ else outputAsFortran(funct1Arg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([funct1Filename]$Lisp,_
+ "e04jaf",_
+ ["n"::S,"ibound"::S,"liw"::S,"lw"::S,"f"::S_
+ ,"ifail"::S,"funct1"::S,"bl"::S,"bu"::S,"x"::S,"iw"::S,"w"::S_
+ ]$Lisp,_
+ ["f"::S,"iw"::S,"w"::S,"funct1"::S]$Lisp,_
+ [["double"::S,"f"::S,["bl"::S,"n"::S]$Lisp_
+ ,["bu"::S,"n"::S]$Lisp,["x"::S,"n"::S]$Lisp,["w"::S,"lw"::S]$Lisp,"funct1"::S]$Lisp_
+ ,["integer"::S,"n"::S,"ibound"::S,"liw"::S_
+ ,"lw"::S,"ifail"::S,["iw"::S,"liw"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["f"::S,"bl"::S,"bu"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,iboundArg::Any,liwArg::Any,lwArg::Any,ifailArg::Any,blArg::Any,buArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04mbf(itmaxArg:Integer,msglvlArg:Integer,nArg:Integer,_
+ nclinArg:Integer,nctotlArg:Integer,nrowaArg:Integer,_
+ aArg:Matrix DoubleFloat,blArg:Matrix DoubleFloat,buArg:Matrix DoubleFloat,_
+ cvecArg:Matrix DoubleFloat,linobjArg:Boolean,liworkArg:Integer,_
+ lworkArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e04mbf",_
+ ["itmax"::S,"msglvl"::S,"n"::S,"nclin"::S,"nctotl"::S_
+ ,"nrowa"::S,"linobj"::S,"liwork"::S,"lwork"::S,"objlp"::S_
+ ,"ifail"::S,"a"::S,"bl"::S,"bu"::S,"cvec"::S,"istate"::S_
+ ,"clamda"::S,"x"::S,"iwork"::S,"work"::S]$Lisp,_
+ ["istate"::S,"objlp"::S,"clamda"::S,"iwork"::S,"work"::S]$Lisp,_
+ [["double"::S,["a"::S,"nrowa"::S,"n"::S]$Lisp_
+ ,["bl"::S,"nctotl"::S]$Lisp,["bu"::S,"nctotl"::S]$Lisp,["cvec"::S,"n"::S]$Lisp,"objlp"::S,["clamda"::S,"nctotl"::S]$Lisp_
+ ,["x"::S,"n"::S]$Lisp,["work"::S,"lwork"::S]$Lisp]$Lisp_
+ ,["integer"::S,"itmax"::S,"msglvl"::S,"n"::S_
+ ,"nclin"::S,"nctotl"::S,"nrowa"::S,"liwork"::S,"lwork"::S,["istate"::S,"nctotl"::S]$Lisp,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp_
+ ]$Lisp_
+ ,["logical"::S,"linobj"::S]$Lisp_
+ ]$Lisp,_
+ ["istate"::S,"objlp"::S,"clamda"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([itmaxArg::Any,msglvlArg::Any,nArg::Any,nclinArg::Any,nctotlArg::Any,nrowaArg::Any,linobjArg::Any,liworkArg::Any,lworkArg::Any,ifailArg::Any,aArg::Any,blArg::Any,buArg::Any,cvecArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04naf(itmaxArg:Integer,msglvlArg:Integer,nArg:Integer,_
+ nclinArg:Integer,nctotlArg:Integer,nrowaArg:Integer,_
+ nrowhArg:Integer,ncolhArg:Integer,bigbndArg:DoubleFloat,_
+ aArg:Matrix DoubleFloat,blArg:Matrix DoubleFloat,buArg:Matrix DoubleFloat,_
+ cvecArg:Matrix DoubleFloat,featolArg:Matrix DoubleFloat,hessArg:Matrix DoubleFloat,_
+ coldArg:Boolean,lppArg:Boolean,orthogArg:Boolean,_
+ liworkArg:Integer,lworkArg:Integer,xArg:Matrix DoubleFloat,_
+ istateArg:Matrix Integer,ifailArg:Integer,qphessArg:Union(fn:FileName,fp:Asp20(QPHESS))): Result ==
+ pushFortranOutputStack(qphessFilename := aspFilename "qphess")$FOP
+ if qphessArg case fn
+ then outputAsFortran(qphessArg.fn)
+ else outputAsFortran(qphessArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([qphessFilename]$Lisp,_
+ "e04naf",_
+ ["itmax"::S,"msglvl"::S,"n"::S,"nclin"::S,"nctotl"::S_
+ ,"nrowa"::S,"nrowh"::S,"ncolh"::S,"bigbnd"::S,"cold"::S_
+ ,"lpp"::S,"orthog"::S,"liwork"::S,"lwork"::S,"iter"::S_
+ ,"obj"::S,"ifail"::S,"qphess"::S,"a"::S,"bl"::S,"bu"::S,"cvec"::S,"featol"::S_
+ ,"hess"::S,"clamda"::S,"x"::S,"istate"::S,"iwork"::S_
+ ,"work"::S]$Lisp,_
+ ["iter"::S,"obj"::S,"clamda"::S,"iwork"::S,"work"::S,"qphess"::S]$Lisp,_
+ [["double"::S,"bigbnd"::S,["a"::S,"nrowa"::S,"n"::S]$Lisp_
+ ,["bl"::S,"nctotl"::S]$Lisp,["bu"::S,"nctotl"::S]$Lisp,["cvec"::S,"n"::S]$Lisp,["featol"::S,"nctotl"::S]$Lisp_
+ ,["hess"::S,"nrowh"::S,"ncolh"::S]$Lisp,"obj"::S,["clamda"::S,"nctotl"::S]$Lisp,["x"::S,"n"::S]$Lisp,["work"::S,"lwork"::S]$Lisp_
+ ,"qphess"::S]$Lisp_
+ ,["integer"::S,"itmax"::S,"msglvl"::S,"n"::S_
+ ,"nclin"::S,"nctotl"::S,"nrowa"::S,"nrowh"::S,"ncolh"::S,"liwork"::S,"lwork"::S,"iter"::S,["istate"::S,"nctotl"::S]$Lisp_
+ ,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp]$Lisp_
+ ,["logical"::S,"cold"::S,"lpp"::S,"orthog"::S]$Lisp_
+ ]$Lisp,_
+ ["iter"::S,"obj"::S,"clamda"::S,"x"::S,"istate"::S,"ifail"::S]$Lisp,_
+ [([itmaxArg::Any,msglvlArg::Any,nArg::Any,nclinArg::Any,nctotlArg::Any,nrowaArg::Any,nrowhArg::Any,ncolhArg::Any,bigbndArg::Any,coldArg::Any,lppArg::Any,orthogArg::Any,liworkArg::Any,lworkArg::Any,ifailArg::Any,aArg::Any,blArg::Any,buArg::Any,cvecArg::Any,featolArg::Any,hessArg::Any,xArg::Any,istateArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04ucf(nArg:Integer,nclinArg:Integer,ncnlnArg:Integer,_
+ nrowaArg:Integer,nrowjArg:Integer,nrowrArg:Integer,_
+ aArg:Matrix DoubleFloat,blArg:Matrix DoubleFloat,buArg:Matrix DoubleFloat,_
+ liworkArg:Integer,lworkArg:Integer,staArg:Boolean,_
+ craArg:DoubleFloat,derArg:Integer,feaArg:DoubleFloat,_
+ funArg:DoubleFloat,hesArg:Boolean,infbArg:DoubleFloat,_
+ infsArg:DoubleFloat,linfArg:DoubleFloat,lintArg:DoubleFloat,_
+ listArg:Boolean,majiArg:Integer,majpArg:Integer,_
+ miniArg:Integer,minpArg:Integer,monArg:Integer,_
+ nonfArg:DoubleFloat,optArg:DoubleFloat,steArg:DoubleFloat,_
+ staoArg:Integer,stacArg:Integer,stooArg:Integer,_
+ stocArg:Integer,veArg:Integer,istateArg:Matrix Integer,_
+ cjacArg:Matrix DoubleFloat,clamdaArg:Matrix DoubleFloat,rArg:Matrix DoubleFloat,_
+ xArg:Matrix DoubleFloat,ifailArg:Integer,confunArg:Union(fn:FileName,fp:Asp55(CONFUN)),_
+ objfunArg:Union(fn:FileName,fp:Asp49(OBJFUN))): Result ==
+ pushFortranOutputStack(confunFilename := aspFilename "confun")$FOP
+ if confunArg case fn
+ then outputAsFortran(confunArg.fn)
+ else outputAsFortran(confunArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(objfunFilename := aspFilename "objfun")$FOP
+ if objfunArg case fn
+ then outputAsFortran(objfunArg.fn)
+ else outputAsFortran(objfunArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([confunFilename,objfunFilename]$Lisp,_
+ "e04ucf",_
+ ["n"::S,"nclin"::S,"ncnln"::S,"nrowa"::S,"nrowj"::S_
+ ,"nrowr"::S,"liwork"::S,"lwork"::S,"sta"::S,"cra"::S_
+ ,"der"::S,"fea"::S,"fun"::S,"hes"::S,"infb"::S_
+ ,"infs"::S,"linf"::S,"lint"::S,"list"::S,"maji"::S_
+ ,"majp"::S,"mini"::S,"minp"::S,"mon"::S,"nonf"::S_
+ ,"opt"::S,"ste"::S,"stao"::S,"stac"::S,"stoo"::S_
+ ,"stoc"::S,"ve"::S,"iter"::S,"objf"::S,"ifail"::S_
+ ,"confun"::S,"objfun"::S,"a"::S,"bl"::S,"bu"::S,"c"::S,"objgrd"::S_
+ ,"istate"::S,"cjac"::S,"clamda"::S,"r"::S,"x"::S_
+ ,"iwork"::S,"work"::S,"iuser"::S,"user"::S]$Lisp,_
+ ["iter"::S,"c"::S,"objf"::S,"objgrd"::S,"iwork"::S,"work"::S,"iuser"::S,"user"::S,"confun"::S,"objfun"::S]$Lisp,_
+ [["double"::S,["a"::S,"nrowa"::S,"n"::S]$Lisp_
+ ,["bl"::S,["+"::S,["+"::S,"nclin"::S,"ncnln"::S]$Lisp,"n"::S]$Lisp]$Lisp,["bu"::S,["+"::S,["+"::S,"nclin"::S,"ncnln"::S]$Lisp,"n"::S]$Lisp]$Lisp_
+ ,"cra"::S,"fea"::S,"fun"::S,"infb"::S,"infs"::S,"linf"::S,"lint"::S,"nonf"::S,"opt"::S,"ste"::S_
+ ,["c"::S,"ncnln"::S]$Lisp,"objf"::S,["objgrd"::S,"n"::S]$Lisp,["cjac"::S,"nrowj"::S,"n"::S]$Lisp,["clamda"::S,["+"::S,["+"::S,"nclin"::S,"ncnln"::S]$Lisp,"n"::S]$Lisp]$Lisp_
+ ,["r"::S,"nrowr"::S,"n"::S]$Lisp,["x"::S,"n"::S]$Lisp,["work"::S,"lwork"::S]$Lisp_
+ ,["user"::S,1$Lisp]$Lisp,"confun"::S,"objfun"::S]$Lisp_
+ ,["integer"::S,"n"::S,"nclin"::S,"ncnln"::S_
+ ,"nrowa"::S,"nrowj"::S,"nrowr"::S,"liwork"::S,"lwork"::S,"der"::S,"maji"::S,"majp"::S,"mini"::S,"minp"::S,"mon"::S,"stao"::S_
+ ,"stac"::S,"stoo"::S,"stoc"::S,"ve"::S,"iter"::S,["istate"::S,["+"::S,["+"::S,"nclin"::S,"ncnln"::S]$Lisp,"n"::S]$Lisp]$Lisp_
+ ,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp,["iuser"::S,1$Lisp]$Lisp]$Lisp_
+ ,["logical"::S,"sta"::S,"hes"::S,"list"::S]$Lisp_
+ ]$Lisp,_
+ ["iter"::S,"c"::S,"objf"::S,"objgrd"::S,"istate"::S,"cjac"::S,"clamda"::S,"r"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,nclinArg::Any,ncnlnArg::Any,nrowaArg::Any,nrowjArg::Any,nrowrArg::Any,liworkArg::Any,lworkArg::Any,staArg::Any,craArg::Any,derArg::Any,feaArg::Any,funArg::Any,hesArg::Any,infbArg::Any,infsArg::Any,linfArg::Any,lintArg::Any,listArg::Any,majiArg::Any,majpArg::Any,miniArg::Any,minpArg::Any,monArg::Any,nonfArg::Any,optArg::Any,steArg::Any,staoArg::Any,stacArg::Any,stooArg::Any,stocArg::Any,veArg::Any,ifailArg::Any,aArg::Any,blArg::Any,buArg::Any,istateArg::Any,cjacArg::Any,clamdaArg::Any,rArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ e04ycf(jobArg:Integer,mArg:Integer,nArg:Integer,_
+ fsumsqArg:DoubleFloat,sArg:Matrix DoubleFloat,lvArg:Integer,_
+ vArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "e04ycf",_
+ ["job"::S,"m"::S,"n"::S,"fsumsq"::S,"lv"::S_
+ ,"ifail"::S,"s"::S,"cj"::S,"v"::S,"work"::S]$Lisp,_
+ ["cj"::S,"work"::S]$Lisp,_
+ [["double"::S,"fsumsq"::S,["s"::S,"n"::S]$Lisp_
+ ,["cj"::S,"n"::S]$Lisp,["v"::S,"lv"::S,"n"::S]$Lisp,["work"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"job"::S,"m"::S,"n"::S,"lv"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["cj"::S,"v"::S,"ifail"::S]$Lisp,_
+ [([jobArg::Any,mArg::Any,nArg::Any,fsumsqArg::Any,lvArg::Any,ifailArg::Any,sArg::Any,vArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGE04 NagOptimisationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/e04Package.spad.pamphlet b/src/algebra/e04Package.spad.pamphlet
new file mode 100644
index 00000000..28da22de
--- /dev/null
+++ b/src/algebra/e04Package.spad.pamphlet
@@ -0,0 +1,448 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra e04Package.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package OPTPACK AnnaNumericalOptimizationPackage}
+<<package OPTPACK AnnaNumericalOptimizationPackage>>=
+)abbrev package OPTPACK AnnaNumericalOptimizationPackage
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: December 1997
+++ Basic Operations: measure, optimize, goodnessOfFit.
+++ Description:
+++ \axiomType{AnnaNumericalOptimizationPackage} is a \axiom{package} of
+++ functions for the \axiomType{NumericalOptimizationCategory}
+++ with \axiom{measure} and \axiom{optimize}.
+EDF ==> Expression DoubleFloat
+LEDF ==> List Expression DoubleFloat
+LDF ==> List DoubleFloat
+MDF ==> Matrix DoubleFloat
+DF ==> DoubleFloat
+LOCDF ==> List OrderedCompletion DoubleFloat
+OCDF ==> OrderedCompletion DoubleFloat
+LOCF ==> List OrderedCompletion Float
+OCF ==> OrderedCompletion Float
+LEF ==> List Expression Float
+EF ==> Expression Float
+LF ==> List Float
+F ==> Float
+LS ==> List Symbol
+LST ==> List String
+INT ==> Integer
+NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+LSA ==> Record(lfn:LEDF, init:LDF)
+IFL ==> List(Record(ifail:Integer,instruction:String))
+Entry ==> Record(chapter:String, type:String, domainName: String,
+ defaultMin:F, measure:F, failList:IFL, explList:LST)
+Measure ==> Record(measure:F,name:String, explanations:List String)
+Measure2 ==> Record(measure:F,explanations:String)
+RT ==> RoutinesTable
+UNOALSA ==> Union(noa:NOA,lsa:LSA)
+
+AnnaNumericalOptimizationPackage(): with
+ measure:NumericalOptimizationProblem -> Measure
+ ++ measure(prob) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical optimization problem defined by
+ ++ \axiom{prob} by checking various attributes of the functions and
+ ++ calculating a measure of compatibility of each routine to these
+ ++ attributes.
+ ++
+ ++ It calls each \axiom{domain} of \axiom{category}
+ ++ \axiomType{NumericalOptimizationCategory} in turn to calculate all
+ ++ measures and returns the best i.e. the name of the most
+ ++ appropriate domain and any other relevant information.
+
+ measure:(NumericalOptimizationProblem,RT) -> Measure
+ ++ measure(prob,R) is a top level ANNA function for identifying the most
+ ++ appropriate numerical routine from those in the routines table
+ ++ provided for solving the numerical optimization problem defined by
+ ++ \axiom{prob} by checking various attributes of the functions and
+ ++ calculating a measure of compatibility of each routine to these
+ ++ attributes.
+ ++
+ ++ It calls each \axiom{domain} listed in \axiom{R} of \axiom{category}
+ ++ \axiomType{NumericalOptimizationCategory} in turn to calculate all
+ ++ measures and returns the best i.e. the name of the most
+ ++ appropriate domain and any other relevant information.
+
+ optimize:(NumericalOptimizationProblem,RT) -> Result
+ ++ optimize(prob,routines) is a top level ANNA function to
+ ++ minimize a function or a set of functions with any constraints
+ ++ as defined within \axiom{prob}.
+ ++
+ ++ It iterates over the \axiom{domains} listed in \axiom{routines} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+
+ optimize:NumericalOptimizationProblem -> Result
+ ++ optimize(prob) is a top level ANNA function to
+ ++ minimize a function or a set of functions with any constraints
+ ++ as defined within \axiom{prob}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+
+ goodnessOfFit:NumericalOptimizationProblem -> Result
+ ++ goodnessOfFit(prob) is a top level ANNA function to
+ ++ check to goodness of fit of a least squares model
+ ++ as defined within \axiom{prob}.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+ ++ It then calls the numerical routine \axiomType{E04YCF} to get estimates
+ ++ of the variance-covariance matrix of the regression coefficients of
+ ++ the least-squares problem.
+ ++
+ ++ It thus returns both the results of the optimization and the
+ ++ variance-covariance calculation.
+
+ optimize:(EF,LF,LOCF,LEF,LOCF) -> Result
+ ++ optimize(f,start,lower,cons,upper) is a top level ANNA function to
+ ++ minimize a function, \axiom{f}, of one or more variables with the
+ ++ given constraints.
+ ++
+ ++ These constraints may be simple constraints on the variables
+ ++ in which case \axiom{cons} would be an empty list and the bounds on
+ ++ those variables defined in \axiom{lower} and \axiom{upper}, or a
+ ++ mixture of simple, linear and non-linear constraints, where
+ ++ \axiom{cons} contains the linear and non-linear constraints and
+ ++ the bounds on these are added to \axiom{upper} and \axiom{lower}.
+ ++
+ ++ The parameter \axiom{start} is a list of the initial guesses of the
+ ++ values of the variables.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+
+ optimize:(EF,LF,LOCF,LOCF) -> Result
+ ++ optimize(f,start,lower,upper) is a top level ANNA function to
+ ++ minimize a function, \axiom{f}, of one or more variables with
+ ++ simple constraints. The bounds on
+ ++ the variables are defined in \axiom{lower} and \axiom{upper}.
+ ++
+ ++ The parameter \axiom{start} is a list of the initial guesses of the
+ ++ values of the variables.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+
+ optimize:(EF,LF) -> Result
+ ++ optimize(f,start) is a top level ANNA function to
+ ++ minimize a function, \axiom{f}, of one or more variables without
+ ++ constraints.
+ ++
+ ++ The parameter \axiom{start} is a list of the initial guesses of the
+ ++ values of the variables.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+
+ optimize:(LEF,LF) -> Result
+ ++ optimize(lf,start) is a top level ANNA function to
+ ++ minimize a set of functions, \axiom{lf}, of one or more variables
+ ++ without constraints i.e. a least-squares problem.
+ ++
+ ++ The parameter \axiom{start} is a list of the initial guesses of the
+ ++ values of the variables.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+
+ goodnessOfFit:(LEF,LF) -> Result
+ ++ goodnessOfFit(lf,start) is a top level ANNA function to
+ ++ check to goodness of fit of a least squares model i.e. the minimization
+ ++ of a set of functions, \axiom{lf}, of one or more variables without
+ ++ constraints.
+ ++
+ ++ The parameter \axiom{start} is a list of the initial guesses of the
+ ++ values of the variables.
+ ++
+ ++ It iterates over the \axiom{domains} of
+ ++ \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+ ++ It then calls the numerical routine \axiomType{E04YCF} to get estimates
+ ++ of the variance-covariance matrix of the regression coefficients of
+ ++ the least-squares problem.
+ ++
+ ++ It thus returns both the results of the optimization and the
+ ++ variance-covariance calculation.
+
+ ++ goodnessOfFit(lf,start) is a top level function to iterate over
+ ++ the \axiom{domains} of \axiomType{NumericalOptimizationCategory}
+ ++ to get the name and other relevant information of the best
+ ++ \axiom{measure} and then optimize the function on that \axiom{domain}.
+ ++ It then checks the goodness of fit of the least squares model.
+
+ == add
+
+ preAnalysis:RT -> RT
+ zeroMeasure:Measure -> Result
+ optimizeSpecific:(UNOALSA,String) -> Result
+ measureSpecific:(String,RT,UNOALSA) -> Measure2
+ changeName:(Result,String) -> Result
+ recoverAfterFail:(UNOALSA,RT,Measure,INT,Result) -> Record(a:Result,b:Measure)
+ constant:UNOALSA -> Union(DF, "failed")
+ optimizeConstant:DF -> Result
+
+ import ExpertSystemToolsPackage,e04AgentsPackage,NumericalOptimizationProblem
+
+ constant(args:UNOALSA):Union(DF,"failed") ==
+ args case noa =>
+ Args := args.noa
+ f := Args.fn
+ retractIfCan(f)@Union(DoubleFloat,"failed")
+ "failed"
+
+ optimizeConstant(c:DF): Result ==
+ a := coerce(c)$AnyFunctions1(DF)
+ text := coerce("Constant Function")$AnyFunctions1(String)
+ construct([[objf@Symbol,a],[method@Symbol,text]])$Result
+
+ preAnalysis(args:UNOALSA,t:RT):RT ==
+ r := selectOptimizationRoutines(t)$RT
+ args case lsa =>
+ selectSumOfSquaresRoutines(r)$RT
+ r
+
+ zeroMeasure(m:Measure):Result ==
+ a := coerce(0$F)$AnyFunctions1(F)
+ text := coerce("Zero Measure")$AnyFunctions1(String)
+ r := construct([[objf@Symbol,a],[method@Symbol,text]])$Result
+ concat(measure2Result m,r)
+
+ measureSpecific(name:String,R:RT,args:UNOALSA): Measure2 ==
+ args case noa =>
+ arg:NOA := args.noa
+ name = "e04dgfAnnaType" => measure(R,arg)$e04dgfAnnaType
+ name = "e04fdfAnnaType" => measure(R,arg)$e04fdfAnnaType
+ name = "e04gcfAnnaType" => measure(R,arg)$e04gcfAnnaType
+ name = "e04jafAnnaType" => measure(R,arg)$e04jafAnnaType
+ name = "e04mbfAnnaType" => measure(R,arg)$e04mbfAnnaType
+ name = "e04nafAnnaType" => measure(R,arg)$e04nafAnnaType
+ name = "e04ucfAnnaType" => measure(R,arg)$e04ucfAnnaType
+ error("measureSpecific","invalid type name: " name)$ErrorFunctions
+ args case lsa =>
+ arg2:LSA := args.lsa
+ name = "e04fdfAnnaType" => measure(R,arg2)$e04fdfAnnaType
+ name = "e04gcfAnnaType" => measure(R,arg2)$e04gcfAnnaType
+ error("measureSpecific","invalid type name: " name)$ErrorFunctions
+ error("measureSpecific","invalid argument type")$ErrorFunctions
+
+ measure(Args:NumericalOptimizationProblem,R:RT):Measure ==
+ args:UNOALSA := retract(Args)$NumericalOptimizationProblem
+ sofar := 0$F
+ best := "none" :: String
+ routs := copy R
+ routs := preAnalysis(args,routs)
+ empty?(routs)$RT =>
+ error("measure", "no routines found")$ErrorFunctions
+ rout := inspect(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ meth := empty()$(List String)
+ for i in 1..# routs repeat
+ rout := extract!(routs)$RT
+ e := retract(rout.entry)$AnyFunctions1(Entry)
+ n := e.domainName
+ if e.defaultMin > sofar then
+ m := measureSpecific(n,R,args)
+ if m.measure > sofar then
+ sofar := m.measure
+ best := n
+ str := [concat(concat([string(rout.key)$Symbol,"measure: ",
+ outputMeasure(m.measure)," - "],
+ m.explanations)$(List String))$String]
+ else
+ str := [concat([string(rout.key)$Symbol
+ ," is no better than other routines"])$String]
+ meth := append(meth,str)$(List String)
+ [sofar,best,meth]
+
+ measure(args:NumericalOptimizationProblem):Measure == measure(args,routines()$RT)
+
+ optimizeSpecific(args:UNOALSA,name:String):Result ==
+ args case noa =>
+ arg:NOA := args.noa
+ name = "e04dgfAnnaType" => numericalOptimization(arg)$e04dgfAnnaType
+ name = "e04fdfAnnaType" => numericalOptimization(arg)$e04fdfAnnaType
+ name = "e04gcfAnnaType" => numericalOptimization(arg)$e04gcfAnnaType
+ name = "e04jafAnnaType" => numericalOptimization(arg)$e04jafAnnaType
+ name = "e04mbfAnnaType" => numericalOptimization(arg)$e04mbfAnnaType
+ name = "e04nafAnnaType" => numericalOptimization(arg)$e04nafAnnaType
+ name = "e04ucfAnnaType" => numericalOptimization(arg)$e04ucfAnnaType
+ error("optimizeSpecific","invalid type name: " name)$ErrorFunctions
+ args case lsa =>
+ arg2:LSA := args.lsa
+ name = "e04fdfAnnaType" => numericalOptimization(arg2)$e04fdfAnnaType
+ name = "e04gcfAnnaType" => numericalOptimization(arg2)$e04gcfAnnaType
+ error("optimizeSpecific","invalid type name: " name)$ErrorFunctions
+ error("optimizeSpecific","invalid type name: " name)$ErrorFunctions
+
+ changeName(ans:Result,name:String):Result ==
+ st:String := concat([name,"Answer"])$String
+ sy:Symbol := coerce(st)$Symbol
+ anyAns:Any := coerce(ans)$AnyFunctions1(Result)
+ construct([[sy,anyAns]])$Result
+
+ recoverAfterFail(args:UNOALSA,routs:RT,m:Measure,
+ iint:INT,r:Result):Record(a:Result,b:Measure) ==
+ while positive?(iint) repeat
+ routineName := m.name
+ s := recoverAfterFail(routs,routineName(1..6),iint)$RT
+ s case "failed" => iint := 0
+ (s = "no action")@Boolean => iint := 0
+ fl := coerce(s)$AnyFunctions1(String)
+ flrec:Record(key:Symbol,entry:Any):=[failure@Symbol,fl]
+ m2 := measure(args::NumericalOptimizationProblem,routs)
+ zero?(m2.measure) => iint := 0
+ r2:Result := optimizeSpecific(args,m2.name)
+ m := m2
+ insert!(flrec,r2)$Result
+ r := concat(r2,changeName(r,routineName))
+ iany := search(ifail@Symbol,r2)$Result
+ iany case "failed" => iint := 0
+ iint := retract(iany)$AnyFunctions1(INT)
+ [r,m]
+
+ optimize(Args:NumericalOptimizationProblem,t:RT):Result ==
+ args:UNOALSA := retract(Args)$NumericalOptimizationProblem
+ routs := copy(t)$RT
+ c:Union(DF,"failed") := constant(args)
+ c case DF => optimizeConstant(c)
+ m := measure(Args,routs)
+ zero?(m.measure) => zeroMeasure m
+ r := optimizeSpecific(args,n := m.name)
+ iany := search(ifail@Symbol,r)$Result
+ iint := 0$INT
+ if (iany case Any) then
+ iint := retract(iany)$AnyFunctions1(INT)
+ if positive?(iint) then
+ tu:Record(a:Result,b:Measure) := recoverAfterFail(args,routs,m,iint,r)
+ r := tu.a
+ m := tu.b
+ r := concat(measure2Result m,r)
+ expl := getExplanations(routs,n(1..6))$RoutinesTable
+ expla := coerce(expl)$AnyFunctions1(LST)
+ explaa:Record(key:Symbol,entry:Any) := ["explanations"::Symbol,expla]
+ r := concat(construct([explaa]),r)
+ att:List String := optAttributes(args)
+ atta := coerce(att)$AnyFunctions1(List String)
+ attr:Record(key:Symbol,entry:Any) := [attributes@Symbol,atta]
+ insert!(attr,r)$Result
+
+ optimize(args:NumericalOptimizationProblem):Result == optimize(args,routines()$RT)
+
+ goodnessOfFit(Args:NumericalOptimizationProblem):Result ==
+ r := optimize(Args)
+ args1:UNOALSA := retract(Args)$NumericalOptimizationProblem
+ args1 case noa => error("goodnessOfFit","Not an appropriate problem")
+ args:LSA := args1.lsa
+ lf := args.lfn
+ n:INT := #(variables(args))
+ m:INT := # lf
+ me := search(method,r)$Result
+ me case "failed" => r
+ meth := retract(me)$AnyFunctions1(Result)
+ na := search(nameOfRoutine,meth)$Result
+ na case "failed" => r
+ name := retract(na)$AnyFunctions1(String)
+ temp:INT := (n*(n-1)) quo 2
+ ns:INT :=
+ name = "e04fdfAnnaType" => 6*n+(2+n)*m+1+max(1,temp)
+ 8*n+(n+2)*m+temp+1+max(1,temp)
+ nv:INT := ns+n
+ ww := search(w,r)$Result
+ ww case "failed" => r
+ ws:MDF := retract(ww)$AnyFunctions1(MDF)
+ fr := search(objf,r)$Result
+ fr case "failed" => r
+ f := retract(fr)$AnyFunctions1(DF)
+ s := subMatrix(ws,1,1,ns,nv-1)$MDF
+ v := subMatrix(ws,1,1,nv,nv+n*n-1)$MDF
+ r2 := e04ycf(0,m,n,f,s,n,v,-1)$NagOptimisationPackage
+ concat(r,r2)
+
+ optimize(f:EF,start:LF,lower:LOCF,cons:LEF,upper:LOCF):Result ==
+ args:NOA := [ef2edf(f),[f2df i for i in start],[ocf2ocdf j for j in lower],
+ [ef2edf k for k in cons], [ocf2ocdf l for l in upper]]
+ optimize(args::NumericalOptimizationProblem)
+
+ optimize(f:EF,start:LF,lower:LOCF,upper:LOCF):Result ==
+ optimize(f,start,lower,empty()$LEF,upper)
+
+ optimize(f:EF,start:LF):Result ==
+ optimize(f,start,empty()$LOCF,empty()$LOCF)
+
+ optimize(lf:LEF,start:LF):Result ==
+ args:LSA := [[ef2edf i for i in lf],[f2df j for j in start]]
+ optimize(args::NumericalOptimizationProblem)
+
+ goodnessOfFit(lf:LEF,start:LF):Result ==
+ args:LSA := [[ef2edf i for i in lf],[f2df j for j in start]]
+ goodnessOfFit(args::NumericalOptimizationProblem)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package OPTPACK AnnaNumericalOptimizationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/e04agents.spad.pamphlet b/src/algebra/e04agents.spad.pamphlet
new file mode 100644
index 00000000..b001d080
--- /dev/null
+++ b/src/algebra/e04agents.spad.pamphlet
@@ -0,0 +1,313 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra e04agents.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package E04AGNT e04AgentsPackage}
+<<package E04AGNT e04AgentsPackage>>=
+)abbrev package E04AGNT e04AgentsPackage
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: June 1996
+++ Basic Operations: simple? linear?, quadratic?, nonLinear?
+++ Description:
+++ \axiomType{e04AgentsPackage} is a package of numerical agents to be used
+++ to investigate attributes of an input function so as to decide the
+++ \axiomFun{measure} of an appropriate numerical optimization routine.
+MDF ==> Matrix DoubleFloat
+VEDF ==> Vector Expression DoubleFloat
+EDF ==> Expression DoubleFloat
+EFI ==> Expression Fraction Integer
+PFI ==> Polynomial Fraction Integer
+FI ==> Fraction Integer
+F ==> Float
+DF ==> DoubleFloat
+OCDF ==> OrderedCompletion DoubleFloat
+LOCDF ==> List OrderedCompletion DoubleFloat
+LEDF ==> List Expression DoubleFloat
+PDF ==> Polynomial DoubleFloat
+LDF ==> List DoubleFloat
+INT ==> Integer
+NNI ==> NonNegativeInteger
+LS ==> List Symbol
+EF2 ==> ExpressionFunctions2
+NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+LSA ==> Record(lfn:LEDF, init:LDF)
+
+e04AgentsPackage(): E == I where
+ E ==> with
+ finiteBound:(LOCDF,DF) -> LDF
+ ++ finiteBound(l,b) repaces all instances of an infinite entry in
+ ++ \axiom{l} by a finite entry \axiom{b} or \axiom{-b}.
+ sortConstraints:NOA -> NOA
+ ++ sortConstraints(args) uses a simple bubblesort on the list of
+ ++ constraints using the degree of the expression on which to sort.
+ ++ Of course, it must match the bounds to the constraints.
+ sumOfSquares:EDF -> Union(EDF,"failed")
+ ++ sumOfSquares(f) returns either an expression for which the square is
+ ++ the original function of "failed".
+ splitLinear:EDF -> EDF
+ ++ splitLinear(f) splits the linear part from an expression which it
+ ++ returns.
+ simpleBounds?:LEDF -> Boolean
+ ++ simpleBounds?(l) returns true if the list of expressions l are
+ ++ simple.
+ linear?:LEDF -> Boolean
+ ++ linear?(l) returns true if all the bounds l are either linear or
+ ++ simple.
+ linear?:EDF -> Boolean
+ ++ linear?(e) tests if \axiom{e} is a linear function.
+ linearMatrix:(LEDF, NNI) -> MDF
+ ++ linearMatrix(l,n) returns a matrix of coefficients of the linear
+ ++ functions in \axiom{l}. If l is empty, the matrix has at least one
+ ++ row.
+ linearPart:LEDF -> LEDF
+ ++ linearPart(l) returns the list of linear functions of \axiom{l}.
+ nonLinearPart:LEDF -> LEDF
+ ++ nonLinearPart(l) returns the list of non-linear functions of \axiom{l}.
+ quadratic?:EDF -> Boolean
+ ++ quadratic?(e) tests if \axiom{e} is a quadratic function.
+ variables:LSA -> LS
+ ++ variables(args) returns the list of variables in \axiom{args.lfn}
+ varList:(EDF,NNI) -> LS
+ ++ varList(e,n) returns a list of \axiom{n} indexed variables with name
+ ++ as in \axiom{e}.
+ changeNameToObjf:(Symbol,Result) -> Result
+ ++ changeNameToObjf(s,r) changes the name of item \axiom{s} in \axiom{r}
+ ++ to objf.
+ expenseOfEvaluation:LSA -> F
+ ++ expenseOfEvaluation(o) returns the intensity value of the
+ ++ cost of evaluating the input set of functions. This is in terms
+ ++ of the number of ``operational units''. It returns a value
+ ++ in the range [0,1].
+ optAttributes:Union(noa:NOA,lsa:LSA) -> List String
+ ++ optAttributes(o) is a function for supplying a list of attributes
+ ++ of an optimization problem.
+
+ I ==> add
+
+ import ExpertSystemToolsPackage, ExpertSystemContinuityPackage
+
+ sumOfSquares2:EFI -> Union(EFI,"failed")
+ nonLinear?:EDF -> Boolean
+ finiteBound2:(OCDF,DF) -> DF
+ functionType:EDF -> String
+
+ finiteBound2(a:OCDF,b:DF):DF ==
+ not finite?(a) =>
+ positive?(a) => b
+ -b
+ retract(a)@DF
+
+ finiteBound(l:LOCDF,b:DF):LDF == [finiteBound2(i,b) for i in l]
+
+ sortConstraints(args:NOA):NOA ==
+ Args := copy args
+ c:LEDF := Args.cf
+ l:LOCDF := Args.lb
+ u:LOCDF := Args.ub
+ m:INT := (# c) - 1
+ n:INT := (# l) - m
+ for j in m..1 by -1 repeat
+ for i in 1..j repeat
+ s:EDF := c.i
+ t:EDF := c.(i+1)
+ if linear?(t) and (nonLinear?(s) or quadratic?(s)) then
+ swap!(c,i,i+1)$LEDF
+ swap!(l,n+i-1,n+i)$LOCDF
+ swap!(u,n+i-1,n+i)$LOCDF
+ Args
+
+ changeNameToObjf(s:Symbol,r:Result):Result ==
+ a := remove!(s,r)$Result
+ a case Any =>
+ insert!([objf@Symbol,a],r)$Result
+ r
+ r
+
+ sum(a:EDF,b:EDF):EDF == a+b
+
+ variables(args:LSA): LS == variables(reduce(sum,(args.lfn)))
+
+ sumOfSquares(f:EDF):Union(EDF,"failed") ==
+ e := edf2efi(f)
+ s:Union(EFI,"failed") := sumOfSquares2(e)
+ s case EFI =>
+ map(fi2df,s)$EF2(FI,DF)
+ "failed"
+
+ sumOfSquares2(f:EFI):Union(EFI,"failed") ==
+ p := retractIfCan(f)@Union(PFI,"failed")
+ p case PFI =>
+ r := squareFreePart(p)$PFI
+ (p=r)@Boolean => "failed"
+ tp := totalDegree(p)$PFI
+ tr := totalDegree(r)$PFI
+ t := tp quo tr
+ found := false
+ q := r
+ for i in 2..t by 2 repeat
+ s := q**2
+ (s=p)@Boolean =>
+ found := true
+ leave
+ q := r**i
+ if found then
+ q :: EFI
+ else
+ "failed"
+ "failed"
+
+ splitLinear(f:EDF):EDF ==
+ out := 0$EDF
+ (l := isPlus(f)$EDF) case LEDF =>
+ for i in l repeat
+ if not quadratic? i then
+ out := out + i
+ out
+ out
+
+ edf2pdf(f:EDF):PDF == (retract(f)@PDF)$EDF
+
+ varList(e:EDF,n:NNI):LS ==
+ s := name(first(variables(edf2pdf(e))$PDF)$LS)$Symbol
+ [subscript(s,[t::OutputForm]) for t in expand([1..n])$Segment(Integer)]
+
+ functionType(f:EDF):String ==
+ n := #(variables(f))$EDF
+ p := (retractIfCan(f)@Union(PDF,"failed"))$EDF
+ p case PDF =>
+ d := totalDegree(p)$PDF
+-- one?(n*d) => "simple"
+ (n*d) = 1 => "simple"
+-- one?(d) => "linear"
+ (d = 1) => "linear"
+ (d=2)@Boolean => "quadratic"
+ "non-linear"
+ "non-linear"
+
+ simpleBounds?(l: LEDF):Boolean ==
+ a := true
+ for e in l repeat
+ not (functionType(e) = "simple")@Boolean =>
+ a := false
+ leave
+ a
+
+ simple?(e:EDF):Boolean == (functionType(e) = "simple")@Boolean
+
+ linear?(e:EDF):Boolean == (functionType(e) = "linear")@Boolean
+
+ quadratic?(e:EDF):Boolean == (functionType(e) = "quadratic")@Boolean
+
+ nonLinear?(e:EDF):Boolean == (functionType(e) = "non-linear")@Boolean
+
+ linear?(l: LEDF):Boolean ==
+ a := true
+ for e in l repeat
+ s := functionType(e)
+ (s = "quadratic")@Boolean or (s = "non-linear")@Boolean =>
+ a := false
+ leave
+ a
+
+ simplePart(l:LEDF):LEDF == [i for i in l | simple?(i)]
+
+ linearPart(l:LEDF):LEDF == [i for i in l | linear?(i)]
+
+ nonLinearPart(l:LEDF):LEDF ==
+ [i for i in l | not linear?(i) and not simple?(i)]
+
+ linearMatrix(l:LEDF, n:NNI):MDF ==
+ empty?(l) => mat([],n)
+ L := linearPart l
+ M := zero(max(1,# L)$NNI,n)$MDF
+ vars := varList(first(l)$LEDF,n)
+ row:INT := 1
+ for a in L repeat
+ for j in monomials(edf2pdf(a))$PDF repeat
+ col:INT := 1
+ for c in vars repeat
+ if ((first(variables(j)$PDF)$LS)=c)@Boolean then
+ M(row,col):= first(coefficients(j)$PDF)$LDF
+ col := col+1
+ row := row + 1
+ M
+
+ expenseOfEvaluation(o:LSA):F ==
+ expenseOfEvaluation(vector(copy o.lfn)$VEDF)
+
+ optAttributes(o:Union(noa:NOA,lsa:LSA)):List String ==
+ o case noa =>
+ n := o.noa
+ s1:String := "The object function is " functionType(n.fn)
+ if empty?(n.lb) then
+ s2:String := "There are no bounds on the variables"
+ else
+ s2:String := "There are simple bounds on the variables"
+ c := n.cf
+ if empty?(c) then
+ s3:String := "There are no constraint functions"
+ else
+ t := #(c)
+ lin := #(linearPart(c))
+ nonlin := #(nonLinearPart(c))
+ s3:String := "There are " string(lin)$String " linear and "_
+ string(nonlin)$String " non-linear constraints"
+ [s1,s2,s3]
+ l := o.lsa
+ s:String := "non-linear"
+ if linear?(l.lfn) then
+ s := "linear"
+ ["The object functions are " s]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package E04AGNT e04AgentsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/e04routine.spad.pamphlet b/src/algebra/e04routine.spad.pamphlet
new file mode 100644
index 00000000..876f969d
--- /dev/null
+++ b/src/algebra/e04routine.spad.pamphlet
@@ -0,0 +1,691 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra e04routine.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain E04DGFA e04dgfAnnaType}
+<<domain E04DGFA e04dgfAnnaType>>=
+)abbrev domain E04DGFA e04dgfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: February 1996
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04dgfAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04DGF, a general optimization routine which
+++ can handle some singularities in the input function. The function
+++ \axiomFun{measure} measures the usefulness of the routine E04DGF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+
+e04dgfAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep, NagOptimisationPackage, ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:NOA) ==
+ string:String := "e04dgf is "
+ positive?(#(args.cf) + #(args.lb) + #(args.ub)) =>
+ string := concat(string,"unsuitable for constrained problems. ")
+ [0.0,string]
+ string := concat(string,"recommended")
+ [getMeasure(R,e04dgf@Symbol)$RoutinesTable, string]
+
+ numericalOptimization(args:NOA) ==
+ argsFn:EDF := args.fn
+ n:NNI := #(variables(argsFn)$EDF)
+ fu:DF := float(4373903597,-24,10)$DF
+ it:INT := max(50,5*n)
+ lin:DF := float(9,-1,10)$DF
+ ma:DF := float(1,20,10)$DF
+ op:DF := float(326,-14,10)$DF
+ x:MDF := mat(args.init,n)
+ ArgsFn:Expression Float := edf2ef(argsFn)
+ f:Union(fn:FileName,fp:Asp49(OBJFUN)) := [retract(ArgsFn)$Asp49(OBJFUN)]
+ e04dgf(n,1$DF,fu,it,lin,true,ma,op,1,1,n,0,x,-1,f)
+
+@
+\section{domain E04FDFA e04fdfAnnaType}
+<<domain E04FDFA e04fdfAnnaType>>=
+)abbrev domain E04FDFA e04fdfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: February 1996
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04fdfAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04FDF, a general optimization routine which
+++ can handle some singularities in the input function. The function
+++ \axiomFun{measure} measures the usefulness of the routine E04FDF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+e04fdfAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep, NagOptimisationPackage
+ import e04AgentsPackage,ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:NOA) ==
+ argsFn := args.fn
+ string:String := "e04fdf is "
+ positive?(#(args.cf) + #(args.lb) + #(args.ub)) =>
+ string := concat(string,"unsuitable for constrained problems. ")
+ [0.0,string]
+ n:NNI := #(variables(argsFn)$EDF)
+ (n>1)@Boolean =>
+ string := concat(string,"unsuitable for single instances of multivariate problems. ")
+ [0.0,string]
+ sumOfSquares(argsFn) case "failed" =>
+ string := concat(string,"unsuitable.")
+ [0.0,string]
+ string := concat(string,"recommended since the function is a sum of squares.")
+ [getMeasure(R,e04fdf@Symbol)$RoutinesTable, string]
+
+ measure(R:RoutinesTable,args:LSA) ==
+ string:String := "e04fdf is recommended"
+ [getMeasure(R,e04fdf@Symbol)$RoutinesTable, string]
+
+ numericalOptimization(args:NOA) ==
+ argsFn := args.fn
+ lw:INT := 14
+ x := mat(args.init,1)
+ (a := sumOfSquares(argsFn)) case EDF =>
+ ArgsFn := vector([edf2ef(a)])$VEF
+ f : Union(fn:FileName,fp:Asp50(LSFUN1)) := [retract(ArgsFn)$Asp50(LSFUN1)]
+ out:Result := e04fdf(1,1,1,lw,x,-1,f)
+ changeNameToObjf(fsumsq@Symbol,out)
+ empty()$Result
+
+ numericalOptimization(args:LSA) ==
+ argsFn := copy args.lfn
+ m:INT := #(argsFn)
+ n:NNI := #(variables(args))
+ nn:INT := n
+ lw:INT :=
+-- one?(nn) => 9+5*m
+ (nn = 1) => 9+5*m
+ nn*(7+n+2*m+((nn-1) quo 2)$INT)+3*m
+ x := mat(args.init,n)
+ ArgsFn := vector([edf2ef(i)$ExpertSystemToolsPackage for i in argsFn])$VEF
+ f : Union(fn:FileName,fp:Asp50(LSFUN1)) := [retract(ArgsFn)$Asp50(LSFUN1)]
+ out:Result := e04fdf(m,n,1,lw,x,-1,f)
+ changeNameToObjf(fsumsq@Symbol,out)
+
+@
+\section{domain E04GCFA e04gcfAnnaType}
+<<domain E04GCFA e04gcfAnnaType>>=
+)abbrev domain E04GCFA e04gcfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: February 1996
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04gcfAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04GCF, a general optimization routine which
+++ can handle some singularities in the input function. The function
+++ \axiomFun{measure} measures the usefulness of the routine E04GCF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+e04gcfAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep, NagOptimisationPackage,ExpertSystemContinuityPackage
+ import e04AgentsPackage,ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:NOA) ==
+ argsFn:EDF := args.fn
+ string:String := "e04gcf is "
+ positive?(#(args.cf) + #(args.lb) + #(args.ub)) =>
+ string := concat(string,"unsuitable for constrained problems. ")
+ [0.0,string]
+ n:NNI := #(variables(argsFn)$EDF)
+ (n>1)@Boolean =>
+ string := concat(string,"unsuitable for single instances of multivariate problems. ")
+ [0.0,string]
+ a := coerce(float(10,0,10))$OCDF
+ seg:SOCDF := -a..a
+ sings := singularitiesOf(argsFn,variables(argsFn)$EDF,seg)
+ s := #(sdf2lst(sings))
+ positive? s =>
+ string := concat(string,"not recommended for discontinuous functions.")
+ [0.0,string]
+ sumOfSquares(args.fn) case "failed" =>
+ string := concat(string,"unsuitable.")
+ [0.0,string]
+ string := concat(string,"recommended since the function is a sum of squares.")
+ [getMeasure(R,e04gcf@Symbol)$RoutinesTable, string]
+
+ measure(R:RoutinesTable,args:LSA) ==
+ string:String := "e04gcf is "
+ a := coerce(float(10,0,10))$OCDF
+ seg:SOCDF := -a..a
+ sings := concat([singularitiesOf(i,variables(args),seg) for i in args.lfn])$SDF
+ s := #(sdf2lst(sings))
+ positive? s =>
+ string := concat(string,"not recommended for discontinuous functions.")
+ [0.0,string]
+ string := concat(string,"recommended.")
+ m := getMeasure(R,e04gcf@Symbol)$RoutinesTable
+ m := m-(1-exp(-(expenseOfEvaluation(args))**3))
+ [m, string]
+
+ numericalOptimization(args:NOA) ==
+ argsFn:EDF := args.fn
+ lw:INT := 16
+ x := mat(args.init,1)
+ (a := sumOfSquares(argsFn)) case EDF =>
+ ArgsFn := vector([edf2ef(a)$ExpertSystemToolsPackage])$VEF
+ f : Union(fn:FileName,fp:Asp19(LSFUN2)) := [retract(ArgsFn)$Asp19(LSFUN2)]
+ out:Result := e04gcf(1,1,1,lw,x,-1,f)
+ changeNameToObjf(fsumsq@Symbol,out)
+ empty()$Result
+
+ numericalOptimization(args:LSA) ==
+ argsFn := copy args.lfn
+ m:NNI := #(argsFn)
+ n:NNI := #(variables(args))
+ lw:INT :=
+-- one?(n) => 11+5*m
+ (n = 1) => 11+5*m
+ 2*n*(4+n+m)+3*m
+ x := mat(args.init,n)
+ ArgsFn := vector([edf2ef(i)$ExpertSystemToolsPackage for i in argsFn])$VEF
+ f : Union(fn:FileName,fp:Asp19(LSFUN2)) := [retract(ArgsFn)$Asp19(LSFUN2)]
+ out:Result := e04gcf(m,n,1,lw,x,-1,f)
+ changeNameToObjf(fsumsq@Symbol,out)
+
+@
+\section{domain E04JAFA e04jafAnnaType}
+<<domain E04JAFA e04jafAnnaType>>=
+)abbrev domain E04JAFA e04jafAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: February 1996
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04jafAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04JAF, a general optimization routine which
+++ can handle some singularities in the input function. The function
+++ \axiomFun{measure} measures the usefulness of the routine E04JAF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+e04jafAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep, NagOptimisationPackage
+ import e04AgentsPackage,ExpertSystemToolsPackage
+
+ bound(a:LOCDF,b:LOCDF):Integer ==
+ empty?(concat(a,b)) => 1
+-- one?(#(removeDuplicates(a))) and zero?(first(a)) => 2
+ (#(removeDuplicates(a)) = 1) and zero?(first(a)) => 2
+-- one?(#(removeDuplicates(a))) and one?(#(removeDuplicates(b))) => 3
+ (#(removeDuplicates(a)) = 1) and (#(removeDuplicates(b)) = 1) => 3
+ 0
+
+ measure(R:RoutinesTable,args:NOA) ==
+ string:String := "e04jaf is "
+ if positive?(#(args.cf)) then
+ if not simpleBounds?(args.cf) then
+ string :=
+ concat(string,"suitable for simple bounds only, not constraint functions.")
+ (# string) < 20 =>
+ if zero?(#(args.lb) + #(args.ub)) then
+ string := concat(string, "usable if there are no constraints")
+ [getMeasure(R,e04jaf@Symbol)$RoutinesTable*0.5,string]
+ else
+ string := concat(string,"recommended")
+ [getMeasure(R,e04jaf@Symbol)$RoutinesTable, string]
+ [0.0,string]
+
+ numericalOptimization(args:NOA) ==
+ argsFn:EDF := args.fn
+ n:NNI := #(variables(argsFn)$EDF)
+ ibound:INT := bound(args.lb,args.ub)
+ m:INT := n
+ lw:INT := max(13,12 * m + ((m * (m - 1)) quo 2)$INT)$INT
+ bl := mat(finiteBound(args.lb,float(1,6,10)$DF),n)
+ bu := mat(finiteBound(args.ub,float(1,6,10)$DF),n)
+ x := mat(args.init,n)
+ ArgsFn:EF := edf2ef(argsFn)
+ fr:Union(fn:FileName,fp:Asp24(FUNCT1)) := [retract(ArgsFn)$Asp24(FUNCT1)]
+ out:Result := e04jaf(n,ibound,n+2,lw,bl,bu,x,-1,fr)
+ changeNameToObjf(f@Symbol,out)
+
+@
+\section{domain E04MBFA e04mbfAnnaType}
+<<domain E04MBFA e04mbfAnnaType>>=
+)abbrev domain E04MBFA e04mbfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: February 1996
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04mbfAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04MBF, an optimization routine for Linear functions.
+++ The function
+++ \axiomFun{measure} measures the usefulness of the routine E04MBF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+e04mbfAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep, NagOptimisationPackage
+ import e04AgentsPackage,ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:NOA) ==
+ (not linear?([args.fn])) or (not linear?(args.cf)) =>
+ [0.0,"e04mbf is for a linear objective function and constraints only."]
+ [getMeasure(R,e04mbf@Symbol)$RoutinesTable,"e04mbf is recommended" ]
+
+ numericalOptimization(args:NOA) ==
+ argsFn:EDF := args.fn
+ c := args.cf
+ listVars:List LS := concat(variables(argsFn)$EDF,[variables(z)$EDF for z in c])
+ n:NNI := #(v := removeDuplicates(concat(listVars)$LS)$LS)
+ A:MDF := linearMatrix(args.cf,n)
+ nclin:NNI := # linearPart(c)
+ nrowa:NNI := max(1,nclin)
+ bl:MDF := mat(finiteBound(args.lb,float(1,21,10)$DF),n)
+ bu:MDF := mat(finiteBound(args.ub,float(1,21,10)$DF),n)
+ cvec:MDF := mat(coefficients(retract(argsFn)@PDF)$PDF,n)
+ x := mat(args.init,n)
+ lwork:INT :=
+ nclin < n => 2*nclin*(nclin+4)+2+6*n+nrowa
+ 2*(n+3)*n+4*nclin+nrowa
+ out:Result := e04mbf(20,1,n,nclin,n+nclin,nrowa,A,bl,bu,cvec,true,2*n,lwork,x,-1)
+ changeNameToObjf(objlp@Symbol,out)
+
+@
+\section{domain E04NAFA e04nafAnnaType}
+<<domain E04NAFA e04nafAnnaType>>=
+)abbrev domain E04NAFA e04nafAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: February 1996
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04nafAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04NAF, an optimization routine for Quadratic functions.
+++ The function
+++ \axiomFun{measure} measures the usefulness of the routine E04NAF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+e04nafAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep, NagOptimisationPackage
+ import e04AgentsPackage,ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:NOA) ==
+ string:String := "e04naf is "
+ argsFn:EDF := args.fn
+ if not (quadratic?(argsFn) and linear?(args.cf)) then
+ string :=
+ concat(string,"for a quadratic function with linear constraints only.")
+ (# string) < 20 =>
+ string := concat(string,"recommended")
+ [getMeasure(R,e04naf@Symbol)$RoutinesTable, string]
+ [0.0,string]
+
+ numericalOptimization(args:NOA) ==
+ argsFn:EDF := args.fn
+ c := args.cf
+ listVars:List LS := concat(variables(argsFn)$EDF,[variables(z)$EDF for z in c])
+ n:NNI := #(v := sort(removeDuplicates(concat(listVars)$LS)$LS)$LS)
+ A:MDF := linearMatrix(c,n)
+ nclin:NNI := # linearPart(c)
+ nrowa:NNI := max(1,nclin)
+ big:DF := float(1,10,10)$DF
+ fea:MDF := new(1,n+nclin,float(1053,-11,10)$DF)$MDF
+ bl:MDF := mat(finiteBound(args.lb,float(1,21,10)$DF),n)
+ bu:MDF := mat(finiteBound(args.ub,float(1,21,10)$DF),n)
+ alin:EDF := splitLinear(argsFn)
+ p:PDF := retract(alin)@PDF
+ pl:List PDF := [coefficient(p,i,1)$PDF for i in v]
+ cvec:MDF := mat([pdf2df j for j in pl],n)
+ h1:MPDF := hessian(p,v)$MVCF(S,PDF,VPDF,LS)
+ hess:MDF := map(pdf2df,h1)$ESTOOLS2(PDF,DF)
+ h2:MEF := map(df2ef,hess)$ESTOOLS2(DF,EF)
+ x := mat(args.init,n)
+ istate:MI := zero(1,n+nclin)$MI
+ lwork:INT := 2*n*(n+2*nclin)+nrowa
+ qphess:Union(fn:FileName,fp:Asp20(QPHESS)) := [retract(h2)$Asp20(QPHESS)]
+ out:Result := e04naf(20,1,n,nclin,n+nclin,nrowa,n,n,big,A,bl,bu,cvec,fea,
+ hess,true,false,true,2*n,lwork,x,istate,-1,qphess)
+ changeNameToObjf(obj@Symbol,out)
+
+@
+\section{domain E04UCFA e04ucfAnnaType}
+<<domain E04UCFA e04ucfAnnaType>>=
+)abbrev domain E04UCFA e04ucfAnnaType
+++ Author: Brian Dupee
+++ Date Created: February 1996
+++ Date Last Updated: November 1997
+++ Basic Operations: measure, numericalOptimization
+++ Related Constructors: Result, RoutinesTable
+++ Description:
+++ \axiomType{e04ucfAnnaType} is a domain of \axiomType{NumericalOptimization}
+++ for the NAG routine E04UCF, a general optimization routine which
+++ can handle some singularities in the input function. The function
+++ \axiomFun{measure} measures the usefulness of the routine E04UCF
+++ for the given problem. The function \axiomFun{numericalOptimization}
+++ performs the optimization by using \axiomType{NagOptimisationPackage}.
+e04ucfAnnaType(): NumericalOptimizationCategory == Result add
+ DF ==> DoubleFloat
+ EF ==> Expression Float
+ EDF ==> Expression DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ VPDF ==> Vector Polynomial DoubleFloat
+ LDF ==> List DoubleFloat
+ LOCDF ==> List OrderedCompletion DoubleFloat
+ MDF ==> Matrix DoubleFloat
+ MPDF ==> Matrix Polynomial DoubleFloat
+ MF ==> Matrix Float
+ MEF ==> Matrix Expression Float
+ LEDF ==> List Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ NOA ==> Record(fn:EDF, init:LDF, lb:LOCDF, cf:LEDF, ub:LOCDF)
+ LSA ==> Record(lfn:LEDF, init:LDF)
+ EF2 ==> ExpressionFunctions2
+ MI ==> Matrix Integer
+ INT ==> Integer
+ F ==> Float
+ NNI ==> NonNegativeInteger
+ S ==> Symbol
+ LS ==> List Symbol
+ MVCF ==> MultiVariableCalculusFunctions
+ ESTOOLS2 ==> ExpertSystemToolsPackage2
+ SDF ==> Stream DoubleFloat
+ LSDF ==> List Stream DoubleFloat
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ OCDF ==> OrderedCompletion DoubleFloat
+
+ Rep:=Result
+ import Rep,NagOptimisationPackage
+ import e04AgentsPackage,ExpertSystemToolsPackage
+
+ measure(R:RoutinesTable,args:NOA) ==
+ zero?(#(args.lb) + #(args.ub)) =>
+ [0.0,"e04ucf is not recommended if there are no bounds specified"]
+ zero?(#(args.cf)) =>
+ string:String := "e04ucf is usable but not always recommended if there are no constraints"
+ [getMeasure(R,e04ucf@Symbol)$RoutinesTable*0.5,string]
+ [getMeasure(R,e04ucf@Symbol)$RoutinesTable,"e04ucf is recommended"]
+
+ numericalOptimization(args:NOA) ==
+ Args := sortConstraints(args)
+ argsFn := Args.fn
+ c := Args.cf
+ listVars:List LS := concat(variables(argsFn)$EDF,[variables(z)$EDF for z in c])
+ n:NNI := #(v := sort(removeDuplicates(concat(listVars)$LS)$LS)$LS)
+ lin:NNI := #(linearPart(c))
+ nlcf := nonLinearPart(c)
+ nonlin:NNI := #(nlcf)
+ if empty?(nlcf) then
+ nlcf := new(n,coerce(first(v)$LS)$EDF)$LEDF
+ nrowa:NNI := max(1,lin)
+ nrowj:NNI := max(1,nonlin)
+ A:MDF := linearMatrix(c,n)
+ bl:MDF := mat(finiteBound(Args.lb,float(1,25,10)$DF),n)
+ bu:MDF := mat(finiteBound(Args.ub,float(1,25,10)$DF),n)
+ liwork:INT := 3*n+lin+2*nonlin
+ lwork:INT :=
+ zero?(lin+nonlin) => 20*n
+ zero?(nonlin) => 2*n*(n+10)+11*lin
+ 2*n*(n+nonlin+10)+(11+n)*lin + 21*nonlin
+ cra:DF := float(1,-2,10)$DF
+ fea:DF := float(1053671201,-17,10)$DF
+ fun:DF := float(4373903597,-24,10)$DF
+ infb:DF := float(1,15,10)$DF
+ lint:DF := float(9,-1,10)$DF
+ maji:INT := max(50,3*(n+lin)+10*nonlin)
+ mini:INT := max(50,3*(n+lin+nonlin))
+ nonf:DF := float(105,-10,10)$DF
+ opt:DF := float(326,-10,10)$DF
+ ste:DF := float(2,0,10)$DF
+ istate:MI := zero(1,n+lin+nonlin)$MI
+ cjac:MDF :=
+ positive?(nonlin) => zero(nrowj,n)$MDF
+ zero(nrowj,1)$MDF
+ clambda:MDF := zero(1,n+lin+nonlin)$MDF
+ r:MDF := zero(n,n)$MDF
+ x:MDF := mat(Args.init,n)
+ VectCF:VEF := vector([edf2ef e for e in nlcf])$VEF
+ ArgsFn:EF := edf2ef(argsFn)
+ fasp : Union(fn:FileName,fp:Asp49(OBJFUN)) := [retract(ArgsFn)$Asp49(OBJFUN)]
+ casp : Union(fn:FileName,fp:Asp55(CONFUN)) := [retract(VectCF)$Asp55(CONFUN)]
+ e04ucf(n,lin,nonlin,nrowa,nrowj,n,A,bl,bu,liwork,lwork,false,cra,3,fea,
+ fun,true,infb,infb,fea,lint,true,maji,1,mini,0,-1,nonf,opt,ste,1,
+ 1,n,n,3,istate,cjac,clambda,r,x,-1,casp,fasp)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain E04DGFA e04dgfAnnaType>>
+<<domain E04FDFA e04fdfAnnaType>>
+<<domain E04GCFA e04gcfAnnaType>>
+<<domain E04JAFA e04jafAnnaType>>
+<<domain E04MBFA e04mbfAnnaType>>
+<<domain E04NAFA e04nafAnnaType>>
+<<domain E04UCFA e04ucfAnnaType>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/efstruc.spad.pamphlet b/src/algebra/efstruc.spad.pamphlet
new file mode 100644
index 00000000..6ac57be1
--- /dev/null
+++ b/src/algebra/efstruc.spad.pamphlet
@@ -0,0 +1,961 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra efstruc.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SYMFUNC SymmetricFunctions}
+<<package SYMFUNC SymmetricFunctions>>=
+)abbrev package SYMFUNC SymmetricFunctions
+++ The elementary symmetric functions
+++ Author: Manuel Bronstein
+++ Date Created: 13 Feb 1989
+++ Date Last Updated: 28 Jun 1990
+++ Description: Computes all the symmetric functions in n variables.
+SymmetricFunctions(R:Ring): Exports == Implementation where
+ UP ==> SparseUnivariatePolynomial R
+
+ Exports ==> with
+ symFunc: List R -> Vector R
+ ++ symFunc([r1,...,rn]) returns the vector of the
+ ++ elementary symmetric functions in the \spad{ri's}:
+ ++ \spad{[r1 + ... + rn, r1 r2 + ... + r(n-1) rn, ..., r1 r2 ... rn]}.
+ symFunc: (R, PositiveInteger) -> Vector R
+ ++ symFunc(r, n) returns the vector of the elementary
+ ++ symmetric functions in \spad{[r,r,...,r]} \spad{n} times.
+
+ Implementation ==> add
+ signFix: (UP, NonNegativeInteger) -> Vector R
+
+ symFunc(x, n) == signFix((monomial(1, 1)$UP - x::UP) ** n, 1 + n)
+
+ symFunc l ==
+ signFix(*/[monomial(1, 1)$UP - a::UP for a in l], 1 + #l)
+
+ signFix(p, n) ==
+ m := minIndex(v := vectorise(p, n)) + 1
+ for i in 0..((#v quo 2) - 1)::NonNegativeInteger repeat
+ qsetelt_!(v, 2*i + m, - qelt(v, 2*i + m))
+ reverse_! v
+
+@
+\section{package TANEXP TangentExpansions}
+<<package TANEXP TangentExpansions>>=
+)abbrev package TANEXP TangentExpansions
+++ Expansions of tangents of sums and quotients
+++ Author: Manuel Bronstein
+++ Date Created: 13 Feb 1989
+++ Date Last Updated: 20 Apr 1990
+++ Description: Expands tangents of sums and scalar products.
+TangentExpansions(R:Field): Exports == Implementation where
+ PI ==> PositiveInteger
+ Z ==> Integer
+ UP ==> SparseUnivariatePolynomial R
+ QF ==> Fraction UP
+
+ Exports ==> with
+ tanSum: List R -> R
+ ++ tanSum([a1,...,an]) returns \spad{f(a1,...,an)} such that
+ ++ if \spad{ai = tan(ui)} then \spad{f(a1,...,an) = tan(u1 + ... + un)}.
+ tanAn : (R, PI) -> UP
+ ++ tanAn(a, n) returns \spad{P(x)} such that
+ ++ if \spad{a = tan(u)} then \spad{P(tan(u/n)) = 0}.
+ tanNa : (R, Z) -> R
+ ++ tanNa(a, n) returns \spad{f(a)} such that
+ ++ if \spad{a = tan(u)} then \spad{f(a) = tan(n * u)}.
+
+ Implementation ==> add
+ import SymmetricFunctions(R)
+ import SymmetricFunctions(UP)
+
+ m1toN : Integer -> Integer
+ tanPIa: PI -> QF
+
+ m1toN n == (odd? n => -1; 1)
+ tanAn(a, n) == a * denom(q := tanPIa n) - numer q
+
+ tanNa(a, n) ==
+ zero? n => 0
+ negative? n => - tanNa(a, -n)
+ (numer(t := tanPIa(n::PI)) a) / ((denom t) a)
+
+ tanSum l ==
+ m := minIndex(v := symFunc l)
+ +/[m1toN(i+1) * v(2*i - 1 + m) for i in 1..(#v quo 2)]
+ / +/[m1toN(i) * v(2*i + m) for i in 0..((#v - 1) quo 2)]
+
+-- tanPIa(n) returns P(a)/Q(a) such that
+-- if a = tan(u) then P(a)/Q(a) = tan(n * u);
+ tanPIa n ==
+ m := minIndex(v := symFunc(monomial(1, 1)$UP, n))
+ +/[m1toN(i+1) * v(2*i - 1 + m) for i in 1..(#v quo 2)]
+ / +/[m1toN(i) * v(2*i + m) for i in 0..((#v - 1) quo 2)]
+
+@
+\section{package EFSTRUC ElementaryFunctionStructurePackage}
+<<package EFSTRUC ElementaryFunctionStructurePackage>>=
+)abbrev package EFSTRUC ElementaryFunctionStructurePackage
+++ Risch structure theorem
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 16 August 1995
+++ Description:
+++ ElementaryFunctionStructurePackage provides functions to test the
+++ algebraic independence of various elementary functions, using the
+++ Risch structure theorem (real and complex versions).
+++ It also provides transformations on elementary functions
+++ which are not considered simplifications.
+++ Keywords: elementary, function, structure.
+ElementaryFunctionStructurePackage(R,F): Exports == Implementation where
+ R : Join(IntegralDomain, OrderedSet, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer)
+ F : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory,
+ FunctionSpace R)
+
+ B ==> Boolean
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Z
+ SY ==> Symbol
+ K ==> Kernel F
+ UP ==> SparseUnivariatePolynomial F
+ SMP ==> SparseMultivariatePolynomial(R, K)
+ REC ==> Record(func:F, kers: List K, vals:List F)
+ U ==> Union(vec:Vector Q, func:F, fail: Boolean)
+ POWER ==> "%power"::SY
+ NTHR ==> "nthRoot"::SY
+
+ Exports ==> with
+ normalize: F -> F
+ ++ normalize(f) rewrites \spad{f} using the least possible number of
+ ++ real algebraically independent kernels.
+ normalize: (F, SY) -> F
+ ++ normalize(f, x) rewrites \spad{f} using the least possible number of
+ ++ real algebraically independent kernels involving \spad{x}.
+ rischNormalize: (F, SY) -> REC
+ ++ rischNormalize(f, x) returns \spad{[g, [k1,...,kn], [h1,...,hn]]}
+ ++ such that \spad{g = normalize(f, x)} and each \spad{ki} was
+ ++ rewritten as \spad{hi} during the normalization.
+ realElementary: F -> F
+ ++ realElementary(f) rewrites \spad{f} in terms of the 4 fundamental real
+ ++ transcendental elementary functions: \spad{log, exp, tan, atan}.
+ realElementary: (F, SY) -> F
+ ++ realElementary(f,x) rewrites the kernels of \spad{f} involving \spad{x}
+ ++ in terms of the 4 fundamental real
+ ++ transcendental elementary functions: \spad{log, exp, tan, atan}.
+ validExponential: (List K, F, SY) -> Union(F, "failed")
+ ++ validExponential([k1,...,kn],f,x) returns \spad{g} if \spad{exp(f)=g}
+ ++ and \spad{g} involves only \spad{k1...kn}, and "failed" otherwise.
+ rootNormalize: (F, K) -> F
+ ++ rootNormalize(f, k) returns \spad{f} rewriting either \spad{k} which
+ ++ must be an nth-root in terms of radicals already in \spad{f}, or some
+ ++ radicals in \spad{f} in terms of \spad{k}.
+ tanQ: (Q, F) -> F
+ ++ tanQ(q,a) is a local function with a conditional implementation.
+
+ Implementation ==> add
+ import TangentExpansions F
+ import IntegrationTools(R, F)
+ import IntegerLinearDependence F
+ import AlgebraicManipulations(R, F)
+ import InnerCommonDenominator(Z, Q, Vector Z, Vector Q)
+
+ k2Elem : (K, List SY) -> F
+ realElem : (F, List SY) -> F
+ smpElem : (SMP, List SY) -> F
+ deprel : (List K, K, SY) -> U
+ rootDep : (List K, K) -> U
+ qdeprel : (List F, F) -> U
+ factdeprel : (List K, K) -> U
+ toR : (List K, F) -> List K
+ toY : List K -> List F
+ toZ : List K -> List F
+ toU : List K -> List F
+ toV : List K -> List F
+ ktoY : K -> F
+ ktoZ : K -> F
+ ktoU : K -> F
+ ktoV : K -> F
+ gdCoef? : (Q, Vector Q) -> Boolean
+ goodCoef : (Vector Q, List K, SY) ->
+ Union(Record(index:Z, ker:K), "failed")
+ tanRN : (Q, K) -> F
+ localnorm : F -> F
+ rooteval : (F, List K, K, Q) -> REC
+ logeval : (F, List K, K, Vector Q) -> REC
+ expeval : (F, List K, K, Vector Q) -> REC
+ taneval : (F, List K, K, Vector Q) -> REC
+ ataneval : (F, List K, K, Vector Q) -> REC
+ depeval : (F, List K, K, Vector Q) -> REC
+ expnosimp : (F, List K, K, Vector Q, List F, F) -> REC
+ tannosimp : (F, List K, K, Vector Q, List F, F) -> REC
+ rtNormalize : F -> F
+ rootNormalize0 : F -> REC
+ rootKernelNormalize: (F, List K, K) -> Union(REC, "failed")
+ tanSum : (F, List F) -> F
+
+ comb? := F has CombinatorialOpsCategory
+ mpiover2:F := pi()$F / (-2::F)
+
+ realElem(f, l) == smpElem(numer f, l) / smpElem(denom f, l)
+ realElementary(f, x) == realElem(f, [x])
+ realElementary f == realElem(f, variables f)
+ toY ker == [func for k in ker | (func := ktoY k) ^= 0]
+ toZ ker == [func for k in ker | (func := ktoZ k) ^= 0]
+ toU ker == [func for k in ker | (func := ktoU k) ^= 0]
+ toV ker == [func for k in ker | (func := ktoV k) ^= 0]
+ rtNormalize f == rootNormalize0(f).func
+ toR(ker, x) == select(is?(#1, NTHR) and first argument(#1) = x, ker)
+
+ if R has GcdDomain then
+ tanQ(c, x) ==
+ tanNa(rootSimp zeroOf tanAn(x, denom(c)::PositiveInteger), numer c)
+ else
+ tanQ(c, x) ==
+ tanNa(zeroOf tanAn(x, denom(c)::PositiveInteger), numer c)
+
+ -- tanSum(c, [a1,...,an]) returns f(c, a1,...,an) such that
+ -- if ai = tan(ui) then f(c, a1,...,an) = tan(c + u1 + ... + un).
+ -- MUST BE CAREFUL FOR WHEN c IS AN ODD MULTIPLE of pi/2
+ tanSum(c, l) ==
+ k := c / mpiover2 -- k = - 2 c / pi, check for odd integer
+ -- tan((2n+1) pi/2 x) = - 1 / tan x
+ (r := retractIfCan(k)@Union(Z, "failed")) case Z and odd?(r::Z) =>
+ - inv tanSum l
+ tanSum concat(tan c, l)
+
+ rootNormalize0 f ==
+ ker := select_!(is?(#1, NTHR) and empty? variables first argument #1,
+ tower f)$List(K)
+ empty? ker => [f, empty(), empty()]
+ (n := (#ker)::Z - 1) < 1 => [f, empty(), empty()]
+ for i in 1..n for kk in rest ker repeat
+ (u := rootKernelNormalize(f, first(ker, i), kk)) case REC =>
+ rec := u::REC
+ rn := rootNormalize0(rec.func)
+ return [rn.func, concat(rec.kers, rn.kers), concat(rec.vals, rn.vals)]
+ [f, empty(), empty()]
+
+ deprel(ker, k, x) ==
+ is?(k, "log"::SY) or is?(k, "exp"::SY) =>
+ qdeprel([differentiate(g, x) for g in toY ker],
+ differentiate(ktoY k, x))
+ is?(k, "atan"::SY) or is?(k, "tan"::SY) =>
+ qdeprel([differentiate(g, x) for g in toU ker],
+ differentiate(ktoU k, x))
+ is?(k, NTHR) => rootDep(ker, k)
+ comb? and is?(k, "factorial"::SY) =>
+ factdeprel([x for x in ker | is?(x,"factorial"::SY) and x^=k],k)
+ [true]
+
+ ktoY k ==
+ is?(k, "log"::SY) => k::F
+ is?(k, "exp"::SY) => first argument k
+ 0
+
+ ktoZ k ==
+ is?(k, "log"::SY) => first argument k
+ is?(k, "exp"::SY) => k::F
+ 0
+
+ ktoU k ==
+ is?(k, "atan"::SY) => k::F
+ is?(k, "tan"::SY) => first argument k
+ 0
+
+ ktoV k ==
+ is?(k, "tan"::SY) => k::F
+ is?(k, "atan"::SY) => first argument k
+ 0
+
+ smpElem(p, l) ==
+ map(k2Elem(#1, l), #1::F, p)$PolynomialCategoryLifting(
+ IndexedExponents K, K, R, SMP, F)
+
+ k2Elem(k, l) ==
+ ez, iez, tz2: F
+ kf := k::F
+ not(empty? l) and empty? [v for v in variables kf | member?(v, l)] => kf
+ empty?(args :List F := [realElem(a, l) for a in argument k]) => kf
+ z := first args
+ is?(k, POWER) => (zero? z => 0; exp(last(args) * log z))
+ is?(k, "cot"::SY) => inv tan z
+ is?(k, "acot"::SY) => atan inv z
+ is?(k, "asin"::SY) => atan(z / sqrt(1 - z**2))
+ is?(k, "acos"::SY) => atan(sqrt(1 - z**2) / z)
+ is?(k, "asec"::SY) => atan sqrt(1 - z**2)
+ is?(k, "acsc"::SY) => atan inv sqrt(1 - z**2)
+ is?(k, "asinh"::SY) => log(sqrt(1 + z**2) + z)
+ is?(k, "acosh"::SY) => log(sqrt(z**2 - 1) + z)
+ is?(k, "atanh"::SY) => log((z + 1) / (1 - z)) / (2::F)
+ is?(k, "acoth"::SY) => log((z + 1) / (z - 1)) / (2::F)
+ is?(k, "asech"::SY) => log((inv z) + sqrt(inv(z**2) - 1))
+ is?(k, "acsch"::SY) => log((inv z) + sqrt(1 + inv(z**2)))
+ is?(k, "%paren"::SY) or is?(k, "%box"::SY) =>
+ empty? rest args => z
+ kf
+ if has?(op := operator k, "htrig") then iez := inv(ez := exp z)
+ is?(k, "sinh"::SY) => (ez - iez) / (2::F)
+ is?(k, "cosh"::SY) => (ez + iez) / (2::F)
+ is?(k, "tanh"::SY) => (ez - iez) / (ez + iez)
+ is?(k, "coth"::SY) => (ez + iez) / (ez - iez)
+ is?(k, "sech"::SY) => 2 * inv(ez + iez)
+ is?(k, "csch"::SY) => 2 * inv(ez - iez)
+ if has?(op, "trig") then tz2 := tan(z / (2::F))
+ is?(k, "sin"::SY) => 2 * tz2 / (1 + tz2**2)
+ is?(k, "cos"::SY) => (1 - tz2**2) / (1 + tz2**2)
+ is?(k, "sec"::SY) => (1 + tz2**2) / (1 - tz2**2)
+ is?(k, "csc"::SY) => (1 + tz2**2) / (2 * tz2)
+ op args
+
+--The next 5 functions are used by normalize, once a relation is found
+ depeval(f, lk, k, v) ==
+ is?(k, "log"::SY) => logeval(f, lk, k, v)
+ is?(k, "exp"::SY) => expeval(f, lk, k, v)
+ is?(k, "tan"::SY) => taneval(f, lk, k, v)
+ is?(k, "atan"::SY) => ataneval(f, lk, k, v)
+ is?(k, NTHR) => rooteval(f, lk, k, v(minIndex v))
+ [f, empty(), empty()]
+
+ rooteval(f, lk, k, n) ==
+ nv := nthRoot(x := first argument k, m := retract(n)@Z)
+ l := [r for r in concat(k, toR(lk, x)) |
+ retract(second argument r)@Z ^= m]
+ lv := [nv ** (n / (retract(second argument r)@Z::Q)) for r in l]
+ [eval(f, l, lv), l, lv]
+
+ ataneval(f, lk, k, v) ==
+ w := first argument k
+ s := tanSum [tanQ(qelt(v,i), x)
+ for i in minIndex v .. maxIndex v for x in toV lk]
+ g := +/[qelt(v, i) * x for i in minIndex v .. maxIndex v for x in toU lk]
+ h:F :=
+ zero?(d := 1 + s * w) => mpiover2
+ atan((w - s) / d)
+ g := g + h
+ [eval(f, [k], [g]), [k], [g]]
+
+ gdCoef?(c, v) ==
+ for i in minIndex v .. maxIndex v repeat
+ retractIfCan(qelt(v, i) / c)@Union(Z, "failed") case "failed" =>
+ return false
+ true
+
+ goodCoef(v, l, s) ==
+ for i in minIndex v .. maxIndex v for k in l repeat
+ is?(k, s) and
+ ((r:=recip(qelt(v,i))) case Q) and
+ (retractIfCan(r::Q)@Union(Z, "failed") case Z)
+ and gdCoef?(qelt(v, i), v) => return([i, k])
+ "failed"
+
+ taneval(f, lk, k, v) ==
+ u := first argument k
+ fns := toU lk
+ c := u - +/[qelt(v, i) * x for i in minIndex v .. maxIndex v for x in fns]
+ (rec := goodCoef(v, lk, "tan"::SY)) case "failed" =>
+ tannosimp(f, lk, k, v, fns, c)
+ v0 := retract(inv qelt(v, rec.index))@Z
+ lv := [qelt(v, i) for i in minIndex v .. maxIndex v |
+ i ^= rec.index]$List(Q)
+ l := [kk for kk in lk | kk ^= rec.ker]
+ g := tanSum(-v0 * c, concat(tanNa(k::F, v0),
+ [tanNa(x, - retract(a * v0)@Z) for a in lv for x in toV l]))
+ [eval(f, [rec.ker], [g]), [rec.ker], [g]]
+
+ tannosimp(f, lk, k, v, fns, c) ==
+ every?(is?(#1, "tan"::SY), lk) =>
+ dd := (d := (cd := splitDenominator v).den)::F
+ newt := [tan(u / dd) for u in fns]$List(F)
+ newtan := [tanNa(t, d) for t in newt]$List(F)
+ h := tanSum(c, [tanNa(t, qelt(cd.num, i))
+ for i in minIndex v .. maxIndex v for t in newt])
+ lk := concat(k, lk)
+ newtan := concat(h, newtan)
+ [eval(f, lk, newtan), lk, newtan]
+ h := tanSum(c, [tanQ(qelt(v, i), x)
+ for i in minIndex v .. maxIndex v for x in toV lk])
+ [eval(f, [k], [h]), [k], [h]]
+
+ expnosimp(f, lk, k, v, fns, g) ==
+ every?(is?(#1, "exp"::SY), lk) =>
+ dd := (d := (cd := splitDenominator v).den)::F
+ newe := [exp(y / dd) for y in fns]$List(F)
+ newexp := [e ** d for e in newe]$List(F)
+ h := */[e ** qelt(cd.num, i)
+ for i in minIndex v .. maxIndex v for e in newe] * g
+ lk := concat(k, lk)
+ newexp := concat(h, newexp)
+ [eval(f, lk, newexp), lk, newexp]
+ h := */[exp(y) ** qelt(v, i)
+ for i in minIndex v .. maxIndex v for y in fns] * g
+ [eval(f, [k], [h]), [k], [h]]
+
+ logeval(f, lk, k, v) ==
+ z := first argument k
+ c := z / (*/[x**qelt(v, i)
+ for x in toZ lk for i in minIndex v .. maxIndex v])
+-- CHANGED log ktoZ x TO ktoY x SINCE WE WANT log exp f TO BE REPLACED BY f.
+ g := +/[qelt(v, i) * x
+ for i in minIndex v .. maxIndex v for x in toY lk] + log c
+ [eval(f, [k], [g]), [k], [g]]
+
+ rischNormalize(f, v) ==
+ empty?(ker := varselect(tower f, v)) => [f, empty(), empty()]
+ first(ker) ^= kernel(v)@K => error "Cannot happen"
+ ker := rest ker
+ (n := (#ker)::Z - 1) < 1 => [f, empty(), empty()]
+ for i in 1..n for kk in rest ker repeat
+ klist := first(ker, i)
+ -- NO EVALUATION ON AN EMPTY VECTOR, WILL CAUSE INFINITE LOOP
+ (c := deprel(klist, kk, v)) case vec and not empty?(c.vec) =>
+ rec := depeval(f, klist, kk, c.vec)
+ rn := rischNormalize(rec.func, v)
+ return [rn.func,
+ concat(rec.kers, rn.kers), concat(rec.vals, rn.vals)]
+ c case func =>
+ rn := rischNormalize(eval(f, [kk], [c.func]), v)
+ return [rn.func, concat(kk, rn.kers), concat(c.func, rn.vals)]
+ [f, empty(), empty()]
+
+ rootNormalize(f, k) ==
+ (u := rootKernelNormalize(f, toR(tower f, first argument k), k))
+ case "failed" => f
+ (u::REC).func
+
+ rootKernelNormalize(f, l, k) ==
+ (c := rootDep(l, k)) case vec =>
+ rooteval(f, l, k, (c.vec)(minIndex(c.vec)))
+ "failed"
+
+ localnorm f ==
+ for x in variables f repeat
+ f := rischNormalize(f, x).func
+ f
+
+ validExponential(twr, eta, x) ==
+ (c := solveLinearlyOverQ(construct([differentiate(g, x)
+ for g in (fns := toY twr)]$List(F))@Vector(F),
+ differentiate(eta, x))) case "failed" => "failed"
+ v := c::Vector(Q)
+ g := eta - +/[qelt(v, i) * yy
+ for i in minIndex v .. maxIndex v for yy in fns]
+ */[exp(yy) ** qelt(v, i)
+ for i in minIndex v .. maxIndex v for yy in fns] * exp g
+
+ rootDep(ker, k) ==
+ empty?(ker := toR(ker, first argument k)) => [true]
+ [new(1,lcm(retract(second argument k)@Z,
+ "lcm"/[retract(second argument r)@Z for r in ker])::Q)$Vector(Q)]
+
+ qdeprel(l, v) ==
+ (u := solveLinearlyOverQ(construct(l)@Vector(F), v))
+ case Vector(Q) => [u::Vector(Q)]
+ [true]
+
+ expeval(f, lk, k, v) ==
+ y := first argument k
+ fns := toY lk
+ g := y - +/[qelt(v, i) * z for i in minIndex v .. maxIndex v for z in fns]
+ (rec := goodCoef(v, lk, "exp"::SY)) case "failed" =>
+ expnosimp(f, lk, k, v, fns, exp g)
+ v0 := retract(inv qelt(v, rec.index))@Z
+ lv := [qelt(v, i) for i in minIndex v .. maxIndex v |
+ i ^= rec.index]$List(Q)
+ l := [kk for kk in lk | kk ^= rec.ker]
+ h :F := */[exp(z) ** (- retract(a * v0)@Z) for a in lv for z in toY l]
+ h := h * exp(-v0 * g) * (k::F) ** v0
+ [eval(f, [rec.ker], [h]), [rec.ker], [h]]
+
+ if F has CombinatorialOpsCategory then
+ normalize f == rtNormalize localnorm factorials realElementary f
+
+ normalize(f, x) ==
+ rtNormalize(rischNormalize(factorials(realElementary(f,x),x),x).func)
+
+ factdeprel(l, k) ==
+ ((r := retractIfCan(n := first argument k)@Union(Z, "failed"))
+ case Z) and (r::Z > 0) => [factorial(r::Z)::F]
+ for x in l repeat
+ m := first argument x
+ ((r := retractIfCan(n - m)@Union(Z, "failed")) case Z) and
+ (r::Z > 0) => return([*/[(m + i::F) for i in 1..r] * x::F])
+ [true]
+
+ else
+ normalize f == rtNormalize localnorm realElementary f
+ normalize(f, x) == rtNormalize(rischNormalize(realElementary(f,x),x).func)
+
+@
+\section{package ITRIGMNP InnerTrigonometricManipulations}
+<<package ITRIGMNP InnerTrigonometricManipulations>>=
+)abbrev package ITRIGMNP InnerTrigonometricManipulations
+++ Trigs to/from exps and logs
+++ Author: Manuel Bronstein
+++ Date Created: 4 April 1988
+++ Date Last Updated: 9 October 1993
+++ Description:
+++ This package provides transformations from trigonometric functions
+++ to exponentials and logarithms, and back.
+++ F and FG should be the same type of function space.
+++ Keywords: trigonometric, function, manipulation.
+InnerTrigonometricManipulations(R,F,FG): Exports == Implementation where
+ R : Join(IntegralDomain, OrderedSet)
+ F : Join(FunctionSpace R, RadicalCategory,
+ TranscendentalFunctionCategory)
+ FG : Join(FunctionSpace Complex R, RadicalCategory,
+ TranscendentalFunctionCategory)
+
+ Z ==> Integer
+ SY ==> Symbol
+ OP ==> BasicOperator
+ GR ==> Complex R
+ GF ==> Complex F
+ KG ==> Kernel FG
+ PG ==> SparseMultivariatePolynomial(GR, KG)
+ UP ==> SparseUnivariatePolynomial PG
+ NTHR ==> "nthRoot"::SY
+
+ Exports ==> with
+ GF2FG : GF -> FG
+ ++ GF2FG(a + i b) returns \spad{a + i b} viewed as a function with
+ ++ the \spad{i} pushed down into the coefficient domain.
+ FG2F : FG -> F
+ ++ FG2F(a + i b) returns \spad{a + sqrt(-1) b}.
+ F2FG : F -> FG
+ ++ F2FG(a + sqrt(-1) b) returns \spad{a + i b}.
+ explogs2trigs: FG -> GF
+ ++ explogs2trigs(f) rewrites all the complex logs and
+ ++ exponentials appearing in \spad{f} in terms of trigonometric
+ ++ functions.
+ trigs2explogs: (FG, List KG, List SY) -> FG
+ ++ trigs2explogs(f, [k1,...,kn], [x1,...,xm]) rewrites
+ ++ all the trigonometric functions appearing in \spad{f} and involving
+ ++ one of the \spad{xi's} in terms of complex logarithms and
+ ++ exponentials. A kernel of the form \spad{tan(u)} is expressed
+ ++ using \spad{exp(u)**2} if it is one of the \spad{ki's}, in terms of
+ ++ \spad{exp(2*u)} otherwise.
+
+ Implementation ==> add
+ ker2explogs: (KG, List KG, List SY) -> FG
+ smp2explogs: (PG, List KG, List SY) -> FG
+ supexp : (UP, GF, GF, Z) -> GF
+ GR2GF : GR -> GF
+ GR2F : GR -> F
+ KG2F : KG -> F
+ PG2F : PG -> F
+ ker2trigs : (OP, List GF) -> GF
+ smp2trigs : PG -> GF
+ sup2trigs : (UP, GF) -> GF
+
+ nth := R has RetractableTo(Integer) and F has RadicalCategory
+
+ GR2F g == real(g)::F + sqrt(-(1::F)) * imag(g)::F
+ KG2F k == map(FG2F, k)$ExpressionSpaceFunctions2(FG, F)
+ FG2F f == (PG2F numer f) / (PG2F denom f)
+ F2FG f == map(#1::GR, f)$FunctionSpaceFunctions2(R,F,GR,FG)
+ GF2FG f == (F2FG real f) + complex(0, 1)$GR ::FG * F2FG imag f
+ GR2GF gr == complex(real(gr)::F, imag(gr)::F)
+
+-- This expects the argument to have only tan and atans left.
+-- Does a half-angle correction if k is not in the initial kernel list.
+ ker2explogs(k, l, lx) ==
+ empty?([v for v in variables(kf := k::FG) |
+ member?(v, lx)]$List(SY)) => kf
+ empty?(args := [trigs2explogs(a, l, lx)
+ for a in argument k]$List(FG)) => kf
+ im := complex(0, 1)$GR :: FG
+ z := first args
+ is?(k, "tan"::Symbol) =>
+ e := (member?(k, l) => exp(im * z) ** 2; exp(2 * im * z))
+ - im * (e - 1) /$FG (e + 1)
+ is?(k, "atan"::Symbol) =>
+ im * log((1 -$FG im *$FG z)/$FG (1 +$FG im *$FG z))$FG / (2::FG)
+ (operator k) args
+
+ trigs2explogs(f, l, lx) ==
+ smp2explogs(numer f, l, lx) / smp2explogs(denom f, l, lx)
+
+ -- return op(arg) as f + %i g
+ -- op is already an operator with semantics over R, not GR
+ ker2trigs(op, arg) ==
+ "and"/[zero? imag x for x in arg] =>
+ complex(op [real x for x in arg]$List(F), 0)
+ a := first arg
+ is?(op, "exp"::Symbol) => exp a
+ is?(op, "log"::Symbol) => log a
+ is?(op, "sin"::Symbol) => sin a
+ is?(op, "cos"::Symbol) => cos a
+ is?(op, "tan"::Symbol) => tan a
+ is?(op, "cot"::Symbol) => cot a
+ is?(op, "sec"::Symbol) => sec a
+ is?(op, "csc"::Symbol) => csc a
+ is?(op, "asin"::Symbol) => asin a
+ is?(op, "acos"::Symbol) => acos a
+ is?(op, "atan"::Symbol) => atan a
+ is?(op, "acot"::Symbol) => acot a
+ is?(op, "asec"::Symbol) => asec a
+ is?(op, "acsc"::Symbol) => acsc a
+ is?(op, "sinh"::Symbol) => sinh a
+ is?(op, "cosh"::Symbol) => cosh a
+ is?(op, "tanh"::Symbol) => tanh a
+ is?(op, "coth"::Symbol) => coth a
+ is?(op, "sech"::Symbol) => sech a
+ is?(op, "csch"::Symbol) => csch a
+ is?(op, "asinh"::Symbol) => asinh a
+ is?(op, "acosh"::Symbol) => acosh a
+ is?(op, "atanh"::Symbol) => atanh a
+ is?(op, "acoth"::Symbol) => acoth a
+ is?(op, "asech"::Symbol) => asech a
+ is?(op, "acsch"::Symbol) => acsch a
+ is?(op, "abs"::Symbol) => sqrt(norm a)::GF
+ nth and is?(op, NTHR) => nthRoot(a, retract(second arg)@Z)
+ error "ker2trigs: cannot convert kernel to gaussian function"
+
+ sup2trigs(p, f) ==
+ map(smp2trigs, p)$SparseUnivariatePolynomialFunctions2(PG, GF) f
+
+ smp2trigs p ==
+ map(explogs2trigs(#1::FG),GR2GF, p)$PolynomialCategoryLifting(
+ IndexedExponents KG, KG, GR, PG, GF)
+
+ explogs2trigs f ==
+ (m := mainKernel f) case "failed" =>
+ GR2GF(retract(numer f)@GR) / GR2GF(retract(denom f)@GR)
+ op := operator(operator(k := m::KG))$F
+ arg := [explogs2trigs x for x in argument k]
+ num := univariate(numer f, k)
+ den := univariate(denom f, k)
+ is?(op, "exp"::Symbol) =>
+ e := exp real first arg
+ y := imag first arg
+ g := complex(e * cos y, e * sin y)$GF
+ gi := complex(cos(y) / e, - sin(y) / e)$GF
+ supexp(num,g,gi,b := (degree num)::Z quo 2)/supexp(den,g,gi,b)
+ sup2trigs(num, g := ker2trigs(op, arg)) / sup2trigs(den, g)
+
+ supexp(p, f1, f2, bse) ==
+ ans:GF := 0
+ while p ^= 0 repeat
+ g := explogs2trigs(leadingCoefficient(p)::FG)
+ if ((d := degree(p)::Z - bse) >= 0) then
+ ans := ans + g * f1 ** d
+ else ans := ans + g * f2 ** (-d)
+ p := reductum p
+ ans
+
+ PG2F p ==
+ map(KG2F, GR2F, p)$PolynomialCategoryLifting(IndexedExponents KG,
+ KG, GR, PG, F)
+
+ smp2explogs(p, l, lx) ==
+ map(ker2explogs(#1, l, lx), #1::FG, p)$PolynomialCategoryLifting(
+ IndexedExponents KG, KG, GR, PG, FG)
+
+@
+\section{package TRIGMNIP TrigonometricManipulations}
+<<package TRIGMNIP TrigonometricManipulations>>=
+)abbrev package TRIGMNIP TrigonometricManipulations
+++ Trigs to/from exps and logs
+++ Author: Manuel Bronstein
+++ Date Created: 4 April 1988
+++ Date Last Updated: 14 February 1994
+++ Description:
+++ \spadtype{TrigonometricManipulations} provides transformations from
+++ trigonometric functions to complex exponentials and logarithms, and back.
+++ Keywords: trigonometric, function, manipulation.
+TrigonometricManipulations(R, F): Exports == Implementation where
+ R : Join(GcdDomain, OrderedSet, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer)
+ F : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory,
+ FunctionSpace R)
+
+ Z ==> Integer
+ SY ==> Symbol
+ K ==> Kernel F
+ FG ==> Expression Complex R
+
+ Exports ==> with
+ complexNormalize: F -> F
+ ++ complexNormalize(f) rewrites \spad{f} using the least possible number
+ ++ of complex independent kernels.
+ complexNormalize: (F, SY) -> F
+ ++ complexNormalize(f, x) rewrites \spad{f} using the least possible
+ ++ number of complex independent kernels involving \spad{x}.
+ complexElementary: F -> F
+ ++ complexElementary(f) rewrites \spad{f} in terms of the 2 fundamental
+ ++ complex transcendental elementary functions: \spad{log, exp}.
+ complexElementary: (F, SY) -> F
+ ++ complexElementary(f, x) rewrites the kernels of \spad{f} involving
+ ++ \spad{x} in terms of the 2 fundamental complex
+ ++ transcendental elementary functions: \spad{log, exp}.
+ trigs : F -> F
+ ++ trigs(f) rewrites all the complex logs and exponentials
+ ++ appearing in \spad{f} in terms of trigonometric functions.
+ real : F -> F
+ ++ real(f) returns the real part of \spad{f} where \spad{f} is a complex
+ ++ function.
+ imag : F -> F
+ ++ imag(f) returns the imaginary part of \spad{f} where \spad{f}
+ ++ is a complex function.
+ real? : F -> Boolean
+ ++ real?(f) returns \spad{true} if \spad{f = real f}.
+ complexForm: F -> Complex F
+ ++ complexForm(f) returns \spad{[real f, imag f]}.
+
+ Implementation ==> add
+ import ElementaryFunctionSign(R, F)
+ import InnerTrigonometricManipulations(R,F,FG)
+ import ElementaryFunctionStructurePackage(R, F)
+ import ElementaryFunctionStructurePackage(Complex R, FG)
+
+ s1 := sqrt(-1::F)
+ ipi := pi()$F * s1
+
+ K2KG : K -> Kernel FG
+ kcomplex : K -> Union(F, "failed")
+ locexplogs : F -> FG
+ localexplogs : (F, F, List SY) -> FG
+ complexKernels: F -> Record(ker: List K, val: List F)
+
+ K2KG k == retract(tan F2FG first argument k)@Kernel(FG)
+ real? f == empty?(complexKernels(f).ker)
+ real f == real complexForm f
+ imag f == imag complexForm f
+
+-- returns [[k1,...,kn], [v1,...,vn]] such that ki should be replaced by vi
+ complexKernels f ==
+ lk:List(K) := empty()
+ lv:List(F) := empty()
+ for k in tower f repeat
+ if (u := kcomplex k) case F then
+ lk := concat(k, lk)
+ lv := concat(u::F, lv)
+ [lk, lv]
+
+-- returns f if it is certain that k is not a real kernel and k = f,
+-- "failed" otherwise
+ kcomplex k ==
+ op := operator k
+ is?(k, "nthRoot"::SY) =>
+ arg := argument k
+ even?(retract(n := second arg)@Z) and ((u := sign(first arg)) case Z)
+ and (u::Z < 0) => op(s1, n / 2::F) * op(- first arg, n)
+ "failed"
+ is?(k, "log"::SY) and ((u := sign(a := first argument k)) case Z)
+ and (u::Z < 0) => op(- a) + ipi
+ "failed"
+
+ complexForm f ==
+ empty?((l := complexKernels f).ker) => complex(f, 0)
+ explogs2trigs locexplogs eval(f, l.ker, l.val)
+
+ locexplogs f ==
+ any?(has?(#1, "rtrig"),
+ operators(g := realElementary f))$List(BasicOperator) =>
+ localexplogs(f, g, variables g)
+ F2FG g
+
+ complexNormalize(f, x) ==
+ any?(has?(operator #1, "rtrig"),
+ [k for k in tower(g := realElementary(f, x))
+ | member?(x, variables(k::F))]$List(K))$List(K) =>
+ FG2F(rischNormalize(localexplogs(f, g, [x]), x).func)
+ rischNormalize(g, x).func
+
+ complexNormalize f ==
+ l := variables(g := realElementary f)
+ any?(has?(#1, "rtrig"), operators g)$List(BasicOperator) =>
+ h := localexplogs(f, g, l)
+ for x in l repeat h := rischNormalize(h, x).func
+ FG2F h
+ for x in l repeat g := rischNormalize(g, x).func
+ g
+
+ complexElementary(f, x) ==
+ any?(has?(operator #1, "rtrig"),
+ [k for k in tower(g := realElementary(f, x))
+ | member?(x, variables(k::F))]$List(K))$List(K) =>
+ FG2F localexplogs(f, g, [x])
+ g
+
+ complexElementary f ==
+ any?(has?(#1, "rtrig"),
+ operators(g := realElementary f))$List(BasicOperator) =>
+ FG2F localexplogs(f, g, variables g)
+ g
+
+ localexplogs(f, g, lx) ==
+ trigs2explogs(F2FG g, [K2KG k for k in tower f
+ | is?(k, "tan"::SY) or is?(k, "cot"::SY)], lx)
+
+ trigs f ==
+ real? f => f
+ g := explogs2trigs F2FG f
+ real g + s1 * imag g
+
+@
+\section{package CTRIGMNP ComplexTrigonometricManipulations}
+<<package CTRIGMNP ComplexTrigonometricManipulations>>=
+)abbrev package CTRIGMNP ComplexTrigonometricManipulations
+++ Real and Imaginary parts of complex functions
+++ Author: Manuel Bronstein
+++ Date Created: 11 June 1993
+++ Date Last Updated: 14 June 1993
+++ Description:
+++ \spadtype{ComplexTrigonometricManipulations} provides function that
+++ compute the real and imaginary parts of complex functions.
+++ Keywords: complex, function, manipulation.
+ComplexTrigonometricManipulations(R, F): Exports == Implementation where
+ R : Join(IntegralDomain, OrderedSet, RetractableTo Integer)
+ F : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory,
+ FunctionSpace Complex R)
+
+
+ SY ==> Symbol
+ FR ==> Expression R
+ K ==> Kernel F
+
+
+ Exports ==> with
+ complexNormalize: F -> F
+ ++ complexNormalize(f) rewrites \spad{f} using the least possible number
+ ++ of complex independent kernels.
+ complexNormalize: (F, SY) -> F
+ ++ complexNormalize(f, x) rewrites \spad{f} using the least possible
+ ++ number of complex independent kernels involving \spad{x}.
+ complexElementary: F -> F
+ ++ complexElementary(f) rewrites \spad{f} in terms of the 2 fundamental
+ ++ complex transcendental elementary functions: \spad{log, exp}.
+ complexElementary: (F, SY) -> F
+ ++ complexElementary(f, x) rewrites the kernels of \spad{f} involving
+ ++ \spad{x} in terms of the 2 fundamental complex
+ ++ transcendental elementary functions: \spad{log, exp}.
+ real : F -> FR
+ ++ real(f) returns the real part of \spad{f} where \spad{f} is a complex
+ ++ function.
+ imag : F -> FR
+ ++ imag(f) returns the imaginary part of \spad{f} where \spad{f}
+ ++ is a complex function.
+ real? : F -> Boolean
+ ++ real?(f) returns \spad{true} if \spad{f = real f}.
+ trigs : F -> F
+ ++ trigs(f) rewrites all the complex logs and exponentials
+ ++ appearing in \spad{f} in terms of trigonometric functions.
+ complexForm: F -> Complex FR
+ ++ complexForm(f) returns \spad{[real f, imag f]}.
+
+ Implementation ==> add
+ import InnerTrigonometricManipulations(R, FR, F)
+ import ElementaryFunctionStructurePackage(Complex R, F)
+
+ rreal?: Complex R -> Boolean
+ kreal?: Kernel F -> Boolean
+ localexplogs : (F, F, List SY) -> F
+
+ real f == real complexForm f
+ imag f == imag complexForm f
+ rreal? r == zero? imag r
+ kreal? k == every?(real?, argument k)$List(F)
+ complexForm f == explogs2trigs f
+
+ trigs f ==
+ GF2FG explogs2trigs f
+
+ real? f ==
+ every?(rreal?, coefficients numer f)
+ and every?(rreal?, coefficients denom f) and every?(kreal?, kernels f)
+
+ localexplogs(f, g, lx) ==
+ trigs2explogs(g, [k for k in tower f
+ | is?(k, "tan"::SY) or is?(k, "cot"::SY)], lx)
+
+ complexElementary f ==
+ any?(has?(#1, "rtrig"),
+ operators(g := realElementary f))$List(BasicOperator) =>
+ localexplogs(f, g, variables g)
+ g
+
+ complexElementary(f, x) ==
+ any?(has?(operator #1, "rtrig"),
+ [k for k in tower(g := realElementary(f, x))
+ | member?(x, variables(k::F))]$List(K))$List(K) =>
+ localexplogs(f, g, [x])
+ g
+
+ complexNormalize(f, x) ==
+ any?(has?(operator #1, "rtrig"),
+ [k for k in tower(g := realElementary(f, x))
+ | member?(x, variables(k::F))]$List(K))$List(K) =>
+ (rischNormalize(localexplogs(f, g, [x]), x).func)
+ rischNormalize(g, x).func
+
+ complexNormalize f ==
+ l := variables(g := realElementary f)
+ any?(has?(#1, "rtrig"), operators g)$List(BasicOperator) =>
+ h := localexplogs(f, g, l)
+ for x in l repeat h := rischNormalize(h, x).func
+ h
+ for x in l repeat g := rischNormalize(g, x).func
+ g
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg intaf EFSTRUC rdeef intef irexpand integrat
+
+<<package SYMFUNC SymmetricFunctions>>
+<<package TANEXP TangentExpansions>>
+<<package EFSTRUC ElementaryFunctionStructurePackage>>
+<<package ITRIGMNP InnerTrigonometricManipulations>>
+<<package TRIGMNIP TrigonometricManipulations>>
+<<package CTRIGMNP ComplexTrigonometricManipulations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/efuls.spad.pamphlet b/src/algebra/efuls.spad.pamphlet
new file mode 100644
index 00000000..6f62a3f1
--- /dev/null
+++ b/src/algebra/efuls.spad.pamphlet
@@ -0,0 +1,400 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra efuls.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package EFULS ElementaryFunctionsUnivariateLaurentSeries}
+<<package EFULS ElementaryFunctionsUnivariateLaurentSeries>>=
+)abbrev package EFULS ElementaryFunctionsUnivariateLaurentSeries
+++ This package provides elementary functions on Laurent series.
+++ Author: Clifton J. Williamson
+++ Date Created: 6 February 1990
+++ Date Last Updated: 25 February 1990
+++ Keywords: elementary function, Laurent series
+++ Examples:
+++ References:
+ElementaryFunctionsUnivariateLaurentSeries(Coef,UTS,ULS):_
+ Exports == Implementation where
+ ++ This package provides elementary functions on any Laurent series
+ ++ domain over a field which was constructed from a Taylor series
+ ++ domain. These functions are implemented by calling the
+ ++ corresponding functions on the Taylor series domain. We also
+ ++ provide 'partial functions' which compute transcendental
+ ++ functions of Laurent series when possible and return "failed"
+ ++ when this is not possible.
+ Coef : Algebra Fraction Integer
+ UTS : UnivariateTaylorSeriesCategory Coef
+ ULS : UnivariateLaurentSeriesConstructorCategory(Coef,UTS)
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+ S ==> String
+ STTF ==> StreamTranscendentalFunctions(Coef)
+
+ Exports ==> PartialTranscendentalFunctions(ULS) with
+
+ if Coef has Field then
+ "**": (ULS,RN) -> ULS
+ ++ s ** r raises a Laurent series s to a rational power r
+
+--% Exponentials and Logarithms
+
+ exp: ULS -> ULS
+ ++ exp(z) returns the exponential of Laurent series z.
+ log: ULS -> ULS
+ ++ log(z) returns the logarithm of Laurent series z.
+
+--% TrigonometricFunctionCategory
+
+ sin: ULS -> ULS
+ ++ sin(z) returns the sine of Laurent series z.
+ cos: ULS -> ULS
+ ++ cos(z) returns the cosine of Laurent series z.
+ tan: ULS -> ULS
+ ++ tan(z) returns the tangent of Laurent series z.
+ cot: ULS -> ULS
+ ++ cot(z) returns the cotangent of Laurent series z.
+ sec: ULS -> ULS
+ ++ sec(z) returns the secant of Laurent series z.
+ csc: ULS -> ULS
+ ++ csc(z) returns the cosecant of Laurent series z.
+
+--% ArcTrigonometricFunctionCategory
+
+ asin: ULS -> ULS
+ ++ asin(z) returns the arc-sine of Laurent series z.
+ acos: ULS -> ULS
+ ++ acos(z) returns the arc-cosine of Laurent series z.
+ atan: ULS -> ULS
+ ++ atan(z) returns the arc-tangent of Laurent series z.
+ acot: ULS -> ULS
+ ++ acot(z) returns the arc-cotangent of Laurent series z.
+ asec: ULS -> ULS
+ ++ asec(z) returns the arc-secant of Laurent series z.
+ acsc: ULS -> ULS
+ ++ acsc(z) returns the arc-cosecant of Laurent series z.
+
+--% HyperbolicFunctionCategory
+
+ sinh: ULS -> ULS
+ ++ sinh(z) returns the hyperbolic sine of Laurent series z.
+ cosh: ULS -> ULS
+ ++ cosh(z) returns the hyperbolic cosine of Laurent series z.
+ tanh: ULS -> ULS
+ ++ tanh(z) returns the hyperbolic tangent of Laurent series z.
+ coth: ULS -> ULS
+ ++ coth(z) returns the hyperbolic cotangent of Laurent series z.
+ sech: ULS -> ULS
+ ++ sech(z) returns the hyperbolic secant of Laurent series z.
+ csch: ULS -> ULS
+ ++ csch(z) returns the hyperbolic cosecant of Laurent series z.
+
+--% ArcHyperbolicFunctionCategory
+
+ asinh: ULS -> ULS
+ ++ asinh(z) returns the inverse hyperbolic sine of Laurent series z.
+ acosh: ULS -> ULS
+ ++ acosh(z) returns the inverse hyperbolic cosine of Laurent series z.
+ atanh: ULS -> ULS
+ ++ atanh(z) returns the inverse hyperbolic tangent of Laurent series z.
+ acoth: ULS -> ULS
+ ++ acoth(z) returns the inverse hyperbolic cotangent of Laurent series z.
+ asech: ULS -> ULS
+ ++ asech(z) returns the inverse hyperbolic secant of Laurent series z.
+ acsch: ULS -> ULS
+ ++ acsch(z) returns the inverse hyperbolic cosecant of Laurent series z.
+
+ Implementation ==> add
+
+--% roots
+
+ RATPOWERS : Boolean := Coef has "**":(Coef,RN) -> Coef
+ TRANSFCN : Boolean := Coef has TranscendentalFunctionCategory
+ RATS : Boolean := Coef has retractIfCan: Coef -> Union(RN,"failed")
+
+ nthRootUTS:(UTS,I) -> Union(UTS,"failed")
+ nthRootUTS(uts,n) ==
+ -- assumed: n > 1, uts has non-zero constant term
+-- one? coefficient(uts,0) => uts ** inv(n::RN)
+ coefficient(uts,0) = 1 => uts ** inv(n::RN)
+ RATPOWERS => uts ** inv(n::RN)
+ "failed"
+
+ nthRootIfCan(uls,nn) ==
+ (n := nn :: I) < 1 => error "nthRootIfCan: n must be positive"
+ n = 1 => uls
+ deg := degree uls
+ if zero? (coef := coefficient(uls,deg)) then
+ uls := removeZeroes(1000,uls); deg := degree uls
+ zero? (coef := coefficient(uls,deg)) =>
+ error "root of series with many leading zero coefficients"
+ (k := deg exquo n) case "failed" => "failed"
+ uts := taylor(uls * monomial(1,-deg))
+ (root := nthRootUTS(uts,n)) case "failed" => "failed"
+ monomial(1,k :: I) * (root :: UTS :: ULS)
+
+ if Coef has Field then
+ (uls:ULS) ** (r:RN) ==
+ num := numer r; den := denom r
+-- one? den => uls ** num
+ den = 1 => uls ** num
+ deg := degree uls
+ if zero? (coef := coefficient(uls,deg)) then
+ uls := removeZeroes(1000,uls); deg := degree uls
+ zero? (coef := coefficient(uls,deg)) =>
+ error "power of series with many leading zero coefficients"
+ (k := deg exquo den) case "failed" =>
+ error "**: rational power does not exist"
+ uts := taylor(uls * monomial(1,-deg)) ** r
+ monomial(1,(k :: I) * num) * (uts :: ULS)
+
+--% transcendental functions
+
+ applyIfCan: (UTS -> UTS,ULS) -> Union(ULS,"failed")
+ applyIfCan(fcn,uls) ==
+ uts := taylorIfCan uls
+ uts case "failed" => "failed"
+ fcn(uts :: UTS) :: ULS
+
+ expIfCan uls == applyIfCan(exp,uls)
+ sinIfCan uls == applyIfCan(sin,uls)
+ cosIfCan uls == applyIfCan(cos,uls)
+ asinIfCan uls == applyIfCan(asin,uls)
+ acosIfCan uls == applyIfCan(acos,uls)
+ asecIfCan uls == applyIfCan(asec,uls)
+ acscIfCan uls == applyIfCan(acsc,uls)
+ sinhIfCan uls == applyIfCan(sinh,uls)
+ coshIfCan uls == applyIfCan(cosh,uls)
+ asinhIfCan uls == applyIfCan(asinh,uls)
+ acoshIfCan uls == applyIfCan(acosh,uls)
+ atanhIfCan uls == applyIfCan(atanh,uls)
+ acothIfCan uls == applyIfCan(acoth,uls)
+ asechIfCan uls == applyIfCan(asech,uls)
+ acschIfCan uls == applyIfCan(acsch,uls)
+
+ logIfCan uls ==
+ uts := taylorIfCan uls
+ uts case "failed" => "failed"
+ zero? coefficient(ts := uts :: UTS,0) => "failed"
+ log(ts) :: ULS
+
+ tanIfCan uls ==
+ -- don't call 'tan' on a UTS (tan(uls) may have a singularity)
+ uts := taylorIfCan uls
+ uts case "failed" => "failed"
+ sc := sincos(coefficients(uts :: UTS))$STTF
+ (cosInv := recip(series(sc.cos) :: ULS)) case "failed" => "failed"
+ (series(sc.sin) :: ULS) * (cosInv :: ULS)
+
+ cotIfCan uls ==
+ -- don't call 'cot' on a UTS (cot(uls) may have a singularity)
+ uts := taylorIfCan uls
+ uts case "failed" => "failed"
+ sc := sincos(coefficients(uts :: UTS))$STTF
+ (sinInv := recip(series(sc.sin) :: ULS)) case "failed" => "failed"
+ (series(sc.cos) :: ULS) * (sinInv :: ULS)
+
+ secIfCan uls ==
+ cos := cosIfCan uls
+ cos case "failed" => "failed"
+ (cosInv := recip(cos :: ULS)) case "failed" => "failed"
+ cosInv :: ULS
+
+ cscIfCan uls ==
+ sin := sinIfCan uls
+ sin case "failed" => "failed"
+ (sinInv := recip(sin :: ULS)) case "failed" => "failed"
+ sinInv :: ULS
+
+ atanIfCan uls ==
+ coef := coefficient(uls,0)
+ (ord := order(uls,0)) = 0 and coef * coef = -1 => "failed"
+ cc : Coef :=
+ ord < 0 =>
+ TRANSFCN =>
+ RATS =>
+ lc := coefficient(uls,ord)
+ (rat := retractIfCan(lc)@Union(RN,"failed")) case "failed" =>
+ (1/2) * pi()
+ (rat :: RN) > 0 => (1/2) * pi()
+ (-1/2) * pi()
+ (1/2) * pi()
+ return "failed"
+ coef = 0 => 0
+ TRANSFCN => atan coef
+ return "failed"
+ (z := recip(1 + uls*uls)) case "failed" => "failed"
+ (cc :: ULS) + integrate(differentiate(uls) * (z :: ULS))
+
+ acotIfCan uls ==
+ coef := coefficient(uls,0)
+ (ord := order(uls,0)) = 0 and coef * coef = -1 => "failed"
+ cc : Coef :=
+ ord < 0 =>
+ RATS =>
+ lc := coefficient(uls,ord)
+ (rat := retractIfCan(lc)@Union(RN,"failed")) case "failed" => 0
+ (rat :: RN) > 0 => 0
+ TRANSFCN => pi()
+ return "failed"
+ 0
+ TRANSFCN => acot coef
+ return "failed"
+ (z := recip(1 + uls*uls)) case "failed" => "failed"
+ (cc :: ULS) - integrate(differentiate(uls) * (z :: ULS))
+
+ tanhIfCan uls ==
+ -- don't call 'tanh' on a UTS (tanh(uls) may have a singularity)
+ uts := taylorIfCan uls
+ uts case "failed" => "failed"
+ sc := sinhcosh(coefficients(uts :: UTS))$STTF
+ (coshInv := recip(series(sc.cosh) :: ULS)) case "failed" =>
+ "failed"
+ (series(sc.sinh) :: ULS) * (coshInv :: ULS)
+
+ cothIfCan uls ==
+ -- don't call 'coth' on a UTS (coth(uls) may have a singularity)
+ uts := taylorIfCan uls
+ uts case "failed" => "failed"
+ sc := sinhcosh(coefficients(uts :: UTS))$STTF
+ (sinhInv := recip(series(sc.sinh) :: ULS)) case "failed" =>
+ "failed"
+ (series(sc.cosh) :: ULS) * (sinhInv :: ULS)
+
+ sechIfCan uls ==
+ cosh := coshIfCan uls
+ cosh case "failed" => "failed"
+ (coshInv := recip(cosh :: ULS)) case "failed" => "failed"
+ coshInv :: ULS
+
+ cschIfCan uls ==
+ sinh := sinhIfCan uls
+ sinh case "failed" => "failed"
+ (sinhInv := recip(sinh :: ULS)) case "failed" => "failed"
+ sinhInv :: ULS
+
+ applyOrError:(ULS -> Union(ULS,"failed"),S,ULS) -> ULS
+ applyOrError(fcn,name,uls) ==
+ ans := fcn uls
+ ans case "failed" =>
+ error concat(name," of function with singularity")
+ ans :: ULS
+
+ exp uls == applyOrError(expIfCan,"exp",uls)
+ log uls == applyOrError(logIfCan,"log",uls)
+ sin uls == applyOrError(sinIfCan,"sin",uls)
+ cos uls == applyOrError(cosIfCan,"cos",uls)
+ tan uls == applyOrError(tanIfCan,"tan",uls)
+ cot uls == applyOrError(cotIfCan,"cot",uls)
+ sec uls == applyOrError(secIfCan,"sec",uls)
+ csc uls == applyOrError(cscIfCan,"csc",uls)
+ asin uls == applyOrError(asinIfCan,"asin",uls)
+ acos uls == applyOrError(acosIfCan,"acos",uls)
+ asec uls == applyOrError(asecIfCan,"asec",uls)
+ acsc uls == applyOrError(acscIfCan,"acsc",uls)
+ sinh uls == applyOrError(sinhIfCan,"sinh",uls)
+ cosh uls == applyOrError(coshIfCan,"cosh",uls)
+ tanh uls == applyOrError(tanhIfCan,"tanh",uls)
+ coth uls == applyOrError(cothIfCan,"coth",uls)
+ sech uls == applyOrError(sechIfCan,"sech",uls)
+ csch uls == applyOrError(cschIfCan,"csch",uls)
+ asinh uls == applyOrError(asinhIfCan,"asinh",uls)
+ acosh uls == applyOrError(acoshIfCan,"acosh",uls)
+ atanh uls == applyOrError(atanhIfCan,"atanh",uls)
+ acoth uls == applyOrError(acothIfCan,"acoth",uls)
+ asech uls == applyOrError(asechIfCan,"asech",uls)
+ acsch uls == applyOrError(acschIfCan,"acsch",uls)
+
+ atan uls ==
+ -- code is duplicated so that correct error messages will be returned
+ coef := coefficient(uls,0)
+ (ord := order(uls,0)) = 0 and coef * coef = -1 =>
+ error "atan: series expansion has logarithmic term"
+ cc : Coef :=
+ ord < 0 =>
+ TRANSFCN =>
+ RATS =>
+ lc := coefficient(uls,ord)
+ (rat := retractIfCan(lc)@Union(RN,"failed")) case "failed" =>
+ (1/2) * pi()
+ (rat :: RN) > 0 => (1/2) * pi()
+ (-1/2) * pi()
+ (1/2) * pi()
+ error "atan: series expansion involves transcendental constants"
+ coef = 0 => 0
+ TRANSFCN => atan coef
+ error "atan: series expansion involves transcendental constants"
+ (z := recip(1 + uls*uls)) case "failed" =>
+ error "atan: leading coefficient not invertible"
+ (cc :: ULS) + integrate(differentiate(uls) * (z :: ULS))
+
+ acot uls ==
+ -- code is duplicated so that correct error messages will be returned
+ coef := coefficient(uls,0)
+ (ord := order(uls,0)) = 0 and coef * coef = -1 =>
+ error "acot: series expansion has logarithmic term"
+ cc : Coef :=
+ ord < 0 =>
+ RATS =>
+ lc := coefficient(uls,ord)
+ (rat := retractIfCan(lc)@Union(RN,"failed")) case "failed" => 0
+ (rat :: RN) > 0 => 0
+ TRANSFCN => pi()
+ error "acot: series expansion involves transcendental constants"
+ 0
+ TRANSFCN => acot coef
+ error "acot: series expansion involves transcendental constants"
+ (z := recip(1 + uls*uls)) case "failed" =>
+ error "acot: leading coefficient not invertible"
+ (cc :: ULS) - integrate(differentiate(uls) * (z :: ULS))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package EFULS ElementaryFunctionsUnivariateLaurentSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/efupxs.spad.pamphlet b/src/algebra/efupxs.spad.pamphlet
new file mode 100644
index 00000000..277b0a85
--- /dev/null
+++ b/src/algebra/efupxs.spad.pamphlet
@@ -0,0 +1,313 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra efupxs.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries}
+<<package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries>>=
+)abbrev package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries
+++ This package provides elementary functions on Puiseux series.
+++ Author: Clifton J. Williamson
+++ Date Created: 20 February 1990
+++ Date Last Updated: 20 February 1990
+++ Keywords: elementary function, Laurent series
+++ Examples:
+++ References:
+ElementaryFunctionsUnivariatePuiseuxSeries(Coef,ULS,UPXS,EFULS):_
+ Exports == Implementation where
+ ++ This package provides elementary functions on any Laurent series
+ ++ domain over a field which was constructed from a Taylor series
+ ++ domain. These functions are implemented by calling the
+ ++ corresponding functions on the Taylor series domain. We also
+ ++ provide 'partial functions' which compute transcendental
+ ++ functions of Laurent series when possible and return "failed"
+ ++ when this is not possible.
+ Coef : Algebra Fraction Integer
+ ULS : UnivariateLaurentSeriesCategory Coef
+ UPXS : UnivariatePuiseuxSeriesConstructorCategory(Coef,ULS)
+ EFULS : PartialTranscendentalFunctions(ULS)
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+
+ Exports ==> PartialTranscendentalFunctions(UPXS) with
+
+ if Coef has Field then
+ "**": (UPXS,RN) -> UPXS
+ ++ z ** r raises a Puiseaux series z to a rational power r
+
+--% Exponentials and Logarithms
+
+ exp: UPXS -> UPXS
+ ++ exp(z) returns the exponential of a Puiseux series z.
+ log: UPXS -> UPXS
+ ++ log(z) returns the logarithm of a Puiseux series z.
+
+--% TrigonometricFunctionCategory
+
+ sin: UPXS -> UPXS
+ ++ sin(z) returns the sine of a Puiseux series z.
+ cos: UPXS -> UPXS
+ ++ cos(z) returns the cosine of a Puiseux series z.
+ tan: UPXS -> UPXS
+ ++ tan(z) returns the tangent of a Puiseux series z.
+ cot: UPXS -> UPXS
+ ++ cot(z) returns the cotangent of a Puiseux series z.
+ sec: UPXS -> UPXS
+ ++ sec(z) returns the secant of a Puiseux series z.
+ csc: UPXS -> UPXS
+ ++ csc(z) returns the cosecant of a Puiseux series z.
+
+--% ArcTrigonometricFunctionCategory
+
+ asin: UPXS -> UPXS
+ ++ asin(z) returns the arc-sine of a Puiseux series z.
+ acos: UPXS -> UPXS
+ ++ acos(z) returns the arc-cosine of a Puiseux series z.
+ atan: UPXS -> UPXS
+ ++ atan(z) returns the arc-tangent of a Puiseux series z.
+ acot: UPXS -> UPXS
+ ++ acot(z) returns the arc-cotangent of a Puiseux series z.
+ asec: UPXS -> UPXS
+ ++ asec(z) returns the arc-secant of a Puiseux series z.
+ acsc: UPXS -> UPXS
+ ++ acsc(z) returns the arc-cosecant of a Puiseux series z.
+
+--% HyperbolicFunctionCategory
+
+ sinh: UPXS -> UPXS
+ ++ sinh(z) returns the hyperbolic sine of a Puiseux series z.
+ cosh: UPXS -> UPXS
+ ++ cosh(z) returns the hyperbolic cosine of a Puiseux series z.
+ tanh: UPXS -> UPXS
+ ++ tanh(z) returns the hyperbolic tangent of a Puiseux series z.
+ coth: UPXS -> UPXS
+ ++ coth(z) returns the hyperbolic cotangent of a Puiseux series z.
+ sech: UPXS -> UPXS
+ ++ sech(z) returns the hyperbolic secant of a Puiseux series z.
+ csch: UPXS -> UPXS
+ ++ csch(z) returns the hyperbolic cosecant of a Puiseux series z.
+
+--% ArcHyperbolicFunctionCategory
+
+ asinh: UPXS -> UPXS
+ ++ asinh(z) returns the inverse hyperbolic sine of a Puiseux series z.
+ acosh: UPXS -> UPXS
+ ++ acosh(z) returns the inverse hyperbolic cosine of a Puiseux series z.
+ atanh: UPXS -> UPXS
+ ++ atanh(z) returns the inverse hyperbolic tangent of a Puiseux series z.
+ acoth: UPXS -> UPXS
+ ++ acoth(z) returns the inverse hyperbolic cotangent of a Puiseux series z.
+ asech: UPXS -> UPXS
+ ++ asech(z) returns the inverse hyperbolic secant of a Puiseux series z.
+ acsch: UPXS -> UPXS
+ ++ acsch(z) returns the inverse hyperbolic cosecant of a Puiseux series z.
+
+ Implementation ==> add
+
+ TRANSFCN : Boolean := Coef has TranscendentalFunctionCategory
+
+--% roots
+
+ nthRootIfCan(upxs,n) ==
+-- one? n => upxs
+ n = 1 => upxs
+ r := rationalPower upxs; uls := laurentRep upxs
+ deg := degree uls
+ if zero?(coef := coefficient(uls,deg)) then
+ deg := order(uls,deg + 1000)
+ zero?(coef := coefficient(uls,deg)) =>
+ error "root of series with many leading zero coefficients"
+ uls := uls * monomial(1,-deg)$ULS
+ (ulsRoot := nthRootIfCan(uls,n)) case "failed" => "failed"
+ puiseux(r,ulsRoot :: ULS) * monomial(1,deg * r * inv(n :: RN))
+
+ if Coef has Field then
+ (upxs:UPXS) ** (q:RN) ==
+ num := numer q; den := denom q
+-- one? den => upxs ** num
+ den = 1 => upxs ** num
+ r := rationalPower upxs; uls := laurentRep upxs
+ deg := degree uls
+ if zero?(coef := coefficient(uls,deg)) then
+ deg := order(uls,deg + 1000)
+ zero?(coef := coefficient(uls,deg)) =>
+ error "power of series with many leading zero coefficients"
+ ulsPow := (uls * monomial(1,-deg)$ULS) ** q
+ puiseux(r,ulsPow) * monomial(1,deg*q*r)
+
+--% transcendental functions
+
+ applyIfCan: (ULS -> Union(ULS,"failed"),UPXS) -> Union(UPXS,"failed")
+ applyIfCan(fcn,upxs) ==
+ uls := fcn laurentRep upxs
+ uls case "failed" => "failed"
+ puiseux(rationalPower upxs,uls :: ULS)
+
+ expIfCan upxs == applyIfCan(expIfCan,upxs)
+ logIfCan upxs == applyIfCan(logIfCan,upxs)
+ sinIfCan upxs == applyIfCan(sinIfCan,upxs)
+ cosIfCan upxs == applyIfCan(cosIfCan,upxs)
+ tanIfCan upxs == applyIfCan(tanIfCan,upxs)
+ cotIfCan upxs == applyIfCan(cotIfCan,upxs)
+ secIfCan upxs == applyIfCan(secIfCan,upxs)
+ cscIfCan upxs == applyIfCan(cscIfCan,upxs)
+ atanIfCan upxs == applyIfCan(atanIfCan,upxs)
+ acotIfCan upxs == applyIfCan(acotIfCan,upxs)
+ sinhIfCan upxs == applyIfCan(sinhIfCan,upxs)
+ coshIfCan upxs == applyIfCan(coshIfCan,upxs)
+ tanhIfCan upxs == applyIfCan(tanhIfCan,upxs)
+ cothIfCan upxs == applyIfCan(cothIfCan,upxs)
+ sechIfCan upxs == applyIfCan(sechIfCan,upxs)
+ cschIfCan upxs == applyIfCan(cschIfCan,upxs)
+ asinhIfCan upxs == applyIfCan(asinhIfCan,upxs)
+ acoshIfCan upxs == applyIfCan(acoshIfCan,upxs)
+ atanhIfCan upxs == applyIfCan(atanhIfCan,upxs)
+ acothIfCan upxs == applyIfCan(acothIfCan,upxs)
+ asechIfCan upxs == applyIfCan(asechIfCan,upxs)
+ acschIfCan upxs == applyIfCan(acschIfCan,upxs)
+
+ asinIfCan upxs ==
+ order(upxs,0) < 0 => "failed"
+ (coef := coefficient(upxs,0)) = 0 =>
+ integrate((1 - upxs*upxs)**(-1/2) * (differentiate upxs))
+ TRANSFCN =>
+ cc := asin(coef) :: UPXS
+ cc + integrate((1 - upxs*upxs)**(-1/2) * (differentiate upxs))
+ "failed"
+
+ acosIfCan upxs ==
+ order(upxs,0) < 0 => "failed"
+ TRANSFCN =>
+ cc := acos(coefficient(upxs,0)) :: UPXS
+ cc + integrate(-(1 - upxs*upxs)**(-1/2) * (differentiate upxs))
+ "failed"
+
+ asecIfCan upxs ==
+ order(upxs,0) < 0 => "failed"
+ TRANSFCN =>
+ cc := asec(coefficient(upxs,0)) :: UPXS
+ f := (upxs*upxs - 1)**(-1/2) * (differentiate upxs)
+ (rec := recip upxs) case "failed" => "failed"
+ cc + integrate(f * (rec :: UPXS))
+ "failed"
+
+ acscIfCan upxs ==
+ order(upxs,0) < 0 => "failed"
+ TRANSFCN =>
+ cc := acsc(coefficient(upxs,0)) :: UPXS
+ f := -(upxs*upxs - 1)**(-1/2) * (differentiate upxs)
+ (rec := recip upxs) case "failed" => "failed"
+ cc + integrate(f * (rec :: UPXS))
+ "failed"
+
+ asinhIfCan upxs ==
+ order(upxs,0) < 0 => "failed"
+ TRANSFCN or (coefficient(upxs,0) = 0) =>
+ log(upxs + (1 + upxs*upxs)**(1/2))
+ "failed"
+
+ acoshIfCan upxs ==
+ TRANSFCN =>
+ order(upxs,0) < 0 => "failed"
+ log(upxs + (upxs*upxs - 1)**(1/2))
+ "failed"
+
+ asechIfCan upxs ==
+ TRANSFCN =>
+ order(upxs,0) < 0 => "failed"
+ (rec := recip upxs) case "failed" => "failed"
+ log((1 + (1 - upxs*upxs)*(1/2)) * (rec :: UPXS))
+ "failed"
+
+ acschIfCan upxs ==
+ TRANSFCN =>
+ order(upxs,0) < 0 => "failed"
+ (rec := recip upxs) case "failed" => "failed"
+ log((1 + (1 + upxs*upxs)*(1/2)) * (rec :: UPXS))
+ "failed"
+
+ applyOrError:(UPXS -> Union(UPXS,"failed"),String,UPXS) -> UPXS
+ applyOrError(fcn,name,upxs) ==
+ ans := fcn upxs
+ ans case "failed" =>
+ error concat(name," of function with singularity")
+ ans :: UPXS
+
+ exp upxs == applyOrError(expIfCan,"exp",upxs)
+ log upxs == applyOrError(logIfCan,"log",upxs)
+ sin upxs == applyOrError(sinIfCan,"sin",upxs)
+ cos upxs == applyOrError(cosIfCan,"cos",upxs)
+ tan upxs == applyOrError(tanIfCan,"tan",upxs)
+ cot upxs == applyOrError(cotIfCan,"cot",upxs)
+ sec upxs == applyOrError(secIfCan,"sec",upxs)
+ csc upxs == applyOrError(cscIfCan,"csc",upxs)
+ asin upxs == applyOrError(asinIfCan,"asin",upxs)
+ acos upxs == applyOrError(acosIfCan,"acos",upxs)
+ atan upxs == applyOrError(atanIfCan,"atan",upxs)
+ acot upxs == applyOrError(acotIfCan,"acot",upxs)
+ asec upxs == applyOrError(asecIfCan,"asec",upxs)
+ acsc upxs == applyOrError(acscIfCan,"acsc",upxs)
+ sinh upxs == applyOrError(sinhIfCan,"sinh",upxs)
+ cosh upxs == applyOrError(coshIfCan,"cosh",upxs)
+ tanh upxs == applyOrError(tanhIfCan,"tanh",upxs)
+ coth upxs == applyOrError(cothIfCan,"coth",upxs)
+ sech upxs == applyOrError(sechIfCan,"sech",upxs)
+ csch upxs == applyOrError(cschIfCan,"csch",upxs)
+ asinh upxs == applyOrError(asinhIfCan,"asinh",upxs)
+ acosh upxs == applyOrError(acoshIfCan,"acosh",upxs)
+ atanh upxs == applyOrError(atanhIfCan,"atanh",upxs)
+ acoth upxs == applyOrError(acothIfCan,"acoth",upxs)
+ asech upxs == applyOrError(asechIfCan,"asech",upxs)
+ acsch upxs == applyOrError(acschIfCan,"acsch",upxs)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package EFUPXS ElementaryFunctionsUnivariatePuiseuxSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/eigen.spad.pamphlet b/src/algebra/eigen.spad.pamphlet
new file mode 100644
index 00000000..193b58f9
--- /dev/null
+++ b/src/algebra/eigen.spad.pamphlet
@@ -0,0 +1,340 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra eigen.spad}
+\author{Patrizia Gianni, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package EP EigenPackage}
+<<package EP EigenPackage>>=
+)abbrev package EP EigenPackage
+++ Author: P. Gianni
+++ Date Created: summer 1986
+++ Date Last Updated: October 1992
+++ Basic Functions:
+++ Related Constructors: NumericRealEigenPackage, NumericComplexEigenPackage,
+++ RadicalEigenPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is a package for the exact computation of eigenvalues and eigenvectors.
+++ This package can be made to work for matrices with coefficients which are
+++ rational functions over a ring where we can factor polynomials.
+++ Rational eigenvalues are always explicitly computed while the
+++ non-rational ones are expressed in terms of their minimal
+++ polynomial.
+-- Functions for the numeric computation of eigenvalues and eigenvectors
+-- are in numeigen spad.
+EigenPackage(R) : C == T
+ where
+ R : GcdDomain
+ P ==> Polynomial R
+ F ==> Fraction P
+ SE ==> Symbol()
+ SUP ==> SparseUnivariatePolynomial(P)
+ SUF ==> SparseUnivariatePolynomial(F)
+ M ==> Matrix(F)
+ NNI ==> NonNegativeInteger
+ ST ==> SuchThat(SE,P)
+
+ Eigenvalue ==> Union(F,ST)
+ EigenForm ==> Record(eigval:Eigenvalue,eigmult:NNI,eigvec : List M)
+ GenEigen ==> Record(eigval:Eigenvalue,geneigvec:List M)
+
+ C == with
+ characteristicPolynomial : (M,Symbol) -> P
+ ++ characteristicPolynomial(m,var) returns the
+ ++ characteristicPolynomial of the matrix m using
+ ++ the symbol var as the main variable.
+
+ characteristicPolynomial : M -> P
+ ++ characteristicPolynomial(m) returns the
+ ++ characteristicPolynomial of the matrix m using
+ ++ a new generated symbol symbol as the main variable.
+
+ eigenvalues : M -> List Eigenvalue
+ ++ eigenvalues(m) returns the
+ ++ eigenvalues of the matrix m which are expressible
+ ++ as rational functions over the rational numbers.
+
+ eigenvector : (Eigenvalue,M) -> List M
+ ++ eigenvector(eigval,m) returns the
+ ++ eigenvectors belonging to the eigenvalue eigval
+ ++ for the matrix m.
+
+ generalizedEigenvector : (Eigenvalue,M,NNI,NNI) -> List M
+ ++ generalizedEigenvector(alpha,m,k,g)
+ ++ returns the generalized eigenvectors
+ ++ of the matrix relative to the eigenvalue alpha.
+ ++ The integers k and g are respectively the algebraic and the
+ ++ geometric multiplicity of tye eigenvalue alpha.
+ ++ alpha can be either rational or not.
+ ++ In the seconda case apha is the minimal polynomial of the
+ ++ eigenvalue.
+
+ generalizedEigenvector : (EigenForm,M) -> List M
+ ++ generalizedEigenvector(eigen,m)
+ ++ returns the generalized eigenvectors
+ ++ of the matrix relative to the eigenvalue eigen, as
+ ++ returned by the function eigenvectors.
+
+ generalizedEigenvectors : M -> List GenEigen
+ ++ generalizedEigenvectors(m)
+ ++ returns the generalized eigenvectors
+ ++ of the matrix m.
+
+ eigenvectors : M -> List(EigenForm)
+ ++ eigenvectors(m) returns the eigenvalues and eigenvectors
+ ++ for the matrix m.
+ ++ The rational eigenvalues and the correspondent eigenvectors
+ ++ are explicitely computed, while the non rational ones
+ ++ are given via their minimal polynomial and the corresponding
+ ++ eigenvectors are expressed in terms of a "generic" root of
+ ++ such a polynomial.
+
+ T == add
+ PI ==> PositiveInteger
+
+
+ MF := GeneralizedMultivariateFactorize(SE,IndexedExponents SE,R,R,P)
+ UPCF2:= UnivariatePolynomialCategoryFunctions2(P,SUP,F,SUF)
+
+
+ ---- Local Functions ----
+ tff : (SUF,SE) -> F
+ fft : (SUF,SE) -> F
+ charpol : (M,SE) -> F
+ intRatEig : (F,M,NNI) -> List M
+ intAlgEig : (ST,M,NNI) -> List M
+ genEigForm : (EigenForm,M) -> GenEigen
+
+ ---- next functions needed for defining ModularField ----
+ reduction(u:SUF,p:SUF):SUF == u rem p
+
+ merge(p:SUF,q:SUF):Union(SUF,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ exactquo(u:SUF,v:SUF,p:SUF):Union(SUF,"failed") ==
+ val:=extendedEuclidean(v,p,u)
+ val case "failed" => "failed"
+ val.coef1
+
+ ---- functions for conversions ----
+ fft(t:SUF,x:SE):F ==
+ n:=degree(t)
+ cf:=monomial(1,x,n)$P :: F
+ cf * leadingCoefficient t
+
+ tff(p:SUF,x:SE) : F ==
+ degree p=0 => leadingCoefficient p
+ r:F:=0$F
+ while p^=0 repeat
+ r:=r+fft(p,x)
+ p := reductum p
+ r
+
+ ---- generalized eigenvectors associated to a given eigenvalue ---
+ genEigForm(eigen : EigenForm,A:M) : GenEigen ==
+ alpha:=eigen.eigval
+ k:=eigen.eigmult
+ g:=#(eigen.eigvec)
+ k = g => [alpha,eigen.eigvec]
+ [alpha,generalizedEigenvector(alpha,A,k,g)]
+
+ ---- characteristic polynomial ----
+ charpol(A:M,x:SE) : F ==
+ dimA :PI := (nrows A):PI
+ dimA ^= ncols A => error " The matrix is not square"
+ B:M:=zero(dimA,dimA)
+ for i in 1..dimA repeat
+ for j in 1..dimA repeat B(i,j):=A(i,j)
+ B(i,i) := B(i,i) - monomial(1$P,x,1)::F
+ determinant B
+
+ -------- EXPORTED FUNCTIONS --------
+
+ ---- characteristic polynomial of a matrix A ----
+ characteristicPolynomial(A:M):P ==
+ x:SE:=new()$SE
+ numer charpol(A,x)
+
+ ---- characteristic polynomial of a matrix A ----
+ characteristicPolynomial(A:M,x:SE) : P == numer charpol(A,x)
+
+ ---- Eigenvalues of the matrix A ----
+ eigenvalues(A:M): List Eigenvalue ==
+ x:=new()$SE
+ pol:= charpol(A,x)
+ lrat:List F :=empty()
+ lsym:List ST :=empty()
+ for eq in solve(pol,x)$SystemSolvePackage(R) repeat
+ alg:=numer lhs eq
+ degree(alg, x)=1 => lrat:=cons(rhs eq,lrat)
+ lsym:=cons([x,alg],lsym)
+ append([lr::Eigenvalue for lr in lrat],
+ [ls::Eigenvalue for ls in lsym])
+
+ ---- Eigenvectors belonging to a given eigenvalue ----
+ ---- the eigenvalue must be exact ----
+ eigenvector(alpha:Eigenvalue,A:M) : List M ==
+ alpha case F => intRatEig(alpha::F,A,1$NNI)
+ intAlgEig(alpha::ST,A,1$NNI)
+
+ ---- Eigenvectors belonging to a given rational eigenvalue ----
+ ---- Internal function -----
+ intRatEig(alpha:F,A:M,m:NNI) : List M ==
+ n:=nrows A
+ B:M := zero(n,n)$M
+ for i in 1..n repeat
+ for j in 1..n repeat B(i,j):=A(i,j)
+ B(i,i):= B(i,i) - alpha
+ [v::M for v in nullSpace(B**m)]
+
+ ---- Eigenvectors belonging to a given algebraic eigenvalue ----
+ ------ Internal Function -----
+ intAlgEig(alpha:ST,A:M,m:NNI) : List M ==
+ n:=nrows A
+ MM := ModularField(SUF,SUF,reduction,merge,exactquo)
+ AM:=Matrix MM
+ x:SE:=lhs alpha
+ pol:SUF:=unitCanonical map(coerce,univariate(rhs alpha,x))$UPCF2
+ alg:MM:=reduce(monomial(1,1),pol)
+ B:AM := zero(n,n)
+ for i in 1..n repeat
+ for j in 1..n repeat B(i,j):=reduce(A(i,j)::SUF,pol)
+ B(i,i):= B(i,i) - alg
+ sol: List M :=empty()
+ for vec in nullSpace(B**m) repeat
+ w:M:=zero(n,1)
+ for i in 1..n repeat w(i,1):=tff((vec.i)::SUF,x)
+ sol:=cons(w,sol)
+ sol
+
+ ---- Generalized Eigenvectors belonging to a given eigenvalue ----
+ generalizedEigenvector(alpha:Eigenvalue,A:M,k:NNI,g:NNI) : List M ==
+ alpha case F => intRatEig(alpha::F,A,(1+k-g)::NNI)
+ intAlgEig(alpha::ST,A,(1+k-g)::NNI)
+
+ ---- Generalized Eigenvectors belonging to a given eigenvalue ----
+ generalizedEigenvector(eigen :EigenForm,A:M) : List M ==
+ generalizedEigenvector(eigen.eigval,A,eigen.eigmult,# eigen.eigvec)
+
+ ---- Generalized Eigenvectors -----
+ generalizedEigenvectors(A:M) : List GenEigen ==
+ n:= nrows A
+ leig:=eigenvectors A
+ [genEigForm(leg,A) for leg in leig]
+
+ ---- eigenvectors and eigenvalues ----
+ eigenvectors(A:M):List(EigenForm) ==
+ n:=nrows A
+ x:=new()$SE
+ p:=numer charpol(A,x)
+ MM := ModularField(SUF,SUF,reduction,merge,exactquo)
+ AM:=Matrix(MM)
+ ratSol : List EigenForm := empty()
+ algSol : List EigenForm := empty()
+ lff:=factors factor p
+ for fact in lff repeat
+ pol:=fact.factor
+ degree(pol,x)=1 =>
+ vec:F :=-coefficient(pol,x,0)/coefficient(pol,x,degree(pol,x))
+ ratSol:=cons([vec,fact.exponent :: NNI,
+ intRatEig(vec,A,1$NNI)]$EigenForm,ratSol)
+ alpha:ST:=[x,pol]
+ algSol:=cons([alpha,fact.exponent :: NNI,
+ intAlgEig(alpha,A,1$NNI)]$EigenForm,algSol)
+ append(ratSol,algSol)
+
+@
+\section{package CHARPOL CharacteristicPolynomialPackage}
+<<package CHARPOL CharacteristicPolynomialPackage>>=
+)abbrev package CHARPOL CharacteristicPolynomialPackage
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides a characteristicPolynomial function
+++ for any matrix over a commutative ring.
+
+CharacteristicPolynomialPackage(R:CommutativeRing):C == T where
+ PI ==> PositiveInteger
+ M ==> Matrix R
+ C == with
+ characteristicPolynomial: (M, R) -> R
+ ++ characteristicPolynomial(m,r) computes the characteristic
+ ++ polynomial of the matrix m evaluated at the point r.
+ ++ In particular, if r is the polynomial 'x, then it returns
+ ++ the characteristic polynomial expressed as a polynomial in 'x.
+ T == add
+
+ ---- characteristic polynomial ----
+ characteristicPolynomial(A:M,v:R) : R ==
+ dimA :PI := (nrows A):PI
+ dimA ^= ncols A => error " The matrix is not square"
+ B:M:=zero(dimA,dimA)
+ for i in 1..dimA repeat
+ for j in 1..dimA repeat B(i,j):=A(i,j)
+ B(i,i) := B(i,i) - v
+ determinant B
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package EP EigenPackage>>
+<<package CHARPOL CharacteristicPolynomialPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/elemntry.spad.pamphlet b/src/algebra/elemntry.spad.pamphlet
new file mode 100644
index 00000000..8ddc8e52
--- /dev/null
+++ b/src/algebra/elemntry.spad.pamphlet
@@ -0,0 +1,914 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra elemntry.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package EF ElementaryFunction}
+<<package EF ElementaryFunction>>=
+)abbrev package EF ElementaryFunction
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 10 April 1995
+++ Keywords: elementary, function, logarithm, exponential.
+++ Examples: )r EF INPUT
+++ Description: Provides elementary functions over an integral domain.
+ElementaryFunction(R, F): Exports == Implementation where
+ R: Join(OrderedSet, IntegralDomain)
+ F: Join(FunctionSpace R, RadicalCategory)
+
+ B ==> Boolean
+ L ==> List
+ Z ==> Integer
+ OP ==> BasicOperator
+ K ==> Kernel F
+ INV ==> error "Invalid argument"
+
+ Exports ==> with
+ exp : F -> F
+ ++ exp(x) applies the exponential operator to x
+ log : F -> F
+ ++ log(x) applies the logarithm operator to x
+ sin : F -> F
+ ++ sin(x) applies the sine operator to x
+ cos : F -> F
+ ++ cos(x) applies the cosine operator to x
+ tan : F -> F
+ ++ tan(x) applies the tangent operator to x
+ cot : F -> F
+ ++ cot(x) applies the cotangent operator to x
+ sec : F -> F
+ ++ sec(x) applies the secant operator to x
+ csc : F -> F
+ ++ csc(x) applies the cosecant operator to x
+ asin : F -> F
+ ++ asin(x) applies the inverse sine operator to x
+ acos : F -> F
+ ++ acos(x) applies the inverse cosine operator to x
+ atan : F -> F
+ ++ atan(x) applies the inverse tangent operator to x
+ acot : F -> F
+ ++ acot(x) applies the inverse cotangent operator to x
+ asec : F -> F
+ ++ asec(x) applies the inverse secant operator to x
+ acsc : F -> F
+ ++ acsc(x) applies the inverse cosecant operator to x
+ sinh : F -> F
+ ++ sinh(x) applies the hyperbolic sine operator to x
+ cosh : F -> F
+ ++ cosh(x) applies the hyperbolic cosine operator to x
+ tanh : F -> F
+ ++ tanh(x) applies the hyperbolic tangent operator to x
+ coth : F -> F
+ ++ coth(x) applies the hyperbolic cotangent operator to x
+ sech : F -> F
+ ++ sech(x) applies the hyperbolic secant operator to x
+ csch : F -> F
+ ++ csch(x) applies the hyperbolic cosecant operator to x
+ asinh : F -> F
+ ++ asinh(x) applies the inverse hyperbolic sine operator to x
+ acosh : F -> F
+ ++ acosh(x) applies the inverse hyperbolic cosine operator to x
+ atanh : F -> F
+ ++ atanh(x) applies the inverse hyperbolic tangent operator to x
+ acoth : F -> F
+ ++ acoth(x) applies the inverse hyperbolic cotangent operator to x
+ asech : F -> F
+ ++ asech(x) applies the inverse hyperbolic secant operator to x
+ acsch : F -> F
+ ++ acsch(x) applies the inverse hyperbolic cosecant operator to x
+ pi : () -> F
+ ++ pi() returns the pi operator
+ belong? : OP -> Boolean
+ ++ belong?(p) returns true if operator p is elementary
+ operator: OP -> OP
+ ++ operator(p) returns an elementary operator with the same symbol as p
+ -- the following should be local, but are conditional
+ iisqrt2 : () -> F
+ ++ iisqrt2() should be local but conditional
+ iisqrt3 : () -> F
+ ++ iisqrt3() should be local but conditional
+ iiexp : F -> F
+ ++ iiexp(x) should be local but conditional
+ iilog : F -> F
+ ++ iilog(x) should be local but conditional
+ iisin : F -> F
+ ++ iisin(x) should be local but conditional
+ iicos : F -> F
+ ++ iicos(x) should be local but conditional
+ iitan : F -> F
+ ++ iitan(x) should be local but conditional
+ iicot : F -> F
+ ++ iicot(x) should be local but conditional
+ iisec : F -> F
+ ++ iisec(x) should be local but conditional
+ iicsc : F -> F
+ ++ iicsc(x) should be local but conditional
+ iiasin : F -> F
+ ++ iiasin(x) should be local but conditional
+ iiacos : F -> F
+ ++ iiacos(x) should be local but conditional
+ iiatan : F -> F
+ ++ iiatan(x) should be local but conditional
+ iiacot : F -> F
+ ++ iiacot(x) should be local but conditional
+ iiasec : F -> F
+ ++ iiasec(x) should be local but conditional
+ iiacsc : F -> F
+ ++ iiacsc(x) should be local but conditional
+ iisinh : F -> F
+ ++ iisinh(x) should be local but conditional
+ iicosh : F -> F
+ ++ iicosh(x) should be local but conditional
+ iitanh : F -> F
+ ++ iitanh(x) should be local but conditional
+ iicoth : F -> F
+ ++ iicoth(x) should be local but conditional
+ iisech : F -> F
+ ++ iisech(x) should be local but conditional
+ iicsch : F -> F
+ ++ iicsch(x) should be local but conditional
+ iiasinh : F -> F
+ ++ iiasinh(x) should be local but conditional
+ iiacosh : F -> F
+ ++ iiacosh(x) should be local but conditional
+ iiatanh : F -> F
+ ++ iiatanh(x) should be local but conditional
+ iiacoth : F -> F
+ ++ iiacoth(x) should be local but conditional
+ iiasech : F -> F
+ ++ iiasech(x) should be local but conditional
+ iiacsch : F -> F
+ ++ iiacsch(x) should be local but conditional
+ specialTrigs:(F, L Record(func:F,pole:B)) -> Union(F, "failed")
+ ++ specialTrigs(x,l) should be local but conditional
+ localReal?: F -> Boolean
+ ++ localReal?(x) should be local but conditional
+
+ Implementation ==> add
+ ipi : List F -> F
+ iexp : F -> F
+ ilog : F -> F
+ iiilog : F -> F
+ isin : F -> F
+ icos : F -> F
+ itan : F -> F
+ icot : F -> F
+ isec : F -> F
+ icsc : F -> F
+ iasin : F -> F
+ iacos : F -> F
+ iatan : F -> F
+ iacot : F -> F
+ iasec : F -> F
+ iacsc : F -> F
+ isinh : F -> F
+ icosh : F -> F
+ itanh : F -> F
+ icoth : F -> F
+ isech : F -> F
+ icsch : F -> F
+ iasinh : F -> F
+ iacosh : F -> F
+ iatanh : F -> F
+ iacoth : F -> F
+ iasech : F -> F
+ iacsch : F -> F
+ dropfun : F -> F
+ kernel : F -> K
+ posrem :(Z, Z) -> Z
+ iisqrt1 : () -> F
+ valueOrPole : Record(func:F, pole:B) -> F
+
+ oppi := operator("pi"::Symbol)$CommonOperators
+ oplog := operator("log"::Symbol)$CommonOperators
+ opexp := operator("exp"::Symbol)$CommonOperators
+ opsin := operator("sin"::Symbol)$CommonOperators
+ opcos := operator("cos"::Symbol)$CommonOperators
+ optan := operator("tan"::Symbol)$CommonOperators
+ opcot := operator("cot"::Symbol)$CommonOperators
+ opsec := operator("sec"::Symbol)$CommonOperators
+ opcsc := operator("csc"::Symbol)$CommonOperators
+ opasin := operator("asin"::Symbol)$CommonOperators
+ opacos := operator("acos"::Symbol)$CommonOperators
+ opatan := operator("atan"::Symbol)$CommonOperators
+ opacot := operator("acot"::Symbol)$CommonOperators
+ opasec := operator("asec"::Symbol)$CommonOperators
+ opacsc := operator("acsc"::Symbol)$CommonOperators
+ opsinh := operator("sinh"::Symbol)$CommonOperators
+ opcosh := operator("cosh"::Symbol)$CommonOperators
+ optanh := operator("tanh"::Symbol)$CommonOperators
+ opcoth := operator("coth"::Symbol)$CommonOperators
+ opsech := operator("sech"::Symbol)$CommonOperators
+ opcsch := operator("csch"::Symbol)$CommonOperators
+ opasinh := operator("asinh"::Symbol)$CommonOperators
+ opacosh := operator("acosh"::Symbol)$CommonOperators
+ opatanh := operator("atanh"::Symbol)$CommonOperators
+ opacoth := operator("acoth"::Symbol)$CommonOperators
+ opasech := operator("asech"::Symbol)$CommonOperators
+ opacsch := operator("acsch"::Symbol)$CommonOperators
+
+ -- Pi is a domain...
+ Pie, isqrt1, isqrt2, isqrt3: F
+
+ -- following code is conditionalized on arbitraryPrecesion to recompute in
+ -- case user changes the precision
+
+ if R has TranscendentalFunctionCategory then
+ Pie := pi()$R :: F
+ else
+ Pie := kernel(oppi, nil()$List(F))
+
+ if R has TranscendentalFunctionCategory and R has arbitraryPrecision then
+ pi() == pi()$R :: F
+ else
+ pi() == Pie
+
+ if R has imaginary: () -> R then
+ isqrt1 := imaginary()$R :: F
+ else isqrt1 := sqrt(-1::F)
+
+ if R has RadicalCategory then
+ isqrt2 := sqrt(2::R)::F
+ isqrt3 := sqrt(3::R)::F
+ else
+ isqrt2 := sqrt(2::F)
+ isqrt3 := sqrt(3::F)
+
+ iisqrt1() == isqrt1
+ if R has RadicalCategory and R has arbitraryPrecision then
+ iisqrt2() == sqrt(2::R)::F
+ iisqrt3() == sqrt(3::R)::F
+ else
+ iisqrt2() == isqrt2
+ iisqrt3() == isqrt3
+
+ ipi l == pi()
+ log x == oplog x
+ exp x == opexp x
+ sin x == opsin x
+ cos x == opcos x
+ tan x == optan x
+ cot x == opcot x
+ sec x == opsec x
+ csc x == opcsc x
+ asin x == opasin x
+ acos x == opacos x
+ atan x == opatan x
+ acot x == opacot x
+ asec x == opasec x
+ acsc x == opacsc x
+ sinh x == opsinh x
+ cosh x == opcosh x
+ tanh x == optanh x
+ coth x == opcoth x
+ sech x == opsech x
+ csch x == opcsch x
+ asinh x == opasinh x
+ acosh x == opacosh x
+ atanh x == opatanh x
+ acoth x == opacoth x
+ asech x == opasech x
+ acsch x == opacsch x
+ kernel x == retract(x)@K
+
+ posrem(n, m) == ((r := n rem m) < 0 => r + m; r)
+ valueOrPole rec == (rec.pole => INV; rec.func)
+ belong? op == has?(op, "elem")
+
+ operator op ==
+ is?(op, "pi"::Symbol) => oppi
+ is?(op, "log"::Symbol) => oplog
+ is?(op, "exp"::Symbol) => opexp
+ is?(op, "sin"::Symbol) => opsin
+ is?(op, "cos"::Symbol) => opcos
+ is?(op, "tan"::Symbol) => optan
+ is?(op, "cot"::Symbol) => opcot
+ is?(op, "sec"::Symbol) => opsec
+ is?(op, "csc"::Symbol) => opcsc
+ is?(op, "asin"::Symbol) => opasin
+ is?(op, "acos"::Symbol) => opacos
+ is?(op, "atan"::Symbol) => opatan
+ is?(op, "acot"::Symbol) => opacot
+ is?(op, "asec"::Symbol) => opasec
+ is?(op, "acsc"::Symbol) => opacsc
+ is?(op, "sinh"::Symbol) => opsinh
+ is?(op, "cosh"::Symbol) => opcosh
+ is?(op, "tanh"::Symbol) => optanh
+ is?(op, "coth"::Symbol) => opcoth
+ is?(op, "sech"::Symbol) => opsech
+ is?(op, "csch"::Symbol) => opcsch
+ is?(op, "asinh"::Symbol) => opasinh
+ is?(op, "acosh"::Symbol) => opacosh
+ is?(op, "atanh"::Symbol) => opatanh
+ is?(op, "acoth"::Symbol) => opacoth
+ is?(op, "asech"::Symbol) => opasech
+ is?(op, "acsch"::Symbol) => opacsch
+ error "Not an elementary operator"
+
+ dropfun x ==
+ ((k := retractIfCan(x)@Union(K, "failed")) case "failed") or
+ empty?(argument(k::K)) => 0
+ first argument(k::K)
+
+ if R has RetractableTo Z then
+ specialTrigs(x, values) ==
+ (r := retractIfCan(y := x/pi())@Union(Fraction Z, "failed"))
+ case "failed" => "failed"
+ q := r::Fraction(Integer)
+ m := minIndex values
+ (n := retractIfCan(q)@Union(Z, "failed")) case Z =>
+ even?(n::Z) => valueOrPole(values.m)
+ valueOrPole(values.(m+1))
+ (n := retractIfCan(2*q)@Union(Z, "failed")) case Z =>
+-- one?(s := posrem(n::Z, 4)) => valueOrPole(values.(m+2))
+ (s := posrem(n::Z, 4)) = 1 => valueOrPole(values.(m+2))
+ valueOrPole(values.(m+3))
+ (n := retractIfCan(3*q)@Union(Z, "failed")) case Z =>
+-- one?(s := posrem(n::Z, 6)) => valueOrPole(values.(m+4))
+ (s := posrem(n::Z, 6)) = 1 => valueOrPole(values.(m+4))
+ s = 2 => valueOrPole(values.(m+5))
+ s = 4 => valueOrPole(values.(m+6))
+ valueOrPole(values.(m+7))
+ (n := retractIfCan(4*q)@Union(Z, "failed")) case Z =>
+-- one?(s := posrem(n::Z, 8)) => valueOrPole(values.(m+8))
+ (s := posrem(n::Z, 8)) = 1 => valueOrPole(values.(m+8))
+ s = 3 => valueOrPole(values.(m+9))
+ s = 5 => valueOrPole(values.(m+10))
+ valueOrPole(values.(m+11))
+ (n := retractIfCan(6*q)@Union(Z, "failed")) case Z =>
+-- one?(s := posrem(n::Z, 12)) => valueOrPole(values.(m+12))
+ (s := posrem(n::Z, 12)) = 1 => valueOrPole(values.(m+12))
+ s = 5 => valueOrPole(values.(m+13))
+ s = 7 => valueOrPole(values.(m+14))
+ valueOrPole(values.(m+15))
+ "failed"
+
+ else specialTrigs(x, values) == "failed"
+
+ isin x ==
+ zero? x => 0
+ y := dropfun x
+ is?(x, opasin) => y
+ is?(x, opacos) => sqrt(1 - y**2)
+ is?(x, opatan) => y / sqrt(1 + y**2)
+ is?(x, opacot) => inv sqrt(1 + y**2)
+ is?(x, opasec) => sqrt(y**2 - 1) / y
+ is?(x, opacsc) => inv y
+ h := inv(2::F)
+ s2 := h * iisqrt2()
+ s3 := h * iisqrt3()
+ u := specialTrigs(x, [[0,false], [0,false], [1,false], [-1,false],
+ [s3,false], [s3,false], [-s3,false], [-s3,false],
+ [s2,false], [s2,false], [-s2,false], [-s2,false],
+ [h,false], [h,false], [-h,false], [-h,false]])
+ u case F => u :: F
+ kernel(opsin, x)
+
+ icos x ==
+ zero? x => 1
+ y := dropfun x
+ is?(x, opasin) => sqrt(1 - y**2)
+ is?(x, opacos) => y
+ is?(x, opatan) => inv sqrt(1 + y**2)
+ is?(x, opacot) => y / sqrt(1 + y**2)
+ is?(x, opasec) => inv y
+ is?(x, opacsc) => sqrt(y**2 - 1) / y
+ h := inv(2::F)
+ s2 := h * iisqrt2()
+ s3 := h * iisqrt3()
+ u := specialTrigs(x, [[1,false],[-1,false], [0,false], [0,false],
+ [h,false],[-h,false],[-h,false],[h,false],
+ [s2,false],[-s2,false],[-s2,false],[s2,false],
+ [s3,false], [-s3,false],[-s3,false],[s3,false]])
+ u case F => u :: F
+ kernel(opcos, x)
+
+ itan x ==
+ zero? x => 0
+ y := dropfun x
+ is?(x, opasin) => y / sqrt(1 - y**2)
+ is?(x, opacos) => sqrt(1 - y**2) / y
+ is?(x, opatan) => y
+ is?(x, opacot) => inv y
+ is?(x, opasec) => sqrt(y**2 - 1)
+ is?(x, opacsc) => inv sqrt(y**2 - 1)
+ s33 := (s3 := iisqrt3()) / (3::F)
+ u := specialTrigs(x, [[0,false], [0,false], [0,true], [0,true],
+ [s3,false], [-s3,false], [s3,false], [-s3,false],
+ [1,false], [-1,false], [1,false], [-1,false],
+ [s33,false], [-s33, false], [s33,false], [-s33, false]])
+ u case F => u :: F
+ kernel(optan, x)
+
+ icot x ==
+ zero? x => INV
+ y := dropfun x
+ is?(x, opasin) => sqrt(1 - y**2) / y
+ is?(x, opacos) => y / sqrt(1 - y**2)
+ is?(x, opatan) => inv y
+ is?(x, opacot) => y
+ is?(x, opasec) => inv sqrt(y**2 - 1)
+ is?(x, opacsc) => sqrt(y**2 - 1)
+ s33 := (s3 := iisqrt3()) / (3::F)
+ u := specialTrigs(x, [[0,true], [0,true], [0,false], [0,false],
+ [s33,false], [-s33,false], [s33,false], [-s33,false],
+ [1,false], [-1,false], [1,false], [-1,false],
+ [s3,false], [-s3, false], [s3,false], [-s3, false]])
+ u case F => u :: F
+ kernel(opcot, x)
+
+ isec x ==
+ zero? x => 1
+ y := dropfun x
+ is?(x, opasin) => inv sqrt(1 - y**2)
+ is?(x, opacos) => inv y
+ is?(x, opatan) => sqrt(1 + y**2)
+ is?(x, opacot) => sqrt(1 + y**2) / y
+ is?(x, opasec) => y
+ is?(x, opacsc) => y / sqrt(y**2 - 1)
+ s2 := iisqrt2()
+ s3 := 2 * iisqrt3() / (3::F)
+ h := 2::F
+ u := specialTrigs(x, [[1,false],[-1,false],[0,true],[0,true],
+ [h,false], [-h,false], [-h,false], [h,false],
+ [s2,false], [-s2,false], [-s2,false], [s2,false],
+ [s3,false], [-s3,false], [-s3,false], [s3,false]])
+ u case F => u :: F
+ kernel(opsec, x)
+
+ icsc x ==
+ zero? x => INV
+ y := dropfun x
+ is?(x, opasin) => inv y
+ is?(x, opacos) => inv sqrt(1 - y**2)
+ is?(x, opatan) => sqrt(1 + y**2) / y
+ is?(x, opacot) => sqrt(1 + y**2)
+ is?(x, opasec) => y / sqrt(y**2 - 1)
+ is?(x, opacsc) => y
+ s2 := iisqrt2()
+ s3 := 2 * iisqrt3() / (3::F)
+ h := 2::F
+ u := specialTrigs(x, [[0,true], [0,true], [1,false], [-1,false],
+ [s3,false], [s3,false], [-s3,false], [-s3,false],
+ [s2,false], [s2,false], [-s2,false], [-s2,false],
+ [h,false], [h,false], [-h,false], [-h,false]])
+ u case F => u :: F
+ kernel(opcsc, x)
+
+ iasin x ==
+ zero? x => 0
+-- one? x => pi() / (2::F)
+ (x = 1) => pi() / (2::F)
+ x = -1 => - pi() / (2::F)
+ y := dropfun x
+ is?(x, opsin) => y
+ is?(x, opcos) => pi() / (2::F) - y
+ kernel(opasin, x)
+
+ iacos x ==
+ zero? x => pi() / (2::F)
+-- one? x => 0
+ (x = 1) => 0
+ x = -1 => pi()
+ y := dropfun x
+ is?(x, opsin) => pi() / (2::F) - y
+ is?(x, opcos) => y
+ kernel(opacos, x)
+
+ iatan x ==
+ zero? x => 0
+-- one? x => pi() / (4::F)
+ (x = 1) => pi() / (4::F)
+ x = -1 => - pi() / (4::F)
+ x = (r3:=iisqrt3()) => pi() / (3::F)
+-- one?(x*r3) => pi() / (6::F)
+ (x*r3) = 1 => pi() / (6::F)
+ y := dropfun x
+ is?(x, optan) => y
+ is?(x, opcot) => pi() / (2::F) - y
+ kernel(opatan, x)
+
+ iacot x ==
+ zero? x => pi() / (2::F)
+-- one? x => pi() / (4::F)
+ (x = 1) => pi() / (4::F)
+ x = -1 => 3 * pi() / (4::F)
+ x = (r3:=iisqrt3()) => pi() / (6::F)
+ x = -r3 => 5 * pi() / (6::F)
+-- one?(xx:=x*r3) => pi() / (3::F)
+ (xx:=x*r3) = 1 => pi() / (3::F)
+ xx = -1 => 2* pi() / (3::F)
+ y := dropfun x
+ is?(x, optan) => pi() / (2::F) - y
+ is?(x, opcot) => y
+ kernel(opacot, x)
+
+ iasec x ==
+ zero? x => INV
+-- one? x => 0
+ (x = 1) => 0
+ x = -1 => pi()
+ y := dropfun x
+ is?(x, opsec) => y
+ is?(x, opcsc) => pi() / (2::F) - y
+ kernel(opasec, x)
+
+ iacsc x ==
+ zero? x => INV
+-- one? x => pi() / (2::F)
+ (x = 1) => pi() / (2::F)
+ x = -1 => - pi() / (2::F)
+ y := dropfun x
+ is?(x, opsec) => pi() / (2::F) - y
+ is?(x, opcsc) => y
+ kernel(opacsc, x)
+
+ isinh x ==
+ zero? x => 0
+ y := dropfun x
+ is?(x, opasinh) => y
+ is?(x, opacosh) => sqrt(y**2 - 1)
+ is?(x, opatanh) => y / sqrt(1 - y**2)
+ is?(x, opacoth) => - inv sqrt(y**2 - 1)
+ is?(x, opasech) => sqrt(1 - y**2) / y
+ is?(x, opacsch) => inv y
+ kernel(opsinh, x)
+
+ icosh x ==
+ zero? x => 1
+ y := dropfun x
+ is?(x, opasinh) => sqrt(y**2 + 1)
+ is?(x, opacosh) => y
+ is?(x, opatanh) => inv sqrt(1 - y**2)
+ is?(x, opacoth) => y / sqrt(y**2 - 1)
+ is?(x, opasech) => inv y
+ is?(x, opacsch) => sqrt(y**2 + 1) / y
+ kernel(opcosh, x)
+
+ itanh x ==
+ zero? x => 0
+ y := dropfun x
+ is?(x, opasinh) => y / sqrt(y**2 + 1)
+ is?(x, opacosh) => sqrt(y**2 - 1) / y
+ is?(x, opatanh) => y
+ is?(x, opacoth) => inv y
+ is?(x, opasech) => sqrt(1 - y**2)
+ is?(x, opacsch) => inv sqrt(y**2 + 1)
+ kernel(optanh, x)
+
+ icoth x ==
+ zero? x => INV
+ y := dropfun x
+ is?(x, opasinh) => sqrt(y**2 + 1) / y
+ is?(x, opacosh) => y / sqrt(y**2 - 1)
+ is?(x, opatanh) => inv y
+ is?(x, opacoth) => y
+ is?(x, opasech) => inv sqrt(1 - y**2)
+ is?(x, opacsch) => sqrt(y**2 + 1)
+ kernel(opcoth, x)
+
+ isech x ==
+ zero? x => 1
+ y := dropfun x
+ is?(x, opasinh) => inv sqrt(y**2 + 1)
+ is?(x, opacosh) => inv y
+ is?(x, opatanh) => sqrt(1 - y**2)
+ is?(x, opacoth) => sqrt(y**2 - 1) / y
+ is?(x, opasech) => y
+ is?(x, opacsch) => y / sqrt(y**2 + 1)
+ kernel(opsech, x)
+
+ icsch x ==
+ zero? x => INV
+ y := dropfun x
+ is?(x, opasinh) => inv y
+ is?(x, opacosh) => inv sqrt(y**2 - 1)
+ is?(x, opatanh) => sqrt(1 - y**2) / y
+ is?(x, opacoth) => - sqrt(y**2 - 1)
+ is?(x, opasech) => y / sqrt(1 - y**2)
+ is?(x, opacsch) => y
+ kernel(opcsch, x)
+
+ iasinh x ==
+ is?(x, opsinh) => first argument kernel x
+ kernel(opasinh, x)
+
+ iacosh x ==
+ is?(x, opcosh) => first argument kernel x
+ kernel(opacosh, x)
+
+ iatanh x ==
+ is?(x, optanh) => first argument kernel x
+ kernel(opatanh, x)
+
+ iacoth x ==
+ is?(x, opcoth) => first argument kernel x
+ kernel(opacoth, x)
+
+ iasech x ==
+ is?(x, opsech) => first argument kernel x
+ kernel(opasech, x)
+
+ iacsch x ==
+ is?(x, opcsch) => first argument kernel x
+ kernel(opacsch, x)
+
+ iexp x ==
+ zero? x => 1
+ is?(x, oplog) => first argument kernel x
+ x < 0 and empty? variables x => inv iexp(-x)
+ h := inv(2::F)
+ i := iisqrt1()
+ s2 := h * iisqrt2()
+ s3 := h * iisqrt3()
+ u := specialTrigs(x / i, [[1,false],[-1,false], [i,false], [-i,false],
+ [h + i * s3,false], [-h + i * s3, false], [-h - i * s3, false],
+ [h - i * s3, false], [s2 + i * s2, false], [-s2 + i * s2, false],
+ [-s2 - i * s2, false], [s2 - i * s2, false], [s3 + i * h, false],
+ [-s3 + i * h, false], [-s3 - i * h, false], [s3 - i * h, false]])
+ u case F => u :: F
+ kernel(opexp, x)
+
+-- THIS DETERMINES WHEN TO PERFORM THE log exp f -> f SIMPLIFICATION
+-- CURRENT BEHAVIOR:
+-- IF R IS COMPLEX(S) THEN ONLY ELEMENTS WHICH ARE RETRACTABLE TO R
+-- AND EQUAL TO THEIR CONJUGATES ARE DEEMED REAL (OVERRESTRICTIVE FOR NOW)
+-- OTHERWISE (e.g. R = INT OR FRAC INT), ALL THE ELEMENTS ARE DEEMED REAL
+
+ if (R has imaginary:() -> R) and (R has conjugate: R -> R) then
+ localReal? x ==
+ (u := retractIfCan(x)@Union(R, "failed")) case R
+ and (u::R) = conjugate(u::R)
+
+ else localReal? x == true
+
+ iiilog x ==
+ zero? x => INV
+-- one? x => 0
+ (x = 1) => 0
+ (u := isExpt(x, opexp)) case Record(var:K, exponent:Integer) =>
+ rec := u::Record(var:K, exponent:Integer)
+ arg := first argument(rec.var);
+ localReal? arg => rec.exponent * first argument(rec.var);
+ ilog x
+ ilog x
+
+ ilog x ==
+-- ((num1 := one?(num := numer x)) or num = -1) and (den := denom x) ^= 1
+ ((num1 := ((num := numer x) = 1)) or num = -1) and (den := denom x) ^= 1
+ and empty? variables x => - kernel(oplog, (num1 => den; -den)::F)
+ kernel(oplog, x)
+
+ if R has ElementaryFunctionCategory then
+ iilog x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iiilog x
+ log(r::R)::F
+
+ iiexp x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iexp x
+ exp(r::R)::F
+
+ else
+ iilog x == iiilog x
+ iiexp x == iexp x
+
+ if R has TrigonometricFunctionCategory then
+ iisin x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => isin x
+ sin(r::R)::F
+
+ iicos x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => icos x
+ cos(r::R)::F
+
+ iitan x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => itan x
+ tan(r::R)::F
+
+ iicot x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => icot x
+ cot(r::R)::F
+
+ iisec x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => isec x
+ sec(r::R)::F
+
+ iicsc x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => icsc x
+ csc(r::R)::F
+
+ else
+ iisin x == isin x
+ iicos x == icos x
+ iitan x == itan x
+ iicot x == icot x
+ iisec x == isec x
+ iicsc x == icsc x
+
+ if R has ArcTrigonometricFunctionCategory then
+ iiasin x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iasin x
+ asin(r::R)::F
+
+ iiacos x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iacos x
+ acos(r::R)::F
+
+ iiatan x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iatan x
+ atan(r::R)::F
+
+ iiacot x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iacot x
+ acot(r::R)::F
+
+ iiasec x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iasec x
+ asec(r::R)::F
+
+ iiacsc x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iacsc x
+ acsc(r::R)::F
+
+ else
+ iiasin x == iasin x
+ iiacos x == iacos x
+ iiatan x == iatan x
+ iiacot x == iacot x
+ iiasec x == iasec x
+ iiacsc x == iacsc x
+
+ if R has HyperbolicFunctionCategory then
+ iisinh x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => isinh x
+ sinh(r::R)::F
+
+ iicosh x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => icosh x
+ cosh(r::R)::F
+
+ iitanh x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => itanh x
+ tanh(r::R)::F
+
+ iicoth x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => icoth x
+ coth(r::R)::F
+
+ iisech x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => isech x
+ sech(r::R)::F
+
+ iicsch x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => icsch x
+ csch(r::R)::F
+
+ else
+ iisinh x == isinh x
+ iicosh x == icosh x
+ iitanh x == itanh x
+ iicoth x == icoth x
+ iisech x == isech x
+ iicsch x == icsch x
+
+ if R has ArcHyperbolicFunctionCategory then
+ iiasinh x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iasinh x
+ asinh(r::R)::F
+
+ iiacosh x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iacosh x
+ acosh(r::R)::F
+
+ iiatanh x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iatanh x
+ atanh(r::R)::F
+
+ iiacoth x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iacoth x
+ acoth(r::R)::F
+
+ iiasech x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iasech x
+ asech(r::R)::F
+
+ iiacsch x ==
+ (r:=retractIfCan(x)@Union(R,"failed")) case "failed" => iacsch x
+ acsch(r::R)::F
+
+ else
+ iiasinh x == iasinh x
+ iiacosh x == iacosh x
+ iiatanh x == iatanh x
+ iiacoth x == iacoth x
+ iiasech x == iasech x
+ iiacsch x == iacsch x
+
+ evaluate(oppi, ipi)$BasicOperatorFunctions1(F)
+ evaluate(oplog, iilog)
+ evaluate(opexp, iiexp)
+ evaluate(opsin, iisin)
+ evaluate(opcos, iicos)
+ evaluate(optan, iitan)
+ evaluate(opcot, iicot)
+ evaluate(opsec, iisec)
+ evaluate(opcsc, iicsc)
+ evaluate(opasin, iiasin)
+ evaluate(opacos, iiacos)
+ evaluate(opatan, iiatan)
+ evaluate(opacot, iiacot)
+ evaluate(opasec, iiasec)
+ evaluate(opacsc, iiacsc)
+ evaluate(opsinh, iisinh)
+ evaluate(opcosh, iicosh)
+ evaluate(optanh, iitanh)
+ evaluate(opcoth, iicoth)
+ evaluate(opsech, iisech)
+ evaluate(opcsch, iicsch)
+ evaluate(opasinh, iiasinh)
+ evaluate(opacosh, iiacosh)
+ evaluate(opatanh, iiatanh)
+ evaluate(opacoth, iiacoth)
+ evaluate(opasech, iiasech)
+ evaluate(opacsch, iiacsch)
+ derivative(opexp, exp)
+ derivative(oplog, inv)
+ derivative(opsin, cos)
+ derivative(opcos, - sin #1)
+ derivative(optan, 1 + tan(#1)**2)
+ derivative(opcot, - 1 - cot(#1)**2)
+ derivative(opsec, tan(#1) * sec(#1))
+ derivative(opcsc, - cot(#1) * csc(#1))
+ derivative(opasin, inv sqrt(1 - #1**2))
+ derivative(opacos, - inv sqrt(1 - #1**2))
+ derivative(opatan, inv(1 + #1**2))
+ derivative(opacot, - inv(1 + #1**2))
+ derivative(opasec, inv(#1 * sqrt(#1**2 - 1)))
+ derivative(opacsc, - inv(#1 * sqrt(#1**2 - 1)))
+ derivative(opsinh, cosh)
+ derivative(opcosh, sinh)
+ derivative(optanh, 1 - tanh(#1)**2)
+ derivative(opcoth, 1 - coth(#1)**2)
+ derivative(opsech, - tanh(#1) * sech(#1))
+ derivative(opcsch, - coth(#1) * csch(#1))
+ derivative(opasinh, inv sqrt(1 + #1**2))
+ derivative(opacosh, inv sqrt(#1**2 - 1))
+ derivative(opatanh, inv(1 - #1**2))
+ derivative(opacoth, inv(1 - #1**2))
+ derivative(opasech, - inv(#1 * sqrt(1 - #1**2)))
+ derivative(opacsch, - inv(#1 * sqrt(1 + #1**2)))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl fspace algfunc ELEMNTRY expr
+<<package EF ElementaryFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/elfuts.spad.pamphlet b/src/algebra/elfuts.spad.pamphlet
new file mode 100644
index 00000000..07366493
--- /dev/null
+++ b/src/algebra/elfuts.spad.pamphlet
@@ -0,0 +1,110 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra elfuts.spad}
+\author{Bill Burge, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ELFUTS EllipticFunctionsUnivariateTaylorSeries}
+<<package ELFUTS EllipticFunctionsUnivariateTaylorSeries>>=
+)abbrev package ELFUTS EllipticFunctionsUnivariateTaylorSeries
+++ Elliptic functions expanded as Taylor series
+++ Author: Bill Burge, Clifton J. Williamson
+++ Date Created: 1986
+++ Date Last Updated: 17 February 1992
+++ Keywords: elliptic function, Taylor series
+++ Examples:
+++ References:
+++ Description: The elliptic functions sn, sc and dn are expanded as
+++ Taylor series.
+EllipticFunctionsUnivariateTaylorSeries(Coef,UTS):
+ Exports == Implementation where
+ Coef : Field
+ UTS : UnivariateTaylorSeriesCategory Coef
+
+ L ==> List
+ I ==> Integer
+ RN ==> Fraction Integer
+ ST ==> Stream Coef
+ STT ==> StreamTaylorSeriesOperations Coef
+ YS ==> Y$ParadoxicalCombinatorsForStreams(Coef)
+
+ Exports ==> with
+ sn : (UTS,Coef) -> UTS
+ ++\spad{sn(x,k)} expands the elliptic function sn as a Taylor
+ ++ series.
+ cn : (UTS,Coef) -> UTS
+ ++\spad{cn(x,k)} expands the elliptic function cn as a Taylor
+ ++ series.
+ dn : (UTS,Coef) -> UTS
+ ++\spad{dn(x,k)} expands the elliptic function dn as a Taylor
+ ++ series.
+ sncndn: (ST,Coef) -> L ST
+ ++\spad{sncndn(s,c)} is used internally.
+
+ Implementation ==> add
+ import StreamTaylorSeriesOperations Coef
+ UPS==> StreamTaylorSeriesOperations Coef
+ integrate ==> lazyIntegrate
+ sncndnre:(Coef,L ST,ST,Coef) -> L ST
+ sncndnre(k,scd,dx,sign) ==
+ [integrate(0, scd.2*$UPS scd.3*$UPS dx), _
+ integrate(1, sign*scd.1*$UPS scd.3*$UPS dx), _
+ integrate(1,sign*k**2*$UPS scd.1*$UPS scd.2*$UPS dx)]
+
+ sncndn(z,k) ==
+ empty? z => [0 :: ST,1 :: ST,1::ST]
+ frst z = 0 => YS(sncndnre(k,#1,deriv z,-1),3)
+ error "ELFUTS:sncndn: constant coefficient should be 0"
+ sn(x,k) == series sncndn.(coefficients x,k).1
+ cn(x,k) == series sncndn.(coefficients x,k).2
+ dn(x,k) == series sncndn.(coefficients x,k).3
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ELFUTS EllipticFunctionsUnivariateTaylorSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/equation1.spad.pamphlet b/src/algebra/equation1.spad.pamphlet
new file mode 100644
index 00000000..a147e689
--- /dev/null
+++ b/src/algebra/equation1.spad.pamphlet
@@ -0,0 +1,112 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra equation1.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category IEVALAB InnerEvalable}
+<<category IEVALAB InnerEvalable>>=
+)abbrev category IEVALAB InnerEvalable
+-- FOR THE BENEFIT OF LIBAX0 GENERATION
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See: Evalable
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This category provides \spadfun{eval} operations.
+++ A domain may belong to this category if it is possible to make
+++ ``evaluation'' substitutions. The difference between this
+++ and \spadtype{Evalable} is that the operations in this category
+++ specify the substitution as a pair of arguments rather than as
+++ an equation.
+InnerEvalable(A:SetCategory, B:Type): Category == with
+ eval: ($, A, B) -> $
+ ++ eval(f, x, v) replaces x by v in f.
+ eval: ($, List A, List B) -> $
+ ++ eval(f, [x1,...,xn], [v1,...,vn]) replaces xi by vi in f.
+ add
+ eval(f:$, x:A, v:B) == eval(f, [x], [v])
+
+@
+\section{category EVALAB Evalable}
+<<category EVALAB Evalable>>=
+)abbrev category EVALAB Evalable
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See: FullyEvalable
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This category provides \spadfun{eval} operations.
+++ A domain may belong to this category if it is possible to make
+++ ``evaluation'' substitutions.
+Evalable(R:SetCategory): Category == InnerEvalable(R,R) with
+ eval: ($, Equation R) -> $
+ ++ eval(f,x = v) replaces x by v in f.
+ eval: ($, List Equation R) -> $
+ ++ eval(f, [x1 = v1,...,xn = vn]) replaces xi by vi in f.
+ add
+ eval(f:$, eq:Equation R) == eval(f, [eq])
+ eval(f:$, xs:List R,vs:List R) == eval(f,[x=v for x in xs for v in vs])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category IEVALAB InnerEvalable>>
+<<category EVALAB Evalable>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/equation2.spad.pamphlet b/src/algebra/equation2.spad.pamphlet
new file mode 100644
index 00000000..8ae385bb
--- /dev/null
+++ b/src/algebra/equation2.spad.pamphlet
@@ -0,0 +1,325 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra equation2.spad}
+\author{Stephen M. Watt, Johannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain EQ Equation}
+<<domain EQ Equation>>=
+)abbrev domain EQ Equation
+--FOR THE BENEFIT OF LIBAX0 GENERATION
+++ Author: Stephen M. Watt, enhancements by Johannes Grabmeier
+++ Date Created: April 1985
+++ Date Last Updated: June 3, 1991; September 2, 1992
+++ Basic Operations: =
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ Equations as mathematical objects. All properties of the basis domain,
+++ e.g. being an abelian group are carried over the equation domain, by
+++ performing the structural operations on the left and on the
+++ right hand side.
+-- The interpreter translates "=" to "equation". Otherwise, it will
+-- find a modemap for "=" in the domain of the arguments.
+
+Equation(S: Type): public == private where
+ Ex ==> OutputForm
+ public ==> Type with
+ "=": (S, S) -> $
+ ++ a=b creates an equation.
+ equation: (S, S) -> $
+ ++ equation(a,b) creates an equation.
+ swap: $ -> $
+ ++ swap(eq) interchanges left and right hand side of equation eq.
+ lhs: $ -> S
+ ++ lhs(eqn) returns the left hand side of equation eqn.
+ rhs: $ -> S
+ ++ rhs(eqn) returns the right hand side of equation eqn.
+ map: (S -> S, $) -> $
+ ++ map(f,eqn) constructs a new equation by applying f to both
+ ++ sides of eqn.
+ if S has InnerEvalable(Symbol,S) then
+ InnerEvalable(Symbol,S)
+ if S has SetCategory then
+ SetCategory
+ CoercibleTo Boolean
+ if S has Evalable(S) then
+ eval: ($, $) -> $
+ ++ eval(eqn, x=f) replaces x by f in equation eqn.
+ eval: ($, List $) -> $
+ ++ eval(eqn, [x1=v1, ... xn=vn]) replaces xi by vi in equation eqn.
+ if S has AbelianSemiGroup then
+ AbelianSemiGroup
+ "+": (S, $) -> $
+ ++ x+eqn produces a new equation by adding x to both sides of
+ ++ equation eqn.
+ "+": ($, S) -> $
+ ++ eqn+x produces a new equation by adding x to both sides of
+ ++ equation eqn.
+ if S has AbelianGroup then
+ AbelianGroup
+ leftZero : $ -> $
+ ++ leftZero(eq) subtracts the left hand side.
+ rightZero : $ -> $
+ ++ rightZero(eq) subtracts the right hand side.
+ "-": (S, $) -> $
+ ++ x-eqn produces a new equation by subtracting both sides of
+ ++ equation eqn from x.
+ "-": ($, S) -> $
+ ++ eqn-x produces a new equation by subtracting x from both sides of
+ ++ equation eqn.
+ if S has SemiGroup then
+ SemiGroup
+ "*": (S, $) -> $
+ ++ x*eqn produces a new equation by multiplying both sides of
+ ++ equation eqn by x.
+ "*": ($, S) -> $
+ ++ eqn*x produces a new equation by multiplying both sides of
+ ++ equation eqn by x.
+ if S has Monoid then
+ Monoid
+ leftOne : $ -> Union($,"failed")
+ ++ leftOne(eq) divides by the left hand side, if possible.
+ rightOne : $ -> Union($,"failed")
+ ++ rightOne(eq) divides by the right hand side, if possible.
+ if S has Group then
+ Group
+ leftOne : $ -> Union($,"failed")
+ ++ leftOne(eq) divides by the left hand side.
+ rightOne : $ -> Union($,"failed")
+ ++ rightOne(eq) divides by the right hand side.
+ if S has Ring then
+ Ring
+ BiModule(S,S)
+ if S has CommutativeRing then
+ Module(S)
+ --Algebra(S)
+ if S has IntegralDomain then
+ factorAndSplit : $ -> List $
+ ++ factorAndSplit(eq) make the right hand side 0 and
+ ++ factors the new left hand side. Each factor is equated
+ ++ to 0 and put into the resulting list without repetitions.
+ if S has PartialDifferentialRing(Symbol) then
+ PartialDifferentialRing(Symbol)
+ if S has Field then
+ VectorSpace(S)
+ "/": ($, $) -> $
+ ++ e1/e2 produces a new equation by dividing the left and right
+ ++ hand sides of equations e1 and e2.
+ inv: $ -> $
+ ++ inv(x) returns the multiplicative inverse of x.
+ if S has ExpressionSpace then
+ subst: ($, $) -> $
+ ++ subst(eq1,eq2) substitutes eq2 into both sides of eq1
+ ++ the lhs of eq2 should be a kernel
+
+ private ==> add
+ Rep := Record(lhs: S, rhs: S)
+ eq1,eq2: $
+ s : S
+ if S has IntegralDomain then
+ factorAndSplit eq ==
+ (S has factor : S -> Factored S) =>
+ eq0 := rightZero eq
+ [equation(rcf.factor,0) for rcf in factors factor lhs eq0]
+ [eq]
+ l:S = r:S == [l, r]
+ equation(l, r) == [l, r] -- hack! See comment above.
+ lhs eqn == eqn.lhs
+ rhs eqn == eqn.rhs
+ swap eqn == [rhs eqn, lhs eqn]
+ map(fn, eqn) == equation(fn(eqn.lhs), fn(eqn.rhs))
+
+ if S has InnerEvalable(Symbol,S) then
+ s:Symbol
+ ls:List Symbol
+ x:S
+ lx:List S
+ eval(eqn,s,x) == eval(eqn.lhs,s,x) = eval(eqn.rhs,s,x)
+ eval(eqn,ls,lx) == eval(eqn.lhs,ls,lx) = eval(eqn.rhs,ls,lx)
+ if S has Evalable(S) then
+ eval(eqn1:$, eqn2:$):$ ==
+ eval(eqn1.lhs, eqn2 pretend Equation S) =
+ eval(eqn1.rhs, eqn2 pretend Equation S)
+ eval(eqn1:$, leqn2:List $):$ ==
+ eval(eqn1.lhs, leqn2 pretend List Equation S) =
+ eval(eqn1.rhs, leqn2 pretend List Equation S)
+ if S has SetCategory then
+ eq1 = eq2 == (eq1.lhs = eq2.lhs)@Boolean and
+ (eq1.rhs = eq2.rhs)@Boolean
+ coerce(eqn:$):Ex == eqn.lhs::Ex = eqn.rhs::Ex
+ coerce(eqn:$):Boolean == eqn.lhs = eqn.rhs
+ if S has AbelianSemiGroup then
+ eq1 + eq2 == eq1.lhs + eq2.lhs = eq1.rhs + eq2.rhs
+ s + eq2 == [s,s] + eq2
+ eq1 + s == eq1 + [s,s]
+ if S has AbelianGroup then
+ - eq == (- lhs eq) = (-rhs eq)
+ s - eq2 == [s,s] - eq2
+ eq1 - s == eq1 - [s,s]
+ leftZero eq == 0 = rhs eq - lhs eq
+ rightZero eq == lhs eq - rhs eq = 0
+ 0 == equation(0$S,0$S)
+ eq1 - eq2 == eq1.lhs - eq2.lhs = eq1.rhs - eq2.rhs
+ if S has SemiGroup then
+ eq1:$ * eq2:$ == eq1.lhs * eq2.lhs = eq1.rhs * eq2.rhs
+ l:S * eqn:$ == l * eqn.lhs = l * eqn.rhs
+ l:S * eqn:$ == l * eqn.lhs = l * eqn.rhs
+ eqn:$ * l:S == eqn.lhs * l = eqn.rhs * l
+ -- We have to be a bit careful here: raising to a +ve integer is OK
+ -- (since it's the equivalent of repeated multiplication)
+ -- but other powers may cause contradictions
+ -- Watch what else you add here! JHD 2/Aug 1990
+ if S has Monoid then
+ 1 == equation(1$S,1$S)
+ recip eq ==
+ (lh := recip lhs eq) case "failed" => "failed"
+ (rh := recip rhs eq) case "failed" => "failed"
+ [lh :: S, rh :: S]
+ leftOne eq ==
+ (re := recip lhs eq) case "failed" => "failed"
+ 1 = rhs eq * re
+ rightOne eq ==
+ (re := recip rhs eq) case "failed" => "failed"
+ lhs eq * re = 1
+ if S has Group then
+ inv eq == [inv lhs eq, inv rhs eq]
+ leftOne eq == 1 = rhs eq * inv rhs eq
+ rightOne eq == lhs eq * inv rhs eq = 1
+ if S has Ring then
+ characteristic() == characteristic()$S
+ i:Integer * eq:$ == (i::S) * eq
+ if S has IntegralDomain then
+ factorAndSplit eq ==
+ (S has factor : S -> Factored S) =>
+ eq0 := rightZero eq
+ [equation(rcf.factor,0) for rcf in factors factor lhs eq0]
+ (S has Polynomial Integer) =>
+ eq0 := rightZero eq
+ MF ==> MultivariateFactorize(Symbol, IndexedExponents Symbol, _
+ Integer, Polynomial Integer)
+ p : Polynomial Integer := (lhs eq0) pretend Polynomial Integer
+ [equation((rcf.factor) pretend S,0) for rcf in factors factor(p)$MF]
+ [eq]
+ if S has PartialDifferentialRing(Symbol) then
+ differentiate(eq:$, sym:Symbol):$ ==
+ [differentiate(lhs eq, sym), differentiate(rhs eq, sym)]
+ if S has Field then
+ dimension() == 2 :: CardinalNumber
+ eq1:$ / eq2:$ == eq1.lhs / eq2.lhs = eq1.rhs / eq2.rhs
+ inv eq == [inv lhs eq, inv rhs eq]
+ if S has ExpressionSpace then
+ subst(eq1,eq2) ==
+ eq3 := eq2 pretend Equation S
+ [subst(lhs eq1,eq3),subst(rhs eq1,eq3)]
+
+@
+\section{package EQ2 EquationFunctions2}
+<<package EQ2 EquationFunctions2>>=
+)abbrev package EQ2 EquationFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains: Equation
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This package provides operations for mapping the sides of equations.
+EquationFunctions2(S: Type, R: Type): with
+ map: (S ->R ,Equation S) -> Equation R
+ ++ map(f,eq) returns an equation where f is applied to the sides of eq
+ == add
+ map(fn, eqn) == equation(fn lhs eqn, fn rhs eqn)
+
+@
+\section{category FEVALAB FullyEvalableOver}
+<<category FEVALAB FullyEvalableOver>>=
+)abbrev category FEVALAB FullyEvalableOver
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains: Equation
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This category provides a selection of evaluation operations
+++ depending on what the argument type R provides.
+FullyEvalableOver(R:SetCategory): Category == with
+ map: (R -> R, $) -> $
+ ++ map(f, ex) evaluates ex, applying f to values of type R in ex.
+ if R has Eltable(R, R) then Eltable(R, $)
+ if R has Evalable(R) then Evalable(R)
+ if R has InnerEvalable(Symbol, R) then InnerEvalable(Symbol, R)
+ add
+ if R has Eltable(R, R) then
+ elt(x:$, r:R) == map(#1.r, x)
+
+ if R has Evalable(R) then
+ eval(x:$, l:List Equation R) == map(eval(#1, l), x)
+
+ if R has InnerEvalable(Symbol, R) then
+ eval(x:$, ls:List Symbol, lv:List R) == map(eval(#1, ls, lv), x)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain EQ Equation>>
+<<package EQ2 EquationFunctions2>>
+<<category FEVALAB FullyEvalableOver>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/error.spad.pamphlet b/src/algebra/error.spad.pamphlet
new file mode 100644
index 00000000..4f3c828f
--- /dev/null
+++ b/src/algebra/error.spad.pamphlet
@@ -0,0 +1,139 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra error.spad}
+\author{Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ERROR ErrorFunctions}
+<<package ERROR ErrorFunctions>>=
+)abbrev package ERROR ErrorFunctions
+++ Author: Robert S. Sutor
+++ Date Created: 29 May 1990
+++ Date Last Updated: 29 May 1990
+++ Description:
+++ ErrorFunctions implements error functions callable from the system
+++ interpreter. Typically, these functions would be called in user
+++ functions. The simple forms of the functions take one argument
+++ which is either a string (an error message) or a list of strings
+++ which all together make up a message. The list can contain
+++ formatting codes (see below). The more sophisticated versions takes
+++ two arguments where the first argument is the name of the function
+++ from which the error was invoked and the second argument is either a
+++ string or a list of strings, as above. When you use the one
+++ argument version in an interpreter function, the system will
+++ automatically insert the name of the function as the new first
+++ argument. Thus in the user interpreter function
+++ \spad{f x == if x < 0 then error "negative argument" else x}
+++ the call to error will actually be of the form
+++ \spad{error("f","negative argument")}
+++ because the interpreter will have created a new first argument.
+++
+++ Formatting codes: error messages may contain the following
+++ formatting codes (they should either start or end a string or
+++ else have blanks around them):
+++ \spad{%l} start a new line
+++ \spad{%b} start printing in a bold font (where available)
+++ \spad{%d} stop printing in a bold font (where available)
+++ \spad{ %ceon} start centering message lines
+++ \spad{%ceoff} stop centering message lines
+++ \spad{%rjon} start displaying lines "ragged left"
+++ \spad{%rjoff} stop displaying lines "ragged left"
+++ \spad{%i} indent following lines 3 additional spaces
+++ \spad{%u} unindent following lines 3 additional spaces
+++ \spad{%xN} insert N blanks (eg, \spad{%x10} inserts 10 blanks)
+++
+++ Examples:
+++ 1. \spad{error "Whoops, you made a %l %ceon %b big %d %ceoff %l mistake!"}
+++ 2. \spad{error ["Whoops, you made a","%l %ceon %b","big",
+++ "%d %ceoff %l","mistake!"]}
+
+ErrorFunctions() : Exports == Implementation where
+ Exports ==> with
+ error: String -> Exit
+ ++ error(msg) displays error message msg and terminates.
+ error: List String -> Exit
+ ++ error(lmsg) displays error message lmsg and terminates.
+ error: (String,String) -> Exit
+ ++ error(nam,msg) displays error message msg preceded by a
+ ++ message containing the name nam of the function in which
+ ++ the error is contained.
+ error: (String,List String) -> Exit
+ ++ error(nam,lmsg) displays error messages lmsg preceded by a
+ ++ message containing the name nam of the function in which
+ ++ the error is contained.
+ Implementation ==> add
+
+ prefix1 : String := "Error signalled from user code: %l "
+ prefix2 : String := "Error signalled from user code in function %b "
+
+ doit(s : String) : Exit ==
+ throwPatternMsg(s,nil$(List String))$Lisp
+ -- there are no objects of type Exit, so we'll fake one,
+ -- knowing we will never get to this step anyway.
+ "exit" pretend Exit
+
+ error(s : String) : Exit ==
+ doit concat [prefix1,s]
+
+ error(l : List String) : Exit ==
+ s : String := prefix1
+ for x in l repeat s := concat [s," ",x]
+ doit s
+
+ error(fn : String,s : String) : Exit ==
+ doit concat [prefix2,fn,": %d %l ",s]
+
+ error(fn : String, l : List String) : Exit ==
+ s : String := concat [prefix2,fn,": %d %l"]
+ for x in l repeat s := concat [s," ",x]
+ doit s
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ERROR ErrorFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/expexpan.spad.pamphlet b/src/algebra/expexpan.spad.pamphlet
new file mode 100644
index 00000000..30e4877b
--- /dev/null
+++ b/src/algebra/expexpan.spad.pamphlet
@@ -0,0 +1,555 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra expexpan.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain EXPUPXS ExponentialOfUnivariatePuiseuxSeries}
+<<domain EXPUPXS ExponentialOfUnivariatePuiseuxSeries>>=
+)abbrev domain EXPUPXS ExponentialOfUnivariatePuiseuxSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 4 August 1992
+++ Date Last Updated: 27 August 1992
+++ Basic Operations:
+++ Related Domains: UnivariatePuiseuxSeries(FE,var,cen)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: limit, functional expression, power series, essential singularity
+++ Examples:
+++ References:
+++ Description:
+++ ExponentialOfUnivariatePuiseuxSeries is a domain used to represent
+++ essential singularities of functions. An object in this domain is a
+++ function of the form \spad{exp(f(x))}, where \spad{f(x)} is a Puiseux
+++ series with no terms of non-negative degree. Objects are ordered
+++ according to order of singularity, with functions which tend more
+++ rapidly to zero or infinity considered to be larger. Thus, if
+++ \spad{order(f(x)) < order(g(x))}, i.e. the first non-zero term of
+++ \spad{f(x)} has lower degree than the first non-zero term of \spad{g(x)},
+++ then \spad{exp(f(x)) > exp(g(x))}. If \spad{order(f(x)) = order(g(x))},
+++ then the ordering is essentially random. This domain is used
+++ in computing limits involving functions with essential singularities.
+ExponentialOfUnivariatePuiseuxSeries(FE,var,cen):_
+ Exports == Implementation where
+ FE : Join(Field,OrderedSet)
+ var : Symbol
+ cen : FE
+ UPXS ==> UnivariatePuiseuxSeries(FE,var,cen)
+
+ Exports ==> Join(UnivariatePuiseuxSeriesCategory(FE),OrderedAbelianMonoid) _
+ with
+ exponential : UPXS -> %
+ ++ exponential(f(x)) returns \spad{exp(f(x))}.
+ ++ Note: the function does NOT check that \spad{f(x)} has no
+ ++ non-negative terms.
+ exponent : % -> UPXS
+ ++ exponent(exp(f(x))) returns \spad{f(x)}
+ exponentialOrder: % -> Fraction Integer
+ ++ exponentialOrder(exp(c * x **(-n) + ...)) returns \spad{-n}.
+ ++ exponentialOrder(0) returns \spad{0}.
+
+ Implementation ==> UPXS add
+
+ Rep := UPXS
+
+ exponential f == complete f
+ exponent f == f pretend UPXS
+ exponentialOrder f == order(exponent f,0)
+
+ zero? f == empty? entries complete terms f
+
+ f = g ==
+ -- we redefine equality because we know that we are dealing with
+ -- a FINITE series, so there is no danger in computing all terms
+ (entries complete terms f) = (entries complete terms g)
+
+ f < g ==
+ zero? f => not zero? g
+ zero? g => false
+ (ordf := exponentialOrder f) > (ordg := exponentialOrder g) => true
+ ordf < ordg => false
+ (fCoef := coefficient(f,ordf)) = (gCoef := coefficient(g,ordg)) =>
+ reductum(f) < reductum(g)
+ fCoef < gCoef -- this is "random" if FE is EXPR INT
+
+ coerce(f:%):OutputForm ==
+ ("%e" :: OutputForm) ** ((coerce$Rep)(complete f)@OutputForm)
+
+@
+\section{domain UPXSSING UnivariatePuiseuxSeriesWithExponentialSingularity}
+<<domain UPXSSING UnivariatePuiseuxSeriesWithExponentialSingularity>>=
+)abbrev domain UPXSSING UnivariatePuiseuxSeriesWithExponentialSingularity
+++ Author: Clifton J. Williamson
+++ Date Created: 4 August 1992
+++ Date Last Updated: 27 August 1992
+++ Basic Operations:
+++ Related Domains: UnivariatePuiseuxSeries(FE,var,cen),
+++ ExponentialOfUnivariatePuiseuxSeries(FE,var,cen)
+++ ExponentialExpansion(R,FE,var,cen)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: limit, functional expression, power series
+++ Examples:
+++ References:
+++ Description:
+++ UnivariatePuiseuxSeriesWithExponentialSingularity is a domain used to
+++ represent functions with essential singularities. Objects in this
+++ domain are sums, where each term in the sum is a univariate Puiseux
+++ series times the exponential of a univariate Puiseux series. Thus,
+++ the elements of this domain are sums of expressions of the form
+++ \spad{g(x) * exp(f(x))}, where g(x) is a univariate Puiseux series
+++ and f(x) is a univariate Puiseux series with no terms of non-negative
+++ degree.
+UnivariatePuiseuxSeriesWithExponentialSingularity(R,FE,var,cen):_
+ Exports == Implementation where
+ R : Join(OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer,GcdDomain)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+ var : Symbol
+ cen : FE
+ B ==> Boolean
+ I ==> Integer
+ L ==> List
+ RN ==> Fraction Integer
+ UPXS ==> UnivariatePuiseuxSeries(FE,var,cen)
+ EXPUPXS ==> ExponentialOfUnivariatePuiseuxSeries(FE,var,cen)
+ OFE ==> OrderedCompletion FE
+ Result ==> Union(OFE,"failed")
+ PxRec ==> Record(k: Fraction Integer,c:FE)
+ Term ==> Record(%coef:UPXS,%expon:EXPUPXS,%expTerms:List PxRec)
+ -- the %expTerms field is used to record the list of the terms (a 'term'
+ -- records an exponent and a coefficient) in the exponent %expon
+ TypedTerm ==> Record(%term:Term,%type:String)
+ -- a term together with a String which tells whether it has an infinite,
+ -- zero, or unknown limit as var -> cen+
+ TRec ==> Record(%zeroTerms: List Term,_
+ %infiniteTerms: List Term,_
+ %failedTerms: List Term,_
+ %puiseuxSeries: UPXS)
+ SIGNEF ==> ElementaryFunctionSign(R,FE)
+
+ Exports ==> Join(FiniteAbelianMonoidRing(UPXS,EXPUPXS),IntegralDomain) with
+ limitPlus : % -> Union(OFE,"failed")
+ ++ limitPlus(f(var)) returns \spad{limit(var -> cen+,f(var))}.
+ dominantTerm : % -> Union(TypedTerm,"failed")
+ ++ dominantTerm(f(var)) returns the term that dominates the limiting
+ ++ behavior of \spad{f(var)} as \spad{var -> cen+} together with a
+ ++ \spadtype{String} which briefly describes that behavior. The
+ ++ value of the \spadtype{String} will be \spad{"zero"} (resp.
+ ++ \spad{"infinity"}) if the term tends to zero (resp. infinity)
+ ++ exponentially and will \spad{"series"} if the term is a
+ ++ Puiseux series.
+
+ Implementation ==> PolynomialRing(UPXS,EXPUPXS) add
+ makeTerm : (UPXS,EXPUPXS) -> Term
+ coeff : Term -> UPXS
+ exponent : Term -> EXPUPXS
+ exponentTerms : Term -> List PxRec
+ setExponentTerms_! : (Term,List PxRec) -> List PxRec
+ computeExponentTerms_! : Term -> List PxRec
+ terms : % -> List Term
+ sortAndDiscardTerms: List Term -> TRec
+ termsWithExtremeLeadingCoef : (L Term,RN,I) -> Union(L Term,"failed")
+ filterByOrder: (L Term,(RN,RN) -> B) -> Record(%list:L Term,%order:RN)
+ dominantTermOnList : (L Term,RN,I) -> Union(Term,"failed")
+ iDominantTerm : L Term -> Union(Record(%term:Term,%type:String),"failed")
+
+ retractIfCan f ==
+ (numberOfMonomials f = 1) and (zero? degree f) => leadingCoefficient f
+ "failed"
+
+ recip f ==
+ numberOfMonomials f = 1 =>
+ monomial(inv leadingCoefficient f,- degree f)
+ "failed"
+
+ makeTerm(coef,expon) == [coef,expon,empty()]
+ coeff term == term.%coef
+ exponent term == term.%expon
+ exponentTerms term == term.%expTerms
+ setExponentTerms_!(term,list) == term.%expTerms := list
+ computeExponentTerms_! term ==
+ setExponentTerms_!(term,entries complete terms exponent term)
+
+ terms f ==
+ -- terms with a higher order singularity will appear closer to the
+ -- beginning of the list because of the ordering in EXPPUPXS;
+ -- no "expnonent terms" are computed by this function
+ zero? f => empty()
+ concat(makeTerm(leadingCoefficient f,degree f),terms reductum f)
+
+ sortAndDiscardTerms termList ==
+ -- 'termList' is the list of terms of some function f(var), ordered
+ -- so that terms with a higher order singularity occur at the
+ -- beginning of the list.
+ -- This function returns lists of candidates for the "dominant
+ -- term" in 'termList', i.e. the term which describes the
+ -- asymptotic behavior of f(var) as var -> cen+.
+ -- 'zeroTerms' will contain terms which tend to zero exponentially
+ -- and contains only those terms with the lowest order singularity.
+ -- 'zeroTerms' will be non-empty only when there are no terms of
+ -- infinite or series type.
+ -- 'infiniteTerms' will contain terms which tend to infinity
+ -- exponentially and contains only those terms with the highest
+ -- order singularity.
+ -- 'failedTerms' will contain terms which have an exponential
+ -- singularity, where we cannot say whether the limiting value
+ -- is zero or infinity. Only terms with a higher order sigularity
+ -- than the terms on 'infiniteList' are included.
+ -- 'pSeries' will be a Puiseux series representing a term without an
+ -- exponential singularity. 'pSeries' will be non-zero only when no
+ -- other terms are known to tend to infinity exponentially
+ zeroTerms : List Term := empty()
+ infiniteTerms : List Term := empty()
+ failedTerms : List Term := empty()
+ -- we keep track of whether or not we've found an infinite term
+ -- if so, 'infTermOrd' will be set to a negative value
+ infTermOrd : RN := 0
+ -- we keep track of whether or not we've found a zero term
+ -- if so, 'zeroTermOrd' will be set to a negative value
+ zeroTermOrd : RN := 0
+ ord : RN := 0; pSeries : UPXS := 0 -- dummy values
+ while not empty? termList repeat
+ -- 'expon' is a Puiseux series
+ expon := exponent(term := first termList)
+ -- quit if there is an infinite term with a higher order singularity
+ (ord := order(expon,0)) > infTermOrd => leave "infinite term dominates"
+ -- if ord = 0, we've hit the end of the list
+ (ord = 0) =>
+ -- since we have a series term, don't bother with zero terms
+ leave(pSeries := coeff(term); zeroTerms := empty())
+ coef := coefficient(expon,ord)
+ -- if we can't tell if the lowest order coefficient is positive or
+ -- negative, we have a "failed term"
+ (signum := sign(coef)$SIGNEF) case "failed" =>
+ failedTerms := concat(term,failedTerms)
+ termList := rest termList
+ -- if the lowest order coefficient is positive, we have an
+ -- "infinite term"
+ (sig := signum :: Integer) = 1 =>
+ infTermOrd := ord
+ infiniteTerms := concat(term,infiniteTerms)
+ -- since we have an infinite term, don't bother with zero terms
+ zeroTerms := empty()
+ termList := rest termList
+ -- if the lowest order coefficient is negative, we have a
+ -- "zero term" if there are no infinite terms and no failed
+ -- terms, add the term to 'zeroTerms'
+ if empty? infiniteTerms then
+ zeroTerms :=
+ ord = zeroTermOrd => concat(term,zeroTerms)
+ zeroTermOrd := ord
+ list term
+ termList := rest termList
+ -- reverse "failed terms" so that higher order singularities
+ -- appear at the beginning of the list
+ [zeroTerms,infiniteTerms,reverse_! failedTerms,pSeries]
+
+ termsWithExtremeLeadingCoef(termList,ord,signum) ==
+ -- 'termList' consists of terms of the form [g(x),exp(f(x)),...];
+ -- when 'signum' is +1 (resp. -1), this function filters 'termList'
+ -- leaving only those terms such that coefficient(f(x),ord) is
+ -- maximal (resp. minimal)
+ while (coefficient(exponent first termList,ord) = 0) repeat
+ termList := rest termList
+ empty? termList => error "UPXSSING: can't happen"
+ coefExtreme := coefficient(exponent first termList,ord)
+ outList := list first termList; termList := rest termList
+ for term in termList repeat
+ (coefDiff := coefficient(exponent term,ord) - coefExtreme) = 0 =>
+ outList := concat(term,outList)
+ (sig := sign(coefDiff)$SIGNEF) case "failed" => return "failed"
+ (sig :: Integer) = signum => outList := list term
+ outList
+
+ filterByOrder(termList,predicate) ==
+ -- 'termList' consists of terms of the form [g(x),exp(f(x)),expTerms],
+ -- where 'expTerms' is a list containing some of the terms in the
+ -- series f(x).
+ -- The function filters 'termList' and, when 'predicate' is < (resp. >),
+ -- leaves only those terms with the lowest (resp. highest) order term
+ -- in 'expTerms'
+ while empty? exponentTerms first termList repeat
+ termList := rest termList
+ empty? termList => error "UPXSING: can't happen"
+ ordExtreme := (first exponentTerms first termList).k
+ outList := list first termList
+ for term in rest termList repeat
+ not empty? exponentTerms term =>
+ (ord := (first exponentTerms term).k) = ordExtreme =>
+ outList := concat(term,outList)
+ predicate(ord,ordExtreme) =>
+ ordExtreme := ord
+ outList := list term
+ -- advance pointers on "exponent terms" on terms on 'outList'
+ for term in outList repeat
+ setExponentTerms_!(term,rest exponentTerms term)
+ [outList,ordExtreme]
+
+ dominantTermOnList(termList,ord0,signum) ==
+ -- finds dominant term on 'termList'
+ -- it is known that "exponent terms" of order < 'ord0' are
+ -- the same for all terms on 'termList'
+ newList := termsWithExtremeLeadingCoef(termList,ord0,signum)
+ newList case "failed" => "failed"
+ termList := newList :: List Term
+ empty? rest termList => first termList
+ filtered :=
+ signum = 1 => filterByOrder(termList,#1 < #2)
+ filterByOrder(termList,#1 > #2)
+ termList := filtered.%list
+ empty? rest termList => first termList
+ dominantTermOnList(termList,filtered.%order,signum)
+
+ iDominantTerm termList ==
+ termRecord := sortAndDiscardTerms termList
+ zeroTerms := termRecord.%zeroTerms
+ infiniteTerms := termRecord.%infiniteTerms
+ failedTerms := termRecord.%failedTerms
+ pSeries := termRecord.%puiseuxSeries
+ -- in future versions, we will deal with "failed terms"
+ -- at present, if any occur, we cannot determine the limit
+ not empty? failedTerms => "failed"
+ not zero? pSeries => [makeTerm(pSeries,0),"series"]
+ not empty? infiniteTerms =>
+ empty? rest infiniteTerms => [first infiniteTerms,"infinity"]
+ for term in infiniteTerms repeat computeExponentTerms_! term
+ ord0 := order exponent first infiniteTerms
+ (dTerm := dominantTermOnList(infiniteTerms,ord0,1)) case "failed" =>
+ return "failed"
+ [dTerm :: Term,"infinity"]
+ empty? rest zeroTerms => [first zeroTerms,"zero"]
+ for term in zeroTerms repeat computeExponentTerms_! term
+ ord0 := order exponent first zeroTerms
+ (dTerm := dominantTermOnList(zeroTerms,ord0,-1)) case "failed" =>
+ return "failed"
+ [dTerm :: Term,"zero"]
+
+ dominantTerm f == iDominantTerm terms f
+
+ limitPlus f ==
+ -- list the terms occurring in 'f'; if there are none, then f = 0
+ empty?(termList := terms f) => 0
+ -- compute dominant term
+ (tInfo := iDominantTerm termList) case "failed" => "failed"
+ termInfo := tInfo :: Record(%term:Term,%type:String)
+ domTerm := termInfo.%term
+ (type := termInfo.%type) = "series" =>
+ -- find limit of series term
+ (ord := order(pSeries := coeff domTerm,1)) > 0 => 0
+ coef := coefficient(pSeries,ord)
+ member?(var,variables coef) => "failed"
+ ord = 0 => coef :: OFE
+ -- in the case of an infinite limit, we need to know the sign
+ -- of the first non-zero coefficient
+ (signum := sign(coef)$SIGNEF) case "failed" => "failed"
+ (signum :: Integer) = 1 => plusInfinity()
+ minusInfinity()
+ type = "zero" => 0
+ -- examine lowest order coefficient in series part of 'domTerm'
+ ord := order(pSeries := coeff domTerm)
+ coef := coefficient(pSeries,ord)
+ member?(var,variables coef) => "failed"
+ (signum := sign(coef)$SIGNEF) case "failed" => "failed"
+ (signum :: Integer) = 1 => plusInfinity()
+ minusInfinity()
+
+@
+\section{domain EXPEXPAN ExponentialExpansion}
+<<domain EXPEXPAN ExponentialExpansion>>=
+)abbrev domain EXPEXPAN ExponentialExpansion
+++ Author: Clifton J. Williamson
+++ Date Created: 13 August 1992
+++ Date Last Updated: 27 August 1992
+++ Basic Operations:
+++ Related Domains: UnivariatePuiseuxSeries(FE,var,cen),
+++ ExponentialOfUnivariatePuiseuxSeries(FE,var,cen)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: limit, functional expression, power series
+++ Examples:
+++ References:
+++ Description:
+++ UnivariatePuiseuxSeriesWithExponentialSingularity is a domain used to
+++ represent essential singularities of functions. Objects in this domain
+++ are quotients of sums, where each term in the sum is a univariate Puiseux
+++ series times the exponential of a univariate Puiseux series.
+ExponentialExpansion(R,FE,var,cen): Exports == Implementation where
+ R : Join(OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer,GcdDomain)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+ var : Symbol
+ cen : FE
+ RN ==> Fraction Integer
+ UPXS ==> UnivariatePuiseuxSeries(FE,var,cen)
+ EXPUPXS ==> ExponentialOfUnivariatePuiseuxSeries(FE,var,cen)
+ UPXSSING ==> UnivariatePuiseuxSeriesWithExponentialSingularity(R,FE,var,cen)
+ OFE ==> OrderedCompletion FE
+ Result ==> Union(OFE,"failed")
+ PxRec ==> Record(k: Fraction Integer,c:FE)
+ Term ==> Record(%coef:UPXS,%expon:EXPUPXS,%expTerms:List PxRec)
+ TypedTerm ==> Record(%term:Term,%type:String)
+ SIGNEF ==> ElementaryFunctionSign(R,FE)
+
+ Exports ==> Join(QuotientFieldCategory UPXSSING,RetractableTo UPXS) with
+ limitPlus : % -> Union(OFE,"failed")
+ ++ limitPlus(f(var)) returns \spad{limit(var -> a+,f(var))}.
+ coerce: UPXS -> %
+ ++ coerce(f) converts a \spadtype{UnivariatePuiseuxSeries} to
+ ++ an \spadtype{ExponentialExpansion}.
+
+ Implementation ==> Fraction(UPXSSING) add
+ coeff : Term -> UPXS
+ exponent : Term -> EXPUPXS
+ upxssingIfCan : % -> Union(UPXSSING,"failed")
+ seriesQuotientLimit: (UPXS,UPXS) -> Union(OFE,"failed")
+ seriesQuotientInfinity: (UPXS,UPXS) -> Union(OFE,"failed")
+
+ Rep := Fraction UPXSSING
+
+ ZEROCOUNT : RN := 1000/1
+
+ coeff term == term.%coef
+ exponent term == term.%expon
+
+ --!! why is this necessary?
+ --!! code can run forever in retractIfCan if original assignment
+ --!! for 'ff' is used
+ upxssingIfCan f ==
+-- one? denom f => numer f
+ (denom f = 1) => numer f
+ "failed"
+
+ retractIfCan(f:%):Union(UPXS,"failed") ==
+ --ff := (retractIfCan$Rep)(f)@Union(UPXSSING,"failed")
+ --ff case "failed" => "failed"
+ (ff := upxssingIfCan f) case "failed" => "failed"
+ (fff := retractIfCan(ff::UPXSSING)@Union(UPXS,"failed")) case "failed" =>
+ "failed"
+ fff :: UPXS
+
+ f:UPXSSING / g:UPXSSING ==
+ (rec := recip g) case "failed" => f /$Rep g
+ f * (rec :: UPXSSING) :: %
+
+ f:% / g:% ==
+ (rec := recip numer g) case "failed" => f /$Rep g
+ (rec :: UPXSSING) * (denom g) * f
+
+ coerce(f:UPXS) == f :: UPXSSING :: %
+
+ seriesQuotientLimit(num,den) ==
+ -- limit of the quotient of two series
+ series := num / den
+ (ord := order(series,1)) > 0 => 0
+ coef := coefficient(series,ord)
+ member?(var,variables coef) => "failed"
+ ord = 0 => coef :: OFE
+ (sig := sign(coef)$SIGNEF) case "failed" => return "failed"
+ (sig :: Integer) = 1 => plusInfinity()
+ minusInfinity()
+
+ seriesQuotientInfinity(num,den) ==
+ -- infinite limit: plus or minus?
+ -- look at leading coefficients of series to tell
+ (numOrd := order(num,ZEROCOUNT)) = ZEROCOUNT => "failed"
+ (denOrd := order(den,ZEROCOUNT)) = ZEROCOUNT => "failed"
+ cc := coefficient(num,numOrd)/coefficient(den,denOrd)
+ member?(var,variables cc) => "failed"
+ (sig := sign(cc)$SIGNEF) case "failed" => return "failed"
+ (sig :: Integer) = 1 => plusInfinity()
+ minusInfinity()
+
+ limitPlus f ==
+ zero? f => 0
+ (den := denom f) = 1 => limitPlus numer f
+ (numerTerm := dominantTerm(num := numer f)) case "failed" => "failed"
+ numType := (numTerm := numerTerm :: TypedTerm).%type
+ (denomTerm := dominantTerm den) case "failed" => "failed"
+ denType := (denTerm := denomTerm :: TypedTerm).%type
+ numExpon := exponent numTerm.%term; denExpon := exponent denTerm.%term
+ numCoef := coeff numTerm.%term; denCoef := coeff denTerm.%term
+ -- numerator tends to zero exponentially
+ (numType = "zero") =>
+ -- denominator tends to zero exponentially
+ (denType = "zero") =>
+ (exponDiff := numExpon - denExpon) = 0 =>
+ seriesQuotientLimit(numCoef,denCoef)
+ expCoef := coefficient(exponDiff,order exponDiff)
+ (sig := sign(expCoef)$SIGNEF) case "failed" => return "failed"
+ (sig :: Integer) = -1 => 0
+ seriesQuotientInfinity(numCoef,denCoef)
+ 0 -- otherwise limit is zero
+ -- numerator is a Puiseux series
+ (numType = "series") =>
+ -- denominator tends to zero exponentially
+ (denType = "zero") =>
+ seriesQuotientInfinity(numCoef,denCoef)
+ -- denominator is a series
+ (denType = "series") => seriesQuotientLimit(numCoef,denCoef)
+ 0
+ -- remaining case: numerator tends to infinity exponentially
+ -- denominator tends to infinity exponentially
+ (denType = "infinity") =>
+ (exponDiff := numExpon - denExpon) = 0 =>
+ seriesQuotientLimit(numCoef,denCoef)
+ expCoef := coefficient(exponDiff,order exponDiff)
+ (sig := sign(expCoef)$SIGNEF) case "failed" => return "failed"
+ (sig :: Integer) = -1 => 0
+ seriesQuotientInfinity(numCoef,denCoef)
+ -- denominator tends to zero exponentially or is a series
+ seriesQuotientInfinity(numCoef,denCoef)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain EXPUPXS ExponentialOfUnivariatePuiseuxSeries>>
+<<domain UPXSSING UnivariatePuiseuxSeriesWithExponentialSingularity>>
+<<domain EXPEXPAN ExponentialExpansion>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/exposed.lsp.pamphlet b/src/algebra/exposed.lsp.pamphlet
new file mode 100644
index 00000000..498b79ab
--- /dev/null
+++ b/src/algebra/exposed.lsp.pamphlet
@@ -0,0 +1,1257 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra exposed.lsp}
+\author{Timothy Daly}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{License}
+<<license>>=
+;;Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+;;All rights reserved.
+;;
+;;Redistribution and use in source and binary forms, with or without
+;;modification, are permitted provided that the following conditions are
+;;met:
+;;
+;; - Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; - Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in
+;; the documentation and/or other materials provided with the
+;; distribution.
+;;
+;; - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+;; names of its contributors may be used to endorse or promote products
+;; derived from this software without specific prior written permission.
+;;
+;;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+;;IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+;;TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+;;PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+;;OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+;;EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+;;PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+;;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+;;LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+(in-package 'BOOT)
+(setq |$globalExposureGroupAlist|
+'(
+;;define the groups |basic| |naglink| |anna| |categories| |Hidden| |defaults|
+(|basic|
+ (|AlgebraicManipulations| . ALGMANIP)
+ (|AlgebraicNumber| . AN)
+ (|AlgFactor| . ALGFACT)
+ (|AlgebraicMultFact| . ALGMFACT)
+ (|AlgebraPackage| . ALGPKG)
+ (|AlgebraGivenByStructuralConstants| . ALGSC)
+ (|Any| . ANY)
+ (|AnyFunctions1| . ANY1)
+ (|ArrayStack| . ASTACK)
+ (|AssociatedJordanAlgebra| . JORDAN)
+ (|AssociatedLieAlgebra| . LIE)
+ (|AttachPredicates| . PMPRED)
+ (|BalancedBinaryTree| . BBTREE)
+ (|BasicOperator| . BOP)
+ (|BasicOperatorFunctions1| . BOP1)
+ (|BinaryExpansion| . BINARY)
+ (|BinaryFile| . BINFILE)
+ (|BinarySearchTree| . BSTREE)
+ (|BinaryTournament| . BTOURN)
+ (|BinaryTree| . BTREE)
+ (|Bits| . BITS)
+ (|Boolean| . BOOLEAN)
+ (|CardinalNumber| . CARD)
+ (|CartesianTensor| . CARTEN)
+ (|CartesianTensorFunctions2| . CARTEN2)
+ (|Character| . CHAR)
+ (|CharacterClass| . CCLASS)
+ (|CharacteristicPolynomialPackage| . CHARPOL)
+ (|CliffordAlgebra| . CLIF)
+ (|Color| . COLOR)
+ (|CommonDenominator| . CDEN)
+ (|Commutator| . COMM)
+ (|Complex| . COMPLEX)
+ (|ComplexFactorization| . COMPFACT)
+ (|ComplexFunctions2| . COMPLEX2)
+ (|ComplexRootPackage| . CMPLXRT)
+ (|ComplexTrigonometricManipulations| . CTRIGMNP)
+ (|ContinuedFraction| . CONTFRAC)
+ (|CoordinateSystems| . COORDSYS)
+ (|CRApackage| . CRAPACK)
+ (|CycleIndicators| . CYCLES)
+ (|Database| . DBASE)
+ (|DataList| . DLIST)
+ (|DecimalExpansion| . DECIMAL)
+ (|DenavitHartenbergMatrix| . DHMATRIX)
+ (|Dequeue| . DEQUEUE)
+ (|DiophantineSolutionPackage| . DIOSP)
+ (|DirectProductFunctions2| . DIRPROD2)
+ (|DisplayPackage| . DISPLAY)
+ (|DistinctDegreeFactorize| . DDFACT)
+ (|DoubleFloat| . DFLOAT)
+ (|DoubleFloatSpecialFunctions| . DFSFUN)
+ (|DrawComplex| . DRAWCX)
+ (|DrawNumericHack| . DRAWHACK)
+ (|DrawOption| . DROPT)
+ (|EigenPackage| . EP)
+ (|ElementaryFunctionDefiniteIntegration| . DEFINTEF)
+ (|ElementaryFunctionLODESolver| . LODEEF)
+ (|ElementaryFunctionODESolver| . ODEEF)
+ (|ElementaryFunctionSign| . SIGNEF)
+ (|ElementaryFunctionStructurePackage| . EFSTRUC)
+ (|Equation| . EQ)
+ (|EquationFunctions2| . EQ2)
+ (|ErrorFunctions| . ERROR)
+ (|EuclideanGroebnerBasisPackage| . GBEUCLID)
+ (|Exit| . EXIT)
+ (|Expression| . EXPR)
+ (|ExpressionFunctions2| . EXPR2)
+ (|ExpressionSpaceFunctions2| . ES2)
+ (|ExpressionSpaceODESolver| . EXPRODE)
+ (|ExpressionToOpenMath| . OMEXPR)
+ (|ExpressionToUnivariatePowerSeries| . EXPR2UPS)
+ (|Factored| . FR)
+ (|FactoredFunctions2| . FR2)
+ (|File| . FILE)
+ (|FileName| . FNAME)
+ (|FiniteDivisorFunctions2| . FDIV2)
+ (|FiniteField| . FF)
+ (|FiniteFieldCyclicGroup| . FFCG)
+ (|FiniteFieldPolynomialPackage2| . FFPOLY2)
+ (|FiniteFieldNormalBasis| . FFNB)
+ (|FiniteFieldHomomorphisms| . FFHOM)
+ (|FiniteLinearAggregateFunctions2| . FLAGG2)
+ (|FiniteLinearAggregateSort| . FLASORT)
+ (|FiniteSetAggregateFunctions2| . FSAGG2)
+ (|FlexibleArray| . FARRAY)
+ (|Float| . FLOAT)
+ (|FloatingRealPackage| . FLOATRP)
+ (|FloatingComplexPackage| . FLOATCP)
+ (|FourierSeries| . FSERIES)
+ (|Fraction| . FRAC)
+ (|FractionalIdealFunctions2| . FRIDEAL2)
+ (|FractionFunctions2| . FRAC2)
+ (|FreeNilpotentLie| . FNLA)
+ (|FullPartialFractionExpansion| . FPARFRAC)
+ (|FunctionFieldCategoryFunctions2| . FFCAT2)
+ (|FunctionSpaceAssertions| . PMASSFS)
+ (|FunctionSpaceAttachPredicates| . PMPREDFS)
+ (|FunctionSpaceComplexIntegration| . FSCINT)
+ (|FunctionSpaceFunctions2| . FS2)
+ (|FunctionSpaceIntegration| . FSINT)
+ (|FunctionSpacePrimitiveElement| . FSPRMELT)
+ (|FunctionSpaceSum| . SUMFS)
+ (|GaussianFactorizationPackage| . GAUSSFAC)
+ (|GeneralUnivariatePowerSeries| . GSERIES)
+ (|GenerateUnivariatePowerSeries| . GENUPS)
+ (|GraphicsDefaults| . GRDEF)
+ (|GroebnerPackage| . GB)
+ (|GroebnerFactorizationPackage| . GBF)
+ (|HallBasis| . HB)
+ (|Heap| . HEAP)
+ (|HexadecimalExpansion| . HEXADEC)
+ (|IndexCard| . ICARD)
+ (|IdealDecompositionPackage| . IDECOMP)
+ (|InfiniteProductCharacteristicZero| . INFPROD0)
+ (|InfiniteProductFiniteField| . INPRODFF)
+ (|InfiniteProductPrimeField| . INPRODPF)
+ (|InfiniteTuple| . ITUPLE)
+ (|InfiniteTupleFunctions2| . ITFUN2)
+ (|InfiniteTupleFunctions3| . ITFUN3)
+ (|Infinity| . INFINITY)
+ (|Integer| . INT)
+ (|IntegerCombinatoricFunctions| . COMBINAT)
+ (|IntegerLinearDependence| . ZLINDEP)
+ (|IntegerNumberTheoryFunctions| . INTHEORY)
+ (|IntegerPrimesPackage| . PRIMES)
+ (|IntegerRetractions| . INTRET)
+ (|IntegerRoots| . IROOT)
+ (|IntegrationResultFunctions2| . IR2)
+ (|IntegrationResultRFToFunction| . IRRF2F)
+ (|IntegrationResultToFunction| . IR2F)
+ (|Interval| . INTRVL)
+ (|InventorDataSink| . IVDATA)
+ (|InventorViewPort| . IVVIEW)
+ (|InventorRenderPackage| . IVREND)
+ (|InverseLaplaceTransform| . INVLAPLA)
+ (|IrrRepSymNatPackage| . IRSN)
+ (|KernelFunctions2| . KERNEL2)
+ (|KeyedAccessFile| . KAFILE)
+ (|LaplaceTransform| . LAPLACE)
+ (|LazardMorenoSolvingPackage| . LAZM3PK)
+ (|Library| . LIB)
+ (|LieSquareMatrix| . LSQM)
+ (|LinearOrdinaryDifferentialOperator| . LODO)
+ (|LinearSystemMatrixPackage| . LSMP)
+ (|LinearSystemMatrixPackage1| . LSMP1)
+ (|LinearSystemPolynomialPackage| . LSPP)
+ (|List| . LIST)
+ (|ListFunctions2| . LIST2)
+ (|ListFunctions3| . LIST3)
+ (|ListToMap| . LIST2MAP)
+ (|MakeFloatCompiledFunction| . MKFLCFN)
+ (|MakeFunction| . MKFUNC)
+ (|MakeRecord| . MKRECORD)
+ (|MappingPackage1| . MAPPKG1)
+ (|MappingPackage2| . MAPPKG2)
+ (|MappingPackage3| . MAPPKG3)
+ (|Matrix| . MATRIX)
+ (|MatrixCategoryFunctions2| . MATCAT2)
+ (|MatrixCommonDenominator| . MCDEN)
+ (|MatrixLinearAlgebraFunctions| . MATLIN)
+ (|MergeThing| . MTHING)
+ (|ModularDistinctDegreeFactorizer| . MDDFACT)
+ (|ModuleOperator| . MODOP)
+ (|MonoidRingFunctions2| . MRF2)
+ (|MoreSystemCommands| . MSYSCMD)
+ (|MPolyCatFunctions2| . MPC2)
+ (|MPolyCatRationalFunctionFactorizer| . MPRFF)
+ (|Multiset| . MSET)
+ (|MultivariateFactorize| . MULTFACT)
+ (|MultivariatePolynomial| . MPOLY)
+ (|MultFiniteFactorize| . MFINFACT)
+ (|NoneFunctions1| . NONE1)
+ (|NonNegativeInteger| . NNI)
+ (|NormalizationPackage| . NORMPK)
+ (|NormInMonogenicAlgebra| . NORMMA)
+ (|NumberTheoreticPolynomialFunctions| . NTPOLFN)
+ (|Numeric| . NUMERIC)
+ (|NumericalOrdinaryDifferentialEquations| . NUMODE)
+ (|NumericalQuadrature| . NUMQUAD)
+ (|NumericComplexEigenPackage| . NCEP)
+ (|NumericRealEigenPackage| . NREP)
+ (|NumericContinuedFraction| . NCNTFRAC)
+ (|Octonion| . OCT)
+ (|OctonionCategoryFunctions2| . OCTCT2)
+ (|OneDimensionalArray| . ARRAY1)
+ (|OneDimensionalArrayFunctions2| . ARRAY12)
+ (|OnePointCompletion| . ONECOMP)
+ (|OnePointCompletionFunctions2| . ONECOMP2)
+ (|OpenMathConnection| . OMCONN)
+ (|OpenMathDevice| . OMDEV)
+ (|OpenMathEncoding| . OMENC)
+ (|OpenMathError| . OMERR)
+ (|OpenMathErrorKind| . OMERRK)
+ (|OpenMathPackage| . OMPKG)
+ (|OpenMathServerPackage| . OMSERVER)
+ (|OperationsQuery| . OPQUERY)
+ (|OrderedCompletion| . ORDCOMP)
+ (|OrderedCompletionFunctions2| . ORDCOMP2)
+ (|OrdinaryDifferentialRing| . ODR)
+ (|OrdSetInts| . OSI)
+ (|OrthogonalPolynomialFunctions| . ORTHPOL)
+ (|OutputPackage| . OUT)
+ (|PadeApproximantPackage| . PADEPAC)
+ (|Palette| . PALETTE)
+ (|PartialFraction| . PFR)
+ (|PatternFunctions2| . PATTERN2)
+ (|ParametricPlaneCurve| . PARPCURV)
+ (|ParametricSpaceCurve| . PARSCURV)
+ (|ParametricSurface| . PARSURF)
+ (|ParametricPlaneCurveFunctions2| . PARPC2)
+ (|ParametricSpaceCurveFunctions2| . PARSC2)
+ (|ParametricSurfaceFunctions2| . PARSU2)
+ (|PartitionsAndPermutations| . PARTPERM)
+ (|PatternMatch| . PATMATCH)
+ (|PatternMatchAssertions| . PMASS)
+ (|PatternMatchResultFunctions2| . PATRES2)
+ (|PendantTree| . PENDTREE)
+ (|Permanent| . PERMAN)
+ (|PermutationGroupExamples| . PGE)
+ (|PermutationGroup| . PERMGRP)
+ (|Permutation| . PERM)
+ (|Pi| . HACKPI)
+ (|PiCoercions| . PICOERCE)
+ (|PointFunctions2| . PTFUNC2)
+ (|PolyGroebner| . PGROEB)
+ (|Polynomial| . POLY)
+ (|PolynomialAN2Expression| . PAN2EXPR)
+ (|PolynomialComposition| . PCOMP)
+ (|PolynomialDecomposition| . PDECOMP)
+ (|PolynomialFunctions2| . POLY2)
+ (|PolynomialIdeals| . IDEAL)
+ (|PolynomialToUnivariatePolynomial| . POLY2UP)
+ (|PositiveInteger| . PI)
+ (|PowerSeriesLimitPackage| . LIMITPS)
+ (|PrimeField| . PF)
+ (|PrimitiveArrayFunctions2| . PRIMARR2)
+ (|PrintPackage| . PRINT)
+ (|QuadraticForm| . QFORM)
+ (|QuasiComponentPackage| . QCMPACK)
+ (|Quaternion| . QUAT)
+ (|QuaternionCategoryFunctions2| . QUATCT2)
+ (|QueryEquation| . QEQUAT)
+ (|Queue| . QUEUE)
+ (|QuotientFieldCategoryFunctions2| . QFCAT2)
+ (|RadicalEigenPackage| . REP)
+ (|RadicalSolvePackage| . SOLVERAD)
+ (|RadixExpansion| . RADIX)
+ (|RadixUtilities| . RADUTIL)
+ (|RandomNumberSource| . RANDSRC)
+ (|RationalFunction| . RF)
+ (|RationalFunctionDefiniteIntegration| . DEFINTRF)
+ (|RationalFunctionFactor| . RFFACT)
+ (|RationalFunctionFactorizer| . RFFACTOR)
+ (|RationalFunctionIntegration| . INTRF)
+ (|RationalFunctionLimitPackage| . LIMITRF)
+ (|RationalFunctionSign| . SIGNRF)
+ (|RationalFunctionSum| . SUMRF)
+ (|RationalRetractions| . RATRET)
+ (|RealClosure| . RECLOS)
+ (|RealPolynomialUtilitiesPackage| . POLUTIL)
+ (|RealZeroPackage| . REAL0)
+ (|RealZeroPackageQ| . REAL0Q)
+ (|RectangularMatrixCategoryFunctions2| . RMCAT2)
+ (|RegularSetDecompositionPackage| . RSDCMPK)
+ (|RegularTriangularSet| . REGSET)
+ (|RegularTriangularSetGcdPackage| . RSETGCD)
+ (|RepresentationPackage1| . REP1)
+ (|RepresentationPackage2| . REP2)
+ (|ResolveLatticeCompletion| . RESLATC)
+ (|RewriteRule| . RULE)
+ (|RightOpenIntervalRootCharacterization| . ROIRC)
+ (|RomanNumeral| . ROMAN)
+ (|Ruleset| . RULESET)
+ (|ScriptFormulaFormat| . FORMULA)
+ (|ScriptFormulaFormat1| . FORMULA1)
+ (|Segment| . SEG)
+ (|SegmentBinding| . SEGBIND)
+ (|SegmentBindingFunctions2| . SEGBIND2)
+ (|SegmentFunctions2| . SEG2)
+ (|Set| . SET)
+ (|SimpleAlgebraicExtensionAlgFactor| . SAEFACT)
+ (|SimplifyAlgebraicNumberConvertPackage| . SIMPAN)
+ (|SingleInteger| . SINT)
+ (|SmithNormalForm| . SMITH)
+ (|SparseUnivariatePolynomialFunctions2| . SUP2)
+ (|SpecialOutputPackage| . SPECOUT)
+ (|SquareFreeRegularSetDecompositionPackage| . SRDCMPK)
+ (|SquareFreeRegularTriangularSet| . SREGSET)
+ (|SquareFreeRegularTriangularSetGcdPackage| . SFRGCD)
+ (|SquareFreeQuasiComponentPackage| . SFQCMPK)
+ (|Stack| . STACK)
+ (|Stream| . STREAM)
+ (|StreamFunctions1| . STREAM1)
+ (|StreamFunctions2| . STREAM2)
+ (|StreamFunctions3| . STREAM3)
+ (|String| . STRING)
+ (|SturmHabichtPackage| . SHP)
+ (|Symbol| . SYMBOL)
+ (|SymmetricGroupCombinatoricFunctions| . SGCF)
+ (|SystemSolvePackage| . SYSSOLP)
+ (|SAERationalFunctionAlgFactor| . SAERFFC)
+ (|Tableau| . TABLEAU)
+ (|TaylorSeries| . TS)
+ (|TexFormat| . TEX)
+ (|TexFormat1| . TEX1)
+ (|TextFile| . TEXTFILE)
+ (|ThreeDimensionalViewport| . VIEW3D)
+ (|ThreeSpace| . SPACE3)
+ (|Timer| . TIMER)
+ (|TopLevelDrawFunctions| . DRAW)
+ (|TopLevelDrawFunctionsForAlgebraicCurves| . DRAWCURV)
+ (|TopLevelDrawFunctionsForCompiledFunctions| . DRAWCFUN)
+ (|TopLevelDrawFunctionsForPoints| . DRAWPT )
+ (|TopLevelThreeSpace| . TOPSP)
+ (|TranscendentalManipulations| . TRMANIP)
+ (|TransSolvePackage| . SOLVETRA)
+ (|Tree| . TREE)
+ (|TrigonometricManipulations| . TRIGMNIP)
+ (|UnivariateLaurentSeriesFunctions2| . ULS2)
+ (|UnivariatePolynomial| . UP)
+ (|UnivariatePolynomialCategoryFunctions2| . UPOLYC2)
+ (|UnivariatePolynomialCommonDenominator| . UPCDEN)
+ (|UnivariatePolynomialFunctions2| . UP2)
+ (|UnivariatePolynomialMultiplicationPackage| . UPMP)
+ (|UnivariatePuiseuxSeriesFunctions2| . UPXS2)
+ (|UnivariateTaylorSeriesFunctions2| . UTS2)
+ (|UniversalSegment| . UNISEG)
+ (|UniversalSegmentFunctions2| . UNISEG2)
+ (|UserDefinedVariableOrdering| . UDVO)
+ (|Vector| . VECTOR)
+ (|VectorFunctions2| . VECTOR2)
+ (|ViewDefaultsPackage| . VIEWDEF)
+ (|Void| . VOID)
+ (|WuWenTsunTriangularSet| . WUTSET)
+)
+(|naglink|
+ (|Asp1| . ASP1)
+ (|Asp4| . ASP4)
+ (|Asp6| . ASP6)
+ (|Asp7| . ASP7)
+ (|Asp8| . ASP8)
+ (|Asp9| . ASP9)
+ (|Asp10| . ASP10)
+ (|Asp12| . ASP12)
+ (|Asp19| . ASP19)
+ (|Asp20| . ASP20)
+ (|Asp24| . ASP24)
+ (|Asp27| . ASP27)
+ (|Asp28| . ASP28)
+ (|Asp29| . ASP29)
+ (|Asp30| . ASP30)
+ (|Asp31| . ASP31)
+ (|Asp33| . ASP33)
+ (|Asp34| . ASP34)
+ (|Asp35| . ASP35)
+ (|Asp41| . ASP41)
+ (|Asp42| . ASP42)
+ (|Asp49| . ASP49)
+ (|Asp50| . ASP50)
+ (|Asp55| . ASP55)
+ (|Asp73| . ASP73)
+ (|Asp74| . ASP74)
+ (|Asp77| . ASP77)
+ (|Asp78| . ASP78)
+ (|Asp80| . ASP80)
+ (|FortranCode| . FC)
+ (|FortranCodePackage1| . FCPAK1)
+ (|FortranExpression| . FEXPR)
+ (|FortranMachineTypeCategory| . FMTC)
+ (|FortranMatrixCategory| . FMC)
+ (|FortranMatrixFunctionCategory| . FMFUN)
+ (|FortranOutputStackPackage| . FOP)
+ (|FortranPackage| . FORT)
+ (|FortranProgramCategory| . FORTCAT)
+ (|FortranProgram| . FORTRAN)
+ (|FortranFunctionCategory| . FORTFN)
+ (|FortranScalarType| . FST)
+ (|FortranType| . FT)
+ (|FortranTemplate| . FTEM)
+ (|FortranVectorFunctionCategory| . FVFUN)
+ (|FortranVectorCategory| . FVC)
+ (|MachineComplex| . MCMPLX)
+ (|MachineFloat| . MFLOAT)
+ (|MachineInteger| . MINT)
+ (|MultiVariableCalculusFunctions| . MCALCFN)
+ (|NagDiscreteFourierTransformInterfacePackage| . NAGDIS)
+ (|NagEigenInterfacePackage| . NAGEIG)
+ (|NAGLinkSupportPackage| . NAGSP)
+ (|NagOptimisationInterfacePackage| . NAGOPT)
+ (|NagQuadratureInterfacePackage| . NAGQUA)
+ (|NagResultChecks| . NAGRES)
+ (|NagSpecialFunctionsInterfacePackage| . NAGSPE)
+ (|NagPolynomialRootsPackage| . NAGC02)
+ (|NagRootFindingPackage| . NAGC05)
+ (|NagSeriesSummationPackage| . NAGC06)
+ (|NagIntegrationPackage| . NAGD01)
+ (|NagOrdinaryDifferentialEquationsPackage| . NAGD02)
+ (|NagPartialDifferentialEquationsPackage| . NAGD03)
+ (|NagInterpolationPackage| . NAGE01)
+ (|NagFittingPackage| . NAGE02)
+ (|NagOptimisationPackage| . NAGE04)
+ (|NagMatrixOperationsPackage| . NAGF01)
+ (|NagEigenPackage| . NAGF02)
+ (|NagLinearEquationSolvingPackage| . NAGF04)
+ (|NagLapack| . NAGF07)
+ (|NagSpecialFunctionsPackage| . NAGS)
+ (|PackedHermitianSequence| . PACKED)
+ (|Result| . RESULT)
+ (|SimpleFortranProgram| . SFORT)
+ (|Switch| . SWITCH)
+ (|SymbolTable| . SYMTAB)
+ (|TemplateUtilities| . TEMUTL)
+ (|TheSymbolTable| . SYMS)
+ (|ThreeDimensionalMatrix| . M3D))
+(|anna|
+ (|AnnaNumericalIntegrationPackage| . INTPACK)
+ (|AnnaNumericalOptimizationPackage| . OPTPACK)
+ (|AnnaOrdinaryDifferentialEquationPackage| . ODEPACK)
+ (|AnnaPartialDifferentialEquationPackage| . PDEPACK)
+ (|AttributeButtons| . ATTRBUT)
+ (|BasicFunctions| . BFUNCT)
+ (|d01ajfAnnaType| . D01AJFA)
+ (|d01akfAnnaType| . D01AKFA)
+ (|d01alfAnnaType| . D01ALFA)
+ (|d01amfAnnaType| . D01AMFA)
+ (|d01anfAnnaType| . D01ANFA)
+ (|d01apfAnnaType| . D01APFA)
+ (|d01aqfAnnaType| . D01AQFA)
+ (|d01asfAnnaType| . D01ASFA)
+ (|d01fcfAnnaType| . D01FCFA)
+ (|d01gbfAnnaType| . D01GBFA)
+ (|d01AgentsPackage| . D01AGNT)
+ (|d01TransformFunctionType| . D01TRNS)
+ (|d01WeightsPackage| . D01WGTS)
+ (|d02AgentsPackage| . D02AGNT)
+ (|d02bbfAnnaType| . D02BBFA)
+ (|d02bhfAnnaType| . D02BHFA)
+ (|d02cjfAnnaType| . D02CJFA)
+ (|d02ejfAnnaType| . D02EJFA)
+ (|d03AgentsPackage| . D03AGNT)
+ (|d03eefAnnaType| . D03EEFA)
+ (|d03fafAnnaType| . D03FAFA)
+ (|e04AgentsPackage| . E04AGNT)
+ (|e04dgfAnnaType| . E04DGFA)
+ (|e04fdfAnnaType| . E04FDFA)
+ (|e04gcfAnnaType| . E04GCFA)
+ (|e04jafAnnaType| . E04JAFA)
+ (|e04mbfAnnaType| . E04MBFA)
+ (|e04nafAnnaType| . E04NAFA)
+ (|e04ucfAnnaType| . E04UCFA)
+ (|ExpertSystemContinuityPackage| . ESCONT)
+ (|ExpertSystemContinuityPackage1| . ESCONT1)
+ (|ExpertSystemToolsPackage| . ESTOOLS)
+ (|ExpertSystemToolsPackage1| . ESTOOLS1)
+ (|ExpertSystemToolsPackage2| . ESTOOLS2)
+ (|NumericalIntegrationCategory| . NUMINT)
+ (|NumericalIntegrationProblem| . NIPROB)
+ (|NumericalODEProblem| . ODEPROB)
+ (|NumericalOptimizationCategory| . OPTCAT)
+ (|NumericalOptimizationProblem| . OPTPROB)
+ (|NumericalPDEProblem| . PDEPROB)
+ (|ODEIntensityFunctionsTable| . ODEIFTBL)
+ (|IntegrationFunctionsTable| . INTFTBL)
+ (|OrdinaryDifferentialEquationsSolverCategory| . ODECAT)
+ (|PartialDifferentialEquationsSolverCategory| . PDECAT)
+ (|RoutinesTable| . ROUTINE))
+(|categories|
+ (|AbelianGroup| . ABELGRP)
+ (|AbelianMonoid| . ABELMON)
+ (|AbelianMonoidRing| . AMR)
+ (|AbelianSemiGroup| . ABELSG)
+ (|Aggregate| . AGG)
+ (|Algebra| . ALGEBRA)
+ (|AlgebraicallyClosedField| . ACF)
+ (|AlgebraicallyClosedFunctionSpace| . ACFS)
+ (|ArcHyperbolicFunctionCategory| . AHYP)
+ (|ArcTrigonometricFunctionCategory| . ATRIG)
+ (|AssociationListAggregate| . ALAGG)
+ (|AttributeRegistry| . ATTREG)
+ (|BagAggregate| . BGAGG)
+ (|BasicType| . BASTYPE)
+ (|BiModule| . BMODULE)
+ (|BinaryRecursiveAggregate| . BRAGG)
+ (|BinaryTreeCategory| . BTCAT)
+ (|BitAggregate| . BTAGG)
+ (|CachableSet| . CACHSET)
+ (|CancellationAbelianMonoid| . CABMON)
+ (|CharacteristicNonZero| . CHARNZ)
+ (|CharacteristicZero| . CHARZ)
+ (|CoercibleTo| . KOERCE)
+ (|Collection| . CLAGG)
+ (|CombinatorialFunctionCategory| . CFCAT)
+ (|CombinatorialOpsCategory| . COMBOPC)
+ (|CommutativeRing| . COMRING)
+ (|ComplexCategory| . COMPCAT)
+ (|ConvertibleTo| . KONVERT)
+ (|DequeueAggregate| . DQAGG)
+ (|Dictionary| . DIAGG)
+ (|DictionaryOperations| . DIOPS)
+ (|DifferentialExtension| . DIFEXT)
+ (|DifferentialPolynomialCategory| . DPOLCAT)
+ (|DifferentialRing| . DIFRING)
+ (|DifferentialVariableCategory| . DVARCAT)
+ (|DirectProductCategory| . DIRPCAT)
+ (|DivisionRing| . DIVRING)
+ (|DoublyLinkedAggregate| . DLAGG)
+ (|ElementaryFunctionCategory| . ELEMFUN)
+ (|Eltable| . ELTAB)
+ (|EltableAggregate| . ELTAGG)
+ (|EntireRing| . ENTIRER)
+ (|EuclideanDomain| . EUCDOM)
+ (|Evalable| . EVALAB)
+ (|ExpressionSpace| . ES)
+ (|ExtensibleLinearAggregate| . ELAGG)
+ (|ExtensionField| . XF)
+ (|Field| . FIELD)
+ (|FieldOfPrimeCharacteristic| . FPC)
+ (|Finite| . FINITE)
+ (|FileCategory| . FILECAT)
+ (|FileNameCategory| . FNCAT)
+ (|FiniteAbelianMonoidRing| . FAMR)
+ (|FiniteAlgebraicExtensionField| . FAXF)
+ (|FiniteDivisorCategory| . FDIVCAT)
+ (|FiniteFieldCategory| . FFIELDC)
+ (|FiniteLinearAggregate| . FLAGG)
+ (|FiniteRankNonAssociativeAlgebra| . FINAALG)
+ (|FiniteRankAlgebra| . FINRALG)
+ (|FiniteSetAggregate| . FSAGG)
+ (|FloatingPointSystem| . FPS)
+ (|FramedAlgebra| . FRAMALG)
+ (|FramedNonAssociativeAlgebra| . FRNAALG)
+ (|FramedNonAssociativeAlgebraFunctions2| . FRNAAF2)
+ (|FreeAbelianMonoidCategory| . FAMONC)
+ (|FreeLieAlgebra| . FLALG)
+ (|FreeModuleCat| . FMCAT)
+ (|FullyEvalableOver| . FEVALAB)
+ (|FullyLinearlyExplicitRingOver| . FLINEXP)
+ (|FullyPatternMatchable| . FPATMAB)
+ (|FullyRetractableTo| . FRETRCT)
+ (|FunctionFieldCategory| . FFCAT)
+ (|FunctionSpace| . FS)
+ (|GcdDomain| . GCDDOM)
+ (|GradedAlgebra| . GRALG)
+ (|GradedModule| . GRMOD)
+ (|Group| . GROUP)
+ (|HomogeneousAggregate| . HOAGG)
+ (|HyperbolicFunctionCategory| . HYPCAT)
+ (|IndexedAggregate| . IXAGG)
+ (|IndexedDirectProductCategory| . IDPC)
+ (|InnerEvalable| . IEVALAB)
+ (|IntegerNumberSystem| . INS)
+ (|IntegralDomain| . INTDOM)
+ (|IntervalCategory| . INTCAT)
+ (|KeyedDictionary| . KDAGG)
+ (|LazyStreamAggregate| . LZSTAGG)
+ (|LeftAlgebra| . LALG)
+ (|LeftModule| . LMODULE)
+ (|LieAlgebra| . LIECAT)
+ (|LinearAggregate| . LNAGG)
+ (|LinearlyExplicitRingOver| . LINEXP)
+ (|LinearOrdinaryDifferentialOperatorCategory| . LODOCAT)
+ (|LiouvillianFunctionCategory| . LFCAT)
+ (|ListAggregate| . LSAGG)
+ (|Logic| . LOGIC)
+ (|MatrixCategory| . MATCAT)
+ (|Module| . MODULE)
+ (|Monad| . MONAD)
+ (|MonadWithUnit| . MONADWU)
+ (|Monoid| . MONOID)
+ (|MonogenicAlgebra| . MONOGEN)
+ (|MonogenicLinearOperator| . MLO)
+ (|MultiDictionary| . MDAGG)
+ (|MultisetAggregate| . MSETAGG)
+ (|MultivariateTaylorSeriesCategory| . MTSCAT)
+ (|NonAssociativeAlgebra| . NAALG)
+ (|NonAssociativeRing| . NASRING)
+ (|NonAssociativeRng| . NARNG)
+ (|NormalizedTriangularSetCategory| . NTSCAT)
+ (|Object| . OBJECT)
+ (|OctonionCategory| . OC)
+ (|OneDimensionalArrayAggregate| . A1AGG)
+ (|OpenMath| . OM)
+ (|OrderedAbelianGroup| . OAGROUP)
+ (|OrderedAbelianMonoid| . OAMON)
+ (|OrderedAbelianMonoidSup| . OAMONS)
+ (|OrderedAbelianSemiGroup| . OASGP)
+ (|OrderedCancellationAbelianMonoid| . OCAMON)
+ (|OrderedFinite| . ORDFIN)
+ (|OrderedIntegralDomain| . OINTDOM)
+ (|OrderedMonoid| . ORDMON)
+ (|OrderedMultisetAggregate| . OMSAGG)
+ (|OrderedRing| . ORDRING)
+ (|OrderedSet| . ORDSET)
+ (|PAdicIntegerCategory| . PADICCT)
+ (|PartialDifferentialRing| . PDRING)
+ (|PartialTranscendentalFunctions| . PTRANFN)
+ (|Patternable| . PATAB)
+ (|PatternMatchable| . PATMAB)
+ (|PermutationCategory| . PERMCAT)
+ (|PlottablePlaneCurveCategory| . PPCURVE)
+ (|PlottableSpaceCurveCategory| . PSCURVE)
+ (|PointCategory| . PTCAT)
+ (|PolynomialCategory| . POLYCAT)
+ (|PolynomialFactorizationExplicit| . PFECAT)
+ (|PolynomialSetCategory| . PSETCAT)
+ (|PowerSeriesCategory| . PSCAT)
+ (|PrimitiveFunctionCategory| . PRIMCAT)
+ (|PrincipalIdealDomain| . PID)
+ (|PriorityQueueAggregate| . PRQAGG)
+ (|QuaternionCategory| . QUATCAT)
+ (|QueueAggregate| . QUAGG)
+ (|QuotientFieldCategory| . QFCAT)
+ (|RadicalCategory| . RADCAT)
+ (|RealClosedField| . RCFIELD)
+ (|RealConstant| . REAL)
+ (|RealNumberSystem| . RNS)
+ (|RealRootCharacterizationCategory| . RRCC)
+ (|RectangularMatrixCategory| . RMATCAT)
+ (|RecursiveAggregate| . RCAGG)
+ (|RecursivePolynomialCategory| . RPOLCAT)
+ (|RegularChain| . RGCHAIN)
+ (|RegularTriangularSetCategory| . RSETCAT)
+ (|RetractableTo| . RETRACT)
+ (|RightModule| . RMODULE)
+ (|Ring| . RING)
+ (|Rng| . RNG)
+ (|SegmentCategory| . SEGCAT)
+ (|SegmentExpansionCategory| . SEGXCAT)
+ (|SemiGroup| . SGROUP)
+ (|SetAggregate| . SETAGG)
+ (|SetCategory| . SETCAT)
+ (|SExpressionCategory| . SEXCAT)
+ (|SpecialFunctionCategory| . SPFCAT)
+ (|SquareFreeNormalizedTriangularSetCategory| . SNTSCAT)
+ (|SquareFreeRegularTriangularSetCategory| . SFRTCAT)
+ (|SquareMatrixCategory| . SMATCAT)
+ (|StackAggregate| . SKAGG)
+ (|StepThrough| . STEP)
+ (|StreamAggregate| . STAGG)
+ (|StringAggregate| . SRAGG)
+ (|StringCategory| . STRICAT)
+ (|StructuralConstantsPackage| . SCPKG)
+ (|TableAggregate| . TBAGG)
+ (|ThreeSpaceCategory| . SPACEC)
+ (|TranscendentalFunctionCategory| . TRANFUN)
+ (|TriangularSetCategory| . TSETCAT)
+ (|TrigonometricFunctionCategory| . TRIGCAT)
+ (|TwoDimensionalArrayCategory| . ARR2CAT)
+ (|Type| . TYPE)
+ (|UnaryRecursiveAggregate| . URAGG)
+ (|UniqueFactorizationDomain| . UFD)
+ (|UnivariateLaurentSeriesCategory| . ULSCAT)
+ (|UnivariateLaurentSeriesConstructorCategory| . ULSCCAT)
+ (|UnivariatePolynomialCategory| . UPOLYC)
+ (|UnivariatePowerSeriesCategory| . UPSCAT)
+ (|UnivariatePuiseuxSeriesCategory| . UPXSCAT)
+ (|UnivariatePuiseuxSeriesConstructorCategory| . UPXSCCA)
+ (|UnivariateSkewPolynomialCategory| . OREPCAT)
+ (|UnivariateTaylorSeriesCategory| . UTSCAT)
+ (|VectorCategory| . VECTCAT)
+ (|VectorSpace| . VSPACE)
+ (|XAlgebra| . XALG)
+ (|XFreeAlgebra| . XFALG)
+ (|XPolynomialsCat| . XPOLYC)
+ (|ZeroDimensionalSolvePackage| . ZDSOLVE))
+(|Hidden|
+ (|AlgebraicFunction| . AF)
+ (|AlgebraicFunctionField| . ALGFF)
+ (|AlgebraicHermiteIntegration| . INTHERAL)
+ (|AlgebraicIntegrate| . INTALG)
+ (|AlgebraicIntegration| . INTAF)
+ (|AnonymousFunction| . ANON)
+ (|AntiSymm| . ANTISYM)
+ (|ApplyRules| . APPRULE)
+ (|ApplyUnivariateSkewPolynomial| . APPLYORE)
+ (|ArrayStack| . ASTACK)
+ (|AssociatedEquations| . ASSOCEQ)
+ (|AssociationList| . ALIST)
+ (|Automorphism| . AUTOMOR)
+ (|BalancedFactorisation| . BALFACT)
+ (|BalancedPAdicInteger| . BPADIC)
+ (|BalancedPAdicRational| . BPADICRT)
+ (|BezoutMatrix| . BEZOUT)
+ (|BoundIntegerRoots| . BOUNDZRO)
+ (|BrillhartTests| . BRILL)
+ (|ChangeOfVariable| . CHVAR)
+ (|CharacteristicPolynomialInMonogenicalAlgebra| . CPIMA)
+ (|ChineseRemainderToolsForIntegralBases| . IBACHIN)
+ (|CoerceVectorMatrixPackage| . CVMP)
+ (|CombinatorialFunction| . COMBF)
+ (|CommonOperators| . COMMONOP)
+ (|CommuteUnivariatePolynomialCategory| . COMMUPC)
+ (|ComplexIntegerSolveLinearPolynomialEquation| . CINTSLPE)
+ (|ComplexPattern| . COMPLPAT)
+ (|ComplexPatternMatch| . CPMATCH)
+ (|ComplexRootFindingPackage| . CRFP)
+ (|ConstantLODE| . ODECONST)
+ (|CyclicStreamTools| . CSTTOOLS)
+ (|CyclotomicPolynomialPackage| . CYCLOTOM)
+ (|DefiniteIntegrationTools| . DFINTTLS)
+ (|DegreeReductionPackage| . DEGRED)
+ (|DeRhamComplex| . DERHAM)
+ (|DifferentialSparseMultivariatePolynomial| . DSMP)
+ (|DirectProduct| . DIRPROD)
+ (|DirectProductMatrixModule| . DPMM)
+ (|DirectProductModule| . DPMO)
+ (|DiscreteLogarithmPackage| . DLP)
+ (|DistributedMultivariatePolynomial| . DMP)
+ (|DoubleResultantPackage| . DBLRESP)
+ (|DrawOptionFunctions0| . DROPT0)
+ (|DrawOptionFunctions1| . DROPT1)
+ (|ElementaryFunction| . EF)
+ (|ElementaryFunctionsUnivariateLaurentSeries| . EFULS)
+ (|ElementaryFunctionsUnivariatePuiseuxSeries| . EFUPXS)
+ (|ElementaryIntegration| . INTEF)
+ (|ElementaryRischDE| . RDEEF)
+ (|ElementaryRischDESystem| . RDEEFS)
+ (|EllipticFunctionsUnivariateTaylorSeries| . ELFUTS)
+ (|EqTable| . EQTBL)
+ (|EuclideanModularRing| . EMR)
+ (|EvaluateCycleIndicators| . EVALCYC)
+ (|ExponentialExpansion| . EXPEXPAN)
+ (|ExponentialOfUnivariatePuiseuxSeries| . EXPUPXS)
+ (|ExpressionSpaceFunctions1| . ES1)
+ (|ExpressionTubePlot| . EXPRTUBE)
+ (|ExtAlgBasis| . EAB)
+ (|FactoredFunctions| . FACTFUNC)
+ (|FactoredFunctionUtilities| . FRUTIL)
+ (|FactoringUtilities| . FACUTIL)
+ (|FGLMIfCanPackage| . FGLMICPK)
+ (|FindOrderFinite| . FORDER)
+ (|FiniteDivisor| . FDIV)
+ (|FiniteFieldCyclicGroupExtension| . FFCGX)
+ (|FiniteFieldCyclicGroupExtensionByPolynomial| . FFCGP)
+ (|FiniteFieldExtension| . FFX)
+ (|FiniteFieldExtensionByPolynomial| . FFP)
+ (|FiniteFieldFunctions| . FFF)
+ (|FiniteFieldNormalBasisExtension| . FFNBX)
+ (|FiniteFieldNormalBasisExtensionByPolynomial| . FFNBP)
+ (|FiniteFieldPolynomialPackage| . FFPOLY)
+ (|FiniteFieldSolveLinearPolynomialEquation| . FFSLPE)
+ (|FormalFraction| . FORMAL)
+ (|FourierComponent| . FCOMP)
+ (|FractionalIdeal| . FRIDEAL)
+ (|FramedModule| . FRMOD)
+ (|FreeAbelianGroup| . FAGROUP)
+ (|FreeAbelianMonoid| . FAMONOID)
+ (|FreeGroup| . FGROUP)
+ (|FreeModule| . FM)
+ (|FreeModule1| . FM1)
+ (|FreeMonoid| . FMONOID)
+ (|FunctionalSpecialFunction| . FSPECF)
+ (|FunctionCalled| . FUNCTION)
+ (|FunctionFieldIntegralBasis| . FFINTBAS)
+ (|FunctionSpaceReduce| . FSRED)
+ (|FunctionSpaceToUnivariatePowerSeries| . FS2UPS)
+ (|FunctionSpaceToExponentialExpansion| . FS2EXPXP)
+ (|FunctionSpaceUnivariatePolynomialFactor| . FSUPFACT)
+ (|GaloisGroupFactorizationUtilities| . GALFACTU)
+ (|GaloisGroupFactorizer| . GALFACT)
+ (|GaloisGroupPolynomialUtilities| . GALPOLYU)
+ (|GaloisGroupUtilities| . GALUTIL)
+ (|GeneralHenselPackage| . GHENSEL)
+ (|GeneralDistributedMultivariatePolynomial| . GDMP)
+ (|GeneralPolynomialGcdPackage| . GENPGCD)
+ (|GeneralSparseTable| . GSTBL)
+ (|GenericNonAssociativeAlgebra| . GCNAALG)
+ (|GenExEuclid| . GENEEZ)
+ (|GeneralizedMultivariateFactorize| . GENMFACT)
+ (|GeneralModulePolynomial| . GMODPOL)
+ (|GeneralPolynomialSet| . GPOLSET)
+ (|GeneralTriangularSet| . GTSET)
+ (|GenUFactorize| . GENUFACT)
+ (|GenusZeroIntegration| . INTG0)
+ (|GosperSummationMethod| . GOSPER)
+ (|GraphImage| . GRIMAGE)
+ (|GrayCode| . GRAY)
+ (|GroebnerInternalPackage| . GBINTERN)
+ (|GroebnerSolve| . GROEBSOL)
+ (|HashTable| . HASHTBL)
+ (|Heap| . HEAP)
+ (|HeuGcd| . HEUGCD)
+ (|HomogeneousDistributedMultivariatePolynomial| . HDMP)
+ (|HyperellipticFiniteDivisor| . HELLFDIV)
+ (|IncrementingMaps| . INCRMAPS)
+ (|IndexedBits| . IBITS)
+ (|IndexedDirectProductAbelianGroup| . IDPAG)
+ (|IndexedDirectProductAbelianMonoid| . IDPAM)
+ (|IndexedDirectProductObject| . IDPO)
+ (|IndexedDirectProductOrderedAbelianMonoid| . IDPOAM)
+ (|IndexedDirectProductOrderedAbelianMonoidSup| . IDPOAMS)
+ (|IndexedExponents| . INDE)
+ (|IndexedFlexibleArray| . IFARRAY)
+ (|IndexedList| . ILIST)
+ (|IndexedMatrix| . IMATRIX)
+ (|IndexedOneDimensionalArray| . IARRAY1)
+ (|IndexedString| . ISTRING)
+ (|IndexedTwoDimensionalArray| . IARRAY2)
+ (|IndexedVector| . IVECTOR)
+ (|InnerAlgFactor| . IALGFACT)
+ (|InnerAlgebraicNumber| . IAN)
+ (|InnerCommonDenominator| . ICDEN)
+ (|InnerFiniteField| . IFF)
+ (|InnerFreeAbelianMonoid| . IFAMON)
+ (|InnerIndexedTwoDimensionalArray| . IIARRAY2)
+ (|InnerMatrixLinearAlgebraFunctions| . IMATLIN)
+ (|InnerMatrixQuotientFieldFunctions| . IMATQF)
+ (|InnerModularGcd| . INMODGCD)
+ (|InnerMultFact| . INNMFACT)
+ (|InnerNormalBasisFieldFunctions| . INBFF)
+ (|InnerNumericEigenPackage| . INEP)
+ (|InnerNumericFloatSolvePackage| . INFSP)
+ (|InnerPAdicInteger| . IPADIC)
+ (|InnerPolySign| . INPSIGN)
+ (|InnerPolySum| . ISUMP)
+ (|InnerPrimeField| . IPF)
+ (|InnerSparseUnivariatePowerSeries| . ISUPS)
+ (|InnerTable| . INTABL)
+ (|InnerTaylorSeries| . ITAYLOR)
+ (|InnerTrigonometricManipulations| . ITRIGMNP)
+ (|InputForm| . INFORM)
+ (|InputFormFunctions1| . INFORM1)
+ (|IntegerBits| . INTBIT)
+ (|IntegerFactorizationPackage| . INTFACT)
+ (|IntegerMod| . ZMOD)
+ (|IntegerSolveLinearPolynomialEquation| . INTSLPE)
+ (|IntegralBasisPolynomialTools| . IBPTOOLS)
+ (|IntegralBasisTools| . IBATOOL)
+ (|IntegrationResult| . IR)
+ (|IntegrationTools| . INTTOOLS)
+ (|InternalPrintPackage| . IPRNTPK)
+ (|InternalRationalUnivariateRepresentationPackage| . IRURPK)
+ (|IrredPolyOverFiniteField| . IRREDFFX)
+ (|Kernel| . KERNEL)
+ (|Kovacic| . KOVACIC)
+ (|LaurentPolynomial| . LAUPOL)
+ (|LeadingCoefDetermination| . LEADCDET)
+ (|LexTriangularPackage| . LEXTRIPK)
+ (|LieExponentials| . LEXP)
+ (|LiePolynomial| . LPOLY)
+ (|LinearDependence| . LINDEP)
+ (|LinearOrdinaryDifferentialOperatorFactorizer| . LODOF)
+ (|LinearOrdinaryDifferentialOperator1| . LODO1)
+ (|LinearOrdinaryDifferentialOperator2| . LODO2)
+ (|LinearOrdinaryDifferentialOperatorsOps| . LODOOPS)
+ (|LinearPolynomialEquationByFractions| . LPEFRAC)
+ (|LinGroebnerPackage| . LGROBP)
+ (|LiouvillianFunction| . LF)
+ (|ListMonoidOps| . LMOPS)
+ (|ListMultiDictionary| . LMDICT)
+ (|LocalAlgebra| . LA)
+ (|Localize| . LO)
+ (|LyndonWord| . LWORD)
+ (|Magma| . MAGMA)
+ (|MakeBinaryCompiledFunction| . MKBCFUNC)
+ (|MakeCachableSet| . MKCHSET)
+ (|MakeUnaryCompiledFunction| . MKUCFUNC)
+ (|MappingPackageInternalHacks1| . MAPHACK1)
+ (|MappingPackageInternalHacks2| . MAPHACK2)
+ (|MappingPackageInternalHacks3| . MAPHACK3)
+ (|MeshCreationRoutinesForThreeDimensions| . MESH)
+ (|ModMonic| . MODMON)
+ (|ModularField| . MODFIELD)
+ (|ModularHermitianRowReduction| . MHROWRED)
+ (|ModularRing| . MODRING)
+ (|ModuleMonomial| . MODMONOM)
+ (|MoebiusTransform| . MOEBIUS)
+ (|MonoidRing| . MRING)
+ (|MonomialExtensionTools| . MONOTOOL)
+ (|MPolyCatPolyFactorizer| . MPCPF)
+ (|MPolyCatFunctions3| . MPC3)
+ (|MRationalFactorize| . MRATFAC)
+ (|MultipleMap| . MMAP)
+ (|MultivariateLifting| . MLIFT)
+ (|MultivariateSquareFree| . MULTSQFR)
+ (|HomogeneousDirectProduct| . HDP)
+ (|NewSparseMultivariatePolynomial| . NSMP)
+ (|NewSparseUnivariatePolynomial| . NSUP)
+ (|NewSparseUnivariatePolynomialFunctions2| . NSUP2)
+ (|NonCommutativeOperatorDivision| . NCODIV)
+ (|None| . NONE)
+ (|NonLinearFirstOrderODESolver| . NODE1)
+ (|NonLinearSolvePackage| . NLINSOL)
+ (|NormRetractPackage| . NORMRETR)
+ (|NPCoef| . NPCOEF)
+ (|NumberFormats| . NUMFMT)
+ (|NumberFieldIntegralBasis| . NFINTBAS)
+ (|NumericTubePlot| . NUMTUBE)
+ (|ODEIntegration| . ODEINT)
+ (|ODETools| . ODETOOLS)
+ (|Operator| . OP)
+ (|OppositeMonogenicLinearOperator| . OMLO)
+ (|OrderedDirectProduct| . ODP)
+ (|OrderedFreeMonoid| . OFMONOID)
+ (|OrderedVariableList| . OVAR)
+ (|OrderingFunctions| . ORDFUNS)
+ (|OrderlyDifferentialPolynomial| . ODPOL)
+ (|OrderlyDifferentialVariable| . ODVAR)
+ (|OrdinaryWeightedPolynomials| . OWP)
+ (|OutputForm| . OUTFORM)
+ (|PadeApproximants| . PADE)
+ (|PAdicInteger| . PADIC)
+ (|PAdicRational| . PADICRAT)
+ (|PAdicRationalConstructor| . PADICRC)
+ (|PAdicWildFunctionFieldIntegralBasis| . PWFFINTB)
+ (|ParadoxicalCombinatorsForStreams| . YSTREAM)
+ (|ParametricLinearEquations| . PLEQN)
+ (|PartialFractionPackage| . PFRPAC)
+ (|Partition| . PRTITION)
+ (|Pattern| . PATTERN)
+ (|PatternFunctions1| . PATTERN1)
+ (|PatternMatchFunctionSpace| . PMFS)
+ (|PatternMatchIntegerNumberSystem| . PMINS)
+ (|PatternMatchIntegration| . INTPM)
+ (|PatternMatchKernel| . PMKERNEL)
+ (|PatternMatchListAggregate| . PMLSAGG)
+ (|PatternMatchListResult| . PATLRES)
+ (|PatternMatchPolynomialCategory| . PMPLCAT)
+ (|PatternMatchPushDown| . PMDOWN)
+ (|PatternMatchQuotientFieldCategory| . PMQFCAT)
+ (|PatternMatchResult| . PATRES)
+ (|PatternMatchSymbol| . PMSYM)
+ (|PatternMatchTools| . PMTOOLS)
+ (|PlaneAlgebraicCurvePlot| . ACPLOT)
+ (|Plot| . PLOT)
+ (|PlotFunctions1| . PLOT1)
+ (|PlotTools| . PLOTTOOL)
+ (|Plot3D| . PLOT3D)
+ (|PoincareBirkhoffWittLyndonBasis| . PBWLB)
+ (|Point| . POINT)
+ (|PointsOfFiniteOrder| . PFO)
+ (|PointsOfFiniteOrderRational| . PFOQ)
+ (|PointsOfFiniteOrderTools| . PFOTOOLS)
+ (|PointPackage| . PTPACK)
+ (|PolToPol| . POLTOPOL)
+ (|PolynomialCategoryLifting| . POLYLIFT)
+ (|PolynomialCategoryQuotientFunctions| . POLYCATQ)
+ (|PolynomialFactorizationByRecursion| . PFBR)
+ (|PolynomialFactorizationByRecursionUnivariate| . PFBRU)
+ (|PolynomialGcdPackage| . PGCD)
+ (|PolynomialInterpolation| . PINTERP)
+ (|PolynomialInterpolationAlgorithms| . PINTERPA)
+ (|PolynomialNumberTheoryFunctions| . PNTHEORY)
+ (|PolynomialRing| . PR)
+ (|PolynomialRoots| . POLYROOT)
+ (|PolynomialSetUtilitiesPackage| . PSETPK)
+ (|PolynomialSolveByFormulas| . SOLVEFOR)
+ (|PolynomialSquareFree| . PSQFR)
+ (|PrecomputedAssociatedEquations| . PREASSOC)
+ (|PrimitiveArray| . PRIMARR)
+ (|PrimitiveElement| . PRIMELT)
+ (|PrimitiveRatDE| . ODEPRIM)
+ (|PrimitiveRatRicDE| . ODEPRRIC)
+ (|Product| . PRODUCT)
+ (|PseudoRemainderSequence| . PRS)
+ (|PseudoLinearNormalForm| . PSEUDLIN)
+ (|PureAlgebraicIntegration| . INTPAF)
+ (|PureAlgebraicLODE| . ODEPAL)
+ (|PushVariables| . PUSHVAR)
+ (|QuasiAlgebraicSet| . QALGSET)
+ (|QuasiAlgebraicSet2| . QALGSET2)
+ (|RadicalFunctionField| . RADFF)
+ (|RandomDistributions| . RDIST)
+ (|RandomFloatDistributions| . RFDIST)
+ (|RandomIntegerDistributions| . RIDIST)
+ (|RationalFactorize| . RATFACT)
+ (|RationalIntegration| . INTRAT)
+ (|RationalInterpolation| . RINTERP)
+ (|RationalLODE| . ODERAT)
+ (|RationalRicDE| . ODERTRIC)
+ (|RationalUnivariateRepresentationPackage| . RURPK)
+ (|RealSolvePackage| . REALSOLV)
+ (|RectangularMatrix| . RMATRIX)
+ (|ReducedDivisor| . RDIV)
+ (|ReduceLODE| . ODERED)
+ (|ReductionOfOrder| . REDORDER)
+ (|Reference| . REF)
+ (|RepeatedDoubling| . REPDB)
+ (|RepeatedSquaring| . REPSQ)
+ (|ResidueRing| . RESRING)
+ (|RetractSolvePackage| . RETSOL)
+ (|RuleCalled| . RULECOLD)
+ (|SetOfMIntegersInOneToN| . SETMN)
+ (|SExpression| . SEX)
+ (|SExpressionOf| . SEXOF)
+ (|SequentialDifferentialPolynomial| . SDPOL)
+ (|SequentialDifferentialVariable| . SDVAR)
+ (|SimpleAlgebraicExtension| . SAE)
+ (|SingletonAsOrderedSet| . SAOS)
+ (|SortedCache| . SCACHE)
+ (|SortPackage| . SORTPAK)
+ (|SparseMultivariatePolynomial| . SMP)
+ (|SparseMultivariateTaylorSeries| . SMTS)
+ (|SparseTable| . STBL)
+ (|SparseUnivariatePolynomial| . SUP)
+ (|SparseUnivariateSkewPolynomial| . ORESUP)
+ (|SparseUnivariateLaurentSeries| . SULS)
+ (|SparseUnivariatePuiseuxSeries| . SUPXS)
+ (|SparseUnivariateTaylorSeries| . SUTS)
+ (|SplitHomogeneousDirectProduct| . SHDP)
+ (|SplittingNode| . SPLNODE)
+ (|SplittingTree| . SPLTREE)
+ (|SquareMatrix| . SQMATRIX)
+ (|Stack| . STACK)
+ (|StorageEfficientMatrixOperations| . MATSTOR)
+ (|StreamInfiniteProduct| . STINPROD)
+ (|StreamTaylorSeriesOperations| . STTAYLOR)
+ (|StreamTranscendentalFunctions| . STTF)
+ (|StreamTranscendentalFunctionsNonCommutative| . STTFNC)
+ (|StringTable| . STRTBL)
+ (|SubResultantPackage| . SUBRESP)
+ (|SubSpace| . SUBSPACE)
+ (|SubSpaceComponentProperty| . COMPPROP)
+ (|SuchThat| . SUCH)
+ (|SupFractionFactorizer| . SUPFRACF)
+ (|SymmetricFunctions| . SYMFUNC)
+ (|SymmetricPolynomial| . SYMPOLY)
+ (|SystemODESolver| . ODESYS)
+ (|Table| . TABLE)
+ (|TableauxBumpers| . TABLBUMP)
+ (|TabulatedComputationPackage| . TBCMPPK)
+ (|TangentExpansions| . TANEXP)
+ (|ToolsForSign| . TOOLSIGN)
+ (|TranscendentalHermiteIntegration| . INTHERTR)
+ (|TranscendentalIntegration| . INTTR)
+ (|TranscendentalRischDE| . RDETR)
+ (|TranscendentalRischDESystem| . RDETRS)
+ (|TransSolvePackageService| . SOLVESER)
+ (|TriangularMatrixOperations| . TRIMAT)
+ (|TubePlot| . TUBE)
+ (|TubePlotTools| . TUBETOOL)
+ (|Tuple| . TUPLE)
+ (|TwoDimensionalArray| . ARRAY2)
+ (|TwoDimensionalPlotClipping| . CLIP)
+ (|TwoDimensionalViewport| . VIEW2D)
+ (|TwoFactorize| . TWOFACT)
+ (|UnivariateFactorize| . UNIFACT)
+ (|UnivariateLaurentSeries| . ULS)
+ (|UnivariateLaurentSeriesConstructor| . ULSCONS)
+ (|UnivariatePolynomialDecompositionPackage| . UPDECOMP)
+ (|UnivariatePolynomialDivisionPackage| . UPDIVP)
+ (|UnivariatePolynomialSquareFree| . UPSQFREE)
+ (|UnivariatePuiseuxSeries| . UPXS)
+ (|UnivariatePuiseuxSeriesConstructor| . UPXSCONS)
+ (|UnivariatePuiseuxSeriesWithExponentialSingularity| . UPXSSING)
+ (|UnivariateSkewPolynomial| . OREUP)
+ (|UnivariateSkewPolynomialCategoryOps| . OREPCTO)
+ (|UnivariateTaylorSeries| . UTS)
+ (|UnivariateTaylorSeriesODESolver| . UTSODE)
+ (|UserDefinedPartialOrdering| . UDPO)
+ (|UTSodetools| . UTSODETL)
+ (|Variable| . VARIABLE)
+ (|ViewportPackage| . VIEW)
+ (|WeierstrassPreparation| . WEIER)
+ (|WeightedPolynomials| . WP)
+ (|WildFunctionFieldIntegralBasis| . WFFINTBS)
+ (|XDistributedPolynomial| . XDPOLY)
+ (|XExponentialPackage| . XEXPPKG)
+ (|XPBWPolynomial| . XPBWPOLY)
+ (|XPolynomial| . XPOLY)
+ (|XPolynomialRing| . XPR)
+ (|XRecursivePolynomial| . XRPOLY))
+(|defaults|
+ (|AbelianGroup&| . ABELGRP-)
+ (|AbelianMonoid&| . ABELMON-)
+ (|AbelianMonoidRing&| . AMR-)
+ (|AbelianSemiGroup&| . ABELSG-)
+ (|Aggregate&| . AGG-)
+ (|Algebra&| . ALGEBRA-)
+ (|AlgebraicallyClosedField&| . ACF-)
+ (|AlgebraicallyClosedFunctionSpace&| . ACFS-)
+ (|ArcTrigonometricFunctionCategory&| . ATRIG-)
+ (|BagAggregate&| . BGAGG-)
+ (|BasicType&| . BASTYPE-)
+ (|BinaryRecursiveAggregate&| . BRAGG-)
+ (|BinaryTreeCategory&| . BTCAT-)
+ (|BitAggregate&| . BTAGG-)
+ (|Collection&| . CLAGG-)
+ (|ComplexCategory&| . COMPCAT-)
+ (|Dictionary&| . DIAGG-)
+ (|DictionaryOperations&| . DIOPS-)
+ (|DifferentialExtension&| . DIFEXT-)
+ (|DifferentialPolynomialCategory&| . DPOLCAT-)
+ (|DifferentialRing&| . DIFRING-)
+ (|DifferentialVariableCategory&| . DVARCAT-)
+ (|DirectProductCategory&| . DIRPCAT-)
+ (|DivisionRing&| . DIVRING-)
+ (|ElementaryFunctionCategory&| . ELEMFUN-)
+ (|EltableAggregate&| . ELTAGG-)
+ (|EuclideanDomain&| . EUCDOM-)
+ (|Evalable&| . EVALAB-)
+ (|ExpressionSpace&| . ES-)
+ (|ExtensibleLinearAggregate&| . ELAGG-)
+ (|ExtensionField&| . XF-)
+ (|Field&| . FIELD-)
+ (|FieldOfPrimeCharacteristic&| . FPC-)
+ (|FiniteAbelianMonoidRing&| . FAMR-)
+ (|FiniteAlgebraicExtensionField&| . FAXF-)
+ (|FiniteDivisorCategory&| . FDIVCAT-)
+ (|FiniteFieldCategory&| . FFIELDC-)
+ (|FiniteLinearAggregate&| . FLAGG-)
+ (|FiniteSetAggregate&| . FSAGG-)
+ (|FiniteRankAlgebra&| . FINRALG-)
+ (|FiniteRankNonAssociativeAlgebra&| . FINAALG-)
+ (|FloatingPointSystem&| . FPS-)
+ (|FramedAlgebra&| . FRAMALG-)
+ (|FramedNonAssociativeAlgebra&| . FRNAALG-)
+ (|FullyEvalableOver&| . FEVALAB-)
+ (|FullyLinearlyExplicitRingOver&| . FLINEXP-)
+ (|FullyRetractableTo&| . FRETRCT-)
+ (|FunctionFieldCategory&| . FFCAT-)
+ (|FunctionSpace&| . FS-)
+ (|GcdDomain&| . GCDDOM-)
+ (|GradedAlgebra&| . GRALG-)
+ (|GradedModule&| . GRMOD-)
+ (|Group&| . GROUP-)
+ (|HomogeneousAggregate&| . HOAGG-)
+ (|HyperbolicFunctionCategory&| . HYPCAT-)
+ (|IndexedAggregate&| . IXAGG-)
+ (|InnerEvalable&| . IEVALAB-)
+ (|IntegerNumberSystem&| . INS-)
+ (|IntegralDomain&| . INTDOM-)
+ (|KeyedDictionary&| . KDAGG-)
+ (|LazyStreamAggregate&| . LZSTAGG-)
+ (|LeftAlgebra&| . LALG-)
+ (|LieAlgebra&| . LIECAT-)
+ (|LinearAggregate&| . LNAGG-)
+ (|ListAggregate&| . LSAGG-)
+ (|Logic&| . LOGIC-)
+ (|LinearOrdinaryDifferentialOperatorCategory&| . LODOCAT-)
+ (|MatrixCategory&| . MATCAT-)
+ (|Module&| . MODULE-)
+ (|Monad&| . MONAD-)
+ (|MonadWithUnit&| . MONADWU-)
+ (|Monoid&| . MONOID-)
+ (|MonogenicAlgebra&| . MONOGEN-)
+ (|NonAssociativeAlgebra&| . NAALG-)
+ (|NonAssociativeRing&| . NASRING-)
+ (|NonAssociativeRng&| . NARNG-)
+ (|OctonionCategory&| . OC-)
+ (|OneDimensionalArrayAggregate&| . A1AGG-)
+ (|OrderedRing&| . ORDRING-)
+ (|OrderedSet&| . ORDSET-)
+ (|PartialDifferentialRing&| . PDRING-)
+ (|PolynomialCategory&| . POLYCAT-)
+ (|PolynomialFactorizationExplicit&| . PFECAT-)
+ (|PolynomialSetCategory&| . PSETCAT-)
+ (|PowerSeriesCategory&| . PSCAT-)
+ (|QuaternionCategory&| . QUATCAT-)
+ (|QuotientFieldCategory&| . QFCAT-)
+ (|RadicalCategory&| . RADCAT-)
+ (|RealClosedField&| . RCFIELD-)
+ (|RealNumberSystem&| . RNS-)
+ (|RealRootCharacterizationCategory&| . RRCC-)
+ (|RectangularMatrixCategory&| . RMATCAT-)
+ (|RecursiveAggregate&| . RCAGG-)
+ (|RecursivePolynomialCategory&| . RPOLCAT-)
+ (|RegularTriangularSetCategory&| . RSETCAT-)
+ (|RetractableTo&| . RETRACT-)
+ (|Ring&| . RING-)
+ (|SemiGroup&| . SGROUP-)
+ (|SetAggregate&| . SETAGG-)
+ (|SetCategory&| . SETCAT-)
+ (|SquareMatrixCategory&| . SMATCAT-)
+ (|StreamAggregate&| . STAGG-)
+ (|StringAggregate&| . SRAGG-)
+ (|TableAggregate&| . TBAGG-)
+ (|TranscendentalFunctionCategory&| . TRANFUN-)
+ (|TriangularSetCategory&| . TSETCAT-)
+ (|TrigonometricFunctionCategory&| . TRIGCAT-)
+ (|TwoDimensionalArrayCategory&| . ARR2CAT-)
+ (|UnaryRecursiveAggregate&| . URAGG-)
+ (|UniqueFactorizationDomain&| . UFD-)
+ (|UnivariateLaurentSeriesConstructorCategory&| . ULSCCAT-)
+ (|UnivariatePolynomialCategory&| . UPOLYC-)
+ (|UnivariatePowerSeriesCategory&| . UPSCAT-)
+ (|UnivariatePuiseuxSeriesConstructorCategory&| . UPXSCCA-)
+ (|UnivariateSkewPolynomialCategory&| . OREPCAT-)
+ (|UnivariateTaylorSeriesCategory&| . UTSCAT-)
+ (|VectorCategory&| . VECTCAT-)
+ (|VectorSpace&| . VSPACE-)))
+)
+(setq |$localExposureDataDefault| (VECTOR
+(LIST
+;;These groups will be exposed
+'|basic|
+'|categories|
+'|naglink|
+'|anna|
+)
+(LIST
+;;These constructors will be explicitly exposed
+)
+(LIST
+;;These constructors will be explicitly hidden
+)
+))
+(setq |$localExposureData| (copy-seq |$localExposureDataDefault|))
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/expr.spad.pamphlet b/src/algebra/expr.spad.pamphlet
new file mode 100644
index 00000000..93324931
--- /dev/null
+++ b/src/algebra/expr.spad.pamphlet
@@ -0,0 +1,915 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra expr.spad}
+\author{Manuel Bronstein, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain EXPR Expression}
+<<domain EXPR Expression>>=
+)abbrev domain EXPR Expression
+++ Top-level mathematical expressions
+++ Author: Manuel Bronstein
+++ Date Created: 19 July 1988
+++ Date Last Updated: October 1993 (P.Gianni), February 1995 (MB)
+++ Description: Expressions involving symbolic functions.
+++ Keywords: operator, kernel, function.
+Expression(R:OrderedSet): Exports == Implementation where
+ Q ==> Fraction Integer
+ K ==> Kernel %
+ MP ==> SparseMultivariatePolynomial(R, K)
+ AF ==> AlgebraicFunction(R, %)
+ EF ==> ElementaryFunction(R, %)
+ CF ==> CombinatorialFunction(R, %)
+ LF ==> LiouvillianFunction(R, %)
+ AN ==> AlgebraicNumber
+ KAN ==> Kernel AN
+ FSF ==> FunctionalSpecialFunction(R, %)
+ ESD ==> ExpressionSpace_&(%)
+ FSD ==> FunctionSpace_&(%, R)
+ SYMBOL ==> "%symbol"
+ ALGOP ==> "%alg"
+ POWER ==> "%power"::Symbol
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> FunctionSpace R with
+ if R has IntegralDomain then
+ AlgebraicallyClosedFunctionSpace R
+ TranscendentalFunctionCategory
+ CombinatorialOpsCategory
+ LiouvillianFunctionCategory
+ SpecialFunctionCategory
+ reduce: % -> %
+ ++ reduce(f) simplifies all the unreduced algebraic quantities
+ ++ present in f by applying their defining relations.
+ number?: % -> Boolean
+ ++ number?(f) tests if f is rational
+ simplifyPower: (%,Integer) -> %
+ ++ simplifyPower?(f,n) \undocumented{}
+ if R has GcdDomain then
+ factorPolynomial : SUP % -> Factored SUP %
+ ++ factorPolynomial(p) \undocumented{}
+ squareFreePolynomial : SUP % -> Factored SUP %
+ ++ squareFreePolynomial(p) \undocumented{}
+ if R has RetractableTo Integer then RetractableTo AN
+
+ Implementation ==> add
+ import KernelFunctions2(R, %)
+
+ retNotUnit : % -> R
+ retNotUnitIfCan: % -> Union(R, "failed")
+
+ belong? op == true
+
+ retNotUnit x ==
+ (u := constantIfCan(k := retract(x)@K)) case R => u::R
+ error "Not retractable"
+
+ retNotUnitIfCan x ==
+ (r := retractIfCan(x)@Union(K,"failed")) case "failed" => "failed"
+ constantIfCan(r::K)
+
+ if R has IntegralDomain then
+ reduc : (%, List Kernel %) -> %
+ commonk : (%, %) -> List K
+ commonk0 : (List K, List K) -> List K
+ toprat : % -> %
+ algkernels: List K -> List K
+ evl : (MP, K, SparseUnivariatePolynomial %) -> Fraction MP
+ evl0 : (MP, K) -> SparseUnivariatePolynomial Fraction MP
+
+ Rep := Fraction MP
+ 0 == 0$Rep
+ 1 == 1$Rep
+-- one? x == one?(x)$Rep
+ one? x == (x = 1)$Rep
+ zero? x == zero?(x)$Rep
+ - x:% == -$Rep x
+ n:Integer * x:% == n *$Rep x
+ coerce(n:Integer) == coerce(n)$Rep@Rep::%
+ x:% * y:% == reduc(x *$Rep y, commonk(x, y))
+ x:% + y:% == reduc(x +$Rep y, commonk(x, y))
+ (x:% - y:%):% == reduc(x -$Rep y, commonk(x, y))
+ x:% / y:% == reduc(x /$Rep y, commonk(x, y))
+
+ number?(x:%):Boolean ==
+ if R has RetractableTo(Integer) then
+ ground?(x) or ((retractIfCan(x)@Union(Q,"failed")) case Q)
+ else
+ ground?(x)
+
+ simplifyPower(x:%,n:Integer):% ==
+ k : List K := kernels x
+ is?(x,POWER) =>
+ -- Look for a power of a number in case we can do a simplification
+ args : List % := argument first k
+ not(#args = 2) => error "Too many arguments to **"
+ number?(args.1) =>
+ reduc((args.1) **$Rep n, algkernels kernels (args.1))**(args.2)
+ (first args)**(n*second(args))
+ reduc(x **$Rep n, algkernels k)
+
+ x:% ** n:NonNegativeInteger ==
+ n = 0 => 1$%
+ n = 1 => x
+ simplifyPower(numerator x,n pretend Integer) / simplifyPower(denominator x,n pretend Integer)
+
+ x:% ** n:Integer ==
+ n = 0 => 1$%
+ n = 1 => x
+ n = -1 => 1/x
+ simplifyPower(numerator x,n) / simplifyPower(denominator x,n)
+
+ x:% ** n:PositiveInteger ==
+ n = 1 => x
+ simplifyPower(numerator x,n pretend Integer) / simplifyPower(denominator x,n pretend Integer)
+
+ x:% < y:% == x <$Rep y
+ x:% = y:% == x =$Rep y
+ numer x == numer(x)$Rep
+ denom x == denom(x)$Rep
+ coerce(p:MP):% == coerce(p)$Rep
+ reduce x == reduc(x, algkernels kernels x)
+ commonk(x, y) == commonk0(algkernels kernels x, algkernels kernels y)
+ algkernels l == select_!(has?(operator #1, ALGOP), l)
+ toprat f == ratDenom(f, algkernels kernels f)$AlgebraicManipulations(R, %)
+
+ x:MP / y:MP ==
+ reduc(x /$Rep y,commonk0(algkernels variables x,algkernels variables y))
+
+-- since we use the reduction from FRAC SMP which asssumes that the
+-- variables are independent, we must remove algebraic from the denominators
+ reducedSystem(m:Matrix %):Matrix(R) ==
+ mm:Matrix(MP) := reducedSystem(map(toprat, m))$Rep
+ reducedSystem(mm)$MP
+
+-- since we use the reduction from FRAC SMP which asssumes that the
+-- variables are independent, we must remove algebraic from the denominators
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix R, vec:Vector R) ==
+ r:Record(mat:Matrix MP, vec:Vector MP) :=
+ reducedSystem(map(toprat, m), map(toprat, v))$Rep
+ reducedSystem(r.mat, r.vec)$MP
+
+-- The result MUST be left sorted deepest first MB 3/90
+ commonk0(x, y) ==
+ ans := empty()$List(K)
+ for k in reverse_! x repeat if member?(k, y) then ans := concat(k, ans)
+ ans
+
+ rootOf(x:SparseUnivariatePolynomial %, v:Symbol) == rootOf(x,v)$AF
+ pi() == pi()$EF
+ exp x == exp(x)$EF
+ log x == log(x)$EF
+ sin x == sin(x)$EF
+ cos x == cos(x)$EF
+ tan x == tan(x)$EF
+ cot x == cot(x)$EF
+ sec x == sec(x)$EF
+ csc x == csc(x)$EF
+ asin x == asin(x)$EF
+ acos x == acos(x)$EF
+ atan x == atan(x)$EF
+ acot x == acot(x)$EF
+ asec x == asec(x)$EF
+ acsc x == acsc(x)$EF
+ sinh x == sinh(x)$EF
+ cosh x == cosh(x)$EF
+ tanh x == tanh(x)$EF
+ coth x == coth(x)$EF
+ sech x == sech(x)$EF
+ csch x == csch(x)$EF
+ asinh x == asinh(x)$EF
+ acosh x == acosh(x)$EF
+ atanh x == atanh(x)$EF
+ acoth x == acoth(x)$EF
+ asech x == asech(x)$EF
+ acsch x == acsch(x)$EF
+
+ abs x == abs(x)$FSF
+ Gamma x == Gamma(x)$FSF
+ Gamma(a, x) == Gamma(a, x)$FSF
+ Beta(x,y) == Beta(x,y)$FSF
+ digamma x == digamma(x)$FSF
+ polygamma(k,x) == polygamma(k,x)$FSF
+ besselJ(v,x) == besselJ(v,x)$FSF
+ besselY(v,x) == besselY(v,x)$FSF
+ besselI(v,x) == besselI(v,x)$FSF
+ besselK(v,x) == besselK(v,x)$FSF
+ airyAi x == airyAi(x)$FSF
+ airyBi x == airyBi(x)$FSF
+
+ x:% ** y:% == x **$CF y
+ factorial x == factorial(x)$CF
+ binomial(n, m) == binomial(n, m)$CF
+ permutation(n, m) == permutation(n, m)$CF
+ factorials x == factorials(x)$CF
+ factorials(x, n) == factorials(x, n)$CF
+ summation(x:%, n:Symbol) == summation(x, n)$CF
+ summation(x:%, s:SegmentBinding %) == summation(x, s)$CF
+ product(x:%, n:Symbol) == product(x, n)$CF
+ product(x:%, s:SegmentBinding %) == product(x, s)$CF
+
+ erf x == erf(x)$LF
+ Ei x == Ei(x)$LF
+ Si x == Si(x)$LF
+ Ci x == Ci(x)$LF
+ li x == li(x)$LF
+ dilog x == dilog(x)$LF
+ integral(x:%, n:Symbol) == integral(x, n)$LF
+ integral(x:%, s:SegmentBinding %) == integral(x, s)$LF
+
+ operator op ==
+ belong?(op)$AF => operator(op)$AF
+ belong?(op)$EF => operator(op)$EF
+ belong?(op)$CF => operator(op)$CF
+ belong?(op)$LF => operator(op)$LF
+ belong?(op)$FSF => operator(op)$FSF
+ belong?(op)$FSD => operator(op)$FSD
+ belong?(op)$ESD => operator(op)$ESD
+ nullary? op and has?(op, SYMBOL) => operator(kernel(name op)$K)
+ (n := arity op) case "failed" => operator name op
+ operator(name op, n::NonNegativeInteger)
+
+ reduc(x, l) ==
+ for k in l repeat
+ p := minPoly k
+ x := evl(numer x, k, p) /$Rep evl(denom x, k, p)
+ x
+
+ evl0(p, k) ==
+ numer univariate(p::Fraction(MP),
+ k)$PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K,R,MP,Fraction MP)
+
+ -- uses some operations from Rep instead of % in order not to
+ -- reduce recursively during those operations.
+ evl(p, k, m) ==
+ degree(p, k) < degree m => p::Fraction(MP)
+ (((evl0(p, k) pretend SparseUnivariatePolynomial($)) rem m)
+ pretend SparseUnivariatePolynomial Fraction MP) (k::MP::Fraction(MP))
+
+ if R has GcdDomain then
+ noalg?: SUP % -> Boolean
+
+ noalg? p ==
+ while p ^= 0 repeat
+ not empty? algkernels kernels leadingCoefficient p => return false
+ p := reductum p
+ true
+
+ gcdPolynomial(p:SUP %, q:SUP %) ==
+ noalg? p and noalg? q => gcdPolynomial(p, q)$Rep
+ gcdPolynomial(p, q)$GcdDomain_&(%)
+
+ factorPolynomial(x:SUP %) : Factored SUP % ==
+ uf:= factor(x pretend SUP(Rep))$SupFractionFactorizer(
+ IndexedExponents K,K,R,MP)
+ uf pretend Factored SUP %
+
+ squareFreePolynomial(x:SUP %) : Factored SUP % ==
+ uf:= squareFree(x pretend SUP(Rep))$SupFractionFactorizer(
+ IndexedExponents K,K,R,MP)
+ uf pretend Factored SUP %
+
+ if R is AN then
+ -- this is to force the coercion R -> EXPR R to be used
+ -- instead of the coercioon AN -> EXPR R which loops.
+ -- simpler looking code will fail! MB 10/91
+ coerce(x:AN):% == (monomial(x, 0$IndexedExponents(K))$MP)::%
+
+ if (R has RetractableTo Integer) then
+ x:% ** r:Q == x **$AF r
+ minPoly k == minPoly(k)$AF
+ definingPolynomial x == definingPolynomial(x)$AF
+ retract(x:%):Q == retract(x)$Rep
+ retractIfCan(x:%):Union(Q, "failed") == retractIfCan(x)$Rep
+
+ if not(R is AN) then
+ k2expr : KAN -> %
+ smp2expr: SparseMultivariatePolynomial(Integer, KAN) -> %
+ R2AN : R -> Union(AN, "failed")
+ k2an : K -> Union(AN, "failed")
+ smp2an : MP -> Union(AN, "failed")
+
+
+ coerce(x:AN):% == smp2expr(numer x) / smp2expr(denom x)
+ k2expr k == map(#1::%, k)$ExpressionSpaceFunctions2(AN, %)
+
+ smp2expr p ==
+ map(k2expr,#1::%,p)$PolynomialCategoryLifting(IndexedExponents KAN,
+ KAN, Integer, SparseMultivariatePolynomial(Integer, KAN), %)
+
+ retractIfCan(x:%):Union(AN, "failed") ==
+ ((n:= smp2an numer x) case AN) and ((d:= smp2an denom x) case AN)
+ => (n::AN) / (d::AN)
+ "failed"
+
+ R2AN r ==
+ (u := retractIfCan(r::%)@Union(Q, "failed")) case Q => u::Q::AN
+ "failed"
+
+ k2an k ==
+ not(belong?(op := operator k)$AN) => "failed"
+ arg:List(AN) := empty()
+ for x in argument k repeat
+ if (a := retractIfCan(x)@Union(AN, "failed")) case "failed" then
+ return "failed"
+ else arg := concat(a::AN, arg)
+ (operator(op)$AN) reverse_!(arg)
+
+ smp2an p ==
+ (x1 := mainVariable p) case "failed" => R2AN leadingCoefficient p
+ up := univariate(p, k := x1::K)
+ (t := k2an k) case "failed" => "failed"
+ ans:AN := 0
+ while not ground? up repeat
+ (c:=smp2an leadingCoefficient up) case "failed" => return "failed"
+ ans := ans + (c::AN) * (t::AN) ** (degree up)
+ up := reductum up
+ (c := smp2an leadingCoefficient up) case "failed" => "failed"
+ ans + c::AN
+
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm == convert(x)$Rep
+ import MakeUnaryCompiledFunction(%, %, %)
+ eval(f:%, op: BasicOperator, g:%, x:Symbol):% ==
+ eval(f,[op],[g],x)
+ eval(f:%, ls:List BasicOperator, lg:List %, x:Symbol) ==
+ -- handle subsrcipted symbols by renaming -> eval -> renaming back
+ llsym:List List Symbol:=[variables g for g in lg]
+ lsym:List Symbol:= removeDuplicates concat llsym
+ lsd:List Symbol:=select (scripted?,lsym)
+ empty? lsd=> eval(f,ls,[compiledFunction(g, x) for g in lg])
+ ns:List Symbol:=[new()$Symbol for i in lsd]
+ lforwardSubs:List Equation % := [(i::%)= (j::%) for i in lsd for j in ns]
+ lbackwardSubs:List Equation % := [(j::%)= (i::%) for i in lsd for j in ns]
+ nlg:List % :=[subst(g,lforwardSubs) for g in lg]
+ res:% :=eval(f, ls, [compiledFunction(g, x) for g in nlg])
+ subst(res,lbackwardSubs)
+ if R has PatternMatchable Integer then
+ patternMatch(x:%, p:Pattern Integer,
+ l:PatternMatchResult(Integer, %)) ==
+ patternMatch(x, p, l)$PatternMatchFunctionSpace(Integer, R, %)
+
+ if R has PatternMatchable Float then
+ patternMatch(x:%, p:Pattern Float,
+ l:PatternMatchResult(Float, %)) ==
+ patternMatch(x, p, l)$PatternMatchFunctionSpace(Float, R, %)
+
+ else -- R is not an integral domain
+ operator op ==
+ belong?(op)$FSD => operator(op)$FSD
+ belong?(op)$ESD => operator(op)$ESD
+ nullary? op and has?(op, SYMBOL) => operator(kernel(name op)$K)
+ (n := arity op) case "failed" => operator name op
+ operator(name op, n::NonNegativeInteger)
+
+ if R has Ring then
+ Rep := MP
+ 0 == 0$Rep
+ 1 == 1$Rep
+ - x:% == -$Rep x
+ n:Integer *x:% == n *$Rep x
+ x:% * y:% == x *$Rep y
+ x:% + y:% == x +$Rep y
+ x:% = y:% == x =$Rep y
+ x:% < y:% == x <$Rep y
+ numer x == x@Rep
+ coerce(p:MP):% == p
+
+ reducedSystem(m:Matrix %):Matrix(R) ==
+ reducedSystem(m)$Rep
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix R, vec:Vector R) ==
+ reducedSystem(m, v)$Rep
+
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm == convert(x)$Rep
+
+ if R has PatternMatchable Integer then
+ kintmatch: (K,Pattern Integer,PatternMatchResult(Integer,Rep))
+ -> PatternMatchResult(Integer, Rep)
+
+ kintmatch(k, p, l) ==
+ patternMatch(k, p, l pretend PatternMatchResult(Integer, %)
+ )$PatternMatchKernel(Integer, %)
+ pretend PatternMatchResult(Integer, Rep)
+
+ patternMatch(x:%, p:Pattern Integer,
+ l:PatternMatchResult(Integer, %)) ==
+ patternMatch(x@Rep, p,
+ l pretend PatternMatchResult(Integer, Rep),
+ kintmatch
+ )$PatternMatchPolynomialCategory(Integer,
+ IndexedExponents K, K, R, Rep)
+ pretend PatternMatchResult(Integer, %)
+
+ if R has PatternMatchable Float then
+ kfltmatch: (K, Pattern Float, PatternMatchResult(Float, Rep))
+ -> PatternMatchResult(Float, Rep)
+
+ kfltmatch(k, p, l) ==
+ patternMatch(k, p, l pretend PatternMatchResult(Float, %)
+ )$PatternMatchKernel(Float, %)
+ pretend PatternMatchResult(Float, Rep)
+
+ patternMatch(x:%, p:Pattern Float,
+ l:PatternMatchResult(Float, %)) ==
+ patternMatch(x@Rep, p,
+ l pretend PatternMatchResult(Float, Rep),
+ kfltmatch
+ )$PatternMatchPolynomialCategory(Float,
+ IndexedExponents K, K, R, Rep)
+ pretend PatternMatchResult(Float, %)
+
+ else -- R is not even a ring
+ if R has AbelianMonoid then
+ import ListToMap(K, %)
+
+ kereval : (K, List K, List %) -> %
+ subeval : (K, List K, List %) -> %
+
+ Rep := FreeAbelianGroup K
+
+ 0 == 0$Rep
+ x:% + y:% == x +$Rep y
+ x:% = y:% == x =$Rep y
+ x:% < y:% == x <$Rep y
+ coerce(k:K):% == coerce(k)$Rep
+ kernels x == [f.gen for f in terms x]
+ coerce(x:R):% == (zero? x => 0; constantKernel(x)::%)
+ retract(x:%):R == (zero? x => 0; retNotUnit x)
+ coerce(x:%):OutputForm == coerce(x)$Rep
+ kereval(k, lk, lv) == match(lk, lv, k, map(eval(#1, lk, lv), #1))
+
+ subeval(k, lk, lv) ==
+ match(lk, lv, k,
+ kernel(operator #1, [subst(a, lk, lv) for a in argument #1]))
+
+ isPlus x ==
+ empty?(l := terms x) or empty? rest l => "failed"
+ [t.exp *$Rep t.gen for t in l]$List(%)
+
+ isMult x ==
+ empty?(l := terms x) or not empty? rest l => "failed"
+ t := first l
+ [t.exp, t.gen]
+
+ eval(x:%, lk:List K, lv:List %) ==
+ _+/[t.exp * kereval(t.gen, lk, lv) for t in terms x]
+
+ subst(x:%, lk:List K, lv:List %) ==
+ _+/[t.exp * subeval(t.gen, lk, lv) for t in terms x]
+
+ retractIfCan(x:%):Union(R, "failed") ==
+ zero? x => 0
+ retNotUnitIfCan x
+
+ if R has AbelianGroup then -(x:%) == -$Rep x
+
+-- else -- R is not an AbelianMonoid
+-- if R has SemiGroup then
+-- Rep := FreeGroup K
+-- 1 == 1$Rep
+-- x:% * y:% == x *$Rep y
+-- x:% = y:% == x =$Rep y
+-- coerce(k:K):% == k::Rep
+-- kernels x == [f.gen for f in factors x]
+-- coerce(x:R):% == (one? x => 1; constantKernel x)
+-- retract(x:%):R == (one? x => 1; retNotUnit x)
+-- coerce(x:%):OutputForm == coerce(x)$Rep
+
+-- retractIfCan(x:%):Union(R, "failed") ==
+-- one? x => 1
+-- retNotUnitIfCan x
+
+-- if R has Group then inv(x:%):% == inv(x)$Rep
+
+ else -- R is nothing
+ import ListToMap(K, %)
+
+ Rep := K
+
+ x:% < y:% == x <$Rep y
+ x:% = y:% == x =$Rep y
+ coerce(k:K):% == k
+ kernels x == [x pretend K]
+ coerce(x:R):% == constantKernel x
+ retract(x:%):R == retNotUnit x
+ retractIfCan(x:%):Union(R, "failed") == retNotUnitIfCan x
+ coerce(x:%):OutputForm == coerce(x)$Rep
+
+ eval(x:%, lk:List K, lv:List %) ==
+ match(lk, lv, x pretend K, map(eval(#1, lk, lv), #1))
+
+ subst(x, lk, lv) ==
+ match(lk, lv, x pretend K,
+ kernel(operator #1, [subst(a, lk, lv) for a in argument #1]))
+
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm == convert(x)$Rep
+
+-- if R has PatternMatchable Integer then
+-- convert(x:%):Pattern(Integer) == convert(x)$Rep
+--
+-- patternMatch(x:%, p:Pattern Integer,
+-- l:PatternMatchResult(Integer, %)) ==
+-- patternMatch(x pretend K,p,l)$PatternMatchKernel(Integer, %)
+--
+-- if R has PatternMatchable Float then
+-- convert(x:%):Pattern(Float) == convert(x)$Rep
+--
+-- patternMatch(x:%, p:Pattern Float,
+-- l:PatternMatchResult(Float, %)) ==
+-- patternMatch(x pretend K, p, l)$PatternMatchKernel(Float, %)
+
+@
+\section{package PAN2EXPR PolynomialAN2Expression}
+<<package PAN2EXPR PolynomialAN2Expression>>=
+)abbrev package PAN2EXPR PolynomialAN2Expression
+++ Author: Barry Trager
+++ Date Created: 8 Oct 1991
+++ Description: This package provides a coerce from polynomials over
+++ algebraic numbers to \spadtype{Expression AlgebraicNumber}.
+PolynomialAN2Expression():Target == Implementation where
+ EXPR ==> Expression(Integer)
+ AN ==> AlgebraicNumber
+ PAN ==> Polynomial AN
+ SY ==> Symbol
+ Target ==> with
+ coerce: Polynomial AlgebraicNumber -> Expression(Integer)
+ ++ coerce(p) converts the polynomial \spad{p} with algebraic number
+ ++ coefficients to \spadtype{Expression Integer}.
+ coerce: Fraction Polynomial AlgebraicNumber -> Expression(Integer)
+ ++ coerce(rf) converts \spad{rf}, a fraction of polynomial \spad{p} with
+ ++ algebraic number coefficients to \spadtype{Expression Integer}.
+ Implementation ==> add
+ coerce(p:PAN):EXPR ==
+ map(#1::EXPR, #1::EXPR, p)$PolynomialCategoryLifting(
+ IndexedExponents SY, SY, AN, PAN, EXPR)
+ coerce(rf:Fraction PAN):EXPR ==
+ numer(rf)::EXPR / denom(rf)::EXPR
+
+@
+\section{package EXPR2 ExpressionFunctions2}
+<<package EXPR2 ExpressionFunctions2>>=
+)abbrev package EXPR2 ExpressionFunctions2
+++ Lifting of maps to Expressions
+++ Author: Manuel Bronstein
+++ Description: Lifting of maps to Expressions.
+++ Date Created: 16 Jan 1989
+++ Date Last Updated: 22 Jan 1990
+ExpressionFunctions2(R:OrderedSet, S:OrderedSet):
+ Exports == Implementation where
+ K ==> Kernel R
+ F2 ==> FunctionSpaceFunctions2(R, Expression R, S, Expression S)
+ E2 ==> ExpressionSpaceFunctions2(Expression R, Expression S)
+
+ Exports ==> with
+ map: (R -> S, Expression R) -> Expression S
+ ++ map(f, e) applies f to all the constants appearing in e.
+
+ Implementation == add
+ if S has Ring and R has Ring then
+ map(f, r) == map(f, r)$F2
+ else
+ map(f, r) == map(map(f, #1), retract r)$E2
+
+@
+\section{package PMPREDFS FunctionSpaceAttachPredicates}
+<<package PMPREDFS FunctionSpaceAttachPredicates>>=
+)abbrev package PMPREDFS FunctionSpaceAttachPredicates
+++ Predicates for pattern-matching.
+++ Author: Manuel Bronstein
+++ Description: Attaching predicates to symbols for pattern matching.
+++ Date Created: 21 Mar 1989
+++ Date Last Updated: 23 May 1990
+++ Keywords: pattern, matching.
+FunctionSpaceAttachPredicates(R, F, D): Exports == Implementation where
+ R: OrderedSet
+ F: FunctionSpace R
+ D: Type
+
+ K ==> Kernel F
+ PMPRED ==> "%pmpredicate"
+
+ Exports ==> with
+ suchThat: (F, D -> Boolean) -> F
+ ++ suchThat(x, foo) attaches the predicate foo to x;
+ ++ error if x is not a symbol.
+ suchThat: (F, List(D -> Boolean)) -> F
+ ++ suchThat(x, [f1, f2, ..., fn]) attaches the predicate
+ ++ f1 and f2 and ... and fn to x.
+ ++ Error: if x is not a symbol.
+
+ Implementation ==> add
+ import AnyFunctions1(D -> Boolean)
+
+ st : (K, List Any) -> F
+ preds: K -> List Any
+ mkk : BasicOperator -> F
+
+ suchThat(p:F, f:D -> Boolean) == suchThat(p, [f])
+ mkk op == kernel(op, empty()$List(F))
+
+ preds k ==
+ (u := property(operator k, PMPRED)) case "failed" => empty()
+ (u::None) pretend List(Any)
+
+ st(k, l) ==
+ mkk assert(setProperty(copy operator k, PMPRED,
+ concat(preds k, l) pretend None), string(new()$Symbol))
+
+ suchThat(p:F, l:List(D -> Boolean)) ==
+ retractIfCan(p)@Union(Symbol, "failed") case Symbol =>
+ st(retract(p)@K, [f::Any for f in l])
+ error "suchThat must be applied to symbols only"
+
+@
+\section{package PMASSFS FunctionSpaceAssertions}
+<<package PMASSFS FunctionSpaceAssertions>>=
+)abbrev package PMASSFS FunctionSpaceAssertions
+++ Assertions for pattern-matching
+++ Author: Manuel Bronstein
+++ Description: Attaching assertions to symbols for pattern matching;
+++ Date Created: 21 Mar 1989
+++ Date Last Updated: 23 May 1990
+++ Keywords: pattern, matching.
+FunctionSpaceAssertions(R, F): Exports == Implementation where
+ R: OrderedSet
+ F: FunctionSpace R
+
+ K ==> Kernel F
+ PMOPT ==> "%pmoptional"
+ PMMULT ==> "%pmmultiple"
+ PMCONST ==> "%pmconstant"
+
+ Exports ==> with
+ assert : (F, String) -> F
+ ++ assert(x, s) makes the assertion s about x.
+ ++ Error: if x is not a symbol.
+ constant: F -> F
+ ++ constant(x) tells the pattern matcher that x should
+ ++ match only the symbol 'x and no other quantity.
+ ++ Error: if x is not a symbol.
+ optional: F -> F
+ ++ optional(x) tells the pattern matcher that x can match
+ ++ an identity (0 in a sum, 1 in a product or exponentiation).
+ ++ Error: if x is not a symbol.
+ multiple: F -> F
+ ++ multiple(x) tells the pattern matcher that x should
+ ++ preferably match a multi-term quantity in a sum or product.
+ ++ For matching on lists, multiple(x) tells the pattern matcher
+ ++ that x should match a list instead of an element of a list.
+ ++ Error: if x is not a symbol.
+
+ Implementation ==> add
+ ass : (K, String) -> F
+ asst : (K, String) -> F
+ mkk : BasicOperator -> F
+
+ mkk op == kernel(op, empty()$List(F))
+
+ ass(k, s) ==
+ has?(op := operator k, s) => k::F
+ mkk assert(copy op, s)
+
+ asst(k, s) ==
+ has?(op := operator k, s) => k::F
+ mkk assert(op, s)
+
+ assert(x, s) ==
+ retractIfCan(x)@Union(Symbol, "failed") case Symbol =>
+ asst(retract(x)@K, s)
+ error "assert must be applied to symbols only"
+
+ constant x ==
+ retractIfCan(x)@Union(Symbol, "failed") case Symbol =>
+ ass(retract(x)@K, PMCONST)
+ error "constant must be applied to symbols only"
+
+ optional x ==
+ retractIfCan(x)@Union(Symbol, "failed") case Symbol =>
+ ass(retract(x)@K, PMOPT)
+ error "optional must be applied to symbols only"
+
+ multiple x ==
+ retractIfCan(x)@Union(Symbol, "failed") case Symbol =>
+ ass(retract(x)@K, PMMULT)
+ error "multiple must be applied to symbols only"
+
+@
+\section{package PMPRED AttachPredicates}
+<<package PMPRED AttachPredicates>>=
+)abbrev package PMPRED AttachPredicates
+++ Predicates for pattern-matching
+++ Author: Manuel Bronstein
+++ Description: Attaching predicates to symbols for pattern matching.
+++ Date Created: 21 Mar 1989
+++ Date Last Updated: 23 May 1990
+++ Keywords: pattern, matching.
+AttachPredicates(D:Type): Exports == Implementation where
+ FE ==> Expression Integer
+
+ Exports ==> with
+ suchThat: (Symbol, D -> Boolean) -> FE
+ ++ suchThat(x, foo) attaches the predicate foo to x.
+ suchThat: (Symbol, List(D -> Boolean)) -> FE
+ ++ suchThat(x, [f1, f2, ..., fn]) attaches the predicate
+ ++ f1 and f2 and ... and fn to x.
+
+ Implementation ==> add
+ import FunctionSpaceAttachPredicates(Integer, FE, D)
+
+ suchThat(p:Symbol, f:D -> Boolean) == suchThat(p::FE, f)
+ suchThat(p:Symbol, l:List(D -> Boolean)) == suchThat(p::FE, l)
+
+@
+\section{package PMASS PatternMatchAssertions}
+<<package PMASS PatternMatchAssertions>>=
+)abbrev package PMASS PatternMatchAssertions
+++ Assertions for pattern-matching
+++ Author: Manuel Bronstein
+++ Description: Attaching assertions to symbols for pattern matching.
+++ Date Created: 21 Mar 1989
+++ Date Last Updated: 23 May 1990
+++ Keywords: pattern, matching.
+PatternMatchAssertions(): Exports == Implementation where
+ FE ==> Expression Integer
+
+ Exports ==> with
+ assert : (Symbol, String) -> FE
+ ++ assert(x, s) makes the assertion s about x.
+ constant: Symbol -> FE
+ ++ constant(x) tells the pattern matcher that x should
+ ++ match only the symbol 'x and no other quantity.
+ optional: Symbol -> FE
+ ++ optional(x) tells the pattern matcher that x can match
+ ++ an identity (0 in a sum, 1 in a product or exponentiation).;
+ multiple: Symbol -> FE
+ ++ multiple(x) tells the pattern matcher that x should
+ ++ preferably match a multi-term quantity in a sum or product.
+ ++ For matching on lists, multiple(x) tells the pattern matcher
+ ++ that x should match a list instead of an element of a list.
+
+ Implementation ==> add
+ import FunctionSpaceAssertions(Integer, FE)
+
+ constant x == constant(x::FE)
+ multiple x == multiple(x::FE)
+ optional x == optional(x::FE)
+ assert(x, s) == assert(x::FE, s)
+
+@
+\section{domain HACKPI Pi}
+<<domain HACKPI Pi>>=
+)abbrev domain HACKPI Pi
+++ Expressions in %pi only
+++ Author: Manuel Bronstein
+++ Description:
+++ Symbolic fractions in %pi with integer coefficients;
+++ The point for using Pi as the default domain for those fractions
+++ is that Pi is coercible to the float types, and not Expression.
+++ Date Created: 21 Feb 1990
+++ Date Last Updated: 12 Mai 1992
+Pi(): Exports == Implementation where
+ PZ ==> Polynomial Integer
+ UP ==> SparseUnivariatePolynomial Integer
+ RF ==> Fraction UP
+
+ Exports ==> Join(Field, CharacteristicZero, RetractableTo Integer,
+ RetractableTo Fraction Integer, RealConstant,
+ CoercibleTo DoubleFloat, CoercibleTo Float,
+ ConvertibleTo RF, ConvertibleTo InputForm) with
+ pi: () -> % ++ pi() returns the symbolic %pi.
+ Implementation ==> RF add
+ Rep := RF
+
+ sympi := "%pi"::Symbol
+
+ p2sf: UP -> DoubleFloat
+ p2f : UP -> Float
+ p2o : UP -> OutputForm
+ p2i : UP -> InputForm
+ p2p: UP -> PZ
+
+ pi() == (monomial(1, 1)$UP :: RF) pretend %
+ convert(x:%):RF == x pretend RF
+ convert(x:%):Float == x::Float
+ convert(x:%):DoubleFloat == x::DoubleFloat
+ coerce(x:%):DoubleFloat == p2sf(numer x) / p2sf(denom x)
+ coerce(x:%):Float == p2f(numer x) / p2f(denom x)
+ p2o p == outputForm(p, sympi::OutputForm)
+ p2i p == convert p2p p
+
+ p2p p ==
+ ans:PZ := 0
+ while p ^= 0 repeat
+ ans := ans + monomial(leadingCoefficient(p)::PZ, sympi, degree p)
+ p := reductum p
+ ans
+
+ coerce(x:%):OutputForm ==
+ (r := retractIfCan(x)@Union(UP, "failed")) case UP => p2o(r::UP)
+ p2o(numer x) / p2o(denom x)
+
+ convert(x:%):InputForm ==
+ (r := retractIfCan(x)@Union(UP, "failed")) case UP => p2i(r::UP)
+ p2i(numer x) / p2i(denom x)
+
+ p2sf p ==
+ map(#1::DoubleFloat, p)$SparseUnivariatePolynomialFunctions2(
+ Integer, DoubleFloat) (pi()$DoubleFloat)
+
+ p2f p ==
+ map(#1::Float, p)$SparseUnivariatePolynomialFunctions2(
+ Integer, Float) (pi()$Float)
+
+@
+\section{package PICOERCE PiCoercions}
+<<package PICOERCE PiCoercions>>=
+)abbrev package PICOERCE PiCoercions
+++ Coercions from %pi to symbolic or numeric domains
+++ Author: Manuel Bronstein
+++ Description:
+++ Provides a coercion from the symbolic fractions in %pi with
+++ integer coefficients to any Expression type.
+++ Date Created: 21 Feb 1990
+++ Date Last Updated: 21 Feb 1990
+PiCoercions(R:Join(OrderedSet, IntegralDomain)): with
+ coerce: Pi -> Expression R
+ ++ coerce(f) returns f as an Expression(R).
+ == add
+ p2e: SparseUnivariatePolynomial Integer -> Expression R
+
+ coerce(x:Pi):Expression(R) ==
+ f := convert(x)@Fraction(SparseUnivariatePolynomial Integer)
+ p2e(numer f) / p2e(denom f)
+
+ p2e p ==
+ map(#1::Expression(R), p)$SparseUnivariatePolynomialFunctions2(
+ Integer, Expression R) (pi()$Expression(R))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl fspace algfunc elemntry combfunc EXPR
+
+<<domain EXPR Expression>>
+<<package PAN2EXPR PolynomialAN2Expression>>
+<<package EXPR2 ExpressionFunctions2>>
+<<package PMPREDFS FunctionSpaceAttachPredicates>>
+<<package PMASSFS FunctionSpaceAssertions>>
+<<package PMPRED AttachPredicates>>
+<<package PMASS PatternMatchAssertions>>
+<<domain HACKPI Pi>>
+<<package PICOERCE PiCoercions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/expr2ups.spad.pamphlet b/src/algebra/expr2ups.spad.pamphlet
new file mode 100644
index 00000000..fb0c2f6c
--- /dev/null
+++ b/src/algebra/expr2ups.spad.pamphlet
@@ -0,0 +1,383 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra expr2ups.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package EXPR2UPS ExpressionToUnivariatePowerSeries}
+<<package EXPR2UPS ExpressionToUnivariatePowerSeries>>=
+)abbrev package EXPR2UPS ExpressionToUnivariatePowerSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 9 May 1989
+++ Date Last Updated: 20 September 1993
+++ Basic Operations: taylor, laurent, puiseux, series
+++ Related Domains: UnivariateTaylorSeries, UnivariateLaurentSeries,
+++ UnivariatePuiseuxSeries, Expression
+++ Also See: FunctionSpaceToUnivariatePowerSeries
+++ AMS Classifications:
+++ Keywords: Taylor series, Laurent series, Puiseux series
+++ Examples:
+++ References:
+++ Description:
+++ This package provides functions to convert functional expressions
+++ to power series.
+ExpressionToUnivariatePowerSeries(R,FE): Exports == Implementation where
+ R : Join(GcdDomain,OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+
+ EQ ==> Equation
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+ SY ==> Symbol
+ UTS ==> UnivariateTaylorSeries
+ ULS ==> UnivariateLaurentSeries
+ UPXS ==> UnivariatePuiseuxSeries
+ GSER ==> GeneralUnivariatePowerSeries
+ EFULS ==> ElementaryFunctionsUnivariateLaurentSeries
+ EFUPXS ==> ElementaryFunctionsUnivariatePuiseuxSeries
+ FS2UPS ==> FunctionSpaceToUnivariatePowerSeries
+ Prob ==> Record(func:String,prob:String)
+ ANY1 ==> AnyFunctions1
+
+ Exports ==> with
+ taylor: SY -> Any
+ ++ \spad{taylor(x)} returns x viewed as a Taylor series.
+ taylor: FE -> Any
+ ++ \spad{taylor(f)} returns a Taylor expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable.
+ taylor: (FE,NNI) -> Any
+ ++ \spad{taylor(f,n)} returns a Taylor expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable and terms will be computed
+ ++ up to order at least n.
+ taylor: (FE,EQ FE) -> Any
+ ++ \spad{taylor(f,x = a)} expands the expression f as a Taylor series
+ ++ in powers of \spad{(x - a)}.
+ taylor: (FE,EQ FE,NNI) -> Any
+ ++ \spad{taylor(f,x = a)} expands the expression f as a Taylor series
+ ++ in powers of \spad{(x - a)}; terms will be computed up to order
+ ++ at least n.
+
+ laurent: SY -> Any
+ ++ \spad{laurent(x)} returns x viewed as a Laurent series.
+ laurent: FE -> Any
+ ++ \spad{laurent(f)} returns a Laurent expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable.
+ laurent: (FE,I) -> Any
+ ++ \spad{laurent(f,n)} returns a Laurent expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable and terms will be computed
+ ++ up to order at least n.
+ laurent: (FE,EQ FE) -> Any
+ ++ \spad{laurent(f,x = a)} expands the expression f as a Laurent series
+ ++ in powers of \spad{(x - a)}.
+ laurent: (FE,EQ FE,I) -> Any
+ ++ \spad{laurent(f,x = a,n)} expands the expression f as a Laurent
+ ++ series in powers of \spad{(x - a)}; terms will be computed up to order
+ ++ at least n.
+ puiseux: SY -> Any
+ ++ \spad{puiseux(x)} returns x viewed as a Puiseux series.
+ puiseux: FE -> Any
+ ++ \spad{puiseux(f)} returns a Puiseux expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable.
+ puiseux: (FE,RN) -> Any
+ ++ \spad{puiseux(f,n)} returns a Puiseux expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable and terms will be computed
+ ++ up to order at least n.
+ puiseux: (FE,EQ FE) -> Any
+ ++ \spad{puiseux(f,x = a)} expands the expression f as a Puiseux series
+ ++ in powers of \spad{(x - a)}.
+ puiseux: (FE,EQ FE,RN) -> Any
+ ++ \spad{puiseux(f,x = a,n)} expands the expression f as a Puiseux
+ ++ series in powers of \spad{(x - a)}; terms will be computed up to order
+ ++ at least n.
+
+ series: SY -> Any
+ ++ \spad{series(x)} returns x viewed as a series.
+ series: FE -> Any
+ ++ \spad{series(f)} returns a series expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable.
+ series: (FE,RN) -> Any
+ ++ \spad{series(f,n)} returns a series expansion of the expression f.
+ ++ Note: f should have only one variable; the series will be
+ ++ expanded in powers of that variable and terms will be computed
+ ++ up to order at least n.
+ series: (FE,EQ FE) -> Any
+ ++ \spad{series(f,x = a)} expands the expression f as a series
+ ++ in powers of (x - a).
+ series: (FE,EQ FE,RN) -> Any
+ ++ \spad{series(f,x = a,n)} expands the expression f as a series
+ ++ in powers of (x - a); terms will be computed up to order
+ ++ at least n.
+
+ Implementation ==> add
+ performSubstitution: (FE,SY,FE) -> FE
+ performSubstitution(fcn,x,a) ==
+ zero? a => fcn
+ xFE := x :: FE
+ eval(fcn,xFE = xFE + a)
+
+ iTaylor: (FE,SY,FE) -> Any
+ iTaylor(fcn,x,a) ==
+ pack := FS2UPS(R,FE,I,ULS(FE,x,a),_
+ EFULS(FE,UTS(FE,x,a),ULS(FE,x,a)),x)
+ ans := exprToUPS(fcn,false,"just do it")$pack
+ ans case %problem =>
+ ans.%problem.prob = "essential singularity" =>
+ error "No Taylor expansion: essential singularity"
+ ans.%problem.func = "log" =>
+ error "No Taylor expansion: logarithmic singularity"
+ ans.%problem.func = "nth root" =>
+ error "No Taylor expansion: fractional powers in expansion"
+ error "No Taylor expansion"
+ uls := ans.%series
+ (uts := taylorIfCan uls) case "failed" =>
+ error "No Taylor expansion: pole"
+ any1 := ANY1(UTS(FE,x,a))
+ coerce(uts :: UTS(FE,x,a))$any1
+
+ taylor(x:SY) ==
+ uts := UTS(FE,x,0$FE); any1 := ANY1(uts)
+ coerce(monomial(1,1)$uts)$any1
+
+ taylor(fcn:FE) ==
+ null(vars := variables fcn) =>
+ error "taylor: expression has no variables"
+ not null rest vars =>
+ error "taylor: expression has more than one variable"
+ taylor(fcn,(first(vars) :: FE) = 0)
+
+ taylor(fcn:FE,n:NNI) ==
+ null(vars := variables fcn) =>
+ error "taylor: expression has no variables"
+ not null rest vars =>
+ error "taylor: expression has more than one variable"
+ x := first vars
+ uts := UTS(FE,x,0$FE); any1 := ANY1(uts)
+ series := retract(taylor(fcn,(x :: FE) = 0))$any1
+ coerce(extend(series,n))$any1
+
+ taylor(fcn:FE,eq:EQ FE) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ iTaylor(performSubstitution(fcn,x,a),x,a)
+
+ taylor(fcn,eq,n) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ any1 := ANY1(UTS(FE,x,a))
+ series := retract(iTaylor(performSubstitution(fcn,x,a),x,a))$any1
+ coerce(extend(series,n))$any1
+
+ iLaurent: (FE,SY,FE) -> Any
+ iLaurent(fcn,x,a) ==
+ pack := FS2UPS(R,FE,I,ULS(FE,x,a),_
+ EFULS(FE,UTS(FE,x,a),ULS(FE,x,a)),x)
+ ans := exprToUPS(fcn,false,"just do it")$pack
+ ans case %problem =>
+ ans.%problem.prob = "essential singularity" =>
+ error "No Laurent expansion: essential singularity"
+ ans.%problem.func = "log" =>
+ error "No Laurent expansion: logarithmic singularity"
+ ans.%problem.func = "nth root" =>
+ error "No Laurent expansion: fractional powers in expansion"
+ error "No Laurent expansion"
+ any1 := ANY1(ULS(FE,x,a))
+ coerce(ans.%series)$any1
+
+ laurent(x:SY) ==
+ uls := ULS(FE,x,0$FE); any1 := ANY1(uls)
+ coerce(monomial(1,1)$uls)$any1
+
+ laurent(fcn:FE) ==
+ null(vars := variables fcn) =>
+ error "laurent: expression has no variables"
+ not null rest vars =>
+ error "laurent: expression has more than one variable"
+ laurent(fcn,(first(vars) :: FE) = 0)
+
+ laurent(fcn:FE,n:I) ==
+ null(vars := variables fcn) =>
+ error "laurent: expression has no variables"
+ not null rest vars =>
+ error "laurent: expression has more than one variable"
+ x := first vars
+ uls := ULS(FE,x,0$FE); any1 := ANY1(uls)
+ series := retract(laurent(fcn,(x :: FE) = 0))$any1
+ coerce(extend(series,n))$any1
+
+ laurent(fcn:FE,eq:EQ FE) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ iLaurent(performSubstitution(fcn,x,a),x,a)
+
+ laurent(fcn,eq,n) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ any1 := ANY1(ULS(FE,x,a))
+ series := retract(iLaurent(performSubstitution(fcn,x,a),x,a))$any1
+ coerce(extend(series,n))$any1
+
+ iPuiseux: (FE,SY,FE) -> Any
+ iPuiseux(fcn,x,a) ==
+ pack := FS2UPS(R,FE,RN,UPXS(FE,x,a),_
+ EFUPXS(FE,ULS(FE,x,a),UPXS(FE,x,a),_
+ EFULS(FE,UTS(FE,x,a),ULS(FE,x,a))),x)
+ ans := exprToUPS(fcn,false,"just do it")$pack
+ ans case %problem =>
+ ans.%problem.prob = "essential singularity" =>
+ error "No Puiseux expansion: essential singularity"
+ ans.%problem.func = "log" =>
+ error "No Puiseux expansion: logarithmic singularity"
+ error "No Puiseux expansion"
+ any1 := ANY1(UPXS(FE,x,a))
+ coerce(ans.%series)$any1
+
+ puiseux(x:SY) ==
+ upxs := UPXS(FE,x,0$FE); any1 := ANY1(upxs)
+ coerce(monomial(1,1)$upxs)$any1
+
+ puiseux(fcn:FE) ==
+ null(vars := variables fcn) =>
+ error "puiseux: expression has no variables"
+ not null rest vars =>
+ error "puiseux: expression has more than one variable"
+ puiseux(fcn,(first(vars) :: FE) = 0)
+
+ puiseux(fcn:FE,n:RN) ==
+ null(vars := variables fcn) =>
+ error "puiseux: expression has no variables"
+ not null rest vars =>
+ error "puiseux: expression has more than one variable"
+ x := first vars
+ upxs := UPXS(FE,x,0$FE); any1 := ANY1(upxs)
+ series := retract(puiseux(fcn,(x :: FE) = 0))$any1
+ coerce(extend(series,n))$any1
+
+ puiseux(fcn:FE,eq:EQ FE) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ iPuiseux(performSubstitution(fcn,x,a),x,a)
+
+ puiseux(fcn,eq,n) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ any1 := ANY1(UPXS(FE,x,a))
+ series := retract(iPuiseux(performSubstitution(fcn,x,a),x,a))$any1
+ coerce(extend(series,n))$any1
+
+ iSeries: (FE,SY,FE) -> Any
+ iSeries(fcn,x,a) ==
+ pack := FS2UPS(R,FE,RN,UPXS(FE,x,a), _
+ EFUPXS(FE,ULS(FE,x,a),UPXS(FE,x,a), _
+ EFULS(FE,UTS(FE,x,a),ULS(FE,x,a))),x)
+ ans := exprToUPS(fcn,false,"just do it")$pack
+ ans case %problem =>
+ ansG := exprToGenUPS(fcn,false,"just do it")$pack
+ ansG case %problem =>
+ ansG.%problem.prob = "essential singularity" =>
+ error "No series expansion: essential singularity"
+ error "No series expansion"
+ anyone := ANY1(GSER(FE,x,a))
+ coerce((ansG.%series) :: GSER(FE,x,a))$anyone
+ any1 := ANY1(UPXS(FE,x,a))
+ coerce(ans.%series)$any1
+
+ series(x:SY) ==
+ upxs := UPXS(FE,x,0$FE); any1 := ANY1(upxs)
+ coerce(monomial(1,1)$upxs)$any1
+
+ series(fcn:FE) ==
+ null(vars := variables fcn) =>
+ error "series: expression has no variables"
+ not null rest vars =>
+ error "series: expression has more than one variable"
+ series(fcn,(first(vars) :: FE) = 0)
+
+ series(fcn:FE,n:RN) ==
+ null(vars := variables fcn) =>
+ error "series: expression has no variables"
+ not null rest vars =>
+ error "series: expression has more than one variable"
+ x := first vars
+ upxs := UPXS(FE,x,0$FE); any1 := ANY1(upxs)
+ series := retract(series(fcn,(x :: FE) = 0))$any1
+ coerce(extend(series,n))$any1
+
+ series(fcn:FE,eq:EQ FE) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ iSeries(performSubstitution(fcn,x,a),x,a)
+
+ series(fcn,eq,n) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ any1 := ANY1(UPXS(FE,x,a))
+ series := retract(iSeries(performSubstitution(fcn,x,a),x,a))$any1
+ coerce(extend(series,n))$any1
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package EXPR2UPS ExpressionToUnivariatePowerSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/exprode.spad.pamphlet b/src/algebra/exprode.spad.pamphlet
new file mode 100644
index 00000000..3aa24347
--- /dev/null
+++ b/src/algebra/exprode.spad.pamphlet
@@ -0,0 +1,255 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra exprode.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package EXPRODE ExpressionSpaceODESolver}
+<<package EXPRODE ExpressionSpaceODESolver>>=
+)abbrev package EXPRODE ExpressionSpaceODESolver
+++ Taylor series solutions of ODE's
+++ Author: Manuel Bronstein
+++ Date Created: 5 Mar 1990
+++ Date Last Updated: 30 September 1993
+++ Description: Taylor series solutions of explicit ODE's;
+++ Keywords: differential equation, ODE, Taylor series
+ExpressionSpaceODESolver(R, F): Exports == Implementation where
+ R: Join(OrderedSet, IntegralDomain, ConvertibleTo InputForm)
+ F: FunctionSpace R
+
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ OP ==> BasicOperator
+ SY ==> Symbol
+ UTS ==> UnivariateTaylorSeries(F, x, center)
+ MKF ==> MakeUnaryCompiledFunction(F, UTS, UTS)
+ MKL ==> MakeUnaryCompiledFunction(F, List UTS, UTS)
+ A1 ==> AnyFunctions1(UTS)
+ AL1 ==> AnyFunctions1(List UTS)
+ EQ ==> Equation F
+ ODE ==> UnivariateTaylorSeriesODESolver(F, UTS)
+
+ Exports ==> with
+ seriesSolve: (EQ, OP, EQ, EQ) -> Any
+ ++ seriesSolve(eq,y,x=a, y a = b) returns a Taylor series solution
+ ++ of eq around x = a with initial condition \spad{y(a) = b}.
+ ++ Note: eq must be of the form
+ ++ \spad{f(x, y x) y'(x) + g(x, y x) = h(x, y x)}.
+ seriesSolve: (EQ, OP, EQ, List F) -> Any
+ ++ seriesSolve(eq,y,x=a,[b0,...,b(n-1)]) returns a Taylor series
+ ++ solution of eq around \spad{x = a} with initial conditions
+ ++ \spad{y(a) = b0}, \spad{y'(a) = b1},
+ ++ \spad{y''(a) = b2}, ...,\spad{y(n-1)(a) = b(n-1)}
+ ++ eq must be of the form
+ ++ \spad{f(x, y x, y'(x),..., y(n-1)(x)) y(n)(x) +
+ ++ g(x,y x,y'(x),...,y(n-1)(x)) = h(x,y x, y'(x),..., y(n-1)(x))}.
+ seriesSolve: (List EQ, List OP, EQ, List EQ) -> Any
+ ++ seriesSolve([eq1,...,eqn],[y1,...,yn],x = a,[y1 a = b1,...,yn a = bn])
+ ++ returns a taylor series solution of \spad{[eq1,...,eqn]} around
+ ++ \spad{x = a} with initial conditions \spad{yi(a) = bi}.
+ ++ Note: eqi must be of the form
+ ++ \spad{fi(x, y1 x, y2 x,..., yn x) y1'(x) +
+ ++ gi(x, y1 x, y2 x,..., yn x) = h(x, y1 x, y2 x,..., yn x)}.
+ seriesSolve: (List EQ, List OP, EQ, List F) -> Any
+ ++ seriesSolve([eq1,...,eqn], [y1,...,yn], x=a, [b1,...,bn])
+ ++ is equivalent to
+ ++ \spad{seriesSolve([eq1,...,eqn], [y1,...,yn], x = a,
+ ++ [y1 a = b1,..., yn a = bn])}.
+ seriesSolve: (List F, List OP, EQ, List F) -> Any
+ ++ seriesSolve([eq1,...,eqn], [y1,...,yn], x=a, [b1,...,bn])
+ ++ is equivalent to
+ ++ \spad{seriesSolve([eq1=0,...,eqn=0], [y1,...,yn], x=a, [b1,...,bn])}.
+ seriesSolve: (List F, List OP, EQ, List EQ) -> Any
+ ++ seriesSolve([eq1,...,eqn], [y1,...,yn], x = a,[y1 a = b1,..., yn a = bn])
+ ++ is equivalent to
+ ++ \spad{seriesSolve([eq1=0,...,eqn=0], [y1,...,yn], x = a,
+ ++ [y1 a = b1,..., yn a = bn])}.
+ seriesSolve: (EQ, OP, EQ, F) -> Any
+ ++ seriesSolve(eq,y, x=a, b) is equivalent to
+ ++ \spad{seriesSolve(eq, y, x=a, y a = b)}.
+ seriesSolve: (F, OP, EQ, F) -> Any
+ ++ seriesSolve(eq, y, x = a, b) is equivalent to
+ ++ \spad{seriesSolve(eq = 0, y, x = a, y a = b)}.
+ seriesSolve: (F, OP, EQ, EQ) -> Any
+ ++ seriesSolve(eq, y, x = a, y a = b) is equivalent to
+ ++ \spad{seriesSolve(eq=0, y, x=a, y a = b)}.
+ seriesSolve: (F, OP, EQ, List F) -> Any
+ ++ seriesSolve(eq, y, x = a, [b0,...,bn]) is equivalent to
+ ++ \spad{seriesSolve(eq = 0, y, x = a, [b0,...,b(n-1)])}.
+
+ Implementation ==> add
+ checkCompat: (OP, EQ, EQ) -> F
+ checkOrder1: (F, OP, K, SY, F) -> F
+ checkOrderN: (F, OP, K, SY, F, NonNegativeInteger) -> F
+ checkSystem: (F, List K, List F) -> F
+ div2exquo : F -> F
+ smp2exquo : P -> F
+ k2exquo : K -> F
+ diffRhs : (F, F) -> F
+ diffRhsK : (K, F) -> F
+ findCompat : (F, List EQ) -> F
+ findEq : (K, SY, List F) -> F
+ localInteger: F -> F
+
+ opelt := operator("elt"::Symbol)$OP
+ --opex := operator("exquo"::Symbol)$OP
+ opex := operator("fixedPointExquo"::Symbol)$OP
+ opint := operator("integer"::Symbol)$OP
+
+ Rint? := R has IntegerNumberSystem
+
+ localInteger n == (Rint? => n; opint n)
+ diffRhs(f, g) == diffRhsK(retract(f)@K, g)
+
+ k2exquo k ==
+ is?(op := operator k, "%diff"::Symbol) =>
+ error "Improper differential equation"
+ kernel(op, [div2exquo f for f in argument k]$List(F))
+
+ smp2exquo p ==
+ map(k2exquo,#1::F,p)$PolynomialCategoryLifting(IndexedExponents K,
+ K, R, P, F)
+
+ div2exquo f ==
+-- one?(d := denom f) => f
+ ((d := denom f) = 1) => f
+ opex(smp2exquo numer f, smp2exquo d)
+
+-- if g is of the form a * k + b, then return -b/a
+ diffRhsK(k, g) ==
+ h := univariate(g, k)
+ (degree(numer h) <= 1) and ground? denom h =>
+ - coefficient(numer h, 0) / coefficient(numer h, 1)
+ error "Improper differential equation"
+
+ checkCompat(y, eqx, eqy) ==
+ lhs(eqy) =$F y(rhs eqx) => rhs eqy
+ error "Improper initial value"
+
+ findCompat(yx, l) ==
+ for eq in l repeat
+ yx =$F lhs eq => return rhs eq
+ error "Improper initial value"
+
+ findEq(k, x, sys) ==
+ k := retract(differentiate(k::F, x))@K
+ for eq in sys repeat
+ member?(k, kernels eq) => return eq
+ error "Improper differential equation"
+
+ checkOrder1(diffeq, y, yx, x, sy) ==
+ div2exquo subst(diffRhs(differentiate(yx::F,x),diffeq),[yx],[sy])
+
+ checkOrderN(diffeq, y, yx, x, sy, n) ==
+ zero? n => error "No initial value(s) given"
+ m := (minIndex(l := [retract(f := yx::F)@K]$List(K)))::F
+ lv := [opelt(sy, localInteger m)]$List(F)
+ for i in 2..n repeat
+ l := concat(retract(f := differentiate(f, x))@K, l)
+ lv := concat(opelt(sy, localInteger(m := m + 1)), lv)
+ div2exquo subst(diffRhs(differentiate(f, x), diffeq), l, lv)
+
+ checkSystem(diffeq, yx, lv) ==
+ for k in kernels diffeq repeat
+ is?(k, "%diff"::SY) =>
+ return div2exquo subst(diffRhsK(k, diffeq), yx, lv)
+ 0
+
+ seriesSolve(l:List EQ, y:List OP, eqx:EQ, eqy:List EQ) ==
+ seriesSolve([lhs deq - rhs deq for deq in l]$List(F), y, eqx, eqy)
+
+ seriesSolve(l:List EQ, y:List OP, eqx:EQ, y0:List F) ==
+ seriesSolve([lhs deq - rhs deq for deq in l]$List(F), y, eqx, y0)
+
+ seriesSolve(l:List F, ly:List OP, eqx:EQ, eqy:List EQ) ==
+ seriesSolve(l, ly, eqx,
+ [findCompat(y rhs eqx, eqy) for y in ly]$List(F))
+
+ seriesSolve(diffeq:EQ, y:OP, eqx:EQ, eqy:EQ) ==
+ seriesSolve(lhs diffeq - rhs diffeq, y, eqx, eqy)
+
+ seriesSolve(diffeq:EQ, y:OP, eqx:EQ, y0:F) ==
+ seriesSolve(lhs diffeq - rhs diffeq, y, eqx, y0)
+
+ seriesSolve(diffeq:EQ, y:OP, eqx:EQ, y0:List F) ==
+ seriesSolve(lhs diffeq - rhs diffeq, y, eqx, y0)
+
+ seriesSolve(diffeq:F, y:OP, eqx:EQ, eqy:EQ) ==
+ seriesSolve(diffeq, y, eqx, checkCompat(y, eqx, eqy))
+
+ seriesSolve(diffeq:F, y:OP, eqx:EQ, y0:F) ==
+ x := symbolIfCan(retract(lhs eqx)@K)::SY
+ sy := name y
+ yx := retract(y lhs eqx)@K
+ f := checkOrder1(diffeq, y, yx, x, sy::F)
+ center := rhs eqx
+ coerce(ode1(compiledFunction(f, sy)$MKF, y0)$ODE)$A1
+
+ seriesSolve(diffeq:F, y:OP, eqx:EQ, y0:List F) ==
+ x := symbolIfCan(retract(lhs eqx)@K)::SY
+ sy := new()$SY
+ yx := retract(y lhs eqx)@K
+ f := checkOrderN(diffeq, y, yx, x, sy::F, #y0)
+ center := rhs eqx
+ coerce(ode(compiledFunction(f, sy)$MKL, y0)$ODE)$A1
+
+ seriesSolve(sys:List F, ly:List OP, eqx:EQ, l0:List F) ==
+ x := symbolIfCan(kx := retract(lhs eqx)@K)::SY
+ fsy := (sy := new()$SY)::F
+ m := (minIndex(l0) - 1)::F
+ yx := concat(kx, [retract(y lhs eqx)@K for y in ly]$List(K))
+ lelt := [opelt(fsy, localInteger(m := m+1)) for k in yx]$List(F)
+ sys := [findEq(k, x, sys) for k in rest yx]
+ l := [checkSystem(eq, yx, lelt) for eq in sys]$List(F)
+ center := rhs eqx
+ coerce(mpsode(l0,[compiledFunction(f,sy)$MKL for f in l])$ODE)$AL1
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package EXPRODE ExpressionSpaceODESolver>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/f01.spad.pamphlet b/src/algebra/f01.spad.pamphlet
new file mode 100644
index 00000000..edbbc356
--- /dev/null
+++ b/src/algebra/f01.spad.pamphlet
@@ -0,0 +1,343 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra f01.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGF01 NagMatrixOperationsPackage}
+<<package NAGF01 NagMatrixOperationsPackage>>=
+)abbrev package NAGF01 NagMatrixOperationsPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:45:15 1994
+++Description:
+++This package uses the NAG Library to provide facilities for matrix factorizations and
+++associated transformations.
+++See \downlink{Manual Page}{manpageXXf01}.
+NagMatrixOperationsPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ f01brf : (Integer,Integer,Integer,Integer,_
+ DoubleFloat,Boolean,Boolean,List Boolean,Matrix DoubleFloat,Matrix Integer,Matrix Integer,Integer) -> Result
+ ++ f01brf(n,nz,licn,lirn,pivot,lblock,grow,abort,a,irn,icn,ifail)
+ ++ factorizes a real sparse matrix. The routine either forms
+ ++ the LU factorization of a permutation of the entire matrix, or,
+ ++ optionally, first permutes the matrix to block lower triangular
+ ++ form and then only factorizes the diagonal blocks.
+ ++ See \downlink{Manual Page}{manpageXXf01brf}.
+ f01bsf : (Integer,Integer,Integer,Matrix Integer,_
+ Matrix Integer,Matrix Integer,Matrix Integer,Boolean,DoubleFloat,Boolean,Matrix Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ f01bsf(n,nz,licn,ivect,jvect,icn,ikeep,grow,eta,abort,idisp,avals,ifail)
+ ++ factorizes a real sparse matrix using the pivotal sequence
+ ++ previously obtained by F01BRF when a matrix of the same sparsity
+ ++ pattern was factorized.
+ ++ See \downlink{Manual Page}{manpageXXf01bsf}.
+ f01maf : (Integer,Integer,Integer,Integer,_
+ List Boolean,Matrix DoubleFloat,Matrix Integer,Matrix Integer,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ f01maf(n,nz,licn,lirn,abort,avals,irn,icn,droptl,densw,ifail)
+ ++ computes an incomplete Cholesky factorization of a real
+ ++ sparse symmetric positive-definite matrix A.
+ ++ See \downlink{Manual Page}{manpageXXf01maf}.
+ f01mcf : (Integer,Matrix DoubleFloat,Integer,Matrix Integer,_
+ Integer) -> Result
+ ++ f01mcf(n,avals,lal,nrow,ifail)
+ ++ computes the Cholesky factorization of a real symmetric
+ ++ positive-definite variable-bandwidth matrix.
+ ++ See \downlink{Manual Page}{manpageXXf01mcf}.
+ f01qcf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Integer) -> Result
+ ++ f01qcf(m,n,lda,a,ifail)
+ ++ finds the QR factorization of the real m by n matrix A,
+ ++ where m>=n.
+ ++ See \downlink{Manual Page}{manpageXXf01qcf}.
+ f01qdf : (String,String,Integer,Integer,_
+ Matrix DoubleFloat,Integer,Matrix DoubleFloat,Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ f01qdf(trans,wheret,m,n,a,lda,zeta,ncolb,ldb,b,ifail)
+ ++ performs one of the transformations
+ ++ See \downlink{Manual Page}{manpageXXf01qdf}.
+ f01qef : (String,Integer,Integer,Integer,_
+ Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ f01qef(wheret,m,n,ncolq,lda,zeta,a,ifail)
+ ++ returns the first ncolq columns of the real m by m
+ ++ orthogonal matrix Q, where Q is given as the product of
+ ++ Householder transformation matrices.
+ ++ See \downlink{Manual Page}{manpageXXf01qef}.
+ f01rcf : (Integer,Integer,Integer,Matrix Complex DoubleFloat,_
+ Integer) -> Result
+ ++ f01rcf(m,n,lda,a,ifail)
+ ++ finds the QR factorization of the complex m by n matrix A,
+ ++ where m>=n.
+ ++ See \downlink{Manual Page}{manpageXXf01rcf}.
+ f01rdf : (String,String,Integer,Integer,_
+ Matrix Complex DoubleFloat,Integer,Matrix Complex DoubleFloat,Integer,Integer,Matrix Complex DoubleFloat,Integer) -> Result
+ ++ f01rdf(trans,wheret,m,n,a,lda,theta,ncolb,ldb,b,ifail)
+ ++ performs one of the transformations
+ ++ See \downlink{Manual Page}{manpageXXf01rdf}.
+ f01ref : (String,Integer,Integer,Integer,_
+ Integer,Matrix Complex DoubleFloat,Matrix Complex DoubleFloat,Integer) -> Result
+ ++ f01ref(wheret,m,n,ncolq,lda,theta,a,ifail)
+ ++ returns the first ncolq columns of the complex m by m
+ ++ unitary matrix Q, where Q is given as the product of Householder
+ ++ transformation matrices.
+ ++ See \downlink{Manual Page}{manpageXXf01ref}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Boolean)
+ import AnyFunctions1(String)
+ import AnyFunctions1(List Boolean)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Matrix Complex DoubleFloat)
+ import AnyFunctions1(Matrix Integer)
+
+
+ f01brf(nArg:Integer,nzArg:Integer,licnArg:Integer,_
+ lirnArg:Integer,pivotArg:DoubleFloat,lblockArg:Boolean,_
+ growArg:Boolean,abortArg:List Boolean,aArg:Matrix DoubleFloat,_
+ irnArg:Matrix Integer,icnArg:Matrix Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01brf",_
+ ["n"::S,"nz"::S,"licn"::S,"lirn"::S,"pivot"::S_
+ ,"lblock"::S,"grow"::S,"ifail"::S,"abort"::S,"ikeep"::S,"w"::S,"idisp"::S,"a"::S_
+ ,"irn"::S,"icn"::S,"iw"::S]$Lisp,_
+ ["ikeep"::S,"w"::S,"idisp"::S,"iw"::S]$Lisp,_
+ [["double"::S,"pivot"::S,["w"::S,"n"::S]$Lisp_
+ ,["a"::S,"licn"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"licn"::S,"lirn"::S_
+ ,["ikeep"::S,["*"::S,5$Lisp,"n"::S]$Lisp]$Lisp,["idisp"::S,10$Lisp]$Lisp,["irn"::S,"lirn"::S]$Lisp,["icn"::S,"licn"::S]$Lisp_
+ ,"ifail"::S,["iw"::S,["*"::S,8$Lisp,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["logical"::S,"lblock"::S,"grow"::S,["abort"::S,4$Lisp]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["ikeep"::S,"w"::S,"idisp"::S,"a"::S,"irn"::S,"icn"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,nzArg::Any,licnArg::Any,lirnArg::Any,pivotArg::Any,lblockArg::Any,growArg::Any,ifailArg::Any,abortArg::Any,aArg::Any,irnArg::Any,icnArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01bsf(nArg:Integer,nzArg:Integer,licnArg:Integer,_
+ ivectArg:Matrix Integer,jvectArg:Matrix Integer,icnArg:Matrix Integer,_
+ ikeepArg:Matrix Integer,growArg:Boolean,etaArg:DoubleFloat,_
+ abortArg:Boolean,idispArg:Matrix Integer,avalsArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01bsf",_
+ ["n"::S,"nz"::S,"licn"::S,"grow"::S,"eta"::S_
+ ,"abort"::S,"rpmin"::S,"ifail"::S,"ivect"::S,"jvect"::S,"icn"::S,"ikeep"::S,"idisp"::S_
+ ,"w"::S,"avals"::S,"iw"::S]$Lisp,_
+ ["w"::S,"rpmin"::S,"iw"::S]$Lisp,_
+ [["double"::S,"eta"::S,["w"::S,"n"::S]$Lisp_
+ ,"rpmin"::S,["avals"::S,"licn"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"licn"::S,["ivect"::S,"nz"::S]$Lisp_
+ ,["jvect"::S,"nz"::S]$Lisp,["icn"::S,"licn"::S]$Lisp,["ikeep"::S,["*"::S,5$Lisp,"n"::S]$Lisp]$Lisp_
+ ,["idisp"::S,2$Lisp]$Lisp,"ifail"::S,["iw"::S,["*"::S,8$Lisp,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["logical"::S,"grow"::S,"abort"::S]$Lisp_
+ ]$Lisp,_
+ ["w"::S,"rpmin"::S,"avals"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,nzArg::Any,licnArg::Any,growArg::Any,etaArg::Any,abortArg::Any,ifailArg::Any,ivectArg::Any,jvectArg::Any,icnArg::Any,ikeepArg::Any,idispArg::Any,avalsArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01maf(nArg:Integer,nzArg:Integer,licnArg:Integer,_
+ lirnArg:Integer,abortArg:List Boolean,avalsArg:Matrix DoubleFloat,_
+ irnArg:Matrix Integer,icnArg:Matrix Integer,droptlArg:DoubleFloat,_
+ denswArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01maf",_
+ ["n"::S,"nz"::S,"licn"::S,"lirn"::S,"droptl"::S_
+ ,"densw"::S,"ifail"::S,"abort"::S,"wkeep"::S,"ikeep"::S,"inform"::S,"avals"::S_
+ ,"irn"::S,"icn"::S,"iwork"::S]$Lisp,_
+ ["wkeep"::S,"ikeep"::S,"inform"::S,"iwork"::S]$Lisp,_
+ [["double"::S,["wkeep"::S,["*"::S,3$Lisp,"n"::S]$Lisp]$Lisp_
+ ,["avals"::S,"licn"::S]$Lisp,"droptl"::S,"densw"::S]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"licn"::S,"lirn"::S_
+ ,["ikeep"::S,["*"::S,2$Lisp,"n"::S]$Lisp]$Lisp,["inform"::S,4$Lisp]$Lisp,["irn"::S,"lirn"::S]$Lisp,["icn"::S,"licn"::S]$Lisp_
+ ,"ifail"::S,["iwork"::S,["*"::S,6$Lisp,"n"::S]$Lisp]$Lisp]$Lisp_
+ ,["logical"::S,["abort"::S,3$Lisp]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["wkeep"::S,"ikeep"::S,"inform"::S,"avals"::S,"irn"::S,"icn"::S,"droptl"::S,"densw"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,nzArg::Any,licnArg::Any,lirnArg::Any,droptlArg::Any,denswArg::Any,ifailArg::Any,abortArg::Any,avalsArg::Any,irnArg::Any,icnArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01mcf(nArg:Integer,avalsArg:Matrix DoubleFloat,lalArg:Integer,_
+ nrowArg:Matrix Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01mcf",_
+ ["n"::S,"lal"::S,"ifail"::S,"avals"::S,"nrow"::S,"al"::S,"d"::S]$Lisp,_
+ ["al"::S,"d"::S]$Lisp,_
+ [["double"::S,["avals"::S,"lal"::S]$Lisp,["al"::S,"lal"::S]$Lisp_
+ ,["d"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"lal"::S,["nrow"::S,"n"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["al"::S,"d"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,lalArg::Any,ifailArg::Any,avalsArg::Any,nrowArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01qcf(mArg:Integer,nArg:Integer,ldaArg:Integer,_
+ aArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01qcf",_
+ ["m"::S,"n"::S,"lda"::S,"ifail"::S,"zeta"::S,"a"::S]$Lisp,_
+ ["zeta"::S]$Lisp,_
+ [["double"::S,["zeta"::S,"n"::S]$Lisp,["a"::S,"lda"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"lda"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["zeta"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ldaArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01qdf(transArg:String,wheretArg:String,mArg:Integer,_
+ nArg:Integer,aArg:Matrix DoubleFloat,ldaArg:Integer,_
+ zetaArg:Matrix DoubleFloat,ncolbArg:Integer,ldbArg:Integer,_
+ bArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01qdf",_
+ ["trans"::S,"wheret"::S,"m"::S,"n"::S,"lda"::S_
+ ,"ncolb"::S,"ldb"::S,"ifail"::S,"a"::S,"zeta"::S,"b"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["a"::S,"lda"::S,"n"::S]$Lisp_
+ ,["zeta"::S,"n"::S]$Lisp,["b"::S,"ldb"::S,"ncolb"::S]$Lisp,["work"::S,"ncolb"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"lda"::S,"ncolb"::S_
+ ,"ldb"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"trans"::S,"wheret"::S]$Lisp_
+ ]$Lisp,_
+ ["b"::S,"ifail"::S]$Lisp,_
+ [([transArg::Any,wheretArg::Any,mArg::Any,nArg::Any,ldaArg::Any,ncolbArg::Any,ldbArg::Any,ifailArg::Any,aArg::Any,zetaArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01qef(wheretArg:String,mArg:Integer,nArg:Integer,_
+ ncolqArg:Integer,ldaArg:Integer,zetaArg:Matrix DoubleFloat,_
+ aArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01qef",_
+ ["wheret"::S,"m"::S,"n"::S,"ncolq"::S,"lda"::S_
+ ,"ifail"::S,"zeta"::S,"a"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["zeta"::S,"n"::S]$Lisp,["a"::S,"lda"::S,"ncolq"::S]$Lisp_
+ ,["work"::S,"ncolq"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"ncolq"::S,"lda"::S_
+ ,"ifail"::S]$Lisp_
+ ,["character"::S,"wheret"::S]$Lisp_
+ ]$Lisp,_
+ ["a"::S,"ifail"::S]$Lisp,_
+ [([wheretArg::Any,mArg::Any,nArg::Any,ncolqArg::Any,ldaArg::Any,ifailArg::Any,zetaArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01rcf(mArg:Integer,nArg:Integer,ldaArg:Integer,_
+ aArg:Matrix Complex DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01rcf",_
+ ["m"::S,"n"::S,"lda"::S,"ifail"::S,"theta"::S,"a"::S]$Lisp,_
+ ["theta"::S]$Lisp,_
+ [["integer"::S,"m"::S,"n"::S,"lda"::S,"ifail"::S_
+ ]$Lisp_
+ ,["double complex"::S,["theta"::S,"n"::S]$Lisp,["a"::S,"lda"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["theta"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ldaArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01rdf(transArg:String,wheretArg:String,mArg:Integer,_
+ nArg:Integer,aArg:Matrix Complex DoubleFloat,ldaArg:Integer,_
+ thetaArg:Matrix Complex DoubleFloat,ncolbArg:Integer,ldbArg:Integer,_
+ bArg:Matrix Complex DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01rdf",_
+ ["trans"::S,"wheret"::S,"m"::S,"n"::S,"lda"::S_
+ ,"ncolb"::S,"ldb"::S,"ifail"::S,"a"::S,"theta"::S,"b"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["integer"::S,"m"::S,"n"::S,"lda"::S,"ncolb"::S_
+ ,"ldb"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"trans"::S,"wheret"::S]$Lisp_
+ ,["double complex"::S,["a"::S,"lda"::S,"n"::S]$Lisp,["theta"::S,"n"::S]$Lisp,["b"::S,"ldb"::S,"ncolb"::S]$Lisp,["work"::S,"ncolb"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["b"::S,"ifail"::S]$Lisp,_
+ [([transArg::Any,wheretArg::Any,mArg::Any,nArg::Any,ldaArg::Any,ncolbArg::Any,ldbArg::Any,ifailArg::Any,aArg::Any,thetaArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f01ref(wheretArg:String,mArg:Integer,nArg:Integer,_
+ ncolqArg:Integer,ldaArg:Integer,thetaArg:Matrix Complex DoubleFloat,_
+ aArg:Matrix Complex DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f01ref",_
+ ["wheret"::S,"m"::S,"n"::S,"ncolq"::S,"lda"::S_
+ ,"ifail"::S,"theta"::S,"a"::S,"work"::S]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["integer"::S,"m"::S,"n"::S,"ncolq"::S,"lda"::S_
+ ,"ifail"::S]$Lisp_
+ ,["character"::S,"wheret"::S]$Lisp_
+ ,["double complex"::S,["theta"::S,"n"::S]$Lisp,["a"::S,"lda"::S,"n"::S]$Lisp,["work"::S,"ncolq"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["a"::S,"ifail"::S]$Lisp,_
+ [([wheretArg::Any,mArg::Any,nArg::Any,ncolqArg::Any,ldaArg::Any,ifailArg::Any,thetaArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGF01 NagMatrixOperationsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/f02.spad.pamphlet b/src/algebra/f02.spad.pamphlet
new file mode 100644
index 00000000..e5db779d
--- /dev/null
+++ b/src/algebra/f02.spad.pamphlet
@@ -0,0 +1,565 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra f02.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGF02 NagEigenPackage}
+<<package NAGF02 NagEigenPackage>>=
+)abbrev package NAGF02 NagEigenPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:45:20 1994
+++Description:
+++This package uses the NAG Library to compute
+++\begin{items}
+++\item eigenvalues and eigenvectors of a matrix
+++\item eigenvalues and eigenvectors of generalized matrix
+++eigenvalue problems
+++\item singular values and singular vectors of a matrix.
+++\end{items}
+++See \downlink{Manual Page}{manpageXXf02}.
+
+NagEigenPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ f02aaf : (Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ f02aaf(ia,n,a,ifail)
+ ++ calculates all the eigenvalue.
+ ++ See \downlink{Manual Page}{manpageXXf02aaf}.
+ f02abf : (Matrix DoubleFloat,Integer,Integer,Integer,_
+ Integer) -> Result
+ ++ f02abf(a,ia,n,iv,ifail)
+ ++ calculates all the eigenvalues of a real
+ ++ symmetric matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02abf}.
+ f02adf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ f02adf(ia,ib,n,a,b,ifail)
+ ++ calculates all the eigenvalues of Ax=(lambda)Bx, where A
+ ++ is a real symmetric matrix and B is a real symmetric positive-
+ ++ definite matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02adf}.
+ f02aef : (Integer,Integer,Integer,Integer,_
+ Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ f02aef(ia,ib,n,iv,a,b,ifail)
+ ++ calculates all the eigenvalues of
+ ++ Ax=(lambda)Bx, where A is a real symmetric matrix and B is a
+ ++ real symmetric positive-definite matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02aef}.
+ f02aff : (Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ f02aff(ia,n,a,ifail)
+ ++ calculates all the eigenvalues of a real unsymmetric
+ ++ matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02aff}.
+ f02agf : (Integer,Integer,Integer,Integer,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ f02agf(ia,n,ivr,ivi,a,ifail)
+ ++ calculates all the eigenvalues of a real
+ ++ unsymmetric matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02agf}.
+ f02ajf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ f02ajf(iar,iai,n,ar,ai,ifail)
+ ++ calculates all the eigenvalue.
+ ++ See \downlink{Manual Page}{manpageXXf02ajf}.
+ f02akf : (Integer,Integer,Integer,Integer,_
+ Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ f02akf(iar,iai,n,ivr,ivi,ar,ai,ifail)
+ ++ calculates all the eigenvalues of a
+ ++ complex matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02akf}.
+ f02awf : (Integer,Integer,Integer,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ f02awf(iar,iai,n,ar,ai,ifail)
+ ++ calculates all the eigenvalues of a complex Hermitian
+ ++ matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02awf}.
+ f02axf : (Matrix DoubleFloat,Integer,Matrix DoubleFloat,Integer,_
+ Integer,Integer,Integer,Integer) -> Result
+ ++ f02axf(ar,iar,ai,iai,n,ivr,ivi,ifail)
+ ++ calculates all the eigenvalues of a
+ ++ complex Hermitian matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02axf}.
+ f02bbf : (Integer,Integer,DoubleFloat,DoubleFloat,_
+ Integer,Integer,Matrix DoubleFloat,Integer) -> Result
+ ++ f02bbf(ia,n,alb,ub,m,iv,a,ifail)
+ ++ calculates selected eigenvalues of a real
+ ++ symmetric matrix by reduction to tridiagonal form, bisection and
+ ++ inverse iteration, where the selected eigenvalues lie within a
+ ++ given interval.
+ ++ See \downlink{Manual Page}{manpageXXf02bbf}.
+ f02bjf : (Integer,Integer,Integer,DoubleFloat,_
+ Boolean,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ f02bjf(n,ia,ib,eps1,matv,iv,a,b,ifail)
+ ++ calculates all the eigenvalues and, if required, all the
+ ++ eigenvectors of the generalized eigenproblem Ax=(lambda)Bx
+ ++ where A and B are real, square matrices, using the QZ algorithm.
+ ++ See \downlink{Manual Page}{manpageXXf02bjf}.
+ f02fjf : (Integer,Integer,DoubleFloat,Integer,_
+ Integer,Integer,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp27(DOT)),Union(fn:FileName,fp:Asp28(IMAGE))) -> Result
+ ++ f02fjf(n,k,tol,novecs,nrx,lwork,lrwork,liwork,m,noits,x,ifail,dot,image)
+ ++ finds eigenvalues of a real sparse symmetric
+ ++ or generalized symmetric eigenvalue problem.
+ ++ See \downlink{Manual Page}{manpageXXf02fjf}.
+ f02fjf : (Integer,Integer,DoubleFloat,Integer,_
+ Integer,Integer,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp27(DOT)),Union(fn:FileName,fp:Asp28(IMAGE)),FileName) -> Result
+ ++ f02fjf(n,k,tol,novecs,nrx,lwork,lrwork,liwork,m,noits,x,ifail,dot,image,monit)
+ ++ finds eigenvalues of a real sparse symmetric
+ ++ or generalized symmetric eigenvalue problem.
+ ++ See \downlink{Manual Page}{manpageXXf02fjf}.
+ f02wef : (Integer,Integer,Integer,Integer,_
+ Integer,Boolean,Integer,Boolean,Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ f02wef(m,n,lda,ncolb,ldb,wantq,ldq,wantp,ldpt,a,b,ifail)
+ ++ returns all, or part, of the singular value decomposition
+ ++ of a general real matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02wef}.
+ f02xef : (Integer,Integer,Integer,Integer,_
+ Integer,Boolean,Integer,Boolean,Integer,Matrix Complex DoubleFloat,Matrix Complex DoubleFloat,Integer) -> Result
+ ++ f02xef(m,n,lda,ncolb,ldb,wantq,ldq,wantp,ldph,a,b,ifail)
+ ++ returns all, or part, of the singular value decomposition
+ ++ of a general complex matrix.
+ ++ See \downlink{Manual Page}{manpageXXf02xef}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import FortranPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(Boolean)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Matrix Complex DoubleFloat)
+ import AnyFunctions1(DoubleFloat)
+
+
+ f02aaf(iaArg:Integer,nArg:Integer,aArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02aaf",_
+ ["ia"::S,"n"::S,"ifail"::S,"r"::S,"a"::S,"e"::S]$Lisp,_
+ ["r"::S,"e"::S]$Lisp,_
+ [["double"::S,["r"::S,"n"::S]$Lisp,["a"::S,"ia"::S,"n"::S]$Lisp_
+ ,["e"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["r"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02abf(aArg:Matrix DoubleFloat,iaArg:Integer,nArg:Integer,_
+ ivArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02abf",_
+ ["ia"::S,"n"::S,"iv"::S,"ifail"::S,"a"::S,"r"::S,"v"::S,"e"::S]$Lisp,_
+ ["r"::S,"v"::S,"e"::S]$Lisp,_
+ [["double"::S,["a"::S,"ia"::S,"n"::S]$Lisp_
+ ,["r"::S,"n"::S]$Lisp,["v"::S,"iv"::S,"n"::S]$Lisp,["e"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"iv"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["r"::S,"v"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,ivArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02adf(iaArg:Integer,ibArg:Integer,nArg:Integer,_
+ aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02adf",_
+ ["ia"::S,"ib"::S,"n"::S,"ifail"::S,"r"::S,"a"::S,"b"::S,"de"::S]$Lisp,_
+ ["r"::S,"de"::S]$Lisp,_
+ [["double"::S,["r"::S,"n"::S]$Lisp,["a"::S,"ia"::S,"n"::S]$Lisp_
+ ,["b"::S,"ib"::S,"n"::S]$Lisp,["de"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"ib"::S,"n"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["r"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,ibArg::Any,nArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02aef(iaArg:Integer,ibArg:Integer,nArg:Integer,_
+ ivArg:Integer,aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02aef",_
+ ["ia"::S,"ib"::S,"n"::S,"iv"::S,"ifail"::S_
+ ,"r"::S,"v"::S,"a"::S,"b"::S,"dl"::S_
+ ,"e"::S]$Lisp,_
+ ["r"::S,"v"::S,"dl"::S,"e"::S]$Lisp,_
+ [["double"::S,["r"::S,"n"::S]$Lisp,["v"::S,"iv"::S,"n"::S]$Lisp_
+ ,["a"::S,"ia"::S,"n"::S]$Lisp,["b"::S,"ib"::S,"n"::S]$Lisp,["dl"::S,"n"::S]$Lisp,["e"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"ia"::S,"ib"::S,"n"::S,"iv"::S_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["r"::S,"v"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,ibArg::Any,nArg::Any,ivArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02aff(iaArg:Integer,nArg:Integer,aArg:Matrix DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02aff",_
+ ["ia"::S,"n"::S,"ifail"::S,"rr"::S,"ri"::S,"intger"::S,"a"::S]$Lisp,_
+ ["rr"::S,"ri"::S,"intger"::S]$Lisp,_
+ [["double"::S,["rr"::S,"n"::S]$Lisp,["ri"::S,"n"::S]$Lisp_
+ ,["a"::S,"ia"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,["intger"::S,"n"::S]$Lisp_
+ ,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["rr"::S,"ri"::S,"intger"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02agf(iaArg:Integer,nArg:Integer,ivrArg:Integer,_
+ iviArg:Integer,aArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02agf",_
+ ["ia"::S,"n"::S,"ivr"::S,"ivi"::S,"ifail"::S_
+ ,"rr"::S,"ri"::S,"vr"::S,"vi"::S,"intger"::S_
+ ,"a"::S]$Lisp,_
+ ["rr"::S,"ri"::S,"vr"::S,"vi"::S,"intger"::S]$Lisp,_
+ [["double"::S,["rr"::S,"n"::S]$Lisp,["ri"::S,"n"::S]$Lisp_
+ ,["vr"::S,"ivr"::S,"n"::S]$Lisp,["vi"::S,"ivi"::S,"n"::S]$Lisp,["a"::S,"ia"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"ivr"::S,"ivi"::S_
+ ,["intger"::S,"n"::S]$Lisp,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["rr"::S,"ri"::S,"vr"::S,"vi"::S,"intger"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,ivrArg::Any,iviArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02ajf(iarArg:Integer,iaiArg:Integer,nArg:Integer,_
+ arArg:Matrix DoubleFloat,aiArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02ajf",_
+ ["iar"::S,"iai"::S,"n"::S,"ifail"::S,"rr"::S,"ri"::S,"ar"::S,"ai"::S,"intger"::S_
+ ]$Lisp,_
+ ["rr"::S,"ri"::S,"intger"::S]$Lisp,_
+ [["double"::S,["rr"::S,"n"::S]$Lisp,["ri"::S,"n"::S]$Lisp_
+ ,["ar"::S,"iar"::S,"n"::S]$Lisp,["ai"::S,"iai"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"iar"::S,"iai"::S,"n"::S,"ifail"::S_
+ ,["intger"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["rr"::S,"ri"::S,"ar"::S,"ai"::S,"ifail"::S]$Lisp,_
+ [([iarArg::Any,iaiArg::Any,nArg::Any,ifailArg::Any,arArg::Any,aiArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02akf(iarArg:Integer,iaiArg:Integer,nArg:Integer,_
+ ivrArg:Integer,iviArg:Integer,arArg:Matrix DoubleFloat,_
+ aiArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02akf",_
+ ["iar"::S,"iai"::S,"n"::S,"ivr"::S,"ivi"::S_
+ ,"ifail"::S,"rr"::S,"ri"::S,"vr"::S,"vi"::S,"ar"::S_
+ ,"ai"::S,"intger"::S]$Lisp,_
+ ["rr"::S,"ri"::S,"vr"::S,"vi"::S,"intger"::S]$Lisp,_
+ [["double"::S,["rr"::S,"n"::S]$Lisp,["ri"::S,"n"::S]$Lisp_
+ ,["vr"::S,"ivr"::S,"n"::S]$Lisp,["vi"::S,"ivi"::S,"n"::S]$Lisp,["ar"::S,"iar"::S,"n"::S]$Lisp,["ai"::S,"iai"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"iar"::S,"iai"::S,"n"::S,"ivr"::S_
+ ,"ivi"::S,"ifail"::S,["intger"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["rr"::S,"ri"::S,"vr"::S,"vi"::S,"ar"::S,"ai"::S,"ifail"::S]$Lisp,_
+ [([iarArg::Any,iaiArg::Any,nArg::Any,ivrArg::Any,iviArg::Any,ifailArg::Any,arArg::Any,aiArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02awf(iarArg:Integer,iaiArg:Integer,nArg:Integer,_
+ arArg:Matrix DoubleFloat,aiArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02awf",_
+ ["iar"::S,"iai"::S,"n"::S,"ifail"::S,"r"::S,"ar"::S,"ai"::S,"wk1"::S,"wk2"::S_
+ ,"wk3"::S]$Lisp,_
+ ["r"::S,"wk1"::S,"wk2"::S,"wk3"::S]$Lisp,_
+ [["double"::S,["r"::S,"n"::S]$Lisp,["ar"::S,"iar"::S,"n"::S]$Lisp_
+ ,["ai"::S,"iai"::S,"n"::S]$Lisp,["wk1"::S,"n"::S]$Lisp,["wk2"::S,"n"::S]$Lisp,["wk3"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"iar"::S,"iai"::S,"n"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["r"::S,"ar"::S,"ai"::S,"ifail"::S]$Lisp,_
+ [([iarArg::Any,iaiArg::Any,nArg::Any,ifailArg::Any,arArg::Any,aiArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02axf(arArg:Matrix DoubleFloat,iarArg:Integer,aiArg:Matrix DoubleFloat,_
+ iaiArg:Integer,nArg:Integer,ivrArg:Integer,_
+ iviArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02axf",_
+ ["iar"::S,"iai"::S,"n"::S,"ivr"::S,"ivi"::S_
+ ,"ifail"::S,"ar"::S,"ai"::S,"r"::S,"vr"::S,"vi"::S_
+ ,"wk1"::S,"wk2"::S,"wk3"::S]$Lisp,_
+ ["r"::S,"vr"::S,"vi"::S,"wk1"::S,"wk2"::S,"wk3"::S]$Lisp,_
+ [["double"::S,["ar"::S,"iar"::S,"n"::S]$Lisp_
+ ,["ai"::S,"iai"::S,"n"::S]$Lisp,["r"::S,"n"::S]$Lisp,["vr"::S,"ivr"::S,"n"::S]$Lisp,["vi"::S,"ivi"::S,"n"::S]$Lisp,["wk1"::S,"n"::S]$Lisp_
+ ,["wk2"::S,"n"::S]$Lisp,["wk3"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"iar"::S,"iai"::S,"n"::S,"ivr"::S_
+ ,"ivi"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["r"::S,"vr"::S,"vi"::S,"ifail"::S]$Lisp,_
+ [([iarArg::Any,iaiArg::Any,nArg::Any,ivrArg::Any,iviArg::Any,ifailArg::Any,arArg::Any,aiArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02bbf(iaArg:Integer,nArg:Integer,albArg:DoubleFloat,_
+ ubArg:DoubleFloat,mArg:Integer,ivArg:Integer,_
+ aArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02bbf",_
+ ["ia"::S,"n"::S,"alb"::S,"ub"::S,"m"::S_
+ ,"iv"::S,"mm"::S,"ifail"::S,"r"::S,"v"::S,"icount"::S,"a"::S,"d"::S_
+ ,"e"::S,"e2"::S,"x"::S,"g"::S,"c"::S_
+ ]$Lisp,_
+ ["mm"::S,"r"::S,"v"::S,"icount"::S,"d"::S,"e"::S,"e2"::S,"x"::S,"g"::S,"c"::S]$Lisp,_
+ [["double"::S,"alb"::S,"ub"::S,["r"::S,"m"::S]$Lisp_
+ ,["v"::S,"iv"::S,"m"::S]$Lisp,["a"::S,"ia"::S,"n"::S]$Lisp,["d"::S,"n"::S]$Lisp,["e"::S,"n"::S]$Lisp,["e2"::S,"n"::S]$Lisp_
+ ,["x"::S,"n"::S,7$Lisp]$Lisp,["g"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"m"::S,"iv"::S_
+ ,"mm"::S,["icount"::S,"m"::S]$Lisp,"ifail"::S]$Lisp_
+ ,["logical"::S,["c"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["mm"::S,"r"::S,"v"::S,"icount"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,albArg::Any,ubArg::Any,mArg::Any,ivArg::Any,ifailArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02bjf(nArg:Integer,iaArg:Integer,ibArg:Integer,_
+ eps1Arg:DoubleFloat,matvArg:Boolean,ivArg:Integer,_
+ aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f02bjf",_
+ ["n"::S,"ia"::S,"ib"::S,"eps1"::S,"matv"::S_
+ ,"iv"::S,"ifail"::S,"alfr"::S,"alfi"::S,"beta"::S,"v"::S,"iter"::S_
+ ,"a"::S,"b"::S]$Lisp,_
+ ["alfr"::S,"alfi"::S,"beta"::S,"v"::S,"iter"::S]$Lisp,_
+ [["double"::S,"eps1"::S,["alfr"::S,"n"::S]$Lisp_
+ ,["alfi"::S,"n"::S]$Lisp,["beta"::S,"n"::S]$Lisp,["v"::S,"iv"::S,"n"::S]$Lisp,["a"::S,"ia"::S,"n"::S]$Lisp,["b"::S,"ib"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"n"::S,"ia"::S,"ib"::S,"iv"::S_
+ ,["iter"::S,"n"::S]$Lisp,"ifail"::S]$Lisp_
+ ,["logical"::S,"matv"::S]$Lisp_
+ ]$Lisp,_
+ ["alfr"::S,"alfi"::S,"beta"::S,"v"::S,"iter"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,iaArg::Any,ibArg::Any,eps1Arg::Any,matvArg::Any,ivArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02fjf(nArg:Integer,kArg:Integer,tolArg:DoubleFloat,_
+ novecsArg:Integer,nrxArg:Integer,lworkArg:Integer,_
+ lrworkArg:Integer,liworkArg:Integer,mArg:Integer,_
+ noitsArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer,_
+ dotArg:Union(fn:FileName,fp:Asp27(DOT)),imageArg:Union(fn:FileName,fp:Asp28(IMAGE))): Result ==
+ pushFortranOutputStack(dotFilename := aspFilename "dot")$FOP
+ if dotArg case fn
+ then outputAsFortran(dotArg.fn)
+ else outputAsFortran(dotArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(imageFilename := aspFilename "image")$FOP
+ if imageArg case fn
+ then outputAsFortran(imageArg.fn)
+ else outputAsFortran(imageArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(monitFilename := aspFilename "monit")$FOP
+ outputAsFortran()$Asp29(MONIT)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([dotFilename,imageFilename,monitFilename]$Lisp,_
+ "f02fjf",_
+ ["n"::S,"k"::S,"tol"::S,"novecs"::S,"nrx"::S_
+ ,"lwork"::S,"lrwork"::S,"liwork"::S,"m"::S,"noits"::S_
+ ,"ifail"::S,"dot"::S,"image"::S,"monit"::S,"d"::S,"x"::S,"work"::S,"rwork"::S,"iwork"::S_
+ ]$Lisp,_
+ ["d"::S,"work"::S,"rwork"::S,"iwork"::S,"dot"::S,"image"::S,"monit"::S]$Lisp,_
+ [["double"::S,"tol"::S,["d"::S,"k"::S]$Lisp_
+ ,["x"::S,"nrx"::S,"k"::S]$Lisp,["work"::S,"lwork"::S]$Lisp,["rwork"::S,"lrwork"::S]$Lisp,"dot"::S,"image"::S,"monit"::S_
+ ]$Lisp_
+ ,["integer"::S,"n"::S,"k"::S,"novecs"::S,"nrx"::S_
+ ,"lwork"::S,"lrwork"::S,"liwork"::S,"m"::S,"noits"::S,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["d"::S,"m"::S,"noits"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,kArg::Any,tolArg::Any,novecsArg::Any,nrxArg::Any,lworkArg::Any,lrworkArg::Any,liworkArg::Any,mArg::Any,noitsArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02fjf(nArg:Integer,kArg:Integer,tolArg:DoubleFloat,_
+ novecsArg:Integer,nrxArg:Integer,lworkArg:Integer,_
+ lrworkArg:Integer,liworkArg:Integer,mArg:Integer,_
+ noitsArg:Integer,xArg:Matrix DoubleFloat,ifailArg:Integer,_
+ dotArg:Union(fn:FileName,fp:Asp27(DOT)),imageArg:Union(fn:FileName,fp:Asp28(IMAGE)),monitArg:FileName): Result ==
+ pushFortranOutputStack(dotFilename := aspFilename "dot")$FOP
+ if dotArg case fn
+ then outputAsFortran(dotArg.fn)
+ else outputAsFortran(dotArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(imageFilename := aspFilename "image")$FOP
+ if imageArg case fn
+ then outputAsFortran(imageArg.fn)
+ else outputAsFortran(imageArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(monitFilename := aspFilename "monit")$FOP
+ outputAsFortran(monitArg)
+ [(invokeNagman([dotFilename,imageFilename,monitFilename]$Lisp,_
+ "f02fjf",_
+ ["n"::S,"k"::S,"tol"::S,"novecs"::S,"nrx"::S_
+ ,"lwork"::S,"lrwork"::S,"liwork"::S,"m"::S,"noits"::S_
+ ,"ifail"::S,"dot"::S,"image"::S,"monit"::S,"d"::S,"x"::S,"work"::S,"rwork"::S,"iwork"::S_
+ ]$Lisp,_
+ ["d"::S,"work"::S,"rwork"::S,"iwork"::S,"dot"::S,"image"::S,"monit"::S]$Lisp,_
+ [["double"::S,"tol"::S,["d"::S,"k"::S]$Lisp_
+ ,["x"::S,"nrx"::S,"k"::S]$Lisp,["work"::S,"lwork"::S]$Lisp,["rwork"::S,"lrwork"::S]$Lisp,"dot"::S,"image"::S,"monit"::S_
+ ]$Lisp_
+ ,["integer"::S,"n"::S,"k"::S,"novecs"::S,"nrx"::S_
+ ,"lwork"::S,"lrwork"::S,"liwork"::S,"m"::S,"noits"::S,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["d"::S,"m"::S,"noits"::S,"x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,kArg::Any,tolArg::Any,novecsArg::Any,nrxArg::Any,lworkArg::Any,lrworkArg::Any,liworkArg::Any,mArg::Any,noitsArg::Any,ifailArg::Any,xArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02wef(mArg:Integer,nArg:Integer,ldaArg:Integer,_
+ ncolbArg:Integer,ldbArg:Integer,wantqArg:Boolean,_
+ ldqArg:Integer,wantpArg:Boolean,ldptArg:Integer,_
+ aArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ workLength : Integer :=
+ mArg >= nArg =>
+ wantqArg and wantpArg =>
+ max(max(nArg**2 + 5*(nArg - 1),nArg + ncolbArg),4)
+ wantqArg =>
+ max(max(nArg**2 + 4*(nArg - 1),nArg + ncolbArg),4)
+ wantpArg =>
+ zero? ncolbArg => max(3*(nArg - 1),2)
+ max(5*(nArg - 1),2)
+ zero? ncolbArg => max(2*(nArg - 1),2)
+ max(3*(nArg - 1),2)
+ wantqArg and wantpArg =>
+ max(mArg**2 + 5*(mArg - 1),2)
+ wantqArg =>
+ max(3*(mArg - 1),1)
+ wantpArg =>
+ zero? ncolbArg => max(mArg**2+3*(mArg - 1),2)
+ max(mArg**2+5*(mArg - 1),2)
+ zero? ncolbArg => max(2*(mArg - 1),1)
+ max(3*(mArg - 1),1)
+
+ [(invokeNagman(NIL$Lisp,_
+ "f02wef",_
+ ["m"::S,"n"::S,"lda"::S,"ncolb"::S,"ldb"::S_
+ ,"wantq"::S,"ldq"::S,"wantp"::S,"ldpt"::S,"ifail"::S_
+ ,"q"::S,"sv"::S,"pt"::S,"work"::S,"a"::S_
+ ,"b"::S]$Lisp,_
+ ["q"::S,"sv"::S,"pt"::S,"work"::S]$Lisp,_
+ [["double"::S,["q"::S,"ldq"::S,"m"::S]$Lisp_
+ ,["sv"::S,"m"::S]$Lisp,["pt"::S,"ldpt"::S,"n"::S]$Lisp,["work"::S,workLength]$Lisp,["a"::S,"lda"::S,"n"::S]$Lisp,["b"::S,"ldb"::S,"ncolb"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"lda"::S,"ncolb"::S_
+ ,"ldb"::S,"ldq"::S,"ldpt"::S,"ifail"::S]$Lisp_
+ ,["logical"::S,"wantq"::S,"wantp"::S]$Lisp_
+ ]$Lisp,_
+ ["q"::S,"sv"::S,"pt"::S,"work"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ldaArg::Any,ncolbArg::Any,ldbArg::Any,wantqArg::Any,ldqArg::Any,wantpArg::Any,ldptArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f02xef(mArg:Integer,nArg:Integer,ldaArg:Integer,_
+ ncolbArg:Integer,ldbArg:Integer,wantqArg:Boolean,_
+ ldqArg:Integer,wantpArg:Boolean,ldphArg:Integer,_
+ aArg:Matrix Complex DoubleFloat,bArg:Matrix Complex DoubleFloat,ifailArg:Integer): Result ==
+ -- This segment added by hand, to deal with an assumed size array GDN
+ tem : Integer := (min(mArg,nArg)-1)
+ rLen : Integer :=
+ zero? ncolbArg and not wantqArg and not wantpArg => 2*tem
+ zero? ncolbArg and wantpArg and not wantqArg => 3*tem
+ not wantpArg =>
+ ncolbArg >0 or wantqArg => 3*tem
+ 5*tem
+ cLen : Integer :=
+ mArg >= nArg =>
+ wantqArg and wantpArg => 2*(nArg + max(nArg**2,ncolbArg))
+ wantqArg and not wantpArg => 2*(nArg + max(nArg**2+nArg,ncolbArg))
+ 2*(nArg + max(nArg,ncolbArg))
+ wantpArg => 2*(mArg**2 + mArg)
+ 2*mArg
+ svLength : Integer :=
+ min(mArg,nArg)
+ [(invokeNagman(NIL$Lisp,_
+ "f02xef",_
+ ["m"::S,"n"::S,"lda"::S,"ncolb"::S,"ldb"::S_
+ ,"wantq"::S,"ldq"::S,"wantp"::S,"ldph"::S,"ifail"::S_
+ ,"q"::S,"sv"::S,"ph"::S,"rwork"::S,"a"::S_
+ ,"b"::S,"cwork"::S]$Lisp,_
+ ["q"::S,"sv"::S,"ph"::S,"rwork"::S,"cwork"::S]$Lisp,_
+ [["double"::S,["sv"::S,svLength]$Lisp,["rwork"::S,rLen]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"lda"::S,"ncolb"::S_
+ ,"ldb"::S,"ldq"::S,"ldph"::S,"ifail"::S]$Lisp_
+ ,["logical"::S,"wantq"::S,"wantp"::S]$Lisp_
+ ,["double complex"::S,["q"::S,"ldq"::S,"m"::S]$Lisp,["ph"::S,"ldph"::S,"n"::S]$Lisp,["a"::S,"lda"::S,"n"::S]$Lisp,["b"::S,"ldb"::S,"ncolb"::S]$Lisp,["cwork"::S,cLen]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["q"::S,"sv"::S,"ph"::S,"rwork"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ldaArg::Any,ncolbArg::Any,ldbArg::Any,wantqArg::Any,ldqArg::Any,wantpArg::Any,ldphArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGF02 NagEigenPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/f04.spad.pamphlet b/src/algebra/f04.spad.pamphlet
new file mode 100644
index 00000000..8be3d92f
--- /dev/null
+++ b/src/algebra/f04.spad.pamphlet
@@ -0,0 +1,408 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra f04.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGF04 NagLinearEquationSolvingPackage}
+<<package NAGF04 NagLinearEquationSolvingPackage>>=
+)abbrev package NAGF04 NagLinearEquationSolvingPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:45:31 1994
+++Description:
+++This package uses the NAG Library to solve the matrix equation \axiom{AX=B}, where \axiom{B}
+++may be a single vector or a matrix of multiple right-hand sides.
+++The matrix \axiom{A} may be real, complex, symmetric, Hermitian positive-
+++definite, or sparse. It may also be rectangular, in which case a
+++least-squares solution is obtained.
+++See \downlink{Manual Page}{manpageXXf04}.
+NagLinearEquationSolvingPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ f04adf : (Integer,Matrix Complex DoubleFloat,Integer,Integer,_
+ Integer,Integer,Matrix Complex DoubleFloat,Integer) -> Result
+ ++ f04adf(ia,b,ib,n,m,ic,a,ifail)
+ ++ calculates the approximate solution of a set of complex
+ ++ linear equations with multiple right-hand sides, using an LU
+ ++ factorization with partial pivoting.
+ ++ See \downlink{Manual Page}{manpageXXf04adf}.
+ f04arf : (Integer,Matrix DoubleFloat,Integer,Matrix DoubleFloat,_
+ Integer) -> Result
+ ++ f04arf(ia,b,n,a,ifail)
+ ++ calculates the approximate solution of a set of real
+ ++ linear equations with a single right-hand side, using an LU
+ ++ factorization with partial pivoting.
+ ++ See \downlink{Manual Page}{manpageXXf04arf}.
+ f04asf : (Integer,Matrix DoubleFloat,Integer,Matrix DoubleFloat,_
+ Integer) -> Result
+ ++ f04asf(ia,b,n,a,ifail)
+ ++ calculates the accurate solution of a set of real
+ ++ symmetric positive-definite linear equations with a single right-
+ ++ hand side, Ax=b, using a Cholesky factorization and iterative
+ ++ refinement.
+ ++ See \downlink{Manual Page}{manpageXXf04asf}.
+ f04atf : (Matrix DoubleFloat,Integer,Matrix DoubleFloat,Integer,_
+ Integer,Integer) -> Result
+ ++ f04atf(a,ia,b,n,iaa,ifail)
+ ++ calculates the accurate solution of a set of real linear
+ ++ equations with a single right-hand side, using an LU
+ ++ factorization with partial pivoting, and iterative refinement.
+ ++ See \downlink{Manual Page}{manpageXXf04atf}.
+ f04axf : (Integer,Matrix DoubleFloat,Integer,Matrix Integer,_
+ Matrix Integer,Integer,Matrix Integer,Matrix DoubleFloat) -> Result
+ ++ f04axf(n,a,licn,icn,ikeep,mtype,idisp,rhs)
+ ++ calculates the approximate solution of a set of real
+ ++ sparse linear equations with a single right-hand side, Ax=b or
+ ++ T
+ ++ A x=b, where A has been factorized by F01BRF or F01BSF.
+ ++ See \downlink{Manual Page}{manpageXXf04axf}.
+ f04faf : (Integer,Integer,Matrix DoubleFloat,Matrix DoubleFloat,_
+ Matrix DoubleFloat,Integer) -> Result
+ ++ f04faf(job,n,d,e,b,ifail)
+ ++ calculates the approximate solution of a set of real
+ ++ symmetric positive-definite tridiagonal linear equations.
+ ++ See \downlink{Manual Page}{manpageXXf04faf}.
+ f04jgf : (Integer,Integer,Integer,DoubleFloat,_
+ Integer,Matrix DoubleFloat,Matrix DoubleFloat,Integer) -> Result
+ ++ f04jgf(m,n,nra,tol,lwork,a,b,ifail)
+ ++ finds the solution of a linear least-squares problem, Ax=b
+ ++ , where A is a real m by n (m>=n) matrix and b is an m element
+ ++ vector. If the matrix of observations is not of full rank, then
+ ++ the minimal least-squares solution is returned.
+ ++ See \downlink{Manual Page}{manpageXXf04jgf}.
+ f04maf : (Integer,Integer,Matrix DoubleFloat,Integer,_
+ Matrix Integer,Integer,Matrix Integer,Matrix DoubleFloat,Matrix Integer,Matrix Integer,Matrix DoubleFloat,Matrix DoubleFloat,Matrix Integer,Integer) -> Result
+ ++ f04maf(n,nz,avals,licn,irn,lirn,icn,wkeep,ikeep,inform,b,acc,noits,ifail)
+ ++ e a sparse symmetric positive-definite system of linear
+ ++ equations, Ax=b, using a pre-conditioned conjugate gradient
+ ++ method, where A has been factorized by F01MAF.
+ ++ See \downlink{Manual Page}{manpageXXf04maf}.
+ f04mbf : (Integer,Matrix DoubleFloat,Boolean,DoubleFloat,_
+ Integer,Integer,Integer,Integer,DoubleFloat,Integer,Union(fn:FileName,fp:Asp28(APROD)),Union(fn:FileName,fp:Asp34(MSOLVE))) -> Result
+ ++ f04mbf(n,b,precon,shift,itnlim,msglvl,lrwork,liwork,rtol,ifail,aprod,msolve)
+ ++ solves a system of real sparse symmetric linear equations
+ ++ using a Lanczos algorithm.
+ ++ See \downlink{Manual Page}{manpageXXf04mbf}.
+ f04mcf : (Integer,Matrix DoubleFloat,Integer,Matrix DoubleFloat,_
+ Matrix Integer,Integer,Matrix DoubleFloat,Integer,Integer,Integer,Integer) -> Result
+ ++ f04mcf(n,al,lal,d,nrow,ir,b,nrb,iselct,nrx,ifail)
+ ++ computes the approximate solution of a system of real
+ ++ linear equations with multiple right-hand sides, AX=B, where A
+ ++ is a symmetric positive-definite variable-bandwidth matrix, which
+ ++ has previously been factorized by F01MCF. Related systems may
+ ++ also be solved.
+ ++ See \downlink{Manual Page}{manpageXXf04mcf}.
+ f04qaf : (Integer,Integer,DoubleFloat,DoubleFloat,_
+ DoubleFloat,DoubleFloat,Integer,Integer,Integer,Integer,Matrix DoubleFloat,Integer,Union(fn:FileName,fp:Asp30(APROD))) -> Result
+ ++ f04qaf(m,n,damp,atol,btol,conlim,itnlim,msglvl,lrwork,liwork,b,ifail,aprod)
+ ++ solves sparse unsymmetric equations, sparse linear least-
+ ++ squares problems and sparse damped linear least-squares problems,
+ ++ using a Lanczos algorithm.
+ ++ See \downlink{Manual Page}{manpageXXf04qaf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import FortranPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(Boolean)
+ import AnyFunctions1(Matrix Complex DoubleFloat)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(Matrix Integer)
+
+
+ f04adf(iaArg:Integer,bArg:Matrix Complex DoubleFloat,ibArg:Integer,_
+ nArg:Integer,mArg:Integer,icArg:Integer,_
+ aArg:Matrix Complex DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04adf",_
+ ["ia"::S,"ib"::S,"n"::S,"m"::S,"ic"::S_
+ ,"ifail"::S,"b"::S,"c"::S,"a"::S,"wkspce"::S]$Lisp,_
+ ["c"::S,"wkspce"::S]$Lisp,_
+ [["double"::S,["wkspce"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"ib"::S,"n"::S,"m"::S_
+ ,"ic"::S,"ifail"::S]$Lisp_
+ ,["double complex"::S,["b"::S,"ib"::S,"m"::S]$Lisp,["c"::S,"ic"::S,"m"::S]$Lisp,["a"::S,"ia"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,ibArg::Any,nArg::Any,mArg::Any,icArg::Any,ifailArg::Any,bArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04arf(iaArg:Integer,bArg:Matrix DoubleFloat,nArg:Integer,_
+ aArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04arf",_
+ ["ia"::S,"n"::S,"ifail"::S,"b"::S,"c"::S,"a"::S,"wkspce"::S]$Lisp,_
+ ["c"::S,"wkspce"::S]$Lisp,_
+ [["double"::S,["b"::S,"n"::S]$Lisp,["c"::S,"n"::S]$Lisp_
+ ,["a"::S,"ia"::S,"n"::S]$Lisp,["wkspce"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,ifailArg::Any,bArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04asf(iaArg:Integer,bArg:Matrix DoubleFloat,nArg:Integer,_
+ aArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04asf",_
+ ["ia"::S,"n"::S,"ifail"::S,"b"::S,"c"::S,"a"::S,"wk1"::S,"wk2"::S_
+ ]$Lisp,_
+ ["c"::S,"wk1"::S,"wk2"::S]$Lisp,_
+ [["double"::S,["b"::S,"n"::S]$Lisp,["c"::S,"n"::S]$Lisp_
+ ,["a"::S,"ia"::S,"n"::S]$Lisp,["wk1"::S,"n"::S]$Lisp,["wk2"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"a"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,ifailArg::Any,bArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04atf(aArg:Matrix DoubleFloat,iaArg:Integer,bArg:Matrix DoubleFloat,_
+ nArg:Integer,iaaArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04atf",_
+ ["ia"::S,"n"::S,"iaa"::S,"ifail"::S,"a"::S,"b"::S,"c"::S,"aa"::S,"wks1"::S_
+ ,"wks2"::S]$Lisp,_
+ ["c"::S,"aa"::S,"wks1"::S,"wks2"::S]$Lisp,_
+ [["double"::S,["a"::S,"ia"::S,"n"::S]$Lisp_
+ ,["b"::S,"n"::S]$Lisp,["c"::S,"n"::S]$Lisp,["aa"::S,"iaa"::S,"n"::S]$Lisp,["wks1"::S,"n"::S]$Lisp,["wks2"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"ia"::S,"n"::S,"iaa"::S,"ifail"::S_
+ ]$Lisp_
+ ]$Lisp,_
+ ["c"::S,"aa"::S,"ifail"::S]$Lisp,_
+ [([iaArg::Any,nArg::Any,iaaArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04axf(nArg:Integer,aArg:Matrix DoubleFloat,licnArg:Integer,_
+ icnArg:Matrix Integer,ikeepArg:Matrix Integer,mtypeArg:Integer,_
+ idispArg:Matrix Integer,rhsArg:Matrix DoubleFloat): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04axf",_
+ ["n"::S,"licn"::S,"mtype"::S,"resid"::S,"a"::S,"icn"::S,"ikeep"::S,"idisp"::S,"rhs"::S_
+ ,"w"::S]$Lisp,_
+ ["resid"::S,"w"::S]$Lisp,_
+ [["double"::S,["a"::S,"licn"::S]$Lisp,"resid"::S_
+ ,["rhs"::S,"n"::S]$Lisp,["w"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"licn"::S,["icn"::S,"licn"::S]$Lisp_
+ ,["ikeep"::S,["*"::S,"n"::S,5$Lisp]$Lisp]$Lisp,"mtype"::S,["idisp"::S,2$Lisp]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["resid"::S,"rhs"::S]$Lisp,_
+ [([nArg::Any,licnArg::Any,mtypeArg::Any,aArg::Any,icnArg::Any,ikeepArg::Any,idispArg::Any,rhsArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04faf(jobArg:Integer,nArg:Integer,dArg:Matrix DoubleFloat,_
+ eArg:Matrix DoubleFloat,bArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04faf",_
+ ["job"::S,"n"::S,"ifail"::S,"d"::S,"e"::S,"b"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,["d"::S,"n"::S]$Lisp,["e"::S,"n"::S]$Lisp_
+ ,["b"::S,"n"::S]$Lisp]$Lisp_
+ ,["integer"::S,"job"::S,"n"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["d"::S,"e"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([jobArg::Any,nArg::Any,ifailArg::Any,dArg::Any,eArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04jgf(mArg:Integer,nArg:Integer,nraArg:Integer,_
+ tolArg:DoubleFloat,lworkArg:Integer,aArg:Matrix DoubleFloat,_
+ bArg:Matrix DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04jgf",_
+ ["m"::S,"n"::S,"nra"::S,"tol"::S,"lwork"::S_
+ ,"svd"::S,"sigma"::S,"irank"::S,"ifail"::S,"work"::S,"a"::S,"b"::S]$Lisp,_
+ ["svd"::S,"sigma"::S,"irank"::S,"work"::S]$Lisp,_
+ [["double"::S,"tol"::S,"sigma"::S,["work"::S,"lwork"::S]$Lisp_
+ ,["a"::S,"nra"::S,"n"::S]$Lisp,["b"::S,"m"::S]$Lisp]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"nra"::S,"lwork"::S_
+ ,"irank"::S,"ifail"::S]$Lisp_
+ ,["logical"::S,"svd"::S]$Lisp_
+ ]$Lisp,_
+ ["svd"::S,"sigma"::S,"irank"::S,"work"::S,"a"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,nraArg::Any,tolArg::Any,lworkArg::Any,ifailArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04maf(nArg:Integer,nzArg:Integer,avalsArg:Matrix DoubleFloat,_
+ licnArg:Integer,irnArg:Matrix Integer,lirnArg:Integer,_
+ icnArg:Matrix Integer,wkeepArg:Matrix DoubleFloat,ikeepArg:Matrix Integer,_
+ informArg:Matrix Integer,bArg:Matrix DoubleFloat,accArg:Matrix DoubleFloat,_
+ noitsArg:Matrix Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04maf",_
+ ["n"::S,"nz"::S,"licn"::S,"lirn"::S,"ifail"::S_
+ ,"avals"::S,"irn"::S,"icn"::S,"wkeep"::S,"ikeep"::S_
+ ,"inform"::S,"work"::S,"b"::S,"acc"::S,"noits"::S_
+ ]$Lisp,_
+ ["work"::S]$Lisp,_
+ [["double"::S,["avals"::S,"licn"::S]$Lisp,["wkeep"::S,["*"::S,3$Lisp,"n"::S]$Lisp]$Lisp_
+ ,["work"::S,["*"::S,3$Lisp,"n"::S]$Lisp]$Lisp,["b"::S,"n"::S]$Lisp,["acc"::S,2$Lisp]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"licn"::S,["irn"::S,"lirn"::S]$Lisp_
+ ,"lirn"::S,["icn"::S,"licn"::S]$Lisp,["ikeep"::S,["*"::S,2$Lisp,"n"::S]$Lisp]$Lisp,["inform"::S,4$Lisp]$Lisp_
+ ,["noits"::S,2$Lisp]$Lisp,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["work"::S,"b"::S,"acc"::S,"noits"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,nzArg::Any,licnArg::Any,lirnArg::Any,ifailArg::Any,avalsArg::Any,irnArg::Any,icnArg::Any,wkeepArg::Any,ikeepArg::Any,informArg::Any,bArg::Any,accArg::Any,noitsArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04mbf(nArg:Integer,bArg:Matrix DoubleFloat,preconArg:Boolean,_
+ shiftArg:DoubleFloat,itnlimArg:Integer,msglvlArg:Integer,_
+ lrworkArg:Integer,liworkArg:Integer,rtolArg:DoubleFloat,_
+ ifailArg:Integer,aprodArg:Union(fn:FileName,fp:Asp28(APROD)),msolveArg:Union(fn:FileName,fp:Asp34(MSOLVE))): Result ==
+-- if both asps are AXIOM generated we do not need lrwork liwork
+-- and will set to 1.
+-- else believe the user but check that they are >0.
+ if (aprodArg case fp) and (msolveArg case fp)
+ then
+ lrworkArg:=1
+ liworkArg:=1
+ else
+ lrworkArg:=max(1,lrworkArg)
+ liworkArg:=max(1,liworkArg)
+ pushFortranOutputStack(aprodFilename := aspFilename "aprod")$FOP
+ if aprodArg case fn
+ then outputAsFortran(aprodArg.fn)
+ else outputAsFortran(aprodArg.fp)
+ popFortranOutputStack()$FOP
+ pushFortranOutputStack(msolveFilename := aspFilename "msolve")$FOP
+ if msolveArg case fn
+ then outputAsFortran(msolveArg.fn)
+ else outputAsFortran(msolveArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([aprodFilename,msolveFilename]$Lisp,_
+ "f04mbf",_
+ ["n"::S,"precon"::S,"shift"::S,"itnlim"::S,"msglvl"::S_
+ ,"lrwork"::S,"liwork"::S,"itn"::S,"anorm"::S,"acond"::S_
+ ,"rnorm"::S,"xnorm"::S,"inform"::S,"rtol"::S,"ifail"::S_
+ ,"aprod"::S,"msolve"::S,"b"::S,"x"::S,"work"::S,"rwork"::S,"iwork"::S_
+ ]$Lisp,_
+ ["x"::S,"itn"::S,"anorm"::S,"acond"::S,"rnorm"::S,"xnorm"::S,"inform"::S,"work"::S,"rwork"::S,"iwork"::S,"aprod"::S,"msolve"::S]$Lisp,_
+ [["double"::S,["b"::S,"n"::S]$Lisp,"shift"::S_
+ ,["x"::S,"n"::S]$Lisp,"anorm"::S,"acond"::S,"rnorm"::S,"xnorm"::S,"rtol"::S,["work"::S,"n"::S,5$Lisp]$Lisp,["rwork"::S,"lrwork"::S]$Lisp_
+ ,"aprod"::S,"msolve"::S]$Lisp_
+ ,["integer"::S,"n"::S,"itnlim"::S,"msglvl"::S_
+ ,"lrwork"::S,"liwork"::S,"itn"::S,"inform"::S,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp]$Lisp_
+ ,["logical"::S,"precon"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"itn"::S,"anorm"::S,"acond"::S,"rnorm"::S,"xnorm"::S,"inform"::S,"rtol"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,preconArg::Any,shiftArg::Any,itnlimArg::Any,msglvlArg::Any,lrworkArg::Any,liworkArg::Any,rtolArg::Any,ifailArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04mcf(nArg:Integer,alArg:Matrix DoubleFloat,lalArg:Integer,_
+ dArg:Matrix DoubleFloat,nrowArg:Matrix Integer,irArg:Integer,_
+ bArg:Matrix DoubleFloat,nrbArg:Integer,iselctArg:Integer,_
+ nrxArg:Integer,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f04mcf",_
+ ["n"::S,"lal"::S,"ir"::S,"nrb"::S,"iselct"::S_
+ ,"nrx"::S,"ifail"::S,"al"::S,"d"::S,"nrow"::S,"b"::S,"x"::S_
+ ]$Lisp,_
+ ["x"::S]$Lisp,_
+ [["double"::S,["al"::S,"lal"::S]$Lisp,["d"::S,"n"::S]$Lisp_
+ ,["b"::S,"nrb"::S,"ir"::S]$Lisp,["x"::S,"nrx"::S,"ir"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"lal"::S,["nrow"::S,"n"::S]$Lisp_
+ ,"ir"::S,"nrb"::S,"iselct"::S,"nrx"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"ifail"::S]$Lisp,_
+ [([nArg::Any,lalArg::Any,irArg::Any,nrbArg::Any,iselctArg::Any,nrxArg::Any,ifailArg::Any,alArg::Any,dArg::Any,nrowArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f04qaf(mArg:Integer,nArg:Integer,dampArg:DoubleFloat,_
+ atolArg:DoubleFloat,btolArg:DoubleFloat,conlimArg:DoubleFloat,_
+ itnlimArg:Integer,msglvlArg:Integer,lrworkArg:Integer,_
+ liworkArg:Integer,bArg:Matrix DoubleFloat,ifailArg:Integer,_
+ aprodArg:Union(fn:FileName,fp:Asp30(APROD))): Result ==
+ pushFortranOutputStack(aprodFilename := aspFilename "aprod")$FOP
+ if aprodArg case fn
+ then outputAsFortran(aprodArg.fn)
+ else outputAsFortran(aprodArg.fp)
+ popFortranOutputStack()$FOP
+ [(invokeNagman([aprodFilename]$Lisp,_
+ "f04qaf",_
+ ["m"::S,"n"::S,"damp"::S,"atol"::S,"btol"::S_
+ ,"conlim"::S,"itnlim"::S,"msglvl"::S,"lrwork"::S,"liwork"::S_
+ ,"itn"::S,"anorm"::S,"acond"::S,"rnorm"::S,"arnorm"::S_
+ ,"xnorm"::S,"inform"::S,"ifail"::S,"aprod"::S,"x"::S,"se"::S,"b"::S,"work"::S,"rwork"::S_
+ ,"iwork"::S]$Lisp,_
+ ["x"::S,"se"::S,"itn"::S,"anorm"::S,"acond"::S,"rnorm"::S,"arnorm"::S,"xnorm"::S,"inform"::S,"work"::S,"rwork"::S,"iwork"::S,"aprod"::S]$Lisp,_
+ [["double"::S,"damp"::S,"atol"::S,"btol"::S_
+ ,"conlim"::S,["x"::S,"n"::S]$Lisp,["se"::S,"n"::S]$Lisp,"anorm"::S,"acond"::S,"rnorm"::S,"arnorm"::S,"xnorm"::S,["b"::S,"m"::S]$Lisp_
+ ,["work"::S,"n"::S,2$Lisp]$Lisp,["rwork"::S,"lrwork"::S]$Lisp,"aprod"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"itnlim"::S,"msglvl"::S_
+ ,"lrwork"::S,"liwork"::S,"itn"::S,"inform"::S,"ifail"::S,["iwork"::S,"liwork"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["x"::S,"se"::S,"itn"::S,"anorm"::S,"acond"::S,"rnorm"::S,"arnorm"::S,"xnorm"::S,"inform"::S,"b"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,dampArg::Any,atolArg::Any,btolArg::Any,conlimArg::Any,itnlimArg::Any,msglvlArg::Any,lrworkArg::Any,liworkArg::Any,ifailArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGF04 NagLinearEquationSolvingPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/f07.spad.pamphlet b/src/algebra/f07.spad.pamphlet
new file mode 100644
index 00000000..bc8f4ae0
--- /dev/null
+++ b/src/algebra/f07.spad.pamphlet
@@ -0,0 +1,182 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra f07.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGF07 NagLapack}
+<<package NAGF07 NagLapack>>=
+)abbrev package NAGF07 NagLapack
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:45:42 1994
+++Description:
+++This package uses the NAG Library to compute matrix
+++factorizations, and to solve systems of linear equations
+++following the matrix factorizations.
+++See \downlink{Manual Page}{manpageXXf07}.
+NagLapack(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ f07adf : (Integer,Integer,Integer,Matrix DoubleFloat) -> Result
+ ++ f07adf(m,n,lda,a)
+ ++ (DGETRF) computes the LU factorization of a real m by n
+ ++ matrix.
+ ++ See \downlink{Manual Page}{manpageXXf07adf}.
+ f07aef : (String,Integer,Integer,Matrix DoubleFloat,_
+ Integer,Matrix Integer,Integer,Matrix DoubleFloat) -> Result
+ ++ f07aef(trans,n,nrhs,a,lda,ipiv,ldb,b)
+ ++ (DGETRS) solves a real system of linear equations with
+ ++ T
+ ++ multiple right-hand sides, AX=B or A X=B, where A has been
+ ++ factorized by F07ADF (DGETRF).
+ ++ See \downlink{Manual Page}{manpageXXf07aef}.
+ f07fdf : (String,Integer,Integer,Matrix DoubleFloat) -> Result
+ ++ f07fdf(uplo,n,lda,a)
+ ++ (DPOTRF) computes the Cholesky factorization of a real
+ ++ symmetric positive-definite matrix.
+ ++ See \downlink{Manual Page}{manpageXXf07fdf}.
+ f07fef : (String,Integer,Integer,Matrix DoubleFloat,_
+ Integer,Integer,Matrix DoubleFloat) -> Result
+ ++ f07fef(uplo,n,nrhs,a,lda,ldb,b)
+ ++ (DPOTRS) solves a real symmetric positive-definite system
+ ++ of linear equations with multiple right-hand sides, AX=B, where A
+ ++ has been factorized by F07FDF (DPOTRF).
+ ++ See \downlink{Manual Page}{manpageXXf07fef}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(Matrix DoubleFloat)
+ import AnyFunctions1(String)
+ import AnyFunctions1(Matrix Integer)
+
+
+ f07adf(mArg:Integer,nArg:Integer,ldaArg:Integer,_
+ aArg:Matrix DoubleFloat): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f07adf",_
+ ["m"::S,"n"::S,"lda"::S,"info"::S,"ipiv"::S,"a"::S]$Lisp,_
+ ["ipiv"::S,"info"::S]$Lisp,_
+ [["double"::S,["a"::S,"lda"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"lda"::S,["ipiv"::S,"m"::S]$Lisp_
+ ,"info"::S]$Lisp_
+ ]$Lisp,_
+ ["ipiv"::S,"info"::S,"a"::S]$Lisp,_
+ [([mArg::Any,nArg::Any,ldaArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f07aef(transArg:String,nArg:Integer,nrhsArg:Integer,_
+ aArg:Matrix DoubleFloat,ldaArg:Integer,ipivArg:Matrix Integer,_
+ ldbArg:Integer,bArg:Matrix DoubleFloat): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f07aef",_
+ ["trans"::S,"n"::S,"nrhs"::S,"lda"::S,"ldb"::S_
+ ,"info"::S,"a"::S,"ipiv"::S,"b"::S]$Lisp,_
+ ["info"::S]$Lisp,_
+ [["double"::S,["a"::S,"lda"::S,"n"::S]$Lisp_
+ ,["b"::S,"ldb"::S,"nrhs"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"nrhs"::S,"lda"::S,["ipiv"::S,"n"::S]$Lisp_
+ ,"ldb"::S,"info"::S]$Lisp_
+ ,["character"::S,"trans"::S]$Lisp_
+ ]$Lisp,_
+ ["info"::S,"b"::S]$Lisp,_
+ [([transArg::Any,nArg::Any,nrhsArg::Any,ldaArg::Any,ldbArg::Any,aArg::Any,ipivArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f07fdf(uploArg:String,nArg:Integer,ldaArg:Integer,_
+ aArg:Matrix DoubleFloat): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f07fdf",_
+ ["uplo"::S,"n"::S,"lda"::S,"info"::S,"a"::S]$Lisp,_
+ ["info"::S]$Lisp,_
+ [["double"::S,["a"::S,"lda"::S,"n"::S]$Lisp_
+ ]$Lisp_
+ ,["integer"::S,"n"::S,"lda"::S,"info"::S]$Lisp_
+ ,["character"::S,"uplo"::S]$Lisp_
+ ]$Lisp,_
+ ["info"::S,"a"::S]$Lisp,_
+ [([uploArg::Any,nArg::Any,ldaArg::Any,aArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ f07fef(uploArg:String,nArg:Integer,nrhsArg:Integer,_
+ aArg:Matrix DoubleFloat,ldaArg:Integer,ldbArg:Integer,_
+ bArg:Matrix DoubleFloat): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "f07fef",_
+ ["uplo"::S,"n"::S,"nrhs"::S,"lda"::S,"ldb"::S_
+ ,"info"::S,"a"::S,"b"::S]$Lisp,_
+ ["info"::S]$Lisp,_
+ [["double"::S,["a"::S,"lda"::S,"n"::S]$Lisp_
+ ,["b"::S,"ldb"::S,"nrhs"::S]$Lisp]$Lisp_
+ ,["integer"::S,"n"::S,"nrhs"::S,"lda"::S,"ldb"::S_
+ ,"info"::S]$Lisp_
+ ,["character"::S,"uplo"::S]$Lisp_
+ ]$Lisp,_
+ ["info"::S,"b"::S]$Lisp,_
+ [([uploArg::Any,nArg::Any,nrhsArg::Any,ldaArg::Any,ldbArg::Any,aArg::Any,bArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGF07 NagLapack>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/facutil.spad.pamphlet b/src/algebra/facutil.spad.pamphlet
new file mode 100644
index 00000000..2b7de8de
--- /dev/null
+++ b/src/algebra/facutil.spad.pamphlet
@@ -0,0 +1,218 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra facutil.spad}
+\author{Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FACUTIL FactoringUtilities}
+<<package FACUTIL FactoringUtilities>>=
+)abbrev package FACUTIL FactoringUtilities
+++ Author: Barry Trager
+++ Date Created: March 12, 1992
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides utilities used by the factorizers
+++ which operate on polynomials represented as univariate polynomials
+++ with multivariate coefficients.
+
+FactoringUtilities(E,OV,R,P) : C == T where
+ E : OrderedAbelianMonoidSup
+ OV : OrderedSet
+ R : Ring
+ P : PolynomialCategory(R,E,OV)
+
+ SUP ==> SparseUnivariatePolynomial
+ NNI ==> NonNegativeInteger
+ Z ==> Integer
+
+ C == with
+ completeEval : (SUP P,List OV,List R) -> SUP R
+ ++ completeEval(upoly, lvar, lval) evaluates the polynomial upoly
+ ++ with each variable in lvar replaced by the corresponding value
+ ++ in lval. Substitutions are done for all variables in upoly
+ ++ producing a univariate polynomial over R.
+ degree : (SUP P,List OV) -> List NNI
+ ++ degree(upoly, lvar) returns a list containing the maximum
+ ++ degree for each variable in lvar.
+ variables : SUP P -> List OV
+ ++ variables(upoly) returns the list of variables for the coefficients
+ ++ of upoly.
+ lowerPolynomial: SUP P -> SUP R
+ ++ lowerPolynomial(upoly) converts upoly to be a univariate polynomial
+ ++ over R. An error if the coefficients contain variables.
+ raisePolynomial: SUP R -> SUP P
+ ++ raisePolynomial(rpoly) converts rpoly from a univariate polynomial
+ ++ over r to be a univariate polynomial with polynomial coefficients.
+ normalDeriv : (SUP P,Z) -> SUP P
+ ++ normalDeriv(poly,i) computes the ith derivative of poly divided
+ ++ by i!.
+ ran : Z -> R
+ ++ ran(k) computes a random integer between -k and k as a member of R.
+
+ T == add
+
+ lowerPolynomial(f:SUP P) : SUP R ==
+ zero? f => 0$SUP(R)
+ monomial(ground leadingCoefficient f, degree f)$SUP(R) +
+ lowerPolynomial(reductum f)
+
+ raisePolynomial(u:SUP R) : SUP P ==
+ zero? u => 0$SUP(P)
+ monomial(leadingCoefficient(u)::P, degree u)$SUP(P) +
+ raisePolynomial(reductum u)
+
+ completeEval(f:SUP P,lvar:List OV,lval:List R) : SUP R ==
+ zero? f => 0$SUP(R)
+ monomial(ground eval(leadingCoefficient f,lvar,lval),degree f)$SUP(R) +
+ completeEval(reductum f,lvar,lval)
+
+ degree(f:SUP P,lvar:List OV) : List NNI ==
+ coefs := coefficients f
+ ldeg:= ["max"/[degree(fc,xx) for fc in coefs] for xx in lvar]
+
+ variables(f:SUP P) : List OV ==
+ "setUnion"/[variables cf for cf in coefficients f]
+
+ if R has FiniteFieldCategory then
+ ran(k:Z):R == random()$R
+ else
+ ran(k:Z):R == (random(2*k+1)$Z -k)::R
+
+ -- Compute the normalized m derivative
+ normalDeriv(f:SUP P,m:Z) : SUP P==
+ (n1:Z:=degree f) < m => 0$SUP(P)
+ n1=m => (leadingCoefficient f)::SUP(P)
+ k:=binomial(n1,m)
+ ris:SUP:=0$SUP(P)
+ n:Z:=n1
+ while n>= m repeat
+ while n1>n repeat
+ k:=(k*(n1-m)) quo n1
+ n1:=n1-1
+ ris:=ris+monomial(k*leadingCoefficient f,(n-m)::NNI)
+ f:=reductum f
+ n:=degree f
+ ris
+
+@
+\section{package PUSHVAR PushVariables}
+<<package PUSHVAR PushVariables>>=
+)abbrev package PUSHVAR PushVariables
+++ This package \undocumented{}
+PushVariables(R,E,OV,PPR):C == T where
+ E : OrderedAbelianMonoidSup
+ OV: OrderedSet with
+ convert: % -> Symbol
+ ++ convert(x) converts x to a symbol
+ variable: Symbol -> Union(%, "failed")
+ ++ variable(s) makes an element from symbol s or fails
+ R : Ring
+ PR ==> Polynomial R
+ PPR: PolynomialCategory(PR,E,OV)
+ SUP ==> SparseUnivariatePolynomial
+ C == with
+ pushdown : (PPR, OV) -> PPR
+ ++ pushdown(p,v) \undocumented{}
+ pushdown : (PPR, List OV) -> PPR
+ ++ pushdown(p,lv) \undocumented{}
+ pushup : (PPR, OV) -> PPR
+ ++ pushup(p,v) \undocumented{}
+ pushup : (PPR, List OV) -> PPR
+ ++ pushup(p,lv) \undocumented{}
+ map : ((PR -> PPR), PPR) -> PPR
+ ++ map(f,p) \undocumented{}
+
+ T == add
+ pushdown(g:PPR,x:OV) : PPR ==
+ eval(g,x,monomial(1,convert x,1)$PR)
+
+ pushdown(g:PPR, lv:List OV) : PPR ==
+ vals:=[monomial(1,convert x,1)$PR for x in lv]
+ eval(g,lv,vals)
+
+ map(f:(PR -> PPR), p: PPR) : PPR ==
+ ground? p => f(retract p)
+ v:=mainVariable(p)::OV
+ multivariate(map(map(f,#1),univariate(p,v)),v)
+
+ ---- push back the variable ----
+ pushupCoef(c:PR, lv:List OV): PPR ==
+ ground? c => c::PPR
+ v:=mainVariable(c)::Symbol
+ v2 := variable(v)$OV
+ uc := univariate(c,v)
+ ppr : PPR := 0
+ v2 case OV =>
+ while not zero? uc repeat
+ ppr := ppr + monomial(1,v2,degree(uc))$PPR *
+ pushupCoef(leadingCoefficient uc, lv)
+ uc := reductum uc
+ ppr
+ while not zero? uc repeat
+ ppr := ppr + monomial(1,v,degree(uc))$PR *
+ pushupCoef(leadingCoefficient uc, lv)
+ uc := reductum uc
+ ppr
+
+ pushup(f:PPR,x:OV) :PPR ==
+ map(pushupCoef(#1,[x]), f)
+
+ pushup(g:PPR, lv:List OV) : PPR ==
+ map(pushupCoef(#1, lv), g)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FACUTIL FactoringUtilities>>
+<<package PUSHVAR PushVariables>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffcat.spad.pamphlet b/src/algebra/ffcat.spad.pamphlet
new file mode 100644
index 00000000..9505c555
--- /dev/null
+++ b/src/algebra/ffcat.spad.pamphlet
@@ -0,0 +1,873 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffcat.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn, Barry Trager, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- 28.01.93: AS and JG:another Error in discreteLog(.,.) in FFIEDLC corrected.
+-- 08.05.92: AS Error in discreteLog(.,.) in FFIEDLC corrected.
+-- 03.04.92: AS Barry Trager added package FFSLPE and some functions to FFIELDC
+-- 25.02.92: AS added following functions in FAXF: impl.of mrepresents,
+-- linearAssociatedExp,linearAssociatedLog, linearAssociatedOrder
+-- 18.02.92: AS: more efficient version of degree added,
+-- first version of degree in FAXF set into comments
+-- 18.06.91: AS: general version of minimalPolynomial added
+-- 08.05.91: JG, AS implementation of missing functions in FFC and FAXF
+-- 04.05.91: JG: comments
+-- 04.04.91: JG: old version of charthRoot in FFC was dropped
+
+-- Fields with finite characteristic
+\end{verbatim}
+\section{category FPC FieldOfPrimeCharacteristic}
+<<category FPC FieldOfPrimeCharacteristic>>=
+)abbrev category FPC FieldOfPrimeCharacteristic
+++ Author: J. Grabmeier, A. Scheerhorn
+++ Date Created: 10 March 1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations: _+, _*
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: field, finite field, prime characteristic
+++ References:
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FieldOfPrimeCharacteristic is the category of fields of prime
+++ characteristic, e.g. finite fields, algebraic closures of
+++ fields of prime characteristic, transcendental extensions of
+++ of fields of prime characteristic.
+FieldOfPrimeCharacteristic:Category == _
+ Join(Field,CharacteristicNonZero) with
+ order: $ -> OnePointCompletion PositiveInteger
+ ++ order(a) computes the order of an element in the multiplicative
+ ++ group of the field.
+ ++ Error: if \spad{a} is 0.
+ discreteLog: ($,$) -> Union(NonNegativeInteger,"failed")
+ ++ discreteLog(b,a) computes s with \spad{b**s = a} if such an s exists.
+ primeFrobenius: $ -> $
+ ++ primeFrobenius(a) returns \spad{a ** p} where p is the characteristic.
+ primeFrobenius: ($,NonNegativeInteger) -> $
+ ++ primeFrobenius(a,s) returns \spad{a**(p**s)} where p
+ ++ is the characteristic.
+ add
+ primeFrobenius(a) == a ** characteristic()
+ primeFrobenius(a,s) == a ** (characteristic()**s)
+
+@
+\section{category XF ExtensionField}
+<<category XF ExtensionField>>=
+)abbrev category XF ExtensionField
+++ Author: J. Grabmeier, A. Scheerhorn
+++ Date Created: 10 March 1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations: _+, _*, extensionDegree, algebraic?, transcendent?
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: field, extension field
+++ References:
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ ExtensionField {\em F} is the category of fields which extend
+++ the field F
+ExtensionField(F:Field) : Category == Join(Field,RetractableTo F,VectorSpace F) with
+ if F has CharacteristicZero then CharacteristicZero
+ if F has CharacteristicNonZero then FieldOfPrimeCharacteristic
+ algebraic? : $ -> Boolean
+ ++ algebraic?(a) tests whether an element \spad{a} is algebraic with
+ ++ respect to the ground field F.
+ transcendent? : $ -> Boolean
+ ++ transcendent?(a) tests whether an element \spad{a} is transcendent
+ ++ with respect to the ground field F.
+ inGroundField?: $ -> Boolean
+ ++ inGroundField?(a) tests whether an element \spad{a}
+ ++ is already in the ground field F.
+ degree : $ -> OnePointCompletion PositiveInteger
+ ++ degree(a) returns the degree of minimal polynomial of an element
+ ++ \spad{a} if \spad{a} is algebraic
+ ++ with respect to the ground field F, and \spad{infinity} otherwise.
+ extensionDegree : () -> OnePointCompletion PositiveInteger
+ ++ extensionDegree() returns the degree of the field extension if the
+ ++ extension is algebraic, and \spad{infinity} if it is not.
+ transcendenceDegree : () -> NonNegativeInteger
+ ++ transcendenceDegree() returns the transcendence degree of the
+ ++ field extension, 0 if the extension is algebraic.
+ -- perhaps more absolute degree functions
+ if F has Finite then
+ FieldOfPrimeCharacteristic
+ Frobenius: $ -> $
+ ++ Frobenius(a) returns \spad{a ** q} where q is the \spad{size()$F}.
+ Frobenius: ($,NonNegativeInteger) -> $
+ ++ Frobenius(a,s) returns \spad{a**(q**s)} where q is the size()$F.
+ add
+ algebraic?(a) == not infinite? (degree(a)@OnePointCompletion_
+ (PositiveInteger))$OnePointCompletion(PositiveInteger)
+ transcendent? a == infinite?(degree(a)@OnePointCompletion _
+ (PositiveInteger))$OnePointCompletion(PositiveInteger)
+ if F has Finite then
+ Frobenius(a) == a ** size()$F
+ Frobenius(a,s) == a ** (size()$F ** s)
+
+@
+\section{category FAXF FiniteAlgebraicExtensionField}
+<<category FAXF FiniteAlgebraicExtensionField>>=
+)abbrev category FAXF FiniteAlgebraicExtensionField
+++ Author: J. Grabmeier, A. Scheerhorn
+++ Date Created: 11 March 1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations: _+, _*, extensionDegree,
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: field, extension field, algebraic extension, finite extension
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteAlgebraicExtensionField {\em F} is the category of fields
+++ which are finite algebraic extensions of the field {\em F}.
+++ If {\em F} is finite then any finite algebraic extension of {\em F} is finite, too.
+++ Let {\em K} be a finite algebraic extension of the finite field {\em F}.
+++ The exponentiation of elements of {\em K} defines a Z-module structure
+++ on the multiplicative group of {\em K}. The additive group of {\em K}
+++ becomes a module over the ring of polynomials over {\em F} via the operation
+++ \spadfun{linearAssociatedExp}(a:K,f:SparseUnivariatePolynomial F)
+++ which is linear over {\em F}, i.e. for elements {\em a} from {\em K},
+++ {\em c,d} from {\em F} and {\em f,g} univariate polynomials over {\em F}
+++ we have \spadfun{linearAssociatedExp}(a,cf+dg) equals {\em c} times
+++ \spadfun{linearAssociatedExp}(a,f) plus {\em d} times
+++ \spadfun{linearAssociatedExp}(a,g).
+++ Therefore \spadfun{linearAssociatedExp} is defined completely by
+++ its action on monomials from {\em F[X]}:
+++ \spadfun{linearAssociatedExp}(a,monomial(1,k)\$SUP(F)) is defined to be
+++ \spadfun{Frobenius}(a,k) which is {\em a**(q**k)} where {\em 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 : Field) : Category == _
+ 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: 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: \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,
+ ++ i.e. \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, i.e.
+ ++ \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 {\em F}, i.e.
+ ++ for elements {\em a} from {\em \$}, {\em c,d} form {\em F} and
+ ++ {\em f,g} univariate polynomials over {\em F} we have
+ ++ \spadfun{linearAssociatedExp}(a,cf+dg) equals {\em c} times
+ ++ \spadfun{linearAssociatedExp}(a,f) plus {\em d} times
+ ++ \spadfun{linearAssociatedExp}(a,g). Therefore
+ ++ \spadfun{linearAssociatedExp} is defined completely by its action on
+ ++ monomials from {\em F[X]}:
+ ++ \spadfun{linearAssociatedExp}(a,monomial(1,k)\$SUP(F)) is defined to
+ ++ be \spadfun{Frobenius}(a,k) which is {\em a**(q**k)},
+ ++ where {\em q=size()\$F}.
+ linearAssociatedOrder: $ -> SparseUnivariatePolynomial F
+ ++ linearAssociatedOrder(a) retruns the monic polynomial {\em g} of
+ ++ least degree, such that \spadfun{linearAssociatedExp}(a,g) is 0.
+ linearAssociatedLog: $ -> SparseUnivariatePolynomial F
+ ++ linearAssociatedLog(a) returns a polynomial {\em g}, such that
+ ++ \spadfun{linearAssociatedExp}(normalElement(),g) equals {\em a}.
+ linearAssociatedLog: ($,$) -> Union(SparseUnivariatePolynomial F,"failed")
+ ++ linearAssociatedLog(b,a) returns a polynomial {\em g}, such that the
+ ++ \spadfun{linearAssociatedExp}(b,g) equals {\em a}.
+ ++ If there is no such polynomial {\em 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
+ extensionDegree():OnePointCompletion(PositiveInteger) ==
+ (#basis()) :: PositiveInteger::OnePointCompletion(PositiveInteger)
+ degree(a):OnePointCompletion(PositiveInteger) ==
+ degree(a)@PI::OnePointCompletion(PositiveInteger)
+
+ 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
+ -- degree a == degree(minimalPolynomial a)$SUP(F) :: PI
+ 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")
+ -- norm(e) == norm(e,1) pretend F
+ -- trace(e) == trace(e,1) pretend F
+ 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
+
+@
+\section{package DLP DiscreteLogarithmPackage}
+<<package DLP DiscreteLogarithmPackage>>=
+)abbrev package DLP DiscreteLogarithmPackage
+++ Author: J. Grabmeier, A. Scheerhorn
+++ Date Created: 12 March 1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: discrete logarithm
+++ References:
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ DiscreteLogarithmPackage implements help functions for discrete logarithms
+++ in monoids using small cyclic groups.
+
+DiscreteLogarithmPackage(M): public == private where
+ M : Join(Monoid,Finite) with
+ "**": (M,Integer) -> M
+ ++ x ** n returns x raised to the integer power n
+ public ==> with
+ shanksDiscLogAlgorithm:(M,M,NonNegativeInteger)-> _
+ Union(NonNegativeInteger,"failed")
+ ++ shanksDiscLogAlgorithm(b,a,p) computes s with \spad{b**s = a} for
+ ++ assuming that \spad{a} and b are elements in a 'small' cyclic group of
+ ++ order p by Shank's algorithm.
+ ++ Note: this is a subroutine of the function \spadfun{discreteLog}.
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SUP ==> SparseUnivariatePolynomial
+ DLP ==> DiscreteLogarithmPackage
+
+ private ==> add
+ shanksDiscLogAlgorithm(logbase,c,p) ==
+ limit:Integer:= 30
+ -- for logarithms up to cyclic groups of order limit a full
+ -- logarithm table is computed
+ p < limit =>
+ a:M:=1
+ disclog:Integer:=0
+ found:Boolean:=false
+ for i in 0..p-1 while not found repeat
+ a = c =>
+ disclog:=i
+ found:=true
+ a:=a*logbase
+ not found =>
+ messagePrint("discreteLog: second argument not in cyclic group_
+ generated by first argument")$OutputForm
+ "failed"
+ disclog pretend NonNegativeInteger
+ l:Integer:=length(p)$Integer
+ if odd?(l)$Integer then n:Integer:= shift(p,-(l quo 2))
+ else n:Integer:= shift(1,(l quo 2))
+ a:M:=1
+ exptable : Table(PI,NNI) :=table()$Table(PI,NNI)
+ for i in (0::NNI)..(n-1)::NNI repeat
+ insert_!([lookup(a),i::NNI]$Record(key:PI,entry:NNI),_
+ exptable)$Table(PI,NNI)
+ a:=a*logbase
+ found := false
+ end := (p-1) quo n
+ disclog:Integer:=0
+ a := c
+ b := logbase ** (-n)
+ for i in 0..end while not found repeat
+ rho:= search(lookup(a),exptable)_
+ $Table(PositiveInteger,NNI)
+ rho case NNI =>
+ found := true
+ disclog:= n * i + rho pretend Integer
+ a := a * b
+ not found =>
+ messagePrint("discreteLog: second argument not in cyclic group_
+ generated by first argument")$OutputForm
+ "failed"
+ disclog pretend NonNegativeInteger
+
+@
+\section{category FFIELDC FiniteFieldCategory}
+<<category FFIELDC FiniteFieldCategory>>=
+)abbrev category FFIELDC FiniteFieldCategory
+++ Author: J. Grabmeier, A. Scheerhorn
+++ Date Created: 11 March 1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations: _+, _*, extensionDegree, order, primitiveElement
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: field, extension field, algebraic extension, finite field
+++ Galois field
+++ References:
+++ D.Lipson, Elements of Algebra and Algebraic Computing, The
+++ Benjamin/Cummings Publishing Company, Inc.-Menlo Park, California, 1981.
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldCategory is the category of finite fields
+
+FiniteFieldCategory() : Category ==_
+ Join(FieldOfPrimeCharacteristic,Finite,StepThrough,DifferentialRing) with
+-- ,PolynomialFactorizationExplicit) with
+ charthRoot: $ -> $
+ ++ charthRoot(a) takes the characteristic'th root of {\em a}.
+ ++ Note: such a root is alway defined in finite fields.
+ conditionP: Matrix $ -> Union(Vector $,"failed")
+ ++ conditionP(mat), given a matrix representing a homogeneous system
+ ++ of equations, returns a vector whose characteristic'th powers
+ ++ is a non-trivial solution, or "failed" if no such vector exists.
+ -- the reason for implementing the following function is that we
+ -- can implement the functions order, getGenerator and primitive? on
+ -- category level without computing the, may be time intensive,
+ -- factorization of size()-1 at every function call again.
+ factorsOfCyclicGroupSize:_
+ () -> List Record(factor:Integer,exponent:Integer)
+ ++ factorsOfCyclicGroupSize() returns the factorization of size()-1
+ -- the reason for implementing the function tableForDiscreteLogarithm
+ -- is that we can implement the functions discreteLog and
+ -- shanksDiscLogAlgorithm on category level
+ -- computing the necessary exponentiation tables in the respective
+ -- domains once and for all
+ -- absoluteDegree : $ -> PositiveInteger
+ -- ++ degree of minimal polynomial, if algebraic with respect
+ -- ++ to the prime subfield
+ tableForDiscreteLogarithm: Integer -> _
+ Table(PositiveInteger,NonNegativeInteger)
+ ++ tableForDiscreteLogarithm(a,n) returns a table of the discrete
+ ++ logarithms of \spad{a**0} up to \spad{a**(n-1)} which, called with
+ ++ key \spad{lookup(a**i)} returns i for i in \spad{0..n-1}.
+ ++ Error: if not called for prime divisors of order of
+ ++ multiplicative group.
+ createPrimitiveElement: () -> $
+ ++ createPrimitiveElement() computes a generator of the (cyclic)
+ ++ multiplicative group of the field.
+ -- RDJ: Are these next lines to be included?
+ -- we run through the field and test, algorithms which construct
+ -- elements of larger order were found to be too slow
+ primitiveElement: () -> $
+ ++ primitiveElement() returns a primitive element stored in a global
+ ++ variable in the domain.
+ ++ At first call, the primitive element is computed
+ ++ by calling \spadfun{createPrimitiveElement}.
+ primitive?: $ -> Boolean
+ ++ primitive?(b) tests whether the element b is a generator of the
+ ++ (cyclic) multiplicative group of the field, i.e. is a primitive
+ ++ element.
+ ++ Implementation Note: see ch.IX.1.3, th.2 in D. Lipson.
+ discreteLog: $ -> NonNegativeInteger
+ ++ discreteLog(a) computes the discrete logarithm of \spad{a}
+ ++ with respect to \spad{primitiveElement()} of the field.
+ order: $ -> PositiveInteger
+ ++ order(b) computes the order of an element b in the multiplicative
+ ++ group of the field.
+ ++ Error: if b equals 0.
+ representationType: () -> Union("prime","polynomial","normal","cyclic")
+ ++ representationType() returns the type of the representation, one of:
+ ++ \spad{prime}, \spad{polynomial}, \spad{normal}, or \spad{cyclic}.
+ add
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SUP ==> SparseUnivariatePolynomial
+ DLP ==> DiscreteLogarithmPackage
+
+ -- exported functions
+
+ differentiate x == 0
+ init() == 0
+ nextItem(a) ==
+ zero?(a:=index(lookup(a)+1)) => "failed"
+ a
+ order(e):OnePointCompletion(PositiveInteger) ==
+ (order(e)@PI)::OnePointCompletion(PositiveInteger)
+
+ conditionP(mat:Matrix $) ==
+ l:=nullSpace mat
+ empty? l or every?(zero?, first l) => "failed"
+ map(charthRoot,first l)
+ charthRoot(x:$):$ == x**(size() quo characteristic())
+ charthRoot(x:%):Union($,"failed") ==
+ (charthRoot(x)@$)::Union($,"failed")
+ createPrimitiveElement() ==
+ sm1 : PositiveInteger := (size()$$-1) pretend PositiveInteger
+ start : Integer :=
+ -- in the polynomial case, index from 1 to characteristic-1
+ -- gives prime field elements
+ representationType = "polynomial" => characteristic()::Integer
+ 1
+ found : Boolean := false
+ for i in start.. while not found repeat
+ e : $ := index(i::PositiveInteger)
+ found := (order(e) = sm1)
+ e
+ primitive? a ==
+ -- add special implementation for prime field case
+ zero?(a) => false
+ explist := factorsOfCyclicGroupSize()
+ q:=(size()-1)@Integer
+ equalone : Boolean := false
+ for exp in explist while not equalone repeat
+-- equalone := one?(a**(q quo exp.factor))
+ equalone := ((a**(q quo exp.factor)) = 1)
+ not equalone
+ order e ==
+ e = 0 => error "order(0) is not defined "
+ ord:Integer:= size()-1 -- order e divides ord
+ a:Integer:= 0
+ lof:=factorsOfCyclicGroupSize()
+ for rec in lof repeat -- run through prime divisors
+ a := ord quo (primeDivisor := rec.factor)
+-- goon := one?(e**a)
+ goon := ((e**a) = 1)
+ -- run through exponents of the prime divisors
+ for j in 0..(rec.exponent)-2 while goon repeat
+ -- as long as we get (e**ord = 1) we
+ -- continue dividing by primeDivisor
+ ord := a
+ a := ord quo primeDivisor
+-- goon := one?(e**a)
+ goon := ((e**a) = 1)
+ if goon then ord := a
+ -- as we do a top down search we have found the
+ -- correct exponent of primeDivisor in order e
+ -- and continue with next prime divisor
+ ord pretend PositiveInteger
+ discreteLog(b) ==
+ zero?(b) => error "discreteLog: logarithm of zero"
+ faclist:=factorsOfCyclicGroupSize()
+ a:=b
+ gen:=primitiveElement()
+ -- in GF(2) its necessary to have discreteLog(1) = 1
+ b = gen => 1
+ disclog:Integer:=0
+ mult:Integer:=1
+ groupord := (size() - 1)@Integer
+ exp:Integer:=groupord
+ for f in faclist repeat
+ fac:=f.factor
+ for t in 0..f.exponent-1 repeat
+ exp:=exp quo fac
+ -- shanks discrete logarithm algorithm
+ exptable:=tableForDiscreteLogarithm(fac)
+ n:=#exptable
+ c:=a**exp
+ end:=(fac - 1) quo n
+ found:=false
+ disc1:Integer:=0
+ for i in 0..end while not found repeat
+ rho:= search(lookup(c),exptable)_
+ $Table(PositiveInteger,NNI)
+ rho case NNI =>
+ found := true
+ disc1:=((n * i + rho)@Integer) * mult
+ c:=c* gen**((groupord quo fac) * (-n))
+ not found => error "discreteLog: ?? discrete logarithm"
+ -- end of shanks discrete logarithm algorithm
+ mult := mult * fac
+ disclog:=disclog+disc1
+ a:=a * (gen ** (-disc1))
+ disclog pretend NonNegativeInteger
+
+ discreteLog(logbase,b) ==
+ zero?(b) =>
+ messagePrint("discreteLog: logarithm of zero")$OutputForm
+ "failed"
+ zero?(logbase) =>
+ messagePrint("discreteLog: logarithm to base zero")$OutputForm
+ "failed"
+ b = logbase => 1
+ not zero?((groupord:=order(logbase)@PI) rem order(b)@PI) =>
+ messagePrint("discreteLog: second argument not in cyclic group _
+generated by first argument")$OutputForm
+ "failed"
+ faclist:=factors factor groupord
+ a:=b
+ disclog:Integer:=0
+ mult:Integer:=1
+ exp:Integer:= groupord
+ for f in faclist repeat
+ fac:=f.factor
+ primroot:= logbase ** (groupord quo fac)
+ for t in 0..f.exponent-1 repeat
+ exp:=exp quo fac
+ rhoHelp:= shanksDiscLogAlgorithm(primroot,_
+ a**exp,fac pretend NonNegativeInteger)$DLP($)
+ rhoHelp case "failed" => return "failed"
+ rho := (rhoHelp :: NNI) * mult
+ disclog := disclog + rho
+ mult := mult * fac
+ a:=a * (logbase ** (-rho))
+ disclog pretend NonNegativeInteger
+
+ FP ==> SparseUnivariatePolynomial($)
+ FRP ==> Factored FP
+ f,g:FP
+ squareFreePolynomial(f:FP):FRP ==
+ squareFree(f)$UnivariatePolynomialSquareFree($,FP)
+ factorPolynomial(f:FP):FRP == factor(f)$DistinctDegreeFactorize($,FP)
+ factorSquareFreePolynomial(f:FP):FRP ==
+ f = 0 => 0
+ flist := distdfact(f,true)$DistinctDegreeFactorize($,FP)
+ (flist.cont :: FP) *
+ (*/[primeFactor(u.irr,u.pow) for u in flist.factors])
+ gcdPolynomial(f:FP,g:FP):FP ==
+ gcd(f,g)$EuclideanDomain_&(FP)
+
+@
+\section{FFIELDC.lsp BOOTSTRAP}
+{\bf FFIELDC} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf FFIELDC}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf FFIELDC.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<FFIELDC.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |FiniteFieldCategory;AL| (QUOTE NIL))
+
+(DEFUN |FiniteFieldCategory| NIL (LET (#:G83129) (COND (|FiniteFieldCategory;AL|) (T (SETQ |FiniteFieldCategory;AL| (|FiniteFieldCategory;|))))))
+
+(DEFUN |FiniteFieldCategory;| NIL (PROG (#1=#:G83127) (RETURN (PROG1 (LETT #1# (|Join| (|FieldOfPrimeCharacteristic|) (|Finite|) (|StepThrough|) (|DifferentialRing|) (|mkCategory| (QUOTE |domain|) (QUOTE (((|charthRoot| (|$| |$|)) T) ((|conditionP| ((|Union| (|Vector| |$|) "failed") (|Matrix| |$|))) T) ((|factorsOfCyclicGroupSize| ((|List| (|Record| (|:| |factor| (|Integer|)) (|:| |exponent| (|Integer|)))))) T) ((|tableForDiscreteLogarithm| ((|Table| (|PositiveInteger|) (|NonNegativeInteger|)) (|Integer|))) T) ((|createPrimitiveElement| (|$|)) T) ((|primitiveElement| (|$|)) T) ((|primitive?| ((|Boolean|) |$|)) T) ((|discreteLog| ((|NonNegativeInteger|) |$|)) T) ((|order| ((|PositiveInteger|) |$|)) T) ((|representationType| ((|Union| "prime" "polynomial" "normal" "cyclic"))) T))) NIL (QUOTE ((|PositiveInteger|) (|NonNegativeInteger|) (|Boolean|) (|Table| (|PositiveInteger|) (|NonNegativeInteger|)) (|Integer|) (|List| (|Record| (|:| |factor| (|Integer|)) (|:| |exponent| (|Integer|)))) (|Matrix| |$|))) NIL)) |FiniteFieldCategory|) (SETELT #1# 0 (QUOTE (|FiniteFieldCategory|)))))))
+
+(MAKEPROP (QUOTE |FiniteFieldCategory|) (QUOTE NILADIC) T)
+@
+\section{FFIELDC-.lsp BOOTSTRAP}
+{\bf FFIELDC-} depends on {\bf FFIELDC}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf FFIELDC-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf FFIELDC-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<FFIELDC-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |FFIELDC-;differentiate;2S;1| (|x| |$|) (|spadConstant| |$| 7))
+
+(DEFUN |FFIELDC-;init;S;2| (|$|) (|spadConstant| |$| 7))
+
+(DEFUN |FFIELDC-;nextItem;SU;3| (|a| |$|) (COND ((SPADCALL (LETT |a| (SPADCALL (|+| (SPADCALL |a| (QREFELT |$| 11)) 1) (QREFELT |$| 12)) |FFIELDC-;nextItem;SU;3|) (QREFELT |$| 14)) (CONS 1 "failed")) ((QUOTE T) (CONS 0 |a|))))
+
+(DEFUN |FFIELDC-;order;SOpc;4| (|e| |$|) (SPADCALL (SPADCALL |e| (QREFELT |$| 17)) (QREFELT |$| 20)))
+
+(DEFUN |FFIELDC-;conditionP;MU;5| (|mat| |$|) (PROG (|l|) (RETURN (SEQ (LETT |l| (SPADCALL |mat| (QREFELT |$| 24)) |FFIELDC-;conditionP;MU;5|) (COND ((OR (NULL |l|) (SPADCALL (ELT |$| 14) (|SPADfirst| |l|) (QREFELT |$| 27))) (EXIT (CONS 1 "failed")))) (EXIT (CONS 0 (SPADCALL (ELT |$| 28) (|SPADfirst| |l|) (QREFELT |$| 30))))))))
+
+(DEFUN |FFIELDC-;charthRoot;2S;6| (|x| |$|) (SPADCALL |x| (QUOTIENT2 (SPADCALL (QREFELT |$| 35)) (SPADCALL (QREFELT |$| 36))) (QREFELT |$| 37)))
+
+(DEFUN |FFIELDC-;charthRoot;SU;7| (|x| |$|) (CONS 0 (SPADCALL |x| (QREFELT |$| 28))))
+
+(DEFUN |FFIELDC-;createPrimitiveElement;S;8| (|$|) (PROG (|sm1| |start| |i| #1=#:G83175 |e| |found|) (RETURN (SEQ (LETT |sm1| (|-| (SPADCALL (QREFELT |$| 35)) 1) |FFIELDC-;createPrimitiveElement;S;8|) (LETT |start| (COND ((SPADCALL (SPADCALL (QREFELT |$| 42)) (CONS 1 "polynomial") (QREFELT |$| 43)) (SPADCALL (QREFELT |$| 36))) ((QUOTE T) 1)) |FFIELDC-;createPrimitiveElement;S;8|) (LETT |found| (QUOTE NIL) |FFIELDC-;createPrimitiveElement;S;8|) (SEQ (LETT |i| |start| |FFIELDC-;createPrimitiveElement;S;8|) G190 (COND ((NULL (COND (|found| (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |e| (SPADCALL (PROG1 (LETT #1# |i| |FFIELDC-;createPrimitiveElement;S;8|) (|check-subtype| (|>| #1# 0) (QUOTE (|PositiveInteger|)) #1#)) (QREFELT |$| 12)) |FFIELDC-;createPrimitiveElement;S;8|) (EXIT (LETT |found| (EQL (SPADCALL |e| (QREFELT |$| 17)) |sm1|) |FFIELDC-;createPrimitiveElement;S;8|))) (LETT |i| (|+| |i| 1) |FFIELDC-;createPrimitiveElement;S;8|) (GO G190) G191 (EXIT NIL)) (EXIT |e|)))))
+
+(DEFUN |FFIELDC-;primitive?;SB;9| (|a| |$|) (PROG (|explist| |q| |exp| #1=#:G83187 |equalone|) (RETURN (SEQ (COND ((SPADCALL |a| (QREFELT |$| 14)) (QUOTE NIL)) ((QUOTE T) (SEQ (LETT |explist| (SPADCALL (QREFELT |$| 47)) |FFIELDC-;primitive?;SB;9|) (LETT |q| (|-| (SPADCALL (QREFELT |$| 35)) 1) |FFIELDC-;primitive?;SB;9|) (LETT |equalone| (QUOTE NIL) |FFIELDC-;primitive?;SB;9|) (SEQ (LETT |exp| NIL |FFIELDC-;primitive?;SB;9|) (LETT #1# |explist| |FFIELDC-;primitive?;SB;9|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |exp| (CAR #1#) |FFIELDC-;primitive?;SB;9|) NIL) (NULL (COND (|equalone| (QUOTE NIL)) ((QUOTE T) (QUOTE T))))) (GO G191))) (SEQ (EXIT (LETT |equalone| (SPADCALL (SPADCALL |a| (QUOTIENT2 |q| (QCAR |exp|)) (QREFELT |$| 48)) (QREFELT |$| 49)) |FFIELDC-;primitive?;SB;9|))) (LETT #1# (CDR #1#) |FFIELDC-;primitive?;SB;9|) (GO G190) G191 (EXIT NIL)) (EXIT (COND (|equalone| (QUOTE NIL)) ((QUOTE T) (QUOTE T)))))))))))
+
+(DEFUN |FFIELDC-;order;SPi;10| (|e| |$|) (PROG (|lof| |rec| #1=#:G83195 |primeDivisor| |j| #2=#:G83196 |a| |goon| |ord|) (RETURN (SEQ (COND ((SPADCALL |e| (|spadConstant| |$| 7) (QREFELT |$| 51)) (|error| "order(0) is not defined ")) ((QUOTE T) (SEQ (LETT |ord| (|-| (SPADCALL (QREFELT |$| 35)) 1) |FFIELDC-;order;SPi;10|) (LETT |a| 0 |FFIELDC-;order;SPi;10|) (LETT |lof| (SPADCALL (QREFELT |$| 47)) |FFIELDC-;order;SPi;10|) (SEQ (LETT |rec| NIL |FFIELDC-;order;SPi;10|) (LETT #1# |lof| |FFIELDC-;order;SPi;10|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |rec| (CAR #1#) |FFIELDC-;order;SPi;10|) NIL)) (GO G191))) (SEQ (LETT |a| (QUOTIENT2 |ord| (LETT |primeDivisor| (QCAR |rec|) |FFIELDC-;order;SPi;10|)) |FFIELDC-;order;SPi;10|) (LETT |goon| (SPADCALL (SPADCALL |e| |a| (QREFELT |$| 48)) (QREFELT |$| 49)) |FFIELDC-;order;SPi;10|) (SEQ (LETT |j| 0 |FFIELDC-;order;SPi;10|) (LETT #2# (|-| (QCDR |rec|) 2) |FFIELDC-;order;SPi;10|) G190 (COND ((OR (QSGREATERP |j| #2#) (NULL |goon|)) (GO G191))) (SEQ (LETT |ord| |a| |FFIELDC-;order;SPi;10|) (LETT |a| (QUOTIENT2 |ord| |primeDivisor|) |FFIELDC-;order;SPi;10|) (EXIT (LETT |goon| (SPADCALL (SPADCALL |e| |a| (QREFELT |$| 48)) (QREFELT |$| 49)) |FFIELDC-;order;SPi;10|))) (LETT |j| (QSADD1 |j|) |FFIELDC-;order;SPi;10|) (GO G190) G191 (EXIT NIL)) (EXIT (COND (|goon| (LETT |ord| |a| |FFIELDC-;order;SPi;10|))))) (LETT #1# (CDR #1#) |FFIELDC-;order;SPi;10|) (GO G190) G191 (EXIT NIL)) (EXIT |ord|))))))))
+
+(DEFUN |FFIELDC-;discreteLog;SNni;11| (|b| |$|) (PROG (|faclist| |gen| |groupord| |f| #1=#:G83216 |fac| |t| #2=#:G83217 |exp| |exptable| |n| |end| |i| |rho| |found| |disc1| |c| |mult| |disclog| |a|) (RETURN (SEQ (COND ((SPADCALL |b| (QREFELT |$| 14)) (|error| "discreteLog: logarithm of zero")) ((QUOTE T) (SEQ (LETT |faclist| (SPADCALL (QREFELT |$| 47)) |FFIELDC-;discreteLog;SNni;11|) (LETT |a| |b| |FFIELDC-;discreteLog;SNni;11|) (LETT |gen| (SPADCALL (QREFELT |$| 53)) |FFIELDC-;discreteLog;SNni;11|) (EXIT (COND ((SPADCALL |b| |gen| (QREFELT |$| 51)) 1) ((QUOTE T) (SEQ (LETT |disclog| 0 |FFIELDC-;discreteLog;SNni;11|) (LETT |mult| 1 |FFIELDC-;discreteLog;SNni;11|) (LETT |groupord| (|-| (SPADCALL (QREFELT |$| 35)) 1) |FFIELDC-;discreteLog;SNni;11|) (LETT |exp| |groupord| |FFIELDC-;discreteLog;SNni;11|) (SEQ (LETT |f| NIL |FFIELDC-;discreteLog;SNni;11|) (LETT #1# |faclist| |FFIELDC-;discreteLog;SNni;11|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |f| (CAR #1#) |FFIELDC-;discreteLog;SNni;11|) NIL)) (GO G191))) (SEQ (LETT |fac| (QCAR |f|) |FFIELDC-;discreteLog;SNni;11|) (EXIT (SEQ (LETT |t| 0 |FFIELDC-;discreteLog;SNni;11|) (LETT #2# (|-| (QCDR |f|) 1) |FFIELDC-;discreteLog;SNni;11|) G190 (COND ((QSGREATERP |t| #2#) (GO G191))) (SEQ (LETT |exp| (QUOTIENT2 |exp| |fac|) |FFIELDC-;discreteLog;SNni;11|) (LETT |exptable| (SPADCALL |fac| (QREFELT |$| 55)) |FFIELDC-;discreteLog;SNni;11|) (LETT |n| (SPADCALL |exptable| (QREFELT |$| 56)) |FFIELDC-;discreteLog;SNni;11|) (LETT |c| (SPADCALL |a| |exp| (QREFELT |$| 48)) |FFIELDC-;discreteLog;SNni;11|) (LETT |end| (QUOTIENT2 (|-| |fac| 1) |n|) |FFIELDC-;discreteLog;SNni;11|) (LETT |found| (QUOTE NIL) |FFIELDC-;discreteLog;SNni;11|) (LETT |disc1| 0 |FFIELDC-;discreteLog;SNni;11|) (SEQ (LETT |i| 0 |FFIELDC-;discreteLog;SNni;11|) G190 (COND ((OR (QSGREATERP |i| |end|) (NULL (COND (|found| (QUOTE NIL)) ((QUOTE T) (QUOTE T))))) (GO G191))) (SEQ (LETT |rho| (SPADCALL (SPADCALL |c| (QREFELT |$| 11)) |exptable| (QREFELT |$| 58)) |FFIELDC-;discreteLog;SNni;11|) (EXIT (COND ((QEQCAR |rho| 0) (SEQ (LETT |found| (QUOTE T) |FFIELDC-;discreteLog;SNni;11|) (EXIT (LETT |disc1| (|*| (|+| (|*| |n| |i|) (QCDR |rho|)) |mult|) |FFIELDC-;discreteLog;SNni;11|)))) ((QUOTE T) (LETT |c| (SPADCALL |c| (SPADCALL |gen| (|*| (QUOTIENT2 |groupord| |fac|) (|-| |n|)) (QREFELT |$| 48)) (QREFELT |$| 59)) |FFIELDC-;discreteLog;SNni;11|))))) (LETT |i| (QSADD1 |i|) |FFIELDC-;discreteLog;SNni;11|) (GO G190) G191 (EXIT NIL)) (EXIT (COND (|found| (SEQ (LETT |mult| (|*| |mult| |fac|) |FFIELDC-;discreteLog;SNni;11|) (LETT |disclog| (|+| |disclog| |disc1|) |FFIELDC-;discreteLog;SNni;11|) (EXIT (LETT |a| (SPADCALL |a| (SPADCALL |gen| (|-| |disc1|) (QREFELT |$| 48)) (QREFELT |$| 59)) |FFIELDC-;discreteLog;SNni;11|)))) ((QUOTE T) (|error| "discreteLog: ?? discrete logarithm"))))) (LETT |t| (QSADD1 |t|) |FFIELDC-;discreteLog;SNni;11|) (GO G190) G191 (EXIT NIL)))) (LETT #1# (CDR #1#) |FFIELDC-;discreteLog;SNni;11|) (GO G190) G191 (EXIT NIL)) (EXIT |disclog|))))))))))))
+
+(DEFUN |FFIELDC-;discreteLog;2SU;12| (|logbase| |b| |$|) (PROG (|groupord| |faclist| |f| #1=#:G83235 |fac| |primroot| |t| #2=#:G83236 |exp| |rhoHelp| #3=#:G83234 |rho| |disclog| |mult| |a|) (RETURN (SEQ (EXIT (COND ((SPADCALL |b| (QREFELT |$| 14)) (SEQ (SPADCALL "discreteLog: logarithm of zero" (QREFELT |$| 64)) (EXIT (CONS 1 "failed")))) ((SPADCALL |logbase| (QREFELT |$| 14)) (SEQ (SPADCALL "discreteLog: logarithm to base zero" (QREFELT |$| 64)) (EXIT (CONS 1 "failed")))) ((SPADCALL |b| |logbase| (QREFELT |$| 51)) (CONS 0 1)) ((QUOTE T) (COND ((NULL (ZEROP (REMAINDER2 (LETT |groupord| (SPADCALL |logbase| (QREFELT |$| 17)) |FFIELDC-;discreteLog;2SU;12|) (SPADCALL |b| (QREFELT |$| 17))))) (SEQ (SPADCALL "discreteLog: second argument not in cyclic group generated by first argument" (QREFELT |$| 64)) (EXIT (CONS 1 "failed")))) ((QUOTE T) (SEQ (LETT |faclist| (SPADCALL (SPADCALL |groupord| (QREFELT |$| 66)) (QREFELT |$| 68)) |FFIELDC-;discreteLog;2SU;12|) (LETT |a| |b| |FFIELDC-;discreteLog;2SU;12|) (LETT |disclog| 0 |FFIELDC-;discreteLog;2SU;12|) (LETT |mult| 1 |FFIELDC-;discreteLog;2SU;12|) (LETT |exp| |groupord| |FFIELDC-;discreteLog;2SU;12|) (SEQ (LETT |f| NIL |FFIELDC-;discreteLog;2SU;12|) (LETT #1# |faclist| |FFIELDC-;discreteLog;2SU;12|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |f| (CAR #1#) |FFIELDC-;discreteLog;2SU;12|) NIL)) (GO G191))) (SEQ (LETT |fac| (QCAR |f|) |FFIELDC-;discreteLog;2SU;12|) (LETT |primroot| (SPADCALL |logbase| (QUOTIENT2 |groupord| |fac|) (QREFELT |$| 48)) |FFIELDC-;discreteLog;2SU;12|) (EXIT (SEQ (LETT |t| 0 |FFIELDC-;discreteLog;2SU;12|) (LETT #2# (|-| (QCDR |f|) 1) |FFIELDC-;discreteLog;2SU;12|) G190 (COND ((QSGREATERP |t| #2#) (GO G191))) (SEQ (LETT |exp| (QUOTIENT2 |exp| |fac|) |FFIELDC-;discreteLog;2SU;12|) (LETT |rhoHelp| (SPADCALL |primroot| (SPADCALL |a| |exp| (QREFELT |$| 48)) |fac| (QREFELT |$| 70)) |FFIELDC-;discreteLog;2SU;12|) (EXIT (COND ((QEQCAR |rhoHelp| 1) (PROGN (LETT #3# (CONS 1 "failed") |FFIELDC-;discreteLog;2SU;12|) (GO #3#))) ((QUOTE T) (SEQ (LETT |rho| (|*| (QCDR |rhoHelp|) |mult|) |FFIELDC-;discreteLog;2SU;12|) (LETT |disclog| (|+| |disclog| |rho|) |FFIELDC-;discreteLog;2SU;12|) (LETT |mult| (|*| |mult| |fac|) |FFIELDC-;discreteLog;2SU;12|) (EXIT (LETT |a| (SPADCALL |a| (SPADCALL |logbase| (|-| |rho|) (QREFELT |$| 48)) (QREFELT |$| 59)) |FFIELDC-;discreteLog;2SU;12|))))))) (LETT |t| (QSADD1 |t|) |FFIELDC-;discreteLog;2SU;12|) (GO G190) G191 (EXIT NIL)))) (LETT #1# (CDR #1#) |FFIELDC-;discreteLog;2SU;12|) (GO G190) G191 (EXIT NIL)) (EXIT (CONS 0 |disclog|)))))))) #3# (EXIT #3#)))))
+
+(DEFUN |FFIELDC-;squareFreePolynomial| (|f| |$|) (SPADCALL |f| (QREFELT |$| 75)))
+
+(DEFUN |FFIELDC-;factorPolynomial| (|f| |$|) (SPADCALL |f| (QREFELT |$| 77)))
+
+(DEFUN |FFIELDC-;factorSquareFreePolynomial| (|f| |$|) (PROG (|flist| |u| #1=#:G83248 #2=#:G83245 #3=#:G83243 #4=#:G83244) (RETURN (SEQ (COND ((SPADCALL |f| (|spadConstant| |$| 78) (QREFELT |$| 79)) (|spadConstant| |$| 80)) ((QUOTE T) (SEQ (LETT |flist| (SPADCALL |f| (QUOTE T) (QREFELT |$| 83)) |FFIELDC-;factorSquareFreePolynomial|) (EXIT (SPADCALL (SPADCALL (QCAR |flist|) (QREFELT |$| 84)) (PROGN (LETT #4# NIL |FFIELDC-;factorSquareFreePolynomial|) (SEQ (LETT |u| NIL |FFIELDC-;factorSquareFreePolynomial|) (LETT #1# (QCDR |flist|) |FFIELDC-;factorSquareFreePolynomial|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |u| (CAR #1#) |FFIELDC-;factorSquareFreePolynomial|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL (QCAR |u|) (QCDR |u|) (QREFELT |$| 85)) |FFIELDC-;factorSquareFreePolynomial|) (COND (#4# (LETT #3# (SPADCALL #3# #2# (QREFELT |$| 86)) |FFIELDC-;factorSquareFreePolynomial|)) ((QUOTE T) (PROGN (LETT #3# #2# |FFIELDC-;factorSquareFreePolynomial|) (LETT #4# (QUOTE T) |FFIELDC-;factorSquareFreePolynomial|))))))) (LETT #1# (CDR #1#) |FFIELDC-;factorSquareFreePolynomial|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) (|spadConstant| |$| 87)))) (QREFELT |$| 88))))))))))
+
+(DEFUN |FFIELDC-;gcdPolynomial;3Sup;16| (|f| |g| |$|) (SPADCALL |f| |g| (QREFELT |$| 90)))
+
+(DEFUN |FiniteFieldCategory&| (|#1|) (PROG (|DV$1| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|FiniteFieldCategory&|)) (LETT |dv$| (LIST (QUOTE |FiniteFieldCategory&|) |DV$1|) . #1#) (LETT |$| (GETREFV 93) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) |$|))))
+
+(MAKEPROP (QUOTE |FiniteFieldCategory&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (0 . |Zero|) |FFIELDC-;differentiate;2S;1| |FFIELDC-;init;S;2| (|PositiveInteger|) (4 . |lookup|) (9 . |index|) (|Boolean|) (14 . |zero?|) (|Union| |$| (QUOTE "failed")) |FFIELDC-;nextItem;SU;3| (19 . |order|) (|Integer|) (|OnePointCompletion| 10) (24 . |coerce|) |FFIELDC-;order;SOpc;4| (|List| 26) (|Matrix| 6) (29 . |nullSpace|) (|Mapping| 13 6) (|Vector| 6) (34 . |every?|) (40 . |charthRoot|) (|Mapping| 6 6) (45 . |map|) (|Union| (|Vector| |$|) (QUOTE "failed")) (|Matrix| |$|) |FFIELDC-;conditionP;MU;5| (|NonNegativeInteger|) (51 . |size|) (55 . |characteristic|) (59 . |**|) |FFIELDC-;charthRoot;2S;6| |FFIELDC-;charthRoot;SU;7| (65 . |One|) (|Union| (QUOTE "prime") (QUOTE "polynomial") (QUOTE "normal") (QUOTE "cyclic")) (69 . |representationType|) (73 . |=|) |FFIELDC-;createPrimitiveElement;S;8| (|Record| (|:| |factor| 18) (|:| |exponent| 18)) (|List| 45) (79 . |factorsOfCyclicGroupSize|) (83 . |**|) (89 . |one?|) |FFIELDC-;primitive?;SB;9| (94 . |=|) |FFIELDC-;order;SPi;10| (100 . |primitiveElement|) (|Table| 10 34) (104 . |tableForDiscreteLogarithm|) (109 . |#|) (|Union| 34 (QUOTE "failed")) (114 . |search|) (120 . |*|) |FFIELDC-;discreteLog;SNni;11| (|Void|) (|String|) (|OutputForm|) (126 . |messagePrint|) (|Factored| |$|) (131 . |factor|) (|Factored| 18) (136 . |factors|) (|DiscreteLogarithmPackage| 6) (141 . |shanksDiscLogAlgorithm|) |FFIELDC-;discreteLog;2SU;12| (|Factored| 73) (|SparseUnivariatePolynomial| 6) (|UnivariatePolynomialSquareFree| 6 73) (148 . |squareFree|) (|DistinctDegreeFactorize| 6 73) (153 . |factor|) (158 . |Zero|) (162 . |=|) (168 . |Zero|) (|Record| (|:| |irr| 73) (|:| |pow| 18)) (|Record| (|:| |cont| 6) (|:| |factors| (|List| 81))) (172 . |distdfact|) (178 . |coerce|) (183 . |primeFactor|) (189 . |*|) (195 . |One|) (199 . |*|) (|EuclideanDomain&| 73) (205 . |gcd|) (|SparseUnivariatePolynomial| |$|) |FFIELDC-;gcdPolynomial;3Sup;16|)) (QUOTE #(|primitive?| 211 |order| 216 |nextItem| 226 |init| 231 |gcdPolynomial| 235 |discreteLog| 241 |differentiate| 252 |createPrimitiveElement| 257 |conditionP| 261 |charthRoot| 266)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 92 (QUOTE (0 6 0 7 1 6 10 0 11 1 6 0 10 12 1 6 13 0 14 1 6 10 0 17 1 19 0 18 20 1 23 22 0 24 2 26 13 25 0 27 1 6 0 0 28 2 26 0 29 0 30 0 6 34 35 0 6 34 36 2 6 0 0 34 37 0 6 0 40 0 6 41 42 2 41 13 0 0 43 0 6 46 47 2 6 0 0 18 48 1 6 13 0 49 2 6 13 0 0 51 0 6 0 53 1 6 54 18 55 1 54 34 0 56 2 54 57 10 0 58 2 6 0 0 0 59 1 63 61 62 64 1 18 65 0 66 1 67 46 0 68 3 69 57 6 6 34 70 1 74 72 73 75 1 76 72 73 77 0 73 0 78 2 73 13 0 0 79 0 72 0 80 2 76 82 73 13 83 1 73 0 6 84 2 72 0 73 18 85 2 72 0 0 0 86 0 72 0 87 2 72 0 73 0 88 2 89 0 0 0 90 1 0 13 0 50 1 0 10 0 52 1 0 19 0 21 1 0 15 0 16 0 0 0 9 2 0 91 91 91 92 1 0 34 0 60 2 0 57 0 0 71 1 0 0 0 8 0 0 0 44 1 0 31 32 33 1 0 0 0 38 1 0 15 0 39)))))) (QUOTE |lookupComplete|)))
+@
+\section{package FFSLPE FiniteFieldSolveLinearPolynomialEquation}
+<<package FFSLPE FiniteFieldSolveLinearPolynomialEquation>>=
+)abbrev package FFSLPE FiniteFieldSolveLinearPolynomialEquation
+++ Author: Davenport
+++ Date Created: 1991
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package solves linear diophantine equations for Bivariate polynomials
+++ over finite fields
+
+FiniteFieldSolveLinearPolynomialEquation(F:FiniteFieldCategory,
+ FP:UnivariatePolynomialCategory F,
+ FPP:UnivariatePolynomialCategory FP): with
+ solveLinearPolynomialEquation: (List FPP, FPP) -> Union(List FPP,"failed")
+ ++ solveLinearPolynomialEquation([f1, ..., fn], g)
+ ++ (where the fi are relatively prime to each other)
+ ++ returns a list of ai such that
+ ++ \spad{g/prod fi = sum ai/fi}
+ ++ or returns "failed" if no such list of ai's exists.
+ == add
+ oldlp:List FPP := []
+ slpePrime: FP := monomial(1,1)
+ oldtable:Vector List FPP := []
+ lp: List FPP
+ p: FPP
+ import DistinctDegreeFactorize(F,FP)
+ solveLinearPolynomialEquation(lp,p) ==
+ if (oldlp ^= lp) then
+ -- we have to generate a new table
+ deg:= +/[degree u for u in lp]
+ ans:Union(Vector List FPP,"failed"):="failed"
+ slpePrime:=monomial(1,1)+monomial(1,0) -- x+1: our starting guess
+ while (ans case "failed") repeat
+ ans:=tablePow(deg,slpePrime,lp)$GenExEuclid(FP,FPP)
+ if (ans case "failed") then
+ slpePrime:= nextItem(slpePrime)::FP
+ while (degree slpePrime > 1) and
+ not irreducible? slpePrime repeat
+ slpePrime := nextItem(slpePrime)::FP
+ oldtable:=(ans:: Vector List FPP)
+ answer:=solveid(p,slpePrime,oldtable)
+ answer
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DLP DiscreteLogarithmPackage>>
+<<category FPC FieldOfPrimeCharacteristic>>
+<<category XF ExtensionField>>
+<<category FAXF FiniteAlgebraicExtensionField>>
+<<category FFIELDC FiniteFieldCategory>>
+<<package FFSLPE FiniteFieldSolveLinearPolynomialEquation>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffcg.spad.pamphlet b/src/algebra/ffcg.spad.pamphlet
new file mode 100644
index 00000000..a2667c0f
--- /dev/null
+++ b/src/algebra/ffcg.spad.pamphlet
@@ -0,0 +1,467 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffcg.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- 28.01.93: AS and JG: setting of initzech? and initelt? flags in
+-- functions initializeZech and initializeElt put at the
+-- end to avoid errors with interruption.
+-- factorsOfCyclicGroupSize() changed.
+-- 12.05.92: JG: long lines
+-- 25.02.92: AS: added functions order and primitive?
+-- 19.02.92: AS: implementation of basis:PI -> Vector $ changed .
+-- 17.02.92: AS: implementation of coordinates corrected.
+-- 10.02.92: AS: implementation of coerce:GF -> $ corrected.
+-- 05.08.91: JG: AS implementation of missing functions in FFC and FAXF
+
+
+-- finite field represented by it's cyclic group and 'zero' as an
+-- extra element
+\end{verbatim}
+\section{domain FFCGP FiniteFieldCyclicGroupExtensionByPolynomial}
+<<domain FFCGP FiniteFieldCyclicGroupExtensionByPolynomial>>=
+)abbrev domain FFCGP FiniteFieldCyclicGroupExtensionByPolynomial
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors: FiniteFieldFunctions
+++ Also See: FiniteFieldExtensionByPolynomial,
+++ FiniteFieldNormalBasisExtensionByPolynomial
+++ AMS Classifications:
+++ Keywords: finite field, primitive elements, cyclic group
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldCyclicGroupExtensionByPolynomial(GF,defpol) implements a
+++ finite extension field of the ground field {\em GF}. Its elements are
+++ represented by powers of a primitive element, i.e. a generator of the
+++ multiplicative (cyclic) group. As primitive
+++ element we choose the root of the extension polynomial {\em defpol},
+++ which MUST be primitive (user responsibility). Zech logarithms are stored
+++ in a table of size half of the field size, and use \spadtype{SingleInteger}
+++ for representing field elements, hence, there are restrictions
+++ on the size of the field.
+
+
+FiniteFieldCyclicGroupExtensionByPolynomial(GF,defpol):_
+ Exports == Implementation where
+ GF : FiniteFieldCategory -- the ground field
+ defpol: SparseUnivariatePolynomial GF -- the extension polynomial
+ -- the root of defpol is used as the primitive element
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ SI ==> SingleInteger
+ SUP ==> SparseUnivariatePolynomial
+ SAE ==> SimpleAlgebraicExtension(GF,SUP GF,defpol)
+ V ==> Vector GF
+ FFP ==> FiniteFieldExtensionByPolynomial(GF,defpol)
+ FFF ==> FiniteFieldFunctions(GF)
+ OUT ==> OutputForm
+ ARR ==> PrimitiveArray(SI)
+ TBL ==> Table(PI,NNI)
+
+
+ Exports ==> FiniteAlgebraicExtensionField(GF) with
+
+ getZechTable:() -> ARR
+ ++ getZechTable() returns the zech logarithm table of the field
+ ++ it is used to perform additions in the field quickly.
+ Implementation ==> add
+
+-- global variables ===================================================
+
+ Rep:= SI
+ -- elements are represented by small integers in the range
+ -- (-1)..(size()-2). The (-1) representing the field element zero,
+ -- the other small integers representing the corresponding power
+ -- of the primitive element, the root of the defining polynomial
+
+ -- it would be very nice if we could use the representation
+ -- Rep:= Union("zero", IntegerMod(size()$GF ** degree(defpol) -1)),
+ -- why doesn't the compiler like this ?
+
+ extdeg:NNI :=degree(defpol)$(SUP GF)::NNI
+ -- the extension degree
+
+ sizeFF:NNI:=(size()$GF ** extdeg) pretend NNI
+ -- the size of the field
+
+ if sizeFF > 2**20 then
+ error "field too large for this representation"
+
+ sizeCG:SI:=(sizeFF - 1) pretend SI
+ -- the order of the cyclic group
+
+ sizeFG:SI:=(sizeCG quo (size()$GF-1)) pretend SI
+ -- the order of the factor group
+
+
+ zechlog:ARR:=new(((sizeFF+1) quo 2)::NNI,-1::SI)$ARR
+ -- the table for the zech logarithm
+
+ alpha :=new()$Symbol :: OutputForm
+ -- get a new symbol for the output representation of
+ -- the elements
+
+ primEltGF:GF:=
+ odd?(extdeg)$I => -$GF coefficient(defpol,0)$(SUP GF)
+ coefficient(defpol,0)$(SUP GF)
+ -- the corresponding primitive element of the groundfield
+ -- equals the trace of the primitive element w.r.t. the groundfield
+
+ facOfGroupSize := nil()$(List Record(factor:Integer,exponent:Integer))
+ -- the factorization of sizeCG
+
+ initzech?:Boolean:=true
+ -- gets false after initialization of the zech logarithm array
+
+ initelt?:Boolean:=true
+ -- gets false after initialization of the normal element
+
+ normalElt:SI:=0
+ -- the global variable containing a normal element
+
+-- functions ==========================================================
+
+ -- for completeness we have to give a dummy implementation for
+ -- 'tableForDiscreteLogarithm', although this function is not
+ -- necessary in the cyclic group representation case
+
+ tableForDiscreteLogarithm(fac) == table()$TBL
+
+
+ getZechTable() == zechlog
+ initializeZech:() -> Void
+ initializeElt: () -> Void
+
+ order(x:$):PI ==
+ zero?(x) =>
+ error"order: order of zero undefined"
+ (sizeCG quo gcd(sizeCG,x pretend NNI))::PI
+
+ primitive?(x:$) ==
+-- zero?(x) or one?(x) => false
+ zero?(x) or (x = 1) => false
+ gcd(x::Rep,sizeCG)$Rep = 1$Rep => true
+ false
+
+ coordinates(x:$) ==
+ x=0 => new(extdeg,0)$(Vector GF)
+ primElement:SAE:=convert(monomial(1,1)$(SUP GF))$SAE
+-- the primitive element in the corresponding algebraic extension
+ coordinates(primElement **$SAE (x pretend SI))$SAE
+
+ x:$ + y:$ ==
+ if initzech? then initializeZech()
+ zero? x => y
+ zero? y => x
+ d:Rep:=positiveRemainder(y -$Rep x,sizeCG)$Rep
+ (d pretend SI) <= shift(sizeCG,-$SI (1$SI)) =>
+ zechlog.(d pretend SI) =$SI -1::SI => 0
+ addmod(x,zechlog.(d pretend SI) pretend Rep,sizeCG)$Rep
+ --d:Rep:=positiveRemainder(x -$Rep y,sizeCG)$Rep
+ d:Rep:=(sizeCG -$SI d)::Rep
+ addmod(y,zechlog.(d pretend SI) pretend Rep,sizeCG)$Rep
+ --positiveRemainder(x +$Rep zechlog.(d pretend SI) -$Rep d,sizeCG)$Rep
+
+
+ initializeZech() ==
+ zechlog:=createZechTable(defpol)$FFF
+ -- set initialization flag
+ initzech? := false
+ void()$Void
+
+ basis(n:PI) ==
+ extensionDegree() rem n ^= 0 =>
+ error("argument must divide extension degree")
+ m:=sizeCG quo (size()$GF**n-1)
+ [index((1+i*m) ::PI) for i in 0..(n-1)]::Vector $
+
+ n:I * x:$ == ((n::GF)::$) * x
+
+ minimalPolynomial(a) ==
+ f:SUP $:=monomial(1,1)$(SUP $) - monomial(a,0)$(SUP $)
+ u:$:=Frobenius(a)
+ while not(u = a) repeat
+ f:=f * (monomial(1,1)$(SUP $) - monomial(u,0)$(SUP $))
+ u:=Frobenius(u)
+ p:SUP GF:=0$(SUP GF)
+ while not zero?(f)$(SUP $) repeat
+ g:GF:=retract(leadingCoefficient(f)$(SUP $))
+ p:=p+monomial(g,_
+ degree(f)$(SUP $))$(SUP GF)
+ f:=reductum(f)$(SUP $)
+ p
+
+ factorsOfCyclicGroupSize() ==
+ if empty? facOfGroupSize then initializeElt()
+ facOfGroupSize
+
+ representationType() == "cyclic"
+
+ definingPolynomial() == defpol
+
+ random() ==
+ positiveRemainder(random()$Rep,sizeFF pretend Rep)$Rep -$Rep 1$Rep
+
+ represents(v) ==
+ u:FFP:=represents(v)$FFP
+ u =$FFP 0$FFP => 0
+ discreteLog(u)$FFP pretend Rep
+
+
+
+ coerce(e:GF):$ ==
+ zero?(e)$GF => 0
+ log:I:=discreteLog(primEltGF,e)$GF::NNI *$I sizeFG
+ -- version before 10.20.92: log pretend Rep
+ -- 1$GF is coerced to sizeCG pretend Rep by old version
+ -- now 1$GF is coerced to 0$Rep which is correct.
+ positiveRemainder(log,sizeCG) pretend Rep
+
+
+ retractIfCan(x:$) ==
+ zero? x => 0$GF
+ u:= (x::Rep) exquo$Rep (sizeFG pretend Rep)
+ u = "failed" => "failed"
+ primEltGF **$GF ((u::$) pretend SI)
+
+ retract(x:$) ==
+ a:=retractIfCan(x)
+ a="failed" => error "element not in groundfield"
+ a :: GF
+
+ basis() == [index(i :: PI) for i in 1..extdeg]::Vector $
+
+
+ inGroundField?(x) ==
+ zero? x=> true
+ positiveRemainder(x::Rep,sizeFG pretend Rep)$Rep =$Rep 0$Rep => true
+ false
+
+ discreteLog(b:$,x:$) ==
+ zero? x => "failed"
+ e:= extendedEuclidean(b,sizeCG,x)$Rep
+ e = "failed" => "failed"
+ e1:Record(coef1:$,coef2:$) := e :: Record(coef1:$,coef2:$)
+ positiveRemainder(e1.coef1,sizeCG)$Rep pretend NNI
+
+ - x:$ ==
+ zero? x => 0
+ characteristic() =$I 2 => x
+ addmod(x,shift(sizeCG,-1)$SI pretend Rep,sizeCG)
+
+ generator() == 1$SI
+ createPrimitiveElement() == 1$SI
+ primitiveElement() == 1$SI
+
+ discreteLog(x:$) ==
+ zero? x => error "discrete logarithm error"
+ x pretend NNI
+
+ normalElement() ==
+ if initelt? then initializeElt()
+ normalElt::$
+
+ initializeElt() ==
+ facOfGroupSize := factors(factor(sizeCG)$Integer)
+ normalElt:=createNormalElement() pretend SI
+ initelt?:=false
+ void()$Void
+
+ extensionDegree() == extdeg pretend PI
+
+ characteristic() == characteristic()$GF
+
+ lookup(x:$) ==
+ x =$Rep (-$Rep 1$Rep) => sizeFF pretend PI
+ (x +$Rep 1$Rep) pretend PI
+
+ index(a:PI) ==
+ positiveRemainder(a,sizeFF)$I pretend Rep -$Rep 1$Rep
+
+ 0 == (-$Rep 1$Rep)
+
+ 1 == 0$Rep
+
+-- to get a "exponent like" output form
+ coerce(x:$):OUT ==
+ x =$Rep (-$Rep 1$Rep) => "0"::OUT
+ x =$Rep 0$Rep => "1"::OUT
+ y:I:=lookup(x)-1
+ alpha **$OUT (y::OUT)
+
+ x:$ = y:$ == x =$Rep y
+
+ x:$ * y:$ ==
+ x = 0 => 0
+ y = 0 => 0
+ addmod(x,y,sizeCG)$Rep
+
+ a:GF * x:$ == coerce(a)@$ * x
+ x:$/a:GF == x/coerce(a)@$
+
+-- x:$ / a:GF ==
+-- a = 0$GF => error "division by zero"
+-- x * inv(coerce(a))
+
+ inv(x:$) ==
+ zero?(x) => error "inv: not invertible"
+-- one?(x) => 1
+ (x = 1) => 1
+ sizeCG -$Rep x
+
+ x:$ ** n:PI == x ** n::I
+
+ x:$ ** n:NNI == x ** n::I
+
+ x:$ ** n:I ==
+ m:Rep:=positiveRemainder(n,sizeCG)$I pretend Rep
+ m =$Rep 0$Rep => 1
+ x = 0 => 0
+ mulmod(m,x,sizeCG::Rep)$Rep
+
+@
+\section{domain FFCGX FiniteFieldCyclicGroupExtension}
+<<domain FFCGX FiniteFieldCyclicGroupExtension>>=
+)abbrev domain FFCGX FiniteFieldCyclicGroupExtension
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 04.04.1991
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FiniteFieldCyclicGroupExtensionByPolynomial,
+++ FiniteFieldPolynomialPackage
+++ Also See: FiniteFieldExtension, FiniteFieldNormalBasisExtension
+++ AMS Classifications:
+++ Keywords: finite field, primitive elements, cyclic group
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldCyclicGroupExtension(GF,n) implements a extension of degree n
+++ over the ground field {\em GF}. Its elements are represented by powers of
+++ a primitive element, i.e. a generator of the multiplicative (cyclic) group.
+++ As primitive element we choose the root of the extension polynomial, which
+++ is created by {\em createPrimitivePoly} from
+++ \spadtype{FiniteFieldPolynomialPackage}. Zech logarithms are stored
+++ in a table of size half of the field size, and use \spadtype{SingleInteger}
+++ for representing field elements, hence, there are restrictions
+++ on the size of the field.
+
+
+FiniteFieldCyclicGroupExtension(GF,extdeg):_
+ Exports == Implementation where
+ GF : FiniteFieldCategory
+ extdeg : PositiveInteger
+ PI ==> PositiveInteger
+ FFPOLY ==> FiniteFieldPolynomialPackage(GF)
+ SI ==> SingleInteger
+ Exports ==> FiniteAlgebraicExtensionField(GF) with
+ getZechTable:() -> PrimitiveArray(SingleInteger)
+ ++ getZechTable() returns the zech logarithm table of the field.
+ ++ This table is used to perform additions in the field quickly.
+ Implementation ==> FiniteFieldCyclicGroupExtensionByPolynomial(GF,_
+ createPrimitivePoly(extdeg)$FFPOLY)
+
+@
+\section{domain FFCG FiniteFieldCyclicGroup}
+<<domain FFCG FiniteFieldCyclicGroup>>=
+)abbrev domain FFCG FiniteFieldCyclicGroup
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 04.04.1991
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FiniteFieldCyclicGroupExtensionByPolynomial,
+++ FiniteFieldPolynomialPackage
+++ Also See: FiniteField, FiniteFieldNormalBasis
+++ AMS Classifications:
+++ Keywords: finite field, primitive elements, cyclic group
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ Description:
+++ FiniteFieldCyclicGroup(p,n) implements a finite field extension of degee n
+++ over the prime field with p elements. Its elements are represented by
+++ powers of a primitive element, i.e. a generator of the multiplicative
+++ (cyclic) group. As primitive element we choose the root of the extension
+++ polynomial, which is created by {\em createPrimitivePoly} from
+++ \spadtype{FiniteFieldPolynomialPackage}. The Zech logarithms are stored
+++ in a table of size half of the field size, and use \spadtype{SingleInteger}
+++ for representing field elements, hence, there are restrictions
+++ on the size of the field.
+
+FiniteFieldCyclicGroup(p,extdeg):_
+ Exports == Implementation where
+ p : PositiveInteger
+ extdeg : PositiveInteger
+ PI ==> PositiveInteger
+ FFPOLY ==> FiniteFieldPolynomialPackage(PrimeField(p))
+ SI ==> SingleInteger
+ Exports ==> FiniteAlgebraicExtensionField(PrimeField(p)) with
+ getZechTable:() -> PrimitiveArray(SingleInteger)
+ ++ getZechTable() returns the zech logarithm table of the field.
+ ++ This table is used to perform additions in the field quickly.
+ Implementation ==> FiniteFieldCyclicGroupExtensionByPolynomial(PrimeField(p),_
+ createPrimitivePoly(extdeg)$FFPOLY)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FFCGP FiniteFieldCyclicGroupExtensionByPolynomial>>
+<<domain FFCGX FiniteFieldCyclicGroupExtension>>
+<<domain FFCG FiniteFieldCyclicGroup>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fff.spad.pamphlet b/src/algebra/fff.spad.pamphlet
new file mode 100644
index 00000000..858b9505
--- /dev/null
+++ b/src/algebra/fff.spad.pamphlet
@@ -0,0 +1,304 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fff.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- 12.03.92: AS: generalized createLowComplexityTable
+-- 25.02.92: AS: added functions:
+-- createLowComplexityTable: PI -> Union(Vector List TERM,"failed")
+-- createLowComplexityNormalBasis: PI -> Union(SUP, V L TERM)
+
+-- Finite Field Functions
+\end{verbatim}
+\section{package FFF FiniteFieldFunctions}
+<<package FFF FiniteFieldFunctions>>=
+)abbrev package FFF FiniteFieldFunctions
+++ Author: J. Grabmeier, A. Scheerhorn
+++ Date Created: 21 March 1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ References:
+++ Lidl, R. & Niederreiter, H., "Finite Fields",
+++ Encycl. of Math. 20, Addison-Wesley, 1983
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldFunctions(GF) is a package with functions
+++ concerning finite extension fields of the finite ground field {\em GF},
+++ e.g. Zech logarithms.
+++ Keywords: finite field, Zech logarithm, Jacobi logarithm, normal basis
+
+FiniteFieldFunctions(GF): Exports == Implementation where
+ GF : FiniteFieldCategory -- the ground field
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ SI ==> SingleInteger
+ SUP ==> SparseUnivariatePolynomial GF
+ V ==> Vector
+ M ==> Matrix
+ L ==> List
+ OUT ==> OutputForm
+ SAE ==> SimpleAlgebraicExtension
+ ARR ==> PrimitiveArray(SI)
+ TERM ==> Record(value:GF,index:SI)
+ MM ==> ModMonic(GF,SUP)
+ PF ==> PrimeField
+
+ Exports ==> with
+
+ createZechTable: SUP -> ARR
+ ++ createZechTable(f) generates a Zech logarithm table for the cyclic
+ ++ group representation of a extension of the ground field by the
+ ++ primitive polynomial {\em f(x)}, i.e. \spad{Z(i)},
+ ++ defined by {\em x**Z(i) = 1+x**i} is stored at index i.
+ ++ This is needed in particular
+ ++ to perform addition of field elements in finite fields represented
+ ++ in this way. See \spadtype{FFCGP}, \spadtype{FFCGX}.
+ createMultiplicationTable: SUP -> V L TERM
+ ++ createMultiplicationTable(f) generates a multiplication
+ ++ table for the normal basis of the field extension determined
+ ++ by {\em f}. This is needed to perform multiplications
+ ++ between elements represented as coordinate vectors to this basis.
+ ++ See \spadtype{FFNBP}, \spadtype{FFNBX}.
+ createMultiplicationMatrix: V L TERM -> M GF
+ ++ createMultiplicationMatrix(m) forms the multiplication table
+ ++ {\em m} into a matrix over the ground field.
+ -- only useful for the user to visualise the multiplication table
+ -- in a nice form
+ sizeMultiplication: V L TERM -> NNI
+ ++ sizeMultiplication(m) returns the number of entries
+ ++ of the multiplication table {\em m}.
+ -- the time of the multiplication of field elements depends
+ -- on this size
+ createLowComplexityTable: PI -> Union(Vector List TERM,"failed")
+ ++ createLowComplexityTable(n) tries to find
+ ++ a low complexity normal basis of degree {\em n} over {\em GF}
+ ++ and returns its multiplication matrix
+ ++ Fails, if it does not find a low complexity basis
+ createLowComplexityNormalBasis: PI -> Union(SUP, V L TERM)
+ ++ createLowComplexityNormalBasis(n) tries to find a
+ ++ a low complexity normal basis of degree {\em n} over {\em GF}
+ ++ and returns its multiplication matrix
+ ++ If no low complexity basis is found it calls
+ ++ \axiomFunFrom{createNormalPoly}{FiniteFieldPolynomialPackage}(n) to produce a normal
+ ++ polynomial of degree {\em n} over {\em GF}
+
+ Implementation ==> add
+
+
+ createLowComplexityNormalBasis(n) ==
+ (u:=createLowComplexityTable(n)) case "failed" =>
+ createNormalPoly(n)$FiniteFieldPolynomialPackage(GF)
+ u::(V L TERM)
+
+-- try to find a low complexity normal basis multiplication table
+-- of the field of extension degree n
+-- the algorithm is from:
+-- Wassermann A., Konstruktion von Normalbasen,
+-- Bayreuther Mathematische Schriften 31 (1989),1-9.
+
+ createLowComplexityTable(n) ==
+ q:=size()$GF
+ -- this algorithm works only for prime fields
+ p:=characteristic()$GF
+ -- search of a suitable parameter k
+ k:NNI:=0
+ for i in 1..n-1 while (k=0) repeat
+ if prime?(i*n+1) and not(p = (i*n+1)) then
+ primitive?(q::PF(i*n+1))$PF(i*n+1) =>
+ a:NNI:=1
+ k:=i
+ t1:PF(k*n+1):=(q::PF(k*n+1))**n
+ gcd(n,a:=discreteLog(q::PF(n*i+1))$PF(n*i+1))$I = 1 =>
+ k:=i
+ t1:=primitiveElement()$PF(k*n+1)**n
+ k = 0 => "failed"
+ -- initialize some start values
+ multmat:M PF(p):=zero(n,n)
+ p1:=(k*n+1)
+ pkn:=q::PF(p1)
+ t:=t1 pretend PF(p1)
+ if odd?(k) then
+ jt:I:=(n quo 2)+1
+ vt:I:=positiveRemainder((k-a) quo 2,k)+1
+ else
+ jt:I:=1
+ vt:I:=(k quo 2)+1
+ -- compute matrix
+ vec:Vector I:=zero(p1 pretend NNI)
+ for x in 1..k repeat
+ for l in 1..n repeat
+ vec.((t**(x-1) * pkn**(l-1)) pretend Integer+1):=_
+ positiveRemainder(l,p1)
+ lvj:M I:=zero(k::NNI,n)
+ for v in 1..k repeat
+ for j in 1..n repeat
+ if (j^=jt) or (v^=vt) then
+ help:PF(p1):=t**(v-1)*pkn**(j-1)+1@PF(p1)
+ setelt(lvj,v,j,vec.(help pretend I +1))
+ for j in 1..n repeat
+ if j^=jt then
+ for v in 1..k repeat
+ lvjh:=elt(lvj,v,j)
+ setelt(multmat,j,lvjh,elt(multmat,j,lvjh)+1)
+ for i in 1..n repeat
+ setelt(multmat,jt,i,positiveRemainder(-k,p)::PF(p))
+ for v in 1..k repeat
+ if v^=vt then
+ lvjh:=elt(lvj,v,jt)
+ setelt(multmat,jt,lvjh,elt(multmat,jt,lvjh)+1)
+ -- multmat
+ m:=nrows(multmat)$(M PF(p))
+ multtable:V L TERM:=new(m,nil()$(L TERM))$(V L TERM)
+ for i in 1..m repeat
+ l:L TERM:=nil()$(L TERM)
+ v:V PF(p):=row(multmat,i)
+ for j in (1::I)..(m::I) repeat
+ if (v.j ^= 0) then
+ -- take -v.j to get trace 1 instead of -1
+ term:TERM:=[(convert(-v.j)@I)::GF,(j-2) pretend SI]$TERM
+ l:=cons(term,l)$(L TERM)
+ qsetelt_!(multtable,i,copy l)$(V L TERM)
+ multtable
+
+ sizeMultiplication(m) ==
+ s:NNI:=0
+ for i in 1..#m repeat
+ s := s + #(m.i)
+ s
+
+ createMultiplicationTable(f:SUP) ==
+ sizeGF:NNI:=size()$GF -- the size of the ground field
+ m:PI:=degree(f)$SUP pretend PI
+ m=1 =>
+ [[[-coefficient(f,0)$SUP,(-1)::SI]$TERM]$(L TERM)]::(V L TERM)
+ m1:I:=m-1
+ -- initialize basis change matrices
+ setPoly(f)$MM
+ e:=reduce(monomial(1,1)$SUP)$MM ** sizeGF
+ w:=1$MM
+ qpow:PrimitiveArray(MM):=new(m,0)
+ qpow.0:=1$MM
+ for i in 1..m1 repeat
+ qpow.i:=(w:=w*e)
+ -- qpow.i = x**(i*q)
+ qexp:PrimitiveArray(MM):=new(m,0)
+ qexp.0:=reduce(monomial(1,1)$SUP)$MM
+ mat:M GF:=zero(m,m)$(M GF)
+ qsetelt_!(mat,2,1,1$GF)$(M GF)
+ h:=qpow.1
+ qexp.1:=h
+ setColumn_!(mat,2,Vectorise(h)$MM)$(M GF)
+ for i in 2..m1 repeat
+ g:=0$MM
+ while h ^= 0 repeat
+ g:=g + leadingCoefficient(h) * qpow.degree(h)$MM
+ h:=reductum(h)$MM
+ qexp.i:=g
+ setColumn_!(mat,i+1,Vectorise(h:=g)$MM)$(M GF)
+ -- loop invariant: qexp.i = x**(q**i)
+ mat1:=inverse(mat)$(M GF)
+ mat1 = "failed" =>
+ error "createMultiplicationTable: polynomial must be normal"
+ mat:=mat1 :: (M GF)
+ -- initialize multiplication table
+ multtable:V L TERM:=new(m,nil()$(L TERM))$(V L TERM)
+ for i in 1..m repeat
+ l:L TERM:=nil()$(L TERM)
+ v:V GF:=mat *$(M GF) Vectorise(qexp.(i-1) *$MM qexp.0)$MM
+ for j in (1::SI)..(m::SI) repeat
+ if (v.j ^= 0$GF) then
+ term:TERM:=[(v.j),j-(2::SI)]$TERM
+ l:=cons(term,l)$(L TERM)
+ qsetelt_!(multtable,i,copy l)$(V L TERM)
+ multtable
+
+
+ createZechTable(f:SUP) ==
+ sizeGF:NNI:=size()$GF -- the size of the ground field
+ m:=degree(f)$SUP::PI
+ qm1:SI:=(sizeGF ** m -1) pretend SI
+ zechlog:ARR:=new(((sizeGF ** m + 1) quo 2)::NNI,-1::SI)$ARR
+ helparr:ARR:=new(sizeGF ** m::NNI,0$SI)$ARR
+ primElement:=reduce(monomial(1,1)$SUP)$SAE(GF,SUP,f)
+ a:=primElement
+ for i in 1..qm1-1 repeat
+ helparr.(lookup(a -$SAE(GF,SUP,f) 1$SAE(GF,SUP,f)_
+ )$SAE(GF,SUP,f)):=i::SI
+ a:=a * primElement
+ characteristic() = 2 =>
+ a:=primElement
+ for i in 1..(qm1 quo 2) repeat
+ zechlog.i:=helparr.lookup(a)$SAE(GF,SUP,f)
+ a:=a * primElement
+ zechlog
+ a:=1$SAE(GF,SUP,f)
+ for i in 0..((qm1-2) quo 2) repeat
+ zechlog.i:=helparr.lookup(a)$SAE(GF,SUP,f)
+ a:=a * primElement
+ zechlog
+
+ createMultiplicationMatrix(m) ==
+ n:NNI:=#m
+ mat:M GF:=zero(n,n)$(M GF)
+ for i in 1..n repeat
+ for t in m.i repeat
+ qsetelt_!(mat,i,t.index+2,t.value)
+ mat
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FFF FiniteFieldFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffhom.spad.pamphlet b/src/algebra/ffhom.spad.pamphlet
new file mode 100644
index 00000000..50bf7ef1
--- /dev/null
+++ b/src/algebra/ffhom.spad.pamphlet
@@ -0,0 +1,431 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffhom.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- 28.01.93: AS and JG: setting of init? flag in
+-- functions initialize put at the
+-- end to avoid errors with interruption.
+-- 12.05.92 JG: long lines
+-- 17.02.92 AS: convertWRTdifferentDefPol12 and convertWRTdifferentDefPol21
+-- simplified.
+-- 17.02.92 AS: initialize() modified set up of basis change
+-- matrices between normal and polynomial rep.
+-- New version uses reducedQPowers and is more efficient.
+-- 24.07.92 JG: error messages improved
+\end{verbatim}
+\section{package FFHOM FiniteFieldHomomorphisms}
+<<package FFHOM FiniteFieldHomomorphisms>>=
+)abbrev package FFHOM FiniteFieldHomomorphisms
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FiniteFieldCategory, FiniteAlgebraicExtensionField
+++ Also See:
+++ AMS Classifications:
+++ Keywords: finite field, homomorphism, isomorphism
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldHomomorphisms(F1,GF,F2) exports coercion functions of
+++ elements between the fields {\em F1} and {\em F2}, which both must be
+++ finite simple algebraic extensions of the finite ground field {\em GF}.
+FiniteFieldHomomorphisms(F1,GF,F2): Exports == Implementation where
+ F1: FiniteAlgebraicExtensionField(GF)
+ GF: FiniteFieldCategory
+ F2: FiniteAlgebraicExtensionField(GF)
+ -- the homorphism can only convert elements w.r.t. the last extension .
+ -- Adding a function 'groundField()' which returns the groundfield of GF
+ -- as a variable of type FiniteFieldCategory in the new compiler, one
+ -- could build up 'convert' recursively to get an homomorphism w.r.t
+ -- the whole extension.
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ SI ==> SingleInteger
+ PI ==> PositiveInteger
+ SUP ==> SparseUnivariatePolynomial
+ M ==> Matrix GF
+ FFP ==> FiniteFieldExtensionByPolynomial
+ FFPOL2 ==> FiniteFieldPolynomialPackage2
+ FFPOLY ==> FiniteFieldPolynomialPackage
+ OUT ==> OutputForm
+
+ Exports ==> with
+
+ coerce: F1 -> F2
+ ++ coerce(x) is the homomorphic image of x from
+ ++ {\em F1} in {\em F2}. Thus {\em coerce} is a
+ ++ field homomorphism between the fields extensions
+ ++ {\em F1} and {\em F2} both over ground field {\em GF}
+ ++ (the second argument to the package).
+ ++ Error: if the extension degree of {\em F1} doesn't divide
+ ++ the extension degree of {\em F2}.
+ ++ Note that the other coercion function in the
+ ++ \spadtype{FiniteFieldHomomorphisms} is a left inverse.
+
+ coerce: F2 -> F1
+ ++ coerce(x) is the homomorphic image of x from
+ ++ {\em F2} in {\em F1}, where {\em coerce} is a
+ ++ field homomorphism between the fields extensions
+ ++ {\em F2} and {\em F1} both over ground field {\em GF}
+ ++ (the second argument to the package).
+ ++ Error: if the extension degree of {\em F2} doesn't divide
+ ++ the extension degree of {\em F1}.
+ ++ Note that the other coercion function in the
+ ++ \spadtype{FiniteFieldHomomorphisms} is a left inverse.
+ -- coerce(coerce(x:F1)@F2)@F1 = x and coerce(coerce(y:F2)@F1)@F2 = y
+
+ Implementation ==> add
+
+-- global variables ===================================================
+
+ degree1:NNI:= extensionDegree()$F1
+ degree2:NNI:= extensionDegree()$F2
+ -- the degrees of the last extension
+
+ -- a necessary condition for the one field being an subfield of
+ -- the other one is, that the respective extension degrees are
+ -- multiples
+ if max(degree1,degree2) rem min(degree1,degree2) ^= 0 then
+ error "FFHOM: one extension degree must divide the other one"
+
+ conMat1to2:M:= zero(degree2,degree1)$M
+ -- conversion Matix for the conversion direction F1 -> F2
+ conMat2to1:M:= zero(degree1,degree2)$M
+ -- conversion Matix for the conversion direction F2 -> F1
+
+ repType1:=representationType()$F1
+ repType2:=representationType()$F2
+ -- the representation types of the fields
+
+ init?:Boolean:=true
+ -- gets false after initialization
+
+ defPol1:=definingPolynomial()$F1
+ defPol2:=definingPolynomial()$F2
+ -- the defining polynomials of the fields
+
+
+-- functions ==========================================================
+
+
+ compare: (SUP GF,SUP GF) -> Boolean
+ -- compares two polynomials
+
+ convertWRTsameDefPol12: F1 -> F2
+ convertWRTsameDefPol21: F2 -> F1
+ -- homomorphism if the last extension of F1 and F2 was build up
+ -- using the same defining polynomials
+
+ convertWRTdifferentDefPol12: F1 -> F2
+ convertWRTdifferentDefPol21: F2 -> F1
+ -- homomorphism if the last extension of F1 and F2 was build up
+ -- with different defining polynomials
+
+ initialize: () -> Void
+ -- computes the conversion matrices
+
+ compare(g:(SUP GF),f:(SUP GF)) ==
+ degree(f)$(SUP GF) >$NNI degree(g)$(SUP GF) => true
+ degree(f)$(SUP GF) <$NNI degree(g)$(SUP GF) => false
+ equal:Integer:=0
+ for i in degree(f)$(SUP GF)..0 by -1 while equal=0 repeat
+ not zero?(coefficient(f,i)$(SUP GF))$GF and _
+ zero?(coefficient(g,i)$(SUP GF))$GF => equal:=1
+ not zero?(coefficient(g,i)$(SUP GF))$GF and _
+ zero?(coefficient(f,i)$(SUP GF))$GF => equal:=(-1)
+ (f1:=lookup(coefficient(f,i)$(SUP GF))$GF) >$PositiveInteger _
+ (g1:=lookup(coefficient(g,i)$(SUP GF))$GF) => equal:=1
+ f1 <$PositiveInteger g1 => equal:=(-1)
+ equal=1 => true
+ false
+
+ initialize() ==
+ -- 1) in the case of equal def. polynomials initialize is called only
+ -- if one of the rep. types is "normal" and the other one is "polynomial"
+ -- we have to compute the basis change matrix 'mat', which i-th
+ -- column are the coordinates of a**(q**i), the i-th component of
+ -- the normal basis ('a' the root of the def. polynomial and q the
+ -- size of the groundfield)
+ defPol1 =$(SUP GF) defPol2 =>
+ -- new code using reducedQPowers
+ mat:=zero(degree1,degree1)$M
+ arr:=reducedQPowers(defPol1)$FFPOLY(GF)
+ for i in 1..degree1 repeat
+ setColumn_!(mat,i,vectorise(arr.(i-1),degree1)$SUP(GF))$M
+ -- old code
+ -- here one of the representation types must be "normal"
+ --a:=basis()$FFP(GF,defPol1).2 -- the root of the def. polynomial
+ --setColumn_!(mat,1,coordinates(a)$FFP(GF,defPol1))$M
+ --for i in 2..degree1 repeat
+ -- a:= a **$FFP(GF,defPol1) size()$GF
+ -- setColumn_!(mat,i,coordinates(a)$FFP(GF,defPol1))$M
+ --for the direction "normal" -> "polynomial" we have to multiply the
+ -- coordinate vector of an element of the normal basis field with
+ -- the matrix 'mat'. In this case 'mat' is the correct conversion
+ -- matrix for the conversion of F1 to F2, its inverse the correct
+ -- inversion matrix for the conversion of F2 to F1
+ repType1 = "normal" => -- repType2 = "polynomial"
+ conMat1to2:=copy(mat)
+ conMat2to1:=copy(inverse(mat)$M :: M)
+ --we finish the function for one case, hence reset initialization flag
+ init? := false
+ void()$Void
+ -- print("'normal' <=> 'polynomial' matrices initialized"::OUT)
+ -- in the other case we have to change the matrices
+ -- repType2 = "normal" and repType1 = "polynomial"
+ conMat2to1:=copy(mat)
+ conMat1to2:=copy(inverse(mat)$M :: M)
+ -- print("'normal' <=> 'polynomial' matrices initialized"::OUT)
+ --we finish the function for one case, hence reset initialization flag
+ init? := false
+ void()$Void
+ -- 2) in the case of different def. polynomials we have to order the
+ -- fields to get the same isomorphism, if the package is called with
+ -- the fields F1 and F2 swapped.
+ dPbig:= defPol2
+ rTbig:= repType2
+ dPsmall:= defPol1
+ rTsmall:= repType1
+ degbig:=degree2
+ degsmall:=degree1
+ if compare(defPol2,defPol1) then
+ degsmall:=degree2
+ degbig:=degree1
+ dPbig:= defPol1
+ rTbig:= repType1
+ dPsmall:= defPol2
+ rTsmall:= repType2
+ -- 3) in every case we need a conversion between the polynomial
+ -- represented fields. Therefore we compute 'root' as a root of the
+ -- 'smaller' def. polynomial in the 'bigger' field.
+ -- We compute the matrix 'matsb', which i-th column are the coordinates
+ -- of the (i-1)-th power of root, i=1..degsmall. Multiplying a
+ -- coordinate vector of an element of the 'smaller' field by this
+ -- matrix, we got the coordinates of the corresponding element in the
+ -- 'bigger' field.
+ -- compute the root of dPsmall in the 'big' field
+ root:=rootOfIrreduciblePoly(dPsmall)$FFPOL2(FFP(GF,dPbig),GF)
+ -- set up matrix for polynomial conversion
+ matsb:=zero(degbig,degsmall)$M
+ qsetelt_!(matsb,1,1,1$GF)$M
+ a:=root
+ for i in 2..degsmall repeat
+ setColumn_!(matsb,i,coordinates(a)$FFP(GF,dPbig))$M
+ a := a *$FFP(GF,dPbig) root
+ -- the conversion from 'big' to 'small': we can't invert matsb
+ -- directly, because it has degbig rows and degsmall columns and
+ -- may be no square matrix. Therfore we construct a square matrix
+ -- mat from degsmall linear independent rows of matsb and invert it.
+ -- Now we get the conversion matrix 'matbs' for the conversion from
+ -- 'big' to 'small' by putting the columns of mat at the indices
+ -- of the linear independent rows of matsb to columns of matbs.
+ ra:I:=1 -- the rank
+ mat:M:=transpose(row(matsb,1))$M -- has already rank 1
+ rowind:I:=2
+ iVec:Vector I:=new(degsmall,1$I)$(Vector I)
+ while ra < degsmall repeat
+ if rank(vertConcat(mat,transpose(row(matsb,rowind))$M)$M)$M > ra then
+ mat:=vertConcat(mat,transpose(row(matsb,rowind))$M)$M
+ ra:=ra+1
+ iVec.ra := rowind
+ rowind:=rowind + 1
+ mat:=inverse(mat)$M :: M
+ matbs:=zero(degsmall,degbig)$M
+ for i in 1..degsmall repeat
+ setColumn_!(matbs,iVec.i,column(mat,i)$M)$M
+ -- print(matsb::OUT)
+ -- print(matbs::OUT)
+ -- 4) if the 'bigger' field is "normal" we have to compose the
+ -- polynomial conversion with a conversion from polynomial to normal
+ -- between the FFP(GF,dPbig) and FFNBP(GF,dPbig) the 'bigger'
+ -- field. Therefore we compute a conversion matrix 'mat' as in 1)
+ -- Multiplying with the inverse of 'mat' yields the desired
+ -- conversion from polynomial to normal. Multiplying this matrix by
+ -- the above computed 'matsb' we got the matrix for converting form
+ -- 'small polynomial' to 'big normal'.
+ -- set up matrix 'mat' for polynomial to normal
+ if rTbig = "normal" then
+ arr:=reducedQPowers(dPbig)$FFPOLY(GF)
+ mat:=zero(degbig,degbig)$M
+ for i in 1..degbig repeat
+ setColumn_!(mat,i,vectorise(arr.(i-1),degbig)$SUP(GF))$M
+ -- old code
+ --a:=basis()$FFP(GF,dPbig).2 -- the root of the def.Polynomial
+ --setColumn_!(mat,1,coordinates(a)$FFP(GF,dPbig))$M
+ --for i in 2..degbig repeat
+ -- a:= a **$FFP(GF,dPbig) size()$GF
+ -- setColumn_!(mat,i,coordinates(a)$FFP(GF,dPbig))$M
+ -- print(inverse(mat)$M::OUT)
+ matsb:= (inverse(mat)$M :: M) * matsb
+ -- print("inv *.."::OUT)
+ matbs:=matbs * mat
+ -- 5) if the 'smaller' field is "normal" we have first to convert
+ -- from 'small normal' to 'small polynomial', that is from
+ -- FFNBP(GF,dPsmall) to FFP(GF,dPsmall). Therefore we compute a
+ -- conversion matrix 'mat' as in 1). Multiplying with 'mat'
+ -- yields the desired conversion from normal to polynomial.
+ -- Multiplying the above computed 'matsb' with 'mat' we got the
+ -- matrix for converting form 'small normal' to 'big normal'.
+ -- set up matrix 'mat' for normal to polynomial
+ if rTsmall = "normal" then
+ arr:=reducedQPowers(dPsmall)$FFPOLY(GF)
+ mat:=zero(degsmall,degsmall)$M
+ for i in 1..degsmall repeat
+ setColumn_!(mat,i,vectorise(arr.(i-1),degsmall)$SUP(GF))$M
+ -- old code
+ --b:FFP(GF,dPsmall):=basis()$FFP(GF,dPsmall).2
+ --setColumn_!(mat,1,coordinates(b)$FFP(GF,dPsmall))$M
+ --for i in 2..degsmall repeat
+ -- b:= b **$FFP(GF,dPsmall) size()$GF
+ -- setColumn_!(mat,i,coordinates(b)$FFP(GF,dPsmall))$M
+ -- print(mat::OUT)
+ matsb:= matsb * mat
+ matbs:= (inverse(mat) :: M) * matbs
+ -- now 'matsb' is the corret conversion matrix for 'small' to 'big'
+ -- and 'matbs' the corret one for 'big' to 'small'.
+ -- depending on the above ordering the conversion matrices are
+ -- initialized
+ dPbig =$(SUP GF) defPol2 =>
+ conMat1to2 :=matsb
+ conMat2to1 :=matbs
+ -- print(conMat1to2::OUT)
+ -- print(conMat2to1::OUT)
+ -- print("conversion matrices initialized"::OUT)
+ --we finish the function for one case, hence reset initialization flag
+ init? := false
+ void()$Void
+ conMat1to2 :=matbs
+ conMat2to1 :=matsb
+ -- print(conMat1to2::OUT)
+ -- print(conMat2to1::OUT)
+ -- print("conversion matrices initialized"::OUT)
+ --we finish the function for one case, hence reset initialization flag
+ init? := false
+ void()$Void
+
+
+ coerce(x:F1) ==
+ inGroundField?(x)$F1 => retract(x)$F1 :: F2
+ -- if x is already in GF then we can use a simple coercion
+ defPol1 =$(SUP GF) defPol2 => convertWRTsameDefPol12(x)
+ convertWRTdifferentDefPol12(x)
+
+ convertWRTsameDefPol12(x:F1) ==
+ repType1 = repType2 => x pretend F2
+ -- same groundfields, same defining polynomials, same
+ -- representation types --> F1 = F2, x is already in F2
+ repType1 = "cyclic" =>
+ x = 0$F1 => 0$F2
+ -- the SI corresponding to the cyclic representation is the exponent of
+ -- the primitiveElement, therefore we exponentiate the primitiveElement
+ -- of F2 by it.
+ primitiveElement()$F2 **$F2 (x pretend SI)
+ repType2 = "cyclic" =>
+ x = 0$F1 => 0$F2
+ -- to get the exponent, we have to take the discrete logarithm of the
+ -- element in the given field.
+ (discreteLog(x)$F1 pretend SI) pretend F2
+ -- here one of the representation types is "normal"
+ if init? then initialize()
+ -- here a conversion matrix is necessary, (see initialize())
+ represents(conMat1to2 *$(Matrix GF) coordinates(x)$F1)$F2
+
+ convertWRTdifferentDefPol12(x:F1) ==
+ if init? then initialize()
+ -- if we want to convert into a 'smaller' field, we have to test,
+ -- whether the element is in the subfield of the 'bigger' field, which
+ -- corresponds to the 'smaller' field
+ if degree1 > degree2 then
+ if positiveRemainder(degree2,degree(x)$F1)^= 0 then
+ error "coerce: element doesn't belong to smaller field"
+ represents(conMat1to2 *$(Matrix GF) coordinates(x)$F1)$F2
+
+-- the three functions below equal the three functions above up to
+-- '1' exchanged by '2' in all domain and variable names
+
+
+ coerce(x:F2) ==
+ inGroundField?(x)$F2 => retract(x)$F2 :: F1
+ -- if x is already in GF then we can use a simple coercion
+ defPol1 =$(SUP GF) defPol2 => convertWRTsameDefPol21(x)
+ convertWRTdifferentDefPol21(x)
+
+ convertWRTsameDefPol21(x:F2) ==
+ repType1 = repType2 => x pretend F1
+ -- same groundfields, same defining polynomials,
+ -- same representation types --> F1 = F2, that is:
+ -- x is already in F1
+ repType2 = "cyclic" =>
+ x = 0$F2 => 0$F1
+ primitiveElement()$F1 **$F1 (x pretend SI)
+ repType1 = "cyclic" =>
+ x = 0$F2 => 0$F1
+ (discreteLog(x)$F2 pretend SI) pretend F1
+ -- here one of the representation types is "normal"
+ if init? then initialize()
+ represents(conMat2to1 *$(Matrix GF) coordinates(x)$F2)$F1
+
+ convertWRTdifferentDefPol21(x:F2) ==
+ if init? then initialize()
+ if degree2 > degree1 then
+ if positiveRemainder(degree1,degree(x)$F2)^= 0 then
+ error "coerce: element doesn't belong to smaller field"
+ represents(conMat2to1 *$(Matrix GF) coordinates(x)$F2)$F1
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FFHOM FiniteFieldHomomorphisms>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffnb.spad.pamphlet b/src/algebra/ffnb.spad.pamphlet
new file mode 100644
index 00000000..032c3501
--- /dev/null
+++ b/src/algebra/ffnb.spad.pamphlet
@@ -0,0 +1,887 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffnb.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- 28.01.93: AS and JG: setting of initlog?, initmult?, and initelt? flags in
+-- functions initializeLog, initializeMult and initializeElt put at the
+-- end to avoid errors with interruption.
+-- factorsOfCyclicGroupSize() changed.
+-- 12.05.92: JG: long lines
+-- 25.02.92: AS: parametrization of FFNBP changed, compatible to old
+-- parametrization. Along with this some changes concerning
+-- global variables and deletion of impl. of represents.
+-- 25.02.92: AS: parameter in implementation of FFNB,FFNBX changed:
+-- Extension now generated by
+-- createLowComplexityNormalBasis(extdeg)$FFF(GF)
+-- 25.02.92: AS added following functions in FFNBP: degree,
+-- linearAssociatedExp,linearAssociatedLog,linearAssociatedOrder
+-- 19.02.92: AS: FFNBP trace + norm added.
+-- 18.02.92: AS: INBFF normalElement corrected. The old one returned a wrong
+-- result for a FFNBP(FFNBP(..)) domain.
+\end{verbatim}
+\section{package INBFF InnerNormalBasisFieldFunctions}
+<<package INBFF InnerNormalBasisFieldFunctions>>=
+)abbrev package INBFF InnerNormalBasisFieldFunctions
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: finite field, normal basis
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ D.R.Stinson: Some observations on parallel Algorithms for fast
+++ exponentiation in GF(2^n), Siam J. Comp., Vol.19, No.4, pp.711-717,
+++ August 1990
+++ T.Itoh, S.Tsujii: A fast algorithm for computing multiplicative inverses
+++ in GF(2^m) using normal bases, Inf. and Comp. 78, pp.171-177, 1988
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ InnerNormalBasisFieldFunctions(GF) (unexposed):
+++ This package has functions used by
+++ every normal basis finite field extension domain.
+
+InnerNormalBasisFieldFunctions(GF): Exports == Implementation where
+ GF : FiniteFieldCategory -- the ground field
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ SI ==> SingleInteger
+ SUP ==> SparseUnivariatePolynomial
+ VGF ==> Vector GF
+ M ==> Matrix
+ V ==> Vector
+ L ==> List
+ OUT ==> OutputForm
+ TERM ==> Record(value:GF,index:SI)
+ MM ==> ModMonic(GF,SUP GF)
+
+ Exports ==> with
+
+ setFieldInfo: (V L TERM,GF) -> Void
+ ++ setFieldInfo(m,p) initializes the field arithmetic, where m is
+ ++ the multiplication table and p is the respective normal element
+ ++ of the ground field GF.
+ random : PI -> VGF
+ ++ random(n) creates a vector over the ground field with random entries.
+ index : (PI,PI) -> VGF
+ ++ index(n,m) is a index function for vectors of length n over
+ ++ the ground field.
+ pol : VGF -> SUP GF
+ ++ pol(v) turns the vector \spad{[v0,...,vn]} into the polynomial
+ ++ \spad{v0+v1*x+ ... + vn*x**n}.
+ xn : NNI -> SUP GF
+ ++ xn(n) returns the polynomial \spad{x**n-1}.
+ dAndcExp : (VGF,NNI,SI) -> VGF
+ ++ dAndcExp(v,n,k) computes \spad{v**e} interpreting v as an element of
+ ++ normal basis field. A divide and conquer algorithm similar to the
+ ++ one from D.R.Stinson,
+ ++ "Some observations on parallel Algorithms for fast exponentiation in
+ ++ GF(2^n)", Siam J. Computation, Vol.19, No.4, pp.711-717, August 1990
+ ++ is used. Argument k is a parameter of this algorithm.
+ repSq : (VGF,NNI) -> VGF
+ ++ repSq(v,e) computes \spad{v**e} by repeated squaring,
+ ++ interpreting v as an element of a normal basis field.
+ expPot : (VGF,SI,SI) -> VGF
+ ++ expPot(v,e,d) returns the sum from \spad{i = 0} to
+ ++ \spad{e - 1} of \spad{v**(q**i*d)}, interpreting
+ ++ v as an element of a normal basis field and where q is
+ ++ the size of the ground field.
+ ++ Note: for a description of the algorithm, see T.Itoh and S.Tsujii,
+ ++ "A fast algorithm for computing multiplicative inverses in GF(2^m)
+ ++ using normal bases",
+ ++ Information and Computation 78, pp.171-177, 1988.
+ qPot : (VGF,I) -> VGF
+ ++ qPot(v,e) computes \spad{v**(q**e)}, interpreting v as an element of
+ ++ normal basis field, q the size of the ground field.
+ ++ This is done by a cyclic e-shift of the vector v.
+
+-- the semantic of the following functions is obvious from the finite field
+-- context, for description see category FAXF
+ "**" :(VGF,I) -> VGF
+ ++ x**n \undocumented{}
+ ++ See \axiomFunFrom{**}{DivisionRing}
+ "*" :(VGF,VGF) -> VGF
+ ++ x*y \undocumented{}
+ ++ See \axiomFunFrom{*}{SemiGroup}
+ "/" :(VGF,VGF) -> VGF
+ ++ x/y \undocumented{}
+ ++ See \axiomFunFrom{/}{Field}
+ norm :(VGF,PI) -> VGF
+ ++ norm(x,n) \undocumented{}
+ ++ See \axiomFunFrom{norm}{FiniteAlgebraicExtensionField}
+ trace :(VGF,PI) -> VGF
+ ++ trace(x,n) \undocumented{}
+ ++ See \axiomFunFrom{trace}{FiniteAlgebraicExtensionField}
+ inv : VGF -> VGF
+ ++ inv x \undocumented{}
+ ++ See \axiomFunFrom{inv}{DivisionRing}
+ lookup : VGF -> PI
+ ++ lookup(x) \undocumented{}
+ ++ See \axiomFunFrom{lookup}{Finite}
+ normal? : VGF -> Boolean
+ ++ normal?(x) \undocumented{}
+ ++ See \axiomFunFrom{normal?}{FiniteAlgebraicExtensionField}
+ basis : PI -> V VGF
+ ++ basis(n) \undocumented{}
+ ++ See \axiomFunFrom{basis}{FiniteAlgebraicExtensionField}
+ normalElement:PI -> VGF
+ ++ normalElement(n) \undocumented{}
+ ++ See \axiomFunFrom{normalElement}{FiniteAlgebraicExtensionField}
+ minimalPolynomial: VGF -> SUP GF
+ ++ minimalPolynomial(x) \undocumented{}
+ ++ See \axiomFunFrom{minimalPolynomial}{FiniteAlgebraicExtensionField}
+
+ Implementation ==> add
+
+-- global variables ===================================================
+
+ sizeGF:NNI:=size()$GF
+ -- the size of the ground field
+
+ multTable:V L TERM:=new(1,nil()$(L TERM))$(V L TERM)
+ -- global variable containing the multiplication table
+
+ trGen:GF:=1$GF
+ -- controls the imbedding of the ground field
+
+ logq:List SI:=[0,10::SI,16::SI,20::SI,23::SI,0,28::SI,_
+ 30::SI,32::SI,0,35::SI]
+ -- logq.i is about 10*log2(i) for the values <12 which
+ -- can match sizeGF. It's used by "**"
+
+ expTable:L L SI:=[[],_
+ [4::SI,12::SI,48::SI,160::SI,480::SI,0],_
+ [8::SI,72::SI,432::SI,0],_
+ [18::SI,216::SI,0],_
+ [32::SI,480::SI,0],[],_
+ [72::SI,0],[98::SI,0],[128::SI,0],[],[200::SI,0]]
+ -- expT is used by "**" to optimize the parameter k
+ -- before calling dAndcExp(..,..,k)
+
+-- functions ===========================================================
+
+-- computes a**(-1) = a**((q**extDeg)-2)
+-- see reference of function expPot
+ inv(a) ==
+ b:VGF:=qPot(expPot(a,(#a-1)::NNI::SI,1::SI)$$,1)$$
+ erg:VGF:=inv((a *$$ b).1 *$GF trGen)$GF *$VGF b
+
+-- "**" decides which exponentiation algorithm will be used, in order to
+-- get the fastest computation. If dAndcExp is used, it chooses the
+-- optimal parameter k for that algorithm.
+ a ** ex ==
+ e:NNI:=positiveRemainder(ex,sizeGF**((#a)::PI)-1)$I :: NNI
+ zero?(e)$NNI => new(#a,trGen)$VGF
+-- one?(e)$NNI => copy(a)$VGF
+ (e = 1)$NNI => copy(a)$VGF
+-- inGroundField?(a) => new(#a,((a.1*trGen) **$GF e))$VGF
+ e1:SI:=(length(e)$I)::SI
+ sizeGF >$I 11 =>
+ q1:SI:=(length(sizeGF)$I)::SI
+ logqe:SI:=(e1 quo$SI q1) +$SI 1$SI
+ 10::SI * (logqe + sizeGF-2) > 15::SI * e1 =>
+-- print("repeatedSquaring"::OUT)
+ repSq(a,e)
+-- print("divAndConquer(a,e,1)"::OUT)
+ dAndcExp(a,e,1)
+ logqe:SI:=((10::SI *$SI e1) quo$SI (logq.sizeGF)) +$SI 1$SI
+ k:SI:=1$SI
+ expT:List SI:=expTable.sizeGF
+ while (logqe >= expT.k) and not zero? expT.k repeat k:=k +$SI 1$SI
+ mult:I:=(sizeGF-1) *$I sizeGF **$I ((k-1)pretend NNI) +$I_
+ ((logqe +$SI k -$SI 1$SI) quo$SI k)::I -$I 2
+ (10*mult) >= (15 * (e1::I)) =>
+-- print("repeatedSquaring(a,e)"::OUT)
+ repSq(a,e)
+-- print(hconcat(["divAndConquer(a,e,"::OUT,k::OUT,")"::OUT])$OUT)
+ dAndcExp(a,e,k)
+
+-- computes a**e by repeated squaring
+ repSq(b,e) ==
+ a:=copy(b)$VGF
+-- one? e => a
+ (e = 1) => a
+ odd?(e)$I => a * repSq(a*a,(e quo 2) pretend NNI)
+ repSq(a*a,(e quo 2) pretend NNI)
+
+-- computes a**e using the divide and conquer algorithm similar to the
+-- one from D.R.Stinson,
+-- "Some observations on parallel Algorithms for fast exponentiation in
+-- GF(2^n)", Siam J. Computation, Vol.19, No.4, pp.711-717, August 1990
+ dAndcExp(a,e,k) ==
+ plist:List VGF:=[copy(a)$VGF]
+ qk:I:=sizeGF**(k pretend NNI)
+ for j in 2..(qk-1) repeat
+ if positiveRemainder(j,sizeGF)=0 then b:=qPot(plist.(j quo sizeGF),1)$$
+ else b:=a *$$ last(plist)$(List VGF)
+ plist:=concat(plist,b)
+ l:List NNI:=nil()
+ ex:I:=e
+ while not(ex = 0) repeat
+ l:=concat(l,positiveRemainder(ex,qk) pretend NNI)
+ ex:=ex quo qk
+ if first(l)=0 then erg:VGF:=new(#a,trGen)$VGF
+ else erg:VGF:=plist.(first(l))
+ i:SI:=k
+ for j in rest(l) repeat
+ if j^=0 then erg:=erg *$$ qPot(plist.j,i)$$
+ i:=i+k
+ erg
+
+ a * b ==
+ e:SI:=(#a)::SI
+ erg:=zero(#a)$VGF
+ for t in multTable.1 repeat
+ for j in 1..e repeat
+ y:=t.value -- didn't work without defining x and y
+ x:=t.index
+ k:SI:=addmod(x,j::SI,e)$SI +$SI 1$SI
+ erg.k:=erg.k +$GF a.j *$GF b.j *$GF y
+ for i in 1..e-1 repeat
+ for j in i+1..e repeat
+ for t in multTable.(j-i+1) repeat
+ y:=t.value -- didn't work without defining x and y
+ x:=t.index
+ k:SI:=addmod(x,i::SI,e)$SI +$SI 1$SI
+ erg.k:GF:=erg.k +$GF (a.i *$GF b.j +$GF a.j *$GF b.i) *$GF y
+ erg
+
+ lookup(x) ==
+ erg:I:=0
+ for j in (#x)..1 by -1 repeat
+ erg:=(erg * sizeGF) + (lookup(x.j)$GF rem sizeGF)
+ erg=0 => (sizeGF**(#x)) :: PI
+ erg :: PI
+
+-- computes the norm of a over GF**d, d must devide extdeg
+-- see reference of function expPot below
+ norm(a,d) ==
+ dSI:=d::SI
+ r:=divide((#a)::SI,dSI)
+ not(r.remainder = 0) => error "norm: 2.arg must divide extdeg"
+ expPot(a,r.quotient,dSI)$$
+
+-- computes expPot(a,e,d) = sum form i=0 to e-1 over a**(q**id))
+-- see T.Itoh and S.Tsujii,
+-- "A fast algorithm for computing multiplicative inverses in GF(2^m)
+-- using normal bases",
+-- Information and Computation 78, pp.171-177, 1988
+ expPot(a,e,d) ==
+ deg:SI:=(#a)::SI
+ e=1 => copy(a)$VGF
+ k2:SI:=d
+ y:=copy(a)
+ if bit?(e,0) then
+ erg:=copy(y)
+ qpot:SI:=k2
+ else
+ erg:=new(#a,inv(trGen)$GF)$VGF
+ qpot:SI:=0
+ for k in 1..length(e) repeat
+ y:= y *$$ qPot(y,k2)
+ k2:=addmod(k2,k2,deg)$SI
+ if bit?(e,k) then
+ erg:=erg *$$ qPot(y,qpot)
+ qpot:=addmod(qpot,k2,deg)$SI
+ erg
+
+-- computes qPot(a,n) = a**(q**n), q=size of GF
+ qPot(e,n) ==
+ ei:=(#e)::SI
+ m:SI:= positiveRemainder(n::SI,ei)$SI
+ zero?(m) => e
+ e1:=zero(#e)$VGF
+ for i in m+1..ei repeat e1.i:=e.(i-m)
+ for i in 1..m repeat e1.i:=e.(ei+i-m)
+ e1
+
+ trace(a,d) ==
+ dSI:=d::SI
+ r:=divide((#a)::SI,dSI)$SI
+ not(r.remainder = 0) => error "trace: 2.arg must divide extdeg"
+ v:=copy(a.(1..dSI))$VGF
+ sSI:SI:=r.quotient
+ for i in 1..dSI repeat
+ for j in 1..sSI-1 repeat
+ v.i:=v.i+a.(i+j::SI*dSI)
+ v
+
+ random(n) ==
+ v:=zero(n)$VGF
+ for i in 1..n repeat v.i:=random()$GF
+ v
+
+
+ xn(m) == monomial(1,m)$(SUP GF) - 1$(SUP GF)
+
+ normal?(x) ==
+ gcd(xn(#x),pol(x))$(SUP GF) = 1 => true
+ false
+
+ x:VGF / y:VGF == x *$$ inv(y)$$
+
+
+ setFieldInfo(m,n) ==
+ multTable:=m
+ trGen:=n
+ void()$Void
+
+ minimalPolynomial(x) ==
+ dx:=#x
+ y:=new(#x,inv(trGen)$GF)$VGF
+ m:=zero(dx,dx+1)$(M GF)
+ for i in 1..dx+1 repeat
+ dy:=#y
+ for j in 1..dy repeat
+ for k in 0..((dx quo dy)-1) repeat
+ qsetelt_!(m,j+k*dy,i,y.j)$(M GF)
+ y:=y *$$ x
+ v:=first nullSpace(m)$(M GF)
+ pol(v)$$
+
+ basis(n) ==
+ bas:(V VGF):=new(n,zero(n)$VGF)$(V VGF)
+ for i in 1..n repeat
+ uniti:=zero(n)$VGF
+ qsetelt_!(uniti,i,1$GF)$VGF
+ qsetelt_!(bas,i,uniti)$(V VGF)
+ bas
+
+ normalElement(n) ==
+ v:=zero(n)$VGF
+ qsetelt_!(v,1,1$GF)
+ v
+-- normalElement(n) == index(n,1)$$
+
+ index(degm,n) ==
+ m:I:=n rem$I (sizeGF ** degm)
+ erg:=zero(degm)$VGF
+ for j in 1..degm repeat
+ erg.j:=index((sizeGF+(m rem sizeGF)) pretend PI)$GF
+ m:=m quo sizeGF
+ erg
+
+ pol(x) ==
+ +/[monomial(x.i,(i-1)::NNI)$(SUP GF) for i in 1..(#x)::I]
+
+@
+\section{domain FFNBP FiniteFieldNormalBasisExtensionByPolynomial}
+<<domain FFNBP FiniteFieldNormalBasisExtensionByPolynomial>>=
+)abbrev domain FFNBP FiniteFieldNormalBasisExtensionByPolynomial
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated: 08 May 1991
+++ Basic Operations:
+++ Related Constructors: InnerNormalBasisFieldFunctions, FiniteFieldFunctions,
+++ Also See: FiniteFieldExtensionByPolynomial,
+++ FiniteFieldCyclicGroupExtensionByPolynomial
+++ AMS Classifications:
+++ Keywords: finite field, normal basis
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM .
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldNormalBasisExtensionByPolynomial(GF,uni) implements a
+++ finite extension of the ground field {\em GF}. The elements are
+++ represented by coordinate vectors with respect to. a normal basis,
+++ i.e. a basis
+++ consisting of the conjugates (q-powers) of an element, in this case
+++ called normal element, where q is the size of {\em GF}.
+++ The normal element is chosen as a root of the extension
+++ polynomial, which MUST be normal over {\em GF} (user responsibility)
+FiniteFieldNormalBasisExtensionByPolynomial(GF,uni): Exports == _
+ Implementation where
+ GF : FiniteFieldCategory -- the ground field
+ uni : Union(SparseUnivariatePolynomial GF,_
+ Vector List Record(value:GF,index:SingleInteger))
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ SI ==> SingleInteger
+ SUP ==> SparseUnivariatePolynomial
+ V ==> Vector GF
+ M ==> Matrix GF
+ OUT ==> OutputForm
+ TERM ==> Record(value:GF,index:SI)
+ R ==> Record(key:PI,entry:NNI)
+ TBL ==> Table(PI,NNI)
+ FFF ==> FiniteFieldFunctions(GF)
+ INBFF ==> InnerNormalBasisFieldFunctions(GF)
+
+ Exports ==> FiniteAlgebraicExtensionField(GF) with
+
+ getMultiplicationTable: () -> Vector List TERM
+ ++ getMultiplicationTable() returns the multiplication
+ ++ table for the normal basis of the field.
+ ++ This table is used to perform multiplications between field elements.
+ getMultiplicationMatrix:() -> M
+ ++ getMultiplicationMatrix() returns the multiplication table in
+ ++ form of a matrix.
+ sizeMultiplication:() -> NNI
+ ++ sizeMultiplication() returns the number of entries in the
+ ++ multiplication table of the field.
+ ++ Note: the time of multiplication
+ ++ of field elements depends on this size.
+ Implementation ==> add
+
+-- global variables ===================================================
+
+ Rep:= V -- elements are represented by vectors over GF
+
+ alpha :=new()$Symbol :: OutputForm
+ -- get a new Symbol for the output representation of the elements
+
+ initlog?:Boolean:=true
+ -- gets false after initialization of the logarithm table
+
+ initelt?:Boolean:=true
+ -- gets false after initialization of the primitive element
+
+ initmult?:Boolean:=true
+ -- gets false after initialization of the multiplication
+ -- table or the primitive element
+
+ extdeg:PI :=1
+
+ defpol:SUP(GF):=0$SUP(GF)
+ -- the defining polynomial
+
+ multTable:Vector List TERM:=new(1,nil()$(List TERM))
+ -- global variable containing the multiplication table
+
+ if uni case (Vector List TERM) then
+ multTable:=uni :: (Vector List TERM)
+ extdeg:= (#multTable) pretend PI
+ vv:V:=new(extdeg,0)$V
+ vv.1:=1$GF
+ setFieldInfo(multTable,1$GF)$INBFF
+ defpol:=minimalPolynomial(vv)$INBFF
+ initmult?:=false
+ else
+ defpol:=uni :: SUP(GF)
+ extdeg:=degree(defpol)$(SUP GF) pretend PI
+ multTable:Vector List TERM:=new(extdeg,nil()$(List TERM))
+
+ basisOutput : List OUT :=
+ qs:OUT:=(q::Symbol)::OUT
+ append([alpha, alpha **$OUT qs],_
+ [alpha **$OUT (qs **$OUT i::OUT) for i in 2..extdeg-1] )
+
+
+ facOfGroupSize :=nil()$(List Record(factor:Integer,exponent:Integer))
+ -- the factorization of the cyclic group size
+
+
+ traceAlpha:GF:=-$GF coefficient(defpol,(degree(defpol)-1)::NNI)
+ -- the inverse of the trace of the normalElt
+ -- is computed here. It defines the imbedding of
+ -- GF in the extension field
+
+ primitiveElt:PI:=1
+ -- for the lookup the primitive Element computed by createPrimitiveElement()
+
+ discLogTable:Table(PI,TBL):=table()$Table(PI,TBL)
+ -- tables indexed by the factors of sizeCG,
+ -- discLogTable(factor) is a table with keys
+ -- primitiveElement() ** (i * (sizeCG quo factor)) and entries i for
+ -- i in 0..n-1, n computed in initialize() in order to use
+ -- the minimal size limit 'limit' optimal.
+
+-- functions ===========================================================
+
+ initializeLog: () -> Void
+ initializeElt: () -> Void
+ initializeMult: () -> Void
+
+
+ coerce(v:GF):$ == new(extdeg,v /$GF traceAlpha)$Rep
+ represents(v) == v::$
+
+ degree(a) ==
+ d:PI:=1
+ b:= qPot(a::Rep,1)$INBFF
+ while (b^=a) repeat
+ b:= qPot(b::Rep,1)$INBFF
+ d:=d+1
+ d
+
+ linearAssociatedExp(x,f) ==
+ xm:SUP(GF):=monomial(1$GF,extdeg)$(SUP GF) - 1$(SUP GF)
+ r:= (f * pol(x::Rep)$INBFF) rem xm
+ vectorise(r,extdeg)$(SUP GF)
+ linearAssociatedLog(x) == pol(x::Rep)$INBFF
+ linearAssociatedOrder(x) ==
+ xm:SUP(GF):=monomial(1$GF,extdeg)$(SUP GF) - 1$(SUP GF)
+ xm quo gcd(xm,pol(x::Rep)$INBFF)
+ linearAssociatedLog(b,x) ==
+ zero? x => 0
+ xm:SUP(GF):=monomial(1$GF,extdeg)$(SUP GF) - 1$(SUP GF)
+ e:= extendedEuclidean(pol(b::Rep)$INBFF,xm,pol(x::Rep)$INBFF)$(SUP GF)
+ e = "failed" => "failed"
+ e1:= e :: Record(coef1:(SUP GF),coef2:(SUP GF))
+ e1.coef1
+
+ getMultiplicationTable() ==
+ if initmult? then initializeMult()
+ multTable
+ getMultiplicationMatrix() ==
+ if initmult? then initializeMult()
+ createMultiplicationMatrix(multTable)$FFF
+ sizeMultiplication() ==
+ if initmult? then initializeMult()
+ sizeMultiplication(multTable)$FFF
+
+ trace(a:$) == retract trace(a,1)
+ norm(a:$) == retract norm(a,1)
+ generator() == normalElement(extdeg)$INBFF
+ basis(n:PI) ==
+ (extdeg rem n) ^= 0 => error "argument must divide extension degree"
+ [Frobenius(trace(normalElement,n),i) for i in 0..(n-1)]::(Vector $)
+
+ a:GF * x:$ == a *$Rep x
+
+ x:$/a:GF == x/coerce(a)
+-- x:$ / a:GF ==
+-- a = 0$GF => error "division by zero"
+-- x * inv(coerce(a))
+
+
+ coordinates(x:$) == x::Rep
+
+ Frobenius(e) == qPot(e::Rep,1)$INBFF
+ Frobenius(e,n) == qPot(e::Rep,n)$INBFF
+
+ retractIfCan(x) ==
+ inGroundField?(x) =>
+ x.1 *$GF traceAlpha
+ "failed"
+
+ retract(x) ==
+ inGroundField?(x) =>
+ x.1 *$GF traceAlpha
+ error("element not in ground field")
+
+-- to get a "normal basis like" output form
+ coerce(x:$):OUT ==
+ l:List OUT:=nil()$(List OUT)
+ n : PI := extdeg
+-- one? n => (x.1) :: OUT
+ (n = 1) => (x.1) :: OUT
+ for i in 1..n for b in basisOutput repeat
+ if not zero? x.i then
+ mon : OUT :=
+-- one? x.i => b
+ (x.i = 1) => b
+ ((x.i)::OUT) *$OUT b
+ l:=cons(mon,l)$(List OUT)
+ null(l)$(List OUT) => (0::OUT)
+ r:=reduce("+",l)$(List OUT)
+ r
+
+ initializeElt() ==
+ facOfGroupSize := factors factor(size()$GF**extdeg-1)$I
+ -- get a primitive element
+ primitiveElt:=lookup(createPrimitiveElement())
+ initelt?:=false
+ void()$Void
+
+ initializeMult() ==
+ multTable:=createMultiplicationTable(defpol)$FFF
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ -- reset initialize flag
+ initmult?:=false
+ void()$Void
+
+ initializeLog() ==
+ if initelt? then initializeElt()
+ -- set up tables for discrete logarithm
+ limit:Integer:=30
+ -- the minimum size for the discrete logarithm table
+ for f in facOfGroupSize repeat
+ fac:=f.factor
+ base:$:=index(primitiveElt)**((size()$GF**extdeg -$I 1$I) quo$I fac)
+ l:Integer:=length(fac)$Integer
+ n:Integer:=0
+ if odd?(l)$I then n:=shift(fac,-$I (l quo$I 2))$I
+ else n:=shift(1,l quo$I 2)$I
+ if n <$I limit then
+ d:=(fac -$I 1$I) quo$I limit +$I 1$I
+ n:=(fac -$I 1$I) quo$I d +$I 1$I
+ tbl:TBL:=table()$TBL
+ a:$:=1
+ for i in (0::NNI)..(n-1)::NNI repeat
+ insert_!([lookup(a),i::NNI]$R,tbl)$TBL
+ a:=a*base
+ insert_!([fac::PI,copy(tbl)$TBL]_
+ $Record(key:PI,entry:TBL),discLogTable)$Table(PI,TBL)
+ initlog?:=false
+ -- tell user about initialization
+ --print("discrete logarithm table initialized"::OUT)
+ void()$Void
+
+ tableForDiscreteLogarithm(fac) ==
+ if initlog? then initializeLog()
+ tbl:=search(fac::PI,discLogTable)$Table(PI,TBL)
+ tbl case "failed" =>
+ error "tableForDiscreteLogarithm: argument must be prime _
+divisor of the order of the multiplicative group"
+ tbl :: TBL
+
+ primitiveElement() ==
+ if initelt? then initializeElt()
+ index(primitiveElt)
+
+ factorsOfCyclicGroupSize() ==
+ if empty? facOfGroupSize then initializeElt()
+ facOfGroupSize
+
+ extensionDegree() == extdeg
+
+ sizeOfGroundField() == size()$GF pretend NNI
+
+ definingPolynomial() == defpol
+
+ trace(a,d) ==
+ v:=trace(a::Rep,d)$INBFF
+ erg:=v
+ for i in 2..(extdeg quo d) repeat
+ erg:=concat(erg,v)$Rep
+ erg
+
+ characteristic() == characteristic()$GF
+
+ random() == random(extdeg)$INBFF
+
+ x:$ * y:$ ==
+ if initmult? then initializeMult()
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ x::Rep *$INBFF y::Rep
+
+
+ 1 == new(extdeg,inv(traceAlpha)$GF)$Rep
+
+ 0 == zero(extdeg)$Rep
+
+ size() == size()$GF ** extdeg
+
+ index(n:PI) == index(extdeg,n)$INBFF
+
+ lookup(x:$) == lookup(x::Rep)$INBFF
+
+
+ basis() ==
+ a:=basis(extdeg)$INBFF
+ vector([e::$ for e in entries a])
+
+
+ x:$ ** e:I ==
+ if initmult? then initializeMult()
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ (x::Rep) **$INBFF e
+
+ normal?(x) == normal?(x::Rep)$INBFF
+
+ -(x:$) == -$Rep x
+ x:$ + y:$ == x +$Rep y
+ x:$ - y:$ == x -$Rep y
+ x:$ = y:$ == x =$Rep y
+ n:I * x:$ == x *$Rep (n::GF)
+
+
+
+
+ representationType() == "normal"
+
+ minimalPolynomial(a) ==
+ if initmult? then initializeMult()
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ minimalPolynomial(a::Rep)$INBFF
+
+-- is x an element of the ground field GF ?
+ inGroundField?(x) ==
+ erg:=true
+ for i in 2..extdeg repeat
+ not(x.i =$GF x.1) => erg:=false
+ erg
+
+ x:$ / y:$ ==
+ if initmult? then initializeMult()
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ x::Rep /$INBFF y::Rep
+
+ inv(a) ==
+ if initmult? then initializeMult()
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ inv(a::Rep)$INBFF
+
+ norm(a,d) ==
+ if initmult? then initializeMult()
+ setFieldInfo(multTable,traceAlpha)$INBFF
+ norm(a::Rep,d)$INBFF
+
+ normalElement() == normalElement(extdeg)$INBFF
+
+@
+\section{domain FFNBX FiniteFieldNormalBasisExtension}
+<<domain FFNBX FiniteFieldNormalBasisExtension>>=
+)abbrev domain FFNBX FiniteFieldNormalBasisExtension
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FiniteFieldNormalBasisExtensionByPolynomial,
+++ FiniteFieldPolynomialPackage
+++ Also See: FiniteFieldExtension, FiniteFieldCyclicGroupExtension
+++ AMS Classifications:
+++ Keywords: finite field, normal basis
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldNormalBasisExtensionByPolynomial(GF,n) implements a
+++ finite extension field of degree n over the ground field {\em GF}.
+++ The elements are represented by coordinate vectors with respect
+++ to a normal basis,
+++ i.e. a basis consisting of the conjugates (q-powers) of an element, in
+++ this case called normal element. This is chosen as a root of the extension
+++ polynomial, created by {\em createNormalPoly} from
+++ \spadtype{FiniteFieldPolynomialPackage}
+FiniteFieldNormalBasisExtension(GF,extdeg):_
+ Exports == Implementation where
+ GF : FiniteFieldCategory -- the ground field
+ extdeg: PositiveInteger -- the extension degree
+ NNI ==> NonNegativeInteger
+ FFF ==> FiniteFieldFunctions(GF)
+ TERM ==> Record(value:GF,index:SingleInteger)
+ Exports ==> FiniteAlgebraicExtensionField(GF) with
+ getMultiplicationTable: () -> Vector List TERM
+ ++ getMultiplicationTable() returns the multiplication
+ ++ table for the normal basis of the field.
+ ++ This table is used to perform multiplications between field elements.
+ getMultiplicationMatrix: () -> Matrix GF
+ ++ getMultiplicationMatrix() returns the multiplication table in
+ ++ form of a matrix.
+ sizeMultiplication:() -> NNI
+ ++ sizeMultiplication() returns the number of entries in the
+ ++ multiplication table of the field. Note: the time of multiplication
+ ++ of field elements depends on this size.
+
+ Implementation ==> FiniteFieldNormalBasisExtensionByPolynomial(GF,_
+ createLowComplexityNormalBasis(extdeg)$FFF)
+
+@
+\section{domain FFNB FiniteFieldNormalBasis}
+<<domain FFNB FiniteFieldNormalBasis>>=
+)abbrev domain FFNB FiniteFieldNormalBasis
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FiniteFieldNormalBasisExtensionByPolynomial,
+++ FiniteFieldPolynomialPackage
+++ Also See: FiniteField, FiniteFieldCyclicGroup
+++ AMS Classifications:
+++ Keywords: finite field, normal basis
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldNormalBasis(p,n) implements a
+++ finite extension field of degree n over the prime field with p elements.
+++ The elements are represented by coordinate vectors with respect to
+++ a normal basis,
+++ i.e. a basis consisting of the conjugates (q-powers) of an element, in
+++ this case called normal element.
+++ This is chosen as a root of the extension polynomial
+++ created by \spadfunFrom{createNormalPoly}{FiniteFieldPolynomialPackage}.
+FiniteFieldNormalBasis(p,extdeg):_
+ Exports == Implementation where
+ p : PositiveInteger
+ extdeg: PositiveInteger -- the extension degree
+ NNI ==> NonNegativeInteger
+ FFF ==> FiniteFieldFunctions(PrimeField(p))
+ TERM ==> Record(value:PrimeField(p),index:SingleInteger)
+ Exports ==> FiniteAlgebraicExtensionField(PrimeField(p)) with
+ getMultiplicationTable: () -> Vector List TERM
+ ++ getMultiplicationTable() returns the multiplication
+ ++ table for the normal basis of the field.
+ ++ This table is used to perform multiplications between field elements.
+ getMultiplicationMatrix: () -> Matrix PrimeField(p)
+ ++ getMultiplicationMatrix() returns the multiplication table in
+ ++ form of a matrix.
+ sizeMultiplication:() -> NNI
+ ++ sizeMultiplication() returns the number of entries in the
+ ++ multiplication table of the field. Note: The time of multiplication
+ ++ of field elements depends on this size.
+
+ Implementation ==> FiniteFieldNormalBasisExtensionByPolynomial(PrimeField(p),_
+ createLowComplexityNormalBasis(extdeg)$FFF)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INBFF InnerNormalBasisFieldFunctions>>
+<<domain FFNBP FiniteFieldNormalBasisExtensionByPolynomial>>
+<<domain FFNBX FiniteFieldNormalBasisExtension>>
+<<domain FFNB FiniteFieldNormalBasis>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffp.spad.pamphlet b/src/algebra/ffp.spad.pamphlet
new file mode 100644
index 00000000..2d97d795
--- /dev/null
+++ b/src/algebra/ffp.spad.pamphlet
@@ -0,0 +1,403 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffp.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn, Robert Sutor, Oswald Gschnitzer}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- 28.01.93: AS and JG: setting of initlog? and initelt? flags in
+-- functions initializeLog and initializeElt put at the
+-- end to avoid errors with interruption. createNormalElement()
+-- included in function initializeElt. Function createNormalElement() set
+-- into comments. factorsOfCyclicGroupSize() changed.
+-- 12.05.92: JG: long lines
+-- 18.02.92: AS: degree: $ -> PI added, faster then category version
+-- 18.06.91: AS: createNormalElement added:
+-- the version in ffcat.spad needs too long
+-- for finding a normal element, because of the "correlation" between
+-- the "additive" structure of the index function and the additive
+-- structure of the field. Our experiments show that this version is
+-- much faster.
+-- 05.04.91 JG: comments, IFF
+-- 04.04.91 JG: error message in function tablesOfDiscreteLogarithm changed
+-- 04.04.91 JG: comment of FFP was changed
+
+\end{verbatim}
+\section{domain FFP FiniteFieldExtensionByPolynomial}
+<<domain FFP FiniteFieldExtensionByPolynomial>>=
+)abbrev domain FFP FiniteFieldExtensionByPolynomial
+++ Authors: R.Sutor, J. Grabmeier, O. Gschnitzer, A. Scheerhorn
+++ Date Created:
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See: FiniteFieldCyclicGroupExtensionByPolynomial,
+++ FiniteFieldNormalBasisExtensionByPolynomial
+++ AMS Classifications:
+++ Keywords: field, extension field, algebraic extension,
+++ finite extension, finite field, Galois field
+++ Reference:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics an
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldExtensionByPolynomial(GF, defpol) implements the extension
+++ of the finite field {\em GF} generated by the extension polynomial
+++ {\em defpol} which MUST be irreducible.
+++ Note: the user has the responsibility to ensure that
+++ {\em defpol} is irreducible.
+
+FiniteFieldExtensionByPolynomial(GF:FiniteFieldCategory,_
+ defpol:SparseUnivariatePolynomial GF): Exports == Implementation where
+-- GF : FiniteFieldCategory
+-- defpol : SparseUnivariatePolynomial GF
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SUP ==> SparseUnivariatePolynomial
+ I ==> Integer
+ R ==> Record(key:PI,entry:NNI)
+ TBL ==> Table(PI,NNI)
+ SAE ==> SimpleAlgebraicExtension(GF,SUP GF,defpol)
+ OUT ==> OutputForm
+
+ Exports ==> FiniteAlgebraicExtensionField(GF)
+
+ Implementation ==> add
+
+-- global variables ====================================================
+
+ Rep:=SAE
+
+ extdeg:PI := degree(defpol)$(SUP GF) pretend PI
+ -- the extension degree
+
+ alpha := new()$Symbol :: OutputForm
+ -- a new symbol for the output form of field elements
+
+ sizeCG:Integer := size()$GF**extdeg - 1
+ -- the order of the multiplicative group
+
+ facOfGroupSize := nil()$(List Record(factor:Integer,exponent:Integer))
+ -- the factorization of sizeCG
+
+ normalElt:PI:=1
+ -- for the lookup of the normal Element computed by
+ -- createNormalElement
+
+ primitiveElt:PI:=1
+ -- for the lookup of the primitive Element computed by
+ -- createPrimitiveElement()
+
+ initlog?:Boolean:=true
+ -- gets false after initialization of the discrete logarithm table
+
+ initelt?:Boolean:=true
+ -- gets false after initialization of the primitive and the
+ -- normal element
+
+
+ discLogTable:Table(PI,TBL):=table()$Table(PI,TBL)
+ -- tables indexed by the factors of sizeCG,
+ -- discLogTable(factor) is a table with keys
+ -- primitiveElement() ** (i * (sizeCG quo factor)) and entries i for
+ -- i in 0..n-1, n computed in initialize() in order to use
+ -- the minimal size limit 'limit' optimal.
+
+-- functions ===========================================================
+
+-- createNormalElement() ==
+-- a:=primitiveElement()
+-- nElt:=generator()
+-- for i in 1.. repeat
+-- normal? nElt => return nElt
+-- nElt:=nElt*a
+-- nElt
+
+ generator() == reduce(monomial(1,1)$SUP(GF))$Rep
+ norm x == resultant(defpol, lift x)
+
+ initializeElt: () -> Void
+ initializeLog: () -> Void
+ basis(n:PI) ==
+ (extdeg rem n) ^= 0 => error "argument must divide extension degree"
+ a:$:=norm(primitiveElement(),n)
+ vector [a**i for i in 0..n-1]
+
+ degree(x) ==
+ y:$:=1
+ m:=zero(extdeg,extdeg+1)$(Matrix GF)
+ for i in 1..extdeg+1 repeat
+ setColumn_!(m,i,coordinates(y))$(Matrix GF)
+ y:=y*x
+ rank(m)::PI
+
+ minimalPolynomial(x:$) ==
+ y:$:=1
+ m:=zero(extdeg,extdeg+1)$(Matrix GF)
+ for i in 1..extdeg+1 repeat
+ setColumn_!(m,i,coordinates(y))$(Matrix GF)
+ y:=y*x
+ v:=first nullSpace(m)$(Matrix GF)
+ +/[monomial(v.(i+1),i)$(SUP GF) for i in 0..extdeg]
+
+
+ normal?(x) ==
+ l:List List GF:=[entries coordinates x]
+ a:=x
+ for i in 2..extdeg repeat
+ a:=Frobenius(a)
+ l:=concat(l,entries coordinates a)$(List List GF)
+ ((rank matrix(l)$(Matrix GF)) = extdeg::NNI) => true
+ false
+
+
+ a:GF * x:$ == a *$Rep x
+ n:I * x:$ == n *$Rep x
+ -x == -$Rep x
+ random() == random()$Rep
+ coordinates(x:$) == coordinates(x)$Rep
+ represents(v) == represents(v)$Rep
+ coerce(x:GF):$ == coerce(x)$Rep
+ definingPolynomial() == defpol
+ retract(x) == retract(x)$Rep
+ retractIfCan(x) == retractIfCan(x)$Rep
+ index(x) == index(x)$Rep
+ lookup(x) == lookup(x)$Rep
+ x:$/y:$ == x /$Rep y
+ x:$/a:GF == x/coerce(a)
+-- x:$ / a:GF ==
+-- a = 0$GF => error "division by zero"
+-- x * inv(coerce(a))
+ x:$ * y:$ == x *$Rep y
+ x:$ + y:$ == x +$Rep y
+ x:$ - y:$ == x -$Rep y
+ x:$ = y:$ == x =$Rep y
+ basis() == basis()$Rep
+ 0 == 0$Rep
+ 1 == 1$Rep
+
+ factorsOfCyclicGroupSize() ==
+ if empty? facOfGroupSize then initializeElt()
+ facOfGroupSize
+
+ representationType() == "polynomial"
+
+ tableForDiscreteLogarithm(fac) ==
+ if initlog? then initializeLog()
+ tbl:=search(fac::PI,discLogTable)$Table(PI,TBL)
+ tbl case "failed" =>
+ error "tableForDiscreteLogarithm: argument must be prime divisor_
+ of the order of the multiplicative group"
+ tbl pretend TBL
+
+ primitiveElement() ==
+ if initelt? then initializeElt()
+ index(primitiveElt)
+
+ normalElement() ==
+ if initelt? then initializeElt()
+ index(normalElt)
+
+ initializeElt() ==
+ facOfGroupSize:=factors(factor(sizeCG)$Integer)
+ -- get a primitive element
+ pE:=createPrimitiveElement()
+ primitiveElt:=lookup(pE)
+ -- create a normal element
+ nElt:=generator()
+ while not normal? nElt repeat
+ nElt:=nElt*pE
+ normalElt:=lookup(nElt)
+ -- set elements initialization flag
+ initelt? := false
+ void()$Void
+
+ initializeLog() ==
+ if initelt? then initializeElt()
+-- set up tables for discrete logarithm
+ limit:Integer:=30
+ -- the minimum size for the discrete logarithm table
+ for f in facOfGroupSize repeat
+ fac:=f.factor
+ base:$:=primitiveElement() ** (sizeCG quo fac)
+ l:Integer:=length(fac)$Integer
+ n:Integer:=0
+ if odd?(l)$Integer then n:=shift(fac,-(l quo 2))
+ else n:=shift(1,(l quo 2))
+ if n < limit then
+ d:=(fac-1) quo limit + 1
+ n:=(fac-1) quo d + 1
+ tbl:TBL:=table()$TBL
+ a:$:=1
+ for i in (0::NNI)..(n-1)::NNI repeat
+ insert_!([lookup(a),i::NNI]$R,tbl)$TBL
+ a:=a*base
+ insert_!([fac::PI,copy(tbl)$TBL]_
+ $Record(key:PI,entry:TBL),discLogTable)$Table(PI,TBL)
+ -- set logarithm initialization flag
+ initlog? := false
+ -- tell user about initialization
+ --print("discrete logarithm tables initialized"::OUT)
+ void()$Void
+
+ coerce(e:$):OutputForm == outputForm(lift(e),alpha)
+
+ extensionDegree() == extdeg
+
+ size() == (sizeCG + 1) pretend NNI
+
+-- sizeOfGroundField() == size()$GF
+
+ inGroundField?(x) ==
+ retractIfCan(x) = "failed" => false
+ true
+
+ characteristic() == characteristic()$GF
+
+@
+\section{domain FFX FiniteFieldExtension}
+<<domain FFX FiniteFieldExtension>>=
+)abbrev domain FFX FiniteFieldExtension
+++ Authors: R.Sutor, J. Grabmeier, A. Scheerhorn
+++ Date Created:
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors: FiniteFieldExtensionByPolynomial,
+++ FiniteFieldPolynomialPackage
+++ Also See: FiniteFieldCyclicGroupExtension,
+++ FiniteFieldNormalBasisExtension
+++ AMS Classifications:
+++ Keywords: field, extension field, algebraic extension,
+++ finite extension, finite field, Galois field
+++ Reference:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics an
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteFieldExtensionByPolynomial(GF, n) implements an extension
+++ of the finite field {\em GF} of degree n generated by the extension
+++ polynomial constructed by
+++ \spadfunFrom{createIrreduciblePoly}{FiniteFieldPolynomialPackage} from
+++ \spadtype{FiniteFieldPolynomialPackage}.
+FiniteFieldExtension(GF, n): Exports == Implementation where
+ GF: FiniteFieldCategory
+ n : PositiveInteger
+ Exports ==> FiniteAlgebraicExtensionField(GF)
+ -- MonogenicAlgebra(GF, SUP) with -- have to check this
+ Implementation ==> FiniteFieldExtensionByPolynomial(GF,
+ createIrreduciblePoly(n)$FiniteFieldPolynomialPackage(GF))
+ -- old code for generating irreducible polynomials:
+ -- now "better" order (sparse polys first)
+ -- generateIrredPoly(n)$IrredPolyOverFiniteField(GF))
+
+@
+\section{domain IFF InnerFiniteField}
+<<domain IFF InnerFiniteField>>=
+)abbrev domain IFF InnerFiniteField
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 29 May 1990
+++ Basic Operations:
+++ Related Constructors: FiniteFieldExtensionByPolynomial,
+++ FiniteFieldPolynomialPackage
+++ Also See: FiniteFieldCyclicGroup, FiniteFieldNormalBasis
+++ AMS Classifications:
+++ Keywords: field, extension field, algebraic extension,
+++ finite extension, finite field, Galois field
+++ Reference:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics an
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ InnerFiniteField(p,n) implements finite fields with \spad{p**n} elements
+++ where p is assumed prime but does not check.
+++ For a version which checks that p is prime, see \spadtype{FiniteField}.
+InnerFiniteField(p:PositiveInteger, n:PositiveInteger) ==
+ FiniteFieldExtension(InnerPrimeField p, n)
+
+@
+\section{domain FF FiniteField}
+<<domain FF FiniteField>>=
+)abbrev domain FF FiniteField
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 29 May 1990
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: field, extension field, algebraic extension,
+++ finite extension, finite field, Galois field
+++ Reference:
+++ R.Lidl, H.Niederreiter: Finite Field, Encyclopedia of Mathematics an
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in AXIOM.
+++ AXIOM Technical Report Series, ATR/5 NP2522.
+++ Description:
+++ FiniteField(p,n) implements finite fields with p**n elements.
+++ This packages checks that p is prime.
+++ For a non-checking version, see \spadtype{InnerFiniteField}.
+FiniteField(p:PositiveInteger, n:PositiveInteger): _
+ FiniteAlgebraicExtensionField(PrimeField p) ==_
+ FiniteFieldExtensionByPolynomial(PrimeField p,_
+ createIrreduciblePoly(n)$FiniteFieldPolynomialPackage(PrimeField p))
+ -- old code for generating irreducible polynomials:
+ -- now "better" order (sparse polys first)
+ -- generateIrredPoly(n)$IrredPolyOverFiniteField(GF))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FFP FiniteFieldExtensionByPolynomial>>
+<<domain FFX FiniteFieldExtension>>
+<<domain IFF InnerFiniteField>>
+<<domain FF FiniteField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffpoly.spad.pamphlet b/src/algebra/ffpoly.spad.pamphlet
new file mode 100644
index 00000000..eba95386
--- /dev/null
+++ b/src/algebra/ffpoly.spad.pamphlet
@@ -0,0 +1,1036 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffpoly.spad}
+\author{Alexandre Bouyer, Johannes Grabmeier, Alfred Scheerhorn, Robert Sutor, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FFPOLY FiniteFieldPolynomialPackage}
+<<package FFPOLY FiniteFieldPolynomialPackage>>=
+)abbrev package FFPOLY FiniteFieldPolynomialPackage
+++ Author: A. Bouyer, J. Grabmeier, A. Scheerhorn, R. Sutor, B. Trager
+++ Date Created: January 1991
+++ Date Last Updated: 1 June 1994
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: finite field, polynomial, irreducible polynomial, normal
+++ polynomial, primitive polynomial, random polynomials
+++ References:
+++ [LS] Lenstra, H. W. & Schoof, R. J., "Primitivive Normal Bases
+++ for Finite Fields", Math. Comp. 48, 1987, pp. 217-231
+++ [LN] Lidl, R. & Niederreiter, H., "Finite Fields",
+++ Encycl. of Math. 20, Addison-Wesley, 1983
+++ J. Grabmeier, A. Scheerhorn: Finite Fields in Axiom.
+++ Axiom Technical Report Series, to appear.
+++ Description:
+++ This package provides a number of functions for generating, counting
+++ and testing irreducible, normal, primitive, random polynomials
+++ over finite fields.
+
+FiniteFieldPolynomialPackage GF : Exports == Implementation where
+
+ GF : FiniteFieldCategory
+
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ Rec ==> Record(expnt:NNI, coeff:GF)
+ Repr ==> L Rec
+ SUP ==> SparseUnivariatePolynomial GF
+
+ Exports ==> with
+ -- qEulerPhiCyclotomic : PI -> PI
+-- ++ qEulerPhiCyclotomic(n)$FFPOLY(GF) yields the q-Euler's function
+-- ++ of the n-th cyclotomic polynomial over the field {\em GF} of
+-- ++ order q (cf. [LN] p.122);
+-- ++ error if n is a multiple of the field characteristic.
+ primitive? : SUP -> Boolean
+ ++ primitive?(f) tests whether the polynomial f over a finite
+ ++ field is primitive, i.e. all its roots are primitive.
+ normal? : SUP -> Boolean
+ ++ normal?(f) tests whether the polynomial f over a finite field is
+ ++ normal, i.e. its roots are linearly independent over the field.
+ numberOfIrreduciblePoly : PI -> PI
+ ++ numberOfIrreduciblePoly(n)$FFPOLY(GF) yields the number of
+ ++ monic irreducible univariate polynomials of degree n
+ ++ over the finite field {\em GF}.
+ numberOfPrimitivePoly : PI -> PI
+ ++ numberOfPrimitivePoly(n)$FFPOLY(GF) yields the number of
+ ++ primitive polynomials of degree n over the finite field {\em GF}.
+ numberOfNormalPoly : PI -> PI
+ ++ numberOfNormalPoly(n)$FFPOLY(GF) yields the number of
+ ++ normal polynomials of degree n over the finite field {\em GF}.
+ createIrreduciblePoly : PI -> SUP
+ ++ createIrreduciblePoly(n)$FFPOLY(GF) generates a monic irreducible
+ ++ univariate polynomial of degree n over the finite field {\em GF}.
+ createPrimitivePoly : PI -> SUP
+ ++ createPrimitivePoly(n)$FFPOLY(GF) generates a primitive polynomial
+ ++ of degree n over the finite field {\em GF}.
+ createNormalPoly : PI -> SUP
+ ++ createNormalPoly(n)$FFPOLY(GF) generates a normal polynomial
+ ++ of degree n over the finite field {\em GF}.
+ createNormalPrimitivePoly : PI -> SUP
+ ++ createNormalPrimitivePoly(n)$FFPOLY(GF) generates a normal and
+ ++ primitive polynomial of degree n over the field {\em GF}.
+ ++ Note: this function is equivalent to createPrimitiveNormalPoly(n)
+ createPrimitiveNormalPoly : PI -> SUP
+ ++ createPrimitiveNormalPoly(n)$FFPOLY(GF) generates a normal and
+ ++ primitive polynomial of degree n over the field {\em GF}.
+ ++ polynomial of degree n over the field {\em GF}.
+ nextIrreduciblePoly : SUP -> Union(SUP, "failed")
+ ++ nextIrreduciblePoly(f) yields the next monic irreducible polynomial
+ ++ over a finite field {\em GF} of the same degree as f in the following
+ ++ order, or "failed" if there are no greater ones.
+ ++ Error: if f has degree 0.
+ ++ Note: the input polynomial f is made monic.
+ ++ Also, \spad{f < g} if
+ ++ the number of monomials of f is less
+ ++ than this number for g.
+ ++ If f and g have the same number of monomials,
+ ++ the lists of exponents are compared lexicographically.
+ ++ If these lists are also equal, the lists of coefficients
+ ++ are compared according to the lexicographic ordering induced by
+ ++ the ordering of the elements of {\em GF} given by {\em lookup}.
+ nextPrimitivePoly : SUP -> Union(SUP, "failed")
+ ++ nextPrimitivePoly(f) yields the next primitive polynomial over
+ ++ a finite field {\em GF} of the same degree as f in the following
+ ++ order, or "failed" if there are no greater ones.
+ ++ Error: if f has degree 0.
+ ++ Note: the input polynomial f is made monic.
+ ++ Also, \spad{f < g} if the {\em lookup} of the constant term
+ ++ of f is less than
+ ++ this number for g.
+ ++ If these values are equal, then \spad{f < g} if
+ ++ if the number of monomials of f is less than that for g or if
+ ++ the lists of exponents of f are lexicographically less than the
+ ++ corresponding list for g.
+ ++ If these lists are also equal, the lists of coefficients are
+ ++ compared according to the lexicographic ordering induced by
+ ++ the ordering of the elements of {\em GF} given by {\em lookup}.
+ nextNormalPoly : SUP -> Union(SUP, "failed")
+ ++ nextNormalPoly(f) yields the next normal polynomial over
+ ++ a finite field {\em GF} of the same degree as f in the following
+ ++ order, or "failed" if there are no greater ones.
+ ++ Error: if f has degree 0.
+ ++ Note: the input polynomial f is made monic.
+ ++ Also, \spad{f < g} if the {\em lookup} of the coefficient
+ ++ of the term of degree
+ ++ {\em n-1} of f is less than that for g.
+ ++ In case these numbers are equal, \spad{f < g} if
+ ++ if the number of monomials of f is less that for g or if
+ ++ the list of exponents of f are lexicographically less than the
+ ++ corresponding list for g.
+ ++ If these lists are also equal, the lists of coefficients are
+ ++ compared according to the lexicographic ordering induced by
+ ++ the ordering of the elements of {\em GF} given by {\em lookup}.
+ nextNormalPrimitivePoly : SUP -> Union(SUP, "failed")
+ ++ nextNormalPrimitivePoly(f) yields the next normal primitive polynomial
+ ++ over a finite field {\em GF} of the same degree as f in the following
+ ++ order, or "failed" if there are no greater ones.
+ ++ Error: if f has degree 0.
+ ++ Note: the input polynomial f is made monic.
+ ++ Also, \spad{f < g} if the {\em lookup} of the constant
+ ++ term of f is less than
+ ++ this number for g or if
+ ++ {\em lookup} of the coefficient of the term of degree {\em n-1}
+ ++ of f is less than this number for g.
+ ++ Otherwise, \spad{f < g}
+ ++ if the number of monomials of f is less than
+ ++ that for g or if the lists of exponents for f are
+ ++ lexicographically less than those for g.
+ ++ If these lists are also equal, the lists of coefficients are
+ ++ compared according to the lexicographic ordering induced by
+ ++ the ordering of the elements of {\em GF} given by {\em lookup}.
+ ++ This operation is equivalent to nextPrimitiveNormalPoly(f).
+ nextPrimitiveNormalPoly : SUP -> Union(SUP, "failed")
+ ++ nextPrimitiveNormalPoly(f) yields the next primitive normal polynomial
+ ++ over a finite field {\em GF} of the same degree as f in the following
+ ++ order, or "failed" if there are no greater ones.
+ ++ Error: if f has degree 0.
+ ++ Note: the input polynomial f is made monic.
+ ++ Also, \spad{f < g} if the {\em lookup} of the
+ ++ constant term of f is less than
+ ++ this number for g or, in case these numbers are equal, if the
+ ++ {\em lookup} of the coefficient of the term of degree {\em n-1}
+ ++ of f is less than this number for g.
+ ++ If these numbers are equals, \spad{f < g}
+ ++ if the number of monomials of f is less than
+ ++ that for g, or if the lists of exponents for f are lexicographically
+ ++ less than those for g.
+ ++ If these lists are also equal, the lists of coefficients are
+ ++ coefficients according to the lexicographic ordering induced by
+ ++ the ordering of the elements of {\em GF} given by {\em lookup}.
+ ++ This operation is equivalent to nextNormalPrimitivePoly(f).
+-- random : () -> SUP
+-- ++ random()$FFPOLY(GF) generates a random monic polynomial
+-- ++ of random degree over the field {\em GF}
+ random : PI -> SUP
+ ++ random(n)$FFPOLY(GF) generates a random monic polynomial
+ ++ of degree n over the finite field {\em GF}.
+ random : (PI, PI) -> SUP
+ ++ random(m,n)$FFPOLY(GF) generates a random monic polynomial
+ ++ of degree d over the finite field {\em GF}, d between m and n.
+ leastAffineMultiple: SUP -> SUP
+ ++ leastAffineMultiple(f) computes the least affine polynomial which
+ ++ is divisible by the polynomial f over the finite field {\em GF},
+ ++ i.e. a polynomial whose exponents are 0 or a power of q, the
+ ++ size of {\em GF}.
+ reducedQPowers: SUP -> PrimitiveArray SUP
+ ++ reducedQPowers(f)
+ ++ generates \spad{[x,x**q,x**(q**2),...,x**(q**(n-1))]}
+ ++ reduced modulo f where \spad{q = size()$GF} and \spad{n = degree f}.
+ --
+ -- we intend to implement also the functions
+ -- cyclotomicPoly: PI -> SUP, order: SUP -> PI,
+ -- and maybe a new version of irreducible?
+
+
+ Implementation ==> add
+
+ import IntegerNumberTheoryFunctions
+ import DistinctDegreeFactorize(GF, SUP)
+
+
+ MM := ModMonic(GF, SUP)
+
+ sizeGF : PI := size()$GF :: PI
+
+ revListToSUP(l:Repr):SUP ==
+ newl:Repr := empty()
+ -- cannot use map since copy for Record is an XLAM
+ for t in l repeat newl := cons(copy t, newl)
+ newl pretend SUP
+
+ listToSUP(l:Repr):SUP ==
+ newl:Repr := [copy t for t in l]
+ newl pretend SUP
+
+ nextSubset : (L NNI, NNI) -> Union(L NNI, "failed")
+ -- for a list s of length m with 1 <= s.1 < ... < s.m <= bound,
+ -- nextSubset(s, bound) yields the immediate successor of s
+ -- (resp. "failed" if s = [1,...,bound])
+ -- where s < t if and only if:
+ -- (i) #s < #t; or
+ -- (ii) #s = #t and s < t in the lexicographical order;
+ -- (we have chosen to fix the signature with NNI instead of PI
+ -- to avoid coercions in the main functions)
+
+ reducedQPowers(f) ==
+ m:PI:=degree(f)$SUP pretend PI
+ m1:I:=m-1
+ setPoly(f)$MM
+ e:=reduce(monomial(1,1)$SUP)$MM ** sizeGF
+ w:=1$MM
+ qpow:PrimitiveArray SUP:=new(m,0)
+ qpow.0:=1$SUP
+ for i in 1..m1 repeat qpow.i:=lift(w:=w*e)$MM
+ qexp:PrimitiveArray SUP:=new(m,0)
+ m = 1 =>
+ qexp.(0$I):= (-coefficient(f,0$NNI)$SUP)::SUP
+ qexp
+ qexp.0$I:=monomial(1,1)$SUP
+ h:=qpow.1
+ qexp.1:=h
+ for i in 2..m1 repeat
+ g:=0$SUP
+ while h ^= 0 repeat
+ g:=g + leadingCoefficient(h) * qpow.degree(h)
+ h:=reductum(h)
+ qexp.i:=(h:=g)
+ qexp
+
+ leastAffineMultiple(f) ==
+ -- [LS] p.112
+ qexp:=reducedQPowers(f)
+ n:=degree(f)$SUP
+ b:Matrix GF:= transpose matrix [entries vectorise
+ (qexp.i,n) for i in 0..n-1]
+ col1:Matrix GF:= new(n,1,0)
+ col1(1,1) := 1
+ ns : List Vector GF := nullSpace (horizConcat(col1,b) )
+ ----------------------------------------------------------------
+ -- perhaps one should use that the first vector in ns is already
+ -- the right one
+ ----------------------------------------------------------------
+ dim:=n+2
+ coeffVector : Vector GF
+ until empty? ns repeat
+ newCoeffVector := ns.1
+ i : PI :=(n+1) pretend PI
+ while newCoeffVector(i) = 0 repeat
+ i := (i - 1) pretend PI
+ if i < dim then
+ dim := i
+ coeffVector := newCoeffVector
+ ns := rest ns
+ (coeffVector(1)::SUP) +(+/[monomial(coeffVector.k, _
+ sizeGF**((k-2)::NNI))$SUP for k in 2..dim])
+
+-- qEulerPhiCyclotomic n ==
+-- n = 1 => (sizeGF - 1) pretend PI
+-- p : PI := characteristic()$GF :: PI
+-- (n rem p) = 0 => error
+-- "cyclotomic polynomial not defined for this argument value"
+-- q : PI := sizeGF
+-- -- determine the multiplicative order of q modulo n
+-- e : PI := 1
+-- qe : PI := q
+-- while (qe rem n) ^= 1 repeat
+-- e := e + 1
+-- qe := qe * q
+-- ((qe - 1) ** ((eulerPhi(n) quo e) pretend PI) ) pretend PI
+
+ numberOfIrreduciblePoly n ==
+ -- we compute the number Nq(n) of monic irreducible polynomials
+ -- of degree n over the field GF of order q by the formula
+ -- Nq(n) = (1/n)* sum(moebiusMu(n/d)*q**d) where the sum extends
+ -- over all divisors d of n (cf. [LN] p.93, Th. 3.25)
+ n = 1 => sizeGF
+ -- the contribution of d = 1 :
+ lastd : PI := 1
+ qd : PI := sizeGF
+ sum : I := moebiusMu(n) * qd
+ -- the divisors d > 1 of n :
+ divisorsOfn : L PI := rest(divisors n) pretend L PI
+ for d in divisorsOfn repeat
+ qd := qd * (sizeGF) ** ((d - lastd) pretend PI)
+ sum := sum + moebiusMu(n quo d) * qd
+ lastd := d
+ (sum quo n) :: PI
+
+ numberOfPrimitivePoly n == (eulerPhi((sizeGF ** n) - 1) quo n) :: PI
+ -- [each root of a primitive polynomial of degree n over a field
+ -- with q elements is a generator of the multiplicative group
+ -- of a field of order q**n (definition), and the number of such
+ -- generators is precisely eulerPhi(q**n - 1)]
+
+ numberOfNormalPoly n ==
+ -- we compute the number Nq(n) of normal polynomials of degree n
+ -- in GF[X], with GF of order q, by the formula
+ -- Nq(n) = (1/n) * qPhi(X**n - 1) (cf. [LN] p.124) where,
+ -- for any polynomial f in GF[X] of positive degree n,
+ -- qPhi(f) = q**n * (1 - q**(-n1)) *...* (1 - q**(-nr)) =
+ -- q**n * ((q**(n1)-1) / q**(n1)) *...* ((q**(nr)-1) / q**(n_r)),
+ -- the ni being the degrees of the distinct irreducible factors
+ -- of f in its canonical factorization over GF
+ -- ([LN] p.122, Lemma 3.69).
+ -- hence, if n = m * p**r where p is the characteristic of GF
+ -- and gcd(m,p) = 1, we get
+ -- Nq(n) = (1/n)* q**(n-m) * qPhi(X**m - 1)
+ -- now X**m - 1 is the product of the (pairwise relatively prime)
+ -- cyclotomic polynomials Qd(X) for which d divides m
+ -- ([LN] p.64, Th. 2.45), and each Qd(X) factors into
+ -- eulerPhi(d)/e (distinct) monic irreducible polynomials in GF[X]
+ -- of the same degree e, where e is the least positive integer k
+ -- such that d divides q**k - 1 ([LN] p.65, Th. 2.47)
+ n = 1 => (sizeGF - 1) :: NNI :: PI
+ m : PI := n
+ p : PI := characteristic()$GF :: PI
+ q : PI := sizeGF
+ while (m rem p) = 0 repeat -- find m such that
+ m := (m quo p) :: PI -- n = m * p**r and gcd(m,p) = 1
+ m = 1 =>
+ -- know that n is a power of p
+ (((q ** ((n-1)::NNI) ) * (q - 1) ) quo n) :: PI
+ prod : I := q - 1
+ divisorsOfm : L PI := rest(divisors m) pretend L PI
+ for d in divisorsOfm repeat
+ -- determine the multiplicative order of q modulo d
+ e : PI := 1
+ qe : PI := q
+ while (qe rem d) ^= 1 repeat
+ e := e + 1
+ qe := qe * q
+ prod := prod * _
+ ((qe - 1) ** ((eulerPhi(d) quo e) pretend PI) ) pretend PI
+ (q**((n-m) pretend PI) * prod quo n) pretend PI
+
+ primitive? f ==
+ -- let GF be a field of order q; a monic polynomial f in GF[X]
+ -- of degree n is primitive over GF if and only if its constant
+ -- term is non-zero, f divides X**(q**n - 1) - 1 and,
+ -- for each prime divisor d of q**n - 1,
+ -- f does not divide X**((q**n - 1) / d) - 1
+ -- (cf. [LN] p.89, Th. 3.16, and p.87, following Th. 3.11)
+ n : NNI := degree f
+ n = 0 => false
+ leadingCoefficient f ^= 1 => false
+ coefficient(f, 0) = 0 => false
+ q : PI := sizeGF
+ qn1: PI := (q**n - 1) :: NNI :: PI
+ setPoly f
+ x := reduce(monomial(1,1)$SUP)$MM -- X rem f represented in MM
+ --
+ -- may be improved by tabulating the residues x**(i*q)
+ -- for i = 0,...,n-1 :
+ --
+ lift(x ** qn1)$MM ^= 1 => false -- X**(q**n - 1) rem f in GF[X]
+ lrec : L Record(factor:I, exponent:I) := factors(factor qn1)
+ lfact : L PI := [] -- collect the prime factors
+ for rec in lrec repeat -- of q**n - 1
+ lfact := cons((rec.factor) :: PI, lfact)
+ for d in lfact repeat
+ if (expt := (qn1 quo d)) >= n then
+ lift(x ** expt)$MM = 1 => return false
+ true
+
+ normal? f ==
+ -- let GF be a field with q elements; a monic irreducible
+ -- polynomial f in GF[X] of degree n is normal if its roots
+ -- x, x**q, ... , x**(q**(n-1)) are linearly independent over GF
+ n : NNI := degree f
+ n = 0 => false
+ leadingCoefficient f ^= 1 => false
+ coefficient(f, 0) = 0 => false
+ n = 1 => true
+ not irreducible? f => false
+ g:=reducedQPowers(f)
+ l:=[entries vectorise(g.i,n)$SUP for i in 0..(n-1)::NNI]
+ rank(matrix(l)$Matrix(GF)) = n => true
+ false
+
+ nextSubset(s, bound) ==
+ m : NNI := #(s)
+ m = 0 => [1]
+ -- find the first element s(i) of s such that s(i) + 1 < s(i+1) :
+ noGap : Boolean := true
+ i : NNI := 0
+ restOfs : L NNI
+ while noGap and not empty?(restOfs := rest s) repeat
+ -- after i steps (0 <= i <= m-1) we have s = [s(i), ... , s(m)]
+ -- and restOfs = [s(i+1), ... , s(m)]
+ secondOfs := first restOfs -- s(i+1)
+ firstOfsPlus1 := first s + 1 -- s(i) + 1
+ secondOfs = firstOfsPlus1 =>
+ s := restOfs
+ i := i + 1
+ setfirst_!(s, firstOfsPlus1) -- s := [s(i)+1, s(i+1),..., s(m)]
+ noGap := false
+ if noGap then -- here s = [s(m)]
+ firstOfs := first s
+ firstOfs < bound => setfirst_!(s, firstOfs + 1) -- s := [s(m)+1]
+ m < bound =>
+ setfirst_!(s, m + 1) -- s := [m+1]
+ i := m
+ return "failed" -- (here m = s(m) = bound)
+ for j in i..1 by -1 repeat -- reconstruct the destroyed
+ s := cons(j, s) -- initial part of s
+ s
+
+ nextIrreduciblePoly f ==
+ n : NNI := degree f
+ n = 0 => error "polynomial must have positive degree"
+ -- make f monic
+ if (lcf := leadingCoefficient f) ^= 1 then f := (inv lcf) * f
+ -- if f = fn*X**n + ... + f{i0}*X**{i0} with the fi non-zero
+ -- then fRepr := [[n,fn], ... , [i0,f{i0}]]
+ fRepr : Repr := f pretend Repr
+ fcopy : Repr := []
+ -- we can not simply write fcopy := copy fRepr because
+ -- the input(!) f would be modified by assigning
+ -- a new value to one of its records
+ for term in fRepr repeat
+ fcopy := cons(copy term, fcopy)
+ if term.expnt ^= 0 then
+ fcopy := cons([0,0]$Rec, fcopy)
+ tailpol : Repr := []
+ headpol : Repr := fcopy -- [[0,f0], ... , [n,fn]] where
+ -- fi is non-zero for i > 0
+ fcopy := reverse fcopy
+ weight : NNI := (#(fcopy) - 1) :: NNI -- #s(f) as explained above
+ taillookuplist : L NNI := []
+ -- the zeroes in the headlookuplist stand for the fi
+ -- whose lookup's were not yet computed :
+ headlookuplist : L NNI := new(weight, 0)
+ s : L NNI := [] -- we will compute s(f) only if necessary
+ n1 : NNI := (n - 1) :: NNI
+ repeat
+ -- (run through the possible weights)
+ while not empty? headlookuplist repeat
+ -- find next polynomial in the above order with fixed weight;
+ -- assume at this point we have
+ -- headpol = [[i1,f{i1}], [i2,f{i2}], ... , [n,1]]
+ -- and tailpol = [[k,fk], ... , [0,f0]] (with k < i1)
+ term := first headpol
+ j := first headlookuplist
+ if j = 0 then j := lookup(term.coeff)$GF
+ j := j + 1 -- lookup(f{i1})$GF + 1
+ j rem sizeGF = 0 =>
+ -- in this case one has to increase f{i2}
+ tailpol := cons(term, tailpol) -- [[i1,f{i1}],...,[0,f0]]
+ headpol := rest headpol -- [[i2,f{i2}],...,[n,1]]
+ taillookuplist := cons(j, taillookuplist)
+ headlookuplist := rest headlookuplist
+ -- otherwise set f{i1} := index(j)$GF
+ setelt(first headpol, coeff, index(j :: PI)$GF)
+ setfirst_!(headlookuplist, j)
+ if empty? taillookuplist then
+ pol := revListToSUP(headpol)
+ --
+ -- may be improved by excluding reciprocal polynomials
+ --
+ irreducible? pol => return pol
+ else
+ -- go back to fk
+ headpol := cons(first tailpol, headpol) -- [[k,fk],...,[n,1]]
+ tailpol := rest tailpol
+ headlookuplist := cons(first taillookuplist, headlookuplist)
+ taillookuplist := rest taillookuplist
+ -- must search for polynomial with greater weight
+ if empty? s then -- compute s(f)
+ restfcopy := rest fcopy
+ for entry in restfcopy repeat s := cons(entry.expnt, s)
+ weight = n => return "failed"
+ s1 := nextSubset(rest s, n1) :: L NNI
+ s := cons(0, s1)
+ weight := #s
+ taillookuplist := []
+ headlookuplist := cons(sizeGF, new((weight-1) :: NNI, 1))
+ tailpol := []
+ headpol := [] -- [[0,0], [s.2,1], ... , [s.weight,1], [n,1]] :
+ s1 := cons(n, reverse s1)
+ while not empty? s1 repeat
+ headpol := cons([first s1, 1]$Rec, headpol)
+ s1 := rest s1
+ headpol := cons([0, 0]$Rec, headpol)
+
+ nextPrimitivePoly f ==
+ n : NNI := degree f
+ n = 0 => error "polynomial must have positive degree"
+ -- make f monic
+ if (lcf := leadingCoefficient f) ^= 1 then f := (inv lcf) * f
+ -- if f = fn*X**n + ... + f{i0}*X**{i0} with the fi non-zero
+ -- then fRepr := [[n,fn], ... , [i0,f{i0}]]
+ fRepr : Repr := f pretend Repr
+ fcopy : Repr := []
+ -- we can not simply write fcopy := copy fRepr because
+ -- the input(!) f would be modified by assigning
+ -- a new value to one of its records
+ for term in fRepr repeat
+ fcopy := cons(copy term, fcopy)
+ if term.expnt ^= 0 then
+ term := [0,0]$Rec
+ fcopy := cons(term, fcopy)
+ fcopy := reverse fcopy
+ xn : Rec := first fcopy
+ c0 : GF := term.coeff
+ l : NNI := lookup(c0)$GF rem sizeGF
+ n = 1 =>
+ -- the polynomial X + c is primitive if and only if -c
+ -- is a primitive element of GF
+ q1 : NNI := (sizeGF - 1) :: NNI
+ while l < q1 repeat -- find next c such that -c is primitive
+ l := l + 1
+ c := index(l :: PI)$GF
+ primitive?(-c)$GF =>
+ return [xn, [0,c]$Rec] pretend SUP
+ "failed"
+ weight : NNI := (#(fcopy) - 1) :: NNI -- #s(f)+1 as explained above
+ s : L NNI := [] -- we will compute s(f) only if necessary
+ n1 : NNI := (n - 1) :: NNI
+ -- a necessary condition for a monic polynomial f of degree n
+ -- over GF to be primitive is that (-1)**n * f(0) be a
+ -- primitive element of GF (cf. [LN] p.90, Th. 3.18)
+ c : GF := c0
+ while l < sizeGF repeat
+ -- (run through the possible values of the constant term)
+ noGenerator : Boolean := true
+ while noGenerator and l < sizeGF repeat
+ -- find least c >= c0 such that (-1)^n c0 is primitive
+ primitive?((-1)**n * c)$GF => noGenerator := false
+ l := l + 1
+ c := index(l :: PI)$GF
+ noGenerator => return "failed"
+ constterm : Rec := [0, c]$Rec
+ if c = c0 and weight > 1 then
+ headpol : Repr := rest reverse fcopy -- [[i0,f{i0}],...,[n,1]]
+ -- fi is non-zero for i>0
+ -- the zeroes in the headlookuplist stand for the fi
+ -- whose lookup's were not yet computed :
+ headlookuplist : L NNI := new(weight, 0)
+ else
+ -- X**n + c can not be primitive for n > 1 (cf. [LN] p.90,
+ -- Th. 3.18); next possible polynomial is X**n + X + c
+ headpol : Repr := [[1,0]$Rec, xn] -- 0*X + X**n
+ headlookuplist : L NNI := [sizeGF]
+ s := [0,1]
+ weight := 2
+ tailpol : Repr := []
+ taillookuplist : L NNI := []
+ notReady : Boolean := true
+ while notReady repeat
+ -- (run through the possible weights)
+ while not empty? headlookuplist repeat
+ -- find next polynomial in the above order with fixed
+ -- constant term and weight; assume at this point we have
+ -- headpol = [[i1,f{i1}], [i2,f{i2}], ... , [n,1]] and
+ -- tailpol = [[k,fk],...,[k0,fk0]] (k0<...<k<i1<i2<...<n)
+ term := first headpol
+ j := first headlookuplist
+ if j = 0 then j := lookup(term.coeff)$GF
+ j := j + 1 -- lookup(f{i1})$GF + 1
+ j rem sizeGF = 0 =>
+ -- in this case one has to increase f{i2}
+ tailpol := cons(term, tailpol) -- [[i1,f{i1}],...,[k0,f{k0}]]
+ headpol := rest headpol -- [[i2,f{i2}],...,[n,1]]
+ taillookuplist := cons(j, taillookuplist)
+ headlookuplist := rest headlookuplist
+ -- otherwise set f{i1} := index(j)$GF
+ setelt(first headpol, coeff, index(j :: PI)$GF)
+ setfirst_!(headlookuplist, j)
+ if empty? taillookuplist then
+ pol := revListToSUP cons(constterm, headpol)
+ --
+ -- may be improved by excluding reciprocal polynomials
+ --
+ primitive? pol => return pol
+ else
+ -- go back to fk
+ headpol := cons(first tailpol, headpol) -- [[k,fk],...,[n,1]]
+ tailpol := rest tailpol
+ headlookuplist := cons(first taillookuplist,
+ headlookuplist)
+ taillookuplist := rest taillookuplist
+ if weight = n then notReady := false
+ else
+ -- must search for polynomial with greater weight
+ if empty? s then -- compute s(f)
+ restfcopy := rest fcopy
+ for entry in restfcopy repeat s := cons(entry.expnt, s)
+ s1 := nextSubset(rest s, n1) :: L NNI
+ s := cons(0, s1)
+ weight := #s
+ taillookuplist := []
+ headlookuplist := cons(sizeGF, new((weight-2) :: NNI, 1))
+ tailpol := []
+ -- headpol = [[s.2,0], [s.3,1], ... , [s.weight,1], [n,1]] :
+ headpol := [[first s1, 0]$Rec]
+ while not empty? (s1 := rest s1) repeat
+ headpol := cons([first s1, 1]$Rec, headpol)
+ headpol := reverse cons([n, 1]$Rec, headpol)
+ -- next polynomial must have greater constant term
+ l := l + 1
+ c := index(l :: PI)$GF
+ "failed"
+
+ nextNormalPoly f ==
+ n : NNI := degree f
+ n = 0 => error "polynomial must have positive degree"
+ -- make f monic
+ if (lcf := leadingCoefficient f) ^= 1 then f := (inv lcf) * f
+ -- if f = fn*X**n + ... + f{i0}*X**{i0} with the fi non-zero
+ -- then fRepr := [[n,fn], ... , [i0,f{i0}]]
+ fRepr : Repr := f pretend Repr
+ fcopy : Repr := []
+ -- we can not simply write fcopy := copy fRepr because
+ -- the input(!) f would be modified by assigning
+ -- a new value to one of its records
+ for term in fRepr repeat
+ fcopy := cons(copy term, fcopy)
+ if term.expnt ^= 0 then
+ term := [0,0]$Rec
+ fcopy := cons(term, fcopy)
+ fcopy := reverse fcopy -- [[n,1], [r,fr], ... , [0,f0]]
+ xn : Rec := first fcopy
+ middlepol : Repr := rest fcopy -- [[r,fr], ... , [0,f0]]
+ a0 : GF := (first middlepol).coeff -- fr
+ l : NNI := lookup(a0)$GF rem sizeGF
+ n = 1 =>
+ -- the polynomial X + a is normal if and only if a is not zero
+ l = sizeGF - 1 => "failed"
+ [xn, [0, index((l+1) :: PI)$GF]$Rec] pretend SUP
+ n1 : NNI := (n - 1) :: NNI
+ n2 : NNI := (n1 - 1) :: NNI
+ -- if the polynomial X**n + a * X**(n-1) + ... is normal then
+ -- a = -(x + x**q +...+ x**(q**n)) can not be zero (where q = #GF)
+ a : GF := a0
+ -- if a = 0 then set a := 1
+ if l = 0 then
+ l := 1
+ a := 1$GF
+ while l < sizeGF repeat
+ -- (run through the possible values of a)
+ if a = a0 then
+ -- middlepol = [[0,f0], ... , [m,fm]] with m < n-1
+ middlepol := reverse rest middlepol
+ weight : NNI := #middlepol -- #s(f) as explained above
+ -- the zeroes in the middlelookuplist stand for the fi
+ -- whose lookup's were not yet computed :
+ middlelookuplist : L NNI := new(weight, 0)
+ s : L NNI := [] -- we will compute s(f) only if necessary
+ else
+ middlepol := [[0,0]$Rec]
+ middlelookuplist : L NNI := [sizeGF]
+ s : L NNI := [0]
+ weight : NNI := 1
+ headpol : Repr := [xn, [n1, a]$Rec] -- X**n + a * X**(n-1)
+ tailpol : Repr := []
+ taillookuplist : L NNI := []
+ notReady : Boolean := true
+ while notReady repeat
+ -- (run through the possible weights)
+ while not empty? middlelookuplist repeat
+ -- find next polynomial in the above order with fixed
+ -- a and weight; assume at this point we have
+ -- middlepol = [[i1,f{i1}], [i2,f{i2}], ... , [m,fm]] and
+ -- tailpol = [[k,fk],...,[0,f0]] ( with k<i1<i2<...<m)
+ term := first middlepol
+ j := first middlelookuplist
+ if j = 0 then j := lookup(term.coeff)$GF
+ j := j + 1 -- lookup(f{i1})$GF + 1
+ j rem sizeGF = 0 =>
+ -- in this case one has to increase f{i2}
+ -- tailpol = [[i1,f{i1}],...,[0,f0]]
+ tailpol := cons(term, tailpol)
+ middlepol := rest middlepol -- [[i2,f{i2}],...,[m,fm]]
+ taillookuplist := cons(j, taillookuplist)
+ middlelookuplist := rest middlelookuplist
+ -- otherwise set f{i1} := index(j)$GF
+ setelt(first middlepol, coeff, index(j :: PI)$GF)
+ setfirst_!(middlelookuplist, j)
+ if empty? taillookuplist then
+ pol := listToSUP append(headpol, reverse middlepol)
+ --
+ -- may be improved by excluding reciprocal polynomials
+ --
+ normal? pol => return pol
+ else
+ -- go back to fk
+ -- middlepol = [[k,fk],...,[m,fm]]
+ middlepol := cons(first tailpol, middlepol)
+ tailpol := rest tailpol
+ middlelookuplist := cons(first taillookuplist,
+ middlelookuplist)
+ taillookuplist := rest taillookuplist
+ if weight = n1 then notReady := false
+ else
+ -- must search for polynomial with greater weight
+ if empty? s then -- compute s(f)
+ restfcopy := rest rest fcopy
+ for entry in restfcopy repeat s := cons(entry.expnt, s)
+ s1 := nextSubset(rest s, n2) :: L NNI
+ s := cons(0, s1)
+ weight := #s
+ taillookuplist := []
+ middlelookuplist := cons(sizeGF, new((weight-1) :: NNI, 1))
+ tailpol := []
+ -- middlepol = [[0,0], [s.2,1], ... , [s.weight,1]] :
+ middlepol := []
+ s1 := reverse s1
+ while not empty? s1 repeat
+ middlepol := cons([first s1, 1]$Rec, middlepol)
+ s1 := rest s1
+ middlepol := cons([0,0]$Rec, middlepol)
+ -- next polynomial must have greater a
+ l := l + 1
+ a := index(l :: PI)$GF
+ "failed"
+
+ nextNormalPrimitivePoly f ==
+ n : NNI := degree f
+ n = 0 => error "polynomial must have positive degree"
+ -- make f monic
+ if (lcf := leadingCoefficient f) ^= 1 then f := (inv lcf) * f
+ -- if f = fn*X**n + ... + f{i0}*X**{i0} with the fi non-zero
+ -- then fRepr := [[n,fn], ... , [i0,f{i0}]]
+ fRepr : Repr := f pretend Repr
+ fcopy : Repr := []
+ -- we can not simply write fcopy := copy fRepr because
+ -- the input(!) f would be modified by assigning
+ -- a new value to one of its records
+ for term in fRepr repeat
+ fcopy := cons(copy term, fcopy)
+ if term.expnt ^= 0 then
+ term := [0,0]$Rec
+ fcopy := cons(term, fcopy)
+ fcopy := reverse fcopy -- [[n,1], [r,fr], ... , [0,f0]]
+ xn : Rec := first fcopy
+ c0 : GF := term.coeff
+ lc : NNI := lookup(c0)$GF rem sizeGF
+ n = 1 =>
+ -- the polynomial X + c is primitive if and only if -c
+ -- is a primitive element of GF
+ q1 : NNI := (sizeGF - 1) :: NNI
+ while lc < q1 repeat -- find next c such that -c is primitive
+ lc := lc + 1
+ c := index(lc :: PI)$GF
+ primitive?(-c)$GF =>
+ return [xn, [0,c]$Rec] pretend SUP
+ "failed"
+ n1 : NNI := (n - 1) :: NNI
+ n2 : NNI := (n1 - 1) :: NNI
+ middlepol : Repr := rest fcopy -- [[r,fr],...,[i0,f{i0}],[0,f0]]
+ a0 : GF := (first middlepol).coeff
+ la : NNI := lookup(a0)$GF rem sizeGF
+ -- if the polynomial X**n + a * X**(n-1) +...+ c is primitive and
+ -- normal over GF then (-1)**n * c is a primitive element of GF
+ -- (cf. [LN] p.90, Th. 3.18), and a = -(x + x**q +...+ x**(q**n))
+ -- is not zero (where q = #GF)
+ c : GF := c0
+ a : GF := a0
+ -- if a = 0 then set a := 1
+ if la = 0 then
+ la := 1
+ a := 1$GF
+ while lc < sizeGF repeat
+ -- (run through the possible values of the constant term)
+ noGenerator : Boolean := true
+ while noGenerator and lc < sizeGF repeat
+ -- find least c >= c0 such that (-1)**n * c0 is primitive
+ primitive?((-1)**n * c)$GF => noGenerator := false
+ lc := lc + 1
+ c := index(lc :: PI)$GF
+ noGenerator => return "failed"
+ constterm : Rec := [0, c]$Rec
+ while la < sizeGF repeat
+ -- (run through the possible values of a)
+ headpol : Repr := [xn, [n1, a]$Rec] -- X**n + a X**(n-1)
+ if c = c0 and a = a0 then
+ -- middlepol = [[i0,f{i0}], ... , [m,fm]] with m < n-1
+ middlepol := rest reverse rest middlepol
+ weight : NNI := #middlepol + 1 -- #s(f)+1 as explained above
+ -- the zeroes in the middlelookuplist stand for the fi
+ -- whose lookup's were not yet computed :
+ middlelookuplist : L NNI := new((weight-1) :: NNI, 0)
+ s : L NNI := [] -- we will compute s(f) only if necessary
+ else
+ pol := listToSUP append(headpol, [constterm])
+ normal? pol and primitive? pol => return pol
+ middlepol := [[1,0]$Rec]
+ middlelookuplist : L NNI := [sizeGF]
+ s : L NNI := [0,1]
+ weight : NNI := 2
+ tailpol : Repr := []
+ taillookuplist : L NNI := []
+ notReady : Boolean := true
+ while notReady repeat
+ -- (run through the possible weights)
+ while not empty? middlelookuplist repeat
+ -- find next polynomial in the above order with fixed
+ -- c, a and weight; assume at this point we have
+ -- middlepol = [[i1,f{i1}], [i2,f{i2}], ... , [m,fm]]
+ -- tailpol = [[k,fk],...,[k0,fk0]] (k0<...<k<i1<...<m)
+ term := first middlepol
+ j := first middlelookuplist
+ if j = 0 then j := lookup(term.coeff)$GF
+ j := j + 1 -- lookup(f{i1})$GF + 1
+ j rem sizeGF = 0 =>
+ -- in this case one has to increase f{i2}
+ -- tailpol = [[i1,f{i1}],...,[k0,f{k0}]]
+ tailpol := cons(term, tailpol)
+ middlepol := rest middlepol -- [[i2,f{i2}],...,[m,fm]]
+ taillookuplist := cons(j, taillookuplist)
+ middlelookuplist := rest middlelookuplist
+ -- otherwise set f{i1} := index(j)$GF
+ setelt(first middlepol, coeff, index(j :: PI)$GF)
+ setfirst_!(middlelookuplist, j)
+ if empty? taillookuplist then
+ pol := listToSUP append(headpol, reverse
+ cons(constterm, middlepol))
+ --
+ -- may be improved by excluding reciprocal polynomials
+ --
+ normal? pol and primitive? pol => return pol
+ else
+ -- go back to fk
+ -- middlepol = [[k,fk],...,[m,fm]]
+ middlepol := cons(first tailpol, middlepol)
+ tailpol := rest tailpol
+ middlelookuplist := cons(first taillookuplist,
+ middlelookuplist)
+ taillookuplist := rest taillookuplist
+ if weight = n1 then notReady := false
+ else
+ -- must search for polynomial with greater weight
+ if empty? s then -- compute s(f)
+ restfcopy := rest rest fcopy
+ for entry in restfcopy repeat s := cons(entry.expnt, s)
+ s1 := nextSubset(rest s, n2) :: L NNI
+ s := cons(0, s1)
+ weight := #s
+ taillookuplist := []
+ middlelookuplist := cons(sizeGF, new((weight-2)::NNI, 1))
+ tailpol := []
+ -- middlepol = [[s.2,0], [s.3,1], ... , [s.weight,1] :
+ middlepol := [[first s1, 0]$Rec]
+ while not empty? (s1 := rest s1) repeat
+ middlepol := cons([first s1, 1]$Rec, middlepol)
+ middlepol := reverse middlepol
+ -- next polynomial must have greater a
+ la := la + 1
+ a := index(la :: PI)$GF
+ -- next polynomial must have greater constant term
+ lc := lc + 1
+ c := index(lc :: PI)$GF
+ la := 1
+ a := 1$GF
+ "failed"
+
+ nextPrimitiveNormalPoly f == nextNormalPrimitivePoly f
+
+ createIrreduciblePoly n ==
+ x := monomial(1,1)$SUP
+ n = 1 => x
+ xn := monomial(1,n)$SUP
+ n >= sizeGF => nextIrreduciblePoly(xn + x) :: SUP
+ -- (since in this case there is most no irreducible binomial X+a)
+ odd? n => nextIrreduciblePoly(xn + 1) :: SUP
+ nextIrreduciblePoly(xn) :: SUP
+
+ createPrimitivePoly n ==
+ -- (see also the comments in the code of nextPrimitivePoly)
+ xn := monomial(1,n)$SUP
+ n = 1 => xn + monomial(-primitiveElement()$GF, 0)$SUP
+ c0 : GF := (-1)**n * primitiveElement()$GF
+ constterm : Rec := [0, c0]$Rec
+ -- try first (probably faster) the polynomials
+ -- f = X**n + f{n-1}*X**(n-1) +...+ f1*X + c0 for which
+ -- fi is 0 or 1 for i=1,...,n-1,
+ -- and this in the order used to define nextPrimitivePoly
+ s : L NNI := [0,1]
+ weight : NNI := 2
+ s1 : L NNI := [1]
+ n1 : NNI := (n - 1) :: NNI
+ notReady : Boolean := true
+ while notReady repeat
+ polRepr : Repr := [constterm]
+ while not empty? s1 repeat
+ polRepr := cons([first s1, 1]$Rec, polRepr)
+ s1 := rest s1
+ polRepr := cons([n, 1]$Rec, polRepr)
+ --
+ -- may be improved by excluding reciprocal polynomials
+ --
+ primitive? (pol := listToSUP polRepr) => return pol
+ if weight = n then notReady := false
+ else
+ s1 := nextSubset(rest s, n1) :: L NNI
+ s := cons(0, s1)
+ weight := #s
+ -- if there is no primitive f of the above form
+ -- search now from the beginning, allowing arbitrary
+ -- coefficients f_i, i = 1,...,n-1
+ nextPrimitivePoly(xn + monomial(c0, 0)$SUP) :: SUP
+
+ createNormalPoly n ==
+ n = 1 => monomial(1,1)$SUP + monomial(-1,0)$SUP
+ -- get a normal polynomial f = X**n + a * X**(n-1) + ...
+ -- with a = -1
+ -- [recall that if f is normal over the field GF of order q
+ -- then a = -(x + x**q +...+ x**(q**n)) can not be zero;
+ -- hence the existence of such an f follows from the
+ -- normal basis theorem ([LN] p.60, Th. 2.35) and the
+ -- surjectivity of the trace ([LN] p.55, Th. 2.23 (iii))]
+ nextNormalPoly(monomial(1,n)$SUP
+ + monomial(-1, (n-1) :: NNI)$SUP) :: SUP
+
+ createNormalPrimitivePoly n ==
+ xn := monomial(1,n)$SUP
+ n = 1 => xn + monomial(-primitiveElement()$GF, 0)$SUP
+ n1 : NNI := (n - 1) :: NNI
+ c0 : GF := (-1)**n * primitiveElement()$GF
+ constterm := monomial(c0, 0)$SUP
+ -- try first the polynomials f = X**n + a * X**(n-1) + ...
+ -- with a = -1
+ pol := xn + monomial(-1, n1)$SUP + constterm
+ normal? pol and primitive? pol => pol
+ res := nextNormalPrimitivePoly(pol)
+ res case SUP => res
+ -- if there is no normal primitive f with a = -1
+ -- get now one with arbitrary (non-zero) a
+ -- (the existence is proved in [LS])
+ pol := xn + monomial(1, n1)$SUP + constterm
+ normal? pol and primitive? pol => pol
+ nextNormalPrimitivePoly(pol) :: SUP
+
+ createPrimitiveNormalPoly n == createNormalPrimitivePoly n
+
+-- qAdicExpansion m ==
+-- ragits : List I := wholeRagits(m :: (RadixExpansion sizeGF))
+-- pol : SUP := 0
+-- expt : NNI := #ragits
+-- for i in ragits repeat
+-- expt := (expt - 1) :: NNI
+-- if i ^= 0 then pol := pol + monomial(index(i::PI)$GF, expt)
+-- pol
+
+-- random == qAdicExpansion(random()$I)
+
+-- random n ==
+-- pol := monomial(1,n)$SUP
+-- n1 : NNI := (n - 1) :: NNI
+-- for i in 0..n1 repeat
+-- if (c := random()$GF) ^= 0 then
+-- pol := pol + monomial(c, i)$SUP
+-- pol
+
+ random n ==
+ polRepr : Repr := []
+ n1 : NNI := (n - 1) :: NNI
+ for i in 0..n1 repeat
+ if (c := random()$GF) ^= 0 then
+ polRepr := cons([i, c]$Rec, polRepr)
+ cons([n, 1$GF]$Rec, polRepr) pretend SUP
+
+ random(m,n) ==
+ if m > n then (m,n) := (n,m)
+ d : NNI := (n - m) :: NNI
+ if d > 1 then n := ((random()$I rem (d::PI)) + m) :: PI
+ random(n)
+
+@
+\begin{verbatim}
+-- 12.05.92: JG: long lines
+-- 25.02.92: AS: normal? changed. Now using reducedQPowers
+-- 05.04.91: JG: error in createNormalPrimitivePoly was corrected
+\end{verbatim}
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FFPOLY FiniteFieldPolynomialPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffpoly2.spad.pamphlet b/src/algebra/ffpoly2.spad.pamphlet
new file mode 100644
index 00000000..1271362a
--- /dev/null
+++ b/src/algebra/ffpoly2.spad.pamphlet
@@ -0,0 +1,172 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffpoly2.spad}
+\author{Johannes Grabmeier, Alfred Scheerhorn}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FFPOLY2 FiniteFieldPolynomialPackage2}
+<<package FFPOLY2 FiniteFieldPolynomialPackage2>>=
+)abbrev package FFPOLY2 FiniteFieldPolynomialPackage2
+++ Authors: J.Grabmeier, A.Scheerhorn
+++ Date Created: 26.03.1991
+++ Date Last Updated:
+++ Basic Operations: rootOfIrreduciblePoly
+++ Related Constructors: FiniteFieldCategory
+++ Also See:
+++ AMS Classifications:
+++ Keywords: finite field, zeros of polynomials, Berlekamp's trace algorithm
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ AXIOM Technical Report Series, to appear.
+++ Description:
+++ FiniteFieldPolynomialPackage2(F,GF) exports some functions concerning
+++ finite fields, which depend on a finite field {\em GF} and an
+++ algebraic extension F of {\em GF}, e.g. a zero of a polynomial
+++ over {\em GF} in F.
+FiniteFieldPolynomialPackage2(F,GF):Exports == Implementation where
+ F:FieldOfPrimeCharacteristic with
+ coerce: GF -> F
+ ++ coerce(x) \undocumented{}
+ lookup: F -> PositiveInteger
+ ++ lookup(x) \undocumented{}
+ basis: PositiveInteger -> Vector F
+ ++ basis(n) \undocumented{}
+ Frobenius: F -> F
+ ++ Frobenius(x) \undocumented{}
+ -- F should be a algebraic extension of the finite field GF, either an
+ -- algebraic closure of GF or a simple algebraic extension field of GF
+ GF:FiniteFieldCategory
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ SUP ==> SparseUnivariatePolynomial
+ MM ==> ModMonic(GF,SUP GF)
+ OUT ==> OutputForm
+ M ==> Matrix
+ V ==> Vector
+ L ==> List
+ FFPOLY ==> FiniteFieldPolynomialPackage(GF)
+ SUPF2 ==> SparseUnivariatePolynomialFunctions2(GF,F)
+
+ Exports ==> with
+
+ rootOfIrreduciblePoly:SUP GF -> F
+ ++ rootOfIrreduciblePoly(f) computes one root of the monic,
+ ++ irreducible polynomial f, which degree must divide the extension degree
+ ++ of {\em F} over {\em GF},
+ ++ i.e. f splits into linear factors over {\em F}.
+
+
+ Implementation ==> add
+
+-- we use berlekamps trace algorithm
+-- it is not checked whether the polynomial is irreducible over GF]]
+ rootOfIrreduciblePoly(pf) ==
+-- not irreducible(pf)$FFPOLY =>
+-- error("polynomial has to be irreducible")
+ sizeGF:=size()$GF
+ -- if the polynomial is of degree one, we're ready
+ deg:=degree(pf)$(SUP GF)::PI
+ deg = 0 => error("no roots")
+ deg = 1 => -coefficient(pf,0)$(SUP GF)::F
+ p : SUP F := map(coerce,pf)$SUPF2
+ -- compute qexp, qexp(i) = x **(size()GF ** i) mod p
+ -- with this list it's easier to compute the gcd(p(x),trace(x))
+ qexp:=reducedQPowers(pf)$FFPOLY
+ stillToFactor:=p
+ -- take linear independent elements, the basis of F over GF
+ basis:Vector F:=basis(deg)$F
+ basispointer:I:=1
+ -- as p is irreducible over GF, 0 can't be a root of p
+ -- therefore we can use the predicate zero?(root) for indicating
+ -- whether a root is found
+ root:=0$F
+ while zero?(root)$F repeat
+ beta:F:=basis.basispointer
+ -- gcd(trace(x)+gf,p(x)) has degree 0,that's why we skip beta=1
+ if beta = 1$F then
+ basispointer:=basispointer + 1
+ beta:= basis.basispointer
+ basispointer:=basispointer+1
+ -- compute the polynomial trace(beta * x) mod p(x) using explist
+ trModp:SUP F:= map(coerce,qexp.0)$SUPF2 * beta
+ for i in 1..deg-1 repeat
+ beta:=Frobenius(beta)
+ trModp:=trModp +$(SUP F) beta *$(SUP F) map(coerce,qexp.i)$SUPF2
+ -- if it is of degree 0, it doesn't help us finding a root
+ if degree(trModp)$(SUP F) > 0 then
+ -- for all elements gf of GF do
+ for j in 1..sizeGF repeat
+ -- compute gcd(trace(beta * x) + gf,stillToFactor)
+ h:=gcd(stillToFactor,trModp +$(SUP F) _
+ (index(j pretend PI)$GF::F::(SUP F)))$(SUP F)
+ -- make the gcd polynomial monic
+ if leadingCoefficient(h)$(SUP F) ^= 1$F then
+ h:= (inv leadingCoefficient(h)) * h
+ degh:=degree(h)$(SUP F)
+ degSTF:=degree(stillToFactor)$(SUP F)
+ -- if the gcd has degree one we are ready
+ degh = 1 => root:=-coefficient(h,0)$(SUP F)
+ -- if the quotient of stillToFactor and the gcd has
+ -- degree one, we're also ready
+ degSTF - degh = 1 =>
+ root:= -coefficient(stillToFactor quo h,0)$(SUP F)
+ -- otherwise the gcd helps us finding a root, only if its
+ -- degree is between 2 and degree(stillToFactor)-2
+ if degh > 1 and degh < degSTF then
+ 2*degh > degSTF => stillToFactor := stillToFactor quo h
+ stillToFactor := h
+ root
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FFPOLY2 FiniteFieldPolynomialPackage2>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffrac.as.pamphlet b/src/algebra/ffrac.as.pamphlet
new file mode 100644
index 00000000..8eccc8a9
--- /dev/null
+++ b/src/algebra/ffrac.as.pamphlet
@@ -0,0 +1,204 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffrac.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+
+-- FormalFraction
+
+-- N.B. ndftip.as inlines this, must be recompiled if this is.
+
+-- To test:
+-- sed '1,/^#if NeverAssertThis/d;/#endif/d' < ffrac.as > ffrac.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r ffrac.input
+
+\end{verbatim}
+\section{FormalFraction}
+<<FormalFraction>>=
+
+#include "axiom.as"
+
+FFRAC ==> FormalFraction ;
+
+OF ==> OutputForm ;
+SC ==> SetCategory ;
+FRAC ==> Fraction ;
+ID ==> IntegralDomain ;
+
++++ Author: M.G. Richardson
++++ Date Created: 1996 Jan. 23
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors: Fraction
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This type represents formal fractions - that is, pairs displayed as
++++ fractions with no simplification.
++++
++++ If the elements of the pair have a type X which is an integral
++++ domain, a FFRAC X can be coerced to a FRAC X, provided that this
++++ is a valid type. A FRAC X can always be coerced to a FFRAC X.
++++ If the type of the elements is a Field, a FFRAC X can be coerced
++++ to X.
++++
++++ Formal fractions are used to return results from numerical methods
++++ which determine numerator and denominator separately, to enable
++++ users to inspect these components and recognise, for example,
++++ ratios of very small numbers as potentially indeterminate.
+
+FormalFraction(X : SC) : SC with {
+
+-- Could generalise further to allow numerator and denominator to be of
+-- different types, X and Y, both SCs. "Left as an exercise."
+
+ / : (X,X) -> % ;
+++ / forms the formal quotient of two items.
+
+ numer : % -> X ;
+++ numer returns the numerator of a FormalFraction.
+
+ denom : % -> X ;
+++ denom returns the denominator of a FormalFraction.
+
+ if X has ID then {
+
+ coerce : % -> FRAC(X pretend ID) ;
+++ coerce x converts a FormalFraction over an IntegralDomain to a
+++ Fraction over that IntegralDomain.
+
+ coerce : FRAC(X pretend ID) -> % ;
+++ coerce converts a Fraction to a FormalFraction.
+
+ }
+
+ if X has Field then coerce : % -> (X pretend Field) ;
+
+} == add {
+
+ import from Record(num : X, den : X) ;
+
+ Rep == Record(num : X, den : X) ; -- representation
+
+ ((x : %) = (y : %)) : Boolean ==
+ ((rep(x).num = rep(y).num) and (rep(x).den = rep(y).den)) ;
+
+ ((n : X)/(d : X)) : % == per(record(n,d)) ;
+
+ coerce(r : %) : OF == (rep(r).num :: OF) / (rep(r).den :: OF) ;
+
+ numer(r : %) : X == rep(r).num ;
+
+ denom(r : %) : X == rep(r).den ;
+
+ if X has ID then {
+
+ coerce(r : %) : FRAC(X pretend ID)
+ == ((rep(r).num)/(rep(r).den)) @ (FRAC(X pretend ID)) ;
+
+ coerce(x : FRAC(X pretend ID)) : % == x pretend % ;
+
+ }
+
+ if X has Field then coerce(r : %) : (X pretend Field)
+ == ((rep(r).num)/(rep(r).den)) $ (X pretend Field) ;
+
+}
+
+#if NeverAssertThis
+
+)lib ffrac
+
+f1 : FormalFraction Integer
+f1 := 6/3
+
+-- 6
+-- -
+-- 3
+
+f2 := (3.6/2.4)$FormalFraction Float
+
+-- 3.6
+-- ---
+-- 2.4
+
+numer f1
+
+-- 6
+
+denom f2
+
+-- 2.4
+
+f1 :: FRAC INT
+
+-- 2
+
+% :: FormalFraction Integer
+
+-- 2
+-- -
+-- 1
+
+f2 :: Float
+
+-- 1.5
+
+output "End of tests"
+
+#endif
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<FormalFraction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ffx.spad.pamphlet b/src/algebra/ffx.spad.pamphlet
new file mode 100644
index 00000000..66ccd76a
--- /dev/null
+++ b/src/algebra/ffx.spad.pamphlet
@@ -0,0 +1,120 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ffx.spad}
+\author{Robert Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IRREDFFX IrredPolyOverFiniteField}
+<<package IRREDFFX IrredPolyOverFiniteField>>=
+)abbrev package IRREDFFX IrredPolyOverFiniteField
+++ Author: Robert S. Sutor (original)
+++ Date Created: ???
+++ Date Last Updated: 29 May 1990
+++ Description:
+++ This package exports the function generateIrredPoly that computes
+++ a monic irreducible polynomial of degree n over a finite field.
+
+IrredPolyOverFiniteField(GF:FiniteFieldCategory): Exports == Impl where
+ N ==> PositiveInteger
+ Z ==> Integer
+ SUP ==> SparseUnivariatePolynomial GF
+ QR ==> Record(quotient: Z, remainder: Z)
+
+ Exports ==> with
+ generateIrredPoly: N -> SUP
+ ++ generateIrredPoly(n) generates an irreducible univariate
+ ++ polynomial of the given degree n over the finite field.
+
+ Impl ==> add
+ import DistinctDegreeFactorize(GF, SUP)
+
+ getIrredPoly : (Z, N) -> SUP
+ qAdicExpansion: Z -> SUP
+
+ p := characteristic()$GF :: N
+ q := size()$GF :: N
+
+ qAdicExpansion(z : Z): SUP ==
+ -- expands z as a sum of powers of q, with coefficients in GF
+ -- z = HornerEval(qAdicExpansion z,q)
+ qr := divide(z, q)
+ zero?(qr.remainder) => monomial(1, 1) * qAdicExpansion(qr.quotient)
+ r := index(qr.remainder pretend N)$GF :: SUP
+ zero?(qr.quotient) => r
+ r + monomial(1, 1) * qAdicExpansion(qr.quotient)
+
+ getIrredPoly(start : Z, n : N) : SUP ==
+ -- idea is to iterate over possibly irreducible monic polynomials
+ -- until we find an irreducible one. The obviously reducible ones
+ -- are avoided.
+ mon := monomial(1, n)$SUP
+ pol: SUP := 0
+ found: Boolean := false
+ end: Z := q**n - 1
+ while not ((end < start) or found) repeat
+ if gcd(start, p) = 1 then
+ if irreducible?(pol := mon + qAdicExpansion(start)) then
+ found := true
+ start := start + 1
+ zero? pol => error "no irreducible poly found"
+ pol
+
+ generateIrredPoly(n : N) : SUP ==
+ -- want same poly every time
+-- one?(n) => monomial(1, 1)$SUP
+ (n = 1) => monomial(1, 1)$SUP
+-- one?(gcd(p, n)) or (n < q) =>
+ (gcd(p, n) = 1) or (n < q) =>
+ odd?(n) => getIrredPoly(2, n)
+ getIrredPoly(1, n)
+ getIrredPoly(q + 1, n)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package IRREDFFX IrredPolyOverFiniteField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/files.spad.pamphlet b/src/algebra/files.spad.pamphlet
new file mode 100644
index 00000000..591bb1a0
--- /dev/null
+++ b/src/algebra/files.spad.pamphlet
@@ -0,0 +1,562 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra files.spad}
+\author{Stephen M. Watt, Victor Miller, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category FILECAT FileCategory}
+<<category FILECAT FileCategory>>=
+)abbrev category FILECAT FileCategory
+++ Author: Stephen M. Watt, Victor Miller
+++ Date Created:
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: File
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This category provides an interface to operate on files in the
+++ computer's file system. The precise method of naming files
+++ is determined by the Name parameter. The type of the contents
+++ of the file is determined by S.
+
+FileCategory(Name, S): Category == FCdefinition where
+ Name: SetCategory
+ S: SetCategory
+ IOMode ==> String -- Union("input", "output", "closed")
+
+ FCdefinition == SetCategory with
+ open: Name -> %
+ ++ open(s) returns the file s open for input.
+
+ open: (Name, IOMode) -> %
+ ++ open(s,mode) returns a file s open for operation in the
+ ++ indicated mode: "input" or "output".
+
+ reopen_!: (%, IOMode) -> %
+ ++ reopen!(f,mode) returns a file f reopened for operation in the
+ ++ indicated mode: "input" or "output".
+ ++ \spad{reopen!(f,"input")} will reopen the file f for input.
+
+ close_!: % -> %
+ ++ close!(f) returns the file f closed to input and output.
+
+ name: % -> Name
+ ++ name(f) returns the external name of the file f.
+
+ iomode: % -> IOMode
+ ++ iomode(f) returns the status of the file f. The input/output
+ ++ status of f may be "input", "output" or "closed" mode.
+
+ read_!: % -> S
+ ++ read!(f) extracts a value from file f. The state of f is
+ ++ modified so a subsequent call to \spadfun{read!} will return
+ ++ the next element.
+
+ write_!: (%,S) -> S
+ ++ write!(f,s) puts the value s into the file f.
+ ++ The state of f is modified so subsequents call to \spad{write!}
+ ++ will append one after another.
+
+@
+\section{domain FILE File}
+<<domain FILE File>>=
+)abbrev domain FILE File
+++ Author: Stephen M. Watt, Victor Miller
+++ Date Created: 1984
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides a basic model of files to save arbitrary values.
+++ The operations provide sequential access to the contents.
+
+File(S:SetCategory): FileCategory(FileName, S) with
+ readIfCan_!: % -> Union(S, "failed")
+ ++ readIfCan!(f) returns a value from the file f, if possible.
+ ++ If f is not open for reading, or if f is at the end of file
+ ++ then \spad{"failed"} is the result.
+ == add
+ FileState ==> SExpression
+ IOMode ==> String
+
+ Rep:=Record(fileName: FileName, _
+ fileState: FileState, _
+ fileIOmode: IOMode)
+
+ defstream(fn: FileName, mode: IOMode): FileState ==
+ mode = "input" =>
+ not readable? fn => error ["File is not readable", fn]
+ MAKE_-INSTREAM(fn::String)$Lisp
+ mode = "output" =>
+ not writable? fn => error ["File is not writable", fn]
+ MAKE_-OUTSTREAM(fn::String)$Lisp
+ error ["IO mode must be input or output", mode]
+
+ f1 = f2 ==
+ f1.fileName = f2.fileName
+ coerce(f: %): OutputForm ==
+ f.fileName::OutputForm
+
+ open fname ==
+ open(fname, "input")
+ open(fname, mode) ==
+ fstream := defstream(fname, mode)
+ [fname, fstream, mode]
+ reopen_!(f, mode) ==
+ fname := f.fileName
+ f.fileState := defstream(fname, mode)
+ f.fileIOmode:= mode
+ f
+ close_! f ==
+ SHUT(f.fileState)$Lisp
+ f.fileIOmode := "closed"
+ f
+ name f ==
+ f.fileName
+ iomode f ==
+ f.fileIOmode
+ read_! f ==
+ f.fileIOmode ^= "input" =>
+ error "File not in read state"
+ x := VMREAD(f.fileState)$Lisp
+ PLACEP(x)$Lisp =>
+ error "End of file"
+ x
+ readIfCan_! f ==
+ f.fileIOmode ^= "input" =>
+ error "File not in read state"
+ x: S := VMREAD(f.fileState)$Lisp
+ PLACEP(x)$Lisp => "failed"
+ x
+ write_!(f, x) ==
+ f.fileIOmode ^= "output" =>
+ error "File not in write state"
+ z := PRINT_-FULL(x, f.fileState)$Lisp
+ TERPRI(f.fileState)$Lisp
+ x
+
+@
+\section{domain TEXTFILE TextFile}
+<<domain TEXTFILE TextFile>>=
+)abbrev domain TEXTFILE TextFile
+++ Author: Stephen M. Watt
+++ Date Created: 1985
+++ Date Last Updated: June 4, 1991
+++ Basic Operations: writeLine! readLine! readLineIfCan! readIfCan! endOfFile?
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain provides an implementation of text files. Text is stored
+++ in these files using the native character set of the computer.
+
+TextFile: Cat == Def where
+ StreamName ==> Union(FileName, "console")
+
+ Cat == FileCategory(FileName, String) with
+ writeLine_!: (%, String) -> String
+ ++ writeLine!(f,s) writes the contents of the string s
+ ++ and finishes the current line in the file f.
+ ++ The value of s is returned.
+
+ writeLine_!: % -> String
+ ++ writeLine!(f) finishes the current line in the file f.
+ ++ An empty string is returned. The call \spad{writeLine!(f)} is
+ ++ equivalent to \spad{writeLine!(f,"")}.
+
+ readLine_!: % -> String
+ ++ readLine!(f) returns a string of the contents of a line from
+ ++ the file f.
+
+ readLineIfCan_!: % -> Union(String, "failed")
+ ++ readLineIfCan!(f) returns a string of the contents of a line from
+ ++ file f, if possible. If f is not readable or if it is
+ ++ positioned at the end of file, then \spad{"failed"} is returned.
+
+ readIfCan_!: % -> Union(String, "failed")
+ ++ readIfCan!(f) returns a string of the contents of a line from
+ ++ file f, if possible. If f is not readable or if it is
+ ++ positioned at the end of file, then \spad{"failed"} is returned.
+
+ endOfFile?: % -> Boolean
+ ++ endOfFile?(f) tests whether the file f is positioned after the
+ ++ end of all text. If the file is open for output, then
+ ++ this test is always true.
+
+ Def == File(String) add
+ FileState ==> SExpression
+
+ Rep := Record(fileName: FileName, _
+ fileState: FileState, _
+ fileIOmode: String)
+
+ read_! f == readLine_! f
+ readIfCan_! f == readLineIfCan_! f
+
+ readLine_! f ==
+ f.fileIOmode ^= "input" => error "File not in read state"
+ s: String := read_-line(f.fileState)$Lisp
+ PLACEP(s)$Lisp => error "End of file"
+ s
+ readLineIfCan_! f ==
+ f.fileIOmode ^= "input" => error "File not in read state"
+ s: String := read_-line(f.fileState)$Lisp
+ PLACEP(s)$Lisp => "failed"
+ s
+ write_!(f, x) ==
+ f.fileIOmode ^= "output" => error "File not in write state"
+ PRINTEXP(x, f.fileState)$Lisp
+ x
+ writeLine_! f ==
+ f.fileIOmode ^= "output" => error "File not in write state"
+ TERPRI(f.fileState)$Lisp
+ ""
+ writeLine_!(f, x) ==
+ f.fileIOmode ^= "output" => error "File not in write state"
+ PRINTEXP(x, f.fileState)$Lisp
+ TERPRI(f.fileState)$Lisp
+ x
+ endOfFile? f ==
+ f.fileIOmode = "output" => false
+ (EOFP(f.fileState)$Lisp pretend Boolean) => true
+ false
+
+@
+\section{domain BINFILE BinaryFile}
+<<domain BINFILE BinaryFile>>=
+)abbrev domain BINFILE BinaryFile
+++ Author: Barry M. Trager
+++ Date Created: 1993
+++ Date Last Updated:
+++ Basic Operations: writeByte! readByte! readByteIfCan!
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain provides an implementation of binary files. Data is
+++ accessed one byte at a time as a small integer.
+
+BinaryFile: Cat == Def where
+
+ Cat == FileCategory(FileName, SingleInteger) with
+ readIfCan_!: % -> Union(SingleInteger, "failed")
+ ++ readIfCan!(f) returns a value from the file f, if possible.
+ ++ If f is not open for reading, or if f is at the end of file
+ ++ then \spad{"failed"} is the result.
+
+-- "#": % -> SingleInteger
+-- ++ #(f) returns the length of the file f in bytes.
+
+ position: % -> SingleInteger
+ ++ position(f) returns the current byte-position in the file f.
+
+ position_!: (%, SingleInteger) -> SingleInteger
+ ++ position!(f, i) sets the current byte-position to i.
+
+ Def == File(SingleInteger) add
+ FileState ==> SExpression
+
+ Rep := Record(fileName: FileName, _
+ fileState: FileState, _
+ fileIOmode: String)
+
+-- direc : Symbol := INTERN("DIRECTION","KEYWORD")$Lisp
+-- input : Symbol := INTERN("INPUT","KEYWORD")$Lisp
+-- output : Symbol := INTERN("OUTPUT","KEYWORD")$Lisp
+-- eltype : Symbol := INTERN("ELEMENT-TYPE","KEYWORD")$Lisp
+-- bytesize : SExpression := LIST(QUOTE(UNSIGNED$Lisp)$Lisp,8)$Lisp
+
+
+ defstream(fn: FileName, mode: String): FileState ==
+ mode = "input" =>
+ not readable? fn => error ["File is not readable", fn]
+ BINARY__OPEN__INPUT(fn::String)$Lisp
+-- OPEN(fn::String, direc, input, eltype, bytesize)$Lisp
+ mode = "output" =>
+ not writable? fn => error ["File is not writable", fn]
+ BINARY__OPEN__OUTPUT(fn::String)$Lisp
+-- OPEN(fn::String, direc, output, eltype, bytesize)$Lisp
+ error ["IO mode must be input or output", mode]
+
+ open(fname, mode) ==
+ fstream := defstream(fname, mode)
+ [fname, fstream, mode]
+
+ reopen_!(f, mode) ==
+ fname := f.fileName
+ f.fileState := defstream(fname, mode)
+ f.fileIOmode:= mode
+ f
+
+ close_! f ==
+ f.fileIOmode = "output" =>
+ BINARY__CLOSE__OUTPUT()$Lisp
+ f
+ f.fileIOmode = "input" =>
+ BINARY__CLOSE__INPUT()$Lisp
+ f
+ error "file must be in read or write state"
+
+ read! f ==
+ f.fileIOmode ^= "input" => error "File not in read state"
+ BINARY__SELECT__INPUT(f.fileState)$Lisp
+ BINARY__READBYTE()$Lisp
+-- READ_-BYTE(f.fileState)$Lisp
+ readIfCan_! f ==
+ f.fileIOmode ^= "input" => error "File not in read state"
+ BINARY__SELECT__INPUT(f.fileState)$Lisp
+ n:SingleInteger:=BINARY__READBYTE()$Lisp
+ n = -1 => "failed"
+ n::Union(SingleInteger,"failed")
+-- READ_-BYTE(f.fileState,NIL$Lisp,
+-- "failed"::Union(SingleInteger,"failed"))$Lisp
+ write_!(f, x) ==
+ f.fileIOmode ^= "output" => error "File not in write state"
+ x < 0 or x>255 => error "integer cannot be represented as a byte"
+ BINARY__PRINBYTE(x)$Lisp
+-- WRITE_-BYTE(x, f.fileState)$Lisp
+ x
+
+-- # f == FILE_-LENGTH(f.fileState)$Lisp
+ position f ==
+ f.fileIOmode ^= "input" => error "file must be in read state"
+ FILE_-POSITION(f.fileState)$Lisp
+ position_!(f,i) ==
+ f.fileIOmode ^= "input" => error "file must be in read state"
+ (FILE_-POSITION(f.fileState,i)$Lisp ; i)
+
+@
+\section{domain KAFILE KeyedAccessFile}
+<<domain KAFILE KeyedAccessFile>>=
+)abbrev domain KAFILE KeyedAccessFile
+++ Author: Stephen M. Watt
+++ Date Created: 1985
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows a random access file to be viewed both as a table
+++ and as a file object.
+
+
+KeyedAccessFile(Entry): KAFcategory == KAFcapsule where
+ Name ==> FileName
+ Key ==> String
+ Entry : SetCategory
+
+ KAFcategory ==
+ Join(FileCategory(Name, Record(key: Key, entry: Entry)),
+ TableAggregate(Key, Entry)) with
+ finiteAggregate
+ pack_!: % -> %
+ ++ pack!(f) reorganizes the file f on disk to recover
+ ++ unused space.
+
+ KAFcapsule == add
+
+ CLASS ==> 131 -- an arbitrary no. greater than 127
+ FileState ==> SExpression
+ IOMode ==> String
+
+
+ Cons:= Record(car: SExpression, cdr: SExpression)
+ Rep := Record(fileName: Name, _
+ fileState: FileState, _
+ fileIOmode: IOMode)
+
+ defstream(fn: Name, mode: IOMode): FileState ==
+ mode = "input" =>
+ not readable? fn => error ["File is not readable", fn]
+ RDEFINSTREAM(fn::String)$Lisp
+ mode = "output" =>
+ not writable? fn => error ["File is not writable", fn]
+ RDEFOUTSTREAM(fn::String)$Lisp
+ error ["IO mode must be input or output", mode]
+
+ ---- From Set ----
+ f1 = f2 ==
+ f1.fileName = f2.fileName
+ coerce(f: %): OutputForm ==
+ f.fileName::OutputForm
+
+ ---- From FileCategory ----
+ open fname ==
+ open(fname, "either")
+ open(fname, mode) ==
+ mode = "either" =>
+ exists? fname =>
+ open(fname, "input")
+ writable? fname =>
+ reopen_!(open(fname, "output"), "input")
+ error "File does not exist and cannot be created"
+ [fname, defstream(fname, mode), mode]
+ reopen_!(f, mode) ==
+ close_! f
+ if mode ^= "closed" then
+ f.fileState := defstream(f.fileName, mode)
+ f.fileIOmode := mode
+ f
+ close_! f ==
+ if f.fileIOmode ^= "closed" then
+ RSHUT(f.fileState)$Lisp
+ f.fileIOmode := "closed"
+ f
+ read_! f ==
+ f.fileIOmode ^= "input" => error ["File not in read state",f]
+ ks: List Symbol := RKEYIDS(f.fileName)$Lisp
+ null ks => error ["Attempt to read empty file", f]
+ ix := random()$Integer rem #ks
+ k: String := PNAME(ks.ix)$Lisp
+ [k, SPADRREAD(k, f.fileState)$Lisp]
+ write_!(f, pr) ==
+ f.fileIOmode ^= "output" => error ["File not in write state",f]
+ SPADRWRITE(pr.key, pr.entry, f.fileState)$Lisp
+ pr
+ name f ==
+ f.fileName
+ iomode f ==
+ f.fileIOmode
+
+ ---- From TableAggregate ----
+ empty() ==
+ fn := new("", "kaf", "sdata")$Name
+ open fn
+ keys f ==
+ close_! f
+ l: List SExpression := RKEYIDS(f.fileName)$Lisp
+ [PNAME(n)$Lisp for n in l]
+ # f ==
+ # keys f
+ elt(f,k) ==
+ reopen_!(f, "input")
+ SPADRREAD(k, f.fileState)$Lisp
+ setelt(f,k,e) ==
+ -- Leaves f in a safe, closed state. For speed use "write".
+ reopen_!(f, "output")
+ UNWIND_-PROTECT(write_!(f, [k,e]), close_! f)$Lisp
+ close_! f
+ e
+ search(k,f) ==
+ not member?(k, keys f) => "failed" -- can't trap RREAD error
+ reopen_!(f, "input")
+ (SPADRREAD(k, f.fileState)$Lisp)@Entry
+ remove_!(k:String,f:%) ==
+ result := search(k,f)
+ result case "failed" => result
+ close_! f
+ RDROPITEMS(NAMESTRING(f.fileName)$Lisp, LIST(k)$Lisp)$Lisp
+ result
+ pack_! f ==
+ close_! f
+ RPACKFILE(f.fileName)$Lisp
+ f
+
+@
+\section{domain LIB Library}
+<<domain LIB Library>>=
+)abbrev domain LIB Library
+++ Author: Stephen M. Watt
+++ Date Created: 1985
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: KeyedAccessFile
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides a simple way to save values in files.
+Library(): TableAggregate(String, Any) with
+ library: FileName -> %
+ ++ library(ln) creates a new library file.
+ pack_!: % -> %
+ ++ pack!(f) reorganizes the file f on disk to recover
+ ++ unused space.
+
+ elt : (%, Symbol) -> Any
+ ++ elt(lib,k) or lib.k extracts the value corresponding to the key \spad{k}
+ ++ from the library \spad{lib}.
+
+ setelt : (%, Symbol, Any) -> Any
+ ++ \spad{lib.k := v} saves the value \spad{v} in the library
+ ++ \spad{lib}. It can later be extracted using the key \spad{k}.
+
+ == KeyedAccessFile(Any) add
+ Rep := KeyedAccessFile(Any)
+ library f == open f
+ elt(f:%,v:Symbol) == elt(f, string v)
+ setelt(f:%, v:Symbol, val:Any) == setelt(f, string v, val)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category FILECAT FileCategory>>
+<<domain FILE File>>
+<<domain TEXTFILE TextFile>>
+<<domain BINFILE BinaryFile>>
+<<domain KAFILE KeyedAccessFile>>
+<<domain LIB Library>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/float.spad.pamphlet b/src/algebra/float.spad.pamphlet
new file mode 100644
index 00000000..3f5753f7
--- /dev/null
+++ b/src/algebra/float.spad.pamphlet
@@ -0,0 +1,1064 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra float.spad}
+\author{Michael Monagan}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FLOAT Float}
+As reported in bug number 4733 (rounding of negative numbers)
+errors were observed in operations such as
+\begin{verbatim}
+ -> round(-3.9)
+ -> truncate(-3.9)
+\end{verbatim}
+The problem is the unexpected behaviour of the shift
+with negative integer arguments.
+\begin{verbatim}
+ -> shift(-7,-1)
+\end{verbatim}
+returns -4 while the code here in float expects the
+value to be -3. shift uses the lisp function ASH
+'arithmetic shift left' but the spad code expects
+an unsigned 'logical' shift. See
+\begin{verbatim}
+ http://www.lispworks.com/reference/HyperSpec/Body/f_ash.htm#ash
+\end{verbatim}
+A new internal function shift2 is defined in terms of
+shift to compensate for the use of ASH and provide the
+required function.
+
+It is currently unknown whether the unexpected behaviour
+of shift for negative arguments will cause bugs in other
+parts of Axiom.
+<<domain FLOAT Float>>=
+)abbrev domain FLOAT Float
+
+B ==> Boolean
+I ==> Integer
+S ==> String
+PI ==> PositiveInteger
+RN ==> Fraction Integer
+SF ==> DoubleFloat
+N ==> NonNegativeInteger
+
+++ Author: Michael Monagan
+++ Date Created:
+++ December 1987
+++ Change History:
+++ 19 Jun 1990
+++ Basic Operations: outputFloating, outputFixed, outputGeneral, outputSpacing,
+++ atan, convert, exp1, log2, log10, normalize, rationalApproximation,
+++ relerror, shift, / , **
+++ Keywords: float, floating point, number
+++ Description: \spadtype{Float} implements arbitrary precision floating
+++ point arithmetic.
+++ The number of significant digits of each operation can be set
+++ to an arbitrary value (the default is 20 decimal digits).
+++ The operation \spad{float(mantissa,exponent,\spadfunFrom{base}{FloatingPointSystem})} for integer
+++ \spad{mantissa}, \spad{exponent} specifies the number
+++ \spad{mantissa * \spadfunFrom{base}{FloatingPointSystem} ** exponent}
+++ The underlying representation for floats is binary
+++ not decimal. The implications of this are described below.
+++
+++ The model adopted is that arithmetic operations are rounded to
+++ to nearest unit in the last place, that is, accurate to within
+++ \spad{2**(-\spadfunFrom{bits}{FloatingPointSystem})}.
+++ Also, the elementary functions and constants are
+++ accurate to one unit in the last place.
+++ A float is represented as a record of two integers, the mantissa
+++ and the exponent. The \spadfunFrom{base}{FloatingPointSystem}
+++ of the representation is binary, hence
+++ a \spad{Record(m:mantissa,e:exponent)} represents the number \spad{m * 2 ** e}.
+++ Though it is not assumed that the underlying integers are represented
+++ with a binary \spadfunFrom{base}{FloatingPointSystem},
+++ the code will be most efficient when this is the
+++ the case (this is true in most implementations of Lisp).
+++ The decision to choose the \spadfunFrom{base}{FloatingPointSystem} to be
+++ binary has some unfortunate
+++ consequences. First, decimal numbers like 0.3 cannot be represented
+++ exactly. Second, there is a further loss of accuracy during
+++ conversion to decimal for output. To compensate for this, if d
+++ digits of precision are specified, \spad{1 + ceiling(log2 d)} bits are used.
+++ Two numbers that are displayed identically may therefore be
+++ not equal. On the other hand, a significant efficiency loss would
+++ be incurred if we chose to use a decimal \spadfunFrom{base}{FloatingPointSystem} when the underlying
+++ integer base is binary.
+++
+++ Algorithms used:
+++ For the elementary functions, the general approach is to apply
+++ identities so that the taylor series can be used, and, so
+++ that it will converge within \spad{O( sqrt n )} steps. For example,
+++ using the identity \spad{exp(x) = exp(x/2)**2}, we can compute
+++ \spad{exp(1/3)} to n digits of precision as follows. We have
+++ \spad{exp(1/3) = exp(2 ** (-sqrt s) / 3) ** (2 ** sqrt s)}.
+++ The taylor series will converge in less than sqrt n steps and the
+++ exponentiation requires sqrt n multiplications for a total of
+++ \spad{2 sqrt n} multiplications. Assuming integer multiplication costs
+++ \spad{O( n**2 )} the overall running time is \spad{O( sqrt(n) n**2 )}.
+++ This approach is the best known approach for precisions up to
+++ about 10,000 digits at which point the methods of Brent
+++ which are \spad{O( log(n) n**2 )} become competitive. Note also that
+++ summing the terms of the taylor series for the elementary
+++ functions is done using integer operations. This avoids the
+++ overhead of floating point operations and results in efficient
+++ code at low precisions. This implementation makes no attempt
+++ to reuse storage, relying on the underlying system to do
+++ \spadgloss{garbage collection}. I estimate that the efficiency of this
+++ package at low precisions could be improved by a factor of 2
+++ if in-place operations were available.
+++
+++ Running times: in the following, n is the number of bits of precision
+++ \spad{*}, \spad{/}, \spad{sqrt}, \spad{pi}, \spad{exp1}, \spad{log2}, \spad{log10}: \spad{ O( n**2 )}
+++ \spad{exp}, \spad{log}, \spad{sin}, \spad{atan}: \spad{ O( sqrt(n) n**2 )}
+++ The other elementary functions are coded in terms of the ones above.
+
+
+Float():
+ Join(FloatingPointSystem, DifferentialRing, ConvertibleTo String, OpenMath,_
+ CoercibleTo DoubleFloat, TranscendentalFunctionCategory, ConvertibleTo InputForm) with
+ _/ : (%, I) -> %
+ ++ x / i computes the division from x by an integer i.
+ _*_*: (%, %) -> %
+ ++ x ** y computes \spad{exp(y log x)} where \spad{x >= 0}.
+ normalize: % -> %
+ ++ normalize(x) normalizes x at current precision.
+ relerror : (%, %) -> I
+ ++ relerror(x,y) computes the absolute value of \spad{x - y} divided by
+ ++ y, when \spad{y \^= 0}.
+ shift: (%, I) -> %
+ ++ shift(x,n) adds n to the exponent of float x.
+ rationalApproximation: (%, N) -> RN
+ ++ rationalApproximation(f, n) computes a rational approximation
+ ++ r to f with relative error \spad{< 10**(-n)}.
+ rationalApproximation: (%, N, N) -> RN
+ ++ rationalApproximation(f, n, b) computes a rational
+ ++ approximation r to f with relative error \spad{< b**(-n)}, that is
+ ++ \spad{|(r-f)/f| < b**(-n)}.
+ log2 : () -> %
+ ++ log2() returns \spad{ln 2}, i.e. \spad{0.6931471805...}.
+ log10: () -> %
+ ++ log10() returns \spad{ln 10}: \spad{2.3025809299...}.
+ exp1 : () -> %
+ ++ exp1() returns exp 1: \spad{2.7182818284...}.
+ atan : (%,%) -> %
+ ++ atan(x,y) computes the arc tangent from x with phase y.
+ log2 : % -> %
+ ++ log2(x) computes the logarithm for x to base 2.
+ log10: % -> %
+ ++ log10(x) computes the logarithm for x to base 10.
+ convert: SF -> %
+ ++ convert(x) converts a \spadtype{DoubleFloat} x to a \spadtype{Float}.
+ outputFloating: () -> Void
+ ++ outputFloating() sets the output mode to floating (scientific) notation, i.e.
+ ++ \spad{mantissa * 10 exponent} is displayed as \spad{0.mantissa E exponent}.
+ outputFloating: N -> Void
+ ++ outputFloating(n) sets the output mode to floating (scientific) notation
+ ++ with n significant digits displayed after the decimal point.
+ outputFixed: () -> Void
+ ++ outputFixed() sets the output mode to fixed point notation;
+ ++ the output will contain a decimal point.
+ outputFixed: N -> Void
+ ++ outputFixed(n) sets the output mode to fixed point notation,
+ ++ with n digits displayed after the decimal point.
+ outputGeneral: () -> Void
+ ++ outputGeneral() sets the output mode (default mode) to general
+ ++ notation; numbers will be displayed in either fixed or floating
+ ++ (scientific) notation depending on the magnitude.
+ outputGeneral: N -> Void
+ ++ outputGeneral(n) sets the output mode to general notation
+ ++ with n significant digits displayed.
+ outputSpacing: N -> Void
+ ++ outputSpacing(n) inserts a space after n (default 10) digits on output;
+ ++ outputSpacing(0) means no spaces are inserted.
+ arbitraryPrecision
+ arbitraryExponent
+ == add
+ BASE ==> 2
+ BITS:Reference(PI) := ref 68 -- 20 digits
+ LENGTH ==> INTEGER_-LENGTH$Lisp
+ ISQRT ==> approxSqrt$IntegerRoots(I)
+ Rep := Record( mantissa:I, exponent:I )
+ StoredConstant ==> Record( precision:PI, value:% )
+ UCA ==> Record( unit:%, coef:%, associate:% )
+ inc ==> increasePrecision
+ dec ==> decreasePrecision
+
+ -- local utility operations
+ shift2 : (I,I) -> I -- WSP: fix bug in shift
+ times : (%,%) -> % -- multiply x and y with no rounding
+ itimes: (I,%) -> % -- multiply by a small integer
+ chop: (%,PI) -> % -- chop x at p bits of precision
+ dvide: (%,%) -> % -- divide x by y with no rounding
+ square: (%,I) -> % -- repeated squaring with chopping
+ power: (%,I) -> % -- x ** n with chopping
+ plus: (%,%) -> % -- addition with no rounding
+ sub: (%,%) -> % -- subtraction with no rounding
+ negate: % -> % -- negation with no rounding
+ ceillog10base2: PI -> PI -- rational approximation
+ floorln2: PI -> PI -- rational approximation
+
+ atanSeries: % -> % -- atan(x) by taylor series |x| < 1/2
+ atanInverse: I -> % -- atan(1/n) for n an integer > 1
+ expInverse: I -> % -- exp(1/n) for n an integer
+ expSeries: % -> % -- exp(x) by taylor series |x| < 1/2
+ logSeries: % -> % -- log(x) by taylor series 1/2 < x < 2
+ sinSeries: % -> % -- sin(x) by taylor series |x| < 1/2
+ cosSeries: % -> % -- cos(x) by taylor series |x| < 1/2
+ piRamanujan: () -> % -- pi using Ramanujans series
+
+ writeOMFloat(dev: OpenMathDevice, x: %): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "bigfloat1", "bigfloat")
+ OMputInteger(dev, mantissa x)
+ OMputInteger(dev, 2)
+ OMputInteger(dev, exponent x)
+ OMputEndApp(dev)
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMFloat(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMFloat(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMFloat(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMFloat(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ shift2(x,y) == sign(x)*shift(sign(x)*x,y)
+
+ asin x ==
+ zero? x => 0
+ negative? x => -asin(-x)
+-- one? x => pi()/2
+ (x = 1) => pi()/2
+ x > 1 => error "asin: argument > 1 in magnitude"
+ inc 5; r := atan(x/sqrt(sub(1,times(x,x)))); dec 5
+ normalize r
+
+ acos x ==
+ zero? x => pi()/2
+ negative? x => (inc 3; r := pi()-acos(-x); dec 3; normalize r)
+-- one? x => 0
+ (x = 1) => 0
+ x > 1 => error "acos: argument > 1 in magnitude"
+ inc 5; r := atan(sqrt(sub(1,times(x,x)))/x); dec 5
+ normalize r
+
+ atan(x,y) ==
+ x = 0 =>
+ y > 0 => pi()/2
+ y < 0 => -pi()/2
+ 0
+ -- Only count on first quadrant being on principal branch.
+ theta := atan abs(y/x)
+ if x < 0 then theta := pi() - theta
+ if y < 0 then theta := - theta
+ theta
+
+ atan x ==
+ zero? x => 0
+ negative? x => -atan(-x)
+ if x > 1 then
+ inc 4
+ r := if zero? fractionPart x and x < [bits(),0] then atanInverse wholePart x
+ else atan(1/x)
+ r := pi/2 - r
+ dec 4
+ return normalize r
+ -- make |x| < O( 2**(-sqrt p) ) < 1/2 to speed series convergence
+ -- by using the formula atan(x) = 2*atan(x/(1+sqrt(1+x**2)))
+ k := ISQRT (bits()-100)::I quo 5
+ k := max(0,2 + k + order x)
+ inc(2*k)
+ for i in 1..k repeat x := x/(1+sqrt(1+x*x))
+ t := atanSeries x
+ dec(2*k)
+ t := shift(t,k)
+ normalize t
+
+ atanSeries x ==
+ -- atan(x) = x (1 - x**2/3 + x**4/5 - x**6/7 + ...) |x| < 1
+ p := bits() + LENGTH bits() + 2
+ s:I := d:I := shift(1,p)
+ y := times(x,x)
+ t := m := - shift2(y.mantissa,y.exponent+p)
+ for i in 3.. by 2 while t ^= 0 repeat
+ s := s + t quo i
+ t := (m * t) quo d
+ x * [s,-p]
+
+ atanInverse n ==
+ -- compute atan(1/n) for an integer n > 1
+ -- atan n = 1/n - 1/n**3/3 + 1/n**5/4 - ...
+ -- pi = 16 atan(1/5) - 4 atan(1/239)
+ n2 := -n*n
+ e:I := bits() + LENGTH bits() + LENGTH n + 1
+ s:I := shift(1,e) quo n
+ t:I := s quo n2
+ for k in 3.. by 2 while t ^= 0 repeat
+ s := s + t quo k
+ t := t quo n2
+ normalize [s,-e]
+
+ sin x ==
+ s := sign x; x := abs x; p := bits(); inc 4
+ if x > [6,0] then (inc p; x := 2*pi*fractionPart(x/pi/2); bits p)
+ if x > [3,0] then (inc p; s := -s; x := x - pi; bits p)
+ if x > [3,-1] then (inc p; x := pi - x; dec p)
+ -- make |x| < O( 2**(-sqrt p) ) < 1/2 to speed series convergence
+ -- by using the formula sin(3*x/3) = 3 sin(x/3) - 4 sin(x/3)**3
+ -- the running time is O( sqrt p M(p) ) assuming |x| < 1
+ k := ISQRT (bits()-100)::I quo 4
+ k := max(0,2 + k + order x)
+ if k > 0 then (inc k; x := x / 3**k::N)
+ r := sinSeries x
+ for i in 1..k repeat r := itimes(3,r)-shift(r**3,2)
+ bits p
+ s * r
+
+ sinSeries x ==
+ -- sin(x) = x (1 - x**2/3! + x**4/5! - x**6/7! + ... |x| < 1/2
+ p := bits() + LENGTH bits() + 2
+ y := times(x,x)
+ s:I := d:I := shift(1,p)
+ m:I := - shift2(y.mantissa,y.exponent+p)
+ t:I := m quo 6
+ for i in 4.. by 2 while t ^= 0 repeat
+ s := s + t
+ t := (m * t) quo (i*(i+1))
+ t := t quo d
+ x * [s,-p]
+
+ cos x ==
+ s:I := 1; x := abs x; p := bits(); inc 4
+ if x > [6,0] then (inc p; x := 2*pi*fractionPart(x/pi/2); dec p)
+ if x > [3,0] then (inc p; s := -s; x := x-pi; dec p)
+ if x > [1,0] then
+ -- take care of the accuracy problem near pi/2
+ inc p; x := pi/2-x; bits p; x := normalize x
+ return (s * sin x)
+ -- make |x| < O( 2**(-sqrt p) ) < 1/2 to speed series convergence
+ -- by using the formula cos(2*x/2) = 2 cos(x/2)**2 - 1
+ -- the running time is O( sqrt p M(p) ) assuming |x| < 1
+ k := ISQRT (bits()-100)::I quo 3
+ k := max(0,2 + k + order x)
+ -- need to increase precision by more than k, otherwise recursion
+ -- causes loss of accuracy.
+ -- Michael Monagan suggests adding a factor of log(k)
+ if k > 0 then (inc(k+length(k)**2); x := shift(x,-k))
+ r := cosSeries x
+ for i in 1..k repeat r := shift(r*r,1)-1
+ bits p
+ s * r
+
+
+
+ cosSeries x ==
+ -- cos(x) = 1 - x**2/2! + x**4/4! - x**6/6! + ... |x| < 1/2
+ p := bits() + LENGTH bits() + 1
+ y := times(x,x)
+ s:I := d:I := shift(1,p)
+ m:I := - shift2(y.mantissa,y.exponent+p)
+ t:I := m quo 2
+ for i in 3.. by 2 while t ^= 0 repeat
+ s := s + t
+ t := (m * t) quo (i*(i+1))
+ t := t quo d
+ normalize [s,-p]
+
+ tan x ==
+ s := sign x; x := abs x; p := bits(); inc 6
+ if x > [3,0] then (inc p; x := pi()*fractionPart(x/pi()); dec p)
+ if x > [3,-1] then (inc p; x := pi()-x; s := -s; dec p)
+ if x > 1 then (c := cos x; t := sqrt(1-c*c)/c)
+ else (c := sin x; t := c/sqrt(1-c*c))
+ bits p
+ s * t
+
+ P:StoredConstant := [1,[1,2]]
+ pi() ==
+ -- We use Ramanujan's identity to compute pi.
+ -- The running time is quadratic in the precision.
+ -- This is about twice as fast as Machin's identity on Lisp/VM
+ -- pi = 16 atan(1/5) - 4 atan(1/239)
+ bits() <= P.precision => normalize P.value
+ (P := [bits(), piRamanujan()]) value
+
+ piRamanujan() ==
+ -- Ramanujans identity for 1/pi
+ -- Reference: Shanks and Wrench, Math Comp, 1962
+ -- "Calculation of pi to 100,000 Decimals".
+ n := bits() + LENGTH bits() + 11
+ t:I := shift(1,n) quo 882
+ d:I := 4*882**2
+ s:I := 0
+ for i in 2.. by 2 for j in 1123.. by 21460 while t ^= 0 repeat
+ s := s + j*t
+ m := -(i-1)*(2*i-1)*(2*i-3)
+ t := (m*t) quo (d*i**3)
+ 1 / [s,-n-2]
+
+ sinh x ==
+ zero? x => 0
+ lost:I := max(- order x,0)
+ 2*lost > bits() => x
+ inc(5+lost); e := exp x; s := (e-1/e)/2; dec(5+lost)
+ normalize s
+
+ cosh x ==
+ (inc 5; e := exp x; c := (e+1/e)/2; dec 5; normalize c)
+
+ tanh x ==
+ zero? x => 0
+ lost:I := max(- order x,0)
+ 2*lost > bits() => x
+ inc(6+lost); e := exp x; e := e*e; t := (e-1)/(e+1); dec(6+lost)
+ normalize t
+
+ asinh x ==
+ p := min(0,order x)
+ if zero? x or 2*p < -bits() then return x
+ inc(5-p); r := log(x+sqrt(1+x*x)); dec(5-p)
+ normalize r
+
+ acosh x ==
+ if x < 1 then error "invalid argument to acosh"
+ inc 5; r := log(x+sqrt(sub(times(x,x),1))); dec 5
+ normalize r
+
+ atanh x ==
+ if x > 1 or x < -1 then error "invalid argument to atanh"
+ p := min(0,order x)
+ if zero? x or 2*p < -bits() then return x
+ inc(5-p); r := log((x+1)/(1-x))/2; dec(5-p)
+ normalize r
+
+ log x ==
+ negative? x => error "negative log"
+ zero? x => error "log 0 generated"
+ p := bits(); inc 5
+ -- apply log(x) = n log 2 + log(x/2**n) so that 1/2 < x < 2
+ if (n := order x) < 0 then n := n+1
+ l := if n = 0 then 0 else (x := shift(x,-n); n * log2)
+ -- speed the series convergence by finding m and k such that
+ -- | exp(m/2**k) x - 1 | < 1 / 2 ** O(sqrt p)
+ -- write log(exp(m/2**k) x) as m/2**k + log x
+ k := ISQRT (p-100)::I quo 3
+ if k > 1 then
+ k := max(1,k+order(x-1))
+ inc k
+ ek := expInverse (2**k::N)
+ dec(p quo 2); m := order square(x,k); inc(p quo 2)
+ m := (6847196937 * m) quo 9878417065 -- m := m log 2
+ x := x * ek ** (-m)
+ l := l + [m,-k]
+ l := l + logSeries x
+ bits p
+ normalize l
+
+ logSeries x ==
+ -- log(x) = 2 y (1 + y**2/3 + y**4/5 ...) for y = (x-1) / (x+1)
+ -- given 1/2 < x < 2 on input we have -1/3 < y < 1/3
+ p := bits() + (g := LENGTH bits() + 3)
+ inc g; y := (x-1)/(x+1); dec g
+ s:I := d:I := shift(1,p)
+ z := times(y,y)
+ t := m := shift2(z.mantissa,z.exponent+p)
+ for i in 3.. by 2 while t ^= 0 repeat
+ s := s + t quo i
+ t := m * t quo d
+ y * [s,1-p]
+
+ L2:StoredConstant := [1,1]
+ log2() ==
+ -- log x = 2 * sum( ((x-1)/(x+1))**(2*k+1)/(2*k+1), k=1.. )
+ -- log 2 = 2 * sum( 1/9**k / (2*k+1), k=0..n ) / 3
+ n := bits() :: N
+ n <= L2.precision => normalize L2.value
+ n := n + LENGTH n + 3 -- guard bits
+ s:I := shift(1,n+1) quo 3
+ t:I := s quo 9
+ for k in 3.. by 2 while t ^= 0 repeat
+ s := s + t quo k
+ t := t quo 9
+ L2 := [bits(),[s,-n]]
+ normalize L2.value
+
+ L10:StoredConstant := [1,[1,1]]
+ log10() ==
+ -- log x = 2 * sum( ((x-1)/(x+1))**(2*k+1)/(2*k+1), k=0.. )
+ -- log 5/4 = 2 * sum( 1/81**k / (2*k+1), k=0.. ) / 9
+ n := bits() :: N
+ n <= L10.precision => normalize L10.value
+ n := n + LENGTH n + 5 -- guard bits
+ s:I := shift(1,n+1) quo 9
+ t:I := s quo 81
+ for k in 3.. by 2 while t ^= 0 repeat
+ s := s + t quo k
+ t := t quo 81
+ -- We have log 10 = log 5 + log 2 and log 5/4 = log 5 - 2 log 2
+ inc 2; L10 := [bits(),[s,-n] + 3*log2]; dec 2
+ normalize L10.value
+
+ log2(x) == (inc 2; r := log(x)/log2; dec 2; normalize r)
+ log10(x) == (inc 2; r := log(x)/log10; dec 2; normalize r)
+
+ exp(x) ==
+ -- exp(n+x) = exp(1)**n exp(x) for n such that |x| < 1
+ p := bits(); inc 5; e1:% := 1
+ if (n := wholePart x) ^= 0 then
+ inc LENGTH n; e1 := exp1 ** n; dec LENGTH n
+ x := fractionPart x
+ if zero? x then (bits p; return normalize e1)
+ -- make |x| < O( 2**(-sqrt p) ) < 1/2 to speed series convergence
+ -- by repeated use of the formula exp(2*x/2) = exp(x/2)**2
+ -- results in an overall running time of O( sqrt p M(p) )
+ k := ISQRT (p-100)::I quo 3
+ k := max(0,2 + k + order x)
+ if k > 0 then (inc k; x := shift(x,-k))
+ e := expSeries x
+ if k > 0 then e := square(e,k)
+ bits p
+ e * e1
+
+ expSeries x ==
+ -- exp(x) = 1 + x + x**2/2 + ... + x**i/i! valid for all x
+ p := bits() + LENGTH bits() + 1
+ s:I := d:I := shift(1,p)
+ t:I := n:I := shift2(x.mantissa,x.exponent+p)
+ for i in 2.. while t ^= 0 repeat
+ s := s + t
+ t := (n * t) quo i
+ t := t quo d
+ normalize [s,-p]
+
+ expInverse k ==
+ -- computes exp(1/k) via continued fraction
+ p0:I := 2*k+1; p1:I := 6*k*p0+1
+ q0:I := 2*k-1; q1:I := 6*k*q0+1
+ for i in 10*k.. by 4*k while 2 * LENGTH p0 < bits() repeat
+ (p0,p1) := (p1,i*p1+p0)
+ (q0,q1) := (q1,i*q1+q0)
+ dvide([p1,0],[q1,0])
+
+ E:StoredConstant := [1,[1,1]]
+ exp1() ==
+ if bits() > E.precision then E := [bits(),expInverse 1]
+ normalize E.value
+
+ sqrt x ==
+ negative? x => error "negative sqrt"
+ m := x.mantissa; e := x.exponent
+ l := LENGTH m
+ p := 2 * bits() - l + 2
+ if odd?(e-l) then p := p - 1
+ i := shift2(x.mantissa,p)
+ -- ISQRT uses a variable precision newton iteration
+ i := ISQRT i
+ normalize [i,(e-p) quo 2]
+
+ bits() == BITS()
+ bits(n) == (t := bits(); BITS() := n; t)
+ precision() == bits()
+ precision(n) == bits(n)
+ increasePrecision n == (b := bits(); bits((b + n)::PI); b)
+ decreasePrecision n == (b := bits(); bits((b - n)::PI); b)
+ ceillog10base2 n == ((13301 * n + 4003) quo 4004) :: PI
+ digits() == max(1,4004 * (bits()-1) quo 13301)::PI
+ digits(n) == (t := digits(); bits (1 + ceillog10base2 n); t)
+
+ order(a) == LENGTH a.mantissa + a.exponent - 1
+ relerror(a,b) == order((a-b)/b)
+ 0 == [0,0]
+ 1 == [1,0]
+ base() == BASE
+ mantissa x == x.mantissa
+ exponent x == x.exponent
+ one? a == a = 1
+ zero? a == zero?(a.mantissa)
+ negative? a == negative?(a.mantissa)
+ positive? a == positive?(a.mantissa)
+
+ chop(x,p) ==
+ e : I := LENGTH x.mantissa - p
+ if e > 0 then x := [shift2(x.mantissa,-e),x.exponent+e]
+ x
+ float(m,e) == normalize [m,e]
+ float(m,e,b) ==
+ m = 0 => 0
+ inc 4; r := m * [b,0] ** e; dec 4
+ normalize r
+ normalize x ==
+ m := x.mantissa
+ m = 0 => 0
+ e : I := LENGTH m - bits()
+ if e > 0 then
+ y := shift2(m,1-e)
+ if odd? y then
+ y := (if y>0 then y+1 else y-1) quo 2
+ if LENGTH y > bits() then
+ y := y quo 2
+ e := e+1
+ else y := y quo 2
+ x := [y,x.exponent+e]
+ x
+ shift(x:%,n:I) == [x.mantissa,x.exponent+n]
+
+ x = y ==
+ order x = order y and sign x = sign y and zero? (x - y)
+ x < y ==
+ y.mantissa = 0 => x.mantissa < 0
+ x.mantissa = 0 => y.mantissa > 0
+ negative? x and positive? y => true
+ negative? y and positive? x => false
+ order x < order y => positive? x
+ order x > order y => negative? x
+ negative? (x-y)
+
+ abs x == if negative? x then -x else normalize x
+ ceiling x ==
+ if negative? x then return (-floor(-x))
+ if zero? fractionPart x then x else truncate x + 1
+ wholePart x == shift2(x.mantissa,x.exponent)
+ floor x == if negative? x then -ceiling(-x) else truncate x
+ round x == (half := [sign x,-1]; truncate(x + half))
+ sign x == if x.mantissa < 0 then -1 else 1
+ truncate x ==
+ if x.exponent >= 0 then return x
+ normalize [shift2(x.mantissa,x.exponent),0]
+ recip(x) == if x=0 then "failed" else 1/x
+ differentiate x == 0
+
+ - x == normalize negate x
+ negate x == [-x.mantissa,x.exponent]
+ x + y == normalize plus(x,y)
+ x - y == normalize plus(x,negate y)
+ sub(x,y) == plus(x,negate y)
+ plus(x,y) ==
+ mx := x.mantissa; my := y.mantissa
+ mx = 0 => y
+ my = 0 => x
+ ex := x.exponent; ey := y.exponent
+ ex = ey => [mx+my,ex]
+ de := ex + LENGTH mx - ey - LENGTH my
+ de > bits()+1 => x
+ de < -(bits()+1) => y
+ if ex < ey then (mx,my,ex,ey) := (my,mx,ey,ex)
+ mw := my + shift2(mx,ex-ey)
+ [mw,ey]
+
+ x:% * y:% == normalize times (x,y)
+ x:I * y:% ==
+ if LENGTH x > bits() then normalize [x,0] * y
+ else normalize [x * y.mantissa,y.exponent]
+ x:% / y:% == normalize dvide(x,y)
+ x:% / y:I ==
+ if LENGTH y > bits() then x / normalize [y,0] else x / [y,0]
+ inv x == 1 / x
+
+ times(x:%,y:%) == [x.mantissa * y.mantissa, x.exponent + y.exponent]
+ itimes(n:I,y:%) == [n * y.mantissa,y.exponent]
+
+ dvide(x,y) ==
+ ew := LENGTH y.mantissa - LENGTH x.mantissa + bits() + 1
+ mw := shift2(x.mantissa,ew) quo y.mantissa
+ ew := x.exponent - y.exponent - ew
+ [mw,ew]
+
+ square(x,n) ==
+ ma := x.mantissa; ex := x.exponent
+ for k in 1..n repeat
+ ma := ma * ma; ex := ex + ex
+ l:I := bits()::I - LENGTH ma
+ ma := shift2(ma,l); ex := ex - l
+ [ma,ex]
+
+ power(x,n) ==
+ y:% := 1; z:% := x
+ repeat
+ if odd? n then y := chop( times(y,z), bits() )
+ if (n := n quo 2) = 0 then return y
+ z := chop( times(z,z), bits() )
+
+ x:% ** y:% ==
+ x = 0 =>
+ y = 0 => error "0**0 is undefined"
+ y < 0 => error "division by 0"
+ y > 0 => 0
+ y = 0 => 1
+ y = 1 => x
+ x = 1 => 1
+ p := abs order y + 5
+ inc p; r := exp(y*log(x)); dec p
+ normalize r
+
+ x:% ** r:RN ==
+ x = 0 =>
+ r = 0 => error "0**0 is undefined"
+ r < 0 => error "division by 0"
+ r > 0 => 0
+ r = 0 => 1
+ r = 1 => x
+ x = 1 => 1
+ n := numer r
+ d := denom r
+ negative? x =>
+ odd? d =>
+ odd? n => return -((-x)**r)
+ return ((-x)**r)
+ error "negative root"
+ if d = 2 then
+ inc LENGTH n; y := sqrt(x); y := y**n; dec LENGTH n
+ return normalize y
+ y := [n,0]/[d,0]
+ x ** y
+
+ x:% ** n:I ==
+ x = 0 =>
+ n = 0 => error "0**0 is undefined"
+ n < 0 => error "division by 0"
+ n > 0 => 0
+ n = 0 => 1
+ n = 1 => x
+ x = 1 => 1
+ p := bits()
+ bits(p + LENGTH n + 2)
+ y := power(x,abs n)
+ if n < 0 then y := dvide(1,y)
+ bits p
+ normalize y
+
+ -- Utility routines for conversion to decimal
+ ceilLength10: I -> I
+ chop10: (%,I) -> %
+ convert10:(%,I) -> %
+ floorLength10: I -> I
+ length10: I -> I
+ normalize10: (%,I) -> %
+ quotient10: (%,%,I) -> %
+ power10: (%,I,I) -> %
+ times10: (%,%,I) -> %
+
+ convert10(x,d) ==
+ m := x.mantissa; e := x.exponent
+ --!! deal with bits here
+ b := bits(); (q,r) := divide(abs e, b)
+ b := 2**b::N; r := 2**r::N
+ -- compute 2**e = b**q * r
+ h := power10([b,0],q,d+5)
+ h := chop10([r*h.mantissa,h.exponent],d+5)
+ if e < 0 then h := quotient10([m,0],h,d)
+ else times10([m,0],h,d)
+
+ ceilLength10 n == 146 * LENGTH n quo 485 + 1
+ floorLength10 n == 643 * LENGTH n quo 2136
+-- length10 n == DECIMAL_-LENGTH(n)$Lisp
+ length10 n ==
+ ln := LENGTH(n:=abs n)
+ upper := 76573 * ln quo 254370
+ lower := 21306 * (ln-1) quo 70777
+ upper = lower => upper + 1
+ n := n quo (10**lower::N)
+ while n >= 10 repeat
+ n:= n quo 10
+ lower := lower + 1
+ lower + 1
+
+ chop10(x,p) ==
+ e : I := floorLength10 x.mantissa - p
+ if e > 0 then x := [x.mantissa quo 10**e::N,x.exponent+e]
+ x
+ normalize10(x,p) ==
+ ma := x.mantissa
+ ex := x.exponent
+ e : I := length10 ma - p
+ if e > 0 then
+ ma := ma quo 10**(e-1)::N
+ ex := ex + e
+ (ma,r) := divide(ma, 10)
+ if r > 4 then
+ ma := ma + 1
+ if ma = 10**p::N then (ma := 1; ex := ex + p)
+ [ma,ex]
+ times10(x,y,p) == normalize10(times(x,y),p)
+ quotient10(x,y,p) ==
+ ew := floorLength10 y.mantissa - ceilLength10 x.mantissa + p + 2
+ if ew < 0 then ew := 0
+ mw := (x.mantissa * 10**ew::N) quo y.mantissa
+ ew := x.exponent - y.exponent - ew
+ normalize10([mw,ew],p)
+ power10(x,n,d) ==
+ x = 0 => 0
+ n = 0 => 1
+ n = 1 => x
+ x = 1 => 1
+ p:I := d + LENGTH n + 1
+ e:I := n
+ y:% := 1
+ z:% := x
+ repeat
+ if odd? e then y := chop10(times(y,z),p)
+ if (e := e quo 2) = 0 then return y
+ z := chop10(times(z,z),p)
+
+ --------------------------------
+ -- Output routines for Floats --
+ --------------------------------
+ zero ==> char("0")
+ separator ==> space()$Character
+
+ SPACING : Reference(N) := ref 10
+ OUTMODE : Reference(S) := ref "general"
+ OUTPREC : Reference(I) := ref(-1)
+
+ fixed : % -> S
+ floating : % -> S
+ general : % -> S
+
+ padFromLeft(s:S):S ==
+ zero? SPACING() => s
+ n:I := #s - 1
+ t := new( (n + 1 + n quo SPACING()) :: N , separator )
+ for i in 0..n for j in minIndex t .. repeat
+ t.j := s.(i + minIndex s)
+ if (i+1) rem SPACING() = 0 then j := j+1
+ t
+ padFromRight(s:S):S ==
+ SPACING() = 0 => s
+ n:I := #s - 1
+ t := new( (n + 1 + n quo SPACING()) :: N , separator )
+ for i in n..0 by -1 for j in maxIndex t .. by -1 repeat
+ t.j := s.(i + minIndex s)
+ if (n-i+1) rem SPACING() = 0 then j := j-1
+ t
+
+ fixed f ==
+ zero? f => "0.0"
+ zero? exponent f =>
+ padFromRight concat(convert(mantissa f)@S, ".0")
+ negative? f => concat("-", fixed abs f)
+ d := if OUTPREC() = -1 then digits::I else OUTPREC()
+-- g := convert10(abs f,digits); m := g.mantissa; e := g.exponent
+ g := convert10(abs f,d); m := g.mantissa; e := g.exponent
+ if OUTPREC() ^= -1 then
+ -- round g to OUTPREC digits after the decimal point
+ l := length10 m
+ if -e > OUTPREC() and -e < 2*digits::I then
+ g := normalize10(g,l+e+OUTPREC())
+ m := g.mantissa; e := g.exponent
+ s := convert(m)@S; n := #s; o := e+n
+ p := if OUTPREC() = -1 then n::I else OUTPREC()
+ t:S
+ if e >= 0 then
+ s := concat(s, new(e::N, zero))
+ t := ""
+ else if o <= 0 then
+ t := concat(new((-o)::N,zero), s)
+ s := "0"
+ else
+ t := s(o + minIndex s .. n + minIndex s - 1)
+ s := s(minIndex s .. o + minIndex s - 1)
+ n := #t
+ if OUTPREC() = -1 then
+ t := rightTrim(t,zero)
+ if t = "" then t := "0"
+ else if n > p then t := t(minIndex t .. p + minIndex t- 1)
+ else t := concat(t, new((p-n)::N,zero))
+ concat(padFromRight s, concat(".", padFromLeft t))
+
+ floating f ==
+ zero? f => "0.0"
+ negative? f => concat("-", floating abs f)
+ t:S := if zero? SPACING() then "E" else " E "
+ zero? exponent f =>
+ s := convert(mantissa f)@S
+ concat ["0.", padFromLeft s, t, convert(#s)@S]
+ -- base conversion to decimal rounded to the requested precision
+ d := if OUTPREC() = -1 then digits::I else OUTPREC()
+ g := convert10(f,d); m := g.mantissa; e := g.exponent
+ -- I'm assuming that length10 m = # s given n > 0
+ s := convert(m)@S; n := #s; o := e+n
+ s := padFromLeft s
+ concat ["0.", s, t, convert(o)@S]
+
+ general(f) ==
+ zero? f => "0.0"
+ negative? f => concat("-", general abs f)
+ d := if OUTPREC() = -1 then digits::I else OUTPREC()
+ zero? exponent f =>
+ d := d + 1
+ s := convert(mantissa f)@S
+ OUTPREC() ^= -1 and (e := #s) > d =>
+ t:S := if zero? SPACING() then "E" else " E "
+ concat ["0.", padFromLeft s, t, convert(e)@S]
+ padFromRight concat(s, ".0")
+ -- base conversion to decimal rounded to the requested precision
+ g := convert10(f,d); m := g.mantissa; e := g.exponent
+ -- I'm assuming that length10 m = # s given n > 0
+ s := convert(m)@S; n := #s; o := n + e
+ -- Note: at least one digit is displayed after the decimal point
+ -- and trailing zeroes after the decimal point are dropped
+ if o > 0 and o <= max(n,d) then
+ -- fixed format: add trailing zeroes before the decimal point
+ if o > n then s := concat(s, new((o-n)::N,zero))
+ t := rightTrim(s(o + minIndex s .. n + minIndex s - 1), zero)
+ if t = "" then t := "0" else t := padFromLeft t
+ s := padFromRight s(minIndex s .. o + minIndex s - 1)
+ concat(s, concat(".", t))
+ else if o <= 0 and o >= -5 then
+ -- fixed format: up to 5 leading zeroes after the decimal point
+ concat("0.",padFromLeft concat(new((-o)::N,zero),rightTrim(s,zero)))
+ else
+ -- print using E format written 0.mantissa E exponent
+ t := padFromLeft rightTrim(s,zero)
+ s := if zero? SPACING() then "E" else " E "
+ concat ["0.", t, s, convert(e+n)@S]
+
+ outputSpacing n == SPACING() := n
+ outputFixed() == (OUTMODE() := "fixed"; OUTPREC() := -1)
+ outputFixed n == (OUTMODE() := "fixed"; OUTPREC() := n::I)
+ outputGeneral() == (OUTMODE() := "general"; OUTPREC() := -1)
+ outputGeneral n == (OUTMODE() := "general"; OUTPREC() := n::I)
+ outputFloating() == (OUTMODE() := "floating"; OUTPREC() := -1)
+ outputFloating n == (OUTMODE() := "floating"; OUTPREC() := n::I)
+
+ convert(f):S ==
+ b:Integer :=
+ OUTPREC() = -1 and not zero? f =>
+ bits(length(abs mantissa f)::PositiveInteger)
+ 0
+ s :=
+ OUTMODE() = "fixed" => fixed f
+ OUTMODE() = "floating" => floating f
+ OUTMODE() = "general" => general f
+ empty()$String
+ if b > 0 then bits(b::PositiveInteger)
+ s = empty()$String => error "bad output mode"
+ s
+
+ coerce(f):OutputForm ==
+ f >= 0 => message(convert(f)@S)
+ - (coerce(-f)@OutputForm)
+
+ convert(f):InputForm ==
+ convert [convert("float"::Symbol), convert mantissa f,
+ convert exponent f, convert base()]$List(InputForm)
+
+ -- Conversion routines
+ convert(x:%):Float == x pretend Float
+ convert(x:%):SF == makeSF(x.mantissa,x.exponent)$Lisp
+ coerce(x:%):SF == convert(x)@SF
+ convert(sf:SF):% == float(mantissa sf,exponent sf,base()$SF)
+
+ retract(f:%):RN == rationalApproximation(f,(bits()-1)::N,BASE)
+
+ retractIfCan(f:%):Union(RN, "failed") ==
+ rationalApproximation(f,(bits()-1)::N,BASE)
+
+ retract(f:%):I ==
+ (f = (n := wholePart f)::%) => n
+ error "Not an integer"
+
+ retractIfCan(f:%):Union(I, "failed") ==
+ (f = (n := wholePart f)::%) => n
+ "failed"
+
+ rationalApproximation(f,d) == rationalApproximation(f,d,10)
+
+ rationalApproximation(f,d,b) ==
+ t: Integer
+ nu := f.mantissa; ex := f.exponent
+ if ex >= 0 then return ((nu*BASE**(ex::N))/1)
+ de := BASE**((-ex)::N)
+ if b < 2 then error "base must be > 1"
+ tol := b**d
+ s := nu; t := de
+ p0,p1,q0,q1 : Integer
+ p0 := 0; p1 := 1; q0 := 1; q1 := 0
+ repeat
+ (q,r) := divide(s, t)
+ p2 := q*p1+p0
+ q2 := q*q1+q0
+ if r = 0 or tol*abs(nu*q2-de*p2) < de*abs(p2) then return (p2/q2)
+ (p0,p1) := (p1,p2)
+ (q0,q1) := (q1,q2)
+ (s,t) := (t,r)
+
+@
+
+--% Float: arbitrary precision floating point arithmetic domain
+
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FLOAT Float>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fmod.spad.pamphlet b/src/algebra/fmod.spad.pamphlet
new file mode 100644
index 00000000..57e6f206
--- /dev/null
+++ b/src/algebra/fmod.spad.pamphlet
@@ -0,0 +1,143 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fmod.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ZMOD IntegerMod}
+<<domain ZMOD IntegerMod>>=
+)abbrev domain ZMOD IntegerMod
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ IntegerMod(n) creates the ring of integers reduced modulo the integer
+++ n.
+
+IntegerMod(p:PositiveInteger):
+ Join(CommutativeRing, Finite, ConvertibleTo Integer, StepThrough) == add
+ size() == p
+ characteristic() == p
+ lookup x == (zero? x => p; (convert(x)@Integer) :: PositiveInteger)
+
+-- Code is duplicated for the optimizer to kick in.
+ if p <= convert(max()$SingleInteger)@Integer then
+ Rep:= SingleInteger
+ q := p::SingleInteger
+
+ bloodyCompiler: Integer -> %
+ bloodyCompiler n == positiveRemainder(n, p)$Integer :: Rep
+
+ convert(x:%):Integer == convert(x)$Rep
+ coerce(x):OutputForm == coerce(x)$Rep
+ coerce(n:Integer):% == bloodyCompiler n
+ 0 == 0$Rep
+ 1 == 1$Rep
+ init == 0$Rep
+ nextItem(n) ==
+ m:=n+1
+ m=0 => "failed"
+ m
+ x = y == x =$Rep y
+ x:% * y:% == mulmod(x, y, q)
+ n:Integer * x:% == mulmod(bloodyCompiler n, x, q)
+ x + y == addmod(x, y, q)
+ x - y == submod(x, y, q)
+ random() == random(q)$Rep
+ index a == positiveRemainder(a::%, q)
+ - x == (zero? x => 0; q -$Rep x)
+
+ x:% ** n:NonNegativeInteger ==
+ n < p => powmod(x, n::Rep, q)
+ powmod(convert(x)@Integer, n, p)$Integer :: Rep
+
+ recip x ==
+ (c1, c2, g) := extendedEuclidean(x, q)$Rep
+-- not one? g => "failed"
+ not (g = 1) => "failed"
+ positiveRemainder(c1, q)
+
+ else
+ Rep:= Integer
+
+ convert(x:%):Integer == convert(x)$Rep
+ coerce(n:Integer):% == positiveRemainder(n::Rep, p)
+ coerce(x):OutputForm == coerce(x)$Rep
+ 0 == 0$Rep
+ 1 == 1$Rep
+ init == 0$Rep
+ nextItem(n) ==
+ m:=n+1
+ m=0 => "failed"
+ m
+ x = y == x =$Rep y
+ x:% * y:% == mulmod(x, y, p)
+ n:Integer * x:% == mulmod(positiveRemainder(n::Rep, p), x, p)
+ x + y == addmod(x, y, p)
+ x - y == submod(x, y, p)
+ random() == random(p)$Rep
+ index a == positiveRemainder(a::Rep, p)
+ - x == (zero? x => 0; p -$Rep x)
+ x:% ** n:NonNegativeInteger == powmod(x, n::Rep, p)
+
+ recip x ==
+ (c1, c2, g) := extendedEuclidean(x, p)$Rep
+-- not one? g => "failed"
+ not (g = 1) => "failed"
+ positiveRemainder(c1, p)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ZMOD IntegerMod>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fname.spad.pamphlet b/src/algebra/fname.spad.pamphlet
new file mode 100644
index 00000000..1a66d427
--- /dev/null
+++ b/src/algebra/fname.spad.pamphlet
@@ -0,0 +1,148 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fname.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category FNCAT FileNameCategory}
+<<category FNCAT FileNameCategory>>=
+)abbrev category FNCAT FileNameCategory
+++ Author: Stephen M. Watt
+++ Date Created: 1985
+++ Date Last Updated: June 20, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This category provides an interface to names in the file system.
+
+FileNameCategory(): Category == SetCategory with
+
+ coerce: String -> %
+ ++ coerce(s) converts a string to a file name
+ ++ according to operating system-dependent conventions.
+ coerce: % -> String
+ ++ coerce(fn) produces a string for a file name
+ ++ according to operating system-dependent conventions.
+
+ filename: (String, String, String) -> %
+ ++ filename(d,n,e) creates a file name with
+ ++ d as its directory, n as its name and e as its extension.
+ ++ This is a portable way to create file names.
+ ++ When d or t is the empty string, a default is used.
+
+ directory: % -> String
+ ++ directory(f) returns the directory part of the file name.
+ name: % -> String
+ ++ name(f) returns the name part of the file name.
+ extension: % -> String
+ ++ extension(f) returns the type part of the file name.
+
+ exists?: % -> Boolean
+ ++ exists?(f) tests if the file exists in the file system.
+ readable?: % -> Boolean
+ ++ readable?(f) tests if the named file exist and can it be opened
+ ++ for reading.
+ writable?: % -> Boolean
+ ++ writable?(f) tests if the named file be opened for writing.
+ ++ The named file need not already exist.
+
+ new: (String, String, String) -> %
+ ++ new(d,pref,e) constructs the name of a new writable file with
+ ++ d as its directory, pref as a prefix of its name and
+ ++ e as its extension.
+ ++ When d or t is the empty string, a default is used.
+ ++ An error occurs if a new file cannot be written in the given
+ ++ directory.
+
+@
+\section{domain FNAME FileName}
+<<domain FNAME FileName>>=
+)abbrev domain FNAME FileName
+++ Author: Stephen M. Watt
+++ Date Created: 1985
+++ Date Last Updated: June 20, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides an interface to names in the file system.
+
+FileName(): FileNameCategory == add
+
+ f1 = f2 == EQUAL(f1, f2)$Lisp
+ coerce(f: %): OutputForm == f::String::OutputForm
+
+ coerce(f: %): String == NAMESTRING(f)$Lisp
+ coerce(s: String): % == PARSE_-NAMESTRING(s)$Lisp
+
+ filename(d,n,e) == fnameMake(d,n,e)$Lisp
+
+ directory(f:%): String == fnameDirectory(f)$Lisp
+ name(f:%): String == fnameName(f)$Lisp
+ extension(f:%): String == fnameType(f)$Lisp
+
+ exists? f == fnameExists?(f)$Lisp
+ readable? f == fnameReadable?(f)$Lisp
+ writable? f == fnameWritable?(f)$Lisp
+
+ new(d,pref,e) == fnameNew(d,pref,e)$Lisp
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category FNCAT FileNameCategory>>
+<<domain FNAME FileName>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fnla.spad.pamphlet b/src/algebra/fnla.spad.pamphlet
new file mode 100644
index 00000000..e56534e4
--- /dev/null
+++ b/src/algebra/fnla.spad.pamphlet
@@ -0,0 +1,344 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fnla.spad}
+\author{Larry Lambe}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain OSI OrdSetInts}
+<<domain OSI OrdSetInts>>=
+)abbrev domain OSI OrdSetInts
+++ Author : Larry Lambe
+++ Date created : 14 August 1988
+++ Date Last Updated : 11 March 1991
+++ Description : A domain used in order to take the free R-module on the
+++ Integers I. This is actually the forgetful functor from OrderedRings
+++ to OrderedSets applied to I
+OrdSetInts: Export == Implement where
+ I ==> Integer
+ L ==> List
+ O ==> OutputForm
+
+ Export == OrderedSet with
+ coerce : Integer -> %
+ ++ coerce(i) returns the element corresponding to i
+ value : % -> I
+ ++ value(x) returns the integer associated with x
+
+ Implement == add
+ Rep := Integer
+ x,y: %
+
+ x = y == x =$Rep y
+ x < y == x <$Rep y
+
+ coerce(i:Integer):% == i
+
+ value(x) == x:Rep
+
+ coerce(x):O ==
+ sub(e::Symbol::O, coerce(x)$Rep)$O
+
+@
+\section{domain COMM Commutator}
+<<domain COMM Commutator>>=
+)abbrev domain COMM Commutator
+++ Author : Larry Lambe
+++ Date created: 30 June 1988.
+++ Updated : 10 March 1991
+++ Description: A type for basic commutators
+Commutator: Export == Implement where
+ I ==> Integer
+ OSI ==> OrdSetInts
+ O ==> OutputForm
+
+ Export == SetCategory with
+ mkcomm : I -> %
+ ++ mkcomm(i) \undocumented{}
+ mkcomm : (%,%) -> %
+ ++ mkcomm(i,j) \undocumented{}
+
+ Implement == add
+ P := Record(left:%,right:%)
+ Rep := Union(OSI,P)
+ x,y: %
+ i : I
+
+ x = y ==
+ (x case OSI) and (y case OSI) => x::OSI = y::OSI
+ (x case P) and (y case P) =>
+ xx:P := x::P
+ yy:P := y::P
+ (xx.right = yy.right) and (xx.left = yy.left)
+ false
+
+ mkcomm(i) == i::OSI
+ mkcomm(x,y) == construct(x,y)$P
+
+ coerce(x: %): O ==
+ x case OSI => x::OSI::O
+ xx := x::P
+ bracket([xx.left::O,xx.right::O])$O
+
+@
+\section{package HB HallBasis}
+<<package HB HallBasis>>=
+)abbrev package HB HallBasis
+++ Author : Larry Lambe
+++ Date Created : August 1988
+++ Date Last Updated : March 9 1990
+++ Related Constructors: OrderedSetInts, Commutator, FreeNilpotentLie
+++ AMS Classification: Primary 17B05, 17B30; Secondary 17A50
+++ Keywords: free Lie algebra, Hall basis, basic commutators
+++ Description : Generate a basis for the free Lie algebra on n
+++ generators over a ring R with identity up to basic commutators
+++ of length c using the algorithm of P. Hall as given in Serre's
+++ book Lie Groups -- Lie Algebras
+
+HallBasis() : Export == Implement where
+ B ==> Boolean
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ VI ==> Vector Integer
+ VLI ==> Vector List Integer
+
+ Export ==> with
+ lfunc : (I,I) -> I
+ ++ lfunc(d,n) computes the rank of the nth factor in the
+ ++ lower central series of the free d-generated free Lie
+ ++ algebra; This rank is d if n = 1 and binom(d,2) if
+ ++ n = 2
+ inHallBasis? : (I,I,I,I) -> B
+ ++ inHallBasis?(numberOfGens, leftCandidate, rightCandidate, left)
+ ++ tests to see if a new element should be added to the P. Hall
+ ++ basis being constructed.
+ ++ The list \spad{[leftCandidate,wt,rightCandidate]}
+ ++ is included in the basis if in the unique factorization of
+ ++ rightCandidate, we have left factor leftOfRight, and
+ ++ leftOfRight <= leftCandidate
+ generate : (NNI,NNI) -> VLI
+ ++ generate(numberOfGens, maximalWeight) generates a vector of
+ ++ elements of the form [left,weight,right] which represents a
+ ++ P. Hall basis element for the free lie algebra on numberOfGens
+ ++ generators. We only generate those basis elements of weight
+ ++ less than or equal to maximalWeight
+
+ Implement ==> add
+
+ lfunc(d,n) ==
+ n < 0 => 0
+ n = 0 => 1
+ n = 1 => d
+ sum:I := 0
+ m:I
+ for m in 1..(n-1) repeat
+ if n rem m = 0 then
+ sum := sum + m * lfunc(d,m)
+ res := (d**(n::NNI) - sum) quo n
+
+ inHallBasis?(n,i,j,l) ==
+ i >= j => false
+ j <= n => true
+ l <= i => true
+ false
+
+ generate(n:NNI,c:NNI) ==
+ gens:=n
+ maxweight:=c
+ siz:I := 0
+ for i in 1 .. maxweight repeat siz := siz + lfunc(gens,i)
+ v:VLI:= new(siz::NNI,[])
+ for i in 1..gens repeat v(i) := [0, 1, i]
+ firstindex:VI := new(maxweight::NNI,0)
+ wt:I := 1
+ firstindex(1) := 1
+ numComms:I := gens
+ newNumComms:I := numComms
+ done:B := false
+ while not done repeat
+ wt := wt + 1
+ if wt > maxweight then done := true
+ else
+ firstindex(wt) := newNumComms + 1
+ leftIndex := 1
+ -- cW == complimentaryWeight
+ cW:I := wt - 1
+ while (leftIndex <= numComms) and (v(leftIndex).2 <= cW) repeat
+ for rightIndex in firstindex(cW)..(firstindex(cW+1) - 1) repeat
+ if inHallBasis?(gens,leftIndex,rightIndex,v(rightIndex).1) then
+ newNumComms := newNumComms + 1
+ v(newNumComms) := [leftIndex,wt,rightIndex]
+ leftIndex := leftIndex + 1
+ cW := wt - v(leftIndex).2
+ numComms := newNumComms
+ v
+
+@
+\section{domain FNLA FreeNilpotentLie}
+<<domain FNLA FreeNilpotentLie>>=
+)abbrev domain FNLA FreeNilpotentLie
+++ Author: Larry Lambe
+++ Date Created: July 1988
+++ Date Last Updated: March 13 1991
+++ Related Constructors: OrderedSetInts, Commutator
+++ AMS Classification: Primary 17B05, 17B30; Secondary 17A50
+++ Keywords: free Lie algebra, Hall basis, basic commutators
+++ Related Constructors: HallBasis, FreeMod, Commutator, OrdSetInts
+++ Description: Generate the Free Lie Algebra over a ring R with identity;
+++ A P. Hall basis is generated by a package call to HallBasis.
+
+FreeNilpotentLie(n:NNI,class:NNI,R: CommutativeRing): Export == Implement where
+ B ==> Boolean
+ Com ==> Commutator
+ HB ==> HallBasis
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ O ==> OutputForm
+ OSI ==> OrdSetInts
+ FM ==> FreeModule(R,OSI)
+ VI ==> Vector Integer
+ VLI ==> Vector List Integer
+ lC ==> leadingCoefficient
+ lS ==> leadingSupport
+
+ Export ==> NonAssociativeAlgebra(R) with
+ dimension : () -> NNI
+ ++ dimension() is the rank of this Lie algebra
+ deepExpand : % -> O
+ ++ deepExpand(x) \undocumented{}
+ shallowExpand : % -> O
+ ++ shallowExpand(x) \undocumented{}
+ generator : NNI -> %
+ ++ generator(i) is the ith Hall Basis element
+
+ Implement ==> FM add
+ Rep := FM
+ f,g : %
+
+ coms:VLI
+ coms := generate(n,class)$HB
+
+ dimension == #coms
+
+ have : (I,I) -> %
+ -- have(left,right) is a lookup function for basic commutators
+ -- already generated; if the nth basic commutator is
+ -- [left,wt,right], then have(left,right) = n
+ have(i,j) ==
+ wt:I := coms(i).2 + coms(j).2
+ wt > class => 0
+ lo:I := 1
+ hi:I := dimension
+ while hi-lo > 1 repeat
+ mid:I := (hi+lo) quo 2
+ if coms(mid).2 < wt then lo := mid else hi := mid
+ while coms(hi).1 < i repeat hi := hi + 1
+ while coms(hi).3 < j repeat hi := hi + 1
+ monomial(1,hi::OSI)$FM
+
+ generator(i) ==
+ i > dimension => 0$Rep
+ monomial(1,i::OSI)$FM
+
+ putIn : I -> %
+ putIn(i) ==
+ monomial(1$R,i::OSI)$FM
+
+ brkt : (I,%) -> %
+ brkt(k,f) ==
+ f = 0 => 0
+ dg:I := value lS f
+ reductum(f) = 0 =>
+ k = dg => 0
+ k > dg => -lC(f)*brkt(dg, putIn(k))
+ inHallBasis?(n,k,dg,coms(dg).1) => lC(f)*have(k, dg)
+ lC(f)*( brkt(coms(dg).1, _
+ brkt(k,putIn coms(dg).3)) - brkt(coms(dg).3, _
+ brkt(k,putIn coms(dg).1) ))
+ brkt(k,monomial(lC f,lS f)$FM)+brkt(k,reductum f)
+
+ f*g ==
+ reductum(f) = 0 =>
+ lC(f)*brkt(value(lS f),g)
+ monomial(lC f,lS f)$FM*g + reductum(f)*g
+
+ Fac : I -> Com
+ -- an auxilliary function used for output of Free Lie algebra
+ -- elements (see expand)
+ Fac(m) ==
+ coms(m).1 = 0 => mkcomm(m)$Com
+ mkcomm(Fac coms(m).1, Fac coms(m).3)
+
+ shallowE : (R,OSI) -> O
+ shallowE(r,s) ==
+ k := value s
+ r = 1 =>
+ k <= n => s::O
+ mkcomm(mkcomm(coms(k).1)$Com,mkcomm(coms(k).3)$Com)$Com::O
+ k <= n => r::O * s::O
+ r::O * mkcomm(mkcomm(coms(k).1)$Com,mkcomm(coms(k).3)$Com)$Com::O
+
+ shallowExpand(f) ==
+ f = 0 => 0::O
+ reductum(f) = 0 => shallowE(lC f,lS f)
+ shallowE(lC f,lS f) + shallowExpand(reductum f)
+
+ deepExpand(f) ==
+ f = 0 => 0::O
+ reductum(f) = 0 =>
+ lC(f)=1 => Fac(value(lS f))::O
+ lC(f)::O * Fac(value(lS f))::O
+ lC(f)=1 => Fac(value(lS f))::O + deepExpand(reductum f)
+ lC(f)::O * Fac(value(lS f))::O + deepExpand(reductum f)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain OSI OrdSetInts>>
+<<domain COMM Commutator>>
+<<package HB HallBasis>>
+<<domain FNLA FreeNilpotentLie>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/formula.spad.pamphlet b/src/algebra/formula.spad.pamphlet
new file mode 100644
index 00000000..b5668638
--- /dev/null
+++ b/src/algebra/formula.spad.pamphlet
@@ -0,0 +1,519 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra formula.spad}
+\author{Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FORMULA ScriptFormulaFormat}
+<<domain FORMULA ScriptFormulaFormat>>=
+)abbrev domain FORMULA ScriptFormulaFormat
+++ Author: Robert S. Sutor
+++ Date Created: 1987 through 1990
+++ Change History:
+++ Basic Operations: coerce, convert, display, epilogue,
+++ formula, new, prologue, setEpilogue!, setFormula!, setPrologue!
+++ Related Constructors: ScriptFormulaFormat1
+++ Also See: TexFormat
+++ AMS Classifications:
+++ Keywords: output, format, SCRIPT, BookMaster, formula
+++ References:
+++ SCRIPT Mathematical Formula Formatter User's Guide, SH20-6453,
+++ IBM Corporation, Publishing Systems Information Development,
+++ Dept. G68, P.O. Box 1900, Boulder, Colorado, USA 80301-9191.
+++ Description:
+++ \spadtype{ScriptFormulaFormat} provides a coercion from
+++ \spadtype{OutputForm} to IBM SCRIPT/VS Mathematical Formula Format.
+++ The basic SCRIPT formula format object consists of three parts: a
+++ prologue, a formula part and an epilogue. The functions
+++ \spadfun{prologue}, \spadfun{formula} and \spadfun{epilogue}
+++ extract these parts, respectively. The central parts of the expression
+++ go into the formula part. The other parts can be set
+++ (\spadfun{setPrologue!}, \spadfun{setEpilogue!}) so that contain the
+++ appropriate tags for printing. For example, the prologue and
+++ epilogue might simply contain ":df." and ":edf." so that the
+++ formula section will be printed in display math mode.
+
+ScriptFormulaFormat(): public == private where
+ E ==> OutputForm
+ I ==> Integer
+ L ==> List
+ S ==> String
+
+ public == SetCategory with
+ coerce: E -> %
+ ++ coerce(o) changes o in the standard output format to
+ ++ SCRIPT formula format.
+ convert: (E,I) -> %
+ ++ convert(o,step) changes o in standard output format to
+ ++ SCRIPT formula format and also adds the given step number.
+ ++ This is useful if you want to create equations with given numbers
+ ++ or have the equation numbers correspond to the interpreter step
+ ++ numbers.
+ display: (%, I) -> Void
+ ++ display(t,width) outputs the formatted code t so that each
+ ++ line has length less than or equal to \spadvar{width}.
+ display: % -> Void
+ ++ display(t) outputs the formatted code t so that each
+ ++ line has length less than or equal to the value set by
+ ++ the system command \spadsyscom{set output length}.
+ epilogue: % -> L S
+ ++ epilogue(t) extracts the epilogue section of a formatted object t.
+ formula: % -> L S
+ ++ formula(t) extracts the formula section of a formatted object t.
+ new: () -> %
+ ++ new() create a new, empty object. Use \spadfun{setPrologue!},
+ ++ \spadfun{setFormula!} and \spadfun{setEpilogue!} to set the
+ ++ various components of this object.
+ prologue: % -> L S
+ ++ prologue(t) extracts the prologue section of a formatted object t.
+ setEpilogue!: (%, L S) -> L S
+ ++ setEpilogue!(t,strings) sets the epilogue section of a
+ ++ formatted object t to strings.
+ setFormula!: (%, L S) -> L S
+ ++ setFormula!(t,strings) sets the formula section of a
+ ++ formatted object t to strings.
+ setPrologue!: (%, L S) -> L S
+ ++ setPrologue!(t,strings) sets the prologue section of a
+ ++ formatted object t to strings.
+
+ private == add
+ import OutputForm
+ import Character
+ import Integer
+ import List OutputForm
+ import List String
+
+ Rep := Record(prolog : L S, formula : L S, epilog : L S)
+
+ -- local variables declarations and definitions
+
+ expr: E
+ prec,opPrec: I
+ str: S
+ blank : S := " @@ "
+
+ maxPrec : I := 1000000
+ minPrec : I := 0
+
+ splitChars : S := " <>[](){}+*=,-%"
+
+ unaryOps : L S := ["-","^"]$(L S)
+ unaryPrecs : L I := [700,260]$(L I)
+
+ -- the precedence of / in the following is relatively low because
+ -- the bar obviates the need for parentheses.
+ binaryOps : L S := ["+->","|","**","/","<",">","=","OVER"]$(L S)
+ binaryPrecs : L I := [0,0,900, 700,400,400,400, 700]$(L I)
+
+ naryOps : L S := ["-","+","*",blank,",",";"," ","ROW","",
+ " habove "," here "," labove "]$(L S)
+ naryPrecs : L I := [700,700,800, 800,110,110, 0, 0, 0,
+ 0, 0, 0]$(L I)
+-- naryNGOps : L S := ["ROW"," here "]$(L S)
+ naryNGOps : L S := nil$(L S)
+
+ plexOps : L S := ["SIGMA","PI","INTSIGN","INDEFINTEGRAL"]$(L S)
+ plexPrecs : L I := [ 700, 800, 700, 700]$(L I)
+
+ specialOps : L S := ["MATRIX","BRACKET","BRACE","CONCATB", _
+ "AGGLST","CONCAT","OVERBAR","ROOT","SUB", _
+ "SUPERSUB","ZAG","AGGSET","SC","PAREN"]
+
+ -- the next two lists provide translations for some strings for
+ -- which the formula formatter provides special variables.
+
+ specialStrings : L S :=
+ ["5","..."]
+ specialStringsInFormula : L S :=
+ [" alpha "," ellipsis "]
+
+ -- local function signatures
+
+ addBraces: S -> S
+ addBrackets: S -> S
+ group: S -> S
+ formatBinary: (S,L E, I) -> S
+ formatFunction: (S,L E, I) -> S
+ formatMatrix: L E -> S
+ formatNary: (S,L E, I) -> S
+ formatNaryNoGroup: (S,L E, I) -> S
+ formatNullary: S -> S
+ formatPlex: (S,L E, I) -> S
+ formatSpecial: (S,L E, I) -> S
+ formatUnary: (S, E, I) -> S
+ formatFormula: (E,I) -> S
+ parenthesize: S -> S
+ precondition: E -> E
+ postcondition: S -> S
+ splitLong: (S,I) -> L S
+ splitLong1: (S,I) -> L S
+ stringify: E -> S
+
+ -- public function definitions
+
+ new() : % == [[".eq set blank @",":df."]$(L S),
+ [""]$(L S), [":edf."]$(L S)]$Rep
+
+ coerce(expr : E): % ==
+ f : % := new()$%
+ f.formula := [postcondition
+ formatFormula(precondition expr, minPrec)]$(L S)
+ f
+
+ convert(expr : E, stepNum : I): % ==
+ f : % := new()$%
+ f.formula := concat(["<leqno lparen ",string(stepNum)$S,
+ " rparen>"], [postcondition
+ formatFormula(precondition expr, minPrec)]$(L S))
+ f
+
+ display(f : %, len : I) ==
+ s,t : S
+ for s in f.prolog repeat sayFORMULA(s)$Lisp
+ for s in f.formula repeat
+ for t in splitLong(s, len) repeat sayFORMULA(t)$Lisp
+ for s in f.epilog repeat sayFORMULA(s)$Lisp
+ void()$Void
+
+ display(f : %) ==
+ display(f, _$LINELENGTH$Lisp pretend I)
+
+ prologue(f : %) == f.prolog
+ formula(f : %) == f.formula
+ epilogue(f : %) == f.epilog
+
+ setPrologue!(f : %, l : L S) == f.prolog := l
+ setFormula!(f : %, l : L S) == f.formula := l
+ setEpilogue!(f : %, l : L S) == f.epilog := l
+
+ coerce(f : %): E ==
+ s,t : S
+ l : L S := nil
+ for s in f.prolog repeat l := concat(s,l)
+ for s in f.formula repeat
+ for t in splitLong(s, (_$LINELENGTH$Lisp pretend Integer) - 4) repeat
+ l := concat(t,l)
+ for s in f.epilog repeat l := concat(s,l)
+ (reverse l) :: E
+
+ -- local function definitions
+
+ postcondition(str: S): S ==
+ len : I := #str
+ len < 4 => str
+ plus : Character := char "+"
+ minus: Character := char "-"
+ for i in 1..(len-1) repeat
+ if (str.i =$Character plus) and (str.(i+1) =$Character minus)
+ then setelt(str,i,char " ")$S
+ str
+
+ stringify expr == object2String(expr)$Lisp pretend S
+
+ splitLong(str : S, len : I): L S ==
+ -- this blocks into lines
+ if len < 20 then len := _$LINELENGTH$Lisp
+ splitLong1(str, len)
+
+ splitLong1(str : S, len : I) ==
+ l : List S := nil
+ s : S := ""
+ ls : I := 0
+ ss : S
+ lss : I
+ for ss in split(str,char " ") repeat
+ lss := #ss
+ if ls + lss > len then
+ l := concat(s,l)$List(S)
+ s := ""
+ ls := 0
+ lss > len => l := concat(ss,l)$List(S)
+ ls := ls + lss + 1
+ s := concat(s,concat(ss," ")$S)$S
+ if ls > 0 then l := concat(s,l)$List(S)
+ reverse l
+
+ group str ==
+ concat ["<",str,">"]
+
+ addBraces str ==
+ concat ["left lbrace ",str," right rbrace"]
+
+ addBrackets str ==
+ concat ["left lb ",str," right rb"]
+
+ parenthesize str ==
+ concat ["left lparen ",str," right rparen"]
+
+ precondition expr ==
+ outputTran(expr)$Lisp
+
+ formatSpecial(op : S, args : L E, prec : I) : S ==
+ op = "AGGLST" =>
+ formatNary(",",args,prec)
+ op = "AGGSET" =>
+ formatNary(";",args,prec)
+ op = "CONCATB" =>
+ formatNary(" ",args,prec)
+ op = "CONCAT" =>
+ formatNary("",args,prec)
+ op = "BRACKET" =>
+ group addBrackets formatFormula(first args, minPrec)
+ op = "BRACE" =>
+ group addBraces formatFormula(first args, minPrec)
+ op = "PAREN" =>
+ group parenthesize formatFormula(first args, minPrec)
+ op = "OVERBAR" =>
+ null args => ""
+ group concat [formatFormula(first args, minPrec)," bar"]
+ op = "ROOT" =>
+ null args => ""
+ tmp : S := formatFormula(first args, minPrec)
+ null rest args => group concat ["sqrt ",tmp]
+ group concat ["midsup adjust(u 1.5 r 9) ",
+ formatFormula(first rest args, minPrec)," sqrt ",tmp]
+ op = "SC" =>
+ formatNary(" labove ",args,prec)
+ op = "SUB" =>
+ group concat [formatFormula(first args, minPrec)," sub ",
+ formatSpecial("AGGLST",rest args,minPrec)]
+ op = "SUPERSUB" =>
+ -- variable name
+ form : List S := [formatFormula(first args, minPrec)]
+ -- subscripts
+ args := rest args
+ null args => concat form
+ tmp : S := formatFormula(first args, minPrec)
+ if tmp ^= "" then form := append(form,[" sub ",tmp])$(List S)
+ -- superscripts
+ args := rest args
+ null args => group concat form
+ tmp : S := formatFormula(first args, minPrec)
+ if tmp ^= "" then form := append(form,[" sup ",tmp])$(List S)
+ -- presuperscripts
+ args := rest args
+ null args => group concat form
+ tmp : S := formatFormula(first args, minPrec)
+ if tmp ^= "" then form := append(form,[" presup ",tmp])$(List S)
+ -- presubscripts
+ args := rest args
+ null args => group concat form
+ tmp : S := formatFormula(first args, minPrec)
+ if tmp ^= "" then form := append(form,[" presub ",tmp])$(List S)
+ group concat form
+ op = "MATRIX" => formatMatrix rest args
+-- op = "ZAG" =>
+-- concat ["\zag{",formatFormula(first args, minPrec),"}{",
+-- formatFormula(first rest args,minPrec),"}"]
+ concat ["not done yet for ",op]
+
+ formatPlex(op : S, args : L E, prec : I) : S ==
+ hold : S
+ p : I := position(op,plexOps)
+ p < 1 => error "unknown Script Formula Formatter unary op"
+ opPrec := plexPrecs.p
+ n : I := #args
+ (n ^= 2) and (n ^= 3) => error "wrong number of arguments for plex"
+ s : S :=
+ op = "SIGMA" => "sum"
+ op = "PI" => "product"
+ op = "INTSIGN" => "integral"
+ op = "INDEFINTEGRAL" => "integral"
+ "????"
+ hold := formatFormula(first args,minPrec)
+ args := rest args
+ if op ^= "INDEFINTEGRAL" then
+ if hold ^= "" then
+ s := concat [s," from",group concat ["\displaystyle ",hold]]
+ if not null rest args then
+ hold := formatFormula(first args,minPrec)
+ if hold ^= "" then
+ s := concat [s," to",group concat ["\displaystyle ",hold]]
+ args := rest args
+ s := concat [s," ",formatFormula(first args,minPrec)]
+ else
+ hold := group concat [hold," ",formatFormula(first args,minPrec)]
+ s := concat [s," ",hold]
+ if opPrec < prec then s := parenthesize s
+ group s
+
+ formatMatrix(args : L E) : S ==
+ -- format for args is [[ROW ...],[ROW ...],[ROW ...]]
+ group addBrackets formatNary(" habove ",args,minPrec)
+
+ formatFunction(op : S, args : L E, prec : I) : S ==
+ group concat [op, " ", parenthesize formatNary(",",args,minPrec)]
+
+ formatNullary(op : S) ==
+ op = "NOTHING" => ""
+ group concat [op,"()"]
+
+ formatUnary(op : S, arg : E, prec : I) ==
+ p : I := position(op,unaryOps)
+ p < 1 => error "unknown Script Formula Formatter unary op"
+ opPrec := unaryPrecs.p
+ s : S := concat [op,formatFormula(arg,opPrec)]
+ opPrec < prec => group parenthesize s
+ op = "-" => s
+ group s
+
+ formatBinary(op : S, args : L E, prec : I) : S ==
+ p : I := position(op,binaryOps)
+ p < 1 => error "unknown Script Formula Formatter binary op"
+ op :=
+ op = "**" => " sup "
+ op = "/" => " over "
+ op = "OVER" => " over "
+ op
+ opPrec := binaryPrecs.p
+ s : S := formatFormula(first args, opPrec)
+ s := concat [s,op,formatFormula(first rest args, opPrec)]
+ group
+ op = " over " => s
+ opPrec < prec => parenthesize s
+ s
+
+ formatNary(op : S, args : L E, prec : I) : S ==
+ group formatNaryNoGroup(op, args, prec)
+
+ formatNaryNoGroup(op : S, args : L E, prec : I) : S ==
+ null args => ""
+ p : I := position(op,naryOps)
+ p < 1 => error "unknown Script Formula Formatter nary op"
+ op :=
+ op = "," => ", @@ "
+ op = ";" => "; @@ "
+ op = "*" => blank
+ op = " " => blank
+ op = "ROW" => " here "
+ op
+ l : L S := nil
+ opPrec := naryPrecs.p
+ for a in args repeat
+ l := concat(op,concat(formatFormula(a,opPrec),l)$L(S))$L(S)
+ s : S := concat reverse rest l
+ opPrec < prec => parenthesize s
+ s
+
+ formatFormula(expr,prec) ==
+ i : Integer
+ ATOM(expr)$Lisp pretend Boolean =>
+ str := stringify expr
+ FIXP(expr)$Lisp =>
+ i := expr : Integer
+ if (i < 0) or (i > 9) then group str else str
+ (i := position(str,specialStrings)) > 0 =>
+ specialStringsInFormula.i
+ str
+ l : L E := (expr pretend L E)
+ null l => blank
+ op : S := stringify first l
+ args : L E := rest l
+ nargs : I := #args
+
+ -- special cases
+ member?(op, specialOps) => formatSpecial(op,args,prec)
+ member?(op, plexOps) => formatPlex(op,args,prec)
+
+ -- nullary case
+ 0 = nargs => formatNullary op
+
+ -- unary case
+ (1 = nargs) and member?(op, unaryOps) =>
+ formatUnary(op, first args, prec)
+
+ -- binary case
+ (2 = nargs) and member?(op, binaryOps) =>
+ formatBinary(op, args, prec)
+
+ -- nary case
+ member?(op,naryNGOps) => formatNaryNoGroup(op,args, prec)
+ member?(op,naryOps) => formatNary(op,args, prec)
+ op := formatFormula(first l,minPrec)
+ formatFunction(op,args,prec)
+
+@
+\section{package FORMULA1 ScriptFormulaFormat1}
+<<package FORMULA1 ScriptFormulaFormat1>>=
+)abbrev package FORMULA1 ScriptFormulaFormat1
+++ Author: Robert S. Sutor
+++ Date Created: 1987 through 1990
+++ Change History:
+++ Basic Operations: coerce
+++ Related Constructors: ScriptFormulaFormat
+++ Also See: TexFormat, TexFormat1
+++ AMS Classifications:
+++ Keywords: output, format, SCRIPT, BookMaster, formula
+++ References:
+++ SCRIPT Mathematical Formula Formatter User's Guide, SH20-6453,
+++ IBM Corporation, Publishing Systems Information Development,
+++ Dept. G68, P.O. Box 1900, Boulder, Colorado, USA 80301-9191.
+++ Description:
+++ \spadtype{ScriptFormulaFormat1} provides a utility coercion for
+++ changing to SCRIPT formula format anything that has a coercion to
+++ the standard output format.
+
+ScriptFormulaFormat1(S : SetCategory): public == private where
+ public == with
+ coerce: S -> ScriptFormulaFormat()
+ ++ coerce(s) provides a direct coercion from an expression s of domain S to
+ ++ SCRIPT formula format. This allows the user to skip the step of
+ ++ first manually coercing the object to standard output format
+ ++ before it is coerced to SCRIPT formula format.
+
+ private == add
+ import ScriptFormulaFormat()
+
+ coerce(s : S): ScriptFormulaFormat ==
+ coerce(s :: OutputForm)$ScriptFormulaFormat
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FORMULA ScriptFormulaFormat>>
+<<package FORMULA1 ScriptFormulaFormat1>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fortcat.spad.pamphlet b/src/algebra/fortcat.spad.pamphlet
new file mode 100644
index 00000000..16daa51d
--- /dev/null
+++ b/src/algebra/fortcat.spad.pamphlet
@@ -0,0 +1,345 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fortcat.spad}
+\author{Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category FORTFN FortranFunctionCategory}
+<<category FORTFN FortranFunctionCategory>>=
+)abbrev category FORTFN FortranFunctionCategory
+++ Author: Mike Dewar
+++ Date Created: 13 January 1994
+++ Date Last Updated: 18 March 1994
+++ Related Constructors: FortranProgramCategory.
+++ Description:
+++ \axiomType{FortranFunctionCategory} is the category of arguments to
+++ NAG Library routines which return (sets of) function values.
+FortranFunctionCategory():Category == FortranProgramCategory with
+ coerce : List FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{List FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : Record(localSymbols:SymbolTable,code:List(FortranCode)) -> $
+ ++ coerce(e) takes the component of \spad{e} from
+ ++ \spadtype{List FortranCode} and uses it as the body of the ASP,
+ ++ making the declarations in the \spadtype{SymbolTable} component.
+ retract : Expression Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Expression Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Expression Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Expression Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Polynomial Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Polynomial Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Polynomial Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Polynomial Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Fraction Polynomial Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Fraction Polynomial Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Fraction Polynomial Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Fraction Polynomial Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+
+ -- NB: These ASPs also have a coerce from an appropriate instantiation
+ -- of FortranExpression.
+
+
+@
+\section{category FMC FortranMatrixCategory}
+<<category FMC FortranMatrixCategory>>=
+)abbrev category FMC FortranMatrixCategory
+++ Author: Mike Dewar
+++ Date Created: 21 March 1994
+++ Date Last Updated:
+++ Related Constructors: FortranProgramCategory.
+++ Description:
+++ \axiomType{FortranMatrixCategory} provides support for
+++ producing Functions and Subroutines when the input to these
+++ is an AXIOM object of type \axiomType{Matrix} or in domains
+++ involving \axiomType{FortranCode}.
+FortranMatrixCategory():Category == FortranProgramCategory with
+ coerce : Matrix MachineFloat -> $
+ ++ coerce(v) produces an ASP which returns the value of \spad{v}.
+ coerce : List FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{List FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : Record(localSymbols:SymbolTable,code:List(FortranCode)) -> $
+ ++ coerce(e) takes the component of \spad{e} from
+ ++ \spadtype{List FortranCode} and uses it as the body of the ASP,
+ ++ making the declarations in the \spadtype{SymbolTable} component.
+
+@
+\section{category FORTCAT FortranProgramCategory}
+<<category FORTCAT FortranProgramCategory>>=
+)abbrev category FORTCAT FortranProgramCategory
+++ Author: Mike Dewar
+++ Date Created: November 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FortranType, FortranCode, Switch
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \axiomType{FortranProgramCategory} provides various models of
+++ FORTRAN subprograms. These can be transformed into actual FORTRAN
+++ code.
+FortranProgramCategory():Category == Join(Type,CoercibleTo OutputForm) with
+ outputAsFortran : $ -> Void
+ ++ \axiom{outputAsFortran(u)} translates \axiom{u} into a legal FORTRAN
+ ++ subprogram.
+
+@
+\section{category FVC FortranVectorCategory}
+<<category FVC FortranVectorCategory>>=
+)abbrev category FVC FortranVectorCategory
+++ Author: Mike Dewar
+++ Date Created: October 1993
+++ Date Last Updated: 18 March 1994
+++ Related Constructors: FortranProgramCategory.
+++ Description:
+++ \axiomType{FortranVectorCategory} provides support for
+++ producing Functions and Subroutines when the input to these
+++ is an AXIOM object of type \axiomType{Vector} or in domains
+++ involving \axiomType{FortranCode}.
+FortranVectorCategory():Category == FortranProgramCategory with
+ coerce : Vector MachineFloat -> $
+ ++ coerce(v) produces an ASP which returns the value of \spad{v}.
+ coerce : List FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{List FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : Record(localSymbols:SymbolTable,code:List(FortranCode)) -> $
+ ++ coerce(e) takes the component of \spad{e} from
+ ++ \spadtype{List FortranCode} and uses it as the body of the ASP,
+ ++ making the declarations in the \spadtype{SymbolTable} component.
+
+@
+\section{category FMTC FortranMachineTypeCategory}
+<<category FMTC FortranMachineTypeCategory>>=
+)abbrev category FMTC FortranMachineTypeCategory
+++ Author: Mike Dewar
+++ Date Created: December 1993
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See: FortranExpression, MachineInteger, MachineFloat, MachineComplex
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A category of domains which model machine arithmetic
+++ used by machines in the AXIOM-NAG link.
+FortranMachineTypeCategory():Category == Join(IntegralDomain,OrderedSet,
+ RetractableTo(Integer) )
+
+@
+\section{category FMFUN FortranMatrixFunctionCategory}
+<<category FMFUN FortranMatrixFunctionCategory>>=
+)abbrev category FMFUN FortranMatrixFunctionCategory
+++ Author: Mike Dewar
+++ Date Created: March 18 1994
+++ Date Last Updated:
+++ Related Constructors: FortranProgramCategory.
+++ Description:
+++ \axiomType{FortranMatrixFunctionCategory} provides support for
+++ producing Functions and Subroutines representing matrices of
+++ expressions.
+
+FortranMatrixFunctionCategory():Category == FortranProgramCategory with
+ coerce : List FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{List FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : Record(localSymbols:SymbolTable,code:List(FortranCode)) -> $
+ ++ coerce(e) takes the component of \spad{e} from
+ ++ \spadtype{List FortranCode} and uses it as the body of the ASP,
+ ++ making the declarations in the \spadtype{SymbolTable} component.
+ retract : Matrix Expression Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Matrix Expression Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Matrix Expression Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Matrix Expression Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Matrix Polynomial Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Matrix Polynomial Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Matrix Polynomial Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Matrix Polynomial Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Matrix Fraction Polynomial Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Matrix Fraction Polynomial Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Matrix Fraction Polynomial Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Matrix Fraction Polynomial Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+
+ -- NB: These ASPs also have a coerce from an appropriate instantiation
+ -- of Matrix FortranExpression.
+
+@
+\section{category FVFUN FortranVectorFunctionCategory}
+<<category FVFUN FortranVectorFunctionCategory>>=
+)abbrev category FVFUN FortranVectorFunctionCategory
+++ Author: Mike Dewar
+++ Date Created: 11 March 1994
+++ Date Last Updated: 18 March 1994
+++ Related Constructors: FortranProgramCategory.
+++ Description:
+++ \axiomType{FortranVectorFunctionCategory} is the catagory of arguments
+++ to NAG Library routines which return the values of vectors of functions.
+FortranVectorFunctionCategory():Category == FortranProgramCategory with
+ coerce : List FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{List FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : FortranCode -> $
+ ++ coerce(e) takes an object from \spadtype{FortranCode} and
+ ++ uses it as the body of an ASP.
+ coerce : Record(localSymbols:SymbolTable,code:List(FortranCode)) -> $
+ ++ coerce(e) takes the component of \spad{e} from
+ ++ \spadtype{List FortranCode} and uses it as the body of the ASP,
+ ++ making the declarations in the \spadtype{SymbolTable} component.
+ retract : Vector Expression Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Vector Expression Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Vector Expression Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Vector Expression Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Vector Polynomial Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Vector Polynomial Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Vector Polynomial Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Vector Polynomial Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Vector Fraction Polynomial Float -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Vector Fraction Polynomial Float -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retract : Vector Fraction Polynomial Integer -> $
+ ++ retract(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+ retractIfCan : Vector Fraction Polynomial Integer -> Union($,"failed")
+ ++ retractIfCan(e) tries to convert \spad{e} into an ASP, checking that
+ ++ legal Fortran-77 is produced.
+
+ -- NB: These ASPs also have a coerce from an appropriate instantiation
+ -- of Vector FortranExpression.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category FORTFN FortranFunctionCategory>>
+<<category FMC FortranMatrixCategory>>
+<<category FORTCAT FortranProgramCategory>>
+<<category FVC FortranVectorCategory>>
+<<category FMTC FortranMachineTypeCategory>>
+<<category FMFUN FortranMatrixFunctionCategory>>
+<<category FVFUN FortranVectorFunctionCategory>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fortmac.spad.pamphlet b/src/algebra/fortmac.spad.pamphlet
new file mode 100644
index 00000000..8c23f9ac
--- /dev/null
+++ b/src/algebra/fortmac.spad.pamphlet
@@ -0,0 +1,461 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fortmac.spad}
+\author{Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MINT MachineInteger}
+<<domain MINT MachineInteger>>=
+)abbrev domain MINT MachineInteger
+++ Author: Mike Dewar
+++ Date Created: December 1993
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See: FortranExpression, FortranMachineTypeCategory, MachineFloat,
+++ MachineComplex
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A domain which models the integer representation
+++ used by machines in the AXIOM-NAG link.
+MachineInteger(): Exports == Implementation where
+
+ S ==> String
+
+ Exports ==> Join(FortranMachineTypeCategory,IntegerNumberSystem) with
+ maxint : PositiveInteger -> PositiveInteger
+ ++ maxint(u) sets the maximum integer in the model to u
+ maxint : () -> PositiveInteger
+ ++ maxint() returns the maximum integer in the model
+ coerce : Expression Integer -> Expression $
+ ++ coerce(x) returns x with coefficients in the domain
+
+ Implementation ==> Integer add
+
+ MAXINT : PositiveInteger := 2**32
+
+ maxint():PositiveInteger == MAXINT
+
+ maxint(new:PositiveInteger):PositiveInteger ==
+ old := MAXINT
+ MAXINT := new
+ old
+
+ coerce(u:Expression Integer):Expression($) ==
+ map(coerce,u)$ExpressionFunctions2(Integer,$)
+
+ coerce(u:Integer):$ ==
+ import S
+ abs(u) > MAXINT =>
+ message: S := concat [convert(u)@S," > MAXINT(",convert(MAXINT)@S,")"]
+ error message
+ u pretend $
+
+ retract(u:$):Integer == u pretend Integer
+
+ retractIfCan(u:$):Union(Integer,"failed") == u pretend Integer
+
+@
+\section{domain MFLOAT MachineFloat}
+<<domain MFLOAT MachineFloat>>=
+)abbrev domain MFLOAT MachineFloat
+++ Author: Mike Dewar
+++ Date Created: December 1993
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See: FortranExpression, FortranMachineTypeCategory, MachineInteger,
+++ MachineComplex
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A domain which models the floating point representation
+++ used by machines in the AXIOM-NAG link.
+MachineFloat(): Exports == Implementation where
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ F ==> Float
+ I ==> Integer
+ S ==> String
+ FI ==> Fraction Integer
+ SUP ==> SparseUnivariatePolynomial
+ SF ==> DoubleFloat
+
+ Exports ==> Join(FloatingPointSystem,FortranMachineTypeCategory,Field,
+ RetractableTo(Float),RetractableTo(Fraction(Integer)),CharacteristicZero) with
+ precision : PI -> PI
+ ++ precision(p) sets the number of digits in the model to p
+ precision : () -> PI
+ ++ precision() returns the number of digits in the model
+ base : PI -> PI
+ ++ base(b) sets the base of the model to b
+ base : () -> PI
+ ++ base() returns the base of the model
+ maximumExponent : I -> I
+ ++ maximumExponent(e) sets the maximum exponent in the model to e
+ maximumExponent : () -> I
+ ++ maximumExponent() returns the maximum exponent in the model
+ minimumExponent : I -> I
+ ++ minimumExponent(e) sets the minimum exponent in the model to e
+ minimumExponent : () -> I
+ ++ minimumExponent() returns the minimum exponent in the model
+ coerce : $ -> F
+ ++ coerce(u) transforms a MachineFloat to a standard Float
+ coerce : MachineInteger -> $
+ ++ coerce(u) transforms a MachineInteger into a MachineFloat
+ mantissa : $ -> I
+ ++ mantissa(u) returns the mantissa of u
+ exponent : $ -> I
+ ++ exponent(u) returns the exponent of u
+ changeBase : (I,I,PI) -> $
+ ++ changeBase(exp,man,base) \undocumented{}
+
+ Implementation ==> add
+
+ import F
+ import FI
+
+ Rep := Record(mantissa:I,exponent:I)
+
+ -- Parameters of the Floating Point Representation
+ P : PI := 16 -- Precision
+ B : PI := 2 -- Base
+ EMIN : I := -1021 -- Minimum Exponent
+ EMAX : I := 1024 -- Maximum Exponent
+
+ -- Useful constants
+ POWER : PI := 53 -- The maximum power of B which will yield P
+ -- decimal digits.
+ MMAX : PI := B**POWER
+
+
+ -- locals
+ locRound:(FI)->I
+ checkExponent:($)->$
+ normalise:($)->$
+ newPower:(PI,PI)->Void
+
+ retractIfCan(u:$):Union(FI,"failed") ==
+ mantissa(u)*(B/1)**(exponent(u))
+
+ wholePart(u:$):Integer ==
+ man:I:=mantissa u
+ exp:I:=exponent u
+ f:=
+ positive? exp => man*B**(exp pretend PI)
+ zero? exp => man
+ wholePart(man/B**((-exp) pretend PI))
+ normalise(u:$):$ ==
+ -- We want the largest possible mantissa, to ensure a canonical
+ -- representation.
+ exp : I := exponent u
+ man : I := mantissa u
+ BB : I := B pretend I
+ sgn : I := sign man ; man := abs man
+ zero? man => [0,0]$Rep
+ if man < MMAX then
+ while man < MMAX repeat
+ exp := exp - 1
+ man := man * BB
+ if man > MMAX then
+ q1:FI:= man/1
+ BBF:FI:=BB/1
+ while wholePart(q1) > MMAX repeat
+ q1:= q1 / BBF
+ exp:=exp + 1
+ man := locRound(q1)
+ positive?(sgn) => checkExponent [man,exp]$Rep
+ checkExponent [-man,exp]$Rep
+
+ mantissa(u:$):I == elt(u,mantissa)$Rep
+ exponent(u:$):I == elt(u,exponent)$Rep
+
+ newPower(base:PI,prec:PI):Void ==
+ power : PI := 1
+ target : PI := 10**prec
+ current : PI := base
+ while (current := current*base) < target repeat power := power+1
+ POWER := power
+ MMAX := B**POWER
+ void()
+
+ changeBase(exp:I,man:I,base:PI):$ ==
+ newExp : I := 0
+ f : FI := man*(base pretend I)::FI**exp
+ sign : I := sign f
+ f : FI := abs f
+ newMan : I := wholePart f
+ zero? f => [0,0]$Rep
+ BB : FI := (B pretend I)::FI
+ if newMan < MMAX then
+ while newMan < MMAX repeat
+ newExp := newExp - 1
+ f := f*BB
+ newMan := wholePart f
+ if newMan > MMAX then
+ while newMan > MMAX repeat
+ newExp := newExp + 1
+ f := f/BB
+ newMan := wholePart f
+ [sign*newMan,newExp]$Rep
+
+ checkExponent(u:$):$ ==
+ exponent(u) < EMIN or exponent(u) > EMAX =>
+ message :S := concat(["Exponent out of range: ",
+ convert(EMIN)@S, "..", convert(EMAX)@S])$S
+ error message
+ u
+
+ coerce(u:$):OutputForm ==
+ coerce(u::F)
+
+ coerce(u:MachineInteger):$ ==
+ checkExponent changeBase(0,retract(u)@Integer,10)
+
+ coerce(u:$):F ==
+ oldDigits : PI := digits(P)$F
+ r : F := float(mantissa u,exponent u,B)$Float
+ digits(oldDigits)$F
+ r
+
+ coerce(u:F):$ ==
+ checkExponent changeBase(exponent(u)$F,mantissa(u)$F,base()$F)
+
+ coerce(u:I):$ ==
+ checkExponent changeBase(0,u,10)
+
+ coerce(u:FI):$ == (numer u)::$/(denom u)::$
+
+ retract(u:$):FI ==
+ value : Union(FI,"failed") := retractIfCan(u)
+ value case "failed" => error "Cannot retract to a Fraction Integer"
+ value::FI
+
+ retract(u:$):F == u::F
+
+ retractIfCan(u:$):Union(F,"failed") == u::F::Union(F,"failed")
+
+ retractIfCan(u:$):Union(I,"failed") ==
+ value:FI := mantissa(u)*(B pretend I)::FI**exponent(u)
+ zero? fractionPart(value) => wholePart(value)::Union(I,"failed")
+ "failed"::Union(I,"failed")
+
+ retract(u:$):I ==
+ result : Union(I,"failed") := retractIfCan u
+ result = "failed" => error "Not an Integer"
+ result::I
+
+ precision(p: PI):PI ==
+ old : PI := P
+ newPower(B,p)
+ P := p
+ old
+
+ precision():PI == P
+
+ base(b:PI):PI ==
+ old : PI := b
+ newPower(b,P)
+ B := b
+ old
+
+ base():PI == B
+
+ maximumExponent(u:I):I ==
+ old : I := EMAX
+ EMAX := u
+ old
+
+ maximumExponent():I == EMAX
+
+ minimumExponent(u:I):I ==
+ old : I := EMIN
+ EMIN := u
+ old
+
+ minimumExponent():I == EMIN
+
+ 0 == [0,0]$Rep
+ 1 == changeBase(0,1,10)
+
+ zero?(u:$):Boolean == u=[0,0]$Rep
+
+
+
+ f1:$
+ f2:$
+
+
+ locRound(x:FI):I ==
+ abs(fractionPart(x)) >= 1/2 => wholePart(x)+sign(x)
+ wholePart(x)
+
+ recip f1 ==
+ zero? f1 => "failed"
+ normalise [ locRound(B**(2*POWER)/mantissa f1),-(exponent f1 + 2*POWER)]
+
+ f1 * f2 ==
+ normalise [mantissa(f1)*mantissa(f2),exponent(f1)+exponent(f2)]$Rep
+
+ f1 **(p:FI) ==
+ ((f1::F)**p)::%
+
+--inline
+ f1 / f2 ==
+ zero? f2 => error "division by zero"
+ zero? f1 => 0
+ f1=f2 => 1
+ normalise [locRound(mantissa(f1)*B**(2*POWER)/mantissa(f2)),
+ exponent(f1)-(exponent f2 + 2*POWER)]
+
+ inv(f1) == 1/f1
+
+ f1 exquo f2 == f1/f2
+
+ divide(f1,f2) == [ f1/f2,0]
+
+ f1 quo f2 == f1/f2
+ f1 rem f2 == 0
+ u:I * f1 ==
+ normalise [u*mantissa(f1),exponent(f1)]$Rep
+
+ f1 = f2 == mantissa(f1)=mantissa(f2) and exponent(f1)=exponent(f2)
+
+ f1 + f2 ==
+ m1 : I := mantissa f1
+ m2 : I := mantissa f2
+ e1 : I := exponent f1
+ e2 : I := exponent f2
+ e1 > e2 =>
+--insignificance
+ e1 > e2 + POWER + 2 =>
+ zero? f1 => f2
+ f1
+ normalise [m1*(B pretend I)**((e1-e2) pretend NNI)+m2,e2]$Rep
+ e2 > e1 + POWER +2 =>
+ zero? f2 => f1
+ f2
+ normalise [m2*(B pretend I)**((e2-e1) pretend NNI)+m1,e1]$Rep
+
+ - f1 == [- mantissa f1,exponent f1]$Rep
+
+ f1 - f2 == f1 + (-f2)
+
+ f1 < f2 ==
+ m1 : I := mantissa f1
+ m2 : I := mantissa f2
+ e1 : I := exponent f1
+ e2 : I := exponent f2
+ sign(m1) = sign(m2) =>
+ e1 < e2 => true
+ e1 = e2 and m1 < m2 => true
+ false
+ sign(m1) = 1 => false
+ sign(m1) = 0 and sign(m2) = -1 => false
+ true
+
+ characteristic():NNI == 0
+
+@
+\section{domain MCMPLX MachineComplex}
+<<domain MCMPLX MachineComplex>>=
+)abbrev domain MCMPLX MachineComplex
+++ Date Created: December 1993
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See: FortranExpression, FortranMachineTypeCategory, MachineInteger,
+++ MachineFloat
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A domain which models the complex number representation
+++ used by machines in the AXIOM-NAG link.
+MachineComplex():Exports == Implementation where
+
+ Exports ==> Join (FortranMachineTypeCategory,
+ ComplexCategory(MachineFloat)) with
+ coerce : Complex Float -> $
+ ++ coerce(u) transforms u into a MachineComplex
+ coerce : Complex Integer -> $
+ ++ coerce(u) transforms u into a MachineComplex
+ coerce : Complex MachineFloat -> $
+ ++ coerce(u) transforms u into a MachineComplex
+ coerce : Complex MachineInteger -> $
+ ++ coerce(u) transforms u into a MachineComplex
+ coerce : $ -> Complex Float
+ ++ coerce(u) transforms u into a COmplex Float
+
+ Implementation ==> Complex MachineFloat add
+
+ coerce(u:Complex Float):$ ==
+ complex(real(u)::MachineFloat,imag(u)::MachineFloat)
+
+ coerce(u:Complex Integer):$ ==
+ complex(real(u)::MachineFloat,imag(u)::MachineFloat)
+
+ coerce(u:Complex MachineInteger):$ ==
+ complex(real(u)::MachineFloat,imag(u)::MachineFloat)
+
+ coerce(u:Complex MachineFloat):$ ==
+ complex(real(u),imag(u))
+
+ coerce(u:$):Complex Float ==
+ complex(real(u)::Float,imag(u)::Float)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MINT MachineInteger>>
+<<domain MFLOAT MachineFloat>>
+<<domain MCMPLX MachineComplex>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fortpak.spad.pamphlet b/src/algebra/fortpak.spad.pamphlet
new file mode 100644
index 00000000..5f3fb1e6
--- /dev/null
+++ b/src/algebra/fortpak.spad.pamphlet
@@ -0,0 +1,659 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fortpak.spad}
+\author{Grant Keady, Godfrey Nolan, Mike Dewar, Themos Tsikas}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FCPAK1 FortranCodePackage1}
+<<package FCPAK1 FortranCodePackage1>>=
+)abbrev package FCPAK1 FortranCodePackage1
+++ Author: Grant Keady and Godfrey Nolan
+++ Date Created: April 1993
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{FortranCodePackage1} provides some utilities for
+++ producing useful objects in FortranCode domain.
+++ The Package may be used with the FortranCode domain and its
+++ \spad{printCode} or possibly via an outputAsFortran.
+++ (The package provides items of use in connection with ASPs
+++ in the AXIOM-NAG link and, where appropriate, naming accords
+++ with that in IRENA.)
+++ The easy-to-use functions use Fortran loop variables I1, I2,
+++ and it is users' responsibility to check that this is sensible.
+++ The advanced functions use SegmentBinding to allow users control
+++ over Fortran loop variable names.
+-- Later might add functions to build
+-- diagonalMatrix from List, i.e. the FC version of the corresponding
+-- AXIOM function from MatrixCategory;
+-- bandedMatrix, i.e. the full-matrix-FC version of the corresponding
+-- AXIOM function in BandedMatrix Domain
+-- bandedSymmetricMatrix, i.e. the full-matrix-FC version of the corresponding
+-- AXIOM function in BandedSymmetricMatrix Domain
+
+FortranCodePackage1: Exports == Implementation where
+
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ PIN ==> Polynomial(Integer)
+ SBINT ==> SegmentBinding(Integer)
+ SEGINT ==> Segment(Integer)
+ LSBINT ==> List(SegmentBinding(Integer))
+ SBPIN ==> SegmentBinding(Polynomial(Integer))
+ SEGPIN ==> Segment(Polynomial(Integer))
+ LSBPIN ==> List(SegmentBinding(Polynomial(Integer)))
+ FC ==> FortranCode
+ EXPRESSION ==> Union(Expression Integer,Expression Float,Expression Complex Integer,Expression Complex Float)
+
+ Exports == with
+
+ zeroVector: (Symbol,PIN) -> FC
+ ++ zeroVector(s,p) \undocumented{}
+
+ zeroMatrix: (Symbol,PIN,PIN) -> FC
+ ++ zeroMatrix(s,p,q) uses loop variables in the Fortran, I1 and I2
+
+ zeroMatrix: (Symbol,SBPIN,SBPIN) -> FC
+ ++ zeroMatrix(s,b,d) in this version gives the user control
+ ++ over names of Fortran variables used in loops.
+
+ zeroSquareMatrix: (Symbol,PIN) -> FC
+ ++ zeroSquareMatrix(s,p) \undocumented{}
+
+ identitySquareMatrix: (Symbol,PIN) -> FC
+ ++ identitySquareMatrix(s,p) \undocumented{}
+
+ Implementation ==> add
+ import FC
+
+ zeroVector(fname:Symbol,n:PIN):FC ==
+ ue:Expression(Integer) := 0
+ i1:Symbol := "I1"::Symbol
+ lp1:PIN := 1::PIN
+ hp1:PIN := n
+ segp1:SEGPIN:= segment(lp1,hp1)$SEGPIN
+ segbp1:SBPIN := equation(i1,segp1)$SBPIN
+ ip1:PIN := i1::PIN
+ indices:List(PIN) := [ip1]
+ fa:FC := forLoop(segbp1,assign(fname,indices,ue)$FC)$FC
+ fa
+
+ zeroMatrix(fname:Symbol,m:PIN,n:PIN):FC ==
+ ue:Expression(Integer) := 0
+ i1:Symbol := "I1"::Symbol
+ lp1:PIN := 1::PIN
+ hp1:PIN := m
+ segp1:SEGPIN:= segment(lp1,hp1)$SEGPIN
+ segbp1:SBPIN := equation(i1,segp1)$SBPIN
+ i2:Symbol := "I2"::Symbol
+ hp2:PIN := n
+ segp2:SEGPIN:= segment(lp1,hp2)$SEGPIN
+ segbp2:SBPIN := equation(i2,segp2)$SBPIN
+ ip1:PIN := i1::PIN
+ ip2:PIN := i2::PIN
+ indices:List(PIN) := [ip1,ip2]
+ fa:FC :=forLoop(segbp1,forLoop(segbp2,assign(fname,indices,ue)$FC)$FC)$FC
+ fa
+
+ zeroMatrix(fname:Symbol,segbp1:SBPIN,segbp2:SBPIN):FC ==
+ ue:Expression(Integer) := 0
+ i1:Symbol := variable(segbp1)$SBPIN
+ i2:Symbol := variable(segbp2)$SBPIN
+ ip1:PIN := i1::PIN
+ ip2:PIN := i2::PIN
+ indices:List(PIN) := [ip1,ip2]
+ fa:FC :=forLoop(segbp1,forLoop(segbp2,assign(fname,indices,ue)$FC)$FC)$FC
+ fa
+
+ zeroSquareMatrix(fname:Symbol,n:PIN):FC ==
+ ue:Expression(Integer) := 0
+ i1:Symbol := "I1"::Symbol
+ lp1:PIN := 1::PIN
+ hp1:PIN := n
+ segp1:SEGPIN:= segment(lp1,hp1)$SEGPIN
+ segbp1:SBPIN := equation(i1,segp1)$SBPIN
+ i2:Symbol := "I2"::Symbol
+ segbp2:SBPIN := equation(i2,segp1)$SBPIN
+ ip1:PIN := i1::PIN
+ ip2:PIN := i2::PIN
+ indices:List(PIN) := [ip1,ip2]
+ fa:FC :=forLoop(segbp1,forLoop(segbp2,assign(fname,indices,ue)$FC)$FC)$FC
+ fa
+
+ identitySquareMatrix(fname:Symbol,n:PIN):FC ==
+ ue:Expression(Integer) := 0
+ u1:Expression(Integer) := 1
+ i1:Symbol := "I1"::Symbol
+ lp1:PIN := 1::PIN
+ hp1:PIN := n
+ segp1:SEGPIN:= segment(lp1,hp1)$SEGPIN
+ segbp1:SBPIN := equation(i1,segp1)$SBPIN
+ i2:Symbol := "I2"::Symbol
+ segbp2:SBPIN := equation(i2,segp1)$SBPIN
+ ip1:PIN := i1::PIN
+ ip2:PIN := i2::PIN
+ indice1:List(PIN) := [ip1,ip1]
+ indices:List(PIN) := [ip1,ip2]
+ fc:FC := forLoop(segbp2,assign(fname,indices,ue)$FC)$FC
+ f1:FC := assign(fname,indice1,u1)$FC
+ fl:List(FC) := [fc,f1]
+ fa:FC := forLoop(segbp1,block(fl)$FC)$FC
+ fa
+
+@
+\section{package NAGSP NAGLinkSupportPackage}
+<<package NAGSP NAGLinkSupportPackage>>=
+)abbrev package NAGSP NAGLinkSupportPackage
+++ Author: Mike Dewar and Godfrey Nolan
+++ Date Created: March 1993
+++ Date Last Updated: March 4 1994
+++ October 6 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Support functions for the NAG Library Link functions
+NAGLinkSupportPackage() : exports == implementation where
+
+ exports ==> with
+ fortranCompilerName : () -> String
+ ++ fortranCompilerName() returns the name of the currently selected
+ ++ Fortran compiler
+ fortranLinkerArgs : () -> String
+ ++ fortranLinkerArgs() returns the current linker arguments
+ aspFilename : String -> String
+ ++ aspFilename("f") returns a String consisting of "f" suffixed with
+ ++ an extension identifying the current AXIOM session.
+ dimensionsOf : (Symbol, Matrix DoubleFloat) -> SExpression
+ ++ dimensionsOf(s,m) \undocumented{}
+ dimensionsOf : (Symbol, Matrix Integer) -> SExpression
+ ++ dimensionsOf(s,m) \undocumented{}
+ checkPrecision : () -> Boolean
+ ++ checkPrecision() \undocumented{}
+ restorePrecision : () -> Void
+ ++ restorePrecision() \undocumented{}
+
+ implementation ==> add
+ makeAs: (Symbol,Symbol) -> Symbol
+ changeVariables: (Expression Integer,Symbol) -> Expression Integer
+ changeVariablesF: (Expression Float,Symbol) -> Expression Float
+
+ import String
+ import Symbol
+
+ checkPrecision():Boolean ==
+ (_$fortranPrecision$Lisp = "single"::Symbol) and (_$nagEnforceDouble$Lisp) =>
+ systemCommand("set fortran precision double")$MoreSystemCommands
+ if _$nagMessages$Lisp then
+ print("*** Warning: Resetting fortran precision to double")$PrintPackage
+ true
+ false
+
+ restorePrecision():Void ==
+ systemCommand("set fortran precision single")$MoreSystemCommands
+ if _$nagMessages$Lisp then
+ print("** Warning: Restoring fortran precision to single")$PrintPackage
+ void()$Void
+
+ uniqueId : String := ""
+ counter : Integer := 0
+ getUniqueId():String ==
+ if uniqueId = "" then
+ uniqueId := concat(getEnv("HOST")$Lisp,getEnv("SPADNUM")$Lisp)
+ concat(uniqueId,string (counter:=counter+1))
+
+ fortranCompilerName() == string _$fortranCompilerName$Lisp
+ fortranLinkerArgs() == string _$fortranLibraries$Lisp
+
+ aspFilename(f:String):String == concat ["/tmp/",f,getUniqueId(),".f"]
+
+ dimensionsOf(u:Symbol,m:Matrix DoubleFloat):SExpression ==
+ [u,nrows m,ncols m]$Lisp
+ dimensionsOf(u:Symbol,m:Matrix Integer):SExpression ==
+ [u,nrows m,ncols m]$Lisp
+
+@
+\section{package FORT FortranPackage}
+<<package FORT FortranPackage>>=
+)abbrev package FORT FortranPackage
+-- Because of a bug in the compiler:
+)bo $noSubsumption:=true
+
+++ Author: Mike Dewar
+++ Date Created: October 6 1991
+++ Date Last Updated: 13 July 1994
+++ Basic Operations: linkToFortran
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: provides an interface to the boot code for calling Fortran
+FortranPackage(): Exports == Implementation where
+ FST ==> FortranScalarType
+ SEX ==> SExpression
+ L ==> List
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+ U ==> Union(array:L S,scalar:S)
+
+ Exports ==> with
+ linkToFortran: (S, L U, L L U, L S) -> SEX
+ ++ linkToFortran(s,l,ll,lv) \undocumented{}
+ linkToFortran: (S, L U, L L U, L S, S) -> SEX
+ ++ linkToFortran(s,l,ll,lv,t) \undocumented{}
+ linkToFortran: (S,L S,TheSymbolTable,L S) -> SEX
+ ++ linkToFortran(s,l,t,lv) \undocumented{}
+ outputAsFortran: FileName -> Void
+ ++ outputAsFortran(fn) \undocumented{}
+ setLegalFortranSourceExtensions: List String -> List String
+ ++ setLegalFortranSourceExtensions(l) \undocumented{}
+
+ Implementation ==> add
+
+ legalFortranSourceExtensions : List String := ["f"]
+
+ setLegalFortranSourceExtensions(l:List String):List String ==
+ legalFortranSourceExtensions := l
+
+ checkExtension(fn : FileName) : String ==
+ -- Does it end in a legal extension ?
+ stringFn := fn::String
+ not member?(extension fn,legalFortranSourceExtensions) =>
+ error [stringFn,"is not a legal Fortran Source File."]
+ stringFn
+
+ outputAsFortran(fn:FileName):Void ==
+-- source : String := checkExtension fn
+ source : String := fn::String
+ not readable? fn =>
+ popFortranOutputStack()$FOP
+ error([source,"is not readable"]@List(String))
+ target : String := topFortranOutputStack()$FOP
+ command : String :=
+ concat(["sys rm -f ",target," ; cp ",source," ",target])$String
+ systemCommand(command)$MoreSystemCommands
+ void()$Void
+
+ linkToFortran(name:S,args:L U, decls:L L U, res:L(S)):SEX ==
+ makeFort(name,args,decls,res,NIL$Lisp,NIL$Lisp)$Lisp
+
+ linkToFortran(name:S,args:L U, decls:L L U, res:L(S),returnType:S):SEX ==
+ makeFort(name,args,decls,res,returnType,NIL$Lisp)$Lisp
+
+ dimensions(type:FortranType):SEX ==
+ convert([convert(convert(u)@InputForm)@SEX _
+ for u in dimensionsOf(type)])@SEX
+
+ ftype(name:S,type:FortranType):SEX ==
+ [name,scalarTypeOf(type),dimensions(type),external? type]$Lisp
+
+ makeAspList(asp:S,syms:TheSymbolTable):SExpression==
+ symtab : SymbolTable := symbolTableOf(asp,syms)
+ [asp,returnTypeOf(asp,syms),argumentListOf(asp,syms), _
+ [ftype(u,fortranTypeOf(u,symtab)) for u in parametersOf symtab]]$Lisp
+
+ linkToFortran(name:S,aArgs:L S,syms:TheSymbolTable,res:L S):SEX ==
+ arguments : L S := argumentListOf(name,syms)$TheSymbolTable
+ dummies : L S := setDifference(arguments,aArgs)
+ symbolTable:SymbolTable := symbolTableOf(name,syms)
+ symbolList := newTypeLists(symbolTable)
+ rt:Union(fst: FST,void: "void") := returnTypeOf(name,syms)$TheSymbolTable
+
+ -- Look for arguments which are subprograms
+ asps :=[makeAspList(u,syms) for u in externalList(symbolTable)$SymbolTable]
+ rt case fst =>
+ makeFort1(name,arguments,aArgs,dummies,symbolList,res,(rt.fst)::S,asps)$Lisp
+ makeFort1(name,arguments,aArgs,dummies,symbolList,res,NIL$Lisp,asps)$Lisp
+
+@
+\section{package FOP FortranOutputStackPackage}
+<<package FOP FortranOutputStackPackage>>=
+)abbrev package FOP FortranOutputStackPackage
+-- Because of a bug in the compiler:
+)bo $noSubsumption:=false
+
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Code to manipulate Fortran Output Stack
+FortranOutputStackPackage() : specification == implementation where
+
+ specification == with
+
+ clearFortranOutputStack : () -> Stack String
+ ++ clearFortranOutputStack() clears the Fortran output stack
+ showFortranOutputStack : () -> Stack String
+ ++ showFortranOutputStack() returns the Fortran output stack
+ popFortranOutputStack : () -> Void
+ ++ popFortranOutputStack() pops the Fortran output stack
+ pushFortranOutputStack : FileName -> Void
+ ++ pushFortranOutputStack(f) pushes f onto the Fortran output stack
+ pushFortranOutputStack : String -> Void
+ ++ pushFortranOutputStack(f) pushes f onto the Fortran output stack
+ topFortranOutputStack : () -> String
+ ++ topFortranOutputStack() returns the top element of the Fortran
+ ++ output stack
+
+ implementation == add
+
+ import MoreSystemCommands
+
+ -- A stack of filenames for Fortran output. We are sharing this with
+ -- the standard Fortran output code, so want to be a bit careful about
+ -- how we interact with what the user does independently. We get round
+ -- potential problems by always examining the top element of the stack
+ -- before we push. If the user has redirected output then we alter our
+ -- top value accordingly.
+ fortranOutputStack : Stack String := empty()@(Stack String)
+
+ topFortranOutputStack():String == string(_$fortranOutputFile$Lisp)
+
+ pushFortranOutputStack(fn:FileName):Void ==
+ if empty? fortranOutputStack then
+ push!(string(_$fortranOutputFile$Lisp),fortranOutputStack)
+ else if not(top(fortranOutputStack)=string(_$fortranOutputFile$Lisp)) then
+ pop! fortranOutputStack
+ push!(string(_$fortranOutputFile$Lisp),fortranOutputStack)
+ push!( fn::String,fortranOutputStack)
+ systemCommand concat(["set output fortran quiet ", fn::String])$String
+ void()
+
+ pushFortranOutputStack(fn:String):Void ==
+ if empty? fortranOutputStack then
+ push!(string(_$fortranOutputFile$Lisp),fortranOutputStack)
+ else if not(top(fortranOutputStack)=string(_$fortranOutputFile$Lisp)) then
+ pop! fortranOutputStack
+ push!(string(_$fortranOutputFile$Lisp),fortranOutputStack)
+ push!( fn,fortranOutputStack)
+ systemCommand concat(["set output fortran quiet ", fn])$String
+ void()
+
+ popFortranOutputStack():Void ==
+ if not empty? fortranOutputStack then pop! fortranOutputStack
+ if empty? fortranOutputStack then push!("CONSOLE",fortranOutputStack)
+ systemCommand concat(["set output fortran quiet append ",_
+ top fortranOutputStack])$String
+ void()
+
+ clearFortranOutputStack():Stack String ==
+ fortranOutputStack := empty()@(Stack String)
+
+ showFortranOutputStack():Stack String ==
+ fortranOutputStack
+
+@
+\section{package TEMUTL TemplateUtilities}
+<<package TEMUTL TemplateUtilities>>=
+)abbrev package TEMUTL TemplateUtilities
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: This package provides functions for template manipulation
+TemplateUtilities(): Exports == Implementation where
+
+ Exports == with
+ interpretString : String -> Any
+ ++ interpretString(s) treats a string as a piece of AXIOM input, by
+ ++ parsing and interpreting it.
+ stripCommentsAndBlanks : String -> String
+ ++ stripCommentsAndBlanks(s) treats s as a piece of AXIOM input, and
+ ++ removes comments, and leading and trailing blanks.
+
+ Implementation == add
+
+ import InputForm
+
+ stripC(s:String,u:String):String ==
+ i : Integer := position(u,s,1)
+ i = 0 => s
+ delete(s,i..)
+
+ stripCommentsAndBlanks(s:String):String ==
+ trim(stripC(stripC(s,"++"),"--"),char " ")
+
+ parse(s:String):InputForm ==
+ ncParseFromString(s)$Lisp::InputForm
+
+ interpretString(s:String):Any ==
+ interpret parse s
+
+@
+\section{package MCALCFN MultiVariableCalculusFunctions}
+<<package MCALCFN MultiVariableCalculusFunctions>>=
+)abbrev package MCALCFN MultiVariableCalculusFunctions
+++ Author: Themos Tsikas, Grant Keady
+++ Date Created: December 1992
+++ Date Last Updated: June 1993
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{MultiVariableCalculusFunctions} Package provides several
+++ functions for multivariable calculus.
+++ These include gradient, hessian and jacobian,
+++ divergence and laplacian.
+++ Various forms for banded and sparse storage of matrices are
+++ included.
+MultiVariableCalculusFunctions(S,F,FLAF,FLAS) : Exports == Implementation where
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+
+ S: SetCategory
+ F: PartialDifferentialRing(S)
+ FLAS: FiniteLinearAggregate(S)
+ with finiteAggregate
+ FLAF: FiniteLinearAggregate(F)
+
+ Exports ==> with
+ gradient: (F,FLAS) -> Vector F
+ ++ \spad{gradient(v,xlist)}
+ ++ computes the gradient, the vector of first partial derivatives,
+ ++ of the scalar field v,
+ ++ v a function of the variables listed in xlist.
+ divergence: (FLAF,FLAS) -> F
+ ++ \spad{divergence(vf,xlist)}
+ ++ computes the divergence of the vector field vf,
+ ++ vf a vector function of the variables listed in xlist.
+ laplacian: (F,FLAS) -> F
+ ++ \spad{laplacian(v,xlist)}
+ ++ computes the laplacian of the scalar field v,
+ ++ v a function of the variables listed in xlist.
+ hessian: (F,FLAS) -> Matrix F
+ ++ \spad{hessian(v,xlist)}
+ ++ computes the hessian, the matrix of second partial derivatives,
+ ++ of the scalar field v,
+ ++ v a function of the variables listed in xlist.
+ bandedHessian: (F,FLAS,NNI) -> Matrix F
+ ++ \spad{bandedHessian(v,xlist,k)}
+ ++ computes the hessian, the matrix of second partial derivatives,
+ ++ of the scalar field v,
+ ++ v a function of the variables listed in xlist,
+ ++ k is the semi-bandwidth, the number of nonzero subdiagonals,
+ ++ 2*k+1 being actual bandwidth.
+ ++ Stores the nonzero band in lower triangle in a matrix,
+ ++ dimensions k+1 by #xlist,
+ ++ whose rows are the vectors formed by diagonal, subdiagonal, etc.
+ ++ of the real, full-matrix, hessian.
+ ++ (The notation conforms to LAPACK/NAG-F07 conventions.)
+ -- At one stage it seemed a good idea to help the ASP<n> domains
+ -- with the types of their input arguments and this led to the
+ -- standard Gradient|Hessian|Jacobian functions.
+ --standardJacobian: (Vector(F),List(S)) -> Matrix F
+ -- ++ \spad{jacobian(vf,xlist)}
+ -- ++ computes the jacobian, the matrix of first partial derivatives,
+ -- ++ of the vector field vf,
+ -- ++ vf a vector function of the variables listed in xlist.
+ jacobian: (FLAF,FLAS) -> Matrix F
+ ++ \spad{jacobian(vf,xlist)}
+ ++ computes the jacobian, the matrix of first partial derivatives,
+ ++ of the vector field vf,
+ ++ vf a vector function of the variables listed in xlist.
+ bandedJacobian: (FLAF,FLAS,NNI,NNI) -> Matrix F
+ ++ \spad{bandedJacobian(vf,xlist,kl,ku)}
+ ++ computes the jacobian, the matrix of first partial derivatives,
+ ++ of the vector field vf,
+ ++ vf a vector function of the variables listed in xlist,
+ ++ kl is the number of nonzero subdiagonals,
+ ++ ku is the number of nonzero superdiagonals,
+ ++ kl+ku+1 being actual bandwidth.
+ ++ Stores the nonzero band in a matrix,
+ ++ dimensions kl+ku+1 by #xlist.
+ ++ The upper triangle is in the top ku rows,
+ ++ the diagonal is in row ku+1,
+ ++ the lower triangle in the last kl rows.
+ ++ Entries in a column in the band store correspond to entries
+ ++ in same column of full store.
+ ++ (The notation conforms to LAPACK/NAG-F07 conventions.)
+
+ Implementation ==> add
+ localGradient(v:F,xlist:List(S)):Vector(F) ==
+ vector([D(v,x) for x in xlist])
+ gradient(v,xflas) ==
+ --xlist:List(S) := [xflas(i) for i in 1 .. maxIndex(xflas)]
+ xlist:List(S) := parts(xflas)
+ localGradient(v,xlist)
+ localDivergence(vf:Vector(F),xlist:List(S)):F ==
+ i: PI
+ n: NNI
+ ans: F
+ -- Perhaps should report error if two args of min different
+ n:= min(#(xlist),((maxIndex(vf))::NNI))$NNI
+ ans:= 0
+ for i in 1 .. n repeat ans := ans + D(vf(i),xlist(i))
+ ans
+ divergence(vf,xflas) ==
+ xlist:List(S) := parts(xflas)
+ i: PI
+ n: NNI
+ ans: F
+ -- Perhaps should report error if two args of min different
+ n:= min(#(xlist),((maxIndex(vf))::NNI))$NNI
+ ans:= 0
+ for i in 1 .. n repeat ans := ans + D(vf(i),xlist(i))
+ ans
+ laplacian(v,xflas) ==
+ xlist:List(S) := parts(xflas)
+ gv:Vector(F) := localGradient(v,xlist)
+ localDivergence(gv,xlist)
+ hessian(v,xflas) ==
+ xlist:List(S) := parts(xflas)
+ matrix([[D(v,[x,y]) for x in xlist] for y in xlist])
+ --standardJacobian(vf,xlist) ==
+ -- i: PI
+ -- matrix([[D(vf(i),x) for x in xlist] for i in 1 .. maxIndex(vf)])
+ jacobian(vf,xflas) ==
+ xlist:List(S) := parts(xflas)
+ i: PI
+ matrix([[D(vf(i),x) for x in xlist] for i in 1 .. maxIndex(vf)])
+ bandedHessian(v,xflas,k) ==
+ xlist:List(S) := parts(xflas)
+ j,iw: PI
+ n: NNI
+ bandM: Matrix F
+ n:= #(xlist)
+ bandM:= new(k+1,n,0)
+ for j in 1 .. n repeat setelt(bandM,1,j,D(v,xlist(j),2))
+ for iw in 2 .. (k+1) repeat (_
+ for j in 1 .. (n-iw+1) repeat (_
+ setelt(bandM,iw,j,D(v,[xlist(j),xlist(j+iw-1)])) ) )
+ bandM
+ jacobian(vf,xflas) ==
+ xlist:List(S) := parts(xflas)
+ i: PI
+ matrix([[D(vf(i),x) for x in xlist] for i in 1 .. maxIndex(vf)])
+ bandedJacobian(vf,xflas,kl,ku) ==
+ xlist:List(S) := parts(xflas)
+ j,iw: PI
+ n: NNI
+ bandM: Matrix F
+ n:= #(xlist)
+ bandM:= new(kl+ku+1,n,0)
+ for j in 1 .. n repeat setelt(bandM,ku+1,j,D(vf(j),xlist(j)))
+ for iw in (ku+2) .. (ku+kl+1) repeat (_
+ for j in 1 .. (n-iw+ku+1) repeat (_
+ setelt(bandM,iw,j,D(vf(j+iw-1-ku),xlist(j))) ) )
+ for iw in 1 .. ku repeat (_
+ for j in (ku+2-iw) .. n repeat (_
+ setelt(bandM,iw,j,D(vf(j+iw-1-ku),xlist(j))) ) )
+ bandM
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FCPAK1 FortranCodePackage1>>
+<<package NAGSP NAGLinkSupportPackage>>
+<<package FORT FortranPackage>>
+<<package FOP FortranOutputStackPackage>>
+<<package TEMUTL TemplateUtilities>>
+<<package MCALCFN MultiVariableCalculusFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fortran.spad.pamphlet b/src/algebra/fortran.spad.pamphlet
new file mode 100644
index 00000000..c8d73e94
--- /dev/null
+++ b/src/algebra/fortran.spad.pamphlet
@@ -0,0 +1,1787 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fortran.spad}
+\author{Didier Pinchon, Mike Dewar, William Naylor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain RESULT Result}
+<<domain RESULT Result>>=
+)abbrev domain RESULT Result
+++ Author: Didier Pinchon and Mike Dewar
+++ Date Created: 8 April 1994
+++ Date Last Updated: 28 June 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A domain used to return the results from a call to the NAG
+++ Library. It prints as a list of names and types, though the user may
+++ choose to display values automatically if he or she wishes.
+Result():Exports==Implementation where
+
+ O ==> OutputForm
+
+ Exports ==> TableAggregate(Symbol,Any) with
+ showScalarValues : Boolean -> Boolean
+ ++ showScalarValues(true) forces the values of scalar components to be
+ ++ displayed rather than just their types.
+ showArrayValues : Boolean -> Boolean
+ ++ showArrayValues(true) forces the values of array components to be
+ ++ displayed rather than just their types.
+ finiteAggregate
+
+ Implementation ==> Table(Symbol,Any) add
+
+ -- Constant
+ colon := ": "::Symbol::O
+ elide := "..."::Symbol::O
+
+ -- Flags
+ showScalarValuesFlag : Boolean := false
+ showArrayValuesFlag : Boolean := false
+
+ cleanUpDomainForm(d:SExpression):O ==
+ not list? d => d::O
+ #d=1 => (car d)::O
+ -- If the car is an atom then we have a domain constructor, if not
+ -- then we have some kind of value. Since we often can't print these
+ -- ****ers we just elide them.
+ not atom? car d => elide
+ prefix((car d)::O,[cleanUpDomainForm(u) for u in destruct cdr(d)]$List(O))
+
+ display(v:Any,d:SExpression):O ==
+ not list? d => error "Domain form is non-list"
+ #d=1 =>
+ showScalarValuesFlag => objectOf v
+ cleanUpDomainForm d
+ car(d) = convert("Complex"::Symbol)@SExpression =>
+ showScalarValuesFlag => objectOf v
+ cleanUpDomainForm d
+ showArrayValuesFlag => objectOf v
+ cleanUpDomainForm d
+
+ makeEntry(k:Symbol,v:Any):O ==
+ hconcat [k::O,colon,display(v,dom v)]
+
+ coerce(r:%):O ==
+ bracket [makeEntry(key,r.key) for key in reverse! keys(r)]
+
+ showArrayValues(b:Boolean):Boolean == showArrayValuesFlag := b
+ showScalarValues(b:Boolean):Boolean == showScalarValuesFlag := b
+
+@
+\section{domain FC FortranCode}
+<<domain FC FortranCode>>=
+)abbrev domain FC FortranCode
+-- The FortranCode domain is used to represent operations which are to be
+-- translated into FORTRAN.
+++ Author: Mike Dewar
+++ Date Created: April 1991
+++ Date Last Updated: 22 March 1994
+++ 26 May 1994 Added common, MCD
+++ 21 June 1994 Changed print to printStatement, MCD
+++ 30 June 1994 Added stop, MCD
+++ 12 July 1994 Added assign for String, MCD
+++ 9 January 1995 Added fortran2Lines to getCall, MCD
+++ Basic Operations:
+++ Related Constructors: FortranProgram, Switch, FortranType
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain builds representations of program code segments for use with
+++ the FortranProgram domain.
+FortranCode(): public == private where
+ L ==> List
+ PI ==> PositiveInteger
+ PIN ==> Polynomial Integer
+ SEX ==> SExpression
+ O ==> OutputForm
+ OP ==> Union(Null:"null",
+ Assignment:"assignment",
+ Conditional:"conditional",
+ Return:"return",
+ Block:"block",
+ Comment:"comment",
+ Call:"call",
+ For:"for",
+ While:"while",
+ Repeat:"repeat",
+ Goto:"goto",
+ Continue:"continue",
+ ArrayAssignment:"arrayAssignment",
+ Save:"save",
+ Stop:"stop",
+ Common:"common",
+ Print:"print")
+ ARRAYASS ==> Record(var:Symbol, rand:O, ints2Floats?:Boolean)
+ EXPRESSION ==> Record(ints2Floats?:Boolean,expr:O)
+ ASS ==> Record(var:Symbol,
+ arrayIndex:L PIN,
+ rand:EXPRESSION
+ )
+ COND ==> Record(switch: Switch(),
+ thenClause: $,
+ elseClause: $
+ )
+ RETURN ==> Record(empty?:Boolean,value:EXPRESSION)
+ BLOCK ==> List $
+ COMMENT ==> List String
+ COMMON ==> Record(name:Symbol,contents:List Symbol)
+ CALL ==> String
+ FOR ==> Record(range:SegmentBinding PIN, span:PIN, body:$)
+ LABEL ==> SingleInteger
+ LOOP ==> Record(switch:Switch(),body:$)
+ PRINTLIST ==> List O
+ OPREC ==> Union(nullBranch:"null", assignmentBranch:ASS,
+ arrayAssignmentBranch:ARRAYASS,
+ conditionalBranch:COND, returnBranch:RETURN,
+ blockBranch:BLOCK, commentBranch:COMMENT, callBranch:CALL,
+ forBranch:FOR, labelBranch:LABEL, loopBranch:LOOP,
+ commonBranch:COMMON, printBranch:PRINTLIST)
+
+ public == SetCategory with
+ coerce: $ -> O
+ ++ coerce(f) returns an object of type OutputForm.
+ forLoop: (SegmentBinding PIN,$) -> $
+ ++ forLoop(i=1..10,c) creates a representation of a FORTRAN DO loop with
+ ++ \spad{i} ranging over the values 1 to 10.
+ forLoop: (SegmentBinding PIN,PIN,$) -> $
+ ++ forLoop(i=1..10,n,c) creates a representation of a FORTRAN DO loop with
+ ++ \spad{i} ranging over the values 1 to 10 by n.
+ whileLoop: (Switch,$) -> $
+ ++ whileLoop(s,c) creates a while loop in FORTRAN.
+ repeatUntilLoop: (Switch,$) -> $
+ ++ repeatUntilLoop(s,c) creates a repeat ... until loop in FORTRAN.
+ goto: SingleInteger -> $
+ ++ goto(l) creates a representation of a FORTRAN GOTO statement
+ continue: SingleInteger -> $
+ ++ continue(l) creates a representation of a FORTRAN CONTINUE labelled
+ ++ with l
+ comment: String -> $
+ ++ comment(s) creates a representation of the String s as a single FORTRAN
+ ++ comment.
+ comment: List String -> $
+ ++ comment(s) creates a representation of the Strings s as a multi-line
+ ++ FORTRAN comment.
+ call: String -> $
+ ++ call(s) creates a representation of a FORTRAN CALL statement
+ returns: () -> $
+ ++ returns() creates a representation of a FORTRAN RETURN statement.
+ returns: Expression MachineFloat -> $
+ ++ returns(e) creates a representation of a FORTRAN RETURN statement
+ ++ with a returned value.
+ returns: Expression MachineInteger -> $
+ ++ returns(e) creates a representation of a FORTRAN RETURN statement
+ ++ with a returned value.
+ returns: Expression MachineComplex -> $
+ ++ returns(e) creates a representation of a FORTRAN RETURN statement
+ ++ with a returned value.
+ returns: Expression Float -> $
+ ++ returns(e) creates a representation of a FORTRAN RETURN statement
+ ++ with a returned value.
+ returns: Expression Integer -> $
+ ++ returns(e) creates a representation of a FORTRAN RETURN statement
+ ++ with a returned value.
+ returns: Expression Complex Float -> $
+ ++ returns(e) creates a representation of a FORTRAN RETURN statement
+ ++ with a returned value.
+ cond: (Switch,$) -> $
+ ++ cond(s,e) creates a representation of the FORTRAN expression
+ ++ IF (s) THEN e.
+ cond: (Switch,$,$) -> $
+ ++ cond(s,e,f) creates a representation of the FORTRAN expression
+ ++ IF (s) THEN e ELSE f.
+ assign: (Symbol,String) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Expression MachineInteger) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Expression MachineFloat) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Expression MachineComplex) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix MachineInteger) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix MachineFloat) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix MachineComplex) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector MachineInteger) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector MachineFloat) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector MachineComplex) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix Expression MachineInteger) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix Expression MachineFloat) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix Expression MachineComplex) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector Expression MachineInteger) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector Expression MachineFloat) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector Expression MachineComplex) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,L PIN,Expression MachineInteger) -> $
+ ++ assign(x,l,y) creates a representation of the assignment of \spad{y}
+ ++ to the \spad{l}'th element of array \spad{x} (\spad{l} is a list of
+ ++ indices).
+ assign: (Symbol,L PIN,Expression MachineFloat) -> $
+ ++ assign(x,l,y) creates a representation of the assignment of \spad{y}
+ ++ to the \spad{l}'th element of array \spad{x} (\spad{l} is a list of
+ ++ indices).
+ assign: (Symbol,L PIN,Expression MachineComplex) -> $
+ ++ assign(x,l,y) creates a representation of the assignment of \spad{y}
+ ++ to the \spad{l}'th element of array \spad{x} (\spad{l} is a list of
+ ++ indices).
+ assign: (Symbol,Expression Integer) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Expression Float) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Expression Complex Float) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix Expression Integer) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix Expression Float) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Matrix Expression Complex Float) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector Expression Integer) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector Expression Float) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,Vector Expression Complex Float) -> $
+ ++ assign(x,y) creates a representation of the FORTRAN expression
+ ++ x=y.
+ assign: (Symbol,L PIN,Expression Integer) -> $
+ ++ assign(x,l,y) creates a representation of the assignment of \spad{y}
+ ++ to the \spad{l}'th element of array \spad{x} (\spad{l} is a list of
+ ++ indices).
+ assign: (Symbol,L PIN,Expression Float) -> $
+ ++ assign(x,l,y) creates a representation of the assignment of \spad{y}
+ ++ to the \spad{l}'th element of array \spad{x} (\spad{l} is a list of
+ ++ indices).
+ assign: (Symbol,L PIN,Expression Complex Float) -> $
+ ++ assign(x,l,y) creates a representation of the assignment of \spad{y}
+ ++ to the \spad{l}'th element of array \spad{x} (\spad{l} is a list of
+ ++ indices).
+ block: List($) -> $
+ ++ block(l) creates a representation of the statements in l as a block.
+ stop: () -> $
+ ++ stop() creates a representation of a STOP statement.
+ save: () -> $
+ ++ save() creates a representation of a SAVE statement.
+ printStatement: List O -> $
+ ++ printStatement(l) creates a representation of a PRINT statement.
+ common: (Symbol,List Symbol) -> $
+ ++ common(name,contents) creates a representation a named common block.
+ operation: $ -> OP
+ ++ operation(f) returns the name of the operation represented by \spad{f}.
+ code: $ -> OPREC
+ ++ code(f) returns the internal representation of the object represented
+ ++ by \spad{f}.
+ printCode: $ -> Void
+ ++ printCode(f) prints out \spad{f} in FORTRAN notation.
+ getCode: $ -> SEX
+ ++ getCode(f) returns a Lisp list of strings representing \spad{f}
+ ++ in Fortran notation. This is used by the FortranProgram domain.
+ setLabelValue:SingleInteger -> SingleInteger
+ ++ setLabelValue(i) resets the counter which produces labels to i
+
+ private == add
+ import Void
+ import ASS
+ import COND
+ import RETURN
+ import L PIN
+ import O
+ import SEX
+ import FortranType
+ import TheSymbolTable
+
+ Rep := Record(op: OP, data: OPREC)
+
+ -- We need to be able to generate unique labels
+ labelValue:SingleInteger := 25000::SingleInteger
+ setLabelValue(u:SingleInteger):SingleInteger == labelValue := u
+ newLabel():SingleInteger ==
+ labelValue := labelValue + 1$SingleInteger
+ labelValue
+
+ commaSep(l:List String):List(String) ==
+ [(l.1),:[:[",",u] for u in rest(l)]]
+
+ getReturn(rec:RETURN):SEX ==
+ returnToken : SEX := convert("RETURN"::Symbol::O)$SEX
+ elt(rec,empty?)$RETURN =>
+ getStatement(returnToken,NIL$Lisp)$Lisp
+ rt : EXPRESSION := elt(rec,value)$RETURN
+ rv : O := elt(rt,expr)$EXPRESSION
+ getStatement([returnToken,convert(rv)$SEX]$Lisp,
+ elt(rt,ints2Floats?)$EXPRESSION )$Lisp
+
+ getStop():SEX ==
+ fortran2Lines(LIST("STOP")$Lisp)$Lisp
+
+ getSave():SEX ==
+ fortran2Lines(LIST("SAVE")$Lisp)$Lisp
+
+ getCommon(u:COMMON):SEX ==
+ fortran2Lines(APPEND(LIST("COMMON"," /",string (u.name),"/ ")$Lisp,_
+ addCommas(u.contents)$Lisp)$Lisp)$Lisp
+
+ getPrint(l:PRINTLIST):SEX ==
+ ll : SEX := LIST("PRINT*")$Lisp
+ for i in l repeat
+ ll := APPEND(ll,CONS(",",expression2Fortran(i)$Lisp)$Lisp)$Lisp
+ fortran2Lines(ll)$Lisp
+
+ getBlock(rec:BLOCK):SEX ==
+ indentFortLevel(convert(1@Integer)$SEX)$Lisp
+ expr : SEX := LIST()$Lisp
+ for u in rec repeat
+ expr := APPEND(expr,getCode(u))$Lisp
+ indentFortLevel(convert(-1@Integer)$SEX)$Lisp
+ expr
+
+ getBody(f:$):SEX ==
+ operation(f) case Block => getCode f
+ indentFortLevel(convert(1@Integer)$SEX)$Lisp
+ expr := getCode f
+ indentFortLevel(convert(-1@Integer)$SEX)$Lisp
+ expr
+
+ getElseIf(f:$):SEX ==
+ rec := code f
+ expr :=
+ fortFormatElseIf(elt(rec.conditionalBranch,switch)$COND::O)$Lisp
+ expr :=
+ APPEND(expr,getBody elt(rec.conditionalBranch,thenClause)$COND)$Lisp
+ elseBranch := elt(rec.conditionalBranch,elseClause)$COND
+ not(operation(elseBranch) case Null) =>
+ operation(elseBranch) case Conditional =>
+ APPEND(expr,getElseIf elseBranch)$Lisp
+ expr := APPEND(expr, getStatement(ELSE::O,NIL$Lisp)$Lisp)$Lisp
+ expr := APPEND(expr, getBody elseBranch)$Lisp
+ expr
+
+ getContinue(label:SingleInteger):SEX ==
+ lab : O := label::O
+ if (width(lab) > 6) then error "Label too big"
+ cnt : O := "CONTINUE"::O
+ --sp : O := hspace(6-width lab)
+ sp : O := hspace(_$fortIndent$Lisp -width lab)
+ LIST(STRCONC(STRINGIMAGE(lab)$Lisp,sp,cnt)$Lisp)$Lisp
+
+ getGoto(label:SingleInteger):SEX ==
+ fortran2Lines(
+ LIST(STRCONC("GOTO ",STRINGIMAGE(label::O)$Lisp)$Lisp)$Lisp)$Lisp
+
+ getRepeat(repRec:LOOP):SEX ==
+ sw : Switch := NOT elt(repRec,switch)$LOOP
+ lab := newLabel()
+ bod := elt(repRec,body)$LOOP
+ APPEND(getContinue lab,getBody bod,
+ fortFormatIfGoto(sw::O,lab)$Lisp)$Lisp
+
+ getWhile(whileRec:LOOP):SEX ==
+ sw := NOT elt(whileRec,switch)$LOOP
+ lab1 := newLabel()
+ lab2 := newLabel()
+ bod := elt(whileRec,body)$LOOP
+ APPEND(fortFormatLabelledIfGoto(sw::O,lab1,lab2)$Lisp,
+ getBody bod, getBody goto(lab1), getContinue lab2)$Lisp
+
+ getArrayAssign(rec:ARRAYASS):SEX ==
+ getfortarrayexp((rec.var)::O,rec.rand,rec.ints2Floats?)$Lisp
+
+ getAssign(rec:ASS):SEX ==
+ indices : L PIN := elt(rec,arrayIndex)$ASS
+ if indices = []::(L PIN) then
+ lhs := elt(rec,var)$ASS::O
+ else
+ lhs := cons(elt(rec,var)$ASS::PIN,indices)::O
+ -- Must get the index brackets correct:
+ lhs := (cdr car cdr convert(lhs)$SEX::SEX)::O -- Yuck!
+ elt(elt(rec,rand)$ASS,ints2Floats?)$EXPRESSION =>
+ assignment2Fortran1(lhs,elt(elt(rec,rand)$ASS,expr)$EXPRESSION)$Lisp
+ integerAssignment2Fortran1(lhs,elt(elt(rec,rand)$ASS,expr)$EXPRESSION)$Lisp
+
+ getCond(rec:COND):SEX ==
+ expr := APPEND(fortFormatIf(elt(rec,switch)$COND::O)$Lisp,
+ getBody elt(rec,thenClause)$COND)$Lisp
+ elseBranch := elt(rec,elseClause)$COND
+ if not(operation(elseBranch) case Null) then
+ operation(elseBranch) case Conditional =>
+ expr := APPEND(expr,getElseIf elseBranch)$Lisp
+ expr := APPEND(expr,getStatement(ELSE::O,NIL$Lisp)$Lisp,
+ getBody elseBranch)$Lisp
+ APPEND(expr,getStatement(ENDIF::O,NIL$Lisp)$Lisp)$Lisp
+
+ getComment(rec:COMMENT):SEX ==
+ convert([convert(concat("C ",c)$String)@SEX for c in rec])@SEX
+
+ getCall(rec:CALL):SEX ==
+ expr := concat("CALL ",rec)$String
+ #expr > 1320 => error "Fortran CALL too large"
+ fortran2Lines(convert([convert(expr)@SEX ])@SEX)$Lisp
+
+ getFor(rec:FOR):SEX ==
+ rnge : SegmentBinding PIN := elt(rec,range)$FOR
+ increment : PIN := elt(rec,span)$FOR
+ lab : SingleInteger := newLabel()
+ declare!(variable rnge,fortranInteger())
+ expr := fortFormatDo(variable rnge, (lo segment rnge)::O,_
+ (hi segment rnge)::O,increment::O,lab)$Lisp
+ APPEND(expr, getBody elt(rec,body)$FOR, getContinue(lab))$Lisp
+
+ getCode(f:$):SEX ==
+ opp:OP := operation f
+ rec:OPREC:= code f
+ opp case Assignment => getAssign(rec.assignmentBranch)
+ opp case ArrayAssignment => getArrayAssign(rec.arrayAssignmentBranch)
+ opp case Conditional => getCond(rec.conditionalBranch)
+ opp case Return => getReturn(rec.returnBranch)
+ opp case Block => getBlock(rec.blockBranch)
+ opp case Comment => getComment(rec.commentBranch)
+ opp case Call => getCall(rec.callBranch)
+ opp case For => getFor(rec.forBranch)
+ opp case Continue => getContinue(rec.labelBranch)
+ opp case Goto => getGoto(rec.labelBranch)
+ opp case Repeat => getRepeat(rec.loopBranch)
+ opp case While => getWhile(rec.loopBranch)
+ opp case Save => getSave()
+ opp case Stop => getStop()
+ opp case Print => getPrint(rec.printBranch)
+ opp case Common => getCommon(rec.commonBranch)
+ error "Unsupported program construct."
+ convert(0)@SEX
+
+ printCode(f:$):Void ==
+ displayLines1$Lisp getCode f
+ void()$Void
+
+ code (f:$):OPREC ==
+ elt(f,data)$Rep
+
+ operation (f:$):OP ==
+ elt(f,op)$Rep
+
+ common(name:Symbol,contents:List Symbol):$ ==
+ [["common"]$OP,[[name,contents]$COMMON]$OPREC]$Rep
+
+ stop():$ ==
+ [["stop"]$OP,["null"]$OPREC]$Rep
+
+ save():$ ==
+ [["save"]$OP,["null"]$OPREC]$Rep
+
+ printStatement(l:List O):$ ==
+ [["print"]$OP,[l]$OPREC]$Rep
+
+ comment(s:List String):$ ==
+ [["comment"]$OP,[s]$OPREC]$Rep
+
+ comment(s:String):$ ==
+ [["comment"]$OP,[list s]$OPREC]$Rep
+
+ forLoop(r:SegmentBinding PIN,body:$):$ ==
+ [["for"]$OP,[[r,(incr segment r)::PIN,body]$FOR]$OPREC]$Rep
+
+ forLoop(r:SegmentBinding PIN,increment:PIN,body:$):$ ==
+ [["for"]$OP,[[r,increment,body]$FOR]$OPREC]$Rep
+
+ goto(l:SingleInteger):$ ==
+ [["goto"]$OP,[l]$OPREC]$Rep
+
+ continue(l:SingleInteger):$ ==
+ [["continue"]$OP,[l]$OPREC]$Rep
+
+ whileLoop(sw:Switch,b:$):$ ==
+ [["while"]$OP,[[sw,b]$LOOP]$OPREC]$Rep
+
+ repeatUntilLoop(sw:Switch,b:$):$ ==
+ [["repeat"]$OP,[[sw,b]$LOOP]$OPREC]$Rep
+
+ returns():$ ==
+ v := [false,0::O]$EXPRESSION
+ [["return"]$OP,[[true,v]$RETURN]$OPREC]$Rep
+
+ returns(v:Expression MachineInteger):$ ==
+ [["return"]$OP,[[false,[false,v::O]$EXPRESSION]$RETURN]$OPREC]$Rep
+
+ returns(v:Expression MachineFloat):$ ==
+ [["return"]$OP,[[false,[false,v::O]$EXPRESSION]$RETURN]$OPREC]$Rep
+
+ returns(v:Expression MachineComplex):$ ==
+ [["return"]$OP,[[false,[false,v::O]$EXPRESSION]$RETURN]$OPREC]$Rep
+
+ returns(v:Expression Integer):$ ==
+ [["return"]$OP,[[false,[false,v::O]$EXPRESSION]$RETURN]$OPREC]$Rep
+
+ returns(v:Expression Float):$ ==
+ [["return"]$OP,[[false,[false,v::O]$EXPRESSION]$RETURN]$OPREC]$Rep
+
+ returns(v:Expression Complex Float):$ ==
+ [["return"]$OP,[[false,[false,v::O]$EXPRESSION]$RETURN]$OPREC]$Rep
+
+ block(l:List $):$ ==
+ [["block"]$OP,[l]$OPREC]$Rep
+
+ cond(sw:Switch,thenC:$):$ ==
+ [["conditional"]$OP,
+ [[sw,thenC,[["null"]$OP,["null"]$OPREC]$Rep]$COND]$OPREC]$Rep
+
+ cond(sw:Switch,thenC:$,elseC:$):$ ==
+ [["conditional"]$OP,[[sw,thenC,elseC]$COND]$OPREC]$Rep
+
+ coerce(f : $):O ==
+ (f.op)::O
+
+ assign(v:Symbol,rhs:String):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[false,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix MachineInteger):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,false]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix MachineFloat):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix MachineComplex):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector MachineInteger):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,false]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector MachineFloat):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector MachineComplex):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix Expression MachineInteger):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,false]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix Expression MachineFloat):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix Expression MachineComplex):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector Expression MachineInteger):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,false]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector Expression MachineFloat):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector Expression MachineComplex):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,index:L PIN,rhs:Expression MachineInteger):$ ==
+ [["assignment"]$OP,[[v,index,[false,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,index:L PIN,rhs:Expression MachineFloat):$ ==
+ [["assignment"]$OP,[[v,index,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,index:L PIN,rhs:Expression MachineComplex):$ ==
+ [["assignment"]$OP,[[v,index,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Expression MachineInteger):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[false,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Expression MachineFloat):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Expression MachineComplex):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix Expression Integer):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,false]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix Expression Float):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Matrix Expression Complex Float):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector Expression Integer):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,false]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector Expression Float):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Vector Expression Complex Float):$ ==
+ [["arrayAssignment"]$OP,[[v,rhs::O,true]$ARRAYASS]$OPREC]$Rep
+
+ assign(v:Symbol,index:L PIN,rhs:Expression Integer):$ ==
+ [["assignment"]$OP,[[v,index,[false,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,index:L PIN,rhs:Expression Float):$ ==
+ [["assignment"]$OP,[[v,index,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,index:L PIN,rhs:Expression Complex Float):$ ==
+ [["assignment"]$OP,[[v,index,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Expression Integer):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[false,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Expression Float):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ assign(v:Symbol,rhs:Expression Complex Float):$ ==
+ [["assignment"]$OP,[[v,nil()::L PIN,[true,rhs::O]$EXPRESSION]$ASS]$OPREC]$Rep
+
+ call(s:String):$ ==
+ [["call"]$OP,[s]$OPREC]$Rep
+
+@
+\section{domain FORTRAN FortranProgram}
+<<domain FORTRAN FortranProgram>>=
+)abbrev domain FORTRAN FortranProgram
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated: 13 January 1994
+++ 23 January 1995 Added support for intrinsic functions
+++ Basic Operations:
+++ Related Constructors: FortranType, FortranCode, Switch
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \axiomType{FortranProgram} allows the user to build and manipulate simple
+++ models of FORTRAN subprograms. These can then be transformed into actual FORTRAN
+++ notation.
+FortranProgram(name,returnType,arguments,symbols): Exports == Implement where
+ name : Symbol
+ returnType : Union(fst:FortranScalarType,void:"void")
+ arguments : List Symbol
+ symbols : SymbolTable
+
+ FC ==> FortranCode
+ EXPR ==> Expression
+ INT ==> Integer
+ CMPX ==> Complex
+ MINT ==> MachineInteger
+ MFLOAT ==> MachineFloat
+ MCMPLX ==> MachineComplex
+ REP ==> Record(localSymbols : SymbolTable, code : List FortranCode)
+
+ Exports ==> FortranProgramCategory with
+ coerce : FortranCode -> $
+ ++ coerce(fc) \undocumented{}
+ coerce : List FortranCode -> $
+ ++ coerce(lfc) \undocumented{}
+ coerce : REP -> $
+ ++ coerce(r) \undocumented{}
+ coerce : EXPR MINT -> $
+ ++ coerce(e) \undocumented{}
+ coerce : EXPR MFLOAT -> $
+ ++ coerce(e) \undocumented{}
+ coerce : EXPR MCMPLX -> $
+ ++ coerce(e) \undocumented{}
+ coerce : Equation EXPR MINT -> $
+ ++ coerce(eq) \undocumented{}
+ coerce : Equation EXPR MFLOAT -> $
+ ++ coerce(eq) \undocumented{}
+ coerce : Equation EXPR MCMPLX -> $
+ ++ coerce(eq) \undocumented{}
+ coerce : EXPR INT -> $
+ ++ coerce(e) \undocumented{}
+ coerce : EXPR Float -> $
+ ++ coerce(e) \undocumented{}
+ coerce : EXPR CMPX Float -> $
+ ++ coerce(e) \undocumented{}
+ coerce : Equation EXPR INT -> $
+ ++ coerce(eq) \undocumented{}
+ coerce : Equation EXPR Float -> $
+ ++ coerce(eq) \undocumented{}
+ coerce : Equation EXPR CMPX Float -> $
+ ++ coerce(eq) \undocumented{}
+
+ Implement ==> add
+
+ Rep := REP
+
+ import SExpression
+ import TheSymbolTable
+ import FortranCode
+
+ makeRep(b:List FortranCode):$ ==
+ construct(empty()$SymbolTable,b)$REP
+
+ codeFrom(u:$):List FortranCode ==
+ elt(u::Rep,code)$REP
+
+ outputAsFortran(p:$):Void ==
+ setLabelValue(25000::SingleInteger)$FC
+ -- Do this first to catch any extra type declarations:
+ tempName := "FPTEMP"::Symbol
+ newSubProgram(tempName)
+ initialiseIntrinsicList()$Lisp
+ body : List SExpression := [getCode(l)$FortranCode for l in codeFrom(p)]
+ intrinsics : SExpression := getIntrinsicList()$Lisp
+ endSubProgram()
+ fortFormatHead(returnType::OutputForm, name::OutputForm, _
+ arguments::OutputForm)$Lisp
+ printTypes(symbols)$SymbolTable
+ printTypes((p::Rep).localSymbols)$SymbolTable
+ printTypes(tempName)$TheSymbolTable
+ fortFormatIntrinsics(intrinsics)$Lisp
+ clearTheSymbolTable(tempName)
+ for expr in body repeat displayLines1(expr)$Lisp
+ dispStatement(END::OutputForm)$Lisp
+ void()$Void
+
+ mkString(l:List Symbol):String ==
+ unparse(convert(l::OutputForm)@InputForm)$InputForm
+
+ checkVariables(user:List Symbol,target:List Symbol):Void ==
+ -- We don't worry about whether the user has subscripted the
+ -- variables or not.
+ setDifference(map(name$Symbol,user),target) ^= empty()$List(Symbol) =>
+ s1 : String := mkString(user)
+ s2 : String := mkString(target)
+ error ["Incompatible variable lists:", s1, s2]
+ void()$Void
+
+ coerce(u:EXPR MINT) : $ ==
+ checkVariables(variables(u)$EXPR(MINT),arguments)
+ l : List(FC) := [assign(name,u)$FC,returns()$FC]
+ makeRep l
+
+ coerce(u:Equation EXPR MINT) : $ ==
+ retractIfCan(lhs u)@Union(Kernel(EXPR MINT),"failed") case "failed" =>
+ error "left hand side is not a kernel"
+ vList : List Symbol := variables lhs u
+ #vList ^= #arguments =>
+ error "Incorrect number of arguments"
+ veList : List EXPR MINT := [w::EXPR(MINT) for w in vList]
+ aeList : List EXPR MINT := [w::EXPR(MINT) for w in arguments]
+ eList : List Equation EXPR MINT :=
+ [equation(w,v) for w in veList for v in aeList]
+ (subst(rhs u,eList))::$
+
+ coerce(u:EXPR MFLOAT) : $ ==
+ checkVariables(variables(u)$EXPR(MFLOAT),arguments)
+ l : List(FC) := [assign(name,u)$FC,returns()$FC]
+ makeRep l
+
+ coerce(u:Equation EXPR MFLOAT) : $ ==
+ retractIfCan(lhs u)@Union(Kernel(EXPR MFLOAT),"failed") case "failed" =>
+ error "left hand side is not a kernel"
+ vList : List Symbol := variables lhs u
+ #vList ^= #arguments =>
+ error "Incorrect number of arguments"
+ veList : List EXPR MFLOAT := [w::EXPR(MFLOAT) for w in vList]
+ aeList : List EXPR MFLOAT := [w::EXPR(MFLOAT) for w in arguments]
+ eList : List Equation EXPR MFLOAT :=
+ [equation(w,v) for w in veList for v in aeList]
+ (subst(rhs u,eList))::$
+
+ coerce(u:EXPR MCMPLX) : $ ==
+ checkVariables(variables(u)$EXPR(MCMPLX),arguments)
+ l : List(FC) := [assign(name,u)$FC,returns()$FC]
+ makeRep l
+
+ coerce(u:Equation EXPR MCMPLX) : $ ==
+ retractIfCan(lhs u)@Union(Kernel EXPR MCMPLX,"failed") case "failed"=>
+ error "left hand side is not a kernel"
+ vList : List Symbol := variables lhs u
+ #vList ^= #arguments =>
+ error "Incorrect number of arguments"
+ veList : List EXPR MCMPLX := [w::EXPR(MCMPLX) for w in vList]
+ aeList : List EXPR MCMPLX := [w::EXPR(MCMPLX) for w in arguments]
+ eList : List Equation EXPR MCMPLX :=
+ [equation(w,v) for w in veList for v in aeList]
+ (subst(rhs u,eList))::$
+
+
+ coerce(u:REP):$ ==
+ u@Rep
+
+ coerce(u:$):OutputForm ==
+ coerce(name)$Symbol
+
+ coerce(c:List FortranCode):$ ==
+ makeRep c
+
+ coerce(c:FortranCode):$ ==
+ makeRep [c]
+
+ coerce(u:EXPR INT) : $ ==
+ checkVariables(variables(u)$EXPR(INT),arguments)
+ l : List(FC) := [assign(name,u)$FC,returns()$FC]
+ makeRep l
+
+ coerce(u:Equation EXPR INT) : $ ==
+ retractIfCan(lhs u)@Union(Kernel(EXPR INT),"failed") case "failed" =>
+ error "left hand side is not a kernel"
+ vList : List Symbol := variables lhs u
+ #vList ^= #arguments =>
+ error "Incorrect number of arguments"
+ veList : List EXPR INT := [w::EXPR(INT) for w in vList]
+ aeList : List EXPR INT := [w::EXPR(INT) for w in arguments]
+ eList : List Equation EXPR INT :=
+ [equation(w,v) for w in veList for v in aeList]
+ (subst(rhs u,eList))::$
+
+ coerce(u:EXPR Float) : $ ==
+ checkVariables(variables(u)$EXPR(Float),arguments)
+ l : List(FC) := [assign(name,u)$FC,returns()$FC]
+ makeRep l
+
+ coerce(u:Equation EXPR Float) : $ ==
+ retractIfCan(lhs u)@Union(Kernel(EXPR Float),"failed") case "failed" =>
+ error "left hand side is not a kernel"
+ vList : List Symbol := variables lhs u
+ #vList ^= #arguments =>
+ error "Incorrect number of arguments"
+ veList : List EXPR Float := [w::EXPR(Float) for w in vList]
+ aeList : List EXPR Float := [w::EXPR(Float) for w in arguments]
+ eList : List Equation EXPR Float :=
+ [equation(w,v) for w in veList for v in aeList]
+ (subst(rhs u,eList))::$
+
+ coerce(u:EXPR Complex Float) : $ ==
+ checkVariables(variables(u)$EXPR(Complex Float),arguments)
+ l : List(FC) := [assign(name,u)$FC,returns()$FC]
+ makeRep l
+
+ coerce(u:Equation EXPR CMPX Float) : $ ==
+ retractIfCan(lhs u)@Union(Kernel EXPR CMPX Float,"failed") case "failed"=>
+ error "left hand side is not a kernel"
+ vList : List Symbol := variables lhs u
+ #vList ^= #arguments =>
+ error "Incorrect number of arguments"
+ veList : List EXPR CMPX Float := [w::EXPR(CMPX Float) for w in vList]
+ aeList : List EXPR CMPX Float := [w::EXPR(CMPX Float) for w in arguments]
+ eList : List Equation EXPR CMPX Float :=
+ [equation(w,v) for w in veList for v in aeList]
+ (subst(rhs u,eList))::$
+
+@
+\section{domain M3D ThreeDimensionalMatrix}
+<<domain M3D ThreeDimensionalMatrix>>=
+)abbrev domain M3D ThreeDimensionalMatrix
+++ Author: William Naylor
+++ Date Created: 20 October 1993
+++ Date Last Updated: 20 May 1994
+++ BasicFunctions:
+++ Related Constructors: Matrix
+++ Also See: PrimitiveArray
+++ AMS Classification:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents three dimensional matrices over a general object type
+ThreeDimensionalMatrix(R) : Exports == Implementation where
+
+ R : SetCategory
+ L ==> List
+ NNI ==> NonNegativeInteger
+ A1AGG ==> OneDimensionalArrayAggregate
+ ARRAY1 ==> OneDimensionalArray
+ PA ==> PrimitiveArray
+ INT ==> Integer
+ PI ==> PositiveInteger
+
+ Exports ==> HomogeneousAggregate(R) with
+
+ if R has Ring then
+ zeroMatrix : (NNI,NNI,NNI) -> $
+ ++ zeroMatrix(i,j,k) create a matrix with all zero terms
+ identityMatrix : (NNI) -> $
+ ++ identityMatrix(n) create an identity matrix
+ ++ we note that this must be square
+ plus : ($,$) -> $
+ ++ plus(x,y) adds two matrices, term by term
+ ++ we note that they must be the same size
+ construct : (L L L R) -> $
+ ++ construct(lll) creates a 3-D matrix from a List List List R lll
+ elt : ($,NNI,NNI,NNI) -> R
+ ++ elt(x,i,j,k) extract an element from the matrix x
+ setelt! :($,NNI,NNI,NNI,R) -> R
+ ++ setelt!(x,i,j,k,s) (or x.i.j.k:=s) sets a specific element of the array to some value of type R
+ coerce : (PA PA PA R) -> $
+ ++ coerce(p) moves from the representation type
+ ++ (PrimitiveArray PrimitiveArray PrimitiveArray R)
+ ++ to the domain
+ coerce : $ -> (PA PA PA R)
+ ++ coerce(x) moves from the domain to the representation type
+ matrixConcat3D : (Symbol,$,$) -> $
+ ++ matrixConcat3D(s,x,y) concatenates two 3-D matrices along a specified axis
+ matrixDimensions : $ -> Vector NNI
+ ++ matrixDimensions(x) returns the dimensions of a matrix
+
+ Implementation ==> (PA PA PA R) add
+
+ import (PA PA PA R)
+ import (PA PA R)
+ import (PA R)
+ import R
+
+ matrix1,matrix2,resultMatrix : $
+
+ -- function to concatenate two matrices
+ -- the first argument must be a symbol, which is either i,j or k
+ -- to specify the direction in which the concatenation is to take place
+ matrixConcat3D(dir : Symbol,mat1 : $,mat2 : $) : $ ==
+ ^((dir = (i::Symbol)) or (dir = (j::Symbol)) or (dir = (k::Symbol)))_
+ => error "the axis of concatenation must be i,j or k"
+ mat1Dim := matrixDimensions(mat1)
+ mat2Dim := matrixDimensions(mat2)
+ iDim1 := mat1Dim.1
+ jDim1 := mat1Dim.2
+ kDim1 := mat1Dim.3
+ iDim2 := mat2Dim.1
+ jDim2 := mat2Dim.2
+ kDim2 := mat2Dim.3
+ matRep1 : (PA PA PA R) := copy(mat1 :: (PA PA PA R))$(PA PA PA R)
+ matRep2 : (PA PA PA R) := copy(mat2 :: (PA PA PA R))$(PA PA PA R)
+ retVal : $
+
+ if (dir = (i::Symbol)) then
+ -- j,k dimensions must agree
+ if (^((jDim1 = jDim2) and (kDim1=kDim2)))
+ then
+ error "jxk do not agree"
+ else
+ retVal := (coerce(concat(matRep1,matRep2)$(PA PA PA R))$$)@$
+
+ if (dir = (j::Symbol)) then
+ -- i,k dimensions must agree
+ if (^((iDim1 = iDim2) and (kDim1=kDim2)))
+ then
+ error "ixk do not agree"
+ else
+ for i in 0..(iDim1-1) repeat
+ setelt(matRep1,i,(concat(elt(matRep1,i)$(PA PA PA R)_
+ ,elt(matRep2,i)$(PA PA PA R))$(PA PA R))@(PA PA R))$(PA PA PA R)
+ retVal := (coerce(matRep1)$$)@$
+
+ if (dir = (k::Symbol)) then
+ temp : (PA PA R)
+ -- i,j dimensions must agree
+ if (^((iDim1 = iDim2) and (jDim1=jDim2)))
+ then
+ error "ixj do not agree"
+ else
+ for i in 0..(iDim1-1) repeat
+ temp := copy(elt(matRep1,i)$(PA PA PA R))$(PA PA R)
+ for j in 0..(jDim1-1) repeat
+ setelt(temp,j,concat(elt(elt(matRep1,i)$(PA PA PA R)_
+ ,j)$(PA PA R),elt(elt(matRep2,i)$(PA PA PA R),j)$(PA PA R)_
+ )$(PA R))$(PA PA R)
+ setelt(matRep1,i,temp)$(PA PA PA R)
+ retVal := (coerce(matRep1)$$)@$
+
+ retVal
+
+ matrixDimensions(mat : $) : Vector NNI ==
+ matRep : (PA PA PA R) := mat :: (PA PA PA R)
+ iDim : NNI := (#matRep)$(PA PA PA R)
+ matRep2 : PA PA R := elt(matRep,0)$(PA PA PA R)
+ jDim : NNI := (#matRep2)$(PA PA R)
+ matRep3 : (PA R) := elt(matRep2,0)$(PA PA R)
+ kDim : NNI := (#matRep3)$(PA R)
+ retVal : Vector NNI := new(3,0)$(Vector NNI)
+ retVal.1 := iDim
+ retVal.2 := jDim
+ retVal.3 := kDim
+ retVal
+
+ coerce(matrixRep : (PA PA PA R)) : $ == matrixRep pretend $
+
+ coerce(mat : $) : (PA PA PA R) == mat pretend (PA PA PA R)
+
+ -- i,j,k must be with in the bounds of the matrix
+ elt(mat : $,i : NNI,j : NNI,k : NNI) : R ==
+ matDims := matrixDimensions(mat)
+ iLength := matDims.1
+ jLength := matDims.2
+ kLength := matDims.3
+ ((i > iLength) or (j > jLength) or (k > kLength) or (i=0) or (j=0) or_
+(k=0)) => error "coordinates must be within the bounds of the matrix"
+ matrixRep : PA PA PA R := mat :: (PA PA PA R)
+ elt(elt(elt(matrixRep,i-1)$(PA PA PA R),j-1)$(PA PA R),k-1)$(PA R)
+
+ setelt!(mat : $,i : NNI,j : NNI,k : NNI,val : R)_
+ : R ==
+ matDims := matrixDimensions(mat)
+ iLength := matDims.1
+ jLength := matDims.2
+ kLength := matDims.3
+ ((i > iLength) or (j > jLength) or (k > kLength) or (i=0) or (j=0) or_
+(k=0)) => error "coordinates must be within the bounds of the matrix"
+ matrixRep : PA PA PA R := mat :: (PA PA PA R)
+ row2 : PA PA R := copy(elt(matrixRep,i-1)$(PA PA PA R))$(PA PA R)
+ row1 : PA R := copy(elt(row2,j-1)$(PA PA R))$(PA R)
+ setelt(row1,k-1,val)$(PA R)
+ setelt(row2,j-1,row1)$(PA PA R)
+ setelt(matrixRep,i-1,row2)$(PA PA PA R)
+ val
+
+ if R has Ring then
+ zeroMatrix(iLength:NNI,jLength:NNI,kLength:NNI) : $ ==
+ (new(iLength,new(jLength,new(kLength,(0$R))$(PA R))$(PA PA R))$(PA PA PA R)) :: $
+
+ identityMatrix(iLength:NNI) : $ ==
+ retValueRep : PA PA PA R := zeroMatrix(iLength,iLength,iLength)$$ :: (PA PA PA R)
+ row1 : PA R
+ row2 : PA PA R
+ row1empty : PA R := new(iLength,0$R)$(PA R)
+ row2empty : PA PA R := new(iLength,copy(row1empty)$(PA R))$(PA PA R)
+ for count in 0..(iLength-1) repeat
+ row1 := copy(row1empty)$(PA R)
+ setelt(row1,count,1$R)$(PA R)
+ row2 := copy(row2empty)$(PA PA R)
+ setelt(row2,count,copy(row1)$(PA R))$(PA PA R)
+ setelt(retValueRep,count,copy(row2)$(PA PA R))$(PA PA PA R)
+ retValueRep :: $
+
+
+ plus(mat1 : $,mat2 :$) : $ ==
+
+ mat1Dims := matrixDimensions(mat1)
+ iLength1 := mat1Dims.1
+ jLength1 := mat1Dims.2
+ kLength1 := mat1Dims.3
+
+ mat2Dims := matrixDimensions(mat2)
+ iLength2 := mat2Dims.1
+ jLength2 := mat2Dims.2
+ kLength2 := mat2Dims.3
+
+ -- check that the dimensions are the same
+ (^(iLength1 = iLength2) or ^(jLength1 = jLength2) or ^(kLength1 = kLength2))_
+ => error "error the matrices are different sizes"
+
+ sum : R
+ row1 : (PA R) := new(kLength1,0$R)$(PA R)
+ row2 : (PA PA R) := new(jLength1,copy(row1)$(PA R))$(PA PA R)
+ row3 : (PA PA PA R) := new(iLength1,copy(row2)$(PA PA R))$(PA PA PA R)
+
+ for i in 1..iLength1 repeat
+ for j in 1..jLength1 repeat
+ for k in 1..kLength1 repeat
+ sum := (elt(mat1,i,j,k)::R +$R_
+ elt(mat2,i,j,k)::R)
+ setelt(row1,k-1,sum)$(PA R)
+ setelt(row2,j-1,copy(row1)$(PA R))$(PA PA R)
+ setelt(row3,i-1,copy(row2)$(PA PA R))$(PA PA PA R)
+
+ resultMatrix := (row3 pretend $)
+
+ resultMatrix
+
+ construct(listRep : L L L R) : $ ==
+
+ (#listRep)$(L L L R) = 0 => error "empty list"
+ (#(listRep.1))$(L L R) = 0 => error "empty list"
+ (#((listRep.1).1))$(L R) = 0 => error "empty list"
+ iLength := (#listRep)$(L L L R)
+ jLength := (#(listRep.1))$(L L R)
+ kLength := (#((listRep.1).1))$(L R)
+
+ --first check that the matrix is in the correct form
+ for subList in listRep repeat
+ ^((#subList)$(L L R) = jLength) => error_
+ "can not have an irregular shaped matrix"
+ for subSubList in subList repeat
+ ^((#(subSubList))$(L R) = kLength) => error_
+ "can not have an irregular shaped matrix"
+
+ row1 : (PA R) := new(kLength,((listRep.1).1).1)$(PA R)
+ row2 : (PA PA R) := new(jLength,copy(row1)$(PA R))$(PA PA R)
+ row3 : (PA PA PA R) := new(iLength,copy(row2)$(PA PA R))$(PA PA PA R)
+
+ for i in 1..iLength repeat
+ for j in 1..jLength repeat
+ for k in 1..kLength repeat
+
+ element := elt(elt(elt(listRep,i)$(L L L R),j)$(L L R),k)$(L R)
+ setelt(row1,k-1,element)$(PA R)
+ setelt(row2,j-1,copy(row1)$(PA R))$(PA PA R)
+ setelt(row3,i-1,copy(row2)$(PA PA R))$(PA PA PA R)
+
+ resultMatrix := (row3 pretend $)
+
+ resultMatrix
+
+@
+\section{domain SFORT SimpleFortranProgram}
+<<domain SFORT SimpleFortranProgram>>=
+)abbrev domain SFORT SimpleFortranProgram
+-- Because of a bug in the compiler:
+)bo $noSubsumption:=true
+
+++ Author: Mike Dewar
+++ Date Created: November 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Constructors: FortranType, FortranCode, Switch
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \axiomType{SimpleFortranProgram(f,type)} provides a simple model of some
+++ FORTRAN subprograms, making it possible to coerce objects of various
+++ domains into a FORTRAN subprogram called \axiom{f}.
+++ These can then be translated into legal FORTRAN code.
+SimpleFortranProgram(R,FS): Exports == Implementation where
+ R : OrderedSet
+ FS : FunctionSpace(R)
+
+ FST ==> FortranScalarType
+
+ Exports ==> FortranProgramCategory with
+ fortran : (Symbol,FST,FS) -> $
+ ++fortran(fname,ftype,body) builds an object of type
+ ++\axiomType{FortranProgramCategory}. The three arguments specify
+ ++the name, the type and the body of the program.
+
+ Implementation ==> add
+
+ Rep := Record(name : Symbol, type : FST, body : FS )
+
+ fortran(fname, ftype, res) ==
+ construct(fname,ftype,res)$Rep
+
+ nameOf(u:$):Symbol == u . name
+
+ typeOf(u:$):Union(FST,"void") == u . type
+
+ bodyOf(u:$):FS == u . body
+
+ argumentsOf(u:$):List Symbol == variables(bodyOf u)$FS
+
+ coerce(u:$):OutputForm ==
+ coerce(nameOf u)$Symbol
+
+ outputAsFortran(u:$):Void ==
+ ftype := (checkType(typeOf(u)::OutputForm)$Lisp)::OutputForm
+ fname := nameOf(u)::OutputForm
+ args := argumentsOf(u)
+ nargs:=args::OutputForm
+ val := bodyOf(u)::OutputForm
+ fortFormatHead(ftype,fname,nargs)$Lisp
+ fortFormatTypes(ftype,args)$Lisp
+ dispfortexp1$Lisp ["="::OutputForm, fname, val]@List(OutputForm)
+ dispfortexp1$Lisp "RETURN"::OutputForm
+ dispfortexp1$Lisp "END"::OutputForm
+ void()$Void
+
+@
+\section{domain SWITCH Switch}
+<<domain SWITCH Switch>>=
+)abbrev domain SWITCH Switch
+-- Because of a bug in the compiler:
+)bo $noSubsumption:=false
+
+++ Author: Mike Dewar
+++ Date Created: April 1991
+++ Date Last Updated: March 1994
+++ 30.6.94 Added coercion from Symbol MCD
+++ Basic Operations:
+++ Related Constructors: FortranProgram, FortranCode, FortranTypes
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain builds representations of boolean expressions for use with
+++ the \axiomType{FortranCode} domain.
+Switch():public == private where
+ EXPR ==> Union(I:Expression Integer,F:Expression Float,
+ CF:Expression Complex Float,switch:%)
+
+ public == CoercibleTo OutputForm with
+ coerce : Symbol -> $
+ ++ coerce(s) \undocumented{}
+ LT : (EXPR,EXPR) -> $
+ ++ LT(x,y) returns the \axiomType{Switch} expression representing \spad{x<y}.
+ GT : (EXPR,EXPR) -> $
+ ++ GT(x,y) returns the \axiomType{Switch} expression representing \spad{x>y}.
+ LE : (EXPR,EXPR) -> $
+ ++ LE(x,y) returns the \axiomType{Switch} expression representing \spad{x<=y}.
+ GE : (EXPR,EXPR) -> $
+ ++ GE(x,y) returns the \axiomType{Switch} expression representing \spad{x>=y}.
+ OR : (EXPR,EXPR) -> $
+ ++ OR(x,y) returns the \axiomType{Switch} expression representing \spad{x or y}.
+ EQ : (EXPR,EXPR) -> $
+ ++ EQ(x,y) returns the \axiomType{Switch} expression representing \spad{x = y}.
+ AND : (EXPR,EXPR) -> $
+ ++ AND(x,y) returns the \axiomType{Switch} expression representing \spad{x and y}.
+ NOT : EXPR -> $
+ ++ NOT(x) returns the \axiomType{Switch} expression representing \spad{\~~x}.
+ NOT : $ -> $
+ ++ NOT(x) returns the \axiomType{Switch} expression representing \spad{\~~x}.
+
+ private == add
+ Rep := Record(op:BasicOperator,rands:List EXPR)
+
+ -- Public function definitions
+
+ nullOp : BasicOperator := operator NULL
+
+ coerce(s:%):OutputForm ==
+ rat := (s . op)::OutputForm
+ ran := [u::OutputForm for u in s.rands]
+ (s . op) = nullOp => first ran
+ #ran = 1 =>
+ prefix(rat,ran)
+ infix(rat,ran)
+
+ coerce(s:Symbol):$ == [nullOp,[[s::Expression(Integer)]$EXPR]$List(EXPR)]$Rep
+
+ NOT(r:EXPR):% ==
+ [operator("~"::Symbol),[r]$List(EXPR)]$Rep
+
+ NOT(r:%):% ==
+ [operator("~"::Symbol),[[r]$EXPR]$List(EXPR)]$Rep
+
+ LT(r1:EXPR,r2:EXPR):% ==
+ [operator("<"::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+ GT(r1:EXPR,r2:EXPR):% ==
+ [operator(">"::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+ LE(r1:EXPR,r2:EXPR):% ==
+ [operator("<="::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+ GE(r1:EXPR,r2:EXPR):% ==
+ [operator(">="::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+ AND(r1:EXPR,r2:EXPR):% ==
+ [operator("and"::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+ OR(r1:EXPR,r2:EXPR):% ==
+ [operator("or"::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+ EQ(r1:EXPR,r2:EXPR):% ==
+ [operator("EQ"::Symbol),[r1,r2]$List(EXPR)]$Rep
+
+@
+\section{domain FTEM FortranTemplate}
+<<domain FTEM FortranTemplate>>=
+)abbrev domain FTEM FortranTemplate
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Code to manipulate Fortran templates
+FortranTemplate() : specification == implementation where
+
+ specification == FileCategory(FileName, String) with
+
+ processTemplate : (FileName, FileName) -> FileName
+ ++ processTemplate(tp,fn) processes the template tp, writing the
+ ++ result out to fn.
+ processTemplate : (FileName) -> FileName
+ ++ processTemplate(tp) processes the template tp, writing the
+ ++ result to the current FORTRAN output stream.
+ fortranLiteralLine : String -> Void
+ ++ fortranLiteralLine(s) writes s to the current Fortran output stream,
+ ++ followed by a carriage return
+ fortranLiteral : String -> Void
+ ++ fortranLiteral(s) writes s to the current Fortran output stream
+ fortranCarriageReturn : () -> Void
+ ++ fortranCarriageReturn() produces a carriage return on the current
+ ++ Fortran output stream
+
+ implementation == TextFile add
+
+ import TemplateUtilities
+ import FortranOutputStackPackage
+
+ Rep := TextFile
+
+ fortranLiteralLine(s:String):Void ==
+ PRINTEXP(s,_$fortranOutputStream$Lisp)$Lisp
+ TERPRI(_$fortranOutputStream$Lisp)$Lisp
+
+ fortranLiteral(s:String):Void ==
+ PRINTEXP(s,_$fortranOutputStream$Lisp)$Lisp
+
+ fortranCarriageReturn():Void ==
+ TERPRI(_$fortranOutputStream$Lisp)$Lisp
+
+ writePassiveLine!(line:String):Void ==
+ -- We might want to be a bit clever here and look for new SubPrograms etc.
+ fortranLiteralLine line
+
+ processTemplate(tp:FileName, fn:FileName):FileName ==
+ pushFortranOutputStack(fn)
+ processTemplate(tp)
+ popFortranOutputStack()
+ fn
+
+ getLine(fp:TextFile):String ==
+ line : String := stripCommentsAndBlanks readLine!(fp)
+ while not empty?(line) and elt(line,maxIndex line) = char "__" repeat
+ setelt(line,maxIndex line,char " ")
+ line := concat(line, stripCommentsAndBlanks readLine!(fp))$String
+ line
+
+ processTemplate(tp:FileName):FileName ==
+ fp : TextFile := open(tp,"input")
+ active : Boolean := true
+ line : String
+ endInput : Boolean := false
+ while not (endInput or endOfFile? fp) repeat
+ if active then
+ line := getLine fp
+ line = "endInput" => endInput := true
+ if line = "beginVerbatim" then
+ active := false
+ else
+ not empty? line => interpretString line
+ else
+ line := readLine!(fp)
+ if line = "endVerbatim" then
+ active := true
+ else
+ writePassiveLine! line
+ close!(fp)
+ if not active then
+ error concat(["Missing `endVerbatim' line in ",tp::String])$String
+ string(_$fortranOutputFile$Lisp)::FileName
+
+@
+\section{domain FEXPR FortranExpression}
+<<domain FEXPR FortranExpression>>=
+)abbrev domain FEXPR FortranExpression
+++ Author: Mike Dewar
+++ Date Created: December 1993
+++ Date Last Updated: 19 May 1994
+++ 7 July 1994 added %power to f77Functions
+++ 12 July 1994 added RetractableTo(R)
+++ Basic Operations:
+++ Related Domains:
+++ Also See: FortranMachineTypeCategory, MachineInteger, MachineFloat,
+++ MachineComplex
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A domain of expressions involving functions which can be
+++ translated into standard Fortran-77, with some extra extensions from
+++ the NAG Fortran Library.
+FortranExpression(basicSymbols,subscriptedSymbols,R):
+ Exports==Implementation where
+ basicSymbols : List Symbol
+ subscriptedSymbols : List Symbol
+ R : FortranMachineTypeCategory
+
+ EXPR ==> Expression
+ EXF2 ==> ExpressionFunctions2
+ S ==> Symbol
+ L ==> List
+ BO ==> BasicOperator
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+
+ Exports ==> Join(ExpressionSpace,Algebra(R),RetractableTo(R),
+ PartialDifferentialRing(Symbol)) with
+ retract : EXPR R -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : EXPR R -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retract : S -> $
+ ++ retract(e) takes e and transforms it into a FortranExpression
+ ++ checking that it is one of the given basic symbols
+ ++ or subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : S -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a FortranExpression
+ ++ checking that it is one of the given basic symbols
+ ++ or subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ coerce : $ -> EXPR R
+ ++ coerce(x) \undocumented{}
+ if (R has RetractableTo(Integer)) then
+ retract : EXPR Integer -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : EXPR Integer -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retract : FRAC POLY Integer -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : FRAC POLY Integer -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retract : POLY Integer -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : POLY Integer -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ if (R has RetractableTo(Float)) then
+ retract : EXPR Float -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : EXPR Float -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retract : FRAC POLY Float -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : FRAC POLY Float -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retract : POLY Float -> $
+ ++ retract(e) takes e and transforms it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ retractIfCan : POLY Float -> Union($,"failed")
+ ++ retractIfCan(e) takes e and tries to transform it into a
+ ++ FortranExpression checking that it contains no non-Fortran
+ ++ functions, and that it only contains the given basic symbols
+ ++ and subscripted symbols which correspond to scalar and array
+ ++ parameters respectively.
+ abs : $ -> $
+ ++ abs(x) represents the Fortran intrinsic function ABS
+ sqrt : $ -> $
+ ++ sqrt(x) represents the Fortran intrinsic function SQRT
+ exp : $ -> $
+ ++ exp(x) represents the Fortran intrinsic function EXP
+ log : $ -> $
+ ++ log(x) represents the Fortran intrinsic function LOG
+ log10 : $ -> $
+ ++ log10(x) represents the Fortran intrinsic function LOG10
+ sin : $ -> $
+ ++ sin(x) represents the Fortran intrinsic function SIN
+ cos : $ -> $
+ ++ cos(x) represents the Fortran intrinsic function COS
+ tan : $ -> $
+ ++ tan(x) represents the Fortran intrinsic function TAN
+ asin : $ -> $
+ ++ asin(x) represents the Fortran intrinsic function ASIN
+ acos : $ -> $
+ ++ acos(x) represents the Fortran intrinsic function ACOS
+ atan : $ -> $
+ ++ atan(x) represents the Fortran intrinsic function ATAN
+ sinh : $ -> $
+ ++ sinh(x) represents the Fortran intrinsic function SINH
+ cosh : $ -> $
+ ++ cosh(x) represents the Fortran intrinsic function COSH
+ tanh : $ -> $
+ ++ tanh(x) represents the Fortran intrinsic function TANH
+ pi : () -> $
+ ++ pi(x) represents the NAG Library function X01AAF which returns
+ ++ an approximation to the value of pi
+ variables : $ -> L S
+ ++ variables(e) return a list of all the variables in \spad{e}.
+ useNagFunctions : () -> Boolean
+ ++ useNagFunctions() indicates whether NAG functions are being used
+ ++ for mathematical and machine constants.
+ useNagFunctions : Boolean -> Boolean
+ ++ useNagFunctions(v) sets the flag which controls whether NAG functions
+ ++ are being used for mathematical and machine constants. The previous
+ ++ value is returned.
+
+ Implementation ==> EXPR R add
+
+ -- The standard FORTRAN-77 intrinsic functions, plus nthRoot which
+ -- can be translated into an arithmetic expression:
+ f77Functions : L S := [abs,sqrt,exp,log,log10,sin,cos,tan,asin,acos,
+ atan,sinh,cosh,tanh,nthRoot,%power]
+ nagFunctions : L S := [pi, X01AAF]
+ useNagFunctionsFlag : Boolean := true
+
+ -- Local functions to check for "unassigned" symbols etc.
+
+ mkEqn(s1:Symbol,s2:Symbol):Equation EXPR(R) ==
+ equation(s2::EXPR(R),script(s1,scripts(s2))::EXPR(R))
+
+ fixUpSymbols(u:EXPR R):Union(EXPR R,"failed") ==
+ -- If its a univariate expression then just fix it up:
+ syms : L S := variables(u)
+-- one?(#basicSymbols) and zero?(#subscriptedSymbols) =>
+ (#basicSymbols = 1) and zero?(#subscriptedSymbols) =>
+-- not one?(#syms) => "failed"
+ not (#syms = 1) => "failed"
+ subst(u,equation(first(syms)::EXPR(R),first(basicSymbols)::EXPR(R)))
+ -- We have one variable but it is subscripted:
+-- zero?(#basicSymbols) and one?(#subscriptedSymbols) =>
+ zero?(#basicSymbols) and (#subscriptedSymbols = 1) =>
+ -- Make sure we don't have both X and X_i
+ for s in syms repeat
+ not scripted?(s) => return "failed"
+-- not one?(#(syms:=removeDuplicates! [name(s) for s in syms]))=> "failed"
+ not ((#(syms:=removeDuplicates! [name(s) for s in syms])) = 1)=> "failed"
+ sym : Symbol := first subscriptedSymbols
+ subst(u,[mkEqn(sym,i) for i in variables(u)])
+ "failed"
+
+ extraSymbols?(u:EXPR R):Boolean ==
+ syms : L S := [name(v) for v in variables(u)]
+ extras : L S := setDifference(syms,
+ setUnion(basicSymbols,subscriptedSymbols))
+ not empty? extras
+
+ checkSymbols(u:EXPR R):EXPR(R) ==
+ syms : L S := [name(v) for v in variables(u)]
+ extras : L S := setDifference(syms,
+ setUnion(basicSymbols,subscriptedSymbols))
+ not empty? extras =>
+ m := fixUpSymbols(u)
+ m case EXPR(R) => m::EXPR(R)
+ error("Extra symbols detected:",[string(v) for v in extras]$L(String))
+ u
+
+ notSymbol?(v:BO):Boolean ==
+ s : S := name v
+ member?(s,basicSymbols) or
+ scripted?(s) and member?(name s,subscriptedSymbols) => false
+ true
+
+ extraOperators?(u:EXPR R):Boolean ==
+ ops : L S := [name v for v in operators(u) | notSymbol?(v)]
+ if useNagFunctionsFlag then
+ fortranFunctions : L S := append(f77Functions,nagFunctions)
+ else
+ fortranFunctions : L S := f77Functions
+ extras : L S := setDifference(ops,fortranFunctions)
+ not empty? extras
+
+ checkOperators(u:EXPR R):Void ==
+ ops : L S := [name v for v in operators(u) | notSymbol?(v)]
+ if useNagFunctionsFlag then
+ fortranFunctions : L S := append(f77Functions,nagFunctions)
+ else
+ fortranFunctions : L S := f77Functions
+ extras : L S := setDifference(ops,fortranFunctions)
+ not empty? extras =>
+ error("Non FORTRAN-77 functions detected:",[string(v) for v in extras])
+ void()
+
+ checkForNagOperators(u:EXPR R):$ ==
+ useNagFunctionsFlag =>
+ import Pi
+ import PiCoercions(R)
+ piOp : BasicOperator := operator X01AAF
+ piSub : Equation EXPR R :=
+ equation(pi()$Pi::EXPR(R),kernel(piOp,0::EXPR(R))$EXPR(R))
+ subst(u,piSub) pretend $
+ u pretend $
+
+ -- Conditional retractions:
+
+ if R has RetractableTo(Integer) then
+
+ retractIfCan(u:POLY Integer):Union($,"failed") ==
+ retractIfCan((u::EXPR Integer)$EXPR(Integer))@Union($,"failed")
+
+ retract(u:POLY Integer):$ ==
+ retract((u::EXPR Integer)$EXPR(Integer))@$
+
+ retractIfCan(u:FRAC POLY Integer):Union($,"failed") ==
+ retractIfCan((u::EXPR Integer)$EXPR(Integer))@Union($,"failed")
+
+ retract(u:FRAC POLY Integer):$ ==
+ retract((u::EXPR Integer)$EXPR(Integer))@$
+
+ int2R(u:Integer):R == u::R
+
+ retractIfCan(u:EXPR Integer):Union($,"failed") ==
+ retractIfCan(map(int2R,u)$EXF2(Integer,R))@Union($,"failed")
+
+ retract(u:EXPR Integer):$ ==
+ retract(map(int2R,u)$EXF2(Integer,R))@$
+
+ if R has RetractableTo(Float) then
+
+ retractIfCan(u:POLY Float):Union($,"failed") ==
+ retractIfCan((u::EXPR Float)$EXPR(Float))@Union($,"failed")
+
+ retract(u:POLY Float):$ ==
+ retract((u::EXPR Float)$EXPR(Float))@$
+
+ retractIfCan(u:FRAC POLY Float):Union($,"failed") ==
+ retractIfCan((u::EXPR Float)$EXPR(Float))@Union($,"failed")
+
+ retract(u:FRAC POLY Float):$ ==
+ retract((u::EXPR Float)$EXPR(Float))@$
+
+ float2R(u:Float):R == (u::R)
+
+ retractIfCan(u:EXPR Float):Union($,"failed") ==
+ retractIfCan(map(float2R,u)$EXF2(Float,R))@Union($,"failed")
+
+ retract(u:EXPR Float):$ ==
+ retract(map(float2R,u)$EXF2(Float,R))@$
+
+ -- Exported Functions
+
+ useNagFunctions():Boolean == useNagFunctionsFlag
+ useNagFunctions(v:Boolean):Boolean ==
+ old := useNagFunctionsFlag
+ useNagFunctionsFlag := v
+ old
+
+ log10(x:$):$ ==
+ kernel(operator log10,x)
+
+ pi():$ == kernel(operator X01AAF,0)
+
+ coerce(u:$):EXPR R == u pretend EXPR(R)
+
+ retractIfCan(u:EXPR R):Union($,"failed") ==
+ if (extraSymbols? u) then
+ m := fixUpSymbols(u)
+ m case "failed" => return "failed"
+ u := m::EXPR(R)
+ extraOperators? u => "failed"
+ checkForNagOperators(u)
+
+ retract(u:EXPR R):$ ==
+ u:=checkSymbols(u)
+ checkOperators(u)
+ checkForNagOperators(u)
+
+ retractIfCan(u:Symbol):Union($,"failed") ==
+ not (member?(u,basicSymbols) or
+ scripted?(u) and member?(name u,subscriptedSymbols)) => "failed"
+ (((u::EXPR(R))$(EXPR R))pretend Rep)::$
+
+ retract(u:Symbol):$ ==
+ res : Union($,"failed") := retractIfCan(u)
+ res case "failed" => error("Illegal Symbol Detected:",u::String)
+ res::$
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain RESULT Result>>
+<<domain FC FortranCode>>
+<<domain FORTRAN FortranProgram>>
+<<domain M3D ThreeDimensionalMatrix>>
+<<domain SFORT SimpleFortranProgram>>
+<<domain SWITCH Switch>>
+<<domain FTEM FortranTemplate>>
+<<domain FEXPR FortranExpression>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/forttyp.spad.pamphlet b/src/algebra/forttyp.spad.pamphlet
new file mode 100644
index 00000000..334b236b
--- /dev/null
+++ b/src/algebra/forttyp.spad.pamphlet
@@ -0,0 +1,703 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra forttyp.spad}
+\author{Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FST FortranScalarType}
+<<domain FST FortranScalarType>>=
+)abbrev domain FST FortranScalarType
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Creates and manipulates objects which correspond to the
+++ basic FORTRAN data types: REAL, INTEGER, COMPLEX, LOGICAL and CHARACTER
+FortranScalarType() : exports == implementation where
+
+ exports == CoercibleTo OutputForm with
+ coerce : String -> $
+ ++ coerce(s) transforms the string s into an element of
+ ++ FortranScalarType provided s is one of "real", "double precision",
+ ++ "complex", "logical", "integer", "character", "REAL",
+ ++ "COMPLEX", "LOGICAL", "INTEGER", "CHARACTER",
+ ++ "DOUBLE PRECISION"
+ coerce : Symbol -> $
+ ++ coerce(s) transforms the symbol s into an element of
+ ++ FortranScalarType provided s is one of real, complex,double precision,
+ ++ logical, integer, character, REAL, COMPLEX, LOGICAL,
+ ++ INTEGER, CHARACTER, DOUBLE PRECISION
+ coerce : $ -> Symbol
+ ++ coerce(x) returns the symbol associated with x
+ coerce : $ -> SExpression
+ ++ coerce(x) returns the s-expression associated with x
+ real? : $ -> Boolean
+ ++ real?(t) tests whether t is equivalent to the FORTRAN type REAL.
+ double? : $ -> Boolean
+ ++ double?(t) tests whether t is equivalent to the FORTRAN type
+ ++ DOUBLE PRECISION
+ integer? : $ -> Boolean
+ ++ integer?(t) tests whether t is equivalent to the FORTRAN type INTEGER.
+ complex? : $ -> Boolean
+ ++ complex?(t) tests whether t is equivalent to the FORTRAN type COMPLEX.
+ doubleComplex? : $ -> Boolean
+ ++ doubleComplex?(t) tests whether t is equivalent to the (non-standard)
+ ++ FORTRAN type DOUBLE COMPLEX.
+ character? : $ -> Boolean
+ ++ character?(t) tests whether t is equivalent to the FORTRAN type
+ ++ CHARACTER.
+ logical? : $ -> Boolean
+ ++ logical?(t) tests whether t is equivalent to the FORTRAN type LOGICAL.
+ "=" : ($,$) -> Boolean
+ ++ x=y tests for equality
+
+ implementation == add
+
+ U == Union(RealThing:"real",
+ IntegerThing:"integer",
+ ComplexThing:"complex",
+ CharacterThing:"character",
+ LogicalThing:"logical",
+ DoublePrecisionThing:"double precision",
+ DoubleComplexThing:"double complex")
+ Rep := U
+
+ doubleSymbol : Symbol := "double precision"::Symbol
+ upperDoubleSymbol : Symbol := "DOUBLE PRECISION"::Symbol
+ doubleComplexSymbol : Symbol := "double complex"::Symbol
+ upperDoubleComplexSymbol : Symbol := "DOUBLE COMPLEX"::Symbol
+
+ u = v ==
+ u case RealThing and v case RealThing => true
+ u case IntegerThing and v case IntegerThing => true
+ u case ComplexThing and v case ComplexThing => true
+ u case LogicalThing and v case LogicalThing => true
+ u case CharacterThing and v case CharacterThing => true
+ u case DoublePrecisionThing and v case DoublePrecisionThing => true
+ u case DoubleComplexThing and v case DoubleComplexThing => true
+ false
+
+ coerce(t:$):OutputForm ==
+ t case RealThing => coerce(REAL)$Symbol
+ t case IntegerThing => coerce(INTEGER)$Symbol
+ t case ComplexThing => coerce(COMPLEX)$Symbol
+ t case CharacterThing => coerce(CHARACTER)$Symbol
+ t case DoublePrecisionThing => coerce(upperDoubleSymbol)$Symbol
+ t case DoubleComplexThing => coerce(upperDoubleComplexSymbol)$Symbol
+ coerce(LOGICAL)$Symbol
+
+ coerce(t:$):SExpression ==
+ t case RealThing => convert(real::Symbol)@SExpression
+ t case IntegerThing => convert(integer::Symbol)@SExpression
+ t case ComplexThing => convert(complex::Symbol)@SExpression
+ t case CharacterThing => convert(character::Symbol)@SExpression
+ t case DoublePrecisionThing => convert(doubleSymbol)@SExpression
+ t case DoubleComplexThing => convert(doubleComplexSymbol)@SExpression
+ convert(logical::Symbol)@SExpression
+
+ coerce(t:$):Symbol ==
+ t case RealThing => real::Symbol
+ t case IntegerThing => integer::Symbol
+ t case ComplexThing => complex::Symbol
+ t case CharacterThing => character::Symbol
+ t case DoublePrecisionThing => doubleSymbol
+ t case DoublePrecisionThing => doubleComplexSymbol
+ logical::Symbol
+
+ coerce(s:Symbol):$ ==
+ s = real => ["real"]$Rep
+ s = REAL => ["real"]$Rep
+ s = integer => ["integer"]$Rep
+ s = INTEGER => ["integer"]$Rep
+ s = complex => ["complex"]$Rep
+ s = COMPLEX => ["complex"]$Rep
+ s = character => ["character"]$Rep
+ s = CHARACTER => ["character"]$Rep
+ s = logical => ["logical"]$Rep
+ s = LOGICAL => ["logical"]$Rep
+ s = doubleSymbol => ["double precision"]$Rep
+ s = upperDoubleSymbol => ["double precision"]$Rep
+ s = doubleComplexSymbol => ["double complex"]$Rep
+ s = upperDoubleCOmplexSymbol => ["double complex"]$Rep
+
+ coerce(s:String):$ ==
+ s = "real" => ["real"]$Rep
+ s = "integer" => ["integer"]$Rep
+ s = "complex" => ["complex"]$Rep
+ s = "character" => ["character"]$Rep
+ s = "logical" => ["logical"]$Rep
+ s = "double precision" => ["double precision"]$Rep
+ s = "double complex" => ["double complex"]$Rep
+ s = "REAL" => ["real"]$Rep
+ s = "INTEGER" => ["integer"]$Rep
+ s = "COMPLEX" => ["complex"]$Rep
+ s = "CHARACTER" => ["character"]$Rep
+ s = "LOGICAL" => ["logical"]$Rep
+ s = "DOUBLE PRECISION" => ["double precision"]$Rep
+ s = "DOUBLE COMPLEX" => ["double complex"]$Rep
+ error concat([s," is invalid as a Fortran Type"])$String
+
+ real?(t:$):Boolean == t case RealThing
+
+ double?(t:$):Boolean == t case DoublePrecisionThing
+
+ logical?(t:$):Boolean == t case LogicalThing
+
+ integer?(t:$):Boolean == t case IntegerThing
+
+ character?(t:$):Boolean == t case CharacterThing
+
+ complex?(t:$):Boolean == t case ComplexThing
+
+ doubleComplex?(t:$):Boolean == t case DoubleComplexThing
+
+@
+\section{domain FT FortranType}
+<<domain FT FortranType>>=
+)abbrev domain FT FortranType
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Creates and manipulates objects which correspond to FORTRAN
+++ data types, including array dimensions.
+FortranType() : exports == implementation where
+
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+
+ exports == SetCategory with
+ coerce : $ -> OutputForm
+ ++ coerce(x) provides a printable form for x
+ coerce : FST -> $
+ ++ coerce(t) creates an element from a scalar type
+ scalarTypeOf : $ -> FSTU
+ ++ scalarTypeOf(t) returns the FORTRAN data type of t
+ dimensionsOf : $ -> List Polynomial Integer
+ ++ dimensionsOf(t) returns the dimensions of t
+ external? : $ -> Boolean
+ ++ external?(u) returns true if u is declared to be EXTERNAL
+ construct : (FSTU,List Symbol,Boolean) -> $
+ ++ construct(type,dims) creates an element of FortranType
+ construct : (FSTU,List Polynomial Integer,Boolean) -> $
+ ++ construct(type,dims) creates an element of FortranType
+ fortranReal : () -> $
+ ++ fortranReal() returns REAL, an element of FortranType
+ fortranDouble : () -> $
+ ++ fortranDouble() returns DOUBLE PRECISION, an element of FortranType
+ fortranInteger : () -> $
+ ++ fortranInteger() returns INTEGER, an element of FortranType
+ fortranLogical : () -> $
+ ++ fortranLogical() returns LOGICAL, an element of FortranType
+ fortranComplex : () -> $
+ ++ fortranComplex() returns COMPLEX, an element of FortranType
+ fortranDoubleComplex: () -> $
+ ++ fortranDoubleComplex() returns DOUBLE COMPLEX, an element of
+ ++ FortranType
+ fortranCharacter : () -> $
+ ++ fortranCharacter() returns CHARACTER, an element of FortranType
+
+ implementation == add
+
+ Dims == List Polynomial Integer
+ Rep := Record(type : FSTU, dimensions : Dims, external : Boolean)
+
+ coerce(a:$):OutputForm ==
+ t : OutputForm
+ if external?(a) then
+ if scalarTypeOf(a) case void then
+ t := "EXTERNAL"::OutputForm
+ else
+ t := blankSeparate(["EXTERNAL"::OutputForm,
+ coerce(scalarTypeOf a)$FSTU])$OutputForm
+ else
+ t := coerce(scalarTypeOf a)$FSTU
+ empty? dimensionsOf(a) => t
+ sub(t,
+ paren([u::OutputForm for u in dimensionsOf(a)])$OutputForm)$OutputForm
+
+ scalarTypeOf(u:$):FSTU ==
+ u.type
+
+ dimensionsOf(u:$):Dims ==
+ u.dimensions
+
+ external?(u:$):Boolean ==
+ u.external
+
+ construct(t:FSTU, d:List Symbol, e:Boolean):$ ==
+ e and not empty? d => error "EXTERNAL objects cannot have dimensions"
+ not(e) and t case void => error "VOID objects must be EXTERNAL"
+ construct(t,[l::Polynomial(Integer) for l in d],e)$Rep
+
+ construct(t:FSTU, d:List Polynomial Integer, e:Boolean):$ ==
+ e and not empty? d => error "EXTERNAL objects cannot have dimensions"
+ not(e) and t case void => error "VOID objects must be EXTERNAL"
+ construct(t,d,e)$Rep
+
+ coerce(u:FST):$ ==
+ construct([u]$FSTU,[]@List Polynomial Integer,false)
+
+ fortranReal():$ == ("real"::FST)::$
+
+ fortranDouble():$ == ("double precision"::FST)::$
+
+ fortranInteger():$ == ("integer"::FST)::$
+
+ fortranComplex():$ == ("complex"::FST)::$
+
+ fortranDoubleComplex():$ == ("double complex"::FST)::$
+
+ fortranCharacter():$ == ("character"::FST)::$
+
+ fortranLogical():$ == ("logical"::FST)::$
+
+@
+\section{domain SYMTAB SymbolTable}
+<<domain SYMTAB SymbolTable>>=
+)abbrev domain SYMTAB SymbolTable
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated: 12 July 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Create and manipulate a symbol table for generated FORTRAN code
+SymbolTable() : exports == implementation where
+
+ T ==> Union(S:Symbol,P:Polynomial Integer)
+ TL1 ==> List T
+ TU ==> Union(name:Symbol,bounds:TL1)
+ TL ==> List TU
+ SEX ==> SExpression
+ OFORM ==> OutputForm
+ L ==> List
+ FSTU ==> Union(fst:FortranScalarType,void:"void")
+
+ exports ==> CoercibleTo OutputForm with
+ coerce : $ -> Table(Symbol,FortranType)
+ ++ coerce(x) returns a table view of x
+ empty : () -> $
+ ++ empty() returns a new, empty symbol table
+ declare! : (L Symbol,FortranType,$) -> FortranType
+ ++ declare!(l,t,tab) creates new entrys in tab, declaring each of l
+ ++ to be of type t
+ declare! : (Symbol,FortranType,$) -> FortranType
+ ++ declare!(u,t,tab) creates a new entry in tab, declaring u to be of
+ ++ type t
+ fortranTypeOf : (Symbol,$) -> FortranType
+ ++ fortranTypeOf(u,tab) returns the type of u in tab
+ parametersOf: $ -> L Symbol
+ ++ parametersOf(tab) returns a list of all the symbols declared in tab
+ typeList : (FortranScalarType,$) -> TL
+ ++ typeList(t,tab) returns a list of all the objects of type t in tab
+ externalList : $ -> L Symbol
+ ++ externalList(tab) returns a list of all the external symbols in tab
+ typeLists : $ -> L TL
+ ++ typeLists(tab) returns a list of lists of types of objects in tab
+ newTypeLists : $ -> SEX
+ ++ newTypeLists(x) \undocumented
+ printTypes: $ -> Void
+ ++ printTypes(tab) produces FORTRAN type declarations from tab, on the
+ ++ current FORTRAN output stream
+ symbolTable: L Record(key:Symbol,entry:FortranType) -> $
+ ++ symbolTable(l) creates a symbol table from the elements of l.
+
+ implementation ==> add
+
+ Rep := Table(Symbol,FortranType)
+
+ coerce(t:$):OFORM ==
+ coerce(t)$Rep
+
+ coerce(t:$):Table(Symbol,FortranType) ==
+ t pretend Table(Symbol,FortranType)
+
+ symbolTable(l:L Record(key:Symbol,entry:FortranType)):$ ==
+ table(l)$Rep
+
+ empty():$ ==
+ empty()$Rep
+
+ parametersOf(tab:$):L(Symbol) ==
+ keys(tab)
+
+ declare!(name:Symbol,type:FortranType,tab:$):FortranType ==
+ setelt(tab,name,type)$Rep
+ type
+
+ declare!(names:L Symbol,type:FortranType,tab:$):FortranType ==
+ for name in names repeat setelt(tab,name,type)$Rep
+ type
+
+ fortranTypeOf(u:Symbol,tab:$):FortranType ==
+ elt(tab,u)$Rep
+
+ externalList(tab:$):L(Symbol) ==
+ [u for u in keys(tab) | external? fortranTypeOf(u,tab)]
+
+ typeList(type:FortranScalarType,tab:$):TL ==
+ scalarList := []@TL
+ arrayList := []@TL
+ for u in keys(tab)$Rep repeat
+ uType : FortranType := fortranTypeOf(u,tab)
+ sType : FSTU := scalarTypeOf(uType)
+ if (sType case fst and (sType.fst)=type) then
+ uDim : TL1 := [[v]$T for v in dimensionsOf(uType)]
+ if empty? uDim then
+ scalarList := cons([u]$TU,scalarList)
+ else
+ arrayList := cons([cons([u],uDim)$TL1]$TU,arrayList)
+ -- Scalars come first in case they are integers which are later
+ -- used as an array dimension.
+ append(scalarList,arrayList)
+
+ typeList2(type:FortranScalarType,tab:$):TL ==
+ tl := []@TL
+ symbolType : Symbol := coerce(type)$FortranScalarType
+ for u in keys(tab)$Rep repeat
+ uType : FortranType := fortranTypeOf(u,tab)
+ sType : FSTU := scalarTypeOf(uType)
+ if (sType case fst and (sType.fst)=type) then
+ uDim : TL1 := [[v]$T for v in dimensionsOf(uType)]
+ tl := if empty? uDim then cons([u]$TU,tl)
+ else cons([cons([u],uDim)$TL1]$TU,tl)
+ empty? tl => tl
+ cons([symbolType]$TU,tl)
+
+ updateList(sType:SEX,name:SEX,lDims:SEX,tl:SEX):SEX ==
+ l : SEX := ASSOC(sType,tl)$Lisp
+ entry : SEX := if null?(lDims) then name else CONS(name,lDims)$Lisp
+ null?(l) => CONS([sType,entry]$Lisp,tl)$Lisp
+ RPLACD(l,CONS(entry,cdr l)$Lisp)$Lisp
+ tl
+
+ newTypeLists(tab:$):SEX ==
+ tl := []$Lisp
+ for u in keys(tab)$Rep repeat
+ uType : FortranType := fortranTypeOf(u,tab)
+ sType : FSTU := scalarTypeOf(uType)
+ dims : L Polynomial Integer := dimensionsOf uType
+ lDims : L SEX := [convert(convert(v)@InputForm)@SEX for v in dims]
+ lType : SEX := if sType case void
+ then convert(void::Symbol)@SEX
+ else coerce(sType.fst)$FortranScalarType
+ tl := updateList(lType,convert(u)@SEX,convert(lDims)@SEX,tl)
+ tl
+
+ typeLists(tab:$):L(TL) ==
+ fortranTypes := ["real"::FortranScalarType, _
+ "double precision"::FortranScalarType, _
+ "integer"::FortranScalarType, _
+ "complex"::FortranScalarType, _
+ "logical"::FortranScalarType, _
+ "character"::FortranScalarType]@L(FortranScalarType)
+ tl := []@L TL
+ for u in fortranTypes repeat
+ types : TL := typeList2(u,tab)
+ if (not null types) then
+ tl := cons(types,tl)$(L TL)
+ tl
+
+ oForm2(w:T):OFORM ==
+ w case S => w.S::OFORM
+ w case P => w.P::OFORM
+
+ oForm(v:TU):OFORM ==
+ v case name => v.name::OFORM
+ v case bounds =>
+ ll : L OFORM := [oForm2(uu) for uu in v.bounds]
+ ll :: OFORM
+
+ outForm(t:TL):L OFORM ==
+ [oForm(u) for u in t]
+
+ printTypes(tab:$):Void ==
+ -- It is important that INTEGER is the first element of this
+ -- list since INTEGER symbols used in type declarations must
+ -- be declared in advance.
+ ft := ["integer"::FortranScalarType, _
+ "real"::FortranScalarType, _
+ "double precision"::FortranScalarType, _
+ "complex"::FortranScalarType, _
+ "logical"::FortranScalarType, _
+ "character"::FortranScalarType]@L(FortranScalarType)
+ for ty in ft repeat
+ tl : TL := typeList(ty,tab)
+ otl : L OFORM := outForm(tl)
+ fortFormatTypes(ty::OFORM,otl)$Lisp
+ el : L OFORM := [u::OFORM for u in externalList(tab)]
+ fortFormatTypes("EXTERNAL"::OFORM,el)$Lisp
+ void()$Void
+
+@
+\section{domain SYMS TheSymbolTable}
+<<domain SYMS TheSymbolTable>>=
+)abbrev domain SYMS TheSymbolTable
+++ Author: Mike Dewar
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: Creates and manipulates one global symbol table for FORTRAN
+++ code generation, containing details of types, dimensions, and argument
+++ lists.
+TheSymbolTable() : Exports == Implementation where
+
+ S ==> Symbol
+ FST ==> FortranScalarType
+ FSTU ==> Union(fst:FST,void:"void")
+
+ Exports == CoercibleTo OutputForm with
+ showTheSymbolTable : () -> $
+ ++ showTheSymbolTable() returns the current symbol table.
+ clearTheSymbolTable : () -> Void
+ ++ clearTheSymbolTable() clears the current symbol table.
+ clearTheSymbolTable : Symbol -> Void
+ ++ clearTheSymbolTable(x) removes the symbol x from the table
+ declare! : (Symbol,FortranType,Symbol,$) -> FortranType
+ ++ declare!(u,t,asp,tab) declares the parameter u of subprogram asp
+ ++ to have type t in symbol table tab.
+ declare! : (List Symbol,FortranType,Symbol,$) -> FortranType
+ ++ declare!(u,t,asp,tab) declares the parameters u of subprogram asp
+ ++ to have type t in symbol table tab.
+ declare! : (Symbol,FortranType) -> FortranType
+ ++ declare!(u,t) declares the parameter u to have type t in the
+ ++ current level of the symbol table.
+ declare! : (Symbol,FortranType,Symbol) -> FortranType
+ ++ declare!(u,t,asp) declares the parameter u to have type t in asp.
+ newSubProgram : Symbol -> Void
+ ++ newSubProgram(f) asserts that from now on type declarations are part
+ ++ of subprogram f.
+ currentSubProgram : () -> Symbol
+ ++ currentSubProgram() returns the name of the current subprogram being
+ ++ processed
+ endSubProgram : () -> Symbol
+ ++ endSubProgram() asserts that we are no longer processing the current
+ ++ subprogram.
+ argumentList! : (Symbol,List Symbol,$) -> Void
+ ++ argumentList!(f,l,tab) declares that the argument list for subprogram f
+ ++ in symbol table tab is l.
+ argumentList! : (Symbol,List Symbol) -> Void
+ ++ argumentList!(f,l) declares that the argument list for subprogram f in
+ ++ the global symbol table is l.
+ argumentList! : List Symbol -> Void
+ ++ argumentList!(l) declares that the argument list for the current
+ ++ subprogram in the global symbol table is l.
+ returnType! : (Symbol,FSTU,$) -> Void
+ ++ returnType!(f,t,tab) declares that the return type of subprogram f in
+ ++ symbol table tab is t.
+ returnType! : (Symbol,FSTU) -> Void
+ ++ returnType!(f,t) declares that the return type of subprogram f in
+ ++ the global symbol table is t.
+ returnType! : FSTU -> Void
+ ++ returnType!(t) declares that the return type of he current subprogram
+ ++ in the global symbol table is t.
+ printHeader : (Symbol,$) -> Void
+ ++ printHeader(f,tab) produces the FORTRAN header for subprogram f in
+ ++ symbol table tab on the current FORTRAN output stream.
+ printHeader : Symbol -> Void
+ ++ printHeader(f) produces the FORTRAN header for subprogram f in
+ ++ the global symbol table on the current FORTRAN output stream.
+ printHeader : () -> Void
+ ++ printHeader() produces the FORTRAN header for the current subprogram in
+ ++ the global symbol table on the current FORTRAN output stream.
+ printTypes: Symbol -> Void
+ ++ printTypes(tab) produces FORTRAN type declarations from tab, on the
+ ++ current FORTRAN output stream
+ empty : () -> $
+ ++ empty() creates a new, empty symbol table.
+ returnTypeOf : (Symbol,$) -> FSTU
+ ++ returnTypeOf(f,tab) returns the type of the object returned by f
+ argumentListOf : (Symbol,$) -> List(Symbol)
+ ++ argumentListOf(f,tab) returns the argument list of f
+ symbolTableOf : (Symbol,$) -> SymbolTable
+ ++ symbolTableOf(f,tab) returns the symbol table of f
+
+ Implementation == add
+
+ Entry : Domain := Record(symtab:SymbolTable, _
+ returnType:FSTU, _
+ argList:List Symbol)
+
+ Rep := Table(Symbol,Entry)
+
+ -- These are the global variables we want to update:
+ theSymbolTable : $ := empty()$Rep
+ currentSubProgramName : Symbol := MAIN
+
+ newEntry():Entry ==
+ construct(empty()$SymbolTable,["void"]$FSTU,[]::List(Symbol))$Entry
+
+ checkIfEntryExists(name:Symbol,tab:$) : Void ==
+ key?(name,tab) => void()$Void
+ setelt(tab,name,newEntry())$Rep
+ void()$Void
+
+ returnTypeOf(name:Symbol,tab:$):FSTU ==
+ elt(elt(tab,name)$Rep,returnType)$Entry
+
+ argumentListOf(name:Symbol,tab:$):List(Symbol) ==
+ elt(elt(tab,name)$Rep,argList)$Entry
+
+ symbolTableOf(name:Symbol,tab:$):SymbolTable ==
+ elt(elt(tab,name)$Rep,symtab)$Entry
+
+ coerce(u:$):OutputForm ==
+ coerce(u)$Rep
+
+ showTheSymbolTable():$ ==
+ theSymbolTable
+
+ clearTheSymbolTable():Void ==
+ theSymbolTable := empty()$Rep
+ void()$Void
+
+ clearTheSymbolTable(u:Symbol):Void ==
+ remove!(u,theSymbolTable)$Rep
+ void()$Void
+
+ empty():$ ==
+ empty()$Rep
+
+ currentSubProgram():Symbol ==
+ currentSubProgramName
+
+ endSubProgram():Symbol ==
+ -- If we want to support more complex languages then we should keep
+ -- a list of subprograms / blocks - but for the moment lets stick with
+ -- Fortran.
+ currentSubProgramName := MAIN
+
+ newSubProgram(u:Symbol):Void ==
+ setelt(theSymbolTable,u,newEntry())$Rep
+ currentSubProgramName := u
+ void()$Void
+
+ argumentList!(u:Symbol,args:List Symbol,symbols:$):Void ==
+ checkIfEntryExists(u,symbols)
+ setelt(elt(symbols,u)$Rep,argList,args)$Entry
+
+ argumentList!(u:Symbol,args:List Symbol):Void ==
+ argumentList!(u,args,theSymbolTable)
+
+ argumentList!(args:List Symbol):Void ==
+ checkIfEntryExists(currentSubProgramName,theSymbolTable)
+ setelt(elt(theSymbolTable,currentSubProgramName)$Rep, _
+ argList,args)$Entry
+
+ returnType!(u:Symbol,type:FSTU,symbols:$):Void ==
+ checkIfEntryExists(u,symbols)
+ setelt(elt(symbols,u)$Rep,returnType,type)$Entry
+
+ returnType!(u:Symbol,type:FSTU):Void ==
+ returnType!(u,type,theSymbolTable)
+
+ returnType!(type:FSTU ):Void ==
+ checkIfEntryExists(currentSubProgramName,theSymbolTable)
+ setelt(elt(theSymbolTable,currentSubProgramName)$Rep, _
+ returnType,type)$Entry
+
+ declare!(u:Symbol,type:FortranType):FortranType ==
+ declare!(u,type,currentSubProgramName,theSymbolTable)
+
+ declare!(u:Symbol,type:FortranType,asp:Symbol,symbols:$):FortranType ==
+ checkIfEntryExists(asp,symbols)
+ declare!(u,type, elt(elt(symbols,asp)$Rep,symtab)$Entry)$SymbolTable
+
+ declare!(u:List Symbol,type:FortranType,asp:Symbol,syms:$):FortranType ==
+ checkIfEntryExists(asp,syms)
+ declare!(u,type, elt(elt(syms,asp)$Rep,symtab)$Entry)$SymbolTable
+
+ declare!(u:Symbol,type:FortranType,asp:Symbol):FortranType ==
+ checkIfEntryExists(asp,theSymbolTable)
+ declare!(u,type,elt(elt(theSymbolTable,asp)$Rep,symtab)$Entry)$SymbolTable
+
+ printHeader(u:Symbol,symbols:$):Void ==
+ entry := elt(symbols,u)$Rep
+ fortFormatHead(elt(entry,returnType)$Entry::OutputForm,u::OutputForm, _
+ elt(entry,argList)$Entry::OutputForm)$Lisp
+ printTypes(elt(entry,symtab)$Entry)$SymbolTable
+
+ printHeader(u:Symbol):Void ==
+ printHeader(u,theSymbolTable)
+
+ printHeader():Void ==
+ printHeader(currentSubProgramName,theSymbolTable)
+
+ printTypes(u:Symbol):Void ==
+ printTypes(elt(elt(theSymbolTable,u)$Rep,symtab)$Entry)$SymbolTable
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FST FortranScalarType>>
+<<domain FT FortranType>>
+<<domain SYMTAB SymbolTable>>
+<<domain SYMS TheSymbolTable>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fourier.spad.pamphlet b/src/algebra/fourier.spad.pamphlet
new file mode 100644
index 00000000..798723c5
--- /dev/null
+++ b/src/algebra/fourier.spad.pamphlet
@@ -0,0 +1,169 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fourier.spad}
+\author{James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FCOMP FourierComponent}
+<<domain FCOMP FourierComponent>>=
+)abbrev domain FCOMP FourierComponent
+++ Author: James Davenport
+++ Date Created: 17 April 1992
+++ Date Last Updated: 12 June 1992
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+FourierComponent(E:OrderedSet):
+ OrderedSet with
+ sin: E -> $
+ ++ sin(x) makes a sin kernel for use in Fourier series
+ cos: E -> $
+ ++ cos(x) makes a cos kernel for use in Fourier series
+ sin?: $ -> Boolean
+ ++ sin?(x) returns true if term is a sin, otherwise false
+ argument: $ -> E
+ ++ argument(x) returns the argument of a given sin/cos expressions
+ ==
+ add
+ --representations
+ Rep:=Record(SinIfTrue:Boolean, arg:E)
+ e:E
+ x,y:$
+ sin e == [true,e]
+ cos e == [false,e]
+ sin? x == x.SinIfTrue
+ argument x == x.arg
+ coerce(x):OutputForm ==
+ hconcat((if x.SinIfTrue then "sin" else "cos")::OutputForm,
+ bracket((x.arg)::OutputForm))
+ x<y ==
+ x.arg < y.arg => true
+ y.arg < x.arg => false
+ x.SinIfTrue => false
+ y.SinIfTrue
+
+@
+\section{domain FSERIES FourierSeries}
+<<domain FSERIES FourierSeries>>=
+)abbrev domain FSERIES FourierSeries
+++ Author: James Davenport
+++ Date Created: 17 April 1992
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+FourierSeries(R:Join(CommutativeRing,Algebra(Fraction Integer)),
+ E:Join(OrderedSet,AbelianGroup)):
+ Algebra(R) with
+ if E has canonical and R has canonical then canonical
+ coerce: R -> $
+ ++ coerce(r) converts coefficients into Fourier Series
+ coerce: FourierComponent(E) -> $
+ ++ coerce(c) converts sin/cos terms into Fourier Series
+ makeSin: (E,R) -> $
+ ++ makeSin(e,r) makes a sin expression with given argument and coefficient
+ makeCos: (E,R) -> $
+ ++ makeCos(e,r) makes a sin expression with given argument and coefficient
+ == FreeModule(R,FourierComponent(E))
+ add
+ --representations
+ Term := Record(k:FourierComponent(E),c:R)
+ Rep := List Term
+ multiply : (Term,Term) -> $
+ w,x1,x2:$
+ t1,t2:Term
+ n:NonNegativeInteger
+ z:Integer
+ e:FourierComponent(E)
+ a:E
+ r:R
+ 1 == [[cos 0,1]]
+ coerce e ==
+ sin? e and zero? argument e => 0
+ if argument e < 0 then
+ not sin? e => e:=cos(- argument e)
+ return [[sin(- argument e),-1]]
+ [[e,1]]
+ multiply(t1,t2) ==
+ r:=(t1.c*t2.c)*(1/2)
+ s1:=argument t1.k
+ s2:=argument t2.k
+ sum:=s1+s2
+ diff:=s1-s2
+ sin? t1.k =>
+ sin? t2.k =>
+ makeCos(diff,r) + makeCos(sum,-r)
+ makeSin(sum,r) + makeSin(diff,r)
+ sin? t2.k =>
+ makeSin(sum,r) + makeSin(diff,r)
+ makeCos(diff,r) + makeCos(sum,r)
+ x1*x2 ==
+ null x1 => 0
+ null x2 => 0
+ +/[+/[multiply(t1,t2) for t2 in x2] for t1 in x1]
+ makeCos(a,r) ==
+ a<0 => [[cos(-a),r]]
+ [[cos a,r]]
+ makeSin(a,r) ==
+ zero? a => []
+ a<0 => [[sin(-a),-r]]
+ [[sin a,r]]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FCOMP FourierComponent>>
+<<domain FSERIES FourierSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fparfrac.spad.pamphlet b/src/algebra/fparfrac.spad.pamphlet
new file mode 100644
index 00000000..9afe1d78
--- /dev/null
+++ b/src/algebra/fparfrac.spad.pamphlet
@@ -0,0 +1,232 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fparfrac.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FPARFRAC FullPartialFractionExpansion}
+<<domain FPARFRAC FullPartialFractionExpansion>>=
+)abbrev domain FPARFRAC FullPartialFractionExpansion
+++ Full partial fraction expansion of rational functions
+++ Author: Manuel Bronstein
+++ Date Created: 9 December 1992
+++ Date Last Updated: 6 October 1993
+++ References: M.Bronstein & B.Salvy,
+++ Full Partial Fraction Decomposition of Rational Functions,
+++ in Proceedings of ISSAC'93, Kiev, ACM Press.
+FullPartialFractionExpansion(F, UP): Exports == Implementation where
+ F : Join(Field, CharacteristicZero)
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ Q ==> Fraction Integer
+ O ==> OutputForm
+ RF ==> Fraction UP
+ SUP ==> SparseUnivariatePolynomial RF
+ REC ==> Record(exponent: N, center: UP, num: UP)
+ ODV ==> OrderlyDifferentialVariable Symbol
+ ODP ==> OrderlyDifferentialPolynomial UP
+ ODF ==> Fraction ODP
+ FPF ==> Record(polyPart: UP, fracPart: List REC)
+
+ Exports ==> Join(SetCategory, ConvertibleTo RF) with
+ "+": (UP, $) -> $
+ ++ p + x returns the sum of p and x
+ fullPartialFraction: RF -> $
+ ++ fullPartialFraction(f) returns \spad{[p, [[j, Dj, Hj]...]]} such that
+ ++ \spad{f = p(x) + \sum_{[j,Dj,Hj] in l} \sum_{Dj(a)=0} Hj(a)/(x - a)\^j}.
+ polyPart: $ -> UP
+ ++ polyPart(f) returns the polynomial part of f.
+ fracPart: $ -> List REC
+ ++ fracPart(f) returns the list of summands of the fractional part of f.
+ construct: List REC -> $
+ ++ construct(l) is the inverse of fracPart.
+ differentiate: $ -> $
+ ++ differentiate(f) returns the derivative of f.
+ D: $ -> $
+ ++ D(f) returns the derivative of f.
+ differentiate: ($, N) -> $
+ ++ differentiate(f, n) returns the n-th derivative of f.
+ D: ($, NonNegativeInteger) -> $
+ ++ D(f, n) returns the n-th derivative of f.
+
+ Implementation ==> add
+ Rep := FPF
+
+ fullParFrac: (UP, UP, UP, N) -> List REC
+ outputexp : (O, N) -> O
+ output : (N, UP, UP) -> O
+ REC2RF : (UP, UP, N) -> RF
+ UP2SUP : UP -> SUP
+ diffrec : REC -> REC
+ FP2O : List REC -> O
+
+-- create a differential variable
+ u := new()$Symbol
+ u0 := makeVariable(u, 0)$ODV
+ alpha := u::O
+ x := monomial(1, 1)$UP
+ xx := x::O
+ zr := (0$N)::O
+
+ construct l == [0, l]
+ D r == differentiate r
+ D(r, n) == differentiate(r,n)
+ polyPart f == f.polyPart
+ fracPart f == f.fracPart
+ p:UP + f:$ == [p + polyPart f, fracPart f]
+
+ differentiate f ==
+ differentiate(polyPart f) + construct [diffrec rec for rec in fracPart f]
+
+ differentiate(r, n) ==
+ for i in 1..n repeat r := differentiate r
+ r
+
+-- diffrec(sum_{rec.center(a) = 0} rec.num(a) / (x - a)^e) =
+-- sum_{rec.center(a) = 0} -e rec.num(a) / (x - a)^{e+1}
+-- where e = rec.exponent
+ diffrec rec ==
+ e := rec.exponent
+ [e + 1, rec.center, - e * rec.num]
+
+ convert(f:$):RF ==
+ ans := polyPart(f)::RF
+ for rec in fracPart f repeat
+ ans := ans + REC2RF(rec.center, rec.num, rec.exponent)
+ ans
+
+ UP2SUP p ==
+ map(#1::UP::RF, p)$UnivariatePolynomialCategoryFunctions2(F, UP, RF, SUP)
+
+ -- returns Trace_k^k(a) (h(a) / (x - a)^n) where d(a) = 0
+ REC2RF(d, h, n) ==
+-- one?(m := degree d) =>
+ ((m := degree d) = 1) =>
+ a := - (leadingCoefficient reductum d) / (leadingCoefficient d)
+ h(a)::UP / (x - a::UP)**n
+ dd := UP2SUP d
+ hh := UP2SUP h
+ aa := monomial(1, 1)$SUP
+ p := (x::RF::SUP - aa)**n rem dd
+ rec := extendedEuclidean(p, dd, hh)::Record(coef1:SUP, coef2:SUP)
+ t := rec.coef1 -- we want Trace_k^k(a)(t) now
+ ans := coefficient(t, 0)
+ for i in 1..degree(d)-1 repeat
+ t := (t * aa) rem dd
+ ans := ans + coefficient(t, i)
+ ans
+
+ fullPartialFraction f ==
+ qr := divide(numer f, d := denom f)
+ qr.quotient + construct concat
+ [fullParFrac(qr.remainder, d, rec.factor, rec.exponent::N)
+ for rec in factors squareFree denom f]
+
+ fullParFrac(a, d, q, n) ==
+ ans:List REC := empty()
+ em := e := d quo (q ** n)
+ rec := extendedEuclidean(e, q, 1)::Record(coef1:UP,coef2:UP)
+ bm := b := rec.coef1 -- b = inverse of e modulo q
+ lvar:List(ODV) := [u0]
+ um := 1::ODP
+ un := (u1 := u0::ODP)**n
+ lval:List(UP) := [q1 := q := differentiate(q0 := q)]
+ h:ODF := a::ODP / (e * un)
+ rec := extendedEuclidean(q1, q0, 1)::Record(coef1:UP,coef2:UP)
+ c := rec.coef1 -- c = inverse of q' modulo q
+ cm := 1::UP
+ cn := (c ** n) rem q0
+ for m in 1..n repeat
+ p := retract(em * un * um * h)@ODP
+ pp := retract(eval(p, lvar, lval))@UP
+ h := inv(m::Q) * differentiate h
+ q := differentiate q
+ lvar := concat(makeVariable(u, m), lvar)
+ lval := concat(inv((m+1)::F) * q, lval)
+ qq := q0 quo gcd(pp, q0) -- new center
+ if (degree(qq) > 0) then
+ ans := concat([(n + 1 - m)::N, qq, (pp * bm * cn * cm) rem qq], ans)
+ cm := (c * cm) rem q0 -- cm = c**m modulo q now
+ um := u1 * um -- um = u**m now
+ em := e * em -- em = e**{m+1} now
+ bm := (b * bm) rem q0 -- bm = b**{m+1} modulo q now
+ ans
+
+ coerce(f:$):O ==
+ ans := FP2O(l := fracPart f)
+ zero?(p := polyPart f) =>
+ empty? l => (0$N)::O
+ ans
+ p::O + ans
+
+ FP2O l ==
+ empty? l => empty()
+ rec := first l
+ ans := output(rec.exponent, rec.center, rec.num)
+ for rec in rest l repeat
+ ans := ans + output(rec.exponent, rec.center, rec.num)
+ ans
+
+ output(n, d, h) ==
+-- one? degree d =>
+ (degree d) = 1 =>
+ a := - leadingCoefficient(reductum d) / leadingCoefficient(d)
+ h(a)::O / outputexp((x - a::UP)::O, n)
+ sum(outputForm(makeSUP h, alpha) / outputexp(xx - alpha, n),
+ outputForm(makeSUP d, alpha) = zr)
+
+ outputexp(f, n) ==
+-- one? n => f
+ (n = 1) => f
+ f ** (n::O)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FPARFRAC FullPartialFractionExpansion>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fr.spad.pamphlet b/src/algebra/fr.spad.pamphlet
new file mode 100644
index 00000000..fc180573
--- /dev/null
+++ b/src/algebra/fr.spad.pamphlet
@@ -0,0 +1,677 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fr.spad}
+\author{Robert S. Sutor, Johnannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+-- This file contains a domain and packages for manipulating objects
+-- in factored form.
+\section{domain FR Factored}
+<<domain FR Factored>>=
+)abbrev domain FR Factored
+++ Author: Robert S. Sutor
+++ Date Created: 1985
+++ Change History:
+++ 21 Jan 1991 J Grabmeier Corrected a bug in exquo.
+++ 16 Aug 1994 R S Sutor Improved convert to InputForm
+++ Basic Operations:
+++ expand, exponent, factorList, factors, flagFactor, irreducibleFactor,
+++ makeFR, map, nilFactor, nthFactor, nthFlag, numberOfFactors,
+++ primeFactor, sqfrFactor, unit, unitNormalize,
+++ Related Constructors: FactoredFunctionUtilities, FactoredFunctions2
+++ Also See:
+++ AMS Classifications: 11A51, 11Y05
+++ Keywords: factorization, prime, square-free, irreducible, factor
+++ References:
+++ Description:
+++ \spadtype{Factored} creates a domain whose objects are kept in
+++ factored form as long as possible. Thus certain operations like
+++ multiplication and gcd are relatively easy to do. Others, like
+++ addition require somewhat more work, and unless the argument
+++ domain provides a factor function, the result may not be
+++ completely factored. Each object consists of a unit and a list of
+++ factors, where a factor has a member of R (the "base"), and
+++ exponent and a flag indicating what is known about the base. A
+++ flag may be one of "nil", "sqfr", "irred" or "prime", which respectively mean
+++ that nothing is known about the base, it is square-free, it is
+++ irreducible, or it is prime. The current
+++ restriction to integral domains allows simplification to be
+++ performed without worrying about multiplication order.
+
+Factored(R: IntegralDomain): Exports == Implementation where
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FF ==> Record(flg: fUnion, fctr: R, xpnt: Integer)
+ SRFE ==> Set(Record(factor:R, exponent:Integer))
+
+ Exports ==> Join(IntegralDomain, DifferentialExtension R, Algebra R,
+ FullyEvalableOver R, FullyRetractableTo R) with
+ expand: % -> R
+ ++ expand(f) multiplies the unit and factors together, yielding an
+ ++ "unfactored" object. Note: this is purposely not called \spadfun{coerce} which would
+ ++ cause the interpreter to do this automatically.
+
+ exponent: % -> Integer
+ ++ exponent(u) returns the exponent of the first factor of
+ ++ \spadvar{u}, or 0 if the factored form consists solely of a unit.
+
+ makeFR : (R, List FF) -> %
+ ++ makeFR(unit,listOfFactors) creates a factored object (for
+ ++ use by factoring code).
+
+ factorList : % -> List FF
+ ++ factorList(u) returns the list of factors with flags (for
+ ++ use by factoring code).
+
+ nilFactor: (R, Integer) -> %
+ ++ nilFactor(base,exponent) creates a factored object with
+ ++ a single factor with no information about the kind of
+ ++ base (flag = "nil").
+
+ factors: % -> List Record(factor:R, exponent:Integer)
+ ++ factors(u) returns a list of the factors in a form suitable
+ ++ for iteration. That is, it returns a list where each element
+ ++ is a record containing a base and exponent. The original
+ ++ object is the product of all the factors and the unit (which
+ ++ can be extracted by \axiom{unit(u)}).
+
+ irreducibleFactor: (R, Integer) -> %
+ ++ irreducibleFactor(base,exponent) creates a factored object with
+ ++ a single factor whose base is asserted to be irreducible
+ ++ (flag = "irred").
+
+ nthExponent: (%, Integer) -> Integer
+ ++ nthExponent(u,n) returns the exponent of the nth factor of
+ ++ \spadvar{u}. If \spadvar{n} is not a valid index for a factor
+ ++ (for example, less than 1 or too big), 0 is returned.
+
+ nthFactor: (%,Integer) -> R
+ ++ nthFactor(u,n) returns the base of the nth factor of
+ ++ \spadvar{u}. If \spadvar{n} is not a valid index for a factor
+ ++ (for example, less than 1 or too big), 1 is returned. If
+ ++ \spadvar{u} consists only of a unit, the unit is returned.
+
+ nthFlag: (%,Integer) -> fUnion
+ ++ nthFlag(u,n) returns the information flag of the nth factor of
+ ++ \spadvar{u}. If \spadvar{n} is not a valid index for a factor
+ ++ (for example, less than 1 or too big), "nil" is returned.
+
+ numberOfFactors : % -> NonNegativeInteger
+ ++ numberOfFactors(u) returns the number of factors in \spadvar{u}.
+
+ primeFactor: (R,Integer) -> %
+ ++ primeFactor(base,exponent) creates a factored object with
+ ++ a single factor whose base is asserted to be prime
+ ++ (flag = "prime").
+
+ sqfrFactor: (R,Integer) -> %
+ ++ sqfrFactor(base,exponent) creates a factored object with
+ ++ a single factor whose base is asserted to be square-free
+ ++ (flag = "sqfr").
+
+ flagFactor: (R,Integer, fUnion) -> %
+ ++ flagFactor(base,exponent,flag) creates a factored object with
+ ++ a single factor whose base is asserted to be properly
+ ++ described by the information flag.
+
+ unit: % -> R
+ ++ unit(u) extracts the unit part of the factorization.
+
+ unitNormalize: % -> %
+ ++ unitNormalize(u) normalizes the unit part of the factorization.
+ ++ For example, when working with factored integers, this operation will
+ ++ ensure that the bases are all positive integers.
+
+ map: (R -> R, %) -> %
+ ++ map(fn,u) maps the function \userfun{fn} across the factors of
+ ++ \spadvar{u} and creates a new factored object. Note: this clears
+ ++ the information flags (sets them to "nil") because the effect of
+ ++ \userfun{fn} is clearly not known in general.
+
+ -- the following operations are conditional on R
+
+ if R has GcdDomain then GcdDomain
+ if R has RealConstant then RealConstant
+ if R has UniqueFactorizationDomain then UniqueFactorizationDomain
+
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+
+ if R has IntegerNumberSystem then
+ rational? : % -> Boolean
+ ++ rational?(u) tests if \spadvar{u} is actually a
+ ++ rational number (see \spadtype{Fraction Integer}).
+ rational : % -> Fraction Integer
+ ++ rational(u) assumes spadvar{u} is actually a rational number
+ ++ and does the conversion to rational number
+ ++ (see \spadtype{Fraction Integer}).
+ rationalIfCan: % -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(u) returns a rational number if u
+ ++ really is one, and "failed" otherwise.
+
+ if R has Eltable(%, %) then Eltable(%, %)
+ if R has Evalable(%) then Evalable(%)
+ if R has InnerEvalable(Symbol, %) then InnerEvalable(Symbol, %)
+
+ Implementation ==> add
+
+ -- Representation:
+ -- Note: exponents are allowed to be integers so that some special cases
+ -- may be used in simplications
+ Rep := Record(unt:R, fct:List FF)
+
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm ==
+ empty?(lf := reverse factorList x) => convert(unit x)@InputForm
+ l := empty()$List(InputForm)
+ for rec in lf repeat
+-- one?(rec.fctr) => l
+ ((rec.fctr) = 1) => l
+ iFactor : InputForm := binary( convert("::" :: Symbol)@InputForm, [convert(rec.fctr)@InputForm, (devaluate R)$Lisp :: InputForm ]$List(InputForm) )
+ iExpon : InputForm := convert(rec.xpnt)@InputForm
+ iFun : List InputForm :=
+ rec.flg case "nil" =>
+ [convert("nilFactor" :: Symbol)@InputForm, iFactor, iExpon]$List(InputForm)
+ rec.flg case "sqfr" =>
+ [convert("sqfrFactor" :: Symbol)@InputForm, iFactor, iExpon]$List(InputForm)
+ rec.flg case "prime" =>
+ [convert("primeFactor" :: Symbol)@InputForm, iFactor, iExpon]$List(InputForm)
+ rec.flg case "irred" =>
+ [convert("irreducibleFactor" :: Symbol)@InputForm, iFactor, iExpon]$List(InputForm)
+ nil$List(InputForm)
+ l := concat( iFun pretend InputForm, l )
+-- one?(rec.xpnt) =>
+-- l := concat(convert(rec.fctr)@InputForm, l)
+-- l := concat(convert(rec.fctr)@InputForm ** rec.xpnt, l)
+ empty? l => convert(unit x)@InputForm
+ if unit x ^= 1 then l := concat(convert(unit x)@InputForm,l)
+ empty? rest l => first l
+ binary(convert(_*::Symbol)@InputForm, l)@InputForm
+
+ orderedR? := R has OrderedSet
+
+ -- Private function signatures:
+ reciprocal : % -> %
+ qexpand : % -> R
+ negexp? : % -> Boolean
+ SimplifyFactorization : List FF -> List FF
+ LispLessP : (FF, FF) -> Boolean
+ mkFF : (R, List FF) -> %
+ SimplifyFactorization1 : (FF, List FF) -> List FF
+ stricterFlag : (fUnion, fUnion) -> fUnion
+
+ nilFactor(r, i) == flagFactor(r, i, "nil")
+ sqfrFactor(r, i) == flagFactor(r, i, "sqfr")
+ irreducibleFactor(r, i) == flagFactor(r, i, "irred")
+ primeFactor(r, i) == flagFactor(r, i, "prime")
+ unit? u == (empty? u.fct) and (not zero? u.unt)
+ factorList u == u.fct
+ unit u == u.unt
+ numberOfFactors u == # u.fct
+ 0 == [1, [["nil", 0, 1]$FF]]
+ zero? u == # u.fct = 1 and
+ (first u.fct).flg case "nil" and
+ zero? (first u.fct).fctr and
+-- one? u.unt
+ (u.unt = 1)
+ 1 == [1, empty()]
+ one? u == empty? u.fct and u.unt = 1
+ mkFF(r, x) == [r, x]
+ coerce(j:Integer):% == (j::R)::%
+ characteristic() == characteristic()$R
+ i:Integer * u:% == (i :: %) * u
+ r:R * u:% == (r :: %) * u
+ factors u == [[fe.fctr, fe.xpnt] for fe in factorList u]
+ expand u == retract u
+ negexp? x == "or"/[negative?(y.xpnt) for y in factorList x]
+
+ makeFR(u, l) ==
+-- normalizing code to be installed when contents are handled better
+-- current squareFree returns the content as a unit part.
+-- if (not unit?(u)) then
+-- l := cons(["nil", u, 1]$FF,l)
+-- u := 1
+ unitNormalize mkFF(u, SimplifyFactorization l)
+
+ if R has IntegerNumberSystem then
+ rational? x == true
+ rationalIfCan x == rational x
+
+ rational x ==
+ convert(unit x)@Integer *
+ _*/[(convert(f.fctr)@Integer)::Fraction(Integer)
+ ** f.xpnt for f in factorList x]
+
+ if R has Eltable(R, R) then
+ elt(x:%, v:%) == x(expand v)
+
+ if R has Evalable(R) then
+ eval(x:%, l:List Equation %) ==
+ eval(x,[expand lhs e = expand rhs e for e in l]$List(Equation R))
+
+ if R has InnerEvalable(Symbol, R) then
+ eval(x:%, ls:List Symbol, lv:List %) ==
+ eval(x, ls, [expand v for v in lv]$List(R))
+
+ if R has RealConstant then
+ --! negcount and rest commented out since RealConstant doesn't support
+ --! positive? or negative?
+ -- negcount: % -> Integer
+ -- positive?(x:%):Boolean == not(zero? x) and even?(negcount x)
+ -- negative?(x:%):Boolean == not(zero? x) and odd?(negcount x)
+ -- negcount x ==
+ -- n := count(negative?(#1.fctr), factorList x)$List(FF)
+ -- negative? unit x => n + 1
+ -- n
+
+ convert(x:%):Float ==
+ convert(unit x)@Float *
+ _*/[convert(f.fctr)@Float ** f.xpnt for f in factorList x]
+
+ convert(x:%):DoubleFloat ==
+ convert(unit x)@DoubleFloat *
+ _*/[convert(f.fctr)@DoubleFloat ** f.xpnt for f in factorList x]
+
+ u:% * v:% ==
+ zero? u or zero? v => 0
+-- one? u => v
+ (u = 1) => v
+-- one? v => u
+ (v = 1) => u
+ mkFF(unit u * unit v,
+ SimplifyFactorization concat(factorList u, copy factorList v))
+
+ u:% ** n:NonNegativeInteger ==
+ mkFF(unit(u)**n, [[x.flg, x.fctr, n * x.xpnt] for x in factorList u])
+
+ SimplifyFactorization x ==
+ empty? x => empty()
+ x := sort_!(LispLessP, x)
+ x := SimplifyFactorization1(first x, rest x)
+ if orderedR? then x := sort_!(LispLessP, x)
+ x
+
+ SimplifyFactorization1(f, x) ==
+ empty? x =>
+ zero?(f.xpnt) => empty()
+ list f
+ f1 := first x
+ f.fctr = f1.fctr =>
+ SimplifyFactorization1([stricterFlag(f.flg, f1.flg),
+ f.fctr, f.xpnt + f1.xpnt], rest x)
+ l := SimplifyFactorization1(first x, rest x)
+ zero?(f.xpnt) => l
+ concat(f, l)
+
+
+ coerce(x:%):OutputForm ==
+ empty?(lf := reverse factorList x) => (unit x)::OutputForm
+ l := empty()$List(OutputForm)
+ for rec in lf repeat
+-- one?(rec.fctr) => l
+ ((rec.fctr) = 1) => l
+-- one?(rec.xpnt) =>
+ ((rec.xpnt) = 1) =>
+ l := concat(rec.fctr :: OutputForm, l)
+ l := concat(rec.fctr::OutputForm ** rec.xpnt::OutputForm, l)
+ empty? l => (unit x) :: OutputForm
+ e :=
+ empty? rest l => first l
+ reduce(_*, l)
+ 1 = unit x => e
+ (unit x)::OutputForm * e
+
+ retract(u:%):R ==
+ negexp? u => error "Negative exponent in factored object"
+ qexpand u
+
+ qexpand u ==
+ unit u *
+ _*/[y.fctr ** (y.xpnt::NonNegativeInteger) for y in factorList u]
+
+ retractIfCan(u:%):Union(R, "failed") ==
+ negexp? u => "failed"
+ qexpand u
+
+ LispLessP(y, y1) ==
+ orderedR? => y.fctr < y1.fctr
+ GGREATERP(y.fctr, y1.fctr)$Lisp => false
+ true
+
+ stricterFlag(fl1, fl2) ==
+ fl1 case "prime" => fl1
+ fl1 case "irred" =>
+ fl2 case "prime" => fl2
+ fl1
+ fl1 case "sqfr" =>
+ fl2 case "nil" => fl1
+ fl2
+ fl2
+
+ if R has IntegerNumberSystem
+ then
+ coerce(r:R):% ==
+ factor(r)$IntegerFactorizationPackage(R) pretend %
+ else
+ if R has UniqueFactorizationDomain
+ then
+ coerce(r:R):% ==
+ zero? r => 0
+ unit? r => mkFF(r, empty())
+ unitNormalize(squareFree(r) pretend %)
+ else
+ coerce(r:R):% ==
+-- one? r => 1
+ (r = 1) => 1
+ unitNormalize mkFF(1, [["nil", r, 1]$FF])
+
+ u = v ==
+ (unit u = unit v) and # u.fct = # v.fct and
+ set(factors u)$SRFE =$SRFE set(factors v)$SRFE
+
+ - u ==
+ zero? u => u
+ mkFF(- unit u, factorList u)
+
+ recip u ==
+ not empty? factorList u => "failed"
+ (r := recip unit u) case "failed" => "failed"
+ mkFF(r::R, empty())
+
+ reciprocal u ==
+ mkFF((recip unit u)::R,
+ [[y.flg, y.fctr, - y.xpnt]$FF for y in factorList u])
+
+ exponent u == -- exponent of first factor
+ empty?(fl := factorList u) or zero? u => 0
+ first(fl).xpnt
+
+ nthExponent(u, i) ==
+ l := factorList u
+ zero? u or i < 1 or i > #l => 0
+ (l.(minIndex(l) + i - 1)).xpnt
+
+ nthFactor(u, i) ==
+ zero? u => 0
+ zero? i => unit u
+ l := factorList u
+ negative? i or i > #l => 1
+ (l.(minIndex(l) + i - 1)).fctr
+
+ nthFlag(u, i) ==
+ l := factorList u
+ zero? u or i < 1 or i > #l => "nil"
+ (l.(minIndex(l) + i - 1)).flg
+
+ flagFactor(r, i, fl) ==
+ zero? i => 1
+ zero? r => 0
+ unitNormalize mkFF(1, [[fl, r, i]$FF])
+
+ differentiate(u:%, deriv: R -> R) ==
+ ans := deriv(unit u) * ((u exquo unit(u)::%)::%)
+ ans + (_+/[fact.xpnt * deriv(fact.fctr) *
+ ((u exquo nilFactor(fact.fctr, 1))::%) for fact in factorList u])
+
+@
+
+This operation provides an implementation of [[differentiate]] from the
+category [[DifferentialExtension]]. It uses the formula
+
+$$\frac{d}{dx} f(x) = \sum_{i=1}^n \frac{f(x)}{f_i(x)}\frac{d}{dx}f_i(x),$$
+
+where
+
+$$f(x)=\prod_{i=1}^n f_i(x).$$
+
+Note that up to [[patch--40]] the following wrong definition was used:
+
+\begin{verbatim}
+ differentiate(u:%, deriv: R -> R) ==
+ ans := deriv(unit u) * ((u exquo (fr := unit(u)::%))::%)
+ ans + fr * (_+/[fact.xpnt * deriv(fact.fctr) *
+ ((u exquo nilFactor(fact.fctr, 1))::%) for fact in factorList u])
+\end{verbatim}
+
+which causes wrong results as soon as units are involved, for example in
+
+<<TEST FR>>=
+ D(factor (-x), x)
+@
+
+(Issue~\#176)
+
+<<domain FR Factored>>=
+ map(fn, u) ==
+ fn(unit u) * _*/[irreducibleFactor(fn(f.fctr),f.xpnt) for f in factorList u]
+
+ u exquo v ==
+ empty?(x1 := factorList v) => unitNormal(retract v).associate * u
+ empty? factorList u => "failed"
+ v1 := u * reciprocal v
+ goodQuotient:Boolean := true
+ while (goodQuotient and (not empty? x1)) repeat
+ if x1.first.xpnt < 0
+ then goodQuotient := false
+ else x1 := rest x1
+ goodQuotient => v1
+ "failed"
+
+ unitNormal u == -- does a bunch of work, but more canonical
+ (ur := recip(un := unit u)) case "failed" => [1, u, 1]
+ as := ur::R
+ vl := empty()$List(FF)
+ for x in factorList u repeat
+ ucar := unitNormal(x.fctr)
+ e := abs(x.xpnt)::NonNegativeInteger
+ if x.xpnt < 0
+ then -- associate is recip of unit
+ un := un * (ucar.associate ** e)
+ as := as * (ucar.unit ** e)
+ else
+ un := un * (ucar.unit ** e)
+ as := as * (ucar.associate ** e)
+-- if not one?(ucar.canonical) then
+ if not ((ucar.canonical) = 1) then
+ vl := concat([x.flg, ucar.canonical, x.xpnt], vl)
+ [mkFF(un, empty()), mkFF(1, reverse_! vl), mkFF(as, empty())]
+
+ unitNormalize u ==
+ uca := unitNormal u
+ mkFF(unit(uca.unit)*unit(uca.canonical),factorList(uca.canonical))
+
+ if R has GcdDomain then
+ u + v ==
+ zero? u => v
+ zero? v => u
+ v1 := reciprocal(u1 := gcd(u, v))
+ (expand(u * v1) + expand(v * v1)) * u1
+
+ gcd(u, v) ==
+-- one? u or one? v => 1
+ (u = 1) or (v = 1) => 1
+ zero? u => v
+ zero? v => u
+ f1 := empty()$List(Integer) -- list of used factor indices in x
+ f2 := f1 -- list of indices corresponding to a given factor
+ f3 := empty()$List(List Integer) -- list of f2-like lists
+ x := concat(factorList u, factorList v)
+ for i in minIndex x .. maxIndex x repeat
+ if not member?(i, f1) then
+ f1 := concat(i, f1)
+ f2 := [i]
+ for j in i+1..maxIndex x repeat
+ if x.i.fctr = x.j.fctr then
+ f1 := concat(j, f1)
+ f2 := concat(j, f2)
+ f3 := concat(f2, f3)
+ x1 := empty()$List(FF)
+ while not empty? f3 repeat
+ f1 := first f3
+ if #f1 > 1 then
+ i := first f1
+ y := copy x.i
+ f1 := rest f1
+ while not empty? f1 repeat
+ i := first f1
+ if x.i.xpnt < y.xpnt then y.xpnt := x.i.xpnt
+ f1 := rest f1
+ x1 := concat(y, x1)
+ f3 := rest f3
+ if orderedR? then x1 := sort_!(LispLessP, x1)
+ mkFF(1, x1)
+
+ else -- R not a GCD domain
+ u + v ==
+ zero? u => v
+ zero? v => u
+ irreducibleFactor(expand u + expand v, 1)
+
+ if R has UniqueFactorizationDomain then
+ prime? u ==
+ not(empty?(l := factorList u)) and (empty? rest l) and
+-- one?(l.first.xpnt) and (l.first.flg case "prime")
+ ((l.first.xpnt) = 1) and (l.first.flg case "prime")
+
+@
+\section{package FRUTIL FactoredFunctionUtilities}
+<<package FRUTIL FactoredFunctionUtilities>>=
+)abbrev package FRUTIL FactoredFunctionUtilities
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: refine, mergeFactors
+++ Related Constructors: Factored
+++ Also See:
+++ AMS Classifications: 11A51, 11Y05
+++ Keywords: factor
+++ References:
+++ Description:
+++ \spadtype{FactoredFunctionUtilities} implements some utility
+++ functions for manipulating factored objects.
+FactoredFunctionUtilities(R): Exports == Implementation where
+ R: IntegralDomain
+ FR ==> Factored R
+
+ Exports ==> with
+ refine: (FR, R-> FR) -> FR
+ ++ refine(u,fn) is used to apply the function \userfun{fn} to
+ ++ each factor of \spadvar{u} and then build a new factored
+ ++ object from the results. For example, if \spadvar{u} were
+ ++ created by calling \spad{nilFactor(10,2)} then
+ ++ \spad{refine(u,factor)} would create a factored object equal
+ ++ to that created by \spad{factor(100)} or
+ ++ \spad{primeFactor(2,2) * primeFactor(5,2)}.
+
+ mergeFactors: (FR,FR) -> FR
+ ++ mergeFactors(u,v) is used when the factorizations of \spadvar{u}
+ ++ and \spadvar{v} are known to be disjoint, e.g. resulting from a
+ ++ content/primitive part split. Essentially, it creates a new
+ ++ factored object by multiplying the units together and appending
+ ++ the lists of factors.
+
+ Implementation ==> add
+ fg: FR
+ func: R -> FR
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FF ==> Record(flg: fUnion, fctr: R, xpnt: Integer)
+
+ mergeFactors(f,g) ==
+ makeFR(unit(f)*unit(g),append(factorList f,factorList g))
+
+ refine(f, func) ==
+ u := unit(f)
+ l: List FF := empty()
+ for item in factorList f repeat
+ fitem := func item.fctr
+ u := u*unit(fitem) ** (item.xpnt :: NonNegativeInteger)
+ if item.xpnt = 1 then
+ l := concat(factorList fitem,l)
+ else l := concat([[v.flg,v.fctr,v.xpnt*item.xpnt]
+ for v in factorList fitem],l)
+ makeFR(u,l)
+
+@
+\section{package FR2 FactoredFunctions2}
+<<package FR2 FactoredFunctions2>>=
+)abbrev package FR2 FactoredFunctions2
+++ Author: Robert S. Sutor
+++ Date Created: 1987
+++ Change History:
+++ Basic Operations: map
+++ Related Constructors: Factored
+++ Also See:
+++ AMS Classifications: 11A51, 11Y05
+++ Keywords: map, factor
+++ References:
+++ Description:
+++ \spadtype{FactoredFunctions2} contains functions that involve
+++ factored objects whose underlying domains may not be the same.
+++ For example, \spadfun{map} might be used to coerce an object of
+++ type \spadtype{Factored(Integer)} to
+++ \spadtype{Factored(Complex(Integer))}.
+FactoredFunctions2(R, S): Exports == Implementation where
+ R: IntegralDomain
+ S: IntegralDomain
+
+ Exports ==> with
+ map: (R -> S, Factored R) -> Factored S
+ ++ map(fn,u) is used to apply the function \userfun{fn} to every
+ ++ factor of \spadvar{u}. The new factored object will have all its
+ ++ information flags set to "nil". This function is used, for
+ ++ example, to coerce every factor base to another type.
+
+ Implementation ==> add
+ map(func, f) ==
+ func(unit f) *
+ _*/[nilFactor(func(g.factor), g.exponent) for g in factors f]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FR Factored>>
+<<package FRUTIL FactoredFunctionUtilities>>
+<<package FR2 FactoredFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fraction.spad.pamphlet b/src/algebra/fraction.spad.pamphlet
new file mode 100644
index 00000000..51cbb0d4
--- /dev/null
+++ b/src/algebra/fraction.spad.pamphlet
@@ -0,0 +1,846 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fraction.spad}
+\author{Dave Barton, Barry Trager, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain LO Localize}
+<<domain LO Localize>>=
+)abbrev domain LO Localize
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: + - / numer denom
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: localization
+++ References:
+++ Description: Localize(M,R,S) produces fractions with numerators
+++ from an R module M and denominators from some multiplicative subset
+++ D of R.
+Localize(M:Module R,
+ R:CommutativeRing,
+ S:SubsetCategory(Monoid, R)): Module R with
+ if M has OrderedAbelianGroup then OrderedAbelianGroup
+ _/ :(%,S) -> %
+ ++ x / d divides the element x by d.
+ _/ :(M,S) -> %
+ ++ m / d divides the element m by d.
+ numer: % -> M
+ ++ numer x returns the numerator of x.
+ denom: % -> S
+ ++ denom x returns the denominator of x.
+ ==
+ add
+ --representation
+ Rep:= Record(num:M,den:S)
+ --declarations
+ x,y: %
+ n: Integer
+ m: M
+ r: R
+ d: S
+ --definitions
+ 0 == [0,1]
+ zero? x == zero? (x.num)
+ -x== [-x.num,x.den]
+ x=y == y.den*x.num = x.den*y.num
+ numer x == x.num
+ denom x == x.den
+ if M has OrderedAbelianGroup then
+ x < y ==
+-- if y.den::R < 0 then (x,y):=(y,x)
+-- if x.den::R < 0 then (x,y):=(y,x)
+ y.den*x.num < x.den*y.num
+ x+y == [y.den*x.num+x.den*y.num, x.den*y.den]
+ n*x == [n*x.num,x.den]
+ r*x == if r=x.den then [x.num,1] else [r*x.num,x.den]
+ x/d ==
+ zero?(u:S:=d*x.den) => error "division by zero"
+ [x.num,u]
+ m/d == if zero? d then error "division by zero" else [m,d]
+ coerce(x:%):OutputForm ==
+-- one?(xd:=x.den) => (x.num)::OutputForm
+ ((xd:=x.den) = 1) => (x.num)::OutputForm
+ (x.num)::OutputForm / (xd::OutputForm)
+ latex(x:%): String ==
+-- one?(xd:=x.den) => latex(x.num)
+ ((xd:=x.den) = 1) => latex(x.num)
+ nl : String := concat("{", concat(latex(x.num), "}")$String)$String
+ dl : String := concat("{", concat(latex(x.den), "}")$String)$String
+ concat("{ ", concat(nl, concat(" \over ", concat(dl, " }")$String)$String)$String)$String
+
+@
+\section{domain LA LocalAlgebra}
+<<domain LA LocalAlgebra>>=
+)abbrev domain LA LocalAlgebra
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: LocalAlgebra produces the localization of an algebra, i.e.
+++ fractions whose numerators come from some R algebra.
+LocalAlgebra(A: Algebra R,
+ R: CommutativeRing,
+ S: SubsetCategory(Monoid, R)): Algebra R with
+ if A has OrderedRing then OrderedRing
+ _/ : (%,S) -> %
+ ++ x / d divides the element x by d.
+ _/ : (A,S) -> %
+ ++ a / d divides the element \spad{a} by d.
+ numer: % -> A
+ ++ numer x returns the numerator of x.
+ denom: % -> S
+ ++ denom x returns the denominator of x.
+ == Localize(A, R, S) add
+ 1 == 1$A / 1$S
+ x:% * y:% == (numer(x) * numer(y)) / (denom(x) * denom(y))
+ characteristic() == characteristic()$A
+
+@
+\section{category QFCAT QuotientFieldCategory}
+<<category QFCAT QuotientFieldCategory>>=
+)abbrev category QFCAT QuotientFieldCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated: 5th March 1996
+++ Basic Functions: + - * / numer denom
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: QuotientField(S) is the
+++ category of fractions of an Integral Domain S.
+QuotientFieldCategory(S: IntegralDomain): Category ==
+ Join(Field, Algebra S, RetractableTo S, FullyEvalableOver S,
+ DifferentialExtension S, FullyLinearlyExplicitRingOver S,
+ Patternable S, FullyPatternMatchable S) with
+ _/ : (S, S) -> %
+ ++ d1 / d2 returns the fraction d1 divided by d2.
+ numer : % -> S
+ ++ numer(x) returns the numerator of the fraction x.
+ denom : % -> S
+ ++ denom(x) returns the denominator of the fraction x.
+ numerator : % -> %
+ ++ numerator(x) is the numerator of the fraction x converted to %.
+ denominator : % -> %
+ ++ denominator(x) is the denominator of the fraction x converted to %.
+ if S has StepThrough then StepThrough
+ if S has RetractableTo Integer then
+ RetractableTo Integer
+ RetractableTo Fraction Integer
+ if S has OrderedSet then OrderedSet
+ if S has OrderedIntegralDomain then OrderedIntegralDomain
+ if S has RealConstant then RealConstant
+ if S has ConvertibleTo InputForm then ConvertibleTo InputForm
+ if S has CharacteristicZero then CharacteristicZero
+ if S has CharacteristicNonZero then CharacteristicNonZero
+ if S has RetractableTo Symbol then RetractableTo Symbol
+ if S has EuclideanDomain then
+ wholePart: % -> S
+ ++ wholePart(x) returns the whole part of the fraction x
+ ++ i.e. the truncated quotient of the numerator by the denominator.
+ fractionPart: % -> %
+ ++ fractionPart(x) returns the fractional part of x.
+ ++ x = wholePart(x) + fractionPart(x)
+ if S has IntegerNumberSystem then
+ random: () -> %
+ ++ random() returns a random fraction.
+ ceiling : % -> S
+ ++ ceiling(x) returns the smallest integral element above x.
+ floor: % -> S
+ ++ floor(x) returns the largest integral element below x.
+ if S has PolynomialFactorizationExplicit then
+ PolynomialFactorizationExplicit
+
+ add
+ import MatrixCommonDenominator(S, %)
+ numerator(x) == numer(x)::%
+ denominator(x) == denom(x) ::%
+
+ if S has StepThrough then
+ init() == init()$S / 1$S
+
+ nextItem(n) ==
+ m:= nextItem(numer(n))
+ m case "failed" =>
+ error "We seem to have a Fraction of a finite object"
+ m / 1
+
+ map(fn, x) == (fn numer x) / (fn denom x)
+ reducedSystem(m:Matrix %):Matrix S == clearDenominator m
+ characteristic() == characteristic()$S
+
+ differentiate(x:%, deriv:S -> S) ==
+ n := numer x
+ d := denom x
+ (deriv n * d - n * deriv d) / (d**2)
+
+ if S has ConvertibleTo InputForm then
+ convert(x:%):InputForm == (convert numer x) / (convert denom x)
+
+ if S has RealConstant then
+ convert(x:%):Float == (convert numer x) / (convert denom x)
+ convert(x:%):DoubleFloat == (convert numer x) / (convert denom x)
+
+ -- Note that being a Join(OrderedSet,IntegralDomain) is not the same
+ -- as being an OrderedIntegralDomain.
+ if S has OrderedIntegralDomain then
+ if S has canonicalUnitNormal then
+ x:% < y:% ==
+ (numer x * denom y) < (numer y * denom x)
+ else
+ x:% < y:% ==
+ if denom(x) < 0 then (x,y):=(y,x)
+ if denom(y) < 0 then (x,y):=(y,x)
+ (numer x * denom y) < (numer y * denom x)
+ else if S has OrderedSet then
+ x:% < y:% ==
+ (numer x * denom y) < (numer y * denom x)
+
+ if (S has EuclideanDomain) then
+ fractionPart x == x - (wholePart(x)::%)
+
+ if S has RetractableTo Symbol then
+ coerce(s:Symbol):% == s::S::%
+ retract(x:%):Symbol == retract(retract(x)@S)
+
+ retractIfCan(x:%):Union(Symbol, "failed") ==
+ (r := retractIfCan(x)@Union(S,"failed")) case "failed" =>"failed"
+ retractIfCan(r::S)
+
+ if (S has ConvertibleTo Pattern Integer) then
+ convert(x:%):Pattern(Integer)==(convert numer x)/(convert denom x)
+
+ if (S has PatternMatchable Integer) then
+ patternMatch(x:%, p:Pattern Integer,
+ l:PatternMatchResult(Integer, %)) ==
+ patternMatch(x, p,
+ l)$PatternMatchQuotientFieldCategory(Integer, S, %)
+
+ if (S has ConvertibleTo Pattern Float) then
+ convert(x:%):Pattern(Float) == (convert numer x)/(convert denom x)
+
+ if (S has PatternMatchable Float) then
+ patternMatch(x:%, p:Pattern Float,
+ l:PatternMatchResult(Float, %)) ==
+ patternMatch(x, p,
+ l)$PatternMatchQuotientFieldCategory(Float, S, %)
+
+ if S has RetractableTo Integer then
+ coerce(x:Fraction Integer):% == numer(x)::% / denom(x)::%
+
+ if not(S is Integer) then
+ retract(x:%):Integer == retract(retract(x)@S)
+
+ retractIfCan(x:%):Union(Integer, "failed") ==
+ (u := retractIfCan(x)@Union(S, "failed")) case "failed" =>
+ "failed"
+ retractIfCan(u::S)
+
+ if S has IntegerNumberSystem then
+ random():% ==
+ while zero?(d:=random()$S) repeat d
+ random()$S / d
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix S, vec:Vector S) ==
+ n := reducedSystem(horizConcat(v::Matrix(%), m))@Matrix(S)
+ [subMatrix(n, minRowIndex n, maxRowIndex n, 1 + minColIndex n,
+ maxColIndex n), column(n, minColIndex n)]
+
+@
+\section{QFCAT.lsp BOOTSTRAP}
+{\bf QFCAT} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf QFCAT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf QFCAT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<QFCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |QuotientFieldCategory;CAT| (QUOTE NIL))
+
+(SETQ |QuotientFieldCategory;AL| (QUOTE NIL))
+
+(DEFUN |QuotientFieldCategory| (#1=#:G103631) (LET (#2=#:G103632) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |QuotientFieldCategory;AL|)) (CDR #2#)) (T (SETQ |QuotientFieldCategory;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|QuotientFieldCategory;| #1#))) |QuotientFieldCategory;AL|)) #2#))))
+
+(DEFUN |QuotientFieldCategory;| (|t#1|) (PROG (#1=#:G103630) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (COND (|QuotientFieldCategory;CAT|) ((QUOTE T) (LETT |QuotientFieldCategory;CAT| (|Join| (|Field|) (|Algebra| (QUOTE |t#1|)) (|RetractableTo| (QUOTE |t#1|)) (|FullyEvalableOver| (QUOTE |t#1|)) (|DifferentialExtension| (QUOTE |t#1|)) (|FullyLinearlyExplicitRingOver| (QUOTE |t#1|)) (|Patternable| (QUOTE |t#1|)) (|FullyPatternMatchable| (QUOTE |t#1|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|/| (|$| |t#1| |t#1|)) T) ((|numer| (|t#1| |$|)) T) ((|denom| (|t#1| |$|)) T) ((|numerator| (|$| |$|)) T) ((|denominator| (|$| |$|)) T) ((|wholePart| (|t#1| |$|)) (|has| |t#1| (|EuclideanDomain|))) ((|fractionPart| (|$| |$|)) (|has| |t#1| (|EuclideanDomain|))) ((|random| (|$|)) (|has| |t#1| (|IntegerNumberSystem|))) ((|ceiling| (|t#1| |$|)) (|has| |t#1| (|IntegerNumberSystem|))) ((|floor| (|t#1| |$|)) (|has| |t#1| (|IntegerNumberSystem|))))) (QUOTE (((|StepThrough|) (|has| |t#1| (|StepThrough|))) ((|RetractableTo| (|Integer|)) (|has| |t#1| (|RetractableTo| (|Integer|)))) ((|RetractableTo| (|Fraction| (|Integer|))) (|has| |t#1| (|RetractableTo| (|Integer|)))) ((|OrderedSet|) (|has| |t#1| (|OrderedSet|))) ((|OrderedIntegralDomain|) (|has| |t#1| (|OrderedIntegralDomain|))) ((|RealConstant|) (|has| |t#1| (|RealConstant|))) ((|ConvertibleTo| (|InputForm|)) (|has| |t#1| (|ConvertibleTo| (|InputForm|)))) ((|CharacteristicZero|) (|has| |t#1| (|CharacteristicZero|))) ((|CharacteristicNonZero|) (|has| |t#1| (|CharacteristicNonZero|))) ((|RetractableTo| (|Symbol|)) (|has| |t#1| (|RetractableTo| (|Symbol|)))) ((|PolynomialFactorizationExplicit|) (|has| |t#1| (|PolynomialFactorizationExplicit|))))) (QUOTE NIL) NIL)) . #2=(|QuotientFieldCategory|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |QuotientFieldCategory|) (|devaluate| |t#1|)))))))
+@
+\section{QFCAT-.lsp BOOTSTRAP}
+{\bf QFCAT-} depends on {\bf QFCAT}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf QFCAT-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf QFCAT-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<QFCAT-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |QFCAT-;numerator;2A;1| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (QREFELT |$| 9)))
+
+(DEFUN |QFCAT-;denominator;2A;2| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 9)))
+
+(DEFUN |QFCAT-;init;A;3| (|$|) (SPADCALL (|spadConstant| |$| 13) (|spadConstant| |$| 14) (QREFELT |$| 15)))
+
+(DEFUN |QFCAT-;nextItem;AU;4| (|n| |$|) (PROG (|m|) (RETURN (SEQ (LETT |m| (SPADCALL (SPADCALL |n| (QREFELT |$| 8)) (QREFELT |$| 18)) |QFCAT-;nextItem;AU;4|) (EXIT (COND ((QEQCAR |m| 1) (|error| "We seem to have a Fraction of a finite object")) ((QUOTE T) (CONS 0 (SPADCALL (QCDR |m|) (|spadConstant| |$| 14) (QREFELT |$| 15))))))))))
+
+(DEFUN |QFCAT-;map;M2A;5| (|fn| |x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) |fn|) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) |fn|) (QREFELT |$| 15)))
+
+(DEFUN |QFCAT-;reducedSystem;MM;6| (|m| |$|) (SPADCALL |m| (QREFELT |$| 26)))
+
+(DEFUN |QFCAT-;characteristic;Nni;7| (|$|) (SPADCALL (QREFELT |$| 30)))
+
+(DEFUN |QFCAT-;differentiate;AMA;8| (|x| |deriv| |$|) (PROG (|n| |d|) (RETURN (SEQ (LETT |n| (SPADCALL |x| (QREFELT |$| 8)) |QFCAT-;differentiate;AMA;8|) (LETT |d| (SPADCALL |x| (QREFELT |$| 11)) |QFCAT-;differentiate;AMA;8|) (EXIT (SPADCALL (SPADCALL (SPADCALL (SPADCALL |n| |deriv|) |d| (QREFELT |$| 32)) (SPADCALL |n| (SPADCALL |d| |deriv|) (QREFELT |$| 32)) (QREFELT |$| 33)) (SPADCALL |d| 2 (QREFELT |$| 35)) (QREFELT |$| 15)))))))
+
+(DEFUN |QFCAT-;convert;AIf;9| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (QREFELT |$| 38)) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 38)) (QREFELT |$| 39)))
+
+(DEFUN |QFCAT-;convert;AF;10| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (QREFELT |$| 42)) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 42)) (QREFELT |$| 43)))
+
+(DEFUN |QFCAT-;convert;ADf;11| (|x| |$|) (|/| (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (QREFELT |$| 46)) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 46))))
+
+(DEFUN |QFCAT-;<;2AB;12| (|x| |y| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (SPADCALL |y| (QREFELT |$| 11)) (QREFELT |$| 32)) (SPADCALL (SPADCALL |y| (QREFELT |$| 8)) (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 32)) (QREFELT |$| 49)))
+
+(DEFUN |QFCAT-;<;2AB;13| (|x| |y| |$|) (PROG (|#G19| |#G20| |#G21| |#G22|) (RETURN (SEQ (COND ((SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (|spadConstant| |$| 51) (QREFELT |$| 49)) (PROGN (LETT |#G19| |y| |QFCAT-;<;2AB;13|) (LETT |#G20| |x| |QFCAT-;<;2AB;13|) (LETT |x| |#G19| |QFCAT-;<;2AB;13|) (LETT |y| |#G20| |QFCAT-;<;2AB;13|)))) (COND ((SPADCALL (SPADCALL |y| (QREFELT |$| 11)) (|spadConstant| |$| 51) (QREFELT |$| 49)) (PROGN (LETT |#G21| |y| |QFCAT-;<;2AB;13|) (LETT |#G22| |x| |QFCAT-;<;2AB;13|) (LETT |x| |#G21| |QFCAT-;<;2AB;13|) (LETT |y| |#G22| |QFCAT-;<;2AB;13|)))) (EXIT (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (SPADCALL |y| (QREFELT |$| 11)) (QREFELT |$| 32)) (SPADCALL (SPADCALL |y| (QREFELT |$| 8)) (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 32)) (QREFELT |$| 49)))))))
+
+(DEFUN |QFCAT-;<;2AB;14| (|x| |y| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (SPADCALL |y| (QREFELT |$| 11)) (QREFELT |$| 32)) (SPADCALL (SPADCALL |y| (QREFELT |$| 8)) (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 32)) (QREFELT |$| 49)))
+
+(DEFUN |QFCAT-;fractionPart;2A;15| (|x| |$|) (SPADCALL |x| (SPADCALL (SPADCALL |x| (QREFELT |$| 52)) (QREFELT |$| 9)) (QREFELT |$| 53)))
+
+(DEFUN |QFCAT-;coerce;SA;16| (|s| |$|) (SPADCALL (SPADCALL |s| (QREFELT |$| 56)) (QREFELT |$| 9)))
+
+(DEFUN |QFCAT-;retract;AS;17| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 58)) (QREFELT |$| 59)))
+
+(DEFUN |QFCAT-;retractIfCan;AU;18| (|x| |$|) (PROG (|r|) (RETURN (SEQ (LETT |r| (SPADCALL |x| (QREFELT |$| 62)) |QFCAT-;retractIfCan;AU;18|) (EXIT (COND ((QEQCAR |r| 1) (CONS 1 "failed")) ((QUOTE T) (SPADCALL (QCDR |r|) (QREFELT |$| 64)))))))))
+
+(DEFUN |QFCAT-;convert;AP;19| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (QREFELT |$| 67)) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 67)) (QREFELT |$| 68)))
+
+(DEFUN |QFCAT-;patternMatch;AP2Pmr;20| (|x| |p| |l| |$|) (SPADCALL |x| |p| |l| (QREFELT |$| 72)))
+
+(DEFUN |QFCAT-;convert;AP;21| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 8)) (QREFELT |$| 76)) (SPADCALL (SPADCALL |x| (QREFELT |$| 11)) (QREFELT |$| 76)) (QREFELT |$| 77)))
+
+(DEFUN |QFCAT-;patternMatch;AP2Pmr;22| (|x| |p| |l| |$|) (SPADCALL |x| |p| |l| (QREFELT |$| 81)))
+
+(DEFUN |QFCAT-;coerce;FA;23| (|x| |$|) (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 86)) (QREFELT |$| 87)) (SPADCALL (SPADCALL |x| (QREFELT |$| 88)) (QREFELT |$| 87)) (QREFELT |$| 89)))
+
+(DEFUN |QFCAT-;retract;AI;24| (|x| |$|) (SPADCALL (SPADCALL |x| (QREFELT |$| 58)) (QREFELT |$| 91)))
+
+(DEFUN |QFCAT-;retractIfCan;AU;25| (|x| |$|) (PROG (|u|) (RETURN (SEQ (LETT |u| (SPADCALL |x| (QREFELT |$| 62)) |QFCAT-;retractIfCan;AU;25|) (EXIT (COND ((QEQCAR |u| 1) (CONS 1 "failed")) ((QUOTE T) (SPADCALL (QCDR |u|) (QREFELT |$| 94)))))))))
+
+(DEFUN |QFCAT-;random;A;26| (|$|) (PROG (|d|) (RETURN (SEQ (SEQ G190 (COND ((NULL (SPADCALL (LETT |d| (SPADCALL (QREFELT |$| 96)) |QFCAT-;random;A;26|) (QREFELT |$| 97))) (GO G191))) (SEQ (EXIT |d|)) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL (SPADCALL (QREFELT |$| 96)) |d| (QREFELT |$| 15)))))))
+
+(DEFUN |QFCAT-;reducedSystem;MVR;27| (|m| |v| |$|) (PROG (|n|) (RETURN (SEQ (LETT |n| (SPADCALL (SPADCALL (SPADCALL |v| (QREFELT |$| 100)) |m| (QREFELT |$| 101)) (QREFELT |$| 102)) |QFCAT-;reducedSystem;MVR;27|) (EXIT (CONS (SPADCALL |n| (SPADCALL |n| (QREFELT |$| 103)) (SPADCALL |n| (QREFELT |$| 104)) (|+| 1 (SPADCALL |n| (QREFELT |$| 105))) (SPADCALL |n| (QREFELT |$| 106)) (QREFELT |$| 107)) (SPADCALL |n| (SPADCALL |n| (QREFELT |$| 105)) (QREFELT |$| 109))))))))
+
+(DEFUN |QuotientFieldCategory&| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|QuotientFieldCategory&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |dv$| (LIST (QUOTE |QuotientFieldCategory&|) |DV$1| |DV$2|) . #1#) (LETT |$| (GETREFV 119) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#2| (QUOTE (|PolynomialFactorizationExplicit|))) (|HasCategory| |#2| (QUOTE (|IntegerNumberSystem|))) (|HasCategory| |#2| (QUOTE (|EuclideanDomain|))) (|HasCategory| |#2| (QUOTE (|RetractableTo| (|Symbol|)))) (|HasCategory| |#2| (QUOTE (|CharacteristicNonZero|))) (|HasCategory| |#2| (QUOTE (|CharacteristicZero|))) (|HasCategory| |#2| (QUOTE (|ConvertibleTo| (|InputForm|)))) (|HasCategory| |#2| (QUOTE (|RealConstant|))) (|HasCategory| |#2| (QUOTE (|OrderedIntegralDomain|))) (|HasCategory| |#2| (QUOTE (|OrderedSet|))) (|HasCategory| |#2| (QUOTE (|RetractableTo| (|Integer|)))) (|HasCategory| |#2| (QUOTE (|StepThrough|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 12) (PROGN (QSETREFV |$| 16 (CONS (|dispatchFunction| |QFCAT-;init;A;3|) |$|)) (QSETREFV |$| 20 (CONS (|dispatchFunction| |QFCAT-;nextItem;AU;4|) |$|))))) (COND ((|testBitVector| |pv$| 7) (QSETREFV |$| 40 (CONS (|dispatchFunction| |QFCAT-;convert;AIf;9|) |$|)))) (COND ((|testBitVector| |pv$| 8) (PROGN (QSETREFV |$| 44 (CONS (|dispatchFunction| |QFCAT-;convert;AF;10|) |$|)) (QSETREFV |$| 47 (CONS (|dispatchFunction| |QFCAT-;convert;ADf;11|) |$|))))) (COND ((|testBitVector| |pv$| 9) (COND ((|HasAttribute| |#2| (QUOTE |canonicalUnitNormal|)) (QSETREFV |$| 50 (CONS (|dispatchFunction| |QFCAT-;<;2AB;12|) |$|))) ((QUOTE T) (QSETREFV |$| 50 (CONS (|dispatchFunction| |QFCAT-;<;2AB;13|) |$|))))) ((|testBitVector| |pv$| 10) (QSETREFV |$| 50 (CONS (|dispatchFunction| |QFCAT-;<;2AB;14|) |$|)))) (COND ((|testBitVector| |pv$| 3) (QSETREFV |$| 54 (CONS (|dispatchFunction| |QFCAT-;fractionPart;2A;15|) |$|)))) (COND ((|testBitVector| |pv$| 4) (PROGN (QSETREFV |$| 57 (CONS (|dispatchFunction| |QFCAT-;coerce;SA;16|) |$|)) (QSETREFV |$| 60 (CONS (|dispatchFunction| |QFCAT-;retract;AS;17|) |$|)) (QSETREFV |$| 65 (CONS (|dispatchFunction| |QFCAT-;retractIfCan;AU;18|) |$|))))) (COND ((|HasCategory| |#2| (QUOTE (|ConvertibleTo| (|Pattern| (|Integer|))))) (PROGN (QSETREFV |$| 69 (CONS (|dispatchFunction| |QFCAT-;convert;AP;19|) |$|)) (COND ((|HasCategory| |#2| (QUOTE (|PatternMatchable| (|Integer|)))) (QSETREFV |$| 74 (CONS (|dispatchFunction| |QFCAT-;patternMatch;AP2Pmr;20|) |$|))))))) (COND ((|HasCategory| |#2| (QUOTE (|ConvertibleTo| (|Pattern| (|Float|))))) (PROGN (QSETREFV |$| 78 (CONS (|dispatchFunction| |QFCAT-;convert;AP;21|) |$|)) (COND ((|HasCategory| |#2| (QUOTE (|PatternMatchable| (|Float|)))) (QSETREFV |$| 83 (CONS (|dispatchFunction| |QFCAT-;patternMatch;AP2Pmr;22|) |$|))))))) (COND ((|testBitVector| |pv$| 11) (PROGN (QSETREFV |$| 90 (CONS (|dispatchFunction| |QFCAT-;coerce;FA;23|) |$|)) (COND ((|domainEqual| |#2| (|Integer|))) ((QUOTE T) (PROGN (QSETREFV |$| 92 (CONS (|dispatchFunction| |QFCAT-;retract;AI;24|) |$|)) (QSETREFV |$| 95 (CONS (|dispatchFunction| |QFCAT-;retractIfCan;AU;25|) |$|)))))))) (COND ((|testBitVector| |pv$| 2) (QSETREFV |$| 98 (CONS (|dispatchFunction| |QFCAT-;random;A;26|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |QuotientFieldCategory&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (0 . |numer|) (5 . |coerce|) |QFCAT-;numerator;2A;1| (10 . |denom|) |QFCAT-;denominator;2A;2| (15 . |init|) (19 . |One|) (23 . |/|) (29 . |init|) (|Union| |$| (QUOTE "failed")) (33 . |nextItem|) (38 . |One|) (42 . |nextItem|) (|Mapping| 7 7) |QFCAT-;map;M2A;5| (|Matrix| 7) (|Matrix| 6) (|MatrixCommonDenominator| 7 6) (47 . |clearDenominator|) (|Matrix| |$|) |QFCAT-;reducedSystem;MM;6| (|NonNegativeInteger|) (52 . |characteristic|) |QFCAT-;characteristic;Nni;7| (56 . |*|) (62 . |-|) (|PositiveInteger|) (68 . |**|) |QFCAT-;differentiate;AMA;8| (|InputForm|) (74 . |convert|) (79 . |/|) (85 . |convert|) (|Float|) (90 . |convert|) (95 . |/|) (101 . |convert|) (|DoubleFloat|) (106 . |convert|) (111 . |convert|) (|Boolean|) (116 . |<|) (122 . |<|) (128 . |Zero|) (132 . |wholePart|) (137 . |-|) (143 . |fractionPart|) (|Symbol|) (148 . |coerce|) (153 . |coerce|) (158 . |retract|) (163 . |retract|) (168 . |retract|) (|Union| 7 (QUOTE "failed")) (173 . |retractIfCan|) (|Union| 55 (QUOTE "failed")) (178 . |retractIfCan|) (183 . |retractIfCan|) (|Pattern| 84) (188 . |convert|) (193 . |/|) (199 . |convert|) (|PatternMatchResult| 84 6) (|PatternMatchQuotientFieldCategory| 84 7 6) (204 . |patternMatch|) (|PatternMatchResult| 84 |$|) (211 . |patternMatch|) (|Pattern| 41) (218 . |convert|) (223 . |/|) (229 . |convert|) (|PatternMatchResult| 41 6) (|PatternMatchQuotientFieldCategory| 41 7 6) (234 . |patternMatch|) (|PatternMatchResult| 41 |$|) (241 . |patternMatch|) (|Integer|) (|Fraction| 84) (248 . |numer|) (253 . |coerce|) (258 . |denom|) (263 . |/|) (269 . |coerce|) (274 . |retract|) (279 . |retract|) (|Union| 84 (QUOTE "failed")) (284 . |retractIfCan|) (289 . |retractIfCan|) (294 . |random|) (298 . |zero?|) (303 . |random|) (|Vector| 6) (307 . |coerce|) (312 . |horizConcat|) (318 . |reducedSystem|) (323 . |minRowIndex|) (328 . |maxRowIndex|) (333 . |minColIndex|) (338 . |maxColIndex|) (343 . |subMatrix|) (|Vector| 7) (352 . |column|) (|Record| (|:| |mat| 23) (|:| |vec| 108)) (|Vector| |$|) |QFCAT-;reducedSystem;MVR;27| (|Union| 85 (QUOTE "failed")) (|Record| (|:| |mat| 115) (|:| |vec| (|Vector| 84))) (|Matrix| 84) (|List| 55) (|List| 29) (|OutputForm|))) (QUOTE #(|retractIfCan| 358 |retract| 368 |reducedSystem| 378 |random| 389 |patternMatch| 393 |numerator| 407 |nextItem| 412 |map| 417 |init| 423 |fractionPart| 427 |differentiate| 432 |denominator| 438 |convert| 443 |coerce| 468 |characteristic| 478 |<| 482)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 112 (QUOTE (1 6 7 0 8 1 6 0 7 9 1 6 7 0 11 0 7 0 13 0 7 0 14 2 6 0 7 7 15 0 0 0 16 1 7 17 0 18 0 6 0 19 1 0 17 0 20 1 25 23 24 26 0 7 29 30 2 7 0 0 0 32 2 7 0 0 0 33 2 7 0 0 34 35 1 7 37 0 38 2 37 0 0 0 39 1 0 37 0 40 1 7 41 0 42 2 41 0 0 0 43 1 0 41 0 44 1 7 45 0 46 1 0 45 0 47 2 7 48 0 0 49 2 0 48 0 0 50 0 7 0 51 1 6 7 0 52 2 6 0 0 0 53 1 0 0 0 54 1 7 0 55 56 1 0 0 55 57 1 6 7 0 58 1 7 55 0 59 1 0 55 0 60 1 6 61 0 62 1 7 63 0 64 1 0 63 0 65 1 7 66 0 67 2 66 0 0 0 68 1 0 66 0 69 3 71 70 6 66 70 72 3 0 73 0 66 73 74 1 7 75 0 76 2 75 0 0 0 77 1 0 75 0 78 3 80 79 6 75 79 81 3 0 82 0 75 82 83 1 85 84 0 86 1 6 0 84 87 1 85 84 0 88 2 6 0 0 0 89 1 0 0 85 90 1 7 84 0 91 1 0 84 0 92 1 7 93 0 94 1 0 93 0 95 0 7 0 96 1 7 48 0 97 0 0 0 98 1 24 0 99 100 2 24 0 0 0 101 1 6 23 27 102 1 23 84 0 103 1 23 84 0 104 1 23 84 0 105 1 23 84 0 106 5 23 0 0 84 84 84 84 107 2 23 108 0 84 109 1 0 93 0 95 1 0 63 0 65 1 0 84 0 92 1 0 55 0 60 2 0 110 27 111 112 1 0 23 27 28 0 0 0 98 3 0 82 0 75 82 83 3 0 73 0 66 73 74 1 0 0 0 10 1 0 17 0 20 2 0 0 21 0 22 0 0 0 16 1 0 0 0 54 2 0 0 0 21 36 1 0 0 0 12 1 0 45 0 47 1 0 37 0 40 1 0 41 0 44 1 0 66 0 69 1 0 75 0 78 1 0 0 55 57 1 0 0 85 90 0 0 29 31 2 0 48 0 0 50)))))) (QUOTE |lookupComplete|)))
+@
+\section{package QFCAT2 QuotientFieldCategoryFunctions2}
+<<package QFCAT2 QuotientFieldCategoryFunctions2>>=
+)abbrev package QFCAT2 QuotientFieldCategoryFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package extends a function between integral domains
+++ to a mapping between their quotient fields.
+QuotientFieldCategoryFunctions2(A, B, R, S): Exports == Impl where
+ A, B: IntegralDomain
+ R : QuotientFieldCategory(A)
+ S : QuotientFieldCategory(B)
+
+ Exports ==> with
+ map: (A -> B, R) -> S
+ ++ map(func,frac) applies the function func to the numerator
+ ++ and denominator of frac.
+
+ Impl ==> add
+ map(f, r) == f(numer r) / f(denom r)
+
+@
+\section{domain FRAC Fraction}
+<<domain FRAC Fraction>>=
+)abbrev domain FRAC Fraction
+++ Author:
+++ Date Created:
+++ Date Last Updated: 12 February 1992
+++ Basic Functions: Field, numer, denom
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: fraction, localization
+++ References:
+++ Description: Fraction takes an IntegralDomain S and produces
+++ the domain of Fractions with numerators and denominators from S.
+++ If S is also a GcdDomain, then gcd's between numerator and
+++ denominator will be cancelled during all operations.
+Fraction(S: IntegralDomain): QuotientFieldCategory S with
+ if S has IntegerNumberSystem and S has OpenMath then OpenMath
+ if S has canonical and S has GcdDomain and S has canonicalUnitNormal
+ then canonical
+ ++ \spad{canonical} means that equal elements are in fact identical.
+ == LocalAlgebra(S, S, S) add
+ Rep:= Record(num:S, den:S)
+ coerce(d:S):% == [d,1]
+ zero?(x:%) == zero? x.num
+
+
+ if S has GcdDomain and S has canonicalUnitNormal then
+ retract(x:%):S ==
+-- one?(x.den) => x.num
+ ((x.den) = 1) => x.num
+ error "Denominator not equal to 1"
+
+ retractIfCan(x:%):Union(S, "failed") ==
+-- one?(x.den) => x.num
+ ((x.den) = 1) => x.num
+ "failed"
+ else
+ retract(x:%):S ==
+ (a:= x.num exquo x.den) case "failed" =>
+ error "Denominator not equal to 1"
+ a
+ retractIfCan(x:%):Union(S,"failed") == x.num exquo x.den
+
+ if S has EuclideanDomain then
+ wholePart x ==
+-- one?(x.den) => x.num
+ ((x.den) = 1) => x.num
+ x.num quo x.den
+
+ if S has IntegerNumberSystem then
+
+ floor x ==
+-- one?(x.den) => x.num
+ ((x.den) = 1) => x.num
+ x < 0 => -ceiling(-x)
+ wholePart x
+
+ ceiling x ==
+-- one?(x.den) => x.num
+ ((x.den) = 1) => x.num
+ x < 0 => -floor(-x)
+ 1 + wholePart x
+
+ if S has OpenMath then
+ -- TODO: somwhere this file does something which redefines the division
+ -- operator. Doh!
+
+ writeOMFrac(dev: OpenMathDevice, x: %): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "nums1", "rational")
+ OMwrite(dev, x.num, false)
+ OMwrite(dev, x.den, false)
+ OMputEndApp(dev)
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := _
+ OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMFrac(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := _
+ OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMFrac(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMFrac(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMFrac(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ if S has GcdDomain then
+ cancelGcd: % -> S
+ normalize: % -> %
+
+ normalize x ==
+ zero?(x.num) => 0
+-- one?(x.den) => x
+ ((x.den) = 1) => x
+ uca := unitNormal(x.den)
+ zero?(x.den := uca.canonical) => error "division by zero"
+ x.num := x.num * uca.associate
+ x
+
+ recip x ==
+ zero?(x.num) => "failed"
+ normalize [x.den, x.num]
+
+ cancelGcd x ==
+-- one?(x.den) => x.den
+ ((x.den) = 1) => x.den
+ d := gcd(x.num, x.den)
+ xn := x.num exquo d
+ xn case "failed" =>
+ error "gcd not gcd in QF cancelGcd (numerator)"
+ xd := x.den exquo d
+ xd case "failed" =>
+ error "gcd not gcd in QF cancelGcd (denominator)"
+ x.num := xn :: S
+ x.den := xd :: S
+ d
+
+ nn:S / dd:S ==
+ zero? dd => error "division by zero"
+ cancelGcd(z := [nn, dd])
+ normalize z
+
+ x + y ==
+ zero? y => x
+ zero? x => y
+ z := [x.den,y.den]
+ d := cancelGcd z
+ g := [z.den * x.num + z.num * y.num, d]
+ cancelGcd g
+ g.den := g.den * z.num * z.den
+ normalize g
+
+ -- We can not rely on the defaulting mechanism
+ -- to supply a definition for -, even though this
+ -- definition would do, for thefollowing reasons:
+ -- 1) The user could have defined a subtraction
+ -- in Localize, which would not work for
+ -- QuotientField;
+ -- 2) even if he doesn't, the system currently
+ -- places a default definition in Localize,
+ -- which uses Localize's +, which does not
+ -- cancel gcds
+ x - y ==
+ zero? y => x
+ z := [x.den, y.den]
+ d := cancelGcd z
+ g := [z.den * x.num - z.num * y.num, d]
+ cancelGcd g
+ g.den := g.den * z.num * z.den
+ normalize g
+
+ x:% * y:% ==
+ zero? x or zero? y => 0
+-- one? x => y
+ (x = 1) => y
+-- one? y => x
+ (y = 1) => x
+ (x, y) := ([x.num, y.den], [y.num, x.den])
+ cancelGcd x; cancelGcd y;
+ normalize [x.num * y.num, x.den * y.den]
+
+ n:Integer * x:% ==
+ y := [n::S, x.den]
+ cancelGcd y
+ normalize [x.num * y.num, y.den]
+
+ nn:S * x:% ==
+ y := [nn, x.den]
+ cancelGcd y
+ normalize [x.num * y.num, y.den]
+
+ differentiate(x:%, deriv:S -> S) ==
+ y := [deriv(x.den), x.den]
+ d := cancelGcd(y)
+ y.num := deriv(x.num) * y.den - x.num * y.num
+ (d, y.den) := (y.den, d)
+ cancelGcd y
+ y.den := y.den * d * d
+ normalize y
+
+ if S has canonicalUnitNormal then
+ x = y == (x.num = y.num) and (x.den = y.den)
+ --x / dd == (cancelGcd (z:=[x.num,dd*x.den]); normalize z)
+
+-- one? x == one? (x.num) and one? (x.den)
+ one? x == ((x.num) = 1) and ((x.den) = 1)
+ -- again assuming canonical nature of representation
+
+ else
+ nn:S/dd:S == if zero? dd then error "division by zero" else [nn,dd]
+
+ recip x ==
+ zero?(x.num) => "failed"
+ [x.den, x.num]
+
+ if (S has RetractableTo Fraction Integer) then
+ retract(x:%):Fraction(Integer) == retract(retract(x)@S)
+
+ retractIfCan(x:%):Union(Fraction Integer, "failed") ==
+ (u := retractIfCan(x)@Union(S, "failed")) case "failed" => "failed"
+ retractIfCan(u::S)
+
+ else if (S has RetractableTo Integer) then
+ retract(x:%):Fraction(Integer) ==
+ retract(numer x) / retract(denom x)
+
+ retractIfCan(x:%):Union(Fraction Integer, "failed") ==
+ (n := retractIfCan numer x) case "failed" => "failed"
+ (d := retractIfCan denom x) case "failed" => "failed"
+ (n::Integer) / (d::Integer)
+
+ QFP ==> SparseUnivariatePolynomial %
+ DP ==> SparseUnivariatePolynomial S
+ import UnivariatePolynomialCategoryFunctions2(%,QFP,S,DP)
+ import UnivariatePolynomialCategoryFunctions2(S,DP,%,QFP)
+
+ if S has GcdDomain then
+ gcdPolynomial(pp,qq) ==
+ zero? pp => qq
+ zero? qq => pp
+ zero? degree pp or zero? degree qq => 1
+ denpp:="lcm"/[denom u for u in coefficients pp]
+ ppD:DP:=map(retract(#1*denpp),pp)
+ denqq:="lcm"/[denom u for u in coefficients qq]
+ qqD:DP:=map(retract(#1*denqq),qq)
+ g:=gcdPolynomial(ppD,qqD)
+ zero? degree g => 1
+-- one? (lc:=leadingCoefficient g) => map(#1::%,g)
+ ((lc:=leadingCoefficient g) = 1) => map(#1::%,g)
+ map(#1 / lc,g)
+
+ if (S has PolynomialFactorizationExplicit) then
+ -- we'll let the solveLinearPolynomialEquations operator
+ -- default from Field
+ pp,qq: QFP
+ lpp: List QFP
+ import Factored SparseUnivariatePolynomial %
+ if S has CharacteristicNonZero then
+ if S has canonicalUnitNormal and S has GcdDomain then
+ charthRoot x ==
+ n:= charthRoot x.num
+ n case "failed" => "failed"
+ d:=charthRoot x.den
+ d case "failed" => "failed"
+ n/d
+ else
+ charthRoot x ==
+ -- to find x = p-th root of n/d
+ -- observe that xd is p-th root of n*d**(p-1)
+ ans:=charthRoot(x.num *
+ (x.den)**(characteristic()$%-1)::NonNegativeInteger)
+ ans case "failed" => "failed"
+ ans / x.den
+ clear: List % -> List S
+ clear l ==
+ d:="lcm"/[x.den for x in l]
+ [ x.num * (d exquo x.den)::S for x in l]
+ mat: Matrix %
+ conditionP mat ==
+ matD: Matrix S
+ matD:= matrix [ clear l for l in listOfLists mat ]
+ ansD := conditionP matD
+ ansD case "failed" => "failed"
+ ansDD:=ansD :: Vector(S)
+ [ ansDD(i)::% for i in 1..#ansDD]$Vector(%)
+
+ factorPolynomial(pp) ==
+ zero? pp => 0
+ denpp:="lcm"/[denom u for u in coefficients pp]
+ ppD:DP:=map(retract(#1*denpp),pp)
+ ff:=factorPolynomial ppD
+ den1:%:=denpp::%
+ lfact:List Record(flg:Union("nil", "sqfr", "irred", "prime"),
+ fctr:QFP, xpnt:Integer)
+ lfact:= [[w.flg,
+ if leadingCoefficient w.fctr =1 then map(#1::%,w.fctr)
+ else (lc:=(leadingCoefficient w.fctr)::%;
+ den1:=den1/lc**w.xpnt;
+ map(#1::%/lc,w.fctr)),
+ w.xpnt] for w in factorList ff]
+ makeFR(map(#1::%/den1,unit(ff)),lfact)
+ factorSquareFreePolynomial(pp) ==
+ zero? pp => 0
+ degree pp = 0 => makeFR(pp,empty())
+ lcpp:=leadingCoefficient pp
+ pp:=pp/lcpp
+ denpp:="lcm"/[denom u for u in coefficients pp]
+ ppD:DP:=map(retract(#1*denpp),pp)
+ ff:=factorSquareFreePolynomial ppD
+ den1:%:=denpp::%/lcpp
+ lfact:List Record(flg:Union("nil", "sqfr", "irred", "prime"),
+ fctr:QFP, xpnt:Integer)
+ lfact:= [[w.flg,
+ if leadingCoefficient w.fctr =1 then map(#1::%,w.fctr)
+ else (lc:=(leadingCoefficient w.fctr)::%;
+ den1:=den1/lc**w.xpnt;
+ map(#1::%/lc,w.fctr)),
+ w.xpnt] for w in factorList ff]
+ makeFR(map(#1::%/den1,unit(ff)),lfact)
+
+@
+\section{package LPEFRAC LinearPolynomialEquationByFractions}
+<<package LPEFRAC LinearPolynomialEquationByFractions>>=
+)abbrev package LPEFRAC LinearPolynomialEquationByFractions
+++ Author: James Davenport
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Given a PolynomialFactorizationExplicit ring, this package
+++ provides a defaulting rule for the \spad{solveLinearPolynomialEquation}
+++ operation, by moving into the field of fractions, and solving it there
+++ via the \spad{multiEuclidean} operation.
+LinearPolynomialEquationByFractions(R:PolynomialFactorizationExplicit): with
+ solveLinearPolynomialEquationByFractions: ( _
+ List SparseUnivariatePolynomial R, _
+ SparseUnivariatePolynomial R) -> _
+ Union(List SparseUnivariatePolynomial R, "failed")
+ ++ solveLinearPolynomialEquationByFractions([f1, ..., fn], g)
+ ++ (where the fi are relatively prime to each other)
+ ++ returns a list of ai such that
+ ++ \spad{g/prod fi = sum ai/fi}
+ ++ or returns "failed" if no such exists.
+ == add
+ SupR ==> SparseUnivariatePolynomial R
+ F ==> Fraction R
+ SupF ==> SparseUnivariatePolynomial F
+ import UnivariatePolynomialCategoryFunctions2(R,SupR,F,SupF)
+ lp : List SupR
+ pp: SupR
+ pF: SupF
+ pullback : SupF -> Union(SupR,"failed")
+ pullback(pF) ==
+ pF = 0 => 0
+ c:=retractIfCan leadingCoefficient pF
+ c case "failed" => "failed"
+ r:=pullback reductum pF
+ r case "failed" => "failed"
+ monomial(c,degree pF) + r
+ solveLinearPolynomialEquationByFractions(lp,pp) ==
+ lpF:List SupF:=[map(#1@R::F,u) for u in lp]
+ pF:SupF:=map(#1@R::F,pp)
+ ans:= solveLinearPolynomialEquation(lpF,pF)$F
+ ans case "failed" => "failed"
+ [(vv:= pullback v;
+ vv case "failed" => return "failed";
+ vv)
+ for v in ans]
+
+@
+\section{package FRAC2 FractionFunctions2}
+<<package FRAC2 FractionFunctions2>>=
+)abbrev package FRAC2 FractionFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: This package extends a map between integral domains to
+++ a map between Fractions over those domains by applying the map to the
+++ numerators and denominators.
+FractionFunctions2(A, B): Exports == Impl where
+ A, B: IntegralDomain
+
+ R ==> Fraction A
+ S ==> Fraction B
+
+ Exports ==> with
+ map: (A -> B, R) -> S
+ ++ map(func,frac) applies the function func to the numerator
+ ++ and denominator of the fraction frac.
+
+ Impl ==> add
+ map(f, r) == map(f, r)$QuotientFieldCategoryFunctions2(A, B, R, S)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain LO Localize>>
+<<domain LA LocalAlgebra>>
+<<category QFCAT QuotientFieldCategory>>
+<<package QFCAT2 QuotientFieldCategoryFunctions2>>
+<<domain FRAC Fraction>>
+<<package LPEFRAC LinearPolynomialEquationByFractions>>
+<<package FRAC2 FractionFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/free.spad.pamphlet b/src/algebra/free.spad.pamphlet
new file mode 100644
index 00000000..95e17711
--- /dev/null
+++ b/src/algebra/free.spad.pamphlet
@@ -0,0 +1,601 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra free.spad}
+\author{Manuel Bronstein, Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain LMOPS ListMonoidOps}
+<<domain LMOPS ListMonoidOps>>=
+)abbrev domain LMOPS ListMonoidOps
+++ Internal representation for monoids
+++ Author: Manuel Bronstein
+++ Date Created: November 1989
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ This internal package represents monoid (abelian or not, with or
+++ without inverses) as lists and provides some common operations
+++ to the various flavors of monoids.
+ListMonoidOps(S, E, un): Exports == Implementation where
+ S : SetCategory
+ E : AbelianMonoid
+ un: E
+
+ REC ==> Record(gen:S, exp: E)
+ O ==> OutputForm
+
+ Exports ==> Join(SetCategory, RetractableTo S) with
+ outputForm : ($, (O, O) -> O, (O, O) -> O, Integer) -> O
+ ++ outputForm(l, fop, fexp, unit) converts the monoid element
+ ++ represented by l to an \spadtype{OutputForm}.
+ ++ Argument unit is the output form
+ ++ for the \spadignore{unit} of the monoid (e.g. 0 or 1),
+ ++ \spad{fop(a, b)} is the
+ ++ output form for the monoid operation applied to \spad{a} and b
+ ++ (e.g. \spad{a + b}, \spad{a * b}, \spad{ab}),
+ ++ and \spad{fexp(a, n)} is the output form
+ ++ for the exponentiation operation applied to \spad{a} and n
+ ++ (e.g. \spad{n a}, \spad{n * a}, \spad{a ** n}, \spad{a\^n}).
+ listOfMonoms : $ -> List REC
+ ++ listOfMonoms(l) returns the list of the monomials forming l.
+ makeTerm : (S, E) -> $
+ ++ makeTerm(s, e) returns the monomial s exponentiated by e
+ ++ (e.g. s^e or e * s).
+ makeMulti : List REC -> $
+ ++ makeMulti(l) returns the element whose list of monomials is l.
+ nthExpon : ($, Integer) -> E
+ ++ nthExpon(l, n) returns the exponent of the n^th monomial of l.
+ nthFactor : ($, Integer) -> S
+ ++ nthFactor(l, n) returns the factor of the n^th monomial of l.
+ reverse : $ -> $
+ ++ reverse(l) reverses the list of monomials forming l. This
+ ++ has some effect if the monoid is non-abelian, i.e.
+ ++ \spad{reverse(a1\^e1 ... an\^en) = an\^en ... a1\^e1} which is different.
+ reverse_! : $ -> $
+ ++ reverse!(l) reverses the list of monomials forming l, destroying
+ ++ the element l.
+ size : $ -> NonNegativeInteger
+ ++ size(l) returns the number of monomials forming l.
+ makeUnit : () -> $
+ ++ makeUnit() returns the unit element of the monomial.
+ rightMult : ($, S) -> $
+ ++ rightMult(a, s) returns \spad{a * s} where \spad{*}
+ ++ is the monoid operation,
+ ++ which is assumed non-commutative.
+ leftMult : (S, $) -> $
+ ++ leftMult(s, a) returns \spad{s * a} where
+ ++ \spad{*} is the monoid operation,
+ ++ which is assumed non-commutative.
+ plus : (S, E, $) -> $
+ ++ plus(s, e, x) returns \spad{e * s + x} where \spad{+}
+ ++ is the monoid operation,
+ ++ which is assumed commutative.
+ plus : ($, $) -> $
+ ++ plus(x, y) returns \spad{x + y} where \spad{+}
+ ++ is the monoid operation,
+ ++ which is assumed commutative.
+ commutativeEquality: ($, $) -> Boolean
+ ++ commutativeEquality(x,y) returns true if x and y are equal
+ ++ assuming commutativity
+ mapExpon : (E -> E, $) -> $
+ ++ 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}.
+
+ Implementation ==> add
+ Rep := List REC
+
+ localplus: ($, $) -> $
+
+ makeUnit() == empty()$Rep
+ size l == # listOfMonoms l
+ coerce(s:S):$ == [[s, un]]
+ coerce(l:$):O == coerce(l)$Rep
+ makeTerm(s, e) == (zero? e => makeUnit(); [[s, e]])
+ makeMulti l == l
+ f = g == f =$Rep g
+ listOfMonoms l == l pretend List(REC)
+ nthExpon(f, i) == f.(i-1+minIndex f).exp
+ nthFactor(f, i) == f.(i-1+minIndex f).gen
+ reverse l == reverse(l)$Rep
+ reverse_! l == reverse_!(l)$Rep
+ mapGen(f, l) == [[f(x.gen), x.exp] for x in l]
+
+ mapExpon(f, l) ==
+ ans:List(REC) := empty()
+ for x in l repeat
+ if (a := f(x.exp)) ^= 0 then ans := concat([x.gen, a], ans)
+ reverse_! ans
+
+ outputForm(l, op, opexp, id) ==
+ empty? l => id::OutputForm
+ l:List(O) :=
+ [(p.exp = un => p.gen::O; opexp(p.gen::O, p.exp::O)) for p in l]
+ reduce(op, l)
+
+ retractIfCan(l:$):Union(S, "failed") ==
+ not empty? l and empty? rest l and l.first.exp = un => l.first.gen
+ "failed"
+
+ rightMult(f, s) ==
+ empty? f => s::$
+ s = f.last.gen => (setlast_!(h := copy f, [s, f.last.exp + un]); h)
+ concat(f, [s, un])
+
+ leftMult(s, f) ==
+ empty? f => s::$
+ s = f.first.gen => concat([s, f.first.exp + un], rest f)
+ concat([s, un], f)
+
+ commutativeEquality(s1:$, s2:$):Boolean ==
+ #s1 ^= #s2 => false
+ for t1 in s1 repeat
+ if not member?(t1,s2) then return false
+ true
+
+ plus_!(s:S, n:E, f:$):$ ==
+ h := g := concat([s, n], f)
+ h1 := rest h
+ while not empty? h1 repeat
+ s = h1.first.gen =>
+ l :=
+ zero?(m := n + h1.first.exp) => rest h1
+ concat([s, m], rest h1)
+ setrest_!(h, l)
+ return rest g
+ h := h1
+ h1 := rest h1
+ g
+
+ plus(s, n, f) == plus_!(s,n,copy f)
+
+ plus(f, g) ==
+ #f < #g => localplus(f, g)
+ localplus(g, f)
+
+ localplus(f, g) ==
+ g := copy g
+ for x in f repeat
+ g := plus(x.gen, x.exp, g)
+ g
+
+@
+\section{domain FMONOID FreeMonoid}
+<<domain FMONOID FreeMonoid>>=
+)abbrev domain FMONOID FreeMonoid
+++ Free monoid on any set of generators
+++ Author: Stephen M. Watt
+++ Date Created: ???
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ 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: SetCategory): FMcategory == FMdefinition where
+ NNI ==> NonNegativeInteger
+ REC ==> Record(gen: S, exp: NonNegativeInteger)
+ Ex ==> OutputForm
+
+ FMcategory ==> 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,
+ ++ i.e. 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,
+ ++ i.e. 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 i.e.
+ ++ 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 i.e.
+ ++ 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, i.e. \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,
+ ++ i.e. \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
+
+ FMdefinition ==> 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:$ ==
+-- one? f => g
+ (f = 1) => g
+-- one? g => f
+ (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) ==
+-- one? la or one? ar => [la, 1, 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) ==
+-- one? a => [lar, 1]
+ (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
+
+@
+\section{domain FGROUP FreeGroup}
+<<domain FGROUP FreeGroup>>=
+)abbrev domain FGROUP FreeGroup
+++ Free group on any set of generators
+++ Author: Stephen M. Watt
+++ Date Created: ???
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ The free group on a set S is the group of finite products of
+++ the form \spad{reduce(*,[si ** ni])} where the si's are in S, and the ni's
+++ are integers. The multiplication is not commutative.
+FreeGroup(S: SetCategory): Join(Group, 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, Integer) -> $
+ ++ s ** n returns the product of s by itself n times.
+ size : $ -> NonNegativeInteger
+ ++ size(x) returns the number of monomials in x.
+ nthExpon : ($, Integer) -> Integer
+ ++ 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 : (Integer -> Integer, $) -> $
+ ++ 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}.
+ factors : $ -> List Record(gen: S, exp: Integer)
+ ++ factors(a1\^e1,...,an\^en) returns \spad{[[a1, e1],...,[an, en]]}.
+ == ListMonoidOps(S, Integer, 1) add
+ Rep := ListMonoidOps(S, Integer, 1)
+
+ 1 == makeUnit()
+ one? f == empty? listOfMonoms f
+ s:S ** n:Integer == makeTerm(s, n)
+ f:$ * s:S == rightMult(f, s)
+ s:S * f:$ == leftMult(s, f)
+ inv f == reverse_! mapExpon("-", f)
+ factors f == copy listOfMonoms f
+ mapExpon(f, x) == mapExpon(f, x)$Rep
+ mapGen(f, x) == mapGen(f, x)$Rep
+ coerce(f:$):OutputForm == outputForm(f, "*", "**", 1)
+
+ f:$ * g:$ ==
+ one? f => g
+ one? g => f
+ r := reverse listOfMonoms f
+ q := copy listOfMonoms g
+ while not empty? r and not empty? q and r.first.gen = q.first.gen
+ and r.first.exp = -q.first.exp repeat
+ r := rest r
+ q := rest q
+ empty? r => makeMulti q
+ empty? q => makeMulti reverse_! r
+ r.first.gen = q.first.gen =>
+ setlast_!(h := reverse_! r,
+ [q.first.gen, q.first.exp + r.first.exp])
+ makeMulti concat_!(h, rest q)
+ makeMulti concat_!(reverse_! r, q)
+
+@
+\section{category FAMONC FreeAbelianMonoidCategory}
+<<category FAMONC FreeAbelianMonoidCategory>>=
+)abbrev category FAMONC FreeAbelianMonoidCategory
+++ Category for free abelian monoid on any set of generators
+++ Author: Manuel Bronstein
+++ Date Created: November 1989
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ A free abelian monoid on a set S is the monoid of finite sums of
+++ the form \spad{reduce(+,[ni * si])} where the si's are in S, and the ni's
+++ are in a given abelian monoid. The operation is commutative.
+FreeAbelianMonoidCategory(S: SetCategory, E:CancellationAbelianMonoid): Category ==
+ Join(CancellationAbelianMonoid, RetractableTo S) with
+ "+" : (S, $) -> $
+ ++ s + x returns the sum of s and x.
+ "*" : (E, S) -> $
+ ++ e * s returns e times s.
+ size : $ -> NonNegativeInteger
+ ++ size(x) returns the number of terms in x.
+ ++ mapGen(f, a1\^e1 ... an\^en) returns \spad{f(a1)\^e1 ... f(an)\^en}.
+ terms : $ -> List Record(gen: S, exp: E)
+ ++ terms(e1 a1 + ... + en an) returns \spad{[[a1, e1],...,[an, en]]}.
+ nthCoef : ($, Integer) -> E
+ ++ nthCoef(x, n) returns the coefficient of the n^th term of x.
+ nthFactor : ($, Integer) -> S
+ ++ nthFactor(x, n) returns the factor of the n^th term of x.
+ coefficient: (S, $) -> E
+ ++ coefficient(s, e1 a1 + ... + en an) returns ei such that
+ ++ ai = s, or 0 if s is not one of the ai's.
+ mapCoef : (E -> E, $) -> $
+ ++ mapCoef(f, e1 a1 +...+ en an) returns
+ ++ \spad{f(e1) a1 +...+ f(en) an}.
+ mapGen : (S -> S, $) -> $
+ ++ mapGen(f, e1 a1 +...+ en an) returns
+ ++ \spad{e1 f(a1) +...+ en f(an)}.
+ if E has OrderedAbelianMonoid then
+ highCommonTerms: ($, $) -> $
+ ++ highCommonTerms(e1 a1 + ... + en an, f1 b1 + ... + fm bm) returns
+ ++ \spad{reduce(+,[max(ei, fi) ci])}
+ ++ where ci ranges in the intersection
+ ++ of \spad{{a1,...,an}} and \spad{{b1,...,bm}}.
+
+@
+\section{domain IFAMON InnerFreeAbelianMonoid}
+<<domain IFAMON InnerFreeAbelianMonoid>>=
+)abbrev domain IFAMON InnerFreeAbelianMonoid
+++ Internal free abelian monoid on any set of generators
+++ Author: Manuel Bronstein
+++ Date Created: November 1989
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ Internal implementation of a free abelian monoid.
+InnerFreeAbelianMonoid(S: SetCategory, E:CancellationAbelianMonoid, un:E):
+ FreeAbelianMonoidCategory(S, E) == ListMonoidOps(S, E, un) add
+ Rep := ListMonoidOps(S, E, un)
+
+ 0 == makeUnit()
+ zero? f == empty? listOfMonoms f
+ terms f == copy listOfMonoms f
+ nthCoef(f, i) == nthExpon(f, i)
+ nthFactor(f, i) == nthFactor(f, i)$Rep
+ s:S + f:$ == plus(s, un, f)
+ f:$ + g:$ == plus(f, g)
+ (f:$ = g:$):Boolean == commutativeEquality(f,g)
+ n:E * s:S == makeTerm(s, n)
+ n:NonNegativeInteger * f:$ == mapExpon(n * #1, f)
+ coerce(f:$):OutputForm == outputForm(f, "+", #2 * #1, 0)
+ mapCoef(f, x) == mapExpon(f, x)
+ mapGen(f, x) == mapGen(f, x)$Rep
+
+ coefficient(s, f) ==
+ for x in terms f repeat
+ x.gen = s => return(x.exp)
+ 0
+
+ if E has OrderedAbelianMonoid then
+ highCommonTerms(f, g) ==
+ makeMulti [[x.gen, min(x.exp, n)] for x in listOfMonoms f |
+ (n := coefficient(x.gen, g)) > 0]
+
+@
+\section{domain FAMONOID FreeAbelianMonoid}
+<<domain FAMONOID FreeAbelianMonoid>>=
+)abbrev domain FAMONOID FreeAbelianMonoid
+++ Free abelian monoid on any set of generators
+++ Author: Manuel Bronstein
+++ Date Created: November 1989
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ The free abelian monoid on a set S is the monoid of finite sums of
+++ the form \spad{reduce(+,[ni * si])} where the si's are in S, and the ni's
+++ are non-negative integers. The operation is commutative.
+FreeAbelianMonoid(S: SetCategory):
+ FreeAbelianMonoidCategory(S, NonNegativeInteger)
+ == InnerFreeAbelianMonoid(S, NonNegativeInteger, 1)
+
+@
+\section{domain FAGROUP FreeAbelianGroup}
+<<domain FAGROUP FreeAbelianGroup>>=
+)abbrev domain FAGROUP FreeAbelianGroup
+++ Free abelian group on any set of generators
+++ Author: Manuel Bronstein
+++ Date Created: November 1989
+++ Date Last Updated: 6 June 1991
+++ Description:
+++ The free abelian group on a set S is the monoid of finite sums of
+++ the form \spad{reduce(+,[ni * si])} where the si's are in S, and the ni's
+++ are integers. The operation is commutative.
+FreeAbelianGroup(S:SetCategory): Exports == Implementation where
+ Exports ==> Join(AbelianGroup, Module Integer,
+ FreeAbelianMonoidCategory(S, Integer)) with
+ if S has OrderedSet then OrderedSet
+
+ Implementation ==> InnerFreeAbelianMonoid(S, Integer, 1) add
+ - f == mapCoef("-", f)
+
+ if S has OrderedSet then
+ inmax: List Record(gen: S, exp: Integer) -> Record(gen: S, exp:Integer)
+
+ inmax l ==
+ mx := first l
+ for t in rest l repeat
+ if t.gen > mx.gen then mx := t
+ mx
+
+ a < b ==
+ zero? a =>
+ zero? b => false
+ (inmax terms b).exp > 0
+ ta := inmax terms a
+ zero? b => ta.exp < 0
+ ta := inmax terms a
+ tb := inmax terms b
+ ta.gen < tb.gen => true
+ ta.gen > tb.gen => false
+ ta.exp < tb.exp => true
+ ta.exp > tb.exp => false
+ lc := ta.exp * ta.gen
+ (a - lc) < (b - lc)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain LMOPS ListMonoidOps>>
+<<domain FMONOID FreeMonoid>>
+<<domain FGROUP FreeGroup>>
+<<category FAMONC FreeAbelianMonoidCategory>>
+<<domain IFAMON InnerFreeAbelianMonoid>>
+<<domain FAMONOID FreeAbelianMonoid>>
+<<domain FAGROUP FreeAbelianGroup>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fs2expxp.spad.pamphlet b/src/algebra/fs2expxp.spad.pamphlet
new file mode 100644
index 00000000..fed80080
--- /dev/null
+++ b/src/algebra/fs2expxp.spad.pamphlet
@@ -0,0 +1,598 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fs2expxp.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FS2EXPXP FunctionSpaceToExponentialExpansion}
+<<package FS2EXPXP FunctionSpaceToExponentialExpansion>>=
+)abbrev package FS2EXPXP FunctionSpaceToExponentialExpansion
+++ Author: Clifton J. Williamson
+++ Date Created: 17 August 1992
+++ Date Last Updated: 2 December 1994
+++ Basic Operations:
+++ Related Domains: ExponentialExpansion, UnivariatePuiseuxSeries(FE,x,cen)
+++ Also See: FunctionSpaceToUnivariatePowerSeries
+++ AMS Classifications:
+++ Keywords: elementary function, power series
+++ Examples:
+++ References:
+++ Description:
+++ This package converts expressions in some function space to exponential
+++ expansions.
+FunctionSpaceToExponentialExpansion(R,FE,x,cen):_
+ Exports == Implementation where
+ R : Join(GcdDomain,OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+ x : Symbol
+ cen : FE
+ B ==> Boolean
+ BOP ==> BasicOperator
+ Expon ==> Fraction Integer
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ K ==> Kernel FE
+ L ==> List
+ RN ==> Fraction Integer
+ S ==> String
+ SY ==> Symbol
+ PCL ==> PolynomialCategoryLifting(IndexedExponents K,K,R,SMP,FE)
+ POL ==> Polynomial R
+ SMP ==> SparseMultivariatePolynomial(R,K)
+ SUP ==> SparseUnivariatePolynomial Polynomial R
+ UTS ==> UnivariateTaylorSeries(FE,x,cen)
+ ULS ==> UnivariateLaurentSeries(FE,x,cen)
+ UPXS ==> UnivariatePuiseuxSeries(FE,x,cen)
+ EFULS ==> ElementaryFunctionsUnivariateLaurentSeries(FE,UTS,ULS)
+ EFUPXS ==> ElementaryFunctionsUnivariatePuiseuxSeries(FE,ULS,UPXS,EFULS)
+ FS2UPS ==> FunctionSpaceToUnivariatePowerSeries(R,FE,RN,UPXS,EFUPXS,x)
+ EXPUPXS ==> ExponentialOfUnivariatePuiseuxSeries(FE,x,cen)
+ UPXSSING ==> UnivariatePuiseuxSeriesWithExponentialSingularity(R,FE,x,cen)
+ XXP ==> ExponentialExpansion(R,FE,x,cen)
+ Problem ==> Record(func:String,prob:String)
+ Result ==> Union(%series:UPXS,%problem:Problem)
+ XResult ==> Union(%expansion:XXP,%problem:Problem)
+ SIGNEF ==> ElementaryFunctionSign(R,FE)
+
+ Exports ==> with
+ exprToXXP : (FE,B) -> XResult
+ ++ exprToXXP(fcn,posCheck?) converts the expression \spad{fcn} to
+ ++ an exponential expansion. If \spad{posCheck?} is true,
+ ++ log's of negative numbers are not allowed nor are nth roots of
+ ++ negative numbers with n even. If \spad{posCheck?} is false,
+ ++ these are allowed.
+ localAbs: FE -> FE
+ ++ localAbs(fcn) = \spad{abs(fcn)} or \spad{sqrt(fcn**2)} depending
+ ++ on whether or not FE has a function \spad{abs}. This should be
+ ++ a local function, but the compiler won't allow it.
+
+ Implementation ==> add
+
+ import FS2UPS -- conversion of functional expressions to Puiseux series
+ import EFUPXS -- partial transcendental funtions on UPXS
+
+ ratIfCan : FE -> Union(RN,"failed")
+ stateSeriesProblem : (S,S) -> Result
+ stateProblem : (S,S) -> XResult
+ newElem : FE -> FE
+ smpElem : SMP -> FE
+ k2Elem : K -> FE
+ iExprToXXP : (FE,B) -> XResult
+ listToXXP : (L FE,B,XXP,(XXP,XXP) -> XXP) -> XResult
+ isNonTrivPower : FE -> Union(Record(val:FE,exponent:I),"failed")
+ negativePowerOK? : UPXS -> Boolean
+ powerToXXP : (FE,I,B) -> XResult
+ carefulNthRootIfCan : (UPXS,NNI,B) -> Result
+ nthRootXXPIfCan : (XXP,NNI,B) -> XResult
+ nthRootToXXP : (FE,NNI,B) -> XResult
+ genPowerToXXP : (L FE,B) -> XResult
+ kernelToXXP : (K,B) -> XResult
+ genExp : (UPXS,B) -> Result
+ exponential : (UPXS,B) -> XResult
+ expToXXP : (FE,B) -> XResult
+ genLog : (UPXS,B) -> Result
+ logToXXP : (FE,B) -> XResult
+ applyIfCan : (UPXS -> Union(UPXS,"failed"),FE,S,B) -> XResult
+ applyBddIfCan : (FE,UPXS -> Union(UPXS,"failed"),FE,S,B) -> XResult
+ tranToXXP : (K,FE,B) -> XResult
+ contOnReals? : S -> B
+ bddOnReals? : S -> B
+ opsInvolvingX : FE -> L BOP
+ opInOpList? : (SY,L BOP) -> B
+ exponential? : FE -> B
+ productOfNonZeroes? : FE -> B
+ atancotToXXP : (FE,FE,B,I) -> XResult
+
+ ZEROCOUNT : RN := 1000/1
+ -- number of zeroes to be removed when taking logs or nth roots
+
+--% retractions
+
+ ratIfCan fcn == retractIfCan(fcn)@Union(RN,"failed")
+
+--% 'problems' with conversion
+
+ stateSeriesProblem(function,problem) ==
+ -- records the problem which occured in converting an expression
+ -- to a power series
+ [[function,problem]]
+
+ stateProblem(function,problem) ==
+ -- records the problem which occured in converting an expression
+ -- to an exponential expansion
+ [[function,problem]]
+
+--% normalizations
+
+ newElem f ==
+ -- rewrites a functional expression; all trig functions are
+ -- expressed in terms of sin and cos; all hyperbolic trig
+ -- functions are expressed in terms of exp; all inverse
+ -- hyperbolic trig functions are expressed in terms of exp
+ -- and log
+ smpElem(numer f) / smpElem(denom f)
+
+ smpElem p == map(k2Elem,#1::FE,p)$PCL
+
+ k2Elem k ==
+ -- rewrites a kernel; all trig functions are
+ -- expressed in terms of sin and cos; all hyperbolic trig
+ -- functions are expressed in terms of exp
+ null(args := [newElem a for a in argument k]) => k :: FE
+ iez := inv(ez := exp(z := first args))
+ sinz := sin z; cosz := cos z
+ is?(k,"tan" :: SY) => sinz / cosz
+ is?(k,"cot" :: SY) => cosz / sinz
+ is?(k,"sec" :: SY) => inv cosz
+ is?(k,"csc" :: SY) => inv sinz
+ is?(k,"sinh" :: SY) => (ez - iez) / (2 :: FE)
+ is?(k,"cosh" :: SY) => (ez + iez) / (2 :: FE)
+ is?(k,"tanh" :: SY) => (ez - iez) / (ez + iez)
+ is?(k,"coth" :: SY) => (ez + iez) / (ez - iez)
+ is?(k,"sech" :: SY) => 2 * inv(ez + iez)
+ is?(k,"csch" :: SY) => 2 * inv(ez - iez)
+ is?(k,"acosh" :: SY) => log(sqrt(z**2 - 1) + z)
+ is?(k,"atanh" :: SY) => log((z + 1) / (1 - z)) / (2 :: FE)
+ is?(k,"acoth" :: SY) => log((z + 1) / (z - 1)) / (2 :: FE)
+ is?(k,"asech" :: SY) => log((inv z) + sqrt(inv(z**2) - 1))
+ is?(k,"acsch" :: SY) => log((inv z) + sqrt(1 + inv(z**2)))
+ (operator k) args
+
+--% general conversion function
+
+ exprToXXP(fcn,posCheck?) == iExprToXXP(newElem fcn,posCheck?)
+
+ iExprToXXP(fcn,posCheck?) ==
+ -- converts a functional expression to an exponential expansion
+ --!! The following line is commented out so that expressions of
+ --!! the form a**b will be normalized to exp(b * log(a)) even if
+ --!! 'a' and 'b' do not involve the limiting variable 'x'.
+ --!! - cjw 1 Dec 94
+ --not member?(x,variables fcn) => [monomial(fcn,0)$UPXS :: XXP]
+ (poly := retractIfCan(fcn)@Union(POL,"failed")) case POL =>
+ [exprToUPS(fcn,false,"real:two sides").%series :: XXP]
+ (sum := isPlus fcn) case L(FE) =>
+ listToXXP(sum :: L(FE),posCheck?,0,#1 + #2)
+ (prod := isTimes fcn) case L(FE) =>
+ listToXXP(prod :: L(FE),posCheck?,1,#1 * #2)
+ (expt := isNonTrivPower fcn) case Record(val:FE,exponent:I) =>
+ power := expt :: Record(val:FE,exponent:I)
+ powerToXXP(power.val,power.exponent,posCheck?)
+ (ker := retractIfCan(fcn)@Union(K,"failed")) case K =>
+ kernelToXXP(ker :: K,posCheck?)
+ error "exprToXXP: neither a sum, product, power, nor kernel"
+
+--% sums and products
+
+ listToXXP(list,posCheck?,ans,op) ==
+ -- converts each element of a list of expressions to an exponential
+ -- expansion and returns the sum of these expansions, when 'op' is +
+ -- and 'ans' is 0, or the product of these expansions, when 'op' is *
+ -- and 'ans' is 1
+ while not null list repeat
+ (term := iExprToXXP(first list,posCheck?)) case %problem =>
+ return term
+ ans := op(ans,term.%expansion)
+ list := rest list
+ [ans]
+
+--% nth roots and integral powers
+
+ isNonTrivPower fcn ==
+ -- is the function a power with exponent other than 0 or 1?
+ (expt := isPower fcn) case "failed" => "failed"
+ power := expt :: Record(val:FE,exponent:I)
+-- one? power.exponent => "failed"
+ (power.exponent = 1) => "failed"
+ power
+
+ negativePowerOK? upxs ==
+ -- checks the lower order coefficient of a Puiseux series;
+ -- the coefficient may be inverted only if
+ -- (a) the only function involving x is 'log', or
+ -- (b) the lowest order coefficient is a product of exponentials
+ -- and functions not involving x
+ deg := degree upxs
+ if (coef := coefficient(upxs,deg)) = 0 then
+ deg := order(upxs,deg + ZEROCOUNT :: Expon)
+ (coef := coefficient(upxs,deg)) = 0 =>
+ error "inverse of series with many leading zero coefficients"
+ xOpList := opsInvolvingX coef
+ -- only function involving x is 'log'
+ (null xOpList) => true
+ (null rest xOpList and is?(first xOpList,"log" :: SY)) => true
+ -- lowest order coefficient is a product of exponentials and
+ -- functions not involving x
+ productOfNonZeroes? coef => true
+ false
+
+ powerToXXP(fcn,n,posCheck?) ==
+ -- converts an integral power to an exponential expansion
+ (b := iExprToXXP(fcn,posCheck?)) case %problem => b
+ xxp := b.%expansion
+ n > 0 => [xxp ** n]
+ -- a Puiseux series will be reciprocated only if n < 0 and
+ -- numerator of 'xxp' has exactly one monomial
+ numberOfMonomials(num := numer xxp) > 1 => [xxp ** n]
+ negativePowerOK? leadingCoefficient num =>
+ (rec := recip num) case "failed" => error "FS2EXPXP: can't happen"
+ nn := (-n) :: NNI
+ [(((denom xxp) ** nn) * ((rec :: UPXSSING) ** nn)) :: XXP]
+ --!! we may want to create a fraction instead of trying to
+ --!! reciprocate the numerator
+ stateProblem("inv","lowest order coefficient involves x")
+
+ carefulNthRootIfCan(ups,n,posCheck?) ==
+ -- similar to 'nthRootIfCan', but it is fussy about the series
+ -- it takes as an argument. If 'n' is EVEN and 'posCheck?'
+ -- is truem then the leading coefficient of the series must
+ -- be POSITIVE. In this case, if 'rightOnly?' is false, the
+ -- order of the series must be zero. The idea is that the
+ -- series represents a real function of a real variable, and
+ -- we want a unique real nth root defined on a neighborhood
+ -- of zero.
+ n < 1 => error "nthRoot: n must be positive"
+ deg := degree ups
+ if (coef := coefficient(ups,deg)) = 0 then
+ deg := order(ups,deg + ZEROCOUNT :: Expon)
+ (coef := coefficient(ups,deg)) = 0 =>
+ error "log of series with many leading zero coefficients"
+ -- if 'posCheck?' is true, we do not allow nth roots of negative
+ -- numbers when n in even
+ if even?(n :: I) then
+ if posCheck? and ((signum := sign(coef)$SIGNEF) case I) then
+ (signum :: I) = -1 =>
+ return stateSeriesProblem("nth root","root of negative number")
+ (ans := nthRootIfCan(ups,n)) case "failed" =>
+ stateSeriesProblem("nth root","no nth root")
+ [ans :: UPXS]
+
+ nthRootXXPIfCan(xxp,n,posCheck?) ==
+ num := numer xxp; den := denom xxp
+ not zero?(reductum num) or not zero?(reductum den) =>
+ stateProblem("nth root","several monomials in numerator or denominator")
+ nInv : RN := 1/n
+ newNum :=
+ coef : UPXS :=
+ root := carefulNthRootIfCan(leadingCoefficient num,n,posCheck?)
+ root case %problem => return [root.%problem]
+ root.%series
+ deg := (nInv :: FE) * (degree num)
+ monomial(coef,deg)
+ newDen :=
+ coef : UPXS :=
+ root := carefulNthRootIfCan(leadingCoefficient den,n,posCheck?)
+ root case %problem => return [root.%problem]
+ root.%series
+ deg := (nInv :: FE) * (degree den)
+ monomial(coef,deg)
+ [newNum/newDen]
+
+ nthRootToXXP(arg,n,posCheck?) ==
+ -- converts an nth root to a power series
+ -- this is not used in the limit package, so the series may
+ -- have non-zero order, in which case nth roots may not be unique
+ (result := iExprToXXP(arg,posCheck?)) case %problem => [result.%problem]
+ ans := nthRootXXPIfCan(result.%expansion,n,posCheck?)
+ ans case %problem => [ans.%problem]
+ [ans.%expansion]
+
+--% general powers f(x) ** g(x)
+
+ genPowerToXXP(args,posCheck?) ==
+ -- converts a power f(x) ** g(x) to an exponential expansion
+ (logBase := logToXXP(first args,posCheck?)) case %problem =>
+ logBase
+ (expon := iExprToXXP(second args,posCheck?)) case %problem =>
+ expon
+ xxp := (expon.%expansion) * (logBase.%expansion)
+ (f := retractIfCan(xxp)@Union(UPXS,"failed")) case "failed" =>
+ stateProblem("exp","multiply nested exponential")
+ exponential(f,posCheck?)
+
+--% kernels
+
+ kernelToXXP(ker,posCheck?) ==
+ -- converts a kernel to a power series
+ (sym := symbolIfCan(ker)) case Symbol =>
+ (sym :: Symbol) = x => [monomial(1,1)$UPXS :: XXP]
+ [monomial(ker :: FE,0)$UPXS :: XXP]
+ empty?(args := argument ker) => [monomial(ker :: FE,0)$UPXS :: XXP]
+ empty? rest args =>
+ arg := first args
+ is?(ker,"%paren" :: Symbol) => iExprToXXP(arg,posCheck?)
+ is?(ker,"log" :: Symbol) => logToXXP(arg,posCheck?)
+ is?(ker,"exp" :: Symbol) => expToXXP(arg,posCheck?)
+ tranToXXP(ker,arg,posCheck?)
+ is?(ker,"%power" :: Symbol) => genPowerToXXP(args,posCheck?)
+ is?(ker,"nthRoot" :: Symbol) =>
+ n := retract(second args)@I
+ nthRootToXXP(first args,n :: NNI,posCheck?)
+ stateProblem(string name ker,"unknown kernel")
+
+--% exponentials and logarithms
+
+ genExp(ups,posCheck?) ==
+ -- If the series has order zero and the constant term a0 of the
+ -- series involves x, the function tries to expand exp(a0) as
+ -- a power series.
+ (deg := order(ups,1)) < 0 =>
+ -- this "can't happen"
+ error "exp of function with sigularity"
+ deg > 0 => [exp(ups)]
+ lc := coefficient(ups,0); varOpList := opsInvolvingX lc
+ not opInOpList?("log" :: Symbol,varOpList) => [exp(ups)]
+ -- try to fix exp(lc) if necessary
+ expCoef := normalize(exp lc,x)$ElementaryFunctionStructurePackage(R,FE)
+ result := exprToGenUPS(expCoef,posCheck?,"real:right side")$FS2UPS
+ --!! will deal with problems in limitPlus in EXPEXPAN
+ --result case %problem => result
+ result case %problem => [exp(ups)]
+ [(result.%series) * exp(ups - monomial(lc,0))]
+
+ exponential(f,posCheck?) ==
+ singPart := truncate(f,0) - (coefficient(f,0) :: UPXS)
+ taylorPart := f - singPart
+ expon := exponential(singPart)$EXPUPXS
+ (coef := genExp(taylorPart,posCheck?)) case %problem => [coef.%problem]
+ [monomial(coef.%series,expon)$UPXSSING :: XXP]
+
+ expToXXP(arg,posCheck?) ==
+ (result := iExprToXXP(arg,posCheck?)) case %problem => result
+ xxp := result.%expansion
+ (f := retractIfCan(xxp)@Union(UPXS,"failed")) case "failed" =>
+ stateProblem("exp","multiply nested exponential")
+ exponential(f,posCheck?)
+
+ genLog(ups,posCheck?) ==
+ deg := degree ups
+ if (coef := coefficient(ups,deg)) = 0 then
+ deg := order(ups,deg + ZEROCOUNT)
+ (coef := coefficient(ups,deg)) = 0 =>
+ error "log of series with many leading zero coefficients"
+ -- if 'posCheck?' is true, we do not allow logs of negative numbers
+ if posCheck? then
+ if ((signum := sign(coef)$SIGNEF) case I) then
+ (signum :: I) = -1 =>
+ return stateSeriesProblem("log","negative leading coefficient")
+ lt := monomial(coef,deg)$UPXS
+ -- check to see if lowest order coefficient is a negative rational
+ negRat? : Boolean :=
+ ((rat := ratIfCan coef) case RN) =>
+ (rat :: RN) < 0 => true
+ false
+ false
+ logTerm : FE :=
+ mon : FE := (x :: FE) - (cen :: FE)
+ pow : FE := mon ** (deg :: FE)
+ negRat? => log(coef * pow)
+ term1 : FE := (deg :: FE) * log(mon)
+ log(coef) + term1
+ [monomial(logTerm,0)$UPXS + log(ups/lt)]
+
+ logToXXP(arg,posCheck?) ==
+ (result := iExprToXXP(arg,posCheck?)) case %problem => result
+ xxp := result.%expansion
+ num := numer xxp; den := denom xxp
+ not zero?(reductum num) or not zero?(reductum den) =>
+ stateProblem("log","several monomials in numerator or denominator")
+ numCoefLog : UPXS :=
+ (res := genLog(leadingCoefficient num,posCheck?)) case %problem =>
+ return [res.%problem]
+ res.%series
+ denCoefLog : UPXS :=
+ (res := genLog(leadingCoefficient den,posCheck?)) case %problem =>
+ return [res.%problem]
+ res.%series
+ numLog := (exponent degree num) + numCoefLog
+ denLog := (exponent degree den) + denCoefLog --?? num?
+ [(numLog - denLog) :: XXP]
+
+--% other transcendental functions
+
+ applyIfCan(fcn,arg,fcnName,posCheck?) ==
+ -- converts fcn(arg) to an exponential expansion
+ (xxpArg := iExprToXXP(arg,posCheck?)) case %problem => xxpArg
+ xxp := xxpArg.%expansion
+ (f := retractIfCan(xxp)@Union(UPXS,"failed")) case "failed" =>
+ stateProblem(fcnName,"multiply nested exponential")
+ upxs := f :: UPXS
+ (deg := order(upxs,1)) < 0 =>
+ stateProblem(fcnName,"essential singularity")
+ deg > 0 => [fcn(upxs) :: UPXS :: XXP]
+ lc := coefficient(upxs,0); xOpList := opsInvolvingX lc
+ null xOpList => [fcn(upxs) :: UPXS :: XXP]
+ opInOpList?("log" :: SY,xOpList) =>
+ stateProblem(fcnName,"logs in constant coefficient")
+ contOnReals? fcnName => [fcn(upxs) :: UPXS :: XXP]
+ stateProblem(fcnName,"x in constant coefficient")
+
+ applyBddIfCan(fe,fcn,arg,fcnName,posCheck?) ==
+ -- converts fcn(arg) to a generalized power series, where the
+ -- function fcn is bounded for real values
+ -- if fcn(arg) has an essential singularity as a complex
+ -- function, we return fcn(arg) as a monomial of degree 0
+ (xxpArg := iExprToXXP(arg,posCheck?)) case %problem =>
+ trouble := xxpArg.%problem
+ trouble.prob = "essential singularity" => [monomial(fe,0)$UPXS :: XXP]
+ xxpArg
+ xxp := xxpArg.%expansion
+ (f := retractIfCan(xxp)@Union(UPXS,"failed")) case "failed" =>
+ stateProblem("exp","multiply nested exponential")
+ (ans := fcn(f :: UPXS)) case "failed" => [monomial(fe,0)$UPXS :: XXP]
+ [ans :: UPXS :: XXP]
+
+ CONTFCNS : L S := ["sin","cos","atan","acot","exp","asinh"]
+ -- functions which are defined and continuous at all real numbers
+
+ BDDFCNS : L S := ["sin","cos","atan","acot"]
+ -- functions which are bounded on the reals
+
+ contOnReals? fcn == member?(fcn,CONTFCNS)
+ bddOnReals? fcn == member?(fcn,BDDFCNS)
+
+ opsInvolvingX fcn ==
+ opList := [op for k in tower fcn | unary?(op := operator k) _
+ and member?(x,variables first argument k)]
+ removeDuplicates opList
+
+ opInOpList?(name,opList) ==
+ for op in opList repeat
+ is?(op,name) => return true
+ false
+
+ exponential? fcn ==
+ -- is 'fcn' of the form exp(f)?
+ (ker := retractIfCan(fcn)@Union(K,"failed")) case K =>
+ is?(ker :: K,"exp" :: Symbol)
+ false
+
+ productOfNonZeroes? fcn ==
+ -- is 'fcn' a product of non-zero terms, where 'non-zero'
+ -- means an exponential or a function not involving x
+ exponential? fcn => true
+ (prod := isTimes fcn) case "failed" => false
+ for term in (prod :: L(FE)) repeat
+ (not exponential? term) and member?(x,variables term) =>
+ return false
+ true
+
+ tranToXXP(ker,arg,posCheck?) ==
+ -- converts op(arg) to a power series for certain functions
+ -- op in trig or hyperbolic trig categories
+ -- N.B. when this function is called, 'k2elem' will have been
+ -- applied, so the following functions cannot appear:
+ -- tan, cot, sec, csc, sinh, cosh, tanh, coth, sech, csch
+ -- acosh, atanh, acoth, asech, acsch
+ is?(ker,"sin" :: SY) =>
+ applyBddIfCan(ker :: FE,sinIfCan,arg,"sin",posCheck?)
+ is?(ker,"cos" :: SY) =>
+ applyBddIfCan(ker :: FE,cosIfCan,arg,"cos",posCheck?)
+ is?(ker,"asin" :: SY) =>
+ applyIfCan(asinIfCan,arg,"asin",posCheck?)
+ is?(ker,"acos" :: SY) =>
+ applyIfCan(acosIfCan,arg,"acos",posCheck?)
+ is?(ker,"atan" :: SY) =>
+ atancotToXXP(ker :: FE,arg,posCheck?,1)
+ is?(ker,"acot" :: SY) =>
+ atancotToXXP(ker :: FE,arg,posCheck?,-1)
+ is?(ker,"asec" :: SY) =>
+ applyIfCan(asecIfCan,arg,"asec",posCheck?)
+ is?(ker,"acsc" :: SY) =>
+ applyIfCan(acscIfCan,arg,"acsc",posCheck?)
+ is?(ker,"asinh" :: SY) =>
+ applyIfCan(asinhIfCan,arg,"asinh",posCheck?)
+ stateProblem(string name ker,"unknown kernel")
+
+ if FE has abs: FE -> FE then
+ localAbs fcn == abs fcn
+ else
+ localAbs fcn == sqrt(fcn * fcn)
+
+ signOfExpression: FE -> FE
+ signOfExpression arg == localAbs(arg)/arg
+
+ atancotToXXP(fe,arg,posCheck?,plusMinus) ==
+ -- converts atan(f(x)) to a generalized power series
+ atanFlag : String := "real: right side"; posCheck? : Boolean := true
+ (result := exprToGenUPS(arg,posCheck?,atanFlag)$FS2UPS) case %problem =>
+ trouble := result.%problem
+ trouble.prob = "essential singularity" => [monomial(fe,0)$UPXS :: XXP]
+ [result.%problem]
+ ups := result.%series; coef := coefficient(ups,0)
+ -- series involves complex numbers
+ (ord := order(ups,0)) = 0 and coef * coef = -1 =>
+ y := differentiate(ups)/(1 + ups*ups)
+ yCoef := coefficient(y,-1)
+ [(monomial(log yCoef,0)+integrate(y - monomial(yCoef,-1)$UPXS)) :: XXP]
+ cc : FE :=
+ ord < 0 =>
+ (rn := ratIfCan(ord :: FE)) case "failed" =>
+ -- this condition usually won't occur because exponents will
+ -- be integers or rational numbers
+ return stateProblem("atan","branch problem")
+ lc := coefficient(ups,ord)
+ (signum := sign(lc)$SIGNEF) case "failed" =>
+ -- can't determine sign
+ posNegPi2 := signOfExpression(lc) * pi()/(2 :: FE)
+ plusMinus = 1 => posNegPi2
+ pi()/(2 :: FE) - posNegPi2
+ (n := signum :: Integer) = -1 =>
+ plusMinus = 1 => -pi()/(2 :: FE)
+ pi()
+ plusMinus = 1 => pi()/(2 :: FE)
+ 0
+ atan coef
+ [((cc :: UPXS) + integrate(differentiate(ups)/(1 + ups*ups))) :: XXP]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FS2EXPXP FunctionSpaceToExponentialExpansion>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fs2ups.spad.pamphlet b/src/algebra/fs2ups.spad.pamphlet
new file mode 100644
index 00000000..9751dd40
--- /dev/null
+++ b/src/algebra/fs2ups.spad.pamphlet
@@ -0,0 +1,812 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fs2ups.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FS2UPS FunctionSpaceToUnivariatePowerSeries}
+<<package FS2UPS FunctionSpaceToUnivariatePowerSeries>>=
+)abbrev package FS2UPS FunctionSpaceToUnivariatePowerSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 21 March 1989
+++ Date Last Updated: 2 December 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: elementary function, power series
+++ Examples:
+++ References:
+++ Description:
+++ This package converts expressions in some function space to power
+++ series in a variable x with coefficients in that function space.
+++ The function \spadfun{exprToUPS} converts expressions to power series
+++ whose coefficients do not contain the variable x. The function
+++ \spadfun{exprToGenUPS} converts functional expressions to power series
+++ whose coefficients may involve functions of \spad{log(x)}.
+FunctionSpaceToUnivariatePowerSeries(R,FE,Expon,UPS,TRAN,x):_
+ Exports == Implementation where
+ R : Join(GcdDomain,OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+ with
+ coerce: Expon -> %
+ ++ coerce(e) converts an 'exponent' e to an 'expression'
+ Expon : OrderedRing
+ UPS : Join(UnivariatePowerSeriesCategory(FE,Expon),Field,_
+ TranscendentalFunctionCategory)
+ with
+ differentiate: % -> %
+ ++ differentiate(x) returns the derivative of x since we
+ ++ need to be able to differentiate a power series
+ integrate: % -> %
+ ++ integrate(x) returns the integral of x since
+ ++ we need to be able to integrate a power series
+ TRAN : PartialTranscendentalFunctions UPS
+ x : Symbol
+ B ==> Boolean
+ BOP ==> BasicOperator
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ K ==> Kernel FE
+ L ==> List
+ RN ==> Fraction Integer
+ S ==> String
+ SY ==> Symbol
+ PCL ==> PolynomialCategoryLifting(IndexedExponents K,K,R,SMP,FE)
+ POL ==> Polynomial R
+ SMP ==> SparseMultivariatePolynomial(R,K)
+ SUP ==> SparseUnivariatePolynomial Polynomial R
+ Problem ==> Record(func:String,prob:String)
+ Result ==> Union(%series:UPS,%problem:Problem)
+ SIGNEF ==> ElementaryFunctionSign(R,FE)
+
+ Exports ==> with
+ exprToUPS : (FE,B,S) -> Result
+ ++ exprToUPS(fcn,posCheck?,atanFlag) converts the expression
+ ++ \spad{fcn} to a power series. If \spad{posCheck?} is true,
+ ++ log's of negative numbers are not allowed nor are nth roots of
+ ++ negative numbers with n even. If \spad{posCheck?} is false,
+ ++ these are allowed. \spad{atanFlag} determines how the case
+ ++ \spad{atan(f(x))}, where \spad{f(x)} has a pole, will be treated.
+ ++ The possible values of \spad{atanFlag} are \spad{"complex"},
+ ++ \spad{"real: two sides"}, \spad{"real: left side"},
+ ++ \spad{"real: right side"}, and \spad{"just do it"}.
+ ++ If \spad{atanFlag} is \spad{"complex"}, then no series expansion
+ ++ will be computed because, viewed as a function of a complex
+ ++ variable, \spad{atan(f(x))} has an essential singularity.
+ ++ Otherwise, the sign of the leading coefficient of the series
+ ++ expansion of \spad{f(x)} determines the constant coefficient
+ ++ in the series expansion of \spad{atan(f(x))}. If this sign cannot
+ ++ be determined, a series expansion is computed only when
+ ++ \spad{atanFlag} is \spad{"just do it"}. When the leading term
+ ++ in the series expansion of \spad{f(x)} is of odd degree (or is a
+ ++ rational degree with odd numerator), then the constant coefficient
+ ++ in the series expansion of \spad{atan(f(x))} for values to the
+ ++ left differs from that for values to the right. If \spad{atanFlag}
+ ++ is \spad{"real: two sides"}, no series expansion will be computed.
+ ++ If \spad{atanFlag} is \spad{"real: left side"} the constant
+ ++ coefficient for values to the left will be used and if \spad{atanFlag}
+ ++ \spad{"real: right side"} the constant coefficient for values to the
+ ++ right will be used.
+ ++ If there is a problem in converting the function to a power series,
+ ++ a record containing the name of the function that caused the problem
+ ++ and a brief description of the problem is returned.
+ ++ When expanding the expression into a series it is assumed that
+ ++ the series is centered at 0. For a series centered at a, the
+ ++ user should perform the substitution \spad{x -> x + a} before calling
+ ++ this function.
+
+ exprToGenUPS : (FE,B,S) -> Result
+ ++ exprToGenUPS(fcn,posCheck?,atanFlag) converts the expression
+ ++ \spad{fcn} to a generalized power series. If \spad{posCheck?}
+ ++ is true, log's of negative numbers are not allowed nor are nth roots
+ ++ of negative numbers with n even. If \spad{posCheck?} is false,
+ ++ these are allowed. \spad{atanFlag} determines how the case
+ ++ \spad{atan(f(x))}, where \spad{f(x)} has a pole, will be treated.
+ ++ The possible values of \spad{atanFlag} are \spad{"complex"},
+ ++ \spad{"real: two sides"}, \spad{"real: left side"},
+ ++ \spad{"real: right side"}, and \spad{"just do it"}.
+ ++ If \spad{atanFlag} is \spad{"complex"}, then no series expansion
+ ++ will be computed because, viewed as a function of a complex
+ ++ variable, \spad{atan(f(x))} has an essential singularity.
+ ++ Otherwise, the sign of the leading coefficient of the series
+ ++ expansion of \spad{f(x)} determines the constant coefficient
+ ++ in the series expansion of \spad{atan(f(x))}. If this sign cannot
+ ++ be determined, a series expansion is computed only when
+ ++ \spad{atanFlag} is \spad{"just do it"}. When the leading term
+ ++ in the series expansion of \spad{f(x)} is of odd degree (or is a
+ ++ rational degree with odd numerator), then the constant coefficient
+ ++ in the series expansion of \spad{atan(f(x))} for values to the
+ ++ left differs from that for values to the right. If \spad{atanFlag}
+ ++ is \spad{"real: two sides"}, no series expansion will be computed.
+ ++ If \spad{atanFlag} is \spad{"real: left side"} the constant
+ ++ coefficient for values to the left will be used and if \spad{atanFlag}
+ ++ \spad{"real: right side"} the constant coefficient for values to the
+ ++ right will be used.
+ ++ If there is a problem in converting the function to a power
+ ++ series, we return a record containing the name of the function
+ ++ that caused the problem and a brief description of the problem.
+ ++ When expanding the expression into a series it is assumed that
+ ++ the series is centered at 0. For a series centered at a, the
+ ++ user should perform the substitution \spad{x -> x + a} before calling
+ ++ this function.
+ localAbs: FE -> FE
+ ++ localAbs(fcn) = \spad{abs(fcn)} or \spad{sqrt(fcn**2)} depending
+ ++ on whether or not FE has a function \spad{abs}. This should be
+ ++ a local function, but the compiler won't allow it.
+
+ Implementation ==> add
+
+ ratIfCan : FE -> Union(RN,"failed")
+ carefulNthRootIfCan : (UPS,NNI,B,B) -> Result
+ stateProblem : (S,S) -> Result
+ polyToUPS : SUP -> UPS
+ listToUPS : (L FE,(FE,B,S) -> Result,B,S,UPS,(UPS,UPS) -> UPS)_
+ -> Result
+ isNonTrivPower : FE -> Union(Record(val:FE,exponent:I),"failed")
+ powerToUPS : (FE,I,B,S) -> Result
+ kernelToUPS : (K,B,S) -> Result
+ nthRootToUPS : (FE,NNI,B,S) -> Result
+ logToUPS : (FE,B,S) -> Result
+ atancotToUPS : (FE,B,S,I) -> Result
+ applyIfCan : (UPS -> Union(UPS,"failed"),FE,S,B,S) -> Result
+ tranToUPS : (K,FE,B,S) -> Result
+ powToUPS : (L FE,B,S) -> Result
+ newElem : FE -> FE
+ smpElem : SMP -> FE
+ k2Elem : K -> FE
+ contOnReals? : S -> B
+ bddOnReals? : S -> B
+ iExprToGenUPS : (FE,B,S) -> Result
+ opsInvolvingX : FE -> L BOP
+ opInOpList? : (SY,L BOP) -> B
+ exponential? : FE -> B
+ productOfNonZeroes? : FE -> B
+ powerToGenUPS : (FE,I,B,S) -> Result
+ kernelToGenUPS : (K,B,S) -> Result
+ nthRootToGenUPS : (FE,NNI,B,S) -> Result
+ logToGenUPS : (FE,B,S) -> Result
+ expToGenUPS : (FE,B,S) -> Result
+ expGenUPS : (UPS,B,S) -> Result
+ atancotToGenUPS : (FE,FE,B,S,I) -> Result
+ genUPSApplyIfCan : (UPS -> Union(UPS,"failed"),FE,S,B,S) -> Result
+ applyBddIfCan : (FE,UPS -> Union(UPS,"failed"),FE,S,B,S) -> Result
+ tranToGenUPS : (K,FE,B,S) -> Result
+ powToGenUPS : (L FE,B,S) -> Result
+
+ ZEROCOUNT : I := 1000
+ -- number of zeroes to be removed when taking logs or nth roots
+
+ ratIfCan fcn == retractIfCan(fcn)@Union(RN,"failed")
+
+ carefulNthRootIfCan(ups,n,posCheck?,rightOnly?) ==
+ -- similar to 'nthRootIfCan', but it is fussy about the series
+ -- it takes as an argument. If 'n' is EVEN and 'posCheck?'
+ -- is truem then the leading coefficient of the series must
+ -- be POSITIVE. In this case, if 'rightOnly?' is false, the
+ -- order of the series must be zero. The idea is that the
+ -- series represents a real function of a real variable, and
+ -- we want a unique real nth root defined on a neighborhood
+ -- of zero.
+ n < 1 => error "nthRoot: n must be positive"
+ deg := degree ups
+ if (coef := coefficient(ups,deg)) = 0 then
+ deg := order(ups,deg + ZEROCOUNT :: Expon)
+ (coef := coefficient(ups,deg)) = 0 =>
+ error "log of series with many leading zero coefficients"
+ -- if 'posCheck?' is true, we do not allow nth roots of negative
+ -- numbers when n in even
+ if even?(n :: I) then
+ if posCheck? and ((signum := sign(coef)$SIGNEF) case I) then
+ (signum :: I) = -1 =>
+ return stateProblem("nth root","negative leading coefficient")
+ not rightOnly? and not zero? deg => -- nth root not unique
+ return stateProblem("nth root","series of non-zero order")
+ (ans := nthRootIfCan(ups,n)) case "failed" =>
+ stateProblem("nth root","no nth root")
+ [ans :: UPS]
+
+ stateProblem(function,problem) ==
+ -- records the problem which occured in converting an expression
+ -- to a power series
+ [[function,problem]]
+
+ exprToUPS(fcn,posCheck?,atanFlag) ==
+ -- converts a functional expression to a power series
+ --!! The following line is commented out so that expressions of
+ --!! the form a**b will be normalized to exp(b * log(a)) even if
+ --!! 'a' and 'b' do not involve the limiting variable 'x'.
+ --!! - cjw 1 Dec 94
+ --not member?(x,variables fcn) => [monomial(fcn,0)]
+ (poly := retractIfCan(fcn)@Union(POL,"failed")) case POL =>
+ [polyToUPS univariate(poly :: POL,x)]
+ (sum := isPlus fcn) case L(FE) =>
+ listToUPS(sum :: L(FE),exprToUPS,posCheck?,atanFlag,0,#1 + #2)
+ (prod := isTimes fcn) case L(FE) =>
+ listToUPS(prod :: L(FE),exprToUPS,posCheck?,atanFlag,1,#1 * #2)
+ (expt := isNonTrivPower fcn) case Record(val:FE,exponent:I) =>
+ power := expt :: Record(val:FE,exponent:I)
+ powerToUPS(power.val,power.exponent,posCheck?,atanFlag)
+ (ker := retractIfCan(fcn)@Union(K,"failed")) case K =>
+ kernelToUPS(ker :: K,posCheck?,atanFlag)
+ error "exprToUPS: neither a sum, product, power, nor kernel"
+
+ polyToUPS poly ==
+ -- converts a polynomial to a power series
+ zero? poly => 0
+ -- we don't start with 'ans := 0' as this may lead to an
+ -- enormous number of leading zeroes in the power series
+ deg := degree poly
+ coef := leadingCoefficient(poly) :: FE
+ ans := monomial(coef,deg :: Expon)$UPS
+ poly := reductum poly
+ while not zero? poly repeat
+ deg := degree poly
+ coef := leadingCoefficient(poly) :: FE
+ ans := ans + monomial(coef,deg :: Expon)$UPS
+ poly := reductum poly
+ ans
+
+ listToUPS(list,feToUPS,posCheck?,atanFlag,ans,op) ==
+ -- converts each element of a list of expressions to a power
+ -- series and returns the sum of these series, when 'op' is +
+ -- and 'ans' is 0, or the product of these series, when 'op' is *
+ -- and 'ans' is 1
+ while not null list repeat
+ (term := feToUPS(first list,posCheck?,atanFlag)) case %problem =>
+ return term
+ ans := op(ans,term.%series)
+ list := rest list
+ [ans]
+
+ isNonTrivPower fcn ==
+ -- is the function a power with exponent other than 0 or 1?
+ (expt := isPower fcn) case "failed" => "failed"
+ power := expt :: Record(val:FE,exponent:I)
+-- one? power.exponent => "failed"
+ (power.exponent = 1) => "failed"
+ power
+
+ powerToUPS(fcn,n,posCheck?,atanFlag) ==
+ -- converts an integral power to a power series
+ (b := exprToUPS(fcn,posCheck?,atanFlag)) case %problem => b
+ n > 0 => [(b.%series) ** n]
+ -- check lowest order coefficient when n < 0
+ ups := b.%series; deg := degree ups
+ if (coef := coefficient(ups,deg)) = 0 then
+ deg := order(ups,deg + ZEROCOUNT :: Expon)
+ (coef := coefficient(ups,deg)) = 0 =>
+ error "inverse of series with many leading zero coefficients"
+ [ups ** n]
+
+ kernelToUPS(ker,posCheck?,atanFlag) ==
+ -- converts a kernel to a power series
+ (sym := symbolIfCan(ker)) case Symbol =>
+ (sym :: Symbol) = x => [monomial(1,1)]
+ [monomial(ker :: FE,0)]
+ empty?(args := argument ker) => [monomial(ker :: FE,0)]
+ not member?(x, variables(ker :: FE)) => [monomial(ker :: FE,0)]
+ empty? rest args =>
+ arg := first args
+ is?(ker,"abs" :: Symbol) =>
+ nthRootToUPS(arg*arg,2,posCheck?,atanFlag)
+ is?(ker,"%paren" :: Symbol) => exprToUPS(arg,posCheck?,atanFlag)
+ is?(ker,"log" :: Symbol) => logToUPS(arg,posCheck?,atanFlag)
+ is?(ker,"exp" :: Symbol) =>
+ applyIfCan(expIfCan,arg,"exp",posCheck?,atanFlag)
+ tranToUPS(ker,arg,posCheck?,atanFlag)
+ is?(ker,"%power" :: Symbol) => powToUPS(args,posCheck?,atanFlag)
+ is?(ker,"nthRoot" :: Symbol) =>
+ n := retract(second args)@I
+ nthRootToUPS(first args,n :: NNI,posCheck?,atanFlag)
+ stateProblem(string name ker,"unknown kernel")
+
+ nthRootToUPS(arg,n,posCheck?,atanFlag) ==
+ -- converts an nth root to a power series
+ -- this is not used in the limit package, so the series may
+ -- have non-zero order, in which case nth roots may not be unique
+ (result := exprToUPS(arg,posCheck?,atanFlag)) case %problem => result
+ ans := carefulNthRootIfCan(result.%series,n,posCheck?,false)
+ ans case %problem => ans
+ [ans.%series]
+
+ logToUPS(arg,posCheck?,atanFlag) ==
+ -- converts a logarithm log(f(x)) to a power series
+ -- f(x) must have order 0 and if 'posCheck?' is true,
+ -- then f(x) must have a non-negative leading coefficient
+ (result := exprToUPS(arg,posCheck?,atanFlag)) case %problem => result
+ ups := result.%series
+ not zero? order(ups,1) =>
+ stateProblem("log","series of non-zero order")
+ coef := coefficient(ups,0)
+ -- if 'posCheck?' is true, we do not allow logs of negative numbers
+ if posCheck? then
+ if ((signum := sign(coef)$SIGNEF) case I) then
+ (signum :: I) = -1 =>
+ return stateProblem("log","negative leading coefficient")
+ [logIfCan(ups) :: UPS]
+
+ if FE has abs: FE -> FE then
+ localAbs fcn == abs fcn
+ else
+ localAbs fcn == sqrt(fcn * fcn)
+
+ signOfExpression: FE -> FE
+ signOfExpression arg == localAbs(arg)/arg
+
+ atancotToUPS(arg,posCheck?,atanFlag,plusMinus) ==
+ -- converts atan(f(x)) to a power series
+ (result := exprToUPS(arg,posCheck?,atanFlag)) case %problem => result
+ ups := result.%series; coef := coefficient(ups,0)
+ (ord := order(ups,0)) = 0 and coef * coef = -1 =>
+ -- series involves complex numbers
+ return stateProblem("atan","logarithmic singularity")
+ cc : FE :=
+ ord < 0 =>
+ atanFlag = "complex" =>
+ return stateProblem("atan","essential singularity")
+ (rn := ratIfCan(ord :: FE)) case "failed" =>
+ -- this condition usually won't occur because exponents will
+ -- be integers or rational numbers
+ return stateProblem("atan","branch problem")
+ if (atanFlag = "real: two sides") and (odd? numer(rn :: RN)) then
+ -- expansions to the left and right of zero have different
+ -- constant coefficients
+ return stateProblem("atan","branch problem")
+ lc := coefficient(ups,ord)
+ (signum := sign(lc)$SIGNEF) case "failed" =>
+ -- can't determine sign
+ atanFlag = "just do it" =>
+ plusMinus = 1 => pi()/(2 :: FE)
+ 0
+ posNegPi2 := signOfExpression(lc) * pi()/(2 :: FE)
+ plusMinus = 1 => posNegPi2
+ pi()/(2 :: FE) - posNegPi2
+ --return stateProblem("atan","branch problem")
+ left? : B := atanFlag = "real: left side"; n := signum :: Integer
+ (left? and n = 1) or (not left? and n = -1) =>
+ plusMinus = 1 => -pi()/(2 :: FE)
+ pi()
+ plusMinus = 1 => pi()/(2 :: FE)
+ 0
+ atan coef
+ [(cc :: UPS) + integrate(plusMinus * differentiate(ups)/(1 + ups*ups))]
+
+ applyIfCan(fcn,arg,fcnName,posCheck?,atanFlag) ==
+ -- converts fcn(arg) to a power series
+ (ups := exprToUPS(arg,posCheck?,atanFlag)) case %problem => ups
+ ans := fcn(ups.%series)
+ ans case "failed" => stateProblem(fcnName,"essential singularity")
+ [ans :: UPS]
+
+ tranToUPS(ker,arg,posCheck?,atanFlag) ==
+ -- converts ker to a power series for certain functions
+ -- in trig or hyperbolic trig categories
+ is?(ker,"sin" :: SY) =>
+ applyIfCan(sinIfCan,arg,"sin",posCheck?,atanFlag)
+ is?(ker,"cos" :: SY) =>
+ applyIfCan(cosIfCan,arg,"cos",posCheck?,atanFlag)
+ is?(ker,"tan" :: SY) =>
+ applyIfCan(tanIfCan,arg,"tan",posCheck?,atanFlag)
+ is?(ker,"cot" :: SY) =>
+ applyIfCan(cotIfCan,arg,"cot",posCheck?,atanFlag)
+ is?(ker,"sec" :: SY) =>
+ applyIfCan(secIfCan,arg,"sec",posCheck?,atanFlag)
+ is?(ker,"csc" :: SY) =>
+ applyIfCan(cscIfCan,arg,"csc",posCheck?,atanFlag)
+ is?(ker,"asin" :: SY) =>
+ applyIfCan(asinIfCan,arg,"asin",posCheck?,atanFlag)
+ is?(ker,"acos" :: SY) =>
+ applyIfCan(acosIfCan,arg,"acos",posCheck?,atanFlag)
+ is?(ker,"atan" :: SY) => atancotToUPS(arg,posCheck?,atanFlag,1)
+ is?(ker,"acot" :: SY) => atancotToUPS(arg,posCheck?,atanFlag,-1)
+ is?(ker,"asec" :: SY) =>
+ applyIfCan(asecIfCan,arg,"asec",posCheck?,atanFlag)
+ is?(ker,"acsc" :: SY) =>
+ applyIfCan(acscIfCan,arg,"acsc",posCheck?,atanFlag)
+ is?(ker,"sinh" :: SY) =>
+ applyIfCan(sinhIfCan,arg,"sinh",posCheck?,atanFlag)
+ is?(ker,"cosh" :: SY) =>
+ applyIfCan(coshIfCan,arg,"cosh",posCheck?,atanFlag)
+ is?(ker,"tanh" :: SY) =>
+ applyIfCan(tanhIfCan,arg,"tanh",posCheck?,atanFlag)
+ is?(ker,"coth" :: SY) =>
+ applyIfCan(cothIfCan,arg,"coth",posCheck?,atanFlag)
+ is?(ker,"sech" :: SY) =>
+ applyIfCan(sechIfCan,arg,"sech",posCheck?,atanFlag)
+ is?(ker,"csch" :: SY) =>
+ applyIfCan(cschIfCan,arg,"csch",posCheck?,atanFlag)
+ is?(ker,"asinh" :: SY) =>
+ applyIfCan(asinhIfCan,arg,"asinh",posCheck?,atanFlag)
+ is?(ker,"acosh" :: SY) =>
+ applyIfCan(acoshIfCan,arg,"acosh",posCheck?,atanFlag)
+ is?(ker,"atanh" :: SY) =>
+ applyIfCan(atanhIfCan,arg,"atanh",posCheck?,atanFlag)
+ is?(ker,"acoth" :: SY) =>
+ applyIfCan(acothIfCan,arg,"acoth",posCheck?,atanFlag)
+ is?(ker,"asech" :: SY) =>
+ applyIfCan(asechIfCan,arg,"asech",posCheck?,atanFlag)
+ is?(ker,"acsch" :: SY) =>
+ applyIfCan(acschIfCan,arg,"acsch",posCheck?,atanFlag)
+ stateProblem(string name ker,"unknown kernel")
+
+ powToUPS(args,posCheck?,atanFlag) ==
+ -- converts a power f(x) ** g(x) to a power series
+ (logBase := logToUPS(first args,posCheck?,atanFlag)) case %problem =>
+ logBase
+ (expon := exprToUPS(second args,posCheck?,atanFlag)) case %problem =>
+ expon
+ ans := expIfCan((expon.%series) * (logBase.%series))
+ ans case "failed" => stateProblem("exp","essential singularity")
+ [ans :: UPS]
+
+-- Generalized power series: power series in x, where log(x) and
+-- bounded functions of x are allowed to appear in the coefficients
+-- of the series. Used for evaluating REAL limits at x = 0.
+
+ newElem f ==
+ -- rewrites a functional expression; all trig functions are
+ -- expressed in terms of sin and cos; all hyperbolic trig
+ -- functions are expressed in terms of exp
+ smpElem(numer f) / smpElem(denom f)
+
+ smpElem p == map(k2Elem,#1::FE,p)$PCL
+
+ k2Elem k ==
+ -- rewrites a kernel; all trig functions are
+ -- expressed in terms of sin and cos; all hyperbolic trig
+ -- functions are expressed in terms of exp
+ null(args := [newElem a for a in argument k]) => k::FE
+ iez := inv(ez := exp(z := first args))
+ sinz := sin z; cosz := cos z
+ is?(k,"tan" :: Symbol) => sinz / cosz
+ is?(k,"cot" :: Symbol) => cosz / sinz
+ is?(k,"sec" :: Symbol) => inv cosz
+ is?(k,"csc" :: Symbol) => inv sinz
+ is?(k,"sinh" :: Symbol) => (ez - iez) / (2 :: FE)
+ is?(k,"cosh" :: Symbol) => (ez + iez) / (2 :: FE)
+ is?(k,"tanh" :: Symbol) => (ez - iez) / (ez + iez)
+ is?(k,"coth" :: Symbol) => (ez + iez) / (ez - iez)
+ is?(k,"sech" :: Symbol) => 2 * inv(ez + iez)
+ is?(k,"csch" :: Symbol) => 2 * inv(ez - iez)
+ (operator k) args
+
+ CONTFCNS : L S := ["sin","cos","atan","acot","exp","asinh"]
+ -- functions which are defined and continuous at all real numbers
+
+ BDDFCNS : L S := ["sin","cos","atan","acot"]
+ -- functions which are bounded on the reals
+
+ contOnReals? fcn == member?(fcn,CONTFCNS)
+ bddOnReals? fcn == member?(fcn,BDDFCNS)
+
+ exprToGenUPS(fcn,posCheck?,atanFlag) ==
+ -- converts a functional expression to a generalized power
+ -- series; "generalized" means that log(x) and bounded functions
+ -- of x are allowed to appear in the coefficients of the series
+ iExprToGenUPS(newElem fcn,posCheck?,atanFlag)
+
+ iExprToGenUPS(fcn,posCheck?,atanFlag) ==
+ -- converts a functional expression to a generalized power
+ -- series without first normalizing the expression
+ --!! The following line is commented out so that expressions of
+ --!! the form a**b will be normalized to exp(b * log(a)) even if
+ --!! 'a' and 'b' do not involve the limiting variable 'x'.
+ --!! - cjw 1 Dec 94
+ --not member?(x,variables fcn) => [monomial(fcn,0)]
+ (poly := retractIfCan(fcn)@Union(POL,"failed")) case POL =>
+ [polyToUPS univariate(poly :: POL,x)]
+ (sum := isPlus fcn) case L(FE) =>
+ listToUPS(sum :: L(FE),iExprToGenUPS,posCheck?,atanFlag,0,#1 + #2)
+ (prod := isTimes fcn) case L(FE) =>
+ listToUPS(prod :: L(FE),iExprToGenUPS,posCheck?,atanFlag,1,#1 * #2)
+ (expt := isNonTrivPower fcn) case Record(val:FE,exponent:I) =>
+ power := expt :: Record(val:FE,exponent:I)
+ powerToGenUPS(power.val,power.exponent,posCheck?,atanFlag)
+ (ker := retractIfCan(fcn)@Union(K,"failed")) case K =>
+ kernelToGenUPS(ker :: K,posCheck?,atanFlag)
+ error "exprToGenUPS: neither a sum, product, power, nor kernel"
+
+ opsInvolvingX fcn ==
+ opList := [op for k in tower fcn | unary?(op := operator k) _
+ and member?(x,variables first argument k)]
+ removeDuplicates opList
+
+ opInOpList?(name,opList) ==
+ for op in opList repeat
+ is?(op,name) => return true
+ false
+
+ exponential? fcn ==
+ -- is 'fcn' of the form exp(f)?
+ (ker := retractIfCan(fcn)@Union(K,"failed")) case K =>
+ is?(ker :: K,"exp" :: Symbol)
+ false
+
+ productOfNonZeroes? fcn ==
+ -- is 'fcn' a product of non-zero terms, where 'non-zero'
+ -- means an exponential or a function not involving x
+ exponential? fcn => true
+ (prod := isTimes fcn) case "failed" => false
+ for term in (prod :: L(FE)) repeat
+ (not exponential? term) and member?(x,variables term) =>
+ return false
+ true
+
+ powerToGenUPS(fcn,n,posCheck?,atanFlag) ==
+ -- converts an integral power to a generalized power series
+ -- if n < 0 and the lowest order coefficient of the series
+ -- involves x, we are careful about inverting this coefficient
+ -- the coefficient is inverted only if
+ -- (a) the only function involving x is 'log', or
+ -- (b) the lowest order coefficient is a product of exponentials
+ -- and functions not involving x
+ (b := exprToGenUPS(fcn,posCheck?,atanFlag)) case %problem => b
+ n > 0 => [(b.%series) ** n]
+ -- check lowest order coefficient when n < 0
+ ups := b.%series; deg := degree ups
+ if (coef := coefficient(ups,deg)) = 0 then
+ deg := order(ups,deg + ZEROCOUNT :: Expon)
+ (coef := coefficient(ups,deg)) = 0 =>
+ error "inverse of series with many leading zero coefficients"
+ xOpList := opsInvolvingX coef
+ -- only function involving x is 'log'
+ (null xOpList) => [ups ** n]
+ (null rest xOpList and is?(first xOpList,"log" :: SY)) =>
+ [ups ** n]
+ -- lowest order coefficient is a product of exponentials and
+ -- functions not involving x
+ productOfNonZeroes? coef => [ups ** n]
+ stateProblem("inv","lowest order coefficient involves x")
+
+ kernelToGenUPS(ker,posCheck?,atanFlag) ==
+ -- converts a kernel to a generalized power series
+ (sym := symbolIfCan(ker)) case Symbol =>
+ (sym :: Symbol) = x => [monomial(1,1)]
+ [monomial(ker :: FE,0)]
+ empty?(args := argument ker) => [monomial(ker :: FE,0)]
+ empty? rest args =>
+ arg := first args
+ is?(ker,"abs" :: Symbol) =>
+ nthRootToGenUPS(arg*arg,2,posCheck?,atanFlag)
+ is?(ker,"%paren" :: Symbol) => iExprToGenUPS(arg,posCheck?,atanFlag)
+ is?(ker,"log" :: Symbol) => logToGenUPS(arg,posCheck?,atanFlag)
+ is?(ker,"exp" :: Symbol) => expToGenUPS(arg,posCheck?,atanFlag)
+ tranToGenUPS(ker,arg,posCheck?,atanFlag)
+ is?(ker,"%power" :: Symbol) => powToGenUPS(args,posCheck?,atanFlag)
+ is?(ker,"nthRoot" :: Symbol) =>
+ n := retract(second args)@I
+ nthRootToGenUPS(first args,n :: NNI,posCheck?,atanFlag)
+ stateProblem(string name ker,"unknown kernel")
+
+ nthRootToGenUPS(arg,n,posCheck?,atanFlag) ==
+ -- convert an nth root to a power series
+ -- used for computing right hand limits, so the series may have
+ -- non-zero order, but may not have a negative leading coefficient
+ -- when n is even
+ (result := iExprToGenUPS(arg,posCheck?,atanFlag)) case %problem =>
+ result
+ ans := carefulNthRootIfCan(result.%series,n,posCheck?,true)
+ ans case %problem => ans
+ [ans.%series]
+
+ logToGenUPS(arg,posCheck?,atanFlag) ==
+ -- converts a logarithm log(f(x)) to a generalized power series
+ (result := iExprToGenUPS(arg,posCheck?,atanFlag)) case %problem =>
+ result
+ ups := result.%series; deg := degree ups
+ if (coef := coefficient(ups,deg)) = 0 then
+ deg := order(ups,deg + ZEROCOUNT :: Expon)
+ (coef := coefficient(ups,deg)) = 0 =>
+ error "log of series with many leading zero coefficients"
+ -- if 'posCheck?' is true, we do not allow logs of negative numbers
+ if posCheck? then
+ if ((signum := sign(coef)$SIGNEF) case I) then
+ (signum :: I) = -1 =>
+ return stateProblem("log","negative leading coefficient")
+ -- create logarithmic term, avoiding log's of negative rationals
+ lt := monomial(coef,deg)$UPS; cen := center lt
+ -- check to see if lowest order coefficient is a negative rational
+ negRat? : Boolean :=
+ ((rat := ratIfCan coef) case RN) =>
+ (rat :: RN) < 0 => true
+ false
+ false
+ logTerm : FE :=
+ mon : FE := (x :: FE) - (cen :: FE)
+ pow : FE := mon ** (deg :: FE)
+ negRat? => log(coef * pow)
+ term1 : FE := (deg :: FE) * log(mon)
+ log(coef) + term1
+ [monomial(logTerm,0) + log(ups/lt)]
+
+ expToGenUPS(arg,posCheck?,atanFlag) ==
+ -- converts an exponential exp(f(x)) to a generalized
+ -- power series
+ (ups := iExprToGenUPS(arg,posCheck?,atanFlag)) case %problem => ups
+ expGenUPS(ups.%series,posCheck?,atanFlag)
+
+ expGenUPS(ups,posCheck?,atanFlag) ==
+ -- computes the exponential of a generalized power series.
+ -- If the series has order zero and the constant term a0 of the
+ -- series involves x, the function tries to expand exp(a0) as
+ -- a power series.
+ (deg := order(ups,1)) < 0 =>
+ stateProblem("exp","essential singularity")
+ deg > 0 => [exp ups]
+ lc := coefficient(ups,0); xOpList := opsInvolvingX lc
+ not opInOpList?("log" :: SY,xOpList) => [exp ups]
+ -- try to fix exp(lc) if necessary
+ expCoef :=
+ normalize(exp lc,x)$ElementaryFunctionStructurePackage(R,FE)
+ opInOpList?("log" :: SY,opsInvolvingX expCoef) =>
+ stateProblem("exp","logs in constant coefficient")
+ result := exprToGenUPS(expCoef,posCheck?,atanFlag)
+ result case %problem => result
+ [(result.%series) * exp(ups - monomial(lc,0))]
+
+ atancotToGenUPS(fe,arg,posCheck?,atanFlag,plusMinus) ==
+ -- converts atan(f(x)) to a generalized power series
+ (result := exprToGenUPS(arg,posCheck?,atanFlag)) case %problem =>
+ trouble := result.%problem
+ trouble.prob = "essential singularity" => [monomial(fe,0)$UPS]
+ result
+ ups := result.%series; coef := coefficient(ups,0)
+ -- series involves complex numbers
+ (ord := order(ups,0)) = 0 and coef * coef = -1 =>
+ y := differentiate(ups)/(1 + ups*ups)
+ yCoef := coefficient(y,-1)
+ [monomial(log yCoef,0) + integrate(y - monomial(yCoef,-1)$UPS)]
+ cc : FE :=
+ ord < 0 =>
+ atanFlag = "complex" =>
+ return stateProblem("atan","essential singularity")
+ (rn := ratIfCan(ord :: FE)) case "failed" =>
+ -- this condition usually won't occur because exponents will
+ -- be integers or rational numbers
+ return stateProblem("atan","branch problem")
+ if (atanFlag = "real: two sides") and (odd? numer(rn :: RN)) then
+ -- expansions to the left and right of zero have different
+ -- constant coefficients
+ return stateProblem("atan","branch problem")
+ lc := coefficient(ups,ord)
+ (signum := sign(lc)$SIGNEF) case "failed" =>
+ -- can't determine sign
+ atanFlag = "just do it" =>
+ plusMinus = 1 => pi()/(2 :: FE)
+ 0
+ posNegPi2 := signOfExpression(lc) * pi()/(2 :: FE)
+ plusMinus = 1 => posNegPi2
+ pi()/(2 :: FE) - posNegPi2
+ --return stateProblem("atan","branch problem")
+ left? : B := atanFlag = "real: left side"; n := signum :: Integer
+ (left? and n = 1) or (not left? and n = -1) =>
+ plusMinus = 1 => -pi()/(2 :: FE)
+ pi()
+ plusMinus = 1 => pi()/(2 :: FE)
+ 0
+ atan coef
+ [(cc :: UPS) + integrate(differentiate(ups)/(1 + ups*ups))]
+
+ genUPSApplyIfCan(fcn,arg,fcnName,posCheck?,atanFlag) ==
+ -- converts fcn(arg) to a generalized power series
+ (series := iExprToGenUPS(arg,posCheck?,atanFlag)) case %problem =>
+ series
+ ups := series.%series
+ (deg := order(ups,1)) < 0 =>
+ stateProblem(fcnName,"essential singularity")
+ deg > 0 => [fcn(ups) :: UPS]
+ lc := coefficient(ups,0); xOpList := opsInvolvingX lc
+ null xOpList => [fcn(ups) :: UPS]
+ opInOpList?("log" :: SY,xOpList) =>
+ stateProblem(fcnName,"logs in constant coefficient")
+ contOnReals? fcnName => [fcn(ups) :: UPS]
+ stateProblem(fcnName,"x in constant coefficient")
+
+ applyBddIfCan(fe,fcn,arg,fcnName,posCheck?,atanFlag) ==
+ -- converts fcn(arg) to a generalized power series, where the
+ -- function fcn is bounded for real values
+ -- if fcn(arg) has an essential singularity as a complex
+ -- function, we return fcn(arg) as a monomial of degree 0
+ (ups := iExprToGenUPS(arg,posCheck?,atanFlag)) case %problem =>
+ trouble := ups.%problem
+ trouble.prob = "essential singularity" => [monomial(fe,0)$UPS]
+ ups
+ (ans := fcn(ups.%series)) case "failed" => [monomial(fe,0)$UPS]
+ [ans :: UPS]
+
+ tranToGenUPS(ker,arg,posCheck?,atanFlag) ==
+ -- converts op(arg) to a power series for certain functions
+ -- op in trig or hyperbolic trig categories
+ -- N.B. when this function is called, 'k2elem' will have been
+ -- applied, so the following functions cannot appear:
+ -- tan, cot, sec, csc, sinh, cosh, tanh, coth, sech, csch
+ is?(ker,"sin" :: SY) =>
+ applyBddIfCan(ker :: FE,sinIfCan,arg,"sin",posCheck?,atanFlag)
+ is?(ker,"cos" :: SY) =>
+ applyBddIfCan(ker :: FE,cosIfCan,arg,"cos",posCheck?,atanFlag)
+ is?(ker,"asin" :: SY) =>
+ genUPSApplyIfCan(asinIfCan,arg,"asin",posCheck?,atanFlag)
+ is?(ker,"acos" :: SY) =>
+ genUPSApplyIfCan(acosIfCan,arg,"acos",posCheck?,atanFlag)
+ is?(ker,"atan" :: SY) =>
+ atancotToGenUPS(ker :: FE,arg,posCheck?,atanFlag,1)
+ is?(ker,"acot" :: SY) =>
+ atancotToGenUPS(ker :: FE,arg,posCheck?,atanFlag,-1)
+ is?(ker,"asec" :: SY) =>
+ genUPSApplyIfCan(asecIfCan,arg,"asec",posCheck?,atanFlag)
+ is?(ker,"acsc" :: SY) =>
+ genUPSApplyIfCan(acscIfCan,arg,"acsc",posCheck?,atanFlag)
+ is?(ker,"asinh" :: SY) =>
+ genUPSApplyIfCan(asinhIfCan,arg,"asinh",posCheck?,atanFlag)
+ is?(ker,"acosh" :: SY) =>
+ genUPSApplyIfCan(acoshIfCan,arg,"acosh",posCheck?,atanFlag)
+ is?(ker,"atanh" :: SY) =>
+ genUPSApplyIfCan(atanhIfCan,arg,"atanh",posCheck?,atanFlag)
+ is?(ker,"acoth" :: SY) =>
+ genUPSApplyIfCan(acothIfCan,arg,"acoth",posCheck?,atanFlag)
+ is?(ker,"asech" :: SY) =>
+ genUPSApplyIfCan(asechIfCan,arg,"asech",posCheck?,atanFlag)
+ is?(ker,"acsch" :: SY) =>
+ genUPSApplyIfCan(acschIfCan,arg,"acsch",posCheck?,atanFlag)
+ stateProblem(string name ker,"unknown kernel")
+
+ powToGenUPS(args,posCheck?,atanFlag) ==
+ -- converts a power f(x) ** g(x) to a generalized power series
+ (logBase := logToGenUPS(first args,posCheck?,atanFlag)) case %problem =>
+ logBase
+ expon := iExprToGenUPS(second args,posCheck?,atanFlag)
+ expon case %problem => expon
+ expGenUPS((expon.%series) * (logBase.%series),posCheck?,atanFlag)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FS2UPS FunctionSpaceToUnivariatePowerSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/fspace.spad.pamphlet b/src/algebra/fspace.spad.pamphlet
new file mode 100644
index 00000000..b1bd6454
--- /dev/null
+++ b/src/algebra/fspace.spad.pamphlet
@@ -0,0 +1,1246 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra fspace.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ES ExpressionSpace}
+<<category ES ExpressionSpace>>=
+)abbrev category ES ExpressionSpace
+++ Category for domains on which operators can be applied
+++ Author: Manuel Bronstein
+++ Date Created: 22 March 1988
+++ Date Last Updated: 27 May 1994
+++ Description:
+++ An expression space is a set which is closed under certain operators;
+++ Keywords: operator, kernel, expression, space.
+ExpressionSpace(): Category == Defn where
+ N ==> NonNegativeInteger
+ K ==> Kernel %
+ OP ==> BasicOperator
+ SY ==> Symbol
+ PAREN ==> "%paren"::SY
+ BOX ==> "%box"::SY
+ DUMMYVAR ==> "%dummyVar"
+
+ Defn ==> Join(OrderedSet, RetractableTo K,
+ InnerEvalable(K, %), Evalable %) with
+ elt : (OP, %) -> %
+ ++ elt(op,x) or op(x) applies the unary operator op to x.
+ elt : (OP, %, %) -> %
+ ++ elt(op,x,y) or op(x, y) applies the binary operator op to x and y.
+ elt : (OP, %, %, %) -> %
+ ++ elt(op,x,y,z) or op(x, y, z) applies the ternary operator op to x, y and z.
+ elt : (OP, %, %, %, %) -> %
+ ++ elt(op,x,y,z,t) or op(x, y, z, t) applies the 4-ary operator op to x, y, z and t.
+ elt : (OP, List %) -> %
+ ++ elt(op,[x1,...,xn]) or op([x1,...,xn]) applies the n-ary operator op to x1,...,xn.
+ subst : (%, Equation %) -> %
+ ++ subst(f, k = g) replaces the kernel k by g formally in f.
+ subst : (%, List Equation %) -> %
+ ++ subst(f, [k1 = g1,...,kn = gn]) replaces the kernels k1,...,kn
+ ++ by g1,...,gn formally in f.
+ subst : (%, List K, List %) -> %
+ ++ subst(f, [k1...,kn], [g1,...,gn]) replaces the kernels k1,...,kn
+ ++ by g1,...,gn formally in f.
+ box : % -> %
+ ++ box(f) returns f with a 'box' around it that prevents f from
+ ++ being evaluated when operators are applied to it. For example,
+ ++ \spad{log(1)} returns 0, but \spad{log(box 1)}
+ ++ returns the formal kernel log(1).
+ box : List % -> %
+ ++ box([f1,...,fn]) returns \spad{(f1,...,fn)} with a 'box'
+ ++ around them that
+ ++ prevents the fi from being evaluated when operators are applied to
+ ++ them, and makes them applicable to a unary operator. For example,
+ ++ \spad{atan(box [x, 2])} returns the formal kernel \spad{atan(x, 2)}.
+ paren : % -> %
+ ++ paren(f) returns (f). This prevents f from
+ ++ being evaluated when operators are applied to it. For example,
+ ++ \spad{log(1)} returns 0, but \spad{log(paren 1)} returns the
+ ++ formal kernel log((1)).
+ paren : List % -> %
+ ++ paren([f1,...,fn]) returns \spad{(f1,...,fn)}. This
+ ++ prevents the fi from being evaluated when operators are applied to
+ ++ them, and makes them applicable to a unary operator. For example,
+ ++ \spad{atan(paren [x, 2])} returns the formal
+ ++ kernel \spad{atan((x, 2))}.
+ distribute : % -> %
+ ++ distribute(f) expands all the kernels in f that are
+ ++ formally enclosed by a \spadfunFrom{box}{ExpressionSpace}
+ ++ or \spadfunFrom{paren}{ExpressionSpace} expression.
+ distribute : (%, %) -> %
+ ++ distribute(f, g) expands all the kernels in f that contain g in their
+ ++ arguments and that are formally
+ ++ enclosed by a \spadfunFrom{box}{ExpressionSpace}
+ ++ or a \spadfunFrom{paren}{ExpressionSpace} expression.
+ height : % -> N
+ ++ height(f) returns the highest nesting level appearing in f.
+ ++ Constants have height 0. Symbols have height 1. For any
+ ++ operator op and expressions f1,...,fn, \spad{op(f1,...,fn)} has
+ ++ height equal to \spad{1 + max(height(f1),...,height(fn))}.
+ mainKernel : % -> Union(K, "failed")
+ ++ mainKernel(f) returns a kernel of f with maximum nesting level, or
+ ++ if f has no kernels (i.e. f is a constant).
+ kernels : % -> List K
+ ++ kernels(f) returns the list of all the top-level kernels
+ ++ appearing in f, but not the ones appearing in the arguments
+ ++ of the top-level kernels.
+ tower : % -> List K
+ ++ tower(f) returns all the kernels appearing in f, no matter
+ ++ what their levels are.
+ operators : % -> List OP
+ ++ operators(f) returns all the basic operators appearing in f,
+ ++ no matter what their levels are.
+ operator : OP -> OP
+ ++ operator(op) returns a copy of op with the domain-dependent
+ ++ properties appropriate for %.
+ belong? : OP -> Boolean
+ ++ belong?(op) tests if % accepts op as applicable to its
+ ++ elements.
+ is? : (%, OP) -> Boolean
+ ++ is?(x, op) tests if x is a kernel and is its operator is op.
+ is? : (%, SY) -> Boolean
+ ++ is?(x, s) tests if x is a kernel and is the name of its
+ ++ operator is s.
+ kernel : (OP, %) -> %
+ ++ kernel(op, x) constructs op(x) without evaluating it.
+ kernel : (OP, List %) -> %
+ ++ kernel(op, [f1,...,fn]) constructs \spad{op(f1,...,fn)} without
+ ++ evaluating it.
+ map : (% -> %, K) -> %
+ ++ map(f, k) returns \spad{op(f(x1),...,f(xn))} where
+ ++ \spad{k = op(x1,...,xn)}.
+ freeOf? : (%, %) -> Boolean
+ ++ freeOf?(x, y) tests if x does not contain any occurrence of y,
+ ++ where y is a single kernel.
+ freeOf? : (%, SY) -> Boolean
+ ++ freeOf?(x, s) tests if x does not contain any operator
+ ++ whose name is s.
+ eval : (%, List SY, List(% -> %)) -> %
+ ++ eval(x, [s1,...,sm], [f1,...,fm]) replaces
+ ++ every \spad{si(a)} in x by \spad{fi(a)} for any \spad{a}.
+ eval : (%, List SY, List(List % -> %)) -> %
+ ++ eval(x, [s1,...,sm], [f1,...,fm]) replaces
+ ++ every \spad{si(a1,...,an)} in x by
+ ++ \spad{fi(a1,...,an)} for any \spad{a1},...,\spad{an}.
+ eval : (%, SY, List % -> %) -> %
+ ++ eval(x, s, f) replaces every \spad{s(a1,..,am)} in x
+ ++ by \spad{f(a1,..,am)} for any \spad{a1},...,\spad{am}.
+ eval : (%, SY, % -> %) -> %
+ ++ eval(x, s, f) replaces every \spad{s(a)} in x by \spad{f(a)}
+ ++ for any \spad{a}.
+ eval : (%, List OP, List(% -> %)) -> %
+ ++ eval(x, [s1,...,sm], [f1,...,fm]) replaces
+ ++ every \spad{si(a)} in x by \spad{fi(a)} for any \spad{a}.
+ eval : (%, List OP, List(List % -> %)) -> %
+ ++ eval(x, [s1,...,sm], [f1,...,fm]) replaces
+ ++ every \spad{si(a1,...,an)} in x by
+ ++ \spad{fi(a1,...,an)} for any \spad{a1},...,\spad{an}.
+ eval : (%, OP, List % -> %) -> %
+ ++ eval(x, s, f) replaces every \spad{s(a1,..,am)} in x
+ ++ by \spad{f(a1,..,am)} for any \spad{a1},...,\spad{am}.
+ eval : (%, OP, % -> %) -> %
+ ++ eval(x, s, f) replaces every \spad{s(a)} in x by \spad{f(a)}
+ ++ for any \spad{a}.
+ if % has Ring then
+ minPoly: K -> SparseUnivariatePolynomial %
+ ++ minPoly(k) returns p such that \spad{p(k) = 0}.
+ definingPolynomial: % -> %
+ ++ definingPolynomial(x) returns an expression p such that
+ ++ \spad{p(x) = 0}.
+ if % has RetractableTo Integer then
+ even?: % -> Boolean
+ ++ even? x is true if x is an even integer.
+ odd? : % -> Boolean
+ ++ odd? x is true if x is an odd integer.
+
+ add
+
+-- the 7 functions not provided are:
+-- kernels minPoly definingPolynomial
+-- coerce:K -> % eval:(%, List K, List %) -> %
+-- subst:(%, List K, List %) -> %
+-- eval:(%, List Symbol, List(List % -> %)) -> %
+
+ allKernels: % -> Set K
+ listk : % -> List K
+ allk : List % -> Set K
+ unwrap : (List K, %) -> %
+ okkernel : (OP, List %) -> %
+ mkKerLists: List Equation % -> Record(lstk: List K, lstv:List %)
+
+ oppren := operator(PAREN)$CommonOperators()
+ opbox := operator(BOX)$CommonOperators()
+
+ box(x:%) == box [x]
+ paren(x:%) == paren [x]
+ belong? op == op = oppren or op = opbox
+ listk f == parts allKernels f
+ tower f == sort_! listk f
+ allk l == reduce("union", [allKernels f for f in l], {})
+ operators f == [operator k for k in listk f]
+ height f == reduce("max", [height k for k in kernels f], 0)
+ freeOf?(x:%, s:SY) == not member?(s, [name k for k in listk x])
+ distribute x == unwrap([k for k in listk x | is?(k, oppren)], x)
+ box(l:List %) == opbox l
+ paren(l:List %) == oppren l
+ freeOf?(x:%, k:%) == not member?(retract k, listk x)
+ kernel(op:OP, arg:%) == kernel(op, [arg])
+ elt(op:OP, x:%) == op [x]
+ elt(op:OP, x:%, y:%) == op [x, y]
+ elt(op:OP, x:%, y:%, z:%) == op [x, y, z]
+ elt(op:OP, x:%, y:%, z:%, t:%) == op [x, y, z, t]
+ eval(x:%, s:SY, f:List % -> %) == eval(x, [s], [f])
+ eval(x:%, s:OP, f:List % -> %) == eval(x, [name s], [f])
+ eval(x:%, s:SY, f:% -> %) == eval(x, [s], [f first #1])
+ eval(x:%, s:OP, f:% -> %) == eval(x, [s], [f first #1])
+ subst(x:%, e:Equation %) == subst(x, [e])
+
+ eval(x:%, ls:List OP, lf:List(% -> %)) ==
+ eval(x, ls, [f first #1 for f in lf]$List(List % -> %))
+
+ eval(x:%, ls:List SY, lf:List(% -> %)) ==
+ eval(x, ls, [f first #1 for f in lf]$List(List % -> %))
+
+ eval(x:%, ls:List OP, lf:List(List % -> %)) ==
+ eval(x, [name s for s in ls]$List(SY), lf)
+
+ map(fn, k) ==
+ (l := [fn x for x in argument k]$List(%)) = argument k => k::%
+ (operator k) l
+
+ operator op ==
+ is?(op, PAREN) => oppren
+ is?(op, BOX) => opbox
+ error "Unknown operator"
+
+ mainKernel x ==
+ empty?(l := kernels x) => "failed"
+ n := height(k := first l)
+ for kk in rest l repeat
+ if height(kk) > n then
+ n := height kk
+ k := kk
+ k
+
+-- takes all the kernels except for the dummy variables, which are second
+-- arguments of rootOf's, integrals, sums and products which appear only in
+-- their first arguments
+ allKernels f ==
+ s := brace(l := kernels f)
+ for k in l repeat
+ t :=
+ (u := property(operator k, DUMMYVAR)) case None =>
+ arg := argument k
+ s0 := remove_!(retract(second arg)@K, allKernels first arg)
+ arg := rest rest arg
+ n := (u::None) pretend N
+ if n > 1 then arg := rest arg
+ union(s0, allk arg)
+ allk argument k
+ s := union(s, t)
+ s
+
+ kernel(op:OP, args:List %) ==
+ not belong? op => error "Unknown operator"
+ okkernel(op, args)
+
+ okkernel(op, l) ==
+ kernel(op, l, 1 + reduce("max", [height f for f in l], 0))$K :: %
+
+ elt(op:OP, args:List %) ==
+ not belong? op => error "Unknown operator"
+ ((u := arity op) case N) and (#args ^= u::N)
+ => error "Wrong number of arguments"
+ (v := evaluate(op,args)$BasicOperatorFunctions1(%)) case % => v::%
+ okkernel(op, args)
+
+ retract f ==
+ (k := mainKernel f) case "failed" => error "not a kernel"
+ k::K::% ^= f => error "not a kernel"
+ k::K
+
+ retractIfCan f ==
+ (k := mainKernel f) case "failed" => "failed"
+ k::K::% ^= f => "failed"
+ k
+
+ is?(f:%, s:SY) ==
+ (k := retractIfCan f) case "failed" => false
+ is?(k::K, s)
+
+ is?(f:%, op:OP) ==
+ (k := retractIfCan f) case "failed" => false
+ is?(k::K, op)
+
+ unwrap(l, x) ==
+ for k in reverse_! l repeat
+ x := eval(x, k, first argument k)
+ x
+
+ distribute(x, y) ==
+ ky := retract y
+ unwrap([k for k in listk x |
+ is?(k, "%paren"::SY) and member?(ky, listk(k::%))], x)
+
+ -- in case of conflicting substitutions e.g. [x = a, x = b],
+ -- the first one prevails.
+ -- this is not part of the semantics of the function, but just
+ -- a feature of this implementation.
+ eval(f:%, leq:List Equation %) ==
+ rec := mkKerLists leq
+ eval(f, rec.lstk, rec.lstv)
+
+ subst(f:%, leq:List Equation %) ==
+ rec := mkKerLists leq
+ subst(f, rec.lstk, rec.lstv)
+
+ mkKerLists leq ==
+ lk := empty()$List(K)
+ lv := empty()$List(%)
+ for eq in leq repeat
+ (k := retractIfCan(lhs eq)@Union(K, "failed")) case "failed" =>
+ error "left hand side must be a single kernel"
+ if not member?(k::K, lk) then
+ lk := concat(k::K, lk)
+ lv := concat(rhs eq, lv)
+ [lk, lv]
+
+ if % has RetractableTo Integer then
+ intpred?: (%, Integer -> Boolean) -> Boolean
+
+ even? x == intpred?(x, even?)
+ odd? x == intpred?(x, odd?)
+
+ intpred?(x, pred?) ==
+ (u := retractIfCan(x)@Union(Integer, "failed")) case Integer
+ and pred?(u::Integer)
+
+@
+\section{ES.lsp BOOTSTRAP}
+{\bf ES} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ES}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ES.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ES.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |ExpressionSpace;AL| (QUOTE NIL))
+
+(DEFUN |ExpressionSpace| NIL (LET (#:G82344) (COND (|ExpressionSpace;AL|) (T (SETQ |ExpressionSpace;AL| (|ExpressionSpace;|))))))
+
+(DEFUN |ExpressionSpace;| NIL (PROG (#1=#:G82342) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (#2=#:G82340 #3=#:G82341)) (LIST (QUOTE (|Kernel| |$|)) (QUOTE (|Kernel| |$|)))) (|Join| (|OrderedSet|) (|RetractableTo| (QUOTE #2#)) (|InnerEvalable| (QUOTE #3#) (QUOTE |$|)) (|Evalable| (QUOTE |$|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|elt| (|$| (|BasicOperator|) |$|)) T) ((|elt| (|$| (|BasicOperator|) |$| |$|)) T) ((|elt| (|$| (|BasicOperator|) |$| |$| |$|)) T) ((|elt| (|$| (|BasicOperator|) |$| |$| |$| |$|)) T) ((|elt| (|$| (|BasicOperator|) (|List| |$|))) T) ((|subst| (|$| |$| (|Equation| |$|))) T) ((|subst| (|$| |$| (|List| (|Equation| |$|)))) T) ((|subst| (|$| |$| (|List| (|Kernel| |$|)) (|List| |$|))) T) ((|box| (|$| |$|)) T) ((|box| (|$| (|List| |$|))) T) ((|paren| (|$| |$|)) T) ((|paren| (|$| (|List| |$|))) T) ((|distribute| (|$| |$|)) T) ((|distribute| (|$| |$| |$|)) T) ((|height| ((|NonNegativeInteger|) |$|)) T) ((|mainKernel| ((|Union| (|Kernel| |$|) "failed") |$|)) T) ((|kernels| ((|List| (|Kernel| |$|)) |$|)) T) ((|tower| ((|List| (|Kernel| |$|)) |$|)) T) ((|operators| ((|List| (|BasicOperator|)) |$|)) T) ((|operator| ((|BasicOperator|) (|BasicOperator|))) T) ((|belong?| ((|Boolean|) (|BasicOperator|))) T) ((|is?| ((|Boolean|) |$| (|BasicOperator|))) T) ((|is?| ((|Boolean|) |$| (|Symbol|))) T) ((|kernel| (|$| (|BasicOperator|) |$|)) T) ((|kernel| (|$| (|BasicOperator|) (|List| |$|))) T) ((|map| (|$| (|Mapping| |$| |$|) (|Kernel| |$|))) T) ((|freeOf?| ((|Boolean|) |$| |$|)) T) ((|freeOf?| ((|Boolean|) |$| (|Symbol|))) T) ((|eval| (|$| |$| (|List| (|Symbol|)) (|List| (|Mapping| |$| |$|)))) T) ((|eval| (|$| |$| (|List| (|Symbol|)) (|List| (|Mapping| |$| (|List| |$|))))) T) ((|eval| (|$| |$| (|Symbol|) (|Mapping| |$| (|List| |$|)))) T) ((|eval| (|$| |$| (|Symbol|) (|Mapping| |$| |$|))) T) ((|eval| (|$| |$| (|List| (|BasicOperator|)) (|List| (|Mapping| |$| |$|)))) T) ((|eval| (|$| |$| (|List| (|BasicOperator|)) (|List| (|Mapping| |$| (|List| |$|))))) T) ((|eval| (|$| |$| (|BasicOperator|) (|Mapping| |$| (|List| |$|)))) T) ((|eval| (|$| |$| (|BasicOperator|) (|Mapping| |$| |$|))) T) ((|minPoly| ((|SparseUnivariatePolynomial| |$|) (|Kernel| |$|))) (|has| |$| (|Ring|))) ((|definingPolynomial| (|$| |$|)) (|has| |$| (|Ring|))) ((|even?| ((|Boolean|) |$|)) (|has| |$| (|RetractableTo| (|Integer|)))) ((|odd?| ((|Boolean|) |$|)) (|has| |$| (|RetractableTo| (|Integer|)))))) NIL (QUOTE ((|Boolean|) (|SparseUnivariatePolynomial| |$|) (|Kernel| |$|) (|BasicOperator|) (|List| (|BasicOperator|)) (|List| (|Mapping| |$| (|List| |$|))) (|List| (|Mapping| |$| |$|)) (|Symbol|) (|List| (|Symbol|)) (|List| |$|) (|List| (|Kernel| |$|)) (|NonNegativeInteger|) (|List| (|Equation| |$|)) (|Equation| |$|))) NIL))) |ExpressionSpace|) (SETELT #1# 0 (QUOTE (|ExpressionSpace|)))))))
+
+(MAKEPROP (QUOTE |ExpressionSpace|) (QUOTE NILADIC) T)
+@
+\section{ES-.lsp BOOTSTRAP}
+{\bf ES-} depends on {\bf ES}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ES-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ES-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ES-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |ES-;box;2S;1| (|x| |$|) (SPADCALL (LIST |x|) (QREFELT |$| 16)))
+
+(DEFUN |ES-;paren;2S;2| (|x| |$|) (SPADCALL (LIST |x|) (QREFELT |$| 18)))
+
+(DEFUN |ES-;belong?;BoB;3| (|op| |$|) (COND ((SPADCALL |op| (QREFELT |$| 13) (QREFELT |$| 21)) (QUOTE T)) ((QUOTE T) (SPADCALL |op| (QREFELT |$| 14) (QREFELT |$| 21)))))
+
+(DEFUN |ES-;listk| (|f| |$|) (SPADCALL (|ES-;allKernels| |f| |$|) (QREFELT |$| 25)))
+
+(DEFUN |ES-;tower;SL;5| (|f| |$|) (SPADCALL (|ES-;listk| |f| |$|) (QREFELT |$| 26)))
+
+(DEFUN |ES-;allk| (|l| |$|) (PROG (#1=#:G82361 |f| #2=#:G82362) (RETURN (SEQ (SPADCALL (ELT |$| 30) (PROGN (LETT #1# NIL |ES-;allk|) (SEQ (LETT |f| NIL |ES-;allk|) (LETT #2# |l| |ES-;allk|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |f| (CAR #2#) |ES-;allk|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (|ES-;allKernels| |f| |$|) #1#) |ES-;allk|))) (LETT #2# (CDR #2#) |ES-;allk|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (SPADCALL NIL (QREFELT |$| 29)) (QREFELT |$| 33))))))
+
+(DEFUN |ES-;operators;SL;7| (|f| |$|) (PROG (#1=#:G82365 |k| #2=#:G82366) (RETURN (SEQ (PROGN (LETT #1# NIL |ES-;operators;SL;7|) (SEQ (LETT |k| NIL |ES-;operators;SL;7|) (LETT #2# (|ES-;listk| |f| |$|) |ES-;operators;SL;7|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |k| (CAR #2#) |ES-;operators;SL;7|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |k| (QREFELT |$| 35)) #1#) |ES-;operators;SL;7|))) (LETT #2# (CDR #2#) |ES-;operators;SL;7|) (GO G190) G191 (EXIT (NREVERSE0 #1#))))))))
+
+(DEFUN |ES-;height;SNni;8| (|f| |$|) (PROG (#1=#:G82371 |k| #2=#:G82372) (RETURN (SEQ (SPADCALL (ELT |$| 41) (PROGN (LETT #1# NIL |ES-;height;SNni;8|) (SEQ (LETT |k| NIL |ES-;height;SNni;8|) (LETT #2# (SPADCALL |f| (QREFELT |$| 38)) |ES-;height;SNni;8|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |k| (CAR #2#) |ES-;height;SNni;8|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |k| (QREFELT |$| 40)) #1#) |ES-;height;SNni;8|))) (LETT #2# (CDR #2#) |ES-;height;SNni;8|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) 0 (QREFELT |$| 44))))))
+
+(DEFUN |ES-;freeOf?;SSB;9| (|x| |s| |$|) (PROG (#1=#:G82377 |k| #2=#:G82378) (RETURN (SEQ (COND ((SPADCALL |s| (PROGN (LETT #1# NIL |ES-;freeOf?;SSB;9|) (SEQ (LETT |k| NIL |ES-;freeOf?;SSB;9|) (LETT #2# (|ES-;listk| |x| |$|) |ES-;freeOf?;SSB;9|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |k| (CAR #2#) |ES-;freeOf?;SSB;9|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |k| (QREFELT |$| 46)) #1#) |ES-;freeOf?;SSB;9|))) (LETT #2# (CDR #2#) |ES-;freeOf?;SSB;9|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 48)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))))))
+
+(DEFUN |ES-;distribute;2S;10| (|x| |$|) (PROG (#1=#:G82381 |k| #2=#:G82382) (RETURN (SEQ (|ES-;unwrap| (PROGN (LETT #1# NIL |ES-;distribute;2S;10|) (SEQ (LETT |k| NIL |ES-;distribute;2S;10|) (LETT #2# (|ES-;listk| |x| |$|) |ES-;distribute;2S;10|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |k| (CAR #2#) |ES-;distribute;2S;10|) NIL)) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |k| (QREFELT |$| 13) (QREFELT |$| 50)) (LETT #1# (CONS |k| #1#) |ES-;distribute;2S;10|))))) (LETT #2# (CDR #2#) |ES-;distribute;2S;10|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |x| |$|)))))
+
+(DEFUN |ES-;box;LS;11| (|l| |$|) (SPADCALL (QREFELT |$| 14) |l| (QREFELT |$| 52)))
+
+(DEFUN |ES-;paren;LS;12| (|l| |$|) (SPADCALL (QREFELT |$| 13) |l| (QREFELT |$| 52)))
+
+(DEFUN |ES-;freeOf?;2SB;13| (|x| |k| |$|) (COND ((SPADCALL (SPADCALL |k| (QREFELT |$| 56)) (|ES-;listk| |x| |$|) (QREFELT |$| 57)) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |ES-;kernel;Bo2S;14| (|op| |arg| |$|) (SPADCALL |op| (LIST |arg|) (QREFELT |$| 59)))
+
+(DEFUN |ES-;elt;Bo2S;15| (|op| |x| |$|) (SPADCALL |op| (LIST |x|) (QREFELT |$| 52)))
+
+(DEFUN |ES-;elt;Bo3S;16| (|op| |x| |y| |$|) (SPADCALL |op| (LIST |x| |y|) (QREFELT |$| 52)))
+
+(DEFUN |ES-;elt;Bo4S;17| (|op| |x| |y| |z| |$|) (SPADCALL |op| (LIST |x| |y| |z|) (QREFELT |$| 52)))
+
+(DEFUN |ES-;elt;Bo5S;18| (|op| |x| |y| |z| |t| |$|) (SPADCALL |op| (LIST |x| |y| |z| |t|) (QREFELT |$| 52)))
+
+(DEFUN |ES-;eval;SSMS;19| (|x| |s| |f| |$|) (SPADCALL |x| (LIST |s|) (LIST |f|) (QREFELT |$| 67)))
+
+(DEFUN |ES-;eval;SBoMS;20| (|x| |s| |f| |$|) (SPADCALL |x| (LIST (SPADCALL |s| (QREFELT |$| 69))) (LIST |f|) (QREFELT |$| 67)))
+
+(DEFUN |ES-;eval;SSMS;21| (|x| |s| |f| |$|) (SPADCALL |x| (LIST |s|) (LIST (CONS (FUNCTION |ES-;eval;SSMS;21!0|) (VECTOR |f| |$|))) (QREFELT |$| 67)))
+
+(DEFUN |ES-;eval;SSMS;21!0| (|#1| |$$|) (SPADCALL (SPADCALL |#1| (QREFELT (QREFELT |$$| 1) 72)) (QREFELT |$$| 0)))
+
+(DEFUN |ES-;eval;SBoMS;22| (|x| |s| |f| |$|) (SPADCALL |x| (LIST |s|) (LIST (CONS (FUNCTION |ES-;eval;SBoMS;22!0|) (VECTOR |f| |$|))) (QREFELT |$| 75)))
+
+(DEFUN |ES-;eval;SBoMS;22!0| (|#1| |$$|) (SPADCALL (SPADCALL |#1| (QREFELT (QREFELT |$$| 1) 72)) (QREFELT |$$| 0)))
+
+(DEFUN |ES-;subst;SES;23| (|x| |e| |$|) (SPADCALL |x| (LIST |e|) (QREFELT |$| 78)))
+
+(DEFUN |ES-;eval;SLLS;24| (|x| |ls| |lf| |$|) (PROG (#1=#:G82403 |f| #2=#:G82404) (RETURN (SEQ (SPADCALL |x| |ls| (PROGN (LETT #1# NIL |ES-;eval;SLLS;24|) (SEQ (LETT |f| NIL |ES-;eval;SLLS;24|) (LETT #2# |lf| |ES-;eval;SLLS;24|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |f| (CAR #2#) |ES-;eval;SLLS;24|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (CONS (FUNCTION |ES-;eval;SLLS;24!0|) (VECTOR |f| |$|)) #1#) |ES-;eval;SLLS;24|))) (LETT #2# (CDR #2#) |ES-;eval;SLLS;24|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 75))))))
+
+(DEFUN |ES-;eval;SLLS;24!0| (|#1| |$$|) (SPADCALL (SPADCALL |#1| (QREFELT (QREFELT |$$| 1) 72)) (QREFELT |$$| 0)))
+
+(DEFUN |ES-;eval;SLLS;25| (|x| |ls| |lf| |$|) (PROG (#1=#:G82407 |f| #2=#:G82408) (RETURN (SEQ (SPADCALL |x| |ls| (PROGN (LETT #1# NIL |ES-;eval;SLLS;25|) (SEQ (LETT |f| NIL |ES-;eval;SLLS;25|) (LETT #2# |lf| |ES-;eval;SLLS;25|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |f| (CAR #2#) |ES-;eval;SLLS;25|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (CONS (FUNCTION |ES-;eval;SLLS;25!0|) (VECTOR |f| |$|)) #1#) |ES-;eval;SLLS;25|))) (LETT #2# (CDR #2#) |ES-;eval;SLLS;25|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 67))))))
+
+(DEFUN |ES-;eval;SLLS;25!0| (|#1| |$$|) (SPADCALL (SPADCALL |#1| (QREFELT (QREFELT |$$| 1) 72)) (QREFELT |$$| 0)))
+
+(DEFUN |ES-;eval;SLLS;26| (|x| |ls| |lf| |$|) (PROG (#1=#:G82412 |s| #2=#:G82413) (RETURN (SEQ (SPADCALL |x| (PROGN (LETT #1# NIL |ES-;eval;SLLS;26|) (SEQ (LETT |s| NIL |ES-;eval;SLLS;26|) (LETT #2# |ls| |ES-;eval;SLLS;26|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |s| (CAR #2#) |ES-;eval;SLLS;26|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |s| (QREFELT |$| 69)) #1#) |ES-;eval;SLLS;26|))) (LETT #2# (CDR #2#) |ES-;eval;SLLS;26|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |lf| (QREFELT |$| 67))))))
+
+(DEFUN |ES-;map;MKS;27| (|fn| |k| |$|) (PROG (#1=#:G82428 |x| #2=#:G82429 |l|) (RETURN (SEQ (COND ((SPADCALL (LETT |l| (PROGN (LETT #1# NIL |ES-;map;MKS;27|) (SEQ (LETT |x| NIL |ES-;map;MKS;27|) (LETT #2# (SPADCALL |k| (QREFELT |$| 85)) |ES-;map;MKS;27|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |x| (CAR #2#) |ES-;map;MKS;27|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |x| |fn|) #1#) |ES-;map;MKS;27|))) (LETT #2# (CDR #2#) |ES-;map;MKS;27|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |ES-;map;MKS;27|) (SPADCALL |k| (QREFELT |$| 85)) (QREFELT |$| 86)) (SPADCALL |k| (QREFELT |$| 87))) ((QUOTE T) (SPADCALL (SPADCALL |k| (QREFELT |$| 35)) |l| (QREFELT |$| 52))))))))
+
+(DEFUN |ES-;operator;2Bo;28| (|op| |$|) (COND ((SPADCALL |op| (SPADCALL "%paren" (QREFELT |$| 9)) (QREFELT |$| 89)) (QREFELT |$| 13)) ((SPADCALL |op| (SPADCALL "%box" (QREFELT |$| 9)) (QREFELT |$| 89)) (QREFELT |$| 14)) ((QUOTE T) (|error| "Unknown operator"))))
+
+(DEFUN |ES-;mainKernel;SU;29| (|x| |$|) (PROG (|l| |kk| #1=#:G82445 |n| |k|) (RETURN (SEQ (COND ((NULL (LETT |l| (SPADCALL |x| (QREFELT |$| 38)) |ES-;mainKernel;SU;29|)) (CONS 1 "failed")) ((QUOTE T) (SEQ (LETT |n| (SPADCALL (LETT |k| (|SPADfirst| |l|) |ES-;mainKernel;SU;29|) (QREFELT |$| 40)) |ES-;mainKernel;SU;29|) (SEQ (LETT |kk| NIL |ES-;mainKernel;SU;29|) (LETT #1# (CDR |l|) |ES-;mainKernel;SU;29|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |kk| (CAR #1#) |ES-;mainKernel;SU;29|) NIL)) (GO G191))) (SEQ (EXIT (COND ((|<| |n| (SPADCALL |kk| (QREFELT |$| 40))) (SEQ (LETT |n| (SPADCALL |kk| (QREFELT |$| 40)) |ES-;mainKernel;SU;29|) (EXIT (LETT |k| |kk| |ES-;mainKernel;SU;29|))))))) (LETT #1# (CDR #1#) |ES-;mainKernel;SU;29|) (GO G190) G191 (EXIT NIL)) (EXIT (CONS 0 |k|)))))))))
+
+(DEFUN |ES-;allKernels| (|f| |$|) (PROG (|l| |k| #1=#:G82458 |u| |s0| |n| |arg| |t| |s|) (RETURN (SEQ (LETT |s| (SPADCALL (LETT |l| (SPADCALL |f| (QREFELT |$| 38)) |ES-;allKernels|) (QREFELT |$| 29)) |ES-;allKernels|) (SEQ (LETT |k| NIL |ES-;allKernels|) (LETT #1# |l| |ES-;allKernels|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |k| (CAR #1#) |ES-;allKernels|) NIL)) (GO G191))) (SEQ (LETT |t| (SEQ (LETT |u| (SPADCALL (SPADCALL |k| (QREFELT |$| 35)) "%dummyVar" (QREFELT |$| 94)) |ES-;allKernels|) (EXIT (COND ((QEQCAR |u| 0) (SEQ (LETT |arg| (SPADCALL |k| (QREFELT |$| 85)) |ES-;allKernels|) (LETT |s0| (SPADCALL (SPADCALL (SPADCALL |arg| (QREFELT |$| 95)) (QREFELT |$| 56)) (|ES-;allKernels| (|SPADfirst| |arg|) |$|) (QREFELT |$| 96)) |ES-;allKernels|) (LETT |arg| (CDR (CDR |arg|)) |ES-;allKernels|) (LETT |n| (QCDR |u|) |ES-;allKernels|) (COND ((|<| 1 |n|) (LETT |arg| (CDR |arg|) |ES-;allKernels|))) (EXIT (SPADCALL |s0| (|ES-;allk| |arg| |$|) (QREFELT |$| 30))))) ((QUOTE T) (|ES-;allk| (SPADCALL |k| (QREFELT |$| 85)) |$|))))) |ES-;allKernels|) (EXIT (LETT |s| (SPADCALL |s| |t| (QREFELT |$| 30)) |ES-;allKernels|))) (LETT #1# (CDR #1#) |ES-;allKernels|) (GO G190) G191 (EXIT NIL)) (EXIT |s|)))))
+
+(DEFUN |ES-;kernel;BoLS;31| (|op| |args| |$|) (COND ((NULL (SPADCALL |op| (QREFELT |$| 97))) (|error| "Unknown operator")) ((QUOTE T) (|ES-;okkernel| |op| |args| |$|))))
+
+(DEFUN |ES-;okkernel| (|op| |l| |$|) (PROG (#1=#:G82465 |f| #2=#:G82466) (RETURN (SEQ (SPADCALL (SPADCALL |op| |l| (|+| 1 (SPADCALL (ELT |$| 41) (PROGN (LETT #1# NIL |ES-;okkernel|) (SEQ (LETT |f| NIL |ES-;okkernel|) (LETT #2# |l| |ES-;okkernel|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |f| (CAR #2#) |ES-;okkernel|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |f| (QREFELT |$| 99)) #1#) |ES-;okkernel|))) (LETT #2# (CDR #2#) |ES-;okkernel|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) 0 (QREFELT |$| 44))) (QREFELT |$| 100)) (QREFELT |$| 87))))))
+
+(DEFUN |ES-;elt;BoLS;33| (|op| |args| |$|) (PROG (|u| #1=#:G82482 |v|) (RETURN (SEQ (EXIT (COND ((NULL (SPADCALL |op| (QREFELT |$| 97))) (|error| "Unknown operator")) ((QUOTE T) (SEQ (SEQ (LETT |u| (SPADCALL |op| (QREFELT |$| 102)) |ES-;elt;BoLS;33|) (EXIT (COND ((QEQCAR |u| 0) (COND ((NULL (EQL (LENGTH |args|) (QCDR |u|))) (PROGN (LETT #1# (|error| "Wrong number of arguments") |ES-;elt;BoLS;33|) (GO #1#)))))))) (LETT |v| (SPADCALL |op| |args| (QREFELT |$| 105)) |ES-;elt;BoLS;33|) (EXIT (COND ((QEQCAR |v| 0) (QCDR |v|)) ((QUOTE T) (|ES-;okkernel| |op| |args| |$|)))))))) #1# (EXIT #1#)))))
+
+(DEFUN |ES-;retract;SK;34| (|f| |$|) (PROG (|k|) (RETURN (SEQ (LETT |k| (SPADCALL |f| (QREFELT |$| 107)) |ES-;retract;SK;34|) (EXIT (COND ((OR (QEQCAR |k| 1) (NULL (SPADCALL (SPADCALL (QCDR |k|) (QREFELT |$| 87)) |f| (QREFELT |$| 108)))) (|error| "not a kernel")) ((QUOTE T) (QCDR |k|))))))))
+
+(DEFUN |ES-;retractIfCan;SU;35| (|f| |$|) (PROG (|k|) (RETURN (SEQ (LETT |k| (SPADCALL |f| (QREFELT |$| 107)) |ES-;retractIfCan;SU;35|) (EXIT (COND ((OR (QEQCAR |k| 1) (NULL (SPADCALL (SPADCALL (QCDR |k|) (QREFELT |$| 87)) |f| (QREFELT |$| 108)))) (CONS 1 "failed")) ((QUOTE T) |k|)))))))
+
+(DEFUN |ES-;is?;SSB;36| (|f| |s| |$|) (PROG (|k|) (RETURN (SEQ (LETT |k| (SPADCALL |f| (QREFELT |$| 111)) |ES-;is?;SSB;36|) (EXIT (COND ((QEQCAR |k| 1) (QUOTE NIL)) ((QUOTE T) (SPADCALL (QCDR |k|) |s| (QREFELT |$| 112)))))))))
+
+(DEFUN |ES-;is?;SBoB;37| (|f| |op| |$|) (PROG (|k|) (RETURN (SEQ (LETT |k| (SPADCALL |f| (QREFELT |$| 111)) |ES-;is?;SBoB;37|) (EXIT (COND ((QEQCAR |k| 1) (QUOTE NIL)) ((QUOTE T) (SPADCALL (QCDR |k|) |op| (QREFELT |$| 50)))))))))
+
+(DEFUN |ES-;unwrap| (|l| |x| |$|) (PROG (|k| #1=#:G82507) (RETURN (SEQ (SEQ (LETT |k| NIL |ES-;unwrap|) (LETT #1# (NREVERSE |l|) |ES-;unwrap|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |k| (CAR #1#) |ES-;unwrap|) NIL)) (GO G191))) (SEQ (EXIT (LETT |x| (SPADCALL |x| |k| (|SPADfirst| (SPADCALL |k| (QREFELT |$| 85))) (QREFELT |$| 115)) |ES-;unwrap|))) (LETT #1# (CDR #1#) |ES-;unwrap|) (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |ES-;distribute;3S;39| (|x| |y| |$|) (PROG (|ky| #1=#:G82512 |k| #2=#:G82513) (RETURN (SEQ (LETT |ky| (SPADCALL |y| (QREFELT |$| 56)) |ES-;distribute;3S;39|) (EXIT (|ES-;unwrap| (PROGN (LETT #1# NIL |ES-;distribute;3S;39|) (SEQ (LETT |k| NIL |ES-;distribute;3S;39|) (LETT #2# (|ES-;listk| |x| |$|) |ES-;distribute;3S;39|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |k| (CAR #2#) |ES-;distribute;3S;39|) NIL)) (GO G191))) (SEQ (EXIT (COND ((COND ((SPADCALL |k| (SPADCALL "%paren" (QREFELT |$| 9)) (QREFELT |$| 112)) (SPADCALL |ky| (|ES-;listk| (SPADCALL |k| (QREFELT |$| 87)) |$|) (QREFELT |$| 57))) ((QUOTE T) (QUOTE NIL))) (LETT #1# (CONS |k| #1#) |ES-;distribute;3S;39|))))) (LETT #2# (CDR #2#) |ES-;distribute;3S;39|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |x| |$|))))))
+
+(DEFUN |ES-;eval;SLS;40| (|f| |leq| |$|) (PROG (|rec|) (RETURN (SEQ (LETT |rec| (|ES-;mkKerLists| |leq| |$|) |ES-;eval;SLS;40|) (EXIT (SPADCALL |f| (QCAR |rec|) (QCDR |rec|) (QREFELT |$| 117)))))))
+
+(DEFUN |ES-;subst;SLS;41| (|f| |leq| |$|) (PROG (|rec|) (RETURN (SEQ (LETT |rec| (|ES-;mkKerLists| |leq| |$|) |ES-;subst;SLS;41|) (EXIT (SPADCALL |f| (QCAR |rec|) (QCDR |rec|) (QREFELT |$| 119)))))))
+
+(DEFUN |ES-;mkKerLists| (|leq| |$|) (PROG (|eq| #1=#:G82530 |k| |lk| |lv|) (RETURN (SEQ (LETT |lk| NIL |ES-;mkKerLists|) (LETT |lv| NIL |ES-;mkKerLists|) (SEQ (LETT |eq| NIL |ES-;mkKerLists|) (LETT #1# |leq| |ES-;mkKerLists|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |eq| (CAR #1#) |ES-;mkKerLists|) NIL)) (GO G191))) (SEQ (LETT |k| (SPADCALL (SPADCALL |eq| (QREFELT |$| 122)) (QREFELT |$| 111)) |ES-;mkKerLists|) (EXIT (COND ((QEQCAR |k| 1) (|error| "left hand side must be a single kernel")) ((NULL (SPADCALL (QCDR |k|) |lk| (QREFELT |$| 57))) (SEQ (LETT |lk| (CONS (QCDR |k|) |lk|) |ES-;mkKerLists|) (EXIT (LETT |lv| (CONS (SPADCALL |eq| (QREFELT |$| 123)) |lv|) |ES-;mkKerLists|))))))) (LETT #1# (CDR #1#) |ES-;mkKerLists|) (GO G190) G191 (EXIT NIL)) (EXIT (CONS |lk| |lv|))))))
+
+(DEFUN |ES-;even?;SB;43| (|x| |$|) (|ES-;intpred?| |x| (ELT |$| 125) |$|))
+
+(DEFUN |ES-;odd?;SB;44| (|x| |$|) (|ES-;intpred?| |x| (ELT |$| 127) |$|))
+
+(DEFUN |ES-;intpred?| (|x| |pred?| |$|) (PROG (|u|) (RETURN (SEQ (LETT |u| (SPADCALL |x| (QREFELT |$| 130)) |ES-;intpred?|) (EXIT (COND ((QEQCAR |u| 0) (SPADCALL (QCDR |u|) |pred?|)) ((QUOTE T) (QUOTE NIL))))))))
+
+(DEFUN |ExpressionSpace&| (|#1|) (PROG (|DV$1| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|ExpressionSpace&|)) (LETT |dv$| (LIST (QUOTE |ExpressionSpace&|) |DV$1|) . #1#) (LETT |$| (GETREFV 131) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#1| (QUOTE (|RetractableTo| (|Integer|)))) (|HasCategory| |#1| (QUOTE (|Ring|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 13 (SPADCALL (SPADCALL "%paren" (QREFELT |$| 9)) (QREFELT |$| 12))) (QSETREFV |$| 14 (SPADCALL (SPADCALL "%box" (QREFELT |$| 9)) (QREFELT |$| 12))) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 126 (CONS (|dispatchFunction| |ES-;even?;SB;43|) |$|)) (QSETREFV |$| 128 (CONS (|dispatchFunction| |ES-;odd?;SB;44|) |$|))))) |$|))))
+
+(MAKEPROP (QUOTE |ExpressionSpace&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|String|) (|Symbol|) (0 . |coerce|) (|BasicOperator|) (|CommonOperators|) (5 . |operator|) (QUOTE |oppren|) (QUOTE |opbox|) (|List| |$|) (10 . |box|) |ES-;box;2S;1| (15 . |paren|) |ES-;paren;2S;2| (|Boolean|) (20 . |=|) |ES-;belong?;BoB;3| (|List| 34) (|Set| 34) (26 . |parts|) (31 . |sort!|) (|List| 55) |ES-;tower;SL;5| (36 . |brace|) (41 . |union|) (|Mapping| 24 24 24) (|List| 24) (47 . |reduce|) (|Kernel| 6) (54 . |operator|) (|List| 10) |ES-;operators;SL;7| (59 . |kernels|) (|NonNegativeInteger|) (64 . |height|) (69 . |max|) (|Mapping| 39 39 39) (|List| 39) (75 . |reduce|) |ES-;height;SNni;8| (82 . |name|) (|List| 8) (87 . |member?|) |ES-;freeOf?;SSB;9| (93 . |is?|) |ES-;distribute;2S;10| (99 . |elt|) |ES-;box;LS;11| |ES-;paren;LS;12| (|Kernel| |$|) (105 . |retract|) (110 . |member?|) |ES-;freeOf?;2SB;13| (116 . |kernel|) |ES-;kernel;Bo2S;14| |ES-;elt;Bo2S;15| |ES-;elt;Bo3S;16| |ES-;elt;Bo4S;17| |ES-;elt;Bo5S;18| (|Mapping| |$| 15) (|List| 65) (122 . |eval|) |ES-;eval;SSMS;19| (129 . |name|) |ES-;eval;SBoMS;20| (|List| 6) (134 . |first|) (|Mapping| |$| |$|) |ES-;eval;SSMS;21| (139 . |eval|) |ES-;eval;SBoMS;22| (|List| 79) (146 . |subst|) (|Equation| |$|) |ES-;subst;SES;23| (|List| 73) |ES-;eval;SLLS;24| |ES-;eval;SLLS;25| |ES-;eval;SLLS;26| (152 . |argument|) (157 . |=|) (163 . |coerce|) |ES-;map;MKS;27| (168 . |is?|) |ES-;operator;2Bo;28| (|Union| 55 (QUOTE "failed")) |ES-;mainKernel;SU;29| (|Union| (|None|) (QUOTE "failed")) (174 . |property|) (180 . |second|) (185 . |remove!|) (191 . |belong?|) |ES-;kernel;BoLS;31| (196 . |height|) (201 . |kernel|) (|Union| 39 (QUOTE "failed")) (208 . |arity|) (|Union| 6 (QUOTE "failed")) (|BasicOperatorFunctions1| 6) (213 . |evaluate|) |ES-;elt;BoLS;33| (219 . |mainKernel|) (224 . |=|) |ES-;retract;SK;34| |ES-;retractIfCan;SU;35| (230 . |retractIfCan|) (235 . |is?|) |ES-;is?;SSB;36| |ES-;is?;SBoB;37| (241 . |eval|) |ES-;distribute;3S;39| (248 . |eval|) |ES-;eval;SLS;40| (255 . |subst|) |ES-;subst;SLS;41| (|Equation| 6) (262 . |lhs|) (267 . |rhs|) (|Integer|) (272 . |even?|) (277 . |even?|) (282 . |odd?|) (287 . |odd?|) (|Union| 124 (QUOTE "failed")) (292 . |retractIfCan|))) (QUOTE #(|tower| 297 |subst| 302 |retractIfCan| 314 |retract| 319 |paren| 324 |operators| 334 |operator| 339 |odd?| 344 |map| 349 |mainKernel| 355 |kernel| 360 |is?| 372 |height| 384 |freeOf?| 389 |even?| 401 |eval| 406 |elt| 461 |distribute| 497 |box| 508 |belong?| 518)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 130 (QUOTE (1 8 0 7 9 1 11 10 8 12 1 6 0 15 16 1 6 0 15 18 2 10 20 0 0 21 1 24 23 0 25 1 23 0 0 26 1 24 0 23 29 2 24 0 0 0 30 3 32 24 31 0 24 33 1 34 10 0 35 1 6 27 0 38 1 34 39 0 40 2 39 0 0 0 41 3 43 39 42 0 39 44 1 34 8 0 46 2 47 20 8 0 48 2 34 20 0 10 50 2 6 0 10 15 52 1 6 55 0 56 2 23 20 34 0 57 2 6 0 10 15 59 3 6 0 0 47 66 67 1 10 8 0 69 1 71 6 0 72 3 6 0 0 36 66 75 2 6 0 0 77 78 1 34 71 0 85 2 71 20 0 0 86 1 6 0 55 87 2 10 20 0 8 89 2 10 93 0 7 94 1 71 6 0 95 2 24 0 34 0 96 1 6 20 10 97 1 6 39 0 99 3 34 0 10 71 39 100 1 10 101 0 102 2 104 103 10 71 105 1 6 91 0 107 2 6 20 0 0 108 1 6 91 0 111 2 34 20 0 8 112 3 6 0 0 55 0 115 3 6 0 0 27 15 117 3 6 0 0 27 15 119 1 121 6 0 122 1 121 6 0 123 1 124 20 0 125 1 0 20 0 126 1 124 20 0 127 1 0 20 0 128 1 6 129 0 130 1 0 27 0 28 2 0 0 0 77 120 2 0 0 0 79 80 1 0 91 0 110 1 0 55 0 109 1 0 0 0 19 1 0 0 15 54 1 0 36 0 37 1 0 10 10 90 1 0 20 0 128 2 0 0 73 55 88 1 0 91 0 92 2 0 0 10 15 98 2 0 0 10 0 60 2 0 20 0 8 113 2 0 20 0 10 114 1 0 39 0 45 2 0 20 0 8 49 2 0 20 0 0 58 1 0 20 0 126 3 0 0 0 10 73 76 3 0 0 0 36 66 84 3 0 0 0 10 65 70 3 0 0 0 36 81 82 3 0 0 0 8 65 68 3 0 0 0 8 73 74 3 0 0 0 47 81 83 2 0 0 0 77 118 2 0 0 10 15 106 5 0 0 10 0 0 0 0 64 3 0 0 10 0 0 62 4 0 0 10 0 0 0 63 2 0 0 10 0 61 2 0 0 0 0 116 1 0 0 0 51 1 0 0 15 53 1 0 0 0 17 1 0 20 10 22)))))) (QUOTE |lookupComplete|)))
+@
+\section{package ES1 ExpressionSpaceFunctions1}
+<<package ES1 ExpressionSpaceFunctions1>>=
+)abbrev package ES1 ExpressionSpaceFunctions1
+++ Lifting of maps from expression spaces to kernels over them
+++ Author: Manuel Bronstein
+++ Date Created: 23 March 1988
+++ Date Last Updated: 19 April 1991
+++ Description:
+++ This package allows a map from any expression space into any object
+++ to be lifted to a kernel over the expression set, using a given
+++ property of the operator of the kernel.
+-- should not be exposed
+ExpressionSpaceFunctions1(F:ExpressionSpace, S:Type): with
+ map: (F -> S, String, Kernel F) -> S
+ ++ map(f, p, k) uses the property p of the operator
+ ++ of k, in order to lift f and apply it to k.
+
+ == add
+ -- prop contains an evaluation function List S -> S
+ map(F2S, prop, k) ==
+ args := [F2S x for x in argument k]$List(S)
+ (p := property(operator k, prop)) case None =>
+ ((p::None) pretend (List S -> S)) args
+ error "Operator does not have required property"
+
+@
+\section{package ES2 ExpressionSpaceFunctions2}
+<<package ES2 ExpressionSpaceFunctions2>>=
+)abbrev package ES2 ExpressionSpaceFunctions2
+++ Lifting of maps from expression spaces to kernels over them
+++ Author: Manuel Bronstein
+++ Date Created: 23 March 1988
+++ Date Last Updated: 19 April 1991
+++ Description:
+++ This package allows a mapping E -> F to be lifted to a kernel over E;
+++ This lifting can fail if the operator of the kernel cannot be applied
+++ in F; Do not use this package with E = F, since this may
+++ drop some properties of the operators.
+ExpressionSpaceFunctions2(E:ExpressionSpace, F:ExpressionSpace): with
+ map: (E -> F, Kernel E) -> F
+ ++ map(f, k) returns \spad{g = op(f(a1),...,f(an))} where
+ ++ \spad{k = op(a1,...,an)}.
+ == add
+ map(f, k) ==
+ (operator(operator k)$F) [f x for x in argument k]$List(F)
+
+@
+\section{category FS FunctionSpace}
+<<category FS FunctionSpace>>=
+)abbrev category FS FunctionSpace
+++ Category for formal functions
+++ Author: Manuel Bronstein
+++ Date Created: 22 March 1988
+++ Date Last Updated: 14 February 1994
+++ Description:
+++ A space of formal functions with arguments in an arbitrary
+++ ordered set.
+++ Keywords: operator, kernel, function.
+FunctionSpace(R:OrderedSet): Category == Definition where
+ OP ==> BasicOperator
+ O ==> OutputForm
+ SY ==> Symbol
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ K ==> Kernel %
+ Q ==> Fraction R
+ PR ==> Polynomial R
+ MP ==> SparseMultivariatePolynomial(R, K)
+ QF==> PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,MP,%)
+
+ ODD ==> "odd"
+ EVEN ==> "even"
+
+ SPECIALDIFF ==> "%specialDiff"
+ SPECIALDISP ==> "%specialDisp"
+ SPECIALEQUAL ==> "%specialEqual"
+ SPECIALINPUT ==> "%specialInput"
+
+ Definition ==> Join(ExpressionSpace, RetractableTo SY, Patternable R,
+ FullyPatternMatchable R, FullyRetractableTo R) with
+ ground? : % -> Boolean
+ ++ ground?(f) tests if f is an element of R.
+ ground : % -> R
+ ++ ground(f) returns f as an element of R.
+ ++ An error occurs if f is not an element of R.
+ variables : % -> List SY
+ ++ variables(f) returns the list of all the variables of f.
+ applyQuote: (SY, %) -> %
+ ++ applyQuote(foo, x) returns \spad{'foo(x)}.
+ applyQuote: (SY, %, %) -> %
+ ++ applyQuote(foo, x, y) returns \spad{'foo(x,y)}.
+ applyQuote: (SY, %, %, %) -> %
+ ++ applyQuote(foo, x, y, z) returns \spad{'foo(x,y,z)}.
+ applyQuote: (SY, %, %, %, %) -> %
+ ++ applyQuote(foo, x, y, z, t) returns \spad{'foo(x,y,z,t)}.
+ applyQuote: (SY, List %) -> %
+ ++ applyQuote(foo, [x1,...,xn]) returns \spad{'foo(x1,...,xn)}.
+ if R has ConvertibleTo InputForm then
+ ConvertibleTo InputForm
+ eval : (%, SY) -> %
+ ++ eval(f, foo) unquotes all the foo's in f.
+ eval : (%, List SY) -> %
+ ++ eval(f, [foo1,...,foon]) unquotes all the \spad{fooi}'s in f.
+ eval : % -> %
+ ++ eval(f) unquotes all the quoted operators in f.
+ eval : (%, OP, %, SY) -> %
+ ++ eval(x, s, f, y) replaces every \spad{s(a)} in x by \spad{f(y)}
+ ++ with \spad{y} replaced by \spad{a} for any \spad{a}.
+ eval : (%, List OP, List %, SY) -> %
+ ++ eval(x, [s1,...,sm], [f1,...,fm], y) replaces every
+ ++ \spad{si(a)} in x by \spad{fi(y)}
+ ++ with \spad{y} replaced by \spad{a} for any \spad{a}.
+ if R has SemiGroup then
+ Monoid
+ -- the following line is necessary because of a compiler bug
+ "**" : (%, N) -> %
+ ++ x**n returns x * x * x * ... * x (n times).
+ isTimes: % -> Union(List %, "failed")
+ ++ isTimes(p) returns \spad{[a1,...,an]}
+ ++ if \spad{p = a1*...*an} and \spad{n > 1}.
+ isExpt : % -> Union(Record(var:K,exponent:Z),"failed")
+ ++ isExpt(p) returns \spad{[x, n]} if \spad{p = x**n}
+ ++ and \spad{n <> 0}.
+ if R has Group then Group
+ if R has AbelianSemiGroup then
+ AbelianMonoid
+ isPlus: % -> Union(List %, "failed")
+ ++ isPlus(p) returns \spad{[m1,...,mn]}
+ ++ if \spad{p = m1 +...+ mn} and \spad{n > 1}.
+ isMult: % -> Union(Record(coef:Z, var:K),"failed")
+ ++ isMult(p) returns \spad{[n, x]} if \spad{p = n * x}
+ ++ and \spad{n <> 0}.
+ if R has AbelianGroup then AbelianGroup
+ if R has Ring then
+ Ring
+ RetractableTo PR
+ PartialDifferentialRing SY
+ FullyLinearlyExplicitRingOver R
+ coerce : MP -> %
+ ++ coerce(p) returns p as an element of %.
+ numer : % -> MP
+ ++ numer(f) returns the
+ ++ numerator of f viewed as a polynomial in the kernels over R
+ ++ if R is an integral domain. If not, then numer(f) = f viewed
+ ++ as a polynomial in the kernels over R.
+ -- DO NOT change this meaning of numer! MB 1/90
+ numerator : % -> %
+ ++ numerator(f) returns the numerator of \spad{f} converted to %.
+ isExpt:(%,OP) -> Union(Record(var:K,exponent:Z),"failed")
+ ++ isExpt(p,op) returns \spad{[x, n]} if \spad{p = x**n}
+ ++ and \spad{n <> 0} and \spad{x = op(a)}.
+ isExpt:(%,SY) -> Union(Record(var:K,exponent:Z),"failed")
+ ++ isExpt(p,f) returns \spad{[x, n]} if \spad{p = x**n}
+ ++ and \spad{n <> 0} and \spad{x = f(a)}.
+ isPower : % -> Union(Record(val:%,exponent:Z),"failed")
+ ++ isPower(p) returns \spad{[x, n]} if \spad{p = x**n}
+ ++ and \spad{n <> 0}.
+ eval: (%, List SY, List N, List(% -> %)) -> %
+ ++ eval(x, [s1,...,sm], [n1,...,nm], [f1,...,fm]) replaces
+ ++ every \spad{si(a)**ni} in x by \spad{fi(a)} for any \spad{a}.
+ eval: (%, List SY, List N, List(List % -> %)) -> %
+ ++ eval(x, [s1,...,sm], [n1,...,nm], [f1,...,fm]) replaces
+ ++ every \spad{si(a1,...,an)**ni} in x by \spad{fi(a1,...,an)}
+ ++ for any a1,...,am.
+ eval: (%, SY, N, List % -> %) -> %
+ ++ eval(x, s, n, f) replaces every \spad{s(a1,...,am)**n} in x
+ ++ by \spad{f(a1,...,am)} for any a1,...,am.
+ eval: (%, SY, N, % -> %) -> %
+ ++ eval(x, s, n, f) replaces every \spad{s(a)**n} in x
+ ++ by \spad{f(a)} for any \spad{a}.
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has CommutativeRing then
+ Algebra R
+ if R has IntegralDomain then
+ Field
+ RetractableTo Fraction PR
+ convert : Factored % -> %
+ ++ convert(f1\^e1 ... fm\^em) returns \spad{(f1)\^e1 ... (fm)\^em}
+ ++ as an element of %, using formal kernels
+ ++ created using a \spadfunFrom{paren}{ExpressionSpace}.
+ denom : % -> MP
+ ++ denom(f) returns the denominator of f viewed as a
+ ++ polynomial in the kernels over R.
+ denominator : % -> %
+ ++ denominator(f) returns the denominator of \spad{f} converted to %.
+ "/" : (MP, MP) -> %
+ ++ p1/p2 returns the quotient of p1 and p2 as an element of %.
+ coerce : Q -> %
+ ++ coerce(q) returns q as an element of %.
+ coerce : Polynomial Q -> %
+ ++ coerce(p) returns p as an element of %.
+ coerce : Fraction Polynomial Q -> %
+ ++ coerce(f) returns f as an element of %.
+ univariate: (%, K) -> Fraction SparseUnivariatePolynomial %
+ ++ univariate(f, k) returns f viewed as a univariate fraction in k.
+ if R has RetractableTo Z then RetractableTo Fraction Z
+ add
+ import BasicOperatorFunctions1(%)
+
+ -- these are needed in Ring only, but need to be declared here
+ -- because of compiler bug: if they are declared inside the Ring
+ -- case, then they are not visible inside the IntegralDomain case.
+ smpIsMult : MP -> Union(Record(coef:Z, var:K),"failed")
+ smpret : MP -> Union(PR, "failed")
+ smpeval : (MP, List K, List %) -> %
+ smpsubst : (MP, List K, List %) -> %
+ smpderiv : (MP, SY) -> %
+ smpunq : (MP, List SY, Boolean) -> %
+ kerderiv : (K, SY) -> %
+ kderiv : K -> List %
+ opderiv : (OP, N) -> List(List % -> %)
+ smp2O : MP -> O
+ bestKernel: List K -> K
+ worse? : (K, K) -> Boolean
+ diffArg : (List %, OP, N) -> List %
+ substArg : (OP, List %, Z, %) -> %
+ dispdiff : List % -> Record(name:O, sub:O, arg:List O, level:N)
+ ddiff : List % -> O
+ diffEval : List % -> %
+ dfeval : (List %, K) -> %
+ smprep : (List SY, List N, List(List % -> %), MP) -> %
+ diffdiff : (List %, SY) -> %
+ diffdiff0 : (List %, SY, %, K, List %) -> %
+ subs : (% -> %, K) -> %
+ symsub : (SY, Z) -> SY
+ kunq : (K, List SY, Boolean) -> %
+ pushunq : (List SY, List %) -> List %
+ notfound : (K -> %, List K, K) -> %
+
+ equaldiff : (K,K)->Boolean
+ debugA: (List % ,List %,Boolean) -> Boolean
+ opdiff := operator("%diff"::SY)$CommonOperators()
+ opquote := operator("applyQuote"::SY)$CommonOperators
+
+ ground? x == retractIfCan(x)@Union(R,"failed") case R
+ ground x == retract x
+ coerce(x:SY):% == kernel(x)@K :: %
+ retract(x:%):SY == symbolIfCan(retract(x)@K)::SY
+ applyQuote(s:SY, x:%) == applyQuote(s, [x])
+ applyQuote(s, x, y) == applyQuote(s, [x, y])
+ applyQuote(s, x, y, z) == applyQuote(s, [x, y, z])
+ applyQuote(s, x, y, z, t) == applyQuote(s, [x, y, z, t])
+ applyQuote(s:SY, l:List %) == opquote concat(s::%, l)
+ belong? op == op = opdiff or op = opquote
+ subs(fn, k) == kernel(operator k,[fn x for x in argument k]$List(%))
+
+ operator op ==
+ is?(op, "%diff"::SY) => opdiff
+ is?(op, "%quote"::SY) => opquote
+ error "Unknown operator"
+
+ if R has ConvertibleTo InputForm then
+ INP==>InputForm
+ import MakeUnaryCompiledFunction(%, %, %)
+ indiff: List % -> INP
+ pint : List INP-> INP
+ differentiand: List % -> %
+
+ differentiand l == eval(first l, retract(second l)@K, third l)
+ pint l == convert concat(convert("D"::SY)@INP, l)
+ indiff l ==
+ r2:= convert([convert("::"::SY)@INP,convert(third l)@INP,convert("Symbol"::SY)@INP]@List INP)@INP
+ pint [convert(differentiand l)@INP, r2]
+ eval(f:%, s:SY) == eval(f, [s])
+ eval(f:%, s:OP, g:%, x:SY) == eval(f, [s], [g], x)
+
+ eval(f:%, ls:List OP, lg:List %, x:SY) ==
+ eval(f, ls, [compiledFunction(g, x) for g in lg])
+
+ setProperty(opdiff,SPECIALINPUT,indiff@(List % -> InputForm) pretend None)
+
+ variables x ==
+ l := empty()$List(SY)
+ for k in tower x repeat
+ if ((s := symbolIfCan k) case SY) then l := concat(s::SY, l)
+ reverse_! l
+
+ retractIfCan(x:%):Union(SY, "failed") ==
+ (k := retractIfCan(x)@Union(K,"failed")) case "failed" => "failed"
+ symbolIfCan(k::K)
+
+ if R has Ring then
+ import UserDefinedPartialOrdering(SY)
+
+-- cannot use new()$Symbol because of possible re-instantiation
+ gendiff := "%%0"::SY
+
+ characteristic() == characteristic()$R
+ coerce(k:K):% == k::MP::%
+ symsub(sy, i) == concat(string sy, convert(i)@String)::SY
+ numerator x == numer(x)::%
+ eval(x:%, s:SY, n:N, f:% -> %) == eval(x,[s],[n],[f first #1])
+ eval(x:%, s:SY, n:N, f:List % -> %) == eval(x, [s], [n], [f])
+ eval(x:%, l:List SY, f:List(List % -> %)) == eval(x, l, new(#l, 1), f)
+
+ elt(op:OP, args:List %) ==
+ unary? op and ((od? := has?(op, ODD)) or has?(op, EVEN)) and
+ leadingCoefficient(numer first args) < 0 =>
+ x := op(- first args)
+ od? => -x
+ x
+ elt(op, args)$ExpressionSpace_&(%)
+
+ eval(x:%, s:List SY, n:List N, l:List(% -> %)) ==
+ eval(x, s, n, [f first #1 for f in l]$List(List % -> %))
+
+ -- op(arg)**m ==> func(arg)**(m quo n) * op(arg)**(m rem n)
+ smprep(lop, lexp, lfunc, p) ==
+ (v := mainVariable p) case "failed" => p::%
+ symbolIfCan(k := v::K) case SY => p::%
+ g := (op := operator k)
+ (arg := [eval(a,lop,lexp,lfunc) for a in argument k]$List(%))
+ q := map(eval(#1::%, lop, lexp, lfunc),
+ univariate(p, k))$SparseUnivariatePolynomialFunctions2(MP, %)
+ (n := position(name op, lop)) < minIndex lop => q g
+ a:% := 0
+ f := eval((lfunc.n) arg, lop, lexp, lfunc)
+ e := lexp.n
+ while q ^= 0 repeat
+ m := degree q
+ qr := divide(m, e)
+ t1 := f ** (qr.quotient)::N
+ t2 := g ** (qr.remainder)::N
+ a := a + leadingCoefficient(q) * t1 * t2
+ q := reductum q
+ a
+
+ dispdiff l ==
+ s := second(l)::O
+ t := third(l)::O
+ a := argument(k := retract(first l)@K)
+ is?(k, opdiff) =>
+ rec := dispdiff a
+ i := position(s, rec.arg)
+ rec.arg.i := t
+ [rec.name,
+ hconcat(rec.sub, hconcat(","::SY::O, (i+1-minIndex a)::O)),
+ rec.arg, (zero?(rec.level) => 0; rec.level + 1)]
+ i := position(second l, a)
+ m := [x::O for x in a]$List(O)
+ m.i := t
+ [name(operator k)::O, hconcat(","::SY::O, (i+1-minIndex a)::O),
+ m, (empty? rest a => 1; 0)]
+
+ ddiff l ==
+ rec := dispdiff l
+ opname :=
+ zero?(rec.level) => sub(rec.name, rec.sub)
+ differentiate(rec.name, rec.level)
+ prefix(opname, rec.arg)
+
+ substArg(op, l, i, g) ==
+ z := copy l
+ z.i := g
+ kernel(op, z)
+
+
+ diffdiff(l, x) ==
+ f := kernel(opdiff, l)
+ diffdiff0(l, x, f, retract(f)@K, empty())
+
+ diffdiff0(l, x, expr, kd, done) ==
+ op := operator(k := retract(first l)@K)
+ gg := second l
+ u := third l
+ arg := argument k
+ ans:% := 0
+ if (not member?(u,done)) and (ans := differentiate(u,x))^=0 then
+ ans := ans * kernel(opdiff,
+ [subst(expr, [kd], [kernel(opdiff, [first l, gg, gg])]),
+ gg, u])
+ done := concat(gg, done)
+ is?(k, opdiff) => ans + diffdiff0(arg, x, expr, k, done)
+ for i in minIndex arg .. maxIndex arg for b in arg repeat
+ if (not member?(b,done)) and (bp:=differentiate(b,x))^=0 then
+ g := symsub(gendiff, i)::%
+ ans := ans + bp * kernel(opdiff, [subst(expr, [kd],
+ [kernel(opdiff, [substArg(op, arg, i, g), gg, u])]), g, b])
+ ans
+
+ dfeval(l, g) ==
+ eval(differentiate(first l, symbolIfCan(g)::SY), g, third l)
+
+ diffEval l ==
+ k:K
+ g := retract(second l)@K
+ ((u := retractIfCan(first l)@Union(K, "failed")) case "failed")
+ or (u case K and symbolIfCan(k := u::K) case SY) => dfeval(l, g)
+ op := operator k
+ (ud := derivative op) case "failed" =>
+ -- possible trouble
+ -- make sure it is a dummy var
+ dumm:%:=symsub(gendiff,1)::%
+ ss:=subst(l.1,l.2=dumm)
+ -- output(nl::OutputForm)$OutputPackage
+ -- output("fixed"::OutputForm)$OutputPackage
+ nl:=[ss,dumm,l.3]
+ kernel(opdiff, nl)
+ (n := position(second l,argument k)) < minIndex l =>
+ dfeval(l,g)
+ d := ud::List(List % -> %)
+ eval((d.n)(argument k), g, third l)
+
+ diffArg(l, op, i) ==
+ n := i - 1 + minIndex l
+ z := copy l
+ z.n := g := symsub(gendiff, n)::%
+ [kernel(op, z), g, l.n]
+
+ opderiv(op, n) ==
+-- one? n =>
+ (n = 1) =>
+ g := symsub(gendiff, n)::%
+ [kernel(opdiff,[kernel(op, g), g, first #1])]
+ [kernel(opdiff, diffArg(#1, op, i)) for i in 1..n]
+
+ kderiv k ==
+ zero?(n := #(args := argument k)) => empty()
+ op := operator k
+ grad :=
+ (u := derivative op) case "failed" => opderiv(op, n)
+ u::List(List % -> %)
+ if #grad ^= n then grad := opderiv(op, n)
+ [g args for g in grad]
+
+ -- SPECIALDIFF contains a map (List %, Symbol) -> %
+ -- it is used when the usual chain rule does not apply,
+ -- for instance with implicit algebraics.
+ kerderiv(k, x) ==
+ (v := symbolIfCan(k)) case SY =>
+ v::SY = x => 1
+ 0
+ (fn := property(operator k, SPECIALDIFF)) case None =>
+ ((fn::None) pretend ((List %, SY) -> %)) (argument k, x)
+ +/[g * differentiate(y,x) for g in kderiv k for y in argument k]
+
+ smpderiv(p, x) ==
+ map(retract differentiate(#1::PR, x), p)::% +
+ +/[differentiate(p,k)::% * kerderiv(k, x) for k in variables p]
+
+ coerce(p:PR):% ==
+ map(#1::%, #1::%, p)$PolynomialCategoryLifting(
+ IndexedExponents SY, SY, R, PR, %)
+
+ worse?(k1, k2) ==
+ (u := less?(name operator k1,name operator k2)) case "failed" =>
+ k1 < k2
+ u::Boolean
+
+ bestKernel l ==
+ empty? rest l => first l
+ a := bestKernel rest l
+ worse?(first l, a) => a
+ first l
+
+ smp2O p ==
+ (r:=retractIfCan(p)@Union(R,"failed")) case R =>r::R::OutputForm
+ a :=
+ userOrdered?() => bestKernel variables p
+ mainVariable(p)::K
+ outputForm(map(#1::%, univariate(p,
+ a))$SparseUnivariatePolynomialFunctions2(MP, %), a::OutputForm)
+
+ smpsubst(p, lk, lv) ==
+ map(match(lk, lv, #1,
+ notfound(subs(subst(#1, lk, lv), #1), lk, #1))$ListToMap(K,%),
+ #1::%,p)$PolynomialCategoryLifting(IndexedExponents K,K,R,MP,%)
+
+ smpeval(p, lk, lv) ==
+ map(match(lk, lv, #1,
+ notfound(map(eval(#1, lk, lv), #1), lk, #1))$ListToMap(K,%),
+ #1::%,p)$PolynomialCategoryLifting(IndexedExponents K,K,R,MP,%)
+
+-- this is called on k when k is not a member of lk
+ notfound(fn, lk, k) ==
+ empty? setIntersection(tower(f := k::%), lk) => f
+ fn k
+
+ if R has ConvertibleTo InputForm then
+ pushunq(l, arg) ==
+ empty? l => [eval a for a in arg]
+ [eval(a, l) for a in arg]
+
+ kunq(k, l, givenlist?) ==
+ givenlist? and empty? l => k::%
+ is?(k, opquote) and
+ (member?(s:=retract(first argument k)@SY, l) or empty? l) =>
+ interpret(convert(concat(convert(s)@InputForm,
+ [convert a for a in pushunq(l, rest argument k)
+ ]@List(InputForm)))@InputForm)$InputFormFunctions1(%)
+ (operator k) pushunq(l, argument k)
+
+ smpunq(p, l, givenlist?) ==
+ givenlist? and empty? l => p::%
+ map(kunq(#1, l, givenlist?), #1::%,
+ p)$PolynomialCategoryLifting(IndexedExponents K,K,R,MP,%)
+
+ smpret p ==
+ "or"/[symbolIfCan(k) case "failed" for k in variables p] =>
+ "failed"
+ map(symbolIfCan(#1)::SY::PR, #1::PR,
+ p)$PolynomialCategoryLifting(IndexedExponents K, K, R, MP, PR)
+
+ isExpt(x:%, op:OP) ==
+ (u := isExpt x) case "failed" => "failed"
+ is?((u::Record(var:K, exponent:Z)).var, op) => u
+ "failed"
+
+ isExpt(x:%, sy:SY) ==
+ (u := isExpt x) case "failed" => "failed"
+ is?((u::Record(var:K, exponent:Z)).var, sy) => u
+ "failed"
+
+ if R has RetractableTo Z then
+ smpIsMult p ==
+-- (u := mainVariable p) case K and one? degree(q:=univariate(p,u::K))
+ (u := mainVariable p) case K and (degree(q:=univariate(p,u::K))=1)
+ and zero?(leadingCoefficient reductum q)
+ and ((r:=retractIfCan(leadingCoefficient q)@Union(R,"failed"))
+ case R)
+ and (n := retractIfCan(r::R)@Union(Z, "failed")) case Z =>
+ [n::Z, u::K]
+ "failed"
+
+ evaluate(opdiff, diffEval)
+
+ debugA(a1,a2,t) ==
+ -- uncomment for debugging
+ -- output(hconcat [a1::OutputForm,a2::OutputForm,t::OutputForm])$OutputPackage
+ t
+
+ equaldiff(k1,k2) ==
+ a1:=argument k1
+ a2:=argument k2
+ -- check the operator
+ res:=operator k1 = operator k2
+ not res => debugA(a1,a2,res)
+ -- check the evaluation point
+ res:= (a1.3 = a2.3)
+ not res => debugA(a1,a2,res)
+ -- check all the arguments
+ res:= (a1.1 = a2.1) and (a1.2 = a2.2)
+ res => debugA(a1,a2,res)
+ -- check the substituted arguments
+ (subst(a1.1,[retract(a1.2)@K],[a2.2]) = a2.1) => debugA(a1,a2,true)
+ debugA(a1,a2,false)
+ setProperty(opdiff,SPECIALEQUAL,
+ equaldiff@((K,K) -> Boolean) pretend None)
+ setProperty(opdiff, SPECIALDIFF,
+ diffdiff@((List %, SY) -> %) pretend None)
+ setProperty(opdiff, SPECIALDISP,
+ ddiff@(List % -> OutputForm) pretend None)
+
+ if not(R has IntegralDomain) then
+ mainKernel x == mainVariable numer x
+ kernels x == variables numer x
+ retract(x:%):R == retract numer x
+ retract(x:%):PR == smpret(numer x)::PR
+ retractIfCan(x:%):Union(R, "failed") == retract numer x
+ retractIfCan(x:%):Union(PR, "failed") == smpret numer x
+ eval(x:%, lk:List K, lv:List %) == smpeval(numer x, lk, lv)
+ subst(x:%, lk:List K, lv:List %) == smpsubst(numer x, lk, lv)
+ differentiate(x:%, s:SY) == smpderiv(numer x, s)
+ coerce(x:%):OutputForm == smp2O numer x
+
+ if R has ConvertibleTo InputForm then
+ eval(f:%, l:List SY) == smpunq(numer f, l, true)
+ eval f == smpunq(numer f, empty(), false)
+
+ eval(x:%, s:List SY, n:List N, f:List(List % -> %)) ==
+ smprep(s, n, f, numer x)
+
+ isPlus x ==
+ (u := isPlus numer x) case "failed" => "failed"
+ [p::% for p in u::List(MP)]
+
+ isTimes x ==
+ (u := isTimes numer x) case "failed" => "failed"
+ [p::% for p in u::List(MP)]
+
+ isExpt x ==
+ (u := isExpt numer x) case "failed" => "failed"
+ r := u::Record(var:K, exponent:NonNegativeInteger)
+ [r.var, r.exponent::Z]
+
+ isPower x ==
+ (u := isExpt numer x) case "failed" => "failed"
+ r := u::Record(var:K, exponent:NonNegativeInteger)
+ [r.var::%, r.exponent::Z]
+
+ if R has ConvertibleTo Pattern Z then
+ convert(x:%):Pattern(Z) == convert numer x
+
+ if R has ConvertibleTo Pattern Float then
+ convert(x:%):Pattern(Float) == convert numer x
+
+ if R has RetractableTo Z then
+ isMult x == smpIsMult numer x
+
+ if R has CommutativeRing then
+ r:R * x:% == r::MP::% * x
+
+ if R has IntegralDomain then
+ par : % -> %
+
+ mainKernel x == mainVariable(x)$QF
+ kernels x == variables(x)$QF
+ univariate(x:%, k:K) == univariate(x, k)$QF
+ isPlus x == isPlus(x)$QF
+ isTimes x == isTimes(x)$QF
+ isExpt x == isExpt(x)$QF
+ isPower x == isPower(x)$QF
+ denominator x == denom(x)::%
+ coerce(q:Q):% == (numer q)::MP / (denom q)::MP
+ coerce(q:Fraction PR):% == (numer q)::% / (denom q)::%
+ coerce(q:Fraction Polynomial Q) == (numer q)::% / (denom q)::%
+ retract(x:%):PR == retract(retract(x)@Fraction(PR))
+ retract(x:%):Fraction(PR) == smpret(numer x)::PR / smpret(denom x)::PR
+ retract(x:%):R == (retract(numer x)@R exquo retract(denom x)@R)::R
+
+ coerce(x:%):OutputForm ==
+-- one?(denom x) => smp2O numer x
+ ((denom x) = 1) => smp2O numer x
+ smp2O(numer x) / smp2O(denom x)
+
+ retractIfCan(x:%):Union(R, "failed") ==
+ (n := retractIfCan(numer x)@Union(R, "failed")) case "failed" or
+ (d := retractIfCan(denom x)@Union(R, "failed")) case "failed"
+ or (r := n::R exquo d::R) case "failed" => "failed"
+ r::R
+
+ eval(f:%, l:List SY) ==
+ smpunq(numer f, l, true) / smpunq(denom f, l, true)
+
+ if R has ConvertibleTo InputForm then
+ eval f ==
+ smpunq(numer f, empty(), false) / smpunq(denom f, empty(), false)
+
+ eval(x:%, s:List SY, n:List N, f:List(List % -> %)) ==
+ smprep(s, n, f, numer x) / smprep(s, n, f, denom x)
+
+ differentiate(f:%, x:SY) ==
+ (smpderiv(numer f, x) * denom(f)::% -
+ numer(f)::% * smpderiv(denom f, x))
+ / (denom(f)::% ** 2)
+
+ eval(x:%, lk:List K, lv:List %) ==
+ smpeval(numer x, lk, lv) / smpeval(denom x, lk, lv)
+
+ subst(x:%, lk:List K, lv:List %) ==
+ smpsubst(numer x, lk, lv) / smpsubst(denom x, lk, lv)
+
+ par x ==
+ (r := retractIfCan(x)@Union(R, "failed")) case R => x
+ paren x
+
+ convert(x:Factored %):% ==
+ par(unit x) * */[par(f.factor) ** f.exponent for f in factors x]
+
+ retractIfCan(x:%):Union(PR, "failed") ==
+ (u := retractIfCan(x)@Union(Fraction PR,"failed")) case "failed"
+ => "failed"
+ retractIfCan(u::Fraction(PR))
+
+ retractIfCan(x:%):Union(Fraction PR, "failed") ==
+ (n := smpret numer x) case "failed" => "failed"
+ (d := smpret denom x) case "failed" => "failed"
+ n::PR / d::PR
+
+ coerce(p:Polynomial Q):% ==
+ map(#1::%, #1::%,
+ p)$PolynomialCategoryLifting(IndexedExponents SY, SY,
+ Q, Polynomial Q, %)
+
+ if R has RetractableTo Z then
+ coerce(x:Fraction Z):% == numer(x)::MP / denom(x)::MP
+
+ isMult x ==
+ (u := smpIsMult numer x) case "failed"
+ or (v := retractIfCan(denom x)@Union(R, "failed")) case "failed"
+ or (w := retractIfCan(v::R)@Union(Z, "failed")) case "failed"
+ => "failed"
+ r := u::Record(coef:Z, var:K)
+ (q := r.coef exquo w::Z) case "failed" => "failed"
+ [q::Z, r.var]
+
+ if R has ConvertibleTo Pattern Z then
+ convert(x:%):Pattern(Z) == convert(numer x) / convert(denom x)
+
+ if R has ConvertibleTo Pattern Float then
+ convert(x:%):Pattern(Float) ==
+ convert(numer x) / convert(denom x)
+
+@
+\section{package FS2 FunctionSpaceFunctions2}
+<<package FS2 FunctionSpaceFunctions2>>=
+)abbrev package FS2 FunctionSpaceFunctions2
+++ Lifting of maps to function spaces
+++ Author: Manuel Bronstein
+++ Date Created: 22 March 1988
+++ Date Last Updated: 3 May 1994
+++ Description:
+++ This package allows a mapping R -> S to be lifted to a mapping
+++ from a function space over R to a function space over S;
+FunctionSpaceFunctions2(R, A, S, B): Exports == Implementation where
+ R, S: Join(Ring, OrderedSet)
+ A : FunctionSpace R
+ B : FunctionSpace S
+
+ K ==> Kernel A
+ P ==> SparseMultivariatePolynomial(R, K)
+
+ Exports ==> with
+ map: (R -> S, A) -> B
+ ++ map(f, a) applies f to all the constants in R appearing in \spad{a}.
+
+ Implementation ==> add
+ smpmap: (R -> S, P) -> B
+
+ smpmap(fn, p) ==
+ map(map(map(fn, #1), #1)$ExpressionSpaceFunctions2(A,B),fn(#1)::B,
+ p)$PolynomialCategoryLifting(IndexedExponents K, K, R, P, B)
+
+ if R has IntegralDomain then
+ if S has IntegralDomain then
+ map(f, x) == smpmap(f, numer x) / smpmap(f, denom x)
+ else
+ map(f, x) == smpmap(f, numer x) * (recip(smpmap(f, denom x))::B)
+ else
+ map(f, x) == smpmap(f, numer x)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl FSPACE expr funcpkgs
+
+<<category ES ExpressionSpace>>
+<<package ES1 ExpressionSpaceFunctions1>>
+<<package ES2 ExpressionSpaceFunctions2>>
+<<category FS FunctionSpace>>
+<<package FS2 FunctionSpaceFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/funcpkgs.spad.pamphlet b/src/algebra/funcpkgs.spad.pamphlet
new file mode 100644
index 00000000..41f979ef
--- /dev/null
+++ b/src/algebra/funcpkgs.spad.pamphlet
@@ -0,0 +1,193 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra funcpkgs.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FSUPFACT FunctionSpaceUnivariatePolynomialFactor}
+<<package FSUPFACT FunctionSpaceUnivariatePolynomialFactor>>=
+)abbrev package FSUPFACT FunctionSpaceUnivariatePolynomialFactor
+++ Used internally by IR2F
+++ Author: Manuel Bronstein
+++ Date Created: 12 May 1988
+++ Date Last Updated: 22 September 1993
+++ Keywords: function, space, polynomial, factoring
+FunctionSpaceUnivariatePolynomialFactor(R, F, UP):
+ Exports == Implementation where
+ R : Join(IntegralDomain, OrderedSet, RetractableTo Integer)
+ F : FunctionSpace R
+ UP: UnivariatePolynomialCategory F
+
+ Q ==> Fraction Integer
+ K ==> Kernel F
+ AN ==> AlgebraicNumber
+ PQ ==> SparseMultivariatePolynomial(Q, K)
+ PR ==> SparseMultivariatePolynomial(R, K)
+ UPQ ==> SparseUnivariatePolynomial Q
+ UPA ==> SparseUnivariatePolynomial AN
+ FR ==> Factored UP
+ FRQ ==> Factored UPQ
+ FRA ==> Factored UPA
+
+ Exports ==> with
+ ffactor: UP -> FR
+ ++ ffactor(p) tries to factor a univariate polynomial p over F
+ qfactor: UP -> Union(FRQ, "failed")
+ ++ qfactor(p) tries to factor p over fractions of integers,
+ ++ returning "failed" if it cannot
+ UP2ifCan: UP -> Union(overq: UPQ, overan: UPA, failed: Boolean)
+ ++ UP2ifCan(x) should be local but conditional.
+ if F has RetractableTo AN then
+ anfactor: UP -> Union(FRA, "failed")
+ ++ anfactor(p) tries to factor p over algebraic numbers,
+ ++ returning "failed" if it cannot
+
+ Implementation ==> add
+ import AlgFactor(UPA)
+ import RationalFactorize(UPQ)
+
+ P2QifCan : PR -> Union(PQ, "failed")
+ UPQ2UP : (SparseUnivariatePolynomial PQ, F) -> UP
+ PQ2F : (PQ, F) -> F
+ ffactor0 : UP -> FR
+
+ dummy := kernel(new()$Symbol)$K
+
+ if F has RetractableTo AN then
+ UPAN2F: UPA -> UP
+ UPQ2AN: UPQ -> UPA
+
+ UPAN2F p ==
+ map(#1::F, p)$UnivariatePolynomialCategoryFunctions2(AN,UPA,F,UP)
+
+ UPQ2AN p ==
+ map(#1::AN, p)$UnivariatePolynomialCategoryFunctions2(Q,UPQ,AN,UPA)
+
+ ffactor p ==
+ (pq := anfactor p) case FRA =>
+ map(UPAN2F, pq::FRA)$FactoredFunctions2(UPA, UP)
+ ffactor0 p
+
+ anfactor p ==
+ (q := UP2ifCan p) case overq =>
+ map(UPQ2AN, factor(q.overq))$FactoredFunctions2(UPQ, UPA)
+ q case overan => factor(q.overan)
+ "failed"
+
+ UP2ifCan p ==
+ ansq := 0$UPQ ; ansa := 0$UPA
+ goforq? := true
+ while p ^= 0 repeat
+ if goforq? then
+ rq := retractIfCan(leadingCoefficient p)@Union(Q, "failed")
+ if rq case Q then
+ ansq := ansq + monomial(rq::Q, degree p)
+ ansa := ansa + monomial(rq::Q::AN, degree p)
+ else
+ goforq? := false
+ ra := retractIfCan(leadingCoefficient p)@Union(AN, "failed")
+ if ra case AN then ansa := ansa + monomial(ra::AN, degree p)
+ else return [true]
+ else
+ ra := retractIfCan(leadingCoefficient p)@Union(AN, "failed")
+ if ra case AN then ansa := ansa + monomial(ra::AN, degree p)
+ else return [true]
+ p := reductum p
+ goforq? => [ansq]
+ [ansa]
+
+ else
+ UPQ2F: UPQ -> UP
+
+ UPQ2F p ==
+ map(#1::F, p)$UnivariatePolynomialCategoryFunctions2(Q,UPQ,F,UP)
+
+ ffactor p ==
+ (pq := qfactor p) case FRQ =>
+ map(UPQ2F, pq::FRQ)$FactoredFunctions2(UPQ, UP)
+ ffactor0 p
+
+ UP2ifCan p ==
+ ansq := 0$UPQ
+ while p ^= 0 repeat
+ rq := retractIfCan(leadingCoefficient p)@Union(Q, "failed")
+ if rq case Q then ansq := ansq + monomial(rq::Q, degree p)
+ else return [true]
+ p := reductum p
+ [ansq]
+
+ ffactor0 p ==
+ smp := numer(ep := p(dummy::F))
+ (q := P2QifCan smp) case "failed" => p::FR
+ map(UPQ2UP(univariate(#1, dummy), denom(ep)::F), factor(q::PQ
+ )$MRationalFactorize(IndexedExponents K, K, Integer,
+ PQ))$FactoredFunctions2(PQ, UP)
+
+ UPQ2UP(p, d) ==
+ map(PQ2F(#1, d), p)$UnivariatePolynomialCategoryFunctions2(PQ,
+ SparseUnivariatePolynomial PQ, F, UP)
+
+ PQ2F(p, d) ==
+ map(#1::F, #1::F, p)$PolynomialCategoryLifting(IndexedExponents K,
+ K, Q, PQ, F) / d
+
+ qfactor p ==
+ (q := UP2ifCan p) case overq => factor(q.overq)
+ "failed"
+
+ P2QifCan p ==
+ and/[retractIfCan(c::F)@Union(Q, "failed") case Q
+ for c in coefficients p] =>
+ map(#1::PQ, retract(#1::F)@Q :: PQ,
+ p)$PolynomialCategoryLifting(IndexedExponents K,K,R,PR,PQ)
+ "failed"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FSUPFACT FunctionSpaceUnivariatePolynomialFactor>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/functions.spad.pamphlet b/src/algebra/functions.spad.pamphlet
new file mode 100644
index 00000000..5dff2a13
--- /dev/null
+++ b/src/algebra/functions.spad.pamphlet
@@ -0,0 +1,120 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra functions.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain BFUNCT BasicFunctions}
+<<domain BFUNCT BasicFunctions>>=
+)abbrev domain BFUNCT BasicFunctions
+++ Author: Brian Dupee
+++ Date Created: August 1994
+++ Date Last Updated: April 1996
+++ Basic Operations: bfKeys, bfEntry
+++ Description: A Domain which implements a table containing details of
+++ points at which particular functions have evaluation problems.
+DF ==> DoubleFloat
+SDF ==> Stream DoubleFloat
+RS ==> Record(zeros: SDF, ones: SDF, singularities: SDF)
+
+BasicFunctions(): E == I where
+ E ==> SetCategory with
+ bfKeys:() -> List Symbol
+ ++ bfKeys() returns the names of each function in the
+ ++ \axiomType{BasicFunctions} table
+ bfEntry:Symbol -> RS
+ ++ bfEntry(k) returns the entry in the \axiomType{BasicFunctions} table
+ ++ corresponding to \spad{k}
+ finiteAggregate
+
+ I ==> add
+
+ Rep := Table(Symbol,RS)
+ import Rep, SDF
+
+ f(x:DF):DF ==
+ positive?(x) => -x
+ -x+1
+
+ bf():$ ==
+ import RS
+ dpi := pi()$DF
+ ndpi:SDF := map(#1*dpi,(z := generate(f,0))) -- [n pi for n in Z]
+ n1dpi:SDF := map(-(2*(#1)-1)*dpi/2,z) -- [(n+1) pi /2]
+ n2dpi:SDF := map(2*#1*dpi,z) -- [2 n pi for n in Z]
+ n3dpi:SDF := map(-(4*(#1)-1)*dpi/4,z)
+ n4dpi:SDF := map(-(4*(#1)-1)*dpi/2,z)
+ sinEntry:RS := [ndpi, n4dpi, empty()$SDF]
+ cosEntry:RS := [n1dpi, n2dpi, esdf := empty()$SDF]
+ tanEntry:RS := [ndpi, n3dpi, n1dpi]
+ asinEntry:RS := [construct([0$DF])$SDF,
+ construct([float(8414709848078965,-16,10)$DF]), esdf]
+ acosEntry:RS := [construct([1$DF])$SDF,
+ construct([float(54030230586813977,-17,10)$DF]), esdf]
+ atanEntry:RS := [construct([0$DF])$SDF,
+ construct([float(15574077246549023,-16,10)$DF]), esdf]
+ secEntry:RS := [esdf, n2dpi, n1dpi]
+ cscEntry:RS := [esdf, n4dpi, ndpi]
+ cotEntry:RS := [n1dpi, n3dpi, ndpi]
+ logEntry:RS := [construct([1$DF])$SDF,esdf, construct([0$DF])$SDF]
+ entryList:List(Record(key:Symbol,entry:RS)) :=
+ [[sin@Symbol, sinEntry], [cos@Symbol, cosEntry],
+ [tan@Symbol, tanEntry], [sec@Symbol, secEntry],
+ [csc@Symbol, cscEntry], [cot@Symbol, cotEntry],
+ [asin@Symbol, asinEntry], [acos@Symbol, acosEntry],
+ [atan@Symbol, atanEntry], [log@Symbol, logEntry]]
+ construct(entryList)$Rep
+
+ bfKeys():List Symbol == keys(bf())$Rep
+
+ bfEntry(k:Symbol):RS == qelt(bf(),k)$Rep
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain BFUNCT BasicFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/galfact.spad.pamphlet b/src/algebra/galfact.spad.pamphlet
new file mode 100644
index 00000000..8d9a6a02
--- /dev/null
+++ b/src/algebra/galfact.spad.pamphlet
@@ -0,0 +1,862 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra galfact.spad}
+\author{Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GALFACT GaloisGroupFactorizer}
+<<package GALFACT GaloisGroupFactorizer>>=
+)abbrev package GALFACT GaloisGroupFactorizer
+++ Author: Frederic Lehobey
+++ Date Created: 28 June 1994
+++ Date Last Updated: 11 July 1997
+++ Basic Operations: factor
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: factorization
+++ Examples:
+++ References:
+++ [1] Bernard Beauzamy, Vilmar Trevisan and Paul S. Wang, Polynomial
+++ Factorization: Sharp Bounds, Efficient Algorithms,
+++ J. Symbolic Computation (1993) 15, 393-413
+++ [2] John Brillhart, Note on Irreducibility Testing,
+++ Mathematics of Computation, vol. 35, num. 35, Oct. 1980, 1379-1381
+++ [3] David R. Musser, On the Efficiency of a Polynomial Irreducibility Test,
+++ Journal of the ACM, Vol. 25, No. 2, April 1978, pp. 271-282
+++ Description: \spadtype{GaloisGroupFactorizer} provides functions
+++ to factor resolvents.
+-- improvements to do :
+-- + reformulate the lifting problem in completeFactor -- See [1] (hard)
+-- + implement algorithm RC -- See [1] (easy)
+-- + use Dedekind's criterion to prove sometimes irreducibility (easy)
+-- or even to improve early detection of true factors (hard)
+-- + replace Sets by Bits
+GaloisGroupFactorizer(UP): Exports == Implementation where
+ Z ==> Integer
+ UP: UnivariatePolynomialCategory Z
+ N ==> NonNegativeInteger
+ P ==> PositiveInteger
+ CYC ==> CyclotomicPolynomialPackage()
+ SUPZ ==> SparseUnivariatePolynomial Z
+
+ ParFact ==> Record(irr: UP, pow: Z)
+ FinalFact ==> Record(contp: Z, factors: List ParFact)
+ DDRecord ==> Record(factor: UP, degree: Z) -- a Distinct-Degree factor
+ DDList ==> List DDRecord
+ MFact ==> Record(prime: Z,factors: List UP) -- Modular Factors
+ LR ==> Record(left: UP, right: UP) -- Functional decomposition
+
+ Exports ==> with
+ makeFR: FinalFact -> Factored UP
+ ++ makeFR(flist) turns the final factorization of henselFact into a
+ ++ \spadtype{Factored} object.
+ degreePartition: DDList -> Multiset N
+ ++ degreePartition(ddfactorization) returns the degree partition of
+ ++ the polynomial f modulo p where ddfactorization is the distinct
+ ++ degree factorization of f computed by
+ ++ \spadfunFrom{ddFact}{ModularDistinctDegreeFactorizer}
+ ++ for some prime p.
+ musserTrials: () -> P
+ ++ musserTrials() returns the number of primes that are tried in
+ ++ \spadfun{modularFactor}.
+ musserTrials: P -> P
+ ++ musserTrials(n) sets to n the number of primes to be tried in
+ ++ \spadfun{modularFactor} and returns the previous value.
+ stopMusserTrials: () -> P
+ ++ stopMusserTrials() returns the bound on the number of factors for
+ ++ which \spadfun{modularFactor} stops to look for an other prime. You
+ ++ will have to remember that the step of recombining the extraneous
+ ++ factors may take up to \spad{2**stopMusserTrials()} trials.
+ stopMusserTrials: P -> P
+ ++ stopMusserTrials(n) sets to n the bound on the number of factors for
+ ++ which \spadfun{modularFactor} stops to look for an other prime. You
+ ++ will have to remember that the step of recombining the extraneous
+ ++ factors may take up to \spad{2**n} trials. Returns the previous
+ ++ value.
+ numberOfFactors: DDList -> N
+ ++ numberOfFactors(ddfactorization) returns the number of factors of
+ ++ the polynomial f modulo p where ddfactorization is the distinct
+ ++ degree factorization of f computed by
+ ++ \spadfunFrom{ddFact}{ModularDistinctDegreeFactorizer}
+ ++ for some prime p.
+ modularFactor: UP -> MFact
+ ++ modularFactor(f) chooses a "good" prime and returns the factorization
+ ++ of f modulo this prime in a form that may be used by
+ ++ \spadfunFrom{completeHensel}{GeneralHenselPackage}. If prime is zero
+ ++ it means that f has been proved to be irreducible over the integers
+ ++ or that f is a unit (i.e. 1 or -1).
+ ++ f shall be primitive (i.e. content(p)=1) and square free (i.e.
+ ++ without repeated factors).
+ useSingleFactorBound?: () -> Boolean
+ ++ useSingleFactorBound?() returns \spad{true} if algorithm with single
+ ++ factor bound is used for factorization, \spad{false} for algorithm
+ ++ with overall bound.
+ useSingleFactorBound: Boolean -> Boolean
+ ++ useSingleFactorBound(b) chooses the algorithm to be used by the
+ ++ factorizers: \spad{true} for algorithm with single
+ ++ factor bound, \spad{false} for algorithm with overall bound.
+ ++ Returns the previous value.
+ useEisensteinCriterion?: () -> Boolean
+ ++ useEisensteinCriterion?() returns \spad{true} if factorizers
+ ++ check Eisenstein's criterion before factoring.
+ useEisensteinCriterion: Boolean -> Boolean
+ ++ useEisensteinCriterion(b) chooses whether factorizers check
+ ++ Eisenstein's criterion before factoring: \spad{true} for
+ ++ using it, \spad{false} else. Returns the previous value.
+ eisensteinIrreducible?: UP -> Boolean
+ ++ eisensteinIrreducible?(p) returns \spad{true} if p can be
+ ++ shown to be irreducible by Eisenstein's criterion,
+ ++ \spad{false} is inconclusive.
+ tryFunctionalDecomposition?: () -> Boolean
+ ++ tryFunctionalDecomposition?() returns \spad{true} if
+ ++ factorizers try functional decomposition of polynomials before
+ ++ factoring them.
+ tryFunctionalDecomposition: Boolean -> Boolean
+ ++ tryFunctionalDecomposition(b) chooses whether factorizers have
+ ++ to look for functional decomposition of polynomials
+ ++ (\spad{true}) or not (\spad{false}). Returns the previous value.
+ factor: UP -> Factored UP
+ ++ factor(p) returns the factorization of p over the integers.
+ factor: (UP,N) -> Factored UP
+ ++ factor(p,r) factorizes the polynomial p using the single factor bound
+ ++ algorithm and knowing that p has at least r factors.
+ factor: (UP,List N) -> Factored UP
+ ++ factor(p,listOfDegrees) factorizes the polynomial p using the single
+ ++ factor bound algorithm and knowing that p has for possible
+ ++ splitting of its degree listOfDegrees.
+ factor: (UP,List N,N) -> Factored UP
+ ++ factor(p,listOfDegrees,r) factorizes the polynomial p using the single
+ ++ factor bound algorithm, knowing that p has for possible
+ ++ splitting of its degree listOfDegrees and that p has at least r
+ ++ factors.
+ factor: (UP,N,N) -> Factored UP
+ ++ factor(p,d,r) factorizes the polynomial p using the single
+ ++ factor bound algorithm, knowing that d divides the degree of all
+ ++ factors of p and that p has at least r factors.
+ factorSquareFree: UP -> Factored UP
+ ++ factorSquareFree(p) returns the factorization of p which is supposed
+ ++ not having any repeated factor (this is not checked).
+ factorSquareFree: (UP,N) -> Factored UP
+ ++ factorSquareFree(p,r) factorizes the polynomial p using the single
+ ++ factor bound algorithm and knowing that p has at least r factors.
+ ++ f is supposed not having any repeated factor (this is not checked).
+ factorSquareFree: (UP,List N) -> Factored UP
+ ++ factorSquareFree(p,listOfDegrees) factorizes the polynomial p using
+ ++ the single factor bound algorithm and knowing that p has for possible
+ ++ splitting of its degree listOfDegrees.
+ ++ f is supposed not having any repeated factor (this is not checked).
+ factorSquareFree: (UP,List N,N) -> Factored UP
+ ++ factorSquareFree(p,listOfDegrees,r) factorizes the polynomial p using
+ ++ the single factor bound algorithm, knowing that p has for possible
+ ++ splitting of its degree listOfDegrees and that p has at least r
+ ++ factors.
+ ++ f is supposed not having any repeated factor (this is not checked).
+ factorSquareFree: (UP,N,N) -> Factored UP
+ ++ factorSquareFree(p,d,r) factorizes the polynomial p using the single
+ ++ factor bound algorithm, knowing that d divides the degree of all
+ ++ factors of p and that p has at least r factors.
+ ++ f is supposed not having any repeated factor (this is not checked).
+ factorOfDegree: (P,UP) -> Union(UP,"failed")
+ ++ factorOfDegree(d,p) returns a factor of p of degree d.
+ factorOfDegree: (P,UP,N) -> Union(UP,"failed")
+ ++ factorOfDegree(d,p,r) returns a factor of p of degree
+ ++ d knowing that p has at least r factors.
+ factorOfDegree: (P,UP,List N) -> Union(UP,"failed")
+ ++ factorOfDegree(d,p,listOfDegrees) returns a factor
+ ++ of p of degree d knowing that p has for possible splitting of its
+ ++ degree listOfDegrees.
+ factorOfDegree: (P,UP,List N,N) -> Union(UP,"failed")
+ ++ factorOfDegree(d,p,listOfDegrees,r) returns a factor
+ ++ of p of degree d knowing that p has for possible splitting of its
+ ++ degree listOfDegrees, and that p has at least r factors.
+ factorOfDegree: (P,UP,List N,N,Boolean) -> Union(UP,"failed")
+ ++ factorOfDegree(d,p,listOfDegrees,r,sqf) returns a
+ ++ factor of p of degree d knowing that p has for possible splitting of
+ ++ its degree listOfDegrees, and that p has at least r factors.
+ ++ If \spad{sqf=true} the polynomial is assumed to be square free (i.e.
+ ++ without repeated factors).
+ henselFact: (UP,Boolean) -> FinalFact
+ ++ henselFact(p,sqf) returns the factorization of p, the result
+ ++ is a Record such that \spad{contp=}content p,
+ ++ \spad{factors=}List of irreducible factors of p with exponent.
+ ++ If \spad{sqf=true} the polynomial is assumed to be square free (i.e.
+ ++ without repeated factors).
+ btwFact: (UP,Boolean,Set N,N) -> FinalFact
+ ++ btwFact(p,sqf,pd,r) returns the factorization of p, the result
+ ++ is a Record such that \spad{contp=}content p,
+ ++ \spad{factors=}List of irreducible factors of p with exponent.
+ ++ If \spad{sqf=true} the polynomial is assumed to be square free (i.e.
+ ++ without repeated factors).
+ ++ pd is the \spadtype{Set} of possible degrees. r is a lower bound for
+ ++ the number of factors of p. Please do not use this function in your
+ ++ code because its design may change.
+
+ Implementation ==> add
+
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FFE ==> Record(flg:fUnion, fctr:UP, xpnt:Z) -- Flag-Factor-Exponent
+ DDFact ==> Record(prime:Z, ddfactors:DDList) -- Distinct Degree Factors
+ HLR ==> Record(plist:List UP, modulo:Z) -- HenselLift Record
+
+ mussertrials: P := 5
+ stopmussertrials: P := 8
+ usesinglefactorbound: Boolean := true
+ tryfunctionaldecomposition: Boolean := true
+ useeisensteincriterion: Boolean := true
+
+ useEisensteinCriterion?():Boolean == useeisensteincriterion
+
+ useEisensteinCriterion(b:Boolean):Boolean ==
+ (useeisensteincriterion,b) := (b,useeisensteincriterion)
+ b
+
+ tryFunctionalDecomposition?():Boolean == tryfunctionaldecomposition
+
+ tryFunctionalDecomposition(b:Boolean):Boolean ==
+ (tryfunctionaldecomposition,b) := (b,tryfunctionaldecomposition)
+ b
+
+ useSingleFactorBound?():Boolean == usesinglefactorbound
+
+ useSingleFactorBound(b:Boolean):Boolean ==
+ (usesinglefactorbound,b) := (b,usesinglefactorbound)
+ b
+
+ stopMusserTrials():P == stopmussertrials
+
+ stopMusserTrials(n:P):P ==
+ (stopmussertrials,n) := (n,stopmussertrials)
+ n
+
+ musserTrials():P == mussertrials
+
+ musserTrials(n:P):P ==
+ (mussertrials,n) := (n,mussertrials)
+ n
+
+ import GaloisGroupFactorizationUtilities(Z,UP,Float)
+
+ import GaloisGroupPolynomialUtilities(Z,UP)
+
+ import IntegerPrimesPackage(Z)
+ import IntegerFactorizationPackage(Z)
+
+ import ModularDistinctDegreeFactorizer(UP)
+
+ eisensteinIrreducible?(f:UP):Boolean ==
+ rf := reductum f
+ c: Z := content rf
+ zero? c => false
+ unit? c => false
+ lc := leadingCoefficient f
+ tc := lc
+ while not zero? rf repeat
+ tc := leadingCoefficient rf
+ rf := reductum rf
+ for p in factors(factor c)$Factored(Z) repeat
+-- if (one? p.exponent) and (not zero? (lc rem p.factor)) and
+ if (p.exponent = 1) and (not zero? (lc rem p.factor)) and
+ (not zero? (tc rem ((p.factor)**2))) then return true
+ false
+
+ numberOfFactors(ddlist:DDList):N ==
+ n: N := 0
+ d: Z := 0
+ for dd in ddlist repeat
+ n := n +
+ zero? (d := degree(dd.factor)::Z) => 1
+ (d quo dd.degree)::N
+ n
+
+ -- local function, returns the a Set of shifted elements
+ shiftSet(s:Set N,shift:N):Set N == set [ e+shift for e in parts s ]
+
+ -- local function, returns the "reductum" of an Integer (as chain of bits)
+ reductum(n:Z):Z == n-shift(1,length(n)-1)
+
+ -- local function, returns an integer with level lowest bits set to 1
+ seed(level:Z):Z == shift(1,level)-1
+
+ -- local function, returns the next number (as a chain of bit) for
+ -- factor reconciliation of a given level (which is the number of
+ -- extraneaous factors involved) or "End of level" if not any
+ nextRecNum(levels:N,level:Z,n:Z):Union("End of level",Z) ==
+ if (l := length n)<levels then return(n+shift(1,l-1))
+ (n=shift(seed(level),levels-level)) => "End of level"
+ b: Z := 1
+ while ((l-b) = (lr := length(n := reductum n)))@Boolean repeat b := b+1
+ reductum(n)+shift(seed(b+1),lr)
+
+ -- local function, return the set of N, 0..n
+ fullSet(n:N):Set N == set [ i for i in 0..n ]
+
+ modularFactor(p:UP):MFact ==
+-- not one? abs(content(p)) =>
+ not (abs(content(p)) = 1) =>
+ error "modularFactor: the polynomial is not primitive."
+ zero? (n := degree p) => [0,[p]]
+
+ -- declarations --
+ cprime: Z := 2
+ trials: List DDFact := empty()
+ d: Set N := fullSet(n)
+ dirred: Set N := set [0,n]
+ s: Set N := empty()
+ ddlist: DDList := empty()
+ degfact: N := 0
+ nf: N := stopmussertrials+1
+ i: Z
+
+ -- Musser, see [3] --
+ diffp := differentiate p
+ for i in 1..mussertrials | nf>stopmussertrials repeat
+ -- test 1: cprime divides leading coefficient
+ -- test 2: "bad" primes: (in future: use Dedekind's Criterion)
+ while (zero? ((leadingCoefficient p) rem cprime)) or
+ (not zero? degree gcd(p,diffp,cprime)) repeat
+ cprime := nextPrime(cprime)
+ ddlist := ddFact(p,cprime)
+ -- degree compatibility: See [3] --
+ s := set [0]
+ for f in ddlist repeat
+ degfact := f.degree::N
+ if not zero? degfact then
+ for j in 1..(degree(f.factor) quo degfact) repeat
+ s := union(s, shiftSet(s,degfact))
+ trials := cons([cprime,ddlist]$DDFact,trials)
+ d := intersect(d, s)
+ d = dirred => return [0,[p]] -- p is irreducible
+ cprime := nextPrime(cprime)
+ nf := numberOfFactors ddlist
+
+ -- choose the one with the smallest number of factors
+ choice := first trials
+ nfc := numberOfFactors(choice.ddfactors)
+ for t in rest trials repeat
+ nf := numberOfFactors(t.ddfactors)
+ if nf<nfc or ((nf=nfc) and (t.prime>choice.prime)) then
+ nfc := nf
+ choice := t
+ cprime := choice.prime
+ -- HenselLift$GHENSEL expects the degree 0 factor first
+ [cprime,separateFactors(choice.ddfactors,cprime)]
+
+ degreePartition(ddlist:DDList):Multiset N ==
+ dp: Multiset N := empty()
+ d: N := 0
+ dd: N := 0
+ for f in ddlist repeat
+ zero? (d := degree(f.factor)) => dp := insert!(0,dp)
+ dd := f.degree::N
+ dp := insert!(dd,dp,d quo dd)
+ dp
+
+ import GeneralHenselPackage(Z,UP)
+ import UnivariatePolynomialDecompositionPackage(Z,UP)
+ import BrillhartTests(UP) -- See [2]
+
+ -- local function, finds the factors of f primitive, square-free, with
+ -- positive leading coefficient and non zero trailing coefficient,
+ -- using the overall bound technique. If pdecomp is true then look
+ -- for a functional decomposition of f.
+ henselfact(f:UP,pdecomp:Boolean):List UP ==
+ if brillhartIrreducible? f or
+ (useeisensteincriterion => eisensteinIrreducible? f ; false)
+ then return [f]
+ cf: Union(LR,"failed")
+ if pdecomp and tryfunctionaldecomposition then
+ cf := monicDecomposeIfCan f
+ else
+ cf := "failed"
+ cf case "failed" =>
+ m := modularFactor f
+ zero? (cprime := m.prime) => m.factors
+ b: P := (2*leadingCoefficient(f)*beauzamyBound(f)) :: P
+ completeHensel(f,m.factors,cprime,b)
+ lrf := cf::LR
+ "append"/[ henselfact(g(lrf.right),false) for g in
+ henselfact(lrf.left,true) ]
+
+ -- local function, returns the complete factorization of its arguments,
+ -- using the single-factor bound technique
+ completeFactor(f:UP,lf:List UP,cprime:Z,pk:P,r:N,d:Set N):List UP ==
+ lc := leadingCoefficient f
+ f0 := coefficient(f,0)
+ ltrue: List UP := empty()
+ found? := true
+ degf: N := 0
+ degg: N := 0
+ g0: Z := 0
+ g: UP := 0
+ rg: N := 0
+ nb: Z := 0
+ lg: List UP := empty()
+ b: P := 1
+ dg: Set N := empty()
+ llg: HLR := [empty(),0]
+ levels: N := #lf
+ level: Z := 1
+ ic: Union(Z,"End of level") := 0
+ i: Z := 0
+ while level<levels repeat
+ -- try all possible factors with degree in d
+ ic := seed(level)
+ while ((not found?) and (ic case Z)) repeat
+ i := ic::Z
+ degg := 0
+ g0 := 1 -- LC algorithm
+ for j in 1..levels repeat
+ if bit?(i,j-1) then
+ degg := degg+degree lf.j
+ g0 := g0*coefficient(lf.j,0) -- LC algorithm
+ g0 := symmetricRemainder(lc*g0,pk) -- LC algorithm
+ if member?(degg,d) and (((lc*f0) exquo g0) case Z) then
+ -- LC algorithm
+ g := lc::UP -- build the possible factor -- LC algorithm
+ for j in 1..levels repeat if bit?(i,j-1) then g := g*lf.j
+ g := primitivePart reduction(g,pk)
+ f1 := f exquo g
+ if f1 case UP then -- g is a true factor
+ found? := true
+ -- remove the factors of g from lf
+ nb := 1
+ for j in 1..levels repeat
+ if bit?(i,j-1) then
+ swap!(lf,j,nb)
+ nb := nb+1
+ lg := lf
+ lf := rest(lf,level::N)
+ setrest!(rest(lg,(level-1)::N),empty()$List(UP))
+ f := f1::UP
+ lc := leadingCoefficient f
+ f0 := coefficient(f,0)
+ -- is g irreducible?
+ dg := select(#1<=degg,d)
+ if not(dg=set [0,degg]) then -- implies degg >= 2
+ rg := max(2,r+level-levels)::N
+ b := (2*leadingCoefficient(g)*singleFactorBound(g,rg)) :: P
+ if b>pk and (not brillhartIrreducible?(g)) and
+ (useeisensteincriterion => not eisensteinIrreducible?(g) ;
+ true)
+ then
+ -- g may be reducible
+ llg := HenselLift(g,lg,cprime,b)
+ gpk: P := (llg.modulo)::P
+ -- In case exact factorisation has been reached by
+ -- HenselLift before coefficient bound.
+ if gpk<b then
+ lg := llg.plist
+ else
+ lg := completeFactor(g,llg.plist,cprime,gpk,rg,dg)
+ else lg := [ g ] -- g irreducible
+ else lg := [ g ] -- g irreducible
+ ltrue := append(ltrue,lg)
+ r := max(2,(r-#lg))::N
+ degf := degree f
+ d := select(#1<=degf,d)
+ if degf<=1 then -- lf exhausted
+-- if one? degf then
+ if (degf = 1) then
+ ltrue := cons(f,ltrue)
+ return ltrue -- 1st exit, all factors found
+ else -- can we go on with the same pk?
+ b := (2*lc*singleFactorBound(f,r)) :: P
+ if b>pk then -- unlucky: no we can't
+ llg := HenselLift(f,lf,cprime,b) -- I should reformulate
+ -- the lifting probleme, but hadn't time for that.
+ -- In any case, such case should be quite exceptional.
+ lf := llg.plist
+ pk := (llg.modulo)::P
+ -- In case exact factorisation has been reached by
+ -- HenselLift before coefficient bound.
+ if pk<b then return append(lf,ltrue) -- 2nd exit
+ level := 1
+ ic := nextRecNum(levels,level,i)
+ if found? then
+ levels := #lf
+ found? := false
+ if not (ic case Z) then level := level+1
+ cons(f,ltrue) -- 3rd exit, the last factor was irreducible but not "true"
+
+ -- local function, returns the set of elements "divided" by an integer
+ divideSet(s:Set N, n:N):Set N ==
+ l: List N := [ 0 ]
+ for e in parts s repeat
+ if (ee := (e exquo n)$N) case N then l := cons(ee::N,l)
+ set(l)
+
+ -- Beauzamy-Trevisan-Wang FACTOR, see [1] with some refinements
+ -- and some differences. f is assumed to be primitive, square-free
+ -- and with positive leading coefficient. If pdecomp is true then
+ -- look for a functional decomposition of f.
+ btwFactor(f:UP,d:Set N,r:N,pdecomp:Boolean):List UP ==
+ df := degree f
+ not (max(d) = df) => error "btwFact: Bad arguments"
+ reverse?: Boolean := false
+ negativelc?: Boolean := false
+
+ (d = set [0,df]) => [ f ]
+ if abs(coefficient(f,0))<abs(leadingCoefficient(f)) then
+ f := reverse f
+ reverse? := true
+ brillhartIrreducible? f or
+ (useeisensteincriterion => eisensteinIrreducible?(f) ; false) =>
+ if reverse? then [ reverse f ] else [ f ]
+ if leadingCoefficient(f)<0 then
+ f := -f
+ negativelc? := true
+ cf: Union(LR,"failed")
+ if pdecomp and tryfunctionaldecomposition then
+ cf := monicDecomposeIfCan f
+ else
+ cf := "failed"
+ if cf case "failed" then
+ m := modularFactor f
+ zero? (cprime := m.prime) =>
+ if reverse? then
+ if negativelc? then return [ -reverse f ]
+ else return [ reverse f ]
+ else if negativelc? then return [ -f ]
+ else return [ f ]
+ if noLinearFactor? f then d := remove(1,d)
+ lc := leadingCoefficient f
+ f0 := coefficient(f,0)
+ b: P := (2*lc*singleFactorBound(f,r)) :: P -- LC algorithm
+ lm := HenselLift(f,m.factors,cprime,b)
+ lf := lm.plist
+ pk: P := (lm.modulo)::P
+ if ground? first lf then lf := rest lf
+ -- in case exact factorisation has been reached by HenselLift
+ -- before coefficient bound
+ if not pk < b then lf := completeFactor(f,lf,cprime,pk,r,d)
+ else
+ lrf := cf::LR
+ dh := degree lrf.right
+ lg := btwFactor(lrf.left,divideSet(d,dh),2,true)
+ lf: List UP := empty()
+ for i in 1..#lg repeat
+ g := lg.i
+ dgh := (degree g)*dh
+ df := subtractIfCan(df,dgh)::N
+ lfg := btwFactor(g(lrf.right),
+ select(#1<=dgh,d),max(2,r-df)::N,false)
+ lf := append(lf,lfg)
+ r := max(2,r-#lfg)::N
+ if reverse? then lf := [ reverse(fact) for fact in lf ]
+ for i in 1..#lf repeat
+ if leadingCoefficient(lf.i)<0 then lf.i := -lf.i
+ -- because we assume f with positive leading coefficient
+ lf
+
+ makeFR(flist:FinalFact):Factored UP ==
+ ctp := factor flist.contp
+ fflist: List FFE := empty()
+ for ff in flist.factors repeat
+ fflist := cons(["prime", ff.irr, ff.pow]$FFE, fflist)
+ for fc in factorList ctp repeat
+ fflist := cons([fc.flg, fc.fctr::UP, fc.xpnt]$FFE, fflist)
+ makeFR(unit(ctp)::UP, fflist)
+
+ import IntegerRoots(Z)
+
+ -- local function, factorizes a quadratic polynomial
+ quadratic(p:UP):List UP ==
+ a := leadingCoefficient p
+ b := coefficient(p,1)
+ d := b**2-4*a*coefficient(p,0)
+ r := perfectSqrt(d)
+ r case "failed" => [p]
+ b := b+(r::Z)
+ a := 2*a
+ d := gcd(a,b)
+-- if not one? d then
+ if not (d = 1) then
+ a := a quo d
+ b := b quo d
+ f: UP := monomial(a,1)+monomial(b,0)
+ cons(f,[(p exquo f)::UP])
+
+ isPowerOf2(n:Z): Boolean ==
+ n = 1 => true
+ qr: Record(quotient: Z, remainder: Z) := divide(n,2)
+ qr.remainder = 1 => false
+ isPowerOf2 qr.quotient
+
+ subMinusX(supPol: SUPZ): UP ==
+ minusX: SUPZ := monomial(-1,1)$SUPZ
+ unmakeSUP(elt(supPol,minusX)$SUPZ)
+
+ henselFact(f:UP, sqf:Boolean):FinalFact ==
+ factorlist: List(ParFact) := empty()
+
+ -- make m primitive
+ c: Z := content f
+ f := (f exquo c)::UP
+
+ -- make the leading coefficient positive
+ if leadingCoefficient f < 0 then
+ c := -c
+ f := -f
+
+ -- is x**d factor of f
+ if (d := minimumDegree f) > 0 then
+ f := monicDivide(f,monomial(1,d)).quotient
+ factorlist := [[monomial(1,1),d]$ParFact]
+
+ d := degree f
+
+ -- is f constant?
+ zero? d => [c,factorlist]$FinalFact
+
+ -- is f linear?
+-- one? d => [c,cons([f,1]$ParFact,factorlist)]$FinalFact
+ (d = 1) => [c,cons([f,1]$ParFact,factorlist)]$FinalFact
+
+ lcPol: UP := leadingCoefficient(f) :: UP
+
+ -- is f cyclotomic (x**n - 1)?
+ -lcPol = reductum(f) => -- if true, both will = 1
+ for fac in map(unmakeSUP(#1)$UP,
+ cyclotomicDecomposition(d)$CYC)$ListFunctions2(SUPZ,UP) repeat
+ factorlist := cons([fac,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is f odd cyclotomic (x**(2*n+1) + 1)?
+ odd?(d) and (lcPol = reductum(f)) =>
+ for sfac in cyclotomicDecomposition(d)$CYC repeat
+ fac := subMinusX sfac
+ if leadingCoefficient fac < 0 then fac := -fac
+ factorlist := cons([fac,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is the poly of the form x**n + 1 with n a power of 2?
+ -- if so, then irreducible
+ isPowerOf2(d) and (lcPol = reductum(f)) =>
+ factorlist := cons([f,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- other special cases to implement...
+
+ -- f is square-free :
+ sqf => [c, append([[pf,1]$ParFact for pf in henselfact(f,true)],
+ factorlist)]$FinalFact
+
+ -- f is not square-free :
+ sqfflist := factors squareFree f
+ for sqfr in sqfflist repeat
+ mult := sqfr.exponent
+ sqff := sqfr.factor
+ d := degree sqff
+-- one? d => factorlist := cons([sqff,mult]$ParFact,factorlist)
+ (d = 1) => factorlist := cons([sqff,mult]$ParFact,factorlist)
+ d=2 =>
+ factorlist := append([[pf,mult]$ParFact for pf in quadratic(sqff)],
+ factorlist)
+ factorlist := append([[pf,mult]$ParFact for pf in
+ henselfact(sqff,true)],factorlist)
+ [c,factorlist]$FinalFact
+
+ btwFact(f:UP, sqf:Boolean, fd:Set N, r:N):FinalFact ==
+ d := degree f
+ not(max(fd)=d) => error "btwFact: Bad arguments"
+ factorlist: List(ParFact) := empty()
+
+ -- make m primitive
+ c: Z := content f
+ f := (f exquo c)::UP
+
+ -- make the leading coefficient positive
+ if leadingCoefficient f < 0 then
+ c := -c
+ f := -f
+
+ -- is x**d factor of f
+ if (maxd := minimumDegree f) > 0 then
+ f := monicDivide(f,monomial(1,maxd)).quotient
+ factorlist := [[monomial(1,1),maxd]$ParFact]
+ r := max(2,r-maxd)::N
+ d := subtractIfCan(d,maxd)::N
+ fd := select(#1<=d,fd)
+
+ -- is f constant?
+ zero? d => [c,factorlist]$FinalFact
+
+ -- is f linear?
+-- one? d => [c,cons([f,1]$ParFact,factorlist)]$FinalFact
+ (d = 1) => [c,cons([f,1]$ParFact,factorlist)]$FinalFact
+
+ lcPol: UP := leadingCoefficient(f) :: UP
+
+ -- is f cyclotomic (x**n - 1)?
+ -lcPol = reductum(f) => -- if true, both will = 1
+ for fac in map(unmakeSUP(#1)$UP,
+ cyclotomicDecomposition(d)$CYC)$ListFunctions2(SUPZ,UP) repeat
+ factorlist := cons([fac,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is f odd cyclotomic (x**(2*n+1) + 1)?
+ odd?(d) and (lcPol = reductum(f)) =>
+ for sfac in cyclotomicDecomposition(d)$CYC repeat
+ fac := subMinusX sfac
+ if leadingCoefficient fac < 0 then fac := -fac
+ factorlist := cons([fac,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is the poly of the form x**n + 1 with n a power of 2?
+ -- if so, then irreducible
+ isPowerOf2(d) and (lcPol = reductum(f)) =>
+ factorlist := cons([f,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- other special cases to implement...
+
+ -- f is square-free :
+ sqf => [c, append([[pf,1]$ParFact for pf in btwFactor(f,fd,r,true)],
+ factorlist)]$FinalFact
+
+ -- f is not square-free :
+ sqfflist := factors squareFree(f)
+-- if one?(#(sqfflist)) then -- indeed f was a power of a square-free
+ if ((#(sqfflist)) = 1) then -- indeed f was a power of a square-free
+ r := max(r quo ((first sqfflist).exponent),2)::N
+ else
+ r := 2
+ for sqfr in sqfflist repeat
+ mult := sqfr.exponent
+ sqff := sqfr.factor
+ d := degree sqff
+-- one? d =>
+ (d = 1) =>
+ factorlist := cons([sqff,mult]$ParFact,factorlist)
+ maxd := (max(fd)-mult)::N
+ fd := select(#1<=maxd,fd)
+ d=2 =>
+ factorlist := append([[pf,mult]$ParFact for pf in quadratic(sqff)],
+ factorlist)
+ maxd := (max(fd)-2*mult)::N
+ fd := select(#1<=maxd,fd)
+ factorlist := append([[pf,mult]$ParFact for pf in
+ btwFactor(sqff,select(#1<=d,fd),r,true)],factorlist)
+ maxd := (max(fd)-d*mult)::N
+ fd := select(#1<=maxd,fd)
+ [c,factorlist]$FinalFact
+
+ factor(f:UP):Factored UP ==
+ makeFR
+ usesinglefactorbound => btwFact(f,false,fullSet(degree f),2)
+ henselFact(f,false)
+
+ -- local function, returns true if the sum of the elements of the list
+ -- is not the degree.
+ errorsum?(d:N,ld:List N):Boolean == not (d = +/ld)
+
+ -- local function, turns list of degrees into a Set
+ makeSet(ld:List N):Set N ==
+ s := set [0]
+ for d in ld repeat s := union(s,shiftSet(s,d))
+ s
+
+ factor(f:UP,ld:List N,r:N):Factored UP ==
+ errorsum?(degree f,ld) => error "factor: Bad arguments"
+ makeFR btwFact(f,false,makeSet(ld),r)
+
+ factor(f:UP,r:N):Factored UP == makeFR btwFact(f,false,fullSet(degree f),r)
+
+ factor(f:UP,ld:List N):Factored UP == factor(f,ld,2)
+
+ factor(f:UP,d:N,r:N):Factored UP ==
+ n := (degree f) exquo d
+ n case "failed" => error "factor: Bad arguments"
+ factor(f,new(n::N,d)$List(N),r)
+
+ factorSquareFree(f:UP):Factored UP ==
+ makeFR
+ usesinglefactorbound => btwFact(f,true,fullSet(degree f),2)
+ henselFact(f,true)
+
+ factorSquareFree(f:UP,ld:List(N),r:N):Factored UP ==
+ errorsum?(degree f,ld) => error "factorSquareFree: Bad arguments"
+ makeFR btwFact(f,true,makeSet(ld),r)
+
+ factorSquareFree(f:UP,r:N):Factored UP ==
+ makeFR btwFact(f,true,fullSet(degree f),r)
+
+ factorSquareFree(f:UP,ld:List N):Factored UP == factorSquareFree(f,ld,2)
+
+ factorSquareFree(f:UP,d:N,r:N):Factored UP ==
+ n := (degree f) exquo d
+ n case "failed" => error "factorSquareFree: Bad arguments"
+ factorSquareFree(f,new(n::N,d)$List(N),r)
+
+ factorOfDegree(d:P,p:UP,ld:List N,r:N,sqf:Boolean):Union(UP,"failed") ==
+ dp := degree p
+ errorsum?(dp,ld) => error "factorOfDegree: Bad arguments"
+-- (one? (d::N)) and noLinearFactor?(p) => "failed"
+ ((d::N) = 1) and noLinearFactor?(p) => "failed"
+ lf := btwFact(p,sqf,makeSet(ld),r).factors
+ for f in lf repeat
+ degree(f.irr)=d => return f.irr
+ "failed"
+
+ factorOfDegree(d:P,p:UP,ld:List N,r:N):Union(UP,"failed") ==
+ factorOfDegree(d,p,ld,r,false)
+
+ factorOfDegree(d:P,p:UP,r:N):Union(UP,"failed") ==
+ factorOfDegree(d,p,new(degree p,1)$List(N),r,false)
+
+ factorOfDegree(d:P,p:UP,ld:List N):Union(UP,"failed") ==
+ factorOfDegree(d,p,ld,2,false)
+
+ factorOfDegree(d:P,p:UP):Union(UP,"failed") ==
+ factorOfDegree(d,p,new(degree p,1)$List(N),2,false)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GALFACT GaloisGroupFactorizer>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/galfactu.spad.pamphlet b/src/algebra/galfactu.spad.pamphlet
new file mode 100644
index 00000000..f7dacfe9
--- /dev/null
+++ b/src/algebra/galfactu.spad.pamphlet
@@ -0,0 +1,214 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra galfactu.spad}
+\author{Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GALFACTU GaloisGroupFactorizationUtilities}
+<<package GALFACTU GaloisGroupFactorizationUtilities>>=
+)abbrev package GALFACTU GaloisGroupFactorizationUtilities
+++ Author: Frederic Lehobey
+++ Date Created: 30 June 1994
+++ Date Last Updated: 19 October 1995
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ [1] Bernard Beauzamy, Products of polynomials and a priori estimates for
+++ coefficients in polynomial decompositions: a sharp result,
+++ J. Symbolic Computation (1992) 13, 463-472
+++ [2] David W. Boyd, Bounds for the Height of a Factor of a Polynomial in
+++ Terms of Bombieri's Norms: I. The Largest Factor,
+++ J. Symbolic Computation (1993) 16, 115-130
+++ [3] David W. Boyd, Bounds for the Height of a Factor of a Polynomial in
+++ Terms of Bombieri's Norms: II. The Smallest Factor,
+++ J. Symbolic Computation (1993) 16, 131-145
+++ [4] Maurice Mignotte, Some Useful Bounds,
+++ Computing, Suppl. 4, 259-263 (1982), Springer-Verlag
+++ [5] Donald E. Knuth, The Art of Computer Programming, Vol. 2, (Seminumerical
+++ Algorithms) 1st edition, 2nd printing, Addison-Wesley 1971, p. 397-398
+++ [6] Bernard Beauzamy, Vilmar Trevisan and Paul S. Wang, Polynomial
+++ Factorization: Sharp Bounds, Efficient Algorithms,
+++ J. Symbolic Computation (1993) 15, 393-413
+++ [7] Augustin-Lux Cauchy, Exercices de Math\'ematiques Quatri\`eme Ann\'ee.
+++ De Bure Fr\`eres, Paris 1829 (reprinted Oeuvres, II S\'erie, Tome IX,
+++ Gauthier-Villars, Paris, 1891).
+++ Description:
+++ \spadtype{GaloisGroupFactorizationUtilities} provides functions
+++ that will be used by the factorizer.
+
+GaloisGroupFactorizationUtilities(R,UP,F): Exports == Implementation where
+ R : Ring
+ UP : UnivariatePolynomialCategory R
+ F : Join(FloatingPointSystem,RetractableTo(R),Field,
+ TranscendentalFunctionCategory,ElementaryFunctionCategory)
+ N ==> NonNegativeInteger
+ P ==> PositiveInteger
+ Z ==> Integer
+
+ Exports ==> with
+ beauzamyBound: UP -> Z -- See [1]
+ ++ beauzamyBound(p) returns a bound on the larger coefficient of any
+ ++ factor of p.
+ bombieriNorm: UP -> F -- See [1]
+ ++ bombieriNorm(p) returns quadratic Bombieri's norm of p.
+ bombieriNorm: (UP,P) -> F -- See [2] and [3]
+ ++ bombieriNorm(p,n) returns the nth Bombieri's norm of p.
+ rootBound: UP -> Z -- See [4] and [5]
+ ++ rootBound(p) returns a bound on the largest norm of the complex roots
+ ++ of p.
+ singleFactorBound: (UP,N) -> Z -- See [6]
+ ++ singleFactorBound(p,r) returns a bound on the infinite norm of
+ ++ the factor of p with smallest Bombieri's norm. r is a lower bound
+ ++ for the number of factors of p. p shall be of degree higher or equal
+ ++ to 2.
+ singleFactorBound: UP -> Z -- See [6]
+ ++ singleFactorBound(p,r) returns a bound on the infinite norm of
+ ++ the factor of p with smallest Bombieri's norm. p shall be of degree
+ ++ higher or equal to 2.
+ norm: (UP,P) -> F
+ ++ norm(f,p) returns the lp norm of the polynomial f.
+ quadraticNorm: UP -> F
+ ++ quadraticNorm(f) returns the l2 norm of the polynomial f.
+ infinityNorm: UP -> F
+ ++ infinityNorm(f) returns the maximal absolute value of the coefficients
+ ++ of the polynomial f.
+ height: UP -> F
+ ++ height(p) returns the maximal absolute value of the coefficients of
+ ++ the polynomial p.
+ length: UP -> F
+ ++ length(p) returns the sum of the absolute values of the coefficients
+ ++ of the polynomial p.
+
+ Implementation ==> add
+
+ import GaloisGroupUtilities(F)
+
+ height(p:UP):F == infinityNorm(p)
+
+ length(p:UP):F == norm(p,1)
+
+ norm(f:UP,p:P):F ==
+ n : F := 0
+ for c in coefficients f repeat
+ n := n+abs(c::F)**p
+ nthRoot(n,p::N)
+
+ quadraticNorm(f:UP):F == norm(f,2)
+
+ infinityNorm(f:UP):F ==
+ n : F := 0
+ for c in coefficients f repeat
+ n := max(n,c::F)
+ n
+
+ singleFactorBound(p:UP,r:N):Z == -- See [6]
+ n : N := degree p
+ r := max(2,r)
+ n < r => error "singleFactorBound: Bad arguments."
+ nf : F := n :: F
+ num : F := nthRoot(bombieriNorm(p),r)
+ if F has Gamma: F -> F then
+ num := num*nthRoot(Gamma(nf+1$F),2*r)
+ den : F := Gamma(nf/((2*r)::F)+1$F)
+ else
+ num := num*(2::F)**(5/8+n/2)*exp(1$F/(4*nf))
+ den : F := (pi()$F*nf)**(3/8)
+ safeFloor( num/den )
+
+ singleFactorBound(p:UP):Z == singleFactorBound(p,2) -- See [6]
+
+ rootBound(p:UP):Z == -- See [4] and [5]
+ n := degree p
+ zero? n => 0
+ lc := abs(leadingCoefficient(p)::F)
+ b1 : F := 0 -- Mignotte
+ b2 : F := 0 -- Knuth
+ b3 : F := 0 -- Zassenhaus in [5]
+ b4 : F := 0 -- Cauchy in [7]
+ c : F := 0
+ cl : F := 0
+ for i in 1..n repeat
+ c := abs(coefficient(p,(n-i)::N)::F)
+ b1 := max(b1,c)
+ cl := c/lc
+ b2 := max(b2,nthRoot(cl,i))
+ b3 := max(b3,nthRoot(cl/pascalTriangle(n,i),i))
+ b4 := max(b4,nthRoot(n*cl,i))
+ min(1+safeCeiling(b1/lc),min(safeCeiling(2*b2),min(safeCeiling(b3/
+ (nthRoot(2::F,n)-1)),safeCeiling(b4))))
+
+ beauzamyBound(f:UP):Z == -- See [1]
+ d := degree f
+ zero? d => safeFloor bombieriNorm f
+ safeFloor( (bombieriNorm(f)*(3::F)**(3/4+d/2))/
+ (2*sqrt(pi()$F*(d::F))) )
+
+ bombieriNorm(f:UP,p:P):F == -- See [2] and [3]
+ d := degree f
+ b := abs(coefficient(f,0)::F)
+ if zero? d then return b
+ else b := b**p
+ b := b+abs(leadingCoefficient(f)::F)**p
+ dd := (d-1) quo 2
+ for i in 1..dd repeat
+ b := b+(abs(coefficient(f,i)::F)**p+abs(coefficient(f,(d-i)::N)::F)**p)
+ /pascalTriangle(d,i)
+ if even? d then
+ dd := dd+1
+ b := b+abs(coefficient(f, dd::N)::F)**p/pascalTriangle(d,dd)
+ nthRoot(b,p::N)
+
+ bombieriNorm(f:UP):F == bombieriNorm(f,2) -- See [1]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GALFACTU GaloisGroupFactorizationUtilities>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/galpolyu.spad.pamphlet b/src/algebra/galpolyu.spad.pamphlet
new file mode 100644
index 00000000..2e573208
--- /dev/null
+++ b/src/algebra/galpolyu.spad.pamphlet
@@ -0,0 +1,156 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra galpolyu.spad}
+\author{Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GALPOLYU GaloisGroupPolynomialUtilities}
+<<package GALPOLYU GaloisGroupPolynomialUtilities>>=
+)abbrev package GALPOLYU GaloisGroupPolynomialUtilities
+++ Author: Frederic Lehobey
+++ Date Created: 30 June 1994
+++ Date Last Updated: 15 July 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: \spadtype{GaloisGroupPolynomialUtilities} provides useful
+++ functions for univariate polynomials which should be added to
+++ \spadtype{UnivariatePolynomialCategory} or to \spadtype{Factored}
+++ (July 1994).
+
+GaloisGroupPolynomialUtilities(R,UP): Exports == Implementation where
+ R : Ring
+ UP : UnivariatePolynomialCategory R
+ N ==> NonNegativeInteger
+ P ==> PositiveInteger
+
+ Exports ==> with
+ monic?: UP -> Boolean
+ ++ monic?(p) tests if p is monic (i.e. leading coefficient equal to 1).
+ unvectorise: Vector R -> UP
+ ++ unvectorise(v) returns the polynomial which has for coefficients the
+ ++ entries of v in the increasing order.
+ reverse: UP -> UP
+ ++ reverse(p) returns the reverse polynomial of p.
+ scaleRoots: (UP,R) -> UP
+ ++ scaleRoots(p,c) returns the polynomial which has c times the roots
+ ++ of p.
+ shiftRoots: (UP,R) -> UP
+ ++ shiftRoots(p,c) returns the polynomial which has for roots c added
+ ++ to the roots of p.
+ degreePartition: Factored UP -> Multiset N
+ ++ degreePartition(f) returns the degree partition (i.e. the multiset
+ ++ of the degrees of the irreducible factors) of
+ ++ the polynomial f.
+ factorOfDegree: (P, Factored UP) -> UP
+ ++ factorOfDegree(d,f) returns a factor of degree d of the factored
+ ++ polynomial f. Such a factor shall exist.
+ factorsOfDegree: (P, Factored UP) -> List UP
+ ++ factorsOfDegree(d,f) returns the factors of degree d of the factored
+ ++ polynomial f.
+
+ Implementation ==> add
+
+ import Factored UP
+
+ factorsOfDegree(d:P,r:Factored UP):List UP ==
+ lfact : List UP := empty()
+ for fr in factors r | degree(fr.factor)=(d::N) repeat
+ for i in 1..fr.exponent repeat
+ lfact := cons(fr.factor,lfact)
+ lfact
+
+ factorOfDegree(d:P,r:Factored UP):UP ==
+ factor : UP := 0
+ for i in 1..numberOfFactors r repeat
+ factor := nthFactor(r,i)
+ if degree(factor)=(d::N) then return factor
+ error "factorOfDegree: Bad arguments"
+
+ degreePartition(r:Factored UP):Multiset N ==
+ multiset([ degree(nthFactor(r,i)) for i in 1..numberOfFactors r ])
+
+-- monic?(p:UP):Boolean == one? leadingCoefficient p
+ monic?(p:UP):Boolean == (leadingCoefficient p) = 1
+
+ unvectorise(v:Vector R):UP ==
+ p : UP := 0
+ for i in 1..#v repeat p := p + monomial(v(i),(i-1)::N)
+ p
+
+ reverse(p:UP):UP ==
+ r : UP := 0
+ n := degree(p)
+ for i in 0..n repeat r := r + monomial(coefficient(p,(n-i)::N),i)
+ r
+
+ scaleRoots(p:UP,c:R):UP ==
+-- one? c => p
+ (c = 1) => p
+ n := degree p
+ zero? c => monomial(leadingCoefficient p,n)
+ r : UP := 0
+ mc : R := 1
+ for i in n..0 by -1 repeat
+ r := r + monomial(mc*coefficient(p,i),i)
+ mc := mc*c
+ r
+
+ import UnivariatePolynomialCategoryFunctions2(R,UP,UP,
+ SparseUnivariatePolynomial UP)
+
+ shiftRoots(p:UP,c:R):UP == elt(map(coerce,p),monomial(1,1)$UP-c::UP)::UP
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GALPOLYU GaloisGroupPolynomialUtilities>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/galutil.spad.pamphlet b/src/algebra/galutil.spad.pamphlet
new file mode 100644
index 00000000..8873a5eb
--- /dev/null
+++ b/src/algebra/galutil.spad.pamphlet
@@ -0,0 +1,173 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra galutil.spad}
+\author{Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GALUTIL GaloisGroupUtilities}
+<<package GALUTIL GaloisGroupUtilities>>=
+)abbrev package GALUTIL GaloisGroupUtilities
+++ Author: Frederic Lehobey
+++ Date Created: 29 June 1994
+++ Date Last Updated: 30 June 1994
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{GaloisGroupUtilities} provides several useful functions.
+
+GaloisGroupUtilities(R): Exports == Implementation where
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ R : Ring
+
+ Exports ==> with
+ pascalTriangle: (N,Z) -> R
+ ++ pascalTriangle(n,r) returns the binomial coefficient
+ ++ \spad{C(n,r)=n!/(r! (n-r)!)}
+ ++ and stores it in a table to prevent recomputation.
+ rangePascalTriangle: N -> N
+ ++ rangePascalTriangle(n) sets the maximal number of lines which
+ ++ are stored and returns the previous value.
+ rangePascalTriangle: () -> N
+ ++ rangePascalTriangle() returns the maximal number of lines stored.
+ sizePascalTriangle: () -> N
+ ++ sizePascalTriangle() returns the number of entries currently stored
+ ++ in the table.
+ fillPascalTriangle: () -> Void
+ ++ fillPascalTriangle() fills the stored table.
+
+ if R has FloatingPointSystem then
+ safeCeiling: R -> Z
+ ++ safeCeiling(x) returns the integer which is greater than any integer
+ ++ with the same floating point number representation.
+ safeFloor: R -> Z
+ ++ safeFloor(x) returns the integer which is lower or equal to the
+ ++ largest integer which has the same floating point number
+ ++ representation.
+ safetyMargin: N -> N
+ ++ safetyMargin(n) sets to n the number of low weight digits we do not
+ ++ trust in the floating point representation and returns the previous
+ ++ value (for use by \spadfun{safeCeiling}).
+ safetyMargin: () -> N
+ ++ safetyMargin() returns the number of low weight digits we do not
+ ++ trust in the floating point representation (used by
+ ++ \spadfun{safeCeiling}).
+
+ Implementation ==> add
+
+ if R has FloatingPointSystem then
+ safetymargin : N := 6
+
+ safeFloor(x:R):Z ==
+ if (shift := order(x)-precision()$R+safetymargin) >= 0 then
+ x := x+float(1,shift)
+ retract(floor(x))@Z
+
+ safeCeiling(x:R):Z ==
+ if (shift := order(x)-precision()$R+safetymargin) >= 0 then
+ x := x+float(1,shift)
+ retract(ceiling(x))@Z
+
+ safetyMargin(n:N):N ==
+ (safetymargin,n) := (n,safetymargin)
+ n
+
+ safetyMargin():N == safetymargin
+
+ pascaltriangle : FlexibleArray(R) := empty()
+ ncomputed : N := 3
+ rangepascaltriangle : N := 216
+
+ pascalTriangle(n:N, r:Z):R ==
+ negative? r => 0
+ (d := n-r) < r => pascalTriangle(n,d)
+ zero? r => 1$R
+-- one? r => n :: R
+ (r = 1) => n :: R
+ n > rangepascaltriangle =>
+ binomial(n,r)$IntegerCombinatoricFunctions(Z) :: R
+ n <= ncomputed =>
+ m := divide(n-4,2)
+ mq := m.quotient
+ pascaltriangle((mq+1)*(mq+m.remainder)+r-1)
+ -- compute the missing lines
+ for i in (ncomputed+1)..n repeat
+ for j in 2..(i quo 2) repeat
+ pascaltriangle := concat!(pascaltriangle,pascalTriangle((i-1)
+ :: N, j-1)+pascalTriangle((i-1) :: N,j))
+ ncomputed := i
+ pascalTriangle(n,r)
+
+ rangePascalTriangle(n:N):N ==
+ if n<ncomputed then
+ if n<3 then
+ pascaltriangle := delete!(pascaltriangle,1..#pascaltriangle)
+ ncomputed := 3
+ else
+ d := divide(n-3,2)
+ dq := d.quotient
+ pascaltriangle := delete!(pascaltriangle,((dq+1)*(dq+d.remainder)
+ +1)..#pascaltriangle)
+ ncomputed := n
+ (rangepascaltriangle,n) := (n,rangepascaltriangle)
+ n
+
+ rangePascalTriangle():N == rangepascaltriangle
+
+ sizePascalTriangle():N == #pascaltriangle
+
+ fillPascalTriangle():Void == pascalTriangle(rangepascaltriangle,2)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GALUTIL GaloisGroupUtilities>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gaussfac.spad.pamphlet b/src/algebra/gaussfac.spad.pamphlet
new file mode 100644
index 00000000..1b1e3197
--- /dev/null
+++ b/src/algebra/gaussfac.spad.pamphlet
@@ -0,0 +1,233 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gaussfac.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GAUSSFAC GaussianFactorizationPackage}
+<<package GAUSSFAC GaussianFactorizationPackage>>=
+)abbrev package GAUSSFAC GaussianFactorizationPackage
+++ Author: Patrizia Gianni
+++ Date Created: Summer 1986
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: Package for the factorization of complex or gaussian
+++ integers.
+GaussianFactorizationPackage() : C == T
+ where
+ NNI == NonNegativeInteger
+ Z ==> Integer
+ ZI ==> Complex Z
+ FRZ ==> Factored ZI
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FFE ==> Record(flg:fUnion, fctr:ZI, xpnt:Integer)
+
+ C == with
+ factor : ZI -> FRZ
+ ++ factor(zi) produces the complete factorization of the complex
+ ++ integer zi.
+ sumSquares : Z -> List Z
+ ++ sumSquares(p) construct \spad{a} and b such that \spad{a**2+b**2}
+ ++ is equal to
+ ++ the integer prime p, and otherwise returns an error.
+ ++ It will succeed if the prime number p is 2 or congruent to 1
+ ++ mod 4.
+ prime? : ZI -> Boolean
+ ++ prime?(zi) tests if the complex integer zi is prime.
+
+ T == add
+ import IntegerFactorizationPackage Z
+
+ reduction(u:Z,p:Z):Z ==
+ p=0 => u
+ positiveRemainder(u,p)
+
+ merge(p:Z,q:Z):Union(Z,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ exactquo(u:Z,v:Z,p:Z):Union(Z,"failed") ==
+ p=0 => u exquo v
+ v rem p = 0 => "failed"
+ positiveRemainder((extendedEuclidean(v,p,u)::Record(coef1:Z,coef2:Z)).coef1,p)
+
+ FMod := ModularRing(Z,Z,reduction,merge,exactquo)
+
+ fact2:ZI:= complex(1,1)
+
+ ---- find the solution of x**2+1 mod q ----
+ findelt(q:Z) : Z ==
+ q1:=q-1
+ r:=q1
+ r1:=r exquo 4
+ while ^(r1 case "failed") repeat
+ r:=r1::Z
+ r1:=r exquo 2
+ s : FMod := reduce(1,q)
+ qq1:FMod :=reduce(q1,q)
+ for i in 2.. while (s=1 or s=qq1) repeat
+ s:=reduce(i,q)**(r::NNI)
+ t:=s
+ while t^=qq1 repeat
+ s:=t
+ t:=t**2
+ s::Z
+
+
+ ---- write p, congruent to 1 mod 4, as a sum of two squares ----
+ sumsq1(p:Z) : List Z ==
+ s:= findelt(p)
+ u:=p
+ while u**2>p repeat
+ w:=u rem s
+ u:=s
+ s:=w
+ [u,s]
+
+ ---- factorization of an integer ----
+ intfactor(n:Z) : Factored ZI ==
+ lfn:= factor n
+ r : List FFE :=[]
+ unity:ZI:=complex(unit lfn,0)
+ for term in (factorList lfn) repeat
+ n:=term.fctr
+ exp:=term.xpnt
+ n=2 =>
+ r :=concat(["prime",fact2,2*exp]$FFE,r)
+ unity:=unity*complex(0,-1)**(exp rem 4)::NNI
+
+ (n rem 4) = 3 => r:=concat(["prime",complex(n,0),exp]$FFE,r)
+
+ sz:=sumsq1(n)
+ z:=complex(sz.1,sz.2)
+ r:=concat(["prime",z,exp]$FFE,
+ concat(["prime",conjugate(z),exp]$FFE,r))
+ makeFR(unity,r)
+
+ ---- factorization of a gaussian number ----
+ factor(m:ZI) : FRZ ==
+ m=0 => primeFactor(0,1)
+ a:= real m
+
+ (b:= imag m)=0 => intfactor(a) :: FRZ
+
+ a=0 =>
+ ris:=intfactor(b)
+ unity:= unit(ris)*complex(0,1)
+ makeFR(unity,factorList ris)
+
+ d:=gcd(a,b)
+ result : List FFE :=[]
+ unity:ZI:=1$ZI
+
+ if d^=1 then
+ a:=(a exquo d)::Z
+ b:=(b exquo d)::Z
+ r:= intfactor(d)
+ result:=factorList r
+ unity:=unit r
+ m:=complex(a,b)
+
+ n:Z:=a**2+b**2
+ factn:= factorList(factor n)
+ part:FFE:=["prime",0$ZI,0]
+ for term in factn repeat
+ n:=term.fctr
+ exp:=term.xpnt
+ n=2 =>
+ part:= ["prime",fact2,exp]$FFE
+ m:=m quo (fact2**exp:NNI)
+ result:=concat(part,result)
+
+ (n rem 4) = 3 =>
+ g0:=complex(n,0)
+ part:= ["prime",g0,exp quo 2]$FFE
+ m:=m quo g0
+ result:=concat(part,result)
+
+ z:=gcd(m,complex(n,0))
+ part:= ["prime",z,exp]$FFE
+ z:=z**(exp:NNI)
+ m:=m quo z
+ result:=concat(part,result)
+
+ if m^=1 then unity:=unity * m
+ makeFR(unity,result)
+
+ ---- write p prime like sum of two squares ----
+ sumSquares(p:Z) : List Z ==
+ p=2 => [1,1]
+ p rem 4 ^= 1 => error "no solutions"
+ sumsq1(p)
+
+
+ prime?(a:ZI) : Boolean ==
+ n : Z := norm a
+ n=0 => false -- zero
+ n=1 => false -- units
+ prime?(n)$IntegerPrimesPackage(Z) => true
+ re : Z := real a
+ im : Z := imag a
+ re^=0 and im^=0 => false
+ p : Z := abs(re+im) -- a is of the form p, -p, %i*p or -%i*p
+ p rem 4 ^= 3 => false
+ -- return-value true, if p is a rational prime,
+ -- and false, otherwise
+ prime?(p)$IntegerPrimesPackage(Z)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GAUSSFAC GaussianFactorizationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gaussian.spad.pamphlet b/src/algebra/gaussian.spad.pamphlet
new file mode 100644
index 00000000..ccbd0728
--- /dev/null
+++ b/src/algebra/gaussian.spad.pamphlet
@@ -0,0 +1,828 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gaussian.spad}
+\author{Barry Trager, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category COMPCAT ComplexCategory}
+<<category COMPCAT ComplexCategory>>=
+)abbrev category COMPCAT ComplexCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated: 18 March 1994
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: complex, gaussian
+++ References:
+++ Description:
+++ This category represents the extension of a ring by a square
+++ root of -1.
+ComplexCategory(R:CommutativeRing): Category ==
+ Join(MonogenicAlgebra(R, SparseUnivariatePolynomial R), FullyRetractableTo R,
+ DifferentialExtension R, FullyEvalableOver R, FullyPatternMatchable(R),
+ Patternable(R), FullyLinearlyExplicitRingOver R, CommutativeRing) with
+ complex ++ indicates that % has sqrt(-1)
+ imaginary: () -> % ++ imaginary() = sqrt(-1) = %i.
+ conjugate: % -> % ++ conjugate(x + %i y) returns x - %i y.
+ complex : (R, R) -> % ++ complex(x,y) constructs x + %i*y.
+ imag : % -> R ++ imag(x) returns imaginary part of x.
+ real : % -> R ++ real(x) returns real part of x.
+ norm : % -> R ++ norm(x) returns x * conjugate(x)
+ if R has OrderedSet then OrderedSet
+ if R has IntegralDomain then
+ IntegralDomain
+ _exquo : (%,R) -> Union(%,"failed")
+ ++ exquo(x, r) returns the exact quotient of x by r, or
+ ++ "failed" if r does not divide x exactly.
+ if R has EuclideanDomain then EuclideanDomain
+ if R has multiplicativeValuation then multiplicativeValuation
+ if R has additiveValuation then additiveValuation
+ if R has Field then -- this is a lie; we must know that
+ Field -- x**2+1 is irreducible in R
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has RealConstant then
+ ConvertibleTo Complex DoubleFloat
+ ConvertibleTo Complex Float
+ if R has RealNumberSystem then
+ abs: % -> %
+ ++ abs(x) returns the absolute value of x = sqrt(norm(x)).
+ if R has TranscendentalFunctionCategory then
+ TranscendentalFunctionCategory
+ argument: % -> R ++ argument(x) returns the angle made by (0,1) and (0,x).
+ if R has RadicalCategory then RadicalCategory
+ if R has RealNumberSystem then
+ polarCoordinates: % -> Record(r:R, phi:R)
+ ++ polarCoordinates(x) returns (r, phi) such that x = r * exp(%i * phi).
+ if R has IntegerNumberSystem then
+ rational? : % -> Boolean
+ ++ rational?(x) tests if x is a rational number.
+ rational : % -> Fraction Integer
+ ++ rational(x) returns x as a rational number.
+ ++ Error: if x is not a rational number.
+ rationalIfCan: % -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(x) returns x as a rational number, or
+ ++ "failed" if x is not a rational number.
+ if R has PolynomialFactorizationExplicit and R has EuclideanDomain then
+ PolynomialFactorizationExplicit
+ add
+ import MatrixCategoryFunctions2(%, Vector %, Vector %, Matrix %,
+ R, Vector R, Vector R, Matrix R)
+ SUP ==> SparseUnivariatePolynomial
+ characteristicPolynomial x ==
+ v := monomial(1,1)$SUP(R)
+ v**2 - trace(x)*v**1 + norm(x)*v**0
+ if R has PolynomialFactorizationExplicit and R has EuclideanDomain then
+ SupR ==> SparseUnivariatePolynomial R
+ Sup ==> SparseUnivariatePolynomial %
+ import FactoredFunctionUtilities Sup
+ import UnivariatePolynomialCategoryFunctions2(R,SupR,%,Sup)
+ import UnivariatePolynomialCategoryFunctions2(%,Sup,R,SupR)
+ pp,qq:Sup
+ if R has IntegerNumberSystem then
+ myNextPrime: (%,NonNegativeInteger) -> %
+ myNextPrime(x,n ) == -- prime is actually in R, and = 3(mod 4)
+ xr:=real(x)-4::R
+ while not prime? xr repeat
+ xr:=xr-4::R
+ complex(xr,0)
+ --!TT:=InnerModularGcd(%,Sup,32719 :: %,myNextPrime)
+ --!gcdPolynomial(pp,qq) == modularGcd(pp,qq)$TT
+ solveLinearPolynomialEquation(lp:List Sup,p:Sup) ==
+ solveLinearPolynomialEquation(lp,p)$ComplexIntegerSolveLinearPolynomialEquation(R,%)
+ normPolynomial: Sup -> SupR
+ normPolynomial pp ==
+ map(retract(#1@%)::R,pp * map(conjugate,pp))
+ factorPolynomial pp ==
+ refine(squareFree pp,factorSquareFreePolynomial)
+ factorSquareFreePolynomial pp ==
+ pnorm:=normPolynomial pp
+ k:R:=0
+ while degree gcd(pnorm,differentiate pnorm)>0 repeat
+ k:=k+1
+ pnorm:=normPolynomial
+ elt(pp,monomial(1,1)-monomial(complex(0,k),0))
+ fR:=factorSquareFreePolynomial pnorm
+ numberOfFactors fR = 1 =>
+ makeFR(1,[["irred",pp,1]])
+ lF:List Record(flg:Union("nil", "sqfr", "irred", "prime"),
+ fctr:Sup, xpnt:Integer):=[]
+ for u in factorList fR repeat
+ p1:=map((#1@R)::%,u.fctr)
+ if not zero? k then
+ p1:=elt(p1,monomial(1,1)+monomial(complex(0,k),0))
+ p2:=gcd(p1,pp)
+ lF:=cons(["irred",p2,1],lF)
+ pp:=(pp exquo p2)::Sup
+ makeFR(pp,lF)
+ rank() == 2
+ discriminant() == -4 :: R
+ norm x == real(x)**2 + imag(x)**2
+ trace x == 2 * real x
+ imaginary() == complex(0, 1)
+ conjugate x == complex(real x, - imag x)
+ characteristic() == characteristic()$R
+ map(fn, x) == complex(fn real x, fn imag x)
+ x = y == real(x) = real(y) and imag(x) = imag(y)
+ x + y == complex(real x + real y, imag x + imag y)
+ - x == complex(- real x, - imag x)
+ r:R * x:% == complex(r * real x, r * imag x)
+ coordinates(x:%) == [real x, imag x]
+ n:Integer * x:% == complex(n * real x, n * imag x)
+ differentiate(x:%, d:R -> R) == complex(d real x, d imag x)
+
+ definingPolynomial() ==
+ monomial(1,2)$(SUP R) + monomial(1,0)$(SUP R)
+
+ reduce(pol:SUP R) ==
+ part:= (monicDivide(pol,definingPolynomial())).remainder
+ complex(coefficient(part,0),coefficient(part,1))
+
+ lift(x) == monomial(real x,0)$(SUP R)+monomial(imag x,1)$(SUP R)
+
+ minimalPolynomial x ==
+ zero? imag x =>
+ monomial(1, 1)$(SUP R) - monomial(real x, 0)$(SUP R)
+ monomial(1, 2)$(SUP R) - monomial(trace x, 1)$(SUP R)
+ + monomial(norm x, 0)$(SUP R)
+
+ coordinates(x:%, v:Vector %):Vector(R) ==
+ ra := real(a := v(minIndex v))
+ rb := real(b := v(maxIndex v))
+ (#v ^= 2) or
+ ((d := recip(ra * (ib := imag b) - (ia := imag a) * rb))
+ case "failed") =>error "coordinates: vector is not a basis"
+ rx := real x
+ ix := imag x
+ [d::R * (rx * ib - ix * rb), d::R * (ra * ix - ia * rx)]
+
+ coerce(x:%):OutputForm ==
+ re := (r := real x)::OutputForm
+ ie := (i := imag x)::OutputForm
+ zero? i => re
+ outi := "%i"::Symbol::OutputForm
+ ip :=
+-- one? i => outi
+ (i = 1) => outi
+-- one?(-i) => -outi
+ ((-i) = 1) => -outi
+ ie * outi
+ zero? r => ip
+ re + ip
+
+ retract(x:%):R ==
+ not zero?(imag x) =>
+ error "Imaginary part is nonzero. Cannot retract."
+ real x
+
+ retractIfCan(x:%):Union(R, "failed") ==
+ not zero?(imag x) => "failed"
+ real x
+
+ x:% * y:% ==
+ complex(real x * real y - imag x * imag y,
+ imag x * real y + imag y * real x)
+
+ reducedSystem(m:Matrix %):Matrix R ==
+ vertConcat(map(real, m), map(imag, m))
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix R, vec:Vector R) ==
+ rh := reducedSystem(v::Matrix %)@Matrix(R)
+ [reducedSystem(m)@Matrix(R), column(rh, minColIndex rh)]
+
+ if R has RealNumberSystem then
+ abs(x:%):% == (sqrt norm x)::%
+
+ if R has RealConstant then
+ convert(x:%):Complex(DoubleFloat) ==
+ complex(convert(real x)@DoubleFloat,convert(imag x)@DoubleFloat)
+
+ convert(x:%):Complex(Float) ==
+ complex(convert(real x)@Float, convert(imag x)@Float)
+
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm ==
+ convert([convert("complex"::Symbol), convert real x,
+ convert imag x]$List(InputForm))@InputForm
+
+ if R has ConvertibleTo Pattern Integer then
+ convert(x:%):Pattern Integer ==
+ convert(x)$ComplexPattern(Integer, R, %)
+ if R has ConvertibleTo Pattern Float then
+ convert(x:%):Pattern Float ==
+ convert(x)$ComplexPattern(Float, R, %)
+
+ if R has PatternMatchable Integer then
+ patternMatch(x:%, p:Pattern Integer,
+ l:PatternMatchResult(Integer, %)) ==
+ patternMatch(x, p, l)$ComplexPatternMatch(Integer, R, %)
+
+ if R has PatternMatchable Float then
+ patternMatch(x:%, p:Pattern Float,
+ l:PatternMatchResult(Float, %)) ==
+ patternMatch(x, p, l)$ComplexPatternMatch(Float, R, %)
+
+
+ if R has OrderedSet then
+ x < y ==
+ real x = real y => imag x < imag y
+ real x < real y
+
+ if R has IntegerNumberSystem then
+ rational? x == zero? imag x
+
+ rational x ==
+ zero? imag x => rational real x
+ error "Not a rational number"
+
+ rationalIfCan x ==
+ zero? imag x => rational real x
+ "failed"
+
+ if R has Field then
+ inv x ==
+ zero? imag x => (inv real x)::%
+ r := norm x
+ complex(real(x) / r, - imag(x) / r)
+
+ if R has IntegralDomain then
+ _exquo(x:%, r:R) ==
+-- one? r => x
+ (r = 1) => x
+ (r1 := real(x) exquo r) case "failed" => "failed"
+ (r2 := imag(x) exquo r) case "failed" => "failed"
+ complex(r1, r2)
+
+ _exquo(x:%, y:%) ==
+ zero? imag y => x exquo real y
+ x * conjugate(y) exquo norm(y)
+
+ recip(x:%) == 1 exquo x
+
+ if R has OrderedRing then
+ unitNormal x ==
+ zero? x => [1,x,1]
+ (u := recip x) case % => [x, 1, u]
+ zero? real x =>
+ c := unitNormal imag x
+ [complex(0, c.unit), (c.associate * imag x)::%,
+ complex(0, - c.associate)]
+ c := unitNormal real x
+ x := c.associate * x
+ imag x < 0 =>
+ x := complex(- imag x, real x)
+ [- c.unit * imaginary(), x, c.associate * imaginary()]
+ [c.unit ::%, x, c.associate ::%]
+ else
+ unitNormal x ==
+ zero? x => [1,x,1]
+ (u := recip x) case % => [x, 1, u]
+ zero? real x =>
+ c := unitNormal imag x
+ [complex(0, c.unit), (c.associate * imag x)::%,
+ complex(0, - c.associate)]
+ c := unitNormal real x
+ x := c.associate * x
+ [c.unit ::%, x, c.associate ::%]
+
+ if R has EuclideanDomain then
+ if R has additiveValuation then
+ euclideanSize x == max(euclideanSize real x,
+ euclideanSize imag x)
+ else
+ euclideanSize x == euclideanSize(real(x)**2 + imag(x)**2)$R
+ if R has IntegerNumberSystem then
+ x rem y ==
+ zero? imag y =>
+ yr:=real y
+ complex(symmetricRemainder(real(x), yr),
+ symmetricRemainder(imag(x), yr))
+ divide(x, y).remainder
+ x quo y ==
+ zero? imag y =>
+ yr:= real y
+ xr:= real x
+ xi:= imag x
+ complex((xr-symmetricRemainder(xr,yr)) quo yr,
+ (xi-symmetricRemainder(xi,yr)) quo yr)
+ divide(x, y).quotient
+
+ else
+ x rem y ==
+ zero? imag y =>
+ yr:=real y
+ complex(real(x) rem yr,imag(x) rem yr)
+ divide(x, y).remainder
+ x quo y ==
+ zero? imag y => complex(real x quo real y,imag x quo real y)
+ divide(x, y).quotient
+
+ divide(x, y) ==
+ r := norm y
+ y1 := conjugate y
+ xx := x * y1
+ x1 := real(xx) rem r
+ a := x1
+ if x1^=0 and sizeLess?(r, 2 * x1) then
+ a := x1 - r
+ if sizeLess?(x1, a) then a := x1 + r
+ x2 := imag(xx) rem r
+ b := x2
+ if x2^=0 and sizeLess?(r, 2 * x2) then
+ b := x2 - r
+ if sizeLess?(x2, b) then b := x2 + r
+ y1 := (complex(a, b) exquo y1)::%
+ [((x - y1) exquo y)::%, y1]
+
+ if R has TranscendentalFunctionCategory then
+ half := recip(2::R)::R
+
+ if R has RealNumberSystem then
+ atan2loc(y: R, x: R): R ==
+ pi1 := pi()$R
+ pi2 := pi1 * half
+ x = 0 => if y >= 0 then pi2 else -pi2
+
+ -- Atan in (-pi/2,pi/2]
+ theta := atan(y * recip(x)::R)
+ while theta <= -pi2 repeat theta := theta + pi1
+ while theta > pi2 repeat theta := theta - pi1
+
+ x >= 0 => theta -- I or IV
+
+ if y >= 0 then
+ theta + pi1 -- II
+ else
+ theta - pi1 -- III
+
+ argument x == atan2loc(imag x, real x)
+
+ else
+ -- Not ordered so dictate two quadrants
+ argument x ==
+ zero? real x => pi()$R * half
+ atan(imag(x) * recip(real x)::R)
+
+ pi() == pi()$R :: %
+
+ if R is DoubleFloat then
+ stoc ==> S_-TO_-C$Lisp
+ ctos ==> C_-TO_-S$Lisp
+
+ exp x == ctos EXP(stoc x)$Lisp
+ log x == ctos LOG(stoc x)$Lisp
+
+ sin x == ctos SIN(stoc x)$Lisp
+ cos x == ctos COS(stoc x)$Lisp
+ tan x == ctos TAN(stoc x)$Lisp
+ asin x == ctos ASIN(stoc x)$Lisp
+ acos x == ctos ACOS(stoc x)$Lisp
+ atan x == ctos ATAN(stoc x)$Lisp
+
+ sinh x == ctos SINH(stoc x)$Lisp
+ cosh x == ctos COSH(stoc x)$Lisp
+ tanh x == ctos TANH(stoc x)$Lisp
+ asinh x == ctos ASINH(stoc x)$Lisp
+ acosh x == ctos ACOSH(stoc x)$Lisp
+ atanh x == ctos ATANH(stoc x)$Lisp
+
+ else
+ atan x ==
+ ix := imaginary()*x
+ - imaginary() * half * (log(1 + ix) - log(1 - ix))
+
+ log x ==
+ complex(log(norm x) * half, argument x)
+
+ exp x ==
+ e := exp real x
+ complex(e * cos imag x, e * sin imag x)
+
+ cos x ==
+ e := exp(imaginary() * x)
+ half * (e + recip(e)::%)
+
+ sin x ==
+ e := exp(imaginary() * x)
+ - imaginary() * half * (e - recip(e)::%)
+
+ if R has RealNumberSystem then
+ polarCoordinates x ==
+ [sqrt norm x, (negative?(t := argument x) => t + 2 * pi(); t)]
+
+ x:% ** q:Fraction(Integer) ==
+ zero? q =>
+ zero? x => error "0 ** 0 is undefined"
+ 1
+ zero? x => 0
+ rx := real x
+ zero? imag x and positive? rx => (rx ** q)::%
+ zero? imag x and denom q = 2 => complex(0, (-rx)**q)
+ ax := sqrt(norm x) ** q
+ tx := q::R * argument x
+ complex(ax * cos tx, ax * sin tx)
+
+ else if R has RadicalCategory then
+ x:% ** q:Fraction(Integer) ==
+ zero? q =>
+ zero? x => error "0 ** 0 is undefined"
+ 1
+ r := real x
+ zero?(i := imag x) => (r ** q)::%
+ t := numer(q) * recip(denom(q)::R)::R * argument x
+ e:R :=
+ zero? r => i ** q
+ norm(x) ** (q / (2::Fraction(Integer)))
+ complex(e * cos t, e * sin t)
+
+@
+\section{package COMPLPAT ComplexPattern}
+<<package COMPLPAT ComplexPattern>>=
+)abbrev package COMPLPAT ComplexPattern
+++ Author: Barry Trager
+++ Date Created: 30 Nov 1995
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: complex, patterns
+++ References:
+++ Description:
+++ This package supports converting complex expressions to patterns
+ComplexPattern(R, S, CS) : C == T where
+ R: SetCategory
+ S: Join(ConvertibleTo Pattern R, CommutativeRing)
+ CS: ComplexCategory S
+ C == with
+ convert: CS -> Pattern R
+ ++ convert(cs) converts the complex expression cs to a pattern
+
+ T == add
+
+ ipat : Pattern R := patternVariable("%i"::Symbol, true, false, false)
+
+ convert(cs) ==
+ zero? imag cs => convert real cs
+ convert real cs + ipat * convert imag cs
+
+@
+\section{package CPMATCH ComplexPatternMatch}
+<<package CPMATCH ComplexPatternMatch>>=
+)abbrev package CPMATCH ComplexPatternMatch
+++ Author: Barry Trager
+++ Date Created: 30 Nov 1995
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: complex, pattern matching
+++ References:
+++ Description:
+++ This package supports matching patterns involving complex expressions
+ComplexPatternMatch(R, S, CS) : C == T where
+ R: SetCategory
+ S: Join(PatternMatchable R, CommutativeRing)
+ CS: ComplexCategory S
+ PMRS ==> PatternMatchResult(R, CS)
+ PS ==> Polynomial S
+ C == with
+ if PS has PatternMatchable(R) then
+ patternMatch: (CS, Pattern R, PMRS) -> PMRS
+ ++ patternMatch(cexpr, pat, res) matches the pattern pat to the
+ ++ complex expression cexpr. res contains the variables of pat
+ ++ which are already matched and their matches.
+
+ T == add
+
+ import PatternMatchPushDown(R, S, CS)
+ import PatternMatchResultFunctions2(R, PS, CS)
+ import PatternMatchResultFunctions2(R, CS, PS)
+
+ ivar : PS := "%i"::Symbol::PS
+
+ makeComplex(p:PS):CS ==
+ up := univariate p
+ degree up > 1 => error "not linear in %i"
+ icoef:=leadingCoefficient(up)
+ rcoef:=leadingCoefficient(reductum p)
+ complex(rcoef,icoef)
+
+ makePoly(cs:CS):PS == real(cs)*ivar + imag(cs)::PS
+
+ if PS has PatternMatchable(R) then
+ patternMatch(cs, pat, result) ==
+ zero? imag cs =>
+ patternMatch(real cs, pat, result)
+ map(makeComplex,
+ patternMatch(makePoly cs, pat, map(makePoly, result)))
+
+@
+\section{domain COMPLEX Complex}
+<<domain COMPLEX Complex>>=
+)abbrev domain COMPLEX Complex
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype {Complex(R)} creates the domain of elements of the form
+++ \spad{a + b * i} where \spad{a} and b come from the ring R,
+++ and i is a new element such that \spad{i**2 = -1}.
+Complex(R:CommutativeRing): ComplexCategory(R) with
+ if R has OpenMath then OpenMath
+ == add
+ Rep := Record(real:R, imag:R)
+
+ if R has OpenMath then
+ writeOMComplex(dev: OpenMathDevice, x: %): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "complex1", "complex__cartesian")
+ OMwrite(dev, real x)
+ OMwrite(dev, imag x)
+ OMputEndApp(dev)
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMComplex(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMComplex(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMComplex(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMComplex(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ 0 == [0, 0]
+ 1 == [1, 0]
+ zero? x == zero?(x.real) and zero?(x.imag)
+-- one? x == one?(x.real) and zero?(x.imag)
+ one? x == ((x.real) = 1) and zero?(x.imag)
+ coerce(r:R):% == [r, 0]
+ complex(r, i) == [r, i]
+ real x == x.real
+ imag x == x.imag
+ x + y == [x.real + y.real, x.imag + y.imag]
+ -- by re-defining this here, we save 5 fn calls
+ x:% * y:% ==
+ [x.real * y.real - x.imag * y.imag,
+ x.imag * y.real + y.imag * x.real] -- here we save nine!
+
+
+ if R has IntegralDomain then
+ _exquo(x:%, y:%) == -- to correct bad defaulting problem
+ zero? y.imag => x exquo y.real
+ x * conjugate(y) exquo norm(y)
+
+@
+\section{package COMPLEX2 ComplexFunctions2}
+<<package COMPLEX2 ComplexFunctions2>>=
+)abbrev package COMPLEX2 ComplexFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package extends maps from underlying rings to maps between
+++ complex over those rings.
+ComplexFunctions2(R:CommutativeRing, S:CommutativeRing): with
+ map: (R -> S, Complex R) -> Complex S
+ ++ map(f,u) maps f onto real and imaginary parts of u.
+ == add
+ map(fn, gr) == complex(fn real gr, fn imag gr)
+
+@
+\section{package COMPFACT ComplexFactorization}
+<<package COMPFACT ComplexFactorization>>=
+)abbrev package COMPFACT ComplexFactorization
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Complex, UnivariatePolynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords: complex, polynomial factorization, factor
+++ References:
+ComplexFactorization(RR,PR) : C == T where
+ RR : EuclideanDomain -- R is Z or Q
+ PR : UnivariatePolynomialCategory Complex RR
+ R ==> Complex RR
+ I ==> Integer
+ RN ==> Fraction I
+ GI ==> Complex I
+ GRN ==> Complex RN
+
+
+ C == with
+
+ factor : PR -> Factored PR
+ ++ factor(p) factorizes the polynomial p with complex coefficients.
+
+ T == add
+ SUP ==> SparseUnivariatePolynomial
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FF ==> Record(flg:fUnion, fctr:PR, xpnt:Integer)
+ SAEF := SimpleAlgebraicExtensionAlgFactor(SUP RN,GRN,SUP GRN)
+ UPCF2 := UnivariatePolynomialCategoryFunctions2(R,PR,GRN,SUP GRN)
+ UPCFB := UnivariatePolynomialCategoryFunctions2(GRN,SUP GRN,R,PR)
+
+ myMap(r:R) : GRN ==
+ R is GI =>
+ cr :GI := r pretend GI
+ complex((real cr)::RN,(imag cr)::RN)
+ R is GRN => r pretend GRN
+
+ compND(cc:GRN):Record(cnum:GI,cden:Integer) ==
+ ccr:=real cc
+ cci:=imag cc
+ dccr:=denom ccr
+ dcci:=denom cci
+ ccd:=lcm(dccr,dcci)
+ [complex(((ccd exquo dccr)::Integer)*numer ccr,
+ ((ccd exquo dcci)::Integer)*numer cci),ccd]
+
+ conv(f:SUP GRN) :Record(convP:SUP GI, convD:RN) ==
+ pris:SUP GI :=0
+ dris:Integer:=1
+ dris1:Integer:=1
+ pdris:Integer:=1
+ for i in 0..(degree f) repeat
+ (cf:= coefficient(f,i)) = 0 => "next i"
+ cdf:=compND cf
+ dris:=lcm(cdf.cden,dris1)
+ pris:=((dris exquo dris1)::Integer)*pris +
+ ((dris exquo cdf.cden)::Integer)*
+ monomial(cdf.cnum,i)$(SUP GI)
+ dris1:=dris
+ [pris,dris::RN]
+
+ backConv(ffr:Factored SUP GRN) : Factored PR ==
+ R is GRN =>
+ makeFR((unit ffr) pretend PR,[[f.flg,(f.fctr) pretend PR,f.xpnt]
+ for f in factorList ffr])
+ R is GI =>
+ const:=unit ffr
+ ris: List FF :=[]
+ for ff in factorList ffr repeat
+ fact:=primitivePart(conv(ff.fctr).convP)
+ expf:=ff.xpnt
+ ris:=cons([ff.flg,fact pretend PR,expf],ris)
+ lc:GRN := myMap leadingCoefficient(fact pretend PR)
+ const:= const*(leadingCoefficient(ff.fctr)/lc)**expf
+ uconst:GI:= compND(coefficient(const,0)).cnum
+ makeFR((uconst pretend R)::PR,ris)
+
+
+ factor(pol : PR) : Factored PR ==
+ ratPol:SUP GRN := 0
+ ratPol:=map(myMap,pol)$UPCF2
+ ffr:=factor ratPol
+ backConv ffr
+
+@
+\section{package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation}
+<<package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation>>=
+)abbrev package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation
+++ Author: James Davenport
+++ Date Created: 1990
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides the generalized euclidean algorithm which is
+++ needed as the basic step for factoring polynomials.
+ComplexIntegerSolveLinearPolynomialEquation(R,CR): C == T
+ where
+ CP ==> SparseUnivariatePolynomial CR
+ R:IntegerNumberSystem
+ CR:ComplexCategory(R)
+ C == with
+ solveLinearPolynomialEquation: (List CP,CP) -> Union(List CP,"failed")
+ ++ solveLinearPolynomialEquation([f1, ..., fn], g)
+ ++ where (fi relatively prime to each other)
+ ++ returns a list of ai such that
+ ++ g = sum ai prod fj (j \= i) or
+ ++ equivalently g/prod fj = sum (ai/fi)
+ ++ or returns "failed" if no such list exists
+ T == add
+ oldlp:List CP := []
+ slpePrime:R:=(2::R)
+ oldtable:Vector List CP := empty()
+ solveLinearPolynomialEquation(lp,p) ==
+ if (oldlp ^= lp) then
+ -- we have to generate a new table
+ deg:= _+/[degree u for u in lp]
+ ans:Union(Vector List CP,"failed"):="failed"
+ slpePrime:=67108859::R -- 2**26 -5 : a prime
+ -- a good test case for this package is
+ -- (good question?)
+ while (ans case "failed") repeat
+ ans:=tablePow(deg,complex(slpePrime,0),lp)$GenExEuclid(CR,CP)
+ if (ans case "failed") then
+ slpePrime:= slpePrime-4::R
+ while not prime?(slpePrime)$IntegerPrimesPackage(R) repeat
+ slpePrime:= slpePrime-4::R
+ oldtable:=(ans:: Vector List CP)
+ answer:=solveid(p,complex(slpePrime,0),oldtable)
+ answer
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category COMPCAT ComplexCategory>>
+<<package COMPLPAT ComplexPattern>>
+<<package CPMATCH ComplexPatternMatch>>
+<<domain COMPLEX Complex>>
+<<package COMPLEX2 ComplexFunctions2>>
+<<package COMPFACT ComplexFactorization>>
+<<package CINTSLPE ComplexIntegerSolveLinearPolynomialEquation>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gb.spad.pamphlet b/src/algebra/gb.spad.pamphlet
new file mode 100644
index 00000000..e62ca71f
--- /dev/null
+++ b/src/algebra/gb.spad.pamphlet
@@ -0,0 +1,211 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gb.spad}
+\author{Rudiger Gebauer, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+--------- GROEBNER PACKAGE DRAFT 06 12/01/1986
+---------
+--------- Example to call groebner:
+---------
+--------- s1:DMP[w,p,z,t,s,b]RN:= 45*p + 35*s - 165*b - 36
+--------- s2:DMP[w,p,z,t,s,b]RN:= 35*p + 40*z + 25*t - 27*s
+--------- s3:DMP[w,p,z,t,s,b]RN:= 15*w + 25*p*s + 30*z - 18*t - 165*b**2
+--------- s4:DMP[w,p,z,t,s,b]RN:= -9*w + 15*p*t + 20*z*s
+--------- s5:DMP[w,p,z,t,s,b]RN:= w*p + 2*z*t - 11*b**3
+--------- s6:DMP[w,p,z,t,s,b]RN:= 99*w - 11*b*s + 3*b**2
+--------- s7:DMP[w,p,z,t,s,b]RN:= b**2 + 33/50*b + 2673/10000
+---------
+--------- sn7:=[s1,s2,s3,s4,s5,s6,s7]
+---------
+--------- groebner(sn7,info)
+---------
+-------------------------------------------------------------------------
+---------
+--------- groebner -> calculate minimal Groebner Basis
+---------
+--------- all reductions are TOTAL reductions
+---------
+--------- use string " redcrit " and you get the reduced critpairs
+--------- printed
+---------
+--------- use string " info " and you get information about
+---------
+--------- ci => Leading monomial for critpair calculation
+--------- tci => Number of terms of polynomial i
+--------- cj => Leading monomial for critpair calculation
+--------- tcj => Number of terms of polynomial j
+--------- c => Leading monomial of critpair polynomial
+--------- tc => Number of terms of critpair polynomial
+--------- rc => Leading monomial of redcritpair polynomial
+--------- trc => Number of terms of redcritpair polynomial
+--------- tF => Number of polynomials in reduction list F
+--------- tD => Number of critpairs still to do
+---------
+\end{verbatim}
+\section{package GB GroebnerPackage}
+<<package GB GroebnerPackage>>=
+)abbrev package GB GroebnerPackage
+++ Authors: Gebauer, Trager
+++ Date Created: 12-1-86
+++ Date Last Updated: 2-28-91
+++ Basic Functions: groebner normalForm
+++ Related Constructors: Ideal, IdealDecompositionPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords: groebner basis, polynomial ideal
+++ References:
+++ Description: \spadtype{GroebnerPackage} computes groebner
+++ bases for polynomial ideals. The basic computation provides
+++ a distinguished set of generators for polynomial ideals over fields.
+++ This basis allows an easy test for membership: the operation \spadfun{normalForm}
+++ returns zero on ideal members. When the provided coefficient domain, Dom,
+++ is not a field, the result is equivalent to considering the extended
+++ ideal with \spadtype{Fraction(Dom)} as coefficients, but considerably more efficient
+++ since all calculations are performed in Dom. Additional argument "info" and "redcrit"
+++ can be given to provide incremental information during
+++ computation. Argument "info" produces a computational summary for each s-polynomial.
+++ Argument "redcrit" prints out the reduced critical pairs. The term ordering
+++ is determined by the polynomial type used. Suggested types include
+++ \spadtype{DistributedMultivariatePolynomial},
+++ \spadtype{HomogeneousDistributedMultivariatePolynomial},
+++ \spadtype{GeneralDistributedMultivariatePolynomial}.
+
+GroebnerPackage(Dom, Expon, VarSet, Dpol): T == C where
+
+ Dom: GcdDomain
+ Expon: OrderedAbelianMonoidSup
+ VarSet: OrderedSet
+ Dpol: PolynomialCategory(Dom, Expon, VarSet)
+
+ T== with
+
+ groebner: List(Dpol) -> List(Dpol)
+ ++ groebner(lp) computes a groebner basis for a polynomial ideal
+ ++ generated by the list of polynomials lp.
+ groebner: ( List(Dpol), String ) -> List(Dpol)
+ ++ groebner(lp, infoflag) computes a groebner basis
+ ++ for a polynomial ideal
+ ++ generated by the list of polynomials lp.
+ ++ Argument infoflag is used to get information on the computation.
+ ++ If infoflag is "info", then summary information
+ ++ is displayed for each s-polynomial generated.
+ ++ If infoflag is "redcrit", the reduced critical pairs are displayed.
+ ++ If infoflag is any other string, no information is printed during computation.
+ groebner: ( List(Dpol), String, String ) -> List(Dpol)
+ ++ groebner(lp, "info", "redcrit") computes a groebner basis
+ ++ for a polynomial ideal generated by the list of polynomials lp,
+ ++ displaying both a summary of the critical pairs considered ("info")
+ ++ and the result of reducing each critical pair ("redcrit").
+ ++ If the second or third arguments have any other string value,
+ ++ the indicated information is suppressed.
+
+ if Dom has Field then
+ normalForm: (Dpol, List(Dpol)) -> Dpol
+ ++ normalForm(poly,gb) reduces the polynomial poly modulo the
+ ++ precomputed groebner basis gb giving a canonical representative
+ ++ of the residue class.
+ C== add
+ import OutputForm
+ import GroebnerInternalPackage(Dom,Expon,VarSet,Dpol)
+
+ if Dom has Field then
+ monicize(p: Dpol):Dpol ==
+-- one?(lc := leadingCoefficient p) => p
+ ((lc := leadingCoefficient p) = 1) => p
+ inv(lc)*p
+
+ normalForm(p : Dpol, l : List(Dpol)) : Dpol ==
+ redPol(p,map(monicize,l))
+
+ ------ MAIN ALGORITHM GROEBNER ------------------------
+
+ groebner( Pol: List(Dpol) ) ==
+ Pol=[] => Pol
+ Pol:=[x for x in Pol | x ^= 0]
+ Pol=[] => [0]
+ minGbasis(sort( degree #1 > degree #2, gbasis(Pol,0,0)))
+
+ groebner( Pol: List(Dpol), xx1: String) ==
+ Pol=[] => Pol
+ Pol:=[x for x in Pol | x ^= 0]
+ Pol=[] => [0]
+ xx1 = "redcrit" =>
+ minGbasis(sort( degree #1 > degree #2, gbasis(Pol,1,0)))
+ xx1 = "info" =>
+ minGbasis(sort( degree #1 > degree #2, gbasis(Pol,2,1)))
+ messagePrint(" ")
+ messagePrint("WARNING: options are - redcrit and/or info - ")
+ messagePrint(" you didn't type them correct")
+ messagePrint(" please try again")
+ messagePrint(" ")
+ []
+
+ groebner( Pol: List(Dpol), xx1: String, xx2: String) ==
+ Pol=[] => Pol
+ Pol:=[x for x in Pol | x ^= 0]
+ Pol=[] => [0]
+ (xx1 = "redcrit" and xx2 = "info") or
+ (xx1 = "info" and xx2 = "redcrit") =>
+ minGbasis(sort( degree #1 > degree #2, gbasis(Pol,1,1)))
+ xx1 = "redcrit" and xx2 = "redcrit" =>
+ minGbasis(sort( degree #1 > degree #2, gbasis(Pol,1,0)))
+ xx1 = "info" and xx2 = "info" =>
+ minGbasis(sort( degree #1 > degree #2, gbasis(Pol,2,1)))
+ messagePrint(" ")
+ messagePrint("WARNING: options are - redcrit and/or info - ")
+ messagePrint(" you didn't type them correctly")
+ messagePrint(" please try again ")
+ messagePrint(" ")
+ []
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GB GroebnerPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gbeuclid.spad.pamphlet b/src/algebra/gbeuclid.spad.pamphlet
new file mode 100644
index 00000000..0ff28e44
--- /dev/null
+++ b/src/algebra/gbeuclid.spad.pamphlet
@@ -0,0 +1,596 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gbeuclid.spad}
+\author{Rudiger Gebauer, Michael Moeller}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+--------- EUCLIDEAN GROEBNER BASIS PACKAGE ---------------
+---------
+---------- version 12.01.1986
+---------
+--------- Example to call euclideanGroebner:
+---------
+--------- a1:DMP[y,x]I:= (9*x**2 + 5*x - 3)+ y*(3*x**2 + 2*x + 1)
+--------- a2:DMP[y,x]I:= (6*x**3 - 2*x**2 - 3*x +3) + y*(2*x**3 - x - 1)
+--------- a3:DMP[y,x]I:= (3*x**3 + 2*x**2) + y*(x**3 + x**2)
+---------
+--------- an:=[a1,a2,a3]
+---------
+--------- euclideanGroebner(an,info)
+---------
+-------------------------------------------------------------------------
+---------
+--------- euclideanGroebner -> calculate weak euclGbasis
+---------
+--------- all reductions are TOTAL reductions
+---------
+--------- use string " redcrit " and you get the reduced critpairs
+--------- printed
+---------
+--------- use string " info " and you get information about
+---------
+--------- ci => Leading monomial for critpair calculation
+--------- tci => Number of terms of polynomial i
+--------- cj => Leading monomial for critpair calculation
+--------- tcj => Number of terms of polynomial j
+--------- c => Leading monomial of critpair polynomial
+--------- tc => Number of terms of critpair polynomial
+--------- rc => Leading monomial of redcritpair polynomial
+--------- trc => Number of terms of redcritpair polynomial
+--------- tH => Number of polynomials in reduction list H
+--------- tD => Number of critpairs still to do
+---------
+\end{verbatim}
+\section{package GBEUCLID EuclideanGroebnerBasisPackage}
+<<package GBEUCLID EuclideanGroebnerBasisPackage>>=
+)abbrev package GBEUCLID EuclideanGroebnerBasisPackage
+++ Authors: Gebauer, Moeller
+++ Date Created: 12-1-86
+++ Date Last Updated: 2-28-91
+++ Basic Functions:
+++ Related Constructors: Ideal, IdealDecompositionPackage, GroebnerPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords: groebner basis, polynomial ideal, euclidean domain
+++ References:
+++ Description: \spadtype{EuclideanGroebnerBasisPackage} computes groebner
+++ bases for polynomial ideals over euclidean domains.
+++ The basic computation provides
+++ a distinguished set of generators for these ideals.
+++ This basis allows an easy test for membership: the operation
+++ \spadfun{euclideanNormalForm} returns zero on ideal members. The string
+++ "info" and "redcrit" can be given as additional args to provide
+++ incremental information during the computation. If "info" is given,
+++ a computational summary is given for each s-polynomial. If "redcrit"
+++ is given, the reduced critical pairs are printed. The term ordering
+++ is determined by the polynomial type used. Suggested types include
+++ \spadtype{DistributedMultivariatePolynomial},
+++ \spadtype{HomogeneousDistributedMultivariatePolynomial},
+++ \spadtype{GeneralDistributedMultivariatePolynomial}.
+
+EuclideanGroebnerBasisPackage(Dom, Expon, VarSet, Dpol): T == C where
+
+ Dom: EuclideanDomain
+ Expon: OrderedAbelianMonoidSup
+ VarSet: OrderedSet
+ Dpol: PolynomialCategory(Dom, Expon, VarSet)
+
+ T== with
+
+ euclideanNormalForm: (Dpol, List(Dpol) ) -> Dpol
+ ++ euclideanNormalForm(poly,gb) reduces the polynomial poly modulo the
+ ++ precomputed groebner basis gb giving a canonical representative
+ ++ of the residue class.
+ euclideanGroebner: List(Dpol) -> List(Dpol)
+ ++ euclideanGroebner(lp) computes a groebner basis for a polynomial ideal
+ ++ over a euclidean domain generated by the list of polynomials lp.
+ euclideanGroebner: (List(Dpol), String) -> List(Dpol)
+ ++ euclideanGroebner(lp, infoflag) computes a groebner basis
+ ++ for a polynomial ideal over a euclidean domain
+ ++ generated by the list of polynomials lp.
+ ++ During computation, additional information is printed out
+ ++ if infoflag is given as
+ ++ either "info" (for summary information) or
+ ++ "redcrit" (for reduced critical pairs)
+ euclideanGroebner: (List(Dpol), String, String ) -> List(Dpol)
+ ++ euclideanGroebner(lp, "info", "redcrit") computes a groebner basis
+ ++ for a polynomial ideal generated by the list of polynomials lp.
+ ++ If the second argument is "info", a summary is given of the critical pairs.
+ ++ If the third argument is "redcrit", critical pairs are printed.
+ C== add
+ Ex ==> OutputForm
+ lc ==> leadingCoefficient
+ red ==> reductum
+
+ import OutputForm
+
+ ------ Definition list of critPair
+ ------ lcmfij is now lcm of headterm of poli and polj
+ ------ lcmcij is now lcm of of lc poli and lc polj
+
+ critPair ==>Record(lcmfij: Expon, lcmcij: Dom, poli:Dpol, polj: Dpol )
+ Prinp ==> Record( ci:Dpol,tci:Integer,cj:Dpol,tcj:Integer,c:Dpol,
+ tc:Integer,rc:Dpol,trc:Integer,tH:Integer,tD:Integer)
+
+ ------ Definition of intermediate functions
+
+ strongGbasis: (List(Dpol), Integer, Integer) -> List(Dpol)
+ eminGbasis: List(Dpol) -> List(Dpol)
+ ecritT: (critPair ) -> Boolean
+ ecritM: (Expon, Dom, Expon, Dom) -> Boolean
+ ecritB: (Expon, Dom, Expon, Dom, Expon, Dom) -> Boolean
+ ecrithinH: (Dpol, List(Dpol)) -> Boolean
+ ecritBonD: (Dpol, List(critPair)) -> List(critPair)
+ ecritMTondd1:(List(critPair)) -> List(critPair)
+ ecritMondd1:(Expon, Dom, List(critPair)) -> List(critPair)
+ crithdelH: (Dpol, List(Dpol)) -> List(Dpol)
+ eupdatF: (Dpol, List(Dpol) ) -> List(Dpol)
+ updatH: (Dpol, List(Dpol), List(Dpol), List(Dpol) ) -> List(Dpol)
+ sortin: (Dpol, List(Dpol) ) -> List(Dpol)
+ eRed: (Dpol, List(Dpol), List(Dpol) ) -> Dpol
+ ecredPol: (Dpol, List(Dpol) ) -> Dpol
+ esPol: (critPair) -> Dpol
+ updatD: (List(critPair), List(critPair)) -> List(critPair)
+ lepol: Dpol -> Integer
+ prinshINFO : Dpol -> Void
+ prindINFO: (critPair, Dpol, Dpol,Integer,Integer,Integer) -> Integer
+ prinpolINFO: List(Dpol) -> Void
+ prinb: Integer -> Void
+
+ ------ MAIN ALGORITHM GROEBNER ------------------------
+ euclideanGroebner( Pol: List(Dpol) ) ==
+ eminGbasis(strongGbasis(Pol,0,0))
+
+ euclideanGroebner( Pol: List(Dpol), xx1: String) ==
+ xx1 = "redcrit" =>
+ eminGbasis(strongGbasis(Pol,1,0))
+ xx1 = "info" =>
+ eminGbasis(strongGbasis(Pol,2,1))
+ print(" "::Ex)
+ print("WARNING: options are - redcrit and/or info - "::Ex)
+ print(" you didn't type them correct"::Ex)
+ print(" please try again"::Ex)
+ print(" "::Ex)
+ []
+
+ euclideanGroebner( Pol: List(Dpol), xx1: String, xx2: String) ==
+ (xx1 = "redcrit" and xx2 = "info") or
+ (xx1 = "info" and xx2 = "redcrit") =>
+ eminGbasis(strongGbasis(Pol,1,1))
+ xx1 = "redcrit" and xx2 = "redcrit" =>
+ eminGbasis(strongGbasis(Pol,1,0))
+ xx1 = "info" and xx2 = "info" =>
+ eminGbasis(strongGbasis(Pol,2,1))
+ print(" "::Ex)
+ print("WARNING: options are - redcrit and/or info - "::Ex)
+ print(" you didn't type them correct"::Ex)
+ print(" please try again "::Ex)
+ print(" "::Ex)
+ []
+
+ ------ calculate basis
+
+ strongGbasis(Pol: List(Dpol),xx1: Integer, xx2: Integer ) ==
+ dd1, D : List(critPair)
+
+ --------- create D and Pol
+
+ Pol1:= sort( (degree #1 > degree #2) or
+ ((degree #1 = degree #2 ) and
+ sizeLess?(leadingCoefficient #2,leadingCoefficient #1)),
+ Pol)
+ Pol:= [first(Pol1)]
+ H:= Pol
+ Pol1:= rest(Pol1)
+ D:= nil
+ while ^null Pol1 repeat
+ h:= first(Pol1)
+ Pol1:= rest(Pol1)
+ en:= degree(h)
+ lch:= lc h
+ dd1:= [[sup(degree(x), en), lcm(leadingCoefficient x, lch), x, h]$critPair
+ for x in Pol]
+ D:= updatD(ecritMTondd1(sort((#1.lcmfij < #2.lcmfij) or
+ (( #1.lcmfij = #2.lcmfij ) and
+ ( sizeLess?(#1.lcmcij,#2.lcmcij)) ),
+ dd1)), ecritBonD(h,D))
+ Pol:= cons(h, eupdatF(h, Pol))
+ ((en = degree(first(H))) and (leadingCoefficient(h) = leadingCoefficient(first(H)) ) ) =>
+ " go to top of while "
+ H:= updatH(h,H,crithdelH(h,H),[h])
+ H:= sort((degree #1 > degree #2) or
+ ((degree #1 = degree #2 ) and
+ sizeLess?(leadingCoefficient #2,leadingCoefficient #1)), H)
+ D:= sort((#1.lcmfij < #2.lcmfij) or
+ (( #1.lcmfij = #2.lcmfij ) and
+ ( sizeLess?(#1.lcmcij,#2.lcmcij)) ) ,D)
+ xx:= xx2
+
+ -------- loop
+
+ while ^null D repeat
+ D0:= first D
+ ep:=esPol(D0)
+ D:= rest(D)
+ eh:= ecredPol(eRed(ep,H,H),H)
+ if xx1 = 1 then
+ prinshINFO(eh)
+ eh = 0 =>
+ if xx2 = 1 then
+ ala:= prindINFO(D0,ep,eh,#H, #D, xx)
+ xx:= 2
+ " go to top of while "
+ eh := unitCanonical eh
+ e:= degree(eh)
+ leh:= lc eh
+ dd1:= [[sup(degree(x), e), lcm(leadingCoefficient x, leh), x, eh]$critPair
+ for x in Pol]
+ D:= updatD(ecritMTondd1(sort( (#1.lcmfij <
+ #2.lcmfij) or (( #1.lcmfij = #2.lcmfij ) and
+ ( sizeLess?(#1.lcmcij,#2.lcmcij)) ), dd1)), ecritBonD(eh,D))
+ Pol:= cons(eh,eupdatF(eh,Pol))
+ ^ecrithinH(eh,H) or
+ ((e = degree(first(H))) and (leadingCoefficient(eh) = leadingCoefficient(first(H)) ) ) =>
+ if xx2 = 1 then
+ ala:= prindINFO(D0,ep,eh,#H, #D, xx)
+ xx:= 2
+ " go to top of while "
+ H:= updatH(eh,H,crithdelH(eh,H),[eh])
+ H:= sort( (degree #1 > degree #2) or
+ ((degree #1 = degree #2 ) and
+ sizeLess?(leadingCoefficient #2,leadingCoefficient #1)), H)
+ if xx2 = 1 then
+ ala:= prindINFO(D0,ep,eh,#H, #D, xx)
+ xx:= 2
+ " go to top of while "
+ if xx2 = 1 then
+ prinpolINFO(Pol)
+ print(" THE GROEBNER BASIS over EUCLIDEAN DOMAIN"::Ex)
+ if xx1 = 1 and xx2 ^= 1 then
+ print(" THE GROEBNER BASIS over EUCLIDEAN DOMAIN"::Ex)
+ H
+
+ --------------------------------------
+
+ --- erase multiple of e in D2 using crit M
+
+ ecritMondd1(e: Expon, c: Dom, D2: List(critPair))==
+ null D2 => nil
+ x:= first(D2)
+ ecritM(e,c, x.lcmfij, lcm(leadingCoefficient(x.poli), leadingCoefficient(x.polj)))
+ => ecritMondd1(e, c, rest(D2))
+ cons(x, ecritMondd1(e, c, rest(D2)))
+
+ -------------------------------
+
+ ecredPol(h: Dpol, F: List(Dpol) ) ==
+ h0:Dpol:= 0
+ null F => h
+ while h ^= 0 repeat
+ h0:= h0 + monomial(leadingCoefficient(h),degree(h))
+ h:= eRed(red(h), F, F)
+ h0
+ ----------------------------
+
+ --- reduce dd1 using crit T and crit M
+
+ ecritMTondd1(dd1: List(critPair))==
+ null dd1 => nil
+ f1:= first(dd1)
+ s1:= #(dd1)
+ cT1:= ecritT(f1)
+ s1= 1 and cT1 => nil
+ s1= 1 => dd1
+ e1:= f1.lcmfij
+ r1:= rest(dd1)
+ f2:= first(r1)
+ e1 = f2.lcmfij and f1.lcmcij = f2.lcmcij =>
+ cT1 => ecritMTondd1(cons(f1, rest(r1)))
+ ecritMTondd1(r1)
+ dd1 := ecritMondd1(e1, f1.lcmcij, r1)
+ cT1 => ecritMTondd1(dd1)
+ cons(f1, ecritMTondd1(dd1))
+
+ -----------------------------
+
+ --- erase elements in D fullfilling crit B
+
+ ecritBonD(h:Dpol, D: List(critPair))==
+ null D => nil
+ x:= first(D)
+ x1:= x.poli
+ x2:= x.polj
+ ecritB(degree(h), leadingCoefficient(h), degree(x1),leadingCoefficient(x1),degree(x2),leadingCoefficient(x2)) =>
+ ecritBonD(h, rest(D))
+ cons(x, ecritBonD(h, rest(D)))
+
+ -----------------------------
+
+ --- concat F and h and erase multiples of h in F
+
+ eupdatF(h: Dpol, F: List(Dpol)) ==
+ null F => nil
+ f1:= first(F)
+ ecritM(degree h, leadingCoefficient(h), degree f1, leadingCoefficient(f1))
+ => eupdatF(h, rest(F))
+ cons(f1, eupdatF(h, rest(F)))
+
+ -----------------------------
+ --- concat H and h and erase multiples of h in H
+
+ updatH(h: Dpol, H: List(Dpol), Hh: List(Dpol), Hhh: List(Dpol)) ==
+ null H => append(Hh,Hhh)
+ h1:= first(H)
+ hlcm:= sup(degree(h1), degree(h))
+ plc:= extendedEuclidean(leadingCoefficient(h), leadingCoefficient(h1))
+ hp:= monomial(plc.coef1,subtractIfCan(hlcm, degree(h))::Expon)*h +
+ monomial(plc.coef2,subtractIfCan(hlcm, degree(h1))::Expon)*h1
+ (ecrithinH(hp, Hh) and ecrithinH(hp, Hhh)) =>
+ hpp:= append(rest(H),Hh)
+ hp:= ecredPol(eRed(hp,hpp,hpp),hpp)
+ updatH(h, rest(H), crithdelH(hp,Hh),cons(hp,crithdelH(hp,Hhh)))
+ updatH(h, rest(H), Hh,Hhh)
+
+ --------------------------------------------------
+ ---- delete elements in cons(h,H)
+
+ crithdelH(h: Dpol, H: List(Dpol))==
+ null H => nil
+ h1:= first(H)
+ dh1:= degree h1
+ dh:= degree h
+ ecritM(dh, lc h, dh1, lc h1) => crithdelH(h, rest(H))
+ dh1 = sup(dh,dh1) =>
+ plc:= extendedEuclidean( lc h1, lc h)
+ cons(plc.coef1*h1 + monomial(plc.coef2,subtractIfCan(dh1,dh)::Expon)*h,
+ crithdelH(h,rest(H)))
+ cons(h1, crithdelH(h,rest(H)))
+
+ eminGbasis(F: List(Dpol)) ==
+ null F => nil
+ newbas := eminGbasis rest F
+ cons(ecredPol( first(F), newbas),newbas)
+
+ ------------------------------------------------
+ --- does h belong to H
+
+ ecrithinH(h: Dpol, H: List(Dpol))==
+ null H => true
+ h1:= first(H)
+ ecritM(degree h1, lc h1, degree h, lc h) => false
+ ecrithinH(h, rest(H))
+
+ -----------------------------
+ --- calculate euclidean S-polynomial of a critical pair
+
+ esPol(p:critPair)==
+ Tij := p.lcmfij
+ fi := p.poli
+ fj := p.polj
+ lij:= lcm(leadingCoefficient(fi), leadingCoefficient(fj))
+ red(fi)*monomial((lij exquo leadingCoefficient(fi))::Dom,
+ subtractIfCan(Tij, degree fi)::Expon) -
+ red(fj)*monomial((lij exquo leadingCoefficient(fj))::Dom,
+ subtractIfCan(Tij, degree fj)::Expon)
+
+ ----------------------------
+
+ --- euclidean reduction mod F
+
+ eRed(s: Dpol, H: List(Dpol), Hh: List(Dpol)) ==
+ ( s = 0 or null H ) => s
+ f1:= first(H)
+ ds:= degree s
+ lf1:= leadingCoefficient(f1)
+ ls:= leadingCoefficient(s)
+ e: Union(Expon, "failed")
+ (((e:= subtractIfCan(ds, degree f1)) case "failed" ) or sizeLess?(ls, lf1) ) =>
+ eRed(s, rest(H), Hh)
+ sdf1:= divide(ls, lf1)
+ q1:= sdf1.quotient
+ sdf1.remainder = 0 =>
+ eRed(red(s) - monomial(q1,e)*reductum(f1), Hh, Hh)
+ eRed(s -(monomial(q1, e)*f1), rest(H), Hh)
+
+ ----------------------------
+
+ --- crit T true, if e1 and e2 are disjoint
+
+ ecritT(p: critPair) ==
+ pi:= p.poli
+ pj:= p.polj
+ ci:= lc pi
+ cj:= lc pj
+ (p.lcmfij = degree pi + degree pj) and (p.lcmcij = ci*cj)
+
+ ----------------------------
+
+ --- crit M - true, if lcm#2 multiple of lcm#1
+
+ ecritM(e1: Expon, c1: Dom, e2: Expon, c2: Dom) ==
+ en: Union(Expon, "failed")
+ ((en:=subtractIfCan(e2, e1)) case "failed") or
+ ((c2 exquo c1) case "failed") => false
+ true
+ ----------------------------
+
+ --- crit B - true, if eik is a multiple of eh and eik ^equal
+ --- lcm(eh,ei) and eik ^equal lcm(eh,ek)
+
+ ecritB(eh:Expon, ch: Dom, ei:Expon, ci: Dom, ek:Expon, ck: Dom) ==
+ eik:= sup(ei, ek)
+ cik:= lcm(ci, ck)
+ ecritM(eh, ch, eik, cik) and
+ ^ecritM(eik, cik, sup(ei, eh), lcm(ci, ch)) and
+ ^ecritM(eik, cik, sup(ek, eh), lcm(ck, ch))
+
+ -------------------------------
+
+ --- reduce p1 mod lp
+
+ euclideanNormalForm(p1: Dpol, lp: List(Dpol))==
+ eRed(p1, lp, lp)
+
+ ---------------------------------
+
+ --- insert element in sorted list
+
+ sortin(p1: Dpol, lp: List(Dpol))==
+ null lp => [p1]
+ f1:= first(lp)
+ elf1:= degree(f1)
+ ep1:= degree(p1)
+ ((elf1 < ep1) or ((elf1 = ep1) and
+ sizeLess?(leadingCoefficient(f1),leadingCoefficient(p1)))) =>
+ cons(f1,sortin(p1, rest(lp)))
+ cons(p1,lp)
+
+ updatD(D1: List(critPair), D2: List(critPair)) ==
+ null D1 => D2
+ null D2 => D1
+ dl1:= first(D1)
+ dl2:= first(D2)
+ (dl1.lcmfij < dl2.lcmfij) => cons(dl1, updatD(D1.rest, D2))
+ cons(dl2, updatD(D1, D2.rest))
+
+ ---- calculate number of terms of polynomial
+
+ lepol(p1:Dpol)==
+ n: Integer
+ n:= 0
+ while p1 ^= 0 repeat
+ n:= n + 1
+ p1:= red(p1)
+ n
+
+ ---- print blanc lines
+
+ prinb(n: Integer)==
+ for i in 1..n repeat messagePrint(" ")
+
+ ---- print reduced critpair polynom
+
+ prinshINFO(h: Dpol)==
+ prinb(2)
+ messagePrint(" reduced Critpair - Polynom :")
+ prinb(2)
+ print(h::Ex)
+ prinb(2)
+
+ -------------------------------
+
+ ---- print info string
+
+ prindINFO(cp: critPair, ps: Dpol, ph: Dpol, i1:Integer,
+ i2:Integer, n:Integer) ==
+ ll: List Prinp
+ a: Dom
+ cpi:= cp.poli
+ cpj:= cp.polj
+ if n = 1 then
+ prinb(1)
+ messagePrint("you choose option -info- ")
+ messagePrint("abbrev. for the following information strings are")
+ messagePrint(" ci => Leading monomial for critpair calculation")
+ messagePrint(" tci => Number of terms of polynomial i")
+ messagePrint(" cj => Leading monomial for critpair calculation")
+ messagePrint(" tcj => Number of terms of polynomial j")
+ messagePrint(" c => Leading monomial of critpair polynomial")
+ messagePrint(" tc => Number of terms of critpair polynomial")
+ messagePrint(" rc => Leading monomial of redcritpair polynomial")
+ messagePrint(" trc => Number of terms of redcritpair polynomial")
+ messagePrint(" tF => Number of polynomials in reduction list F")
+ messagePrint(" tD => Number of critpairs still to do")
+ prinb(4)
+ n:= 2
+ prinb(1)
+ a:= 1
+ ph = 0 =>
+ ps = 0 =>
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),monomial(a,degree(cpj)),
+ lepol(cpj),ps,0,ph,0,i1,i2]$Prinp]
+ print(ll::Ex)
+ prinb(1)
+ n
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),lepol(cpj),monomial(a,degree(ps)),
+ lepol(ps), ph,0,i1,i2]$Prinp]
+ print(ll::Ex)
+ prinb(1)
+ n
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),lepol(cpj),monomial(a,degree(ps)),
+ lepol(ps),monomial(a,degree(ph)),lepol(ph),i1,i2]$Prinp]
+ print(ll::Ex)
+ prinb(1)
+ n
+
+ -------------------------------
+
+ ---- print the groebner basis polynomials
+
+ prinpolINFO(pl: List(Dpol))==
+ n:Integer
+ n:= #pl
+ prinb(1)
+ n = 1 =>
+ print(" There is 1 Groebner Basis Polynomial "::Ex)
+ prinb(2)
+ print(" There are "::Ex)
+ prinb(1)
+ print(n::Ex)
+ prinb(1)
+ print(" Groebner Basis Polynomials. "::Ex)
+ prinb(2)
+
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GBEUCLID EuclideanGroebnerBasisPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gbintern.spad.pamphlet b/src/algebra/gbintern.spad.pamphlet
new file mode 100644
index 00000000..1ba941b2
--- /dev/null
+++ b/src/algebra/gbintern.spad.pamphlet
@@ -0,0 +1,514 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gbintern.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GBINTERN GroebnerInternalPackage}
+<<package GBINTERN GroebnerInternalPackage>>=
+)abbrev package GBINTERN GroebnerInternalPackage
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Keywords:
+++ Description
+++ This package provides low level tools for Groebner basis computations
+GroebnerInternalPackage(Dom, Expon, VarSet, Dpol): T == C where
+ Dom: GcdDomain
+ Expon: OrderedAbelianMonoidSup
+ VarSet: OrderedSet
+ Dpol: PolynomialCategory(Dom, Expon, VarSet)
+ NNI ==> NonNegativeInteger
+ ------ Definition of Record critPair and Prinp
+
+ critPair ==> Record( lcmfij: Expon, totdeg: NonNegativeInteger,
+ poli: Dpol, polj: Dpol )
+ sugarPol ==> Record( totdeg: NonNegativeInteger, pol : Dpol)
+ Prinp ==> Record( ci:Dpol,tci:Integer,cj:Dpol,tcj:Integer,c:Dpol,
+ tc:Integer,rc:Dpol,trc:Integer,tF:Integer,tD:Integer)
+ Prinpp ==> Record( ci:Dpol,tci:Integer,cj:Dpol,tcj:Integer,c:Dpol,
+ tc:Integer,rc:Dpol,trc:Integer,tF:Integer,tDD:Integer,
+ tDF:Integer)
+ T== with
+
+ credPol: (Dpol, List(Dpol)) -> Dpol
+ ++ credPol \undocumented
+ redPol: (Dpol, List(Dpol)) -> Dpol
+ ++ redPol \undocumented
+ gbasis: (List(Dpol), Integer, Integer) -> List(Dpol)
+ ++ gbasis \undocumented
+ critT: critPair -> Boolean
+ ++ critT \undocumented
+ critM: (Expon, Expon) -> Boolean
+ ++ critM \undocumented
+ critB: (Expon, Expon, Expon, Expon) -> Boolean
+ ++ critB \undocumented
+ critBonD: (Dpol, List(critPair)) -> List(critPair)
+ ++ critBonD \undocumented
+ critMTonD1: (List(critPair)) -> List(critPair)
+ ++ critMTonD1 \undocumented
+ critMonD1: (Expon, List(critPair)) -> List(critPair)
+ ++ critMonD1 \undocumented
+ redPo: (Dpol, List(Dpol) ) -> Record(poly:Dpol, mult:Dom)
+ ++ redPo \undocumented
+ hMonic: Dpol -> Dpol
+ ++ hMonic \undocumented
+ updatF: (Dpol, NNI, List(sugarPol) ) -> List(sugarPol)
+ ++ updatF \undocumented
+ sPol: critPair -> Dpol
+ ++ sPol \undocumented
+ updatD: (List(critPair), List(critPair)) -> List(critPair)
+ ++ updatD \undocumented
+ minGbasis: List(Dpol) -> List(Dpol)
+ ++ minGbasis \undocumented
+ lepol: Dpol -> Integer
+ ++ lepol \undocumented
+ prinshINFO : Dpol -> Void
+ ++ prinshINFO \undocumented
+ prindINFO: (critPair, Dpol, Dpol,Integer,Integer,Integer) -> Integer
+ ++ prindINFO \undocumented
+ fprindINFO: (critPair, Dpol, Dpol, Integer,Integer,Integer
+ ,Integer) -> Integer
+ ++ fprindINFO \undocumented
+ prinpolINFO: List(Dpol) -> Void
+ ++ prinpolINFO \undocumented
+ prinb: Integer-> Void
+ ++ prinb \undocumented
+ critpOrder: (critPair, critPair) -> Boolean
+ ++ critpOrder \undocumented
+ makeCrit: (sugarPol, Dpol, NonNegativeInteger) -> critPair
+ ++ makeCrit \undocumented
+ virtualDegree : Dpol -> NonNegativeInteger
+ ++ virtualDegree \undocumented
+
+ C== add
+ Ex ==> OutputForm
+ import OutputForm
+
+ ------ Definition of intermediate functions
+ if Dpol has totalDegree: Dpol -> NonNegativeInteger then
+ virtualDegree p == totalDegree p
+ else
+ virtualDegree p == 0
+
+ ------ ordering of critpairs
+
+ critpOrder(cp1,cp2) ==
+ cp1.totdeg < cp2.totdeg => true
+ cp2.totdeg < cp1.totdeg => false
+ cp1.lcmfij < cp2.lcmfij
+
+ ------ creating a critical pair
+
+ makeCrit(sp1, p2, totdeg2) ==
+ p1 := sp1.pol
+ deg := sup(degree(p1), degree(p2))
+ e1 := subtractIfCan(deg, degree(p1))::Expon
+ e2 := subtractIfCan(deg, degree(p2))::Expon
+ tdeg := max(sp1.totdeg + virtualDegree(monomial(1,e1)),
+ totdeg2 + virtualDegree(monomial(1,e2)))
+ [deg, tdeg, p1, p2]$critPair
+
+ ------ calculate basis
+
+ gbasis(Pol: List(Dpol), xx1: Integer, xx2: Integer ) ==
+ D, D1: List(critPair)
+ --------- create D and Pol
+
+ Pol1:= sort(degree #1 > degree #2, Pol)
+ basPols:= updatF(hMonic(first Pol1),virtualDegree(first Pol1),[])
+ Pol1:= rest(Pol1)
+ D:= nil
+ while _^ null Pol1 repeat
+ h:= hMonic(first(Pol1))
+ Pol1:= rest(Pol1)
+ toth := virtualDegree h
+ D1:= [makeCrit(x,h,toth) for x in basPols]
+ D:= updatD(critMTonD1(sort(critpOrder, D1)),
+ critBonD(h,D))
+ basPols:= updatF(h,toth,basPols)
+ D:= sort(critpOrder, D)
+ xx:= xx2
+ -------- loop
+
+ redPols := [x.pol for x in basPols]
+ while _^ null D repeat
+ D0:= first D
+ s:= hMonic(sPol(D0))
+ D:= rest(D)
+ h:= hMonic(redPol(s,redPols))
+ if xx1 = 1 then
+ prinshINFO(h)
+ h = 0 =>
+ if xx2 = 1 then
+ prindINFO(D0,s,h,# basPols, # D,xx)
+ xx:= 2
+ " go to top of while "
+ degree(h) = 0 =>
+ D:= nil
+ if xx2 = 1 then
+ prindINFO(D0,s,h,# basPols, # D,xx)
+ xx:= 2
+ basPols:= updatF(h,0,[])
+ leave "out of while"
+ D1:= [makeCrit(x,h,D0.totdeg) for x in basPols]
+ D:= updatD(critMTonD1(sort(critpOrder, D1)),
+ critBonD(h,D))
+ basPols:= updatF(h,D0.totdeg,basPols)
+ redPols := concat(redPols,h)
+ if xx2 = 1 then
+ prindINFO(D0,s,h,# basPols, # D,xx)
+ xx:= 2
+ Pol := [x.pol for x in basPols]
+ if xx2 = 1 then
+ prinpolINFO(Pol)
+ messagePrint(" THE GROEBNER BASIS POLYNOMIALS")
+ if xx1 = 1 and xx2 ^= 1 then
+ messagePrint(" THE GROEBNER BASIS POLYNOMIALS")
+ Pol
+
+ --------------------------------------
+
+ --- erase multiple of e in D2 using crit M
+
+ critMonD1(e: Expon, D2: List(critPair))==
+ null D2 => nil
+ x:= first(D2)
+ critM(e, x.lcmfij) => critMonD1(e, rest(D2))
+ cons(x, critMonD1(e, rest(D2)))
+
+ ----------------------------
+
+ --- reduce D1 using crit T and crit M
+
+ critMTonD1(D1: List(critPair))==
+ null D1 => nil
+ f1:= first(D1)
+ s1:= #(D1)
+ cT1:= critT(f1)
+ s1= 1 and cT1 => nil
+ s1= 1 => D1
+ e1:= f1.lcmfij
+ r1:= rest(D1)
+ e1 = (first r1).lcmfij =>
+ cT1 => critMTonD1(cons(f1, rest(r1)))
+ critMTonD1(r1)
+ D1 := critMonD1(e1, r1)
+ cT1 => critMTonD1(D1)
+ cons(f1, critMTonD1(D1))
+
+ -----------------------------
+
+ --- erase elements in D fullfilling crit B
+
+ critBonD(h:Dpol, D: List(critPair))==
+ null D => nil
+ x:= first(D)
+ critB(degree(h), x.lcmfij, degree(x.poli), degree(x.polj)) =>
+ critBonD(h, rest(D))
+ cons(x, critBonD(h, rest(D)))
+
+ -----------------------------
+
+ --- concat F and h and erase multiples of h in F
+
+ updatF(h: Dpol, deg:NNI, F: List(sugarPol)) ==
+ null F => [[deg,h]]
+ f1:= first(F)
+ critM(degree(h), degree(f1.pol)) => updatF(h, deg, rest(F))
+ cons(f1, updatF(h, deg, rest(F)))
+
+ -----------------------------
+
+ --- concat ordered critical pair lists D1 and D2
+
+ updatD(D1: List(critPair), D2: List(critPair)) ==
+ null D1 => D2
+ null D2 => D1
+ dl1:= first(D1)
+ dl2:= first(D2)
+ critpOrder(dl1,dl2) => cons(dl1, updatD(D1.rest, D2))
+ cons(dl2, updatD(D1, D2.rest))
+
+ -----------------------------
+
+ --- remove gcd from pair of coefficients
+
+ gcdCo(c1:Dom, c2:Dom):Record(co1:Dom,co2:Dom) ==
+ d:=gcd(c1,c2)
+ [(c1 exquo d)::Dom, (c2 exquo d)::Dom]
+
+ --- calculate S-polynomial of a critical pair
+
+ sPol(p:critPair)==
+ Tij := p.lcmfij
+ fi := p.poli
+ fj := p.polj
+ cc := gcdCo(leadingCoefficient fi, leadingCoefficient fj)
+ reductum(fi)*monomial(cc.co2,subtractIfCan(Tij, degree fi)::Expon) -
+ reductum(fj)*monomial(cc.co1,subtractIfCan(Tij, degree fj)::Expon)
+
+ ----------------------------
+
+ --- reduce critpair polynomial mod F
+ --- iterative version
+
+ redPo(s: Dpol, F: List(Dpol)) ==
+ m:Dom := 1
+ Fh := F
+ while _^ ( s = 0 or null F ) repeat
+ f1:= first(F)
+ s1:= degree(s)
+ e: Union(Expon, "failed")
+ (e:= subtractIfCan(s1, degree(f1))) case Expon =>
+ cc:=gcdCo(leadingCoefficient f1, leadingCoefficient s)
+ s:=cc.co1*reductum(s) - monomial(cc.co2,e)*reductum(f1)
+ m := m*cc.co1
+ F:= Fh
+ F:= rest F
+ [s,m]
+
+ redPol(s: Dpol, F: List(Dpol)) == credPol(redPo(s,F).poly,F)
+
+ ----------------------------
+
+ --- crit T true, if e1 and e2 are disjoint
+
+ critT(p: critPair) == p.lcmfij = (degree(p.poli) + degree(p.polj))
+
+ ----------------------------
+
+ --- crit M - true, if lcm#2 multiple of lcm#1
+
+ critM(e1: Expon, e2: Expon) ==
+ en: Union(Expon, "failed")
+ (en:=subtractIfCan(e2, e1)) case Expon
+
+ ----------------------------
+
+ --- crit B - true, if eik is a multiple of eh and eik ^equal
+ --- lcm(eh,ei) and eik ^equal lcm(eh,ek)
+
+ critB(eh:Expon, eik:Expon, ei:Expon, ek:Expon) ==
+ critM(eh, eik) and (eik ^= sup(eh, ei)) and (eik ^= sup(eh, ek))
+
+ ----------------------------
+
+ --- make polynomial monic case Domain a Field
+
+ hMonic(p: Dpol) ==
+ p= 0 => p
+ -- inv(leadingCoefficient(p))*p
+ primitivePart p
+
+ -----------------------------
+
+ --- reduce all terms of h mod F (iterative version )
+
+ credPol(h: Dpol, F: List(Dpol) ) ==
+ null F => h
+ h0:Dpol:= monomial(leadingCoefficient h, degree h)
+ while (h:=reductum h) ^= 0 repeat
+ hred:= redPo(h, F)
+ h := hred.poly
+ h0:=(hred.mult)*h0 + monomial(leadingCoefficient(h),degree h)
+ h0
+
+ -------------------------------
+
+ ---- calculate minimal basis for ordered F
+
+ minGbasis(F: List(Dpol)) ==
+ null F => nil
+ newbas := minGbasis rest F
+ cons(hMonic credPol( first(F), newbas),newbas)
+
+ -------------------------------
+
+ ---- calculate number of terms of polynomial
+
+ lepol(p1:Dpol)==
+ n: Integer
+ n:= 0
+ while p1 ^= 0 repeat
+ n:= n + 1
+ p1:= reductum(p1)
+ n
+
+ ---- print blanc lines
+
+ prinb(n: Integer)==
+ for x in 1..n repeat
+ messagePrint(" ")
+
+ ---- print reduced critpair polynom
+
+ prinshINFO(h: Dpol)==
+ prinb(2)
+ messagePrint(" reduced Critpair - Polynom :")
+ prinb(2)
+ print(h::Ex)
+ prinb(2)
+
+ -------------------------------
+
+ ---- print info string
+
+ prindINFO(cp: critPair, ps: Dpol, ph: Dpol, i1:Integer,
+ i2:Integer, n:Integer) ==
+ ll: List Prinp
+ a: Dom
+ cpi:= cp.poli
+ cpj:= cp.polj
+ if n = 1 then
+ prinb(1)
+ messagePrint("you choose option -info- ")
+ messagePrint("abbrev. for the following information strings are")
+ messagePrint(" ci => Leading monomial for critpair calculation")
+ messagePrint(" tci => Number of terms of polynomial i")
+ messagePrint(" cj => Leading monomial for critpair calculation")
+ messagePrint(" tcj => Number of terms of polynomial j")
+ messagePrint(" c => Leading monomial of critpair polynomial")
+ messagePrint(" tc => Number of terms of critpair polynomial")
+ messagePrint(" rc => Leading monomial of redcritpair polynomial")
+ messagePrint(" trc => Number of terms of redcritpair polynomial")
+ messagePrint(" tF => Number of polynomials in reduction list F")
+ messagePrint(" tD => Number of critpairs still to do")
+ prinb(4)
+ n:= 2
+ prinb(1)
+ a:= 1
+ ph = 0 =>
+ ps = 0 =>
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),
+ lepol(cpj),ps,0,ph,0,i1,i2]$Prinp]
+ print(ll::Ex)
+ prinb(1)
+ n
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),lepol(cpj),monomial(a,degree(ps)),
+ lepol(ps), ph,0,i1,i2]$Prinp]
+ print(ll::Ex)
+ prinb(1)
+ n
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),lepol(cpj),monomial(a,degree(ps)),
+ lepol(ps),monomial(a,degree(ph)),lepol(ph),i1,i2]$Prinp]
+ print(ll::Ex)
+ prinb(1)
+ n
+
+ -------------------------------
+
+ ---- print the groebner basis polynomials
+
+ prinpolINFO(pl: List(Dpol))==
+ n:Integer
+ n:= # pl
+ prinb(1)
+ n = 1 =>
+ messagePrint(" There is 1 Groebner Basis Polynomial ")
+ prinb(2)
+ messagePrint(" There are ")
+ prinb(1)
+ print(n::Ex)
+ prinb(1)
+ messagePrint(" Groebner Basis Polynomials. ")
+ prinb(2)
+
+ fprindINFO(cp: critPair, ps: Dpol, ph: Dpol, i1:Integer,
+ i2:Integer, i3:Integer, n: Integer) ==
+ ll: List Prinpp
+ a: Dom
+ cpi:= cp.poli
+ cpj:= cp.polj
+ if n = 1 then
+ prinb(1)
+ messagePrint("you choose option -info- ")
+ messagePrint("abbrev. for the following information strings are")
+ messagePrint(" ci => Leading monomial for critpair calculation")
+ messagePrint(" tci => Number of terms of polynomial i")
+ messagePrint(" cj => Leading monomial for critpair calculation")
+ messagePrint(" tcj => Number of terms of polynomial j")
+ messagePrint(" c => Leading monomial of critpair polynomial")
+ messagePrint(" tc => Number of terms of critpair polynomial")
+ messagePrint(" rc => Leading monomial of redcritpair polynomial")
+ messagePrint(" trc => Number of terms of redcritpair polynomial")
+ messagePrint(" tF => Number of polynomials in reduction list F")
+ messagePrint(" tD => Number of critpairs still to do")
+ messagePrint(" tDF => Number of subproblems still to do")
+ prinb(4)
+ n:= 2
+ prinb(1)
+ a:= 1
+ ph = 0 =>
+ ps = 0 =>
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),
+ lepol(cpj),ps,0,ph,0,i1,i2,i3]$Prinpp]
+ print(ll::Ex)
+ prinb(1)
+ n
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),lepol(cpj),monomial(a,degree(ps)),
+ lepol(ps), ph,0,i1,i2,i3]$Prinpp]
+ print(ll::Ex)
+ prinb(1)
+ n
+ ll:= [[monomial(a,degree(cpi)),lepol(cpi),
+ monomial(a,degree(cpj)),lepol(cpj),monomial(a,degree(ps)),
+ lepol(ps),monomial(a,degree(ph)),lepol(ph),i1,i2,i3]$Prinpp]
+ print(ll::Ex)
+ prinb(1)
+ n
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GBINTERN GroebnerInternalPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gdirprod.spad.pamphlet b/src/algebra/gdirprod.spad.pamphlet
new file mode 100644
index 00000000..c12b2fd4
--- /dev/null
+++ b/src/algebra/gdirprod.spad.pamphlet
@@ -0,0 +1,254 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gdirprod.spad}
+\author{Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ORDFUNS OrderingFunctions}
+<<package ORDFUNS OrderingFunctions>>=
+)abbrev package ORDFUNS OrderingFunctions
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: OrderedDirectProduct
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides ordering functions on vectors which
+++ are suitable parameters for OrderedDirectProduct.
+
+OrderingFunctions(dim,S) : T == C where
+ dim : NonNegativeInteger
+ S : OrderedAbelianMonoid
+ VS == Vector S
+
+ T == with
+ pureLex : (VS,VS) -> Boolean
+ ++ pureLex(v1,v2) return true if the vector v1 is less than the
+ ++ vector v2 in the lexicographic ordering.
+ totalLex : (VS,VS) -> Boolean
+ ++ totalLex(v1,v2) return true if the vector v1 is less than the
+ ++ vector v2 in the ordering which is total degree refined by
+ ++ lexicographic ordering.
+ reverseLex : (VS,VS) -> Boolean
+ ++ reverseLex(v1,v2) return true if the vector v1 is less than the
+ ++ vector v2 in the ordering which is total degree refined by
+ ++ the reverse lexicographic ordering.
+
+ C == add
+ n:NonNegativeInteger:=dim
+
+ -- pure lexicographical ordering
+ pureLex(v1:VS,v2:VS) : Boolean ==
+ for i in 1..n repeat
+ if qelt(v1,i) < qelt(v2,i) then return true
+ if qelt(v2,i) < qelt(v1,i) then return false
+ false
+
+ -- total ordering refined with lex
+ totalLex(v1:VS,v2:VS) :Boolean ==
+ n1:S:=0
+ n2:S:=0
+ for i in 1..n repeat
+ n1:= n1+qelt(v1,i)
+ n2:=n2+qelt(v2,i)
+ n1<n2 => true
+ n2<n1 => false
+ for i in 1..n repeat
+ if qelt(v1,i) < qelt(v2,i) then return true
+ if qelt(v2,i) < qelt(v1,i) then return false
+ false
+
+ -- reverse lexicographical ordering
+ reverseLex(v1:VS,v2:VS) :Boolean ==
+ n1:S:=0
+ n2:S:=0
+ for i in 1..n repeat
+ n1:= n1+qelt(v1,i)
+ n2:=n2+qelt(v2,i)
+ n1<n2 => true
+ n2<n1 => false
+ for i in reverse(1..n) repeat
+ if qelt(v2,i) < qelt(v1,i) then return true
+ if qelt(v1,i) < qelt(v2,i) then return false
+ false
+
+@
+\section{domain ODP OrderedDirectProduct}
+<<domain ODP OrderedDirectProduct>>=
+)abbrev domain ODP OrderedDirectProduct
+-- all direct product category domains must be compiled
+-- without subsumption, set SourceLevelSubset to EQUAL
+--)bo $noSubsumption := true
+
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Vector, DirectProduct
+++ Also See: HomogeneousDirectProduct, SplitHomogeneousDirectProduct
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type represents the finite direct or cartesian product of an
+++ underlying ordered component type. The ordering on the type is determined
+++ by its third argument which represents the less than function on
+++ vectors. This type is a suitable third argument for
+++ \spadtype{GeneralDistributedMultivariatePolynomial}.
+
+OrderedDirectProduct(dim:NonNegativeInteger,
+ S:OrderedAbelianMonoidSup,
+ f:(Vector(S),Vector(S))->Boolean):T
+ == C where
+ T == DirectProductCategory(dim,S)
+ C == DirectProduct(dim,S) add
+ Rep:=Vector(S)
+ x:% < y:% == f(x::Rep,y::Rep)
+
+@
+\section{domain HDP HomogeneousDirectProduct}
+<<domain HDP HomogeneousDirectProduct>>=
+)abbrev domain HDP HomogeneousDirectProduct
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Vector, DirectProduct
+++ Also See: OrderedDirectProduct, SplitHomogeneousDirectproduct
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type represents the finite direct or cartesian product of an
+++ underlying ordered component type. The vectors are ordered first
+++ by the sum of their components, and then refined using a reverse
+++ lexicographic ordering. This type is a suitable third argument for
+++ \spadtype{GeneralDistributedMultivariatePolynomial}.
+
+HomogeneousDirectProduct(dim,S) : T == C where
+ dim : NonNegativeInteger
+ S : OrderedAbelianMonoidSup
+
+ T == DirectProductCategory(dim,S)
+ C == DirectProduct(dim,S) add
+ Rep:=Vector(S)
+ v1:% < v2:% ==
+ -- reverse lexicographical ordering
+ n1:S:=0
+ n2:S:=0
+ for i in 1..dim repeat
+ n1:= n1+qelt(v1,i)
+ n2:=n2+qelt(v2,i)
+ n1<n2 => true
+ n2<n1 => false
+ for i in reverse(1..dim) repeat
+ if qelt(v2,i) < qelt(v1,i) then return true
+ if qelt(v1,i) < qelt(v2,i) then return false
+ false
+
+@
+\section{domain SHDP SplitHomogeneousDirectProduct}
+<<domain SHDP SplitHomogeneousDirectProduct>>=
+)abbrev domain SHDP SplitHomogeneousDirectProduct
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Vector, DirectProduct
+++ Also See: OrderedDirectProduct, HomogeneousDirectProduct
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type represents the finite direct or cartesian product of an
+++ underlying ordered component type. The vectors are ordered as if
+++ they were split into two blocks. The dim1 parameter specifies the
+++ length of the first block. The ordering is lexicographic between
+++ the blocks but acts like \spadtype{HomogeneousDirectProduct}
+++ within each block. This type is a suitable third argument for
+++ \spadtype{GeneralDistributedMultivariatePolynomial}.
+
+SplitHomogeneousDirectProduct(dimtot,dim1,S) : T == C where
+ NNI ==> NonNegativeInteger
+ dim1,dimtot : NNI
+ S : OrderedAbelianMonoidSup
+
+ T == DirectProductCategory(dimtot,S)
+ C == DirectProduct(dimtot,S) add
+ Rep:=Vector(S)
+ lessThanRlex(v1:%,v2:%,low:NNI,high:NNI):Boolean ==
+ -- reverse lexicographical ordering
+ n1:S:=0
+ n2:S:=0
+ for i in low..high repeat
+ n1:= n1+qelt(v1,i)
+ n2:=n2+qelt(v2,i)
+ n1<n2 => true
+ n2<n1 => false
+ for i in reverse(low..high) repeat
+ if qelt(v2,i) < qelt(v1,i) then return true
+ if qelt(v1,i) < qelt(v2,i) then return false
+ false
+
+ (v1:% < v2:%):Boolean ==
+ lessThanRlex(v1,v2,1,dim1) => true
+ for i in 1..dim1 repeat
+ if qelt(v1,i) ^= qelt(v2,i) then return false
+ lessThanRlex(v1,v2,dim1+1,dimtot)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ORDFUNS OrderingFunctions>>
+<<domain ODP OrderedDirectProduct>>
+<<domain HDP HomogeneousDirectProduct>>
+<<domain SHDP SplitHomogeneousDirectProduct>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gdpoly.spad.pamphlet b/src/algebra/gdpoly.spad.pamphlet
new file mode 100644
index 00000000..6c3ae4fd
--- /dev/null
+++ b/src/algebra/gdpoly.spad.pamphlet
@@ -0,0 +1,378 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gdpoly.spad}
+\author{Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain GDMP GeneralDistributedMultivariatePolynomial}
+<<domain GDMP GeneralDistributedMultivariatePolynomial>>=
+)abbrev domain GDMP GeneralDistributedMultivariatePolynomial
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, degree, eval, coefficient, monomial, differentiate,
+++ resultant, gcd, leadingCoefficient
+++ Related Constructors: DistributedMultivariatePolynomial,
+++ HomogeneousDistributedMultivariatePolynomial
+++ Also See: Polynomial
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, distributed
+++ References:
+++ Description:
+++ This type supports distributed multivariate polynomials
+++ whose variables are from a user specified list of symbols.
+++ The coefficient ring may be non commutative,
+++ but the variables are assumed to commute.
+++ The term ordering is specified by its third parameter.
+++ Suggested types which define term orderings include: \spadtype{DirectProduct},
+++ \spadtype{HomogeneousDirectProduct}, \spadtype{SplitHomogeneousDirectProduct}
+++ and finally \spadtype{OrderedDirectProduct} which accepts an arbitrary user
+++ function to define a term ordering.
+
+GeneralDistributedMultivariatePolynomial(vl,R,E): public == private where
+ vl: List Symbol
+ R: Ring
+ E: DirectProductCategory(#vl,NonNegativeInteger)
+ OV ==> OrderedVariableList(vl)
+ SUP ==> SparseUnivariatePolynomial
+ NNI ==> NonNegativeInteger
+
+ public == PolynomialCategory(R,E,OV) with
+ reorder: (%,List Integer) -> %
+ ++ reorder(p, perm) applies the permutation perm to the variables
+ ++ in a polynomial and returns the new correctly ordered polynomial
+
+ private == PolynomialRing(R,E) add
+ --representations
+ Term := Record(k:E,c:R)
+ Rep := List Term
+ n := #vl
+ Vec ==> Vector(NonNegativeInteger)
+ zero?(p : %): Boolean == null(p : Rep)
+
+ totalDegree p ==
+ zero? p => 0
+ "max"/[reduce("+",(t.k)::(Vector NNI), 0) for t in p]
+
+ monomial(p:%, v: OV,e: NonNegativeInteger):% ==
+ locv := lookup v
+ p*monomial(1,
+ directProduct [if z=locv then e else 0 for z in 1..n]$Vec)
+
+ coerce(v: OV):% == monomial(1,v,1)
+
+ listCoef(p : %): List R ==
+ rec : Term
+ [rec.c for rec in (p:Rep)]
+
+ mainVariable(p: %) ==
+ zero?(p) => "failed"
+ for v in vl repeat
+ vv := variable(v)::OV
+ if degree(p,vv)>0 then return vv
+ "failed"
+
+ ground?(p) == mainVariable(p) case "failed"
+
+ retract(p : %): R ==
+ not ground? p => error "not a constant"
+ leadingCoefficient p
+
+ retractIfCan(p : %): Union(R,"failed") ==
+ ground?(p) => leadingCoefficient p
+ "failed"
+
+ degree(p: %,v: OV) == degree(univariate(p,v))
+ minimumDegree(p: %,v: OV) == minimumDegree(univariate(p,v))
+ differentiate(p: %,v: OV) ==
+ multivariate(differentiate(univariate(p,v)),v)
+
+ degree(p: %,lv: List OV) == [degree(p,v) for v in lv]
+ minimumDegree(p: %,lv: List OV) == [minimumDegree(p,v) for v in lv]
+
+ numberOfMonomials(p:%) ==
+ l : Rep := p : Rep
+ null(l) => 1
+ #l
+
+ monomial?(p : %): Boolean ==
+ l : Rep := p : Rep
+ null(l) or null rest(l)
+
+ if R has OrderedRing then
+ maxNorm(p : %): R ==
+ l : List R := nil
+ r,m : R
+ m := 0
+ for r in listCoef(p) repeat
+ if r > m then m := r
+ else if (-r) > m then m := -r
+ m
+
+ --trailingCoef(p : %) ==
+ -- l : Rep := p : Rep
+ -- null l => 0
+ -- r : Term := last l
+ -- r.c
+
+ --leadingPrimitiveMonomial(p : %) ==
+ -- ground?(p) => 1$%
+ -- r : Term := first(p:Rep)
+ -- r := [r.k,1$R]$Term -- new cell
+ -- list(r)$Rep :: %
+
+ -- The following 2 defs are inherited from PolynomialRing
+
+ --leadingMonomial(p : %) ==
+ -- ground?(p) => p
+ -- r : Term := first(p:Rep)
+ -- r := [r.k,r.c]$Term -- new cell
+ -- list(r)$Rep :: %
+
+ --reductum(p : %): % ==
+ -- ground? p => 0$%
+ -- (rest(p:Rep)):%
+
+ if R has Field then
+ (p : %) / (r : R) == inv(r) * p
+
+ variables(p: %) ==
+ maxdeg:Vector(NonNegativeInteger) := new(n,0)
+ while not zero?(p) repeat
+ tdeg := degree p
+ p := reductum p
+ for i in 1..n repeat
+ maxdeg.i := max(maxdeg.i, tdeg.i)
+ [index(i:PositiveInteger) for i in 1..n | maxdeg.i^=0]
+
+ reorder(p: %,perm: List Integer):% ==
+ #perm ^= n => error "must be a complete permutation of all vars"
+ q := [[directProduct [term.k.j for j in perm]$Vec,term.c]$Term
+ for term in p]
+ sort(#1.k > #2.k,q)
+
+ --coerce(dp:DistributedMultivariatePolynomial(vl,R)):% ==
+ -- q:=dp:List(Term)
+ -- sort(#1.k > #2.k,q):%
+
+ univariate(p: %,v: OV):SUP(%) ==
+ zero?(p) => 0
+ exp := degree p
+ locv := lookup v
+ deg:NonNegativeInteger := 0
+ nexp := directProduct [if i=locv then (deg :=exp.i;0) else exp.i
+ for i in 1..n]$Vec
+ monomial(monomial(leadingCoefficient p,nexp),deg)+
+ univariate(reductum p,v)
+
+ eval(p: %,v: OV,val:%):% == univariate(p,v)(val)
+
+ eval(p: %,v: OV,val:R):% == eval(p,v,val::%)$%
+
+ eval(p: %,lv: List OV,lval: List R):% ==
+ lv = [] => p
+ eval(eval(p,first lv,(first lval)::%)$%, rest lv, rest lval)$%
+
+ -- assume Lvar are sorted correctly
+ evalSortedVarlist(p: %,Lvar: List OV,Lpval: List %):% ==
+ v := mainVariable p
+ v case "failed" => p
+ pv := v:: OV
+ Lvar=[] or Lpval=[] => p
+ mvar := Lvar.first
+ mvar > pv => evalSortedVarlist(p,Lvar.rest,Lpval.rest)
+ pval := Lpval.first
+ pts:SUP(%):= map(evalSortedVarlist(#1,Lvar,Lpval),univariate(p,pv))
+ mvar=pv => pts(pval)
+ multivariate(pts,pv)
+
+ eval(p:%,Lvar:List OV,Lpval:List %) ==
+ nlvar:List OV := sort(#1 > #2,Lvar)
+ nlpval :=
+ Lvar = nlvar => Lpval
+ nlpval := [Lpval.position(mvar,Lvar) for mvar in nlvar]
+ evalSortedVarlist(p,nlvar,nlpval)
+
+ multivariate(p1:SUP(%),v: OV):% ==
+ 0=p1 => 0
+ degree p1 = 0 => leadingCoefficient p1
+ leadingCoefficient(p1)*(v::%)**degree(p1) +
+ multivariate(reductum p1,v)
+
+ univariate(p: %):SUP(R) ==
+ (v := mainVariable p) case "failed" =>
+ monomial(leadingCoefficient p,0)
+ q := univariate(p,v:: OV)
+ ans:SUP(R) := 0
+ while q ^= 0 repeat
+ ans := ans + monomial(ground leadingCoefficient q,degree q)
+ q := reductum q
+ ans
+
+ multivariate(p:SUP(R),v: OV):% ==
+ 0=p => 0
+ (leadingCoefficient p)*monomial(1,v,degree p) +
+ multivariate(reductum p,v)
+
+ if R has GcdDomain then
+ content(p: %):R ==
+ zero?(p) => 0
+ "gcd"/[t.c for t in p]
+
+
+
+ if R has EuclideanDomain and not(R has FloatingPointSystem) then
+ gcd(p: %,q:%):% ==
+ gcd(p,q)$PolynomialGcdPackage(E,OV,R,%)
+
+ else gcd(p: %,q:%):% ==
+ r : R
+ (pv := mainVariable(p)) case "failed" =>
+ (r := leadingCoefficient p) = 0$R => q
+ gcd(r,content q)::%
+ (qv := mainVariable(q)) case "failed" =>
+ (r := leadingCoefficient q) = 0$R => p
+ gcd(r,content p)::%
+ pv<qv => gcd(p,content univariate(q,qv))
+ qv<pv => gcd(q,content univariate(p,pv))
+ multivariate(gcd(univariate(p,pv),univariate(q,qv)),pv)
+
+ coerce(p: %) : OutputForm ==
+ zero?(p) => (0$R) :: OutputForm
+ l,lt : List OutputForm
+ lt := nil
+ vl1 := [v::OutputForm for v in vl]
+ for t in reverse p repeat
+ l := nil
+ for i in 1..#vl1 repeat
+ t.k.i = 0 => l
+ t.k.i = 1 => l := cons(vl1.i,l)
+ l := cons(vl1.i ** t.k.i ::OutputForm,l)
+ l := reverse l
+ if (t.c ^= 1) or (null l) then l := cons(t.c :: OutputForm,l)
+ 1 = #l => lt := cons(first l,lt)
+ lt := cons(reduce("*",l),lt)
+ 1 = #lt => first lt
+ reduce("+",lt)
+
+@
+\section{domain DMP DistributedMultivariatePolynomial}
+<<domain DMP DistributedMultivariatePolynomial>>=
+)abbrev domain DMP DistributedMultivariatePolynomial
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, degree, eval, coefficient, monomial, differentiate,
+++ resultant, gcd, leadingCoefficient
+++ Related Constructors: GeneralDistributedMultivariatePolynomial,
+++ HomogeneousDistributedMultivariatePolynomial
+++ Also See: Polynomial
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, distributed
+++ References:
+++ Description:
+++ This type supports distributed multivariate polynomials
+++ whose variables are from a user specified list of symbols.
+++ The coefficient ring may be non commutative,
+++ but the variables are assumed to commute.
+++ The term ordering is lexicographic specified by the variable
+++ list parameter with the most significant variable first in the list.
+DistributedMultivariatePolynomial(vl,R): public == private where
+ vl : List Symbol
+ R : Ring
+ E ==> DirectProduct(#vl,NonNegativeInteger)
+ OV ==> OrderedVariableList(vl)
+ public == PolynomialCategory(R,E,OV) with
+ reorder: (%,List Integer) -> %
+ ++ reorder(p, perm) applies the permutation perm to the variables
+ ++ in a polynomial and returns the new correctly ordered polynomial
+
+ private ==
+ GeneralDistributedMultivariatePolynomial(vl,R,E)
+
+@
+\section{domain HDMP HomogeneousDistributedMultivariatePolynomial}
+<<domain HDMP HomogeneousDistributedMultivariatePolynomial>>=
+)abbrev domain HDMP HomogeneousDistributedMultivariatePolynomial
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, degree, eval, coefficient, monomial, differentiate,
+++ resultant, gcd, leadingCoefficient
+++ Related Constructors: DistributedMultivariatePolynomial,
+++ GeneralDistributedMultivariatePolynomial
+++ Also See: Polynomial
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, distributed
+++ References:
+++ Description:
+++ This type supports distributed multivariate polynomials
+++ whose variables are from a user specified list of symbols.
+++ The coefficient ring may be non commutative,
+++ but the variables are assumed to commute.
+++ The term ordering is total degree ordering refined by reverse
+++ lexicographic ordering with respect to the position that the variables
+++ appear in the list of variables parameter.
+HomogeneousDistributedMultivariatePolynomial(vl,R): public == private where
+ vl : List Symbol
+ R : Ring
+ E ==> HomogeneousDirectProduct(#vl,NonNegativeInteger)
+ OV ==> OrderedVariableList(vl)
+ public == PolynomialCategory(R,E,OV) with
+ reorder: (%,List Integer) -> %
+ ++ reorder(p, perm) applies the permutation perm to the variables
+ ++ in a polynomial and returns the new correctly ordered polynomial
+ private ==
+ GeneralDistributedMultivariatePolynomial(vl,R,E)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain GDMP GeneralDistributedMultivariatePolynomial>>
+<<domain DMP DistributedMultivariatePolynomial>>
+<<domain HDMP HomogeneousDistributedMultivariatePolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/geneez.spad.pamphlet b/src/algebra/geneez.spad.pamphlet
new file mode 100644
index 00000000..74076d65
--- /dev/null
+++ b/src/algebra/geneez.spad.pamphlet
@@ -0,0 +1,248 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra geneez.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GENEEZ GenExEuclid}
+<<package GENEEZ GenExEuclid>>=
+)abbrev package GENEEZ GenExEuclid
+++ Author : P.Gianni.
+++ January 1990
+++ The equation \spad{Af+Bg=h} and its generalization to n polynomials
+++ is solved for solutions over the R, euclidean domain.
+++ A table containing the solutions of \spad{Af+Bg=x**k} is used.
+++ The operations are performed modulus a prime which are in principle big enough,
+++ but the solutions are tested and, in case of failure, a hensel
+++ lifting process is used to get to the right solutions.
+++ It will be used in the factorization of multivariate polynomials
+++ over finite field, with \spad{R=F[x]}.
+
+GenExEuclid(R,BP) : C == T
+ where
+ R : EuclideanDomain
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ BP : UnivariatePolynomialCategory R
+ L ==> List
+
+ C == with
+ reduction: (BP,R) -> BP
+ ++ reduction(p,prime) reduces the polynomial p modulo prime of R.
+ ++ Note: this function is exported only because it's conditional.
+ compBound: (BP,L BP) -> NNI
+ ++ compBound(p,lp)
+ ++ computes a bound for the coefficients of the solution
+ ++ polynomials.
+ ++ Given a polynomial right hand side p, and a list lp of left hand side polynomials.
+ ++ Exported because it depends on the valuation.
+ tablePow : (NNI,R,L BP) -> Union(Vector(L BP),"failed")
+ ++ tablePow(maxdeg,prime,lpol) constructs the table with the
+ ++ coefficients of the Extended Euclidean Algorithm for lpol.
+ ++ Here the right side is \spad{x**k}, for k less or equal to maxdeg.
+ ++ The operation returns "failed" when the elements are not coprime modulo prime.
+ solveid : (BP,R,Vector L BP) -> Union(L BP,"failed")
+ ++ solveid(h,table) computes the coefficients of the
+ ++ extended euclidean algorithm for a list of polynomials
+ ++ whose tablePow is table and with right side h.
+
+ testModulus : (R, L BP) -> Boolean
+ ++ testModulus(p,lp) returns true if the the prime p
+ ++ is valid for the list of polynomials lp, i.e. preserves
+ ++ the degree and they remain relatively prime.
+
+ T == add
+ if R has multiplicativeValuation then
+ compBound(m:BP,listpolys:L BP) : NNI ==
+ ldeg:=[degree f for f in listpolys]
+ n:NNI:= (+/[df for df in ldeg])
+ normlist:=[ +/[euclideanSize(u)**2 for u in coefficients f]
+ for f in listpolys]
+ nm:= +/[euclideanSize(u)**2 for u in coefficients m]
+ normprod := */[g**((n-df)::NNI) for g in normlist for df in ldeg]
+ 2*(approxSqrt(normprod * nm)$IntegerRoots(Integer))::NNI
+ else if R has additiveValuation then
+ -- a fairly crude Hadamard-style bound for the solution
+ -- based on regarding the problem as a system of linear equations.
+ compBound(m:BP,listpolys:L BP) : NNI ==
+ "max"/[euclideanSize u for u in coefficients m] +
+ +/["max"/[euclideanSize u for u in coefficients p]
+ for p in listpolys]
+ else
+ compBound(m:BP,listpolys:L BP) : NNI ==
+ error "attempt to use compBound without a well-understood valuation"
+ if R has IntegerNumberSystem then
+ reduction(u:BP,p:R):BP ==
+ p = 0 => u
+ map(symmetricRemainder(#1,p),u)
+ else reduction(u:BP,p:R):BP ==
+ p = 0 => u
+ map(#1 rem p,u)
+
+ merge(p:R,q:R):Union(R,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ modInverse(c:R,p:R):R ==
+ (extendedEuclidean(c,p,1)::Record(coef1:R,coef2:R)).coef1
+
+ exactquo(u:BP,v:BP,p:R):Union(BP,"failed") ==
+ invlcv:=modInverse(leadingCoefficient v,p)
+ r:=monicDivide(u,reduction(invlcv*v,p))
+ reduction(r.remainder,p) ^=0 => "failed"
+ reduction(invlcv*r.quotient,p)
+
+ FP:=EuclideanModularRing(R,BP,R,reduction,merge,exactquo)
+
+ --make table global variable!
+ table:Vector L BP
+ import GeneralHenselPackage(R,BP)
+
+ --local functions
+ makeProducts : L BP -> L BP
+ liftSol: (L BP,BP,R,R,Vector L BP,BP,NNI) -> Union(L BP,"failed")
+
+ reduceList(lp:L BP,lmod:R): L FP ==[reduce(ff,lmod) for ff in lp]
+
+ coerceLFP(lf:L FP):L BP == [fm::BP for fm in lf]
+
+ liftSol(oldsol:L BP,err:BP,lmod:R,lmodk:R,
+ table:Vector L BP,m:BP,bound:NNI):Union(L BP,"failed") ==
+ euclideanSize(lmodk) > bound => "failed"
+ d:=degree err
+ ftab:Vector L FP :=
+ map(reduceList(#1,lmod),table)$VectorFunctions2(List BP,List FP)
+ sln:L FP:=[0$FP for xx in ftab.1 ]
+ for i in 0 .. d |(cc:=coefficient(err,i)) ^=0 repeat
+ sln:=[slp+reduce(cc::BP,lmod)*pp
+ for pp in ftab.(i+1) for slp in sln]
+ nsol:=[f-lmodk*reduction(g::BP,lmod) for f in oldsol for g in sln]
+ lmodk1:=lmod*lmodk
+ nsol:=[reduction(slp,lmodk1) for slp in nsol]
+ lpolys:L BP:=table.(#table)
+ (fs:=+/[f*g for f in lpolys for g in nsol]) = m => nsol
+ a:BP:=((fs-m) exquo lmodk1)::BP
+ liftSol(nsol,a,lmod,lmodk1,table,m,bound)
+
+ makeProducts(listPol:L BP):L BP ==
+ #listPol < 2 => listPol
+ #listPol = 2 => reverse listPol
+ f:= first listPol
+ ll := rest listPol
+ [*/ll,:[f*g for g in makeProducts ll]]
+
+ testModulus(pmod, listPol) ==
+ redListPol := reduceList(listPol, pmod)
+ for pol in listPol for rpol in redListPol repeat
+ degree(pol) ^= degree(rpol::BP) => return false
+ while not empty? redListPol repeat
+ rpol := first redListPol
+ redListPol := rest redListPol
+ for rpol2 in redListPol repeat
+ gcd(rpol, rpol2) ^= 1 => return false
+ true
+
+ if R has Field then
+ tablePow(mdeg:NNI,pmod:R,listPol:L BP) ==
+ multiE:=multiEuclidean(listPol,1$BP)
+ multiE case "failed" => "failed"
+ ptable:Vector L BP :=new(mdeg+1,[])
+ ptable.1:=multiE
+ x:BP:=monomial(1,1)
+ for i in 2..mdeg repeat ptable.i:=
+ [tpol*x rem fpol for tpol in ptable.(i-1) for fpol in listPol]
+ ptable.(mdeg+1):=makeProducts listPol
+ ptable
+
+ solveid(m:BP,pmod:R,table:Vector L BP) : Union(L BP,"failed") ==
+ -- Actually, there's no possibility of failure
+ d:=degree m
+ sln:L BP:=[0$BP for xx in table.1]
+ for i in 0 .. d | coefficient(m,i)^=0 repeat
+ sln:=[slp+coefficient(m,i)*pp
+ for pp in table.(i+1) for slp in sln]
+ sln
+
+ else
+
+ tablePow(mdeg:NNI,pmod:R,listPol:L BP) ==
+ listP:L FP:= [reduce(pol,pmod) for pol in listPol]
+ multiE:=multiEuclidean(listP,1$FP)
+ multiE case "failed" => "failed"
+ ftable:Vector L FP :=new(mdeg+1,[])
+ fl:L FP:= [ff::FP for ff in multiE]
+ ftable.1:=[fpol for fpol in fl]
+ x:FP:=reduce(monomial(1,1),pmod)
+ for i in 2..mdeg repeat ftable.i:=
+ [tpol*x rem fpol for tpol in ftable.(i-1) for fpol in listP]
+ ptable:= map(coerceLFP,ftable)$VectorFunctions2(List FP,List BP)
+ ptable.(mdeg+1):=makeProducts listPol
+ ptable
+
+ solveid(m:BP,pmod:R,table:Vector L BP) : Union(L BP,"failed") ==
+ d:=degree m
+ ftab:Vector L FP:=
+ map(reduceList(#1,pmod),table)$VectorFunctions2(List BP,List FP)
+ lpolys:L BP:=table.(#table)
+ sln:L FP:=[0$FP for xx in ftab.1]
+ for i in 0 .. d | coefficient(m,i)^=0 repeat
+ sln:=[slp+reduce(coefficient(m,i)::BP,pmod)*pp
+ for pp in ftab.(i+1) for slp in sln]
+ soln:=[slp::BP for slp in sln]
+ (fs:=+/[f*g for f in lpolys for g in soln]) = m=> soln
+ -- Compute bound
+ bound:=compBound(m,lpolys)
+ a:BP:=((fs-m) exquo pmod)::BP
+ liftSol(soln,a,pmod,pmod,table,m,bound)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GENEEZ GenExEuclid>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/generic.spad.pamphlet b/src/algebra/generic.spad.pamphlet
new file mode 100644
index 00000000..611284be
--- /dev/null
+++ b/src/algebra/generic.spad.pamphlet
@@ -0,0 +1,406 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra generic.spad}
+\author{Johannes Grabmeier, Robert Wisbauer}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain GCNAALG GenericNonAssociativeAlgebra}
+<<domain GCNAALG GenericNonAssociativeAlgebra>>=
+)abbrev domain GCNAALG GenericNonAssociativeAlgebra
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 26 June 1991
+++ Date Last Updated: 26 June 1991
+++ Basic Operations: generic
+++ Related Constructors: AlgebraPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords: generic element. rank polynomial
+++ Reference:
+++ A. Woerz-Busekros: Algebra in Genetics
+++ Lectures Notes in Biomathematics 36,
+++ Springer-Verlag, Heidelberg, 1980
+++ Description:
+++ AlgebraGenericElementPackage allows you to create generic elements
+++ of an algebra, i.e. the scalars are extended to include symbolic
+++ coefficients
+GenericNonAssociativeAlgebra(R : CommutativeRing, n : PositiveInteger,_
+ ls : List Symbol, gamma: Vector Matrix R ): public == private where
+
+ NNI ==> NonNegativeInteger
+ V ==> Vector
+ PR ==> Polynomial R
+ FPR ==> Fraction Polynomial R
+ SUP ==> SparseUnivariatePolynomial
+ S ==> Symbol
+
+ public ==> Join(FramedNonAssociativeAlgebra(FPR), _
+ LeftModule(SquareMatrix(n,FPR)) ) with
+
+ coerce : Vector FPR -> %
+ ++ coerce(v) assumes that it is called with a vector
+ ++ of length equal to the dimension of the algebra, then
+ ++ a linear combination with the basis element is formed
+ leftUnits:() -> Union(Record(particular: %, basis: List %), "failed")
+ ++ leftUnits() returns the affine space of all left units of the
+ ++ algebra, or \spad{"failed"} if there is none
+ rightUnits:() -> Union(Record(particular: %, basis: List %), "failed")
+ ++ rightUnits() returns the affine space of all right units of the
+ ++ algebra, or \spad{"failed"} if there is none
+ generic : () -> %
+ ++ generic() returns a generic element, i.e. the linear combination
+ ++ of the fixed basis with the symbolic coefficients
+ ++ \spad{%x1,%x2,..}
+ generic : Symbol -> %
+ ++ generic(s) returns a generic element, i.e. the linear combination
+ ++ of the fixed basis with the symbolic coefficients
+ ++ \spad{s1,s2,..}
+ generic : Vector Symbol -> %
+ ++ generic(vs) returns a generic element, i.e. the linear combination
+ ++ of the fixed basis with the symbolic coefficients
+ ++ \spad{vs};
+ ++ error, if the vector of symbols is too short
+ generic : Vector % -> %
+ ++ generic(ve) returns a generic element, i.e. the linear combination
+ ++ of \spad{ve} basis with the symbolic coefficients
+ ++ \spad{%x1,%x2,..}
+ generic : (Symbol, Vector %) -> %
+ ++ generic(s,v) returns a generic element, i.e. the linear combination
+ ++ of v with the symbolic coefficients
+ ++ \spad{s1,s2,..}
+ generic : (Vector Symbol, Vector %) -> %
+ ++ generic(vs,ve) returns a generic element, i.e. the linear combination
+ ++ of \spad{ve} with the symbolic coefficients \spad{vs}
+ ++ error, if the vector of symbols is shorter than the vector of
+ ++ elements
+ if R has IntegralDomain then
+ leftRankPolynomial : () -> SparseUnivariatePolynomial FPR
+ ++ leftRankPolynomial() returns the left minimimal polynomial
+ ++ of the generic element
+ genericLeftMinimalPolynomial : % -> SparseUnivariatePolynomial FPR
+ ++ genericLeftMinimalPolynomial(a) substitutes the coefficients
+ ++ of {em a} for the generic coefficients in
+ ++ \spad{leftRankPolynomial()}
+ genericLeftTrace : % -> FPR
+ ++ genericLeftTrace(a) substitutes the coefficients
+ ++ of \spad{a} for the generic coefficients into the
+ ++ coefficient of the second highest term in
+ ++ \spadfun{leftRankPolynomial} and changes the sign.
+ ++ This is a linear form
+ genericLeftNorm : % -> FPR
+ ++ genericLeftNorm(a) substitutes the coefficients
+ ++ of \spad{a} for the generic coefficients into the
+ ++ coefficient of the constant term in \spadfun{leftRankPolynomial}
+ ++ and changes the sign if the degree of this polynomial is odd.
+ ++ This is a form of degree k
+ rightRankPolynomial : () -> SparseUnivariatePolynomial FPR
+ ++ rightRankPolynomial() returns the right minimimal polynomial
+ ++ of the generic element
+ genericRightMinimalPolynomial : % -> SparseUnivariatePolynomial FPR
+ ++ genericRightMinimalPolynomial(a) substitutes the coefficients
+ ++ of \spad{a} for the generic coefficients in
+ ++ \spadfun{rightRankPolynomial}
+ genericRightTrace : % -> FPR
+ ++ genericRightTrace(a) substitutes the coefficients
+ ++ of \spad{a} for the generic coefficients into the
+ ++ coefficient of the second highest term in
+ ++ \spadfun{rightRankPolynomial} and changes the sign
+ genericRightNorm : % -> FPR
+ ++ genericRightNorm(a) substitutes the coefficients
+ ++ of \spad{a} for the generic coefficients into the
+ ++ coefficient of the constant term in \spadfun{rightRankPolynomial}
+ ++ and changes the sign if the degree of this polynomial is odd
+ genericLeftTraceForm : (%,%) -> FPR
+ ++ genericLeftTraceForm (a,b) is defined to be
+ ++ \spad{genericLeftTrace (a*b)}, this defines
+ ++ a symmetric bilinear form on the algebra
+ genericLeftDiscriminant: () -> FPR
+ ++ genericLeftDiscriminant() is the determinant of the
+ ++ generic left trace forms of all products of basis element,
+ ++ if the generic left trace form is associative, an algebra
+ ++ is separable if the generic left discriminant is invertible,
+ ++ if it is non-zero, there is some ring extension which
+ ++ makes the algebra separable
+ genericRightTraceForm : (%,%) -> FPR
+ ++ genericRightTraceForm (a,b) is defined to be
+ ++ \spadfun{genericRightTrace (a*b)}, this defines
+ ++ a symmetric bilinear form on the algebra
+ genericRightDiscriminant: () -> FPR
+ ++ genericRightDiscriminant() is the determinant of the
+ ++ generic left trace forms of all products of basis element,
+ ++ if the generic left trace form is associative, an algebra
+ ++ is separable if the generic left discriminant is invertible,
+ ++ if it is non-zero, there is some ring extension which
+ ++ makes the algebra separable
+ conditionsForIdempotents: Vector % -> List Polynomial R
+ ++ conditionsForIdempotents([v1,...,vn]) determines a complete list
+ ++ of polynomial equations for the coefficients of idempotents
+ ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}
+ conditionsForIdempotents: () -> List Polynomial R
+ ++ conditionsForIdempotents() determines a complete list
+ ++ of polynomial equations for the coefficients of idempotents
+ ++ with respect to the fixed \spad{R}-module basis
+
+ private ==> AlgebraGivenByStructuralConstants(FPR,n,ls,_
+ coerce(gamma)$CoerceVectorMatrixPackage(R) ) add
+
+ listOfNumbers : List String := [STRINGIMAGE(q)$Lisp for q in 1..n]
+ symbolsForCoef : V Symbol :=
+ [concat("%", concat("x", i))::Symbol for i in listOfNumbers]
+ genericElement : % :=
+ v : Vector PR :=
+ [monomial(1$PR, [symbolsForCoef.i],[1]) for i in 1..n]
+ convert map(coerce,v)$VectorFunctions2(PR,FPR)
+
+ eval : (FPR, %) -> FPR
+ eval(rf,a) ==
+ -- for the moment we only substitute the numerators
+ -- of the coefficients
+ coefOfa : List PR :=
+ map(numer, entries coordinates a)$ListFunctions2(FPR,PR)
+ ls : List PR :=[monomial(1$PR, [s],[1]) for s in entries symbolsForCoef]
+ lEq : List Equation PR := []
+ for i in 1..maxIndex ls repeat
+ lEq := cons(equation(ls.i,coefOfa.i)$Equation(PR) , lEq)
+ top : PR := eval(numer(rf),lEq)$PR
+ bot : PR := eval(numer(rf),lEq)$PR
+ top/bot
+
+
+ if R has IntegralDomain then
+
+ genericLeftTraceForm(a,b) == genericLeftTrace(a*b)
+ genericLeftDiscriminant() ==
+ listBasis : List % := entries basis()$%
+ m : Matrix FPR := matrix
+ [[genericLeftTraceForm(a,b) for a in listBasis] for b in listBasis]
+ determinant m
+
+ genericRightTraceForm(a,b) == genericRightTrace(a*b)
+ genericRightDiscriminant() ==
+ listBasis : List % := entries basis()$%
+ m : Matrix FPR := matrix
+ [[genericRightTraceForm(a,b) for a in listBasis] for b in listBasis]
+ determinant m
+
+
+
+ leftRankPoly : SparseUnivariatePolynomial FPR := 0
+ initLeft? : Boolean :=true
+
+ initializeLeft: () -> Void
+ initializeLeft() ==
+ -- reset initialize flag
+ initLeft?:=false
+ leftRankPoly := leftMinimalPolynomial genericElement
+ void()$Void
+
+ rightRankPoly : SparseUnivariatePolynomial FPR := 0
+ initRight? : Boolean :=true
+
+ initializeRight: () -> Void
+ initializeRight() ==
+ -- reset initialize flag
+ initRight?:=false
+ rightRankPoly := rightMinimalPolynomial genericElement
+ void()$Void
+
+ leftRankPolynomial() ==
+ if initLeft? then initializeLeft()
+ leftRankPoly
+
+ rightRankPolynomial() ==
+ if initRight? then initializeRight()
+ rightRankPoly
+
+ genericLeftMinimalPolynomial a ==
+ if initLeft? then initializeLeft()
+ map(eval(#1,a),leftRankPoly)$SUP(FPR)
+
+ genericRightMinimalPolynomial a ==
+ if initRight? then initializeRight()
+ map(eval(#1,a),rightRankPoly)$SUP(FPR)
+
+ genericLeftTrace a ==
+ if initLeft? then initializeLeft()
+ d1 : NNI := (degree leftRankPoly - 1) :: NNI
+ rf : FPR := coefficient(leftRankPoly, d1)
+ rf := eval(rf,a)
+ - rf
+
+ genericRightTrace a ==
+ if initRight? then initializeRight()
+ d1 : NNI := (degree rightRankPoly - 1) :: NNI
+ rf : FPR := coefficient(rightRankPoly, d1)
+ rf := eval(rf,a)
+ - rf
+
+ genericLeftNorm a ==
+ if initLeft? then initializeLeft()
+ rf : FPR := coefficient(leftRankPoly, 1)
+ if odd? degree leftRankPoly then rf := - rf
+ rf
+
+ genericRightNorm a ==
+ if initRight? then initializeRight()
+ rf : FPR := coefficient(rightRankPoly, 1)
+ if odd? degree rightRankPoly then rf := - rf
+ rf
+
+ conditionsForIdempotents(b: V %) : List Polynomial R ==
+ x : % := generic(b)
+ map(numer,entries coordinates(x*x-x,b))$ListFunctions2(FPR,PR)
+
+ conditionsForIdempotents(): List Polynomial R ==
+ x : % := genericElement
+ map(numer,entries coordinates(x*x-x))$ListFunctions2(FPR,PR)
+
+ generic() == genericElement
+
+ generic(vs:V S, ve: V %): % ==
+ maxIndex v > maxIndex ve =>
+ error "generic: too little symbols"
+ v : Vector PR :=
+ [monomial(1$PR, [vs.i],[1]) for i in 1..maxIndex ve]
+ represents(map(coerce,v)$VectorFunctions2(PR,FPR),ve)
+
+ generic(s: S, ve: V %): % ==
+ lON : List String := [STRINGIMAGE(q)$Lisp for q in 1..maxIndex ve]
+ sFC : Vector Symbol :=
+ [concat(s pretend String, i)::Symbol for i in lON]
+ generic(sFC, ve)
+
+ generic(ve : V %) ==
+ lON : List String := [STRINGIMAGE(q)$Lisp for q in 1..maxIndex ve]
+ sFC : Vector Symbol :=
+ [concat("%", concat("x", i))::Symbol for i in lON]
+ v : Vector PR :=
+ [monomial(1$PR, [sFC.i],[1]) for i in 1..maxIndex ve]
+ represents(map(coerce,v)$VectorFunctions2(PR,FPR),ve)
+
+ generic(vs:V S): % == generic(vs, basis()$%)
+
+ generic(s: S): % == generic(s, basis()$%)
+
+)fin
+ -- variations on eval
+ --coefOfa : List FPR := entries coordinates a
+ --ls : List Symbol := entries symbolsForCoef
+ -- a very dangerous sequential implementation for the moment,
+ -- because the compiler doesn't manage the parallel code
+ -- also doesn't run:
+ -- not known that (Fraction (Polynomial R)) has (has (Polynomial R)
+ -- (Evalable (Fraction (Polynomial R))))
+ --res : FPR := rf
+ --for eq in lEq repeat res := eval(res,eq)$FPR
+ --res
+ --rf
+ --eval(rf, le)$FPR
+ --eval(rf, entries symbolsForCoef, coefOfa)$FPR
+ --eval(rf, ls, coefOfa)$FPR
+ --le : List Equation PR := [equation(lh,rh) for lh in ls for rh in coefOfa]
+
+@
+\section{package CVMP CoerceVectorMatrixPackage}
+<<package CVMP CoerceVectorMatrixPackage>>=
+)abbrev package CVMP CoerceVectorMatrixPackage
+++ Authors: J. Grabmeier
+++ Date Created: 26 June 1991
+++ Date Last Updated: 26 June 1991
+++ Basic Operations: coerceP, coerce
+++ Related Constructors: GenericNonAssociativeAlgebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Reference:
+++ Description:
+++ CoerceVectorMatrixPackage: an unexposed, technical package
+++ for data conversions
+CoerceVectorMatrixPackage(R : CommutativeRing): public == private where
+ M2P ==> MatrixCategoryFunctions2(R, Vector R, Vector R, Matrix R, _
+ Polynomial R, Vector Polynomial R, Vector Polynomial R, Matrix Polynomial R)
+ M2FP ==> MatrixCategoryFunctions2(R, Vector R, Vector R, Matrix R, _
+ Fraction Polynomial R, Vector Fraction Polynomial R, _
+ Vector Fraction Polynomial R, Matrix Fraction Polynomial R)
+ public ==> with
+ coerceP: Vector Matrix R -> Vector Matrix Polynomial R
+ ++ coerceP(v) coerces a vector v with entries in \spadtype{Matrix R}
+ ++ as vector over \spadtype{Matrix Polynomial R}
+ coerce: Vector Matrix R -> Vector Matrix Fraction Polynomial R
+ ++ coerce(v) coerces a vector v with entries in \spadtype{Matrix R}
+ ++ as vector over \spadtype{Matrix Fraction Polynomial R}
+ private ==> add
+
+ imbedFP : R -> Fraction Polynomial R
+ imbedFP r == (r:: Polynomial R) :: Fraction Polynomial R
+
+ imbedP : R -> Polynomial R
+ imbedP r == (r:: Polynomial R)
+
+ coerceP(g:Vector Matrix R) : Vector Matrix Polynomial R ==
+ m2 : Matrix Polynomial R
+ lim : List Matrix R := entries g
+ l: List Matrix Polynomial R := []
+ for m in lim repeat
+ m2 := map(imbedP,m)$M2P
+ l := cons(m2,l)
+ vector reverse l
+
+ coerce(g:Vector Matrix R) : Vector Matrix Fraction Polynomial R ==
+ m3 : Matrix Fraction Polynomial R
+ lim : List Matrix R := entries g
+ l: List Matrix Fraction Polynomial R := []
+ for m in lim repeat
+ m3 := map(imbedFP,m)$M2FP
+ l := cons(m3,l)
+ vector reverse l
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain GCNAALG GenericNonAssociativeAlgebra>>
+<<package CVMP CoerceVectorMatrixPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/genufact.spad.pamphlet b/src/algebra/genufact.spad.pamphlet
new file mode 100644
index 00000000..94ae4328
--- /dev/null
+++ b/src/algebra/genufact.spad.pamphlet
@@ -0,0 +1,116 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra genufact.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GENUFACT GenUFactorize}
+<<package GENUFACT GenUFactorize>>=
+)abbrev package GENUFACT GenUFactorize
+++ Description
+++ This package provides operations for the factorization of univariate polynomials with integer
+++ coefficients. The factorization is done by "lifting" the
+++ finite "berlekamp's" factorization
+GenUFactorize(R) : public == private where
+ R : EuclideanDomain
+ PR ==> SparseUnivariatePolynomial R -- with factor
+ -- should be UnivariatePolynomialCategory
+ NNI ==> NonNegativeInteger
+ SUP ==> SparseUnivariatePolynomial
+
+
+ public == with
+ factor : PR -> Factored PR
+ ++ factor(p) returns the factorisation of p
+
+ private == add
+
+ -- Factorisation currently fails when algebraic extensions have multiple
+ -- generators.
+ factorWarning(f:OutputForm):Void ==
+ import AnyFunctions1(String)
+ import AnyFunctions1(OutputForm)
+ outputList(["WARNING (genufact): No known algorithm to factor "::Any, _
+ f::Any, _
+ ", trying square-free."::Any])$OutputPackage
+
+ factor(f:PR) : Factored PR ==
+ R is Integer => (factor f)$GaloisGroupFactorizer(PR)
+
+ R is Fraction Integer =>
+ (factor f)$RationalFactorize(PR)
+
+-- R has Field and R has Finite =>
+ R has FiniteFieldCategory =>
+ (factor f)$DistinctDegreeFactorize(R,PR)
+
+ R is (Complex Integer) => (factor f)$ComplexFactorization(Integer,PR)
+
+ R is (Complex Fraction Integer) =>
+ (factor f)$ComplexFactorization(Fraction Integer,PR)
+
+ R is AlgebraicNumber => (factor f)$AlgFactor(PR)
+
+ -- following is to handle SAE
+ R has generator : () -> R =>
+ var := symbol(convert(generator()::OutputForm)@InputForm)
+ up:=UnivariatePolynomial(var,Fraction Integer)
+ R has MonogenicAlgebra(Fraction Integer, up) =>
+ factor(f)$SimpleAlgebraicExtensionAlgFactor(up, R, PR)
+ upp:=UnivariatePolynomial(var,Fraction Polynomial Integer)
+ R has MonogenicAlgebra(Fraction Polynomial Integer, upp) =>
+ factor(f)$SAERationalFunctionAlgFactor(upp, R, PR)
+ factorWarning(f::OutputForm)
+ squareFree f
+ factorWarning(f::OutputForm)
+ squareFree f
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GENUFACT GenUFactorize>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/genups.spad.pamphlet b/src/algebra/genups.spad.pamphlet
new file mode 100644
index 00000000..efc99560
--- /dev/null
+++ b/src/algebra/genups.spad.pamphlet
@@ -0,0 +1,249 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra genups.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GENUPS GenerateUnivariatePowerSeries}
+<<package GENUPS GenerateUnivariatePowerSeries>>=
+)abbrev package GENUPS GenerateUnivariatePowerSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 29 April 1990
+++ Date Last Updated: 31 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Taylor, Laurent, Puiseux
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{GenerateUnivariatePowerSeries} provides functions that create
+++ power series from explicit formulas for their \spad{n}th coefficient.
+GenerateUnivariatePowerSeries(R,FE): Exports == Implementation where
+ R : Join(IntegralDomain,OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+ ANY1 ==> AnyFunctions1
+ EQ ==> Equation
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+ SEG ==> UniversalSegment
+ ST ==> Stream
+ SY ==> Symbol
+ UTS ==> UnivariateTaylorSeries
+ ULS ==> UnivariateLaurentSeries
+ UPXS ==> UnivariatePuiseuxSeries
+
+ Exports ==> with
+ taylor: (I -> FE,EQ FE) -> Any
+ ++ \spad{taylor(n +-> a(n),x = a)} returns
+ ++ \spad{sum(n = 0..,a(n)*(x-a)**n)}.
+ taylor: (FE,SY,EQ FE) -> Any
+ ++ \spad{taylor(a(n),n,x = a)} returns \spad{sum(n = 0..,a(n)*(x-a)**n)}.
+ taylor: (I -> FE,EQ FE,SEG NNI) -> Any
+ ++ \spad{taylor(n +-> a(n),x = a,n0..)} returns
+ ++ \spad{sum(n=n0..,a(n)*(x-a)**n)};
+ ++ \spad{taylor(n +-> a(n),x = a,n0..n1)} returns
+ ++ \spad{sum(n = n0..,a(n)*(x-a)**n)}.
+ taylor: (FE,SY,EQ FE,SEG NNI) -> Any
+ ++ \spad{taylor(a(n),n,x = a,n0..)} returns
+ ++ \spad{sum(n = n0..,a(n)*(x-a)**n)};
+ ++ \spad{taylor(a(n),n,x = a,n0..n1)} returns
+ ++ \spad{sum(n = n0..,a(n)*(x-a)**n)}.
+
+ laurent: (I -> FE,EQ FE,SEG I) -> Any
+ ++ \spad{laurent(n +-> a(n),x = a,n0..)} returns
+ ++ \spad{sum(n = n0..,a(n) * (x - a)**n)};
+ ++ \spad{laurent(n +-> a(n),x = a,n0..n1)} returns
+ ++ \spad{sum(n = n0..n1,a(n) * (x - a)**n)}.
+ laurent: (FE,SY,EQ FE,SEG I) -> Any
+ ++ \spad{laurent(a(n),n,x=a,n0..)} returns
+ ++ \spad{sum(n = n0..,a(n) * (x - a)**n)};
+ ++ \spad{laurent(a(n),n,x=a,n0..n1)} returns
+ ++ \spad{sum(n = n0..n1,a(n) * (x - a)**n)}.
+
+ puiseux: (RN -> FE,EQ FE,SEG RN,RN) -> Any
+ ++ \spad{puiseux(n +-> a(n),x = a,r0..,r)} returns
+ ++ \spad{sum(n = r0,r0 + r,r0 + 2*r..., a(n) * (x - a)**n)};
+ ++ \spad{puiseux(n +-> a(n),x = a,r0..r1,r)} returns
+ ++ \spad{sum(n = r0 + k*r while n <= r1, a(n) * (x - a)**n)}.
+ puiseux: (FE,SY,EQ FE,SEG RN,RN) -> Any
+ ++ \spad{puiseux(a(n),n,x = a,r0..,r)} returns
+ ++ \spad{sum(n = r0,r0 + r,r0 + 2*r..., a(n) * (x - a)**n)};
+ ++ \spad{puiseux(a(n),n,x = a,r0..r1,r)} returns
+ ++ \spad{sum(n = r0 + k*r while n <= r1, a(n) * (x - a)**n)}.
+
+ series: (I -> FE,EQ FE) -> Any
+ ++ \spad{series(n +-> a(n),x = a)} returns
+ ++ \spad{sum(n = 0..,a(n)*(x-a)**n)}.
+ series: (FE,SY,EQ FE) -> Any
+ ++ \spad{series(a(n),n,x = a)} returns
+ ++ \spad{sum(n = 0..,a(n)*(x-a)**n)}.
+ series: (I -> FE,EQ FE,SEG I) -> Any
+ ++ \spad{series(n +-> a(n),x = a,n0..)} returns
+ ++ \spad{sum(n = n0..,a(n) * (x - a)**n)};
+ ++ \spad{series(n +-> a(n),x = a,n0..n1)} returns
+ ++ \spad{sum(n = n0..n1,a(n) * (x - a)**n)}.
+ series: (FE,SY,EQ FE,SEG I) -> Any
+ ++ \spad{series(a(n),n,x=a,n0..)} returns
+ ++ \spad{sum(n = n0..,a(n) * (x - a)**n)};
+ ++ \spad{series(a(n),n,x=a,n0..n1)} returns
+ ++ \spad{sum(n = n0..n1,a(n) * (x - a)**n)}.
+ series: (RN -> FE,EQ FE,SEG RN,RN) -> Any
+ ++ \spad{series(n +-> a(n),x = a,r0..,r)} returns
+ ++ \spad{sum(n = r0,r0 + r,r0 + 2*r..., a(n) * (x - a)**n)};
+ ++ \spad{series(n +-> a(n),x = a,r0..r1,r)} returns
+ ++ \spad{sum(n = r0 + k*r while n <= r1, a(n) * (x - a)**n)}.
+ series: (FE,SY,EQ FE,SEG RN,RN) -> Any
+ ++ \spad{series(a(n),n,x = a,r0..,r)} returns
+ ++ \spad{sum(n = r0,r0 + r,r0 + 2*r..., a(n) * (x - a)**n)};
+ ++ \spad{series(a(n),n,x = a,r0..r1,r)} returns
+ ++ \spad{sum(n = r0 + k*r while n <= r1, a(n) * (x - a)**n)}.
+
+ Implementation ==> add
+
+ genStream: (I -> FE,I) -> ST FE
+ genStream(f,n) == delay concat(f(n),genStream(f,n + 1))
+
+ genFiniteStream: (I -> FE,I,I) -> ST FE
+ genFiniteStream(f,n,m) == delay
+ n > m => empty()
+ concat(f(n),genFiniteStream(f,n + 1,m))
+
+ taylor(f,eq) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ coerce(series(genStream(f,0))$UTS(FE,x,a))$ANY1(UTS(FE,x,a))
+
+ taylor(an:FE,n:SY,eq:EQ FE) ==
+ taylor(eval(an,(n :: FE) = (#1 :: FE)),eq)
+
+ taylor(f:I -> FE,eq:EQ FE,seg:SEG NNI) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ hasHi seg =>
+ n0 := lo seg; n1 := hi seg
+ if n1 < n0 then (n0,n1) := (n1,n0)
+ uts := series(genFiniteStream(f,n0,n1))$UTS(FE,x,a)
+ uts := uts * monomial(1,n0)$UTS(FE,x,a)
+ coerce(uts)$ANY1(UTS(FE,x,a))
+ n0 := lo seg
+ uts := series(genStream(f,n0))$UTS(FE,x,a)
+ uts := uts * monomial(1,n0)$UTS(FE,x,a)
+ coerce(uts)$ANY1(UTS(FE,x,a))
+
+ taylor(an,n,eq,seg) ==
+ taylor(eval(an,(n :: FE) = (#1 :: FE)),eq,seg)
+
+ laurent(f,eq,seg) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "taylor: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ hasHi seg =>
+ n0 := lo seg; n1 := hi seg
+ if n1 < n0 then (n0,n1) := (n1,n0)
+ uts := series(genFiniteStream(f,n0,n1))$UTS(FE,x,a)
+ coerce(laurent(n0,uts)$ULS(FE,x,a))$ANY1(ULS(FE,x,a))
+ n0 := lo seg
+ uts := series(genStream(f,n0))$UTS(FE,x,a)
+ coerce(laurent(n0,uts)$ULS(FE,x,a))$ANY1(ULS(FE,x,a))
+
+ laurent(an,n,eq,seg) ==
+ laurent(eval(an,(n :: FE) = (#1 :: FE)),eq,seg)
+
+ modifyFcn:(RN -> FE,I,I,I,I) -> FE
+ modifyFcn(f,n0,nn,q,m) == (zero?((m - n0) rem nn) => f(m/q); 0)
+
+ puiseux(f,eq,seg,r) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "puiseux: left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ not positive? r => error "puiseux: last argument must be positive"
+ hasHi seg =>
+ r0 := lo seg; r1 := hi seg
+ if r1 < r0 then (r0,r1) := (r1,r0)
+ p0 := numer r0; q0 := denom r0
+ p1 := numer r1; q1 := denom r1
+ p2 := numer r; q2 := denom r
+ q := lcm(lcm(q0,q1),q2)
+ n0 := p0 * (q quo q0); n1 := p1 * (q quo q1)
+ nn := p2 * (q quo q2)
+ ulsUnion := laurent(modifyFcn(f,n0,nn,q,#1),eq,segment(n0,n1))
+ uls := retract(ulsUnion)$ANY1(ULS(FE,x,a))
+ coerce(puiseux(1/q,uls)$UPXS(FE,x,a))$ANY1(UPXS(FE,x,a))
+ p0 := numer(r0 := lo seg); q0 := denom r0
+ p2 := numer r; q2 := denom r
+ q := lcm(q0,q2)
+ n0 := p0 * (q quo q0); nn := p2 * (q quo q2)
+ ulsUnion := laurent(modifyFcn(f,n0,nn,q,#1),eq,segment n0)
+ uls := retract(ulsUnion)$ANY1(ULS(FE,x,a))
+ coerce(puiseux(1/q,uls)$UPXS(FE,x,a))$ANY1(UPXS(FE,x,a))
+
+ puiseux(an,n,eq,r0,m) ==
+ puiseux(eval(an,(n :: FE) = (#1 :: FE)),eq,r0,m)
+
+ series(f:I -> FE,eq:EQ FE) == puiseux(f(numer #1),eq,segment 0,1)
+ series(an:FE,n:SY,eq:EQ FE) == puiseux(an,n,eq,segment 0,1)
+ series(f:I -> FE,eq:EQ FE,seg:SEG I) ==
+ ratSeg : SEG RN := map(#1::RN,seg)$UniversalSegmentFunctions2(I,RN)
+ puiseux(f(numer #1),eq,ratSeg,1)
+ series(an:FE,n:SY,eq:EQ FE,seg:SEG I) ==
+ ratSeg : SEG RN := map(#1::RN,seg)$UniversalSegmentFunctions2(I,RN)
+ puiseux(an,n,eq,ratSeg,1)
+ series(f:RN -> FE,eq:EQ FE,seg:SEG RN,r:RN) == puiseux(f,eq,seg,r)
+ series(an:FE,n:SY,eq:EQ FE,seg:SEG RN,r:RN) == puiseux(an,n,eq,seg,r)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GENUPS GenerateUnivariatePowerSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ghensel.spad.pamphlet b/src/algebra/ghensel.spad.pamphlet
new file mode 100644
index 00000000..79d49c13
--- /dev/null
+++ b/src/algebra/ghensel.spad.pamphlet
@@ -0,0 +1,202 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ghensel.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GHENSEL GeneralHenselPackage}
+<<package GHENSEL GeneralHenselPackage>>=
+)abbrev package GHENSEL GeneralHenselPackage
+++ Author : P.Gianni
+++ General Hensel Lifting
+++ Used for Factorization of bivariate polynomials over a finite field.
+GeneralHenselPackage(RP,TP):C == T where
+ RP : EuclideanDomain
+ TP : UnivariatePolynomialCategory RP
+
+ PI ==> PositiveInteger
+
+ C == with
+ HenselLift: (TP,List(TP),RP,PI) -> Record(plist:List(TP), modulo:RP)
+ ++ HenselLift(pol,lfacts,prime,bound) lifts lfacts,
+ ++ that are the factors of pol mod prime,
+ ++ to factors of pol mod prime**k > bound. No recombining is done .
+
+ completeHensel: (TP,List(TP),RP,PI) -> List TP
+ ++ completeHensel(pol,lfact,prime,bound) lifts lfact,
+ ++ the factorization mod prime of pol,
+ ++ to the factorization mod prime**k>bound.
+ ++ Factors are recombined on the way.
+
+ reduction : (TP,RP) -> TP
+ ++ reduction(u,pol) computes the symmetric reduction of u mod pol
+
+ T == add
+ GenExEuclid: (List(FP),List(FP),FP) -> List(FP)
+ HenselLift1: (TP,List(TP),List(FP),List(FP),RP,RP,F) -> List(TP)
+ mQuo: (TP,RP) -> TP
+
+ reduceCoef(c:RP,p:RP):RP ==
+ zero? p => c
+ RP is Integer => symmetricRemainder(c,p)
+ c rem p
+
+ reduction(u:TP,p:RP):TP ==
+ zero? p => u
+ RP is Integer => map(symmetricRemainder(#1,p),u)
+ map(#1 rem p,u)
+
+ merge(p:RP,q:RP):Union(RP,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ modInverse(c:RP,p:RP):RP ==
+ (extendedEuclidean(c,p,1)::Record(coef1:RP,coef2:RP)).coef1
+
+ exactquo(u:TP,v:TP,p:RP):Union(TP,"failed") ==
+ invlcv:=modInverse(leadingCoefficient v,p)
+ r:=monicDivide(u,reduction(invlcv*v,p))
+ reduction(r.remainder,p) ^=0 => "failed"
+ reduction(invlcv*r.quotient,p)
+
+ FP:=EuclideanModularRing(RP,TP,RP,reduction,merge,exactquo)
+
+ mQuo(poly:TP,n:RP) : TP == map(#1 quo n,poly)
+
+ GenExEuclid(fl:List FP,cl:List FP,rhs:FP) :List FP ==
+ [clp*rhs rem flp for clp in cl for flp in fl]
+
+ -- generate the possible factors
+ genFact(fln:List TP,factlist:List List TP) : List List TP ==
+ factlist=[] => [[pol] for pol in fln]
+ maxd := +/[degree f for f in fln] quo 2
+ auxfl:List List TP := []
+ for poly in fln while factlist^=[] repeat
+ factlist := [term for term in factlist | ^member?(poly,term)]
+ dp := degree poly
+ for term in factlist repeat
+ (+/[degree f for f in term]) + dp > maxd => "next term"
+ auxfl := cons(cons(poly,term),auxfl)
+ auxfl
+
+ HenselLift1(poly:TP,fln:List TP,fl1:List FP,cl1:List FP,
+ prime:RP,Modulus:RP,cinv:RP):List TP ==
+ lcp := leadingCoefficient poly
+ rhs := reduce(mQuo(poly - lcp * */fln,Modulus),prime)
+ zero? rhs => fln
+ lcinv:=reduce(cinv::TP,prime)
+ vl := GenExEuclid(fl1,cl1,lcinv*rhs)
+ [flp + Modulus*(vlp::TP) for flp in fln for vlp in vl]
+
+ HenselLift(poly:TP,tl1:List TP,prime:RP,bound:PI) ==
+ -- convert tl1
+ constp:TP:=0
+ if degree first tl1 = 0 then
+ constp:=tl1.first
+ tl1 := rest tl1
+ fl1:=[reduce(ttl,prime) for ttl in tl1]
+ cl1 := multiEuclidean(fl1,1)::List FP
+ Modulus:=prime
+ fln :List TP := [ffl1::TP for ffl1 in fl1]
+ lcinv:RP:=retract((inv
+ (reduce((leadingCoefficient poly)::TP,prime)))::TP)
+ while euclideanSize(Modulus)<bound repeat
+ nfln:=HenselLift1(poly,fln,fl1,cl1,prime,Modulus,lcinv)
+ fln = nfln and zero?(err:=poly-*/fln) => leave "finished"
+ fln := nfln
+ Modulus := prime*Modulus
+ if constp^=0 then fln:=cons(constp,fln)
+ [fln,Modulus]
+
+ completeHensel(m:TP,tl1:List TP,prime:RP,bound:PI) ==
+ hlift:=HenselLift(m,tl1,prime,bound)
+ Modulus:RP:=hlift.modulo
+ fln:List TP:=hlift.plist
+ nm := degree m
+ u:Union(TP,"failed")
+ aux,auxl,finallist:List TP
+ auxfl,factlist:List List TP
+ factlist := []
+ dfn :NonNegativeInteger := nm
+ lcm1 := leadingCoefficient m
+ mm := lcm1*m
+ while dfn>0 and (factlist := genFact(fln,factlist))^=[] repeat
+ auxfl := []
+ while factlist^=[] repeat
+ auxl := factlist.first
+ factlist := factlist.rest
+ tc := reduceCoef((lcm1 * */[coefficient(poly,0)
+ for poly in auxl]), Modulus)
+ coefficient(mm,0) exquo tc case "failed" =>
+ auxfl := cons(auxl,auxfl)
+ pol := */[poly for poly in auxl]
+ poly :=reduction(lcm1*pol,Modulus)
+ u := mm exquo poly
+ u case "failed" => auxfl := cons(auxl,auxfl)
+ poly1: TP := primitivePart poly
+ m := mQuo((u::TP),leadingCoefficient poly1)
+ lcm1 := leadingCoefficient(m)
+ mm := lcm1*m
+ finallist := cons(poly1,finallist)
+ dfn := degree m
+ aux := []
+ for poly in fln repeat
+ ^member?(poly,auxl) => aux := cons(poly,aux)
+ auxfl := [term for term in auxfl | ^member?(poly,term)]
+ factlist := [term for term in factlist |^member?(poly,term)]
+ fln := aux
+ factlist := auxfl
+ if dfn > 0 then finallist := cons(m,finallist)
+ finallist
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GHENSEL GeneralHenselPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gpgcd.spad.pamphlet b/src/algebra/gpgcd.spad.pamphlet
new file mode 100644
index 00000000..bf758915
--- /dev/null
+++ b/src/algebra/gpgcd.spad.pamphlet
@@ -0,0 +1,691 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gpgcd.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GENPGCD GeneralPolynomialGcdPackage}
+<<package GENPGCD GeneralPolynomialGcdPackage>>=
+)abbrev package GENPGCD GeneralPolynomialGcdPackage
+++ Description:
+++ This package provides operations for GCD computations
+++ on polynomials
+GeneralPolynomialGcdPackage(E,OV,R,P):C == T where
+ R : PolynomialFactorizationExplicit
+ P : PolynomialCategory(R,E,OV)
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+
+ SUPP ==> SparseUnivariatePolynomial P
+--JHD ContPrim ==> Record(cont:P,prim:P)
+
+ C == with
+ gcdPolynomial : (SUPP,SUPP) -> SUPP
+ ++ gcdPolynomial(p,q) returns the GCD of p and q
+ randomR : () ->R
+ ++ randomR() should be local but conditional
+--JHD gcd : (P,P) -> P
+--JHD gcd : List P -> P
+--JHD gcdprim : (P,P) -> P
+--JHD gcdprim : List P -> P
+
+--JHD gcdcofact : List P -> List P
+--JHD gcdcofactprim : List P -> List P
+
+--JHD primitate : (P,OV) -> P
+--JHD primitate : SUPP -> SUPP
+
+--JHD content : P -> P
+--JHD content : List P -> List P
+--JHD contprim : List P -> List ContPrim
+
+--JHD monomContent : (P,OV) -> P
+--JHD monomContent : SUPP -> SUPP
+
+
+ T == add
+
+ SUPR ==> SparseUnivariatePolynomial R
+--JHD SUPLGcd ==> Record(locgcd:SUPP,goodint:List R)
+--JHD LGcd ==> Record(locgcd:P,goodint:List R)
+--JHD UTerm ==> Record(lpol:List SUPR,lint:List R,mpol:P)
+--JHD--JHD pmod:R := (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
+
+--JHD import MultivariateLifting(E,OV,R,P,pmod)
+ import UnivariatePolynomialCategoryFunctions2(R,SUPR,P,SUPP)
+ import UnivariatePolynomialCategoryFunctions2(P,SUPP,R,SUPR)
+ -------- Local Functions --------
+
+--JHD abs : P -> P
+ better : (P,P) -> Boolean
+--JHD failtest : (P,P,P) -> Boolean
+--JHD gcdMonom : (P,P,OV) -> P
+--JHD gcdTermList : (P,P) -> P
+--JHD gcdPrim : (P,P,OV) -> P
+--JHD gcdSameMainvar : (P,P,OV) -> P
+--JHD internal : (P,P,OV) -> P
+--JHD good : (P,List OV) -> Record(upol:SUPR,inval:List R)
+--JHD gcdPrs : (P,P,NNI,OV) -> Union(P,"failed")
+--JHD
+--JHD chooseVal : (P,P,List OV) -> UTerm
+--JHD localgcd : (P,P,List OV) -> LGcd
+--JHD notCoprime : (P,P, List NNI,List OV) -> P
+--JHD imposelc : (List SUPR,List OV,List R,List P) -> List SUPR
+
+--JHD lift? :(P,P,UTerm,List NNI,List OV) -> Union("failed",P)
+-- lift :(P,SUPR,SUPR,P,List OV,List NNI,List R) -> P
+ lift : (SUPR,SUPP,SUPR,List OV,List R) -> Union(SUPP,"failed")
+ -- lifts first and third arguments as factors of the second
+ -- fourth is number of variables.
+--JHD monomContent : (P,OV) -> P
+ monomContentSup : SUPP -> SUPP
+--
+--JHD gcdcofact : List P -> List P
+
+ gcdTrivial : (SUPP,SUPP) -> SUPP
+ gcdSameVariables: (SUPP,SUPP,List OV) -> SUPP
+ recursivelyGCDCoefficients: (SUPP,List OV,SUPP,List OV) -> SUPP
+ flatten : (SUPP,List OV) -> SUPP
+ -- evaluates out all variables in the second
+ -- argument, leaving a polynomial of the same
+ -- degree
+-- eval : (SUPP,List OV,List R) -> SUPP
+ variables : SUPP -> List OV
+ ---- JHD's exported functions ---
+ gcdPolynomial(p1:SUPP,p2:SUPP) ==
+ zero? p1 => p2
+ zero? p2 => p1
+ 0=degree p1 => gcdTrivial(p1,p2)
+ 0=degree p2 => gcdTrivial(p2,p1)
+ if degree p1 < degree p2 then (p1,p2):=(p2,p1)
+ p1 exquo p2 case SUPP => (unitNormal p2).canonical
+ c1:= monomContentSup(p1)
+ c2:= monomContentSup(p2)
+ p1:= (p1 exquo c1)::SUPP
+ p2:= (p2 exquo c2)::SUPP
+ (p1 exquo p2) case SUPP => (unitNormal p2).canonical * gcd(c1,c2)
+ vp1:=variables p1
+ vp2:=variables p2
+ v1:=setDifference(vp1,vp2)
+ v2:=setDifference(vp2,vp1)
+ #v1 = 0 and #v2 = 0 => gcdSameVariables(p1,p2,vp1)*gcd(c1,c2)
+ -- all variables are in common
+ v:=setDifference(vp1,v1)
+ pp1:=flatten(p1,v1)
+ pp2:=flatten(p2,v2)
+ g:=gcdSameVariables(pp1,pp2,v)
+-- one? g => gcd(c1,c2)::SUPP
+ (g = 1) => gcd(c1,c2)::SUPP
+ (#v1 = 0 or not (p1 exquo g) case "failed") and
+ -- if #vi = 0 then pp1 = p1, so we know g divides
+ (#v2 = 0 or not (p2 exquo g) case "failed")
+ => g*gcd(c1,c2) -- divdes them both, so is the gcd
+ -- OK, so it's not the gcd: try again
+ v:=variables g -- there can be at most these variables in answer
+ v1:=setDifference(vp1,v)
+ v2:=setDifference(vp2,v)
+ if (#v1 = 0) then g:= gcdSameVariables(g,flatten(p2,v2),v)
+ else if (#v2=0) then g:=gcdSameVariables(g,flatten(p1,v1),v)
+ else g:=gcdSameVariables(g,flatten(p1,v1)-flatten(p2,v2),v)
+-- one? g => gcd(c1,c2)::SUPP
+ (g = 1) => gcd(c1,c2)::SUPP
+ (#v1 = 0 or not (p1 exquo g) case "failed") and
+ (#v2 = 0 or not (p2 exquo g) case "failed")
+ => g*gcd(c1,c2)::SUPP -- divdes them both, so is the gcd
+ v:=variables g -- there can be at most these variables in answer
+ v1:=setDifference(vp1,v)
+ if #v1 ^= 0 then
+ g:=recursivelyGCDCoefficients(g,v,p1,v1)
+-- one? g => return gcd(c1,c2)::SUPP
+ (g = 1) => return gcd(c1,c2)::SUPP
+ v:=variables g -- there can be at most these variables in answer
+ v2:=setDifference(vp2,v)
+ recursivelyGCDCoefficients(g,v,p2,v2)*gcd(c1,c2)
+ if R has StepThrough then
+ randomCount:R := init()
+ randomR() ==
+ (v:=nextItem(randomCount)) case R =>
+ randomCount:=v
+ v
+ SAY("Taking next stepthrough range in GeneralPolynomialGcdPackage")$Lisp
+ randomCount:=init()
+ randomCount
+ else
+ randomR() == (random$Integer() rem 100)::R
+ ---- JHD's local functions ---
+ gcdSameVariables(p1:SUPP,p2:SUPP,lv:List OV) ==
+ -- two non-trivial primitive (or, at least, we don't care
+ -- about content)
+ -- polynomials with precisely the same degree
+ #lv = 0 => map(#1::P,gcdPolynomial(map(ground,p1),
+ map(ground,p2)))
+ degree p2 = 1 =>
+ p1 exquo p2 case SUPP => p2
+ 1
+ gcdLC:=gcd(leadingCoefficient p1,leadingCoefficient p2)
+ lr:=[randomR() for vv in lv]
+ count:NonNegativeInteger:=0
+ while count<10 repeat
+ while zero? eval(gcdLC,lv,lr) and count<10 repeat
+ lr:=[randomR() for vv in lv]
+ count:=count+1
+ count = 10 => error "too many evaluations in GCD code"
+ up1:SUPR:=map(ground eval(#1,lv,lr),p1)
+ up2:SUPR:=map(ground eval(#1,lv,lr),p2)
+ u:=gcdPolynomial(up1,up2)
+ degree u = 0 => return 1
+ -- let's pick a second one, just to check
+ lrr:=[randomR() for vv in lv]
+ while zero? eval(gcdLC,lv,lrr) and count<10 repeat
+ lrr:=[randomR() for vv in lv]
+ count:=count+1
+ count = 10 => error "too many evaluations in GCD code"
+ vp1:SUPR:=map(ground eval(#1,lv,lrr),p1)
+ vp2:SUPR:=map(ground eval(#1,lv,lrr),p2)
+ v:=gcdPolynomial(vp1,vp2)
+ degree v = 0 => return 1
+ if degree v < degree u then
+ u:=v
+ up1:=vp1
+ up2:=vp2
+ lr:=lrr
+ up1:=(up1 exquo u)::SUPR
+ degree gcd(u,up1) = 0 =>
+ ans:=lift(u,p1,up1,lv,lr)
+ ans case SUPP => return ans
+ "next"
+ up2:=(up2 exquo u)::SUPR
+ degree gcd(u,up2) = 0 =>
+ ans:=lift(u,p2,up2,lv,lr)
+ ans case SUPP => return ans
+ "next"
+ -- so neither cofactor is relatively prime
+ count:=0
+ while count < 10 repeat
+ r:=randomR()
+ uu:=up1+r*up2
+ degree gcd(u,uu)=0 =>
+ ans:= lift(u,p1+r::P *p2,uu,lv,lr)
+ ans case SUPP => return ans
+ "next"
+ error "too many evaluations in GCD code"
+ count >= 10 => error "too many evaluations in GCD code"
+ lift(gR:SUPR,p:SUPP,cfR:SUPR,lv:List OV,lr:List R) ==
+ -- lift the coprime factorisation gR*cfR = (univariate of p)
+ -- where the variables lv have been evaluated at lr
+ lcp:=leadingCoefficient p
+ g:=monomial(lcp,degree gR)+map(#1::P,reductum gR)
+ cf:=monomial(lcp,degree cfR)+map(#1::P,reductum cfR)
+ p:=lcp*p -- impose leaidng coefficient of p on each factor
+ while lv ^= [] repeat
+ v:=first lv
+ r:=first lr
+ lv:=rest lv
+ lr:=rest lr
+ thisp:=map(eval(#1,lv,lr),p)
+ d:="max"/[degree(c,v) for c in coefficients p]
+ prime:=v::P - r::P
+ pn:=prime
+ origFactors:=[g,cf]::List SUPP
+ for n in 1..d repeat
+ Ecart:=(thisp- g*cf) exquo pn
+ Ecart case "failed" =>
+ error "failed lifting in hensel in Complex Polynomial GCD"
+ zero? Ecart => leave
+ step:=solveLinearPolynomialEquation(origFactors,
+ map(eval(#1,v,r),Ecart::SUPP))
+ step case "failed" => return "failed"
+ g:=g+pn*first step
+ cf:=cf+pn*second step
+ pn:=pn*prime
+ thisp ^= g*cf => return "failed"
+ g
+ recursivelyGCDCoefficients(g:SUPP,v:List OV,p:SUPP,pv:List OV) ==
+ mv:=first pv -- take each coefficient w.r.t. mv
+ pv:=rest pv -- and recurse on pv as necessary
+ d:="max"/[degree(u,mv) for u in coefficients p]
+ for i in 0..d repeat
+ p1:=map(coefficient(#1,mv,i),p)
+ oldg:=g
+ if pv = [] then g:=gcdSameVariables(g,p1,v)
+ else g:=recursivelyGCDCoefficients(p,v,p1,pv)
+-- one? g => return 1
+ (g = 1) => return 1
+ g^=oldg =>
+ oldv:=v
+ v:=variables g
+ pv:=setUnion(pv,setDifference(v,oldv))
+ g
+ flatten(p1:SUPP,lv:List OV) ==
+ #lv = 0 => p1
+ lr:=[ randomR() for vv in lv]
+ dg:=degree p1
+ while dg ^= degree (ans:= map(eval(#1,lv,lr),p1)) repeat
+ lr:=[ randomR() for vv in lv]
+ ans
+-- eval(p1:SUPP,lv:List OV,lr:List R) == map(eval(#1,lv,lr),p1)
+ variables(p1:SUPP) ==
+ removeDuplicates ("concat"/[variables u for u in coefficients p1])
+ gcdTrivial(p1:SUPP,p2:SUPP) ==
+ -- p1 is non-zero, but has degree zero
+ -- p2 is non-zero
+ cp1:=leadingCoefficient p1
+-- one? cp1 => 1
+ (cp1 = 1) => 1
+ degree p2 = 0 => gcd(cp1,leadingCoefficient p2)::SUPP
+ un?:=unit? cp1
+ while not zero? p2 and not un? repeat
+ cp1:=gcd(leadingCoefficient p2,cp1)
+ un?:=unit? cp1
+ p2:=reductum p2
+ un? => 1
+ cp1::SUPP
+
+ ---- Local functions ----
+--JHD -- test if something wrong happened in the gcd
+--JHD failtest(f:P,p1:P,p2:P) : Boolean ==
+--JHD (p1 exquo f) case "failed" or (p2 exquo f) case "failed"
+--JHD
+--JHD -- Choose the integers
+--JHD chooseVal(p1:P,p2:P,lvar:List OV):UTerm ==
+--JHD x:OV:=lvar.first
+--JHD lvr:=lvar.rest
+--JHD d1:=degree(p1,x)
+--JHD d2:=degree(p2,x)
+--JHD dd:NNI:=0$NNI
+--JHD nvr:NNI:=#lvr
+--JHD lval:List R :=[]
+--JHD range:I:=8
+--JHD for i in 1.. repeat
+--JHD range:=2*range
+--JHD lval:=[(random()$I rem (2*range) - range)::R for i in 1..nvr]
+--JHD uf1:SUPR:=univariate eval(p1,lvr,lval)
+--JHD degree uf1 ^= d1 => "new point"
+--JHD uf2:SUPR:=univariate eval(p2,lvr,lval)
+--JHD degree uf2 ^= d2 => "new point"
+--JHD u:=gcd(uf1,uf2)
+--JHD du:=degree u
+--JHD --the univariate gcd is 1
+--JHD if du=0 then return [[1$SUPR],lval,0$P]$UTerm
+--JHD
+--JHD ugcd:List SUPR:=[u,(uf1 exquo u)::SUPR,(uf2 exquo u)::SUPR]
+--JHD uterm:=[ugcd,lval,0$P]$UTerm
+--JHD dd=0 => dd:=du
+--JHD
+--JHD --the degree is not changed
+--JHD du=dd =>
+--JHD
+--JHD --test if one of the polynomials is the gcd
+--JHD dd=d1 =>
+--JHD if ^((f:=p2 exquo p1) case "failed") then
+--JHD return [[u],lval,p1]$UTerm
+--JHD if dd^=d2 then dd:=(dd-1)::NNI
+--JHD
+--JHD dd=d2 =>
+--JHD if ^((f:=p1 exquo p2) case "failed") then
+--JHD return [[u],lval,p2]$UTerm
+--JHD dd:=(dd-1)::NNI
+--JHD return uterm
+--JHD
+--JHD --the new gcd has degree less
+--JHD du<dd => dd:=du
+--JHD
+--JHD good(f:P,lvr:List OV):Record(upol:SUPR,inval:List R) ==
+--JHD nvr:NNI:=#lvr
+--JHD range:I:=1
+--JHD ltry:List List R:=[]
+--JHD while true repeat
+--JHD range:=2*range
+--JHD lval:=[(random()$I rem (2*range) -range)::R for i in 1..nvr]
+--JHD member?(lval,ltry) => "new point"
+--JHD ltry:=cons(lval,ltry)
+--JHD uf:=univariate eval(f,lvr,lval)
+--JHD if degree gcd(uf,differentiate uf)=0 then return [uf,lval]
+--JHD
+--JHD -- impose the right lc
+--JHD imposelc(lipol:List SUPR,
+--JHD lvar:List OV,lval:List R,leadc:List P):List SUPR ==
+--JHD result:List SUPR :=[]
+--JHD lvar:=lvar.rest
+--JHD for pol in lipol for leadpol in leadc repeat
+--JHD p1:= univariate eval(leadpol,lvar,lval) * pol
+--JHD result:= cons((p1 exquo leadingCoefficient pol)::SUPR,result)
+--JHD reverse result
+--JHD
+--JHD --Compute the gcd between not coprime polynomials
+--JHD notCoprime(g:P,p2:P,ldeg:List NNI,lvar:List OV) : P ==
+--JHD x:OV:=lvar.first
+--JHD lvar1:List OV:=lvar.rest
+--JHD lg1:=gcdcofact([g,differentiate(g,x)])
+--JHD g1:=lg1.1
+--JHD lg:LGcd:=localgcd(g1,p2,lvar)
+--JHD (l,lval):=(lg.locgcd,lg.goodint)
+--JHD p2:=(p2 exquo l)::P
+--JHD (gd1,gd2):=(l,l)
+--JHD ul:=univariate(eval(l,lvar1,lval))
+--JHD dl:=degree ul
+--JHD if degree gcd(ul,differentiate ul) ^=0 then
+--JHD newchoice:=good(l,lvar.rest)
+--JHD ul:=newchoice.upol
+--JHD lval:=newchoice.inval
+--JHD ug1:=univariate(eval(g1,lvar1,lval))
+--JHD ulist:=[ug1,univariate eval(p2,lvar1,lval)]
+--JHD lcpol:=[leadingCoefficient univariate(g1,x),
+--JHD leadingCoefficient univariate(p2,x)]
+--JHD while true repeat
+--JHD d:SUPR:=gcd(cons(ul,ulist))
+--JHD if degree d =0 then return gd1
+--JHD lquo:=(ul exquo d)::SUPR
+--JHD if degree lquo ^=0 then
+--JHD lgcd:=gcd(cons(leadingCoefficient univariate(l,x),lcpol))
+--JHD gd2:=lift(l,d,lquo,lgcd,lvar,ldeg,lval)
+--JHD l:=gd2
+--JHD ul:=univariate(eval(l,lvar1,lval))
+--JHD dl:=degree ul
+--JHD gd1:=gd1*gd2
+--JHD ulist:=[(uf exquo d)::SUPR for uf in ulist]
+--JHD
+--JHD -- we suppose that the poly have the same mainvar, deg p1<deg p2 and the
+--JHD -- polys primitive
+--JHD internal(p1:P,p2:P,x:OV) : P ==
+--JHD lvar:List OV:=sort(#1>#2,setUnion(variables p1,variables p2))
+--JHD d1:=degree(p1,x)
+--JHD d2:=degree(p2,x)
+--JHD result: P:=localgcd(p1,p2,lvar).locgcd
+--JHD -- special cases
+--JHD result=1 => 1$P
+--JHD (dr:=degree(result,x))=d1 or dr=d2 => result
+--JHD while failtest(result,p1,p2) repeat
+--JHD SAY$Lisp "retrying gcd"
+--JHD result:=localgcd(p1,p2,lvar).locgcd
+--JHD result
+--JHD
+--JHD --local function for the gcd : it returns the evaluation point too
+--JHD localgcd(p1:P,p2:P,lvar:List(OV)) : LGcd ==
+--JHD x:OV:=lvar.first
+--JHD uterm:=chooseVal(p1,p2,lvar)
+--JHD listpol:= uterm.lpol
+--JHD ud:=listpol.first
+--JHD dd:= degree ud
+--JHD
+--JHD --the univariate gcd is 1
+--JHD dd=0 => [1$P,uterm.lint]$LGcd
+--JHD
+--JHD --one of the polynomials is the gcd
+--JHD dd=degree(p1,x) or dd=degree(p2,x) =>
+--JHD [uterm.mpol,uterm.lint]$LGcd
+--JHD ldeg:List NNI:=map(min,degree(p1,lvar),degree(p2,lvar))
+--JHD
+--JHD -- if there is a polynomial g s.t. g/gcd and gcd are coprime ...
+--JHD -- I can lift
+--JHD (h:=lift?(p1,p2,uterm,ldeg,lvar)) case "failed" =>
+--JHD [notCoprime(p1,p2,ldeg,lvar),uterm.lint]$LGcd
+--JHD [h::P,uterm.lint]$LGcd
+--JHD
+--JHD
+--JHD -- content, internal functions return the poly if it is a monomial
+--JHD monomContent(p:P,var:OV):P ==
+--JHD ground? p => 1$P
+--JHD md:= minimumDegree(p,var)
+--JHD ((var::P)**md)*(gcd sort(better,coefficients univariate(p,var)))
+
+ monomContentSup(u:SUPP):SUPP ==
+ degree(u) = 0$NonNegativeInteger => 1$SUPP
+ md:= minimumDegree u
+ gcd(sort(better,coefficients u)) * monomial(1$P,md)$SUPP
+
+--JHD -- change the polynomials to have positive lc
+--JHD abs(p:P): P == unitNormal(p).canonical
+
+ -- Ordering for gcd purposes
+ better(p1:P,p2:P):Boolean ==
+ ground? p1 => true
+ ground? p2 => false
+ degree(p1,mainVariable(p1)::OV) < degree(p2,mainVariable(p2)::OV)
+
+ -- PRS algorithm
+ -- gcdPrs(p1:P,p2:P,d:NNI,var:OV):Union(P,"failed") ==
+ -- u1:= univariate(p1,var)
+ -- u2:= univariate(p2,var)
+ -- finished:Boolean:= false
+ -- until finished repeat
+ -- dd:NNI:=(degree u1 - degree u2)::NNI
+ -- lc1:SUPP:=leadingCoefficient u2 * reductum u1
+ -- lc2:SUPP:=leadingCoefficient u1 * reductum u2
+ -- u3:SUPP:= primitate((lc1-lc2)*monomial(1$P,dd))$%
+ -- (d3:=degree(u3)) <= d => finished:= true
+ -- u1:= u2
+ -- u2:= u3
+ -- if d3 > degree(u1) then (u1,u2):= (u2,u1)
+ -- g:= (u2 exquo u3)
+ -- g case SUPP => abs multivariate(u3,var)
+ -- "failed"
+
+ -- Gcd between polynomial p1 and p2 with
+ -- mainVariable p1 < x=mainVariable p2
+--JHD gcdTermList(p1:P,p2:P) : P ==
+--JHD termList:=sort(better,
+--JHD cons(p1,coefficients univariate(p2,(mainVariable p2)::OV)))
+--JHD q:P:=termList.first
+--JHD for term in termList.rest until q = 1$P repeat q:= gcd(q,term)
+--JHD q
+--JHD
+--JHD -- Gcd between polynomials with the same mainVariable
+--JHD gcdSameMainvar(p1:P,p2:P,mvar:OV): P ==
+--JHD if degree(p1,mvar) < degree(p2,mvar) then (p1,p2):= (p2,p1)
+--JHD (p1 exquo p2) case P => abs p2
+--JHD c1:= monomContent(p1,mvar)$%
+--JHD c1 = p1 => gcdMonom(p1,p2,mvar)
+--JHD c2:= monomContent(p2,mvar)$%
+--JHD c2 = p2 => gcdMonom(p2,p1,mvar)
+--JHD p1:= (p1 exquo c1)::P
+--JHD p2:= (p2 exquo c2)::P
+--JHD if degree(p1,mvar) < degree(p2,mvar) then (p1,p2):= (p2,p1)
+--JHD (p1 exquo p2) case P => abs(p2) * gcd(c1,c2)
+--JHD abs(gcdPrim(p1,p2,mvar)) * gcd(c1,c2)
+--JHD
+--JHD -- make the polynomial primitive with respect to var
+--JHD primitate(p:P,var:OV):P == (p exquo monomContent(p,var))::P
+--JHD
+--JHD primitate(u:SUPP):SUPP == (u exquo monomContentSup u)::SUPP
+--JHD
+--JHD -- gcd between primitive polynomials with the same mainVariable
+--JHD gcdPrim(p1:P,p2:P,mvar:OV):P ==
+--JHD vars:= removeDuplicates append(variables p1,variables p2)
+--JHD #vars=1 => multivariate(gcd(univariate p1,univariate p2),mvar)
+--JHD vars:=delete(vars,position(mvar,vars))
+--JHD --d:= degModGcd(p1,p2,mvar,vars)
+--JHD --d case "failed" => internal(p2,p1,mvar)
+--JHD --deg:= d:NNI
+--JHD --deg = 0$NNI => 1$P
+--JHD --deg = degree(p1,mvar) =>
+--JHD -- (p2 exquo p1) case P => abs(p1) -- already know that
+--JHD -- ^(p1 exquo p2)
+--JHD -- internal(p2,p1,mvar)
+--JHD --cheapPrs?(p1,p2,deg,mvar) =>
+--JHD -- g:= gcdPrs(p1,p2,deg,mvar)
+--JHD -- g case P => g::P
+--JHD -- internal(p2,p1,mvar)
+--JHD internal(p2,p1,mvar)
+--JHD
+--JHD -- gcd between a monomial and a polynomial
+--JHD gcdMonom(m:P,p:P,var:OV):P ==
+--JHD ((var::P) ** min(minimumDegree(m,var),minimumDegree(p,var))) *
+--JHD gcdTermList(leadingCoefficient(univariate(m,var)),p)
+--JHD
+--JHD --If there is a pol s.t. pol/gcd and gcd are coprime I can lift
+--JHD lift?(p1:P,p2:P,uterm:UTerm,ldeg:List NNI,
+--JHD lvar:List OV) : Union("failed",P) ==
+--JHD x:OV:=lvar.first
+--JHD leadpol:Boolean:=false
+--JHD (listpol,lval):=(uterm.lpol,uterm.lint)
+--JHD d:=listpol.first
+--JHD listpol:=listpol.rest
+--JHD nolift:Boolean:=true
+--JHD for uf in listpol repeat
+--JHD --note uf and d not necessarily primitive
+--JHD degree gcd(uf,d) =0 => nolift:=false
+--JHD nolift => "failed"
+--JHD f:P:=([p1,p2]$List(P)).(position(uf,listpol))
+--JHD lgcd:=gcd(leadingCoefficient univariate(p1,x),
+--JHD leadingCoefficient univariate(p2,x))
+--JHD lift(f,d,uf,lgcd,lvar,ldeg,lval)
+--JHD
+--JHD -- interface with the general "lifting" function
+--JHD lift(f:P,d:SUPR,uf:SUPR,lgcd:P,lvar:List OV,
+--JHD ldeg:List NNI,lval:List R):P ==
+--JHD x:OV:=lvar.first
+--JHD leadpol:Boolean:=false
+--JHD lcf:P
+--JHD lcf:=leadingCoefficient univariate(f,x)
+--JHD df:=degree(f,x)
+--JHD leadlist:List(P):=[]
+--JHD
+--JHD if lgcd^=1$P then
+--JHD leadpol:=true
+--JHD f:=lgcd*f
+--JHD ldeg:=[n0+n1 for n0 in ldeg for n1 in degree(lgcd,lvar)]
+--JHD lcd:R:=leadingCoefficient d
+--JHD if ground? lgcd then d:=((retract lgcd) *d exquo lcd)::SUPR
+--JHD else d:=(retract(eval(lgcd,lvar.rest,lval)) * d exquo lcd)::SUPR
+--JHD uf:=lcd*uf
+--JHD leadlist:=[lgcd,lcf]
+--JHD lg:=imposelc([d,uf],lvar,lval,leadlist)
+--JHD plist:=lifting(univariate(f,x),lvar,lg,lval,leadlist,ldeg)::List P
+--JHD (p0:P,p1:P):=(plist.first,plist.2)
+--JHD if univariate eval(p0,rest lvar,lval) ^= lg.first then
+--JHD (p0,p1):=(p1,p0)
+--JHD ^leadpol => p0
+--JHD cprim:=contprim([p0])
+--JHD cprim.first.prim
+--JHD
+--JHD -- Gcd for two multivariate polynomials
+--JHD gcd(p1:P,p2:P) : P ==
+--JHD (p1:= abs(p1)) = (p2:= abs(p2)) => p1
+--JHD ground? p1 =>
+--JHD p1 = 1$P => p1
+--JHD p1 = 0$P => p2
+--JHD ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
+--JHD gcdTermList(p1,p2)
+--JHD ground? p2 =>
+--JHD p2 = 1$P => p2
+--JHD p2 = 0$P => p1
+--JHD gcdTermList(p2,p1)
+--JHD mv1:= mainVariable(p1)::OV
+--JHD mv2:= mainVariable(p2)::OV
+--JHD mv1 = mv2 => gcdSameMainvar(p1,p2,mv1)
+--JHD mv1 < mv2 => gcdTermList(p1,p2)
+--JHD gcdTermList(p2,p1)
+--JHD
+--JHD -- Gcd for a list of multivariate polynomials
+--JHD gcd(listp:List P) : P ==
+--JHD lf:=sort(better,listp)
+--JHD f:=lf.first
+--JHD for g in lf.rest repeat
+--JHD f:=gcd(f,g)
+--JHD if f=1$P then return f
+--JHD f
+--JHD -- Gcd and cofactors for a list of polynomials
+--JHD gcdcofact(listp : List P) : List P ==
+--JHD h:=gcd listp
+--JHD cons(h,[(f exquo h) :: P for f in listp])
+--JHD
+--JHD -- Gcd for primitive polynomials
+--JHD gcdprim(p1:P,p2:P):P ==
+--JHD (p1:= abs(p1)) = (p2:= abs(p2)) => p1
+--JHD ground? p1 =>
+--JHD ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
+--JHD p1 = 0$P => p2
+--JHD 1$P
+--JHD ground? p2 =>
+--JHD p2 = 0$P => p1
+--JHD 1$P
+--JHD mv1:= mainVariable(p1)::OV
+--JHD mv2:= mainVariable(p2)::OV
+--JHD mv1 = mv2 =>
+--JHD md:=min(minimumDegree(p1,mv1),minimumDegree(p2,mv1))
+--JHD mp:=1$P
+--JHD if md>1 then
+--JHD mp:=(mv1::P)**md
+--JHD p1:=(p1 exquo mp)::P
+--JHD p2:=(p2 exquo mp)::P
+--JHD mp*gcdPrim(p1,p2,mv1)
+--JHD 1$P
+--JHD
+--JHD -- Gcd for a list of primitive multivariate polynomials
+--JHD gcdprim(listp:List P) : P ==
+--JHD lf:=sort(better,listp)
+--JHD f:=lf.first
+--JHD for g in lf.rest repeat
+--JHD f:=gcdprim(f,g)
+--JHD if f=1$P then return f
+--JHD f
+--JHD -- Gcd and cofactors for a list of primitive polynomials
+--JHD gcdcofactprim(listp : List P) : List P ==
+--JHD h:=gcdprim listp
+--JHD cons(h,[(f exquo h) :: P for f in listp])
+--JHD
+--JHD -- content of a polynomial (with respect to its main var)
+--JHD content(f:P):P ==
+--JHD ground? f => f
+--JHD x:OV:=(mainVariable f)::OV
+--JHD gcd sort(better,coefficients univariate(f,x))
+--JHD
+--JHD -- contents of a list of polynomials
+--JHD content(listf:List P) : List P == [content f for f in listf]
+--JHD
+--JHD -- contents and primitive parts of a list of polynomials
+--JHD contprim(listf:List P) : List ContPrim ==
+--JHD prelim :List P := content listf
+--JHD [[q,(f exquo q)::P]$ContPrim for q in prelim for f in listf]
+--JHD
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GENPGCD GeneralPolynomialGcdPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gpol.spad.pamphlet b/src/algebra/gpol.spad.pamphlet
new file mode 100644
index 00000000..a4563b03
--- /dev/null
+++ b/src/algebra/gpol.spad.pamphlet
@@ -0,0 +1,214 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gpol.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain LAUPOL LaurentPolynomial}
+<<domain LAUPOL LaurentPolynomial>>=
+)abbrev domain LAUPOL LaurentPolynomial
+++ Univariate polynomials with negative and positive exponents.
+++ Author: Manuel Bronstein
+++ Date Created: May 1988
+++ Date Last Updated: 26 Apr 1990
+LaurentPolynomial(R, UP): Exports == Implementation where
+ R : IntegralDomain
+ UP: UnivariatePolynomialCategory R
+
+ O ==> OutputForm
+ B ==> Boolean
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+
+ Exports ==> Join(DifferentialExtension UP, IntegralDomain,
+ ConvertibleTo RF, FullyRetractableTo R, RetractableTo UP) with
+ monomial? : % -> B
+ ++ monomial?(x) \undocumented
+ degree : % -> Z
+ ++ degree(x) \undocumented
+ order : % -> Z
+ ++ order(x) \undocumented
+ reductum : % -> %
+ ++ reductum(x) \undocumented
+ leadingCoefficient : % -> R
+ ++ leadingCoefficient \undocumented
+ trailingCoefficient: % -> R
+ ++ trailingCoefficient \undocumented
+ coefficient : (%, Z) -> R
+ ++ coefficient(x,n) \undocumented
+ monomial : (R, Z) -> %
+ ++ monomial(x,n) \undocumented
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has Field then
+ EuclideanDomain
+ separate: RF -> Record(polyPart:%, fracPart:RF)
+ ++ separate(x) \undocumented
+
+ Implementation ==> add
+ Rep := Record(polypart: UP, order0: Z)
+
+ poly : % -> UP
+ check0 : (Z, UP) -> %
+ mkgpol : (Z, UP) -> %
+ gpol : (UP, Z) -> %
+ toutput: (R, Z, O) -> O
+ monTerm: (R, Z, O) -> O
+
+ 0 == [0, 0]
+ 1 == [1, 0]
+ p = q == p.order0 = q.order0 and p.polypart = q.polypart
+ poly p == p.polypart
+ order p == p.order0
+ gpol(p, n) == [p, n]
+ monomial(r, n) == check0(n, r::UP)
+ coerce(p:UP):% == mkgpol(0, p)
+ reductum p == check0(order p, reductum poly p)
+ n:Z * p:% == check0(order p, n * poly p)
+ characteristic() == characteristic()$R
+ coerce(n:Z):% == n::R::%
+ degree p == degree(poly p)::Z + order p
+ monomial? p == monomial? poly p
+ coerce(r:R):% == gpol(r::UP, 0)
+ convert(p:%):RF == poly(p) * (monomial(1, 1)$UP)::RF ** order p
+ p:% * q:% == check0(order p + order q, poly p * poly q)
+ - p == gpol(- poly p, order p)
+ check0(n, p) == (zero? p => 0; gpol(p, n))
+ trailingCoefficient p == coefficient(poly p, 0)
+ leadingCoefficient p == leadingCoefficient poly p
+
+ coerce(p:%):O ==
+ zero? p => 0::Z::O
+ l := nil()$List(O)
+ v := monomial(1, 1)$UP :: O
+ while p ^= 0 repeat
+ l := concat(l, toutput(leadingCoefficient p, degree p, v))
+ p := reductum p
+ reduce("+", l)
+
+ coefficient(p, n) ==
+ (m := n - order p) < 0 => 0
+ coefficient(poly p, m::N)
+
+ differentiate(p:%, derivation:UP -> UP) ==
+ t := monomial(1, 1)$UP
+ mkgpol(order(p) - 1,
+ derivation(poly p) * t + order(p) * poly(p) * derivation t)
+
+ monTerm(r, n, v) ==
+ zero? n => r::O
+-- one? n => v
+ (n = 1) => v
+ v ** (n::O)
+
+ toutput(r, n, v) ==
+ mon := monTerm(r, n, v)
+-- zero? n or one? r => mon
+ zero? n or (r = 1) => mon
+ r = -1 => - mon
+ r::O * mon
+
+ recip p ==
+ (q := recip poly p) case "failed" => "failed"
+ gpol(q::UP, - order p)
+
+ p + q ==
+ zero? q => p
+ zero? p => q
+ (d := order p - order q) > 0 =>
+ gpol(poly(p) * monomial(1, d::N) + poly q, order q)
+ d < 0 => gpol(poly(p) + poly(q) * monomial(1, (-d)::N), order p)
+ mkgpol(order p, poly(p) + poly q)
+
+ mkgpol(n, p) ==
+ zero? p => 0
+ d := order(p, monomial(1, 1)$UP)
+ gpol((p exquo monomial(1, d))::UP, n + d::Z)
+
+ p exquo q ==
+ (r := poly(p) exquo poly q) case "failed" => "failed"
+ check0(order p - order q, r::UP)
+
+ retractIfCan(p:%):Union(UP, "failed") ==
+ order(p) < 0 => error "Not retractable"
+ poly(p) * monomial(1, order(p)::N)$UP
+
+ retractIfCan(p:%):Union(R, "failed") ==
+ order(p) ^= 0 => "failed"
+ retractIfCan poly p
+
+ if R has Field then
+ gcd(p, q) == gcd(poly p, poly q)::%
+
+ separate f ==
+ n := order(q := denom f, monomial(1, 1))
+ q := (q exquo (tn := monomial(1, n)$UP))::UP
+ bc := extendedEuclidean(tn,q,numer f)::Record(coef1:UP,coef2:UP)
+ qr := divide(bc.coef1, q)
+ [mkgpol(-n, bc.coef2 + tn * qr.quotient), qr.remainder / q]
+
+-- returns (z, r) s.t. p = q z + r,
+-- and degree(r) < degree(q), order(r) >= min(order(p), order(q))
+ divide(p, q) ==
+ c := min(order p, order q)
+ qr := divide(poly(p) * monomial(1, (order p - c)::N)$UP, poly q)
+ [mkgpol(c - order q, qr.quotient), mkgpol(c, qr.remainder)]
+
+ euclideanSize p == degree poly p
+
+ extendedEuclidean(a, b, c) ==
+ (bc := extendedEuclidean(poly a, poly b, poly c)) case "failed"
+ => "failed"
+ [mkgpol(order c - order a, bc.coef1),
+ mkgpol(order c - order b, bc.coef2)]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain LAUPOL LaurentPolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/grdef.spad.pamphlet b/src/algebra/grdef.spad.pamphlet
new file mode 100644
index 00000000..bfcdf379
--- /dev/null
+++ b/src/algebra/grdef.spad.pamphlet
@@ -0,0 +1,143 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra grdef.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GRDEF GraphicsDefaults}
+<<package GRDEF GraphicsDefaults>>=
+)abbrev package GRDEF GraphicsDefaults
+++ Author: Clifton J. Williamson
+++ Date Created: 8 January 1990
+++ Date Last Updated: 8 January 1990
+++ Basic Operations: clipPointsDefault, drawToScale, adaptive, maxPoints,
+++ minPoints, screenResolution
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TwoDimensionalPlotSettings sets global flags and constants
+++ for 2-dimensional plotting.
+
+GraphicsDefaults(): Exports == Implementation where
+ B ==> Boolean
+ I ==> Integer
+ SF ==> DoubleFloat
+ maxWidth ==> 1000
+ maxHeight ==> 1000
+
+ Exports ==> with
+ clipPointsDefault: () -> B
+ ++ clipPointsDefault() determines whether or not automatic clipping is
+ ++ to be done.
+ drawToScale: () -> B
+ ++ drawToScale() determines whether or not plots are to be drawn to scale.
+
+ clipPointsDefault: B -> B
+ ++ clipPointsDefault(true) turns on automatic clipping;
+ ++ \spad{clipPointsDefault(false)} turns off automatic clipping.
+ ++ The default setting is true.
+ drawToScale: B -> B
+ ++ drawToScale(true) causes plots to be drawn to scale.
+ ++ \spad{drawToScale(false)} causes plots to be drawn so that they
+ ++ fill up the viewport window.
+ ++ The default setting is false.
+
+--% settings from the two-dimensional plot package
+
+ adaptive: () -> B
+ ++ adaptive() determines whether plotting will be done adaptively.
+ maxPoints: () -> I
+ ++ maxPoints() returns the maximum number of points in a plot.
+ minPoints: () -> I
+ ++ minPoints() returns the minimum number of points in a plot.
+ screenResolution: () -> I
+ ++ screenResolution() returns the screen resolution n.
+
+ adaptive: B -> B
+ ++ adaptive(true) turns adaptive plotting on;
+ ++ \spad{adaptive(false)} turns adaptive plotting off.
+ maxPoints: I -> I
+ ++ maxPoints() sets the maximum number of points in a plot.
+ minPoints: I -> I
+ ++ minPoints() sets the minimum number of points in a plot.
+ screenResolution: I -> I
+ ++ screenResolution(n) sets the screen resolution to n.
+
+ Implementation ==> add
+
+--% global flags and constants
+
+ CLIPPOINTSDEFAULT : B := true
+ TOSCALE : B := false
+
+--% functions
+
+ clipPointsDefault() == CLIPPOINTSDEFAULT
+ drawToScale() == TOSCALE
+
+ clipPointsDefault b == CLIPPOINTSDEFAULT := b
+ drawToScale b == TOSCALE := b
+
+--% settings from the two-dimensional plot package
+
+ adaptive() == adaptive?()$Plot
+ minPoints() == minPoints()$Plot
+ maxPoints() == maxPoints()$Plot
+ screenResolution() == screenResolution()$Plot
+
+ adaptive b == setAdaptive(b)$Plot
+ minPoints n == setMinPoints(n)$Plot
+ maxPoints n == setMaxPoints(n)$Plot
+ screenResolution n == setScreenResolution(n)$Plot
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GRDEF GraphicsDefaults>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/groebf.spad.pamphlet b/src/algebra/groebf.spad.pamphlet
new file mode 100644
index 00000000..68cc216c
--- /dev/null
+++ b/src/algebra/groebf.spad.pamphlet
@@ -0,0 +1,385 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra groebf.spad}
+\author{H. Michael Moeller, Johannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GBF GroebnerFactorizationPackage}
+<<package GBF GroebnerFactorizationPackage>>=
+)abbrev package GBF GroebnerFactorizationPackage
+++ Author: H. Michael Moeller, Johannes Grabmeier
+++ Date Created: 24 August 1989
+++ Date Last Updated: 01 January 1992
+++ Basic Operations: groebnerFactorize factorGroebnerBasis
+++ Related Constructors:
+++ Also See: GroebnerPackage, Ideal, IdealDecompositionPackage
+++ AMS Classifications:
+++ Keywords: groebner basis, groebner factorization, ideal decomposition
+++ References:
+++ Description:
+++ \spadtype{GroebnerFactorizationPackage} provides the function
+++ groebnerFactor" which uses the factorization routines of \Language{} to
+++ factor each polynomial under consideration while doing the groebner basis
+++ algorithm. Then it writes the ideal as an intersection of ideals
+++ determined by the irreducible factors. Note that the whole ring may
+++ occur as well as other redundancies. We also use the fact, that from the
+++ second factor on we can assume that the preceding factors are
+++ not equal to 0 and we divide all polynomials under considerations
+++ by the elements of this list of "nonZeroRestrictions".
+++ The result is a list of groebner bases, whose union of solutions
+++ of the corresponding systems of equations is the solution of
+++ the system of equation corresponding to the input list.
+++ The term ordering is determined by the polynomial type used.
+++ Suggested types include
+++ \spadtype{DistributedMultivariatePolynomial},
+++ \spadtype{HomogeneousDistributedMultivariatePolynomial},
+++ \spadtype{GeneralDistributedMultivariatePolynomial}.
+
+GroebnerFactorizationPackage(Dom, Expon, VarSet, Dpol): T == C where
+
+ Dom : Join(EuclideanDomain,CharacteristicZero)
+ Expon : OrderedAbelianMonoidSup
+ VarSet : OrderedSet
+ Dpol: PolynomialCategory(Dom, Expon, VarSet)
+ MF ==> MultivariateFactorize(VarSet,Expon,Dom,Dpol)
+ sugarPol ==> Record(totdeg: NonNegativeInteger, pol : Dpol)
+ critPair ==> Record(lcmfij: Expon,totdeg: NonNegativeInteger, poli: Dpol, polj: Dpol )
+ L ==> List
+ B ==> Boolean
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+
+ T ==> with
+
+ factorGroebnerBasis : L Dpol -> L L Dpol
+ ++ factorGroebnerBasis(basis) checks whether the basis contains
+ ++ reducible polynomials and uses these to split the basis.
+ factorGroebnerBasis : (L Dpol, Boolean) -> L L Dpol
+ ++ factorGroebnerBasis(basis,info) checks whether the basis contains
+ ++ reducible polynomials and uses these to split the basis.
+ ++ If argument {\em info} is true, information is printed about
+ ++ partial results.
+ groebnerFactorize : (L Dpol, L Dpol) -> L L Dpol
+ ++ groebnerFactorize(listOfPolys, nonZeroRestrictions) returns
+ ++ a list of groebner basis. The union of their solutions
+ ++ is the solution of the system of equations given by {\em listOfPolys}
+ ++ under the restriction that the polynomials of {\em nonZeroRestrictions}
+ ++ don't vanish.
+ ++ At each stage the polynomial p under consideration (either from
+ ++ the given basis or obtained from a reduction of the next S-polynomial)
+ ++ is factorized. For each irreducible factors of p, a
+ ++ new {\em createGroebnerBasis} is started
+ ++ doing the usual updates with the factor
+ ++ in place of p.
+ groebnerFactorize : (L Dpol, L Dpol, Boolean) -> L L Dpol
+ ++ groebnerFactorize(listOfPolys, nonZeroRestrictions, info) returns
+ ++ a list of groebner basis. The union of their solutions
+ ++ is the solution of the system of equations given by {\em listOfPolys}
+ ++ under the restriction that the polynomials of {\em nonZeroRestrictions}
+ ++ don't vanish.
+ ++ At each stage the polynomial p under consideration (either from
+ ++ the given basis or obtained from a reduction of the next S-polynomial)
+ ++ is factorized. For each irreducible factors of p a
+ ++ new {\em createGroebnerBasis} is started
+ ++ doing the usual updates with the factor in place of p.
+ ++ If argument {\em info} is true, information is printed about
+ ++ partial results.
+ groebnerFactorize : L Dpol -> L L Dpol
+ ++ groebnerFactorize(listOfPolys) returns
+ ++ a list of groebner bases. The union of their solutions
+ ++ is the solution of the system of equations given by {\em listOfPolys}.
+ ++ At each stage the polynomial p under consideration (either from
+ ++ the given basis or obtained from a reduction of the next S-polynomial)
+ ++ is factorized. For each irreducible factors of p, a
+ ++ new {\em createGroebnerBasis} is started
+ ++ doing the usual updates with the factor
+ ++ in place of p.
+ groebnerFactorize : (L Dpol, Boolean) -> L L Dpol
+ ++ groebnerFactorize(listOfPolys, info) returns
+ ++ a list of groebner bases. The union of their solutions
+ ++ is the solution of the system of equations given by {\em listOfPolys}.
+ ++ At each stage the polynomial p under consideration (either from
+ ++ the given basis or obtained from a reduction of the next S-polynomial)
+ ++ is factorized. For each irreducible factors of p, a
+ ++ new {\em createGroebnerBasis} is started
+ ++ doing the usual updates with the factor
+ ++ in place of p.
+ ++ If {\em info} is true, information is printed about partial results.
+
+ C ==> add
+
+ import GroebnerInternalPackage(Dom,Expon,VarSet,Dpol)
+ -- next to help compiler to choose correct signatures:
+ info: Boolean
+ -- signatures of local functions
+
+ newPairs : (L sugarPol, Dpol) -> L critPair
+ -- newPairs(lp, p) constructs list of critical pairs from the list of
+ -- {\em lp} of input polynomials and a given further one p.
+ -- It uses criteria M and T to reduce the list.
+ updateCritPairs : (L critPair, L critPair, Dpol) -> L critPair
+ -- updateCritPairs(lcP1,lcP2,p) applies criterion B to {\em lcP1} using
+ -- p. Then this list is merged with {\em lcP2}.
+ updateBasis : (L sugarPol, Dpol, NNI) -> L sugarPol
+ -- updateBasis(li,p,deg) every polynomial in {\em li} is dropped if
+ -- its leading term is a multiple of the leading term of p.
+ -- The result is this list enlarged by p.
+ createGroebnerBases : (L sugarPol, L Dpol, L Dpol, L Dpol, L critPair,_
+ L L Dpol, Boolean) -> L L Dpol
+ -- createGroebnerBases(basis, redPols, nonZeroRestrictions, inputPolys,
+ -- lcP,listOfBases): This function is used to be called from
+ -- groebnerFactorize.
+ -- basis: part of a Groebner basis, computed so far
+ -- redPols: Polynomials from the ideal to be used for reducing,
+ -- we don't throw away polynomials
+ -- nonZeroRestrictions: polynomials not zero in the common zeros
+ -- of the polynomials in the final (Groebner) basis
+ -- inputPolys: assumed to be in descending order
+ -- lcP: list of critical pairs built from polynomials of the
+ -- actual basis
+ -- listOfBases: Collects the (Groebner) bases constructed by this
+ -- recursive algorithm at different stages.
+ -- we print info messages if info is true
+ createAllFactors: Dpol -> L Dpol
+ -- factor reduced critpair polynomial
+
+ -- implementation of local functions
+
+
+ createGroebnerBases(basis, redPols, nonZeroRestrictions, inputPolys,_
+ lcP, listOfBases, info) ==
+ doSplitting? : B := false
+ terminateWithBasis : B := false
+ allReducedFactors : L Dpol := []
+ nP : Dpol -- actual polynomial under consideration
+ p : Dpol -- next polynomial from input list
+ h : Dpol -- next polynomial from critical pairs
+ stopDividing : Boolean
+ -- STEP 1 do the next polynomials until a splitting is possible
+ -- In the first step we take the first polynomial of "inputPolys"
+ -- if empty, from list of critical pairs "lcP" and do the following:
+ -- Divide it, if possible, by the polynomials from "nonZeroRestrictions".
+ -- We factorize it and reduce each irreducible factor with respect to
+ -- "basis". If 0$Dpol occurs in the list we update the list and continue
+ -- with next polynomial.
+ -- If there are at least two (irreducible) factors
+ -- in the list of factors we finish STEP 1 and set a boolean variable
+ -- to continue with STEP 2, the splitting step.
+ -- If there is just one of it, we do the following:
+ -- If it is 1$Dpol we stop the whole calculation and put
+ -- [1$Dpol] into the listOfBases
+ -- Otherwise we update the "basis" and the other lists and continue
+ -- with next polynomial.
+
+ while (not doSplitting?) and (not terminateWithBasis) repeat
+ terminateWithBasis := (null inputPolys and null lcP)
+ not terminateWithBasis => -- still polynomials left
+ -- determine next polynomial "nP"
+ nP :=
+ not null inputPolys =>
+ p := first inputPolys
+ inputPolys := rest inputPolys
+ -- we know that p is not equal to 0 or 1, but, although,
+ -- the inputPolys and the basis are ordered, we cannot assume
+ -- that p is reduced w.r.t. basis, as the ordering is only quasi
+ -- and we could have equal leading terms, and due to factorization
+ -- polynomials of smaller leading terms, hence reduce p first:
+ hMonic redPol(p,redPols)
+ -- now we have inputPolys empty and hence lcP is not empty:
+ -- create S-Polynomial from first critical pair:
+ h := sPol first lcP
+ lcP := rest lcP
+ hMonic redPol(h,redPols)
+
+ nP = 1$Dpol =>
+ basis := [[0,1$Dpol]$sugarPol]
+ terminateWithBasis := true
+
+ -- if "nP" ^= 0, then we continue, otherwise we determine next "nP"
+ nP ^= 0$Dpol =>
+ -- now we divide "nP", if possible, by the polynomials
+ -- from "nonZeroRestrictions"
+ for q in nonZeroRestrictions repeat
+ stopDividing := false
+ until stopDividing repeat
+ nPq := nP exquo q
+ stopDividing := (nPq case "failed")
+ if not stopDividing then nP := autoCoerce nPq
+ stopDividing := stopDividing or zero? degree nP
+
+ zero? degree nP =>
+ basis := [[0,1$Dpol]$sugarPol]
+ terminateWithBasis := true -- doSplitting? is still false
+
+ -- a careful analysis has to be done, when and whether the
+ -- following reduction and case nP=1 is necessary
+
+ nP := hMonic redPol(nP,redPols)
+ zero? degree nP =>
+ basis := [[0,1$Dpol]$sugarPol]
+ terminateWithBasis := true -- doSplitting? is still false
+
+ -- if "nP" ^= 0, then we continue, otherwise we determine next "nP"
+ nP ^= 0$Dpol =>
+ -- now we factorize "nP", which is not constant
+ irreducibleFactors : L Dpol := createAllFactors(nP)
+ -- if there are more than 1 factors we reduce them and split
+ (doSplitting? := not null rest irreducibleFactors) =>
+ -- and reduce and normalize the factors
+ for fnP in irreducibleFactors repeat
+ fnP := hMonic redPol(fnP,redPols)
+ -- no factor reduces to 0, as then "fP" would have been
+ -- reduced to zero,
+ -- but 1 may occur, which we will drop in a later version.
+ allReducedFactors := cons(fnP, allReducedFactors)
+ -- end of "for fnP in irreducibleFactors repeat"
+
+ -- we want that the smaller factors are dealt with first
+ allReducedFactors := reverse allReducedFactors
+ -- now the case of exactly 1 factor, but certainly not
+ -- further reducible with respect to "redPols"
+ nP := first irreducibleFactors
+ -- put "nP" into "basis" and update "lcP" and "redPols":
+ lcP : L critPair := updateCritPairs(lcP,newPairs(basis,nP),nP)
+ basis := updateBasis(basis,nP,virtualDegree nP)
+ redPols := concat(redPols,nP)
+ -- end of "while not doSplitting? and not terminateWithBasis repeat"
+
+ -- STEP 2 splitting step
+
+ doSplitting? =>
+ for fnP in allReducedFactors repeat
+ if fnP ^= 1$Dpol
+ then
+ newInputPolys : L Dpol := _
+ sort( degree #1 > degree #2 ,cons(fnP,inputPolys))
+ listOfBases := createGroebnerBases(basis, redPols, _
+ nonZeroRestrictions,newInputPolys,lcP,listOfBases,info)
+ -- update "nonZeroRestrictions"
+ nonZeroRestrictions := cons(fnP,nonZeroRestrictions)
+ else
+ if info then
+ messagePrint("we terminated with [1]")$OUT
+ listOfBases := cons([1$Dpol],listOfBases)
+
+ -- we finished with all the branches on one level and hence
+ -- finished this call of createGroebnerBasis. Therefore
+ -- we terminate with the actual "listOfBasis" as
+ -- everything is done in the recursions
+ listOfBases
+ -- end of "doSplitting? =>"
+
+ -- STEP 3 termination step
+
+ -- we found a groebner basis and put it into the list "listOfBases"
+ -- (auto)reduce each basis element modulo the others
+ newBasis := minGbasis(sort(degree #1 > degree #2,[p.pol for p in basis]))
+ -- now check whether the normalized basis again has reducible
+ -- polynomials, in this case continue splitting!
+ if info then
+ messagePrint("we found a groebner basis and check whether it ")$OUT
+ messagePrint("contains reducible polynomials")$OUT
+ print(newBasis::OUT)$OUT
+ -- here we should create an output form which is reusable by the system
+ -- print(convert(newBasis::OUT)$InputForm :: OUT)$OUT
+ removeDuplicates append(factorGroebnerBasis(newBasis, info), listOfBases)
+
+ createAllFactors(p: Dpol) ==
+ loF : L Dpol := [el.fctr for el in factorList factor(p)$MF]
+ sort(degree #1 < degree #2, loF)
+ newPairs(lp : L sugarPol,p : Dpol) ==
+ totdegreeOfp : NNI := virtualDegree p
+ -- next list lcP contains all critPair constructed from
+ -- p and and the polynomials q in lp
+ lcP: L critPair := _
+ --[[sup(degree q, degreeOfp), q, p]$critPair for q in lp]
+ [makeCrit(q, p, totdegreeOfp) for q in lp]
+ -- application of the criteria to reduce the list lcP
+ critMTonD1 sort(critpOrder,lcP)
+ updateCritPairs(oldListOfcritPairs, newListOfcritPairs, p)==
+ updatD (newListOfcritPairs, critBonD(p,oldListOfcritPairs))
+ updateBasis(lp, p, deg) == updatF(p,deg,lp)
+
+ -- exported functions
+
+ factorGroebnerBasis basis == factorGroebnerBasis(basis, false)
+
+ factorGroebnerBasis (basis, info) ==
+ foundAReducible : Boolean := false
+ for p in basis while not foundAReducible repeat
+ -- we use fact that polynomials have content 1
+ foundAReducible := 1 < #[el.fctr for el in factorList factor(p)$MF]
+ not foundAReducible =>
+ if info then messagePrint("factorGroebnerBasis: no reducible polynomials in this basis")$OUT
+ [basis]
+ -- improve! Use the fact that the irreducible ones already
+ -- build part of the basis, use the done factorizations, etc.
+ if info then messagePrint("factorGroebnerBasis:_
+ we found reducible polynomials and continue splitting")$OUT
+ createGroebnerBases([],[],[],basis,[],[],info)
+
+ groebnerFactorize(basis, nonZeroRestrictions) ==
+ groebnerFactorize(basis, nonZeroRestrictions, false)
+
+ groebnerFactorize(basis, nonZeroRestrictions, info) ==
+ basis = [] => [basis]
+ basis := remove(#1 = 0$Dpol,basis)
+ basis = [] => [[0$Dpol]]
+ -- normalize all input polynomial
+ basis := [hMonic p for p in basis]
+ member?(1$Dpol,basis) => [[1$Dpol]]
+ basis := sort(degree #1 > degree #2, basis)
+ createGroebnerBases([],[],nonZeroRestrictions,basis,[],[],info)
+
+ groebnerFactorize(basis) == groebnerFactorize(basis, [], false)
+ groebnerFactorize(basis,info) == groebnerFactorize(basis, [], info)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GBF GroebnerFactorizationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/groebsol.spad.pamphlet b/src/algebra/groebsol.spad.pamphlet
new file mode 100644
index 00000000..b2e4ab76
--- /dev/null
+++ b/src/algebra/groebsol.spad.pamphlet
@@ -0,0 +1,245 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra groebsol.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GROEBSOL GroebnerSolve}
+<<package GROEBSOL GroebnerSolve>>=
+)abbrev package GROEBSOL GroebnerSolve
+++ Author : P.Gianni, Summer '88, revised November '89
+++ Solve systems of polynomial equations using Groebner bases
+++ Total order Groebner bases are computed and then converted to lex ones
+++ This package is mostly intended for internal use.
+GroebnerSolve(lv,F,R) : C == T
+
+ where
+ R : GcdDomain
+ F : GcdDomain
+ lv : List Symbol
+
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ S ==> Symbol
+
+ OV ==> OrderedVariableList(lv)
+ IES ==> IndexedExponents Symbol
+
+ DP ==> DirectProduct(#lv,NonNegativeInteger)
+ DPoly ==> DistributedMultivariatePolynomial(lv,F)
+
+ HDP ==> HomogeneousDirectProduct(#lv,NonNegativeInteger)
+ HDPoly ==> HomogeneousDistributedMultivariatePolynomial(lv,F)
+
+ SUP ==> SparseUnivariatePolynomial(DPoly)
+ L ==> List
+ P ==> Polynomial
+
+ C == with
+ groebSolve : (L DPoly,L OV) -> L L DPoly
+ ++ groebSolve(lp,lv) reduces the polynomial system lp in variables lv
+ ++ to triangular form. Algorithm based on groebner bases algorithm
+ ++ with linear algebra for change of ordering.
+ ++ Preprocessing for the general solver.
+ ++ The polynomials in input are of type \spadtype{DMP}.
+
+ testDim : (L HDPoly,L OV) -> Union(L HDPoly,"failed")
+ ++ testDim(lp,lv) tests if the polynomial system lp
+ ++ in variables lv is zero dimensional.
+
+ genericPosition : (L DPoly, L OV) -> Record(dpolys:L DPoly, coords: L I)
+ ++ genericPosition(lp,lv) puts a radical zero dimensional ideal
+ ++ in general position, for system lp in variables lv.
+
+ T == add
+ import PolToPol(lv,F)
+ import GroebnerPackage(F,DP,OV,DPoly)
+ import GroebnerInternalPackage(F,DP,OV,DPoly)
+ import GroebnerPackage(F,HDP,OV,HDPoly)
+ import LinGroebnerPackage(lv,F)
+
+ nv:NNI:=#lv
+
+ ---- test if f is power of a linear mod (rad lpol) ----
+ ---- f is monic ----
+ testPower(uf:SUP,x:OV,lpol:L DPoly) : Union(DPoly,"failed") ==
+ df:=degree(uf)
+ trailp:DPoly := coefficient(uf,(df-1)::NNI)
+ (testquo := trailp exquo (df::F)) case "failed" => "failed"
+ trailp := testquo::DPoly
+ gg:=gcd(lc:=leadingCoefficient(uf),trailp)
+ trailp := (trailp exquo gg)::DPoly
+ lc := (lc exquo gg)::DPoly
+ linp:SUP:=monomial(lc,1$NNI)$SUP + monomial(trailp,0$NNI)$SUP
+ g:DPoly:=multivariate(uf-linp**df,x)
+ redPol(g,lpol) ^= 0 => "failed"
+ multivariate(linp,x)
+
+ -- is the 0-dimensional ideal I in general position ? --
+ ---- internal function ----
+ testGenPos(lpol:L DPoly,lvar:L OV):Union(L DPoly,"failed") ==
+ rlpol:=reverse lpol
+ f:=rlpol.first
+ #lvar=1 => [f]
+ rlvar:=rest reverse lvar
+ newlpol:List(DPoly):=[f]
+ for f in rlpol.rest repeat
+ x:=first rlvar
+ fi:= univariate(f,x)
+ if (mainVariable leadingCoefficient fi case "failed") then
+ if ((g:= testPower(fi,x,newlpol)) case "failed")
+ then return "failed"
+ newlpol :=concat(redPol(g::DPoly,newlpol),newlpol)
+ rlvar:=rest rlvar
+ else if redPol(f,newlpol)^=0 then return"failed"
+ newlpol
+
+
+ -- change coordinates and out the ideal in general position ----
+ genPos(lp:L DPoly,lvar:L OV): Record(polys:L HDPoly, lpolys:L DPoly,
+ coord:L I, univp:HDPoly) ==
+ rlvar:=reverse lvar
+ lnp:=[dmpToHdmp(f) for f in lp]
+ x := first rlvar;rlvar:=rest rlvar
+ testfail:=true
+ for count in 1.. while testfail repeat
+ ranvals:L I:=[1+(random()$I rem (count*(# lvar))) for vv in rlvar]
+ val:=+/[rv*(vv::HDPoly)
+ for vv in rlvar for rv in ranvals]
+ val:=val+x::HDPoly
+ gb:L HDPoly:= [elt(univariate(p,x),val) for p in lnp]
+ gb:=groebner gb
+ gbt:=totolex gb
+ (gb1:=testGenPos(gbt,lvar)) case "failed"=>"try again"
+ testfail:=false
+ [gb,gbt,ranvals,dmpToHdmp(last (gb1::L DPoly))]
+
+ genericPosition(lp:L DPoly,lvar:L OV) ==
+ nans:=genPos(lp,lvar)
+ [nans.lpolys, nans.coord]
+
+ ---- select the univariate factors
+ select(lup:L L HDPoly) : L L HDPoly ==
+ lup=[] => list []
+ [:[cons(f,lsel) for lsel in select lup.rest] for f in lup.first]
+
+ ---- in the non generic case, we compute the prime ideals ----
+ ---- associated to leq, basis is the algebra basis ----
+ findCompon(leq:L HDPoly,lvar:L OV):L L DPoly ==
+ teq:=totolex(leq)
+ #teq = #lvar => [teq]
+ -- ^((teq1:=testGenPos(teq,lvar)) case "failed") => [teq1::L DPoly]
+ gp:=genPos(teq,lvar)
+ lgp:= gp.polys
+ g:HDPoly:=gp.univp
+ fg:=(factor g)$GeneralizedMultivariateFactorize(OV,HDP,R,F,HDPoly)
+ lfact:=[ff.factor for ff in factors(fg::Factored(HDPoly))]
+ result: L L HDPoly := []
+ #lfact=1 => [teq]
+ for tfact in lfact repeat
+ tlfact:=concat(tfact,lgp)
+ result:=concat(tlfact,result)
+ ranvals:L I:=gp.coord
+ rlvar:=reverse lvar
+ x:=first rlvar
+ rlvar:=rest rlvar
+ val:=+/[rv*(vv::HDPoly) for vv in rlvar for rv in ranvals]
+ val:=(x::HDPoly)-val
+ ans:=[totolex groebner [elt(univariate(p,x),val) for p in lp]
+ for lp in result]
+ [ll for ll in ans | ll^=[1]]
+
+ zeroDim?(lp: List HDPoly,lvar:L OV) : Boolean ==
+ empty? lp => false
+ n:NNI := #lvar
+ #lp < n => false
+ lvint1 := lvar
+ for f in lp while not empty?(lvint1) repeat
+ g:= f - reductum f
+ x:=mainVariable(g)::OV
+ if ground?(leadingCoefficient(univariate(g,x))) then
+ lvint1 := remove(x, lvint1)
+ empty? lvint1
+
+ -- general solve, gives an error if the system not 0-dimensional
+ groebSolve(leq: L DPoly,lvar:L OV) : L L DPoly ==
+ lnp:=[dmpToHdmp(f) for f in leq]
+ leq1:=groebner lnp
+ #(leq1) = 1 and first(leq1) = 1 => list empty()
+ ^(zeroDim?(leq1,lvar)) =>
+ error "system does not have a finite number of solutions"
+ -- add computation of dimension, for a more useful error
+ basis:=computeBasis(leq1)
+ lup:L HDPoly:=[]
+ llfact:L Factored(HDPoly):=[]
+ for x in lvar repeat
+ g:=minPol(leq1,basis,x)
+ fg:=(factor g)$GeneralizedMultivariateFactorize(OV,HDP,R,F,HDPoly)
+ llfact:=concat(fg::Factored(HDPoly),llfact)
+ if degree(g,x) = #basis then leave "stop factoring"
+ result: L L DPoly := []
+ -- selecting a factor from the lists of the univariate factors
+ lfact:=select [[ff.factor for ff in factors llf]
+ for llf in llfact]
+ for tfact in lfact repeat
+ tfact:=groebner concat(tfact,leq1)
+ tfact=[1] => "next value"
+ result:=concat(result,findCompon(tfact,lvar))
+ result
+
+ -- test if the system is zero dimensional
+ testDim(leq : L HDPoly,lvar : L OV) : Union(L HDPoly,"failed") ==
+ leq1:=groebner leq
+ #(leq1) = 1 and first(leq1) = 1 => empty()
+ ^(zeroDim?(leq1,lvar)) => "failed"
+ leq1
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GROEBSOL GroebnerSolve>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/gseries.spad.pamphlet b/src/algebra/gseries.spad.pamphlet
new file mode 100644
index 00000000..cc152a3a
--- /dev/null
+++ b/src/algebra/gseries.spad.pamphlet
@@ -0,0 +1,165 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra gseries.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain GSERIES GeneralUnivariatePowerSeries}
+<<domain GSERIES GeneralUnivariatePowerSeries>>=
+)abbrev domain GSERIES GeneralUnivariatePowerSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 22 September 1993
+++ Date Last Updated: 23 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Puiseux
+++ Examples:
+++ References:
+++ Description:
+++ This is a category of univariate Puiseux series constructed
+++ from univariate Laurent series. A Puiseux series is represented
+++ by a pair \spad{[r,f(x)]}, where r is a positive rational number and
+++ \spad{f(x)} is a Laurent series. This pair represents the Puiseux
+++ series \spad{f(x\^r)}.
+GeneralUnivariatePowerSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ I ==> Integer
+ UTS ==> UnivariateTaylorSeries
+ ULS ==> UnivariateLaurentSeries
+ UPXS ==> UnivariatePuiseuxSeries
+ EFULS ==> ElementaryFunctionsUnivariateLaurentSeries
+ EFUPXS ==> ElementaryFunctionsUnivariatePuiseuxSeries
+ FS2UPS ==> FunctionSpaceToUnivariatePowerSeries
+
+ Exports ==> UnivariatePuiseuxSeriesCategory Coef with
+ coerce: Variable(var) -> %
+ ++ coerce(var) converts the series variable \spad{var} into a
+ ++ Puiseux series.
+ coerce: UPXS(Coef,var,cen) -> %
+ ++ coerce(f) converts a Puiseux series to a general power series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} returns the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> UnivariatePuiseuxSeries(Coef,var,cen) add
+
+ coerce(upxs:UPXS(Coef,var,cen)) == upxs pretend %
+
+ puiseux: % -> UPXS(Coef,var,cen)
+ puiseux f == f pretend UPXS(Coef,var,cen)
+
+ if Coef has Algebra Fraction Integer then
+
+ differentiate f ==
+ str1 : String := "'differentiate' unavailable on this domain; "
+ str2 : String := "use 'approximate' first"
+ error concat(str1,str2)
+
+ differentiate(f:%,v:Variable(var)) == differentiate f
+
+ if Coef has PartialDifferentialRing(Symbol) then
+ differentiate(f:%,s:Symbol) ==
+ (s = variable(f)) =>
+ str1 : String := "'differentiate' unavailable on this domain; "
+ str2 : String := "use 'approximate' first"
+ error concat(str1,str2)
+ dcds := differentiate(center f,s)
+ deriv := differentiate(puiseux f) :: %
+ map(differentiate(#1,s),f) - dcds * deriv
+
+ integrate f ==
+ str1 : String := "'integrate' unavailable on this domain; "
+ str2 : String := "use 'approximate' first"
+ error concat(str1,str2)
+
+ integrate(f:%,v:Variable(var)) == integrate f
+
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+
+ integrate(f:%,s:Symbol) ==
+ (s = variable(f)) =>
+ str1 : String := "'integrate' unavailable on this domain; "
+ str2 : String := "use 'approximate' first"
+ error concat(str1,str2)
+ not entry?(s,variables center f) => map(integrate(#1,s),f)
+ error "integrate: center is a function of variable of integration"
+
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+
+ integrateWithOneAnswer: (Coef,Symbol) -> Coef
+ integrateWithOneAnswer(f,s) ==
+ res := integrate(f,s)$FunctionSpaceIntegration(Integer,Coef)
+ res case Coef => res :: Coef
+ first(res :: List Coef)
+
+ integrate(f:%,s:Symbol) ==
+ (s = variable(f)) =>
+ str1 : String := "'integrate' unavailable on this domain; "
+ str2 : String := "use 'approximate' first"
+ error concat(str1,str2)
+ not entry?(s,variables center f) =>
+ map(integrateWithOneAnswer(#1,s),f)
+ error "integrate: center is a function of variable of integration"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain GSERIES GeneralUnivariatePowerSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/herm.as.pamphlet b/src/algebra/herm.as.pamphlet
new file mode 100644
index 00000000..81915bae
--- /dev/null
+++ b/src/algebra/herm.as.pamphlet
@@ -0,0 +1,369 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra herm.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+-- N.B. ndftip.as inlines this, must be recompiled if this is.
+
+-- To test:
+-- sed -ne '1,/^#if NeverAssertThis/d;/#endif/d;p' < herm.as > herm.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r herm.input
+\end{verbatim}
+\section{PackedHermitianSequence}
+<<PackedHermitianSequence>>=
+#include "axiom.as"
+
+INT ==> Integer ;
+NNI ==> NonNegativeInteger ;
+PHS ==> PackedHermitianSequence ;
+
++++ Author: M.G. Richardson
++++ Date Created: 1995 Nov. 24
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors: Vector
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This type represents packed Hermitian sequences - that is, complex
++++ sequences s, whose tails ("rest s", in Axiom terms) are conjugate to
++++ themselves reversed - by real sequences, in the "standard" manner;
++++ in this, the real parts of the elements of the first "half" of the
++++ tail are stored there and the imaginary parts are stored in reverse
++++ order in the second "half" of the tail.
++++ (If the tail has an odd number of elements, its middle element is
++++ real and is stored unchanged. The "halves" mentioned above then
++++ refer to the elements before and after the middle, respectively.)
+
+PackedHermitianSequence(R : CommutativeRing) : LinearAggregate(R) with{
+
+ pHS : List R -> % ;
+++ pHS(l) converts the list l to a packedHermitianSequence.
+
+ expand : % -> Vector Complex R ;
+++ expand(h) converts the packedHermitianSequence h to a Hermitian
+++ sequence (a complex vector).
+
+ packHS : Vector Complex R -> % ;
+++ packHS(v) checks that the complex vector v represents a Hermitian
+++ sequences and, if so, converts it to a packedHermitianSequence;
+++ otherwise an error message is printed.
+
+ conjHerm : % -> % ;
+++ conjHerm(h) returns the packedHermitianSequence which represents the
+++ Hermitian sequence conjugate to that represented by h.
+
+ coerce : % -> OutputForm -- shouldn't need this, should be inherited
+ -- from Vector.
+
+} == Vector(R) add {
+ Rep ==> Vector R;
+ import from Rep;
+ import from INT ;
+ import from R ;
+ import from Vector R ;
+ import from Complex R ;
+ import from Vector Complex R ;
+ import from ErrorFunctions ;
+ import from String ;
+ import from List String ;
+
+ local (..)(a:INT,b:INT):Generator INT == {
+ generate {
+ t := a ;
+ while (t <= b) repeat {
+ yield t ;
+ t := t + 1 ;
+ }
+ }
+ }
+
+ pHS(l : List R) : % == (vector l) pretend PHS R ;
+
+ expand(h : %) : Vector Complex R == {
+
+ local len : NNI ;
+ local nvals, npairs, n1, n2 : INT ;
+ local fullh : Vector Complex R ;
+
+ {
+ len := # h ;
+ nvals := len pretend INT ; -- pretend since :: fails
+ npairs := (nvals - 1) quo 2 ;
+ fullh := new(len, 0) ;
+ (nvals = 0) => () ;
+ fullh.1 := complex(h.1,0) ;
+ (nvals = 1) => () ;
+ fullh.(npairs+2) := complex(h.(npairs+2),0) ; -- need if even length
+ -- (not worth testing)
+ for j in 1 .. npairs repeat {
+ n1 := j + 1 ;
+ n2 := nvals - j + 1 ;
+ fullh.n1 := complex(h.n1, h.n2) ;
+ fullh.n2 := complex(h.n1, -(h.n2)) ;
+ }
+
+ }
+
+ fullh
+
+ }
+
+ packHS(v : Vector Complex R) : % == {
+
+ local len : NNI ;
+ local nonhs : String == "The argument of packHS is not Hermitian" ;
+ local nvals, testprs, n1, n2 : INT ;
+ local hpacked : Vector R ;
+ local v1, v2 : Complex R ;
+ local r1, i1, r2, i2 : R ;
+
+ {
+ len := # v ;
+ nvals := len pretend INT ; -- pretend since :: fails
+ testprs := nvals quo 2 ;
+ hpacked := new(len, 0) ;
+ (nvals = 0) => () ;
+ if imag(v.1) ~= 0
+ then error [nonhs, " - the first element must be real."]
+ else {
+ hpacked.1 := real(v.1) ;
+ (nvals = 1) => () ;
+ for j in 1 .. testprs repeat {
+ n1 := j + 1 ;
+ n2 := nvals - j + 1 ;
+ v1 := v.n1 ;
+ v2 := v.n2 ;
+ r1 := real v1 ;
+ i1 := imag v1 ;
+ r2 := real v2 ;
+ i2 := imag v2 ;
+ if r1 ~= r2 or i1 ~= -i2
+ then if n1 = n2
+ then error [nonhs,
+ " - element ",
+ string(n1),
+ " must be real to be self-conjugate."]
+ else error [nonhs,
+ " - elements ",
+ string(n1),
+ " and ",
+ string(n2),
+ " are not conjugate."]
+ else {
+ hpacked.n2 := i1 ; -- This order means that when the tail of v
+ hpacked.n1 := r1 ; -- has odd length, the (real part) of its
+ -- middle element ends up in that position.
+ }
+ }
+ }
+ }
+
+ hpacked pretend %
+
+ }
+
+ local set!(x: %, i: INT, v: R): () == {
+ (rep x).i := v;
+ }
+ conjHerm(h : %) : % == {
+
+ local len : NNI ;
+ local nvals, npairs : INT ;
+ local ch : % ;
+
+ ch := copy h ;
+ len := # h ;
+ (len < 3) => ch ; -- these Hermitian sequences are self-conjugate.
+ nvals := len pretend INT ; -- pretend since :: fails
+ npairs := (nvals - 1) quo 2 ;
+ for j in (nvals - npairs + 1) .. nvals repeat ch.j := - h.j ;
+ ch
+
+ }
+
+ import from List OutputForm ;
+
+ coerce(h : %) : OutputForm ==
+ bracket commaSeparate [
+ qelt(h, k) :: OutputForm for k in minIndex h .. maxIndex h]
+
+}
+
+#if NeverAssertThis
+
+)lib herm
+
+h0 := pHS([] :: List INT)
+
+-- []
+
+h1 := pHS [1]
+
+-- [1]
+
+h2 := pHS [1,2]
+
+-- [1,2]
+
+h3 := pHS [1,2,3]
+
+-- [1,2,3]
+
+h4 := pHS [1,2,3,4]
+
+-- [1,2,3,4]
+
+h5 := pHS [1,2,3,4,5]
+
+-- [1,2,3,4,5]
+
+
+f0 := expand h0
+
+-- []
+
+f1 := expand h1
+
+-- [1]
+
+f2 := expand h2
+
+-- [1,2]
+
+f3 := expand h3
+
+-- [1,2 + 3%i,2 - 3%i]
+
+f4 := expand h4
+
+-- [1,2 + 4%i,3,2 - 4%i]
+
+f5 := expand h5
+
+-- [1,2 + 5%i,3 + 4%i,3 - 4%i,2 - 5%i]
+
+packHS f0
+
+-- []
+
+packHS f1
+
+-- [1]
+
+packHS f2
+
+-- [1,2]
+
+packHS f3
+
+-- [1,2,3]
+
+packHS f4
+
+-- [1,2,3,4]
+
+packHS f5
+
+-- [1,2,3,4,5]
+
+packHS vector[%i,3,3,3]
+
+-- Error signalled from user code:
+-- The argument of packHS is not Hermitian - the first element must
+-- be real.
+
+packHS vector [1, 3, 5, 7]
+
+-- Error signalled from user code:
+-- The argument of packHS is not Hermitian - elements 2 and 4 are
+-- not conjugate.
+
+packHS [1, 3, %i, 3]
+
+-- Error signalled from user code:
+-- The argument of packHS is not Hermitian - element 3 must be real
+-- to be self-conjugate.
+
+conjHerm h0
+
+-- []
+
+conjHerm h1
+
+-- [1]
+
+conjHerm h2
+
+-- [1,2]
+
+conjHerm h3
+
+-- [1,2,- 3]
+
+conjHerm h4
+
+-- [1,2,3,- 4]
+
+conjHerm h5
+
+-- [1,2,3,- 4,- 5]
+
+output "End of tests"
+
+#endif
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<PackedHermitianSequence>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ideal.spad.pamphlet b/src/algebra/ideal.spad.pamphlet
new file mode 100644
index 00000000..f1ba1d61
--- /dev/null
+++ b/src/algebra/ideal.spad.pamphlet
@@ -0,0 +1,474 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ideal.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain IDEAL PolynomialIdeals}
+<<domain IDEAL PolynomialIdeals>>=
+)abbrev domain IDEAL PolynomialIdeals
+++ Author: P. Gianni
+++ Date Created: summer 1986
+++ Date Last Updated: September 1996
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References: GTZ
+++ Description: This domain represents polynomial ideals with coefficients in any
+++ field and supports the basic ideal operations, including intersection
+++ sum and quotient.
+++ An ideal is represented by a list of polynomials (the generators of
+++ the ideal) and a boolean that is true if the generators are a Groebner
+++ basis.
+++ The algorithms used are based on Groebner basis computations. The
+++ ordering is determined by the datatype of the input polynomials.
+++ Users may use refinements of total degree orderings.
+
+PolynomialIdeals(F,Expon,VarSet,DPoly) : C == T
+ where
+ F : Field
+ Expon : OrderedAbelianMonoidSup
+ VarSet : OrderedSet
+ DPoly : PolynomialCategory(F,Expon,VarSet)
+
+ SUP ==> SparseUnivariatePolynomial(DPoly)
+ NNI ==> NonNegativeInteger
+ Z ==> Integer
+ P ==> Polynomial F
+ MF ==> Matrix(F)
+ ST ==> SuchThat(List P, List Equation P)
+
+ GenMPos ==> Record(mval:MF,invmval:MF,genIdeal:Ideal)
+ Ideal ==> %
+
+ C == SetCategory with
+
+ "*" : (Ideal,Ideal) -> Ideal
+ ++ I*J computes the product of the ideal I and J.
+ "**" : (Ideal,NNI) -> Ideal
+ ++ I**n computes the nth power of the ideal I.
+ "+" : (Ideal,Ideal) -> Ideal
+ ++ I+J computes the ideal generated by the union of I and J.
+ one? : Ideal -> Boolean
+ ++ one?(I) tests whether the ideal I is the unit ideal,
+ ++ i.e. contains 1.
+ zero? : Ideal -> Boolean
+ ++ zero?(I) tests whether the ideal I is the zero ideal
+ element? : (DPoly,Ideal) -> Boolean
+ ++ element?(f,I) tests whether the polynomial f belongs to
+ ++ the ideal I.
+ in? : (Ideal,Ideal) -> Boolean
+ ++ in?(I,J) tests if the ideal I is contained in the ideal J.
+ inRadical? : (DPoly,Ideal) -> Boolean
+ ++ inRadical?(f,I) tests if some power of the polynomial f
+ ++ belongs to the ideal I.
+ zeroDim? : (Ideal,List VarSet) -> Boolean
+ ++ zeroDim?(I,lvar) tests if the ideal I is zero dimensional, i.e.
+ ++ all its associated primes are maximal,
+ ++ in the ring \spad{F[lvar]}
+ zeroDim? : Ideal -> Boolean
+ ++ zeroDim?(I) tests if the ideal I is zero dimensional, i.e.
+ ++ all its associated primes are maximal,
+ ++ in the ring \spad{F[lvar]}, where lvar are the variables appearing in I
+ intersect : (Ideal,Ideal) -> Ideal
+ ++ intersect(I,J) computes the intersection of the ideals I and J.
+ intersect : List(Ideal) -> Ideal
+ ++ intersect(LI) computes the intersection of the list of ideals LI.
+ quotient : (Ideal,Ideal) -> Ideal
+ ++ quotient(I,J) computes the quotient of the ideals I and J, \spad{(I:J)}.
+ quotient : (Ideal,DPoly) -> Ideal
+ ++ quotient(I,f) computes the quotient of the ideal I by the principal
+ ++ ideal generated by the polynomial f, \spad{(I:(f))}.
+ groebner : Ideal -> Ideal
+ ++ groebner(I) returns a set of generators of I that are a Groebner basis
+ ++ for I.
+ generalPosition : (Ideal,List VarSet) -> GenMPos
+ ++ generalPosition(I,listvar) perform a random linear
+ ++ transformation on the variables in listvar and returns
+ ++ the transformed ideal along with the change of basis matrix.
+ backOldPos : GenMPos -> Ideal
+ ++ backOldPos(genPos) takes the result
+ ++ produced by \spadfunFrom{generalPosition}{PolynomialIdeals}
+ ++ and performs the inverse transformation, returning the original ideal
+ ++ \spad{backOldPos(generalPosition(I,listvar))} = I.
+ dimension : (Ideal,List VarSet) -> Z
+ ++ dimension(I,lvar) gives the dimension of the ideal I,
+ ++ in the ring \spad{F[lvar]}
+ dimension : Ideal -> Z
+ ++ dimension(I) gives the dimension of the ideal I.
+ ++ in the ring \spad{F[lvar]}, where lvar are the variables appearing in I
+ leadingIdeal : Ideal -> Ideal
+ ++ leadingIdeal(I) is the ideal generated by the
+ ++ leading terms of the elements of the ideal I.
+ ideal : List DPoly -> Ideal
+ ++ ideal(polyList) constructs the ideal generated by the list
+ ++ of polynomials polyList.
+ groebnerIdeal : List DPoly -> Ideal
+ ++ groebnerIdeal(polyList) constructs the ideal generated by the list
+ ++ of polynomials polyList which are assumed to be a Groebner
+ ++ basis.
+ ++ Note: this operation avoids a Groebner basis computation.
+ groebner? : Ideal -> Boolean
+ ++ groebner?(I) tests if the generators of the ideal I are a Groebner basis.
+ generators : Ideal -> List DPoly
+ ++ generators(I) returns a list of generators for the ideal I.
+ coerce : List DPoly -> Ideal
+ ++ coerce(polyList) converts the list of polynomials polyList to an ideal.
+
+ saturate : (Ideal,DPoly) -> Ideal
+ ++ saturate(I,f) is the saturation of the ideal I
+ ++ with respect to the multiplicative
+ ++ set generated by the polynomial f.
+ saturate :(Ideal,DPoly,List VarSet) -> Ideal
+ ++ saturate(I,f,lvar) is the saturation with respect to the prime
+ ++ principal ideal which is generated by f in the polynomial ring
+ ++ \spad{F[lvar]}.
+ if VarSet has ConvertibleTo Symbol then
+ relationsIdeal : List DPoly -> ST
+ ++ relationsIdeal(polyList) returns the ideal of relations among the
+ ++ polynomials in polyList.
+
+ T == add
+
+ --- Representation ---
+ Rep := Record(idl:List DPoly,isGr:Boolean)
+
+
+ ---- Local Functions ----
+
+ contractGrob : newIdeal -> Ideal
+ npoly : DPoly -> newPoly
+ oldpoly : newPoly -> Union(DPoly,"failed")
+ leadterm : (DPoly,VarSet) -> DPoly
+ choosel : (DPoly,DPoly) -> DPoly
+ isMonic? : (DPoly,VarSet) -> Boolean
+ randomat : List Z -> Record(mM:MF,imM:MF)
+ monomDim : (Ideal,List VarSet) -> NNI
+ variables : Ideal -> List VarSet
+ subset : List VarSet -> List List VarSet
+ makeleast : (List VarSet,List VarSet) -> List VarSet
+
+ newExpon: OrderedAbelianMonoidSup
+ newExpon:= Product(NNI,Expon)
+ newPoly := PolynomialRing(F,newExpon)
+
+ import GaloisGroupFactorizer(SparseUnivariatePolynomial Z)
+ import GroebnerPackage(F,Expon,VarSet,DPoly)
+ import GroebnerPackage(F,newExpon,VarSet,newPoly)
+
+ newIdeal ==> List(newPoly)
+
+ npoly(f:DPoly) : newPoly ==
+ f=0$DPoly => 0$newPoly
+ monomial(leadingCoefficient f,makeprod(0,degree f))$newPoly +
+ npoly(reductum f)
+
+ oldpoly(q:newPoly) : Union(DPoly,"failed") ==
+ q=0$newPoly => 0$DPoly
+ dq:newExpon:=degree q
+ n:NNI:=selectfirst (dq)
+ n^=0 => "failed"
+ ((g:=oldpoly reductum q) case "failed") => "failed"
+ monomial(leadingCoefficient q,selectsecond dq)$DPoly + (g::DPoly)
+
+ leadterm(f:DPoly,lvar:List VarSet) : DPoly ==
+ empty?(lf:=variables f) or lf=lvar => f
+ leadterm(leadingCoefficient univariate(f,lf.first),lvar)
+
+ choosel(f:DPoly,g:DPoly) : DPoly ==
+ g=0 => f
+ (f1:=f exquo g) case "failed" => f
+ choosel(f1::DPoly,g)
+
+ contractGrob(I1:newIdeal) : Ideal ==
+ J1:List(newPoly):=groebner(I1)
+ while (oldpoly J1.first) case "failed" repeat J1:=J1.rest
+ [[(oldpoly f)::DPoly for f in J1],true]
+
+ makeleast(fullVars: List VarSet,leastVars:List VarSet) : List VarSet ==
+ n:= # leastVars
+ #fullVars < n => error "wrong vars"
+ n=0 => fullVars
+ append([vv for vv in fullVars| ^member?(vv,leastVars)],leastVars)
+
+ isMonic?(f:DPoly,x:VarSet) : Boolean ==
+ ground? leadingCoefficient univariate(f,x)
+
+ subset(lv : List VarSet) : List List VarSet ==
+ #lv =1 => [lv,empty()]
+ v:=lv.1
+ ll:=subset(rest lv)
+ l1:=[concat(v,set) for set in ll]
+ concat(l1,ll)
+
+ monomDim(listm:Ideal,lv:List VarSet) : NNI ==
+ monvar: List List VarSet := []
+ for f in generators listm repeat
+ mvset := variables f
+ #mvset > 1 => monvar:=concat(mvset,monvar)
+ lv:=delete(lv,position(mvset.1,lv))
+ empty? lv => 0
+ lsubset : List List VarSet := sort(#(#1)>#(#2),subset(lv))
+ for subs in lsubset repeat
+ ldif:List VarSet:= lv
+ for mvset in monvar while ldif ^=[] repeat
+ ldif:=setDifference(mvset,subs)
+ if ^(empty? ldif) then return #subs
+ 0
+
+ -- Exported Functions ----
+
+ ---- is I = J ? ----
+ (I:Ideal = J:Ideal) == in?(I,J) and in?(J,I)
+
+ ---- check if f is in I ----
+ element?(f:DPoly,I:Ideal) : Boolean ==
+ Id:=(groebner I).idl
+ empty? Id => f = 0
+ normalForm(f,Id) = 0
+
+ ---- check if I is contained in J ----
+ in?(I:Ideal,J:Ideal):Boolean ==
+ J:= groebner J
+ empty?(I.idl) => true
+ "and"/[element?(f,J) for f in I.idl ]
+
+
+ ---- groebner base for an Ideal ----
+ groebner(I:Ideal) : Ideal ==
+ I.isGr =>
+ "or"/[^zero? f for f in I.idl] => I
+ [empty(),true]
+ [groebner I.idl ,true]
+
+ ---- Intersection of two ideals ----
+ intersect(I:Ideal,J:Ideal) : Ideal ==
+ empty?(Id:=I.idl) => I
+ empty?(Jd:=J.idl) => J
+ tp:newPoly := monomial(1,makeprod(1,0$Expon))$newPoly
+ tp1:newPoly:= tp-1
+ contractGrob(concat([tp*npoly f for f in Id],
+ [tp1*npoly f for f in Jd]))
+
+
+ ---- intersection for a list of ideals ----
+
+ intersect(lid:List(Ideal)) : Ideal == "intersect"/[l for l in lid]
+
+ ---- quotient by an element ----
+ quotient(I:Ideal,f:DPoly) : Ideal ==
+ --[[(g exquo f)::DPoly for g in (intersect(I,[f]::%)).idl ],true]
+ import GroebnerInternalPackage(F,Expon,VarSet,DPoly)
+ [minGbasis [(g exquo f)::DPoly
+ for g in (intersect(I,[f]::%)).idl ],true]
+
+ ---- quotient of two ideals ----
+ quotient(I:Ideal,J:Ideal) : Ideal ==
+ Jdl := J.idl
+ empty?(Jdl) => ideal [1]
+ [("intersect"/[quotient(I,f) for f in Jdl ]).idl ,true]
+
+
+ ---- sum of two ideals ----
+ (I:Ideal + J:Ideal) : Ideal == [groebner(concat(I.idl ,J.idl )),true]
+
+ ---- product of two ideals ----
+ (I:Ideal * J:Ideal):Ideal ==
+ [groebner([:[f*g for f in I.idl ] for g in J.idl ]),true]
+
+ ---- power of an ideal ----
+ (I:Ideal ** n:NNI) : Ideal ==
+ n=0 => [[1$DPoly],true]
+ (I * (I**(n-1):NNI))
+
+ ---- saturation with respect to the multiplicative set f**n ----
+ saturate(I:Ideal,f:DPoly) : Ideal ==
+ f=0 => error "f is zero"
+ tp:newPoly := (monomial(1,makeprod(1,0$Expon))$newPoly * npoly f)-1
+ contractGrob(concat(tp,[npoly g for g in I.idl ]))
+
+ ---- saturation with respect to a prime principal ideal in lvar ---
+ saturate(I:Ideal,f:DPoly,lvar:List(VarSet)) : Ideal ==
+ Id := I.idl
+ fullVars := "setUnion"/[variables g for g in Id]
+ newVars:=makeleast(fullVars,lvar)
+ subVars := [monomial(1,vv,1) for vv in newVars]
+ J:List DPoly:=groebner([eval(g,fullVars,subVars) for g in Id])
+ ltJ:=[leadterm(g,lvar) for g in J]
+ s:DPoly:=_*/[choosel(ltg,f) for ltg in ltJ]
+ fullPol:=[monomial(1,vv,1) for vv in fullVars]
+ [[eval(g,newVars,fullPol) for g in (saturate(J::%,s)).idl],true]
+
+ ---- is the ideal zero dimensional? ----
+ ---- in the ring F[lvar]? ----
+ zeroDim?(I:Ideal,lvar:List VarSet) : Boolean ==
+ J:=(groebner I).idl
+ empty? J => false
+ J = [1] => false
+ n:NNI := # lvar
+ #J < n => false
+ for f in J while ^empty?(lvar) repeat
+ x:=(mainVariable f)::VarSet
+ if isMonic?(f,x) then lvar:=delete(lvar,position(x,lvar))
+ empty?(lvar)
+
+ ---- is the ideal zero dimensional? ----
+ zeroDim?(I:Ideal):Boolean == zeroDim?(I,"setUnion"/[variables g for g in I.idl])
+
+ ---- test if f is in the radical of I ----
+ inRadical?(f:DPoly,I:Ideal) : Boolean ==
+ f=0$DPoly => true
+ tp:newPoly :=(monomial(1,makeprod(1,0$Expon))$newPoly * npoly f)-1
+ Id:=I.idl
+ normalForm(1$newPoly,groebner concat(tp,[npoly g for g in Id])) = 0
+
+ ---- dimension of an ideal ----
+ ---- in the ring F[lvar] ----
+ dimension(I:Ideal,lvar:List VarSet) : Z ==
+ I:=groebner I
+ empty?(I.idl) => # lvar
+ element?(1,I) => -1
+ truelist:="setUnion"/[variables f for f in I.idl]
+ "or"/[^member?(vv,lvar) for vv in truelist] => error "wrong variables"
+ truelist:=setDifference(lvar,setDifference(lvar,truelist))
+ ed:Z:=#lvar - #truelist
+ leadid:=leadingIdeal(I)
+ n1:Z:=monomDim(leadid,truelist)::Z
+ ed+n1
+
+ dimension(I:Ideal) : Z == dimension(I,"setUnion"/[variables g for g in I.idl])
+
+ -- leading term ideal --
+ leadingIdeal(I : Ideal) : Ideal ==
+ Idl:= (groebner I).idl
+ [[(f-reductum f) for f in Idl],true]
+
+ ---- ideal of relations among the fi ----
+ if VarSet has ConvertibleTo Symbol then
+
+ monompol(df:List NNI,lcf:F,lv:List VarSet) : P ==
+ g:P:=lcf::P
+ for dd in df for v in lv repeat
+ g:= monomial(g,convert v,dd)
+ g
+
+ relationsIdeal(listf : List DPoly): ST ==
+ empty? listf => [empty(),empty()]$ST
+ nf:=#listf
+ lvint := "setUnion"/[variables g for g in listf]
+ vl: List Symbol := [convert vv for vv in lvint]
+ nvar:List Symbol:=[new() for i in 1..nf]
+ VarSet1:=OrderedVariableList(concat(vl,nvar))
+ lv1:=[variable(vv)$VarSet1::VarSet1 for vv in nvar]
+ DirP:=DirectProduct(nf,NNI)
+ nExponent:=Product(Expon,DirP)
+ nPoly := PolynomialRing(F,nExponent)
+ gp:=GroebnerPackage(F,nExponent,VarSet1,nPoly)
+ lf:List nPoly :=[]
+ lp:List P:=[]
+ for f in listf for i in 1.. repeat
+ vec2:Vector(NNI):=new(nf,0$NNI)
+ vec2.i:=1
+ g:nPoly:=0$nPoly
+ pol:=0$P
+ while f^=0 repeat
+ df:=degree(f-reductum f,lvint)
+ lcf:=leadingCoefficient f
+ pol:=pol+monompol(df,lcf,lvint)
+ g:=g+monomial(lcf,makeprod(degree f,0))$nPoly
+ f:=reductum f
+ lp:=concat(pol,lp)
+ lf:=concat(monomial(1,makeprod(0,directProduct vec2))-g,lf)
+ npol:List P :=[v::P for v in nvar]
+ leq : List Equation P :=
+ [p = pol for p in npol for pol in reverse lp ]
+ lf:=(groebner lf)$gp
+ while lf^=[] repeat
+ q:=lf.first
+ dq:nExponent:=degree q
+ n:=selectfirst (dq)
+ if n=0 then leave "done"
+ lf:=lf.rest
+ solsn:List P:=[]
+ for q in lf repeat
+ g:Polynomial F :=0
+ while q^=0 repeat
+ dq:=degree q
+ lcq:=leadingCoefficient q
+ q:=reductum q
+ vdq:=(selectsecond dq):Vector NNI
+ g:=g+ lcq*
+ _*/[p**vdq.j for p in npol for j in 1..]
+ solsn:=concat(g,solsn)
+ [solsn,leq]$ST
+
+ coerce(Id:List DPoly) : Ideal == [Id,false]
+
+ coerce(I:Ideal) : OutputForm ==
+ Idl := I.idl
+ empty? Idl => [0$DPoly] :: OutputForm
+ Idl :: OutputForm
+
+ ideal(Id:List DPoly) :Ideal == [[f for f in Id|f^=0],false]
+
+ groebnerIdeal(Id:List DPoly) : Ideal == [Id,true]
+
+ generators(I:Ideal) : List DPoly == I.idl
+
+ groebner?(I:Ideal) : Boolean == I.isGr
+
+ one?(I:Ideal) : Boolean == element?(1, I)
+
+ zero?(I:Ideal) : Boolean == empty? (groebner I).idl
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain IDEAL PolynomialIdeals>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/idecomp.spad.pamphlet b/src/algebra/idecomp.spad.pamphlet
new file mode 100644
index 00000000..9ba4d219
--- /dev/null
+++ b/src/algebra/idecomp.spad.pamphlet
@@ -0,0 +1,440 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra idecomp.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IDECOMP IdealDecompositionPackage}
+<<package IDECOMP IdealDecompositionPackage>>=
+)abbrev package IDECOMP IdealDecompositionPackage
+++ Author: P. Gianni
+++ Date Created: summer 1986
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: PolynomialIdeals
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides functions for the primary decomposition of
+++ polynomial ideals over the rational numbers. The ideals are members
+++ of the \spadtype{PolynomialIdeals} domain, and the polynomial generators are
+++ required to be from the \spadtype{DistributedMultivariatePolynomial} domain.
+
+IdealDecompositionPackage(vl,nv) : C == T -- take away nv, now doesn't
+ -- compile if it isn't there
+ where
+ vl : List Symbol
+ nv : NonNegativeInteger
+ Z ==> Integer -- substitute with PFE cat
+ Q ==> Fraction Z
+ F ==> Fraction P
+ P ==> Polynomial Z
+ UP ==> SparseUnivariatePolynomial P
+ Expon ==> DirectProduct(nv,NNI)
+ OV ==> OrderedVariableList(vl)
+ SE ==> Symbol
+ SUP ==> SparseUnivariatePolynomial(DPoly)
+
+ DPoly1 ==> DistributedMultivariatePolynomial(vl,Q)
+ DPoly ==> DistributedMultivariatePolynomial(vl,F)
+ NNI ==> NonNegativeInteger
+
+ Ideal == PolynomialIdeals(Q,Expon,OV,DPoly1)
+ FIdeal == PolynomialIdeals(F,Expon,OV,DPoly)
+ Fun0 == Union("zeroPrimDecomp","zeroRadComp")
+ GenPos == Record(changeval:List Z,genideal:FIdeal)
+
+ C == with
+
+
+ zeroDimPrime? : Ideal -> Boolean
+ ++ zeroDimPrime?(I) tests if the ideal I is a 0-dimensional prime.
+
+ zeroDimPrimary? : Ideal -> Boolean
+ ++ zeroDimPrimary?(I) tests if the ideal I is 0-dimensional primary.
+ prime? : Ideal -> Boolean
+ ++ prime?(I) tests if the ideal I is prime.
+ radical : Ideal -> Ideal
+ ++ radical(I) returns the radical of the ideal I.
+ primaryDecomp : Ideal -> List(Ideal)
+ ++ primaryDecomp(I) returns a list of primary ideals such that their
+ ++ intersection is the ideal I.
+
+ contract : (Ideal,List OV ) -> Ideal
+ ++ contract(I,lvar) contracts the ideal I to the polynomial ring
+ ++ \spad{F[lvar]}.
+
+ T == add
+
+ import MPolyCatRationalFunctionFactorizer(Expon,OV,Z,DPoly)
+ import GroebnerPackage(F,Expon,OV,DPoly)
+ import GroebnerPackage(Q,Expon,OV,DPoly1)
+
+ ---- Local Functions -----
+ genPosLastVar : (FIdeal,List OV) -> GenPos
+ zeroPrimDecomp : (FIdeal,List OV) -> List(FIdeal)
+ zeroRadComp : (FIdeal,List OV) -> FIdeal
+ zerodimcase : (FIdeal,List OV) -> Boolean
+ is0dimprimary : (FIdeal,List OV) -> Boolean
+ backGenPos : (FIdeal,List Z,List OV) -> FIdeal
+ reduceDim : (Fun0,FIdeal,List OV) -> List FIdeal
+ findvar : (FIdeal,List OV) -> OV
+ testPower : (SUP,OV,FIdeal) -> Boolean
+ goodPower : (DPoly,FIdeal) -> Record(spol:DPoly,id:FIdeal)
+ pushdown : (DPoly,OV) -> DPoly
+ pushdterm : (DPoly,OV,Z) -> DPoly
+ pushup : (DPoly,OV) -> DPoly
+ pushuterm : (DPoly,SE,OV) -> DPoly
+ pushucoef : (UP,OV) -> DPoly
+ trueden : (P,SE) -> P
+ rearrange : (List OV) -> List OV
+ deleteunit : List FIdeal -> List FIdeal
+ ismonic : (DPoly,OV) -> Boolean
+
+
+ MPCFQF ==> MPolyCatFunctions2(OV,Expon,Expon,Q,F,DPoly1,DPoly)
+ MPCFFQ ==> MPolyCatFunctions2(OV,Expon,Expon,F,Q,DPoly,DPoly1)
+
+ convertQF(a:Q) : F == ((numer a):: F)/((denom a)::F)
+ convertFQ(a:F) : Q == (ground numer a)/(ground denom a)
+
+ internalForm(I:Ideal) : FIdeal ==
+ Id:=generators I
+ nId:=[map(convertQF,poly)$MPCFQF for poly in Id]
+ groebner? I => groebnerIdeal nId
+ ideal nId
+
+ externalForm(I:FIdeal) : Ideal ==
+ Id:=generators I
+ nId:=[map(convertFQ,poly)$MPCFFQ for poly in Id]
+ groebner? I => groebnerIdeal nId
+ ideal nId
+
+ lvint:=[variable(xx)::OV for xx in vl]
+ nvint1:=(#lvint-1)::NNI
+
+ deleteunit(lI: List FIdeal) : List FIdeal ==
+ [I for I in lI | _^ element?(1$DPoly,I)]
+
+ rearrange(vlist:List OV) :List OV ==
+ vlist=[] => vlist
+ sort(#1>#2,setDifference(lvint,setDifference(lvint,vlist)))
+
+ ---- radical of a 0-dimensional ideal ----
+ zeroRadComp(I:FIdeal,truelist:List OV) : FIdeal ==
+ truelist=[] => I
+ Id:=generators I
+ x:OV:=truelist.last
+ #Id=1 =>
+ f:=Id.first
+ g:= (f exquo (gcd (f,differentiate(f,x))))::DPoly
+ groebnerIdeal([g])
+ y:=truelist.first
+ px:DPoly:=x::DPoly
+ py:DPoly:=y::DPoly
+ f:=Id.last
+ g:= (f exquo (gcd (f,differentiate(f,x))))::DPoly
+ Id:=groebner(cons(g,remove(f,Id)))
+ lf:=Id.first
+ pv:DPoly:=0
+ pw:DPoly:=0
+ while degree(lf,y)^=1 repeat
+ val:=random()$Z rem 23
+ pv:=px+val*py
+ pw:=px-val*py
+ Id:=groebner([(univariate(h,x)).pv for h in Id])
+ lf:=Id.first
+ ris:= generators(zeroRadComp(groebnerIdeal(Id.rest),truelist.rest))
+ ris:=cons(lf,ris)
+ if pv^=0 then
+ ris:=[(univariate(h,x)).pw for h in ris]
+ groebnerIdeal(groebner ris)
+
+ ---- find the power that stabilizes (I:s) ----
+ goodPower(s:DPoly,I:FIdeal) : Record(spol:DPoly,id:FIdeal) ==
+ f:DPoly:=s
+ I:=groebner I
+ J:=generators(JJ:= (saturate(I,s)))
+ while _^ in?(ideal([f*g for g in J]),I) repeat f:=s*f
+ [f,JJ]
+
+ ---- is the ideal zerodimensional? ----
+ ---- the "true variables" are in truelist ----
+ zerodimcase(J:FIdeal,truelist:List OV) : Boolean ==
+ element?(1,J) => true
+ truelist=[] => true
+ n:=#truelist
+ Jd:=groebner generators J
+ for x in truelist while Jd^=[] repeat
+ f := Jd.first
+ Jd:=Jd.rest
+ if ((y:=mainVariable f) case "failed") or (y::OV ^=x )
+ or _^ (ismonic (f,x)) then return false
+ while Jd^=[] and (mainVariable Jd.first)::OV=x repeat Jd:=Jd.rest
+ if Jd=[] and position(x,truelist)<n then return false
+ true
+
+ ---- choose the variable for the reduction step ----
+ --- J groebnerner in gen pos ---
+ findvar(J:FIdeal,truelist:List OV) : OV ==
+ lmonicvar:List OV :=[]
+ for f in generators J repeat
+ t:=f - reductum f
+ vt:List OV :=variables t
+ if #vt=1 then lmonicvar:=setUnion(vt,lmonicvar)
+ badvar:=setDifference(truelist,lmonicvar)
+ badvar.first
+
+ ---- function for the "reduction step ----
+ reduceDim(flag:Fun0,J:FIdeal,truelist:List OV) : List(FIdeal) ==
+ element?(1,J) => [J]
+ zerodimcase(J,truelist) =>
+ (flag case "zeroPrimDecomp") => zeroPrimDecomp(J,truelist)
+ (flag case "zeroRadComp") => [zeroRadComp(J,truelist)]
+ x:OV:=findvar(J,truelist)
+ Jnew:=[pushdown(f,x) for f in generators J]
+ Jc: List FIdeal :=[]
+ Jc:=reduceDim(flag,groebnerIdeal Jnew,remove(x,truelist))
+ res1:=[ideal([pushup(f,x) for f in generators idp]) for idp in Jc]
+ s:=pushup((_*/[leadingCoefficient f for f in Jnew])::DPoly,x)
+ degree(s,x)=0 => res1
+ res1:=[saturate(II,s) for II in res1]
+ good:=goodPower(s,J)
+ sideal := groebnerIdeal(groebner(cons(good.spol,generators J)))
+ in?(good.id, sideal) => res1
+ sresult:=reduceDim(flag,sideal,truelist)
+ for JJ in sresult repeat
+ if not(in?(good.id,JJ)) then res1:=cons(JJ,res1)
+ res1
+
+ ---- Primary Decomposition for 0-dimensional ideals ----
+ zeroPrimDecomp(I:FIdeal,truelist:List OV): List(FIdeal) ==
+ truelist=[] => list I
+ newJ:=genPosLastVar(I,truelist);lval:=newJ.changeval;
+ J:=groebner newJ.genideal
+ x:=truelist.last
+ Jd:=generators J
+ g:=Jd.last
+ lfact:= factors factor(g)
+ ris:List FIdeal:=[]
+ for ef in lfact repeat
+ g:DPoly:=(ef.factor)**(ef.exponent::NNI)
+ J1:= groebnerIdeal(groebner cons(g,Jd))
+ if _^ (is0dimprimary (J1,truelist)) then
+ return zeroPrimDecomp(I,truelist)
+ ris:=cons(groebner backGenPos(J1,lval,truelist),ris)
+ ris
+
+ ---- radical of an Ideal ----
+ radical(I:Ideal) : Ideal ==
+ J:=groebner(internalForm I)
+ truelist:=rearrange("setUnion"/[variables f for f in generators J])
+ truelist=[] => externalForm J
+ externalForm("intersect"/reduceDim("zeroRadComp",J,truelist))
+
+
+-- the following functions are used to "push" x in the coefficient ring -
+
+ ---- push x in the coefficient domain for a polynomial ----
+ pushdown(g:DPoly,x:OV) : DPoly ==
+ rf:DPoly:=0$DPoly
+ i:=position(x,lvint)
+ while g^=0 repeat
+ g1:=reductum g
+ rf:=rf+pushdterm(g-g1,x,i)
+ g := g1
+ rf
+
+ ---- push x in the coefficient domain for a term ----
+ pushdterm(t:DPoly,x:OV,i:Z):DPoly ==
+ n:=degree(t,x)
+ xp:=convert(x)@SE
+ cf:=monomial(1,xp,n)$P :: F
+ newt := t exquo monomial(1,x,n)$DPoly
+ cf * newt::DPoly
+
+ ---- push back the variable ----
+ pushup(f:DPoly,x:OV) :DPoly ==
+ h:=1$P
+ rf:DPoly:=0$DPoly
+ g := f
+ xp := convert(x)@SE
+ while g^=0 repeat
+ h:=lcm(trueden(denom leadingCoefficient g,xp),h)
+ g:=reductum g
+ f:=(h::F)*f
+ while f^=0 repeat
+ g:=reductum f
+ rf:=rf+pushuterm(f-g,xp,x)
+ f:=g
+ rf
+
+ trueden(c:P,x:SE) : P ==
+ degree(c,x) = 0 => 1
+ c
+
+ ---- push x back from the coefficient domain for a term ----
+ pushuterm(t:DPoly,xp:SE,x:OV):DPoly ==
+ pushucoef((univariate(numer leadingCoefficient t,xp)$P), x)*
+ monomial(inv((denom leadingCoefficient t)::F),degree t)$DPoly
+
+
+ pushucoef(c:UP,x:OV):DPoly ==
+ c = 0 => 0
+ monomial((leadingCoefficient c)::F::DPoly,x,degree c) +
+ pushucoef(reductum c,x)
+
+ -- is the 0-dimensional ideal I primary ? --
+ ---- internal function ----
+ is0dimprimary(J:FIdeal,truelist:List OV) : Boolean ==
+ element?(1,J) => true
+ Jd:=generators(groebner J)
+ #(factors factor Jd.last)^=1 => return false
+ i:=subtractIfCan(#truelist,1)
+ (i case "failed") => return true
+ JR:=(reverse Jd);JM:=groebnerIdeal([JR.first]);JP:List(DPoly):=[]
+ for f in JR.rest repeat
+ if _^ ismonic(f,truelist.i) then
+ if _^ inRadical?(f,JM) then return false
+ JP:=cons(f,JP)
+ else
+ x:=truelist.i
+ i:=(i-1)::NNI
+ if _^ testPower(univariate(f,x),x,JM) then return false
+ JM :=groebnerIdeal(append(cons(f,JP),generators JM))
+ true
+
+ ---- Functions for the General Position step ----
+
+ ---- put the ideal in general position ----
+ genPosLastVar(J:FIdeal,truelist:List OV):GenPos ==
+ x := last truelist ;lv1:List OV :=remove(x,truelist)
+ ranvals:List(Z):=[(random()$Z rem 23) for vv in lv1]
+ val:=_+/[rv*(vv::DPoly) for vv in lv1 for rv in ranvals]
+ val:=val+(x::DPoly)
+ [ranvals,groebnerIdeal(groebner([(univariate(p,x)).val
+ for p in generators J]))]$GenPos
+
+
+ ---- convert back the ideal ----
+ backGenPos(I:FIdeal,lval:List Z,truelist:List OV) : FIdeal ==
+ lval=[] => I
+ x := last truelist ;lv1:List OV:=remove(x,truelist)
+ val:=-(_+/[rv*(vv::DPoly) for vv in lv1 for rv in lval])
+ val:=val+(x::DPoly)
+ groebnerIdeal
+ (groebner([(univariate(p,x)).val for p in generators I ]))
+
+ ismonic(f:DPoly,x:OV) : Boolean == ground? leadingCoefficient(univariate(f,x))
+
+ ---- test if f is power of a linear mod (rad J) ----
+ ---- f is monic ----
+ testPower(uf:SUP,x:OV,J:FIdeal) : Boolean ==
+ df:=degree(uf)
+ trailp:DPoly := inv(df:Z ::F) *coefficient(uf,(df-1)::NNI)
+ linp:SUP:=(monomial(1$DPoly,1$NNI)$SUP +
+ monomial(trailp,0$NNI)$SUP)**df
+ g:DPoly:=multivariate(uf-linp,x)
+ inRadical?(g,J)
+
+
+ ---- Exported Functions ----
+
+ -- is the 0-dimensional ideal I prime ? --
+ zeroDimPrime?(I:Ideal) : Boolean ==
+ J:=groebner((genPosLastVar(internalForm I,lvint)).genideal)
+ element?(1,J) => true
+ n:NNI:=#vl;i:NNI:=1
+ Jd:=generators J
+ #Jd^=n => false
+ for f in Jd repeat
+ if _^ ismonic(f,lvint.i) then return false
+ if i<n and (degree univariate(f,lvint.i))^=1 then return false
+ i:=i+1
+ g:=Jd.n
+ #(lfact:=factors(factor g)) >1 => false
+ lfact.1.exponent =1
+
+
+ -- is the 0-dimensional ideal I primary ? --
+ zeroDimPrimary?(J:Ideal):Boolean ==
+ is0dimprimary(internalForm J,lvint)
+
+ ---- Primary Decomposition of I -----
+
+ primaryDecomp(I:Ideal) : List(Ideal) ==
+ J:=groebner(internalForm I)
+ truelist:=rearrange("setUnion"/[variables f for f in generators J])
+ truelist=[] => [externalForm J]
+ [externalForm II for II in reduceDim("zeroPrimDecomp",J,truelist)]
+
+ ---- contract I to the ring with lvar variables ----
+ contract(I:Ideal,lvar: List OV) : Ideal ==
+ Id:= generators(groebner I)
+ empty?(Id) => I
+ fullVars:= "setUnion"/[variables g for g in Id]
+ fullVars = lvar => I
+ n:= # lvar
+ #fullVars < n => error "wrong vars"
+ n=0 => I
+ newVars:= append([vv for vv in fullVars| ^member?(vv,lvar)]$List(OV),lvar)
+ subsVars := [monomial(1,vv,1)$DPoly1 for vv in newVars]
+ lJ:= [eval(g,fullVars,subsVars) for g in Id]
+ J := groebner(lJ)
+ J=[1] => groebnerIdeal J
+ J=[0] => groebnerIdeal empty()
+ J:=[f for f in J| member?(mainVariable(f)::OV,newVars)]
+ fullPol :=[monomial(1,vv,1)$DPoly1 for vv in fullVars]
+ groebnerIdeal([eval(gg,newVars,fullPol) for gg in J])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package IDECOMP IdealDecompositionPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/indexedp.spad.pamphlet b/src/algebra/indexedp.spad.pamphlet
new file mode 100644
index 00000000..41f9bc89
--- /dev/null
+++ b/src/algebra/indexedp.spad.pamphlet
@@ -0,0 +1,350 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra indexedp.spad}
+\author{James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category IDPC IndexedDirectProductCategory}
+<<category IDPC IndexedDirectProductCategory>>=
+)abbrev category IDPC IndexedDirectProductCategory
+++ Author: James Davenport
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This category represents the direct product of some set with
+++ respect to an ordered indexing set.
+
+IndexedDirectProductCategory(A:SetCategory,S:OrderedSet): Category ==
+ SetCategory with
+ map: (A -> A, %) -> %
+ ++ map(f,z) returns the new element created by applying the
+ ++ function f to each component of the direct product element z.
+ monomial: (A, S) -> %
+ ++ monomial(a,s) constructs a direct product element with the s
+ ++ component set to \spad{a}
+ leadingCoefficient: % -> A
+ ++ leadingCoefficient(z) returns the coefficient of the leading
+ ++ (with respect to the ordering on the indexing set)
+ ++ monomial of z.
+ ++ Error: if z has no support.
+ leadingSupport: % -> S
+ ++ leadingSupport(z) returns the index of leading
+ ++ (with respect to the ordering on the indexing set) monomial of z.
+ ++ Error: if z has no support.
+ reductum: % -> %
+ ++ reductum(z) returns a new element created by removing the
+ ++ leading coefficient/support pair from the element z.
+ ++ Error: if z has no support.
+
+@
+\section{domain IDPO IndexedDirectProductObject}
+<<domain IDPO IndexedDirectProductObject>>=
+)abbrev domain IDPO IndexedDirectProductObject
+++ Indexed direct products of objects over a set \spad{A}
+++ of generators indexed by an ordered set S. All items have finite support.
+IndexedDirectProductObject(A:SetCategory,S:OrderedSet): IndexedDirectProductCategory(A,S)
+ == add
+ --representations
+ Term:= Record(k:S,c:A)
+ Rep:= List Term
+ --declarations
+ x,y: %
+ f: A -> A
+ s: S
+ --define
+ x = y ==
+ while not null x and _^ null y repeat
+ x.first.k ^= y.first.k => return false
+ x.first.c ^= y.first.c => return false
+ x:=x.rest
+ y:=y.rest
+ null x and null y
+
+ coerce(x:%):OutputForm ==
+ bracket [rarrow(t.k :: OutputForm, t.c :: OutputForm) for t in x]
+
+ -- sample():% == [[sample()$S,sample()$A]$Term]$Rep
+
+ monomial(r,s) == [[s,r]]
+ map(f,x) == [[tm.k,f(tm.c)] for tm in x]
+
+ reductum x ==
+ rest x
+ leadingCoefficient x ==
+ null x => error "Can't take leadingCoefficient of empty product element"
+ x.first.c
+ leadingSupport x ==
+ null x => error "Can't take leadingCoefficient of empty product element"
+ x.first.k
+
+@
+\section{domain IDPAM IndexedDirectProductAbelianMonoid}
+<<domain IDPAM IndexedDirectProductAbelianMonoid>>=
+)abbrev domain IDPAM IndexedDirectProductAbelianMonoid
+++ Indexed direct products of abelian monoids over an abelian monoid \spad{A} of
+++ generators indexed by the ordered set S. All items have finite support.
+++ Only non-zero terms are stored.
+IndexedDirectProductAbelianMonoid(A:AbelianMonoid,S:OrderedSet):
+ Join(AbelianMonoid,IndexedDirectProductCategory(A,S))
+ == IndexedDirectProductObject(A,S) add
+ --representations
+ Term:= Record(k:S,c:A)
+ Rep:= List Term
+ x,y: %
+ r: A
+ n: NonNegativeInteger
+ f: A -> A
+ s: S
+ 0 == []
+ zero? x == null x
+
+ -- PERFORMANCE CRITICAL; Should build list up
+ -- by merging 2 sorted lists. Doing this will
+ -- avoid the recursive calls (very useful if there is a
+ -- large number of vars in a polynomial.
+-- x + y ==
+-- null x => y
+-- null y => x
+-- y.first.k > x.first.k => cons(y.first,(x + y.rest))
+-- x.first.k > y.first.k => cons(x.first,(x.rest + y))
+-- r:= x.first.c + y.first.c
+-- r = 0 => x.rest + y.rest
+-- cons([x.first.k,r],(x.rest + y.rest))
+ qsetrest!: (Rep, Rep) -> Rep
+ qsetrest!(l: Rep, e: Rep): Rep == RPLACD(l, e)$Lisp
+
+ x + y ==
+ null x => y
+ null y => x
+ endcell: Rep := empty()
+ res: Rep := empty()
+ while not empty? x and not empty? y repeat
+ newcell := empty()
+ if x.first.k = y.first.k then
+ r:= x.first.c + y.first.c
+ if not zero? r then
+ newcell := cons([x.first.k, r], empty())
+ x := rest x
+ y := rest y
+ else if x.first.k > y.first.k then
+ newcell := cons(x.first, empty())
+ x := rest x
+ else
+ newcell := cons(y.first, empty())
+ y := rest y
+ if not empty? newcell then
+ if not empty? endcell then
+ qsetrest!(endcell, newcell)
+ endcell := newcell
+ else
+ res := newcell;
+ endcell := res
+ if empty? x then end := y
+ else end := x
+ if empty? res then res := end
+ else qsetrest!(endcell, end)
+ res
+
+ n * x ==
+ n = 0 => 0
+ n = 1 => x
+ [[u.k,a] for u in x | (a:=n*u.c) ^= 0$A]
+
+ monomial(r,s) == (r = 0 => 0; [[s,r]])
+ map(f,x) == [[tm.k,a] for tm in x | (a:=f(tm.c)) ^= 0$A]
+
+ reductum x == (null x => 0; rest x)
+ leadingCoefficient x == (null x => 0; x.first.c)
+
+@
+\section{domain IDPOAM IndexedDirectProductOrderedAbelianMonoid}
+<<domain IDPOAM IndexedDirectProductOrderedAbelianMonoid>>=
+)abbrev domain IDPOAM IndexedDirectProductOrderedAbelianMonoid
+++ Indexed direct products of ordered abelian monoids \spad{A} of
+++ generators indexed by the ordered set S.
+++ The inherited order is lexicographical.
+++ All items have finite support: only non-zero terms are stored.
+IndexedDirectProductOrderedAbelianMonoid(A:OrderedAbelianMonoid,S:OrderedSet):
+ Join(OrderedAbelianMonoid,IndexedDirectProductCategory(A,S))
+ == IndexedDirectProductAbelianMonoid(A,S) add
+ --representations
+ Term:= Record(k:S,c:A)
+ Rep:= List Term
+ x,y: %
+ x<y ==
+ empty? y => false
+ empty? x => true -- note careful order of these two lines
+ y.first.k > x.first.k => true
+ y.first.k < x.first.k => false
+ y.first.c > x.first.c => true
+ y.first.c < x.first.c => false
+ x.rest < y.rest
+
+@
+\section{domain IDPOAMS IndexedDirectProductOrderedAbelianMonoidSup}
+<<domain IDPOAMS IndexedDirectProductOrderedAbelianMonoidSup>>=
+)abbrev domain IDPOAMS IndexedDirectProductOrderedAbelianMonoidSup
+++ Indexed direct products of ordered abelian monoid sups \spad{A},
+++ generators indexed by the ordered set S.
+++ All items have finite support: only non-zero terms are stored.
+IndexedDirectProductOrderedAbelianMonoidSup(A:OrderedAbelianMonoidSup,S:OrderedSet):
+ Join(OrderedAbelianMonoidSup,IndexedDirectProductCategory(A,S))
+ == IndexedDirectProductOrderedAbelianMonoid(A,S) add
+ --representations
+ Term:= Record(k:S,c:A)
+ Rep:= List Term
+ x,y: %
+ r: A
+ s: S
+
+ subtractIfCan(x,y) ==
+ empty? y => x
+ empty? x => "failed"
+ x.first.k < y.first.k => "failed"
+ x.first.k > y.first.k =>
+ t:= subtractIfCan(x.rest, y)
+ t case "failed" => "failed"
+ cons( x.first, t)
+ u:=subtractIfCan(x.first.c, y.first.c)
+ u case "failed" => "failed"
+ zero? u => subtractIfCan(x.rest, y.rest)
+ t:= subtractIfCan(x.rest, y.rest)
+ t case "failed" => "failed"
+ cons([x.first.k,u],t)
+
+ sup(x,y) ==
+ empty? y => x
+ empty? x => y
+ x.first.k < y.first.k => cons(y.first,sup(x,y.rest))
+ x.first.k > y.first.k => cons(x.first,sup(x.rest,y))
+ u:=sup(x.first.c, y.first.c)
+ cons([x.first.k,u],sup(x.rest,y.rest))
+
+@
+\section{domain IDPAG IndexedDirectProductAbelianGroup}
+<<domain IDPAG IndexedDirectProductAbelianGroup>>=
+)abbrev domain IDPAG IndexedDirectProductAbelianGroup
+++ Indexed direct products of abelian groups over an abelian group \spad{A} of
+++ generators indexed by the ordered set S.
+++ All items have finite support: only non-zero terms are stored.
+IndexedDirectProductAbelianGroup(A:AbelianGroup,S:OrderedSet):
+ Join(AbelianGroup,IndexedDirectProductCategory(A,S))
+ == IndexedDirectProductAbelianMonoid(A,S) add
+ --representations
+ Term:= Record(k:S,c:A)
+ Rep:= List Term
+ x,y: %
+ r: A
+ n: Integer
+ f: A -> A
+ s: S
+ -x == [[u.k,-u.c] for u in x]
+ n * x ==
+ n = 0 => 0
+ n = 1 => x
+ [[u.k,a] for u in x | (a:=n*u.c) ^= 0$A]
+
+ qsetrest!: (Rep, Rep) -> Rep
+ qsetrest!(l: Rep, e: Rep): Rep == RPLACD(l, e)$Lisp
+
+ x - y ==
+ null x => -y
+ null y => x
+ endcell: Rep := empty()
+ res: Rep := empty()
+ while not empty? x and not empty? y repeat
+ newcell := empty()
+ if x.first.k = y.first.k then
+ r:= x.first.c - y.first.c
+ if not zero? r then
+ newcell := cons([x.first.k, r], empty())
+ x := rest x
+ y := rest y
+ else if x.first.k > y.first.k then
+ newcell := cons(x.first, empty())
+ x := rest x
+ else
+ newcell := cons([y.first.k,-y.first.c], empty())
+ y := rest y
+ if not empty? newcell then
+ if not empty? endcell then
+ qsetrest!(endcell, newcell)
+ endcell := newcell
+ else
+ res := newcell;
+ endcell := res
+ if empty? x then end := - y
+ else end := x
+ if empty? res then res := end
+ else qsetrest!(endcell, end)
+ res
+
+-- x - y ==
+-- empty? x => - y
+-- empty? y => x
+-- y.first.k > x.first.k => cons([y.first.k,-y.first.c],(x - y.rest))
+-- x.first.k > y.first.k => cons(x.first,(x.rest - y))
+-- r:= x.first.c - y.first.c
+-- r = 0 => x.rest - y.rest
+-- cons([x.first.k,r],(x.rest - y.rest))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category IDPC IndexedDirectProductCategory>>
+<<domain IDPO IndexedDirectProductObject>>
+<<domain IDPAM IndexedDirectProductAbelianMonoid>>
+<<domain IDPOAM IndexedDirectProductOrderedAbelianMonoid>>
+<<domain IDPOAMS IndexedDirectProductOrderedAbelianMonoidSup>>
+<<domain IDPAG IndexedDirectProductAbelianGroup>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/infprod.spad.pamphlet b/src/algebra/infprod.spad.pamphlet
new file mode 100644
index 00000000..ac34c2ea
--- /dev/null
+++ b/src/algebra/infprod.spad.pamphlet
@@ -0,0 +1,346 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra infprod.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package STINPROD StreamInfiniteProduct}
+<<package STINPROD StreamInfiniteProduct>>=
+)abbrev package STINPROD StreamInfiniteProduct
+++ Author: Clifton J. Williamson
+++ Date Created: 23 February 1990
+++ Date Last Updated: 23 February 1990
+++ Basic Operations: infiniteProduct, evenInfiniteProduct, oddInfiniteProduct,
+++ generalInfiniteProduct
+++ Related Domains: UnivariateTaylorSeriesCategory
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, infinite product
+++ Examples:
+++ References:
+++ Description:
+++ This package computes infinite products of Taylor series over an
+++ integral domain of characteristic 0. Here Taylor series are
+++ represented by streams of Taylor coefficients.
+StreamInfiniteProduct(Coef): Exports == Implementation where
+ Coef: Join(IntegralDomain,CharacteristicZero)
+ I ==> Integer
+ QF ==> Fraction
+ ST ==> Stream
+
+ Exports ==> with
+
+ infiniteProduct: ST Coef -> ST Coef
+ ++ infiniteProduct(f(x)) computes \spad{product(n=1,2,3...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ evenInfiniteProduct: ST Coef -> ST Coef
+ ++ evenInfiniteProduct(f(x)) computes \spad{product(n=2,4,6...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ oddInfiniteProduct: ST Coef -> ST Coef
+ ++ oddInfiniteProduct(f(x)) computes \spad{product(n=1,3,5...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ generalInfiniteProduct: (ST Coef,I,I) -> ST Coef
+ ++ generalInfiniteProduct(f(x),a,d) computes
+ ++ \spad{product(n=a,a+d,a+2*d,...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+
+ Implementation ==> add
+
+ if Coef has Field then
+
+ import StreamTaylorSeriesOperations(Coef)
+ import StreamTranscendentalFunctions(Coef)
+
+ infiniteProduct st == exp lambert log st
+ evenInfiniteProduct st == exp evenlambert log st
+ oddInfiniteProduct st == exp oddlambert log st
+ generalInfiniteProduct(st,a,d) == exp generalLambert(log st,a,d)
+
+ else
+
+ import StreamTaylorSeriesOperations(QF Coef)
+ import StreamTranscendentalFunctions(QF Coef)
+
+ applyOverQF:(ST QF Coef -> ST QF Coef,ST Coef) -> ST Coef
+ applyOverQF(f,st) ==
+ stQF := map(#1 :: QF(Coef),st)$StreamFunctions2(Coef,QF Coef)
+ map(retract(#1)@Coef,f stQF)$StreamFunctions2(QF Coef,Coef)
+
+ infiniteProduct st == applyOverQF(exp lambert log #1,st)
+ evenInfiniteProduct st == applyOverQF(exp evenlambert log #1,st)
+ oddInfiniteProduct st == applyOverQF(exp oddlambert log #1,st)
+ generalInfiniteProduct(st,a,d) ==
+ applyOverQF(exp generalLambert(log #1,a,d),st)
+
+@
+\section{package INFPROD0 InfiniteProductCharacteristicZero}
+<<package INFPROD0 InfiniteProductCharacteristicZero>>=
+)abbrev package INFPROD0 InfiniteProductCharacteristicZero
+++ Author: Clifton J. Williamson
+++ Date Created: 22 February 1990
+++ Date Last Updated: 23 February 1990
+++ Basic Operations: infiniteProduct, evenInfiniteProduct, oddInfiniteProduct,
+++ generalInfiniteProduct
+++ Related Domains: UnivariateTaylorSeriesCategory
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, infinite product
+++ Examples:
+++ References:
+++ Description:
+++ This package computes infinite products of univariate Taylor series
+++ over an integral domain of characteristic 0.
+InfiniteProductCharacteristicZero(Coef,UTS):_
+ Exports == Implementation where
+ Coef : Join(IntegralDomain,CharacteristicZero)
+ UTS : UnivariateTaylorSeriesCategory Coef
+ I ==> Integer
+
+ Exports ==> with
+
+ infiniteProduct: UTS -> UTS
+ ++ infiniteProduct(f(x)) computes \spad{product(n=1,2,3...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ evenInfiniteProduct: UTS -> UTS
+ ++ evenInfiniteProduct(f(x)) computes \spad{product(n=2,4,6...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ oddInfiniteProduct: UTS -> UTS
+ ++ oddInfiniteProduct(f(x)) computes \spad{product(n=1,3,5...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ generalInfiniteProduct: (UTS,I,I) -> UTS
+ ++ generalInfiniteProduct(f(x),a,d) computes
+ ++ \spad{product(n=a,a+d,a+2*d,...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+
+ Implementation ==> add
+
+ import StreamInfiniteProduct Coef
+
+ infiniteProduct x == series infiniteProduct coefficients x
+ evenInfiniteProduct x == series evenInfiniteProduct coefficients x
+ oddInfiniteProduct x == series oddInfiniteProduct coefficients x
+
+ generalInfiniteProduct(x,a,d) ==
+ series generalInfiniteProduct(coefficients x,a,d)
+
+@
+\section{package INPRODPF InfiniteProductPrimeField}
+<<package INPRODPF InfiniteProductPrimeField>>=
+)abbrev package INPRODPF InfiniteProductPrimeField
+++ Author: Clifton J. Williamson
+++ Date Created: 22 February 1990
+++ Date Last Updated: 23 February 1990
+++ Basic Operations: infiniteProduct, evenInfiniteProduct, oddInfiniteProduct,
+++ generalInfiniteProduct
+++ Related Domains: UnivariateTaylorSeriesCategory
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, infinite product
+++ Examples:
+++ References:
+++ Description:
+++ This package computes infinite products of univariate Taylor series
+++ over a field of prime order.
+InfiniteProductPrimeField(Coef,UTS): Exports == Implementation where
+ Coef : Join(Field,Finite,ConvertibleTo Integer)
+ UTS : UnivariateTaylorSeriesCategory Coef
+ I ==> Integer
+ ST ==> Stream
+
+ Exports ==> with
+
+ infiniteProduct: UTS -> UTS
+ ++ infiniteProduct(f(x)) computes \spad{product(n=1,2,3...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ evenInfiniteProduct: UTS -> UTS
+ ++ evenInfiniteProduct(f(x)) computes \spad{product(n=2,4,6...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ oddInfiniteProduct: UTS -> UTS
+ ++ oddInfiniteProduct(f(x)) computes \spad{product(n=1,3,5...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ generalInfiniteProduct: (UTS,I,I) -> UTS
+ ++ generalInfiniteProduct(f(x),a,d) computes
+ ++ \spad{product(n=a,a+d,a+2*d,...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+
+ Implementation ==> add
+
+ import StreamInfiniteProduct Integer
+
+ applyOverZ:(ST I -> ST I,ST Coef) -> ST Coef
+ applyOverZ(f,st) ==
+ stZ := map(convert(#1)@Integer,st)$StreamFunctions2(Coef,I)
+ map(#1 :: Coef,f stZ)$StreamFunctions2(I,Coef)
+
+ infiniteProduct x ==
+ series applyOverZ(infiniteProduct,coefficients x)
+ evenInfiniteProduct x ==
+ series applyOverZ(evenInfiniteProduct,coefficients x)
+ oddInfiniteProduct x ==
+ series applyOverZ(oddInfiniteProduct,coefficients x)
+ generalInfiniteProduct(x,a,d) ==
+ series applyOverZ(generalInfiniteProduct(#1,a,d),coefficients x)
+
+@
+\section{package INPRODFF InfiniteProductFiniteField}
+<<package INPRODFF InfiniteProductFiniteField>>=
+)abbrev package INPRODFF InfiniteProductFiniteField
+++ Author: Clifton J. Williamson
+++ Date Created: 22 February 1990
+++ Date Last Updated: 23 February 1990
+++ Basic Operations: infiniteProduct, evenInfiniteProduct, oddInfiniteProduct,
+++ generalInfiniteProduct
+++ Related Domains: UnivariateTaylorSeriesCategory
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, infinite product
+++ Examples:
+++ References:
+++ Description:
+++ This package computes infinite products of univariate Taylor series
+++ over an arbitrary finite field.
+InfiniteProductFiniteField(K,UP,Coef,UTS):_
+ Exports == Implementation where
+ K : Join(Field,Finite,ConvertibleTo Integer)
+ UP : UnivariatePolynomialCategory K
+ Coef : MonogenicAlgebra(K,UP)
+ UTS : UnivariateTaylorSeriesCategory Coef
+ I ==> Integer
+ RN ==> Fraction Integer
+ SAE ==> SimpleAlgebraicExtension
+ ST ==> Stream
+ STF ==> StreamTranscendentalFunctions
+ STT ==> StreamTaylorSeriesOperations
+ ST2 ==> StreamFunctions2
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> with
+
+ infiniteProduct: UTS -> UTS
+ ++ infiniteProduct(f(x)) computes \spad{product(n=1,2,3...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ evenInfiniteProduct: UTS -> UTS
+ ++ evenInfiniteProduct(f(x)) computes \spad{product(n=2,4,6...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ oddInfiniteProduct: UTS -> UTS
+ ++ oddInfiniteProduct(f(x)) computes \spad{product(n=1,3,5...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+ generalInfiniteProduct: (UTS,I,I) -> UTS
+ ++ generalInfiniteProduct(f(x),a,d) computes
+ ++ \spad{product(n=a,a+d,a+2*d,...,f(x**n))}.
+ ++ The series \spad{f(x)} should have constant coefficient 1.
+
+ Implementation ==> add
+
+ liftPoly: UP -> SUP RN
+ liftPoly poly ==
+ -- lift coefficients of 'poly' to integers
+ ans : SUP RN := 0
+ while not zero? poly repeat
+ coef := convert(leadingCoefficient poly)@I :: RN
+ ans := ans + monomial(coef,degree poly)
+ poly := reductum poly
+ ans
+
+ reducePoly: SUP RN -> UP
+ reducePoly poly ==
+ -- reduce coefficients of 'poly' to elements of K
+ ans : UP := 0
+ while not zero? poly repeat
+ coef := numer(leadingCoefficient(poly)) :: K
+ ans := ans + monomial(coef,degree poly)
+ poly := reductum poly
+ ans
+
+ POLY := liftPoly definingPolynomial()$Coef
+ ALG := SAE(RN,SUP RN,POLY)
+
+ infiniteProduct x ==
+ stUP := map(lift,coefficients x)$ST2(Coef,UP)
+ stSUP := map(liftPoly,stUP)$ST2(UP,SUP RN)
+ stALG := map(reduce,stSUP)$ST2(SUP RN,ALG)
+ stALG := exp(lambert(log(stALG)$STF(ALG))$STT(ALG))$STF(ALG)
+ stSUP := map(lift,stALG)$ST2(ALG,SUP RN)
+ stUP := map(reducePoly,stSUP)$ST2(SUP RN,UP)
+ series map(reduce,stUP)$ST2(UP,Coef)
+
+ evenInfiniteProduct x ==
+ stUP := map(lift,coefficients x)$ST2(Coef,UP)
+ stSUP := map(liftPoly,stUP)$ST2(UP,SUP RN)
+ stALG := map(reduce,stSUP)$ST2(SUP RN,ALG)
+ stALG := exp(evenlambert(log(stALG)$STF(ALG))$STT(ALG))$STF(ALG)
+ stSUP := map(lift,stALG)$ST2(ALG,SUP RN)
+ stUP := map(reducePoly,stSUP)$ST2(SUP RN,UP)
+ series map(reduce,stUP)$ST2(UP,Coef)
+
+ oddInfiniteProduct x ==
+ stUP := map(lift,coefficients x)$ST2(Coef,UP)
+ stSUP := map(liftPoly,stUP)$ST2(UP,SUP RN)
+ stALG := map(reduce,stSUP)$ST2(SUP RN,ALG)
+ stALG := exp(oddlambert(log(stALG)$STF(ALG))$STT(ALG))$STF(ALG)
+ stSUP := map(lift,stALG)$ST2(ALG,SUP RN)
+ stUP := map(reducePoly,stSUP)$ST2(SUP RN,UP)
+ series map(reduce,stUP)$ST2(UP,Coef)
+
+ generalInfiniteProduct(x,a,d) ==
+ stUP := map(lift,coefficients x)$ST2(Coef,UP)
+ stSUP := map(liftPoly,stUP)$ST2(UP,SUP RN)
+ stALG := map(reduce,stSUP)$ST2(SUP RN,ALG)
+ stALG := generalLambert(log(stALG)$STF(ALG),a,d)$STT(ALG)
+ stALG := exp(stALG)$STF(ALG)
+ stSUP := map(lift,stALG)$ST2(ALG,SUP RN)
+ stUP := map(reducePoly,stSUP)$ST2(SUP RN,UP)
+ series map(reduce,stUP)$ST2(UP,Coef)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package STINPROD StreamInfiniteProduct>>
+<<package INFPROD0 InfiniteProductCharacteristicZero>>
+<<package INPRODPF InfiniteProductPrimeField>>
+<<package INPRODFF InfiniteProductFiniteField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intaf.spad.pamphlet b/src/algebra/intaf.spad.pamphlet
new file mode 100644
index 00000000..23f73b17
--- /dev/null
+++ b/src/algebra/intaf.spad.pamphlet
@@ -0,0 +1,782 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intaf.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTG0 GenusZeroIntegration}
+<<package INTG0 GenusZeroIntegration>>=
+)abbrev package INTG0 GenusZeroIntegration
+++ Rationalization of several types of genus 0 integrands;
+++ Author: Manuel Bronstein
+++ Date Created: 11 October 1988
+++ Date Last Updated: 24 June 1994
+++ Description:
+++ This internal package rationalises integrands on curves of the form:
+++ \spad{y\^2 = a x\^2 + b x + c}
+++ \spad{y\^2 = (a x + b) / (c x + d)}
+++ \spad{f(x, y) = 0} where f has degree 1 in x
+++ The rationalization is done for integration, limited integration,
+++ extended integration and the risch differential equation;
+GenusZeroIntegration(R, F, L): Exports == Implementation where
+ R: Join(GcdDomain, RetractableTo Integer, OrderedSet, CharacteristicZero,
+ LinearlyExplicitRingOver Integer)
+ F: Join(FunctionSpace R, AlgebraicallyClosedField,
+ TranscendentalFunctionCategory)
+ L: SetCategory
+
+ SY ==> Symbol
+ Q ==> Fraction Integer
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ UPUP ==> SparseUnivariatePolynomial RF
+ IR ==> IntegrationResult F
+ LOG ==> Record(coeff:F, logand:F)
+ U1 ==> Union(F, "failed")
+ U2 ==> Union(Record(ratpart:F, coeff:F),"failed")
+ U3 ==> Union(Record(mainpart:F, limitedlogs:List LOG), "failed")
+ REC ==> Record(coeff:F, var:List K, val:List F)
+ ODE ==> Record(particular: Union(F, "failed"), basis: List F)
+ LODO==> LinearOrdinaryDifferentialOperator1 RF
+
+ Exports ==> with
+ palgint0 : (F, K, K, F, UP) -> IR
+ ++ palgint0(f, x, y, d, p) returns the integral of \spad{f(x,y)dx}
+ ++ where y is an algebraic function of x satisfying
+ ++ \spad{d(x)\^2 y(x)\^2 = P(x)}.
+ palgint0 : (F, K, K, K, F, RF) -> IR
+ ++ palgint0(f, x, y, z, t, c) returns the integral of \spad{f(x,y)dx}
+ ++ where y is an algebraic function of x satisfying
+ ++ \spad{f(x,y)dx = c f(t,y) dy}; c and t are rational functions of y.
+ ++ Argument z is a dummy variable not appearing in \spad{f(x,y)}.
+ palgextint0: (F, K, K, F, F, UP) -> U2
+ ++ palgextint0(f, x, y, g, d, p) returns functions \spad{[h, c]} such
+ ++ that \spad{dh/dx = f(x,y) - c g}, where y is an algebraic function
+ ++ of x satisfying \spad{d(x)\^2 y(x)\^2 = P(x)},
+ ++ or "failed" if no such functions exist.
+ palgextint0: (F, K, K, F, K, F, RF) -> U2
+ ++ palgextint0(f, x, y, g, z, t, c) returns functions \spad{[h, d]} such
+ ++ that \spad{dh/dx = f(x,y) - d g}, where y is an algebraic function
+ ++ of x satisfying \spad{f(x,y)dx = c f(t,y) dy}, and c and t are rational
+ ++ functions of y.
+ ++ Argument z is a dummy variable not appearing in \spad{f(x,y)}.
+ ++ The operation returns "failed" if no such functions exist.
+ palglimint0: (F, K, K, List F, F, UP) -> U3
+ ++ palglimint0(f, x, y, [u1,...,un], d, p) returns functions
+ ++ \spad{[h,[[ci, ui]]]} such that the ui's are among \spad{[u1,...,un]}
+ ++ and \spad{d(h + sum(ci log(ui)))/dx = f(x,y)} if such functions exist,
+ ++ and "failed" otherwise.
+ ++ Argument y is an algebraic function of x satisfying
+ ++ \spad{d(x)\^2y(x)\^2 = P(x)}.
+ palglimint0: (F, K, K, List F, K, F, RF) -> U3
+ ++ palglimint0(f, x, y, [u1,...,un], z, t, c) returns functions
+ ++ \spad{[h,[[ci, ui]]]} such that the ui's are among \spad{[u1,...,un]}
+ ++ and \spad{d(h + sum(ci log(ui)))/dx = f(x,y)} if such functions exist,
+ ++ and "failed" otherwise.
+ ++ Argument y is an algebraic function of x satisfying
+ ++ \spad{f(x,y)dx = c f(t,y) dy}; c and t are rational functions of y.
+ palgRDE0 : (F, F, K, K, (F, F, SY) -> U1, F, UP) -> U1
+ ++ palgRDE0(f, g, x, y, foo, d, p) returns a function \spad{z(x,y)}
+ ++ such that \spad{dz/dx + n * df/dx z(x,y) = g(x,y)} if such a z exists,
+ ++ and "failed" otherwise.
+ ++ Argument y is an algebraic function of x satisfying
+ ++ \spad{d(x)\^2y(x)\^2 = P(x)}.
+ ++ Argument foo, called by \spad{foo(a, b, x)}, is a function that solves
+ ++ \spad{du/dx + n * da/dx u(x) = u(x)}
+ ++ for an unknown \spad{u(x)} not involving y.
+ palgRDE0 : (F, F, K, K, (F, F, SY) -> U1, K, F, RF) -> U1
+ ++ palgRDE0(f, g, x, y, foo, t, c) returns a function \spad{z(x,y)}
+ ++ such that \spad{dz/dx + n * df/dx z(x,y) = g(x,y)} if such a z exists,
+ ++ and "failed" otherwise.
+ ++ Argument y is an algebraic function of x satisfying
+ ++ \spad{f(x,y)dx = c f(t,y) dy}; c and t are rational functions of y.
+ ++ Argument \spad{foo}, called by \spad{foo(a, b, x)}, is a function that
+ ++ solves \spad{du/dx + n * da/dx u(x) = u(x)}
+ ++ for an unknown \spad{u(x)} not involving y.
+ univariate: (F, K, K, UP) -> UPUP
+ ++ univariate(f,k,k,p) \undocumented
+ multivariate: (UPUP, K, F) -> F
+ ++ multivariate(u,k,f) \undocumented
+ lift: (UP, K) -> UPUP
+ ++ lift(u,k) \undocumented
+ if L has LinearOrdinaryDifferentialOperatorCategory F then
+ palgLODE0 : (L, F, K, K, F, UP) -> ODE
+ ++ palgLODE0(op, g, x, y, d, p) returns the solution of \spad{op f = g}.
+ ++ Argument y is an algebraic function of x satisfying
+ ++ \spad{d(x)\^2y(x)\^2 = P(x)}.
+ palgLODE0 : (L, F, K, K, K, F, RF) -> ODE
+ ++ palgLODE0(op,g,x,y,z,t,c) returns the solution of \spad{op f = g}
+ ++ Argument y is an algebraic function of x satisfying
+ ++ \spad{f(x,y)dx = c f(t,y) dy}; c and t are rational functions of y.
+
+ Implementation ==> add
+ import RationalIntegration(F, UP)
+ import AlgebraicManipulations(R, F)
+ import IntegrationResultFunctions2(RF, F)
+ import ElementaryFunctionStructurePackage(R, F)
+ import SparseUnivariatePolynomialFunctions2(F, RF)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+ mkRat : (F, REC, List K) -> RF
+ mkRatlx : (F, K, K, F, K, RF) -> RF
+ quadsubst: (K, K, F, UP) -> Record(diff:F, subs:REC, newk:List K)
+ kerdiff : (F, F) -> List K
+ checkroot: (F, List K) -> F
+ univ : (F, List K, K) -> RF
+
+ dummy := kernel(new()$SY)@K
+
+ kerdiff(sa, a) == setDifference(kernels sa, kernels a)
+ checkroot(f, l) == (empty? l => f; rootNormalize(f, first l))
+ univ(c, l, x) == univariate(checkroot(c, l), x)
+ univariate(f, x, y, p) == lift(univariate(f, y, p), x)
+ lift(p, k) == map(univariate(#1, k), p)
+
+ palgint0(f, x, y, den, radi) ==
+ -- y is a square root so write f as f1 y + f0 and integrate separately
+ ff := univariate(f, x, y, minPoly y)
+ f0 := reductum ff
+ pr := quadsubst(x, y, den, radi)
+ map(#1(x::F), integrate(retract(f0)@RF)) +
+ map(#1(pr.diff),
+ integrate
+ mkRat(multivariate(leadingMonomial ff,x,y::F), pr.subs, pr.newk))
+
+-- the algebraic relation is (den * y)**2 = p where p is a * x**2 + b * x + c
+-- if p is squarefree, then parametrize in the following form:
+-- u = y - x \sqrt{a}
+-- x = (u^2 - c) / (b - 2 u \sqrt{a}) = h(u)
+-- dx = h'(u) du
+-- y = (u + a h(u)) / den = g(u)
+-- if a is a perfect square,
+-- u = (y - \sqrt{c}) / x
+-- x = (b - 2 u \sqrt{c}) / (u^2 - a) = h(u)
+-- dx = h'(u) du
+-- y = (u h(u) + \sqrt{c}) / den = g(u)
+-- otherwise.
+-- if p is a square p = a t^2, then we choose only one branch for now:
+-- u = x
+-- x = u = h(u)
+-- dx = du
+-- y = t \sqrt{a} / den = g(u)
+-- returns [u(x,y), [h'(u), [x,y], [h(u), g(u)], l] in both cases,
+-- where l is empty if no new square root was needed,
+-- l := [k] if k is the new square root kernel that was created.
+ quadsubst(x, y, den, p) ==
+ u := dummy::F
+ b := coefficient(p, 1)
+ c := coefficient(p, 0)
+ sa := rootSimp sqrt(a := coefficient(p, 2))
+ zero?(b * b - 4 * a * c) => -- case where p = a (x + b/(2a))^2
+ [x::F, [1, [x, y], [u, sa * (u + b / (2*a)) / eval(den,x,u)]], empty()]
+ empty? kerdiff(sa, a) =>
+ bm2u := b - 2 * u * sa
+ q := eval(den, x, xx := (u**2 - c) / bm2u)
+ yy := (ua := u + xx * sa) / q
+ [y::F - x::F * sa, [2 * ua / bm2u, [x, y], [xx, yy]], empty()]
+ u2ma:= u**2 - a
+ sc := rootSimp sqrt c
+ q := eval(den, x, xx := (b - 2 * u * sc) / u2ma)
+ yy := (ux := xx * u + sc) / q
+ [(y::F - sc) / x::F, [- 2 * ux / u2ma, [x ,y], [xx, yy]], kerdiff(sc, c)]
+
+ mkRatlx(f,x,y,t,z,dx) ==
+ rat := univariate(eval(f, [x, y], [t, z::F]), z) * dx
+ numer(rat) / denom(rat)
+
+ mkRat(f, rec, l) ==
+ rat:=univariate(checkroot(rec.coeff * eval(f,rec.var,rec.val), l), dummy)
+ numer(rat) / denom(rat)
+
+ palgint0(f, x, y, z, xx, dx) ==
+ map(multivariate(#1, y), integrate mkRatlx(f, x, y, xx, z, dx))
+
+ palgextint0(f, x, y, g, z, xx, dx) ==
+ map(multivariate(#1, y),
+ extendedint(mkRatlx(f,x,y,xx,z,dx), mkRatlx(g,x,y,xx,z,dx)))
+
+ palglimint0(f, x, y, lu, z, xx, dx) ==
+ map(multivariate(#1, y), limitedint(mkRatlx(f, x, y, xx, z, dx),
+ [mkRatlx(u, x, y, xx, z, dx) for u in lu]))
+
+ palgRDE0(f, g, x, y, rischde, z, xx, dx) ==
+ (u := rischde(eval(f, [x, y], [xx, z::F]),
+ multivariate(dx, z) * eval(g, [x, y], [xx, z::F]),
+ symbolIfCan(z)::SY)) case "failed" => "failed"
+ eval(u::F, z, y::F)
+
+-- given p = sum_i a_i(X) Y^i, returns sum_i a_i(x) y^i
+ multivariate(p, x, y) ==
+ (map(multivariate(#1, x),
+ p)$SparseUnivariatePolynomialFunctions2(RF, F))
+ (y)
+
+ palgextint0(f, x, y, g, den, radi) ==
+ pr := quadsubst(x, y, den, radi)
+ map(#1(pr.diff),
+ extendedint(mkRat(f, pr.subs, pr.newk), mkRat(g, pr.subs, pr.newk)))
+
+ palglimint0(f, x, y, lu, den, radi) ==
+ pr := quadsubst(x, y, den, radi)
+ map(#1(pr.diff),
+ limitedint(mkRat(f, pr.subs, pr.newk),
+ [mkRat(u, pr.subs, pr.newk) for u in lu]))
+
+ palgRDE0(f, g, x, y, rischde, den, radi) ==
+ pr := quadsubst(x, y, den, radi)
+ (u := rischde(checkroot(eval(f, pr.subs.var, pr.subs.val), pr.newk),
+ checkroot(pr.subs.coeff * eval(g, pr.subs.var, pr.subs.val),
+ pr.newk), symbolIfCan(dummy)::SY)) case "failed"
+ => "failed"
+ eval(u::F, dummy, pr.diff)
+
+ if L has LinearOrdinaryDifferentialOperatorCategory F then
+ import RationalLODE(F, UP)
+
+ palgLODE0(eq, g, x, y, den, radi) ==
+ pr := quadsubst(x, y, den, radi)
+ d := monomial(univ(inv(pr.subs.coeff), pr.newk, dummy), 1)$LODO
+ di:LODO := 1 -- will accumulate the powers of d
+ op:LODO := 0 -- will accumulate the new LODO
+ for i in 0..degree eq repeat
+ op := op + univ(eval(coefficient(eq, i), pr.subs.var, pr.subs.val),
+ pr.newk, dummy) * di
+ di := d * di
+ rec := ratDsolve(op,univ(eval(g,pr.subs.var,pr.subs.val),pr.newk,dummy))
+ bas:List(F) := [b(pr.diff) for b in rec.basis]
+ rec.particular case "failed" => ["failed", bas]
+ [((rec.particular)::RF) (pr.diff), bas]
+
+ palgLODE0(eq, g, x, y, kz, xx, dx) ==
+ d := monomial(univariate(inv multivariate(dx, kz), kz), 1)$LODO
+ di:LODO := 1 -- will accumulate the powers of d
+ op:LODO := 0 -- will accumulate the new LODO
+ lk:List(K) := [x, y]
+ lv:List(F) := [xx, kz::F]
+ for i in 0..degree eq repeat
+ op := op + univariate(eval(coefficient(eq, i), lk, lv), kz) * di
+ di := d * di
+ rec := ratDsolve(op, univariate(eval(g, lk, lv), kz))
+ bas:List(F) := [multivariate(b, y) for b in rec.basis]
+ rec.particular case "failed" => ["failed", bas]
+ [multivariate((rec.particular)::RF, y), bas]
+
+@
+\section{package INTPAF PureAlgebraicIntegration}
+<<package INTPAF PureAlgebraicIntegration>>=
+)abbrev package INTPAF PureAlgebraicIntegration
+++ Integration of pure algebraic functions;
+++ Author: Manuel Bronstein
+++ Date Created: 27 May 1988
+++ Date Last Updated: 24 June 1994
+++ Description:
+++ This package provides functions for integration, limited integration,
+++ extended integration and the risch differential equation for
+++ pure algebraic integrands;
+PureAlgebraicIntegration(R, F, L): Exports == Implementation where
+ R: Join(GcdDomain,RetractableTo Integer,OrderedSet, CharacteristicZero,
+ LinearlyExplicitRingOver Integer)
+ F: Join(FunctionSpace R, AlgebraicallyClosedField,
+ TranscendentalFunctionCategory)
+ L: SetCategory
+
+ SY ==> Symbol
+ N ==> NonNegativeInteger
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ UPUP==> SparseUnivariatePolynomial RF
+ IR ==> IntegrationResult F
+ IR2 ==> IntegrationResultFunctions2(curve, F)
+ ALG ==> AlgebraicIntegrate(R, F, UP, UPUP, curve)
+ LDALG ==> LinearOrdinaryDifferentialOperator1 curve
+ RDALG ==> PureAlgebraicLODE(F, UP, UPUP, curve)
+ LOG ==> Record(coeff:F, logand:F)
+ REC ==> Record(particular:U1, basis:List F)
+ CND ==> Record(left:UP, right:UP)
+ CHV ==> Record(int:UPUP, left:UP, right:UP, den:RF, deg:N)
+ U1 ==> Union(F, "failed")
+ U2 ==> Union(Record(ratpart:F, coeff:F),"failed")
+ U3 ==> Union(Record(mainpart:F, limitedlogs:List LOG), "failed")
+ FAIL==> error "failed - cannot handle that integrand"
+
+ Exports ==> with
+ palgint : (F, K, K) -> IR
+ ++ palgint(f, x, y) returns the integral of \spad{f(x,y)dx}
+ ++ where y is an algebraic function of x.
+ palgextint: (F, K, K, F) -> U2
+ ++ palgextint(f, x, y, g) returns functions \spad{[h, c]} such that
+ ++ \spad{dh/dx = f(x,y) - c g}, where y is an algebraic function of x;
+ ++ returns "failed" if no such functions exist.
+ palglimint: (F, K, K, List F) -> U3
+ ++ palglimint(f, x, y, [u1,...,un]) returns functions
+ ++ \spad{[h,[[ci, ui]]]} such that the ui's are among \spad{[u1,...,un]}
+ ++ and \spad{d(h + sum(ci log(ui)))/dx = f(x,y)} if such functions exist,
+ ++ "failed" otherwise;
+ ++ y is an algebraic function of x.
+ palgRDE : (F, F, F, K, K, (F, F, SY) -> U1) -> U1
+ ++ palgRDE(nfp, f, g, x, y, foo) returns a function \spad{z(x,y)}
+ ++ such that \spad{dz/dx + n * df/dx z(x,y) = g(x,y)} if such a z exists,
+ ++ "failed" otherwise;
+ ++ y is an algebraic function of x;
+ ++ \spad{foo(a, b, x)} is a function that solves
+ ++ \spad{du/dx + n * da/dx u(x) = u(x)}
+ ++ for an unknown \spad{u(x)} not involving y.
+ ++ \spad{nfp} is \spad{n * df/dx}.
+ if L has LinearOrdinaryDifferentialOperatorCategory F then
+ palgLODE: (L, F, K, K, SY) -> REC
+ ++ palgLODE(op, g, kx, y, x) returns the solution of \spad{op f = g}.
+ ++ y is an algebraic function of x.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import RationalIntegration(F, UP)
+ import GenusZeroIntegration(R, F, L)
+ import ChangeOfVariable(F, UP, UPUP)
+ import IntegrationResultFunctions2(F, F)
+ import IntegrationResultFunctions2(RF, F)
+ import SparseUnivariatePolynomialFunctions2(F, RF)
+ import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+ quadIfCan : (K, K) -> Union(Record(coef:F, poly:UP), "failed")
+ linearInXIfCan : (K, K) -> Union(Record(xsub:F, dxsub:RF), "failed")
+ prootintegrate : (F, K, K) -> IR
+ prootintegrate1: (UPUP, K, K, UPUP) -> IR
+ prootextint : (F, K, K, F) -> U2
+ prootlimint : (F, K, K, List F) -> U3
+ prootRDE : (F, F, F, K, K, (F, F, SY) -> U1) -> U1
+ palgRDE1 : (F, F, K, K) -> U1
+ palgLODE1 : (List F, F, K, K, SY) -> REC
+ palgintegrate : (F, K, K) -> IR
+ palgext : (F, K, K, F) -> U2
+ palglim : (F, K, K, List F) -> U3
+ UPUP2F1 : (UPUP, RF, RF, K, K) -> F
+ UPUP2F0 : (UPUP, K, K) -> F
+ RF2UPUP : (RF, UPUP) -> UPUP
+ algaddx : (IR, F) -> IR
+ chvarIfCan : (UPUP, RF, UP, RF) -> Union(UPUP, "failed")
+ changeVarIfCan : (UPUP, RF, N) -> Union(CHV, "failed")
+ rationalInt : (UPUP, N, UP) -> IntegrationResult RF
+ chv : (UPUP, N, F, F) -> RF
+ chv0 : (UPUP, N, F, F) -> F
+ candidates : UP -> List CND
+
+ dummy := new()$SY
+ dumk := kernel(dummy)@K
+
+ UPUP2F1(p, t, cf, kx, k) == UPUP2F0(eval(p, t, cf), kx, k)
+ UPUP2F0(p, kx, k) == multivariate(p, kx, k::F)
+ chv(f, n, a, b) == univariate(chv0(f, n, a, b), dumk)
+
+ RF2UPUP(f, modulus) ==
+ bc := extendedEuclidean(map(#1::UP::RF, denom f), modulus,
+ 1)::Record(coef1:UPUP, coef2:UPUP)
+ (map(#1::UP::RF, numer f) * bc.coef1) rem modulus
+
+-- returns "failed", or (xx, c) such that f(x, y)dx = f(xx, y) c dy
+-- if p(x, y) = 0 is linear in x
+ linearInXIfCan(x, y) ==
+ a := b := 0$UP
+ p := clearDenominator lift(minPoly y, x)
+ while p ^= 0 repeat
+ degree(q := numer leadingCoefficient p) > 1 => return "failed"
+ a := a + monomial(coefficient(q, 1), d := degree p)
+ b := b - monomial(coefficient(q, 0), d)
+ p := reductum p
+ xx:RF := b / a
+ [xx(dumk::F), differentiate(xx, differentiate)]
+
+-- return Int(f(x,y)dx) where y is an n^th root of a rational function in x
+ prootintegrate(f, x, y) ==
+ modulus := lift(p := minPoly y, x)
+ rf := reductum(ff := univariate(f, x, y, p))
+ ((r := retractIfCan(rf)@Union(RF,"failed")) case RF) and rf ^= 0 =>
+ -- in this case, ff := lc(ff) y^i + r so we integrate both terms
+ -- separately to gain time
+ map(#1(x::F), integrate(r::RF)) +
+ prootintegrate1(leadingMonomial ff, x, y, modulus)
+ prootintegrate1(ff, x, y, modulus)
+
+ prootintegrate1(ff, x, y, modulus) ==
+ chv:CHV
+ r := radPoly(modulus)::Record(radicand:RF, deg:N)
+ (uu := changeVarIfCan(ff, r.radicand, r.deg)) case CHV =>
+ chv := uu::CHV
+ newalg := nthRoot((chv.left)(dumk::F), chv.deg)
+ kz := retract(numer newalg)@K
+ newf := multivariate(chv.int, ku := dumk, newalg)
+ vu := (chv.right)(x::F)
+ vz := (chv.den)(x::F) * (y::F) * denom(newalg)::F
+ map(eval(#1, [ku, kz], [vu, vz]), palgint(newf, ku, kz))
+ cv := chvar(ff, modulus)
+ r := radPoly(cv.poly)::Record(radicand:RF, deg:N)
+ qprime := differentiate(q := retract(r.radicand)@UP)::RF
+ not zero? qprime and
+ ((u := chvarIfCan(cv.func, 1, q, inv qprime)) case UPUP) =>
+ m := monomial(1, r.deg)$UPUP - q::RF::UPUP
+ map(UPUP2F1(RF2UPUP(#1, m), cv.c1, cv.c2, x, y),
+ rationalInt(u::UPUP, r.deg, monomial(1, 1)))
+ curve := RadicalFunctionField(F, UP, UPUP, q::RF, r.deg)
+ algaddx(map(UPUP2F1(lift #1, cv.c1, cv.c2, x, y),
+ palgintegrate(reduce(cv.func), differentiate$UP)$ALG)$IR2, x::F)
+
+-- Do the rationalizing change of variable
+-- Int(f(x, y) dx) --> Int(n u^(n-1) f((u^n - b)/a, u) / a du) where
+-- u^n = y^n = g(x) = a x + b
+-- returns the integral as an integral of a rational function in u
+ rationalInt(f, n, g) ==
+-- not one? degree g => error "rationalInt: radicand must be linear"
+ not ((degree g) = 1) => error "rationalInt: radicand must be linear"
+ a := leadingCoefficient g
+ integrate(n * monomial(inv a, (n-1)::N)$UP
+ * chv(f, n, a, leadingCoefficient reductum g))
+
+-- Do the rationalizing change of variable f(x,y) --> f((u^n - b)/a, u) where
+-- u = y = (a x + b)^(1/n).
+-- Returns f((u^n - b)/a,u) as an element of F
+ chv0(f, n, a, b) ==
+ d := dumk::F
+ (f (d::UP::RF)) ((d ** n - b) / a)
+
+-- candidates(p) returns a list of pairs [g, u] such that p(x) = g(u(x)),
+-- those u's are candidates for change of variables
+-- currently uses a dumb heuristic where the candidates u's are p itself
+-- and all the powers x^2, x^3, ..., x^{deg(p)},
+-- will use polynomial decomposition in smarter days MB 8/93
+ candidates p ==
+ l:List(CND) := empty()
+ ground? p => l
+ for i in 2..degree p repeat
+ if (u := composite(p, xi := monomial(1, i))) case UP then
+ l := concat([u::UP, xi], l)
+ concat([monomial(1, 1), p], l)
+
+-- checks whether Int(p(x, y) dx) can be rewritten as
+-- Int(r(u, z) du) where u is some polynomial of x,
+-- z = d y for some polynomial d, and z^m = g(u)
+-- returns either [r(u, z), g, u, d, m] or "failed"
+-- we have y^n = radi
+ changeVarIfCan(p, radi, n) ==
+ rec := rootPoly(radi, n)
+ for cnd in candidates(rec.radicand) repeat
+ (u := chvarIfCan(p, rec.coef, cnd.right,
+ inv(differentiate(cnd.right)::RF))) case UPUP =>
+ return [u::UPUP, cnd.left, cnd.right, rec.coef, rec.exponent]
+ "failed"
+
+-- checks whether Int(p(x, y) dx) can be rewritten as
+-- Int(r(u, z) du) where u is some polynomial of x and z = d y
+-- we have y^n = a(x)/d(x)
+-- returns either "failed" or r(u, z)
+ chvarIfCan(p, d, u, u1) ==
+ ans:UPUP := 0
+ while p ^= 0 repeat
+ (v := composite(u1 * leadingCoefficient(p) / d ** degree(p), u))
+ case "failed" => return "failed"
+ ans := ans + monomial(v::RF, degree p)
+ p := reductum p
+ ans
+
+ algaddx(i, xx) ==
+ elem? i => i
+ mkAnswer(ratpart i, logpart i,
+ [[- ne.integrand / (xx**2), xx] for ne in notelem i])
+
+ prootRDE(nfp, f, g, x, k, rde) ==
+ modulus := lift(p := minPoly k, x)
+ r := radPoly(modulus)::Record(radicand:RF, deg:N)
+ rec := rootPoly(r.radicand, r.deg)
+ dqdx := inv(differentiate(q := rec.radicand)::RF)
+ ((uf := chvarIfCan(ff := univariate(f,x,k,p),rec.coef,q,1)) case UPUP) and
+ ((ug:=chvarIfCan(gg:=univariate(g,x,k,p),rec.coef,q,dqdx)) case UPUP) =>
+ (u := rde(chv0(uf::UPUP, rec.exponent, 1, 0), rec.exponent *
+ (dumk::F) ** (rec.exponent * (rec.exponent - 1))
+ * chv0(ug::UPUP, rec.exponent, 1, 0),
+ symbolIfCan(dumk)::SY)) case "failed" => "failed"
+ eval(u::F, dumk, k::F)
+-- one?(rec.coef) =>
+ ((rec.coef) = 1) =>
+ curve := RadicalFunctionField(F, UP, UPUP, q::RF, rec.exponent)
+ rc := algDsolve(D()$LDALG + reduce(univariate(nfp, x, k, p))::LDALG,
+ reduce univariate(g, x, k, p))$RDALG
+ rc.particular case "failed" => "failed"
+ UPUP2F0(lift((rc.particular)::curve), x, k)
+ palgRDE1(nfp, g, x, k)
+
+ prootlimint(f, x, k, lu) ==
+ modulus := lift(p := minPoly k, x)
+ r := radPoly(modulus)::Record(radicand:RF, deg:N)
+ rec := rootPoly(r.radicand, r.deg)
+ dqdx := inv(differentiate(q := rec.radicand)::RF)
+ (uf := chvarIfCan(ff := univariate(f,x,k,p),rec.coef,q,dqdx)) case UPUP =>
+ l := empty()$List(RF)
+ n := rec.exponent * monomial(1, (rec.exponent - 1)::N)$UP
+ for u in lu repeat
+ if ((v:=chvarIfCan(uu:=univariate(u,x,k,p),rec.coef,q,dqdx))case UPUP)
+ then l := concat(n * chv(v::UPUP,rec.exponent, 1, 0), l) else FAIL
+ m := monomial(1, rec.exponent)$UPUP - q::RF::UPUP
+ map(UPUP2F0(RF2UPUP(#1,m), x, k),
+ limitedint(n * chv(uf::UPUP, rec.exponent, 1, 0), reverse_! l))
+ cv := chvar(ff, modulus)
+ r := radPoly(cv.poly)::Record(radicand:RF, deg:N)
+ dqdx := inv(differentiate(q := retract(r.radicand)@UP)::RF)
+ curve := RadicalFunctionField(F, UP, UPUP, q::RF, r.deg)
+ (ui := palginfieldint(reduce(cv.func), differentiate$UP)$ALG)
+ case "failed" => FAIL
+ [UPUP2F1(lift(ui::curve), cv.c1, cv.c2, x, k), empty()]
+
+ prootextint(f, x, k, g) ==
+ modulus := lift(p := minPoly k, x)
+ r := radPoly(modulus)::Record(radicand:RF, deg:N)
+ rec := rootPoly(r.radicand, r.deg)
+ dqdx := inv(differentiate(q := rec.radicand)::RF)
+ ((uf:=chvarIfCan(ff:=univariate(f,x,k,p),rec.coef,q,dqdx)) case UPUP) and
+ ((ug:=chvarIfCan(gg:=univariate(g,x,k,p),rec.coef,q,dqdx)) case UPUP) =>
+ m := monomial(1, rec.exponent)$UPUP - q::RF::UPUP
+ n := rec.exponent * monomial(1, (rec.exponent - 1)::N)$UP
+ map(UPUP2F0(RF2UPUP(#1,m), x, k),
+ extendedint(n * chv(uf::UPUP, rec.exponent, 1, 0),
+ n * chv(ug::UPUP, rec.exponent, 1, 0)))
+ cv := chvar(ff, modulus)
+ r := radPoly(cv.poly)::Record(radicand:RF, deg:N)
+ dqdx := inv(differentiate(q := retract(r.radicand)@UP)::RF)
+ curve := RadicalFunctionField(F, UP, UPUP, q::RF, r.deg)
+ (u := palginfieldint(reduce(cv.func), differentiate$UP)$ALG)
+ case "failed" => FAIL
+ [UPUP2F1(lift(u::curve), cv.c1, cv.c2, x, k), 0]
+
+ palgRDE1(nfp, g, x, y) ==
+ palgLODE1([nfp, 1], g, x, y, symbolIfCan(x)::SY).particular
+
+ palgLODE1(eq, g, kx, y, x) ==
+ modulus:= lift(p := minPoly y, kx)
+ curve := AlgebraicFunctionField(F, UP, UPUP, modulus)
+ neq:LDALG := 0
+ for f in eq for i in 0.. repeat
+ neq := neq + monomial(reduce univariate(f, kx, y, p), i)
+ empty? remove_!(y, remove_!(kx, varselect(kernels g, x))) =>
+ rec := algDsolve(neq, reduce univariate(g, kx, y, p))$RDALG
+ bas:List(F) := [UPUP2F0(lift h, kx, y) for h in rec.basis]
+ rec.particular case "failed" => ["failed", bas]
+ [UPUP2F0(lift((rec.particular)::curve), kx, y), bas]
+ rec := algDsolve(neq, 0)
+ ["failed", [UPUP2F0(lift h, kx, y) for h in rec.basis]]
+
+ palgintegrate(f, x, k) ==
+ modulus:= lift(p := minPoly k, x)
+ cv := chvar(univariate(f, x, k, p), modulus)
+ curve := AlgebraicFunctionField(F, UP, UPUP, cv.poly)
+ knownInfBasis(cv.deg)
+ algaddx(map(UPUP2F1(lift #1, cv.c1, cv.c2, x, k),
+ palgintegrate(reduce(cv.func), differentiate$UP)$ALG)$IR2, x::F)
+
+ palglim(f, x, k, lu) ==
+ modulus:= lift(p := minPoly k, x)
+ cv := chvar(univariate(f, x, k, p), modulus)
+ curve := AlgebraicFunctionField(F, UP, UPUP, cv.poly)
+ knownInfBasis(cv.deg)
+ (u := palginfieldint(reduce(cv.func), differentiate$UP)$ALG)
+ case "failed" => FAIL
+ [UPUP2F1(lift(u::curve), cv.c1, cv.c2, x, k), empty()]
+
+ palgext(f, x, k, g) ==
+ modulus:= lift(p := minPoly k, x)
+ cv := chvar(univariate(f, x, k, p), modulus)
+ curve := AlgebraicFunctionField(F, UP, UPUP, cv.poly)
+ knownInfBasis(cv.deg)
+ (u := palginfieldint(reduce(cv.func), differentiate$UP)$ALG)
+ case "failed" => FAIL
+ [UPUP2F1(lift(u::curve), cv.c1, cv.c2, x, k), 0]
+
+ palgint(f, x, y) ==
+ (v := linearInXIfCan(x, y)) case "failed" =>
+ (u := quadIfCan(x, y)) case "failed" =>
+ is?(y, "nthRoot"::SY) => prootintegrate(f, x, y)
+ is?(y, "rootOf"::SY) => palgintegrate(f, x, y)
+ FAIL
+ palgint0(f, x, y, u.coef, u.poly)
+ palgint0(f, x, y, dumk, v.xsub, v.dxsub)
+
+ palgextint(f, x, y, g) ==
+ (v := linearInXIfCan(x, y)) case "failed" =>
+ (u := quadIfCan(x, y)) case "failed" =>
+ is?(y, "nthRoot"::SY) => prootextint(f, x, y, g)
+ is?(y, "rootOf"::SY) => palgext(f, x, y, g)
+ FAIL
+ palgextint0(f, x, y, g, u.coef, u.poly)
+ palgextint0(f, x, y, g, dumk, v.xsub, v.dxsub)
+
+ palglimint(f, x, y, lu) ==
+ (v := linearInXIfCan(x, y)) case "failed" =>
+ (u := quadIfCan(x, y)) case "failed" =>
+ is?(y, "nthRoot"::SY) => prootlimint(f, x, y, lu)
+ is?(y, "rootOf"::SY) => palglim(f, x, y, lu)
+ FAIL
+ palglimint0(f, x, y, lu, u.coef, u.poly)
+ palglimint0(f, x, y, lu, dumk, v.xsub, v.dxsub)
+
+ palgRDE(nfp, f, g, x, y, rde) ==
+ (v := linearInXIfCan(x, y)) case "failed" =>
+ (u := quadIfCan(x, y)) case "failed" =>
+ is?(y, "nthRoot"::SY) => prootRDE(nfp, f, g, x, y, rde)
+ palgRDE1(nfp, g, x, y)
+ palgRDE0(f, g, x, y, rde, u.coef, u.poly)
+ palgRDE0(f, g, x, y, rde, dumk, v.xsub, v.dxsub)
+
+ -- returns "failed", or (d, P) such that (dy)**2 = P(x)
+ -- and degree(P) = 2
+ quadIfCan(x, y) ==
+ (degree(p := minPoly y) = 2) and zero?(coefficient(p, 1)) =>
+ d := denom(ff :=
+ univariate(- coefficient(p, 0) / coefficient(p, 2), x))
+ degree(radi := d * numer ff) = 2 => [d(x::F), radi]
+ "failed"
+ "failed"
+
+ if L has LinearOrdinaryDifferentialOperatorCategory F then
+ palgLODE(eq, g, kx, y, x) ==
+ (v := linearInXIfCan(kx, y)) case "failed" =>
+ (u := quadIfCan(kx, y)) case "failed" =>
+ palgLODE1([coefficient(eq, i) for i in 0..degree eq], g, kx, y, x)
+ palgLODE0(eq, g, kx, y, u.coef, u.poly)
+ palgLODE0(eq, g, kx, y, dumk, v.xsub, v.dxsub)
+
+@
+\section{package INTAF AlgebraicIntegration}
+<<package INTAF AlgebraicIntegration>>=
+)abbrev package INTAF AlgebraicIntegration
+++ Mixed algebraic integration;
+++ Author: Manuel Bronstein
+++ Date Created: 12 October 1988
+++ Date Last Updated: 4 June 1988
+++ Description:
+++ This package provides functions for the integration of
+++ algebraic integrands over transcendental functions;
+AlgebraicIntegration(R, F): Exports == Implementation where
+ R : Join(OrderedSet, IntegralDomain)
+ F : Join(AlgebraicallyClosedField, FunctionSpace R)
+
+ SY ==> Symbol
+ N ==> NonNegativeInteger
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ UPUP==> SparseUnivariatePolynomial RF
+ IR ==> IntegrationResult F
+ IR2 ==> IntegrationResultFunctions2(curve, F)
+ ALG ==> AlgebraicIntegrate(R, F, UP, UPUP, curve)
+ FAIL==> error "failed - cannot handle that integrand"
+
+ Exports ==> with
+ algint: (F, K, K, UP -> UP) -> IR
+ ++ algint(f, x, y, d) returns the integral of \spad{f(x,y)dx}
+ ++ where y is an algebraic function of x;
+ ++ d is the derivation to use on \spad{k[x]}.
+
+ Implementation ==> add
+ import ChangeOfVariable(F, UP, UPUP)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+ rootintegrate: (F, K, K, UP -> UP) -> IR
+ algintegrate : (F, K, K, UP -> UP) -> IR
+ UPUP2F : (UPUP, RF, K, K) -> F
+ F2UPUP : (F, K, K, UP) -> UPUP
+ UP2UPUP : (UP, K) -> UPUP
+
+ F2UPUP(f, kx, k, p) == UP2UPUP(univariate(f, k, p), kx)
+
+ rootintegrate(f, t, k, derivation) ==
+ r1 := mkIntegral(modulus := UP2UPUP(p := minPoly k, t))
+ f1 := F2UPUP(f, t, k, p) monomial(inv(r1.coef), 1)
+ r := radPoly(r1.poly)::Record(radicand:RF, deg:N)
+ q := retract(r.radicand)
+ curve := RadicalFunctionField(F, UP, UPUP, q::RF, r.deg)
+ map(UPUP2F(lift #1, r1.coef, t, k),
+ algintegrate(reduce f1, derivation)$ALG)$IR2
+
+ algintegrate(f, t, k, derivation) ==
+ r1 := mkIntegral(modulus := UP2UPUP(p := minPoly k, t))
+ f1 := F2UPUP(f, t, k, p) monomial(inv(r1.coef), 1)
+ modulus:= UP2UPUP(p := minPoly k, t)
+ curve := AlgebraicFunctionField(F, UP, UPUP, r1.poly)
+ map(UPUP2F(lift #1, r1.coef, t, k),
+ algintegrate(reduce f1, derivation)$ALG)$IR2
+
+ UP2UPUP(p, k) ==
+ map(univariate(#1,k),p)$SparseUnivariatePolynomialFunctions2(F,RF)
+
+ UPUP2F(p, cf, t, k) ==
+ map(multivariate(#1, t),
+ p)$SparseUnivariatePolynomialFunctions2(RF, F)
+ (multivariate(cf, t) * k::F)
+
+ algint(f, t, y, derivation) ==
+ is?(y, "nthRoot"::SY) => rootintegrate(f, t, y, derivation)
+ is?(y, "rootOf"::SY) => algintegrate(f, t, y, derivation)
+ FAIL
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg INTAF efstruc rdeef intef irexpand integrat
+
+<<package INTG0 GenusZeroIntegration>>
+<<package INTPAF PureAlgebraicIntegration>>
+<<package INTAF AlgebraicIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intalg.spad.pamphlet b/src/algebra/intalg.spad.pamphlet
new file mode 100644
index 00000000..a08b41fa
--- /dev/null
+++ b/src/algebra/intalg.spad.pamphlet
@@ -0,0 +1,488 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intalg.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DBLRESP DoubleResultantPackage}
+<<package DBLRESP DoubleResultantPackage>>=
+)abbrev package DBLRESP DoubleResultantPackage
+++ Residue resultant
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 12 July 1990
+++ Description:
+++ This package provides functions for computing the residues
+++ of a function on an algebraic curve.
+DoubleResultantPackage(F, UP, UPUP, R): Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ RF ==> Fraction UP
+ UP2 ==> SparseUnivariatePolynomial UP
+ UP3 ==> SparseUnivariatePolynomial UP2
+
+ Exports ==> with
+ doubleResultant: (R, UP -> UP) -> UP
+ ++ doubleResultant(f, ') returns p(x) whose roots are
+ ++ rational multiples of the residues of f at all its
+ ++ finite poles. Argument ' is the derivation to use.
+
+ Implementation ==> add
+ import CommuteUnivariatePolynomialCategory(F, UP, UP2)
+ import UnivariatePolynomialCommonDenominator(UP, RF, UPUP)
+
+ UP22 : UP -> UP2
+ UP23 : UPUP -> UP3
+ remove0: UP -> UP -- removes the power of x dividing p
+
+ remove0 p ==
+ primitivePart((p exquo monomial(1, minimumDegree p))::UP)
+
+ UP22 p ==
+ map(#1::UP, p)$UnivariatePolynomialCategoryFunctions2(F,UP,UP,UP2)
+
+ UP23 p ==
+ map(UP22(retract(#1)@UP),
+ p)$UnivariatePolynomialCategoryFunctions2(RF, UPUP, UP2, UP3)
+
+ doubleResultant(h, derivation) ==
+ cd := splitDenominator lift h
+ d := (cd.den exquo (g := gcd(cd.den, derivation(cd.den))))::UP
+ r := swap primitivePart swap resultant(UP23(cd.num)
+ - ((monomial(1, 1)$UP :: UP2) * UP22(g * derivation d))::UP3,
+ UP23 definingPolynomial())
+ remove0 resultant(r, UP22 d)
+
+@
+\section{package INTHERAL AlgebraicHermiteIntegration}
+<<package INTHERAL AlgebraicHermiteIntegration>>=
+)abbrev package INTHERAL AlgebraicHermiteIntegration
+++ Hermite integration, algebraic case
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 25 July 1990
+++ Description: algebraic Hermite redution.
+AlgebraicHermiteIntegration(F,UP,UPUP,R):Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ N ==> NonNegativeInteger
+ RF ==> Fraction UP
+
+ Exports ==> with
+ HermiteIntegrate: (R, UP -> UP) -> Record(answer:R, logpart:R)
+ ++ HermiteIntegrate(f, ') returns \spad{[g,h]} such that
+ ++ \spad{f = g' + h} and h has a only simple finite normal poles.
+
+ Implementation ==> add
+ localsolve: (Matrix UP, Vector UP, UP) -> Vector UP
+
+-- the denominator of f should have no prime factor P s.t. P | P'
+-- (which happens only for P = t in the exponential case)
+ HermiteIntegrate(f, derivation) ==
+ ratform:R := 0
+ n := rank()
+ m := transpose((mat:= integralDerivationMatrix derivation).num)
+ inum := (cform := integralCoordinates f).num
+ if ((iden := cform.den) exquo (e := mat.den)) case "failed" then
+ iden := (coef := (e exquo gcd(e, iden))::UP) * iden
+ inum := coef * inum
+ for trm in factors squareFree iden | (j:= trm.exponent) > 1 repeat
+ u':=(u:=(iden exquo (v:=trm.factor)**(j::N))::UP) * derivation v
+ sys := ((u * v) exquo e)::UP * m
+ nn := minRowIndex sys - minIndex inum
+ while j > 1 repeat
+ j := j - 1
+ p := - j * u'
+ sol := localsolve(sys + scalarMatrix(n, p), inum, v)
+ ratform := ratform + integralRepresents(sol, v ** (j::N))
+ inum := [((qelt(inum, i) - p * qelt(sol, i) -
+ dot(row(sys, i - nn), sol))
+ exquo v)::UP - u * derivation qelt(sol, i)
+ for i in minIndex inum .. maxIndex inum]
+ iden := u * v
+ [ratform, integralRepresents(inum, iden)]
+
+ localsolve(mat, vec, modulus) ==
+ ans:Vector(UP) := new(nrows mat, 0)
+ diagonal? mat =>
+ for i in minIndex ans .. maxIndex ans
+ for j in minRowIndex mat .. maxRowIndex mat
+ for k in minColIndex mat .. maxColIndex mat repeat
+ (bc := extendedEuclidean(qelt(mat, j, k), modulus,
+ qelt(vec, i))) case "failed" => return new(0, 0)
+ qsetelt_!(ans, i, bc.coef1)
+ ans
+ sol := particularSolution(map(#1::RF, mat)$MatrixCategoryFunctions2(UP,
+ Vector UP, Vector UP, Matrix UP, RF,
+ Vector RF, Vector RF, Matrix RF),
+ map(#1::RF, vec)$VectorFunctions2(UP,
+ RF))$LinearSystemMatrixPackage(RF,
+ Vector RF, Vector RF, Matrix RF)
+ sol case "failed" => new(0, 0)
+ for i in minIndex ans .. maxIndex ans repeat
+ (bc := extendedEuclidean(denom qelt(sol, i), modulus, 1))
+ case "failed" => return new(0, 0)
+ qsetelt_!(ans, i, (numer qelt(sol, i) * bc.coef1) rem modulus)
+ ans
+
+@
+\section{package INTALG AlgebraicIntegrate}
+<<package INTALG AlgebraicIntegrate>>=
+)abbrev package INTALG AlgebraicIntegrate
+++ Integration of an algebraic function
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 19 May 1993
+++ Description:
+++ This package provides functions for integrating a function
+++ on an algebraic curve.
+AlgebraicIntegrate(R0, F, UP, UPUP, R): Exports == Implementation where
+ R0 : Join(OrderedSet, IntegralDomain, RetractableTo Integer)
+ F : Join(AlgebraicallyClosedField, FunctionSpace R0)
+ UP : UnivariatePolynomialCategory F
+ UPUP : UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ SE ==> Symbol
+ Z ==> Integer
+ Q ==> Fraction Z
+ SUP ==> SparseUnivariatePolynomial F
+ QF ==> Fraction UP
+ GP ==> LaurentPolynomial(F, UP)
+ K ==> Kernel F
+ IR ==> IntegrationResult R
+ UPQ ==> SparseUnivariatePolynomial Q
+ UPR ==> SparseUnivariatePolynomial R
+ FRQ ==> Factored UPQ
+ FD ==> FiniteDivisor(F, UP, UPUP, R)
+ FAC ==> Record(factor:UPQ, exponent:Z)
+ LOG ==> Record(scalar:Q, coeff:UPR, logand:UPR)
+ DIV ==> Record(num:R, den:UP, derivden:UP, gd:UP)
+ FAIL0 ==> error "integrate: implementation incomplete (constant residues)"
+ FAIL1==> error "integrate: implementation incomplete (non-algebraic residues)"
+ FAIL2 ==> error "integrate: implementation incomplete (residue poly has multiple non-linear factors)"
+ FAIL3 ==> error "integrate: implementation incomplete (has polynomial part)"
+ NOTI ==> error "Not integrable (provided residues have no relations)"
+
+ Exports ==> with
+ algintegrate : (R, UP -> UP) -> IR
+ ++ algintegrate(f, d) integrates f with respect to the derivation d.
+ palgintegrate : (R, UP -> UP) -> IR
+ ++ palgintegrate(f, d) integrates f with respect to the derivation d.
+ ++ Argument f must be a pure algebraic function.
+ palginfieldint: (R, UP -> UP) -> Union(R, "failed")
+ ++ palginfieldint(f, d) returns an algebraic function g
+ ++ such that \spad{dg = f} if such a g exists, "failed" otherwise.
+ ++ Argument f must be a pure algebraic function.
+
+ Implementation ==> add
+ import FD
+ import DoubleResultantPackage(F, UP, UPUP, R)
+ import PointsOfFiniteOrder(R0, F, UP, UPUP, R)
+ import AlgebraicHermiteIntegration(F, UP, UPUP, R)
+ import InnerCommonDenominator(Z, Q, List Z, List Q)
+ import FunctionSpaceUnivariatePolynomialFactor(R0, F, UP)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R0, SparseMultivariatePolynomial(R0, K), F)
+
+ F2R : F -> R
+ F2UPR : F -> UPR
+ UP2SUP : UP -> SUP
+ SUP2UP : SUP -> UP
+ UPQ2F : UPQ -> UP
+ univ : (F, K) -> QF
+ pLogDeriv : (LOG, R -> R) -> R
+ nonLinear : List FAC -> Union(FAC, "failed")
+ mkLog : (UP, Q, R, F) -> List LOG
+ R2UP : (R, K) -> UPR
+ alglogint : (R, UP -> UP) -> Union(List LOG, "failed")
+ palglogint : (R, UP -> UP) -> Union(List LOG, "failed")
+ trace00 : (DIV, UP, List LOG) -> Union(List LOG,"failed")
+ trace0 : (DIV, UP, Q, FD) -> Union(List LOG, "failed")
+ trace1 : (DIV, UP, List Q, List FD, Q) -> Union(List LOG, "failed")
+ nonQ : (DIV, UP) -> Union(List LOG, "failed")
+ rlift : (F, K, K) -> R
+ varRoot? : (UP, F -> F) -> Boolean
+ algintexp : (R, UP -> UP) -> IR
+ algintprim : (R, UP -> UP) -> IR
+
+ dummy:R := 0
+
+ dumx := kernel(new()$SE)$K
+ dumy := kernel(new()$SE)$K
+
+ F2UPR f == F2R(f)::UPR
+ F2R f == f::UP::QF::R
+
+ algintexp(f, derivation) ==
+ d := (c := integralCoordinates f).den
+ v := c.num
+ vp:Vector(GP) := new(n := #v, 0)
+ vf:Vector(QF) := new(n, 0)
+ for i in minIndex v .. maxIndex v repeat
+ r := separate(qelt(v, i) / d)$GP
+ qsetelt_!(vf, i, r.fracPart)
+ qsetelt_!(vp, i, r.polyPart)
+ ff := represents(vf, w := integralBasis())
+ h := HermiteIntegrate(ff, derivation)
+ p := represents(map(convert(#1)@QF, vp)$VectorFunctions2(GP, QF), w)
+ zero?(h.logpart) and zero? p => h.answer::IR
+ (u := alglogint(h.logpart, derivation)) case "failed" =>
+ mkAnswer(h.answer, empty(), [[p + h.logpart, dummy]])
+ zero? p => mkAnswer(h.answer, u::List(LOG), empty())
+ FAIL3
+
+ algintprim(f, derivation) ==
+ h := HermiteIntegrate(f, derivation)
+ zero?(h.logpart) => h.answer::IR
+ (u := alglogint(h.logpart, derivation)) case "failed" =>
+ mkAnswer(h.answer, empty(), [[h.logpart, dummy]])
+ mkAnswer(h.answer, u::List(LOG), empty())
+
+ -- checks whether f = +/[ci (ui)'/(ui)]
+ -- f dx must have no pole at infinity
+ palglogint(f, derivation) ==
+ rec := algSplitSimple(f, derivation)
+ ground?(r := doubleResultant(f, derivation)) => "failed"
+-- r(z) has roots which are the residues of f at all its poles
+ (u := qfactor r) case "failed" => nonQ(rec, r)
+ (fc := nonLinear(lf := factors(u::FRQ))) case "failed" => FAIL2
+-- at this point r(z) = fc(z) (z - b1)^e1 .. (z - bk)^ek
+-- where the ri's are rational numbers, and fc(z) is arbitrary
+-- (fc can be linear too)
+-- la = [b1....,bk] (all rational residues)
+ la := [- coefficient(q.factor, 0) for q in remove_!(fc::FAC, lf)]
+-- ld = [D1,...,Dk] where Di is the sum of places where f has residue bi
+ ld := [divisor(rec.num, rec.den, rec.derivden, rec.gd, b::F) for b in la]
+ pp := UPQ2F(fc.factor)
+-- bb = - sum of all the roots of fc (i.e. the other residues)
+ zero?(bb := coefficient(fc.factor,
+ (degree(fc.factor) - 1)::NonNegativeInteger)) =>
+ -- cd = [[a1,...,ak], d] such that bi = ai/d
+ cd := splitDenominator la
+ -- g = gcd(a1,...,ak), so bi = (g/d) ci with ci = bi / g
+ -- so [g/d] is a basis for [a1,...,ak] over the integers
+ g := gcd(cd.num)
+ -- dv0 is the divisor +/[ci Di] corresponding to all the residues
+ -- of f except the ones which are root of fc(z)
+ dv0 := +/[(a quo g) * dv for a in cd.num for dv in ld]
+ trace0(rec, pp, g / cd.den, dv0)
+ trace1(rec, pp, la, ld, bb)
+
+
+ UPQ2F p ==
+ map(#1::F, p)$UnivariatePolynomialCategoryFunctions2(Q,UPQ,F,UP)
+
+ UP2SUP p ==
+ map(#1, p)$UnivariatePolynomialCategoryFunctions2(F, UP, F, SUP)
+
+ SUP2UP p ==
+ map(#1, p)$UnivariatePolynomialCategoryFunctions2(F, SUP, F, UP)
+
+ varRoot?(p, derivation) ==
+ for c in coefficients primitivePart p repeat
+ derivation(c) ^= 0 => return true
+ false
+
+ pLogDeriv(log, derivation) ==
+ map(derivation, log.coeff) ^= 0 =>
+ error "can only handle logs with constant coefficients"
+-- one?(n := degree(log.coeff)) =>
+ ((n := degree(log.coeff)) = 1) =>
+ c := - (leadingCoefficient reductum log.coeff)
+ / (leadingCoefficient log.coeff)
+ ans := (log.logand) c
+ (log.scalar)::R * c * derivation(ans) / ans
+ numlog := map(derivation, log.logand)
+ (diflog := extendedEuclidean(log.logand, log.coeff, numlog)) case
+ "failed" => error "this shouldn't happen"
+ algans := diflog.coef1
+ ans:R := 0
+ for i in 0..n-1 repeat
+ algans := (algans * monomial(1, 1)) rem log.coeff
+ ans := ans + coefficient(algans, i)
+ (log.scalar)::R * ans
+
+ R2UP(f, k) ==
+ x := dumx :: F
+ g := (map(#1 x, lift f)$UnivariatePolynomialCategoryFunctions2(QF,
+ UPUP, F, UP)) (y := dumy::F)
+ map(rlift(#1, dumx, dumy), univariate(g, k,
+ minPoly k))$UnivariatePolynomialCategoryFunctions2(F,SUP,R,UPR)
+
+ univ(f, k) ==
+ g := univariate(f, k)
+ (SUP2UP numer g) / (SUP2UP denom g)
+
+ rlift(f, kx, ky) ==
+ reduce map(univ(#1, kx), retract(univariate(f,
+ ky))@SUP)$UnivariatePolynomialCategoryFunctions2(F,SUP,QF,UPUP)
+
+ nonQ(rec, p) ==
+ empty? rest(lf := factors ffactor primitivePart p) =>
+ trace00(rec, first(lf).factor, empty()$List(LOG))
+ FAIL1
+
+-- case when the irreducible factor p has roots which sum to 0
+-- p is assumed doubly transitive for now
+ trace0(rec, q, r, dv0) ==
+ lg:List(LOG) :=
+ zero? dv0 => empty()
+ (rc0 := torsionIfCan dv0) case "failed" => NOTI
+ mkLog(1, r / (rc0.order::Q), rc0.function, 1)
+ trace00(rec, q, lg)
+
+ trace00(rec, pp, lg) ==
+ p0 := divisor(rec.num, rec.den, rec.derivden, rec.gd,
+ alpha0 := zeroOf UP2SUP pp)
+ q := (pp exquo (monomial(1, 1)$UP - alpha0::UP))::UP
+ alpha := rootOf UP2SUP q
+ dvr := divisor(rec.num, rec.den, rec.derivden, rec.gd, alpha) - p0
+ (rc := torsionIfCan dvr) case "failed" =>
+ degree(pp) <= 2 => "failed"
+ NOTI
+ concat(lg, mkLog(q, inv(rc.order::Q), rc.function, alpha))
+
+-- case when the irreducible factor p has roots which sum <> 0
+-- the residues of f are of the form [a1,...,ak] rational numbers
+-- plus all the roots of q(z), which is squarefree
+-- la is the list of residues la := [a1,...,ak]
+-- ld is the list of divisors [D1,...Dk] where Di is the sum of all the
+-- places where f has residue ai
+-- q(z) is assumed doubly transitive for now.
+-- let [alpha_1,...,alpha_m] be the roots of q(z)
+-- in this function, b = - alpha_1 - ... - alpha_m is <> 0
+-- which implies only one generic log term
+ trace1(rec, q, la, ld, b) ==
+-- cd = [[b1,...,bk], d] such that ai / b = bi / d
+ cd := splitDenominator [a / b for a in la]
+-- then, a basis for all the residues of f over the integers is
+-- [beta_1 = - alpha_1 / d,..., beta_m = - alpha_m / d], since:
+-- alpha_i = - d beta_i
+-- ai = (ai / b) * b = (bi / d) * b = b1 * beta_1 + ... + bm * beta_m
+-- linear independence is a consequence of the doubly transitive assumption
+-- v0 is the divisor +/[bi Di] corresponding to the residues [a1,...,ak]
+ v0 := +/[a * dv for a in cd.num for dv in ld]
+-- alpha is a generic root of q(z)
+ alpha := rootOf UP2SUP q
+-- v is the divisor corresponding to all the residues
+ v := v0 - cd.den * divisor(rec.num, rec.den, rec.derivden, rec.gd, alpha)
+ (rc := torsionIfCan v) case "failed" => -- non-torsion case
+ degree(q) <= 2 => "failed" -- guaranteed doubly-transitive
+ NOTI -- maybe doubly-transitive
+ mkLog(q, inv((- rc.order * cd.den)::Q), rc.function, alpha)
+
+ mkLog(q, scalr, lgd, alpha) ==
+ degree(q) <= 1 =>
+ [[scalr, monomial(1, 1)$UPR - F2UPR alpha, lgd::UPR]]
+ [[scalr,
+ map(F2R, q)$UnivariatePolynomialCategoryFunctions2(F,UP,R,UPR),
+ R2UP(lgd, retract(alpha)@K)]]
+
+-- return the non-linear factor, if unique
+-- or any linear factor if they are all linear
+ nonLinear l ==
+ found:Boolean := false
+ ans := first l
+ for q in l repeat
+ if degree(q.factor) > 1 then
+ found => return "failed"
+ found := true
+ ans := q
+ ans
+
+-- f dx must be locally integral at infinity
+ palginfieldint(f, derivation) ==
+ h := HermiteIntegrate(f, derivation)
+ zero?(h.logpart) => h.answer
+ "failed"
+
+-- f dx must be locally integral at infinity
+ palgintegrate(f, derivation) ==
+ h := HermiteIntegrate(f, derivation)
+ zero?(h.logpart) => h.answer::IR
+ (not integralAtInfinity?(h.logpart)) or
+ ((u := palglogint(h.logpart, derivation)) case "failed") =>
+ mkAnswer(h.answer, empty(), [[h.logpart, dummy]])
+ zero?(difFirstKind := h.logpart - +/[pLogDeriv(lg,
+ differentiate(#1, derivation)) for lg in u::List(LOG)]) =>
+ mkAnswer(h.answer, u::List(LOG), empty())
+ mkAnswer(h.answer, u::List(LOG), [[difFirstKind, dummy]])
+
+-- for mixed functions. f dx not assumed locally integral at infinity
+ algintegrate(f, derivation) ==
+ zero? degree(x' := derivation(x := monomial(1, 1)$UP)) =>
+ algintprim(f, derivation)
+ ((xx := x' exquo x) case UP) and
+ (retractIfCan(xx::UP)@Union(F, "failed") case F) =>
+ algintexp(f, derivation)
+ error "should not happen"
+
+ alglogint(f, derivation) ==
+ varRoot?(doubleResultant(f, derivation),
+ retract(derivation(#1::UP))@F) => "failed"
+ FAIL0
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- INTALG intaf efstruc rdeef intef irexpand integrat
+
+<<package DBLRESP DoubleResultantPackage>>
+<<package INTHERAL AlgebraicHermiteIntegration>>
+<<package INTALG AlgebraicIntegrate>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intaux.spad.pamphlet b/src/algebra/intaux.spad.pamphlet
new file mode 100644
index 00000000..d8d3493f
--- /dev/null
+++ b/src/algebra/intaux.spad.pamphlet
@@ -0,0 +1,299 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intaux.spad}
+\author{Barry Trager, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain IR IntegrationResult}
+<<domain IR IntegrationResult>>=
+)abbrev domain IR IntegrationResult
+++ The result of a transcendental integration.
+++ Author: Barry Trager, Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 12 August 1992
+++ Description:
+++ If a function f has an elementary integral g, then g can be written
+++ in the form \spad{g = h + c1 log(u1) + c2 log(u2) + ... + cn log(un)}
+++ where h, which is in the same field than f, is called the rational
+++ part of the integral, and \spad{c1 log(u1) + ... cn log(un)} is called the
+++ logarithmic part of the integral. This domain manipulates integrals
+++ represented in that form, by keeping both parts separately. The logs
+++ are not explicitly computed.
+++ Keywords: integration.
+++ Examples: )r RATINT INPUT
+IntegrationResult(F:Field): Exports == Implementation where
+ O ==> OutputForm
+ B ==> Boolean
+ Z ==> Integer
+ Q ==> Fraction Integer
+ SE ==> Symbol
+ UP ==> SparseUnivariatePolynomial F
+ LOG ==> Record(scalar:Q, coeff:UP, logand:UP)
+ NE ==> Record(integrand:F, intvar:F)
+
+ Exports ==> (Module Q, RetractableTo F) with
+ mkAnswer: (F, List LOG, List NE) -> %
+ ++ mkAnswer(r,l,ne) creates an integration result from
+ ++ a rational part r, a logarithmic part l, and a non-elementary part ne.
+ ratpart : % -> F
+ ++ ratpart(ir) returns the rational part of an integration result
+ logpart : % -> List LOG
+ ++ logpart(ir) returns the logarithmic part of an integration result
+ notelem : % -> List NE
+ ++ notelem(ir) returns the non-elementary part of an integration result
+ elem? : % -> B
+ ++ elem?(ir) tests if an integration result is elementary over F?
+ integral: (F, F) -> %
+ ++ integral(f,x) returns the formal integral of f with respect to x
+ differentiate: (%, F -> F) -> F
+ ++ differentiate(ir,D) differentiates ir with respect to the derivation D.
+ if F has PartialDifferentialRing(SE) then
+ differentiate: (%, Symbol) -> F
+ ++ differentiate(ir,x) differentiates ir with respect to x
+ if F has RetractableTo Symbol then
+ integral: (F, Symbol) -> %
+ ++ integral(f,x) returns the formal integral of f with respect to x
+
+ Implementation ==> add
+ Rep := Record(ratp: F, logp: List LOG, nelem: List NE)
+
+ timelog : (Q, LOG) -> LOG
+ timene : (Q, NE) -> NE
+ LOG2O : LOG -> O
+ NE2O : NE -> O
+ Q2F : Q -> F
+ nesimp : List NE -> List NE
+ neselect: (List NE, F) -> F
+ pLogDeriv: (LOG, F -> F) -> F
+ pNeDeriv : (NE, F -> F) -> F
+
+
+ alpha:O := new()$Symbol :: O
+
+ - u == (-1$Z) * u
+ 0 == mkAnswer(0, empty(), empty())
+ coerce(x:F):% == mkAnswer(x, empty(), empty())
+ ratpart u == u.ratp
+ logpart u == u.logp
+ notelem u == u.nelem
+ elem? u == empty? notelem u
+ mkAnswer(x, l, n) == [x, l, nesimp n]
+ timelog(r, lg) == [r * lg.scalar, lg.coeff, lg.logand]
+ integral(f:F,x:F) == (zero? f => 0; mkAnswer(0, empty(), [[f, x]]))
+ timene(r, ne) == [Q2F(r) * ne.integrand, ne.intvar]
+ n:Z * u:% == (n::Q) * u
+ Q2F r == numer(r)::F / denom(r)::F
+ neselect(l, x) == _+/[ne.integrand for ne in l | ne.intvar = x]
+
+ if F has RetractableTo Symbol then
+ integral(f:F, x:Symbol):% == integral(f, x::F)
+
+ LOG2O rec ==
+-- one? degree rec.coeff =>
+ (degree rec.coeff) = 1 =>
+ -- deg 1 minimal poly doesn't get sigma
+ lastc := - coefficient(rec.coeff, 0) / coefficient(rec.coeff, 1)
+ lg := (rec.logand) lastc
+ logandp := prefix("log"::Symbol::O, [lg::O])
+ (cc := Q2F(rec.scalar) * lastc) = 1 => logandp
+ cc = -1 => - logandp
+ cc::O * logandp
+ coeffp:O := (outputForm(rec.coeff, alpha) = 0::Z::O)@O
+ logandp :=
+ alpha * prefix("log"::Symbol::O, [outputForm(rec.logand, alpha)])
+ if (cc := Q2F(rec.scalar)) ^= 1 then
+ logandp := cc::O * logandp
+ sum(logandp, coeffp)
+
+ nesimp l ==
+ [[u,x] for x in removeDuplicates_!([ne.intvar for ne in l]$List(F))
+ | (u := neselect(l, x)) ^= 0]
+
+ if (F has LiouvillianFunctionCategory) and (F has RetractableTo Symbol) then
+ retractIfCan u ==
+ empty? logpart u =>
+ ratpart u +
+ _+/[integral(ne.integrand, retract(ne.intvar)@Symbol)$F
+ for ne in notelem u]
+ "failed"
+
+ else
+ retractIfCan u ==
+ elem? u and empty? logpart u => ratpart u
+ "failed"
+
+ r:Q * u:% ==
+ r = 0 => 0
+ mkAnswer(Q2F(r) * ratpart u, map(timelog(r, #1), logpart u),
+ map(timene(r, #1), notelem u))
+
+ -- Initial attempt, quick and dirty, no simplification
+ u + v ==
+ mkAnswer(ratpart u + ratpart v, concat(logpart u, logpart v),
+ nesimp concat(notelem u, notelem v))
+
+ if F has PartialDifferentialRing(Symbol) then
+ differentiate(u:%, x:Symbol):F == differentiate(u, differentiate(#1, x))
+
+ differentiate(u:%, derivation:F -> F):F ==
+ derivation ratpart u +
+ _+/[pLogDeriv(log, derivation) for log in logpart u]
+ + _+/[pNeDeriv(ne, derivation) for ne in notelem u]
+
+ pNeDeriv(ne, derivation) ==
+-- one? derivation(ne.intvar) => ne.integrand
+ (derivation(ne.intvar) = 1) => ne.integrand
+ zero? derivation(ne.integrand) => 0
+ error "pNeDeriv: cannot differentiate not elementary part into F"
+
+ pLogDeriv(log, derivation) ==
+ map(derivation, log.coeff) ^= 0 =>
+ error "pLogDeriv: can only handle logs with constant coefficients"
+-- one?(n := degree(log.coeff)) =>
+ ((n := degree(log.coeff)) = 1) =>
+ c := - (leadingCoefficient reductum log.coeff)
+ / (leadingCoefficient log.coeff)
+ ans := (log.logand) c
+ Q2F(log.scalar) * c * derivation(ans) / ans
+ numlog := map(derivation, log.logand)
+ diflog := extendedEuclidean(log.logand, log.coeff,
+ numlog)::Record(coef1:UP, coef2:UP)
+ algans := diflog.coef1
+ ans:F := 0
+ for i in 0..(n-1) repeat
+ algans := algans * monomial(1, 1) rem log.coeff
+ ans := ans + coefficient(algans, i)
+ Q2F(log.scalar) * ans
+
+ coerce(u:%):O ==
+ (r := retractIfCan u) case F => r::F::O
+ l := reverse_! [LOG2O f for f in logpart u]$List(O)
+ if ratpart u ^= 0 then l := concat(ratpart(u)::O, l)
+ if not elem? u then l := concat([NE2O f for f in notelem u], l)
+ null l => 0::O
+ reduce("+", l)
+
+ NE2O ne ==
+ int((ne.integrand)::O * hconcat ["d"::Symbol::O, (ne.intvar)::O])
+
+@
+\section{package IR2 IntegrationResultFunctions2}
+<<package IR2 IntegrationResultFunctions2>>=
+)abbrev package IR2 IntegrationResultFunctions2
+++ Internally used by the integration packages
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 12 August 1992
+++ Keywords: integration.
+IntegrationResultFunctions2(E, F): Exports == Implementation where
+ E : Field
+ F : Field
+
+ SE ==> Symbol
+ Q ==> Fraction Integer
+ IRE ==> IntegrationResult E
+ IRF ==> IntegrationResult F
+ UPE ==> SparseUnivariatePolynomial E
+ UPF ==> SparseUnivariatePolynomial F
+ NEE ==> Record(integrand:E, intvar:E)
+ NEF ==> Record(integrand:F, intvar:F)
+ LGE ==> Record(scalar:Q, coeff:UPE, logand:UPE)
+ LGF ==> Record(scalar:Q, coeff:UPF, logand:UPF)
+ NLE ==> Record(coeff:E, logand:E)
+ NLF ==> Record(coeff:F, logand:F)
+ UFE ==> Union(Record(mainpart:E, limitedlogs:List NLE), "failed")
+ URE ==> Union(Record(ratpart:E, coeff:E), "failed")
+ UE ==> Union(E, "failed")
+
+ Exports ==> with
+ map: (E -> F, IRE) -> IRF
+ ++ map(f,ire) \undocumented
+ map: (E -> F, URE) -> Union(Record(ratpart:F, coeff:F), "failed")
+ ++ map(f,ure) \undocumented
+ map: (E -> F, UE) -> Union(F, "failed")
+ ++ map(f,ue) \undocumented
+ map: (E -> F, UFE) ->
+ Union(Record(mainpart:F, limitedlogs:List NLF), "failed")
+ ++ map(f,ufe) \undocumented
+
+ Implementation ==> add
+ import SparseUnivariatePolynomialFunctions2(E, F)
+
+ NEE2F: (E -> F, NEE) -> NEF
+ LGE2F: (E -> F, LGE) -> LGF
+ NLE2F: (E -> F, NLE) -> NLF
+
+ NLE2F(func, r) == [func(r.coeff), func(r.logand)]
+ NEE2F(func, n) == [func(n.integrand), func(n.intvar)]
+ map(func:E -> F, u:UE) == (u case "failed" => "failed"; func(u::E))
+
+ map(func:E -> F, ir:IRE) ==
+ mkAnswer(func ratpart ir, [LGE2F(func, f) for f in logpart ir],
+ [NEE2F(func, g) for g in notelem ir])
+
+ map(func:E -> F, u:URE) ==
+ u case "failed" => "failed"
+ [func(u.ratpart), func(u.coeff)]
+
+ map(func:E -> F, u:UFE) ==
+ u case "failed" => "failed"
+ [func(u.mainpart), [NLE2F(func, f) for f in u.limitedlogs]]
+
+ LGE2F(func, lg) ==
+ [lg.scalar, map(func, lg.coeff), map(func, lg.logand)]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- INTAUX rderf intrf rdeef intef irexpand integrat
+
+<<domain IR IntegrationResult>>
+<<package IR2 IntegrationResultFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intclos.spad.pamphlet b/src/algebra/intclos.spad.pamphlet
new file mode 100644
index 00000000..4470fc41
--- /dev/null
+++ b/src/algebra/intclos.spad.pamphlet
@@ -0,0 +1,816 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intclos.spad}
+\author{Victor Miller, Barry Trager, Clifton Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package TRIMAT TriangularMatrixOperations}
+<<package TRIMAT TriangularMatrixOperations>>=
+)abbrev package TRIMAT TriangularMatrixOperations
+++ Fraction free inverses of triangular matrices
+++ Author: Victor Miller
+++ Date Created:
+++ Date Last Updated: 24 Jul 1990
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package provides functions that compute "fraction-free"
+++ inverses of upper and lower triangular matrices over a integral
+++ domain. By "fraction-free inverses" we mean the following:
+++ given a matrix B with entries in R and an element d of R such that
+++ d * inv(B) also has entries in R, we return d * inv(B). Thus,
+++ it is not necessary to pass to the quotient field in any of our
+++ computations.
+
+
+TriangularMatrixOperations(R,Row,Col,M): Exports == Implementation where
+ R : IntegralDomain
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+ M : MatrixCategory(R,Row,Col)
+
+ Exports ==> with
+
+ UpTriBddDenomInv: (M,R) -> M
+ ++ UpTriBddDenomInv(B,d) returns M, where
+ ++ B is a non-singular upper triangular matrix and d is an
+ ++ element of R such that \spad{M = d * inv(B)} has entries in R.
+ LowTriBddDenomInv:(M,R) -> M
+ ++ LowTriBddDenomInv(B,d) returns M, where
+ ++ B is a non-singular lower triangular matrix and d is an
+ ++ element of R such that \spad{M = d * inv(B)} has entries in R.
+
+ Implementation ==> add
+
+ UpTriBddDenomInv(A,denom) ==
+ AI := zero(nrows A, nrows A)$M
+ offset := minColIndex AI - minRowIndex AI
+ for i in minRowIndex AI .. maxRowIndex AI
+ for j in minColIndex AI .. maxColIndex AI repeat
+ qsetelt_!(AI,i,j,(denom exquo qelt(A,i,j))::R)
+ for i in minRowIndex AI .. maxRowIndex AI repeat
+ for j in offset + i + 1 .. maxColIndex AI repeat
+ qsetelt_!(AI,i,j, - (((+/[qelt(AI,i,k) * qelt(A,k-offset,j)
+ for k in i+offset..(j-1)])
+ exquo qelt(A, j-offset, j))::R))
+ AI
+
+ LowTriBddDenomInv(A, denom) ==
+ AI := zero(nrows A, nrows A)$M
+ offset := minColIndex AI - minRowIndex AI
+ for i in minRowIndex AI .. maxRowIndex AI
+ for j in minColIndex AI .. maxColIndex AI repeat
+ qsetelt_!(AI,i,j,(denom exquo qelt(A,i,j))::R)
+ for i in minColIndex AI .. maxColIndex AI repeat
+ for j in i - offset + 1 .. maxRowIndex AI repeat
+ qsetelt_!(AI,j,i, - (((+/[qelt(A,j,k+offset) * qelt(AI,k,i)
+ for k in i-offset..(j-1)])
+ exquo qelt(A, j, j+offset))::R))
+ AI
+
+@
+\section{package IBATOOL IntegralBasisTools}
+<<package IBATOOL IntegralBasisTools>>=
+)abbrev package IBATOOL IntegralBasisTools
+++ Functions common to both integral basis packages
+++ Author: Victor Miller, Barry Trager, Clifton Williamson
+++ Date Created: 11 April 1990
+++ Date Last Updated: 20 September 1994
+++ Keywords: integral basis, function field, number field
+++ Examples:
+++ References:
+++ Description:
+++ This package contains functions used in the packages
+++ FunctionFieldIntegralBasis and NumberFieldIntegralBasis.
+
+IntegralBasisTools(R,UP,F): Exports == Implementation where
+ R : EuclideanDomain with
+ squareFree: $ -> Factored $
+ ++ squareFree(x) returns a square-free factorisation of x
+ UP : UnivariatePolynomialCategory R
+ F : FramedAlgebra(R,UP)
+ Mat ==> Matrix R
+ NNI ==> NonNegativeInteger
+ Ans ==> Record(basis: Mat, basisDen: R, basisInv:Mat)
+
+ Exports ==> with
+
+ diagonalProduct: Mat -> R
+ ++ diagonalProduct(m) returns the product of the elements on the
+ ++ diagonal of the matrix m
+ matrixGcd: (Mat,R,NNI) -> R
+ ++ matrixGcd(mat,sing,n) is \spad{gcd(sing,g)} where \spad{g} is the
+ ++ gcd of the entries of the \spad{n}-by-\spad{n} upper-triangular
+ ++ matrix \spad{mat}.
+ divideIfCan_!: (Matrix R,Matrix R,R,Integer) -> R
+ ++ divideIfCan!(matrix,matrixOut,prime,n) attempts to divide the
+ ++ entries of \spad{matrix} by \spad{prime} and store the result in
+ ++ \spad{matrixOut}. If it is successful, 1 is returned and if not,
+ ++ \spad{prime} is returned. Here both \spad{matrix} and
+ ++ \spad{matrixOut} are \spad{n}-by-\spad{n} upper triangular matrices.
+ leastPower: (NNI,NNI) -> NNI
+ ++ leastPower(p,n) returns e, where e is the smallest integer
+ ++ such that \spad{p **e >= n}
+ idealiser: (Mat,Mat) -> Mat
+ ++ idealiser(m1,m2) computes the order of an ideal defined by m1 and m2
+ idealiser: (Mat,Mat,R) -> Mat
+ ++ idealiser(m1,m2,d) computes the order of an ideal defined by m1 and m2
+ ++ where d is the known part of the denominator
+ idealiserMatrix: (Mat, Mat) -> Mat
+ ++ idealiserMatrix(m1, m2) returns the matrix representing the linear
+ ++ conditions on the Ring associatied with an ideal defined by m1 and m2.
+ moduleSum: (Ans,Ans) -> Ans
+ ++ moduleSum(m1,m2) returns the sum of two modules in the framed
+ ++ algebra \spad{F}. Each module \spad{mi} is represented as follows:
+ ++ F is a framed algebra with R-module basis \spad{w1,w2,...,wn} and
+ ++ \spad{mi} is a record \spad{[basis,basisDen,basisInv]}. If
+ ++ \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ a basis \spad{v1,...,vn} for \spad{mi} is given by
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of 'basis' contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+
+ Implementation ==> add
+ import ModularHermitianRowReduction(R)
+ import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+
+ diagonalProduct m ==
+ ans : R := 1
+ for i in minRowIndex m .. maxRowIndex m
+ for j in minColIndex m .. maxColIndex m repeat
+ ans := ans * qelt(m, i, j)
+ ans
+
+ matrixGcd(mat,sing,n) ==
+ -- note: 'matrix' is upper triangular;
+ -- no need to do anything below the diagonal
+ d := sing
+ for i in 1..n repeat
+ for j in i..n repeat
+ if not zero?(mij := qelt(mat,i,j)) then d := gcd(d,mij)
+-- one? d => return d
+ (d = 1) => return d
+ d
+
+ divideIfCan_!(matrix,matrixOut,prime,n) ==
+ -- note: both 'matrix' and 'matrixOut' will be upper triangular;
+ -- no need to do anything below the diagonal
+ for i in 1..n repeat
+ for j in i..n repeat
+ (a := (qelt(matrix,i,j) exquo prime)) case "failed" => return prime
+ qsetelt_!(matrixOut,i,j,a :: R)
+ 1
+
+ leastPower(p,n) ==
+ -- efficiency is not an issue here
+ e : NNI := 1; q := p
+ while q < n repeat (e := e + 1; q := q * p)
+ e
+
+ idealiserMatrix(ideal,idealinv) ==
+ -- computes the Order of the ideal
+ n := rank()$F
+ bigm := zero(n * n,n)$Mat
+ mr := minRowIndex bigm; mc := minColIndex bigm
+ v := basis()$F
+ for i in 0..n-1 repeat
+ r := regularRepresentation qelt(v,i + minIndex v)
+ m := ideal * r * idealinv
+ for j in 0..n-1 repeat
+ for k in 0..n-1 repeat
+ bigm(j * n + k + mr,i + mc) := qelt(m,j + mr,k + mc)
+ bigm
+
+ idealiser(ideal,idealinv) ==
+ bigm := idealiserMatrix(ideal, idealinv)
+ transpose squareTop rowEch bigm
+
+ idealiser(ideal,idealinv,denom) ==
+ bigm := (idealiserMatrix(ideal, idealinv) exquo denom)::Mat
+ transpose squareTop rowEchelon(bigm,denom)
+
+ moduleSum(mod1,mod2) ==
+ rb1 := mod1.basis; rbden1 := mod1.basisDen; rbinv1 := mod1.basisInv
+ rb2 := mod2.basis; rbden2 := mod2.basisDen; rbinv2 := mod2.basisInv
+ -- compatibility check: doesn't take much computation time
+ (not square? rb1) or (not square? rbinv1) or (not square? rb2) _
+ or (not square? rbinv2) =>
+ error "moduleSum: matrices must be square"
+ ((n := nrows rb1) ^= (nrows rbinv1)) or (n ^= (nrows rb2)) _
+ or (n ^= (nrows rbinv2)) =>
+ error "moduleSum: matrices of imcompatible dimensions"
+ (zero? rbden1) or (zero? rbden2) =>
+ error "moduleSum: denominator must be non-zero"
+ den := lcm(rbden1,rbden2); c1 := den quo rbden1; c2 := den quo rbden2
+ rb := squareTop rowEchelon(vertConcat(c1 * rb1,c2 * rb2),den)
+ rbinv := UpTriBddDenomInv(rb,den)
+ [rb,den,rbinv]
+
+@
+\section{package FFINTBAS FunctionFieldIntegralBasis}
+<<package FFINTBAS FunctionFieldIntegralBasis>>=
+)abbrev package FFINTBAS FunctionFieldIntegralBasis
+++ Integral bases for function fields of dimension one
+++ Author: Victor Miller
+++ Date Created: 9 April 1990
+++ Date Last Updated: 20 September 1994
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ In this package R is a Euclidean domain and F is a framed algebra
+++ over R. The package provides functions to compute the integral
+++ closure of R in the quotient field of F. It is assumed that
+++ \spad{char(R/P) = char(R)} for any prime P of R. A typical instance of
+++ this is when \spad{R = K[x]} and F is a function field over R.
+
+
+FunctionFieldIntegralBasis(R,UP,F): Exports == Implementation where
+ R : EuclideanDomain with
+ squareFree: $ -> Factored $
+ ++ squareFree(x) returns a square-free factorisation of x
+ UP : UnivariatePolynomialCategory R
+ F : FramedAlgebra(R,UP)
+
+ I ==> Integer
+ Mat ==> Matrix R
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ integralBasis : () -> Record(basis: Mat, basisDen: R, basisInv:Mat)
+ ++ \spad{integralBasis()} returns a record
+ ++ \spad{[basis,basisDen,basisInv]} containing information regarding
+ ++ the integral closure of R in the quotient field of F, where
+ ++ F is a framed algebra with R-module basis \spad{w1,w2,...,wn}.
+ ++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of \spad{basis} contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+ localIntegralBasis : R -> Record(basis: Mat, basisDen: R, basisInv:Mat)
+ ++ \spad{integralBasis(p)} returns a record
+ ++ \spad{[basis,basisDen,basisInv]} containing information regarding
+ ++ the local integral closure of R at the prime \spad{p} in the quotient
+ ++ field of F, where F is a framed algebra with R-module basis
+ ++ \spad{w1,w2,...,wn}.
+ ++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the local integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of \spad{basis} contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+
+ Implementation ==> add
+ import IntegralBasisTools(R, UP, F)
+ import ModularHermitianRowReduction(R)
+ import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+
+ squaredFactors: R -> R
+ squaredFactors px ==
+ */[(if ffe.exponent > 1 then ffe.factor else 1$R)
+ for ffe in factors squareFree px]
+
+ iIntegralBasis: (Mat,R,R) -> Record(basis: Mat, basisDen: R, basisInv:Mat)
+ iIntegralBasis(tfm,disc,sing) ==
+ -- tfm = trace matrix of current order
+ n := rank()$F; tfm0 := copy tfm; disc0 := disc
+ rb := scalarMatrix(n, 1); rbinv := scalarMatrix(n, 1)
+ -- rb = basis matrix of current order
+ -- rbinv = inverse basis matrix of current order
+ -- these are wrt the original basis for F
+ rbden : R := 1; index : R := 1; oldIndex : R := 1
+ -- rbden = denominator for current basis matrix
+ -- index = index of original order in current order
+ not sizeLess?(1, sing) => [rb, rbden, rbinv]
+ repeat
+ -- compute the p-radical
+ idinv := transpose squareTop rowEchelon(tfm, sing)
+ -- [u1,..,un] are the coordinates of an element of the p-radical
+ -- iff [u1,..,un] * idinv is in sing * R^n
+ id := rowEchelon LowTriBddDenomInv(idinv, sing)
+ -- id = basis matrix of the p-radical
+ idinv := UpTriBddDenomInv(id, sing)
+ -- id * idinv = sing * identity
+ -- no need to check for inseparability in this case
+ rbinv := idealiser(id * rb, rbinv * idinv, sing * rbden)
+ index := diagonalProduct rbinv
+ rb := rowEchelon LowTriBddDenomInv(rbinv, rbden * sing)
+ g := matrixGcd(rb,sing,n)
+ if sizeLess?(1,g) then rb := (rb exquo g) :: Mat
+ rbden := rbden * (sing quo g)
+ rbinv := UpTriBddDenomInv(rb, rbden)
+ disc := disc0 quo (index * index)
+ indexChange := index quo oldIndex; oldIndex := index
+ sing := gcd(indexChange, squaredFactors disc)
+ not sizeLess?(1, sing) => return [rb, rbden, rbinv]
+ tfm := ((rb * tfm0 * transpose rb) exquo (rbden * rbden)) :: Mat
+
+ integralBasis() ==
+ n := rank()$F; p := characteristic()$F
+ (not zero? p) and (n >= p) =>
+ error "integralBasis: possible wild ramification"
+ tfm := traceMatrix()$F; disc := determinant tfm
+ sing := squaredFactors disc -- singularities of relative Spec
+ iIntegralBasis(tfm,disc,sing)
+
+ localIntegralBasis prime ==
+ n := rank()$F; p := characteristic()$F
+ (not zero? p) and (n >= p) =>
+ error "integralBasis: possible wild ramification"
+ tfm := traceMatrix()$F; disc := determinant tfm
+ (disc exquo (prime * prime)) case "failed" =>
+ [scalarMatrix(n,1),1,scalarMatrix(n,1)]
+ iIntegralBasis(tfm,disc,prime)
+
+@
+\section{package WFFINTBS WildFunctionFieldIntegralBasis}
+<<package WFFINTBS WildFunctionFieldIntegralBasis>>=
+)abbrev package WFFINTBS WildFunctionFieldIntegralBasis
+++ Authors: Victor Miller, Clifton Williamson
+++ Date Created: 24 July 1991
+++ Date Last Updated: 20 September 1994
+++ Basic Operations: integralBasis, localIntegralBasis
+++ Related Domains: IntegralBasisTools(R,UP,F),
+++ TriangularMatrixOperations(R,Vector R,Vector R,Matrix R)
+++ Also See: FunctionFieldIntegralBasis, NumberFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, integral basis
+++ Examples:
+++ References:
+++ Description:
+++ In this package K is a finite field, R is a ring of univariate
+++ polynomials over K, and F is a framed algebra over R. The package
+++ provides a function to compute the integral closure of R in the quotient
+++ field of F as well as a function to compute a "local integral basis"
+++ at a specific prime.
+
+WildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
+ K : FiniteFieldCategory
+ --K : Join(Field,Finite)
+ R : UnivariatePolynomialCategory K
+ UP : UnivariatePolynomialCategory R
+ F : FramedAlgebra(R,UP)
+
+ I ==> Integer
+ Mat ==> Matrix R
+ NNI ==> NonNegativeInteger
+ SAE ==> SimpleAlgebraicExtension
+ RResult ==> Record(basis: Mat, basisDen: R, basisInv:Mat)
+ IResult ==> Record(basis: Mat, basisDen: R, basisInv:Mat,discr: R)
+ MATSTOR ==> StorageEfficientMatrixOperations
+
+ Exports ==> with
+ integralBasis : () -> RResult
+ ++ \spad{integralBasis()} returns a record
+ ++ \spad{[basis,basisDen,basisInv]} containing information regarding
+ ++ the integral closure of R in the quotient field of F, where
+ ++ F is a framed algebra with R-module basis \spad{w1,w2,...,wn}.
+ ++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of \spad{basis} contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+ localIntegralBasis : R -> RResult
+ ++ \spad{integralBasis(p)} returns a record
+ ++ \spad{[basis,basisDen,basisInv]} containing information regarding
+ ++ the local integral closure of R at the prime \spad{p} in the quotient
+ ++ field of F, where F is a framed algebra with R-module basis
+ ++ \spad{w1,w2,...,wn}.
+ ++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the local integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of \spad{basis} contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+
+ Implementation ==> add
+ import IntegralBasisTools(R, UP, F)
+ import ModularHermitianRowReduction(R)
+ import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+ import DistinctDegreeFactorize(K,R)
+
+ listSquaredFactors: R -> List R
+ listSquaredFactors px ==
+ -- returns a list of the factors of px which occur with
+ -- exponent > 1
+ ans : List R := empty()
+ factored := factor(px)$DistinctDegreeFactorize(K,R)
+ for f in factors(factored) repeat
+ if f.exponent > 1 then ans := concat(f.factor,ans)
+ ans
+
+ iLocalIntegralBasis: (Vector F,Vector F,Matrix R,Matrix R,R,R) -> IResult
+ iLocalIntegralBasis(bas,pows,tfm,matrixOut,disc,prime) ==
+ n := rank()$F; standardBasis := basis()$F
+ -- 'standardBasis' is the basis for F as a FramedAlgebra;
+ -- usually this is [1,y,y**2,...,y**(n-1)]
+ p2 := prime * prime; sae := SAE(K,R,prime)
+ p := characteristic()$F; q := size()$sae
+ lp := leastPower(q,n)
+ rb := scalarMatrix(n,1); rbinv := scalarMatrix(n,1)
+ -- rb = basis matrix of current order
+ -- rbinv = inverse basis matrix of current order
+ -- these are wrt the orginal basis for F
+ rbden : R := 1; index : R := 1; oldIndex : R := 1
+ -- rbden = denominator for current basis matrix
+ -- index = index of original order in current order
+ repeat
+ -- pows = [(w1 * rbden) ** q,...,(wn * rbden) ** q], where
+ -- bas = [w1,...,wn] is 'rbden' times the basis for the order B = 'rb'
+ for i in 1..n repeat
+ bi : F := 0
+ for j in 1..n repeat
+ bi := bi + qelt(rb,i,j) * qelt(standardBasis,j)
+ qsetelt_!(bas,i,bi)
+ qsetelt_!(pows,i,bi ** p)
+ coor0 := transpose coordinates(pows,bas)
+ denPow := rbden ** ((p - 1) :: NNI)
+ (coMat0 := coor0 exquo denPow) case "failed" =>
+ error "can't happen"
+ -- the jth column of coMat contains the coordinates of (wj/rbden)**q
+ -- with respect to the basis [w1/rbden,...,wn/rbden]
+ coMat := coMat0 :: Matrix R
+ -- the ith column of 'pPows' contains the coordinates of the pth power
+ -- of the ith basis element for B/prime.B over 'sae' = R/prime.R
+ pPows := map(reduce,coMat)$MatrixCategoryFunctions2(R,Vector R,
+ Vector R,Matrix R,sae,Vector sae,Vector sae,Matrix sae)
+ -- 'frob' will eventually be the Frobenius matrix for B/prime.B over
+ -- 'sae' = R/prime.R; at each stage of the loop the ith column will
+ -- contain the coordinates of p^k-th powers of the ith basis element
+ frob := copy pPows; tmpMat : Matrix sae := new(n,n,0)
+ for r in 2..leastPower(p,q) repeat
+ for i in 1..n repeat for j in 1..n repeat
+ qsetelt_!(tmpMat,i,j,qelt(frob,i,j) ** p)
+ times_!(frob,pPows,tmpMat)$MATSTOR(sae)
+ frobPow := frob ** lp
+ -- compute the p-radical
+ ns := nullSpace frobPow
+ for i in 1..n repeat for j in 1..n repeat qsetelt_!(tfm,i,j,0)
+ for vec in ns for i in 1.. repeat
+ for j in 1..n repeat
+ qsetelt_!(tfm,i,j,lift qelt(vec,j))
+ id := squareTop rowEchelon(tfm,prime)
+ -- id = basis matrix of the p-radical
+ idinv := UpTriBddDenomInv(id, prime)
+ -- id * idinv = prime * identity
+ -- no need to check for inseparability in this case
+ rbinv := idealiser(id * rb, rbinv * idinv, prime * rbden)
+ index := diagonalProduct rbinv
+ rb := rowEchelon LowTriBddDenomInv(rbinv,rbden * prime)
+ if divideIfCan_!(rb,matrixOut,prime,n) = 1
+ then rb := matrixOut
+ else rbden := rbden * prime
+ rbinv := UpTriBddDenomInv(rb,rbden)
+ indexChange := index quo oldIndex
+ oldIndex := index
+ disc := disc quo (indexChange * indexChange)
+ (not sizeLess?(1,indexChange)) or ((disc exquo p2) case "failed") =>
+ return [rb, rbden, rbinv, disc]
+
+ integralBasis() ==
+ traceMat := traceMatrix()$F; n := rank()$F
+ disc := determinant traceMat -- discriminant of current order
+ zero? disc => error "integralBasis: polynomial must be separable"
+ singList := listSquaredFactors disc -- singularities of relative Spec
+ runningRb := scalarMatrix(n,1); runningRbinv := scalarMatrix(n,1)
+ -- runningRb = basis matrix of current order
+ -- runningRbinv = inverse basis matrix of current order
+ -- these are wrt the original basis for F
+ runningRbden : R := 1
+ -- runningRbden = denominator for current basis matrix
+ empty? singList => [runningRb, runningRbden, runningRbinv]
+ bas : Vector F := new(n,0); pows : Vector F := new(n,0)
+ -- storage for basis elements and their powers
+ tfm : Matrix R := new(n,n,0)
+ -- 'tfm' will contain the coordinates of a lifting of the kernel
+ -- of a power of Frobenius
+ matrixOut : Matrix R := new(n,n,0)
+ for prime in singList repeat
+ lb := iLocalIntegralBasis(bas,pows,tfm,matrixOut,disc,prime)
+ rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
+ disc := lb.discr
+ -- update 'running integral basis' if newly computed
+ -- local integral basis is non-trivial
+ if sizeLess?(1,rbden) then
+ mat := vertConcat(rbden * runningRb,runningRbden * rb)
+ runningRbden := runningRbden * rbden
+ runningRb := squareTop rowEchelon(mat,runningRbden)
+ runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
+ [runningRb, runningRbden, runningRbinv]
+
+ localIntegralBasis prime ==
+ traceMat := traceMatrix()$F; n := rank()$F
+ disc := determinant traceMat -- discriminant of current order
+ zero? disc => error "localIntegralBasis: polynomial must be separable"
+ (disc exquo (prime * prime)) case "failed" =>
+ [scalarMatrix(n,1), 1, scalarMatrix(n,1)]
+ bas : Vector F := new(n,0); pows : Vector F := new(n,0)
+ -- storage for basis elements and their powers
+ tfm : Matrix R := new(n,n,0)
+ -- 'tfm' will contain the coordinates of a lifting of the kernel
+ -- of a power of Frobenius
+ matrixOut : Matrix R := new(n,n,0)
+ lb := iLocalIntegralBasis(bas,pows,tfm,matrixOut,disc,prime)
+ [lb.basis, lb.basisDen, lb.basisInv]
+
+@
+\section{package NFINTBAS NumberFieldIntegralBasis}
+<<package NFINTBAS NumberFieldIntegralBasis>>=
+)abbrev package NFINTBAS NumberFieldIntegralBasis
+++ Author: Victor Miller, Clifton Williamson
+++ Date Created: 9 April 1990
+++ Date Last Updated: 20 September 1994
+++ Basic Operations: discriminant, integralBasis
+++ Related Domains: IntegralBasisTools, TriangularMatrixOperations
+++ Also See: FunctionFieldIntegralBasis, WildFunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: number field, integral basis, discriminant
+++ Examples:
+++ References:
+++ Description:
+++ In this package F is a framed algebra over the integers (typically
+++ \spad{F = Z[a]} for some algebraic integer a). The package provides
+++ functions to compute the integral closure of Z in the quotient
+++ quotient field of F.
+NumberFieldIntegralBasis(UP,F): Exports == Implementation where
+ UP : UnivariatePolynomialCategory Integer
+ F : FramedAlgebra(Integer,UP)
+
+ FR ==> Factored Integer
+ I ==> Integer
+ Mat ==> Matrix I
+ NNI ==> NonNegativeInteger
+ Ans ==> Record(basis: Mat, basisDen: I, basisInv:Mat,discr: I)
+
+ Exports ==> with
+ discriminant: () -> Integer
+ ++ \spad{discriminant()} returns the discriminant of the integral
+ ++ closure of Z in the quotient field of the framed algebra F.
+ integralBasis : () -> Record(basis: Mat, basisDen: I, basisInv:Mat)
+ ++ \spad{integralBasis()} returns a record
+ ++ \spad{[basis,basisDen,basisInv]}
+ ++ containing information regarding the integral closure of Z in the
+ ++ quotient field of F, where F is a framed algebra with Z-module
+ ++ basis \spad{w1,w2,...,wn}.
+ ++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of \spad{basis} contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+ localIntegralBasis : I -> Record(basis: Mat, basisDen: I, basisInv:Mat)
+ ++ \spad{integralBasis(p)} returns a record
+ ++ \spad{[basis,basisDen,basisInv]} containing information regarding
+ ++ the local integral closure of Z at the prime \spad{p} in the quotient
+ ++ field of F, where F is a framed algebra with Z-module basis
+ ++ \spad{w1,w2,...,wn}.
+ ++ If \spad{basis} is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of \spad{basis} contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix \spad{basisInv} contains the coordinates of \spad{wi} with
+ ++ respect to the basis \spad{v1,...,vn}: if \spad{basisInv} is the
+ ++ matrix \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+
+ Implementation ==> add
+ import IntegralBasisTools(I, UP, F)
+ import ModularHermitianRowReduction(I)
+ import TriangularMatrixOperations(I, Vector I, Vector I, Matrix I)
+
+ frobMatrix : (Mat,Mat,I,NNI) -> Mat
+ wildPrimes : (FR,I) -> List I
+ tameProduct : (FR,I) -> I
+ iTameLocalIntegralBasis : (Mat,I,I) -> Ans
+ iWildLocalIntegralBasis : (Mat,I,I) -> Ans
+
+ frobMatrix(rb,rbinv,rbden,p) ==
+ n := rank()$F; b := basis()$F
+ v : Vector F := new(n,0)
+ for i in minIndex(v)..maxIndex(v)
+ for ii in minRowIndex(rb)..maxRowIndex(rb) repeat
+ a : F := 0
+ for j in minIndex(b)..maxIndex(b)
+ for jj in minColIndex(rb)..maxColIndex(rb) repeat
+ a := a + qelt(rb,ii,jj) * qelt(b,j)
+ qsetelt_!(v,i,a**p)
+ mat := transpose coordinates v
+ ((transpose(rbinv) * mat) exquo (rbden ** p)) :: Mat
+
+ wildPrimes(factoredDisc,n) ==
+ -- returns a list of the primes <=n which divide factoredDisc to a
+ -- power greater than 1
+ ans : List I := empty()
+ for f in factors(factoredDisc) repeat
+ if f.exponent > 1 and f.factor <= n then ans := concat(f.factor,ans)
+ ans
+
+ tameProduct(factoredDisc,n) ==
+ -- returns the product of the primes > n which divide factoredDisc
+ -- to a power greater than 1
+ ans : I := 1
+ for f in factors(factoredDisc) repeat
+ if f.exponent > 1 and f.factor > n then ans := f.factor * ans
+ ans
+
+ integralBasis() ==
+ traceMat := traceMatrix()$F; n := rank()$F
+ disc := determinant traceMat -- discriminant of current order
+ disc0 := disc -- this is disc(F)
+ factoredDisc := factor(disc0)$IntegerFactorizationPackage(Integer)
+ wilds := wildPrimes(factoredDisc,n)
+ sing := tameProduct(factoredDisc,n)
+ runningRb := scalarMatrix(n, 1); runningRbinv := scalarMatrix(n, 1)
+ -- runningRb = basis matrix of current order
+ -- runningRbinv = inverse basis matrix of current order
+ -- these are wrt the original basis for F
+ runningRbden : I := 1
+ -- runningRbden = denominator for current basis matrix
+-- one? sing and empty? wilds => [runningRb, runningRbden, runningRbinv]
+ (sing = 1) and empty? wilds => [runningRb, runningRbden, runningRbinv]
+ -- id = basis matrix of the ideal (p-radical) wrt current basis
+ matrixOut : Mat := scalarMatrix(n,0)
+ for p in wilds repeat
+ lb := iWildLocalIntegralBasis(matrixOut,disc,p)
+ rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
+ disc := lb.discr
+ -- update 'running integral basis' if newly computed
+ -- local integral basis is non-trivial
+ if sizeLess?(1,rbden) then
+ mat := vertConcat(rbden * runningRb,runningRbden * rb)
+ runningRbden := runningRbden * rbden
+ runningRb := squareTop rowEchelon(mat,runningRbden)
+ runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
+ lb := iTameLocalIntegralBasis(traceMat,disc,sing)
+ rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
+ disc := lb.discr
+ -- update 'running integral basis' if newly computed
+ -- local integral basis is non-trivial
+ if sizeLess?(1,rbden) then
+ mat := vertConcat(rbden * runningRb,runningRbden * rb)
+ runningRbden := runningRbden * rbden
+ runningRb := squareTop rowEchelon(mat,runningRbden)
+ runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
+ [runningRb,runningRbden,runningRbinv]
+
+ localIntegralBasis p ==
+ traceMat := traceMatrix()$F; n := rank()$F
+ disc := determinant traceMat -- discriminant of current order
+ (disc exquo (p*p)) case "failed" =>
+ [scalarMatrix(n, 1), 1, scalarMatrix(n, 1)]
+ lb :=
+ p > rank()$F =>
+ iTameLocalIntegralBasis(traceMat,disc,p)
+ iWildLocalIntegralBasis(scalarMatrix(n,0),disc,p)
+ [lb.basis,lb.basisDen,lb.basisInv]
+
+ iTameLocalIntegralBasis(traceMat,disc,sing) ==
+ n := rank()$F; disc0 := disc
+ rb := scalarMatrix(n, 1); rbinv := scalarMatrix(n, 1)
+ -- rb = basis matrix of current order
+ -- rbinv = inverse basis matrix of current order
+ -- these are wrt the original basis for F
+ rbden : I := 1; index : I := 1; oldIndex : I := 1
+ -- rbden = denominator for current basis matrix
+ -- id = basis matrix of the ideal (p-radical) wrt current basis
+ tfm := traceMat
+ repeat
+ -- compute the p-radical = p-trace-radical
+ idinv := transpose squareTop rowEchelon(tfm,sing)
+ -- [u1,..,un] are the coordinates of an element of the p-radical
+ -- iff [u1,..,un] * idinv is in p * Z^n
+ id := rowEchelon LowTriBddDenomInv(idinv, sing)
+ -- id = basis matrix of the p-radical
+ idinv := UpTriBddDenomInv(id, sing)
+ -- id * idinv = sing * identity
+ -- no need to check for inseparability in this case
+ rbinv := idealiser(id * rb, rbinv * idinv, sing * rbden)
+ index := diagonalProduct rbinv
+ rb := rowEchelon LowTriBddDenomInv(rbinv, sing * rbden)
+ g := matrixGcd(rb,sing,n)
+ if sizeLess?(1,g) then rb := (rb exquo g) :: Mat
+ rbden := rbden * (sing quo g)
+ rbinv := UpTriBddDenomInv(rb, rbden)
+ disc := disc0 quo (index * index)
+ indexChange := index quo oldIndex; oldIndex := index
+-- one? indexChange => return [rb, rbden, rbinv, disc]
+ (indexChange = 1) => return [rb, rbden, rbinv, disc]
+ tfm := ((rb * traceMat * transpose rb) exquo (rbden * rbden)) :: Mat
+
+ iWildLocalIntegralBasis(matrixOut,disc,p) ==
+ n := rank()$F; disc0 := disc
+ rb := scalarMatrix(n, 1); rbinv := scalarMatrix(n, 1)
+ -- rb = basis matrix of current order
+ -- rbinv = inverse basis matrix of current order
+ -- these are wrt the original basis for F
+ rbden : I := 1; index : I := 1; oldIndex : I := 1
+ -- rbden = denominator for current basis matrix
+ -- id = basis matrix of the ideal (p-radical) wrt current basis
+ p2 := p * p; lp := leastPower(p::NNI,n)
+ repeat
+ tfm := frobMatrix(rb,rbinv,rbden,p::NNI) ** lp
+ -- compute Rp = p-radical
+ idinv := transpose squareTop rowEchelon(tfm, p)
+ -- [u1,..,un] are the coordinates of an element of Rp
+ -- iff [u1,..,un] * idinv is in p * Z^n
+ id := rowEchelon LowTriBddDenomInv(idinv,p)
+ -- id = basis matrix of the p-radical
+ idinv := UpTriBddDenomInv(id,p)
+ -- id * idinv = p * identity
+ -- no need to check for inseparability in this case
+ rbinv := idealiser(id * rb, rbinv * idinv, p * rbden)
+ index := diagonalProduct rbinv
+ rb := rowEchelon LowTriBddDenomInv(rbinv, p * rbden)
+ if divideIfCan_!(rb,matrixOut,p,n) = 1
+ then rb := matrixOut
+ else rbden := p * rbden
+ rbinv := UpTriBddDenomInv(rb, rbden)
+ indexChange := index quo oldIndex; oldIndex := index
+ disc := disc quo (indexChange * indexChange)
+-- one? indexChange or gcd(p2,disc) ^= p2 =>
+ (indexChange = 1) or gcd(p2,disc) ^= p2 =>
+ return [rb, rbden, rbinv, disc]
+
+ discriminant() ==
+ disc := determinant traceMatrix()$F
+ intBas := integralBasis()
+ rb := intBas.basis; rbden := intBas.basisDen
+ index := ((rbden ** rank()$F) exquo (determinant rb)) :: Integer
+ (disc exquo (index * index)) :: Integer
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package TRIMAT TriangularMatrixOperations>>
+<<package IBATOOL IntegralBasisTools>>
+<<package FFINTBAS FunctionFieldIntegralBasis>>
+<<package WFFINTBS WildFunctionFieldIntegralBasis>>
+<<package NFINTBAS NumberFieldIntegralBasis>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intef.spad.pamphlet b/src/algebra/intef.spad.pamphlet
new file mode 100644
index 00000000..4dbbc26f
--- /dev/null
+++ b/src/algebra/intef.spad.pamphlet
@@ -0,0 +1,389 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intef.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTEF ElementaryIntegration}
+<<package INTEF ElementaryIntegration>>=
+)abbrev package INTEF ElementaryIntegration
+++ Integration of elementary functions
+++ Author: Manuel Bronstein
+++ Date Created: 1 February 1988
+++ Date Last Updated: 24 October 1995
+++ Description:
+++ This package provides functions for integration, limited integration,
+++ extended integration and the risch differential equation for
+++ elemntary functions.
+++ Keywords: elementary, function, integration.
+++ Examples: )r INTEF INPUT
+ElementaryIntegration(R, F): Exports == Implementation where
+ R : Join(GcdDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory,
+ FunctionSpace R)
+
+ SE ==> Symbol
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ IR ==> IntegrationResult F
+ FF ==> Record(ratpart:RF, coeff:RF)
+ LLG ==> List Record(coeff:F, logand:F)
+ U2 ==> Union(Record(ratpart:F, coeff:F), "failed")
+ U3 ==> Union(Record(mainpart:F, limitedlogs:LLG), "failed")
+ ANS ==> Record(special:F, integrand:F)
+ FAIL==> error "failed - cannot handle that integrand"
+ ALGOP ==> "%alg"
+ OPDIFF ==> "%diff"::SE
+
+ Exports ==> with
+ lfextendedint: (F, SE, F) -> U2
+ ++ lfextendedint(f, x, g) returns functions \spad{[h, c]} such that
+ ++ \spad{dh/dx = f - cg}, if (h, c) exist, "failed" otherwise.
+ lflimitedint : (F, SE, List F) -> U3
+ ++ lflimitedint(f,x,[g1,...,gn]) returns functions \spad{[h,[[ci, gi]]]}
+ ++ such that the gi's are among \spad{[g1,...,gn]}, and
+ ++ \spad{d(h+sum(ci log(gi)))/dx = f}, if possible, "failed" otherwise.
+ lfinfieldint : (F, SE) -> Union(F, "failed")
+ ++ lfinfieldint(f, x) returns a function g such that \spad{dg/dx = f}
+ ++ if g exists, "failed" otherwise.
+ lfintegrate : (F, SE) -> IR
+ ++ lfintegrate(f, x) = g such that \spad{dg/dx = f}.
+ lfextlimint : (F, SE, K, List K) -> U2
+ ++ lfextlimint(f,x,k,[k1,...,kn]) returns functions \spad{[h, c]}
+ ++ such that \spad{dh/dx = f - c dk/dx}. Value h is looked for in a field
+ ++ containing f and k1,...,kn (the ki's must be logs).
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import ElementaryRischDE(R, F)
+ import RationalIntegration(F, UP)
+ import AlgebraicIntegration(R, F)
+ import AlgebraicManipulations(R, F)
+ import ElementaryRischDESystem(R, F)
+ import TranscendentalIntegration(F, UP)
+ import PureAlgebraicIntegration(R, F, F)
+ import IntegrationResultFunctions2(F, F)
+ import IntegrationResultFunctions2(RF, F)
+ import FunctionSpacePrimitiveElement(R, F)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+ alglfint : (F, K, List K, SE) -> IR
+ alglfextint : (F, K, List K, SE, F) -> U2
+ alglflimint : (F, K, List K, SE, List F) -> U3
+ primextint : (F, SE, K, F) -> U2
+ expextint : (F, SE, K, F) -> U2
+ primlimint : (F, SE, K, List F) -> U3
+ explimint : (F, SE, K, List F) -> U3
+ algprimint : (F, K, K, SE) -> IR
+ algexpint : (F, K, K, SE) -> IR
+ primint : (F, SE, K) -> IR
+ expint : (F, SE, K) -> IR
+ tanint : (F, SE, K) -> IR
+ prim? : (K, SE) -> Boolean
+ isx? : (F, SE) -> Boolean
+ addx : (IR, F) -> IR
+ cfind : (F, LLG) -> F
+ lfintegrate0: (F, SE) -> IR
+ unknownint : (F, SE) -> IR
+ unkextint : (F, SE, F) -> U2
+ unklimint : (F, SE, List F) -> U3
+ tryChangeVar: (F, K, SE) -> Union(IR, "failed")
+ droponex : (F, F, K, F) -> Union(F, "failed")
+
+ prim?(k, x) == is?(k, "log"::SE) or has?(operator k, "prim")
+
+ tanint(f, x, k) ==
+ eta' := differentiate(eta := first argument k, x)
+ r1 := tanintegrate(univariate(f, k), differentiate(#1,
+ differentiate(#1, x), monomial(eta', 2) + eta'::UP),
+ rischDEsys(#1, 2 * eta, #2, #3, x, lflimitedint(#1, x, #2),
+ lfextendedint(#1, x, #2)))
+ map(multivariate(#1, k), r1.answer) + lfintegrate(r1.a0, x)
+
+-- tries various tricks since the integrand contains something not elementary
+ unknownint(f, x) ==
+ ((r := retractIfCan(f)@Union(K, "failed")) case K) and
+ is?(k := r::K, OPDIFF) and
+ ((ka:=retractIfCan(a:=second(l:=argument k))@Union(K,"failed"))case K)
+ and ((z := retractIfCan(zz := third l)@Union(SE, "failed")) case SE)
+ and (z::SE = x)
+ and ((u := droponex(first l, a, ka, zz)) case F) => u::F::IR
+ (da := differentiate(a := denom(f)::F, x)) ^= 0 and
+ zero? differentiate(c := numer(f)::F / da, x) => (c * log a)::IR
+ mkAnswer(0, empty(), [[f, x::F]])
+
+ droponex(f, a, ka, x) ==
+ (r := retractIfCan(f)@Union(K, "failed")) case "failed" => "failed"
+ is?(op := operator(k := r::K), OPDIFF) =>
+ (z := third(arg := argument k)) = a => op [first arg, second arg, x]
+ (u := droponex(first arg, a, ka, x)) case "failed" => "failed"
+ op [u::F, second arg, z]
+ eval(f, [ka], [x])
+
+ unklimint(f, x, lu) ==
+ for u in lu | u ^= 0 repeat
+ zero? differentiate(c := f * u / differentiate(u, x), x) => [0,[[c,u]]]
+ "failed"
+
+ unkextint(f, x, g) ==
+ zero?(g' := differentiate(g, x)) => "failed"
+ zero? differentiate(c := f / g', x) => [0, c]
+ "failed"
+
+ isx?(f, x) ==
+ (k := retractIfCan(f)@Union(K, "failed")) case "failed" => false
+ (r := symbolIfCan(k::K)) case "failed" => false
+ r::SE = x
+
+ alglfint(f, k, l, x) ==
+ xf := x::F
+ symbolIfCan(kx := ksec(k,l,x)) case SE => addx(palgint(f, kx, k), xf)
+ is?(kx, "exp"::SE) => addx(algexpint(f, kx, k, x), xf)
+ prim?(kx, x) => addx(algprimint(f, kx, k, x), xf)
+ has?(operator kx, ALGOP) =>
+ rec := primitiveElement(kx::F, k::F)
+ y := rootOf(rec.prim)
+ map(eval(#1, retract(y)@K, rec.primelt),
+ lfintegrate(eval(f, [kx,k], [(rec.pol1) y, (rec.pol2) y]), x))
+ unknownint(f, x)
+
+ alglfextint(f, k, l, x, g) ==
+ symbolIfCan(kx := ksec(k,l,x)) case SE => palgextint(f, kx, k, g)
+ has?(operator kx, ALGOP) =>
+ rec := primitiveElement(kx::F, k::F)
+ y := rootOf(rec.prim)
+ lrhs := [(rec.pol1) y, (rec.pol2) y]$List(F)
+ (u := lfextendedint(eval(f, [kx, k], lrhs), x,
+ eval(g, [kx, k], lrhs))) case "failed" => "failed"
+ ky := retract(y)@K
+ r := u::Record(ratpart:F, coeff:F)
+ [eval(r.ratpart,ky,rec.primelt), eval(r.coeff,ky,rec.primelt)]
+ is?(kx, "exp"::SE) or is?(kx, "log"::SE) => FAIL
+ unkextint(f, x, g)
+
+ alglflimint(f, k, l, x, lu) ==
+ symbolIfCan(kx := ksec(k,l,x)) case SE => palglimint(f, kx, k, lu)
+ has?(operator kx, ALGOP) =>
+ rec := primitiveElement(kx::F, k::F)
+ y := rootOf(rec.prim)
+ lrhs := [(rec.pol1) y, (rec.pol2) y]$List(F)
+ (u := lflimitedint(eval(f, [kx, k], lrhs), x,
+ map(eval(#1, [kx, k], lrhs), lu))) case "failed" => "failed"
+ ky := retract(y)@K
+ r := u::Record(mainpart:F, limitedlogs:LLG)
+ [eval(r.mainpart, ky, rec.primelt),
+ [[eval(rc.coeff, ky, rec.primelt),
+ eval(rc.logand,ky, rec.primelt)] for rc in r.limitedlogs]]
+ is?(kx, "exp"::SE) or is?(kx, "log"::SE) => FAIL
+ unklimint(f, x, lu)
+
+ if R has Join(ConvertibleTo Pattern Integer, PatternMatchable Integer)
+ and F has Join(LiouvillianFunctionCategory, RetractableTo SE) then
+ import PatternMatchIntegration(R, F)
+ lfintegrate(f, x) == intPatternMatch(f, x, lfintegrate0, pmintegrate)
+
+ else lfintegrate(f, x) == lfintegrate0(f, x)
+
+ lfintegrate0(f, x) ==
+ zero? f => 0
+ xf := x::F
+ empty?(l := varselect(kernels f, x)) => (xf * f)::IR
+ symbolIfCan(k := kmax l) case SE =>
+ map(multivariate(#1, k), integrate univariate(f, k))
+ is?(k, "tan"::SE) => addx(tanint(f, x, k), xf)
+ is?(k, "exp"::SE) => addx(expint(f, x, k), xf)
+ prim?(k, x) => addx(primint(f, x, k), xf)
+ has?(operator k, ALGOP) => alglfint(f, k, l, x)
+ unknownint(f, x)
+
+ addx(i, x) ==
+ elem? i => i
+ mkAnswer(ratpart i, logpart i,
+ [[ne.integrand, x] for ne in notelem i])
+
+ tryChangeVar(f, t, x) ==
+ z := new()$Symbol
+ g := subst(f / differentiate(t::F, x), [t], [z::F])
+ freeOf?(g, x) => -- can we do change of variables?
+ map(eval(#1, kernel z, t::F), lfintegrate(g, z))
+ "failed"
+
+ algexpint(f, t, y, x) ==
+ (u := tryChangeVar(f, t, x)) case IR => u::IR
+ algint(f, t, y, differentiate(#1, differentiate(#1, x),
+ monomial(differentiate(first argument t, x), 1)))
+
+ algprimint(f, t, y, x) ==
+ (u := tryChangeVar(f, t, x)) case IR => u::IR
+ algint(f, t, y, differentiate(#1, differentiate(#1, x),
+ differentiate(t::F, x)::UP))
+
+ lfextendedint(f, x, g) ==
+ empty?(l := varselect(kernels f, x)) => [x::F * f, 0]
+ symbolIfCan(k := kmax(l := union(l, varselect(kernels g, x))))
+ case SE =>
+ map(multivariate(#1, k), extendedint(univariate(f, k),
+ univariate(g, k)))
+ is?(k, "exp"::SE) => expextint(f, x, k, g)
+ prim?(k, x) => primextint(f, x, k, g)
+ has?(operator k, ALGOP) => alglfextint(f, k, l, x, g)
+ unkextint(f, x, g)
+
+ lflimitedint(f, x, lu) ==
+ empty?(l := varselect(kernels f, x)) => [x::F * f, empty()]
+ symbolIfCan(k := kmax(l := union(l, vark(lu, x)))) case SE =>
+ map(multivariate(#1, k), limitedint(univariate(f, k),
+ [univariate(u, k) for u in lu]))
+ is?(k, "exp"::SE) => explimint(f, x, k, lu)
+ prim?(k, x) => primlimint(f, x, k, lu)
+ has?(operator k, ALGOP) => alglflimint(f, k, l, x, lu)
+ unklimint(f, x, lu)
+
+ lfinfieldint(f, x) ==
+ (u := lfextendedint(f, x, 0)) case "failed" => "failed"
+ u.ratpart
+
+ primextint(f, x, k, g) ==
+ lk := varselect([a for a in tower f
+ | k ^= a and is?(a, "log"::SE)], x)
+ (u1 := primextendedint(univariate(f, k), differentiate(#1,
+ differentiate(#1, x), differentiate(k::F, x)::UP),
+ lfextlimint(#1, x, k, lk), univariate(g, k))) case "failed"
+ => "failed"
+ u1 case FF =>
+ [multivariate(u1.ratpart, k), multivariate(u1.coeff, k)]
+ (u2 := lfextendedint(u1.a0, x, g)) case "failed" => "failed"
+ [multivariate(u1.answer, k) + u2.ratpart, u2.coeff]
+
+ expextint(f, x, k, g) ==
+ (u1 := expextendedint(univariate(f, k), differentiate(#1,
+ differentiate(#1, x),
+ monomial(differentiate(first argument k, x), 1)),
+ rischDE(#1, first argument k, #2, x, lflimitedint(#1, x, #2),
+ lfextendedint(#1, x, #2)), univariate(g, k)))
+ case "failed" => "failed"
+ u1 case FF =>
+ [multivariate(u1.ratpart, k), multivariate(u1.coeff, k)]
+ (u2 := lfextendedint(u1.a0, x, g)) case "failed" => "failed"
+ [multivariate(u1.answer, k) + u2.ratpart, u2.coeff]
+
+ primint(f, x, k) ==
+ lk := varselect([a for a in tower f
+ | k ^= a and is?(a, "log"::SE)], x)
+ r1 := primintegrate(univariate(f, k), differentiate(#1,
+ differentiate(#1, x), differentiate(k::F, x)::UP),
+ lfextlimint(#1, x, k, lk))
+ map(multivariate(#1, k), r1.answer) + lfintegrate(r1.a0, x)
+
+ lfextlimint(f, x, k, lk) ==
+ not((u1 := lfextendedint(f, x, differentiate(k::F, x)))
+ case "failed") => u1
+ twr := tower f
+ empty?(lg := [kk for kk in lk | not member?(kk, twr)]) => "failed"
+ is?(k, "log"::SE) =>
+ (u2 := lflimitedint(f, x,
+ [first argument u for u in union(lg, [k])])) case "failed"
+ => "failed"
+ cf := cfind(first argument k, u2.limitedlogs)
+ [u2.mainpart - cf * k::F +
+ +/[c.coeff * log(c.logand) for c in u2.limitedlogs], cf]
+ "failed"
+
+ cfind(f, l) ==
+ for u in l repeat
+ f = u.logand => return u.coeff
+ 0
+
+ expint(f, x, k) ==
+ eta := first argument k
+ r1 := expintegrate(univariate(f, k), differentiate(#1,
+ differentiate(#1, x), monomial(differentiate(eta, x), 1)),
+ rischDE(#1, eta, #2, x, lflimitedint(#1, x, #2),
+ lfextendedint(#1, x, #2)))
+ map(multivariate(#1, k), r1.answer) + lfintegrate(r1.a0, x)
+
+ primlimint(f, x, k, lu) ==
+ lk := varselect([a for a in tower f
+ | k ^= a and is?(a, "log"::SE)], x)
+ (u1 := primlimitedint(univariate(f, k), differentiate(#1,
+ differentiate(#1, x), differentiate(k::F, x)::UP),
+ lfextlimint(#1, x, k, lk), [univariate(u, k) for u in lu]))
+ case "failed" => "failed"
+ l := [[multivariate(lg.coeff, k),multivariate(lg.logand, k)]
+ for lg in u1.answer.limitedlogs]$LLG
+ (u2 := lflimitedint(u1.a0, x, lu)) case "failed" => "failed"
+ [multivariate(u1.answer.mainpart, k) + u2.mainpart,
+ concat(u2.limitedlogs, l)]
+
+ explimint(f, x, k, lu) ==
+ eta := first argument k
+ (u1 := explimitedint(univariate(f, k), differentiate(#1,
+ differentiate(#1, x), monomial(differentiate(eta, x), 1)),
+ rischDE(#1, eta, #2, x,
+ lflimitedint(#1, x, #2), lfextendedint(#1, x, #2)),
+ [univariate(u, k) for u in lu])) case "failed" => "failed"
+ l := [[multivariate(lg.coeff, k),multivariate(lg.logand, k)]
+ for lg in u1.answer.limitedlogs]$LLG
+ (u2 := lflimitedint(u1.a0, x, lu)) case "failed" => "failed"
+ [multivariate(u1.answer.mainpart, k) + u2.mainpart,
+ concat(u2.limitedlogs, l)]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg intaf efstruc rdeef intpm INTEF irexpand integrat
+
+<<package INTEF ElementaryIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/integer.spad.pamphlet b/src/algebra/integer.spad.pamphlet
new file mode 100644
index 00000000..3aa12fa9
--- /dev/null
+++ b/src/algebra/integer.spad.pamphlet
@@ -0,0 +1,865 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra integer.spad}
+\author{James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTSLPE IntegerSolveLinearPolynomialEquation}
+<<package INTSLPE IntegerSolveLinearPolynomialEquation>>=
+)abbrev package INTSLPE IntegerSolveLinearPolynomialEquation
+++ Author: Davenport
+++ Date Created: 1991
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides the implementation for the
+++ \spadfun{solveLinearPolynomialEquation}
+++ operation over the integers. It uses a lifting technique
+++ from the package GenExEuclid
+IntegerSolveLinearPolynomialEquation(): C ==T
+ where
+ ZP ==> SparseUnivariatePolynomial Integer
+ C == with
+ solveLinearPolynomialEquation: (List ZP,ZP) -> Union(List ZP,"failed")
+ ++ solveLinearPolynomialEquation([f1, ..., fn], g)
+ ++ (where the fi are relatively prime to each other)
+ ++ returns a list of ai such that
+ ++ \spad{g/prod fi = sum ai/fi}
+ ++ or returns "failed" if no such list of ai's exists.
+ T == add
+ oldlp:List ZP := []
+ slpePrime:Integer:=(2::Integer)
+ oldtable:Vector List ZP := empty()
+ solveLinearPolynomialEquation(lp,p) ==
+ if (oldlp ^= lp) then
+ -- we have to generate a new table
+ deg:= _+/[degree u for u in lp]
+ ans:Union(Vector List ZP,"failed"):="failed"
+ slpePrime:=2147483647::Integer -- 2**31 -1 : a prime
+ -- a good test case for this package is
+ -- ([x**31-1,x-2],2)
+ while (ans case "failed") repeat
+ ans:=tablePow(deg,slpePrime,lp)$GenExEuclid(Integer,ZP)
+ if (ans case "failed") then
+ slpePrime:= prevPrime(slpePrime)$IntegerPrimesPackage(Integer)
+ oldtable:=(ans:: Vector List ZP)
+ answer:=solveid(p,slpePrime,oldtable)
+ answer
+
+@
+\section{domain INT Integer}
+The function {\bf one?} has been rewritten back to its original form.
+The NAG version called a lisp primitive that exists only in Codemist
+Common Lisp and is not defined in Common Lisp.
+<<domain INT Integer>>=
+)abbrev domain INT Integer
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations:
+++ Related Constructors:
+++ Keywords: integer
+++ Description: \spadtype{Integer} provides the domain of arbitrary precision
+++ integers.
+
+Integer: Join(IntegerNumberSystem, ConvertibleTo String, OpenMath) with
+ random : % -> %
+ ++ random(n) returns a random integer from 0 to \spad{n-1}.
+ canonical
+ ++ mathematical equality is data structure equality.
+ canonicalsClosed
+ ++ two positives multiply to give positive.
+ noetherian
+ ++ ascending chain condition on ideals.
+ infinite
+ ++ nextItem never returns "failed".
+ == add
+ ZP ==> SparseUnivariatePolynomial %
+ ZZP ==> SparseUnivariatePolynomial Integer
+ x,y: %
+ n: NonNegativeInteger
+
+ writeOMInt(dev: OpenMathDevice, x: %): Void ==
+ if x < 0 then
+ OMputApp(dev)
+ OMputSymbol(dev, "arith1", "unary__minus")
+ OMputInteger(dev, (-x) pretend Integer)
+ OMputEndApp(dev)
+ else
+ OMputInteger(dev, x pretend Integer)
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMInt(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMInt(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMInt(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMInt(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ zero? x == ZEROP(x)$Lisp
+-- one? x == ONEP(x)$Lisp
+ one? x == x = 1
+ 0 == 0$Lisp
+ 1 == 1$Lisp
+ base() == 2$Lisp
+ copy x == x
+ inc x == x + 1
+ dec x == x - 1
+ hash x == SXHASH(x)$Lisp
+ negative? x == MINUSP(x)$Lisp
+ coerce(x):OutputForm == outputForm(x pretend Integer)
+ coerce(m:Integer):% == m pretend %
+ convert(x:%):Integer == x pretend Integer
+ length a == INTEGER_-LENGTH(a)$Lisp
+ addmod(a, b, p) ==
+ (c:=a + b) >= p => c - p
+ c
+ submod(a, b, p) ==
+ (c:=a - b) < 0 => c + p
+ c
+ mulmod(a, b, p) == (a * b) rem p
+ convert(x:%):Float == coerce(x pretend Integer)$Float
+ convert(x:%):DoubleFloat == coerce(x pretend Integer)$DoubleFloat
+ convert(x:%):InputForm == convert(x pretend Integer)$InputForm
+ convert(x:%):String == string(x pretend Integer)$String
+
+ latex(x:%):String ==
+ s : String := string(x pretend Integer)$String
+ (-1 < (x pretend Integer)) and ((x pretend Integer) < 10) => s
+ concat("{", concat(s, "}")$String)$String
+
+ positiveRemainder(a, b) ==
+ negative?(r := a rem b) =>
+ negative? b => r - b
+ r + b
+ r
+
+ reducedSystem(m:Matrix %):Matrix(Integer) ==
+ m pretend Matrix(Integer)
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix(Integer), vec:Vector(Integer)) ==
+ [m pretend Matrix(Integer), vec pretend Vector(Integer)]
+
+ abs(x) == ABS(x)$Lisp
+ random() == random()$Lisp
+ random(x) == RANDOM(x)$Lisp
+ x = y == EQL(x,y)$Lisp
+ x < y == (x<y)$Lisp
+ - x == (-x)$Lisp
+ x + y == (x+y)$Lisp
+ x - y == (x-y)$Lisp
+ x * y == (x*y)$Lisp
+ (m:Integer) * (y:%) == (m*y)$Lisp -- for subsumption problem
+ x ** n == EXPT(x,n)$Lisp
+ odd? x == ODDP(x)$Lisp
+ max(x,y) == MAX(x,y)$Lisp
+ min(x,y) == MIN(x,y)$Lisp
+ divide(x,y) == DIVIDE2(x,y)$Lisp
+ x quo y == QUOTIENT2(x,y)$Lisp
+ x rem y == REMAINDER2(x,y)$Lisp
+ shift(x, y) == ASH(x,y)$Lisp
+ x exquo y ==
+ zero? y => "failed"
+ zero?(x rem y) => x quo y
+ "failed"
+-- recip(x) == if one? x or x=-1 then x else "failed"
+ recip(x) == if (x = 1) or x=-1 then x else "failed"
+ gcd(x,y) == GCD(x,y)$Lisp
+ UCA ==> Record(unit:%,canonical:%,associate:%)
+ unitNormal x ==
+ x < 0 => [-1,-x,-1]$UCA
+ [1,x,1]$UCA
+ unitCanonical x == abs x
+ solveLinearPolynomialEquation(lp:List ZP,p:ZP):Union(List ZP,"failed") ==
+ solveLinearPolynomialEquation(lp pretend List ZZP,
+ p pretend ZZP)$IntegerSolveLinearPolynomialEquation pretend
+ Union(List ZP,"failed")
+ squareFreePolynomial(p:ZP):Factored ZP ==
+ squareFree(p)$UnivariatePolynomialSquareFree(%,ZP)
+ factorPolynomial(p:ZP):Factored ZP ==
+ -- GaloisGroupFactorizer doesn't factor the content
+ -- so we have to do this by hand
+ pp:=primitivePart p
+ leadingCoefficient pp = leadingCoefficient p =>
+ factor(p)$GaloisGroupFactorizer(ZP)
+ mergeFactors(factor(pp)$GaloisGroupFactorizer(ZP),
+ map(#1::ZP,
+ factor((leadingCoefficient p exquo
+ leadingCoefficient pp)
+ ::%))$FactoredFunctions2(%,ZP)
+ )$FactoredFunctionUtilities(ZP)
+ factorSquareFreePolynomial(p:ZP):Factored ZP ==
+ factorSquareFree(p)$GaloisGroupFactorizer(ZP)
+ gcdPolynomial(p:ZP, q:ZP):ZP ==
+ zero? p => unitCanonical q
+ zero? q => unitCanonical p
+ gcd([p,q])$HeuGcd(ZP)
+-- myNextPrime: (%,NonNegativeInteger) -> %
+-- myNextPrime(x,n) ==
+-- nextPrime(x)$IntegerPrimesPackage(%)
+-- TT:=InnerModularGcd(%,ZP,67108859 pretend %,myNextPrime)
+-- gcdPolynomial(p,q) == modularGcd(p,q)$TT
+
+@
+\section{INT.lsp BOOTSTRAP}
+{\bf INT} depends on {\bf OINTDOM} which depends on {\bf ORDRING}
+which depends on {\bf INT}.
+We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf INT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf INT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<INT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |INT;writeOMInt| (|dev| |x| |$|) (SEQ (COND ((|<| |x| 0) (SEQ (SPADCALL |dev| (QREFELT |$| 8)) (SPADCALL |dev| "arith1" "unary_minus" (QREFELT |$| 10)) (SPADCALL |dev| (|-| |x|) (QREFELT |$| 12)) (EXIT (SPADCALL |dev| (QREFELT |$| 13))))) ((QUOTE T) (SPADCALL |dev| |x| (QREFELT |$| 12))))))
+
+(DEFUN |INT;OMwrite;$S;2| (|x| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |INT;OMwrite;$S;2|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |INT;OMwrite;$S;2|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 15)) (QREFELT |$| 16)) |INT;OMwrite;$S;2|) (SPADCALL |dev| (QREFELT |$| 17)) (|INT;writeOMInt| |dev| |x| |$|) (SPADCALL |dev| (QREFELT |$| 18)) (SPADCALL |dev| (QREFELT |$| 19)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |INT;OMwrite;$S;2|) (EXIT |s|)))))
+
+(DEFUN |INT;OMwrite;$BS;3| (|x| |wholeObj| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |INT;OMwrite;$BS;3|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |INT;OMwrite;$BS;3|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 15)) (QREFELT |$| 16)) |INT;OMwrite;$BS;3|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 17)))) (|INT;writeOMInt| |dev| |x| |$|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 18)))) (SPADCALL |dev| (QREFELT |$| 19)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |INT;OMwrite;$BS;3|) (EXIT |s|)))))
+
+(DEFUN |INT;OMwrite;Omd$V;4| (|dev| |x| |$|) (SEQ (SPADCALL |dev| (QREFELT |$| 17)) (|INT;writeOMInt| |dev| |x| |$|) (EXIT (SPADCALL |dev| (QREFELT |$| 18)))))
+
+(DEFUN |INT;OMwrite;Omd$BV;5| (|dev| |x| |wholeObj| |$|) (SEQ (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 17)))) (|INT;writeOMInt| |dev| |x| |$|) (EXIT (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 18)))))))
+
+(PUT (QUOTE |INT;zero?;$B;6|) (QUOTE |SPADreplace|) (QUOTE ZEROP))
+
+(DEFUN |INT;zero?;$B;6| (|x| |$|) (ZEROP |x|))
+
+(PUT (QUOTE |INT;Zero;$;7|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL 0)))
+
+(DEFUN |INT;Zero;$;7| (|$|) 0)
+
+(PUT (QUOTE |INT;One;$;8|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL 1)))
+
+(DEFUN |INT;One;$;8| (|$|) 1)
+
+(PUT (QUOTE |INT;base;$;9|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL 2)))
+
+(DEFUN |INT;base;$;9| (|$|) 2)
+
+(PUT (QUOTE |INT;copy;2$;10|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) |x|)))
+
+(DEFUN |INT;copy;2$;10| (|x| |$|) |x|)
+
+(PUT (QUOTE |INT;inc;2$;11|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) (|+| |x| 1))))
+
+(DEFUN |INT;inc;2$;11| (|x| |$|) (|+| |x| 1))
+
+(PUT (QUOTE |INT;dec;2$;12|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) (|-| |x| 1))))
+
+(DEFUN |INT;dec;2$;12| (|x| |$|) (|-| |x| 1))
+
+(PUT (QUOTE |INT;hash;2$;13|) (QUOTE |SPADreplace|) (QUOTE SXHASH))
+
+(DEFUN |INT;hash;2$;13| (|x| |$|) (SXHASH |x|))
+
+(PUT (QUOTE |INT;negative?;$B;14|) (QUOTE |SPADreplace|) (QUOTE MINUSP))
+
+(DEFUN |INT;negative?;$B;14| (|x| |$|) (MINUSP |x|))
+
+(DEFUN |INT;coerce;$Of;15| (|x| |$|) (SPADCALL |x| (QREFELT |$| 35)))
+
+(PUT (QUOTE |INT;coerce;2$;16|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|m|) |m|)))
+
+(DEFUN |INT;coerce;2$;16| (|m| |$|) |m|)
+
+(PUT (QUOTE |INT;convert;2$;17|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) |x|)))
+
+(DEFUN |INT;convert;2$;17| (|x| |$|) |x|)
+
+(PUT (QUOTE |INT;length;2$;18|) (QUOTE |SPADreplace|) (QUOTE |INTEGER-LENGTH|))
+
+(DEFUN |INT;length;2$;18| (|a| |$|) (|INTEGER-LENGTH| |a|))
+
+(DEFUN |INT;addmod;4$;19| (|a| |b| |p| |$|) (PROG (|c| #1=#:G86338) (RETURN (SEQ (EXIT (SEQ (SEQ (LETT |c| (|+| |a| |b|) |INT;addmod;4$;19|) (EXIT (COND ((NULL (|<| |c| |p|)) (PROGN (LETT #1# (|-| |c| |p|) |INT;addmod;4$;19|) (GO #1#)))))) (EXIT |c|))) #1# (EXIT #1#)))))
+
+(DEFUN |INT;submod;4$;20| (|a| |b| |p| |$|) (PROG (|c|) (RETURN (SEQ (LETT |c| (|-| |a| |b|) |INT;submod;4$;20|) (EXIT (COND ((|<| |c| 0) (|+| |c| |p|)) ((QUOTE T) |c|)))))))
+
+(DEFUN |INT;mulmod;4$;21| (|a| |b| |p| |$|) (REMAINDER2 (|*| |a| |b|) |p|))
+
+(DEFUN |INT;convert;$F;22| (|x| |$|) (SPADCALL |x| (QREFELT |$| 44)))
+
+(PUT (QUOTE |INT;convert;$Df;23|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) (FLOAT |x| |MOST-POSITIVE-LONG-FLOAT|))))
+
+(DEFUN |INT;convert;$Df;23| (|x| |$|) (FLOAT |x| |MOST-POSITIVE-LONG-FLOAT|))
+
+(DEFUN |INT;convert;$If;24| (|x| |$|) (SPADCALL |x| (QREFELT |$| 49)))
+
+(PUT (QUOTE |INT;convert;$S;25|) (QUOTE |SPADreplace|) (QUOTE STRINGIMAGE))
+
+(DEFUN |INT;convert;$S;25| (|x| |$|) (STRINGIMAGE |x|))
+
+(DEFUN |INT;latex;$S;26| (|x| |$|) (PROG (|s|) (RETURN (SEQ (LETT |s| (STRINGIMAGE |x|) |INT;latex;$S;26|) (COND ((|<| -1 |x|) (COND ((|<| |x| 10) (EXIT |s|))))) (EXIT (STRCONC "{" (STRCONC |s| "}")))))))
+
+(DEFUN |INT;positiveRemainder;3$;27| (|a| |b| |$|) (PROG (|r|) (RETURN (COND ((MINUSP (LETT |r| (REMAINDER2 |a| |b|) |INT;positiveRemainder;3$;27|)) (COND ((MINUSP |b|) (|-| |r| |b|)) ((QUOTE T) (|+| |r| |b|)))) ((QUOTE T) |r|)))))
+
+(PUT (QUOTE |INT;reducedSystem;2M;28|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|m|) |m|)))
+
+(DEFUN |INT;reducedSystem;2M;28| (|m| |$|) |m|)
+
+(DEFUN |INT;reducedSystem;MVR;29| (|m| |v| |$|) (CONS |m| (QUOTE |vec|)))
+
+(PUT (QUOTE |INT;abs;2$;30|) (QUOTE |SPADreplace|) (QUOTE ABS))
+
+(DEFUN |INT;abs;2$;30| (|x| |$|) (ABS |x|))
+
+(PUT (QUOTE |INT;random;$;31|) (QUOTE |SPADreplace|) (QUOTE |random|))
+
+(DEFUN |INT;random;$;31| (|$|) (|random|))
+
+(PUT (QUOTE |INT;random;2$;32|) (QUOTE |SPADreplace|) (QUOTE RANDOM))
+
+(DEFUN |INT;random;2$;32| (|x| |$|) (RANDOM |x|))
+
+(PUT (QUOTE |INT;=;2$B;33|) (QUOTE |SPADreplace|) (QUOTE EQL))
+
+(DEFUN |INT;=;2$B;33| (|x| |y| |$|) (EQL |x| |y|))
+
+(PUT (QUOTE |INT;<;2$B;34|) (QUOTE |SPADreplace|) (QUOTE |<|))
+
+(DEFUN |INT;<;2$B;34| (|x| |y| |$|) (|<| |x| |y|))
+
+(PUT (QUOTE |INT;-;2$;35|) (QUOTE |SPADreplace|) (QUOTE |-|))
+
+(DEFUN |INT;-;2$;35| (|x| |$|) (|-| |x|))
+
+(PUT (QUOTE |INT;+;3$;36|) (QUOTE |SPADreplace|) (QUOTE |+|))
+
+(DEFUN |INT;+;3$;36| (|x| |y| |$|) (|+| |x| |y|))
+
+(PUT (QUOTE |INT;-;3$;37|) (QUOTE |SPADreplace|) (QUOTE |-|))
+
+(DEFUN |INT;-;3$;37| (|x| |y| |$|) (|-| |x| |y|))
+
+(PUT (QUOTE |INT;*;3$;38|) (QUOTE |SPADreplace|) (QUOTE |*|))
+
+(DEFUN |INT;*;3$;38| (|x| |y| |$|) (|*| |x| |y|))
+
+(PUT (QUOTE |INT;*;3$;39|) (QUOTE |SPADreplace|) (QUOTE |*|))
+
+(DEFUN |INT;*;3$;39| (|m| |y| |$|) (|*| |m| |y|))
+
+(PUT (QUOTE |INT;**;$Nni$;40|) (QUOTE |SPADreplace|) (QUOTE EXPT))
+
+(DEFUN |INT;**;$Nni$;40| (|x| |n| |$|) (EXPT |x| |n|))
+
+(PUT (QUOTE |INT;odd?;$B;41|) (QUOTE |SPADreplace|) (QUOTE ODDP))
+
+(DEFUN |INT;odd?;$B;41| (|x| |$|) (ODDP |x|))
+
+(PUT (QUOTE |INT;max;3$;42|) (QUOTE |SPADreplace|) (QUOTE MAX))
+
+(DEFUN |INT;max;3$;42| (|x| |y| |$|) (MAX |x| |y|))
+
+(PUT (QUOTE |INT;min;3$;43|) (QUOTE |SPADreplace|) (QUOTE MIN))
+
+(DEFUN |INT;min;3$;43| (|x| |y| |$|) (MIN |x| |y|))
+
+(PUT (QUOTE |INT;divide;2$R;44|) (QUOTE |SPADreplace|) (QUOTE DIVIDE2))
+
+(DEFUN |INT;divide;2$R;44| (|x| |y| |$|) (DIVIDE2 |x| |y|))
+
+(PUT (QUOTE |INT;quo;3$;45|) (QUOTE |SPADreplace|) (QUOTE QUOTIENT2))
+
+(DEFUN |INT;quo;3$;45| (|x| |y| |$|) (QUOTIENT2 |x| |y|))
+
+(PUT (QUOTE |INT;rem;3$;46|) (QUOTE |SPADreplace|) (QUOTE REMAINDER2))
+
+(DEFUN |INT;rem;3$;46| (|x| |y| |$|) (REMAINDER2 |x| |y|))
+
+(PUT (QUOTE |INT;shift;3$;47|) (QUOTE |SPADreplace|) (QUOTE ASH))
+
+(DEFUN |INT;shift;3$;47| (|x| |y| |$|) (ASH |x| |y|))
+
+(DEFUN |INT;exquo;2$U;48| (|x| |y| |$|) (COND ((OR (ZEROP |y|) (NULL (ZEROP (REMAINDER2 |x| |y|)))) (CONS 1 "failed")) ((QUOTE T) (CONS 0 (QUOTIENT2 |x| |y|)))))
+
+(DEFUN |INT;recip;$U;49| (|x| |$|) (COND ((OR (EQL |x| 1) (EQL |x| -1)) (CONS 0 |x|)) ((QUOTE T) (CONS 1 "failed"))))
+
+(PUT (QUOTE |INT;gcd;3$;50|) (QUOTE |SPADreplace|) (QUOTE GCD))
+
+(DEFUN |INT;gcd;3$;50| (|x| |y| |$|) (GCD |x| |y|))
+
+(DEFUN |INT;unitNormal;$R;51| (|x| |$|) (COND ((|<| |x| 0) (VECTOR -1 (|-| |x|) -1)) ((QUOTE T) (VECTOR 1 |x| 1))))
+
+(PUT (QUOTE |INT;unitCanonical;2$;52|) (QUOTE |SPADreplace|) (QUOTE ABS))
+
+(DEFUN |INT;unitCanonical;2$;52| (|x| |$|) (ABS |x|))
+
+(DEFUN |INT;solveLinearPolynomialEquation| (|lp| |p| |$|) (SPADCALL |lp| |p| (QREFELT |$| 91)))
+
+(DEFUN |INT;squareFreePolynomial| (|p| |$|) (SPADCALL |p| (QREFELT |$| 95)))
+
+(DEFUN |INT;factorPolynomial| (|p| |$|) (PROG (|pp| #1=#:G86409) (RETURN (SEQ (LETT |pp| (SPADCALL |p| (QREFELT |$| 96)) |INT;factorPolynomial|) (EXIT (COND ((EQL (SPADCALL |pp| (QREFELT |$| 97)) (SPADCALL |p| (QREFELT |$| 97))) (SPADCALL |p| (QREFELT |$| 99))) ((QUOTE T) (SPADCALL (SPADCALL |pp| (QREFELT |$| 99)) (SPADCALL (CONS (FUNCTION |INT;factorPolynomial!0|) |$|) (SPADCALL (PROG2 (LETT #1# (SPADCALL (SPADCALL |p| (QREFELT |$| 97)) (SPADCALL |pp| (QREFELT |$| 97)) (QREFELT |$| 81)) |INT;factorPolynomial|) (QCDR #1#) (|check-union| (QEQCAR #1# 0) |$| #1#)) (QREFELT |$| 102)) (QREFELT |$| 106)) (QREFELT |$| 108)))))))))
+
+(DEFUN |INT;factorPolynomial!0| (|#1| |$|) (SPADCALL |#1| (QREFELT |$| 100)))
+
+(DEFUN |INT;factorSquareFreePolynomial| (|p| |$|) (SPADCALL |p| (QREFELT |$| 109)))
+
+(DEFUN |INT;gcdPolynomial;3Sup;57| (|p| |q| |$|) (COND ((SPADCALL |p| (QREFELT |$| 110)) (SPADCALL |q| (QREFELT |$| 111))) ((SPADCALL |q| (QREFELT |$| 110)) (SPADCALL |p| (QREFELT |$| 111))) ((QUOTE T) (SPADCALL (LIST |p| |q|) (QREFELT |$| 114)))))
+
+(DEFUN |Integer| NIL (PROG NIL (RETURN (PROG (#1=#:G86434) (RETURN (COND ((LETT #1# (HGET |$ConstructorCache| (QUOTE |Integer|)) |Integer|) (|CDRwithIncrement| (CDAR #1#))) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (CDDAR (HPUT |$ConstructorCache| (QUOTE |Integer|) (LIST (CONS NIL (CONS 1 (|Integer;|)))))) (LETT #1# T |Integer|)) (COND ((NOT #1#) (HREM |$ConstructorCache| (QUOTE |Integer|))))))))))))
+
+(DEFUN |Integer;| NIL (PROG (|dv$| |$| |pv$|) (RETURN (PROGN (LETT |dv$| (QUOTE (|Integer|)) . #1=(|Integer|)) (LETT |$| (GETREFV 130) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|haddProp| |$ConstructorCache| (QUOTE |Integer|) NIL (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 69 (QSETREFV |$| 68 (CONS (|dispatchFunction| |INT;*;3$;39|) |$|))) |$|))))
+
+(MAKEPROP (QUOTE |Integer|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|Void|) (|OpenMathDevice|) (0 . |OMputApp|) (|String|) (5 . |OMputSymbol|) (|Integer|) (12 . |OMputInteger|) (18 . |OMputEndApp|) (|OpenMathEncoding|) (23 . |OMencodingXML|) (27 . |OMopenString|) (33 . |OMputObject|) (38 . |OMputEndObject|) (43 . |OMclose|) |INT;OMwrite;$S;2| (|Boolean|) |INT;OMwrite;$BS;3| |INT;OMwrite;Omd$V;4| |INT;OMwrite;Omd$BV;5| |INT;zero?;$B;6| (CONS IDENTITY (FUNCALL (|dispatchFunction| |INT;Zero;$;7|) |$|)) (CONS IDENTITY (FUNCALL (|dispatchFunction| |INT;One;$;8|) |$|)) |INT;base;$;9| |INT;copy;2$;10| |INT;inc;2$;11| |INT;dec;2$;12| |INT;hash;2$;13| |INT;negative?;$B;14| (|OutputForm|) (48 . |outputForm|) |INT;coerce;$Of;15| |INT;coerce;2$;16| |INT;convert;2$;17| |INT;length;2$;18| |INT;addmod;4$;19| |INT;submod;4$;20| |INT;mulmod;4$;21| (|Float|) (53 . |coerce|) |INT;convert;$F;22| (|DoubleFloat|) |INT;convert;$Df;23| (|InputForm|) (58 . |convert|) |INT;convert;$If;24| |INT;convert;$S;25| |INT;latex;$S;26| |INT;positiveRemainder;3$;27| (|Matrix| 11) (|Matrix| |$|) |INT;reducedSystem;2M;28| (|Record| (|:| |mat| 54) (|:| |vec| (|Vector| 11))) (|Vector| |$|) |INT;reducedSystem;MVR;29| |INT;abs;2$;30| |INT;random;$;31| |INT;random;2$;32| |INT;=;2$B;33| |INT;<;2$B;34| |INT;-;2$;35| |INT;+;3$;36| |INT;-;3$;37| NIL NIL (|NonNegativeInteger|) |INT;**;$Nni$;40| |INT;odd?;$B;41| |INT;max;3$;42| |INT;min;3$;43| (|Record| (|:| |quotient| |$|) (|:| |remainder| |$|)) |INT;divide;2$R;44| |INT;quo;3$;45| |INT;rem;3$;46| |INT;shift;3$;47| (|Union| |$| (QUOTE "failed")) |INT;exquo;2$U;48| |INT;recip;$U;49| |INT;gcd;3$;50| (|Record| (|:| |unit| |$|) (|:| |canonical| |$|) (|:| |associate| |$|)) |INT;unitNormal;$R;51| |INT;unitCanonical;2$;52| (|Union| 88 (QUOTE "failed")) (|List| 89) (|SparseUnivariatePolynomial| 11) (|IntegerSolveLinearPolynomialEquation|) (63 . |solveLinearPolynomialEquation|) (|Factored| 93) (|SparseUnivariatePolynomial| |$$|) (|UnivariatePolynomialSquareFree| |$$| 93) (69 . |squareFree|) (74 . |primitivePart|) (79 . |leadingCoefficient|) (|GaloisGroupFactorizer| 93) (84 . |factor|) (89 . |coerce|) (|Factored| |$|) (94 . |factor|) (|Mapping| 93 |$$|) (|Factored| |$$|) (|FactoredFunctions2| |$$| 93) (99 . |map|) (|FactoredFunctionUtilities| 93) (105 . |mergeFactors|) (111 . |factorSquareFree|) (116 . |zero?|) (121 . |unitCanonical|) (|List| 93) (|HeuGcd| 93) (126 . |gcd|) (|SparseUnivariatePolynomial| |$|) |INT;gcdPolynomial;3Sup;57| (|Union| 118 (QUOTE "failed")) (|Fraction| 11) (|PatternMatchResult| 11 |$|) (|Pattern| 11) (|Union| 11 (QUOTE "failed")) (|Union| 123 (QUOTE "failed")) (|List| |$|) (|Record| (|:| |coef| 123) (|:| |generator| |$|)) (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|)) (|Union| 125 (QUOTE "failed")) (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|) (|:| |generator| |$|)) (|PositiveInteger|) (|SingleInteger|))) (QUOTE #(|~=| 131 |zero?| 137 |unitNormal| 142 |unitCanonical| 147 |unit?| 152 |symmetricRemainder| 157 |subtractIfCan| 163 |submod| 169 |squareFreePart| 176 |squareFree| 181 |sizeLess?| 186 |sign| 192 |shift| 197 |sample| 203 |retractIfCan| 207 |retract| 212 |rem| 217 |reducedSystem| 223 |recip| 234 |rationalIfCan| 239 |rational?| 244 |rational| 249 |random| 254 |quo| 263 |principalIdeal| 269 |prime?| 274 |powmod| 279 |positiveRemainder| 286 |positive?| 292 |permutation| 297 |patternMatch| 303 |one?| 310 |odd?| 315 |nextItem| 320 |negative?| 325 |multiEuclidean| 330 |mulmod| 336 |min| 343 |max| 349 |mask| 355 |length| 360 |lcm| 365 |latex| 376 |invmod| 381 |init| 387 |inc| 391 |hash| 396 |gcdPolynomial| 406 |gcd| 412 |factorial| 423 |factor| 428 |extendedEuclidean| 433 |exquo| 446 |expressIdealMember| 452 |even?| 458 |euclideanSize| 463 |divide| 468 |differentiate| 474 |dec| 485 |copy| 490 |convert| 495 |coerce| 525 |characteristic| 545 |bit?| 549 |binomial| 555 |base| 561 |associates?| 565 |addmod| 571 |abs| 578 |^| 583 |Zero| 595 |One| 599 |OMwrite| 603 D 627 |>=| 638 |>| 644 |=| 650 |<=| 656 |<| 662 |-| 668 |+| 679 |**| 685 |*| 697)) (QUOTE ((|infinite| . 0) (|noetherian| . 0) (|canonicalsClosed| . 0) (|canonical| . 0) (|canonicalUnitNormal| . 0) (|multiplicativeValuation| . 0) (|noZeroDivisors| . 0) ((|commutative| "*") . 0) (|rightUnitary| . 0) (|leftUnitary| . 0) (|unitsKnown| . 0))) (CONS (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))) (CONS (QUOTE #(|IntegerNumberSystem&| |EuclideanDomain&| |UniqueFactorizationDomain&| NIL NIL |GcdDomain&| |IntegralDomain&| |Algebra&| NIL NIL |DifferentialRing&| |OrderedRing&| NIL NIL |Module&| NIL NIL |Ring&| NIL NIL NIL NIL NIL |AbelianGroup&| NIL NIL |AbelianMonoid&| |Monoid&| NIL NIL |OrderedSet&| |AbelianSemiGroup&| |SemiGroup&| NIL |SetCategory&| NIL NIL NIL NIL NIL NIL NIL |RetractableTo&| NIL |BasicType&| NIL)) (CONS (QUOTE #((|IntegerNumberSystem|) (|EuclideanDomain|) (|UniqueFactorizationDomain|) (|PrincipalIdealDomain|) (|OrderedIntegralDomain|) (|GcdDomain|) (|IntegralDomain|) (|Algebra| |$$|) (|CharacteristicZero|) (|LinearlyExplicitRingOver| 11) (|DifferentialRing|) (|OrderedRing|) (|CommutativeRing|) (|EntireRing|) (|Module| |$$|) (|OrderedAbelianGroup|) (|BiModule| |$$| |$$|) (|Ring|) (|OrderedCancellationAbelianMonoid|) (|LeftModule| |$$|) (|Rng|) (|RightModule| |$$|) (|OrderedAbelianMonoid|) (|AbelianGroup|) (|OrderedAbelianSemiGroup|) (|CancellationAbelianMonoid|) (|AbelianMonoid|) (|Monoid|) (|StepThrough|) (|PatternMatchable| 11) (|OrderedSet|) (|AbelianSemiGroup|) (|SemiGroup|) (|RealConstant|) (|SetCategory|) (|OpenMath|) (|ConvertibleTo| 9) (|ConvertibleTo| 43) (|ConvertibleTo| 46) (|CombinatorialFunctionCategory|) (|ConvertibleTo| 120) (|ConvertibleTo| 48) (|RetractableTo| 11) (|ConvertibleTo| 11) (|BasicType|) (|CoercibleTo| 34))) (|makeByteWordVec2| 129 (QUOTE (1 7 6 0 8 3 7 6 0 9 9 10 2 7 6 0 11 12 1 7 6 0 13 0 14 0 15 2 7 0 9 14 16 1 7 6 0 17 1 7 6 0 18 1 7 6 0 19 1 34 0 11 35 1 43 0 11 44 1 48 0 11 49 2 90 87 88 89 91 1 94 92 93 95 1 93 0 0 96 1 93 2 0 97 1 98 92 93 99 1 93 0 2 100 1 0 101 0 102 2 105 92 103 104 106 2 107 92 92 92 108 1 98 92 93 109 1 93 21 0 110 1 93 0 0 111 1 113 93 112 114 2 0 21 0 0 1 1 0 21 0 25 1 0 84 0 85 1 0 0 0 86 1 0 21 0 1 2 0 0 0 0 1 2 0 80 0 0 1 3 0 0 0 0 0 41 1 0 0 0 1 1 0 101 0 1 2 0 21 0 0 1 1 0 11 0 1 2 0 0 0 0 79 0 0 0 1 1 0 121 0 1 1 0 11 0 1 2 0 0 0 0 78 2 0 57 55 58 59 1 0 54 55 56 1 0 80 0 82 1 0 117 0 1 1 0 21 0 1 1 0 118 0 1 1 0 0 0 62 0 0 0 61 2 0 0 0 0 77 1 0 124 123 1 1 0 21 0 1 3 0 0 0 0 0 1 2 0 0 0 0 53 1 0 21 0 1 2 0 0 0 0 1 3 0 119 0 120 119 1 1 0 21 0 1 1 0 21 0 72 1 0 80 0 1 1 0 21 0 33 2 0 122 123 0 1 3 0 0 0 0 0 42 2 0 0 0 0 74 2 0 0 0 0 73 1 0 0 0 1 1 0 0 0 39 1 0 0 123 1 2 0 0 0 0 1 1 0 9 0 52 2 0 0 0 0 1 0 0 0 1 1 0 0 0 30 1 0 0 0 32 1 0 129 0 1 2 0 115 115 115 116 2 0 0 0 0 83 1 0 0 123 1 1 0 0 0 1 1 0 101 0 102 3 0 126 0 0 0 1 2 0 127 0 0 1 2 0 80 0 0 81 2 0 122 123 0 1 1 0 21 0 1 1 0 70 0 1 2 0 75 0 0 76 1 0 0 0 1 2 0 0 0 70 1 1 0 0 0 31 1 0 0 0 29 1 0 9 0 51 1 0 46 0 47 1 0 43 0 45 1 0 48 0 50 1 0 120 0 1 1 0 11 0 38 1 0 0 11 37 1 0 0 11 37 1 0 0 0 1 1 0 34 0 36 0 0 70 1 2 0 21 0 0 1 2 0 0 0 0 1 0 0 0 28 2 0 21 0 0 1 3 0 0 0 0 0 40 1 0 0 0 60 2 0 0 0 70 1 2 0 0 0 128 1 0 0 0 26 0 0 0 27 3 0 6 7 0 21 24 2 0 9 0 21 22 2 0 6 7 0 23 1 0 9 0 20 1 0 0 0 1 2 0 0 0 70 1 2 0 21 0 0 1 2 0 21 0 0 1 2 0 21 0 0 63 2 0 21 0 0 1 2 0 21 0 0 64 2 0 0 0 0 67 1 0 0 0 65 2 0 0 0 0 66 2 0 0 0 70 71 2 0 0 0 128 1 2 0 0 0 0 68 2 0 0 11 0 69 2 0 0 70 0 1 2 0 0 128 0 1)))))) (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |Integer|) (QUOTE NILADIC) T)
+@
+\section{domain NNI NonNegativeInteger}
+<<domain NNI NonNegativeInteger>>=
+)abbrev domain NNI NonNegativeInteger
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations:
+++ Related Constructors:
+++ Keywords: integer
+++ Description: \spadtype{NonNegativeInteger} provides functions for non
+++ negative integers.
+NonNegativeInteger: Join(OrderedAbelianMonoidSup,Monoid) with
+ _quo : (%,%) -> %
+ ++ a quo b returns the quotient of \spad{a} and b, forgetting
+ ++ the remainder.
+ _rem : (%,%) -> %
+ ++ a rem b returns the remainder of \spad{a} and b.
+ gcd : (%,%) -> %
+ ++ gcd(a,b) computes the greatest common divisor of two
+ ++ non negative integers \spad{a} and b.
+ divide: (%,%) -> Record(quotient:%,remainder:%)
+ ++ divide(a,b) returns a record containing both
+ ++ remainder and quotient.
+ _exquo: (%,%) -> Union(%,"failed")
+ ++ exquo(a,b) returns the quotient of \spad{a} and b, or "failed"
+ ++ if b is zero or \spad{a} rem b is zero.
+ shift: (%, Integer) -> %
+ ++ shift(a,i) shift \spad{a} by i bits.
+ random : % -> %
+ ++ random(n) returns a random integer from 0 to \spad{n-1}.
+ commutative("*")
+ ++ commutative("*") means multiplication is commutative : \spad{x*y = y*x}.
+
+ == SubDomain(Integer,#1 >= 0) add
+ x,y:%
+ sup(x,y) == MAX(x,y)$Lisp
+ shift(x:%, n:Integer):% == ASH(x,n)$Lisp
+ subtractIfCan(x, y) ==
+ c:Integer := (x pretend Integer) - (y pretend Integer)
+ c < 0 => "failed"
+ c pretend %
+
+@
+\section{NNI.lsp BOOTSTRAP}
+{\bf NNI} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf NNI}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf NNI.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<NNI.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |$CategoryFrame|
+ (|put|
+ #1=(QUOTE |NonNegativeInteger|)
+ (QUOTE |SuperDomain|)
+ #2=(QUOTE (|Integer|))
+ (|put|
+ #2#
+ #3=(QUOTE |SubDomain|)
+ (CONS
+ (QUOTE
+ (|NonNegativeInteger|
+ COND ((|<| |#1| 0) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+ (DELASC #1# (|get| #2# #3# |$CategoryFrame|)))
+ |$CategoryFrame|)))
+
+(PUT
+ (QUOTE |NNI;sup;3$;1|)
+ (QUOTE |SPADreplace|)
+ (QUOTE MAX))
+
+(DEFUN |NNI;sup;3$;1| (|x| |y| |$|) (MAX |x| |y|))
+
+(PUT
+ (QUOTE |NNI;shift;$I$;2|)
+ (QUOTE |SPADreplace|)
+ (QUOTE ASH))
+
+(DEFUN |NNI;shift;$I$;2| (|x| |n| |$|) (ASH |x| |n|))
+
+(DEFUN |NNI;subtractIfCan;2$U;3| (|x| |y| |$|)
+ (PROG (|c|)
+ (RETURN
+ (SEQ
+ (LETT |c| (|-| |x| |y|) |NNI;subtractIfCan;2$U;3|)
+ (EXIT
+ (COND
+ ((|<| |c| 0) (CONS 1 "failed"))
+ ((QUOTE T) (CONS 0 |c|))))))))
+
+(DEFUN |NonNegativeInteger| NIL
+ (PROG NIL
+ (RETURN
+ (PROG (#1=#:G96708)
+ (RETURN
+ (COND
+ ((LETT #1#
+ (HGET |$ConstructorCache| (QUOTE |NonNegativeInteger|))
+ |NonNegativeInteger|)
+ (|CDRwithIncrement| (CDAR #1#)))
+ ((QUOTE T)
+ (|UNWIND-PROTECT|
+ (PROG1
+ (CDDAR
+ (HPUT
+ |$ConstructorCache|
+ (QUOTE |NonNegativeInteger|)
+ (LIST (CONS NIL (CONS 1 (|NonNegativeInteger;|))))))
+ (LETT #1# T |NonNegativeInteger|))
+ (COND
+ ((NOT #1#)
+ (HREM
+ |$ConstructorCache|
+ (QUOTE |NonNegativeInteger|))))))))))))
+
+(DEFUN |NonNegativeInteger;| NIL
+ (PROG (|dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |dv$| (QUOTE (|NonNegativeInteger|)) . #1=(|NonNegativeInteger|))
+ (LETT |$| (GETREFV 17) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|haddProp|
+ |$ConstructorCache|
+ (QUOTE |NonNegativeInteger|)
+ NIL
+ (CONS 1 |$|))
+ (|stuffDomainSlots| |$|) |$|))))
+
+(MAKEPROP
+ (QUOTE |NonNegativeInteger|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL
+ (|Integer|)
+ |NNI;sup;3$;1|
+ |NNI;shift;$I$;2|
+ (|Union| |$| (QUOTE "failed"))
+ |NNI;subtractIfCan;2$U;3|
+ (|Record| (|:| |quotient| |$|) (|:| |remainder| |$|))
+ (|PositiveInteger|)
+ (|Boolean|)
+ (|NonNegativeInteger|)
+ (|SingleInteger|)
+ (|String|)
+ (|OutputForm|)))
+ (QUOTE
+ #(|~=| 0 |zero?| 6 |sup| 11 |subtractIfCan| 17 |shift| 23 |sample| 29
+ |rem| 33 |recip| 39 |random| 44 |quo| 49 |one?| 55 |min| 60 |max| 66
+ |latex| 72 |hash| 77 |gcd| 82 |exquo| 88 |divide| 94 |coerce| 100
+ |^| 105 |Zero| 117 |One| 121 |>=| 125 |>| 131 |=| 137 |<=| 143
+ |<| 149 |+| 155 |**| 161 |*| 173))
+ (QUOTE (((|commutative| "*") . 0)))
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0 0 0 0 0 0 0 0)))
+ (CONS
+ (QUOTE
+ #(NIL NIL NIL NIL NIL
+ |Monoid&|
+ |AbelianMonoid&|
+ |OrderedSet&|
+ |SemiGroup&|
+ |AbelianSemiGroup&|
+ |SetCategory&|
+ |BasicType&|
+ NIL))
+ (CONS
+ (QUOTE
+ #((|OrderedAbelianMonoidSup|)
+ (|OrderedCancellationAbelianMonoid|)
+ (|OrderedAbelianMonoid|)
+ (|OrderedAbelianSemiGroup|)
+ (|CancellationAbelianMonoid|)
+ (|Monoid|)
+ (|AbelianMonoid|)
+ (|OrderedSet|)
+ (|SemiGroup|)
+ (|AbelianSemiGroup|)
+ (|SetCategory|)
+ (|BasicType|)
+ (|CoercibleTo| 16)))
+ (|makeByteWordVec2| 16
+ (QUOTE
+ (2 0 12 0 0 1 1 0 12 0 1 2 0 0 0 0 6 2 0 8 0 0 9 2 0 0 0 5 7 0 0
+ 0 1 2 0 0 0 0 1 1 0 8 0 1 1 0 0 0 1 2 0 0 0 0 1 1 0 12 0 1 2 0
+ 0 0 0 1 2 0 0 0 0 1 1 0 15 0 1 1 0 14 0 1 2 0 0 0 0 1 2 0 8 0 0
+ 1 2 0 10 0 0 1 1 0 16 0 1 2 0 0 0 11 1 2 0 0 0 13 1 0 0 0 1 0 0
+ 0 1 2 0 12 0 0 1 2 0 12 0 0 1 2 0 12 0 0 1 2 0 12 0 0 1 2 0 12
+ 0 0 1 2 0 0 0 0 1 2 0 0 0 11 1 2 0 0 0 13 1 2 0 0 0 0 1 2 0 0
+ 11 0 1 2 0 0 13 0 1))))))
+ (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |NonNegativeInteger|) (QUOTE NILADIC) T)
+
+@
+\section{domain PI PositiveInteger}
+<<domain PI PositiveInteger>>=
+)abbrev domain PI PositiveInteger
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations:
+++ Related Constructors:
+++ Keywords: positive integer
+++ Description: \spadtype{PositiveInteger} provides functions for
+++ positive integers.
+PositiveInteger: Join(AbelianSemiGroup,OrderedSet,Monoid) with
+ gcd: (%,%) -> %
+ ++ gcd(a,b) computes the greatest common divisor of two
+ ++ positive integers \spad{a} and b.
+ commutative("*")
+ ++ commutative("*") means multiplication is commutative : x*y = y*x
+ == SubDomain(NonNegativeInteger,#1 > 0) add
+ x:%
+ y:%
+
+@
+\section{PI.lsp BOOTSTRAP}
+{\bf PI} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf PI}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf PI.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<PI.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |$CategoryFrame|
+ (|put|
+ #1=(QUOTE |PositiveInteger|)
+ (QUOTE |SuperDomain|)
+ #2=(QUOTE (|NonNegativeInteger|))
+ (|put|
+ #2#
+ #3=(QUOTE |SubDomain|)
+ (CONS
+ (QUOTE (|PositiveInteger| |<| 0 |#1|))
+ (DELASC #1# (|get| #2# #3# |$CategoryFrame|)))
+ |$CategoryFrame|)))
+
+(DEFUN |PositiveInteger| NIL
+ (PROG NIL
+ (RETURN
+ (PROG (#1=#:G96739)
+ (RETURN
+ (COND
+ ((LETT #1#
+ (HGET |$ConstructorCache| (QUOTE |PositiveInteger|))
+ |PositiveInteger|)
+ (|CDRwithIncrement| (CDAR #1#)))
+ ((QUOTE T)
+ (|UNWIND-PROTECT|
+ (PROG1
+ (CDDAR (HPUT |$ConstructorCache| (QUOTE |PositiveInteger|) (LIST (CONS NIL (CONS 1 (|PositiveInteger;|))))))
+ (LETT #1# T |PositiveInteger|))
+ (COND
+ ((NOT #1#)
+ (HREM
+ |$ConstructorCache|
+ (QUOTE |PositiveInteger|))))))))))))
+
+(DEFUN |PositiveInteger;| NIL
+ (PROG (|dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |dv$| (QUOTE (|PositiveInteger|)) . #1=(|PositiveInteger|))
+ (LETT |$| (GETREFV 12) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|haddProp|
+ |$ConstructorCache| (QUOTE |PositiveInteger|) NIL (CONS 1 |$|))
+ (|stuffDomainSlots| |$|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |PositiveInteger|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL
+ (|NonNegativeInteger|)
+ (|PositiveInteger|)
+ (|Boolean|)
+ (|Union| |$| (QUOTE "failed"))
+ (|SingleInteger|)
+ (|String|)
+ (|OutputForm|)))
+ (QUOTE #(|~=| 0 |sample| 6 |recip| 10 |one?| 15 |min| 20 |max| 26
+ |latex| 32 |hash| 37 |gcd| 42 |coerce| 48 |^| 53 |One| 65
+ |>=| 69 |>| 75 |=| 81 |<=| 87 |<| 93 |+| 99 |**| 105 |*| 117))
+ (QUOTE (((|commutative| "*") . 0)))
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0 0)))
+ (CONS
+ (QUOTE #(|Monoid&| |AbelianSemiGroup&| |SemiGroup&| |OrderedSet&|
+ |SetCategory&| |BasicType&| NIL))
+ (CONS
+ (QUOTE #(
+ (|Monoid|)
+ (|AbelianSemiGroup|)
+ (|SemiGroup|)
+ (|OrderedSet|)
+ (|SetCategory|)
+ (|BasicType|)
+ (|CoercibleTo| 11)))
+ (|makeByteWordVec2| 11
+ (QUOTE (2 0 7 0 0 1 0 0 0 1 1 0 8 0 1 1 0 7 0 1 2 0 0 0 0 1 2 0 0 0
+ 0 1 1 0 10 0 1 1 0 9 0 1 2 0 0 0 0 1 1 0 11 0 1 2 0 0 0 6 1
+ 2 0 0 0 5 1 0 0 0 1 2 0 7 0 0 1 2 0 7 0 0 1 2 0 7 0 0 1 2 0
+ 7 0 0 1 2 0 7 0 0 1 2 0 0 0 0 1 2 0 0 0 6 1 2 0 0 0 5 1 2 0
+ 0 0 0 1 2 0 0 6 0 1))))))
+ (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |PositiveInteger|) (QUOTE NILADIC) T)
+
+@
+\section{domain ROMAN RomanNumeral}
+<<domain ROMAN RomanNumeral>>=
+)abbrev domain ROMAN RomanNumeral
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations:
+++ convert, roman
+++ Related Constructors:
+++ Keywords: roman numerals
+++ Description: \spadtype{RomanNumeral} provides functions for converting
+++ integers to roman numerals.
+RomanNumeral(): IntegerNumberSystem with
+ canonical
+ ++ mathematical equality is data structure equality.
+ canonicalsClosed
+ ++ two positives multiply to give positive.
+ noetherian
+ ++ ascending chain condition on ideals.
+ convert: Symbol -> %
+ ++ convert(n) creates a roman numeral for symbol n.
+ roman : Symbol -> %
+ ++ roman(n) creates a roman numeral for symbol n.
+ roman : Integer -> %
+ ++ roman(n) creates a roman numeral for n.
+
+ == Integer add
+ import NumberFormats()
+
+ roman(n:Integer) == n::%
+ roman(sy:Symbol) == convert sy
+ convert(sy:Symbol):% == ScanRoman(string sy)::%
+
+ coerce(r:%):OutputForm ==
+ n := convert(r)@Integer
+ -- okay, we stretch it
+ zero? n => n::OutputForm
+ negative? n => - ((-r)::OutputForm)
+ FormatRoman(n::PositiveInteger)::Symbol::OutputForm
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INTSLPE IntegerSolveLinearPolynomialEquation>>
+<<domain INT Integer>>
+<<domain NNI NonNegativeInteger>>
+<<domain PI PositiveInteger>>
+<<domain ROMAN RomanNumeral>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/integrat.spad.pamphlet b/src/algebra/integrat.spad.pamphlet
new file mode 100644
index 00000000..f70dfe1c
--- /dev/null
+++ b/src/algebra/integrat.spad.pamphlet
@@ -0,0 +1,269 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra integrat.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FSCINT FunctionSpaceComplexIntegration}
+<<package FSCINT FunctionSpaceComplexIntegration>>=
+)abbrev package FSCINT FunctionSpaceComplexIntegration
+++ Top-level complex function integration
+++ Author: Manuel Bronstein
+++ Date Created: 4 February 1988
+++ Date Last Updated: 11 June 1993
+++ Description:
+++ \spadtype{FunctionSpaceComplexIntegration} provides functions for the
+++ indefinite integration of complex-valued functions.
+++ Keywords: function, integration.
+FunctionSpaceComplexIntegration(R, F): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory,
+ AlgebraicallyClosedFunctionSpace R)
+
+ SE ==> Symbol
+ G ==> Complex R
+ FG ==> Expression G
+ IR ==> IntegrationResult F
+
+ Exports ==> with
+ internalIntegrate : (F, SE) -> IR
+ ++ internalIntegrate(f, x) returns the integral of \spad{f(x)dx}
+ ++ where x is viewed as a complex variable.
+ internalIntegrate0: (F, SE) -> IR
+ ++ internalIntegrate0 should be a local function, but is conditional.
+ complexIntegrate : (F, SE) -> F
+ ++ complexIntegrate(f, x) returns the integral of \spad{f(x)dx}
+ ++ where x is viewed as a complex variable.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import ElementaryIntegration(R, F)
+ import ElementaryIntegration(G, FG)
+ import AlgebraicManipulations(R, F)
+ import AlgebraicManipulations(G, FG)
+ import TrigonometricManipulations(R, F)
+ import IntegrationResultToFunction(R, F)
+ import IntegrationResultFunctions2(FG, F)
+ import ElementaryFunctionStructurePackage(R, F)
+ import ElementaryFunctionStructurePackage(G, FG)
+ import InnerTrigonometricManipulations(R, F, FG)
+
+ K2KG: Kernel F -> Kernel FG
+
+ K2KG k == retract(tan F2FG first argument k)@Kernel(FG)
+
+ complexIntegrate(f, x) ==
+ removeConstantTerm(complexExpand internalIntegrate(f, x), x)
+
+ if R has Join(ConvertibleTo Pattern Integer, PatternMatchable Integer)
+ and F has Join(LiouvillianFunctionCategory, RetractableTo SE) then
+ import PatternMatchIntegration(R, F)
+ internalIntegrate0(f, x) ==
+ intPatternMatch(f, x, lfintegrate, pmComplexintegrate)
+
+ else internalIntegrate0(f, x) == lfintegrate(f, x)
+
+ internalIntegrate(f, x) ==
+ f := distribute(f, x::F)
+ any?(has?(operator #1, "rtrig"),
+ [k for k in tower(g := realElementary(f, x))
+ | member?(x, variables(k::F))]$List(Kernel F))$List(Kernel F) =>
+ h := trigs2explogs(F2FG g, [K2KG k for k in tower f
+ | is?(k, "tan"::SE) or is?(k, "cot"::SE)], [x])
+ real?(g := FG2F h) =>
+ internalIntegrate0(rootSimp(rischNormalize(g, x).func), x)
+ real?(g := FG2F(h := rootSimp(rischNormalize(h, x).func))) =>
+ internalIntegrate0(g, x)
+ map(FG2F, lfintegrate(h, x))
+ internalIntegrate0(rootSimp(rischNormalize(g, x).func), x)
+
+@
+\section{package FSINT FunctionSpaceIntegration}
+<<package FSINT FunctionSpaceIntegration>>=
+)abbrev package FSINT FunctionSpaceIntegration
+++ Top-level real function integration
+++ Author: Manuel Bronstein
+++ Date Created: 4 February 1988
+++ Date Last Updated: 11 June 1993
+++ Keywords: function, integration.
+++ Description:
+++ \spadtype{FunctionSpaceIntegration} provides functions for the
+++ indefinite integration of real-valued functions.
+++ Examples: )r INTEF INPUT
+FunctionSpaceIntegration(R, F): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
+ AlgebraicallyClosedFunctionSpace R)
+
+ B ==> Boolean
+ G ==> Complex R
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ SE ==> Symbol
+ IR ==> IntegrationResult F
+ FG ==> Expression G
+ ALGOP ==> "%alg"
+ TANTEMP ==> "%temptan"::SE
+
+ Exports ==> with
+ integrate: (F, SE) -> Union(F, List F)
+ ++ integrate(f, x) returns the integral of \spad{f(x)dx}
+ ++ where x is viewed as a real variable.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import ElementaryIntegration(R, F)
+ import ElementaryIntegration(G, FG)
+ import AlgebraicManipulations(R, F)
+ import TrigonometricManipulations(R, F)
+ import IntegrationResultToFunction(R, F)
+ import TranscendentalManipulations(R, F)
+ import IntegrationResultFunctions2(FG, F)
+ import FunctionSpaceComplexIntegration(R, F)
+ import ElementaryFunctionStructurePackage(R, F)
+ import InnerTrigonometricManipulations(R, F, FG)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, SparseMultivariatePolynomial(R, K), F)
+
+ K2KG : K -> Kernel FG
+ postSubst : (F, List F, List K, B, List K, SE) -> F
+ rinteg : (IR, F, SE, B, B) -> Union(F, List F)
+ mkPrimh : (F, SE, B, B) -> F
+ trans? : F -> B
+ goComplex?: (B, List K, List K) -> B
+ halfangle : F -> F
+ Khalf : K -> F
+ tan2temp : K -> K
+
+ optemp:BasicOperator := operator(TANTEMP, 1)
+
+ K2KG k == retract(tan F2FG first argument k)@Kernel(FG)
+ tan2temp k == kernel(optemp, argument k, height k)$K
+
+ trans? f ==
+ any?(is?(#1,"log"::SE) or is?(#1,"exp"::SE) or is?(#1,"atan"::SE),
+ operators f)$List(BasicOperator)
+
+ mkPrimh(f, x, h, comp) ==
+ f := real f
+ if comp then f := removeSinSq f
+ g := mkPrim(f, x)
+ h and trans? g => htrigs g
+ g
+
+ rinteg(i, f, x, h, comp) ==
+ not elem? i => integral(f, x)$F
+ empty? rest(l := [mkPrimh(f, x, h, comp) for f in expand i]) => first l
+ l
+
+-- replace tan(a/2)**2 by (1-cos a)/(1+cos a) if tan(a/2) is in ltan
+ halfangle a ==
+ a := 2 * a
+ (1 - cos a) / (1 + cos a)
+
+ Khalf k ==
+ a := 2 * first argument k
+ sin(a) / (1 + cos a)
+
+-- ltan = list of tangents in the integrand after real normalization
+ postSubst(f, lv, lk, comp, ltan, x) ==
+ for v in lv for k in lk repeat
+ if ((u := retractIfCan(v)@Union(K, "failed")) case K) then
+ if has?(operator(kk := u::K), ALGOP) then
+ f := univariate(f, kk, minPoly kk) (kk::F)
+ f := eval(f, [u::K], [k::F])
+ if not(comp or empty? ltan) then
+ ltemp := [tan2temp k for k in ltan]
+ f := eval(f, ltan, [k::F for k in ltemp])
+ f := eval(f, TANTEMP, 2, halfangle)
+ f := eval(f, ltemp, [Khalf k for k in ltemp])
+ removeConstantTerm(f, x)
+
+-- can handle a single unnested tangent directly, otherwise go complex for now
+-- l is the list of all the kernels containing x
+-- ltan is the list of all the tangents in l
+ goComplex?(rt, l, ltan) ==
+ empty? ltan => rt
+ not empty? rest rest l
+
+ integrate(f, x) ==
+ not real? f => complexIntegrate(f, x)
+ f := distribute(f, x::F)
+ tf := [k for k in tower f | member?(x, variables(k::F)@List(SE))]$List(K)
+ ltf := select(is?(operator #1, "tan"::SE), tf)
+ ht := any?(has?(operator #1, "htrig"), tf)
+ rec := rischNormalize(realElementary(f, x), x)
+ g := rootSimp(rec.func)
+ tg := [k for k in tower g | member?(x, variables(k::F))]$List(K)
+ ltg := select(is?(operator #1, "tan"::SE), tg)
+ rtg := any?(has?(operator #1, "rtrig"), tg)
+ el := any?(has?(operator #1, "elem"), tg)
+ i:IR
+ if (comp := goComplex?(rtg, tg, ltg)) then
+ i := map(FG2F, lfintegrate(trigs2explogs(F2FG g,
+ [K2KG k for k in tf | is?(k, "tan"::SE) or
+ is?(k, "cot"::SE)], [x]), x))
+ else i := lfintegrate(g, x)
+ ltg := setDifference(ltg, ltf) -- tan's added by normalization
+ (u := rinteg(i, f, x, el and ht, comp)) case F =>
+ postSubst(u::F, rec.vals, rec.kers, comp, ltg, x)
+ [postSubst(h, rec.vals, rec.kers, comp, ltg, x) for h in u::List(F)]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg intaf EFSTRUC rdeef intef irexpand integrat
+
+<<package FSCINT FunctionSpaceComplexIntegration>>
+<<package FSINT FunctionSpaceIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/interval.as.pamphlet b/src/algebra/interval.as.pamphlet
new file mode 100644
index 00000000..765d7327
--- /dev/null
+++ b/src/algebra/interval.as.pamphlet
@@ -0,0 +1,564 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra interval.as}
+\author{Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{IntervalCategory}
+<<IntervalCategory>>=
+#include "axiom.as"
+
++++ Author: Mike Dewar
++++ Date Created: November 1996
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This category is an implementation of interval arithmetic and transcendental
++++ functions over intervals.
+
+FUNCAT ==> Join(FloatingPointSystem,TranscendentalFunctionCategory);
+
+define IntervalCategory(R:FUNCAT): Category ==
+ Join(GcdDomain, OrderedSet, TranscendentalFunctionCategory, RadicalCategory,
+ RetractableTo(Integer))
+ with {
+ approximate;
+ interval : (R,R) -> %;
+ ++ interval(inf,sup) creates a new interval, either \axiom{[inf,sup]} if
+ ++ \axiom{inf <= sup} or \axiom{[sup,in]} otherwise.
+ qinterval : (R,R) -> %;
+ ++ qinterval(inf,sup) creates a new interval \axiom{[inf,sup]}, without
+ ++ checking the ordering on the elements.
+ interval : R -> %;
+ ++ interval(f) creates a new interval around f.
+ interval : Fraction Integer -> %;
+ ++ interval(f) creates a new interval around f.
+ inf : % -> R;
+ ++ inf(u) returns the infinum of \axiom{u}.
+ sup : % -> R;
+ ++ sup(u) returns the supremum of \axiom{u}.
+ width : % -> R;
+ ++ width(u) returns \axiom{sup(u) - inf(u)}.
+ positive? : % -> Boolean;
+ ++ positive?(u) returns \axiom{true} if every element of u is positive,
+ ++ \axiom{false} otherwise.
+ negative? : % -> Boolean;
+ ++ negative?(u) returns \axiom{true} if every element of u is negative,
+ ++ \axiom{false} otherwise.
+ contains? : (%,R) -> Boolean;
+ ++ contains?(i,f) returns true if \axiom{f} is contained within the interval
+ ++ \axiom{i}, false otherwise.
+}
+
+@
+\section{Interval}
+<<Interval>>=
++++ Author: Mike Dewar
++++ Date Created: November 1996
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This domain is an implementation of interval arithmetic and transcendental
++++ functions over intervals.
+
+Interval(R:FUNCAT): IntervalCategory(R) == add {
+
+ import from Integer;
+ import from R;
+
+ Rep ==> Record(Inf:R, Sup:R);
+
+ import from Rep;
+
+ local roundDown(u:R):R ==
+ if zero?(u) then float(-1,-(bits() pretend Integer));
+ else float(mantissa(u) - 1,exponent(u));
+
+ local roundUp(u:R):R ==
+ if zero?(u) then float(1, -(bits()) pretend Integer);
+ else float(mantissa(u) + 1,exponent(u));
+
+ -- Sometimes the float representation does not use all the bits (e.g. when
+ -- representing an integer in software using arbitrary-length Integers as
+ -- your mantissa it is convenient to keep them exact). This function
+ -- normalises things so that rounding etc. works as expected. It is only
+ -- called when creating new intervals.
+ local normaliseFloat(u:R):R ==
+ if zero? u then u else {
+ m : Integer := mantissa u;
+ b : Integer := bits() pretend Integer;
+ l : Integer := length(m);
+ if (l < b) then {
+ BASE : Integer := base()$R pretend Integer;
+ float(m*BASE**((b-l) pretend PositiveInteger),exponent(u)-b+l);
+ }
+ else
+ u;
+ }
+
+ interval(i:R,s:R):% == {
+ i > s => per [roundDown normaliseFloat s,roundUp normaliseFloat i];
+ per [roundDown normaliseFloat i,roundUp normaliseFloat s];
+ }
+
+ interval(f:R):% == {
+ zero?(f) => 0;
+ one?(f) => 1;
+ -- This next part is necessary to allow e.g. mapping between Expressions:
+ -- AXIOM assumes that Integers stay as Integers!
+ import from Union(value1:Integer,failed:'failed');
+ fnew : R := normaliseFloat f;
+ retractIfCan(f)@Union(value1:Integer,failed:'failed') case value1 =>
+ per [fnew,fnew];
+ per [roundDown fnew, roundUp fnew];
+ }
+
+ qinterval(i:R,s:R):% ==
+ per [roundDown normaliseFloat i,roundUp normaliseFloat s];
+
+ local exactInterval(i:R,s:R):% == per [i,s];
+ local exactSupInterval(i:R,s:R):% == per [roundDown i,s];
+ local exactInfInterval(i:R,s:R):% == per [i,roundUp s];
+
+ inf(u:%):R == (rep u).Inf;
+ sup(u:%):R == (rep u).Sup;
+ width(u:%):R == (rep u).Sup - (rep u).Inf;
+
+ contains?(u:%,f:R):Boolean == (f > inf(u)) and (f < sup(u));
+
+ positive?(u:%):Boolean == inf(u) > 0;
+ negative?(u:%):Boolean == sup(u) < 0;
+
+ (<)(a:%,b:%):Boolean ==
+ if inf(a) < inf(b) then
+ true
+ else if inf(a) > inf(b) then
+ false
+ else
+ sup(a) < sup(b);
+
+ (+)(a:%,b:%):% == {
+ -- A couple of blatent hacks to preserve the Ring Axioms!
+ if zero?(a) then return(b) else if zero?(b) then return(a);
+ if a=b then return qinterval(2*inf(a),2*sup(a));
+ qinterval(inf(a) + inf(b), sup(a) + sup(b));
+ }
+
+ (-)(a:%,b:%):% == {
+ if zero?(a) then return(-b) else if zero?(b) then return(a);
+ if a=b then 0 else qinterval(inf(a) - sup(b), sup(a) - inf(b));
+ }
+
+ (*)(a:%,b:%):% == {
+ -- A couple of blatent hacks to preserve the Ring Axioms!
+ if one?(a) then return(b) else if one?(b) then return(a);
+ if zero?(a) then return(0) else if zero?(b) then return(0);
+ prods : List R := sort [inf(a)*inf(b),sup(a)*sup(b),
+ inf(a)*sup(b),sup(a)*inf(b)];
+ qinterval(first prods, last prods);
+ }
+
+ (*)(a:Integer,b:%):% == {
+ if (a > 0) then
+ qinterval(a*inf(b),a*sup(b));
+ else if (a < 0) then
+ qinterval(a*sup(b),a*inf(b));
+ else
+ 0;
+ }
+
+ (*)(a:PositiveInteger,b:%):% == qinterval(a*inf(b),a*sup(b));
+
+ (**)(a:%,n:PositiveInteger):% == {
+ contains?(a,0) and zero?((n pretend Integer) rem 2) =>
+ interval(0,max(inf(a)**n,sup(a)**n));
+ interval(inf(a)**n,sup(a)**n);
+ }
+
+ (^) (a:%,n:PositiveInteger):% == {
+ contains?(a,0) and zero?((n pretend Integer) rem 2) =>
+ interval(0,max(inf(a)**n,sup(a)**n));
+ interval(inf(a)**n,sup(a)**n);
+ }
+
+ (-)(a:%):% == exactInterval(-sup(a),-inf(a));
+
+ (=)(a:%,b:%):Boolean == (inf(a)=inf(b)) and (sup(a)=sup(b));
+ (~=)(a:%,b:%):Boolean == (inf(a)~=inf(b)) or (sup(a)~=sup(b));
+
+ 1:% == {one : R := normaliseFloat 1; per([one,one])};
+ 0:% == per([0,0]);
+
+ recip(u:%):Union(value1:%,failed:'failed') == {
+ contains?(u,0) => [failed];
+ vals:List R := sort[1/inf(u),1/sup(u)];
+ [qinterval(first vals, last vals)];
+ }
+
+ unit?(u:%):Boolean == contains?(u,0);
+
+ exquo(u:%,v:%):Union(value1:%,failed:'failed') == {
+ contains?(v,0) => [failed];
+ one?(v) => [u];
+ u=v => [1];
+ u=-v => [-1];
+ vals:List R := sort[inf(u)/inf(v),inf(u)/sup(v),sup(u)/inf(v),sup(u)/sup(v)];
+ [qinterval(first vals, last vals)];
+ }
+
+ gcd(u:%,v:%):% == 1;
+
+ coerce(u:Integer):% == {
+ ur := normaliseFloat(u::R);
+ exactInterval(ur,ur);
+ }
+
+ interval(u:Fraction Integer):% == {
+ import { log2 : % -> %;
+ coerce : Integer -> %;
+ retractIfCan : % -> Union(value1:Integer,failed:'failed');}
+ from Float;
+ flt := u::R;
+
+ -- Test if the representation in R is exact
+ --den := denom(u)::Float;
+ local bin : Union(value1:Integer,failed:'failed');
+ bin := retractIfCan(log2(denom(u)::Float));
+ bin case value1 and length(numer u)$Integer < (bits() pretend Integer) => {
+ flt := normaliseFloat flt;
+ exactInterval(flt,flt);
+ }
+
+ qinterval(flt,flt);
+ }
+
+ retractIfCan(u:%):Union(value1:Integer,failed:'failed') == {
+ not zero? width(u) => [failed];
+ retractIfCan inf u;
+ }
+
+ retract(u:%):Integer == {
+ not zero? width(u) =>
+ error "attempt to retract a non-Integer interval to an Integer";
+ retract inf u;
+ }
+
+ coerce(u:%):OutputForm ==
+ bracket([coerce inf(u), coerce sup(u)]$List(OutputForm));
+
+ characteristic():NonNegativeInteger == 0;
+
+
+ -- Explicit export from TranscendentalFunctionCategory
+ pi():% == qinterval(pi(),pi());
+
+ -- From ElementaryFunctionCategory
+ log(u:%):% == {
+ positive?(u) => qinterval(log inf u, log sup u);
+ error "negative logs in interval";
+ }
+
+ exp(u:%):% == qinterval(exp inf u, exp sup u);
+
+ (**)(u:%,v:%):% == {
+ zero?(v) => if zero?(u) then error "0**0 is undefined" else 1;
+ one?(u) => 1;
+ expts : List R := sort [inf(u)**inf(v),sup(u)**sup(v),
+ inf(u)**sup(v),sup(u)**inf(v)];
+ qinterval(first expts, last expts);
+ }
+
+ -- From TrigonometricFunctionCategory
+
+ -- This function checks whether an interval contains a value of the form
+ -- `offset + 2 n pi'.
+ local hasTwoPiMultiple(offset:R,Pi:R,i:%):Boolean == {
+ import from Integer;
+ next : Integer := retract ceiling( (inf(i) - offset)/(2*Pi) );
+ contains?(i,offset+2*next*Pi);
+ }
+
+ -- This function checks whether an interval contains a value of the form
+ -- `offset + n pi'.
+ local hasPiMultiple(offset:R,Pi:R,i:%):Boolean == {
+ import from Integer;
+ next : Integer := retract ceiling( (inf(i) - offset)/Pi );
+ contains?(i,offset+next*Pi);
+ }
+
+ sin(u:%):% == {
+ import from Integer;
+ Pi : R := pi();
+ hasOne? : Boolean := hasTwoPiMultiple(Pi/(2::R),Pi,u);
+ hasMinusOne? : Boolean := hasTwoPiMultiple(3*Pi/(2::R),Pi,u);
+
+ if hasOne? and hasMinusOne? then
+ exactInterval(-1,1);
+ else {
+ vals : List R := sort [sin inf u, sin sup u];
+ if hasOne? then
+ exactSupInterval(first vals, 1);
+ else if hasMinusOne? then
+ exactInfInterval(-1,last vals);
+ else
+ qinterval(first vals, last vals);
+ }
+ }
+
+ cos(u:%):% == {
+ Pi : R := pi();
+ hasOne? : Boolean := hasTwoPiMultiple(0,Pi,u);
+ hasMinusOne? : Boolean := hasTwoPiMultiple(Pi,Pi,u);
+
+ if hasOne? and hasMinusOne? then
+ exactInterval(-1,1);
+ else {
+ vals : List R := sort [cos inf u, cos sup u];
+ if hasOne? then
+ exactSupInterval(first vals, 1);
+ else if hasMinusOne? then
+ exactInfInterval(-1,last vals);
+ else
+ qinterval(first vals, last vals);
+ }
+ }
+
+ tan(u:%):% == {
+ Pi : R := pi();
+ if width(u) > Pi then
+ error "Interval contains a singularity"
+ else {
+ -- Since we know the interval is less than pi wide, monotonicity implies
+ -- that there is no singularity. If there is a singularity on a endpoint
+ -- of the interval the user will see the error generated by R.
+ lo : R := tan inf u;
+ hi : R := tan sup u;
+
+ lo > hi => error "Interval contains a singularity";
+ qinterval(lo,hi);
+ }
+ }
+
+ csc(u:%):% == {
+ Pi : R := pi();
+ if width(u) > Pi then
+ error "Interval contains a singularity"
+ else {
+ import from Integer;
+ -- singularities are at multiples of Pi
+ if hasPiMultiple(0,Pi,u) then error "Interval contains a singularity";
+ vals : List R := sort [csc inf u, csc sup u];
+ if hasTwoPiMultiple(Pi/(2::R),Pi,u) then
+ exactInfInterval(1,last vals);
+ else if hasTwoPiMultiple(3*Pi/(2::R),Pi,u) then
+ exactSupInterval(first vals,-1);
+ else
+ qinterval(first vals, last vals);
+ }
+ }
+
+ sec(u:%):% == {
+ Pi : R := pi();
+ if width(u) > Pi then
+ error "Interval contains a singularity"
+ else {
+ import from Integer;
+ -- singularities are at Pi/2 + n Pi
+ if hasPiMultiple(Pi/(2::R),Pi,u) then
+ error "Interval contains a singularity";
+ vals : List R := sort [sec inf u, sec sup u];
+ if hasTwoPiMultiple(0,Pi,u) then
+ exactInfInterval(1,last vals);
+ else if hasTwoPiMultiple(Pi,Pi,u) then
+ exactSupInterval(first vals,-1);
+ else
+ qinterval(first vals, last vals);
+ }
+ }
+
+
+ cot(u:%):% == {
+ Pi : R := pi();
+ if width(u) > Pi then
+ error "Interval contains a singularity"
+ else {
+ -- Since we know the interval is less than pi wide, monotonicity implies
+ -- that there is no singularity. If there is a singularity on a endpoint
+ -- of the interval the user will see the error generated by R.
+ hi : R := cot inf u;
+ lo : R := cot sup u;
+
+ lo > hi => error "Interval contains a singularity";
+ qinterval(lo,hi);
+ }
+ }
+
+ -- From ArcTrigonometricFunctionCategory
+
+ asin(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if (lo < -1) or (hi > 1) then error "asin only defined on the region -1..1";
+ qinterval(asin lo,asin hi);
+ }
+
+ acos(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if (lo < -1) or (hi > 1) then error "acos only defined on the region -1..1";
+ qinterval(acos hi,acos lo);
+ }
+
+ atan(u:%):% == qinterval(atan inf u, atan sup u);
+
+ acot(u:%):% == qinterval(acot sup u, acot inf u);
+
+ acsc(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if ((lo <= -1) and (hi >= -1)) or ((lo <= 1) and (hi >= 1)) then
+ error "acsc not defined on the region -1..1";
+ qinterval(acsc hi, acsc lo);
+ }
+
+ asec(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if ((lo < -1) and (hi > -1)) or ((lo < 1) and (hi > 1)) then
+ error "asec not defined on the region -1..1";
+ qinterval(asec lo, asec hi);
+ }
+
+ -- From HyperbolicFunctionCategory
+
+ tanh(u:%):% == qinterval(tanh inf u, tanh sup u);
+
+ sinh(u:%):% == qinterval(sinh inf u, sinh sup u);
+
+ sech(u:%):% == {
+ negative? u => qinterval(sech inf u, sech sup u);
+ positive? u => qinterval(sech sup u, sech inf u);
+ vals : List R := sort [sech inf u, sech sup u];
+ exactSupInterval(first vals,1);
+ }
+
+ cosh(u:%):% == {
+ negative? u => qinterval(cosh sup u, cosh inf u);
+ positive? u => qinterval(cosh inf u, cosh sup u);
+ vals : List R := sort [cosh inf u, cosh sup u];
+ exactInfInterval(1,last vals);
+ }
+
+ csch(u:%):% == {
+ contains?(u,0) => error "csch: singularity at zero";
+ qinterval(csch sup u, csch inf u);
+ }
+
+ coth(u:%):% == {
+ contains?(u,0) => error "coth: singularity at zero";
+ qinterval(coth sup u, coth inf u);
+ }
+
+ -- From ArcHyperbolicFunctionCategory
+
+ acosh(u:%):% == {
+ inf(u)<1 => error "invalid argument: acosh only defined on the region 1..";
+ qinterval(acosh inf u, acosh sup u);
+ }
+
+ acoth(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if ((lo <= -1) and (hi >= -1)) or ((lo <= 1) and (hi >= 1)) then
+ error "acoth not defined on the region -1..1";
+ qinterval(acoth hi, acoth lo);
+ }
+
+ acsch(u:%):% == {
+ contains?(u,0) => error "acsch: singularity at zero";
+ qinterval(acsch sup u, acsch inf u);
+ }
+
+ asech(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if (lo <= 0) or (hi > 1) then
+ error "asech only defined on the region 0 < x <= 1";
+ qinterval(asech hi, asech lo);
+ }
+
+ asinh(u:%):% == qinterval(asinh inf u, asinh sup u);
+
+ atanh(u:%):% == {
+ lo : R := inf(u);
+ hi : R := sup(u);
+ if (lo <= -1) or (hi >= 1) then
+ error "atanh only defined on the region -1 < x < 1";
+ qinterval(atanh lo, atanh hi);
+ }
+
+ -- From RadicalCategory
+ (**)(u:%,n:Fraction Integer):% == interval(inf(u)**n,sup(u)**n);
+
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<IntervalCategory>>
+<<Interval>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/interval.spad.pamphlet b/src/algebra/interval.spad.pamphlet
new file mode 100644
index 00000000..ab9bfa9e
--- /dev/null
+++ b/src/algebra/interval.spad.pamphlet
@@ -0,0 +1,547 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra interval.spad}
+\author{Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category INTCAT IntervalCategory}
+<<category INTCAT IntervalCategory>>=
+)abbrev category INTCAT IntervalCategory
++++ Author: Mike Dewar
++++ Date Created: November 1996
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This category implements of interval arithmetic and transcendental
++++ functions over intervals.
+IntervalCategory(R: Join(FloatingPointSystem,TranscendentalFunctionCategory)):
+ Category == Join(GcdDomain, OrderedSet, TranscendentalFunctionCategory, RadicalCategory, RetractableTo(Integer)) with
+ approximate
+ interval : (R,R) -> %
+ ++ interval(inf,sup) creates a new interval, either \axiom{[inf,sup]} if
+ ++ \axiom{inf <= sup} or \axiom{[sup,in]} otherwise.
+ qinterval : (R,R) -> %
+ ++ qinterval(inf,sup) creates a new interval \axiom{[inf,sup]}, without
+ ++ checking the ordering on the elements.
+ interval : R -> %
+ ++ interval(f) creates a new interval around f.
+ interval : Fraction Integer -> %
+ ++ interval(f) creates a new interval around f.
+ inf : % -> R
+ ++ inf(u) returns the infinum of \axiom{u}.
+ sup : % -> R
+ ++ sup(u) returns the supremum of \axiom{u}.
+ width : % -> R
+ ++ width(u) returns \axiom{sup(u) - inf(u)}.
+ positive? : % -> Boolean
+ ++ positive?(u) returns \axiom{true} if every element of u is positive,
+ ++ \axiom{false} otherwise.
+ negative? : % -> Boolean
+ ++ negative?(u) returns \axiom{true} if every element of u is negative,
+ ++ \axiom{false} otherwise.
+ contains? : (%,R) -> Boolean
+ ++ contains?(i,f) returns true if \axiom{f} is contained within the interval
+ ++ \axiom{i}, false otherwise.
+
+@
+\section{domain INTRVL Interval}
+<<domain INTRVL Interval>>=
+)abbrev domain INTRVL Interval
++++ Author: Mike Dewar
++++ Date Created: November 1996
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This domain is an implementation of interval arithmetic and transcendental
++++ functions over intervals.
+Interval(R:Join(FloatingPointSystem,TranscendentalFunctionCategory)): IntervalCategory(R) == add
+
+ import Integer
+-- import from R
+
+ Rep := Record(Inf:R, Sup:R)
+
+ roundDown(u:R):R ==
+ if zero?(u) then float(-1,-(bits() pretend Integer))
+ else float(mantissa(u) - 1,exponent(u))
+
+ roundUp(u:R):R ==
+ if zero?(u) then float(1, -(bits()) pretend Integer)
+ else float(mantissa(u) + 1,exponent(u))
+
+ -- Sometimes the float representation does not use all the bits (e.g. when
+ -- representing an integer in software using arbitrary-length Integers as
+ -- your mantissa it is convenient to keep them exact). This function
+ -- normalises things so that rounding etc. works as expected. It is only
+ -- called when creating new intervals.
+ normaliseFloat(u:R):R ==
+ zero? u => u
+ m : Integer := mantissa u
+ b : Integer := bits() pretend Integer
+ l : Integer := length(m)
+ if l < b then
+ BASE : Integer := base()$R pretend Integer
+ float(m*BASE**((b-l) pretend PositiveInteger),exponent(u)-b+l)
+ else
+ u
+
+ interval(i:R,s:R):% ==
+ i > s => [roundDown normaliseFloat s,roundUp normaliseFloat i]
+ [roundDown normaliseFloat i,roundUp normaliseFloat s]
+
+ interval(f:R):% ==
+ zero?(f) => 0
+ one?(f) => 1
+ -- This next part is necessary to allow e.g. mapping between Expressions:
+ -- AXIOM assumes that Integers stay as Integers!
+-- import from Union(value1:Integer,failed:"failed")
+ fnew : R := normaliseFloat f
+ retractIfCan(f)@Union(Integer,"failed") case "failed" =>
+ [roundDown fnew, roundUp fnew]
+ [fnew,fnew]
+
+ qinterval(i:R,s:R):% ==
+ [roundDown normaliseFloat i,roundUp normaliseFloat s]
+
+ exactInterval(i:R,s:R):% == [i,s]
+ exactSupInterval(i:R,s:R):% == [roundDown i,s]
+ exactInfInterval(i:R,s:R):% == [i,roundUp s]
+
+ inf(u:%):R == u.Inf
+ sup(u:%):R == u.Sup
+ width(u:%):R == u.Sup - u.Inf
+
+ contains?(u:%,f:R):Boolean == (f > inf(u)) and (f < sup(u))
+
+ positive?(u:%):Boolean == inf(u) > 0
+ negative?(u:%):Boolean == sup(u) < 0
+
+ _< (a:%,b:%):Boolean ==
+ if inf(a) < inf(b) then
+ true
+ else if inf(a) > inf(b) then
+ false
+ else
+ sup(a) < sup(b)
+
+ _+ (a:%,b:%):% ==
+ -- A couple of blatent hacks to preserve the Ring Axioms!
+ if zero?(a) then return(b) else if zero?(b) then return(a)
+ if a = b then return qinterval(2*inf(a),2*sup(a))
+ qinterval(inf(a) + inf(b), sup(a) + sup(b))
+
+
+ _- (a:%,b:%):% ==
+ if zero?(a) then return(-b) else if zero?(b) then return(a)
+ if a = b then 0 else qinterval(inf(a) - sup(b), sup(a) - inf(b))
+
+
+ _* (a:%,b:%):% ==
+ -- A couple of blatent hacks to preserve the Ring Axioms!
+ if one?(a) then return(b) else if one?(b) then return(a)
+ if zero?(a) then return(0) else if zero?(b) then return(0)
+ prods : List R := sort [inf(a)*inf(b),sup(a)*sup(b),
+ inf(a)*sup(b),sup(a)*inf(b)]
+ qinterval(first prods, last prods)
+
+
+ _* (a:Integer,b:%):% ==
+ if (a > 0) then
+ qinterval(a*inf(b),a*sup(b))
+ else if (a < 0) then
+ qinterval(a*sup(b),a*inf(b))
+ else
+ 0
+
+ _* (a:PositiveInteger,b:%):% == qinterval(a*inf(b),a*sup(b))
+
+ _*_* (a:%,n:PositiveInteger):% ==
+ contains?(a,0) and zero?((n pretend Integer) rem 2) =>
+ interval(0,max(inf(a)**n,sup(a)**n))
+ interval(inf(a)**n,sup(a)**n)
+
+
+ _^ (a:%,n:PositiveInteger):% ==
+ contains?(a,0) and zero?((n pretend Integer) rem 2) =>
+ interval(0,max(inf(a)**n,sup(a)**n))
+ interval(inf(a)**n,sup(a)**n)
+
+ _- (a:%):% == exactInterval(-sup(a),-inf(a))
+
+ _= (a:%,b:%):Boolean == (inf(a)=inf(b)) and (sup(a)=sup(b))
+ _~_= (a:%,b:%):Boolean == (inf(a)~=inf(b)) or (sup(a)~=sup(b))
+
+ 1 ==
+ one : R := normaliseFloat 1
+ [one,one]
+
+ 0 == [0,0]
+
+ recip(u:%):Union(%,"failed") ==
+ contains?(u,0) => "failed"
+ vals:List R := sort [1/inf(u),1/sup(u)]$List(R)
+ qinterval(first vals, last vals)
+
+
+ unit?(u:%):Boolean == contains?(u,0)
+
+ _exquo(u:%,v:%):Union(%,"failed") ==
+ contains?(v,0) => "failed"
+ one?(v) => u
+ u=v => 1
+ u=-v => -1
+ vals:List R := sort [inf(u)/inf(v),inf(u)/sup(v),sup(u)/inf(v),sup(u)/sup(v)]$List(R)
+ qinterval(first vals, last vals)
+
+
+ gcd(u:%,v:%):% == 1
+
+ coerce(u:Integer):% ==
+ ur := normaliseFloat(u::R)
+ exactInterval(ur,ur)
+
+
+ interval(u:Fraction Integer):% ==
+-- import log2 : % -> %
+-- coerce : Integer -> %
+-- retractIfCan : % -> Union(value1:Integer,failed:"failed")
+-- from Float
+ flt := u::R
+
+ -- Test if the representation in R is exact
+ --den := denom(u)::Float
+ bin : Union(Integer,"failed") := retractIfCan(log2(denom(u)::Float))
+ bin case Integer and length(numer u)$Integer < (bits() pretend Integer) =>
+ flt := normaliseFloat flt
+ exactInterval(flt,flt)
+
+ qinterval(flt,flt)
+
+
+ retractIfCan(u:%):Union(Integer,"failed") ==
+ not zero? width(u) => "failed"
+ retractIfCan inf u
+
+
+ retract(u:%):Integer ==
+ not zero? width(u) =>
+ error "attempt to retract a non-Integer interval to an Integer"
+ retract inf u
+
+
+ coerce(u:%):OutputForm ==
+ bracket([coerce inf(u), coerce sup(u)]$List(OutputForm))
+
+ characteristic():NonNegativeInteger == 0
+
+
+ -- Explicit export from TranscendentalFunctionCategory
+ pi():% == qinterval(pi(),pi())
+
+ -- From ElementaryFunctionCategory
+ log(u:%):% ==
+ positive?(u) => qinterval(log inf u, log sup u)
+ error "negative logs in interval"
+
+
+ exp(u:%):% == qinterval(exp inf u, exp sup u)
+
+ _*_* (u:%,v:%):% ==
+ zero?(v) => if zero?(u) then error "0**0 is undefined" else 1
+ one?(u) => 1
+ expts : List R := sort [inf(u)**inf(v),sup(u)**sup(v),
+ inf(u)**sup(v),sup(u)**inf(v)]
+ qinterval(first expts, last expts)
+
+ -- From TrigonometricFunctionCategory
+
+ -- This function checks whether an interval contains a value of the form
+ -- `offset + 2 n pi'.
+ hasTwoPiMultiple(offset:R,ipi:R,i:%):Boolean ==
+ next : Integer := retract ceiling( (inf(i) - offset)/(2*ipi) )
+ contains?(i,offset+2*next*ipi)
+
+
+ -- This function checks whether an interval contains a value of the form
+ -- `offset + n pi'.
+ hasPiMultiple(offset:R,ipi:R,i:%):Boolean ==
+ next : Integer := retract ceiling( (inf(i) - offset)/ipi )
+ contains?(i,offset+next*ipi)
+
+
+ sin(u:%):% ==
+ ipi : R := pi()$R
+ hasOne? : Boolean := hasTwoPiMultiple(ipi/(2::R),ipi,u)
+ hasMinusOne? : Boolean := hasTwoPiMultiple(3*ipi/(2::R),ipi,u)
+
+ if hasOne? and hasMinusOne? then
+ exactInterval(-1,1)
+ else
+ vals : List R := sort [sin inf u, sin sup u]
+ if hasOne? then
+ exactSupInterval(first vals, 1)
+ else if hasMinusOne? then
+ exactInfInterval(-1,last vals)
+ else
+ qinterval(first vals, last vals)
+
+
+
+ cos(u:%):% ==
+ ipi : R := pi()
+ hasOne? : Boolean := hasTwoPiMultiple(0,ipi,u)
+ hasMinusOne? : Boolean := hasTwoPiMultiple(ipi,ipi,u)
+
+ if hasOne? and hasMinusOne? then
+ exactInterval(-1,1)
+ else
+ vals : List R := sort [cos inf u, cos sup u]
+ if hasOne? then
+ exactSupInterval(first vals, 1)
+ else if hasMinusOne? then
+ exactInfInterval(-1,last vals)
+ else
+ qinterval(first vals, last vals)
+
+
+
+ tan(u:%):% ==
+ ipi : R := pi()
+ if width(u) > ipi then
+ error "Interval contains a singularity"
+ else
+ -- Since we know the interval is less than pi wide, monotonicity implies
+ -- that there is no singularity. If there is a singularity on a endpoint
+ -- of the interval the user will see the error generated by R.
+ lo : R := tan inf u
+ hi : R := tan sup u
+
+ lo > hi => error "Interval contains a singularity"
+ qinterval(lo,hi)
+
+
+
+ csc(u:%):% ==
+ ipi : R := pi()
+ if width(u) > ipi then
+ error "Interval contains a singularity"
+ else
+-- import from Integer
+ -- singularities are at multiples of Pi
+ if hasPiMultiple(0,ipi,u) then error "Interval contains a singularity"
+ vals : List R := sort [csc inf u, csc sup u]
+ if hasTwoPiMultiple(ipi/(2::R),ipi,u) then
+ exactInfInterval(1,last vals)
+ else if hasTwoPiMultiple(3*ipi/(2::R),ipi,u) then
+ exactSupInterval(first vals,-1)
+ else
+ qinterval(first vals, last vals)
+
+
+
+ sec(u:%):% ==
+ ipi : R := pi()
+ if width(u) > ipi then
+ error "Interval contains a singularity"
+ else
+-- import from Integer
+ -- singularities are at Pi/2 + n Pi
+ if hasPiMultiple(ipi/(2::R),ipi,u) then
+ error "Interval contains a singularity"
+ vals : List R := sort [sec inf u, sec sup u]
+ if hasTwoPiMultiple(0,ipi,u) then
+ exactInfInterval(1,last vals)
+ else if hasTwoPiMultiple(ipi,ipi,u) then
+ exactSupInterval(first vals,-1)
+ else
+ qinterval(first vals, last vals)
+
+
+
+
+ cot(u:%):% ==
+ ipi : R := pi()
+ if width(u) > ipi then
+ error "Interval contains a singularity"
+ else
+ -- Since we know the interval is less than pi wide, monotonicity implies
+ -- that there is no singularity. If there is a singularity on a endpoint
+ -- of the interval the user will see the error generated by R.
+ hi : R := cot inf u
+ lo : R := cot sup u
+
+ lo > hi => error "Interval contains a singularity"
+ qinterval(lo,hi)
+
+
+
+ -- From ArcTrigonometricFunctionCategory
+
+ asin(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if (lo < -1) or (hi > 1) then error "asin only defined on the region -1..1"
+ qinterval(asin lo,asin hi)
+
+
+ acos(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if (lo < -1) or (hi > 1) then error "acos only defined on the region -1..1"
+ qinterval(acos hi,acos lo)
+
+
+ atan(u:%):% == qinterval(atan inf u, atan sup u)
+
+ acot(u:%):% == qinterval(acot sup u, acot inf u)
+
+ acsc(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if ((lo <= -1) and (hi >= -1)) or ((lo <= 1) and (hi >= 1)) then
+ error "acsc not defined on the region -1..1"
+ qinterval(acsc hi, acsc lo)
+
+
+ asec(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if ((lo < -1) and (hi > -1)) or ((lo < 1) and (hi > 1)) then
+ error "asec not defined on the region -1..1"
+ qinterval(asec lo, asec hi)
+
+
+ -- From HyperbolicFunctionCategory
+
+ tanh(u:%):% == qinterval(tanh inf u, tanh sup u)
+
+ sinh(u:%):% == qinterval(sinh inf u, sinh sup u)
+
+ sech(u:%):% ==
+ negative? u => qinterval(sech inf u, sech sup u)
+ positive? u => qinterval(sech sup u, sech inf u)
+ vals : List R := sort [sech inf u, sech sup u]
+ exactSupInterval(first vals,1)
+
+
+ cosh(u:%):% ==
+ negative? u => qinterval(cosh sup u, cosh inf u)
+ positive? u => qinterval(cosh inf u, cosh sup u)
+ vals : List R := sort [cosh inf u, cosh sup u]
+ exactInfInterval(1,last vals)
+
+
+ csch(u:%):% ==
+ contains?(u,0) => error "csch: singularity at zero"
+ qinterval(csch sup u, csch inf u)
+
+
+ coth(u:%):% ==
+ contains?(u,0) => error "coth: singularity at zero"
+ qinterval(coth sup u, coth inf u)
+
+
+ -- From ArcHyperbolicFunctionCategory
+
+ acosh(u:%):% ==
+ inf(u)<1 => error "invalid argument: acosh only defined on the region 1.."
+ qinterval(acosh inf u, acosh sup u)
+
+
+ acoth(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if ((lo <= -1) and (hi >= -1)) or ((lo <= 1) and (hi >= 1)) then
+ error "acoth not defined on the region -1..1"
+ qinterval(acoth hi, acoth lo)
+
+
+ acsch(u:%):% ==
+ contains?(u,0) => error "acsch: singularity at zero"
+ qinterval(acsch sup u, acsch inf u)
+
+
+ asech(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if (lo <= 0) or (hi > 1) then
+ error "asech only defined on the region 0 < x <= 1"
+ qinterval(asech hi, asech lo)
+
+
+ asinh(u:%):% == qinterval(asinh inf u, asinh sup u)
+
+ atanh(u:%):% ==
+ lo : R := inf(u)
+ hi : R := sup(u)
+ if (lo <= -1) or (hi >= 1) then
+ error "atanh only defined on the region -1 < x < 1"
+ qinterval(atanh lo, atanh hi)
+
+
+ -- From RadicalCategory
+ _*_* (u:%,n:Fraction Integer):% == interval(inf(u)**n,sup(u)**n)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category INTCAT IntervalCategory>>
+<<domain INTRVL Interval>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
+
+
diff --git a/src/algebra/intfact.spad.pamphlet b/src/algebra/intfact.spad.pamphlet
new file mode 100644
index 00000000..996b9232
--- /dev/null
+++ b/src/algebra/intfact.spad.pamphlet
@@ -0,0 +1,534 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intfact.spad}
+\author{Michael Monagan}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PRIMES IntegerPrimesPackage}
+<<package PRIMES IntegerPrimesPackage>>=
+)abbrev package PRIMES IntegerPrimesPackage
+++ Author: Michael Monagan
+++ Date Created: August 1987
+++ Date Last Updated: 31 May 1993
+++ Updated by: James Davenport
+++ Updated Because: of problems with strong pseudo-primes
+++ and for some efficiency reasons.
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: integer, prime
+++ Examples:
+++ References: Davenport's paper in ISSAC 1992
+++ AXIOM Technical Report ATR/6
+++ Description:
+++ The \spadtype{IntegerPrimesPackage} implements a modification of
+++ Rabin's probabilistic
+++ primality test and the utility functions \spadfun{nextPrime},
+++ \spadfun{prevPrime} and \spadfun{primes}.
+IntegerPrimesPackage(I:IntegerNumberSystem): with
+ prime?: I -> Boolean
+ ++ \spad{prime?(n)} returns true if n is prime and false if not.
+ ++ The algorithm used is Rabin's probabilistic primality test
+ ++ (reference: Knuth Volume 2 Semi Numerical Algorithms).
+ ++ If \spad{prime? n} returns false, n is proven composite.
+ ++ If \spad{prime? n} returns true, prime? may be in error
+ ++ however, the probability of error is very low.
+ ++ and is zero below 25*10**9 (due to a result of Pomerance et al),
+ ++ below 10**12 and 10**13 due to results of Pinch,
+ ++ and below 341550071728321 due to a result of Jaeschke.
+ ++ Specifically, this implementation does at least 10 pseudo prime
+ ++ tests and so the probability of error is \spad{< 4**(-10)}.
+ ++ The running time of this method is cubic in the length
+ ++ of the input n, that is \spad{O( (log n)**3 )}, for n<10**20.
+ ++ beyond that, the algorithm is quartic, \spad{O( (log n)**4 )}.
+ ++ Two improvements due to Davenport have been incorporated
+ ++ which catches some trivial strong pseudo-primes, such as
+ ++ [Jaeschke, 1991] 1377161253229053 * 413148375987157, which
+ ++ the original algorithm regards as prime
+ nextPrime: I -> I
+ ++ \spad{nextPrime(n)} returns the smallest prime strictly larger than n
+ prevPrime: I -> I
+ ++ \spad{prevPrime(n)} returns the largest prime strictly smaller than n
+ primes: (I,I) -> List I
+ ++ \spad{primes(a,b)} returns a list of all primes p with
+ ++ \spad{a <= p <= b}
+ == add
+ smallPrimes: List I := [2::I,3::I,5::I,7::I,11::I,13::I,17::I,19::I,_
+ 23::I,29::I,31::I,37::I,41::I,43::I,47::I,_
+ 53::I,59::I,61::I,67::I,71::I,73::I,79::I,_
+ 83::I,89::I,97::I,101::I,103::I,107::I,109::I,_
+ 113::I,127::I,131::I,137::I,139::I,149::I,151::I,_
+ 157::I,163::I,167::I,173::I,179::I,181::I,191::I,_
+ 193::I,197::I,199::I,211::I,223::I,227::I,229::I,_
+ 233::I,239::I,241::I,251::I,257::I,263::I,269::I,_
+ 271::I,277::I,281::I,283::I,293::I,307::I,311::I,_
+ 313::I]
+
+ productSmallPrimes := */smallPrimes
+ nextSmallPrime := 317::I
+ nextSmallPrimeSquared := nextSmallPrime**2
+ two := 2::I
+ tenPowerTwenty:=(10::I)**20
+ PomeranceList:= [25326001::I, 161304001::I, 960946321::I, 1157839381::I,
+ -- 3215031751::I, -- has a factor of 151
+ 3697278427::I, 5764643587::I, 6770862367::I,
+ 14386156093::I, 15579919981::I, 18459366157::I,
+ 19887974881::I, 21276028621::I ]::(List I)
+ PomeranceLimit:=27716349961::I -- replaces (25*10**9) due to Pinch
+ PinchList:= [3215031751::I, 118670087467::I, 128282461501::I, 354864744877::I,
+ 546348519181::I, 602248359169::I, 669094855201::I ]
+ PinchLimit:= (10**12)::I
+ PinchList2:= [2152302898747::I, 3474749660383::I]
+ PinchLimit2:= (10**13)::I
+ JaeschkeLimit:=341550071728321::I
+ rootsMinus1:Set I := empty()
+ -- used to check whether we detect too many roots of -1
+ count2Order:Vector NonNegativeInteger := new(1,0)
+ -- used to check whether we observe an element of maximal two-order
+
+ primes(m, n) ==
+ -- computes primes from m to n inclusive using prime?
+ l:List(I) :=
+ m <= two => [two]
+ empty()
+ n < two or n < m => empty()
+ if even? m then m := m + 1
+ ll:List(I) := [k::I for k in
+ convert(m)@Integer..convert(n)@Integer by 2 | prime?(k::I)]
+ reverse_! concat_!(ll, l)
+
+ rabinProvesComposite : (I,I,I,I,NonNegativeInteger) -> Boolean
+ rabinProvesCompositeSmall : (I,I,I,I,NonNegativeInteger) -> Boolean
+
+
+ rabinProvesCompositeSmall(p,n,nm1,q,k) ==
+ -- probability n prime is > 3/4 for each iteration
+ -- for most n this probability is much greater than 3/4
+ t := powmod(p, q, n)
+ -- neither of these cases tells us anything
+-- if not (one? t or t = nm1) then
+ if not ((t = 1) or t = nm1) then
+ for j in 1..k-1 repeat
+ oldt := t
+ t := mulmod(t, t, n)
+-- one? t => return true
+ (t = 1) => return true
+ -- we have squared someting not -1 and got 1
+ t = nm1 =>
+ leave
+ not (t = nm1) => return true
+ false
+
+ rabinProvesComposite(p,n,nm1,q,k) ==
+ -- probability n prime is > 3/4 for each iteration
+ -- for most n this probability is much greater than 3/4
+ t := powmod(p, q, n)
+ -- neither of these cases tells us anything
+ if t=nm1 then count2Order(1):=count2Order(1)+1
+-- if not (one? t or t = nm1) then
+ if not ((t = 1) or t = nm1) then
+ for j in 1..k-1 repeat
+ oldt := t
+ t := mulmod(t, t, n)
+-- one? t => return true
+ (t = 1) => return true
+ -- we have squared someting not -1 and got 1
+ t = nm1 =>
+ rootsMinus1:=union(rootsMinus1,oldt)
+ count2Order(j+1):=count2Order(j+1)+1
+ leave
+ not (t = nm1) => return true
+ # rootsMinus1 > 2 => true -- Z/nZ can't be a field
+ false
+
+ prime? n ==
+ n < two => false
+ n < nextSmallPrime => member?(n, smallPrimes)
+-- not one? gcd(n, productSmallPrimes) => false
+ not (gcd(n, productSmallPrimes) = 1) => false
+ n < nextSmallPrimeSquared => true
+
+ nm1 := n-1
+ q := (nm1) quo two
+ for k in 1.. while not odd? q repeat q := q quo two
+ -- q = (n-1) quo 2**k for largest possible k
+
+ n < JaeschkeLimit =>
+ rabinProvesCompositeSmall(2::I,n,nm1,q,k) => return false
+ rabinProvesCompositeSmall(3::I,n,nm1,q,k) => return false
+
+ n < PomeranceLimit =>
+ rabinProvesCompositeSmall(5::I,n,nm1,q,k) => return false
+ member?(n,PomeranceList) => return false
+ true
+
+ rabinProvesCompositeSmall(7::I,n,nm1,q,k) => return false
+ n < PinchLimit =>
+ rabinProvesCompositeSmall(10::I,n,nm1,q,k) => return false
+ member?(n,PinchList) => return false
+ true
+
+ rabinProvesCompositeSmall(5::I,n,nm1,q,k) => return false
+ rabinProvesCompositeSmall(11::I,n,nm1,q,k) => return false
+ n < PinchLimit2 =>
+ member?(n,PinchList2) => return false
+ true
+
+ rabinProvesCompositeSmall(13::I,n,nm1,q,k) => return false
+ rabinProvesCompositeSmall(17::I,n,nm1,q,k) => return false
+ true
+
+ rootsMinus1:= empty()
+ count2Order := new(k,0) -- vector of k zeroes
+
+ mn := minIndex smallPrimes
+ for i in mn+1..mn+10 repeat
+ rabinProvesComposite(smallPrimes i,n,nm1,q,k) => return false
+ import IntegerRoots(I)
+ q > 1 and perfectSquare?(3*n+1) => false
+ ((n9:=n rem (9::I))=1 or n9 = -1) and perfectSquare?(8*n+1) => false
+ -- Both previous tests from Damgard & Landrock
+ currPrime:=smallPrimes(mn+10)
+ probablySafe:=tenPowerTwenty
+ while count2Order(k) = 0 or n > probablySafe repeat
+ currPrime := nextPrime currPrime
+ probablySafe:=probablySafe*(100::I)
+ rabinProvesComposite(currPrime,n,nm1,q,k) => return false
+ true
+
+ nextPrime n ==
+ -- computes the first prime after n
+ n < two => two
+ if odd? n then n := n + two else n := n + 1
+ while not prime? n repeat n := n + two
+ n
+
+ prevPrime n ==
+ -- computes the first prime before n
+ n < 3::I => error "no primes less than 2"
+ n = 3::I => two
+ if odd? n then n := n - two else n := n - 1
+ while not prime? n repeat n := n - two
+ n
+
+@
+\section{package IROOT IntegerRoots}
+<<package IROOT IntegerRoots>>=
+)abbrev package IROOT IntegerRoots
+++ Author: Michael Monagan
+++ Date Created: November 1987
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: integer roots
+++ Examples:
+++ References:
+++ Description: The \spadtype{IntegerRoots} package computes square roots and
+++ nth roots of integers efficiently.
+IntegerRoots(I:IntegerNumberSystem): Exports == Implementation where
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ perfectNthPower?: (I, NNI) -> Boolean
+ ++ \spad{perfectNthPower?(n,r)} returns true if n is an \spad{r}th
+ ++ power and false otherwise
+ perfectNthRoot: (I,NNI) -> Union(I,"failed")
+ ++ \spad{perfectNthRoot(n,r)} returns the \spad{r}th root of n if n
+ ++ is an \spad{r}th power and returns "failed" otherwise
+ perfectNthRoot: I -> Record(base:I, exponent:NNI)
+ ++ \spad{perfectNthRoot(n)} returns \spad{[x,r]}, where \spad{n = x\^r}
+ ++ and r is the largest integer such that n is a perfect \spad{r}th power
+ approxNthRoot: (I,NNI) -> I
+ ++ \spad{approxRoot(n,r)} returns an approximation x
+ ++ to \spad{n**(1/r)} such that \spad{-1 < x - n**(1/r) < 1}
+ perfectSquare?: I -> Boolean
+ ++ \spad{perfectSquare?(n)} returns true if n is a perfect square
+ ++ and false otherwise
+ perfectSqrt: I -> Union(I,"failed")
+ ++ \spad{perfectSqrt(n)} returns the square root of n if n is a
+ ++ perfect square and returns "failed" otherwise
+ approxSqrt: I -> I
+ ++ \spad{approxSqrt(n)} returns an approximation x
+ ++ to \spad{sqrt(n)} such that \spad{-1 < x - sqrt(n) < 1}.
+ ++ Compute an approximation s to \spad{sqrt(n)} such that
+ ++ \spad{-1 < s - sqrt(n) < 1}
+ ++ A variable precision Newton iteration is used.
+ ++ The running time is \spad{O( log(n)**2 )}.
+
+ Implementation ==> add
+ import IntegerPrimesPackage(I)
+
+ resMod144: List I := [0::I,1::I,4::I,9::I,16::I,25::I,36::I,49::I,_
+ 52::I,64::I,73::I,81::I,97::I,100::I,112::I,121::I]
+ two := 2::I
+
+
+ perfectSquare? a == (perfectSqrt a) case I
+ perfectNthPower?(b, n) == perfectNthRoot(b, n) case I
+
+ perfectNthRoot n == -- complexity (log log n)**2 (log n)**2
+ m:NNI
+-- one? n or zero? n or n = -1 => [n, 1]
+ (n = 1) or zero? n or n = -1 => [n, 1]
+ e:NNI := 1
+ p:NNI := 2
+ while p::I <= length(n) + 1 repeat
+ for m in 0.. while (r := perfectNthRoot(n, p)) case I repeat
+ n := r::I
+ e := e * p ** m
+ p := convert(nextPrime(p::I))@Integer :: NNI
+ [n, e]
+
+ approxNthRoot(a, n) == -- complexity (log log n) (log n)**2
+ zero? n => error "invalid arguments"
+-- one? n => a
+ (n = 1) => a
+ n=2 => approxSqrt a
+ negative? a =>
+ odd? n => - approxNthRoot(-a, n)
+ 0
+ zero? a => 0
+-- one? a => 1
+ (a = 1) => 1
+ -- quick check for case of large n
+ ((3*n) quo 2)::I >= (l := length a) => two
+ -- the initial approximation must be >= the root
+ y := max(two, shift(1, (n::I+l-1) quo (n::I)))
+ z:I := 1
+ n1:= (n-1)::NNI
+ while z > 0 repeat
+ x := y
+ xn:= x**n1
+ y := (n1*x*xn+a) quo (n*xn)
+ z := x-y
+ x
+
+ perfectNthRoot(b, n) ==
+ (r := approxNthRoot(b, n)) ** n = b => r
+ "failed"
+
+ perfectSqrt a ==
+ a < 0 or not member?(a rem (144::I), resMod144) => "failed"
+ (s := approxSqrt a) * s = a => s
+ "failed"
+
+ approxSqrt a ==
+ a < 1 => 0
+ if (n := length a) > (100::I) then
+ -- variable precision newton iteration
+ n := n quo (4::I)
+ s := approxSqrt shift(a, -2 * n)
+ s := shift(s, n)
+ return ((1 + s + a quo s) quo two)
+ -- initial approximation for the root is within a factor of 2
+ (new, old) := (shift(1, n quo two), 1)
+ while new ^= old repeat
+ (new, old) := ((1 + new + a quo new) quo two, new)
+ new
+
+@
+\section{package INTFACT IntegerFactorizationPackage}
+<<package INTFACT IntegerFactorizationPackage>>=
+)abbrev package INTFACT IntegerFactorizationPackage
+++ This Package contains basic methods for integer factorization.
+++ The factor operation employs trial division up to 10,000. It
+++ then tests to see if n is a perfect power before using Pollards
+++ rho method. Because Pollards method may fail, the result
+++ of factor may contain composite factors. We should also employ
+++ Lenstra's eliptic curve method.
+
+IntegerFactorizationPackage(I): Exports == Implementation where
+ I: IntegerNumberSystem
+
+ B ==> Boolean
+ FF ==> Factored I
+ NNI ==> NonNegativeInteger
+ LMI ==> ListMultiDictionary I
+ FFE ==> Record(flg:Union("nil","sqfr","irred","prime"),
+ fctr:I, xpnt:Integer)
+
+ Exports ==> with
+ factor : I -> FF
+ ++ factor(n) returns the full factorization of integer n
+ squareFree : I -> FF
+ ++ squareFree(n) returns the square free factorization of integer n
+ BasicMethod : I -> FF
+ ++ BasicMethod(n) returns the factorization
+ ++ of integer n by trial division
+ PollardSmallFactor: I -> Union(I,"failed")
+ ++ PollardSmallFactor(n) returns a factor
+ ++ of n or "failed" if no one is found
+
+ Implementation ==> add
+ import IntegerRoots(I)
+
+ BasicSieve: (I, I) -> FF
+
+ squareFree(n:I):FF ==
+ u:I
+ if n<0 then (m := -n; u := -1)
+ else (m := n; u := 1)
+ (m > 1) and ((v := perfectSqrt m) case I) =>
+ for rec in (l := factorList(sv := squareFree(v::I))) repeat
+ rec.xpnt := 2 * rec.xpnt
+ makeFR(u * unit sv, l)
+ -- avoid using basic sieve when the lim is too big
+ lim := 1 + approxNthRoot(m,3)
+ lim > (100000::I) => makeFR(u, factorList factor m)
+ x := BasicSieve(m, lim)
+ y :=
+-- one?(m:= unit x) => factorList x
+ ((m:= unit x) = 1) => factorList x
+ (v := perfectSqrt m) case I =>
+ concat_!(factorList x, ["sqfr",v,2]$FFE)
+ concat_!(factorList x, ["sqfr",m,1]$FFE)
+ makeFR(u, y)
+
+ -- Pfun(y: I,n: I): I == (y**2 + 5) rem n
+ PollardSmallFactor(n:I):Union(I,"failed") ==
+ -- Use the Brent variation
+ x0 := random()$I
+ m := 100::I
+ y := x0 rem n
+ r:I := 1
+ q:I := 1
+ G:I := 1
+ until G > 1 repeat
+ x := y
+ for i in 1..convert(r)@Integer repeat
+ y := (y*y+5::I) rem n
+ q := (q*abs(x-y)) rem n
+ k:I := 0
+ until (k>=r) or (G>1) repeat
+ ys := y
+ for i in 1..convert(min(m,r-k))@Integer repeat
+ y := (y*y+5::I) rem n
+ q := q*abs(x-y) rem n
+ G := gcd(q,n)
+ k := k+m
+ r := 2*r
+ if G=n then
+ until G>1 repeat
+ ys := (ys*ys+5::I) rem n
+ G := gcd(abs(x-ys),n)
+ G=n => "failed"
+ G
+
+ BasicSieve(r, lim) ==
+ l:List(I) :=
+ [1::I,2::I,2::I,4::I,2::I,4::I,2::I,4::I,6::I,2::I,6::I]
+ concat_!(l, rest(l, 3))
+ d := 2::I
+ n := r
+ ls := empty()$List(FFE)
+ for s in l repeat
+ d > lim => return makeFR(n, ls)
+ if n<d*d then
+ if n>1 then ls := concat_!(ls, ["prime",n,1]$FFE)
+ return makeFR(1, ls)
+ for m in 0.. while zero?(n rem d) repeat n := n quo d
+ if m>0 then ls := concat_!(ls, ["prime",d,convert m]$FFE)
+ d := d+s
+
+ BasicMethod n ==
+ u:I
+ if n<0 then (m := -n; u := -1)
+ else (m := n; u := 1)
+ x := BasicSieve(m, 1 + approxSqrt m)
+ makeFR(u, factorList x)
+
+ factor m ==
+ u:I
+ zero? m => 0
+ if negative? m then (n := -m; u := -1)
+ else (n := m; u := 1)
+ b := BasicSieve(n, 10000::I)
+ flb := factorList b
+-- one?(n := unit b) => makeFR(u, flb)
+ ((n := unit b) = 1) => makeFR(u, flb)
+ a:LMI := dictionary() -- numbers yet to be factored
+ b:LMI := dictionary() -- prime factors found
+ f:LMI := dictionary() -- number which could not be factored
+ insert_!(n, a)
+ while not empty? a repeat
+ n := inspect a; c := count(n, a); remove_!(n, a)
+ prime?(n)$IntegerPrimesPackage(I) => insert_!(n, b, c)
+ -- test for a perfect power
+ (s := perfectNthRoot n).exponent > 1 =>
+ insert_!(s.base, a, c * s.exponent)
+ -- test for a difference of square
+ x:=approxSqrt n;
+ if (x**2<n) then x:=x+1
+ (y:=perfectSqrt (x**2-n)) case I =>
+ insert_!(x+y,a,c)
+ insert_!(x-y,a,c)
+ (d := PollardSmallFactor n) case I =>
+ for m in 0.. while zero?(n rem d) repeat n := n quo d
+ insert_!(d, a, m * c)
+ if n > 1 then insert_!(n, a, c)
+ -- an elliptic curve factorization attempt should be made here
+ insert_!(n, f, c)
+ -- insert prime factors found
+ while not empty? b repeat
+ n := inspect b; c := count(n, b); remove_!(n, b)
+ flb := concat_!(flb, ["prime",n,convert c]$FFE)
+ -- insert non-prime factors found
+ while not empty? f repeat
+ n := inspect f; c := count(n, f); remove_!(n, f)
+ flb := concat_!(flb, ["nil",n,convert c]$FFE)
+ makeFR(u, flb)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PRIMES IntegerPrimesPackage>>
+<<package IROOT IntegerRoots>>
+<<package INTFACT IntegerFactorizationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intpm.spad.pamphlet b/src/algebra/intpm.spad.pamphlet
new file mode 100644
index 00000000..49f03dbe
--- /dev/null
+++ b/src/algebra/intpm.spad.pamphlet
@@ -0,0 +1,377 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intpm.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTPM PatternMatchIntegration}
+<<package INTPM PatternMatchIntegration>>=
+)abbrev package INTPM PatternMatchIntegration
+++ Author: Manuel Bronstein
+++ Date Created: 5 May 1992
+++ Date Last Updated: 27 September 1995
+++ Description:
+++ \spadtype{PatternMatchIntegration} provides functions that use
+++ the pattern matcher to find some indefinite and definite integrals
+++ involving special functions and found in the litterature.
+PatternMatchIntegration(R, F): Exports == Implementation where
+ R : Join(OrderedSet, RetractableTo Integer, GcdDomain,
+ LinearlyExplicitRingOver Integer)
+ F : Join(AlgebraicallyClosedField, TranscendentalFunctionCategory,
+ FunctionSpace R)
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ SY ==> Symbol
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ SUP ==> SparseUnivariatePolynomial F
+ PAT ==> Pattern Z
+ RES ==> PatternMatchResult(Z, F)
+ OFE ==> OrderedCompletion F
+ REC ==> Record(which: Z, exponent: F, coeff: F)
+ ANS ==> Record(special:F, integrand:F)
+ NONE ==> 0
+ EI ==> 1
+ ERF ==> 2
+ SI ==> 3
+ CI ==> 4
+ GAM2 ==> 5
+ CI0 ==> 6
+
+ Exports ==> with
+ splitConstant: (F, SY) -> Record(const:F, nconst:F)
+ ++ splitConstant(f, x) returns \spad{[c, g]} such that
+ ++ \spad{f = c * g} and \spad{c} does not involve \spad{t}.
+ if R has ConvertibleTo Pattern Integer and
+ R has PatternMatchable Integer then
+ if F has LiouvillianFunctionCategory then
+ pmComplexintegrate: (F, SY) -> Union(ANS, "failed")
+ ++ pmComplexintegrate(f, x) returns either "failed" or
+ ++ \spad{[g,h]} such that
+ ++ \spad{integrate(f,x) = g + integrate(h,x)}.
+ ++ It only looks for special complex integrals that pmintegrate
+ ++ does not return.
+ pmintegrate: (F, SY) -> Union(ANS, "failed")
+ ++ pmintegrate(f, x) returns either "failed" or \spad{[g,h]} such
+ ++ that \spad{integrate(f,x) = g + integrate(h,x)}.
+ if F has SpecialFunctionCategory then
+ pmintegrate: (F, SY, OFE, OFE) -> Union(F, "failed")
+ ++ pmintegrate(f, x = a..b) returns the integral of
+ ++ \spad{f(x)dx} from a to b
+ ++ if it can be found by the built-in pattern matching rules.
+
+ Implementation ==> add
+ import PatternMatch(Z, F, F)
+ import ElementaryFunctionSign(R, F)
+ import FunctionSpaceAssertions(R, F)
+ import TrigonometricManipulations(R, F)
+ import FunctionSpaceAttachPredicates(R, F, F)
+
+ mkalist : RES -> AssociationList(SY, F)
+
+ pm := new()$SY
+ pmw := new pm
+ pmm := new pm
+ pms := new pm
+ pmc := new pm
+ pma := new pm
+ pmb := new pm
+
+ c := optional(pmc::F)
+ w := suchThat(optional(pmw::F), empty? variables #1)
+ s := suchThat(optional(pms::F), empty? variables #1 and real? #1)
+ m := suchThat(optional(pmm::F),
+ (retractIfCan(#1)@Union(Z,"failed") case Z) and #1 >= 0)
+
+ spi := sqrt(pi()$F)
+
+ half := 1::F / 2::F
+
+ mkalist res == construct destruct res
+
+ splitConstant(f, x) ==
+ not member?(x, variables f) => [f, 1]
+ (retractIfCan(f)@Union(K, "failed")) case K => [1, f]
+ (u := isTimes f) case List(F) =>
+ cc := nc := 1$F
+ for g in u::List(F) repeat
+ rec := splitConstant(g, x)
+ cc := cc * rec.const
+ nc := nc * rec.nconst
+ [cc, nc]
+ (u := isPlus f) case List(F) =>
+ rec := splitConstant(first(u::List(F)), x)
+ cc := rec.const
+ nc := rec.nconst
+ for g in rest(u::List(F)) repeat
+ rec := splitConstant(g, x)
+ if rec.nconst = nc then cc := cc + rec.const
+ else if rec.nconst = -nc then cc := cc - rec.const
+ else return [1, f]
+ [cc, nc]
+ if (v := isPower f) case Record(val:F, exponent:Z) then
+ vv := v::Record(val:F, exponent:Z)
+ (vv.exponent ^= 1) =>
+ rec := splitConstant(vv.val, x)
+ return [rec.const ** vv.exponent, rec.nconst ** vv.exponent]
+ error "splitConstant: should not happen"
+
+ if R has ConvertibleTo Pattern Integer and
+ R has PatternMatchable Integer then
+ if F has LiouvillianFunctionCategory then
+ import ElementaryFunctionSign(R, F)
+
+ insqrt : F -> F
+ matchei : (F, SY) -> REC
+ matcherfei : (F, SY, Boolean) -> REC
+ matchsici : (F, SY) -> REC
+ matchli : (F, SY) -> List F
+ matchli0 : (F, K, SY) -> List F
+ matchdilog : (F, SY) -> List F
+ matchdilog0: (F, K, SY, P, F) -> List F
+ goodlilog? : (K, P) -> Boolean
+ gooddilog? : (K, P, P) -> Boolean
+
+-- goodlilog?(k, p) == is?(k, "log"::SY) and one? minimumDegree(p, k)
+ goodlilog?(k, p) == is?(k, "log"::SY) and (minimumDegree(p, k) = 1)
+
+ gooddilog?(k, p, q) ==
+-- is?(k, "log"::SY) and one? degree(p, k) and zero? degree(q, k)
+ is?(k, "log"::SY) and (degree(p, k) = 1) and zero? degree(q, k)
+
+-- matches the integral to a result of the form d * erf(u) or d * ei(u)
+-- returns [case, u, d]
+ matcherfei(f, x, comp?) ==
+ res0 := new()$RES
+ pat := c * exp(pma::F)
+ failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ comp? => [NONE, 0,0]
+ matchei(f,x)
+ l := mkalist res
+ da := differentiate(a := l.pma, x)
+ d := a * (cc := l.pmc) / da
+ zero? differentiate(d, x) => [EI, a, d]
+ comp? or (((u := sign a) case Z) and (u::Z) < 0) =>
+ d := cc * (sa := insqrt(- a)) / da
+ zero? differentiate(d, x) => [ERF, sa, - d * spi]
+ [NONE, 0, 0]
+ [NONE, 0, 0]
+
+-- matches the integral to a result of the form d * ei(k * log u)
+-- returns [case, k * log u, d]
+ matchei(f, x) ==
+ res0 := new()$RES
+ a := pma::F
+ pat := c * a**w / log a
+ failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ [NONE, 0, 0]
+ l := mkalist res
+ da := differentiate(a := l.pma, x)
+ d := (cc := l.pmc) / da
+ zero? differentiate(d, x) => [EI, (1 + l.pmw) * log a, d]
+ [NONE, 0, 0]
+
+-- matches the integral to a result of the form d * dilog(u) + int(v),
+-- returns [u,d,v] or []
+ matchdilog(f, x) ==
+ n := numer f
+ df := (d := denom f)::F
+ for k in select_!(gooddilog?(#1, n, d), variables n)$List(K) repeat
+ not empty?(l := matchdilog0(f, k, x, n, df)) => return l
+ empty()
+
+-- matches the integral to a result of the form d * dilog(a) + int(v)
+-- where k = log(a)
+-- returns [a,d,v] or []
+ matchdilog0(f, k, x, p, q) ==
+ zero?(da := differentiate(a := first argument k, x)) => empty()
+ a1 := 1 - a
+ d := coefficient(univariate(p, k), 1)::F * a1 / (q * da)
+ zero? differentiate(d, x) => [a, d, f - d * da * (k::F) / a1]
+ empty()
+
+-- matches the integral to a result of the form d * li(u) + int(v),
+-- returns [u,d,v] or []
+ matchli(f, x) ==
+ d := denom f
+ for k in select_!(goodlilog?(#1, d), variables d)$List(K) repeat
+ not empty?(l := matchli0(f, k, x)) => return l
+ empty()
+
+-- matches the integral to a result of the form d * li(a) + int(v)
+-- where k = log(a)
+-- returns [a,d,v] or []
+ matchli0(f, k, x) ==
+ g := (lg := k::F) * f
+ zero?(da := differentiate(a := first argument k, x)) => empty()
+ zero? differentiate(d := g / da, x) => [a, d, 0]
+ ug := univariate(g, k)
+ (u:=retractIfCan(ug)@Union(SUP,"failed")) case "failed" => empty()
+ degree(p := u::SUP) > 1 => empty()
+ zero? differentiate(d := coefficient(p, 0) / da, x) =>
+ [a, d, leadingCoefficient p]
+ empty()
+
+-- matches the integral to a result of the form d * Si(u) or d * Ci(u)
+-- returns [case, u, d]
+ matchsici(f, x) ==
+ res0 := new()$RES
+ b := pmb::F
+ t := tan(a := pma::F)
+ patsi := c * t / (patden := b + b * t**2)
+ patci := (c - c * t**2) / patden
+ patci0 := c / patden
+ ci0?:Boolean
+ (ci? := failed?(res := patternMatch(f, convert(patsi)@PAT, res0)))
+ and (ci0?:=failed?(res:=patternMatch(f,convert(patci)@PAT,res0)))
+ and failed?(res := patternMatch(f,convert(patci0)@PAT,res0)) =>
+ [NONE, 0, 0]
+ l := mkalist res
+ (b := l.pmb) ^= 2 * (a := l.pma) => [NONE, 0, 0]
+ db := differentiate(b, x)
+ d := (cc := l.pmc) / db
+ zero? differentiate(d, x) =>
+ ci? =>
+ ci0? => [CI0, b, d / (2::F)]
+ [CI, b, d]
+ [SI, b, d / (2::F)]
+ [NONE, 0, 0]
+
+-- returns a simplified sqrt(y)
+ insqrt y ==
+ rec := froot(y, 2)$PolynomialRoots(IndexedExponents K, K, R, P, F)
+-- one?(rec.exponent) => rec.coef * rec.radicand
+ ((rec.exponent) = 1) => rec.coef * rec.radicand
+ rec.exponent ^=2 => error "insqrt: hould not happen"
+ rec.coef * sqrt(rec.radicand)
+
+ pmintegrate(f, x) ==
+ (rc := splitConstant(f, x)).const ^= 1 =>
+ (u := pmintegrate(rc.nconst, x)) case "failed" => "failed"
+ rec := u::ANS
+ [rc.const * rec.special, rc.const * rec.integrand]
+ not empty?(l := matchli(f, x)) => [second l * li first l, third l]
+ not empty?(l := matchdilog(f, x)) =>
+ [second l * dilog first l, third l]
+ cse := (rec := matcherfei(f, x, false)).which
+ cse = EI => [rec.coeff * Ei(rec.exponent), 0]
+ cse = ERF => [rec.coeff * erf(rec.exponent), 0]
+ cse := (rec := matchsici(f, x)).which
+ cse = SI => [rec.coeff * Si(rec.exponent), 0]
+ cse = CI => [rec.coeff * Ci(rec.exponent), 0]
+ cse = CI0 => [rec.coeff * Ci(rec.exponent)
+ + rec.coeff * log(rec.exponent), 0]
+ "failed"
+
+ pmComplexintegrate(f, x) ==
+ (rc := splitConstant(f, x)).const ^= 1 =>
+ (u := pmintegrate(rc.nconst, x)) case "failed" => "failed"
+ rec := u::ANS
+ [rc.const * rec.special, rc.const * rec.integrand]
+ cse := (rec := matcherfei(f, x, true)).which
+ cse = ERF => [rec.coeff * erf(rec.exponent), 0]
+ "failed"
+
+ if F has SpecialFunctionCategory then
+ match1 : (F, SY, F, F) -> List F
+ formula1 : (F, SY, F, F) -> Union(F, "failed")
+
+-- tries only formula (1) of the Geddes & al, AAECC 1 (1990) paper
+ formula1(f, x, t, cc) ==
+ empty?(l := match1(f, x, t, cc)) => "failed"
+ mw := first l
+ zero?(ms := third l) or ((sgs := sign ms) case "failed")=> "failed"
+ ((sgz := sign(z := (mw + 1) / ms)) case "failed") or (sgz::Z < 0)
+ => "failed"
+ mmi := retract(mm := second l)@Z
+ sgs * (last l) * ms**(- mmi - 1) *
+ eval(differentiate(Gamma(x::F), x, mmi::N), [kernel(x)@K], [z])
+
+-- returns [w, m, s, c] or []
+-- matches only formula (1) of the Geddes & al, AAECC 1 (1990) paper
+ match1(f, x, t, cc) ==
+ res0 := new()$RES
+ pat := cc * log(t)**m * exp(-t**s)
+ not failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ l := mkalist res
+ [0, l.pmm, l.pms, l.pmc]
+ pat := cc * t**w * exp(-t**s)
+ not failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ l := mkalist res
+ [l.pmw, 0, l.pms, l.pmc]
+ pat := cc / t**w * exp(-t**s)
+ not failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ l := mkalist res
+ [- l.pmw, 0, l.pms, l.pmc]
+ pat := cc * t**w * log(t)**m * exp(-t**s)
+ not failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ l := mkalist res
+ [l.pmw, l.pmm, l.pms, l.pmc]
+ pat := cc / t**w * log(t)**m * exp(-t**s)
+ not failed?(res := patternMatch(f, convert(pat)@PAT, res0)) =>
+ l := mkalist res
+ [- l.pmw, l.pmm, l.pms, l.pmc]
+ empty()
+
+ pmintegrate(f, x, a, b) ==
+-- zero? a and one? whatInfinity b =>
+ zero? a and ((whatInfinity b) = 1) =>
+ formula1(f, x, constant(x::F), suchThat(c, freeOf?(#1, x)))
+ "failed"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg intaf efstruc rdeef INTPM intef irexpand integrat
+
+<<package INTPM PatternMatchIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/intrf.spad.pamphlet b/src/algebra/intrf.spad.pamphlet
new file mode 100644
index 00000000..17f21167
--- /dev/null
+++ b/src/algebra/intrf.spad.pamphlet
@@ -0,0 +1,911 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra intrf.spad}
+\author{Barry Trager, Renaud Rioboo, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SUBRESP SubResultantPackage}
+<<package SUBRESP SubResultantPackage>>=
+)abbrev package SUBRESP SubResultantPackage
+++ Subresultants
+++ Author: Barry Trager, Renaud Rioboo
+++ Date Created: 1987
+++ Date Last Updated: August 2000
+++ Description:
+++ This package computes the subresultants of two polynomials which is needed
+++ for the `Lazard Rioboo' enhancement to Tragers integrations formula
+++ For efficiency reasons this has been rewritten to call Lionel Ducos
+++ package which is currently the best one.
+++
+SubResultantPackage(R, UP): Exports == Implementation where
+ R : IntegralDomain
+ UP: UnivariatePolynomialCategory R
+
+ Z ==> Integer
+ N ==> NonNegativeInteger
+
+ Exports ==> with
+ subresultantVector: (UP, UP) -> PrimitiveArray UP
+ ++ subresultantVector(p, q) returns \spad{[p0,...,pn]}
+ ++ where pi is the i-th subresultant of p and q.
+ ++ In particular, \spad{p0 = resultant(p, q)}.
+ if R has EuclideanDomain then
+ primitivePart : (UP, R) -> UP
+ ++ primitivePart(p, q) reduces the coefficient of p
+ ++ modulo q, takes the primitive part of the result,
+ ++ and ensures that the leading coefficient of that
+ ++ result is monic.
+
+ Implementation ==> add
+
+ Lionel ==> PseudoRemainderSequence(R,UP)
+
+ if R has EuclideanDomain then
+ primitivePart(p, q) ==
+ rec := extendedEuclidean(leadingCoefficient p, q,
+ 1)::Record(coef1:R, coef2:R)
+ unitCanonical primitivePart map((rec.coef1 * #1) rem q, p)
+
+ subresultantVector(p1, p2) ==
+ F : UP -- auxiliary stuff !
+ res : PrimitiveArray(UP) := new(2+max(degree(p1),degree(p2)), 0)
+ --
+ -- kind of stupid interface to Lionel's Package !!!!!!!!!!!!
+ -- might have been wiser to rewrite the loop ...
+ -- But I'm too lazy. [rr]
+ --
+ l := chainSubResultants(p1,p2)$Lionel
+ --
+ -- this returns the chain of non null subresultants !
+ -- we must rebuild subresultants from this.
+ -- we really hope Lionel Ducos minded what he wrote
+ -- since we are fully blind !
+ --
+ null l =>
+ -- Hum it seems that Lionel returns [] when min(|p1|,|p2|) = 0
+ zero?(degree(p1)) =>
+ res.degree(p2) := p2
+ if degree(p2) > 0
+ then
+ res.((degree(p2)-1)::NonNegativeInteger) := p1
+ res.0 := (leadingCoefficient(p1)**(degree p2)) :: UP
+ else
+ -- both are of degree 0 the resultant is 1 according to Loos
+ res.0 := 1
+ res
+ zero?(degree(p2)) =>
+ if degree(p1) > 0
+ then
+ res.((degree(p1)-1)::NonNegativeInteger) := p2
+ res.0 := (leadingCoefficient(p2)**(degree p1)) :: UP
+ else
+ -- both are of degree 0 the resultant is 1 according to Loos
+ res.0 := 1
+ res
+ error "SUBRESP: strange Subresultant chain from PRS"
+ Sn := first(l)
+ --
+ -- as of Loos definitions last subresultant should not be defective
+ --
+ l := rest(l)
+ n := degree(Sn)
+ F := Sn
+ null l => error "SUBRESP: strange Subresultant chain from PRS"
+ zero? Sn => error "SUBRESP: strange Subresultant chain from PRS"
+ while (l ^= []) repeat
+ res.(n) := Sn
+ F := first(l)
+ l := rest(l)
+ -- F is potentially defective
+ if degree(F) = n
+ then
+ --
+ -- F is defective
+ --
+ null l => error "SUBRESP: strange Subresultant chain from PRS"
+ Sn := first(l)
+ l := rest(l)
+ n := degree(Sn)
+ res.((n-1)::NonNegativeInteger) := F
+ else
+ --
+ -- F is non defective
+ --
+ degree(F) < n => error "strange result !"
+ Sn := F
+ n := degree(Sn)
+ --
+ -- Lionel forgets about p1 if |p1| > |p2|
+ -- forgets about p2 if |p2| > |p1|
+ -- but he reminds p2 if |p1| = |p2|
+ -- a glance at Loos should correct this !
+ --
+ res.n := Sn
+ --
+ -- Loos definition
+ --
+ if degree(p1) = degree(p2)
+ then
+ res.((degree p1)+1) := p1
+ else
+ if degree(p1) > degree(p2)
+ then
+ res.(degree p1) := p1
+ else
+ res.(degree p2) := p2
+ res
+
+@
+\section{package MONOTOOL MonomialExtensionTools}
+<<package MONOTOOL MonomialExtensionTools>>=
+)abbrev package MONOTOOL MonomialExtensionTools
+++ Tools for handling monomial extensions
+++ Author: Manuel Bronstein
+++ Date Created: 18 August 1992
+++ Date Last Updated: 3 June 1993
+++ Description: Tools for handling monomial extensions.
+MonomialExtensionTools(F, UP): Exports == Implementation where
+ F : Field
+ UP: UnivariatePolynomialCategory F
+
+ RF ==> Fraction UP
+ FR ==> Factored UP
+
+ Exports ==> with
+ split : (UP, UP -> UP) -> Record(normal:UP, special:UP)
+ ++ split(p, D) returns \spad{[n,s]} such that \spad{p = n s},
+ ++ all the squarefree factors of n are normal w.r.t. D,
+ ++ and s is special w.r.t. D.
+ ++ D is the derivation to use.
+ splitSquarefree: (UP, UP -> UP) -> Record(normal:FR, special:FR)
+ ++ splitSquarefree(p, D) returns
+ ++ \spad{[n_1 n_2\^2 ... n_m\^m, s_1 s_2\^2 ... s_q\^q]} such that
+ ++ \spad{p = n_1 n_2\^2 ... n_m\^m s_1 s_2\^2 ... s_q\^q}, each
+ ++ \spad{n_i} is normal w.r.t. D and each \spad{s_i} is special
+ ++ w.r.t D.
+ ++ D is the derivation to use.
+ normalDenom: (RF, UP -> UP) -> UP
+ ++ normalDenom(f, D) returns the product of all the normal factors
+ ++ of \spad{denom(f)}.
+ ++ D is the derivation to use.
+ decompose : (RF, UP -> UP) -> Record(poly:UP, normal:RF, special:RF)
+ ++ decompose(f, D) returns \spad{[p,n,s]} such that \spad{f = p+n+s},
+ ++ all the squarefree factors of \spad{denom(n)} are normal w.r.t. D,
+ ++ \spad{denom(s)} is special w.r.t. D,
+ ++ and n and s are proper fractions (no pole at infinity).
+ ++ D is the derivation to use.
+
+ Implementation ==> add
+ normalDenom(f, derivation) == split(denom f, derivation).normal
+
+ split(p, derivation) ==
+ pbar := (gcd(p, derivation p) exquo gcd(p, differentiate p))::UP
+ zero? degree pbar => [p, 1]
+ rec := split((p exquo pbar)::UP, derivation)
+ [rec.normal, pbar * rec.special]
+
+ splitSquarefree(p, derivation) ==
+ s:Factored(UP) := 1
+ n := s
+ q := squareFree p
+ for rec in factors q repeat
+ r := rec.factor
+ g := gcd(r, derivation r)
+ if not ground? g then s := s * sqfrFactor(g, rec.exponent)
+ h := (r exquo g)::UP
+ if not ground? h then n := n * sqfrFactor(h, rec.exponent)
+ [n, unit(q) * s]
+
+ decompose(f, derivation) ==
+ qr := divide(numer f, denom f)
+-- rec.normal * rec.special = denom f
+ rec := split(denom f, derivation)
+-- eeu.coef1 * rec.normal + eeu.coef2 * rec.special = qr.remainder
+-- and degree(eeu.coef1) < degree(rec.special)
+-- and degree(eeu.coef2) < degree(rec.normal)
+-- qr.remainder/denom(f) = eeu.coef1 / rec.special + eeu.coef2 / rec.normal
+ eeu := extendedEuclidean(rec.normal, rec.special,
+ qr.remainder)::Record(coef1:UP, coef2:UP)
+ [qr.quotient, eeu.coef2 / rec.normal, eeu.coef1 / rec.special]
+
+@
+\section{package INTHERTR TranscendentalHermiteIntegration}
+<<package INTHERTR TranscendentalHermiteIntegration>>=
+)abbrev package INTHERTR TranscendentalHermiteIntegration
+++ Hermite integration, transcendental case
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 12 August 1992
+++ Description: Hermite integration, transcendental case.
+TranscendentalHermiteIntegration(F, UP): Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ RF ==> Fraction UP
+ REC ==> Record(answer:RF, lognum:UP, logden:UP)
+ HER ==> Record(answer:RF, logpart:RF, specpart:RF, polypart:UP)
+
+ Exports ==> with
+ HermiteIntegrate: (RF, UP -> UP) -> HER
+ ++ HermiteIntegrate(f, D) returns \spad{[g, h, s, p]}
+ ++ such that \spad{f = Dg + h + s + p},
+ ++ h has a squarefree denominator normal w.r.t. D,
+ ++ and all the squarefree factors of the denominator of s are
+ ++ special w.r.t. D. Furthermore, h and s have no polynomial parts.
+ ++ D is the derivation to use on \spadtype{UP}.
+
+ Implementation ==> add
+ import MonomialExtensionTools(F, UP)
+
+ normalHermiteIntegrate: (RF,UP->UP) -> Record(answer:RF,lognum:UP,logden:UP)
+
+ HermiteIntegrate(f, derivation) ==
+ rec := decompose(f, derivation)
+ hi := normalHermiteIntegrate(rec.normal, derivation)
+ qr := divide(hi.lognum, hi.logden)
+ [hi.answer, qr.remainder / hi.logden, rec.special, qr.quotient + rec.poly]
+
+-- Hermite Reduction on f, every squarefree factor of denom(f) is normal wrt D
+-- this is really a "parallel" Hermite reduction, in the sense that
+-- every multiple factor of the denominator gets reduced at each pass
+-- so if the denominator is P1 P2**2 ... Pn**n, this requires O(n)
+-- reduction steps instead of O(n**2), like Mack's algorithm
+-- (D.Mack, On Rational Integration, Univ. of Utah C.S. Tech.Rep. UCP-38,1975)
+-- returns [g, b, d] s.t. f = g' + b/d and d is squarefree and normal wrt D
+ normalHermiteIntegrate(f, derivation) ==
+ a := numer f
+ q := denom f
+ p:UP := 0
+ mult:UP := 1
+ qhat := (q exquo (g0 := g := gcd(q, differentiate q)))::UP
+ while(degree(qbar := g) > 0) repeat
+ qbarhat := (qbar exquo (g := gcd(qbar, differentiate qbar)))::UP
+ qtil:= - ((qhat * (derivation qbar)) exquo qbar)::UP
+ bc :=
+ extendedEuclidean(qtil, qbarhat, a)::Record(coef1:UP, coef2:UP)
+ qr := divide(bc.coef1, qbarhat)
+ a := bc.coef2 + qtil * qr.quotient - derivation(qr.remainder)
+ * (qhat exquo qbarhat)::UP
+ p := p + mult * qr.remainder
+ mult:= mult * qbarhat
+ [p / g0, a, qhat]
+
+@
+\section{package INTTR TranscendentalIntegration}
+<<package INTTR TranscendentalIntegration>>=
+)abbrev package INTTR TranscendentalIntegration
+++ Risch algorithm, transcendental case
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 24 October 1995
+++ Description:
+++ This package provides functions for the transcendental
+++ case of the Risch algorithm.
+-- Internally used by the integrator
+TranscendentalIntegration(F, UP): Exports == Implementation where
+ F : Field
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Z
+ GP ==> LaurentPolynomial(F, UP)
+ UP2 ==> SparseUnivariatePolynomial UP
+ RF ==> Fraction UP
+ UPR ==> SparseUnivariatePolynomial RF
+ IR ==> IntegrationResult RF
+ LOG ==> Record(scalar:Q, coeff:UPR, logand:UPR)
+ LLG ==> List Record(coeff:RF, logand:RF)
+ NE ==> Record(integrand:RF, intvar:RF)
+ NL ==> Record(mainpart:RF, limitedlogs:LLG)
+ UPF ==> Record(answer:UP, a0:F)
+ RFF ==> Record(answer:RF, a0:F)
+ IRF ==> Record(answer:IR, a0:F)
+ NLF ==> Record(answer:NL, a0:F)
+ GPF ==> Record(answer:GP, a0:F)
+ UPUP==> Record(elem:UP, notelem:UP)
+ GPGP==> Record(elem:GP, notelem:GP)
+ RFRF==> Record(elem:RF, notelem:RF)
+ FF ==> Record(ratpart:F, coeff:F)
+ FFR ==> Record(ratpart:RF, coeff:RF)
+ UF ==> Union(FF, "failed")
+ UF2 ==> Union(List F, "failed")
+ REC ==> Record(ir:IR, specpart:RF, polypart:UP)
+ PSOL==> Record(ans:F, right:F, sol?:Boolean)
+ FAIL==> error "Sorry - cannot handle that integrand yet"
+
+ Exports ==> with
+ primintegrate : (RF, UP -> UP, F -> UF) -> IRF
+ ++ primintegrate(f, ', foo) returns \spad{[g, a]} such that
+ ++ \spad{f = g' + a}, and \spad{a = 0} or \spad{a} has no integral in UP.
+ ++ Argument foo is an extended integration function on F.
+ expintegrate : (RF, UP -> UP, (Z, F) -> PSOL) -> IRF
+ ++ expintegrate(f, ', foo) returns \spad{[g, a]} such that
+ ++ \spad{f = g' + a}, and \spad{a = 0} or \spad{a} has no integral in F;
+ ++ Argument foo is a Risch differential equation solver on F;
+ tanintegrate : (RF, UP -> UP, (Z, F, F) -> UF2) -> IRF
+ ++ tanintegrate(f, ', foo) returns \spad{[g, a]} such that
+ ++ \spad{f = g' + a}, and \spad{a = 0} or \spad{a} has no integral in F;
+ ++ Argument foo is a Risch differential system solver on F;
+ primextendedint:(RF, UP -> UP, F->UF, RF) -> Union(RFF,FFR,"failed")
+ ++ primextendedint(f, ', foo, g) returns either \spad{[v, c]} such that
+ ++ \spad{f = v' + c g} and \spad{c' = 0}, or \spad{[v, a]} such that
+ ++ \spad{f = g' + a}, and \spad{a = 0} or \spad{a} has no integral in UP.
+ ++ Returns "failed" if neither case can hold.
+ ++ Argument foo is an extended integration function on F.
+ expextendedint:(RF,UP->UP,(Z,F)->PSOL, RF) -> Union(RFF,FFR,"failed")
+ ++ expextendedint(f, ', foo, g) returns either \spad{[v, c]} such that
+ ++ \spad{f = v' + c g} and \spad{c' = 0}, or \spad{[v, a]} such that
+ ++ \spad{f = g' + a}, and \spad{a = 0} or \spad{a} has no integral in F.
+ ++ Returns "failed" if neither case can hold.
+ ++ Argument foo is a Risch differential equation function on F.
+ primlimitedint:(RF, UP -> UP, F->UF, List RF) -> Union(NLF,"failed")
+ ++ primlimitedint(f, ', foo, [u1,...,un]) returns
+ ++ \spad{[v, [c1,...,cn], a]} such that \spad{ci' = 0},
+ ++ \spad{f = v' + a + reduce(+,[ci * ui'/ui])},
+ ++ and \spad{a = 0} or \spad{a} has no integral in UP.
+ ++ Returns "failed" if no such v, ci, a exist.
+ ++ Argument foo is an extended integration function on F.
+ explimitedint:(RF, UP->UP,(Z,F)->PSOL,List RF) -> Union(NLF,"failed")
+ ++ explimitedint(f, ', foo, [u1,...,un]) returns
+ ++ \spad{[v, [c1,...,cn], a]} such that \spad{ci' = 0},
+ ++ \spad{f = v' + a + reduce(+,[ci * ui'/ui])},
+ ++ and \spad{a = 0} or \spad{a} has no integral in F.
+ ++ Returns "failed" if no such v, ci, a exist.
+ ++ Argument foo is a Risch differential equation function on F.
+ primextintfrac : (RF, UP -> UP, RF) -> Union(FFR, "failed")
+ ++ primextintfrac(f, ', g) returns \spad{[v, c]} such that
+ ++ \spad{f = v' + c g} and \spad{c' = 0}.
+ ++ Error: if \spad{degree numer f >= degree denom f} or
+ ++ if \spad{degree numer g >= degree denom g} or
+ ++ if \spad{denom g} is not squarefree.
+ primlimintfrac : (RF, UP -> UP, List RF) -> Union(NL, "failed")
+ ++ primlimintfrac(f, ', [u1,...,un]) returns \spad{[v, [c1,...,cn]]}
+ ++ such that \spad{ci' = 0} and \spad{f = v' + +/[ci * ui'/ui]}.
+ ++ Error: if \spad{degree numer f >= degree denom f}.
+ primintfldpoly : (UP, F -> UF, F) -> Union(UP, "failed")
+ ++ primintfldpoly(p, ', t') returns q such that \spad{p' = q} or
+ ++ "failed" if no such q exists. Argument \spad{t'} is the derivative of
+ ++ the primitive generating the extension.
+ expintfldpoly : (GP, (Z, F) -> PSOL) -> Union(GP, "failed")
+ ++ expintfldpoly(p, foo) returns q such that \spad{p' = q} or
+ ++ "failed" if no such q exists.
+ ++ Argument foo is a Risch differential equation function on F.
+ monomialIntegrate : (RF, UP -> UP) -> REC
+ ++ monomialIntegrate(f, ') returns \spad{[ir, s, p]} such that
+ ++ \spad{f = ir' + s + p} and all the squarefree factors of the
+ ++ denominator of s are special w.r.t the derivation '.
+ monomialIntPoly : (UP, UP -> UP) -> Record(answer:UP, polypart:UP)
+ ++ monomialIntPoly(p, ') returns [q, r] such that
+ ++ \spad{p = q' + r} and \spad{degree(r) < degree(t')}.
+ ++ Error if \spad{degree(t') < 2}.
+
+ Implementation ==> add
+ import SubResultantPackage(UP, UP2)
+ import MonomialExtensionTools(F, UP)
+ import TranscendentalHermiteIntegration(F, UP)
+ import CommuteUnivariatePolynomialCategory(F, UP, UP2)
+
+ primintegratepoly : (UP, F -> UF, F) -> Union(UPF, UPUP)
+ expintegratepoly : (GP, (Z, F) -> PSOL) -> Union(GPF, GPGP)
+ expextintfrac : (RF, UP -> UP, RF) -> Union(FFR, "failed")
+ explimintfrac : (RF, UP -> UP, List RF) -> Union(NL, "failed")
+ limitedLogs : (RF, RF -> RF, List RF) -> Union(LLG, "failed")
+ logprmderiv : (RF, UP -> UP) -> RF
+ logexpderiv : (RF, UP -> UP, F) -> RF
+ tanintegratespecial: (RF, RF -> RF, (Z, F, F) -> UF2) -> Union(RFF, RFRF)
+ UP2UP2 : UP -> UP2
+ UP2UPR : UP -> UPR
+ UP22UPR : UP2 -> UPR
+ notelementary : REC -> IR
+ kappa : (UP, UP -> UP) -> UP
+
+ dummy:RF := 0
+
+ logprmderiv(f, derivation) == differentiate(f, derivation) / f
+
+ UP2UP2 p ==
+ map(#1::UP, p)$UnivariatePolynomialCategoryFunctions2(F, UP, UP, UP2)
+
+ UP2UPR p ==
+ map(#1::UP::RF, p)$UnivariatePolynomialCategoryFunctions2(F, UP, RF, UPR)
+
+ UP22UPR p == map(#1::RF, p)$SparseUnivariatePolynomialFunctions2(UP, RF)
+
+-- given p in k[z] and a derivation on k[t] returns the coefficient lifting
+-- in k[z] of the restriction of D to k.
+ kappa(p, derivation) ==
+ ans:UP := 0
+ while p ^= 0 repeat
+ ans := ans + derivation(leadingCoefficient(p)::UP)*monomial(1,degree p)
+ p := reductum p
+ ans
+
+-- works in any monomial extension
+ monomialIntegrate(f, derivation) ==
+ zero? f => [0, 0, 0]
+ r := HermiteIntegrate(f, derivation)
+ zero?(inum := numer(r.logpart)) => [r.answer::IR, r.specpart, r.polypart]
+ iden := denom(r.logpart)
+ x := monomial(1, 1)$UP
+ resultvec := subresultantVector(UP2UP2 inum -
+ (x::UP2) * UP2UP2 derivation iden, UP2UP2 iden)
+ respoly := primitivePart leadingCoefficient resultvec 0
+ rec := splitSquarefree(respoly, kappa(#1, derivation))
+ logs:List(LOG) := [
+ [1, UP2UPR(term.factor),
+ UP22UPR swap primitivePart(resultvec(term.exponent),term.factor)]
+ for term in factors(rec.special)]
+ dlog :=
+-- one? derivation x => r.logpart
+ ((derivation x) = 1) => r.logpart
+ differentiate(mkAnswer(0, logs, empty()),
+ differentiate(#1, derivation))
+ (u := retractIfCan(p := r.logpart - dlog)@Union(UP, "failed")) case UP =>
+ [mkAnswer(r.answer, logs, empty), r.specpart, r.polypart + u::UP]
+ [mkAnswer(r.answer, logs, [[p, dummy]]), r.specpart, r.polypart]
+
+-- returns [q, r] such that p = q' + r and degree(r) < degree(dt)
+-- must have degree(derivation t) >= 2
+ monomialIntPoly(p, derivation) ==
+ (d := degree(dt := derivation monomial(1,1))::Z) < 2 =>
+ error "monomIntPoly: monomial must have degree 2 or more"
+ l := leadingCoefficient dt
+ ans:UP := 0
+ while (n := 1 + degree(p)::Z - d) > 0 repeat
+ ans := ans + (term := monomial(leadingCoefficient(p) / (n * l), n::N))
+ p := p - derivation term -- degree(p) must drop here
+ [ans, p]
+
+-- returns either
+-- (q in GP, a in F) st p = q' + a, and a=0 or a has no integral in F
+-- or (q in GP, r in GP) st p = q' + r, and r has no integral elem/UP
+ expintegratepoly(p, FRDE) ==
+ coef0:F := 0
+ notelm := answr := 0$GP
+ while p ^= 0 repeat
+ ans1 := FRDE(n := degree p, a := leadingCoefficient p)
+ answr := answr + monomial(ans1.ans, n)
+ if ~ans1.sol? then -- Risch d.e. has no complete solution
+ missing := a - ans1.right
+ if zero? n then coef0 := missing
+ else notelm := notelm + monomial(missing, n)
+ p := reductum p
+ zero? notelm => [answr, coef0]
+ [answr, notelm]
+
+-- f is either 0 or of the form p(t)/(1 + t**2)**n
+-- returns either
+-- (q in RF, a in F) st f = q' + a, and a=0 or a has no integral in F
+-- or (q in RF, r in RF) st f = q' + r, and r has no integral elem/UP
+ tanintegratespecial(f, derivation, FRDE) ==
+ ans:RF := 0
+ p := monomial(1, 2)$UP + 1
+ while (n := degree(denom f) quo 2) ^= 0 repeat
+ r := numer(f) rem p
+ a := coefficient(r, 1)
+ b := coefficient(r, 0)
+ (u := FRDE(n, a, b)) case "failed" => return [ans, f]
+ l := u::List(F)
+ term:RF := (monomial(first l, 1)$UP + second(l)::UP) / denom f
+ ans := ans + term
+ f := f - derivation term -- the order of the pole at 1+t^2 drops
+ zero?(c0 := retract(retract(f)@UP)@F) or
+ (u := FRDE(0, c0, 0)) case "failed" => [ans, c0]
+ [ans + first(u::List(F))::UP::RF, 0::F]
+
+-- returns (v in RF, c in RF) s.t. f = v' + cg, and c' = 0, or "failed"
+-- g must have a squarefree denominator (always possible)
+-- g must have no polynomial part and no pole above t = 0
+-- f must have no polynomial part and no pole above t = 0
+ expextintfrac(f, derivation, g) ==
+ zero? f => [0, 0]
+ degree numer f >= degree denom f => error "Not a proper fraction"
+ order(denom f,monomial(1,1)) ^= 0 => error "Not integral at t = 0"
+ r := HermiteIntegrate(f, derivation)
+ zero? g =>
+ r.logpart ^= 0 => "failed"
+ [r.answer, 0]
+ degree numer g >= degree denom g => error "Not a proper fraction"
+ order(denom g,monomial(1,1)) ^= 0 => error "Not integral at t = 0"
+ differentiate(c := r.logpart / g, derivation) ^= 0 => "failed"
+ [r.answer, c]
+
+ limitedLogs(f, logderiv, lu) ==
+ zero? f => empty()
+ empty? lu => "failed"
+ empty? rest lu =>
+ logderiv(c0 := f / logderiv(u0 := first lu)) ^= 0 => "failed"
+ [[c0, u0]]
+ num := numer f
+ den := denom f
+ l1:List Record(logand2:RF, contrib:UP) :=
+-- [[u, numer v] for u in lu | one? denom(v := den * logderiv u)]
+ [[u, numer v] for u in lu | (denom(v := den * logderiv u) = 1)]
+ rows := max(degree den,
+ 1 + reduce(max, [degree(u.contrib) for u in l1], 0)$List(N))
+ m:Matrix(F) := zero(rows, cols := 1 + #l1)
+ for i in 0..rows-1 repeat
+ for pp in l1 for j in minColIndex m .. maxColIndex m - 1 repeat
+ qsetelt_!(m, i + minRowIndex m, j, coefficient(pp.contrib, i))
+ qsetelt_!(m,i+minRowIndex m, maxColIndex m, coefficient(num, i))
+ m := rowEchelon m
+ ans := empty()$LLG
+ for i in minRowIndex m .. maxRowIndex m |
+ qelt(m, i, maxColIndex m) ^= 0 repeat
+ OK := false
+ for pp in l1 for j in minColIndex m .. maxColIndex m - 1
+ while not OK repeat
+ if qelt(m, i, j) ^= 0 then
+ OK := true
+ c := qelt(m, i, maxColIndex m) / qelt(m, i, j)
+ logderiv(c0 := c::UP::RF) ^= 0 => return "failed"
+ ans := concat([c0, pp.logand2], ans)
+ not OK => return "failed"
+ ans
+
+-- returns q in UP s.t. p = q', or "failed"
+ primintfldpoly(p, extendedint, t') ==
+ (u := primintegratepoly(p, extendedint, t')) case UPUP => "failed"
+ u.a0 ^= 0 => "failed"
+ u.answer
+
+-- returns q in GP st p = q', or "failed"
+ expintfldpoly(p, FRDE) ==
+ (u := expintegratepoly(p, FRDE)) case GPGP => "failed"
+ u.a0 ^= 0 => "failed"
+ u.answer
+
+-- returns (v in RF, c1...cn in RF, a in F) s.t. ci' = 0,
+-- and f = v' + a + +/[ci * ui'/ui]
+-- and a = 0 or a has no integral in UP
+ primlimitedint(f, derivation, extendedint, lu) ==
+ qr := divide(numer f, denom f)
+ (u1 := primlimintfrac(qr.remainder / (denom f), derivation, lu))
+ case "failed" => "failed"
+ (u2 := primintegratepoly(qr.quotient, extendedint,
+ retract derivation monomial(1, 1))) case UPUP => "failed"
+ [[u1.mainpart + u2.answer::RF, u1.limitedlogs], u2.a0]
+
+-- returns (v in RF, c1...cn in RF, a in F) s.t. ci' = 0,
+-- and f = v' + a + +/[ci * ui'/ui]
+-- and a = 0 or a has no integral in F
+ explimitedint(f, derivation, FRDE, lu) ==
+ qr := separate(f)$GP
+ (u1 := explimintfrac(qr.fracPart,derivation, lu)) case "failed" =>
+ "failed"
+ (u2 := expintegratepoly(qr.polyPart, FRDE)) case GPGP => "failed"
+ [[u1.mainpart + convert(u2.answer)@RF, u1.limitedlogs], u2.a0]
+
+-- returns [v, c1...cn] s.t. f = v' + +/[ci * ui'/ui]
+-- f must have no polynomial part (degree numer f < degree denom f)
+ primlimintfrac(f, derivation, lu) ==
+ zero? f => [0, empty()]
+ degree numer f >= degree denom f => error "Not a proper fraction"
+ r := HermiteIntegrate(f, derivation)
+ zero?(r.logpart) => [r.answer, empty()]
+ (u := limitedLogs(r.logpart, logprmderiv(#1, derivation), lu))
+ case "failed" => "failed"
+ [r.answer, u::LLG]
+
+-- returns [v, c1...cn] s.t. f = v' + +/[ci * ui'/ui]
+-- f must have no polynomial part (degree numer f < degree denom f)
+-- f must be integral above t = 0
+ explimintfrac(f, derivation, lu) ==
+ zero? f => [0, empty()]
+ degree numer f >= degree denom f => error "Not a proper fraction"
+ order(denom f, monomial(1,1)) > 0 => error "Not integral at t = 0"
+ r := HermiteIntegrate(f, derivation)
+ zero?(r.logpart) => [r.answer, empty()]
+ eta' := coefficient(derivation monomial(1, 1), 1)
+ (u := limitedLogs(r.logpart, logexpderiv(#1,derivation,eta'), lu))
+ case "failed" => "failed"
+ [r.answer - eta'::UP *
+ +/[((degree numer(v.logand))::Z - (degree denom(v.logand))::Z) *
+ v.coeff for v in u], u::LLG]
+
+ logexpderiv(f, derivation, eta') ==
+ (differentiate(f, derivation) / f) -
+ (((degree numer f)::Z - (degree denom f)::Z) * eta')::UP::RF
+
+ notelementary rec ==
+ rec.ir + integral(rec.polypart::RF + rec.specpart, monomial(1,1)$UP :: RF)
+
+-- returns
+-- (g in IR, a in F) st f = g'+ a, and a=0 or a has no integral in UP
+ primintegrate(f, derivation, extendedint) ==
+ rec := monomialIntegrate(f, derivation)
+ not elem?(i1 := rec.ir) => [notelementary rec, 0]
+ (u2 := primintegratepoly(rec.polypart, extendedint,
+ retract derivation monomial(1, 1))) case UPUP =>
+ [i1 + u2.elem::RF::IR
+ + integral(u2.notelem::RF, monomial(1,1)$UP :: RF), 0]
+ [i1 + u2.answer::RF::IR, u2.a0]
+
+-- returns
+-- (g in IR, a in F) st f = g' + a, and a = 0 or a has no integral in F
+ expintegrate(f, derivation, FRDE) ==
+ rec := monomialIntegrate(f, derivation)
+ not elem?(i1 := rec.ir) => [notelementary rec, 0]
+-- rec.specpart is either 0 or of the form p(t)/t**n
+ special := rec.polypart::GP +
+ (numer(rec.specpart)::GP exquo denom(rec.specpart)::GP)::GP
+ (u2 := expintegratepoly(special, FRDE)) case GPGP =>
+ [i1 + convert(u2.elem)@RF::IR + integral(convert(u2.notelem)@RF,
+ monomial(1,1)$UP :: RF), 0]
+ [i1 + convert(u2.answer)@RF::IR, u2.a0]
+
+-- returns
+-- (g in IR, a in F) st f = g' + a, and a = 0 or a has no integral in F
+ tanintegrate(f, derivation, FRDE) ==
+ rec := monomialIntegrate(f, derivation)
+ not elem?(i1 := rec.ir) => [notelementary rec, 0]
+ r := monomialIntPoly(rec.polypart, derivation)
+ t := monomial(1, 1)$UP
+ c := coefficient(r.polypart, 1) / leadingCoefficient(derivation t)
+ derivation(c::UP) ^= 0 =>
+ [i1 + mkAnswer(r.answer::RF, empty(),
+ [[r.polypart::RF + rec.specpart, dummy]$NE]), 0]
+ logs:List(LOG) :=
+ zero? c => empty()
+ [[1, monomial(1,1)$UPR - (c/(2::F))::UP::RF::UPR, (1 + t**2)::RF::UPR]]
+ c0 := coefficient(r.polypart, 0)
+ (u := tanintegratespecial(rec.specpart, differentiate(#1, derivation),
+ FRDE)) case RFRF =>
+ [i1 + mkAnswer(r.answer::RF + u.elem, logs, [[u.notelem,dummy]$NE]), c0]
+ [i1 + mkAnswer(r.answer::RF + u.answer, logs, empty()), u.a0 + c0]
+
+-- returns either (v in RF, c in RF) s.t. f = v' + cg, and c' = 0
+-- or (v in RF, a in F) s.t. f = v' + a
+-- and a = 0 or a has no integral in UP
+ primextendedint(f, derivation, extendedint, g) ==
+ fqr := divide(numer f, denom f)
+ gqr := divide(numer g, denom g)
+ (u1 := primextintfrac(fqr.remainder / (denom f), derivation,
+ gqr.remainder / (denom g))) case "failed" => "failed"
+ zero?(gqr.remainder) =>
+ -- the following FAIL cannot occur if the primitives are all logs
+ degree(gqr.quotient) > 0 => FAIL
+ (u3 := primintegratepoly(fqr.quotient, extendedint,
+ retract derivation monomial(1, 1))) case UPUP => "failed"
+ [u1.ratpart + u3.answer::RF, u3.a0]
+ (u2 := primintfldpoly(fqr.quotient - retract(u1.coeff)@UP *
+ gqr.quotient, extendedint, retract derivation monomial(1, 1)))
+ case "failed" => "failed"
+ [u2::UP::RF + u1.ratpart, u1.coeff]
+
+-- returns either (v in RF, c in RF) s.t. f = v' + cg, and c' = 0
+-- or (v in RF, a in F) s.t. f = v' + a
+-- and a = 0 or a has no integral in F
+ expextendedint(f, derivation, FRDE, g) ==
+ qf := separate(f)$GP
+ qg := separate g
+ (u1 := expextintfrac(qf.fracPart, derivation, qg.fracPart))
+ case "failed" => "failed"
+ zero?(qg.fracPart) =>
+ --the following FAIL's cannot occur if the primitives are all logs
+ retractIfCan(qg.polyPart)@Union(F,"failed") case "failed"=> FAIL
+ (u3 := expintegratepoly(qf.polyPart,FRDE)) case GPGP => "failed"
+ [u1.ratpart + convert(u3.answer)@RF, u3.a0]
+ (u2 := expintfldpoly(qf.polyPart - retract(u1.coeff)@UP :: GP
+ * qg.polyPart, FRDE)) case "failed" => "failed"
+ [convert(u2::GP)@RF + u1.ratpart, u1.coeff]
+
+-- returns either
+-- (q in UP, a in F) st p = q'+ a, and a=0 or a has no integral in UP
+-- or (q in UP, r in UP) st p = q'+ r, and r has no integral elem/UP
+ primintegratepoly(p, extendedint, t') ==
+ zero? p => [0, 0$F]
+ ans:UP := 0
+ while (d := degree p) > 0 repeat
+ (ans1 := extendedint leadingCoefficient p) case "failed" =>
+ return([ans, p])
+ p := reductum p - monomial(d * t' * ans1.ratpart, (d - 1)::N)
+ ans := ans + monomial(ans1.ratpart, d)
+ + monomial(ans1.coeff / (d + 1)::F, d + 1)
+ (ans1:= extendedint(rp := retract(p)@F)) case "failed" => [ans,rp]
+ [monomial(ans1.coeff, 1) + ans1.ratpart::UP + ans, 0$F]
+
+-- returns (v in RF, c in RF) s.t. f = v' + cg, and c' = 0
+-- g must have a squarefree denominator (always possible)
+-- g must have no polynomial part (degree numer g < degree denom g)
+-- f must have no polynomial part (degree numer f < degree denom f)
+ primextintfrac(f, derivation, g) ==
+ zero? f => [0, 0]
+ degree numer f >= degree denom f => error "Not a proper fraction"
+ r := HermiteIntegrate(f, derivation)
+ zero? g =>
+ r.logpart ^= 0 => "failed"
+ [r.answer, 0]
+ degree numer g >= degree denom g => error "Not a proper fraction"
+ differentiate(c := r.logpart / g, derivation) ^= 0 => "failed"
+ [r.answer, c]
+
+@
+\section{package INTRAT RationalIntegration}
+<<package INTRAT RationalIntegration>>=
+)abbrev package INTRAT RationalIntegration
+++ Rational function integration
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 24 October 1995
+++ Description:
+++ This package provides functions for the base
+++ case of the Risch algorithm.
+-- Used internally bt the integration packages
+RationalIntegration(F, UP): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Integer)
+ UP: UnivariatePolynomialCategory F
+
+ RF ==> Fraction UP
+ IR ==> IntegrationResult RF
+ LLG ==> List Record(coeff:RF, logand:RF)
+ URF ==> Union(Record(ratpart:RF, coeff:RF), "failed")
+ U ==> Union(Record(mainpart:RF, limitedlogs:LLG), "failed")
+
+ Exports ==> with
+ integrate : RF -> IR
+ ++ integrate(f) returns g such that \spad{g' = f}.
+ infieldint : RF -> Union(RF, "failed")
+ ++ infieldint(f) returns g such that \spad{g' = f} or "failed"
+ ++ if the integral of f is not a rational function.
+ extendedint: (RF, RF) -> URF
+ ++ extendedint(f, g) returns fractions \spad{[h, c]} such that
+ ++ \spad{c' = 0} and \spad{h' = f - cg},
+ ++ if \spad{(h, c)} exist, "failed" otherwise.
+ limitedint : (RF, List RF) -> U
+ ++ \spad{limitedint(f, [g1,...,gn])} returns
+ ++ fractions \spad{[h,[[ci, gi]]]}
+ ++ such that the gi's are among \spad{[g1,...,gn]}, \spad{ci' = 0}, and
+ ++ \spad{(h+sum(ci log(gi)))' = f}, if possible, "failed" otherwise.
+
+ Implementation ==> add
+ import TranscendentalIntegration(F, UP)
+
+ infieldint f ==
+ rec := baseRDE(0, f)$TranscendentalRischDE(F, UP)
+ rec.nosol => "failed"
+ rec.ans
+
+ integrate f ==
+ rec := monomialIntegrate(f, differentiate)
+ integrate(rec.polypart)::RF::IR + rec.ir
+
+ limitedint(f, lu) ==
+ quorem := divide(numer f, denom f)
+ (u := primlimintfrac(quorem.remainder / (denom f), differentiate,
+ lu)) case "failed" => "failed"
+ [u.mainpart + integrate(quorem.quotient)::RF, u.limitedlogs]
+
+ extendedint(f, g) ==
+ fqr := divide(numer f, denom f)
+ gqr := divide(numer g, denom g)
+ (i1 := primextintfrac(fqr.remainder / (denom f), differentiate,
+ gqr.remainder / (denom g))) case "failed" => "failed"
+ i2:=integrate(fqr.quotient-retract(i1.coeff)@UP *gqr.quotient)::RF
+ [i2 + i1.ratpart, i1.coeff]
+
+@
+\section{package INTRF RationalFunctionIntegration}
+<<package INTRF RationalFunctionIntegration>>=
+)abbrev package INTRF RationalFunctionIntegration
+++ Integration of rational functions
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 29 Mar 1990
+++ Keywords: polynomial, fraction, integration.
+++ Description:
+++ This package provides functions for the integration
+++ of rational functions.
+++ Examples: )r INTRF INPUT
+RationalFunctionIntegration(F): Exports == Implementation where
+ F: Join(IntegralDomain, RetractableTo Integer, CharacteristicZero)
+
+ SE ==> Symbol
+ P ==> Polynomial F
+ Q ==> Fraction P
+ UP ==> SparseUnivariatePolynomial Q
+ QF ==> Fraction UP
+ LGQ ==> List Record(coeff:Q, logand:Q)
+ UQ ==> Union(Record(ratpart:Q, coeff:Q), "failed")
+ ULQ ==> Union(Record(mainpart:Q, limitedlogs:LGQ), "failed")
+
+ Exports ==> with
+ internalIntegrate: (Q, SE) -> IntegrationResult Q
+ ++ internalIntegrate(f, x) returns g such that \spad{dg/dx = f}.
+ infieldIntegrate : (Q, SE) -> Union(Q, "failed")
+ ++ infieldIntegrate(f, x) returns a fraction
+ ++ g such that \spad{dg/dx = f}
+ ++ if g exists, "failed" otherwise.
+ limitedIntegrate : (Q, SE, List Q) -> ULQ
+ ++ \spad{limitedIntegrate(f, x, [g1,...,gn])} returns fractions
+ ++ \spad{[h, [[ci,gi]]]} such that the gi's are among
+ ++ \spad{[g1,...,gn]},
+ ++ \spad{dci/dx = 0}, and \spad{d(h + sum(ci log(gi)))/dx = f}
+ ++ if possible, "failed" otherwise.
+ extendedIntegrate: (Q, SE, Q) -> UQ
+ ++ extendedIntegrate(f, x, g) returns fractions \spad{[h, c]} such that
+ ++ \spad{dc/dx = 0} and \spad{dh/dx = f - cg}, if \spad{(h, c)} exist,
+ ++ "failed" otherwise.
+
+ Implementation ==> add
+ import RationalIntegration(Q, UP)
+ import IntegrationResultFunctions2(QF, Q)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents SE,
+ SE, F, P, Q)
+
+ infieldIntegrate(f, x) ==
+ map(multivariate(#1, x), infieldint univariate(f, x))
+
+ internalIntegrate(f, x) ==
+ map(multivariate(#1, x), integrate univariate(f, x))
+
+ extendedIntegrate(f, x, g) ==
+ map(multivariate(#1, x),
+ extendedint(univariate(f, x), univariate(g, x)))
+
+ limitedIntegrate(f, x, lu) ==
+ map(multivariate(#1, x),
+ limitedint(univariate(f, x), [univariate(u, x) for u in lu]))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf INTRF curve curvepkg divisor pfo
+-- intalg intaf efstruc rdeef intpm intef irexpand integrat
+
+<<package SUBRESP SubResultantPackage>>
+<<package MONOTOOL MonomialExtensionTools>>
+<<package INTHERTR TranscendentalHermiteIntegration>>
+<<package INTTR TranscendentalIntegration>>
+<<package INTRAT RationalIntegration>>
+<<package INTRF RationalFunctionIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/invnode.as.pamphlet b/src/algebra/invnode.as.pamphlet
new file mode 100644
index 00000000..d0517539
--- /dev/null
+++ b/src/algebra/invnode.as.pamphlet
@@ -0,0 +1,340 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra invnode.as}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{IVNodeCategory}
+<<IVNodeCategory>>=
+#include "axiom"
+
+POINT ==> Point DoubleFloat;
+
+local DF2S;
+DF2S(u:DoubleFloat):String == {
+ STRINGIMAGE ==> VMLISP_:_:STRINGIMAGE;
+ import { STRINGIMAGE : DoubleFloat -> String} from Foreign Lisp;
+ STRINGIMAGE(u);
+}
+
++++ Category of all open inventor node types
++++ Uses IVObject as a 'generic' value.
+define IVNodeCategory: Category == SetCategory with {
+ quickWrite: (TextFile, %) -> ();
+ ++ Quick version. Not guaranteed to terminate
+ children: % -> List IVNodeObject;
+ addChild!: (%, IVNodeObject) -> ();
+ fields: % -> List IVField;
+ className: % -> String;
+ coerce: % -> IVNodeObject;
+ default {
+ import from Symbol;
+ quickWrite(out: TextFile, node: %): () == {
+ write!(out, className(node));
+ write!(out, " {");
+ writeLine!(out);
+ import from List IVField;
+ import from IVValue;
+ for field in fields node repeat {
+ write!(out, string name field);
+ write!(out, " ");
+ invWrite(out, value field);
+ }
+ writeLine!(out, "}");
+ }
+ coerce(x: %): IVNodeObject ==
+ make(% pretend IVNodeCategory, x);
+
+ coerce(x: %): OutputForm == {
+ import from String;
+ coerce className x;
+ }
+ }
+}
+
+@
+\section{IVLeafNodeCategory}
+<<IVLeafNodeCategory>>=
++++ Category for leaves --- just adds a few defaults to make life
++++ easy.
+define IVLeafNodeCategory: Category == IVNodeCategory with {
+ default {
+ children(v: %): List IVNodeObject == [];
+ addChild!(v: %, new: IVNodeObject): () ==
+ error "can't add child to a leaf";
+ }
+}
+
+@
+\section{IVNodeObject}
+<<IVNodeObject>>=
+-- virtual functions for fun and profit...
+IVNodeObject: IVNodeCategory with {
+ make: (T: IVNodeCategory, T) -> %;
+ coerce: (T: IVNodeCategory, %) -> T;
+ uniqueID: % -> Integer;
+} == add {
+ Rep ==> Record(NT: IVNodeCategory, val: NT, idx: Integer);
+ import from Rep;
+ default z: Integer;
+
+ local iCount: Integer := 0;
+ local explode: (o: %) -> (NodeType: IVNodeCategory, NodeType);
+
+ uniqueID(o: %): Integer == rep(o).idx;
+
+ explode(o: %): (NodeType: IVNodeCategory, v: NodeType) == {
+ (NT, val, id) == explode rep o;
+ (NT, val);
+ }
+
+ make(T: IVNodeCategory, val: T): % == {
+ free iCount := iCount + 1;
+ per [T, val, iCount];
+ }
+ coerce(T: IVNodeCategory, val: %): T == {
+ (type, v, id) == explode rep val;
+ v pretend T;
+ }
+
+ -- The '0' functions are needed to turn non-constants
+ -- (eg. fn return values) -- into constants.
+ children(v: %): List IVNodeObject == {
+ children0(NodeType: IVNodeCategory, val: NodeType):
+ List IVNodeObject ==
+ children val;
+ children0 explode v;
+ }
+
+ fields(v: %): List IVField == {
+ fields0(NodeType: IVNodeCategory, val: NodeType): List IVField ==
+ fields val;
+ fields0 explode v;
+ }
+
+ className(v: %): String == {
+ name0(NodeType: IVNodeCategory, val: NodeType): String ==
+ className(val)$NodeType;
+ name0 explode v;
+ }
+
+ addChild!(v: %, child: %): () == {
+ addChild0!(NodeType: IVNodeCategory, val: NodeType): () ==
+ addChild!(val, child);
+ addChild0! explode v;
+ }
+
+ -- BasicType stuff
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on ivobject";
+}
+
+@
+\section{IVNodeConnection}
+<<IVNodeConnection>>=
+IVNodeConnection: with {
+ bracket: (IVNodeObject, Symbol) -> %;
+ field: % -> Symbol;
+ node: % -> IVNodeObject;
+} == add {
+ Rep ==> Record(o: IVNodeObject, f: Symbol);
+ import from Rep;
+
+ [o: IVNodeObject, f: Symbol]: % == per [o,f];
+ field(c: %): Symbol == rep(c).f;
+ node(c: %): IVNodeObject == rep(c).o;
+}
+
+@
+\section{IVValue}
+<<IVValue>>=
+IVValue: BasicType with {
+ DECL(T, fld, flg) ==> {
+ coerce: % -> T;
+ flg: % -> Boolean;
+ fld: T -> %;
+ }
+ DECL(DoubleFloat, float, float?);
+ DECL(IVNodeObject, node, node?);
+ DECL(Boolean, bool, bool?);
+ DECL(SingleInteger, int, int?);
+ DECL(String, string, string?);
+ DECL(Symbol, symbol, symbol?);
+ DECL(POINT, point, point?);
+ DECL(List DoubleFloat, floatlist, floatlist?);
+ DECL(List SingleInteger, intlist, intlist?);
+ DECL(List POINT, pointlist, pointlist?);
+ DECL(IVNodeConnection, connect, connect?);
+
+ invWrite: (TextFile, %) -> ();
+} == add {
+ Rep ==> Union( float: DoubleFloat,
+ node: IVNodeObject,
+ bool: Boolean,
+ int: SingleInteger,
+ string: String,
+ symbol: Symbol,
+ point: POINT,
+ intlist: List SingleInteger,
+ floatlist: List DoubleFloat,
+ pointlist: List POINT,
+ connect: IVNodeConnection
+ );
+ import from Rep;
+
+ Accessor(T, fld, flg) ==> {
+ coerce(x: %): T == rep(x).fld;
+ flg(x: %): Boolean == rep(x) case fld;
+ fld(x: T): % == per [x, fld];
+ }
+ Accessor(DoubleFloat, float, float?);
+ Accessor(IVNodeObject, node, node?);
+ Accessor(Boolean, bool, bool?);
+ Accessor(SingleInteger, int, int?);
+ Accessor(String, string, string?);
+ Accessor(Symbol, symbol, symbol?);
+ Accessor(POINT, point, point?);
+ Accessor(List DoubleFloat, floatlist, floatlist?);
+ Accessor(List SingleInteger, intlist, intlist?);
+ Accessor(List POINT, pointlist, pointlist?);
+ Accessor(IVNodeConnection, connect, connect?);
+
+ local ppoint(out: TextFile, val: POINT, dim: Integer): () == {
+ for i in 1..dim repeat {
+ write!(out, DF2S(val.(i::Integer)));
+ write!(out, " ");
+ }
+ }
+ invWrite(out: TextFile, val: %): () == {
+ import from Float, Integer;
+ float? val => {
+ writeLine!(out,
+ convert(convert(val::DoubleFloat)$Float));
+ }
+ node? val or connect? val => {
+ error "Sorry, can't write a node here";
+ --writeLine!(out, val::IVNodeObject);
+ }
+ bool? val => {
+ writeLine!(out,
+ if val::Boolean then "true" else "false");
+ }
+ int? val => {
+ writeLine!(out,
+ convert(convert(val::SingleInteger)@Integer));
+ }
+ string? val => {
+ writeLine!(out, val::String);
+ }
+ symbol? val => {
+ writeLine!(out, string(val::Symbol));
+ }
+ point? val => {
+ ppoint(out, rep(val).point, 3);
+ writeLine!(out, "");
+ }
+ floatlist? val => {
+ write!(out, "[ ");
+ for fl in val::List DoubleFloat repeat {
+ write!(out,convert(convert(fl)$Float));
+ write!(out, ", ");
+ }
+ writeLine!(out, "]");
+ }
+ intlist? val => {
+ write!(out, "[ ");
+ for i in val::List SingleInteger repeat {
+ write!(out,convert(convert(i)@Integer));
+ write!(out, ", ");
+ }
+ writeLine!(out, "]");
+ }
+ pointlist? val => {
+ write!(out, "[ ");
+ for p in val::List POINT repeat {
+ ppoint(out, p, 3);
+ writeLine!(out, ",");
+ }
+ writeLine!(out, "]");
+ }
+ never
+ }
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality for values";
+}
+
+@
+\section{IVField}
+<<IVField>>=
+IVField: BasicType with {
+ new: (Symbol,IVValue) -> %;
+ name: % -> Symbol;
+ value: % -> IVValue;
+} == add {
+ Rep ==> Record(name: Symbol, v: IVValue);
+ import from Rep;
+
+ new(name: Symbol, val: IVValue): % == per [name, val];
+ name(f: %): Symbol == rep(f).name;
+ value(f: %): IVValue == rep(f).v;
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality for values";
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<IVNodeCategory>>
+<<IVLeafNodeCategory>>
+<<IVNodeObject>>
+<<IVNodeConnection>>
+<<IVValue>>
+<<IVField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/invrender.as.pamphlet b/src/algebra/invrender.as.pamphlet
new file mode 100644
index 00000000..a107b9b1
--- /dev/null
+++ b/src/algebra/invrender.as.pamphlet
@@ -0,0 +1,172 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra invrender.as}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{RenderTools}
+<<RenderTools>>=
+#include "axiom"
+
+POINT ==> Point DoubleFloat;
+NNI ==> NonNegativeInteger;
+SI ==> SingleInteger;
+
+RenderTools: with {
+ renderToFile!: (FileName, ThreeSpace DoubleFloat) -> ();
+ makeSceneGraph: (ThreeSpace DoubleFloat) -> IVNodeObject;
+} == add {
+ import from IVUtilities;
+
+ renderToFile!(f: FileName, space: ThreeSpace DoubleFloat): () == {
+ root := makeSceneGraph(space);
+ write!(f, root);
+ }
+
+ local makePts: (lpts: List POINT,
+ indicies: List List List NonNegativeInteger) ->
+ (List POINT, List DoubleFloat);
+
+ local makePts(lp: List POINT, indicies: List List List NonNegativeInteger):
+ (List POINT, List DoubleFloat) == {
+ local colorIdx: Integer;
+ indexList := concat concat indicies;
+ coordpts := lp;
+ if (# first lp = 4) then colorIdx := 4 else colorIdx := 3;
+ colors := [pt.colorIdx for pt in lp];
+ (coordpts, colors)
+ }
+
+ local makeBaseColor(l: List DoubleFloat): IVBaseColor == {
+ -- This works by interpolating between blue and green (via cyan).
+ -- There may well be better ways...
+ import from POINT;
+ import from List POINT;
+ import from DoubleFloat;
+ import from List DoubleFloat;
+ low := 10000.0;
+ high := -10000.0;
+ for df in l repeat {
+ if low > df then low := df;
+ if high < df then high := df;
+ }
+ if (high = low) then high := high + 1.0;
+ new [ point([0, (df - low)/(high - low), (high - df)/(high - low)])
+ for df in l]
+ }
+ makeSceneGraph(space: ThreeSpace DoubleFloat): IVNodeObject == {
+ import from List ThreeSpace DoubleFloat;
+ import from List List List NNI;
+ import from Integer;
+ import from Symbol;
+ import from IVValue;
+ check(space);
+ lpts := lp(space);
+ indicies := lllip(space);
+ root: IVSeparator := new();
+ (coordpts, colorvalues) := makePts(lpts, indicies);
+ coords: IVCoordinate3 := new coordpts;
+ colors: IVBaseColor := makeBaseColor(colorvalues);
+ addChild!(root, coerce coords);
+ addChild!(root, coerce colors);
+ binding: IVBasicNode := make "MaterialBinding";
+ addField!(binding, "value", symbol "PER__VERTEX");
+ addChild!(root, coerce binding);
+ offset: NNI := 0;
+ for ss in components space
+ for index in indicies repeat {
+ local coordIndex: List NNI;
+ default i: Integer;
+ closedCurve? ss => {
+ n: Integer := (#(index.1))::Integer;
+ coordIndex :=
+ [offset+coerce(i) for i in 0..n::Integer];
+ -- Close the curve
+ setlast!(coordIndex,offset);
+ curve : IVIndexedLineSet := new coordIndex;
+ addChild!(root, coerce curve);
+ offset := offset+n::NNI;
+ }
+ curve? ss => {
+ n := (#(index.1))::Integer;
+ coordIndex :=
+ [offset+coerce(i) for i in 0..(n-1)];
+ curve : IVIndexedLineSet := new coordIndex;
+ addChild!(root, coerce curve);
+ offset := offset+n::NNI;
+ }
+ polygon? ss => {
+ vertices := #(index.1) + #(index.2);
+ face : IVFaceSet := new(vertices::SI,offset::SI);
+ addChild!(root, coerce face);
+ offset := offset+vertices;
+ }
+ mesh? ss => {
+ xStep: SingleInteger := (#index)::SingleInteger;
+ yStep: SingleInteger := (#(first index))::SingleInteger;
+ quadMesh : IVQuadMesh :=
+ new(xStep,yStep,offset::SingleInteger);
+ addChild!(root, coerce quadMesh);
+ offset := offset+coerce(xStep*yStep);
+ }
+ point? ss => {
+ pt : IVPointSet := new(offset::SingleInteger,
+ 1$SingleInteger);
+ addChild!(root, coerce pt);
+ offset := offset+1;
+ }
+ error "Unrecognised SubSpace component";
+ }
+ coerce root;
+ }
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<RenderTools>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/invtypes.as.pamphlet b/src/algebra/invtypes.as.pamphlet
new file mode 100644
index 00000000..5ada870a
--- /dev/null
+++ b/src/algebra/invtypes.as.pamphlet
@@ -0,0 +1,302 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra invtypes.as}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{IVSimpleInnerNode}
+<<IVSimpleInnerNode>>=
+#include "axiom"
+
+import from IVValue, Symbol;
+
+POINT ==> Point DoubleFloat;
+NNI ==> NonNegativeInteger;
+
+IVSimpleInnerNode: with {
+ new: () -> %;
+ addChild!: (%, IVNodeObject) -> ();
+ children: % -> List IVNodeObject;
+ fields: % -> List IVField;
+
+ =: (%, %) -> Boolean;
+
+} == add {
+ Rep ==> Record(lst: List IVNodeObject);
+ import from Rep;
+
+ new(): % == per [[]];
+ addChild!(v: %, new: IVNodeObject): () == {
+ rep(v).lst := concat!(rep(v).lst, new);
+ }
+
+ children(v: %): List IVNodeObject == rep(v).lst;
+
+ fields(node: %): List IVField == [];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVInnerNodes";
+}
+
+@
+\section{IVSeparator}
+<<IVSeparator>>=
+IVSeparator: IVNodeCategory with {
+ new: () -> %;
+} == IVSimpleInnerNode add {
+ className(v: %): String == "Separator";
+}
+
+@
+\section{IVGroup}
+<<IVGroup>>=
+IVGroup: IVNodeCategory with {
+ new: () -> %;
+} == IVSimpleInnerNode add {
+ className(v: %): String == "Group";
+}
+
+@
+\section{IVCoordinate3}
+<<IVCoordinate3>>=
+IVCoordinate3: IVLeafNodeCategory with {
+ new: List POINT -> %;
+} == add {
+ Rep ==> List POINT;
+ className(x: %): String == "Coordinate3";
+
+ new(l: List POINT): % == per l;
+ fields(v: %): List IVField == [ new("point", pointlist rep v)];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVCoord3";
+}
+
+@
+\section{IVCoordinate4}
+<<IVCoordinate4>>=
+IVCoordinate4: IVLeafNodeCategory with {
+ new: List POINT -> %;
+} == add {
+ Rep ==> List POINT;
+ import from Rep;
+
+ className(x: %): String == "Coordinate4";
+
+ new(l: List POINT): % == per l;
+ fields(v: %): List IVField == [ new("point", pointlist rep v)];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVCoord4";
+}
+
+@
+\section{IVQuadMesh}
+<<IVQuadMesh>>=
+IVQuadMesh: IVLeafNodeCategory with {
+ new: (SingleInteger, SingleInteger, SingleInteger) -> %;
+} == add {
+ Rep ==> Record( rowc: SingleInteger,
+ colc: SingleInteger,
+ start: SingleInteger);
+ import from Rep;
+
+ className(x: %): String == "QuadMesh";
+
+ new(rc: SingleInteger, cc: SingleInteger, start: SingleInteger): % ==
+ per [rc, cc, start];
+
+ fields(v: %): List IVField == [
+ new("verticesPerColumn", int rep(v).colc),
+ new("verticesPerRow", int rep(v).rowc),
+ new("startIndex", int rep(v).start)
+ ];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVQuadMesh";
+}
+
+@
+\section{IVBaseColor}
+<<IVBaseColor>>=
+IVBaseColor: IVLeafNodeCategory with {
+ new: List POINT -> %;
+} == add {
+ Rep ==> List POINT;
+ import from Rep;
+
+ className(x: %): String == "BaseColor";
+
+ new(l: List POINT): % == per l;
+ fields(v: %): List IVField == [ new("rgb", pointlist rep v) ];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVBaseColor";
+}
+
+@
+\section{IVIndexedLineSet}
+<<IVIndexedLineSet>>=
+IVIndexedLineSet: IVLeafNodeCategory with {
+ new: List NNI -> %;
+ new: List SingleInteger -> %;
+} == add {
+ Rep ==> List SingleInteger;
+ import from Rep;
+
+ className(x: %): String == "IndexedLineSet";
+
+ new(l: List SingleInteger): % == per l;
+ new(l: List NNI): % == new [ coerce n for n in l];
+
+ fields(v: %): List IVField == [ new("points", intlist rep v) ];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVBaseColor";
+}
+
+@
+\section{IVFaceSet}
+<<IVFaceSet>>=
+IVFaceSet: IVLeafNodeCategory with {
+ new: (SingleInteger, SingleInteger) -> %;
+} == add {
+ Rep ==> Record(startIndex: SingleInteger, numVertices: SingleInteger);
+ import from Rep;
+
+ className(x: %): String == "FaceSet";
+
+ new(x: SingleInteger, y: SingleInteger): % == per [x,y];
+ fields(v: %): List IVField == [
+ new("numVertices", int rep(v).numVertices),
+ new("startIndex", int rep(v).startIndex)
+ ];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVFaceSet";
+}
+
+@
+\section{IVPointSet}
+<<IVPointSet>>=
+IVPointSet: IVLeafNodeCategory with {
+ new: (SingleInteger, SingleInteger) -> %;
+} == add {
+ Rep ==> Record(startIndex: SingleInteger, numPoints: SingleInteger);
+ import from Rep;
+
+ className(x: %): String == "PointSet";
+
+ new(x: SingleInteger, y: SingleInteger): % == per [x,y];
+
+ fields(v: %): List IVField == [
+ new("numPoints", int rep(v).numPoints),
+ new("startIndex", int rep(v).startIndex)
+ ];
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVFaceSet";
+}
+
+@
+\section{IVBasicNode}
+<<IVBasicNode>>=
+IVBasicNode: IVNodeCategory with {
+ make: String -> %;
+ addField!: (%, IVField) -> ();
+ addField!: (%, Symbol, IVValue) -> ();
+} == add {
+ Rep ==> Record(class: String,
+ kids: List IVNodeObject,
+ fields: List IVField);
+ import from Rep, IVField;
+
+ make(name: String): % == per [name, [], []];
+
+ className(node: %): String == rep(node).class;
+ children(node: %): List IVNodeObject == rep(node).kids;
+ fields(node: %): List IVField == rep(node).fields;
+
+ addField!(node: %, fld: IVField): () == {
+ rep(node).fields := cons(fld, rep(node).fields);
+ }
+
+ addChild!(node: %, kid: IVNodeObject): () == {
+ rep(node).kids := cons(kid, rep(node).kids);
+ }
+
+ addField!(node: %, sym: Symbol, val: IVValue): () ==
+ addField!(node, new(sym, val));
+
+ --
+ sample: % == % pretend %;
+ (=)(a: %, b: %): Boolean == error "no equality on IVBasicNode";
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<IVSimpleInnerNode>>
+<<IVSeparator>>
+<<IVGroup>>
+<<IVCoordinate3>>
+<<IVCoordinate4>>
+<<IVQuadMesh>>
+<<IVBaseColor>>
+<<IVIndexedLineSet>>
+<<IVFaceSet>>
+<<IVPointSet>>
+<<IVBasicNode>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/invutils.as.pamphlet b/src/algebra/invutils.as.pamphlet
new file mode 100644
index 00000000..e3751336
--- /dev/null
+++ b/src/algebra/invutils.as.pamphlet
@@ -0,0 +1,172 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra invutils.as}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{IVUtilities}
+<<IVUtilities>>=
+#include "axiom"
+
+IVUtilities: with {
+ walkTree: ((IVNodeObject, Boolean) -> Boolean,
+ (IVNodeObject, Boolean) -> Boolean,
+ IVNodeObject, Boolean) -> ();
+ write!: (TextFile, IVNodeObject) -> ();
+ write!: (FileName, IVNodeObject) -> ();
+} == add {
+ -- walk a tree from 'root', and call f on each node.
+ -- nodesOnly will stop the recursion finding subnodes within
+ -- fields.
+ -- preFn is a function that takes a node, a flag indicating if the
+ -- node has already been traversed. It returns a flag
+ -- indicating if the traversal should descend the node.
+ walkTree(preFn: (IVNodeObject, Boolean) -> Boolean,
+ postFn: (IVNodeObject, Boolean) -> Boolean,
+ root: IVNodeObject,
+ nodesOnly: Boolean): () == {
+ tab: Table(Integer, IVNodeObject) := table();
+ innerWalk(node: IVNodeObject): () == {
+ import from List IVNodeObject;
+ import from List IVField;
+ import from IVValue;
+ present := key?(uniqueID node, tab);
+ not preFn(node, present) => return;
+ tab.(uniqueID node) := node;
+ for child in children node repeat
+ innerWalk(child);
+ if not nodesOnly then {
+ for fld in fields node repeat {
+ import from IVNodeConnection;
+ connect? value fld =>
+ innerWalk(node coerce value fld);
+ node? value fld =>
+ innerWalk(coerce value fld);
+ }
+ }
+ postFn(node, false);
+ }
+ innerWalk(root);
+ }
+
+ write!(out: TextFile, root: IVNodeObject): () == {
+ import from Boolean;
+ names: Table(Integer, IVNodeObject) := table();
+
+ getName(node: IVNodeObject): String == {
+ import from Integer;
+ convert uniqueID node;
+ }
+
+ doNamingVisit(node: IVNodeObject, flag: Boolean): Boolean == {
+ if flag then names.(uniqueID node) := node;
+ flag
+ }
+ writeNodeHeader(node: IVNodeObject): () == {
+ present := key?(uniqueID node, names);
+ if present then {
+ write!(out, "DEF ");
+ write!(out, getName node);
+ }
+ }
+ doPrintingVisit(node: IVNodeObject,
+ flag: Boolean): Boolean == {
+ if flag then {
+ write!(out, "USE ");
+ write!(out, getName node);
+ return false;
+ }
+ write!(out, className(node));
+ writeLine!(out, " {");
+ import from List IVField, Symbol;
+ for field in fields node repeat {
+ import from IVNodeConnection;
+ val: IVValue := value field;
+ write!(out, string name field);
+ write!(out, " ");
+ node? val => {
+ walkTree(doPrintingVisit,
+ doFinalPrint,
+ coerce val, false);
+ }
+ connect? val => {
+ walkTree(doPrintingVisit,
+ doFinalPrint,
+ node coerce val, false);
+ write!(out, ".");
+ writeLine!(out,
+ string field coerce val);
+ }
+ -- simple case:
+ invWrite(out, value field);
+ }
+ return true;
+ }
+
+ doFinalPrint(node: IVNodeObject, x: Boolean): Boolean == {
+ writeLine!(out, "}");
+ true;
+ }
+ doNothing(node: IVNodeObject, x: Boolean): Boolean == x;
+
+ writeLine!(out, "#Inventor V2.0 ascii");
+ walkTree(doNamingVisit, doNothing, root, true);
+ walkTree(doPrintingVisit, doFinalPrint, root, false);
+ }
+
+ write!(file: FileName, root:IVNodeObject): () == {
+ out: TextFile := open(file, "output");
+ write!(out, root);
+ close!(out);
+ }
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<IVUtilities>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/irexpand.spad.pamphlet b/src/algebra/irexpand.spad.pamphlet
new file mode 100644
index 00000000..2a39f76b
--- /dev/null
+++ b/src/algebra/irexpand.spad.pamphlet
@@ -0,0 +1,343 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra irexpand.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IR2F IntegrationResultToFunction}
+<<package IR2F IntegrationResultToFunction>>=
+)abbrev package IR2F IntegrationResultToFunction
+++ Conversion of integration results to top-level expressions
+++ Author: Manuel Bronstein
+++ Date Created: 4 February 1988
+++ Date Last Updated: 9 October 1991
+++ Description:
+++ This package allows a sum of logs over the roots of a polynomial
+++ to be expressed as explicit logarithms and arc tangents, provided
+++ that the indexing polynomial can be factored into quadratics.
+++ Keywords: integration, expansion, function.
+IntegrationResultToFunction(R, F): Exports == Implementation where
+ R: Join(GcdDomain, RetractableTo Integer, OrderedSet,
+ LinearlyExplicitRingOver Integer)
+ F: Join(AlgebraicallyClosedFunctionSpace R,
+ TranscendentalFunctionCategory)
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Z
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ IR ==> IntegrationResult F
+ REC ==> Record(ans1:F, ans2:F)
+ LOG ==> Record(scalar:Q, coeff:UP, logand:UP)
+
+ Exports ==> with
+ split : IR -> IR
+ ++ split(u(x) + sum_{P(a)=0} Q(a,x)) returns
+ ++ \spad{u(x) + sum_{P1(a)=0} Q(a,x) + ... + sum_{Pn(a)=0} Q(a,x)}
+ ++ where P1,...,Pn are the factors of P.
+ expand : IR -> List F
+ ++ expand(i) returns the list of possible real functions
+ ++ corresponding to i.
+ complexExpand: IR -> F
+ ++ complexExpand(i) returns the expanded complex function
+ ++ corresponding to i.
+
+ Implementation ==> add
+ import AlgebraicManipulations(R, F)
+ import ElementaryFunctionSign(R, F)
+
+ IR2F : IR -> F
+ insqrt : F -> Record(sqrt:REC, sgn:Z)
+ pairsum : (List F, List F) -> List F
+ pairprod : (F, List F) -> List F
+ quadeval : (UP, F, F, F) -> REC
+ linear : (UP, UP) -> F
+ tantrick : (F, F) -> F
+ ilog : (F, F, List K) -> F
+ ilog0 : (F, F, UP, UP, F) -> F
+ nlogs : LOG -> List LOG
+ lg2func : LOG -> List F
+ quadratic : (UP, UP) -> List F
+ mkRealFunc : List LOG -> List F
+ lg2cfunc : LOG -> F
+ loglist : (Q, UP, UP) -> List LOG
+ cmplex : (F, UP) -> F
+ evenRoots : F -> List F
+ compatible?: (List F, List F) -> Boolean
+
+ cmplex(alpha, p) == alpha * log p alpha
+ IR2F i == retract mkAnswer(ratpart i, empty(), notelem i)
+ pairprod(x, l) == [x * y for y in l]
+
+ evenRoots x ==
+ [first argument k for k in tower x |
+ is?(k,"nthRoot"::Symbol) and even?(retract(second argument k)@Z)
+ and (not empty? variables first argument k)]
+
+ expand i ==
+ j := split i
+ pairsum([IR2F j], mkRealFunc logpart j)
+
+ split i ==
+ mkAnswer(ratpart i,concat [nlogs l for l in logpart i],notelem i)
+
+ complexExpand i ==
+ j := split i
+ IR2F j + +/[lg.scalar::F * lg2cfunc lg for lg in logpart j]
+
+-- p = a t^2 + b t + c
+-- Expands sum_{p(t) = 0} t log(lg(t))
+ quadratic(p, lg) ==
+ zero?(delta := (b := coefficient(p, 1))**2 - 4 *
+ (a := coefficient(p,2)) * (p0 := coefficient(p, 0))) =>
+ [linear(monomial(1, 1) + (b / a)::UP, lg)]
+ e := (q := quadeval(lg, c := - b * (d := inv(2*a)),d, delta)).ans1
+ lgp := c * log(nrm := (e**2 - delta * (f := q.ans2)**2))
+ s := (sqr := insqrt delta).sqrt
+ pp := nn := 0$F
+ if sqr.sgn >= 0 then
+ sqrp := s.ans1 * rootSimp sqrt(s.ans2)
+ pp := lgp + d * sqrp * log(((2 * e * f) / nrm) * sqrp
+ + (e**2 + delta * f**2) / nrm)
+ if sqr.sgn <= 0 then
+ sqrn := s.ans1 * rootSimp sqrt(-s.ans2)
+ nn := lgp + d * sqrn * ilog(e, f * sqrn,
+ setUnion(setUnion(kernels a, kernels b), kernels p0))
+ sqr.sgn > 0 => [pp]
+ sqr.sgn < 0 => [nn]
+ [pp, nn]
+
+-- returns 2 atan(a/b) or 2 atan(-b/a) whichever looks better
+-- they differ by a constant so it's ok to do it from an IR
+ tantrick(a, b) ==
+ retractIfCan(a)@Union(Q, "failed") case Q => 2 * atan(-b/a)
+ 2 * atan(a/b)
+
+-- transforms i log((a + i b) / (a - i b)) into a sum of real
+-- arc-tangents using Rioboo's algorithm
+-- lk is a list of kernels which are parameters for the integral
+ ilog(a, b, lk) ==
+ l := setDifference(setUnion(variables numer a, variables numer b),
+ setUnion(lk, setUnion(variables denom a, variables denom b)))
+ empty? l => tantrick(a, b)
+ k := "max"/l
+ ilog0(a, b, numer univariate(a, k), numer univariate(b, k), k::F)
+
+-- transforms i log((a + i b) / (a - i b)) into a sum of real
+-- arc-tangents using Rioboo's algorithm
+-- the arc-tangents will not have k in the denominator
+-- we always keep upa(k) = a and upb(k) = b
+ ilog0(a, b, upa, upb, k) ==
+ if degree(upa) < degree(upb) then
+ (upa, upb) := (-upb, upa)
+ (a, b) := (-b, a)
+ zero? degree upb => tantrick(a, b)
+ r := extendedEuclidean(upa, upb)
+ (g:= retractIfCan(r.generator)@Union(F,"failed")) case "failed" =>
+ tantrick(a, b)
+ if degree(r.coef1) >= degree upb then
+ qr := divide(r.coef1, upb)
+ r.coef1 := qr.remainder
+ r.coef2 := r.coef2 + qr.quotient * upa
+ aa := (r.coef2) k
+ bb := -(r.coef1) k
+ tantrick(aa * a + bb * b, g::F) + ilog0(aa,bb,r.coef2,-r.coef1,k)
+
+ lg2func lg ==
+ zero?(d := degree(p := lg.coeff)) => error "poly has degree 0"
+-- one? d => [linear(p, lg.logand)]
+ (d = 1) => [linear(p, lg.logand)]
+ d = 2 => quadratic(p, lg.logand)
+ odd? d and
+ ((r := retractIfCan(reductum p)@Union(F, "failed")) case F) =>
+ pairsum([cmplex(alpha := rootSimp zeroOf p, lg.logand)],
+ lg2func [lg.scalar,
+ (p exquo (monomial(1, 1)$UP - alpha::UP))::UP,
+ lg.logand])
+ [lg2cfunc lg]
+
+ lg2cfunc lg ==
+ +/[cmplex(alpha, lg.logand) for alpha in zerosOf(lg.coeff)]
+
+ mkRealFunc l ==
+ ans := empty()$List(F)
+ for lg in l repeat
+ ans := pairsum(ans, pairprod(lg.scalar::F, lg2func lg))
+ ans
+
+-- returns a log(b)
+ linear(p, lg) ==
+ alpha := - coefficient(p, 0) / coefficient(p, 1)
+ alpha * log lg alpha
+
+-- returns (c, d) s.t. p(a + b t) = c + d t, where t^2 = delta
+ quadeval(p, a, b, delta) ==
+ zero? p => [0, 0]
+ bi := c := d := 0$F
+ ai := 1$F
+ v := vectorise(p, 1 + degree p)
+ for i in minIndex v .. maxIndex v repeat
+ c := c + qelt(v, i) * ai
+ d := d + qelt(v, i) * bi
+ temp := a * ai + b * bi * delta
+ bi := a * bi + b * ai
+ ai := temp
+ [c, d]
+
+ compatible?(lx, ly) ==
+ empty? ly => true
+ for x in lx repeat
+ for y in ly repeat
+ ((s := sign(x*y)) case Z) and (s::Z < 0) => return false
+ true
+
+ pairsum(lx, ly) ==
+ empty? lx => ly
+ empty? ly => lx
+ l := empty()$List(F)
+ for x in lx repeat
+ ls := evenRoots x
+ if not empty?(ln :=
+ [x + y for y in ly | compatible?(ls, evenRoots y)]) then
+ l := removeDuplicates concat(l, ln)
+ l
+
+-- returns [[a, b], s] where sqrt(y) = a sqrt(b) and
+-- s = 1 if b > 0, -1 if b < 0, 0 if the sign of b cannot be determined
+ insqrt y ==
+ rec := froot(y, 2)$PolynomialRoots(IndexedExponents K, K, R, P, F)
+-- one?(rec.exponent) => [[rec.coef * rec.radicand, 1], 1]
+ ((rec.exponent) = 1) => [[rec.coef * rec.radicand, 1], 1]
+ rec.exponent ^=2 => error "Should not happen"
+ [[rec.coef, rec.radicand],
+ ((s := sign(rec.radicand)) case "failed" => 0; s::Z)]
+
+ nlogs lg ==
+ [[f.exponent * lg.scalar, f.factor, lg.logand] for f in factors
+ ffactor(primitivePart(lg.coeff)
+ )$FunctionSpaceUnivariatePolynomialFactor(R, F, UP)]
+
+@
+\section{package IRRF2F IntegrationResultRFToFunction}
+<<package IRRF2F IntegrationResultRFToFunction>>=
+)abbrev package IRRF2F IntegrationResultRFToFunction
+++ Conversion of integration results to top-level expressions
+++ Author: Manuel Bronstein
+++ Description:
+++ This package allows a sum of logs over the roots of a polynomial
+++ to be expressed as explicit logarithms and arc tangents, provided
+++ that the indexing polynomial can be factored into quadratics.
+++ Date Created: 21 August 1988
+++ Date Last Updated: 4 October 1993
+IntegrationResultRFToFunction(R): Exports == Implementation where
+ R: Join(GcdDomain, RetractableTo Integer, OrderedSet,
+ LinearlyExplicitRingOver Integer)
+
+ RF ==> Fraction Polynomial R
+ F ==> Expression R
+ IR ==> IntegrationResult RF
+
+ Exports ==> with
+ split : IR -> IR
+ ++ split(u(x) + sum_{P(a)=0} Q(a,x)) returns
+ ++ \spad{u(x) + sum_{P1(a)=0} Q(a,x) + ... + sum_{Pn(a)=0} Q(a,x)}
+ ++ where P1,...,Pn are the factors of P.
+ expand : IR -> List F
+ ++ expand(i) returns the list of possible real functions
+ ++ corresponding to i.
+ complexExpand : IR -> F
+ ++ complexExpand(i) returns the expanded complex function
+ ++ corresponding to i.
+ if R has CharacteristicZero then
+ integrate : (RF, Symbol) -> Union(F, List F)
+ ++ integrate(f, x) returns the integral of \spad{f(x)dx}
+ ++ where x is viewed as a real variable..
+ complexIntegrate: (RF, Symbol) -> F
+ ++ complexIntegrate(f, x) returns the integral of \spad{f(x)dx}
+ ++ where x is viewed as a complex variable.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import TrigonometricManipulations(R, F)
+ import IntegrationResultToFunction(R, F)
+
+ toEF: IR -> IntegrationResult F
+
+ toEF i == map(#1::F, i)$IntegrationResultFunctions2(RF, F)
+ expand i == expand toEF i
+ complexExpand i == complexExpand toEF i
+
+ split i ==
+ map(retract, split toEF i)$IntegrationResultFunctions2(F, RF)
+
+ if R has CharacteristicZero then
+ import RationalFunctionIntegration(R)
+
+ complexIntegrate(f, x) == complexExpand internalIntegrate(f, x)
+
+-- do not use real integration if R is complex
+ if R has imaginary: () -> R then integrate(f, x) == complexIntegrate(f, x)
+ else
+ integrate(f, x) ==
+ l := [mkPrim(real g, x) for g in expand internalIntegrate(f, x)]
+ empty? rest l => first l
+ l
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg intaf efstruc rdeef intef IREXPAND integrat
+
+<<package IR2F IntegrationResultToFunction>>
+<<package IRRF2F IntegrationResultRFToFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/irsn.spad.pamphlet b/src/algebra/irsn.spad.pamphlet
new file mode 100644
index 00000000..369e7fc8
--- /dev/null
+++ b/src/algebra/irsn.spad.pamphlet
@@ -0,0 +1,365 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra irsn.spad}
+\author{Johannes Grabmeier, Thorsten Werther}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IRSN IrrRepSymNatPackage}
+<<package IRSN IrrRepSymNatPackage>>=
+)abbrev package IRSN IrrRepSymNatPackage
+++ Authors: Johannes Grabmeier, Thorsten Werther
+++ Date Created: 04 August 1988
+++ Date Last Updated: 24 May 1991
+++ Basic Operations: dimensionOfIrreducibleRepresentation
+++ irreducibleRepresentation
+++ Related Constructors: RepresentationTheoryPackage1
+++ RepresentationTheoryPackage2
+++ Also See: SymmetricGroupCombinatoricFunctions
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ G. James, A. Kerber: The Representation Theory of the Symmetric
+++ Group. Encycl. of Math. and its Appl. Vol 16., Cambr. Univ Press 1981;
+++ J. Grabmeier, A. Kerber: The Evaluation of Irreducible
+++ Polynomial Representations of the General Linear Groups
+++ and of the Unitary Groups over Fields of Characteristic 0,
+++ Acta Appl. Math. 8 (1987), 271-291;
+++ H. Gollan, J. Grabmeier: Algorithms in Representation Theory and
+++ their Realization in the Computer Algebra System Scratchpad,
+++ Bayreuther Mathematische Schriften, Heft 33, 1990, 1-23
+++ Description:
+++ IrrRepSymNatPackage contains functions for computing
+++ the ordinary irreducible representations of symmetric groups on
+++ n letters {\em {1,2,...,n}} in Young's natural form and their dimensions.
+++ These representations can be labelled by number partitions of n,
+++ i.e. a weakly decreasing sequence of integers summing up to n, e.g.
+++ {\em [3,3,3,1]} labels an irreducible representation for n equals 10.
+++ Note: whenever a \spadtype{List Integer} appears in a signature,
+++ a partition required.
+-- NOT TRUE in current system, but should:
+-- also could be an element of \spadtype(Partition)
+
+IrrRepSymNatPackage(): public == private where
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ L ==> List
+ M ==> Matrix
+ V ==> Vector
+ B ==> Boolean
+ SGCF ==> SymmetricGroupCombinatoricFunctions
+ ICF ==> IntegerCombinatoricFunctions Integer
+ PP ==> PartitionsAndPermutations
+ PERM ==> Permutation
+
+ public ==> with
+
+ dimensionOfIrreducibleRepresentation : L I -> NNI
+ ++ dimensionOfIrreducibleRepresentation(lambda) is the dimension
+ ++ of the ordinary irreducible representation of the symmetric group
+ ++ corresponding to {\em lambda}.
+ ++ Note: the Robinson-Thrall hook formula is implemented.
+ irreducibleRepresentation : (L I, PERM I) -> M I
+ ++ irreducibleRepresentation(lambda,pi) is the irreducible representation
+ ++ corresponding to partition {\em lambda} in Young's natural form of the
+ ++ permutation {\em pi} in the symmetric group, whose elements permute
+ ++ {\em {1,2,...,n}}.
+ irreducibleRepresentation : L I -> L M I
+ ++ irreducibleRepresentation(lambda) is the list of the two
+ ++ irreducible representations corresponding to the partition {\em lambda}
+ ++ in Young's natural form for the following two generators
+ ++ of the symmetric group, whose elements permute
+ ++ {\em {1,2,...,n}}, namely {\em (1 2)} (2-cycle) and
+ ++ {\em (1 2 ... n)} (n-cycle).
+ irreducibleRepresentation : (L I, L PERM I) -> L M I
+ ++ irreducibleRepresentation(lambda,listOfPerm) is the list of the
+ ++ irreducible representations corresponding to {\em lambda}
+ ++ in Young's natural form for the list of permutations
+ ++ given by {\em listOfPerm}.
+
+ private ==> add
+
+ -- local variables
+ oldlambda : L I := nil$(L I)
+ flambda : NNI := 0 -- dimension of the irreducible repr.
+ younglist : L M I := nil$(L M I) -- list of all standard tableaus
+ lprime : L I := nil$(L I) -- conjugated partition of lambda
+ n : NNI := 0 -- concerning symmetric group S_n
+ rows : NNI := 0 -- # of rows of standard tableau
+ columns : NNI := 0 -- # of columns of standard tableau
+ aId : M I := new(1,1,0)
+
+ -- declaration of local functions
+
+ aIdInverse : () -> Void
+ -- computes aId, the inverse of the matrix
+ -- (signum(k,l,id))_1 <= k,l <= flambda, where id
+ -- denotes the identity permutation
+
+ alreadyComputed? : L I -> Void
+ -- test if the last calling of an exported function concerns
+ -- the same partition lambda as the previous call
+
+ listPermutation : PERM I -> L I -- should be in Permutation
+ -- converts a permutation pi into the list
+ -- [pi(1),pi(2),..,pi(n)]
+
+ signum : (NNI, NNI, L I) -> I
+ -- if there exists a vertical permutation v of the tableau
+ -- tl := pi o younglist(l) (l-th standard tableau)
+ -- and a horizontal permutation h of the tableau
+ -- tk := younglist(k) (k-th standard tableau) such that
+ -- v o tl = h o tk,
+ -- then
+ -- signum(k,l,pi) = sign(v),
+ -- otherwise
+ -- signum(k,l,pi) = 0.
+
+ sumPartition : L I -> NNI
+ -- checks if lambda is a proper partition and results in
+ -- the sum of the entries
+
+ testPermutation : L I -> NNI
+ -- testPermutation(pi) checks if pi is an element of S_n,
+ -- the set of permutations of the set {1,2,...,n}.
+ -- If not, an error message will occur, if yes it replies n.
+
+
+ -- definition of local functions
+
+
+ aIdInverse() ==
+
+ aId := new(flambda,flambda,0)
+ for k in 1..flambda repeat
+ aId(k,k) := 1
+ if n < 5 then return aId
+
+ idperm : L I := nil$(L I)
+ for k in n..1 by -1 repeat
+ idperm := cons(k,idperm)
+ for k in 1..(flambda-1) repeat
+ for l in (k+1)..flambda repeat
+ aId(k::NNI,l::NNI) := signum(k::NNI,l::NNI,idperm)
+
+ -- invert the upper triangular matrix aId
+ for j in flambda..2 by -1 repeat
+ for i in (j-1)..1 by -1 repeat
+ aId(i::NNI,j:NNI) := -aId(i::NNI,j::NNI)
+ for k in (j+1)..flambda repeat
+ for i in (j-1)..1 by -1 repeat
+ aId(i::NNI,k:NNI) := aId(i::NNI,k::NNI) +
+ aId(i::NNI,j:NNI) * aId(j::NNI,k::NNI)
+
+
+ alreadyComputed?(lambda) ==
+ if not(lambda = oldlambda) then
+ oldlambda := lambda
+ lprime := conjugate(lambda)$PP
+ rows := (first(lprime)$(L I))::NNI
+ columns := (first(lambda)$(L I))::NNI
+ n := (+/lambda)::NNI
+ younglist := listYoungTableaus(lambda)$SGCF
+ flambda := #younglist
+ aIdInverse() -- side effect: creates actual aId
+
+ listPermutation(pi) ==
+ li : L I := nil$(L I)
+ for k in n..1 by -1 repeat
+ li := cons(eval(pi,k)$(PERM I),li)
+ li
+
+ signum(numberOfRowTableau, numberOfColumnTableau,pi) ==
+
+ rowtab : M I := copy younglist numberOfRowTableau
+ columntab : M I := copy younglist numberOfColumnTableau
+ swap : I
+ sign : I := 1
+ end : B := false
+ endk : B
+ ctrl : B
+
+ -- k-loop for all rows of tableau rowtab
+ k : NNI := 1
+ while (k <= rows) and (not end) repeat
+ -- l-loop along the k-th row of rowtab
+ l : NNI := 1
+ while (l <= oldlambda(k)) and (not end) repeat
+ z : NNI := l
+ endk := false
+ -- z-loop for k-th row of rowtab beginning at column l.
+ -- test wether the entry rowtab(k,z) occurs in the l-th column
+ -- beginning at row k of pi o columntab
+ while (z <= oldlambda(k)) and (not endk) repeat
+ s : NNI := k
+ ctrl := true
+ while ctrl repeat
+ if (s <= lprime(l))
+ then
+ if (1+rowtab(k,z) = pi(1+columntab(s,l)))
+ -- if entries in the tableaus were from 1,..,n, then
+ -- it should be ..columntab(s,l)... .
+ then ctrl := false
+ else s := s + 1
+ else ctrl := false
+ -- end of ctrl-loop
+ endk := (s <= lprime(l)) -- same entry found ?
+ if not endk
+ then -- try next entry
+ z := z + 1
+ else
+ if k < s
+ then -- verticalpermutation
+ sign := -sign
+ swap := columntab(s,l)
+ columntab(s,l) := columntab(k,l)
+ columntab(k,l) := swap
+ if l < z
+ then -- horizontalpermutation
+ swap := rowtab(k,z)
+ rowtab(k,z) := rowtab(k,l)
+ rowtab(k,l) := swap
+ -- end of else
+ -- end of z-loop
+ if (z > oldlambda(k)) -- no coresponding entry found
+ then
+ sign := 0
+ end := true
+ l := l + 1
+ -- end of l-loop
+ k := k + 1
+ -- end of k-loop
+
+ sign
+
+
+ sumPartition(lambda) ==
+ ok : B := true
+ prev : I := first lambda
+ sum : I := 0
+ for x in lambda repeat
+ sum := sum + x
+ ok := ok and (prev >= x)
+ prev := x
+ if not ok then
+ error("No proper partition ")
+ sum::NNI
+
+
+ testPermutation(pi : L I) : NNI ==
+ ok : B := true
+ n : I := 0
+ for i in pi repeat
+ if i > n then n := i -- find the largest entry n in pi
+ if i < 1 then ok := false -- check whether there are entries < 1
+ -- now n should be the number of permuted objects
+ if (not (n=#pi)) or (not ok) then
+ error("No permutation of 1,2,..,n")
+ -- now we know that pi has n Elements ranging from 1 to n
+ test : Vector(B) := new((n)::NNI,false)
+ for i in pi repeat
+ test(i) := true -- this means that i occurs in pi
+ if member?(false,test) then error("No permutation") -- pi not surjective
+ n::NNI
+
+
+ -- definitions of exported functions
+
+
+ dimensionOfIrreducibleRepresentation(lambda) ==
+ nn : I := sumPartition(lambda)::I --also checks whether lambda
+ dd : I := 1 --is a partition
+ lambdaprime : L I := conjugate(lambda)$PP
+ -- run through all rows of the Youngtableau corr. to lambda
+ for i in 1..lambdaprime.1 repeat
+ -- run through all nodes in row i of the Youngtableau
+ for j in 1..lambda.i repeat
+ -- the hooklength of node (i,j) of the Youngtableau
+ -- is the new factor, remember counting starts with 1
+ dd := dd * (lambda.i + lambdaprime.j - i - j + 1)
+ (factorial(nn)$ICF quo dd)::NNI
+
+
+ irreducibleRepresentation(lambda:(L I),pi:(PERM I)) ==
+ nn : NNI := sumPartition(lambda)
+ alreadyComputed?(lambda)
+ piList : L I := listPermutation pi
+ if not (nn = testPermutation(piList)) then
+ error("Partition and permutation are not consistent")
+ aPi : M I := new(flambda,flambda,0)
+ for k in 1..flambda repeat
+ for l in 1..flambda repeat
+ aPi(k,l) := signum(k,l,piList)
+ aId * aPi
+
+
+ irreducibleRepresentation(lambda) ==
+ listperm : L PERM I := nil$(L PERM I)
+ li : L I := nil$(L I)
+ sumPartition(lambda)
+ alreadyComputed?(lambda)
+ listperm :=
+ n = 1 => cons(1$(PERM I),listperm)
+ n = 2 => cons(cycle([1,2])$(PERM I),listperm)
+ -- the n-cycle (1,2,..,n) and the 2-cycle (1,2) generate S_n
+ for k in n..1 by -1 repeat
+ li := cons(k,li) -- becomes n-cycle (1,2,..,n)
+ listperm := cons(cycle(li)$(PERM I),listperm)
+ -- 2-cycle (1,2)
+ cons(cycle([1,2])$(PERM I),listperm)
+ irreducibleRepresentation(lambda,listperm)
+
+
+ irreducibleRepresentation(lambda:(L I),listperm:(L PERM I)) ==
+ sumPartition(lambda)
+ alreadyComputed?(lambda)
+ [irreducibleRepresentation(lambda, pi) for pi in listperm]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package IRSN IrrRepSymNatPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ituple.spad.pamphlet b/src/algebra/ituple.spad.pamphlet
new file mode 100644
index 00000000..84eaa8c2
--- /dev/null
+++ b/src/algebra/ituple.spad.pamphlet
@@ -0,0 +1,140 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ituple.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ITUPLE InfiniteTuple}
+<<domain ITUPLE InfiniteTuple>>=
+)abbrev domain ITUPLE InfiniteTuple
+++ Infinite tuples for the interpreter
+++ Author: Clifton J. Williamson
+++ Date Created: 16 February 1990
+++ Date Last Updated: 16 February 1990
+++ Keywords:
+++ Examples:
+++ References:
+InfiniteTuple(S:Type): Exports == Implementation where
+ ++ This package implements 'infinite tuples' for the interpreter.
+ ++ The representation is a stream.
+
+ Exports ==> CoercibleTo OutputForm with
+ map: (S -> S, %) -> %
+ ++ map(f,t) replaces the tuple t
+ ++ by \spad{[f(x) for x in t]}.
+ filterWhile: (S -> Boolean, %) -> %
+ ++ filterWhile(p,t) returns \spad{[x for x in t while p(x)]}.
+ filterUntil: (S -> Boolean, %) -> %
+ ++ filterUntil(p,t) returns \spad{[x for x in t while not p(x)]}.
+ select: (S -> Boolean, %) -> %
+ ++ select(p,t) returns \spad{[x for x in t | p(x)]}.
+ generate: (S -> S,S) -> %
+ ++ generate(f,s) returns \spad{[s,f(s),f(f(s)),...]}.
+ construct: % -> Stream S
+ ++ construct(t) converts an infinite tuple to a stream.
+
+ Implementation ==> Stream S add
+ generate(f,x) == generate(f,x)$Stream(S) pretend %
+ filterWhile(f, x) == filterWhile(f,x pretend Stream(S))$Stream(S) pretend %
+ filterUntil(f, x) == filterUntil(f,x pretend Stream(S))$Stream(S) pretend %
+ select(f, x) == select(f,x pretend Stream(S))$Stream(S) pretend %
+ construct x == x pretend Stream(S)
+-- coerce x ==
+-- coerce(x)$Stream(S)
+
+@
+\section{package ITFUN2 InfiniteTupleFunctions2}
+<<package ITFUN2 InfiniteTupleFunctions2>>=
+)abbrev package ITFUN2 InfiniteTupleFunctions2
+InfiniteTupleFunctions2(A:Type,B:Type): Exports == Implementation where
+ ++ Functions defined on streams with entries in two sets.
+ IT ==> InfiniteTuple
+
+ Exports ==> with
+ map: ((A -> B),IT A) -> IT B
+ ++ \spad{map(f,[x0,x1,x2,...])} returns \spad{[f(x0),f(x1),f(x2),..]}.
+
+ Implementation ==> add
+
+ map(f,x) ==
+ map(f,x pretend Stream(A))$StreamFunctions2(A,B) pretend IT(B)
+
+@
+\section{package ITFUN3 InfiniteTupleFunctions3}
+<<package ITFUN3 InfiniteTupleFunctions3>>=
+)abbrev package ITFUN3 InfiniteTupleFunctions3
+InfiniteTupleFunctions3(A:Type, B:Type,C:Type): Exports
+ == Implementation where
+ ++ Functions defined on streams with entries in two sets.
+ IT ==> InfiniteTuple
+ ST ==> Stream
+ SF3 ==> StreamFunctions3(A,B,C)
+ FUN ==> ((A,B)->C)
+ Exports ==> with
+ map: (((A,B)->C), IT A, IT B) -> IT C
+ ++ map(f,a,b) \undocumented
+ map: (((A,B)->C), ST A, IT B) -> ST C
+ ++ map(f,a,b) \undocumented
+ map: (((A,B)->C), IT A, ST B) -> ST C
+ ++ map(f,a,b) \undocumented
+
+ Implementation ==> add
+
+ map(f:FUN, s1:IT A, s2:IT B):IT C ==
+ map(f, s1 pretend Stream(A), s2 pretend Stream(B))$SF3 pretend IT(C)
+ map(f:FUN, s1:ST A, s2:IT B):ST C ==
+ map(f, s1, s2 pretend Stream(B))$SF3
+ map(f:FUN, s1:IT A, s2:ST B):ST C ==
+ map(f, s1 pretend Stream(A), s2)$SF3
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ITUPLE InfiniteTuple>>
+<<package ITFUN2 InfiniteTupleFunctions2>>
+<<package ITFUN3 InfiniteTupleFunctions3>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/iviews.as.pamphlet b/src/algebra/iviews.as.pamphlet
new file mode 100644
index 00000000..37a09af4
--- /dev/null
+++ b/src/algebra/iviews.as.pamphlet
@@ -0,0 +1,330 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra iviews.as}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{InventorDataSink}
+<<InventorDataSink>>=
+#include "axiom"
+#assert Real
+
+NNI ==> NonNegativeInteger;
+SI ==> SingleInteger;
+DF ==> DoubleFloat;
+POINT ==> Point DF;
+SPACE3 ==> ThreeSpace DoubleFloat;
+
+DefaultSize ==> 65530;
+
+Value ==> Symbol;
+
+InventorDataSink: with {
+ CoercibleTo OutputForm;
+ new: () -> %;
+ dispose!: % -> ();
+
+ put!: (%, SI) -> ();
+ put!: (%, DF) -> ();
+ put!: (%, String) -> ();
+
+ vstart!: (%, 'int,float', SI) -> ();
+ vput!: (%, SI) -> ();
+ vput!: (%, DF) -> ();
+
+ lstart!: % -> ();
+ lend!: % -> ();
+ export from 'int,float'
+} == add {
+#if Real
+ -- No rep (we cheat!)
+ import from SI;
+ valOf(x) ==> x pretend Value;
+ default sink: %;
+ import {
+ LISP_:_:GR_-GET_-MEM_-AREA: SI -> %;
+ LISP_:_:GR_-KILL_-MEM_-AREA: % -> ();
+ LISP_:_:GR_-PUT_-ITEM: (%, Value) -> ();
+ LISP_:_:GR_-PUT_-LSTART: % -> ();
+ LISP_:_:GR_-PUT_-LEND: % -> ();
+ LISP_:_:GR_-INIT_-VECTOR: (%, Value, Value) -> %;
+ LISP_:_:GR_-ADD_-TO_-VECTOR: (%, Value) -> %;
+ } from Foreign Lisp;
+
+ new(): % == LISP_:_:GR_-GET_-MEM_-AREA(DefaultSize);
+ dispose!(sink): () == LISP_:_:GR_-KILL_-MEM_-AREA(sink);
+
+ put!(sink, si: SI): () == LISP_:_:GR_-PUT_-ITEM(sink, valOf(si));
+ put!(sink, st: String): () == LISP_:_:GR_-PUT_-ITEM(sink, valOf(st));
+ put!(sink, fl: DF): () == LISP_:_:GR_-PUT_-ITEM(sink, valOf(fl));
+
+ vstart!(sink, type: 'int,float', sz: SI): () == {
+ local sym: Symbol;
+ if type = int then
+ sym := coerce("integer");
+ else
+ sym := coerce("float");
+ LISP_:_:GR_-INIT_-VECTOR(sink, valOf(sym), valOf(sz));
+ }
+
+ vput!(sink, si: SI): () ==
+ LISP_:_:GR_-ADD_-TO_-VECTOR(sink, valOf(si));
+ vput!(sink, df: DF): () ==
+ LISP_:_:GR_-ADD_-TO_-VECTOR(sink, valOf(df));
+
+ lstart!(sink): () == LISP_:_:GR_-PUT_-LSTART sink;
+ lend!(sink): () == LISP_:_:GR_-PUT_-LEND sink;
+
+ coerce(sink): OutputForm == {
+ [outputForm "aSink"]
+ }
+#else
+ Rep ==> Record(count: NonNegativeInteger);
+ import from Rep, NNI;
+ default sink: %;
+ coerce(sink): OutputForm == {
+ import from List OutputForm;
+ bracket [outputForm "Sink: ",
+ outputForm coerce rep(sink).count];
+ }
+
+ local addn!(sink, n: NNI): () ==
+ rep(sink).count := rep(sink).count + n;
+ new(): % == per [0];
+ dispose!(sink): () == dispose! rep sink;
+
+ put!(sink, n: SI): () == addn!(sink, 1 + 4);
+ put!(sink, f: DF): () == addn!(sink, 1 + 4);
+ put!(sink, s: String): () == {
+ addn!(sink, #s + 1 + 1);
+ }
+
+ vstart!(sink, type: 'int, float', n: SI): () == {
+ addn!(sink, 1 + n::NNI*4);
+ }
+
+ vput!(sink, n: SI): () == {};
+ vput!(sink, n: DF): () == {};
+
+ lstart!(sink): () == addn!(sink, 1);
+ lend!(sink): () == addn!(sink, 1);
+
+#endif
+}
+
+@
+\section{InventorViewPort}
+<<InventorViewPort>>=
+InventorViewPort: with {
+ new: () -> %;
+ new: ThreeSpace DoubleFloat -> %;
+ addData!: (%, InventorDataSink) -> %;
+ addData!: (%, ThreeSpace DoubleFloat) -> %;
+} == add {
+#if Real
+ import {
+ LISP_:_:GR_-MAKE_-VIEW: (SI) -> %;
+ LISP_:_:GR_-SET_-DATA: (%, InventorDataSink) -> ();
+ } from Foreign Lisp;
+ import from SingleInteger;
+
+ new(): % == LISP_:_:GR_-MAKE_-VIEW(0);
+
+ new(space: ThreeSpace DoubleFloat): % == {
+ import from InventorDataSink;
+ import from InventorRenderPackage;
+ view: % := new();
+ addData!(view, space);
+ view
+ }
+
+ addData!(view: %, data: InventorDataSink): % == {
+ LISP_:_:GR_-SET_-DATA(view, data);
+ view;
+ }
+
+ addData!(view: %, space: ThreeSpace DoubleFloat): % == {
+ import from InventorRenderPackage;
+ sink: InventorDataSink := new();
+ render(sink, space, cartesian$CoordinateSystems(DoubleFloat));
+ addData!(view, sink);
+ view
+ }
+
+#else
+ Rep ==> SingleInteger;
+ import from Rep;
+ new(): % == per 1;
+ new(x: ThreeSpace DoubleFloat): % == per 2;
+ addData!(view: %, data: InventorDataSink): % == view;
+#endif
+
+}
+
+@
+\section{InventorRenderPackage}
+<<InventorRenderPackage>>=
+InventorRenderPackage: with {
+ render: (InventorDataSink, ThreeSpace DoubleFloat, POINT->POINT) -> ();
+} == add {
+ default sink: InventorDataSink;
+ default space: ThreeSpace DoubleFloat;
+ default transform: POINT->POINT;
+ import from SI;
+
+ local put!(sink, dims: UniversalSegment SI,
+ lp: List Point DoubleFloat,
+ f: Point DoubleFloat -> Point DoubleFloat): () == {
+ import from NNI, Integer;
+ i : SI := 0;
+ for x in dims repeat i:= i+1;
+ vstart!(sink, float, i*(coerce #lp));
+ for p in lp repeat {
+ p1 := f(p);
+ for idx in dims repeat
+ vput!(sink, p1.(idx::Integer));
+ }
+ }
+
+ local put!(sink, lp: List SI): () == {
+ import from NNI;
+ vstart!(sink, int, coerce #lp);
+ for p in lp repeat {
+ vput!(sink, p);
+ }
+ }
+
+ local putPoints!(sink, transform,
+ lpts: List POINT, indexList: List NNI): () == {
+ import from Integer;
+ if not sorted? indexList
+ then {
+ -- not nice!
+ lst: List POINT := [];
+ for idx in indexList repeat
+ lst := cons(lpts.(coerce idx), lst);
+ lpts := reverse! lst;
+ }
+ put!(sink, 1..3, lpts, transform);
+ if (# first lpts) = 4
+ then {
+ put!(sink, "Colours");
+ put!(sink, 4..4, lpts, transform);
+ }
+ }
+ render(sink, space, transform): () == {
+ default ss: SPACE3;
+ default i: NNI;
+ import from List POINT;
+ import from List List List NNI;
+ import from List List NNI;
+ import from List SPACE3;
+ import from SingleInteger;
+ put!(sink, "ThreeDScene");
+ -- Get the point data
+ check(space);
+ indices := lllip(space);
+ lpts := lp(space);
+ indexList := concat concat indices;
+ put!(sink, "Points");
+ putPoints!(sink, transform, lpts, indexList);
+ offset : SI := 0;
+ lstart!(sink);
+ for ss in components(space) for index in indices repeat {
+ closedCurve? ss => {
+ put!(sink, "closedCurve");
+ n: SI := coerce #(first index);
+ put!(sink, offset);
+ put!(sink, n);
+ offset := offset + n;
+ }
+ curve? ss=> {
+ put!(sink, "curve");
+ n: SI := coerce #(first index);
+ put!(sink, offset);
+ put!(sink, n);
+ offset := offset + n;
+ }
+ polygon? ss => {
+ local vertices: SI;
+ put!(sink, "polygon");
+ vertices := coerce(#(first index)
+ + #(first rest index));
+ put!(sink, offset);
+ put!(sink, vertices);
+ offset := offset+vertices;
+ }
+ mesh? ss=> {
+ local xStep, yStep: SI;
+ put!(sink, "mesh");
+ xStep := coerce #index;
+ yStep := coerce #(first index);
+ put!(sink, offset);
+ put!(sink, xStep);
+ put!(sink, yStep);
+ offset := offset+xStep*yStep;
+ }
+ point? ss => {
+ put!(sink, "points");
+ put!(sink, offset);
+ put!(sink, 1);
+ offset := offset+1;
+ }
+ error "Unrecognised SubSpace component";
+ }
+ lend!(sink);
+ }
+
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<InventorDataSink>>
+<<InventorViewPort>>
+<<InventorRenderPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/kl.spad.pamphlet b/src/algebra/kl.spad.pamphlet
new file mode 100644
index 00000000..0ebb9578
--- /dev/null
+++ b/src/algebra/kl.spad.pamphlet
@@ -0,0 +1,361 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra kl.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category CACHSET CachableSet}
+<<category CACHSET CachableSet>>=
+)abbrev category CACHSET CachableSet
+++ Sets whose elements can cache an integer
+++ Author: Manuel Bronstein
+++ Date Created: 31 Oct 1988
+++ Date Last Updated: 14 May 1991
+++ Description:
+++ A cachable set is a set whose elements keep an integer as part
+++ of their structure.
+CachableSet: Category == OrderedSet with
+ position : % -> NonNegativeInteger
+ ++ position(x) returns the integer n associated to x.
+ setPosition: (%, NonNegativeInteger) -> Void
+ ++ setPosition(x, n) associates the integer n to x.
+
+@
+\section{package SCACHE SortedCache}
+<<package SCACHE SortedCache>>=
+)abbrev package SCACHE SortedCache
+++ Cache of elements in a set
+++ Author: Manuel Bronstein
+++ Date Created: 31 Oct 1988
+++ Date Last Updated: 14 May 1991
+++ A sorted cache of a cachable set S is a dynamic structure that
+++ keeps the elements of S sorted and assigns an integer to each
+++ element of S once it is in the cache. This way, equality and ordering
+++ on S are tested directly on the integers associated with the elements
+++ of S, once they have been entered in the cache.
+SortedCache(S:CachableSet): Exports == Implementation where
+ N ==> NonNegativeInteger
+ DIFF ==> 1024
+
+ Exports ==> with
+ clearCache : () -> Void
+ ++ clearCache() empties the cache.
+ cache : () -> List S
+ ++ cache() returns the current cache as a list.
+ enterInCache: (S, S -> Boolean) -> S
+ ++ enterInCache(x, f) enters x in the cache, calling \spad{f(y)} to
+ ++ determine whether x is equal to y. It returns x with an integer
+ ++ associated with it.
+ enterInCache: (S, (S, S) -> Integer) -> S
+ ++ enterInCache(x, f) enters x in the cache, calling \spad{f(x, y)} to
+ ++ determine whether \spad{x < y (f(x,y) < 0), x = y (f(x,y) = 0)}, or
+ ++ \spad{x > y (f(x,y) > 0)}.
+ ++ It returns x with an integer associated with it.
+
+ Implementation ==> add
+ shiftCache : (List S, N) -> Void
+ insertInCache: (List S, List S, S, N) -> S
+
+ cach := [nil()]$Record(cche:List S)
+
+ cache() == cach.cche
+
+ shiftCache(l, n) ==
+ for x in l repeat setPosition(x, n + position x)
+ void
+
+ clearCache() ==
+ for x in cache repeat setPosition(x, 0)
+ cach.cche := nil()
+ void
+
+ enterInCache(x:S, equal?:S -> Boolean) ==
+ scan := cache()
+ while not null scan repeat
+ equal?(y := first scan) =>
+ setPosition(x, position y)
+ return y
+ scan := rest scan
+ setPosition(x, 1 + #cache())
+ cach.cche := concat(cache(), x)
+ x
+
+ enterInCache(x:S, triage:(S, S) -> Integer) ==
+ scan := cache()
+ pos:N:= 0
+ for i in 1..#scan repeat
+ zero?(n := triage(x, y := first scan)) =>
+ setPosition(x, position y)
+ return y
+ n<0 => return insertInCache(first(cache(),(i-1)::N),scan,x,pos)
+ scan := rest scan
+ pos := position y
+ setPosition(x, pos + DIFF)
+ cach.cche := concat(cache(), x)
+ x
+
+ insertInCache(before, after, x, pos) ==
+ if ((pos+1) = position first after) then shiftCache(after, DIFF)
+ setPosition(x, pos + (((position first after) - pos)::N quo 2))
+ cach.cche := concat(before, concat(x, after))
+ x
+
+@
+\section{domain MKCHSET MakeCachableSet}
+<<domain MKCHSET MakeCachableSet>>=
+)abbrev domain MKCHSET MakeCachableSet
+++ Make a cachable set from any set
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description:
+++ MakeCachableSet(S) returns a cachable set which is equal to S as a set.
+MakeCachableSet(S:SetCategory): Exports == Implementation where
+ Exports ==> Join(CachableSet, CoercibleTo S) with
+ coerce: S -> %
+ ++ coerce(s) returns s viewed as an element of %.
+
+ Implementation ==> add
+ import SortedCache(%)
+
+ Rep := Record(setpart: S, pos: NonNegativeInteger)
+
+ clearCache()
+
+ position x == x.pos
+ setPosition(x, n) == (x.pos := n; void)
+ coerce(x:%):S == x.setpart
+ coerce(x:%):OutputForm == x::S::OutputForm
+ coerce(s:S):% == enterInCache([s, 0]$Rep, s = #1::S)
+
+ x < y ==
+ if position(x) = 0 then enterInCache(x, x::S = #1::S)
+ if position(y) = 0 then enterInCache(y, y::S = #1::S)
+ position(x) < position(y)
+
+ x = y ==
+ if position(x) = 0 then enterInCache(x, x::S = #1::S)
+ if position(y) = 0 then enterInCache(y, y::S = #1::S)
+ position(x) = position(y)
+
+@
+\section{domain KERNEL Kernel}
+<<domain KERNEL Kernel>>=
+)abbrev domain KERNEL Kernel
+++ Operators applied to elements of a set
+++ Author: Manuel Bronstein
+++ Date Created: 22 March 1988
+++ Date Last Updated: 10 August 1994
+++ Description:
+++ A kernel over a set S is an operator applied to a given list
+++ of arguments from S.
+Kernel(S:OrderedSet): Exports == Implementation where
+ O ==> OutputForm
+ N ==> NonNegativeInteger
+ OP ==> BasicOperator
+
+ SYMBOL ==> "%symbol"
+ PMPRED ==> "%pmpredicate"
+ PMOPT ==> "%pmoptional"
+ PMMULT ==> "%pmmultiple"
+ PMCONST ==> "%pmconstant"
+ SPECIALDISP ==> "%specialDisp"
+ SPECIALEQUAL ==> "%specialEqual"
+ SPECIALINPUT ==> "%specialInput"
+
+ Exports ==> Join(CachableSet, Patternable S) with
+ name : % -> Symbol
+ ++ name(op(a1,...,an)) returns the name of op.
+ operator: % -> OP
+ ++ operator(op(a1,...,an)) returns the operator op.
+ argument: % -> List S
+ ++ argument(op(a1,...,an)) returns \spad{[a1,...,an]}.
+ height : % -> N
+ ++ height(k) returns the nesting level of k.
+ kernel : (OP, List S, N) -> %
+ ++ kernel(op, [a1,...,an], m) returns the kernel \spad{op(a1,...,an)}
+ ++ of nesting level m.
+ ++ Error: if op is k-ary for some k not equal to m.
+ kernel : Symbol -> %
+ ++ kernel(x) returns x viewed as a kernel.
+ symbolIfCan: % -> Union(Symbol, "failed")
+ ++ symbolIfCan(k) returns k viewed as a symbol if k is a symbol, and
+ ++ "failed" otherwise.
+ is? : (%, OP) -> Boolean
+ ++ is?(op(a1,...,an), f) tests if op = f.
+ is? : (%, Symbol) -> Boolean
+ ++ is?(op(a1,...,an), s) tests if the name of op is s.
+ if S has ConvertibleTo InputForm then ConvertibleTo InputForm
+
+ Implementation ==> add
+ import SortedCache(%)
+
+ Rep := Record(op:OP, arg:List S, nest:N, posit:N)
+
+ clearCache()
+
+ B2Z : Boolean -> Integer
+ triage: (%, %) -> Integer
+ preds : OP -> List Any
+
+ is?(k:%, s:Symbol) == is?(operator k, s)
+ is?(k:%, o:OP) == (operator k) = o
+ name k == name operator k
+ height k == k.nest
+ operator k == k.op
+ argument k == k.arg
+ position k == k.posit
+ setPosition(k, n) == k.posit := n
+ B2Z flag == (flag => -1; 1)
+ kernel s == kernel(assert(operator(s,0),SYMBOL), nil(), 1)
+
+ preds o ==
+ (u := property(o, PMPRED)) case "failed" => nil()
+ (u::None) pretend List(Any)
+
+ symbolIfCan k ==
+ has?(operator k, SYMBOL) => name operator k
+ "failed"
+
+ k1 = k2 ==
+ if k1.posit = 0 then enterInCache(k1, triage)
+ if k2.posit = 0 then enterInCache(k2, triage)
+ k1.posit = k2.posit
+
+ k1 < k2 ==
+ if k1.posit = 0 then enterInCache(k1, triage)
+ if k2.posit = 0 then enterInCache(k2, triage)
+ k1.posit < k2.posit
+
+ kernel(fn, x, n) ==
+ ((u := arity fn) case N) and (#x ^= u::N)
+ => error "Wrong number of arguments"
+ enterInCache([fn, x, n, 0]$Rep, triage)
+
+ -- SPECIALDISP contains a map List S -> OutputForm
+ -- it is used when the converting the arguments first is not good,
+ -- for instance with formal derivatives.
+ coerce(k:%):OutputForm ==
+ (v := symbolIfCan k) case Symbol => v::Symbol::OutputForm
+ (f := property(o := operator k, SPECIALDISP)) case None =>
+ ((f::None) pretend (List S -> OutputForm)) (argument k)
+ l := [x::OutputForm for x in argument k]$List(OutputForm)
+ (u := display o) case "failed" => prefix(name(o)::OutputForm, l)
+ (u::(List OutputForm -> OutputForm)) l
+
+ triage(k1, k2) ==
+ k1.nest ^= k2.nest => B2Z(k1.nest < k2.nest)
+ k1.op ^= k2.op => B2Z(k1.op < k2.op)
+ (n1 := #(argument k1)) ^= (n2 := #(argument k2)) => B2Z(n1 < n2)
+ ((func := property(operator k1, SPECIALEQUAL)) case None) and
+ (((func::None) pretend ((%, %) -> Boolean)) (k1, k2)) => 0
+ for x1 in argument(k1) for x2 in argument(k2) repeat
+ x1 ^= x2 => return B2Z(x1 < x2)
+ 0
+
+ if S has ConvertibleTo InputForm then
+ convert(k:%):InputForm ==
+ (v := symbolIfCan k) case Symbol => convert(v::Symbol)@InputForm
+ (f := property(o := operator k, SPECIALINPUT)) case None =>
+ ((f::None) pretend (List S -> InputForm)) (argument k)
+ l := [convert x for x in argument k]$List(InputForm)
+ (u := input operator k) case "failed" =>
+ convert concat(convert name operator k, l)
+ (u::(List InputForm -> InputForm)) l
+
+ if S has ConvertibleTo Pattern Integer then
+ convert(k:%):Pattern(Integer) ==
+ o := operator k
+ (v := symbolIfCan k) case Symbol =>
+ s := patternVariable(v::Symbol,
+ has?(o, PMCONST), has?(o, PMOPT), has?(o, PMMULT))
+ empty?(l := preds o) => s
+ setPredicates(s, l)
+ o [convert x for x in k.arg]$List(Pattern Integer)
+
+ if S has ConvertibleTo Pattern Float then
+ convert(k:%):Pattern(Float) ==
+ o := operator k
+ (v := symbolIfCan k) case Symbol =>
+ s := patternVariable(v::Symbol,
+ has?(o, PMCONST), has?(o, PMOPT), has?(o, PMMULT))
+ empty?(l := preds o) => s
+ setPredicates(s, l)
+ o [convert x for x in k.arg]$List(Pattern Float)
+
+@
+\section{package KERNEL2 KernelFunctions2}
+<<package KERNEL2 KernelFunctions2>>=
+)abbrev package KERNEL2 KernelFunctions2
+++ Description:
+++ This package exports some auxiliary functions on kernels
+KernelFunctions2(R:OrderedSet, S:OrderedSet): with
+ constantKernel: R -> Kernel S
+ ++ constantKernel(r) \undocumented
+ constantIfCan : Kernel S -> Union(R, "failed")
+ ++ constantIfCan(k) \undocumented
+
+ == add
+ import BasicOperatorFunctions1(R)
+
+ constantKernel r == kernel(constantOperator r, nil(), 1)
+ constantIfCan k == constantOpIfCan operator k
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op KL expr function
+
+<<category CACHSET CachableSet>>
+<<package SCACHE SortedCache>>
+<<domain MKCHSET MakeCachableSet>>
+<<domain KERNEL Kernel>>
+<<package KERNEL2 KernelFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/kovacic.spad.pamphlet b/src/algebra/kovacic.spad.pamphlet
new file mode 100644
index 00000000..9a330d2d
--- /dev/null
+++ b/src/algebra/kovacic.spad.pamphlet
@@ -0,0 +1,152 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra kovacic.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package KOVACIC Kovacic}
+<<package KOVACIC Kovacic>>=
+)abbrev package KOVACIC Kovacic
+++ Author: Manuel Bronstein
+++ Date Created: 14 January 1992
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{Kovacic} provides a modified Kovacic's algorithm for
+++ solving explicitely irreducible 2nd order linear ordinary
+++ differential equations.
+++ Keywords: differential equation, ODE
+Kovacic(F, UP): Exports == Impl where
+ F : Join(CharacteristicZero, AlgebraicallyClosedField,
+ RetractableTo Integer, RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+
+ RF ==> Fraction UP
+ SUP ==> SparseUnivariatePolynomial RF
+ LF ==> List Record(factor:UP, exponent:Integer)
+ LODO==> LinearOrdinaryDifferentialOperator1 RF
+
+ Exports ==> with
+ kovacic: (RF, RF, RF) -> Union(SUP, "failed")
+ ++ kovacic(a_0,a_1,a_2) returns either "failed" or P(u) such that
+ ++ \spad{$e^{\int(-a_1/2a_2)} e^{\int u}$} is a solution of
+ ++ \spad{a_2 y'' + a_1 y' + a0 y = 0}
+ ++ whenever \spad{u} is a solution of \spad{P u = 0}.
+ ++ The equation must be already irreducible over the rational functions.
+ kovacic: (RF, RF, RF, UP -> Factored UP) -> Union(SUP, "failed")
+ ++ kovacic(a_0,a_1,a_2,ezfactor) returns either "failed" or P(u) such
+ ++ that \spad{$e^{\int(-a_1/2a_2)} e^{\int u}$} is a solution of
+ ++ \spad{$a_2 y'' + a_1 y' + a0 y = 0$}
+ ++ whenever \spad{u} is a solution of \spad{P u = 0}.
+ ++ The equation must be already irreducible over the rational functions.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+
+ Impl ==> add
+ import RationalRicDE(F, UP)
+
+ case2 : (RF, LF, UP -> Factored UP) -> Union(SUP, "failed")
+ cannotCase2?: LF -> Boolean
+
+ kovacic(a0, a1, a2) == kovacic(a0, a1, a2, squareFree)
+
+ -- it is assumed here that a2 y'' + a1 y' + a0 y is already irreducible
+ -- over the rational functions, i.e. that the associated Riccati equation
+ -- does NOT have rational solutions (so we don't check case 1 of Kovacic's
+ -- algorithm)
+ -- currently only check case 2, not 3
+ kovacic(a0, a1, a2, ezfactor) ==
+ -- transform first the equation to the form y'' = r y
+ -- which makes the Galois group unimodular
+ -- this does not change irreducibility over the rational functions
+ -- the following is split into 5 lines in order to save a couple of
+ -- hours of compile time.
+ r:RF := a1**2
+ r := r + 2 * a2 * differentiate a1
+ r := r - 2 * a1 * differentiate a2
+ r := r - 4 * a0 * a2
+ r := r / (4 * a2**2)
+ lf := factors squareFree denom r
+ case2(r, lf, ezfactor)
+
+ -- this is case 2 of Kovacic's algorithm, i.e. look for a solution
+ -- of the associated Riccati equation in a quadratic extension
+ -- lf is the squarefree factorisation of denom(r) and is used to
+ -- check the necessary condition
+ case2(r, lf, ezfactor) ==
+ cannotCase2? lf => "failed"
+ -- build the symmetric square of the operator L = y'' - r y
+ -- which is L2 = y''' - 4 r y' - 2 r' y
+ l2:LODO := monomial(1, 3) - monomial(4*r, 1) - 2 * differentiate(r)::LODO
+ -- no solution in this case if L2 has no rational solution
+ empty?(sol := ricDsolve(l2, ezfactor)) => "failed"
+ -- otherwise the defining polynomial for an algebraic solution
+ -- of the Ricatti equation associated with L is
+ -- u^2 - b u + (1/2 b' + 1/2 b^2 - r) = 0
+ -- where b is a rational solution of the Ricatti of L2
+ b := first sol
+ monomial(1, 2)$SUP - monomial(b, 1)$SUP
+ + ((differentiate(b) + b**2 - 2 * r) / (2::RF))::SUP
+
+ -- checks the necessary condition for case 2
+ -- returns true if case 2 cannot have solutions
+ -- the necessary condition is that there is either a factor with
+ -- exponent 2 or odd exponent > 2
+ cannotCase2? lf ==
+ for rec in lf repeat
+ rec.exponent = 2 or (odd?(rec.exponent) and rec.exponent > 2) =>
+ return false
+ true
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad
+-- kovacic.spad odeef.spad
+
+<<package KOVACIC Kovacic>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/laplace.spad.pamphlet b/src/algebra/laplace.spad.pamphlet
new file mode 100644
index 00000000..6f81b2ee
--- /dev/null
+++ b/src/algebra/laplace.spad.pamphlet
@@ -0,0 +1,337 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra laplace.spad}
+\author{Manuel Bronstein, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LAPLACE LaplaceTransform}
+<<package LAPLACE LaplaceTransform>>=
+)abbrev package LAPLACE LaplaceTransform
+++ Laplace transform
+++ Author: Manuel Bronstein
+++ Date Created: 30 May 1990
+++ Date Last Updated: 13 December 1995
+++ Description: This package computes the forward Laplace Transform.
+LaplaceTransform(R, F): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
+ AlgebraicallyClosedFunctionSpace R)
+
+ SE ==> Symbol
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ K ==> Kernel F
+ OFE ==> OrderedCompletion F
+ EQ ==> Equation OFE
+
+ ALGOP ==> "%alg"
+ SPECIALDIFF ==> "%specialDiff"
+
+ Exports ==> with
+ laplace: (F, SE, SE) -> F
+ ++ laplace(f, t, s) returns the Laplace transform of \spad{f(t)}
+ ++ using \spad{s} as the new variable.
+ ++ This is \spad{integral(exp(-s*t)*f(t), t = 0..%plusInfinity)}.
+ ++ Returns the formal object \spad{laplace(f, t, s)} if it cannot
+ ++ compute the transform.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import ElementaryIntegration(R, F)
+ import PatternMatchIntegration(R, F)
+ import PowerSeriesLimitPackage(R, F)
+ import FunctionSpaceIntegration(R, F)
+ import TrigonometricManipulations(R, F)
+
+ locallaplace : (F, SE, F, SE, F) -> F
+ lapkernel : (F, SE, F, F) -> Union(F, "failed")
+ intlaplace : (F, F, F, SE, F) -> Union(F, "failed")
+ isLinear : (F, SE) -> Union(Record(const:F, nconst:F), "failed")
+ mkPlus : F -> Union(List F, "failed")
+ dvlap : (List F, SE) -> F
+ tdenom : (F, F) -> Union(F, "failed")
+ atn : (F, SE) -> Union(Record(coef:F, deg:PI), "failed")
+ aexp : (F, SE) -> Union(Record(coef:F, coef1:F, coef0:F), "failed")
+ algebraic? : (F, SE) -> Boolean
+
+ oplap := operator("laplace"::Symbol, 3)$BasicOperator
+
+ laplace(f,t,s) == locallaplace(complexElementary(f,t),t,t::F,s,s::F)
+
+-- returns true if the highest kernel of f is algebraic over something
+ algebraic?(f, t) ==
+ l := varselect(kernels f, t)
+ m:N := reduce(max, [height k for k in l], 0)$List(N)
+ for k in l repeat
+ height k = m and has?(operator k, ALGOP) => return true
+ false
+
+-- differentiate a kernel of the form laplace(l.1,l.2,l.3) w.r.t x.
+-- note that x is not necessarily l.3
+-- if x = l.3, then there is no use recomputing the laplace transform,
+-- it will remain formal anyways
+ dvlap(l, x) ==
+ l1 := first l
+ l2 := second l
+ x = (v := retract(l3 := third l)@SE) => - oplap(l2 * l1, l2, l3)
+ e := exp(- l3 * l2)
+ locallaplace(differentiate(e * l1, x) / e, retract(l2)@SE, l2, v, l3)
+
+-- returns [b, c] iff f = c * t + b
+-- and b and c do not involve t
+ isLinear(f, t) ==
+ ff := univariate(f, kernel(t)@K)
+ ((d := retractIfCan(denom ff)@Union(F, "failed")) case "failed")
+ or (degree(numer ff) > 1) => "failed"
+ freeOf?(b := coefficient(numer ff, 0) / d, t) and
+ freeOf?(c := coefficient(numer ff, 1) / d, t) => [b, c]
+ "failed"
+
+-- returns [a, n] iff f = a * t**n
+ atn(f, t) ==
+ if ((v := isExpt f) case Record(var:K, exponent:Integer)) then
+ w := v::Record(var:K, exponent:Integer)
+ (w.exponent > 0) and
+ ((vv := symbolIfCan(w.var)) case SE) and (vv::SE = t) =>
+ return [1, w.exponent::PI]
+ (u := isTimes f) case List(F) =>
+ c:F := 1
+ d:N := 0
+ for g in u::List(F) repeat
+ if (rec := atn(g, t)) case Record(coef:F, deg:PI) then
+ r := rec::Record(coef:F, deg:PI)
+ c := c * r.coef
+ d := d + r.deg
+ else c := c * g
+ zero? d => "failed"
+ [c, d::PI]
+ "failed"
+
+-- returns [a, c, b] iff f = a * exp(c * t + b)
+-- and b and c do not involve t
+ aexp(f, t) ==
+ is?(f, "exp"::SE) =>
+ (v := isLinear(first argument(retract(f)@K),t)) case "failed" =>
+ "failed"
+ [1, v.nconst, v.const]
+ (u := isTimes f) case List(F) =>
+ c:F := 1
+ c1 := c0 := 0$F
+ for g in u::List(F) repeat
+ if (r := aexp(g,t)) case Record(coef:F,coef1:F,coef0:F) then
+ rec := r::Record(coef:F, coef1:F, coef0:F)
+ c := c * rec.coef
+ c0 := c0 + rec.coef0
+ c1 := c1 + rec.coef1
+ else c := c * g
+ zero? c0 and zero? c1 => "failed"
+ [c, c1, c0]
+ if (v := isPower f) case Record(val:F, exponent:Integer) then
+ w := v::Record(val:F, exponent:Integer)
+ (w.exponent ^= 1) and
+ ((r := aexp(w.val, t)) case Record(coef:F,coef1:F,coef0:F)) =>
+ rec := r::Record(coef:F, coef1:F, coef0:F)
+ return [rec.coef ** w.exponent, w.exponent * rec.coef1,
+ w.exponent * rec.coef0]
+ "failed"
+
+ mkPlus f ==
+ (u := isPlus numer f) case "failed" => "failed"
+ d := denom f
+ [p / d for p in u::List(SparseMultivariatePolynomial(R, K))]
+
+-- returns g if f = g/t
+ tdenom(f, t) ==
+ (denom f exquo numer t) case "failed" => "failed"
+ t * f
+
+ intlaplace(f, ss, g, v, vv) ==
+ is?(g, oplap) or ((i := integrate(g, v)) case List(F)) => "failed"
+ (u:=limit(i::F,equation(vv::OFE,plusInfinity()$OFE)$EQ)) case OFE =>
+ (l := limit(i::F, equation(vv::OFE, ss::OFE)$EQ)) case OFE =>
+ retractIfCan(u::OFE - l::OFE)@Union(F, "failed")
+ "failed"
+ "failed"
+
+ lapkernel(f, t, tt, ss) ==
+ (k := retractIfCan(f)@Union(K, "failed")) case "failed" => "failed"
+ empty?(arg := argument(k::K)) or not empty? rest arg => "failed"
+ member?(t, variables(a := first(arg) / tt)) => "failed"
+ is?(op := operator k, "Si"::SE) => atan(a / ss) / ss
+ is?(op, "Ci"::SE) => log((ss**2 + a**2) / a**2) / (2 * ss)
+ is?(op, "Ei"::SE) => log((ss + a) / a) / ss
+ "failed"
+
+ locallaplace(f, t, tt, s, ss) ==
+ zero? f => 0
+-- one? f => inv ss
+ (f = 1) => inv ss
+ (x := tdenom(f, tt)) case F =>
+ g := locallaplace(x::F, t, tt, vv := new()$SE, vvv := vv::F)
+ (x := intlaplace(f, ss, g, vv, vvv)) case F => x::F
+ oplap(f, tt, ss)
+ (u := mkPlus f) case List(F) =>
+ +/[locallaplace(g, t, tt, s, ss) for g in u::List(F)]
+ (rec := splitConstant(f, t)).const ^= 1 =>
+ rec.const * locallaplace(rec.nconst, t, tt, s, ss)
+ (v := atn(f, t)) case Record(coef:F, deg:PI) =>
+ vv := v::Record(coef:F, deg:PI)
+ is?(la := locallaplace(vv.coef, t, tt, s, ss), oplap) => oplap(f,tt,ss)
+ (-1$Integer)**(vv.deg) * differentiate(la, s, vv.deg)
+ (w := aexp(f, t)) case Record(coef:F, coef1:F, coef0:F) =>
+ ww := w::Record(coef:F, coef1:F, coef0:F)
+ exp(ww.coef0) * locallaplace(ww.coef,t,tt,s,ss - ww.coef1)
+ (x := lapkernel(f, t, tt, ss)) case F => x::F
+ -- last chance option: try to use the fact that
+ -- laplace(f(t),t,s) = s laplace(g(t),t,s) - g(0) where dg/dt = f(t)
+ elem?(int := lfintegrate(f, t)) and (rint := retractIfCan int) case F =>
+ fint := rint :: F
+ -- to avoid infinite loops, we don't call laplace recursively
+ -- if the integral has no new logs and f is an algebraic function
+ empty?(logpart int) and algebraic?(f, t) => oplap(fint, tt, ss)
+ ss * locallaplace(fint, t, tt, s, ss) - eval(fint, tt = 0)
+ oplap(f, tt, ss)
+
+ setProperty(oplap,SPECIALDIFF,dvlap@((List F,SE)->F) pretend None)
+
+@
+\section{package INVLAPLA InverseLaplaceTransform}
+<<package INVLAPLA InverseLaplaceTransform>>=
+)abbrev package INVLAPLA InverseLaplaceTransform
+++ Inverse Laplace transform
+++ Author: Barry Trager
+++ Date Created: 3 Sept 1991
+++ Date Last Updated: 3 Sept 1991
+++ Description: This package computes the inverse Laplace Transform.
+InverseLaplaceTransform(R, F): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
+ SpecialFunctionCategory, AlgebraicallyClosedFunctionSpace R)
+
+ SE ==> Symbol
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ K ==> Kernel F
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+
+ Exports ==> with
+ inverseLaplace: (F, SE, SE) -> Union(F,"failed")
+ ++ inverseLaplace(f, s, t) returns the Inverse
+ ++ Laplace transform of \spad{f(s)}
+ ++ using t as the new variable or "failed" if unable to find
+ ++ a closed form.
+
+ Implementation ==> add
+
+ -- local ops --
+ ilt : (F,Symbol,Symbol) -> Union(F,"failed")
+ ilt1 : (RF,F) -> F
+ iltsqfr : (RF,F) -> F
+ iltirred: (UP,UP,F) -> F
+ freeOf?: (UP,Symbol) -> Boolean
+
+ inverseLaplace(expr,ivar,ovar) == ilt(expr,ivar,ovar)
+
+ freeOf?(p:UP,v:Symbol) ==
+ "and"/[freeOf?(c,v) for c in coefficients p]
+
+ ilt(expr,var,t) ==
+ expr = 0 => 0
+ r := univariate(expr,kernel(var))
+ not(numer(r) quo denom(r) = 0) => "failed"
+ not( freeOf?(numer r,var) and freeOf?(denom r,var)) => "failed"
+ ilt1(r,t::F)
+
+ hintpac := TranscendentalHermiteIntegration(F, UP)
+
+ ilt1(r,t) ==
+ r = 0 => 0
+ rsplit := HermiteIntegrate(r, differentiate)$hintpac
+ -t*ilt1(rsplit.answer,t) + iltsqfr(rsplit.logpart,t)
+
+ iltsqfr(r,t) ==
+ r = 0 => 0
+ p:=numer r
+ q:=denom r
+ -- ql := [qq.factor for qq in factors factor q]
+ ql := [qq.factor for qq in factors squareFree q]
+ # ql = 1 => iltirred(p,q,t)
+ nl := multiEuclidean(ql,p)::List(UP)
+ +/[iltirred(a,b,t) for a in nl for b in ql]
+
+ -- q is irreducible, monic, degree p < degree q
+ iltirred(p,q,t) ==
+ degree q = 1 =>
+ cp := coefficient(p,0)
+ (c:=coefficient(q,0))=0 => cp
+ cp*exp(-c*t)
+ degree q = 2 =>
+ a := coefficient(p,1)
+ b := coefficient(p,0)
+ c:=(-1/2)*coefficient(q,1)
+ d:= coefficient(q,0)
+ e := exp(c*t)
+ b := b+a*c
+ d := d-c**2
+ d > 0 =>
+ alpha:F := sqrt d
+ e*(a*cos(t*alpha) + b*sin(t*alpha)/alpha)
+ alpha :F := sqrt(-d)
+ e*(a*cosh(t*alpha) + b*sinh(t*alpha)/alpha)
+ roots:List F := zerosOf q
+ q1 := differentiate q
+ +/[p(root)/q1(root)*exp(root*t) for root in roots]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package LAPLACE LaplaceTransform>>
+<<package INVLAPLA InverseLaplaceTransform>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/laurent.spad.pamphlet b/src/algebra/laurent.spad.pamphlet
new file mode 100644
index 00000000..ab0417c1
--- /dev/null
+++ b/src/algebra/laurent.spad.pamphlet
@@ -0,0 +1,678 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra laurent.spad}
+\author{Clifton J. Williamson, Bill Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ULSCCAT UnivariateLaurentSeriesConstructorCategory}
+<<category ULSCCAT UnivariateLaurentSeriesConstructorCategory>>=
+)abbrev category ULSCCAT UnivariateLaurentSeriesConstructorCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 6 February 1990
+++ Date Last Updated: 10 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Laurent, Taylor
+++ Examples:
+++ References:
+++ Description:
+++ This is a category of univariate Laurent series constructed from
+++ univariate Taylor series. A Laurent series is represented by a pair
+++ \spad{[n,f(x)]}, where n is an arbitrary integer and \spad{f(x)}
+++ is a Taylor series. This pair represents the Laurent series
+++ \spad{x**n * f(x)}.
+UnivariateLaurentSeriesConstructorCategory(Coef,UTS):_
+ Category == Definition where
+ Coef: Ring
+ UTS : UnivariateTaylorSeriesCategory Coef
+ I ==> Integer
+
+ Definition ==> Join(UnivariateLaurentSeriesCategory(Coef),_
+ RetractableTo UTS) with
+ laurent: (I,UTS) -> %
+ ++ \spad{laurent(n,f(x))} returns \spad{x**n * f(x)}.
+ degree: % -> I
+ ++ \spad{degree(f(x))} returns the degree of the lowest order term of
+ ++ \spad{f(x)}, which may have zero as a coefficient.
+ taylorRep: % -> UTS
+ ++ \spad{taylorRep(f(x))} returns \spad{g(x)}, where
+ ++ \spad{f = x**n * g(x)} is represented by \spad{[n,g(x)]}.
+ removeZeroes: % -> %
+ ++ \spad{removeZeroes(f(x))} removes leading zeroes from the
+ ++ representation of the Laurent series \spad{f(x)}.
+ ++ A Laurent series is represented by (1) an exponent and
+ ++ (2) a Taylor series which may have leading zero coefficients.
+ ++ When the Taylor series has a leading zero coefficient, the
+ ++ 'leading zero' is removed from the Laurent series as follows:
+ ++ the series is rewritten by increasing the exponent by 1 and
+ ++ dividing the Taylor series by its variable.
+ ++ Note: \spad{removeZeroes(f)} removes all leading zeroes from f
+ removeZeroes: (I,%) -> %
+ ++ \spad{removeZeroes(n,f(x))} removes up to n leading zeroes from
+ ++ the Laurent series \spad{f(x)}.
+ ++ A Laurent series is represented by (1) an exponent and
+ ++ (2) a Taylor series which may have leading zero coefficients.
+ ++ When the Taylor series has a leading zero coefficient, the
+ ++ 'leading zero' is removed from the Laurent series as follows:
+ ++ the series is rewritten by increasing the exponent by 1 and
+ ++ dividing the Taylor series by its variable.
+ coerce: UTS -> %
+ ++ \spad{coerce(f(x))} converts the Taylor series \spad{f(x)} to a
+ ++ Laurent series.
+ taylor: % -> UTS
+ ++ taylor(f(x)) converts the Laurent series f(x) to a Taylor series,
+ ++ if possible. Error: if this is not possible.
+ taylorIfCan: % -> Union(UTS,"failed")
+ ++ \spad{taylorIfCan(f(x))} converts the Laurent series \spad{f(x)}
+ ++ to a Taylor series, if possible. If this is not possible,
+ ++ "failed" is returned.
+ if Coef has Field then QuotientFieldCategory(UTS)
+ --++ the quotient field of univariate Taylor series over a field is
+ --++ the field of Laurent series
+
+ add
+
+ zero? x == zero? taylorRep x
+ retract(x:%):UTS == taylor x
+ retractIfCan(x:%):Union(UTS,"failed") == taylorIfCan x
+
+@
+\section{domain ULSCONS UnivariateLaurentSeriesConstructor}
+<<domain ULSCONS UnivariateLaurentSeriesConstructor>>=
+)abbrev domain ULSCONS UnivariateLaurentSeriesConstructor
+++ Authors: Bill Burge, Clifton J. Williamson
+++ Date Created: August 1988
+++ Date Last Updated: 17 June 1996
+++ Fix History:
+++ 14 June 1996: provided missing exquo: (%,%) -> % (Frederic Lehobey)
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Laurent, Taylor
+++ Examples:
+++ References:
+++ Description:
+++ This package enables one to construct a univariate Laurent series
+++ domain from a univariate Taylor series domain. Univariate
+++ Laurent series are represented by a pair \spad{[n,f(x)]}, where n is
+++ an arbitrary integer and \spad{f(x)} is a Taylor series. This pair
+++ represents the Laurent series \spad{x**n * f(x)}.
+UnivariateLaurentSeriesConstructor(Coef,UTS):_
+ Exports == Implementation where
+ Coef : Ring
+ UTS : UnivariateTaylorSeriesCategory Coef
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ P ==> Polynomial Coef
+ RF ==> Fraction Polynomial Coef
+ RN ==> Fraction Integer
+ ST ==> Stream Coef
+ TERM ==> Record(k:I,c:Coef)
+ monom ==> monomial$UTS
+ EFULS ==> ElementaryFunctionsUnivariateLaurentSeries(Coef,UTS,%)
+ STTAYLOR ==> StreamTaylorSeriesOperations Coef
+
+ Exports ==> UnivariateLaurentSeriesConstructorCategory(Coef,UTS)
+
+ Implementation ==> add
+
+--% representation
+
+ Rep := Record(expon:I,ps:UTS)
+
+ getExpon : % -> I
+ getUTS : % -> UTS
+
+ getExpon x == x.expon
+ getUTS x == x.ps
+
+--% creation and destruction
+
+ laurent(n,psr) == [n,psr]
+ taylorRep x == getUTS x
+ degree x == getExpon x
+
+ 0 == laurent(0,0)
+ 1 == laurent(0,1)
+
+ monomial(s,e) == laurent(e,s::UTS)
+
+ coerce(uts:UTS):% == laurent(0,uts)
+ coerce(r:Coef):% == r :: UTS :: %
+ coerce(i:I):% == i :: Coef :: %
+
+ taylorIfCan uls ==
+ n := getExpon uls
+ n < 0 =>
+ uls := removeZeroes(-n,uls)
+ getExpon(uls) < 0 => "failed"
+ getUTS uls
+ n = 0 => getUTS uls
+ getUTS(uls) * monom(1,n :: NNI)
+
+ taylor uls ==
+ (uts := taylorIfCan uls) case "failed" =>
+ error "taylor: Laurent series has a pole"
+ uts :: UTS
+
+ termExpon: TERM -> I
+ termExpon term == term.k
+ termCoef: TERM -> Coef
+ termCoef term == term.c
+ rec: (I,Coef) -> TERM
+ rec(exponent,coef) == [exponent,coef]
+
+ recs: (ST,I) -> Stream TERM
+ recs(st,n) == delay
+ empty? st => empty()
+ zero? (coef := frst st) => recs(rst st,n + 1)
+ concat(rec(n,coef),recs(rst st,n + 1))
+
+ terms x == recs(coefficients getUTS x,getExpon x)
+
+ recsToCoefs: (Stream TERM,I) -> ST
+ recsToCoefs(st,n) == delay
+ empty? st => empty()
+ term := frst st; ex := termExpon term
+ n = ex => concat(termCoef term,recsToCoefs(rst st,n + 1))
+ concat(0,recsToCoefs(rst st,n + 1))
+
+ series st ==
+ empty? st => 0
+ ex := termExpon frst st
+ laurent(ex,series recsToCoefs(st,ex))
+
+--% normalizations
+
+ removeZeroes x ==
+ empty? coefficients(xUTS := getUTS x) => 0
+ coefficient(xUTS,0) = 0 =>
+ removeZeroes laurent(getExpon(x) + 1,quoByVar xUTS)
+ x
+
+ removeZeroes(n,x) ==
+ n <= 0 => x
+ empty? coefficients(xUTS := getUTS x) => 0
+ coefficient(xUTS,0) = 0 =>
+ removeZeroes(n - 1,laurent(getExpon(x) + 1,quoByVar xUTS))
+ x
+
+--% predicates
+
+ x = y ==
+ EQ(x,y)$Lisp => true
+ (expDiff := getExpon(x) - getExpon(y)) = 0 =>
+ getUTS(x) = getUTS(y)
+ abs(expDiff) > _$streamCount$Lisp => false
+ expDiff > 0 =>
+ getUTS(x) * monom(1,expDiff :: NNI) = getUTS(y)
+ getUTS(y) * monom(1,(- expDiff) :: NNI) = getUTS(x)
+
+ pole? x ==
+ (n := degree x) >= 0 => false
+ x := removeZeroes(-n,x)
+ degree x < 0
+
+--% arithmetic
+
+ x + y ==
+ n := getExpon(x) - getExpon(y)
+ n >= 0 =>
+ laurent(getExpon y,getUTS(y) + getUTS(x) * monom(1,n::NNI))
+ laurent(getExpon x,getUTS(x) + getUTS(y) * monom(1,(-n)::NNI))
+
+ x - y ==
+ n := getExpon(x) - getExpon(y)
+ n >= 0 =>
+ laurent(getExpon y,getUTS(x) * monom(1,n::NNI) - getUTS(y))
+ laurent(getExpon x,getUTS(x) - getUTS(y) * monom(1,(-n)::NNI))
+
+ x:% * y:% == laurent(getExpon x + getExpon y,getUTS x * getUTS y)
+
+ x:% ** n:NNI ==
+ zero? n =>
+ zero? x => error "0 ** 0 is undefined"
+ 1
+ laurent(n * getExpon(x),getUTS(x) ** n)
+
+ recip x ==
+ x := removeZeroes(1000,x)
+ zero? coefficient(x,d := degree x) => "failed"
+ (uts := recip getUTS x) case "failed" => "failed"
+ laurent(-d,uts :: UTS)
+
+ elt(uls1:%,uls2:%) ==
+ (uts := taylorIfCan uls2) case "failed" =>
+ error "elt: second argument must have positive order"
+ uts2 := uts :: UTS
+ not zero? coefficient(uts2,0) =>
+ error "elt: second argument must have positive order"
+ if (deg := getExpon uls1) < 0 then uls1 := removeZeroes(-deg,uls1)
+ (deg := getExpon uls1) < 0 =>
+ (recipr := recip(uts2 :: %)) case "failed" =>
+ error "elt: second argument not invertible"
+ uts1 := taylor(uls1 * monomial(1,-deg))
+ (elt(uts1,uts2) :: %) * (recipr :: %) ** ((-deg) :: NNI)
+ elt(taylor uls1,uts2) :: %
+
+ eval(uls:%,r:Coef) ==
+ if (n := getExpon uls) < 0 then uls := removeZeroes(-n,uls)
+ uts := getUTS uls
+ (n := getExpon uls) < 0 =>
+ zero? r => error "eval: 0 raised to negative power"
+ (recipr := recip r) case "failed" =>
+ error "eval: non-unit raised to negative power"
+ (recipr :: Coef) ** ((-n) :: NNI) *$STTAYLOR eval(uts,r)
+ zero? n => eval(uts,r)
+ r ** (n :: NNI) *$STTAYLOR eval(uts,r)
+
+--% values
+
+ variable x == variable getUTS x
+ center x == center getUTS x
+
+ coefficient(x,n) ==
+ a := n - getExpon(x)
+ a >= 0 => coefficient(getUTS x,a :: NNI)
+ 0
+
+ elt(x:%,n:I) == coefficient(x,n)
+
+--% other functions
+
+ order x == getExpon x + order getUTS x
+ order(x,n) ==
+ (m := n - (e := getExpon x)) < 0 => n
+ e + order(getUTS x,m :: NNI)
+
+ truncate(x,n) ==
+ (m := n - (e := getExpon x)) < 0 => 0
+ laurent(e,truncate(getUTS x,m :: NNI))
+
+ truncate(x,n1,n2) ==
+ if n2 < n1 then (n1,n2) := (n2,n1)
+ (m1 := n1 - (e := getExpon x)) < 0 => truncate(x,n2)
+ laurent(e,truncate(getUTS x,m1 :: NNI,(n2 - e) :: NNI))
+
+ if Coef has IntegralDomain then
+ rationalFunction(x,n) ==
+ (m := n - (e := getExpon x)) < 0 => 0
+ poly := polynomial(getUTS x,m :: NNI) :: RF
+ zero? e => poly
+ v := variable(x) :: RF; c := center(x) :: P :: RF
+ positive? e => poly * (v - c) ** (e :: NNI)
+ poly / (v - c) ** ((-e) :: NNI)
+
+ rationalFunction(x,n1,n2) ==
+ if n2 < n1 then (n1,n2) := (n2,n1)
+ (m1 := n1 - (e := getExpon x)) < 0 => rationalFunction(x,n2)
+ poly := polynomial(getUTS x,m1 :: NNI,(n2 - e) :: NNI) :: RF
+ zero? e => poly
+ v := variable(x) :: RF; c := center(x) :: P :: RF
+ positive? e => poly * (v - c) ** (e :: NNI)
+ poly / (v - c) ** ((-e) :: NNI)
+
+ -- La fonction < exquo > manque dans laurent.spad,
+ --les lignes suivantes le mettent en evidence :
+ --
+ --ls := laurent(0,series [i for i in 1..])$ULS(INT,x,0)
+ ---- missing function in laurent.spad of Axiom 2.0a version of
+ ---- Friday March 10, 1995 at 04:15:22 on 615:
+ --exquo(ls,ls)
+ --
+ -- Je l'ai ajoutee a laurent.spad.
+ --
+ --Frederic Lehobey
+ x exquo y ==
+ x := removeZeroes(1000,x)
+ y := removeZeroes(1000,y)
+ zero? coefficient(y, d := degree y) => "failed"
+ (uts := (getUTS x) exquo (getUTS y)) case "failed" => "failed"
+ laurent(degree x-d,uts :: UTS)
+
+ if Coef has coerce: Symbol -> Coef then
+ if Coef has "**": (Coef,I) -> Coef then
+
+ approximate(x,n) ==
+ (m := n - (e := getExpon x)) < 0 => 0
+ app := approximate(getUTS x,m :: NNI)
+ zero? e => app
+ app * ((variable(x) :: Coef) - center(x)) ** e
+
+ complete x == laurent(getExpon x,complete getUTS x)
+ extend(x,n) ==
+ e := getExpon x
+ (m := n - e) < 0 => x
+ laurent(e,extend(getUTS x,m :: NNI))
+
+ map(f:Coef -> Coef,x:%) == laurent(getExpon x,map(f,getUTS x))
+
+ multiplyCoefficients(f,x) ==
+ e := getExpon x
+ laurent(e,multiplyCoefficients(f(e + #1),getUTS x))
+
+ multiplyExponents(x,n) ==
+ laurent(n * getExpon x,multiplyExponents(getUTS x,n))
+
+ differentiate x ==
+ e := getExpon x
+ laurent(e - 1,multiplyCoefficients((e + #1) :: Coef,getUTS x))
+
+ if Coef has PartialDifferentialRing(Symbol) then
+ differentiate(x:%,s:Symbol) ==
+ (s = variable(x)) => differentiate x
+ map(differentiate(#1,s),x) - differentiate(center x,s)*differentiate(x)
+
+ characteristic() == characteristic()$Coef
+
+ if Coef has Field then
+
+ retract(x:%):UTS == taylor x
+ retractIfCan(x:%):Union(UTS,"failed") == taylorIfCan x
+
+ (x:%) ** (n:I) ==
+ zero? n =>
+ zero? x => error "0 ** 0 is undefined"
+ 1
+ n > 0 => laurent(n * getExpon(x),getUTS(x) ** (n :: NNI))
+ xInv := inv x; minusN := (-n) :: NNI
+ laurent(minusN * getExpon(xInv),getUTS(xInv) ** minusN)
+
+ (x:UTS) * (y:%) == (x :: %) * y
+ (x:%) * (y:UTS) == x * (y :: %)
+
+ inv x ==
+ (xInv := recip x) case "failed" =>
+ error "multiplicative inverse does not exist"
+ xInv :: %
+
+ (x:%) / (y:%) ==
+ (yInv := recip y) case "failed" =>
+ error "inv: multiplicative inverse does not exist"
+ x * (yInv :: %)
+
+ (x:UTS) / (y:UTS) == (x :: %) / (y :: %)
+
+ numer x ==
+ (n := degree x) >= 0 => taylor x
+ x := removeZeroes(-n,x)
+ (n := degree x) = 0 => taylor x
+ getUTS x
+
+ denom x ==
+ (n := degree x) >= 0 => 1
+ x := removeZeroes(-n,x)
+ (n := degree x) = 0 => 1
+ monom(1,(-n) :: NNI)
+
+--% algebraic and transcendental functions
+
+ if Coef has Algebra Fraction Integer then
+
+ coerce(r:RN) == r :: Coef :: %
+
+ if Coef has Field then
+ (x:%) ** (r:RN) == x **$EFULS r
+
+ exp x == exp(x)$EFULS
+ log x == log(x)$EFULS
+ sin x == sin(x)$EFULS
+ cos x == cos(x)$EFULS
+ tan x == tan(x)$EFULS
+ cot x == cot(x)$EFULS
+ sec x == sec(x)$EFULS
+ csc x == csc(x)$EFULS
+ asin x == asin(x)$EFULS
+ acos x == acos(x)$EFULS
+ atan x == atan(x)$EFULS
+ acot x == acot(x)$EFULS
+ asec x == asec(x)$EFULS
+ acsc x == acsc(x)$EFULS
+ sinh x == sinh(x)$EFULS
+ cosh x == cosh(x)$EFULS
+ tanh x == tanh(x)$EFULS
+ coth x == coth(x)$EFULS
+ sech x == sech(x)$EFULS
+ csch x == csch(x)$EFULS
+ asinh x == asinh(x)$EFULS
+ acosh x == acosh(x)$EFULS
+ atanh x == atanh(x)$EFULS
+ acoth x == acoth(x)$EFULS
+ asech x == asech(x)$EFULS
+ acsch x == acsch(x)$EFULS
+
+ ratInv: I -> Coef
+ ratInv n ==
+ zero? n => 1
+ inv(n :: RN) :: Coef
+
+ integrate x ==
+ not zero? coefficient(x,-1) =>
+ error "integrate: series has term of order -1"
+ e := getExpon x
+ laurent(e + 1,multiplyCoefficients(ratInv(e + 1 + #1),getUTS x))
+
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+ integrate(x:%,s:Symbol) ==
+ (s = variable(x)) => integrate x
+ not entry?(s,variables center x) => map(integrate(#1,s),x)
+ error "integrate: center is a function of variable of integration"
+
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+
+ integrateWithOneAnswer: (Coef,Symbol) -> Coef
+ integrateWithOneAnswer(f,s) ==
+ res := integrate(f,s)$FunctionSpaceIntegration(I,Coef)
+ res case Coef => res :: Coef
+ first(res :: List Coef)
+
+ integrate(x:%,s:Symbol) ==
+ (s = variable(x)) => integrate x
+ not entry?(s,variables center x) =>
+ map(integrateWithOneAnswer(#1,s),x)
+ error "integrate: center is a function of variable of integration"
+
+ termOutput:(I,Coef,OUT) -> OUT
+ termOutput(k,c,vv) ==
+ -- creates a term c * vv ** k
+ k = 0 => c :: OUT
+ mon :=
+ k = 1 => vv
+ vv ** (k :: OUT)
+ c = 1 => mon
+ c = -1 => -mon
+ (c :: OUT) * mon
+
+ showAll?:() -> Boolean
+ -- check a global Lisp variable
+ showAll?() == true
+
+ termsToOutputForm:(I,ST,OUT) -> OUT
+ termsToOutputForm(m,uu,xxx) ==
+ l : L OUT := empty()
+ empty? uu => (0$Coef) :: OUT
+ n : NNI ; count : NNI := _$streamCount$Lisp
+ for n in 0..count while not empty? uu repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput((n :: I) + m,frst(uu),xxx),l)
+ uu := rst uu
+ if showAll?() then
+ for n in (count + 1).. while explicitEntries? uu and _
+ not eq?(uu,rst uu) repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput((n::I) + m,frst(uu),xxx),l)
+ uu := rst uu
+ l :=
+ explicitlyEmpty? uu => l
+ eq?(uu,rst uu) and frst uu = 0 => l
+ concat(prefix("O" :: OUT,[xxx ** ((n :: I) + m) :: OUT]),l)
+ empty? l => (0$Coef) :: OUT
+ reduce("+",reverse_! l)
+
+ coerce(x:%):OUT ==
+ x := removeZeroes(_$streamCount$Lisp,x)
+ m := degree x
+ uts := getUTS x
+ p := coefficients uts
+ var := variable uts; cen := center uts
+ xxx :=
+ zero? cen => var :: OUT
+ paren(var :: OUT - cen :: OUT)
+ termsToOutputForm(m,p,xxx)
+
+@
+\section{domain ULS UnivariateLaurentSeries}
+<<domain ULS UnivariateLaurentSeries>>=
+)abbrev domain ULS UnivariateLaurentSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 18 January 1990
+++ Date Last Updated: 21 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Laurent
+++ Examples:
+++ References:
+++ Description: Dense Laurent series in one variable
+++ \spadtype{UnivariateLaurentSeries} is a domain representing Laurent
+++ series in one variable with coefficients in an arbitrary ring. The
+++ parameters of the type specify the coefficient ring, the power series
+++ variable, and the center of the power series expansion. For example,
+++ \spad{UnivariateLaurentSeries(Integer,x,3)} represents Laurent series in
+++ \spad{(x - 3)} with integer coefficients.
+UnivariateLaurentSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ I ==> Integer
+ UTS ==> UnivariateTaylorSeries(Coef,var,cen)
+
+ Exports ==> UnivariateLaurentSeriesConstructorCategory(Coef,UTS) with
+ coerce: Variable(var) -> %
+ ++ \spad{coerce(var)} converts the series variable \spad{var} into a
+ ++ Laurent series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} returns the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> UnivariateLaurentSeriesConstructor(Coef,UTS) add
+
+ variable x == var
+ center x == cen
+
+ coerce(v:Variable(var)) ==
+ zero? cen => monomial(1,1)
+ monomial(1,1) + monomial(cen,0)
+
+ differentiate(x:%,v:Variable(var)) == differentiate x
+
+ if Coef has Algebra Fraction Integer then
+ integrate(x:%,v:Variable(var)) == integrate x
+
+@
+\section{package ULS2 UnivariateLaurentSeriesFunctions2}
+<<package ULS2 UnivariateLaurentSeriesFunctions2>>=
+)abbrev package ULS2 UnivariateLaurentSeriesFunctions2
+++ Author: Clifton J. Williamson
+++ Date Created: 5 March 1990
+++ Date Last Updated: 5 March 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Laurent series, map
+++ Examples:
+++ References:
+++ Description: Mapping package for univariate Laurent series
+++ This package allows one to apply a function to the coefficients of
+++ a univariate Laurent series.
+UnivariateLaurentSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
+ Exports == Implementation where
+ Coef1 : Ring
+ Coef2 : Ring
+ var1: Symbol
+ var2: Symbol
+ cen1: Coef1
+ cen2: Coef2
+ ULS1 ==> UnivariateLaurentSeries(Coef1, var1, cen1)
+ ULS2 ==> UnivariateLaurentSeries(Coef2, var2, cen2)
+ UTS1 ==> UnivariateTaylorSeries(Coef1, var1, cen1)
+ UTS2 ==> UnivariateTaylorSeries(Coef2, var2, cen2)
+ UTSF2 ==> UnivariateTaylorSeriesFunctions2(Coef1, Coef2, UTS1, UTS2)
+
+ Exports ==> with
+ map: (Coef1 -> Coef2,ULS1) -> ULS2
+ ++ \spad{map(f,g(x))} applies the map f to the coefficients of the Laurent
+ ++ series \spad{g(x)}.
+
+ Implementation ==> add
+
+ map(f,ups) == laurent(degree ups, map(f, taylorRep ups)$UTSF2)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category ULSCCAT UnivariateLaurentSeriesConstructorCategory>>
+<<domain ULSCONS UnivariateLaurentSeriesConstructor>>
+<<domain ULS UnivariateLaurentSeries>>
+<<package ULS2 UnivariateLaurentSeriesFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/leadcdet.spad.pamphlet b/src/algebra/leadcdet.spad.pamphlet
new file mode 100644
index 00000000..73635266
--- /dev/null
+++ b/src/algebra/leadcdet.spad.pamphlet
@@ -0,0 +1,167 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra leadcdet.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LEADCDET LeadingCoefDetermination}
+<<package LEADCDET LeadingCoefDetermination>>=
+)abbrev package LEADCDET LeadingCoefDetermination
+++ Author : P.Gianni, May 1990
+++ Description:
+++ Package for leading coefficient determination in the lifting step.
+++ Package working for every R euclidean with property "F".
+LeadingCoefDetermination(OV,E,Z,P) : C == T
+ where
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ Z : EuclideanDomain
+ BP ==> SparseUnivariatePolynomial Z
+ P : PolynomialCategory(Z,E,OV)
+ NNI ==> NonNegativeInteger
+ LeadFact ==> Record(polfac:List(P),correct:Z,corrfact:List(BP))
+ ParFact ==> Record(irr:P,pow:Integer)
+ FinalFact ==> Record(contp:Z,factors:List(ParFact))
+
+ C == with
+ polCase : (Z,NNI,List(Z)) -> Boolean
+ ++ polCase(contprod, numFacts, evallcs), where contprod is the
+ ++ product of the content of the leading coefficient of
+ ++ the polynomial to be factored with the content of the
+ ++ evaluated polynomial, numFacts is the number of factors
+ ++ of the leadingCoefficient, and evallcs is the list of
+ ++ the evaluated factors of the leadingCoefficient, returns
+ ++ true if the factors of the leading Coefficient can be
+ ++ distributed with this valuation.
+ distFact : (Z,List(BP),FinalFact,List(Z),List(OV),List(Z)) ->
+ Union(LeadFact,"failed")
+ ++ distFact(contm,unilist,plead,vl,lvar,lval), where contm is
+ ++ the content of the evaluated polynomial, unilist is the list
+ ++ of factors of the evaluated polynomial, plead is the complete
+ ++ factorization of the leading coefficient, vl is the list
+ ++ of factors of the leading coefficient evaluated, lvar is the
+ ++ list of variables, lval is the list of values, returns a record
+ ++ giving the list of leading coefficients to impose on the univariate
+ ++ factors,
+
+ T == add
+ distribute: (Z,List(BP),List(P),List(Z),List(OV),List(Z)) -> LeadFact
+ checkpow : (Z,Z) -> NNI
+
+ polCase(d:Z,nk:NNI,lval:List(Z)):Boolean ==
+ -- d is the product of the content lc m (case polynomial)
+ -- and the cont of the polynomial evaluated
+ q:Z
+ distlist:List(Z) := [d]
+ for i in 1..nk repeat
+ q := unitNormal(lval.i).canonical
+ for j in 0..(i-1)::NNI repeat
+ y := distlist.((i-j)::NNI)
+ while y^=1 repeat
+ y := gcd(y,q)
+ q := q quo y
+ if q=1 then return false
+ distlist := append(distlist,[q])
+ true
+
+ checkpow(a:Z,b:Z) : NonNegativeInteger ==
+ qt: Union(Z,"failed")
+ for i in 0.. repeat
+ qt:= b exquo a
+ if qt case "failed" then return i
+ b:=qt::Z
+
+ distribute(contm:Z,unilist:List(BP),pl:List(P),vl:List(Z),
+ lvar:List(OV),lval:List(Z)): LeadFact ==
+ d,lcp : Z
+ nf:NNI:=#unilist
+ for i in 1..nf repeat
+ lcp := leadingCoefficient (unilist.i)
+ d:= gcd(lcp,vl.i)
+ pl.i := (lcp quo d)*pl.i
+ d := vl.i quo d
+ unilist.i := d*unilist.i
+ contm := contm quo d
+ if contm ^=1 then for i in 1..nf repeat pl.i := contm*pl.i
+ [pl,contm,unilist]$LeadFact
+
+ distFact(contm:Z,unilist:List(BP),plead:FinalFact,
+ vl:List(Z),lvar:List(OV),lval:List(Z)):Union(LeadFact,"failed") ==
+ h:NonNegativeInteger
+ c,d : Z
+ lpol:List(P):=[]
+ lexp:List(Integer):=[]
+ nf:NNI := #unilist
+ vl := reverse vl --lpol and vl reversed so test from right to left
+ for fpl in plead.factors repeat
+ lpol:=[fpl.irr,:lpol]
+ lexp:=[fpl.pow,:lexp]
+ vlp:List(Z):= [1$Z for i in 1..nf]
+ aux : List(P) := [1$P for i in 1..nf]
+ for i in 1..nf repeat
+ c := contm*leadingCoefficient unilist.i
+ c=1 or c=-1 => "next i"
+ for k in 1..(# lpol) repeat
+ lexp.k=0 => "next factor"
+ h:= checkpow(vl.k,c)
+ if h ^=0 then
+ if h>lexp.k then return "failed"
+ lexp.k:=lexp.k-h
+ aux.i := aux.i*(lpol.k ** h)
+ d:= vl.k**h
+ vlp.i:= vlp.i*d
+ c:= c quo d
+ if contm=1 then vlp.i:=c
+ for k in 1..(# lpol) repeat if lexp.k ^= 0 then return "failed"
+ contm =1 => [[vlp.i*aux.i for i in 1..nf],1,unilist]$LeadFact
+ distribute(contm,unilist,aux,vlp,lvar,lval)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package LEADCDET LeadingCoefDetermination>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/libdb.text b/src/algebra/libdb.text
new file mode 100644
index 00000000..e7836135
--- /dev/null
+++ b/src/algebra/libdb.text
@@ -0,0 +1,78 @@
+acanonicalUnitNormal`0`x``cIntegerNumberSystem``
+acanonical`0`x``dSingleInteger``\spad{canonical} means that mathematical equality is implied by data structure equality.
+acanonicalsClosed`0`x``dSingleInteger``\spad{canonicalClosed} means two positives multiply to give positive.
+amultiplicativeValuation`0`x``cIntegerNumberSystem``euclideanSize(a*b) returns \spad{euclideanSize(a)*euclideanSize(b)}.
+anoetherian`0`x``dSingleInteger``\spad{noetherian} all ideals are finitely generated (in fact principal).
+cIntegerNumberSystem`0`x`()->Category``INS`An \spad{IntegerNumberSystem} is a model for the integers.
+dPlaneAlgebraicCurvePlot`0`x`()->Join(PlottablePlaneCurveCategory,etc)``ACPLOT`\indented{1}{Plot a NON-SINGULAR plane algebraic curve \spad{p}(\spad{x},{}\spad{y}) = 0.} Author: Clifton \spad{J}. Williamson Date Created: Fall 1988 Date Last Updated: 27 April 1990 Keywords: algebraic curve,{} non-singular,{} plot Examples: References:
+dSingleInteger`0`x`()->Join(IntegerNumberSystem,etc)``SINT`SingleInteger is intended to support machine integer arithmetic.
+o/\`2`x`(_$,_$)->_$`dSingleInteger``\spad{n} \spad{/\} \spad{m} returns the bit-by-bit logical {\em and} of the single integers \spad{n} and \spad{m}.
+oAnd`2`x`(_$,_$)->_$`dSingleInteger``\spad{And(n,{}m)} returns the bit-by-bit logical {\em and} of the single integers \spad{n} and \spad{m}.
+oNot`1`x`(_$)->_$`dSingleInteger``\spad{Not(n)} returns the bit-by-bit logical {\em not} of the single integer \spad{n}.
+oOr`2`x`(_$,_$)->_$`dSingleInteger``\spad{Or(n,{}m)} returns the bit-by-bit logical {\em or} of the single integers \spad{n} and \spad{m}.
+o\/`2`x`(_$,_$)->_$`dSingleInteger``\spad{n} \spad{\/} \spad{m} returns the bit-by-bit logical {\em or} of the single integers \spad{n} and \spad{m}.
+oaddmod`3`x`(_$,_$,_$)->_$`cIntegerNumberSystem``\spad{addmod(a,{}b,{}p)},{} \spad{0<=a,{}b<p>1},{} means \spad{a+b mod p}.
+obase`0`x`()->_$`cIntegerNumberSystem``\spad{base()} returns the base for the operations of \spad{IntegerNumberSystem}.
+obinomial`2`x`(S,S)->S`xIntegerNumberSystem&(S)``
+obit?`2`x`(S,S)->Boolean`xIntegerNumberSystem&(S)``
+obit?`2`x`(_$,_$)->Boolean`cIntegerNumberSystem``\spad{bit?(n,{}i)} returns \spad{true} if and only if \spad{i}-th bit of \spad{n} is a 1.
+ocharacteristic`0`x`()->NonNegativeInteger`xIntegerNumberSystem&(S)``
+oconvert`1`x`(S)->DoubleFloat`xIntegerNumberSystem&(S)``
+oconvert`1`x`(S)->Float`xIntegerNumberSystem&(S)``
+oconvert`1`x`(S)->InputForm`xIntegerNumberSystem&(S)``
+oconvert`1`x`(S)->Integer`xIntegerNumberSystem&(S)``
+oconvert`1`x`(S)->Pattern(Integer)`xIntegerNumberSystem&(S)``
+ocopy`1`x`(S)->S`xIntegerNumberSystem&(S)``
+ocopy`1`x`(_$)->_$`cIntegerNumberSystem``\spad{copy(n)} gives a copy of \spad{n}.
+odec`1`x`(_$)->_$`cIntegerNumberSystem``\spad{dec(x)} returns \spad{x - 1}.
+odifferentiate`1`x`(S)->S`xIntegerNumberSystem&(S)``
+odifferentiate`2`x`(S,NonNegativeInteger)->S`xIntegerNumberSystem&(S)``
+oeuclideanSize`1`x`(S)->NonNegativeInteger`xIntegerNumberSystem&(S)``
+oeven?`1`x`(S)->Boolean`xIntegerNumberSystem&(S)``
+oeven?`1`x`(_$)->Boolean`cIntegerNumberSystem``\spad{even?(n)} returns \spad{true} if and only if \spad{n} is even.
+ofactor`1`x`(S)->Factored(S)`xIntegerNumberSystem&(S)``
+ofactorial`1`x`(S)->S`xIntegerNumberSystem&(S)``
+ohash`1`x`(_$)->_$`cIntegerNumberSystem``\spad{hash(n)} returns the hash code of \spad{n}.
+oinc`1`x`(_$)->_$`cIntegerNumberSystem``\spad{inc(x)} returns \spad{x + 1}.
+oinit`0`x`()->S`xIntegerNumberSystem&(S)``
+oinvmod`2`x`(S,S)->S`xIntegerNumberSystem&(S)``
+oinvmod`2`x`(_$,_$)->_$`cIntegerNumberSystem``\spad{invmod(a,{}b)},{} \spad{0<=a<b>1},{} \spad{(a,{}b)=1} means \spad{1/a mod b}.
+olength`1`x`(_$)->_$`cIntegerNumberSystem``\spad{length(a)} length of \spad{a} in digits.
+omakeSketch`5`x`(Polynomial(Integer),Symbol,Symbol,Segment(Fraction(Integer)),Segment(Fraction(Integer)))->_$`dPlaneAlgebraicCurvePlot``\spad{makeSketch(p,{}x,{}y,{}a..b,{}c..d)} creates an ACPLOT of the curve \spad{p = 0} in the region {\em a <= x <= b,{} c <= y <= d}. More specifically,{} 'makeSketch' plots a non-singular algebraic curve \spad{p = 0} in an rectangular region {\em xMin <= x <= xMax},{} {\em yMin <= y <= yMax}. The user inputs \spad{makeSketch(p,{}x,{}y,{}xMin..xMax,{}yMin..yMax----)}. Here \spad{p} is a polynomial in the variables \spad{x} and \spad{y} with integer coefficients (\spad{p} belongs to the domain \spad{Polynomial Integer}). The case where \spad{p} is a polynomial in only one of the variables is allowed. The variables \spad{x} and \spad{y} are input to specify the the coordinate axes. The horizontal axis is the \spad{x}-axis and the vertical axis is the \spad{y}-axis. The rational numbers xMin,{}...,{}yMax specify the boundaries of the region in which the --cu--rve is to be plotted.
+omask`1`x`(S)->S`xIntegerNumberSystem&(S)``
+omask`1`x`(_$)->_$`cIntegerNumberSystem``\spad{mask(n)} returns \spad{2**n-1} (an \spad{n} bit mask).
+omax`0`x`()->_$`dSingleInteger``\spad{max()} returns the largest single integer.
+omin`0`x`()->_$`dSingleInteger``\spad{min()} returns the smallest single integer.
+omulmod`3`x`(_$,_$,_$)->_$`cIntegerNumberSystem``\spad{mulmod(a,{}b,{}p)},{} \spad{0<=a,{}b<p>1},{} means \spad{a*b mod p}.
+onextItem`1`x`(S)->Union(S,"failed")`xIntegerNumberSystem&(S)``
+oodd?`1`x`(_$)->Boolean`cIntegerNumberSystem``\spad{odd?(n)} returns \spad{true} if and only if \spad{n} is odd.
+opatternMatch`3`x`(S,Pattern(Integer),PatternMatchResult(Integer,S))->PatternMatchResult(Integer,S)`xIntegerNumberSystem&(S)``
+opermutation`2`x`(S,S)->S`xIntegerNumberSystem&(S)``
+opositive?`1`x`(S)->Boolean`xIntegerNumberSystem&(S)``
+opositiveRemainder`2`x`(_$,_$)->_$`cIntegerNumberSystem``\spad{positiveRemainder(a,{}b)} (where \spad{b > 1}) yields \spad{r} where \spad{0 <= r < b} and \spad{r == a rem b}.
+opowmod`3`x`(S,S,S)->S`xIntegerNumberSystem&(S)``
+opowmod`3`x`(_$,_$,_$)->_$`cIntegerNumberSystem``\spad{powmod(a,{}b,{}p)},{} \spad{0<=a,{}b<p>1},{} means \spad{a**b mod p}.
+oprime?`1`x`(S)->Boolean`xIntegerNumberSystem&(S)``
+orandom`0`x`()->_$`cIntegerNumberSystem``\spad{random()} creates a random element.
+orandom`1`x`(_$)->_$`cIntegerNumberSystem``\spad{random(a)} creates a random element from 0 to \spad{n-1}.
+orational?`1`x`(S)->Boolean`xIntegerNumberSystem&(S)``
+orational?`1`x`(_$)->Boolean`cIntegerNumberSystem``\spad{rational?(n)} tests if \spad{n} is a rational number (see \spadtype{Fraction Integer}).
+orationalIfCan`1`x`(S)->Union(Fraction(Integer),"failed")`xIntegerNumberSystem&(S)``
+orationalIfCan`1`x`(_$)->Union(Fraction(Integer),"failed")`cIntegerNumberSystem``\spad{rationalIfCan(n)} creates a rational number,{} or returns "failed" if this is not possible.
+orational`1`x`(S)->Fraction(Integer)`xIntegerNumberSystem&(S)``
+orational`1`x`(_$)->Fraction(Integer)`cIntegerNumberSystem``\spad{rational(n)} creates a rational number (see \spadtype{Fraction Integer})..
+orealSolve`3`x`(List(Polynomial(Integer)),List(Symbol),Float)->List(List(Float))`pRealSolvePackage``\spad{realSolve(lp,{}lv,{}eps)} = compute the list of the real solutions of the list \spad{lp} of polynomials with integer coefficients with respect to the variables in \spad{lv},{} with precision \spad{eps}.
+orefine`2`x`(_$,DoubleFloat)->_$`dPlaneAlgebraicCurvePlot``\spad{refine(p,{}x)} \undocumented{}
+oretractIfCan`1`x`(S)->Union(Integer,"failed")`xIntegerNumberSystem&(S)``
+oretract`1`x`(S)->Integer`xIntegerNumberSystem&(S)``
+oshift`2`x`(_$,_$)->_$`cIntegerNumberSystem``\spad{shift(a,{}i)} shift \spad{a} by \spad{i} digits.
+osolve`2`x`(Polynomial(Fraction(Integer)),Float)->List(Float)`pRealSolvePackage``\spad{solve(p,{}eps)} finds the real zeroes of a univariate rational polynomial \spad{p} with precision \spad{eps}.
+osolve`2`x`(Polynomial(Integer),Float)->List(Float)`pRealSolvePackage``\spad{solve(p,{}eps)} finds the real zeroes of a univariate integer polynomial \spad{p} with precision \spad{eps}.
+osquareFree`1`x`(S)->Factored(S)`xIntegerNumberSystem&(S)``
+osubmod`3`x`(_$,_$,_$)->_$`cIntegerNumberSystem``\spad{submod(a,{}b,{}p)},{} \spad{0<=a,{}b<p>1},{} means \spad{a-b mod p}.
+osymmetricRemainder`2`x`(S,S)->S`xIntegerNumberSystem&(S)``
+osymmetricRemainder`2`x`(_$,_$)->_$`cIntegerNumberSystem``\spad{symmetricRemainder(a,{}b)} (where \spad{b > 1}) yields \spad{r} where \spad{ -b/2 <= r < b/2 }.
+oxor`2`x`(_$,_$)->_$`dSingleInteger``\spad{xor(n,{}m)} returns the bit-by-bit logical {\em xor} of the single integers \spad{n} and \spad{m}.
+o~`1`x`(_$)->_$`dSingleInteger``\spad{~ n} returns the bit-by-bit logical {\em not } of the single integer \spad{n}.
+pRealSolvePackage`0`x`()->etc``REALSOLV`\indented{1}{This package provides numerical solutions of systems of polynomial} equations for use in ACPLOT.
+xIntegerNumberSystem&`1`x`(IntegerNumberSystem)->etc`(S)`INS-`An \spad{IntegerNumberSystem} is a model for the integers.
diff --git a/src/algebra/lie.spad.pamphlet b/src/algebra/lie.spad.pamphlet
new file mode 100644
index 00000000..c5822d71
--- /dev/null
+++ b/src/algebra/lie.spad.pamphlet
@@ -0,0 +1,259 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lie.spad}
+\author{Johannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain LIE AssociatedLieAlgebra}
+<<domain LIE AssociatedLieAlgebra>>=
+)abbrev domain LIE AssociatedLieAlgebra
+++ Author: J. Grabmeier
+++ Date Created: 07 March 1991
+++ Date Last Updated: 14 June 1991
+++ Basic Operations: *,**,+,-
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: associated Liealgebra
+++ References:
+++ Description:
+++ AssociatedLieAlgebra takes an algebra \spad{A}
+++ and uses \spadfun{*$A} to define the
+++ Lie bracket \spad{a*b := (a *$A b - b *$A a)} (commutator). Note that
+++ the notation \spad{[a,b]} cannot be used due to
+++ restrictions of the current compiler.
+++ This domain only gives a Lie algebra if the
+++ Jacobi-identity \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0} holds
+++ for all \spad{a},\spad{b},\spad{c} in \spad{A}.
+++ This relation can be checked by
+++ \spad{lieAdmissible?()$A}.
+++
+++ If the underlying algebra is of type
+++ \spadtype{FramedNonAssociativeAlgebra(R)} (i.e. a non
+++ associative algebra over R which is a free \spad{R}-module of finite
+++ rank, together with a fixed \spad{R}-module basis), then the same
+++ is true for the associated Lie algebra.
+++ Also, if the underlying algebra is of type
+++ \spadtype{FiniteRankNonAssociativeAlgebra(R)} (i.e. a non
+++ associative algebra over R which is a free R-module of finite
+++ rank), then the same is true for the associated Lie algebra.
+
+AssociatedLieAlgebra(R:CommutativeRing,A:NonAssociativeAlgebra R):
+ public == private where
+ public ==> Join (NonAssociativeAlgebra R, CoercibleTo A) with
+ coerce : A -> %
+ ++ coerce(a) coerces the element \spad{a} of the algebra \spad{A}
+ ++ to an element of the Lie
+ ++ algebra \spadtype{AssociatedLieAlgebra}(R,A).
+ if A has FramedNonAssociativeAlgebra(R) then
+ FramedNonAssociativeAlgebra(R)
+ if A has FiniteRankNonAssociativeAlgebra(R) then
+ FiniteRankNonAssociativeAlgebra(R)
+
+ private ==> A add
+ Rep := A
+ (a:%) * (b:%) == (a::Rep) * $Rep (b::Rep) -$Rep (b::Rep) * $Rep (a::Rep)
+ coerce(a:%):A == a :: Rep
+ coerce(a:A):% == a :: %
+ (a:%) ** (n:PositiveInteger) ==
+ n = 1 => a
+ 0
+
+@
+\section{domain JORDAN AssociatedJordanAlgebra}
+<<domain JORDAN AssociatedJordanAlgebra>>=
+)abbrev domain JORDAN AssociatedJordanAlgebra
+++ Author: J. Grabmeier
+++ Date Created: 14 June 1991
+++ Date Last Updated: 14 June 1991
+++ Basic Operations: *,**,+,-
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: associated Jordan algebra
+++ References:
+++ Description:
+++ AssociatedJordanAlgebra takes an algebra \spad{A} and uses \spadfun{*$A}
+++ to define the new multiplications \spad{a*b := (a *$A b + b *$A a)/2}
+++ (anticommutator).
+++ The usual notation \spad{{a,b}_+} cannot be used due to
+++ restrictions in the current language.
+++ This domain only gives a Jordan algebra if the
+++ Jordan-identity \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0} holds
+++ for all \spad{a},\spad{b},\spad{c} in \spad{A}.
+++ This relation can be checked by
+++ \spadfun{jordanAdmissible?()$A}.
+++
+++ If the underlying algebra is of type
+++ \spadtype{FramedNonAssociativeAlgebra(R)} (i.e. a non
+++ associative algebra over R which is a free R-module of finite
+++ rank, together with a fixed R-module basis), then the same
+++ is true for the associated Jordan algebra.
+++ Moreover, if the underlying algebra is of type
+++ \spadtype{FiniteRankNonAssociativeAlgebra(R)} (i.e. a non
+++ associative algebra over R which is a free R-module of finite
+++ rank), then the same true for the associated Jordan algebra.
+
+AssociatedJordanAlgebra(R:CommutativeRing,A:NonAssociativeAlgebra R):
+ public == private where
+ public ==> Join (NonAssociativeAlgebra R, CoercibleTo A) with
+ coerce : A -> %
+ ++ coerce(a) coerces the element \spad{a} of the algebra \spad{A}
+ ++ to an element of the Jordan algebra
+ ++ \spadtype{AssociatedJordanAlgebra}(R,A).
+ if A has FramedNonAssociativeAlgebra(R) then _
+ FramedNonAssociativeAlgebra(R)
+ if A has FiniteRankNonAssociativeAlgebra(R) then _
+ FiniteRankNonAssociativeAlgebra(R)
+
+ private ==> A add
+ Rep := A
+ two : R := (1$R + 1$R)
+ oneHalf : R := (recip two) :: R
+ (a:%) * (b:%) ==
+ zero? two => error
+ "constructor must no be called with Ring of characteristic 2"
+ ((a::Rep) * $Rep (b::Rep) +$Rep (b::Rep) * $Rep (a::Rep)) * oneHalf
+ -- (a::Rep) * $Rep (b::Rep) +$Rep (b::Rep) * $Rep (a::Rep)
+ coerce(a:%):A == a :: Rep
+ coerce(a:A):% == a :: %
+ (a:%) ** (n:PositiveInteger) == a
+
+@
+\section{domain LSQM LieSquareMatrix}
+<<domain LSQM LieSquareMatrix>>=
+)abbrev domain LSQM LieSquareMatrix
+++ Author: J. Grabmeier
+++ Date Created: 07 March 1991
+++ Date Last Updated: 08 March 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ LieSquareMatrix(n,R) implements the Lie algebra of the n by n
+++ matrices over the commutative ring R.
+++ The Lie bracket (commutator) of the algebra is given by
+++ \spad{a*b := (a *$SQMATRIX(n,R) b - b *$SQMATRIX(n,R) a)},
+++ where \spadfun{*$SQMATRIX(n,R)} is the usual matrix multiplication.
+LieSquareMatrix(n,R): Exports == Implementation where
+
+ n : PositiveInteger
+ R : CommutativeRing
+
+ Row ==> DirectProduct(n,R)
+ Col ==> DirectProduct(n,R)
+
+ Exports ==> Join(SquareMatrixCategory(n,R,Row,Col), CoercibleTo Matrix R,_
+ FramedNonAssociativeAlgebra R) --with
+
+ Implementation ==> AssociatedLieAlgebra (R,SquareMatrix(n, R)) add
+
+ Rep := AssociatedLieAlgebra (R,SquareMatrix(n, R))
+ -- local functions
+ n2 : PositiveInteger := n*n
+
+ convDM : DirectProduct(n2,R) -> %
+ conv : DirectProduct(n2,R) -> SquareMatrix(n,R)
+ --++ converts n2-vector to (n,n)-matrix row by row
+ conv v ==
+ cond : Matrix(R) := new(n,n,0$R)$Matrix(R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ z := z+1
+ setelt(cond,i,j,v.z)
+ squareMatrix(cond)$SquareMatrix(n, R)
+
+
+ coordinates(a:%,b:Vector(%)):Vector(R) ==
+ -- only valid for b canonicalBasis
+ res : Vector R := new(n2,0$R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ z := z+1
+ res.z := elt(a,i,j)$%
+ res
+
+
+ convDM v ==
+ sq := conv v
+ coerce(sq)$Rep :: %
+
+ basis() ==
+ n2 : PositiveInteger := n*n
+ ldp : List DirectProduct(n2,R) :=
+ [unitVector(i::PositiveInteger)$DirectProduct(n2,R) for i in 1..n2]
+ res:Vector % := vector map(convDM,_
+ ldp)$ListFunctions2(DirectProduct(n2,R), %)
+
+ someBasis() == basis()
+ rank() == n*n
+
+
+-- transpose: % -> %
+-- ++ computes the transpose of a matrix
+-- squareMatrix: Matrix R -> %
+-- ++ converts a Matrix to a LieSquareMatrix
+-- coerce: % -> Matrix R
+-- ++ converts a LieSquareMatrix to a Matrix
+-- symdecomp : % -> Record(sym:%,antisym:%)
+-- if R has commutative("*") then
+-- minorsVect: -> Vector(Union(R,"uncomputed")) --range: 1..2**n-1
+-- if R has commutative("*") then central
+-- if R has commutative("*") and R has unitsKnown then unitsKnown
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain LIE AssociatedLieAlgebra>>
+<<domain JORDAN AssociatedJordanAlgebra>>
+<<domain LSQM LieSquareMatrix>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/limitps.spad.pamphlet b/src/algebra/limitps.spad.pamphlet
new file mode 100644
index 00000000..a388417e
--- /dev/null
+++ b/src/algebra/limitps.spad.pamphlet
@@ -0,0 +1,768 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra limitps.spad}
+\author{Clifton J. Williamson, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LIMITPS PowerSeriesLimitPackage}
+<<package LIMITPS PowerSeriesLimitPackage>>=
+)abbrev package LIMITPS PowerSeriesLimitPackage
+++ Author: Clifton J. Williamson
+++ Date Created: 21 March 1989
+++ Date Last Updated: 30 March 1994
+++ Basic Operations:
+++ Related Domains: UnivariateLaurentSeries(FE,x,a),
+++ UnivariatePuiseuxSeries(FE,x,a),ExponentialExpansion(R,FE,x,a)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: limit, functional expression, power series
+++ Examples:
+++ References:
+++ Description:
+++ PowerSeriesLimitPackage implements limits of expressions
+++ in one or more variables as one of the variables approaches a
+++ limiting value. Included are two-sided limits, left- and right-
+++ hand limits, and limits at plus or minus infinity.
+PowerSeriesLimitPackage(R,FE): Exports == Implementation where
+ R : Join(GcdDomain,OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer)
+ FE : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+ Z ==> Integer
+ RN ==> Fraction Integer
+ RF ==> Fraction Polynomial R
+ OFE ==> OrderedCompletion FE
+ OPF ==> OnePointCompletion FE
+ SY ==> Symbol
+ EQ ==> Equation
+ LF ==> LiouvillianFunction
+ UTS ==> UnivariateTaylorSeries
+ ULS ==> UnivariateLaurentSeries
+ UPXS ==> UnivariatePuiseuxSeries
+ EFULS ==> ElementaryFunctionsUnivariateLaurentSeries
+ EFUPXS ==> ElementaryFunctionsUnivariatePuiseuxSeries
+ FS2UPS ==> FunctionSpaceToUnivariatePowerSeries
+ FS2EXPXP ==> FunctionSpaceToExponentialExpansion
+ Problem ==> Record(func:String,prob:String)
+ RESULT ==> Union(OFE,"failed")
+ TwoSide ==> Record(leftHandLimit:RESULT,rightHandLimit:RESULT)
+ U ==> Union(OFE,TwoSide,"failed")
+ SIGNEF ==> ElementaryFunctionSign(R,FE)
+
+ Exports ==> with
+
+ limit: (FE,EQ OFE) -> U
+ ++ limit(f(x),x = a) computes the real limit \spad{lim(x -> a,f(x))}.
+
+ complexLimit: (FE,EQ OPF) -> Union(OPF, "failed")
+ ++ complexLimit(f(x),x = a) computes the complex limit
+ ++ \spad{lim(x -> a,f(x))}.
+
+ limit: (FE,EQ FE,String) -> RESULT
+ ++ limit(f(x),x=a,"left") computes the left hand real limit
+ ++ \spad{lim(x -> a-,f(x))};
+ ++ \spad{limit(f(x),x=a,"right")} computes the right hand real limit
+ ++ \spad{lim(x -> a+,f(x))}.
+
+ Implementation ==> add
+ import ToolsForSign(R)
+ import ElementaryFunctionStructurePackage(R,FE)
+
+ zeroFE:FE := 0
+ anyRootsOrAtrigs? : FE -> Boolean
+ complLimit : (FE,SY) -> Union(OPF,"failed")
+ okProblem? : (String,String) -> Boolean
+ realLimit : (FE,SY) -> U
+ xxpLimit : (FE,SY) -> RESULT
+ limitPlus : (FE,SY) -> RESULT
+ localsubst : (FE,Kernel FE,Z,FE) -> FE
+ locallimit : (FE,SY,OFE) -> U
+ locallimitcomplex : (FE,SY,OPF) -> Union(OPF,"failed")
+ poleLimit:(RN,FE,SY) -> U
+ poleLimitPlus:(RN,FE,SY) -> RESULT
+
+ noX?: (FE,SY) -> Boolean
+ noX?(fcn,x) == not member?(x,variables fcn)
+
+ constant?: FE -> Boolean
+ constant? fcn == empty? variables fcn
+
+ firstNonLogPtr: (FE,SY) -> List Kernel FE
+ firstNonLogPtr(fcn,x) ==
+ -- returns a pointer to the first element of kernels(fcn) which
+ -- has 'x' as a variable, which is not a logarithm, and which is
+ -- not simply 'x'
+ list := kernels fcn
+ while not empty? list repeat
+ ker := first list
+ not is?(ker,"log" :: Symbol) and member?(x,variables(ker::FE)) _
+ and not(x = name(ker)) =>
+ return list
+ list := rest list
+ empty()
+
+ finiteValueAtInfinity?: Kernel FE -> Boolean
+ finiteValueAtInfinity? ker ==
+ is?(ker,"erf" :: Symbol) => true
+ is?(ker,"sech" :: Symbol) => true
+ is?(ker,"csch" :: Symbol) => true
+ is?(ker,"tanh" :: Symbol) => true
+ is?(ker,"coth" :: Symbol) => true
+ is?(ker,"atan" :: Symbol) => true
+ is?(ker,"acot" :: Symbol) => true
+ is?(ker,"asec" :: Symbol) => true
+ is?(ker,"acsc" :: Symbol) => true
+ is?(ker,"acsch" :: Symbol) => true
+ is?(ker,"acoth" :: Symbol) => true
+ false
+
+ knownValueAtInfinity?: Kernel FE -> Boolean
+ knownValueAtInfinity? ker ==
+ is?(ker,"exp" :: Symbol) => true
+ is?(ker,"sinh" :: Symbol) => true
+ is?(ker,"cosh" :: Symbol) => true
+ false
+
+ leftOrRight: (FE,SY,FE) -> SingleInteger
+ leftOrRight(fcn,x,limVal) ==
+ -- function is called when limitPlus(fcn,x) = limVal
+ -- determines whether the limiting value is approached
+ -- from the left or from the right
+ (value := limitPlus(inv(fcn - limVal),x)) case "failed" => 0
+ (inf := whatInfinity(val := value :: OFE)) = 0 =>
+ error "limit package: internal error"
+ inf
+
+ specialLimit1: (FE,SY) -> RESULT
+ specialLimitKernel: (Kernel FE,SY) -> RESULT
+ specialLimitNormalize: (FE,SY) -> RESULT
+ specialLimit: (FE, SY) -> RESULT
+
+ specialLimit(fcn, x) ==
+ xkers := [k for k in kernels fcn | member?(x,variables(k::FE))]
+ #xkers = 1 => specialLimit1(fcn,x)
+ num := numerator fcn
+ den := denominator fcn
+ for k in xkers repeat
+ (fval := limitPlus(k::FE,x)) case "failed" =>
+ return specialLimitNormalize(fcn,x)
+ whatInfinity(val := fval::OFE) ^= 0 =>
+ return specialLimitNormalize(fcn,x)
+ (valu := retractIfCan(val)@Union(FE,"failed")) case "failed" =>
+ return specialLimitNormalize(fcn,x)
+ finVal := valu :: FE
+ num := eval(num, k, finVal)
+ den := eval(den, k, finVal)
+ den = 0 => return specialLimitNormalize(fcn,x)
+ (num/den) :: OFE :: RESULT
+
+ specialLimitNormalize(fcn,x) == -- tries to normalize result first
+ nfcn := normalize(fcn)
+ fcn ^= nfcn => limitPlus(nfcn,x)
+ xkers := [k for k in tower fcn | member?(x,variables(k::FE))]
+ # xkers ^= 2 => "failed"
+ expKers := [k for k in xkers | is?(k, "exp" :: Symbol)]
+ # expKers ^= 1 => "failed"
+ -- fcn is a rational function of x and exp(g(x)) for some rational function g
+ expKer := first expKers
+ (fval := limitPlus(expKer::FE,x)) case "failed" => "failed"
+ vv := new()$SY; eq : EQ FE := equation(expKer :: FE,vv :: FE)
+ cc := eval(fcn,eq)
+ expKerLim := fval :: OFE
+ -- following test for "failed" is needed due to compiler bug
+ -- limVal case OFE generates EQCAR(limVal, 1) which fails on atom "failed"
+ (limVal := locallimit(cc,vv,expKerLim)) case "failed" => "failed"
+ limVal case OFE =>
+ limm := limVal :: OFE
+ (lim := retractIfCan(limm)@Union(FE,"failed")) case "failed" =>
+ "failed" -- need special handling for directions at infinity
+ limitPlus(lim, x)
+ "failed"
+
+ -- limit of expression having only 1 kernel involving x
+ specialLimit1(fcn,x) ==
+ -- find the first interesting kernel in tower(fcn)
+ xkers := [k for k in kernels fcn | member?(x,variables(k::FE))]
+ #xkers ^= 1 => "failed"
+ ker := first xkers
+ vv := new()$SY; eq : EQ FE := equation(ker :: FE,vv :: FE)
+ cc := eval(fcn,eq)
+ member?(x,variables cc) => "failed"
+ (lim := specialLimitKernel(ker, x)) case "failed" => lim
+ argLim : OFE := lim :: OFE
+ (limVal := locallimit(cc,vv,argLim)) case "failed" => "failed"
+ limVal case OFE => limVal :: OFE
+ "failed"
+
+ -- limit of single kernel involving x
+ specialLimitKernel(ker,x) ==
+ is?(ker,"log" :: Symbol) =>
+ args := argument ker
+ empty? args => "failed" -- error "No argument"
+ not empty? rest args => "failed" -- error "Too many arugments"
+ arg := first args
+ -- compute limit(x -> 0+,arg)
+ (limm := limitPlus(arg,x)) case "failed" => "failed"
+ lim := limm :: OFE
+ (inf := whatInfinity lim) = -1 => "failed"
+ argLim : OFE :=
+ -- log(+infinity) = +infinity
+ inf = 1 => lim
+ -- now 'lim' must be finite
+ (li := retractIfCan(lim)@Union(FE,"failed") :: FE) = 0 =>
+ -- log(0) = -infinity
+ leftOrRight(arg,x,0) = 1 => minusInfinity()
+ return "failed"
+ log(li) :: OFE
+ -- kernel should be a function of one argument f(arg)
+ args := argument(ker)
+ empty? args => "failed" -- error "No argument"
+ not empty? rest args => "failed" -- error "Too many arugments"
+ arg := first args
+ -- compute limit(x -> 0+,arg)
+ (limm := limitPlus(arg,x)) case "failed" => "failed"
+ lim := limm :: OFE
+ f := elt(operator ker,(var := new()$SY) :: FE)
+ -- compute limit(x -> 0+,f(arg))
+ -- case where 'lim' is finite
+ (inf := whatInfinity lim) = 0 =>
+ is?(ker,"erf" :: Symbol) => erf(retract(lim)@FE)$LF(R,FE) :: OFE
+ (kerValue := locallimit(f,var,lim)) case "failed" => "failed"
+ kerValue case OFE => kerValue :: OFE
+ "failed"
+ -- case where 'lim' is plus infinity
+ inf = 1 =>
+ finiteValueAtInfinity? ker =>
+ val : FE :=
+ is?(ker,"erf" :: Symbol) => 1
+ is?(ker,"sech" :: Symbol) => 0
+ is?(ker,"csch" :: Symbol) => 0
+ is?(ker,"tanh" :: Symbol) => 0
+ is?(ker,"coth" :: Symbol) => 0
+ is?(ker,"atan" :: Symbol) => pi()/(2 :: FE)
+ is?(ker,"acot" :: Symbol) => 0
+ is?(ker,"asec" :: Symbol) => pi()/(2 :: FE)
+ is?(ker,"acsc" :: Symbol) => 0
+ is?(ker,"acsch" :: Symbol) => 0
+ -- ker must be acoth
+ 0
+ val :: OFE
+ knownValueAtInfinity? ker =>
+ lim -- limit(exp, cosh, sinh ,x=inf) = inf
+ "failed"
+ -- case where 'lim' is minus infinity
+ finiteValueAtInfinity? ker =>
+ val : FE :=
+ is?(ker,"erf" :: Symbol) => -1
+ is?(ker,"sech" :: Symbol) => 0
+ is?(ker,"csch" :: Symbol) => 0
+ is?(ker,"tanh" :: Symbol) => 0
+ is?(ker,"coth" :: Symbol) => 0
+ is?(ker,"atan" :: Symbol) => -pi()/(2 :: FE)
+ is?(ker,"acot" :: Symbol) => pi()
+ is?(ker,"asec" :: Symbol) => -pi()/(2 :: FE)
+ is?(ker,"acsc" :: Symbol) => -pi()
+ is?(ker,"acsch" :: Symbol) => 0
+ -- ker must be acoth
+ 0
+ val :: OFE
+ knownValueAtInfinity? ker =>
+ is?(ker,"exp" :: Symbol) => (0@FE) :: OFE
+ is?(ker,"sinh" :: Symbol) => lim
+ is?(ker,"cosh" :: Symbol) => plusInfinity()
+ "failed"
+ "failed"
+
+ logOnlyLimit: (FE,SY) -> RESULT
+ logOnlyLimit(coef,x) ==
+ -- this function is called when the 'constant' coefficient involves
+ -- the variable 'x'. Its purpose is to compute a right hand limit
+ -- of an expression involving log x. Here log x is replaced by -1/v,
+ -- where v is a new variable. If the new expression no longer involves
+ -- x, then take the right hand limit as v -> 0+
+ vv := new()$SY
+ eq : EQ FE := equation(log(x :: FE),-inv(vv :: FE))
+ member?(x,variables(cc := eval(coef,eq))) => "failed"
+ limitPlus(cc,vv)
+
+ locallimit(fcn,x,a) ==
+ -- Here 'fcn' is a function f(x) = f(x,...) in 'x' and possibly
+ -- other variables, and 'a' is a limiting value. The function
+ -- computes lim(x -> a,f(x)).
+ xK := retract(x::FE)@Kernel(FE)
+ (n := whatInfinity a) = 0 =>
+ realLimit(localsubst(fcn,xK,1,retract(a)@FE),x)
+ (u := limitPlus(eval(fcn,xK,n * inv(xK::FE)),x))
+ case "failed" => "failed"
+ u::OFE
+
+ localsubst(fcn, k, n, a) ==
+ a = 0 and n = 1 => fcn
+ eval(fcn,k,n * (k::FE) + a)
+
+ locallimitcomplex(fcn,x,a) ==
+ xK := retract(x::FE)@Kernel(FE)
+ (g := retractIfCan(a)@Union(FE,"failed")) case FE =>
+ complLimit(localsubst(fcn,xK,1,g::FE),x)
+ complLimit(eval(fcn,xK,inv(xK::FE)),x)
+
+ limit(fcn,eq,str) ==
+ (xx := retractIfCan(lhs eq)@Union(SY,"failed")) case "failed" =>
+ error "limit:left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ xK := retract(x::FE)@Kernel(FE)
+ limitPlus(localsubst(fcn,xK,direction str,a),x)
+
+ anyRootsOrAtrigs? fcn ==
+ -- determines if 'fcn' has any kernels which are roots
+ -- or if 'fcn' has any kernels which are inverse trig functions
+ -- which could produce series expansions with fractional exponents
+ for kernel in tower fcn repeat
+ is?(kernel,"nthRoot" :: Symbol) => return true
+ is?(kernel,"asin" :: Symbol) => return true
+ is?(kernel,"acos" :: Symbol) => return true
+ is?(kernel,"asec" :: Symbol) => return true
+ is?(kernel,"acsc" :: Symbol) => return true
+ false
+
+ complLimit(fcn,x) ==
+ -- computes lim(x -> 0,fcn) using a Puiseux expansion of fcn,
+ -- if fcn is an expression involving roots, and using a Laurent
+ -- expansion of fcn otherwise
+ lim : FE :=
+ anyRootsOrAtrigs? fcn =>
+ ppack := FS2UPS(R,FE,RN,_
+ UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
+ EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
+ pseries := exprToUPS(fcn,false,"complex")$ppack
+ pseries case %problem => return "failed"
+ if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
+ pole? upxs => return infinity()
+ coefficient(upxs,0)
+ lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
+ EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
+ lseries := exprToUPS(fcn,false,"complex")$lpack
+ lseries case %problem => return "failed"
+ if pole?(uls := lseries.%series) then uls := map(normalize,uls)
+ pole? uls => return infinity()
+ coefficient(uls,0)
+ -- can the following happen?
+ member?(x,variables lim) =>
+ member?(x,variables(answer := normalize lim)) =>
+ error "limit: can't evaluate limit"
+ answer :: OPF
+ lim :: FE :: OPF
+
+ okProblem?(function,problem) ==
+ (function = "log") or (function = "nth root") =>
+ (problem = "series of non-zero order") or _
+ (problem = "negative leading coefficient")
+ (function = "atan") => problem = "branch problem"
+ (function = "erf") => problem = "unknown kernel"
+ problem = "essential singularity"
+
+ poleLimit(order,coef,x) ==
+ -- compute limit for function with pole
+ not member?(x,variables coef) =>
+ (s := sign(coef)$SIGNEF) case Integer =>
+ rtLim := (s :: Integer) * plusInfinity()
+ even? numer order => rtLim
+ even? denom order => ["failed",rtLim]$TwoSide
+ [-rtLim,rtLim]$TwoSide
+ -- infinite limit, but cannot determine sign
+ "failed"
+ error "limit: can't evaluate limit"
+
+ poleLimitPlus(order,coef,x) ==
+ -- compute right hand limit for function with pole
+ not member?(x,variables coef) =>
+ (s := sign(coef)$SIGNEF) case Integer =>
+ (s :: Integer) * plusInfinity()
+ -- infinite limit, but cannot determine sign
+ "failed"
+ (clim := specialLimit(coef,x)) case "failed" => "failed"
+ zero? (lim := clim :: OFE) =>
+ -- in this event, we need to determine if the limit of
+ -- the coef is 0+ or 0-
+ (cclim := specialLimit(inv coef,x)) case "failed" => "failed"
+ ss := whatInfinity(cclim :: OFE) :: Z
+ zero? ss =>
+ error "limit: internal error"
+ ss * plusInfinity()
+ t := whatInfinity(lim :: OFE) :: Z
+ zero? t =>
+ (tt := sign(coef)$SIGNEF) case Integer =>
+ (tt :: Integer) * plusInfinity()
+ -- infinite limit, but cannot determine sign
+ "failed"
+ t * plusInfinity()
+
+ realLimit(fcn,x) ==
+ -- computes lim(x -> 0,fcn) using a Puiseux expansion of fcn,
+ -- if fcn is an expression involving roots, and using a Laurent
+ -- expansion of fcn otherwise
+ lim : Union(FE,"failed") :=
+ anyRootsOrAtrigs? fcn =>
+ ppack := FS2UPS(R,FE,RN,_
+ UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
+ EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
+ pseries := exprToUPS(fcn,true,"real: two sides")$ppack
+ pseries case %problem =>
+ trouble := pseries.%problem
+ function := trouble.func; problem := trouble.prob
+ okProblem?(function,problem) =>
+ left :=
+ xK : Kernel FE := kernel x
+ fcn0 := eval(fcn,xK,-(xK :: FE))
+ limitPlus(fcn0,x)
+ right := limitPlus(fcn,x)
+ (left case "failed") and (right case "failed") =>
+ return "failed"
+ if (left case OFE) and (right case OFE) then
+ (left :: OFE) = (right :: OFE) => return (left :: OFE)
+ return([left,right]$TwoSide)
+ return "failed"
+ if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
+ pole? upxs =>
+ cp := coefficient(upxs,ordp := order upxs)
+ return poleLimit(ordp,cp,x)
+ coefficient(upxs,0)
+ lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
+ EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
+ lseries := exprToUPS(fcn,true,"real: two sides")$lpack
+ lseries case %problem =>
+ trouble := lseries.%problem
+ function := trouble.func; problem := trouble.prob
+ okProblem?(function,problem) =>
+ left :=
+ xK : Kernel FE := kernel x
+ fcn0 := eval(fcn,xK,-(xK :: FE))
+ limitPlus(fcn0,x)
+ right := limitPlus(fcn,x)
+ (left case "failed") and (right case "failed") =>
+ return "failed"
+ if (left case OFE) and (right case OFE) then
+ (left :: OFE) = (right :: OFE) => return (left :: OFE)
+ return([left,right]$TwoSide)
+ return "failed"
+ if pole?(uls := lseries.%series) then uls := map(normalize,uls)
+ pole? uls =>
+ cl := coefficient(uls,ordl := order uls)
+ return poleLimit(ordl :: RN,cl,x)
+ coefficient(uls,0)
+ lim case "failed" => "failed"
+ member?(x,variables(lim :: FE)) =>
+ member?(x,variables(answer := normalize(lim :: FE))) =>
+ error "limit: can't evaluate limit"
+ answer :: OFE
+ lim :: FE :: OFE
+
+ xxpLimit(fcn,x) ==
+ -- computes lim(x -> 0+,fcn) using an exponential expansion of fcn
+ xpack := FS2EXPXP(R,FE,x,zeroFE)
+ xxp := exprToXXP(fcn,true)$xpack
+ xxp case %problem => "failed"
+ limitPlus(xxp.%expansion)
+
+ limitPlus(fcn,x) ==
+ -- computes lim(x -> 0+,fcn) using a generalized Puiseux expansion
+ -- of fcn, if fcn is an expression involving roots, and using a
+ -- generalized Laurent expansion of fcn otherwise
+ lim : Union(FE,"failed") :=
+ anyRootsOrAtrigs? fcn =>
+ ppack := FS2UPS(R,FE,RN,_
+ UPXS(FE,x,zeroFE),EFUPXS(FE,ULS(FE,x,zeroFE),UPXS(FE,x,zeroFE),_
+ EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE))),x)
+ pseries := exprToGenUPS(fcn,true,"real: right side")$ppack
+ pseries case %problem =>
+ trouble := pseries.%problem
+ ff := trouble.func; pp := trouble.prob
+ (pp = "negative leading coefficient") => return "failed"
+ "failed"
+ -- pseries case %problem => return "failed"
+ if pole?(upxs := pseries.%series) then upxs := map(normalize,upxs)
+ pole? upxs =>
+ cp := coefficient(upxs,ordp := order upxs)
+ return poleLimitPlus(ordp,cp,x)
+ coefficient(upxs,0)
+ lpack := FS2UPS(R,FE,Z,ULS(FE,x,zeroFE),_
+ EFULS(FE,UTS(FE,x,zeroFE),ULS(FE,x,zeroFE)),x)
+ lseries := exprToGenUPS(fcn,true,"real: right side")$lpack
+ lseries case %problem =>
+ trouble := lseries.%problem
+ ff := trouble.func; pp := trouble.prob
+ (pp = "negative leading coefficient") => return "failed"
+ "failed"
+ -- lseries case %problem => return "failed"
+ if pole?(uls := lseries.%series) then uls := map(normalize,uls)
+ pole? uls =>
+ cl := coefficient(uls,ordl := order uls)
+ return poleLimitPlus(ordl :: RN,cl,x)
+ coefficient(uls,0)
+ lim case "failed" =>
+ (xLim := xxpLimit(fcn,x)) case "failed" => specialLimit(fcn,x)
+ xLim
+ member?(x,variables(lim :: FE)) =>
+ member?(x,variables(answer := normalize(lim :: FE))) =>
+ (xLim := xxpLimit(answer,x)) case "failed" => specialLimit(answer,x)
+ xLim
+ answer :: OFE
+ lim :: FE :: OFE
+
+ limit(fcn:FE,eq:EQ OFE) ==
+ (f := retractIfCan(lhs eq)@Union(FE,"failed")) case "failed" =>
+ error "limit:left hand side must be a variable"
+ (xx := retractIfCan(f)@Union(SY,"failed")) case "failed" =>
+ error "limit:left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ locallimit(fcn,x,a)
+
+ complexLimit(fcn:FE,eq:EQ OPF) ==
+ (f := retractIfCan(lhs eq)@Union(FE,"failed")) case "failed" =>
+ error "limit:left hand side must be a variable"
+ (xx := retractIfCan(f)@Union(SY,"failed")) case "failed" =>
+ error "limit:left hand side must be a variable"
+ x := xx :: SY; a := rhs eq
+ locallimitcomplex(fcn,x,a)
+
+@
+\section{package SIGNEF ElementaryFunctionSign}
+<<package SIGNEF ElementaryFunctionSign>>=
+)abbrev package SIGNEF ElementaryFunctionSign
+++ Author: Manuel Bronstein
+++ Date Created: 25 Aug 1989
+++ Date Last Updated: 4 May 1992
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: elementary function, sign
+++ Examples:
+++ References:
+++ Description:
+++ This package provides functions to determine the sign of an
+++ elementary function around a point or infinity.
+ElementaryFunctionSign(R,F): Exports == Implementation where
+ R : Join(IntegralDomain,OrderedSet,RetractableTo Integer,_
+ LinearlyExplicitRingOver Integer,GcdDomain)
+ F : Join(AlgebraicallyClosedField,TranscendentalFunctionCategory,_
+ FunctionSpace R)
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ SY ==> Symbol
+ RF ==> Fraction Polynomial R
+ ORF ==> OrderedCompletion RF
+ OFE ==> OrderedCompletion F
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ U ==> Union(Z, "failed")
+ FS2 ==> FunctionSpaceFunctions2
+ POSIT ==> "positive"
+ NEGAT ==> "negative"
+
+ Exports ==> with
+ sign: F -> U
+ ++ sign(f) returns the sign of f if it is constant everywhere.
+ sign: (F, SY, OFE) -> U
+ ++ sign(f, x, a) returns the sign of f as x nears \spad{a}, from both
+ ++ sides if \spad{a} is finite.
+ sign: (F, SY, F, String) -> U
+ ++ sign(f, x, a, s) returns the sign of f as x nears \spad{a} from below
+ ++ if s is "left", or above if s is "right".
+
+ Implementation ==> add
+ import ToolsForSign R
+ import RationalFunctionSign(R)
+ import PowerSeriesLimitPackage(R, F)
+ import TrigonometricManipulations(R, F)
+
+ smpsign : P -> U
+ sqfrSign: P -> U
+ termSign: P -> U
+ kerSign : K -> U
+ listSign: (List P,Z) -> U
+ insign : (F,SY,OFE, N) -> U
+ psign : (F,SY,F,String, N) -> U
+ ofesign : OFE -> U
+ overRF : OFE -> Union(ORF, "failed")
+
+ sign(f, x, a) ==
+ not real? f => "failed"
+ insign(f, x, a, 0)
+
+ sign(f, x, a, st) ==
+ not real? f => "failed"
+ psign(f, x, a, st, 0)
+
+ sign f ==
+ not real? f => "failed"
+ (u := retractIfCan(f)@Union(RF,"failed")) case RF => sign(u::RF)
+ (un := smpsign numer f) case Z and (ud := smpsign denom f) case Z =>
+ un::Z * ud::Z
+ --abort if there are any variables
+ not empty? variables f => "failed"
+ -- abort in the presence of algebraic numbers
+ member?(coerce("rootOf")::Symbol,map(name,operators f)$ListFunctions2(BasicOperator,Symbol)) => "failed"
+ -- In the last resort try interval evaluation where feasible.
+ if R has ConvertibleTo Float then
+ import Interval(Float)
+ import Expression(Interval Float)
+ mapfun : (R -> Interval(Float)) := interval(convert(#1)$R)
+ f2 : Expression(Interval Float) := map(mapfun,f)$FS2(R,F,Interval(Float),Expression(Interval Float))
+ r : Union(Interval(Float),"failed") := retractIfCan f2
+ if r case "failed" then return "failed"
+ negative? r => return(-1)
+ positive? r => return 1
+ zero? r => return 0
+ "failed"
+ "failed"
+
+ overRF a ==
+ (n := whatInfinity a) = 0 =>
+ (u := retractIfCan(retract(a)@F)@Union(RF,"failed")) _
+ case "failed" => "failed"
+ u::RF::ORF
+ n * plusInfinity()$ORF
+
+ ofesign a ==
+ (n := whatInfinity a) ^= 0 => convert(n)@Z
+ sign(retract(a)@F)
+
+ insign(f, x, a, m) ==
+ m > 10 => "failed" -- avoid infinite loops for now
+ (uf := retractIfCan(f)@Union(RF,"failed")) case RF and
+ (ua := overRF a) case ORF => sign(uf::RF, x, ua::ORF)
+ eq : Equation OFE := equation(x :: F :: OFE,a)
+ (u := limit(f,eq)) case "failed" => "failed"
+ u case OFE =>
+ (n := whatInfinity(u::OFE)) ^= 0 => convert(n)@Z
+ (v := retract(u::OFE)@F) = 0 =>
+ (s := insign(differentiate(f, x), x, a, m + 1)) case "failed"
+ => "failed"
+ - s::Z * n
+ sign v
+ (u.leftHandLimit case "failed") or
+ (u.rightHandLimit case "failed") => "failed"
+ (ul := ofesign(u.leftHandLimit::OFE)) case "failed" => "failed"
+ (ur := ofesign(u.rightHandLimit::OFE)) case "failed" => "failed"
+ (ul::Z) = (ur::Z) => ul
+ "failed"
+
+ psign(f, x, a, st, m) ==
+ m > 10 => "failed" -- avoid infinite loops for now
+ f = 0 => 0
+ (uf := retractIfCan(f)@Union(RF,"failed")) case RF and
+ (ua := retractIfCan(a)@Union(RF,"failed")) case RF =>
+ sign(uf::RF, x, ua::RF, st)
+ eq : Equation F := equation(x :: F,a)
+ (u := limit(f,eq,st)) case "failed" => "failed"
+ u case OFE =>
+ (n := whatInfinity(u::OFE)) ^= 0 => convert(n)@Z
+ (v := retract(u::OFE)@F) = 0 =>
+ (s := psign(differentiate(f,x),x,a,st,m + 1)) case "failed"=>
+ "failed"
+ direction(st) * s::Z
+ sign v
+
+ smpsign p ==
+ (r := retractIfCan(p)@Union(R,"failed")) case R => sign(r::R)
+ (u := sign(retract(unit(s := squareFree p))@R)) case "failed" =>
+ "failed"
+ ans := u::Z
+ for term in factorList s | odd?(term.xpnt) repeat
+ (u := sqfrSign(term.fctr)) case "failed" => return "failed"
+ ans := ans * u::Z
+ ans
+
+ sqfrSign p ==
+ (u := termSign first(l := monomials p)) case "failed" => "failed"
+ listSign(rest l, u::Z)
+
+ listSign(l, s) ==
+ for term in l repeat
+ (u := termSign term) case "failed" => return "failed"
+ not(s = u::Z) => return "failed"
+ s
+
+ termSign term ==
+ (us := sign leadingCoefficient term) case "failed" => "failed"
+ for var in (lv := variables term) repeat
+ odd? degree(term, var) =>
+ empty? rest lv and (vs := kerSign first lv) case Z =>
+ return(us::Z * vs::Z)
+ return "failed"
+ us::Z
+
+ kerSign k ==
+ has?(op := operator k, "NEGAT") => -1
+ has?(op, "POSIT") or is?(op, "pi"::SY) or is?(op,"exp"::SY) or
+ is?(op,"cosh"::SY) or is?(op,"sech"::SY) => 1
+ empty?(arg := argument k) => "failed"
+ (s := sign first arg) case "failed" =>
+ is?(op,"nthRoot" :: SY) =>
+ even?(retract(second arg)@Z) => 1
+ "failed"
+ "failed"
+ is?(op,"log" :: SY) =>
+ s::Z < 0 => "failed"
+ sign(first arg - 1)
+ is?(op,"tanh" :: SY) or is?(op,"sinh" :: SY) or
+ is?(op,"csch" :: SY) or is?(op,"coth" :: SY) => s
+ is?(op,"nthRoot" :: SY) =>
+ even?(retract(second arg)@Z) =>
+ s::Z < 0 => "failed"
+ s
+ s
+ "failed"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package LIMITPS PowerSeriesLimitPackage>>
+<<package SIGNEF ElementaryFunctionSign>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/lindep.spad.pamphlet b/src/algebra/lindep.spad.pamphlet
new file mode 100644
index 00000000..fb52df5c
--- /dev/null
+++ b/src/algebra/lindep.spad.pamphlet
@@ -0,0 +1,165 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lindep.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LINDEP LinearDependence}
+<<package LINDEP LinearDependence>>=
+)abbrev package LINDEP LinearDependence
+++ Test for linear dependence
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Test for linear dependence.
+LinearDependence(S, R): Exports == Implementation where
+ S: IntegralDomain
+ R: LinearlyExplicitRingOver S
+
+ Q ==> Fraction S
+
+ Exports ==> with
+ linearlyDependent?: Vector R -> Boolean
+ ++ \spad{linearlyDependent?([v1,...,vn])} returns true if
+ ++ the vi's are linearly dependent over S, false otherwise.
+ linearDependence : Vector R -> Union(Vector S, "failed")
+ ++ \spad{linearDependence([v1,...,vn])} returns \spad{[c1,...,cn]} if
+ ++ \spad{c1*v1 + ... + cn*vn = 0} and not all the ci's are 0,
+ ++ "failed" if the vi's are linearly independent over S.
+ if S has Field then
+ solveLinear: (Vector R, R) -> Union(Vector S, "failed")
+ ++ \spad{solveLinear([v1,...,vn], u)} returns \spad{[c1,...,cn]}
+ ++ such that \spad{c1*v1 + ... + cn*vn = u},
+ ++ "failed" if no such ci's exist in S.
+ else
+ solveLinear: (Vector R, R) -> Union(Vector Q, "failed")
+ ++ \spad{solveLinear([v1,...,vn], u)} returns \spad{[c1,...,cn]}
+ ++ such that \spad{c1*v1 + ... + cn*vn = u},
+ ++ "failed" if no such ci's exist in the quotient field of S.
+
+ Implementation ==> add
+ aNonZeroSolution: Matrix S -> Union(Vector S, "failed")
+
+ aNonZeroSolution m ==
+ every?(zero?, v := first nullSpace m) => "failed"
+ v
+
+ linearlyDependent? v ==
+ zero?(n := #v) => true
+-- one? n => zero?(v(minIndex v))
+ (n = 1) => zero?(v(minIndex v))
+ positive? nullity reducedSystem transpose v
+
+ linearDependence v ==
+ zero?(n := #v) => empty()
+-- one? n =>
+ (n = 1) =>
+ zero?(v(minIndex v)) => new(1, 1)
+ "failed"
+ aNonZeroSolution reducedSystem transpose v
+
+ if S has Field then
+ solveLinear(v:Vector R, c:R):Union(Vector S, "failed") ==
+ zero? c => new(#v, 0)
+ empty? v => "failed"
+ sys := reducedSystem(transpose v, new(1, c))
+ particularSolution(sys.mat, sys.vec)$LinearSystemMatrixPackage(S,
+ Vector S, Vector S, Matrix S)
+
+ else
+ solveLinear(v:Vector R, c:R):Union(Vector Q, "failed") ==
+ zero? c => new(#v, 0)
+ empty? v => "failed"
+ sys := reducedSystem(transpose v, new(1, c))
+ particularSolution(map(#1::Q, sys.mat)$MatrixCategoryFunctions2(S,
+ Vector S,Vector S,Matrix S,Q,Vector Q,Vector Q,Matrix Q),
+ map(#1::Q, sys.vec)$VectorFunctions2(S, Q)
+ )$LinearSystemMatrixPackage(Q,
+ Vector Q, Vector Q, Matrix Q)
+
+@
+\section{package ZLINDEP IntegerLinearDependence}
+<<package ZLINDEP IntegerLinearDependence>>=
+)abbrev package ZLINDEP IntegerLinearDependence
+++ Test for linear dependence over the integers
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Test for linear dependence over the integers.
+IntegerLinearDependence(R): Exports == Implementation where
+ R: LinearlyExplicitRingOver Integer
+
+ Z ==> Integer
+
+ Exports ==> with
+ linearlyDependentOverZ?: Vector R -> Boolean
+ ++ \spad{linearlyDependentOverZ?([v1,...,vn])} returns true if the
+ ++ vi's are linearly dependent over the integers, false otherwise.
+ linearDependenceOverZ : Vector R -> Union(Vector Z, "failed")
+ ++ \spad{linearlyDependenceOverZ([v1,...,vn])} returns
+ ++ \spad{[c1,...,cn]} if
+ ++ \spad{c1*v1 + ... + cn*vn = 0} and not all the ci's are 0, "failed"
+ ++ if the vi's are linearly independent over the integers.
+ solveLinearlyOverQ : (Vector R, R) ->
+ Union(Vector Fraction Z, "failed")
+ ++ \spad{solveLinearlyOverQ([v1,...,vn], u)} returns \spad{[c1,...,cn]}
+ ++ such that \spad{c1*v1 + ... + cn*vn = u},
+ ++ "failed" if no such rational numbers ci's exist.
+
+ Implementation ==> add
+ import LinearDependence(Z, R)
+
+ linearlyDependentOverZ? v == linearlyDependent? v
+ linearDependenceOverZ v == linearDependence v
+ solveLinearlyOverQ(v, c) == solveLinear(v, c)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package LINDEP LinearDependence>>
+<<package ZLINDEP IntegerLinearDependence>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/lingrob.spad.pamphlet b/src/algebra/lingrob.spad.pamphlet
new file mode 100644
index 00000000..29e2b34f
--- /dev/null
+++ b/src/algebra/lingrob.spad.pamphlet
@@ -0,0 +1,362 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lingrob.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LGROBP LinGroebnerPackage}
+<<package LGROBP LinGroebnerPackage>>=
+)abbrev package LGROBP LinGroebnerPackage
+++ Given a Groebner basis B with respect to the total degree ordering for
+++ a zero-dimensional ideal I, compute
+++ a Groebner basis with respect to the lexicographical ordering by using
+++ linear algebra.
+LinGroebnerPackage(lv,F) : C == T
+
+ where
+ Z ==> Integer
+ lv : List Symbol
+ F : GcdDomain
+
+ DP ==> DirectProduct(#lv,NonNegativeInteger)
+ DPoly ==> DistributedMultivariatePolynomial(lv,F)
+
+ HDP ==> HomogeneousDirectProduct(#lv,NonNegativeInteger)
+ HDPoly ==> HomogeneousDistributedMultivariatePolynomial(lv,F)
+
+ OV ==> OrderedVariableList(lv)
+ NNI ==> NonNegativeInteger
+ LVals ==> Record(gblist : List DPoly,gvlist : List Z)
+ VF ==> Vector F
+ VV ==> Vector NNI
+ MF ==> Matrix F
+ cLVars ==> Record(glbase:List DPoly,glval:List Z)
+
+ C == with
+
+ linGenPos : List HDPoly -> LVals
+ ++ linGenPos \undocumented
+ groebgen : List DPoly -> cLVars
+ ++ groebgen \undocumented
+ totolex : List HDPoly -> List DPoly
+ ++ totolex \undocumented
+ minPol : (List HDPoly,List HDPoly,OV) -> HDPoly
+ ++ minPol \undocumented
+ minPol : (List HDPoly,OV) -> HDPoly
+ ++ minPol \undocumented
+
+
+ computeBasis : List HDPoly -> List HDPoly
+ ++ computeBasis \undocumented
+ coord : (HDPoly,List HDPoly) -> VF
+ ++ coord \undocumented
+ anticoord : (List F,DPoly,List DPoly) -> DPoly
+ ++ anticoord \undocumented
+ intcompBasis : (OV,List HDPoly,List HDPoly) -> List HDPoly
+ ++ intcompBasis \undocumented
+ choosemon : (DPoly,List DPoly) -> DPoly
+ ++ choosemon \undocumented
+ transform : DPoly -> HDPoly
+ ++ transform \undocumented
+
+
+ T == add
+
+ import GroebnerPackage(F,DP,OV,DPoly)
+ import GroebnerPackage(F,HDP,OV,HDPoly)
+ import GroebnerInternalPackage(F,HDP,OV,HDPoly)
+ import GroebnerInternalPackage(F,DP,OV,DPoly)
+
+ lvar :=[variable(yx)::OV for yx in lv]
+
+ reduceRow(M:MF, v : VF, lastRow: Integer, pivots: Vector(Integer)) : VF ==
+ a1:F := 1
+ b:F := 0
+ dim := #v
+ for j in 1..lastRow repeat -- scan over rows
+ mj := row(M,j)
+ k:=pivots(j)
+ b:=mj.k
+ vk := v.k
+ for kk in 1..(k-1) repeat
+ v(kk) := ((-b*v(kk)) exquo a1) :: F
+ for kk in k..dim repeat
+ v(kk) := ((vk*mj(kk)-b*v(kk)) exquo a1)::F
+ a1 := b
+ v
+
+ rRedPol(f:HDPoly, B:List HDPoly):Record(poly:HDPoly, mult:F) ==
+ gm := redPo(f,B)
+ gm.poly = 0 => gm
+ gg := reductum(gm.poly)
+ ggm := rRedPol(gg,B)
+ [ggm.mult*(gm.poly - gg) + ggm.poly, ggm.mult*gm.mult]
+
+----- transform the total basis B in lex basis -----
+ totolex(B : List HDPoly) : List DPoly ==
+ result:List DPoly :=[]
+ ltresult:List DPoly :=[]
+ vBasis:= computeBasis B
+ nBasis:List DPoly :=[1$DPoly]
+ ndim:=(#vBasis)::PositiveInteger
+ ndim1:NNI:=ndim+1
+ lm:VF
+ linmat:MF:=zero(ndim,2*ndim+1)
+ linmat(1,1):=1$F
+ linmat(1,ndim1):=1
+ pivots:Vector Integer := new(ndim,0)
+ pivots(1) := 1
+ firstmon:DPoly:=1$DPoly
+ ofirstmon:DPoly:=1$DPoly
+ orecfmon:Record(poly:HDPoly, mult:F) := [1,1]
+ i:NNI:=2
+ while (firstmon:=choosemon(firstmon,ltresult))^=1 repeat
+ if (v:=firstmon exquo ofirstmon) case "failed" then
+ recfmon:=rRedPol(transform firstmon,B)
+ else
+ recfmon:=rRedPol(transform(v::DPoly) *orecfmon.poly,B)
+ recfmon.mult := recfmon.mult * orecfmon.mult
+ cc := gcd(content recfmon.poly, recfmon.mult)
+ recfmon.poly := (recfmon.poly exquo cc)::HDPoly
+ recfmon.mult := (recfmon.mult exquo cc)::F
+ veccoef:VF:=coord(recfmon.poly,vBasis)
+ ofirstmon:=firstmon
+ orecfmon := recfmon
+ lm:=zero(2*ndim+1)
+ for j in 1..ndim repeat lm(j):=veccoef(j)
+ lm(ndim+i):=recfmon.mult
+ lm := reduceRow(linmat, lm, i-1, pivots)
+ if i=ndim1 then j:=ndim1
+ else
+ j:=1
+ while lm(j) = 0 and j< ndim1 repeat j:=j+1
+ if j=ndim1 then
+ cordlist:List F:=[lm(k) for k in ndim1..ndim1+(#nBasis)]
+ antc:=+/[c*b for c in reverse cordlist
+ for b in concat(firstmon,nBasis)]
+ antc:=primitivePart antc
+ result:=concat(antc,result)
+ ltresult:=concat(antc-reductum antc,ltresult)
+ else
+ pivots(i) := j
+ setRow_!(linmat,i,lm)
+ i:=i+1
+ nBasis:=cons(firstmon,nBasis)
+ result
+
+---- Compute the univariate polynomial for x
+----oldBasis is a total degree Groebner basis
+ minPol(oldBasis:List HDPoly,x:OV) :HDPoly ==
+ algBasis:= computeBasis oldBasis
+ minPol(oldBasis,algBasis,x)
+
+---- Compute the univariate polynomial for x
+---- oldBasis is total Groebner, algBasis is the basis as algebra
+ minPol(oldBasis:List HDPoly,algBasis:List HDPoly,x:OV) :HDPoly ==
+ nvp:HDPoly:=x::HDPoly
+ f:=1$HDPoly
+ omult:F :=1
+ ndim:=(#algBasis)::PositiveInteger
+ ndim1:NNI:=ndim+1
+ lm:VF
+ linmat:MF:=zero(ndim,2*ndim+1)
+ linmat(1,1):=1$F
+ linmat(1,ndim1):=1
+ pivots:Vector Integer := new(ndim,0)
+ pivots(1) := 1
+ for i in 2..ndim1 repeat
+ recf:=rRedPol(f*nvp,oldBasis)
+ omult := recf.mult * omult
+ f := recf.poly
+ cc := gcd(content f, omult)
+ f := (f exquo cc)::HDPoly
+ omult := (omult exquo cc)::F
+ veccoef:VF:=coord(f,algBasis)
+ lm:=zero(2*ndim+1)
+ for j in 1..ndim repeat lm(j) := veccoef(j)
+ lm(ndim+i):=omult
+ lm := reduceRow(linmat, lm, i-1, pivots)
+ j:=1
+ while lm(j)=0 and j<ndim1 repeat j:=j+1
+ if j=ndim1 then return
+ g:HDPoly:=0
+ for k in ndim1..2*ndim+1 repeat
+ g:=g+lm(k) * nvp**((k-ndim1):NNI)
+ primitivePart g
+ pivots(i) := j
+ setRow_!(linmat,i,lm)
+
+----- transform a DPoly in a HDPoly -----
+ transform(dpol:DPoly) : HDPoly ==
+ dpol=0 => 0$HDPoly
+ monomial(leadingCoefficient dpol,
+ directProduct(degree(dpol)::VV)$HDP)$HDPoly +
+ transform(reductum dpol)
+
+----- compute the basis for the vector space determined by B -----
+ computeBasis(B:List HDPoly) : List HDPoly ==
+ mB:List HDPoly:=[monomial(1$F,degree f)$HDPoly for f in B]
+ result:List HDPoly := [1$HDPoly]
+ for var in lvar repeat
+ part:=intcompBasis(var,result,mB)
+ result:=concat(result,part)
+ result
+
+----- internal function for computeBasis -----
+ intcompBasis(x:OV,lr:List HDPoly,mB : List HDPoly):List HDPoly ==
+ lr=[] => lr
+ part:List HDPoly :=[]
+ for f in lr repeat
+ g:=x::HDPoly * f
+ if redPo(g,mB).poly^=0 then part:=concat(g,part)
+ concat(part,intcompBasis(x,part,mB))
+
+----- coordinate of f with respect to the basis B -----
+----- f is a reduced polynomial -----
+ coord(f:HDPoly,B:List HDPoly) : VF ==
+ ndim := #B
+ vv:VF:=new(ndim,0$F)$VF
+ while f^=0 repeat
+ rf := reductum f
+ lf := f-rf
+ lcf := leadingCoefficient f
+ i:Z:=position(monomial(1$F,degree lf),B)
+ vv.i:=lcf
+ f := rf
+ vv
+
+----- reconstruct the polynomial from its coordinate -----
+ anticoord(vv:List F,mf:DPoly,B:List DPoly) : DPoly ==
+ for f in B for c in vv repeat (mf:=mf-c*f)
+ mf
+
+----- choose the next monom -----
+ choosemon(mf:DPoly,nB:List DPoly) : DPoly ==
+ nB = [] => ((lvar.last)::DPoly)*mf
+ for x in reverse lvar repeat
+ xx:=x ::DPoly
+ mf:=xx*mf
+ if redPo(mf,nB).poly ^= 0 then return mf
+ dx := degree(mf,x)
+ mf := (mf exquo (xx ** dx))::DPoly
+ mf
+
+----- put B in general position, B is Groebner -----
+ linGenPos(B : List HDPoly) : LVals ==
+ result:List DPoly :=[]
+ ltresult:List DPoly :=[]
+ vBasis:= computeBasis B
+ nBasis:List DPoly :=[1$DPoly]
+ ndim:=#vBasis : PositiveInteger
+ ndim1:NNI:=ndim+1
+ lm:VF
+ linmat:MF:=zero(ndim,2*ndim+1)
+ linmat(1,1):=1$F
+ linmat(1,ndim1):=1
+ pivots:Vector Integer := new(ndim,0)
+ pivots(1) := 1
+ i:NNI:=2
+ rval:List Z :=[]
+ for ii in 1..(#lvar-1) repeat
+ c:Z:=0
+ while c=0 repeat c:=random()$Z rem 11
+ rval:=concat(c,rval)
+ nval:DPoly := (last.lvar)::DPoly -
+ (+/[r*(vv)::DPoly for r in rval for vv in lvar])
+ firstmon:DPoly:=1$DPoly
+ ofirstmon:DPoly:=1$DPoly
+ orecfmon:Record(poly:HDPoly, mult:F) := [1,1]
+ lx:= lvar.last
+ while (firstmon:=choosemon(firstmon,ltresult))^=1 repeat
+ if (v:=firstmon exquo ofirstmon) case "failed" then
+ recfmon:=rRedPol(transform(eval(firstmon,lx,nval)),B)
+ else
+ recfmon:=rRedPol(transform(eval(v,lx,nval))*orecfmon.poly,B)
+ recfmon.mult := recfmon.mult * orecfmon.mult
+ cc := gcd(content recfmon.poly, recfmon.mult)
+ recfmon.poly := (recfmon.poly exquo cc)::HDPoly
+ recfmon.mult := (recfmon.mult exquo cc)::F
+ veccoef:VF:=coord(recfmon.poly,vBasis)
+ ofirstmon:=firstmon
+ orecfmon := recfmon
+ lm:=zero(2*ndim+1)
+ for j in 1..ndim repeat lm(j):=veccoef(j)
+ lm(ndim+i):=recfmon.mult
+ lm := reduceRow(linmat, lm, i-1, pivots)
+ j:=1
+ while lm(j) = 0 and j<ndim1 repeat j:=j+1
+ if j=ndim1 then
+ cordlist:List F:=[lm(j) for j in ndim1..ndim1+(#nBasis)]
+ antc:=+/[c*b for c in reverse cordlist
+ for b in concat(firstmon,nBasis)]
+ result:=concat(primitivePart antc,result)
+ ltresult:=concat(antc-reductum antc,ltresult)
+ else
+ pivots(i) := j
+ setRow_!(linmat,i,lm)
+ i:=i+1
+ nBasis:=concat(firstmon,nBasis)
+ [result,rval]$LVals
+
+----- given a basis of a zero-dimensional ideal,
+----- performs a random change of coordinates
+----- computes a Groebner basis for the lex ordering
+ groebgen(L:List DPoly) : cLVars ==
+ xn:=lvar.last
+ val := xn::DPoly
+ nvar1:NNI:=(#lvar-1):NNI
+ ll: List Z :=[random()$Z rem 11 for i in 1..nvar1]
+ val:=val+ +/[ll.i*(lvar.i)::DPoly for i in 1..nvar1]
+ LL:=[elt(univariate(f,xn),val) for f in L]
+ LL:= groebner(LL)
+ [LL,ll]$cLVars
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package LGROBP LinGroebnerPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/liouv.spad.pamphlet b/src/algebra/liouv.spad.pamphlet
new file mode 100644
index 00000000..6be5415c
--- /dev/null
+++ b/src/algebra/liouv.spad.pamphlet
@@ -0,0 +1,246 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra liouv.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LF LiouvillianFunction}
+<<package LF LiouvillianFunction>>=
+)abbrev package LF LiouvillianFunction
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 10 August 1994
+++ Keywords: liouvillian, function, primitive, exponential.
+++ Examples: )r LF INPUT
+++ Description:
+++ This package provides liouvillian functions over an integral domain.
+LiouvillianFunction(R, F): Exports == Implementation where
+ R:Join(OrderedSet, IntegralDomain)
+ F:Join(FunctionSpace R,RadicalCategory,TranscendentalFunctionCategory)
+
+ OP ==> BasicOperator
+ PR ==> Polynomial R
+ K ==> Kernel F
+ SE ==> Symbol
+ O ==> OutputForm
+ INP ==> InputForm
+ INV ==> error "Invalid argument"
+
+ SPECIALDIFF ==> "%specialDiff"
+ SPECIALDISP ==> "%specialDisp"
+ SPECIALINPUT ==> "%specialInput"
+ SPECIALEQUAL ==> "%specialEqual"
+
+ Exports ==> with
+ belong? : OP -> Boolean
+ ++ belong?(op) checks if op is Liouvillian
+ operator: OP -> OP
+ ++ operator(op) returns the Liouvillian operator based on op
+ Ei : F -> F
+ ++ Ei(f) denotes the exponential integral
+ Si : F -> F
+ ++ Si(f) denotes the sine integral
+ Ci : F -> F
+ ++ Ci(f) denotes the cosine integral
+ li : F -> F
+ ++ li(f) denotes the logarithmic integral
+ erf : F -> F
+ ++ erf(f) denotes the error function
+ dilog : F -> F
+ ++ dilog(f) denotes the dilogarithm
+ integral: (F, SE) -> F
+ ++ integral(f,x) indefinite integral of f with respect to x.
+ integral: (F, SegmentBinding F) -> F
+ ++ integral(f,x = a..b) denotes the definite integral of f with
+ ++ respect to x from \spad{a} to b.
+
+ Implementation ==> add
+ iei : F -> F
+ isi : F -> F
+ ici : F -> F
+ ierf : F -> F
+ ili : F -> F
+ ili2 : F -> F
+ iint : List F -> F
+ eqint : (K,K) -> Boolean
+ dvint : (List F, SE) -> F
+ dvdint : (List F, SE) -> F
+ ddint : List F -> O
+ integrand : List F -> F
+
+ dummy := new()$SE :: F
+
+ opint := operator("integral"::Symbol)$CommonOperators
+ opdint := operator("%defint"::Symbol)$CommonOperators
+ opei := operator("Ei"::Symbol)$CommonOperators
+ opli := operator("li"::Symbol)$CommonOperators
+ opsi := operator("Si"::Symbol)$CommonOperators
+ opci := operator("Ci"::Symbol)$CommonOperators
+ opli2 := operator("dilog"::Symbol)$CommonOperators
+ operf := operator("erf"::Symbol)$CommonOperators
+
+ Si x == opsi x
+ Ci x == opci x
+ Ei x == opei x
+ erf x == operf x
+ li x == opli x
+ dilog x == opli2 x
+
+ belong? op == has?(op, "prim")
+ isi x == kernel(opsi, x)
+ ici x == kernel(opci, x)
+ ierf x == (zero? x => 0; kernel(operf, x))
+-- ili2 x == (one? x => INV; kernel(opli2, x))
+ ili2 x == ((x = 1) => INV; kernel(opli2, x))
+ integrand l == eval(first l, retract(second l)@K, third l)
+ integral(f:F, x:SE) == opint [eval(f, k:=kernel(x)$K, dummy), dummy, k::F]
+
+ iint l ==
+ zero? first l => 0
+ kernel(opint, l)
+
+ ddint l ==
+ int(integrand(l)::O * hconcat("d"::SE::O, third(l)::O),
+ third(rest l)::O, third(rest rest l)::O)
+
+ eqint(k1,k2) ==
+ a1:=argument k1
+ a2:=argument k2
+ res:=operator k1 = operator k2
+ if not res then return res
+ res:= a1 = a2
+ if res then return res
+ res:= (a1.3 = a2.3) and (subst(a1.1,[retract(a1.2)@K],[a2.2]) = a2.1)
+
+ dvint(l, x) ==
+ k := retract(second l)@K
+ differentiate(third l, x) * integrand l
+ + opint [differentiate(first l, x), second l, third l]
+
+
+ dvdint(l, x) ==
+ x = retract(y := third l)@SE => 0
+ k := retract(d := second l)@K
+ differentiate(h := third rest rest l,x) * eval(f := first l, k, h)
+ - differentiate(g := third rest l, x) * eval(f, k, g)
+ + opdint [differentiate(f, x), d, y, g, h]
+
+ integral(f:F, s: SegmentBinding F) ==
+ x := kernel(variable s)$K
+ opdint [eval(f,x,dummy), dummy, x::F, lo segment s, hi segment s]
+
+ ili x ==
+ x = 1 => INV
+ is?(x, "exp"::Symbol) => Ei first argument(retract(x)@K)
+ kernel(opli, x)
+
+ iei x ==
+ x = 0 => INV
+ is?(x, "log"::Symbol) => li first argument(retract(x)@K)
+ kernel(opei, x)
+
+ operator op ==
+ is?(op, "integral"::Symbol) => opint
+ is?(op, "%defint"::Symbol) => opdint
+ is?(op, "Ei"::Symbol) => opei
+ is?(op, "Si"::Symbol) => opsi
+ is?(op, "Ci"::Symbol) => opci
+ is?(op, "li"::Symbol) => opli
+ is?(op, "erf"::Symbol) => operf
+ is?(op, "dilog"::Symbol) => opli2
+ error "Not a Liouvillian operator"
+
+ evaluate(opei, iei)$BasicOperatorFunctions1(F)
+ evaluate(opli, ili)
+ evaluate(opsi, isi)
+ evaluate(opci, ici)
+ evaluate(operf, ierf)
+ evaluate(opli2, ili2)
+ evaluate(opint, iint)
+ derivative(opsi, sin(#1) / #1)
+ derivative(opci, cos(#1) / #1)
+ derivative(opei, exp(#1) / #1)
+ derivative(opli, inv log(#1))
+ derivative(operf, 2 * exp(-(#1**2)) / sqrt(pi()))
+ derivative(opli2, log(#1) / (1 - #1))
+ setProperty(opint,SPECIALEQUAL,eqint@((K,K) -> Boolean) pretend None)
+ setProperty(opint,SPECIALDIFF,dvint@((List F,SE) -> F) pretend None)
+ setProperty(opdint,SPECIALDIFF,dvdint@((List F,SE)->F) pretend None)
+ setProperty(opdint, SPECIALDISP, ddint@(List F -> O) pretend None)
+
+ if R has ConvertibleTo INP then
+ inint : List F -> INP
+ indint: List F -> INP
+ pint : List INP -> INP
+
+
+ pint l == convert concat(convert("integral"::SE)@INP, l)
+ inint l ==
+ r2:= convert([convert("::"::SE)@INP,convert(third l)@INP,convert("Symbol"::SE)@INP]@List INP)@INP
+ pint [convert(integrand l)@INP, r2]
+
+ indint l ==
+ pint [convert(integrand l)@INP,
+ convert concat(convert("="::SE)@INP,
+ [convert(third l)@INP,
+ convert concat(convert("SEGMENT"::SE)@INP,
+ [convert(third rest l)@INP,
+ convert(third rest rest l)@INP])])]
+
+ setProperty(opint, SPECIALINPUT, inint@(List F -> INP) pretend None)
+ setProperty(opdint, SPECIALINPUT, indint@(List F -> INP) pretend None)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl fspace algfunc elemntry LIOUV expr
+
+<<package LF LiouvillianFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/list.spad.pamphlet b/src/algebra/list.spad.pamphlet
new file mode 100644
index 00000000..d773bb61
--- /dev/null
+++ b/src/algebra/list.spad.pamphlet
@@ -0,0 +1,803 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra list.spad}
+\author{Michael Monagon, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ILIST IndexedList}
+<<domain ILIST IndexedList>>=
+)abbrev domain ILIST IndexedList
+++ Author: Michael Monagan
+++ Date Created: Sep 1987
+++ Change History:
+++ Basic Operations:
+++ \#, concat, concat!, construct, copy, elt, elt, empty,
+++ empty?, eq?, first, member?, merge!, mergeSort, minIndex,
+++ parts, removeDuplicates!, rest, rest, reverse, reverse!,
+++ setelt, setfirst!, setrest!, sort!, split!
+++ Related Constructors: List
+++ Also See:
+++ AMS Classification:
+++ Keywords: list, aggregate, index
+++ Description:
+++ \spadtype{IndexedList} is a basic implementation of the functions
+++ in \spadtype{ListAggregate}, often using functions in the underlying
+++ LISP system. The second parameter to the constructor (\spad{mn})
+++ is the beginning index of the list. That is, if \spad{l} is a
+++ list, then \spad{elt(l,mn)} is the first value. This constructor
+++ is probably best viewed as the implementation of singly-linked
+++ lists that are addressable by index rather than as a mere wrapper
+++ for LISP lists.
+IndexedList(S:Type, mn:Integer): Exports == Implementation where
+ cycleMax ==> 1000 -- value used in checking for cycles
+
+-- The following seems to be a bit out of date, but is kept in case
+-- a knowledgeable person wants to update it:
+-- The following LISP dependencies are divided into two groups
+-- Those that are required
+-- CONS, EQ, NIL, NULL, QCAR, QCDR, RPLACA, RPLACD
+-- Those that are included for efficiency only
+-- NEQ, LIST, CAR, CDR, NCONC2, NREVERSE, LENGTH
+-- Also REVERSE, since it's called in Polynomial Ring
+
+ Qfirst ==> QCAR$Lisp
+ Qrest ==> QCDR$Lisp
+ Qnull ==> NULL$Lisp
+ Qeq ==> EQ$Lisp
+ Qneq ==> NEQ$Lisp
+ Qcons ==> CONS$Lisp
+ Qpush ==> PUSH$Lisp
+
+ Exports ==> ListAggregate S
+ Implementation ==>
+ add
+ #x == LENGTH(x)$Lisp
+ concat(s:S,x:%) == CONS(s,x)$Lisp
+ eq?(x,y) == EQ(x,y)$Lisp
+ first x == SPADfirst(x)$Lisp
+ elt(x,"first") == SPADfirst(x)$Lisp
+ empty() == NIL$Lisp
+ empty? x == NULL(x)$Lisp
+ rest x == CDR(x)$Lisp
+ elt(x,"rest") == CDR(x)$Lisp
+ setfirst_!(x,s) ==
+ empty? x => error "Cannot update an empty list"
+ Qfirst RPLACA(x,s)$Lisp
+ setelt(x,"first",s) ==
+ empty? x => error "Cannot update an empty list"
+ Qfirst RPLACA(x,s)$Lisp
+ setrest_!(x,y) ==
+ empty? x => error "Cannot update an empty list"
+ Qrest RPLACD(x,y)$Lisp
+ setelt(x,"rest",y) ==
+ empty? x => error "Cannot update an empty list"
+ Qrest RPLACD(x,y)$Lisp
+ construct l == l pretend %
+ parts s == s pretend List S
+ reverse_! x == NREVERSE(x)$Lisp
+ reverse x == REVERSE(x)$Lisp
+ minIndex x == mn
+
+ rest(x, n) ==
+ for i in 1..n repeat
+ if Qnull x then error "index out of range"
+ x := Qrest x
+ x
+
+ copy x ==
+ y := empty()
+ for i in 0.. while not Qnull x repeat
+ if Qeq(i,cycleMax) and cyclic? x then error "cyclic list"
+ y := Qcons(Qfirst x,y)
+ x := Qrest x
+ (NREVERSE(y)$Lisp)@%
+
+ if S has SetCategory then
+ coerce(x):OutputForm ==
+ -- displays cycle with overbar over the cycle
+ y := empty()$List(OutputForm)
+ s := cycleEntry x
+ while Qneq(x, s) repeat
+ y := concat((first x)::OutputForm, y)
+ x := rest x
+ y := reverse_! y
+ empty? s => bracket y
+ -- cyclic case: z is cylic part
+ z := list((first x)::OutputForm)
+ while Qneq(s, rest x) repeat
+ x := rest x
+ z := concat((first x)::OutputForm, z)
+ bracket concat_!(y, overbar commaSeparate reverse_! z)
+
+ x = y ==
+ Qeq(x,y) => true
+ while not Qnull x and not Qnull y repeat
+ Qfirst x ^=$S Qfirst y => return false
+ x := Qrest x
+ y := Qrest y
+ Qnull x and Qnull y
+
+ latex(x : %): String ==
+ s : String := "\left["
+ while not Qnull x repeat
+ s := concat(s, latex(Qfirst x)$S)$String
+ x := Qrest x
+ if not Qnull x then s := concat(s, ", ")$String
+ concat(s, " \right]")$String
+
+ member?(s,x) ==
+ while not Qnull x repeat
+ if s = Qfirst x then return true else x := Qrest x
+ false
+
+ -- Lots of code from parts of AGGCAT, repeated here to
+ -- get faster compilation
+ concat_!(x:%,y:%) ==
+ Qnull x =>
+ Qnull y => x
+ Qpush(first y,x)
+ QRPLACD(x,rest y)$Lisp
+ x
+ z:=x
+ while not Qnull Qrest z repeat
+ z:=Qrest z
+ QRPLACD(z,y)$Lisp
+ x
+
+ -- Then a quicky:
+ if S has SetCategory then
+ removeDuplicates_! l ==
+ p := l
+ while not Qnull p repeat
+-- p := setrest_!(p, remove_!(#1 = Qfirst p, Qrest p))
+-- far too expensive - builds closures etc.
+ pp:=p
+ f:S:=Qfirst p
+ p:=Qrest p
+ while not Qnull (pr:=Qrest pp) repeat
+ if (Qfirst pr)@S = f then QRPLACD(pp,Qrest pr)$Lisp
+ else pp:=pr
+ l
+
+ -- then sorting
+ mergeSort: ((S, S) -> Boolean, %, Integer) -> %
+
+ sort_!(f, l) == mergeSort(f, l, #l)
+
+ merge_!(f, p, q) ==
+ Qnull p => q
+ Qnull q => p
+ Qeq(p, q) => error "cannot merge a list into itself"
+ if f(Qfirst p, Qfirst q)
+ then (r := t := p; p := Qrest p)
+ else (r := t := q; q := Qrest q)
+ while not Qnull p and not Qnull q repeat
+ if f(Qfirst p, Qfirst q)
+ then (QRPLACD(t, p)$Lisp; t := p; p := Qrest p)
+ else (QRPLACD(t, q)$Lisp; t := q; q := Qrest q)
+ QRPLACD(t, if Qnull p then q else p)$Lisp
+ r
+
+ split_!(p, n) ==
+ n < 1 => error "index out of range"
+ p := rest(p, (n - 1)::NonNegativeInteger)
+ q := Qrest p
+ QRPLACD(p, NIL$Lisp)$Lisp
+ q
+
+ mergeSort(f, p, n) ==
+ if n = 2 and f(first rest p, first p) then p := reverse_! p
+ n < 3 => p
+ l := (n quo 2)::NonNegativeInteger
+ q := split_!(p, l)
+ p := mergeSort(f, p, l)
+ q := mergeSort(f, q, n - l)
+ merge_!(f, p, q)
+
+@
+\section{ILIST.lsp BOOTSTRAP}
+{\bf ILIST} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf ILIST} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf ILIST.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ILIST.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |ILIST;#;$Nni;1|) (QUOTE |SPADreplace|) (QUOTE LENGTH))
+
+(DEFUN |ILIST;#;$Nni;1| (|x| |$|) (LENGTH |x|))
+
+(PUT (QUOTE |ILIST;concat;S2$;2|) (QUOTE |SPADreplace|) (QUOTE CONS))
+
+(DEFUN |ILIST;concat;S2$;2| (|s| |x| |$|) (CONS |s| |x|))
+
+(PUT (QUOTE |ILIST;eq?;2$B;3|) (QUOTE |SPADreplace|) (QUOTE EQ))
+
+(DEFUN |ILIST;eq?;2$B;3| (|x| |y| |$|) (EQ |x| |y|))
+
+(PUT (QUOTE |ILIST;first;$S;4|) (QUOTE |SPADreplace|) (QUOTE |SPADfirst|))
+
+(DEFUN |ILIST;first;$S;4| (|x| |$|) (|SPADfirst| |x|))
+
+(PUT (QUOTE |ILIST;elt;$firstS;5|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x| "first") (|SPADfirst| |x|))))
+
+(DEFUN |ILIST;elt;$firstS;5| (|x| G101995 |$|) (|SPADfirst| |x|))
+
+(PUT (QUOTE |ILIST;empty;$;6|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL NIL)))
+
+(DEFUN |ILIST;empty;$;6| (|$|) NIL)
+
+(PUT (QUOTE |ILIST;empty?;$B;7|) (QUOTE |SPADreplace|) (QUOTE NULL))
+
+(DEFUN |ILIST;empty?;$B;7| (|x| |$|) (NULL |x|))
+
+(PUT (QUOTE |ILIST;rest;2$;8|) (QUOTE |SPADreplace|) (QUOTE CDR))
+
+(DEFUN |ILIST;rest;2$;8| (|x| |$|) (CDR |x|))
+
+(PUT (QUOTE |ILIST;elt;$rest$;9|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x| "rest") (CDR |x|))))
+
+(DEFUN |ILIST;elt;$rest$;9| (|x| G102000 |$|) (CDR |x|))
+
+(DEFUN |ILIST;setfirst!;$2S;10| (|x| |s| |$|) (COND ((SPADCALL |x| (QREFELT |$| 17)) (|error| "Cannot update an empty list")) ((QUOTE T) (QCAR (RPLACA |x| |s|)))))
+
+(DEFUN |ILIST;setelt;$first2S;11| (|x| G102005 |s| |$|) (COND ((SPADCALL |x| (QREFELT |$| 17)) (|error| "Cannot update an empty list")) ((QUOTE T) (QCAR (RPLACA |x| |s|)))))
+
+(DEFUN |ILIST;setrest!;3$;12| (|x| |y| |$|) (COND ((SPADCALL |x| (QREFELT |$| 17)) (|error| "Cannot update an empty list")) ((QUOTE T) (QCDR (RPLACD |x| |y|)))))
+
+(DEFUN |ILIST;setelt;$rest2$;13| (|x| G102010 |y| |$|) (COND ((SPADCALL |x| (QREFELT |$| 17)) (|error| "Cannot update an empty list")) ((QUOTE T) (QCDR (RPLACD |x| |y|)))))
+
+(PUT (QUOTE |ILIST;construct;L$;14|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|l|) |l|)))
+
+(DEFUN |ILIST;construct;L$;14| (|l| |$|) |l|)
+
+(PUT (QUOTE |ILIST;parts;$L;15|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|s|) |s|)))
+
+(DEFUN |ILIST;parts;$L;15| (|s| |$|) |s|)
+
+(PUT (QUOTE |ILIST;reverse!;2$;16|) (QUOTE |SPADreplace|) (QUOTE NREVERSE))
+
+(DEFUN |ILIST;reverse!;2$;16| (|x| |$|) (NREVERSE |x|))
+
+(PUT (QUOTE |ILIST;reverse;2$;17|) (QUOTE |SPADreplace|) (QUOTE REVERSE))
+
+(DEFUN |ILIST;reverse;2$;17| (|x| |$|) (REVERSE |x|))
+
+(DEFUN |ILIST;minIndex;$I;18| (|x| |$|) (QREFELT |$| 7))
+
+(DEFUN |ILIST;rest;$Nni$;19| (|x| |n| |$|) (PROG (|i|) (RETURN (SEQ (SEQ (LETT |i| 1 |ILIST;rest;$Nni$;19|) G190 (COND ((QSGREATERP |i| |n|) (GO G191))) (SEQ (COND ((NULL |x|) (|error| "index out of range"))) (EXIT (LETT |x| (QCDR |x|) |ILIST;rest;$Nni$;19|))) (LETT |i| (QSADD1 |i|) |ILIST;rest;$Nni$;19|) (GO G190) G191 (EXIT NIL)) (EXIT |x|)))))
+
+(DEFUN |ILIST;copy;2$;20| (|x| |$|) (PROG (|i| |y|) (RETURN (SEQ (LETT |y| (SPADCALL (QREFELT |$| 16)) |ILIST;copy;2$;20|) (SEQ (LETT |i| 0 |ILIST;copy;2$;20|) G190 (COND ((NULL (COND ((NULL |x|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((EQ |i| 1000) (COND ((SPADCALL |x| (QREFELT |$| 33)) (|error| "cyclic list"))))) (LETT |y| (CONS (QCAR |x|) |y|) |ILIST;copy;2$;20|) (EXIT (LETT |x| (QCDR |x|) |ILIST;copy;2$;20|))) (LETT |i| (QSADD1 |i|) |ILIST;copy;2$;20|) (GO G190) G191 (EXIT NIL)) (EXIT (NREVERSE |y|))))))
+
+(DEFUN |ILIST;coerce;$Of;21| (|x| |$|) (PROG (|s| |y| |z|) (RETURN (SEQ (LETT |y| NIL |ILIST;coerce;$Of;21|) (LETT |s| (SPADCALL |x| (QREFELT |$| 35)) |ILIST;coerce;$Of;21|) (SEQ G190 (COND ((NULL (NEQ |x| |s|)) (GO G191))) (SEQ (LETT |y| (CONS (SPADCALL (SPADCALL |x| (QREFELT |$| 13)) (QREFELT |$| 37)) |y|) |ILIST;coerce;$Of;21|) (EXIT (LETT |x| (SPADCALL |x| (QREFELT |$| 18)) |ILIST;coerce;$Of;21|))) NIL (GO G190) G191 (EXIT NIL)) (LETT |y| (NREVERSE |y|) |ILIST;coerce;$Of;21|) (EXIT (COND ((SPADCALL |s| (QREFELT |$| 17)) (SPADCALL |y| (QREFELT |$| 39))) ((QUOTE T) (SEQ (LETT |z| (SPADCALL (SPADCALL (SPADCALL |x| (QREFELT |$| 13)) (QREFELT |$| 37)) (QREFELT |$| 41)) |ILIST;coerce;$Of;21|) (SEQ G190 (COND ((NULL (NEQ |s| (SPADCALL |x| (QREFELT |$| 18)))) (GO G191))) (SEQ (LETT |x| (SPADCALL |x| (QREFELT |$| 18)) |ILIST;coerce;$Of;21|) (EXIT (LETT |z| (CONS (SPADCALL (SPADCALL |x| (QREFELT |$| 13)) (QREFELT |$| 37)) |z|) |ILIST;coerce;$Of;21|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL (SPADCALL |y| (SPADCALL (SPADCALL (NREVERSE |z|) (QREFELT |$| 42)) (QREFELT |$| 43)) (QREFELT |$| 44)) (QREFELT |$| 39)))))))))))
+
+(DEFUN |ILIST;=;2$B;22| (|x| |y| |$|) (PROG (#1=#:G102042) (RETURN (SEQ (EXIT (COND ((EQ |x| |y|) (QUOTE T)) ((QUOTE T) (SEQ (SEQ G190 (COND ((NULL (COND ((OR (NULL |x|) (NULL |y|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((NULL (SPADCALL (QCAR |x|) (QCAR |y|) (QREFELT |$| 46))) (PROGN (LETT #1# (QUOTE NIL) |ILIST;=;2$B;22|) (GO #1#))) ((QUOTE T) (SEQ (LETT |x| (QCDR |x|) |ILIST;=;2$B;22|) (EXIT (LETT |y| (QCDR |y|) |ILIST;=;2$B;22|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((NULL |x|) (NULL |y|)) ((QUOTE T) (QUOTE NIL)))))))) #1# (EXIT #1#)))))
+
+(DEFUN |ILIST;latex;$S;23| (|x| |$|) (PROG (|s|) (RETURN (SEQ (LETT |s| "\\left[" |ILIST;latex;$S;23|) (SEQ G190 (COND ((NULL (COND ((NULL |x|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |s| (STRCONC |s| (SPADCALL (QCAR |x|) (QREFELT |$| 49))) |ILIST;latex;$S;23|) (LETT |x| (QCDR |x|) |ILIST;latex;$S;23|) (EXIT (COND ((NULL (NULL |x|)) (LETT |s| (STRCONC |s| ", ") |ILIST;latex;$S;23|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (STRCONC |s| " \\right]"))))))
+
+(DEFUN |ILIST;member?;S$B;24| (|s| |x| |$|) (PROG (#1=#:G102052) (RETURN (SEQ (EXIT (SEQ (SEQ G190 (COND ((NULL (COND ((NULL |x|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL |s| (QCAR |x|) (QREFELT |$| 46)) (PROGN (LETT #1# (QUOTE T) |ILIST;member?;S$B;24|) (GO #1#))) ((QUOTE T) (LETT |x| (QCDR |x|) |ILIST;member?;S$B;24|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (QUOTE NIL)))) #1# (EXIT #1#)))))
+
+(DEFUN |ILIST;concat!;3$;25| (|x| |y| |$|) (PROG (|z|) (RETURN (SEQ (COND ((NULL |x|) (COND ((NULL |y|) |x|) ((QUOTE T) (SEQ (PUSH (SPADCALL |y| (QREFELT |$| 13)) |x|) (QRPLACD |x| (SPADCALL |y| (QREFELT |$| 18))) (EXIT |x|))))) ((QUOTE T) (SEQ (LETT |z| |x| |ILIST;concat!;3$;25|) (SEQ G190 (COND ((NULL (COND ((NULL (QCDR |z|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |z| (QCDR |z|) |ILIST;concat!;3$;25|))) NIL (GO G190) G191 (EXIT NIL)) (QRPLACD |z| |y|) (EXIT |x|))))))))
+
+(DEFUN |ILIST;removeDuplicates!;2$;26| (|l| |$|) (PROG (|f| |p| |pr| |pp|) (RETURN (SEQ (LETT |p| |l| |ILIST;removeDuplicates!;2$;26|) (SEQ G190 (COND ((NULL (COND ((NULL |p|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |pp| |p| |ILIST;removeDuplicates!;2$;26|) (LETT |f| (QCAR |p|) |ILIST;removeDuplicates!;2$;26|) (LETT |p| (QCDR |p|) |ILIST;removeDuplicates!;2$;26|) (EXIT (SEQ G190 (COND ((NULL (COND ((NULL (LETT |pr| (QCDR |pp|) |ILIST;removeDuplicates!;2$;26|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (QCAR |pr|) |f| (QREFELT |$| 46)) (QRPLACD |pp| (QCDR |pr|))) ((QUOTE T) (LETT |pp| |pr| |ILIST;removeDuplicates!;2$;26|))))) NIL (GO G190) G191 (EXIT NIL)))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |l|)))))
+
+(DEFUN |ILIST;sort!;M2$;27| (|f| |l| |$|) (|ILIST;mergeSort| |f| |l| (SPADCALL |l| (QREFELT |$| 9)) |$|))
+
+(DEFUN |ILIST;merge!;M3$;28| (|f| |p| |q| |$|) (PROG (|r| |t|) (RETURN (SEQ (COND ((NULL |p|) |q|) ((NULL |q|) |p|) ((EQ |p| |q|) (|error| "cannot merge a list into itself")) ((QUOTE T) (SEQ (COND ((SPADCALL (QCAR |p|) (QCAR |q|) |f|) (SEQ (LETT |r| (LETT |t| |p| |ILIST;merge!;M3$;28|) |ILIST;merge!;M3$;28|) (EXIT (LETT |p| (QCDR |p|) |ILIST;merge!;M3$;28|)))) ((QUOTE T) (SEQ (LETT |r| (LETT |t| |q| |ILIST;merge!;M3$;28|) |ILIST;merge!;M3$;28|) (EXIT (LETT |q| (QCDR |q|) |ILIST;merge!;M3$;28|))))) (SEQ G190 (COND ((NULL (COND ((OR (NULL |p|) (NULL |q|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (QCAR |p|) (QCAR |q|) |f|) (SEQ (QRPLACD |t| |p|) (LETT |t| |p| |ILIST;merge!;M3$;28|) (EXIT (LETT |p| (QCDR |p|) |ILIST;merge!;M3$;28|)))) ((QUOTE T) (SEQ (QRPLACD |t| |q|) (LETT |t| |q| |ILIST;merge!;M3$;28|) (EXIT (LETT |q| (QCDR |q|) |ILIST;merge!;M3$;28|))))))) NIL (GO G190) G191 (EXIT NIL)) (QRPLACD |t| (COND ((NULL |p|) |q|) ((QUOTE T) |p|))) (EXIT |r|))))))))
+
+(DEFUN |ILIST;split!;$I$;29| (|p| |n| |$|) (PROG (#1=#:G102085 |q|) (RETURN (SEQ (COND ((|<| |n| 1) (|error| "index out of range")) ((QUOTE T) (SEQ (LETT |p| (SPADCALL |p| (PROG1 (LETT #1# (|-| |n| 1) |ILIST;split!;$I$;29|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 32)) |ILIST;split!;$I$;29|) (LETT |q| (QCDR |p|) |ILIST;split!;$I$;29|) (QRPLACD |p| NIL) (EXIT |q|))))))))
+
+(DEFUN |ILIST;mergeSort| (|f| |p| |n| |$|) (PROG (#1=#:G102089 |l| |q|) (RETURN (SEQ (COND ((EQL |n| 2) (COND ((SPADCALL (SPADCALL (SPADCALL |p| (QREFELT |$| 18)) (QREFELT |$| 13)) (SPADCALL |p| (QREFELT |$| 13)) |f|) (LETT |p| (SPADCALL |p| (QREFELT |$| 28)) |ILIST;mergeSort|))))) (EXIT (COND ((|<| |n| 3) |p|) ((QUOTE T) (SEQ (LETT |l| (PROG1 (LETT #1# (QUOTIENT2 |n| 2) |ILIST;mergeSort|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) |ILIST;mergeSort|) (LETT |q| (SPADCALL |p| |l| (QREFELT |$| 57)) |ILIST;mergeSort|) (LETT |p| (|ILIST;mergeSort| |f| |p| |l| |$|) |ILIST;mergeSort|) (LETT |q| (|ILIST;mergeSort| |f| |q| (|-| |n| |l|) |$|) |ILIST;mergeSort|) (EXIT (SPADCALL |f| |p| |q| (QREFELT |$| 56)))))))))))
+
+(DEFUN |IndexedList| (|&REST| #1=#:G102103 |&AUX| #2=#:G102101) (DSETQ #2# #1#) (PROG NIL (RETURN (PROG (#3=#:G102102) (RETURN (COND ((LETT #3# (|lassocShiftWithFunction| (|devaluateList| #2#) (HGET |$ConstructorCache| (QUOTE |IndexedList|)) (QUOTE |domainEqualList|)) |IndexedList|) (|CDRwithIncrement| #3#)) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (APPLY (|function| |IndexedList;|) #2#) (LETT #3# T |IndexedList|)) (COND ((NOT #3#) (HREM |$ConstructorCache| (QUOTE |IndexedList|))))))))))))
+
+(DEFUN |IndexedList;| (|#1| |#2|) (PROG (|DV$1| |DV$2| |dv$| |$| #1=#:G102100 |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #2=(|IndexedList|)) (LETT |DV$2| (|devaluate| |#2|) . #2#) (LETT |dv$| (LIST (QUOTE |IndexedList|) |DV$1| |DV$2|) . #2#) (LETT |$| (GETREFV 71) . #2#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#1| (QUOTE (|SetCategory|))) (|HasCategory| |#1| (QUOTE (|ConvertibleTo| (|InputForm|)))) (LETT #1# (|HasCategory| |#1| (QUOTE (|OrderedSet|))) . #2#) (OR #1# (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (|HasCategory| (|Integer|) (QUOTE (|OrderedSet|))) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (OR (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) #1#) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|))))))) . #2#)) (|haddProp| |$ConstructorCache| (QUOTE |IndexedList|) (LIST |DV$1| |DV$2|) (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 45 (CONS (|dispatchFunction| |ILIST;coerce;$Of;21|) |$|)) (QSETREFV |$| 47 (CONS (|dispatchFunction| |ILIST;=;2$B;22|) |$|)) (QSETREFV |$| 50 (CONS (|dispatchFunction| |ILIST;latex;$S;23|) |$|)) (QSETREFV |$| 51 (CONS (|dispatchFunction| |ILIST;member?;S$B;24|) |$|))))) (COND ((|testBitVector| |pv$| 1) (QSETREFV |$| 53 (CONS (|dispatchFunction| |ILIST;removeDuplicates!;2$;26|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |IndexedList|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|NonNegativeInteger|) |ILIST;#;$Nni;1| |ILIST;concat;S2$;2| (|Boolean|) |ILIST;eq?;2$B;3| |ILIST;first;$S;4| (QUOTE "first") |ILIST;elt;$firstS;5| |ILIST;empty;$;6| |ILIST;empty?;$B;7| |ILIST;rest;2$;8| (QUOTE "rest") |ILIST;elt;$rest$;9| |ILIST;setfirst!;$2S;10| |ILIST;setelt;$first2S;11| |ILIST;setrest!;3$;12| |ILIST;setelt;$rest2$;13| (|List| 6) |ILIST;construct;L$;14| |ILIST;parts;$L;15| |ILIST;reverse!;2$;16| |ILIST;reverse;2$;17| (|Integer|) |ILIST;minIndex;$I;18| |ILIST;rest;$Nni$;19| (0 . |cyclic?|) |ILIST;copy;2$;20| (5 . |cycleEntry|) (|OutputForm|) (10 . |coerce|) (|List| |$|) (15 . |bracket|) (|List| 36) (20 . |list|) (25 . |commaSeparate|) (30 . |overbar|) (35 . |concat!|) (41 . |coerce|) (46 . |=|) (52 . |=|) (|String|) (58 . |latex|) (63 . |latex|) (68 . |member?|) |ILIST;concat!;3$;25| (74 . |removeDuplicates!|) (|Mapping| 11 6 6) |ILIST;sort!;M2$;27| |ILIST;merge!;M3$;28| |ILIST;split!;$I$;29| (|Mapping| 6 6 6) (|Equation| 6) (|List| 59) (|Mapping| 11 6) (|Void|) (|UniversalSegment| 30) (QUOTE "last") (QUOTE "value") (|Mapping| 6 6) (|InputForm|) (|SingleInteger|) (|List| 30) (|Union| 6 (QUOTE "failed")))) (QUOTE #(|~=| 79 |value| 85 |third| 90 |tail| 95 |swap!| 100 |split!| 107 |sorted?| 113 |sort!| 124 |sort| 135 |size?| 146 |setvalue!| 152 |setrest!| 158 |setlast!| 164 |setfirst!| 170 |setelt| 176 |setchildren!| 218 |select!| 224 |select| 230 |second| 236 |sample| 241 |reverse!| 245 |reverse| 250 |rest| 255 |removeDuplicates!| 266 |removeDuplicates| 271 |remove!| 276 |remove| 288 |reduce| 300 |qsetelt!| 321 |qelt| 328 |possiblyInfinite?| 334 |position| 339 |parts| 358 |nodes| 363 |node?| 368 |new| 374 |more?| 380 |minIndex| 386 |min| 391 |merge!| 397 |merge| 410 |members| 423 |member?| 428 |maxIndex| 434 |max| 439 |map!| 445 |map| 451 |list| 464 |less?| 469 |leaves| 475 |leaf?| 480 |latex| 485 |last| 490 |insert!| 501 |insert| 515 |indices| 529 |index?| 534 |hash| 540 |first| 545 |find| 556 |fill!| 562 |explicitlyFinite?| 568 |every?| 573 |eval| 579 |eq?| 605 |entry?| 611 |entries| 617 |empty?| 622 |empty| 627 |elt| 631 |distance| 674 |delete!| 680 |delete| 692 |cyclic?| 704 |cycleTail| 709 |cycleSplit!| 714 |cycleLength| 719 |cycleEntry| 724 |count| 729 |copyInto!| 741 |copy| 748 |convert| 753 |construct| 758 |concat!| 763 |concat| 775 |coerce| 798 |children| 803 |child?| 808 |any?| 814 |>=| 820 |>| 826 |=| 832 |<=| 838 |<| 844 |#| 850)) (QUOTE ((|shallowlyMutable| . 0) (|finiteAggregate| . 0))) (CONS (|makeByteWordVec2| 7 (QUOTE (0 0 0 0 0 0 0 0 0 0 3 0 0 7 4 0 0 7 1 2 4))) (CONS (QUOTE #(|ListAggregate&| |StreamAggregate&| |ExtensibleLinearAggregate&| |FiniteLinearAggregate&| |UnaryRecursiveAggregate&| |LinearAggregate&| |RecursiveAggregate&| |IndexedAggregate&| |Collection&| |HomogeneousAggregate&| |OrderedSet&| |Aggregate&| |EltableAggregate&| |Evalable&| |SetCategory&| NIL NIL |InnerEvalable&| NIL NIL |BasicType&|)) (CONS (QUOTE #((|ListAggregate| 6) (|StreamAggregate| 6) (|ExtensibleLinearAggregate| 6) (|FiniteLinearAggregate| 6) (|UnaryRecursiveAggregate| 6) (|LinearAggregate| 6) (|RecursiveAggregate| 6) (|IndexedAggregate| 30 6) (|Collection| 6) (|HomogeneousAggregate| 6) (|OrderedSet|) (|Aggregate|) (|EltableAggregate| 30 6) (|Evalable| 6) (|SetCategory|) (|Type|) (|Eltable| 30 6) (|InnerEvalable| 6 6) (|CoercibleTo| 36) (|ConvertibleTo| 67) (|BasicType|))) (|makeByteWordVec2| 70 (QUOTE (1 0 11 0 33 1 0 0 0 35 1 6 36 0 37 1 36 0 38 39 1 40 0 36 41 1 36 0 38 42 1 36 0 0 43 2 40 0 0 36 44 1 0 36 0 45 2 6 11 0 0 46 2 0 11 0 0 47 1 6 48 0 49 1 0 48 0 50 2 0 11 6 0 51 1 0 0 0 53 2 1 11 0 0 1 1 0 6 0 1 1 0 6 0 1 1 0 0 0 1 3 0 62 0 30 30 1 2 0 0 0 30 57 1 3 11 0 1 2 0 11 54 0 1 1 3 0 0 1 2 0 0 54 0 55 1 3 0 0 1 2 0 0 54 0 1 2 0 11 0 8 1 2 0 6 0 6 1 2 0 0 0 0 23 2 0 6 0 6 1 2 0 6 0 6 21 3 0 6 0 30 6 1 3 0 6 0 63 6 1 3 0 6 0 64 6 1 3 0 0 0 19 0 24 3 0 6 0 14 6 22 3 0 6 0 65 6 1 2 0 0 0 38 1 2 0 0 61 0 1 2 0 0 61 0 1 1 0 6 0 1 0 0 0 1 1 0 0 0 28 1 0 0 0 29 2 0 0 0 8 32 1 0 0 0 18 1 1 0 0 53 1 1 0 0 1 2 1 0 6 0 1 2 0 0 61 0 1 2 1 0 6 0 1 2 0 0 61 0 1 4 1 6 58 0 6 6 1 2 0 6 58 0 1 3 0 6 58 0 6 1 3 0 6 0 30 6 1 2 0 6 0 30 1 1 0 11 0 1 2 1 30 6 0 1 3 1 30 6 0 30 1 2 0 30 61 0 1 1 0 25 0 27 1 0 38 0 1 2 1 11 0 0 1 2 0 0 8 6 1 2 0 11 0 8 1 1 5 30 0 31 2 3 0 0 0 1 2 3 0 0 0 1 3 0 0 54 0 0 56 2 3 0 0 0 1 3 0 0 54 0 0 1 1 0 25 0 1 2 1 11 6 0 51 1 5 30 0 1 2 3 0 0 0 1 2 0 0 66 0 1 3 0 0 58 0 0 1 2 0 0 66 0 1 1 0 0 6 1 2 0 11 0 8 1 1 0 25 0 1 1 0 11 0 1 1 1 48 0 50 2 0 0 0 8 1 1 0 6 0 1 3 0 0 6 0 30 1 3 0 0 0 0 30 1 3 0 0 0 0 30 1 3 0 0 6 0 30 1 1 0 69 0 1 2 0 11 30 0 1 1 1 68 0 1 2 0 0 0 8 1 1 0 6 0 13 2 0 70 61 0 1 2 0 0 0 6 1 1 0 11 0 1 2 0 11 61 0 1 3 6 0 0 6 6 1 3 6 0 0 25 25 1 2 6 0 0 59 1 2 6 0 0 60 1 2 0 11 0 0 12 2 1 11 6 0 1 1 0 25 0 1 1 0 11 0 17 0 0 0 16 2 0 6 0 30 1 3 0 6 0 30 6 1 2 0 0 0 63 1 2 0 6 0 64 1 2 0 0 0 19 20 2 0 6 0 14 15 2 0 6 0 65 1 2 0 30 0 0 1 2 0 0 0 63 1 2 0 0 0 30 1 2 0 0 0 63 1 2 0 0 0 30 1 1 0 11 0 33 1 0 0 0 1 1 0 0 0 1 1 0 8 0 1 1 0 0 0 35 2 1 8 6 0 1 2 0 8 61 0 1 3 0 0 0 0 30 1 1 0 0 0 34 1 2 67 0 1 1 0 0 25 26 2 0 0 0 0 52 2 0 0 0 6 1 1 0 0 38 1 2 0 0 0 6 1 2 0 0 6 0 10 2 0 0 0 0 1 1 1 36 0 45 1 0 38 0 1 2 1 11 0 0 1 2 0 11 61 0 1 2 3 11 0 0 1 2 3 11 0 0 1 2 1 11 0 0 47 2 3 11 0 0 1 2 3 11 0 0 1 1 0 8 0 9)))))) (QUOTE |lookupComplete|)))
+@
+\section{domain LIST List}
+<<domain LIST List>>=
+)abbrev domain LIST List
+++ Author: Michael Monagan
+++ Date Created: Sep 1987
+++ Change History:
+++ Basic Operations:
+++ \#, append, concat, concat!, cons, construct, copy, elt, elt,
+++ empty, empty?, eq?, first, member?, merge!, mergeSort, minIndex,
+++ nil, null, parts, removeDuplicates!, rest, rest, reverse,
+++ reverse!, setDifference, setIntersection, setUnion, setelt,
+++ setfirst!, setrest!, sort!, split!
+++ Related Constructors: ListFunctions2, ListFunctions3, ListToMap
+++ Also See: IndexList, ListAggregate
+++ AMS Classification:
+++ Keywords: list, index, aggregate, lisp
+++ Description:
+++ \spadtype{List} implements singly-linked lists that are
+++ addressable by indices; the index of the first element
+++ is 1. In addition to the operations provided by
+++ \spadtype{IndexedList}, this constructor provides some
+++ LISP-like functions such as \spadfun{null} and \spadfun{cons}.
+List(S:Type): Exports == Implementation where
+ LISTMININDEX ==> 1 -- this is the minimum list index
+
+ Exports ==> ListAggregate S with
+ nil : () -> %
+ ++ nil() returns the empty list.
+ null : % -> Boolean
+ ++ null(u) tests if list \spad{u} is the
+ ++ empty list.
+ cons : (S, %) -> %
+ ++ cons(element,u) appends \spad{element} onto the front
+ ++ of list \spad{u} and returns the new list. This new list
+ ++ and the old one will share some structure.
+ append : (%, %) -> %
+ ++ append(u1,u2) appends the elements of list \spad{u1}
+ ++ onto the front of list \spad{u2}. This new list
+ ++ and \spad{u2} will share some structure.
+ if S has SetCategory then
+ setUnion : (%, %) -> %
+ ++ setUnion(u1,u2) appends the two lists u1 and u2, then
+ ++ removes all duplicates. The order of elements in the
+ ++ resulting list is unspecified.
+ setIntersection : (%, %) -> %
+ ++ setIntersection(u1,u2) returns a list of the elements
+ ++ that lists \spad{u1} and \spad{u2} have in common.
+ ++ The order of elements in the resulting list is unspecified.
+ setDifference : (%, %) -> %
+ ++ setDifference(u1,u2) returns a list of the elements
+ ++ of \spad{u1} that are not also in \spad{u2}.
+ ++ The order of elements in the resulting list is unspecified.
+ if S has OpenMath then OpenMath
+
+ Implementation ==>
+ IndexedList(S, LISTMININDEX) add
+ nil() == NIL$Lisp
+ null l == NULL(l)$Lisp
+ cons(s, l) == CONS(s, l)$Lisp
+ append(l:%, t:%) == APPEND(l, t)$Lisp
+
+ if S has OpenMath then
+ writeOMList(dev: OpenMathDevice, x: %): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "list1", "list")
+ -- The following didn't compile because the compiler isn't
+ -- convinced that `xval' is a S. Duhhh! MCD.
+ --for xval in x repeat
+ -- OMwrite(dev, xval, false)
+ while not null x repeat
+ OMwrite(dev,first x,false)
+ x := rest x
+ OMputEndApp(dev)
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMList(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMList(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMList(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMList(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ if S has SetCategory then
+ setUnion(l1:%,l2:%) == removeDuplicates concat(l1,l2)
+
+ setIntersection(l1:%,l2:%) ==
+ u :% := empty()
+ l1 := removeDuplicates l1
+ while not empty? l1 repeat
+ if member?(first l1,l2) then u := cons(first l1,u)
+ l1 := rest l1
+ u
+
+ setDifference(l1:%,l2:%) ==
+ l1 := removeDuplicates l1
+ lu:% := empty()
+ while not empty? l1 repeat
+ l11:=l1.1
+ if not member?(l11,l2) then lu := concat(l11,lu)
+ l1 := rest l1
+ lu
+
+ if S has ConvertibleTo InputForm then
+ convert(x:%):InputForm ==
+ convert concat(convert("construct"::Symbol)@InputForm,
+ [convert a for a in (x pretend List S)]$List(InputForm))
+
+@
+\section{LIST.lsp BOOTSTRAP}
+{\bf LIST} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf LIST} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf LIST.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<LIST.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |LIST;nil;$;1|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL NIL)))
+
+(DEFUN |LIST;nil;$;1| (|$|) NIL)
+
+(PUT (QUOTE |LIST;null;$B;2|) (QUOTE |SPADreplace|) (QUOTE NULL))
+
+(DEFUN |LIST;null;$B;2| (|l| |$|) (NULL |l|))
+
+(PUT (QUOTE |LIST;cons;S2$;3|) (QUOTE |SPADreplace|) (QUOTE CONS))
+
+(DEFUN |LIST;cons;S2$;3| (|s| |l| |$|) (CONS |s| |l|))
+
+(PUT (QUOTE |LIST;append;3$;4|) (QUOTE |SPADreplace|) (QUOTE APPEND))
+
+(DEFUN |LIST;append;3$;4| (|l| |t| |$|) (APPEND |l| |t|))
+
+(DEFUN |LIST;writeOMList| (|dev| |x| |$|) (SEQ (SPADCALL |dev| (QREFELT |$| 14)) (SPADCALL |dev| "list1" "list" (QREFELT |$| 16)) (SEQ G190 (COND ((NULL (COND ((NULL |x|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (SPADCALL |dev| (|SPADfirst| |x|) (QUOTE NIL) (QREFELT |$| 17)) (EXIT (LETT |x| (CDR |x|) |LIST;writeOMList|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |dev| (QREFELT |$| 18)))))
+
+(DEFUN |LIST;OMwrite;$S;6| (|x| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |LIST;OMwrite;$S;6|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |LIST;OMwrite;$S;6|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 20)) (QREFELT |$| 21)) |LIST;OMwrite;$S;6|) (SPADCALL |dev| (QREFELT |$| 22)) (|LIST;writeOMList| |dev| |x| |$|) (SPADCALL |dev| (QREFELT |$| 23)) (SPADCALL |dev| (QREFELT |$| 24)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |LIST;OMwrite;$S;6|) (EXIT |s|)))))
+
+(DEFUN |LIST;OMwrite;$BS;7| (|x| |wholeObj| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |LIST;OMwrite;$BS;7|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |LIST;OMwrite;$BS;7|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 20)) (QREFELT |$| 21)) |LIST;OMwrite;$BS;7|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 22)))) (|LIST;writeOMList| |dev| |x| |$|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 23)))) (SPADCALL |dev| (QREFELT |$| 24)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |LIST;OMwrite;$BS;7|) (EXIT |s|)))))
+
+(DEFUN |LIST;OMwrite;Omd$V;8| (|dev| |x| |$|) (SEQ (SPADCALL |dev| (QREFELT |$| 22)) (|LIST;writeOMList| |dev| |x| |$|) (EXIT (SPADCALL |dev| (QREFELT |$| 23)))))
+
+(DEFUN |LIST;OMwrite;Omd$BV;9| (|dev| |x| |wholeObj| |$|) (SEQ (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 22)))) (|LIST;writeOMList| |dev| |x| |$|) (EXIT (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 23)))))))
+
+(DEFUN |LIST;setUnion;3$;10| (|l1| |l2| |$|) (SPADCALL (SPADCALL |l1| |l2| (QREFELT |$| 29)) (QREFELT |$| 30)))
+
+(DEFUN |LIST;setIntersection;3$;11| (|l1| |l2| |$|) (PROG (|u|) (RETURN (SEQ (LETT |u| NIL |LIST;setIntersection;3$;11|) (LETT |l1| (SPADCALL |l1| (QREFELT |$| 30)) |LIST;setIntersection;3$;11|) (SEQ G190 (COND ((NULL (COND ((NULL |l1|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (COND ((SPADCALL (|SPADfirst| |l1|) |l2| (QREFELT |$| 32)) (LETT |u| (CONS (|SPADfirst| |l1|) |u|) |LIST;setIntersection;3$;11|))) (EXIT (LETT |l1| (CDR |l1|) |LIST;setIntersection;3$;11|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |u|)))))
+
+(DEFUN |LIST;setDifference;3$;12| (|l1| |l2| |$|) (PROG (|l11| |lu|) (RETURN (SEQ (LETT |l1| (SPADCALL |l1| (QREFELT |$| 30)) |LIST;setDifference;3$;12|) (LETT |lu| NIL |LIST;setDifference;3$;12|) (SEQ G190 (COND ((NULL (COND ((NULL |l1|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |l11| (SPADCALL |l1| 1 (QREFELT |$| 35)) |LIST;setDifference;3$;12|) (COND ((NULL (SPADCALL |l11| |l2| (QREFELT |$| 32))) (LETT |lu| (CONS |l11| |lu|) |LIST;setDifference;3$;12|))) (EXIT (LETT |l1| (CDR |l1|) |LIST;setDifference;3$;12|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |lu|)))))
+
+(DEFUN |LIST;convert;$If;13| (|x| |$|) (PROG (#1=#:G102544 |a| #2=#:G102545) (RETURN (SEQ (SPADCALL (CONS (SPADCALL (SPADCALL "construct" (QREFELT |$| 38)) (QREFELT |$| 40)) (PROGN (LETT #1# NIL |LIST;convert;$If;13|) (SEQ (LETT |a| NIL |LIST;convert;$If;13|) (LETT #2# |x| |LIST;convert;$If;13|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |a| (CAR #2#) |LIST;convert;$If;13|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |a| (QREFELT |$| 41)) #1#) |LIST;convert;$If;13|))) (LETT #2# (CDR #2#) |LIST;convert;$If;13|) (GO G190) G191 (EXIT (NREVERSE0 #1#))))) (QREFELT |$| 43))))))
+
+(DEFUN |List| (#1=#:G102555) (PROG NIL (RETURN (PROG (#2=#:G102556) (RETURN (COND ((LETT #2# (|lassocShiftWithFunction| (LIST (|devaluate| #1#)) (HGET |$ConstructorCache| (QUOTE |List|)) (QUOTE |domainEqualList|)) |List|) (|CDRwithIncrement| #2#)) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (|List;| #1#) (LETT #2# T |List|)) (COND ((NOT #2#) (HREM |$ConstructorCache| (QUOTE |List|))))))))))))
+
+(DEFUN |List;| (|#1|) (PROG (|DV$1| |dv$| |$| #1=#:G102554 |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #2=(|List|)) (LETT |dv$| (LIST (QUOTE |List|) |DV$1|) . #2#) (LETT |$| (GETREFV 62) . #2#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#1| (QUOTE (|SetCategory|))) (|HasCategory| |#1| (QUOTE (|ConvertibleTo| (|InputForm|)))) (LETT #1# (|HasCategory| |#1| (QUOTE (|OrderedSet|))) . #2#) (OR #1# (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (|HasCategory| |#1| (QUOTE (|OpenMath|))) (|HasCategory| (|Integer|) (QUOTE (|OrderedSet|))) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (OR (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) #1#) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|))))))) . #2#)) (|haddProp| |$ConstructorCache| (QUOTE |List|) (LIST |DV$1|) (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (COND ((|testBitVector| |pv$| 5) (PROGN (QSETREFV |$| 25 (CONS (|dispatchFunction| |LIST;OMwrite;$S;6|) |$|)) (QSETREFV |$| 26 (CONS (|dispatchFunction| |LIST;OMwrite;$BS;7|) |$|)) (QSETREFV |$| 27 (CONS (|dispatchFunction| |LIST;OMwrite;Omd$V;8|) |$|)) (QSETREFV |$| 28 (CONS (|dispatchFunction| |LIST;OMwrite;Omd$BV;9|) |$|))))) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 31 (CONS (|dispatchFunction| |LIST;setUnion;3$;10|) |$|)) (QSETREFV |$| 33 (CONS (|dispatchFunction| |LIST;setIntersection;3$;11|) |$|)) (QSETREFV |$| 36 (CONS (|dispatchFunction| |LIST;setDifference;3$;12|) |$|))))) (COND ((|testBitVector| |pv$| 2) (QSETREFV |$| 44 (CONS (|dispatchFunction| |LIST;convert;$If;13|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |List|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL (|IndexedList| 6 (NRTEVAL 1)) (|local| |#1|) |LIST;nil;$;1| (|Boolean|) |LIST;null;$B;2| |LIST;cons;S2$;3| |LIST;append;3$;4| (|Void|) (|OpenMathDevice|) (0 . |OMputApp|) (|String|) (5 . |OMputSymbol|) (12 . |OMwrite|) (19 . |OMputEndApp|) (|OpenMathEncoding|) (24 . |OMencodingXML|) (28 . |OMopenString|) (34 . |OMputObject|) (39 . |OMputEndObject|) (44 . |OMclose|) (49 . |OMwrite|) (54 . |OMwrite|) (60 . |OMwrite|) (66 . |OMwrite|) (73 . |concat|) (79 . |removeDuplicates|) (84 . |setUnion|) (90 . |member?|) (96 . |setIntersection|) (|Integer|) (102 . |elt|) (108 . |setDifference|) (|Symbol|) (114 . |coerce|) (|InputForm|) (119 . |convert|) (124 . |convert|) (|List| |$|) (129 . |convert|) (134 . |convert|) (|Mapping| 6 6 6) (|NonNegativeInteger|) (|List| 6) (|List| 49) (|Equation| 6) (|Mapping| 8 6) (|Mapping| 8 6 6) (|UniversalSegment| 34) (QUOTE "last") (QUOTE "rest") (QUOTE "first") (QUOTE "value") (|Mapping| 6 6) (|SingleInteger|) (|OutputForm|) (|List| 34) (|Union| 6 (QUOTE "failed")))) (QUOTE #(|setUnion| 139 |setIntersection| 145 |setDifference| 151 |removeDuplicates| 157 |null| 162 |nil| 167 |member?| 171 |elt| 177 |convert| 183 |cons| 188 |concat| 194 |append| 200 |OMwrite| 206)) (QUOTE ((|shallowlyMutable| . 0) (|finiteAggregate| . 0))) (CONS (|makeByteWordVec2| 8 (QUOTE (0 0 0 0 0 0 0 0 0 0 3 0 0 8 4 0 0 8 1 2 4 5))) (CONS (QUOTE #(|ListAggregate&| |StreamAggregate&| |ExtensibleLinearAggregate&| |FiniteLinearAggregate&| |UnaryRecursiveAggregate&| |LinearAggregate&| |RecursiveAggregate&| |IndexedAggregate&| |Collection&| |HomogeneousAggregate&| |OrderedSet&| |Aggregate&| |EltableAggregate&| |Evalable&| |SetCategory&| NIL NIL |InnerEvalable&| NIL NIL |BasicType&| NIL)) (CONS (QUOTE #((|ListAggregate| 6) (|StreamAggregate| 6) (|ExtensibleLinearAggregate| 6) (|FiniteLinearAggregate| 6) (|UnaryRecursiveAggregate| 6) (|LinearAggregate| 6) (|RecursiveAggregate| 6) (|IndexedAggregate| 34 6) (|Collection| 6) (|HomogeneousAggregate| 6) (|OrderedSet|) (|Aggregate|) (|EltableAggregate| 34 6) (|Evalable| 6) (|SetCategory|) (|Type|) (|Eltable| 34 6) (|InnerEvalable| 6 6) (|CoercibleTo| 59) (|ConvertibleTo| 39) (|BasicType|) (|OpenMath|))) (|makeByteWordVec2| 44 (QUOTE (1 13 12 0 14 3 13 12 0 15 15 16 3 6 12 13 0 8 17 1 13 12 0 18 0 19 0 20 2 13 0 15 19 21 1 13 12 0 22 1 13 12 0 23 1 13 12 0 24 1 0 15 0 25 2 0 15 0 8 26 2 0 12 13 0 27 3 0 12 13 0 8 28 2 0 0 0 0 29 1 0 0 0 30 2 0 0 0 0 31 2 0 8 6 0 32 2 0 0 0 0 33 2 0 6 0 34 35 2 0 0 0 0 36 1 37 0 15 38 1 39 0 37 40 1 6 39 0 41 1 39 0 42 43 1 0 39 0 44 2 1 0 0 0 31 2 1 0 0 0 33 2 1 0 0 0 36 1 1 0 0 30 1 0 8 0 9 0 0 0 7 2 1 8 6 0 32 2 0 6 0 34 35 1 2 39 0 44 2 0 0 6 0 10 2 0 0 0 0 29 2 0 0 0 0 11 3 5 12 13 0 8 28 2 5 12 13 0 27 1 5 15 0 25 2 5 15 0 8 26)))))) (QUOTE |lookupIncomplete|)))
+@
+\section{package LIST2 ListFunctions2}
+<<package LIST2 ListFunctions2>>=
+)abbrev package LIST2 ListFunctions2
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: map, reduce, scan
+++ Related Constructors: List
+++ Also See: ListFunctions3
+++ AMS Classification:
+++ Keywords: list, aggregate, map, reduce
+++ Description:
+++ \spadtype{ListFunctions2} implements utility functions that
+++ operate on two kinds of lists, each with a possibly different
+++ type of element.
+ListFunctions2(A:Type, B:Type): public == private where
+ LA ==> List A
+ LB ==> List B
+ O2 ==> FiniteLinearAggregateFunctions2(A, LA, B, LB)
+
+ public ==> with
+ scan: ((A, B) -> B, LA, B) -> LB
+ ++ scan(fn,u,ident) successively uses the binary function
+ ++ \spad{fn} to reduce more and more of list \spad{u}.
+ ++ \spad{ident} is returned if the \spad{u} is empty.
+ ++ The result is a list of the reductions at each step. See
+ ++ \spadfun{reduce} for more information. Examples:
+ ++ \spad{scan(fn,[1,2],0) = [fn(2,fn(1,0)),fn(1,0)]} and
+ ++ \spad{scan(*,[2,3],1) = [2 * 1, 3 * (2 * 1)]}.
+ reduce: ((A, B) -> B, LA, B) -> B
+ ++ reduce(fn,u,ident) successively uses the binary function
+ ++ \spad{fn} on the elements of list \spad{u} and the result
+ ++ of previous applications. \spad{ident} is returned if the
+ ++ \spad{u} is empty. Note the order of application in
+ ++ the following examples:
+ ++ \spad{reduce(fn,[1,2,3],0) = fn(3,fn(2,fn(1,0)))} and
+ ++ \spad{reduce(*,[2,3],1) = 3 * (2 * 1)}.
+ map: (A -> B, LA) -> LB
+ ++ map(fn,u) applies \spad{fn} to each element of
+ ++ list \spad{u} and returns a new list with the results.
+ ++ For example \spad{map(square,[1,2,3]) = [1,4,9]}.
+
+ private ==> add
+ map(f, l) == map(f, l)$O2
+ scan(f, l, b) == scan(f, l, b)$O2
+ reduce(f, l, b) == reduce(f, l, b)$O2
+
+@
+\section{package LIST3 ListFunctions3}
+<<package LIST3 ListFunctions3>>=
+)abbrev package LIST3 ListFunctions3
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: map
+++ Related Constructors: List
+++ Also See: ListFunctions2
+++ AMS Classification:
+++ Keywords: list, aggregate, map
+++ Description:
+++ \spadtype{ListFunctions3} implements utility functions that
+++ operate on three kinds of lists, each with a possibly different
+++ type of element.
+ListFunctions3(A:Type, B:Type, C:Type): public == private where
+ LA ==> List A
+ LB ==> List B
+ LC ==> List C
+
+ public ==> with
+ map: ( (A,B)->C, LA, LB) -> LC
+ ++ map(fn,list1, u2) applies the binary function \spad{fn}
+ ++ to corresponding elements of lists \spad{u1} and \spad{u2}
+ ++ and returns a list of the results (in the same order). Thus
+ ++ \spad{map(/,[1,2,3],[4,5,6]) = [1/4,2/4,1/2]}. The computation
+ ++ terminates when the end of either list is reached. That is,
+ ++ the length of the result list is equal to the minimum of the
+ ++ lengths of \spad{u1} and \spad{u2}.
+
+ private ==> add
+ map(fn : (A,B) -> C, la : LA, lb : LB): LC ==
+ empty?(la) or empty?(lb) => empty()$LC
+ concat(fn(first la, first lb), map(fn, rest la, rest lb))
+
+@
+\section{package LIST2MAP ListToMap}
+<<package LIST2MAP ListToMap>>=
+)abbrev package LIST2MAP ListToMap
+++ Author: Manuel Bronstein
+++ Date Created: 22 Mar 1988
+++ Change History:
+++ 11 Oct 1989 MB ?
+++ Basic Operations: match
+++ Related Constructors: List
+++ Also See:
+++ AMS Classification:
+++ Keywords: mapping, list
+++ Description:
+++ \spadtype{ListToMap} allows mappings to be described by a pair of
+++ lists of equal lengths. The image of an element \spad{x},
+++ which appears in position \spad{n} in the first list, is then
+++ the \spad{n}th element of the second list. A default value or
+++ default function can be specified to be used when \spad{x}
+++ does not appear in the first list. In the absence of defaults,
+++ an error will occur in that case.
+ListToMap(A:SetCategory, B:Type): Exports == Implementation where
+ LA ==> List A
+ LB ==> List B
+ AB ==> (A -> B)
+
+ Exports ==> with
+ match: (LA, LB ) -> AB
+ ++ match(la, lb) creates a map with no default source or target values
+ ++ defined by lists la and lb of equal length.
+ ++ The target of a source value \spad{x} in la is the
+ ++ value y with the same index lb.
+ ++ Error: if la and lb are not of equal length.
+ ++ Note: when this map is applied, an error occurs when
+ ++ applied to a value missing from la.
+ match: (LA, LB, A) -> B
+ ++ match(la, lb, a) creates a map
+ ++ defined by lists la and lb of equal length, where \spad{a} is used
+ ++ as the default source value if the given one is not in \spad{la}.
+ ++ The target of a source value \spad{x} in la is the
+ ++ value y with the same index lb.
+ ++ Error: if la and lb are not of equal length.
+ match: (LA, LB, B) -> AB
+ ++ match(la, lb, b) creates a map
+ ++ defined by lists la and lb of equal length, where \spad{b} is used
+ ++ as the default target value if the given function argument is
+ ++ not in \spad{la}.
+ ++ The target of a source value \spad{x} in la is the
+ ++ value y with the same index lb.
+ ++ Error: if la and lb are not of equal length.
+ match: (LA, LB, A, B) -> B
+ ++ match(la, lb, a, b) creates a map
+ ++ defined by lists la and lb of equal length.
+ ++ and applies this map to a.
+ ++ The target of a source value \spad{x} in la is the
+ ++ value y with the same index lb.
+ ++ Argument b is the default target value if a is not in la.
+ ++ Error: if la and lb are not of equal length.
+ match: (LA, LB, AB) -> AB
+ ++ match(la, lb, f) creates a map
+ ++ defined by lists la and lb of equal length.
+ ++ The target of a source value \spad{x} in la is the
+ ++ value y with the same index lb.
+ ++ Argument \spad{f} is used as the
+ ++ function to call when the given function argument is not in
+ ++ \spad{la}.
+ ++ The value returned is f applied to that argument.
+ match: (LA, LB, A, AB) -> B
+ ++ match(la, lb, a, f) creates a map
+ ++ defined by lists la and lb of equal length.
+ ++ and applies this map to a.
+ ++ The target of a source value \spad{x} in la is the
+ ++ value y with the same index lb.
+ ++ Argument \spad{f} is a default function to call if a is not in la.
+ ++ The value returned is then obtained by applying f to argument a.
+
+ Implementation ==> add
+ match(la, lb) == match(la, lb, #1)
+ match(la:LA, lb:LB, a:A) == lb.position(a, la)
+ match(la:LA, lb:LB, b:B) == match(la, lb, #1, b)
+ match(la:LA, lb:LB, f:AB) == match(la, lb, #1, f)
+
+ match(la:LA, lb:LB, a:A, b:B) ==
+ (p := position(a, la)) < minIndex(la) => b
+ lb.p
+
+ match(la:LA, lb:LB, a:A, f:AB) ==
+ (p := position(a, la)) < minIndex(la) => f a
+ lb.p
+
+@
+\section{domain ALIST AssociationList}
+<<domain ALIST AssociationList>>=
+)abbrev domain ALIST AssociationList
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: empty, empty?, keys, \#, concat, first, rest,
+++ setrest!, search, setelt, remove!
+++ Related Constructors:
+++ Also See: List
+++ AMS Classification:
+++ Keywords: list, association list
+++ Description:
+++ \spadtype{AssociationList} implements association lists. These
+++ may be viewed as lists of pairs where the first part is a key
+++ and the second is the stored value. For example, the key might
+++ be a string with a persons employee identification number and
+++ the value might be a record with personnel data.
+
+AssociationList(Key:SetCategory, Entry:SetCategory):
+ AssociationListAggregate(Key, Entry) == add
+ Pair ==> Record(key:Key, entry:Entry)
+ Rep := Reference List Pair
+
+ dictionary() == ref empty()
+ empty() == dictionary()
+ empty? t == empty? deref t
+ entries(t:%):List(Pair) == deref t
+ parts(t:%):List(Pair) == deref t
+ keys t == [k.key for k in deref t]
+ # t == # deref t
+ first(t:%):Pair == first deref t
+ rest t == ref rest deref t
+ concat(p:Pair, t:%) == ref concat(p, deref t)
+ setrest_!(a:%, b:%) == ref setrest_!(deref a, deref b)
+ setfirst_!(a:%, p:Pair) == setfirst_!(deref a,p)
+ minIndex(a:%):Integer == minIndex(deref a)
+ maxIndex(a:%):Integer == maxIndex(deref a)
+
+ search(k, t) ==
+ for r in deref t repeat
+ k = r.key => return(r.entry)
+ "failed"
+
+ latex(a : %) : String ==
+ l : List Pair := entries a
+ s : String := "\left["
+ while not empty?(l) repeat
+ r : Pair := first l
+ l := rest l
+ s := concat(s, concat(latex r.key, concat(" = ", latex r.entry)$String)$String)$String
+ if not empty?(l) then s := concat(s, ", ")$String
+ concat(s, " \right]")$String
+
+-- assoc(k, l) ==
+-- (r := find(#1.key=k, l)) case "failed" => "failed"
+-- r
+
+ assoc(k, t) ==
+ for r in deref t repeat
+ k = r.key => return r
+ "failed"
+
+ setelt(t:%, k:Key, e:Entry) ==
+ (r := assoc(k, t)) case Pair => (r::Pair).entry := e
+ setref(t, concat([k, e], deref t))
+ e
+
+ remove_!(k:Key, t:%) ==
+ empty?(l := deref t) => "failed"
+ k = first(l).key =>
+ setref(t, rest l)
+ first(l).entry
+ prev := l
+ curr := rest l
+ while not empty? curr and first(curr).key ^= k repeat
+ prev := curr
+ curr := rest curr
+ empty? curr => "failed"
+ setrest_!(prev, rest curr)
+ first(curr).entry
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ILIST IndexedList>>
+<<domain LIST List>>
+<<package LIST2 ListFunctions2>>
+<<package LIST3 ListFunctions3>>
+<<package LIST2MAP ListToMap>>
+<<domain ALIST AssociationList>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/listgcd.spad.pamphlet b/src/algebra/listgcd.spad.pamphlet
new file mode 100644
index 00000000..f626adbd
--- /dev/null
+++ b/src/algebra/listgcd.spad.pamphlet
@@ -0,0 +1,268 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra listgcd.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package HEUGCD HeuGcd}
+<<package HEUGCD HeuGcd>>=
+)abbrev package HEUGCD HeuGcd
+++ Author: P.Gianni
+++ Date Created:
+++ Date Last Updated: 13 September 94
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides the functions for the heuristic integer gcd.
+++ Geddes's algorithm,for univariate polynomials with integer coefficients
+HeuGcd (BP):C == T
+ where
+ BP : UnivariatePolynomialCategory Integer
+ Z ==> Integer
+ ContPrim ==> Record(cont:Z,prim:BP)
+
+
+ C == with
+ gcd : List BP -> BP
+ ++ gcd([f1,..,fk]) = gcd of the polynomials fi.
+ gcdprim : List BP -> BP
+ ++ gcdprim([f1,..,fk]) = gcd of k PRIMITIVE univariate polynomials
+ gcdcofact : List BP -> List BP
+ ++ gcdcofact([f1,..fk]) = gcd and cofactors of k univariate polynomials.
+ gcdcofactprim: List BP -> List BP
+ ++ gcdcofactprim([f1,..fk]) = gcd and cofactors of k
+ ++ primitive polynomials.
+ content : List BP -> List Z
+ ++ content([f1,..,fk]) = content of a list of univariate polynonials
+ lintgcd : List Z -> Z
+ ++ lintgcd([a1,..,ak]) = gcd of a list of integers
+
+ T == add
+
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ Cases ==> Union("gcdprim","gcd","gcdcofactprim","gcdcofact")
+ import ModularDistinctDegreeFactorizer BP
+
+ --local functions
+ localgcd : List BP -> List BP
+ constNotZero : BP -> Boolean
+ height : BP -> PI
+ genpoly : (Z,PI) -> BP
+ negShiftz : (Z,PI) -> Z
+ internal : (Cases,List BP ) -> List BP
+ constcase : (List NNI ,List BP ) -> List BP
+ lincase : (List NNI ,List BP ) -> List BP
+ myNextPrime : ( Z , NNI ) -> Z
+
+ bigPrime:= prevPrime(2**26)$IntegerPrimesPackage(Integer)
+
+ myNextPrime(val:Z,bound:NNI) : Z == nextPrime(val)$IntegerPrimesPackage(Z)
+
+ constNotZero(f : BP ) : Boolean == (degree f = 0) and ^(zero? f)
+
+ negShiftz(n:Z,Modulus:PI):Z ==
+ n < 0 => n:= n+Modulus
+ n > (Modulus quo 2) => n-Modulus
+ n
+
+ --compute the height of a polynomial
+ height(f:BP):PI ==
+ k:PI:=1
+ while f^=0 repeat
+ k:=max(k,abs(leadingCoefficient(f)@Z)::PI)
+ f:=reductum f
+ k
+
+ --reconstruct the polynomial from the value-adic representation of
+ --dval.
+ genpoly(dval:Z,value:PI):BP ==
+ d:=0$BP
+ val:=dval
+ for i in 0.. while (val^=0) repeat
+ val1:=negShiftz(val rem value,value)
+ d:= d+monomial(val1,i)
+ val:=(val-val1) quo value
+ d
+
+ --gcd of a list of integers
+ lintgcd(lval:List(Z)):Z ==
+ empty? lval => 0$Z
+ member?(1,lval) => 1$Z
+ lval:=sort(#1<#2,lval)
+ val:=lval.first
+ for val1 in lval.rest while ^(val=1) repeat val:=gcd(val,val1)
+ val
+
+ --content for a list of univariate polynomials
+ content(listf:List BP ):List(Z) ==
+ [lintgcd coefficients f for f in listf]
+
+ --content of a list of polynomials with the relative primitive parts
+ contprim(listf:List BP ):List(ContPrim) ==
+ [[c:=lintgcd coefficients f,(f exquo c)::BP]$ContPrim for f in listf]
+
+ -- one polynomial is constant, remark that they are primitive
+ -- but listf can contain the zero polynomial
+ constcase(listdeg:List NNI ,listf:List BP ): List BP ==
+ lind:=select(constNotZero,listf)
+ empty? lind =>
+ member?(1,listdeg) => lincase(listdeg,listf)
+ localgcd listf
+ or/[n>0 for n in listdeg] => cons(1$BP,listf)
+ lclistf:List(Z):= [leadingCoefficient f for f in listf]
+ d:=lintgcd(lclistf)
+ d=1 => cons(1$BP,listf)
+ cons(d::BP,[(lcf quo d)::BP for lcf in lclistf])
+
+ testDivide(listf: List BP, g:BP):Union(List BP, "failed") ==
+ result:List BP := []
+ for f in listf repeat
+ if (f1:=f exquo g) case "failed" then return "failed"
+ result := cons(f1::BP,result)
+ reverse!(result)
+
+ --one polynomial is linear, remark that they are primitive
+ lincase(listdeg:List NNI ,listf:List BP ):List BP ==
+ n:= position(1,listdeg)
+ g:=listf.n
+ result:=[g]
+ for f in listf repeat
+ if (f1:=f exquo g) case "failed" then return cons(1$BP,listf)
+ result := cons(f1::BP,result)
+ reverse(result)
+
+ IMG := InnerModularGcd(Z,BP,67108859,myNextPrime)
+
+ mindegpol(f:BP, g:BP):BP ==
+ degree(g) < degree (f) => g
+ f
+
+ --local function for the gcd among n PRIMITIVE univariate polynomials
+ localgcd(listf:List BP ):List BP ==
+ hgt:="min"/[height(f) for f in listf|^zero? f]
+ answr:=2+2*hgt
+ minf := "mindegpol"/[f for f in listf|^zero? f]
+ (result := testDivide(listf, minf)) case List(BP) =>
+ cons(minf, result::List BP)
+ if degree minf < 100 then for k in 1..10 repeat
+ listval:=[f answr for f in listf]
+ dval:=lintgcd(listval)
+ dd:=genpoly(dval,answr)
+ contd:=content(dd)
+ d:=(dd exquo contd)::BP
+ result:List BP :=[d]
+ flag : Boolean := true
+ for f in listf while flag repeat
+ (f1:=f exquo d) case "failed" => flag:=false
+ result := cons (f1::BP,result)
+ if flag then return reverse(result)
+ nvalue:= answr*832040 quo 317811
+ if ((nvalue + answr) rem 2) = 0 then nvalue:=nvalue+1
+ answr:=nvalue::PI
+ gg:=modularGcdPrimitive(listf)$IMG
+ cons(gg,[(f exquo gg) :: BP for f in listf])
+
+ --internal function:it evaluates the gcd and avoids duplication of
+ --code.
+ internal(flag:Cases,listf:List BP ):List BP ==
+ --special cases
+ listf=[] => [1$BP]
+ (nlf:=#listf)=1 => [first listf,1$BP]
+ minpol:=1$BP
+ -- extract a monomial gcd
+ mdeg:= "min"/[minimumDegree f for f in listf]
+ if mdeg>0 then
+ minpol1:= monomial(1,mdeg)
+ listf:= [(f exquo minpol1)::BP for f in listf]
+ minpol:=minpol*minpol1
+ -- make the polynomials primitive
+ Cgcd:List(Z):=[]
+ contgcd : Z := 1
+ if (flag case "gcd") or (flag case "gcdcofact") then
+ contlistf:List(ContPrim):=contprim(listf)
+ Cgcd:= [term.cont for term in contlistf]
+ contgcd:=lintgcd(Cgcd)
+ listf:List BP :=[term.prim for term in contlistf]
+ minpol:=contgcd*minpol
+ listdeg:=[degree f for f in listf ]
+ f:= first listf
+ for g in rest listf repeat
+ f:=gcd(f,g,bigPrime)
+ if degree f = 0 then return cons(minpol,listf)
+ ans:List BP :=
+ --one polynomial is constant
+ member?(0,listdeg) => constcase(listdeg,listf)
+ --one polynomial is linear
+ member?(1,listdeg) => lincase(listdeg,listf)
+ localgcd(listf)
+ (result,ans):=(first ans*minpol,rest ans)
+ if (flag case "gcdcofact") then
+ ans:= [(p quo contgcd)*q for p in Cgcd for q in ans]
+ cons(result,ans)
+
+ --gcd among n PRIMITIVE univariate polynomials
+ gcdprim (listf:List BP ):BP == first internal("gcdprim",listf)
+
+ --gcd and cofactors for n PRIMITIVE univariate polynomials
+ gcdcofactprim(listf:List BP ):List BP == internal("gcdcofactprim",listf)
+
+ --gcd for n generic univariate polynomials.
+ gcd(listf:List BP ): BP == first internal("gcd",listf)
+
+ --gcd and cofactors for n generic univariate polynomials.
+ gcdcofact (listf:List BP ):List BP == internal("gcdcofact",listf)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package HEUGCD HeuGcd>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/lmdict.spad.pamphlet b/src/algebra/lmdict.spad.pamphlet
new file mode 100644
index 00000000..cba196e2
--- /dev/null
+++ b/src/algebra/lmdict.spad.pamphlet
@@ -0,0 +1,200 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lmdict.spad}
+\author{Michael Monagan, Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain LMDICT ListMultiDictionary}
+<<domain LMDICT ListMultiDictionary>>=
+)abbrev domain LMDICT ListMultiDictionary
+++ Author: MBM Nov/87, MB Oct/89
+++ Date Created:
+++ Date Last Updated: 13 June 1994 Frederic Lehobey
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: The \spadtype{ListMultiDictionary} domain implements a
+++ dictionary with duplicates
+++ allowed. The representation is a list with duplicates represented
+++ explicitly. Hence most operations will be relatively inefficient
+++ when the number of entries in the dictionary becomes large.
+-- The operations \spadfun{pick}, \spadfun{count} and \spadfun{delete} can be used to iterate
+-- over the objects in the dictionary.
+-- [FDLL : those functions have not been implemented in the parent Categories]
+++ If the objects in the
+++ dictionary belong to an ordered set, the entries are maintained in
+++ ascending order.
+
+NNI ==> NonNegativeInteger
+D ==> Record(entry:S, count:NonNegativeInteger)
+
+ListMultiDictionary(S:SetCategory): MultiDictionary(S) with
+ finiteAggregate
+ duplicates?: % -> Boolean
+ ++ duplicates?(d) tests if dictionary d has duplicate entries.
+ substitute : (S, S, %) -> %
+ ++ substitute(x,y,d) replace x's with y's in dictionary d.
+ == add
+ Rep := Reference List S
+
+ sub: (S, S, S) -> S
+
+ coerce(s:%):OutputForm ==
+ prefix("dictionary"::OutputForm, [x::OutputForm for x in parts s])
+
+ #s == # parts s
+ copy s == dictionary copy parts s
+ empty? s == empty? parts s
+ bag l == dictionary l
+ dictionary() == dictionary empty()
+
+ empty():% == ref empty()
+
+ dictionary(ls:List S):% ==
+ empty? ls => empty()
+ lmd := empty()
+ for x in ls repeat insert_!(x,lmd)
+ lmd
+
+ if S has ConvertibleTo InputForm then
+ convert(lmd:%):InputForm ==
+ convert [convert("dictionary"::Symbol)@InputForm,
+ convert(parts lmd)@InputForm]
+
+ map(f, s) == dictionary map(f, parts s)
+ map_!(f, s) == dictionary map_!(f, parts s)
+ parts s == deref s
+ sub(x, y, z) == (z = x => y; z)
+ insert_!(x, s, n) == (for i in 1..n repeat insert_!(x, s); s)
+ substitute(x, y, s) == dictionary map(sub(x, y, #1), parts s)
+ removeDuplicates_! s == dictionary removeDuplicates_! parts s
+
+ inspect s ==
+ empty? s => error "empty dictionary"
+ first parts s
+
+ extract_! s ==
+ empty? s => error "empty dictionary"
+ x := first(p := parts s)
+ setref(s, rest p)
+ x
+
+ duplicates? s ==
+ empty?(p := parts s) => false
+ q := rest p
+ while not empty? q repeat
+ first p = first q => return true
+ p := q
+ q := rest q
+ false
+
+ remove_!(p: S->Boolean, lmd:%):% ==
+ for x in removeDuplicates parts lmd | p(x) repeat remove_!(x,lmd)
+ lmd
+
+ select_!(p: S->Boolean, lmd:%):% == remove_!(not p(#1), lmd)
+
+ duplicates(lmd:%):List D ==
+ ld: List D := empty()
+ for x in removeDuplicates parts lmd | (n := count(x, lmd)) >
+ 1$NonNegativeInteger repeat
+ ld := cons([x, n], ld)
+ ld
+
+ if S has OrderedSet then
+ s = t == parts s = parts t
+
+ remove_!(x:S, s:%) ==
+ p := deref s
+ while not empty? p and x = first p repeat p := rest p
+ setref(s, p)
+ empty? p => s
+ q := rest p
+ while not empty? q and x > first q repeat (p := q; q := rest q)
+ while not empty? q and x = first q repeat q := rest q
+ p.rest := q
+ s
+
+ insert_!(x, s) ==
+ p := deref s
+ empty? p or x < first p =>
+ setref(s, concat(x, p))
+ s
+ q := rest p
+ while not empty? q and x > first q repeat (p := q; q := rest q)
+ p.rest := concat(x, q)
+ s
+
+ else
+ remove_!(x:S, s:%) == (setref(s, remove_!(x, parts s)); s)
+
+ s = t ==
+ a := copy s
+ while not empty? a repeat
+ x := inspect a
+ count(x, s) ^= count(x, t) => return false
+ remove_!(x, a)
+ true
+
+ insert_!(x, s) ==
+ p := deref s
+ while not empty? p repeat
+ x = first p =>
+ p.rest := concat(x, rest p)
+ s
+ p := rest p
+ setref(s, concat(x, deref s))
+ s
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain LMDICT ListMultiDictionary>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/lodo.spad.pamphlet b/src/algebra/lodo.spad.pamphlet
new file mode 100644
index 00000000..c25901eb
--- /dev/null
+++ b/src/algebra/lodo.spad.pamphlet
@@ -0,0 +1,293 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lodo.spad}
+\author{Manuel Bronstein, Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category LODOCAT LinearOrdinaryDifferentialOperatorCategory}
+<<category LODOCAT LinearOrdinaryDifferentialOperatorCategory>>=
+)abbrev category LODOCAT LinearOrdinaryDifferentialOperatorCategory
+++ Author: Manuel Bronstein
+++ Date Created: 9 December 1993
+++ Date Last Updated: 15 April 1994
+++ Keywords: differential operator
+++ Description:
+++ \spad{LinearOrdinaryDifferentialOperatorCategory} is the category
+++ of differential operators with coefficients in a ring A with a given
+++ derivation.
+++ Multiplication of operators corresponds to functional composition:
+++ \spad{(L1 * L2).(f) = L1 L2 f}
+LinearOrdinaryDifferentialOperatorCategory(A:Ring): Category ==
+ Join(UnivariateSkewPolynomialCategory A, Eltable(A, A)) with
+ D: () -> %
+ ++ D() provides the operator corresponding to a derivation
+ ++ in the ring \spad{A}.
+ adjoint: % -> %
+ ++ adjoint(a) returns the adjoint operator of a.
+ if A has Field then
+ symmetricProduct: (%, %) -> %
+ ++ symmetricProduct(a,b) computes an operator \spad{c} of
+ ++ minimal order such that the nullspace of \spad{c} is
+ ++ generated by all the products of a solution of \spad{a} by
+ ++ a solution of \spad{b}.
+ symmetricPower : (%, NonNegativeInteger) -> %
+ ++ symmetricPower(a,n) computes an operator \spad{c} of
+ ++ minimal order such that the nullspace of \spad{c} is
+ ++ generated by all the products of \spad{n} solutions
+ ++ of \spad{a}.
+ symmetricSquare : % -> %
+ ++ symmetricSquare(a) computes \spad{symmetricProduct(a,a)}
+ ++ using a more efficient method.
+ directSum: (%, %) -> %
+ ++ directSum(a,b) computes an operator \spad{c} of
+ ++ minimal order such that the nullspace of \spad{c} is
+ ++ generated by all the sums of a solution of \spad{a} by
+ ++ a solution of \spad{b}.
+ add
+ m1monom: NonNegativeInteger -> %
+
+ D() == monomial(1, 1)
+
+ m1monom n ==
+ a:A := (odd? n => -1; 1)
+ monomial(a, n)
+
+ adjoint a ==
+ ans:% := 0
+ while a ^= 0 repeat
+ ans := ans + m1monom(degree a) * leadingCoefficient(a)::%
+ a := reductum a
+ ans
+
+ if A has Field then symmetricSquare l == symmetricPower(l, 2)
+
+@
+\section{package LODOOPS LinearOrdinaryDifferentialOperatorsOps}
+<<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>=
+)abbrev package LODOOPS LinearOrdinaryDifferentialOperatorsOps
+++ Author: Manuel Bronstein
+++ Date Created: 18 January 1994
+++ Date Last Updated: 15 April 1994
+++ Description:
+++ \spad{LinearOrdinaryDifferentialOperatorsOps} provides symmetric
+++ products and sums for linear ordinary differential operators.
+-- Putting those operations here rather than defaults in LODOCAT allows
+-- LODOCAT to be defined independently of the derivative used.
+-- MB 1/94
+LinearOrdinaryDifferentialOperatorsOps(A, L): Exports == Implementation where
+ A: Field
+ L: LinearOrdinaryDifferentialOperatorCategory A
+
+ N ==> NonNegativeInteger
+ V ==> OrderlyDifferentialVariable Symbol
+ P ==> DifferentialSparseMultivariatePolynomial(A, Symbol, V)
+
+ Exports ==> with
+ symmetricProduct: (L, L, A -> A) -> L
+ ++ symmetricProduct(a,b,D) computes an operator \spad{c} of
+ ++ minimal order such that the nullspace of \spad{c} is
+ ++ generated by all the products of a solution of \spad{a} by
+ ++ a solution of \spad{b}.
+ ++ D is the derivation to use.
+ symmetricPower: (L, N, A -> A) -> L
+ ++ symmetricPower(a,n,D) computes an operator \spad{c} of
+ ++ minimal order such that the nullspace of \spad{c} is
+ ++ generated by all the products of \spad{n} solutions
+ ++ of \spad{a}.
+ ++ D is the derivation to use.
+ directSum: (L, L, A -> A) -> L
+ ++ directSum(a,b,D) computes an operator \spad{c} of
+ ++ minimal order such that the nullspace of \spad{c} is
+ ++ generated by all the sums of a solution of \spad{a} by
+ ++ a solution of \spad{b}.
+ ++ D is the derivation to use.
+
+ Implementation ==> add
+ import IntegerCombinatoricFunctions
+
+ var1 := new()$Symbol
+ var2 := new()$Symbol
+
+ nonTrivial?: Vector A -> Boolean
+ applyLODO : (L, V) -> P
+ killer : (P, N, List V, List P, A -> A) -> L
+ vec2LODO : Vector A -> L
+
+ nonTrivial? v == any?(#1 ^= 0, v)$Vector(A)
+ vec2LODO v == +/[monomial(v.i, (i-1)::N) for i in 1..#v]
+
+ symmetricPower(l, m, diff) ==
+ u := var1::V; n := degree l
+ un := differentiate(u, n)
+ a := applyLODO(inv(- leadingCoefficient l) * reductum l, u)
+ killer(u::P ** m, binomial(n + m - 1, n - 1)::N, [un], [a], diff)
+
+-- returns an operator L such that L(u) = 0, for a given differential
+-- polynomial u, given that the differential variables appearing in u
+-- satisfy some linear ode's
+-- m is a bound on the order of the operator searched.
+-- lvar, lval describe the substitution(s) to perform when differentiating
+-- the expression u (they encode the fact the the differential variables
+-- satisfy some differential equations, which can be seen as the rewrite
+-- rules lvar --> lval)
+-- diff is the derivation to use
+ killer(u, m, lvar, lval, diff) ==
+ lu:List P := [u]
+ for q in 0..m repeat
+ mat := reducedSystem(matrix([lu])@Matrix(P))@Matrix(A)
+ (sol := find(nonTrivial?, l := nullSpace mat)) case Vector(A) =>
+ return vec2LODO(sol::Vector(A))
+ u := eval(differentiate(u, diff), lvar, lval)
+ lu := concat_!(lu, [u])
+ error "killer: no linear dependence found"
+
+ symmetricProduct(l1, l2, diff) ==
+ u := var1::V; v := var2::V
+ n1 := degree l1; n2 := degree l2
+ un := differentiate(u, n1); vn := differentiate(v, n2)
+ a := applyLODO(inv(- leadingCoefficient l1) * reductum l1, u)
+ b := applyLODO(inv(- leadingCoefficient l2) * reductum l2, v)
+ killer(u::P * v::P, n1 * n2, [un, vn], [a, b], diff)
+
+ directSum(l1, l2, diff) ==
+ u := var1::V; v := var2::V
+ n1 := degree l1; n2 := degree l2
+ un := differentiate(u, n1); vn := differentiate(v, n2)
+ a := applyLODO(inv(- leadingCoefficient l1) * reductum l1, u)
+ b := applyLODO(inv(- leadingCoefficient l2) * reductum l2, v)
+ killer(u::P + v::P, n1 + n2, [un, vn], [a, b], diff)
+
+ applyLODO(l, v) ==
+ p:P := 0
+ while l ^= 0 repeat
+ p := p + monomial(leadingCoefficient(l)::P,
+ differentiate(v, degree l), 1)
+ l := reductum l
+ p
+
+@
+\section{domain LODO LinearOrdinaryDifferentialOperator}
+<<domain LODO LinearOrdinaryDifferentialOperator>>=
+)abbrev domain LODO LinearOrdinaryDifferentialOperator
+++ Author: Manuel Bronstein
+++ Date Created: 9 December 1993
+++ Date Last Updated: 15 April 1994
+++ Keywords: differential operator
+++ Description:
+++ \spad{LinearOrdinaryDifferentialOperator} defines a ring of
+++ differential operators with coefficients in a ring A with a given
+++ derivation.
+++ Multiplication of operators corresponds to functional composition:
+++ \spad{(L1 * L2).(f) = L1 L2 f}
+LinearOrdinaryDifferentialOperator(A:Ring, diff: A -> A):
+ LinearOrdinaryDifferentialOperatorCategory A
+ == SparseUnivariateSkewPolynomial(A, 1, diff) add
+ Rep := SparseUnivariateSkewPolynomial(A, 1, diff)
+
+ outputD := "D"@String :: Symbol :: OutputForm
+
+ coerce(l:%):OutputForm == outputForm(l, outputD)
+ elt(p:%, a:A):A == apply(p, 0, a)
+
+ if A has Field then
+ import LinearOrdinaryDifferentialOperatorsOps(A, %)
+
+ symmetricProduct(a, b) == symmetricProduct(a, b, diff)
+ symmetricPower(a, n) == symmetricPower(a, n, diff)
+ directSum(a, b) == directSum(a, b, diff)
+
+@
+\section{domain LODO1 LinearOrdinaryDifferentialOperator1}
+<<domain LODO1 LinearOrdinaryDifferentialOperator1>>=
+)abbrev domain LODO1 LinearOrdinaryDifferentialOperator1
+++ Author: Manuel Bronstein
+++ Date Created: 9 December 1993
+++ Date Last Updated: 31 January 1994
+++ Keywords: differential operator
+++ Description:
+++ \spad{LinearOrdinaryDifferentialOperator1} defines a ring of
+++ differential operators with coefficients in a differential ring A.
+++ Multiplication of operators corresponds to functional composition:
+++ \spad{(L1 * L2).(f) = L1 L2 f}
+LinearOrdinaryDifferentialOperator1(A:DifferentialRing) ==
+ LinearOrdinaryDifferentialOperator(A, differentiate$A)
+
+@
+\section{domain LODO2 LinearOrdinaryDifferentialOperator2}
+<<domain LODO2 LinearOrdinaryDifferentialOperator2>>=
+)abbrev domain LODO2 LinearOrdinaryDifferentialOperator2
+++ Author: Stephen M. Watt, Manuel Bronstein
+++ Date Created: 1986
+++ Date Last Updated: 1 February 1994
+++ Keywords: differential operator
+++ Description:
+++ \spad{LinearOrdinaryDifferentialOperator2} defines a ring of
+++ differential operators with coefficients in a differential ring A
+++ and acting on an A-module M.
+++ Multiplication of operators corresponds to functional composition:
+++ \spad{(L1 * L2).(f) = L1 L2 f}
+LinearOrdinaryDifferentialOperator2(A, M): Exports == Implementation where
+ A: DifferentialRing
+ M: LeftModule A with
+ differentiate: $ -> $
+ ++ differentiate(x) returns the derivative of x
+
+ Exports ==> Join(LinearOrdinaryDifferentialOperatorCategory A, Eltable(M, M))
+
+ Implementation ==> LinearOrdinaryDifferentialOperator(A, differentiate$A) add
+ elt(p:%, m:M):M ==
+ apply(p, differentiate, m)$ApplyUnivariateSkewPolynomial(A, M, %)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category LODOCAT LinearOrdinaryDifferentialOperatorCategory>>
+<<package LODOOPS LinearOrdinaryDifferentialOperatorsOps>>
+<<domain LODO LinearOrdinaryDifferentialOperator>>
+<<domain LODO1 LinearOrdinaryDifferentialOperator1>>
+<<domain LODO2 LinearOrdinaryDifferentialOperator2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/lodof.spad.pamphlet b/src/algebra/lodof.spad.pamphlet
new file mode 100644
index 00000000..fd72c15a
--- /dev/null
+++ b/src/algebra/lodof.spad.pamphlet
@@ -0,0 +1,533 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lodof.spad}
+\author{Manuel Bronstein, Fritz Schwarz}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SETMN SetOfMIntegersInOneToN}
+<<domain SETMN SetOfMIntegersInOneToN>>=
+)abbrev domain SETMN SetOfMIntegersInOneToN
+++ Author: Manuel Bronstein
+++ Date Created: 10 January 1994
+++ Date Last Updated: 10 January 1994
+++ Description:
+++ \spadtype{SetOfMIntegersInOneToN} implements the subsets of M integers
+++ in the interval \spad{[1..n]}
+SetOfMIntegersInOneToN(m, n): Exports == Implementation where
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ U ==> Union(%, "failed")
+ n,m: PI
+
+ Exports ==> Finite with
+ incrementKthElement: (%, PI) -> U
+ ++ incrementKthElement(S,k) increments the k^{th} element of S,
+ ++ and returns "failed" if the result is not a set of M integers
+ ++ in \spad{1..n} any more.
+ replaceKthElement: (%, PI, PI) -> U
+ ++ replaceKthElement(S,k,p) replaces the k^{th} element of S by p,
+ ++ and returns "failed" if the result is not a set of M integers
+ ++ in \spad{1..n} any more.
+ elements: % -> List PI
+ ++ elements(S) returns the list of the elements of S in increasing order.
+ setOfMinN: List PI -> %
+ ++ setOfMinN([a_1,...,a_m]) returns the set {a_1,...,a_m}.
+ ++ Error if {a_1,...,a_m} is not a set of M integers in \spad{1..n}.
+ enumerate: () -> Vector %
+ ++ enumerate() returns a vector of all the sets of M integers in
+ ++ \spad{1..n}.
+ member?: (PI, %) -> Boolean
+ ++ member?(p, s) returns true is p is in s, false otherwise.
+ delta: (%, PI, PI) -> N
+ ++ delta(S,k,p) returns the number of elements of S which are strictly
+ ++ between p and the k^{th} element of S.
+
+ Implementation ==> add
+ Rep := Record(bits:Bits, pos:N)
+
+ reallyEnumerate: () -> Vector %
+ enum: (N, N, PI) -> List Bits
+
+ all:Reference Vector % := ref empty()
+ sz:Reference N := ref 0
+
+ s1 = s2 == s1.bits =$Bits s2.bits
+ coerce(s:%):OutputForm == brace [i::OutputForm for i in elements s]
+ random() == index((1 + (random()$Integer rem size()))::PI)
+ reallyEnumerate() == [[b, i] for b in enum(m, n, n) for i in 1..]
+ member?(p, s) == s.bits.p
+
+ enumerate() ==
+ if empty? all() then all() := reallyEnumerate()
+ all()
+
+-- enumerates the sets of p integers in 1..q, returns them as sets in 1..n
+-- must have p <= q
+ enum(p, q, n) ==
+ zero? p or zero? q => empty()
+ p = q =>
+ b := new(n, false)$Bits
+ for i in 1..p repeat b.i := true
+ [b]
+ q1 := (q - 1)::N
+ l := enum((p - 1)::N, q1, n)
+ if empty? l then l := [new(n, false)$Bits]
+ for s in l repeat s.q := true
+ concat_!(enum(p, q1, n), l)
+
+ size() ==
+ if zero? sz() then
+ sz() := binomial(n, m)$IntegerCombinatoricFunctions(Integer) :: N
+ sz()
+
+ lookup s ==
+ if empty? all() then all() := reallyEnumerate()
+ if zero?(s.pos) then s.pos := position(s, all()) :: N
+ s.pos :: PI
+
+ index p ==
+ p > size() => error "index: argument too large"
+ if empty? all() then all() := reallyEnumerate()
+ all().p
+
+ setOfMinN l ==
+ s := new(n, false)$Bits
+ count:N := 0
+ for i in l repeat
+ count := count + 1
+ count > m or zero? i or i > n or s.i =>
+ error "setOfMinN: improper set of integers"
+ s.i := true
+ count < m => error "setOfMinN: improper set of integers"
+ [s, 0]
+
+ elements s ==
+ b := s.bits
+ l:List PI := empty()
+ found:N := 0
+ i:PI := 1
+ while found < m repeat
+ if b.i then
+ l := concat(i, l)
+ found := found + 1
+ i := i + 1
+ reverse_! l
+
+ incrementKthElement(s, k) ==
+ b := s.bits
+ found:N := 0
+ i:N := 1
+ while found < k repeat
+ if b.i then found := found + 1
+ i := i + 1
+ i > n or b.i => "failed"
+ newb := copy b
+ newb.i := true
+ newb.((i-1)::N) := false
+ [newb, 0]
+
+ delta(s, k, p) ==
+ b := s.bits
+ count:N := found:N := 0
+ i:PI := 1
+ while found < k repeat
+ if b.i then
+ found := found + 1
+ if i > p and found < k then count := count + 1
+ i := i + 1
+ count
+
+ replaceKthElement(s, k, p) ==
+ b := s.bits
+ found:N := 0
+ i:PI := 1
+ while found < k repeat
+ if b.i then found := found + 1
+ if found < k then i := i + 1
+ b.p and i ^= p => "failed"
+ newb := copy b
+ newb.p := true
+ newb.i := false
+ [newb, (i = p => s.pos; 0)]
+
+@
+\section{package PREASSOC PrecomputedAssociatedEquations}
+<<package PREASSOC PrecomputedAssociatedEquations>>=
+)abbrev package PREASSOC PrecomputedAssociatedEquations
+++ Author: Manuel Bronstein
+++ Date Created: 13 January 1994
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{PrecomputedAssociatedEquations} stores some generic
+++ precomputations which speed up the computations of the
+++ associated equations needed for factoring operators.
+PrecomputedAssociatedEquations(R, L): Exports == Implementation where
+ R: IntegralDomain
+ L: LinearOrdinaryDifferentialOperatorCategory R
+
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ A ==> PrimitiveArray R
+ U ==> Union(Matrix R, "failed")
+
+ Exports ==> with
+ firstUncouplingMatrix: (L, PI) -> U
+ ++ firstUncouplingMatrix(op, m) returns the matrix A such that
+ ++ \spad{A w = (W',W'',...,W^N)} in the corresponding associated
+ ++ equations for right-factors of order m of op.
+ ++ Returns "failed" if the matrix A has not been precomputed for
+ ++ the particular combination \spad{degree(L), m}.
+
+ Implementation ==> add
+ A32: L -> U
+ A42: L -> U
+ A425: (A, A, A) -> List R
+ A426: (A, A, A) -> List R
+ makeMonic: L -> Union(A, "failed")
+
+ diff:L := D()
+
+ firstUncouplingMatrix(op, m) ==
+ n := degree op
+ n = 3 and m = 2 => A32 op
+ n = 4 and m = 2 => A42 op
+ "failed"
+
+ makeMonic op ==
+ lc := leadingCoefficient op
+ a:A := new(n := degree op, 0)
+ for i in 0..(n-1)::N repeat
+ (u := coefficient(op, i) exquo lc) case "failed" => return "failed"
+ a.i := - (u::R)
+ a
+
+ A32 op ==
+ (u := makeMonic op) case "failed" => "failed"
+ a := u::A
+ matrix [[0, 1, 0], [a.1, a.2, 1],
+ [diff(a.1) + a.1 * a.2 - a.0, diff(a.2) + a.2**2 + a.1, 2 * a.2]]
+
+ A42 op ==
+ (u := makeMonic op) case "failed" => "failed"
+ a := u::A
+ a':A := new(4, 0)
+ a'':A := new(4, 0)
+ for i in 0..3 repeat
+ a'.i := diff(a.i)
+ a''.i := diff(a'.i)
+ matrix [[0, 1, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0], [a.1,a.2,0,a.3,2::R,0],
+ [a'.1 + a.1 * a.3 - 2 * a.0, a'.2 + a.2 * a.3 + a.1, 3 * a.2,
+ a'.3 + a.3 ** 2 + a.2, 3 * a.3, 2::R],
+ A425(a, a', a''), A426(a, a', a'')]
+
+ A425(a, a', a'') ==
+ [a''.1 + 2 * a.1 * a'.3 + a.3 * a'.1 - 2 * a'.0 + a.1 * a.3 ** 2
+ - 3 * a.0 * a.3 + a.1 * a.2,
+ a''.2 + 2 * a.2 * a'.3 + a.3 * a'.2 + 2 * a'.1 + a.2 * a.3 ** 2
+ + a.1 * a.3 + a.2 ** 2 - 4 * a.0,
+ 4 * a'.2 + 4 * a.2 * a.3 - a.1,
+ a''.3 + 3 * a.3 * a'.3 + 2 * a'.2 + a.3 ** 3 + 2 * a.2 * a.3 + a.1,
+ 4 * a'.3 + 4 * a.3 ** 2 + 4 * a.2, 5 * a.3]
+
+ A426(a, a', a'') ==
+ [diff(a''.1) + 3 * a.1 * a''.3 + a.3 * a''.1 - 2 * a''.0
+ + (3 * a'.1 + 5 * a.1 * a.3 - 7 * a.0) * a'.3 + 3 * a.1 * a'.2
+ + (a.3 ** 2 + a.2) * a'.1 - 3 * a.3 * a'.0 + a.1 * a.3 ** 3
+ - 4 * a.0 * a.3 ** 2 + 2 * a.1 * a.2 * a.3 - 4 * a.0 * a.2 + a.1 ** 2,
+ diff(a''.2) + 3 * a.2 * a''.3 + a.3 * a''.2 + 3 * a''.1
+ + (3*a'.2 + 5*a.2 * a.3 + 3 * a.1) * a'.3 + (a.3**2 + 4*a.2)*a'.2
+ + 2 * a.3 * a'.1 - 6 * a'.0 + a.2 * a.3 ** 3 + a.1 * a.3 ** 2
+ + (2 * a.2**2 - 8 * a.0) * a.3 + 2 * a.1 * a.2,
+ 5 * a''.2 + 10 * a.2 * a'.3 + 5 * a.3 * a'.2 + a'.1
+ + 5 * a.2 * a.3 ** 2 - 4 * a.1 * a.3 + 5 * a.2**2 - 4 * a.0,
+ diff(a''.3) + 4 * a.3 * a''.3 + 3*a''.2 + 3 * a'.3**2
+ + (6 * a.3**2 + 4 * a.2) * a'.3 + 5 * a.3 * a'.2 + 3 * a'.1
+ + a.3**4 + 3 * a.2 * a.3**2 + 2 * a.1 * a.3 + a.2**2 - 4*a.0,
+ 5 * a''.3 + 15 * a.3 * a'.3 + 10 * a'.2 + 5 * a.3**3
+ + 10 * a.2 * a.3, 9 * a'.3 + 9 * a.3**2 + 4 * a.2]
+
+@
+\section{package ASSOCEQ AssociatedEquations}
+<<package ASSOCEQ AssociatedEquations>>=
+)abbrev package ASSOCEQ AssociatedEquations
+++ Author: Manuel Bronstein
+++ Date Created: 10 January 1994
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{AssociatedEquations} provides functions to compute the
+++ associated equations needed for factoring operators
+AssociatedEquations(R, L):Exports == Implementation where
+ R: IntegralDomain
+ L: LinearOrdinaryDifferentialOperatorCategory R
+
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ MAT ==> Matrix R
+ REC ==> Record(minor: List PI, eq: L, minors: List List PI, ops: List L)
+
+ Exports ==> with
+ associatedSystem: (L, PI) -> Record(mat: MAT, vec:Vector List PI)
+ ++ associatedSystem(op, m) returns \spad{[M,w]} such that the
+ ++ m-th associated equation system to L is \spad{w' = M w}.
+ uncouplingMatrices: MAT -> Vector MAT
+ ++ uncouplingMatrices(M) returns \spad{[A_1,...,A_n]} such that if
+ ++ \spad{y = [y_1,...,y_n]} is a solution of \spad{y' = M y}, then
+ ++ \spad{[$y_j',y_j'',...,y_j^{(n)}$] = $A_j y$} for all j's.
+ if R has Field then
+ associatedEquations: (L, PI) -> REC
+ ++ associatedEquations(op, m) returns \spad{[w, eq, lw, lop]}
+ ++ such that \spad{eq(w) = 0} where w is the given minor, and
+ ++ \spad{lw_i = lop_i(w)} for all the other minors.
+
+ Implementation ==> add
+ makeMatrix: (Vector MAT, N) -> MAT
+
+ diff:L := D()
+
+ makeMatrix(v, n) == matrix [parts row(v.i, n) for i in 1..#v]
+
+ associatedSystem(op, m) ==
+ eq: Vector R
+ S := SetOfMIntegersInOneToN(m, n := degree(op)::PI)
+ w := enumerate()$S
+ s := size()$S
+ ww:Vector List PI := new(s, empty())
+ M:MAT := new(s, s, 0)
+ m1 := (m::Integer - 1)::PI
+ an := leadingCoefficient op
+ a:Vector(R) := [- (coefficient(op, j) exquo an)::R for j in 0..n - 1]
+ for i in 1..s repeat
+ eq := new(s, 0)
+ wi := w.i
+ ww.i := elements wi
+ for k in 1..m1 repeat
+ u := incrementKthElement(wi, k::PI)$S
+ if u case S then eq(lookup(u::S)) := 1
+ if member?(n, wi) then
+ for j in 1..n | a.j ^= 0 repeat
+ u := replaceKthElement(wi, m, j::PI)
+ if u case S then
+ eq(lookup(u::S)) := (odd? delta(wi, m, j::PI) => -a.j; a.j)
+ else
+ u := incrementKthElement(wi, m)$S
+ if u case S then eq(lookup(u::S)) := 1
+ setRow_!(M, i, eq)
+ [M, ww]
+
+ uncouplingMatrices m ==
+ n := nrows m
+ v:Vector MAT := new(n, zero(1, 0)$MAT)
+ v.1 := mi := m
+ for i in 2..n repeat v.i := mi := map(diff #1, mi) + mi * m
+ [makeMatrix(v, i) for i in 1..n]
+
+ if R has Field then
+ import PrecomputedAssociatedEquations(R, L)
+
+ makeop: Vector R -> L
+ makeeq: (Vector List PI, MAT, N, N) -> REC
+ computeIt: (L, PI, N) -> REC
+
+ makeeq(v, m, i, n) ==
+ [v.i, makeop row(m, i) - 1, [v.j for j in 1..n | j ^= i],
+ [makeop row(m, j) for j in 1..n | j ^= i]]
+
+ associatedEquations(op, m) ==
+ (u := firstUncouplingMatrix(op, m)) case "failed" => computeIt(op,m,1)
+ (v := inverse(u::MAT)) case "failed" => computeIt(op, m, 2)
+ S := SetOfMIntegersInOneToN(m, degree(op)::PI)
+ w := enumerate()$S
+ s := size()$S
+ ww:Vector List PI := new(s, empty())
+ for i in 1..s repeat ww.i := elements(w.i)
+ makeeq(ww, v::MAT, 1, s)
+
+ computeIt(op, m, k) ==
+ rec := associatedSystem(op, m)
+ a := uncouplingMatrices(rec.mat)
+ n := #a
+ for i in k..n repeat
+ (u := inverse(a.i)) case MAT => return makeeq(rec.vec,u::MAT,i,n)
+ error "associatedEquations: full degenerate case"
+
+ makeop v ==
+ op:L := 0
+ for i in 1..#v repeat op := op + monomial(v i, i)
+ op
+
+@
+\section{package LODOF LinearOrdinaryDifferentialOperatorFactorizer}
+<<package LODOF LinearOrdinaryDifferentialOperatorFactorizer>>=
+)abbrev package LODOF LinearOrdinaryDifferentialOperatorFactorizer
+++ Author: Fritz Schwarz, Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{LinearOrdinaryDifferentialOperatorFactorizer} provides a
+++ factorizer for linear ordinary differential operators whose coefficients
+++ are rational functions.
+++ Keywords: differential equation, ODE, LODO, factoring
+LinearOrdinaryDifferentialOperatorFactorizer(F, UP): Exports == Impl where
+ F : Join(Field, CharacteristicZero,
+ RetractableTo Integer, RetractableTo Fraction Integer)
+ UP: UnivariatePolynomialCategory F
+
+ RF ==> Fraction UP
+ L ==> LinearOrdinaryDifferentialOperator1 RF
+
+ Exports ==> with
+ factor: (L, UP -> List F) -> List L
+ ++ factor(a, zeros) returns the factorisation of a.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ if F has AlgebraicallyClosedField then
+ factor: L -> List L
+ ++ factor(a) returns the factorisation of a.
+ factor1: L -> List L
+ ++ factor1(a) returns the factorisation of a,
+ ++ assuming that a has no first-order right factor.
+
+ Impl ==> add
+ import RationalLODE(F, UP)
+ import RationalRicDE(F, UP)
+-- import AssociatedEquations RF
+
+ dd := D()$L
+
+ expsol : (L, UP -> List F, UP -> Factored UP) -> Union(RF, "failed")
+ expsols : (L, UP -> List F, UP -> Factored UP, Boolean) -> List RF
+ opeval : (L, L) -> L
+ recurfactor: (L, L, UP -> List F, UP -> Factored UP, Boolean) -> List L
+ rfactor : (L, L, UP -> List F, UP -> Factored UP, Boolean) -> List L
+ rightFactor: (L, NonNegativeInteger, UP -> List F, UP -> Factored UP)
+ -> Union(L, "failed")
+ innerFactor: (L, UP -> List F, UP -> Factored UP, Boolean) -> List L
+
+ factor(l, zeros) == innerFactor(l, zeros, squareFree, true)
+
+ expsol(l, zeros, ezfactor) ==
+ empty?(sol := expsols(l, zeros, ezfactor, false)) => "failed"
+ first sol
+
+ expsols(l, zeros, ezfactor, all?) ==
+ sol := [differentiate(f)/f for f in ratDsolve(l, 0).basis | f ^= 0]
+ not(all? or empty? sol) => sol
+ concat(sol, ricDsolve(l, zeros, ezfactor))
+
+-- opeval(l1, l2) returns l1(l2)
+ opeval(l1, l2) ==
+ ans:L := 0
+ l2n:L := 1
+ for i in 0..degree l1 repeat
+ ans := ans + coefficient(l1, i) * l2n
+ l2n := l2 * l2n
+ ans
+
+ recurfactor(l, r, zeros, ezfactor, adj?) ==
+ q := rightExactQuotient(l, r)::L
+ if adj? then q := adjoint q
+ innerFactor(q, zeros, ezfactor, true)
+
+ rfactor(op, r, zeros, ezfactor, adj?) ==
+-- degree r > 1 or not one? leadingCoefficient r =>
+ degree r > 1 or not ((leadingCoefficient r) = 1) =>
+ recurfactor(op, r, zeros, ezfactor, adj?)
+ op1 := opeval(op, dd - coefficient(r, 0)::L)
+ map_!(opeval(#1, r), recurfactor(op1, dd, zeros, ezfactor, adj?))
+
+-- r1? is true means look for 1st-order right-factor also
+ innerFactor(l, zeros, ezfactor, r1?) ==
+ (n := degree l) <= 1 => [l]
+ ll := adjoint l
+ for i in 1..(n quo 2) repeat
+ (r1? or (i > 1)) and ((u := rightFactor(l,i,zeros,ezfactor)) case L) =>
+ return concat_!(rfactor(l, u::L, zeros, ezfactor, false), u::L)
+ (2 * i < n) and ((u := rightFactor(ll, i, zeros, ezfactor)) case L) =>
+ return concat(adjoint(u::L), rfactor(ll, u::L, zeros,ezfactor,true))
+ [l]
+
+ rightFactor(l, n, zeros, ezfactor) ==
+-- one? n =>
+ (n = 1) =>
+ (u := expsol(l, zeros, ezfactor)) case "failed" => "failed"
+ D() - u::RF::L
+-- rec := associatedEquations(l, n::PositiveInteger)
+-- empty?(sol := expsols(rec.eq, zeros, ezfactor, true)) => "failed"
+ "failed"
+
+ if F has AlgebraicallyClosedField then
+ zro1: UP -> List F
+ zro : (UP, UP -> Factored UP) -> List F
+
+ zro(p, ezfactor) ==
+ concat [zro1(r.factor) for r in factors ezfactor p]
+
+ zro1 p ==
+ [zeroOf(map(#1, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
+ F, SparseUnivariatePolynomial F))]
+
+ if F is AlgebraicNumber then
+ import AlgFactor UP
+
+ factor l == innerFactor(l, zro(#1, factor), factor, true)
+ factor1 l == innerFactor(l, zro(#1, factor), factor, false)
+
+ else
+ factor l == innerFactor(l, zro(#1, squareFree), squareFree, true)
+ factor1 l == innerFactor(l, zro(#1, squareFree), squareFree, false)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad
+-- kovacic.spad lodof.spad odeef.spad
+
+<<domain SETMN SetOfMIntegersInOneToN>>
+<<package PREASSOC PrecomputedAssociatedEquations>>
+<<package ASSOCEQ AssociatedEquations>>
+<<package LODOF LinearOrdinaryDifferentialOperatorFactorizer>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/lodop.spad.pamphlet b/src/algebra/lodop.spad.pamphlet
new file mode 100644
index 00000000..f1e5eebb
--- /dev/null
+++ b/src/algebra/lodop.spad.pamphlet
@@ -0,0 +1,349 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra lodop.spad}
+\author{Stephen M. Watt, Jean Della Dora}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category MLO MonogenicLinearOperator}
+<<category MLO MonogenicLinearOperator>>=
+)abbrev category MLO MonogenicLinearOperator
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: NonCommutativeOperatorDivision
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This is the category of linear operator rings with one generator.
+++ The generator is not named by the category but can always be
+++ constructed as \spad{monomial(1,1)}.
+++
+++ For convenience, call the generator \spad{G}.
+++ Then each value is equal to
+++ \spad{sum(a(i)*G**i, i = 0..n)}
+++ for some unique \spad{n} and \spad{a(i)} in \spad{R}.
+++
+++ Note that multiplication is not necessarily commutative.
+++ In fact, if \spad{a} is in \spad{R}, it is quite normal
+++ to have \spad{a*G \^= G*a}.
+
+MonogenicLinearOperator(R): Category == Defn where
+ E ==> NonNegativeInteger
+ R: Ring
+ Defn == Join(Ring, BiModule(R,R)) with
+ if R has CommutativeRing then Algebra(R)
+ degree: $ -> E
+ ++ degree(l) is \spad{n} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ minimumDegree: $ -> E
+ ++ minimumDegree(l) is the smallest \spad{k} such that
+ ++ \spad{a(k) \^= 0} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ leadingCoefficient: $ -> R
+ ++ leadingCoefficient(l) is \spad{a(n)} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ reductum: $ -> $
+ ++ reductum(l) is \spad{l - monomial(a(n),n)} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ coefficient: ($, E) -> R
+ ++ coefficient(l,k) is \spad{a(k)} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ monomial: (R, E) -> $
+ ++ monomial(c,k) produces c times the k-th power of
+ ++ the generating operator, \spad{monomial(1,1)}.
+
+@
+\section{domain OMLO OppositeMonogenicLinearOperator}
+<<domain OMLO OppositeMonogenicLinearOperator>>=
+)abbrev domain OMLO OppositeMonogenicLinearOperator
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: MonogenicLinearOperator
+++ Also See:
+++ AMS Classifications:
+++ Keywords: opposite ring
+++ Examples:
+++ References:
+++ Description:
+++ This constructor creates the \spadtype{MonogenicLinearOperator} domain
+++ which is ``opposite'' in the ring sense to P.
+++ That is, as sets \spad{P = $} but \spad{a * b} in \spad{$} is equal to
+++ \spad{b * a} in P.
+
+OppositeMonogenicLinearOperator(P, R): OPRcat == OPRdef where
+ P: MonogenicLinearOperator(R)
+ R: Ring
+
+ OPRcat == MonogenicLinearOperator(R) with
+ if P has DifferentialRing then DifferentialRing
+ op: P -> $ ++ op(p) creates a value in $ equal to p in P.
+ po: $ -> P ++ po(q) creates a value in P equal to q in $.
+
+ OPRdef == P add
+ Rep := P
+ x, y: $
+ a: P
+ op a == a: $
+ po x == x: P
+ x*y == (y:P) *$P (x:P)
+ coerce(x): OutputForm == prefix(op::OutputForm, [coerce(x:P)$P])
+
+@
+\section{package NCODIV NonCommutativeOperatorDivision}
+<<package NCODIV NonCommutativeOperatorDivision>>=
+)abbrev package NCODIV NonCommutativeOperatorDivision
+++ Author: Jean Della Dora, Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: LinearOrdinaryDifferentialOperator
+++ Also See:
+++ AMS Classifications:
+++ Keywords: gcd, lcm, division, non-commutative
+++ Examples:
+++ References:
+++ Description:
+++ This package provides a division and related operations for
+++ \spadtype{MonogenicLinearOperator}s over a \spadtype{Field}.
+++ Since the multiplication is in general non-commutative,
+++ these operations all have left- and right-hand versions.
+++ This package provides the operations based on left-division.
+ -- [q,r] = leftDivide(a,b) means a=b*q+r
+
+NonCommutativeOperatorDivision(P, F): PDcat == PDdef where
+ P: MonogenicLinearOperator(F)
+ F: Field
+
+ PDcat == with
+ leftDivide: (P, P) -> Record(quotient: P, remainder: P)
+ ++ leftDivide(a,b) returns the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ This process is called ``left division''.
+ leftQuotient: (P, P) -> P
+ ++ leftQuotient(a,b) computes the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ The value \spad{q} is returned.
+ leftRemainder: (P, P) -> P
+ ++ leftRemainder(a,b) computes the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ The value \spad{r} is returned.
+ leftExactQuotient:(P, P) -> Union(P, "failed")
+ ++ leftExactQuotient(a,b) computes the value \spad{q}, if it exists,
+ ++ such that \spad{a = b*q}.
+
+ leftGcd: (P, P) -> P
+ ++ leftGcd(a,b) computes the value \spad{g} of highest degree
+ ++ such that
+ ++ \spad{a = aa*g}
+ ++ \spad{b = bb*g}
+ ++ for some values \spad{aa} and \spad{bb}.
+ ++ The value \spad{g} is computed using left-division.
+ leftLcm: (P, P) -> P
+ ++ leftLcm(a,b) computes the value \spad{m} of lowest degree
+ ++ such that \spad{m = a*aa = b*bb} for some values
+ ++ \spad{aa} and \spad{bb}. The value \spad{m} is
+ ++ computed using left-division.
+
+ PDdef == add
+ leftDivide(a, b) ==
+ q: P := 0
+ r: P := a
+ iv:F := inv leadingCoefficient b
+ while degree r >= degree b and r ^= 0 repeat
+ h := monomial(iv*leadingCoefficient r,
+ (degree r - degree b)::NonNegativeInteger)$P
+ r := r - b*h
+ q := q + h
+ [q,r]
+
+ -- leftQuotient(a,b) is the quotient from left division, etc.
+ leftQuotient(a,b) == leftDivide(a,b).quotient
+ leftRemainder(a,b) == leftDivide(a,b).remainder
+ leftExactQuotient(a,b) ==
+ qr := leftDivide(a,b)
+ if qr.remainder = 0 then qr.quotient else "failed"
+ -- l = leftGcd(a,b) means a = aa*l b = bb*l. Uses leftDivide.
+ leftGcd(a,b) ==
+ a = 0 =>b
+ b = 0 =>a
+ while degree b > 0 repeat (a,b) := (b, leftRemainder(a,b))
+ if b=0 then a else b
+ -- l = leftLcm(a,b) means l = a*aa l = b*bb Uses leftDivide.
+ leftLcm(a,b) ==
+ a = 0 =>b
+ b = 0 =>a
+ b0 := b
+ u := monomial(1,0)$P
+ v := 0
+ while leadingCoefficient b ^= 0 repeat
+ qr := leftDivide(a,b)
+ (a, b) := (b, qr.remainder)
+ (u, v) := (u*qr.quotient+v, u)
+ b0*u
+
+@
+\section{domain ODR OrdinaryDifferentialRing}
+<<domain ODR OrdinaryDifferentialRing>>=
+)abbrev domain ODR OrdinaryDifferentialRing
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: differential ring
+++ Examples:
+++ References:
+++ Description:
+++ This constructor produces an ordinary differential ring from
+++ a partial differential ring by specifying a variable.
+
+OrdinaryDifferentialRing(Kernels,R,var): DRcategory == DRcapsule where
+ Kernels:SetCategory
+ R: PartialDifferentialRing(Kernels)
+ var : Kernels
+ DRcategory == Join(BiModule($,$), DifferentialRing) with
+ if R has Field then Field
+ coerce: R -> $
+ ++ coerce(r) views r as a value in the ordinary differential ring.
+ coerce: $ -> R
+ ++ coerce(p) views p as a valie in the partial differential ring.
+ DRcapsule == R add
+ n: Integer
+ Rep := R
+ coerce(u:R):$ == u::Rep::$
+ coerce(p:$):R == p::Rep::R
+ differentiate p == differentiate(p, var)
+
+ if R has Field then
+ p / q == ((p::R) /$R (q::R))::$
+ p ** n == ((p::R) **$R n)::$
+ inv(p) == (inv(p::R)$R)::$
+
+@
+\section{domain DPMO DirectProductModule}
+<<domain DPMO DirectProductModule>>=
+)abbrev domain DPMO DirectProductModule
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This constructor provides a direct product of R-modules
+++ with an R-module view.
+
+DirectProductModule(n, R, S): DPcategory == DPcapsule where
+ n: NonNegativeInteger
+ R: Ring
+ S: LeftModule(R)
+
+ DPcategory == Join(DirectProductCategory(n,S), LeftModule(R))
+ -- with if S has Algebra(R) then Algebra(R)
+ -- <above line leads to matchMmCond: unknown form of condition>
+
+ DPcapsule == DirectProduct(n,S) add
+ Rep := Vector(S)
+ r:R * x:$ == [r * x.i for i in 1..n]
+
+@
+\section{domain DPMM DirectProductMatrixModule}
+<<domain DPMM DirectProductMatrixModule>>=
+)abbrev domain DPMM DirectProductMatrixModule
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This constructor provides a direct product type with a
+++ left matrix-module view.
+
+DirectProductMatrixModule(n, R, M, S): DPcategory == DPcapsule where
+ n: PositiveInteger
+ R: Ring
+ RowCol ==> DirectProduct(n,R)
+ M: SquareMatrixCategory(n,R,RowCol,RowCol)
+ S: LeftModule(R)
+
+ DPcategory == Join(DirectProductCategory(n,S), LeftModule(R), LeftModule(M))
+
+ DPcapsule == DirectProduct(n, S) add
+ Rep := Vector(S)
+ r:R * x:$ == [r*x.i for i in 1..n]
+ m:M * x:$ == [ +/[m(i,j)*x.j for j in 1..n] for i in 1..n]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category MLO MonogenicLinearOperator>>
+<<domain OMLO OppositeMonogenicLinearOperator>>
+<<package NCODIV NonCommutativeOperatorDivision>>
+<<domain ODR OrdinaryDifferentialRing>>
+<<domain DPMO DirectProductModule>>
+<<domain DPMM DirectProductMatrixModule>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/manip.spad.pamphlet b/src/algebra/manip.spad.pamphlet
new file mode 100644
index 00000000..2322ac7c
--- /dev/null
+++ b/src/algebra/manip.spad.pamphlet
@@ -0,0 +1,874 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra manip.spad}
+\author{Manuel Bronstein, Robert Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FACTFUNC FactoredFunctions}
+<<package FACTFUNC FactoredFunctions>>=
+)abbrev package FACTFUNC FactoredFunctions
+++ Author: Manuel Bronstein
+++ Date Created: 2 Feb 1988
+++ Date Last Updated: 25 Jun 1990
+++ Description: computes various functions on factored arguments.
+-- not visible to the user
+FactoredFunctions(M:IntegralDomain): Exports == Implementation where
+ N ==> NonNegativeInteger
+
+ Exports ==> with
+ nthRoot: (Factored M,N) -> Record(exponent:N,coef:M,radicand:List M)
+ ++ nthRoot(f, n) returns \spad{(p, r, [r1,...,rm])} such that
+ ++ the nth-root of f is equal to \spad{r * pth-root(r1 * ... * rm)},
+ ++ where r1,...,rm are distinct factors of f,
+ ++ each of which has an exponent smaller than p in f.
+ log : Factored M -> List Record(coef:N, logand:M)
+ ++ log(f) returns \spad{[(a1,b1),...,(am,bm)]} such that
+ ++ the logarithm of f is equal to \spad{a1*log(b1) + ... + am*log(bm)}.
+
+ Implementation ==> add
+ nthRoot(ff, n) ==
+ coeff:M := 1
+-- radi:List(M) := (one? unit ff => empty(); [unit ff])
+ radi:List(M) := (((unit ff) = 1) => empty(); [unit ff])
+ lf := factors ff
+ d:N :=
+ empty? radi => gcd(concat(n, [t.exponent::N for t in lf]))::N
+ 1
+ n := n quo d
+ for term in lf repeat
+ qr := divide(term.exponent::N quo d, n)
+ coeff := coeff * term.factor ** qr.quotient
+ not zero?(qr.remainder) =>
+ radi := concat_!(radi, term.factor ** qr.remainder)
+ [n, coeff, radi]
+
+ log ff ==
+ ans := unit ff
+ concat([1, unit ff],
+ [[term.exponent::N, term.factor] for term in factors ff])
+
+@
+\section{package POLYROOT PolynomialRoots}
+<<package POLYROOT PolynomialRoots>>=
+)abbrev package POLYROOT PolynomialRoots
+++ Author: Manuel Bronstein
+++ Date Created: 15 July 1988
+++ Date Last Updated: 10 November 1993
+++ Description: computes n-th roots of quotients of
+++ multivariate polynomials
+-- not visible to the user
+PolynomialRoots(E, V, R, P, F):Exports == Implementation where
+ E: OrderedAbelianMonoidSup
+ V: OrderedSet
+ R: IntegralDomain
+ P: PolynomialCategory(R, E, V)
+ F: Field with
+ numer : $ -> P
+ ++ numer(x) \undocumented
+ denom : $ -> P
+ ++ denom(x) \undocumented
+ coerce: P -> $
+ ++ coerce(p) \undocumented
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Z
+ REC ==> Record(exponent:N, coef:F, radicand:F)
+
+ Exports ==> with
+ rroot: (R, N) -> REC
+ ++ rroot(f, n) returns \spad{[m,c,r]} such
+ ++ that \spad{f**(1/n) = c * r**(1/m)}.
+ qroot : (Q, N) -> REC
+ ++ qroot(f, n) returns \spad{[m,c,r]} such
+ ++ that \spad{f**(1/n) = c * r**(1/m)}.
+ if R has GcdDomain then froot: (F, N) -> REC
+ ++ froot(f, n) returns \spad{[m,c,r]} such
+ ++ that \spad{f**(1/n) = c * r**(1/m)}.
+ nthr: (P, N) -> Record(exponent:N,coef:P,radicand:List P)
+ ++ nthr(p,n) should be local but conditional
+
+ Implementation ==> add
+ import FactoredFunctions Z
+ import FactoredFunctions P
+
+ rsplit: List P -> Record(coef:R, poly:P)
+ zroot : (Z, N) -> Record(exponent:N, coef:Z, radicand:Z)
+
+ zroot(x, n) ==
+-- zero? x or one? x => [1, x, 1]
+ zero? x or (x = 1) => [1, x, 1]
+ s := nthRoot(squareFree x, n)
+ [s.exponent, s.coef, */s.radicand]
+
+ if R has imaginary: () -> R then
+ czroot: (Z, N) -> REC
+
+ czroot(x, n) ==
+ rec := zroot(x, n)
+ rec.exponent = 2 and rec.radicand < 0 =>
+ [rec.exponent, rec.coef * imaginary()::P::F, (-rec.radicand)::F]
+ [rec.exponent, rec.coef::F, rec.radicand::F]
+
+ qroot(x, n) ==
+ sn := czroot(numer x, n)
+ sd := czroot(denom x, n)
+ m := lcm(sn.exponent, sd.exponent)::N
+ [m, sn.coef / sd.coef,
+ (sn.radicand ** (m quo sn.exponent)) /
+ (sd.radicand ** (m quo sd.exponent))]
+ else
+ qroot(x, n) ==
+ sn := zroot(numer x, n)
+ sd := zroot(denom x, n)
+ m := lcm(sn.exponent, sd.exponent)::N
+ [m, sn.coef::F / sd.coef::F,
+ (sn.radicand ** (m quo sn.exponent))::F /
+ (sd.radicand ** (m quo sd.exponent))::F]
+
+ if R has RetractableTo Fraction Z then
+ rroot(x, n) ==
+ (r := retractIfCan(x)@Union(Fraction Z,"failed")) case "failed"
+ => [n, 1, x::P::F]
+ qroot(r::Q, n)
+
+ else
+ if R has RetractableTo Z then
+ rroot(x, n) ==
+ (r := retractIfCan(x)@Union(Z,"failed")) case "failed"
+ => [n, 1, x::P::F]
+ qroot(r::Z::Q, n)
+ else
+ rroot(x, n) == [n, 1, x::P::F]
+
+ rsplit l ==
+ r := 1$R
+ p := 1$P
+ for q in l repeat
+ if (u := retractIfCan(q)@Union(R, "failed")) case "failed"
+ then p := p * q
+ else r := r * u::R
+ [r, p]
+
+ if R has GcdDomain then
+ if R has RetractableTo Z then
+ nthr(x, n) ==
+ (r := retractIfCan(x)@Union(Z,"failed")) case "failed"
+ => nthRoot(squareFree x, n)
+ rec := zroot(r::Z, n)
+ [rec.exponent, rec.coef::P, [rec.radicand::P]]
+ else nthr(x, n) == nthRoot(squareFree x, n)
+
+ froot(x, n) ==
+-- zero? x or one? x => [1, x, 1]
+ zero? x or (x = 1) => [1, x, 1]
+ sn := nthr(numer x, n)
+ sd := nthr(denom x, n)
+ pn := rsplit(sn.radicand)
+ pd := rsplit(sd.radicand)
+ rn := rroot(pn.coef, sn.exponent)
+ rd := rroot(pd.coef, sd.exponent)
+ m := lcm([rn.exponent, rd.exponent, sn.exponent, sd.exponent])::N
+ [m, (sn.coef::F / sd.coef::F) * (rn.coef / rd.coef),
+ ((rn.radicand ** (m quo rn.exponent)) /
+ (rd.radicand ** (m quo rd.exponent))) *
+ (pn.poly ** (m quo sn.exponent))::F /
+ (pd.poly ** (m quo sd.exponent))::F]
+
+
+@
+\section{package ALGMANIP AlgebraicManipulations}
+<<package ALGMANIP AlgebraicManipulations>>=
+)abbrev package ALGMANIP AlgebraicManipulations
+++ Author: Manuel Bronstein
+++ Date Created: 28 Mar 1988
+++ Date Last Updated: 5 August 1993
+++ Description:
+++ AlgebraicManipulations provides functions to simplify and expand
+++ expressions involving algebraic operators.
+++ Keywords: algebraic, manipulation.
+AlgebraicManipulations(R, F): Exports == Implementation where
+ R : IntegralDomain
+ F : Join(Field, ExpressionSpace) with
+ numer : $ -> SparseMultivariatePolynomial(R, Kernel $)
+ ++ numer(x) \undocumented
+ denom : $ -> SparseMultivariatePolynomial(R, Kernel $)
+ ++ denom(x) \undocumented
+ coerce : SparseMultivariatePolynomial(R, Kernel $) -> $
+ ++ coerce(x) \undocumented
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ OP ==> BasicOperator
+ SY ==> Symbol
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ RF ==> Fraction P
+ REC ==> Record(ker:List K, exponent: List Z)
+ ALGOP ==> "%alg"
+ NTHR ==> "nthRoot"
+
+ Exports ==> with
+ rootSplit: F -> F
+ ++ rootSplit(f) transforms every radical of the form
+ ++ \spad{(a/b)**(1/n)} appearing in f into \spad{a**(1/n) / b**(1/n)}.
+ ++ This transformation is not in general valid for all
+ ++ complex numbers \spad{a} and b.
+ ratDenom : F -> F
+ ++ ratDenom(f) rationalizes the denominators appearing in f
+ ++ by moving all the algebraic quantities into the numerators.
+ ratDenom : (F, F) -> F
+ ++ ratDenom(f, a) removes \spad{a} from the denominators in f
+ ++ if \spad{a} is an algebraic kernel.
+ ratDenom : (F, List F) -> F
+ ++ ratDenom(f, [a1,...,an]) removes the ai's which are
+ ++ algebraic kernels from the denominators in f.
+ ratDenom : (F, List K) -> F
+ ++ ratDenom(f, [a1,...,an]) removes the ai's which are
+ ++ algebraic from the denominators in f.
+ ratPoly : F -> SparseUnivariatePolynomial F
+ ++ ratPoly(f) returns a polynomial p such that p has no
+ ++ algebraic coefficients, and \spad{p(f) = 0}.
+ if R has Join(OrderedSet, GcdDomain, RetractableTo Integer)
+ and F has FunctionSpace(R) then
+ rootPower : F -> F
+ ++ rootPower(f) transforms every radical power of the form
+ ++ \spad{(a**(1/n))**m} into a simpler form if \spad{m} and
+ ++ \spad{n} have a common factor.
+ rootProduct: F -> F
+ ++ rootProduct(f) combines every product of the form
+ ++ \spad{(a**(1/n))**m * (a**(1/s))**t} into a single power
+ ++ of a root of \spad{a}, and transforms every radical power
+ ++ of the form \spad{(a**(1/n))**m} into a simpler form.
+ rootSimp : F -> F
+ ++ rootSimp(f) transforms every radical of the form
+ ++ \spad{(a * b**(q*n+r))**(1/n)} appearing in f into
+ ++ \spad{b**q * (a * b**r)**(1/n)}.
+ ++ This transformation is not in general valid for all
+ ++ complex numbers b.
+ rootKerSimp: (OP, F, N) -> F
+ ++ rootKerSimp(op,f,n) should be local but conditional.
+
+ Implementation ==> add
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,P,F)
+
+ innerRF : (F, List K) -> F
+ rootExpand : K -> F
+ algkernels : List K -> List K
+ rootkernels: List K -> List K
+
+ dummy := kernel(new()$SY)$K
+
+ ratDenom x == innerRF(x, algkernels tower x)
+ ratDenom(x:F, l:List K):F == innerRF(x, algkernels l)
+ ratDenom(x:F, y:F) == ratDenom(x, [y])
+ ratDenom(x:F, l:List F) == ratDenom(x, [retract(y)@K for y in l]$List(K))
+ algkernels l == select_!(has?(operator #1, ALGOP), l)
+ rootkernels l == select_!(is?(operator #1, NTHR::SY), l)
+
+ ratPoly x ==
+ numer univariate(denom(ratDenom inv(dummy::P::F - x))::F, dummy)
+
+ rootSplit x ==
+ lk := rootkernels tower x
+ eval(x, lk, [rootExpand k for k in lk])
+
+ rootExpand k ==
+ x := first argument k
+ n := second argument k
+ op := operator k
+ op(numer(x)::F, n) / op(denom(x)::F, n)
+
+-- all the kernels in ll must be algebraic
+ innerRF(x, ll) ==
+ empty?(l := sort_!(#1 > #2, kernels x)$List(K)) or
+ empty? setIntersection(ll, tower x) => x
+ lk := empty()$List(K)
+ while not member?(k := first l, ll) repeat
+ lk := concat(k, lk)
+ empty?(l := rest l) =>
+ return eval(x, lk, [map(innerRF(#1, ll), kk) for kk in lk])
+ q := univariate(eval(x, lk,
+ [map(innerRF(#1, ll), kk) for kk in lk]), k, minPoly k)
+ map(innerRF(#1, ll), q) (map(innerRF(#1, ll), k))
+
+ if R has Join(OrderedSet, GcdDomain, RetractableTo Integer)
+ and F has FunctionSpace(R) then
+ import PolynomialRoots(IndexedExponents K, K, R, P, F)
+
+ sroot : K -> F
+ inroot : (OP, F, N) -> F
+ radeval: (P, K) -> F
+ breakup: List K -> List REC
+
+ if R has RadicalCategory then
+ rootKerSimp(op, x, n) ==
+ (r := retractIfCan(x)@Union(R, "failed")) case R =>
+ nthRoot(r::R, n)::F
+ inroot(op, x, n)
+ else
+ rootKerSimp(op, x, n) == inroot(op, x, n)
+
+-- l is a list of nth-roots, returns a list of records of the form
+-- [a**(1/n1),a**(1/n2),...], [n1,n2,...]]
+-- such that the whole list covers l exactly
+ breakup l ==
+ empty? l => empty()
+ k := first l
+ a := first(arg := argument(k := first l))
+ n := retract(second arg)@Z
+ expo := empty()$List(Z)
+ others := same := empty()$List(K)
+ for kk in rest l repeat
+ if (a = first(arg := argument kk)) then
+ same := concat(kk, same)
+ expo := concat(retract(second arg)@Z, expo)
+ else others := concat(kk, others)
+ ll := breakup others
+ concat([concat(k, same), concat(n, expo)], ll)
+
+ rootProduct x ==
+ for rec in breakup rootkernels tower x repeat
+ k0 := first(l := rec.ker)
+ nx := numer x; dx := denom x
+ if empty? rest l then x := radeval(nx, k0) / radeval(dx, k0)
+ else
+ n := lcm(rec.exponent)
+ k := kernel(operator k0, [first argument k0, n::F], height k0)$K
+ lv := [monomial(1, k, (n quo m)::N) for m in rec.exponent]$List(P)
+ x := radeval(eval(nx, l, lv), k) / radeval(eval(dx, l, lv), k)
+ x
+
+ rootPower x ==
+ for k in rootkernels tower x repeat
+ x := radeval(numer x, k) / radeval(denom x, k)
+ x
+
+-- replaces (a**(1/n))**m in p by a power of a simpler radical of a if
+-- n and m have a common factor
+ radeval(p, k) ==
+ a := first(arg := argument k)
+ n := (retract(second arg)@Integer)::NonNegativeInteger
+ ans:F := 0
+ q := univariate(p, k)
+ while (d := degree q) > 0 repeat
+ term :=
+-- one?(g := gcd(d, n)) => monomial(1, k, d)
+ ((g := gcd(d, n)) = 1) => monomial(1, k, d)
+ monomial(1, kernel(operator k, [a,(n quo g)::F], height k), d quo g)
+ ans := ans + leadingCoefficient(q)::F * term::F
+ q := reductum q
+ leadingCoefficient(q)::F + ans
+
+ inroot(op, x, n) ==
+-- one? x => x
+ (x = 1) => x
+-- (x ^= -1) and (one?(num := numer x) or (num = -1)) =>
+ (x ^= -1) and (((num := numer x) = 1) or (num = -1)) =>
+ inv inroot(op, (num * denom x)::F, n)
+ (u := isExpt(x, op)) case "failed" => kernel(op, [x, n::F])
+ pr := u::Record(var:K, exponent:Integer)
+ q := pr.exponent /$Fraction(Z)
+ (n * retract(second argument(pr.var))@Z)
+ qr := divide(numer q, denom q)
+ x := first argument(pr.var)
+ x ** qr.quotient * rootKerSimp(op,x,denom(q)::N) ** qr.remainder
+
+ sroot k ==
+ pr := froot(first(arg := argument k),(retract(second arg)@Z)::N)
+ pr.coef * rootKerSimp(operator k, pr.radicand, pr.exponent)
+
+ rootSimp x ==
+ lk := rootkernels tower x
+ eval(x, lk, [sroot k for k in lk])
+
+@
+\section{package SIMPAN SimplifyAlgebraicNumberConvertPackage}
+<<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>=
+)abbrev package SIMPAN SimplifyAlgebraicNumberConvertPackage
+++ Package to allow simplify to be called on AlgebraicNumbers
+++ by converting to EXPR(INT)
+SimplifyAlgebraicNumberConvertPackage(): with
+ simplify: AlgebraicNumber -> Expression(Integer)
+ ++ simplify(an) applies simplifications to an
+ == add
+ simplify(a:AlgebraicNumber) ==
+ simplify(a::Expression(Integer))$TranscendentalManipulations(Integer, Expression Integer)
+
+@
+\section{package TRMANIP TranscendentalManipulations}
+<<package TRMANIP TranscendentalManipulations>>=
+)abbrev package TRMANIP TranscendentalManipulations
+++ Transformations on transcendental objects
+++ Author: Bob Sutor, Manuel Bronstein
+++ Date Created: Way back
+++ Date Last Updated: 22 January 1996, added simplifyLog MCD.
+++ Description:
+++ TranscendentalManipulations provides functions to simplify and
+++ expand expressions involving transcendental operators.
+++ Keywords: transcendental, manipulation.
+TranscendentalManipulations(R, F): Exports == Implementation where
+ R : Join(OrderedSet, GcdDomain)
+ F : Join(FunctionSpace R, TranscendentalFunctionCategory)
+
+ Z ==> Integer
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial P
+ POWER ==> "%power"::Symbol
+ POW ==> Record(val: F,exponent: Z)
+ PRODUCT ==> Record(coef : Z, var : K)
+ FPR ==> Fraction Polynomial R
+
+ Exports ==> with
+ expand : F -> F
+ ++ expand(f) performs the following expansions on f:\begin{items}
+ ++ \item 1. logs of products are expanded into sums of logs,
+ ++ \item 2. trigonometric and hyperbolic trigonometric functions
+ ++ of sums are expanded into sums of products of trigonometric
+ ++ and hyperbolic trigonometric functions.
+ ++ \item 3. formal powers of the form \spad{(a/b)**c} are expanded into
+ ++ \spad{a**c * b**(-c)}.
+ ++ \end{items}
+ simplify : F -> F
+ ++ simplify(f) performs the following simplifications on f:\begin{items}
+ ++ \item 1. rewrites trigs and hyperbolic trigs in terms
+ ++ of \spad{sin} ,\spad{cos}, \spad{sinh}, \spad{cosh}.
+ ++ \item 2. rewrites \spad{sin**2} and \spad{sinh**2} in terms
+ ++ of \spad{cos} and \spad{cosh},
+ ++ \item 3. rewrites \spad{exp(a)*exp(b)} as \spad{exp(a+b)}.
+ ++ \item 4. rewrites \spad{(a**(1/n))**m * (a**(1/s))**t} as a single
+ ++ power of a single radical of \spad{a}.
+ ++ \end{items}
+ htrigs : F -> F
+ ++ htrigs(f) converts all the exponentials in f into
+ ++ hyperbolic sines and cosines.
+ simplifyExp: F -> F
+ ++ simplifyExp(f) converts every product \spad{exp(a)*exp(b)}
+ ++ appearing in f into \spad{exp(a+b)}.
+ simplifyLog : F -> F
+ ++ simplifyLog(f) converts every \spad{log(a) - log(b)} appearing in f
+ ++ into \spad{log(a/b)}, every \spad{log(a) + log(b)} into \spad{log(a*b)}
+ ++ and every \spad{n*log(a)} into \spad{log(a^n)}.
+ expandPower: F -> F
+ ++ expandPower(f) converts every power \spad{(a/b)**c} appearing
+ ++ in f into \spad{a**c * b**(-c)}.
+ expandLog : F -> F
+ ++ expandLog(f) converts every \spad{log(a/b)} appearing in f into
+ ++ \spad{log(a) - log(b)}, and every \spad{log(a*b)} into
+ ++ \spad{log(a) + log(b)}..
+ cos2sec : F -> F
+ ++ cos2sec(f) converts every \spad{cos(u)} appearing in f into
+ ++ \spad{1/sec(u)}.
+ cosh2sech : F -> F
+ ++ cosh2sech(f) converts every \spad{cosh(u)} appearing in f into
+ ++ \spad{1/sech(u)}.
+ cot2trig : F -> F
+ ++ cot2trig(f) converts every \spad{cot(u)} appearing in f into
+ ++ \spad{cos(u)/sin(u)}.
+ coth2trigh : F -> F
+ ++ coth2trigh(f) converts every \spad{coth(u)} appearing in f into
+ ++ \spad{cosh(u)/sinh(u)}.
+ csc2sin : F -> F
+ ++ csc2sin(f) converts every \spad{csc(u)} appearing in f into
+ ++ \spad{1/sin(u)}.
+ csch2sinh : F -> F
+ ++ csch2sinh(f) converts every \spad{csch(u)} appearing in f into
+ ++ \spad{1/sinh(u)}.
+ sec2cos : F -> F
+ ++ sec2cos(f) converts every \spad{sec(u)} appearing in f into
+ ++ \spad{1/cos(u)}.
+ sech2cosh : F -> F
+ ++ sech2cosh(f) converts every \spad{sech(u)} appearing in f into
+ ++ \spad{1/cosh(u)}.
+ sin2csc : F -> F
+ ++ sin2csc(f) converts every \spad{sin(u)} appearing in f into
+ ++ \spad{1/csc(u)}.
+ sinh2csch : F -> F
+ ++ sinh2csch(f) converts every \spad{sinh(u)} appearing in f into
+ ++ \spad{1/csch(u)}.
+ tan2trig : F -> F
+ ++ tan2trig(f) converts every \spad{tan(u)} appearing in f into
+ ++ \spad{sin(u)/cos(u)}.
+ tanh2trigh : F -> F
+ ++ tanh2trigh(f) converts every \spad{tanh(u)} appearing in f into
+ ++ \spad{sinh(u)/cosh(u)}.
+ tan2cot : F -> F
+ ++ tan2cot(f) converts every \spad{tan(u)} appearing in f into
+ ++ \spad{1/cot(u)}.
+ tanh2coth : F -> F
+ ++ tanh2coth(f) converts every \spad{tanh(u)} appearing in f into
+ ++ \spad{1/coth(u)}.
+ cot2tan : F -> F
+ ++ cot2tan(f) converts every \spad{cot(u)} appearing in f into
+ ++ \spad{1/tan(u)}.
+ coth2tanh : F -> F
+ ++ coth2tanh(f) converts every \spad{coth(u)} appearing in f into
+ ++ \spad{1/tanh(u)}.
+ removeCosSq: F -> F
+ ++ removeCosSq(f) converts every \spad{cos(u)**2} appearing in f into
+ ++ \spad{1 - sin(x)**2}, and also reduces higher
+ ++ powers of \spad{cos(u)} with that formula.
+ removeSinSq: F -> F
+ ++ removeSinSq(f) converts every \spad{sin(u)**2} appearing in f into
+ ++ \spad{1 - cos(x)**2}, and also reduces higher powers of
+ ++ \spad{sin(u)} with that formula.
+ removeCoshSq:F -> F
+ ++ removeCoshSq(f) converts every \spad{cosh(u)**2} appearing in f into
+ ++ \spad{1 - sinh(x)**2}, and also reduces higher powers of
+ ++ \spad{cosh(u)} with that formula.
+ removeSinhSq:F -> F
+ ++ removeSinhSq(f) converts every \spad{sinh(u)**2} appearing in f into
+ ++ \spad{1 - cosh(x)**2}, and also reduces higher powers
+ ++ of \spad{sinh(u)} with that formula.
+ if R has PatternMatchable(R) and R has ConvertibleTo(Pattern(R)) and F has ConvertibleTo(Pattern(R)) and F has PatternMatchable R then
+ expandTrigProducts : F -> F
+ ++ expandTrigProducts(e) replaces \axiom{sin(x)*sin(y)} by
+ ++ \spad{(cos(x-y)-cos(x+y))/2}, \axiom{cos(x)*cos(y)} by
+ ++ \spad{(cos(x-y)+cos(x+y))/2}, and \axiom{sin(x)*cos(y)} by
+ ++ \spad{(sin(x-y)+sin(x+y))/2}. Note that this operation uses
+ ++ the pattern matcher and so is relatively expensive. To avoid
+ ++ getting into an infinite loop the transformations are applied
+ ++ at most ten times.
+
+ Implementation ==> add
+ import FactoredFunctions(P)
+ import PolynomialCategoryLifting(IndexedExponents K, K, R, P, F)
+ import
+ PolynomialCategoryQuotientFunctions(IndexedExponents K,K,R,P,F)
+
+ smpexp : P -> F
+ termexp : P -> F
+ exlog : P -> F
+ smplog : P -> F
+ smpexpand : P -> F
+ smp2htrigs: P -> F
+ kerexpand : K -> F
+ expandpow : K -> F
+ logexpand : K -> F
+ sup2htrigs: (UP, F) -> F
+ supexp : (UP, F, F, Z) -> F
+ ueval : (F, String, F -> F) -> F
+ ueval2 : (F, String, F -> F) -> F
+ powersimp : (P, List K) -> F
+ t2t : F -> F
+ c2t : F -> F
+ c2s : F -> F
+ s2c : F -> F
+ s2c2 : F -> F
+ th2th : F -> F
+ ch2th : F -> F
+ ch2sh : F -> F
+ sh2ch : F -> F
+ sh2ch2 : F -> F
+ simplify0 : F -> F
+ simplifyLog1 : F -> F
+ logArgs : List F -> F
+
+ import F
+ import List F
+
+ if R has PatternMatchable R and R has ConvertibleTo Pattern R and F has ConvertibleTo(Pattern(R)) and F has PatternMatchable R then
+ XX : F := coerce new()$Symbol
+ YY : F := coerce new()$Symbol
+ sinCosRule : RewriteRule(R,R,F) :=
+ rule(cos(XX)*sin(YY),(sin(XX+YY)-sin(XX-YY))/2::F)
+ sinSinRule : RewriteRule(R,R,F) :=
+ rule(sin(XX)*sin(YY),(cos(XX-YY)-cos(XX+YY))/2::F)
+ cosCosRule : RewriteRule(R,R,F) :=
+ rule(cos(XX)*cos(YY),(cos(XX-YY)+cos(XX+YY))/2::F)
+ expandTrigProducts(e:F):F ==
+ applyRules([sinCosRule,sinSinRule,cosCosRule],e,10)$ApplyRules(R,R,F)
+
+ logArgs(l:List F):F ==
+ -- This function will take a list of Expressions (implicitly a sum) and
+ -- add them up, combining log terms. It also replaces n*log(x) by
+ -- log(x^n).
+ import K
+ sum : F := 0
+ arg : F := 1
+ for term in l repeat
+ is?(term,"log"::Symbol) =>
+ arg := arg * simplifyLog(first(argument(first(kernels(term)))))
+ -- Now look for multiples, including negative ones.
+ prod : Union(PRODUCT, "failed") := isMult(term)
+ (prod case PRODUCT) and is?(prod.var,"log"::Symbol) =>
+ arg := arg * simplifyLog ((first argument(prod.var))**(prod.coef))
+ sum := sum+term
+ sum+log(arg)
+
+ simplifyLog(e:F):F ==
+ simplifyLog1(numerator e)/simplifyLog1(denominator e)
+
+ simplifyLog1(e:F):F ==
+ freeOf?(e,"log"::Symbol) => e
+
+ -- Check for n*log(u)
+ prod : Union(PRODUCT, "failed") := isMult(e)
+ (prod case PRODUCT) and is?(prod.var,"log"::Symbol) =>
+ log simplifyLog ((first argument(prod.var))**(prod.coef))
+
+ termList : Union(List(F),"failed") := isTimes(e)
+ -- I'm using two variables, termList and terms, to work round a
+ -- bug in the old compiler.
+ not (termList case "failed") =>
+ -- We want to simplify each log term in the product and then multiply
+ -- them together. However, if there is a constant or arithmetic
+ -- expression (i.e. somwthing which looks like a Polynomial) we would
+ -- like to combine it with a log term.
+ terms :List F := [simplifyLog(term) for term in termList::List(F)]
+ exprs :List F := []
+ for i in 1..#terms repeat
+ if retractIfCan(terms.i)@Union(FPR,"failed") case FPR then
+ exprs := cons(terms.i,exprs)
+ terms := delete!(terms,i)
+ if not empty? exprs then
+ foundLog := false
+ i : NonNegativeInteger := 0
+ while (not(foundLog) and (i < #terms)) repeat
+ i := i+1
+ if is?(terms.i,"log"::Symbol) then
+ args : List F := argument(retract(terms.i)@K)
+ setelt(terms,i, log simplifyLog1(first(args)**(*/exprs)))
+ foundLog := true
+ -- The next line deals with a situation which shouldn't occur,
+ -- since we have checked whether we are freeOf log already.
+ if not foundLog then terms := append(exprs,terms)
+ */terms
+
+ terms : Union(List(F),"failed") := isPlus(e)
+ not (terms case "failed") => logArgs(terms)
+
+ expt : Union(POW, "failed") := isPower(e)
+-- (expt case POW) and not one? expt.exponent =>
+ (expt case POW) and not (expt.exponent = 1) =>
+ simplifyLog(expt.val)**(expt.exponent)
+
+ kers : List K := kernels e
+-- not(one?(#kers)) => e -- Have a constant
+ not(((#kers) = 1)) => e -- Have a constant
+ kernel(operator first kers,[simplifyLog(u) for u in argument first kers])
+
+
+ if R has RetractableTo Integer then
+ simplify x == rootProduct(simplify0 x)$AlgebraicManipulations(R,F)
+
+ else simplify x == simplify0 x
+
+ expandpow k ==
+ a := expandPower first(arg := argument k)
+ b := expandPower second arg
+-- ne:F := (one? numer a => 1; numer(a)::F ** b)
+ ne:F := (((numer a) = 1) => 1; numer(a)::F ** b)
+-- de:F := (one? denom a => 1; denom(a)::F ** (-b))
+ de:F := (((denom a) = 1) => 1; denom(a)::F ** (-b))
+ ne * de
+
+ termexp p ==
+ exponent:F := 0
+ coef := (leadingCoefficient p)::P
+ lpow := select(is?(#1, POWER)$K, lk := variables p)$List(K)
+ for k in lk repeat
+ d := degree(p, k)
+ if is?(k, "exp"::Symbol) then
+ exponent := exponent + d * first argument k
+ else if not is?(k, POWER) then
+ -- Expand arguments to functions as well ... MCD 23/1/97
+ --coef := coef * monomial(1, k, d)
+ coef := coef * monomial(1, kernel(operator k,[simplifyExp u for u in argument k], height k), d)
+ coef::F * exp exponent * powersimp(p, lpow)
+
+ expandPower f ==
+ l := select(is?(#1, POWER)$K, kernels f)$List(K)
+ eval(f, l, [expandpow k for k in l])
+
+-- l is a list of pure powers appearing as kernels in p
+ powersimp(p, l) ==
+ empty? l => 1
+ k := first l -- k = a**b
+ a := first(arg := argument k)
+ exponent := degree(p, k) * second arg
+ empty?(lk := select(a = first argument #1, rest l)) =>
+ (a ** exponent) * powersimp(p, rest l)
+ for k0 in lk repeat
+ exponent := exponent + degree(p, k0) * second argument k0
+ (a ** exponent) * powersimp(p, setDifference(rest l, lk))
+
+ t2t x == sin(x) / cos(x)
+ c2t x == cos(x) / sin(x)
+ c2s x == inv sin x
+ s2c x == inv cos x
+ s2c2 x == 1 - cos(x)**2
+ th2th x == sinh(x) / cosh(x)
+ ch2th x == cosh(x) / sinh(x)
+ ch2sh x == inv sinh x
+ sh2ch x == inv cosh x
+ sh2ch2 x == cosh(x)**2 - 1
+ ueval(x, s,f) == eval(x, s::Symbol, f)
+ ueval2(x,s,f) == eval(x, s::Symbol, 2, f)
+ cos2sec x == ueval(x, "cos", inv sec #1)
+ sin2csc x == ueval(x, "sin", inv csc #1)
+ csc2sin x == ueval(x, "csc", c2s)
+ sec2cos x == ueval(x, "sec", s2c)
+ tan2cot x == ueval(x, "tan", inv cot #1)
+ cot2tan x == ueval(x, "cot", inv tan #1)
+ tan2trig x == ueval(x, "tan", t2t)
+ cot2trig x == ueval(x, "cot", c2t)
+ cosh2sech x == ueval(x, "cosh", inv sech #1)
+ sinh2csch x == ueval(x, "sinh", inv csch #1)
+ csch2sinh x == ueval(x, "csch", ch2sh)
+ sech2cosh x == ueval(x, "sech", sh2ch)
+ tanh2coth x == ueval(x, "tanh", inv coth #1)
+ coth2tanh x == ueval(x, "coth", inv tanh #1)
+ tanh2trigh x == ueval(x, "tanh", th2th)
+ coth2trigh x == ueval(x, "coth", ch2th)
+ removeCosSq x == ueval2(x, "cos", 1 - (sin #1)**2)
+ removeSinSq x == ueval2(x, "sin", s2c2)
+ removeCoshSq x== ueval2(x, "cosh", 1 + (sinh #1)**2)
+ removeSinhSq x== ueval2(x, "sinh", sh2ch2)
+ expandLog x == smplog(numer x) / smplog(denom x)
+ simplifyExp x == (smpexp numer x) / (smpexp denom x)
+ expand x == (smpexpand numer x) / (smpexpand denom x)
+ smpexpand p == map(kerexpand, #1::F, p)
+ smplog p == map(logexpand, #1::F, p)
+ smp2htrigs p == map(htrigs(#1::F), #1::F, p)
+
+ htrigs f ==
+ (m := mainKernel f) case "failed" => f
+ op := operator(k := m::K)
+ arg := [htrigs x for x in argument k]$List(F)
+ num := univariate(numer f, k)
+ den := univariate(denom f, k)
+ is?(op, "exp"::Symbol) =>
+ g1 := cosh(a := first arg) + sinh(a)
+ g2 := cosh(a) - sinh(a)
+ supexp(num,g1,g2,b:= (degree num)::Z quo 2)/supexp(den,g1,g2,b)
+ sup2htrigs(num, g1:= op arg) / sup2htrigs(den, g1)
+
+ supexp(p, f1, f2, bse) ==
+ ans:F := 0
+ while p ^= 0 repeat
+ g := htrigs(leadingCoefficient(p)::F)
+ if ((d := degree(p)::Z - bse) >= 0) then
+ ans := ans + g * f1 ** d
+ else ans := ans + g * f2 ** (-d)
+ p := reductum p
+ ans
+
+ sup2htrigs(p, f) ==
+ (map(smp2htrigs, p)$SparseUnivariatePolynomialFunctions2(P, F)) f
+
+ exlog p == +/[r.coef * log(r.logand::F) for r in log squareFree p]
+
+ logexpand k ==
+ nullary?(op := operator k) => k::F
+ is?(op, "log"::Symbol) =>
+ exlog(numer(x := expandLog first argument k)) - exlog denom x
+ op [expandLog x for x in argument k]$List(F)
+
+ kerexpand k ==
+ nullary?(op := operator k) => k::F
+ is?(op, POWER) => expandpow k
+ arg := first argument k
+ is?(op, "sec"::Symbol) => inv expand cos arg
+ is?(op, "csc"::Symbol) => inv expand sin arg
+ is?(op, "log"::Symbol) =>
+ exlog(numer(x := expand arg)) - exlog denom x
+ num := numer arg
+ den := denom arg
+ (b := (reductum num) / den) ^= 0 =>
+ a := (leadingMonomial num) / den
+ is?(op, "exp"::Symbol) => exp(expand a) * expand(exp b)
+ is?(op, "sin"::Symbol) =>
+ sin(expand a) * expand(cos b) + cos(expand a) * expand(sin b)
+ is?(op, "cos"::Symbol) =>
+ cos(expand a) * expand(cos b) - sin(expand a) * expand(sin b)
+ is?(op, "tan"::Symbol) =>
+ ta := tan expand a
+ tb := expand tan b
+ (ta + tb) / (1 - ta * tb)
+ is?(op, "cot"::Symbol) =>
+ cta := cot expand a
+ ctb := expand cot b
+ (cta * ctb - 1) / (ctb + cta)
+ op [expand x for x in argument k]$List(F)
+ op [expand x for x in argument k]$List(F)
+
+ smpexp p ==
+ ans:F := 0
+ while p ^= 0 repeat
+ ans := ans + termexp leadingMonomial p
+ p := reductum p
+ ans
+
+ -- this now works in 3 passes over the expression:
+ -- pass1 rewrites trigs and htrigs in terms of sin,cos,sinh,cosh
+ -- pass2 rewrites sin**2 and sinh**2 in terms of cos and cosh.
+ -- pass3 groups exponentials together
+ simplify0 x ==
+ simplifyExp eval(eval(x,
+ ["tan"::Symbol,"cot"::Symbol,"sec"::Symbol,"csc"::Symbol,
+ "tanh"::Symbol,"coth"::Symbol,"sech"::Symbol,"csch"::Symbol],
+ [t2t,c2t,s2c,c2s,th2th,ch2th,sh2ch,ch2sh]),
+ ["sin"::Symbol, "sinh"::Symbol], [2, 2], [s2c2, sh2ch2])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- op kl function funcpkgs MANIP combfunc
+-- algfunc elemntry constant funceval fe
+
+
+<<package FACTFUNC FactoredFunctions>>
+<<package POLYROOT PolynomialRoots>>
+<<package ALGMANIP AlgebraicManipulations>>
+<<package SIMPAN SimplifyAlgebraicNumberConvertPackage>>
+<<package TRMANIP TranscendentalManipulations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mappkg.spad.pamphlet b/src/algebra/mappkg.spad.pamphlet
new file mode 100644
index 00000000..f4d18db3
--- /dev/null
+++ b/src/algebra/mappkg.spad.pamphlet
@@ -0,0 +1,304 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mappkg.spad}
+\author{Stephen M. Watt, William Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MAPHACK1 MappingPackageInternalHacks1}
+<<package MAPHACK1 MappingPackageInternalHacks1>>=
+)abbrev package MAPHACK1 MappingPackageInternalHacks1
+++ Author: S.M.Watt and W.H.Burge
+++ Date Created:Jan 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: various Currying operations.
+MappingPackageInternalHacks1(A: SetCategory): MPcat == MPdef where
+ NNI ==> NonNegativeInteger
+
+ MPcat == with
+ iter: ((A -> A), NNI, A) -> A
+ ++\spad{iter(f,n,x)} applies \spad{f n} times to \spad{x}.
+ recur: ((NNI, A)->A, NNI, A) -> A
+ ++\spad{recur(n,g,x)} is \spad{g(n,g(n-1,..g(1,x)..))}.
+
+ MPdef == add
+ iter(g,n,x) ==
+ for i in 1..n repeat x := g x -- g(g(..(x)..))
+ x
+ recur(g,n,x) ==
+ for i in 1..n repeat x := g(i,x) -- g(n,g(n-1,..g(1,x)..))
+ x
+
+@
+\section{package MAPHACK2 MappingPackageInternalHacks2}
+<<package MAPHACK2 MappingPackageInternalHacks2>>=
+)abbrev package MAPHACK2 MappingPackageInternalHacks2
+++ Description: various Currying operations.
+MappingPackageInternalHacks2(A: SetCategory, C: SetCategory):_
+ MPcat == MPdef where
+ NNI ==> NonNegativeInteger
+
+ MPcat == with
+ arg1: (A, C) -> A
+ ++\spad{arg1(a,c)} selects its first argument.
+ arg2: (A, C) -> C
+ ++\spad{arg2(a,c)} selects its second argument.
+
+ MPdef == add
+ arg1(a, c) == a
+ arg2(a, c) == c
+
+@
+\section{package MAPHACK3 MappingPackageInternalHacks3}
+<<package MAPHACK3 MappingPackageInternalHacks3>>=
+)abbrev package MAPHACK3 MappingPackageInternalHacks3
+++ Description: various Currying operations.
+MappingPackageInternalHacks3(A: SetCategory, B: SetCategory, C: SetCategory):_
+ MPcat == MPdef where
+ NNI ==> NonNegativeInteger
+
+ MPcat == with
+ comp: (B->C, A->B, A) -> C
+ ++\spad{comp(f,g,x)} is \spad{f(g x)}.
+
+ MPdef == add
+ comp(g,h,x) == g h x
+
+@
+\section{package MAPPKG1 MappingPackage1}
+<<package MAPPKG1 MappingPackage1>>=
+)abbrev package MAPPKG1 MappingPackage1
+++ Author: S.M.Watt and W.H.Burge
+++ Date Created:Jan 87
+++ Date Last Updated:Feb 92
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: various Currying operations.
+MappingPackage1(A:SetCategory): MPcat == MPdef where
+ NNI ==> NonNegativeInteger
+
+ MPcat == with
+ nullary: A -> (()->A)
+ ++\spad{nullary A} changes its argument into a
+ ++ nullary function.
+ coerce: A -> (()->A)
+ ++\spad{coerce A} changes its argument into a
+ ++ nullary function.
+
+ fixedPoint: (A->A) -> A
+ ++\spad{fixedPoint f} is the fixed point of function \spad{f}.
+ ++ i.e. such that \spad{fixedPoint f = f(fixedPoint f)}.
+ fixedPoint: (List A->List A, Integer) -> List A
+ ++\spad{fixedPoint(f,n)} is the fixed point of function
+ ++ \spad{f} which is assumed to transform a list of length
+ ++ \spad{n}.
+
+
+ id: A -> A
+ ++\spad{id x} is \spad{x}.
+ "**": (A->A, NNI) -> (A->A)
+ ++\spad{f**n} is the function which is the n-fold application
+ ++ of \spad{f}.
+
+ recur: ((NNI, A)->A) -> ((NNI, A)->A)
+ ++\spad{recur(g)} is the function \spad{h} such that
+ ++ \spad{h(n,x)= g(n,g(n-1,..g(1,x)..))}.
+
+
+ MPdef == add
+
+ MappingPackageInternalHacks1(A)
+
+ a: A
+ faa: A -> A
+ f0a: ()-> A
+
+ nullary a == a
+ coerce a == nullary a
+ fixedPoint faa ==
+ g0 := GENSYM()$Lisp
+ g1 := faa g0
+ EQ(g0, g1)$Lisp => error "All points are fixed points"
+ GEQNSUBSTLIST([g0]$Lisp, [g1]$Lisp, g1)$Lisp
+
+ fixedPoint(fll, n) ==
+ g0 := [(GENSYM()$Lisp):A for i in 1..n]
+ g1 := fll g0
+ or/[EQ(e0,e1)$Lisp for e0 in g0 for e1 in g1] =>
+ error "All points are fixed points"
+ GEQNSUBSTLIST(g0, g1, g1)$Lisp
+
+ -- Composition and recursion.
+ id a == a
+ g**n == iter(g, n, #1)
+
+ recur fnaa == recur(fnaa, #1, #2)
+
+@
+\section{package MAPPKG2 MappingPackage2}
+<<package MAPPKG2 MappingPackage2>>=
+)abbrev package MAPPKG2 MappingPackage2
+++ Description: various Currying operations.
+MappingPackage2(A:SetCategory, C:SetCategory): MPcat == MPdef where
+ NNI ==> NonNegativeInteger
+
+ MPcat == with
+ const: C -> (A ->C)
+ ++\spad{const c} is a function which produces \spad{c} when
+ ++ applied to its argument.
+
+ curry: (A ->C, A) -> (()->C)
+ ++\spad{cu(f,a)} is the function \spad{g}
+ ++ such that \spad{g ()= f a}.
+ constant: (()->C) -> (A ->C)
+ ++\spad{vu(f)} is the function \spad{g}
+ ++ such that \spad{g a= f ()}.
+
+ diag: ((A,A)->C) -> (A->C)
+ ++\spad{diag(f)} is the function \spad{g}
+ ++ such that \spad{g a = f(a,a)}.
+
+
+ MPdef == add
+
+ MappingPackageInternalHacks2(A, C)
+
+ a: A
+ c: C
+ faa: A -> A
+ f0c: ()-> C
+ fac: A -> C
+ faac: (A,A)->C
+
+ const c == arg2(#1, c)
+ curry(fac, a) == fac a
+ constant f0c == arg2(#1, f0c())
+
+ diag faac == faac(#1, #1)
+
+@
+\section{package MAPPKG3 MappingPackage3}
+<<package MAPPKG3 MappingPackage3>>=
+)abbrev package MAPPKG3 MappingPackage3
+++ Description: various Currying operations.
+MappingPackage3(A:SetCategory, B:SetCategory, C:SetCategory):_
+ MPcat == MPdef where
+ NNI ==> NonNegativeInteger
+
+ MPcat == with
+ curryRight: ((A,B)->C, B) -> (A ->C)
+ ++\spad{curryRight(f,b)} is the function \spad{g} such that
+ ++ \spad{g a = f(a,b)}.
+ curryLeft: ((A,B)->C, A) -> (B ->C)
+ ++\spad{curryLeft(f,a)} is the function \spad{g}
+ ++ such that \spad{g b = f(a,b)}.
+
+ constantRight: (A -> C) -> ((A,B)->C)
+ ++\spad{constantRight(f)} is the function \spad{g}
+ ++ such that \spad{g (a,b)= f a}.
+ constantLeft: (B -> C) -> ((A,B)->C)
+ ++\spad{constantLeft(f)} is the function \spad{g}
+ ++ such that \spad{g (a,b)= f b}.
+
+ twist: ((A,B)->C) -> ((B,A)->C)
+ ++\spad{twist(f)} is the function \spad{g}
+ ++ such that \spad{g (a,b)= f(b,a)}.
+
+ "*": (B->C, A->B) -> (A->C)
+ ++\spad{f*g} is the function \spad{h}
+ ++ such that \spad{h x= f(g x)}.
+
+
+ MPdef == add
+
+ MappingPackageInternalHacks3(A, B, C)
+
+ a: A
+ b: B
+ c: C
+ faa: A -> A
+ f0c: ()-> C
+ fac: A -> C
+ fbc: B -> C
+ fab: A -> B
+ fabc: (A,B)->C
+ faac: (A,A)->C
+
+ -- Fix left and right arguments as constants.
+ curryRight(fabc,b) == fabc(#1,b)
+ curryLeft(fabc,a) == fabc(a, #1)
+
+ -- Add left and right arguments which are ignored.
+ constantRight fac == fac #1
+ constantLeft fbc == fbc #2
+
+ -- Combinators to rearrange arguments.
+ twist fabc == fabc(#2, #1)
+ -- Functional composition
+ fbc*fab == comp(fbc,fab,#1)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MAPHACK1 MappingPackageInternalHacks1>>
+<<package MAPHACK2 MappingPackageInternalHacks2>>
+<<package MAPHACK3 MappingPackageInternalHacks3>>
+<<package MAPPKG1 MappingPackage1>>
+<<package MAPPKG2 MappingPackage2>>
+<<package MAPPKG3 MappingPackage3>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/matcat.spad.pamphlet b/src/algebra/matcat.spad.pamphlet
new file mode 100644
index 00000000..f7bc1ef8
--- /dev/null
+++ b/src/algebra/matcat.spad.pamphlet
@@ -0,0 +1,904 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra matcat.spad}
+\author{Johannes Grabmeier, Oswald Gschnitzer, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category MATCAT MatrixCategory}
+<<category MATCAT MatrixCategory>>=
+)abbrev category MATCAT MatrixCategory
+++ Authors: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: Matrix(R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{MatrixCategory} is a general matrix category which allows
+++ different representations and indexing schemes. Rows and
+++ columns may be extracted with rows returned as objects of
+++ type Row and colums returned as objects of type Col.
+++ A domain belonging to this category will be shallowly mutable.
+++ The index of the 'first' row may be obtained by calling the
+++ function \spadfun{minRowIndex}. The index of the 'first' column may
+++ be obtained by calling the function \spadfun{minColIndex}. The index of
+++ the first element of a Row is the same as the index of the
+++ first column in a matrix and vice versa.
+MatrixCategory(R,Row,Col): Category == Definition where
+ R : Ring
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+
+ Definition ==> TwoDimensionalArrayCategory(R,Row,Col) with
+ shallowlyMutable
+ ++ One may destructively alter matrices
+
+ finiteAggregate
+ ++ matrices are finite
+
+--% Predicates
+
+ square? : % -> Boolean
+ ++ \spad{square?(m)} returns true if m is a square matrix
+ ++ (i.e. if m has the same number of rows as columns) and false otherwise.
+ diagonal?: % -> Boolean
+ ++ \spad{diagonal?(m)} returns true if the matrix m is square and
+ ++ diagonal (i.e. all entries of m not on the diagonal are zero) and
+ ++ false otherwise.
+ symmetric?: % -> Boolean
+ ++ \spad{symmetric?(m)} returns true if the matrix m is square and
+ ++ symmetric (i.e. \spad{m[i,j] = m[j,i]} for all i and j) and false
+ ++ otherwise.
+ antisymmetric?: % -> Boolean
+ ++ \spad{antisymmetric?(m)} returns true if the matrix m is square and
+ ++ antisymmetric (i.e. \spad{m[i,j] = -m[j,i]} for all i and j) and false
+ ++ otherwise.
+
+--% Creation
+
+ zero: (NonNegativeInteger,NonNegativeInteger) -> %
+ ++ \spad{zero(m,n)} returns an m-by-n zero matrix.
+ matrix: List List R -> %
+ ++ \spad{matrix(l)} converts the list of lists l to a matrix, where the
+ ++ list of lists is viewed as a list of the rows of the matrix.
+ scalarMatrix: (NonNegativeInteger,R) -> %
+ ++ \spad{scalarMatrix(n,r)} returns an n-by-n matrix with r's on the
+ ++ diagonal and zeroes elsewhere.
+ diagonalMatrix: List R -> %
+ ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
+ ++ of l on the diagonal.
+ diagonalMatrix: List % -> %
+ ++ \spad{diagonalMatrix([m1,...,mk])} creates a block diagonal matrix
+ ++ M with block matrices {\em m1},...,{\em mk} down the diagonal,
+ ++ with 0 block matrices elsewhere.
+ ++ More precisly: if \spad{ri := nrows mi}, \spad{ci := ncols mi},
+ ++ then m is an (r1+..+rk) by (c1+..+ck) - matrix with entries
+ ++ \spad{m.i.j = ml.(i-r1-..-r(l-1)).(j-n1-..-n(l-1))}, if
+ ++ \spad{(r1+..+r(l-1)) < i <= r1+..+rl} and
+ ++ \spad{(c1+..+c(l-1)) < i <= c1+..+cl},
+ ++ \spad{m.i.j} = 0 otherwise.
+ coerce: Col -> %
+ ++ \spad{coerce(col)} converts the column col to a column matrix.
+ transpose: Row -> %
+ ++ \spad{transpose(r)} converts the row r to a row matrix.
+
+--% Creation of new matrices from old
+
+ transpose: % -> %
+ ++ \spad{transpose(m)} returns the transpose of the matrix m.
+ squareTop: % -> %
+ ++ \spad{squareTop(m)} returns an n-by-n matrix consisting of the first
+ ++ n rows of the m-by-n matrix m. Error: if
+ ++ \spad{m < n}.
+ horizConcat: (%,%) -> %
+ ++ \spad{horizConcat(x,y)} horizontally concatenates two matrices with
+ ++ an equal number of rows. The entries of y appear to the right
+ ++ of the entries of x. Error: if the matrices
+ ++ do not have the same number of rows.
+ vertConcat: (%,%) -> %
+ ++ \spad{vertConcat(x,y)} vertically concatenates two matrices with an
+ ++ equal number of columns. The entries of y appear below
+ ++ of the entries of x. Error: if the matrices
+ ++ do not have the same number of columns.
+
+--% Part extractions/assignments
+
+ listOfLists: % -> List List R
+ ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
+ ++ of lists.
+ elt: (%,List Integer,List Integer) -> %
+ ++ \spad{elt(x,rowList,colList)} returns an m-by-n matrix consisting
+ ++ of elements of x, where \spad{m = # rowList} and \spad{n = # colList}.
+ ++ If \spad{rowList = [i<1>,i<2>,...,i<m>]} and \spad{colList =
+ ++ [j<1>,j<2>,...,j<n>]}, then the \spad{(k,l)}th entry of
+ ++ \spad{elt(x,rowList,colList)} is \spad{x(i<k>,j<l>)}.
+ setelt: (%,List Integer,List Integer, %) -> %
+ ++ \spad{setelt(x,rowList,colList,y)} destructively alters the matrix x.
+ ++ If y is \spad{m}-by-\spad{n}, \spad{rowList = [i<1>,i<2>,...,i<m>]}
+ ++ and \spad{colList = [j<1>,j<2>,...,j<n>]}, then \spad{x(i<k>,j<l>)}
+ ++ is set to \spad{y(k,l)} for \spad{k = 1,...,m} and \spad{l = 1,...,n}.
+ swapRows_!: (%,Integer,Integer) -> %
+ ++ \spad{swapRows!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
+ ++ rows of m. This destructively alters the matrix.
+ swapColumns_!: (%,Integer,Integer) -> %
+ ++ \spad{swapColumns!(m,i,j)} interchanges the \spad{i}th and \spad{j}th
+ ++ columns of m. This destructively alters the matrix.
+ subMatrix: (%,Integer,Integer,Integer,Integer) -> %
+ ++ \spad{subMatrix(x,i1,i2,j1,j2)} extracts the submatrix
+ ++ \spad{[x(i,j)]} where the index i ranges from \spad{i1} to \spad{i2}
+ ++ and the index j ranges from \spad{j1} to \spad{j2}.
+ setsubMatrix_!: (%,Integer,Integer,%) -> %
+ ++ \spad{setsubMatrix(x,i1,j1,y)} destructively alters the
+ ++ matrix x. Here \spad{x(i,j)} is set to \spad{y(i-i1+1,j-j1+1)} for
+ ++ \spad{i = i1,...,i1-1+nrows y} and \spad{j = j1,...,j1-1+ncols y}.
+
+--% Arithmetic
+
+ "+": (%,%) -> %
+ ++ \spad{x + y} is the sum of the matrices x and y.
+ ++ Error: if the dimensions are incompatible.
+ "-": (%,%) -> %
+ ++ \spad{x - y} is the difference of the matrices x and y.
+ ++ Error: if the dimensions are incompatible.
+ "-": % -> %
+ ++ \spad{-x} returns the negative of the matrix x.
+ "*": (%,%) -> %
+ ++ \spad{x * y} is the product of the matrices x and y.
+ ++ Error: if the dimensions are incompatible.
+ "*": (R,%) -> %
+ ++ \spad{r*x} is the left scalar multiple of the scalar r and the
+ ++ matrix x.
+ "*": (%,R) -> %
+ ++ \spad{x * r} is the right scalar multiple of the scalar r and the
+ ++ matrix x.
+ "*": (Integer,%) -> %
+ ++ \spad{n * x} is an integer multiple.
+ "*": (%,Col) -> Col
+ ++ \spad{x * c} is the product of the matrix x and the column vector c.
+ ++ Error: if the dimensions are incompatible.
+ "*": (Row,%) -> Row
+ ++ \spad{r * x} is the product of the row vector r and the matrix x.
+ ++ Error: if the dimensions are incompatible.
+ "**": (%,NonNegativeInteger) -> %
+ ++ \spad{x ** n} computes a non-negative integral power of the matrix x.
+ ++ Error: if the matrix is not square.
+ if R has IntegralDomain then
+ "exquo": (%,R) -> Union(%,"failed")
+ ++ \spad{exquo(m,r)} computes the exact quotient of the elements
+ ++ of m by r, returning \axiom{"failed"} if this is not possible.
+ if R has Field then
+ "/": (%,R) -> %
+ ++ \spad{m/r} divides the elements of m by r. Error: if \spad{r = 0}.
+
+--% Linear algebra
+
+ if R has EuclideanDomain then
+ rowEchelon: % -> %
+ ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+ if R has IntegralDomain then
+ rank: % -> NonNegativeInteger
+ ++ \spad{rank(m)} returns the rank of the matrix m.
+ nullity: % -> NonNegativeInteger
+ ++ \spad{nullity(m)} returns the nullity of the matrix m. This is
+ ++ the dimension of the null space of the matrix m.
+ nullSpace: % -> List Col
+ ++ \spad{nullSpace(m)} returns a basis for the null space of
+ ++ the matrix m.
+ if R has commutative("*") then
+ determinant: % -> R
+ ++ \spad{determinant(m)} returns the determinant of the matrix m.
+ ++ Error: if the matrix is not square.
+ minordet: % -> R
+ ++ \spad{minordet(m)} computes the determinant of the matrix m using
+ ++ minors. Error: if the matrix is not square.
+ if R has Field then
+ inverse: % -> Union(%,"failed")
+ ++ \spad{inverse(m)} returns the inverse of the matrix m.
+ ++ If the matrix is not invertible, "failed" is returned.
+ ++ Error: if the matrix is not square.
+ "**": (%,Integer) -> %
+ ++ \spad{m**n} computes an integral power of the matrix m.
+ ++ Error: if matrix is not square or if the matrix
+ ++ is square but not invertible.
+
+ add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+ mini ==> minIndex
+ maxi ==> maxIndex
+
+--% Predicates
+
+ square? x == nrows x = ncols x
+
+ diagonal? x ==
+ not square? x => false
+ for i in minr x .. maxr x repeat
+ for j in minc x .. maxc x | (j - minc x) ^= (i - minr x) repeat
+ not zero? qelt(x, i, j) => return false
+ true
+
+ symmetric? x ==
+ (nRows := nrows x) ^= ncols x => false
+ mr := minRowIndex x; mc := minColIndex x
+ for i in 0..(nRows - 1) repeat
+ for j in (i + 1)..(nRows - 1) repeat
+ qelt(x,mr + i,mc + j) ^= qelt(x,mr + j,mc + i) => return false
+ true
+
+ antisymmetric? x ==
+ (nRows := nrows x) ^= ncols x => false
+ mr := minRowIndex x; mc := minColIndex x
+ for i in 0..(nRows - 1) repeat
+ for j in i..(nRows - 1) repeat
+ qelt(x,mr + i,mc + j) ^= -qelt(x,mr + j,mc + i) =>
+ return false
+ true
+
+--% Creation of matrices
+
+ zero(rows,cols) == new(rows,cols,0)
+
+ matrix(l: List List R) ==
+ null l => new(0,0,0)
+ -- error check: this is a top level function
+ rows : NonNegativeInteger := 1; cols := # first l
+ cols = 0 => error "matrices with zero columns are not supported"
+ for ll in rest l repeat
+ cols ^= # ll => error "matrix: rows of different lengths"
+ rows := rows + 1
+ ans := new(rows,cols,0)
+ for i in minr(ans)..maxr(ans) for ll in l repeat
+ for j in minc(ans)..maxc(ans) for r in ll repeat
+ qsetelt_!(ans,i,j,r)
+ ans
+
+ scalarMatrix(n,r) ==
+ ans := zero(n,n)
+ for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) repeat
+ qsetelt_!(ans,i,j,r)
+ ans
+
+ diagonalMatrix(l: List R) ==
+ n := #l; ans := zero(n,n)
+ for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) _
+ for r in l repeat qsetelt_!(ans,i,j,r)
+ ans
+
+ diagonalMatrix(list: List %) ==
+ rows : NonNegativeInteger := 0
+ cols : NonNegativeInteger := 0
+ for mat in list repeat
+ rows := rows + nrows mat
+ cols := cols + ncols mat
+ ans := zero(rows,cols)
+ loR := minr ans; loC := minc ans
+ for mat in list repeat
+ hiR := loR + nrows(mat) - 1; hiC := loC + nrows(mat) - 1
+ for i in loR..hiR for k in minr(mat)..maxr(mat) repeat
+ for j in loC..hiC for l in minc(mat)..maxc(mat) repeat
+ qsetelt_!(ans,i,j,qelt(mat,k,l))
+ loR := hiR + 1; loC := hiC + 1
+ ans
+
+ coerce(v:Col) ==
+ x := new(#v,1,0)
+ one := minc(x)
+ for i in minr(x)..maxr(x) for k in mini(v)..maxi(v) repeat
+ qsetelt_!(x,i,one,qelt(v,k))
+ x
+
+ transpose(v:Row) ==
+ x := new(1,#v,0)
+ one := minr(x)
+ for j in minc(x)..maxc(x) for k in mini(v)..maxi(v) repeat
+ qsetelt_!(x,one,j,qelt(v,k))
+ x
+
+ transpose(x:%) ==
+ ans := new(ncols x,nrows x,0)
+ for i in minr(ans)..maxr(ans) repeat
+ for j in minc(ans)..maxc(ans) repeat
+ qsetelt_!(ans,i,j,qelt(x,j,i))
+ ans
+
+ squareTop x ==
+ nrows x < (cols := ncols x) =>
+ error "squareTop: number of columns exceeds number of rows"
+ ans := new(cols,cols,0)
+ for i in minr(x)..(minr(x) + cols - 1) repeat
+ for j in minc(x)..maxc(x) repeat
+ qsetelt_!(ans,i,j,qelt(x,i,j))
+ ans
+
+ horizConcat(x,y) ==
+ (rows := nrows x) ^= nrows y =>
+ error "HConcat: matrices must have same number of rows"
+ ans := new(rows,(cols := ncols x) + ncols y,0)
+ for i in minr(x)..maxr(x) repeat
+ for j in minc(x)..maxc(x) repeat
+ qsetelt_!(ans,i,j,qelt(x,i,j))
+ for i in minr(y)..maxr(y) repeat
+ for j in minc(y)..maxc(y) repeat
+ qsetelt_!(ans,i,j + cols,qelt(y,i,j))
+ ans
+
+ vertConcat(x,y) ==
+ (cols := ncols x) ^= ncols y =>
+ error "HConcat: matrices must have same number of columns"
+ ans := new((rows := nrows x) + nrows y,cols,0)
+ for i in minr(x)..maxr(x) repeat
+ for j in minc(x)..maxc(x) repeat
+ qsetelt_!(ans,i,j,qelt(x,i,j))
+ for i in minr(y)..maxr(y) repeat
+ for j in minc(y)..maxc(y) repeat
+ qsetelt_!(ans,i + rows,j,qelt(y,i,j))
+ ans
+
+--% Part extraction/assignment
+
+ listOfLists x ==
+ ll : List List R := nil()
+ for i in maxr(x)..minr(x) by -1 repeat
+ l : List R := nil()
+ for j in maxc(x)..minc(x) by -1 repeat
+ l := cons(qelt(x,i,j),l)
+ ll := cons(l,ll)
+ ll
+
+ swapRows_!(x,i1,i2) ==
+ (i1 < minr(x)) or (i1 > maxr(x)) or (i2 < minr(x)) or _
+ (i2 > maxr(x)) => error "swapRows!: index out of range"
+ i1 = i2 => x
+ for j in minc(x)..maxc(x) repeat
+ r := qelt(x,i1,j)
+ qsetelt_!(x,i1,j,qelt(x,i2,j))
+ qsetelt_!(x,i2,j,r)
+ x
+
+ swapColumns_!(x,j1,j2) ==
+ (j1 < minc(x)) or (j1 > maxc(x)) or (j2 < minc(x)) or _
+ (j2 > maxc(x)) => error "swapColumns!: index out of range"
+ j1 = j2 => x
+ for i in minr(x)..maxr(x) repeat
+ r := qelt(x,i,j1)
+ qsetelt_!(x,i,j1,qelt(x,i,j2))
+ qsetelt_!(x,i,j2,r)
+ x
+
+ elt(x:%,rowList:List Integer,colList:List Integer) ==
+ for ei in rowList repeat
+ (ei < minr(x)) or (ei > maxr(x)) =>
+ error "elt: index out of range"
+ for ej in colList repeat
+ (ej < minc(x)) or (ej > maxc(x)) =>
+ error "elt: index out of range"
+ y := new(# rowList,# colList,0)
+ for ei in rowList for i in minr(y)..maxr(y) repeat
+ for ej in colList for j in minc(y)..maxc(y) repeat
+ qsetelt_!(y,i,j,qelt(x,ei,ej))
+ y
+
+ setelt(x:%,rowList:List Integer,colList:List Integer,y:%) ==
+ for ei in rowList repeat
+ (ei < minr(x)) or (ei > maxr(x)) =>
+ error "setelt: index out of range"
+ for ej in colList repeat
+ (ej < minc(x)) or (ej > maxc(x)) =>
+ error "setelt: index out of range"
+ ((# rowList) ^= (nrows y)) or ((# colList) ^= (ncols y)) =>
+ error "setelt: matrix has bad dimensions"
+ for ei in rowList for i in minr(y)..maxr(y) repeat
+ for ej in colList for j in minc(y)..maxc(y) repeat
+ qsetelt_!(x,ei,ej,qelt(y,i,j))
+ y
+
+ subMatrix(x,i1,i2,j1,j2) ==
+ (i2 < i1) => error "subMatrix: bad row indices"
+ (j2 < j1) => error "subMatrix: bad column indices"
+ (i1 < minr(x)) or (i2 > maxr(x)) =>
+ error "subMatrix: index out of range"
+ (j1 < minc(x)) or (j2 > maxc(x)) =>
+ error "subMatrix: index out of range"
+ rows := (i2 - i1 + 1) pretend NonNegativeInteger
+ cols := (j2 - j1 + 1) pretend NonNegativeInteger
+ y := new(rows,cols,0)
+ for i in minr(y)..maxr(y) for k in i1..i2 repeat
+ for j in minc(y)..maxc(y) for l in j1..j2 repeat
+ qsetelt_!(y,i,j,qelt(x,k,l))
+ y
+
+ setsubMatrix_!(x,i1,j1,y) ==
+ i2 := i1 + nrows(y) -1
+ j2 := j1 + ncols(y) -1
+ (i1 < minr(x)) or (i2 > maxr(x)) =>
+ error "setsubMatrix!: inserted matrix too big, use subMatrix to restrict it"
+ (j1 < minc(x)) or (j2 > maxc(x)) =>
+ error "setsubMatrix!: inserted matrix too big, use subMatrix to restrict it"
+ for i in minr(y)..maxr(y) for k in i1..i2 repeat
+ for j in minc(y)..maxc(y) for l in j1..j2 repeat
+ qsetelt_!(x,k,l,qelt(y,i,j))
+ x
+
+--% Arithmetic
+
+ x + y ==
+ ((r := nrows x) ^= nrows y) or ((c := ncols x) ^= ncols y) =>
+ error "can't add matrices of different dimensions"
+ ans := new(r,c,0)
+ for i in minr(x)..maxr(x) repeat
+ for j in minc(x)..maxc(x) repeat
+ qsetelt_!(ans,i,j,qelt(x,i,j) + qelt(y,i,j))
+ ans
+
+ x - y ==
+ ((r := nrows x) ^= nrows y) or ((c := ncols x) ^= ncols y) =>
+ error "can't subtract matrices of different dimensions"
+ ans := new(r,c,0)
+ for i in minr(x)..maxr(x) repeat
+ for j in minc(x)..maxc(x) repeat
+ qsetelt_!(ans,i,j,qelt(x,i,j) - qelt(y,i,j))
+ ans
+
+ - x == map(- #1,x)
+
+ a:R * x:% == map(a * #1,x)
+ x:% * a:R == map(#1 * a,x)
+ m:Integer * x:% == map(m * #1,x)
+
+ x:% * y:% ==
+ (ncols x ^= nrows y) =>
+ error "can't multiply matrices of incompatible dimensions"
+ ans := new(nrows x,ncols y,0)
+ for i in minr(x)..maxr(x) repeat
+ for j in minc(y)..maxc(y) repeat
+ entry :=
+ sum : R := 0
+ for k in minr(y)..maxr(y) for l in minc(x)..maxc(x) repeat
+ sum := sum + qelt(x,i,l) * qelt(y,k,j)
+ sum
+ qsetelt_!(ans,i,j,entry)
+ ans
+
+ positivePower:(%,Integer) -> %
+ positivePower(x,n) ==
+-- one? n => x
+ (n = 1) => x
+ odd? n => x * positivePower(x,n - 1)
+ y := positivePower(x,n quo 2)
+ y * y
+
+ x:% ** n:NonNegativeInteger ==
+ not((nn:= nrows x) = ncols x) => error "**: matrix must be square"
+ zero? n => scalarMatrix(nn,1)
+ positivePower(x,n)
+
+ --if R has ConvertibleTo InputForm then
+ --convert(x:%):InputForm ==
+ --convert [convert("matrix"::Symbol)@InputForm,
+ --convert listOfLists x]$List(InputForm)
+
+ if Col has shallowlyMutable then
+
+ x:% * v:Col ==
+ ncols(x) ^= #v =>
+ error "can't multiply matrix A and vector v if #cols A ^= #v"
+ w : Col := new(nrows x,0)
+ for i in minr(x)..maxr(x) for k in mini(w)..maxi(w) repeat
+ w.k :=
+ sum : R := 0
+ for j in minc(x)..maxc(x) for l in mini(v)..maxi(v) repeat
+ sum := sum + qelt(x,i,j) * v(l)
+ sum
+ w
+
+ if Row has shallowlyMutable then
+
+ v:Row * x:% ==
+ nrows(x) ^= #v =>
+ error "can't multiply vector v and matrix A if #rows A ^= #v"
+ w : Row := new(ncols x,0)
+ for j in minc(x)..maxc(x) for k in mini(w)..maxi(w) repeat
+ w.k :=
+ sum : R := 0
+ for i in minr(x)..maxr(x) for l in mini(v)..maxi(v) repeat
+ sum := sum + qelt(x,i,j) * v(l)
+ sum
+ w
+
+ if R has IntegralDomain then
+ x exquo a ==
+ ans := new(nrows x,ncols x,0)
+ for i in minr(x)..maxr(x) repeat
+ for j in minc(x)..maxc(x) repeat
+ entry :=
+ (r := (qelt(x,i,j) exquo a)) case "failed" =>
+ return "failed"
+ r :: R
+ qsetelt_!(ans,i,j,entry)
+ ans
+
+ if R has Field then
+ x / r == map(#1 / r,x)
+
+ x:% ** n:Integer ==
+ not((nn:= nrows x) = ncols x) => error "**: matrix must be square"
+ zero? n => scalarMatrix(nn,1)
+ positive? n => positivePower(x,n)
+ (xInv := inverse x) case "failed" =>
+ error "**: matrix must be invertible"
+ positivePower(xInv :: %,-n)
+
+@
+\section{category RMATCAT RectangularMatrixCategory}
+<<category RMATCAT RectangularMatrixCategory>>=
+)abbrev category RMATCAT RectangularMatrixCategory
+++ Authors: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: RectangularMatrix(m,n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{RectangularMatrixCategory} is a category of matrices of fixed
+++ dimensions. The dimensions of the matrix will be parameters of the
+++ domain. Domains in this category will be R-modules and will be
+++ non-mutable.
+RectangularMatrixCategory(m,n,R,Row,Col): Category == Definition where
+ m,n : NonNegativeInteger
+ R : Ring
+ Row : DirectProductCategory(n,R)
+ Col : DirectProductCategory(m,R)
+
+ Definition ==> Join(BiModule(R,R),HomogeneousAggregate(R)) with
+
+ finiteAggregate
+ ++ matrices are finite
+
+ if R has CommutativeRing then Module(R)
+
+--% Matrix creation
+
+ matrix: List List R -> %
+ ++ \spad{matrix(l)} converts the list of lists l to a matrix, where the
+ ++ list of lists is viewed as a list of the rows of the matrix.
+
+--% Predicates
+
+ square? : % -> Boolean
+ ++ \spad{square?(m)} returns true if m is a square matrix (i.e. if m
+ ++ has the same number of rows as columns) and false otherwise.
+ diagonal?: % -> Boolean
+ ++ \spad{diagonal?(m)} returns true if the matrix m is square and diagonal
+ ++ (i.e. all entries of m not on the diagonal are zero) and false
+ ++ otherwise.
+ symmetric?: % -> Boolean
+ ++ \spad{symmetric?(m)} returns true if the matrix m is square and
+ ++ symmetric (i.e. \spad{m[i,j] = m[j,i]} for all \spad{i} and j) and
+ ++ false otherwise.
+ antisymmetric?: % -> Boolean
+ ++ \spad{antisymmetric?(m)} returns true if the matrix m is square and
+ ++ antisymmetric (i.e. \spad{m[i,j] = -m[j,i]} for all \spad{i} and j)
+ ++ and false otherwise.
+
+--% Size inquiries
+
+ minRowIndex : % -> Integer
+ ++ \spad{minRowIndex(m)} returns the index of the 'first' row of the
+ ++ matrix m.
+ maxRowIndex : % -> Integer
+ ++ \spad{maxRowIndex(m)} returns the index of the 'last' row of the
+ ++ matrix m.
+ minColIndex : % -> Integer
+ ++ \spad{minColIndex(m)} returns the index of the 'first' column of the
+ ++ matrix m.
+ maxColIndex : % -> Integer
+ ++ \spad{maxColIndex(m)} returns the index of the 'last' column of the
+ ++ matrix m.
+ nrows : % -> NonNegativeInteger
+ ++ \spad{nrows(m)} returns the number of rows in the matrix m.
+ ncols : % -> NonNegativeInteger
+ ++ \spad{ncols(m)} returns the number of columns in the matrix m.
+
+--% Part extractions
+
+ listOfLists: % -> List List R
+ ++ \spad{listOfLists(m)} returns the rows of the matrix m as a list
+ ++ of lists.
+ elt: (%,Integer,Integer) -> R
+ ++ \spad{elt(m,i,j)} returns the element in the \spad{i}th row and
+ ++ \spad{j}th column of the matrix m.
+ ++ Error: if indices are outside the proper
+ ++ ranges.
+ qelt: (%,Integer,Integer) -> R
+ ++ \spad{qelt(m,i,j)} returns the element in the \spad{i}th row and
+ ++ \spad{j}th column of
+ ++ the matrix m. Note: there is NO error check to determine if indices are
+ ++ in the proper ranges.
+ elt: (%,Integer,Integer,R) -> R
+ ++ \spad{elt(m,i,j,r)} returns the element in the \spad{i}th row and
+ ++ \spad{j}th column of the matrix m, if m has an \spad{i}th row and a
+ ++ \spad{j}th column, and returns r otherwise.
+ row: (%,Integer) -> Row
+ ++ \spad{row(m,i)} returns the \spad{i}th row of the matrix m.
+ ++ Error: if the index is outside the proper range.
+ column: (%,Integer) -> Col
+ ++ \spad{column(m,j)} returns the \spad{j}th column of the matrix m.
+ ++ Error: if the index outside the proper range.
+
+--% Map and Zip
+
+ map: (R -> R,%) -> %
+ ++ \spad{map(f,a)} returns b, where \spad{b(i,j) = a(i,j)} for all i, j.
+ map:((R,R) -> R,%,%) -> %
+ ++ \spad{map(f,a,b)} returns c, where c is such that
+ ++ \spad{c(i,j) = f(a(i,j),b(i,j))} for all \spad{i}, j.
+
+--% Arithmetic
+
+ if R has IntegralDomain then
+ "exquo": (%,R) -> Union(%,"failed")
+ ++ \spad{exquo(m,r)} computes the exact quotient of the elements
+ ++ of m by r, returning \axiom{"failed"} if this is not possible.
+ if R has Field then
+ "/": (%,R) -> %
+ ++ \spad{m/r} divides the elements of m by r. Error: if \spad{r = 0}.
+
+--% Linear algebra
+
+ if R has EuclideanDomain then
+ rowEchelon: % -> %
+ ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+ if R has IntegralDomain then
+ rank: % -> NonNegativeInteger
+ ++ \spad{rank(m)} returns the rank of the matrix m.
+ nullity: % -> NonNegativeInteger
+ ++ \spad{nullity(m)} returns the nullity of the matrix m. This is
+ ++ the dimension of the null space of the matrix m.
+ nullSpace: % -> List Col
+ ++ \spad{nullSpace(m)}+ returns a basis for the null space of
+ ++ the matrix m.
+ add
+ nrows x == m
+ ncols x == n
+ square? x == m = n
+
+ diagonal? x ==
+ not square? x => false
+ for i in minRowIndex x .. maxRowIndex x repeat
+ for j in minColIndex x .. maxColIndex x
+ | (j - minColIndex x) ^= (i - minRowIndex x) repeat
+ not zero? qelt(x, i, j) => return false
+ true
+
+ symmetric? x ==
+ m ^= n => false
+ mr := minRowIndex x; mc := minColIndex x
+ for i in 0..(n - 1) repeat
+ for j in (i + 1)..(n - 1) repeat
+ qelt(x,mr + i,mc + j) ^= qelt(x,mr + j,mc + i) => return false
+ true
+
+ antisymmetric? x ==
+ m ^= n => false
+ mr := minRowIndex x; mc := minColIndex x
+ for i in 0..(n - 1) repeat
+ for j in i..(n - 1) repeat
+ qelt(x,mr + i,mc + j) ^= -qelt(x,mr + j,mc + i) =>
+ return false
+ true
+
+@
+\section{category SMATCAT SquareMatrixCategory}
+<<category SMATCAT SquareMatrixCategory>>=
+)abbrev category SMATCAT SquareMatrixCategory
+++ Authors: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: SquareMatrix(ndim,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{SquareMatrixCategory} is a general square matrix category which
+++ allows different representations and indexing schemes. Rows and
+++ columns may be extracted with rows returned as objects of
+++ type Row and colums returned as objects of type Col.
+SquareMatrixCategory(ndim,R,Row,Col): Category == Definition where
+ ndim : NonNegativeInteger
+ R : Ring
+ Row : DirectProductCategory(ndim,R)
+ Col : DirectProductCategory(ndim,R)
+ I ==> Integer
+
+ Definition ==> Join(DifferentialExtension R, BiModule(R, R),_
+ RectangularMatrixCategory(ndim,ndim,R,Row,Col),_
+ FullyRetractableTo R,_
+ FullyLinearlyExplicitRingOver R) with
+ if R has CommutativeRing then Module(R)
+ scalarMatrix: R -> %
+ ++ \spad{scalarMatrix(r)} returns an n-by-n matrix with r's on the
+ ++ diagonal and zeroes elsewhere.
+ diagonalMatrix: List R -> %
+ ++ \spad{diagonalMatrix(l)} returns a diagonal matrix with the elements
+ ++ of l on the diagonal.
+ diagonal: % -> Row
+ ++ \spad{diagonal(m)} returns a row consisting of the elements on the
+ ++ diagonal of the matrix m.
+ trace: % -> R
+ ++ \spad{trace(m)} returns the trace of the matrix m. this is the sum
+ ++ of the elements on the diagonal of the matrix m.
+ diagonalProduct: % -> R
+ ++ \spad{diagonalProduct(m)} returns the product of the elements on the
+ ++ diagonal of the matrix m.
+ "*": (%,Col) -> Col
+ ++ \spad{x * c} is the product of the matrix x and the column vector c.
+ ++ Error: if the dimensions are incompatible.
+ "*": (Row,%) -> Row
+ ++ \spad{r * x} is the product of the row vector r and the matrix x.
+ ++ Error: if the dimensions are incompatible.
+
+--% Linear algebra
+
+ if R has commutative("*") then
+ Algebra R
+ determinant: % -> R
+ ++ \spad{determinant(m)} returns the determinant of the matrix m.
+ minordet: % -> R
+ ++ \spad{minordet(m)} computes the determinant of the matrix m
+ ++ using minors.
+ if R has Field then
+ inverse: % -> Union(%,"failed")
+ ++ \spad{inverse(m)} returns the inverse of the matrix m, if that
+ ++ matrix is invertible and returns "failed" otherwise.
+ "**": (%,Integer) -> %
+ ++ \spad{m**n} computes an integral power of the matrix m.
+ ++ Error: if the matrix is not invertible.
+
+ add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+ mini ==> minIndex
+ maxi ==> maxIndex
+
+ positivePower:(%,Integer) -> %
+ positivePower(x,n) ==
+-- one? n => x
+ (n = 1) => x
+ odd? n => x * positivePower(x,n - 1)
+ y := positivePower(x,n quo 2)
+ y * y
+
+ x:% ** n:NonNegativeInteger ==
+ zero? n => scalarMatrix 1
+ positivePower(x,n)
+
+ coerce(r:R) == scalarMatrix r
+
+ equation2R: Vector % -> Matrix R
+
+ differentiate(x:%,d:R -> R) == map(d,x)
+
+ diagonal x ==
+ v:Vector(R) := new(ndim,0)
+ for i in minr x .. maxr x
+ for j in minc x .. maxc x
+ for k in minIndex v .. maxIndex v repeat
+ qsetelt_!(v, k, qelt(x, i, j))
+ directProduct v
+
+ retract(x:%):R ==
+ diagonal? x => retract diagonal x
+ error "Not retractable"
+
+ retractIfCan(x:%):Union(R, "failed") ==
+ diagonal? x => retractIfCan diagonal x
+ "failed"
+
+ equation2R v ==
+ ans:Matrix(Col) := new(ndim,#v,0)
+ for i in minr ans .. maxr ans repeat
+ for j in minc ans .. maxc ans repeat
+ qsetelt_!(ans, i, j, column(qelt(v, j), i))
+ reducedSystem ans
+
+ reducedSystem(x:Matrix %):Matrix(R) ==
+ empty? x => new(0,0,0)
+ reduce(vertConcat, [equation2R row(x, i)
+ for i in minr x .. maxr x])$List(Matrix R)
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix R, vec:Vector R) ==
+ vh:Vector(R) :=
+ empty? v => new(0,0)
+ rh := reducedSystem(v::Matrix %)@Matrix(R)
+ column(rh, minColIndex rh)
+ [reducedSystem(m)@Matrix(R), vh]
+
+ trace x ==
+ tr : R := 0
+ for i in minr(x)..maxr(x) for j in minc(x)..maxc(x) repeat
+ tr := tr + x(i,j)
+ tr
+
+ diagonalProduct x ==
+ pr : R := 1
+ for i in minr(x)..maxr(x) for j in minc(x)..maxc(x) repeat
+ pr := pr * x(i,j)
+ pr
+
+ if R has Field then
+
+ x:% ** n:Integer ==
+ zero? n => scalarMatrix 1
+ positive? n => positivePower(x,n)
+ (xInv := inverse x) case "failed" =>
+ error "**: matrix must be invertible"
+ positivePower(xInv :: %,-n)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category MATCAT MatrixCategory>>
+<<category RMATCAT RectangularMatrixCategory>>
+<<category SMATCAT SquareMatrixCategory>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/matfuns.spad.pamphlet b/src/algebra/matfuns.spad.pamphlet
new file mode 100644
index 00000000..59d08748
--- /dev/null
+++ b/src/algebra/matfuns.spad.pamphlet
@@ -0,0 +1,803 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra matfuns.spad}
+\author{Clifton J. Williamson, Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IMATLIN InnerMatrixLinearAlgebraFunctions}
+<<package IMATLIN InnerMatrixLinearAlgebraFunctions>>=
+)abbrev package IMATLIN InnerMatrixLinearAlgebraFunctions
+++ Author: Clifton J. Williamson, P.Gianni
+++ Date Created: 13 November 1989
+++ Date Last Updated: September 1993
+++ Basic Operations:
+++ Related Domains: IndexedMatrix(R,minRow,minCol), Matrix(R),
+++ RectangularMatrix(n,m,R), SquareMatrix(n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, canonical forms, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{InnerMatrixLinearAlgebraFunctions} is an internal package
+++ which provides standard linear algebra functions on domains in
+++ \spad{MatrixCategory}
+InnerMatrixLinearAlgebraFunctions(R,Row,Col,M):_
+ Exports == Implementation where
+ R : Field
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+ M : MatrixCategory(R,Row,Col)
+ I ==> Integer
+
+ Exports ==> with
+ rowEchelon: M -> M
+ ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+ rank: M -> NonNegativeInteger
+ ++ \spad{rank(m)} returns the rank of the matrix m.
+ nullity: M -> NonNegativeInteger
+ ++ \spad{nullity(m)} returns the mullity of the matrix m. This is the
+ ++ dimension of the null space of the matrix m.
+ if Col has shallowlyMutable then
+ nullSpace: M -> List Col
+ ++ \spad{nullSpace(m)} returns a basis for the null space of the
+ ++ matrix m.
+ determinant: M -> R
+ ++ \spad{determinant(m)} returns the determinant of the matrix m.
+ ++ an error message is returned if the matrix is not square.
+ generalizedInverse: M -> M
+ ++ \spad{generalizedInverse(m)} returns the generalized (Moore--Penrose)
+ ++ inverse of the matrix m, i.e. the matrix h such that
+ ++ m*h*m=h, h*m*h=m, m*h and h*m are both symmetric matrices.
+ inverse: M -> Union(M,"failed")
+ ++ \spad{inverse(m)} returns the inverse of the matrix m.
+ ++ If the matrix is not invertible, "failed" is returned.
+ ++ Error: if the matrix is not square.
+
+ Implementation ==> add
+
+ rowAllZeroes?: (M,I) -> Boolean
+ rowAllZeroes?(x,i) ==
+ -- determines if the ith row of x consists only of zeroes
+ -- internal function: no check on index i
+ for j in minColIndex(x)..maxColIndex(x) repeat
+ qelt(x,i,j) ^= 0 => return false
+ true
+
+ colAllZeroes?: (M,I) -> Boolean
+ colAllZeroes?(x,j) ==
+ -- determines if the ith column of x consists only of zeroes
+ -- internal function: no check on index j
+ for i in minRowIndex(x)..maxRowIndex(x) repeat
+ qelt(x,i,j) ^= 0 => return false
+ true
+
+ rowEchelon y ==
+ -- row echelon form via Gaussian elimination
+ x := copy y
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := maxColIndex x
+ i := minR
+ n: I := minR - 1
+ for j in minC..maxC repeat
+ i > maxR => return x
+ n := minR - 1
+ -- n = smallest k such that k >= i and x(k,j) ^= 0
+ for k in i..maxR repeat
+ if qelt(x,k,j) ^= 0 then leave (n := k)
+ n = minR - 1 => "no non-zeroes"
+ -- put nth row in ith position
+ if i ^= n then swapRows_!(x,i,n)
+ -- divide ith row by its first non-zero entry
+ b := inv qelt(x,i,j)
+ qsetelt_!(x,i,j,1)
+ for k in (j+1)..maxC repeat qsetelt_!(x,i,k,b * qelt(x,i,k))
+ -- perform row operations so that jth column has only one 1
+ for k in minR..maxR repeat
+ if k ^= i and qelt(x,k,j) ^= 0 then
+ for k1 in (j+1)..maxC repeat
+ qsetelt_!(x,k,k1,qelt(x,k,k1) - qelt(x,k,j) * qelt(x,i,k1))
+ qsetelt_!(x,k,j,0)
+ -- increment i
+ i := i + 1
+ x
+
+ rank x ==
+ y :=
+ (rk := nrows x) > (rh := ncols x) =>
+ rk := rh
+ transpose x
+ copy x
+ y := rowEchelon y; i := maxRowIndex y
+ while rk > 0 and rowAllZeroes?(y,i) repeat
+ i := i - 1
+ rk := (rk - 1) :: NonNegativeInteger
+ rk :: NonNegativeInteger
+
+ nullity x == (ncols x - rank x) :: NonNegativeInteger
+
+ if Col has shallowlyMutable then
+
+ nullSpace y ==
+ x := rowEchelon y
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := maxColIndex x
+ nrow := nrows x; ncol := ncols x
+ basis : List Col := nil()
+ rk := nrow; row := maxR
+ -- compute rank = # rows - # rows of all zeroes
+ while rk > 0 and rowAllZeroes?(x,row) repeat
+ rk := (rk - 1) :: NonNegativeInteger
+ row := (row - 1) :: NonNegativeInteger
+ -- if maximal rank, return zero vector
+ ncol <= nrow and rk = ncol => [new(ncol,0)]
+ -- if rank = 0, return standard basis vectors
+ rk = 0 =>
+ for j in minC..maxC repeat
+ w : Col := new(ncol,0)
+ qsetelt_!(w,j,1)
+ basis := cons(w,basis)
+ basis
+ -- v contains information about initial 1's in the rows of x
+ -- if the ith row has an initial 1 in the jth column, then
+ -- v.j = i; v.j = minR - 1, otherwise
+ v : IndexedOneDimensionalArray(I,minC) := new(ncol,minR - 1)
+ for i in minR..(minR + rk - 1) repeat
+ for j in minC.. while qelt(x,i,j) = 0 repeat j
+ qsetelt_!(v,j,i)
+ j := maxC; l := minR + ncol - 1
+ while j >= minC repeat
+ w : Col := new(ncol,0)
+ -- if there is no row with an initial 1 in the jth column,
+ -- create a basis vector with a 1 in the jth row
+ if qelt(v,j) = minR - 1 then
+ colAllZeroes?(x,j) =>
+ qsetelt_!(w,l,1)
+ basis := cons(w,basis)
+ for k in minC..(j-1) for ll in minR..(l-1) repeat
+ if qelt(v,k) ^= minR - 1 then
+ qsetelt_!(w,ll,-qelt(x,qelt(v,k),j))
+ qsetelt_!(w,l,1)
+ basis := cons(w,basis)
+ j := j - 1; l := l - 1
+ basis
+
+ determinant y ==
+ (ndim := nrows y) ^= (ncols y) =>
+ error "determinant: matrix must be square"
+ -- Gaussian Elimination
+ ndim = 1 => qelt(y,minRowIndex y,minColIndex y)
+ x := copy y
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := maxColIndex x
+ ans : R := 1
+ for i in minR..(maxR - 1) for j in minC..(maxC - 1) repeat
+ if qelt(x,i,j) = 0 then
+ rown := minR - 1
+ for k in (i+1)..maxR repeat
+ qelt(x,k,j) ^= 0 => leave (rown := k)
+ if rown = minR - 1 then return 0
+ swapRows_!(x,i,rown); ans := -ans
+ ans := qelt(x,i,j) * ans; b := -inv qelt(x,i,j)
+ for l in (j+1)..maxC repeat qsetelt_!(x,i,l,b * qelt(x,i,l))
+ for k in (i+1)..maxR repeat
+ if (b := qelt(x,k,j)) ^= 0 then
+ for l in (j+1)..maxC repeat
+ qsetelt_!(x,k,l,qelt(x,k,l) + b * qelt(x,i,l))
+ qelt(x,maxR,maxC) * ans
+
+ generalizedInverse(x) ==
+ SUP:=SparseUnivariatePolynomial R
+ FSUP := Fraction SUP
+ VFSUP := Vector FSUP
+ MATCAT2 := MatrixCategoryFunctions2(R, Row, Col, M,
+ FSUP, VFSUP, VFSUP, Matrix FSUP)
+ MATCAT22 := MatrixCategoryFunctions2(FSUP, VFSUP, VFSUP, Matrix FSUP,
+ R, Row, Col, M)
+ y:= map(coerce(coerce(#1)$SUP)$(Fraction SUP),x)$MATCAT2
+ ty:=transpose y
+ yy:=ty*y
+ nc:=ncols yy
+ var:=monomial(1,1)$SUP ::(Fraction SUP)
+ yy:=inverse(yy+scalarMatrix(ncols yy,var))::Matrix(FSUP)*ty
+ map(elt(#1,0),yy)$MATCAT22
+
+ inverse x ==
+ (ndim := nrows x) ^= (ncols x) =>
+ error "inverse: matrix must be square"
+ ndim = 2 =>
+ ans2 : M := zero(ndim, ndim)
+ zero?(det := x(1,1)*x(2,2)-x(1,2)*x(2,1)) => "failed"
+ detinv := inv det
+ ans2(1,1) := x(2,2)*detinv
+ ans2(1,2) := -x(1,2)*detinv
+ ans2(2,1) := -x(2,1)*detinv
+ ans2(2,2) := x(1,1)*detinv
+ ans2
+ AB : M := zero(ndim,ndim + ndim)
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := maxColIndex x
+ kmin := minRowIndex AB; kmax := kmin + ndim - 1
+ lmin := minColIndex AB; lmax := lmin + ndim - 1
+ for i in minR..maxR for k in kmin..kmax repeat
+ for j in minC..maxC for l in lmin..lmax repeat
+ qsetelt_!(AB,k,l,qelt(x,i,j))
+ qsetelt_!(AB,k,lmin + ndim + k - kmin,1)
+ AB := rowEchelon AB
+ elt(AB,kmax,lmax) = 0 => "failed"
+ subMatrix(AB,kmin,kmax,lmin + ndim,lmax + ndim)
+
+@
+\section{package MATCAT2 MatrixCategoryFunctions2}
+<<package MATCAT2 MatrixCategoryFunctions2>>=
+)abbrev package MATCAT2 MatrixCategoryFunctions2
+++ Author: Clifton J. Williamson
+++ Date Created: 21 November 1989
+++ Date Last Updated: 21 March 1994
+++ Basic Operations:
+++ Related Domains: IndexedMatrix(R,minRow,minCol), Matrix(R),
+++ RectangularMatrix(n,m,R), SquareMatrix(n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: matrix, map, reduce
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{MatrixCategoryFunctions2} provides functions between two matrix
+++ domains. The functions provided are \spadfun{map} and \spadfun{reduce}.
+MatrixCategoryFunctions2(R1,Row1,Col1,M1,R2,Row2,Col2,M2):_
+ Exports == Implementation where
+ R1 : Ring
+ Row1 : FiniteLinearAggregate R1
+ Col1 : FiniteLinearAggregate R1
+ M1 : MatrixCategory(R1,Row1,Col1)
+ R2 : Ring
+ Row2 : FiniteLinearAggregate R2
+ Col2 : FiniteLinearAggregate R2
+ M2 : MatrixCategory(R2,Row2,Col2)
+
+ Exports ==> with
+ map: (R1 -> R2,M1) -> M2
+ ++ \spad{map(f,m)} applies the function f to the elements of the matrix m.
+ map: (R1 -> Union(R2,"failed"),M1) -> Union(M2,"failed")
+ ++ \spad{map(f,m)} applies the function f to the elements of the matrix m.
+ reduce: ((R1,R2) -> R2,M1,R2) -> R2
+ ++ \spad{reduce(f,m,r)} returns a matrix n where
+ ++ \spad{n[i,j] = f(m[i,j],r)} for all indices i and j.
+
+ Implementation ==> add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+
+ map(f:(R1->R2),m:M1):M2 ==
+ ans : M2 := new(nrows m,ncols m,0)
+ for i in minr(m)..maxr(m) for k in minr(ans)..maxr(ans) repeat
+ for j in minc(m)..maxc(m) for l in minc(ans)..maxc(ans) repeat
+ qsetelt_!(ans,k,l,f qelt(m,i,j))
+ ans
+
+ map(f:(R1 -> (Union(R2,"failed"))),m:M1):Union(M2,"failed") ==
+ ans : M2 := new(nrows m,ncols m,0)
+ for i in minr(m)..maxr(m) for k in minr(ans)..maxr(ans) repeat
+ for j in minc(m)..maxc(m) for l in minc(ans)..maxc(ans) repeat
+ (r := f qelt(m,i,j)) = "failed" => return "failed"
+ qsetelt_!(ans,k,l,r::R2)
+ ans
+
+ reduce(f,m,ident) ==
+ s := ident
+ for i in minr(m)..maxr(m) repeat
+ for j in minc(m)..maxc(m) repeat
+ s := f(qelt(m,i,j),s)
+ s
+
+@
+\section{package RMCAT2 RectangularMatrixCategoryFunctions2}
+<<package RMCAT2 RectangularMatrixCategoryFunctions2>>=
+)abbrev package RMCAT2 RectangularMatrixCategoryFunctions2
+++ Author: Clifton J. Williamson
+++ Date Created: 21 November 1989
+++ Date Last Updated: 12 June 1991
+++ Basic Operations:
+++ Related Domains: IndexedMatrix(R,minRow,minCol), Matrix(R),
+++ RectangularMatrix(n,m,R), SquareMatrix(n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: matrix, map, reduce
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{RectangularMatrixCategoryFunctions2} provides functions between
+++ two matrix domains. The functions provided are \spadfun{map} and \spadfun{reduce}.
+
+RectangularMatrixCategoryFunctions2(m,n,R1,Row1,Col1,M1,R2,Row2,Col2,M2):_
+ Exports == Implementation where
+ m,n : NonNegativeInteger
+ R1 : Ring
+ Row1 : DirectProductCategory(n, R1)
+ Col1 : DirectProductCategory(m, R1)
+ M1 : RectangularMatrixCategory(m,n,R1,Row1,Col1)
+ R2 : Ring
+ Row2 : DirectProductCategory(n, R2)
+ Col2 : DirectProductCategory(m, R2)
+ M2 : RectangularMatrixCategory(m,n,R2,Row2,Col2)
+
+ Exports ==> with
+ map: (R1 -> R2,M1) -> M2
+ ++ \spad{map(f,m)} applies the function \spad{f} to the elements of the
+ ++ matrix \spad{m}.
+ reduce: ((R1,R2) -> R2,M1,R2) -> R2
+ ++ \spad{reduce(f,m,r)} returns a matrix \spad{n} where
+ ++ \spad{n[i,j] = f(m[i,j],r)} for all indices spad{i} and \spad{j}.
+
+ Implementation ==> add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+
+ map(f,mat) ==
+ ans : M2 := new(m,n,0)$Matrix(R2) pretend M2
+ for i in minr(mat)..maxr(mat) for k in minr(ans)..maxr(ans) repeat
+ for j in minc(mat)..maxc(mat) for l in minc(ans)..maxc(ans) repeat
+ qsetelt_!(ans pretend Matrix R2,k,l,f qelt(mat,i,j))
+ ans
+
+ reduce(f,mat,ident) ==
+ s := ident
+ for i in minr(mat)..maxr(mat) repeat
+ for j in minc(mat)..maxc(mat) repeat
+ s := f(qelt(mat,i,j),s)
+ s
+
+@
+\section{package IMATQF InnerMatrixQuotientFieldFunctions}
+<<package IMATQF InnerMatrixQuotientFieldFunctions>>=
+)abbrev package IMATQF InnerMatrixQuotientFieldFunctions
+++ Author: Clifton J. Williamson
+++ Date Created: 22 November 1989
+++ Date Last Updated: 22 November 1989
+++ Basic Operations:
+++ Related Domains: IndexedMatrix(R,minRow,minCol), Matrix(R), RectangularMatrix(n,m,R), SquareMatrix(n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, inverse, integral domain
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{InnerMatrixQuotientFieldFunctions} provides functions on matrices
+++ over an integral domain which involve the quotient field of that integral
+++ domain. The functions rowEchelon and inverse return matrices with
+++ entries in the quotient field.
+InnerMatrixQuotientFieldFunctions(R,Row,Col,M,QF,Row2,Col2,M2):_
+ Exports == Implementation where
+ R : IntegralDomain
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+ M : MatrixCategory(R,Row,Col)
+ QF : QuotientFieldCategory R
+ Row2 : FiniteLinearAggregate QF
+ Col2 : FiniteLinearAggregate QF
+ M2 : MatrixCategory(QF,Row2,Col2)
+ IMATLIN ==> InnerMatrixLinearAlgebraFunctions(QF,Row2,Col2,M2)
+ MATCAT2 ==> MatrixCategoryFunctions2(R,Row,Col,M,QF,Row2,Col2,M2)
+ CDEN ==> InnerCommonDenominator(R,QF,Col,Col2)
+
+ Exports ==> with
+ rowEchelon: M -> M2
+ ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+ ++ the result will have entries in the quotient field.
+ inverse: M -> Union(M2,"failed")
+ ++ \spad{inverse(m)} returns the inverse of the matrix m.
+ ++ If the matrix is not invertible, "failed" is returned.
+ ++ Error: if the matrix is not square.
+ ++ Note: the result will have entries in the quotient field.
+ if Col2 has shallowlyMutable then
+ nullSpace : M -> List Col
+ ++ \spad{nullSpace(m)} returns a basis for the null space of the
+ ++ matrix m.
+ Implementation ==> add
+
+ qfMat: M -> M2
+ qfMat m == map(#1 :: QF,m)$MATCAT2
+
+ rowEchelon m == rowEchelon(qfMat m)$IMATLIN
+ inverse m ==
+ (inv := inverse(qfMat m)$IMATLIN) case "failed" => "failed"
+ inv :: M2
+
+ if Col2 has shallowlyMutable then
+ nullSpace m ==
+ [clearDenominator(v)$CDEN for v in nullSpace(qfMat m)$IMATLIN]
+
+@
+\section{package MATLIN MatrixLinearAlgebraFunctions}
+<<package MATLIN MatrixLinearAlgebraFunctions>>=
+)abbrev package MATLIN MatrixLinearAlgebraFunctions
+++ Author: Clifton J. Williamson, P.Gianni
+++ Date Created: 13 November 1989
+++ Date Last Updated: December 1992
+++ Basic Operations:
+++ Related Domains: IndexedMatrix(R,minRow,minCol), Matrix(R),
+++ RectangularMatrix(n,m,R), SquareMatrix(n,R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, canonical forms, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{MatrixLinearAlgebraFunctions} provides functions to compute
+++ inverses and canonical forms.
+MatrixLinearAlgebraFunctions(R,Row,Col,M):Exports == Implementation where
+ R : CommutativeRing
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+ M : MatrixCategory(R,Row,Col)
+ I ==> Integer
+
+ Exports ==> with
+
+ determinant: M -> R
+ ++ \spad{determinant(m)} returns the determinant of the matrix m.
+ ++ an error message is returned if the matrix is not square.
+ minordet: M -> R
+ ++ \spad{minordet(m)} computes the determinant of the matrix m using
+ ++ minors. Error: if the matrix is not square.
+ elRow1! : (M,I,I) -> M
+ ++ elRow1!(m,i,j) swaps rows i and j of matrix m : elementary operation
+ ++ of first kind
+ elRow2! : (M,R,I,I) -> M
+ ++ elRow2!(m,a,i,j) adds to row i a*row(m,j) : elementary operation of
+ ++ second kind. (i ^=j)
+ elColumn2! : (M,R,I,I) -> M
+ ++ elColumn2!(m,a,i,j) adds to column i a*column(m,j) : elementary
+ ++ operation of second kind. (i ^=j)
+
+ if R has IntegralDomain then
+ rank: M -> NonNegativeInteger
+ ++ \spad{rank(m)} returns the rank of the matrix m.
+ nullity: M -> NonNegativeInteger
+ ++ \spad{nullity(m)} returns the mullity of the matrix m. This is
+ ++ the dimension of the null space of the matrix m.
+ nullSpace: M -> List Col
+ ++ \spad{nullSpace(m)} returns a basis for the null space of the
+ ++ matrix m.
+ fractionFreeGauss! : M -> M
+ ++ \spad{fractionFreeGauss(m)} performs the fraction
+ ++ free gaussian elimination on the matrix m.
+ invertIfCan : M -> Union(M,"failed")
+ ++ \spad{invertIfCan(m)} returns the inverse of m over R
+ adjoint : M -> Record(adjMat:M, detMat:R)
+ ++ \spad{adjoint(m)} returns the ajoint matrix of m (i.e. the matrix
+ ++ n such that m*n = determinant(m)*id) and the detrminant of m.
+
+ if R has EuclideanDomain then
+ rowEchelon: M -> M
+ ++ \spad{rowEchelon(m)} returns the row echelon form of the matrix m.
+
+ normalizedDivide: (R, R) -> Record(quotient:R, remainder:R)
+ ++ normalizedDivide(n,d) returns a normalized quotient and
+ ++ remainder such that consistently unique representatives
+ ++ for the residue class are chosen, e.g. positive remainders
+
+ if R has Field then
+ inverse: M -> Union(M,"failed")
+ ++ \spad{inverse(m)} returns the inverse of the matrix.
+ ++ If the matrix is not invertible, "failed" is returned.
+ ++ Error: if the matrix is not square.
+
+ Implementation ==> add
+
+ rowAllZeroes?: (M,I) -> Boolean
+ rowAllZeroes?(x,i) ==
+ -- determines if the ith row of x consists only of zeroes
+ -- internal function: no check on index i
+ for j in minColIndex(x)..maxColIndex(x) repeat
+ qelt(x,i,j) ^= 0 => return false
+ true
+
+ colAllZeroes?: (M,I) -> Boolean
+ colAllZeroes?(x,j) ==
+ -- determines if the ith column of x consists only of zeroes
+ -- internal function: no check on index j
+ for i in minRowIndex(x)..maxRowIndex(x) repeat
+ qelt(x,i,j) ^= 0 => return false
+ true
+
+ minorDet:(M,I,List I,I,PrimitiveArray(Union(R,"uncomputed")))-> R
+ minorDet(x,m,l,i,v) ==
+ z := v.m
+ z case R => z
+ ans : R := 0; rl : List I := nil()
+ j := first l; l := rest l; pos := true
+ minR := minRowIndex x; minC := minColIndex x;
+ repeat
+ if qelt(x,j + minR,i + minC) ^= 0 then
+ ans :=
+ md := minorDet(x,m - 2**(j :: NonNegativeInteger),_
+ concat_!(reverse rl,l),i + 1,v) *_
+ qelt(x,j + minR,i + minC)
+ pos => ans + md
+ ans - md
+ null l =>
+ v.m := ans
+ return ans
+ pos := not pos; rl := cons(j,rl); j := first l; l := rest l
+
+ minordet x ==
+ (ndim := nrows x) ^= (ncols x) =>
+ error "determinant: matrix must be square"
+ -- minor expansion with (s---loads of) memory
+ n1 : I := ndim - 1
+ v : PrimitiveArray(Union(R,"uncomputed")) :=
+ new((2**ndim - 1) :: NonNegativeInteger,"uncomputed")
+ minR := minRowIndex x; maxC := maxColIndex x
+ for i in 0..n1 repeat
+ qsetelt_!(v,(2**i - 1),qelt(x,i + minR,maxC))
+ minorDet(x, 2**ndim - 2, [i for i in 0..n1], 0, v)
+
+ -- elementary operation of first kind: exchange two rows --
+ elRow1!(m:M,i:I,j:I) : M ==
+ vec:=row(m,i)
+ setRow!(m,i,row(m,j))
+ setRow!(m,j,vec)
+ m
+
+ -- elementary operation of second kind: add to row i--
+ -- a*row j (i^=j) --
+ elRow2!(m : M,a:R,i:I,j:I) : M ==
+ vec:= map(a*#1,row(m,j))
+ vec:=map("+",row(m,i),vec)
+ setRow!(m,i,vec)
+ m
+ -- elementary operation of second kind: add to column i --
+ -- a*column j (i^=j) --
+ elColumn2!(m : M,a:R,i:I,j:I) : M ==
+ vec:= map(a*#1,column(m,j))
+ vec:=map("+",column(m,i),vec)
+ setColumn!(m,i,vec)
+ m
+
+ if R has IntegralDomain then
+ -- Fraction-Free Gaussian Elimination
+ fractionFreeGauss! x ==
+ (ndim := nrows x) = 1 => x
+ ans := b := 1$R
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := maxColIndex x
+ i := minR
+ for j in minC..maxC repeat
+ if qelt(x,i,j) = 0 then -- candidate for pivot = 0
+ rown := minR - 1
+ for k in (i+1)..maxR repeat
+ if qelt(x,k,j) ^= 0 then
+ rown := k -- found a pivot
+ leave
+ if rown > minR - 1 then
+ swapRows_!(x,i,rown)
+ ans := -ans
+ (c := qelt(x,i,j)) = 0 => "next j" -- try next column
+ for k in (i+1)..maxR repeat
+ if qelt(x,k,j) = 0 then
+ for l in (j+1)..maxC repeat
+ qsetelt_!(x,k,l,(c * qelt(x,k,l) exquo b) :: R)
+ else
+ pv := qelt(x,k,j)
+ qsetelt_!(x,k,j,0)
+ for l in (j+1)..maxC repeat
+ val := c * qelt(x,k,l) - pv * qelt(x,i,l)
+ qsetelt_!(x,k,l,(val exquo b) :: R)
+ b := c
+ (i := i+1)>maxR => leave
+ if ans=-1 then
+ lasti := i-1
+ for j in 1..maxC repeat x(lasti, j) := -x(lasti,j)
+ x
+
+ --
+ lastStep(x:M) : M ==
+ ndim := nrows x
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := minC+ndim -1
+ exCol:=maxColIndex x
+ det:=x(maxR,maxC)
+ maxR1:=maxR-1
+ maxC1:=maxC+1
+ minC1:=minC+1
+ iRow:=maxR
+ iCol:=maxC-1
+ for i in maxR1..1 by -1 repeat
+ for j in maxC1..exCol repeat
+ ss:=+/[x(i,iCol+k)*x(i+k,j) for k in 1..(maxR-i)]
+ x(i,j) := _exquo((det * x(i,j) - ss),x(i,iCol))::R
+ iCol:=iCol-1
+ subMatrix(x,minR,maxR,maxC1,exCol)
+
+ invertIfCan(y) ==
+ (nr:=nrows y) ^= (ncols y) =>
+ error "invertIfCan: matrix must be square"
+ adjRec := adjoint y
+ (den:=recip(adjRec.detMat)) case "failed" => "failed"
+ den::R * adjRec.adjMat
+
+ adjoint(y) ==
+ (nr:=nrows y) ^= (ncols y) => error "adjoint: matrix must be square"
+ maxR := maxRowIndex y
+ maxC := maxColIndex y
+ x := horizConcat(copy y,scalarMatrix(nr,1$R))
+ ffr:= fractionFreeGauss!(x)
+ det:=ffr(maxR,maxC)
+ [lastStep(ffr),det]
+
+
+ if R has Field then
+
+ VR ==> Vector R
+ IMATLIN ==> InnerMatrixLinearAlgebraFunctions(R,Row,Col,M)
+ MMATLIN ==> InnerMatrixLinearAlgebraFunctions(R,VR,VR,Matrix R)
+ FLA2 ==> FiniteLinearAggregateFunctions2(R, VR, R, Col)
+ MAT2 ==> MatrixCategoryFunctions2(R,Row,Col,M,R,VR,VR,Matrix R)
+
+ rowEchelon y == rowEchelon(y)$IMATLIN
+ rank y == rank(y)$IMATLIN
+ nullity y == nullity(y)$IMATLIN
+ determinant y == determinant(y)$IMATLIN
+ inverse y == inverse(y)$IMATLIN
+ if Col has shallowlyMutable then
+ nullSpace y == nullSpace(y)$IMATLIN
+ else
+ nullSpace y ==
+ [map(#1, v)$FLA2 for v in nullSpace(map(#1, y)$MAT2)$MMATLIN]
+
+ else if R has IntegralDomain then
+ QF ==> Fraction R
+ Row2 ==> Vector QF
+ Col2 ==> Vector QF
+ M2 ==> Matrix QF
+ IMATQF ==> InnerMatrixQuotientFieldFunctions(R,Row,Col,M,QF,Row2,Col2,M2)
+
+ nullSpace m == nullSpace(m)$IMATQF
+
+ determinant y ==
+ (nrows y) ^= (ncols y) => error "determinant: matrix must be square"
+ fm:=fractionFreeGauss!(copy y)
+ fm(maxRowIndex fm,maxColIndex fm)
+
+ rank x ==
+ y :=
+ (rk := nrows x) > (rh := ncols x) =>
+ rk := rh
+ transpose x
+ copy x
+ y := fractionFreeGauss! y
+ i := maxRowIndex y
+ while rk > 0 and rowAllZeroes?(y,i) repeat
+ i := i - 1
+ rk := (rk - 1) :: NonNegativeInteger
+ rk :: NonNegativeInteger
+
+ nullity x == (ncols x - rank x) :: NonNegativeInteger
+
+ if R has EuclideanDomain then
+
+ if R has IntegerNumberSystem then
+ normalizedDivide(n:R, d:R):Record(quotient:R, remainder:R) ==
+ qr := divide(n, d)
+ qr.remainder >= 0 => qr
+ d > 0 =>
+ qr.remainder := qr.remainder + d
+ qr.quotient := qr.quotient - 1
+ qr
+ qr.remainder := qr.remainder - d
+ qr.quotient := qr.quotient + 1
+ qr
+ else
+ normalizedDivide(n:R, d:R):Record(quotient:R, remainder:R) ==
+ divide(n, d)
+
+ rowEchelon y ==
+ x := copy y
+ minR := minRowIndex x; maxR := maxRowIndex x
+ minC := minColIndex x; maxC := maxColIndex x
+ n := minR - 1
+ i := minR
+ for j in minC..maxC repeat
+ if i > maxR then leave x
+ n := minR - 1
+ xnj: R
+ for k in i..maxR repeat
+ if not zero?(xkj:=qelt(x,k,j)) and ((n = minR - 1) _
+ or sizeLess?(xkj,xnj)) then
+ n := k
+ xnj := xkj
+ n = minR - 1 => "next j"
+ swapRows_!(x,i,n)
+ for k in (i+1)..maxR repeat
+ qelt(x,k,j) = 0 => "next k"
+ aa := extendedEuclidean(qelt(x,i,j),qelt(x,k,j))
+ (a,b,d) := (aa.coef1,aa.coef2,aa.generator)
+ b1 := (qelt(x,i,j) exquo d) :: R
+ a1 := (qelt(x,k,j) exquo d) :: R
+ -- a*b1+a1*b = 1
+ for k1 in (j+1)..maxC repeat
+ val1 := a * qelt(x,i,k1) + b * qelt(x,k,k1)
+ val2 := -a1 * qelt(x,i,k1) + b1 * qelt(x,k,k1)
+ qsetelt_!(x,i,k1,val1); qsetelt_!(x,k,k1,val2)
+ qsetelt_!(x,i,j,d); qsetelt_!(x,k,j,0)
+
+ un := unitNormal qelt(x,i,j)
+ qsetelt_!(x,i,j,un.canonical)
+ if un.associate ^= 1 then for jj in (j+1)..maxC repeat
+ qsetelt_!(x,i,jj,un.associate * qelt(x,i,jj))
+
+ xij := qelt(x,i,j)
+ for k in minR..(i-1) repeat
+ qelt(x,k,j) = 0 => "next k"
+ qr := normalizedDivide(qelt(x,k,j), xij)
+ qsetelt_!(x,k,j,qr.remainder)
+ for k1 in (j+1)..maxC repeat
+ qsetelt_!(x,k,k1,qelt(x,k,k1) - qr.quotient * qelt(x,i,k1))
+ i := i + 1
+ x
+
+ else determinant x == minordet x
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- This file and MATRIX SPAD must be compiled in bootstrap mode.
+
+<<package IMATLIN InnerMatrixLinearAlgebraFunctions>>
+<<package MATCAT2 MatrixCategoryFunctions2>>
+<<package RMCAT2 RectangularMatrixCategoryFunctions2>>
+<<package IMATQF InnerMatrixQuotientFieldFunctions>>
+<<package MATLIN MatrixLinearAlgebraFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/matrix.spad.pamphlet b/src/algebra/matrix.spad.pamphlet
new file mode 100644
index 00000000..3704e00e
--- /dev/null
+++ b/src/algebra/matrix.spad.pamphlet
@@ -0,0 +1,530 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra matrix.spad}
+\author{Johannes Grabmeier, Oswald Gschnitzer, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain IMATRIX IndexedMatrix}
+<<domain IMATRIX IndexedMatrix>>=
+)abbrev domain IMATRIX IndexedMatrix
+++ Author: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: Matrix, RectangularMatrix, SquareMatrix,
+++ StorageEfficientMatrixOperations
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ An \spad{IndexedMatrix} is a matrix where the minimal row and column
+++ indices are parameters of the type. The domains Row and Col
+++ are both IndexedVectors.
+++ The index of the 'first' row may be obtained by calling the
+++ function \spadfun{minRowIndex}. The index of the 'first' column may
+++ be obtained by calling the function \spadfun{minColIndex}. The index of
+++ the first element of a 'Row' is the same as the index of the
+++ first column in a matrix and vice versa.
+IndexedMatrix(R,mnRow,mnCol): Exports == Implementation where
+ R : Ring
+ mnRow, mnCol : Integer
+ Row ==> IndexedVector(R,mnCol)
+ Col ==> IndexedVector(R,mnRow)
+ MATLIN ==> MatrixLinearAlgebraFunctions(R,Row,Col,$)
+
+ Exports ==> MatrixCategory(R,Row,Col)
+
+ Implementation ==>
+ InnerIndexedTwoDimensionalArray(R,mnRow,mnCol,Row,Col) add
+
+ swapRows_!(x,i1,i2) ==
+ (i1 < minRowIndex(x)) or (i1 > maxRowIndex(x)) or _
+ (i2 < minRowIndex(x)) or (i2 > maxRowIndex(x)) =>
+ error "swapRows!: index out of range"
+ i1 = i2 => x
+ minRow := minRowIndex x
+ xx := x pretend PrimitiveArray(PrimitiveArray(R))
+ n1 := i1 - minRow; n2 := i2 - minRow
+ row1 := qelt(xx,n1)
+ qsetelt_!(xx,n1,qelt(xx,n2))
+ qsetelt_!(xx,n2,row1)
+ xx pretend $
+
+ if R has commutative("*") then
+
+ determinant x == determinant(x)$MATLIN
+ minordet x == minordet(x)$MATLIN
+
+ if R has EuclideanDomain then
+
+ rowEchelon x == rowEchelon(x)$MATLIN
+
+ if R has IntegralDomain then
+
+ rank x == rank(x)$MATLIN
+ nullity x == nullity(x)$MATLIN
+ nullSpace x == nullSpace(x)$MATLIN
+
+ if R has Field then
+
+ inverse x == inverse(x)$MATLIN
+
+@
+\section{domain MATRIX Matrix}
+<<domain MATRIX Matrix>>=
+)abbrev domain MATRIX Matrix
+++ Author: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: IndexedMatrix, RectangularMatrix, SquareMatrix
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{Matrix} is a matrix domain where 1-based indexing is used
+++ for both rows and columns.
+Matrix(R): Exports == Implementation where
+ R : Ring
+ Row ==> Vector R
+ Col ==> Vector R
+ mnRow ==> 1
+ mnCol ==> 1
+ MATLIN ==> MatrixLinearAlgebraFunctions(R,Row,Col,$)
+ MATSTOR ==> StorageEfficientMatrixOperations(R)
+
+ Exports ==> MatrixCategory(R,Row,Col) with
+ diagonalMatrix: Vector R -> $
+ ++ \spad{diagonalMatrix(v)} returns a diagonal matrix where the elements
+ ++ of v appear on the diagonal.
+
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+
+ if R has Field then
+ inverse: $ -> Union($,"failed")
+ ++ \spad{inverse(m)} returns the inverse of the matrix m.
+ ++ If the matrix is not invertible, "failed" is returned.
+ ++ Error: if the matrix is not square.
+-- matrix: Vector Vector R -> $
+-- ++ \spad{matrix(v)} converts the vector of vectors v to a matrix, where
+-- ++ the vector of vectors is viewed as a vector of the rows of the
+-- ++ matrix
+-- diagonalMatrix: Vector $ -> $
+-- ++ \spad{diagonalMatrix([m1,...,mk])} creates a block diagonal matrix
+-- ++ M with block matrices {\em m1},...,{\em mk} down the diagonal,
+-- ++ with 0 block matrices elsewhere.
+-- vectorOfVectors: $ -> Vector Vector R
+-- ++ \spad{vectorOfVectors(m)} returns the rows of the matrix m as a
+-- ++ vector of vectors
+
+ Implementation ==>
+ InnerIndexedTwoDimensionalArray(R,mnRow,mnCol,Row,Col) add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+ mini ==> minIndex
+ maxi ==> maxIndex
+
+ minRowIndex x == mnRow
+ minColIndex x == mnCol
+
+ swapRows_!(x,i1,i2) ==
+ (i1 < minRowIndex(x)) or (i1 > maxRowIndex(x)) or _
+ (i2 < minRowIndex(x)) or (i2 > maxRowIndex(x)) =>
+ error "swapRows!: index out of range"
+ i1 = i2 => x
+ minRow := minRowIndex x
+ xx := x pretend PrimitiveArray(PrimitiveArray(R))
+ n1 := i1 - minRow; n2 := i2 - minRow
+ row1 := qelt(xx,n1)
+ qsetelt_!(xx,n1,qelt(xx,n2))
+ qsetelt_!(xx,n2,row1)
+ xx pretend $
+
+ positivePower:($,Integer,NonNegativeInteger) -> $
+ positivePower(x,n,nn) ==
+-- one? n => x
+ (n = 1) => x
+ -- no need to allocate space for 3 additional matrices
+ n = 2 => x * x
+ n = 3 => x * x * x
+ n = 4 => (y := x * x; y * y)
+ a := new(nn,nn,0) pretend Matrix(R)
+ b := new(nn,nn,0) pretend Matrix(R)
+ c := new(nn,nn,0) pretend Matrix(R)
+ xx := x pretend Matrix(R)
+ power_!(a,b,c,xx,n :: NonNegativeInteger)$MATSTOR pretend $
+
+ x:$ ** n:NonNegativeInteger ==
+ not((nn := nrows x) = ncols x) =>
+ error "**: matrix must be square"
+ zero? n => scalarMatrix(nn,1)
+ positivePower(x,n,nn)
+
+ if R has commutative("*") then
+
+ determinant x == determinant(x)$MATLIN
+ minordet x == minordet(x)$MATLIN
+
+ if R has EuclideanDomain then
+
+ rowEchelon x == rowEchelon(x)$MATLIN
+
+ if R has IntegralDomain then
+
+ rank x == rank(x)$MATLIN
+ nullity x == nullity(x)$MATLIN
+ nullSpace x == nullSpace(x)$MATLIN
+
+ if R has Field then
+
+ inverse x == inverse(x)$MATLIN
+
+ x:$ ** n:Integer ==
+ nn := nrows x
+ not(nn = ncols x) =>
+ error "**: matrix must be square"
+ zero? n => scalarMatrix(nn,1)
+ positive? n => positivePower(x,n,nn)
+ (xInv := inverse x) case "failed" =>
+ error "**: matrix must be invertible"
+ positivePower(xInv :: $,-n,nn)
+
+-- matrix(v: Vector Vector R) ==
+-- (rows := # v) = 0 => new(0,0,0)
+-- -- error check: this is a top level function
+-- cols := # v.mini(v)
+-- for k in (mini(v) + 1)..maxi(v) repeat
+-- cols ^= # v.k => error "matrix: rows of different lengths"
+-- ans := new(rows,cols,0)
+-- for i in minr(ans)..maxr(ans) for k in mini(v)..maxi(v) repeat
+-- vv := v.k
+-- for j in minc(ans)..maxc(ans) for l in mini(vv)..maxi(vv) repeat
+-- ans(i,j) := vv.l
+-- ans
+
+ diagonalMatrix(v: Vector R) ==
+ n := #v; ans := zero(n,n)
+ for i in minr(ans)..maxr(ans) for j in minc(ans)..maxc(ans) _
+ for k in mini(v)..maxi(v) repeat qsetelt_!(ans,i,j,qelt(v,k))
+ ans
+
+-- diagonalMatrix(vec: Vector $) ==
+-- rows : NonNegativeInteger := 0
+-- cols : NonNegativeInteger := 0
+-- for r in mini(vec)..maxi(vec) repeat
+-- mat := vec.r
+-- rows := rows + nrows mat; cols := cols + ncols mat
+-- ans := zero(rows,cols)
+-- loR := minr ans; loC := minc ans
+-- for r in mini(vec)..maxi(vec) repeat
+-- mat := vec.r
+-- hiR := loR + nrows(mat) - 1; hiC := loC + nrows(mat) - 1
+-- for i in loR..hiR for k in minr(mat)..maxr(mat) repeat
+-- for j in loC..hiC for l in minc(mat)..maxc(mat) repeat
+-- ans(i,j) := mat(k,l)
+-- loR := hiR + 1; loC := hiC + 1
+-- ans
+
+-- vectorOfVectors x ==
+-- vv : Vector Vector R := new(nrows x,0)
+-- cols := ncols x
+-- for k in mini(vv)..maxi(vv) repeat
+-- vv.k := new(cols,0)
+-- for i in minr(x)..maxr(x) for k in mini(vv)..maxi(vv) repeat
+-- v := vv.k
+-- for j in minc(x)..maxc(x) for l in mini(v)..maxi(v) repeat
+-- v.l := x(i,j)
+-- vv
+
+ if R has ConvertibleTo InputForm then
+ convert(x:$):InputForm ==
+ convert [convert("matrix"::Symbol)@InputForm,
+ convert listOfLists x]$List(InputForm)
+
+@
+\section{domain RMATRIX RectangularMatrix}
+<<domain RMATRIX RectangularMatrix>>=
+)abbrev domain RMATRIX RectangularMatrix
+++ Author: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: IndexedMatrix, Matrix, SquareMatrix
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{RectangularMatrix} is a matrix domain where the number of rows
+++ and the number of columns are parameters of the domain.
+RectangularMatrix(m,n,R): Exports == Implementation where
+ m,n : NonNegativeInteger
+ R : Ring
+ Row ==> DirectProduct(n,R)
+ Col ==> DirectProduct(m,R)
+ Exports ==> Join(RectangularMatrixCategory(m,n,R,Row,Col),_
+ CoercibleTo Matrix R) with
+
+ if R has Field then VectorSpace R
+
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+
+ rectangularMatrix: Matrix R -> $
+ ++ \spad{rectangularMatrix(m)} converts a matrix of type \spadtype{Matrix}
+ ++ to a matrix of type \spad{RectangularMatrix}.
+ coerce: $ -> Matrix R
+ ++ \spad{coerce(m)} converts a matrix of type \spadtype{RectangularMatrix}
+ ++ to a matrix of type \spad{Matrix}.
+
+ Implementation ==> Matrix R add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+ mini ==> minIndex
+ maxi ==> maxIndex
+
+ ZERO := new(m,n,0)$Matrix(R) pretend $
+ 0 == ZERO
+
+ coerce(x:$):OutputForm == coerce(x pretend Matrix R)$Matrix(R)
+
+ matrix(l: List List R) ==
+ -- error check: this is a top level function
+ #l ^= m => error "matrix: wrong number of rows"
+ for ll in l repeat
+ #ll ^= n => error "matrix: wrong number of columns"
+ ans : Matrix R := new(m,n,0)
+ for i in minr(ans)..maxr(ans) for ll in l repeat
+ for j in minc(ans)..maxc(ans) for r in ll repeat
+ qsetelt_!(ans,i,j,r)
+ ans pretend $
+
+ row(x,i) == directProduct row(x pretend Matrix(R),i)
+ column(x,j) == directProduct column(x pretend Matrix(R),j)
+
+ coerce(x:$):Matrix(R) == copy(x pretend Matrix(R))
+
+ rectangularMatrix x ==
+ (nrows(x) ^= m) or (ncols(x) ^= n) =>
+ error "rectangularMatrix: matrix of bad dimensions"
+ copy(x) pretend $
+
+ if R has EuclideanDomain then
+
+ rowEchelon x == rowEchelon(x pretend Matrix(R)) pretend $
+
+ if R has IntegralDomain then
+
+ rank x == rank(x pretend Matrix(R))
+ nullity x == nullity(x pretend Matrix(R))
+ nullSpace x ==
+ [directProduct c for c in nullSpace(x pretend Matrix(R))]
+
+ if R has Field then
+
+ dimension() == (m * n) :: CardinalNumber
+
+ if R has ConvertibleTo InputForm then
+ convert(x:$):InputForm ==
+ convert [convert("rectangularMatrix"::Symbol)@InputForm,
+ convert(x::Matrix(R))]$List(InputForm)
+
+@
+\section{domain SQMATRIX SquareMatrix}
+<<domain SQMATRIX SquareMatrix>>=
+)abbrev domain SQMATRIX SquareMatrix
+++ Author: Grabmeier, Gschnitzer, Williamson
+++ Date Created: 1987
+++ Date Last Updated: July 1990
+++ Basic Operations:
+++ Related Domains: IndexedMatrix, Matrix, RectangularMatrix
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{SquareMatrix} is a matrix domain of square matrices, where the
+++ number of rows (= number of columns) is a parameter of the type.
+SquareMatrix(ndim,R): Exports == Implementation where
+ ndim : NonNegativeInteger
+ R : Ring
+ Row ==> DirectProduct(ndim,R)
+ Col ==> DirectProduct(ndim,R)
+ MATLIN ==> MatrixLinearAlgebraFunctions(R,Row,Col,$)
+
+ Exports ==> Join(SquareMatrixCategory(ndim,R,Row,Col),_
+ CoercibleTo Matrix R) with
+
+ transpose: $ -> $
+ ++ \spad{transpose(m)} returns the transpose of the matrix m.
+ squareMatrix: Matrix R -> $
+ ++ \spad{squareMatrix(m)} converts a matrix of type \spadtype{Matrix}
+ ++ to a matrix of type \spadtype{SquareMatrix}.
+ coerce: $ -> Matrix R
+ ++ \spad{coerce(m)} converts a matrix of type \spadtype{SquareMatrix}
+ ++ to a matrix of type \spadtype{Matrix}.
+-- symdecomp : $ -> Record(sym:$,antisym:$)
+-- ++ \spad{symdecomp(m)} decomposes the matrix m as a sum of a symmetric
+-- ++ matrix \spad{m1} and an antisymmetric matrix \spad{m2}. The object
+-- ++ returned is the Record \spad{[m1,m2]}
+-- if R has commutative("*") then
+-- minorsVect: -> Vector(Union(R,"uncomputed")) --range: 1..2**n-1
+-- ++ \spad{minorsVect(m)} returns a vector of the minors of the matrix m
+ if R has commutative("*") then central
+ ++ the elements of the Ring R, viewed as diagonal matrices, commute
+ ++ with all matrices and, indeed, are the only matrices which commute
+ ++ with all matrices.
+ if R has commutative("*") and R has unitsKnown then unitsKnown
+ ++ the invertible matrices are simply the matrices whose determinants
+ ++ are units in the Ring R.
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+
+ Implementation ==> Matrix R add
+ minr ==> minRowIndex
+ maxr ==> maxRowIndex
+ minc ==> minColIndex
+ maxc ==> maxColIndex
+ mini ==> minIndex
+ maxi ==> maxIndex
+
+ ZERO := scalarMatrix 0
+ 0 == ZERO
+ ONE := scalarMatrix 1
+ 1 == ONE
+
+ characteristic() == characteristic()$R
+
+ matrix(l: List List R) ==
+ -- error check: this is a top level function
+ #l ^= ndim => error "matrix: wrong number of rows"
+ for ll in l repeat
+ #ll ^= ndim => error "matrix: wrong number of columns"
+ ans : Matrix R := new(ndim,ndim,0)
+ for i in minr(ans)..maxr(ans) for ll in l repeat
+ for j in minc(ans)..maxc(ans) for r in ll repeat
+ qsetelt_!(ans,i,j,r)
+ ans pretend $
+
+ row(x,i) == directProduct row(x pretend Matrix(R),i)
+ column(x,j) == directProduct column(x pretend Matrix(R),j)
+ coerce(x:$):OutputForm == coerce(x pretend Matrix R)$Matrix(R)
+
+ scalarMatrix r == scalarMatrix(ndim,r)$Matrix(R) pretend $
+
+ diagonalMatrix l ==
+ #l ^= ndim =>
+ error "diagonalMatrix: wrong number of entries in list"
+ diagonalMatrix(l)$Matrix(R) pretend $
+
+ coerce(x:$):Matrix(R) == copy(x pretend Matrix(R))
+
+ squareMatrix x ==
+ (nrows(x) ^= ndim) or (ncols(x) ^= ndim) =>
+ error "squareMatrix: matrix of bad dimensions"
+ copy(x) pretend $
+
+ x:$ * v:Col ==
+ directProduct((x pretend Matrix(R)) * (v :: Vector(R)))
+
+ v:Row * x:$ ==
+ directProduct((v :: Vector(R)) * (x pretend Matrix(R)))
+
+ x:$ ** n:NonNegativeInteger ==
+ ((x pretend Matrix(R)) ** n) pretend $
+
+ if R has commutative("*") then
+
+ determinant x == determinant(x pretend Matrix(R))
+ minordet x == minordet(x pretend Matrix(R))
+
+ if R has EuclideanDomain then
+
+ rowEchelon x == rowEchelon(x pretend Matrix(R)) pretend $
+
+ if R has IntegralDomain then
+
+ rank x == rank(x pretend Matrix(R))
+ nullity x == nullity(x pretend Matrix(R))
+ nullSpace x ==
+ [directProduct c for c in nullSpace(x pretend Matrix(R))]
+
+ if R has Field then
+
+ dimension() == (m * n) :: CardinalNumber
+
+ inverse x ==
+ (u := inverse(x pretend Matrix(R))) case "failed" => "failed"
+ (u :: Matrix(R)) pretend $
+
+ x:$ ** n:Integer ==
+ ((x pretend Matrix(R)) ** n) pretend $
+
+ recip x == inverse x
+
+ if R has ConvertibleTo InputForm then
+ convert(x:$):InputForm ==
+ convert [convert("squareMatrix"::Symbol)@InputForm,
+ convert(x::Matrix(R))]$List(InputForm)
+
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain IMATRIX IndexedMatrix>>
+<<domain MATRIX Matrix>>
+<<domain RMATRIX RectangularMatrix>>
+<<domain SQMATRIX SquareMatrix>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/matstor.spad.pamphlet b/src/algebra/matstor.spad.pamphlet
new file mode 100644
index 00000000..f34f9e29
--- /dev/null
+++ b/src/algebra/matstor.spad.pamphlet
@@ -0,0 +1,246 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra matstor.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MATSTOR StorageEfficientMatrixOperations}
+<<package MATSTOR StorageEfficientMatrixOperations>>=
+)abbrev package MATSTOR StorageEfficientMatrixOperations
+++ Author: Clifton J. Williamson
+++ Date Created: 18 July 1990
+++ Date Last Updated: 18 July 1990
+++ Basic Operations:
+++ Related Domains: Matrix(R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ This package provides standard arithmetic operations on matrices.
+++ The functions in this package store the results of computations
+++ in existing matrices, rather than creating new matrices. This
+++ package works only for matrices of type Matrix and uses the
+++ internal representation of this type.
+StorageEfficientMatrixOperations(R): Exports == Implementation where
+ R : Ring
+ M ==> Matrix R
+ NNI ==> NonNegativeInteger
+ ARR ==> PrimitiveArray R
+ REP ==> PrimitiveArray PrimitiveArray R
+
+ Exports ==> with
+ copy_! : (M,M) -> M
+ ++ \spad{copy!(c,a)} copies the matrix \spad{a} into the matrix c.
+ ++ Error: if \spad{a} and c do not have the same
+ ++ dimensions.
+ plus_! : (M,M,M) -> M
+ ++ \spad{plus!(c,a,b)} computes the matrix sum \spad{a + b} and stores the
+ ++ result in the matrix c.
+ ++ Error: if \spad{a}, b, and c do not have the same dimensions.
+ minus_! : (M,M) -> M
+ ++ \spad{minus!(c,a)} computes \spad{-a} and stores the result in the
+ ++ matrix c.
+ ++ Error: if a and c do not have the same dimensions.
+ minus_! : (M,M,M) -> M
+ ++ \spad{!minus!(c,a,b)} computes the matrix difference \spad{a - b}
+ ++ and stores the result in the matrix c.
+ ++ Error: if \spad{a}, b, and c do not have the same dimensions.
+ leftScalarTimes_! : (M,R,M) -> M
+ ++ \spad{leftScalarTimes!(c,r,a)} computes the scalar product
+ ++ \spad{r * a} and stores the result in the matrix c.
+ ++ Error: if \spad{a} and c do not have the same dimensions.
+ rightScalarTimes_! : (M,M,R) -> M
+ ++ \spad{rightScalarTimes!(c,a,r)} computes the scalar product
+ ++ \spad{a * r} and stores the result in the matrix c.
+ ++ Error: if \spad{a} and c do not have the same dimensions.
+ times_! : (M,M,M) -> M
+ ++ \spad{times!(c,a,b)} computes the matrix product \spad{a * b}
+ ++ and stores the result in the matrix c.
+ ++ Error: if \spad{a}, b, and c do not have
+ ++ compatible dimensions.
+ power_! : (M,M,M,M,NNI) -> M
+ ++ \spad{power!(a,b,c,m,n)} computes m ** n and stores the result in
+ ++ \spad{a}. The matrices b and c are used to store intermediate results.
+ ++ Error: if \spad{a}, b, c, and m are not square
+ ++ and of the same dimensions.
+ "**" : (M,NNI) -> M
+ ++ \spad{x ** n} computes the n-th power
+ ++ of a square matrix. The power n is assumed greater than 1.
+
+ Implementation ==> add
+
+ rep : M -> REP
+ rep m == m pretend REP
+
+ copy_!(c,a) ==
+ m := nrows a; n := ncols a
+ not((nrows c) = m and (ncols c) = n) =>
+ error "copy!: matrices of incompatible dimensions"
+ aa := rep a; cc := rep c
+ for i in 0..(m-1) repeat
+ aRow := qelt(aa,i); cRow := qelt(cc,i)
+ for j in 0..(n-1) repeat
+ qsetelt_!(cRow,j,qelt(aRow,j))
+ c
+
+ plus_!(c,a,b) ==
+ m := nrows a; n := ncols a
+ not((nrows b) = m and (ncols b) = n) =>
+ error "plus!: matrices of incompatible dimensions"
+ not((nrows c) = m and (ncols c) = n) =>
+ error "plus!: matrices of incompatible dimensions"
+ aa := rep a; bb := rep b; cc := rep c
+ for i in 0..(m-1) repeat
+ aRow := qelt(aa,i); bRow := qelt(bb,i); cRow := qelt(cc,i)
+ for j in 0..(n-1) repeat
+ qsetelt_!(cRow,j,qelt(aRow,j) + qelt(bRow,j))
+ c
+
+ minus_!(c,a) ==
+ m := nrows a; n := ncols a
+ not((nrows c) = m and (ncols c) = n) =>
+ error "minus!: matrices of incompatible dimensions"
+ aa := rep a; cc := rep c
+ for i in 0..(m-1) repeat
+ aRow := qelt(aa,i); cRow := qelt(cc,i)
+ for j in 0..(n-1) repeat
+ qsetelt_!(cRow,j,-qelt(aRow,j))
+ c
+
+ minus_!(c,a,b) ==
+ m := nrows a; n := ncols a
+ not((nrows b) = m and (ncols b) = n) =>
+ error "minus!: matrices of incompatible dimensions"
+ not((nrows c) = m and (ncols c) = n) =>
+ error "minus!: matrices of incompatible dimensions"
+ aa := rep a; bb := rep b; cc := rep c
+ for i in 0..(m-1) repeat
+ aRow := qelt(aa,i); bRow := qelt(bb,i); cRow := qelt(cc,i)
+ for j in 0..(n-1) repeat
+ qsetelt_!(cRow,j,qelt(aRow,j) - qelt(bRow,j))
+ c
+
+ leftScalarTimes_!(c,r,a) ==
+ m := nrows a; n := ncols a
+ not((nrows c) = m and (ncols c) = n) =>
+ error "leftScalarTimes!: matrices of incompatible dimensions"
+ aa := rep a; cc := rep c
+ for i in 0..(m-1) repeat
+ aRow := qelt(aa,i); cRow := qelt(cc,i)
+ for j in 0..(n-1) repeat
+ qsetelt_!(cRow,j,r * qelt(aRow,j))
+ c
+
+ rightScalarTimes_!(c,a,r) ==
+ m := nrows a; n := ncols a
+ not((nrows c) = m and (ncols c) = n) =>
+ error "rightScalarTimes!: matrices of incompatible dimensions"
+ aa := rep a; cc := rep c
+ for i in 0..(m-1) repeat
+ aRow := qelt(aa,i); cRow := qelt(cc,i)
+ for j in 0..(n-1) repeat
+ qsetelt_!(cRow,j,qelt(aRow,j) * r)
+ c
+
+ copyCol_!: (ARR,REP,Integer,Integer) -> ARR
+ copyCol_!(bCol,bb,j,n1) ==
+ for i in 0..n1 repeat qsetelt_!(bCol,i,qelt(qelt(bb,i),j))
+
+ times_!(c,a,b) ==
+ m := nrows a; n := ncols a; p := ncols b
+ not((nrows b) = n and (nrows c) = m and (ncols c) = p) =>
+ error "times!: matrices of incompatible dimensions"
+ aa := rep a; bb := rep b; cc := rep c
+ bCol : ARR := new(n,0)
+ m1 := (m :: Integer) - 1; n1 := (n :: Integer) - 1
+ for j in 0..(p-1) repeat
+ copyCol_!(bCol,bb,j,n1)
+ for i in 0..m1 repeat
+ aRow := qelt(aa,i); cRow := qelt(cc,i)
+ sum : R := 0
+ for k in 0..n1 repeat
+ sum := sum + qelt(aRow,k) * qelt(bCol,k)
+ qsetelt_!(cRow,j,sum)
+ c
+
+ power_!(a,b,c,m,p) ==
+ mm := nrows a; nn := ncols a
+ not(mm = nn) =>
+ error "power!: matrix must be square"
+ not((nrows b) = mm and (ncols b) = nn) =>
+ error "power!: matrices of incompatible dimensions"
+ not((nrows c) = mm and (ncols c) = nn) =>
+ error "power!: matrices of incompatible dimensions"
+ not((nrows m) = mm and (ncols m) = nn) =>
+ error "power!: matrices of incompatible dimensions"
+ flag := false
+ copy_!(b,m)
+ repeat
+ if odd? p then
+ flag =>
+ times_!(c,b,a)
+ copy_!(a,c)
+ flag := true
+ copy_!(a,b)
+-- one? p => return a
+ (p = 1) => return a
+ p := p quo 2
+ times_!(c,b,b)
+ copy_!(b,c)
+
+ m ** n ==
+ not square? m => error "**: matrix must be square"
+ a := copy m; b := copy m; c := copy m
+ power_!(a,b,c,m,n)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MATSTOR StorageEfficientMatrixOperations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mesh.spad.pamphlet b/src/algebra/mesh.spad.pamphlet
new file mode 100644
index 00000000..8cc1c8e0
--- /dev/null
+++ b/src/algebra/mesh.spad.pamphlet
@@ -0,0 +1,188 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mesh.spad}
+\author{James Wen, Jon Steinbach}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MESH MeshCreationRoutinesForThreeDimensions}
+<<package MESH MeshCreationRoutinesForThreeDimensions>>=
+)abbrev package MESH MeshCreationRoutinesForThreeDimensions
+++ <description of package>
+++ Author: Jim Wen
+++ Date Created: ??
+++ Date Last Updated: October 1991 by Jon Steinbach
+++ Keywords:
+++ Examples:
+++ References:
+MeshCreationRoutinesForThreeDimensions():Exports == Implementation where
+
+ I ==> Integer
+ PI ==> PositiveInteger
+ SF ==> DoubleFloat
+ L ==> List
+ SEG ==> Segment
+ S ==> String
+ Fn1 ==> SF -> SF
+ Fn2 ==> (SF,SF) -> SF
+ Fn3 ==> (SF,SF,SF) -> SF
+ FnPt ==> (SF,SF) -> Point(SF)
+ FnU ==> Union(Fn3,"undefined")
+ EX ==> Expression
+ DROP ==> DrawOption
+ POINT ==> Point(SF)
+ SPACE3 ==> ThreeSpace(SF)
+ COMPPROP ==> SubSpaceComponentProperty
+ TUBE ==> TubePlot
+
+ Exports ==> with
+ meshPar2Var: (Fn2,Fn2,Fn2,FnU,SEG SF,SEG SF,L DROP) -> SPACE3
+ ++ meshPar2Var(f,g,h,j,s1,s2,l) \undocumented
+ meshPar2Var: (FnPt,SEG SF,SEG SF,L DROP) -> SPACE3
+ ++ meshPar2Var(f,s1,s2,l) \undocumented
+ meshPar2Var: (SPACE3,FnPt,SEG SF,SEG SF,L DROP) -> SPACE3
+ ++ meshPar2Var(sp,f,s1,s2,l) \undocumented
+ meshFun2Var: (Fn2,FnU,SEG SF,SEG SF,L DROP) -> SPACE3
+ ++ meshFun2Var(f,g,s1,s2,l) \undocumented
+ meshPar1Var: (EX I,EX I,EX I,Fn1,SEG SF,L DROP) -> SPACE3
+ ++ meshPar1Var(s,t,u,f,s1,l) \undocumented
+ ptFunc: (Fn2,Fn2,Fn2,Fn3) -> ((SF,SF) -> POINT)
+ ++ ptFunc(a,b,c,d) is an internal function exported in
+ ++ order to compile packages.
+
+ Implementation ==> add
+ import ViewDefaultsPackage()
+ import SubSpaceComponentProperty()
+ import DrawOptionFunctions0
+ import SPACE3
+ --import TUBE()
+
+ -- local functions
+ numberCheck(nums:Point SF):Void ==
+ -- this function checks to see that the small floats are
+ -- actually just that - rather than complex numbers or
+ -- whatever (the whatever includes nothing presently
+ -- since NaN, Not a Number, is not necessarily supported
+ -- by common lisp). note that this function is dependent
+ -- upon the fact that Common Lisp supports complex numbers.
+ for i in minIndex(nums)..maxIndex(nums) repeat
+ COMPLEXP(nums.(i::PositiveInteger))$Lisp =>
+ error "An unexpected complex number was encountered in the calculations."
+
+ makePt:(SF,SF,SF,SF) -> POINT
+ makePt(x,y,z,c) == point(l : List SF := [x,y,z,c])
+ ptFunc(f,g,h,c) ==
+ x := f(#1,#2); y := g(#1,#2); z := h(#1,#2)
+ makePt(x,y,z,c(x,y,z))
+
+ -- parameterized equations of two variables
+ meshPar2Var(sp,ptFun,uSeg,vSeg,opts) ==
+ -- the issue of open and closed needs to be addressed, here, we are
+ -- defaulting to open (which is probably the correct default)
+ -- the user should be able to override that (optional argument?)
+ llp : L L POINT := nil()
+ uNum : PI := var1Steps(opts,var1StepsDefault())
+ vNum : PI := var2Steps(opts,var2StepsDefault())
+ ustep := (lo uSeg - hi uSeg)/uNum
+ vstep := (lo vSeg - hi vSeg)/vNum
+ someV := hi vSeg
+ for iv in vNum..0 by -1 repeat
+ if zero? iv then someV := lo vSeg
+ -- hack: get last number in segment within segment
+ lp : L POINT := nil()
+ someU := hi uSeg
+ for iu in uNum..0 by -1 repeat
+ if zero? iu then someU := lo uSeg
+ -- hack: get last number in segment within segment
+ pt := ptFun(someU,someV)
+ numberCheck pt
+ lp := concat(pt,lp)
+ someU := someU + ustep
+ llp := concat(lp,llp)
+ someV := someV + vstep
+ -- now llp contains a list of lists of points
+ -- for a surface that is a result of a function of 2 variables,
+ -- the main component is open and each sublist is open as well
+ lProp : L COMPPROP := [ new() for l in llp ]
+ for aProp in lProp repeat
+ close(aProp,false)
+ solid(aProp,false)
+ aProp : COMPPROP:= new()
+ close(aProp,false)
+ solid(aProp,false)
+ space := sp
+-- space := create3Space()
+ mesh(space,llp,lProp,aProp)
+ space
+
+ meshPar2Var(ptFun,uSeg,vSeg,opts) ==
+ sp := create3Space()
+ meshPar2Var(sp,ptFun,uSeg,vSeg,opts)
+
+ zCoord: (SF,SF,SF) -> SF
+ zCoord(x,y,z) == z
+
+ meshPar2Var(xFun,yFun,zFun,colorFun,uSeg,vSeg,opts) ==
+ -- the color function should be parameterized by (u,v) as well,
+ -- not (x,y,z) but we also want some sort of consistency and so
+ -- changing this over would mean possibly changing the explicit
+ -- stuff over and there, we probably do want the color function
+ -- to be parameterized by (x,y,z) - not just (x,y) (this being
+ -- for convinience only since z is also defined in terms of (x,y)).
+ (colorFun case Fn3) =>
+ meshPar2Var(ptFunc(xFun,yFun,zFun,colorFun :: Fn3),uSeg,vSeg,opts)
+ meshPar2Var(ptFunc(xFun,yFun,zFun,zCoord),uSeg,vSeg,opts)
+
+ -- explicit equations of two variables
+ meshFun2Var(zFun,colorFun,xSeg,ySeg,opts) ==
+ -- here, we construct the data for a function of two variables
+ meshPar2Var(#1,#2,zFun,colorFun,xSeg,ySeg,opts)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MESH MeshCreationRoutinesForThreeDimensions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mfinfact.spad.pamphlet b/src/algebra/mfinfact.spad.pamphlet
new file mode 100644
index 00000000..685afc57
--- /dev/null
+++ b/src/algebra/mfinfact.spad.pamphlet
@@ -0,0 +1,547 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mfinfact.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MFINFACT MultFiniteFactorize}
+<<package MFINFACT MultFiniteFactorize>>=
+)abbrev package MFINFACT MultFiniteFactorize
+++ Author: P. Gianni
+++ Date Created: Summer 1990
+++ Date Last Updated: 19 March 1992
+++ Basic Functions:
+++ Related Constructors: PrimeField, FiniteField, Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: Package for factorization of multivariate polynomials
+++ over finite fields.
+
+
+MultFiniteFactorize(OV,E,F,PG) : C == T
+ where
+ F : FiniteFieldCategory
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ PG : PolynomialCategory(F,E,OV)
+ SUP ==> SparseUnivariatePolynomial
+ R ==> SUP F
+ P ==> SparseMultivariatePolynomial(R,OV)
+ Z ==> Integer
+ FFPOLY ==> FiniteFieldPolynomialPackage(F)
+ MParFact ==> Record(irr:P,pow:Z)
+ MFinalFact ==> Record(contp:R,factors:List MParFact)
+ SUParFact ==> Record(irr:SUP P,pow:Z)
+ SUPFinalFact ==> Record(contp:R,factors:List SUParFact)
+
+ -- contp = content,
+ -- factors = List of irreducible factors with exponent
+
+ C == with
+
+ factor : PG -> Factored PG
+ ++ factor(p) produces the complete factorization of the multivariate
+ ++ polynomial p over a finite field.
+ factor : SUP PG -> Factored SUP PG
+ ++ factor(p) produces the complete factorization of the multivariate
+ ++ polynomial p over a finite field. p is represented as a univariate
+ ++ polynomial with multivariate coefficients over a finite field.
+
+ T == add
+
+ import LeadingCoefDetermination(OV,IndexedExponents OV,R,P)
+ import MultivariateLifting(IndexedExponents OV,OV,R,P)
+ import FactoringUtilities(IndexedExponents OV,OV,R,P)
+ import FactoringUtilities(E,OV,F,PG)
+ import GenExEuclid(R,SUP R)
+
+ NNI ==> NonNegativeInteger
+ L ==> List
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+ LeadFact ==> Record(polfac:L P,correct:R,corrfact:L SUP R)
+ ContPrim ==> Record(cont:P,prim:P)
+ ParFact ==> Record(irr:SUP R,pow:Z)
+ FinalFact ==> Record(contp:R,factors:L ParFact)
+ NewOrd ==> Record(npol:SUP P,nvar:L OV,newdeg:L NNI)
+ Valuf ==> Record(inval:L L R,unvfact:L SUP R,lu:R,complead:L R)
+
+ ---- Local Functions ----
+ ran : Z -> R
+ mFactor : (P,Z) -> MFinalFact
+ supFactor : (SUP P,Z) -> SUPFinalFact
+ mfconst : (SUP P,Z,L OV,L NNI) -> L SUP P
+ mfpol : (SUP P,Z,L OV,L NNI) -> L SUP P
+ varChoose : (P,L OV,L NNI) -> NewOrd
+ simplify : (P,Z,L OV,L NNI) -> MFinalFact
+ intChoose : (SUP P,L OV,R,L P,L L R) -> Valuf
+ pretest : (P,NNI,L OV,L R) -> FinalFact
+ checkzero : (SUP P,SUP R) -> Boolean
+ pushdcoef : PG -> P
+ pushdown : (PG,OV) -> P
+ pushupconst : (R,OV) -> PG
+ pushup : (P,OV) -> PG
+ norm : L SUP R -> Integer
+ constantCase : (P,L MParFact) -> MFinalFact
+ pM : L SUP R -> R
+ intfact : (SUP P,L OV,L NNI,MFinalFact,L L R) -> L SUP P
+
+ basicVar:OV:=NIL$Lisp pretend OV -- variable for the basic step
+
+
+ convertPUP(lfg:MFinalFact): SUPFinalFact ==
+ [lfg.contp,[[lff.irr ::SUP P,lff.pow]$SUParFact
+ for lff in lfg.factors]]$SUPFinalFact
+
+ supFactor(um:SUP P,dx:Z) : SUPFinalFact ==
+ degree(um)=0 => convertPUP(mFactor(ground um,dx))
+ lvar:L OV:= "setUnion"/[variables cf for cf in coefficients um]
+ lcont:SUP P
+ lf:L SUP P
+
+ flead : SUPFinalFact:=[0,empty()]$SUPFinalFact
+ factorlist:L SUParFact :=empty()
+
+ mdeg :=minimumDegree um ---- is the Mindeg > 0? ----
+ if mdeg>0 then
+ f1:SUP P:=monomial(1,mdeg)
+ um:=(um exquo f1)::SUP P
+ factorlist:=cons([monomial(1,1),mdeg],factorlist)
+ if degree um=0 then return
+ lfg:=convertPUP mFactor(ground um, dx)
+ [lfg.contp,append(factorlist,lfg.factors)]
+
+
+ om:=map(pushup(#1,basicVar),um)$UPCF2(P,SUP P,PG,SUP PG)
+ sqfacs:=squareFree(om)
+ lcont:=map(pushdown(#1,basicVar),unit sqfacs)$UPCF2(PG,SUP PG,P,SUP P)
+
+ ---- Factorize the content ----
+ if ground? lcont then
+ flead:=convertPUP constantCase(ground lcont,empty())
+ else
+ flead:=supFactor(lcont,dx)
+
+ factorlist:=flead.factors
+
+ ---- Make the polynomial square-free ----
+ sqqfact:=[[map(pushdown(#1,basicVar),ff.factor),ff.exponent]
+ for ff in factors sqfacs]
+
+ --- Factorize the primitive square-free terms ---
+ for fact in sqqfact repeat
+ ffactor:SUP P:=fact.irr
+ ffexp:=fact.pow
+ ffcont:=content ffactor
+ coefs := coefficients ffactor
+ ldeg:= ["max"/[degree(fc,xx) for fc in coefs] for xx in lvar]
+ if ground?(leadingCoefficient ffactor) then
+ lf:= mfconst(ffactor,dx,lvar,ldeg)
+ else lf:=mfpol(ffactor,dx,lvar,ldeg)
+ auxfl:=[[lfp,ffexp]$SUParFact for lfp in lf]
+ factorlist:=append(factorlist,auxfl)
+ lcfacs := */[leadingCoefficient leadingCoefficient(f.irr)**((f.pow)::NNI)
+ for f in factorlist]
+ [(leadingCoefficient leadingCoefficient(um) exquo lcfacs)::R,
+ factorlist]$SUPFinalFact
+
+ factor(um:SUP PG):Factored SUP PG ==
+ lv:List OV:=variables um
+ ld:=degree(um,lv)
+ dx:="min"/ld
+ basicVar:=lv.position(dx,ld)
+ cm:=map(pushdown(#1,basicVar),um)$UPCF2(PG,SUP PG,P,SUP P)
+ flist := supFactor(cm,dx)
+ pushupconst(flist.contp,basicVar)::SUP(PG) *
+ (*/[primeFactor(map(pushup(#1,basicVar),u.irr)$UPCF2(P,SUP P,PG,SUP PG),
+ u.pow) for u in flist.factors])
+
+
+
+ mFactor(m:P,dx:Z) : MFinalFact ==
+ ground?(m) => constantCase(m,empty())
+ lvar:L OV:= variables m
+ lcont:P
+ lf:L SUP P
+ flead : MFinalFact:=[1,empty()]$MFinalFact
+ factorlist:L MParFact :=empty()
+ ---- is the Mindeg > 0? ----
+ lmdeg :=minimumDegree(m,lvar)
+ or/[n>0 for n in lmdeg] => simplify(m,dx,lvar,lmdeg)
+ ---- Make the polynomial square-free ----
+ om:=pushup(m,basicVar)
+ sqfacs:=squareFree(om)
+ lcont := pushdown(unit sqfacs,basicVar)
+
+ ---- Factorize the content ----
+ if ground? lcont then
+ flead:=constantCase(lcont,empty())
+ else
+ flead:=mFactor(lcont,dx)
+ factorlist:=flead.factors
+ sqqfact:List Record(factor:P,exponent:Integer)
+ sqqfact:=[[pushdown(ff.factor,basicVar),ff.exponent]
+ for ff in factors sqfacs]
+ --- Factorize the primitive square-free terms ---
+ for fact in sqqfact repeat
+ ffactor:P:=fact.factor
+ ffexp := fact.exponent
+ ground? ffactor =>
+ for lterm in constantCase(ffactor,empty()).factors repeat
+ factorlist:=cons([lterm.irr,lterm.pow * ffexp], factorlist)
+ lvar := variables ffactor
+ x:OV:=lvar.1
+ ldeg:=degree(ffactor,lvar)
+ --- Is the polynomial linear in one of the variables ? ---
+ member?(1,ldeg) =>
+ x:OV:=lvar.position(1,ldeg)
+ lcont:= gcd coefficients(univariate(ffactor,x))
+ ffactor:=(ffactor exquo lcont)::P
+ factorlist:=cons([ffactor,ffexp]$MParFact,factorlist)
+ for lcterm in mFactor(lcont,dx).factors repeat
+ factorlist:=cons([lcterm.irr,lcterm.pow * ffexp], factorlist)
+
+ varch:=varChoose(ffactor,lvar,ldeg)
+ um:=varch.npol
+
+
+ ldeg:=ldeg.rest
+ lvar:=lvar.rest
+ if varch.nvar.1 ^= x then
+ lvar:= varch.nvar
+ x := lvar.1
+ lvar:=lvar.rest
+ pc:= gcd coefficients um
+ if pc^=1 then
+ um:=(um exquo pc)::SUP P
+ ffactor:=multivariate(um,x)
+ for lcterm in mFactor(pc,dx).factors repeat
+ factorlist:=cons([lcterm.irr,lcterm.pow*ffexp],factorlist)
+ ldeg:= degree(ffactor,lvar)
+
+ -- should be unitNormal if unified, but for now it is easier
+ lcum:F:= leadingCoefficient leadingCoefficient
+ leadingCoefficient um
+ if lcum ^=1 then
+ um:=((inv lcum)::R::P) * um
+ flead.contp := (lcum::R) *flead.contp
+
+ if ground?(leadingCoefficient um)
+ then lf:= mfconst(um,dx,lvar,ldeg)
+ else lf:=mfpol(um,dx,lvar,ldeg)
+ auxfl:=[[multivariate(lfp,x),ffexp]$MParFact for lfp in lf]
+ factorlist:=append(factorlist,auxfl)
+ flead.factors:= factorlist
+ flead
+
+
+ pM(lum:L SUP R) : R ==
+ x := monomial(1,1)$R
+ for i in 1..size()$F repeat
+ p := x + (index(i::PositiveInteger)$F) ::R
+ testModulus(p,lum) => return p
+ for e in 2.. repeat
+ p := (createIrreduciblePoly(e::PositiveInteger))$FFPOLY
+ testModulus(p,lum) => return p
+ while not((q := nextIrreduciblePoly(p)$FFPOLY) case "failed") repeat
+ p := q::SUP F
+ if testModulus(p, lum)$GenExEuclid(R, SUP R) then return p
+
+ ---- push x in the coefficient domain for a term ----
+ pushdcoef(t:PG):P ==
+ map(coerce(#1)$R,t)$MPolyCatFunctions2(OV,E,
+ IndexedExponents OV,F,R,PG,P)
+
+
+ ---- internal function, for testing bad cases ----
+ intfact(um:SUP P,lvar: L OV,ldeg:L NNI,
+ tleadpol:MFinalFact,ltry:L L R): L SUP P ==
+ polcase:Boolean:=(not empty? tleadpol.factors )
+ vfchoo:Valuf:=
+ polcase =>
+ leadpol:L P:=[ff.irr for ff in tleadpol.factors]
+ intChoose(um,lvar,tleadpol.contp,leadpol,ltry)
+ intChoose(um,lvar,1,empty(),empty())
+ unifact:List SUP R := vfchoo.unvfact
+ nfact:NNI := #unifact
+ nfact=1 => [um]
+ ltry:L L R:= vfchoo.inval
+ lval:L R:=first ltry
+ dd:= vfchoo.lu
+ lpol:List P:=empty()
+ leadval:List R:=empty()
+ if polcase then
+ leadval := vfchoo.complead
+ distf := distFact(vfchoo.lu,unifact,tleadpol,leadval,lvar,lval)
+ distf case "failed" =>
+ return intfact(um,lvar,ldeg,tleadpol,ltry)
+ dist := distf :: LeadFact
+ -- check the factorization of leading coefficient
+ lpol:= dist.polfac
+ dd := dist.correct
+ unifact:=dist.corrfact
+ if dd^=1 then
+ unifact := [dd*unifact.i for i in 1..nfact]
+ um := ((dd**(nfact-1)::NNI)::P)*um
+ (ffin:= lifting(um,lvar,unifact,lval,lpol,ldeg,pM(unifact)))
+ case "failed" => intfact(um,lvar,ldeg,tleadpol,ltry)
+ factfin: L SUP P:=ffin :: L SUP P
+ if dd^=1 then
+ factfin:=[primitivePart ff for ff in factfin]
+ factfin
+
+-- the following functions are used to "push" x in the coefficient ring -
+ ---- push back the variable ----
+ pushup(f:P,x:OV) :PG ==
+ ground? f => pushupconst((retract f)@R,x)
+ rr:PG:=0
+ while f^=0 repeat
+ lf:=leadingMonomial f
+ cf:=pushupconst(leadingCoefficient f,x)
+ lvf:=variables lf
+ rr:=rr+monomial(cf,lvf, degree(lf,lvf))$PG
+ f:=reductum f
+ rr
+
+ ---- push x in the coefficient domain for a polynomial ----
+ pushdown(g:PG,x:OV) : P ==
+ ground? g => ((retract g)@F)::R::P
+ rf:P:=0$P
+ ug:=univariate(g,x)
+ while ug^=0 repeat
+ cf:=monomial(1,degree ug)$R
+ rf:=rf+cf*pushdcoef(leadingCoefficient ug)
+ ug := reductum ug
+ rf
+
+ ---- push x back from the coefficient domain ----
+ pushupconst(r:R,x:OV):PG ==
+ ground? r => (retract r)@F ::PG
+ rr:PG:=0
+ while r^=0 repeat
+ rr:=rr+monomial((leadingCoefficient r)::PG,x,degree r)$PG
+ r:=reductum r
+ rr
+
+ -- This function has to be added to Eucliden domain
+ ran(k1:Z) : R ==
+ --if R case Integer then random()$R rem (2*k1)-k1
+ --else
+ +/[monomial(random()$F,i)$R for i in 0..k1]
+
+ checkzero(u:SUP P,um:SUP R) : Boolean ==
+ u=0 => um =0
+ um = 0 => false
+ degree u = degree um => checkzero(reductum u, reductum um)
+ false
+
+ --- Choose the variable of least degree ---
+ varChoose(m:P,lvar:L OV,ldeg:L NNI) : NewOrd ==
+ k:="min"/[d for d in ldeg]
+ k=degree(m,first lvar) =>
+ [univariate(m,first lvar),lvar,ldeg]$NewOrd
+ i:=position(k,ldeg)
+ x:OV:=lvar.i
+ ldeg:=cons(k,delete(ldeg,i))
+ lvar:=cons(x,delete(lvar,i))
+ [univariate(m,x),lvar,ldeg]$NewOrd
+
+
+ norm(lum: L SUP R): Integer == "max"/[degree lup for lup in lum]
+
+ --- Choose the values to reduce to the univariate case ---
+ intChoose(um:SUP P,lvar:L OV,clc:R,plist:L P,ltry:L L R) : Valuf ==
+ -- declarations
+ degum:NNI := degree um
+ nvar1:=#lvar
+ range:NNI:=0
+ unifact:L SUP R
+ ctf1 : R := 1
+ testp:Boolean := -- polynomial leading coefficient
+ plist = empty() => false
+ true
+ leadcomp,leadcomp1 : L R
+ leadcomp:=leadcomp1:=empty()
+ nfatt:NNI := degum+1
+ lffc:R:=1
+ lffc1:=lffc
+ newunifact : L SUP R:=empty()
+ leadtest:=true --- the lc test with polCase has to be performed
+ int:L R:=empty()
+
+ -- New sets of values are chosen until we find twice the
+ -- same number of "univariate" factors:the set smaller in modulo is
+ -- is chosen.
+ while true repeat
+ lval := [ ran(range) for i in 1..nvar1]
+ member?(lval,ltry) => range:=1+range
+ ltry := cons(lval,ltry)
+ leadcomp1:=[retract eval(pol,lvar,lval) for pol in plist]
+ testp and or/[unit? epl for epl in leadcomp1] => range:=range+1
+ newm:SUP R:=completeEval(um,lvar,lval)
+ degum ^= degree newm or minimumDegree newm ^=0 => range:=range+1
+ lffc1:=content newm
+ newm:=(newm exquo lffc1)::SUP R
+ testp and leadtest and ^ polCase(lffc1*clc,#plist,leadcomp1)
+ => range:=range+1
+ Dnewm := differentiate newm
+ D2newm := map(differentiate, newm)
+ degree(gcd [newm,Dnewm,D2newm])^=0 => range:=range+1
+ -- if R has Integer then luniv:=henselFact(newm,false)$
+ -- else
+ lcnm:F:=1
+ -- should be unitNormal if unified, but for now it is easier
+ if (lcnm:=leadingCoefficient leadingCoefficient newm)^=1 then
+ newm:=((inv lcnm)::R)*newm
+ dx:="max"/[degree uc for uc in coefficients newm]
+ luniv:=generalTwoFactor(newm)$TwoFactorize(F)
+ lunivf:= factors luniv
+ nf:= #lunivf
+
+ nf=0 or nf>nfatt => "next values" --- pretest failed ---
+
+ --- the univariate polynomial is irreducible ---
+ if nf=1 then leave (unifact:=[newm])
+
+ lffc1:=lcnm * retract(unit luniv)@R * lffc1
+
+ -- the new integer give the same number of factors
+ nfatt = nf =>
+ -- if this is the first univariate factorization with polCase=true
+ -- or if the last factorization has smaller norm and satisfies
+ -- polCase
+ if leadtest or
+ ((norm unifact > norm [ff.factor for ff in lunivf]) and
+ (^testp or polCase(lffc1*clc,#plist,leadcomp1))) then
+ unifact:=[uf.factor for uf in lunivf]
+ int:=lval
+ lffc:=lffc1
+ if testp then leadcomp:=leadcomp1
+ leave "foundit"
+
+ -- the first univariate factorization, inizialize
+ nfatt > degum =>
+ unifact:=[uf.factor for uf in lunivf]
+ lffc:=lffc1
+ if testp then leadcomp:=leadcomp1
+ int:=lval
+ leadtest := false
+ nfatt := nf
+
+ nfatt>nf => -- for the previous values there were more factors
+ if testp then leadtest:=^polCase(lffc*clc,#plist,leadcomp)
+ else leadtest:= false
+ -- if polCase=true we can consider the univariate decomposition
+ if ^leadtest then
+ unifact:=[uf.factor for uf in lunivf]
+ lffc:=lffc1
+ if testp then leadcomp:=leadcomp1
+ int:=lval
+ nfatt := nf
+ [cons(int,ltry),unifact,lffc,leadcomp]$Valuf
+
+
+ constantCase(m:P,factorlist:List MParFact) : MFinalFact ==
+ --if R case Integer then [const m,factorlist]$MFinalFact
+ --else
+ lunm:=distdfact((retract m)@R,false)$DistinctDegreeFactorize(F,R)
+ [(lunm.cont)::R, append(factorlist,
+ [[(pp.irr)::P,pp.pow] for pp in lunm.factors])]$MFinalFact
+
+ ---- The polynomial has mindeg>0 ----
+
+ simplify(m:P,dm:Z,lvar:L OV,lmdeg:L NNI):MFinalFact ==
+ factorlist:L MParFact:=empty()
+ pol1:P:= 1$P
+ for x in lvar repeat
+ i := lmdeg.(position(x,lvar))
+ i=0 => "next value"
+ pol1:=pol1*monomial(1$P,x,i)
+ factorlist:=cons([x::P,i]$MParFact,factorlist)
+ m := (m exquo pol1)::P
+ ground? m => constantCase(m,factorlist)
+ flead:=mFactor(m,dm)
+ flead.factors:=append(factorlist,flead.factors)
+ flead
+
+ ---- m square-free,primitive,lc constant ----
+ mfconst(um:SUP P,dm:Z,lvar:L OV,ldeg:L NNI):L SUP P ==
+ nsign:Boolean
+ factfin:L SUP P:=empty()
+ empty? lvar =>
+ um1:SUP R:=map(ground,
+ um)$UPCF2(P,SUP P,R,SUP R)
+ lum:= generalTwoFactor(um1)$TwoFactorize(F)
+ [map(coerce,lumf.factor)$UPCF2(R,SUP R,P,SUP P)
+ for lumf in factors lum]
+ intfact(um,lvar,ldeg,[0,empty()]$MFinalFact,empty())
+
+ --- m is square-free,primitive,lc is a polynomial ---
+ mfpol(um:SUP P,dm:Z,lvar:L OV,ldeg:L NNI):L SUP P ==
+ dist : LeadFact
+ tleadpol:=mFactor(leadingCoefficient um,dm)
+ intfact(um,lvar,ldeg,tleadpol,empty())
+
+ factor(m:PG):Factored PG ==
+ lv:=variables m
+ lv=empty() => makeFR(m,empty() )
+ -- reduce to multivariate over SUP
+ ld:=[degree(m,x) for x in lv]
+ dx:="min"/ld
+ basicVar:=lv(position(dx,ld))
+ cm:=pushdown(m,basicVar)
+ flist := mFactor(cm,dx)
+ pushupconst(flist.contp,basicVar) *
+ (*/[primeFactor(pushup(u.irr,basicVar),u.pow)
+ for u in flist.factors])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MFINFACT MultFiniteFactorize>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/misc.spad.pamphlet b/src/algebra/misc.spad.pamphlet
new file mode 100644
index 00000000..86caa39b
--- /dev/null
+++ b/src/algebra/misc.spad.pamphlet
@@ -0,0 +1,74 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra misc.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SAOS SingletonAsOrderedSet}
+<<domain SAOS SingletonAsOrderedSet>>=
+)abbrev domain SAOS SingletonAsOrderedSet
+++ This trivial domain lets us build Univariate Polynomials
+++ in an anonymous variable
+SingletonAsOrderedSet(): OrderedSet with
+ create:() -> %
+ convert:% -> Symbol
+ == add
+ create() == "?" pretend %
+ a<b == false -- only one element
+ coerce(a) == outputForm "?" -- CJW doesn't like this: change ?
+ a=b == true -- only one element
+ min(a,b) == a -- only one element
+ max(a,b) == a -- only one element
+ convert a == coerce("?")
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+--bug fix TTT Nov 11 1992. (add convert $ to Symbol)
+
+<<domain SAOS SingletonAsOrderedSet>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mkfunc.spad.pamphlet b/src/algebra/mkfunc.spad.pamphlet
new file mode 100644
index 00000000..7b1ad3ee
--- /dev/null
+++ b/src/algebra/mkfunc.spad.pamphlet
@@ -0,0 +1,497 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mkfunc.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain INFORM InputForm}
+<<domain INFORM InputForm>>=
+)abbrev domain INFORM InputForm
+++ Parser forms
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 19 April 1991
+++ Description:
+++ Domain of parsed forms which can be passed to the interpreter.
+++ This is also the interface between algebra code and facilities
+++ in the interpreter.
+
+--)boot $noSubsumption := true
+
+InputForm():
+ Join(SExpressionCategory(String,Symbol,Integer,DoubleFloat,OutputForm),
+ ConvertibleTo SExpression) with
+ interpret: % -> Any
+ ++ interpret(f) passes f to the interpreter.
+ convert : SExpression -> %
+ ++ convert(s) makes s into an input form.
+ binary : (%, List %) -> %
+ ++ \spad{binary(op, [a1,...,an])} returns the input form
+ ++ corresponding to \spad{a1 op a2 op ... op an}.
+ function : (%, List Symbol, Symbol) -> %
+ ++ \spad{function(code, [x1,...,xn], f)} returns the input form
+ ++ corresponding to \spad{f(x1,...,xn) == code}.
+ lambda : (%, List Symbol) -> %
+ ++ \spad{lambda(code, [x1,...,xn])} returns the input form
+ ++ corresponding to \spad{(x1,...,xn) +-> code} if \spad{n > 1},
+ ++ or to \spad{x1 +-> code} if \spad{n = 1}.
+ "+" : (%, %) -> %
+ ++ \spad{a + b} returns the input form corresponding to \spad{a + b}.
+ "*" : (%, %) -> %
+ ++ \spad{a * b} returns the input form corresponding to \spad{a * b}.
+ "/" : (%, %) -> %
+ ++ \spad{a / b} returns the input form corresponding to \spad{a / b}.
+ "**" : (%, NonNegativeInteger) -> %
+ ++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}.
+ "**" : (%, Integer) -> %
+ ++ \spad{a ** b} returns the input form corresponding to \spad{a ** b}.
+ 0 : constant -> %
+ ++ \spad{0} returns the input form corresponding to 0.
+ 1 : constant -> %
+ ++ \spad{1} returns the input form corresponding to 1.
+ flatten : % -> %
+ ++ flatten(s) returns an input form corresponding to s with
+ ++ all the nested operations flattened to triples using new
+ ++ local variables.
+ ++ If s is a piece of code, this speeds up
+ ++ the compilation tremendously later on.
+ unparse : % -> String
+ ++ unparse(f) returns a string s such that the parser
+ ++ would transform s to f.
+ ++ Error: if f is not the parsed form of a string.
+ declare : List % -> Symbol
+ ++ declare(t) returns a name f such that f has been
+ ++ declared to the interpreter to be of type t, but has
+ ++ not been assigned a value yet.
+ ++ Note: t should be created as \spad{devaluate(T)$Lisp} where T is the
+ ++ actual type of f (this hack is required for the case where
+ ++ T is a mapping type).
+ compile : (Symbol, List %) -> Symbol
+ ++ \spad{compile(f, [t1,...,tn])} forces the interpreter to compile
+ ++ the function f with signature \spad{(t1,...,tn) -> ?}.
+ ++ returns the symbol f if successful.
+ ++ Error: if f was not defined beforehand in the interpreter,
+ ++ or if the ti's are not valid types, or if the compiler fails.
+ == SExpression add
+ Rep := SExpression
+
+ mkProperOp: Symbol -> %
+ strsym : % -> String
+ tuplify : List Symbol -> %
+ flatten0 : (%, Symbol, NonNegativeInteger) ->
+ Record(lst: List %, symb:%)
+
+ 0 == convert(0::Integer)
+ 1 == convert(1::Integer)
+ convert(x:%):SExpression == x pretend SExpression
+ convert(x:SExpression):% == x
+
+ conv(ll : List %): % ==
+ convert(ll pretend List SExpression)$SExpression pretend %
+
+ lambda(f,l) == conv([convert("+->"::Symbol),tuplify l,f]$List(%))
+
+ interpret x ==
+ v := interpret(x)$Lisp
+ mkObj(unwrap(objVal(v)$Lisp)$Lisp, objMode(v)$Lisp)$Lisp
+
+ convert(x:DoubleFloat):% ==
+ zero? x => 0
+-- one? x => 1
+ (x = 1) => 1
+ convert(x)$Rep
+
+ flatten s ==
+ -- will not compile if I use 'or'
+ atom? s => s
+ every?(atom?,destruct s)$List(%) => s
+ sy := new()$Symbol
+ n:NonNegativeInteger := 0
+ l2 := [flatten0(x, sy, n := n + 1) for x in rest(l := destruct s)]
+ conv(concat(convert("SEQ"::Symbol)@%,
+ concat(concat [u.lst for u in l2], conv(
+ [convert("exit"::Symbol)@%, 1$%, conv(concat(first l,
+ [u.symb for u in l2]))@%]$List(%))@%)))@%
+
+ flatten0(s, sy, n) ==
+ atom? s => [nil(), s]
+ a := convert(concat(string sy, convert(n)@String)::Symbol)@%
+ l2 := [flatten0(x, sy, n := n+1) for x in rest(l := destruct s)]
+ [concat(concat [u.lst for u in l2], conv([convert(
+ "LET"::Symbol)@%, a, conv(concat(first l,
+ [u.symb for u in l2]))@%]$List(%))@%), a]
+
+ strsym s ==
+ string? s => string s
+ symbol? s => string symbol s
+ error "strsym: form is neither a string or symbol"
+
+ unparse x ==
+ atom?(s:% := form2String(x)$Lisp) => strsym s
+ concat [strsym a for a in destruct s]
+
+ declare signature ==
+ declare(name := new()$Symbol, signature)$Lisp
+ name
+
+ compile(name, types) ==
+ symbol car cdr car
+ selectLocalMms(mkProperOp name, convert(name)@%,
+ types, nil$List(%))$Lisp
+
+ mkProperOp name ==
+ op := mkAtree(nme := convert(name)@%)$Lisp
+ transferPropsToNode(nme, op)$Lisp
+ convert op
+
+ binary(op, args) ==
+ (n := #args) < 2 => error "Need at least 2 arguments"
+ n = 2 => convert([op, first args, last args]$List(%))
+ convert([op, first args, binary(op, rest args)]$List(%))
+
+ tuplify l ==
+ empty? rest l => convert first l
+ conv
+ concat(convert("Tuple"::Symbol), [convert x for x in l]$List(%))
+
+ function(f, l, name) ==
+ nn := convert(new(1 + #l, convert(nil()$List(%)))$List(%))@%
+ conv([convert("DEF"::Symbol), conv(cons(convert(name)@%,
+ [convert(x)@% for x in l])), nn, nn, f]$List(%))
+
+ s1 + s2 ==
+ s1 = 0 => s2
+ s2 = 0 => s1
+ conv [convert("+"::Symbol), s1, s2]$List(%)
+
+ s1 * s2 ==
+ s1 = 0 or s2 = 0 => 0
+ s1 = 1 => s2
+ s2 = 1 => s1
+ conv [convert("*"::Symbol), s1, s2]$List(%)
+
+ s1:% ** n:Integer ==
+ s1 = 0 and n > 0 => 0
+ s1 = 1 or zero? n => 1
+-- one? n => s1
+ (n = 1) => s1
+ conv [convert("**"::Symbol), s1, convert n]$List(%)
+
+ s1:% ** n:NonNegativeInteger == s1 ** (n::Integer)
+
+ s1 / s2 ==
+ s2 = 1 => s1
+ conv [convert("/"::Symbol), s1, s2]$List(%)
+
+@
+\section{package INFORM1 InputFormFunctions1}
+<<package INFORM1 InputFormFunctions1>>=
+)abbrev package INFORM1 InputFormFunctions1
+--)boot $noSubsumption := false
+
+++ Tools for manipulating input forms
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 19 April 1991
+++ Description: Tools for manipulating input forms.
+
+InputFormFunctions1(R:Type):with
+ packageCall: Symbol -> InputForm
+ ++ packageCall(f) returns the input form corresponding to f$R.
+ interpret : InputForm -> R
+ ++ interpret(f) passes f to the interpreter, and transforms
+ ++ the result into an object of type R.
+ == add
+ Rname := devaluate(R)$Lisp :: InputForm
+
+ packageCall name ==
+ convert([convert("$elt"::Symbol), Rname,
+ convert name]$List(InputForm))@InputForm
+
+ interpret form ==
+ retract(interpret(convert([convert("@"::Symbol), form,
+ Rname]$List(InputForm))@InputForm)$InputForm)$AnyFunctions1(R)
+
+@
+\section{package MKFUNC MakeFunction}
+<<package MKFUNC MakeFunction>>=
+)abbrev package MKFUNC MakeFunction
+++ Tools for making interpreter functions from top-level expressions
+++ Author: Manuel Bronstein
+++ Date Created: 22 Nov 1988
+++ Date Last Updated: 8 Jan 1990
+++ Description: transforms top-level objects into interpreter functions.
+MakeFunction(S:ConvertibleTo InputForm): Exports == Implementation where
+ SY ==> Symbol
+
+ Exports ==> with
+ function: (S, SY ) -> SY
+ ++ function(e, foo) creates a function \spad{foo() == e}.
+ function: (S, SY, SY) -> SY
+ ++ function(e, foo, x) creates a function \spad{foo(x) == e}.
+ function: (S, SY, SY, SY) -> SY
+ ++ function(e, foo, x, y) creates a function \spad{foo(x, y) = e}.
+ function: (S, SY, List SY) -> SY
+ ++ \spad{function(e, foo, [x1,...,xn])} creates a function
+ ++ \spad{foo(x1,...,xn) == e}.
+
+ Implementation ==> add
+ function(s, name) == function(s, name, nil())
+ function(s:S, name:SY, x:SY) == function(s, name, [x])
+ function(s, name, x, y) == function(s, name, [x, y])
+
+ function(s:S, name:SY, args:List SY) ==
+ interpret function(convert s, args, name)$InputForm
+ name
+
+@
+\section{package MKUCFUNC MakeUnaryCompiledFunction}
+<<package MKUCFUNC MakeUnaryCompiledFunction>>=
+)abbrev package MKUCFUNC MakeUnaryCompiledFunction
+++ Tools for making compiled functions from top-level expressions
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1988
+++ Date Last Updated: 5 Mar 1990
+++ Description: transforms top-level objects into compiled functions.
+MakeUnaryCompiledFunction(S, D, I): Exports == Implementation where
+ S: ConvertibleTo InputForm
+ D, I: Type
+
+ SY ==> Symbol
+ DI ==> devaluate(D -> I)$Lisp
+
+ Exports ==> with
+ unaryFunction : SY -> (D -> I)
+ ++ unaryFunction(a) is a local function
+ compiledFunction: (S, SY) -> (D -> I)
+ ++ compiledFunction(expr, x) returns a function \spad{f: D -> I}
+ ++ defined by \spad{f(x) == expr}.
+ ++ Function f is compiled and directly
+ ++ applicable to objects of type D.
+
+ Implementation ==> add
+ import MakeFunction(S)
+
+ func: (SY, D) -> I
+
+ func(name, x) == FUNCALL(name, x, NIL$Lisp)$Lisp
+ unaryFunction name == func(name, #1)
+
+ compiledFunction(e:S, x:SY) ==
+ t := [convert([devaluate(D)$Lisp]$List(InputForm))
+ ]$List(InputForm)
+ unaryFunction compile(function(e, declare DI, x), t)
+
+@
+\section{package MKBCFUNC MakeBinaryCompiledFunction}
+<<package MKBCFUNC MakeBinaryCompiledFunction>>=
+)abbrev package MKBCFUNC MakeBinaryCompiledFunction
+++ Tools for making compiled functions from top-level expressions
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1988
+++ Date Last Updated: 5 Mar 1990
+++ Description: transforms top-level objects into compiled functions.
+MakeBinaryCompiledFunction(S, D1, D2, I):Exports == Implementation where
+ S: ConvertibleTo InputForm
+ D1, D2, I: Type
+
+ SY ==> Symbol
+ DI ==> devaluate((D1, D2) -> I)$Lisp
+
+ Exports ==> with
+ binaryFunction : SY -> ((D1, D2) -> I)
+ ++ binaryFunction(s) is a local function
+ compiledFunction: (S, SY, SY) -> ((D1, D2) -> I)
+ ++ compiledFunction(expr,x,y) returns a function \spad{f: (D1, D2) -> I}
+ ++ defined by \spad{f(x, y) == expr}.
+ ++ Function f is compiled and directly
+ ++ applicable to objects of type \spad{(D1, D2)}
+
+ Implementation ==> add
+ import MakeFunction(S)
+
+ func: (SY, D1, D2) -> I
+
+ func(name, x, y) == FUNCALL(name, x, y, NIL$Lisp)$Lisp
+ binaryFunction name == func(name, #1, #2)
+
+ compiledFunction(e, x, y) ==
+ t := [devaluate(D1)$Lisp, devaluate(D2)$Lisp]$List(InputForm)
+ binaryFunction compile(function(e, declare DI, x, y), t)
+
+@
+\section{package MKFLCFN MakeFloatCompiledFunction}
+<<package MKFLCFN MakeFloatCompiledFunction>>=
+)abbrev package MKFLCFN MakeFloatCompiledFunction
+++ Tools for making compiled functions from top-level expressions
+++ Author: Manuel Bronstein
+++ Date Created: 2 Mar 1990
+++ Date Last Updated: 2 Dec 1996 (MCD)
+++ Description:
+++ MakeFloatCompiledFunction transforms top-level objects into
+++ compiled Lisp functions whose arguments are Lisp floats.
+++ This by-passes the \Language{} compiler and interpreter,
+++ thereby gaining several orders of magnitude.
+MakeFloatCompiledFunction(S): Exports == Implementation where
+ S: ConvertibleTo InputForm
+
+ INF ==> InputForm
+ SF ==> DoubleFloat
+ DI1 ==> devaluate(SF -> SF)$Lisp
+ DI2 ==> devaluate((SF, SF) -> SF)$Lisp
+
+ Exports ==> with
+ makeFloatFunction: (S, Symbol) -> (SF -> SF)
+ ++ makeFloatFunction(expr, x) returns a Lisp function
+ ++ \spad{f: \axiomType{DoubleFloat} -> \axiomType{DoubleFloat}}
+ ++ defined by \spad{f(x) == expr}.
+ ++ Function f is compiled and directly
+ ++ applicable to objects of type \axiomType{DoubleFloat}.
+ makeFloatFunction: (S, Symbol, Symbol) -> ((SF, SF) -> SF)
+ ++ makeFloatFunction(expr, x, y) returns a Lisp function
+ ++ \spad{f: (\axiomType{DoubleFloat}, \axiomType{DoubleFloat}) -> \axiomType{DoubleFloat}}
+ ++ defined by \spad{f(x, y) == expr}.
+ ++ Function f is compiled and directly
+ ++ applicable to objects of type \spad{(\axiomType{DoubleFloat}, \axiomType{DoubleFloat})}.
+
+ Implementation ==> add
+ import MakeUnaryCompiledFunction(S, SF, SF)
+ import MakeBinaryCompiledFunction(S, SF, SF, SF)
+
+ streq? : (INF, String) -> Boolean
+ streqlist?: (INF, List String) -> Boolean
+ gencode : (String, List INF) -> INF
+ mkLisp : INF -> Union(INF, "failed")
+ mkLispList: List INF -> Union(List INF, "failed")
+ mkDefun : (INF, List INF) -> INF
+ mkLispCall: INF -> INF
+ mkPretend : INF -> INF
+ mkCTOR : INF -> INF
+
+ lsf := convert([convert("DoubleFloat"::Symbol)@INF]$List(INF))@INF
+
+ streq?(s, st) == s = convert(st::Symbol)@INF
+ gencode(s, l) == convert(concat(convert(s::Symbol)@INF, l))@INF
+ streqlist?(s, l) == member?(string symbol s, l)
+
+ mkPretend form ==
+ convert([convert("pretend"::Symbol), form, lsf]$List(INF))@INF
+
+ mkCTOR form ==
+ convert([convert("C-TO-R"::Symbol), form]$List(INF))@INF
+
+
+ mkLispCall name ==
+ convert([convert("$elt"::Symbol),
+ convert("Lisp"::Symbol), name]$List(INF))@INF
+
+ mkDefun(s, lv) ==
+ name := convert(new()$Symbol)@INF
+ fun := convert([convert("DEFUN"::Symbol), name, convert lv,
+ gencode("DECLARE",[gencode("FLOAT",lv)]),mkCTOR s]$List(INF))@INF
+ EVAL(fun)$Lisp
+ if _$compileDontDefineFunctions$Lisp then COMPILE(name)$Lisp
+ name
+
+ makeFloatFunction(f, x, y) ==
+ (u := mkLisp(convert(f)@INF)) case "failed" =>
+ compiledFunction(f, x, y)
+ name := mkDefun(u::INF, [ix := convert x, iy := convert y])
+ t := [lsf, lsf]$List(INF)
+ spadname := declare DI2
+ spadform:=mkPretend convert([mkLispCall name,ix,iy]$List(INF))@INF
+ interpret function(spadform, [x, y], spadname)
+ binaryFunction compile(spadname, t)
+
+ makeFloatFunction(f, var) ==
+ (u := mkLisp(convert(f)@INF)) case "failed" =>
+ compiledFunction(f, var)
+ name := mkDefun(u::INF, [ivar := convert var])
+ t := [lsf]$List(INF)
+ spadname := declare DI1
+ spadform:= mkPretend convert([mkLispCall name,ivar]$List(INF))@INF
+ interpret function(spadform, [var], spadname)
+ unaryFunction compile(spadname, t)
+
+ mkLispList l ==
+ ans := nil()$List(INF)
+ for s in l repeat
+ (u := mkLisp s) case "failed" => return "failed"
+ ans := concat(u::INF, ans)
+ reverse_! ans
+
+
+ mkLisp s ==
+ atom? s => s
+ op := first(l := destruct s)
+ (u := mkLispList rest l) case "failed" => "failed"
+ ll := u::List(INF)
+ streqlist?(op, ["+","*","/","-"]) => convert(concat(op, ll))@INF
+ streq?(op, "**") => gencode("EXPT", ll)
+ streqlist?(op, ["exp","sin","cos","tan","atan",
+ "log", "sinh","cosh","tanh","asinh","acosh","atanh","sqrt"]) =>
+ gencode(upperCase string symbol op, ll)
+ streq?(op, "nthRoot") =>
+ second ll = convert(2::Integer)@INF =>gencode("SQRT",[first ll])
+ gencode("EXPT", concat(first ll, [1$INF / second ll]))
+ streq?(op, "float") =>
+ a := ll.1
+ e := ll.2
+ b := ll.3
+ _*(a, EXPT(b, e)$Lisp)$Lisp pretend INF
+ "failed"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain INFORM InputForm>>
+<<package INFORM1 InputFormFunctions1>>
+<<package MKFUNC MakeFunction>>
+<<package MKUCFUNC MakeUnaryCompiledFunction>>
+<<package MKBCFUNC MakeBinaryCompiledFunction>>
+<<package MKFLCFN MakeFloatCompiledFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mkrecord.spad.pamphlet b/src/algebra/mkrecord.spad.pamphlet
new file mode 100644
index 00000000..2fe15855
--- /dev/null
+++ b/src/algebra/mkrecord.spad.pamphlet
@@ -0,0 +1,70 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mkrecord.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MKRECORD MakeRecord}
+<<package MKRECORD MakeRecord>>=
+)abbrev package MKRECORD MakeRecord
+++ Description:
+++ MakeRecord is used internally by the interpreter to create record
+++ types which are used for doing parallel iterations on streams.
+MakeRecord(S: Type, T: Type): public == private where
+ public == with
+ makeRecord: (S,T) -> Record(part1: S, part2: T)
+ ++ makeRecord(a,b) creates a record object with type
+ ++ Record(part1:S, part2:R), where part1 is \spad{a} and part2 is \spad{b}.
+ private == add
+ makeRecord(s: S, t: T) ==
+ [s,t]$Record(part1: S, part2: T)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MKRECORD MakeRecord>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mlift.spad.jhd.pamphlet b/src/algebra/mlift.spad.jhd.pamphlet
new file mode 100644
index 00000000..637d1b32
--- /dev/null
+++ b/src/algebra/mlift.spad.jhd.pamphlet
@@ -0,0 +1,272 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mlift.spad.jhd}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MLIFT MultivariateLifting}
+<<package MLIFT MultivariateLifting>>=
+)abbrev package MLIFT MultivariateLifting
+++ Author : P.Gianni.
+++ Description:
+++ This package provides the functions for the multivariate "lifting", using
+++ an algorithm of Paul Wang.
+++ This package will work for every euclidean domain R which has property
+++ F, i.e. there exists a factor operation in \spad{R[x]}.
+
+MultivariateLifting(E,OV,R,P) : C == T
+ where
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ R : EuclideanDomain -- with property "F"
+ Z ==> Integer
+ BP ==> SparseUnivariatePolynomial R
+ P : PolynomialCategory(R,E,OV)
+ SUP ==> SparseUnivariatePolynomial P
+ NNI ==> NonNegativeInteger
+ Term ==> Record(expt:NNI,pcoef:P)
+ VTerm ==> List Term
+ Table ==> Vector List BP
+ L ==> List
+
+ C == with
+ corrPoly: (SUP,L OV,L R,L NNI,L SUP,Table,R) -> Union(L SUP,"failed")
+ lifting: (SUP,L OV,L BP,L R,L P,L NNI,R) -> Union(L SUP,"failed")
+ lifting1: (SUP,L OV,L SUP,L R,L P,L VTerm,L NNI,Table,R) ->
+ Union(L SUP,"failed")
+
+ T == add
+ GenExEuclid(R,BP)
+ NPCoef(BP,E,OV,R,P)
+ IntegerCombinatoricFunctions(Z)
+
+ SUPF2 ==> SparseUnivariatePolynomialFunctions2
+
+ DetCoef ==> Record(deter:L SUP,dterm:L VTerm,nfacts:L BP,
+ nlead:L P)
+
+ --- local functions ---
+ normalDerivM : (P,Z,OV) -> P
+ normalDeriv : (SUP,Z) -> SUP
+ subslead : (SUP,P) -> SUP
+ subscoef : (SUP,L Term) -> SUP
+ maxDegree : (SUP,OV) -> NonNegativeInteger
+
+
+ corrPoly(m:SUP,lvar:L OV,fval:L R,ld:L NNI,flist:L SUP,
+ table:Table,pmod:R):Union(L SUP,"failed") ==
+ -- The correction coefficients are evaluated recursively.
+ -- Extended Euclidean algorithm for the multivariate case.
+
+ -- the polynomial is univariate --
+ #lvar=0 =>
+ lp:=solveid(map(ground,m)$SUPF2(P,R),pmod,table)
+ if lp case "failed" then return "failed"
+ lcoef:= [map(coerce,mp)$SUPF2(R,P) for mp in lp::L BP]
+
+
+ diff,ddiff,pol,polc:SUP
+ listpolv,listcong:L SUP
+ deg1:NNI:= ld.first
+ np:NNI:= #flist
+ a:P:= fval.first ::P
+ y:OV:=lvar.first
+ lvar:=lvar.rest
+ listpolv:L SUP := [map(eval(#1,y,a),f1) for f1 in flist]
+ um:=map(eval(#1,y,a),m)
+ flcoef:=corrPoly(um,lvar,fval.rest,ld.rest,listpolv,table,pmod)
+ if flcoef case "failed" then return "failed"
+ else lcoef:=flcoef :: L SUP
+ listcong:=[*/[flist.i for i in 1..np | i^=l] for l in 1..np]
+ polc:SUP:= (monomial(1,y,1) - a)::SUP
+ pol := 1$SUP
+ diff:=m- +/[lcoef.i*listcong.i for i in 1..np]
+ for l in 1..deg1 repeat
+ if diff=0 then return lcoef
+ pol := pol*polc
+ (ddiff:= map(eval(normalDerivM(#1,l,y),y,a),diff)) = 0 => "next l"
+ fbeta := corrPoly(ddiff,lvar,fval.rest,ld.rest,listpolv,table,pmod)
+ if fbeta case "failed" then return "failed"
+ else beta:=fbeta :: L SUP
+ lcoef := [lcoef.i+beta.i*pol for i in 1..np]
+ diff:=diff- +/[listcong.i*beta.i for i in 1..np]*pol
+ lcoef
+
+
+
+ lifting1(m:SUP,lvar:L OV,plist:L SUP,vlist:L R,tlist:L P,_
+ coeflist:L VTerm,listdeg:L NNI,table:Table,pmod:R) :Union(L SUP,"failed") ==
+ -- The factors of m (multivariate) are determined ,
+ -- We suppose to know the true univariate factors
+ -- some coefficients are determined
+ conglist:L SUP:=empty()
+ nvar : NNI:= #lvar
+ pol,polc:P
+ mc,mj:SUP
+ testp:Boolean:= (not empty?(tlist))
+ lalpha : L SUP := empty()
+ tlv:L P:=empty()
+ subsvar:L OV:=empty()
+ subsval:L R:=empty()
+ li:L OV := lvar
+ ldeg:L NNI:=empty()
+ clv:L VTerm:=empty()
+ --j =#variables, i=#factors
+ for j in 1..nvar repeat
+ x := li.first
+ li := rest li
+ conglist:= plist
+ v := vlist.first
+ vlist := rest vlist
+ degj := listdeg.j
+ ldeg := cons(degj,ldeg)
+ subsvar:=cons(x,subsvar)
+ subsval:=cons(v,subsval)
+
+ --substitute the determined coefficients
+ if testp then
+ if j<nvar then
+ tlv:=[eval(p,li,vlist) for p in tlist]
+ clv:=[[[term.expt,eval(term.pcoef,li,vlist)]$Term
+ for term in clist] for clist in coeflist]
+ else (tlv,clv):=(tlist,coeflist)
+ plist :=[subslead(p,lcp) for p in plist for lcp in tlv]
+ if not(empty? coeflist) then
+ plist:=[subscoef(tpol,clist)
+ for tpol in plist for clist in clv]
+ mj := map(eval(#1,li,vlist),m) --m(x1,..,xj,aj+1,..,an
+ polc := x::P - v::P --(xj-aj)
+ pol:= 1$P
+ --Construction of Rik, k in 1..right degree for xj+1
+ for k in 1..degj repeat --I can exit before
+ pol := pol*polc
+ mc := */[term for term in plist]-mj
+ if mc=0 then leave "next var"
+ --Modulus Dk
+ mc:=map(normalDerivM(#1,k,x),mc)
+ (mc := map(eval(#1,[x],[v]),mc))=0 => "next k"
+ flalpha:=corrPoly(mc,subsvar.rest,subsval.rest,
+ ldeg.rest,conglist,table,pmod)
+ if flalpha case "failed" then return "failed"
+ else lalpha:=flalpha :: L SUP
+ plist:=[term-alpha*pol for term in plist for alpha in lalpha]
+ for term in plist repeat degj:=degj-maxDegree(term,x)
+ degj ^= 0 => return "failed"
+ plist
+ --There are not extraneous factors
+
+ maxDegree(um:SUP,x:OV):NonNegativeInteger ==
+ ans:NonNegativeInteger:=0
+ while um ^= 0 repeat
+ ans:=max(ans,degree(leadingCoefficient um,x))
+ um:=reductum um
+ ans
+
+ lifting(um:SUP,lvar:L OV,plist:L BP,vlist:L R,
+ tlist:L P,listdeg:L NNI,pmod:R):Union(L SUP,"failed") ==
+ -- The factors of m (multivariate) are determined, when the
+ -- univariate true factors are known and some coefficient determined
+ nplist:List SUP:=[map(coerce,pp)$SUPF2(R,P) for pp in plist]
+ empty? tlist =>
+ table:=tablePow(degree um,pmod,plist)
+ table case "failed" => error "Table construction failed in MLIFT"
+ lifting1(um,lvar,nplist,vlist,tlist,empty(),listdeg,table,pmod)
+ ldcoef:DetCoef:=npcoef(um,plist,tlist)
+ if not empty?(listdet:=ldcoef.deter) then
+ if #listdet = #plist then return listdet
+ plist:=ldcoef.nfacts
+ nplist:=[map(coerce,pp)$SUPF2(R,P) for pp in plist]
+ um:=(um exquo */[pol for pol in listdet])::SUP
+ tlist:=ldcoef.nlead
+ tab:=tablePow(degree um,pmod,plist.rest)
+ else tab:=tablePow(degree um,pmod,plist)
+ tab case "failed" => error "Table construction failed in MLIFT"
+ table:Table:=tab
+ ffl:=lifting1(um,lvar,nplist,vlist,tlist,ldcoef.dterm,listdeg,table,pmod)
+ if ffl case "failed" then return "failed"
+ append(listdet,ffl:: L SUP)
+
+ -- normalDerivM(f,m,x) = the normalized (divided by m!) m-th
+ -- derivative with respect to x of the multivariate polynomial f
+ normalDerivM(g:P,m:Z,x:OV) : P ==
+ multivariate(normalDeriv(univariate(g,x),m),x)
+
+ normalDeriv(f:SUP,m:Z) : SUP ==
+ (n1:Z:=degree f) < m => 0$SUP
+ n1=m => leadingCoefficient f :: SUP
+ k:=binomial(n1,m)
+ ris:SUP:=0$SUP
+ n:Z:=n1
+ while n>= m repeat
+ while n1>n repeat
+ k:=(k*(n1-m)) quo n1
+ n1:=n1-1
+ ris:=ris+monomial(k*leadingCoefficient f,(n-m)::NNI)
+ f:=reductum f
+ n:=degree f
+ ris
+
+ subslead(m:SUP,pol:P):SUP ==
+ dm:NNI:=degree m
+ monomial(pol,dm)+reductum m
+
+ subscoef(um:SUP,lterm:L Term):SUP ==
+ dm:NNI:=degree um
+ new:=monomial(leadingCoefficient um,dm)
+ for k in dm-1..0 by -1 repeat
+ i:NNI:=k::NNI
+ empty?(lterm) or lterm.first.expt^=i =>
+ new:=new+monomial(coefficient(um,i),i)
+ new:=new+monomial(lterm.first.pcoef,i)
+ lterm:=lterm.rest
+ new
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MLIFT MultivariateLifting>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mlift.spad.pamphlet b/src/algebra/mlift.spad.pamphlet
new file mode 100644
index 00000000..4ec8d14c
--- /dev/null
+++ b/src/algebra/mlift.spad.pamphlet
@@ -0,0 +1,277 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mlift.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MLIFT MultivariateLifting}
+<<package MLIFT MultivariateLifting>>=
+)abbrev package MLIFT MultivariateLifting
+++ Author : P.Gianni.
+++ Description:
+++ This package provides the functions for the multivariate "lifting", using
+++ an algorithm of Paul Wang.
+++ This package will work for every euclidean domain R which has property
+++ F, i.e. there exists a factor operation in \spad{R[x]}.
+
+MultivariateLifting(E,OV,R,P) : C == T
+ where
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ R : EuclideanDomain -- with property "F"
+ Z ==> Integer
+ BP ==> SparseUnivariatePolynomial R
+ P : PolynomialCategory(R,E,OV)
+ SUP ==> SparseUnivariatePolynomial P
+ NNI ==> NonNegativeInteger
+ Term ==> Record(expt:NNI,pcoef:P)
+ VTerm ==> List Term
+ Table ==> Vector List BP
+ L ==> List
+
+ C == with
+ corrPoly: (SUP,L OV,L R,L NNI,L SUP,Table,R) -> Union(L SUP,"failed")
+ ++ corrPoly(u,lv,lr,ln,lu,t,r) \undocumented
+ lifting: (SUP,L OV,L BP,L R,L P,L NNI,R) -> Union(L SUP,"failed")
+ ++ lifting(u,lv,lu,lr,lp,ln,r) \undocumented
+ lifting1: (SUP,L OV,L SUP,L R,L P,L VTerm,L NNI,Table,R) ->
+ Union(L SUP,"failed")
+ ++ lifting1(u,lv,lu,lr,lp,lt,ln,t,r) \undocumented
+
+ T == add
+ GenExEuclid(R,BP)
+ NPCoef(BP,E,OV,R,P)
+ IntegerCombinatoricFunctions(Z)
+
+ SUPF2 ==> SparseUnivariatePolynomialFunctions2
+
+ DetCoef ==> Record(deter:L SUP,dterm:L VTerm,nfacts:L BP,
+ nlead:L P)
+
+ --- local functions ---
+ normalDerivM : (P,Z,OV) -> P
+ normalDeriv : (SUP,Z) -> SUP
+ subslead : (SUP,P) -> SUP
+ subscoef : (SUP,L Term) -> SUP
+ maxDegree : (SUP,OV) -> NonNegativeInteger
+
+
+ corrPoly(m:SUP,lvar:L OV,fval:L R,ld:L NNI,flist:L SUP,
+ table:Table,pmod:R):Union(L SUP,"failed") ==
+ -- The correction coefficients are evaluated recursively.
+ -- Extended Euclidean algorithm for the multivariate case.
+
+ -- the polynomial is univariate --
+ #lvar=0 =>
+ lp:=solveid(map(ground,m)$SUPF2(P,R),pmod,table)
+ if lp case "failed" then return "failed"
+ lcoef:= [map(coerce,mp)$SUPF2(R,P) for mp in lp::L BP]
+
+
+ diff,ddiff,pol,polc:SUP
+ listpolv,listcong:L SUP
+ deg1:NNI:= ld.first
+ np:NNI:= #flist
+ a:P:= fval.first ::P
+ y:OV:=lvar.first
+ lvar:=lvar.rest
+ listpolv:L SUP := [map(eval(#1,y,a),f1) for f1 in flist]
+ um:=map(eval(#1,y,a),m)
+ flcoef:=corrPoly(um,lvar,fval.rest,ld.rest,listpolv,table,pmod)
+ if flcoef case "failed" then return "failed"
+ else lcoef:=flcoef :: L SUP
+ listcong:=[*/[flist.i for i in 1..np | i^=l] for l in 1..np]
+ polc:SUP:= (monomial(1,y,1) - a)::SUP
+ pol := 1$SUP
+ diff:=m- +/[lcoef.i*listcong.i for i in 1..np]
+ for l in 1..deg1 repeat
+ if diff=0 then return lcoef
+ pol := pol*polc
+ (ddiff:= map(eval(normalDerivM(#1,l,y),y,a),diff)) = 0 => "next l"
+ fbeta := corrPoly(ddiff,lvar,fval.rest,ld.rest,listpolv,table,pmod)
+ if fbeta case "failed" then return "failed"
+ else beta:=fbeta :: L SUP
+ lcoef := [lcoef.i+beta.i*pol for i in 1..np]
+ diff:=diff- +/[listcong.i*beta.i for i in 1..np]*pol
+ lcoef
+
+
+
+ lifting1(m:SUP,lvar:L OV,plist:L SUP,vlist:L R,tlist:L P,_
+ coeflist:L VTerm,listdeg:L NNI,table:Table,pmod:R) :Union(L SUP,"failed") ==
+ -- The factors of m (multivariate) are determined ,
+ -- We suppose to know the true univariate factors
+ -- some coefficients are determined
+ conglist:L SUP:=empty()
+ nvar : NNI:= #lvar
+ pol,polc:P
+ mc,mj:SUP
+ testp:Boolean:= (not empty?(tlist))
+ lalpha : L SUP := empty()
+ tlv:L P:=empty()
+ subsvar:L OV:=empty()
+ subsval:L R:=empty()
+ li:L OV := lvar
+ ldeg:L NNI:=empty()
+ clv:L VTerm:=empty()
+ --j =#variables, i=#factors
+ for j in 1..nvar repeat
+ x := li.first
+ li := rest li
+ conglist:= plist
+ v := vlist.first
+ vlist := rest vlist
+ degj := listdeg.j
+ ldeg := cons(degj,ldeg)
+ subsvar:=cons(x,subsvar)
+ subsval:=cons(v,subsval)
+
+ --substitute the determined coefficients
+ if testp then
+ if j<nvar then
+ tlv:=[eval(p,li,vlist) for p in tlist]
+ clv:=[[[term.expt,eval(term.pcoef,li,vlist)]$Term
+ for term in clist] for clist in coeflist]
+ else (tlv,clv):=(tlist,coeflist)
+ plist :=[subslead(p,lcp) for p in plist for lcp in tlv]
+ if not(empty? coeflist) then
+ plist:=[subscoef(tpol,clist)
+ for tpol in plist for clist in clv]
+ mj := map(eval(#1,li,vlist),m) --m(x1,..,xj,aj+1,..,an
+ polc := x::P - v::P --(xj-aj)
+ pol:= 1$P
+ --Construction of Rik, k in 1..right degree for xj+1
+ for k in 1..degj repeat --I can exit before
+ pol := pol*polc
+ mc := */[term for term in plist]-mj
+ if mc=0 then leave "next var"
+ --Modulus Dk
+ mc:=map(normalDerivM(#1,k,x),mc)
+ (mc := map(eval(#1,[x],[v]),mc))=0 => "next k"
+ flalpha:=corrPoly(mc,subsvar.rest,subsval.rest,
+ ldeg.rest,conglist,table,pmod)
+ if flalpha case "failed" then return "failed"
+ else lalpha:=flalpha :: L SUP
+ plist:=[term-alpha*pol for term in plist for alpha in lalpha]
+ -- PGCD may call with a smaller valure of degj
+ idegj:Integer:=maxDegree(m,x)
+ for term in plist repeat idegj:=idegj -maxDegree(term,x)
+ idegj < 0 => return "failed"
+ plist
+ --There are not extraneous factors
+
+ maxDegree(um:SUP,x:OV):NonNegativeInteger ==
+ ans:NonNegativeInteger:=0
+ while um ^= 0 repeat
+ ans:=max(ans,degree(leadingCoefficient um,x))
+ um:=reductum um
+ ans
+
+ lifting(um:SUP,lvar:L OV,plist:L BP,vlist:L R,
+ tlist:L P,listdeg:L NNI,pmod:R):Union(L SUP,"failed") ==
+ -- The factors of m (multivariate) are determined, when the
+ -- univariate true factors are known and some coefficient determined
+ nplist:List SUP:=[map(coerce,pp)$SUPF2(R,P) for pp in plist]
+ empty? tlist =>
+ table:=tablePow(degree um,pmod,plist)
+ table case "failed" => error "Table construction failed in MLIFT"
+ lifting1(um,lvar,nplist,vlist,tlist,empty(),listdeg,table,pmod)
+ ldcoef:DetCoef:=npcoef(um,plist,tlist)
+ if not empty?(listdet:=ldcoef.deter) then
+ if #listdet = #plist then return listdet
+ plist:=ldcoef.nfacts
+ nplist:=[map(coerce,pp)$SUPF2(R,P) for pp in plist]
+ um:=(um exquo */[pol for pol in listdet])::SUP
+ tlist:=ldcoef.nlead
+ tab:=tablePow(degree um,pmod,plist.rest)
+ else tab:=tablePow(degree um,pmod,plist)
+ tab case "failed" => error "Table construction failed in MLIFT"
+ table:Table:=tab
+ ffl:=lifting1(um,lvar,nplist,vlist,tlist,ldcoef.dterm,listdeg,table,pmod)
+ if ffl case "failed" then return "failed"
+ append(listdet,ffl:: L SUP)
+
+ -- normalDerivM(f,m,x) = the normalized (divided by m!) m-th
+ -- derivative with respect to x of the multivariate polynomial f
+ normalDerivM(g:P,m:Z,x:OV) : P ==
+ multivariate(normalDeriv(univariate(g,x),m),x)
+
+ normalDeriv(f:SUP,m:Z) : SUP ==
+ (n1:Z:=degree f) < m => 0$SUP
+ n1=m => leadingCoefficient f :: SUP
+ k:=binomial(n1,m)
+ ris:SUP:=0$SUP
+ n:Z:=n1
+ while n>= m repeat
+ while n1>n repeat
+ k:=(k*(n1-m)) quo n1
+ n1:=n1-1
+ ris:=ris+monomial(k*leadingCoefficient f,(n-m)::NNI)
+ f:=reductum f
+ n:=degree f
+ ris
+
+ subslead(m:SUP,pol:P):SUP ==
+ dm:NNI:=degree m
+ monomial(pol,dm)+reductum m
+
+ subscoef(um:SUP,lterm:L Term):SUP ==
+ dm:NNI:=degree um
+ new:=monomial(leadingCoefficient um,dm)
+ for k in dm-1..0 by -1 repeat
+ i:NNI:=k::NNI
+ empty?(lterm) or lterm.first.expt^=i =>
+ new:=new+monomial(coefficient(um,i),i)
+ new:=new+monomial(lterm.first.pcoef,i)
+ lterm:=lterm.rest
+ new
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MLIFT MultivariateLifting>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/moddfact.spad.pamphlet b/src/algebra/moddfact.spad.pamphlet
new file mode 100644
index 00000000..19692d42
--- /dev/null
+++ b/src/algebra/moddfact.spad.pamphlet
@@ -0,0 +1,282 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra moddfact.spad}
+\author{Barry Trager, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MDDFACT ModularDistinctDegreeFactorizer}
+<<package MDDFACT ModularDistinctDegreeFactorizer>>=
+)abbrev package MDDFACT ModularDistinctDegreeFactorizer
+++ Author: Barry Trager
+++ Date Created:
+++ Date Last Updated: 20.9.95 (JHD)
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package supports factorization and gcds
+++ of univariate polynomials over the integers modulo different
+++ primes. The inputs are given as polynomials over the integers
+++ with the prime passed explicitly as an extra argument.
+
+ModularDistinctDegreeFactorizer(U):C == T where
+ U : UnivariatePolynomialCategory(Integer)
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ V ==> Vector
+ L ==> List
+ DDRecord ==> Record(factor:EMR,degree:I)
+ UDDRecord ==> Record(factor:U,degree:I)
+ DDList ==> L DDRecord
+ UDDList ==> L UDDRecord
+
+
+ C == with
+ gcd:(U,U,I) -> U
+ ++ gcd(f1,f2,p) computes the gcd of the univariate polynomials
+ ++ f1 and f2 modulo the integer prime p.
+ linears: (U,I) -> U
+ ++ linears(f,p) returns the product of all the linear factors
+ ++ of f modulo p. Potentially incorrect result if f is not
+ ++ square-free modulo p.
+ factor:(U,I) -> L U
+ ++ factor(f1,p) returns the list of factors of the univariate
+ ++ polynomial f1 modulo the integer prime p.
+ ++ Error: if f1 is not square-free modulo p.
+ ddFact:(U,I) -> UDDList
+ ++ ddFact(f,p) computes a distinct degree factorization of the
+ ++ polynomial f modulo the prime p, i.e. such that each factor
+ ++ is a product of irreducibles of the same degrees. The input
+ ++ polynomial f is assumed to be square-free modulo p.
+ separateFactors:(UDDList,I) -> L U
+ ++ separateFactors(ddl, p) refines the distinct degree factorization
+ ++ produced by \spadfunFrom{ddFact}{ModularDistinctDegreeFactorizer}
+ ++ to give a complete list of factors.
+ exptMod:(U,I,U,I) -> U
+ ++ exptMod(f,n,g,p) raises the univariate polynomial f to the nth
+ ++ power modulo the polynomial g and the prime p.
+
+ T == add
+ reduction(u:U,p:I):U ==
+ zero? p => u
+ map(positiveRemainder(#1,p),u)
+ merge(p:I,q:I):Union(I,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+ modInverse(c:I,p:I):I ==
+ (extendedEuclidean(c,p,1)::Record(coef1:I,coef2:I)).coef1
+ exactquo(u:U,v:U,p:I):Union(U,"failed") ==
+ invlcv:=modInverse(leadingCoefficient v,p)
+ r:=monicDivide(u,reduction(invlcv*v,p))
+ reduction(r.remainder,p) ^=0 => "failed"
+ reduction(invlcv*r.quotient,p)
+ EMR := EuclideanModularRing(Integer,U,Integer,
+ reduction,merge,exactquo)
+
+ probSplit2:(EMR,EMR,I) -> Union(List EMR,"failed")
+ trace:(EMR,I,EMR) -> EMR
+ ddfactor:EMR -> L EMR
+ ddfact:EMR -> DDList
+ sepFact1:DDRecord -> L EMR
+ sepfact:DDList -> L EMR
+ probSplit:(EMR,EMR,I) -> Union(L EMR,"failed")
+ makeMonic:EMR -> EMR
+ exptmod:(EMR,I,EMR) -> EMR
+
+ lc(u:EMR):I == leadingCoefficient(u::U)
+ degree(u:EMR):I == degree(u::U)
+ makeMonic(u) == modInverse(lc(u),modulus(u)) * u
+
+ i:I
+
+ exptmod(u1,i,u2) ==
+ i < 0 => error("negative exponentiation not allowed for exptMod")
+ ans:= 1$EMR
+ while i > 0 repeat
+ if odd?(i) then ans:= (ans * u1) rem u2
+ i:= i quo 2
+ u1:= (u1 * u1) rem u2
+ ans
+
+ exptMod(a,i,b,q) ==
+ ans:= exptmod(reduce(a,q),i,reduce(b,q))
+ ans::U
+
+ ddfactor(u) ==
+ if (c:= lc(u)) ^= 1$I then u:= makeMonic(u)
+ ans:= sepfact(ddfact(u))
+ cons(c::EMR,[makeMonic(f) for f in ans | degree(f) > 0])
+
+ gcd(u,v,q) == gcd(reduce(u,q),reduce(v,q))::U
+
+ factor(u,q) ==
+ v:= reduce(u,q)
+ dv:= reduce(differentiate(u),q)
+ degree gcd(v,dv) > 0 =>
+ error("Modular factor: polynomial must be squarefree")
+ ans:= ddfactor v
+ [f::U for f in ans]
+
+ ddfact(u) ==
+ p:=modulus u
+ w:= reduce(monomial(1,1)$U,p)
+ m:= w
+ d:I:= 1
+ if (c:= lc(u)) ^= 1$I then u:= makeMonic u
+ ans:DDList:= []
+ repeat
+ w:= exptmod(w,p,u)
+ g:= gcd(w - m,u)
+ if degree g > 0 then
+ g:= makeMonic(g)
+ ans:= [[g,d],:ans]
+ u:= (u quo g)
+ degree(u) = 0 => return [[c::EMR,0$I],:ans]
+ d:= d+1
+ d > (degree(u):I quo 2) =>
+ return [[c::EMR,0$I],[u,degree(u)],:ans]
+
+ ddFact(u,q) ==
+ ans:= ddfact(reduce(u,q))
+ [[(dd.factor)::U,dd.degree]$UDDRecord for dd in ans]$UDDList
+
+ linears(u,q) ==
+ uu:=reduce(u,q)
+ m:= reduce(monomial(1,1)$U,q)
+ gcd(exptmod(m,q,uu)-m,uu)::U
+
+ sepfact(factList) ==
+ "append"/[sepFact1(f) for f in factList]
+
+ separateFactors(uddList,q) ==
+ ans:= sepfact [[reduce(udd.factor,q),udd.degree]$DDRecord for
+ udd in uddList]$DDList
+ [f::U for f in ans]
+
+ decode(s:Integer, p:Integer, x:U):U ==
+ s<p => s::U
+ qr := divide(s,p)
+ qr.remainder :: U + x*decode(qr.quotient, p, x)
+
+ sepFact1(f) ==
+ u:= f.factor
+ p:=modulus u
+ (d := f.degree) = 0 => [u]
+ if (c:= lc(u)) ^= 1$I then u:= makeMonic(u)
+ d = (du := degree(u)) => [u]
+ ans:L EMR:= []
+ x:U:= monomial(1,1)
+ -- for small primes find linear factors by exhaustion
+ d=1 and p < 1000 =>
+ for i in 0.. while du > 0 repeat
+ if u(i::U) = 0 then
+ ans := cons(reduce(x-(i::U),p),ans)
+ du := du-1
+ ans
+ y:= x
+ s:I:= 0
+ ss:I := 1
+ stack:L EMR:= [u]
+ until null stack repeat
+ t:= reduce(((s::U)+x),p)
+ if not ((flist:= probSplit(first stack,t,d)) case "failed") then
+ stack:= rest stack
+ for fact in flist repeat
+ f1:= makeMonic(fact)
+ (df1:= degree(f1)) = 0 => nil
+ df1 > d => stack:= [f1,:stack]
+ ans:= [f1,:ans]
+ p = 2 =>
+ ss:= ss + 1
+ x := y * decode(ss, p, y)
+ s:= s+1
+ s = p =>
+ s:= 0
+ ss := ss + 1
+ x:= y * decode(ss, p, y)
+-- not one? leadingCoefficient(x) =>
+ not (leadingCoefficient(x) = 1) =>
+ ss := p ** degree x
+ x:= y ** (degree(x) + 1)
+ [c * first(ans),:rest(ans)]
+
+ probSplit(u,t,d) ==
+ (p:=modulus(u)) = 2 => probSplit2(u,t,d)
+ f1:= gcd(u,t)
+ r:= ((p**(d:NNI)-1) quo 2):NNI
+ n:= exptmod(t,r,u)
+ f2:= gcd(u,n + 1)
+ (g:= f1 * f2) = 1 => "failed"
+ g = u => "failed"
+ [f1,f2,(u quo g)]
+
+ probSplit2(u,t,d) ==
+ f:= gcd(u,trace(t,d,u))
+ f = 1 => "failed"
+ degree u = degree f => "failed"
+ [1,f,u quo f]
+
+ trace(t,d,u) ==
+ p:=modulus(t)
+ d:= d - 1
+ tt:=t
+ while d > 0 repeat
+ tt:= (tt + (t:=exptmod(t,p,u))) rem u
+ d:= d - 1
+ tt
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MDDFACT ModularDistinctDegreeFactorizer>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/modgcd.spad.pamphlet b/src/algebra/modgcd.spad.pamphlet
new file mode 100644
index 00000000..a2f056cf
--- /dev/null
+++ b/src/algebra/modgcd.spad.pamphlet
@@ -0,0 +1,315 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra modgcd.spad}
+\author{James Davenport, Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INMODGCD InnerModularGcd}
+<<package INMODGCD InnerModularGcd>>=
+)abbrev package INMODGCD InnerModularGcd
+++ Author: J.H. Davenport and P. Gianni
+++ Date Created: July 1990
+++ Date Last Updated: November 1991
+++ Description:
+++ This file contains the functions for modular gcd algorithm
+++ for univariate polynomials with coefficients in a
+++ non-trivial euclidean domain (i.e. not a field).
+++ The package parametrised by the coefficient domain,
+++ the polynomial domain, a prime,
+++ and a function for choosing the next prime
+
+Z ==> Integer
+NNI ==> NonNegativeInteger
+
+InnerModularGcd(R,BP,pMod,nextMod):C == T
+ where
+ R : EuclideanDomain
+ BP : UnivariatePolynomialCategory(R)
+ pMod : R
+ nextMod : (R,NNI) -> R
+
+ C == with
+ modularGcdPrimitive : List BP -> BP
+ ++ modularGcdPrimitive(f1,f2) computes the gcd of the two polynomials
+ ++ f1 and f2 by modular methods.
+ modularGcd : List BP -> BP
+ ++ modularGcd(listf) computes the gcd of the list of polynomials
+ ++ listf by modular methods.
+ reduction : (BP,R) -> BP
+ ++ reduction(f,p) reduces the coefficients of the polynomial f
+ ++ modulo the prime p.
+
+ T == add
+
+ -- local functions --
+ height : BP -> NNI
+ mbound : (BP,BP) -> NNI
+ modGcdPrimitive : (BP,BP) -> BP
+ test : (BP,BP,BP) -> Boolean
+ merge : (R,R) -> Union(R,"failed")
+ modInverse : (R,R) -> R
+ exactquo : (BP,BP,R) -> Union(BP,"failed")
+ constNotZero : BP -> Boolean
+ constcase : (List NNI ,List BP ) -> BP
+ lincase : (List NNI ,List BP ) -> BP
+
+
+ if R has IntegerNumberSystem then
+ reduction(u:BP,p:R):BP ==
+ p = 0 => u
+ map(symmetricRemainder(#1,p),u)
+ else
+ reduction(u:BP,p:R):BP ==
+ p = 0 => u
+ map(#1 rem p,u)
+
+ FP:=EuclideanModularRing(R,BP,R,reduction,merge,exactquo)
+ zeroChar : Boolean := R has CharacteristicZero
+
+ -- exported functions --
+
+ -- modular Gcd for a list of primitive polynomials
+ modularGcdPrimitive(listf : List BP) :BP ==
+ empty? listf => 0$BP
+ g := first listf
+ for f in rest listf | ^zero? f while degree g > 0 repeat
+ g:=modGcdPrimitive(g,f)
+ g
+
+ -- gcd for univariate polynomials
+ modularGcd(listf : List BP): BP ==
+ listf:=remove!(0$BP,listf)
+ empty? listf => 0$BP
+ # listf = 1 => first listf
+ minpol:=1$BP
+ -- extract a monomial gcd
+ mdeg:= "min"/[minimumDegree f for f in listf]
+ if mdeg>0 then
+ minpol1:= monomial(1,mdeg)
+ listf:= [(f exquo minpol1)::BP for f in listf]
+ minpol:=minpol*minpol1
+ listdeg:=[degree f for f in listf ]
+ -- make the polynomials primitive
+ listCont := [content f for f in listf]
+ contgcd:= gcd listCont
+ -- make the polynomials primitive
+ listf :=[(f exquo cf)::BP for f in listf for cf in listCont]
+ minpol:=contgcd*minpol
+ ans:BP :=
+ --one polynomial is constant
+ member?(1,listf) => 1
+ --one polynomial is linear
+ member?(1,listdeg) => lincase(listdeg,listf)
+ modularGcdPrimitive listf
+ minpol*ans
+
+ -- local functions --
+
+ --one polynomial is linear, remark that they are primitive
+ lincase(listdeg:List NNI ,listf:List BP ): BP ==
+ n:= position(1,listdeg)
+ g:=listf.n
+ for f in listf repeat
+ if (f1:=f exquo g) case "failed" then return 1$BP
+ g
+
+ -- test if d is the gcd
+ test(f:BP,g:BP,d:BP):Boolean ==
+ d0:=coefficient(d,0)
+ coefficient(f,0) exquo d0 case "failed" => false
+ coefficient(g,0) exquo d0 case "failed" => false
+ f exquo d case "failed" => false
+ g exquo d case "failed" => false
+ true
+
+ -- gcd and cofactors for PRIMITIVE univariate polynomials
+ -- also assumes that constant terms are non zero
+ modGcdPrimitive(f:BP,g:BP): BP ==
+ df:=degree f
+ dg:=degree g
+ dp:FP
+ lcf:=leadingCoefficient f
+ lcg:=leadingCoefficient g
+ testdeg:NNI
+ lcd:R:=gcd(lcf,lcg)
+ prime:=pMod
+ bound:=mbound(f,g)
+ while zero? (lcd rem prime) repeat
+ prime := nextMod(prime,bound)
+ soFar:=gcd(reduce(f,prime),reduce(g,prime))::BP
+ testdeg:=degree soFar
+ zero? testdeg => return 1$BP
+ ldp:FP:=
+ ((lcdp:=leadingCoefficient(soFar::BP)) = 1) =>
+ reduce(lcd::BP,prime)
+ reduce((modInverse(lcdp,prime)*lcd)::BP,prime)
+ soFar:=reduce(ldp::BP *soFar,prime)::BP
+ soFarModulus:=prime
+ -- choose the prime
+ while true repeat
+ prime := nextMod(prime,bound)
+ lcd rem prime =0 => "next prime"
+ fp:=reduce(f,prime)
+ gp:=reduce(g,prime)
+ dp:=gcd(fp,gp)
+ dgp :=euclideanSize dp
+ if dgp =0 then return 1$BP
+ if dgp=dg and ^(f exquo g case "failed") then return g
+ if dgp=df and ^(g exquo f case "failed") then return f
+ dgp > testdeg => "next prime"
+ ldp:FP:=
+ ((lcdp:=leadingCoefficient(dp::BP)) = 1) =>
+ reduce(lcd::BP,prime)
+ reduce((modInverse(lcdp,prime)*lcd)::BP,prime)
+ dp:=ldp *dp
+ dgp=testdeg =>
+ correction:=reduce(dp::BP-soFar,prime)::BP
+ zero? correction =>
+ ans:=reduce(lcd::BP*soFar,soFarModulus)::BP
+ cont:=content ans
+ ans:=(ans exquo cont)::BP
+ test(f,g,ans) => return ans
+ soFarModulus:=soFarModulus*prime
+ correctionFactor:=modInverse(soFarModulus rem prime,prime)
+ -- the initial rem is just for efficiency
+ soFar:=soFar+soFarModulus*(correctionFactor*correction)
+ soFarModulus:=soFarModulus*prime
+ soFar:=reduce(soFar,soFarModulus)::BP
+ dgp<testdeg =>
+ soFarModulus:=prime
+ soFar:=dp::BP
+ testdeg:=dgp
+ if ^zeroChar and euclideanSize(prime)>1 then
+ result:=dp::BP
+ test(f,g,result) => return result
+ -- this is based on the assumption that the caller of this package,
+ -- in non-zero characteristic, will use primes of the form
+ -- x-alpha as long as possible, but, if these are exhausted,
+ -- will switch to a prime of degree larger than the answer
+ -- so the result can be used directly.
+
+ merge(p:R,q:R):Union(R,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ modInverse(c:R,p:R):R ==
+ (extendedEuclidean(c,p,1)::Record(coef1:R,coef2:R)).coef1
+
+ exactquo(u:BP,v:BP,p:R):Union(BP,"failed") ==
+ invlcv:=modInverse(leadingCoefficient v,p)
+ r:=monicDivide(u,reduction(invlcv*v,p))
+ reduction(r.remainder,p) ^=0 => "failed"
+ reduction(invlcv*r.quotient,p)
+
+
+ -- compute the height of a polynomial --
+ height(f:BP):NNI ==
+ degf:=degree f
+ "max"/[euclideanSize cc for cc in coefficients f]
+
+ -- compute the bound
+ mbound(f:BP,g:BP):NNI ==
+ hf:=height f
+ hg:=height g
+ 2*min(hf,hg)
+
+\section{package FOMOGCD ForModularGcd}
+-- ForModularGcd(R,BP) : C == T
+-- where
+-- R : EuclideanDomain -- characteristic 0
+-- BP : UnivariatePolynomialCategory(R)
+--
+-- C == with
+-- nextMod : (R,NNI) -> R
+--
+-- T == add
+-- nextMod(val:R,bound:NNI) : R ==
+-- ival:Z:= val pretend Z
+-- (nextPrime(ival)$IntegerPrimesPackage(Z))::R
+--
+-- ForTwoGcd(F) : C == T
+-- where
+-- F : Join(Finite,Field)
+-- SUP ==> SparseUnivariatePolynomial
+-- R ==> SUP F
+-- P ==> SUP R
+-- UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+--
+-- C == with
+-- nextMod : (R,NNI) -> R
+--
+-- T == add
+-- nextMod(val:R,bound:NNI) : R ==
+-- ris:R:= nextItem(val) :: R
+-- euclideanSize ris < 2 => ris
+-- generateIrredPoly(
+-- (bound+1)::PositiveInteger)$IrredPolyOverFiniteField(F)
+--
+--
+-- ModularGcd(R,BP) == T
+-- where
+-- R : EuclideanDomain -- characteristic 0
+-- BP : UnivariatePolynomialCategory(R)
+-- T ==> InnerModularGcd(R,BP,67108859::R,nextMod$ForModularGcd(R,BP))
+--
+-- TwoGcd(F) : C == T
+-- where
+-- F : Join(Finite,Field)
+-- SUP ==> SparseUnivariatePolynomial
+-- R ==> SUP F
+-- P ==> SUP R
+--
+-- T ==> InnerModularGcd(R,P,nextMod(monomial(1,1)$R)$ForTwoGcd(F),
+-- nextMod$ForTwoGcd(F))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INMODGCD InnerModularGcd>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/modmon.spad.pamphlet b/src/algebra/modmon.spad.pamphlet
new file mode 100644
index 00000000..cc8bebec
--- /dev/null
+++ b/src/algebra/modmon.spad.pamphlet
@@ -0,0 +1,224 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra modmon.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MODMON ModMonic}
+<<domain MODMON ModMonic>>=
+)abbrev domain MODMON ModMonic
+++ Description:
+++ This package \undocumented
+-- following line prevents caching ModMonic
+)bo PUSH('ModMonic, $mutableDomains)
+
+ModMonic(R,Rep): C == T
+ where
+ R: Ring
+ Rep: UnivariatePolynomialCategory(R)
+ C == UnivariatePolynomialCategory(R) with
+ --operations
+ setPoly : Rep -> Rep
+ ++ setPoly(x) \undocumented
+ modulus : -> Rep
+ ++ modulus() \undocumented
+ reduce: Rep -> %
+ ++ reduce(x) \undocumented
+ lift: % -> Rep --reduce lift = identity
+ ++ lift(x) \undocumented
+ coerce: Rep -> %
+ ++ coerce(x) \undocumented
+ Vectorise: % -> Vector(R)
+ ++ Vectorise(x) \undocumented
+ UnVectorise: Vector(R) -> %
+ ++ UnVectorise(v) \undocumented
+ An: % -> Vector(R)
+ ++ An(x) \undocumented
+ pow : -> PrimitiveArray(%)
+ ++ pow() \undocumented
+ computePowers : -> PrimitiveArray(%)
+ ++ computePowers() \undocumented
+ if R has FiniteFieldCategory then
+ frobenius: % -> %
+ ++ frobenius(x) \undocumented
+ --LinearTransf: (%,Vector(R)) -> SquareMatrix<deg> R
+ --assertions
+ if R has Finite then Finite
+ T == add
+ --constants
+ m:Rep := monomial(1,1)$Rep --| degree(m) > 0 and LeadingCoef(m) = R$1
+ d := degree(m)$Rep
+ d1 := (d-1):NonNegativeInteger
+ twod := 2*d1+1
+ frobenius?:Boolean := R has FiniteFieldCategory
+ --VectorRep:= DirectProduct(d:NonNegativeInteger,R)
+ --declarations
+ x,y: %
+ p: Rep
+ d,n: Integer
+ e,k1,k2: NonNegativeInteger
+ c: R
+ --vect: Vector(R)
+ power:PrimitiveArray(%)
+ frobeniusPower:PrimitiveArray(%)
+ computeFrobeniusPowers : () -> PrimitiveArray(%)
+ --representations
+ --mutable m --take this out??
+ --define
+ power := new(0,0)
+ frobeniusPower := new(0,0)
+ setPoly (mon : Rep) ==
+ mon =$Rep m => mon
+ oldm := m
+ leadingCoefficient mon ^= 1 => error "polynomial must be monic"
+ -- following copy code needed since FFPOLY can modify mon
+ copymon:Rep:= 0
+ while not zero? mon repeat
+ copymon := monomial(leadingCoefficient mon, degree mon)$Rep + copymon
+ mon := reductum mon
+ m := copymon
+ d := degree(m)$Rep
+ d1 := (d-1)::NonNegativeInteger
+ twod := 2*d1+1
+ power := computePowers()
+ if frobenius? then
+ degree(oldm)>1 and not((oldm exquo$Rep m) case "failed") =>
+ for i in 1..d1 repeat
+ frobeniusPower(i) := reduce lift frobeniusPower(i)
+ frobeniusPower := computeFrobeniusPowers()
+ m
+ modulus == m
+ if R has Finite then
+ size == d * size$R
+ random == UnVectorise([random()$R for i in 0..d1])
+ 0 == 0$Rep
+ 1 == 1$Rep
+ c * x == c *$Rep x
+ n * x == (n::R) *$Rep x
+ coerce(c:R):% == monomial(c,0)$Rep
+ coerce(x:%):OutputForm == coerce(x)$Rep
+ coefficient(x,e):R == coefficient(x,e)$Rep
+ reductum(x) == reductum(x)$Rep
+ leadingCoefficient x == (leadingCoefficient x)$Rep
+ degree x == (degree x)$Rep
+ lift(x) == x pretend Rep
+ reduce(p) == (monicDivide(p,m)$Rep).remainder
+ coerce(p) == reduce(p)
+ x = y == x =$Rep y
+ x + y == x +$Rep y
+ - x == -$Rep x
+ x * y ==
+ p := x *$Rep y
+ ans:=0$Rep
+ while (n:=degree p)>d1 repeat
+ ans:=ans + leadingCoefficient(p)*power.(n-d)
+ p := reductum p
+ ans+p
+ Vectorise(x) == [coefficient(lift(x),i) for i in 0..d1]
+ UnVectorise(vect) ==
+ reduce(+/[monomial(vect.(i+1),i) for i in 0..d1])
+ computePowers ==
+ mat : PrimitiveArray(%):= new(d,0)
+ mat.0:= reductum(-m)$Rep
+ w: % := monomial$Rep (1,1)
+ for i in 1..d1 repeat
+ mat.i := w *$Rep mat.(i-1)
+ if degree mat.i=d then
+ mat.i:= reductum mat.i + leadingCoefficient mat.i * mat.0
+ mat
+ if frobenius? then
+ computeFrobeniusPowers() ==
+ mat : PrimitiveArray(%):= new(d,1)
+ mat.1:= mult := monomial(1, size$R)$%
+ for i in 2..d1 repeat
+ mat.i := mult * mat.(i-1)
+ mat
+
+ frobenius(a:%):% ==
+ aq:% := 0
+ while a^=0 repeat
+ aq:= aq + leadingCoefficient(a)*frobeniusPower(degree a)
+ a := reductum a
+ aq
+
+ pow == power
+ monomial(c,e)==
+ if e<d then monomial(c,e)$Rep
+ else
+ if e<=twod then
+ c * power.(e-d)
+ else
+ k1:=e quo twod
+ k2 := (e-k1*twod)::NonNegativeInteger
+ reduce((power.d1 **k1)*monomial(c,k2))
+ if R has Field then
+
+ (x:% exquo y:%):Union(%, "failed") ==
+ uv := extendedEuclidean(y, modulus(), x)$Rep
+ uv case "failed" => "failed"
+ return reduce(uv.coef1)
+
+ recip(y:%):Union(%, "failed") == 1 exquo y
+ divide(x:%, y:%) ==
+ (q := (x exquo y)) case "failed" => error "not divisible"
+ [q, 0]
+
+-- An(MM) == Vectorise(-(reduce(reductum(m))::MM))
+-- LinearTransf(vect,MM) ==
+-- ans:= 0::SquareMatrix<d>(R)
+-- for i in 1..d do setelt(ans,i,1,vect.i)
+-- for j in 2..d do
+-- setelt(ans,1,j, elt(ans,d,j-1) * An(MM).1)
+-- for i in 2..d do
+-- setelt(ans,i,j, elt(ans,i-1,j-1) + elt(ans,d,j-1) * An(MM).i)
+-- ans
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MODMON ModMonic>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/modmonom.spad.pamphlet b/src/algebra/modmonom.spad.pamphlet
new file mode 100644
index 00000000..f96b812c
--- /dev/null
+++ b/src/algebra/modmonom.spad.pamphlet
@@ -0,0 +1,158 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra modmonom.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MODMONOM ModuleMonomial}
+<<domain MODMONOM ModuleMonomial>>=
+)abbrev domain MODMONOM ModuleMonomial
+++ Description:
+++ This package \undocumented
+ModuleMonomial(IS: OrderedSet,
+ E: SetCategory,
+ ff:(MM, MM) -> Boolean): T == C where
+
+ MM ==> Record(index:IS, exponent:E)
+
+ T == OrderedSet with
+ exponent: $ -> E
+ ++ exponent(x) \undocumented
+ index: $ -> IS
+ ++ index(x) \undocumented
+ coerce: MM -> $
+ ++ coerce(x) \undocumented
+ coerce: $ -> MM
+ ++ coerce(x) \undocumented
+ construct: (IS, E) -> $
+ ++ construct(i,e) \undocumented
+ C == MM add
+ Rep:= MM
+ x:$ < y:$ == ff(x::Rep, y::Rep)
+ exponent(x:$):E == x.exponent
+ index(x:$): IS == x.index
+ coerce(x:$):MM == x::Rep::MM
+ coerce(x:MM):$ == x::Rep::$
+ construct(i:IS, e:E):$ == [i, e]$MM::Rep::$
+
+@
+\section{domain GMODPOL GeneralModulePolynomial}
+<<domain GMODPOL GeneralModulePolynomial>>=
+)abbrev domain GMODPOL GeneralModulePolynomial
+++ Description:
+++ This package \undocumented
+GeneralModulePolynomial(vl, R, IS, E, ff, P): public == private where
+ vl: List(Symbol)
+ R: CommutativeRing
+ IS: OrderedSet
+ NNI ==> NonNegativeInteger
+ E: DirectProductCategory(#vl, NNI)
+ MM ==> Record(index:IS, exponent:E)
+ ff: (MM, MM) -> Boolean
+ OV ==> OrderedVariableList(vl)
+ P: PolynomialCategory(R, E, OV)
+ ModMonom ==> ModuleMonomial(IS, E, ff)
+
+
+ public == Join(Module(P), Module(R)) with
+ leadingCoefficient: $ -> R
+ ++ leadingCoefficient(x) \undocumented
+ leadingMonomial: $ -> ModMonom
+ ++ leadingMonomial(x) \undocumented
+ leadingExponent: $ -> E
+ ++ leadingExponent(x) \undocumented
+ leadingIndex: $ -> IS
+ ++ leadingIndex(x) \undocumented
+ reductum: $ -> $
+ ++ reductum(x) \undocumented
+ monomial: (R, ModMonom) -> $
+ ++ monomial(r,x) \undocumented
+ unitVector: IS -> $
+ ++ unitVector(x) \undocumented
+ build: (R, IS, E) -> $
+ ++ build(r,i,e) \undocumented
+ multMonom: (R, E, $) -> $
+ ++ multMonom(r,e,x) \undocumented
+ "*": (P,$) -> $
+ ++ p*x \undocumented
+
+
+ private == FreeModule(R, ModMonom) add
+ Rep:= FreeModule(R, ModMonom)
+ leadingMonomial(p:$):ModMonom == leadingSupport(p)$Rep
+ leadingExponent(p:$):E == exponent(leadingMonomial p)
+ leadingIndex(p:$):IS == index(leadingMonomial p)
+ unitVector(i:IS):$ == monomial(1,[i, 0$E]$ModMonom)
+
+
+ -----------------------------------------------------------------------------
+
+ build(c:R, i:IS, e:E):$ == monomial(c, construct(i, e))
+
+ -----------------------------------------------------------------------------
+
+ ---- WARNING: assumes c ^= 0
+
+ multMonom(c:R, e:E, mp:$):$ ==
+ zero? mp => mp
+ monomial(c * leadingCoefficient mp, [leadingIndex mp,
+ e + leadingExponent mp]) + multMonom(c, e, reductum mp)
+
+ -----------------------------------------------------------------------------
+
+
+ ((p:P) * (mp:$)):$ ==
+ zero? p => 0
+ multMonom(leadingCoefficient p, degree p, mp) +
+ reductum(p) * mp
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MODMONOM ModuleMonomial>>
+<<domain GMODPOL GeneralModulePolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/modring.spad.pamphlet b/src/algebra/modring.spad.pamphlet
new file mode 100644
index 00000000..015a5c84
--- /dev/null
+++ b/src/algebra/modring.spad.pamphlet
@@ -0,0 +1,280 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra modring.spad}
+\author{Patrizia Gianni, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MODRING ModularRing}
+<<domain MODRING ModularRing>>=
+)abbrev domain MODRING ModularRing
+++ Author: P.Gianni, B.Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ These domains are used for the factorization and gcds
+++ of univariate polynomials over the integers in order to work modulo
+++ different primes.
+++ See \spadtype{EuclideanModularRing} ,\spadtype{ModularField}
+
+ModularRing(R,Mod,reduction:(R,Mod) -> R,
+ merge:(Mod,Mod) -> Union(Mod,"failed"),
+ exactQuo : (R,R,Mod) -> Union(R,"failed")) : C == T
+ where
+ R : CommutativeRing
+ Mod : AbelianMonoid
+
+ C == Ring with
+ modulus : % -> Mod
+ ++ modulus(x) \undocumented
+ coerce : % -> R
+ ++ coerce(x) \undocumented
+ reduce : (R,Mod) -> %
+ ++ reduce(r,m) \undocumented
+ exQuo : (%,%) -> Union(%,"failed")
+ ++ exQuo(x,y) \undocumented
+ recip : % -> Union(%,"failed")
+ ++ recip(x) \undocumented
+ inv : % -> %
+ ++ inv(x) \undocumented
+
+ T == add
+ --representation
+ Rep:= Record(val:R,modulo:Mod)
+ --declarations
+ x,y: %
+
+ --define
+ modulus(x) == x.modulo
+ coerce(x) == x.val
+ coerce(i:Integer):% == [i::R,0]$Rep
+ i:Integer * x:% == (i::%)*x
+ coerce(x):OutputForm == (x.val)::OutputForm
+ reduce (a:R,m:Mod) == [reduction(a,m),m]$Rep
+
+ characteristic():NonNegativeInteger == characteristic()$R
+ 0 == [0$R,0$Mod]$Rep
+ 1 == [1$R,0$Mod]$Rep
+ zero? x == zero? x.val
+-- one? x == one? x.val
+ one? x == (x.val = 1)
+
+ newmodulo(m1:Mod,m2:Mod) : Mod ==
+ r:=merge(m1,m2)
+ r case "failed" => error "incompatible moduli"
+ r::Mod
+
+ x=y ==
+ x.val = y.val => true
+ x.modulo = y.modulo => false
+ (x-y).val = 0
+ x+y == reduce((x.val +$R y.val),newmodulo(x.modulo,y.modulo))
+ x-y == reduce((x.val -$R y.val),newmodulo(x.modulo,y.modulo))
+ -x == reduce ((-$R x.val),x.modulo)
+ x*y == reduce((x.val *$R y.val),newmodulo(x.modulo,y.modulo))
+
+ exQuo(x,y) ==
+ xm:=x.modulo
+ if xm ^=$Mod y.modulo then xm:=newmodulo(xm,y.modulo)
+ r:=exactQuo(x.val,y.val,xm)
+ r case "failed"=> "failed"
+ [r::R,xm]$Rep
+
+ --if R has EuclideanDomain then
+ recip x ==
+ r:=exactQuo(1$R,x.val,x.modulo)
+ r case "failed" => "failed"
+ [r,x.modulo]$Rep
+
+ inv x ==
+ if (u:=recip x) case "failed" then error("not invertible")
+ else u::%
+
+@
+\section{domain EMR EuclideanModularRing}
+<<domain EMR EuclideanModularRing>>=
+)abbrev domain EMR EuclideanModularRing
+++ Description:
+++ These domains are used for the factorization and gcds
+++ of univariate polynomials over the integers in order to work modulo
+++ different primes.
+++ See \spadtype{ModularRing}, \spadtype{ModularField}
+EuclideanModularRing(S,R,Mod,reduction:(R,Mod) -> R,
+ merge:(Mod,Mod) -> Union(Mod,"failed"),
+ exactQuo : (R,R,Mod) -> Union(R,"failed")) : C == T
+ where
+ S : CommutativeRing
+ R : UnivariatePolynomialCategory S
+ Mod : AbelianMonoid
+
+ C == EuclideanDomain with
+ modulus : % -> Mod
+ ++ modulus(x) \undocumented
+ coerce : % -> R
+ ++ coerce(x) \undocumented
+ reduce : (R,Mod) -> %
+ ++ reduce(r,m) \undocumented
+ exQuo : (%,%) -> Union(%,"failed")
+ ++ exQuo(x,y) \undocumented
+ recip : % -> Union(%,"failed")
+ ++ recip(x) \undocumented
+ inv : % -> %
+ ++ inv(x) \undocumented
+ elt : (%, R) -> R
+ ++ elt(x,r) or x.r \undocumented
+
+ T == ModularRing(R,Mod,reduction,merge,exactQuo) add
+
+ --representation
+ Rep:= Record(val:R,modulo:Mod)
+ --declarations
+ x,y,z: %
+
+ divide(x,y) ==
+ t:=merge(x.modulo,y.modulo)
+ t case "failed" => error "incompatible moduli"
+ xm:=t::Mod
+ yv:=y.val
+ invlcy:R
+-- if one? leadingCoefficient yv then invlcy:=1
+ if (leadingCoefficient yv = 1) then invlcy:=1
+ else
+ invlcy:=(inv reduce((leadingCoefficient yv)::R,xm)).val
+ yv:=reduction(invlcy*yv,xm)
+ r:=monicDivide(x.val,yv)
+ [reduce(invlcy*r.quotient,xm),reduce(r.remainder,xm)]
+
+ if R has fmecg:(R,NonNegativeInteger,S,R)->R
+ then x rem y ==
+ t:=merge(x.modulo,y.modulo)
+ t case "failed" => error "incompatible moduli"
+ xm:=t::Mod
+ yv:=y.val
+ invlcy:R
+-- if not one? leadingCoefficient yv then
+ if not (leadingCoefficient yv = 1) then
+ invlcy:=(inv reduce((leadingCoefficient yv)::R,xm)).val
+ yv:=reduction(invlcy*yv,xm)
+ dy:=degree yv
+ xv:=x.val
+ while (d:=degree xv - dy)>=0 repeat
+ xv:=reduction(fmecg(xv,d::NonNegativeInteger,
+ leadingCoefficient xv,yv),xm)
+ xv = 0 => return [xv,xm]$Rep
+ [xv,xm]$Rep
+ else x rem y ==
+ t:=merge(x.modulo,y.modulo)
+ t case "failed" => error "incompatible moduli"
+ xm:=t::Mod
+ yv:=y.val
+ invlcy:R
+-- if not one? leadingCoefficient yv then
+ if not (leadingCoefficient yv = 1) then
+ invlcy:=(inv reduce((leadingCoefficient yv)::R,xm)).val
+ yv:=reduction(invlcy*yv,xm)
+ r:=monicDivide(x.val,yv)
+ reduce(r.remainder,xm)
+
+ euclideanSize x == degree x.val
+
+ unitCanonical x ==
+ zero? x => x
+ degree(x.val) = 0 => 1
+-- one? leadingCoefficient(x.val) => x
+ (leadingCoefficient(x.val) = 1) => x
+ invlcx:%:=inv reduce((leadingCoefficient(x.val))::R,x.modulo)
+ invlcx * x
+
+ unitNormal x ==
+-- zero?(x) or one?(leadingCoefficient(x.val)) => [1, x, 1]
+ zero?(x) or ((leadingCoefficient(x.val)) = 1) => [1, x, 1]
+ lcx := reduce((leadingCoefficient(x.val))::R,x.modulo)
+ invlcx:=inv lcx
+ degree(x.val) = 0 => [lcx, 1, invlcx]
+ [lcx, invlcx * x, invlcx]
+
+ elt(x : %,s : R) : R == reduction(elt(x.val,s),x.modulo)
+
+@
+\section{domain MODFIELD ModularField}
+<<domain MODFIELD ModularField>>=
+)abbrev domain MODFIELD ModularField
+++ These domains are used for the factorization and gcds
+++ of univariate polynomials over the integers in order to work modulo
+++ different primes.
+++ See \spadtype{ModularRing}, \spadtype{EuclideanModularRing}
+ModularField(R,Mod,reduction:(R,Mod) -> R,
+ merge:(Mod,Mod) -> Union(Mod,"failed"),
+ exactQuo : (R,R,Mod) -> Union(R,"failed")) : C == T
+ where
+ R : CommutativeRing
+ Mod : AbelianMonoid
+
+ C == Field with
+ modulus : % -> Mod
+ ++ modulus(x) \undocumented
+ coerce : % -> R
+ ++ coerce(x) \undocumented
+ reduce : (R,Mod) -> %
+ ++ reduce(r,m) \undocumented
+ exQuo : (%,%) -> Union(%,"failed")
+ ++ exQuo(x,y) \undocumented
+
+ T == ModularRing(R,Mod,reduction,merge,exactQuo)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MODRING ModularRing>>
+<<domain EMR EuclideanModularRing>>
+<<domain MODFIELD ModularField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/moebius.spad.pamphlet b/src/algebra/moebius.spad.pamphlet
new file mode 100644
index 00000000..2185b426
--- /dev/null
+++ b/src/algebra/moebius.spad.pamphlet
@@ -0,0 +1,154 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra moebius.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MOEBIUS MoebiusTransform}
+<<domain MOEBIUS MoebiusTransform>>=
+)abbrev domain MOEBIUS MoebiusTransform
+++ 2-by-2 matrices acting on P1(F).
+++ Author: Stephen "Say" Watt
+++ Date Created: January 1987
+++ Date Last Updated: 11 April 1990
+++ Keywords:
+++ Examples:
+++ References:
+MoebiusTransform(F): Exports == Implementation where
+ ++ MoebiusTransform(F) is the domain of fractional linear (Moebius)
+ ++ transformations over F.
+ F : Field
+ OUT ==> OutputForm
+ P1F ==> OnePointCompletion F -- projective 1-space over F
+
+ Exports ==> Group with
+
+ moebius: (F,F,F,F) -> %
+ ++ moebius(a,b,c,d) returns \spad{matrix [[a,b],[c,d]]}.
+ shift: F -> %
+ ++ shift(k) returns \spad{matrix [[1,k],[0,1]]} representing the map
+ ++ \spad{x -> x + k}.
+ scale: F -> %
+ ++ scale(k) returns \spad{matrix [[k,0],[0,1]]} representing the map
+ ++ \spad{x -> k * x}.
+ recip: () -> %
+ ++ recip() returns \spad{matrix [[0,1],[1,0]]} representing the map
+ ++ \spad{x -> 1 / x}.
+ shift: (%,F) -> %
+ ++ shift(m,h) returns \spad{shift(h) * m}
+ ++ (see \spadfunFrom{shift}{MoebiusTransform}).
+ scale: (%,F) -> %
+ ++ scale(m,h) returns \spad{scale(h) * m}
+ ++ (see \spadfunFrom{shift}{MoebiusTransform}).
+ recip: % -> %
+ ++ recip(m) = recip() * m
+ eval: (%,F) -> F
+ ++ eval(m,x) returns \spad{(a*x + b)/(c*x + d)}
+ ++ where \spad{m = moebius(a,b,c,d)}
+ ++ (see \spadfunFrom{moebius}{MoebiusTransform}).
+ eval: (%,P1F) -> P1F
+ ++ eval(m,x) returns \spad{(a*x + b)/(c*x + d)}
+ ++ where \spad{m = moebius(a,b,c,d)}
+ ++ (see \spadfunFrom{moebius}{MoebiusTransform}).
+
+ Implementation ==> add
+
+ Rep := Record(a: F,b: F,c: F,d: F)
+
+ moebius(aa,bb,cc,dd) == [aa,bb,cc,dd]
+
+ a(t:%):F == t.a
+ b(t:%):F == t.b
+ c(t:%):F == t.c
+ d(t:%):F == t.d
+
+ 1 == moebius(1,0,0,1)
+ t * s ==
+ moebius(b(t)*c(s) + a(t)*a(s), b(t)*d(s) + a(t)*b(s), _
+ d(t)*c(s) + c(t)*a(s), d(t)*d(s) + c(t)*b(s))
+ inv t == moebius(d(t),-b(t),-c(t),a(t))
+
+ shift f == moebius(1,f,0,1)
+ scale f == moebius(f,0,0,1)
+ recip() == moebius(0,1,1,0)
+
+ shift(t,f) == moebius(a(t) + f*c(t), b(t) + f*d(t), c(t), d(t))
+ scale(t,f) == moebius(f*a(t),f*b(t),c(t),d(t))
+ recip t == moebius(c(t),d(t),a(t),b(t))
+
+ eval(t:%,f:F) == (a(t)*f + b(t))/(c(t)*f + d(t))
+ eval(t:%,f:P1F) ==
+ (ff := retractIfCan(f)@Union(F,"failed")) case "failed" =>
+ (a(t)/c(t)) :: P1F
+ zero?(den := c(t) * (fff := ff :: F) + d(t)) => infinity()
+ ((a(t) * fff + b(t))/den) :: P1F
+
+ coerce t ==
+ var := "%x" :: OUT
+ num := (a(t) :: OUT) * var + (b(t) :: OUT)
+ den := (c(t) :: OUT) * var + (d(t) :: OUT)
+ rarrow(var,num/den)
+
+ proportional?: (List F,List F) -> Boolean
+ proportional?(list1,list2) ==
+ empty? list1 => empty? list2
+ empty? list2 => false
+ zero? (x1 := first list1) =>
+ (zero? first list2) and proportional?(rest list1,rest list2)
+ zero? (x2 := first list2) => false
+ map(#1 / x1,list1) = map(#1 / x2,list2)
+
+ t = s ==
+ list1 : List F := [a(t),b(t),c(t),d(t)]
+ list2 : List F := [a(s),b(s),c(s),d(s)]
+ proportional?(list1,list2)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MOEBIUS MoebiusTransform>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mring.spad.pamphlet b/src/algebra/mring.spad.pamphlet
new file mode 100644
index 00000000..04c50f32
--- /dev/null
+++ b/src/algebra/mring.spad.pamphlet
@@ -0,0 +1,405 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mring.spad}
+\author{Stephen M. Watt, Johannes Grabmeier, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MRING MonoidRing}
+<<domain MRING MonoidRing>>=
+)abbrev domain MRING MonoidRing
+++ Authors: Stephan M. Watt; revised by Johannes Grabmeier
+++ Date Created: January 1986
+++ Date Last Updated: 14 December 1995, Mike Dewar
+++ Basic Operations: *, +, monomials, coefficients
+++ Related Constructors: Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords: monoid ring, group ring, polynomials in non-commuting
+++ indeterminates
+++ References:
+++ Description:
+++ \spadtype{MonoidRing}(R,M), implements the algebra
+++ of all maps from the monoid M to the commutative ring R with
+++ finite support.
+++ Multiplication of two maps f and g is defined
+++ to map an element c of M to the (convolution) sum over {\em f(a)g(b)}
+++ such that {\em ab = c}. Thus M can be identified with a canonical
+++ basis and the maps can also be considered as formal linear combinations
+++ of the elements in M. Scalar multiples of a basis element are called
+++ monomials. A prominent example is the class of polynomials
+++ where the monoid is a direct product of the natural numbers
+++ with pointwise addition. When M is
+++ \spadtype{FreeMonoid Symbol}, one gets polynomials
+++ in infinitely many non-commuting variables. Another application
+++ area is representation theory of finite groups G, where modules
+++ over \spadtype{MonoidRing}(R,G) are studied.
+
+MonoidRing(R: Ring, M: Monoid): MRcategory == MRdefinition where
+ Term ==> Record(coef: R, monom: M)
+
+ MRcategory ==> Join(Ring, RetractableTo M, RetractableTo R) with
+ monomial : (R, M) -> %
+ ++ monomial(r,m) creates a scalar multiple of the basis element m.
+ coefficient : (%, M) -> R
+ ++ coefficient(f,m) extracts the coefficient of m in f with respect
+ ++ to the canonical basis M.
+ coerce: List Term -> %
+ ++ coerce(lt) converts a list of terms and coefficients to a member of the domain.
+ terms : % -> List Term
+ ++ terms(f) gives the list of non-zero coefficients combined
+ ++ with their corresponding basis element as records.
+ ++ This is the internal representation.
+ map : (R -> R, %) -> %
+ ++ map(fn,u) maps function fn onto the coefficients
+ ++ of the non-zero monomials of u.
+ monomial? : % -> Boolean
+ ++ monomial?(f) tests if f is a single monomial.
+ coefficients: % -> List R
+ ++ coefficients(f) lists all non-zero coefficients.
+ monomials: % -> List %
+ ++ monomials(f) gives the list of all monomials whose
+ ++ sum is f.
+ numberOfMonomials: % -> NonNegativeInteger
+ ++ numberOfMonomials(f) is the number of non-zero coefficients
+ ++ with respect to the canonical basis.
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has CommutativeRing then Algebra(R)
+ if (R has Finite and M has Finite) then Finite
+ if M has OrderedSet then
+ leadingMonomial : % -> M
+ ++ leadingMonomial(f) gives the monomial of f whose
+ ++ corresponding monoid element is the greatest
+ ++ among all those with non-zero coefficients.
+ leadingCoefficient: % -> R
+ ++ leadingCoefficient(f) gives the coefficient of f, whose
+ ++ corresponding monoid element is the greatest
+ ++ among all those with non-zero coefficients.
+ reductum : % -> %
+ ++ reductum(f) is f minus its leading monomial.
+
+ MRdefinition ==> add
+ Ex ==> OutputForm
+ Cf ==> coef
+ Mn ==> monom
+
+ Rep := List Term
+
+ coerce(x: List Term): % == x :: %
+
+ monomial(r:R, m:M) ==
+ r = 0 => empty()
+ [[r, m]]
+
+ if (R has Finite and M has Finite) then
+ size() == size()$R ** size()$M
+
+ index k ==
+ -- use p-adic decomposition of k
+ -- coefficient of p**j determines coefficient of index(i+p)$M
+ i:Integer := k rem size()
+ p:Integer := size()$R
+ n:Integer := size()$M
+ ans:% := 0
+ for j in 0.. while i > 0 repeat
+ h := i rem p
+ -- we use index(p) = 0$R
+ if h ^= 0 then
+ c : R := index(h :: PositiveInteger)$R
+ m : M := index((j+n) :: PositiveInteger)$M
+ --ans := ans + c *$% m
+ ans := ans + monomial(c, m)$%
+ i := i quo p
+ ans
+
+ lookup(z : %) : PositiveInteger ==
+ -- could be improved, if M has OrderedSet
+ -- z = index lookup z, n = lookup index n
+ -- use p-adic decomposition of k
+ -- coefficient of p**j determines coefficient of index(i+p)$M
+ zero?(z) => size()$% pretend PositiveInteger
+ liTe : List Term := terms z -- all non-zero coefficients
+ p : Integer := size()$R
+ n : Integer := size()$M
+ res : Integer := 0
+ for te in liTe repeat
+ -- assume that lookup(p)$R = 0
+ l:NonNegativeInteger:=lookup(te.Mn)$M
+ ex : NonNegativeInteger := (n=l => 0;l)
+ co : Integer := lookup(te.Cf)$R
+ res := res + co * p ** ex
+ res pretend PositiveInteger
+
+ random() == index( (1+(random()$Integer rem size()$%) )_
+ pretend PositiveInteger)$%
+
+ 0 == empty()
+ 1 == [[1, 1]]
+ terms a == (copy a) pretend List(Term)
+ monomials a == [[t] for t in a]
+ coefficients a == [t.Cf for t in a]
+ coerce(m:M):% == [[1, m]]
+ coerce(r:R): % ==
+ -- coerce of ring
+ r = 0 => 0
+ [[r, 1]]
+ coerce(n:Integer): % ==
+ -- coerce of integers
+ n = 0 => 0
+ [[n::R, 1]]
+ - a == [[ -t.Cf, t.Mn] for t in a]
+ if R has noZeroDivisors
+ then
+ (r:R) * (a:%) ==
+ r = 0 => 0
+ [[r*t.Cf, t.Mn] for t in a]
+ else
+ (r:R) * (a:%) ==
+ r = 0 => 0
+ [[rt, t.Mn] for t in a | (rt:=r*t.Cf) ^= 0]
+ if R has noZeroDivisors
+ then
+ (n:Integer) * (a:%) ==
+ n = 0 => 0
+ [[n*t.Cf, t.Mn] for t in a]
+ else
+ (n:Integer) * (a:%) ==
+ n = 0 => 0
+ [[nt, t.Mn] for t in a | (nt:=n*t.Cf) ^= 0]
+ map(f, a) == [[ft, t.Mn] for t in a | (ft:=f(t.Cf)) ^= 0]
+ numberOfMonomials a == #a
+
+ retractIfCan(a:%):Union(M, "failed") ==
+-- one?(#a) and one?(a.first.Cf) => a.first.Mn
+ ((#a) = 1) and ((a.first.Cf) = 1) => a.first.Mn
+ "failed"
+
+ retractIfCan(a:%):Union(R, "failed") ==
+-- one?(#a) and one?(a.first.Mn) => a.first.Cf
+ ((#a) = 1) and ((a.first.Mn) = 1) => a.first.Cf
+ "failed"
+
+ if R has noZeroDivisors then
+ if M has Group then
+ recip a ==
+ lt := terms a
+ #lt ^= 1 => "failed"
+ (u := recip lt.first.Cf) case "failed" => "failed"
+ --(u::R) * inv lt.first.Mn
+ monomial((u::R), inv lt.first.Mn)$%
+ else
+ recip a ==
+ #a ^= 1 or a.first.Mn ^= 1 => "failed"
+ (u := recip a.first.Cf) case "failed" => "failed"
+ u::R::%
+
+ mkTerm(r:R, m:M):Ex ==
+ r=1 => m::Ex
+ r=0 or m=1 => r::Ex
+ r::Ex * m::Ex
+
+ coerce(a:%):Ex ==
+ empty? a => (0$Integer)::Ex
+ empty? rest a => mkTerm(a.first.Cf, a.first.Mn)
+ reduce(_+, [mkTerm(t.Cf, t.Mn) for t in a])$List(Ex)
+
+ if M has OrderedSet then -- we mean totally ordered
+ -- Terms are stored in decending order.
+ leadingCoefficient a == (empty? a => 0; a.first.Cf)
+ leadingMonomial a == (empty? a => 1; a.first.Mn)
+ reductum a == (empty? a => a; rest a)
+
+ a = b ==
+ #a ^= #b => false
+ for ta in a for tb in b repeat
+ ta.Cf ^= tb.Cf or ta.Mn ^= tb.Mn => return false
+ true
+
+ a + b ==
+ c:% := empty()
+ while not empty? a and not empty? b repeat
+ ta := first a; tb := first b
+ ra := rest a; rb := rest b
+ c :=
+ ta.Mn > tb.Mn => (a := ra; concat_!(c, ta))
+ ta.Mn < tb.Mn => (b := rb; concat_!(c, tb))
+ a := ra; b := rb
+ not zero?(r := ta.Cf+tb.Cf) =>
+ concat_!(c, [r, ta.Mn])
+ c
+ concat_!(c, concat(a, b))
+
+ coefficient(a, m) ==
+ for t in a repeat
+ if t.Mn = m then return t.Cf
+ if t.Mn < m then return 0
+ 0
+
+
+ if M has OrderedMonoid then
+
+ -- we use that multiplying an ordered list of monoid elements
+ -- by a single element respects the ordering
+
+ if R has noZeroDivisors then
+ a:% * b:% ==
+ +/[[[ta.Cf*tb.Cf, ta.Mn*tb.Mn]$Term
+ for tb in b ] for ta in reverse a]
+ else
+ a:% * b:% ==
+ +/[[[r, ta.Mn*tb.Mn]$Term
+ for tb in b | not zero?(r := ta.Cf*tb.Cf)]
+ for ta in reverse a]
+ else -- M hasn't OrderedMonoid
+
+ -- we cannot assume that mutiplying an ordered list of
+ -- monoid elements by a single element respects the ordering:
+ -- we have to order and to collect equal terms
+ ge : (Term,Term) -> Boolean
+ ge(s,t) == t.Mn <= s.Mn
+
+ sortAndAdd : List Term -> List Term
+ sortAndAdd(liTe) == -- assume liTe not empty
+ liTe := sort(ge,liTe)
+ m : M := (first liTe).Mn
+ cf : R := (first liTe).Cf
+ res : List Term := []
+ for te in rest liTe repeat
+ if m = te.Mn then
+ cf := cf + te.Cf
+ else
+ if not zero? cf then res := cons([cf,m]$Term, res)
+ m := te.Mn
+ cf := te.Cf
+ if not zero? cf then res := cons([cf,m]$Term, res)
+ reverse res
+
+
+ if R has noZeroDivisors then
+ a:% * b:% ==
+ zero? a => a
+ zero? b => b -- avoid calling sortAndAdd with []
+ +/[sortAndAdd [[ta.Cf*tb.Cf, ta.Mn*tb.Mn]$Term
+ for tb in b ] for ta in reverse a]
+ else
+ a:% * b:% ==
+ zero? a => a
+ zero? b => b -- avoid calling sortAndAdd with []
+ +/[sortAndAdd [[r, ta.Mn*tb.Mn]$Term
+ for tb in b | not zero?(r := ta.Cf*tb.Cf)]
+ for ta in reverse a]
+
+
+ else -- M hasn't OrderedSet
+ -- Terms are stored in random order.
+ a = b ==
+ #a ^= #b => false
+ brace(a pretend List(Term)) =$Set(Term) brace(b pretend List(Term))
+
+ coefficient(a, m) ==
+ for t in a repeat
+ t.Mn = m => return t.Cf
+ 0
+
+ addterm(Tabl: AssociationList(M,R), r:R, m:M):R ==
+ (u := search(m, Tabl)) case "failed" => Tabl.m := r
+ zero?(r := r + u::R) => (remove_!(m, Tabl); 0)
+ Tabl.m := r
+
+ a + b ==
+ Tabl := table()$AssociationList(M,R)
+ for t in a repeat
+ Tabl t.Mn := t.Cf
+ for t in b repeat
+ addterm(Tabl, t.Cf, t.Mn)
+ [[Tabl m, m]$Term for m in keys Tabl]
+
+ a:% * b:% ==
+ Tabl := table()$AssociationList(M,R)
+ for ta in a repeat
+ for tb in (b pretend List(Term)) repeat
+ addterm(Tabl, ta.Cf*tb.Cf, ta.Mn*tb.Mn)
+ [[Tabl.m, m]$Term for m in keys Tabl]
+
+@
+\section{package MRF2 MonoidRingFunctions2}
+<<package MRF2 MonoidRingFunctions2>>=
+)abbrev package MRF2 MonoidRingFunctions2
+++ Author: Johannes Grabmeier
+++ Date Created: 14 May 1991
+++ Date Last Updated: 14 May 1991
+++ Basic Operations: map
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: monoid ring, group ring, change of coefficient domain
+++ References:
+++ Description:
+++ MonoidRingFunctions2 implements functions between
+++ two monoid rings defined with the same monoid over different rings.
+MonoidRingFunctions2(R,S,M) : Exports == Implementation where
+ R : Ring
+ S : Ring
+ M : Monoid
+ Exports ==> with
+ map: (R -> S, MonoidRing(R,M)) -> MonoidRing(S,M)
+ ++ map(f,u) maps f onto the coefficients f the element
+ ++ u of the monoid ring to create an element of a monoid
+ ++ ring with the same monoid b.
+ Implementation ==> add
+ map(fn, u) ==
+ res : MonoidRing(S,M) := 0
+ for te in terms u repeat
+ res := res + monomial(fn(te.coef), te.monom)
+ res
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MRING MonoidRing>>
+<<package MRF2 MonoidRingFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mset.spad.pamphlet b/src/algebra/mset.spad.pamphlet
new file mode 100644
index 00000000..abe5d56d
--- /dev/null
+++ b/src/algebra/mset.spad.pamphlet
@@ -0,0 +1,339 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mset.spad}
+\author{Stephen M. Watt, William H. Burge, Richard D. Jenks, Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MSET Multiset}
+<<domain MSET Multiset>>=
+)abbrev domain MSET Multiset
+++ Author:Stephen M. Watt, William H. Burge, Richard D. Jenks, Frederic Lehobey
+++ Date Created:NK
+++ Date Last Updated: 14 June 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A multiset is a set with multiplicities.
+Multiset(S: SetCategory): MultisetAggregate S with
+ finiteAggregate
+ shallowlyMutable
+ multiset: () -> %
+ ++ multiset()$D creates an empty multiset of domain D.
+ multiset: S -> %
+ ++ multiset(s) creates a multiset with singleton s.
+ multiset: List S -> %
+ ++ multiset(ls) creates a multiset with elements from \spad{ls}.
+ members: % -> List S
+ ++ members(ms) returns a list of the elements of \spad{ms}
+ ++ {\em without} their multiplicity. See also \spadfun{parts}.
+ remove: (S,%,Integer) -> %
+ ++ remove(x,ms,number) removes at most \spad{number} copies of
+ ++ element x if \spad{number} is positive, all of them if
+ ++ \spad{number} equals zero, and all but at most \spad{-number} if
+ ++ \spad{number} is negative.
+ remove: ( S -> Boolean ,%,Integer) -> %
+ ++ remove(p,ms,number) removes at most \spad{number} copies of
+ ++ elements x such that \spad{p(x)} is \spadfun{true}
+ ++ if \spad{number} is positive, all of them if
+ ++ \spad{number} equals zero, and all but at most \spad{-number} if
+ ++ \spad{number} is negative.
+ remove_!: (S,%,Integer) -> %
+ ++ remove!(x,ms,number) removes destructively at most \spad{number}
+ ++ copies of element x if \spad{number} is positive, all
+ ++ of them if \spad{number} equals zero, and all but at most
+ ++ \spad{-number} if \spad{number} is negative.
+ remove_!: ( S -> Boolean ,%,Integer) -> %
+ ++ remove!(p,ms,number) removes destructively at most \spad{number}
+ ++ copies of elements x such that \spad{p(x)} is
+ ++ \spadfun{true} if \spad{number} is positive, all of them if
+ ++ \spad{number} equals zero, and all but at most \spad{-number} if
+ ++ \spad{number} is negative.
+
+ == add
+
+ Tbl ==> Table(S, Integer)
+ tbl ==> table$Tbl
+ Rep := Record(count: Integer, table: Tbl)
+
+ n: Integer
+ ms, m1, m2: %
+ t, t1, t2: Tbl
+ D ==> Record(entry: S, count: NonNegativeInteger)
+ K ==> Record(key: S, entry: Integer)
+
+ elt(t:Tbl, s:S):Integer ==
+ a := search(s,t)$Tbl
+ a case "failed" => 0
+ a::Integer
+
+ empty():% == [0,tbl()]
+ multiset():% == empty()
+ dictionary():% == empty() -- DictionaryOperations
+ set():% == empty()
+ brace():% == empty()
+
+ construct(l:List S):% ==
+ t := tbl()
+ n := 0
+ for e in l repeat
+ t.e := inc t.e
+ n := inc n
+ [n, t]
+ multiset(l:List S):% == construct l
+ bag(l:List S):% == construct l -- BagAggregate
+ dictionary(l:List S):% == construct l -- DictionaryOperations
+ set(l:List S):% == construct l
+ brace(l:List S):% == construct l
+
+ multiset(s:S):% == construct [s]
+
+ if S has ConvertibleTo InputForm then
+ convert(ms:%):InputForm ==
+ convert [convert("multiset"::Symbol)@InputForm,
+ convert(parts ms)@InputForm]
+
+ members(ms:%):List S == keys ms.table
+
+ coerce(ms:%):OutputForm ==
+ l: List OutputForm := empty()
+ t := ms.table
+ colon := ": " :: OutputForm
+ for e in keys t repeat
+ ex := e::OutputForm
+ n := t.e
+ item :=
+ n > 1 => hconcat [n :: OutputForm,colon, ex]
+ ex
+ l := cons(item,l)
+ brace l
+
+ duplicates(ms:%):List D == -- MultiDictionary
+ ld : List D := empty()
+ t := ms.table
+ for e in keys t | (n := t.e) > 1 repeat
+ ld := cons([e,n::NonNegativeInteger],ld)
+ ld
+
+ extract_!(ms:%):S == -- BagAggregate
+ empty? ms => error "extract: Empty multiset"
+ ms.count := dec ms.count
+ t := ms.table
+ e := inspect(t).key
+ if (n := t.e) > 1 then t.e := dec n
+ else remove_!(e,t)
+ e
+
+ inspect(ms:%):S == inspect(ms.table).key -- BagAggregate
+
+ insert_!(e:S,ms:%):% == -- BagAggregate
+ ms.count := inc ms.count
+ ms.table.e := inc ms.table.e
+ ms
+
+ member?(e:S,ms:%):Boolean == member?(e,keys ms.table)
+
+ empty?(ms:%):Boolean == ms.count = 0
+
+ #(ms:%):NonNegativeInteger == ms.count::NonNegativeInteger
+
+ count(e:S, ms:%):NonNegativeInteger == ms.table.e::NonNegativeInteger
+
+ remove_!(e:S, ms:%, max:Integer):% ==
+ zero? max => remove_!(e,ms)
+ t := ms.table
+ if member?(e, keys t) then
+ ((n := t.e) <= max) =>
+ remove_!(e,t)
+ ms.count := ms.count-n
+ max > 0 =>
+ t.e := n-max
+ ms.count := ms.count-max
+ (n := n+max) > 0 =>
+ t.e := -max
+ ms.count := ms.count-n
+ ms
+
+ remove_!(p: S -> Boolean, ms:%, max:Integer):% ==
+ zero? max => remove_!(p,ms)
+ t := ms.table
+ for e in keys t | p(e) repeat
+ ((n := t.e) <= max) =>
+ remove_!(e,t)
+ ms.count := ms.count-n
+ max > 0 =>
+ t.e := n-max
+ ms.count := ms.count-max
+ (n := n+max) > 0 =>
+ t.e := -max
+ ms.count := ms.count-n
+ ms
+
+ remove(e:S, ms:%, max:Integer):% == remove_!(e, copy ms, max)
+
+ remove(p: S -> Boolean,ms:%,max:Integer):% == remove_!(p, copy ms, max)
+
+ remove_!(e:S, ms:%):% == -- DictionaryOperations
+ t := ms.table
+ if member?(e, keys t) then
+ ms.count := ms.count-t.e
+ remove_!(e, t)
+ ms
+
+ remove_!(p:S ->Boolean, ms:%):% == -- DictionaryOperations
+ t := ms.table
+ for e in keys t | p(e) repeat
+ ms.count := ms.count-t.e
+ remove_!(e, t)
+ ms
+
+ select_!(p: S -> Boolean, ms:%):% == -- DictionaryOperations
+ remove_!(not p(#1), ms)
+
+ removeDuplicates_!(ms:%):% == -- MultiDictionary
+ t := ms.table
+ l := keys t
+ for e in l repeat t.e := 1
+ ms.count := #l
+ ms
+
+ insert_!(e:S,ms:%,more:NonNegativeInteger):% == -- MultiDictionary
+ ms.count := ms.count+more
+ ms.table.e := ms.table.e+more
+ ms
+
+ map_!(f: S->S, ms:%):% == -- HomogeneousAggregate
+ t := ms.table
+ t1 := tbl()
+ for e in keys t repeat
+ t1.f(e) := t.e
+ remove_!(e, t)
+ ms.table := t1
+ ms
+
+ map(f: S -> S, ms:%):% == map_!(f, copy ms) -- HomogeneousAggregate
+
+ parts(m:%):List S ==
+ l := empty()$List(S)
+ t := m.table
+ for e in keys t repeat
+ for i in 1..t.e repeat
+ l := cons(e,l)
+ l
+
+ union(m1:%, m2:%):% ==
+ t := tbl()
+ t1:= m1.table
+ t2:= m2.table
+ for e in keys t1 repeat t.e := t1.e
+ for e in keys t2 repeat t.e := t2.e + t.e
+ [m1.count + m2.count, t]
+
+ intersect(m1:%, m2:%):% ==
+-- if #m1 > #m2 then intersect(m2, m1)
+ t := tbl()
+ t1:= m1.table
+ t2:= m2.table
+ n := 0
+ for e in keys t1 repeat
+ m := min(t1.e,t2.e)
+ m > 0 =>
+ m := t1.e + t2.e
+ t.e := m
+ n := n + m
+ [n, t]
+
+ difference(m1:%, m2:%):% ==
+ t := tbl()
+ t1:= m1.table
+ t2:= m2.table
+ n := 0
+ for e in keys t1 repeat
+ k1 := t1.e
+ k2 := t2.e
+ k1 > 0 and k2 = 0 =>
+ t.e := k1
+ n := n + k1
+ n = 0 => empty()
+ [n, t]
+
+ symmetricDifference(m1:%, m2:%):% ==
+ union(difference(m1,m2), difference(m2,m1))
+
+ m1 = m2 ==
+ m1.count ^= m2.count => false
+ t1 := m1.table
+ t2 := m2.table
+ for e in keys t1 repeat
+ t1.e ^= t2.e => return false
+ for e in keys t2 repeat
+ t1.e ^= t2.e => return false
+ true
+
+ m1 < m2 ==
+ m1.count >= m2.count => false
+ t1 := m1.table
+ t2 := m2.table
+ for e in keys t1 repeat
+ t1.e > t2.e => return false
+ m1.count < m2.count
+
+ subset?(m1:%, m2:%):Boolean ==
+ m1.count > m2.count => false
+ t1 := m1.table
+ t2 := m2.table
+ for e in keys t1 repeat t1.e > t2.e => return false
+ true
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MSET Multiset>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/mts.spad.pamphlet b/src/algebra/mts.spad.pamphlet
new file mode 100644
index 00000000..a7335877
--- /dev/null
+++ b/src/algebra/mts.spad.pamphlet
@@ -0,0 +1,367 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra mts.spad}
+\author{William Burge, Stephen Watt, Clifton Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SMTS SparseMultivariateTaylorSeries}
+<<domain SMTS SparseMultivariateTaylorSeries>>=
+)abbrev domain SMTS SparseMultivariateTaylorSeries
+++ This domain provides multivariate Taylor series
+++ Authors: William Burge, Stephen Watt, Clifton Williamson
+++ Date Created: 15 August 1988
+++ Date Last Updated: 18 May 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See: UnivariateTaylorSeries
+++ AMS Classifications:
+++ Keywords: multivariate, Taylor, series
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides multivariate Taylor series with variables
+++ from an arbitrary ordered set. A Taylor series is represented
+++ by a stream of polynomials from the polynomial domain SMP.
+++ The nth element of the stream is a form of degree n. SMTS is an
+++ internal domain.
+SparseMultivariateTaylorSeries(Coef,Var,SMP):_
+ Exports == Implementation where
+ Coef : Ring
+ Var : OrderedSet
+ SMP : PolynomialCategory(Coef,IndexedExponents Var,Var)
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ PS ==> InnerTaylorSeries SMP
+ RN ==> Fraction Integer
+ ST ==> Stream
+ StS ==> Stream SMP
+ STT ==> StreamTaylorSeriesOperations SMP
+ STF ==> StreamTranscendentalFunctions SMP
+ ST2 ==> StreamFunctions2
+ ST3 ==> StreamFunctions3
+
+ Exports ==> MultivariateTaylorSeriesCategory(Coef,Var) with
+ coefficient: (%,NNI) -> SMP
+ ++ \spad{coefficient(s, n)} gives the terms of total degree n.
+ coerce: Var -> %
+ ++ \spad{coerce(var)} converts a variable to a Taylor series
+ coerce: SMP -> %
+ ++ \spad{coerce(poly)} regroups the terms by total degree and forms
+ ++ a series.
+ "*":(SMP,%)->%
+ ++\spad{smp*ts} multiplies a TaylorSeries by a monomial SMP.
+ csubst:(L Var,L StS) -> (SMP -> StS)
+ ++\spad{csubst(a,b)} is for internal use only
+
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Var,Coef) -> %
+ ++\spad{integrate(s,v,c)} is the integral of s with respect
+ ++ to v and having c as the constant of integration.
+ fintegrate: (() -> %,Var,Coef) -> %
+ ++\spad{fintegrate(f,v,c)} is the integral of \spad{f()} with respect
+ ++ to v and having c as the constant of integration.
+ ++ The evaluation of \spad{f()} is delayed.
+
+ Implementation ==> PS add
+
+ Rep := StS -- Below we use the fact that Rep of PS is Stream SMP.
+ extend(x,n) == extend(x,n + 1)$Rep
+ complete x == complete(x)$Rep
+
+ evalstream:(%,L Var,L SMP) -> StS
+ evalstream(s:%,lv:(L Var),lsmp:(L SMP)):(ST SMP) ==
+ scan(0,_+$SMP,map(eval(#1,lv,lsmp),s pretend StS))$ST2(SMP,SMP)
+
+ addvariable:(Var,InnerTaylorSeries Coef) -> %
+ addvariable(v,s) ==
+ ints := integers(0)$STT pretend ST NNI
+ map(monomial(#2 :: SMP,v,#1)$SMP,ints,s pretend ST Coef)$ST3(NNI,Coef,SMP)
+
+ coefficient(s,n) == elt(s,n + 1)$Rep -- 1-based indexing for streams
+
+--% creation of series
+
+ coerce(r:Coef) == monom(r::SMP,0)$STT
+ smp:SMP * p:% == (((smp) * (p pretend Rep))$STT)pretend %
+ r:Coef * p:% == (((r::SMP) * (p pretend Rep))$STT)pretend %
+ p:% * r:Coef == (((r::SMP) * ( p pretend Rep))$STT)pretend %
+ mts(p:SMP):% ==
+ (uv := mainVariable p) case "failed" => monom(p,0)$STT
+ v := uv :: Var
+ s : % := 0
+ up := univariate(p,v)
+ while not zero? up repeat
+ s := s + monomial(1,v,degree up) * mts(leadingCoefficient up)
+ up := reductum up
+ s
+
+ coerce(p:SMP) == mts p
+ coerce(v:Var) == v :: SMP :: %
+
+ monomial(r:%,v:Var,n:NNI) ==
+ r * monom(monomial(1,v,n)$SMP,n)$STT
+
+--% evaluation
+
+ substvar: (SMP,L Var,L %) -> %
+ substvar(p,vl,q) ==
+ null vl => monom(p,0)$STT
+ (uv := mainVariable p) case "failed" => monom(p,0)$STT
+ v := uv :: Var
+ v = first vl =>
+ s : % := 0
+ up := univariate(p,v)
+ while not zero? up repeat
+ c := leadingCoefficient up
+ s := s + first q ** degree up * substvar(c,rest vl,rest q)
+ up := reductum up
+ s
+ substvar(p,rest vl,rest q)
+
+ sortmfirst:(SMP,L Var,L %) -> %
+ sortmfirst(p,vl,q) ==
+ nlv : L Var := sort(#1 > #2,vl)
+ nq : L % := [q position$(L Var) (i,vl) for i in nlv]
+ substvar(p,nlv,nq)
+
+ csubst(vl,q) == sortmfirst(#1,vl,q pretend L(%)) pretend StS
+
+ restCheck(s:StS):StS ==
+ -- checks that stream is null or first element is 0
+ -- returns empty() or rest of stream
+ empty? s => s
+ not zero? frst s =>
+ error "eval: constant coefficient should be 0"
+ rst s
+
+ eval(s:%,v:L Var,q:L %) ==
+ #v ^= #q =>
+ error "eval: number of variables should equal number of values"
+ nq : L StS := [restCheck(i pretend StS) for i in q]
+ addiag(map(csubst(v,nq),s pretend StS)$ST2(SMP,StS))$STT pretend %
+
+ substmts(v:Var,p:SMP,q:%):% ==
+ up := univariate(p,v)
+ ss : % := 0
+ while not zero? up repeat
+ d:=degree up
+ c:SMP:=leadingCoefficient up
+ ss := ss + c* q ** d
+ up := reductum up
+ ss
+
+ subststream(v:Var,p:SMP,q:StS):StS==
+ substmts(v,p,q pretend %) pretend StS
+
+ comp1:(Var,StS,StS) -> StS
+ comp1(v,r,t)== addiag(map(subststream(v,#1,t),r)$ST2(SMP,StS))$STT
+
+ comp(v:Var,s:StS,t:StS):StS == delay
+ empty? s => s
+ f := frst s; r : StS := rst s;
+ empty? r => s
+ empty? t => concat(f,comp1(v,r,empty()$StS))
+ not zero? frst t =>
+ error "eval: constant coefficient should be zero"
+ concat(f,comp1(v,r,rst t))
+
+ eval(s:%,v:Var,t:%) == comp(v,s pretend StS,t pretend StS)
+
+--% differentiation and integration
+
+ differentiate(s:%,v:Var):% ==
+ empty? s => 0
+ map(differentiate(#1,v),rst s)
+
+ if Coef has Algebra Fraction Integer then
+
+ stream(x:%):Rep == x pretend Rep
+
+ (x:%) ** (r:RN) == powern(r,stream x)$STT
+ (r:RN) * (x:%) == map(r * #1, stream x)$ST2(SMP,SMP) pretend %
+ (x:%) * (r:RN) == map(#1 * r,stream x )$ST2(SMP,SMP) pretend %
+
+ exp x == exp(stream x)$STF
+ log x == log(stream x)$STF
+
+ sin x == sin(stream x)$STF
+ cos x == cos(stream x)$STF
+ tan x == tan(stream x)$STF
+ cot x == cot(stream x)$STF
+ sec x == sec(stream x)$STF
+ csc x == csc(stream x)$STF
+
+ asin x == asin(stream x)$STF
+ acos x == acos(stream x)$STF
+ atan x == atan(stream x)$STF
+ acot x == acot(stream x)$STF
+ asec x == asec(stream x)$STF
+ acsc x == acsc(stream x)$STF
+
+ sinh x == sinh(stream x)$STF
+ cosh x == cosh(stream x)$STF
+ tanh x == tanh(stream x)$STF
+ coth x == coth(stream x)$STF
+ sech x == sech(stream x)$STF
+ csch x == csch(stream x)$STF
+
+ asinh x == asinh(stream x)$STF
+ acosh x == acosh(stream x)$STF
+ atanh x == atanh(stream x)$STF
+ acoth x == acoth(stream x)$STF
+ asech x == asech(stream x)$STF
+ acsch x == acsch(stream x)$STF
+
+ intsmp(v:Var,p: SMP): SMP ==
+ up := univariate(p,v)
+ ss : SMP := 0
+ while not zero? up repeat
+ d := degree up
+ c := leadingCoefficient up
+ ss := ss + inv((d+1) :: RN) * monomial(c,v,d+1)$SMP
+ up := reductum up
+ ss
+
+ fintegrate(f,v,r) ==
+ concat(r::SMP,delay map(intsmp(v,#1),f() pretend StS))
+ integrate(s,v,r) ==
+ concat(r::SMP,map(intsmp(v,#1),s pretend StS))
+
+ -- If there is more than one term of the same order, group them.
+ tout(p:SMP):OUT ==
+ pe := p :: OUT
+ monomial? p => pe
+ paren pe
+
+ showAll?: () -> Boolean
+ -- check a global Lisp variable
+ showAll?() == true
+
+ coerce(s:%):OUT ==
+ uu := s pretend Stream(SMP)
+ empty? uu => (0$SMP) :: OUT
+ n : NNI; count : NNI := _$streamCount$Lisp
+ l : List OUT := empty()
+ for n in 0..count while not empty? uu repeat
+ if frst(uu) ^= 0 then l := concat(tout frst uu,l)
+ uu := rst uu
+ if showAll?() then
+ for n in n.. while explicitEntries? uu and _
+ not eq?(uu,rst uu) repeat
+ if frst(uu) ^= 0 then l := concat(tout frst uu,l)
+ uu := rst uu
+ l :=
+ explicitlyEmpty? uu => l
+ eq?(uu,rst uu) and frst uu = 0 => l
+ concat(prefix("O" :: OUT,[n :: OUT]),l)
+ empty? l => (0$SMP) :: OUT
+ reduce("+",reverse_! l)
+ if Coef has Field then
+ stream(x:%):Rep == x pretend Rep
+ SF2==> StreamFunctions2
+ p:% / r:Coef ==(map(#1/$SMP r,stream p)$SF2(SMP,SMP))pretend %
+
+@
+\section{domain TS TaylorSeries}
+<<domain TS TaylorSeries>>=
+)abbrev domain TS TaylorSeries
+++ Authors: Burge, Watt, Williamson
+++ Date Created: 15 August 1988
+++ Date Last Updated: 18 May 1991
+++ Basic Operations:
+++ Related Domains: SparseMultivariateTaylorSeries
+++ Also See: UnivariateTaylorSeries
+++ AMS Classifications:
+++ Keywords: multivariate, Taylor, series
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{TaylorSeries} is a general multivariate Taylor series domain
+++ over the ring Coef and with variables of type Symbol.
+TaylorSeries(Coef): Exports == Implementation where
+ Coef : Ring
+ L ==> List
+ NNI ==> NonNegativeInteger
+ SMP ==> Polynomial Coef
+ StS ==> Stream SMP
+
+ Exports ==> MultivariateTaylorSeriesCategory(Coef,Symbol) with
+ coefficient: (%,NNI) -> SMP
+ ++\spad{coefficient(s, n)} gives the terms of total degree n.
+ coerce: Symbol -> %
+ ++\spad{coerce(s)} converts a variable to a Taylor series
+ coerce: SMP -> %
+ ++\spad{coerce(s)} regroups terms of s by total degree
+ ++ and forms a series.
+
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Symbol,Coef) -> %
+ ++\spad{integrate(s,v,c)} is the integral of s with respect
+ ++ to v and having c as the constant of integration.
+ fintegrate: (() -> %,Symbol,Coef) -> %
+ ++\spad{fintegrate(f,v,c)} is the integral of \spad{f()} with respect
+ ++ to v and having c as the constant of integration.
+ ++ The evaluation of \spad{f()} is delayed.
+
+ Implementation ==> SparseMultivariateTaylorSeries(Coef,Symbol,SMP) add
+ Rep := StS -- Below we use the fact that Rep of PS is Stream SMP.
+
+ polynomial(s,n) ==
+ sum : SMP := 0
+ for i in 0..n while not empty? s repeat
+ sum := sum + frst s
+ s:= rst s
+ sum
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SMTS SparseMultivariateTaylorSeries>>
+<<domain TS TaylorSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/multfact.spad.pamphlet b/src/algebra/multfact.spad.pamphlet
new file mode 100644
index 00000000..6efcd462
--- /dev/null
+++ b/src/algebra/multfact.spad.pamphlet
@@ -0,0 +1,604 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra multfact.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INNMFACT InnerMultFact}
+<<package INNMFACT InnerMultFact>>=
+)abbrev package INNMFACT InnerMultFact
+++ Author: P. Gianni
+++ Date Created: 1983
+++ Date Last Updated: Sept. 1990
+++ Additional Comments: JHD Aug 1997
+++ Basic Functions:
+++ Related Constructors: MultivariateFactorize, AlgebraicMultFact
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is an inner package for factoring multivariate polynomials
+++ over various coefficient domains in characteristic 0.
+++ The univariate factor operation is passed as a parameter.
+++ Multivariate hensel lifting is used to lift the univariate
+++ factorization
+
+-- Both exposed functions call mFactor. This deals with issues such as
+-- monomial factors, contents, square-freeness etc., then calls intfact.
+-- This uses intChoose to find a "good" evaluation and factorise the
+-- corresponding univariate, and then uses MultivariateLifting to find
+-- the multivariate factors.
+
+InnerMultFact(OV,E,R,P) : C == T
+ where
+ R : Join(EuclideanDomain, CharacteristicZero)
+ -- with factor on R[x]
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ P : PolynomialCategory(R,E,OV)
+ BP ==> SparseUnivariatePolynomial R
+ UFactor ==> (BP -> Factored BP)
+ Z ==> Integer
+ MParFact ==> Record(irr:P,pow:Z)
+ USP ==> SparseUnivariatePolynomial P
+ SUParFact ==> Record(irr:USP,pow:Z)
+ SUPFinalFact ==> Record(contp:R,factors:List SUParFact)
+ MFinalFact ==> Record(contp:R,factors:List MParFact)
+
+ -- contp = content,
+ -- factors = List of irreducible factors with exponent
+ L ==> List
+
+ C == with
+ factor : (P,UFactor) -> Factored P
+ ++ factor(p,ufact) factors the multivariate polynomial p
+ ++ by specializing variables and calling the univariate
+ ++ factorizer ufact.
+ factor : (USP,UFactor) -> Factored USP
+ ++ factor(p,ufact) factors the multivariate polynomial p
+ ++ by specializing variables and calling the univariate
+ ++ factorizer ufact. p is represented as a univariate
+ ++ polynomial with multivariate coefficients.
+
+ T == add
+
+ NNI ==> NonNegativeInteger
+
+ LeadFact ==> Record(polfac:L P,correct:R,corrfact:L BP)
+ ContPrim ==> Record(cont:P,prim:P)
+ ParFact ==> Record(irr:BP,pow:Z)
+ FinalFact ==> Record(contp:R,factors:L ParFact)
+ NewOrd ==> Record(npol:USP,nvar:L OV,newdeg:L NNI)
+ pmod:R := (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
+
+ import GenExEuclid(R,BP)
+ import MultivariateLifting(E,OV,R,P)
+ import FactoringUtilities(E,OV,R,P)
+ import LeadingCoefDetermination(OV,E,R,P)
+ Valuf ==> Record(inval:L L R,unvfact:L BP,lu:R,complead:L R)
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+ ---- Local Functions ----
+ mFactor : (P,UFactor) -> MFinalFact
+ supFactor : (USP,UFactor) -> SUPFinalFact
+ mfconst : (USP,L OV,L NNI,UFactor) -> L USP
+ mfpol : (USP,L OV,L NNI,UFactor) -> L USP
+ monicMfpol: (USP,L OV,L NNI,UFactor) -> L USP
+ varChoose : (P,L OV,L NNI) -> NewOrd
+ simplify : (P,L OV,L NNI,UFactor) -> MFinalFact
+ intChoose : (USP,L OV,R,L P,L L R,UFactor) -> Union(Valuf,"failed")
+ intfact : (USP,L OV,L NNI,MFinalFact,L L R,UFactor) -> L USP
+ pretest : (P,NNI,L OV,L R) -> FinalFact
+ checkzero : (USP,BP) -> Boolean
+ localNorm : L BP -> Z
+
+ convertPUP(lfg:MFinalFact): SUPFinalFact ==
+ [lfg.contp,[[lff.irr ::USP,lff.pow]$SUParFact
+ for lff in lfg.factors]]$SUPFinalFact
+
+ -- intermediate routine if an SUP was passed in.
+ supFactor(um:USP,ufactor:UFactor) : SUPFinalFact ==
+ ground?(um) => convertPUP(mFactor(ground um,ufactor))
+ lvar:L OV:= "setUnion"/[variables cf for cf in coefficients um]
+ empty? lvar => -- the polynomial is univariate
+ umv:= map(ground,um)$UPCF2(P,USP,R,BP)
+ lfact:=ufactor umv
+ [retract unit lfact,[[map(coerce,ff.factor)$UPCF2(R,BP,P,USP),
+ ff.exponent] for ff in factors lfact]]$SUPFinalFact
+ lcont:P
+ lf:L USP
+ flead : SUPFinalFact:=[0,empty()]$SUPFinalFact
+ factorlist:L SUParFact :=empty()
+
+ mdeg :=minimumDegree um ---- is the Mindeg > 0? ----
+ if mdeg>0 then
+ f1:USP:=monomial(1,mdeg)
+ um:=(um exquo f1)::USP
+ factorlist:=cons([monomial(1,1),mdeg],factorlist)
+ if degree um=0 then return
+ lfg:=convertPUP mFactor(ground um, ufactor)
+ [lfg.contp,append(factorlist,lfg.factors)]
+ uum:=unitNormal um
+ um :=uum.canonical
+ sqfacs := squareFree(um)$MultivariateSquareFree(E,OV,R,P)
+ lcont := ground(uum.unit * unit sqfacs)
+ ---- Factorize the content ----
+ flead:=convertPUP mFactor(lcont,ufactor)
+ factorlist:=append(flead.factors,factorlist)
+ ---- Make the polynomial square-free ----
+ sqqfact:=factors sqfacs
+ --- Factorize the primitive square-free terms ---
+ for fact in sqqfact repeat
+ ffactor:USP:=fact.factor
+ ffexp:=fact.exponent
+ zero? degree ffactor =>
+ lfg:=mFactor(ground ffactor,ufactor)
+ lcont:=lfg.contp * lcont
+ factorlist := append(factorlist,
+ [[lff.irr ::USP,lff.pow * ffexp]$SUParFact
+ for lff in lfg.factors])
+ coefs := coefficients ffactor
+ ldeg:= ["max"/[degree(fc,xx) for fc in coefs] for xx in lvar]
+ lf :=
+ ground?(leadingCoefficient ffactor) =>
+ mfconst(ffactor,lvar,ldeg,ufactor)
+ mfpol(ffactor,lvar,ldeg,ufactor)
+ auxfl:=[[lfp,ffexp]$SUParFact for lfp in lf]
+ factorlist:=append(factorlist,auxfl)
+ lcfacs := */[leadingCoefficient leadingCoefficient(f.irr)**((f.pow)::NNI)
+ for f in factorlist]
+ [(leadingCoefficient leadingCoefficient(um) exquo lcfacs)::R,
+ factorlist]$SUPFinalFact
+
+ factor(um:USP,ufactor:UFactor):Factored USP ==
+ flist := supFactor(um,ufactor)
+ (flist.contp):: P :: USP *
+ (*/[primeFactor(u.irr,u.pow) for u in flist.factors])
+
+ checkzero(u:USP,um:BP) : Boolean ==
+ u=0 => um =0
+ um = 0 => false
+ degree u = degree um => checkzero(reductum u, reductum um)
+ false
+ --- Choose the variable of less degree ---
+ varChoose(m:P,lvar:L OV,ldeg:L NNI) : NewOrd ==
+ k:="min"/[d for d in ldeg]
+ k=degree(m,first lvar) =>
+ [univariate(m,first lvar),lvar,ldeg]$NewOrd
+ i:=position(k,ldeg)
+ x:OV:=lvar.i
+ ldeg:=cons(k,delete(ldeg,i))
+ lvar:=cons(x,delete(lvar,i))
+ [univariate(m,x),lvar,ldeg]$NewOrd
+
+ localNorm(lum: L BP): Z ==
+ R is AlgebraicNumber =>
+ "max"/[numberOfMonomials ff for ff in lum]
+
+ "max"/[+/[euclideanSize cc for i in 0..degree ff|
+ (cc:= coefficient(ff,i))^=0] for ff in lum]
+
+ --- Choose the integer to reduce to univariate case ---
+ intChoose(um:USP,lvar:L OV,clc:R,plist:L P,ltry:L L R,
+ ufactor:UFactor) : Union(Valuf,"failed") ==
+ -- declarations
+ degum:NNI := degree um
+ nvar1:=#lvar
+ range:NNI:=5
+ unifact:L BP
+ ctf1 : R := 1
+ testp:Boolean := -- polynomial leading coefficient
+ empty? plist => false
+ true
+ leadcomp,leadcomp1 : L R
+ leadcomp:=leadcomp1:=empty()
+ nfatt:NNI := degum+1
+ lffc:R:=1
+ lffc1:=lffc
+ newunifact : L BP:=empty()
+ leadtest:=true --- the lc test with polCase has to be performed
+ int:L R:=empty()
+
+ -- New sets of integers are chosen to reduce the multivariate problem to
+ -- a univariate one, until we find twice the
+ -- same (and minimal) number of "univariate" factors:
+ -- the set smaller in modulo is chosen.
+ -- Note that there is no guarantee that this is the truth:
+ -- merely the closest approximation we have found!
+
+ while true repeat
+ testp and #ltry>10 => return "failed"
+ lval := [ ran(range) for i in 1..nvar1]
+ member?(lval,ltry) => range:=2*range
+ ltry := cons(lval,ltry)
+ leadcomp1:=[retract eval(pol,lvar,lval) for pol in plist]
+ testp and or/[unit? epl for epl in leadcomp1] => range:=2*range
+ newm:BP:=completeEval(um,lvar,lval)
+ degum ^= degree newm or minimumDegree newm ^=0 => range:=2*range
+ lffc1:=content newm
+ newm:=(newm exquo lffc1)::BP
+ testp and leadtest and ^ polCase(lffc1*clc,#plist,leadcomp1)
+ => range:=2*range
+ degree(gcd [newm,differentiate(newm)])^=0 => range:=2*range
+ luniv:=ufactor(newm)
+ lunivf:= factors luniv
+ lffc1:R:=retract(unit luniv)@R * lffc1
+ nf:= #lunivf
+
+ nf=0 or nf>nfatt => "next values" --- pretest failed ---
+
+ --- the univariate polynomial is irreducible ---
+ if nf=1 then leave (unifact:=[newm])
+
+ -- the new integer give the same number of factors
+ nfatt = nf =>
+ -- if this is the first univariate factorization with polCase=true
+ -- or if the last factorization has smaller norm and satisfies
+ -- polCase
+ if leadtest or
+ ((localNorm unifact > localNorm [ff.factor for ff in lunivf])
+ and (^testp or polCase(lffc1*clc,#plist,leadcomp1))) then
+ unifact:=[uf.factor for uf in lunivf]
+ int:=lval
+ lffc:=lffc1
+ if testp then leadcomp:=leadcomp1
+ leave "foundit"
+
+ -- the first univariate factorization, inizialize
+ nfatt > degum =>
+ unifact:=[uf.factor for uf in lunivf]
+ lffc:=lffc1
+ if testp then leadcomp:=leadcomp1
+ int:=lval
+ leadtest := false
+ nfatt := nf
+
+ nfatt>nf => -- for the previous values there were more factors
+ if testp then leadtest:=^polCase(lffc*clc,#plist,leadcomp)
+ else leadtest:= false
+ -- if polCase=true we can consider the univariate decomposition
+ if ^leadtest then
+ unifact:=[uf.factor for uf in lunivf]
+ lffc:=lffc1
+ if testp then leadcomp:=leadcomp1
+ int:=lval
+ nfatt := nf
+ [cons(int,ltry),unifact,lffc,leadcomp]$Valuf
+
+
+ ---- The polynomial has mindeg>0 ----
+
+ simplify(m:P,lvar:L OV,lmdeg:L NNI,ufactor:UFactor):MFinalFact ==
+ factorlist:L MParFact:=[]
+ pol1:P:= 1$P
+ for x in lvar repeat
+ i := lmdeg.(position(x,lvar))
+ i=0 => "next value"
+ pol1:=pol1*monomial(1$P,x,i)
+ factorlist:=cons([x::P,i]$MParFact,factorlist)
+ m := (m exquo pol1)::P
+ ground? m => [retract m,factorlist]$MFinalFact
+ flead:=mFactor(m,ufactor)
+ flead.factors:=append(factorlist,flead.factors)
+ flead
+
+ -- This is the key internal function
+ -- We now know that the polynomial is square-free etc.,
+ -- We use intChoose to find a set of integer values to reduce the
+ -- problem to univariate (and for efficiency, intChoose returns
+ -- the univariate factors).
+ -- In the case of a polynomial leading coefficient, we check that this
+ -- is consistent with leading coefficient determination (else try again)
+ -- We then lift the univariate factors to multivariate factors, and
+ -- return the result
+ intfact(um:USP,lvar: L OV,ldeg:L NNI,tleadpol:MFinalFact,
+ ltry:L L R,ufactor:UFactor) : L USP ==
+ polcase:Boolean:=(not empty? tleadpol.factors)
+ vfchoo:Valuf:=
+ polcase =>
+ leadpol:L P:=[ff.irr for ff in tleadpol.factors]
+ check:=intChoose(um,lvar,tleadpol.contp,leadpol,ltry,ufactor)
+ check case "failed" => return monicMfpol(um,lvar,ldeg,ufactor)
+ check::Valuf
+ intChoose(um,lvar,1,empty(),empty(),ufactor)::Valuf
+ unifact:List BP := vfchoo.unvfact
+ nfact:NNI := #unifact
+ nfact=1 => [um]
+ ltry:L L R:= vfchoo.inval
+ lval:L R:=first ltry
+ dd:= vfchoo.lu
+ leadval:L R:=empty()
+ lpol:List P:=empty()
+ if polcase then
+ leadval := vfchoo.complead
+ distf := distFact(vfchoo.lu,unifact,tleadpol,leadval,lvar,lval)
+ distf case "failed" =>
+ return intfact(um,lvar,ldeg,tleadpol,ltry,ufactor)
+ dist := distf :: LeadFact
+ -- check the factorization of leading coefficient
+ lpol:= dist.polfac
+ dd := dist.correct
+ unifact:=dist.corrfact
+ if dd^=1 then
+-- if polcase then lpol := [unitCanonical lp for lp in lpol]
+-- dd:=unitCanonical(dd)
+ unifact := [dd * unif for unif in unifact]
+ umd := unitNormal(dd).unit * ((dd**(nfact-1)::NNI)::P)*um
+ else umd := um
+ (ffin:=lifting(umd,lvar,unifact,lval,lpol,ldeg,pmod))
+ case "failed" => intfact(um,lvar,ldeg,tleadpol,ltry,ufactor)
+ factfin: L USP:=ffin :: L USP
+ if dd^=1 then
+ factfin:=[primitivePart ff for ff in factfin]
+ factfin
+
+ ---- m square-free,primitive,lc constant ----
+ mfconst(um:USP,lvar:L OV,ldeg:L NNI,ufactor:UFactor):L USP ==
+ factfin:L USP:=empty()
+ empty? lvar =>
+ lum:=factors ufactor(map(ground,um)$UPCF2(P,USP,R,BP))
+ [map(coerce,uf.factor)$UPCF2(R,BP,P,USP) for uf in lum]
+ intfact(um,lvar,ldeg,[0,empty()]$MFinalFact,empty(),ufactor)
+
+ monicize(um:USP,c:P):USP ==
+ n:=degree(um)
+ ans:USP := monomial(1,n)
+ n:=(n-1)::NonNegativeInteger
+ prod:P:=1
+ while (um:=reductum(um)) ^= 0 repeat
+ i := degree um
+ lc := leadingCoefficient um
+ prod := prod * c ** (n-(n:=i))::NonNegativeInteger
+ ans := ans + monomial(prod*lc, i)
+ ans
+
+ unmonicize(m:USP,c:P):USP == primitivePart m(monomial(c,1))
+
+ --- m is square-free,primitive,lc is a polynomial ---
+ monicMfpol(um:USP,lvar:L OV,ldeg:L NNI,ufactor:UFactor):L USP ==
+ l := leadingCoefficient um
+ monpol := monicize(um,l)
+ nldeg := degree(monpol,lvar)
+ map(unmonicize(#1,l),
+ mfconst(monpol,lvar,nldeg,ufactor))
+
+ mfpol(um:USP,lvar:L OV,ldeg:L NNI,ufactor:UFactor):L USP ==
+ R has Field =>
+ monicMfpol(um,lvar,ldeg,ufactor)
+ tleadpol:=mFactor(leadingCoefficient um,ufactor)
+ intfact(um,lvar,ldeg,tleadpol,[],ufactor)
+
+ mFactor(m:P,ufactor:UFactor) : MFinalFact ==
+ ground?(m) => [retract(m),empty()]$MFinalFact
+ lvar:L OV:= variables m
+ lcont:P
+ lf:L USP
+ flead : MFinalFact:=[0,empty()]$MFinalFact
+ factorlist:L MParFact :=empty()
+
+ lmdeg :=minimumDegree(m,lvar) ---- is the Mindeg > 0? ----
+ or/[n>0 for n in lmdeg] => simplify(m,lvar,lmdeg,ufactor)
+
+ sqfacs := squareFree m
+ lcont := unit sqfacs
+
+ ---- Factorize the content ----
+ if ground? lcont then flead.contp:=retract lcont
+ else flead:=mFactor(lcont,ufactor)
+ factorlist:=flead.factors
+
+
+
+ ---- Make the polynomial square-free ----
+ sqqfact:=factors sqfacs
+
+ --- Factorize the primitive square-free terms ---
+ for fact in sqqfact repeat
+ ffactor:P:=fact.factor
+ ffexp := fact.exponent
+ lvar := variables ffactor
+ x:OV :=lvar.first
+ ldeg:=degree(ffactor,lvar)
+ --- Is the polynomial linear in one of the variables ? ---
+ member?(1,ldeg) =>
+ x:OV:=lvar.position(1,ldeg)
+ lcont:= gcd coefficients(univariate(ffactor,x))
+ ffactor:=(ffactor exquo lcont)::P
+ factorlist:=cons([ffactor,ffexp]$MParFact,factorlist)
+ for lcterm in mFactor(lcont,ufactor).factors repeat
+ factorlist:=cons([lcterm.irr,lcterm.pow * ffexp], factorlist)
+
+ varch:=varChoose(ffactor,lvar,ldeg)
+ um:=varch.npol
+
+ x:=lvar.first
+ ldeg:=ldeg.rest
+ lvar := lvar.rest
+ if varch.nvar.first ^= x then
+ lvar:= varch.nvar
+ x := lvar.first
+ lvar := lvar.rest
+ pc:= gcd coefficients um
+ if pc^=1 then
+ um:=(um exquo pc)::USP
+ ffactor:=multivariate(um,x)
+ for lcterm in mFactor(pc,ufactor).factors repeat
+ factorlist:=cons([lcterm.irr,lcterm.pow*ffexp],factorlist)
+ ldeg:=degree(ffactor,lvar)
+ um := unitCanonical um
+ if ground?(leadingCoefficient um) then
+ lf:= mfconst(um,lvar,ldeg,ufactor)
+ else lf:=mfpol(um,lvar,ldeg,ufactor)
+ auxfl:=[[unitCanonical multivariate(lfp,x),ffexp]$MParFact for lfp in lf]
+ factorlist:=append(factorlist,auxfl)
+ lcfacs := */[leadingCoefficient(f.irr)**((f.pow)::NNI) for f in factorlist]
+ [(leadingCoefficient(m) exquo lcfacs):: R,factorlist]$MFinalFact
+
+ factor(m:P,ufactor:UFactor):Factored P ==
+ flist := mFactor(m,ufactor)
+ (flist.contp):: P *
+ (*/[primeFactor(u.irr,u.pow) for u in flist.factors])
+
+@
+\section{package MULTFACT MultivariateFactorize}
+<<package MULTFACT MultivariateFactorize>>=
+)abbrev package MULTFACT MultivariateFactorize
+++ Author: P. Gianni
+++ Date Created: 1983
+++ Date Last Updated: Sept. 1990
+++ Basic Functions:
+++ Related Constructors: MultFiniteFactorize, AlgebraicMultFact, UnivariateFactorize
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is the top level package for doing multivariate factorization
+++ over basic domains like \spadtype{Integer} or \spadtype{Fraction Integer}.
+
+MultivariateFactorize(OV,E,R,P) : C == T
+ where
+ R : Join(EuclideanDomain, CharacteristicZero)
+ -- with factor on R[x]
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ P : PolynomialCategory(R,E,OV)
+ Z ==> Integer
+ MParFact ==> Record(irr:P,pow:Z)
+ USP ==> SparseUnivariatePolynomial P
+ SUParFact ==> Record(irr:USP,pow:Z)
+ SUPFinalFact ==> Record(contp:R,factors:List SUParFact)
+ MFinalFact ==> Record(contp:R,factors:List MParFact)
+
+ -- contp = content,
+ -- factors = List of irreducible factors with exponent
+ L ==> List
+
+ C == with
+ factor : P -> Factored P
+ ++ factor(p) factors the multivariate polynomial p over its coefficient
+ ++ domain
+ factor : USP -> Factored USP
+ ++ factor(p) factors the multivariate polynomial p over its coefficient
+ ++ domain where p is represented as a univariate polynomial with
+ ++ multivariate coefficients
+ T == add
+ factor(p:P) : Factored P ==
+ R is Fraction Integer =>
+ factor(p)$MRationalFactorize(E,OV,Integer,P)
+ R is Fraction Complex Integer =>
+ factor(p)$MRationalFactorize(E,OV,Complex Integer,P)
+ R is Fraction Polynomial Integer and OV has convert: % -> Symbol =>
+ factor(p)$MPolyCatRationalFunctionFactorizer(E,OV,Integer,P)
+ factor(p,factor$GenUFactorize(R))$InnerMultFact(OV,E,R,P)
+
+ factor(up:USP) : Factored USP ==
+ factor(up,factor$GenUFactorize(R))$InnerMultFact(OV,E,R,P)
+
+@
+\section{package ALGMFACT AlgebraicMultFact}
+<<package ALGMFACT AlgebraicMultFact>>=
+)abbrev package ALGMFACT AlgebraicMultFact
+++ Author: P. Gianni
+++ Date Created: 1990
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package factors multivariate polynomials over the
+++ domain of \spadtype{AlgebraicNumber} by allowing the user
+++ to specify a list of algebraic numbers generating the particular
+++ extension to factor over.
+
+AlgebraicMultFact(OV,E,P) : C == T
+ where
+ AN ==> AlgebraicNumber
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ P : PolynomialCategory(AN,E,OV)
+ BP ==> SparseUnivariatePolynomial AN
+ Z ==> Integer
+ MParFact ==> Record(irr:P,pow:Z)
+ USP ==> SparseUnivariatePolynomial P
+ SUParFact ==> Record(irr:USP,pow:Z)
+ SUPFinalFact ==> Record(contp:R,factors:List SUParFact)
+ MFinalFact ==> Record(contp:R,factors:List MParFact)
+
+ -- contp = content,
+ -- factors = List of irreducible factors with exponent
+ L ==> List
+
+ C == with
+ factor : (P,L AN) -> Factored P
+ ++ factor(p,lan) factors the polynomial p over the extension
+ ++ generated by the algebraic numbers given by the list lan.
+ factor : (USP,L AN) -> Factored USP
+ ++ factor(p,lan) factors the polynomial p over the extension
+ ++ generated by the algebraic numbers given by the list lan.
+ ++ p is presented as a univariate polynomial with multivariate
+ ++ coefficients.
+ T == add
+ AF := AlgFactor(BP)
+
+ factor(p:P,lalg:L AN) : Factored P ==
+ factor(p,factor(#1,lalg)$AF)$InnerMultFact(OV,E,AN,P)
+
+ factor(up:USP,lalg:L AN) : Factored USP ==
+ factor(up,factor(#1,lalg)$AF)$InnerMultFact(OV,E,AN,P)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INNMFACT InnerMultFact>>
+<<package MULTFACT MultivariateFactorize>>
+<<package ALGMFACT AlgebraicMultFact>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/multpoly.spad.pamphlet b/src/algebra/multpoly.spad.pamphlet
new file mode 100644
index 00000000..86e5548a
--- /dev/null
+++ b/src/algebra/multpoly.spad.pamphlet
@@ -0,0 +1,760 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra multpoly.spad}
+\author{Dave Barton, Barry Trager, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain POLY Polynomial}
+<<domain POLY Polynomial>>=
+)abbrev domain POLY Polynomial
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, degree, eval, coefficient, monomial, differentiate,
+++ resultant, gcd
+++ Related Constructors: SparseMultivariatePolynomial, MultivariatePolynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate
+++ References:
+++ Description:
+++ This type is the basic representation of sparse recursive multivariate
+++ polynomials whose variables are arbitrary symbols. The ordering
+++ is alphabetic determined by the Symbol type.
+++ The coefficient ring may be non commutative,
+++ but the variables are assumed to commute.
+
+Polynomial(R:Ring):
+ PolynomialCategory(R, IndexedExponents Symbol, Symbol) with
+ if R has Algebra Fraction Integer then
+ integrate: (%, Symbol) -> %
+ ++ integrate(p,x) computes the integral of \spad{p*dx}, i.e.
+ ++ integrates the polynomial p with respect to the variable x.
+ == SparseMultivariatePolynomial(R, Symbol) add
+
+ import UserDefinedPartialOrdering(Symbol)
+
+ coerce(p:%):OutputForm ==
+ (r:= retractIfCan(p)@Union(R,"failed")) case R => r::R::OutputForm
+ a :=
+ userOrdered?() => largest variables p
+ mainVariable(p)::Symbol
+ outputForm(univariate(p, a), a::OutputForm)
+
+ if R has Algebra Fraction Integer then
+ integrate(p, x) == (integrate univariate(p, x)) (x::%)
+
+@
+\section{package POLY2 PolynomialFunctions2}
+<<package POLY2 PolynomialFunctions2>>=
+)abbrev package POLY2 PolynomialFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package takes a mapping between coefficient rings, and lifts
+++ it to a mapping between polynomials over those rings.
+
+PolynomialFunctions2(R:Ring, S:Ring): with
+ map: (R -> S, Polynomial R) -> Polynomial S
+ ++ map(f, p) produces a new polynomial as a result of applying
+ ++ the function f to every coefficient of the polynomial p.
+ == add
+ map(f, p) == map(#1::Polynomial(S), f(#1)::Polynomial(S),
+ p)$PolynomialCategoryLifting(IndexedExponents Symbol,
+ Symbol, R, Polynomial R, Polynomial S)
+
+
+@
+\section{domain MPOLY MultivariatePolynomial}
+<<domain MPOLY MultivariatePolynomial>>=
+)abbrev domain MPOLY MultivariatePolynomial
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, degree, eval, coefficient, monomial, differentiate,
+++ resultant, gcd
+++ Related Constructors: SparseMultivariatePolynomial, Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate
+++ References:
+++ Description:
+++ This type is the basic representation of sparse recursive multivariate
+++ polynomials whose variables are from a user specified list of symbols.
+++ The ordering is specified by the position of the variable in the list.
+++ The coefficient ring may be non commutative,
+++ but the variables are assumed to commute.
+
+MultivariatePolynomial(vl:List Symbol, R:Ring)
+ == SparseMultivariatePolynomial(--SparseUnivariatePolynomial,
+ R, OrderedVariableList vl)
+
+@
+\section{domain SMP SparseMultivariatePolynomial}
+<<domain SMP SparseMultivariatePolynomial>>=
+)abbrev domain SMP SparseMultivariatePolynomial
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated: 30 November 1994
+++ Fix History:
+++ 30 Nov 94: added gcdPolynomial for float-type coefficients
+++ Basic Functions: Ring, degree, eval, coefficient, monomial, differentiate,
+++ resultant, gcd
+++ Related Constructors: Polynomial, MultivariatePolynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate
+++ References:
+++ Description:
+++ This type is the basic representation of sparse recursive multivariate
+++ polynomials. It is parameterized by the coefficient ring and the
+++ variable set which may be infinite. The variable ordering is determined
+++ by the variable set parameter. The coefficient ring may be non-commutative,
+++ but the variables are assumed to commute.
+
+SparseMultivariatePolynomial(R: Ring,VarSet: OrderedSet): C == T where
+ pgcd ==> PolynomialGcdPackage(IndexedExponents VarSet,VarSet,R,%)
+ C == PolynomialCategory(R,IndexedExponents(VarSet),VarSet)
+ SUP ==> SparseUnivariatePolynomial
+ T == add
+ --constants
+ --D := F(%) replaced by next line until compiler support completed
+
+ --representations
+ D := SparseUnivariatePolynomial(%)
+ VPoly:= Record(v:VarSet,ts:D)
+ Rep:= Union(R,VPoly)
+
+ --local function
+
+
+ --declarations
+ fn: R -> R
+ n: Integer
+ k: NonNegativeInteger
+ kp:PositiveInteger
+ k1:NonNegativeInteger
+ c: R
+ mvar: VarSet
+ val : R
+ var:VarSet
+ up: D
+ p,p1,p2,pval: %
+ Lval : List(R)
+ Lpval : List(%)
+ Lvar : List(VarSet)
+
+ --define
+ 0 == 0$R::%
+ 1 == 1$R::%
+
+
+ zero? p == p case R and zero?(p)$R
+-- one? p == p case R and one?(p)$R
+ one? p == p case R and ((p) = 1)$R
+ -- a local function
+ red(p:%):% ==
+ p case R => 0
+ if ground?(reductum p.ts) then leadingCoefficient(reductum p.ts) else [p.v,reductum p.ts]$VPoly
+
+ numberOfMonomials(p): NonNegativeInteger ==
+ p case R =>
+ zero?(p)$R => 0
+ 1
+ +/[numberOfMonomials q for q in coefficients(p.ts)]
+
+ coerce(mvar):% == [mvar,monomial(1,1)$D]$VPoly
+
+ monomial? p ==
+ p case R => true
+ sup : D := p.ts
+ 1 ^= numberOfMonomials(sup) => false
+ monomial? leadingCoefficient(sup)$D
+
+-- local
+ moreThanOneVariable?: % -> Boolean
+
+ moreThanOneVariable? p ==
+ p case R => false
+ q:=p.ts
+ any?(not ground? #1 ,coefficients q) => true
+ false
+
+ -- if we already know we use this (slighlty) faster function
+ univariateKnown: % -> SparseUnivariatePolynomial R
+
+ univariateKnown p ==
+ p case R => (leadingCoefficient p) :: SparseUnivariatePolynomial(R)
+ monomial( leadingCoefficient p,degree p.ts)+ univariateKnown(red p)
+
+ univariate p ==
+ p case R =>(leadingCoefficient p) :: SparseUnivariatePolynomial(R)
+ moreThanOneVariable? p => error "not univariate"
+ monomial( leadingCoefficient p,degree p.ts)+ univariate(red p)
+
+ multivariate (u:SparseUnivariatePolynomial(R),var:VarSet) ==
+ ground? u => (leadingCoefficient u) ::%
+ [var,monomial(leadingCoefficient u,degree u)$D]$VPoly +
+ multivariate(reductum u,var)
+
+ univariate(p:%,mvar:VarSet):SparseUnivariatePolynomial(%) ==
+ p case R or mvar>p.v => monomial(p,0)$D
+ pt:=p.ts
+ mvar=p.v => pt
+ monomial(1,p.v,degree pt)*univariate(leadingCoefficient pt,mvar)+
+ univariate(red p,mvar)
+
+-- a local functions, used in next definition
+ unlikeUnivReconstruct(u:SparseUnivariatePolynomial(%),mvar:VarSet):% ==
+ zero? (d:=degree u) => coefficient(u,0)
+ monomial(leadingCoefficient u,mvar,d)+
+ unlikeUnivReconstruct(reductum u,mvar)
+
+ multivariate(u:SparseUnivariatePolynomial(%),mvar:VarSet):% ==
+ ground? u => coefficient(u,0)
+ uu:=u
+ while not zero? uu repeat
+ cc:=leadingCoefficient uu
+ cc case R or mvar > cc.v => uu:=reductum uu
+ return unlikeUnivReconstruct(u,mvar)
+ [mvar,u]$VPoly
+
+ ground?(p:%):Boolean ==
+ p case R => true
+ false
+
+-- const p ==
+-- p case R => p
+-- error "the polynomial is not a constant"
+
+ monomial(p,mvar,k1) ==
+ zero? k1 or zero? p => p
+ p case R or mvar>p.v => [mvar,monomial(p,k1)$D]$VPoly
+ p*[mvar,monomial(1,k1)$D]$VPoly
+
+ monomial(c:R,e:IndexedExponents(VarSet)):% ==
+ zero? e => (c::%)
+ monomial(1,leadingSupport e, leadingCoefficient e) *
+ monomial(c,reductum e)
+
+ coefficient(p:%, e:IndexedExponents(VarSet)) : R ==
+ zero? e =>
+ p case R => p::R
+ coefficient(coefficient(p.ts,0),e)
+ p case R => 0
+ ve := leadingSupport e
+ vp := p.v
+ ve < vp =>
+ coefficient(coefficient(p.ts,0),e)
+ ve > vp => 0
+ coefficient(coefficient(p.ts,leadingCoefficient e),reductum e)
+
+-- coerce(e:IndexedExponents(VarSet)) : % ==
+-- e = 0 => 1
+-- monomial(1,leadingSupport e, leadingCoefficient e) *
+-- (reductum e)::%
+
+-- retract(p:%):IndexedExponents(VarSet) ==
+-- q:Union(IndexedExponents(VarSet),"failed"):=retractIfCan p
+-- q :: IndexedExponents(VarSet)
+
+-- retractIfCan(p:%):Union(IndexedExponents(VarSet),"failed") ==
+-- p = 0 => degree p
+-- reductum(p)=0 and leadingCoefficient(p)=1 => degree p
+-- "failed"
+
+ coerce(n) == n::R::%
+ coerce(c) == c::%
+ characteristic == characteristic$R
+
+ recip(p) ==
+ p case R => (uu:=recip(p::R);uu case "failed" => "failed"; uu::%)
+ "failed"
+
+ - p ==
+ p case R => -$R p
+ [p.v, - p.ts]$VPoly
+ n * p ==
+ p case R => n * p::R
+ mvar:=p.v
+ up:=n*p.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ c * p ==
+ c = 1 => p
+ p case R => c * p::R
+ mvar:=p.v
+ up:=c*p.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ p1 + p2 ==
+ p1 case R and p2 case R => p1 +$R p2
+ p1 case R => [p2.v, p1::D + p2.ts]$VPoly
+ p2 case R => [p1.v, p1.ts + p2::D]$VPoly
+ p1.v = p2.v =>
+ mvar:=p1.v
+ up:=p1.ts+p2.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ p1.v < p2.v =>
+ [p2.v, p1::D + p2.ts]$VPoly
+ [p1.v, p1.ts + p2::D]$VPoly
+
+ p1 - p2 ==
+ p1 case R and p2 case R => p1 -$R p2
+ p1 case R => [p2.v, p1::D - p2.ts]$VPoly
+ p2 case R => [p1.v, p1.ts - p2::D]$VPoly
+ p1.v = p2.v =>
+ mvar:=p1.v
+ up:=p1.ts-p2.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ p1.v < p2.v =>
+ [p2.v, p1::D - p2.ts]$VPoly
+ [p1.v, p1.ts - p2::D]$VPoly
+
+ p1 = p2 ==
+ p1 case R =>
+ p2 case R => p1 =$R p2
+ false
+ p2 case R => false
+ p1.v = p2.v => p1.ts = p2.ts
+ false
+
+ p1 * p2 ==
+ p1 case R => p1::R * p2
+ p2 case R =>
+ mvar:=p1.v
+ up:=p1.ts*p2
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ p1.v = p2.v =>
+ mvar:=p1.v
+ up:=p1.ts*p2.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ p1.v > p2.v =>
+ mvar:=p1.v
+ up:=p1.ts*p2
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ --- p1.v < p2.v
+ mvar:=p2.v
+ up:=p1*p2.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+
+ p ^ kp == p ** (kp pretend NonNegativeInteger)
+ p ** kp == p ** (kp pretend NonNegativeInteger )
+ p ^ k == p ** k
+ p ** k ==
+ p case R => p::R ** k
+ -- univariate special case
+ not moreThanOneVariable? p =>
+ multivariate( (univariateKnown p) ** k , p.v)
+ mvar:=p.v
+ up:=p.ts ** k
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+
+ if R has IntegralDomain then
+ UnitCorrAssoc ==> Record(unit:%,canonical:%,associate:%)
+ unitNormal(p) ==
+ u,c,a:R
+ p case R =>
+ (u,c,a):= unitNormal(p::R)$R
+ [u::%,c::%,a::%]$UnitCorrAssoc
+ (u,c,a):= unitNormal(leadingCoefficient(p))$R
+ [u::%,(a*p)::%,a::%]$UnitCorrAssoc
+ unitCanonical(p) ==
+ p case R => unitCanonical(p::R)$R
+ (u,c,a):= unitNormal(leadingCoefficient(p))$R
+ a*p
+ unit? p ==
+ p case R => unit?(p::R)$R
+ false
+ associates?(p1,p2) ==
+ p1 case R => p2 case R and associates?(p1,p2)$R
+ p2 case VPoly and p1.v = p2.v and associates?(p1.ts,p2.ts)
+
+ if R has approximate then
+ p1 exquo p2 ==
+ p1 case R and p2 case R =>
+ a:= (p1::R exquo p2::R)
+ if a case "failed" then "failed" else a::%
+ zero? p1 => p1
+-- one? p2 => p1
+ (p2 = 1) => p1
+ p1 case R or p2 case VPoly and p1.v < p2.v => "failed"
+ p2 case R or p1.v > p2.v =>
+ a:= (p1.ts exquo p2::D)
+ a case "failed" => "failed"
+ [p1.v,a]$VPoly::%
+ -- The next test is useful in the case that R has inexact
+ -- arithmetic (in particular when it is Interval(...)).
+ -- In the case where the test succeeds, empirical evidence
+ -- suggests that it can speed up the computation several times,
+ -- but in other cases where there are a lot of variables
+ -- and p1 and p2 differ only in the low order terms (e.g. p1=p2+1)
+ -- it slows exquo down by about 15-20%.
+ p1 = p2 => 1
+ a:= p1.ts exquo p2.ts
+ a case "failed" => "failed"
+ mvar:=p1.v
+ up:SUP %:=a
+ if ground? (up) then leadingCoefficient(up) else [mvar,up]$VPoly::%
+ else
+ p1 exquo p2 ==
+ p1 case R and p2 case R =>
+ a:= (p1::R exquo p2::R)
+ if a case "failed" then "failed" else a::%
+ zero? p1 => p1
+-- one? p2 => p1
+ (p2 = 1) => p1
+ p1 case R or p2 case VPoly and p1.v < p2.v => "failed"
+ p2 case R or p1.v > p2.v =>
+ a:= (p1.ts exquo p2::D)
+ a case "failed" => "failed"
+ [p1.v,a]$VPoly::%
+ a:= p1.ts exquo p2.ts
+ a case "failed" => "failed"
+ mvar:=p1.v
+ up:SUP %:=a
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly::%
+
+ map(fn,p) ==
+ p case R => fn(p)
+ mvar:=p.v
+ up:=map(map(fn,#1),p.ts)
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+
+ if R has Field then
+ (p : %) / (r : R) == inv(r) * p
+
+ if R has GcdDomain then
+ content(p) ==
+ p case R => p
+ c :R :=0
+ up:=p.ts
+-- while not(zero? up) and not(one? c) repeat
+ while not(zero? up) and not(c = 1) repeat
+ c:=gcd(c,content leadingCoefficient(up))
+ up := reductum up
+ c
+
+ if R has EuclideanDomain and R has CharacteristicZero and not(R has FloatingPointSystem) then
+ content(p,mvar) ==
+ p case R => p
+ gcd(coefficients univariate(p,mvar))$pgcd
+
+ gcd(p1,p2) == gcd(p1,p2)$pgcd
+
+ gcd(lp:List %) == gcd(lp)$pgcd
+
+ gcdPolynomial(a:SUP $,b:SUP $):SUP $ == gcd(a,b)$pgcd
+
+ else if R has GcdDomain then
+ content(p,mvar) ==
+ p case R => p
+ content univariate(p,mvar)
+
+ gcd(p1,p2) ==
+ p1 case R =>
+ p2 case R => gcd(p1,p2)$R::%
+ zero? p1 => p2
+ gcd(p1, content(p2.ts))
+ p2 case R =>
+ zero? p2 => p1
+ gcd(p2, content(p1.ts))
+ p1.v < p2.v => gcd(p1, content(p2.ts))
+ p1.v > p2.v => gcd(content(p1.ts), p2)
+ mvar:=p1.v
+ up:=gcd(p1.ts, p2.ts)
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+
+ if R has FloatingPointSystem then
+ -- eventually need a better notion of gcd's over floats
+ -- this essentially computes the gcds of the monomial contents
+ gcdPolynomial(a:SUP $,b:SUP $):SUP $ ==
+ ground? (a) =>
+ zero? a => b
+ gcd(leadingCoefficient a, content b)::SUP $
+ ground?(b) =>
+ zero? b => b
+ gcd(leadingCoefficient b, content a)::SUP $
+ conta := content a
+ mona:SUP $ := monomial(conta, minimumDegree a)
+ if mona ^= 1 then
+ a := (a exquo mona)::SUP $
+ contb := content b
+ monb:SUP $ := monomial(contb, minimumDegree b)
+ if monb ^= 1 then
+ b := (b exquo monb)::SUP $
+ mong:SUP $ := monomial(gcd(conta, contb),
+ min(degree mona, degree monb))
+ degree(a) >= degree b =>
+ not((a exquo b) case "failed") =>
+ mong * b
+ mong
+ not((b exquo a) case "failed") => mong * a
+ mong
+
+ coerce(p):OutputForm ==
+ p case R => (p::R)::OutputForm
+ outputForm(p.ts,p.v::OutputForm)
+
+ coefficients p ==
+ p case R => list(p :: R)$List(R)
+ "append"/[coefficients(p1)$% for p1 in coefficients(p.ts)]
+
+ retract(p:%):R ==
+ p case R => p :: R
+ error "cannot retract nonconstant polynomial"
+
+ retractIfCan(p:%):Union(R, "failed") ==
+ p case R => p::R
+ "failed"
+
+-- leadingCoefficientRecursive(p:%):% ==
+-- p case R => p
+-- leadingCoefficient p.ts
+
+ mymerge:(List VarSet,List VarSet) ->List VarSet
+ mymerge(l:List VarSet,m:List VarSet):List VarSet ==
+ empty? l => m
+ empty? m => l
+ first l = first m =>
+ empty? rest l =>
+ setrest!(l,rest m)
+ l
+ empty? rest m => l
+ setrest!(l, mymerge(rest l, rest m))
+ l
+ first l > first m =>
+ empty? rest l =>
+ setrest!(l,m)
+ l
+ setrest!(l, mymerge(rest l, m))
+ l
+ empty? rest m =>
+ setrest!(m,l)
+ m
+ setrest!(m,mymerge(l,rest m))
+ m
+
+ variables p ==
+ p case R => empty()
+ lv:List VarSet:=empty()
+ q := p.ts
+ while not zero? q repeat
+ lv:=mymerge(lv,variables leadingCoefficient q)
+ q := reductum q
+ cons(p.v,lv)
+
+ mainVariable p ==
+ p case R => "failed"
+ p.v
+
+ eval(p,mvar,pval) == univariate(p,mvar)(pval)
+ eval(p,mvar,val) == univariate(p,mvar)(val)
+
+ evalSortedVarlist(p,Lvar,Lpval):% ==
+ p case R => p
+ empty? Lvar or empty? Lpval => p
+ mvar := Lvar.first
+ mvar > p.v => evalSortedVarlist(p,Lvar.rest,Lpval.rest)
+ pval := Lpval.first
+ pts := map(evalSortedVarlist(#1,Lvar,Lpval),p.ts)
+ mvar=p.v =>
+ pval case R => pts (pval::R)
+ pts pval
+ multivariate(pts,p.v)
+
+ eval(p,Lvar,Lpval) ==
+ empty? rest Lvar => evalSortedVarlist(p,Lvar,Lpval)
+ sorted?(#1 > #2, Lvar) => evalSortedVarlist(p,Lvar,Lpval)
+ nlvar := sort(#1 > #2,Lvar)
+ nlpval :=
+ Lvar = nlvar => Lpval
+ nlpval := [Lpval.position(mvar,Lvar) for mvar in nlvar]
+ evalSortedVarlist(p,nlvar,nlpval)
+
+ eval(p,Lvar,Lval) ==
+ eval(p,Lvar,[val::% for val in Lval]$(List %)) -- kill?
+
+ degree(p,mvar) ==
+ p case R => 0
+ mvar= p.v => degree p.ts
+ mvar > p.v => 0 -- might as well take advantage of the order
+ max(degree(leadingCoefficient p.ts,mvar),degree(red p,mvar))
+
+ degree(p,Lvar) == [degree(p,mvar) for mvar in Lvar]
+
+ degree p ==
+ p case R => 0
+ degree(leadingCoefficient(p.ts)) + monomial(degree(p.ts), p.v)
+
+ minimumDegree p ==
+ p case R => 0
+ md := minimumDegree p.ts
+ minimumDegree(coefficient(p.ts,md)) + monomial(md, p.v)
+
+ minimumDegree(p,mvar) ==
+ p case R => 0
+ mvar = p.v => minimumDegree p.ts
+ md:=minimumDegree(leadingCoefficient p.ts,mvar)
+ zero? (p1:=red p) => md
+ min(md,minimumDegree(p1,mvar))
+
+ minimumDegree(p,Lvar) ==
+ [minimumDegree(p,mvar) for mvar in Lvar]
+
+ totalDegree(p, Lvar) ==
+ ground? p => 0
+ null setIntersection(Lvar, variables p) => 0
+ u := univariate(p, mv := mainVariable(p)::VarSet)
+ weight:NonNegativeInteger := (member?(mv,Lvar) => 1; 0)
+ tdeg:NonNegativeInteger := 0
+ while u ^= 0 repeat
+ termdeg:NonNegativeInteger := weight*degree u +
+ totalDegree(leadingCoefficient u, Lvar)
+ tdeg := max(tdeg, termdeg)
+ u := reductum u
+ tdeg
+
+ if R has CommutativeRing then
+ differentiate(p,mvar) ==
+ p case R => 0
+ mvar=p.v =>
+ up:=differentiate p.ts
+ if ground? up then leadingCoefficient(up) else [mvar,up]$VPoly
+ up:=map(differentiate(#1,mvar),p.ts)
+ if ground? up then leadingCoefficient(up) else [p.v,up]$VPoly
+
+ leadingCoefficient(p) ==
+ p case R => p
+ leadingCoefficient(leadingCoefficient(p.ts))
+
+-- trailingCoef(p) ==
+-- p case R => p
+-- coef(p.ts,0) case R => coef(p.ts,0)
+-- trailingCoef(red p)
+-- TrailingCoef(p) == trailingCoef(p)
+
+ leadingMonomial p ==
+ p case R => p
+ monomial(leadingMonomial leadingCoefficient(p.ts),
+ p.v, degree(p.ts))
+
+ reductum(p) ==
+ p case R => 0
+ p - leadingMonomial p
+
+
+-- if R is Integer then
+-- pgcd := PolynomialGcdPackage(%,VarSet)
+-- gcd(p1,p2) ==
+-- gcd(p1,p2)$pgcd
+--
+-- else if R is RationalNumber then
+-- gcd(p1,p2) ==
+-- mrat:= MRationalFactorize(VarSet,%)
+-- gcd(p1,p2)$mrat
+--
+-- else gcd(p1,p2) ==
+-- p1 case R =>
+-- p2 case R => gcd(p1,p2)$R::%
+-- p1 = 0 => p2
+-- gcd(p1, content(p2.ts))
+-- p2 case R =>
+-- p2 = 0 => p1
+-- gcd(p2, content(p1.ts))
+-- p1.v < p2.v => gcd(p1, content(p2.ts))
+-- p1.v > p2.v => gcd(content(p1.ts), p2)
+-- PSimp(p1.v, gcd(p1.ts, p2.ts))
+
+@
+\section{domain INDE IndexedExponents}
+<<domain INDE IndexedExponents>>=
+)abbrev domain INDE IndexedExponents
+++ Author: James Davenport
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ IndexedExponents of an ordered set of variables gives a representation
+++ for the degree of polynomials in commuting variables. It gives an ordered
+++ pairing of non negative integer exponents with variables
+
+IndexedExponents(Varset:OrderedSet): C == T where
+ C == Join(OrderedAbelianMonoidSup,
+ IndexedDirectProductCategory(NonNegativeInteger,Varset))
+ T == IndexedDirectProductOrderedAbelianMonoidSup(NonNegativeInteger,Varset) add
+ Term:= Record(k:Varset,c:NonNegativeInteger)
+ Rep:= List Term
+ x:%
+ t:Term
+ coerceOF(t):OutputForm == --++ converts term to OutputForm
+ t.c = 1 => (t.k)::OutputForm
+ (t.k)::OutputForm ** (t.c)::OutputForm
+ coerce(x):OutputForm == ++ converts entire exponents to OutputForm
+ null x => 1::Integer::OutputForm
+ null rest x => coerceOF(first x)
+ reduce("*",[coerceOF t for t in x])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain INDE IndexedExponents>>
+<<domain SMP SparseMultivariatePolynomial>>
+<<domain POLY Polynomial>>
+<<package POLY2 PolynomialFunctions2>>
+<<domain MPOLY MultivariatePolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/multsqfr.spad.pamphlet b/src/algebra/multsqfr.spad.pamphlet
new file mode 100644
index 00000000..fbc32eeb
--- /dev/null
+++ b/src/algebra/multsqfr.spad.pamphlet
@@ -0,0 +1,395 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra multsqfr.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MULTSQFR MultivariateSquareFree}
+<<package MULTSQFR MultivariateSquareFree>>=
+)abbrev package MULTSQFR MultivariateSquareFree
+++Author : P.Gianni
+++ This package provides the functions for the computation of the square
+++ free decomposition of a multivariate polynomial.
+++ It uses the package GenExEuclid for the resolution of
+++ the equation \spad{Af + Bg = h} and its generalization to n polynomials
+++ over an integral domain and the package \spad{MultivariateLifting}
+++ for the "multivariate" lifting.
+
+MultivariateSquareFree (E,OV,R,P) : C == T where
+ Z ==> Integer
+ NNI ==> NonNegativeInteger
+ R : EuclideanDomain
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ P : PolynomialCategory(R,E,OV)
+ SUP ==> SparseUnivariatePolynomial P
+
+ BP ==> SparseUnivariatePolynomial(R)
+ fUnion ==> Union("nil","sqfr","irred","prime")
+ ffSUP ==> Record(flg:fUnion,fctr:SUP,xpnt:Integer)
+ ffP ==> Record(flg:fUnion,fctr:P,xpnt:Integer)
+ FFE ==> Record(factor:BP,exponent:Z)
+ FFEP ==> Record(factor:P,exponent:Z)
+ FFES ==> Record(factor:SUP,exponent:Z)
+ Choice ==> Record(upol:BP,Lval:List(R),Lfact:List FFE,ctpol:R)
+ squareForm ==> Record(unitPart:P,suPart:List FFES)
+ Twopol ==> Record(pol:SUP,polval:BP)
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+
+ C == with
+ squareFree : P -> Factored P
+ ++ squareFree(p) computes the square free
+ ++ decomposition of a multivariate polynomial p.
+ squareFree : SUP -> Factored SUP
+ ++ squareFree(p) computes the square free
+ ++ decomposition of a multivariate polynomial p presented as
+ ++ a univariate polynomial with multivariate coefficients.
+ squareFreePrim : P -> Factored P
+ ++ squareFreePrim(p) compute the square free decomposition
+ ++ of a primitive multivariate polynomial p.
+
+
+
+ ---- local functions ----
+ compdegd : List FFE -> Z
+ ++ compdegd should be local
+ univcase : (P,OV) -> Factored(P)
+ ++ univcase should be local
+ consnewpol : (SUP,BP,Z) -> Twopol
+ ++ consnewpol should be local
+ nsqfree : (SUP,List(OV), List List R) -> squareForm
+ ++ nsqfree should be local
+ intChoose : (SUP,List(OV),List List R) -> Choice
+ ++ intChoose should be local
+ coefChoose : (Z,Factored P) -> P
+ ++ coefChoose should be local
+ check : (List(FFE),List(FFE)) -> Boolean
+ ++ check should be local
+ lift : (SUP,BP,BP,P,List(OV),List(NNI),List(R)) -> Union(List(SUP),"failed")
+ ++ lift should be local
+ myDegree : (SUP,List OV,NNI) -> List NNI
+ ++ myDegree should be local
+ normDeriv2 : (BP,Z) -> BP
+ ++ normDeriv2 should be local
+
+
+
+ T == add
+
+ pmod:R := (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
+
+
+ import GenExEuclid()
+ import MultivariateLifting(E,OV,R,P)
+ import PolynomialGcdPackage(E,OV,R,P)
+ import FactoringUtilities(E,OV,R,P)
+ import IntegerCombinatoricFunctions(Z)
+
+
+ ---- Are the univariate square-free decompositions consistent? ----
+
+ ---- new square-free algorithm for primitive polynomial ----
+ nsqfree(oldf:SUP,lvar:List(OV),ltry:List List R) : squareForm ==
+ f:=oldf
+ univPol := intChoose(f,lvar,ltry)
+-- debug msg
+-- if not empty? ltry then output("ltry =", (ltry::OutputForm))$OutputPackage
+ f0:=univPol.upol
+ --the polynomial is square-free
+ f0=1$BP => [1$P,[[f,1]$FFES]]$squareForm
+ lfact:List(FFE):=univPol.Lfact
+ lval:=univPol.Lval
+ ctf:=univPol.ctpol
+ leadpol:Boolean:=false
+ sqdec:List FFES := empty()
+ exp0:Z:=0
+ unitsq:P:=1
+ lcf:P:=leadingCoefficient f
+ if ctf^=1 then
+ f0:=ctf*f0
+ f:=(ctf::P)*f
+ lcf:=ctf*lcf
+ sqlead:List FFEP:= empty()
+ sqlc:Factored P:=1
+ if lcf^=1$P then
+ leadpol:=true
+ sqlc:=squareFree lcf
+ unitsq:=unitsq*(unit sqlc)
+ sqlead:= factors sqlc
+ lfact:=sort(#1.exponent > #2.exponent,lfact)
+ while lfact^=[] repeat
+ pfact:=lfact.first
+ (g0,exp0):=(pfact.factor,pfact.exponent)
+ lfact:=lfact.rest
+ lfact=[] and exp0 =1 =>
+ f := (f exquo (ctf::P))::SUP
+ gg := unitNormal leadingCoefficient f
+ sqdec:=cons([gg.associate*f,exp0],sqdec)
+ return [gg.unit, sqdec]$squareForm
+ if ctf^=1 then g0:=ctf*g0
+ npol:=consnewpol(f,f0,exp0)
+ (d,d0):=(npol.pol,npol.polval)
+ if leadpol then lcoef:=coefChoose(exp0,sqlc)
+ else lcoef:=1$P
+ ldeg:=myDegree(f,lvar,exp0::NNI)
+ result:=lift(d,g0,(d0 exquo g0)::BP,lcoef,lvar,ldeg,lval)
+ result case "failed" => return nsqfree(oldf,lvar,ltry)
+ result0:SUP:= (result::List SUP).1
+ r1:SUP:=result0**(exp0:NNI)
+ if (h:=f exquo r1) case "failed" then return nsqfree(oldf,lvar,empty())
+ sqdec:=cons([result0,exp0],sqdec)
+ f:=h::SUP
+ f0:=completeEval(h,lvar,lval)
+ lcr:P:=leadingCoefficient result0
+ if leadpol and lcr^=1$P then
+ for lpfact in sqlead while lcr^=1 repeat
+ ground? lcr =>
+ unitsq:=(unitsq exquo lcr)::P
+ lcr:=1$P
+ (h1:=lcr exquo lpfact.factor) case "failed" => "next"
+ lcr:=h1::P
+ lpfact.exponent:=(lpfact.exponent)-exp0
+ [((retract f) exquo ctf)::P,sqdec]$squareForm
+
+
+ squareFree(f:SUP) : Factored SUP ==
+ degree f =0 =>
+ fu:=squareFree retract f
+ makeFR((unit fu)::SUP,[["sqfr",ff.fctr::SUP,ff.xpnt]
+ for ff in factorList fu])
+ lvar:= "setUnion"/[variables cf for cf in coefficients f]
+ empty? lvar => -- the polynomial is univariate
+ upol:=map(ground,f)$UPCF2(P,SUP,R,BP)
+ usqfr:=squareFree upol
+ makeFR(map(coerce,unit usqfr)$UPCF2(R,BP,P,SUP),
+ [["sqfr",map(coerce,ff.fctr)$UPCF2(R,BP,P,SUP),ff.xpnt]
+ for ff in factorList usqfr])
+
+ lcf:=content f
+ f:=(f exquo lcf) ::SUP
+ lcSq:=squareFree lcf
+ lfs:List ffSUP:=[["sqfr",ff.fctr ::SUP,ff.xpnt]
+ for ff in factorList lcSq]
+ partSq:=nsqfree(f,lvar,empty())
+
+ lfs:=append([["sqfr",fu.factor,fu.exponent]$ffSUP
+ for fu in partSq.suPart],lfs)
+ makeFR((unit lcSq * partSq.unitPart) ::SUP,lfs)
+
+ squareFree(f:P) : Factored P ==
+ ground? f => makeFR(f,[]) --- the polynomial is constant ---
+
+ lvar:List(OV):=variables(f)
+ result1:List ffP:= empty()
+
+ lmdeg :=minimumDegree(f,lvar) --- is the mindeg > 0 ? ---
+ p:P:=1$P
+ for im in 1..#lvar repeat
+ (n:=lmdeg.im)=0 => "next im"
+ y:=lvar.im
+ p:=p*monomial(1$P,y,n)
+ result1:=cons(["sqfr",y::P,n],result1)
+ if p^=1$P then
+ f := (f exquo p)::P
+ if ground? f then return makeFR(f, result1)
+ lvar:=variables(f)
+
+
+ #lvar=1 => --- the polynomial is univariate ---
+ result:=univcase(f,lvar.first)
+ makeFR(unit result,append(result1,factorList result))
+
+ ldeg:=degree(f,lvar) --- general case ---
+ m:="min"/[j for j in ldeg|j^=0]
+ i:Z:=1
+ for j in ldeg while j>m repeat i:=i+1
+ x:=lvar.i
+ lvar:=delete(lvar,i)
+ f0:=univariate (f,x)
+ lcont:P:= content f0
+ nsqfftot:=nsqfree((f0 exquo lcont)::SUP,lvar,empty())
+ nsqff:List ffP:=[["sqfr",multivariate(fu.factor,x),fu.exponent]$ffP
+ for fu in nsqfftot.suPart]
+ result1:=append(result1,nsqff)
+ ground? lcont => makeFR(lcont*nsqfftot.unitPart,result1)
+ sqlead:=squareFree(lcont)
+ makeFR(unit sqlead*nsqfftot.unitPart,append(result1,factorList sqlead))
+
+ -- Choose the integer for the evaluation. --
+ -- If the polynomial is square-free the function returns upol=1. --
+
+ intChoose(f:SUP,lvar:List(OV),ltry:List List R):Choice ==
+ degf:= degree f
+ try:NNI:=0
+ nvr:=#lvar
+ range:Z:=10
+ lfact1:List(FFE):=[]
+ lval1:List R := []
+ lfact:List(FFE)
+ ctf1:R:=1
+ f1:BP:=1$BP
+ d1:Z
+ while range<10000000000 repeat
+ range:=2*range
+ lval:= [ran(range) for i in 1..nvr]
+ member?(lval,ltry) => "new integer"
+ ltry:=cons(lval,ltry)
+ f0:=completeEval(f,lvar,lval)
+ degree f0 ^=degf => "new integer"
+ ctf:=content f0
+ lfact:List(FFE):=factors(squareFree((f0 exquo (ctf:R)::BP)::BP))
+
+ ---- the univariate polynomial is square-free ----
+ if #lfact=1 and (lfact.1).exponent=1 then
+ return [1$BP,lval,lfact,1$R]$Choice
+
+ d0:=compdegd lfact
+ ---- inizialize lfact1 ----
+ try=0 =>
+ f1:=f0
+ lfact1:=lfact
+ ctf1:=ctf
+ lval1:=lval
+ d1:=d0
+ try:=1
+ d0=d1 =>
+ return [f1,lval1,lfact1,ctf1]$Choice
+ d0 < d1 =>
+ try:=1
+ f1:=f0
+ lfact1:=lfact
+ ctf1:=ctf
+ lval1:=lval
+ d1:=d0
+
+
+ ---- Choose the leading coefficient for the lifting ----
+ coefChoose(exp:Z,sqlead:Factored(P)) : P ==
+ lcoef:P:=unit(sqlead)
+ for term in factors(sqlead) repeat
+ texp:=term.exponent
+ texp<exp => "next term"
+ texp=exp => lcoef:=lcoef*term.factor
+ lcoef:=lcoef*(term.factor)**((texp quo exp)::NNI)
+ lcoef
+
+ ---- Construction of the polynomials for the lifting ----
+ consnewpol(g:SUP,g0:BP,deg:Z):Twopol ==
+ deg=1 => [g,g0]$Twopol
+ deg:=deg-1
+ [normalDeriv(g,deg),normDeriv2(g0,deg)]$Twopol
+
+ ---- lift the univariate square-free factor ----
+ lift(ud:SUP,g0:BP,g1:BP,lcoef:P,lvar:List(OV),
+ ldeg:List(NNI),lval:List(R)) : Union(List SUP,"failed") ==
+ leadpol:Boolean:=false
+ lcd:P:=leadingCoefficient ud
+ leadlist:List(P):=empty()
+
+ if ^ground?(leadingCoefficient ud) then
+ leadpol:=true
+ ud:=lcoef*ud
+ lcg0:R:=leadingCoefficient g0
+ if ground? lcoef then g0:=retract(lcoef) quo lcg0 *g0
+ else g0:=(retract(eval(lcoef,lvar,lval)) quo lcg0) * g0
+ g1:=lcg0*g1
+ leadlist:=[lcoef,lcd]
+ plist:=lifting(ud,lvar,[g0,g1],lval,leadlist,ldeg,pmod)
+ plist case "failed" => "failed"
+ (p0:SUP,p1:SUP):=((plist::List SUP).1,(plist::List SUP).2)
+ if completeEval(p0,lvar,lval) ^= g0 then (p0,p1):=(p1,p0)
+ [primitivePart p0,primitivePart p1]
+
+ ---- the polynomial is univariate ----
+ univcase(f:P,x:OV) : Factored(P) ==
+ uf := univariate f
+ cf:=content uf
+ uf :=(uf exquo cf)::BP
+ result:Factored BP:=squareFree uf
+ makeFR(multivariate(cf*unit result,x),
+ [["sqfr",multivariate(term.factor,x),term.exponent]
+ for term in factors result])
+
+-- squareFreePrim(p:P) : Factored P ==
+-- -- p is content free
+-- ground? p => makeFR(p,[]) --- the polynomial is constant ---
+--
+-- lvar:List(OV):=variables p
+-- #lvar=1 => --- the polynomial is univariate ---
+-- univcase(p,lvar.first)
+-- nsqfree(p,lvar,1)
+
+ compdegd(lfact:List(FFE)) : Z ==
+ ris:Z:=0
+ for pfact in lfact repeat
+ ris:=ris+(pfact.exponent -1)*degree pfact.factor
+ ris
+
+ normDeriv2(f:BP,m:Z) : BP ==
+ (n1:Z:=degree f) < m => 0$BP
+ n1=m => (leadingCoefficient f)::BP
+ k:=binomial(n1,m)
+ ris:BP:=0$BP
+ n:Z:=n1
+ while n>= m repeat
+ while n1>n repeat
+ k:=(k*(n1-m)) quo n1
+ n1:=n1-1
+ ris:=ris+monomial(k*leadingCoefficient f,(n-m)::NNI)
+ f:=reductum f
+ n:=degree f
+ ris
+
+ myDegree(f:SUP,lvar:List OV,exp:NNI) : List NNI==
+ [n quo exp for n in degree(f,lvar)]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MULTSQFR MultivariateSquareFree>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/naalg.spad.pamphlet b/src/algebra/naalg.spad.pamphlet
new file mode 100644
index 00000000..ec93ce54
--- /dev/null
+++ b/src/algebra/naalg.spad.pamphlet
@@ -0,0 +1,1095 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra naalg.spad}
+\author{Johannes Grabmeier, Robert Wisbauer}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ALGSC AlgebraGivenByStructuralConstants}
+<<domain ALGSC AlgebraGivenByStructuralConstants>>=
+)abbrev domain ALGSC AlgebraGivenByStructuralConstants
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 22 January 1992
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: algebra, structural constants
+++ Reference:
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++ Description:
+++ AlgebraGivenByStructuralConstants implements finite rank algebras
+++ over a commutative ring, given by the structural constants \spad{gamma}
+++ with respect to a fixed basis \spad{[a1,..,an]}, where
+++ \spad{gamma} is an \spad{n}-vector of n by n matrices
+++ \spad{[(gammaijk) for k in 1..rank()]} defined by
+++ \spad{ai * aj = gammaij1 * a1 + ... + gammaijn * an}.
+++ The symbols for the fixed basis
+++ have to be given as a list of symbols.
+AlgebraGivenByStructuralConstants(R:Field, n : PositiveInteger,_
+ ls : List Symbol, gamma: Vector Matrix R ): public == private where
+
+ V ==> Vector
+ M ==> Matrix
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ REC ==> Record(particular: Union(V R,"failed"),basis: List V R)
+ LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+
+ --public ==> FramedNonAssociativeAlgebra(R) with
+ public ==> Join(FramedNonAssociativeAlgebra(R), _
+ LeftModule(SquareMatrix(n,R)) ) with
+
+ coerce : Vector R -> %
+ ++ coerce(v) converts a vector to a member of the algebra
+ ++ by forming a linear combination with the basis element.
+ ++ Note: the vector is assumed to have length equal to the
+ ++ dimension of the algebra.
+
+ private ==> DirectProduct(n,R) add
+
+ Rep := DirectProduct(n,R)
+
+ x,y : %
+ dp : DirectProduct(n,R)
+ v : V R
+
+
+ recip(x) == recip(x)$FiniteRankNonAssociativeAlgebra_&(%,R)
+
+ (m:SquareMatrix(n,R))*(x:%) == apply((m :: Matrix R),x)
+ coerce v == directProduct(v) :: %
+
+ structuralConstants() == gamma
+
+ coordinates(x) == vector(entries(x :: Rep)$Rep)$Vector(R)
+
+ coordinates(x,b) ==
+ --not (maxIndex b = n) =>
+ -- error("coordinates: your 'basis' has not the right length")
+ m : NonNegativeInteger := (maxIndex b) :: NonNegativeInteger
+ transitionMatrix : Matrix R := new(n,m,0$R)$Matrix(R)
+ for i in 1..m repeat
+ setColumn_!(transitionMatrix,i,coordinates(b.i))
+ res : REC := solve(transitionMatrix,coordinates(x))$LSMP
+ if (not every?(zero?$R,first res.basis)) then
+ error("coordinates: warning your 'basis' is linearly dependent")
+ (res.particular case "failed") =>
+ error("coordinates: first argument is not in linear span of second argument")
+ (res.particular) :: (Vector R)
+
+ basis() == [unitVector(i::PositiveInteger)::% for i in 1..n]
+
+ someBasis() == basis()$%
+
+ rank() == n
+
+ elt(x,i) == elt(x:Rep,i)$Rep
+
+ coerce(x:%):OutputForm ==
+ zero?(x::Rep)$Rep => (0$R) :: OutputForm
+ le : List OutputForm := nil
+ for i in 1..n repeat
+ coef : R := elt(x::Rep,i)
+ not zero?(coef)$R =>
+-- one?(coef)$R =>
+ ((coef) = 1)$R =>
+ -- sy : OutputForm := elt(ls,i)$(List Symbol) :: OutputForm
+ le := cons(elt(ls,i)$(List Symbol) :: OutputForm, le)
+ le := cons(coef :: OutputForm * elt(ls,i)$(List Symbol)_
+ :: OutputForm, le)
+ reduce("+",le)
+
+ x * y ==
+ v : Vector R := new(n,0)
+ for k in 1..n repeat
+ h : R := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ h := h +$R elt(x,i) *$R elt(y,j) *$R elt(gamma.k,i,j )
+ v.k := h
+ directProduct v
+
+
+
+ alternative?() ==
+ for i in 1..n repeat
+ -- expression for check of left alternative is symmetric in i and j:
+ -- expression for check of right alternative is symmetric in j and k:
+ for j in 1..i-1 repeat
+ for k in j..n repeat
+ -- right check
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res - _
+ (elt(gamma.l,j,k)+elt(gamma.l,k,j))*elt(gamma.r,i,l)+_
+ (elt(gamma.l,i,j)*elt(gamma.r,l,k) + elt(gamma.l,i,k)*_
+ elt(gamma.r,l,j) )
+ not zero? res =>
+ messagePrint("algebra is not right alternative")$OutputForm
+ return false
+ for j in i..n repeat
+ for k in 1..j-1 repeat
+ -- left check
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res + _
+ (elt(gamma.l,i,j)+elt(gamma.l,j,i))*elt(gamma.r,l,k)-_
+ (elt(gamma.l,j,k)*elt(gamma.r,i,l) + elt(gamma.l,i,k)*_
+ elt(gamma.r,j,l) )
+ not (zero? res) =>
+ messagePrint("algebra is not left alternative")$OutputForm
+ return false
+
+ for k in j..n repeat
+ -- left check
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res + _
+ (elt(gamma.l,i,j)+elt(gamma.l,j,i))*elt(gamma.r,l,k)-_
+ (elt(gamma.l,j,k)*elt(gamma.r,i,l) + elt(gamma.l,i,k)*_
+ elt(gamma.r,j,l) )
+ not (zero? res) =>
+ messagePrint("algebra is not left alternative")$OutputForm
+ return false
+ -- right check
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res - _
+ (elt(gamma.l,j,k)+elt(gamma.l,k,j))*elt(gamma.r,i,l)+_
+ (elt(gamma.l,i,j)*elt(gamma.r,l,k) + elt(gamma.l,i,k)*_
+ elt(gamma.r,l,j) )
+ not (zero? res) =>
+ messagePrint("algebra is not right alternative")$OutputForm
+ return false
+
+ messagePrint("algebra satisfies 2*associator(a,b,b) = 0 = 2*associator(a,a,b) = 0")$OutputForm
+ true
+
+ -- should be in the category, but is not exported
+-- conditionsForIdempotents b ==
+-- n := rank()
+-- --gamma : Vector Matrix R := structuralConstants b
+-- listOfNumbers : List String := [STRINGIMAGE(q)$Lisp for q in 1..n]
+-- symbolsForCoef : Vector Symbol :=
+-- [concat("%", concat("x", i))::Symbol for i in listOfNumbers]
+-- conditions : List Polynomial R := []
+ -- for k in 1..n repeat
+ -- xk := symbolsForCoef.k
+ -- p : Polynomial R := monomial( - 1$Polynomial(R), [xk], [1] )
+ -- for i in 1..n repeat
+ -- for j in 1..n repeat
+ -- xi := symbolsForCoef.i
+ -- xj := symbolsForCoef.j
+ -- p := p + monomial(_
+ -- elt((gamma.k),i,j) :: Polynomial(R), [xi,xj], [1,1])
+ -- conditions := cons(p,conditions)
+ -- conditions
+
+ associative?() ==
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res + elt(gamma.l,i,j)*elt(gamma.r,l,k)-_
+ elt(gamma.l,j,k)*elt(gamma.r,i,l)
+ not (zero? res) =>
+ messagePrint("algebra is not associative")$OutputForm
+ return false
+ messagePrint("algebra is associative")$OutputForm
+ true
+
+
+ antiAssociative?() ==
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res + elt(gamma.l,i,j)*elt(gamma.r,l,k)+_
+ elt(gamma.l,j,k)*elt(gamma.r,i,l)
+ not (zero? res) =>
+ messagePrint("algebra is not anti-associative")$OutputForm
+ return false
+ messagePrint("algebra is anti-associative")$OutputForm
+ true
+
+ commutative?() ==
+ for i in 1..n repeat
+ for j in (i+1)..n repeat
+ for k in 1..n repeat
+ not ( elt(gamma.k,i,j)=elt(gamma.k,j,i) ) =>
+ messagePrint("algebra is not commutative")$OutputForm
+ return false
+ messagePrint("algebra is commutative")$OutputForm
+ true
+
+ antiCommutative?() ==
+ for i in 1..n repeat
+ for j in i..n repeat
+ for k in 1..n repeat
+ not zero? (i=j => elt(gamma.k,i,i); elt(gamma.k,i,j)+elt(gamma.k,j,i) ) =>
+ messagePrint("algebra is not anti-commutative")$OutputForm
+ return false
+ messagePrint("algebra is anti-commutative")$OutputForm
+ true
+
+ leftAlternative?() ==
+ for i in 1..n repeat
+ -- expression is symmetric in i and j:
+ for j in i..n repeat
+ for k in 1..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res + (elt(gamma.l,i,j)+elt(gamma.l,j,i))*elt(gamma.r,l,k)-_
+ (elt(gamma.l,j,k)*elt(gamma.r,i,l) + elt(gamma.l,i,k)*elt(gamma.r,j,l) )
+ not (zero? res) =>
+ messagePrint("algebra is not left alternative")$OutputForm
+ return false
+ messagePrint("algebra is left alternative")$OutputForm
+ true
+
+
+ rightAlternative?() ==
+ for i in 1..n repeat
+ for j in 1..n repeat
+ -- expression is symmetric in j and k:
+ for k in j..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res - (elt(gamma.l,j,k)+elt(gamma.l,k,j))*elt(gamma.r,i,l)+_
+ (elt(gamma.l,i,j)*elt(gamma.r,l,k) + elt(gamma.l,i,k)*elt(gamma.r,l,j) )
+ not (zero? res) =>
+ messagePrint("algebra is not right alternative")$OutputForm
+ return false
+ messagePrint("algebra is right alternative")$OutputForm
+ true
+
+
+ flexible?() ==
+ for i in 1..n repeat
+ for j in 1..n repeat
+ -- expression is symmetric in i and k:
+ for k in i..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res + elt(gamma.l,i,j)*elt(gamma.r,l,k)-_
+ elt(gamma.l,j,k)*elt(gamma.r,i,l)+_
+ elt(gamma.l,k,j)*elt(gamma.r,l,i)-_
+ elt(gamma.l,j,i)*elt(gamma.r,k,l)
+ not (zero? res) =>
+ messagePrint("algebra is not flexible")$OutputForm
+ return false
+ messagePrint("algebra is flexible")$OutputForm
+ true
+
+ lieAdmissible?() ==
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ res := res_
+ + (elt(gamma.l,i,j)-elt(gamma.l,j,i))*(elt(gamma.r,l,k)-elt(gamma.r,k,l)) _
+ + (elt(gamma.l,j,k)-elt(gamma.l,k,j))*(elt(gamma.r,l,i)-elt(gamma.r,i,l)) _
+ + (elt(gamma.l,k,i)-elt(gamma.l,i,k))*(elt(gamma.r,l,j)-elt(gamma.r,j,l))
+ not (zero? res) =>
+ messagePrint("algebra is not Lie admissible")$OutputForm
+ return false
+ messagePrint("algebra is Lie admissible")$OutputForm
+ true
+
+ jordanAdmissible?() ==
+ recip(2 * 1$R) case "failed" =>
+ messagePrint("this algebra is not Jordan admissible, as 2 is not invertible in the ground ring")$OutputForm
+ false
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for w in 1..n repeat
+ for t in 1..n repeat
+ res := 0$R
+ for l in 1..n repeat
+ for r in 1..n repeat
+ res := res_
+ + (elt(gamma.l,i,j)+elt(gamma.l,j,i))_
+ * (elt(gamma.r,w,k)+elt(gamma.r,k,w))_
+ * (elt(gamma.t,l,r)+elt(gamma.t,r,l))_
+ - (elt(gamma.r,w,k)+elt(gamma.r,k,w))_
+ * (elt(gamma.l,j,r)+elt(gamma.l,r,j))_
+ * (elt(gamma.t,i,l)+elt(gamma.t,l,i))_
+ + (elt(gamma.l,w,j)+elt(gamma.l,j,w))_
+ * (elt(gamma.r,k,i)+elt(gamma.r,i,k))_
+ * (elt(gamma.t,l,r)+elt(gamma.t,r,l))_
+ - (elt(gamma.r,k,i)+elt(gamma.r,k,i))_
+ * (elt(gamma.l,j,r)+elt(gamma.l,r,j))_
+ * (elt(gamma.t,w,l)+elt(gamma.t,l,w))_
+ + (elt(gamma.l,k,j)+elt(gamma.l,j,k))_
+ * (elt(gamma.r,i,w)+elt(gamma.r,w,i))_
+ * (elt(gamma.t,l,r)+elt(gamma.t,r,l))_
+ - (elt(gamma.r,i,w)+elt(gamma.r,w,i))_
+ * (elt(gamma.l,j,r)+elt(gamma.l,r,j))_
+ * (elt(gamma.t,k,l)+elt(gamma.t,l,k))
+ not (zero? res) =>
+ messagePrint("algebra is not Jordan admissible")$OutputForm
+ return false
+ messagePrint("algebra is Jordan admissible")$OutputForm
+ true
+
+ jordanAlgebra?() ==
+ recip(2 * 1$R) case "failed" =>
+ messagePrint("this is not a Jordan algebra, as 2 is not invertible in the ground ring")$OutputForm
+ false
+ not commutative?() =>
+ messagePrint("this is not a Jordan algebra")$OutputForm
+ false
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for l in 1..n repeat
+ for t in 1..n repeat
+ res := 0$R
+ for r in 1..n repeat
+ for s in 1..n repeat
+ res := res + _
+ elt(gamma.r,i,j)*elt(gamma.s,l,k)*elt(gamma.t,r,s) - _
+ elt(gamma.r,l,k)*elt(gamma.s,j,r)*elt(gamma.t,i,s) + _
+ elt(gamma.r,l,j)*elt(gamma.s,k,k)*elt(gamma.t,r,s) - _
+ elt(gamma.r,k,i)*elt(gamma.s,j,r)*elt(gamma.t,l,s) + _
+ elt(gamma.r,k,j)*elt(gamma.s,i,k)*elt(gamma.t,r,s) - _
+ elt(gamma.r,i,l)*elt(gamma.s,j,r)*elt(gamma.t,k,s)
+ not zero? res =>
+ messagePrint("this is not a Jordan algebra")$OutputForm
+ return false
+ messagePrint("this is a Jordan algebra")$OutputForm
+ true
+
+
+ jacobiIdentity?() ==
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for r in 1..n repeat
+ res := 0$R
+ for s in 1..n repeat
+ res := res + elt(gamma.r,i,j)*elt(gamma.s,j,k) +_
+ elt(gamma.r,j,k)*elt(gamma.s,k,i) +_
+ elt(gamma.r,k,i)*elt(gamma.s,i,j)
+ not zero? res =>
+ messagePrint("Jacobi identity does not hold")$OutputForm
+ return false
+ messagePrint("Jacobi identity holds")$OutputForm
+ true
+
+@
+\section{package SCPKG StructuralConstantsPackage}
+<<package SCPKG StructuralConstantsPackage>>=
+)abbrev package SCPKG StructuralConstantsPackage
+++ Authors: J. Grabmeier
+++ Date Created: 02 April 1992
+++ Date Last Updated: 14 April 1992
+++ Basic Operations:
+++ Related Constructors: AlgebraPackage, AlgebraGivenByStructuralConstants
+++ Also See:
+++ AMS Classifications:
+++ Keywords: structural constants
+++ Reference:
+++ Description:
+++ StructuralConstantsPackage provides functions creating
+++ structural constants from a multiplication tables or a basis
+++ of a matrix algebra and other useful functions in this context.
+StructuralConstantsPackage(R:Field): public == private where
+
+ L ==> List
+ S ==> Symbol
+ FRAC ==> Fraction
+ POLY ==> Polynomial
+ V ==> Vector
+ M ==> Matrix
+ REC ==> Record(particular: Union(V R,"failed"),basis: List V R)
+ LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+
+ public ==> with
+ -- what we really want to have here is a matrix over
+ -- linear polynomials in the list of symbols, having arbitrary
+ -- coefficients from a ring extension of R, e.g. FRAC POLY R.
+ structuralConstants : (L S, M FRAC POLY R) -> V M FRAC POLY R
+ ++ structuralConstants(ls,mt) determines the structural constants
+ ++ of an algebra with generators ls and multiplication table mt, the
+ ++ entries of which must be given as linear polynomials in the
+ ++ indeterminates given by ls. The result is in particular useful
+ ++ as fourth argument for \spadtype{AlgebraGivenByStructuralConstants}
+ ++ and \spadtype{GenericNonAssociativeAlgebra}.
+ structuralConstants : (L S, M POLY R) -> V M POLY R
+ ++ structuralConstants(ls,mt) determines the structural constants
+ ++ of an algebra with generators ls and multiplication table mt, the
+ ++ entries of which must be given as linear polynomials in the
+ ++ indeterminates given by ls. The result is in particular useful
+ ++ as fourth argument for \spadtype{AlgebraGivenByStructuralConstants}
+ ++ and \spadtype{GenericNonAssociativeAlgebra}.
+ structuralConstants: L M R -> V M R
+ ++ structuralConstants(basis) takes the basis of a matrix
+ ++ algebra, e.g. the result of \spadfun{basisOfCentroid} and calculates
+ ++ the structural constants.
+ ++ Note, that the it is not checked, whether basis really is a
+ ++ basis of a matrix algebra.
+ coordinates: (M R, L M R) -> V R
+ ++ coordinates(a,[v1,...,vn]) returns the coordinates of \spad{a}
+ ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+
+ private ==> add
+
+ matrix2Vector: M R -> V R
+ matrix2Vector m ==
+ lili : L L R := listOfLists m
+ --li : L R := reduce(concat, listOfLists m)
+ li : L R := reduce(concat, lili)
+ construct(li)$(V R)
+
+ coordinates(x,b) ==
+ m : NonNegativeInteger := (maxIndex b) :: NonNegativeInteger
+ n : NonNegativeInteger := nrows(b.1) * ncols(b.1)
+ transitionMatrix : Matrix R := new(n,m,0$R)$Matrix(R)
+ for i in 1..m repeat
+ setColumn_!(transitionMatrix,i,matrix2Vector(b.i))
+ res : REC := solve(transitionMatrix,matrix2Vector(x))$LSMP
+ if (not every?(zero?$R,first res.basis)) then
+ error("coordinates: the second argument is linearly dependent")
+ (res.particular case "failed") =>
+ error("coordinates: first argument is not in linear span of _
+second argument")
+ (res.particular) :: (Vector R)
+
+ structuralConstants b ==
+ --n := rank()
+ -- be careful with the possibility that b is not a basis
+ m : NonNegativeInteger := (maxIndex b) :: NonNegativeInteger
+ sC : Vector Matrix R := [new(m,m,0$R) for k in 1..m]
+ for i in 1..m repeat
+ for j in 1..m repeat
+ covec : Vector R := coordinates(b.i * b.j, b)$%
+ for k in 1..m repeat
+ setelt( sC.k, i, j, covec.k )
+ sC
+
+ structuralConstants(ls:L S, mt: M POLY R) ==
+ nn := #(ls)
+ nrows(mt) ^= nn or ncols(mt) ^= nn =>
+ error "structuralConstants: size of second argument does not _
+agree with number of generators"
+ gamma : L M POLY R := []
+ lscopy : L S := copy ls
+ while not null lscopy repeat
+ mat : M POLY R := new(nn,nn,0)
+ s : S := first lscopy
+ for i in 1..nn repeat
+ for j in 1..nn repeat
+ p := qelt(mt,i,j)
+ totalDegree(p,ls) > 1 =>
+ error "structuralConstants: entries of second argument _
+must be linear polynomials in the generators"
+ if (c := coefficient(p, s, 1) ) ^= 0 then qsetelt_!(mat,i,j,c)
+ gamma := cons(mat, gamma)
+ lscopy := rest lscopy
+ vector reverse gamma
+
+ structuralConstants(ls:L S, mt: M FRAC POLY R) ==
+ nn := #(ls)
+ nrows(mt) ^= nn or ncols(mt) ^= nn =>
+ error "structuralConstants: size of second argument does not _
+agree with number of generators"
+ gamma : L M FRAC(POLY R) := []
+ lscopy : L S := copy ls
+ while not null lscopy repeat
+ mat : M FRAC(POLY R) := new(nn,nn,0)
+ s : S := first lscopy
+ for i in 1..nn repeat
+ for j in 1..nn repeat
+ r := qelt(mt,i,j)
+ q := denom(r)
+ totalDegree(q,ls) ^= 0 =>
+ error "structuralConstants: entries of second argument _
+must be (linear) polynomials in the generators"
+ p := numer(r)
+ totalDegree(p,ls) > 1 =>
+ error "structuralConstants: entries of second argument _
+must be linear polynomials in the generators"
+ if (c := coefficient(p, s, 1) ) ^= 0 then qsetelt_!(mat,i,j,c/q)
+ gamma := cons(mat, gamma)
+ lscopy := rest lscopy
+ vector reverse gamma
+
+@
+\section{package ALGPKG AlgebraPackage}
+<<package ALGPKG AlgebraPackage>>=
+)abbrev package ALGPKG AlgebraPackage
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 04 March 1991
+++ Date Last Updated: 04 April 1992
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: rank, nucleus, nucloid, structural constants
+++ Reference:
+++ R.S. Pierce: Associative Algebras
+++ Graduate Texts in Mathematics 88
+++ Springer-Verlag, Heidelberg, 1982, ISBN 0-387-90693-2
+++
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++
+++ A. Woerz-Busekros: Algebra in Genetics
+++ Lectures Notes in Biomathematics 36,
+++ Springer-Verlag, Heidelberg, 1980
+++ Description:
+++ AlgebraPackage assembles a variety of useful functions for
+++ general algebras.
+AlgebraPackage(R:IntegralDomain, A: FramedNonAssociativeAlgebra(R)): _
+ public == private where
+
+ V ==> Vector
+ M ==> Matrix
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ REC ==> Record(particular: Union(V R,"failed"),basis: List V R)
+ LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+
+ public ==> with
+
+ leftRank: A -> NonNegativeInteger
+ ++ leftRank(x) determines the number of linearly independent elements
+ ++ in \spad{x*b1},...,\spad{x*bn},
+ ++ where \spad{b=[b1,...,bn]} is a basis.
+ rightRank: A -> NonNegativeInteger
+ ++ rightRank(x) determines the number of linearly independent elements
+ ++ in \spad{b1*x},...,\spad{bn*x},
+ ++ where \spad{b=[b1,...,bn]} is a basis.
+ doubleRank: A -> NonNegativeInteger
+ ++ doubleRank(x) determines the number of linearly
+ ++ independent elements
+ ++ in \spad{b1*x},...,\spad{x*bn},
+ ++ where \spad{b=[b1,...,bn]} is a basis.
+ weakBiRank: A -> NonNegativeInteger
+ ++ weakBiRank(x) determines the number of
+ ++ linearly independent elements
+ ++ in the \spad{bi*x*bj}, \spad{i,j=1,...,n},
+ ++ where \spad{b=[b1,...,bn]} is a basis.
+ biRank: A -> NonNegativeInteger
+ ++ biRank(x) determines the number of linearly independent elements
+ ++ in \spad{x}, \spad{x*bi}, \spad{bi*x}, \spad{bi*x*bj},
+ ++ \spad{i,j=1,...,n},
+ ++ where \spad{b=[b1,...,bn]} is a basis.
+ ++ Note: if \spad{A} has a unit,
+ ++ then \spadfunFrom{doubleRank}{AlgebraPackage},
+ ++ \spadfunFrom{weakBiRank}{AlgebraPackage}
+ ++ and \spadfunFrom{biRank}{AlgebraPackage} coincide.
+ basisOfCommutingElements: () -> List A
+ ++ basisOfCommutingElements() returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{0 = commutator(x,a)} for all
+ ++ \spad{a} in \spad{A}.
+ basisOfLeftAnnihilator: A -> List A
+ ++ basisOfLeftAnnihilator(a) returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{0 = x*a}.
+ basisOfRightAnnihilator: A -> List A
+ ++ basisOfRightAnnihilator(a) returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{0 = a*x}.
+ basisOfLeftNucleus: () -> List A
+ ++ basisOfLeftNucleus() returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{0 = associator(x,a,b)}
+ ++ for all \spad{a},b in \spad{A}.
+ basisOfRightNucleus: () -> List A
+ ++ basisOfRightNucleus() returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{0 = associator(a,b,x)}
+ ++ for all \spad{a},b in \spad{A}.
+ basisOfMiddleNucleus: () -> List A
+ ++ basisOfMiddleNucleus() returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{0 = associator(a,x,b)}
+ ++ for all \spad{a},b in \spad{A}.
+ basisOfNucleus: () -> List A
+ ++ basisOfNucleus() returns a basis of the space of all x of \spad{A} satisfying
+ ++ \spad{associator(x,a,b) = associator(a,x,b) = associator(a,b,x) = 0}
+ ++ for all \spad{a},b in \spad{A}.
+ basisOfCenter: () -> List A
+ ++ basisOfCenter() returns a basis of the space of
+ ++ all x of \spad{A} satisfying \spad{commutator(x,a) = 0} and
+ ++ \spad{associator(x,a,b) = associator(a,x,b) = associator(a,b,x) = 0}
+ ++ for all \spad{a},b in \spad{A}.
+ basisOfLeftNucloid:()-> List Matrix R
+ ++ basisOfLeftNucloid() returns a basis of the space of
+ ++ endomorphisms of \spad{A} as right module.
+ ++ Note: left nucloid coincides with left nucleus if \spad{A} has a unit.
+ basisOfRightNucloid:()-> List Matrix R
+ ++ basisOfRightNucloid() returns a basis of the space of
+ ++ endomorphisms of \spad{A} as left module.
+ ++ Note: right nucloid coincides with right nucleus if \spad{A} has a unit.
+ basisOfCentroid:()-> List Matrix R
+ ++ basisOfCentroid() returns a basis of the centroid, i.e. the
+ ++ endomorphism ring of \spad{A} considered as \spad{(A,A)}-bimodule.
+ radicalOfLeftTraceForm: () -> List A
+ ++ radicalOfLeftTraceForm() returns basis for null space of
+ ++ \spad{leftTraceMatrix()}, if the algebra is
+ ++ associative, alternative or a Jordan algebra, then this
+ ++ space equals the radical (maximal nil ideal) of the algebra.
+ if R has EuclideanDomain then
+ basis : V A -> V A
+ ++ basis(va) selects a basis from the elements of va.
+
+
+ private ==> add
+
+ -- constants
+
+ n : PositiveInteger := rank()$A
+ n2 : PositiveInteger := n*n
+ n3 : PositiveInteger := n*n2
+ gamma : Vector Matrix R := structuralConstants()$A
+
+
+ -- local functions
+
+ convVM : Vector R -> Matrix R
+ -- converts n2-vector to (n,n)-matrix row by row
+ convMV : Matrix R -> Vector R
+ -- converts n-square matrix to n2-vector row by row
+ convVM v ==
+ cond : Matrix(R) := new(n,n,0$R)$M(R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ z := z+1
+ setelt(cond,i,j,v.z)
+ cond
+
+
+ -- convMV m ==
+ -- vec : Vector(R) := new(n*n,0$R)
+ -- z : Integer := 0
+ -- for i in 1..n repeat
+ -- for j in 1..n repeat
+ -- z := z+1
+ -- setelt(vec,z,elt(m,i,j))
+ -- vec
+
+
+ radicalOfLeftTraceForm() ==
+ ma : M R := leftTraceMatrix()$A
+ map(represents, nullSpace ma)$ListFunctions2(Vector R, A)
+
+
+ basisOfLeftAnnihilator a ==
+ ca : M R := transpose (coordinates(a) :: M R)
+ cond : M R := reduce(vertConcat$(M R),
+ [ca*transpose(gamma.i) for i in 1..#gamma])
+ map(represents, nullSpace cond)$ListFunctions2(Vector R, A)
+
+ basisOfRightAnnihilator a ==
+ ca : M R := transpose (coordinates(a) :: M R)
+ cond : M R := reduce(vertConcat$(M R),
+ [ca*(gamma.i) for i in 1..#gamma])
+ map(represents, nullSpace cond)$ListFunctions2(Vector R, A)
+
+ basisOfLeftNucloid() ==
+ cond : Matrix(R) := new(n3,n2,0$R)$M(R)
+ condo: Matrix(R) := new(n3,n2,0$R)$M(R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ r1 : Integer := 0
+ for k in 1..n repeat
+ z := z + 1
+ -- z equals (i-1)*n*n+(j-1)*n+k (loop-invariant)
+ r2 : Integer := i
+ for r in 1..n repeat
+ r1 := r1 + 1
+ -- here r1 equals (k-1)*n+r (loop-invariant)
+ setelt(cond,z,r1,elt(gamma.r,i,j))
+ -- here r2 equals (r-1)*n+i (loop-invariant)
+ setelt(condo,z,r2,-elt(gamma.k,r,j))
+ r2 := r2 + n
+ [convVM(sol) for sol in nullSpace(cond+condo)]
+
+ basisOfCommutingElements() ==
+ --gamma1 := first gamma
+ --gamma1 := gamma1 - transpose gamma1
+ --cond : Matrix(R) := gamma1 :: Matrix(R)
+ --for i in 2..n repeat
+ -- gammak := gamma.i
+ -- gammak := gammak - transpose gammak
+ -- cond := vertConcat(cond, gammak :: Matrix(R))$Matrix(R)
+ --map(represents, nullSpace cond)$ListFunctions2(Vector R, A)
+
+ cond : M R := reduce(vertConcat$(M R),
+ [(gam := gamma.i) - transpose gam for i in 1..#gamma])
+ map(represents, nullSpace cond)$ListFunctions2(Vector R, A)
+
+ basisOfLeftNucleus() ==
+ condi: Matrix(R) := new(n3,n,0$R)$Matrix(R)
+ z : Integer := 0
+ for k in 1..n repeat
+ for j in 1..n repeat
+ for s in 1..n repeat
+ z := z+1
+ for i in 1..n repeat
+ entry : R := 0
+ for l in 1..n repeat
+ entry := entry+elt(gamma.l,j,k)*elt(gamma.s,i,l)_
+ -elt(gamma.l,i,j)*elt(gamma.s,l,k)
+ setelt(condi,z,i,entry)$Matrix(R)
+ map(represents, nullSpace condi)$ListFunctions2(Vector R,A)
+
+ basisOfRightNucleus() ==
+ condo : Matrix(R) := new(n3,n,0$R)$Matrix(R)
+ z : Integer := 0
+ for k in 1..n repeat
+ for j in 1..n repeat
+ for s in 1..n repeat
+ z := z+1
+ for i in 1..n repeat
+ entry : R := 0
+ for l in 1..n repeat
+ entry := entry+elt(gamma.l,k,i)*elt(gamma.s,j,l) _
+ -elt(gamma.l,j,k)*elt(gamma.s,l,i)
+ setelt(condo,z,i,entry)$Matrix(R)
+ map(represents, nullSpace condo)$ListFunctions2(Vector R,A)
+
+ basisOfMiddleNucleus() ==
+ conda : Matrix(R) := new(n3,n,0$R)$Matrix(R)
+ z : Integer := 0
+ for k in 1..n repeat
+ for j in 1..n repeat
+ for s in 1..n repeat
+ z := z+1
+ for i in 1..n repeat
+ entry : R := 0
+ for l in 1..n repeat
+ entry := entry+elt(gamma.l,j,i)*elt(gamma.s,l,k)
+ -elt(gamma.l,i,k)*elt(gamma.s,j,l)
+ setelt(conda,z,i,entry)$Matrix(R)
+ map(represents, nullSpace conda)$ListFunctions2(Vector R,A)
+
+
+ basisOfNucleus() ==
+ condi: Matrix(R) := new(3*n3,n,0$R)$Matrix(R)
+ z : Integer := 0
+ u : Integer := n3
+ w : Integer := 2*n3
+ for k in 1..n repeat
+ for j in 1..n repeat
+ for s in 1..n repeat
+ z := z+1
+ u := u+1
+ w := w+1
+ for i in 1..n repeat
+ entry : R := 0
+ enter : R := 0
+ ent : R := 0
+ for l in 1..n repeat
+ entry := entry + elt(gamma.l,j,k)*elt(gamma.s,i,l) _
+ - elt(gamma.l,i,j)*elt(gamma.s,l,k)
+ enter := enter + elt(gamma.l,k,i)*elt(gamma.s,j,l) _
+ - elt(gamma.l,j,k)*elt(gamma.s,l,i)
+ ent := ent + elt(gamma.l,j,k)*elt(gamma.s,i,l) _
+ - elt(gamma.l,j,i)*elt(gamma.s,l,k)
+ setelt(condi,z,i,entry)$Matrix(R)
+ setelt(condi,u,i,enter)$Matrix(R)
+ setelt(condi,w,i,ent)$Matrix(R)
+ map(represents, nullSpace condi)$ListFunctions2(Vector R,A)
+
+ basisOfCenter() ==
+ gamma1 := first gamma
+ gamma1 := gamma1 - transpose gamma1
+ cond : Matrix(R) := gamma1 :: Matrix(R)
+ for i in 2..n repeat
+ gammak := gamma.i
+ gammak := gammak - transpose gammak
+ cond := vertConcat(cond, gammak :: Matrix(R))$Matrix(R)
+ B := cond :: Matrix(R)
+ condi: Matrix(R) := new(2*n3,n,0$R)$Matrix(R)
+ z : Integer := 0
+ u : Integer := n3
+ for k in 1..n repeat
+ for j in 1..n repeat
+ for s in 1..n repeat
+ z := z+1
+ u := u+1
+ for i in 1..n repeat
+ entry : R := 0
+ enter : R := 0
+ for l in 1..n repeat
+ entry := entry + elt(gamma.l,j,k)*elt(gamma.s,i,l) _
+ - elt(gamma.l,i,j)*elt(gamma.s,l,k)
+ enter := enter + elt(gamma.l,k,i)*elt(gamma.s,j,l) _
+ - elt(gamma.l,j,k)*elt(gamma.s,l,i)
+ setelt(condi,z,i,entry)$Matrix(R)
+ setelt(condi,u,i,enter)$Matrix(R)
+ D := vertConcat(condi,B)$Matrix(R)
+ map(represents, nullSpace D)$ListFunctions2(Vector R, A)
+
+ basisOfRightNucloid() ==
+ cond : Matrix(R) := new(n3,n2,0$R)$M(R)
+ condo: Matrix(R) := new(n3,n2,0$R)$M(R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ r1 : Integer := 0
+ for k in 1..n repeat
+ z := z + 1
+ -- z equals (i-1)*n*n+(j-1)*n+k (loop-invariant)
+ r2 : Integer := i
+ for r in 1..n repeat
+ r1 := r1 + 1
+ -- here r1 equals (k-1)*n+r (loop-invariant)
+ setelt(cond,z,r1,elt(gamma.r,j,i))
+ -- here r2 equals (r-1)*n+i (loop-invariant)
+ setelt(condo,z,r2,-elt(gamma.k,j,r))
+ r2 := r2 + n
+ [convVM(sol) for sol in nullSpace(cond+condo)]
+
+ basisOfCentroid() ==
+ cond : Matrix(R) := new(2*n3,n2,0$R)$M(R)
+ condo: Matrix(R) := new(2*n3,n2,0$R)$M(R)
+ z : Integer := 0
+ u : Integer := n3
+ for i in 1..n repeat
+ for j in 1..n repeat
+ r1 : Integer := 0
+ for k in 1..n repeat
+ z := z + 1
+ u := u + 1
+ -- z equals (i-1)*n*n+(j-1)*n+k (loop-invariant)
+ -- u equals n**3 + (i-1)*n*n+(j-1)*n+k (loop-invariant)
+ r2 : Integer := i
+ for r in 1..n repeat
+ r1 := r1 + 1
+ -- here r1 equals (k-1)*n+r (loop-invariant)
+ setelt(cond,z,r1,elt(gamma.r,i,j))
+ setelt(cond,u,r1,elt(gamma.r,j,i))
+ -- here r2 equals (r-1)*n+i (loop-invariant)
+ setelt(condo,z,r2,-elt(gamma.k,r,j))
+ setelt(condo,u,r2,-elt(gamma.k,j,r))
+ r2 := r2 + n
+ [convVM(sol) for sol in nullSpace(cond+condo)]
+
+
+ doubleRank x ==
+ cond : Matrix(R) := new(2*n,n,0$R)
+ for k in 1..n repeat
+ z : Integer := 0
+ u : Integer := n
+ for j in 1..n repeat
+ z := z+1
+ u := u+1
+ entry : R := 0
+ enter : R := 0
+ for i in 1..n repeat
+ entry := entry + elt(x,i)*elt(gamma.k,j,i)
+ enter := enter + elt(x,i)*elt(gamma.k,i,j)
+ setelt(cond,z,k,entry)$Matrix(R)
+ setelt(cond,u,k,enter)$Matrix(R)
+ rank(cond)$(M R)
+
+ weakBiRank(x) ==
+ cond : Matrix(R) := new(n2,n,0$R)$Matrix(R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ z := z+1
+ for k in 1..n repeat
+ entry : R := 0
+ for l in 1..n repeat
+ for s in 1..n repeat
+ entry:=entry+elt(x,l)*elt(gamma.s,i,l)*elt(gamma.k,s,j)
+ setelt(cond,z,k,entry)$Matrix(R)
+ rank(cond)$(M R)
+
+ biRank(x) ==
+ cond : Matrix(R) := new(n2+2*n+1,n,0$R)$Matrix(R)
+ z : Integer := 0
+ for j in 1..n repeat
+ for i in 1..n repeat
+ z := z+1
+ for k in 1..n repeat
+ entry : R := 0
+ for l in 1..n repeat
+ for s in 1..n repeat
+ entry:=entry+elt(x,l)*elt(gamma.s,i,l)*elt(gamma.k,s,j)
+ setelt(cond,z,k,entry)$Matrix(R)
+ u : Integer := n*n
+ w : Integer := n*(n+1)
+ c := n2 + 2*n + 1
+ for j in 1..n repeat
+ u := u+1
+ w := w+1
+ for k in 1..n repeat
+ entry : R := 0
+ enter : R := 0
+ for i in 1..n repeat
+ entry := entry + elt(x,i)*elt(gamma.k,j,i)
+ enter := enter + elt(x,i)*elt(gamma.k,i,j)
+ setelt(cond,u,k,entry)$Matrix(R)
+ setelt(cond,w,k,enter)$Matrix(R)
+ setelt(cond,c,j, elt(x,j))
+ rank(cond)$(M R)
+
+ leftRank x ==
+ cond : Matrix(R) := new(n,n,0$R)
+ for k in 1..n repeat
+ for j in 1..n repeat
+ entry : R := 0
+ for i in 1..n repeat
+ entry := entry + elt(x,i)*elt(gamma.k,i,j)
+ setelt(cond,j,k,entry)$Matrix(R)
+ rank(cond)$(M R)
+
+ rightRank x ==
+ cond : Matrix(R) := new(n,n,0$R)
+ for k in 1..n repeat
+ for j in 1..n repeat
+ entry : R := 0
+ for i in 1..n repeat
+ entry := entry + elt(x,i)*elt(gamma.k,j,i)
+ setelt(cond,j,k,entry)$Matrix(R)
+ rank(cond)$(M R)
+
+
+ if R has EuclideanDomain then
+ basis va ==
+ v : V A := remove(zero?, va)$(V A)
+ v : V A := removeDuplicates v
+ empty? v => [0$A]
+ m : Matrix R := coerce(coordinates(v.1))$(Matrix R)
+ for i in 2..maxIndex v repeat
+ m := horizConcat(m,coerce(coordinates(v.i))$(Matrix R) )
+ m := rowEchelon m
+ lj : List Integer := []
+ h : Integer := 1
+ mRI : Integer := maxRowIndex m
+ mCI : Integer := maxColIndex m
+ finished? : Boolean := false
+ j : Integer := 1
+ while not finished? repeat
+ not zero? m(h,j) => -- corner found
+ lj := cons(j,lj)
+ h := mRI
+ while zero? m(h,j) repeat h := h-1
+ finished? := (h = mRI)
+ if not finished? then h := h+1
+ if j < mCI then
+ j := j + 1
+ else
+ finished? := true
+ [v.j for j in reverse lj]
+
+@
+\section{package FRNAAF2 FramedNonAssociativeAlgebraFunctions2}
+<<package FRNAAF2 FramedNonAssociativeAlgebraFunctions2>>=
+)abbrev package FRNAAF2 FramedNonAssociativeAlgebraFunctions2
+++ Author: Johannes Grabmeier
+++ Date Created: 28 February 1992
+++ Date Last Updated: 28 February 1992
+++ Basic Operations: map
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: non-associative algebra
+++ References:
+++ Description:
+++ FramedNonAssociativeAlgebraFunctions2 implements functions between
+++ two framed non associative algebra domains defined over different rings.
+++ The function map is used to coerce between algebras over different
+++ domains having the same structural constants.
+
+FramedNonAssociativeAlgebraFunctions2(AR,R,AS,S) : Exports ==
+ Implementation where
+ R : CommutativeRing
+ S : CommutativeRing
+ AR : FramedNonAssociativeAlgebra R
+ AS : FramedNonAssociativeAlgebra S
+ V ==> Vector
+ Exports ==> with
+ map: (R -> S, AR) -> AS
+ ++ map(f,u) maps f onto the coordinates of u to get an element
+ ++ in \spad{AS} via identification of the basis of \spad{AR}
+ ++ as beginning part of the basis of \spad{AS}.
+ Implementation ==> add
+ map(fn : R -> S, u : AR): AS ==
+ rank()$AR > rank()$AS => error("map: ranks of algebras do not fit")
+ vr : V R := coordinates u
+ vs : V S := map(fn,vr)$VectorFunctions2(R,S)
+@
+This line used to read:
+\begin{verbatim}
+ rank()$AR = rank()$AR => represents(vs)$AS
+\end{verbatim}
+but the test is clearly always true and cannot be what was intended.
+Gregory Vanuxem supplied the fix below.
+<<package FRNAAF2 FramedNonAssociativeAlgebraFunctions2>>=
+ rank()$AR = rank()$AS => represents(vs)$AS
+ ba := basis()$AS
+ represents(vs,[ba.i for i in 1..rank()$AR])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ALGSC AlgebraGivenByStructuralConstants>>
+<<package ALGPKG AlgebraPackage>>
+<<package SCPKG StructuralConstantsPackage>>
+<<package FRNAAF2 FramedNonAssociativeAlgebraFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/naalgc.spad.pamphlet b/src/algebra/naalgc.spad.pamphlet
new file mode 100644
index 00000000..b48429ca
--- /dev/null
+++ b/src/algebra/naalgc.spad.pamphlet
@@ -0,0 +1,1260 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra naalgc.spad}
+\author{Johannes Grabmeier, Robert Wisbauer}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category MONAD Monad}
+<<category MONAD Monad>>=
+)abbrev category MONAD Monad
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: *, **
+++ Related Constructors: SemiGroup, Monoid, MonadWithUnit
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Monad, binary operation
+++ Reference:
+++ N. Jacobson: Structure and Representations of Jordan Algebras
+++ AMS, Providence, 1968
+++ Description:
+++ Monad is the class of all multiplicative monads, i.e. sets
+++ with a binary operation.
+Monad(): Category == SetCategory with
+ --operations
+ "*": (%,%) -> %
+ ++ a*b is the product of \spad{a} and b in a set with
+ ++ a binary operation.
+ rightPower: (%,PositiveInteger) -> %
+ ++ rightPower(a,n) returns the \spad{n}-th right power of \spad{a},
+ ++ i.e. \spad{rightPower(a,n) := rightPower(a,n-1) * a} and
+ ++ \spad{rightPower(a,1) := a}.
+ leftPower: (%,PositiveInteger) -> %
+ ++ leftPower(a,n) returns the \spad{n}-th left power of \spad{a},
+ ++ i.e. \spad{leftPower(a,n) := a * leftPower(a,n-1)} and
+ ++ \spad{leftPower(a,1) := a}.
+ "**": (%,PositiveInteger) -> %
+ ++ a**n returns the \spad{n}-th power of \spad{a},
+ ++ defined by repeated squaring.
+ add
+ import RepeatedSquaring(%)
+ x:% ** n:PositiveInteger == expt(x,n)
+ rightPower(a,n) ==
+-- one? n => a
+ (n = 1) => a
+ res := a
+ for i in 1..(n-1) repeat res := res * a
+ res
+ leftPower(a,n) ==
+-- one? n => a
+ (n = 1) => a
+ res := a
+ for i in 1..(n-1) repeat res := a * res
+ res
+
+@
+\section{category MONADWU MonadWithUnit}
+<<category MONADWU MonadWithUnit>>=
+)abbrev category MONADWU MonadWithUnit
+++ Authors: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: *, **, 1
+++ Related Constructors: SemiGroup, Monoid, Monad
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: Monad with unit, binary operation
+++ Reference:
+++ N. Jacobson: Structure and Representations of Jordan Algebras
+++ AMS, Providence, 1968
+++ Description:
+++ MonadWithUnit is the class of multiplicative monads with unit,
+++ i.e. sets with a binary operation and a unit element.
+++ Axioms
+++ leftIdentity("*":(%,%)->%,1) \tab{30} 1*x=x
+++ rightIdentity("*":(%,%)->%,1) \tab{30} x*1=x
+++ Common Additional Axioms
+++ unitsKnown---if "recip" says "failed", that PROVES input wasn't a unit
+MonadWithUnit(): Category == Monad with
+ --constants
+ 1: constant -> %
+ ++ 1 returns the unit element, denoted by 1.
+ --operations
+ one?: % -> Boolean
+ ++ one?(a) tests whether \spad{a} is the unit 1.
+ rightPower: (%,NonNegativeInteger) -> %
+ ++ rightPower(a,n) returns the \spad{n}-th right power of \spad{a},
+ ++ i.e. \spad{rightPower(a,n) := rightPower(a,n-1) * a} and
+ ++ \spad{rightPower(a,0) := 1}.
+ leftPower: (%,NonNegativeInteger) -> %
+ ++ leftPower(a,n) returns the \spad{n}-th left power of \spad{a},
+ ++ i.e. \spad{leftPower(a,n) := a * leftPower(a,n-1)} and
+ ++ \spad{leftPower(a,0) := 1}.
+ "**": (%,NonNegativeInteger) -> %
+ ++ \spad{a**n} returns the \spad{n}-th power of \spad{a},
+ ++ defined by repeated squaring.
+ recip: % -> Union(%,"failed")
+ ++ recip(a) returns an element, which is both a left and a right
+ ++ inverse of \spad{a},
+ ++ or \spad{"failed"} if such an element doesn't exist or cannot
+ ++ be determined (see unitsKnown).
+ leftRecip: % -> Union(%,"failed")
+ ++ leftRecip(a) returns an element, which is a left inverse of \spad{a},
+ ++ or \spad{"failed"} if such an element doesn't exist or cannot
+ ++ be determined (see unitsKnown).
+ rightRecip: % -> Union(%,"failed")
+ ++ rightRecip(a) returns an element, which is a right inverse of
+ ++ \spad{a}, or \spad{"failed"} if such an element doesn't exist
+ ++ or cannot be determined (see unitsKnown).
+ add
+ import RepeatedSquaring(%)
+ one? x == x = 1
+ x:% ** n:NonNegativeInteger ==
+ zero? n => 1
+ expt(x,n pretend PositiveInteger)
+ rightPower(a,n) ==
+ zero? n => 1
+ res := 1
+ for i in 1..n repeat res := res * a
+ res
+ leftPower(a,n) ==
+ zero? n => 1
+ res := 1
+ for i in 1..n repeat res := a * res
+ res
+
+@
+\section{category NARNG NonAssociativeRng}
+<<category NARNG NonAssociativeRng>>=
+)abbrev category NARNG NonAssociativeRng
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 03 July 1991
+++ Basic Operations: +, *, -, **
+++ Related Constructors: Rng, Ring, NonAssociativeRing
+++ Also See:
+++ AMS Classifications:
+++ Keywords: not associative ring
+++ Reference:
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++ Description:
+++ NonAssociativeRng is a basic ring-type structure, not necessarily
+++ commutative or associative, and not necessarily with unit.
+++ Axioms
+++ x*(y+z) = x*y + x*z
+++ (x+y)*z = x*z + y*z
+++ Common Additional Axioms
+++ noZeroDivisors ab = 0 => a=0 or b=0
+NonAssociativeRng(): Category == Join(AbelianGroup,Monad) with
+ associator: (%,%,%) -> %
+ ++ associator(a,b,c) returns \spad{(a*b)*c-a*(b*c)}.
+ commutator: (%,%) -> %
+ ++ commutator(a,b) returns \spad{a*b-b*a}.
+ antiCommutator: (%,%) -> %
+ ++ antiCommutator(a,b) returns \spad{a*b+b*a}.
+ add
+ associator(x,y,z) == (x*y)*z - x*(y*z)
+ commutator(x,y) == x*y - y*x
+ antiCommutator(x,y) == x*y + y*x
+
+@
+\section{category NASRING NonAssociativeRing}
+<<category NASRING NonAssociativeRing>>=
+)abbrev category NASRING NonAssociativeRing
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +, *, -, **
+++ Related Constructors: NonAssociativeRng, Rng, Ring
+++ Also See:
+++ AMS Classifications:
+++ Keywords: non-associative ring with unit
+++ Reference:
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++ Description:
+++ A NonAssociativeRing is a non associative rng which has a unit,
+++ the multiplication is not necessarily commutative or associative.
+NonAssociativeRing(): Category == Join(NonAssociativeRng,MonadWithUnit) with
+ --operations
+ characteristic: -> NonNegativeInteger
+ ++ characteristic() returns the characteristic of the ring.
+ --we can not make this a constant, since some domains are mutable
+ coerce: Integer -> %
+ ++ coerce(n) coerces the integer n to an element of the ring.
+ add
+ n:Integer
+ coerce(n) == n * 1$%
+
+@
+\section{category NAALG NonAssociativeAlgebra}
+<<category NAALG NonAssociativeAlgebra>>=
+)abbrev category NAALG NonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +, -, *, **
+++ Related Constructors: Algebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords: nonassociative algebra
+++ Reference:
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++ Description:
+++ NonAssociativeAlgebra is the category of non associative algebras
+++ (modules which are themselves non associative rngs).
+++ Axioms
+++ r*(a*b) = (r*a)*b = a*(r*b)
+NonAssociativeAlgebra(R:CommutativeRing): Category == _
+ Join(NonAssociativeRng, Module R) with
+ --operations
+ plenaryPower : (%,PositiveInteger) -> %
+ ++ plenaryPower(a,n) is recursively defined to be
+ ++ \spad{plenaryPower(a,n-1)*plenaryPower(a,n-1)} for \spad{n>1}
+ ++ and \spad{a} for \spad{n=1}.
+ add
+ plenaryPower(a,n) ==
+-- one? n => a
+ ( n = 1 ) => a
+ n1 : PositiveInteger := (n-1)::NonNegativeInteger::PositiveInteger
+ plenaryPower(a,n1) * plenaryPower(a,n1)
+
+@
+\section{category FINAALG FiniteRankNonAssociativeAlgebra}
+<<category FINAALG FiniteRankNonAssociativeAlgebra>>=
+)abbrev category FINAALG FiniteRankNonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 12 June 1991
+++ Basic Operations: +,-,*,**, someBasis
+++ Related Constructors: FramedNonAssociativeAlgebra, FramedAlgebra,
+++ FiniteRankAssociativeAlgebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords: nonassociative algebra, basis
+++ References:
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++
+++ R. Wisbauer: Bimodule Structure of Algebra
+++ Lecture Notes Univ. Duesseldorf 1991
+++ Description:
+++ A FiniteRankNonAssociativeAlgebra is a non associative algebra over
+++ a commutative ring R which is a free \spad{R}-module of finite rank.
+FiniteRankNonAssociativeAlgebra(R:CommutativeRing):
+ Category == NonAssociativeAlgebra R with
+ someBasis : () -> Vector %
+ ++ someBasis() returns some \spad{R}-module basis.
+ rank : () -> PositiveInteger
+ ++ rank() returns the rank of the algebra as \spad{R}-module.
+ conditionsForIdempotents: Vector % -> List Polynomial R
+ ++ conditionsForIdempotents([v1,...,vn]) determines a complete list
+ ++ of polynomial equations for the coefficients of idempotents
+ ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+ structuralConstants: Vector % -> Vector Matrix R
+ ++ structuralConstants([v1,v2,...,vm]) calculates the structural
+ ++ constants \spad{[(gammaijk) for k in 1..m]} defined by
+ ++ \spad{vi * vj = gammaij1 * v1 + ... + gammaijm * vm},
+ ++ where \spad{[v1,...,vm]} is an \spad{R}-module basis
+ ++ of a subalgebra.
+ leftRegularRepresentation: (% , Vector %) -> Matrix R
+ ++ leftRegularRepresentation(a,[v1,...,vn]) returns the matrix of
+ ++ the linear map defined by left multiplication by \spad{a}
+ ++ with respect to the \spad{R}-module basis \spad{[v1,...,vn]}.
+ rightRegularRepresentation: (% , Vector %) -> Matrix R
+ ++ rightRegularRepresentation(a,[v1,...,vn]) returns the matrix of
+ ++ the linear map defined by right multiplication by \spad{a}
+ ++ with respect to the \spad{R}-module basis \spad{[v1,...,vn]}.
+ leftTrace: % -> R
+ ++ leftTrace(a) returns the trace of the left regular representation
+ ++ of \spad{a}.
+ rightTrace: % -> R
+ ++ rightTrace(a) returns the trace of the right regular representation
+ ++ of \spad{a}.
+ leftNorm: % -> R
+ ++ leftNorm(a) returns the determinant of the left regular representation
+ ++ of \spad{a}.
+ rightNorm: % -> R
+ ++ rightNorm(a) returns the determinant of the right regular
+ ++ representation of \spad{a}.
+ coordinates: (%, Vector %) -> Vector R
+ ++ coordinates(a,[v1,...,vn]) returns the coordinates of \spad{a}
+ ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+ coordinates: (Vector %, Vector %) -> Matrix R
+ ++ coordinates([a1,...,am],[v1,...,vn]) returns a matrix whose
+ ++ i-th row is formed by the coordinates of \spad{ai}
+ ++ with respect to the \spad{R}-module basis \spad{v1},...,\spad{vn}.
+ represents: (Vector R, Vector %) -> %
+ ++ represents([a1,...,am],[v1,...,vm]) returns the linear
+ ++ combination \spad{a1*vm + ... + an*vm}.
+ leftDiscriminant: Vector % -> R
+ ++ leftDiscriminant([v1,...,vn]) returns the determinant of the
+ ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row
+ ++ and \spad{j}-th column is given by the left trace of the product
+ ++ \spad{vi*vj}.
+ ++ Note: the same as \spad{determinant(leftTraceMatrix([v1,...,vn]))}.
+ rightDiscriminant: Vector % -> R
+ ++ rightDiscriminant([v1,...,vn]) returns the determinant of the
+ ++ \spad{n}-by-\spad{n} matrix whose element at the \spad{i}-th row
+ ++ and \spad{j}-th column is given by the right trace of the product
+ ++ \spad{vi*vj}.
+ ++ Note: the same as \spad{determinant(rightTraceMatrix([v1,...,vn]))}.
+ leftTraceMatrix: Vector % -> Matrix R
+ ++ leftTraceMatrix([v1,...,vn]) is the \spad{n}-by-\spad{n} matrix
+ ++ whose element at the \spad{i}-th row and \spad{j}-th column is given
+ ++ by the left trace of the product \spad{vi*vj}.
+ rightTraceMatrix: Vector % -> Matrix R
+ ++ rightTraceMatrix([v1,...,vn]) is the \spad{n}-by-\spad{n} matrix
+ ++ whose element at the \spad{i}-th row and \spad{j}-th column is given
+ ++ by the right trace of the product \spad{vi*vj}.
+ leftCharacteristicPolynomial: % -> SparseUnivariatePolynomial R
+ ++ leftCharacteristicPolynomial(a) returns the characteristic
+ ++ polynomial of the left regular representation of \spad{a}
+ ++ with respect to any basis.
+ rightCharacteristicPolynomial: % -> SparseUnivariatePolynomial R
+ ++ rightCharacteristicPolynomial(a) returns the characteristic
+ ++ polynomial of the right regular representation of \spad{a}
+ ++ with respect to any basis.
+
+ --we not necessarily have a unit
+ --if R has CharacteristicZero then CharacteristicZero
+ --if R has CharacteristicNonZero then CharacteristicNonZero
+
+ commutative?:()-> Boolean
+ ++ commutative?() tests if multiplication in the algebra
+ ++ is commutative.
+ antiCommutative?:()-> Boolean
+ ++ antiCommutative?() tests if \spad{a*a = 0}
+ ++ for all \spad{a} in the algebra.
+ ++ Note: this implies \spad{a*b + b*a = 0} for all \spad{a} and \spad{b}.
+ associative?:()-> Boolean
+ ++ associative?() tests if multiplication in algebra
+ ++ is associative.
+ antiAssociative?:()-> Boolean
+ ++ antiAssociative?() tests if multiplication in algebra
+ ++ is anti-associative, i.e. \spad{(a*b)*c + a*(b*c) = 0}
+ ++ for all \spad{a},b,c in the algebra.
+ leftAlternative?: ()-> Boolean
+ ++ leftAlternative?() tests if \spad{2*associator(a,a,b) = 0}
+ ++ for all \spad{a}, b in the algebra.
+ ++ Note: we only can test this; in general we don't know
+ ++ whether \spad{2*a=0} implies \spad{a=0}.
+ rightAlternative?: ()-> Boolean
+ ++ rightAlternative?() tests if \spad{2*associator(a,b,b) = 0}
+ ++ for all \spad{a}, b in the algebra.
+ ++ Note: we only can test this; in general we don't know
+ ++ whether \spad{2*a=0} implies \spad{a=0}.
+ flexible?: ()-> Boolean
+ ++ flexible?() tests if \spad{2*associator(a,b,a) = 0}
+ ++ for all \spad{a}, b in the algebra.
+ ++ Note: we only can test this; in general we don't know
+ ++ whether \spad{2*a=0} implies \spad{a=0}.
+ alternative?: ()-> Boolean
+ ++ alternative?() tests if
+ ++ \spad{2*associator(a,a,b) = 0 = 2*associator(a,b,b)}
+ ++ for all \spad{a}, b in the algebra.
+ ++ Note: we only can test this; in general we don't know
+ ++ whether \spad{2*a=0} implies \spad{a=0}.
+ powerAssociative?:()-> Boolean
+ ++ powerAssociative?() tests if all subalgebras
+ ++ generated by a single element are associative.
+ jacobiIdentity?:() -> Boolean
+ ++ jacobiIdentity?() tests if \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0}
+ ++ for all \spad{a},b,c in the algebra. For example, this holds
+ ++ for crossed products of 3-dimensional vectors.
+ lieAdmissible?: () -> Boolean
+ ++ lieAdmissible?() tests if the algebra defined by the commutators
+ ++ is a Lie algebra, i.e. satisfies the Jacobi identity.
+ ++ The property of anticommutativity follows from definition.
+ jordanAdmissible?: () -> Boolean
+ ++ jordanAdmissible?() tests if 2 is invertible in the
+ ++ coefficient domain and the multiplication defined by
+ ++ \spad{(1/2)(a*b+b*a)} determines a
+ ++ Jordan algebra, i.e. satisfies the Jordan identity.
+ ++ The property of \spadatt{commutative("*")}
+ ++ follows from by definition.
+ noncommutativeJordanAlgebra?: () -> Boolean
+ ++ noncommutativeJordanAlgebra?() tests if the algebra
+ ++ is flexible and Jordan admissible.
+ jordanAlgebra?:() -> Boolean
+ ++ jordanAlgebra?() tests if the algebra is commutative,
+ ++ characteristic is not 2, and \spad{(a*b)*a**2 - a*(b*a**2) = 0}
+ ++ for all \spad{a},b,c in the algebra (Jordan identity).
+ ++ Example:
+ ++ for every associative algebra \spad{(A,+,@)} we can construct a
+ ++ Jordan algebra \spad{(A,+,*)}, where \spad{a*b := (a@b+b@a)/2}.
+ lieAlgebra?:() -> Boolean
+ ++ lieAlgebra?() tests if the algebra is anticommutative
+ ++ and \spad{(a*b)*c + (b*c)*a + (c*a)*b = 0}
+ ++ for all \spad{a},b,c in the algebra (Jacobi identity).
+ ++ Example:
+ ++ for every associative algebra \spad{(A,+,@)} we can construct a
+ ++ Lie algebra \spad{(A,+,*)}, where \spad{a*b := a@b-b@a}.
+
+ if R has IntegralDomain then
+ -- we not neccessarily have a unit, hence we don't inherit
+ -- the next 3 functions anc hence copy them from MonadWithUnit:
+ recip: % -> Union(%,"failed")
+ ++ recip(a) returns an element, which is both a left and a right
+ ++ inverse of \spad{a},
+ ++ or \spad{"failed"} if there is no unit element, if such an
+ ++ element doesn't exist or cannot be determined (see unitsKnown).
+ leftRecip: % -> Union(%,"failed")
+ ++ leftRecip(a) returns an element, which is a left inverse of \spad{a},
+ ++ or \spad{"failed"} if there is no unit element, if such an
+ ++ element doesn't exist or cannot be determined (see unitsKnown).
+ rightRecip: % -> Union(%,"failed")
+ ++ rightRecip(a) returns an element, which is a right inverse of
+ ++ \spad{a},
+ ++ or \spad{"failed"} if there is no unit element, if such an
+ ++ element doesn't exist or cannot be determined (see unitsKnown).
+ associatorDependence:() -> List Vector R
+ ++ associatorDependence() looks for the associator identities, i.e.
+ ++ finds a basis of the solutions of the linear combinations of the
+ ++ six permutations of \spad{associator(a,b,c)} which yield 0,
+ ++ for all \spad{a},b,c in the algebra.
+ ++ The order of the permutations is \spad{123 231 312 132 321 213}.
+ leftMinimalPolynomial : % -> SparseUnivariatePolynomial R
+ ++ leftMinimalPolynomial(a) returns the polynomial determined by the
+ ++ smallest non-trivial linear combination of left powers of \spad{a}.
+ ++ Note: the polynomial never has a constant term as in general
+ ++ the algebra has no unit.
+ rightMinimalPolynomial : % -> SparseUnivariatePolynomial R
+ ++ rightMinimalPolynomial(a) returns the polynomial determined by the
+ ++ smallest non-trivial linear
+ ++ combination of right powers of \spad{a}.
+ ++ Note: the polynomial never has a constant term as in general
+ ++ the algebra has no unit.
+ leftUnits:() -> Union(Record(particular: %, basis: List %), "failed")
+ ++ leftUnits() returns the affine space of all left units of the
+ ++ algebra, or \spad{"failed"} if there is none.
+ rightUnits:() -> Union(Record(particular: %, basis: List %), "failed")
+ ++ rightUnits() returns the affine space of all right units of the
+ ++ algebra, or \spad{"failed"} if there is none.
+ leftUnit:() -> Union(%, "failed")
+ ++ leftUnit() returns a left unit of the algebra
+ ++ (not necessarily unique), or \spad{"failed"} if there is none.
+ rightUnit:() -> Union(%, "failed")
+ ++ rightUnit() returns a right unit of the algebra
+ ++ (not necessarily unique), or \spad{"failed"} if there is none.
+ unit:() -> Union(%, "failed")
+ ++ unit() returns a unit of the algebra (necessarily unique),
+ ++ or \spad{"failed"} if there is none.
+ -- we not necessarily have a unit, hence we can't say anything
+ -- about characteristic
+ -- if R has CharacteristicZero then CharacteristicZero
+ -- if R has CharacteristicNonZero then CharacteristicNonZero
+ unitsKnown
+ ++ unitsKnown means that \spadfun{recip} truly yields reciprocal
+ ++ or \spad{"failed"} if not a unit,
+ ++ similarly for \spadfun{leftRecip} and
+ ++ \spadfun{rightRecip}. The reason is that we use left, respectively
+ ++ right, minimal polynomials to decide this question.
+
+ add
+ --n := rank()
+ --b := someBasis()
+ --gamma : Vector Matrix R := structuralConstants b
+ -- here is a problem: there seems to be a problem having local
+ -- variables in the capsule of a category, furthermore
+ -- see the commented code of conditionsForIdempotents, where
+ -- we call structuralConstants, which also doesn't work
+ -- at runtime, i.e. is not properly inherited, hence for
+ -- the moment we put the code for
+ -- conditionsForIdempotents, structuralConstants, unit, leftUnit,
+ -- rightUnit into the domain constructor ALGSC
+ V ==> Vector
+ M ==> Matrix
+ REC ==> Record(particular: Union(V R,"failed"),basis: List V R)
+ LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+
+
+ SUP ==> SparseUnivariatePolynomial
+ NNI ==> NonNegativeInteger
+ -- next 2 functions: use a general characteristicPolynomial
+ leftCharacteristicPolynomial a ==
+ n := rank()$%
+ ma : Matrix R := leftRegularRepresentation(a,someBasis()$%)
+ mb : Matrix SUP R := zero(n,n)
+ for i in 1..n repeat
+ for j in 1..n repeat
+ mb(i,j):=
+ i=j => monomial(ma(i,j),0)$SUP(R) - monomial(1,1)$SUP(R)
+ monomial(ma(i,j),1)$SUP(R)
+ determinant mb
+
+ rightCharacteristicPolynomial a ==
+ n := rank()$%
+ ma : Matrix R := rightRegularRepresentation(a,someBasis()$%)
+ mb : Matrix SUP R := zero(n,n)
+ for i in 1..n repeat
+ for j in 1..n repeat
+ mb(i,j):=
+ i=j => monomial(ma(i,j),0)$SUP(R) - monomial(1,1)$SUP(R)
+ monomial(ma(i,j),1)$SUP(R)
+ determinant mb
+
+
+
+ leftTrace a ==
+ t : R := 0
+ ma : Matrix R := leftRegularRepresentation(a,someBasis()$%)
+ for i in 1..rank()$% repeat
+ t := t + elt(ma,i,i)
+ t
+
+ rightTrace a ==
+ t : R := 0
+ ma : Matrix R := rightRegularRepresentation(a,someBasis()$%)
+ for i in 1..rank()$% repeat
+ t := t + elt(ma,i,i)
+ t
+
+ leftNorm a == determinant leftRegularRepresentation(a,someBasis()$%)
+
+ rightNorm a == determinant rightRegularRepresentation(a,someBasis()$%)
+
+
+ antiAssociative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? ( (b.i*b.j)*b.k + b.i*(b.j*b.k) ) =>
+ messagePrint("algebra is not anti-associative")$OutputForm
+ return false
+ messagePrint("algebra is anti-associative")$OutputForm
+ true
+
+
+ jordanAdmissible?() ==
+ b := someBasis()
+ n := rank()
+ recip(2 * 1$R) case "failed" =>
+ messagePrint("this algebra is not Jordan admissible, as 2 is not invertible in the ground ring")$OutputForm
+ false
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for l in 1..n repeat
+ not zero? ( _
+ antiCommutator(antiCommutator(b.i,b.j),antiCommutator(b.l,b.k)) + _
+ antiCommutator(antiCommutator(b.l,b.j),antiCommutator(b.k,b.i)) + _
+ antiCommutator(antiCommutator(b.k,b.j),antiCommutator(b.i,b.l)) _
+ ) =>
+ messagePrint("this algebra is not Jordan admissible")$OutputForm
+ return false
+ messagePrint("this algebra is Jordan admissible")$OutputForm
+ true
+
+ lieAdmissible?() ==
+ n := rank()
+ b := someBasis()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? (commutator(commutator(b.i,b.j),b.k) _
+ + commutator(commutator(b.j,b.k),b.i) _
+ + commutator(commutator(b.k,b.i),b.j)) =>
+ messagePrint("this algebra is not Lie admissible")$OutputForm
+ return false
+ messagePrint("this algebra is Lie admissible")$OutputForm
+ true
+
+ -- conditionsForIdempotents b ==
+ -- n := rank()
+ -- gamma : Vector Matrix R := structuralConstants b
+ -- listOfNumbers : List String := [STRINGIMAGE(q)$Lisp for q in 1..n]
+ -- symbolsForCoef : Vector Symbol :=
+ -- [concat("%", concat("x", i))::Symbol for i in listOfNumbers]
+ -- conditions : List Polynomial R := []
+ -- for k in 1..n repeat
+ -- xk := symbolsForCoef.k
+ -- p : Polynomial R := monomial( - 1$Polynomial(R), [xk], [1] )
+ -- for i in 1..n repeat
+ -- for j in 1..n repeat
+ -- xi := symbolsForCoef.i
+ -- xj := symbolsForCoef.j
+ -- p := p + monomial(_
+ -- elt((gamma.k),i,j) :: Polynomial(R), [xi,xj], [1,1])
+ -- conditions := cons(p,conditions)
+ -- conditions
+
+ structuralConstants b ==
+ --n := rank()
+ -- be careful with the possibility that b is not a basis
+ m : NonNegativeInteger := (maxIndex b) :: NonNegativeInteger
+ sC : Vector Matrix R := [new(m,m,0$R) for k in 1..m]
+ for i in 1..m repeat
+ for j in 1..m repeat
+ covec : Vector R := coordinates(b.i * b.j, b)
+ for k in 1..m repeat
+ setelt( sC.k, i, j, covec.k )
+ sC
+
+ if R has IntegralDomain then
+
+ leftRecip x ==
+ zero? x => "failed"
+ lu := leftUnit()
+ lu case "failed" => "failed"
+ b := someBasis()
+ xx : % := (lu :: %)
+ k : PositiveInteger := 1
+ cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+ listOfPowers : List % := [xx]
+ while rank(cond) = k repeat
+ k := k+1
+ xx := xx*x
+ listOfPowers := cons(xx,listOfPowers)
+ cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+ vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+ invC := recip vectorOfCoef.1
+ invC case "failed" => "failed"
+ invCR : R := - (invC :: R)
+ reduce(_+,[(invCR*vectorOfCoef.i)*power for i in _
+ 2..maxIndex vectorOfCoef for power in reverse listOfPowers])
+
+
+ rightRecip x ==
+ zero? x => "failed"
+ ru := rightUnit()
+ ru case "failed" => "failed"
+ b := someBasis()
+ xx : % := (ru :: %)
+ k : PositiveInteger := 1
+ cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+ listOfPowers : List % := [xx]
+ while rank(cond) = k repeat
+ k := k+1
+ xx := x*xx
+ listOfPowers := cons(xx,listOfPowers)
+ cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+ vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+ invC := recip vectorOfCoef.1
+ invC case "failed" => "failed"
+ invCR : R := - (invC :: R)
+ reduce(_+,[(invCR*vectorOfCoef.i)*power for i in _
+ 2..maxIndex vectorOfCoef for power in reverse listOfPowers])
+
+
+ recip x ==
+ lrx := leftRecip x
+ lrx case "failed" => "failed"
+ rrx := rightRecip x
+ rrx case "failed" => "failed"
+ (lrx :: %) ^= (rrx :: %) => "failed"
+ lrx :: %
+
+
+ leftMinimalPolynomial x ==
+ zero? x => monomial(1$R,1)$(SparseUnivariatePolynomial R)
+ b := someBasis()
+ xx : % := x
+ k : PositiveInteger := 1
+ cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+ while rank(cond) = k repeat
+ k := k+1
+ xx := x*xx
+ cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+ vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+ res : SparseUnivariatePolynomial R := 0
+ for i in 1..k repeat
+ res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial R)
+ res
+
+ rightMinimalPolynomial x ==
+ zero? x => monomial(1$R,1)$(SparseUnivariatePolynomial R)
+ b := someBasis()
+ xx : % := x
+ k : PositiveInteger := 1
+ cond : Matrix R := coordinates(xx,b) :: Matrix(R)
+ while rank(cond) = k repeat
+ k := k+1
+ xx := xx*x
+ cond := horizConcat(cond, coordinates(xx,b) :: Matrix(R) )
+ vectorOfCoef : Vector R := (nullSpace(cond)$Matrix(R)).first
+ res : SparseUnivariatePolynomial R := 0
+ for i in 1..k repeat
+ res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial R)
+ res
+
+
+
+ associatorDependence() ==
+ n := rank()
+ b := someBasis()
+ cond : Matrix(R) := new(n**4,6,0$R)$Matrix(R)
+ z : Integer := 0
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ a123 : Vector R := coordinates(associator(b.i,b.j,b.k),b)
+ a231 : Vector R := coordinates(associator(b.j,b.k,b.i),b)
+ a312 : Vector R := coordinates(associator(b.k,b.i,b.j),b)
+ a132 : Vector R := coordinates(associator(b.i,b.k,b.j),b)
+ a321 : Vector R := coordinates(associator(b.k,b.j,b.i),b)
+ a213 : Vector R := coordinates(associator(b.j,b.i,b.k),b)
+ for r in 1..n repeat
+ z:= z+1
+ setelt(cond,z,1,elt(a123,r))
+ setelt(cond,z,2,elt(a231,r))
+ setelt(cond,z,3,elt(a312,r))
+ setelt(cond,z,4,elt(a132,r))
+ setelt(cond,z,5,elt(a321,r))
+ setelt(cond,z,6,elt(a213,r))
+ nullSpace(cond)
+
+ jacobiIdentity?() ==
+ n := rank()
+ b := someBasis()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? ((b.i*b.j)*b.k + (b.j*b.k)*b.i + (b.k*b.i)*b.j) =>
+ messagePrint("Jacobi identity does not hold")$OutputForm
+ return false
+ messagePrint("Jacobi identity holds")$OutputForm
+ true
+
+ lieAlgebra?() ==
+ not antiCommutative?() =>
+ messagePrint("this is not a Lie algebra")$OutputForm
+ false
+ not jacobiIdentity?() =>
+ messagePrint("this is not a Lie algebra")$OutputForm
+ false
+ messagePrint("this is a Lie algebra")$OutputForm
+ true
+
+
+
+
+ jordanAlgebra?() ==
+ b := someBasis()
+ n := rank()
+ recip(2 * 1$R) case "failed" =>
+ messagePrint("this is not a Jordan algebra, as 2 is not invertible in the ground ring")$OutputForm
+ false
+ not commutative?() =>
+ messagePrint("this is not a Jordan algebra")$OutputForm
+ false
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ for l in 1..n repeat
+ not zero? (associator(b.i,b.j,b.l*b.k)+_
+ associator(b.l,b.j,b.k*b.i)+associator(b.k,b.j,b.i*b.l)) =>
+ messagePrint("not a Jordan algebra")$OutputForm
+ return false
+ messagePrint("this is a Jordan algebra")$OutputForm
+ true
+
+ noncommutativeJordanAlgebra?() ==
+ b := someBasis()
+ n := rank()
+ recip(2 * 1$R) case "failed" =>
+ messagePrint("this is not a noncommutative Jordan algebra, as 2 is not invertible in the ground ring")$OutputForm
+ false
+ not flexible?()$% =>
+ messagePrint("this is not a noncommutative Jordan algebra, as it is not flexible")$OutputForm
+ false
+ not jordanAdmissible?()$% =>
+ messagePrint("this is not a noncommutative Jordan algebra, as it is not Jordan admissible")$OutputForm
+ false
+ messagePrint("this is a noncommutative Jordan algebra")$OutputForm
+ true
+
+ antiCommutative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in i..n repeat
+ not zero? (i=j => b.i*b.i; b.i*b.j + b.j*b.i) =>
+ messagePrint("algebra is not anti-commutative")$OutputForm
+ return false
+ messagePrint("algebra is anti-commutative")$OutputForm
+ true
+
+ commutative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in i+1..n repeat
+ not zero? commutator(b.i,b.j) =>
+ messagePrint("algebra is not commutative")$OutputForm
+ return false
+ messagePrint("algebra is commutative")$OutputForm
+ true
+
+
+ associative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? associator(b.i,b.j,b.k) =>
+ messagePrint("algebra is not associative")$OutputForm
+ return false
+ messagePrint("algebra is associative")$OutputForm
+ true
+
+ leftAlternative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? (associator(b.i,b.j,b.k) + associator(b.j,b.i,b.k)) =>
+ messagePrint("algebra is not left alternative")$OutputForm
+ return false
+ messagePrint("algebra satisfies 2*associator(a,a,b) = 0")$OutputForm
+ true
+
+ rightAlternative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? (associator(b.i,b.j,b.k) + associator(b.i,b.k,b.j)) =>
+ messagePrint("algebra is not right alternative")$OutputForm
+ return false
+ messagePrint("algebra satisfies 2*associator(a,b,b) = 0")$OutputForm
+ true
+
+ flexible?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? (associator(b.i,b.j,b.k) + associator(b.k,b.j,b.i)) =>
+ messagePrint("algebra is not flexible")$OutputForm
+ return false
+ messagePrint("algebra satisfies 2*associator(a,b,a) = 0")$OutputForm
+ true
+
+ alternative?() ==
+ b := someBasis()
+ n := rank()
+ for i in 1..n repeat
+ for j in 1..n repeat
+ for k in 1..n repeat
+ not zero? (associator(b.i,b.j,b.k) + associator(b.j,b.i,b.k)) =>
+ messagePrint("algebra is not alternative")$OutputForm
+ return false
+ not zero? (associator(b.i,b.j,b.k) + associator(b.i,b.k,b.j)) =>
+ messagePrint("algebra is not alternative")$OutputForm
+ return false
+ messagePrint("algebra satisfies 2*associator(a,b,b) = 0 = 2*associator(a,a,b) = 0")$OutputForm
+ true
+
+ leftDiscriminant v == determinant leftTraceMatrix v
+ rightDiscriminant v == determinant rightTraceMatrix v
+
+ coordinates(v:Vector %, b:Vector %) ==
+ m := new(#v, #b, 0)$Matrix(R)
+ for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
+ setRow_!(m, j, coordinates(qelt(v, i), b))
+ m
+
+ represents(v, b) ==
+ m := minIndex v - 1
+ reduce(_+,[v(i+m) * b(i+m) for i in 1..maxIndex b])
+
+ leftTraceMatrix v ==
+ matrix [[leftTrace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
+ for i in minIndex v .. maxIndex v]$List(List R)
+
+ rightTraceMatrix v ==
+ matrix [[rightTrace(v.i*v.j) for j in minIndex v..maxIndex v]$List(R)
+ for i in minIndex v .. maxIndex v]$List(List R)
+
+ leftRegularRepresentation(x, b) ==
+ m := minIndex b - 1
+ matrix
+ [parts coordinates(x*b(i+m),b) for i in 1..rank()]$List(List R)
+
+ rightRegularRepresentation(x, b) ==
+ m := minIndex b - 1
+ matrix
+ [parts coordinates(b(i+m)*x,b) for i in 1..rank()]$List(List R)
+
+@
+\section{category FRNAALG FramedNonAssociativeAlgebra}
+<<category FRNAALG FramedNonAssociativeAlgebra>>=
+)abbrev category FRNAALG FramedNonAssociativeAlgebra
+++ Author: J. Grabmeier, R. Wisbauer
+++ Date Created: 01 March 1991
+++ Date Last Updated: 11 June 1991
+++ Basic Operations: +,-,*,**,basis
+++ Related Constructors: FiniteRankNonAssociativeAlgebra, FramedAlgebra,
+++ FiniteRankAssociativeAlgebra
+++ Also See:
+++ AMS Classifications:
+++ Keywords: nonassociative algebra, basis
+++ Reference:
+++ R.D. Schafer: An Introduction to Nonassociative Algebras
+++ Academic Press, New York, 1966
+++ Description:
+++ FramedNonAssociativeAlgebra(R) is a
+++ \spadtype{FiniteRankNonAssociativeAlgebra} (i.e. a non associative
+++ algebra over R which is a free \spad{R}-module of finite rank)
+++ over a commutative ring R together with a fixed \spad{R}-module basis.
+FramedNonAssociativeAlgebra(R:CommutativeRing):
+ Category == FiniteRankNonAssociativeAlgebra(R) with
+ --operations
+ basis: () -> Vector %
+ ++ basis() returns the fixed \spad{R}-module basis.
+ coordinates: % -> Vector R
+ ++ coordinates(a) returns the coordinates of \spad{a}
+ ++ with respect to the
+ ++ fixed \spad{R}-module basis.
+ coordinates: Vector % -> Matrix R
+ ++ coordinates([a1,...,am]) returns a matrix whose i-th row
+ ++ is formed by the coordinates of \spad{ai} with respect to the
+ ++ fixed \spad{R}-module basis.
+ elt : (%,Integer) -> R
+ ++ elt(a,i) returns the i-th coefficient of \spad{a} with respect to the
+ ++ fixed \spad{R}-module basis.
+ structuralConstants:() -> Vector Matrix R
+ ++ structuralConstants() calculates the structural constants
+ ++ \spad{[(gammaijk) for k in 1..rank()]} defined by
+ ++ \spad{vi * vj = gammaij1 * v1 + ... + gammaijn * vn},
+ ++ where \spad{v1},...,\spad{vn} is the fixed \spad{R}-module basis.
+ conditionsForIdempotents: () -> List Polynomial R
+ ++ conditionsForIdempotents() determines a complete list
+ ++ of polynomial equations for the coefficients of idempotents
+ ++ with respect to the fixed \spad{R}-module basis.
+ represents: Vector R -> %
+ ++ represents([a1,...,an]) returns \spad{a1*v1 + ... + an*vn},
+ ++ where \spad{v1}, ..., \spad{vn} are the elements of the
+ ++ fixed \spad{R}-module basis.
+ convert: % -> Vector R
+ ++ convert(a) returns the coordinates of \spad{a} with respect to the
+ ++ fixed \spad{R}-module basis.
+ convert: Vector R -> %
+ ++ convert([a1,...,an]) returns \spad{a1*v1 + ... + an*vn},
+ ++ where \spad{v1}, ..., \spad{vn} are the elements of the
+ ++ fixed \spad{R}-module basis.
+ leftDiscriminant : () -> R
+ ++ leftDiscriminant() returns the
+ ++ determinant of the \spad{n}-by-\spad{n}
+ ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
+ ++ given by the left trace of the product \spad{vi*vj}, where
+ ++ \spad{v1},...,\spad{vn} are the
+ ++ elements of the fixed \spad{R}-module basis.
+ ++ Note: the same as \spad{determinant(leftTraceMatrix())}.
+ rightDiscriminant : () -> R
+ ++ rightDiscriminant() returns the determinant of the \spad{n}-by-\spad{n}
+ ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
+ ++ given by the right trace of the product \spad{vi*vj}, where
+ ++ \spad{v1},...,\spad{vn} are the elements of
+ ++ the fixed \spad{R}-module basis.
+ ++ Note: the same as \spad{determinant(rightTraceMatrix())}.
+ leftTraceMatrix : () -> Matrix R
+ ++ leftTraceMatrix() is the \spad{n}-by-\spad{n}
+ ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
+ ++ given by left trace of the product \spad{vi*vj},
+ ++ where \spad{v1},...,\spad{vn} are the
+ ++ elements of the fixed \spad{R}-module
+ ++ basis.
+ rightTraceMatrix : () -> Matrix R
+ ++ rightTraceMatrix() is the \spad{n}-by-\spad{n}
+ ++ matrix whose element at the \spad{i}-th row and \spad{j}-th column is
+ ++ given by the right trace of the product \spad{vi*vj}, where
+ ++ \spad{v1},...,\spad{vn} are the elements
+ ++ of the fixed \spad{R}-module basis.
+ leftRegularRepresentation : % -> Matrix R
+ ++ leftRegularRepresentation(a) returns the matrix of the linear
+ ++ map defined by left multiplication by \spad{a} with respect
+ ++ to the fixed \spad{R}-module basis.
+ rightRegularRepresentation : % -> Matrix R
+ ++ rightRegularRepresentation(a) returns the matrix of the linear
+ ++ map defined by right multiplication by \spad{a} with respect
+ ++ to the fixed \spad{R}-module basis.
+ if R has Field then
+ leftRankPolynomial : () -> SparseUnivariatePolynomial Polynomial R
+ ++ leftRankPolynomial() calculates the left minimal polynomial
+ ++ of the generic element in the algebra,
+ ++ defined by the same structural
+ ++ constants over the polynomial ring in symbolic coefficients with
+ ++ respect to the fixed basis.
+ rightRankPolynomial : () -> SparseUnivariatePolynomial Polynomial R
+ ++ rightRankPolynomial() calculates the right minimal polynomial
+ ++ of the generic element in the algebra,
+ ++ defined by the same structural
+ ++ constants over the polynomial ring in symbolic coefficients with
+ ++ respect to the fixed basis.
+ apply: (Matrix R, %) -> %
+ ++ apply(m,a) defines a left operation of n by n matrices
+ ++ where n is the rank of the algebra in terms of matrix-vector
+ ++ multiplication, this is a substitute for a left module structure.
+ ++ Error: if shape of matrix doesn't fit.
+ --attributes
+ --attributes
+ --separable <=> discriminant() ^= 0
+ add
+
+ V ==> Vector
+ M ==> Matrix
+ P ==> Polynomial
+ F ==> Fraction
+ REC ==> Record(particular: Union(V R,"failed"),basis: List V R)
+ LSMP ==> LinearSystemMatrixPackage(R,V R,V R, M R)
+ CVMP ==> CoerceVectorMatrixPackage(R)
+
+ --GA ==> GenericNonAssociativeAlgebra(R,rank()$%,_
+ -- [random()$Character :: String :: Symbol for i in 1..rank()$%], _
+ -- structuralConstants()$%)
+ --y : GA := generic()
+ if R has Field then
+ leftRankPolynomial() ==
+ n := rank()
+ b := basis()
+ gamma : Vector Matrix R := structuralConstants b
+ listOfNumbers : List String := [STRINGIMAGE(q)$Lisp for q in 1..n]
+ symbolsForCoef : Vector Symbol :=
+ [concat("%", concat("x", i))::Symbol for i in listOfNumbers]
+ xx : M P R
+ mo : P R
+ x : M P R := new(1,n,0)
+ for i in 1..n repeat
+ mo := monomial(1, [symbolsForCoef.i], [1])$(P R)
+ qsetelt_!(x,1,i,mo)
+ y : M P R := copy x
+ k : PositiveInteger := 1
+ cond : M P R := copy x
+ -- multiplication in the generic algebra means using
+ -- the structural matrices as bilinear forms.
+ -- left multiplication by x, we prepare for that:
+ genGamma : V M P R := coerceP$CVMP gamma
+ x := reduce(horizConcat,[x*genGamma(i) for i in 1..#genGamma])
+ while rank(cond) = k repeat
+ k := k+1
+ for i in 1..n repeat
+ setelt(xx,[1],[i],x*transpose y)
+ y := copy xx
+ cond := horizConcat(cond, xx)
+ vectorOfCoef : Vector P R := (nullSpace(cond)$Matrix(P R)).first
+ res : SparseUnivariatePolynomial P R := 0
+ for i in 1..k repeat
+ res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial P R)
+ res
+
+ rightRankPolynomial() ==
+ n := rank()
+ b := basis()
+ gamma : Vector Matrix R := structuralConstants b
+ listOfNumbers : List String := [STRINGIMAGE(q)$Lisp for q in 1..n]
+ symbolsForCoef : Vector Symbol :=
+ [concat("%", concat("x", i))::Symbol for i in listOfNumbers]
+ xx : M P R
+ mo : P R
+ x : M P R := new(1,n,0)
+ for i in 1..n repeat
+ mo := monomial(1, [symbolsForCoef.i], [1])$(P R)
+ qsetelt_!(x,1,i,mo)
+ y : M P R := copy x
+ k : PositiveInteger := 1
+ cond : M P R := copy x
+ -- multiplication in the generic algebra means using
+ -- the structural matrices as bilinear forms.
+ -- left multiplication by x, we prepare for that:
+ genGamma : V M P R := coerceP$CVMP gamma
+ x := reduce(horizConcat,[genGamma(i)*transpose x for i in 1..#genGamma])
+ while rank(cond) = k repeat
+ k := k+1
+ for i in 1..n repeat
+ setelt(xx,[1],[i],y * transpose x)
+ y := copy xx
+ cond := horizConcat(cond, xx)
+ vectorOfCoef : Vector P R := (nullSpace(cond)$Matrix(P R)).first
+ res : SparseUnivariatePolynomial P R := 0
+ for i in 1..k repeat
+ res := res+monomial(vectorOfCoef.i,i)$(SparseUnivariatePolynomial P R)
+ res
+
+ leftUnitsInternal : () -> REC
+ leftUnitsInternal() ==
+ n := rank()
+ b := basis()
+ gamma : Vector Matrix R := structuralConstants b
+ cond : Matrix(R) := new(n**2,n,0$R)$Matrix(R)
+ rhs : Vector(R) := new(n**2,0$R)$Vector(R)
+ z : Integer := 0
+ addOn : R := 0
+ for k in 1..n repeat
+ for i in 1..n repeat
+ z := z+1 -- index for the rows
+ addOn :=
+ k=i => 1
+ 0
+ setelt(rhs,z,addOn)$Vector(R)
+ for j in 1..n repeat -- index for the columns
+ setelt(cond,z,j,elt(gamma.k,j,i))$Matrix(R)
+ solve(cond,rhs)$LSMP
+
+
+ leftUnit() ==
+ res : REC := leftUnitsInternal()
+ res.particular case "failed" =>
+ messagePrint("this algebra has no left unit")$OutputForm
+ "failed"
+ represents (res.particular :: V R)
+
+ leftUnits() ==
+ res : REC := leftUnitsInternal()
+ res.particular case "failed" =>
+ messagePrint("this algebra has no left unit")$OutputForm
+ "failed"
+ [represents(res.particular :: V R)$%, _
+ map(represents, res.basis)$ListFunctions2(Vector R, %) ]
+
+ rightUnitsInternal : () -> REC
+ rightUnitsInternal() ==
+ n := rank()
+ b := basis()
+ gamma : Vector Matrix R := structuralConstants b
+ condo : Matrix(R) := new(n**2,n,0$R)$Matrix(R)
+ rhs : Vector(R) := new(n**2,0$R)$Vector(R)
+ z : Integer := 0
+ addOn : R := 0
+ for k in 1..n repeat
+ for i in 1..n repeat
+ z := z+1 -- index for the rows
+ addOn :=
+ k=i => 1
+ 0
+ setelt(rhs,z,addOn)$Vector(R)
+ for j in 1..n repeat -- index for the columns
+ setelt(condo,z,j,elt(gamma.k,i,j))$Matrix(R)
+ solve(condo,rhs)$LSMP
+
+ rightUnit() ==
+ res : REC := rightUnitsInternal()
+ res.particular case "failed" =>
+ messagePrint("this algebra has no right unit")$OutputForm
+ "failed"
+ represents (res.particular :: V R)
+
+ rightUnits() ==
+ res : REC := rightUnitsInternal()
+ res.particular case "failed" =>
+ messagePrint("this algebra has no right unit")$OutputForm
+ "failed"
+ [represents(res.particular :: V R)$%, _
+ map(represents, res.basis)$ListFunctions2(Vector R, %) ]
+
+ unit() ==
+ n := rank()
+ b := basis()
+ gamma : Vector Matrix R := structuralConstants b
+ cond : Matrix(R) := new(2*n**2,n,0$R)$Matrix(R)
+ rhs : Vector(R) := new(2*n**2,0$R)$Vector(R)
+ z : Integer := 0
+ u : Integer := n*n
+ addOn : R := 0
+ for k in 1..n repeat
+ for i in 1..n repeat
+ z := z+1 -- index for the rows
+ addOn :=
+ k=i => 1
+ 0
+ setelt(rhs,z,addOn)$Vector(R)
+ setelt(rhs,u,addOn)$Vector(R)
+ for j in 1..n repeat -- index for the columns
+ setelt(cond,z,j,elt(gamma.k,j,i))$Matrix(R)
+ setelt(cond,u,j,elt(gamma.k,i,j))$Matrix(R)
+ res : REC := solve(cond,rhs)$LSMP
+ res.particular case "failed" =>
+ messagePrint("this algebra has no unit")$OutputForm
+ "failed"
+ represents (res.particular :: V R)
+ apply(m:Matrix(R),a:%) ==
+ v : Vector R := coordinates(a)
+ v := m *$Matrix(R) v
+ convert v
+
+
+ structuralConstants() == structuralConstants basis()
+ conditionsForIdempotents() == conditionsForIdempotents basis()
+ convert(x:%):Vector(R) == coordinates(x, basis())
+ convert(v:Vector R):% == represents(v, basis())
+ leftTraceMatrix() == leftTraceMatrix basis()
+ rightTraceMatrix() == rightTraceMatrix basis()
+ leftDiscriminant() == leftDiscriminant basis()
+ rightDiscriminant() == rightDiscriminant basis()
+ leftRegularRepresentation x == leftRegularRepresentation(x, basis())
+ rightRegularRepresentation x == rightRegularRepresentation(x, basis())
+ coordinates x == coordinates(x, basis())
+ represents(v:Vector R):%== represents(v, basis())
+
+ coordinates(v:Vector %) ==
+ m := new(#v, rank(), 0)$Matrix(R)
+ for i in minIndex v .. maxIndex v for j in minRowIndex m .. repeat
+ setRow_!(m, j, coordinates qelt(v, i))
+ m
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category MONAD Monad>>
+<<category MONADWU MonadWithUnit>>
+<<category NARNG NonAssociativeRng>>
+<<category NASRING NonAssociativeRing>>
+<<category NAALG NonAssociativeAlgebra>>
+<<category FINAALG FiniteRankNonAssociativeAlgebra>>
+<<category FRNAALG FramedNonAssociativeAlgebra>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ndftip.as.pamphlet b/src/algebra/ndftip.as.pamphlet
new file mode 100644
index 00000000..3c9c0ea5
--- /dev/null
+++ b/src/algebra/ndftip.as.pamphlet
@@ -0,0 +1,1174 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ndftip.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{NagDiscreteFourierTransformInterfacePackage}
+<<NagDiscreteFourierTransformInterfacePackage>>=
++++ Author: M.G. Richardson
++++ Date Created: 1995 Dec. 08
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This package provides Axiom-like interfaces to the NAG
++++ Finite Fourier Transform routines in the NAGlink.
+
+NagDiscreteFourierTransformInterfacePackage: with {
+
+ nagDFT : VDF -> VCDF ; -- test 1
+
+++ nagDFT(seq) calculates the discrete Fourier transform of a sequence
+++ of real data values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the vector seq.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06EAF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06eaf.
+
+ nagDFT : VCDF -> VCDF ; -- test 3
+
+++ nagDFT(seq) calculates the discrete Fourier transform of a sequence
+++ of complex data values
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the vector seq.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06ECF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06ecf.
+
+ nagDFT : PHSDF -> VDF ; -- test 7
+
+++ nagDFT(seq) calculates the discrete Fourier transform of a Hermitian
+++ sequence of complex data values,
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the PackedHermitianSequence seq.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06EBF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06ebf.
+
+ nagDFT : LVDF -> LVCDF ; -- test 10, 19
+
+++ nagDFT(seqs) calculates the discrete Fourier transform of each of a
+++ list of sequences of real data values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the list of vectors, seqs.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FPF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06fpf.
+
+ nagDFT : LVCDF -> LVCDF ; -- test 16
+
+++ nagDFT(seqs) calculates the discrete Fourier transform of each of a
+++ list of sequences of complex data values
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the list of vectors, seqs.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FRF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06frf.
+
+ nagDFT : LPHSDF -> LVDF ; -- test 12, 21
+
+++ nagDFT(seq) calculates the discrete Fourier transform of a each of a
+++ list of Hermitian sequences of complex data values,
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the List PackedHermitianSequence, seq.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FQF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06fqf.
+
+ nagInverseDFT : VDF -> VCDF ; -- test 8
+
+++ nagInverseDFT(seq) calculates the inverse discrete Fourier
+++ transform of a sequence of real data values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the vector seq.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06EAF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06eaf.
+
+ nagInverseDFT : VCDF -> VCDF ; -- test 2, 4
+
+++ nagInverseDFT(seq) calculates the inverse discrete Fourier
+++ transform of a sequence of complex data values
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the vector seq.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06ECF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06ecf.
+
+ nagInverseDFT : PHSDF -> VDF ; -- test 6
+
+++ nagInverseDFT(seq) calculates the inverse discrete Fourier transform
+++ of a Hermitian sequence of complex data values
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the PackedHermitianSequence seq.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06EBF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06ebf.
+
+ nagInverseDFT : LVDF -> LVCDF ; -- test 13
+
+++ nagInverseDFT(seqs) calculates the inverse discrete Fourier
+++ transform of each of a list of sequences of real data values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the list of vectors, seqs.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FPF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06fpf.
+
+ nagInverseDFT : LVCDF -> LVCDF ; -- test 11, 17
+
+++ nagInverseDFT(seqs) calculates the inverse discrete Fourier
+++ transform of each of a list of sequences of complex data values
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the list of vectors, seqs.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FRF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06frf.
+
+ nagInverseDFT : LPHSDF -> LVDF ; -- test 15
+
+++ nagInverseDFT(seqs) calculates the inverse discrete Fourier transform
+++ of each of a list of Hermitian sequences of complex data values
+#if saturn
+++ $z_{1} \ldots z_{n}$
+#else
+++ \spad{z[1] .. z[n]}
+#endif
+++ supplied in the List PackedHermitianSequence, seqs.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} z_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(z[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FQF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06fqf.
+
+ nagHermitianDFT : VDF -> PHSDF ; -- test 5
+
+++ nagHermitianDFT(seq) calculates the discrete Fourier transform, in
+++ packed Hermitian form, of a sequence of real data values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the vector seq.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06EAF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06eaf.
+
+ nagHermitianDFT : LVDF -> LPHSDF ; -- test 14, 20
+
+++ nagHermitianDFT(seqs) calculates the discrete Fourier transform, in
+++ packed Hermitian form, of each of a list of sequences of real data
+++ values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the list of vectors, seqs.
+++ Note that the definition used for the discrete Fourier transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{-i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(-i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FPF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06fpf.
+
+ nagHermitianInverseDFT : VDF -> PHSDF ; -- test 9
+
+++ nagHermitianInverseDFT(seq) calculates the inverse discrete Fourier
+++ transform, in packed Hermitian form, of a sequence of real data
+++ values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the vector seq.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06EAF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06eaf.
+
+ nagHermitianInverseDFT : LVDF -> LPHSDF ; -- test 18
+
+++ nagHermitianInverseDFT(seqs) calculates the inverse discrete Fourier
+++ transform, in packed Hermitian form, of each of a list of sequences
+++ of real data values
+#if saturn
+++ $x_{1} \ldots x_{n}$
+#else
+++ \spad{x[1] .. x[n]}
+#endif
+++ supplied in the list of vectors, seqs.
+++ Note that the definition used for the inverse discrete Fourier
+++ transform is
+#if saturn
+++ \[ \frac{1}{\sqrt{n} \sum_{j=0}^{n-1} x_{j} e^{i \frac{2 \pi j k}{n}
+++ \qquad k = 0 \ldots n - 1 \]
+#else
+++ \spad{1/sqrt(n)*sum(x[j]*%e^(i*2*%pi*j*k/n), j=0..(n-1))} for
+++ \spad{k=0..(n-1)}.
+#endif
+++ The numerical calculation is performed by the NAG routine C06FPF.
+++
+++ For more detailed information, please consult the NAG
+++ manual via the Browser page for the operation c06fpf.
+
+} == add {
+
+ import from AnyFunctions1 MDF ;
+ import from CDF;
+ import from ErrorFunctions ;
+ import from LLDF ;
+ import from MCDF ;
+ import from MDF ;
+ import from NagResultChecks ;
+ import from NagSeriesSummationPackage ;
+ import from PHSDF;
+ import from STRG ;
+ import from List STRG ;
+ import from Symbol ;
+ import from VDF ;
+
+ local (..)(a:INT,b:INT):Generator INT == {
+ generate {
+ t := a ;
+ while (t <= b) repeat {
+ yield t ;
+ t := t + 1 ;
+ }
+ }
+ }
+
+ local ipIfail : INT := -1 ;
+
+-- First, the functions corresponding to single NAGlink calls of C06E
+-- routines (single vector transforms):
+
+-- c06eaf:
+
+ nagHermitianDFT(seq : VDF) : PHSDF ; == {
+ local lseq : INT ;
+
+ lseq := ((# seq)@NNI) pretend INT ; -- @ to eliminate SI possibility
+ row(checkMxDF(c06eaf(lseq,matrix [members seq],ipIfail),
+ "x",
+ "C06EAF"),
+ 1)
+ pretend PHSDF
+ }
+
+-- c06ebf:
+
+ nagDFT(seq : PHSDF) : VDF == {
+ local lseq : INT ;
+
+ lseq := ((# seq)@NNI) pretend INT ; -- @ to eliminate SI possibility
+ row(checkMxDF(c06ebf(lseq,matrix [members seq],ipIfail),
+ "x",
+ "C06EBF"),
+ 1)
+ }
+
+-- c06ecf:
+
+ nagDFT(seq : VCDF) : VCDF == {
+ local nseq : NNI ;
+ local lseq : INT ;
+ local rvec, ivec : VDF ;
+ local cvec : VCDF ;
+ local c06ecfResult : RSLT ;
+
+ nseq := # seq ;
+ lseq := nseq pretend INT ;
+ rvec := new(nseq,0) ;
+ ivec := new(nseq,0) ;
+ for i in 1..lseq repeat {
+ rvec(i) := real seq(i) ;
+ ivec(i) := imag seq(i) ;
+ }
+ c06ecfResult := c06ecf(lseq,
+ matrix [members rvec],
+ matrix [members ivec],
+ ipIfail) ;
+ rvec := row(checkMxDF(c06ecfResult,"x","C06ECF"),1) ;
+ ivec := row((retract(c06ecfResult."y") @ MDF),1) ;
+ cvec := new(nseq,0) ;
+ for i in 1..lseq repeat cvec(i) := complex(rvec(i),ivec(i)) ;
+ cvec
+ }
+
+-- inverse transforms, in terms of these and functions from PHS:
+
+ nagInverseDFT(seq : PHSDF) : VDF == nagDFT conjHerm seq ;
+
+ nagHermitianInverseDFT(seq : VDF) : PHSDF
+ == conjHerm nagHermitianDFT seq ;
+
+ nagInverseDFT(seq : VCDF) : VCDF == {
+ local nseq : NNI ;
+ local lseq : INT ;
+ local rvec, ivec : VDF ;
+ local cvec : VCDF ;
+ local c06ecfResult : RSLT ;
+
+ nseq := # seq ;
+ lseq := nseq pretend INT ;
+ rvec := new(nseq,0) ;
+ ivec := new(nseq,0) ;
+ for i in 1..lseq repeat {
+ rvec(i) := real seq(i) ;
+ ivec(i) := - imag seq(i) ;
+ }
+ c06ecfResult := c06ecf(lseq,
+ matrix [members rvec],
+ matrix [members ivec],
+ ipIfail) ;
+ rvec := row(checkMxDF(c06ecfResult,"x","C06ECF"),1) ;
+ ivec := row((retract(c06ecfResult."y") @ MDF),1) ;
+ cvec := new(nseq,0) ;
+ for i in 1..lseq repeat cvec(i) := complex(rvec(i), - ivec(i)) ;
+ cvec
+ }
+
+-- "Full form" equivalents of c06eaf and inverse:
+
+ nagDFT(seq : VDF) : VCDF == expand nagHermitianDFT seq ;
+
+ nagInverseDFT(seq : VDF) : VCDF == expand nagHermitianInverseDFT seq ;
+
+
+-- Next, the functions corresponding to single NAGlink calls of C06F
+-- routines (multiple vector transforms):
+
+-- basic routines:
+
+-- c06fpf
+
+ nagHermitianDFT(seqs : LVDF) : LPHSDF ; == {
+
+ local nr, nc : NNI ;
+ local inr, inc : INT ;
+ local seqMat, trig, result : MDF ;
+ local nextSeq : PHSDF ;
+ local hermDFTs : LPHSDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ nc := # (seqs.1) ;
+ inc := nc pretend INT ;
+ seqMat := new(nr,nc,0) ;
+ for j in 1 .. inc repeat seqMat(1,j) := (seqs.1).j ;
+ for i in 2 .. inr repeat
+ if (# seqs.i) ~= nc
+ then error ["The data sequences in nagHermitianDFT must all",
+ " have the same length. ",
+ "The length of sequence 1 is ",
+ string(inc),
+ "that of sequence ",
+ string(i pretend INT),
+ " is ",
+ string((# seqs.i)@NNI pretend INT), -- @ avoids SI
+ "."]
+ else for j in 1 .. inc repeat seqMat(i,j) := (seqs.i).j ;
+ trig := new(1@NNI,2*nc,0) ;
+ result :=
+ checkMxDF(c06fpf(inr,inc,"i",seqMat,trig,ipIfail),"x","C06FPF") ;
+ hermDFTs := [] ;
+ for i in inr .. 1 by -1 repeat {
+ nextSeq := new(nc,0) ;
+ for j in 1 .. inc repeat nextSeq(j) := result(1,(j-1)*inr + i) ;
+ hermDFTs := cons(nextSeq,hermDFTs) ;
+ }
+ hermDFTs
+ }
+
+-- c06fqf
+
+ nagDFT(seqs : LPHSDF) : LVDF == {
+
+ local nr, nc : NNI ;
+ local inr, inc : INT ;
+ local seqMat, trig, result : MDF ;
+ local nextSeq : VDF ;
+ local dfts : LVDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ nc := # (seqs.1) ;
+ inc := nc pretend INT ;
+ seqMat := new(nr,nc,0) ;
+ for j in 1 .. inc repeat seqMat(1,j) := (seqs.1).j ;
+ for i in 2 .. inr repeat
+ if (# seqs.i) ~= nc
+ then error ["The data sequences in nagDFT must all",
+ " have the same length. ",
+ "The length of sequence 1 is ",
+ string(inc),
+ "that of sequence ",
+ string(i pretend INT),
+ " is ",
+ string((# seqs.i)@NNI pretend INT), -- @ avoids SI
+ "."]
+ else for j in 1 .. inc repeat seqMat(i,j) := (seqs.i).j ;
+ trig := new(1@NNI,2*nc,0) ;
+ result :=
+ checkMxDF(c06fqf(inr,inc,"i",seqMat,trig,ipIfail),"x","C06FQF") ;
+ dfts := [] ;
+ for i in inr .. 1 by -1 repeat {
+ nextSeq := new(nc,0) ;
+ for j in 1 .. inc repeat nextSeq(j) := result(1,(j-1)*inr + i) ;
+ dfts := cons(nextSeq,dfts) ;
+ }
+ dfts
+ }
+
+-- c06frf
+
+ nagDFT(seqs : LVCDF) : LVCDF == {
+
+ local nr, nc : NNI ;
+ local inr, inc : INT ;
+ local trig, rMat, iMat : MDF ;
+ local result : RSLT ;
+ local nextSeq : VCDF ;
+ local dfts : LVCDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ nc := # (seqs.1) ;
+ inc := nc pretend INT ;
+ rMat := new(nr,nc,0) ;
+ iMat := new(nr,nc,0) ;
+ for j in 1 .. inc repeat {
+ rMat(1,j) := real((seqs.1).j) ;
+ iMat(1,j) := imag((seqs.1).j) ;
+ }
+ for i in 2 .. inr repeat {
+ if (# seqs.i) ~= nc
+ then error ["The data sequences in nagDFT must all",
+ " have the same length. ",
+ "The length of sequence 1 is ",
+ string(inc),
+ "that of sequence ",
+ string(i pretend INT),
+ " is ",
+ string((# seqs.i)@NNI pretend INT), -- @ avoids SI
+ "."]
+ else for j in 1 .. inc repeat {
+ rMat(i,j) := real((seqs.i).j) ;
+ iMat(i,j) := imag((seqs.i).j) ;
+ }
+ }
+ trig := new(1@NNI,2*nc,0) ;
+ result := c06frf(inr,inc,"i",rMat,iMat,trig,ipIfail) ;
+ rMat := checkMxDF(result, "x", "C06FRF") ;
+ iMat := retract(result."y") @ MDF ;
+ dfts := [] ;
+ for i in inr .. 1 by -1 repeat {
+ nextSeq := new(nc,0) ;
+ for j in 1 .. inc repeat
+ nextSeq(j) := complex(rMat(1,(j-1)*inr+i),iMat(1,(j-1)*inr+i)) ;
+ dfts := cons(nextSeq,dfts) ;
+ }
+ dfts
+ }
+
+-- inverse transforms, in terms of these and functions from PHS:
+
+ nagInverseDFT(seqs : LVCDF) : LVCDF == {
+
+ local nr, nc : NNI ;
+ local inr, inc : INT ;
+ local conjSeq : VCDF ;
+ local temp, invdfts : LVCDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ temp := [] ;
+ for i in inr .. 1 by -1 repeat {
+ nc := #(seqs.i) ;
+ inc := nc pretend INT ;
+ conjSeq := new(nc,0) ;
+ for j in 1 .. inc repeat
+ conjSeq(j) := conjugate((seqs.i).j) ;
+ temp := cons(conjSeq,temp) ;
+ }
+ temp := nagDFT temp ;
+ invdfts := [] ;
+ for i in inr .. 1 by -1 repeat {
+ conjSeq := new(nc,0) ;
+ for j in 1 .. inc repeat -- know inc is constant after nagDFT call
+ conjSeq(j) := conjugate((temp.i).j) ;
+ invdfts := cons(conjSeq,invdfts) ;
+ }
+ invdfts
+ }
+
+ nagInverseDFT(seqs : LPHSDF) : LVDF == {
+ local nr : NNI ;
+ local inr : INT ;
+ local conjSeqs : LPHSDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ conjSeqs := [] ;
+ for i in inr .. 1 by -1 repeat
+ conjSeqs := cons(conjHerm(seqs.i),conjSeqs) ;
+ nagDFT conjSeqs ;
+ }
+
+ nagHermitianInverseDFT(seqs : LVDF) : LPHSDF == {
+ local nr : NNI ;
+ local inr : INT ;
+ local conjSeqs, invSeqs : LPHSDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ conjSeqs := nagHermitianDFT seqs ;
+ invSeqs := [] ;
+ for i in inr .. 1 by -1 repeat
+ invSeqs := cons(conjHerm(conjSeqs.i),invSeqs) ;
+ invSeqs
+ }
+
+-- "Full form" equivalents of c06fpf and inverse:
+
+ nagDFT(seqs : LVDF) : LVCDF == {
+
+ local nr : NNI ;
+ local inr : INT ;
+ local hermdfts : LPHSDF ;
+ local dfts : LVCDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ hermdfts := nagHermitianDFT seqs ;
+ dfts := [] ;
+ for i in inr .. 1 by -1 repeat
+ dfts := cons(expand(hermdfts.i),dfts) ;
+ dfts
+ }
+
+ nagInverseDFT(seqs : LVDF) : LVCDF == {
+ local nr : NNI ;
+ local inr : INT ;
+ local hermdfts : LPHSDF ;
+ local invdfts : LVCDF ;
+
+ nr := # seqs ;
+ inr := nr pretend INT ;
+ hermdfts := nagHermitianDFT seqs ;
+ invdfts := [] ;
+ for i in inr .. 1 by -1 repeat
+ invdfts := cons(expand conjHerm(hermdfts.i),invdfts) ;
+ invdfts
+ }
+
+}
+
+#if NeverAssertThis
+
+-- Note that the conversions of results from DoubleFloat to Float
+-- will become unnecessary if outputGeneral is extended to apply to
+-- DoubleFloat quantities. Those results not converted will, of
+-- course, then be displayed to 6 s.f.
+
+)lib nrc
+)lib herm
+)lib ndftip
+
+outputGeneral 6
+
+seqA := [0.34907,0.54890,0.74776,0.94459,1.1385,1.3285,1.5137];
+
+seqB := [0.34907 - 0.37168*%i, _
+ 0.54890 - 0.35669*%i, _
+ 0.74776 - 0.31175*%i, _
+ 0.94459 - 0.23702*%i, _
+ 1.13850 - 0.13274*%i, _
+ 1.32850 + 0.00074*%i, _
+ 1.51370 + 0.16298*%i];
+
+hseqC : PackedHermitianSequence DoubleFloat
+hseqC := packHS [0.34907, _
+ 0.54890 + %i*1.51370, _
+ 0.74776 + %i*1.32850, _
+ 0.94459 + %i*1.13850, _
+ 0.94459 - %i*1.13850, _
+ 0.74776 - %i*1.32850, _
+ 0.54890 - %i*1.51370];
+
+seqsD : List Vector DoubleFloat;
+seqsD := [vector [0.3854, 0.6772, 0.1138, 0.6751, 0.6362, 0.1424], _
+ vector [0.5417, 0.2983, 0.1181, 0.7255, 0.8638, 0.8723], _
+ vector [0.9172, 0.0644, 0.6037, 0.6430, 0.0428, 0.4815]];
+
+seqsE : List PackedHermitianSequence DoubleFloat;
+seqsE := [pHS [0.3854, 0.6772, 0.1138, 0.6751, 0.6362, 0.1424], _
+ pHS [0.5417, 0.2983, 0.1181, 0.7255, 0.8638, 0.8723], _
+ pHS [0.9172, 0.0644, 0.6037, 0.6430, 0.0428, 0.4815]];
+
+seqsF : List Vector Complex DoubleFloat
+seqsF := [vector [0.3854 + 0.5417*%i, 0.6772 + 0.2983*%i, _
+ 0.1138 + 0.1181*%i, 0.6751 + 0.7255*%i, _
+ 0.6362 + 0.8638*%i, 0.1424 + 0.8723*%i], _
+ vector [0.9172 + 0.9089*%i, 0.0644 + 0.3118*%i, _
+ 0.6037 + 0.3465*%i, 0.6430 + 0.6198*%i, _
+ 0.0428 + 0.2668*%i, 0.4815 + 0.1614*%i], _
+ vector [0.1156 + 0.6214*%i, 0.0685 + 0.8681*%i, _
+ 0.2060 + 0.7060*%i, 0.8630 + 0.8652*%i, _
+ 0.6967 + 0.9190*%i, 0.2792 + 0.3355*%i]];
+
+-- test 1
+
+dftA := nagDFT seqA;
+dftA :: Vector Complex Float :: Matrix Complex Float
+ -- Matrix to force display as a column,
+ -- Float to allow outputGeneral to work.
+
+-- + 2.48361 +
+-- | |
+-- |- 0.265985 + 0.530898 %i |
+-- | |
+-- |- 0.257682 + 0.202979 %i |
+-- | |
+-- |- 0.256363 + 0.0580623 %i|
+-- | |
+-- |- 0.256363 - 0.0580623 %i|
+-- | |
+-- |- 0.257682 - 0.202979 %i |
+-- | |
+-- +- 0.265985 - 0.530898 %i +
+
+-- test 2
+
+nagInverseDFT dftA :: Vector Float
+
+-- [0.34907,0.5489,0.74776,0.94459,1.1385,1.3285,1.5137]
+
+-- test 3
+
+dftB := nagDFT seqB;
+dftB :: Vector Complex Float :: Matrix Complex Float
+
+-- + 2.48361 - 0.471004 %i +
+-- | |
+-- | - 0.5518 + 0.496841 %i |
+-- | |
+-- |- 0.367113 + 0.0975621 %i|
+-- | |
+-- |- 0.287669 - 0.0586476 %i|
+-- | |
+-- |- 0.225057 - 0.174772 %i |
+-- | |
+-- |- 0.148251 - 0.308396 %i |
+-- | |
+-- + 0.0198297 - 0.564956 %i +
+
+-- test 4
+
+(nagInverseDFT dftB) :: Vector Complex Float :: Matrix Complex Float
+
+-- +0.34907 - 0.37168 %i+
+-- | |
+-- |0.5489 - 0.35669 %i |
+-- | |
+-- |0.74776 - 0.31175 %i|
+-- | |
+-- |0.94459 - 0.23702 %i|
+-- | |
+-- |1.1385 - 0.13274 %i |
+-- | |
+-- |1.3285 + 0.00074 %i |
+-- | |
+-- +1.5137 + 0.16298 %i +
+
+-- test 5
+
+hdftA := nagHermitianDFT seqA;
+(expand hdftA) :: Vector Complex Float :: Matrix Complex Float
+
+-- + 2.48361 +
+-- | |
+-- |- 0.265985 + 0.530898 %i |
+-- | |
+-- |- 0.257682 + 0.202979 %i |
+-- | |
+-- |- 0.256363 + 0.0580623 %i|
+-- | |
+-- |- 0.256363 - 0.0580623 %i|
+-- | |
+-- |- 0.257682 - 0.202979 %i |
+-- | |
+-- +- 0.265985 - 0.530898 %i +
+
+-- test 6
+
+(nagInverseDFT hdftA) :: Vector Float
+
+-- [0.34907,0.5489,0.74776,0.94459,1.1385,1.3285,1.5137]
+
+-- test 7
+
+dftC := nagDFT hseqC;
+dftC :: Vector Float
+
+-- [1.82616,1.86862,- 0.017503,0.502001,- 0.598725,- 0.0314404,- 2.62557]
+
+-- test 8
+
+(nagInverseDFT dftC) :: Vector Complex Float
+
+-- [0.34907, 0.5489 + 1.5137 %i, 0.74776 + 1.3285 %i, 0.94459 + 1.1385 %i,
+-- 0.94459 - 1.1385 %i, 0.74776 - 1.3285 %i, 0.5489 - 1.5137 %i]
+
+-- test 9
+
+nagHermitianInverseDFT dftC
+
+-- [0.34907000000000005, 0.54889999999999983, 0.74775999999999987,
+-- 0.94459000000000004, 1.1385000000000003, 1.3284999999999998,
+-- 1.5136999999999998]
+
+-- test 10:
+
+dftsD := nagDFT seqsD;
+
+dftsD :: List Vector Complex Float
+
+-- [
+-- [1.07373, - 0.104062 - 0.00438406 %i, 0.112554 - 0.373777 %i, - 0.146684,
+-- 0.112554 + 0.373777 %i, - 0.104062 + 0.00438406 %i]
+-- ,
+
+-- [1.39609, - 0.0365178 + 0.466584 %i, 0.077955 - 0.0607051 %i, - 0.152072,
+-- 0.077955 + 0.0607051 %i, - 0.0365178 - 0.466584 %i]
+-- ,
+
+-- [1.12374, 0.0914068 - 0.050841 %i, 0.393551 + 0.345775 %i, 0.153011,
+-- 0.393551 - 0.345775 %i, 0.0914068 + 0.050841 %i]
+-- ]
+
+-- test 11:
+
+invdftsD := nagInverseDFT dftsD ;
+invdftsD :: List Vector Complex Float
+
+-- [[0.3854,0.6772,0.1138,0.6751,0.6362,0.1424],
+-- [0.5417,0.2983,0.1181,0.7255,0.8638,0.8723],
+-- [0.9172,0.0644,0.6037,0.643,0.0428,0.4815]]
+
+-- test 12:
+
+dftsE := nagDFT seqsE;
+dftsE :: List Vector Float
+
+-- [[1.0788,0.662291,- 0.239146,- 0.578284,0.459192,- 0.438816],
+-- [0.857321,1.22614,0.353348,- 0.222169,0.341327,- 1.22908],
+-- [1.18245,0.262509,0.674406,0.552278,0.0539906,- 0.478963]]
+
+-- test 13:
+
+invdftsE := nagInverseDFT dftsE;
+invdftsE :: List Vector Complex Float
+
+-- [
+-- [0.3854, 0.6772 + 0.1424 %i, 0.1138 + 0.6362 %i, 0.6751,
+-- 0.1138 - 0.6362 %i, 0.6772 - 0.1424 %i]
+-- ,
+
+-- [0.5417, 0.2983 + 0.8723 %i, 0.1181 + 0.8638 %i, 0.7255,
+-- 0.1181 - 0.8638 %i, 0.2983 - 0.8723 %i]
+-- ,
+
+-- [0.9172, 0.0644 + 0.4815 %i, 0.6037 + 0.0428 %i, 0.643,
+-- 0.6037 - 0.0428 %i, 0.0644 - 0.4815 %i]
+-- ]
+
+-- test 14:
+
+hdftsD := nagHermitianDFT seqsD;
+map(expand,hdftsD) :: List Vector Complex Float
+
+-- [
+-- [1.07373, - 0.104062 - 0.00438406 %i, 0.112554 - 0.373777 %i, - 0.146684,
+-- 0.112554 + 0.373777 %i, - 0.104062 + 0.00438406 %i]
+-- ,
+
+-- [1.39609, - 0.0365178 + 0.466584 %i, 0.077955 - 0.0607051 %i, - 0.152072,
+-- 0.077955 + 0.0607051 %i, - 0.0365178 - 0.466584 %i]
+-- ,
+
+-- [1.12374, 0.0914068 - 0.050841 %i, 0.393551 + 0.345775 %i, 0.153011,
+-- 0.393551 - 0.345775 %i, 0.0914068 + 0.050841 %i]
+-- ]
+
+-- test 15:
+
+(nagInverseDFT hdftsD) :: List Vector Float
+
+-- [[0.3854,0.6772,0.1138,0.6751,0.6362,0.1424],
+-- [0.5417,0.2983,0.1181,0.7255,0.8638,0.8723],
+-- [0.9172,0.0644,0.6037,0.643,0.0428,0.4815]]
+
+-- test 16:
+
+dftsF := nagDFT seqsF;
+dftsF :: List Vector Complex Float
+
+-- [
+-- [1.07373 + 1.39609 %i, - 0.570647 - 0.0409019 %i, 0.173259 - 0.295822 %i,
+-- - 0.146684 - 0.152072 %i, 0.0518489 + 0.451732 %i,
+-- 0.362522 - 0.0321337 %i]
+-- ,
+
+-- [1.12374 + 1.06765 %i, 0.172759 + 0.0385858 %i, 0.418548 + 0.748083 %i,
+-- 0.153011 + 0.17522 %i, 0.368555 + 0.0565331 %i, 0.0100542 + 0.140268 %i]
+-- ,
+
+-- [0.909985 + 1.76167 %i, - 0.305418 + 0.0624335 %i,
+-- 0.407884 - 0.0694786 %i, - 0.078547 + 0.0725049 %i,
+-- - 0.119334 + 0.128511 %i, - 0.531409 - 0.433531 %i]
+-- ]
+
+-- test 17:
+
+invdftsF := nagInverseDFT dftsF ;
+invdftsF :: List Vector Complex Float
+
+-- [
+-- [0.3854 + 0.5417 %i, 0.6772 + 0.2983 %i, 0.1138 + 0.1181 %i,
+-- 0.6751 + 0.7255 %i, 0.6362 + 0.8638 %i, 0.1424 + 0.8723 %i]
+-- ,
+
+-- [0.9172 + 0.9089 %i, 0.0644 + 0.3118 %i, 0.6037 + 0.3465 %i,
+-- 0.643 + 0.6198 %i, 0.0428 + 0.2668 %i, 0.4815 + 0.1614 %i]
+-- ,
+
+-- [0.1156 + 0.6214 %i, 0.0685 + 0.8681 %i, 0.206 + 0.706 %i,
+-- 0.863 + 0.8652 %i, 0.6967 + 0.919 %i, 0.2792 + 0.3355 %i]
+-- ]
+
+-- test 18:
+
+nagHermitianInverseDFT dftsE
+
+-- [
+-- [0.38540000000000013, 0.67720000000000025, 0.11380000000000001,
+-- 0.67510000000000014, 0.63620000000000021, 0.14240000000000003]
+-- ,
+
+-- [0.54170000000000018, 0.29830000000000012, 0.1181, 0.72550000000000014,
+-- 0.86380000000000023, 0.87230000000000019]
+-- ,
+
+-- [0.91720000000000035, 0.064399999999999999, 0.60370000000000024,
+-- 0.64300000000000013, 0.042799999999999991, 0.48150000000000015]
+-- ]
+
+-- error tests:
+
+-- test 19:
+
+nagDFT [vector [0.3854 + 0.5417*%i, 0.6772 + 0.2983*%i, _
+ 0.1138 + 0.1181*%i, 0.6751 + 0.7255*%i, _
+ 0.6362 + 0.8638*%i, 0.1424 + 0.8723*%i], _
+ vector [0.1156 + 0.6214*%i, 0.0685 + 0.8681*%i, _
+ 0.6967 + 0.9190*%i, 0.2792 + 0.3355*%i]]
+
+-- Error signalled from user code:
+-- The data sequences in nagDFT must all have the same length. The
+-- length of sequence 1 is 6 that of sequence 2 is 4.
+
+-- test 20:
+
+nagHermitianDFT [vector [0.3854, 0.6751, 0.6362, 0.1424], _
+ vector [0.5417, 0.7255, 0.8638, 0.8723], _
+ vector [0.9172, 0.0428, 0.4815]]
+
+-- Error signalled from user code:
+-- The data sequences in nagHermitianDFT must all have the same
+-- length. The length of sequence 1 is 4 that of sequence 3 is 3.
+
+-- test 21:
+
+badSeqs : List PackedHermitianSequence DoubleFloat
+badSeqs := [pHS [0.3854, 0.1138, 0.6751, 0.6362, 0.1424], _
+ pHS [0.5417, 0.2983, 0.1181, 0.7255, 0.8638, 0.8723], _
+ pHS [0.9172, 0.0644, 0.6037, 0.6430, 0.0428, 0.4815]];
+
+nagDFT badSeqs
+
+-- Error signalled from user code:
+-- The data sequences in nagDFT must all have the same length. The
+-- length of sequence 1 is 5 that of sequence 2 is 6.
+
+outputGeneral()
+
+output "End of tests"
+
+#endif
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- To test:
+-- sed -ne '1,/^#if NeverAssertThis/d;/#endif/d;p' < ndftip.as > ndftip.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r ndftip.input
+
+#unassert saturn
+
+#include "axiom.as"
+
+DF ==> DoubleFloat ;
+CDF ==> Complex DoubleFloat ;
+LDF ==> List DoubleFloat ;
+LLDF ==> List LDF ;
+VDF ==> Vector DoubleFloat ;
+LVDF ==> List VDF ;
+VCDF ==> Vector Complex DoubleFloat ;
+LVCDF ==> List VCDF ;
+MDF ==> Matrix DoubleFloat ;
+MCDF ==> Matrix Complex DoubleFloat ;
+INT ==> Integer ;
+NNI ==> NonNegativeInteger ;
+RSLT ==> Result ;
+STRG ==> String ;
+PHSDF ==> PackedHermitianSequence DF;
+LPHSDF ==> List PackedHermitianSequence DF;
+
+<<NagDiscreteFourierTransformInterfacePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nepip.as.pamphlet b/src/algebra/nepip.as.pamphlet
new file mode 100644
index 00000000..4d361776
--- /dev/null
+++ b/src/algebra/nepip.as.pamphlet
@@ -0,0 +1,626 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nepip.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{NagEigenInterfacePackage}
+<<NagEigenInterfacePackage>>=
++++ Author: M.G. Richardson
++++ Date Created: 1996 January 12
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This package provides Axiom-like interfaces to the NAG generalised
++++ eigenvalue and eigenvector routines in the NAGlink.
+
+DF ==> DoubleFloat ;
+CDF ==> Complex DoubleFloat ;
+FFCDF ==> FormalFraction Complex DoubleFloat ;
+LFFCDF ==> List FormalFraction Complex DoubleFloat ;
+LDF ==> List DoubleFloat ;
+LCDF ==> List Complex DoubleFloat ;
+LLDF ==> List LDF ;
+VDF ==> Vector DoubleFloat ;
+LVDF ==> List VDF ;
+VCDF ==> Vector Complex DoubleFloat ;
+LVCDF ==> List VCDF ;
+MDF ==> Matrix DoubleFloat ;
+MCDF ==> Matrix Complex DoubleFloat ;
+INT ==> Integer ;
+NNI ==> NonNegativeInteger ;
+RCD ==> Record ;
+RSLT ==> Result ;
+STRG ==> String ;
+UNNRES ==> Union(a:LDF,b:LFFCDF) ; -- a & b are dummy tags
+RURSLV ==> RCD(eigenvalues : UNNRES, eigenvectors : LVCDF) ;
+
+NagEigenInterfacePackage: with {
+
+ nagEigenvalues : (MDF,MDF,DF) -> UNNRES ;
+
+++ nagEigenvalues(A,B,eps) returns a list of the eigenvalues
+#if saturn
+++ $ \lambda $
+#else
+++ \spad{l}
+#endif
+++ of the system
+#if saturn
+++ $ A x = \lambda B x $
+#else
+++ \spad{A*x = l*B*x}
+#endif
+++
+++ The numerical calculation is performed by one of the NAG routines
+++ F02ADF and F02BJF, depending on the the form of \spad{A} and B.
+++ The result is of type Union(List DoubleFloat, List FormalFraction
+++ Complex DoubleFloat), the first branch resulting from F02ADF and
+++ the second from F02BJF. Note that in the latter case values should
+++ be inspected for numerically small numerators and denominators,
+++ ratios of which may be in effect indeterminate, before the result is
+++ converted to List Complex DoubleFloat.
+++
+++ The parameter eps, if positive, defines a tolerance to be used in
+++ recognising negligable matrix elements when F02BJF is called; setting
+++ this may result in faster execution with less accuracy.
+++
+++ For more detailed information, please consult the NAG manual
+++ via the Browser pages for the operations f02adf and f02bjf.
+
+ nagEigenvalues : (MDF,MDF) -> UNNRES ;
+
+++ nagEigenvalues(A,B) returns a list of the eigenvalues
+#if saturn
+++ $ \lambda $
+#else
+++ \spad{l}
+#endif
+++ of the system
+#if saturn
+++ $ A x = \lambda B x $
+#else
+++ \spad{A*x = l*B*x}
+#endif
+++
+++ The numerical calculation is performed by one of the NAG routines
+++ F02ADF and F02BJF, depending on the the form of \spad{A} and B.
+++ The result is of type Union(List DoubleFloat, List FormalFraction
+++ Complex DoubleFloat), the first branch resulting from F02ADF and
+++ the second from F02BJF. Note that in the latter case values should
+++ be inspected for numerically small numerators and denominators,
+++ ratios of which may be in effect indeterminate, before the result is
+++ converted to List Complex DoubleFloat.
+++
+++ For more detailed information, please consult the NAG manual
+++ via the Browser pages for the operations f02adf and f02bjf.
+
+ nagEigenvectors : (MDF,MDF,DF) -> RURSLV ;
+
+++ nagEigenvectors(A,B,eps) returns a record consisting of a list of the
+++ eigenvalues
+#if saturn
+++ $ \lambda $
+#else
+++ \spad{l}
+#endif
+++ and a list of the corresponding eigenvectors of the system
+#if saturn
+++ $ A x = \lambda B x $
+#else
+++ \spad{A*x = l*B*x}
+#endif
+++ where
+#if saturn
+++ $A$ and $B$
+#else
+++ \spad{A} and B
+#endif
+
+#if saturn
+++ $B$
+#else
+++ B
+#endif
+++ is positive-definite.
+++
+++ The numerical calculation is performed by one of the NAG routines
+++ F02AEF and F02BJF, depending on the the form of \spad{A} and B.
+++ The first component of the result, \spad{eigenvalues},
+++ is of type Union(List DoubleFloat, List FormalFraction
+++ Complex DoubleFloat), the first branch resulting from F02AEF and
+++ the second from F02BJF. Note that in the latter case values should
+++ be inspected for numerically small numerators and denominators,
+++ ratios of which may be in effect indeterminate, before the result is
+++ converted to List Complex DoubleFloat.
+++
+++ The parameter eps, if positive, defines a tolerance to be used in
+++ recognising negligable matrix elements when F02BJF is called; setting
+++ this may result in faster execution with less accuracy.
+++
+++ For more detailed information, please consult the NAG manual
+++ via the Browser pages for the operations f02aef and f02bjf.
+
+ nagEigenvectors : (MDF,MDF) -> RURSLV ;
+
+++ nagEigenvectors(A,B) returns a record consisting of a list of the
+++ eigenvalues
+#if saturn
+++ $ \lambda $
+#else
+++ \spad{l}
+#endif
+++ and a list of the corresponding eigenvectors of the system
+#if saturn
+++ $ A x = \lambda B x $
+#else
+++ \spad{A*x = l*B*x}
+#endif
+++ where
+#if saturn
+++ $A$ and $B$
+#else
+++ \spad{A} and B
+#endif
+
+#if saturn
+++ $B$
+#else
+++ B
+#endif
+++ is positive-definite.
+++
+++ The numerical calculation is performed by one of the NAG routines
+++ F02AEF and F02BJF, depending on the the form of \spad{A} and B.
+++ The first component of the result, \spad{eigenvalues},
+++ is of type Union(List DoubleFloat, List FormalFraction
+++ Complex DoubleFloat), the first branch resulting from F02AEF and
+++ the second from F02BJF. Note that in the latter case values should
+++ be inspected for numerically small numerators and denominators,
+++ ratios of which may be in effect indeterminate, before the result is
+++ converted to List Complex DoubleFloat.
+++
+++ For more detailed information, please consult the NAG manual
+++ via the Browser pages for the operations f02aef and f02bjf.
+
+} == add {
+
+ import from AnyFunctions1 INT ;
+ import from AnyFunctions1 MDF ;
+ import from CDF;
+ import from ErrorFunctions ;
+ import from MDF ;
+ import from NagResultChecks ;
+ import from NagEigenPackage ;
+ import from List STRG ;
+ import from Symbol ;
+ import from VDF ;
+ import from Boolean ;
+ import from Result ;
+
+ local (..)(a:INT,b:INT):Generator INT == {
+ generate {
+ t := a ;
+ while (t <= b) repeat {
+ yield t ;
+ t := t + 1 ;
+ }
+ }
+ }
+
+ local ipIfail : INT := -1 ;
+
+ -- First, some local functions:
+
+ f02bjfEigVals(A : MDF, B : MDF, orderAB : INT, eps : DF) : LFFCDF == {
+
+ -- orderAB is the common order of the square matrices A and B.
+
+ local f02bjfResult : RSLT ;
+ local numR, numI, den : LDF ;
+
+ f02bjfResult := f02bjf(orderAB,orderAB,orderAB,eps,
+ false,orderAB,A,B,ipIfail) ;
+ den := entries(row(checkMxDF(f02bjfResult, "beta", "F02BJF"), 1)) ;
+ numR := entries(row(retract(f02bjfResult."alfr") @ MDF, 1)) ;
+ numI := entries(row(retract(f02bjfResult."alfi") @ MDF, 1)) ;
+
+ [ (complex(r,i)/complex(d,0@DF))$FFCDF for r in numR
+ for i in numI
+ for d in den ]
+
+ }
+
+
+ f02bjfEigVecs(A : MDF, B : MDF, orderAB : INT, eps : DF) : RURSLV == {
+
+ -- orderAB is the common order of the square matrices A and B.
+
+ local size : NNI ;
+ local f02bjfResult : RSLT ;
+ local numR, numI, den : LDF ;
+ local eVals : UNNRES ;
+ local vecMat : MDF ;
+ local eVecs : LVCDF ;
+ local j : INT ;
+ local thisVec, leftVec : VCDF ;
+
+ size := orderAB pretend NNI ;
+
+ f02bjfResult := f02bjf(orderAB,orderAB,orderAB,eps,
+ true,orderAB,A,B,ipIfail) ;
+
+ den := entries(row(checkMxDF(f02bjfResult, "beta", "F02BJF"), 1)) ;
+ numR := entries(row(retract(f02bjfResult."alfr") @ MDF, 1)) ;
+ numI := entries(row(retract(f02bjfResult."alfi") @ MDF, 1)) ;
+ vecMat := retract(f02bjfResult."v") @ MDF ;
+
+ -- outer [] for union type:
+ eVals := [[(complex(r,i)/complex(d,0@DF))$FFCDF for r in numR
+ for i in numI
+ for d in den]] ;
+
+ eVecs := [] ;
+ j := orderAB ;
+ while j > 0 repeat {
+ if numI.j ~= 0$DF then {
+ if j = 1 or numI.(j-1) = 0$DF then
+ error("nagEigenvectors",
+ "Inconsistent results returned from NAG routine F02BJF") ;
+ thisVec := new(size,0) ;
+ leftVec := new(size,0) ;
+ for i in 1 .. orderAB repeat {
+ thisVec.i := complex(vecMat(i,j-1),-vecMat(i,j)) ;
+ leftVec.i := complex(vecMat(i,j-1),vecMat(i,j)) ;
+ }
+ eVecs := cons(leftVec,cons(thisVec,eVecs)) ;
+ j := j - 2;
+ }
+ else {
+ thisVec := new(size,0) ;
+ for i in 1 .. orderAB repeat
+ thisVec.i := complex(vecMat(i,j),0@DF) ;
+ eVecs := cons(thisVec,eVecs) ;
+ j := j - 1 ;
+ }
+ }
+
+ [eVals,eVecs]
+
+ }
+
+
+ nagError(routine : STRG, opIfail : INT) : Exit ==
+ error ["An error was detected when calling the NAG Library routine ",
+ routine,
+ ". The error number (IFAIL value) is ",
+ string(opIfail),
+ ", please consult the NAG manual via the Browser for",
+ " diagnostic information."] ;
+
+ -- Then the exported functions:
+
+ nagEigenvalues(A : MDF, B : MDF, eps : DF) : UNNRES == {
+
+ -- Strategy: if either matrix is asymmetric, use F02BJF, otherwise
+ -- try F02ADF in case B is positive-definite.
+ -- If F02ADF gives IFAIL=1 (should happen quickly if at all),
+ -- not positive-definite, use less efficient F02BJF.
+
+ local rA, rB, cA, cB : NNI ;
+ local orderAB, opIfail: INT ;
+ local vals : UNNRES ;
+
+ rA := nrows A ;
+ rB := nrows B ;
+
+ if rA ~= rB
+ then error("nagEigenvalues",
+ "the two matrices supplied are of different sizes.") ;
+ orderAB := rA pretend INT ;
+
+ if symmetric?(A) and symmetric?(B) then {
+ f02adfResult := f02adf(orderAB,orderAB,orderAB,A,B,ipIfail) ;
+ opIfail := retract(f02adfResult."ifail") @ INT ;
+ if zero? opIfail then -- using [] to give union type:
+ vals := [entries(row(retract(f02adfResult."r") @ MDF,1))] ;
+ else if opIfail = 1 then
+ vals := [f02bjfEigVals(A,B,orderAB,eps)]
+ else
+ nagError("F02BJF",opIfail) ;
+ }
+ else {
+ cA := ncols A ;
+ if cA ~= rA then
+ error("nagEigenvalues",
+ "the first matrix supplied is not square") ;
+ cB := ncols B ;
+ if cB ~= rB then
+ error("nagEigenvalues",
+ "the second matrix supplied is not square") ;
+ vals := [f02bjfEigVals(A,B,orderAB,eps)] ;
+ }
+
+ vals
+
+ }
+
+
+ nagEigenvalues(A : MDF, B : MDF) : UNNRES
+ == nagEigenvalues(A,B,0@DF) ;
+
+
+ nagEigenvectors(A : MDF, B : MDF, eps : DF) : RURSLV == {
+
+ -- Strategy: if either matrix is asymmetric, use F02BJF, otherwise
+ -- try F02AEF in case B is positive-definite.
+ -- If F02AEF gives IFAIL=1 (should happen quickly if at all),
+ -- not positive-definite, use less efficient F02BJF.
+
+ local rA, rB, cA, cB : NNI ;
+ local orderAB, opIfail, j : INT ;
+ local eVals : UNNRES ;
+ local eVecs : LVCDF ;
+ local vecMat : MDF ;
+ local thisVec : VCDF ;
+ local f02aefResult : RSLT ;
+ local result : RURSLV ;
+
+ rA := nrows A ;
+ rB := nrows B ;
+
+ if rA ~= rB
+ then error("nagEigenvectors",
+ "the two matrices supplied are of different sizes.") ;
+ orderAB := rA pretend INT ;
+
+ if symmetric?(A) and symmetric?(B) then {
+ f02aefResult := f02aef(orderAB,orderAB,orderAB,
+ orderAB,A,B,ipIfail) ;
+ opIfail := retract(f02aefResult."ifail") @ INT ;
+ if zero? opIfail then {
+ -- using [] to give union type:
+ eVals := [entries(row(retract(f02aefResult."r") @ MDF,1))] ;
+ vecMat := retract(f02aefResult."v") @ MDF ;
+ eVecs := [] ;
+ j := orderAB ;
+ while j > 0 repeat {
+ thisVec := new(rA,0) ;
+ for i in 1 .. orderAB repeat
+ thisVec.i := complex(vecMat(i,j),0@DF) ;
+ eVecs := cons(thisVec,eVecs) ;
+ j := j - 1 ;
+ }
+ result := [eVals,eVecs]
+ }
+ else if opIfail = 1 then
+ result := f02bjfEigVecs(A,B,orderAB,eps)
+ else
+ nagError("F02BJF",opIfail) ;
+ }
+ else {
+ cA := ncols A ;
+ if cA ~= rA then
+ error("nagEigenvectors",
+ "the first matrix supplied is not square") ;
+ cB := ncols B ;
+ if cB ~= rB then
+ error("nagEigenvectors",
+ "the second matrix supplied is not square") ;
+ result := f02bjfEigVecs(A,B,orderAB,eps) ;
+ }
+
+ result
+
+ }
+
+
+ nagEigenvectors(A : MDF, B : MDF) : RURSLV
+ == nagEigenvectors(A,B,0@DF) ;
+
+}
+
+#if NeverAssertThis
+
+-- Note that the conversions of results from DoubleFloat to Float
+-- will become unnecessary if outputGeneral is extended to apply to
+-- DoubleFloat quantities.
+
+)lib nrc
+)lib ffrac
+)lib nepip
+
+outputGeneral 5
+
+mA1 := matrix [[ 0.5 , 1.5 , 6.6 , 4.8], _
+ [ 1.5 , 6.5 , 16.2 , 8.6], _
+ [ 6.6 , 16.2 , 37.6 , 9.8], _
+ [ 4.8 , 8.6 , 9.8 , -17.1]];
+
+mB1 := matrix[[ 1 , 3 , 4 , 1], _
+ [ 3 , 13 , 16 , 11], _
+ [ 4 , 16 , 24 , 18], _
+ [ 1 , 11 , 18 , 27]];
+
+mA2 := matrix [[ 3.9 , 12.5 , -34.5 , -0.5], _
+ [ 4.3 , 21.5 , -47.5 , 7.5], _
+ [ 4.3 , 21.5 , -43.5 , 3.5], _
+ [ 4.4 , 26.0 , -46.0 , 6.0]];
+
+mB2 := matrix[[ 1 , 2 , -3 , 1], _
+ [ 1 , 3 , -5 , 4], _
+ [ 1 , 3 , -4 , 3], _
+ [ 1 , 3 , -4 , 4]];
+
+nagEigenvalues(mA1,mB1) :: List Float
+
+-- [- 3.0,- 1.0,2.0,4.0]
+
+vv1 := nagEigenvectors(mA1,mB1);
+(vv1.eigenvalues) :: List Float
+
+-- [- 3.0,- 1.0,2.0,4.0]
+
+(vv1.eigenvectors) :: List Vector Complex Float
+
+-- [[- 4.35,0.05,1.0,- 0.5], [- 2.05,0.15,0.5,- 0.5], [- 3.95,0.85,0.5,- 0.5],
+-- [2.65,0.05,- 1.0,0.5]]
+
+nagEigenvalues(mA2,mB2)
+
+-- all components are O(1) or more so:
+
+% :: List Complex Float
+
+-- [2.0,3.0 + 4.0 %i,3.0 - 4.0 %i,4.0]
+
+vv2 := nagEigenvectors(mA2,mB2);
+vv2.eigenvalues
+
+-- all components are O(1) or more so:
+
+% :: List Complex Float
+
+-- [2.0,3.0 + 4.0 %i,3.0 - 4.0 %i,4.0]
+
+vv2.eigenvectors :: List Vector Complex Float
+
+-- [[0.99606,0.0056917,0.062609,0.062609],
+--
+-- [0.94491, 0.18898 + 0.26077 E -14 %i, 0.11339 - 0.15119 %i,
+-- 0.11339 - 0.15119 %i]
+-- ,
+--
+-- [0.94491, 0.18898 - 0.26077 E -14 %i, 0.11339 + 0.15119 %i,
+-- 0.11339 + 0.15119 %i]
+-- ,
+-- [0.98752,0.010972,- 0.032917,0.15361]]
+
+-- The same call with eps=0.0001:
+
+vv2a := nagEigenvectors(mA2,mB2,0.0001);
+vv2a.eigenvalues :: List Complex Float
+
+-- [1.9989,3.0003 + 3.9994 %i,3.0003 - 3.9994 %i,4.0]
+
+vv2a.eigenvectors :: List Vector Complex Float
+
+-- [[0.99605,0.0057355,0.062656,0.062656],
+--
+-- [0.94491, 0.18899 - 0.000048882 %i, 0.11336 - 0.15119 %i,
+-- 0.11336 - 0.15119 %i]
+-- ,
+--
+-- [0.94491, 0.18899 + 0.000048882 %i, 0.11336 + 0.15119 %i,
+-- 0.11336 + 0.15119 %i]
+-- ,
+-- [0.98751,0.011031,- 0.032912,0.15367]]
+
+mB1(1,1) := -1;
+
+-- The next test should fail on F02ADF then call F02BJF:
+
+nagEigenvalues(mA1,mB1)
+
+-- all components are O(1) or more so:
+
+% :: List Complex Float
+
+-- [3.5016,- 1.5471,0.041212 + 0.21738 %i,0.041212 - 0.21738 %i]
+
+-- Similarly, this should fail on F02AEF then call F02BJF:
+
+vv3 := nagEigenvectors(mA1,mB1);
+vv3.eigenvalues
+
+-- all components are O(1) or more so:
+
+% :: List Complex Float
+
+-- [3.5016,- 1.5471,0.041212 + 0.21738 %i,0.041212 - 0.21738 %i]
+
+vv3.eigenvectors :: List Vector Complex Float
+
+-- [[- 0.034577,0.63045,- 0.75202,0.1892],
+-- [0.17876,- 0.73845,0.047413,0.64845],
+--
+-- [0.80838, - 0.00095133 + 0.47557 %i, - 0.20354 - 0.21737 %i,
+-- 0.15404 + 0.089179 %i]
+-- ,
+--
+-- [0.80838, - 0.00095133 - 0.47557 %i, - 0.20354 + 0.21737 %i,
+-- 0.15404 - 0.089179 %i]
+-- ]
+
+outputGeneral()
+
+output "End of tests"
+
+#endif
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- NagEigenProblemInterfacePackage
+
+-- To test:
+-- sed '1,/^#if NeverAssertThis/d;/#endif/d' < nepip.as > nepip.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r nepip.input
+
+#unassert saturn
+
+#include "axiom.as"
+
+<<NagEigenInterfacePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/newdata.spad.pamphlet b/src/algebra/newdata.spad.pamphlet
new file mode 100644
index 00000000..7e053170
--- /dev/null
+++ b/src/algebra/newdata.spad.pamphlet
@@ -0,0 +1,671 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra newdata.spad}
+\author{Themos Tsikas, Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IPRNTPK InternalPrintPackage}
+<<package IPRNTPK InternalPrintPackage>>=
+)abbrev package IPRNTPK InternalPrintPackage
+++ Author: Themos Tsikas
+++ Date Created: 09/09/1998
+++ Date Last Updated: 09/09/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: A package to print strings without line-feed
+++ nor carriage-return.
+
+InternalPrintPackage(): Exports == Implementation where
+
+ Exports == with
+ iprint: String -> Void
+ ++ \axiom{iprint(s)} prints \axiom{s} at the current position
+ ++ of the cursor.
+
+ Implementation == add
+ iprint(s:String) ==
+ PRINC(coerce(s)@Symbol)$Lisp
+ FLUSH()$Lisp
+
+@
+\section{package TBCMPPK TabulatedComputationPackage}
+<<package TBCMPPK TabulatedComputationPackage>>=
+)abbrev package TBCMPPK TabulatedComputationPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 09/09/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \axiom{TabulatedComputationPackage(Key ,Entry)} provides some modest support
+++ for dealing with operations with type \axiom{Key -> Entry}. The result of
+++ such operations can be stored and retrieved with this package by using
+++ a hash-table. The user does not need to worry about the management of
+++ this hash-table. However, onnly one hash-table is built by calling
+++ \axiom{TabulatedComputationPackage(Key ,Entry)}.
+++ Version: 2.
+
+TabulatedComputationPackage(Key ,Entry): Exports == Implementation where
+ Key: SetCategory
+ Entry: SetCategory
+ N ==> NonNegativeInteger
+ H ==> HashTable(Key, Entry, "UEQUAL")
+ iprintpack ==> InternalPrintPackage()
+
+ Exports == with
+ initTable!: () -> Void
+ ++ \axiom{initTable!()} initializes the hash-table.
+ printInfo!: (String, String) -> Void
+ ++ \axiom{printInfo!(x,y)} initializes the mesages to be printed
+ ++ when manipulating items from the hash-table. If
+ ++ a key is retrieved then \axiom{x} is displayed. If an item is
+ ++ stored then \axiom{y} is displayed.
+ startStats!: (String) -> Void
+ ++ \axiom{startStats!(x)} initializes the statisitics process and
+ ++ sets the comments to display when statistics are printed
+ printStats!: () -> Void
+ ++ \axiom{printStats!()} prints the statistics.
+ clearTable!: () -> Void
+ ++ \axiom{clearTable!()} clears the hash-table and assumes that
+ ++ it will no longer be used.
+ usingTable?: () -> Boolean
+ ++ \axiom{usingTable?()} returns true iff the hash-table is used
+ printingInfo?: () -> Boolean
+ ++ \axiom{printingInfo?()} returns true iff messages are printed
+ ++ when manipulating items from the hash-table.
+ makingStats?: () -> Boolean
+ ++ \axiom{makingStats?()} returns true iff the statisitics process
+ ++ is running.
+ extractIfCan: Key -> Union(Entry,"failed")
+ ++ \axiom{extractIfCan(x)} searches the item whose key is \axiom{x}.
+ insert!: (Key, Entry) -> Void
+ ++ \axiom{insert!(x,y)} stores the item whose key is \axiom{x} and whose
+ ++ entry is \axiom{y}.
+
+ Implementation == add
+ table?: Boolean := false
+ t: H := empty()
+ info?: Boolean := false
+ stats?: Boolean := false
+ used: NonNegativeInteger := 0
+ ok: String := "o"
+ ko: String := "+"
+ domainName: String := empty()$String
+
+ initTable!(): Void ==
+ table? := true
+ t := empty()
+ void()
+ printInfo!(s1: String, s2: String): Void ==
+ (empty? s1) or (empty? s2) => void()
+ not usingTable? =>
+ error "in printInfo!()$TBCMPPK: not allowed to use hashtable"
+ info? := true
+ ok := s1
+ ko := s2
+ void()
+ startStats!(s: String): Void ==
+ empty? s => void()
+ not table? =>
+ error "in startStats!()$TBCMPPK: not allowed to use hashtable"
+ stats? := true
+ used := 0
+ domainName := s
+ void()
+ printStats!(): Void ==
+ not table? =>
+ error "in printStats!()$TBCMPPK: not allowed to use hashtable"
+ not stats? =>
+ error "in printStats!()$TBCMPPK: statistics not started"
+ output(" ")$OutputPackage
+ title: String := concat("*** ", concat(domainName," Statistics ***"))
+ output(title)$OutputPackage
+ n: N := #t
+ output(" Table size: ", n::OutputForm)$OutputPackage
+ output(" Entries reused: ", used::OutputForm)$OutputPackage
+ clearTable!(): Void ==
+ not table? =>
+ error "in clearTable!()$TBCMPPK: not allowed to use hashtable"
+ t := empty()
+ table? := false
+ info? := false
+ stats? := false
+ domainName := empty()$String
+ void()
+ usingTable?() == table?
+ printingInfo?() == info?
+ makingStats?() == stats?
+ extractIfCan(k: Key): Union(Entry,"failed") ==
+ not table? => "failed" :: Union(Entry,"failed")
+ s: Union(Entry,"failed") := search(k,t)
+ s case Entry =>
+ if info? then iprint(ok)$iprintpack
+ if stats? then used := used + 1
+ return s
+ "failed" :: Union(Entry,"failed")
+ insert!(k: Key, e:Entry): Void ==
+ not table? => void()
+ t.k := e
+ if info? then iprint(ko)$iprintpack
+ void()
+
+@
+\section{domain SPLNODE SplittingNode}
+<<domain SPLNODE SplittingNode>>=
+)abbrev domain SPLNODE SplittingNode
+++ Author: Marc Moereno Maza
+++ Date Created: 07/05/1996
+++ Date Last Updated: 07/19/1996
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ References:
+++ Description:
+++ This domain exports a modest implementation for the
+++ vertices of splitting trees. These vertices are called
+++ here splitting nodes. Every of these nodes store 3 informations.
+++ The first one is its value, that is the current expression
+++ to evaluate. The second one is its condition, that is the
+++ hypothesis under which the value has to be evaluated.
+++ The last one is its status, that is a boolean flag
+++ which is true iff the value is the result of its
+++ evaluation under its condition. Two splitting vertices
+++ are equal iff they have the sane values and the same
+++ conditions (so their status do not matter).
+
+SplittingNode(V,C) : Exports == Implementation where
+
+ V:Join(SetCategory,Aggregate)
+ C:Join(SetCategory,Aggregate)
+ Z ==> Integer
+ B ==> Boolean
+ O ==> OutputForm
+ VT ==> Record(val:V, tower:C)
+ VTB ==> Record(val:V, tower:C, flag:B)
+
+ Exports == SetCategory with
+
+ empty : () -> %
+ ++ \axiom{empty()} returns the same as
+ ++ \axiom{[empty()$V,empty()$C,false]$%}
+ empty? : % -> B
+ ++ \axiom{empty?(n)} returns true iff the node n is \axiom{empty()$%}.
+ value : % -> V
+ ++ \axiom{value(n)} returns the value of the node n.
+ condition : % -> C
+ ++ \axiom{condition(n)} returns the condition of the node n.
+ status : % -> B
+ ++ \axiom{status(n)} returns the status of the node n.
+ construct : (V,C,B) -> %
+ ++ \axiom{construct(v,t,b)} returns the non-empty node with
+ ++ value v, condition t and flag b
+ construct : (V,C) -> %
+ ++ \axiom{construct(v,t)} returns the same as
+ ++ \axiom{construct(v,t,false)}
+ construct : VT -> %
+ ++ \axiom{construct(vt)} returns the same as
+ ++ \axiom{construct(vt.val,vt.tower)}
+ construct : List VT -> List %
+ ++ \axiom{construct(lvt)} returns the same as
+ ++ \axiom{[construct(vt.val,vt.tower) for vt in lvt]}
+ construct : (V, List C) -> List %
+ ++ \axiom{construct(v,lt)} returns the same as
+ ++ \axiom{[construct(v,t) for t in lt]}
+ copy : % -> %
+ ++ \axiom{copy(n)} returns a copy of n.
+ setValue! : (%,V) -> %
+ ++ \axiom{setValue!(n,v)} returns n whose value
+ ++ has been replaced by v if it is not
+ ++ empty, else an error is produced.
+ setCondition! : (%,C) -> %
+ ++ \axiom{setCondition!(n,t)} returns n whose condition
+ ++ has been replaced by t if it is not
+ ++ empty, else an error is produced.
+ setStatus!: (%,B) -> %
+ ++ \axiom{setStatus!(n,b)} returns n whose status
+ ++ has been replaced by b if it is not
+ ++ empty, else an error is produced.
+ setEmpty! : % -> %
+ ++ \axiom{setEmpty!(n)} replaces n by \axiom{empty()$%}.
+ infLex? : (%,%,(V,V) -> B,(C,C) -> B) -> B
+ ++ \axiom{infLex?(n1,n2,o1,o2)} returns true iff
+ ++ \axiom{o1(value(n1),value(n2))} or
+ ++ \axiom{value(n1) = value(n2)} and
+ ++ \axiom{o2(condition(n1),condition(n2))}.
+ subNode? : (%,%,(C,C) -> B) -> B
+ ++ \axiom{subNode?(n1,n2,o2)} returns true iff
+ ++ \axiom{value(n1) = value(n2)} and
+ ++ \axiom{o2(condition(n1),condition(n2))}
+
+ Implementation == add
+
+ Rep ==> VTB
+
+ rep(n:%):Rep == n pretend Rep
+ per(r:Rep):% == r pretend %
+
+ empty() == per [empty()$V,empty()$C,false]$Rep
+ empty?(n:%) == empty?((rep n).val)$V and empty?((rep n).tower)$C
+ value(n:%) == (rep n).val
+ condition(n:%) == (rep n).tower
+ status(n:%) == (rep n).flag
+ construct(v:V,t:C,b:B) == per [v,t,b]$Rep
+ construct(v:V,t:C) == [v,t,false]$%
+ construct(vt:VT) == [vt.val,vt.tower]$%
+ construct(lvt:List VT) == [[vt]$% for vt in lvt]
+ construct(v:V,lt: List C) == [[v,t]$% for t in lt]
+ copy(n:%) == per copy rep n
+ setValue!(n:%,v:V) ==
+ (rep n).val := v
+ n
+ setCondition!(n:%,t:C) ==
+ (rep n).tower := t
+ n
+ setStatus!(n:%,b:B) ==
+ (rep n).flag := b
+ n
+ setEmpty!(n:%) ==
+ (rep n).val := empty()$V
+ (rep n).tower := empty()$C
+ n
+ infLex?(n1,n2,o1,o2) ==
+ o1((rep n1).val,(rep n2).val) => true
+ (rep n1).val = (rep n2).val =>
+ o2((rep n1).tower,(rep n2).tower)
+ false
+ subNode?(n1,n2,o2) ==
+ (rep n1).val = (rep n2).val =>
+ o2((rep n1).tower,(rep n2).tower)
+ false
+ -- sample() == empty()
+ n1:% = n2:% ==
+ (rep n1).val ~= (rep n2).val => false
+ (rep n1).tower = (rep n2).tower
+ n1:% ~= n2:% ==
+ (rep n1).val = (rep n2).val => false
+ (rep n1).tower ~= (rep n2).tower
+ coerce(n:%):O ==
+ l1,l2,l3,l : List O
+ l1 := [message("value == "), ((rep n).val)::O]
+ o1 : O := blankSeparate l1
+ l2 := [message(" tower == "), ((rep n).tower)::O]
+ o2 : O := blankSeparate l2
+ if ((rep n).flag)
+ then
+ o3 := message(" closed == true")
+ else
+ o3 := message(" closed == false")
+ l := [o1,o2,o3]
+ bracket commaSeparate l
+
+@
+\section{domain SPLTREE SplittingTree}
+<<domain SPLTREE SplittingTree>>=
+)abbrev domain SPLTREE SplittingTree
+++ Author: Marc Moereno Maza
+++ Date Created: 07/05/1996
+++ Date Last Updated: 07/19/1996
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+++ Description:
+++ This domain exports a modest implementation of splitting
+++ trees. Spliiting trees are needed when the
+++ evaluation of some quantity under some hypothesis
+++ requires to split the hypothesis into sub-cases.
+++ For instance by adding some new hypothesis on one
+++ hand and its negation on another hand. The computations
+++ are terminated is a splitting tree \axiom{a} when
+++ \axiom{status(value(a))} is \axiom{true}. Thus,
+++ if for the splitting tree \axiom{a} the flag
+++ \axiom{status(value(a))} is \axiom{true}, then
+++ \axiom{status(value(d))} is \axiom{true} for any
+++ subtree \axiom{d} of \axiom{a}. This property
+++ of splitting trees is called the termination
+++ condition. If no vertex in a splitting tree \axiom{a}
+++ is equal to another, \axiom{a} is said to satisfy
+++ the no-duplicates condition. The splitting
+++ tree \axiom{a} will satisfy this condition
+++ if nodes are added to \axiom{a} by mean of
+++ \axiom{splitNodeOf!} and if \axiom{construct}
+++ is only used to create the root of \axiom{a}
+++ with no children.
+
+SplittingTree(V,C) : Exports == Implementation where
+
+ V:Join(SetCategory,Aggregate)
+ C:Join(SetCategory,Aggregate)
+ B ==> Boolean
+ O ==> OutputForm
+ NNI ==> NonNegativeInteger
+ VT ==> Record(val:V, tower:C)
+ VTB ==> Record(val:V, tower:C, flag:B)
+ S ==> SplittingNode(V,C)
+ A ==> Record(root:S,subTrees:List(%))
+
+ Exports == RecursiveAggregate(S) with
+ shallowlyMutable
+ finiteAggregate
+ extractSplittingLeaf : % -> Union(%,"failed")
+ ++ \axiom{extractSplittingLeaf(a)} returns the left
+ ++ most leaf (as a tree) whose status is false
+ ++ if any, else "failed" is returned.
+ updateStatus! : % -> %
+ ++ \axiom{updateStatus!(a)} returns a where the status
+ ++ of the vertices are updated to satisfy
+ ++ the "termination condition".
+ construct : S -> %
+ ++ \axiom{construct(s)} creates a splitting tree
+ ++ with value (i.e. root vertex) given by
+ ++ \axiom{s} and no children. Thus, if the
+ ++ status of \axiom{s} is false, \axiom{[s]}
+ ++ represents the starting point of the
+ ++ evaluation \axiom{value(s)} under the
+ ++ hypothesis \axiom{condition(s)}.
+ construct : (V,C, List %) -> %
+ ++ \axiom{construct(v,t,la)} creates a splitting tree
+ ++ with value (i.e. root vertex) given by
+ ++ \axiom{[v,t]$S} and with \axiom{la} as
+ ++ children list.
+ construct : (V,C,List S) -> %
+ ++ \axiom{construct(v,t,ls)} creates a splitting tree
+ ++ with value (i.e. root vertex) given by
+ ++ \axiom{[v,t]$S} and with children list given by
+ ++ \axiom{[[s]$% for s in ls]}.
+ construct : (V,C,V,List C) -> %
+ ++ \axiom{construct(v1,t,v2,lt)} creates a splitting tree
+ ++ with value (i.e. root vertex) given by
+ ++ \axiom{[v,t]$S} and with children list given by
+ ++ \axiom{[[[v,t]$S]$% for s in ls]}.
+ conditions : % -> List C
+ ++ \axiom{conditions(a)} returns the list of the conditions
+ ++ of the leaves of a
+ result : % -> List VT
+ ++ \axiom{result(a)} where \axiom{ls} is the leaves list of \axiom{a}
+ ++ returns \axiom{[[value(s),condition(s)]$VT for s in ls]}
+ ++ if the computations are terminated in \axiom{a} else
+ ++ an error is produced.
+ nodeOf? : (S,%) -> B
+ ++ \axiom{nodeOf?(s,a)} returns true iff some node of \axiom{a}
+ ++ is equal to \axiom{s}
+ subNodeOf? : (S,%,(C,C) -> B) -> B
+ ++ \axiom{subNodeOf?(s,a,sub?)} returns true iff for some node
+ ++ \axiom{n} in \axiom{a} we have \axiom{s = n} or
+ ++ \axiom{status(n)} and \axiom{subNode?(s,n,sub?)}.
+ remove : (S,%) -> %
+ ++ \axiom{remove(s,a)} returns the splitting tree obtained
+ ++ from a by removing every sub-tree \axiom{b} such
+ ++ that \axiom{value(b)} and \axiom{s} have the same
+ ++ value, condition and status.
+ remove! : (S,%) -> %
+ ++ \axiom{remove!(s,a)} replaces a by remove(s,a)
+ splitNodeOf! : (%,%,List(S)) -> %
+ ++ \axiom{splitNodeOf!(l,a,ls)} returns \axiom{a} where the children
+ ++ list of \axiom{l} has been set to
+ ++ \axiom{[[s]$% for s in ls | not nodeOf?(s,a)]}.
+ ++ Thus, if \axiom{l} is not a node of \axiom{a}, this
+ ++ latter splitting tree is unchanged.
+ splitNodeOf! : (%,%,List(S),(C,C) -> B) -> %
+ ++ \axiom{splitNodeOf!(l,a,ls,sub?)} returns \axiom{a} where the children
+ ++ list of \axiom{l} has been set to
+ ++ \axiom{[[s]$% for s in ls | not subNodeOf?(s,a,sub?)]}.
+ ++ Thus, if \axiom{l} is not a node of \axiom{a}, this
+ ++ latter splitting tree is unchanged.
+
+
+ Implementation == add
+
+ Rep ==> A
+
+ rep(n:%):Rep == n pretend Rep
+ per(r:Rep):% == r pretend %
+
+ construct(s:S) ==
+ per [s,[]]$A
+ construct(v:V,t:C,la:List(%)) ==
+ per [[v,t]$S,la]$A
+ construct(v:V,t:C,ls:List(S)) ==
+ per [[v,t]$S,[[s]$% for s in ls]]$A
+ construct(v1:V,t:C,v2:V,lt:List(C)) ==
+ [v1,t,([v2,lt]$S)@(List S)]$%
+
+ empty?(a:%) == empty?((rep a).root) and empty?((rep a).subTrees)
+ empty() == [empty()$S]$%
+
+ remove(s:S,a:%) ==
+ empty? a => a
+ (s = value(a)) and (status(s) = status(value(a))) => empty()$%
+ la := children(a)
+ lb : List % := []
+ while (not empty? la) repeat
+ lb := cons(remove(s,first la), lb)
+ la := rest la
+ lb := reverse remove(empty?,lb)
+ [value(value(a)),condition(value(a)),lb]$%
+
+ remove!(s:S,a:%) ==
+ empty? a => a
+ (s = value(a)) and (status(s) = status(value(a))) =>
+ (rep a).root := empty()$S
+ (rep a).subTrees := []
+ a
+ la := children(a)
+ lb : List % := []
+ while (not empty? la) repeat
+ lb := cons(remove!(s,first la), lb)
+ la := rest la
+ lb := reverse remove(empty()$%,lb)
+ setchildren!(a,lb)
+
+ value(a:%) ==
+ (rep a).root
+ children(a:%) ==
+ (rep a).subTrees
+ leaf?(a:%) ==
+ empty? a => false
+ empty? (rep a).subTrees
+ setchildren!(a:%,la:List(%)) ==
+ (rep a).subTrees := la
+ a
+ setvalue!(a:%,s:S) ==
+ (rep a).root := s
+ s
+ cyclic?(a:%) == false
+ map(foo:(S -> S),a:%) ==
+ empty? a => a
+ b : % := [foo(value(a))]$%
+ leaf? a => b
+ setchildren!(b,[map(foo,c) for c in children(a)])
+ map!(foo:(S -> S),a:%) ==
+ empty? a => a
+ setvalue!(a,foo(value(a)))
+ leaf? a => a
+ setchildren!(a,[map!(foo,c) for c in children(a)])
+ copy(a:%) ==
+ map(copy,a)
+ eq?(a1:%,a2:%) ==
+ error"in eq? from SPLTREE : la vache qui rit est-elle folle?"
+ nodes(a:%) ==
+ empty? a => []
+ leaf? a => [a]
+ cons(a,concat([nodes(c) for c in children(a)]))
+ leaves(a:%) ==
+ empty? a => []
+ leaf? a => [value(a)]
+ concat([leaves(c) for c in children(a)])
+ members(a:%) ==
+ empty? a => []
+ leaf? a => [value(a)]
+ cons(value(a),concat([members(c) for c in children(a)]))
+ #(a:%) ==
+ empty? a => 0$NNI
+ leaf? a => 1$NNI
+ reduce("+",[#c for c in children(a)],1$NNI)$(List NNI)
+ a1:% = a2:% ==
+ empty? a1 => empty? a2
+ empty? a2 => false
+ leaf? a1 =>
+ not leaf? a2 => false
+ value(a1) =$S value(a2)
+ leaf? a2 => false
+ value(a1) ~=$S value(a2) => false
+ children(a1) = children(a2)
+ -- sample() == [sample()$S]$%
+ localCoerce(a:%,k:NNI):O ==
+ s : String
+ if k = 1 then s := "* " else s := "-> "
+ for i in 2..k repeat s := concat("-+",s)$String
+ ro : O := left(hconcat(message(s)$O,value(a)::O)$O)$O
+ leaf? a => ro
+ lo : List O := [localCoerce(c,k+1) for c in children(a)]
+ lo := cons(ro,lo)
+ vconcat(lo)$O
+ coerce(a:%):O ==
+ empty? a => vconcat(message(" ")$O,message("* []")$O)
+ vconcat(message(" ")$O,localCoerce(a,1))
+
+ extractSplittingLeaf(a:%) ==
+ empty? a => "failed"::Union(%,"failed")
+ status(value(a))$S => "failed"::Union(%,"failed")
+ la := children(a)
+ empty? la => a
+ while (not empty? la) repeat
+ esl := extractSplittingLeaf(first la)
+ (esl case %) => return(esl)
+ la := rest la
+ "failed"::Union(%,"failed")
+
+ updateStatus!(a:%) ==
+ la := children(a)
+ (empty? la) or (status(value(a))$S) => a
+ done := true
+ while (not empty? la) and done repeat
+ done := done and status(value(updateStatus! first la))
+ la := rest la
+ setStatus!(value(a),done)$S
+ a
+
+ result(a:%) ==
+ empty? a => []
+ not status(value(a))$S =>
+ error"in result from SLPTREE : mad cow!"
+ ls : List S := leaves(a)
+ [[value(s),condition(s)]$VT for s in ls]
+
+ conditions(a:%) ==
+ empty? a => []
+ ls : List S := leaves(a)
+ [condition(s) for s in ls]
+
+ nodeOf?(s:S,a:%) ==
+ empty? a => false
+ s =$S value(a) => true
+ la := children(a)
+ while (not empty? la) and (not nodeOf?(s,first la)) repeat
+ la := rest la
+ not empty? la
+
+ subNodeOf?(s:S,a:%,sub?:((C,C) -> B)) ==
+ empty? a => false
+ -- s =$S value(a) => true
+ status(value(a)$%)$S and subNode?(s,value(a),sub?)$S => true
+ la := children(a)
+ while (not empty? la) and (not subNodeOf?(s,first la,sub?)) repeat
+ la := rest la
+ not empty? la
+
+ splitNodeOf!(l:%,a:%,ls:List(S)) ==
+ ln := removeDuplicates ls
+ la : List % := []
+ while not empty? ln repeat
+ if not nodeOf?(first ln,a)
+ then
+ la := cons([first ln]$%, la)
+ ln := rest ln
+ la := reverse la
+ setchildren!(l,la)$%
+ if empty? la then (rep l).root := [empty()$V,empty()$C,true]$S
+ updateStatus!(a)
+
+ splitNodeOf!(l:%,a:%,ls:List(S),sub?:((C,C) -> B)) ==
+ ln := removeDuplicates ls
+ la : List % := []
+ while not empty? ln repeat
+ if not subNodeOf?(first ln,a,sub?)
+ then
+ la := cons([first ln]$%, la)
+ ln := rest ln
+ la := reverse la
+ setchildren!(l,la)$%
+ if empty? la then (rep l).root := [empty()$V,empty()$C,true]$S
+ updateStatus!(a)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package IPRNTPK InternalPrintPackage>>
+<<package TBCMPPK TabulatedComputationPackage>>
+<<domain SPLNODE SplittingNode>>
+<<domain SPLTREE SplittingTree>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/newpoint.spad.pamphlet b/src/algebra/newpoint.spad.pamphlet
new file mode 100644
index 00000000..b6b32e30
--- /dev/null
+++ b/src/algebra/newpoint.spad.pamphlet
@@ -0,0 +1,732 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra newpoint.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PTCAT PointCategory}
+<<category PTCAT PointCategory>>=
+)abbrev category PTCAT PointCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Operations: point, elt, setelt, copy, dimension, minIndex, maxIndex,
+++ convert
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: PointCategory is the category of points in space which
+++ may be plotted via the graphics facilities. Functions are provided for
+++ defining points and handling elements of points.
+
+PointCategory(R:Ring) : Category == VectorCategory(R) with
+ point: List R -> %
+ ++ point(l) returns a point category defined by a list l of elements from
+ ++ the domain R.
+ dimension: % -> PositiveInteger
+ ++ dimension(s) returns the dimension of the point category s.
+ convert: List R -> %
+ ++ convert(l) takes a list of elements, l, from the domain Ring and
+ ++ returns the form of point category.
+ cross: (%,%) -> %
+ ++ cross(p,q) computes the cross product of the two points \spad{p}
+ ++ and \spad{q}. Error if the p and q are not 3 dimensional
+ extend : (%,List R) -> %
+ ++ extend(x,l,r) \undocumented
+
+@
+\section{domain POINT Point}
+<<domain POINT Point>>=
+)abbrev domain POINT Point
+++ Description:
+++ This domain implements points in coordinate space
+
+Point(R:Ring) : Exports == Implementation where
+ -- Domains for points, subspaces and properties of components in
+ -- a subspace
+
+ Exports ==> PointCategory(R)
+
+ Implementation ==> Vector (R) add
+ PI ==> PositiveInteger
+
+ point(l:List R):% ==
+ pt := new(#l,R)
+ for x in l for i in minIndex(pt).. repeat
+ pt.i := x
+ pt
+ dimension p == (# p)::PI -- Vector returns NonNegativeInteger...?
+ convert(l:List R):% == point(l)
+ cross(p0, p1) ==
+ #p0 ^=3 or #p1^=3 => error "Arguments to cross must be three dimensional"
+ point [p0.2 * p1.3 - p1.2 * p0.3, _
+ p1.1 * p0.3 - p0.1 * p1.3, _
+ p0.1 * p1.2 - p1.1 * p0.2]
+ extend(p,l) == concat(p,point l)
+
+@
+\section{domain COMPPROP SubSpaceComponentProperty}
+<<domain COMPPROP SubSpaceComponentProperty>>=
+)abbrev domain COMPPROP SubSpaceComponentProperty
+++ Description:
+++ This domain implements some global properties of subspaces.
+
+SubSpaceComponentProperty() : Exports == Implementation where
+
+ O ==> OutputForm
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ L ==> List
+ B ==> Boolean
+
+ Exports ==> SetCategory with
+ new : () -> %
+ ++ new() \undocumented
+ closed? : % -> B
+ ++ closed?(x) \undocumented
+ solid? : % -> B
+ ++ solid?(x) \undocumented
+ close : (%,B) -> B
+ ++ close(x,b) \undocumented
+ solid : (%,B) -> B
+ ++ solid(x,b) \undocumented
+ copy : % -> %
+ ++ copy(x) \undocumented
+
+ Implementation ==> add
+ Rep := Record(closed:B, solid:B)
+ closed? p == p.closed
+ solid? p == p.solid
+ close(p,b) == p.closed := b
+ solid(p,b) == p.solid := b
+ new() == [false,false]
+ copy p ==
+ annuderOne := new()
+ close(annuderOne,closed? p)
+ solid(annuderOne,solid? p)
+ annuderOne
+ coerce p ==
+ hconcat(["Component is "::O,
+ (closed? p => ""::O; "not "::O),"closed, "::O, _
+ (solid? p => ""::O; "not "::O),"solid"::O ])
+
+@
+\section{domain SUBSPACE SubSpace}
+<<domain SUBSPACE SubSpace>>=
+)abbrev domain SUBSPACE SubSpace
+++ Description:
+++ This domain \undocumented
+SubSpace(n:PI,R:Ring) : Exports == Implementation where
+ -- n is the dimension of the subSpace
+ -- The SubSpace domain is implemented as a tree. The root of the tree
+ -- is the only node in which the field dataList - which points to a
+ -- list of points over the ring, R - is defined. The children of the
+ -- root are the top level components of the SubSpace (in 2D, these
+ -- would be separate curves; in 3D, these would be separate surfaces).
+ -- The pt field is only defined in the leaves.
+ -- By way of example, consider a three dimensional subspace with
+ -- two components - a three by three grid and a sphere. The internal
+ -- representation of this subspace is a tree with a depth of three.
+ -- The root holds a list of all the points used in the subspace (so,
+ -- if the grid and the sphere share points, the shared points would not
+ -- be represented redundantly but would be referenced by index).
+ -- The root, in this case, has two children - the first points to the
+ -- grid component and the second to the sphere component. The grid child
+ -- has four children of its own - a 3x3 grid has 4 endpoints - and each
+ -- of these point to a list of four points. To see it another way, the
+ -- grid (child of the root) holds a list of line components which, when
+ -- placed one above the next, forms a grid. Each of these line components
+ -- is a list of points.
+ -- Points could be explicitly added to subspaces at any level. A path
+ -- could be given as an argument to the addPoint() function. It is a list
+ -- of NonNegativeIntegers and refers, in order, to the n-th child of the
+ -- current node. For example,
+ -- addPoint(s,[2,3],p)
+ -- would add the point p to the subspace s by going to the second child of
+ -- the root and then the third child of that node. If the path does extend
+ -- to the full depth of the tree, nodes are automatically added so that
+ -- the tree is of constant depth down any path. By not specifying the full
+ -- path, new components could be added - e.g. for s from SubSpace(3,Float)
+ -- addPoint(s,[],p)
+ -- would create a new child to the root (a new component in N-space) and
+ -- extend a path to a leaf of depth 3 that points to the data held in p.
+ -- The subspace s would now have a new component which has one child
+ -- which, in turn, has one child (the leaf). The new component is then a
+ -- point.
+
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ L ==> List
+ B ==> Boolean
+ POINT ==> Point(R)
+ PROP ==> SubSpaceComponentProperty()
+ S ==> String
+ O ==> OutputForm
+ empty ==> nil -- macro to ease conversion to new aggcat.spad
+
+ Exports ==> SetCategory with
+ leaf? : % -> B
+ ++ leaf?(x) \undocumented
+ root? : % -> B
+ ++ root?(x) \undocumented
+ internal? : % -> B
+ ++ internal?(x) \undocumented
+ new : () -> %
+ ++ new() \undocumented
+ subspace : () -> %
+ ++ subspace() \undocumented
+ birth : % -> % -- returns a pointer to the baby
+ ++ birth(x) \undocumented
+ child : (%,NNI) -> %
+ ++ child(x,n) \undocumented
+ children : % -> List %
+ ++ children(x) \undocumented
+ numberOfChildren: % -> NNI
+ ++ numberOfChildren(x) \undocumented
+ shallowCopy : % -> %
+ ++ shallowCopy(x) \undocumented
+ deepCopy : % -> %
+ ++ deepCopy(x) \undocumented
+ merge : (%,%) -> %
+ ++ merge(s1,s2) the subspaces s1 and s2 into a single subspace.
+ merge : List % -> %
+ ++ merge(ls) a list of subspaces, ls, into one subspace.
+ separate : % -> List %
+ ++ separate(s) makes each of the components of the \spadtype{SubSpace},
+ ++ s, into a list of separate and distinct subspaces and returns
+ ++ the list.
+ addPoint : (%,List NNI,POINT) -> %
+ ++ addPoint(s,li,p) adds the 4 dimensional point, p, to the 3
+ ++ dimensional subspace, s. The list of non negative integers, li,
+ ++ dictates the path to follow, or, to look at it another way,
+ ++ points to the component in which the point is to be added. It's
+ ++ length should range from 0 to \spad{n - 1} where n is the dimension
+ ++ of the subspace. If the length is \spad{n - 1}, then a specific
+ ++ lowest level component is being referenced. If it is less than
+ ++ \spad{n - 1}, then some higher level component (0 indicates top
+ ++ level component) is being referenced and a component of that level
+ ++ with the desired point is created. The subspace s is returned
+ ++ with the additional point.
+ addPoint2 : (%,POINT) -> %
+ ++ addPoint2(s,p) adds the 4 dimensional point, p, to the 3
+ ++ dimensional subspace, s.
+ ++ The subspace s is returned with the additional point.
+ addPointLast : (%,%,POINT, NNI) -> %
+ ++ addPointLast(s,s2,li,p) adds the 4 dimensional point, p, to the 3
+ ++ dimensional subspace, s. s2 point to the end of the subspace
+ ++ s. n is the path in the s2 component.
+ ++ The subspace s is returned with the additional point.
+ modifyPoint : (%,List NNI,POINT) -> %
+ ++ modifyPoint(s,li,p) replaces an existing point in the 3 dimensional
+ ++ subspace, s, with the 4 dimensional point, p. The list of non
+ ++ negative integers, li, dictates the path to follow, or, to look at
+ ++ it another way, points to the component in which the existing point
+ ++ is to be modified. An error message occurs if s is empty, otherwise
+ ++ the subspace s is returned with the point modification.
+ addPoint : (%,List NNI,NNI) -> %
+ ++ addPoint(s,li,i) adds the 4 dimensional point indicated by the
+ ++ index location, i, to the 3 dimensional subspace, s. The list of
+ ++ non negative integers, li, dictates the path to follow, or, to
+ ++ look at it another way, points to the component in which the point
+ ++ is to be added. It's length should range from 0 to \spad{n - 1}
+ ++ where n is the dimension of the subspace. If the length is
+ ++ \spad{n - 1}, then a specific lowest level component is being
+ ++ referenced. If it is less than \spad{n - 1}, then some higher
+ ++ level component (0 indicates top level component) is being
+ ++ referenced and a component of that level with the desired point
+ ++ is created. The subspace s is returned with the additional point.
+ modifyPoint : (%,List NNI,NNI) -> %
+ ++ modifyPoint(s,li,i) replaces an existing point in the 3 dimensional
+ ++ subspace, s, with the 4 dimensional point indicated by the index
+ ++ location, i. The list of non negative integers, li, dictates
+ ++ the path to follow, or, to look at it another way, points to the
+ ++ component in which the existing point is to be modified. An error
+ ++ message occurs if s is empty, otherwise the subspace s is returned
+ ++ with the point modification.
+ addPoint : (%,POINT) -> NNI
+ ++ addPoint(s,p) adds the point, p, to the 3 dimensional subspace, s,
+ ++ and returns the new total number of points in s.
+ modifyPoint : (%,NNI,POINT) -> %
+ ++ modifyPoint(s,ind,p) modifies the point referenced by the index
+ ++ location, ind, by replacing it with the point, p in the 3 dimensional
+ ++ subspace, s. An error message occurs if s is empty, otherwise the
+ ++ subspace s is returned with the point modification.
+
+ closeComponent : (%,List NNI,B) -> %
+ ++ closeComponent(s,li,b) sets the property of the component in the
+ ++ 3 dimensional subspace, s, to be closed if b is true, or open if
+ ++ b is false. The list of non negative integers, li, dictates the
+ ++ path to follow, or, to look at it another way, points to the
+ ++ component whose closed property is to be set. The subspace, s,
+ ++ is returned with the component property modification.
+ defineProperty : (%,List NNI,PROP) -> %
+ ++ defineProperty(s,li,p) defines the component property in the
+ ++ 3 dimensional subspace, s, to be that of p, where p is of the
+ ++ domain \spadtype{SubSpaceComponentProperty}. The list of non
+ ++ negative integers, li, dictates the path to follow, or, to look
+ ++ at it another way, points to the component whose property is
+ ++ being defined. The subspace, s, is returned with the component
+ ++ property definition.
+ traverse : (%,List NNI) -> %
+ ++ traverse(s,li) follows the branch list of the 3 dimensional
+ ++ subspace, s, along the path dictated by the list of non negative
+ ++ integers, li, which points to the component which has been
+ ++ traversed to. The subspace, s, is returned, where s is now
+ ++ the subspace pointed to by li.
+ extractPoint : % -> POINT
+ ++ extractPoint(s) returns the point which is given by the current
+ ++ index location into the point data field of the 3 dimensional
+ ++ subspace s.
+ extractIndex : % -> NNI
+ ++ extractIndex(s) returns a non negative integer which is the current
+ ++ index of the 3 dimensional subspace s.
+ extractClosed : % -> B
+ ++ extractClosed(s) returns the \spadtype{Boolean} value of the closed
+ ++ property for the indicated 3 dimensional subspace s. If the
+ ++ property is closed, \spad{True} is returned, otherwise \spad{False}
+ ++ is returned.
+ extractProperty : % -> PROP
+ ++ extractProperty(s) returns the property of domain
+ ++ \spadtype{SubSpaceComponentProperty} of the indicated 3 dimensional
+ ++ subspace s.
+ level : % -> NNI
+ ++ level(s) returns a non negative integer which is the current
+ ++ level field of the indicated 3 dimensional subspace s.
+ parent : % -> %
+ ++ parent(s) returns the subspace which is the parent of the indicated
+ ++ 3 dimensional subspace s. If s is the top level subspace an error
+ ++ message is returned.
+ pointData : % -> L POINT
+ ++ pointData(s) returns the list of points from the point data field
+ ++ of the 3 dimensional subspace s.
+
+ Implementation ==> add
+ import String()
+
+ Rep := Record(pt:POINT, index:NNI, property:PROP, _
+ childrenField:List %, _
+ lastChild: List %, _
+ levelField:NNI, _
+ pointDataField:L POINT, _
+ lastPoint: L POINT, _
+ noPoints: NNI, _
+ noChildren: NNI, _
+ parentField:List %) -- needn't be list but...base case?
+
+ TELLWATT : String := "Non-null list: Please inform Stephen Watt"
+
+ leaf? space == empty? children space
+ root? space == (space.levelField = 0$NNI)
+ internal? space == ^(root? space and leaf? space)
+
+ new() ==
+ [point(empty())$POINT,0,new()$PROP,empty(),empty(),0,_
+ empty(),empty(),0,0,empty()]
+ subspace() == new()
+
+ birth momma ==
+ baby := new()
+ baby.levelField := momma.levelField+1
+ baby.parentField := [momma]
+ if not empty?(lastKid := momma.lastChild) then
+ not empty? rest lastKid => error TELLWATT
+ if empty? lastKid
+ then
+ momma.childrenField := [baby]
+ momma.lastChild := momma.childrenField
+ momma.noChildren := 1
+ else
+ setrest_!(lastKid,[baby])
+ momma.lastChild := rest lastKid
+ momma.noChildren := momma.noChildren + 1
+ baby
+
+ child(space,num) ==
+ space.childrenField.num
+
+ children space == space.childrenField
+ numberOfChildren space == space.noChildren
+
+ shallowCopy space ==
+ node := new()
+ node.pt := space.pt
+ node.index := space.index
+ node.property := copy(space.property)
+ node.levelField := space.levelField
+ node.parentField := nil()
+ if root? space then
+ node.pointDataField := copy(space.pointDataField)
+ node.lastPoint := tail(node.pointDataField)
+ node.noPoints := space.noPoints
+ node
+
+ deepCopy space ==
+ node := shallowCopy(space)
+ leaf? space => node
+ for c in children space repeat
+ cc := deepCopy c
+ cc.parentField := [node]
+ node.childrenField := cons(cc,node.childrenField)
+ node.childrenField := reverse_!(node.childrenField)
+ node.lastChild := tail node.childrenField
+ node
+
+ merge(s1,s2) ==
+ ------------------ need to worry about reindexing s2 & parentField
+ n1 : Rep := deepCopy s1
+ n2 : Rep := deepCopy s2
+ n1.childrenField := append(children n1,children n2)
+ n1
+
+ merge listOfSpaces ==
+ ------------------ need to worry about reindexing & parentField
+ empty? listOfSpaces => error "empty list passed as argument to merge"
+ -- notice that the properties of the first subspace on the
+ -- list are the ones that are inherited...hmmmm...
+ space := deepCopy first listOfSpaces
+ for s in rest listOfSpaces repeat
+ -- because of the initial deepCopy, above, everything is
+ -- deepCopied to be consistent...more hmmm...
+ space.childrenField := append(space.childrenField,[deepCopy c for c in s.childrenField])
+ space
+
+ separate space ==
+ ------------------ need to worry about reindexing & parentField
+ spaceList := empty()
+ for s in space.childrenField repeat
+ spc:=shallowCopy space
+ spc.childrenField:=[deepCopy s]
+ spaceList := cons(spc,spaceList)
+ spaceList
+
+ addPoint(space:%,path:List NNI,point:POINT) ==
+ if not empty?(lastPt := space.lastPoint) then
+ not empty? rest lastPt => error TELLWATT
+ if empty? lastPt
+ then
+ space.pointDataField := [point]
+ space.lastPoint := space.pointDataField
+ else
+ setrest_!(lastPt,[point])
+ space.lastPoint := rest lastPt
+ space.noPoints := space.noPoints + 1
+ which := space.noPoints
+ node := space
+ depth : NNI := 0
+ for i in path repeat
+ node := child(node,i)
+ depth := depth + 1
+ for more in depth..(n-1) repeat
+ node := birth node
+ node.pt := point -- will be obsolete field
+ node.index := which
+ space
+
+ addPoint2(space:%,point:POINT) ==
+ if not empty?(lastPt := space.lastPoint) then
+ not empty? rest lastPt => error TELLWATT
+ if empty? lastPt
+ then
+ space.pointDataField := [point]
+ space.lastPoint := space.pointDataField
+ else
+ setrest_!(lastPt,[point])
+ space.lastPoint := rest lastPt
+ space.noPoints := space.noPoints + 1
+ which := space.noPoints
+ node := space
+ depth : NNI := 0
+ node := birth node
+ first := node
+ for more in 1..n-1 repeat
+ node := birth node
+ node.pt := point -- will be obsolete field
+ node.index := which
+ first
+
+ addPointLast(space:%,node:%, point:POINT, depth:NNI) ==
+ if not empty?(lastPt := space.lastPoint) then
+ not empty? rest lastPt => error TELLWATT
+ if empty? lastPt
+ then
+ space.pointDataField := [point]
+ space.lastPoint := space.pointDataField
+ else
+ setrest_!(lastPt,[point])
+ space.lastPoint := rest lastPt
+ space.noPoints := space.noPoints + 1
+ which := space.noPoints
+ if depth = 2 then node := child(node, 2)
+ for more in depth..(n-1) repeat
+ node := birth node
+ node.pt := point -- will be obsolete field
+ node.index := which
+ node -- space
+
+ addPoint(space:%,path:List NNI,which:NNI) ==
+ node := space
+ depth : NNI := 0
+ for i in path repeat
+ node := child(node,i)
+ depth := depth + 1
+ for more in depth..(n-1) repeat
+ node := birth node
+ node.pt := space.pointDataField.which -- will be obsolete field
+ node.index := which
+ space
+
+ addPoint(space:%,point:POINT) ==
+ root? space =>
+ if not empty?(lastPt := space.lastPoint) then
+ not empty? rest lastPt => error TELLWATT
+ if empty? lastPt
+ then
+ space.pointDataField := [point]
+ space.lastPoint := space.pointDataField
+ else
+ setrest_!(lastPt,[point])
+ space.lastPoint := rest lastPt
+ space.noPoints := space.noPoints + 1
+ error "You need to pass a top level SubSpace (level should be zero)"
+
+ modifyPoint(space:%,path:List NNI,point:POINT) ==
+ if not empty?(lastPt := space.lastPoint) then
+ not empty? rest lastPt => error TELLWATT
+ if empty? lastPt
+ then
+ space.pointDataField := [point]
+ space.lastPoint := space.pointDataField
+ else
+ setrest_!(lastPt,[point])
+ space.lastPoint := rest lastPt
+ space.noPoints := space.noPoints + 1
+ which := space.noPoints
+ node := space
+ for i in path repeat
+ node := child(node,i)
+ node.pt := point ---------- will be obsolete field
+ node.index := which
+ space
+
+ modifyPoint(space:%,path:List NNI,which:NNI) ==
+ node := space
+ for i in path repeat
+ node := child(node,i)
+ node.pt := space.pointDataField.which ---------- will be obsolete field
+ node.index := which
+ space
+
+ modifyPoint(space:%,which:NNI,point:POINT) ==
+ root? space =>
+ space.pointDataField.which := point
+ space
+ error "You need to pass a top level SubSpace (level should be zero)"
+
+ closeComponent(space,path,val) ==
+ node := space
+ for i in path repeat
+ node := child(node,i)
+ close(node.property,val)
+ space
+
+ defineProperty(space,path,prop) ==
+ node := space
+ for i in path repeat
+ node := child(node,i)
+ node.property := prop
+ space
+
+ traverse(space,path) ==
+ for i in path repeat space := child(space,i)
+ space
+
+ extractPoint space ==
+ node := space
+ while ^root? node repeat node := parent node
+ (node.pointDataField).(space.index)
+ extractIndex space == space.index
+ extractClosed space == closed? space.property
+ extractProperty space == space.property
+
+ parent space ==
+ empty? space.parentField => error "This is a top level SubSpace - it does not have a parent"
+ first space.parentField
+ pointData space == space.pointDataField
+ level space == space.levelField
+ s1 = s2 ==
+ ------------ extra checks for list of point data
+ (leaf? s1 and leaf? s2) =>
+ (s1.pt = s2.pt) and (s1.property = s2.property) and (s1.levelField = s2.levelField)
+ -- note that the ordering of children is important
+ #s1.childrenField ^= #s2.childrenField => false
+ and/[c1 = c2 for c1 in s1.childrenField for c2 in s2.childrenField]
+ and (s1.property = s2.property) and (s1.levelField = s2.levelField)
+ coerce(space:%):O ==
+ hconcat([n::O,"-Space with depth of "::O, _
+ (n - space.levelField)::O," and "::O,(s:=(#space.childrenField))::O, _
+ (s=1 => " component"::O;" components"::O)])
+
+@
+\section{package PTPACK PointPackage}
+<<package PTPACK PointPackage>>=
+)abbrev package PTPACK PointPackage
+++ Description:
+++ This package \undocumented
+PointPackage(R:Ring):Exports == Implementation where
+
+ POINT ==> Point(R)
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ L ==> List
+ B ==> Boolean
+
+ Exports == with
+ xCoord : POINT -> R
+ ++ xCoord(pt) returns the first element of the point, pt,
+ ++ although no assumptions are made as to the coordinate
+ ++ system being used. This function is defined for the
+ ++ convenience of the user dealing with a Cartesian
+ ++ coordinate system.
+ yCoord : POINT -> R
+ ++ yCoord(pt) returns the second element of the point, pt,
+ ++ although no assumptions are made as to the coordinate
+ ++ system being used. This function is defined for the
+ ++ convenience of the user dealing with a Cartesian
+ ++ coordinate system.
+ zCoord : POINT -> R
+ ++ zCoord(pt) returns the third element of the point, pt,
+ ++ although no assumptions are made as to the coordinate
+ ++ system being used. This function is defined for the
+ ++ convenience of the user dealing with a Cartesian
+ ++ or a cylindrical coordinate system.
+ rCoord : POINT -> R
+ ++ rCoord(pt) returns the first element of the point, pt,
+ ++ although no assumptions are made as to the coordinate
+ ++ system being used. This function is defined for the
+ ++ convenience of the user dealing with a spherical
+ ++ or a cylindrical coordinate system.
+ thetaCoord : POINT -> R
+ ++ thetaCoord(pt) returns the second element of the point, pt,
+ ++ although no assumptions are made as to the coordinate
+ ++ system being used. This function is defined for the
+ ++ convenience of the user dealing with a spherical
+ ++ or a cylindrical coordinate system.
+ phiCoord : POINT -> R
+ ++ phiCoord(pt) returns the third element of the point, pt,
+ ++ although no assumptions are made as to the coordinate
+ ++ system being used. This function is defined for the
+ ++ convenience of the user dealing with a spherical
+ ++ coordinate system.
+ color : POINT -> R
+ ++ color(pt) returns the fourth element of the point, pt,
+ ++ although no assumptions are made with regards as to
+ ++ how the components of higher dimensional points are
+ ++ interpreted. This function is defined for the
+ ++ convenience of the user using specifically, color
+ ++ to express a fourth dimension.
+ hue : POINT -> R
+ ++ hue(pt) returns the third element of the two dimensional point, pt,
+ ++ although no assumptions are made with regards as to how the
+ ++ components of higher dimensional points are interpreted. This
+ ++ function is defined for the convenience of the user using
+ ++ specifically, hue to express a third dimension.
+ shade : POINT -> R
+ ++ shade(pt) returns the fourth element of the two dimensional
+ ++ point, pt, although no assumptions are made with regards as to
+ ++ how the components of higher dimensional points are interpreted.
+ ++ This function is defined for the convenience of the user using
+ ++ specifically, shade to express a fourth dimension.
+
+ -- 2D and 3D extraction of data
+ Implementation ==> add
+
+ xCoord p == elt(p,1)
+ yCoord p == elt(p,2)
+ zCoord p == elt(p,3)
+ rCoord p == elt(p,1)
+ thetaCoord p == elt(p,2)
+ phiCoord p == elt(p,3)
+ color p ==
+ #p > 3 => p.4
+ p.3
+ hue p == elt(p,3) -- 4D points in 2D using extra dimensions for palette information
+ shade p == elt(p,4) -- 4D points in 2D using extra dimensions for palette information
+
+@
+\section{package PTFUNC2 PointFunctions2}
+<<package PTFUNC2 PointFunctions2>>=
+)abbrev package PTFUNC2 PointFunctions2
+++ Description:
+++ This package \undocumented
+PointFunctions2(R1:Ring,R2:Ring):Exports == Implementation where
+
+ Exports == with
+ map : ((R1->R2),Point(R1)) -> Point(R2)
+ ++ map(f,p) \undocumented
+
+ Implementation ==> add
+ import Point(R1)
+ import Point(R2)
+
+ map(mapping,p) ==
+ point([mapping p.(i::PositiveInteger) for i in minIndex(p)..maxIndex(p)])$Point(R2)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PTCAT PointCategory>>
+<<domain POINT Point>>
+<<domain COMPPROP SubSpaceComponentProperty>>
+<<domain SUBSPACE SubSpace>>
+<<package PTPACK PointPackage>>
+<<package PTFUNC2 PointFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/newpoly.spad.pamphlet b/src/algebra/newpoly.spad.pamphlet
new file mode 100644
index 00000000..db2974e2
--- /dev/null
+++ b/src/algebra/newpoly.spad.pamphlet
@@ -0,0 +1,1888 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra newpoly.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+Based on the {\bf PseudoRemainderSequence} package, the domain
+constructor {\bf NewSparseUnivariatePolynomial} extends the
+constructur {\bf SparseUnivariatePolynomial}.
+\section{domain NSUP NewSparseUnivariatePolynomial}
+<<domain NSUP NewSparseUnivariatePolynomial>>=
+)abbrev domain NSUP NewSparseUnivariatePolynomial
+++ Author: Marc Moreno Maza
+++ Date Created: 23/07/98
+++ Date Last Updated: 14/12/98
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A post-facto extension for \axiomType{SUP} in order
+++ to speed up operations related to pseudo-division and gcd for
+++ both \axiomType{SUP} and, consequently, \axiomType{NSMP}.
+
+NewSparseUnivariatePolynomial(R): Exports == Implementation where
+
+ R:Ring
+ NNI ==> NonNegativeInteger
+ SUPR ==> SparseUnivariatePolynomial R
+
+ Exports == Join(UnivariatePolynomialCategory(R),
+ CoercibleTo(SUPR),RetractableTo(SUPR)) with
+ fmecg : (%,NNI,R,%) -> %
+ ++ \axiom{fmecg(p1,e,r,p2)} returns \axiom{p1 - r * X**e * p2}
+ ++ where \axiom{X} is \axiom{monomial(1,1)}
+ monicModulo : ($, $) -> $
+ ++ \axiom{monicModulo(a,b)} returns \axiom{r} such that \axiom{r} is
+ ++ reduced w.r.t. \axiom{b} and \axiom{b} divides \axiom{a -r}
+ ++ where \axiom{b} is monic.
+ lazyResidueClass: ($,$) -> Record(polnum:$, polden:R, power:NNI)
+ ++ \axiom{lazyResidueClass(a,b)} returns \axiom{[r,c,n]} such that
+ ++ \axiom{r} is reduced w.r.t. \axiom{b} and \axiom{b} divides
+ ++ \axiom{c^n * a - r} where \axiom{c} is \axiom{leadingCoefficient(b)}
+ ++ and \axiom{n} is as small as possible with the previous properties.
+ lazyPseudoRemainder: ($,$) -> $
+ ++ \axiom{lazyPseudoRemainder(a,b)} returns \axiom{r} if \axiom{lazyResidueClass(a,b)}
+ ++ returns \axiom{[r,c,n]}. This lazy pseudo-remainder is computed by
+ ++ means of the \axiomOpFrom{fmecg}{NewSparseUnivariatePolynomial} operation.
+ lazyPseudoDivide: ($,$) -> Record(coef:R, gap:NNI, quotient:$, remainder: $)
+ ++ \axiom{lazyPseudoDivide(a,b)} returns \axiom{[c,g,q,r]} such that
+ ++ \axiom{c^n * a = q*b +r} and \axiom{lazyResidueClass(a,b)} returns \axiom{[r,c,n]}
+ ++ where \axiom{n + g = max(0, degree(b) - degree(a) + 1)}.
+ lazyPseudoQuotient: ($,$) -> $
+ ++ \axiom{lazyPseudoQuotient(a,b)} returns \axiom{q} if \axiom{lazyPseudoDivide(a,b)}
+ ++ returns \axiom{[c,g,q,r]}
+ if R has IntegralDomain
+ then
+ subResultantsChain: ($, $) -> List $
+ ++ \axiom{subResultantsChain(a,b)} returns the list of the non-zero
+ ++ sub-resultants of \axiom{a} and \axiom{b} sorted by increasing
+ ++ degree.
+ lastSubResultant: ($, $) -> $
+ ++ \axiom{lastSubResultant(a,b)} returns \axiom{resultant(a,b)}
+ ++ if \axiom{a} and \axiom{b} has no non-trivial gcd in \axiom{R^(-1) P}
+ ++ otherwise the non-zero sub-resultant with smallest index.
+ extendedSubResultantGcd: ($, $) -> Record(gcd: $, coef1: $, coef2: $)
+ ++ \axiom{extendedSubResultantGcd(a,b)} returns \axiom{[g,ca, cb]} such
+ ++ that \axiom{g} is a gcd of \axiom{a} and \axiom{b} in \axiom{R^(-1) P}
+ ++ and \axiom{g = ca * a + cb * b}
+ halfExtendedSubResultantGcd1: ($, $) -> Record(gcd: $, coef1: $)
+ ++ \axiom{halfExtendedSubResultantGcd1(a,b)} returns \axiom{[g,ca]} such that
+ ++ \axiom{extendedSubResultantGcd(a,b)} returns \axiom{[g,ca, cb]}
+ halfExtendedSubResultantGcd2: ($, $) -> Record(gcd: $, coef2: $)
+ ++ \axiom{halfExtendedSubResultantGcd2(a,b)} returns \axiom{[g,cb]} such that
+ ++ \axiom{extendedSubResultantGcd(a,b)} returns \axiom{[g,ca, cb]}
+ extendedResultant: ($, $) -> Record(resultant: R, coef1: $, coef2: $)
+ ++ \axiom{extendedResultant(a,b)} returns \axiom{[r,ca,cb]} such that
+ ++ \axiom{r} is the resultant of \axiom{a} and \axiom{b} and
+ ++ \axiom{r = ca * a + cb * b}
+ halfExtendedResultant1: ($, $) -> Record(resultant: R, coef1: $)
+ ++ \axiom{halfExtendedResultant1(a,b)} returns \axiom{[r,ca]} such that
+ ++ \axiom{extendedResultant(a,b)} returns \axiom{[r,ca, cb]}
+ halfExtendedResultant2: ($, $) -> Record(resultant: R, coef2: $)
+ ++ \axiom{halfExtendedResultant2(a,b)} returns \axiom{[r,ca]} such that
+ ++ \axiom{extendedResultant(a,b)} returns \axiom{[r,ca, cb]}
+
+ Implementation == SparseUnivariatePolynomial(R) add
+
+ Term == Record(k:NonNegativeInteger,c:R)
+ Rep ==> List Term
+
+ rep(s:$):Rep == s pretend Rep
+ per(l:Rep):$ == l pretend $
+
+ coerce (p:$):SUPR ==
+ p pretend SUPR
+
+ coerce (p:SUPR):$ ==
+ p pretend $
+
+ retractIfCan (p:$) : Union(SUPR,"failed") ==
+ (p pretend SUPR)::Union(SUPR,"failed")
+
+ monicModulo(x,y) ==
+ zero? y =>
+ error "in monicModulo$NSUP: division by 0"
+ ground? y =>
+ error "in monicModulo$NSUP: ground? #2"
+ yy := rep y
+-- not one? (yy.first.c) =>
+ not ((yy.first.c) = 1) =>
+ error "in monicModulo$NSUP: not monic #2"
+ xx := rep x; empty? xx => x
+ e := yy.first.k; y := per(yy.rest)
+ -- while (not empty? xx) repeat
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ xx:= rep fmecg(per rest(xx), u, xx.first.c, y)
+ if empty? xx then break
+ per xx
+
+ lazyResidueClass(x,y) ==
+ zero? y =>
+ error "in lazyResidueClass$NSUP: division by 0"
+ ground? y =>
+ error "in lazyResidueClass$NSUP: ground? #2"
+ yy := rep y; co := yy.first.c; xx: Rep := rep x
+ empty? xx => [x, co, 0]
+ pow: NNI := 0; e := yy.first.k; y := per(yy.rest);
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ xx:= rep fmecg(co * per rest(xx), u, xx.first.c, y)
+ pow := pow + 1
+ if empty? xx then break
+ [per xx, co, pow]
+
+ lazyPseudoRemainder(x,y) ==
+ zero? y =>
+ error "in lazyPseudoRemainder$NSUP: division by 0"
+ ground? y =>
+ error "in lazyPseudoRemainder$NSUP: ground? #2"
+ ground? x => x
+ yy := rep y; co := yy.first.c
+-- one? co => monicModulo(x,y)
+ (co = 1) => monicModulo(x,y)
+ (co = -1) => - monicModulo(-x,-y)
+ xx:= rep x; e := yy.first.k; y := per(yy.rest)
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ xx:= rep fmecg(co * per rest(xx), u, xx.first.c, y)
+ if empty? xx then break
+ per xx
+
+ lazyPseudoDivide(x,y) ==
+ zero? y =>
+ error "in lazyPseudoDivide$NSUP: division by 0"
+ ground? y =>
+ error "in lazyPseudoDivide$NSUP: ground? #2"
+ yy := rep y; e := yy.first.k;
+ xx: Rep := rep x; co := yy.first.c
+ (empty? xx) or (xx.first.k < e) => [co,0,0,x]
+ pow: NNI := subtractIfCan(xx.first.k,e)::NNI + 1
+ qq: Rep := []; y := per(yy.rest)
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ qq := cons([u::NNI, xx.first.c]$Term, rep (co * per qq))
+ xx := rep fmecg(co * per rest(xx), u, xx.first.c, y)
+ pow := subtractIfCan(pow,1)::NNI
+ if empty? xx then break
+ [co, pow, per reverse qq, per xx]
+
+ lazyPseudoQuotient(x,y) ==
+ zero? y =>
+ error "in lazyPseudoQuotient$NSUP: division by 0"
+ ground? y =>
+ error "in lazyPseudoQuotient$NSUP: ground? #2"
+ yy := rep y; e := yy.first.k; xx: Rep := rep x
+ (empty? xx) or (xx.first.k < e) => 0
+ qq: Rep := []; co := yy.first.c; y := per(yy.rest)
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ qq := cons([u::NNI, xx.first.c]$Term, rep (co * per qq))
+ xx := rep fmecg(co * per rest(xx), u, xx.first.c, y)
+ if empty? xx then break
+ per reverse qq
+
+ if R has IntegralDomain
+ then
+ pack ==> PseudoRemainderSequence(R, %)
+
+ subResultantGcd(p1,p2) == subResultantGcd(p1,p2)$pack
+
+ subResultantsChain(p1,p2) == chainSubResultants(p1,p2)$pack
+
+ lastSubResultant(p1,p2) == lastSubResultant(p1,p2)$pack
+
+ resultant(p1,p2) == resultant(p1,p2)$pack
+
+ extendedResultant(p1,p2) ==
+ re: Record(coef1: $, coef2: $, resultant: R) := resultantEuclidean(p1,p2)$pack
+ [re.resultant, re.coef1, re.coef2]
+
+ halfExtendedResultant1(p1:$, p2: $): Record(resultant: R, coef1: $) ==
+ re: Record(coef1: $, resultant: R) := semiResultantEuclidean1(p1, p2)$pack
+ [re.resultant, re.coef1]
+
+ halfExtendedResultant2(p1:$, p2: $): Record(resultant: R, coef2: $) ==
+ re: Record(coef2: $, resultant: R) := semiResultantEuclidean2(p1, p2)$pack
+ [re.resultant, re.coef2]
+
+ extendedSubResultantGcd(p1,p2) ==
+ re: Record(coef1: $, coef2: $, gcd: $) := subResultantGcdEuclidean(p1,p2)$pack
+ [re.gcd, re.coef1, re.coef2]
+
+ halfExtendedSubResultantGcd1(p1:$, p2: $): Record(gcd: $, coef1: $) ==
+ re: Record(coef1: $, gcd: $) := semiSubResultantGcdEuclidean1(p1, p2)$pack
+ [re.gcd, re.coef1]
+
+ halfExtendedSubResultantGcd2(p1:$, p2: $): Record(gcd: $, coef2: $) ==
+ re: Record(coef2: $, gcd: $) := semiSubResultantGcdEuclidean2(p1, p2)$pack
+ [re.gcd, re.coef2]
+
+ pseudoDivide(x,y) ==
+ zero? y =>
+ error "in pseudoDivide$NSUP: division by 0"
+ ground? y =>
+ error "in pseudoDivide$NSUP: ground? #2"
+ yy := rep y; e := yy.first.k
+ xx: Rep := rep x; co := yy.first.c
+ (empty? xx) or (xx.first.k < e) => [co,0,x]
+ pow: NNI := subtractIfCan(xx.first.k,e)::NNI + 1
+ qq: Rep := []; y := per(yy.rest)
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ qq := cons([u::NNI, xx.first.c]$Term, rep (co * per qq))
+ xx := rep fmecg(co * per rest(xx), u, xx.first.c, y)
+ pow := subtractIfCan(pow,1)::NNI
+ if empty? xx then break
+ zero? pow => [co, per reverse qq, per xx]
+ default: R := co ** pow
+ q := default * (per reverse qq)
+ x := default * (per xx)
+ [co, q, x]
+
+ pseudoQuotient(x,y) ==
+ zero? y =>
+ error "in pseudoDivide$NSUP: division by 0"
+ ground? y =>
+ error "in pseudoDivide$NSUP: ground? #2"
+ yy := rep y; e := yy.first.k; xx: Rep := rep x
+ (empty? xx) or (xx.first.k < e) => 0
+ pow: NNI := subtractIfCan(xx.first.k,e)::NNI + 1
+ qq: Rep := []; co := yy.first.c; y := per(yy.rest)
+ repeat
+ if (u:=subtractIfCan(xx.first.k,e)) case "failed" then break
+ qq := cons([u::NNI, xx.first.c]$Term, rep (co * per qq))
+ xx := rep fmecg(co * per rest(xx), u, xx.first.c, y)
+ pow := subtractIfCan(pow,1)::NNI
+ if empty? xx then break
+ zero? pow => per reverse qq
+ (co ** pow) * (per reverse qq)
+
+@
+\section{package NSUP2 NewSparseUnivariatePolynomialFunctions2}
+<<package NSUP2 NewSparseUnivariatePolynomialFunctions2>>=
+)abbrev package NSUP2 NewSparseUnivariatePolynomialFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package lifts a mapping from coefficient rings R to S to
+++ a mapping from sparse univariate polynomial over R to
+++ a sparse univariate polynomial over S.
+++ Note that the mapping is assumed
+++ to send zero to zero, since it will only be applied to the non-zero
+++ coefficients of the polynomial.
+
+NewSparseUnivariatePolynomialFunctions2(R:Ring, S:Ring): with
+ map:(R->S,NewSparseUnivariatePolynomial R) -> NewSparseUnivariatePolynomial S
+ ++ \axiom{map(func, poly)} creates a new polynomial by applying func to
+ ++ every non-zero coefficient of the polynomial poly.
+ == add
+ map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
+ NewSparseUnivariatePolynomial R, S, NewSparseUnivariatePolynomial S)
+
+@
+\section{category RPOLCAT RecursivePolynomialCategory}
+<<category RPOLCAT RecursivePolynomialCategory>>=
+)abbrev category RPOLCAT RecursivePolynomialCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 04/22/1994
+++ Date Last Updated: 14/12/1998
+++ Basic Functions: mvar, mdeg, init, head, tail, prem, lazyPrem
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ References:
+++ Description:
+++ A category for general multi-variate polynomials with coefficients
+++ in a ring, variables in an ordered set, and exponents from an
+++ ordered abelian monoid, with a \axiomOp{sup} operation.
+++ When not constant, such a polynomial is viewed as a univariate polynomial in its
+++ main variable w. r. t. to the total ordering on the elements in the ordered set, so that some
+++ operations usually defined for univariate polynomials make sense here.
+
+RecursivePolynomialCategory(R:Ring, E:OrderedAbelianMonoidSup, V:OrderedSet): Category ==
+ PolynomialCategory(R, E, V) with
+ mvar : $ -> V
+ ++ \axiom{mvar(p)} returns an error if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns its main variable w. r. t. to the total ordering
+ ++ on the elements in \axiom{V}.
+ mdeg : $ -> NonNegativeInteger
+ ++ \axiom{mdeg(p)} returns an error if \axiom{p} is \axiom{0},
+ ++ otherwise, if \axiom{p} belongs to \axiom{R} returns \axiom{0},
+ ++ otherwise, returns the degree of \axiom{p} in its main variable.
+ init : $ -> $
+ ++ \axiom{init(p)} returns an error if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns its leading coefficient, where \axiom{p} is viewed
+ ++ as a univariate polynomial in its main variable.
+ head : $ -> $
+ ++ \axiom{head(p)} returns \axiom{p} if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns its leading term (monomial in the AXIOM sense),
+ ++ where \axiom{p} is viewed as a univariate polynomial in its main variable.
+ tail : $ -> $
+ ++ \axiom{tail(p)} returns its reductum, where \axiom{p} is viewed as a univariate
+ ++ polynomial in its main variable.
+ deepestTail : $ -> $
+ ++ \axiom{deepestTail(p)} returns \axiom{0} if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns tail(p), if \axiom{tail(p)} belongs to \axiom{R}
+ ++ or \axiom{mvar(tail(p)) < mvar(p)}, otherwise returns \axiom{deepestTail(tail(p))}.
+ iteratedInitials : $ -> List $
+ ++ \axiom{iteratedInitials(p)} returns \axiom{[]} if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns the list of the iterated initials of \axiom{p}.
+ deepestInitial : $ -> $
+ ++ \axiom{deepestInitial(p)} returns an error if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns the last term of \axiom{iteratedInitials(p)}.
+ leadingCoefficient : ($,V) -> $
+ ++ \axiom{leadingCoefficient(p,v)} returns the leading coefficient of \axiom{p},
+ ++ where \axiom{p} is viewed as A univariate polynomial in \axiom{v}.
+ reductum : ($,V) -> $
+ ++ \axiom{reductum(p,v)} returns the reductum of \axiom{p}, where \axiom{p} is viewed as
+ ++ a univariate polynomial in \axiom{v}.
+ monic? : $ -> Boolean
+ ++ \axiom{monic?(p)} returns false if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns true iff \axiom{p} is monic as a univariate polynomial
+ ++ in its main variable.
+ quasiMonic? : $ -> Boolean
+ ++ \axiom{quasiMonic?(p)} returns false if \axiom{p} belongs to \axiom{R},
+ ++ otherwise returns true iff the initial of \axiom{p} lies in the base ring \axiom{R}.
+ mainMonomial : $ -> $
+ ++ \axiom{mainMonomial(p)} returns an error if \axiom{p} is \axiom{O},
+ ++ otherwise, if \axiom{p} belongs to \axiom{R} returns \axiom{1},
+ ++ otherwise, \axiom{mvar(p)} raised to the power \axiom{mdeg(p)}.
+ leastMonomial : $ -> $
+ ++ \axiom{leastMonomial(p)} returns an error if \axiom{p} is \axiom{O},
+ ++ otherwise, if \axiom{p} belongs to \axiom{R} returns \axiom{1},
+ ++ otherwise, the monomial of \axiom{p} with lowest degree,
+ ++ where \axiom{p} is viewed as a univariate polynomial in its main variable.
+ mainCoefficients : $ -> List $
+ ++ \axiom{mainCoefficients(p)} returns an error if \axiom{p} is \axiom{O},
+ ++ otherwise, if \axiom{p} belongs to \axiom{R} returns [p],
+ ++ otherwise returns the list of the coefficients of \axiom{p},
+ ++ where \axiom{p} is viewed as a univariate polynomial in its main variable.
+ mainMonomials : $ -> List $
+ ++ \axiom{mainMonomials(p)} returns an error if \axiom{p} is \axiom{O},
+ ++ otherwise, if \axiom{p} belongs to \axiom{R} returns [1],
+ ++ otherwise returns the list of the monomials of \axiom{p},
+ ++ where \axiom{p} is viewed as a univariate polynomial in its main variable.
+ RittWuCompare : ($, $) -> Union(Boolean,"failed")
+ ++ \axiom{RittWuCompare(a,b)} returns \axiom{"failed"} if \axiom{a} and \axiom{b} have same rank w.r.t.
+ ++ Ritt and Wu Wen Tsun ordering using the refinement of Lazard,
+ ++ otherwise returns \axiom{infRittWu?(a,b)}.
+ infRittWu? : ($, $) -> Boolean
+ ++ \axiom{infRittWu?(a,b)} returns true if \axiom{a} is less than \axiom{b}
+ ++ w.r.t. the Ritt and Wu Wen Tsun ordering using the refinement of Lazard.
+ supRittWu? : ($, $) -> Boolean
+ ++ \axiom{supRittWu?(a,b)} returns true if \axiom{a} is greater than \axiom{b}
+ ++ w.r.t. the Ritt and Wu Wen Tsun ordering using the refinement of Lazard.
+ reduced? : ($,$) -> Boolean
+ ++ \axiom{reduced?(a,b)} returns true iff \axiom{degree(a,mvar(b)) < mdeg(b)}.
+ reduced? : ($,List($)) -> Boolean
+ ++ \axiom{reduced?(q,lp)} returns true iff \axiom{reduced?(q,p)} holds
+ ++ for every \axiom{p} in \axiom{lp}.
+ headReduced? : ($,$) -> Boolean
+ ++ \axiom{headReduced?(a,b)} returns true iff \axiom{degree(head(a),mvar(b)) < mdeg(b)}.
+ headReduced? : ($,List($)) -> Boolean
+ ++ \axiom{headReduced?(q,lp)} returns true iff \axiom{headReduced?(q,p)} holds
+ ++ for every \axiom{p} in \axiom{lp}.
+ initiallyReduced? : ($,$) -> Boolean
+ ++ \axiom{initiallyReduced?(a,b)} returns false iff there exists an iterated initial
+ ++ of \axiom{a} which is not reduced w.r.t \axiom{b}.
+ initiallyReduced? : ($,List($)) -> Boolean
+ ++ \axiom{initiallyReduced?(q,lp)} returns true iff \axiom{initiallyReduced?(q,p)} holds
+ ++ for every \axiom{p} in \axiom{lp}.
+ normalized? : ($,$) -> Boolean
+ ++ \axiom{normalized?(a,b)} returns true iff \axiom{a} and its iterated initials have
+ ++ degree zero w.r.t. the main variable of \axiom{b}
+ normalized? : ($,List($)) -> Boolean
+ ++ \axiom{normalized?(q,lp)} returns true iff \axiom{normalized?(q,p)} holds
+ ++ for every \axiom{p} in \axiom{lp}.
+ prem : ($, $) -> $
+ ++ \axiom{prem(a,b)} computes the pseudo-remainder of \axiom{a} by \axiom{b},
+ ++ both viewed as univariate polynomials in the main variable of \axiom{b}.
+ pquo : ($, $) -> $
+ ++ \axiom{pquo(a,b)} computes the pseudo-quotient of \axiom{a} by \axiom{b},
+ ++ both viewed as univariate polynomials in the main variable of \axiom{b}.
+ prem : ($, $, V) -> $
+ ++ \axiom{prem(a,b,v)} computes the pseudo-remainder of \axiom{a} by \axiom{b},
+ ++ both viewed as univariate polynomials in \axiom{v}.
+ pquo : ($, $, V) -> $
+ ++ \axiom{pquo(a,b,v)} computes the pseudo-quotient of \axiom{a} by \axiom{b},
+ ++ both viewed as univariate polynomials in \axiom{v}.
+ lazyPrem : ($, $) -> $
+ ++ \axiom{lazyPrem(a,b)} returns the polynomial \axiom{r} reduced w.r.t. \axiom{b}
+ ++ and such that \axiom{b} divides \axiom{init(b)^e a - r} where \axiom{e}
+ ++ is the number of steps of this pseudo-division.
+ lazyPquo : ($, $) -> $
+ ++ \axiom{lazyPquo(a,b)} returns the polynomial \axiom{q} such that
+ ++ \axiom{lazyPseudoDivide(a,b)} returns \axiom{[c,g,q,r]}.
+ lazyPrem : ($, $, V) -> $
+ ++ \axiom{lazyPrem(a,b,v)} returns the polynomial \axiom{r}
+ ++ reduced w.r.t. \axiom{b} viewed as univariate polynomials in the variable
+ ++ \axiom{v} such that \axiom{b} divides \axiom{init(b)^e a - r}
+ ++ where \axiom{e} is the number of steps of this pseudo-division.
+ lazyPquo : ($, $, V) -> $
+ ++ \axiom{lazyPquo(a,b,v)} returns the polynomial \axiom{q} such that
+ ++ \axiom{lazyPseudoDivide(a,b,v)} returns \axiom{[c,g,q,r]}.
+ lazyPremWithDefault : ($, $) -> Record (coef : $, gap : NonNegativeInteger, remainder : $)
+ ++ \axiom{lazyPremWithDefault(a,b)} returns \axiom{[c,g,r]}
+ ++ such that \axiom{r = lazyPrem(a,b)} and \axiom{(c**g)*r = prem(a,b)}.
+ lazyPremWithDefault : ($, $, V) -> Record (coef : $, gap : NonNegativeInteger, remainder : $)
+ ++ \axiom{lazyPremWithDefault(a,b,v)} returns \axiom{[c,g,r]}
+ ++ such that \axiom{r = lazyPrem(a,b,v)} and \axiom{(c**g)*r = prem(a,b,v)}.
+ lazyPseudoDivide : ($,$) -> Record(coef:$, gap: NonNegativeInteger,quotient:$, remainder:$)
+ ++ \axiom{lazyPseudoDivide(a,b)} returns \axiom{[c,g,q,r]}
+ ++ such that \axiom{[c,g,r] = lazyPremWithDefault(a,b)} and
+ ++ \axiom{q} is the pseudo-quotient computed in this lazy pseudo-division.
+ lazyPseudoDivide : ($,$,V) -> Record(coef:$, gap:NonNegativeInteger, quotient:$, remainder: $)
+ ++ \axiom{lazyPseudoDivide(a,b,v)} returns \axiom{[c,g,q,r]} such that
+ ++ \axiom{r = lazyPrem(a,b,v)}, \axiom{(c**g)*r = prem(a,b,v)} and \axiom{q}
+ ++ is the pseudo-quotient computed in this lazy pseudo-division.
+ pseudoDivide : ($, $) -> Record (quotient : $, remainder : $)
+ ++ \axiom{pseudoDivide(a,b)} computes \axiom{[pquo(a,b),prem(a,b)]}, both
+ ++ polynomials viewed as univariate polynomials in the main variable of \axiom{b},
+ ++ if \axiom{b} is not a constant polynomial.
+ monicModulo : ($, $) -> $
+ ++ \axiom{monicModulo(a,b)} computes \axiom{a mod b}, if \axiom{b} is
+ ++ monic as univariate polynomial in its main variable.
+ lazyResidueClass : ($,$) -> Record(polnum:$, polden:$, power:NonNegativeInteger)
+ ++ \axiom{lazyResidueClass(a,b)} returns \axiom{[p,q,n]} where \axiom{p / q**n}
+ ++ represents the residue class of \axiom{a} modulo \axiom{b}
+ ++ and \axiom{p} is reduced w.r.t. \axiom{b} and \axiom{q} is \axiom{init(b)}.
+ headReduce: ($, $) -> $
+ ++ \axiom{headReduce(a,b)} returns a polynomial \axiom{r} such that
+ ++ \axiom{headReduced?(r,b)} holds and there exists an integer \axiom{e}
+ ++ such that \axiom{init(b)^e a - r} is zero modulo \axiom{b}.
+ initiallyReduce: ($, $) -> $
+ ++ \axiom{initiallyReduce(a,b)} returns a polynomial \axiom{r} such that
+ ++ \axiom{initiallyReduced?(r,b)} holds and there exists an integer \axiom{e}
+ ++ such that \axiom{init(b)^e a - r} is zero modulo \axiom{b}.
+
+ if (V has ConvertibleTo(Symbol))
+ then
+ CoercibleTo(Polynomial R)
+ ConvertibleTo(Polynomial R)
+ if R has Algebra Fraction Integer
+ then
+ retractIfCan : Polynomial Fraction Integer -> Union($,"failed")
+ ++ \axiom{retractIfCan(p)} returns \axiom{p} as an element of the current domain
+ ++ if all its variables belong to \axiom{V}.
+ retract : Polynomial Fraction Integer -> $
+ ++ \axiom{retract(p)} returns \axiom{p} as an element of the current domain
+ ++ if \axiom{retractIfCan(p)} does not return "failed", otherwise an error
+ ++ is produced.
+ convert : Polynomial Fraction Integer -> $
+ ++ \axiom{convert(p)} returns the same as \axiom{retract(p)}.
+ retractIfCan : Polynomial Integer -> Union($,"failed")
+ ++ \axiom{retractIfCan(p)} returns \axiom{p} as an element of the current domain
+ ++ if all its variables belong to \axiom{V}.
+ retract : Polynomial Integer -> $
+ ++ \axiom{retract(p)} returns \axiom{p} as an element of the current domain
+ ++ if \axiom{retractIfCan(p)} does not return "failed", otherwise an error
+ ++ is produced.
+ convert : Polynomial Integer -> $
+ ++ \axiom{convert(p)} returns the same as \axiom{retract(p)}
+ if not (R has QuotientFieldCategory(Integer))
+ then
+ retractIfCan : Polynomial R -> Union($,"failed")
+ ++ \axiom{retractIfCan(p)} returns \axiom{p} as an element of the current domain
+ ++ if all its variables belong to \axiom{V}.
+ retract : Polynomial R -> $
+ ++ \axiom{retract(p)} returns \axiom{p} as an element of the current domain
+ ++ if \axiom{retractIfCan(p)} does not return "failed", otherwise an error
+ ++ is produced.
+ if (R has Algebra Integer) and not(R has Algebra Fraction Integer)
+ then
+ retractIfCan : Polynomial Integer -> Union($,"failed")
+ ++ \axiom{retractIfCan(p)} returns \axiom{p} as an element of the current domain
+ ++ if all its variables belong to \axiom{V}.
+ retract : Polynomial Integer -> $
+ ++ \axiom{retract(p)} returns \axiom{p} as an element of the current domain
+ ++ if \axiom{retractIfCan(p)} does not return "failed", otherwise an error
+ ++ is produced.
+ convert : Polynomial Integer -> $
+ ++ \axiom{convert(p)} returns the same as \axiom{retract(p)}.
+ if not (R has IntegerNumberSystem)
+ then
+ retractIfCan : Polynomial R -> Union($,"failed")
+ ++ \axiom{retractIfCan(p)} returns \axiom{p} as an element of the current domain
+ ++ if all its variables belong to \axiom{V}.
+ retract : Polynomial R -> $
+ ++ \axiom{retract(p)} returns \axiom{p} as an element of the current domain
+ ++ if \axiom{retractIfCan(p)} does not return "failed", otherwise an error
+ ++ is produced.
+ if not(R has Algebra Integer) and not(R has Algebra Fraction Integer)
+ then
+ retractIfCan : Polynomial R -> Union($,"failed")
+ ++ \axiom{retractIfCan(p)} returns \axiom{p} as an element of the current domain
+ ++ if all its variables belong to \axiom{V}.
+ retract : Polynomial R -> $
+ ++ \axiom{retract(p)} returns \axiom{p} as an element of the current domain
+ ++ if \axiom{retractIfCan(p)} does not return "failed", otherwise an error
+ ++ is produced.
+ convert : Polynomial R -> $
+ ++ \axiom{convert(p)} returns \axiom{p} as an element of the current domain if all
+ ++ its variables belong to \axiom{V}, otherwise an error is produced.
+
+ if R has RetractableTo(Integer)
+ then
+ ConvertibleTo(String)
+
+ if R has IntegralDomain
+ then
+ primPartElseUnitCanonical : $ -> $
+ ++ \axiom{primPartElseUnitCanonical(p)} returns \axiom{primitivePart(p)}
+ ++ if \axiom{R} is a gcd-domain, otherwise \axiom{unitCanonical(p)}.
+ primPartElseUnitCanonical! : $ -> $
+ ++ \axiom{primPartElseUnitCanonical!(p)} replaces \axiom{p}
+ ++ by \axiom{primPartElseUnitCanonical(p)}.
+ exactQuotient : ($,R) -> $
+ ++ \axiom{exactQuotient(p,r)} computes the exact quotient of \axiom{p}
+ ++ by \axiom{r}, which is assumed to be a divisor of \axiom{p}.
+ ++ No error is returned if this exact quotient fails!
+ exactQuotient! : ($,R) -> $
+ ++ \axiom{exactQuotient!(p,r)} replaces \axiom{p} by \axiom{exactQuotient(p,r)}.
+ exactQuotient : ($,$) -> $
+ ++ \axiom{exactQuotient(a,b)} computes the exact quotient of \axiom{a}
+ ++ by \axiom{b}, which is assumed to be a divisor of \axiom{a}.
+ ++ No error is returned if this exact quotient fails!
+ exactQuotient! : ($,$) -> $
+ ++ \axiom{exactQuotient!(a,b)} replaces \axiom{a} by \axiom{exactQuotient(a,b)}
+ subResultantGcd : ($, $) -> $
+ ++ \axiom{subResultantGcd(a,b)} computes a gcd of \axiom{a} and \axiom{b}
+ ++ where \axiom{a} and \axiom{b} are assumed to have the same main variable \axiom{v}
+ ++ and are viewed as univariate polynomials in \axiom{v} with coefficients
+ ++ in the fraction field of the polynomial ring generated by their other variables
+ ++ over \axiom{R}.
+ extendedSubResultantGcd : ($, $) -> Record (gcd : $, coef1 : $, coef2 : $)
+ ++ \axiom{extendedSubResultantGcd(a,b)} returns \axiom{[ca,cb,r]}
+ ++ such that \axiom{r} is \axiom{subResultantGcd(a,b)} and we have
+ ++ \axiom{ca * a + cb * cb = r} .
+ halfExtendedSubResultantGcd1: ($, $) -> Record (gcd : $, coef1 : $)
+ ++ \axiom{halfExtendedSubResultantGcd1(a,b)} returns \axiom{[g,ca]}
+ ++ if \axiom{extendedSubResultantGcd(a,b)} returns \axiom{[g,ca,cb]}
+ ++ otherwise produces an error.
+ halfExtendedSubResultantGcd2: ($, $) -> Record (gcd : $, coef2 : $)
+ ++ \axiom{halfExtendedSubResultantGcd2(a,b)} returns \axiom{[g,cb]}
+ ++ if \axiom{extendedSubResultantGcd(a,b)} returns \axiom{[g,ca,cb]}
+ ++ otherwise produces an error.
+ resultant : ($, $) -> $
+ ++ \axiom{resultant(a,b)} computes the resultant of \axiom{a} and \axiom{b}
+ ++ where \axiom{a} and \axiom{b} are assumed to have the same main variable \axiom{v}
+ ++ and are viewed as univariate polynomials in \axiom{v}.
+ subResultantChain : ($, $) -> List $
+ ++ \axiom{subResultantChain(a,b)}, where \axiom{a} and \axiom{b} are not
+ ++ contant polynomials with the same
+ ++ main variable, returns the subresultant chain of \axiom{a} and \axiom{b}.
+ lastSubResultant: ($, $) -> $
+ ++ \axiom{lastSubResultant(a,b)} returns the last non-zero subresultant
+ ++ of \axiom{a} and \axiom{b} where \axiom{a} and \axiom{b} are assumed to have
+ ++ the same main variable \axiom{v} and are viewed as univariate polynomials in \axiom{v}.
+ LazardQuotient: ($, $, NonNegativeInteger) -> $
+ ++ \axiom{LazardQuotient(a,b,n)} returns \axiom{a**n exquo b**(n-1)}
+ ++ assuming that this quotient does not fail.
+ LazardQuotient2: ($, $, $, NonNegativeInteger) -> $
+ ++ \axiom{LazardQuotient2(p,a,b,n)} returns
+ ++ \axiom{(a**(n-1) * p) exquo b**(n-1)}
+ ++ assuming that this quotient does not fail.
+ next_subResultant2: ($, $, $, $) -> $
+ ++ \axiom{nextsubResultant2(p,q,z,s)} is the multivariate version
+ ++ of the operation \axiomOpFrom{next_sousResultant2}{PseudoRemainderSequence} from
+ ++ the \axiomType{PseudoRemainderSequence} constructor.
+
+ if R has GcdDomain
+ then
+ gcd : (R,$) -> R
+ ++ \axiom{gcd(r,p)} returns the gcd of \axiom{r} and the content of \axiom{p}.
+ primitivePart! : $ -> $
+ ++ \axiom{primitivePart!(p)} replaces \axiom{p} by its primitive part.
+ mainContent : $ -> $
+ ++ \axiom{mainContent(p)} returns the content of \axiom{p} viewed as a univariate
+ ++ polynomial in its main variable and with coefficients in the
+ ++ polynomial ring generated by its other variables over \axiom{R}.
+ mainPrimitivePart : $ -> $
+ ++ \axiom{mainPrimitivePart(p)} returns the primitive part of \axiom{p} viewed as a
+ ++ univariate polynomial in its main variable and with coefficients
+ ++ in the polynomial ring generated by its other variables over \axiom{R}.
+ mainSquareFreePart : $ -> $
+ ++ \axiom{mainSquareFreePart(p)} returns the square free part of \axiom{p} viewed as a
+ ++ univariate polynomial in its main variable and with coefficients
+ ++ in the polynomial ring generated by its other variables over \axiom{R}.
+
+ add
+ O ==> OutputForm
+ NNI ==> NonNegativeInteger
+ INT ==> Integer
+
+ exactQuo : (R,R) -> R
+
+ coerce(p:$):O ==
+ ground? (p) => (ground(p))::O
+-- if one?((ip := init(p)))
+ if (((ip := init(p))) = 1)
+ then
+ if zero?((tp := tail(p)))
+ then
+-- if one?((dp := mdeg(p)))
+ if (((dp := mdeg(p))) = 1)
+ then
+ return((mvar(p))::O)
+ else
+ return(((mvar(p))::O **$O (dp::O)))
+ else
+-- if one?((dp := mdeg(p)))
+ if (((dp := mdeg(p))) = 1)
+ then
+ return((mvar(p))::O +$O (tp::O))
+ else
+ return(((mvar(p))::O **$O (dp::O)) +$O (tp::O))
+ else
+ if zero?((tp := tail(p)))
+ then
+-- if one?((dp := mdeg(p)))
+ if (((dp := mdeg(p))) = 1)
+ then
+ return((ip::O) *$O (mvar(p))::O)
+ else
+ return((ip::O) *$O ((mvar(p))::O **$O (dp::O)))
+ else
+-- if one?(mdeg(p))
+ if ((mdeg(p)) = 1)
+ then
+ return(((ip::O) *$O (mvar(p))::O) +$O (tp::O))
+ ((ip)::O *$O ((mvar(p))::O **$O ((mdeg(p)::O))) +$O (tail(p)::O))
+
+ mvar p ==
+ ground?(p) => error"Error in mvar from RPOLCAT : #1 is constant."
+ mainVariable(p)::V
+
+ mdeg p ==
+ ground?(p) => 0$NNI
+ degree(p,mainVariable(p)::V)
+
+ init p ==
+ ground?(p) => error"Error in mvar from RPOLCAT : #1 is constant."
+ v := mainVariable(p)::V
+ coefficient(p,v,degree(p,v))
+
+ leadingCoefficient (p,v) ==
+ zero? (d := degree(p,v)) => p
+ coefficient(p,v,d)
+
+ head p ==
+ ground? p => p
+ v := mainVariable(p)::V
+ d := degree(p,v)
+ monomial(coefficient(p,v,d),v,d)
+
+ reductum(p,v) ==
+ zero? (d := degree(p,v)) => 0$$
+ p - monomial(coefficient(p,v,d),v,d)
+
+ tail p ==
+ ground? p => 0$$
+ p - head(p)
+
+ deepestTail p ==
+ ground? p => 0$$
+ ground? tail(p) => tail(p)
+ mvar(p) > mvar(tail(p)) => tail(p)
+ deepestTail(tail(p))
+
+ iteratedInitials p ==
+ ground? p => []
+ p := init(p)
+ cons(p,iteratedInitials(p))
+
+ localDeepestInitial (p : $) : $ ==
+ ground? p => p
+ localDeepestInitial init p
+
+ deepestInitial p ==
+ ground? p => error"Error in deepestInitial from RPOLCAT : #1 is constant."
+ localDeepestInitial init p
+
+ monic? p ==
+ ground? p => false
+ (recip(init(p))$$ case $)@Boolean
+
+ quasiMonic? p ==
+ ground? p => false
+ ground?(init(p))
+
+ mainMonomial p ==
+ zero? p => error"Error in mainMonomial from RPOLCAT : #1 is zero"
+ ground? p => 1$$
+ v := mainVariable(p)::V
+ monomial(1$$,v,degree(p,v))
+
+ leastMonomial p ==
+ zero? p => error"Error in leastMonomial from RPOLCAT : #1 is zero"
+ ground? p => 1$$
+ v := mainVariable(p)::V
+ monomial(1$$,v,minimumDegree(p,v))
+
+ mainCoefficients p ==
+ zero? p => error"Error in mainCoefficients from RPOLCAT : #1 is zero"
+ ground? p => [p]
+ v := mainVariable(p)::V
+ coefficients(univariate(p,v)@SparseUnivariatePolynomial($))
+
+ mainMonomials p ==
+ zero? p => error"Error in mainMonomials from RPOLCAT : #1 is zero"
+ ground? p => [1$$]
+ v := mainVariable(p)::V
+ lm := monomials(univariate(p,v)@SparseUnivariatePolynomial($))
+ [monomial(1$$,v,degree(m)) for m in lm]
+
+ RittWuCompare (a,b) ==
+ (ground? b and ground? a) => "failed"::Union(Boolean,"failed")
+ ground? b => false::Union(Boolean,"failed")
+ ground? a => true::Union(Boolean,"failed")
+ mvar(a) < mvar(b) => true::Union(Boolean,"failed")
+ mvar(a) > mvar(b) => false::Union(Boolean,"failed")
+ mdeg(a) < mdeg(b) => true::Union(Boolean,"failed")
+ mdeg(a) > mdeg(b) => false::Union(Boolean,"failed")
+ lc := RittWuCompare(init(a),init(b))
+ lc case Boolean => lc
+ RittWuCompare(tail(a),tail(b))
+
+ infRittWu? (a,b) ==
+ lc : Union(Boolean,"failed") := RittWuCompare(a,b)
+ lc case Boolean => lc::Boolean
+ false
+
+ supRittWu? (a,b) ==
+ infRittWu? (b,a)
+
+ prem (a:$, b:$) : $ ==
+ cP := lazyPremWithDefault (a,b)
+ ((cP.coef) ** (cP.gap)) * cP.remainder
+
+ pquo (a:$, b:$) : $ ==
+ cPS := lazyPseudoDivide (a,b)
+ c := (cPS.coef) ** (cPS.gap)
+ c * cPS.quotient
+
+ prem (a:$, b:$, v:V) : $ ==
+ cP := lazyPremWithDefault (a,b,v)
+ ((cP.coef) ** (cP.gap)) * cP.remainder
+
+ pquo (a:$, b:$, v:V) : $ ==
+ cPS := lazyPseudoDivide (a,b,v)
+ c := (cPS.coef) ** (cPS.gap)
+ c * cPS.quotient
+
+ lazyPrem (a:$, b:$) : $ ==
+ (not ground?(b)) and (monic?(b)) => monicModulo(a,b)
+ (lazyPremWithDefault (a,b)).remainder
+
+ lazyPquo (a:$, b:$) : $ ==
+ (lazyPseudoDivide (a,b)).quotient
+
+ lazyPrem (a:$, b:$, v:V) : $ ==
+ zero? b => error"Error in lazyPrem : ($,$,V) -> $ from RPOLCAT : #2 is zero"
+ ground?(b) => 0$$
+ (v = mvar(b)) => lazyPrem(a,b)
+ dbv : NNI := degree(b,v)
+ zero? dbv => 0$$
+ dav : NNI := degree(a,v)
+ zero? dav => a
+ test : INT := dav::INT - dbv
+ lcbv : $ := leadingCoefficient(b,v)
+ while not zero?(a) and not negative?(test) repeat
+ lcav := leadingCoefficient(a,v)
+ term := monomial(lcav,v,test::NNI)
+ a := lcbv * a - term * b
+ test := degree(a,v)::INT - dbv
+ a
+
+ lazyPquo (a:$, b:$, v:V) : $ ==
+ (lazyPseudoDivide (a,b,v)).quotient
+
+ headReduce (a:$,b:$) ==
+ ground? b => error"Error in headReduce : ($,$) -> Boolean from TSETCAT : #2 is constant"
+ ground? a => a
+ mvar(a) = mvar(b) => lazyPrem(a,b)
+ while not reduced?((ha := head a),b) repeat
+ lrc := lazyResidueClass(ha,b)
+ if zero? tail(a)
+ then
+ a := lrc.polnum
+ else
+ a := lrc.polnum + (lrc.polden)**(lrc.power) * tail(a)
+ a
+
+ initiallyReduce(a:$,b:$) ==
+ ground? b => error"Error in initiallyReduce : ($,$) -> Boolean from TSETCAT : #2 is constant"
+ ground? a => a
+ v := mvar(b)
+ mvar(a) = v => lazyPrem(a,b)
+ ia := a
+ ma := 1$$
+ ta := 0$$
+ while (not ground?(ia)) and (mvar(ia) >= mvar(b)) repeat
+ if (mvar(ia) = mvar(b)) and (mdeg(ia) >= mdeg(b))
+ then
+ iamodb := lazyResidueClass(ia,b)
+ ia := iamodb.polnum
+ if not zero? ta
+ then
+ ta := (iamodb.polden)**(iamodb.power) * ta
+ if zero? ia
+ then
+ ia := ta
+ ma := 1$$
+ ta := 0$$
+ else
+ if not ground?(ia)
+ then
+ ta := tail(ia) * ma + ta
+ ma := mainMonomial(ia) * ma
+ ia := init(ia)
+ ia * ma + ta
+
+ lazyPremWithDefault (a,b) ==
+ ground?(b) => error"Error in lazyPremWithDefault from RPOLCAT : #2 is constant"
+ ground?(a) => [1$$,0$NNI,a]
+ xa := mvar a
+ xb := mvar b
+ xa < xb => [1$$,0$NNI,a]
+ lcb : $ := init b
+ db : NNI := mdeg b
+ test : INT := degree(a,xb)::INT - db
+ delta : INT := max(test + 1$INT, 0$INT)
+ if xa = xb
+ then
+ b := tail b
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(init(a),xb,test::NNI)
+ a := lcb * tail(a) - term * b
+ delta := delta - 1$INT
+ test := degree(a,xb)::INT - db
+ else
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,xb),xb,test::NNI)
+ a := lcb * a - term * b
+ delta := delta - 1$INT
+ test := degree(a,xb)::INT - db
+ [lcb, (delta::NNI), a]
+
+ lazyPremWithDefault (a,b,v) ==
+ zero? b => error"Error in lazyPremWithDefault : ($,$,V) -> $ from RPOLCAT : #2 is zero"
+ ground?(b) => [b,1$NNI,0$$]
+ (v = mvar(b)) => lazyPremWithDefault(a,b)
+ dbv : NNI := degree(b,v)
+ zero? dbv => [b,1$NNI,0$$]
+ dav : NNI := degree(a,v)
+ zero? dav => [1$$,0$NNI,a]
+ test : INT := dav::INT - dbv
+ delta : INT := max(test + 1$INT, 0$INT)
+ lcbv : $ := leadingCoefficient(b,v)
+ while not zero?(a) and not negative?(test) repeat
+ lcav := leadingCoefficient(a,v)
+ term := monomial(lcav,v,test::NNI)
+ a := lcbv * a - term * b
+ delta := delta - 1$INT
+ test := degree(a,v)::INT - dbv
+ [lcbv, (delta::NNI), a]
+
+ pseudoDivide (a,b) ==
+ cPS := lazyPseudoDivide (a,b)
+ c := (cPS.coef) ** (cPS.gap)
+ [c * cPS.quotient, c * cPS.remainder]
+
+ lazyPseudoDivide (a,b) ==
+ ground?(b) => error"Error in lazyPseudoDivide from RPOLCAT : #2 is constant"
+ ground?(a) => [1$$,0$NNI,0$$,a]
+ xa := mvar a
+ xb := mvar b
+ xa < xb => [1$$,0$NNI,0$$, a]
+ lcb : $ := init b
+ db : NNI := mdeg b
+ q := 0$$
+ test : INT := degree(a,xb)::INT - db
+ delta : INT := max(test + 1$INT, 0$INT)
+ if xa = xb
+ then
+ b := tail b
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(init(a),xb,test::NNI)
+ a := lcb * tail(a) - term * b
+ q := lcb * q + term
+ delta := delta - 1$INT
+ test := degree(a,xb)::INT - db
+ else
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,xb),xb,test::NNI)
+ a := lcb * a - term * b
+ q := lcb * q + term
+ delta := delta - 1$INT
+ test := degree(a,xb)::INT - db
+ [lcb, (delta::NNI), q, a]
+
+ lazyPseudoDivide (a,b,v) ==
+ zero? b => error"Error in lazyPseudoDivide : ($,$,V) -> $ from RPOLCAT : #2 is zero"
+ ground?(b) => [b,1$NNI,a,0$$]
+ (v = mvar(b)) => lazyPseudoDivide(a,b)
+ dbv : NNI := degree(b,v)
+ zero? dbv => [b,1$NNI,a,0$$]
+ dav : NNI := degree(a,v)
+ zero? dav => [1$$,0$NNI,0$$, a]
+ test : INT := dav::INT - dbv
+ delta : INT := max(test + 1$INT, 0$INT)
+ lcbv : $ := leadingCoefficient(b,v)
+ q := 0$$
+ while not zero?(a) and not negative?(test) repeat
+ lcav := leadingCoefficient(a,v)
+ term := monomial(lcav,v,test::NNI)
+ a := lcbv * a - term * b
+ q := lcbv * q + term
+ delta := delta - 1$INT
+ test := degree(a,v)::INT - dbv
+ [lcbv, (delta::NNI), q, a]
+
+ monicModulo (a,b) ==
+ ground?(b) => error"Error in monicModulo from RPOLCAT : #2 is constant"
+ rec : Union($,"failed")
+ rec := recip((ib := init(b)))$$
+ (rec case "failed")@Boolean => error"Error in monicModulo from RPOLCAT : #2 is not monic"
+ ground? a => a
+ ib * ((lazyPremWithDefault ((rec::$) * a,(rec::$) * b)).remainder)
+
+ lazyResidueClass(a,b) ==
+ zero? b => [a,1$$,0$NNI]
+ ground? b => [0$$,1$$,0$NNI]
+ ground? a => [a,1$$,0$NNI]
+ xa := mvar a
+ xb := mvar b
+ xa < xb => [a,1$$,0$NNI]
+ monic?(b) => [monicModulo(a,b),1$$,0$NNI]
+ lcb : $ := init b
+ db : NNI := mdeg b
+ test : INT := degree(a,xb)::INT - db
+ pow : NNI := 0
+ if xa = xb
+ then
+ b := tail b
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(init(a),xb,test::NNI)
+ a := lcb * tail(a) - term * b
+ pow := pow + 1$NNI
+ test := degree(a,xb)::INT - db
+ else
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,xb),xb,test::NNI)
+ a := lcb * a - term * b
+ pow := pow + 1$NNI
+ test := degree(a,xb)::INT - db
+ [a,lcb,pow]
+
+ reduced? (a:$,b:$) : Boolean ==
+ degree(a,mvar(b)) < mdeg(b)
+
+ reduced? (p:$, lq : List($)) : Boolean ==
+ ground? p => true
+ while (not empty? lq) and (reduced?(p, first lq)) repeat
+ lq := rest lq
+ empty? lq
+
+ headReduced? (a:$,b:$) : Boolean ==
+ reduced?(head(a),b)
+
+ headReduced? (p:$, lq : List($)) : Boolean ==
+ reduced?(head(p),lq)
+
+ initiallyReduced? (a:$,b:$) : Boolean ==
+ ground? b => error"Error in initiallyReduced? : ($,$) -> Bool. from RPOLCAT : #2 is constant"
+ ground?(a) => true
+ mvar(a) < mvar(b) => true
+ (mvar(a) = mvar(b)) => reduced?(a,b)
+ initiallyReduced?(init(a),b)
+
+ initiallyReduced? (p:$, lq : List($)) : Boolean ==
+ ground? p => true
+ while (not empty? lq) and (initiallyReduced?(p, first lq)) repeat
+ lq := rest lq
+ empty? lq
+
+ normalized?(a:$,b:$) : Boolean ==
+ ground? b => error"Error in normalized? : ($,$) -> Boolean from TSETCAT : #2 is constant"
+ ground? a => true
+ mvar(a) < mvar(b) => true
+ (mvar(a) = mvar(b)) => false
+ normalized?(init(a),b)
+
+ normalized? (p:$, lq : List($)) : Boolean ==
+ while (not empty? lq) and (normalized?(p, first lq)) repeat
+ lq := rest lq
+ empty? lq
+
+ if R has IntegralDomain
+ then
+
+ if R has EuclideanDomain
+ then
+ exactQuo(r:R,s:R):R ==
+ r quo$R s
+ else
+ exactQuo(r:R,s:R):R ==
+ (r exquo$R s)::R
+
+ exactQuotient (p:$,r:R) ==
+ (p exquo$$ r)::$
+
+ exactQuotient (a:$,b:$) ==
+ ground? b => exactQuotient(a,ground(b))
+ (a exquo$$ b)::$
+
+ exactQuotient! (a:$,b:$) ==
+ ground? b => exactQuotient!(a,ground(b))
+ a := (a exquo$$ b)::$
+
+ if (R has GcdDomain) and not(R has Field)
+ then
+
+ primPartElseUnitCanonical p ==
+ primitivePart p
+
+ primitivePart! p ==
+ zero? p => p
+-- if one?(cp := content(p))
+ if ((cp := content(p)) = 1)
+ then
+ p := unitCanonical p
+ else
+ p := unitCanonical exactQuotient!(p,cp)
+ p
+
+ primPartElseUnitCanonical! p ==
+ primitivePart! p
+
+ else
+ primPartElseUnitCanonical p ==
+ unitCanonical p
+
+ primPartElseUnitCanonical! p ==
+ p := unitCanonical p
+
+
+ if R has GcdDomain
+ then
+
+ gcd(r:R,p:$):R ==
+-- one? r => r
+ (r = 1) => r
+ zero? p => r
+ ground? p => gcd(r,ground(p))$R
+ gcd(gcd(r,init(p)),tail(p))
+
+ mainContent p ==
+ zero? p => p
+ "gcd"/mainCoefficients(p)
+
+ mainPrimitivePart p ==
+ zero? p => p
+ (unitNormal((p exquo$$ mainContent(p))::$)).canonical
+
+ mainSquareFreePart p ==
+ ground? p => p
+ v := mainVariable(p)::V
+ sfp : SparseUnivariatePolynomial($)
+ sfp := squareFreePart(univariate(p,v)@SparseUnivariatePolynomial($))
+ multivariate(sfp,v)
+
+ if (V has ConvertibleTo(Symbol))
+ then
+
+ PR ==> Polynomial R
+ PQ ==> Polynomial Fraction Integer
+ PZ ==> Polynomial Integer
+ IES ==> IndexedExponents(Symbol)
+ Q ==> Fraction Integer
+ Z ==> Integer
+
+ convert(p:$) : PR ==
+ ground? p => (ground(p)$$)::PR
+ v : V := mvar(p)
+ d : NNI := mdeg(p)
+ convert(init(p))@PR *$PR ((convert(v)@Symbol)::PR)**d +$PR convert(tail(p))@PR
+
+ coerce(p:$) : PR ==
+ convert(p)@PR
+
+ localRetract : PR -> $
+ localRetractPQ : PQ -> $
+ localRetractPZ : PZ -> $
+ localRetractIfCan : PR -> Union($,"failed")
+ localRetractIfCanPQ : PQ -> Union($,"failed")
+ localRetractIfCanPZ : PZ -> Union($,"failed")
+
+ if V has Finite
+ then
+
+ sizeV : NNI := size()$V
+ lv : List Symbol
+ lv := [convert(index(i::PositiveInteger)$V)@Symbol for i in 1..sizeV]
+
+ localRetract(p : PR) : $ ==
+ ground? p => (ground(p)$PR)::$
+ mvp : Symbol := (mainVariable(p)$PR)::Symbol
+ d : NNI
+ imvp : PositiveInteger := (position(mvp,lv)$(List Symbol))::PositiveInteger
+ vimvp : V := index(imvp)$V
+ xvimvp,c : $
+ newp := 0$$
+ while (not zero? (d := degree(p,mvp))) repeat
+ c := localRetract(coefficient(p,mvp,d)$PR)
+ xvimvp := monomial(c,vimvp,d)$$
+ newp := newp +$$ xvimvp
+ p := p -$PR monomial(coefficient(p,mvp,d)$PR,mvp,d)$PR
+ newp +$$ localRetract(p)
+
+ if R has Algebra Fraction Integer
+ then
+ localRetractPQ(pq:PQ):$ ==
+ ground? pq => ((ground(pq)$PQ)::R)::$
+ mvp : Symbol := (mainVariable(pq)$PQ)::Symbol
+ d : NNI
+ imvp : PositiveInteger := (position(mvp,lv)$(List Symbol))::PositiveInteger
+ vimvp : V := index(imvp)$V
+ xvimvp,c : $
+ newp := 0$$
+ while (not zero? (d := degree(pq,mvp))) repeat
+ c := localRetractPQ(coefficient(pq,mvp,d)$PQ)
+ xvimvp := monomial(c,vimvp,d)$$
+ newp := newp +$$ xvimvp
+ pq := pq -$PQ monomial(coefficient(pq,mvp,d)$PQ,mvp,d)$PQ
+ newp +$$ localRetractPQ(pq)
+
+ if R has Algebra Integer
+ then
+ localRetractPZ(pz:PZ):$ ==
+ ground? pz => ((ground(pz)$PZ)::R)::$
+ mvp : Symbol := (mainVariable(pz)$PZ)::Symbol
+ d : NNI
+ imvp : PositiveInteger := (position(mvp,lv)$(List Symbol))::PositiveInteger
+ vimvp : V := index(imvp)$V
+ xvimvp,c : $
+ newp := 0$$
+ while (not zero? (d := degree(pz,mvp))) repeat
+ c := localRetractPZ(coefficient(pz,mvp,d)$PZ)
+ xvimvp := monomial(c,vimvp,d)$$
+ newp := newp +$$ xvimvp
+ pz := pz -$PZ monomial(coefficient(pz,mvp,d)$PZ,mvp,d)$PZ
+ newp +$$ localRetractPZ(pz)
+
+ retractable?(p:PR):Boolean ==
+ lvp := variables(p)$PR
+ while not empty? lvp and member?(first lvp,lv) repeat
+ lvp := rest lvp
+ empty? lvp
+
+ retractablePQ?(p:PQ):Boolean ==
+ lvp := variables(p)$PQ
+ while not empty? lvp and member?(first lvp,lv) repeat
+ lvp := rest lvp
+ empty? lvp
+
+ retractablePZ?(p:PZ):Boolean ==
+ lvp := variables(p)$PZ
+ while not empty? lvp and member?(first lvp,lv) repeat
+ lvp := rest lvp
+ empty? lvp
+
+ localRetractIfCan(p : PR): Union($,"failed") ==
+ not retractable?(p) => "failed"::Union($,"failed")
+ localRetract(p)::Union($,"failed")
+
+ localRetractIfCanPQ(p : PQ): Union($,"failed") ==
+ not retractablePQ?(p) => "failed"::Union($,"failed")
+ localRetractPQ(p)::Union($,"failed")
+
+ localRetractIfCanPZ(p : PZ): Union($,"failed") ==
+ not retractablePZ?(p) => "failed"::Union($,"failed")
+ localRetractPZ(p)::Union($,"failed")
+
+ if R has Algebra Fraction Integer
+ then
+
+ mpc2Z := MPolyCatFunctions2(Symbol,IES,IES,Z,R,PZ,PR)
+ mpc2Q := MPolyCatFunctions2(Symbol,IES,IES,Q,R,PQ,PR)
+ ZToR (z:Z):R == coerce(z)@R
+ QToR (q:Q):R == coerce(q)@R
+ PZToPR (pz:PZ):PR == map(ZToR,pz)$mpc2Z
+ PQToPR (pq:PQ):PR == map(QToR,pq)$mpc2Q
+
+ retract(pz:PZ) ==
+ rif : Union($,"failed") := retractIfCan(pz)@Union($,"failed")
+ (rif case "failed") => error"failed in retract: POLY Z -> $ from RPOLCAT"
+ rif::$
+
+ convert(pz:PZ) ==
+ retract(pz)@$
+
+ retract(pq:PQ) ==
+ rif : Union($,"failed") := retractIfCan(pq)@Union($,"failed")
+ (rif case "failed") => error"failed in retract: POLY Z -> $ from RPOLCAT"
+ rif::$
+
+ convert(pq:PQ) ==
+ retract(pq)@$
+
+ if not (R has QuotientFieldCategory(Integer))
+ then
+ -- the only operation to implement is retractIfCan : PR -> Union($,"failed")
+ -- when V does not have Finite
+
+ if V has Finite
+ then
+ retractIfCan(pr:PR) ==
+ localRetractIfCan(pr)@Union($,"failed")
+
+ retractIfCan(pq:PQ) ==
+ localRetractIfCanPQ(pq)@Union($,"failed")
+ else
+ retractIfCan(pq:PQ) ==
+ pr : PR := PQToPR(pq)
+ retractIfCan(pr)@Union($,"failed")
+
+ retractIfCan(pz:PZ) ==
+ pr : PR := PZToPR(pz)
+ retractIfCan(pr)@Union($,"failed")
+
+ retract(pr:PR) ==
+ rif : Union($,"failed") := retractIfCan(pr)@Union($,"failed")
+ (rif case "failed") => error"failed in retract: POLY Z -> $ from RPOLCAT"
+ rif::$
+
+ convert(pr:PR) ==
+ retract(pr)@$
+
+ else
+ -- the only operation to implement is retractIfCan : PQ -> Union($,"failed")
+ -- when V does not have Finite
+ mpc2ZQ := MPolyCatFunctions2(Symbol,IES,IES,Z,Q,PZ,PQ)
+ mpc2RQ := MPolyCatFunctions2(Symbol,IES,IES,R,Q,PR,PQ)
+ ZToQ(z:Z):Q == coerce(z)@Q
+ RToQ(r:R):Q == retract(r)@Q
+
+ PZToPQ (pz:PZ):PQ == map(ZToQ,pz)$mpc2ZQ
+ PRToPQ (pr:PR):PQ == map(RToQ,pr)$mpc2RQ
+
+ retractIfCan(pz:PZ) ==
+ pq : PQ := PZToPQ(pz)
+ retractIfCan(pq)@Union($,"failed")
+
+ if V has Finite
+ then
+ retractIfCan(pq:PQ) ==
+ localRetractIfCanPQ(pq)@Union($,"failed")
+
+ convert(pr:PR) ==
+ lrif : Union($,"failed") := localRetractIfCan(pr)@Union($,"failed")
+ (lrif case "failed") => error"failed in convert: PR->$ from RPOLCAT"
+ lrif::$
+ else
+ convert(pr:PR) ==
+ pq : PQ := PRToPQ(pr)
+ retract(pq)@$
+
+ if (R has Algebra Integer) and not(R has Algebra Fraction Integer)
+ then
+
+ mpc2Z := MPolyCatFunctions2(Symbol,IES,IES,Z,R,PZ,PR)
+ ZToR (z:Z):R == coerce(z)@R
+ PZToPR (pz:PZ):PR == map(ZToR,pz)$mpc2Z
+
+ retract(pz:PZ) ==
+ rif : Union($,"failed") := retractIfCan(pz)@Union($,"failed")
+ (rif case "failed") => error"failed in retract: POLY Z -> $ from RPOLCAT"
+ rif::$
+
+ convert(pz:PZ) ==
+ retract(pz)@$
+
+ if not (R has IntegerNumberSystem)
+ then
+ -- the only operation to implement is retractIfCan : PR -> Union($,"failed")
+ -- when V does not have Finite
+
+ if V has Finite
+ then
+ retractIfCan(pr:PR) ==
+ localRetractIfCan(pr)@Union($,"failed")
+
+ retractIfCan(pz:PZ) ==
+ localRetractIfCanPZ(pz)@Union($,"failed")
+ else
+ retractIfCan(pz:PZ) ==
+ pr : PR := PZToPR(pz)
+ retractIfCan(pr)@Union($,"failed")
+
+ retract(pr:PR) ==
+ rif : Union($,"failed") := retractIfCan(pr)@Union($,"failed")
+ (rif case "failed") => error"failed in retract: POLY Z -> $ from RPOLCAT"
+ rif::$
+
+ convert(pr:PR) ==
+ retract(pr)@$
+
+ else
+ -- the only operation to implement is retractIfCan : PZ -> Union($,"failed")
+ -- when V does not have Finite
+
+ mpc2RZ := MPolyCatFunctions2(Symbol,IES,IES,R,Z,PR,PZ)
+ RToZ(r:R):Z == retract(r)@Z
+ PRToPZ (pr:PR):PZ == map(RToZ,pr)$mpc2RZ
+
+ if V has Finite
+ then
+ convert(pr:PR) ==
+ lrif : Union($,"failed") := localRetractIfCan(pr)@Union($,"failed")
+ (lrif case "failed") => error"failed in convert: PR->$ from RPOLCAT"
+ lrif::$
+ retractIfCan(pz:PZ) ==
+ localRetractIfCanPZ(pz)@Union($,"failed")
+ else
+ convert(pr:PR) ==
+ pz : PZ := PRToPZ(pr)
+ retract(pz)@$
+
+
+ if not(R has Algebra Integer) and not(R has Algebra Fraction Integer)
+ then
+ -- the only operation to implement is retractIfCan : PR -> Union($,"failed")
+
+ if V has Finite
+ then
+ retractIfCan(pr:PR) ==
+ localRetractIfCan(pr)@Union($,"failed")
+
+ retract(pr:PR) ==
+ rif : Union($,"failed") := retractIfCan(pr)@Union($,"failed")
+ (rif case "failed") => error"failed in retract: POLY Z -> $ from RPOLCAT"
+ rif::$
+
+ convert(pr:PR) ==
+ retract(pr)@$
+
+ if (R has RetractableTo(INT))
+ then
+
+ convert(pol:$):String ==
+ ground?(pol) => convert(retract(ground(pol))@INT)@String
+ ipol : $ := init(pol)
+ vpol : V := mvar(pol)
+ dpol : NNI := mdeg(pol)
+ tpol: $ := tail(pol)
+ sipol,svpol,sdpol,stpol : String
+-- if one? ipol
+ if (ipol = 1)
+ then
+ sipol := empty()$String
+ else
+-- if one?(-ipol)
+ if ((-ipol) = 1)
+ then
+ sipol := "-"
+ else
+ sipol := convert(ipol)@String
+ if not monomial?(ipol)
+ then
+ sipol := concat(["(",sipol,")*"])$String
+ else
+ sipol := concat(sipol,"*")$String
+ svpol := string(convert(vpol)@Symbol)
+-- if one? dpol
+ if (dpol = 1)
+ then
+ sdpol := empty()$String
+ else
+ sdpol := concat("**",convert(convert(dpol)@INT)@String )$String
+ if zero? tpol
+ then
+ stpol := empty()$String
+ else
+ if ground?(tpol)
+ then
+ n := retract(ground(tpol))@INT
+ if n > 0
+ then
+ stpol := concat(" +",convert(n)@String)$String
+ else
+ stpol := convert(n)@String
+ else
+ stpol := convert(tpol)@String
+ if not member?((stpol.1)::String,["+","-"])$(List String)
+ then
+ stpol := concat(" + ",stpol)$String
+ concat([sipol,svpol,sdpol,stpol])$String
+
+@
+Based on the {\bf PseudoRemainderSequence} package, the domain
+constructor {\bf NewSparseMulitvariatePolynomial} extends
+the constructor {\bf SparseMultivariatePolynomial}. It also provides
+some additional operations related to polynomial system solving
+by means of triangular sets.
+\section{domain NSMP NewSparseMultivariatePolynomial}
+<<domain NSMP NewSparseMultivariatePolynomial>>=
+)abbrev domain NSMP NewSparseMultivariatePolynomial
+++ Author: Marc Moreno Maza
+++ Date Created: 22/04/94
+++ Date Last Updated: 14/12/1998
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: A post-facto extension for \axiomType{SMP} in order
+++ to speed up operations related to pseudo-division and gcd.
+++ This domain is based on the \axiomType{NSUP} constructor which is
+++ itself a post-facto extension of the \axiomType{SUP} constructor.
+++ Version: 2
+
+NewSparseMultivariatePolynomial(R,VarSet) : Exports == Implementation where
+ R:Ring
+ VarSet:OrderedSet
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ SUP ==> NewSparseUnivariatePolynomial
+ SMPR ==> SparseMultivariatePolynomial(R, VarSet)
+ SUP2 ==> NewSparseUnivariatePolynomialFunctions2($,$)
+
+ Exports == Join(RecursivePolynomialCategory(R,IndexedExponents VarSet, VarSet),
+ CoercibleTo(SMPR),RetractableTo(SMPR))
+
+ Implementation == SparseMultivariatePolynomial(R, VarSet) add
+
+ D := NewSparseUnivariatePolynomial($)
+ VPoly:= Record(v:VarSet,ts:D)
+ Rep:= Union(R,VPoly)
+
+ --local function
+ PSimp: (D,VarSet) -> %
+
+ PSimp(up,mv) ==
+ if degree(up) = 0 then leadingCoefficient(up) else [mv,up]$VPoly
+
+ coerce (p:$):SMPR ==
+ p pretend SMPR
+
+ coerce (p:SMPR):$ ==
+ p pretend $
+
+ retractIfCan (p:$) : Union(SMPR,"failed") ==
+ (p pretend SMPR)::Union(SMPR,"failed")
+
+ mvar p ==
+ p case R => error" Error in mvar from NSMP : #1 has no variables."
+ p.v
+
+ mdeg p ==
+ p case R => 0$N
+ degree(p.ts)$D
+
+ init p ==
+ p case R => error" Error in init from NSMP : #1 has no variables."
+ leadingCoefficient(p.ts)$D
+
+ head p ==
+ p case R => p
+ ([p.v,leadingMonomial(p.ts)$D]$VPoly)::Rep
+
+ tail p ==
+ p case R => 0$$
+ red := reductum(p.ts)$D
+ ground?(red)$D => (ground(red)$D)::Rep
+ ([p.v,red]$VPoly)::Rep
+
+ iteratedInitials p ==
+ p case R => []
+ p := leadingCoefficient(p.ts)$D
+ cons(p,iteratedInitials(p))
+
+ localDeepestInitial (p : $) : $ ==
+ p case R => p
+ localDeepestInitial leadingCoefficient(p.ts)$D
+
+ deepestInitial p ==
+ p case R => error"Error in deepestInitial from NSMP : #1 has no variables."
+ localDeepestInitial leadingCoefficient(p.ts)$D
+
+ mainMonomial p ==
+ zero? p => error"Error in mainMonomial from NSMP : the argument is zero"
+ p case R => 1$$
+ monomial(1$$,p.v,degree(p.ts)$D)
+
+ leastMonomial p ==
+ zero? p => error"Error in leastMonomial from NSMP : the argument is zero"
+ p case R => 1$$
+ monomial(1$$,p.v,minimumDegree(p.ts)$D)
+
+ mainCoefficients p ==
+ zero? p => error"Error in mainCoefficients from NSMP : the argument is zero"
+ p case R => [p]
+ coefficients(p.ts)$D
+
+ leadingCoefficient(p:$,x:VarSet):$ ==
+ (p case R) => p
+ p.v = x => leadingCoefficient(p.ts)$D
+ zero? (d := degree(p,x)) => p
+ coefficient(p,x,d)
+
+ localMonicModulo(a:$,b:$):$ ==
+ -- b is assumed to have initial 1
+ a case R => a
+ a.v < b.v => a
+ mM: $
+ if a.v > b.v
+ then
+ m : D := map(localMonicModulo(#1,b),a.ts)$SUP2
+ else
+ m : D := monicModulo(a.ts,b.ts)$D
+ if ground?(m)$D
+ then
+ mM := (ground(m)$D)::Rep
+ else
+ mM := ([a.v,m]$VPoly)::Rep
+ mM
+
+ monicModulo (a,b) ==
+ b case R => error"Error in monicModulo from NSMP : #2 is constant"
+ ib : $ := init(b)@$
+ not ground?(ib)$$ =>
+ error"Error in monicModulo from NSMP : #2 is not monic"
+ mM : $
+-- if not one?(ib)$$
+ if not ((ib) = 1)$$
+ then
+ r : R := ground(ib)$$
+ rec : Union(R,"failed"):= recip(r)$R
+ (rec case "failed") =>
+ error"Error in monicModulo from NSMP : #2 is not monic"
+ a case R => a
+ a := (rec::R) * a
+ b := (rec::R) * b
+ mM := ib * localMonicModulo (a,b)
+ else
+ mM := localMonicModulo (a,b)
+ mM
+
+ prem(a:$, b:$): $ ==
+ -- with pseudoRemainder$NSUP
+ b case R =>
+ error "in prem$NSMP: ground? #2"
+ db: N := degree(b.ts)$D
+ lcb: $ := leadingCoefficient(b.ts)$D
+ test: Z := degree(a,b.v)::Z - db
+ delta: Z := max(test + 1$Z, 0$Z)
+ (a case R) or (a.v < b.v) => lcb ** (delta::N) * a
+ a.v = b.v =>
+ r: D := pseudoRemainder(a.ts,b.ts)$D
+ ground?(r) => return (ground(r)$D)::Rep
+ ([a.v,r]$VPoly)::Rep
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,b.v),b.v,test::N)
+ a := lcb * a - term * b
+ delta := delta - 1$Z
+ test := degree(a,b.v)::Z - db
+ lcb ** (delta::N) * a
+
+ pquo (a:$, b:$) : $ ==
+ cPS := lazyPseudoDivide (a,b)
+ c := (cPS.coef) ** (cPS.gap)
+ c * cPS.quotient
+
+ pseudoDivide(a:$, b:$): Record (quotient : $, remainder : $) ==
+ -- from RPOLCAT
+ cPS := lazyPseudoDivide(a,b)
+ c := (cPS.coef) ** (cPS.gap)
+ [c * cPS.quotient, c * cPS.remainder]
+
+ lazyPrem(a:$, b:$): $ ==
+ -- with lazyPseudoRemainder$NSUP
+ -- Uses leadingCoefficient: ($, V) -> $
+ b case R =>
+ error "in lazyPrem$NSMP: ground? #2"
+ (a case R) or (a.v < b.v) => a
+ a.v = b.v => PSimp(lazyPseudoRemainder(a.ts,b.ts)$D,a.v)
+ db: N := degree(b.ts)$D
+ lcb: $ := leadingCoefficient(b.ts)$D
+ test: Z := degree(a,b.v)::Z - db
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,b.v),b.v,test::N)
+ a := lcb * a - term * b
+ test := degree(a,b.v)::Z - db
+ a
+
+ lazyPquo (a:$, b:$) : $ ==
+ -- with lazyPseudoQuotient$NSUP
+ b case R =>
+ error " in lazyPquo$NSMP: #2 is conctant"
+ (a case R) or (a.v < b.v) => 0
+ a.v = b.v => PSimp(lazyPseudoQuotient(a.ts,b.ts)$D,a.v)
+ db: N := degree(b.ts)$D
+ lcb: $ := leadingCoefficient(b.ts)$D
+ test: Z := degree(a,b.v)::Z - db
+ q := 0$$
+ test: Z := degree(a,b.v)::Z - db
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,b.v),b.v,test::N)
+ a := lcb * a - term * b
+ q := lcb * q + term
+ test := degree(a,b.v)::Z - db
+ q
+
+ lazyPseudoDivide(a:$, b:$): Record(coef:$, gap: N,quotient:$, remainder:$) ==
+ -- with lazyPseudoDivide$NSUP
+ b case R =>
+ error " in lazyPseudoDivide$NSMP: #2 is conctant"
+ (a case R) or (a.v < b.v) => [1$$,0$N,0$$,a]
+ a.v = b.v =>
+ cgqr := lazyPseudoDivide(a.ts,b.ts)
+ [cgqr.coef, cgqr.gap, PSimp(cgqr.quotient,a.v), PSimp(cgqr.remainder,a.v)]
+ db: N := degree(b.ts)$D
+ lcb: $ := leadingCoefficient(b.ts)$D
+ test: Z := degree(a,b.v)::Z - db
+ q := 0$$
+ delta: Z := max(test + 1$Z, 0$Z)
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,b.v),b.v,test::N)
+ a := lcb * a - term * b
+ q := lcb * q + term
+ delta := delta - 1$Z
+ test := degree(a,b.v)::Z - db
+ [lcb, (delta::N), q, a]
+
+ lazyResidueClass(a:$, b:$): Record(polnum:$, polden:$, power:N) ==
+ -- with lazyResidueClass$NSUP
+ b case R =>
+ error " in lazyResidueClass$NSMP: #2 is conctant"
+ lcb: $ := leadingCoefficient(b.ts)$D
+ (a case R) or (a.v < b.v) => [a,lcb,0]
+ a.v = b.v =>
+ lrc := lazyResidueClass(a.ts,b.ts)$D
+ [PSimp(lrc.polnum,a.v), lrc.polden, lrc.power]
+ db: N := degree(b.ts)$D
+ test: Z := degree(a,b.v)::Z - db
+ pow: N := 0
+ while not zero?(a) and not negative?(test) repeat
+ term := monomial(leadingCoefficient(a,b.v),b.v,test::N)
+ a := lcb * a - term * b
+ pow := pow + 1
+ test := degree(a,b.v)::Z - db
+ [a, lcb, pow]
+
+ if R has IntegralDomain
+ then
+
+ packD := PseudoRemainderSequence($,D)
+
+ exactQuo(x:$, y:$):$ ==
+ ex: Union($,"failed") := x exquo$$ y
+ (ex case $) => ex::$
+ error "in exactQuotient$NSMP: bad args"
+
+ LazardQuotient(x:$, y:$, n: N):$ ==
+ zero?(n) => error("LazardQuotient$NSMP : n = 0")
+-- one?(n) => x
+ (n = 1) => x
+ a: N := 1
+ while n >= (b := 2*a) repeat a := b
+ c: $ := x
+ n := (n - a)::N
+ repeat
+-- one?(a) => return c
+ (a = 1) => return c
+ a := a quo 2
+ c := exactQuo(c*c,y)
+ if n >= a then ( c := exactQuo(c*x,y) ; n := (n - a)::N )
+
+ LazardQuotient2(p:$, a:$, b:$, n: N) ==
+ zero?(n) => error " in LazardQuotient2$NSMP: bad #4"
+-- one?(n) => p
+ (n = 1) => p
+ c: $ := LazardQuotient(a,b,(n-1)::N)
+ exactQuo(c*p,b)
+
+ next_subResultant2(p:$, q:$, z:$, s:$) ==
+ PSimp(next_sousResultant2(p.ts,q.ts,z.ts,s)$packD,p.v)
+
+ subResultantGcd(a:$, b:$): $ ==
+ (a case R) or (b case R) =>
+ error "subResultantGcd$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "subResultantGcd$NSMP: mvar(#1) ~= mvar(#2)"
+ PSimp(subResultantGcd(a.ts,b.ts),a.v)
+
+ halfExtendedSubResultantGcd1(a:$,b:$): Record (gcd: $, coef1: $) ==
+ (a case R) or (b case R) =>
+ error "halfExtendedSubResultantGcd1$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "halfExtendedSubResultantGcd1$NSMP: mvar(#1) ~= mvar(#2)"
+ hesrg := halfExtendedSubResultantGcd1(a.ts,b.ts)$D
+ [PSimp(hesrg.gcd,a.v), PSimp(hesrg.coef1,a.v)]
+
+ halfExtendedSubResultantGcd2(a:$,b:$): Record (gcd: $, coef2: $) ==
+ (a case R) or (b case R) =>
+ error "halfExtendedSubResultantGcd2$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "halfExtendedSubResultantGcd2$NSMP: mvar(#1) ~= mvar(#2)"
+ hesrg := halfExtendedSubResultantGcd2(a.ts,b.ts)$D
+ [PSimp(hesrg.gcd,a.v), PSimp(hesrg.coef2,a.v)]
+
+ extendedSubResultantGcd(a:$,b:$): Record (gcd: $, coef1: $, coef2: $) ==
+ (a case R) or (b case R) =>
+ error "extendedSubResultantGcd$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "extendedSubResultantGcd$NSMP: mvar(#1) ~= mvar(#2)"
+ esrg := extendedSubResultantGcd(a.ts,b.ts)$D
+ [PSimp(esrg.gcd,a.v),PSimp(esrg.coef1,a.v),PSimp(esrg.coef2,a.v)]
+
+ resultant(a:$, b:$): $ ==
+ (a case R) or (b case R) =>
+ error "resultant$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "resultant$NSMP: mvar(#1) ~= mvar(#2)"
+ resultant(a.ts,b.ts)$D
+
+ subResultantChain(a:$, b:$): List $ ==
+ (a case R) or (b case R) =>
+ error "subResultantChain$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "subResultantChain$NSMP: mvar(#1) ~= mvar(#2)"
+ [PSimp(up,a.v) for up in subResultantsChain(a.ts,b.ts)]
+
+ lastSubResultant(a:$, b:$): $ ==
+ (a case R) or (b case R) =>
+ error "lastSubResultant$NSMP: one arg is constant"
+ a.v ~= b.v =>
+ error "lastSubResultant$NSMP: mvar(#1) ~= mvar(#2)"
+ PSimp(lastSubResultant(a.ts,b.ts),a.v)
+
+ if R has EuclideanDomain
+ then
+
+ exactQuotient (a:$,b:R) ==
+-- one? b => a
+ (b = 1) => a
+ a case R => (a::R quo$R b)::$
+ ([a.v, map(exactQuotient(#1,b),a.ts)$SUP2]$VPoly)::Rep
+
+ exactQuotient! (a:$,b:R) ==
+-- one? b => a
+ (b = 1) => a
+ a case R => (a::R quo$R b)::$
+ a.ts := map(exactQuotient!(#1,b),a.ts)$SUP2
+ a
+
+ else
+
+ exactQuotient (a:$,b:R) ==
+-- one? b => a
+ (b = 1) => a
+ a case R => ((a::R exquo$R b)::R)::$
+ ([a.v, map(exactQuotient(#1,b),a.ts)$SUP2]$VPoly)::Rep
+
+ exactQuotient! (a:$,b:R) ==
+-- one? b => a
+ (b = 1) => a
+ a case R => ((a::R exquo$R b)::R)::$
+ a.ts := map(exactQuotient!(#1,b),a.ts)$SUP2
+ a
+
+ if R has GcdDomain
+ then
+
+ localGcd(r:R,p:$):R ==
+ p case R => gcd(r,p::R)$R
+ gcd(r,content(p))$R
+
+ gcd(r:R,p:$):R ==
+-- one? r => r
+ (r = 1) => r
+ zero? p => r
+ localGcd(r,p)
+
+ content p ==
+ p case R => p
+ up : D := p.ts
+ r := 0$R
+-- while (not zero? up) and (not one? r) repeat
+ while (not zero? up) and (not (r = 1)) repeat
+ r := localGcd(r,leadingCoefficient(up))
+ up := reductum up
+ r
+
+ primitivePart! p ==
+ zero? p => p
+ p case R => 1$$
+ cp := content(p)
+ p.ts := unitCanonical(map(exactQuotient!(#1,cp),p.ts)$SUP2)$D
+ p
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain NSUP NewSparseUnivariatePolynomial>>
+<<package NSUP2 NewSparseUnivariatePolynomialFunctions2>>
+<<category RPOLCAT RecursivePolynomialCategory>>
+<<domain NSMP NewSparseMultivariatePolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nlinsol.spad.pamphlet b/src/algebra/nlinsol.spad.pamphlet
new file mode 100644
index 00000000..f181a478
--- /dev/null
+++ b/src/algebra/nlinsol.spad.pamphlet
@@ -0,0 +1,224 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nlinsol.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package RETSOL RetractSolvePackage}
+<<package RETSOL RetractSolvePackage>>=
+)abbrev package RETSOL RetractSolvePackage
+++ Author: Manuel Bronstein
+++ Date Created: 31 October 1991
+++ Date Last Updated: 31 October 1991
+++ Description:
+++ RetractSolvePackage is an interface to \spadtype{SystemSolvePackage}
+++ that attempts to retract the coefficients of the equations before
+++ solving.
+
+RetractSolvePackage(Q, R): Exports == Implementation where
+ Q: IntegralDomain
+ R: Join(IntegralDomain, RetractableTo Q)
+
+ PQ ==> Polynomial Q
+ FQ ==> Fraction PQ
+ SY ==> Symbol
+ P ==> Polynomial R
+ F ==> Fraction P
+ EQ ==> Equation
+ SSP ==> SystemSolvePackage
+
+ Exports ==> with
+ solveRetract: (List P, List SY) -> List List EQ F
+ ++ solveRetract(lp,lv) finds the solutions of the list lp of
+ ++ rational functions with respect to the list of symbols lv.
+ ++ The function tries to retract all the coefficients of the equations
+ ++ to Q before solving if possible.
+
+ Implementation ==> add
+ LEQQ2F : List EQ FQ -> List EQ F
+ FQ2F : FQ -> F
+ PQ2P : PQ -> P
+ QIfCan : List P -> Union(List FQ, "failed")
+ PQIfCan: P -> Union(FQ, "failed")
+
+ PQ2P p == map(#1::R, p)$PolynomialFunctions2(Q, R)
+ FQ2F f == PQ2P numer f / PQ2P denom f
+ LEQQ2F l == [equation(FQ2F lhs eq, FQ2F rhs eq) for eq in l]
+
+ solveRetract(lp, lv) ==
+ (u := QIfCan lp) case "failed" =>
+ solve([p::F for p in lp]$List(F), lv)$SSP(R)
+ [LEQQ2F l for l in solve(u::List(FQ), lv)$SSP(Q)]
+
+ QIfCan l ==
+ ans:List(FQ) := empty()
+ for p in l repeat
+ (u := PQIfCan p) case "failed" => return "failed"
+ ans := concat(u::FQ, ans)
+ ans
+
+ PQIfCan p ==
+ (u := mainVariable p) case "failed" =>
+ (r := retractIfCan(ground p)@Union(Q,"failed")) case Q => r::Q::PQ::FQ
+ "failed"
+ up := univariate(p, s := u::SY)
+ ans:FQ := 0
+ while up ^= 0 repeat
+ (v := PQIfCan leadingCoefficient up) case "failed" => return "failed"
+ ans := ans + monomial(1, s, degree up)$PQ * (v::FQ)
+ up := reductum up
+ ans
+
+@
+\section{package NLINSOL NonLinearSolvePackage}
+<<package NLINSOL NonLinearSolvePackage>>=
+)abbrev package NLINSOL NonLinearSolvePackage
+++ Author: Manuel Bronstein
+++ Date Created: 31 October 1991
+++ Date Last Updated: 26 June 1992
+++ Description:
+++ NonLinearSolvePackage is an interface to \spadtype{SystemSolvePackage}
+++ that attempts to retract the coefficients of the equations before
+++ solving. The solutions are given in the algebraic closure of R whenever
+++ possible.
+
+NonLinearSolvePackage(R:IntegralDomain): Exports == Implementation where
+ Z ==> Integer
+ Q ==> Fraction Z
+ SY ==> Symbol
+ P ==> Polynomial R
+ F ==> Fraction P
+ EQ ==> Equation F
+ SSP ==> SystemSolvePackage
+ SOL ==> RetractSolvePackage
+
+ Exports ==> with
+ solveInField: (List P, List SY) -> List List EQ
+ ++ solveInField(lp,lv) finds the solutions of the list lp of
+ ++ rational functions with respect to the list of symbols lv.
+ solveInField: List P -> List List EQ
+ ++ solveInField(lp) finds the solution of the list lp of rational
+ ++ functions with respect to all the symbols appearing in lp.
+ solve: (List P, List SY) -> List List EQ
+ ++ solve(lp,lv) finds the solutions in the algebraic closure of R
+ ++ of the list lp of
+ ++ rational functions with respect to the list of symbols lv.
+ solve: List P -> List List EQ
+ ++ solve(lp) finds the solution in the algebraic closure of R
+ ++ of the list lp of rational
+ ++ functions with respect to all the symbols appearing in lp.
+
+ Implementation ==> add
+ solveInField l == solveInField(l, "setUnion"/[variables p for p in l])
+
+ if R has AlgebraicallyClosedField then
+ import RationalFunction(R)
+
+ expandSol: List EQ -> List List EQ
+ RIfCan : F -> Union(R, "failed")
+ addRoot : (EQ, List List EQ) -> List List EQ
+ allRoots : List P -> List List EQ
+ evalSol : (List EQ, List EQ) -> List EQ
+
+ solve l == solve(l, "setUnion"/[variables p for p in l])
+ solve(lp, lv) == concat([expandSol sol for sol in solveInField(lp, lv)])
+ addRoot(eq, l) == [concat(eq, sol) for sol in l]
+ evalSol(ls, l) == [equation(lhs eq, eval(rhs eq, l)) for eq in ls]
+
+-- converts [p1(a1),...,pn(an)] to
+-- [[a1=v1,...,an=vn]] where vi ranges over all the zeros of pi
+ allRoots l ==
+ empty? l => [empty()$List(EQ)]
+ z := allRoots rest l
+ s := mainVariable(p := first l)::SY::P::F
+ concat [addRoot(equation(s, a::P::F), z) for a in zerosOf univariate p]
+
+ expandSol l ==
+ lassign := lsubs := empty()$List(EQ)
+ luniv := empty()$List(P)
+ for eq in l repeat
+ if retractIfCan(lhs eq)@Union(SY, "failed") case SY then
+ if RIfCan(rhs eq) case R then lassign := concat(eq, lassign)
+ else lsubs := concat(eq, lsubs)
+ else
+ if ((u := retractIfCan(lhs eq)@Union(P, "failed")) case P) and
+-- one?(# variables(u::P)) and ((r := RIfCan rhs eq) case R) then
+ ((# variables(u::P)) = 1) and ((r := RIfCan rhs eq) case R) then
+ luniv := concat(u::P - r::R::P, luniv)
+ else return [l]
+ empty? luniv => [l]
+ [concat(z, concat(evalSol(lsubs,z), lassign)) for z in allRoots luniv]
+
+ RIfCan f ==
+ ((n := retractIfCan(numer f)@Union(R,"failed")) case R) and
+ ((d := retractIfCan(denom f)@Union(R,"failed")) case R) => n::R / d::R
+ "failed"
+ else
+ solve l == solveInField l
+ solve(lp, lv) == solveInField(lp, lv)
+
+ -- 'else if' is doubtful with this compiler so all 3 conditions are explicit
+ if (not(R is Q)) and (R has RetractableTo Q) then
+ solveInField(lp, lv) == solveRetract(lp, lv)$SOL(Q, R)
+
+ if (not(R is Z)) and (not(R has RetractableTo Q)) and
+ (R has RetractableTo Z) then
+ solveInField(lp, lv) == solveRetract(lp, lv)$SOL(Z, R)
+
+ if (not(R is Z)) and (not(R has RetractableTo Q)) and
+ (not(R has RetractableTo Z)) then
+ solveInField(lp, lv) == solve([p::F for p in lp]$List(F), lv)$SSP(R)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad odeef.spad
+
+<<package RETSOL RetractSolvePackage>>
+<<package NLINSOL NonLinearSolvePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nlode.spad.pamphlet b/src/algebra/nlode.spad.pamphlet
new file mode 100644
index 00000000..2f7f672d
--- /dev/null
+++ b/src/algebra/nlode.spad.pamphlet
@@ -0,0 +1,207 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nlode.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NODE1 NonLinearFirstOrderODESolver}
+<<package NODE1 NonLinearFirstOrderODESolver>>=
+)abbrev package NODE1 NonLinearFirstOrderODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 2 September 1991
+++ Date Last Updated: 14 October 1994
+++ Description: NonLinearFirstOrderODESolver provides a function
+++ for finding closed form first integrals of nonlinear ordinary
+++ differential equations of order 1.
+++ Keywords: differential equation, ODE
+NonLinearFirstOrderODESolver(R, F): Exports == Implementation where
+ R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, CharacteristicZero)
+ F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+ PrimitiveFunctionCategory)
+
+ N ==> NonNegativeInteger
+ Q ==> Fraction Integer
+ UQ ==> Union(Q, "failed")
+ OP ==> BasicOperator
+ SY ==> Symbol
+ K ==> Kernel F
+ U ==> Union(F, "failed")
+ P ==> SparseMultivariatePolynomial(R, K)
+ REC ==> Record(coef:Q, logand:F)
+ SOL ==> Record(particular: F,basis: List F)
+ BER ==> Record(coef1:F, coefn:F, exponent:N)
+
+ Exports ==> with
+ solve: (F, F, OP, SY) -> U
+ ++ solve(M(x,y), N(x,y), y, x) returns \spad{F(x,y)} such that
+ ++ \spad{F(x,y) = c} for a constant \spad{c} is a first integral
+ ++ of the equation \spad{M(x,y) dx + N(x,y) dy = 0}, or
+ ++ "failed" if no first-integral can be found.
+
+ Implementation ==> add
+ import ODEIntegration(R, F)
+ import ElementaryFunctionODESolver(R, F) -- recursive dependency!
+
+ checkBernoulli : (F, F, K) -> Union(BER, "failed")
+ solveBernoulli : (BER, OP, SY, F) -> Union(F, "failed")
+ checkRiccati : (F, F, K) -> Union(List F, "failed")
+ solveRiccati : (List F, OP, SY, F) -> Union(F, "failed")
+ partSolRiccati : (List F, OP, SY, F) -> Union(F, "failed")
+ integratingFactor: (F, F, SY, SY) -> U
+
+ unk := new()$SY
+ kunk:K := kernel unk
+
+ solve(m, n, y, x) ==
+-- first replace the operator y(x) by a new symbol z in m(x,y) and n(x,y)
+ lk:List(K) := [retract(yx := y(x::F))@K]
+ lv:List(F) := [kunk::F]
+ mm := eval(m, lk, lv)
+ nn := eval(n, lk, lv)
+-- put over a common denominator (to balance m and n)
+ d := lcm(denom mm, denom nn)::F
+ mm := d * mm
+ nn := d * nn
+-- look for an integrating factor mu
+ (u := integratingFactor(mm, nn, unk, x)) case F =>
+ mu := u::F
+ mm := mm * mu
+ nn := nn * mu
+ eval(int(mm,x) + int(nn-int(differentiate(mm,unk),x), unk),[kunk],[yx])
+-- check for Bernoulli equation
+ (w := checkBernoulli(m, n, k1 := first lk)) case BER =>
+ solveBernoulli(w::BER, y, x, yx)
+-- check for Riccati equation
+ (v := checkRiccati(m, n, k1)) case List(F) =>
+ solveRiccati(v::List(F), y, x, yx)
+ "failed"
+
+-- look for an integrating factor
+ integratingFactor(m, n, y, x) ==
+-- check first for exactness
+ zero?(d := differentiate(m, y) - differentiate(n, x)) => 1
+-- look for an integrating factor involving x only
+ not member?(y, variables(f := d / n)) => expint(f, x)
+-- look for an integrating factor involving y only
+ not member?(x, variables(f := - d / m)) => expint(f, y)
+-- room for more techniques later on (e.g. Prelle-Singer etc...)
+ "failed"
+
+-- check whether the equation is of the form
+-- dy/dx + p(x)y + q(x)y^N = 0 with N > 1
+-- i.e. whether m/n is of the form p(x) y + q(x) y^N
+-- returns [p, q, N] if the equation is in that form
+ checkBernoulli(m, n, ky) ==
+ r := denom(f := m / n)::F
+ (not freeOf?(r, y := ky::F))
+ or (d := degree(p := univariate(numer f, ky))) < 2
+ or degree(pp := reductum p) ^= 1 or reductum(pp) ^= 0
+ or (not freeOf?(a := (leadingCoefficient(pp)::F), y))
+ or (not freeOf?(b := (leadingCoefficient(p)::F), y)) => "failed"
+ [a / r, b / r, d]
+
+-- solves the equation dy/dx + rec.coef1 y + rec.coefn y^rec.exponent = 0
+-- the change of variable v = y^{1-n} transforms the above equation to
+-- dv/dx + (1 - n) p v + (1 - n) q = 0
+ solveBernoulli(rec, y, x, yx) ==
+ n1 := 1 - rec.exponent::Integer
+ deq := differentiate(yx, x) + n1 * rec.coef1 * yx + n1 * rec.coefn
+ sol := solve(deq, y, x)::SOL -- can always solve for order 1
+-- if v = vp + c v0 is the general solution of the linear equation, then
+-- the general first integral for the Bernoulli equation is
+-- (y^{1-n} - vp) / v0 = c for any constant c
+ (yx**n1 - sol.particular) / first(sol.basis)
+
+-- check whether the equation is of the form
+-- dy/dx + q0(x) + q1(x)y + q2(x)y^2 = 0
+-- i.e. whether m/n is a quadratic polynomial in y.
+-- returns the list [q0, q1, q2] if the equation is in that form
+ checkRiccati(m, n, ky) ==
+ q := denom(f := m / n)::F
+ (not freeOf?(q, y := ky::F)) or degree(p := univariate(numer f, ky)) > 2
+ or (not freeOf?(a0 := (coefficient(p, 0)::F), y))
+ or (not freeOf?(a1 := (coefficient(p, 1)::F), y))
+ or (not freeOf?(a2 := (coefficient(p, 2)::F), y)) => "failed"
+ [a0 / q, a1 / q, a2 / q]
+
+-- solves the equation dy/dx + l.1 + l.2 y + l.3 y^2 = 0
+ solveRiccati(l, y, x, yx) ==
+-- get first a particular solution
+ (u := partSolRiccati(l, y, x, yx)) case "failed" => "failed"
+-- once a particular solution yp is known, the general solution is of the
+-- form y = yp + 1/v where v satisfies the linear 1st order equation
+-- v' - (l.2 + 2 l.3 yp) v = l.3
+ deq := differentiate(yx, x) - (l.2 + 2 * l.3 * u::F) * yx - l.3
+ gsol := solve(deq, y, x)::SOL -- can always solve for order 1
+-- if v = vp + c v0 is the general solution of the above equation, then
+-- the general first integral for the Riccati equation is
+-- (1/(y - yp) - vp) / v0 = c for any constant c
+ (inv(yx - u::F) - gsol.particular) / first(gsol.basis)
+
+-- looks for a particular solution of dy/dx + l.1 + l.2 y + l.3 y^2 = 0
+ partSolRiccati(l, y, x, yx) ==
+-- we first do the change of variable y = z / l.3, which transforms
+-- the equation into dz/dx + l.1 l.3 + (l.2 - l.3'/l.3) z + z^2 = 0
+ q0 := l.1 * (l3 := l.3)
+ q1 := l.2 - differentiate(l3, x) / l3
+-- the equation dz/dx + q0 + q1 z + z^2 = 0 is transformed by the change
+-- of variable z = w'/w into the linear equation w'' + q1 w' + q0 w = 0
+ lineq := differentiate(yx, x, 2) + q1 * differentiate(yx, x) + q0 * yx
+-- should be made faster by requesting a particular nonzero solution only
+ (not((gsol := solve(lineq, y, x)) case SOL))
+ or empty?(bas := (gsol::SOL).basis) => "failed"
+ differentiate(first bas, x) / (l3 * first bas)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad odeef.spad
+
+<<package NODE1 NonLinearFirstOrderODESolver>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/noptip.as.pamphlet b/src/algebra/noptip.as.pamphlet
new file mode 100644
index 00000000..150087bb
--- /dev/null
+++ b/src/algebra/noptip.as.pamphlet
@@ -0,0 +1,241 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra noptip.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{NagOptimisationInterfacePackage}
+<<NagOptimisationInterfacePackage>>=
++++ Author: M.G. Richardson
++++ Date Created: 1996 Feb. 01
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This package provides Axiom-like interfaces to some of the NAG
++++ optimisation routines in the NAGlink.
+
+NagOptimisationInterfacePackage: with {
+
+ nagMin : (EDF,LEQPDF) -> LEQPDF ;
+
+} == add {
+
+ import from MINT ;
+ import from BOOL ;
+ import from LLDF ;
+ import from VDF ;
+ import from PDF ;
+ import from LEQEDF ;
+ import from MDF ;
+ import from EDF ;
+ import from FL ;
+ import from SMBL ;
+ import from A49 ;
+ import from A55 ;
+ import from U49 ;
+ import from U55 ;
+ import from NagOptimisationPackage ;
+ import from OF ;
+ import from LOF ;
+ import from LLOF ;
+ import from ListFunctions2(INT,OF) ;
+ import from NagResultChecks ;
+ import from EF2DFFL ;
+
+ local (..)(a:INT,b:INT):Generator INT == {
+ generate {
+ t := a ;
+ while (t <= b) repeat {
+ yield t ;
+ t := t + 1 ;
+ }
+ }
+ }
+
+ -- to avoid unrecognised versions of U49 type for e04dgf:
+ e04dgflocal := e04dgf$NagOptimisationPackage pretend
+ ((INT,DF,DF,INT,DF,BOOL, DF,DF,INT,INT,INT,INT,MDF,INT, U49)->RSLT) ;
+
+ nagMin(objective:EDF,startList:LEQPDF) : LEQPDF == {
+
+ -- Note that, as objective is an EDF, subst and eval
+ -- for this have as 2nd parameters LEQEDFs.
+
+ local nv : INT ;
+ local substList : LEQEDF ;
+ local indxOb : EF ;
+ local startVals : LDF ;
+ local startListXDF : LEQEDF ;
+ local startFVal : DF ;
+ local e04dgfResult : RSLT ;
+ local location : LDF ;
+
+
+ nv := ((# startList)@NNI pretend INT) ; -- @ avoids SI
+
+ substList := [lhs(startList.i)::EDF
+ = (script("x"::SMBL,[[i::OF]]@LLOF))::EDF
+ for i in 1..nv] ;
+ -- [x=x[1], y=x[2], etc.]
+
+ indxOb := map(convert$Float,subst(objective,substList)) ;
+ -- objective function as an EF with x[i]'s, as required by A49
+
+ startVals := [retract(rhs(startList.i))@DF for i in 1..nv] ;
+
+ startListXDF := [lhs(startList.i)::EDF = rhs(startList.i)::EDF
+ for i in 1..nv] ;
+ startFVal := ground(eval(objective,startListXDF))::DF ;
+ startFVal := startFVal * 1.015625 ;
+
+-- Note that there appears to be a problem running the standard NAG
+-- example on Suns with an exact value for startFVal. It looks as if
+-- this causes too large a stepsize, perhaps due to exception code
+-- being obeyed in the Fortran. Until this is fixed, using the above
+-- slightly perturbed value (adding 1/64) seems to avoid the problem.
+
+ e04dgfResult := e04dgflocal(
+ nv, -- No.vbls.
+ --
+ -- "optional" params next:
+ --
+ startFVal, -- es(timated obj've fn val)
+ -1.0, -- fun:
+ -1, -- it:
+ -1.0, -- lin:
+ false, -- list:
+ -1.0, -- ma:
+ -2.0, -- opt: made < fun for safety
+ 0, -- pr:
+ -1, -- sta:
+ -1, -- sto:
+ -1, -- ve:
+ --
+ matrix [startVals], -- initial position estimate
+ -1, -- IFAIL
+ [retract(indxOb)@A49]@U49 -- objective function
+ ) ;
+
+ location := entries(row(checkMxDF(e04dgfResult,"x","E04DGF"),1)) ;
+
+ [ ((retract(lhs(startList.i))@SMBL)::PDF
+ = (location.i)::PDF)@EQPDF for i in 1..nv ]
+
+ }
+
+}
+
+#if NeverAssertThis
+
+-- Note that the conversions of results from DoubleFloat to Float
+-- will become unnecessary if outputGeneral is extended to apply to
+-- DoubleFloat quantities.
+
+)lib nrc
+
+outputGeneral 5
+
+f := %e^x*(4*x^2 + 2*y^2 + 4*x*y + 2*y + 1);
+start := [x=-1.0, y=1.0];
+nagMin(f,start) :: List Equation Polynomial Float
+
+-- [x= 0.5,y= - 1.0]
+
+outputGeneral()
+
+output "End of tests"
+
+#endif
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- To test:
+-- sed '1,/^#if NeverAssertThis/d;/#endif/d' < noptip.as > noptip.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r noptip.input
+
+#unassert saturn
+
+#include "axiom.as"
+
+INT ==> Integer ;
+NNI ==> NonNegativeInteger ;
+MINT ==> Matrix INT ;
+DF ==> DoubleFloat ;
+EDF ==> Expression DF ;
+EQEDF ==> Equation EDF ;
+LEQEDF ==> List EQEDF ;
+LDF ==> List DF ;
+LLDF ==> List LDF ;
+VDF ==> Vector DF ;
+MDF ==> Matrix DF ;
+PDF ==> Polynomial DF ;
+EQPDF ==> Equation PDF ;
+LEQPDF ==> List EQPDF ;
+FL ==> Float ;
+EF ==> Expression FL ;
+BOOL ==> Boolean ;
+A49 ==> Asp49("OBJFUN") ;
+A55 ==> Asp55("CONFUN") ;
+U49 ==> Union(fn: FileName, fp: A49) ;
+U55 ==> Union(fn: FileName, fp: A55) ;
+SMBL ==> Symbol ;
+RSLT ==> Result ;
+OF ==> OutputForm ;
+LOF ==> List OF ;
+LLOF ==> List LOF ;
+EF2DFFL ==> ExpressionFunctions2(DF,FL) ;
+
+<<NagOptimisationInterfacePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/npcoef.spad.pamphlet b/src/algebra/npcoef.spad.pamphlet
new file mode 100644
index 00000000..ef842223
--- /dev/null
+++ b/src/algebra/npcoef.spad.pamphlet
@@ -0,0 +1,212 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra npcoef.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NPCOEF NPCoef}
+<<package NPCOEF NPCoef>>=
+)abbrev package NPCOEF NPCoef
+++ Author : P.Gianni, revised May 1990
+++ Description:
+++ Package for the determination of the coefficients in the lifting
+++ process. Used by \spadtype{MultivariateLifting}.
+++ This package will work for every euclidean domain R which has property
+++ F, i.e. there exists a factor operation in \spad{R[x]}.
+NPCoef(BP,E,OV,R,P) : C == T where
+
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ R : EuclideanDomain -- with property "F"
+ BP : UnivariatePolynomialCategory R
+ P : PolynomialCategory(R,E,OV)
+
+ Z ==> Integer
+ NNI ==> NonNegativeInteger
+ USP ==> SparseUnivariatePolynomial(P)
+ Term ==> Record(expt:NNI,pcoef:P)
+ Detc ==> Record(valexp:NNI,valcoef:P,posit:NNI)
+ VTerm ==> List(Term)
+ DetCoef ==> Record(deter:List(USP),dterm:List(VTerm),
+ nfacts:List(BP),nlead:List(P))
+ TermC ==> Record(coefu:P,detfacts:List(VTerm))
+ TCoef ==> List(TermC)
+
+ C == with
+ npcoef : (USP,List(BP),List(P)) -> DetCoef
+ ++ npcoef \undocumented
+ listexp : BP -> List(NNI)
+ ++ listexp \undocumented
+ T == add
+
+ ---- Local Functions ----
+ check : (TermC,Vector P) -> Union(Detc,"failed")
+ buildvect : (List(VTerm),NNI) -> Vector(List(VTerm))
+ buildtable : (Vector(P),List(List NNI),List P) -> TCoef
+ modify : (TCoef,Detc) -> TCoef
+ constructp : VTerm -> USP
+
+ npcoef(u:USP,factlist:List(BP),leadlist:List(P)) :DetCoef ==
+ detcoef:List(VTerm):=empty();detufact:List(USP):=empty()
+ lexp:List(List(NNI)):=[listexp(v) for v in factlist]
+ ulist :Vector(P):=vector [coefficient(u,i) for i in 0..degree u]
+ tablecoef:=buildtable(ulist,lexp,leadlist)
+ detcoef:=[[[ep.first,lcu]$Term] for ep in lexp for lcu in leadlist]
+ ldtcf:=detcoef
+ lexp:=[ep.rest for ep in lexp]
+ ndet:NNI:=#factlist
+ changed:Boolean:=true
+ ltochange:List(NNI):=empty()
+ ltodel:List(NNI):=empty()
+ while changed and ndet^=1 repeat
+ changed :=false
+ dt:=#tablecoef
+ for i in 1..dt while ^changed repeat
+ (cf:=check(tablecoef.i,ulist)) case "failed" => "next i"
+ ltochange:=cons(i,ltochange)
+ celtf:Detc:=cf::Detc
+ tablecoef:=modify(tablecoef,celtf)
+ vpos:=celtf.posit
+ vexp:=celtf.valexp
+ nterm:=[vexp,celtf.valcoef]$Term
+ detcoef.vpos:=cons(nterm,detcoef.vpos)
+ lexp.vpos:=delete(lexp.vpos,position(vexp,lexp.vpos))
+ if lexp.vpos=[] then
+ ltodel:=cons(vpos,ltodel)
+ ndet:=(ndet-1):NNI
+ detufact:=cons(constructp(detcoef.vpos),detufact)
+ changed:=true
+ for i in ltochange repeat tablecoef:=delete(tablecoef,i)
+ ltochange:=[]
+ if ndet=1 then
+ uu:=u exquo */[pol for pol in detufact]
+ if uu case "failed" then return
+ [empty(),ldtcf,factlist,leadlist]$DetCoef
+ else detufact:=cons(uu::USP,detufact)
+ else
+ ltodel:=sort(#1>#2,ltodel)
+ for i in ltodel repeat
+ detcoef:=delete(detcoef,i)
+ factlist:=delete(factlist,i)
+ leadlist:=delete(leadlist,i)
+ [detufact,detcoef,factlist,leadlist]$DetCoef
+
+
+ check(tterm:TermC,ulist:Vector(P)) : Union(Detc,"failed") ==
+ cfu:P:=1$P;doit:NNI:=0;poselt:NNI:=0;pp:Union(P,"failed")
+ termlist:List(VTerm):=tterm.detfacts
+ vterm:VTerm:=empty()
+ #termlist=1 =>
+ vterm:=termlist.first
+ for elterm in vterm while doit<2 repeat
+ (cu1:=elterm.pcoef)^=0 => cfu:=cu1*cfu
+ doit:=doit+1
+ poselt:=position(elterm,vterm):NNI
+ doit=2 or (pp:=tterm.coefu exquo cfu) case "failed" => "failed"
+ [vterm.poselt.expt,pp::P,poselt]$Detc
+ "failed"
+
+ buildvect(lvterm:List(VTerm),n:NNI) : Vector(List(VTerm)) ==
+ vtable:Vector(List(VTerm)):=new(n,empty())
+ (#lvterm)=1 =>
+ for term in lvterm.first repeat vtable.(term.expt+1):=[[term]]
+ vtable
+
+ vtable:=buildvect(lvterm.rest,n)
+ ntable:Vector(List(VTerm)):=new(n,empty())
+ for term in lvterm.first repeat
+ nexp:=term.expt
+ for i in 1..n while (nexp+i)<(n+1) repeat
+ ntable.(nexp+i):=append(
+ [cons(term,lvterm) for lvterm in vtable.i],
+ ntable.(nexp+i))
+ ntable
+
+ buildtable(vu:Vector(P),lvect:List(List(NNI)),leadlist:List(P)):TCoef==
+ nfact:NNI:=#leadlist
+ table:TCoef:=empty()
+ degu:=(#vu-1)::NNI
+ prelim:List(VTerm):=[[[e,0$P]$Term for e in lv] for lv in lvect]
+ for i in 1..nfact repeat prelim.i.first.pcoef:=leadlist.i
+ partialv:Vector(List(VTerm)):=new(nfact,empty())
+ partialv:=buildvect(prelim,degu)
+ for i in 1..degu repeat
+ empty? partialv.i => "next i"
+ table:=cons([vu.i,partialv.i]$TermC, table)
+ table
+
+ modify(tablecoef:TCoef,cfter:Detc) : TCoef ==
+ cfexp:=cfter.valexp;cfcoef:=cfter.valcoef;cfpos:=cfter.posit
+ lterase:List(NNI):=empty()
+ for cterm in tablecoef | ^empty?(ctdet:=cterm.detfacts) repeat
+ (+/[term.expt for term in ctdet.first])<cfexp => "next term"
+ for celt in ctdet repeat
+ if celt.cfpos.expt=cfexp then
+ celt.cfpos.pcoef:=cfcoef
+ if (and/[cc.pcoef ^=0 for cc in celt]) then
+ k:=position(celt,ctdet):NNI
+ lterase:=cons(k,lterase)
+ cterm.coefu:=(cterm.coefu - */[cc.pcoef for cc in celt])
+ if not empty? lterase then
+ lterase:=sort(#1>#2,lterase)
+ for i in lterase repeat ctdet:=delete(ctdet,i)
+ cterm.detfacts:=ctdet
+ lterase:=empty()
+ tablecoef
+
+ listexp(up:BP) :List(NNI) ==
+ degree up=0 => [0]
+ [degree up,:listexp(reductum up)]
+
+ constructp(lterm:VTerm):USP ==
+ +/[monomial(term.pcoef,term.expt) for term in lterm]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NPCOEF NPCoef>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nqip.as.pamphlet b/src/algebra/nqip.as.pamphlet
new file mode 100644
index 00000000..e3e8d968
--- /dev/null
+++ b/src/algebra/nqip.as.pamphlet
@@ -0,0 +1,231 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nqip.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{NagQuadratureInterfacePackage}
+<<NagQuadratureInterfacePackage>>=
++++ Author: M.G. Richardson
++++ Date Created: 1995 Dec. 07
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This package provides Axiom-like interfaces to some of the NAG
++++ quadrature (numerical integration) routines in the NAGlink.
+
+NagQuadratureInterfacePackage: with {
+
+ nagPolygonIntegrate : (LDF, LDF) ->
+ RCD(integral : DF, errorEstimate : DF) ;
+
+ ++ nagPolygonIntegrate(xlist,ylist) evaluates the definite integral
+#if saturn
+ ++ $\int_{x_{1}}^{x_{n}}y(x) \, dx$
+#else
+ ++ integrate(y(x), x=x[1]..x[n])
+#endif
+ ++ where the numerical value of the function \spad{y} is specified at
+ ++ the \spad{n} distinct points
+#if saturn
+ ++ $x_{1}, x_{2}, \ldots , x_{n}$.
+#else
+ ++ x[1], x[2] ... x[n].
+#endif
+ ++ The \spad{x} and \spad{y} values are specified in the lists
+ ++ \spad{xlist} and \spad{ylist}, respectively; the \spad{xlist}
+ ++ values must form a strictly monotonic sequence of four or more
+ ++ points.
+ ++ The calculation is performed by the NAG routine D01GAF.
+ ++
+ ++ An estimate of the numerical error in the calculation is also
+ ++ returned; however, by choosing unrepresentative data points to
+ ++ approximate the function it is possible to achieve an arbitrarily
+ ++ large difference between the true integral and the value
+ ++ calculated.
+ ++ For more detailed information, please consult the NAG
+ ++ manual via the Browser page for the operation d01gaf.
+
+ nagPolygonIntegrate : MDF -> RCD(integral : DF, errorEstimate : DF) ;
+
+
+} == add {
+
+ import from NagIntegrationPackage ;
+ import from NagResultChecks ;
+ import from AnyFunctions1 DF ;
+ import from STRG ;
+ import from List STRG ;
+ import from Symbol ;
+ import from LLDF ;
+ import from VDF ;
+ import from MDF ;
+ import from ErrorFunctions ;
+
+ local ipIfail : INT := -1 ;
+ local d01gafError : DF := 0 ;
+
+ nagPolygonIntegrate(xlist : LDF, ylist : LDF)
+ : RCD(integral : DF, errorEstimate : DF) == {
+
+ local lx, ly : INT ;
+ local d01gafResult : RSLT ;
+
+ lx := (# xlist) pretend INT ;
+ ly := (# ylist) pretend INT ;
+ if lx ~= ly
+ then error ["The lists supplied to nagPolygonIntegrate are of ",
+ "different lengths: ",
+ string(lx),
+ " and ",
+ string(ly),
+ "."]
+ else {
+ d01gafResult := d01gaf(matrix [xlist],matrix [ylist],lx,ipIfail) ;
+ [checkResult(d01gafResult,"ans","D01GAF"),
+ retract(d01gafResult."er") @ DF]
+ }
+ }
+
+ nagPolygonIntegrate(coords : MDF)
+ : RCD(integral : DF, errorEstimate : DF) ==
+ if (ncols(coords) pretend INT) ~= 2
+ then error ["Please supply the coordinate matrix in ",
+ "nagPolygonIntegrate with each row consisting of ",
+ "a single x-y pair."]
+ else nagPolygonIntegrate(members column(coords,1),
+ members column(coords,2)) ;
+
+}
+
+#if NeverAssertThis
+
+-- Note that the conversions of results from DoubleFloat to Float
+-- will become unnecessary if outputGeneral is extended to apply to
+-- DoubleFloat quantities.
+
+)lib nrc
+)lib nqip
+
+outputGeneral 5
+
+xvals := [0.00,0.04,0.08,0.12,0.22,0.26,0.30,0.38,0.39,0.42,0.45,
+ 0.46,0.60,0.68,0.72,0.73,0.83,0.85,0.88,0.90,1.00];
+
+yvals := [4.0000,3.9936,3.9746,3.9432,3.8135,3.7467,3.6697,3.4943,
+ 3.4719,3.4002,3.3264,3.3017,2.9412,2.7352,2.6344,
+ 2.6094,2.3684,2.3222,2.2543,2.2099,2.0000];
+
+result := nagPolygonIntegrate(xvals,yvals);
+result.integral :: Float
+
+-- 3.1414
+
+result.errorEstimate :: Float
+
+-- - 0.000025627
+
+coords := transpose matrix [xvals, yvals];
+result := nagPolygonIntegrate coords;
+result.integral :: Float
+
+-- 3.1414
+
+result.errorEstimate :: Float
+
+-- - 0.000025627
+
+nagPolygonIntegrate([1,2,3],[1,2,3,4])
+
+-- Error signalled from user code:
+-- The lists supplied to nagPolygonIntegrate are of different
+-- lengths: 3 and 4.
+
+nagPolygonIntegrate([[1,2,3],[4,5,6]])
+
+-- Error signalled from user code:
+-- Please supply the coordinate matrix in nagPolygonIntegrate with
+-- each row consisting of single a x-y pair.
+
+outputGeneral()
+
+output "End of tests"
+
+#endif
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- NagQuadratureInterfacePackage
+
+-- To test:
+-- sed -ne '1,/^#if NeverAssertThis/d;/#endif/d;p' < nqip.as > nqip.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r nqip.input
+
+#unassert saturn
+
+#include "axiom.as"
+
+DF ==> DoubleFloat ;
+LDF ==> List DoubleFloat ;
+LLDF ==> List LDF ;
+VDF ==> Vector DoubleFloat ;
+MDF ==> Matrix DoubleFloat ;
+INT ==> Integer ;
+RCD ==> Record ;
+RSLT ==> Result ;
+STRG ==> String ;
+
+<<NagQuadratureInterfacePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nrc.as.pamphlet b/src/algebra/nrc.as.pamphlet
new file mode 100644
index 00000000..d317958c
--- /dev/null
+++ b/src/algebra/nrc.as.pamphlet
@@ -0,0 +1,132 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nrc.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{NagResultChecks}
+<<NagResultChecks>>=
++++ Author: M.G. Richardson
++++ Date Created: 1995 Dec. 06
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
+
+NagResultChecks: with {
+
+ checkResult : (RSLT, STRG, STRG) -> DF ;
+ checkCxResult : (RSLT, STRG, STRG) -> CDF ;
+ checkMxCDF : (RSLT, STRG, STRG) -> MCDF ;
+ checkMxDF : (RSLT, STRG, STRG) -> MDF ;
+
+} == add {
+
+ import from DF ;
+ import from SMBL ;
+ import from INT ;
+ import from AnyFunctions1 INT ;
+ import from AnyFunctions1 DF ;
+ import from AnyFunctions1 CDF ;
+ import from AnyFunctions1 MDF ;
+ import from AnyFunctions1 MCDF ;
+ import from ErrorFunctions ;
+ import from STRG ;
+ import from List STRG ;
+
+ checkResult(returnValue : RSLT, returnKey : STRG, routine : STRG) : DF ==
+ if not zero?(retract(returnValue."ifail") @ INT)
+ then nagError(routine, retract(returnValue."ifail") @ INT)
+ else retract(returnValue.(returnKey::SMBL)) @ DF ;
+
+ checkCxResult(returnValue : RSLT, returnKey : STRG, routine : STRG) : CDF ==
+ if not zero?(retract(returnValue."ifail") @ INT)
+ then nagError(routine, retract(returnValue."ifail") @ INT)
+ else retract(returnValue.(returnKey::SMBL)) @ CDF ;
+
+ checkMxDF(returnValue : RSLT, returnKey : STRG, routine : STRG) : MDF ==
+ if not zero?(retract(returnValue."ifail") @ INT)
+ then nagError(routine, retract(returnValue."ifail") @ INT)
+ else retract(returnValue.(returnKey::SMBL)) @ MDF ;
+
+ checkMxCDF(returnValue : RSLT, returnKey : STRG, routine : STRG) : MCDF ==
+ if not zero?(retract(returnValue."ifail") @ INT)
+ then nagError(routine, retract(returnValue."ifail") @ INT)
+ else retract(returnValue.(returnKey::SMBL)) @ MCDF ;
+
+ nagError(routine : STRG, opIfail : INT) : Exit ==
+ error ["An error was detected when calling the NAG Library routine ",
+ routine,
+ ". The error number (IFAIL value) is ",
+ string(opIfail),
+ ", please consult the NAG manual via the Browser for",
+ " diagnostic information."] ;
+}
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- N.B. ndftip.as, nqip.as and nsfip.as inline from nrc
+-- and must be recompiled if this is.
+
+#include "axiom.as"
+
+DF ==> DoubleFloat ;
+CDF ==> Complex DoubleFloat ;
+MDF ==> Matrix DoubleFloat ;
+MCDF ==> Matrix Complex DoubleFloat ;
+INT ==> Integer ;
+RSLT ==> Result ;
+SMBL ==> Symbol ;
+STRG ==> String ;
+
+<<NagResultChecks>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nregset.spad.pamphlet b/src/algebra/nregset.spad.pamphlet
new file mode 100644
index 00000000..a1ad85fe
--- /dev/null
+++ b/src/algebra/nregset.spad.pamphlet
@@ -0,0 +1,288 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nregset.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category NTSCAT NormalizedTriangularSetCategory}
+<<category NTSCAT NormalizedTriangularSetCategory>>=
+)abbrev category NTSCAT NormalizedTriangularSetCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 10/07/1998
+++ Date Last Updated: 12/12/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See: essai Graphisme
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ Description:
+++ The category of normalized triangular sets. A triangular
+++ set \spad{ts} is said normalized if for every algebraic
+++ variable \spad{v} of \spad{ts} the polynomial \spad{select(ts,v)}
+++ is normalized w.r.t. every polynomial in \spad{collectUnder(ts,v)}.
+++ A polynomial \spad{p} is said normalized w.r.t. a non-constant
+++ polynomial \spad{q} if \spad{p} is constant or \spad{degree(p,mdeg(q)) = 0}
+++ and \spad{init(p)} is normalized w.r.t. \spad{q}. One of the important
+++ features of normalized triangular sets is that they are regular sets.\newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+++ [2] P. AUBRY, D. LAZARD and M. MORENO MAZA "On the Theories
+++ of Triangular Sets" Journal of Symbol. Comp. (to appear)
+++ [3] M. MORENO MAZA and R. RIOBOO "Computations of gcd over
+++ algebraic towers of simple extensions" In proceedings of AAECC11
+++ Paris, 1995.
+++ [4] M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+
+
+NormalizedTriangularSetCategory(R:GcdDomain,E:OrderedAbelianMonoidSup,_
+ V:OrderedSet,P:RecursivePolynomialCategory(R,E,V)):
+ Category == RegularTriangularSetCategory(R,E,V,P)
+
+@
+\section{package NORMPK NormalizationPackage}
+<<package NORMPK NormalizationPackage>>=
+)abbrev package NORMPK NormalizationPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 09/23/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A package for computing normalized assocites of univariate polynomials
+++ with coefficients in a tower of simple extensions of a field.\newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+++ [2] M. MORENO MAZA and R. RIOBOO "Computations of gcd over
+++ algebraic towers of simple extensions" In proceedings of AAECC11
+++ Paris, 1995.
+++ [3] M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+++ Version: 1.
+
+NormalizationPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : RegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ K ==> Fraction R
+ LP ==> List P
+ PWT ==> Record(val : P, tower : TS)
+
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Split ==> List TS
+ --KeyGcd ==> Record(arg1: P, arg2: P, arg3: TS, arg4: B)
+ --EntryGcd ==> List PWT
+ --HGcd ==> TabulatedComputationPackage(KeyGcd, EntryGcd)
+ --KeyInvSet ==> Record(arg1: P, arg3: TS)
+ --EntryInvSet ==> List TS
+ --HInvSet ==> TabulatedComputationPackage(KeyInvSet, EntryInvSet)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ regsetgcdpack ==> SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,TS)
+
+ Exports == with
+
+ recip: (P, TS) -> Record(num:P,den:P)
+ ++ \axiom{recip(p,ts)} returns the inverse of \axiom{p} w.r.t \spad{ts}
+ ++ assuming that \axiom{p} is invertible w.r.t \spad{ts}.
+ normalizedAssociate: (P, TS) -> P
+ ++ \axiom{normalizedAssociate(p,ts)} returns a normalized polynomial
+ ++ \axiom{n} w.r.t. \spad{ts} such that \axiom{n} and \axiom{p} are
+ ++ associates w.r.t \spad{ts} and assuming that \axiom{p} is invertible
+ ++ w.r.t \spad{ts}.
+ normalize: (P, TS) -> List PWT
+ ++ \axiom{normalize(p,ts)} normalizes \axiom{p} w.r.t \spad{ts}.
+ outputArgs: (S, S, P, TS) -> Void
+ ++ \axiom{outputArgs(s1,s2,p,ts)}
+ ++ is an internal subroutine, exported only for developement.
+ normInvertible?: (P, TS) -> List BWT
+ ++ \axiom{normInvertible?(p,ts)}
+ ++ is an internal subroutine, exported only for developement.
+
+ Implementation == add
+
+ if TS has SquareFreeRegularTriangularSetCategory(R,E,V,P)
+ then
+
+ normInvertible?(p:P, ts:TS): List BWT ==
+ stoseInvertible?_sqfreg(p,ts)$regsetgcdpack
+
+ else
+
+ normInvertible?(p:P, ts:TS): List BWT ==
+ stoseInvertible?_reg(p,ts)$regsetgcdpack
+
+ if (R has RetractableTo(Integer)) and (V has ConvertibleTo(Symbol))
+ then
+
+ outputArgs(s1:S, s2: S, p:P,ts:TS): Void ==
+ if not empty? s1 then output(s1, p::OutputForm)$OutputPackage
+ if not empty? s1 then output(s1,(convert(p)@String)::OutputForm)$OutputPackage
+ output(" ")$OutputPackage
+ if not empty? s2 then output(s2, ts::OutputForm)$OutputPackage
+ empty? s2 => void()
+ output(s2,("[")::OutputForm)$OutputPackage
+ lp: List P := members(ts)
+ for q in lp repeat
+ output((convert(q)@String)::OutputForm)$OutputPackage
+ output("]")$OutputPackage
+ output(" ")$OutputPackage
+
+ else
+
+ outputArgs(s1:S, s2: S, p:P,ts:TS): Void ==
+ if not empty? s1 then output(s1, p::OutputForm)$OutputPackage
+ output(" ")$OutputPackage
+ if not empty? s2 then output(s2, ts::OutputForm)$OutputPackage
+ output(" ")$OutputPackage
+
+ recip(p:P,ts:TS): Record(num:P, den:P) ==
+ -- ASSUME p is invertible w.r.t. ts
+ -- ASSUME mvar(p) is algebraic w.r.t. ts
+ v := mvar(p)
+ ts_v := select(ts,v)::P
+ if mdeg(p) < mdeg(ts_v)
+ then
+ hesrg: Record (gcd : P, coef2 : P) := halfExtendedSubResultantGcd2(ts_v,p)$P
+ d: P := hesrg.gcd; n: P := hesrg.coef2
+ else
+ hesrg: Record (gcd : P, coef1 : P) := halfExtendedSubResultantGcd1(p,ts_v)$P
+ d: P := hesrg.gcd; n: P := hesrg.coef1
+ g := gcd(n,d)
+ (n, d) := ((n exquo g)::P, (d exquo g)::P)
+ remn, remd: Record(rnum:R,polnum:P,den:R)
+ remn := remainder(n,ts); remd := remainder(d,ts)
+ cn := remn.rnum; pn := remn.polnum; dn := remn.den
+ cd := remd.rnum; pd := remd.polnum; dp := remd.den
+ k: K := (cn / cd) * (dp / dn)
+ pn := removeZero(pn,ts)
+ pd := removeZero(pd,ts)
+ [numer(k) * pn, denom(k) * pd]$Record(num:P, den:P)
+
+ normalizedAssociate(p:P,ts:TS): P ==
+ -- ASSUME p is invertible or zero w.r.t. ts
+ empty? ts => p
+ zero?(p) => p
+ ground?(p) => 1
+ zero? initiallyReduce(init(p),ts) =>
+ error "in normalizedAssociate$NORMPK: bad #1"
+ vp := mvar(p)
+ ip: P := p
+ mp: P := 1
+ tp: P := 0
+ while not ground?(ip) repeat
+ v := mvar(ip)
+ if algebraic?(v,ts)
+ then
+ if v = vp
+ then
+ ts_v := select(ts,v)::P
+ ip := lastSubResultant(ip,ts_v)$P
+ ip := remainder(ip,ts).polnum
+ -- ip := primitivePart stronglyReduce(ip,ts)
+ ip := primitivePart initiallyReduce(ip,ts)
+ else
+ qr := recip(ip,ts)
+ ip := qr.den
+ tp := qr.num * tp
+ zero? ip =>
+ outputArgs("p = ", " ts = ",p,ts)
+ error "in normalizedAssociate$NORMPK: should never happen !"
+ else
+ tp := tail(ip) * mp + tp
+ mp := mainMonomial(ip) * mp
+ ip := init(ip)
+ r := ip * mp + tp
+ r := remainder(r,ts).polnum
+ -- primitivePart stronglyReduce(r,ts)
+ primitivePart initiallyReduce(r,ts)
+
+ normalize(p: P, ts: TS): List PWT ==
+ zero? p => [[p,ts]$PWT]
+ ground? p => [[1,ts]$PWT]
+ zero? initiallyReduce(init(p),ts) =>
+ error "in normalize$NORMPK: init(#1) reduces to 0 w.r.t. #2"
+ --output("Entering normalize")$OutputPackage
+ --outputArgs("p = ", " ts = ",p,ts)
+ --output("Calling normInvertible?")$OutputPackage
+ lbwt: List BWT := normInvertible?(p,ts)
+ --output("Result is: ")$OutputPackage
+ --output(lbwt::OutputForm)$OutputPackage
+ lpwt: List PWT := []
+ for bwt in lbwt repeat
+ us := bwt.tower
+ q := remainder(p,us).polnum
+ q := removeZero(q,us)
+ bwt.val =>
+ --output("Calling normalizedAssociate")$OutputPackage
+ --outputArgs("q = ", " us = ",q,us)
+ lpwt := cons([normalizedAssociate(q,us)@P,us]$PWT, lpwt)
+ --output("Leaving normalizedAssociate")$OutputPackage
+ zero? q => lpwt := cons([0$P,us]$PWT, lpwt)
+ lpwt := concat(normalize(q,us)@(List PWT),lpwt)
+ lpwt
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category NTSCAT NormalizedTriangularSetCategory>>
+<<package NORMPK NormalizationPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nsfip.as.pamphlet b/src/algebra/nsfip.as.pamphlet
new file mode 100644
index 00000000..d6bbba93
--- /dev/null
+++ b/src/algebra/nsfip.as.pamphlet
@@ -0,0 +1,1223 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nsfip.as}
+\author{Michael Richardson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{NagSpecialFunctionsInterfacePackage}
+<<NagSpecialFunctionsInterfacePackage>>=
++++ Author: M.G. Richardson
++++ Date Created: 1995 Nov. 27
++++ Date Last Updated:
++++ Basic Functions:
++++ Related Constructors:
++++ Also See:
++++ AMS Classifications:
++++ Keywords:
++++ References:
++++ Description:
++++ This package provides Axiom-like interfaces to those of the NAG
++++ special functions in the NAGlink for which no equivalent
++++ functionality is transparently present in Axiom.
+
+NagSpecialFunctionsInterfacePackage: with {
+
+ nagExpInt : DF -> DF ;
+
+ ++ nagExpInt calculates an approximation to the exponential integral,
+ ++ \spad{E1}, defined by
+#if saturn
+ ++ \[E_{1}(x) = \int_{x}^{\infty }\frac{e^{-u}}{u}\,du\]
+#else
+ ++ \spad{E1(x) = integrate(1/u*%e^u, u=x..%infinity)}
+#endif
+ ++ using the NAG routine S13AAF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s13aaf.
+
+ nagSinInt : DF -> DF ;
+
+ ++ nagSinInt calculates an approximation to the sine integral,
+ ++ \spad{Si}, defined by
+#if saturn
+ ++ \[{\rm Si} (x) = \int_{0}^{x}\frac{\sin u}{u}\,du\]
+#else
+ ++ \spad{Si(x) = integrate(1/u*sin(u), u=0..x)}
+#endif
+ ++ using the NAG routine S13ADF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s13adf.
+
+ nagCosInt : DF -> DF ;
+
+ ++ nagCosInt calculates an approximation to the cosine integral,
+ ++ \spad{Ci}, defined by
+#if saturn
+ ++ \[{\rm Ci} (x) =
+ ++ \gamma + \ln x+ \int_{0}^{x}\frac{\cos u- 1}{u}\,du\]
+#else
+ ++ \spad{Ci(x) = gamma + log x + integrate(1/u*cos(u), u=0..x)}
+ ++ where \spad{gamma} is Euler's constant,
+#endif
+ ++ using the NAG routine S13ACF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s13acf.
+
+ nagIncompleteGammaP : (DF, DF) -> DF ; -- to machine precision
+
+ ++ nagIncompleteGammaP evaluates the incomplete gamma function
+ ++ \spad{P}, defined by
+#if saturn
+ ++ \[P(a,x) & = & \frac{1}{\Gamma(a)}\int_{0}^{x}t^{a-1}e^{-t}\,dt\]
+#else
+ ++ \spad{P(a,x) = 1/Gamma(a)*integrate(t^(a-1)%e^(-t),t=0..x)}
+#endif
+ ++ to machine precision, using the NAG routine S14BAF.
+
+ nagIncompleteGammaP : (DF, DF, DF) -> DF ;
+
+ ++ nagIncompleteGammaP(a,x,tol) evaluates the incomplete gamma
+ ++ function \spad{P}, defined by
+#if saturn
+ ++ \[P(a,x) & = & \frac{1}{\Gamma(a)}\int_{0}^{x}t^{a-1}e^{-t}\,dt\]
+#else
+ ++ \spad{P(a,x) = 1/Gamma(a)*integrate(t^(a-1)%e^(-t),t=0..x)}
+#endif
+ ++ to a relative accuracy \spad{tol}, using the NAG routine S14BAF.
+
+ nagIncompleteGammaQ : (DF, DF) -> DF ;
+
+ ++ nagIncompleteGammaQ evaluates the incomplete gamma function
+ ++ \spad{Q}, defined by
+#if saturn
+ ++ \[Q(a,x)&=&\frac{1}{\Gamma(a)}\int_{x}^{\infty}t^{a-1}e^{-t}\,dt\]
+#else
+ ++ \spad{Q(a,x) = 1/Gamma(a)*integrate(t^(a-1)%e^(-t),t=x..%infinity)}
+#endif
+ ++ to machine precision, using the NAG routine S14BAF.
+
+ nagIncompleteGammaQ : (DF, DF, DF) -> DF ;
+
+ ++ nagIncompleteGammaQ(a,x,tol) evaluates the incomplete gamma
+ ++ function \spad{Q}, defined by
+#if saturn
+ ++ \[Q(a,x)&=&\frac{1}{\Gamma(a)}\int_{x}^{\infty}t^{a-1}e^{-t}\,dt\]
+#else
+ ++ \spad{Q(a,x) = 1/Gamma(a)*integrate(t^(a-1)%e^(-t),t=x..%infinity)}
+#endif
+ ++ to a relative accuracy \spad{tol}, using the NAG routine S14BAF.
+
+ nagErf : DF -> DF ;
+
+ ++ nagErf calculates an approximation to the error function,
+ ++ \spad{erf}, defined by
+#if saturn
+ ++ \[{\rm erf}\, x = \frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^{2}}\,dt\]
+#else
+ ++ \spad{erf(x) = 2/sqrt(\%pi)*integrate(\%e^(-t^2),t=0..x)}
+#endif
+ ++ using the NAG routine S15AEF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s15aef.
+
+ nagErfC : DF -> DF ;
+
+ ++ nagErfC calculates an approximation to the complementary error
+ ++ function \spad{erfc}, defined by
+#if saturn
+ ++ \[{\rm erfc}\,x =
+ ++ \frac{2} {\sqrt{\pi}}\int_{x}^{\infty}e^{-t^{2}}\,dt\]
+#else
+ ++ \spad{erfc(x) = 2/sqrt(%pi)*integrate(%e^(-t^2),t=x..%infinity)}
+#endif
+ ++ using the NAG routine S15ADF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s15adf.
+
+ nagDAiryAi : DF -> DF ;
+
+ ++ nagDAiryAi calculates an approximation to \spad{Ai'}, the
+ ++ derivative of the Airy function \spad{Ai}, using the NAG routine
+ ++ S17AJF.
+
+ nagDAiryAi : CDF -> CDF ;
+
+ ++ nagDAiryAi calculates an approximation to \spad{Ai'}, the
+ ++ derivative of the Airy function \spad{Ai}, using the NAG routine
+ ++ S17DGF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dgf.
+
+ nagDAiryBi : DF -> DF ;
+
+ ++ nagDAiryBi calculates an approximation to \spad{Bi'}, the
+ ++ derivative of the Airy function \spad{Bi}, using the NAG routine
+ ++ S17AKF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17akf.
+
+ nagDAiryBi : CDF -> CDF ;
+
+ ++ nagDAiryBi calculates an approximation to \spad{Bi'}, the
+ ++ derivative of the Airy function \spad{Bi}, using the NAG routine
+ ++ S17DHF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dhf.
+
+ nagScaledDAiryAi : CDF -> CDF ;
+
+ ++ nagDAiryAi(z) calculates an approximation to \spad{Ai'(z)}, the
+ ++ derivative of the Airy function \spad{Ai(z)}, with the result
+ ++ scaled by a factor
+#if saturn
+ ++ $e^{2z\sqrt{z}/ 3}$
+#else
+ ++ \spad{%e^(2*z*sqrt(z)/3)}
+#endif
+ ++ using the NAG routine S17DGF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dgf.
+
+ nagScaledDAiryBi : CDF -> CDF ;
+
+ ++ nagDAiryBi(z) calculates an approximation to \spad{Bi'(z)}, the
+ ++ derivative of the Airy function \spad{Bi(z)}, with the result
+ ++ scaled by a factor
+#if saturn
+ ++ $e^{2z\sqrt{z}/ 3}$
+#else
+ ++ \spad{%e^(2*z*sqrt(z)/3)}
+#endif
+ ++ using the NAG routine S17DHF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dhf.
+
+ nagHankelH1 : (DF, CDF, INT) -> MCDF ;
+
+ ++ nagHankelH1(nu,z,n) calculates an approximation to a sequence of n
+ ++ values of the Hankel function
+#if saturn
+ ++ $H_{\nu + k}^{(1)}(z)$
+#else
+ ++ \spad{H1(nu + k, z)}
+#endif
+ ++ for non-negative nu and \spad{k = 0,1 ... n-1}, using the NAG
+ ++ routine S17DLF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dlf.
+
+ nagHankelH2 : (DF, CDF, INT) -> MCDF ;
+
+ ++ nagHankelH2(nu,z,n) calculates an approximation to a sequence of n
+ ++ values of the Hankel function
+#if saturn
+ ++ $H_{\nu + k}^{(2)}(z)$
+#else
+ ++ \spad{H2(nu + k, z)}
+#endif
+ ++ for non-negative nu and \spad{k = 0,1 ... n-1}, using the NAG
+ ++ routine S17DLF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dlf.
+
+ nagScaledHankelH1 : (DF, CDF, INT) -> MCDF ;
+
+ ++ nagHankelH1(nu,z,n) calculates an approximation to a sequence of n
+ ++ values of the Hankel function
+#if saturn
+ ++ $H_{\nu + k}^{(1)}(z)$
+#else
+ ++ \spad{H1(nu + k, z)}
+#endif
+ ++ for non-negative nu and \spad{k = 0,1 ... n-1}, with the result
+ ++ scaled by a factor
+#if saturn
+ ++ $e^{-iz}
+#else
+ ++ \spad{%e^(-%i*z)}
+#endif
+ ++ using the NAG routine S17DLF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dlf.
+
+ nagScaledHankelH2 : (DF, CDF, INT) -> MCDF ;
+
+ ++ nagHankelH2(nu,z,n) calculates an approximation to a sequence of n
+ ++ values of the Hankel function
+#if saturn
+ ++ $H_{\nu + k}^{(2)}(z)$
+#else
+ ++ \spad{H2(nu + k, z)}
+#endif
+ ++ for non-negative nu and \spad{k = 0,1 ... n-1}, with the result
+ ++ scaled by a factor
+#if saturn
+ ++ $e^{iz}
+#else
+ ++ \spad{%e^(%i*z)}
+#endif
+ ++ using the NAG routine S17DLF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s17dlf.
+
+ nagKelvinBer : DF -> DF ;
+
+ ++ nagKelvinBer calculates an approximation to the Kelvin function
+ ++ \spad{ber}, using the NAG routine S19AAF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s19aaf.
+
+ nagKelvinBei : DF -> DF ;
+
+ ++ nagKelvinBei calculates an approximation to the Kelvin function
+ ++ \spad{bei}, using the NAG routine S19ABF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s19abf.
+
+ nagKelvinKer : DF -> DF ;
+
+ ++ nagKelvinKer calculates an approximation to the Kelvin function
+ ++ \spad{ker}, using the NAG routine S19ACF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s19acf.
+
+ nagKelvinKei : DF -> DF ;
+
+ ++ nagKelvinKei calculates an approximation to the Kelvin function
+ ++ \spad{kei}, using the NAG routine S19ADF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s19adf.
+
+ nagFresnelS : DF -> DF ;
+
+ ++ nagFresnelS calculates an approximation to the Fresnel integral
+ ++ \spad{S}, defined by
+#if saturn
+ ++ \[S(x) = \int_{0}^{x}\sin\left(\frac{\pi}{2}t^{2}\right)\,dt\]
+#else
+ ++ \spad{S(x) = integrate(sin(%pi/2*t^2),t=0..x)}
+#endif
+ ++ using the NAG routine S20ACF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s20acf.
+
+ nagFresnelC : DF -> DF ;
+
+ ++ nagFresnelC calculates an approximation to the Fresnel integral
+ ++ \spad{C}, defined by
+#if saturn
+ ++ \[C(x) = \int_{0}^{x}\cos\left(\frac{\pi}{2}t^{2}\right)\,dt\]
+#else
+ ++ \spad{C(x) = integrate(cos(%pi/2*t^2),t=0..x)}
+#endif
+ ++ using the NAG routine S20ADF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s20adf.
+
+ nagEllipticIntegralRC : (DF, DF) -> DF ;
+
+ ++ nagEllipticIntegralRC(x,y) calculates an approximation to the
+ ++ elementary (degenerate symmetrised elliptic) integral
+#if saturn
+ ++ \[R_{C}(x,y) =
+ ++ \frac{1}{2}\int_{0}^{\infty}\frac{dt}{\sqrt{t+x}(t+y)}\]
+#else
+ ++ \spad{RC(x,y) = 1/2*integrate(1/(sqrt(t+x)*(t+y)),t=0..\infinity)}
+#endif
+ ++ using the NAG routine S21BAF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s21baf.
+
+ nagEllipticIntegralRF : (DF, DF, DF) -> DF ;
+
+ ++ nagEllipticIntegralRF(x,y,z) calculates an approximation to the
+ ++ symmetrised elliptic integral of the first kind,
+#if saturn
+ ++ \[R_{F}(x, y, z) =
+ ++ \frac{1}{2}\int_{0}^{\infty}\frac{dt}{\sqrt{(t+x)(t+y)(t+z)}}\]
+#else
+ ++ \spad{RF(x,y,z) =
+ ++ 1/2*integrate(1/sqrt((t+x)*(t+y)*(t+z)),t=0..\infinity)}
+#endif
+ ++ using the NAG routine S21BBF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s21bbf.
+
+ nagEllipticIntegralRD : (DF, DF, DF) -> DF ;
+
+ ++ nagEllipticIntegralRD(x,y,z) calculates an approximation to the
+ ++ symmetrised elliptic integral of the second kind,
+#if saturn
+ ++ \[R_{D}(x, y, z) =
+ ++ \frac{3}{2}\int_{0}^{\infty}\frac{dt}{\sqrt{(t+x)(t+y)(t+z)^{3}}}\]
+#else
+ ++ \spad{RD(x,y,z) =
+ ++ 1/2*integrate(1/sqrt((t+x)*(t+y)*(t+z)^3),t=0..\infinity)}
+#endif
+ ++ using the NAG routine S21BCF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s21bcf.
+
+ nagEllipticIntegralRJ : (DF, DF, DF, DF) -> DF ;
+
+ ++ nagEllipticIntegralRJ(x,y,z,rho) calculates an approximation to
+ ++ the symmetrised elliptic integral of the third kind,
+#if saturn
+ ++ \[R_{J}(x, y, z, \rho ) =
+ ++ \frac{3}{2}\int_{0}^{\infty}
+ ++ \frac{dt}{(t+\rho)\sqrt{(t+x)(t+y)(t+z)}}\]
+#else
+ ++ \spad{RJ(x,y,z,rho) =
+ ++ 3/2*integrate(1/((t+rho)*sqrt((t+x)*(t+y)*(t+z))),t=0..\infinity))u}
+#endif
+ ++ using the NAG routine S21BDF.
+ ++ For detailed information on the accuracy, please consult the NAG
+ ++ manual via the Browser page for the operation s21bdf.
+
+} == add {
+
+ import from NagSpecialFunctionsPackage ;
+ import from NagResultChecks ;
+
+ local ipIfail : Integer := -1 ;
+
+ nagExpInt(x : DF) : DF ==
+ checkResult(s13aaf(x,ipIfail), "s13aafResult", "S13AAF") ;
+
+ nagCosInt(x : DF) : DF ==
+ checkResult(s13acf(x,ipIfail), "s13acfResult", "S13ACF") ;
+
+ nagSinInt(x : DF) : DF ==
+ checkResult(s13adf(x,ipIfail), "s13adfResult", "S13ADF") ;
+
+ nagIncompleteGammaP(a : DF, x : DF) : DF ==
+ checkResult(s14baf(a,x,0.0,ipIfail), "p", "S14BAF") ;
+
+ nagIncompleteGammaP(a : DF, x : DF, tol : DF) : DF ==
+ checkResult(s14baf(a,x,tol,ipIfail), "p", "S14BAF") ;
+
+ nagIncompleteGammaQ(a : DF, x : DF) : DF ==
+ checkResult(s14baf(a,x,0.0,ipIfail), "q", "S14BAF") ;
+
+ nagIncompleteGammaQ(a : DF, x : DF, tol : DF) : DF ==
+ checkResult(s14baf(a,x,tol,ipIfail), "q", "S14BAF") ;
+
+ nagErfC(x : DF) : DF ==
+ checkResult(s15adf(x,ipIfail), "s15adfResult", "S15ADF") ;
+
+ nagErf(x : DF) : DF ==
+ checkResult(s15aef(x,ipIfail), "s15aefResult", "S15AEF") ;
+
+ nagDAiryAi(x : DF) : DF ==
+ checkResult(s17ajf(x,ipIfail), "s17ajfResult", "S17AJF") ;
+
+ nagDAiryAi(z : CDF) : CDF ==
+ checkCxResult(s17dgf("d",z,"u",ipIfail), "ai", "S17DGF") ;
+
+ nagDAiryBi(x : DF) : DF ==
+ checkResult(s17akf(x,ipIfail), "s17akfResult", "S17AKF") ;
+
+ nagDAiryBi(z : CDF) : CDF ==
+ checkCxResult(s17dhf("d",z,"u",ipIfail), "bi", "S17DHF") ;
+
+ nagScaledDAiryAi(z : CDF) : CDF ==
+ checkCxResult(s17dgf("d",z,"s",ipIfail), "ai", "S17DGF") ;
+
+ nagScaledDAiryBi(z : CDF) : CDF ==
+ checkCxResult(s17dhf("d",z,"s",ipIfail), "bi", "S17DHF") ;
+
+ nagHankelH1(order : DF, z : CDF, n : INT) : Matrix CDF ==
+ checkMxCDF(s17dlf(1,order,z,n,"u",ipIfail), "cy", "S17DLF") ;
+
+ nagHankelH2(order : DF, z : CDF, n : INT) : Matrix CDF ==
+ checkMxCDF(s17dlf(2,order,z,n,"u",ipIfail), "cy", "S17DLF") ;
+
+ nagScaledHankelH1(order : DF, z : CDF, n : INT) : Matrix CDF ==
+ checkMxCDF(s17dlf(1,order,z,n,"s",ipIfail), "cy", "S17DLF") ;
+
+ nagScaledHankelH2(order : DF, z : CDF, n : INT) : Matrix CDF ==
+ checkMxCDF(s17dlf(2,order,z,n,"s",ipIfail), "cy", "S17DLF") ;
+
+ nagKelvinBer(x : DF) : DF ==
+ checkResult(s19aaf(x,ipIfail), "s19aafResult", "S19AAF") ;
+
+ nagKelvinBei(x : DF) : DF ==
+ checkResult(s19abf(x,ipIfail), "s19abfResult", "S19ABF") ;
+
+ nagKelvinKer(x : DF) : DF ==
+ checkResult(s19acf(x,ipIfail), "s19acfResult", "S19ACF") ;
+
+ nagKelvinKei(x : DF) : DF ==
+ checkResult(s19adf(x,ipIfail), "s19adfResult", "S19ADF") ;
+
+ nagFresnelS(x : DF) : DF ==
+ checkResult(s20acf(x,ipIfail), "s20acfResult", "S20ACF") ;
+
+ nagFresnelC(x : DF) : DF ==
+ checkResult(s20adf(x,ipIfail), "s20adfResult", "S20ADF") ;
+
+ nagEllipticIntegralRC(x : DF, y : DF) : DF ==
+ checkResult(s21baf(x,y,ipIfail), "s21bafResult", "S21BAF") ;
+
+ nagEllipticIntegralRF(x : DF, y : DF, z : DF) : DF ==
+ checkResult(s21bbf(x,y,z,ipIfail), "s21bbfResult", "S21BBF") ;
+
+ nagEllipticIntegralRD(x : DF, y : DF, z : DF) : DF ==
+ checkResult(s21bcf(x,y,z,ipIfail), "s21bcfResult", "S21BCF") ;
+
+ nagEllipticIntegralRJ(x : DF, y : DF, z : DF, rho : DF) : DF ==
+ checkResult(s21bdf(x,y,z,rho,ipIfail), "s21bdfResult", "S21BDF") ;
+}
+
+#if NeverAssertThis
+
+-- Note that the conversions of Results from DoubleFloat to Float
+-- will become unnecessary if outputGeneral is extended to apply to
+-- DoubleFloat quantities.
+
+)lib nrc
+)lib nsfip
+
+outputGeneral 4
+
+-- DF here means DoubleFloat.
+-- Results converted to Float as outputGeneral not working on DF.
+
+-- nagExpInt : DF -> DF ;
+
+nagExpInt(2) :: Float
+
+-- 0.0489
+
+nagExpInt(-1) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S13AAF: IFAIL = 1
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S13AAF. The error number (IFAIL value) is 1, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+-- nagSinInt : DF -> DF ;
+
+nagSinInt(0) :: Float
+
+-- 0.0
+
+nagSinInt(0.2) :: Float
+
+-- 0.1996
+
+nagSinInt(0.4) :: Float
+
+-- 0.3965
+
+nagSinInt(0.6) :: Float
+
+-- 0.5881
+
+nagSinInt(0.8) :: Float
+
+-- 0.7721
+
+nagSinInt(1) :: Float
+
+-- 0.9461
+
+-- nagCosInt : DF -> DF ;
+
+nagCosInt(0.2) :: Float
+
+-- - 1.042
+
+nagCosInt(0.4) :: Float
+
+-- - 0.3788
+
+nagCosInt(0.6) :: Float
+
+-- - 0.02227
+
+nagCosInt(0.8) :: Float
+
+-- 0.1983
+
+nagCosInt(1) :: Float
+
+-- 0.3374
+
+-- nagIncompleteGammaP : (DF, DF) -> DF ; (to machine precision)
+
+nagIncompleteGammaP(2,3) :: Float
+
+-- 0.8009
+
+nagIncompleteGammaP(7,1) :: Float
+
+-- 0.00008324
+
+nagIncompleteGammaP(0.5,99) :: Float
+
+-- 1.0
+
+nagIncompleteGammaP(20,21) :: Float
+
+-- 0.6157
+
+nagIncompleteGammaP(21,20) :: Float
+
+-- 0.4409
+
+-- nagIncompleteGammaP : (DF, DF, DF) -> DF ; (to specified precision)
+
+nagIncompleteGammaP(7,1,0.1) :: Float
+
+-- 0.00008313
+
+-- nagIncompleteGammaQ : (DF, DF) -> DF ; (to machine precision)
+
+nagIncompleteGammaQ(2,3) :: Float
+
+-- 0.1991
+
+nagIncompleteGammaQ(7,1) :: Float
+
+-- 0.9999
+
+nagIncompleteGammaQ(0.5,99) :: Float
+
+-- 0.5705 E -44
+
+nagIncompleteGammaQ(20,21) :: Float
+
+-- 0.3843
+
+nagIncompleteGammaQ(21,20) :: Float
+
+-- 0.5591
+
+nagIncompleteGammaQ(25,14) :: Float
+
+-- 0.995
+
+-- nagIncompleteGammaQ : (DF, DF, DF) -> DF ; (to specified precision)
+
+nagIncompleteGammaQ(25,14,0.1) :: Float
+
+-- 0.9953
+
+-- nagErf : DF -> DF ;
+
+nagErf(-6) :: Float
+
+-- - 1.0
+
+nagErf(-4.5) :: Float
+
+-- - 1.0
+
+nagErf(-1) :: Float
+
+-- - 0.8427
+
+nagErf(1) :: Float
+
+-- 0.8427
+
+nagErf(4.5) :: Float
+
+-- 1.0
+
+nagErf(6) :: Float
+
+-- 1.0
+
+-- nagErfC : DF -> DF ;
+
+nagErfC(-10) :: Float
+
+-- 2.0
+
+nagErfC(-1) :: Float
+
+-- 1.843
+
+nagErfC(0) :: Float
+
+-- 1.0
+
+nagErfC(1) :: Float
+
+-- 0.1573
+
+nagErfC(15) :: Float
+
+-- 0.7213 E -99
+
+-- nagDAiryAi : DF -> DF ;
+
+nagDAiryAi(-10) :: Float
+
+-- 0.9963
+
+nagDAiryAi(-1) :: Float
+
+-- - 0.01016
+
+nagDAiryAi(0) :: Float
+
+-- - 0.2588
+
+nagDAiryAi(1) :: Float
+
+-- - 0.1591
+
+nagDAiryAi(5) :: Float
+
+-- - 0.0002474
+
+nagDAiryAi(10) :: Float
+
+-- - 0.3521 E -9
+
+nagDAiryAi(20) :: Float
+
+-- - 0.7586 E -26
+
+-- nagDAiryAi : CDF -> CDF ;
+
+nagDAiryAi(0.3+0.4*%i) :: Complex Float
+
+-- - 0.2612 + 0.03848 %i
+
+-- nagDAiryBi : DF -> DF ;
+
+nagDAiryBi(-10) :: Float
+
+-- 0.1194
+
+nagDAiryBi(-1) :: Float
+
+-- 0.5924
+
+nagDAiryBi(0) :: Float
+
+-- 0.4483
+
+nagDAiryBi(1) :: Float
+
+-- 0.9324
+
+nagDAiryBi(5) :: Float
+
+-- 1436.0
+
+nagDAiryBi(10) :: Float
+
+-- 0.1429 E 10
+
+nagDAiryBi(20) :: Float
+
+-- 0.9382 E 26
+
+-- nagDAiryBi : CDF -> CDF ;
+
+nagDAiryBi(0.3+0.4*%i) :: Complex Float
+
+-- 0.4093 + 0.07966 %i
+
+-- nagScaledDAiryAi : CDF -> CDF ;
+
+nagScaledDAiryAi(0.3+0.4*%i) :: Complex Float
+
+-- - 0.2744 - 0.02356 %i
+
+-- nagScaledDAiryBi : CDF -> CDF ;
+
+nagScaledDAiryBi(0.3+0.4*%i) :: Complex Float
+
+-- 0.3924 + 0.07638 %i
+
+-- nagHankelH1 : (DF, CDF, Int) -> List CDF ;
+
+nagHankelH1(0,0.3+0.4*%i,2) :: Matrix Complex Float
+
+-- [0.3466 - 0.5588 %i - 0.7912 - 0.8178 %i]
+
+nagHankelH1(2.3,2,2) :: Matrix Complex Float
+
+-- [0.2721 - 0.7398 %i 0.08902 - 1.412 %i]
+
+nagHankelH1(2.12,-1,2) :: Matrix Complex Float
+
+-- [- 0.7722 - 1.693 %i 2.601 + 6.527 %i]
+
+-- nagHankelH2 : (DF, CDF, Int) -> List CDF ;
+
+nagHankelH2(6,3.1-1.6*%i,2) :: Matrix Complex Float
+
+-- [- 1.371 - 1.28 %i - 1.491 - 5.993 %i]
+
+-- nagScaledHankelH1 : (DF, CDF, Int) -> List CDF ;
+
+nagScaledHankelH1(0,0.3+0.4*%i,2) :: Matrix Complex Float
+
+-- [0.2477 - 0.9492 %i - 1.488 - 0.8166 %i]
+
+-- nagScaledHankelH2 : (DF, CDF, Int) -> List CDF ;
+
+nagScaledHankelH2(6,3.1-1.6*%i,2) :: Matrix Complex Float
+
+-- [7.05 + 6.052 %i 8.614 + 29.35 %i]
+
+-- nagKelvinBer : DF -> DF ;
+
+nagKelvinBer(0.1) :: Float
+
+-- 1.0
+
+nagKelvinBer(1) :: Float
+
+-- 0.9844
+
+nagKelvinBer(2.5) :: Float
+
+-- 0.4
+
+nagKelvinBer(5) :: Float
+
+-- - 6.23
+
+nagKelvinBer(10) :: Float
+
+-- 138.8
+
+nagKelvinBer(15) :: Float
+
+-- - 2967.0
+
+nagKelvinBer(60) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19AAF: IFAIL = 1
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19AAF. The error number (IFAIL value) is 1, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+nagKelvinBer(-1) :: Float
+
+-- 0.9844
+
+-- nagKelvinBei : DF -> DF ;
+
+nagKelvinBei(0.1) :: Float
+
+-- 0.0025
+
+nagKelvinBei(1) :: Float
+
+-- 0.2496
+
+nagKelvinBei(2.5) :: Float
+
+-- 1.457
+
+nagKelvinBei(5) :: Float
+
+-- 0.116
+
+nagKelvinBei(10) :: Float
+
+-- 56.37
+
+nagKelvinBei(15) :: Float
+
+-- - 2953.0
+
+nagKelvinBei(60) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19ABF: IFAIL = 1
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19ABF. The error number (IFAIL value) is 1, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+nagKelvinBei(-1) :: Float
+
+-- 0.2496
+
+-- nagKelvinKer : DF -> DF ;
+
+nagKelvinKer(0) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19ACF: IFAIL = 2
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19ACF. The error number (IFAIL value) is 2, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+nagKelvinKer(0.1) :: Float
+
+-- 2.42
+
+nagKelvinKer(1) :: Float
+
+-- 0.2867
+
+nagKelvinKer(2.5) :: Float
+
+-- - 0.06969
+
+nagKelvinKer(5) :: Float
+
+-- - 0.01151
+
+nagKelvinKer(10) :: Float
+
+-- 0.0001295
+
+nagKelvinKer(15) :: Float
+
+-- - 0.1514 E -7
+
+nagKelvinKer(1100) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19ACF: IFAIL = 1
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19ACF. The error number (IFAIL value) is 1, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+nagKelvinKer(-1) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19ACF: IFAIL = 2
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19ACF. The error number (IFAIL value) is 2, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+-- nagKelvinKei : DF -> DF ;
+
+nagKelvinKei(0) :: Float
+
+-- - 0.7854
+
+nagKelvinKei(0.1) :: Float
+
+-- - 0.7769
+
+nagKelvinKei(1) :: Float
+
+-- - 0.495
+
+nagKelvinKei(2.5) :: Float
+
+-- - 0.1107
+
+nagKelvinKei(5) :: Float
+
+-- 0.01119
+
+nagKelvinKei(10) :: Float
+
+-- - 0.0003075
+
+nagKelvinKei(15) :: Float
+
+-- 0.000007963
+
+nagKelvinKei(1100) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19ADF: IFAIL = 1
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19ADF. The error number (IFAIL value) is 1, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+nagKelvinKei(-1) :: Float
+
+-- ** ABNORMAL EXIT from NAG Library routine S19ADF: IFAIL = 2
+-- ** NAG soft failure - control returned
+--
+-- Error signalled from user code:
+-- An error was detected when calling the NAG Library routine
+-- S19ADF. The error number (IFAIL value) is 2, please consult the
+-- NAG manual via the Browser for diagnostic information.
+
+
+-- nagFresnelS : DF -> DF ;
+
+nagFresnelS(0) :: Float
+
+-- 0.0
+
+nagFresnelS(0.5) :: Float
+
+-- 0.06473
+
+nagFresnelS(1) :: Float
+
+-- 0.4383
+
+nagFresnelS(2) :: Float
+
+-- 0.3434
+
+nagFresnelS(4) :: Float
+
+-- 0.4205
+
+nagFresnelS(5) :: Float
+
+-- 0.4992
+
+nagFresnelS(6) :: Float
+
+-- 0.447
+
+nagFresnelS(8) :: Float
+
+-- 0.4602
+
+nagFresnelS(10) :: Float
+
+-- 0.4682
+
+nagFresnelS(-1) :: Float
+
+-- - 0.4383
+
+nagFresnelS(1000) :: Float
+
+-- 0.4997
+
+-- nagFresnelC : DF -> DF ;
+
+nagFresnelC(0) :: Float
+
+-- 0.0
+
+nagFresnelC(0.5) :: Float
+
+-- 0.4923
+
+nagFresnelC(1) :: Float
+
+-- 0.7799
+
+nagFresnelC(2) :: Float
+
+-- 0.4883
+
+nagFresnelC(4) :: Float
+
+-- 0.4984
+
+nagFresnelC(5) :: Float
+
+-- 0.5636
+
+nagFresnelC(6) :: Float
+
+-- 0.4995
+
+nagFresnelC(8) :: Float
+
+-- 0.4998
+
+nagFresnelC(10) :: Float
+
+-- 0.4999
+
+nagFresnelC(-1) :: Float
+
+-- - 0.7799
+
+nagFresnelC(1000) :: Float
+
+-- 0.5
+
+-- nagEllipticIntegralRC : (DF, DF) -> DF ;
+
+nagEllipticIntegralRC(0.5,1) :: Float
+
+-- 1.111
+
+nagEllipticIntegralRC(1,1) :: Float
+
+-- 1.0
+
+nagEllipticIntegralRC(1.5,1) :: Float
+
+-- 0.9312
+
+-- nagEllipticIntegralRD : (DF, DF, DF) -> DF ;
+
+nagEllipticIntegralRD(0.5,0.5,1) :: Float
+
+-- 1.479
+
+nagEllipticIntegralRD(0.5,1,1) :: Float
+
+-- 1.211
+
+nagEllipticIntegralRD(0.5,1.5,1) :: Float
+
+-- 1.061
+
+nagEllipticIntegralRD(1,1,1) :: Float
+
+-- 1.0
+
+nagEllipticIntegralRD(1,1.5,1) :: Float
+
+-- 0.8805
+
+nagEllipticIntegralRD(1.5,1.5,1) :: Float
+
+-- 0.7775
+
+-- nagEllipticIntegralRF : (DF, DF, DF) -> DF ;
+
+nagEllipticIntegralRF(0.5,1,1.5) :: Float
+
+-- 1.028
+
+nagEllipticIntegralRF(1,1.5,2) :: Float
+
+-- 0.826
+
+nagEllipticIntegralRF(1.5,2,2.5) :: Float
+
+-- 0.7116
+
+-- nagEllipticIntegralRJ : (DF, DF, DF, DF) -> DF ;
+
+nagEllipticIntegralRJ(0.5,0.5,0.5,2) :: Float
+
+-- 1.118
+
+nagEllipticIntegralRJ(0.5,0.5,1,2) :: Float
+
+-- 0.9221
+
+nagEllipticIntegralRJ(0.5,0.5,1.5,2) :: Float
+
+-- 0.8115
+
+nagEllipticIntegralRJ(0.5,1,1,2) :: Float
+
+-- 0.7671
+
+nagEllipticIntegralRJ(0.5,1,1.5,2) :: Float
+
+-- 0.6784
+
+nagEllipticIntegralRJ(0.5,1.5,1.5,2) :: Float
+
+-- 0.6017
+
+nagEllipticIntegralRJ(1,1,1,2) :: Float
+
+-- 0.6438
+
+nagEllipticIntegralRJ(1,1,1.5,2) :: Float
+
+-- 0.5722
+
+nagEllipticIntegralRJ(1,1.5,1.5,2) :: Float
+
+-- 0.5101
+
+nagEllipticIntegralRJ(1.5,1.5,1.5,2) :: Float
+
+-- 0.4561
+
+outputGeneral()
+
+output "End of tests"
+
+#endif
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- NagSpecialFunctionsInterfacePackage
+
+-- To test:
+-- sed -ne '1,/^#if NeverAssertThis/d;/#endif/d;p' < nsfip.as > nsfip.input
+-- axiom
+-- )set nag host <some machine running nagd>
+-- )r nsfip.input
+
+#unassert saturn
+
+#include "axiom.as"
+
+DF ==> DoubleFloat ;
+CDF ==> Complex DoubleFloat ;
+MCDF ==> Matrix Complex DoubleFloat ;
+INT ==> Integer ;
+RSLT ==> Result ;
+SMBL ==> Symbol ;
+STRG ==> String ;
+
+<<NagSpecialFunctionsInterfacePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/nsregset.spad.pamphlet b/src/algebra/nsregset.spad.pamphlet
new file mode 100644
index 00000000..13d90b21
--- /dev/null
+++ b/src/algebra/nsregset.spad.pamphlet
@@ -0,0 +1,203 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra nsregset.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category SNTSCAT SquareFreeNormalizedTriangularSetCategory}
+<<category SNTSCAT SquareFreeNormalizedTriangularSetCategory>>=
+)abbrev category SNTSCAT SquareFreeNormalizedTriangularSetCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 10/07/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See: essai Graphisme
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ Description:
+++ The category of square-free and normalized triangular sets.
+++ Thus, up to the primitivity axiom of [1], these sets are Lazard
+++ triangular sets.\newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+SquareFreeNormalizedTriangularSetCategory(R:GcdDomain,E:OrderedAbelianMonoidSup,_
+ V:OrderedSet,P:RecursivePolynomialCategory(R,E,V)):
+ Category ==
+ Join(SquareFreeRegularTriangularSetCategory(R,E,V,P), NormalizedTriangularSetCategory(R,E,V,P))
+
+@
+\section{package LAZM3PK LazardSetSolvingPackage}
+<<package LAZM3PK LazardSetSolvingPackage>>=
+)abbrev package LAZM3PK LazardSetSolvingPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 10/02/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A package for solving polynomial systems by means of Lazard triangular
+++ sets [1].
+++ This package provides two operations. One for solving in the sense
+++ of the regular zeros, and the other for solving in the sense of
+++ the Zariski closure. Both produce square-free regular sets.
+++ Moreover, the decompositions do not contain any redundant component.
+++ However, only zero-dimensional regular sets are normalized, since
+++ normalization may be time consumming in positive dimension.
+++ The decomposition process is that of [2].\newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+++ [2] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 1.
+
+LazardSetSolvingPackage(R,E,V,P,TS,ST): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS: RegularTriangularSetCategory(R,E,V,P)
+ ST : SquareFreeRegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ K ==> Fraction R
+ LP ==> List P
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Split ==> List TS
+ --KeyGcd ==> Record(arg1: P, arg2: P, arg3: TS, arg4: B)
+ --EntryGcd ==> List PWT
+ --HGcd ==> TabulatedComputationPackage(KeyGcd, EntryGcd)
+ --KeyInvSet ==> Record(arg1: P, arg3: TS)
+ --EntryInvSet ==> List TS
+ --HInvSet ==> TabulatedComputationPackage(KeyInvSet, EntryInvSet)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ regsetgcdpack ==> SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,ST)
+ quasicomppack ==> SquareFreeQuasiComponentPackage(R,E,V,P,ST)
+ normalizpack ==> NormalizationPackage(R,E,V,P,ST)
+
+ Exports == with
+
+ normalizeIfCan: ST -> ST
+ ++ \axiom{normalizeIfCan(ts)} returns \axiom{ts} in an normalized shape
+ ++ if \axiom{ts} is zero-dimensional.
+ zeroSetSplit: (LP, B) -> List ST
+ ++ \axiom{zeroSetSplit(lp,clos?)} has the same specifications as
+ ++ \axiomOpFrom{zeroSetSplit(lp,clos?)}{RegularTriangularSetCategory}.
+
+ Implementation == add
+
+ convert(st: ST): TS ==
+ ts: TS := empty()
+ lp: LP := members(st)$ST
+ lp := sort(infRittWu?,lp)
+ for p in lp repeat
+ ts := internalAugment(p,ts)$TS
+ ts
+
+ squareFree(ts: TS): List ST ==
+ empty? ts => [empty()$ST]
+ lp: LP := members(ts)$TS
+ lp := sort(infRittWu?,lp)
+ newts: ST := empty()$ST
+ toSee: List ST := [newts]
+ toSave: List ST
+ for p in lp repeat
+ toSave := []
+ while (not empty? toSee) repeat
+ us := first toSee; toSee := rest toSee
+ lpwt := stoseSquareFreePart(p,us)$regsetgcdpack
+ for pwt in lpwt repeat
+ newus := internalAugment(pwt.val,pwt.tower)$ST
+ toSave := cons(newus,toSave)
+ toSee := toSave
+ toSave
+
+ normalizeIfCan(ts: ST): ST ==
+ empty? ts => ts
+ lp: LP := members(ts)$ST
+ lp := sort(infRittWu?,lp)
+ p: P := first lp
+ not univariate?(p)$polsetpack => ts
+ lp := rest lp
+ newts: ST := empty()$ST
+ newts := internalAugment(p,newts)$ST
+ while (not empty? lp) repeat
+ p := first lp
+ lv := variables(p)
+ for v in lv repeat
+ v = mvar(p) => "leave"
+ not algebraic?(v,newts) => return internalAugment(lp,newts)$ST
+ lp := rest lp
+ p := normalizedAssociate(p,newts)$normalizpack
+ newts := internalAugment(p,newts)$ST
+ newts
+
+ zeroSetSplit(lp:List(P), clos?:B): List ST ==
+ -- if clos? then SOLVE in the closure sense
+ toSee: Split := zeroSetSplit(lp, clos?)$TS
+ toSave: List ST := []
+ for ts in toSee repeat
+ toSave := concat(squareFree(ts),toSave)
+ toSave := removeSuperfluousQuasiComponents(toSave)$quasicomppack
+ [normalizeIfCan(ts) for ts in toSave]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category SNTSCAT SquareFreeNormalizedTriangularSetCategory>>
+<<package LAZM3PK LazardSetSolvingPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/numeigen.spad.pamphlet b/src/algebra/numeigen.spad.pamphlet
new file mode 100644
index 00000000..310fe945
--- /dev/null
+++ b/src/algebra/numeigen.spad.pamphlet
@@ -0,0 +1,413 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra numeigen.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INEP InnerNumericEigenPackage}
+<<package INEP InnerNumericEigenPackage>>=
+)abbrev package INEP InnerNumericEigenPackage
+++ Author:P. Gianni
+++ Date Created: Summer 1990
+++ Date Last Updated:Spring 1991
+++ Basic Functions:
+++ Related Constructors: ModularField
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package is the inner package to be used by NumericRealEigenPackage
+++ and NumericComplexEigenPackage for the computation of numeric
+++ eigenvalues and eigenvectors.
+InnerNumericEigenPackage(K,F,Par) : C == T
+ where
+ F : Field -- this is the field where the answer will be
+ -- for dealing with the complex case
+ K : Field -- type of the input
+ Par : Join(Field,OrderedRing) -- it will be NF or RN
+
+ SE ==> Symbol()
+ RN ==> Fraction Integer
+ I ==> Integer
+ NF ==> Float
+ CF ==> Complex Float
+ GRN ==> Complex RN
+ GI ==> Complex Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ MRN ==> Matrix RN
+
+ MK ==> Matrix K
+ PK ==> Polynomial K
+ MF ==> Matrix F
+ SUK ==> SparseUnivariatePolynomial K
+ SUF ==> SparseUnivariatePolynomial F
+ SUP ==> SparseUnivariatePolynomial
+ MSUK ==> Matrix SUK
+
+ PEigenForm ==> Record(algpol:SUK,almult:Integer,poleigen:List(MSUK))
+
+ outForm ==> Record(outval:F,outmult:Integer,outvect:List MF)
+
+ IntForm ==> Union(outForm,PEigenForm)
+ UFactor ==> (SUK -> Factored SUK)
+ C == with
+
+ charpol : MK -> SUK
+ ++ charpol(m) computes the characteristic polynomial of a matrix
+ ++ m with entries in K.
+ ++ This function returns a polynomial
+ ++ over K, while the general one (that is in EiegenPackage) returns
+ ++ Fraction P K
+
+ solve1 : (SUK, Par) -> List F
+ ++ solve1(pol, eps) finds the roots of the univariate polynomial
+ ++ polynomial pol to precision eps. If K is \spad{Fraction Integer}
+ ++ then only the real roots are returned, if K is
+ ++ \spad{Complex Fraction Integer} then all roots are found.
+
+ innerEigenvectors : (MK,Par,UFactor) -> List(outForm)
+ ++ innerEigenvectors(m,eps,factor) computes explicitly
+ ++ the eigenvalues and the correspondent eigenvectors
+ ++ of the matrix m. The parameter eps determines the type of
+ ++ the output, factor is the univariate factorizer to br used
+ ++ to reduce the characteristic polynomial into irreducible factors.
+
+ T == add
+
+ numeric(r:K):F ==
+ K is RN =>
+ F is NF => convert(r)$RN
+ F is RN => r
+ F is CF => r :: RN :: CF
+ F is GRN => r::RN::GRN
+ K is GRN =>
+ F is GRN => r
+ F is CF => convert(convert r)
+ error "unsupported coefficient type"
+
+ ---- next functions neeeded for defining ModularField ----
+
+ monicize(f:SUK) : SUK ==
+ (a:=leadingCoefficient f) =1 => f
+ inv(a)*f
+
+ reduction(u:SUK,p:SUK):SUK == u rem p
+
+ merge(p:SUK,q:SUK):Union(SUK,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ exactquo(u:SUK,v:SUK,p:SUK):Union(SUK,"failed") ==
+ val:=extendedEuclidean(v,p,u)
+ val case "failed" => "failed"
+ val.coef1
+
+ ---- eval a vector of F in a radical expression ----
+ evalvect(vect:MSUK,alg:F) : MF ==
+ n:=nrows vect
+ w:MF:=zero(n,1)$MF
+ for i in 1..n repeat
+ polf:=map(numeric,
+ vect(i,1))$UnivariatePolynomialCategoryFunctions2(K,SUK,F,SUF)
+ v:F:=elt(polf,alg)
+ setelt(w,i,1,v)
+ w
+
+ ---- internal function for the computation of eigenvectors ----
+ inteigen(A:MK,p:SUK,fact:UFactor) : List(IntForm) ==
+ dimA:NNI:= nrows A
+ MM:=ModularField(SUK,SUK,reduction,merge,exactquo)
+ AM:=Matrix(MM)
+ lff:=factors fact(p)
+ res: List IntForm :=[]
+ lr : List MF:=[]
+ for ff in lff repeat
+ pol:SUK:= ff.factor
+ if (degree pol)=1 then
+ alpha:K:=-coefficient(pol,0)/leadingCoefficient pol
+ -- compute the eigenvectors, rational case
+ B1:MK := zero(dimA,dimA)$MK
+ for i in 1..dimA repeat
+ for j in 1..dimA repeat B1(i,j):=A(i,j)
+ B1(i,i):= B1(i,i) - alpha
+ lr:=[]
+ for vecr in nullSpace B1 repeat
+ wf:MF:=zero(dimA,1)
+ for i in 1..dimA repeat wf(i,1):=numeric vecr.i
+ lr:=cons(wf,lr)
+ res:=cons([numeric alpha,ff.exponent,lr]$outForm,res)
+ else
+ ppol:=monicize pol
+ alg:MM:= reduce(monomial(1,1),ppol)
+ B:AM:= zero(dimA,dimA)$AM
+ for i in 1..dimA repeat
+ for j in 1..dimA repeat B(i,j):=reduce(A(i,j) ::SUK,ppol)
+ B(i,i):=B(i,i) - alg
+ sln2:=nullSpace B
+ soln:List MSUK :=[]
+ for vec in sln2 repeat
+ wk:MSUK:=zero(dimA,1)
+ for i in 1..dimA repeat wk(i,1):=(vec.i)::SUK
+ soln:=cons(wk,soln)
+ res:=cons([ff.factor,ff.exponent,soln]$PEigenForm,
+ res)
+ res
+
+ if K is RN then
+ solve1(up:SUK, eps:Par) : List(F) ==
+ denom := "lcm"/[denom(c::RN) for c in coefficients up]
+ up:=denom*up
+ upi := map(numer,up)$UnivariatePolynomialCategoryFunctions2(RN,SUP RN,I,SUP I)
+ innerSolve1(upi, eps)$InnerNumericFloatSolvePackage(I,F,Par)
+ else if K is GRN then
+ solve1(up:SUK, eps:Par) : List(F) ==
+ denom := "lcm"/[lcm(denom real(c::GRN), denom imag(c::GRN))
+ for c in coefficients up]
+ up:=denom*up
+ upgi := map(complex(numer(real #1), numer(imag #1)),
+ up)$UnivariatePolynomialCategoryFunctions2(GRN,SUP GRN,GI,SUP GI)
+ innerSolve1(upgi, eps)$InnerNumericFloatSolvePackage(GI,F,Par)
+ else error "unsupported matrix type"
+
+ ---- the real eigenvectors expressed as floats ----
+
+ innerEigenvectors(A:MK,eps:Par,fact:UFactor) : List outForm ==
+ pol:= charpol A
+ sln1:List(IntForm):=inteigen(A,pol,fact)
+ n:=nrows A
+ sln:List(outForm):=[]
+ for lev in sln1 repeat
+ lev case outForm => sln:=cons(lev,sln)
+ leva:=lev::PEigenForm
+ lval:List(F):= solve1(leva.algpol,eps)
+ lvect:=leva.poleigen
+ lmult:=leva.almult
+ for alg in lval repeat
+ nsl:=[alg,lmult,[evalvect(ep,alg) for ep in lvect]]$outForm
+ sln:=cons(nsl,sln)
+ sln
+
+ charpol(A:MK) : SUK ==
+ dimA :PI := (nrows A):PI
+ dimA ^= ncols A => error " The matrix is not square"
+ B:Matrix SUK :=zero(dimA,dimA)
+ for i in 1..dimA repeat
+ for j in 1..dimA repeat B(i,j):=A(i,j)::SUK
+ B(i,i) := B(i,i) - monomial(1,1)$SUK
+ determinant B
+
+
+@
+\section{package NREP NumericRealEigenPackage}
+<<package NREP NumericRealEigenPackage>>=
+)abbrev package NREP NumericRealEigenPackage
+++ Author:P. Gianni
+++ Date Created:Summer 1990
+++ Date Last Updated:Spring 1991
+++ Basic Functions:
+++ Related Constructors: FloatingRealPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package computes explicitly eigenvalues and eigenvectors of
+++ matrices with entries over the Rational Numbers.
+++ The results are expressed as floating numbers or as rational numbers
+++ depending on the type of the parameter Par.
+NumericRealEigenPackage(Par) : C == T
+ where
+ Par : Join(Field,OrderedRing) -- Float or RationalNumber
+
+ SE ==> Symbol()
+ RN ==> Fraction Integer
+ I ==> Integer
+ NF ==> Float
+ CF ==> Complex Float
+ GRN ==> Complex RN
+ GI ==> Complex Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ MRN ==> Matrix RN
+
+ MPar ==> Matrix Par
+ outForm ==> Record(outval:Par,outmult:Integer,outvect:List MPar)
+
+ C == with
+ characteristicPolynomial : MRN -> Polynomial RN
+ ++ characteristicPolynomial(m) returns the characteristic polynomial
+ ++ of the matrix m expressed as polynomial
+ ++ over RN with a new symbol as variable.
+ -- while the function in EigenPackage returns Fraction P RN.
+ characteristicPolynomial : (MRN,SE) -> Polynomial RN
+ ++ characteristicPolynomial(m,x) returns the characteristic polynomial
+ ++ of the matrix m expressed as polynomial
+ ++ over RN with variable x.
+ -- while the function in EigenPackage returns
+ ++ Fraction P RN.
+ realEigenvalues : (MRN,Par) -> List Par
+ ++ realEigenvalues(m,eps) computes the eigenvalues of the matrix
+ ++ m to precision eps. The eigenvalues are expressed as floats or
+ ++ rational numbers depending on the type of eps (float or rational).
+ realEigenvectors : (MRN,Par) -> List(outForm)
+ ++ realEigenvectors(m,eps) returns a list of
+ ++ records each one containing
+ ++ a real eigenvalue, its algebraic multiplicity, and a list of
+ ++ associated eigenvectors. All these results
+ ++ are computed to precision eps as floats or rational
+ ++ numbers depending on the type of eps .
+
+
+ T == add
+
+ import InnerNumericEigenPackage(RN, Par, Par)
+
+ characteristicPolynomial(m:MRN) : Polynomial RN ==
+ x:SE:=new()$SE
+ multivariate(charpol(m),x)
+
+ ---- characteristic polynomial of a matrix A ----
+ characteristicPolynomial(A:MRN,x:SE):Polynomial RN ==
+ multivariate(charpol(A),x)
+
+ realEigenvalues(m:MRN,eps:Par) : List Par ==
+ solve1(charpol m, eps)
+
+ realEigenvectors(m:MRN,eps:Par) :List outForm ==
+ innerEigenvectors(m,eps,factor$GenUFactorize(RN))
+
+@
+\section{package NCEP NumericComplexEigenPackage}
+<<package NCEP NumericComplexEigenPackage>>=
+)abbrev package NCEP NumericComplexEigenPackage
+++ Author: P. Gianni
+++ Date Created: Summer 1990
+++ Date Last Updated: Spring 1991
+++ Basic Functions:
+++ Related Constructors: FloatingComplexPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package computes explicitly eigenvalues and eigenvectors of
+++ matrices with entries over the complex rational numbers.
+++ The results are expressed either as complex floating numbers or as
+++ complex rational numbers
+++ depending on the type of the precision parameter.
+NumericComplexEigenPackage(Par) : C == T
+ where
+ Par : Join(Field,OrderedRing) -- Float or RationalNumber
+
+ SE ==> Symbol()
+ RN ==> Fraction Integer
+ I ==> Integer
+ NF ==> Float
+ CF ==> Complex Float
+ GRN ==> Complex RN
+ GI ==> Complex Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ MRN ==> Matrix RN
+
+ MCF ==> Matrix CF
+ MGRN ==> Matrix GRN
+ MCPar ==> Matrix Complex Par
+ SUPGRN ==> SparseUnivariatePolynomial GRN
+ outForm ==> Record(outval:Complex Par,outmult:Integer,outvect:List MCPar)
+
+ C == with
+ characteristicPolynomial : MGRN -> Polynomial GRN
+ ++ characteristicPolynomial(m) returns the characteristic polynomial
+ ++ of the matrix m expressed as polynomial
+ ++ over complex rationals with a new symbol as variable.
+ -- while the function in EigenPackage returns Fraction P GRN.
+ characteristicPolynomial : (MGRN,SE) -> Polynomial GRN
+ ++ characteristicPolynomial(m,x) returns the characteristic polynomial
+ ++ of the matrix m expressed as polynomial
+ ++ over Complex Rationals with variable x.
+ -- while the function in EigenPackage returns Fraction P GRN.
+ complexEigenvalues : (MGRN,Par) -> List Complex Par
+ ++ complexEigenvalues(m,eps) computes the eigenvalues of the matrix
+ ++ m to precision eps. The eigenvalues are expressed as complex floats or
+ ++ complex rational numbers depending on the type of eps (float or rational).
+ complexEigenvectors : (MGRN,Par) -> List(outForm)
+ ++ complexEigenvectors(m,eps) returns a list of
+ ++ records each one containing
+ ++ a complex eigenvalue, its algebraic multiplicity, and a list of
+ ++ associated eigenvectors. All these results
+ ++ are computed to precision eps and are expressed as complex floats
+ ++ or complex rational numbers depending on the type of eps (float or rational).
+ T == add
+
+ import InnerNumericEigenPackage(GRN,Complex Par,Par)
+
+ characteristicPolynomial(m:MGRN) : Polynomial GRN ==
+ x:SE:=new()$SE
+ multivariate(charpol m, x)
+
+ ---- characteristic polynomial of a matrix A ----
+ characteristicPolynomial(A:MGRN,x:SE):Polynomial GRN ==
+ multivariate(charpol A, x)
+
+ complexEigenvalues(m:MGRN,eps:Par) : List Complex Par ==
+ solve1(charpol m, eps)
+
+ complexEigenvectors(m:MGRN,eps:Par) :List outForm ==
+ innerEigenvectors(m,eps,factor$ComplexFactorization(RN,SUPGRN))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INEP InnerNumericEigenPackage>>
+<<package NREP NumericRealEigenPackage>>
+<<package NCEP NumericComplexEigenPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/numeric.spad.pamphlet b/src/algebra/numeric.spad.pamphlet
new file mode 100644
index 00000000..cb575e80
--- /dev/null
+++ b/src/algebra/numeric.spad.pamphlet
@@ -0,0 +1,520 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra numeric.spad}
+\author{Manuel Bronstein, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NUMERIC Numeric}
+<<package NUMERIC Numeric>>=
+)abbrev package NUMERIC Numeric
+++ Author: Manuel Bronstein
+++ Date Created: 21 Feb 1990
+++ Date Last Updated: 17 August 1995, Mike Dewar
+++ 24 January 1997, Miked Dewar (added partial operators)
+++ Basic Operations: numeric, complexNumeric, numericIfCan, complexNumericIfCan
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: Numeric provides real and complex numerical evaluation
+++ functions for various symbolic types.
+
+Numeric(S:ConvertibleTo Float): with
+ numeric: S -> Float
+ ++ numeric(x) returns a real approximation of x.
+ numeric: (S, PositiveInteger) -> Float
+ ++ numeric(x, n) returns a real approximation of x up to n decimal
+ ++ places.
+ complexNumeric: S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x up
+ ++ to n decimal places.
+ if S has CommutativeRing then
+ complexNumeric: Complex S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Complex S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x up
+ ++ to n decimal places.
+ complexNumeric: Polynomial Complex S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Polynomial Complex S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x up
+ ++ to n decimal places.
+ if S has Ring then
+ numeric: Polynomial S -> Float
+ ++ numeric(x) returns a real approximation of x.
+ numeric: (Polynomial S, PositiveInteger) -> Float
+ ++ numeric(x,n) returns a real approximation of x up to n decimal
+ ++ places.
+ complexNumeric: Polynomial S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Polynomial S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x
+ ++ up to n decimal places.
+ if S has IntegralDomain then
+ numeric: Fraction Polynomial S -> Float
+ ++ numeric(x) returns a real approximation of x.
+ numeric: (Fraction Polynomial S, PositiveInteger) -> Float
+ ++ numeric(x,n) returns a real approximation of x up to n decimal
+ ++ places.
+ complexNumeric: Fraction Polynomial S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Fraction Polynomial S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x
+ complexNumeric: Fraction Polynomial Complex S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Fraction Polynomial Complex S, PositiveInteger) ->
+ Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x
+ ++ up to n decimal places.
+ if S has OrderedSet then
+ numeric: Expression S -> Float
+ ++ numeric(x) returns a real approximation of x.
+ numeric: (Expression S, PositiveInteger) -> Float
+ ++ numeric(x, n) returns a real approximation of x up to n
+ ++ decimal places.
+ complexNumeric: Expression S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Expression S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x
+ ++ up to n decimal places.
+ complexNumeric: Expression Complex S -> Complex Float
+ ++ complexNumeric(x) returns a complex approximation of x.
+ complexNumeric: (Expression Complex S, PositiveInteger) -> Complex Float
+ ++ complexNumeric(x, n) returns a complex approximation of x
+ ++ up to n decimal places.
+ if S has CommutativeRing then
+ complexNumericIfCan: Polynomial Complex S -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not constant.
+ complexNumericIfCan: (Polynomial Complex S, PositiveInteger) -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x, n) returns a complex approximation of x up
+ ++ to n decimal places, or "failed" if \axiom{x} is not a constant.
+ if S has Ring then
+ numericIfCan: Polynomial S -> Union(Float,"failed")
+ ++ numericIfCan(x) returns a real approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ numericIfCan: (Polynomial S, PositiveInteger) -> Union(Float,"failed")
+ ++ numericIfCan(x,n) returns a real approximation of x up to n decimal
+ ++ places, or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: Polynomial S -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: (Polynomial S, PositiveInteger) -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x, n) returns a complex approximation of x
+ ++ up to n decimal places, or "failed" if \axiom{x} is not a constant.
+ if S has IntegralDomain then
+ numericIfCan: Fraction Polynomial S -> Union(Float,"failed")
+ ++ numericIfCan(x) returns a real approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ numericIfCan: (Fraction Polynomial S, PositiveInteger) -> Union(Float,"failed")
+ ++ numericIfCan(x,n) returns a real approximation of x up to n decimal
+ ++ places, or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: Fraction Polynomial S -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: (Fraction Polynomial S, PositiveInteger) -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x, n) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: Fraction Polynomial Complex S -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: (Fraction Polynomial Complex S, PositiveInteger) ->
+ Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x, n) returns a complex approximation of x
+ ++ up to n decimal places, or "failed" if \axiom{x} is not a constant.
+ if S has OrderedSet then
+ numericIfCan: Expression S -> Union(Float,"failed")
+ ++ numericIfCan(x) returns a real approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ numericIfCan: (Expression S, PositiveInteger) -> Union(Float,"failed")
+ ++ numericIfCan(x, n) returns a real approximation of x up to n
+ ++ decimal places, or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: Expression S -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: (Expression S, PositiveInteger) ->
+ Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x, n) returns a complex approximation of x
+ ++ up to n decimal places, or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: Expression Complex S -> Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x) returns a complex approximation of x,
+ ++ or "failed" if \axiom{x} is not a constant.
+ complexNumericIfCan: (Expression Complex S, PositiveInteger) ->
+ Union(Complex Float,"failed")
+ ++ complexNumericIfCan(x, n) returns a complex approximation of x
+ ++ up to n decimal places, or "failed" if \axiom{x} is not a constant.
+ == add
+
+ if S has CommutativeRing then
+ complexNumericIfCan(p:Polynomial Complex S) ==
+ p' : Union(Complex(S),"failed") := retractIfCan p
+ p' case "failed" => "failed"
+ complexNumeric(p')
+
+ complexNumericIfCan(p:Polynomial Complex S,n:PositiveInteger) ==
+ p' : Union(Complex(S),"failed") := retractIfCan p
+ p' case "failed" => "failed"
+ complexNumeric(p',n)
+
+ if S has Ring then
+ numericIfCan(p:Polynomial S) ==
+ p' : Union(S,"failed") := retractIfCan p
+ p' case "failed" => "failed"
+ numeric(p')
+
+ complexNumericIfCan(p:Polynomial S) ==
+ p' : Union(S,"failed") := retractIfCan p
+ p' case "failed" => "failed"
+ complexNumeric(p')
+
+ complexNumericIfCan(p:Polynomial S, n:PositiveInteger) ==
+ p' : Union(S,"failed") := retractIfCan p
+ p' case "failed" => "failed"
+ complexNumeric(p', n)
+
+ numericIfCan(p:Polynomial S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := numericIfCan p
+ digits(old)$Float
+ ans
+
+ if S has IntegralDomain then
+ numericIfCan(f:Fraction Polynomial S)==
+ num := numericIfCan(numer(f))
+ num case "failed" => "failed"
+ den := numericIfCan(denom f)
+ den case "failed" => "failed"
+ num/den
+
+ complexNumericIfCan(f:Fraction Polynomial S) ==
+ num := complexNumericIfCan(numer f)
+ num case "failed" => "failed"
+ den := complexNumericIfCan(denom f)
+ den case "failed" => "failed"
+ num/den
+
+ complexNumericIfCan(f:Fraction Polynomial S, n:PositiveInteger) ==
+ num := complexNumericIfCan(numer f, n)
+ num case "failed" => "failed"
+ den := complexNumericIfCan(denom f, n)
+ den case "failed" => "failed"
+ num/den
+
+ numericIfCan(f:Fraction Polynomial S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := numericIfCan f
+ digits(old)$Float
+ ans
+
+ complexNumericIfCan(f:Fraction Polynomial Complex S) ==
+ num := complexNumericIfCan(numer f)
+ num case "failed" => "failed"
+ den := complexNumericIfCan(denom f)
+ den case "failed" => "failed"
+ num/den
+
+ complexNumericIfCan(f:Fraction Polynomial Complex S, n:PositiveInteger) ==
+ num := complexNumericIfCan(numer f, n)
+ num case "failed" => "failed"
+ den := complexNumericIfCan(denom f, n)
+ den case "failed" => "failed"
+ num/den
+
+ if S has OrderedSet then
+ numericIfCan(x:Expression S) ==
+ retractIfCan(map(convert, x)$ExpressionFunctions2(S, Float))
+
+ --s2cs(u:S):Complex(S) == complex(u,0)
+
+ complexNumericIfCan(x:Expression S) ==
+ complexNumericIfCan map(coerce, x)$ExpressionFunctions2(S,Complex S)
+
+ numericIfCan(x:Expression S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Float := map(convert, x)$ExpressionFunctions2(S, Float)
+ ans : Union(Float,"failed") := retractIfCan x'
+ digits(old)$Float
+ ans
+
+ complexNumericIfCan(x:Expression S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Complex S := map(coerce, x)$ExpressionFunctions2(S, Complex S)
+ ans : Union(Complex Float,"failed") := complexNumericIfCan(x')
+ digits(old)$Float
+ ans
+
+ if S has RealConstant then
+ complexNumericIfCan(x:Expression Complex S) ==
+ retractIfCan(map(convert, x)$ExpressionFunctions2(Complex S,Complex Float))
+
+ complexNumericIfCan(x:Expression Complex S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Complex Float :=
+ map(convert, x)$ExpressionFunctions2(Complex S,Complex Float)
+ ans : Union(Complex Float,"failed") := retractIfCan x'
+ digits(old)$Float
+ ans
+ else
+ convert(x:Complex S):Complex(Float)==map(convert,x)$ComplexFunctions2(S,Float)
+
+ complexNumericIfCan(x:Expression Complex S) ==
+ retractIfCan(map(convert, x)$ExpressionFunctions2(Complex S,Complex Float))
+
+ complexNumericIfCan(x:Expression Complex S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Complex Float :=
+ map(convert, x)$ExpressionFunctions2(Complex S,Complex Float)
+ ans : Union(Complex Float,"failed") := retractIfCan x'
+ digits(old)$Float
+ ans
+ numeric(s:S) == convert(s)@Float
+
+ if S has ConvertibleTo Complex Float then
+ complexNumeric(s:S) == convert(s)@Complex(Float)
+
+ complexNumeric(s:S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := complexNumeric s
+ digits(old)$Float
+ ans
+
+ else
+ complexNumeric(s:S) == convert(s)@Float :: Complex(Float)
+
+ complexNumeric(s:S,n:PositiveInteger) ==
+ numeric(s, n)::Complex(Float)
+
+ if S has CommutativeRing then
+ complexNumeric(p:Polynomial Complex S) ==
+ p' : Union(Complex(S),"failed") := retractIfCan p
+ p' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant polynomial"
+ complexNumeric(p')
+
+ complexNumeric(p:Polynomial Complex S,n:PositiveInteger) ==
+ p' : Union(Complex(S),"failed") := retractIfCan p
+ p' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant polynomial"
+ complexNumeric(p',n)
+
+ if S has RealConstant then
+ complexNumeric(s:Complex S) == convert(s)$Complex(S)
+
+ complexNumeric(s:Complex S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := complexNumeric s
+ digits(old)$Float
+ ans
+
+ else if Complex(S) has ConvertibleTo(Complex Float) then
+ complexNumeric(s:Complex S) == convert(s)@Complex(Float)
+
+ complexNumeric(s:Complex S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := complexNumeric s
+ digits(old)$Float
+ ans
+
+ else
+ complexNumeric(s:Complex S) ==
+ s' : Union(S,"failed") := retractIfCan s
+ s' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant object"
+ complexNumeric(s')
+
+ complexNumeric(s:Complex S, n:PositiveInteger) ==
+ s' : Union(S,"failed") := retractIfCan s
+ s' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant object"
+ old := digits(n)$Float
+ ans := complexNumeric s'
+ digits(old)$Float
+ ans
+
+ numeric(s:S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := numeric s
+ digits(old)$Float
+ ans
+
+ if S has Ring then
+ numeric(p:Polynomial S) ==
+ p' : Union(S,"failed") := retractIfCan p
+ p' case "failed" => error
+ "Can only compute the numerical value of a constant, real-valued polynomial"
+ numeric(p')
+
+ complexNumeric(p:Polynomial S) ==
+ p' : Union(S,"failed") := retractIfCan p
+ p' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant polynomial"
+ complexNumeric(p')
+
+ complexNumeric(p:Polynomial S, n:PositiveInteger) ==
+ p' : Union(S,"failed") := retractIfCan p
+ p' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant polynomial"
+ complexNumeric(p', n)
+
+ numeric(p:Polynomial S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := numeric p
+ digits(old)$Float
+ ans
+
+ if S has IntegralDomain then
+ numeric(f:Fraction Polynomial S)==
+ numeric(numer(f)) / numeric(denom f)
+
+ complexNumeric(f:Fraction Polynomial S) ==
+ complexNumeric(numer f)/complexNumeric(denom f)
+
+ complexNumeric(f:Fraction Polynomial S, n:PositiveInteger) ==
+ complexNumeric(numer f, n)/complexNumeric(denom f, n)
+
+ numeric(f:Fraction Polynomial S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ ans := numeric f
+ digits(old)$Float
+ ans
+
+ complexNumeric(f:Fraction Polynomial Complex S) ==
+ complexNumeric(numer f)/complexNumeric(denom f)
+
+ complexNumeric(f:Fraction Polynomial Complex S, n:PositiveInteger) ==
+ complexNumeric(numer f, n)/complexNumeric(denom f, n)
+
+ if S has OrderedSet then
+ numeric(x:Expression S) ==
+ x' : Union(Float,"failed") :=
+ retractIfCan(map(convert, x)$ExpressionFunctions2(S, Float))
+ x' case "failed" => error
+ "Can only compute the numerical value of a constant, real-valued Expression"
+ x'
+
+ complexNumeric(x:Expression S) ==
+ x' : Union(Complex Float,"failed") := retractIfCan(
+ map(complexNumeric, x)$ExpressionFunctions2(S,Complex Float))
+ x' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant expression"
+ x'
+
+ numeric(x:Expression S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Float := map(convert, x)$ExpressionFunctions2(S, Float)
+ ans : Union(Float,"failed") := retractIfCan x'
+ digits(old)$Float
+ ans case "failed" => error
+ "Can only compute the numerical value of a constant, real-valued Expression"
+ ans
+
+ complexNumeric(x:Expression S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Complex Float :=
+ map(complexNumeric, x)$ExpressionFunctions2(S,Complex Float)
+ ans : Union(Complex Float,"failed") := retractIfCan x'
+ digits(old)$Float
+ ans case "failed" =>
+ error "Cannot compute the numerical value of a non-constant expression"
+ ans
+
+ complexNumeric(x:Expression Complex S) ==
+ x' : Union(Complex Float,"failed") := retractIfCan(
+ map(complexNumeric, x)$ExpressionFunctions2(Complex S,Complex Float))
+ x' case "failed" =>
+ error "Cannot compute the numerical value of a non-constant expression"
+ x'
+
+ complexNumeric(x:Expression Complex S, n:PositiveInteger) ==
+ old := digits(n)$Float
+ x' : Expression Complex Float :=
+ map(complexNumeric, x)$ExpressionFunctions2(Complex S,Complex Float)
+ ans : Union(Complex Float,"failed") := retractIfCan x'
+ digits(old)$Float
+ ans case "failed" =>
+ error "Cannot compute the numerical value of a non-constant expression"
+ ans
+
+@
+\section{package DRAWHACK DrawNumericHack}
+<<package DRAWHACK DrawNumericHack>>=
+)abbrev package DRAWHACK DrawNumericHack
+++ Author: Manuel Bronstein
+++ Date Created: 21 Feb 1990
+++ Date Last Updated: 21 Feb 1990
+++ Basic Operations: coerce
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: Hack for the draw interface. DrawNumericHack provides
+++ a "coercion" from something of the form \spad{x = a..b} where \spad{a}
+++ and b are
+++ formal expressions to a binding of the form \spad{x = c..d} where c and d
+++ are the numerical values of \spad{a} and b. This "coercion" fails if
+++ \spad{a} and b contains symbolic variables, but is meant for expressions
+++ involving %pi.
+++ NOTE: This is meant for internal use only.
+
+DrawNumericHack(R:Join(OrderedSet,IntegralDomain,ConvertibleTo Float)):
+ with coerce: SegmentBinding Expression R -> SegmentBinding Float
+ ++ coerce(x = a..b) returns \spad{x = c..d} where c and d are the
+ ++ numerical values of \spad{a} and b.
+ == add
+ coerce s ==
+ map(numeric$Numeric(R),s)$SegmentBindingFunctions2(Expression R, Float)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NUMERIC Numeric>>
+<<package DRAWHACK DrawNumericHack>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/numode.spad.pamphlet b/src/algebra/numode.spad.pamphlet
new file mode 100644
index 00000000..4de1cf27
--- /dev/null
+++ b/src/algebra/numode.spad.pamphlet
@@ -0,0 +1,410 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra numode.spad}
+\author{Yurij Baransky}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NUMODE NumericalOrdinaryDifferentialEquations}
+<<package NUMODE NumericalOrdinaryDifferentialEquations>>=
+)abbrev package NUMODE NumericalOrdinaryDifferentialEquations
+++ Author: Yurij Baransky
+++ Date Created: October 90
+++ Date Last Updated: October 90
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package is a suite of functions for the numerical integration of an
+++ ordinary differential equation of n variables:
+++
+++ \center{dy/dx = f(y,x)\space{5}y is an n-vector}
+++
+++ \par All the routines are based on a 4-th order Runge-Kutta kernel.
+++ These routines generally have as arguments:
+++ n, the number of dependent variables;
+++ x1, the initial point;
+++ h, the step size;
+++ y, a vector of initial conditions of length n which upon exit contains the solution at \spad{x1 + h};
+++ \spad{derivs}, a function which computes the right hand side of the
+++ ordinary differential equation: \spad{derivs(dydx,y,x)} computes \spad{dydx},
+++ a vector which contains the derivative information.
+++
+++ \par In order of increasing complexity:\begin{items}
+++
+++ \item \spad{rk4(y,n,x1,h,derivs)} advances the solution vector to
+++ \spad{x1 + h} and return the values in y.
+++
+++ \item \spad{rk4(y,n,x1,h,derivs,t1,t2,t3,t4)} is the same as
+++ \spad{rk4(y,n,x1,h,derivs)} except that you must provide 4 scratch
+++ arrays t1-t4 of size n.
+++
+++ \item Starting with y at x1, \spad{rk4f(y,n,x1,x2,ns,derivs)}
+++ uses \spad{ns} fixed
+++ steps of a 4-th order Runge-Kutta integrator to advance the
+++ solution vector to x2 and return the values in y.
+++ Argument x2, is the final point, and
+++ \spad{ns}, the number of steps to take.
+++
+++ \item \spad{rk4qc(y,n,x1,step,eps,yscal,derivs)} takes a 5-th order
+++ Runge-Kutta step with monitoring
+++ of local truncation to ensure accuracy and adjust stepsize.
+++ The function takes two half steps and one full step and scales
+++ the difference in solutions at the final point. If the error is
+++ within \spad{eps}, the step is taken and the result is returned.
+++ If the error is not within \spad{eps}, the stepsize if decreased
+++ and the procedure is tried again until the desired accuracy is
+++ reached. Upon input, an trial step size must be given and upon
+++ return, an estimate of the next step size to use is returned as
+++ well as the step size which produced the desired accuracy.
+++ The scaled error is computed as
+++ \center{\spad{error = MAX(ABS((y2steps(i) - y1step(i))/yscal(i)))}}
+++ and this is compared against \spad{eps}. If this is greater
+++ than \spad{eps}, the step size is reduced accordingly to
+++ \center{\spad{hnew = 0.9 * hdid * (error/eps)**(-1/4)}}
+++ If the error criterion is satisfied, then we check if the
+++ step size was too fine and return a more efficient one. If
+++ \spad{error > \spad{eps} * (6.0E-04)} then the next step size should be
+++ \center{\spad{hnext = 0.9 * hdid * (error/\spad{eps})**(-1/5)}}
+++ Otherwise \spad{hnext = 4.0 * hdid} is returned.
+++ A more detailed discussion of this and related topics can be
+++ found in the book "Numerical Recipies" by W.Press, B.P. Flannery,
+++ S.A. Teukolsky, W.T. Vetterling published by Cambridge University Press.
+++ Argument \spad{step} is a record of 3 floating point
+++ numbers \spad{(try , did , next)},
+++ \spad{eps} is the required accuracy,
+++ \spad{yscal} is the scaling vector for the difference in solutions.
+++ On input, \spad{step.try} should be the guess at a step
+++ size to achieve the accuracy.
+++ On output, \spad{step.did} contains the step size which achieved the
+++ accuracy and \spad{step.next} is the next step size to use.
+++
+++ \item \spad{rk4qc(y,n,x1,step,eps,yscal,derivs,t1,t2,t3,t4,t5,t6,t7)} is the
+++ same as \spad{rk4qc(y,n,x1,step,eps,yscal,derivs)} except that the user
+++ must provide the 7 scratch arrays \spad{t1-t7} of size n.
+++
+++ \item \spad{rk4a(y,n,x1,x2,eps,h,ns,derivs)}
+++ is a driver program which uses \spad{rk4qc} to integrate n ordinary
+++ differential equations starting at x1 to x2, keeping the local
+++ truncation error to within \spad{eps} by changing the local step size.
+++ The scaling vector is defined as
+++ \center{\spad{yscal(i) = abs(y(i)) + abs(h*dydx(i)) + tiny}}
+++ where \spad{y(i)} is the solution at location x, \spad{dydx} is the
+++ ordinary differential equation's right hand side, h is the current
+++ step size and \spad{tiny} is 10 times the
+++ smallest positive number representable.
+++ The user must supply an estimate for a trial step size and
+++ the maximum number of calls to \spad{rk4qc} to use.
+++ Argument x2 is the final point,
+++ \spad{eps} is local truncation,
+++ \spad{ns} is the maximum number of call to \spad{rk4qc} to use.
+++ \end{items}
+NumericalOrdinaryDifferentialEquations(): Exports == Implementation where
+ L ==> List
+ V ==> Vector
+ B ==> Boolean
+ I ==> Integer
+ E ==> OutputForm
+ NF ==> Float
+ NNI ==> NonNegativeInteger
+ VOID ==> Void
+ OFORM ==> OutputForm
+ RK4STEP ==> Record(try:NF, did:NF, next:NF)
+
+ Exports ==> with
+--header definitions here
+ rk4 : (V NF,I,NF,NF, (V NF,V NF,NF) -> VOID) -> VOID
+ ++ rk4(y,n,x1,h,derivs) uses a 4-th order Runge-Kutta method
+ ++ to numerically integrate the ordinary differential equation
+ ++ {\em dy/dx = f(y,x)} of n variables, where y is an n-vector.
+ ++ Argument y is a vector of initial conditions of length n which upon exit
+ ++ contains the solution at \spad{x1 + h}, n is the number of dependent
+ ++ variables, x1 is the initial point, h is the step size, and
+ ++ \spad{derivs} is a function which computes the right hand side of the
+ ++ ordinary differential equation.
+ ++ For details, see \spadtype{NumericalOrdinaryDifferentialEquations}.
+ rk4 : (V NF,I,NF,NF, (V NF,V NF,NF) -> VOID
+ ,V NF,V NF,V NF,V NF) -> VOID
+ ++ rk4(y,n,x1,h,derivs,t1,t2,t3,t4) is the same as
+ ++ \spad{rk4(y,n,x1,h,derivs)} except that you must provide 4 scratch
+ ++ arrays t1-t4 of size n.
+ ++ For details, see \con{NumericalOrdinaryDifferentialEquations}.
+ rk4a : (V NF,I,NF,NF,NF,NF,I,(V NF,V NF,NF) -> VOID ) -> VOID
+ ++ rk4a(y,n,x1,x2,eps,h,ns,derivs) is a driver function for the
+ ++ numerical integration of an ordinary differential equation
+ ++ {\em dy/dx = f(y,x)} of n variables, where y is an n-vector
+ ++ using a 4-th order Runge-Kutta method.
+ ++ For details, see \con{NumericalOrdinaryDifferentialEquations}.
+ rk4qc : (V NF,I,NF,RK4STEP,NF,V NF,(V NF,V NF,NF) -> VOID) -> VOID
+ ++ rk4qc(y,n,x1,step,eps,yscal,derivs) is a subfunction for the
+ ++ numerical integration of an ordinary differential equation
+ ++ {\em dy/dx = f(y,x)} of n variables, where y is an n-vector
+ ++ using a 4-th order Runge-Kutta method.
+ ++ This function takes a 5-th order Runge-Kutta step with monitoring
+ ++ of local truncation to ensure accuracy and adjust stepsize.
+ ++ For details, see \con{NumericalOrdinaryDifferentialEquations}.
+ rk4qc : (V NF,I,NF,RK4STEP,NF,V NF,(V NF,V NF,NF) -> VOID
+ ,V NF,V NF,V NF,V NF,V NF,V NF,V NF) -> VOID
+ ++ rk4qc(y,n,x1,step,eps,yscal,derivs,t1,t2,t3,t4,t5,t6,t7) is a subfunction for the
+ ++ numerical integration of an ordinary differential equation
+ ++ {\em dy/dx = f(y,x)} of n variables, where y is an n-vector
+ ++ using a 4-th order Runge-Kutta method.
+ ++ This function takes a 5-th order Runge-Kutta step with monitoring
+ ++ of local truncation to ensure accuracy and adjust stepsize.
+ ++ For details, see \con{NumericalOrdinaryDifferentialEquations}.
+ rk4f : (V NF,I,NF,NF,I,(V NF,V NF,NF) -> VOID ) -> VOID
+ ++ rk4f(y,n,x1,x2,ns,derivs) uses a 4-th order Runge-Kutta method
+ ++ to numerically integrate the ordinary differential equation
+ ++ {\em dy/dx = f(y,x)} of n variables, where y is an n-vector.
+ ++ Starting with y at x1, this function uses \spad{ns} fixed
+ ++ steps of a 4-th order Runge-Kutta integrator to advance the
+ ++ solution vector to x2 and return the values in y.
+ ++ For details, see \con{NumericalOrdinaryDifferentialEquations}.
+
+ Implementation ==> add
+ --some local function definitions here
+ rk4qclocal : (V NF,V NF,I,NF,RK4STEP,NF,V NF,(V NF,V NF,NF) -> VOID
+ ,V NF,V NF,V NF,V NF,V NF,V NF) -> VOID
+ rk4local : (V NF,V NF,I,NF,NF,V NF,(V NF,V NF,NF) -> VOID
+ ,V NF,V NF,V NF) -> VOID
+ import OutputPackage
+
+------------------------------------------------------------
+
+ rk4a(ystart,nvar,x1,x2,eps,htry,nstep,derivs) ==
+ y : V NF := new(nvar::NNI,0.0)
+ yscal : V NF := new(nvar::NNI,1.0)
+ dydx : V NF := new(nvar::NNI,0.0)
+ t1 : V NF := new(nvar::NNI,0.0)
+ t2 : V NF := new(nvar::NNI,0.0)
+ t3 : V NF := new(nvar::NNI,0.0)
+ t4 : V NF := new(nvar::NNI,0.0)
+ t5 : V NF := new(nvar::NNI,0.0)
+ t6 : V NF := new(nvar::NNI,0.0)
+ step : RK4STEP := [htry,0.0,0.0]
+ x : NF := x1
+ tiny : NF := 10.0**(-(digits()+1)::I)
+ m : I := nvar
+ outlist : L OFORM := [x::E,x::E,x::E]
+ i : I
+ iter : I
+
+ eps := 1.0/eps
+ for i in 1..m repeat
+ y(i) := ystart(i)
+ for iter in 1..nstep repeat
+--compute the derivative
+ derivs(dydx,y,x)
+--if overshoot, the set h accordingly
+ if (x + step.try - x2) > 0.0 then
+ step.try := x2 - x
+--find the correct scaling
+ for i in 1..m repeat
+ yscal(i) := abs(y(i)) + abs(step.try * dydx(i)) + tiny
+--take a quality controlled runge-kutta step
+ rk4qclocal(y,dydx,nvar,x,step,eps,yscal,derivs
+ ,t1,t2,t3,t4,t5,t6)
+ x := x + step.did
+-- outlist.0 := x::E
+-- outlist.1 := y(0)::E
+-- outlist.2 := y(1)::E
+-- output(blankSeparate(outlist)::E)
+--check to see if done
+ if (x-x2) >= 0.0 then
+ leave
+--next stepsize to use
+ step.try := step.next
+--end nstep repeat
+ if iter = (nstep+1) then
+ output("ode: ERROR ")
+ outlist.1 := nstep::E
+ outlist.2 := " steps to small, last h = "::E
+ outlist.3 := step.did::E
+ output(blankSeparate(outlist))
+ output(" y= ",y::E)
+ for i in 1..m repeat
+ ystart(i) := y(i)
+
+----------------------------------------------------------------
+
+ rk4qc(y,n,x,step,eps,yscal,derivs) ==
+ t1 : V NF := new(n::NNI,0.0)
+ t2 : V NF := new(n::NNI,0.0)
+ t3 : V NF := new(n::NNI,0.0)
+ t4 : V NF := new(n::NNI,0.0)
+ t5 : V NF := new(n::NNI,0.0)
+ t6 : V NF := new(n::NNI,0.0)
+ t7 : V NF := new(n::NNI,0.0)
+ derivs(t7,y,x)
+ eps := 1.0/eps
+ rk4qclocal(y,t7,n,x,step,eps,yscal,derivs,t1,t2,t3,t4,t5,t6)
+
+--------------------------------------------------------
+
+ rk4qc(y,n,x,step,eps,yscal,derivs,t1,t2,t3,t4,t5,t6,dydx) ==
+ derivs(dydx,y,x)
+ eps := 1.0/eps
+ rk4qclocal(y,dydx,n,x,step,eps,yscal,derivs,t1,t2,t3,t4,t5,t6)
+
+--------------------------------------------------------
+
+ rk4qclocal(y,dydx,n,x,step,eps,yscal,derivs
+ ,t1,t2,t3,ysav,dysav,ytemp) ==
+ xsav : NF := x
+ h : NF := step.try
+ fcor : NF := 1.0/15.0
+ safety : NF := 0.9
+ grow : NF := -0.20
+ shrink : NF := -0.25
+ errcon : NF := 0.6E-04 --(this is 4/safety)**(1/grow)
+ hh : NF
+ errmax : NF
+ i : I
+ m : I := n
+--
+ for i in 1..m repeat
+ dysav(i) := dydx(i)
+ ysav(i) := y(i)
+--cut down step size till error criterion is met
+ repeat
+--take two little steps to get to x + h
+ hh := 0.5 * h
+ rk4local(ysav,dysav,n,xsav,hh,ytemp,derivs,t1,t2,t3)
+ x := xsav + hh
+ derivs(dydx,ytemp,x)
+ rk4local(ytemp,dydx,n,x,hh,y,derivs,t1,t2,t3)
+ x := xsav + h
+--take one big step get to x + h
+ rk4local(ysav,dysav,n,xsav,h,ytemp,derivs,t1,t2,t3)
+
+--compute the maximum scaled difference
+ errmax := 0.0
+ for i in 1..m repeat
+ ytemp(i) := y(i) - ytemp(i)
+ errmax := max(errmax,abs(ytemp(i)/yscal(i)))
+--scale relative to required accuracy
+ errmax := errmax * eps
+--update integration stepsize
+ if (errmax > 1.0) then
+ h := safety * h * (errmax ** shrink)
+ else
+ step.did := h
+ if errmax > errcon then
+ step.next := safety * h * (errmax ** grow)
+ else
+ step.next := 4 * h
+ leave
+--make fifth order with 4-th order error estimate
+ for i in 1..m repeat
+ y(i) := y(i) + ytemp(i) * fcor
+
+--------------------------------------------
+
+ rk4f(y,nvar,x1,x2,nstep,derivs) ==
+ yt : V NF := new(nvar::NNI,0.0)
+ dyt : V NF := new(nvar::NNI,0.0)
+ dym : V NF := new(nvar::NNI,0.0)
+ dydx : V NF := new(nvar::NNI,0.0)
+ ynew : V NF := new(nvar::NNI,0.0)
+ h : NF := (x2-x1) / (nstep::NF)
+ x : NF := x1
+ i : I
+ j : I
+-- start integrating
+ for i in 1..nstep repeat
+ derivs(dydx,y,x)
+ rk4local(y,dydx,nvar,x,h,y,derivs,yt,dyt,dym)
+ x := x + h
+
+--------------------------------------------------------
+
+ rk4(y,n,x,h,derivs) ==
+ t1 : V NF := new(n::NNI,0.0)
+ t2 : V NF := new(n::NNI,0.0)
+ t3 : V NF := new(n::NNI,0.0)
+ t4 : V NF := new(n::NNI,0.0)
+ derivs(t1,y,x)
+ rk4local(y,t1,n,x,h,y,derivs,t2,t3,t4)
+
+------------------------------------------------------------
+
+ rk4(y,n,x,h,derivs,t1,t2,t3,t4) ==
+ derivs(t1,y,x)
+ rk4local(y,t1,n,x,h,y,derivs,t2,t3,t4)
+
+------------------------------------------------------------
+
+ rk4local(y,dydx,n,x,h,yout,derivs,yt,dyt,dym) ==
+ hh : NF := h*0.5
+ h6 : NF := h/6.0
+ xh : NF := x+hh
+ m : I := n
+ i : I
+-- first step
+ for i in 1..m repeat
+ yt(i) := y(i) + hh*dydx(i)
+-- second step
+ derivs(dyt,yt,xh)
+ for i in 1..m repeat
+ yt(i) := y(i) + hh*dyt(i)
+-- third step
+ derivs(dym,yt,xh)
+ for i in 1..m repeat
+ yt(i) := y(i) + h*dym(i)
+ dym(i) := dyt(i) + dym(i)
+-- fourth step
+ derivs(dyt,yt,x+h)
+ for i in 1..m repeat
+ yout(i) := y(i) + h6*( dydx(i) + 2.0*dym(i) + dyt(i) )
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NUMODE NumericalOrdinaryDifferentialEquations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/numquad.spad.pamphlet b/src/algebra/numquad.spad.pamphlet
new file mode 100644
index 00000000..79987429
--- /dev/null
+++ b/src/algebra/numquad.spad.pamphlet
@@ -0,0 +1,600 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra numquad.spad}
+\author{Yurij Baransky}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NUMQUAD NumericalQuadrature}
+<<package NUMQUAD NumericalQuadrature>>=
+)abbrev package NUMQUAD NumericalQuadrature
+++ Author: Yurij A. Baransky
+++ Date Created: October 90
+++ Date Last Updated: October 90
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This suite of routines performs numerical quadrature using
+++ algorithms derived from the basic trapezoidal rule. Because
+++ the error term of this rule contains only even powers of the
+++ step size (for open and closed versions), fast convergence
+++ can be obtained if the integrand is sufficiently smooth.
+++
+++ Each routine returns a Record of type TrapAns, which contains\indent{3}
+++ \newline value (\spadtype{Float}):\tab{20} estimate of the integral
+++ \newline error (\spadtype{Float}):\tab{20} estimate of the error in the computation
+++ \newline totalpts (\spadtype{Integer}):\tab{20} total number of function evaluations
+++ \newline success (\spadtype{Boolean}):\tab{20} if the integral was computed within the user specified error criterion
+++ \indent{0}\indent{0}
+++ To produce this estimate, each routine generates an internal
+++ sequence of sub-estimates, denoted by {\em S(i)}, depending on the
+++ routine, to which the various convergence criteria are applied.
+++ The user must supply a relative accuracy, \spad{eps_r}, and an absolute
+++ accuracy, \spad{eps_a}. Convergence is obtained when either
+++ \center{\spad{ABS(S(i) - S(i-1)) < eps_r * ABS(S(i-1))}}
+++ \center{or \spad{ABS(S(i) - S(i-1)) < eps_a}}
+++ are true statements.
+++
+++ The routines come in three families and three flavors:
+++ \newline\tab{3} closed:\tab{20}romberg,\tab{30}simpson,\tab{42}trapezoidal
+++ \newline\tab{3} open: \tab{20}rombergo,\tab{30}simpsono,\tab{42}trapezoidalo
+++ \newline\tab{3} adaptive closed:\tab{20}aromberg,\tab{30}asimpson,\tab{42}atrapezoidal
+++ \par
+++ The {\em S(i)} for the trapezoidal family is the value of the
+++ integral using an equally spaced absicca trapezoidal rule for
+++ that level of refinement.
+++ \par
+++ The {\em S(i)} for the simpson family is the value of the integral
+++ using an equally spaced absicca simpson rule for that level of
+++ refinement.
+++ \par
+++ The {\em S(i)} for the romberg family is the estimate of the integral
+++ using an equally spaced absicca romberg method. For
+++ the \spad{i}-th level, this is an appropriate combination of all the
+++ previous trapezodial estimates so that the error term starts
+++ with the \spad{2*(i+1)} power only.
+++ \par
+++ The three families come in a closed version, where the formulas
+++ include the endpoints, an open version where the formulas do not
+++ include the endpoints and an adaptive version, where the user
+++ is required to input the number of subintervals over which the
+++ appropriate closed family integrator will apply with the usual
+++ convergence parmeters for each subinterval. This is useful
+++ where a large number of points are needed only in a small fraction
+++ of the entire domain.
+++ \par
+++ Each routine takes as arguments:
+++ \newline f\tab{10} integrand
+++ \newline a\tab{10} starting point
+++ \newline b\tab{10} ending point
+++ \newline \spad{eps_r}\tab{10} relative error
+++ \newline \spad{eps_a}\tab{10} absolute error
+++ \newline \spad{nmin} \tab{10} refinement level when to start checking for convergence (> 1)
+++ \newline \spad{nmax} \tab{10} maximum level of refinement
+++ \par
+++ The adaptive routines take as an additional parameter
+++ \newline \spad{nint}\tab{10} the number of independent intervals to apply a closed
+++ family integrator of the same name.
+++ \par Notes:
+++ \newline Closed family level i uses \spad{1 + 2**i} points.
+++ \newline Open family level i uses \spad{1 + 3**i} points.
+NumericalQuadrature(): Exports == Implementation where
+ L ==> List
+ V ==> Vector
+ I ==> Integer
+ B ==> Boolean
+ E ==> OutputForm
+ F ==> Float
+ PI ==> PositiveInteger
+ OFORM ==> OutputForm
+ TrapAns ==> Record(value:F, error:F, totalpts:I, success:B )
+
+ Exports ==> with
+ aromberg : (F -> F,F,F,F,F,I,I,I) -> TrapAns
+ ++ aromberg(fn,a,b,epsrel,epsabs,nmin,nmax,nint)
+ ++ uses the adaptive romberg method to numerically integrate function
+ ++ \spad{fn} over the closed interval from \spad{a} to \spad{b},
+ ++ with relative accuracy \spad{epsrel} and absolute accuracy
+ ++ \spad{epsabs}, with the refinement levels for convergence checking
+ ++ vary from \spad{nmin} to \spad{nmax}, and where \spad{nint}
+ ++ is the number of independent intervals to apply the integrator.
+ ++ The value returned is a record containing the value of the integral,
+ ++ the estimate of the error in the computation, the total number of
+ ++ function evaluations, and either a boolean value which is true if
+ ++ the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ asimpson : (F -> F,F,F,F,F,I,I,I) -> TrapAns
+ ++ asimpson(fn,a,b,epsrel,epsabs,nmin,nmax,nint) uses the
+ ++ adaptive simpson method to numerically integrate function \spad{fn}
+ ++ over the closed interval from \spad{a} to \spad{b}, with relative
+ ++ accuracy \spad{epsrel} and absolute accuracy \spad{epsabs}, with the
+ ++ refinement levels for convergence checking vary from \spad{nmin}
+ ++ to \spad{nmax}, and where \spad{nint} is the number of independent
+ ++ intervals to apply the integrator. The value returned is a record
+ ++ containing the value of the integral, the estimate of the error in
+ ++ the computation, the total number of function evaluations, and
+ ++ either a boolean value which is true if the integral was computed
+ ++ within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ atrapezoidal : (F -> F,F,F,F,F,I,I,I) -> TrapAns
+ ++ atrapezoidal(fn,a,b,epsrel,epsabs,nmin,nmax,nint) uses the
+ ++ adaptive trapezoidal method to numerically integrate function
+ ++ \spad{fn} over the closed interval from \spad{a} to \spad{b}, with
+ ++ relative accuracy \spad{epsrel} and absolute accuracy \spad{epsabs},
+ ++ with the refinement levels for convergence checking vary from
+ ++ \spad{nmin} to \spad{nmax}, and where \spad{nint} is the number
+ ++ of independent intervals to apply the integrator. The value returned
+ ++ is a record containing the value of the integral, the estimate of
+ ++ the error in the computation, the total number of function
+ ++ evaluations, and either a boolean value which is true if
+ ++ the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ romberg : (F -> F,F,F,F,F,I,I) -> TrapAns
+ ++ romberg(fn,a,b,epsrel,epsabs,nmin,nmax) uses the romberg
+ ++ method to numerically integrate function \spadvar{fn} over the closed
+ ++ interval \spad{a} to \spad{b}, with relative accuracy \spad{epsrel}
+ ++ and absolute accuracy \spad{epsabs}, with the refinement levels
+ ++ for convergence checking vary from \spad{nmin} to \spad{nmax}.
+ ++ The value returned is a record containing the value
+ ++ of the integral, the estimate of the error in the computation, the
+ ++ total number of function evaluations, and either a boolean value
+ ++ which is true if the integral was computed within the user specified
+ ++ error criterion. See \spadtype{NumericalQuadrature} for details.
+ simpson : (F -> F,F,F,F,F,I,I) -> TrapAns
+ ++ simpson(fn,a,b,epsrel,epsabs,nmin,nmax) uses the simpson
+ ++ method to numerically integrate function \spad{fn} over the closed
+ ++ interval \spad{a} to \spad{b}, with
+ ++ relative accuracy \spad{epsrel} and absolute accuracy \spad{epsabs},
+ ++ with the refinement levels for convergence checking vary from
+ ++ \spad{nmin} to \spad{nmax}. The value returned
+ ++ is a record containing the value of the integral, the estimate of
+ ++ the error in the computation, the total number of function
+ ++ evaluations, and either a boolean value which is true if
+ ++ the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ trapezoidal : (F -> F,F,F,F,F,I,I) -> TrapAns
+ ++ trapezoidal(fn,a,b,epsrel,epsabs,nmin,nmax) uses the
+ ++ trapezoidal method to numerically integrate function \spadvar{fn} over
+ ++ the closed interval \spad{a} to \spad{b}, with relative accuracy
+ ++ \spad{epsrel} and absolute accuracy \spad{epsabs}, with the
+ ++ refinement levels for convergence checking vary
+ ++ from \spad{nmin} to \spad{nmax}. The value
+ ++ returned is a record containing the value of the integral, the
+ ++ estimate of the error in the computation, the total number of
+ ++ function evaluations, and either a boolean value which is true
+ ++ if the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ rombergo : (F -> F,F,F,F,F,I,I) -> TrapAns
+ ++ rombergo(fn,a,b,epsrel,epsabs,nmin,nmax) uses the romberg
+ ++ method to numerically integrate function \spad{fn} over
+ ++ the open interval from \spad{a} to \spad{b}, with
+ ++ relative accuracy \spad{epsrel} and absolute accuracy \spad{epsabs},
+ ++ with the refinement levels for convergence checking vary from
+ ++ \spad{nmin} to \spad{nmax}. The value returned
+ ++ is a record containing the value of the integral, the estimate of
+ ++ the error in the computation, the total number of function
+ ++ evaluations, and either a boolean value which is true if
+ ++ the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ simpsono : (F -> F,F,F,F,F,I,I) -> TrapAns
+ ++ simpsono(fn,a,b,epsrel,epsabs,nmin,nmax) uses the
+ ++ simpson method to numerically integrate function \spad{fn} over
+ ++ the open interval from \spad{a} to \spad{b}, with
+ ++ relative accuracy \spad{epsrel} and absolute accuracy \spad{epsabs},
+ ++ with the refinement levels for convergence checking vary from
+ ++ \spad{nmin} to \spad{nmax}. The value returned
+ ++ is a record containing the value of the integral, the estimate of
+ ++ the error in the computation, the total number of function
+ ++ evaluations, and either a boolean value which is true if
+ ++ the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+ trapezoidalo : (F -> F,F,F,F,F,I,I) -> TrapAns
+ ++ trapezoidalo(fn,a,b,epsrel,epsabs,nmin,nmax) uses the
+ ++ trapezoidal method to numerically integrate function \spad{fn}
+ ++ over the open interval from \spad{a} to \spad{b}, with
+ ++ relative accuracy \spad{epsrel} and absolute accuracy \spad{epsabs},
+ ++ with the refinement levels for convergence checking vary from
+ ++ \spad{nmin} to \spad{nmax}. The value returned
+ ++ is a record containing the value of the integral, the estimate of
+ ++ the error in the computation, the total number of function
+ ++ evaluations, and either a boolean value which is true if
+ ++ the integral was computed within the user specified error criterion.
+ ++ See \spadtype{NumericalQuadrature} for details.
+
+ Implementation ==> add
+ trapclosed : (F -> F,F,F,F,I) -> F
+ trapopen : (F -> F,F,F,F,I) -> F
+ import OutputPackage
+
+---------------------------------------------------
+
+ aromberg(func,a,b,epsrel,epsabs,nmin,nmax,nint) ==
+ ans : TrapAns
+ sum : F := 0.0
+ err : F := 0.0
+ pts : I := 1
+ done : B := true
+ hh : F := (b-a) / nint
+ x1 : F := a
+ x2 : F := a + hh
+ io : L OFORM := [x1::E,x2::E]
+ i : I
+ for i in 1..nint repeat
+ ans := romberg(func,x1,x2,epsrel,epsabs,nmin,nmax)
+ if (not ans.success) then
+ io.1 := x1::E
+ io.2 := x2::E
+ print blankSeparate cons("accuracy not reached in interval"::E,io)
+ sum := sum + ans.value
+ err := err + abs(ans.error)
+ pts := pts + ans.totalpts-1
+ done := (done and ans.success)
+ x1 := x2
+ x2 := x2 + hh
+ return( [sum , err , pts , done] )
+
+---------------------------------------------------
+
+ asimpson(func,a,b,epsrel,epsabs,nmin,nmax,nint) ==
+ ans : TrapAns
+ sum : F := 0.0
+ err : F := 0.0
+ pts : I := 1
+ done : B := true
+ hh : F := (b-a) / nint
+ x1 : F := a
+ x2 : F := a + hh
+ io : L OFORM := [x1::E,x2::E]
+ i : I
+ for i in 1..nint repeat
+ ans := simpson(func,x1,x2,epsrel,epsabs,nmin,nmax)
+ if (not ans.success) then
+ io.1 := x1::E
+ io.2 := x2::E
+ print blankSeparate cons("accuracy not reached in interval"::E,io)
+ sum := sum + ans.value
+ err := err + abs(ans.error)
+ pts := pts + ans.totalpts-1
+ done := (done and ans.success)
+ x1 := x2
+ x2 := x2 + hh
+ return( [sum , err , pts , done] )
+
+---------------------------------------------------
+
+ atrapezoidal(func,a,b,epsrel,epsabs,nmin,nmax,nint) ==
+ ans : TrapAns
+ sum : F := 0.0
+ err : F := 0.0
+ pts : I := 1
+ i : I
+ done : B := true
+ hh : F := (b-a) / nint
+ x1 : F := a
+ x2 : F := a + hh
+ io : L OFORM := [x1::E,x2::E]
+ for i in 1..nint repeat
+ ans := trapezoidal(func,x1,x2,epsrel,epsabs,nmin,nmax)
+ if (not ans.success) then
+ io.1 := x1::E
+ io.2 := x2::E
+ print blankSeparate cons("accuracy not reached in interval"::E,io)
+ sum := sum + ans.value
+ err := err + abs(ans.error)
+ pts := pts + ans.totalpts-1
+ done := (done and ans.success)
+ x1 := x2
+ x2 := x2 + hh
+ return( [sum , err , pts , done] )
+
+---------------------------------------------------
+
+ romberg(func,a,b,epsrel,epsabs,nmin,nmax) ==
+ length : F := (b-a)
+ delta : F := length
+ newsum : F := 0.5 * length * (func(a)+func(b))
+ newest : F := 0.0
+ oldsum : F := 0.0
+ oldest : F := 0.0
+ change : F := 0.0
+ qx1 : F := newsum
+ table : V F := new((nmax+1)::PI,0.0)
+ n : I := 1
+ pts : I := 1
+ four : I
+ j : I
+ i : I
+ if (nmin < 2) then
+ output("romberg: nmin to small (nmin > 1) nmin = ",nmin::E)
+ return([0.0,0.0,0,false])
+ if (nmax < nmin) then
+ output("romberg: nmax < nmin : nmax = ",nmax::E)
+ output(" nmin = ",nmin::E)
+ return([0.0,0.0,0,false])
+ if (a = b) then
+ output("romberg: integration limits are equal = ",a::E)
+ return([0.0,0.0,1,true])
+ if (epsrel < 0.0) then
+ output("romberg: eps_r < 0.0 eps_r = ",epsrel::E)
+ return([0.0,0.0,0,false])
+ if (epsabs < 0.0) then
+ output("romberg: eps_a < 0.0 eps_a = ",epsabs::E)
+ return([0.0,0.0,0,false])
+ for n in 1..nmax repeat
+ oldsum := newsum
+ newsum := trapclosed(func,a,delta,oldsum,pts)
+ newest := (4.0 * newsum - oldsum) / 3.0
+ four := 4
+ table(n) := newest
+ for j in 2..n repeat
+ i := n+1-j
+ four := four * 4
+ table(i) := table(i+1) + (table(i+1)-table(i)) / (four-1)
+ if n > nmin then
+ change := abs(table(1) - qx1)
+ if change < abs(epsrel*qx1) then
+ return( [table(1) , change , 2*pts+1 , true] )
+ if change < epsabs then
+ return( [table(1) , change , 2*pts+1 , true] )
+ oldsum := newsum
+ oldest := newest
+ delta := 0.5*delta
+ pts := 2*pts
+ qx1 := table(1)
+ return( [table(1) , 1.25*change , pts+1 ,false] )
+
+---------------------------------------------------
+
+ simpson(func,a,b,epsrel,epsabs,nmin,nmax) ==
+ length : F := (b-a)
+ delta : F := length
+ newsum : F := 0.5*(b-a)*(func(a)+func(b))
+ newest : F := 0.0
+ oldsum : F := 0.0
+ oldest : F := 0.0
+ change : F := 0.0
+ n : I := 1
+ pts : I := 1
+ if (nmin < 2) then
+ output("simpson: nmin to small (nmin > 1) nmin = ",nmin::E)
+ return([0.0,0.0,0,false])
+ if (nmax < nmin) then
+ output("simpson: nmax < nmin : nmax = ",nmax::E)
+ output(" nmin = ",nmin::E)
+ return([0.0,0.0,0,false])
+ if (a = b) then
+ output("simpson: integration limits are equal = ",a::E)
+ return([0.0,0.0,1,true])
+ if (epsrel < 0.0) then
+ output("simpson: eps_r < 0.0 : eps_r = ",epsrel::E)
+ return([0.0,0.0,0,false])
+ if (epsabs < 0.0) then
+ output("simpson: eps_a < 0.0 : eps_a = ",epsabs::E)
+ return([0.0,0.0,0,false])
+ for n in 1..nmax repeat
+ oldsum := newsum
+ newsum := trapclosed(func,a,delta,oldsum,pts)
+ newest := (4.0 * newsum - oldsum) / 3.0
+ if n > nmin then
+ change := abs(newest-oldest)
+ if change < abs(epsrel*oldest) then
+ return( [newest , 1.25*change , 2*pts+1 , true] )
+ if change < epsabs then
+ return( [newest , 1.25*change , 2*pts+1 , true] )
+ oldsum := newsum
+ oldest := newest
+ delta := 0.5*delta
+ pts := 2*pts
+ return( [newest , 1.25*change , pts+1 ,false] )
+
+---------------------------------------------------
+
+ trapezoidal(func,a,b,epsrel,epsabs,nmin,nmax) ==
+ length : F := (b-a)
+ delta : F := length
+ newsum : F := 0.5*(b-a)*(func(a)+func(b))
+ change : F := 0.0
+ oldsum : F
+ n : I := 1
+ pts : I := 1
+ if (nmin < 2) then
+ output("trapezoidal: nmin to small (nmin > 1) nmin = ",nmin::E)
+ return([0.0,0.0,0,false])
+ if (nmax < nmin) then
+ output("trapezoidal: nmax < nmin : nmax = ",nmax::E)
+ output(" nmin = ",nmin::E)
+ return([0.0,0.0,0,false])
+ if (a = b) then
+ output("trapezoidal: integration limits are equal = ",a::E)
+ return([0.0,0.0,1,true])
+ if (epsrel < 0.0) then
+ output("trapezoidal: eps_r < 0.0 : eps_r = ",epsrel::E)
+ return([0.0,0.0,0,false])
+ if (epsabs < 0.0) then
+ output("trapezoidal: eps_a < 0.0 : eps_a = ",epsabs::E)
+ return([0.0,0.0,0,false])
+ for n in 1..nmax repeat
+ oldsum := newsum
+ newsum := trapclosed(func,a,delta,oldsum,pts)
+ if n > nmin then
+ change := abs(newsum-oldsum)
+ if change < abs(epsrel*oldsum) then
+ return( [newsum , 1.25*change , 2*pts+1 , true] )
+ if change < epsabs then
+ return( [newsum , 1.25*change , 2*pts+1 , true] )
+ delta := 0.5*delta
+ pts := 2*pts
+ return( [newsum , 1.25*change , pts+1 ,false] )
+
+---------------------------------------------------
+
+ rombergo(func,a,b,epsrel,epsabs,nmin,nmax) ==
+ length : F := (b-a)
+ delta : F := length / 3.0
+ newsum : F := length * func( 0.5*(a+b) )
+ newest : F := 0.0
+ oldsum : F := 0.0
+ oldest : F := 0.0
+ change : F := 0.0
+ qx1 : F := newsum
+ table : V F := new((nmax+1)::PI,0.0)
+ four : I
+ j : I
+ i : I
+ n : I := 1
+ pts : I := 1
+ for n in 1..nmax repeat
+ oldsum := newsum
+ newsum := trapopen(func,a,delta,oldsum,pts)
+ newest := (9.0 * newsum - oldsum) / 8.0
+ table(n) := newest
+ nine := 9
+ output(newest::E)
+ for j in 2..n repeat
+ i := n+1-j
+ nine := nine * 9
+ table(i) := table(i+1) + (table(i+1)-table(i)) / (nine-1)
+ if n > nmin then
+ change := abs(table(1) - qx1)
+ if change < abs(epsrel*qx1) then
+ return( [table(1) , 1.5*change , 3*pts , true] )
+ if change < epsabs then
+ return( [table(1) , 1.5*change , 3*pts , true] )
+ output(table::E)
+ oldsum := newsum
+ oldest := newest
+ delta := delta / 3.0
+ pts := 3*pts
+ qx1 := table(1)
+ return( [table(1) , 1.5*change , pts ,false] )
+
+---------------------------------------------------
+
+ simpsono(func,a,b,epsrel,epsabs,nmin,nmax) ==
+ length : F := (b-a)
+ delta : F := length / 3.0
+ newsum : F := length * func( 0.5*(a+b) )
+ newest : F := 0.0
+ oldsum : F := 0.0
+ oldest : F := 0.0
+ change : F := 0.0
+ n : I := 1
+ pts : I := 1
+ for n in 1..nmax repeat
+ oldsum := newsum
+ newsum := trapopen(func,a,delta,oldsum,pts)
+ newest := (9.0 * newsum - oldsum) / 8.0
+ output(newest::E)
+ if n > nmin then
+ change := abs(newest - oldest)
+ if change < abs(epsrel*oldest) then
+ return( [newest , 1.5*change , 3*pts , true] )
+ if change < epsabs then
+ return( [newest , 1.5*change , 3*pts , true] )
+ oldsum := newsum
+ oldest := newest
+ delta := delta / 3.0
+ pts := 3*pts
+ return( [newest , 1.5*change , pts ,false] )
+
+---------------------------------------------------
+
+ trapezoidalo(func,a,b,epsrel,epsabs,nmin,nmax) ==
+ length : F := (b-a)
+ delta : F := length/3.0
+ newsum : F := length*func( 0.5*(a+b) )
+ change : F := 0.0
+ pts : I := 1
+ oldsum : F
+ n : I
+ for n in 1..nmax repeat
+ oldsum := newsum
+ newsum := trapopen(func,a,delta,oldsum,pts)
+ output(newsum::E)
+ if n > nmin then
+ change := abs(newsum-oldsum)
+ if change < abs(epsrel*oldsum) then
+ return([newsum , 1.5*change , 3*pts , true] )
+ if change < epsabs then
+ return([newsum , 1.5*change , 3*pts , true] )
+ delta := delta / 3.0
+ pts := 3*pts
+ return([newsum , 1.5*change , pts ,false] )
+
+---------------------------------------------------
+
+ trapclosed(func,start,h,oldsum,numpoints) ==
+ x : F := start + 0.5*h
+ sum : F := 0.0
+ i : I
+ for i in 1..numpoints repeat
+ sum := sum + func(x)
+ x := x + h
+ return( 0.5*(oldsum + sum*h) )
+
+---------------------------------------------------
+
+ trapopen(func,start,del,oldsum,numpoints) ==
+ ddel : F := 2.0*del
+ x : F := start + 0.5*del
+ sum : F := 0.0
+ i : I
+ for i in 1..numpoints repeat
+ sum := sum + func(x)
+ x := x + ddel
+ sum := sum + func(x)
+ x := x + del
+ return( (oldsum/3.0 + sum*del) )
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NUMQUAD NumericalQuadrature>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/numsolve.spad.pamphlet b/src/algebra/numsolve.spad.pamphlet
new file mode 100644
index 00000000..b640b925
--- /dev/null
+++ b/src/algebra/numsolve.spad.pamphlet
@@ -0,0 +1,485 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra numsolve.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INFSP InnerNumericFloatSolvePackage}
+<<package INFSP InnerNumericFloatSolvePackage>>=
+)abbrev package INFSP InnerNumericFloatSolvePackage
+++ Author: P. Gianni
+++ Date Created: January 1990
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is an internal package
+++ for computing approximate solutions to systems of polynomial equations.
+++ The parameter K specifies the coefficient field of the input polynomials
+++ and must be either \spad{Fraction(Integer)} or \spad{Complex(Fraction Integer)}.
+++ The parameter F specifies where the solutions must lie and can
+++ be one of the following: \spad{Float}, \spad{Fraction(Integer)}, \spad{Complex(Float)},
+++ \spad{Complex(Fraction Integer)}. The last parameter specifies the type
+++ of the precision operand and must be either \spad{Fraction(Integer)} or \spad{Float}.
+InnerNumericFloatSolvePackage(K,F,Par): Cat == Cap where
+ F : Field -- this is the field where the answer will be
+ K : GcdDomain -- type of the input
+ Par : Join(Field, OrderedRing ) -- it will be NF or RN
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ P ==> Polynomial
+ EQ ==> Equation
+ L ==> List
+ SUP ==> SparseUnivariatePolynomial
+ RN ==> Fraction Integer
+ NF ==> Float
+ CF ==> Complex Float
+ GI ==> Complex Integer
+ GRN ==> Complex RN
+ SE ==> Symbol
+ RFI ==> Fraction P I
+
+ Cat == with
+
+ innerSolve1 : (SUP K,Par) -> L F
+ ++ innerSolve1(up,eps) returns the list of the zeros
+ ++ of the univariate polynomial up with precision eps.
+ innerSolve1 : (P K,Par) -> L F
+ ++ innerSolve1(p,eps) returns the list of the zeros
+ ++ of the polynomial p with precision eps.
+ innerSolve : (L P K,L P K,L SE,Par) -> L L F
+ ++ innerSolve(lnum,lden,lvar,eps) returns a list of
+ ++ solutions of the system of polynomials lnum, with
+ ++ the side condition that none of the members of lden
+ ++ vanish identically on any solution. Each solution
+ ++ is expressed as a list corresponding to the list of
+ ++ variables in lvar and with precision specified by eps.
+ makeEq : (L F,L SE) -> L EQ P F
+ ++ makeEq(lsol,lvar) returns a list of equations formed
+ ++ by corresponding members of lvar and lsol.
+
+ Cap == add
+
+ ------ Local Functions ------
+ isGeneric? : (L P K,L SE) -> Boolean
+ evaluate : (P K,SE,SE,F) -> F
+ numeric : K -> F
+ oldCoord : (L F,L I) -> L F
+ findGenZeros : (L P K,L SE,Par) -> L L F
+ failPolSolve : (L P K,L SE) -> Union(L L P K,"failed")
+
+ numeric(r:K):F ==
+ K is I =>
+ F is Float => r::I::Float
+ F is RN => r::I::RN
+ F is CF => r::I::CF
+ F is GRN => r::I::GRN
+ K is GI =>
+ gr:GI := r::GI
+ F is GRN => complex(real(gr)::RN,imag(gr)::RN)$GRN
+ F is CF => convert(gr)
+ error "case not handled"
+
+ -- construct the equation
+ makeEq(nres:L F,lv:L SE) : L EQ P F ==
+ [equation(x::(P F),r::(P F)) for x in lv for r in nres]
+
+ evaluate(pol:P K,xvar:SE,zvar:SE,z:F):F ==
+ rpp:=map(numeric,pol)$PolynomialFunctions2(K,F)
+ rpp := eval(rpp,zvar,z)
+ upol:=univariate(rpp,xvar)
+ retract(-coefficient(upol,0))/retract(leadingCoefficient upol)
+
+ myConvert(eps:Par) : RN ==
+ Par is RN => eps
+ Par is NF => retract(eps)$NF
+
+ innerSolve1(pol:P K,eps:Par) : L F == innerSolve1(univariate pol,eps)
+
+ innerSolve1(upol:SUP K,eps:Par) : L F ==
+ K is GI and (Par is RN or Par is NF) =>
+ (complexZeros(upol,
+ eps)$ComplexRootPackage(SUP K,Par)) pretend L(F)
+ K is I =>
+ F is Float =>
+ z:= realZeros(upol,myConvert eps)$RealZeroPackage(SUP I)
+ [convert((1/2)*(x.left+x.right))@Float for x in z] pretend L(F)
+
+ F is RN =>
+ z:= realZeros(upol,myConvert eps)$RealZeroPackage(SUP I)
+ [(1/2)*(x.left + x.right) for x in z] pretend L(F)
+ error "improper arguments to INFSP"
+ error "improper arguments to INFSP"
+
+
+ -- find the zeros of components in "generic" position --
+ findGenZeros(lp:L P K,rlvar:L SE,eps:Par) : L L F ==
+ rlp:=reverse lp
+ f:=rlp.first
+ zvar:= rlvar.first
+ rlp:=rlp.rest
+ lz:=innerSolve1(f,eps)
+ [reverse cons(z,[evaluate(pol,xvar,zvar,z) for pol in rlp
+ for xvar in rlvar.rest]) for z in lz]
+
+ -- convert to the old coordinates --
+ oldCoord(numres:L F,lval:L I) : L F ==
+ rnumres:=reverse numres
+ rnumres.first:= rnumres.first +
+ (+/[n*nr for n in lval for nr in rnumres.rest])
+ reverse rnumres
+
+ -- real zeros of a system of 2 polynomials lp (incomplete)
+ innerSolve2(lp:L P K,lv:L SE,eps: Par):L L F ==
+ mainvar := first lv
+ up1:=univariate(lp.1, mainvar)
+ up2:=univariate(lp.2, mainvar)
+ vec := subresultantVector(up1,up2)$SubResultantPackage(P K,SUP P K)
+ p0 := primitivePart multivariate(vec.0, mainvar)
+ p1 := primitivePart(multivariate(vec.1, mainvar),mainvar)
+ zero? p1 or
+ gcd(p0, leadingCoefficient(univariate(p1,mainvar))) ^=1 =>
+ innerSolve(cons(0,lp),empty(),lv,eps)
+ findGenZeros([p1, p0], reverse lv, eps)
+
+ -- real zeros of the system of polynomial lp --
+ innerSolve(lp:L P K,ld:L P K,lv:L SE,eps: Par) : L L F ==
+ -- empty?(ld) and (#lv = 2) and (# lp = 2) => innerSolve2(lp, lv, eps)
+ lnp:= [pToDmp(p)$PolToPol(lv,K) for p in lp]
+ OV:=OrderedVariableList(lv)
+ lvv:L OV:= [variable(vv)::OV for vv in lv]
+ DP:=DirectProduct(#lv,NonNegativeInteger)
+ dmp:=DistributedMultivariatePolynomial(lv,K)
+ lq:L dmp:=[]
+ if ld^=[] then
+ lq:= [(pToDmp(q1)$PolToPol(lv,K)) pretend dmp for q1 in ld]
+ partRes:=groebSolve(lnp,lvv)$GroebnerSolve(lv,K,K) pretend (L L dmp)
+ partRes=list [] => []
+ -- remove components where denominators vanish
+ if lq^=[] then
+ gb:=GroebnerInternalPackage(K,DirectProduct(#lv,NNI),OV,dmp)
+ partRes:=[pr for pr in partRes|
+ and/[(redPol(fq,pr pretend List(dmp))$gb) ^=0
+ for fq in lq]]
+
+ -- select the components in "generic" form
+ rlv:=reverse lv
+ rrlvv:= rest reverse lvv
+
+ listGen:L L dmp:=[]
+ for res in partRes repeat
+ res1:=rest reverse res
+ "and"/[("max"/degree(f,rrlvv))=1 for f in res1] =>
+ listGen:=concat(res pretend (L dmp),listGen)
+ result:L L F := []
+ if listGen^=[] then
+ listG :L L P K:=
+ [[dmpToP(pf)$PolToPol(lv,K) for pf in pr] for pr in listGen]
+ result:=
+ "append"/[findGenZeros(res,rlv,eps) for res in listG]
+ for gres in listGen repeat
+ partRes:=delete(partRes,position(gres,partRes))
+ -- adjust the non-generic components
+ for gres in partRes repeat
+ genRecord := genericPosition(gres,lvv)$GroebnerSolve(lv,K,K)
+ lgen := genRecord.dpolys
+ lval := genRecord.coords
+ lgen1:=[dmpToP(pf)$PolToPol(lv,K) for pf in lgen]
+ lris:=findGenZeros(lgen1,rlv,eps)
+ result:= append([oldCoord(r,lval) for r in lris],result)
+ result
+
+@
+\section{package FLOATRP FloatingRealPackage}
+<<package FLOATRP FloatingRealPackage>>=
+)abbrev package FLOATRP FloatingRealPackage
+++ Author: P. Gianni
+++ Date Created: January 1990
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: SystemSolvePackage, RadicalSolvePackage,
+++ FloatingComplexPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is a package for the approximation of real solutions for
+++ systems of polynomial equations over the rational numbers.
+++ The results are expressed as either rational numbers or floats
+++ depending on the type of the precision parameter which can be
+++ either a rational number or a floating point number.
+FloatingRealPackage(Par): Cat == Cap where
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ P ==> Polynomial
+ EQ ==> Equation
+ L ==> List
+ SUP ==> SparseUnivariatePolynomial
+ RN ==> Fraction Integer
+ NF ==> Float
+ CF ==> Complex Float
+ GI ==> Complex Integer
+ GRN ==> Complex RN
+ SE ==> Symbol
+ RFI ==> Fraction P I
+ INFSP ==> InnerNumericFloatSolvePackage
+
+ Par : Join(OrderedRing, Field) -- RN or NewFloat
+
+ Cat == with
+
+ solve: (L RFI,Par) -> L L EQ P Par
+ ++ solve(lp,eps) finds all of the real solutions of the
+ ++ system lp of rational functions over the rational numbers
+ ++ with respect to all the variables appearing in lp,
+ ++ with precision eps.
+
+ solve: (L EQ RFI,Par) -> L L EQ P Par
+ ++ solve(leq,eps) finds all of the real solutions of the
+ ++ system leq of equationas of rational functions
+ ++ with respect to all the variables appearing in lp,
+ ++ with precision eps.
+
+ solve: (RFI,Par) -> L EQ P Par
+ ++ solve(p,eps) finds all of the real solutions of the
+ ++ univariate rational function p with rational coefficients
+ ++ with respect to the unique variable appearing in p,
+ ++ with precision eps.
+
+ solve: (EQ RFI,Par) -> L EQ P Par
+ ++ solve(eq,eps) finds all of the real solutions of the
+ ++ univariate equation eq of rational functions
+ ++ with respect to the unique variables appearing in eq,
+ ++ with precision eps.
+
+ realRoots: (L RFI,L SE,Par) -> L L Par
+ ++ realRoots(lp,lv,eps) computes the list of the real
+ ++ solutions of the list lp of rational functions with rational
+ ++ coefficients with respect to the variables in lv,
+ ++ with precision eps. Each solution is expressed as a list
+ ++ of numbers in order corresponding to the variables in lv.
+
+ realRoots : (RFI,Par) -> L Par
+ ++ realRoots(rf, eps) finds the real zeros of a univariate
+ ++ rational function with precision given by eps.
+
+ Cap == add
+
+ makeEq(nres:L Par,lv:L SE) : L EQ P Par ==
+ [equation(x::(P Par),r::(P Par)) for x in lv for r in nres]
+
+ -- find the real zeros of an univariate rational polynomial --
+ realRoots(p:RFI,eps:Par) : L Par ==
+ innerSolve1(numer p,eps)$INFSP(I,Par,Par)
+
+ -- real zeros of the system of polynomial lp --
+ realRoots(lp:L RFI,lv:L SE,eps: Par) : L L Par ==
+ lnum:=[numer p for p in lp]
+ lden:=[dp for p in lp |(dp:=denom p)^=1]
+ innerSolve(lnum,lden,lv,eps)$INFSP(I,Par,Par)
+
+ solve(lp:L RFI,eps : Par) : L L EQ P Par ==
+ lnum:=[numer p for p in lp]
+ lden:=[dp for p in lp |(dp:=denom p)^=1]
+ lv:="setUnion"/[variables np for np in lnum]
+ if lden^=[] then
+ lv:=setUnion(lv,"setUnion"/[variables dp for dp in lden])
+ [makeEq(numres,lv) for numres
+ in innerSolve(lnum,lden,lv,eps)$INFSP(I,Par,Par)]
+
+ solve(le:L EQ RFI,eps : Par) : L L EQ P Par ==
+ lp:=[lhs ep - rhs ep for ep in le]
+ lnum:=[numer p for p in lp]
+ lden:=[dp for p in lp |(dp:=denom p)^=1]
+ lv:="setUnion"/[variables np for np in lnum]
+ if lden^=[] then
+ lv:=setUnion(lv,"setUnion"/[variables dp for dp in lden])
+ [makeEq(numres,lv) for numres
+ in innerSolve(lnum,lden,lv,eps)$INFSP(I,Par,Par)]
+
+ solve(p : RFI,eps : Par) : L EQ P Par ==
+ (mvar := mainVariable numer p ) case "failed" =>
+ error "no variable found"
+ x:P Par:=mvar::SE::(P Par)
+ [equation(x,val::(P Par)) for val in realRoots(p,eps)]
+
+ solve(eq : EQ RFI,eps : Par) : L EQ P Par ==
+ solve(lhs eq - rhs eq,eps)
+
+@
+\section{package FLOATCP FloatingComplexPackage}
+<<package FLOATCP FloatingComplexPackage>>=
+)abbrev package FLOATCP FloatingComplexPackage
+++ Author: P. Gianni
+++ Date Created: January 1990
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: SystemSolvePackage, RadicalSolvePackage,
+++ FloatingRealPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is a package for the approximation of complex solutions for
+++ systems of equations of rational functions with complex rational
+++ coefficients. The results are expressed as either complex rational
+++ numbers or complex floats depending on the type of the precision
+++ parameter which can be either a rational number or a floating point number.
+FloatingComplexPackage(Par): Cat == Cap where
+ Par : Join(Field, OrderedRing)
+ K ==> GI
+ FPK ==> Fraction P K
+ C ==> Complex
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ P ==> Polynomial
+ EQ ==> Equation
+ L ==> List
+ SUP ==> SparseUnivariatePolynomial
+ RN ==> Fraction Integer
+ NF ==> Float
+ CF ==> Complex Float
+ GI ==> Complex Integer
+ GRN ==> Complex RN
+ SE ==> Symbol
+ RFI ==> Fraction P I
+ INFSP ==> InnerNumericFloatSolvePackage
+
+
+ Cat == with
+
+ complexSolve: (L FPK,Par) -> L L EQ P C Par
+ ++ complexSolve(lp,eps) finds all the complex solutions to
+ ++ precision eps of the system lp of rational functions
+ ++ over the complex rationals with respect to all the
+ ++ variables appearing in lp.
+
+ complexSolve: (L EQ FPK,Par) -> L L EQ P C Par
+ ++ complexSolve(leq,eps) finds all the complex solutions
+ ++ to precision eps of the system leq of equations
+ ++ of rational functions over complex rationals
+ ++ with respect to all the variables appearing in lp.
+
+ complexSolve: (FPK,Par) -> L EQ P C Par
+ ++ complexSolve(p,eps) find all the complex solutions of the
+ ++ rational function p with complex rational coefficients
+ ++ with respect to all the variables appearing in p,
+ ++ with precision eps.
+
+ complexSolve: (EQ FPK,Par) -> L EQ P C Par
+ ++ complexSolve(eq,eps) finds all the complex solutions of the
+ ++ equation eq of rational functions with rational rational coefficients
+ ++ with respect to all the variables appearing in eq,
+ ++ with precision eps.
+
+ complexRoots : (FPK,Par) -> L C Par
+ ++ complexRoots(rf, eps) finds all the complex solutions of a
+ ++ univariate rational function with rational number coefficients.
+ ++ The solutions are computed to precision eps.
+
+ complexRoots : (L FPK,L SE,Par) -> L L C Par
+ ++ complexRoots(lrf, lv, eps) finds all the complex solutions of a
+ ++ list of rational functions with rational number coefficients
+ ++ with respect the the variables appearing in lv.
+ ++ Each solution is computed to precision eps and returned as
+ ++ list corresponding to the order of variables in lv.
+
+ Cap == add
+
+ -- find the complex zeros of an univariate polynomial --
+ complexRoots(q:FPK,eps:Par) : L C Par ==
+ p:=numer q
+ complexZeros(univariate p,eps)$ComplexRootPackage(SUP GI, Par)
+
+ -- find the complex zeros of an univariate polynomial --
+ complexRoots(lp:L FPK,lv:L SE,eps:Par) : L L C Par ==
+ lnum:=[numer p for p in lp]
+ lden:=[dp for p in lp |(dp:=denom p)^=1]
+ innerSolve(lnum,lden,lv,eps)$INFSP(K,C Par,Par)
+
+ complexSolve(lp:L FPK,eps : Par) : L L EQ P C Par ==
+ lnum:=[numer p for p in lp]
+ lden:=[dp for p in lp |(dp:=denom p)^=1]
+ lv:="setUnion"/[variables np for np in lnum]
+ if lden^=[] then
+ lv:=setUnion(lv,"setUnion"/[variables dp for dp in lden])
+ [[equation(x::(P C Par),r::(P C Par)) for x in lv for r in nres]
+ for nres in innerSolve(lnum,lden,lv,eps)$INFSP(K,C Par,Par)]
+
+ complexSolve(le:L EQ FPK,eps : Par) : L L EQ P C Par ==
+ lp:=[lhs ep - rhs ep for ep in le]
+ lnum:=[numer p for p in lp]
+ lden:=[dp for p in lp |(dp:=denom p)^=1]
+ lv:="setUnion"/[variables np for np in lnum]
+ if lden^=[] then
+ lv:=setUnion(lv,"setUnion"/[variables dp for dp in lden])
+ [[equation(x::(P C Par),r::(P C Par)) for x in lv for r in nres]
+ for nres in innerSolve(lnum,lden,lv,eps)$INFSP(K,C Par,Par)]
+
+ complexSolve(p : FPK,eps : Par) : L EQ P C Par ==
+ (mvar := mainVariable numer p ) case "failed" =>
+ error "no variable found"
+ x:P C Par:=mvar::SE::(P C Par)
+ [equation(x,val::(P C Par)) for val in complexRoots(p,eps)]
+
+ complexSolve(eq : EQ FPK,eps : Par) : L EQ P C Par ==
+ complexSolve(lhs eq - rhs eq,eps)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INFSP InnerNumericFloatSolvePackage>>
+<<package FLOATRP FloatingRealPackage>>
+<<package FLOATCP FloatingComplexPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/numtheor.spad.pamphlet b/src/algebra/numtheor.spad.pamphlet
new file mode 100644
index 00000000..b5cf7404
--- /dev/null
+++ b/src/algebra/numtheor.spad.pamphlet
@@ -0,0 +1,736 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra numtheor.spad}
+\author{Martin Brock, Timothy Daly, Michael Monagan, Robert Sutor,
+Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTHEORY IntegerNumberTheoryFunctions}
+\subsection{The inverse function}
+The inverse function is derived from the
+{\bf Extended Euclidean Algorithm}.
+If we divide one integer by another nonzero integer we get an integer
+quotient plus a remainder which is, in general, a rational number.
+For instance,
+\[13/5 = 2 + 3/5\]
+where 2 is the quotient and $3/5$ is the remainder.
+
+If we multiply thru by the denominator of the remainder we get an answer
+in integer terms which no longer involves division:
+\[13 = 2(5) + 3\]
+
+This gives a method of dividing integers. Specifically, if a and b are
+positive integers, there exist unique non-negative integers q
+and r so that
+\[a = qb + r , {\rm\ where\ } 0 \le r < b\]
+q is called the quotient and r the remainder.
+
+The greatest common divisor of integers a and b, denoted by gcd(a,b),
+is the largest integer that divides (without remainder) both a and
+b. So, for example: gcd(15, 5) = 5, gcd(7, 9) = 1, gcd(12, 9) = 3,
+gcd(81, 57) = 3.
+
+The gcd of two integers can be found by repeated application of the
+division algorithm, this is known as the Euclidean Algorithm. You
+repeatedly divide the divisor by the remainder until the remainder is
+0. The gcd is the last non-zero remainder in this algorithm. The
+following example shows the algorithm.
+
+Finding the gcd of 81 and 57 by the {\bf Euclidean Algorithm}:
+\[
+\begin{array}{rcl}
+81 & = & 1(57) + 24\\
+57 & = & 2(24) + 9\\
+24 & = & 2(9) + 6\\
+9 & = & 1(6) + 3\\
+6 & = & 2(3) + 0
+\end{array}
+\]
+
+So the greatest commmon divisor, the GCD(81,51)=3.
+
+If the gcd(a, b) = r then there exist integers s and t so that
+\[s(a) + t(b) = r\]
+
+By back substitution in the steps in the Euclidean Algorithm, it is
+possible to find these integers s and t. We shall do this with the
+above example:
+
+Starting with the next to last line, we have:
+\[3 = 9 -1(6)\]
+From the line before that, we see that $6 = 24 - 2(9)$, so:
+\[3 = 9 - 1(24 - 2(9)) = 3(9) - 1(24)\]
+From the line before that, we have $9 = 57 - 2(24)$, so:
+\[3 = 3( 57 - 2(24)) - 1(24) = 3(57) - 7(24)\]
+And, from the line before that $24 = 81 - 1(57)$, giving us:
+\[3 = 3(57) - 7( 81 - 1(57)) = 10(57) -7(81)\]
+So we have found s = -7 and t = 10.
+
+The {\bf Extended Euclidean Algorithm} computes the GCD($a$,$b$) and
+the values for $s$ and $t$.
+
+Suppose we were doing arithmetics modulo 26 and we needed to find the
+inverse of a number mod 26. This turned out to be a difficult task
+(and not always possible). We observed that a number $x$ had an inverse
+mod 26 (i.e., a number $y$ so that $xy = 1 {\rm\ mod\ } 26$)
+if and only if $gcd(x,26) = 1$.
+In the general case the inverse
+of $x$ exists if and only if $gcd(x, n) = 1$ and if it exists then
+there exist integers $s$ and $t$ so that
+
+\[sx + tn = 1\]
+
+But this says that $sx = 1 + (-t)n$, or in other words,
+\[sx \equiv 1 {\rm\ mod\ } n\]
+So, s (reduced mod n if need be) is the inverse of $x {\rm\ mod\ }n$.
+The extended Euclidean algorithm calculates $s$ efficiently.
+
+\subsubsection{Finding the inverse mod n}
+
+We will number the steps of the Euclidean algorithm starting
+with step 0. The quotient obtained at step $i$ will be denoted by $q_i$
+and an auxillary number, $s_i$. For the first two steps, the value
+of this number is given: $s_0 = 0$ and $s_1 = 1$. For the remainder of the
+steps, we recursively calculate
+\[s_i = s_{i-2} - s_{i-1} q_{i-2} {\rm\ (mod\ n)}\]
+
+The algorithm starts by "dividing" $n$ by $x$.
+If the last non-zero remainder occurs at step $k$,
+then if this remainder is 1, $x$ has an inverse and it is $s_{k+2}$.
+If the remainder is not 1, then $x$ does not have an inverse.
+
+Find the inverse of 15 mod 26.
+\[
+\begin{array}{crcll}
+Step 0: &26 &=& 1(15) + 11 &s_0 = 0\\
+Step 1: &15 &=& 1(11) + 4 &s_1 = 1\\
+Step 2: &11 &=& 2(4) + 3
+&s_2 = 0 - 1( 1) {\rm\ mod\ } 26 = 25\\
+Step 3: &4 &=& 1(3) + 1
+&s_3 = 1 - 25( 1) {\rm\ mod\ } 26 = -24 {\rm\ mod\ } 26 = 2\\
+Step 4: &3 &=& 3(1) + 0
+&s_4 = 25 - 2( 2) {\rm\ mod\ } 26 = 21\\
+&&& &s_5 = 2 - 21( 1) {\rm\ mod\ } 26 = -19 {\rm\ mod\ } 26 = 7
+\end{array}
+\]
+Notice that $15(7) = 105 = 1 + 4(26) \equiv 1 ({\rm\ mod\ } 26)$.
+
+Using the half extended Euclidean algorithm we compute 1/a mod b.
+<<inverse(a,b)>>=
+ inverse(a,b) ==
+ borg:I:=b
+ c1:I := 1
+ d1:I := 0
+ while b ^= 0 repeat
+ q:I := a quo b
+ r:I := a-q*b
+ (a,b):=(b,r)
+ (c1,d1):=(d1,c1-q*d1)
+ a ^= 1 => error("moduli are not relatively prime")
+ positiveRemainder(c1,borg)
+
+@
+<<inverse : (I,I) -> I>>=
+ inverse : (I,I) -> I
+@
+Since this algorithm in local we need to reproduce it in the
+input file for testing purposes.
+<<TESTinverse>>=
+)clear completely
+
+inverse:(INT,INT)->INT
+
+inverse(a,b) ==
+ borg:INT:=b
+ c1:INT := 1
+ d1:INT := 0
+ while b ~= 0 repeat
+ q := a quo b
+ r := a-q*b
+ print [a, "=", q, "*(", b, ")+", r]
+ (a,b):=(b,r)
+ (c1,d1):=(d1,c1-q*d1)
+ a ~= 1 => error("moduli are not relatively prime")
+ positiveRemainder(c1,borg)
+
+if ((inverse(26,15)*26)::IntegerMod(15) ~= 1) then print "DALY BUG"
+if ((inverse(15,26)*15)::IntegerMod(26) ~= 1) then print "DALY BUG"
+
+@
+\subsection{The Chinese Remainder Algorithm}
+\subsubsection{Chinese Remainder Theorem}
+Let $m_1$,$m_2$,\ldots,$m_r$ be positive integers that are pairwise
+relatively prime. Let $x_1$,$x_2$,\ldots,$x_r$ be integers with
+$0 \le x_i < m_i$. Then, there is exactly one $x$ in the interval
+\[0 \le x < m_1 \cdot m_2 \cdots m_r\]
+that satisfies the remainder equations
+\[{\rm\ irem\ }(x,m_i) = x_i,\ \ \ i=1,2,\ldots,r\]
+where {\bf irem} is the positive integer remainder function.
+\subsubsection{Chinese Remainder Example}
+Let $x_1 = 4$, $m_1 = 5$, $x_2 = 2$, $m_2 = 3$. We know that
+\[{\rm\ irem\ }(x,m_1) = x_1\]
+\[{\rm\ irem\ }(x,m_2) = x_2\]
+where $0 \le x_1 < m_1$ and $0 \le x_2 < m_2$. By the extended
+Euclidean Algorithm there are integers $c$ and $d$ such that
+\[c m_1 + d m_2 = 1\].
+\noindent
+In this case we are looking for an integer such that
+\[{\rm\ irem\ }(x,5) = 4\]
+\[{\rm\ irem\ }(x,3) = 2\]
+
+The algorithm we use is to first
+compute the positive integer
+remainder of $x_1$ and $m_1$ to get a new $x_1$:
+\[
+\begin{array}{rcl}
+x_1 & = & {\rm\ positiveRemainder\ }(x_1,m_1)\\
+4 & = & {\rm\ positiveRemainder\ }(4,5)
+\end{array}
+\]
+Next compute the positive integer
+remainder of $x_2$ and $m_2$ to get a new $x_2$:
+\[
+\begin{array}{rcl}
+x_2 & = & {\rm\ positiveRemainder\ }(x_2,m_2)\\
+2 & = & {\rm\ positiveRemainder\ }(2,3)
+\end{array}
+\]
+Then we compute
+\[x_1 + m_1 \cdot {\rm\ positiveRemainder\ }
+(((x_2-x_1)\cdot{\rm inverse}(m_1,m_2)),m_2)\]
+or
+\[4+5*{\rm\ positiveRemainder\ }(((2-4)*{\rm\ inverse\ }(5,3)),3)\]
+or
+\[4+5*{\rm\ positiveRemainder\ }(-2*2),3)\]
+or
+\[4+5*2\]
+or
+\[14\]
+<<chineseRemainder(x1,m1,x2,m2)>>=
+ chineseRemainder(x1,m1,x2,m2) ==
+ m1 < 0 or m2 < 0 => error "moduli must be positive"
+ x1 := positiveRemainder(x1,m1)
+ x2 := positiveRemainder(x2,m2)
+ x1 + m1 * positiveRemainder(((x2-x1) * inverse(m1,m2)),m2)
+
+@
+This function has a restricted signature which only allows for
+computing the chinese remainder of two numbers and two moduli.
+<<chineseRemainder: (I,I,I,I) -> I>>=
+ chineseRemainder: (I,I,I,I) -> I
+ ++ \spad{chineseRemainder(x1,m1,x2,m2)} returns w, where w is such that
+ ++ \spad{w = x1 mod m1} and \spad{w = x2 mod m2}. Note: \spad{m1} and
+ ++ \spad{m2} must be relatively prime.
+@
+We test the particular example. The result should be 14.
+<<TESTchineseRemainder>>=
+)clear all
+x1:=4
+m1:=5
+x2:=2
+m2:=3
+result:=chineseRemainder(x1,m1,x2,m2)
+expected:=14
+if (result-expected ~=0) then print "DALY BUG"
+
+@
+<<package INTHEORY IntegerNumberTheoryFunctions>>=
+)abbrev package INTHEORY IntegerNumberTheoryFunctions
+++ Author: Michael Monagan, Martin Brock, Robert Sutor, Timothy Daly
+++ Date Created: June 1987
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: number theory, integer
+++ Examples:
+++ References: Knuth, The Art of Computer Programming Vol.2
+++ Description:
+++ This package provides various number theoretic functions on the integers.
+IntegerNumberTheoryFunctions(): Exports == Implementation where
+ I ==> Integer
+ RN ==> Fraction I
+ SUP ==> SparseUnivariatePolynomial
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ bernoulli : I -> RN
+ ++ \spad{bernoulli(n)} returns the nth Bernoulli number.
+ ++ this is \spad{B(n,0)}, where \spad{B(n,x)} is the \spad{n}th Bernoulli
+ ++ polynomial.
+<<chineseRemainder: (I,I,I,I) -> I>>
+ divisors : I -> List I
+ ++ \spad{divisors(n)} returns a list of the divisors of n.
+ euler : I -> I
+ ++ \spad{euler(n)} returns the \spad{n}th Euler number. This is
+ ++ \spad{2^n E(n,1/2)}, where \spad{E(n,x)} is the nth Euler polynomial.
+ eulerPhi : I -> I
+ ++ \spad{eulerPhi(n)} returns the number of integers between 1 and n
+ ++ (including 1) which are relatively prime to n. This is the Euler phi
+ ++ function \spad{\phi(n)} is also called the totient function.
+ fibonacci : I -> I
+ ++ \spad{fibonacci(n)} returns the nth Fibonacci number. the Fibonacci
+ ++ numbers \spad{F[n]} are defined by \spad{F[0] = F[1] = 1} and
+ ++ \spad{F[n] = F[n-1] + F[n-2]}.
+ ++ The algorithm has running time \spad{O(log(n)^3)}.
+ ++ Reference: Knuth, The Art of Computer Programming
+ ++ Vol 2, Semi-Numerical Algorithms.
+ harmonic : I -> RN
+ ++ \spad{harmonic(n)} returns the nth harmonic number. This is
+ ++ \spad{H[n] = sum(1/k,k=1..n)}.
+ jacobi : (I,I) -> I
+ ++ \spad{jacobi(a,b)} returns the Jacobi symbol \spad{J(a/b)}.
+ ++ When b is odd, \spad{J(a/b) = product(L(a/p) for p in factor b )}.
+ ++ Note: by convention, 0 is returned if \spad{gcd(a,b) ^= 1}.
+ ++ Iterative \spad{O(log(b)^2)} version coded by Michael Monagan June 1987.
+ legendre : (I,I) -> I
+ ++ \spad{legendre(a,p)} returns the Legendre symbol \spad{L(a/p)}.
+ ++ \spad{L(a/p) = (-1)**((p-1)/2) mod p} (p prime), which is 0 if \spad{a}
+ ++ is 0, 1 if \spad{a} is a quadratic residue \spad{mod p} and -1 otherwise.
+ ++ Note: because the primality test is expensive,
+ ++ if it is known that p is prime then use \spad{jacobi(a,p)}.
+ moebiusMu : I -> I
+ ++ \spad{moebiusMu(n)} returns the Moebius function \spad{mu(n)}.
+ ++ \spad{mu(n)} is either -1,0 or 1 as follows:
+ ++ \spad{mu(n) = 0} if n is divisible by a square > 1,
+ ++ \spad{mu(n) = (-1)^k} if n is square-free and has k distinct
+ ++ prime divisors.
+ numberOfDivisors: I -> I
+ ++ \spad{numberOfDivisors(n)} returns the number of integers between 1 and n
+ ++ (inclusive) which divide n. The number of divisors of n is often
+ ++ denoted by \spad{tau(n)}.
+ sumOfDivisors : I -> I
+ ++ \spad{sumOfDivisors(n)} returns the sum of the integers between 1 and n
+ ++ (inclusive) which divide n. The sum of the divisors of n is often
+ ++ denoted by \spad{sigma(n)}.
+ sumOfKthPowerDivisors: (I,NNI) -> I
+ ++ \spad{sumOfKthPowerDivisors(n,k)} returns the sum of the \spad{k}th
+ ++ powers of the integers between 1 and n (inclusive) which divide n.
+ ++ the sum of the \spad{k}th powers of the divisors of n is often denoted
+ ++ by \spad{sigma_k(n)}.
+ Implementation ==> add
+ import IntegerPrimesPackage(I)
+
+ -- we store the euler and bernoulli numbers computed so far in
+ -- a Vector because they are computed from an n-term recurrence
+ E: IndexedFlexibleArray(I,0) := new(1, 1)
+ B: IndexedFlexibleArray(RN,0) := new(1, 1)
+ H: Record(Hn:I,Hv:RN) := [1, 1]
+
+ harmonic n ==
+ s:I; h:RN
+ n < 0 => error("harmonic not defined for negative integers")
+ if n >= H.Hn then (s,h) := H else (s := 0; h := 0)
+ for k in s+1..n repeat h := h + 1/k
+ H.Hn := n
+ H.Hv := h
+ h
+
+ fibonacci n ==
+ n = 0 => 0
+ n < 0 => (odd? n => 1; -1) * fibonacci(-n)
+ f1, f2 : I
+ (f1,f2) := (0,1)
+ for k in length(n)-2 .. 0 by -1 repeat
+ t := f2**2
+ (f1,f2) := (t+f1**2,t+2*f1*f2)
+ if bit?(n,k) then (f1,f2) := (f2,f1+f2)
+ f2
+
+ euler n ==
+ n < 0 => error "euler not defined for negative integers"
+ odd? n => 0
+ l := (#E) :: I
+ n < l => E(n)
+ concat_!(E, new((n+1-l)::NNI, 0)$IndexedFlexibleArray(I,0))
+ for i in 1 .. l by 2 repeat E(i) := 0
+ -- compute E(i) i = l+2,l+4,...,n given E(j) j = 0,2,...,i-2
+ t,e : I
+ for i in l+1 .. n by 2 repeat
+ t := e := 1
+ for j in 2 .. i-2 by 2 repeat
+ t := (t*(i-j+1)*(i-j+2)) quo (j*(j-1))
+ e := e + t*E(j)
+ E(i) := -e
+ E(n)
+
+ bernoulli n ==
+ n < 0 => error "bernoulli not defined for negative integers"
+ odd? n =>
+ n = 1 => -1/2
+ 0
+ l := (#B) :: I
+ n < l => B(n)
+ concat_!(B, new((n+1-l)::NNI, 0)$IndexedFlexibleArray(RN,0))
+ for i in 1 .. l by 2 repeat B(i) := 0
+ -- compute B(i) i = l+2,l+4,...,n given B(j) j = 0,2,...,i-2
+ for i in l+1 .. n by 2 repeat
+ t:I := 1
+ b := (1-i)/2
+ for j in 2 .. i-2 by 2 repeat
+ t := (t*(i-j+2)*(i-j+3)) quo (j*(j-1))
+ b := b + (t::RN) * B(j)
+ B(i) := -b/((i+1)::RN)
+ B(n)
+
+<<inverse : (I,I) -> I>>
+<<inverse(a,b)>>
+<<chineseRemainder(x1,m1,x2,m2)>>
+
+ jacobi(a,b) ==
+ -- Revised by Clifton Williamson January 1989.
+ -- Previous version returned incorrect answers when b was even.
+ -- The formula J(a/b) = product ( L(a/p) for p in factor b) is only
+ -- valid when b is odd (the Legendre symbol L(a/p) is not defined
+ -- for p = 2). When b is even, the Jacobi symbol J(a/b) is only
+ -- defined for a = 0 or 1 (mod 4). When a = 1 (mod 8),
+ -- J(a/2) = +1 and when a = 5 (mod 8), we define J(a/2) = -1.
+ -- Extending by multiplicativity, we have J(a/b) for even b and
+ -- appropriate a.
+ -- We also define J(a/1) = 1.
+ -- The point of this is the following: if d is the discriminant of
+ -- a quadratic field K and chi is the quadratic character for K,
+ -- then J(d/n) = chi(n) for n > 0.
+ -- Reference: Hecke, Vorlesungen ueber die Theorie der Algebraischen
+ -- Zahlen.
+ if b < 0 then b := -b
+ b = 0 => error "second argument of jacobi may not be 0"
+ b = 1 => 1
+ even? b and positiveRemainder(a,4) > 1 =>
+ error "J(a/b) not defined for b even and a = 2 or 3 (mod 4)"
+ even? b and even? a => 0
+ for k in 0.. while even? b repeat b := b quo 2
+ j:I := (odd? k and positiveRemainder(a,8) = 5 => -1; 1)
+ b = 1 => j
+ a := positiveRemainder(a,b)
+ -- assertion: 0 < a < b and odd? b
+ while a > 1 repeat
+ if odd? a then
+ -- J(a/b) = J(b/a) (-1) ** (a-1)/2 (b-1)/2
+ if a rem 4 = 3 and b rem 4 = 3 then j := -j
+ (a,b) := (b rem a,a)
+ else
+ -- J(2*a/b) = J(a/b) (-1) (b**2-1)/8
+ for k in 0.. until odd? a repeat a := a quo 2
+ if odd? k and (b+2) rem 8 > 4 then j := -j
+ a = 0 => 0
+ j
+
+ legendre(a,p) ==
+ prime? p => jacobi(a,p)
+ error "characteristic of legendre must be prime"
+
+ eulerPhi n ==
+ n = 0 => 0
+ r : RN := 1
+ for entry in factors factor n repeat
+ r := ((entry.factor - 1) /$RN entry.factor) * r
+ numer(n * r)
+
+ divisors n ==
+ oldList : List Integer := concat(1,nil())
+ for f in factors factor n repeat
+ newList : List Integer := nil()
+ for k in 0..f.exponent repeat
+ pow := f.factor ** k
+ for m in oldList repeat
+ newList := concat(pow * m,newList)
+ oldList := newList
+ sort(#1 < #2,newList)
+
+ numberOfDivisors n ==
+ n = 0 => 0
+ */[1+entry.exponent for entry in factors factor n]
+
+ sumOfDivisors n ==
+ n = 0 => 0
+ r : RN := */[(entry.factor**(entry.exponent::NNI + 1)-1)/
+ (entry.factor-1) for entry in factors factor n]
+ numer r
+
+ sumOfKthPowerDivisors(n,k) ==
+ n = 0 => 0
+ r : RN := */[(entry.factor**(k*entry.exponent::NNI+k)-1)/
+ (entry.factor**k-1) for entry in factors factor n]
+ numer r
+
+ moebiusMu n ==
+ n = 1 => 1
+ t := factor n
+ for k in factors t repeat
+ k.exponent > 1 => return 0
+ odd? numberOfFactors t => -1
+ 1
+
+@
+\subsection{TEST INTHEORY}
+<<TEST INTHEORY>>=
+<<TESTchineseRemainder>>
+<<TESTinverse>>
+@
+\section{package PNTHEORY PolynomialNumberTheoryFunctions}
+<<package PNTHEORY PolynomialNumberTheoryFunctions>>=
+)abbrev package PNTHEORY PolynomialNumberTheoryFunctions
+++ Author: Michael Monagan, Clifton J. Williamson
+++ Date Created: June 1987
+++ Date Last Updated: 10 November 1996 (Claude Quitte)
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, number theory
+++ Examples:
+++ References: Knuth, The Art of Computer Programming Vol.2
+++ Description:
+++ This package provides various polynomial number theoretic functions
+++ over the integers.
+PolynomialNumberTheoryFunctions(): Exports == Implementation where
+ I ==> Integer
+ RN ==> Fraction I
+ SUP ==> SparseUnivariatePolynomial
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ bernoulli : I -> SUP RN
+ ++ bernoulli(n) returns the nth Bernoulli polynomial \spad{B[n](x)}.
+ ++ Note: Bernoulli polynomials denoted \spad{B(n,x)} computed by solving the
+ ++ differential equation \spad{differentiate(B(n,x),x) = n B(n-1,x)} where
+ ++ \spad{B(0,x) = 1} and initial condition comes from \spad{B(n) = B(n,0)}.
+ chebyshevT: I -> SUP I
+ ++ chebyshevT(n) returns the nth Chebyshev polynomial \spad{T[n](x)}.
+ ++ Note: Chebyshev polynomials of the first kind, denoted \spad{T[n](x)},
+ ++ computed from the two term recurrence. The generating function
+ ++ \spad{(1-t*x)/(1-2*t*x+t**2) = sum(T[n](x)*t**n, n=0..infinity)}.
+ chebyshevU: I -> SUP I
+ ++ chebyshevU(n) returns the nth Chebyshev polynomial \spad{U[n](x)}.
+ ++ Note: Chebyshev polynomials of the second kind, denoted \spad{U[n](x)},
+ ++ computed from the two term recurrence. The generating function
+ ++ \spad{1/(1-2*t*x+t**2) = sum(T[n](x)*t**n, n=0..infinity)}.
+ cyclotomic: I -> SUP I
+ ++ cyclotomic(n) returns the nth cyclotomic polynomial \spad{phi[n](x)}.
+ ++ Note: \spad{phi[n](x)} is the factor of \spad{x**n - 1} whose roots
+ ++ are the primitive nth roots of unity.
+ euler : I -> SUP RN
+ ++ euler(n) returns the nth Euler polynomial \spad{E[n](x)}.
+ ++ Note: Euler polynomials denoted \spad{E(n,x)} computed by solving the
+ ++ differential equation \spad{differentiate(E(n,x),x) = n E(n-1,x)} where
+ ++ \spad{E(0,x) = 1} and initial condition comes from \spad{E(n) = 2**n E(n,1/2)}.
+ fixedDivisor: SUP I -> I
+ ++ fixedDivisor(a) for \spad{a(x)} in \spad{Z[x]} is the largest integer
+ ++ f such that f divides \spad{a(x=k)} for all integers k.
+ ++ Note: fixed divisor of \spad{a} is
+ ++ \spad{reduce(gcd,[a(x=k) for k in 0..degree(a)])}.
+ hermite : I -> SUP I
+ ++ hermite(n) returns the nth Hermite polynomial \spad{H[n](x)}.
+ ++ Note: Hermite polynomials, denoted \spad{H[n](x)}, are computed from
+ ++ the two term recurrence. The generating function is:
+ ++ \spad{exp(2*t*x-t**2) = sum(H[n](x)*t**n/n!, n=0..infinity)}.
+ laguerre : I -> SUP I
+ ++ laguerre(n) returns the nth Laguerre polynomial \spad{L[n](x)}.
+ ++ Note: Laguerre polynomials, denoted \spad{L[n](x)}, are computed from
+ ++ the two term recurrence. The generating function is:
+ ++ \spad{exp(x*t/(t-1))/(1-t) = sum(L[n](x)*t**n/n!, n=0..infinity)}.
+ legendre : I -> SUP RN
+ ++ legendre(n) returns the nth Legendre polynomial \spad{P[n](x)}.
+ ++ Note: Legendre polynomials, denoted \spad{P[n](x)}, are computed from
+ ++ the two term recurrence. The generating function is:
+ ++ \spad{1/sqrt(1-2*t*x+t**2) = sum(P[n](x)*t**n, n=0..infinity)}.
+ Implementation ==> add
+ import IntegerPrimesPackage(I)
+
+ x := monomial(1,1)$SUP(I)
+ y := monomial(1,1)$SUP(RN)
+
+ -- For functions computed via a fixed term recurrence we record
+ -- previous values so that the next value can be computed directly
+
+ E : Record(En:I, Ev:SUP(RN)) := [0,1]
+ B : Record( Bn:I, Bv:SUP(RN) ) := [0,1]
+ H : Record( Hn:I, H1:SUP(I), H2:SUP(I) ) := [0,1,x]
+ L : Record( Ln:I, L1:SUP(I), L2:SUP(I) ) := [0,1,x]
+ P : Record( Pn:I, P1:SUP(RN), P2:SUP(RN) ) := [0,1,y]
+ CT : Record( Tn:I, T1:SUP(I), T2:SUP(I) ) := [0,1,x]
+ U : Record( Un:I, U1:SUP(I), U2:SUP(I) ) := [0,1,0]
+
+ MonicQuotient: (SUP(I),SUP(I)) -> SUP(I)
+ MonicQuotient (a,b) ==
+ leadingCoefficient(b) ^= 1 => error "divisor must be monic"
+ b = 1 => a
+ da := degree a
+ db := degree b -- assertion: degree b > 0
+ q:SUP(I) := 0
+ while da >= db repeat
+ t := monomial(leadingCoefficient a, (da-db)::NNI)
+ a := a - b * t
+ q := q + t
+ da := degree a
+ q
+
+ cyclotomic n ==
+ --++ cyclotomic polynomial denoted phi[n](x)
+ p:I; q:I; r:I; s:I; m:NNI; c:SUP(I); t:SUP(I)
+ n < 0 => error "cyclotomic not defined for negative integers"
+ n = 0 => x
+ k := n; s := p := 1
+ c := x - 1
+ while k > 1 repeat
+ p := nextPrime p
+ (q,r) := divide(k, p)
+ if r = 0 then
+ while r = 0 repeat (k := q; (q,r) := divide(k,p))
+ t := multiplyExponents(c,p::NNI)
+ c := MonicQuotient(t,c)
+ s := s * p
+ m := (n quo s) :: NNI
+ multiplyExponents(c,m)
+
+ euler n ==
+ p : SUP(RN); t : SUP(RN); c : RN; s : I
+ n < 0 => error "euler not defined for negative integers"
+ if n < E.En then (s,p) := (0$I,1$SUP(RN)) else (s,p) := E
+ -- (s,p) := if n < E.En then (0,1) else E
+ for i in s+1 .. n repeat
+ t := (i::RN) * integrate p
+ c := euler(i)$IntegerNumberTheoryFunctions / 2**(i::NNI) - t(1/2)
+ p := t + c::SUP(RN)
+ E.En := n
+ E.Ev := p
+ p
+
+ bernoulli n ==
+ p : SUP RN; t : SUP RN; c : RN; s : I
+ n < 0 => error "bernoulli not defined for negative integers"
+ if n < B.Bn then (s,p) := (0$I,1$SUP(RN)) else (s,p) := B
+ -- (s,p) := if n < B.Bn then (0,1) else B
+ for i in s+1 .. n repeat
+ t := (i::RN) * integrate p
+ c := bernoulli(i)$IntegerNumberTheoryFunctions
+ p := t + c::SUP(RN)
+ B.Bn := n
+ B.Bv := p
+ p
+
+ fixedDivisor a ==
+ g:I; d:NNI; SUP(I)
+ d := degree a
+ g := coefficient(a, minimumDegree a)
+ for k in 1..d while g > 1 repeat g := gcd(g,a k)
+ g
+
+ hermite n ==
+ s : I; p : SUP(I); q : SUP(I)
+ n < 0 => error "hermite not defined for negative integers"
+ -- (s,p,q) := if n < H.Hn then (0,1,x) else H
+ if n < H.Hn then (s := 0; p := 1; q := x) else (s,p,q) := H
+ for k in s+1 .. n repeat (p,q) := (2*x*p-2*(k-1)*q,p)
+ H.Hn := n
+ H.H1 := p
+ H.H2 := q
+ p
+
+ legendre n ==
+ s:I; t:I; p:SUP(RN); q:SUP(RN)
+ n < 0 => error "legendre not defined for negative integers"
+ -- (s,p,q) := if n < P.Pn then (0,1,y) else P
+ if n < P.Pn then (s := 0; p := 1; q := y) else (s,p,q) := P
+ for k in s+1 .. n repeat
+ t := k-1
+ (p,q) := ((k+t)$I/k*y*p - t/k*q,p)
+ P.Pn := n
+ P.P1 := p
+ P.P2 := q
+ p
+
+ laguerre n ==
+ k:I; s:I; t:I; p:SUP(I); q:SUP(I)
+ n < 0 => error "laguerre not defined for negative integers"
+ -- (s,p,q) := if n < L.Ln then (0,1,x) else L
+ if n < L.Ln then (s := 0; p := 1; q := x) else (s,p,q) := L
+ for k in s+1 .. n repeat
+ t := k-1
+ (p,q) := ((((k+t)$I)::SUP(I)-x)*p-t**2*q,p)
+ L.Ln := n
+ L.L1 := p
+ L.L2 := q
+ p
+
+ chebyshevT n ==
+ s : I; p : SUP(I); q : SUP(I)
+ n < 0 => error "chebyshevT not defined for negative integers"
+ -- (s,p,q) := if n < CT.Tn then (0,1,x) else CT
+ if n < CT.Tn then (s := 0; p := 1; q := x) else (s,p,q) := CT
+ for k in s+1 .. n repeat (p,q) := ((2*x*p - q),p)
+ CT.Tn := n
+ CT.T1 := p
+ CT.T2 := q
+ p
+
+ chebyshevU n ==
+ s : I; p : SUP(I); q : SUP(I)
+ n < 0 => error "chebyshevU not defined for negative integers"
+ if n < U.Un then (s := 0; p := 1; q := 0) else (s,p,q) := U
+ for k in s+1 .. n repeat (p,q) := ((2*x*p - q),p)
+ U.Un := n
+ U.U1 := p
+ U.U2 := q
+ p
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package INTHEORY IntegerNumberTheoryFunctions>>
+<<package PNTHEORY PolynomialNumberTheoryFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} Cohen, Joel S.,
+{\sl Computer Algebra and Symbolic Computation}
+{\sl Mathematical Methods},
+A.K. Peters, Ltd, Natick, MA. USA (2003)
+ISBN 1-56881-159-4
+\bibitem{2} Geddes, Keith O., Czapor, Stephen R., Labahn, George
+{\sl Algorithms for Computer Algebra}
+Kluwer Academic Publishers
+ISBN 0-7923-9259-0
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/oct.spad.pamphlet b/src/algebra/oct.spad.pamphlet
new file mode 100644
index 00000000..680cb040
--- /dev/null
+++ b/src/algebra/oct.spad.pamphlet
@@ -0,0 +1,414 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra oct.spad}
+\author{Robert Wisbauer, Johannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category OC OctonionCategory}
+<<category OC OctonionCategory>>=
+)abbrev category OC OctonionCategory
+++ Author: R. Wisbauer, J. Grabmeier
+++ Date Created: 05 September 1990
+++ Date Last Updated: 19 September 1990
+++ Basic Operations: _+, _*, octon, real, imagi, imagj, imagk,
+++ imagE, imagI, imagJ, imagK
+++ Related Constructors: QuaternionCategory
+++ Also See:
+++ AMS Classifications:
+++ Keywords: octonion, non-associative algebra, Cayley-Dixon
+++ References: e.g. I.L Kantor, A.S. Solodovnikov:
+++ Hypercomplex Numbers, Springer Verlag Heidelberg, 1989,
+++ ISBN 0-387-96980-2
+++ Description:
+++ OctonionCategory gives the categorial frame for the
+++ octonions, and eight-dimensional non-associative algebra,
+++ doubling the the quaternions in the same way as doubling
+++ the Complex numbers to get the quaternions.
+-- Examples: octonion.input
+
+OctonionCategory(R: CommutativeRing): Category ==
+ -- we are cheating a little bit, algebras in \Language{}
+ -- are mainly considered to be associative, but that's not
+ -- an attribute and we can't guarantee that there is no piece
+ -- of code which implicitly
+ -- uses this. In a later version we shall properly combine
+ -- all this code in the context of general, non-associative
+ -- algebras, which are meanwhile implemented in \Language{}
+ Join(Algebra R, FullyRetractableTo R, FullyEvalableOver R) with
+ conjugate: % -> %
+ ++ conjugate(o) negates the imaginary parts i,j,k,E,I,J,K of octonian o.
+ real: % -> R
+ ++ real(o) extracts real part of octonion o.
+ imagi: % -> R
+ ++ imagi(o) extracts the i part of octonion o.
+ imagj: % -> R
+ ++ imagj(o) extracts the j part of octonion o.
+ imagk: % -> R
+ ++ imagk(o) extracts the k part of octonion o.
+ imagE: % -> R
+ ++ imagE(o) extracts the imaginary E part of octonion o.
+ imagI: % -> R
+ ++ imagI(o) extracts the imaginary I part of octonion o.
+ imagJ: % -> R
+ ++ imagJ(o) extracts the imaginary J part of octonion o.
+ imagK: % -> R
+ ++ imagK(o) extracts the imaginary K part of octonion o.
+ norm: % -> R
+ ++ norm(o) returns the norm of an octonion, equal to
+ ++ the sum of the squares
+ ++ of its coefficients.
+ octon: (R,R,R,R,R,R,R,R) -> %
+ ++ octon(re,ri,rj,rk,rE,rI,rJ,rK) constructs an octonion
+ ++ from scalars.
+ if R has Finite then Finite
+ if R has OrderedSet then OrderedSet
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has RealNumberSystem then
+ abs: % -> R
+ ++ abs(o) computes the absolute value of an octonion, equal to
+ ++ the square root of the \spadfunFrom{norm}{Octonion}.
+ if R has IntegerNumberSystem then
+ rational? : % -> Boolean
+ ++ rational?(o) tests if o is rational, i.e. that all seven
+ ++ imaginary parts are 0.
+ rational : % -> Fraction Integer
+ ++ rational(o) returns the real part if all seven
+ ++ imaginary parts are 0.
+ ++ Error: if o is not rational.
+ rationalIfCan: % -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(o) returns the real part if
+ ++ all seven imaginary parts are 0, and "failed" otherwise.
+ if R has Field then
+ inv : % -> %
+ ++ inv(o) returns the inverse of o if it exists.
+ add
+ characteristic() ==
+ characteristic()$R
+ conjugate x ==
+ octon(real x, - imagi x, - imagj x, - imagk x, - imagE x,_
+ - imagI x, - imagJ x, - imagK x)
+ map(fn, x) ==
+ octon(fn real x,fn imagi x,fn imagj x,fn imagk x, fn imagE x,_
+ fn imagI x, fn imagJ x,fn imagK x)
+ norm x ==
+ real x * real x + imagi x * imagi x + _
+ imagj x * imagj x + imagk x * imagk x + _
+ imagE x * imagE x + imagI x * imagI x + _
+ imagJ x * imagJ x + imagK x * imagK x
+ x = y ==
+ (real x = real y) and (imagi x = imagi y) and _
+ (imagj x = imagj y) and (imagk x = imagk y) and _
+ (imagE x = imagE y) and (imagI x = imagI y) and _
+ (imagJ x = imagJ y) and (imagK x = imagK y)
+ x + y ==
+ octon(real x + real y, imagi x + imagi y,_
+ imagj x + imagj y, imagk x + imagk y,_
+ imagE x + imagE y, imagI x + imagI y,_
+ imagJ x + imagJ y, imagK x + imagK y)
+ - x ==
+ octon(- real x, - imagi x, - imagj x, - imagk x,_
+ - imagE x, - imagI x, - imagJ x, - imagK x)
+ r:R * x:% ==
+ octon(r * real x, r * imagi x, r * imagj x, r * imagk x,_
+ r * imagE x, r * imagI x, r * imagJ x, r * imagK x)
+ n:Integer * x:% ==
+ octon(n * real x, n * imagi x, n * imagj x, n * imagk x,_
+ n * imagE x, n * imagI x, n * imagJ x, n * imagK x)
+ coerce(r:R) ==
+ octon(r,0$R,0$R,0$R,0$R,0$R,0$R,0$R)
+ coerce(n:Integer) ==
+ octon(n :: R,0$R,0$R,0$R,0$R,0$R,0$R,0$R)
+ zero? x ==
+ zero? real x and zero? imagi x and _
+ zero? imagj x and zero? imagk x and _
+ zero? imagE x and zero? imagI x and _
+ zero? imagJ x and zero? imagK x
+ retract(x):R ==
+ not (zero? imagi x and zero? imagj x and zero? imagk x and _
+ zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
+ error "Cannot retract octonion."
+ real x
+ retractIfCan(x):Union(R,"failed") ==
+ not (zero? imagi x and zero? imagj x and zero? imagk x and _
+ zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
+ "failed"
+ real x
+
+ coerce(x:%):OutputForm ==
+ part,z : OutputForm
+ y : %
+ zero? x => (0$R) :: OutputForm
+ not zero?(real x) =>
+ y := octon(0$R,imagi(x),imagj(x),imagk(x),imagE(x),
+ imagI(x),imagJ(x),imagK(x))
+ zero? y => real(x) :: OutputForm
+ (real(x) :: OutputForm) + (y :: OutputForm)
+ -- we know that the real part is 0
+ not zero?(imagi(x)) =>
+ y := octon(0$R,0$R,imagj(x),imagk(x),imagE(x),
+ imagI(x),imagJ(x),imagK(x))
+ z :=
+ part := "i"::Symbol::OutputForm
+-- one? imagi(x) => part
+ (imagi(x) = 1) => part
+ (imagi(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part and i part are 0
+ not zero?(imagj(x)) =>
+ y := octon(0$R,0$R,0$R,imagk(x),imagE(x),
+ imagI(x),imagJ(x),imagK(x))
+ z :=
+ part := "j"::Symbol::OutputForm
+-- one? imagj(x) => part
+ (imagj(x) = 1) => part
+ (imagj(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part and i and j parts are 0
+ not zero?(imagk(x)) =>
+ y := octon(0$R,0$R,0$R,0$R,imagE(x),
+ imagI(x),imagJ(x),imagK(x))
+ z :=
+ part := "k"::Symbol::OutputForm
+-- one? imagk(x) => part
+ (imagk(x) = 1) => part
+ (imagk(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part,i,j,k parts are 0
+ not zero?(imagE(x)) =>
+ y := octon(0$R,0$R,0$R,0$R,0$R,
+ imagI(x),imagJ(x),imagK(x))
+ z :=
+ part := "E"::Symbol::OutputForm
+-- one? imagE(x) => part
+ (imagE(x) = 1) => part
+ (imagE(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part,i,j,k,E parts are 0
+ not zero?(imagI(x)) =>
+ y := octon(0$R,0$R,0$R,0$R,0$R,0$R,imagJ(x),imagK(x))
+ z :=
+ part := "I"::Symbol::OutputForm
+-- one? imagI(x) => part
+ (imagI(x) = 1) => part
+ (imagI(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part,i,j,k,E,I parts are 0
+ not zero?(imagJ(x)) =>
+ y := octon(0$R,0$R,0$R,0$R,0$R,0$R,0$R,imagK(x))
+ z :=
+ part := "J"::Symbol::OutputForm
+-- one? imagJ(x) => part
+ (imagJ(x) = 1) => part
+ (imagJ(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part,i,j,k,E,I,J parts are 0
+ part := "K"::Symbol::OutputForm
+-- one? imagK(x) => part
+ (imagK(x) = 1) => part
+ (imagK(x) :: OutputForm) * part
+
+ if R has Field then
+ inv x ==
+ (norm x) = 0 => error "This octonion is not invertible."
+ (inv norm x) * conjugate x
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm ==
+ l : List InputForm := [convert("octon" :: Symbol),
+ convert(real x)$R, convert(imagi x)$R, convert(imagj x)$R,_
+ convert(imagk x)$R, convert(imagE x)$R,_
+ convert(imagI x)$R, convert(imagJ x)$R,_
+ convert(imagK x)$R]
+ convert(l)$InputForm
+ if R has OrderedSet then
+ x < y ==
+ real x = real y =>
+ imagi x = imagi y =>
+ imagj x = imagj y =>
+ imagk x = imagk y =>
+ imagE x = imagE y =>
+ imagI x = imagI y =>
+ imagJ x = imagJ y =>
+ imagK x < imagK y
+ imagJ x < imagJ y
+ imagI x < imagI y
+ imagE x < imagE y
+ imagk x < imagk y
+ imagj x < imagj y
+ imagi x < imagi y
+ real x < real y
+
+ if R has RealNumberSystem then
+ abs x == sqrt norm x
+
+ if R has IntegerNumberSystem then
+ rational? x ==
+ (zero? imagi x) and (zero? imagj x) and (zero? imagk x) and _
+ (zero? imagE x) and (zero? imagI x) and (zero? imagJ x) and _
+ (zero? imagK x)
+ rational x ==
+ rational? x => rational real x
+ error "Not a rational number"
+ rationalIfCan x ==
+ rational? x => rational real x
+ "failed"
+
+@
+\section{domain OCT Octonion}
+<<domain OCT Octonion>>=
+)abbrev domain OCT Octonion
+++ Author: R. Wisbauer, J. Grabmeier
+++ Date Created: 05 September 1990
+++ Date Last Updated: 20 September 1990
+++ Basic Operations: _+,_*,octon,image,imagi,imagj,imagk,
+++ imagE,imagI,imagJ,imagK
+++ Related Constructors: Quaternion
+++ Also See: AlgebraGivenByStructuralConstants
+++ AMS Classifications:
+++ Keywords: octonion, non-associative algebra, Cayley-Dixon
+++ References: e.g. I.L Kantor, A.S. Solodovnikov:
+++ Hypercomplex Numbers, Springer Verlag Heidelberg, 1989,
+++ ISBN 0-387-96980-2
+++ Description:
+++ Octonion implements octonions (Cayley-Dixon algebra) over a
+++ commutative ring, an eight-dimensional non-associative
+++ algebra, doubling the quaternions in the same way as doubling
+++ the complex numbers to get the quaternions
+++ the main constructor function is {\em octon} which takes 8
+++ arguments: the real part, the i imaginary part, the j
+++ imaginary part, the k imaginary part, (as with quaternions)
+++ and in addition the imaginary parts E, I, J, K.
+-- Examples: octonion.input
+--)boot $noSubsumption := true
+Octonion(R:CommutativeRing): export == impl where
+
+ QR ==> Quaternion R
+
+ export ==> Join(OctonionCategory R, FullyRetractableTo QR) with
+ octon: (QR,QR) -> %
+ ++ octon(qe,qE) constructs an octonion from two quaternions
+ ++ using the relation {\em O = Q + QE}.
+ impl ==> add
+ Rep := Record(e: QR,E: QR)
+
+ 0 == [0,0]
+ 1 == [1,0]
+
+ a,b,c,d,f,g,h,i : R
+ p,q : QR
+ x,y : %
+
+ real x == real (x.e)
+ imagi x == imagI (x.e)
+ imagj x == imagJ (x.e)
+ imagk x == imagK (x.e)
+ imagE x == real (x.E)
+ imagI x == imagI (x.E)
+ imagJ x == imagJ (x.E)
+ imagK x == imagK (x.E)
+ octon(a,b,c,d,f,g,h,i) == [quatern(a,b,c,d)$QR,quatern(f,g,h,i)$QR]
+ octon(p,q) == [p,q]
+ coerce(q) == [q,0$QR]
+ retract(x):QR ==
+ not(zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
+ error "Cannot retract octonion to quaternion."
+ quatern(real x, imagi x,imagj x, imagk x)$QR
+ retractIfCan(x):Union(QR,"failed") ==
+ not(zero? imagE x and zero? imagI x and zero? imagJ x and zero? imagK x)=>
+ "failed"
+ quatern(real x, imagi x,imagj x, imagk x)$QR
+ x * y == [x.e*y.e-(conjugate y.E)*x.E, y.E*x.e + x.E*(conjugate y.e)]
+
+@
+\section{package OCTCT2 OctonionCategoryFunctions2}
+<<package OCTCT2 OctonionCategoryFunctions2>>=
+)abbrev package OCTCT2 OctonionCategoryFunctions2
+--% OctonionCategoryFunctions2
+++ Author: Johannes Grabmeier
+++ Date Created: 10 September 1990
+++ Date Last Updated: 10 September 1990
+++ Basic Operations: map
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: octonion, non-associative algebra, Cayley-Dixon
+++ References:
+++ Description:
+++ OctonionCategoryFunctions2 implements functions between
+++ two octonion domains defined over different rings.
+++ The function map is used
+++ to coerce between octonion types.
+
+OctonionCategoryFunctions2(OR,R,OS,S) : Exports ==
+ Implementation where
+ R : CommutativeRing
+ S : CommutativeRing
+ OR : OctonionCategory R
+ OS : OctonionCategory S
+ Exports == with
+ map: (R -> S, OR) -> OS
+ ++ map(f,u) maps f onto the component parts of the octonion
+ ++ u.
+ Implementation == add
+ map(fn : R -> S, u : OR): OS ==
+ octon(fn real u, fn imagi u, fn imagj u, fn imagk u,_
+ fn imagE u, fn imagI u, fn imagJ u, fn imagK u)$OS
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category OC OctonionCategory>>
+<<domain OCT Octonion>>
+<<package OCTCT2 OctonionCategoryFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/odealg.spad.pamphlet b/src/algebra/odealg.spad.pamphlet
new file mode 100644
index 00000000..29a358d9
--- /dev/null
+++ b/src/algebra/odealg.spad.pamphlet
@@ -0,0 +1,393 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra odealg.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ODESYS SystemODESolver}
+<<package ODESYS SystemODESolver>>=
+)abbrev package ODESYS SystemODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 11 June 1991
+++ Date Last Updated: 13 April 1994
+++ Description: SystemODESolver provides tools for triangulating
+++ and solving some systems of linear ordinary differential equations.
+++ Keywords: differential equation, ODE, system
+SystemODESolver(F, LO): Exports == Implementation where
+ F : Field
+ LO: LinearOrdinaryDifferentialOperatorCategory F
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ MF ==> Matrix F
+ M ==> Matrix LO
+ V ==> Vector F
+ UF ==> Union(F, "failed")
+ UV ==> Union(V, "failed")
+ REC ==> Record(mat: M, vec: V)
+ FSL ==> Record(particular: UF, basis: List F)
+ VSL ==> Record(particular: UV, basis: List V)
+ SOL ==> Record(particular: F, basis: List F)
+ USL ==> Union(SOL, "failed")
+ ER ==> Record(C: MF, g: V, eq: LO, rh: F)
+
+ Exports ==> with
+ triangulate: (MF, V) -> Record(A:MF, eqs: List ER)
+ ++ triangulate(M,v) returns
+ ++ \spad{A,[[C_1,g_1,L_1,h_1],...,[C_k,g_k,L_k,h_k]]}
+ ++ such that under the change of variable \spad{y = A z}, the first
+ ++ order linear system \spad{D y = M y + v} is uncoupled as
+ ++ \spad{D z_i = C_i z_i + g_i} and each \spad{C_i} is a companion
+ ++ matrix corresponding to the scalar equation \spad{L_i z_j = h_i}.
+ triangulate: (M, V) -> REC
+ ++ triangulate(m, v) returns \spad{[m_0, v_0]} such that \spad{m_0}
+ ++ is upper triangular and the system \spad{m_0 x = v_0} is equivalent
+ ++ to \spad{m x = v}.
+ solve: (MF,V,(LO,F)->USL) -> Union(Record(particular:V, basis:MF), "failed")
+ ++ solve(m, v, solve) returns \spad{[[v_1,...,v_m], v_p]} such that
+ ++ the solutions in \spad{F} of the system \spad{D x = m x + v} are
+ ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
+ ++ constants, and the \spad{v_i's} form a basis for the solutions of
+ ++ \spad{D x = m x}.
+ ++ Argument \spad{solve} is a function for solving a single linear
+ ++ ordinary differential equation in \spad{F}.
+ solveInField: (M, V, (LO, F) -> FSL) -> VSL
+ ++ solveInField(m, v, solve) returns \spad{[[v_1,...,v_m], v_p]} such that
+ ++ the solutions in \spad{F} of the system \spad{m x = v} are
+ ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
+ ++ constants, and the \spad{v_i's} form a basis for the solutions of
+ ++ \spad{m x = 0}.
+ ++ Argument \spad{solve} is a function for solving a single linear
+ ++ ordinary differential equation in \spad{F}.
+
+ Implementation ==> add
+ import PseudoLinearNormalForm F
+
+ applyLodo : (M, Z, V, N) -> F
+ applyLodo0 : (M, Z, Matrix F, Z, N) -> F
+ backsolve : (M, V, (LO, F) -> FSL) -> VSL
+ firstnonzero: (M, Z) -> Z
+ FSL2USL : FSL -> USL
+ M2F : M -> Union(MF, "failed")
+
+ diff := D()$LO
+
+ solve(mm, v, solve) ==
+ rec := triangulate(mm, v)
+ sols:List(SOL) := empty()
+ for e in rec.eqs repeat
+ (u := solve(e.eq, e.rh)) case "failed" => return "failed"
+ sols := concat(u::SOL, sols)
+ n := nrows(rec.A) -- dimension of original vectorspace
+ k:N := 0 -- sum of sizes of visited companionblocks
+ i:N := 0 -- number of companionblocks
+ m:N := 0 -- number of Solutions
+ part:V := new(n, 0)
+ -- count first the different solutions
+ for sol in sols repeat m := m + count(#1 ^= 0, sol.basis)$List(F)
+ SolMatrix:MF := new(n, m, 0)
+ m := 0
+ for sol in reverse_! sols repeat
+ i := i+1
+ er := rec.eqs.i
+ nn := #(er.g) -- size of active companionblock
+ for s in sol.basis repeat
+ solVec:V := new(n, 0)
+ -- compute corresponding solution base with recursion (24)
+ solVec(k+1) := s
+ for l in 2..nn repeat solVec(k+l) := diff solVec(k+l-1)
+ m := m+1
+ setColumn!(SolMatrix, m, solVec)
+ -- compute with (24) the corresponding components of the part. sol.
+ part(k+1) := sol.particular
+ for l in 2..nn repeat part(k+l) := diff part(k+l-1) - (er.g)(l-1)
+ k := k+nn
+ -- transform these values back to the original system
+ [rec.A * part, rec.A * SolMatrix]
+
+ triangulate(m:MF, v:V) ==
+ k:N := 0 -- sum of companion-dimensions
+ rat := normalForm(m, 1, - diff #1)
+ l := companionBlocks(rat.R, rat.Ainv * v)
+ ler:List(ER) := empty()
+ for er in l repeat
+ n := nrows(er.C) -- dimension of this companion vectorspace
+ op:LO := 0 -- compute homogeneous equation
+ for j in 0..n-1 repeat op := op + monomial((er.C)(n, j + 1), j)
+ op := monomial(1, n) - op
+ sum:V := new(n::N, 0) -- compute inhomogen Vector (25)
+ for j in 1..n-1 repeat sum(j+1) := diff(sum j) + (er.g) j
+ h0:F := 0 -- compute inhomogenity (26)
+ for j in 1..n repeat h0 := h0 - (er.C)(n, j) * sum j
+ h0 := h0 + diff(sum n) + (er.g) n
+ ler := concat([er.C, er.g, op, h0], ler)
+ k := k + n
+ [rat.A, ler]
+
+-- like solveInField, but expects a system already triangularized
+ backsolve(m, v, solve) ==
+ part:V
+ r := maxRowIndex m
+ offset := minIndex v - (mr := minRowIndex m)
+ while r >= mr and every?(zero?, row(m, r))$Vector(LO) repeat r := r - 1
+ r < mr => error "backsolve: system has a 0 matrix"
+ (c := firstnonzero(m, r)) ^= maxColIndex m =>
+ error "backsolve: undetermined system"
+ rec := solve(m(r, c), v(r + offset))
+ dim := (r - mr + 1)::N
+ if (part? := ((u := rec.particular) case F)) then
+ part := new(dim, 0) -- particular solution
+ part(r + offset) := u::F
+-- hom is the basis for the homogeneous solutions, each column is a solution
+ hom:Matrix(F) := new(dim, #(rec.basis), 0)
+ for i in minColIndex hom .. maxColIndex hom for b in rec.basis repeat
+ hom(r, i) := b
+ n:N := 1 -- number of equations already solved
+ while r > mr repeat
+ r := r - 1
+ c := c - 1
+ firstnonzero(m, r) ^= c => error "backsolve: undetermined system"
+ degree(eq := m(r, c)) > 0 => error "backsolve: pivot of order > 0"
+ a := leadingCoefficient(eq)::F
+ if part? then
+ part(r + offset) := (v(r + offset) - applyLodo(m, r, part, n)) / a
+ for i in minColIndex hom .. maxColIndex hom repeat
+ hom(r, i) := - applyLodo0(m, r, hom, i, n)
+ n := n + 1
+ bas:List(V) := [column(hom,i) for i in minColIndex hom..maxColIndex hom]
+ part? => [part, bas]
+ ["failed", bas]
+
+ solveInField(m, v, solve) ==
+ ((n := nrows m) = ncols m) and
+ ((u := M2F(diagonalMatrix [diff for i in 1..n] - m)) case MF) =>
+ (uu := solve(u::MF, v, FSL2USL solve(#1, #2))) case "failed" =>
+ ["failed", empty()]
+ rc := uu::Record(particular:V, basis:MF)
+ [rc.particular, [column(rc.basis, i) for i in 1..ncols(rc.basis)]]
+ rec := triangulate(m, v)
+ backsolve(rec.mat, rec.vec, solve)
+
+ M2F m ==
+ mf:MF := new(nrows m, ncols m, 0)
+ for i in minRowIndex m .. maxRowIndex m repeat
+ for j in minColIndex m .. maxColIndex m repeat
+ (u := retractIfCan(m(i, j))@Union(F, "failed")) case "failed" =>
+ return "failed"
+ mf(i, j) := u::F
+ mf
+
+ FSL2USL rec ==
+ rec.particular case "failed" => "failed"
+ [rec.particular::F, rec.basis]
+
+-- returns the index of the first nonzero entry in row r of m
+ firstnonzero(m, r) ==
+ for c in minColIndex m .. maxColIndex m repeat
+ m(r, c) ^= 0 => return c
+ error "firstnonzero: zero row"
+
+-- computes +/[m(r, i) v(i) for i ranging over the last n columns of m]
+ applyLodo(m, r, v, n) ==
+ ans:F := 0
+ c := maxColIndex m
+ cv := maxIndex v
+ for i in 1..n repeat
+ ans := ans + m(r, c) (v cv)
+ c := c - 1
+ cv := cv - 1
+ ans
+
+-- computes +/[m(r, i) mm(i, c) for i ranging over the last n columns of m]
+ applyLodo0(m, r, mm, c, n) ==
+ ans := 0
+ rr := maxRowIndex mm
+ cc := maxColIndex m
+ for i in 1..n repeat
+ ans := ans + m(r, cc) mm(rr, c)
+ cc := cc - 1
+ rr := rr - 1
+ ans
+
+ triangulate(m:M, v:V) ==
+ x := copy m
+ w := copy v
+ nrows := maxRowIndex x
+ ncols := maxColIndex x
+ minr := i := minRowIndex x
+ offset := minIndex w - minr
+ for j in minColIndex x .. ncols repeat
+ if i > nrows then leave x
+ rown := minr - 1
+ for k in i .. nrows repeat
+ if (x(k, j) ^= 0) and ((rown = minr - 1) or
+ degree x(k,j) < degree x(rown,j)) then rown := k
+ rown = minr - 1 => "enuf"
+ x := swapRows_!(x, i, rown)
+ swap_!(w, i + offset, rown + offset)
+ for k in i+1 .. nrows | x(k, j) ^= 0 repeat
+ l := rightLcm(x(i,j), x(k,j))
+ a := rightQuotient(l, x(i, j))
+ b := rightQuotient(l, x(k, j))
+ -- l = a x(i,j) = b x(k,j)
+ for k1 in j+1 .. ncols repeat
+ x(k, k1) := a * x(i, k1) - b * x(k, k1)
+ x(k, j) := 0
+ w(k + offset) := a(w(i + offset)) - b(w(k + offset))
+ i := i+1
+ [x, w]
+
+@
+\section{package ODERED ReduceLODE}
+<<package ODERED ReduceLODE>>=
+)abbrev package ODERED ReduceLODE
+++ Author: Manuel Bronstein
+++ Date Created: 19 August 1991
+++ Date Last Updated: 11 April 1994
+++ Description: Elimination of an algebraic from the coefficentss
+++ of a linear ordinary differential equation.
+ReduceLODE(F, L, UP, A, LO): Exports == Implementation where
+ F : Field
+ L : LinearOrdinaryDifferentialOperatorCategory F
+ UP: UnivariatePolynomialCategory F
+ A : MonogenicAlgebra(F, UP)
+ LO: LinearOrdinaryDifferentialOperatorCategory A
+
+ V ==> Vector F
+ M ==> Matrix L
+
+ Exports ==> with
+ reduceLODE: (LO, A) -> Record(mat:M, vec:V)
+ ++ reduceLODE(op, g) returns \spad{[m, v]} such that
+ ++ any solution in \spad{A} of \spad{op z = g}
+ ++ is of the form \spad{z = (z_1,...,z_m) . (b_1,...,b_m)} where
+ ++ the \spad{b_i's} are the basis of \spad{A} over \spad{F} returned
+ ++ by \spadfun{basis}() from \spad{A}, and the \spad{z_i's} satisfy the
+ ++ differential system \spad{M.z = v}.
+
+ Implementation ==> add
+ matF2L: Matrix F -> M
+
+ diff := D()$L
+
+-- coerces a matrix of elements of F into a matrix of (order 0) L.O.D.O's
+ matF2L m ==
+ map(#1::L, m)$MatrixCategoryFunctions2(F, V, V, Matrix F,
+ L, Vector L, Vector L, M)
+
+-- This follows the algorithm and notation of
+-- "The Risch Differential Equation on an Algebraic Curve", M. Bronstein,
+-- in 'Proceedings of ISSAC '91', Bonn, BRD, ACM Press, pp.241-246, July 1991.
+ reduceLODE(l, g) ==
+ n := rank()$A
+-- md is the basic differential matrix (D x I + Dy)
+ md := matF2L transpose derivationCoordinates(basis(), diff #1)
+ for i in minRowIndex md .. maxRowIndex md
+ for j in minColIndex md .. maxColIndex md repeat
+ md(i, j) := diff + md(i, j)
+-- mdi will go through the successive powers of md
+ mdi := copy md
+ sys := matF2L(transpose regularRepresentation coefficient(l, 0))
+ for i in 1..degree l repeat
+ sys := sys +
+ matF2L(transpose regularRepresentation coefficient(l, i)) * mdi
+ mdi := md * mdi
+ [sys, coordinates g]
+
+@
+\section{package ODEPAL PureAlgebraicLODE}
+<<package ODEPAL PureAlgebraicLODE>>=
+)abbrev package ODEPAL PureAlgebraicLODE
+++ Author: Manuel Bronstein
+++ Date Created: 21 August 1991
+++ Date Last Updated: 3 February 1994
+++ Description: In-field solution of an linear ordinary differential equation,
+++ pure algebraic case.
+PureAlgebraicLODE(F, UP, UPUP, R): Exports == Implementation where
+ F : Join(Field, CharacteristicZero,
+ RetractableTo Integer, RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ RF ==> Fraction UP
+ V ==> Vector RF
+ U ==> Union(R, "failed")
+ REC ==> Record(particular: Union(RF, "failed"), basis: List RF)
+ L ==> LinearOrdinaryDifferentialOperator1 R
+ LQ ==> LinearOrdinaryDifferentialOperator1 RF
+
+ Exports ==> with
+ algDsolve: (L, R) -> Record(particular: U, basis: List R)
+ ++ algDsolve(op, g) returns \spad{["failed", []]} if the equation
+ ++ \spad{op y = g} has no solution in \spad{R}. Otherwise, it returns
+ ++ \spad{[f, [y1,...,ym]]} where \spad{f} is a particular rational
+ ++ solution and the \spad{y_i's} form a basis for the solutions in
+ ++ \spad{R} of the homogeneous equation.
+
+ Implementation ==> add
+ import RationalLODE(F, UP)
+ import SystemODESolver(RF, LQ)
+ import ReduceLODE(RF, LQ, UPUP, R, L)
+
+ algDsolve(l, g) ==
+ rec := reduceLODE(l, g)
+ sol := solveInField(rec.mat, rec.vec, ratDsolve)
+ bas:List(R) := [represents v for v in sol.basis]
+ (u := sol.particular) case V => [represents(u::V), bas]
+ ["failed", bas]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad odeef.spad
+
+<<package ODESYS SystemODESolver>>
+<<package ODERED ReduceLODE>>
+<<package ODEPAL PureAlgebraicLODE>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/odeef.spad.pamphlet b/src/algebra/odeef.spad.pamphlet
new file mode 100644
index 00000000..734344a9
--- /dev/null
+++ b/src/algebra/odeef.spad.pamphlet
@@ -0,0 +1,643 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra odeef.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REDORDER ReductionOfOrder}
+<<package REDORDER ReductionOfOrder>>=
+)abbrev package REDORDER ReductionOfOrder
+++ Author: Manuel Bronstein
+++ Date Created: 4 November 1991
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spadtype{ReductionOfOrder} provides
+++ functions for reducing the order of linear ordinary differential equations
+++ once some solutions are known.
+++ Keywords: differential equation, ODE
+ReductionOfOrder(F, L): Exports == Impl where
+ F: Field
+ L: LinearOrdinaryDifferentialOperatorCategory F
+
+ Z ==> Integer
+ A ==> PrimitiveArray F
+
+ Exports ==> with
+ ReduceOrder: (L, F) -> L
+ ++ ReduceOrder(op, s) returns \spad{op1} such that for any solution
+ ++ \spad{z} of \spad{op1 z = 0}, \spad{y = s \int z} is a solution of
+ ++ \spad{op y = 0}. \spad{s} must satisfy \spad{op s = 0}.
+ ReduceOrder: (L, List F) -> Record(eq:L, op:List F)
+ ++ ReduceOrder(op, [f1,...,fk]) returns \spad{[op1,[g1,...,gk]]} such that
+ ++ for any solution \spad{z} of \spad{op1 z = 0},
+ ++ \spad{y = gk \int(g_{k-1} \int(... \int(g1 \int z)...)} is a solution
+ ++ of \spad{op y = 0}. Each \spad{fi} must satisfy \spad{op fi = 0}.
+
+ Impl ==> add
+ ithcoef : (L, Z, A) -> F
+ locals : (A, Z, Z) -> F
+ localbinom: (Z, Z) -> Z
+
+ diff := D()$L
+
+ localbinom(j, i) == (j > i => binomial(j, i+1); 0)
+ locals(s, j, i) == (j > i => qelt(s, j - i - 1); 0)
+
+ ReduceOrder(l:L, sols:List F) ==
+ empty? sols => [l, empty()]
+ neweq := ReduceOrder(l, sol := first sols)
+ rec := ReduceOrder(neweq, [diff(s / sol) for s in rest sols])
+ [rec.eq, concat_!(rec.op, sol)]
+
+ ithcoef(eq, i, s) ==
+ ans:F := 0
+ while eq ^= 0 repeat
+ j := degree eq
+ ans := ans + localbinom(j, i) * locals(s,j,i) * leadingCoefficient eq
+ eq := reductum eq
+ ans
+
+ ReduceOrder(eq:L, sol:F) ==
+ s:A := new(n := degree eq, 0) -- will contain derivatives of sol
+ si := sol -- will run through the derivatives
+ qsetelt_!(s, 0, si)
+ for i in 1..(n-1)::NonNegativeInteger repeat
+ qsetelt_!(s, i, si := diff si)
+ ans:L := 0
+ for i in 0..(n-1)::NonNegativeInteger repeat
+ ans := ans + monomial(ithcoef(eq, i, s), i)
+ ans
+
+@
+\section{package LODEEF ElementaryFunctionLODESolver}
+<<package LODEEF ElementaryFunctionLODESolver>>=
+)abbrev package LODEEF ElementaryFunctionLODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 3 February 1994
+++ Date Last Updated: 9 March 1994
+++ Description:
+++ \spad{ElementaryFunctionLODESolver} provides the top-level
+++ functions for finding closed form solutions of linear ordinary
+++ differential equations and initial value problems.
+++ Keywords: differential equation, ODE
+ElementaryFunctionLODESolver(R, F, L): Exports == Implementation where
+ R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, CharacteristicZero)
+ F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+ PrimitiveFunctionCategory)
+ L: LinearOrdinaryDifferentialOperatorCategory F
+
+ SY ==> Symbol
+ N ==> NonNegativeInteger
+ K ==> Kernel F
+ V ==> Vector F
+ M ==> Matrix F
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ UPUP==> SparseUnivariatePolynomial RF
+ P ==> SparseMultivariatePolynomial(R, K)
+ P2 ==> SparseMultivariatePolynomial(P, K)
+ LQ ==> LinearOrdinaryDifferentialOperator1 RF
+ REC ==> Record(particular: F, basis: List F)
+ U ==> Union(REC, "failed")
+ ALGOP ==> "%alg"
+
+ Exports ==> with
+ solve: (L, F, SY) -> U
+ ++ solve(op, g, x) returns either a solution of the ordinary differential
+ ++ equation \spad{op y = g} or "failed" if no non-trivial solution can be
+ ++ found; When found, the solution is returned in the form
+ ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution and
+ ++ and \spad{[b1,...bm]} are linearly independent solutions of the
+ ++ associated homogenuous equation \spad{op y = 0}.
+ ++ A full basis for the solutions of the homogenuous equation
+ ++ is not always returned, only the solutions which were found;
+ ++ \spad{x} is the dependent variable.
+ solve: (L, F, SY, F, List F) -> Union(F, "failed")
+ ++ solve(op, g, x, a, [y0,...,ym]) returns either the solution
+ ++ of the initial value problem \spad{op y = g, y(a) = y0, y'(a) = y1,...}
+ ++ or "failed" if the solution cannot be found;
+ ++ \spad{x} is the dependent variable.
+
+ Implementation ==> add
+ import Kovacic(F, UP)
+ import ODETools(F, L)
+ import RationalLODE(F, UP)
+ import RationalRicDE(F, UP)
+ import ODEIntegration(R, F)
+ import ConstantLODE(R, F, L)
+ import IntegrationTools(R, F)
+ import ReductionOfOrder(F, L)
+ import ReductionOfOrder(RF, LQ)
+ import PureAlgebraicIntegration(R, F, L)
+ import FunctionSpacePrimitiveElement(R, F)
+ import LinearSystemMatrixPackage(F, V, V, M)
+ import SparseUnivariatePolynomialFunctions2(RF, F)
+ import FunctionSpaceUnivariatePolynomialFactor(R, F, UP)
+ import LinearOrdinaryDifferentialOperatorFactorizer(F, UP)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+ upmp : (P, List K) -> P2
+ downmp : (P2, List K, List P) -> P
+ xpart : (F, SY) -> F
+ smpxpart : (P, SY, List K, List P) -> P
+ multint : (F, List F, SY) -> F
+ ulodo : (L, K) -> LQ
+ firstOrder : (F, F, F, SY) -> REC
+ rfSolve : (L, F, K, SY) -> U
+ ratlogsol : (LQ, List RF, K, SY) -> List F
+ expsols : (LQ, K, SY) -> List F
+ homosolve : (L, LQ, List RF, K, SY) -> List F
+ homosolve1 : (L, List F, K, SY) -> List F
+ norf1 : (L, K, SY, N) -> List F
+ kovode : (LQ, K, SY) -> List F
+ doVarParams: (L, F, List F, SY) -> U
+ localmap : (F -> F, L) -> L
+ algSolve : (L, F, K, List K, SY) -> U
+ palgSolve : (L, F, K, K, SY) -> U
+ lastChance : (L, F, SY) -> U
+
+ diff := D()$L
+
+ smpxpart(p, x, l, lp) == downmp(primitivePart upmp(p, l), l, lp)
+ downmp(p, l, lp) == ground eval(p, l, lp)
+ homosolve(lf, op, sols, k, x) == homosolve1(lf, ratlogsol(op,sols,k,x),k,x)
+
+-- left hand side has algebraic (not necessarily pure) coefficients
+ algSolve(op, g, k, l, x) ==
+ symbolIfCan(kx := ksec(k, l, x)) case SY => palgSolve(op, g, kx, k, x)
+ has?(operator kx, ALGOP) =>
+ rec := primitiveElement(kx::F, k::F)
+ z := rootOf(rec.prim)
+ lk:List K := [kx, k]
+ lv:List F := [(rec.pol1) z, (rec.pol2) z]
+ (u := solve(localmap(eval(#1, lk, lv), op), eval(g, lk, lv), x))
+ case "failed" => "failed"
+ rc := u::REC
+ kz := retract(z)@K
+ [eval(rc.particular, kz, rec.primelt),
+ [eval(f, kz, rec.primelt) for f in rc.basis]]
+ lastChance(op, g, x)
+
+ doVarParams(eq, g, bas, x) ==
+ (u := particularSolution(eq, g, bas, int(#1, x))) case "failed" =>
+ lastChance(eq, g, x)
+ [u::F, bas]
+
+ lastChance(op, g, x) ==
+-- one? degree op => firstOrder(coefficient(op,0), leadingCoefficient op,g,x)
+ (degree op) = 1 => firstOrder(coefficient(op,0), leadingCoefficient op,g,x)
+ "failed"
+
+-- solves a0 y + a1 y' = g
+-- does not check whether there is a solution in the field generated by
+-- a0, a1 and g
+ firstOrder(a0, a1, g, x) ==
+ h := xpart(expint(- a0 / a1, x), x)
+ [h * int((g / h) / a1, x), [h]]
+
+-- xpart(f,x) removes any constant not involving x from f
+ xpart(f, x) ==
+ l := reverse_! varselect(tower f, x)
+ lp := [k::P for k in l]
+ smpxpart(numer f, x, l, lp) / smpxpart(denom f, x, l, lp)
+
+ upmp(p, l) ==
+ empty? l => p::P2
+ up := univariate(p, k := first l)
+ l := rest l
+ ans:P2 := 0
+ while up ^= 0 repeat
+ ans := ans + monomial(upmp(leadingCoefficient up, l), k, degree up)
+ up := reductum up
+ ans
+
+-- multint(a, [g1,...,gk], x) returns gk \int(g(k-1) \int(....g1 \int(a))...)
+ multint(a, l, x) ==
+ for g in l repeat a := g * xpart(int(a, x), x)
+ a
+
+ expsols(op, k, x) ==
+-- one? degree op =>
+ (degree op) = 1 =>
+ firstOrder(multivariate(coefficient(op, 0), k),
+ multivariate(leadingCoefficient op, k), 0, x).basis
+ [xpart(expint(multivariate(h, k), x), x) for h in ricDsolve(op, ffactor)]
+
+-- Finds solutions with rational logarithmic derivative
+ ratlogsol(oper, sols, k, x) ==
+ bas := [xpart(multivariate(h, k), x) for h in sols]
+ degree(oper) = #bas => bas -- all solutions are found already
+ rec := ReduceOrder(oper, sols)
+ le := expsols(rec.eq, k, x)
+ int:List(F) := [xpart(multivariate(h, k), x) for h in rec.op]
+ concat_!([xpart(multivariate(h, k), x) for h in sols],
+ [multint(e, int, x) for e in le])
+
+ homosolve1(oper, sols, k, x) ==
+ zero?(n := (degree(oper) - #sols)::N) => sols -- all solutions found
+ rec := ReduceOrder(oper, sols)
+ int:List(F) := [xpart(h, x) for h in rec.op]
+ concat_!(sols, [multint(e, int, x) for e in norf1(rec.eq, k, x, n::N)])
+
+-- if the coefficients are rational functions, then the equation does not
+-- not have a proper 1st-order right factor over the rational functions
+ norf1(op, k, x, n) ==
+-- one? n => firstOrder(coefficient(op, 0), leadingCoefficient op,0,x).basis
+ (n = 1) => firstOrder(coefficient(op, 0), leadingCoefficient op,0,x).basis
+-- for order > 2, we check that the coeffs are still rational functions
+ symbolIfCan(kmax vark(coefficients op, x)) case SY =>
+ eq := ulodo(op, k)
+ n = 2 => kovode(eq, k, x)
+ eq := last factor1 eq -- eq cannot have order 1
+ degree(eq) = 2 =>
+ empty?(bas := kovode(eq, k, x)) => empty()
+ homosolve1(op, bas, k, x)
+ empty()
+ empty()
+
+ kovode(op, k, x) ==
+ b := coefficient(op, 1)
+ a := coefficient(op, 2)
+ (u := kovacic(coefficient(op, 0), b, a, ffactor)) case "failed" => empty()
+ p := map(multivariate(#1, k), u::UPUP)
+ ba := multivariate(- b / a, k)
+-- if p has degree 2 (case 2), then it must be squarefree since the
+-- ode is irreducible over the rational functions, so the 2 roots of p
+-- are distinct and must yield 2 independent solutions.
+ degree(p) = 2 => [xpart(expint(ba/(2::F) + e, x), x) for e in zerosOf p]
+-- otherwise take 1 root of p and find the 2nd solution by reduction of order
+ y1 := xpart(expint(ba / (2::F) + zeroOf p, x), x)
+ [y1, y1 * xpart(int(expint(ba, x) / y1**2, x), x)]
+
+ solve(op:L, g:F, x:SY) ==
+ empty?(l := vark(coefficients op, x)) => constDsolve(op, g, x)
+ symbolIfCan(k := kmax l) case SY => rfSolve(op, g, k, x)
+ has?(operator k, ALGOP) => algSolve(op, g, k, l, x)
+ lastChance(op, g, x)
+
+ ulodo(eq, k) ==
+ op:LQ := 0
+ while eq ^= 0 repeat
+ op := op + monomial(univariate(leadingCoefficient eq, k), degree eq)
+ eq := reductum eq
+ op
+
+-- left hand side has rational coefficients
+ rfSolve(eq, g, k, x) ==
+ op := ulodo(eq, k)
+ empty? remove_!(k, varselect(kernels g, x)) => -- i.e. rhs is rational
+ rc := ratDsolve(op, univariate(g, k))
+ rc.particular case "failed" => -- this implies g ^= 0
+ doVarParams(eq, g, homosolve(eq, op, rc.basis, k, x), x)
+ [multivariate(rc.particular::RF, k), homosolve(eq, op, rc.basis, k, x)]
+ doVarParams(eq, g, homosolve(eq, op, ratDsolve(op, 0).basis, k, x), x)
+
+ solve(op, g, x, a, y0) ==
+ (u := solve(op, g, x)) case "failed" => "failed"
+ hp := h := (u::REC).particular
+ b := (u::REC).basis
+ v:V := new(n := #y0, 0)
+ kx:K := kernel x
+ for i in minIndex v .. maxIndex v for yy in y0 repeat
+ v.i := yy - eval(h, kx, a)
+ h := diff h
+ (sol := particularSolution(map_!(eval(#1,kx,a),wronskianMatrix(b,n)), v))
+ case "failed" => "failed"
+ for f in b for i in minIndex(s := sol::V) .. repeat
+ hp := hp + s.i * f
+ hp
+
+ localmap(f, op) ==
+ ans:L := 0
+ while op ^= 0 repeat
+ ans := ans + monomial(f leadingCoefficient op, degree op)
+ op := reductum op
+ ans
+
+-- left hand side has pure algebraic coefficients
+ palgSolve(op, g, kx, k, x) ==
+ rec := palgLODE(op, g, kx, k, x) -- finds solutions in the coef. field
+ rec.particular case "failed" =>
+ doVarParams(op, g, homosolve1(op, rec.basis, k, x), x)
+ [(rec.particular)::F, homosolve1(op, rec.basis, k, x)]
+
+@
+\section{package ODEEF ElementaryFunctionODESolver}
+<<package ODEEF ElementaryFunctionODESolver>>=
+)abbrev package ODEEF ElementaryFunctionODESolver
+++ Author: Manuel Bronstein
+++ Date Created: 18 March 1991
+++ Date Last Updated: 8 March 1994
+++ Description:
+++ \spad{ElementaryFunctionODESolver} provides the top-level
+++ functions for finding closed form solutions of ordinary
+++ differential equations and initial value problems.
+++ Keywords: differential equation, ODE
+ElementaryFunctionODESolver(R, F): Exports == Implementation where
+ R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, CharacteristicZero)
+ F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+ PrimitiveFunctionCategory)
+
+ N ==> NonNegativeInteger
+ OP ==> BasicOperator
+ SY ==> Symbol
+ K ==> Kernel F
+ EQ ==> Equation F
+ V ==> Vector F
+ M ==> Matrix F
+ UP ==> SparseUnivariatePolynomial F
+ P ==> SparseMultivariatePolynomial(R, K)
+ LEQ ==> Record(left:UP, right:F)
+ NLQ ==> Record(dx:F, dy:F)
+ REC ==> Record(particular: F, basis: List F)
+ VEC ==> Record(particular: V, basis: List V)
+ ROW ==> Record(index: Integer, row: V, rh: F)
+ SYS ==> Record(mat:M, vec: V)
+ U ==> Union(REC, F, "failed")
+ UU ==> Union(F, "failed")
+ OPDIFF ==> "%diff"::SY
+
+ Exports ==> with
+ solve: (M, V, SY) -> Union(VEC, "failed")
+ ++ solve(m, v, x) returns \spad{[v_p, [v_1,...,v_m]]} such that
+ ++ the solutions of the system \spad{D y = m y + v} are
+ ++ \spad{v_p + c_1 v_1 + ... + c_m v_m} where the \spad{c_i's} are
+ ++ constants, and the \spad{v_i's} form a basis for the solutions of
+ ++ \spad{D y = m y}.
+ ++ \spad{x} is the dependent variable.
+ solve: (M, SY) -> Union(List V, "failed")
+ ++ solve(m, x) returns a basis for the solutions of \spad{D y = m y}.
+ ++ \spad{x} is the dependent variable.
+ solve: (List EQ, List OP, SY) -> Union(VEC, "failed")
+ ++ solve([eq_1,...,eq_n], [y_1,...,y_n], x) returns either "failed"
+ ++ or, if the equations form a fist order linear system, a solution
+ ++ of the form \spad{[y_p, [b_1,...,b_n]]} where \spad{h_p} is a
+ ++ particular solution and \spad{[b_1,...b_m]} are linearly independent
+ ++ solutions of the associated homogenuous system.
+ ++ error if the equations do not form a first order linear system
+ solve: (List F, List OP, SY) -> Union(VEC, "failed")
+ ++ solve([eq_1,...,eq_n], [y_1,...,y_n], x) returns either "failed"
+ ++ or, if the equations form a fist order linear system, a solution
+ ++ of the form \spad{[y_p, [b_1,...,b_n]]} where \spad{h_p} is a
+ ++ particular solution and \spad{[b_1,...b_m]} are linearly independent
+ ++ solutions of the associated homogenuous system.
+ ++ error if the equations do not form a first order linear system
+ solve: (EQ, OP, SY) -> U
+ ++ solve(eq, y, x) returns either a solution of the ordinary differential
+ ++ equation \spad{eq} or "failed" if no non-trivial solution can be found;
+ ++ If the equation is linear ordinary, a solution is of the form
+ ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution
+ ++ and \spad{[b1,...bm]} are linearly independent solutions of the
+ ++ associated homogenuous equation \spad{f(x,y) = 0};
+ ++ A full basis for the solutions of the homogenuous equation
+ ++ is not always returned, only the solutions which were found;
+ ++ If the equation is of the form {dy/dx = f(x,y)}, a solution is of
+ ++ the form \spad{h(x,y)} where \spad{h(x,y) = c} is a first integral
+ ++ of the equation for any constant \spad{c};
+ ++ error if the equation is not one of those 2 forms;
+ solve: (F, OP, SY) -> U
+ ++ solve(eq, y, x) returns either a solution of the ordinary differential
+ ++ equation \spad{eq} or "failed" if no non-trivial solution can be found;
+ ++ If the equation is linear ordinary, a solution is of the form
+ ++ \spad{[h, [b1,...,bm]]} where \spad{h} is a particular solution and
+ ++ and \spad{[b1,...bm]} are linearly independent solutions of the
+ ++ associated homogenuous equation \spad{f(x,y) = 0};
+ ++ A full basis for the solutions of the homogenuous equation
+ ++ is not always returned, only the solutions which were found;
+ ++ If the equation is of the form {dy/dx = f(x,y)}, a solution is of
+ ++ the form \spad{h(x,y)} where \spad{h(x,y) = c} is a first integral
+ ++ of the equation for any constant \spad{c};
+ solve: (EQ, OP, EQ, List F) -> UU
+ ++ solve(eq, y, x = a, [y0,...,ym]) returns either the solution
+ ++ of the initial value problem \spad{eq, y(a) = y0, y'(a) = y1,...}
+ ++ or "failed" if the solution cannot be found;
+ ++ error if the equation is not one linear ordinary or of the form
+ ++ \spad{dy/dx = f(x,y)};
+ solve: (F, OP, EQ, List F) -> UU
+ ++ solve(eq, y, x = a, [y0,...,ym]) returns either the solution
+ ++ of the initial value problem \spad{eq, y(a) = y0, y'(a) = y1,...}
+ ++ or "failed" if the solution cannot be found;
+ ++ error if the equation is not one linear ordinary or of the form
+ ++ \spad{dy/dx = f(x,y)};
+
+ Implementation ==> add
+ import ODEIntegration(R, F)
+ import IntegrationTools(R, F)
+ import NonLinearFirstOrderODESolver(R, F)
+
+ getfreelincoeff : (F, K, SY) -> F
+ getfreelincoeff1: (F, K, List F) -> F
+ getlincoeff : (F, K) -> F
+ getcoeff : (F, K) -> UU
+ parseODE : (F, OP, SY) -> Union(LEQ, NLQ)
+ parseLODE : (F, List K, UP, SY) -> LEQ
+ parseSYS : (List F, List OP, SY) -> Union(SYS, "failed")
+ parseSYSeq : (F, List K, List K, List F, SY) -> Union(ROW, "failed")
+
+ solve(diffeq:EQ, y:OP, x:SY) == solve(lhs diffeq - rhs diffeq, y, x)
+
+ solve(leq: List EQ, lop: List OP, x:SY) ==
+ solve([lhs eq - rhs eq for eq in leq], lop, x)
+
+ solve(diffeq:EQ, y:OP, center:EQ, y0:List F) ==
+ solve(lhs diffeq - rhs diffeq, y, center, y0)
+
+ solve(m:M, x:SY) ==
+ (u := solve(m, new(nrows m, 0), x)) case "failed" => "failed"
+ u.basis
+
+ solve(m:M, v:V, x:SY) ==
+ Lx := LinearOrdinaryDifferentialOperator(F, diff x)
+ uu := solve(m, v, solve(#1, #2,
+ x)$ElementaryFunctionLODESolver(R, F, Lx))$SystemODESolver(F, Lx)
+ uu case "failed" => "failed"
+ rec := uu::Record(particular: V, basis: M)
+ [rec.particular, [column(rec.basis, i) for i in 1..ncols(rec.basis)]]
+
+ solve(diffeq:F, y:OP, center:EQ, y0:List F) ==
+ a := rhs center
+ kx:K := kernel(x := retract(lhs(center))@SY)
+ (ur := parseODE(diffeq, y, x)) case NLQ =>
+-- not one?(#y0) => error "solve: more than one initial condition!"
+ not ((#y0) = 1) => error "solve: more than one initial condition!"
+ rc := ur::NLQ
+ (u := solve(rc.dx, rc.dy, y, x)) case "failed" => "failed"
+ u::F - eval(u::F, [kx, retract(y(x::F))@K], [a, first y0])
+ rec := ur::LEQ
+ p := rec.left
+ Lx := LinearOrdinaryDifferentialOperator(F, diff x)
+ op:Lx := 0
+ while p ^= 0 repeat
+ op := op + monomial(leadingCoefficient p, degree p)
+ p := reductum p
+ solve(op, rec.right, x, a, y0)$ElementaryFunctionLODESolver(R, F, Lx)
+
+ solve(leq: List F, lop: List OP, x:SY) ==
+ (u := parseSYS(leq, lop, x)) case SYS =>
+ rec := u::SYS
+ solve(rec.mat, rec.vec, x)
+ error "solve: not a first order linear system"
+
+ solve(diffeq:F, y:OP, x:SY) ==
+ (u := parseODE(diffeq, y, x)) case NLQ =>
+ rc := u::NLQ
+ (uu := solve(rc.dx, rc.dy, y, x)) case "failed" => "failed"
+ uu::F
+ rec := u::LEQ
+ p := rec.left
+ Lx := LinearOrdinaryDifferentialOperator(F, diff x)
+ op:Lx := 0
+ while p ^= 0 repeat
+ op := op + monomial(leadingCoefficient p, degree p)
+ p := reductum p
+ (uuu := solve(op, rec.right, x)$ElementaryFunctionLODESolver(R, F, Lx))
+ case "failed" => "failed"
+ uuu::REC
+
+-- returns [M, v] s.t. the equations are D x = M x + v
+ parseSYS(eqs, ly, x) ==
+ (n := #eqs) ^= #ly => "failed"
+ m:M := new(n, n, 0)
+ v:V := new(n, 0)
+ xx := x::F
+ lf := [y xx for y in ly]
+ lk0:List(K) := [retract(f)@K for f in lf]
+ lk1:List(K) := [retract(differentiate(f, x))@K for f in lf]
+ for eq in eqs repeat
+ (u := parseSYSeq(eq,lk0,lk1,lf,x)) case "failed" => return "failed"
+ rec := u::ROW
+ setRow_!(m, rec.index, rec.row)
+ v(rec.index) := rec.rh
+ [m, v]
+
+ parseSYSeq(eq, l0, l1, lf, x) ==
+ l := [k for k in varselect(kernels eq, x) | is?(k, OPDIFF)]
+ empty? l or not empty? rest l or zero?(n := position(k := first l,l1)) =>
+ "failed"
+ c := getfreelincoeff1(eq, k, lf)
+ eq := eq - c * k::F
+ v:V := new(#l0, 0)
+ for y in l0 for i in 1.. repeat
+ ci := getfreelincoeff1(eq, y, lf)
+ v.i := - ci / c
+ eq := eq - ci * y::F
+ [n, v, -eq]
+
+-- returns either [p, g] where the equation (diffeq) is of the form p(D)(y) = g
+-- or [p, q] such that the equation (diffeq) is of the form p dx + q dy = 0
+ parseODE(diffeq, y, x) ==
+ f := y(x::F)
+ l:List(K) := [retract(f)@K]
+ n:N := 2
+ for k in varselect(kernels diffeq, x) | is?(k, OPDIFF) repeat
+ if (m := height k) > n then n := m
+ n := (n - 2)::N
+-- build a list of kernels in the order [y^(n)(x),...,y''(x),y'(x),y(x)]
+ for i in 1..n repeat
+ l := concat(retract(f := differentiate(f, x))@K, l)
+ k:K -- #$^#& compiler requires this line and the next one too...
+ c:F
+ while not(empty? l) and zero?(c := getlincoeff(diffeq, k := first l))
+ repeat l := rest l
+ empty? l or empty? rest l => error "parseODE: equation has order 0"
+ diffeq := diffeq - c * (k::F)
+ ny := name y
+ l := rest l
+ height(k) > 3 => parseLODE(diffeq, l, monomial(c, #l), ny)
+ (u := getcoeff(diffeq, k := first l)) case "failed" => [diffeq, c]
+ eqrhs := (d := u::F) * (k::F) - diffeq
+ freeOf?(eqrhs, ny) and freeOf?(c, ny) and freeOf?(d, ny) =>
+ [monomial(c, 1) + d::UP, eqrhs]
+ [diffeq, c]
+
+-- returns [p, g] where the equation (diffeq) is of the form p(D)(y) = g
+ parseLODE(diffeq, l, p, y) ==
+ not freeOf?(leadingCoefficient p, y) =>
+ error "parseLODE: not a linear ordinary differential equation"
+ d := degree(p)::Integer - 1
+ for k in l repeat
+ p := p + monomial(c := getfreelincoeff(diffeq, k, y), d::N)
+ d := d - 1
+ diffeq := diffeq - c * (k::F)
+ freeOf?(diffeq, y) => [p, - diffeq]
+ error "parseLODE: not a linear ordinary differential equation"
+
+ getfreelincoeff(f, k, y) ==
+ freeOf?(c := getlincoeff(f, k), y) => c
+ error "getfreelincoeff: not a linear ordinary differential equation"
+
+ getfreelincoeff1(f, k, ly) ==
+ c := getlincoeff(f, k)
+ for y in ly repeat
+ not freeOf?(c, y) =>
+ error "getfreelincoeff: not a linear ordinary differential equation"
+ c
+
+ getlincoeff(f, k) ==
+ (u := getcoeff(f, k)) case "failed" =>
+ error "getlincoeff: not an appropriate ordinary differential equation"
+ u::F
+
+ getcoeff(f, k) ==
+ (r := retractIfCan(univariate(denom f, k))@Union(P, "failed"))
+ case "failed" or degree(p := univariate(numer f, k)) > 1 => "failed"
+ coefficient(p, 1) / (r::P)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad
+-- kovacic.spad lodof.spad odeef.spad
+
+<<package REDORDER ReductionOfOrder>>
+<<package LODEEF ElementaryFunctionLODESolver>>
+<<package ODEEF ElementaryFunctionODESolver>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/oderf.spad.pamphlet b/src/algebra/oderf.spad.pamphlet
new file mode 100644
index 00000000..6573a809
--- /dev/null
+++ b/src/algebra/oderf.spad.pamphlet
@@ -0,0 +1,900 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra oderf.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package BALFACT BalancedFactorisation}
+<<package BALFACT BalancedFactorisation>>=
+)abbrev package BALFACT BalancedFactorisation
+++ Author: Manuel Bronstein
+++ Date Created: 1 March 1991
+++ Date Last Updated: 11 October 1991
+++ Description: This package provides balanced factorisations of polynomials.
+BalancedFactorisation(R, UP): Exports == Implementation where
+ R : Join(GcdDomain, CharacteristicZero)
+ UP : UnivariatePolynomialCategory R
+
+ Exports ==> with
+ balancedFactorisation: (UP, UP) -> Factored UP
+ ++ balancedFactorisation(a, b) returns
+ ++ a factorisation \spad{a = p1^e1 ... pm^em} such that each
+ ++ \spad{pi} is balanced with respect to b.
+ balancedFactorisation: (UP, List UP) -> Factored UP
+ ++ balancedFactorisation(a, [b1,...,bn]) returns
+ ++ a factorisation \spad{a = p1^e1 ... pm^em} such that each
+ ++ pi is balanced with respect to \spad{[b1,...,bm]}.
+
+ Implementation ==> add
+ balSqfr : (UP, Integer, List UP) -> Factored UP
+ balSqfr1: (UP, Integer, UP) -> Factored UP
+
+ balancedFactorisation(a:UP, b:UP) == balancedFactorisation(a, [b])
+
+ balSqfr1(a, n, b) ==
+ g := gcd(a, b)
+ fa := sqfrFactor((a exquo g)::UP, n)
+ ground? g => fa
+ fa * balSqfr1(g, n, (b exquo (g ** order(b, g)))::UP)
+
+ balSqfr(a, n, l) ==
+ b := first l
+ empty? rest l => balSqfr1(a, n, b)
+ */[balSqfr1(f.factor, n, b) for f in factors balSqfr(a,n,rest l)]
+
+ balancedFactorisation(a:UP, l:List UP) ==
+ empty?(ll := select(#1 ^= 0, l)) =>
+ error "balancedFactorisation: 2nd argument is empty or all 0"
+ sa := squareFree a
+ unit(sa) * */[balSqfr(f.factor,f.exponent,ll) for f in factors sa])
+
+@
+\section{package BOUNDZRO BoundIntegerRoots}
+<<package BOUNDZRO BoundIntegerRoots>>=
+)abbrev package BOUNDZRO BoundIntegerRoots
+++ Author: Manuel Bronstein
+++ Date Created: 11 March 1991
+++ Date Last Updated: 18 November 1991
+++ Description:
+++ \spadtype{BoundIntegerRoots} provides functions to
+++ find lower bounds on the integer roots of a polynomial.
+BoundIntegerRoots(F, UP): Exports == Implementation where
+ F : Join(Field, RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+
+ Z ==> Integer
+ Q ==> Fraction Z
+ K ==> Kernel F
+ UPQ ==> SparseUnivariatePolynomial Q
+ ALGOP ==> "%alg"
+
+ Exports ==> with
+ integerBound: UP -> Z
+ ++ integerBound(p) returns a lower bound on the negative integer
+ ++ roots of p, and 0 if p has no negative integer roots.
+
+ Implementation ==> add
+ import RationalFactorize(UPQ)
+ import UnivariatePolynomialCategoryFunctions2(F, UP, Q, UPQ)
+
+ qbound : (UP, UPQ) -> Z
+ zroot1 : UP -> Z
+ qzroot1: UPQ -> Z
+ negint : Q -> Z
+
+-- returns 0 if p has no integer root < 0, its negative integer root otherwise
+ qzroot1 p == negint(- leadingCoefficient(reductum p) / leadingCoefficient p)
+
+-- returns 0 if p has no integer root < 0, its negative integer root otherwise
+ zroot1 p ==
+ z := - leadingCoefficient(reductum p) / leadingCoefficient p
+ (r := retractIfCan(z)@Union(Q, "failed")) case Q => negint(r::Q)
+ 0
+
+-- returns 0 if r is not a negative integer, r otherwise
+ negint r ==
+ ((u := retractIfCan(r)@Union(Z, "failed")) case Z) and (u::Z < 0) => u::Z
+ 0
+
+ if F has ExpressionSpace then
+ bringDown: F -> Q
+
+-- the random substitution used by bringDown is NOT always a ring-homorphism
+-- (because of potential algebraic kernels), but is ALWAYS a Z-linear map.
+-- this guarantees that bringing down the coefficients of (x + n) q(x) for an
+-- integer n yields a polynomial h(x) which is divisible by x + n
+-- the only problem is that evaluating with random numbers can cause a
+-- division by 0. We should really be able to trap this error later and
+-- reevaluate with a new set of random numbers MB 11/91
+ bringDown f ==
+ t := tower f
+ retract eval(f, t, [random()$Q :: F for k in t])
+
+ integerBound p ==
+-- one? degree p => zroot1 p
+ (degree p) = 1 => zroot1 p
+ q1 := map(bringDown, p)
+ q2 := map(bringDown, p)
+ qbound(p, gcd(q1, q2))
+
+ else
+ integerBound p ==
+-- one? degree p => zroot1 p
+ (degree p) = 1 => zroot1 p
+ qbound(p, map(retract(#1)@Q, p))
+
+-- we can probably do better here (i.e. without factoring)
+ qbound(p, q) ==
+ bound:Z := 0
+ for rec in factors factor q repeat
+-- if one?(degree(rec.factor)) and ((r := qzroot1(rec.factor)) < bound)
+ if ((degree(rec.factor)) = 1) and ((r := qzroot1(rec.factor)) < bound)
+ and zero? p(r::Q::F) then bound := r
+ bound
+
+@
+\section{package ODEPRIM PrimitiveRatDE}
+<<package ODEPRIM PrimitiveRatDE>>=
+)abbrev package ODEPRIM PrimitiveRatDE
+++ Author: Manuel Bronstein
+++ Date Created: 1 March 1991
+++ Date Last Updated: 1 February 1994
+++ Description:
+++ \spad{PrimitiveRatDE} provides functions for in-field solutions of linear
+++ ordinary differential equations, in the transcendental case.
+++ The derivation to use is given by the parameter \spad{L}.
+PrimitiveRatDE(F, UP, L, LQ): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+ L : LinearOrdinaryDifferentialOperatorCategory UP
+ LQ : LinearOrdinaryDifferentialOperatorCategory Fraction UP
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ UP2 ==> SparseUnivariatePolynomial UP
+ REC ==> Record(center:UP, equation:UP)
+
+ Exports ==> with
+ denomLODE: (L, RF) -> Union(UP, "failed")
+ ++ denomLODE(op, g) returns a polynomial d such that
+ ++ any rational solution of \spad{op y = g}
+ ++ is of the form \spad{p/d} for some polynomial p, and
+ ++ "failed", if the equation has no rational solution.
+ denomLODE: (L, List RF) -> UP
+ ++ denomLODE(op, [g1,...,gm]) returns a polynomial
+ ++ d such that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
+ ++ is of the form \spad{p/d} for some polynomial p.
+ indicialEquations: L -> List REC
+ ++ indicialEquations op returns \spad{[[d1,e1],...,[dq,eq]]} where
+ ++ the \spad{d_i}'s are the affine singularities of \spad{op},
+ ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+ indicialEquations: (L, UP) -> List REC
+ ++ indicialEquations(op, p) returns \spad{[[d1,e1],...,[dq,eq]]} where
+ ++ the \spad{d_i}'s are the affine singularities of \spad{op}
+ ++ above the roots of \spad{p},
+ ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+ indicialEquation: (L, F) -> UP
+ ++ indicialEquation(op, a) returns the indicial equation of \spad{op}
+ ++ at \spad{a}.
+ indicialEquations: LQ -> List REC
+ ++ indicialEquations op returns \spad{[[d1,e1],...,[dq,eq]]} where
+ ++ the \spad{d_i}'s are the affine singularities of \spad{op},
+ ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+ indicialEquations: (LQ, UP) -> List REC
+ ++ indicialEquations(op, p) returns \spad{[[d1,e1],...,[dq,eq]]} where
+ ++ the \spad{d_i}'s are the affine singularities of \spad{op}
+ ++ above the roots of \spad{p},
+ ++ and the \spad{e_i}'s are the indicial equations at each \spad{d_i}.
+ indicialEquation: (LQ, F) -> UP
+ ++ indicialEquation(op, a) returns the indicial equation of \spad{op}
+ ++ at \spad{a}.
+ splitDenominator: (LQ, List RF) -> Record(eq:L, rh:List RF)
+ ++ splitDenominator(op, [g1,...,gm]) returns \spad{op0, [h1,...,hm]}
+ ++ such that the equations \spad{op y = c1 g1 + ... + cm gm} and
+ ++ \spad{op0 y = c1 h1 + ... + cm hm} have the same solutions.
+
+ Implementation ==> add
+ import BoundIntegerRoots(F, UP)
+ import BalancedFactorisation(F, UP)
+ import InnerCommonDenominator(UP, RF, List UP, List RF)
+ import UnivariatePolynomialCategoryFunctions2(F, UP, UP, UP2)
+
+ tau : (UP, UP, UP, N) -> UP
+ NPbound : (UP, L, UP) -> N
+ hdenom : (L, UP, UP) -> UP
+ denom0 : (Z, L, UP, UP, UP) -> UP
+ indicialEq : (UP, List N, List UP) -> UP
+ separateZeros: (UP, UP) -> UP
+ UPfact : N -> UP
+ UP2UP2 : UP -> UP2
+ indeq : (UP, L) -> UP
+ NPmulambda : (UP, L) -> Record(mu:Z, lambda:List N, func:List UP)
+
+ diff := D()$L
+
+ UP2UP2 p == map(#1::UP, p)
+ indicialEquations(op:L) == indicialEquations(op, leadingCoefficient op)
+ indicialEquation(op:L, a:F) == indeq(monomial(1, 1) - a::UP, op)
+
+ splitDenominator(op, lg) ==
+ cd := splitDenominator coefficients op
+ f := cd.den / gcd(cd.num)
+ l:L := 0
+ while op ^= 0 repeat
+ l := l + monomial(retract(f * leadingCoefficient op), degree op)
+ op := reductum op
+ [l, [f * g for g in lg]]
+
+ tau(p, pp, q, n) ==
+ ((pp ** n) * ((q exquo (p ** order(q, p)))::UP)) rem p
+
+ indicialEquations(op:LQ) ==
+ indicialEquations(splitDenominator(op, empty()).eq)
+
+ indicialEquations(op:LQ, p:UP) ==
+ indicialEquations(splitDenominator(op, empty()).eq, p)
+
+ indicialEquation(op:LQ, a:F) ==
+ indeq(monomial(1, 1) - a::UP, splitDenominator(op, empty()).eq)
+
+-- returns z(z-1)...(z-(n-1))
+ UPfact n ==
+ zero? n => 1
+ z := monomial(1, 1)$UP
+ */[z - i::F::UP for i in 0..(n-1)::N]
+
+ indicialEq(c, lamb, lf) ==
+ cp := diff c
+ cc := UP2UP2 c
+ s:UP2 := 0
+ for i in lamb for f in lf repeat
+ s := s + (UPfact i) * UP2UP2 tau(c, cp, f, i)
+ primitivePart resultant(cc, s)
+
+ NPmulambda(c, l) ==
+ lamb:List(N) := [d := degree l]
+ lf:List(UP) := [a := leadingCoefficient l]
+ mup := d::Z - order(a, c)
+ while (l := reductum l) ^= 0 repeat
+ a := leadingCoefficient l
+ if (m := (d := degree l)::Z - order(a, c)) > mup then
+ mup := m
+ lamb := [d]
+ lf := [a]
+ else if (m = mup) then
+ lamb := concat(d, lamb)
+ lf := concat(a, lf)
+ [mup, lamb, lf]
+
+-- e = 0 means homogeneous equation
+ NPbound(c, l, e) ==
+ rec := NPmulambda(c, l)
+ n := max(0, - integerBound indicialEq(c, rec.lambda, rec.func))
+ zero? e => n::N
+ max(n, order(e, c)::Z - rec.mu)::N
+
+ hdenom(l, d, e) ==
+ */[dd.factor ** NPbound(dd.factor, l, e)
+ for dd in factors balancedFactorisation(d, coefficients l)]
+
+ denom0(n, l, d, e, h) ==
+ hdenom(l, d, e) * */[hh.factor ** max(0, order(e, hh.factor) - n)::N
+ for hh in factors balancedFactorisation(h, e)]
+
+-- returns a polynomials whose zeros are the zeros of e which are not
+-- zeros of d
+ separateZeros(d, e) ==
+ ((g := squareFreePart e) exquo gcd(g, squareFreePart d))::UP
+
+ indeq(c, l) ==
+ rec := NPmulambda(c, l)
+ indicialEq(c, rec.lambda, rec.func)
+
+ indicialEquations(op:L, p:UP) ==
+ [[dd.factor, indeq(dd.factor, op)]
+ for dd in factors balancedFactorisation(p, coefficients op)]
+
+-- cannot return "failed" in the homogeneous case
+ denomLODE(l:L, g:RF) ==
+ d := leadingCoefficient l
+ zero? g => hdenom(l, d, 0)
+ h := separateZeros(d, e := denom g)
+ n := degree l
+ (e exquo (h**(n + 1))) case "failed" => "failed"
+ denom0(n, l, d, e, h)
+
+ denomLODE(l:L, lg:List RF) ==
+ empty? lg => denomLODE(l, 0)::UP
+ d := leadingCoefficient l
+ h := separateZeros(d, e := "lcm"/[denom g for g in lg])
+ denom0(degree l, l, d, e, h)
+
+@
+\section{package UTSODETL UTSodetools}
+<<package UTSODETL UTSodetools>>=
+)abbrev package UTSODETL UTSodetools
+++ Author: Manuel Bronstein
+++ Date Created: 31 January 1994
+++ Date Last Updated: 3 February 1994
+++ Description:
+++ \spad{RUTSodetools} provides tools to interface with the series
+++ ODE solver when presented with linear ODEs.
+UTSodetools(F, UP, L, UTS): Exports == Implementation where
+ F : Ring
+ UP : UnivariatePolynomialCategory F
+ L : LinearOrdinaryDifferentialOperatorCategory UP
+ UTS: UnivariateTaylorSeriesCategory F
+
+ Exports ==> with
+ UP2UTS: UP -> UTS
+ ++ UP2UTS(p) converts \spad{p} to a Taylor series.
+ UTS2UP: (UTS, NonNegativeInteger) -> UP
+ ++ UTS2UP(s, n) converts the first \spad{n} terms of \spad{s}
+ ++ to a univariate polynomial.
+ LODO2FUN: L -> (List UTS -> UTS)
+ ++ LODO2FUN(op) returns the function to pass to the series ODE
+ ++ solver in order to solve \spad{op y = 0}.
+ if F has IntegralDomain then
+ RF2UTS: Fraction UP -> UTS
+ ++ RF2UTS(f) converts \spad{f} to a Taylor series.
+
+ Implementation ==> add
+ fun: (Vector UTS, List UTS) -> UTS
+
+ UP2UTS p ==
+ q := p(monomial(1, 1) + center(0)::UP)
+ +/[monomial(coefficient(q, i), i)$UTS for i in 0..degree q]
+
+ UTS2UP(s, n) ==
+ xmc := monomial(1, 1)$UP - center(0)::UP
+ xmcn:UP := 1
+ ans:UP := 0
+ for i in 0..n repeat
+ ans := ans + coefficient(s, i) * xmcn
+ xmcn := xmc * xmcn
+ ans
+
+ LODO2FUN op ==
+ a := recip(UP2UTS(- leadingCoefficient op))::UTS
+ n := (degree(op) - 1)::NonNegativeInteger
+ v := [a * UP2UTS coefficient(op, i) for i in 0..n]$Vector(UTS)
+ fun(v, #1)
+
+ fun(v, l) ==
+ ans:UTS := 0
+ for b in l for i in 1.. repeat ans := ans + v.i * b
+ ans
+
+ if F has IntegralDomain then
+ RF2UTS f == UP2UTS(numer f) * recip(UP2UTS denom f)::UTS
+
+@
+\section{package ODERAT RationalLODE}
+<<package ODERAT RationalLODE>>=
+)abbrev package ODERAT RationalLODE
+++ Author: Manuel Bronstein
+++ Date Created: 13 March 1991
+++ Date Last Updated: 13 April 1994
+++ Description:
+++ \spad{RationalLODE} provides functions for in-field solutions of linear
+++ ordinary differential equations, in the rational case.
+RationalLODE(F, UP): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Integer,
+ RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ U ==> Union(RF, "failed")
+ V ==> Vector F
+ M ==> Matrix F
+ LODO ==> LinearOrdinaryDifferentialOperator1 RF
+ LODO2==> LinearOrdinaryDifferentialOperator2(UP, RF)
+
+ Exports ==> with
+ ratDsolve: (LODO, RF) -> Record(particular: U, basis: List RF)
+ ++ ratDsolve(op, g) returns \spad{["failed", []]} if the equation
+ ++ \spad{op y = g} has no rational solution. Otherwise, it returns
+ ++ \spad{[f, [y1,...,ym]]} where f is a particular rational solution
+ ++ and the yi's form a basis for the rational solutions of the
+ ++ homogeneous equation.
+ ratDsolve: (LODO, List RF) -> Record(basis:List RF, mat:Matrix F)
+ ++ ratDsolve(op, [g1,...,gm]) returns \spad{[[h1,...,hq], M]} such
+ ++ that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
+ ++ is of the form \spad{d1 h1 + ... + dq hq} where
+ ++ \spad{M [d1,...,dq,c1,...,cm] = 0}.
+ ratDsolve: (LODO2, RF) -> Record(particular: U, basis: List RF)
+ ++ ratDsolve(op, g) returns \spad{["failed", []]} if the equation
+ ++ \spad{op y = g} has no rational solution. Otherwise, it returns
+ ++ \spad{[f, [y1,...,ym]]} where f is a particular rational solution
+ ++ and the yi's form a basis for the rational solutions of the
+ ++ homogeneous equation.
+ ratDsolve: (LODO2, List RF) -> Record(basis:List RF, mat:Matrix F)
+ ++ ratDsolve(op, [g1,...,gm]) returns \spad{[[h1,...,hq], M]} such
+ ++ that any rational solution of \spad{op y = c1 g1 + ... + cm gm}
+ ++ is of the form \spad{d1 h1 + ... + dq hq} where
+ ++ \spad{M [d1,...,dq,c1,...,cm] = 0}.
+ indicialEquationAtInfinity: LODO -> UP
+ ++ indicialEquationAtInfinity op returns the indicial equation of
+ ++ \spad{op} at infinity.
+ indicialEquationAtInfinity: LODO2 -> UP
+ ++ indicialEquationAtInfinity op returns the indicial equation of
+ ++ \spad{op} at infinity.
+
+ Implementation ==> add
+ import BoundIntegerRoots(F, UP)
+ import RationalIntegration(F, UP)
+ import PrimitiveRatDE(F, UP, LODO2, LODO)
+ import LinearSystemMatrixPackage(F, V, V, M)
+ import InnerCommonDenominator(UP, RF, List UP, List RF)
+
+ nzero? : V -> Boolean
+ evenodd : N -> F
+ UPfact : N -> UP
+ infOrder : RF -> Z
+ infTau : (UP, N) -> F
+ infBound : (LODO2, List RF) -> N
+ regularPoint : (LODO2, List RF) -> Z
+ infIndicialEquation: (List N, List UP) -> UP
+ makeDot : (Vector F, List RF) -> RF
+ unitlist : (N, N) -> List F
+ infMuLambda: LODO2 -> Record(mu:Z, lambda:List N, func:List UP)
+ ratDsolve0: (LODO2, RF) -> Record(particular: U, basis: List RF)
+ ratDsolve1: (LODO2, List RF) -> Record(basis:List RF, mat:Matrix F)
+ candidates: (LODO2,List RF,UP) -> Record(basis:List RF,particular:List RF)
+
+ dummy := new()$Symbol
+
+ infOrder f == (degree denom f) - (degree numer f)
+ evenodd n == (even? n => 1; -1)
+
+ ratDsolve1(op, lg) ==
+ d := denomLODE(op, lg)
+ rec := candidates(op, lg, d)
+ l := concat([op q for q in rec.basis],
+ [op(rec.particular.i) - lg.i for i in 1..#(rec.particular)])
+ sys1 := reducedSystem(matrix [l])@Matrix(UP)
+ [rec.basis, reducedSystem sys1]
+
+ ratDsolve0(op, g) ==
+ zero? degree op => [inv(leadingCoefficient(op)::RF) * g, empty()]
+ minimumDegree op > 0 =>
+ sol := ratDsolve0(monicRightDivide(op, monomial(1, 1)).quotient, g)
+ b:List(RF) := [1]
+ for f in sol.basis repeat
+ if (uu := infieldint f) case RF then b := concat(uu::RF, b)
+ sol.particular case "failed" => ["failed", b]
+ [infieldint(sol.particular::RF), b]
+ (u := denomLODE(op, g)) case "failed" => ["failed", empty()]
+ rec := candidates(op, [g], u::UP)
+ l := lb := lsol := empty()$List(RF)
+ for q in rec.basis repeat
+ if zero?(opq := op q) then lsol := concat(q, lsol)
+ else (l := concat(opq, l); lb := concat(q, lb))
+ h:RF := (zero? g => 0; first(rec.particular))
+ empty? l =>
+ zero? g => [0, lsol]
+ [(g = op h => h; "failed"), lsol]
+ m:M
+ v:V
+ if zero? g then
+ m := reducedSystem(reducedSystem(matrix [l])@Matrix(UP))@M
+ v := new(ncols m, 0)$V
+ else
+ sys1 := reducedSystem(matrix [l], vector [g - op h]
+ )@Record(mat: Matrix UP, vec: Vector UP)
+ sys2 := reducedSystem(sys1.mat, sys1.vec)@Record(mat:M, vec:V)
+ m := sys2.mat
+ v := sys2.vec
+ sol := solve(m, v)
+ part:U :=
+ zero? g => 0
+ sol.particular case "failed" => "failed"
+ makeDot(sol.particular::V, lb) + first(rec.particular)
+ [part,
+ concat_!(lsol, [makeDot(v, lb) for v in sol.basis | nzero? v])]
+
+ indicialEquationAtInfinity(op:LODO2) ==
+ rec := infMuLambda op
+ infIndicialEquation(rec.lambda, rec.func)
+
+ indicialEquationAtInfinity(op:LODO) ==
+ rec := splitDenominator(op, empty())
+ indicialEquationAtInfinity(rec.eq)
+
+ regularPoint(l, lg) ==
+ a := leadingCoefficient(l) * commonDenominator lg
+ coefficient(a, 0) ^= 0 => 0
+ for i in 1.. repeat
+ a(j := i::F) ^= 0 => return i
+ a(-j) ^= 0 => return(-i)
+
+ unitlist(i, q) ==
+ v := new(q, 0)$Vector(F)
+ v.i := 1
+ parts v
+
+ candidates(op, lg, d) ==
+ n := degree d + infBound(op, lg)
+ m := regularPoint(op, lg)
+ uts := UnivariateTaylorSeries(F, dummy, m::F)
+ tools := UTSodetools(F, UP, LODO2, uts)
+ solver := UnivariateTaylorSeriesODESolver(F, uts)
+ dd := UP2UTS(d)$tools
+ f := LODO2FUN(op)$tools
+ q := degree op
+ e := unitlist(1, q)
+ hom := [UTS2UP(dd * ode(f, unitlist(i, q))$solver, n)$tools /$RF d
+ for i in 1..q]$List(RF)
+ a1 := inv(leadingCoefficient(op)::RF)
+ part := [UTS2UP(dd * ode(RF2UTS(a1 * g)$tools + f #1, e)$solver, n)$tools
+ /$RF d for g in lg | g ^= 0]$List(RF)
+ [hom, part]
+
+ nzero? v ==
+ for i in minIndex v .. maxIndex v repeat
+ not zero? qelt(v, i) => return true
+ false
+
+-- returns z(z+1)...(z+(n-1))
+ UPfact n ==
+ zero? n => 1
+ z := monomial(1, 1)$UP
+ */[z + i::F::UP for i in 0..(n-1)::N]
+
+ infMuLambda l ==
+ lamb:List(N) := [d := degree l]
+ lf:List(UP) := [a := leadingCoefficient l]
+ mup := degree(a)::Z - d
+ while (l := reductum l) ^= 0 repeat
+ a := leadingCoefficient l
+ if (m := degree(a)::Z - (d := degree l)) > mup then
+ mup := m
+ lamb := [d]
+ lf := [a]
+ else if (m = mup) then
+ lamb := concat(d, lamb)
+ lf := concat(a, lf)
+ [mup, lamb, lf]
+
+ infIndicialEquation(lambda, lf) ==
+ ans:UP := 0
+ for i in lambda for f in lf repeat
+ ans := ans + evenodd i * leadingCoefficient f * UPfact i
+ ans
+
+ infBound(l, lg) ==
+ rec := infMuLambda l
+ n := min(- degree(l)::Z - 1,
+ integerBound infIndicialEquation(rec.lambda, rec.func))
+ while not(empty? lg) and zero? first lg repeat lg := rest lg
+ empty? lg => (-n)::N
+ m := infOrder first lg
+ for g in rest lg repeat
+ if not(zero? g) and (mm := infOrder g) < m then m := mm
+ (-min(n, rec.mu - degree(leadingCoefficient l)::Z + m))::N
+
+ makeDot(v, bas) ==
+ ans:RF := 0
+ for i in 1.. for b in bas repeat ans := ans + v.i::UP * b
+ ans
+
+ ratDsolve(op:LODO, g:RF) ==
+ rec := splitDenominator(op, [g])
+ ratDsolve0(rec.eq, first(rec.rh))
+
+ ratDsolve(op:LODO, lg:List RF) ==
+ rec := splitDenominator(op, lg)
+ ratDsolve1(rec.eq, rec.rh)
+
+ ratDsolve(op:LODO2, g:RF) ==
+ unit?(c := content op) => ratDsolve0(op, g)
+ ratDsolve0((op exquo c)::LODO2, inv(c::RF) * g)
+
+ ratDsolve(op:LODO2, lg:List RF) ==
+ unit?(c := content op) => ratDsolve1(op, lg)
+ ratDsolve1((op exquo c)::LODO2, [inv(c::RF) * g for g in lg])
+
+@
+\section{package ODETOOLS ODETools}
+<<package ODETOOLS ODETools>>=
+)abbrev package ODETOOLS ODETools
+++ Author: Manuel Bronstein
+++ Date Created: 20 March 1991
+++ Date Last Updated: 2 February 1994
+++ Description:
+++ \spad{ODETools} provides tools for the linear ODE solver.
+ODETools(F, LODO): Exports == Implementation where
+ N ==> NonNegativeInteger
+ L ==> List F
+ V ==> Vector F
+ M ==> Matrix F
+
+ F: Field
+ LODO: LinearOrdinaryDifferentialOperatorCategory F
+
+ Exports ==> with
+ wronskianMatrix: L -> M
+ ++ wronskianMatrix([f1,...,fn]) returns the \spad{n x n} matrix m
+ ++ whose i^th row is \spad{[f1^(i-1),...,fn^(i-1)]}.
+ wronskianMatrix: (L, N) -> M
+ ++ wronskianMatrix([f1,...,fn], q, D) returns the \spad{q x n} matrix m
+ ++ whose i^th row is \spad{[f1^(i-1),...,fn^(i-1)]}.
+ variationOfParameters: (LODO, F, L) -> Union(V, "failed")
+ ++ variationOfParameters(op, g, [f1,...,fm])
+ ++ returns \spad{[u1,...,um]} such that a particular solution of the
+ ++ equation \spad{op y = g} is \spad{f1 int(u1) + ... + fm int(um)}
+ ++ where \spad{[f1,...,fm]} are linearly independent and \spad{op(fi)=0}.
+ ++ The value "failed" is returned if \spad{m < n} and no particular
+ ++ solution is found.
+ particularSolution: (LODO, F, L, F -> F) -> Union(F, "failed")
+ ++ particularSolution(op, g, [f1,...,fm], I) returns a particular
+ ++ solution h of the equation \spad{op y = g} where \spad{[f1,...,fm]}
+ ++ are linearly independent and \spad{op(fi)=0}.
+ ++ The value "failed" is returned if no particular solution is found.
+ ++ Note: the method of variations of parameters is used.
+
+ Implementation ==> add
+ import LinearSystemMatrixPackage(F, V, V, M)
+
+ diff := D()$LODO
+
+ wronskianMatrix l == wronskianMatrix(l, #l)
+
+ wronskianMatrix(l, q) ==
+ v:V := vector l
+ m:M := zero(q, #v)
+ for i in minRowIndex m .. maxRowIndex m repeat
+ setRow_!(m, i, v)
+ v := map_!(diff #1, v)
+ m
+
+ variationOfParameters(op, g, b) ==
+ empty? b => "failed"
+ v:V := new(n := degree op, 0)
+ qsetelt_!(v, maxIndex v, g / leadingCoefficient op)
+ particularSolution(wronskianMatrix(b, n), v)
+
+ particularSolution(op, g, b, integration) ==
+ zero? g => 0
+ (sol := variationOfParameters(op, g, b)) case "failed" => "failed"
+ ans:F := 0
+ for f in b for i in minIndex(s := sol::V) .. repeat
+ ans := ans + integration(qelt(s, i)) * f
+ ans
+
+@
+\section{package ODEINT ODEIntegration}
+<<package ODEINT ODEIntegration>>=
+)abbrev package ODEINT ODEIntegration
+++ Author: Manuel Bronstein
+++ Date Created: 4 November 1991
+++ Date Last Updated: 2 February 1994
+++ Description:
+++ \spadtype{ODEIntegration} provides an interface to the integrator.
+++ This package is intended for use
+++ by the differential equations solver but not at top-level.
+ODEIntegration(R, F): Exports == Implementation where
+ R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, CharacteristicZero)
+ F: Join(AlgebraicallyClosedFunctionSpace R, TranscendentalFunctionCategory,
+ PrimitiveFunctionCategory)
+
+ Q ==> Fraction Integer
+ UQ ==> Union(Q, "failed")
+ SY ==> Symbol
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ REC ==> Record(coef:Q, logand:F)
+
+ Exports ==> with
+ int : (F, SY) -> F
+ ++ int(f, x) returns the integral of f with respect to x.
+ expint: (F, SY) -> F
+ ++ expint(f, x) returns e^{the integral of f with respect to x}.
+ diff : SY -> (F -> F)
+ ++ diff(x) returns the derivation with respect to x.
+
+ Implementation ==> add
+ import FunctionSpaceIntegration(R, F)
+ import ElementaryFunctionStructurePackage(R, F)
+
+ isQ : List F -> UQ
+ isQlog: F -> Union(REC, "failed")
+ mkprod: List REC -> F
+
+ diff x == differentiate(#1, x)
+
+-- This is the integration function to be used for quadratures
+ int(f, x) ==
+ (u := integrate(f, x)) case F => u::F
+ first(u::List(F))
+
+-- mkprod([q1, f1],...,[qn,fn]) returns */(fi^qi) but groups the
+-- qi having the same denominator together
+ mkprod l ==
+ empty? l => 1
+ rec := first l
+ d := denom(rec.coef)
+ ll := select(denom(#1.coef) = d, l)
+ nthRoot(*/[r.logand ** numer(r.coef) for r in ll], d) *
+ mkprod setDifference(l, ll)
+
+-- computes exp(int(f,x)) in a non-naive way
+ expint(f, x) ==
+ a := int(f, x)
+ (u := validExponential(tower a, a, x)) case F => u::F
+ da := denom a
+ l :=
+ (v := isPlus(na := numer a)) case List(P) => v::List(P)
+ [na]
+ exponent:P := 0
+ lrec:List(REC) := empty()
+ for term in l repeat
+ if (w := isQlog(term / da)) case REC then
+ lrec := concat(w::REC, lrec)
+ else
+ exponent := exponent + term
+ mkprod(lrec) * exp(exponent / da)
+
+-- checks if all the elements of l are rational numbers, returns their product
+ isQ l ==
+ prod:Q := 1
+ for x in l repeat
+ (u := retractIfCan(x)@UQ) case "failed" => return "failed"
+ prod := prod * u::Q
+ prod
+
+-- checks if a non-sum expr is of the form c * log(g) for a rational number c
+ isQlog f ==
+ is?(f, "log"::SY) => [1, first argument(retract(f)@K)]
+ (v := isTimes f) case List(F) and (#(l := v::List(F)) <= 3) =>
+ l := reverse_! sort_! l
+ is?(first l, "log"::SY) and ((u := isQ rest l) case Q) =>
+ [u::Q, first argument(retract(first(l))@K)]
+ "failed"
+ "failed"
+
+@
+\section{package ODECONST ConstantLODE}
+<<package ODECONST ConstantLODE>>=
+)abbrev package ODECONST ConstantLODE
+++ Author: Manuel Bronstein
+++ Date Created: 18 March 1991
+++ Date Last Updated: 3 February 1994
+++ Description: Solution of linear ordinary differential equations, constant coefficient case.
+ConstantLODE(R, F, L): Exports == Implementation where
+ R: Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, CharacteristicZero)
+ F: Join(AlgebraicallyClosedFunctionSpace R,
+ TranscendentalFunctionCategory, PrimitiveFunctionCategory)
+ L: LinearOrdinaryDifferentialOperatorCategory F
+
+ Z ==> Integer
+ SY ==> Symbol
+ K ==> Kernel F
+ V ==> Vector F
+ M ==> Matrix F
+ SUP ==> SparseUnivariatePolynomial F
+
+ Exports ==> with
+ constDsolve: (L, F, SY) -> Record(particular:F, basis:List F)
+ ++ constDsolve(op, g, x) returns \spad{[f, [y1,...,ym]]}
+ ++ where f is a particular solution of the equation \spad{op y = g},
+ ++ and the \spad{yi}'s form a basis for the solutions of \spad{op y = 0}.
+
+ Implementation ==> add
+ import ODETools(F, L)
+ import ODEIntegration(R, F)
+ import ElementaryFunctionSign(R, F)
+ import AlgebraicManipulations(R, F)
+ import FunctionSpaceIntegration(R, F)
+ import FunctionSpaceUnivariatePolynomialFactor(R, F, SUP)
+
+ homoBasis: (L, F) -> List F
+ quadSol : (SUP, F) -> List F
+ basisSqfr: (SUP, F) -> List F
+ basisSol : (SUP, Z, F) -> List F
+
+ constDsolve(op, g, x) ==
+ b := homoBasis(op, x::F)
+ [particularSolution(op, g, b, int(#1, x))::F, b]
+
+ homoBasis(op, x) ==
+ p:SUP := 0
+ while op ^= 0 repeat
+ p := p + monomial(leadingCoefficient op, degree op)
+ op := reductum op
+ b:List(F) := empty()
+ for ff in factors ffactor p repeat
+ b := concat_!(b, basisSol(ff.factor, dec(ff.exponent), x))
+ b
+
+ basisSol(p, n, x) ==
+ l := basisSqfr(p, x)
+ zero? n => l
+ ll := copy l
+ xn := x::F
+ for i in 1..n repeat
+ l := concat_!(l, [xn * f for f in ll])
+ xn := x * xn
+ l
+
+ basisSqfr(p, x) ==
+-- one?(d := degree p) =>
+ ((d := degree p) = 1) =>
+ [exp(- coefficient(p, 0) * x / leadingCoefficient p)]
+ d = 2 => quadSol(p, x)
+ [exp(a * x) for a in rootsOf p]
+
+ quadSol(p, x) ==
+ (u := sign(delta := (b := coefficient(p, 1))**2 - 4 *
+ (a := leadingCoefficient p) * (c := coefficient(p, 0))))
+ case Z and negative?(u::Z) =>
+ y := x / (2 * a)
+ r := - b * y
+ i := rootSimp(sqrt(-delta)) * y
+ [exp(r) * cos(i), exp(r) * sin(i)]
+ [exp(a * x) for a in zerosOf p]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad odeef.spad
+
+<<package BALFACT BalancedFactorisation>>
+<<package BOUNDZRO BoundIntegerRoots>>
+<<package ODEPRIM PrimitiveRatDE>>
+<<package UTSODETL UTSodetools>>
+<<package ODERAT RationalLODE>>
+<<package ODETOOLS ODETools>>
+<<package ODEINT ODEIntegration>>
+<<package ODECONST ConstantLODE>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/omcat.spad.pamphlet b/src/algebra/omcat.spad.pamphlet
new file mode 100644
index 00000000..824bf1b2
--- /dev/null
+++ b/src/algebra/omcat.spad.pamphlet
@@ -0,0 +1,85 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra omcat.spad}
+\author{Mike Dewar, Vilya Harvey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category OM OpenMath}
+<<category OM OpenMath>>=
+)abbrev category OM OpenMath
+++ Author: Mike Dewar & Vilya Harvey
+++ Basic Functions: OMwrite
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{OpenMath} provides operations for exporting an object
+++ in OpenMath format.
+
+OpenMath(): Category == with
+ OMwrite : % -> String
+ ++ OMwrite(u) returns the OpenMath XML encoding of \axiom{u} as a
+ ++ complete OpenMath object.
+ OMwrite : (%, Boolean) -> String
+ ++ OMwrite(u, true) returns the OpenMath XML encoding of \axiom{u}
+ ++ as a complete OpenMath object; OMwrite(u, false) returns the
+ ++ OpenMath XML encoding of \axiom{u} as an OpenMath fragment.
+ OMwrite : (OpenMathDevice, %) -> Void
+ ++ OMwrite(dev, u) writes the OpenMath form of \axiom{u} to the
+ ++ OpenMath device \axiom{dev} as a complete OpenMath object.
+ OMwrite : (OpenMathDevice, %, Boolean) -> Void
+ ++ OMwrite(dev, u, true) writes the OpenMath form of \axiom{u} to
+ ++ the OpenMath device \axiom{dev} as a complete OpenMath object;
+ ++ OMwrite(dev, u, false) writes the object as an OpenMath fragment.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category OM OpenMath>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/omdev.spad.pamphlet b/src/algebra/omdev.spad.pamphlet
new file mode 100644
index 00000000..070de7bb
--- /dev/null
+++ b/src/algebra/omdev.spad.pamphlet
@@ -0,0 +1,385 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra omdev.spad}
+\author{Vilya Harvey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain OMENC OpenMathEncoding}
+<<domain OMENC OpenMathEncoding>>=
+)abbrev domain OMENC OpenMathEncoding
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{OpenMathEncoding} is the set of valid OpenMath encodings.
+OpenMathEncoding(): SetCategory with
+ OMencodingUnknown : () -> %
+ ++ OMencodingUnknown() is the constant for unknown encoding types. If this
+ ++ is used on an input device, the encoding will be autodetected.
+ ++ It is invalid to use it on an output device.
+ OMencodingXML : () -> %
+ ++ OMencodingXML() is the constant for the OpenMath XML encoding.
+ OMencodingSGML : () -> %
+ ++ OMencodingSGML() is the constant for the deprecated OpenMath SGML encoding.
+ OMencodingBinary : () -> %
+ ++ OMencodingBinary() is the constant for the OpenMath binary encoding.
+ == add
+ Rep := SingleInteger
+
+ =(u,v) == (u=v)$Rep
+
+ import Rep
+
+ coerce(u) ==
+ u::Rep = 0$Rep => "Unknown"::OutputForm
+ u::Rep = 1$Rep => "Binary"::OutputForm
+ u::Rep = 2::Rep => "XML"::OutputForm
+ u::Rep = 3::Rep => "SGML"::OutputForm
+ error "Bogus OpenMath Encoding Type"
+
+ OMencodingUnknown(): % == 0::Rep
+ OMencodingBinary(): % == 1::Rep
+ OMencodingXML(): % == 2::Rep
+ OMencodingSGML(): % == 3::Rep
+
+@
+\section{domain OMDEV OpenMathDevice}
+<<domain OMDEV OpenMathDevice>>=
+)abbrev domain OMDEV OpenMathDevice
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathDevice} provides support for reading
+++ and writing openMath objects to files, strings etc. It also provides
+++ access to low-level operations from within the interpreter.
+
+
+OpenMathDevice(): with
+ OMopenFile : (String, String, OpenMathEncoding) -> %
+ ++ OMopenFile(f,mode,enc) opens file \axiom{f} for reading or writing
+ ++ OpenMath objects (depending on \axiom{mode} which can be "r", "w"
+ ++ or "a" for read, write and append respectively), in the encoding
+ ++ \axiom{enc}.
+ OMopenString : (String, OpenMathEncoding) -> %
+ ++ OMopenString(s,mode) opens the string \axiom{s} for reading or writing
+ ++ OpenMath objects in encoding \axiom{enc}.
+ OMclose : % -> Void
+ ++ OMclose(dev) closes \axiom{dev}, flushing output if necessary.
+ OMsetEncoding : (%, OpenMathEncoding) -> Void
+ ++ OMsetEncoding(dev,enc) sets the encoding used for reading or writing
+ ++ OpenMath objects to or from \axiom{dev} to \axiom{enc}.
+ OMputApp : % -> Void
+ ++ OMputApp(dev) writes a begin application token to \axiom{dev}.
+ OMputAtp : % -> Void
+ ++ OMputAtp(dev) writes a begin attribute pair token to \axiom{dev}.
+ OMputAttr : % -> Void
+ ++ OMputAttr(dev) writes a begin attribute token to \axiom{dev}.
+ OMputBind : % -> Void
+ ++ OMputBind(dev) writes a begin binder token to \axiom{dev}.
+ OMputBVar : % -> Void
+ ++ OMputBVar(dev) writes a begin bound variable list token to \axiom{dev}.
+ OMputError : % -> Void
+ ++ OMputError(dev) writes a begin error token to \axiom{dev}.
+ OMputObject : % -> Void
+ ++ OMputObject(dev) writes a begin object token to \axiom{dev}.
+ OMputEndApp : % -> Void
+ ++ OMputEndApp(dev) writes an end application token to \axiom{dev}.
+ OMputEndAtp : % -> Void
+ ++ OMputEndAtp(dev) writes an end attribute pair token to \axiom{dev}.
+ OMputEndAttr : % -> Void
+ ++ OMputEndAttr(dev) writes an end attribute token to \axiom{dev}.
+ OMputEndBind : % -> Void
+ ++ OMputEndBind(dev) writes an end binder token to \axiom{dev}.
+ OMputEndBVar : % -> Void
+ ++ OMputEndBVar(dev) writes an end bound variable list token to \axiom{dev}.
+ OMputEndError : % -> Void
+ ++ OMputEndError(dev) writes an end error token to \axiom{dev}.
+ OMputEndObject: % -> Void
+ ++ OMputEndObject(dev) writes an end object token to \axiom{dev}.
+ OMputInteger : (%, Integer) -> Void
+ ++ OMputInteger(dev,i) writes the integer \axiom{i} to \axiom{dev}.
+ OMputFloat : (%, DoubleFloat) -> Void
+ ++ OMputFloat(dev,i) writes the float \axiom{i} to \axiom{dev}.
+ OMputVariable : (%, Symbol) -> Void
+ ++ OMputVariable(dev,i) writes the variable \axiom{i} to \axiom{dev}.
+ OMputString : (%, String) -> Void
+ ++ OMputString(dev,i) writes the string \axiom{i} to \axiom{dev}.
+ OMputSymbol : (%, String, String) -> Void
+ ++ OMputSymbol(dev,cd,s) writes the symbol \axiom{s} from CD \axiom{cd}
+ ++ to \axiom{dev}.
+
+ OMgetApp : % -> Void
+ ++ OMgetApp(dev) reads a begin application token from \axiom{dev}.
+ OMgetAtp : % -> Void
+ ++ OMgetAtp(dev) reads a begin attribute pair token from \axiom{dev}.
+ OMgetAttr : % -> Void
+ ++ OMgetAttr(dev) reads a begin attribute token from \axiom{dev}.
+ OMgetBind : % -> Void
+ ++ OMgetBind(dev) reads a begin binder token from \axiom{dev}.
+ OMgetBVar : % -> Void
+ ++ OMgetBVar(dev) reads a begin bound variable list token from \axiom{dev}.
+ OMgetError : % -> Void
+ ++ OMgetError(dev) reads a begin error token from \axiom{dev}.
+ OMgetObject : % -> Void
+ ++ OMgetObject(dev) reads a begin object token from \axiom{dev}.
+ OMgetEndApp : % -> Void
+ ++ OMgetEndApp(dev) reads an end application token from \axiom{dev}.
+ OMgetEndAtp : % -> Void
+ ++ OMgetEndAtp(dev) reads an end attribute pair token from \axiom{dev}.
+ OMgetEndAttr : % -> Void
+ ++ OMgetEndAttr(dev) reads an end attribute token from \axiom{dev}.
+ OMgetEndBind : % -> Void
+ ++ OMgetEndBind(dev) reads an end binder token from \axiom{dev}.
+ OMgetEndBVar : % -> Void
+ ++ OMgetEndBVar(dev) reads an end bound variable list token from \axiom{dev}.
+ OMgetEndError : % -> Void
+ ++ OMgetEndError(dev) reads an end error token from \axiom{dev}.
+ OMgetEndObject: % -> Void
+ ++ OMgetEndObject(dev) reads an end object token from \axiom{dev}.
+ OMgetInteger : % -> Integer
+ ++ OMgetInteger(dev) reads an integer from \axiom{dev}.
+ OMgetFloat : % -> DoubleFloat
+ ++ OMgetFloat(dev) reads a float from \axiom{dev}.
+ OMgetVariable : % -> Symbol
+ ++ OMgetVariable(dev) reads a variable from \axiom{dev}.
+ OMgetString : % -> String
+ ++ OMgetString(dev) reads a string from \axiom{dev}.
+ OMgetSymbol : % -> Record(cd:String, name:String)
+ ++ OMgetSymbol(dev) reads a symbol from \axiom{dev}.
+
+ OMgetType : % -> Symbol
+ ++ OMgetType(dev) returns the type of the next object on \axiom{dev}.
+ == add
+ OMopenFile(fname: String, fmode: String, enc: OpenMathEncoding): % ==
+ OM_-OPENFILEDEV(fname, fmode, enc)$Lisp
+ OMopenString(str: String, enc: OpenMathEncoding): % ==
+ OM_-OPENSTRINGDEV(str, enc)$Lisp
+ OMclose(dev: %): Void ==
+ OM_-CLOSEDEV(dev)$Lisp
+ OMsetEncoding(dev: %, enc: OpenMathEncoding): Void ==
+ OM_-SETDEVENCODING(dev, enc)$Lisp
+
+ OMputApp(dev: %): Void == OM_-PUTAPP(dev)$Lisp
+ OMputAtp(dev: %): Void == OM_-PUTATP(dev)$Lisp
+ OMputAttr(dev: %): Void == OM_-PUTATTR(dev)$Lisp
+ OMputBind(dev: %): Void == OM_-PUTBIND(dev)$Lisp
+ OMputBVar(dev: %): Void == OM_-PUTBVAR(dev)$Lisp
+ OMputError(dev: %): Void == OM_-PUTERROR(dev)$Lisp
+ OMputObject(dev: %): Void == OM_-PUTOBJECT(dev)$Lisp
+ OMputEndApp(dev: %): Void == OM_-PUTENDAPP(dev)$Lisp
+ OMputEndAtp(dev: %): Void == OM_-PUTENDATP(dev)$Lisp
+ OMputEndAttr(dev: %): Void == OM_-PUTENDATTR(dev)$Lisp
+ OMputEndBind(dev: %): Void == OM_-PUTENDBIND(dev)$Lisp
+ OMputEndBVar(dev: %): Void == OM_-PUTENDBVAR(dev)$Lisp
+ OMputEndError(dev: %): Void == OM_-PUTENDERROR(dev)$Lisp
+ OMputEndObject(dev: %): Void == OM_-PUTENDOBJECT(dev)$Lisp
+ OMputInteger(dev: %, i: Integer): Void == OM_-PUTINT(dev, i)$Lisp
+ OMputFloat(dev: %, f: DoubleFloat): Void == OM_-PUTFLOAT(dev, f)$Lisp
+ --OMputByteArray(dev: %, b: Array Byte): Void == OM_-PUTBYTEARRAY(dev, b)$Lisp
+ OMputVariable(dev: %, v: Symbol): Void == OM_-PUTVAR(dev, v)$Lisp
+ OMputString(dev: %, s: String): Void == OM_-PUTSTRING(dev, s)$Lisp
+ OMputSymbol(dev: %, cd: String, nm: String): Void == OM_-PUTSYMBOL(dev, cd, nm)$Lisp
+
+ OMgetApp(dev: %): Void == OM_-GETAPP(dev)$Lisp
+ OMgetAtp(dev: %): Void == OM_-GETATP(dev)$Lisp
+ OMgetAttr(dev: %): Void == OM_-GETATTR(dev)$Lisp
+ OMgetBind(dev: %): Void == OM_-GETBIND(dev)$Lisp
+ OMgetBVar(dev: %): Void == OM_-GETBVAR(dev)$Lisp
+ OMgetError(dev: %): Void == OM_-GETERROR(dev)$Lisp
+ OMgetObject(dev: %): Void == OM_-GETOBJECT(dev)$Lisp
+ OMgetEndApp(dev: %): Void == OM_-GETENDAPP(dev)$Lisp
+ OMgetEndAtp(dev: %): Void == OM_-GETENDATP(dev)$Lisp
+ OMgetEndAttr(dev: %): Void == OM_-GETENDATTR(dev)$Lisp
+ OMgetEndBind(dev: %): Void == OM_-GETENDBIND(dev)$Lisp
+ OMgetEndBVar(dev: %): Void == OM_-GETENDBVAR(dev)$Lisp
+ OMgetEndError(dev: %): Void == OM_-GETENDERROR(dev)$Lisp
+ OMgetEndObject(dev: %): Void == OM_-GETENDOBJECT(dev)$Lisp
+ OMgetInteger(dev: %): Integer == OM_-GETINT(dev)$Lisp
+ OMgetFloat(dev: %): DoubleFloat == OM_-GETFLOAT(dev)$Lisp
+ --OMgetByteArray(dev: %): Array Byte == OM_-GETBYTEARRAY(dev)$Lisp
+ OMgetVariable(dev: %): Symbol == OM_-GETVAR(dev)$Lisp
+ OMgetString(dev: %): String == OM_-GETSTRING(dev)$Lisp
+ OMgetSymbol(dev: %): Record(cd:String, name:String) == OM_-GETSYMBOL(dev)$Lisp
+
+ OMgetType(dev: %): Symbol == OM_-GETTYPE(dev)$Lisp
+
+@
+\section{domain OMCONN OpenMathConnection}
+<<domain OMCONN OpenMathConnection>>=
+)abbrev domain OMCONN OpenMathConnection
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathConnection} provides low-level functions
+++ for handling connections to and from \spadtype{OpenMathDevice}s.
+
+
+OpenMathConnection(): with
+ OMmakeConn : SingleInteger -> % ++ \spad{OMmakeConn}
+ OMcloseConn : % -> Void ++ \spad{OMcloseConn}
+ OMconnInDevice: %-> OpenMathDevice ++ \spad{OMconnInDevice:}
+ OMconnOutDevice: %-> OpenMathDevice ++ \spad{OMconnOutDevice:}
+ OMconnectTCP : (%, String, SingleInteger) -> Boolean ++ \spad{OMconnectTCP}
+ OMbindTCP : (%, SingleInteger) -> Boolean ++ \spad{OMbindTCP}
+ == add
+ OMmakeConn(timeout: SingleInteger): % == OM_-MAKECONN(timeout)$Lisp
+ OMcloseConn(conn: %): Void == OM_-CLOSECONN(conn)$Lisp
+
+ OMconnInDevice(conn: %): OpenMathDevice ==
+ OM_-GETCONNINDEV(conn)$Lisp
+ OMconnOutDevice(conn: %): OpenMathDevice ==
+ OM_-GETCONNOUTDEV(conn)$Lisp
+
+ OMconnectTCP(conn: %, host: String, port: SingleInteger): Boolean ==
+ OM_-CONNECTTCP(conn, host, port)$Lisp
+ OMbindTCP(conn: %, port: SingleInteger): Boolean ==
+ OM_-BINDTCP(conn, port)$Lisp
+
+@
+\section{package OMPKG OpenMathPackage}
+<<package OMPKG OpenMathPackage>>=
+)abbrev package OMPKG OpenMathPackage
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathPackage} provides some simple utilities
+++ to make reading OpenMath objects easier.
+
+OpenMathPackage(): with
+ OMread : OpenMathDevice -> Any
+ ++ OMread(dev) reads an OpenMath object from \axiom{dev} and passes it
+ ++ to AXIOM.
+ OMreadFile : String -> Any
+ ++ OMreadFile(f) reads an OpenMath object from \axiom{f} and passes it
+ ++ to AXIOM.
+ OMreadStr : String -> Any
+ ++ OMreadStr(f) reads an OpenMath object from \axiom{f} and passes it
+ ++ to AXIOM.
+ OMlistCDs : () -> List(String)
+ ++ OMlistCDs() lists all the CDs supported by AXIOM.
+ OMlistSymbols : String -> List(String)
+ ++ OMlistSymbols(cd) lists all the symbols in \axiom{cd}.
+ OMsupportsCD? : String -> Boolean
+ ++ OMsupportsCD?(cd) returns true if AXIOM supports \axiom{cd}, false
+ ++ otherwise.
+ OMsupportsSymbol? : (String, String) -> Boolean
+ ++ OMsupportsSymbol?(s,cd) returns true if AXIOM supports symbol \axiom{s}
+ ++ from CD \axiom{cd}, false otherwise.
+ OMunhandledSymbol : (String, String) -> Exit
+ ++ OMunhandledSymbol(s,cd) raises an error if AXIOM reads a symbol which it
+ ++ is unable to handle. Note that this is different from an unexpected
+ ++ symbol.
+ == add
+ import OpenMathEncoding
+ import OpenMathDevice
+ import String
+
+ OMunhandledSymbol(u,v) ==
+ error concat ["AXIOM is unable to process the symbol ",u," from CD ",v,"."]
+
+ OMread(dev: OpenMathDevice): Any ==
+ interpret(OM_-READ(dev)$Lisp :: InputForm)
+
+ OMreadFile(filename: String): Any ==
+ dev := OMopenFile(filename, "r", OMencodingUnknown())
+ res: Any := interpret(OM_-READ(dev)$Lisp :: InputForm)
+ OMclose(dev)
+ res
+
+ OMreadStr(str: String): Any ==
+ strp := OM_-STRINGTOSTRINGPTR(str)$Lisp
+ dev := OMopenString(strp pretend String, OMencodingUnknown())
+ res: Any := interpret(OM_-READ(dev)$Lisp :: InputForm)
+ OMclose(dev)
+ res
+
+ OMlistCDs(): List(String) ==
+ OM_-LISTCDS()$Lisp pretend List(String)
+
+ OMlistSymbols(cd: String): List(String) ==
+ OM_-LISTSYMBOLS(cd)$Lisp pretend List(String)
+
+ import SExpression
+
+ OMsupportsCD?(cd: String): Boolean ==
+ not null? OM_-SUPPORTSCD(cd)$Lisp
+
+ OMsupportsSymbol?(cd: String, name: String): Boolean ==
+ not null? OM_-SUPPORTSSYMBOL(cd, name)$Lisp
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain OMENC OpenMathEncoding>>
+<<domain OMDEV OpenMathDevice>>
+<<domain OMCONN OpenMathConnection>>
+<<package OMPKG OpenMathPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/omerror.spad.pamphlet b/src/algebra/omerror.spad.pamphlet
new file mode 100644
index 00000000..410b31d6
--- /dev/null
+++ b/src/algebra/omerror.spad.pamphlet
@@ -0,0 +1,151 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra omerror.spad}
+\author{Vilya Harvey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain OMERRK OpenMathErrorKind}
+<<domain OMERRK OpenMathErrorKind>>=
+)abbrev domain OMERRK OpenMathErrorKind
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathErrorKind} represents different kinds
+++ of OpenMath errors: specifically parse errors, unknown CD or symbol
+++ errors, and read errors.
+OpenMathErrorKind() : SetCategory with
+ coerce : Symbol -> %
+ ++ coerce(u) creates an OpenMath error object of an appropriate type if
+ ++ \axiom{u} is one of \axiom{OMParseError}, \axiom{OMReadError},
+ ++ \axiom{OMUnknownCD} or \axiom{OMUnknownSymbol}, otherwise it
+ ++ raises a runtime error.
+ OMParseError? : % -> Boolean
+ ++ OMParseError?(u) tests whether u is an OpenMath parsing error.
+ OMUnknownCD? : % -> Boolean
+ ++ OMUnknownCD?(u) tests whether u is an OpenMath unknown CD error.
+ OMUnknownSymbol? : % -> Boolean
+ ++ OMUnknownSymbol?(u) tests whether u is an OpenMath unknown symbol error.
+ OMReadError? : % -> Boolean
+ ++ OMReadError?(u) tests whether u is an OpenMath read error.
+ == add
+ Rep := Union(parseError:"OMParseError", unknownCD:"OMUnknownCD",
+ unknownSymbol:"OMUnknownSymbol",readError:"OMReadError")
+
+ OMParseError?(u) == (u case parseError)$Rep
+ OMUnknownCD?(u) == (u case unknownCD)$Rep
+ OMUnknownSymbol?(u) == (u case unknownSymbol)$Rep
+ OMReadError?(u) == (u case readError)$Rep
+
+ coerce(s:Symbol):% ==
+ s = OMParseError => ["OMParseError"]$Rep
+ s = OMUnknownCD => ["OMUnknownCD"]$Rep
+ s = OMUnknownSymbol => ["OMUnknownSymbol"]$Rep
+ s = OMReadError => ["OMReadError"]$Rep
+ error concat(string s, " is not a valid OpenMathErrorKind.")
+
+ a = b == (a=b)$Rep
+
+ coerce(e:%):OutputForm == coerce(e)$Rep
+
+@
+\section{domain OMERR OpenMathError}
+<<domain OMERR OpenMathError>>=
+)abbrev domain OMERR OpenMathError
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathError} is the domain of OpenMath errors.
+OpenMathError() : SetCategory with
+ errorKind : % -> OpenMathErrorKind
+ ++ errorKind(u) returns the type of error which u represents.
+ errorInfo : % -> List Symbol
+ ++ errorInfo(u) returns information about the error u.
+ omError : (OpenMathErrorKind, List Symbol) -> %
+ ++ omError(k,l) creates an instance of OpenMathError.
+ == add
+ Rep := Record(err:OpenMathErrorKind, info:List Symbol)
+
+ import List String
+
+ coerce(e:%):OutputForm ==
+ OMParseError? e.err => message "Error parsing OpenMath object"
+ infoSize := #(e.info)
+ OMUnknownCD? e.err =>
+-- not one? infoSize => error "Malformed info list in OMUnknownCD"
+ not (infoSize = 1) => error "Malformed info list in OMUnknownCD"
+ message concat("Cannot handle CD ",string first e.info)
+ OMUnknownSymbol? e.err =>
+ not 2=infoSize => error "Malformed info list in OMUnknownSymbol"
+ message concat ["Cannot handle Symbol ",
+ string e.info.2, " from CD ", string e.info.1]
+ OMReadError? e.err =>
+ message "OpenMath read error"
+ error "Malformed OpenMath Error"
+
+ omError(e:OpenMathErrorKind,i:List Symbol):% == [e,i]$Rep
+
+ errorKind(e:%):OpenMathErrorKind == e.err
+ errorInfo(e:%):List Symbol == e.info
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain OMERRK OpenMathErrorKind>>
+<<domain OMERR OpenMathError>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/omserver.spad.pamphlet b/src/algebra/omserver.spad.pamphlet
new file mode 100644
index 00000000..a6872f1f
--- /dev/null
+++ b/src/algebra/omserver.spad.pamphlet
@@ -0,0 +1,120 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra omserver.spad}
+\author{Vilya Harvey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package OMSERVER OpenMathServerPackage}
+<<package OMSERVER OpenMathServerPackage>>=
+)abbrev package OMSERVER OpenMathServerPackage
+++ Author: Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{OpenMathServerPackage} provides the necessary
+++ operations to run AXIOM as an OpenMath server, reading/writing objects
+++ to/from a port. Please note the facilities available here are very basic.
+++ The idea is that a user calls e.g. \axiom{Omserve(4000,60)} and then
+++ another process sends OpenMath objects to port 4000 and reads the result.
+
+OpenMathServerPackage(): with
+ OMreceive : OpenMathConnection -> Any
+ ++ OMreceive(c) reads an OpenMath object from connection \axiom{c} and
+ ++ returns the appropriate AXIOM object.
+ OMsend : (OpenMathConnection, Any) -> Void
+ ++ OMsend(c,u) attempts to output \axiom{u} on \aciom{c} in OpenMath.
+ OMserve : (SingleInteger, SingleInteger) -> Void
+ ++ OMserve(portnum,timeout) puts AXIOM into server mode on port number
+ ++ \axiom{portnum}. The parameter \axiom{timeout} specifies the timeout
+ ++ period for the connection.
+ == add
+ import OpenMathDevice
+ import OpenMathConnection
+ import OpenMathPackage
+ import OpenMath
+
+
+
+ OMreceive(conn: OpenMathConnection): Any ==
+ dev: OpenMathDevice := OMconnInDevice(conn)
+ OMsetEncoding(dev, OMencodingUnknown);
+ OMread(dev)
+
+ OMsend(conn: OpenMathConnection, value: Any): Void ==
+ dev: OpenMathDevice := OMconnOutDevice(conn)
+ OMsetEncoding(dev, OMencodingXML);
+ --retractable?(value)$AnyFunctions1(Expression Integer) =>
+ -- OMwrite(dev, retract(value)$AnyFunctions1(Expression Integer), true)
+ retractable?(value)$AnyFunctions1(Integer) =>
+ OMwrite(dev, retract(value)$AnyFunctions1(Integer), true)
+ retractable?(value)$AnyFunctions1(Float) =>
+ OMwrite(dev, retract(value)$AnyFunctions1(Float), true)
+ retractable?(value)$AnyFunctions1(SingleInteger) =>
+ OMwrite(dev, retract(value)$AnyFunctions1(SingleInteger), true)
+ retractable?(value)$AnyFunctions1(DoubleFloat) =>
+ OMwrite(dev, retract(value)$AnyFunctions1(DoubleFloat), true)
+ retractable?(value)$AnyFunctions1(String) =>
+ OMwrite(dev, retract(value)$AnyFunctions1(String), true)
+
+ OMserve(portNum: SingleInteger, timeout: SingleInteger): Void ==
+ conn: OpenMathConnection := OMmakeConn(timeout)
+ OMbindTCP(conn, portNum)
+ val: Any
+ while true repeat
+ val := OMreceive(conn)
+ OMsend(conn, val)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package OMSERVER OpenMathServerPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/op.spad.pamphlet b/src/algebra/op.spad.pamphlet
new file mode 100644
index 00000000..19d4218e
--- /dev/null
+++ b/src/algebra/op.spad.pamphlet
@@ -0,0 +1,541 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra op.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain BOP BasicOperator}
+<<domain BOP BasicOperator>>=
+)abbrev domain BOP BasicOperator
+++ Basic system operators
+++ Author: Manuel Bronstein
+++ Date Created: 22 March 1988
+++ Date Last Updated: 11 October 1993
+++ Description:
+++ A basic operator is an object that can be applied to a list of
+++ arguments from a set, the result being a kernel over that set.
+++ Keywords: operator, kernel.
+BasicOperator(): Exports == Implementation where
+ O ==> OutputForm
+ P ==> AssociationList(String, None)
+ L ==> List Record(key:String, entry:None)
+ SEX ==> InputForm
+-- some internal properties
+ LESS? ==> "%less?"
+ EQUAL? ==> "%equal?"
+ WEIGHT ==> "%weight"
+ DISPLAY ==> "%display"
+ SEXPR ==> "%input"
+
+ Exports ==> OrderedSet with
+ name : $ -> Symbol
+ ++ name(op) returns the name of op.
+ properties: $ -> P
+ ++ properties(op) returns the list of all the properties
+ ++ currently attached to op.
+ copy : $ -> $
+ ++ copy(op) returns a copy of op.
+ operator : Symbol -> $
+ ++ operator(f) makes f into an operator with arbitrary arity.
+ operator : (Symbol, NonNegativeInteger) -> $
+ ++ operator(f, n) makes f into an n-ary operator.
+ arity : $ -> Union(NonNegativeInteger, "failed")
+ ++ arity(op) returns n if op is n-ary, and
+ ++ "failed" if op has arbitrary arity.
+ nullary? : $ -> Boolean
+ ++ nullary?(op) tests if op is nullary.
+ unary? : $ -> Boolean
+ ++ unary?(op) tests if op is unary.
+ nary? : $ -> Boolean
+ ++ nary?(op) tests if op has arbitrary arity.
+ weight : $ -> NonNegativeInteger
+ ++ weight(op) returns the weight attached to op.
+ weight : ($, NonNegativeInteger) -> $
+ ++ weight(op, n) attaches the weight n to op.
+ equality : ($, ($, $) -> Boolean) -> $
+ ++ equality(op, foo?) attaches foo? as the "%equal?" property
+ ++ to op. If op1 and op2 have the same name, and one of them
+ ++ has an "%equal?" property f, then \spad{f(op1, op2)} is called to
+ ++ decide whether op1 and op2 should be considered equal.
+ comparison : ($, ($, $) -> Boolean) -> $
+ ++ comparison(op, foo?) attaches foo? as the "%less?" property
+ ++ to op. If op1 and op2 have the same name, and one of them
+ ++ has a "%less?" property f, then \spad{f(op1, op2)} is called to
+ ++ decide whether \spad{op1 < op2}.
+ display : $ -> Union(List O -> O, "failed")
+ ++ display(op) returns the "%display" property of op if
+ ++ it has one attached, and "failed" otherwise.
+ display : ($, List O -> O) -> $
+ ++ display(op, foo) attaches foo as the "%display" property
+ ++ of op. If op has a "%display" property f, then \spad{op(a1,...,an)}
+ ++ gets converted to OutputForm as \spad{f(a1,...,an)}.
+ display : ($, O -> O) -> $
+ ++ display(op, foo) attaches foo as the "%display" property
+ ++ of op. If op has a "%display" property f, then \spad{op(a)}
+ ++ gets converted to OutputForm as \spad{f(a)}.
+ ++ Argument op must be unary.
+ input : ($, List SEX -> SEX) -> $
+ ++ input(op, foo) attaches foo as the "%input" property
+ ++ of op. If op has a "%input" property f, then \spad{op(a1,...,an)}
+ ++ gets converted to InputForm as \spad{f(a1,...,an)}.
+ input : $ -> Union(List SEX -> SEX, "failed")
+ ++ input(op) returns the "%input" property of op if
+ ++ it has one attached, "failed" otherwise.
+ is? : ($, Symbol) -> Boolean
+ ++ is?(op, s) tests if the name of op is s.
+ has? : ($, String) -> Boolean
+ ++ has?(op, s) tests if property s is attached to op.
+ assert : ($, String) -> $
+ ++ assert(op, s) attaches property s to op.
+ ++ Argument op is modified "in place", i.e. no copy is made.
+ deleteProperty_!: ($, String) -> $
+ ++ deleteProperty!(op, s) unattaches property s from op.
+ ++ Argument op is modified "in place", i.e. no copy is made.
+ property : ($, String) -> Union(None, "failed")
+ ++ property(op, s) returns the value of property s if
+ ++ it is attached to op, and "failed" otherwise.
+ setProperty : ($, String, None) -> $
+ ++ setProperty(op, s, v) attaches property s to op,
+ ++ and sets its value to v.
+ ++ Argument op is modified "in place", i.e. no copy is made.
+ setProperties : ($, P) -> $
+ ++ setProperties(op, l) sets the property list of op to l.
+ ++ Argument op is modified "in place", i.e. no copy is made.
+
+ Implementation ==> add
+ -- if narg < 0 then the operator ahs variable arity.
+ Rep := Record(opname:Symbol, narg:SingleInteger, props:P)
+
+ oper: (Symbol, SingleInteger, P) -> $
+
+ is?(op, s) == name(op) = s
+ name op == op.opname
+ properties op == op.props
+ setProperties(op, l) == (op.props := l; op)
+ operator s == oper(s, -1::SingleInteger, table())
+ operator(s, n) == oper(s, n::Integer::SingleInteger, table())
+ property(op, name) == search(name, op.props)
+ assert(op, s) == setProperty(op, s, NIL$Lisp)
+ has?(op, name) == key?(name, op.props)
+ oper(se, n, prop) == [se, n, prop]
+ weight(op, n) == setProperty(op, WEIGHT, n pretend None)
+ nullary? op == zero?(op.narg)
+-- unary? op == one?(op.narg)
+ unary? op == ((op.narg) = 1)
+ nary? op == negative?(op.narg)
+ equality(op, func) == setProperty(op, EQUAL?, func pretend None)
+ comparison(op, func) == setProperty(op, LESS?, func pretend None)
+ display(op:$, f:O -> O) == display(op, f first #1)
+ deleteProperty_!(op, name) == (remove_!(name, properties op); op)
+ setProperty(op, name, valu) == (op.props.name := valu; op)
+ coerce(op:$):OutputForm == name(op)::OutputForm
+ input(op:$, f:List SEX -> SEX) == setProperty(op, SEXPR, f pretend None)
+ display(op:$, f:List O -> O) == setProperty(op, DISPLAY, f pretend None)
+
+ display op ==
+ (u := property(op, DISPLAY)) case "failed" => "failed"
+ (u::None) pretend (List O -> O)
+
+ input op ==
+ (u := property(op, SEXPR)) case "failed" => "failed"
+ (u::None) pretend (List SEX -> SEX)
+
+ arity op ==
+ negative?(n := op.narg) => "failed"
+ convert(n)@Integer :: NonNegativeInteger
+
+ copy op ==
+ oper(name op, op.narg,
+ table([[r.key, r.entry] for r in entries(properties op)@L]$L))
+
+-- property EQUAL? contains a function f: (BOP, BOP) -> Boolean
+-- such that f(o1, o2) is true iff o1 = o2
+ op1 = op2 ==
+ name(op1) ^= name(op2) => false
+ op1.narg ^= op2.narg => false
+ brace(keys properties op1)^=$Set(String) brace(keys properties op2) => false
+ (func := property(op1, EQUAL?)) case None =>
+ ((func::None) pretend (($, $) -> Boolean)) (op1, op2)
+ true
+
+-- property WEIGHT allows one to change the ordering around
+-- by default, every operator has weigth 1
+ weight op ==
+ (w := property(op, WEIGHT)) case "failed" => 1
+ (w::None) pretend NonNegativeInteger
+
+-- property LESS? contains a function f: (BOP, BOP) -> Boolean
+-- such that f(o1, o2) is true iff o1 < o2
+ op1 < op2 ==
+ (w1 := weight op1) ^= (w2 := weight op2) => w1 < w2
+ op1.narg ^= op2.narg => op1.narg < op2.narg
+ name(op1) ^= name(op2) => name(op1) < name(op2)
+ n1 := #(k1 := brace(keys(properties op1))$Set(String))
+ n2 := #(k2 := brace(keys(properties op2))$Set(String))
+ n1 ^= n2 => n1 < n2
+ not zero?(n1 := #(d1 := difference(k1, k2))) =>
+ n1 ^= (n2 := #(d2 := difference(k2, k1))) => n1 < n2
+ inspect(d1) < inspect(d2)
+ (func := property(op1, LESS?)) case None =>
+ ((func::None) pretend (($, $) -> Boolean)) (op1, op2)
+ (func := property(op1, EQUAL?)) case None =>
+ not(((func::None) pretend (($, $) -> Boolean)) (op1, op2))
+ false
+
+@
+\section{package BOP1 BasicOperatorFunctions1}
+<<package BOP1 BasicOperatorFunctions1>>=
+)abbrev package BOP1 BasicOperatorFunctions1
+++ Tools to set/get common properties of operators
+++ Author: Manuel Bronstein
+++ Date Created: 28 Mar 1988
+++ Date Last Updated: 15 May 1990
+++ Description:
+++ This package exports functions to set some commonly used properties
+++ of operators, including properties which contain functions.
+++ Keywords: operator.
+BasicOperatorFunctions1(A:SetCategory): Exports == Implementation where
+ OP ==> BasicOperator
+ EVAL ==> "%eval"
+ CONST ==> "%constant"
+ DIFF ==> "%diff"
+
+ Exports ==> with
+ evaluate : (OP, List A) -> Union(A, "failed")
+ ++ evaluate(op, [a1,...,an]) checks if op has an "%eval"
+ ++ property f. If it has, then \spad{f(a1,...,an)} is returned, and
+ ++ "failed" otherwise.
+ evaluate : (OP, List A -> A) -> OP
+ ++ evaluate(op, foo) attaches foo as the "%eval" property
+ ++ of op. If op has an "%eval" property f, then applying op
+ ++ to \spad{(a1,...,an)} returns the result of \spad{f(a1,...,an)}.
+ evaluate : (OP, A -> A) -> OP
+ ++ evaluate(op, foo) attaches foo as the "%eval" property
+ ++ of op. If op has an "%eval" property f, then applying op
+ ++ to a returns the result of \spad{f(a)}. Argument op must be unary.
+ evaluate : OP -> Union(List A -> A, "failed")
+ ++ evaluate(op) returns the value of the "%eval" property of
+ ++ op if it has one, and "failed" otherwise.
+ derivative : (OP, List (List A -> A)) -> OP
+ ++ derivative(op, [foo1,...,foon]) attaches [foo1,...,foon] as
+ ++ the "%diff" property of op. If op has an "%diff" property
+ ++ \spad{[f1,...,fn]} then applying a derivation D to \spad{op(a1,...,an)}
+ ++ returns \spad{f1(a1,...,an) * D(a1) + ... + fn(a1,...,an) * D(an)}.
+ derivative : (OP, A -> A) -> OP
+ ++ derivative(op, foo) attaches foo as the "%diff" property
+ ++ of op. If op has an "%diff" property f, then applying a
+ ++ derivation D to op(a) returns \spad{f(a) * D(a)}. Argument op must be unary.
+ derivative : OP -> Union(List(List A -> A), "failed")
+ ++ derivative(op) returns the value of the "%diff" property of
+ ++ op if it has one, and "failed" otherwise.
+ if A has OrderedSet then
+ constantOperator: A -> OP
+ ++ constantOperator(a) returns a nullary operator op
+ ++ such that \spad{op()} always evaluate to \spad{a}.
+ constantOpIfCan : OP -> Union(A, "failed")
+ ++ constantOpIfCan(op) returns \spad{a} if op is the constant
+ ++ nullary operator always returning \spad{a}, "failed" otherwise.
+
+ Implementation ==> add
+ evaluate(op:OP, func:A -> A) == evaluate(op, func first #1)
+
+ evaluate op ==
+ (func := property(op, EVAL)) case "failed" => "failed"
+ (func::None) pretend (List A -> A)
+
+ evaluate(op:OP, args:List A) ==
+ (func := property(op, EVAL)) case "failed" => "failed"
+ ((func::None) pretend (List A -> A)) args
+
+ evaluate(op:OP, func:List A -> A) ==
+ setProperty(op, EVAL, func pretend None)
+
+ derivative op ==
+ (func := property(op, DIFF)) case "failed" => "failed"
+ ((func::None) pretend List(List A -> A))
+
+ derivative(op:OP, grad:List(List A -> A)) ==
+ setProperty(op, DIFF, grad pretend None)
+
+ derivative(op:OP, f:A -> A) ==
+ unary? op or nary? op =>
+ derivative(op, [f first #1]$List(List A -> A))
+ error "Operator is not unary"
+
+ if A has OrderedSet then
+ cdisp : (OutputForm, List OutputForm) -> OutputForm
+ csex : (InputForm, List InputForm) -> InputForm
+ eqconst?: (OP, OP) -> Boolean
+ ltconst?: (OP, OP) -> Boolean
+ constOp : A -> OP
+
+ opconst:OP :=
+ comparison(equality(operator("constant"::Symbol, 0), eqconst?),
+ ltconst?)
+
+ cdisp(a, l) == a
+ csex(a, l) == a
+
+ eqconst?(a, b) ==
+ (va := property(a, CONST)) case "failed" => not has?(b, CONST)
+ ((vb := property(b, CONST)) case None) and
+ ((va::None) pretend A) = ((vb::None) pretend A)
+
+ ltconst?(a, b) ==
+ (va := property(a, CONST)) case "failed" => has?(b, CONST)
+ ((vb := property(b, CONST)) case None) and
+ ((va::None) pretend A) < ((vb::None) pretend A)
+
+ constOp a ==
+ setProperty(display(copy opconst, cdisp(a::OutputForm, #1)),
+ CONST, a pretend None)
+
+ constantOpIfCan op ==
+ is?(op, "constant"::Symbol) and
+ ((u := property(op, CONST)) case None) => (u::None) pretend A
+ "failed"
+
+ if A has ConvertibleTo InputForm then
+ constantOperator a == input(constOp a, csex(convert a, #1))
+ else
+ constantOperator a == constOp a
+
+@
+\section{package COMMONOP CommonOperators}
+<<package COMMONOP CommonOperators>>=
+)abbrev package COMMONOP CommonOperators
+++ Provides commonly used operators
+++ Author: Manuel Bronstein
+++ Date Created: 25 Mar 1988
+++ Date Last Updated: 2 December 1994
+++ Description:
+++ This package exports the elementary operators, with some semantics
+++ already attached to them. The semantics that is attached here is not
+++ dependent on the set in which the operators will be applied.
+++ Keywords: operator.
+CommonOperators(): Exports == Implementation where
+ OP ==> BasicOperator
+ O ==> OutputForm
+ POWER ==> "%power"::Symbol
+ ALGOP ==> "%alg"
+ EVEN ==> "even"
+ ODD ==> "odd"
+ DUMMYVAR ==> "%dummyVar"
+
+ Exports ==> with
+ operator: Symbol -> OP
+ ++ operator(s) returns an operator with name s, with the
+ ++ appropriate semantics if s is known. If s is not known,
+ ++ the result has no semantics.
+
+ Implementation ==> add
+ dpi : List O -> O
+ dgamma : List O -> O
+ dquote : List O -> O
+ dexp : O -> O
+ dfact : O -> O
+ startUp : Boolean -> Void
+ setDummyVar: (OP, NonNegativeInteger) -> OP
+
+ brandNew?:Reference(Boolean) := ref true
+
+ opalg := operator("rootOf"::Symbol, 2)$OP
+ oproot := operator("nthRoot"::Symbol, 2)
+ oppi := operator("pi"::Symbol, 0)
+ oplog := operator("log"::Symbol, 1)
+ opexp := operator("exp"::Symbol, 1)
+ opabs := operator("abs"::Symbol, 1)
+ opsin := operator("sin"::Symbol, 1)
+ opcos := operator("cos"::Symbol, 1)
+ optan := operator("tan"::Symbol, 1)
+ opcot := operator("cot"::Symbol, 1)
+ opsec := operator("sec"::Symbol, 1)
+ opcsc := operator("csc"::Symbol, 1)
+ opasin := operator("asin"::Symbol, 1)
+ opacos := operator("acos"::Symbol, 1)
+ opatan := operator("atan"::Symbol, 1)
+ opacot := operator("acot"::Symbol, 1)
+ opasec := operator("asec"::Symbol, 1)
+ opacsc := operator("acsc"::Symbol, 1)
+ opsinh := operator("sinh"::Symbol, 1)
+ opcosh := operator("cosh"::Symbol, 1)
+ optanh := operator("tanh"::Symbol, 1)
+ opcoth := operator("coth"::Symbol, 1)
+ opsech := operator("sech"::Symbol, 1)
+ opcsch := operator("csch"::Symbol, 1)
+ opasinh := operator("asinh"::Symbol, 1)
+ opacosh := operator("acosh"::Symbol, 1)
+ opatanh := operator("atanh"::Symbol, 1)
+ opacoth := operator("acoth"::Symbol, 1)
+ opasech := operator("asech"::Symbol, 1)
+ opacsch := operator("acsch"::Symbol, 1)
+ opbox := operator("%box"::Symbol)$OP
+ oppren := operator("%paren"::Symbol)$OP
+ opquote := operator("applyQuote"::Symbol)$OP
+ opdiff := operator("%diff"::Symbol, 3)
+ opsi := operator("Si"::Symbol, 1)
+ opci := operator("Ci"::Symbol, 1)
+ opei := operator("Ei"::Symbol, 1)
+ opli := operator("li"::Symbol, 1)
+ operf := operator("erf"::Symbol, 1)
+ opli2 := operator("dilog"::Symbol, 1)
+ opGamma := operator("Gamma"::Symbol, 1)
+ opGamma2 := operator("Gamma2"::Symbol, 2)
+ opBeta := operator("Beta"::Symbol, 2)
+ opdigamma := operator("digamma"::Symbol, 1)
+ oppolygamma := operator("polygamma"::Symbol, 2)
+ opBesselJ := operator("besselJ"::Symbol, 2)
+ opBesselY := operator("besselY"::Symbol, 2)
+ opBesselI := operator("besselI"::Symbol, 2)
+ opBesselK := operator("besselK"::Symbol, 2)
+ opAiryAi := operator("airyAi"::Symbol, 1)
+ opAiryBi := operator("airyBi"::Symbol , 1)
+ opint := operator("integral"::Symbol, 3)
+ opdint := operator("%defint"::Symbol, 5)
+ opfact := operator("factorial"::Symbol, 1)
+ opperm := operator("permutation"::Symbol, 2)
+ opbinom := operator("binomial"::Symbol, 2)
+ oppow := operator(POWER, 2)
+ opsum := operator("summation"::Symbol, 3)
+ opdsum := operator("%defsum"::Symbol, 5)
+ opprod := operator("product"::Symbol, 3)
+ opdprod := operator("%defprod"::Symbol, 5)
+
+ algop := [oproot, opalg]$List(OP)
+ rtrigop := [opsin, opcos, optan, opcot, opsec, opcsc,
+ opasin, opacos, opatan, opacot, opasec, opacsc]
+ htrigop := [opsinh, opcosh, optanh, opcoth, opsech, opcsch,
+ opasinh, opacosh, opatanh, opacoth, opasech, opacsch]
+ trigop := concat(rtrigop, htrigop)
+ elemop := concat(trigop, [oppi, oplog, opexp])
+ primop := [opei, opli, opsi, opci, operf, opli2, opint, opdint]
+ combop := [opfact, opperm, opbinom, oppow,
+ opsum, opdsum, opprod, opdprod]
+ specop := [opGamma, opGamma2, opBeta, opdigamma, oppolygamma, opabs,
+ opBesselJ, opBesselY, opBesselI, opBesselK]
+ anyop := [oppren, opdiff, opbox, opquote]
+ allop := concat(concat(concat(concat(concat(
+ algop,elemop),primop),combop),specop),anyop)
+
+-- odd and even operators, must be maintained current!
+ evenop := [opcos, opsec, opcosh, opsech, opabs]
+ oddop := [opsin, opcsc, optan, opcot, opasin, opacsc, opatan,
+ opsinh, opcsch, optanh, opcoth, opasinh, opacsch,opatanh,opacoth,
+ opsi, operf]
+
+-- operators whose second argument is a dummy variable
+ dummyvarop1 := [opdiff,opalg, opint, opsum, opprod]
+-- operators whose second and third arguments are dummy variables
+ dummyvarop2 := [opdint, opdsum, opdprod]
+
+ operator s ==
+ if (deref brandNew?) then startUp false
+ for op in allop repeat
+ is?(op, s) => return copy op
+ operator(s)$OP
+
+ dpi l == "%pi"::Symbol::O
+ dfact x == postfix("!"::Symbol::O, (ATOM(x)$Lisp => x; paren x))
+ dquote l == prefix(quote(first(l)::O), rest l)
+ dgamma l == prefix(hconcat("|"::Symbol::O, overbar(" "::Symbol::O)), l)
+ setDummyVar(op, n) == setProperty(op, DUMMYVAR, n pretend None)
+
+ dexp x ==
+ e := "%e"::Symbol::O
+ x = 1::O => e
+ e ** x
+
+ startUp b ==
+ brandNew?() := b
+ display(oppren, paren)
+ display(opbox, commaSeparate)
+ display(oppi, dpi)
+ display(opexp, dexp)
+ display(opGamma, dgamma)
+ display(opGamma2, dgamma)
+ display(opfact, dfact)
+ display(opquote, dquote)
+ display(opperm, supersub("A"::Symbol::O, #1))
+ display(opbinom, binomial(first #1, second #1))
+ display(oppow, first(#1) ** second(#1))
+ display(opsum, sum(first #1, second #1, third #1))
+ display(opprod, prod(first #1, second #1, third #1))
+ display(opint, int(first #1 * hconcat("d"::Symbol::O, second #1),
+ empty(), third #1))
+ input(oppren, convert concat(convert("("::Symbol)@InputForm,
+ concat(#1, convert(")"::Symbol)@InputForm)))
+ input(oppow, convert concat(convert("**"::Symbol)@InputForm, #1))
+ input(oproot,
+ convert [convert("**"::Symbol)@InputForm, first #1, 1 / second #1])
+ for op in algop repeat assert(op, ALGOP)
+ for op in rtrigop repeat assert(op, "rtrig")
+ for op in htrigop repeat assert(op, "htrig")
+ for op in trigop repeat assert(op, "trig")
+ for op in elemop repeat assert(op, "elem")
+ for op in primop repeat assert(op, "prim")
+ for op in combop repeat assert(op, "comb")
+ for op in specop repeat assert(op, "special")
+ for op in anyop repeat assert(op, "any")
+ for op in evenop repeat assert(op, EVEN)
+ for op in oddop repeat assert(op, ODD)
+ for op in dummyvarop1 repeat setDummyVar(op, 1)
+ for op in dummyvarop2 repeat setDummyVar(op, 2)
+ assert(oppren, "linear")
+ void
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the functional world should be compiled in the
+-- following order:
+--
+-- OP kl expr function
+
+<<domain BOP BasicOperator>>
+<<package BOP1 BasicOperatorFunctions1>>
+<<package COMMONOP CommonOperators>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/opalg.spad.pamphlet b/src/algebra/opalg.spad.pamphlet
new file mode 100644
index 00000000..a03c8cec
--- /dev/null
+++ b/src/algebra/opalg.spad.pamphlet
@@ -0,0 +1,294 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra opalg.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MODOP ModuleOperator}
+<<domain MODOP ModuleOperator>>=
+)abbrev domain MODOP ModuleOperator
+++ Author: Manuel Bronstein
+++ Date Created: 15 May 1990
+++ Date Last Updated: 17 June 1993
+++ Description:
+++ Algebra of ADDITIVE operators on a module.
+ModuleOperator(R: Ring, M:LeftModule(R)): Exports == Implementation where
+ O ==> OutputForm
+ OP ==> BasicOperator
+ FG ==> FreeGroup OP
+ RM ==> Record(coef:R, monom:FG)
+ TERM ==> List RM
+ FAB ==> FreeAbelianGroup TERM
+ OPADJ ==> "%opAdjoint"
+ OPEVAL ==> "%opEval"
+ INVEVAL ==> "%invEval"
+
+ Exports ==> Join(Ring, RetractableTo R, RetractableTo OP,
+ Eltable(M, M)) with
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has CommutativeRing then
+ Algebra(R)
+ adjoint: $ -> $
+ ++ adjoint(op) returns the adjoint of the operator \spad{op}.
+ adjoint: ($, $) -> $
+ ++ adjoint(op1, op2) sets the adjoint of op1 to be op2.
+ ++ op1 must be a basic operator
+ conjug : R -> R
+ ++ conjug(x)should be local but conditional
+ evaluate: ($, M -> M) -> $
+ ++ evaluate(f, u +-> g u) attaches the map g to f.
+ ++ f must be a basic operator
+ ++ g MUST be additive, i.e. \spad{g(a + b) = g(a) + g(b)} for
+ ++ any \spad{a}, \spad{b} in M.
+ ++ This implies that \spad{g(n a) = n g(a)} for
+ ++ any \spad{a} in M and integer \spad{n > 0}.
+ evaluateInverse: ($, M -> M) -> $
+ ++ evaluateInverse(x,f) \undocumented
+ "**": (OP, Integer) -> $
+ ++ op**n \undocumented
+ "**": ($, Integer) -> $
+ ++ op**n \undocumented
+ opeval : (OP, M) -> M
+ ++ opeval should be local but conditional
+ makeop : (R, FG) -> $
+ ++ makeop should be local but conditional
+
+ Implementation ==> FAB add
+ import NoneFunctions1($)
+ import BasicOperatorFunctions1(M)
+
+ Rep := FAB
+
+ inv : TERM -> $
+ termeval : (TERM, M) -> M
+ rmeval : (RM, M) -> M
+ monomeval: (FG, M) -> M
+ opInvEval: (OP, M) -> M
+ mkop : (R, FG) -> $
+ termprod0: (Integer, TERM, TERM) -> $
+ termprod : (Integer, TERM, TERM) -> TERM
+ termcopy : TERM -> TERM
+ trm2O : (Integer, TERM) -> O
+ term2O : TERM -> O
+ rm2O : (R, FG) -> O
+ nocopy : OP -> $
+
+ 1 == makeop(1, 1)
+ coerce(n:Integer):$ == n::R::$
+ coerce(r:R):$ == (zero? r => 0; makeop(r, 1))
+ coerce(op:OP):$ == nocopy copy op
+ nocopy(op:OP):$ == makeop(1, op::FG)
+ elt(x:$, r:M) == +/[t.exp * termeval(t.gen, r) for t in terms x]
+ rmeval(t, r) == t.coef * monomeval(t.monom, r)
+ termcopy t == [[rm.coef, rm.monom] for rm in t]
+ characteristic() == characteristic()$R
+ mkop(r, fg) == [[r, fg]$RM]$TERM :: $
+ evaluate(f, g) == nocopy setProperty(retract(f)@OP,OPEVAL,g pretend None)
+
+ if R has OrderedSet then
+ makeop(r, fg) == (r >= 0 => mkop(r, fg); - mkop(-r, fg))
+ else makeop(r, fg) == mkop(r, fg)
+
+ inv(t:TERM):$ ==
+ empty? t => 1
+ c := first(t).coef
+ m := first(t).monom
+ inv(rest t) * makeop(1, inv m) * (recip(c)::R::$)
+
+ x:$ ** i:Integer ==
+ i = 0 => 1
+ i > 0 => expt(x,i pretend PositiveInteger)$RepeatedSquaring($)
+ (inv(retract(x)@TERM)) ** (-i)
+
+ evaluateInverse(f, g) ==
+ nocopy setProperty(retract(f)@OP, INVEVAL, g pretend None)
+
+ coerce(x:$):O ==
+ zero? x => (0$R)::O
+ reduce(_+, [trm2O(t.exp, t.gen) for t in terms x])$List(O)
+
+ trm2O(c, t) ==
+-- one? c => term2O t
+ (c = 1) => term2O t
+ c = -1 => - term2O t
+ c::O * term2O t
+
+ term2O t ==
+ reduce(_*, [rm2O(rm.coef, rm.monom) for rm in t])$List(O)
+
+ rm2O(c, m) ==
+-- one? c => m::O
+ (c = 1) => m::O
+-- one? m => c::O
+ (m = 1) => c::O
+ c::O * m::O
+
+ x:$ * y:$ ==
+ +/[ +/[termprod0(t.exp * s.exp, t.gen, s.gen) for s in terms y]
+ for t in terms x]
+
+ termprod0(n, x, y) ==
+ n >= 0 => termprod(n, x, y)::$
+ - (termprod(-n, x, y)::$)
+
+ termprod(n, x, y) ==
+ lc := first(xx := termcopy x)
+ lc.coef := n * lc.coef
+ rm := last xx
+-- one?(first(y).coef) =>
+ ((first(y).coef) = 1) =>
+ rm.monom := rm.monom * first(y).monom
+ concat_!(xx, termcopy rest y)
+-- one?(rm.monom) =>
+ ((rm.monom) = 1) =>
+ rm.coef := rm.coef * first(y).coef
+ rm.monom := first(y).monom
+ concat_!(xx, termcopy rest y)
+ concat_!(xx, termcopy y)
+
+ if M has ExpressionSpace then
+ opeval(op, r) ==
+ (func := property(op, OPEVAL)) case "failed" => kernel(op, r)
+ ((func::None) pretend (M -> M)) r
+
+ else
+ opeval(op, r) ==
+ (func := property(op, OPEVAL)) case "failed" =>
+ error "eval: operator has no evaluation function"
+ ((func::None) pretend (M -> M)) r
+
+ opInvEval(op, r) ==
+ (func := property(op, INVEVAL)) case "failed" =>
+ error "eval: operator has no inverse evaluation function"
+ ((func::None) pretend (M -> M)) r
+
+ termeval(t, r) ==
+ for rm in reverse t repeat r := rmeval(rm, r)
+ r
+
+ monomeval(m, r) ==
+ for rec in reverse_! factors m repeat
+ e := rec.exp
+ g := rec.gen
+ e > 0 =>
+ for i in 1..e repeat r := opeval(g, r)
+ e < 0 =>
+ for i in 1..(-e) repeat r := opInvEval(g, r)
+ r
+
+ recip x ==
+ (r := retractIfCan(x)@Union(R, "failed")) case "failed" => "failed"
+ (r1 := recip(r::R)) case "failed" => "failed"
+ r1::R::$
+
+ retractIfCan(x:$):Union(R, "failed") ==
+ (r:= retractIfCan(x)@Union(TERM,"failed")) case "failed" => "failed"
+ empty?(t := r::TERM) => 0$R
+ empty? rest t =>
+ rm := first t
+-- one?(rm.monom) => rm.coef
+ (rm.monom = 1) => rm.coef
+ "failed"
+ "failed"
+
+ retractIfCan(x:$):Union(OP, "failed") ==
+ (r:= retractIfCan(x)@Union(TERM,"failed")) case "failed" => "failed"
+ empty?(t := r::TERM) => "failed"
+ empty? rest t =>
+ rm := first t
+-- one?(rm.coef) => retractIfCan(rm.monom)
+ (rm.coef = 1) => retractIfCan(rm.monom)
+ "failed"
+ "failed"
+
+ if R has CommutativeRing then
+ termadj : TERM -> $
+ rmadj : RM -> $
+ monomadj : FG -> $
+ opadj : OP -> $
+
+ r:R * x:$ == r::$ * x
+ x:$ * r:R == x * (r::$)
+ adjoint x == +/[t.exp * termadj(t.gen) for t in terms x]
+ rmadj t == conjug(t.coef) * monomadj(t.monom)
+ adjoint(op, adj) == nocopy setProperty(retract(op)@OP, OPADJ, adj::None)
+
+ termadj t ==
+ ans:$ := 1
+ for rm in t repeat ans := rmadj(rm) * ans
+ ans
+
+ monomadj m ==
+ ans:$ := 1
+ for rec in factors m repeat ans := (opadj(rec.gen) ** rec.exp) * ans
+ ans
+
+ opadj op ==
+ (adj := property(op, OPADJ)) case "failed" =>
+ error "adjoint: operator does not have a defined adjoint"
+ (adj::None) pretend $
+
+ if R has conjugate:R -> R then conjug r == conjugate r else conjug r == r
+
+@
+\section{domain OP Operator}
+<<domain OP Operator>>=
+)abbrev domain OP Operator
+++ Author: Manuel Bronstein
+++ Date Created: 15 May 1990
+++ Date Last Updated: 12 February 1993
+++ Description:
+++ Algebra of ADDITIVE operators over a ring.
+Operator(R: Ring) == ModuleOperator(R,R)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MODOP ModuleOperator>>
+<<domain OP Operator>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/openmath.spad.pamphlet b/src/algebra/openmath.spad.pamphlet
new file mode 100644
index 00000000..2ad57181
--- /dev/null
+++ b/src/algebra/openmath.spad.pamphlet
@@ -0,0 +1,331 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra openmath.spad}
+\author{Mike Dewar, Vilya Harvey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package OMEXPR ExpressionToOpenMath}
+<<package OMEXPR ExpressionToOpenMath>>=
+)abbrev package OMEXPR ExpressionToOpenMath
+++ Author: Mike Dewar & Vilya Harvey
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: \spadtype{ExpressionToOpenMath} provides support for
+++ converting objects of type \spadtype{Expression} into OpenMath.
+ExpressionToOpenMath(R: Join(OpenMath, OrderedSet, Ring)): with
+ OMwrite : Expression R -> String
+ OMwrite : (Expression R, Boolean) -> String
+ OMwrite : (OpenMathDevice, Expression R) -> Void
+ OMwrite : (OpenMathDevice, Expression R, Boolean) -> Void
+ == add
+ import Expression R
+ SymInfo ==> Record(cd:String, name:String)
+ import SymInfo
+ import Record(key: Symbol, entry: SymInfo)
+ import AssociationList(Symbol, SymInfo)
+ import OMENC
+
+ ----------------------------
+ -- Local translation tables.
+ ----------------------------
+
+ nullaryFunctionAList : AssociationList(Symbol, SymInfo) := construct [_
+ [pi, ["nums1", "pi"]] ]
+
+ unaryFunctionAList : AssociationList(Symbol, SymInfo) := construct [_
+ [exp, ["transc1", "exp"]],_
+ [log, ["transc1", "ln"]],_
+ [sin, ["transc1", "sin"]],_
+ [cos, ["transc1", "cos"]],_
+ [tan, ["transc1", "tan"]],_
+ [cot, ["transc1", "cot"]],_
+ [sec, ["transc1", "sec"]],_
+ [csc, ["transc1", "csc"]],_
+ [asin, ["transc1", "arcsin"]],_
+ [acos, ["transc1", "arccos"]],_
+ [atan, ["transc1", "arctan"]],_
+ [acot, ["transc1", "arccot"]],_
+ [asec, ["transc1", "arcsec"]],_
+ [acsc, ["transc1", "arccsc"]],_
+ [sinh, ["transc1", "sinh"]],_
+ [cosh, ["transc1", "cosh"]],_
+ [tanh, ["transc1", "tanh"]],_
+ [coth, ["transc1", "coth"]],_
+ [sech, ["transc1", "sech"]],_
+ [csch, ["transc1", "csch"]],_
+ [asinh, ["transc1", "arcsinh"]],_
+ [acosh, ["transc1", "arccosh"]],_
+ [atanh, ["transc1", "arctanh"]],_
+ [acoth, ["transc1", "arccoth"]],_
+ [asech, ["transc1", "arcsech"]],_
+ [acsch, ["transc1", "arccsch"]],_
+ [factorial, ["integer1", "factorial"]],_
+ [abs, ["arith1", "abs"]] ]
+
+ -- Still need the following unary functions:
+ -- digamma
+ -- Gamma
+ -- airyAi
+ -- airyBi
+ -- erf
+ -- Ei
+ -- Si
+ -- Ci
+ -- li
+ -- dilog
+
+ -- Still need the following binary functions:
+ -- Gamma(a, x)
+ -- Beta(x,y)
+ -- polygamma(k,x)
+ -- besselJ(v,x)
+ -- besselY(v,x)
+ -- besselI(v,x)
+ -- besselK(v,x)
+ -- permutation(n, m)
+ -- summation(x:%, n:Symbol) : as opposed to "definite" sum
+ -- product(x:%, n:Symbol) : ditto
+
+ ------------------------
+ -- Forward declarations.
+ ------------------------
+
+ outputOMExpr : (OpenMathDevice, Expression R) -> Void
+
+ -------------------------
+ -- Local helper functions
+ -------------------------
+
+ outputOMArith1(dev: OpenMathDevice, sym: String, args: List Expression R): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "arith1", sym)
+ for arg in args repeat
+ OMwrite(dev, arg, false)
+ OMputEndApp(dev)
+
+ outputOMLambda(dev: OpenMathDevice, ex: Expression R, var: Expression R): Void ==
+ OMputBind(dev)
+ OMputSymbol(dev, "fns1", "lambda")
+ OMputBVar(dev)
+ OMwrite(dev, var, false)
+ OMputEndBVar(dev)
+ OMwrite(dev, ex, false)
+ OMputEndBind(dev)
+
+ outputOMInterval(dev: OpenMathDevice, lo: Expression R, hi: Expression R): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "interval1", "interval")
+ OMwrite(dev, lo, false)
+ OMwrite(dev, hi, false)
+ OMputEndApp(dev)
+
+ outputOMIntInterval(dev: OpenMathDevice, lo: Expression R, hi: Expression R): Void ==
+ OMputApp(dev)
+ OMputSymbol(dev, "interval1", "integer__interval")
+ OMwrite(dev, lo, false)
+ OMwrite(dev, hi, false)
+ OMputEndApp(dev)
+
+ outputOMBinomial(dev: OpenMathDevice, args: List Expression R): Void ==
+ not #args=2 => error "Wrong number of arguments to binomial"
+ OMputApp(dev)
+ OMputSymbol(dev, "combinat1", "binomial")
+ for arg in args repeat
+ OMwrite(dev, arg, false)
+ OMputEndApp(dev)
+
+ outputOMPower(dev: OpenMathDevice, args: List Expression R): Void ==
+ not #args=2 => error "Wrong number of arguments to power"
+ outputOMArith1(dev, "power", args)
+
+ outputOMDefsum(dev: OpenMathDevice, args: List Expression R): Void ==
+ #args ^= 5 => error "Unexpected number of arguments to a defsum"
+ OMputApp(dev)
+ OMputSymbol(dev, "arith1", "sum")
+ outputOMIntInterval(dev, args.4, args.5)
+ outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+ OMputEndApp(dev)
+
+ outputOMDefprod(dev: OpenMathDevice, args: List Expression R): Void ==
+ #args ^= 5 => error "Unexpected number of arguments to a defprod"
+ OMputApp(dev)
+ OMputSymbol(dev, "arith1", "product")
+ outputOMIntInterval(dev, args.4, args.5)
+ outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+ OMputEndApp(dev)
+
+ outputOMDefint(dev: OpenMathDevice, args: List Expression R): Void ==
+ #args ^= 5 => error "Unexpected number of arguments to a defint"
+ OMputApp(dev)
+ OMputSymbol(dev, "calculus1", "defint")
+ outputOMInterval(dev, args.4, args.5)
+ outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+ OMputEndApp(dev)
+
+ outputOMInt(dev: OpenMathDevice, args: List Expression R): Void ==
+ #args ^= 3 => error "Unexpected number of arguments to a defint"
+ OMputApp(dev)
+ OMputSymbol(dev, "calculus1", "int")
+ outputOMLambda(dev, eval(args.1, args.2, args.3), args.3)
+ OMputEndApp(dev)
+
+ outputOMFunction(dev: OpenMathDevice, op: Symbol, args: List Expression R): Void ==
+ nargs := #args
+ zero? nargs =>
+ omOp: Union(SymInfo, "failed") := search(op, nullaryFunctionAList)
+ omOp case "failed" =>
+ error concat ["No OpenMath definition for nullary function ", coerce op]
+ OMputSymbol(dev, omOp.cd, omOp.name)
+-- one? nargs =>
+ (nargs = 1) =>
+ omOp: Union(SymInfo, "failed") := search(op, unaryFunctionAList)
+ omOp case "failed" =>
+ error concat ["No OpenMath definition for unary function ", coerce op]
+ OMputApp(dev)
+ OMputSymbol(dev, omOp.cd, omOp.name)
+ for arg in args repeat
+ OMwrite(dev, arg, false)
+ OMputEndApp(dev)
+ -- Most of the binary operators cannot be handled trivialy like the
+ -- unary ones since they have bound variables of one kind or another.
+ -- The special functions should be straightforward, but we don't have
+ -- a CD for them yet :-)
+ op = %defint => outputOMDefint(dev, args)
+ op = integral => outputOMInt(dev, args)
+ op = %defsum => outputOMDefsum(dev, args)
+ op = %defprod => outputOMDefprod(dev, args)
+ op = %power => outputOMPower(dev, args)
+ op = binomial => outputOMBinomial(dev, args)
+ error concat ["No OpenMath definition for function ", string op]
+
+ outputOMExpr(dev: OpenMathDevice, ex: Expression R): Void ==
+ ground? ex => OMwrite(dev, ground ex, false)
+ not((v := retractIfCan(ex)@Union(Symbol,"failed")) case "failed") =>
+ OMputVariable(dev, v)
+ not((w := isPlus ex) case "failed") => outputOMArith1(dev, "plus", w)
+ not((w := isTimes ex) case "failed") => outputOMArith1(dev, "times", w)
+ --not((y := isMult ex) case "failed") =>
+ -- outputOMArith("times", [OMwrite(y.coef)$Integer,
+ -- OMwrite(coerce y.var)])
+ -- At the time of writing we don't need both isExpt and isPower
+ -- here but they may be relevent when we integrate this stuff into
+ -- the main Expression code. Note that if we don't check that
+ -- the exponent is non-trivial we get thrown into an infinite recursion.
+-- not (((x := isExpt ex) case "failed") or one? x.exponent) =>
+ not (((x := isExpt ex) case "failed") or (x.exponent = 1)) =>
+ not((s := symbolIfCan(x.var)@Union(Symbol,"failed")) case "failed") =>
+ --outputOMPower(dev, [s::Expression(R), (x.exponent)::Expression(R)])
+ OMputApp(dev)
+ OMputSymbol(dev, "arith1", "power")
+ OMputVariable(dev, s)
+ OMputInteger(dev, x.exponent)
+ OMputEndApp(dev)
+ -- TODO: add error handling code here...
+-- not (((z := isPower ex) case "failed") or one? z.exponent) =>
+ not (((z := isPower ex) case "failed") or (z.exponent = 1)) =>
+ outputOMPower(dev, [ z.val, z.exponent::Expression R ])
+ --OMputApp(dev)
+ --OMputSymbol(dev, "arith1", "power")
+ --outputOMExpr(dev, z.val)
+ --OMputInteger(dev, z.exponent)
+ --OMputEndApp(dev)
+ -- Must only be one top-level Kernel by this point
+ k : Kernel Expression R := first kernels ex
+ outputOMFunction(dev, name operator k, argument k)
+
+
+ ----------
+ -- Exports
+ ----------
+
+ OMwrite(ex: Expression R): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML())
+ OMputObject(dev)
+ outputOMExpr(dev, ex)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(ex: Expression R, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML())
+ if wholeObj then
+ OMputObject(dev)
+ outputOMExpr(dev, ex)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, ex: Expression R): Void ==
+ OMputObject(dev)
+ outputOMExpr(dev, ex)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, ex: Expression R, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ outputOMExpr(dev, ex)
+ if wholeObj then
+ OMputEndObject(dev)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package OMEXPR ExpressionToOpenMath>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ore.spad.pamphlet b/src/algebra/ore.spad.pamphlet
new file mode 100644
index 00000000..1c567ebf
--- /dev/null
+++ b/src/algebra/ore.spad.pamphlet
@@ -0,0 +1,559 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ore.spad}
+\author{Manuel Bronstein, Jean Della Dora, Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category OREPCAT UnivariateSkewPolynomialCategory}
+<<category OREPCAT UnivariateSkewPolynomialCategory>>=
+)abbrev category OREPCAT UnivariateSkewPolynomialCategory
+++ Author: Manuel Bronstein, Jean Della Dora, Stephen M. Watt
+++ Date Created: 19 October 1993
+++ Date Last Updated: 1 February 1994
+++ Description:
+++ This is the category of univariate skew polynomials over an Ore
+++ coefficient ring.
+++ The multiplication is given by \spad{x a = \sigma(a) x + \delta a}.
+++ This category is an evolution of the types
+++ MonogenicLinearOperator, OppositeMonogenicLinearOperator, and
+++ NonCommutativeOperatorDivision
+++ developped by Jean Della Dora and Stephen M. Watt.
+UnivariateSkewPolynomialCategory(R:Ring):
+ Category == Join(Ring, BiModule(R, R), FullyRetractableTo R) with
+ degree: $ -> NonNegativeInteger
+ ++ degree(l) is \spad{n} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ minimumDegree: $ -> NonNegativeInteger
+ ++ minimumDegree(l) is the smallest \spad{k} such that
+ ++ \spad{a(k) ^= 0} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ leadingCoefficient: $ -> R
+ ++ leadingCoefficient(l) is \spad{a(n)} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ reductum: $ -> $
+ ++ reductum(l) is \spad{l - monomial(a(n),n)} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ coefficient: ($, NonNegativeInteger) -> R
+ ++ coefficient(l,k) is \spad{a(k)} if
+ ++ \spad{l = sum(monomial(a(i),i), i = 0..n)}.
+ monomial: (R, NonNegativeInteger) -> $
+ ++ monomial(c,k) produces c times the k-th power of
+ ++ the generating operator, \spad{monomial(1,1)}.
+ coefficients: % -> List R
+ ++ coefficients(l) returns the list of all the nonzero
+ ++ coefficients of l.
+ apply: (%, R, R) -> R
+ ++ apply(p, c, m) returns \spad{p(m)} where the action is
+ ++ given by \spad{x m = c sigma(m) + delta(m)}.
+ if R has CommutativeRing then Algebra R
+ if R has IntegralDomain then
+ "exquo": (%, R) -> Union(%, "failed")
+ ++ exquo(l, a) returns the exact quotient of l by a,
+ ++ returning \axiom{"failed"} if this is not possible.
+ monicLeftDivide: (%, %) -> Record(quotient: %, remainder: %)
+ ++ monicLeftDivide(a,b) returns the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ \spad{b} must be monic.
+ ++ This process is called ``left division''.
+ monicRightDivide: (%, %) -> Record(quotient: %, remainder: %)
+ ++ monicRightDivide(a,b) returns the pair \spad{[q,r]} such that
+ ++ \spad{a = q*b + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ \spad{b} must be monic.
+ ++ This process is called ``right division''.
+ if R has GcdDomain then
+ content: % -> R
+ ++ content(l) returns the gcd of all the coefficients of l.
+ primitivePart: % -> %
+ ++ primitivePart(l) returns l0 such that \spad{l = a * l0}
+ ++ for some a in R, and \spad{content(l0) = 1}.
+ if R has Field then
+ leftDivide: (%, %) -> Record(quotient: %, remainder: %)
+ ++ leftDivide(a,b) returns the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ This process is called ``left division''.
+ leftQuotient: (%, %) -> %
+ ++ leftQuotient(a,b) computes the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ The value \spad{q} is returned.
+ leftRemainder: (%, %) -> %
+ ++ leftRemainder(a,b) computes the pair \spad{[q,r]} such that
+ ++ \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ The value \spad{r} is returned.
+ leftExactQuotient:(%, %) -> Union(%, "failed")
+ ++ leftExactQuotient(a,b) computes the value \spad{q}, if it exists,
+ ++ such that \spad{a = b*q}.
+ leftGcd: (%, %) -> %
+ ++ leftGcd(a,b) computes the value \spad{g} of highest degree
+ ++ such that
+ ++ \spad{a = g*aa}
+ ++ \spad{b = g*bb}
+ ++ for some values \spad{aa} and \spad{bb}.
+ ++ The value \spad{g} is computed using left-division.
+ leftExtendedGcd: (%, %) -> Record(coef1:%, coef2:%, generator:%)
+ ++ leftExtendedGcd(a,b) returns \spad{[c,d]} such that
+ ++ \spad{g = a * c + b * d = leftGcd(a, b)}.
+ rightLcm: (%, %) -> %
+ ++ rightLcm(a,b) computes the value \spad{m} of lowest degree
+ ++ such that \spad{m = a*aa = b*bb} for some values
+ ++ \spad{aa} and \spad{bb}. The value \spad{m} is
+ ++ computed using left-division.
+ rightDivide: (%, %) -> Record(quotient: %, remainder: %)
+ ++ rightDivide(a,b) returns the pair \spad{[q,r]} such that
+ ++ \spad{a = q*b + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ This process is called ``right division''.
+ rightQuotient: (%, %) -> %
+ ++ rightQuotient(a,b) computes the pair \spad{[q,r]} such that
+ ++ \spad{a = q*b + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ The value \spad{q} is returned.
+ rightRemainder: (%, %) -> %
+ ++ rightRemainder(a,b) computes the pair \spad{[q,r]} such that
+ ++ \spad{a = q*b + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ The value \spad{r} is returned.
+ rightExactQuotient:(%, %) -> Union(%, "failed")
+ ++ rightExactQuotient(a,b) computes the value \spad{q}, if it exists
+ ++ such that \spad{a = q*b}.
+ rightGcd: (%, %) -> %
+ ++ rightGcd(a,b) computes the value \spad{g} of highest degree
+ ++ such that
+ ++ \spad{a = aa*g}
+ ++ \spad{b = bb*g}
+ ++ for some values \spad{aa} and \spad{bb}.
+ ++ The value \spad{g} is computed using right-division.
+ rightExtendedGcd: (%, %) -> Record(coef1:%, coef2:%, generator:%)
+ ++ rightExtendedGcd(a,b) returns \spad{[c,d]} such that
+ ++ \spad{g = c * a + d * b = rightGcd(a, b)}.
+ leftLcm: (%, %) -> %
+ ++ leftLcm(a,b) computes the value \spad{m} of lowest degree
+ ++ such that \spad{m = aa*a = bb*b} for some values
+ ++ \spad{aa} and \spad{bb}. The value \spad{m} is
+ ++ computed using right-division.
+
+ add
+ coerce(x:R):% == monomial(x, 0)
+
+ coefficients l ==
+ ans:List(R) := empty()
+ while l ^= 0 repeat
+ ans := concat(leadingCoefficient l, ans)
+ l := reductum l
+ ans
+
+ a:R * y:% ==
+ z:% := 0
+ while y ^= 0 repeat
+ z := z + monomial(a * leadingCoefficient y, degree y)
+ y := reductum y
+ z
+
+ retractIfCan(x:%):Union(R, "failed") ==
+ zero? x or zero? degree x => leadingCoefficient x
+ "failed"
+
+ if R has IntegralDomain then
+ l exquo a ==
+ ans:% := 0
+ while l ^= 0 repeat
+ (u := (leadingCoefficient(l) exquo a)) case "failed" =>
+ return "failed"
+ ans := ans + monomial(u::R, degree l)
+ l := reductum l
+ ans
+
+ if R has GcdDomain then
+ content l == gcd coefficients l
+ primitivePart l == (l exquo content l)::%
+
+ if R has Field then
+ leftEEA: (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)
+ rightEEA: (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)
+ ncgcd: (%, %, (%, %) -> %) -> %
+ nclcm: (%, %, (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)) -> %
+ exactQuotient: Record(quotient:%, remainder:%) -> Union(%, "failed")
+ extended: (%, %, (%, %) -> Record(gcd:%, coef1:%, coef2:%, lcm:%)) ->
+ Record(coef1:%, coef2:%, generator:%)
+
+ leftQuotient(a, b) == leftDivide(a,b).quotient
+ leftRemainder(a, b) == leftDivide(a,b).remainder
+ leftExtendedGcd(a, b) == extended(a, b, leftEEA)
+ rightLcm(a, b) == nclcm(a, b, leftEEA)
+ rightQuotient(a, b) == rightDivide(a,b).quotient
+ rightRemainder(a, b) == rightDivide(a,b).remainder
+ rightExtendedGcd(a, b) == extended(a, b, rightEEA)
+ leftLcm(a, b) == nclcm(a, b, rightEEA)
+ leftExactQuotient(a, b) == exactQuotient leftDivide(a, b)
+ rightExactQuotient(a, b) == exactQuotient rightDivide(a, b)
+ rightGcd(a, b) == ncgcd(a, b, rightRemainder)
+ leftGcd(a, b) == ncgcd(a, b, leftRemainder)
+ exactQuotient qr == (zero?(qr.remainder) => qr.quotient; "failed")
+
+ -- returns [g = leftGcd(a, b), c, d, l = rightLcm(a, b)]
+ -- such that g := a c + b d
+ leftEEA(a, b) ==
+ a0 := a
+ u0:% := v:% := 1
+ v0:% := u:% := 0
+ while b ^= 0 repeat
+ qr := leftDivide(a, b)
+ (a, b) := (b, qr.remainder)
+ (u0, u):= (u, u0 - u * qr.quotient)
+ (v0, v):= (v, v0 - v * qr.quotient)
+ [a, u0, v0, a0 * u]
+
+ ncgcd(a, b, ncrem) ==
+ zero? a => b
+ zero? b => a
+ degree a < degree b => ncgcd(b, a, ncrem)
+ while b ^= 0 repeat (a, b) := (b, ncrem(a, b))
+ a
+
+ extended(a, b, eea) ==
+ zero? a => [0, 1, b]
+ zero? b => [1, 0, a]
+ degree a < degree b =>
+ rec := eea(b, a)
+ [rec.coef2, rec.coef1, rec.gcd]
+ rec := eea(a, b)
+ [rec.coef1, rec.coef2, rec.gcd]
+
+ nclcm(a, b, eea) ==
+ zero? a or zero? b => 0
+ degree a < degree b => nclcm(b, a, eea)
+ rec := eea(a, b)
+ rec.lcm
+
+ -- returns [g = rightGcd(a, b), c, d, l = leftLcm(a, b)]
+ -- such that g := a c + b d
+ rightEEA(a, b) ==
+ a0 := a
+ u0:% := v:% := 1
+ v0:% := u:% := 0
+ while b ^= 0 repeat
+ qr := rightDivide(a, b)
+ (a, b) := (b, qr.remainder)
+ (u0, u):= (u, u0 - qr.quotient * u)
+ (v0, v):= (v, v0 - qr.quotient * v)
+ [a, u0, v0, u * a0]
+
+@
+\section{package APPLYORE ApplyUnivariateSkewPolynomial}
+<<package APPLYORE ApplyUnivariateSkewPolynomial>>=
+)abbrev package APPLYORE ApplyUnivariateSkewPolynomial
+++ Author: Manuel Bronstein
+++ Date Created: 7 December 1993
+++ Date Last Updated: 1 February 1994
+++ Description:
+++ \spad{ApplyUnivariateSkewPolynomial} (internal) allows univariate
+++ skew polynomials to be applied to appropriate modules.
+ApplyUnivariateSkewPolynomial(R:Ring, M: LeftModule R,
+ P: UnivariateSkewPolynomialCategory R): with
+ apply: (P, M -> M, M) -> M
+ ++ apply(p, f, m) returns \spad{p(m)} where the action is given
+ ++ by \spad{x m = f(m)}.
+ ++ \spad{f} must be an R-pseudo linear map on M.
+ == add
+ apply(p, f, m) ==
+ w:M := 0
+ mn:M := m
+ for i in 0..degree p repeat
+ w := w + coefficient(p, i) * mn
+ mn := f mn
+ w
+
+@
+\section{domain AUTOMOR Automorphism}
+<<domain AUTOMOR Automorphism>>=
+)abbrev domain AUTOMOR Automorphism
+++ Author: Manuel Bronstein
+++ Date Created: 31 January 1994
+++ Date Last Updated: 31 January 1994
+++ References:
+++ Description:
+++ Automorphism R is the multiplicative group of automorphisms of R.
+-- In fact, non-invertible endomorphism are allowed as partial functions.
+-- This domain is noncanonical in that f*f^{-1} will be the identity
+-- function but won't be equal to 1.
+Automorphism(R:Ring): Join(Group, Eltable(R, R)) with
+ morphism: (R -> R) -> %
+ ++ morphism(f) returns the non-invertible morphism given by f.
+ morphism: (R -> R, R -> R) -> %
+ ++ morphism(f, g) returns the invertible morphism given by f, where
+ ++ g is the inverse of f..
+ morphism: ((R, Integer) -> R) -> %
+ ++ morphism(f) returns the morphism given by \spad{f^n(x) = f(x,n)}.
+ == add
+ err: R -> R
+ ident: (R, Integer) -> R
+ iter: (R -> R, NonNegativeInteger, R) -> R
+ iterat: (R -> R, R -> R, Integer, R) -> R
+ apply: (%, R, Integer) -> R
+
+ Rep := ((R, Integer) -> R)
+
+ 1 == ident
+ err r == error "Morphism is not invertible"
+ ident(r, n) == r
+ f = g == EQ(f, g)$Lisp
+ elt(f, r) == apply(f, r, 1)
+ inv f == apply(f, #1, - #2)
+ f ** n == apply(f, #1, n * #2)
+ coerce(f:%):OutputForm == message("R -> R")
+ morphism(f:(R, Integer) -> R):% == f
+ morphism(f:R -> R):% == morphism(f, err)
+ morphism(f, g) == iterat(f, g, #2, #1)
+ apply(f, r, n) == (g := f pretend ((R, Integer) -> R); g(r, n))
+
+ iterat(f, g, n, r) ==
+ n < 0 => iter(g, (-n)::NonNegativeInteger, r)
+ iter(f, n::NonNegativeInteger, r)
+
+ iter(f, n, r) ==
+ for i in 1..n repeat r := f r
+ r
+
+ f * g ==
+ f = g => f**2
+ iterat(f g #1, (inv g)(inv f) #1, #2, #1)
+
+@
+\section{package OREPCTO UnivariateSkewPolynomialCategoryOps}
+<<package OREPCTO UnivariateSkewPolynomialCategoryOps>>=
+)abbrev package OREPCTO UnivariateSkewPolynomialCategoryOps
+++ Author: Manuel Bronstein
+++ Date Created: 1 February 1994
+++ Date Last Updated: 1 February 1994
+++ Description:
+++ \spad{UnivariateSkewPolynomialCategoryOps} provides products and
+++ divisions of univariate skew polynomials.
+-- Putting those operations here rather than defaults in OREPCAT allows
+-- OREPCAT to be defined independently of sigma and delta.
+-- MB 2/94
+UnivariateSkewPolynomialCategoryOps(R, C): Exports == Implementation where
+ R: Ring
+ C: UnivariateSkewPolynomialCategory R
+
+ N ==> NonNegativeInteger
+ MOR ==> Automorphism R
+ QUOREM ==> Record(quotient: C, remainder: C)
+
+ Exports ==> with
+ times: (C, C, MOR, R -> R) -> C
+ ++ times(p, q, sigma, delta) returns \spad{p * q}.
+ ++ \spad{\sigma} and \spad{\delta} are the maps to use.
+ apply: (C, R, R, MOR, R -> R) -> R
+ ++ apply(p, c, m, sigma, delta) returns \spad{p(m)} where the action
+ ++ is given by \spad{x m = c sigma(m) + delta(m)}.
+ if R has IntegralDomain then
+ monicLeftDivide: (C, C, MOR) -> QUOREM
+ ++ monicLeftDivide(a, b, sigma) returns the pair \spad{[q,r]}
+ ++ such that \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ \spad{b} must be monic.
+ ++ This process is called ``left division''.
+ ++ \spad{\sigma} is the morphism to use.
+ monicRightDivide: (C, C, MOR) -> QUOREM
+ ++ monicRightDivide(a, b, sigma) returns the pair \spad{[q,r]}
+ ++ such that \spad{a = q*b + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ \spad{b} must be monic.
+ ++ This process is called ``right division''.
+ ++ \spad{\sigma} is the morphism to use.
+ if R has Field then
+ leftDivide: (C, C, MOR) -> QUOREM
+ ++ leftDivide(a, b, sigma) returns the pair \spad{[q,r]} such
+ ++ that \spad{a = b*q + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ This process is called ``left division''.
+ ++ \spad{\sigma} is the morphism to use.
+ rightDivide: (C, C, MOR) -> QUOREM
+ ++ rightDivide(a, b, sigma) returns the pair \spad{[q,r]} such
+ ++ that \spad{a = q*b + r} and the degree of \spad{r} is
+ ++ less than the degree of \spad{b}.
+ ++ This process is called ``right division''.
+ ++ \spad{\sigma} is the morphism to use.
+
+ Implementation ==> add
+ termPoly: (R, N, C, MOR, R -> R) -> C
+ localLeftDivide : (C, C, MOR, R) -> QUOREM
+ localRightDivide: (C, C, MOR, R) -> QUOREM
+
+ times(x, y, sigma, delta) ==
+ zero? y => 0
+ z:C := 0
+ while x ^= 0 repeat
+ z := z + termPoly(leadingCoefficient x, degree x, y, sigma, delta)
+ x := reductum x
+ z
+
+ termPoly(a, n, y, sigma, delta) ==
+ zero? y => 0
+ (u := subtractIfCan(n, 1)) case "failed" => a * y
+ n1 := u::N
+ z:C := 0
+ while y ^= 0 repeat
+ m := degree y
+ b := leadingCoefficient y
+ z := z + termPoly(a, n1, monomial(sigma b, m + 1), sigma, delta)
+ + termPoly(a, n1, monomial(delta b, m), sigma, delta)
+ y := reductum y
+ z
+
+ apply(p, c, x, sigma, delta) ==
+ w:R := 0
+ xn:R := x
+ for i in 0..degree p repeat
+ w := w + coefficient(p, i) * xn
+ xn := c * sigma xn + delta xn
+ w
+
+ -- localLeftDivide(a, b) returns [q, r] such that a = q b + r
+ -- b1 is the inverse of the leadingCoefficient of b
+ localLeftDivide(a, b, sigma, b1) ==
+ zero? b => error "leftDivide: division by 0"
+ zero? a or
+ (n := subtractIfCan(degree(a),(m := degree b))) case "failed" =>
+ [0,a]
+ q := monomial((sigma**(-m))(b1 * leadingCoefficient a), n::N)
+ qr := localLeftDivide(a - b * q, b, sigma, b1)
+ [q + qr.quotient, qr.remainder]
+
+ -- localRightDivide(a, b) returns [q, r] such that a = q b + r
+ -- b1 is the inverse of the leadingCoefficient of b
+ localRightDivide(a, b, sigma, b1) ==
+ zero? b => error "rightDivide: division by 0"
+ zero? a or
+ (n := subtractIfCan(degree(a),(m := degree b))) case "failed" =>
+ [0,a]
+ q := monomial(leadingCoefficient(a) * (sigma**n) b1, n::N)
+ qr := localRightDivide(a - q * b, b, sigma, b1)
+ [q + qr.quotient, qr.remainder]
+
+ if R has IntegralDomain then
+ monicLeftDivide(a, b, sigma) ==
+ unit?(u := leadingCoefficient b) =>
+ localLeftDivide(a, b, sigma, recip(u)::R)
+ error "monicLeftDivide: divisor is not monic"
+
+ monicRightDivide(a, b, sigma) ==
+ unit?(u := leadingCoefficient b) =>
+ localRightDivide(a, b, sigma, recip(u)::R)
+ error "monicRightDivide: divisor is not monic"
+
+ if R has Field then
+ leftDivide(a, b, sigma) ==
+ localLeftDivide(a, b, sigma, inv leadingCoefficient b)
+
+ rightDivide(a, b, sigma) ==
+ localRightDivide(a, b, sigma, inv leadingCoefficient b)
+
+@
+\section{domain ORESUP SparseUnivariateSkewPolynomial}
+<<domain ORESUP SparseUnivariateSkewPolynomial>>=
+)abbrev domain ORESUP SparseUnivariateSkewPolynomial
+++ Author: Manuel Bronstein
+++ Date Created: 19 October 1993
+++ Date Last Updated: 1 February 1994
+++ Description:
+++ This is the domain of sparse univariate skew polynomials over an Ore
+++ coefficient field.
+++ The multiplication is given by \spad{x a = \sigma(a) x + \delta a}.
+SparseUnivariateSkewPolynomial(R:Ring, sigma:Automorphism R, delta: R -> R):
+ UnivariateSkewPolynomialCategory R with
+ outputForm: (%, OutputForm) -> OutputForm
+ ++ outputForm(p, x) returns the output form of p using x for the
+ ++ otherwise anonymous variable.
+ == SparseUnivariatePolynomial R add
+ import UnivariateSkewPolynomialCategoryOps(R, %)
+
+ x:% * y:% == times(x, y, sigma, delta)
+ apply(p, c, r) == apply(p, c, r, sigma, delta)
+
+ if R has IntegralDomain then
+ monicLeftDivide(a, b) == monicLeftDivide(a, b, sigma)
+ monicRightDivide(a, b) == monicRightDivide(a, b, sigma)
+
+ if R has Field then
+ leftDivide(a, b) == leftDivide(a, b, sigma)
+ rightDivide(a, b) == rightDivide(a, b, sigma)
+
+@
+\section{domain OREUP UnivariateSkewPolynomial}
+<<domain OREUP UnivariateSkewPolynomial>>=
+)abbrev domain OREUP UnivariateSkewPolynomial
+++ Author: Manuel Bronstein
+++ Date Created: 19 October 1993
+++ Date Last Updated: 1 February 1994
+++ Description:
+++ This is the domain of univariate skew polynomials over an Ore
+++ coefficient field in a named variable.
+++ The multiplication is given by \spad{x a = \sigma(a) x + \delta a}.
+UnivariateSkewPolynomial(x:Symbol, R:Ring, sigma:Automorphism R, delta: R -> R):
+ UnivariateSkewPolynomialCategory R with
+ coerce: Variable x -> %
+ ++ coerce(x) returns x as a skew-polynomial.
+ == SparseUnivariateSkewPolynomial(R, sigma, delta) add
+ Rep := SparseUnivariateSkewPolynomial(R, sigma, delta)
+ coerce(v:Variable(x)):% == monomial(1, 1)
+ coerce(p:%):OutputForm == outputForm(p, outputForm x)$Rep
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category OREPCAT UnivariateSkewPolynomialCategory>>
+<<package APPLYORE ApplyUnivariateSkewPolynomial>>
+<<domain AUTOMOR Automorphism>>
+<<package OREPCTO UnivariateSkewPolynomialCategoryOps>>
+<<domain ORESUP SparseUnivariateSkewPolynomial>>
+<<domain OREUP UnivariateSkewPolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/out.spad.pamphlet b/src/algebra/out.spad.pamphlet
new file mode 100644
index 00000000..19388b78
--- /dev/null
+++ b/src/algebra/out.spad.pamphlet
@@ -0,0 +1,311 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra out.spad}
+\author{Stephen M. Watt, Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package OUT OutputPackage}
+<<package OUT OutputPackage>>=
+)abbrev package OUT OutputPackage
+++ Author: Stephen M. Watt
+++ Date Created: February 1986
+++ Date Last Updated: October 27 1995 (MCD)
+++ Basic Operations: output
+++ Related Constructors: OutputForm
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: OutPackage allows pretty-printing from programs.
+
+OutputPackage: with
+ output: String -> Void
+ ++ output(s) displays the string s on the ``algebra output''
+ ++ stream, as defined by \spadsyscom{set output algebra}.
+ output: OutputForm -> Void
+ ++ output(x) displays the output form x on the
+ ++ ``algebra output'' stream, as defined by
+ ++ \spadsyscom{set output algebra}.
+ output: (String, OutputForm) -> Void
+ ++ output(s,x) displays the string s followed by the form x
+ ++ on the ``algebra output'' stream, as defined by
+ ++ \spadsyscom{set output algebra}.
+ outputList: (List Any) -> Void
+ ++ outputList(l) displays the concatenated components of the
+ ++ list l on the ``algebra output'' stream, as defined by
+ ++ \spadsyscom{set output algebra}; quotes are stripped
+ ++ from strings.
+
+ == add
+ --ExpressionPackage()
+ E ==> OutputForm
+ putout ==> mathprint$Lisp
+
+ s: String
+ e: OutputForm
+ l: List Any
+
+ output e ==
+ mathprint(e)$Lisp
+ void()
+ output s ==
+ output(s:E)
+ output(s,e) ==
+ output blankSeparate [s:E, e]
+ outputList(l) == -- MGR
+ output hconcat
+ [if retractable?(x)$AnyFunctions1(String) then
+ message(retract(x)$AnyFunctions1(String))$OutputForm
+ else
+ x::OutputForm
+ for x in l]
+
+@
+\section{package SPECOUT SpecialOutputPackage}
+<<package SPECOUT SpecialOutputPackage>>=
+)abbrev package SPECOUT SpecialOutputPackage
+++ Author: Stephen M. Watt
+++ Date Created: September 1986
+++ Date Last Updated: May 23, 1991
+++ Basic Operations: outputAsFortran, outputAsScript, outputAsTex
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: SpecialOutputPackage allows FORTRAN, Tex and
+++ Script Formula Formatter output from programs.
+
+SpecialOutputPackage: public == private where
+ public == with
+ outputAsFortran: (String,OutputForm) -> Void
+ ++ outputAsFortran(v,o) sends output v = o in FORTRAN format
+ ++ to the destination defined by \spadsyscom{set output fortran}.
+ outputAsFortran: OutputForm -> Void
+ ++ outputAsFortran(o) sends output o in FORTRAN format.
+ outputAsScript: OutputForm -> Void
+ ++ outputAsScript(o) sends output o in Script Formula Formatter format
+ ++ to the destination defined by \spadsyscom{set output formula}.
+ outputAsTex: OutputForm -> Void
+ ++ outputAsTex(o) sends output o in Tex format to the destination
+ ++ defined by \spadsyscom{set output tex}.
+ outputAsFortran: List OutputForm -> Void
+ ++ outputAsFortran(l) sends (for each expression in the list l)
+ ++ output in FORTRAN format to the destination defined by
+ ++ \spadsyscom{set output fortran}.
+ outputAsScript: List OutputForm -> Void
+ ++ outputAsScript(l) sends (for each expression in the list l)
+ ++ output in Script Formula Formatter format to the destination defined.
+ ++ by \spadsyscom{set output forumula}.
+ outputAsTex: List OutputForm -> Void
+ ++ outputAsTex(l) sends (for each expression in the list l)
+ ++ output in Tex format to the destination as defined by
+ ++ \spadsyscom{set output tex}.
+
+ private == add
+ e : OutputForm
+ l : List OutputForm
+ var : String
+ --ExpressionPackage()
+
+ juxtaposeTerms: List OutputForm -> OutputForm
+ juxtaposeTerms l == blankSeparate l
+
+ outputAsFortran e ==
+ dispfortexp$Lisp e
+ void()$Void
+
+ outputAsFortran(var,e) ==
+ e := var::Symbol::OutputForm = e
+ dispfortexp(e)$Lisp
+ void()$Void
+
+ outputAsFortran l ==
+ dispfortexp$Lisp juxtaposeTerms l
+ void()$Void
+
+ outputAsScript e ==
+ formulaFormat$Lisp e
+ void()$Void
+
+ outputAsScript l ==
+ formulaFormat$Lisp juxtaposeTerms l
+ void()$Void
+
+ outputAsTex e ==
+ texFormat$Lisp e
+ void()$Void
+
+ outputAsTex l ==
+ texFormat$Lisp juxtaposeTerms l
+ void()$Void
+
+@
+\section{package DISPLAY DisplayPackage}
+<<package DISPLAY DisplayPackage>>=
+)abbrev package DISPLAY DisplayPackage
+++ Author: Robert S. Sutor
+++ Date Created: September 1986
+++ Date Last Updated:
+++ Basic Operations: bright, newLine, copies, center, say, sayLength
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: DisplayPackage allows one to print strings in a nice manner,
+++ including highlighting substrings.
+
+DisplayPackage: public == private where
+ I ==> Integer
+ L ==> List
+ S ==> String
+ RECLR ==> Record(lhs : S, rhs : S)
+
+ public == with
+ bright: S -> L S
+ ++ bright(s) sets the font property of the string s to bold-face type.
+ bright: L S -> L S
+ ++ bright(l) sets the font property of a list of strings, l, to
+ ++ bold-face type.
+ newLine: () -> S
+ ++ newLine() sends a new line command to output.
+
+ copies: (I,S) -> S
+ ++ copies(i,s) will take a string s and create a new string composed of
+ ++ i copies of s.
+ center: (S,I,S) -> S
+ ++ center(s,i,s) takes the first string s, and centers it within a string
+ ++ of length i, in which the other elements of the string are composed
+ ++ of as many replications as possible of the second indicated string, s
+ ++ which must have a length greater than that of an empty string.
+ center: (L S,I,S) -> L S
+ ++ center(l,i,s) takes a list of strings l, and centers them within a
+ ++ list of strings which is i characters long, in which the remaining
+ ++ spaces are filled with strings composed of as many repetitions as
+ ++ possible of the last string parameter s.
+
+ say: S -> Void
+ ++ say(s) sends a string s to output.
+ say: L S -> Void
+ ++ say(l) sends a list of strings l to output.
+ sayLength: S -> I
+ ++ sayLength(s) returns the length of a string s as an integer.
+ sayLength: L S -> I
+ ++ sayLength(l) returns the length of a list of strings l as an integer.
+
+ private == add
+ --StringManipulations()
+
+ center0: (I,I,S) -> RECLR
+
+ s : S
+ l : L S
+
+ HION : S := "%b"
+ HIOFF : S := "%d"
+ NEWLINE : S := "%l"
+
+ bright s == [HION,s,HIOFF]$(L S)
+ bright l == cons(HION,append(l,list HIOFF))
+ newLine() == NEWLINE
+
+ copies(n : I, s : S) ==
+ n < 1 => ""
+ n = 1 => s
+ t : S := copies(n quo 2, s)
+ odd? n => concat [s,t,t]
+ concat [t,t]
+
+ center0(len : I, wid : I, fill : S) : RECLR ==
+ (wid < 1) or (len >= wid) => ["",""]$RECLR
+ m : I := (wid - len) quo 2
+ t : S := copies(1 + (m quo (sayLength fill)),fill)
+ [t(1..m),t(1..wid-len-m)]$RECLR
+
+ center(s, wid, fill) ==
+ wid < 1 => ""
+ len : I := sayLength s
+ len = wid => s
+ len > wid => s(1..wid)
+ rec : RECLR := center0(len,wid,fill)
+ concat [rec.lhs,s,rec.rhs]
+
+ center(l, wid, fill) ==
+ wid < 1 => [""]$(L S)
+ len : I := sayLength l
+ len = wid => l
+-- len > wid => s(1..wid)
+ rec : RECLR := center0(len,wid,fill)
+ cons(rec.lhs,append(l,list rec.rhs))
+
+ say s ==
+ sayBrightly$Lisp s
+ void()$Void
+
+ say l ==
+ sayBrightly$Lisp l
+ void()$Void
+
+ sayLength s == #s
+
+ sayLength l ==
+ sum : I := 0
+ for s in l repeat
+ s = HION => sum := sum + 1
+ s = HIOFF => sum := sum + 1
+ s = NEWLINE => sum
+ sum := sum + sayLength s
+ sum
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package OUT OutputPackage>>
+<<package SPECOUT SpecialOutputPackage>>
+<<package DISPLAY DisplayPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/outform.spad.pamphlet b/src/algebra/outform.spad.pamphlet
new file mode 100644
index 00000000..16e65431
--- /dev/null
+++ b/src/algebra/outform.spad.pamphlet
@@ -0,0 +1,964 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra outform.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NUMFMT NumberFormats}
+<<package NUMFMT NumberFormats>>=
+)abbrev package NUMFMT NumberFormats
+++ SMW March 88
+++ Keywords: string manipulation, roman numerals, format
+++ Description:
+++ NumberFormats provides function to format and read arabic and
+++ roman numbers, to convert numbers to strings and to read
+++ floating-point numbers.
+
+NumberFormats(): NFexports == NFimplementation where
+ PI ==> PositiveInteger
+ I ==> Integer
+ C ==> Character
+ F ==> Float
+ S ==> String
+ V ==> PrimitiveArray
+
+ NFexports ==> with
+ FormatArabic: PI -> S
+ ++ FormatArabic(n) forms an Arabic numeral
+ ++ string from an integer n.
+ ScanArabic: S -> PI
+ ++ ScanArabic(s) forms an integer from an Arabic numeral string s.
+ FormatRoman: PI -> S
+ ++ FormatRoman(n) forms a Roman numeral string from an integer n.
+ ScanRoman: S -> PI
+ ++ ScanRoman(s) forms an integer from a Roman numeral string s.
+ ScanFloatIgnoreSpaces: S -> F
+ ++ ScanFloatIgnoreSpaces(s) forms a floating point number from
+ ++ the string s ignoring any spaces. Error is generated if the
+ ++ string is not recognised as a floating point number.
+ ScanFloatIgnoreSpacesIfCan: S -> Union(F, "failed")
+ ++ ScanFloatIgnoreSpacesIfCan(s) tries to form a floating point number from
+ ++ the string s ignoring any spaces.
+
+
+ NFimplementation ==> add
+ import SExpression
+ import Symbol
+ replaceD: C -> C
+ replaced: C -> C
+ contract: S -> S
+ check: S ->Boolean
+ replaceD c ==
+ if c = char "D" then char "E" else c
+ replaced c ==
+ if c = char "d" then char "E" else c
+ contract s ==
+ s:= map(replaceD,s)
+ s:= map(replaced,s)
+ ls:List S := split(s,char " ")$String
+ s:= concat ls
+ check s ==
+ NUMBERP(READ_-FROM_-STRING(s)$Lisp)$Lisp and
+ -- if there is an "E" then there must be a "."
+ -- this is not caught by code above
+ -- also if the exponent is v.big the above returns false
+ not (any?(#1=char "E",s) and not any?(#1=char ".",s) )
+
+-- Original interpreter function:
+-- )lis (defun scanstr(x) (spadcomp::|parseFromString| x))
+ sexfloat:SExpression:=convert(coerce("Float")@Symbol)$SExpression
+ ScanFloatIgnoreSpaces s ==
+ s := contract s
+ not check s => error "Non-numeric value"
+ sex := interpret(packageTran(ncParseFromString(s)$Lisp)$Lisp)$Lisp
+ sCheck := car(car(sex))
+ if (sCheck=sexfloat) = true then
+ f := (cdr cdr sex) pretend Float
+ else
+ if integer?(cdr sex) = true then
+ f := (cdr sex) pretend Integer
+ f::F
+ else
+ error "Non-numeric value"
+
+ ScanFloatIgnoreSpacesIfCan s ==
+ s := contract s
+ not check s => "failed"
+ sex := interpret(packageTran(ncParseFromString(s)$Lisp)$Lisp)$Lisp
+ sCheck := car(car(sex))
+ if (sCheck=sexfloat) = true then
+ f := (cdr cdr sex) pretend Float
+ else
+ if integer?(cdr sex) = true then
+ f := (cdr sex) pretend Integer
+ f::F
+ else
+ "failed"
+
+ units:V S :=
+ construct ["","I","II","III","IV","V","VI","VII","VIII","IX"]
+ tens :V S :=
+ construct ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"]
+ hunds:V S :=
+ construct ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]
+ umin := minIndex units
+ tmin := minIndex tens
+ hmin := minIndex hunds
+ romval:V I := new(256, -1)
+ romval ord char(" ")$C := 0
+ romval ord char("I")$C := 1
+ romval ord char("V")$C := 5
+ romval ord char("X")$C := 10
+ romval ord char("L")$C := 50
+ romval ord char("C")$C := 100
+ romval ord char("D")$C := 500
+ romval ord char("M")$C := 1000
+ thou:C := char "M"
+ plen:C := char "("
+ pren:C := char ")"
+ ichar:C := char "I"
+
+ FormatArabic n == STRINGIMAGE(n)$Lisp
+ ScanArabic s == PARSE_-INTEGER(s)$Lisp
+
+ FormatRoman pn ==
+ n := pn::Integer
+ -- Units
+ d := (n rem 10) + umin
+ n := n quo 10
+ s := units.d
+ zero? n => s
+ -- Tens
+ d := (n rem 10) + tmin
+ n := n quo 10
+ s := concat(tens.d, s)
+ zero? n => s
+ -- Hundreds
+ d := (n rem 10) + hmin
+ n := n quo 10
+ s := concat(hunds.d, s)
+ zero? n => s
+ -- Thousands
+ d := n rem 10
+ n := n quo 10
+ s := concat(new(d::NonNegativeInteger, thou), s)
+ zero? n => s
+ -- Ten thousand and higher
+ for i in 2.. while not zero? n repeat
+ -- Coefficient of 10**(i+2)
+ d := n rem 10
+ n := n quo 10
+ zero? d => "iterate"
+ m0:String := concat(new(i,plen),concat("I",new(i,pren)))
+ mm := concat([m0 for j in 1..d]$List(String))
+ -- strictly speaking the blank is gratuitous
+ if #s > 0 then s := concat(" ", s)
+ s := concat(mm, s)
+ s
+
+ -- ScanRoman
+ --
+ -- The Algorithm:
+ -- Read number from right to left. When the current
+ -- numeral is lower in magnitude than the previous maximum
+ -- then subtract otherwise add.
+ -- Shift left and repeat until done.
+
+ ScanRoman s ==
+ s := upperCase s
+ tot: I := 0
+ Max: I := 0
+ i: I := maxIndex s
+ while i >= minIndex s repeat
+ -- Read a single roman digit
+ c := s.i; i := i-1
+ n := romval ord c
+ -- (I)=1000, ((I))=10000, (((I)))=100000, etc
+ if n < 0 then
+ c ^= pren =>
+ error ["Improper character in Roman numeral: ",c]
+ nprens: PI := 1
+ while c = pren and i >= minIndex s repeat
+ c := s.i; i := i-1
+ if c = pren then nprens := nprens+1
+ c ^= ichar =>
+ error "Improper Roman numeral: (x)"
+ for k in 1..nprens while i >= minIndex s repeat
+ c := s.i; i := i-1
+ c ^= plen =>
+ error "Improper Roman numeral: unbalanced ')'"
+ n := 10**(nprens + 2)
+ if n < Max then
+ tot := tot - n
+ else
+ tot := tot + n
+ Max := n
+ tot < 0 => error ["Improper Roman numeral: ", tot]
+ tot::PI
+
+@
+\section{domain OUTFORM OutputForm}
+<<domain OUTFORM OutputForm>>=
+)abbrev domain OUTFORM OutputForm
+++ Keywords: output, I/O, expression
+++ SMW March/88
+++ Description:
+++ This domain is used to create and manipulate mathematical expressions
+++ for output. It is intended to provide an insulating layer between
+++ the expression rendering software (e.g.FORTRAN, TeX, or Script) and
+++ the output coercions in the various domains.
+
+OutputForm(): SetCategory with
+ --% Printing
+ print : $ -> Void
+ ++ print(u) prints the form u.
+ message: String -> $
+ ++ message(s) creates an form with no string quotes
+ ++ from string s.
+ messagePrint: String -> Void
+ ++ messagePrint(s) prints s without string quotes. Note:
+ ++ \spad{messagePrint(s)} is equivalent to \spad{print message(s)}.
+ --% Creation of atomic forms
+ outputForm: Integer -> $
+ ++ outputForm(n) creates an form for integer n.
+ outputForm: Symbol -> $
+ ++ outputForm(s) creates an form for symbol s.
+ outputForm: String -> $
+ ++ outputForm(s) creates an form for string s.
+ outputForm: DoubleFloat -> $
+ ++ outputForm(sf) creates an form for small float sf.
+ empty : () -> $
+ ++ empty() creates an empty form.
+
+ --% Sizings
+ width: $ -> Integer
+ ++ width(f) returns the width of form f (an integer).
+ height: $ -> Integer
+ ++ height(f) returns the height of form f (an integer).
+ width: -> Integer
+ ++ width() returns the width of the display area (an integer).
+ height: -> Integer
+ ++ height() returns the height of the display area (an integer).
+ subHeight: $ -> Integer
+ ++ subHeight(f) returns the height of form f below the base line.
+ superHeight: $ -> Integer
+ ++ superHeight(f) returns the height of form f above the base line.
+ --% Space manipulations
+ hspace: Integer -> $ ++ hspace(n) creates white space of width n.
+ vspace: Integer -> $ ++ vspace(n) creates white space of height n.
+ rspace: (Integer,Integer) -> $
+ ++ rspace(n,m) creates rectangular white space, n wide by m high.
+ --% Area adjustments
+ left: ($,Integer) -> $
+ ++ left(f,n) left-justifies form f within space of width n.
+ right: ($,Integer) -> $
+ ++ right(f,n) right-justifies form f within space of width n.
+ center: ($,Integer) -> $
+ ++ center(f,n) centers form f within space of width n.
+ left: $ -> $
+ ++ left(f) left-justifies form f in total space.
+ right: $ -> $
+ ++ right(f) right-justifies form f in total space.
+ center: $ -> $
+ ++ center(f) centers form f in total space.
+
+ --% Area manipulations
+ hconcat: ($,$) -> $
+ ++ hconcat(f,g) horizontally concatenate forms f and g.
+ vconcat: ($,$) -> $
+ ++ vconcat(f,g) vertically concatenates forms f and g.
+ hconcat: List $ -> $
+ ++ hconcat(u) horizontally concatenates all forms in list u.
+ vconcat: List $ -> $
+ ++ vconcat(u) vertically concatenates all forms in list u.
+
+ --% Application formers
+ prefix: ($, List $) -> $
+ ++ prefix(f,l) creates a form depicting the n-ary prefix
+ ++ application of f to a tuple of arguments given by list l.
+ infix: ($, List $) -> $
+ ++ infix(f,l) creates a form depicting the n-ary application
+ ++ of infix operation f to a tuple of arguments l.
+ infix: ($, $, $) -> $
+ ++ infix(op, a, b) creates a form which prints as: a op b.
+ postfix: ($, $) -> $
+ ++ postfix(op, a) creates a form which prints as: a op.
+ infix?: $ -> Boolean
+ ++ infix?(op) returns true if op is an infix operator,
+ ++ and false otherwise.
+ elt: ($, List $) -> $
+ ++ elt(op,l) creates a form for application of op
+ ++ to list of arguments l.
+
+ --% Special forms
+ string: $ -> $
+ ++ string(f) creates f with string quotes.
+ label: ($, $) -> $
+ ++ label(n,f) gives form f an equation label n.
+ box: $ -> $
+ ++ box(f) encloses f in a box.
+ matrix: List List $ -> $
+ ++ matrix(llf) makes llf (a list of lists of forms) into
+ ++ a form which displays as a matrix.
+ zag: ($, $) -> $
+ ++ zag(f,g) creates a form for the continued fraction form for f over g.
+ root: $ -> $
+ ++ root(f) creates a form for the square root of form f.
+ root: ($, $) -> $
+ ++ root(f,n) creates a form for the nth root of form f.
+ over: ($, $) -> $
+ ++ over(f,g) creates a form for the vertical fraction of f over g.
+ slash: ($, $) -> $
+ ++ slash(f,g) creates a form for the horizontal fraction of f over g.
+ assign: ($, $) -> $
+ ++ assign(f,g) creates a form for the assignment \spad{f := g}.
+ rarrow: ($, $) -> $
+ ++ rarrow(f,g) creates a form for the mapping \spad{f -> g}.
+ differentiate: ($, NonNegativeInteger) -> $
+ ++ differentiate(f,n) creates a form for the nth derivative of f,
+ ++ e.g. \spad{f'}, \spad{f''}, \spad{f'''},
+ ++ "f super \spad{iv}".
+ binomial: ($, $) -> $
+ ++ binomial(n,m) creates a form for the binomial coefficient of n and m.
+
+ --% Scripts
+ sub: ($, $) -> $
+ ++ sub(f,n) creates a form for f subscripted by n.
+ super: ($, $) -> $
+ ++ super(f,n) creates a form for f superscripted by n.
+ presub: ($, $) -> $
+ ++ presub(f,n) creates a form for f presubscripted by n.
+ presuper:($, $) -> $
+ ++ presuper(f,n) creates a form for f presuperscripted by n.
+ scripts: ($, List $) -> $
+ ++ \spad{scripts(f, [sub, super, presuper, presub])}
+ ++ creates a form for f with scripts on all 4 corners.
+ supersub:($, List $) -> $
+ ++ supersub(a,[sub1,super1,sub2,super2,...])
+ ++ creates a form with each subscript aligned
+ ++ under each superscript.
+
+ --% Diacritical marks
+ quote: $ -> $
+ ++ quote(f) creates the form f with a prefix quote.
+ dot: $ -> $
+ ++ dot(f) creates the form with a one dot overhead.
+ dot: ($, NonNegativeInteger) -> $
+ ++ dot(f,n) creates the form f with n dots overhead.
+ prime: $ -> $
+ ++ prime(f) creates the form f followed by a suffix prime (single quote).
+ prime: ($, NonNegativeInteger) -> $
+ ++ prime(f,n) creates the form f followed by n primes.
+ overbar: $ -> $
+ ++ overbar(f) creates the form f with an overbar.
+ overlabel: ($, $) -> $
+ ++ overlabel(x,f) creates the form f with "x overbar" over the top.
+
+ --% Plexes
+ sum: ($) -> $
+ ++ sum(expr) creates the form prefixing expr by a capital sigma.
+ sum: ($, $) -> $
+ ++ sum(expr,lowerlimit) creates the form prefixing expr by
+ ++ a capital sigma with a lowerlimit.
+ sum: ($, $, $) -> $
+ ++ sum(expr,lowerlimit,upperlimit) creates the form prefixing expr by
+ ++ a capital sigma with both a lowerlimit and upperlimit.
+ prod: ($) -> $
+ ++ prod(expr) creates the form prefixing expr by a capital pi.
+ prod: ($, $) -> $
+ ++ prod(expr,lowerlimit) creates the form prefixing expr by
+ ++ a capital pi with a lowerlimit.
+ prod: ($, $, $) -> $
+ ++ prod(expr,lowerlimit,upperlimit) creates the form prefixing expr by
+ ++ a capital pi with both a lowerlimit and upperlimit.
+ int: ($) -> $
+ ++ int(expr) creates the form prefixing expr with an integral sign.
+ int: ($, $) -> $
+ ++ int(expr,lowerlimit) creates the form prefixing expr by an
+ ++ integral sign with a lowerlimit.
+ int: ($, $, $) -> $
+ ++ int(expr,lowerlimit,upperlimit) creates the form prefixing expr by
+ ++ an integral sign with both a lowerlimit and upperlimit.
+
+ --% Matchfix forms
+ brace: $ -> $
+ ++ brace(f) creates the form enclosing f in braces (curly brackets).
+ brace: List $ -> $
+ ++ brace(lf) creates the form separating the elements of lf
+ ++ by commas and encloses the result in curly brackets.
+ bracket: $ -> $
+ ++ bracket(f) creates the form enclosing f in square brackets.
+ bracket: List $ -> $
+ ++ bracket(lf) creates the form separating the elements of lf
+ ++ by commas and encloses the result in square brackets.
+ paren: $ -> $
+ ++ paren(f) creates the form enclosing f in parentheses.
+ paren: List $ -> $
+ ++ paren(lf) creates the form separating the elements of lf
+ ++ by commas and encloses the result in parentheses.
+
+ --% Separators for aggregates
+ pile: List $ -> $
+ ++ pile(l) creates the form consisting of the elements of l which
+ ++ displays as a pile, i.e. the elements begin on a new line and
+ ++ are indented right to the same margin.
+
+ commaSeparate: List $ -> $
+ ++ commaSeparate(l) creates the form separating the elements of l
+ ++ by commas.
+ semicolonSeparate: List $ -> $
+ ++ semicolonSeparate(l) creates the form separating the elements of l
+ ++ by semicolons.
+ blankSeparate: List $ -> $
+ ++ blankSeparate(l) creates the form separating the elements of l
+ ++ by blanks.
+ --% Specific applications
+ "=": ($, $) -> $
+ ++ f = g creates the equivalent infix form.
+ "^=": ($, $) -> $
+ ++ f ^= g creates the equivalent infix form.
+ "<": ($, $) -> $
+ ++ f < g creates the equivalent infix form.
+ ">": ($, $) -> $
+ ++ f > g creates the equivalent infix form.
+ "<=": ($, $) -> $
+ ++ f <= g creates the equivalent infix form.
+ ">=": ($, $) -> $
+ ++ f >= g creates the equivalent infix form.
+ "+": ($, $) -> $
+ ++ f + g creates the equivalent infix form.
+ "-": ($, $) -> $
+ ++ f - g creates the equivalent infix form.
+ "-": ($) -> $
+ ++ - f creates the equivalent prefix form.
+ "*": ($, $) -> $
+ ++ f * g creates the equivalent infix form.
+ "/": ($, $) -> $
+ ++ f / g creates the equivalent infix form.
+ "**": ($, $) -> $
+ ++ f ** g creates the equivalent infix form.
+ "div": ($, $) -> $
+ ++ f div g creates the equivalent infix form.
+ "rem": ($, $) -> $
+ ++ f rem g creates the equivalent infix form.
+ "quo": ($, $) -> $
+ ++ f quo g creates the equivalent infix form.
+ "exquo": ($, $) -> $
+ ++ exquo(f,g) creates the equivalent infix form.
+ "and": ($, $) -> $
+ ++ f and g creates the equivalent infix form.
+ "or": ($, $) -> $
+ ++ f or g creates the equivalent infix form.
+ "not": ($) -> $
+ ++ not f creates the equivalent prefix form.
+ SEGMENT: ($,$) -> $
+ ++ SEGMENT(x,y) creates the infix form: \spad{x..y}.
+ SEGMENT: ($) -> $
+ ++ SEGMENT(x) creates the prefix form: \spad{x..}.
+
+ == add
+ import NumberFormats
+
+ -- Todo:
+ -- program forms, greek letters
+ -- infix, prefix, postfix, matchfix support in OUT BOOT
+ -- labove rabove, corresponding overs.
+ -- better super script, overmark, undermark
+ -- bug in product, paren blankSeparate []
+ -- uniformize integrals, products, etc as plexes.
+
+ cons ==> CONS$Lisp
+ car ==> CAR$Lisp
+ cdr ==> CDR$Lisp
+
+ Rep := List $
+
+ a, b: $
+ l: List $
+ s: String
+ e: Symbol
+ n: Integer
+ nn:NonNegativeInteger
+
+ sform: String -> $
+ eform: Symbol -> $
+ iform: Integer -> $
+
+ print x == mathprint(x)$Lisp
+ message s == (empty? s => empty(); s pretend $)
+ messagePrint s == print message s
+ (a:$ = b:$):Boolean == EQUAL(a, b)$Lisp
+ (a:$ = b:$):$ == [sform "=", a, b]
+ coerce(a):OutputForm == a pretend OutputForm
+ outputForm n == n pretend $
+ outputForm e == e pretend $
+ outputForm(f:DoubleFloat) == f pretend $
+ sform s == s pretend $
+ eform e == e pretend $
+ iform n == n pretend $
+
+ outputForm s ==
+ sform concat(quote()$Character, concat(s, quote()$Character))
+
+ width(a) == outformWidth(a)$Lisp
+ height(a) == height(a)$Lisp
+ subHeight(a) == subspan(a)$Lisp
+ superHeight(a) == superspan(a)$Lisp
+ height() == 20
+ width() == 66
+
+ center(a,w) == hconcat(hspace((w - width(a)) quo 2),a)
+ left(a,w) == hconcat(a,hspace((w - width(a))))
+ right(a,w) == hconcat(hspace(w - width(a)),a)
+ center(a) == center(a,width())
+ left(a) == left(a,width())
+ right(a) == right(a,width())
+
+ vspace(n) ==
+ n = 0 => empty()
+ vconcat(sform " ",vspace(n - 1))
+
+ hspace(n) ==
+ n = 0 => empty()
+ sform(fillerSpaces(n)$Lisp)
+
+ rspace(n, m) ==
+ n = 0 or m = 0 => empty()
+ vconcat(hspace n, rspace(n, m - 1))
+
+ matrix ll ==
+ lv:$ := [LIST2VEC$Lisp l for l in ll]
+ CONS(eform MATRIX, LIST2VEC$Lisp lv)$Lisp
+
+ pile l == cons(eform SC, l)
+ commaSeparate l == cons(eform AGGLST, l)
+ semicolonSeparate l == cons(eform AGGSET, l)
+ blankSeparate l ==
+ c:=eform CONCATB
+ l1:$:=[]
+ for u in reverse l repeat
+ if EQCAR(u,c)$Lisp
+ then l1:=[:cdr u,:l1]
+ else l1:=[u,:l1]
+ cons(c, l1)
+
+ brace a == [eform BRACE, a]
+ brace l == brace commaSeparate l
+ bracket a == [eform BRACKET, a]
+ bracket l == bracket commaSeparate l
+ paren a == [eform PAREN, a]
+ paren l == paren commaSeparate l
+
+ sub (a,b) == [eform SUB, a, b]
+ super (a, b) == [eform SUPERSUB,a,sform " ",b]
+ presub(a,b) == [eform SUPERSUB,a,sform " ",sform " ",sform " ",b]
+ presuper(a, b) == [eform SUPERSUB,a,sform " ",sform " ",b]
+ scripts (a, l) ==
+ null l => a
+ null rest l => sub(a, first l)
+ cons(eform SUPERSUB, cons(a, l))
+ supersub(a, l) ==
+ if odd?(#l) then l := append(l, [empty()])
+ cons(eform ALTSUPERSUB, cons(a, l))
+
+ hconcat(a,b) == [eform CONCAT, a, b]
+ hconcat l == cons(eform CONCAT, l)
+ vconcat(a,b) == [eform VCONCAT, a, b]
+ vconcat l == cons(eform VCONCAT, l)
+
+ a ^= b == [sform "^=", a, b]
+ a < b == [sform "<", a, b]
+ a > b == [sform ">", a, b]
+ a <= b == [sform "<=", a, b]
+ a >= b == [sform ">=", a, b]
+
+ a + b == [sform "+", a, b]
+ a - b == [sform "-", a, b]
+ - a == [sform "-", a]
+ a * b == [sform "*", a, b]
+ a / b == [sform "/", a, b]
+ a ** b == [sform "**", a, b]
+ a div b == [sform "div", a, b]
+ a rem b == [sform "rem", a, b]
+ a quo b == [sform "quo", a, b]
+ a exquo b == [sform "exquo", a, b]
+ a and b == [sform "and", a, b]
+ a or b == [sform "or", a, b]
+ not a == [sform "not", a]
+ SEGMENT(a,b)== [eform SEGMENT, a, b]
+ SEGMENT(a) == [eform SEGMENT, a]
+ binomial(a,b)==[eform BINOMIAL, a, b]
+
+ empty() == [eform NOTHING]
+
+ infix? a ==
+ e:$ :=
+ IDENTP$Lisp a => a
+ STRINGP$Lisp a => INTERN$Lisp a
+ return false
+ if GET(e,QUOTE(INFIXOP$Lisp)$Lisp)$Lisp then true else false
+
+ elt(a, l) ==
+ cons(a, l)
+ prefix(a,l) ==
+ not infix? a => cons(a, l)
+ hconcat(a, paren commaSeparate l)
+ infix(a, l) ==
+ null l => empty()
+ null rest l => first l
+ infix? a => cons(a, l)
+ hconcat [first l, a, infix(a, rest l)]
+ infix(a,b,c) ==
+ infix? a => [a, b, c]
+ hconcat [b, a, c]
+ postfix(a, b) ==
+ hconcat(b, a)
+
+ string a == [eform STRING, a]
+ quote a == [eform QUOTE, a]
+ overbar a == [eform OVERBAR, a]
+ dot a == super(a, sform ".")
+ prime a == super(a, sform ",")
+ dot(a,nn) == (s := new(nn, char "."); super(a, sform s))
+ prime(a,nn) == (s := new(nn, char ","); super(a, sform s))
+
+ overlabel(a,b) == [eform OVERLABEL, a, b]
+ box a == [eform BOX, a]
+ zag(a,b) == [eform ZAG, a, b]
+ root a == [eform ROOT, a]
+ root(a,b) == [eform ROOT, a, b]
+ over(a,b) == [eform OVER, a, b]
+ slash(a,b) == [eform SLASH, a, b]
+ assign(a,b)== [eform LET, a, b]
+
+ label(a,b) == [eform EQUATNUM, a, b]
+ rarrow(a,b)== [eform TAG, a, b]
+ differentiate(a, nn)==
+ zero? nn => a
+ nn < 4 => prime(a, nn)
+ r := FormatRoman(nn::PositiveInteger)
+ s := lowerCase(r::String)
+ super(a, paren sform s)
+
+ sum(a) == [eform SIGMA, empty(), a]
+ sum(a,b) == [eform SIGMA, b, a]
+ sum(a,b,c) == [eform SIGMA2, b, c, a]
+ prod(a) == [eform PI, empty(), a]
+ prod(a,b) == [eform PI, b, a]
+ prod(a,b,c)== [eform PI2, b, c, a]
+ int(a) == [eform INTSIGN,empty(), empty(), a]
+ int(a,b) == [eform INTSIGN,b, empty(), a]
+ int(a,b,c) == [eform INTSIGN,b, c, a]
+
+@
+\section{OUTFORM.lsp BOOTSTRAP}
+{\bf OUTFORM} depends on itself.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf OUTFORM} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf OUTFORM.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<OUTFORM.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |OUTFORM;print;$V;1|) (QUOTE |SPADreplace|) (QUOTE |mathprint|))
+
+(DEFUN |OUTFORM;print;$V;1| (|x| |$|) (|mathprint| |x|))
+
+(DEFUN |OUTFORM;message;S$;2| (|s| |$|) (COND ((SPADCALL |s| (QREFELT |$| 11)) (SPADCALL (QREFELT |$| 12))) ((QUOTE T) |s|)))
+
+(DEFUN |OUTFORM;messagePrint;SV;3| (|s| |$|) (SPADCALL (SPADCALL |s| (QREFELT |$| 13)) (QREFELT |$| 8)))
+
+(PUT (QUOTE |OUTFORM;=;2$B;4|) (QUOTE |SPADreplace|) (QUOTE EQUAL))
+
+(DEFUN |OUTFORM;=;2$B;4| (|a| |b| |$|) (EQUAL |a| |b|))
+
+(DEFUN |OUTFORM;=;3$;5| (|a| |b| |$|) (LIST (|OUTFORM;sform| "=" |$|) |a| |b|))
+
+(PUT (QUOTE |OUTFORM;coerce;2$;6|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|a|) |a|)))
+
+(DEFUN |OUTFORM;coerce;2$;6| (|a| |$|) |a|)
+
+(PUT (QUOTE |OUTFORM;outputForm;I$;7|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|n|) |n|)))
+
+(DEFUN |OUTFORM;outputForm;I$;7| (|n| |$|) |n|)
+
+(PUT (QUOTE |OUTFORM;outputForm;S$;8|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|e|) |e|)))
+
+(DEFUN |OUTFORM;outputForm;S$;8| (|e| |$|) |e|)
+
+(PUT (QUOTE |OUTFORM;outputForm;Df$;9|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|f|) |f|)))
+
+(DEFUN |OUTFORM;outputForm;Df$;9| (|f| |$|) |f|)
+
+(PUT (QUOTE |OUTFORM;sform|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|s|) |s|)))
+
+(DEFUN |OUTFORM;sform| (|s| |$|) |s|)
+
+(PUT (QUOTE |OUTFORM;eform|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|e|) |e|)))
+
+(DEFUN |OUTFORM;eform| (|e| |$|) |e|)
+
+(PUT (QUOTE |OUTFORM;iform|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|n|) |n|)))
+
+(DEFUN |OUTFORM;iform| (|n| |$|) |n|)
+
+(DEFUN |OUTFORM;outputForm;S$;13| (|s| |$|) (|OUTFORM;sform| (SPADCALL (SPADCALL (QREFELT |$| 26)) (SPADCALL |s| (SPADCALL (QREFELT |$| 26)) (QREFELT |$| 27)) (QREFELT |$| 28)) |$|))
+
+(PUT (QUOTE |OUTFORM;width;$I;14|) (QUOTE |SPADreplace|) (QUOTE |outformWidth|))
+
+(DEFUN |OUTFORM;width;$I;14| (|a| |$|) (|outformWidth| |a|))
+
+(PUT (QUOTE |OUTFORM;height;$I;15|) (QUOTE |SPADreplace|) (QUOTE |height|))
+
+(DEFUN |OUTFORM;height;$I;15| (|a| |$|) (|height| |a|))
+
+(PUT (QUOTE |OUTFORM;subHeight;$I;16|) (QUOTE |SPADreplace|) (QUOTE |subspan|))
+
+(DEFUN |OUTFORM;subHeight;$I;16| (|a| |$|) (|subspan| |a|))
+
+(PUT (QUOTE |OUTFORM;superHeight;$I;17|) (QUOTE |SPADreplace|) (QUOTE |superspan|))
+
+(DEFUN |OUTFORM;superHeight;$I;17| (|a| |$|) (|superspan| |a|))
+
+(PUT (QUOTE |OUTFORM;height;I;18|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL 20)))
+
+(DEFUN |OUTFORM;height;I;18| (|$|) 20)
+
+(PUT (QUOTE |OUTFORM;width;I;19|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL 66)))
+
+(DEFUN |OUTFORM;width;I;19| (|$|) 66)
+
+(DEFUN |OUTFORM;center;$I$;20| (|a| |w| |$|) (SPADCALL (SPADCALL (QUOTIENT2 (|-| |w| (SPADCALL |a| (QREFELT |$| 30))) 2) (QREFELT |$| 36)) |a| (QREFELT |$| 37)))
+
+(DEFUN |OUTFORM;left;$I$;21| (|a| |w| |$|) (SPADCALL |a| (SPADCALL (|-| |w| (SPADCALL |a| (QREFELT |$| 30))) (QREFELT |$| 36)) (QREFELT |$| 37)))
+
+(DEFUN |OUTFORM;right;$I$;22| (|a| |w| |$|) (SPADCALL (SPADCALL (|-| |w| (SPADCALL |a| (QREFELT |$| 30))) (QREFELT |$| 36)) |a| (QREFELT |$| 37)))
+
+(DEFUN |OUTFORM;center;2$;23| (|a| |$|) (SPADCALL |a| (SPADCALL (QREFELT |$| 35)) (QREFELT |$| 38)))
+
+(DEFUN |OUTFORM;left;2$;24| (|a| |$|) (SPADCALL |a| (SPADCALL (QREFELT |$| 35)) (QREFELT |$| 39)))
+
+(DEFUN |OUTFORM;right;2$;25| (|a| |$|) (SPADCALL |a| (SPADCALL (QREFELT |$| 35)) (QREFELT |$| 40)))
+
+(DEFUN |OUTFORM;vspace;I$;26| (|n| |$|) (COND ((EQL |n| 0) (SPADCALL (QREFELT |$| 12))) ((QUOTE T) (SPADCALL (|OUTFORM;sform| " " |$|) (SPADCALL (|-| |n| 1) (QREFELT |$| 44)) (QREFELT |$| 45)))))
+
+(DEFUN |OUTFORM;hspace;I$;27| (|n| |$|) (COND ((EQL |n| 0) (SPADCALL (QREFELT |$| 12))) ((QUOTE T) (|OUTFORM;sform| (|fillerSpaces| |n|) |$|))))
+
+(DEFUN |OUTFORM;rspace;2I$;28| (|n| |m| |$|) (COND ((OR (EQL |n| 0) (EQL |m| 0)) (SPADCALL (QREFELT |$| 12))) ((QUOTE T) (SPADCALL (SPADCALL |n| (QREFELT |$| 36)) (SPADCALL |n| (|-| |m| 1) (QREFELT |$| 46)) (QREFELT |$| 45)))))
+
+(DEFUN |OUTFORM;matrix;L$;29| (|ll| |$|) (PROG (#1=#:G82748 |l| #2=#:G82749 |lv|) (RETURN (SEQ (LETT |lv| (PROGN (LETT #1# NIL |OUTFORM;matrix;L$;29|) (SEQ (LETT |l| NIL |OUTFORM;matrix;L$;29|) (LETT #2# |ll| |OUTFORM;matrix;L$;29|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |l| (CAR #2#) |OUTFORM;matrix;L$;29|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (LIST2VEC |l|) #1#) |OUTFORM;matrix;L$;29|))) (LETT #2# (CDR #2#) |OUTFORM;matrix;L$;29|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |OUTFORM;matrix;L$;29|) (EXIT (CONS (|OUTFORM;eform| (QUOTE MATRIX) |$|) (LIST2VEC |lv|)))))))
+
+(DEFUN |OUTFORM;pile;L$;30| (|l| |$|) (CONS (|OUTFORM;eform| (QUOTE SC) |$|) |l|))
+
+(DEFUN |OUTFORM;commaSeparate;L$;31| (|l| |$|) (CONS (|OUTFORM;eform| (QUOTE AGGLST) |$|) |l|))
+
+(DEFUN |OUTFORM;semicolonSeparate;L$;32| (|l| |$|) (CONS (|OUTFORM;eform| (QUOTE AGGSET) |$|) |l|))
+
+(DEFUN |OUTFORM;blankSeparate;L$;33| (|l| |$|) (PROG (|c| |u| #1=#:G82757 |l1|) (RETURN (SEQ (LETT |c| (|OUTFORM;eform| (QUOTE CONCATB) |$|) |OUTFORM;blankSeparate;L$;33|) (LETT |l1| NIL |OUTFORM;blankSeparate;L$;33|) (SEQ (LETT |u| NIL |OUTFORM;blankSeparate;L$;33|) (LETT #1# (SPADCALL |l| (QREFELT |$| 53)) |OUTFORM;blankSeparate;L$;33|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |u| (CAR #1#) |OUTFORM;blankSeparate;L$;33|) NIL)) (GO G191))) (SEQ (EXIT (COND ((EQCAR |u| |c|) (LETT |l1| (SPADCALL (CDR |u|) |l1| (QREFELT |$| 54)) |OUTFORM;blankSeparate;L$;33|)) ((QUOTE T) (LETT |l1| (CONS |u| |l1|) |OUTFORM;blankSeparate;L$;33|))))) (LETT #1# (CDR #1#) |OUTFORM;blankSeparate;L$;33|) (GO G190) G191 (EXIT NIL)) (EXIT (CONS |c| |l1|))))))
+
+(DEFUN |OUTFORM;brace;2$;34| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE BRACE) |$|) |a|))
+
+(DEFUN |OUTFORM;brace;L$;35| (|l| |$|) (SPADCALL (SPADCALL |l| (QREFELT |$| 51)) (QREFELT |$| 56)))
+
+(DEFUN |OUTFORM;bracket;2$;36| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE BRACKET) |$|) |a|))
+
+(DEFUN |OUTFORM;bracket;L$;37| (|l| |$|) (SPADCALL (SPADCALL |l| (QREFELT |$| 51)) (QREFELT |$| 58)))
+
+(DEFUN |OUTFORM;paren;2$;38| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE PAREN) |$|) |a|))
+
+(DEFUN |OUTFORM;paren;L$;39| (|l| |$|) (SPADCALL (SPADCALL |l| (QREFELT |$| 51)) (QREFELT |$| 60)))
+
+(DEFUN |OUTFORM;sub;3$;40| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SUB) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;super;3$;41| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SUPERSUB) |$|) |a| (|OUTFORM;sform| " " |$|) |b|))
+
+(DEFUN |OUTFORM;presub;3$;42| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SUPERSUB) |$|) |a| (|OUTFORM;sform| " " |$|) (|OUTFORM;sform| " " |$|) (|OUTFORM;sform| " " |$|) |b|))
+
+(DEFUN |OUTFORM;presuper;3$;43| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SUPERSUB) |$|) |a| (|OUTFORM;sform| " " |$|) (|OUTFORM;sform| " " |$|) |b|))
+
+(DEFUN |OUTFORM;scripts;$L$;44| (|a| |l| |$|) (COND ((SPADCALL |l| (QREFELT |$| 66)) |a|) ((SPADCALL (SPADCALL |l| (QREFELT |$| 67)) (QREFELT |$| 66)) (SPADCALL |a| (SPADCALL |l| (QREFELT |$| 68)) (QREFELT |$| 62))) ((QUOTE T) (CONS (|OUTFORM;eform| (QUOTE SUPERSUB) |$|) (CONS |a| |l|)))))
+
+(DEFUN |OUTFORM;supersub;$L$;45| (|a| |l| |$|) (SEQ (COND ((ODDP (SPADCALL |l| (QREFELT |$| 71))) (LETT |l| (SPADCALL |l| (LIST (SPADCALL (QREFELT |$| 12))) (QREFELT |$| 73)) |OUTFORM;supersub;$L$;45|))) (EXIT (CONS (|OUTFORM;eform| (QUOTE ALTSUPERSUB) |$|) (CONS |a| |l|)))))
+
+(DEFUN |OUTFORM;hconcat;3$;46| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE CONCAT) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;hconcat;L$;47| (|l| |$|) (CONS (|OUTFORM;eform| (QUOTE CONCAT) |$|) |l|))
+
+(DEFUN |OUTFORM;vconcat;3$;48| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE VCONCAT) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;vconcat;L$;49| (|l| |$|) (CONS (|OUTFORM;eform| (QUOTE VCONCAT) |$|) |l|))
+
+(DEFUN |OUTFORM;^=;3$;50| (|a| |b| |$|) (LIST (|OUTFORM;sform| "^=" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;<;3$;51| (|a| |b| |$|) (LIST (|OUTFORM;sform| "<" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;>;3$;52| (|a| |b| |$|) (LIST (|OUTFORM;sform| ">" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;<=;3$;53| (|a| |b| |$|) (LIST (|OUTFORM;sform| "<=" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;>=;3$;54| (|a| |b| |$|) (LIST (|OUTFORM;sform| ">=" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;+;3$;55| (|a| |b| |$|) (LIST (|OUTFORM;sform| "+" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;-;3$;56| (|a| |b| |$|) (LIST (|OUTFORM;sform| "-" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;-;2$;57| (|a| |$|) (LIST (|OUTFORM;sform| "-" |$|) |a|))
+
+(DEFUN |OUTFORM;*;3$;58| (|a| |b| |$|) (LIST (|OUTFORM;sform| "*" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;/;3$;59| (|a| |b| |$|) (LIST (|OUTFORM;sform| "/" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;**;3$;60| (|a| |b| |$|) (LIST (|OUTFORM;sform| "**" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;div;3$;61| (|a| |b| |$|) (LIST (|OUTFORM;sform| "div" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;rem;3$;62| (|a| |b| |$|) (LIST (|OUTFORM;sform| "rem" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;quo;3$;63| (|a| |b| |$|) (LIST (|OUTFORM;sform| "quo" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;exquo;3$;64| (|a| |b| |$|) (LIST (|OUTFORM;sform| "exquo" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;and;3$;65| (|a| |b| |$|) (LIST (|OUTFORM;sform| "and" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;or;3$;66| (|a| |b| |$|) (LIST (|OUTFORM;sform| "or" |$|) |a| |b|))
+
+(DEFUN |OUTFORM;not;2$;67| (|a| |$|) (LIST (|OUTFORM;sform| "not" |$|) |a|))
+
+(DEFUN |OUTFORM;SEGMENT;3$;68| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SEGMENT) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;SEGMENT;2$;69| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE SEGMENT) |$|) |a|))
+
+(DEFUN |OUTFORM;binomial;3$;70| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE BINOMIAL) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;empty;$;71| (|$|) (LIST (|OUTFORM;eform| (QUOTE NOTHING) |$|)))
+
+(DEFUN |OUTFORM;infix?;$B;72| (|a| |$|) (PROG (#1=#:G82802 |e|) (RETURN (SEQ (EXIT (SEQ (LETT |e| (COND ((IDENTP |a|) |a|) ((STRINGP |a|) (INTERN |a|)) ((QUOTE T) (PROGN (LETT #1# (QUOTE NIL) |OUTFORM;infix?;$B;72|) (GO #1#)))) |OUTFORM;infix?;$B;72|) (EXIT (COND ((GET |e| (QUOTE INFIXOP)) (QUOTE T)) ((QUOTE T) (QUOTE NIL)))))) #1# (EXIT #1#)))))
+
+(PUT (QUOTE |OUTFORM;elt;$L$;73|) (QUOTE |SPADreplace|) (QUOTE CONS))
+
+(DEFUN |OUTFORM;elt;$L$;73| (|a| |l| |$|) (CONS |a| |l|))
+
+(DEFUN |OUTFORM;prefix;$L$;74| (|a| |l| |$|) (COND ((NULL (SPADCALL |a| (QREFELT |$| 98))) (CONS |a| |l|)) ((QUOTE T) (SPADCALL |a| (SPADCALL (SPADCALL |l| (QREFELT |$| 51)) (QREFELT |$| 60)) (QREFELT |$| 37)))))
+
+(DEFUN |OUTFORM;infix;$L$;75| (|a| |l| |$|) (COND ((SPADCALL |l| (QREFELT |$| 66)) (SPADCALL (QREFELT |$| 12))) ((SPADCALL (SPADCALL |l| (QREFELT |$| 67)) (QREFELT |$| 66)) (SPADCALL |l| (QREFELT |$| 68))) ((SPADCALL |a| (QREFELT |$| 98)) (CONS |a| |l|)) ((QUOTE T) (SPADCALL (LIST (SPADCALL |l| (QREFELT |$| 68)) |a| (SPADCALL |a| (SPADCALL |l| (QREFELT |$| 101)) (QREFELT |$| 102))) (QREFELT |$| 75)))))
+
+(DEFUN |OUTFORM;infix;4$;76| (|a| |b| |c| |$|) (COND ((SPADCALL |a| (QREFELT |$| 98)) (LIST |a| |b| |c|)) ((QUOTE T) (SPADCALL (LIST |b| |a| |c|) (QREFELT |$| 75)))))
+
+(DEFUN |OUTFORM;postfix;3$;77| (|a| |b| |$|) (SPADCALL |b| |a| (QREFELT |$| 37)))
+
+(DEFUN |OUTFORM;string;2$;78| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE STRING) |$|) |a|))
+
+(DEFUN |OUTFORM;quote;2$;79| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE QUOTE) |$|) |a|))
+
+(DEFUN |OUTFORM;overbar;2$;80| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE OVERBAR) |$|) |a|))
+
+(DEFUN |OUTFORM;dot;2$;81| (|a| |$|) (SPADCALL |a| (|OUTFORM;sform| "." |$|) (QREFELT |$| 63)))
+
+(DEFUN |OUTFORM;prime;2$;82| (|a| |$|) (SPADCALL |a| (|OUTFORM;sform| "," |$|) (QREFELT |$| 63)))
+
+(DEFUN |OUTFORM;dot;$Nni$;83| (|a| |nn| |$|) (PROG (|s|) (RETURN (SEQ (LETT |s| (|MAKE-FULL-CVEC| |nn| (SPADCALL "." (QREFELT |$| 110))) |OUTFORM;dot;$Nni$;83|) (EXIT (SPADCALL |a| (|OUTFORM;sform| |s| |$|) (QREFELT |$| 63)))))))
+
+(DEFUN |OUTFORM;prime;$Nni$;84| (|a| |nn| |$|) (PROG (|s|) (RETURN (SEQ (LETT |s| (|MAKE-FULL-CVEC| |nn| (SPADCALL "," (QREFELT |$| 110))) |OUTFORM;prime;$Nni$;84|) (EXIT (SPADCALL |a| (|OUTFORM;sform| |s| |$|) (QREFELT |$| 63)))))))
+
+(DEFUN |OUTFORM;overlabel;3$;85| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE OVERLABEL) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;box;2$;86| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE BOX) |$|) |a|))
+
+(DEFUN |OUTFORM;zag;3$;87| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE ZAG) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;root;2$;88| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE ROOT) |$|) |a|))
+
+(DEFUN |OUTFORM;root;3$;89| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE ROOT) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;over;3$;90| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE OVER) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;slash;3$;91| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SLASH) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;assign;3$;92| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE LET) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;label;3$;93| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE EQUATNUM) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;rarrow;3$;94| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE TAG) |$|) |a| |b|))
+
+(DEFUN |OUTFORM;differentiate;$Nni$;95| (|a| |nn| |$|) (PROG (#1=#:G82832 |r| |s|) (RETURN (SEQ (COND ((ZEROP |nn|) |a|) ((|<| |nn| 4) (SPADCALL |a| |nn| (QREFELT |$| 112))) ((QUOTE T) (SEQ (LETT |r| (SPADCALL (PROG1 (LETT #1# |nn| |OUTFORM;differentiate;$Nni$;95|) (|check-subtype| (|>| #1# 0) (QUOTE (|PositiveInteger|)) #1#)) (QREFELT |$| 125)) |OUTFORM;differentiate;$Nni$;95|) (LETT |s| (SPADCALL |r| (QREFELT |$| 126)) |OUTFORM;differentiate;$Nni$;95|) (EXIT (SPADCALL |a| (SPADCALL (|OUTFORM;sform| |s| |$|) (QREFELT |$| 60)) (QREFELT |$| 63))))))))))
+
+(DEFUN |OUTFORM;sum;2$;96| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE SIGMA) |$|) (SPADCALL (QREFELT |$| 12)) |a|))
+
+(DEFUN |OUTFORM;sum;3$;97| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE SIGMA) |$|) |b| |a|))
+
+(DEFUN |OUTFORM;sum;4$;98| (|a| |b| |c| |$|) (LIST (|OUTFORM;eform| (QUOTE SIGMA2) |$|) |b| |c| |a|))
+
+(DEFUN |OUTFORM;prod;2$;99| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE PI) |$|) (SPADCALL (QREFELT |$| 12)) |a|))
+
+(DEFUN |OUTFORM;prod;3$;100| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE PI) |$|) |b| |a|))
+
+(DEFUN |OUTFORM;prod;4$;101| (|a| |b| |c| |$|) (LIST (|OUTFORM;eform| (QUOTE PI2) |$|) |b| |c| |a|))
+
+(DEFUN |OUTFORM;int;2$;102| (|a| |$|) (LIST (|OUTFORM;eform| (QUOTE INTSIGN) |$|) (SPADCALL (QREFELT |$| 12)) (SPADCALL (QREFELT |$| 12)) |a|))
+
+(DEFUN |OUTFORM;int;3$;103| (|a| |b| |$|) (LIST (|OUTFORM;eform| (QUOTE INTSIGN) |$|) |b| (SPADCALL (QREFELT |$| 12)) |a|))
+
+(DEFUN |OUTFORM;int;4$;104| (|a| |b| |c| |$|) (LIST (|OUTFORM;eform| (QUOTE INTSIGN) |$|) |b| |c| |a|))
+
+(DEFUN |OutputForm| NIL (PROG NIL (RETURN (PROG (#1=#:G82846) (RETURN (COND ((LETT #1# (HGET |$ConstructorCache| (QUOTE |OutputForm|)) |OutputForm|) (|CDRwithIncrement| (CDAR #1#))) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (CDDAR (HPUT |$ConstructorCache| (QUOTE |OutputForm|) (LIST (CONS NIL (CONS 1 (|OutputForm;|)))))) (LETT #1# T |OutputForm|)) (COND ((NOT #1#) (HREM |$ConstructorCache| (QUOTE |OutputForm|))))))))))))
+
+(DEFUN |OutputForm;| NIL (PROG (|dv$| |$| |pv$|) (RETURN (PROGN (LETT |dv$| (QUOTE (|OutputForm|)) . #1=(|OutputForm|)) (LETT |$| (GETREFV 138) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|haddProp| |$ConstructorCache| (QUOTE |OutputForm|) NIL (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 (|List| |$|)) |$|))))
+
+(MAKEPROP (QUOTE |OutputForm|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (QUOTE |Rep|) (|Void|) |OUTFORM;print;$V;1| (|Boolean|) (|String|) (0 . |empty?|) |OUTFORM;empty;$;71| |OUTFORM;message;S$;2| |OUTFORM;messagePrint;SV;3| |OUTFORM;=;2$B;4| |OUTFORM;=;3$;5| (|OutputForm|) |OUTFORM;coerce;2$;6| (|Integer|) |OUTFORM;outputForm;I$;7| (|Symbol|) |OUTFORM;outputForm;S$;8| (|DoubleFloat|) |OUTFORM;outputForm;Df$;9| (|Character|) (5 . |quote|) (9 . |concat|) (15 . |concat|) |OUTFORM;outputForm;S$;13| |OUTFORM;width;$I;14| |OUTFORM;height;$I;15| |OUTFORM;subHeight;$I;16| |OUTFORM;superHeight;$I;17| |OUTFORM;height;I;18| |OUTFORM;width;I;19| |OUTFORM;hspace;I$;27| |OUTFORM;hconcat;3$;46| |OUTFORM;center;$I$;20| |OUTFORM;left;$I$;21| |OUTFORM;right;$I$;22| |OUTFORM;center;2$;23| |OUTFORM;left;2$;24| |OUTFORM;right;2$;25| |OUTFORM;vspace;I$;26| |OUTFORM;vconcat;3$;48| |OUTFORM;rspace;2I$;28| (|List| 49) |OUTFORM;matrix;L$;29| (|List| |$|) |OUTFORM;pile;L$;30| |OUTFORM;commaSeparate;L$;31| |OUTFORM;semicolonSeparate;L$;32| (21 . |reverse|) (26 . |append|) |OUTFORM;blankSeparate;L$;33| |OUTFORM;brace;2$;34| |OUTFORM;brace;L$;35| |OUTFORM;bracket;2$;36| |OUTFORM;bracket;L$;37| |OUTFORM;paren;2$;38| |OUTFORM;paren;L$;39| |OUTFORM;sub;3$;40| |OUTFORM;super;3$;41| |OUTFORM;presub;3$;42| |OUTFORM;presuper;3$;43| (32 . |null|) (37 . |rest|) (42 . |first|) |OUTFORM;scripts;$L$;44| (|NonNegativeInteger|) (47 . |#|) (|List| |$$|) (52 . |append|) |OUTFORM;supersub;$L$;45| |OUTFORM;hconcat;L$;47| |OUTFORM;vconcat;L$;49| |OUTFORM;^=;3$;50| |OUTFORM;<;3$;51| |OUTFORM;>;3$;52| |OUTFORM;<=;3$;53| |OUTFORM;>=;3$;54| |OUTFORM;+;3$;55| |OUTFORM;-;3$;56| |OUTFORM;-;2$;57| |OUTFORM;*;3$;58| |OUTFORM;/;3$;59| |OUTFORM;**;3$;60| |OUTFORM;div;3$;61| |OUTFORM;rem;3$;62| |OUTFORM;quo;3$;63| |OUTFORM;exquo;3$;64| |OUTFORM;and;3$;65| |OUTFORM;or;3$;66| |OUTFORM;not;2$;67| |OUTFORM;SEGMENT;3$;68| |OUTFORM;SEGMENT;2$;69| |OUTFORM;binomial;3$;70| |OUTFORM;infix?;$B;72| |OUTFORM;elt;$L$;73| |OUTFORM;prefix;$L$;74| (58 . |rest|) |OUTFORM;infix;$L$;75| |OUTFORM;infix;4$;76| |OUTFORM;postfix;3$;77| |OUTFORM;string;2$;78| |OUTFORM;quote;2$;79| |OUTFORM;overbar;2$;80| |OUTFORM;dot;2$;81| |OUTFORM;prime;2$;82| (63 . |char|) |OUTFORM;dot;$Nni$;83| |OUTFORM;prime;$Nni$;84| |OUTFORM;overlabel;3$;85| |OUTFORM;box;2$;86| |OUTFORM;zag;3$;87| |OUTFORM;root;2$;88| |OUTFORM;root;3$;89| |OUTFORM;over;3$;90| |OUTFORM;slash;3$;91| |OUTFORM;assign;3$;92| |OUTFORM;label;3$;93| |OUTFORM;rarrow;3$;94| (|PositiveInteger|) (|NumberFormats|) (68 . |FormatRoman|) (73 . |lowerCase|) |OUTFORM;differentiate;$Nni$;95| |OUTFORM;sum;2$;96| |OUTFORM;sum;3$;97| |OUTFORM;sum;4$;98| |OUTFORM;prod;2$;99| |OUTFORM;prod;3$;100| |OUTFORM;prod;4$;101| |OUTFORM;int;2$;102| |OUTFORM;int;3$;103| |OUTFORM;int;4$;104| (|SingleInteger|))) (QUOTE #(|~=| 78 |zag| 84 |width| 90 |vspace| 99 |vconcat| 104 |supersub| 115 |superHeight| 121 |super| 126 |sum| 132 |subHeight| 150 |sub| 155 |string| 161 |slash| 166 |semicolonSeparate| 172 |scripts| 177 |rspace| 183 |root| 189 |right| 200 |rem| 211 |rarrow| 217 |quote| 223 |quo| 228 |prod| 234 |print| 252 |prime| 257 |presuper| 268 |presub| 274 |prefix| 280 |postfix| 286 |pile| 292 |paren| 297 |overlabel| 307 |overbar| 313 |over| 318 |outputForm| 324 |or| 344 |not| 350 |messagePrint| 355 |message| 360 |matrix| 365 |left| 370 |latex| 381 |label| 386 |int| 392 |infix?| 410 |infix| 415 |hspace| 428 |height| 433 |hconcat| 442 |hash| 453 |exquo| 458 |empty| 464 |elt| 468 |dot| 474 |div| 485 |differentiate| 491 |commaSeparate| 497 |coerce| 502 |center| 507 |bracket| 518 |brace| 528 |box| 538 |blankSeparate| 543 |binomial| 548 |assign| 554 |and| 560 |^=| 566 SEGMENT 572 |>=| 583 |>| 589 |=| 595 |<=| 607 |<| 613 |/| 619 |-| 625 |+| 636 |**| 642 |*| 648)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE (0 0 0))) (CONS (QUOTE #(|SetCategory&| |BasicType&| NIL)) (CONS (QUOTE #((|SetCategory|) (|BasicType|) (|CoercibleTo| 17))) (|makeByteWordVec2| 137 (QUOTE (1 10 9 0 11 0 25 0 26 2 10 0 0 25 27 2 10 0 25 0 28 1 6 0 0 53 2 6 0 0 0 54 1 6 9 0 66 1 6 0 0 67 1 6 2 0 68 1 6 70 0 71 2 72 0 0 0 73 1 72 0 0 101 1 25 0 10 110 1 124 10 123 125 1 10 0 0 126 2 0 9 0 0 1 2 0 0 0 0 115 0 0 19 35 1 0 19 0 30 1 0 0 19 44 1 0 0 49 76 2 0 0 0 0 45 2 0 0 0 49 74 1 0 19 0 33 2 0 0 0 0 63 2 0 0 0 0 129 3 0 0 0 0 0 130 1 0 0 0 128 1 0 19 0 32 2 0 0 0 0 62 1 0 0 0 105 2 0 0 0 0 119 1 0 0 49 52 2 0 0 0 49 69 2 0 0 19 19 46 1 0 0 0 116 2 0 0 0 0 117 1 0 0 0 43 2 0 0 0 19 40 2 0 0 0 0 89 2 0 0 0 0 122 1 0 0 0 106 2 0 0 0 0 90 3 0 0 0 0 0 133 1 0 0 0 131 2 0 0 0 0 132 1 0 7 0 8 2 0 0 0 70 112 1 0 0 0 109 2 0 0 0 0 65 2 0 0 0 0 64 2 0 0 0 49 100 2 0 0 0 0 104 1 0 0 49 50 1 0 0 49 61 1 0 0 0 60 2 0 0 0 0 113 1 0 0 0 107 2 0 0 0 0 118 1 0 0 10 29 1 0 0 23 24 1 0 0 21 22 1 0 0 19 20 2 0 0 0 0 93 1 0 0 0 94 1 0 7 10 14 1 0 0 10 13 1 0 0 47 48 1 0 0 0 42 2 0 0 0 19 39 1 0 10 0 1 2 0 0 0 0 121 3 0 0 0 0 0 136 2 0 0 0 0 135 1 0 0 0 134 1 0 9 0 98 2 0 0 0 49 102 3 0 0 0 0 0 103 1 0 0 19 36 0 0 19 34 1 0 19 0 31 1 0 0 49 75 2 0 0 0 0 37 1 0 137 0 1 2 0 0 0 0 91 0 0 0 12 2 0 0 0 49 99 2 0 0 0 70 111 1 0 0 0 108 2 0 0 0 0 88 2 0 0 0 70 127 1 0 0 49 51 1 0 17 0 18 1 0 0 0 41 2 0 0 0 19 38 1 0 0 0 58 1 0 0 49 59 1 0 0 49 57 1 0 0 0 56 1 0 0 0 114 1 0 0 49 55 2 0 0 0 0 97 2 0 0 0 0 120 2 0 0 0 0 92 2 0 0 0 0 77 1 0 0 0 96 2 0 0 0 0 95 2 0 0 0 0 81 2 0 0 0 0 79 2 0 0 0 0 16 2 0 9 0 0 15 2 0 0 0 0 80 2 0 0 0 0 78 2 0 0 0 0 86 1 0 0 0 84 2 0 0 0 0 83 2 0 0 0 0 82 2 0 0 0 0 87 2 0 0 0 0 85)))))) (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |OutputForm|) (QUOTE NILADIC) T)
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NUMFMT NumberFormats>>
+<<domain OUTFORM OutputForm>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pade.spad.pamphlet b/src/algebra/pade.spad.pamphlet
new file mode 100644
index 00000000..de1a71b2
--- /dev/null
+++ b/src/algebra/pade.spad.pamphlet
@@ -0,0 +1,247 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pade.spad}
+\author{Barry Trager, William Burge, Martin Hassner,Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PADEPAC PadeApproximantPackage}
+<<package PADEPAC PadeApproximantPackage>>=
+)abbrev package PADEPAC PadeApproximantPackage
+++ This package computes reliable Pad&ea. approximants using
+++ a generalized Viskovatov continued fraction algorithm.
+++ Authors: Trager,Burge, Hassner & Watt.
+++ Date Created: April 1987
+++ Date Last Updated: 12 April 1990
+++ Keywords: Pade, series
+++ Examples:
+++ References:
+++ "Pade Approximants, Part I: Basic Theory", Baker & Graves-Morris.
+
+PadeApproximantPackage(R: Field, x:Symbol, pt:R): Exports == Implementation where
+ PS ==> UnivariateTaylorSeries(R,x,pt)
+ UP ==> UnivariatePolynomial(x,R)
+ QF ==> Fraction UP
+ CF ==> ContinuedFraction UP
+ NNI ==> NonNegativeInteger
+ Exports ==> with
+ pade: (NNI,NNI,PS,PS) -> Union(QF,"failed")
+ ++ pade(nd,dd,ns,ds) computes the approximant as a quotient of polynomials
+ ++ (if it exists) for arguments
+ ++ nd (numerator degree of approximant),
+ ++ dd (denominator degree of approximant),
+ ++ ns (numerator series of function), and
+ ++ ds (denominator series of function).
+ pade: (NNI,NNI,PS) -> Union(QF,"failed")
+ ++ pade(nd,dd,s)
+ ++ computes the quotient of polynomials
+ ++ (if it exists) with numerator degree at
+ ++ most nd and denominator degree at most dd
+ ++ which matches the series s to order \spad{nd + dd}.
+
+ Implementation ==> add
+ n,m : NNI
+ u,v : PS
+ pa := PadeApproximants(R,PS,UP)
+ pade(n,m,u,v) ==
+ ans:=pade(n,m,u,v)$pa
+ ans case "failed" => ans
+ pt = 0 => ans
+ num := numer(ans::QF)
+ den := denom(ans::QF)
+ xpt : UP := monomial(1,1)-monomial(pt,0)
+ num := num(xpt)
+ den := den(xpt)
+ num/den
+ pade(n,m,u) == pade(n,m,u,1)
+
+@
+\section{package PADE PadeApproximants}
+<<package PADE PadeApproximants>>=
+)abbrev package PADE PadeApproximants
+++ This package computes reliable Pad&ea. approximants using
+++ a generalized Viskovatov continued fraction algorithm.
+++ Authors: Burge, Hassner & Watt.
+++ Date Created: April 1987
+++ Date Last Updated: 12 April 1990
+++ Keywords: Pade, series
+++ Examples:
+++ References:
+++ "Pade Approximants, Part I: Basic Theory", Baker & Graves-Morris.
+PadeApproximants(R,PS,UP): Exports == Implementation where
+ R: Field -- IntegralDomain
+ PS: UnivariateTaylorSeriesCategory R
+ UP: UnivariatePolynomialCategory R
+
+ NNI ==> NonNegativeInteger
+ QF ==> Fraction UP
+ CF ==> ContinuedFraction UP
+
+ Exports ==> with
+ pade: (NNI,NNI,PS,PS) -> Union(QF,"failed")
+ ++ pade(nd,dd,ns,ds)
+ ++ computes the approximant as a quotient of polynomials
+ ++ (if it exists) for arguments
+ ++ nd (numerator degree of approximant),
+ ++ dd (denominator degree of approximant),
+ ++ ns (numerator series of function), and
+ ++ ds (denominator series of function).
+ padecf: (NNI,NNI,PS,PS) -> Union(CF, "failed")
+ ++ padecf(nd,dd,ns,ds)
+ ++ computes the approximant as a continued fraction of
+ ++ polynomials (if it exists) for arguments
+ ++ nd (numerator degree of approximant),
+ ++ dd (denominator degree of approximant),
+ ++ ns (numerator series of function), and
+ ++ ds (denominator series of function).
+
+ Implementation ==> add
+ -- The approximant is represented as
+ -- p0 + x**a1/(p1 + x**a2/(...))
+
+ PadeRep ==> Record(ais: List UP, degs: List NNI) -- #ais= #degs
+ PadeU ==> Union(PadeRep, "failed") -- #ais= #degs+1
+
+ constInner(up:UP):PadeU == [[up], []]
+
+ truncPoly(p:UP,n:NNI):UP ==
+ while n < degree p repeat p := reductum p
+ p
+
+ truncSeries(s:PS,n:NNI):UP ==
+ p: UP := 0
+ for i in 0..n repeat p := p + monomial(coefficient(s,i),i)
+ p
+
+ -- Assumes s starts with a<n>*x**n + ... and divides out x**n.
+ divOutDegree(s:PS,n:NNI):PS ==
+ for i in 1..n repeat s := quoByVar s
+ s
+
+ padeNormalize: (NNI,NNI,PS,PS) -> PadeU
+ padeInner: (NNI,NNI,PS,PS) -> PadeU
+
+ pade(l,m,gps,dps) ==
+ (ad := padeNormalize(l,m,gps,dps)) case "failed" => "failed"
+ plist := ad.ais; dlist := ad.degs
+ approx := first(plist) :: QF
+ for d in dlist for p in rest plist repeat
+ approx := p::QF + (monomial(1,d)$UP :: QF)/approx
+ approx
+
+ padecf(l,m,gps,dps) ==
+ (ad := padeNormalize(l,m,gps,dps)) case "failed" => "failed"
+ alist := reverse(ad.ais)
+ blist := [monomial(1,d)$UP for d in reverse ad.degs]
+ continuedFraction(first(alist),_
+ blist::Stream UP,(rest alist) :: Stream UP)
+
+ padeNormalize(l,m,gps,dps) ==
+ zero? dps => "failed"
+ zero? gps => constInner 0
+ -- Normalize so numerator or denominator has constant term.
+ ldeg:= min(order dps,order gps)
+ if ldeg > 0 then
+ dps := divOutDegree(dps,ldeg)
+ gps := divOutDegree(gps,ldeg)
+ padeInner(l,m,gps,dps)
+
+ padeInner(l, m, gps, dps) ==
+ zero? coefficient(gps,0) and zero? coefficient(dps,0) =>
+ error "Pade' problem not normalized."
+ plist: List UP := nil()
+ alist: List NNI := nil()
+ -- Ensure denom has constant term.
+ if zero? coefficient(dps,0) then
+ -- g/d = 0 + z**0/(d/g)
+ (gps,dps) := (dps,gps)
+ (l,m) := (m,l)
+ plist := concat(0,plist)
+ alist := concat(0,alist)
+ -- Ensure l >= m, maintaining coef(dps,0)^=0.
+ if l < m then
+ -- (a<n>*x**n + a<n+1>*x**n+1 + ...)/b
+ -- = x**n/b + (a<n> + a<n+1>*x + ...)/b
+ alpha := order gps
+ if alpha > l then return "failed"
+ gps := divOutDegree(gps, alpha)
+ (l,m) := (m,(l-alpha) :: NNI)
+ (gps,dps) := (dps,gps)
+ plist := concat(0,plist)
+ alist := concat(alpha,alist)
+ degbd: NNI := l + m + 1
+ g := truncSeries(gps,degbd)
+ d := truncSeries(dps,degbd)
+ for j in 0.. repeat
+ -- Normalize d so constant coefs cancel. (B&G-M is wrong)
+ d0 := coefficient(d,0)
+ d := (1/d0) * d; g := (1/d0) * g
+ p : UP := 0; s := g
+ if l-m+1 < 0 then error "Internal pade error"
+ degbd := (l-m+1) :: NNI
+ for k in 1..degbd repeat
+ pk := coefficient(s,0)
+ p := p + monomial(pk,(k-1) :: NNI)
+ s := s - pk*d
+ s := (s exquo monomial(1,1)) :: UP
+ plist := concat(p,plist)
+ s = 0 => return [plist,alist]
+ alpha := minimumDegree(s) + degbd
+ alpha > l + m => return [plist,alist]
+ alpha > l => return "failed"
+ alist := concat(alpha,alist)
+ h := (s exquo monomial(1,minimumDegree s)) :: UP
+ degbd := (l + m - alpha) :: NNI
+ g := truncPoly(d,degbd)
+ d := truncPoly(h,degbd)
+ (l,m) := (m,(l-alpha) :: NNI)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PADEPAC PadeApproximantPackage>>
+<<package PADE PadeApproximants>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/padic.spad.pamphlet b/src/algebra/padic.spad.pamphlet
new file mode 100644
index 00000000..a75faa77
--- /dev/null
+++ b/src/algebra/padic.spad.pamphlet
@@ -0,0 +1,624 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra padic.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PADICCT PAdicIntegerCategory}
+<<category PADICCT PAdicIntegerCategory>>=
+)abbrev category PADICCT PAdicIntegerCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 15 May 1990
+++ Date Last Updated: 15 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: p-adic, completion
+++ Examples:
+++ References:
+++ Description: This is the catefory of stream-based representations of
+++ the p-adic integers.
+PAdicIntegerCategory(p): Category == Definition where
+ p : Integer
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ ST ==> Stream
+ SUP ==> SparseUnivariatePolynomial
+
+ Definition ==> Join(EuclideanDomain,CharacteristicZero) with
+ digits: % -> ST I
+ ++ \spad{digits(x)} returns a stream of p-adic digits of x.
+ order: % -> NNI
+ ++ \spad{order(x)} returns the exponent of the highest power of p
+ ++ dividing x.
+ extend: (%,I) -> %
+ ++ \spad{extend(x,n)} forces the computation of digits up to order n.
+ complete: % -> %
+ ++ \spad{complete(x)} forces the computation of all digits.
+ modulus: () -> I
+ ++ \spad{modulus()} returns the value of p.
+ moduloP: % -> I
+ ++ \spad{modulo(x)} returns a, where \spad{x = a + b p}.
+ quotientByP: % -> %
+ ++ \spad{quotientByP(x)} returns b, where \spad{x = a + b p}.
+ approximate: (%,I) -> I
+ ++ \spad{approximate(x,n)} returns an integer y such that
+ ++ \spad{y = x (mod p^n)}
+ ++ when n is positive, and 0 otherwise.
+ sqrt: (%,I) -> %
+ ++ \spad{sqrt(b,a)} returns a square root of b.
+ ++ Argument \spad{a} is a square root of b \spad{(mod p)}.
+ root: (SUP I,I) -> %
+ ++ \spad{root(f,a)} returns a root of the polynomial \spad{f}.
+ ++ Argument \spad{a} must be a root of \spad{f} \spad{(mod p)}.
+
+@
+\section{domain IPADIC InnerPAdicInteger}
+<<domain IPADIC InnerPAdicInteger>>=
+)abbrev domain IPADIC InnerPAdicInteger
+++ Author: Clifton J. Williamson
+++ Date Created: 20 August 1989
+++ Date Last Updated: 15 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: p-adic, completion
+++ Examples:
+++ References:
+++ Description:
+++ This domain implements Zp, the p-adic completion of the integers.
+++ This is an internal domain.
+InnerPAdicInteger(p,unBalanced?): Exports == Implementation where
+ p : Integer
+ unBalanced? : Boolean
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ L ==> List
+ ST ==> Stream
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> PAdicIntegerCategory p
+
+ Implementation ==> add
+
+ PEXPR := p :: OUT
+
+ Rep := ST I
+
+ characteristic() == 0
+ euclideanSize(x) == order(x)
+
+ stream(x:%):ST I == x pretend ST(I)
+ padic(x:ST I):% == x pretend %
+ digits x == stream x
+
+ extend(x,n) == extend(x,n + 1)$Rep
+ complete x == complete(x)$Rep
+
+-- notBalanced?:() -> Boolean
+-- notBalanced?() == unBalanced?
+
+ modP:I -> I
+ modP n ==
+ unBalanced? or (p = 2) => positiveRemainder(n,p)
+ symmetricRemainder(n,p)
+
+ modPInfo:I -> Record(digit:I,carry:I)
+ modPInfo n ==
+ dv := divide(n,p)
+ r0 := dv.remainder; q := dv.quotient
+ if (r := modP r0) ^= r0 then q := q + ((r0 - r) quo p)
+ [r,q]
+
+ invModP: I -> I
+ invModP n == invmod(n,p)
+
+ modulus() == p
+ moduloP x == (empty? x => 0; frst x)
+ quotientByP x == (empty? x => x; rst x)
+
+ approximate(x,n) ==
+ n <= 0 or empty? x => 0
+ frst x + p * approximate(rst x,n - 1)
+
+ x = y ==
+ st : ST I := stream(x - y)
+ n : I := _$streamCount$Lisp
+ for i in 0..n repeat
+ empty? st => return true
+ frst st ^= 0 => return false
+ st := rst st
+ empty? st
+
+ order x ==
+ st := stream x
+ for i in 0..1000 repeat
+ empty? st => return 0
+ frst st ^= 0 => return i
+ st := rst st
+ error "order: series has more than 1000 leading zero coefs"
+
+ 0 == padic concat(0$I,empty())
+ 1 == padic concat(1$I,empty())
+
+ intToPAdic: I -> ST I
+ intToPAdic n == delay
+ n = 0 => empty()
+ modp := modPInfo n
+ concat(modp.digit,intToPAdic modp.carry)
+
+ intPlusPAdic: (I,ST I) -> ST I
+ intPlusPAdic(n,x) == delay
+ empty? x => intToPAdic n
+ modp := modPInfo(n + frst x)
+ concat(modp.digit,intPlusPAdic(modp.carry,rst x))
+
+ intMinusPAdic: (I,ST I) -> ST I
+ intMinusPAdic(n,x) == delay
+ empty? x => intToPAdic n
+ modp := modPInfo(n - frst x)
+ concat(modp.digit,intMinusPAdic(modp.carry,rst x))
+
+ plusAux: (I,ST I,ST I) -> ST I
+ plusAux(n,x,y) == delay
+ empty? x and empty? y => intToPAdic n
+ empty? x => intPlusPAdic(n,y)
+ empty? y => intPlusPAdic(n,x)
+ modp := modPInfo(n + frst x + frst y)
+ concat(modp.digit,plusAux(modp.carry,rst x,rst y))
+
+ minusAux: (I,ST I,ST I) -> ST I
+ minusAux(n,x,y) == delay
+ empty? x and empty? y => intToPAdic n
+ empty? x => intMinusPAdic(n,y)
+ empty? y => intPlusPAdic(n,x)
+ modp := modPInfo(n + frst x - frst y)
+ concat(modp.digit,minusAux(modp.carry,rst x,rst y))
+
+ x + y == padic plusAux(0,stream x,stream y)
+ x - y == padic minusAux(0,stream x,stream y)
+ - y == padic intMinusPAdic(0,stream y)
+ coerce(n:I) == padic intToPAdic n
+
+ intMult:(I,ST I) -> ST I
+ intMult(n,x) == delay
+ empty? x => empty()
+ modp := modPInfo(n * frst x)
+ concat(modp.digit,intPlusPAdic(modp.carry,intMult(n,rst x)))
+
+ (n:I) * (x:%) ==
+ padic intMult(n,stream x)
+
+ timesAux:(ST I,ST I) -> ST I
+ timesAux(x,y) == delay
+ empty? x or empty? y => empty()
+ modp := modPInfo(frst x * frst y)
+ car := modp.digit
+ cdr : ST I --!!
+ cdr := plusAux(modp.carry,intMult(frst x,rst y),timesAux(rst x,y))
+ concat(car,cdr)
+
+ (x:%) * (y:%) == padic timesAux(stream x,stream y)
+
+ quotientAux:(ST I,ST I) -> ST I
+ quotientAux(x,y) == delay
+ empty? x => error "quotientAux: first argument"
+ empty? y => empty()
+ modP frst x = 0 =>
+ modP frst y = 0 => quotientAux(rst x,rst y)
+ error "quotient: quotient not integral"
+ z0 := modP(invModP frst x * frst y)
+ yy : ST I --!!
+ yy := rest minusAux(0,y,intMult(z0,x))
+ concat(z0,quotientAux(x,yy))
+
+ recip x ==
+ empty? x or modP frst x = 0 => "failed"
+ padic quotientAux(stream x,concat(1,empty()))
+
+ iExquo: (%,%,I) -> Union(%,"failed")
+ iExquo(xx,yy,n) ==
+ n > 1000 =>
+ error "exquo: quotient by series with many leading zero coefs"
+ empty? yy => "failed"
+ empty? xx => 0
+ zero? frst yy =>
+ zero? frst xx => iExquo(rst xx,rst yy,n + 1)
+ "failed"
+ (rec := recip yy) case "failed" => "failed"
+ xx * (rec :: %)
+
+ x exquo y == iExquo(stream x,stream y,0)
+
+ divide(x,y) ==
+ (z:=x exquo y) case "failed" => [0,x]
+ [z, 0]
+
+ iSqrt: (I,I,I,%) -> %
+ iSqrt(pn,an,bn,bSt) == delay
+ bn1 := (empty? bSt => bn; bn + pn * frst(bSt))
+ c := (bn1 - an*an) quo pn
+ aa := modP(c * invmod(2*an,p))
+ nSt := (empty? bSt => bSt; rst bSt)
+ concat(aa,iSqrt(pn*p,an + pn*aa,bn1,nSt))
+
+ sqrt(b,a) ==
+ p = 2 =>
+ error "sqrt: no square roots in Z2 yet"
+ not zero? modP(a*a - (bb := moduloP b)) =>
+ error "sqrt: not a square root (mod p)"
+ b := (empty? b => b; rst b)
+ a := modP a
+ concat(a,iSqrt(p,a,bb,b))
+
+ iRoot: (SUP I,I,I,I) -> ST I
+ iRoot(f,alpha,invFpx0,pPow) == delay
+ num := -((f(alpha) exquo pPow) :: I)
+ digit := modP(num * invFpx0)
+ concat(digit,iRoot(f,alpha + digit * pPow,invFpx0,p * pPow))
+
+ root(f,x0) ==
+ x0 := modP x0
+ not zero? modP f(x0) =>
+ error "root: not a root (mod p)"
+ fpx0 := modP (differentiate f)(x0)
+ zero? fpx0 =>
+ error "root: approximate root must be a simple root (mod p)"
+ invFpx0 := modP invModP fpx0
+ padic concat(x0,iRoot(f,x0,invFpx0,p))
+
+ termOutput:(I,I) -> OUT
+ termOutput(k,c) ==
+ k = 0 => c :: OUT
+ mon := (k = 1 => PEXPR; PEXPR ** (k :: OUT))
+ c = 1 => mon
+ c = -1 => -mon
+ (c :: OUT) * mon
+
+ showAll?:() -> Boolean
+ -- check a global Lisp variable
+ showAll?() == true
+
+ coerce(x:%):OUT ==
+ empty?(st := stream x) => 0 :: OUT
+ n : NNI ; count : NNI := _$streamCount$Lisp
+ l : L OUT := empty()
+ for n in 0..count while not empty? st repeat
+ if frst(st) ^= 0 then
+ l := concat(termOutput(n :: I,frst st),l)
+ st := rst st
+ if showAll?() then
+ for n in (count + 1).. while explicitEntries? st and _
+ not eq?(st,rst st) repeat
+ if frst(st) ^= 0 then
+ l := concat(termOutput(n pretend I,frst st),l)
+ st := rst st
+ l :=
+ explicitlyEmpty? st => l
+ eq?(st,rst st) and frst st = 0 => l
+ concat(prefix("O" :: OUT,[PEXPR ** (n :: OUT)]),l)
+ empty? l => 0 :: OUT
+ reduce("+",reverse_! l)
+
+@
+\section{domain PADIC PAdicInteger}
+<<domain PADIC PAdicInteger>>=
+)abbrev domain PADIC PAdicInteger
+++ Author: Clifton J. Williamson
+++ Date Created: 20 August 1989
+++ Date Last Updated: 15 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: p-adic, completion
+++ Examples:
+++ References:
+++ Description:
+++ Stream-based implementation of Zp: p-adic numbers are represented as
+++ sum(i = 0.., a[i] * p^i), where the a[i] lie in 0,1,...,(p - 1).
+PAdicInteger(p:Integer) == InnerPAdicInteger(p,true$Boolean)
+
+@
+\section{domain BPADIC BalancedPAdicInteger}
+<<domain BPADIC BalancedPAdicInteger>>=
+)abbrev domain BPADIC BalancedPAdicInteger
+++ Author: Clifton J. Williamson
+++ Date Created: 15 May 1990
+++ Date Last Updated: 15 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: p-adic, complementation
+++ Examples:
+++ References:
+++ Description:
+++ Stream-based implementation of Zp: p-adic numbers are represented as
+++ sum(i = 0.., a[i] * p^i), where the a[i] lie in -(p - 1)/2,...,(p - 1)/2.
+BalancedPAdicInteger(p:Integer) == InnerPAdicInteger(p,false$Boolean)
+
+@
+\section{domain PADICRC PAdicRationalConstructor}
+<<domain PADICRC PAdicRationalConstructor>>=
+)abbrev domain PADICRC PAdicRationalConstructor
+++ Author: Clifton J. Williamson
+++ Date Created: 10 May 1990
+++ Date Last Updated: 10 May 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Keywords: p-adic, completion
+++ Examples:
+++ References:
+++ Description: This is the category of stream-based representations of Qp.
+PAdicRationalConstructor(p,PADIC): Exports == Implementation where
+ p : Integer
+ PADIC : PAdicIntegerCategory p
+ CF ==> ContinuedFraction
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ L ==> List
+ RN ==> Fraction Integer
+ ST ==> Stream
+
+ Exports ==> QuotientFieldCategory(PADIC) with
+ approximate: (%,I) -> RN
+ ++ \spad{approximate(x,n)} returns a rational number y such that
+ ++ \spad{y = x (mod p^n)}.
+ continuedFraction: % -> CF RN
+ ++ \spad{continuedFraction(x)} converts the p-adic rational number x
+ ++ to a continued fraction.
+ removeZeroes: % -> %
+ ++ \spad{removeZeroes(x)} removes leading zeroes from the
+ ++ representation of the p-adic rational \spad{x}.
+ ++ A p-adic rational is represented by (1) an exponent and
+ ++ (2) a p-adic integer which may have leading zero digits.
+ ++ When the p-adic integer has a leading zero digit, a 'leading zero'
+ ++ is removed from the p-adic rational as follows:
+ ++ the number is rewritten by increasing the exponent by 1 and
+ ++ dividing the p-adic integer by p.
+ ++ Note: \spad{removeZeroes(f)} removes all leading zeroes from f.
+ removeZeroes: (I,%) -> %
+ ++ \spad{removeZeroes(n,x)} removes up to n leading zeroes from
+ ++ the p-adic rational \spad{x}.
+
+ Implementation ==> add
+
+ PEXPR := p :: OUT
+
+--% representation
+
+ Rep := Record(expon:I,pint:PADIC)
+
+ getExpon: % -> I
+ getZp : % -> PADIC
+ makeQp : (I,PADIC) -> %
+
+ getExpon x == x.expon
+ getZp x == x.pint
+ makeQp(r,int) == [r,int]
+
+--% creation
+
+ 0 == makeQp(0,0)
+ 1 == makeQp(0,1)
+
+ coerce(x:I) == x :: PADIC :: %
+ coerce(r:RN) == (numer(r) :: %)/(denom(r) :: %)
+ coerce(x:PADIC) == makeQp(0,x)
+
+--% normalizations
+
+ removeZeroes x ==
+ empty? digits(xx := getZp x) => 0
+ zero? moduloP xx =>
+ removeZeroes makeQp(getExpon x + 1,quotientByP xx)
+ x
+
+ removeZeroes(n,x) ==
+ n <= 0 => x
+ empty? digits(xx := getZp x) => 0
+ zero? moduloP xx =>
+ removeZeroes(n - 1,makeQp(getExpon x + 1,quotientByP xx))
+ x
+
+--% arithmetic
+
+ x = y ==
+ EQ(x,y)$Lisp => true
+ n := getExpon(x) - getExpon(y)
+ n >= 0 =>
+ (p**(n :: NNI) * getZp(x)) = getZp(y)
+ (p**((- n) :: NNI) * getZp(y)) = getZp(x)
+
+ x + y ==
+ n := getExpon(x) - getExpon(y)
+ n >= 0 =>
+ makeQp(getExpon y,getZp(y) + p**(n :: NNI) * getZp(x))
+ makeQp(getExpon x,getZp(x) + p**((-n) :: NNI) * getZp(y))
+
+ -x == makeQp(getExpon x,-getZp(x))
+
+ x - y ==
+ n := getExpon(x) - getExpon(y)
+ n >= 0 =>
+ makeQp(getExpon y,p**(n :: NNI) * getZp(x) - getZp(y))
+ makeQp(getExpon x,getZp(x) - p**((-n) :: NNI) * getZp(y))
+
+ n:I * x:% == makeQp(getExpon x,n * getZp x)
+ x:% * y:% == makeQp(getExpon x + getExpon y,getZp x * getZp y)
+
+ x:% ** n:I ==
+ zero? n => 1
+ positive? n => expt(x,n :: PositiveInteger)$RepeatedSquaring(%)
+ inv expt(x,(-n) :: PositiveInteger)$RepeatedSquaring(%)
+
+ recip x ==
+ x := removeZeroes(1000,x)
+ zero? moduloP(xx := getZp x) => "failed"
+ (inv := recip xx) case "failed" => "failed"
+ makeQp(- getExpon x,inv :: PADIC)
+
+ inv x ==
+ (inv := recip x) case "failed" => error "inv: no inverse"
+ inv :: %
+
+ x:% / y:% == x * inv y
+ x:PADIC / y:PADIC == (x :: %) / (y :: %)
+ x:PADIC * y:% == makeQp(getExpon y,x * getZp y)
+
+ approximate(x,n) ==
+ k := getExpon x
+ (p :: RN) ** k * approximate(getZp x,n - k)
+
+ cfStream: % -> Stream RN
+ cfStream x == delay
+-- zero? x => empty()
+ invx := inv x; x0 := approximate(invx,1)
+ concat(x0,cfStream(invx - (x0 :: %)))
+
+ continuedFraction x ==
+ x0 := approximate(x,1)
+ reducedContinuedFraction(x0,cfStream(x - (x0 :: %)))
+
+ termOutput:(I,I) -> OUT
+ termOutput(k,c) ==
+ k = 0 => c :: OUT
+ mon := (k = 1 => PEXPR; PEXPR ** (k :: OUT))
+ c = 1 => mon
+ c = -1 => -mon
+ (c :: OUT) * mon
+
+ showAll?:() -> Boolean
+ -- check a global Lisp variable
+ showAll?() == true
+
+ coerce(x:%):OUT ==
+ x := removeZeroes(_$streamCount$Lisp,x)
+ m := getExpon x; zp := getZp x
+ uu := digits zp
+ l : L OUT := empty()
+ empty? uu => 0 :: OUT
+ n : NNI ; count : NNI := _$streamCount$Lisp
+ for n in 0..count while not empty? uu repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput((n :: I) + m,frst(uu)),l)
+ uu := rst uu
+ if showAll?() then
+ for n in (count + 1).. while explicitEntries? uu and _
+ not eq?(uu,rst uu) repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput((n::I) + m,frst(uu)),l)
+ uu := rst uu
+ l :=
+ explicitlyEmpty? uu => l
+ eq?(uu,rst uu) and frst uu = 0 => l
+ concat(prefix("O" :: OUT,[PEXPR ** ((n :: I) + m) :: OUT]),l)
+ empty? l => 0 :: OUT
+ reduce("+",reverse_! l)
+
+@
+\section{domain PADICRAT PAdicRational}
+<<domain PADICRAT PAdicRational>>=
+)abbrev domain PADICRAT PAdicRational
+++ Author: Clifton J. Williamson
+++ Date Created: 15 May 1990
+++ Date Last Updated: 15 May 1990
+++ Keywords: p-adic, complementation
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: p-adic, completion
+++ Examples:
+++ References:
+++ Description:
+++ Stream-based implementation of Qp: numbers are represented as
+++ sum(i = k.., a[i] * p^i) where the a[i] lie in 0,1,...,(p - 1).
+PAdicRational(p:Integer) == PAdicRationalConstructor(p,PAdicInteger p)
+
+@
+\section{domain BPADICRT BalancedPAdicRational}
+<<domain BPADICRT BalancedPAdicRational>>=
+)abbrev domain BPADICRT BalancedPAdicRational
+++ Author: Clifton J. Williamson
+++ Date Created: 15 May 1990
+++ Date Last Updated: 15 May 1990
+++ Keywords: p-adic, complementation
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: p-adic, completion
+++ Examples:
+++ References:
+++ Description:
+++ Stream-based implementation of Qp: numbers are represented as
+++ sum(i = k.., a[i] * p^i), where the a[i] lie in -(p - 1)/2,...,(p - 1)/2.
+BalancedPAdicRational(p:Integer) ==
+ PAdicRationalConstructor(p,BalancedPAdicInteger p)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PADICCT PAdicIntegerCategory>>
+<<domain IPADIC InnerPAdicInteger>>
+<<domain PADIC PAdicInteger>>
+<<domain BPADIC BalancedPAdicInteger>>
+<<domain PADICRC PAdicRationalConstructor>>
+<<domain PADICRAT PAdicRational>>
+<<domain BPADICRT BalancedPAdicRational>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/padiclib.spad.pamphlet b/src/algebra/padiclib.spad.pamphlet
new file mode 100644
index 00000000..9b3e79cc
--- /dev/null
+++ b/src/algebra/padiclib.spad.pamphlet
@@ -0,0 +1,571 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra padiclib.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package IBPTOOLS IntegralBasisPolynomialTools}
+<<package IBPTOOLS IntegralBasisPolynomialTools>>=
+)abbrev package IBPTOOLS IntegralBasisPolynomialTools
+++ Author: Clifton Williamson
+++ Date Created: 13 August 1993
+++ Date Last Updated: 17 August 1993
+++ Basic Operations: mapUnivariate, mapBivariate
+++ Related Domains: PAdicWildFunctionFieldIntegralBasis(K,R,UP,F)
+++ Also See: WildFunctionFieldIntegralBasis, FunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, finite field, integral basis
+++ Examples:
+++ References:
+++ Description: IntegralBasisPolynomialTools provides functions for
+++ mapping functions on the coefficients of univariate and bivariate
+++ polynomials.
+
+IntegralBasisPolynomialTools(K,R,UP,L): Exports == Implementation where
+ K : Ring
+ R : UnivariatePolynomialCategory K
+ UP : UnivariatePolynomialCategory R
+ L : Ring
+
+ MAT ==> Matrix
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> with
+ mapUnivariate: (L -> K,SUP L) -> R
+ ++ mapUnivariate(f,p(x)) applies the function \spad{f} to the
+ ++ coefficients of \spad{p(x)}.
+
+ mapUnivariate: (K -> L,R) -> SUP L
+ ++ mapUnivariate(f,p(x)) applies the function \spad{f} to the
+ ++ coefficients of \spad{p(x)}.
+
+ mapUnivariateIfCan: (L -> Union(K,"failed"),SUP L) -> Union(R,"failed")
+ ++ mapUnivariateIfCan(f,p(x)) applies the function \spad{f} to the
+ ++ coefficients of \spad{p(x)}, if possible, and returns
+ ++ \spad{"failed"} otherwise.
+
+ mapMatrixIfCan: (L -> Union(K,"failed"),MAT SUP L) -> Union(MAT R,"failed")
+ ++ mapMatrixIfCan(f,mat) applies the function \spad{f} to the
+ ++ coefficients of the entries of \spad{mat} if possible, and returns
+ ++ \spad{"failed"} otherwise.
+
+ mapBivariate: (K -> L,UP) -> SUP SUP L
+ ++ mapBivariate(f,p(x,y)) applies the function \spad{f} to the
+ ++ coefficients of \spad{p(x,y)}.
+
+ Implementation ==> add
+
+ mapUnivariate(f:L -> K,poly:SUP L) ==
+ ans : R := 0
+ while not zero? poly repeat
+ ans := ans + monomial(f leadingCoefficient poly,degree poly)
+ poly := reductum poly
+ ans
+
+ mapUnivariate(f:K -> L,poly:R) ==
+ ans : SUP L := 0
+ while not zero? poly repeat
+ ans := ans + monomial(f leadingCoefficient poly,degree poly)
+ poly := reductum poly
+ ans
+
+ mapUnivariateIfCan(f,poly) ==
+ ans : R := 0
+ while not zero? poly repeat
+ (lc := f leadingCoefficient poly) case "failed" => return "failed"
+ ans := ans + monomial(lc :: K,degree poly)
+ poly := reductum poly
+ ans
+
+ mapMatrixIfCan(f,mat) ==
+ m := nrows mat; n := ncols mat
+ matOut : MAT R := new(m,n,0)
+ for i in 1..m repeat for j in 1..n repeat
+ (poly := mapUnivariateIfCan(f,qelt(mat,i,j))) case "failed" =>
+ return "failed"
+ qsetelt_!(matOut,i,j,poly :: R)
+ matOut
+
+ mapBivariate(f,poly) ==
+ ans : SUP SUP L := 0
+ while not zero? poly repeat
+ ans :=
+ ans + monomial(mapUnivariate(f,leadingCoefficient poly),degree poly)
+ poly := reductum poly
+ ans
+
+@
+\section{package IBACHIN ChineseRemainderToolsForIntegralBases}
+<<package IBACHIN ChineseRemainderToolsForIntegralBases>>=
+)abbrev package IBACHIN ChineseRemainderToolsForIntegralBases
+++ Author: Clifton Williamson
+++ Date Created: 9 August 1993
+++ Date Last Updated: 3 December 1993
+++ Basic Operations: chineseRemainder, factorList
+++ Related Domains: PAdicWildFunctionFieldIntegralBasis(K,R,UP,F)
+++ Also See: WildFunctionFieldIntegralBasis, FunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, finite field, integral basis
+++ Examples:
+++ References:
+++ Description:
+
+ChineseRemainderToolsForIntegralBases(K,R,UP): Exports == Implementation where
+ K : FiniteFieldCategory
+ R : UnivariatePolynomialCategory K
+ UP : UnivariatePolynomialCategory R
+
+ DDFACT ==> DistinctDegreeFactorize
+ I ==> Integer
+ L ==> List
+ L2 ==> ListFunctions2
+ Mat ==> Matrix R
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ Q ==> Fraction R
+ SAE ==> SimpleAlgebraicExtension
+ SUP ==> SparseUnivariatePolynomial
+ SUP2 ==> SparseUnivariatePolynomialFunctions2
+ Result ==> Record(basis: Mat, basisDen: R, basisInv: Mat)
+
+ Exports ==> with
+ factorList: (K,NNI,NNI,NNI) -> L SUP K
+ ++ factorList(k,n,m,j) \undocumented
+
+ listConjugateBases: (Result,NNI,NNI) -> List Result
+ ++ listConjugateBases(bas,q,n) returns the list
+ ++ \spad{[bas,bas^Frob,bas^(Frob^2),...bas^(Frob^(n-1))]}, where
+ ++ \spad{Frob} raises the coefficients of all polynomials
+ ++ appearing in the basis \spad{bas} to the \spad{q}th power.
+
+ chineseRemainder: (List UP, List Result, NNI) -> Result
+ ++ chineseRemainder(lu,lr,n) \undocumented
+
+ Implementation ==> add
+ import ModularHermitianRowReduction(R)
+ import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+
+ applyFrobToMatrix: (Matrix R,NNI) -> Matrix R
+ applyFrobToMatrix(mat,q) ==
+ -- raises the coefficients of the polynomial entries of 'mat'
+ -- to the qth power
+ m := nrows mat; n := ncols mat
+ ans : Matrix R := new(m,n,0)
+ for i in 1..m repeat for j in 1..n repeat
+ qsetelt_!(ans,i,j,map(#1 ** q,qelt(mat,i,j)))
+ ans
+
+ listConjugateBases(bas,q,n) ==
+ outList : List Result := list bas
+ b := bas.basis; bInv := bas.basisInv; bDen := bas.basisDen
+ for i in 1..(n-1) repeat
+ b := applyFrobToMatrix(b,q)
+ bInv := applyFrobToMatrix(bInv,q)
+ bDen := map(#1 ** q,bDen)
+ newBasis : Result := [b,bDen,bInv]
+ outList := concat(newBasis,outList)
+ reverse_! outList
+
+ factorList(a,q,n,k) ==
+ coef : SUP K := monomial(a,0); xx : SUP K := monomial(1,1)
+ outList : L SUP K := list((xx - coef)**k)
+ for i in 1..(n-1) repeat
+ coef := coef ** q
+ outList := concat((xx - coef)**k,outList)
+ reverse_! outList
+
+ basisInfoToPolys: (Mat,R,R) -> L UP
+ basisInfoToPolys(mat,lcm,den) ==
+ n := nrows(mat) :: I; n1 := n - 1
+ outList : L UP := empty()
+ for i in 1..n repeat
+ pp : UP := 0
+ for j in 0..n1 repeat
+ pp := pp + monomial((lcm quo den) * qelt(mat,i,j+1),j)
+ outList := concat(pp,outList)
+ reverse_! outList
+
+ basesToPolyLists: (L Result,R) -> L L UP
+ basesToPolyLists(basisList,lcm) ==
+ [basisInfoToPolys(b.basis,lcm,b.basisDen) for b in basisList]
+
+ OUT ==> OutputForm
+
+ approximateExtendedEuclidean: (UP,UP,R,NNI) -> Record(coef1:UP,coef2:UP)
+ approximateExtendedEuclidean(f,g,p,n) ==
+ -- f and g are monic and relatively prime (mod p)
+ -- function returns [coef1,coef2] such that
+ -- coef1 * f + coef2 * g = 1 (mod p^n)
+ sae := SAE(K,R,p)
+ fSUP : SUP R := makeSUP f; gSUP : SUP R := makeSUP g
+ fBar : SUP sae := map(convert(#1)@sae,fSUP)$SUP2(R,sae)
+ gBar : SUP sae := map(convert(#1)@sae,gSUP)$SUP2(R,sae)
+ ee := extendedEuclidean(fBar,gBar)
+-- not one?(ee.generator) =>
+ not (ee.generator = 1) =>
+ error "polynomials aren't relatively prime"
+ ss1 := ee.coef1; tt1 := ee.coef2
+ s1 : SUP R := map(convert(#1)@R,ss1)$SUP2(sae,R); s := s1
+ t1 : SUP R := map(convert(#1)@R,tt1)$SUP2(sae,R); t := t1
+ pPower := p
+ for i in 2..n repeat
+ num := 1 - s * fSUP - t * gSUP
+ rhs := (num exquo pPower) :: SUP R
+ sigma := map(#1 rem p,s1 * rhs); tau := map(#1 rem p,t1 * rhs)
+ s := s + pPower * sigma; t := t + pPower * tau
+ quorem := monicDivide(s,gSUP)
+ pPower := pPower * p
+ s := map(#1 rem pPower,quorem.remainder)
+ t := map(#1 rem pPower,t + fSUP * (quorem.quotient))
+ [unmakeSUP s,unmakeSUP t]
+
+ --mapChineseToList: (L SUP Q,L SUP Q,I) -> L SUP Q
+ --mapChineseToList(list,polyList,i) ==
+ mapChineseToList: (L UP,L UP,I,R) -> L UP
+ mapChineseToList(list,polyList,i,den) ==
+ -- 'polyList' consists of MONIC polynomials
+ -- computes a polynomial p such that p = pp (modulo polyList[i])
+ -- and p = 0 (modulo polyList[j]) for j ~= i for each 'pp' in 'list'
+ -- create polynomials
+ q : UP := 1
+ for j in 1..(i-1) repeat
+ q := q * first polyList
+ polyList := rest polyList
+ p := first polyList
+ polyList := rest polyList
+ for j in (i+1).. while not empty? polyList repeat
+ q := q * first polyList
+ polyList := rest polyList
+ --p := map((numer(#1) rem den)/1, p)
+ --q := map((numer(#1) rem den)/1, q)
+ -- 'den' is a power of an irreducible polynomial
+ --!! make this computation more efficient!!
+ factoredDen := factor(den)$DDFACT(K,R)
+ prime := nthFactor(factoredDen,1)
+ n := nthExponent(factoredDen,1) :: NNI
+ invPoly := approximateExtendedEuclidean(q,p,prime,n).coef1
+ -- monicDivide may be inefficient?
+ [monicDivide(pp * invPoly * q,p * q).remainder for pp in list]
+
+ polyListToMatrix: (L UP,NNI) -> Mat
+ polyListToMatrix(polyList,n) ==
+ mat : Mat := new(n,n,0)
+ for i in 1..n for poly in polyList repeat
+ while not zero? poly repeat
+ mat(i,degree(poly) + 1) := leadingCoefficient poly
+ poly := reductum poly
+ mat
+
+ chineseRemainder(factors,factorBases,n) ==
+ denLCM : R := reduce("lcm",[base.basisDen for base in factorBases])
+ denLCM = 1 => [scalarMatrix(n,1),1,scalarMatrix(n,1)]
+ -- compute local basis polynomials with denominators cleared
+ factorBasisPolyLists := basesToPolyLists(factorBases,denLCM)
+ -- use Chinese remainder to compute basis polynomials w/o denominators
+ basisPolyLists : L L UP := empty()
+ for i in 1.. for pList in factorBasisPolyLists repeat
+ polyList := mapChineseToList(pList,factors,i,denLCM)
+ basisPolyLists := concat(polyList,basisPolyLists)
+ basisPolys := concat reverse_! basisPolyLists
+ mat := squareTop rowEchelon(polyListToMatrix(basisPolys,n),denLCM)
+ matInv := UpTriBddDenomInv(mat,denLCM)
+ [mat,denLCM,matInv]
+
+@
+\section{package PWFFINTB PAdicWildFunctionFieldIntegralBasis}
+<<package PWFFINTB PAdicWildFunctionFieldIntegralBasis>>=
+)abbrev package PWFFINTB PAdicWildFunctionFieldIntegralBasis
+++ Author: Clifton Williamson
+++ Date Created: 5 July 1993
+++ Date Last Updated: 17 August 1993
+++ Basic Operations: integralBasis, localIntegralBasis
+++ Related Domains: WildFunctionFieldIntegralBasis(K,R,UP,F)
+++ Also See: FunctionFieldIntegralBasis
+++ AMS Classifications:
+++ Keywords: function field, finite field, integral basis
+++ Examples:
+++ References:
+++ Description:
+++ In this package K is a finite field, R is a ring of univariate
+++ polynomials over K, and F is a monogenic algebra over R.
+++ We require that F is monogenic, i.e. that \spad{F = K[x,y]/(f(x,y))},
+++ because the integral basis algorithm used will factor the polynomial
+++ \spad{f(x,y)}. The package provides a function to compute the integral
+++ closure of R in the quotient field of F as well as a function to compute
+++ a "local integral basis" at a specific prime.
+
+PAdicWildFunctionFieldIntegralBasis(K,R,UP,F): Exports == Implementation where
+ K : FiniteFieldCategory
+ R : UnivariatePolynomialCategory K
+ UP : UnivariatePolynomialCategory R
+ F : MonogenicAlgebra(R,UP)
+
+ I ==> Integer
+ L ==> List
+ L2 ==> ListFunctions2
+ Mat ==> Matrix R
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ Q ==> Fraction R
+ SAE ==> SimpleAlgebraicExtension
+ SUP ==> SparseUnivariatePolynomial
+ CDEN ==> CommonDenominator
+ DDFACT ==> DistinctDegreeFactorize
+ WFFINTBS ==> WildFunctionFieldIntegralBasis
+ Result ==> Record(basis: Mat, basisDen: R, basisInv:Mat)
+ IResult ==> Record(basis: Mat, basisDen: R, basisInv:Mat,discr: R)
+ IBPTOOLS ==> IntegralBasisPolynomialTools
+ IBACHIN ==> ChineseRemainderToolsForIntegralBases
+ IRREDFFX ==> IrredPolyOverFiniteField
+ GHEN ==> GeneralHenselPackage
+
+ Exports ==> with
+ integralBasis : () -> Result
+ ++ \spad{integralBasis()} returns a record
+ ++ \spad{[basis,basisDen,basisInv] } containing information regarding
+ ++ the integral closure of R in the quotient field of the framed
+ ++ algebra F. F is a framed algebra with R-module basis
+ ++ \spad{w1,w2,...,wn}.
+ ++ If 'basis' is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of 'basis' contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix 'basisInv' contains the coordinates of \spad{wi} with respect
+ ++ to the basis \spad{v1,...,vn}: if 'basisInv' is the matrix
+ ++ \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+ localIntegralBasis : R -> Result
+ ++ \spad{integralBasis(p)} returns a record
+ ++ \spad{[basis,basisDen,basisInv] } containing information regarding
+ ++ the local integral closure of R at the prime \spad{p} in the quotient
+ ++ field of the framed algebra F. F is a framed algebra with R-module
+ ++ basis \spad{w1,w2,...,wn}.
+ ++ If 'basis' is the matrix \spad{(aij, i = 1..n, j = 1..n)}, then
+ ++ the \spad{i}th element of the local integral basis is
+ ++ \spad{vi = (1/basisDen) * sum(aij * wj, j = 1..n)}, i.e. the
+ ++ \spad{i}th row of 'basis' contains the coordinates of the
+ ++ \spad{i}th basis vector. Similarly, the \spad{i}th row of the
+ ++ matrix 'basisInv' contains the coordinates of \spad{wi} with respect
+ ++ to the basis \spad{v1,...,vn}: if 'basisInv' is the matrix
+ ++ \spad{(bij, i = 1..n, j = 1..n)}, then
+ ++ \spad{wi = sum(bij * vj, j = 1..n)}.
+ reducedDiscriminant: UP -> R
+ ++ reducedDiscriminant(up) \undocumented
+
+ Implementation ==> add
+ import IntegralBasisTools(R, UP, F)
+ import GeneralHenselPackage(R,UP)
+ import ModularHermitianRowReduction(R)
+ import TriangularMatrixOperations(R, Vector R, Vector R, Matrix R)
+
+ reducedDiscriminant f ==
+ ff : SUP Q := mapUnivariate(#1 :: Q,f)$IBPTOOLS(R,UP,SUP UP,Q)
+ ee := extendedEuclidean(ff,differentiate ff)
+ cc := concat(coefficients(ee.coef1),coefficients(ee.coef2))
+ cden := splitDenominator(cc)$CDEN(R,Q,L Q)
+ denom := cden.den
+ gg := gcd map(numer,cden.num)$L2(Q,R)
+ (ans := denom exquo gg) case "failed" =>
+ error "PWFFINTB: error in reduced discriminant computation"
+ ans :: R
+
+ compLocalBasis: (UP,R) -> Result
+ compLocalBasis(poly,prime) ==
+ -- compute a local integral basis at 'prime' for k[x,y]/(poly(x,y)).
+ sae := SAE(R,UP,poly)
+ localIntegralBasis(prime)$WFFINTBS(K,R,UP,sae)
+
+ compLocalBasisOverExt: (UP,R,UP,NNI) -> Result
+ compLocalBasisOverExt(poly0,prime0,irrPoly0,k) ==
+ -- poly0 = irrPoly0**k (mod prime0)
+ n := degree poly0; disc0 := discriminant poly0
+ (disc0 exquo prime0) case "failed" =>
+ [scalarMatrix(n,1), 1, scalarMatrix(n,1)]
+ r := degree irrPoly0
+ -- extend scalars:
+ -- construct irreducible polynomial of degree r over K
+ irrPoly := generateIrredPoly(r :: PI)$IRREDFFX(K)
+ -- construct extension of degree r over K
+ E := SAE(K,SUP K,irrPoly)
+ -- lift coefficients to elements of E
+ poly := mapBivariate(#1 :: E,poly0)$IBPTOOLS(K,R,UP,E)
+ redDisc0 := reducedDiscriminant poly0
+ redDisc := mapUnivariate(#1 :: E,redDisc0)$IBPTOOLS(K,R,UP,E)
+ prime := mapUnivariate(#1 :: E,prime0)$IBPTOOLS(K,R,UP,E)
+ sae := SAE(E,SUP E,prime)
+ -- reduction (mod prime) of polynomial of which poly is the kth power
+ redIrrPoly :=
+ pp := mapBivariate(#1 :: E,irrPoly0)$IBPTOOLS(K,R,UP,E)
+ mapUnivariate(reduce,pp)$IBPTOOLS(SUP E,SUP SUP E,SUP SUP SUP E,sae)
+ -- factor the reduction
+ factorListSAE := factors factor(redIrrPoly)$DDFACT(sae,SUP sae)
+ -- list the 'primary factors' of the reduction of poly
+ redFactors : List SUP sae := [(f.factor)**k for f in factorListSAE]
+ -- lift these factors to elements of SUP SUP E
+ primaries : List SUP SUP E :=
+ [mapUnivariate(lift,ff)$IBPTOOLS(SUP E,SUP SUP E,SUP SUP SUP E,sae) _
+ for ff in redFactors]
+ -- lift the factors to factors modulo a suitable power of 'prime'
+ deg := (1 + order(redDisc,prime) * degree(prime)) :: PI
+ henselInfo := HenselLift(poly,primaries,prime,deg)$GHEN(SUP E,SUP SUP E)
+ henselFactors := henselInfo.plist
+ psi1 := first henselFactors
+ FF := SAE(SUP E,SUP SUP E,psi1)
+ factorIb := localIntegralBasis(prime)$WFFINTBS(E,SUP E,SUP SUP E,FF)
+ bs := listConjugateBases(factorIb,size()$K,r)$IBACHIN(E,SUP E,SUP SUP E)
+ ib := chineseRemainder(henselFactors,bs,n)$IBACHIN(E,SUP E,SUP SUP E)
+ b : Matrix R :=
+ bas := mapMatrixIfCan(retractIfCan,ib.basis)$IBPTOOLS(K,R,UP,E)
+ bas case "failed" => error "retraction of basis failed"
+ bas :: Matrix R
+ bInv : Matrix R :=
+ --bas := mapMatrixIfCan(ric,ib.basisInv)$IBPTOOLS(K,R,UP,E)
+ bas := mapMatrixIfCan(retractIfCan,ib.basisInv)$IBPTOOLS(K,R,UP,E)
+ bas case "failed" => error "retraction of basis inverse failed"
+ bas :: Matrix R
+ bDen : R :=
+ p := mapUnivariateIfCan(retractIfCan,ib.basisDen)$IBPTOOLS(K,R,UP,E)
+ p case "failed" => error "retraction of basis denominator failed"
+ p :: R
+ [b,bDen,bInv]
+
+ padicLocalIntegralBasis: (UP,R,R,R) -> IResult
+ padicLocalIntegralBasis(p,disc,redDisc,prime) ==
+ -- polynomials in x modulo 'prime'
+ sae := SAE(K,R,prime)
+ -- find the factorization of 'p' modulo 'prime' and lift the
+ -- prime powers to elements of UP:
+ -- reduce 'p' modulo 'prime'
+ reducedP := mapUnivariate(reduce,p)$IBPTOOLS(R,UP,SUP UP,sae)
+ -- factor the reduced polynomial
+ factorListSAE := factors factor(reducedP)$DDFACT(sae,SUP sae)
+ -- if only one prime factor, perform usual integral basis computation
+ (# factorListSAE) = 1 =>
+ ib := localIntegralBasis(prime)$WFFINTBS(K,R,UP,F)
+ index := diagonalProduct(ib.basisInv)
+ [ib.basis,ib.basisDen,ib.basisInv,disc quo (index * index)]
+ -- list the 'prime factors' of the reduced polynomial
+ redPrimes : List SUP sae :=
+ [f.factor for f in factorListSAE]
+ -- lift these factors to elements of UP
+ primes : List UP :=
+ [mapUnivariate(lift,ff)$IBPTOOLS(R,UP,SUP UP,sae) for ff in redPrimes]
+ -- list the exponents
+ expons : List NNI := [((f.exponent) :: NNI) for f in factorListSAE]
+ -- list the 'primary factors' of the reduced polynomial
+ redPrimaries : List SUP sae :=
+ [(f.factor) **((f.exponent) :: NNI) for f in factorListSAE]
+ -- lift these factors to elements of UP
+ primaries : List UP :=
+ [mapUnivariate(lift,ff)$IBPTOOLS(R,UP,SUP UP,sae) for ff in redPrimaries]
+ -- lift the factors to factors modulo a suitable power of 'prime'
+ deg := (1 + order(redDisc,prime) * degree(prime)) :: PI
+ henselInfo := HenselLift(p,primaries,prime,deg)
+ henselFactors := henselInfo.plist
+ -- compute integral bases for the factors
+ factorBases : List Result := empty(); degPrime := degree prime
+ for pp in primes for k in expons for qq in henselFactors repeat
+ base :=
+ degPp := degree pp
+ degPp > 1 and gcd(degPp,degPrime) = 1 =>
+ compLocalBasisOverExt(qq,prime,pp,k)
+ compLocalBasis(qq,prime)
+ factorBases := concat(base,factorBases)
+ factorBases := reverse_! factorBases
+ ib := chineseRemainder(henselFactors,factorBases,rank()$F)$IBACHIN(K,R,UP)
+ index := diagonalProduct(ib.basisInv)
+ [ib.basis,ib.basisDen,ib.basisInv,disc quo (index * index)]
+
+ localIntegralBasis prime ==
+ p := definingPolynomial()$F; disc := discriminant p
+ --disc := determinant traceMatrix()$F
+ redDisc := reducedDiscriminant p
+ ib := padicLocalIntegralBasis(p,disc,redDisc,prime)
+ [ib.basis,ib.basisDen,ib.basisInv]
+
+ listSquaredFactors: R -> List R
+ listSquaredFactors px ==
+ -- returns a list of the factors of px which occur with
+ -- exponent > 1
+ ans : List R := empty()
+ factored := factor(px)$DistinctDegreeFactorize(K,R)
+ for f in factors(factored) repeat
+ if f.exponent > 1 then ans := concat(f.factor,ans)
+ ans
+
+ integralBasis() ==
+ p := definingPolynomial()$F; disc := discriminant p; n := rank()$F
+ --traceMat := traceMatrix()$F; n := rank()$F
+ --disc := determinant traceMat -- discriminant of current order
+ singList := listSquaredFactors disc -- singularities of relative Spec
+ redDisc := reducedDiscriminant p
+ runningRb := runningRbinv := scalarMatrix(n,1)$Mat
+ -- runningRb = basis matrix of current order
+ -- runningRbinv = inverse basis matrix of current order
+ -- these are wrt the original basis for F
+ runningRbden : R := 1
+ -- runningRbden = denominator for current basis matrix
+ empty? singList => [runningRb, runningRbden, runningRbinv]
+ for prime in singList repeat
+ lb := padicLocalIntegralBasis(p,disc,redDisc,prime)
+ rb := lb.basis; rbinv := lb.basisInv; rbden := lb.basisDen
+ disc := lb.discr
+ mat := vertConcat(rbden * runningRb,runningRbden * rb)
+ runningRbden := runningRbden * rbden
+ runningRb := squareTop rowEchelon(mat,runningRbden)
+ --runningRb := squareTop rowEch mat
+ runningRbinv := UpTriBddDenomInv(runningRb,runningRbden)
+ [runningRb, runningRbden, runningRbinv]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package IBPTOOLS IntegralBasisPolynomialTools>>
+<<package IBACHIN ChineseRemainderToolsForIntegralBases>>
+<<package PWFFINTB PAdicWildFunctionFieldIntegralBasis>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/paramete.spad.pamphlet b/src/algebra/paramete.spad.pamphlet
new file mode 100644
index 00000000..8cf1a256
--- /dev/null
+++ b/src/algebra/paramete.spad.pamphlet
@@ -0,0 +1,218 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra paramete.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PARPCURV ParametricPlaneCurve}
+<<domain PARPCURV ParametricPlaneCurve>>=
+)abbrev domain PARPCURV ParametricPlaneCurve
+++ Author: Clifton J. Williamson
+++ Date Created: 24 May 1990
+++ Date Last Updated: 24 May 1990
+++ Basic Operations: curve, coordinate
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: parametric curve, graphics
+++ References:
+++ Description: ParametricPlaneCurve is used for plotting parametric plane
+++ curves in the affine plane.
+
+ParametricPlaneCurve(ComponentFunction): Exports == Implementation where
+ ComponentFunction : Type
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ curve: (ComponentFunction,ComponentFunction) -> %
+ ++ curve(c1,c2) creates a plane curve from 2 component functions \spad{c1}
+ ++ and \spad{c2}.
+ coordinate: (%,NNI) -> ComponentFunction
+ ++ coordinate(c,i) returns a coordinate function for c using 1-based
+ ++ indexing according to i. This indicates what the function for the
+ ++ coordinate component i of the plane curve is.
+
+ Implementation ==> add
+
+ Rep := Record(xCoord:ComponentFunction,yCoord:ComponentFunction)
+
+ curve(x,y) == [x,y]
+ coordinate(c,n) ==
+ n = 1 => c.xCoord
+ n = 2 => c.yCoord
+ error "coordinate: index out of bounds"
+
+@
+\section{package PARPC2 ParametricPlaneCurveFunctions2}
+<<package PARPC2 ParametricPlaneCurveFunctions2>>=
+)abbrev package PARPC2 ParametricPlaneCurveFunctions2
+++ Description:
+++ This package \undocumented
+ParametricPlaneCurveFunctions2(CF1: Type, CF2:Type): with
+ map: (CF1 -> CF2, ParametricPlaneCurve(CF1)) -> ParametricPlaneCurve(CF2)
+ ++ map(f,x) \undocumented
+ == add
+ map(f, c) == curve(f coordinate(c,1), f coordinate(c, 2))
+
+@
+\section{domain PARSCURV ParametricSpaceCurve}
+<<domain PARSCURV ParametricSpaceCurve>>=
+)abbrev domain PARSCURV ParametricSpaceCurve
+++ Author: Clifton J. Williamson
+++ Date Created: 24 May 1990
+++ Date Last Updated: 24 May 1990
+++ Basic Operations: curve, coordinate
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: parametric curve, graphics
+++ References:
+++ Description: ParametricSpaceCurve is used for plotting parametric space
+++ curves in affine 3-space.
+
+ParametricSpaceCurve(ComponentFunction): Exports == Implementation where
+ ComponentFunction : Type
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ curve: (ComponentFunction,ComponentFunction,ComponentFunction) -> %
+ ++ curve(c1,c2,c3) creates a space curve from 3 component functions
+ ++ \spad{c1}, \spad{c2}, and \spad{c3}.
+ coordinate: (%,NNI) -> ComponentFunction
+ ++ coordinate(c,i) returns a coordinate function of c using 1-based
+ ++ indexing according to i. This indicates what the function for the
+ ++ coordinate component, i, of the space curve is.
+
+ Implementation ==> add
+
+ Rep := Record(xCoord:ComponentFunction,_
+ yCoord:ComponentFunction,_
+ zCoord:ComponentFunction)
+
+ curve(x,y,z) == [x,y,z]
+ coordinate(c,n) ==
+ n = 1 => c.xCoord
+ n = 2 => c.yCoord
+ n = 3 => c.zCoord
+ error "coordinate: index out of bounds"
+
+@
+\section{package PARSC2 ParametricSpaceCurveFunctions2}
+<<package PARSC2 ParametricSpaceCurveFunctions2>>=
+)abbrev package PARSC2 ParametricSpaceCurveFunctions2
+++ Description:
+++ This package \undocumented
+ParametricSpaceCurveFunctions2(CF1: Type, CF2:Type): with
+ map: (CF1 -> CF2, ParametricSpaceCurve(CF1)) -> ParametricSpaceCurve(CF2)
+ ++ map(f,x) \undocumented
+ == add
+ map(f, c) == curve(f coordinate(c,1), f coordinate(c,2), f coordinate(c,3))
+
+@
+\section{domain PARSURF ParametricSurface}
+<<domain PARSURF ParametricSurface>>=
+)abbrev domain PARSURF ParametricSurface
+++ Author: Clifton J. Williamson
+++ Date Created: 24 May 1990
+++ Date Last Updated: 24 May 1990
+++ Basic Operations: surface, coordinate
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: parametric surface, graphics
+++ References:
+++ Description: ParametricSurface is used for plotting parametric surfaces in
+++ affine 3-space.
+
+ParametricSurface(ComponentFunction): Exports == Implementation where
+ ComponentFunction : Type
+ NNI ==> NonNegativeInteger
+
+ Exports ==> with
+ surface: (ComponentFunction,ComponentFunction,ComponentFunction) -> %
+ ++ surface(c1,c2,c3) creates a surface from 3 parametric component
+ ++ functions \spad{c1}, \spad{c2}, and \spad{c3}.
+ coordinate: (%,NNI) -> ComponentFunction
+ ++ coordinate(s,i) returns a coordinate function of s using 1-based
+ ++ indexing according to i. This indicates what the function for the
+ ++ coordinate component, i, of the surface is.
+
+ Implementation ==> add
+
+ Rep := Record(xCoord:ComponentFunction,_
+ yCoord:ComponentFunction,_
+ zCoord:ComponentFunction)
+
+ surface(x,y,z) == [x,y,z]
+ coordinate(c,n) ==
+ n = 1 => c.xCoord
+ n = 2 => c.yCoord
+ n = 3 => c.zCoord
+ error "coordinate: index out of bounds"
+
+@
+\section{package PARSU2 ParametricSurfaceFunctions2}
+<<package PARSU2 ParametricSurfaceFunctions2>>=
+)abbrev package PARSU2 ParametricSurfaceFunctions2
+++ Description:
+++ This package \undocumented
+ParametricSurfaceFunctions2(CF1: Type, CF2:Type): with
+ map: (CF1 -> CF2, ParametricSurface(CF1)) -> ParametricSurface(CF2)
+ ++ map(f,x) \undocumented
+ == add
+ map(f, c) == surface(f coordinate(c,1), f coordinate(c,2), f coordinate(c,3))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PARPCURV ParametricPlaneCurve>>
+<<package PARPC2 ParametricPlaneCurveFunctions2>>
+<<domain PARSCURV ParametricSpaceCurve>>
+<<package PARSC2 ParametricSpaceCurveFunctions2>>
+<<domain PARSURF ParametricSurface>>
+<<package PARSU2 ParametricSurfaceFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/partperm.spad.pamphlet b/src/algebra/partperm.spad.pamphlet
new file mode 100644
index 00000000..cbe68098
--- /dev/null
+++ b/src/algebra/partperm.spad.pamphlet
@@ -0,0 +1,168 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra partperm.spad}
+\author{William Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PARTPERM PartitionsAndPermutations}
+<<package PARTPERM PartitionsAndPermutations>>=
+)abbrev package PARTPERM PartitionsAndPermutations
+++ Author: William H. Burge
+++ Date Created: 29 October 1987
+++ Date Last Updated: 3 April 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: partition, permutation
+++ References:
+++ Description: PartitionsAndPermutations contains
+++ functions for generating streams of integer partitions,
+++ and streams of sequences of integers
+++ composed from a multi-set.
+PartitionsAndPermutations: Exports == Implementation where
+ I ==> Integer
+ L ==> List
+ ST ==> Stream
+ ST1 ==> StreamFunctions1
+ ST2 ==> StreamFunctions2
+ ST3 ==> StreamFunctions3
+
+ Exports ==> with
+
+ partitions: (I,I,I) -> ST L I
+ ++\spad{partitions(p,l,n)} is the stream of partitions
+ ++ of n whose number of parts is no greater than p
+ ++ and whose largest part is no greater than l.
+ partitions: I -> ST L I
+ ++\spad{partitions(n)} is the stream of all partitions of n.
+ partitions: (I,I) -> ST L I
+ ++\spad{partitions(p,l)} is the stream of all
+ ++ partitions whose number of
+ ++ parts and largest part are no greater than p and l.
+ conjugate: L I -> L I
+ ++\spad{conjugate(pt)} is the conjugate of the partition pt.
+ conjugates: ST L I -> ST L I
+ ++\spad{conjugates(lp)} is the stream of conjugates of a stream
+ ++ of partitions lp.
+ shuffle: (L I,L I) -> ST L I
+ ++\spad{shuffle(l1,l2)} forms the stream of all shuffles of l1
+ ++ and l2, i.e. all sequences that can be formed from
+ ++ merging l1 and l2.
+ shufflein: (L I,ST L I) -> ST L I
+ ++\spad{shufflein(l,st)} maps shuffle(l,u) on to all
+ ++ members u of st, concatenating the results.
+ sequences: (L I,L I) -> ST L I
+ ++\spad{sequences(l1,l2)} is the stream of all sequences that
+ ++ can be composed from the multiset defined from
+ ++ two lists of integers l1 and l2.
+ ++ For example,the pair \spad{([1,2,4],[2,3,5])} represents
+ ++ multi-set with 1 \spad{2}, 2 \spad{3}'s, and 4 \spad{5}'s.
+ sequences: L I -> ST L I
+ ++ \spad{sequences([l0,l1,l2,..,ln])} is the set of
+ ++ all sequences formed from
+ ++ \spad{l0} 0's,\spad{l1} 1's,\spad{l2} 2's,...,\spad{ln} n's.
+ permutations: I -> ST L I
+ ++\spad{permutations(n)} is the stream of permutations
+ ++ formed from \spad{1,2,3,...,n}.
+
+ Implementation ==> add
+
+ partitions(M,N,n) ==
+ zero? n => concat(empty()$L(I),empty()$(ST L I))
+ zero? M or zero? N or n < 0 => empty()
+ c := map(concat(N,#1),partitions(M - 1,N,n - N))
+ concat(c,partitions(M,N - 1,n))
+
+ partitions n == partitions(n,n,n)
+
+ partitions(M,N)==
+ aaa : L ST L I := [partitions(M,N,i) for i in 0..M*N]
+ concat(aaa :: ST ST L I)$ST1(L I)
+
+ -- nogreq(n,l) is the number of elements of l that are greater or
+ -- equal to n
+ nogreq: (I,L I) -> I
+ nogreq(n,x) == +/[1 for i in x | i >= n]
+
+ conjugate x ==
+ empty? x => empty()
+ [nogreq(i,x) for i in 1..first x]
+
+ conjugates z == map(conjugate,z)
+
+ shuffle(x,y)==
+ empty? x => concat(y,empty())$(ST L I)
+ empty? y => concat(x,empty())$(ST L I)
+ concat(map(concat(first x,#1),shuffle(rest x,y)),_
+ map(concat(first y,#1),shuffle(x,rest y)))
+
+ shufflein(x,yy) ==
+ concat(map(shuffle(x,#1),yy)$ST2(L I,ST L I))$ST1(L I)
+
+ -- rpt(n,m) is the list of n m's
+ rpt: (I,I) -> L I
+ rpt(n,m) == [m for i in 1..n]
+
+ -- zrpt(x,y) where x is [x0,x1,x2...] and y is [y0,y1,y2...]
+ -- is the stream [rpt(x0,y0),rpt(x1,y1),...]
+ zrpt: (L I,L I) -> ST L I
+ zrpt(x,y) == map(rpt,x :: ST I,y :: ST I)$ST3(I,I,L I)
+
+ sequences(x,y) ==
+ reduce(concat(empty()$L(I),empty()$(ST L I)),_
+ shufflein,zrpt(x,y))$ST2(L I,ST L I)
+
+ sequences x == sequences(x,[i for i in 0..#x-1])
+
+ permutations n == sequences(rpt(n,1),[i for i in 1..n])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PARTPERM PartitionsAndPermutations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/patmatch1.spad.pamphlet b/src/algebra/patmatch1.spad.pamphlet
new file mode 100644
index 00000000..381bbf30
--- /dev/null
+++ b/src/algebra/patmatch1.spad.pamphlet
@@ -0,0 +1,712 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra patmatch1.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PATRES PatternMatchResult}
+<<domain PATRES PatternMatchResult>>=
+)abbrev domain PATRES PatternMatchResult
+++ Result returned by the pattern matcher
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 5 Jul 1990
+++ Description:
+++ A PatternMatchResult is an object internally returned by the
+++ pattern matcher; It is either a failed match, or a list of
+++ matches of the form (var, expr) meaning that the variable var
+++ matches the expression expr.
+++ Keywords: pattern, matching.
+-- not exported
+PatternMatchResult(R:SetCategory, S:SetCategory): SetCategory with
+ failed? : % -> Boolean
+ ++ failed?(r) tests if r is a failed match.
+ failed : () -> %
+ ++ failed() returns a failed match.
+ new : () -> %
+ ++ new() returns a new empty match result.
+ union : (%, %) -> %
+ ++ union(a, b) makes the set-union of two match results.
+ getMatch : (Pattern R, %) -> Union(S, "failed")
+ ++ getMatch(var, r) returns the expression that var matches
+ ++ in the result r, and "failed" if var is not matched in r.
+ addMatch : (Pattern R, S, %) -> %
+ ++ addMatch(var, expr, r) adds the match (var, expr) in r,
+ ++ provided that expr satisfies the predicates attached to var,
+ ++ and that var is not matched to another expression already.
+ insertMatch : (Pattern R, S, %) -> %
+ ++ insertMatch(var, expr, r) adds the match (var, expr) in r,
+ ++ without checking predicates or previous matches for var.
+ addMatchRestricted: (Pattern R, S, %, S) -> %
+ ++ addMatchRestricted(var, expr, r, val) adds the match
+ ++ (var, expr) in r,
+ ++ provided that expr satisfies the predicates attached to var,
+ ++ that var is not matched to another expression already,
+ ++ and that either var is an optional pattern variable or that
+ ++ expr is not equal to val (usually an identity).
+ destruct : % -> List Record(key:Symbol, entry:S)
+ ++ destruct(r) returns the list of matches (var, expr) in r.
+ ++ Error: if r is a failed match.
+ construct : List Record(key:Symbol, entry:S) -> %
+ ++ construct([v1,e1],...,[vn,en]) returns the match result
+ ++ containing the matches (v1,e1),...,(vn,en).
+ satisfy? : (%, Pattern R) -> Union(Boolean, "failed")
+ ++ satisfy?(r, p) returns true if the matches satisfy the
+ ++ top-level predicate of p, false if they don't, and "failed"
+ ++ if not enough variables of p are matched in r to decide.
+
+ == add
+ LR ==> AssociationList(Symbol, S)
+
+ import PatternFunctions1(R, S)
+
+ Rep := Union(LR, "failed")
+
+ new() == empty()
+ failed() == "failed"
+ failed? x == x case "failed"
+ insertMatch(p, x, l) == concat([retract p, x], l::LR)
+ construct l == construct(l)$LR
+ destruct l == entries(l::LR)$LR
+
+-- returns "failed" if not all the variables of the pred. are matched
+ satisfy?(r, p) ==
+ failed? r => false
+ lr := r::LR
+ lv := [if (u := search(v, lr)) case "failed" then return "failed"
+ else u::S for v in topPredicate(p).var]$List(S)
+ satisfy?(lv, p)
+
+ union(x, y) ==
+ failed? x or failed? y => failed()
+ removeDuplicates concat(x::LR, y::LR)
+
+ x = y ==
+ failed? x => failed? y
+ failed? y => false
+ x::LR =$LR y::LR
+
+ coerce(x:%):OutputForm ==
+ failed? x => "Does not match"::OutputForm
+ destruct(x)::OutputForm
+
+ addMatchRestricted(p, x, l, ident) ==
+ (not optional? p) and (x = ident) => failed()
+ addMatch(p, x, l)
+
+ addMatch(p, x, l) ==
+ failed?(l) or not(satisfy?(x, p)) => failed()
+ al := l::LR
+ sy := retract(p)@Symbol
+ (r := search(sy, al)) case "failed" => insertMatch(p, x, l)
+ r::S = x => l
+ failed()
+
+ getMatch(p, l) ==
+ failed? l => "failed"
+ search(retract(p)@Symbol, l::LR)
+
+@
+\section{package PATRES2 PatternMatchResultFunctions2}
+<<package PATRES2 PatternMatchResultFunctions2>>=
+)abbrev package PATRES2 PatternMatchResultFunctions2
+++ Lifts maps to pattern matching results
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1989
+++ Date Last Updated: 14 Dec 1989
+++ Description: Lifts maps to pattern matching results.
+++ Keywords: pattern, matching.
+PatternMatchResultFunctions2(R, A, B): Exports == Implementation where
+ R: SetCategory
+ A: SetCategory
+ B: SetCategory
+
+ Exports ==> with
+ map: (A -> B, PatternMatchResult(R, A)) -> PatternMatchResult(R, B)
+ ++ map(f, [(v1,a1),...,(vn,an)]) returns the matching result
+ ++ [(v1,f(a1)),...,(vn,f(an))].
+
+ Implementation ==> add
+ map(f, r) ==
+ failed? r => failed()
+ construct [[rec.key, f(rec.entry)] for rec in destruct r]
+
+@
+\section{domain PATLRES PatternMatchListResult}
+<<domain PATLRES PatternMatchListResult>>=
+)abbrev domain PATLRES PatternMatchListResult
+++ Result returned by the pattern matcher when using lists
+++ Author: Manuel Bronstein
+++ Date Created: 4 Dec 1989
+++ Date Last Updated: 4 Dec 1989
+++ Description:
+++ A PatternMatchListResult is an object internally returned by the
+++ pattern matcher when matching on lists.
+++ It is either a failed match, or a pair of PatternMatchResult,
+++ one for atoms (elements of the list), and one for lists.
+++ Keywords: pattern, matching, list.
+-- not exported
+PatternMatchListResult(R:SetCategory, S:SetCategory, L:ListAggregate S):
+ SetCategory with
+ failed? : % -> Boolean
+ ++ failed?(r) tests if r is a failed match.
+ failed : () -> %
+ ++ failed() returns a failed match.
+ new : () -> %
+ ++ new() returns a new empty match result.
+ makeResult: (PatternMatchResult(R,S), PatternMatchResult(R,L)) -> %
+ ++ makeResult(r1,r2) makes the combined result [r1,r2].
+ atoms : % -> PatternMatchResult(R, S)
+ ++ atoms(r) returns the list of matches that match atoms
+ ++ (elements of the lists).
+ lists : % -> PatternMatchResult(R, L)
+ ++ lists(r) returns the list of matches that match lists.
+ == add
+ Rep := Record(a:PatternMatchResult(R, S), l:PatternMatchResult(R, L))
+
+ new() == [new(), new()]
+ atoms r == r.a
+ lists r == r.l
+ failed() == [failed(), failed()]
+ failed? r == failed?(atoms r)
+ x = y == (atoms x = atoms y) and (lists x = lists y)
+
+ makeResult(r1, r2) ==
+ failed? r1 or failed? r2 => failed()
+ [r1, r2]
+
+ coerce(r:%):OutputForm ==
+ failed? r => atoms(r)::OutputForm
+ RecordPrint(r, Rep)$Lisp
+
+@
+\section{category PATMAB PatternMatchable}
+<<category PATMAB PatternMatchable>>=
+)abbrev category PATMAB PatternMatchable
+++ Category of sets that can be pattern-matched on
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 15 Mar 1990
+++ Description:
+++ A set R is PatternMatchable over S if elements of R can
+++ be matched to patterns over S.
+++ Keywords: pattern, matching.
+PatternMatchable(S:SetCategory): Category == SetCategory with
+ patternMatch: (%, Pattern S, PatternMatchResult(S, %)) ->
+ PatternMatchResult(S, %)
+ ++ patternMatch(expr, pat, res) matches the pattern pat to the
+ ++ expression expr. res contains the variables of pat which
+ ++ are already matched and their matches (necessary for recursion).
+ ++ Initially, res is just the result of \spadfun{new}
+ ++ which is an empty list of matches.
+
+@
+\section{category FPATMAB FullyPatternMatchable}
+<<category FPATMAB FullyPatternMatchable>>=
+)abbrev category FPATMAB FullyPatternMatchable
+++ Category of sets that can be pattern-matched on
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 29 Nov 1989
+++ Description:
+++ A set S is PatternMatchable over R if S can lift the
+++ pattern-matching functions of S over the integers and float
+++ to itself (necessary for matching in towers).
+++ Keywords: pattern, matching.
+FullyPatternMatchable(R:Type): Category == Type with
+ if R has PatternMatchable Integer then PatternMatchable Integer
+ if R has PatternMatchable Float then PatternMatchable Float
+
+@
+\section{package PMSYM PatternMatchSymbol}
+<<package PMSYM PatternMatchSymbol>>=
+)abbrev package PMSYM PatternMatchSymbol
+++ Pattern matching on symbols
+++ Author: Manuel Bronstein
+++ Date Created: 9 Jan 1990
+++ Date Last Updated: 20 June 1991
+++ Description:
+++ This package provides pattern matching functions on symbols.
+++ Keywords: pattern, matching, symbol.
+PatternMatchSymbol(S:SetCategory): with
+ patternMatch: (Symbol, Pattern S, PatternMatchResult(S, Symbol)) ->
+ PatternMatchResult(S, Symbol)
+ ++ patternMatch(expr, pat, res) matches the pattern pat to the
+ ++ expression expr; res contains the variables of pat which
+ ++ are already matched and their matches (necessary for recursion).
+ == add
+ import TopLevelPatternMatchControl
+
+ patternMatch(s, p, l) ==
+ generic? p => addMatch(p, s, l)
+ constant? p =>
+ ((u := retractIfCan(p)@Union(Symbol, "failed")) case Symbol)
+ and (u::Symbol) = s => l
+ failed()
+ failed()
+
+@
+\section{package PMKERNEL PatternMatchKernel}
+<<package PMKERNEL PatternMatchKernel>>=
+)abbrev package PMKERNEL PatternMatchKernel
+++ Pattern matching on kernels
+++ Author: Manuel Bronstein
+++ Date Created: 12 Jan 1990
+++ Date Last Updated: 4 May 1992
+++ Description:
+++ This package provides pattern matching functions on kernels.
+++ Keywords: pattern, matching, kernel.
+PatternMatchKernel(S, E): Exports == Implementation where
+ S: SetCategory
+ E: Join(OrderedSet, RetractableTo Kernel %,
+ ConvertibleTo Pattern S, PatternMatchable S)
+
+ PAT ==> Pattern S
+ PRS ==> PatternMatchResult(S, E)
+ POWER ==> "%power"::Symbol
+ NTHRT ==> "nthRoot"::Symbol
+
+ Exports ==> with
+ patternMatch: (Kernel E, PAT, PRS) -> PRS
+ ++ patternMatch(f(e1,...,en), pat, res) matches the pattern pat
+ ++ to \spad{f(e1,...,en)}; res contains the variables of pat which
+ ++ are already matched and their matches.
+
+ Implementation ==> add
+ patternMatchArg : (List E, List PAT, PRS) -> PRS
+ patternMatchInner: (Kernel E, PAT, PRS) -> Union(PRS, "failed")
+
+ -- matches the ordered lists ls and lp.
+ patternMatchArg(ls, lp, l) ==
+ #ls ^= #lp => failed()
+ for p in lp for s in ls repeat
+ generic? p and failed?(l := addMatch(p,s,l)) => return failed()
+ for p in lp for s in ls repeat
+ not(generic? p) and failed?(l := patternMatch(s, p, l)) =>
+ return failed()
+ l
+
+ patternMatchInner(s, p, l) ==
+ generic? p => addMatch(p, s::E, l)
+ (u := isOp p) case Record(op:BasicOperator, arg: List PAT) =>
+ ur := u::Record(op:BasicOperator, arg: List PAT)
+ ur.op = operator s => patternMatchArg(argument s, ur.arg, l)
+ failed()
+ constant? p =>
+ ((v := retractIfCan(p)@Union(Symbol, "failed")) case Symbol)
+ and ((w := symbolIfCan s) case Symbol) and
+ (v::Symbol = w::Symbol) => l
+ failed()
+ "failed"
+
+ if E has Monoid then
+ patternMatchMonoid: (Kernel E, PAT, PRS) -> Union(PRS, "failed")
+ patternMatchOpt : (E, List PAT, PRS, E) -> PRS
+
+ patternMatchOpt(x, lp, l, id) ==
+ (u := optpair lp) case List(PAT) =>
+ failed?(l := addMatch(first(u::List(PAT)), id, l)) => failed()
+ patternMatch(x, second(u::List(PAT)), l)
+ failed()
+
+ patternMatchMonoid(s, p, l) ==
+ (u := patternMatchInner(s, p, l)) case PRS => u::PRS
+ (v := isPower p) case Record(val:PAT, exponent:PAT) =>
+ vr := v::Record(val:PAT, exponent: PAT)
+ is?(op := operator s, POWER) =>
+ patternMatchArg(argument s, [vr.val, vr.exponent], l)
+ is?(op,NTHRT) and ((r := recip(second(arg := argument s))) case E) =>
+ patternMatchArg([first arg, r::E], [vr.val, vr.exponent], l)
+ optional?(vr.exponent) =>
+ failed?(l := addMatch(vr.exponent, 1, l)) => failed()
+ patternMatch(s::E, vr.val, l)
+ failed()
+ (w := isTimes p) case List(PAT) =>
+ patternMatchOpt(s::E, w::List(PAT), l, 1)
+ "failed"
+
+ if E has AbelianMonoid then
+ patternMatch(s, p, l) ==
+ (u := patternMatchMonoid(s, p, l)) case PRS => u::PRS
+ (w := isPlus p) case List(PAT) =>
+ patternMatchOpt(s::E, w::List(PAT), l, 0)
+ failed()
+
+ else
+ patternMatch(s, p, l) ==
+ (u := patternMatchMonoid(s, p, l)) case PRS => u::PRS
+ failed()
+
+ else
+ patternMatch(s, p, l) ==
+ (u := patternMatchInner(s, p, l)) case PRS => u::PRS
+ failed()
+
+@
+\section{package PMDOWN PatternMatchPushDown}
+<<package PMDOWN PatternMatchPushDown>>=
+)abbrev package PMDOWN PatternMatchPushDown
+++ Pattern matching in towers
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1989
+++ Date Last Updated: 16 August 1995
+++ Description:
+++ This packages provides tools for matching recursively
+++ in type towers.
+++ Keywords: pattern, matching, quotient, field.
+PatternMatchPushDown(S, A, B): Exports == Implementation where
+ S: SetCategory
+ A: PatternMatchable S
+ B: Join(SetCategory, RetractableTo A)
+
+ PAT ==> Pattern S
+ PRA ==> PatternMatchResult(S, A)
+ PRB ==> PatternMatchResult(S, B)
+ REC ==> Record(pat:PAT, res:PRA)
+
+ Exports ==> with
+ fixPredicate: (B -> Boolean) -> (A -> Boolean)
+ ++ fixPredicate(f) returns g defined by g(a) = f(a::B);
+ patternMatch: (A, PAT, PRB) -> PRB
+ ++ patternMatch(expr, pat, res) matches the pattern pat to the
+ ++ expression expr; res contains the variables of pat which
+ ++ are already matched and their matches.
+ ++ Note: this function handles type towers by changing the predicates
+ ++ and calling the matching function provided by \spad{A}.
+
+ Implementation ==> add
+ import PatternMatchResultFunctions2(S, A, B)
+
+ fixPred : Any -> Union(Any, "failed")
+ inA : (PAT, PRB) -> Union(List A, "failed")
+ fixPredicates: (PAT, PRB, PRA) -> Union(REC, "failed")
+ fixList:(List PAT -> PAT, List PAT, PRB, PRA) -> Union(REC,"failed")
+
+ fixPredicate f == f(#1::B)
+
+ patternMatch(a, p, l) ==
+ (u := fixPredicates(p, l, new())) case "failed" => failed()
+ union(l, map(#1::B, patternMatch(a, (u::REC).pat, (u::REC).res)))
+
+ inA(p, l) ==
+ (u := getMatch(p, l)) case "failed" => empty()
+ (r := retractIfCan(u::B)@Union(A, "failed")) case A => [r::A]
+ "failed"
+
+ fixList(fn, l, lb, la) ==
+ ll:List(PAT) := empty()
+ for x in l repeat
+ (f := fixPredicates(x, lb, la)) case "failed" => return "failed"
+ ll := concat((f::REC).pat, ll)
+ la := (f::REC).res
+ [fn ll, la]
+
+ fixPred f ==
+ (u:= retractIfCan(f)$AnyFunctions1(B -> Boolean)) case "failed" =>
+ "failed"
+ g := fixPredicate(u::(B -> Boolean))
+ coerce(g)$AnyFunctions1(A -> Boolean)
+
+ fixPredicates(p, lb, la) ==
+ (r:=retractIfCan(p)@Union(S,"failed")) case S or quoted? p =>[p,la]
+ (u := isOp p) case Record(op:BasicOperator, arg:List PAT) =>
+ ur := u::Record(op:BasicOperator, arg:List PAT)
+ fixList((ur.op) #1, ur.arg, lb, la)
+ (us := isPlus p) case List(PAT) =>
+ fixList(reduce("+", #1), us::List(PAT), lb, la)
+ (us := isTimes p) case List(PAT) =>
+ fixList(reduce("*", #1), us::List(PAT), lb, la)
+ (v := isQuotient p) case Record(num:PAT, den:PAT) =>
+ vr := v::Record(num:PAT, den:PAT)
+ (fn := fixPredicates(vr.num, lb, la)) case "failed" => "failed"
+ la := (fn::REC).res
+ (fd := fixPredicates(vr.den, lb, la)) case "failed" => "failed"
+ [(fn::REC).pat / (fd::REC).pat, (fd::REC).res]
+ (w:= isExpt p) case Record(val:PAT,exponent:NonNegativeInteger) =>
+ wr := w::Record(val:PAT, exponent: NonNegativeInteger)
+ (f := fixPredicates(wr.val, lb, la)) case "failed" => "failed"
+ [(f::REC).pat ** wr.exponent, (f::REC).res]
+ (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+ uur := uu::Record(val:PAT, exponent: PAT)
+ (fv := fixPredicates(uur.val, lb, la)) case "failed" => "failed"
+ la := (fv::REC).res
+ (fe := fixPredicates(uur.exponent, lb, la)) case "failed" =>
+ "failed"
+ [(fv::REC).pat ** (fe::REC).pat, (fe::REC).res]
+ generic? p =>
+ (ua := inA(p, lb)) case "failed" => "failed"
+ lp := [if (h := fixPred g) case Any then h::Any else
+ return "failed" for g in predicates p]$List(Any)
+ q := setPredicates(patternVariable(retract p, constant? p,
+ optional? p, multiple? p), lp)
+ [q, (empty?(ua::List A) => la; insertMatch(q,first(ua::List A), la))]
+ error "Should not happen"
+
+@
+\section{package PMTOOLS PatternMatchTools}
+<<package PMTOOLS PatternMatchTools>>=
+)abbrev package PMTOOLS PatternMatchTools
+++ Tools for the pattern matcher
+++ Author: Manuel Bronstein
+++ Date Created: 13 Mar 1990
+++ Date Last Updated: 4 February 1992
+++ Description:
+++ This package provides tools for the pattern matcher.
+++ Keywords: pattern, matching, tools.
+PatternMatchTools(S, R, P): Exports == Implementation where
+ S: SetCategory
+ R: Join(Ring, OrderedSet)
+ P: Join(Ring, ConvertibleTo Pattern S, RetractableTo R)
+
+ PAT ==> Pattern S
+ PRS ==> PatternMatchResult(S, P)
+ REC ==> Record(res:PRS, s:List P)
+ RC ==> Record(pat:List PAT, s:List P)
+
+ Exports ==> with
+ patternMatch: (List P, List PAT, List P -> P, PRS,
+ (P, PAT, PRS) -> PRS) -> PRS
+ ++ patternMatch(lsubj, lpat, op, res, match) matches the list
+ ++ of patterns lpat to the list of subjects lsubj, allowing for
+ ++ commutativity; op is the operator such that op(lpat) should
+ ++ match op(lsubj) at the end, r contains the previous matches,
+ ++ and match is a pattern-matching function on P.
+ patternMatchTimes: (List P, List PAT, PRS,
+ (P, PAT, PRS) -> PRS) -> PRS
+ ++ patternMatchTimes(lsubj, lpat, res, match) matches the
+ ++ product of patterns \spad{reduce(*,lpat)}
+ ++ to the product of subjects \spad{reduce(*,lsubj)};
+ ++ r contains the previous matches
+ ++ and match is a pattern-matching function on P.
+
+ Implementation ==> add
+ import PatternFunctions1(S, P)
+
+ preprocessList: (PAT, List P, PRS) -> Union(List P, "failed")
+ selBestGen : List PAT -> List PAT
+ negConstant : List P -> Union(P, "failed")
+ findMatch : (PAT, List P, PRS, P, (P, PAT, PRS) -> PRS) -> REC
+ tryToMatch : (List PAT, REC, P, (P, PAT, PRS) -> PRS) ->
+ Union(REC, "failed")
+ filterMatchedPatterns: (List PAT, List P, PRS) -> Union(RC, "failed")
+
+ mn1 := convert(-1::P)@Pattern(S)
+
+ negConstant l ==
+ for x in l repeat
+ ((r := retractIfCan(x)@Union(R, "failed")) case R) and
+ (r::R < 0) => return x
+ "failed"
+
+-- tries to match the list of patterns lp to the list of subjects rc.s
+-- with rc.res being the list of existing matches.
+-- updates rc with the new result and subjects still to match
+ tryToMatch(lp, rc, ident, pmatch) ==
+ rec:REC := [l := rc.res, ls := rc.s]
+ for p in lp repeat
+ rec := findMatch(p, ls, l, ident, pmatch)
+ failed?(l := rec.res) => return "failed"
+ ls := rec.s
+ rec
+
+-- handles -1 in the pattern list.
+ patternMatchTimes(ls, lp, l, pmatch) ==
+ member?(mn1, lp) =>
+ (u := negConstant ls) case "failed" => failed()
+ if (u::P ^= -1::P) then ls := concat(-u::P, ls)
+ patternMatch(remove(u::P,ls), remove(mn1,lp), */#1, l, pmatch)
+ patternMatch(ls, lp, */#1, l, pmatch)
+
+-- finds a match for p in ls, try not to match to a "bad" value
+ findMatch(p, ls, l, ident, pmatch) ==
+ bad:List(P) :=
+ generic? p => setIntersection(badValues p, ls)
+ empty()
+ l1:PRS := failed()
+ for x in setDifference(ls, bad)
+ while (t := x; failed?(l1 := pmatch(x, p, l))) repeat 0
+ failed? l1 =>
+ for x in bad
+ while (t := x; failed?(l1 := pmatch(x, p, l))) repeat 0
+ failed? l1 => [addMatchRestricted(p, ident, l, ident), ls]
+ [l1, remove(t, ls)]
+ [l1, remove(t, ls)]
+
+-- filters out pattern if it's generic and already matched.
+ preprocessList(pattern, ls, l) ==
+ generic? pattern =>
+ (u := getMatch(pattern, l)) case P =>
+ member?(u::P, ls) => [u::P]
+ "failed"
+ empty()
+ empty()
+
+-- take out already matched generic patterns
+ filterMatchedPatterns(lp, ls, l) ==
+ for p in lp repeat
+ (rc := preprocessList(p, ls, l)) case "failed" => return "failed"
+ if not empty?(rc::List(P)) then
+ lp := remove(p, lp)
+ ls := remove(first(rc::List(P)), ls)
+ [lp, ls]
+
+-- select a generic pattern with no predicate if possible
+ selBestGen l ==
+ ans := empty()$List(PAT)
+ for p in l | generic? p repeat
+ ans := [p]
+ not hasPredicate? p => return ans
+ ans
+
+-- matches unordered lists ls and lp
+ patternMatch(ls, lp, op, l, pmatch) ==
+ ident := op empty()
+ (rc := filterMatchedPatterns(lp, ls, l)) case "failed" => return failed()
+ lp := (rc::RC).pat
+ ls := (rc::RC).s
+ empty? lp => l
+ #(lpm := select(optional?, lp)) > 1 =>
+ error "More than one optional pattern in sum/product"
+ (#ls + #lpm) < #lp => failed()
+ if (not empty? lpm) and (#ls + 1 = #lp) then
+ lp := remove(first lpm, lp)
+ failed?(l := addMatch(first lpm, ident, l)) => return l
+ #(lpm := select(multiple?, lp)) > 1 =>
+ error "More than one expandable pattern in sum/product"
+ #ls > #lp and empty? lpm and empty?(lpm := selBestGen lp) =>
+ failed()
+ if not empty? lpm then lp := remove(first lpm, lp)
+ -- this is the order in which we try to match predicates
+ -- l1 = constant patterns (i.e. 'x, or sin('x))
+ l1 := select(constant?, lp)
+ -- l2 = patterns with a predicate attached to them
+ l2 := select(hasPredicate? #1 and not constant? #1, lp)
+ -- l3 = non-generic patterns without predicates
+ l3 := sort_!(depth(#1) > depth(#2),
+ select(not(hasPredicate? #1 or generic? #1 or constant? #1),lp))
+ -- l4 = generic patterns with predicates
+ l4 := select(generic? #1 and
+ not(hasPredicate? #1 or constant? #1), lp)
+ rec:REC := [l, ls]
+ (u := tryToMatch(l1, rec, ident, pmatch)) case "failed" =>
+ failed()
+ (u := tryToMatch(l2, u::REC, ident, pmatch)) case "failed" =>
+ failed()
+ (u := tryToMatch(l3, u::REC, ident, pmatch)) case "failed" =>
+ failed()
+ rec := u::REC
+ (rc := filterMatchedPatterns(l4,rec.s,rec.res)) case "failed" => failed()
+ rec := [rec.res, (rc::RC).s]
+ (u := tryToMatch((rc::RC).pat,rec,ident,pmatch)) case "failed" => failed()
+ rec := u::REC
+ l := rec.res
+ ls := rec.s
+ empty? lpm =>
+ empty? ls => l
+ failed()
+ addMatch(first lpm, op ls, l)
+
+@
+\section{package PMLSAGG PatternMatchListAggregate}
+<<package PMLSAGG PatternMatchListAggregate>>=
+)abbrev package PMLSAGG PatternMatchListAggregate
+++ Pattern matching for list aggregates
+++ Author: Manuel Bronstein
+++ Date Created: 4 Dec 1989
+++ Date Last Updated: 29 Jun 1990
+++ Description:
+++ This package provides pattern matching functions on lists.
+++ Keywords: pattern, matching, list.
+PatternMatchListAggregate(S, R, L): Exports == Implementation where
+ S: SetCategory
+ R: PatternMatchable S
+ L: ListAggregate R
+
+ PLR ==> PatternMatchListResult(S, R, L)
+
+ Exports ==> with
+ patternMatch: (L, Pattern S, PLR) -> PLR
+ ++ patternMatch(l, pat, res) matches the pattern pat to the
+ ++ list l; res contains the variables of pat which
+ ++ are already matched and their matches.
+
+ Implementation ==> add
+ match: (L, List Pattern S, PLR, Boolean) -> PLR
+
+ patternMatch(l, p, r) ==
+ (u := isList p) case "failed" => failed()
+ match(l, u::List Pattern S, r, true)
+
+ match(l, lp, r, new?) ==
+ empty? lp =>
+ empty? l => r
+ failed()
+ multiple?(p0 := first lp) =>
+ empty? rest lp =>
+ if not new? then l := reverse_! l
+ makeResult(atoms r, addMatchRestricted(p0,l,lists r,empty()))
+ new? => match(reverse l, reverse lp, r, false)
+ error "Only one multiple pattern allowed in list"
+ empty? l => failed()
+ failed?(r := makeResult(patternMatch(first l,p0,atoms r),lists r))
+ => failed()
+ match(rest l, rest lp, r, new?)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PATRES PatternMatchResult>>
+<<package PATRES2 PatternMatchResultFunctions2>>
+<<domain PATLRES PatternMatchListResult>>
+<<category PATMAB PatternMatchable>>
+<<category FPATMAB FullyPatternMatchable>>
+<<package PMSYM PatternMatchSymbol>>
+<<package PMKERNEL PatternMatchKernel>>
+<<package PMDOWN PatternMatchPushDown>>
+<<package PMTOOLS PatternMatchTools>>
+<<package PMLSAGG PatternMatchListAggregate>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/patmatch2.spad.pamphlet b/src/algebra/patmatch2.spad.pamphlet
new file mode 100644
index 00000000..0c86c747
--- /dev/null
+++ b/src/algebra/patmatch2.spad.pamphlet
@@ -0,0 +1,404 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra patmatch2.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PMINS PatternMatchIntegerNumberSystem}
+<<package PMINS PatternMatchIntegerNumberSystem>>=
+)abbrev package PMINS PatternMatchIntegerNumberSystem
+++ Pattern matching on integer number systems
+++ Author: Manuel Bronstein
+++ Date Created: 29 Nov 1989
+++ Date Last Updated: 22 Mar 1990
+++ Description:
+++ This package provides pattern matching functions on integers.
+++ Keywords: pattern, matching, integer.
+PatternMatchIntegerNumberSystem(I:IntegerNumberSystem): with
+ patternMatch: (I, Pattern Integer, PatternMatchResult(Integer, I)) ->
+ PatternMatchResult(Integer, I)
+ ++ patternMatch(n, pat, res) matches the pattern pat to the
+ ++ integer n; res contains the variables of pat which
+ ++ are already matched and their matches.
+ == add
+ import IntegerRoots(I)
+
+ PAT ==> Pattern Integer
+ PMR ==> PatternMatchResult(Integer, I)
+
+ patternMatchInner : (I, PAT, PMR) -> PMR
+ patternMatchRestricted: (I, PAT, PMR, I) -> PMR
+ patternMatchSumProd :
+ (I, List PAT, PMR, (I, I) -> Union(I, "failed"), I) -> PMR
+
+ patternMatch(x, p, l) ==
+ generic? p => addMatch(p, x, l)
+ patternMatchInner(x, p, l)
+
+ patternMatchRestricted(x, p, l, y) ==
+ generic? p => addMatchRestricted(p, x, l, y)
+ patternMatchInner(x, p, l)
+
+ patternMatchSumProd(x, lp, l, invOp, ident) ==
+ #lp = 2 =>
+ p2 := last lp
+ if ((r:= retractIfCan(p1 := first lp)@Union(Integer,"failed"))
+ case "failed") then (p1 := p2; p2 := first lp)
+ (r := retractIfCan(p1)@Union(Integer, "failed")) case "failed" =>
+ failed()
+ (y := invOp(x, r::Integer::I)) case "failed" => failed()
+ patternMatchRestricted(y::I, p2, l, ident)
+ failed()
+
+ patternMatchInner(x, p, l) ==
+ constant? p =>
+ (r := retractIfCan(p)@Union(Integer, "failed")) case Integer =>
+ convert(x)@Integer = r::Integer => l
+ failed()
+ failed()
+ (u := isExpt p) case Record(val:PAT,exponent:NonNegativeInteger) =>
+ ur := u::Record(val:PAT, exponent:NonNegativeInteger)
+ (v := perfectNthRoot(x, ur.exponent)) case "failed" => failed()
+ patternMatchRestricted(v::I, ur.val, l, 1)
+ (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+ uur := uu::Record(val:PAT, exponent: PAT)
+ pr := perfectNthRoot x
+ failed?(l := patternMatchRestricted(pr.exponent::Integer::I,
+ uur.exponent, l,1)) => failed()
+ patternMatchRestricted(pr.base, uur.val, l, 1)
+ (w := isTimes p) case List(PAT) =>
+ patternMatchSumProd(x, w::List(PAT), l, #1 exquo #2, 1)
+ (w := isPlus p) case List(PAT) =>
+ patternMatchSumProd(x,w::List(PAT),l,(#1-#2)::Union(I,"failed"),0)
+ (uv := isQuotient p) case Record(num:PAT, den:PAT) =>
+ uvr := uv::Record(num:PAT, den:PAT)
+ (r := retractIfCan(uvr.num)@Union(Integer,"failed")) case Integer
+ and (v := r::Integer::I exquo x) case I =>
+ patternMatchRestricted(v::I, uvr.den, l, 1)
+ (r := retractIfCan(uvr.den)@Union(Integer,"failed")) case Integer
+ => patternMatch(r::Integer * x, uvr.num, l)
+ failed()
+ failed()
+
+@
+\section{package PMQFCAT PatternMatchQuotientFieldCategory}
+<<package PMQFCAT PatternMatchQuotientFieldCategory>>=
+)abbrev package PMQFCAT PatternMatchQuotientFieldCategory
+++ Pattern matching on quotient objects
+++ Author: Manuel Bronstein
+++ Date Created: 1 Dec 1989
+++ Date Last Updated: 20 June 1991
+++ Description:
+++ This package provides pattern matching functions on quotients.
+++ Keywords: pattern, matching, quotient, field.
+PatternMatchQuotientFieldCategory(S,R,Q):Exports == Implementation where
+ S: SetCategory
+ R: Join(IntegralDomain, PatternMatchable S, ConvertibleTo Pattern S)
+ Q: QuotientFieldCategory R
+
+ PAT ==> Pattern S
+ PRQ ==> PatternMatchResult(S, Q)
+
+ Exports ==> with
+ patternMatch: (Q, PAT, PRQ) -> PRQ
+ ++ patternMatch(a/b, pat, res) matches the pattern pat to the
+ ++ quotient a/b; res contains the variables of pat which
+ ++ are already matched and their matches.
+
+ Implementation ==> add
+ import PatternMatchPushDown(S, R, Q)
+
+ patternMatch(x, p, l) ==
+ generic? p => addMatch(p, x, l)
+ (r := retractIfCan x)@Union(R, "failed") case R =>
+ patternMatch(r::R, p, l)
+ (u := isQuotient p) case Record(num:PAT, den:PAT) =>
+ ur := u::Record(num:PAT, den:PAT)
+ failed?(l := patternMatch(numer x, ur.num, l)) => l
+ patternMatch(denom x, ur.den, l)
+ failed()
+
+@
+\section{package PMPLCAT PatternMatchPolynomialCategory}
+<<package PMPLCAT PatternMatchPolynomialCategory>>=
+)abbrev package PMPLCAT PatternMatchPolynomialCategory
+++ Pattern matching on polynomial objects
+++ Author: Manuel Bronstein
+++ Date Created: 9 Jan 1990
+++ Date Last Updated: 20 June 1991
+++ Description:
+++ This package provides pattern matching functions on polynomials.
+++ Keywords: pattern, matching, polynomial.
+PatternMatchPolynomialCategory(S,E,V,R,P):Exports== Implementation where
+ S: SetCategory
+ E: OrderedAbelianMonoidSup
+ V: OrderedSet
+ R: Join(Ring, OrderedSet, PatternMatchable S)
+ P: Join(PolynomialCategory(R, E, V), ConvertibleTo Pattern S)
+
+ N ==> NonNegativeInteger
+ PAT ==> Pattern S
+ PRS ==> PatternMatchResult(S, P)
+ RCP ==> Record(val:PAT, exponent:N)
+ RCX ==> Record(var:V, exponent:N)
+
+ Exports ==> with
+ patternMatch: (P, PAT, PRS, (V, PAT, PRS) -> PRS) -> PRS
+ ++ patternMatch(p, pat, res, vmatch) matches the pattern pat to
+ ++ the polynomial p. res contains the variables of pat which
+ ++ are already matched and their matches; vmatch is the matching
+ ++ function to use on the variables.
+ -- This can be more efficient than pushing down when the variables
+ -- are recursive over P (e.g. kernels)
+ if V has PatternMatchable S then
+ patternMatch: (P, PAT, PRS) -> PRS
+ ++ patternMatch(p, pat, res) matches the pattern pat to
+ ++ the polynomial p; res contains the variables of pat which
+ ++ are already matched and their matches.
+
+ Implementation ==> add
+ import PatternMatchTools(S, R, P)
+ import PatternMatchPushDown(S, R, P)
+
+ if V has PatternMatchable S then
+ patternMatch(x, p, l) ==
+ patternMatch(x, p, l, patternMatch$PatternMatchPushDown(S,V,P))
+
+ patternMatch(x, p, l, vmatch) ==
+ generic? p => addMatch(p, x, l)
+ (r := retractIfCan(x)@Union(R, "failed")) case R =>
+ patternMatch(r::R, p, l)
+ (v := retractIfCan(x)@Union(V, "failed")) case V =>
+ vmatch(v::V, p, l)
+ (u := isPlus p) case List(PAT) =>
+ (lx := isPlus x) case List(P) =>
+ patternMatch(lx::List(P), u::List(PAT), +/#1, l,
+ patternMatch(#1, #2, #3, vmatch))
+ (u := optpair(u::List(PAT))) case List(PAT) =>
+ failed?(l := addMatch(first(u::List(PAT)), 0, l)) => failed()
+ patternMatch(x, second(u::List(PAT)), l, vmatch)
+ failed()
+ (u := isTimes p) case List(PAT) =>
+ (lx := isTimes x) case List(P) =>
+ patternMatchTimes(lx::List(P), u::List(PAT), l,
+ patternMatch(#1, #2, #3, vmatch))
+ (u := optpair(u::List(PAT))) case List(PAT) =>
+ failed?(l := addMatch(first(u::List(PAT)), 1, l)) => failed()
+ patternMatch(x, second(u::List(PAT)), l, vmatch)
+ failed()
+ (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+ uur := uu::Record(val:PAT, exponent: PAT)
+ (ex := isExpt x) case RCX =>
+ failed?(l := patternMatch((ex::RCX).exponent::Integer::P,
+ uur.exponent, l, vmatch)) => failed()
+ vmatch((ex::RCX).var, uur.val, l)
+ optional?(uur.exponent) =>
+ failed?(l := addMatch(uur.exponent, 1, l)) => failed()
+ patternMatch(x, uur.val, l, vmatch)
+ failed()
+ ((ep := isExpt p) case RCP) and ((ex := isExpt x) case RCX) and
+ (ex::RCX).exponent = (ep::RCP).exponent =>
+ vmatch((ex::RCX).var, (ep::RCP).val, l)
+ failed()
+
+@
+\section{package PMFS PatternMatchFunctionSpace}
+<<package PMFS PatternMatchFunctionSpace>>=
+)abbrev package PMFS PatternMatchFunctionSpace
+++ Pattern matching on function spaces
+++ Author: Manuel Bronstein
+++ Date Created: 15 Mar 1990
+++ Date Last Updated: 20 June 1991
+++ Description:
+++ This package provides pattern matching functions on function spaces.
+++ Keywords: pattern, matching, function, space.
+PatternMatchFunctionSpace(S, R, F): Exports== Implementation where
+ S: SetCategory
+ R: Join(IntegralDomain, OrderedSet, PatternMatchable S)
+ F: Join(FunctionSpace R, ConvertibleTo Pattern S, PatternMatchable S,
+ RetractableTo Kernel %) -- that one is redundant but won't
+ -- compile without it
+
+ N ==> NonNegativeInteger
+ K ==> Kernel F
+ PAT ==> Pattern S
+ PRS ==> PatternMatchResult(S, F)
+ RCP ==> Record(val:PAT, exponent:N)
+ RCX ==> Record(var:K, exponent:Integer)
+
+ Exports ==> with
+ patternMatch: (F, PAT, PRS) -> PRS
+ ++ patternMatch(expr, pat, res) matches the pattern pat to the
+ ++ expression expr; res contains the variables of pat which
+ ++ are already matched and their matches.
+
+ Implementation ==> add
+ import PatternMatchKernel(S, F)
+ import PatternMatchTools(S, R, F)
+ import PatternMatchPushDown(S, R, F)
+
+ patternMatch(x, p, l) ==
+ generic? p => addMatch(p, x, l)
+ (r := retractIfCan(x)@Union(R, "failed")) case R =>
+ patternMatch(r::R, p, l)
+ (v := retractIfCan(x)@Union(K, "failed")) case K =>
+ patternMatch(v::K, p, l)
+ (q := isQuotient p) case Record(num:PAT, den:PAT) =>
+ uq := q::Record(num:PAT, den:PAT)
+ failed?(l := patternMatch(numer(x)::F, uq.num, l)) => l
+ patternMatch(denom(x)::F, uq.den, l)
+ (u := isPlus p) case List(PAT) =>
+ (lx := isPlus x) case List(F) =>
+ patternMatch(lx::List(F), u::List(PAT), +/#1, l, patternMatch)
+ (u := optpair(u::List(PAT))) case List(PAT) =>
+ failed?(l := addMatch(first(u::List(PAT)), 0, l)) => failed()
+ patternMatch(x, second(u::List(PAT)), l)
+ failed()
+ (u := isTimes p) case List(PAT) =>
+ (lx := isTimes x) case List(F) =>
+ patternMatchTimes(lx::List(F), u::List(PAT), l, patternMatch)
+ (u := optpair(u::List(PAT))) case List(PAT) =>
+ failed?(l := addMatch(first(u::List(PAT)), 1, l)) => failed()
+ patternMatch(x, second(u::List(PAT)), l)
+ failed()
+ (uu := isPower p) case Record(val:PAT, exponent:PAT) =>
+ uur := uu::Record(val:PAT, exponent: PAT)
+ (ex := isExpt x) case RCX =>
+ failed?(l := patternMatch((ex::RCX).exponent::Integer::F,
+ uur.exponent, l)) => failed()
+ patternMatch((ex::RCX).var, uur.val, l)
+ optional?(uur.exponent) =>
+ failed?(l := addMatch(uur.exponent, 1, l)) => failed()
+ patternMatch(x, uur.val, l)
+ failed()
+ ((ep := isExpt p) case RCP) and ((ex := isExpt x) case RCX) and
+ (ex::RCX).exponent = ((ep::RCP).exponent)::Integer =>
+ patternMatch((ex::RCX).var, (ep::RCP).val, l)
+ failed()
+
+@
+\section{package PATMATCH PatternMatch}
+<<package PATMATCH PatternMatch>>=
+)abbrev package PATMATCH PatternMatch
+++ Top-level pattern matching functions
+++ Author: Manuel Bronstein
+++ Date Created: 3 Dec 1989
+++ Date Last Updated: 29 Jun 1990
+++ Description:
+++ This package provides the top-level pattern macthing functions.
+++ Keywords: pattern, matching.
+PatternMatch(Base, Subject, Pat): Exports == Implementation where
+ Base : SetCategory
+ Subject: PatternMatchable Base
+ Pat : ConvertibleTo Pattern Base
+
+ Exports ==> with
+ is?: (Subject, Pat) -> Boolean
+ ++ is?(expr, pat) tests if the expression expr matches
+ ++ the pattern pat.
+ is?: (List Subject, Pat) -> Boolean
+ ++ is?([e1,...,en], pat) tests if the list of
+ ++ expressions \spad{[e1,...,en]} matches
+ ++ the pattern pat.
+ Is : (List Subject, Pat) ->
+ PatternMatchListResult(Base, Subject, List Subject)
+ ++ Is([e1,...,en], pat) matches the pattern pat on the list of
+ ++ expressions \spad{[e1,...,en]} and returns the result.
+ if Subject has RetractableTo(Symbol) then
+ Is: (Subject, Pat) -> List Equation Subject
+ ++ Is(expr, pat) matches the pattern pat on the expression
+ ++ expr and returns a list of matches \spad{[v1 = e1,...,vn = en]};
+ ++ returns an empty list if either expr is exactly equal to
+ ++ pat or if pat does not match expr.
+ else
+ if Subject has Ring then
+ Is: (Subject, Pat) -> List Equation Polynomial Subject
+ ++ Is(expr, pat) matches the pattern pat on the expression
+ ++ expr and returns a list of matches \spad{[v1 = e1,...,vn = en]};
+ ++ returns an empty list if either expr is exactly equal to
+ ++ pat or if pat does not match expr.
+ else
+ Is: (Subject, Pat) -> PatternMatchResult(Base, Subject)
+ ++ Is(expr, pat) matches the pattern pat on the expression
+ ++ expr and returns a match of the form \spad{[v1 = e1,...,vn = en]};
+ ++ returns an empty match if expr is exactly equal to pat.
+ ++ returns a \spadfun{failed} match if pat does not match expr.
+
+ Implementation ==> add
+ import PatternMatchListAggregate(Base, Subject, List Subject)
+
+ ist: (Subject, Pat) -> PatternMatchResult(Base, Subject)
+
+ ist(s, p) == patternMatch(s, convert p, new())
+ is?(s: Subject, p:Pat) == not failed? ist(s, p)
+ is?(s:List Subject, p:Pat) == not failed? Is(s, p)
+ Is(s:List Subject, p:Pat) == patternMatch(s, convert p, new())
+
+ if Subject has RetractableTo(Symbol) then
+ Is(s:Subject, p:Pat):List(Equation Subject) ==
+ failed?(r := ist(s, p)) => empty()
+ [rec.key::Subject = rec.entry for rec in destruct r]
+
+ else
+ if Subject has Ring then
+ Is(s:Subject, p:Pat):List(Equation Polynomial Subject) ==
+ failed?(r := ist(s, p)) => empty()
+ [rec.key::Polynomial(Subject) =$Equation(Polynomial Subject)
+ rec.entry::Polynomial(Subject) for rec in destruct r]
+
+ else
+ Is(s:Subject,p:Pat):PatternMatchResult(Base,Subject) == ist(s,p)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PMINS PatternMatchIntegerNumberSystem>>
+<<package PMQFCAT PatternMatchQuotientFieldCategory>>
+<<package PMPLCAT PatternMatchPolynomialCategory>>
+<<package PMFS PatternMatchFunctionSpace>>
+<<package PATMATCH PatternMatch>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pattern.spad.pamphlet b/src/algebra/pattern.spad.pamphlet
new file mode 100644
index 00000000..e22e9207
--- /dev/null
+++ b/src/algebra/pattern.spad.pamphlet
@@ -0,0 +1,555 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pattern.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PATTERN Pattern}
+<<domain PATTERN Pattern>>=
+)abbrev domain PATTERN Pattern
+++ Patterns for use by the pattern matcher
+++ Author: Manuel Bronstein
+++ Date Created: 10 Nov 1988
+++ Date Last Updated: 20 June 1991
+++ Description: Patterns for use by the pattern matcher.
+++ Keywords: pattern, matching.
+-- Not exposed.
+-- Patterns are optimized for quick answers to structural questions.
+Pattern(R:SetCategory): Exports == Implementation where
+ B ==> Boolean
+ SI ==> SingleInteger
+ Z ==> Integer
+ SY ==> Symbol
+ O ==> OutputForm
+ BOP ==> BasicOperator
+ QOT ==> Record(num:%, den:%)
+ REC ==> Record(val:%, exponent:NonNegativeInteger)
+ RSY ==> Record(tag:SI, val: SY, pred:List Any, bad:List Any)
+ KER ==> Record(tag:SI, op:BOP, arg:List %)
+ PAT ==> Union(ret:R, ker: KER, exp:REC, qot: QOT, sym:RSY)
+
+-- the following MUST be the name of the formal exponentiation operator
+ POWER ==> "%power"::Symbol
+
+-- the 4 SYM_ constants must be disting powers of 2 (bitwise arithmetic)
+ SYM_GENERIC ==> 1::SI
+ SYM_MULTIPLE ==> 2::SI
+ SYM_OPTIONAL ==> 4::SI
+
+ PAT_PLUS ==> 1::SI
+ PAT_TIMES ==> 2::SI
+ PAT_LIST ==> 3::SI
+ PAT_ZERO ==> 4::SI
+ PAT_ONE ==> 5::SI
+ PAT_EXPT ==> 6::SI
+
+ Exports ==> Join(SetCategory, RetractableTo R, RetractableTo SY) with
+ 0 : constant -> % ++ 0
+ 1 : constant -> % ++ 1
+ isPlus : % -> Union(List %, "failed")
+ ++ isPlus(p) returns \spad{[a1,...,an]} if \spad{n > 1}
+ ++ and \spad{p = a1 + ... + an},
+ ++ and "failed" otherwise.
+ isTimes : % -> Union(List %, "failed")
+ ++ isTimes(p) returns \spad{[a1,...,an]} if \spad{n > 1} and
+ ++ \spad{p = a1 * ... * an}, and
+ ++ "failed" otherwise.
+ isOp : (%, BOP) -> Union(List %, "failed")
+ ++ isOp(p, op) returns \spad{[a1,...,an]} if \spad{p = op(a1,...,an)}, and
+ ++ "failed" otherwise.
+ isOp : % -> Union(Record(op:BOP, arg:List %), "failed")
+ ++ isOp(p) returns \spad{[op, [a1,...,an]]} if
+ ++ \spad{p = op(a1,...,an)}, and
+ ++ "failed" otherwise;
+ isExpt : % -> Union(REC, "failed")
+ ++ isExpt(p) returns \spad{[q, n]} if \spad{n > 0} and \spad{p = q ** n},
+ ++ and "failed" otherwise.
+ isQuotient : % -> Union(QOT, "failed")
+ ++ isQuotient(p) returns \spad{[a, b]} if \spad{p = a / b}, and
+ ++ "failed" otherwise.
+ isList : % -> Union(List %, "failed")
+ ++ isList(p) returns \spad{[a1,...,an]} if \spad{p = [a1,...,an]},
+ ++ "failed" otherwise;
+ isPower : % -> Union(Record(val:%, exponent:%), "failed")
+ ++ isPower(p) returns \spad{[a, b]} if \spad{p = a ** b}, and
+ ++ "failed" otherwise.
+ elt : (BOP, List %) -> %
+ ++ \spad{elt(op, [a1,...,an])} returns \spad{op(a1,...,an)}.
+ "+" : (%, %) -> %
+ ++ \spad{a + b} returns the pattern \spad{a + b}.
+ "*" : (%, %) -> %
+ ++ \spad{a * b} returns the pattern \spad{a * b}.
+ "**" : (%, NonNegativeInteger) -> %
+ ++ \spad{a ** n} returns the pattern \spad{a ** n}.
+ "**" : (%, %) -> %
+ ++ \spad{a ** b} returns the pattern \spad{a ** b}.
+ "/" : (%, %) -> %
+ ++ \spad{a / b} returns the pattern \spad{a / b}.
+ depth : % -> NonNegativeInteger
+ ++ depth(p) returns the nesting level of p.
+ convert : List % -> %
+ ++ \spad{convert([a1,...,an])} returns the pattern \spad{[a1,...,an]}.
+ copy : % -> %
+ ++ copy(p) returns a recursive copy of p.
+ inR? : % -> B
+ ++ inR?(p) tests if p is an atom (i.e. an element of R).
+ quoted? : % -> B
+ ++ quoted?(p) tests if p is of the form 's for a symbol s.
+ symbol? : % -> B
+ ++ symbol?(p) tests if p is a symbol.
+ constant? : % -> B
+ ++ constant?(p) tests if p contains no matching variables.
+ generic? : % -> B
+ ++ generic?(p) tests if p is a single matching variable.
+ multiple? : % -> B
+ ++ multiple?(p) tests if p is a single matching variable
+ ++ allowing list matching or multiple term matching in a
+ ++ sum or product.
+ optional? : % -> B
+ ++ optional?(p) tests if p is a single matching variable
+ ++ which can match an identity.
+ hasPredicate?: % -> B
+ ++ hasPredicate?(p) tests if p has predicates attached to it.
+ predicates : % -> List Any
+ ++ predicates(p) returns \spad{[p1,...,pn]} such that the predicate
+ ++ attached to p is p1 and ... and pn.
+ setPredicates: (%, List Any) -> %
+ ++ \spad{setPredicates(p, [p1,...,pn])} attaches the predicate
+ ++ p1 and ... and pn to p.
+ withPredicates:(%, List Any) -> %
+ ++ \spad{withPredicates(p, [p1,...,pn])} makes a copy of p and attaches
+ ++ the predicate p1 and ... and pn to the copy, which is
+ ++ returned.
+ patternVariable: (SY, B, B, B) -> %
+ ++ patternVariable(x, c?, o?, m?) creates a pattern variable x,
+ ++ which is constant if \spad{c? = true}, optional if \spad{o? = true},
+ ++ and multiple if \spad{m? = true}.
+ setTopPredicate: (%, List SY, Any) -> %
+ ++ \spad{setTopPredicate(x, [a1,...,an], f)} returns x with
+ ++ the top-level predicate set to \spad{f(a1,...,an)}.
+ topPredicate: % -> Record(var:List SY, pred:Any)
+ ++ topPredicate(x) returns \spad{[[a1,...,an], f]} where the top-level
+ ++ predicate of x is \spad{f(a1,...,an)}.
+ ++ Note: n is 0 if x has no top-level
+ ++ predicate.
+ hasTopPredicate?: % -> B
+ ++ hasTopPredicate?(p) tests if p has a top-level predicate.
+ resetBadValues: % -> %
+ ++ resetBadValues(p) initializes the list of "bad values" for p
+ ++ to \spad{[]}.
+ ++ Note: p is not allowed to match any of its "bad values".
+ addBadValue: (%, Any) -> %
+ ++ addBadValue(p, v) adds v to the list of "bad values" for p.
+ ++ Note: p is not allowed to match any of its "bad values".
+ getBadValues: % -> List Any
+ ++ getBadValues(p) returns the list of "bad values" for p.
+ ++ Note: p is not allowed to match any of its "bad values".
+ variables: % -> List %
+ ++ variables(p) returns the list of matching variables
+ ++ appearing in p.
+ optpair: List % -> Union(List %, "failed")
+ ++ optpair(l) returns l has the form \spad{[a, b]} and
+ ++ a is optional, and
+ ++ "failed" otherwise;
+
+ Implementation ==> add
+ Rep := Record(cons?: B, pat:PAT, lev: NonNegativeInteger,
+ topvar: List SY, toppred: Any)
+
+ dummy:BOP := operator(new()$Symbol)
+ nopred := coerce(0$Integer)$AnyFunctions1(Integer)
+
+ mkPat : (B, PAT, NonNegativeInteger) -> %
+ mkrsy : (SY, B, B, B) -> RSY
+ SYM2O : RSY -> O
+ PAT2O : PAT -> O
+ patcopy : PAT -> PAT
+ bitSet? : (SI , SI) -> B
+ pateq? : (PAT, PAT) -> B
+ LPAT2O : ((O, O) -> O, List %) -> O
+ taggedElt : (SI, List %) -> %
+ isTaggedOp: (%, SI) -> Union(List %, "failed")
+ incmax : List % -> NonNegativeInteger
+
+ coerce(r:R):% == mkPat(true, [r], 0)
+ mkPat(c, p, l) == [c, p, l, empty(), nopred]
+ hasTopPredicate? x == not empty?(x.topvar)
+ topPredicate x == [x.topvar, x.toppred]
+ setTopPredicate(x, l, f) == (x.topvar := l; x.toppred := f; x)
+ constant? p == p.cons?
+ depth p == p.lev
+ inR? p == p.pat case ret
+ symbol? p == p.pat case sym
+ isPlus p == isTaggedOp(p, PAT_PLUS)
+ isTimes p == isTaggedOp(p, PAT_TIMES)
+ isList p == isTaggedOp(p, PAT_LIST)
+ isExpt p == (p.pat case exp => p.pat.exp; "failed")
+ isQuotient p == (p.pat case qot => p.pat.qot; "failed")
+ hasPredicate? p == not empty? predicates p
+ quoted? p == symbol? p and zero?(p.pat.sym.tag)
+ generic? p == symbol? p and bitSet?(p.pat.sym.tag, SYM_GENERIC)
+ multiple? p == symbol? p and bitSet?(p.pat.sym.tag,SYM_MULTIPLE)
+ optional? p == symbol? p and bitSet?(p.pat.sym.tag,SYM_OPTIONAL)
+ bitSet?(a, b) == And(a, b) ^= 0
+ coerce(p:%):O == PAT2O(p.pat)
+ p1:% ** p2:% == taggedElt(PAT_EXPT, [p1, p2])
+ LPAT2O(f, l) == reduce(f, [x::O for x in l])$List(O)
+ retract(p:%):R == (inR? p => p.pat.ret; error "Not retractable")
+ convert(l:List %):% == taggedElt(PAT_LIST, l)
+ retractIfCan(p:%):Union(R,"failed") ==(inR? p => p.pat.ret;"failed")
+ withPredicates(p, l) == setPredicates(copy p, l)
+ coerce(sy:SY):% == patternVariable(sy, false, false, false)
+ copy p == [constant? p, patcopy(p.pat), p.lev, p.topvar, p.toppred]
+
+ -- returns [a, b] if #l = 2 and optional? a, "failed" otherwise
+ optpair l ==
+ empty? rest rest l =>
+ b := first rest l
+ optional?(a := first l) => l
+ optional? b => reverse l
+ "failed"
+ "failed"
+
+ incmax l ==
+ 1 + reduce("max", [p.lev for p in l], 0)$List(NonNegativeInteger)
+
+ p1 = p2 ==
+ (p1.cons? = p2.cons?) and (p1.lev = p2.lev) and
+ (p1.topvar = p2.topvar) and
+ ((EQ(p1.toppred, p2.toppred)$Lisp) pretend B) and
+ pateq?(p1.pat, p2.pat)
+
+ isPower p ==
+ (u := isTaggedOp(p, PAT_EXPT)) case "failed" => "failed"
+ [first(u::List(%)), second(u::List(%))]
+
+ taggedElt(n, l) ==
+ mkPat(every?(constant?, l), [[n, dummy, l]$KER], incmax l)
+
+ elt(o, l) ==
+ is?(o, POWER) and #l = 2 => first(l) ** last(l)
+ mkPat(every?(constant?, l), [[0, o, l]$KER], incmax l)
+
+ isOp p ==
+ (p.pat case ker) and zero?(p.pat.ker.tag) =>
+ [p.pat.ker.op, p.pat.ker.arg]
+ "failed"
+
+ isTaggedOp(p,t) ==
+ (p.pat case ker) and (p.pat.ker.tag = t) => p.pat.ker.arg
+ "failed"
+
+ if R has Monoid then
+ 1 == 1::R::%
+ else
+ 1 == taggedElt(PAT_ONE, empty())
+
+ if R has AbelianMonoid then
+ 0 == 0::R::%
+ else
+ 0 == taggedElt(PAT_ZERO, empty())
+
+ p:% ** n:NonNegativeInteger ==
+ p = 0 and n > 0 => 0
+ p = 1 or zero? n => 1
+-- one? n => p
+ (n = 1) => p
+ mkPat(constant? p, [[p, n]$REC], 1 + (p.lev))
+
+ p1 / p2 ==
+ p2 = 1 => p1
+ mkPat(constant? p1 and constant? p2, [[p1, p2]$QOT],
+ 1 + max(p1.lev, p2.lev))
+
+ p1 + p2 ==
+ p1 = 0 => p2
+ p2 = 0 => p1
+ (u1 := isPlus p1) case List(%) =>
+ (u2 := isPlus p2) case List(%) =>
+ taggedElt(PAT_PLUS, concat(u1::List %, u2::List %))
+ taggedElt(PAT_PLUS, concat(u1::List %, p2))
+ (u2 := isPlus p2) case List(%) =>
+ taggedElt(PAT_PLUS, concat(p1, u2::List %))
+ taggedElt(PAT_PLUS, [p1, p2])
+
+ p1 * p2 ==
+ p1 = 0 or p2 = 0 => 0
+ p1 = 1 => p2
+ p2 = 1 => p1
+ (u1 := isTimes p1) case List(%) =>
+ (u2 := isTimes p2) case List(%) =>
+ taggedElt(PAT_TIMES, concat(u1::List %, u2::List %))
+ taggedElt(PAT_TIMES, concat(u1::List %, p2))
+ (u2 := isTimes p2) case List(%) =>
+ taggedElt(PAT_TIMES, concat(p1, u2::List %))
+ taggedElt(PAT_TIMES, [p1, p2])
+
+ isOp(p, o) ==
+ (p.pat case ker) and zero?(p.pat.ker.tag) and (p.pat.ker.op =o) =>
+ p.pat.ker.arg
+ "failed"
+
+ predicates p ==
+ symbol? p => p.pat.sym.pred
+ empty()
+
+ setPredicates(p, l) ==
+ generic? p => (p.pat.sym.pred := l; p)
+ error "Can only attach predicates to generic symbol"
+
+ resetBadValues p ==
+ generic? p => (p.pat.sym.bad := empty()$List(Any); p)
+ error "Can only attach bad values to generic symbol"
+
+ addBadValue(p, a) ==
+ generic? p =>
+ if not member?(a, p.pat.sym.bad) then
+ p.pat.sym.bad := concat(a, p.pat.sym.bad)
+ p
+ error "Can only attach bad values to generic symbol"
+
+ getBadValues p ==
+ generic? p => p.pat.sym.bad
+ error "Not a generic symbol"
+
+ SYM2O p ==
+ sy := (p.val)::O
+ empty?(p.pred) => sy
+ paren infix(" | "::O, sy,
+ reduce("and",[sub("f"::O, i::O) for i in 1..#(p.pred)])$List(O))
+
+ variables p ==
+ constant? p => empty()
+ generic? p => [p]
+ q := p.pat
+ q case ret => empty()
+ q case exp => variables(q.exp.val)
+ q case qot => concat_!(variables(q.qot.num), variables(q.qot.den))
+ q case ker => concat [variables r for r in q.ker.arg]
+ empty()
+
+ PAT2O p ==
+ p case ret => (p.ret)::O
+ p case sym => SYM2O(p.sym)
+ p case exp => (p.exp.val)::O ** (p.exp.exponent)::O
+ p case qot => (p.qot.num)::O / (p.qot.den)::O
+ p.ker.tag = PAT_PLUS => LPAT2O("+", p.ker.arg)
+ p.ker.tag = PAT_TIMES => LPAT2O("*", p.ker.arg)
+ p.ker.tag = PAT_LIST => (p.ker.arg)::O
+ p.ker.tag = PAT_ZERO => 0::Integer::O
+ p.ker.tag = PAT_ONE => 1::Integer::O
+ l := [x::O for x in p.ker.arg]$List(O)
+ (u:=display(p.ker.op)) case "failed" =>prefix(name(p.ker.op)::O,l)
+ (u::(List O -> O)) l
+
+ patcopy p ==
+ p case ret => [p.ret]
+ p case sym =>
+ [[p.sym.tag, p.sym.val, copy(p.sym.pred), copy(p.sym.bad)]$RSY]
+ p case ker=>[[p.ker.tag,p.ker.op,[copy x for x in p.ker.arg]]$KER]
+ p case qot => [[copy(p.qot.num), copy(p.qot.den)]$QOT]
+ [[copy(p.exp.val), p.exp.exponent]$REC]
+
+ pateq?(p1, p2) ==
+ p1 case ret => (p2 case ret) and (p1.ret = p2.ret)
+ p1 case qot =>
+ (p2 case qot) and (p1.qot.num = p2.qot.num)
+ and (p1.qot.den = p2.qot.den)
+ p1 case sym =>
+ (p2 case sym) and (p1.sym.val = p2.sym.val)
+ and {p1.sym.pred} =$Set(Any) {p2.sym.pred}
+ and {p1.sym.bad} =$Set(Any) {p2.sym.bad}
+ p1 case ker =>
+ (p2 case ker) and (p1.ker.tag = p2.ker.tag)
+ and (p1.ker.op = p2.ker.op) and (p1.ker.arg = p2.ker.arg)
+ (p2 case exp) and (p1.exp.exponent = p2.exp.exponent)
+ and (p1.exp.val = p2.exp.val)
+
+ retractIfCan(p:%):Union(SY, "failed") ==
+ symbol? p => p.pat.sym.val
+ "failed"
+
+ mkrsy(t, c?, o?, m?) ==
+ c? => [0, t, empty(), empty()]
+ mlt := (m? => SYM_MULTIPLE; 0)
+ opt := (o? => SYM_OPTIONAL; 0)
+ [Or(Or(SYM_GENERIC, mlt), opt), t, empty(), empty()]
+
+ patternVariable(sy, c?, o?, m?) ==
+ rsy := mkrsy(sy, c?, o?, m?)
+ mkPat(zero?(rsy.tag), [rsy], 0)
+
+@
+\section{package PATTERN1 PatternFunctions1}
+<<package PATTERN1 PatternFunctions1>>=
+)abbrev package PATTERN1 PatternFunctions1
+++ Utilities for handling patterns
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 5 Jul 1990
+++ Description: Tools for patterns;
+++ Keywords: pattern, matching.
+PatternFunctions1(R:SetCategory, D:Type): with
+ suchThat : (Pattern R, D -> Boolean) -> Pattern R
+ ++ suchThat(p, f) makes a copy of p and adds the predicate
+ ++ f to the copy, which is returned.
+ suchThat : (Pattern R, List(D -> Boolean)) -> Pattern R
+ ++ \spad{suchThat(p, [f1,...,fn])} makes a copy of p and adds the
+ ++ predicate f1 and ... and fn to the copy, which is returned.
+ suchThat : (Pattern R, List Symbol, List D -> Boolean) -> Pattern R
+ ++ \spad{suchThat(p, [a1,...,an], f)} returns a copy of p with
+ ++ the top-level predicate set to \spad{f(a1,...,an)}.
+ predicate : Pattern R -> (D -> Boolean)
+ ++ predicate(p) returns the predicate attached to p, the
+ ++ constant function true if p has no predicates attached to it.
+ satisfy? : (D, Pattern R) -> Boolean
+ ++ satisfy?(v, p) returns f(v) where f is the predicate
+ ++ attached to p.
+ satisfy? : (List D, Pattern R) -> Boolean
+ ++ \spad{satisfy?([v1,...,vn], p)} returns \spad{f(v1,...,vn)}
+ ++ where f is the
+ ++ top-level predicate attached to p.
+ addBadValue: (Pattern R, D) -> Pattern R
+ ++ addBadValue(p, v) adds v to the list of "bad values" for p;
+ ++ p is not allowed to match any of its "bad values".
+ badValues : Pattern R -> List D
+ ++ badValues(p) returns the list of "bad values" for p;
+ ++ p is not allowed to match any of its "bad values".
+ == add
+ A1D ==> AnyFunctions1(D)
+ A1 ==> AnyFunctions1(D -> Boolean)
+ A1L ==> AnyFunctions1(List D -> Boolean)
+
+ applyAll: (List Any, D) -> Boolean
+ st : (Pattern R, List Any) -> Pattern R
+
+ st(p, l) == withPredicates(p, concat(predicates p, l))
+ predicate p == applyAll(predicates p, #1)
+ addBadValue(p, v) == addBadValue(p, coerce(v)$A1D)
+ badValues p == [retract(v)$A1D for v in getBadValues p]
+ suchThat(p, l, f) == setTopPredicate(copy p, l, coerce(f)$A1L)
+ suchThat(p:Pattern R, f:D -> Boolean) == st(p, [coerce(f)$A1])
+ satisfy?(d:D, p:Pattern R) == applyAll(predicates p, d)
+
+ satisfy?(l:List D, p:Pattern R) ==
+ empty?((rec := topPredicate p).var) => true
+ retract(rec.pred)$A1L l
+
+ applyAll(l, d) ==
+ for f in l repeat
+ not(retract(f)$A1 d) => return false
+ true
+
+ suchThat(p:Pattern R, l:List(D -> Boolean)) ==
+ st(p, [coerce(f)$A1 for f in l])
+
+@
+\section{package PATTERN2 PatternFunctions2}
+<<package PATTERN2 PatternFunctions2>>=
+)abbrev package PATTERN2 PatternFunctions2
+++ Lifting of maps to patterns
+++ Author: Manuel Bronstein
+++ Date Created: 28 Nov 1989
+++ Date Last Updated: 12 Jan 1990
+++ Description: Lifts maps to patterns;
+++ Keywords: pattern, matching.
+PatternFunctions2(R:SetCategory, S:SetCategory): with
+ map: (R -> S, Pattern R) -> Pattern S
+ ++ map(f, p) applies f to all the leaves of p and
+ ++ returns the result as a pattern over S.
+ == add
+ map(f, p) ==
+ (r := (retractIfCan p)@Union(R, "failed")) case R =>
+ f(r::R)::Pattern(S)
+ (u := isOp p) case Record(op:BasicOperator, arg:List Pattern R) =>
+ ur := u::Record(op:BasicOperator, arg:List Pattern R)
+ (ur.op) [map(f, x) for x in ur.arg]
+ (v := isQuotient p) case Record(num:Pattern R, den:Pattern R) =>
+ vr := v::Record(num:Pattern R, den:Pattern R)
+ map(f, vr.num) / map(f, vr.den)
+ (l := isPlus p) case List(Pattern R) =>
+ reduce("+", [map(f, x) for x in l::List(Pattern R)])
+ (l := isTimes p) case List(Pattern R) =>
+ reduce("*", [map(f, x) for x in l::List(Pattern R)])
+ (x := isPower p) case
+ Record(val:Pattern R, exponent: Pattern R) =>
+ xr := x::Record(val:Pattern R, exponent: Pattern R)
+ map(f, xr.val) ** map(f, xr.exponent)
+ (w := isExpt p) case
+ Record(val:Pattern R, exponent: NonNegativeInteger) =>
+ wr := w::Record(val:Pattern R, exponent: NonNegativeInteger)
+ map(f, wr.val) ** wr.exponent
+ sy := retract(p)@Symbol
+ setPredicates(sy::Pattern(S), copy predicates p)
+
+@
+\section{category PATAB Patternable}
+<<category PATAB Patternable>>=
+)abbrev category PATAB Patternable
+++ Category of sets that can be converted to useful patterns
+++ Author: Manuel Bronstein
+++ Date Created: 29 Nov 1989
+++ Date Last Updated: 29 Nov 1989
+++ Description:
+++ An object S is Patternable over an object R if S can
+++ lift the conversions from R into \spadtype{Pattern(Integer)} and
+++ \spadtype{Pattern(Float)} to itself;
+++ Keywords: pattern, matching.
+Patternable(R:Type): Category == with
+ if R has ConvertibleTo Pattern Integer then
+ ConvertibleTo Pattern Integer
+ if R has ConvertibleTo Pattern Float then
+ ConvertibleTo Pattern Float
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PATTERN Pattern>>
+<<package PATTERN1 PatternFunctions1>>
+<<package PATTERN2 PatternFunctions2>>
+<<category PATAB Patternable>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pcurve.spad.pamphlet b/src/algebra/pcurve.spad.pamphlet
new file mode 100644
index 00000000..9fa07574
--- /dev/null
+++ b/src/algebra/pcurve.spad.pamphlet
@@ -0,0 +1,132 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pcurve.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PPCURVE PlottablePlaneCurveCategory}
+<<category PPCURVE PlottablePlaneCurveCategory>>=
+)abbrev category PPCURVE PlottablePlaneCurveCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 11 January 1990
+++ Date Last Updated: 15 June 1990
+++ Basic Operations: listBranches, xRange, yRange
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: plot, graphics
+++ References:
+++ Description: PlottablePlaneCurveCategory is the category of curves in the
+++ plane which may be plotted via the graphics facilities. Functions are
+++ provided for obtaining lists of lists of points, representing the
+++ branches of the curve, and for determining the ranges of the
+++ x-coordinates and y-coordinates of the points on the curve.
+
+PlottablePlaneCurveCategory(): Category == Definition where
+ L ==> List
+ SEG ==> Segment
+ SF ==> DoubleFloat
+ POINT ==> Point DoubleFloat
+
+ Definition ==> CoercibleTo OutputForm with
+
+ listBranches: % -> L L POINT
+ ++ listBranches(c) returns a list of lists of points, representing the
+ ++ branches of the curve c.
+ xRange: % -> SEG SF
+ ++ xRange(c) returns the range of the x-coordinates of the points
+ ++ on the curve c.
+ yRange: % -> SEG SF
+ ++ yRange(c) returns the range of the y-coordinates of the points
+ ++ on the curve c.
+
+@
+\section{category PSCURVE PlottableSpaceCurveCategory}
+<<category PSCURVE PlottableSpaceCurveCategory>>=
+)abbrev category PSCURVE PlottableSpaceCurveCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 11 January 1990
+++ Date Last Updated: 15 June 1990
+++ Basic Operations: listBranches, xRange, yRange, zRange
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: plot, graphics
+++ References:
+++ Description: PlottableSpaceCurveCategory is the category of curves in
+++ 3-space which may be plotted via the graphics facilities. Functions are
+++ provided for obtaining lists of lists of points, representing the
+++ branches of the curve, and for determining the ranges of the
+++ x-, y-, and z-coordinates of the points on the curve.
+
+PlottableSpaceCurveCategory(): Category == Definition where
+ L ==> List
+ SEG ==> Segment
+ SF ==> DoubleFloat
+ POINT ==> Point DoubleFloat
+
+ Definition ==> CoercibleTo OutputForm with
+
+ listBranches: % -> L L POINT
+ ++ listBranches(c) returns a list of lists of points, representing the
+ ++ branches of the curve c.
+ xRange: % -> SEG SF
+ ++ xRange(c) returns the range of the x-coordinates of the points
+ ++ on the curve c.
+ yRange: % -> SEG SF
+ ++ yRange(c) returns the range of the y-coordinates of the points
+ ++ on the curve c.
+ zRange: % -> SEG SF
+ ++ zRange(c) returns the range of the z-coordinates of the points
+ ++ on the curve c.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PPCURVE PlottablePlaneCurveCategory>>
+<<category PSCURVE PlottableSpaceCurveCategory>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pdecomp.spad.pamphlet b/src/algebra/pdecomp.spad.pamphlet
new file mode 100644
index 00000000..37057fc4
--- /dev/null
+++ b/src/algebra/pdecomp.spad.pamphlet
@@ -0,0 +1,135 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pdecomp.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PCOMP PolynomialComposition}
+<<package PCOMP PolynomialComposition>>=
+)abbrev package PCOMP PolynomialComposition
+++ Description:
+++ This package \undocumented
+PolynomialComposition(UP: UnivariatePolynomialCategory(R), R: Ring): with
+ compose: (UP, UP) -> UP
+ ++ compose(p,q) \undocumented
+ == add
+ compose(g, h) ==
+ r: UP := 0
+ while g ^= 0 repeat
+ r := leadingCoefficient(g)*h**degree(g) + r
+ g := reductum g
+ r
+
+@
+\section{package PDECOMP PolynomialDecomposition}
+<<package PDECOMP PolynomialDecomposition>>=
+)abbrev package PDECOMP PolynomialDecomposition
+++ Description:
+++ This package \undocumented
+-- Ref: Kozen and Landau, Cornell University TR 86-773
+PolynomialDecomposition(UP, F): PDcat == PDdef where
+ F:Field
+ UP:UnivariatePolynomialCategory F
+ NNI ==> NonNegativeInteger
+ LR ==> Record(left: UP, right: UP)
+
+ PDcat == with
+ decompose: UP -> List UP
+ ++ decompose(up) \undocumented
+ decompose: (UP, NNI, NNI) -> Union(LR, "failed")
+ ++ decompose(up,m,n) \undocumented
+ leftFactor: (UP, UP) -> Union(UP, "failed")
+ ++ leftFactor(p,q) \undocumented
+ rightFactorCandidate: (UP, NNI) -> UP
+ ++ rightFactorCandidate(p,n) \undocumented
+ PDdef == add
+ leftFactor(f, h) ==
+ g: UP := 0
+ for i in 0.. while f ^= 0 repeat
+ fr := divide(f, h)
+ f := fr.quotient; r := fr.remainder
+ degree r > 0 => return "failed"
+ g := g + r * monomial(1, i)
+ g
+
+ decompose(f, dg, dh) ==
+ df := degree f
+ dg*dh ^= df => "failed"
+ h := rightFactorCandidate(f, dh)
+ g := leftFactor(f, h)
+ g case "failed" => "failed"
+ [g::UP, h]
+
+ decompose f ==
+ df := degree f
+ for dh in 2..df-1 | df rem dh = 0 repeat
+ h := rightFactorCandidate(f, dh)
+ g := leftFactor(f, h)
+ g case UP => return
+ append(decompose(g::UP), decompose h)
+ [f]
+ rightFactorCandidate(f, dh) ==
+ f := f/leadingCoefficient f
+ df := degree f
+ dg := df quo dh
+ h := monomial(1, dh)
+ for k in 1..dh repeat
+ hdg:= h**dg
+ c := (coefficient(f,(df-k)::NNI)-coefficient(hdg,(df-k)::NNI))/(dg::F)
+ h := h + monomial(c, (dh-k)::NNI)
+ h - monomial(coefficient(h, 0), 0) -- drop constant term
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+--% Polynomial composition and decomposition functions
+-- If f = g o h then g = leftFactor(f, h) & h = rightFactor(f, g)
+-- SMW Dec 86
+
+<<package PCOMP PolynomialComposition>>
+<<package PDECOMP PolynomialDecomposition>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/perm.spad.pamphlet b/src/algebra/perm.spad.pamphlet
new file mode 100644
index 00000000..23f24341
--- /dev/null
+++ b/src/algebra/perm.spad.pamphlet
@@ -0,0 +1,534 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra perm.spad}
+\author{Holger Gollan, Johannes Grabmeier, Gerhard Schneider}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PERMCAT PermutationCategory}
+<<category PERMCAT PermutationCategory>>=
+)abbrev category PERMCAT PermutationCategory
+++ Authors: Holger Gollan, Johannes Grabmeier, Gerhard Schneider
+++ Date Created: 27 July 1989
+++ Date Last Updated: 29 March 1990
+++ Basic Operations: cycle, cycles, eval, orbit
+++ Related Constructors: PermutationGroup, PermutationGroupExamples
+++ Also See: RepresentationTheoryPackage1
+++ AMS Classifications:
+++ Keywords: permutation, symmetric group
+++ References:
+++ Description: PermutationCategory provides a categorial environment
+++ for subgroups of bijections of a set (i.e. permutations)
+
+PermutationCategory(S:SetCategory): Category == Group with
+ cycle : List S -> %
+ ++ cycle(ls) coerces a cycle {\em ls}, i.e. a list with not
+ ++ repetitions to a permutation, which maps {\em ls.i} to
+ ++ {\em ls.i+1}, indices modulo the length of the list.
+ ++ Error: if repetitions occur.
+ cycles : List List S -> %
+ ++ cycles(lls) coerces a list list of cycles {\em lls}
+ ++ to a permutation, each cycle being a list with not
+ ++ repetitions, is coerced to the permutation, which maps
+ ++ {\em ls.i} to {\em ls.i+1}, indices modulo the length of the list,
+ ++ then these permutations are mutiplied.
+ ++ Error: if repetitions occur in one cycle.
+ eval : (%,S) -> S
+ ++ eval(p, el) returns the image of {\em el} under the
+ ++ permutation p.
+ elt : (%,S) -> S
+ ++ elt(p, el) returns the image of {\em el} under the
+ ++ permutation p.
+ orbit : (%,S) -> Set S
+ ++ orbit(p, el) returns the orbit of {\em el} under the
+ ++ permutation p, i.e. the set which is given by applications of
+ ++ the powers of p to {\em el}.
+ "<" : (%,%) -> Boolean
+ ++ p < q is an order relation on permutations.
+ ++ Note: this order is only total if and only if S is totally ordered
+ ++ or S is finite.
+ if S has OrderedSet then OrderedSet
+ if S has Finite then OrderedSet
+
+@
+\section{domain PERM Permutation}
+<<domain PERM Permutation>>=
+)abbrev domain PERM Permutation
+++ Authors: Johannes Grabmeier, Holger Gollan
+++ Date Created: 19 May 1989
+++ Date Last Updated: 2 June 2006
+++ Basic Operations: _*, degree, movedPoints, cyclePartition, order,
+++ numberOfCycles, sign, even?, odd?
+++ Related Constructors: PermutationGroup, PermutationGroupExamples
+++ Also See: RepresentationTheoryPackage1
+++ AMS Classifications:
+++ Keywords:
+++ Reference: G. James/A. Kerber: The Representation Theory of the Symmetric
+++ Group. Encycl. of Math. and its Appl., Vol. 16., Cambridge
+++ Description: Permutation(S) implements the group of all bijections
+++ on a set S, which move only a finite number of points.
+++ A permutation is considered as a map from S into S. In particular
+++ multiplication is defined as composition of maps:
+++ {\em pi1 * pi2 = pi1 o pi2}.
+++ The internal representation of permuatations are two lists
+++ of equal length representing preimages and images.
+
+Permutation(S:SetCategory): public == private where
+
+ B ==> Boolean
+ PI ==> PositiveInteger
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ V ==> Vector
+ PT ==> Partition
+ OUTFORM ==> OutputForm
+ RECCYPE ==> Record(cycl: L L S, permut: %)
+ RECPRIM ==> Record(preimage: L S, image : L S)
+
+ public ==> PermutationCategory S with
+
+ listRepresentation: % -> RECPRIM
+ ++ listRepresentation(p) produces a representation {\em rep} of
+ ++ the permutation p as a list of preimages and images, i.e
+ ++ p maps {\em (rep.preimage).k} to {\em (rep.image).k} for all
+ ++ indices k. Elements of \spad{S} not in {\em (rep.preimage).k}
+ ++ are fixed points, and these are the only fixed points of the
+ ++ permutation.
+ coercePreimagesImages : List List S -> %
+ ++ coercePreimagesImages(lls) coerces the representation {\em lls}
+ ++ of a permutation as a list of preimages and images to a permutation.
+ ++ We assume that both preimage and image do not contain repetitions.
+ coerce : List List S -> %
+ ++ coerce(lls) coerces a list of cycles {\em lls} to a
+ ++ permutation, each cycle being a list with no
+ ++ repetitions, is coerced to the permutation, which maps
+ ++ {\em ls.i} to {\em ls.i+1}, indices modulo the length of the list,
+ ++ then these permutations are mutiplied.
+ ++ Error: if repetitions occur in one cycle.
+ coerce : List S -> %
+ ++ coerce(ls) coerces a cycle {\em ls}, i.e. a list with not
+ ++ repetitions to a permutation, which maps {\em ls.i} to
+ ++ {\em ls.i+1}, indices modulo the length of the list.
+ ++ Error: if repetitions occur.
+ coerceListOfPairs : List List S -> %
+ ++ coerceListOfPairs(lls) coerces a list of pairs {\em lls} to a
+ ++ permutation.
+ ++ Error: if not consistent, i.e. the set of the first elements
+ ++ coincides with the set of second elements.
+ --coerce : % -> OUTFORM
+ ++ coerce(p) generates output of the permutation p with domain
+ ++ OutputForm.
+ degree : % -> NonNegativeInteger
+ ++ degree(p) retuns the number of points moved by the
+ ++ permutation p.
+ movedPoints : % -> Set S
+ ++ movedPoints(p) returns the set of points moved by the permutation p.
+ cyclePartition : % -> Partition
+ ++ cyclePartition(p) returns the cycle structure of a permutation
+ ++ p including cycles of length 1 only if S is finite.
+ order : % -> NonNegativeInteger
+ ++ order(p) returns the order of a permutation p as a group element.
+ numberOfCycles : % -> NonNegativeInteger
+ ++ numberOfCycles(p) returns the number of non-trivial cycles of
+ ++ the permutation p.
+ sign : % -> Integer
+ ++ sign(p) returns the signum of the permutation p, +1 or -1.
+ even? : % -> Boolean
+ ++ even?(p) returns true if and only if p is an even permutation,
+ ++ i.e. {\em sign(p)} is 1.
+ odd? : % -> Boolean
+ ++ odd?(p) returns true if and only if p is an odd permutation
+ ++ i.e. {\em sign(p)} is {\em -1}.
+ sort : L % -> L %
+ ++ sort(lp) sorts a list of permutations {\em lp} according to
+ ++ cycle structure first according to length of cycles,
+ ++ second, if S has \spadtype{Finite} or S has
+ ++ \spadtype{OrderedSet} according to lexicographical order of
+ ++ entries in cycles of equal length.
+ if S has Finite then
+ fixedPoints : % -> Set S
+ ++ fixedPoints(p) returns the points fixed by the permutation p.
+ if S has IntegerNumberSystem or S has Finite then
+ coerceImages : L S -> %
+ ++ coerceImages(ls) coerces the list {\em ls} to a permutation
+ ++ whose image is given by {\em ls} and the preimage is fixed
+ ++ to be {\em [1,...,n]}.
+ ++ Note: {coerceImages(ls)=coercePreimagesImages([1,...,n],ls)}.
+ ++ We assume that both preimage and image do not contain repetitions.
+
+ private ==> add
+
+ -- representation of the object:
+
+ Rep := V L S
+@
+
+We represent a permutation as two lists of equal length representing preimages
+and images of moved points. I.e., fixed points do not occur in either of these
+lists. This enables us to compute the set of fixed points and the set of moved
+points easily.
+
+Note that this was not respected in versions before [[patch--50]] of this
+domain.
+
+<<domain PERM Permutation>>=
+ -- import of domains and packages
+
+ import OutputForm
+ import Vector List S
+
+ -- variables
+
+ p,q : %
+ exp : I
+
+ -- local functions first, signatures:
+
+ smaller? : (S,S) -> B
+ rotateCycle: L S -> L S
+ coerceCycle: L L S -> %
+ smallerCycle?: (L S, L S) -> B
+ shorterCycle?:(L S, L S) -> B
+ permord:(RECCYPE,RECCYPE) -> B
+ coerceToCycle:(%,B) -> L L S
+ duplicates?: L S -> B
+
+ smaller?(a:S, b:S): B ==
+ S has OrderedSet => a <$S b
+ S has Finite => lookup a < lookup b
+ false
+
+ rotateCycle(cyc: L S): L S ==
+ -- smallest element is put in first place
+ -- doesn't change cycle if underlying set
+ -- is not ordered or not finite.
+ min:S := first cyc
+ minpos:I := 1 -- 1 = minIndex cyc
+ for i in 2..maxIndex cyc repeat
+ if smaller?(cyc.i,min) then
+ min := cyc.i
+ minpos := i
+-- one? minpos => cyc
+ (minpos = 1) => cyc
+ concat(last(cyc,((#cyc-minpos+1)::NNI)),first(cyc,(minpos-1)::NNI))
+
+ coerceCycle(lls : L L S): % ==
+ perm : % := 1
+ for lists in reverse lls repeat
+ perm := cycle lists * perm
+ perm
+
+ smallerCycle?(cyca: L S, cycb: L S): B ==
+ #cyca ^= #cycb =>
+ #cyca < #cycb
+ for i in cyca for j in cycb repeat
+ i ^= j => return smaller?(i, j)
+ false
+
+ shorterCycle?(cyca: L S, cycb: L S): B ==
+ #cyca < #cycb
+
+ permord(pa: RECCYPE, pb : RECCYPE): B ==
+ for i in pa.cycl for j in pb.cycl repeat
+ i ^= j => return smallerCycle?(i, j)
+ #pa.cycl < #pb.cycl
+
+ coerceToCycle(p: %, doSorting?: B): L L S ==
+ preim := p.1
+ im := p.2
+ cycles := nil()$(L L S)
+ while not null preim repeat
+ -- start next cycle
+ firstEltInCycle: S := first preim
+ nextCycle : L S := list firstEltInCycle
+ preim := rest preim
+ nextEltInCycle := first im
+ im := rest im
+ while nextEltInCycle ^= firstEltInCycle repeat
+ nextCycle := cons(nextEltInCycle, nextCycle)
+ i := position(nextEltInCycle, preim)
+ preim := delete(preim,i)
+ nextEltInCycle := im.i
+ im := delete(im,i)
+ nextCycle := reverse nextCycle
+ -- check on 1-cycles, we don't list these
+ if not null rest nextCycle then
+ if doSorting? and (S has OrderedSet or S has Finite) then
+ -- put smallest element in cycle first:
+ nextCycle := rotateCycle nextCycle
+ cycles := cons(nextCycle, cycles)
+ not doSorting? => cycles
+ -- sort cycles
+ S has OrderedSet or S has Finite =>
+ sort(smallerCycle?,cycles)$(L L S)
+ sort(shorterCycle?,cycles)$(L L S)
+
+ duplicates? (ls : L S ): B ==
+ x := copy ls
+ while not null x repeat
+ member? (first x ,rest x) => return true
+ x := rest x
+ false
+
+ -- now the exported functions
+
+ listRepresentation p ==
+ s : RECPRIM := [p.1,p.2]
+
+ coercePreimagesImages preImageAndImage ==
+ preImage: List S := []
+ image: List S := []
+ for i in preImageAndImage.1
+ for pi in preImageAndImage.2 repeat
+ if i ~= pi then
+ preImage := cons(i, preImage)
+ image := cons(pi, image)
+
+ [preImage, image]
+@
+
+This operation transforms a pair of preimages and images into an element of the
+domain. Since we assume that fixed points do not occur in the representation,
+we have to sort them out here.
+
+Note that before [[patch--50]] this read
+\begin{verbatim}
+ coercePreimagesImages preImageAndImage ==
+ p : % := [preImageAndImage.1,preImageAndImage.2]
+\end{verbatim}
+causing bugs when computing [[movedPoints]], [[fixedPoints]], [[even?]],
+[[odd?]], etc., as reported in Issue~\#295.
+
+The other coercion facilities check for fixed points. It also seems that [[*]]
+removes fixed points from its result.
+
+<<TEST PERM>>=
+ p := coercePreimagesImages([[1,2,3],[1,2,3]])
+ movedPoints p -- should return {}
+ even? p -- should return true
+ p := coercePreimagesImages([[0,1,2,3],[3,0,2,1]])$PERM ZMOD 4
+ fixedPoints p -- should return {2}
+ q := coercePreimagesImages([[0,1,2,3],[1,0]])$PERM ZMOD 4
+ fixedPoints(p*q) -- should return {2,0}
+ even?(p*q) -- should return false
+@
+
+<<domain PERM Permutation>>=
+
+ movedPoints p == construct p.1
+
+ degree p == #movedPoints p
+
+ p = q ==
+ #(preimp := p.1) ^= #(preimq := q.1) => false
+ for i in 1..maxIndex preimp repeat
+ pos := position(preimp.i, preimq)
+ pos = 0 => return false
+ (p.2).i ^= (q.2).pos => return false
+ true
+
+ orbit(p ,el) ==
+ -- start with a 1-element list:
+ out : Set S := brace list el
+ el2 := eval(p, el)
+ while el2 ^= el repeat
+ -- be carefull: insert adds one element
+ -- as side effect to out
+ insert_!(el2, out)
+ el2 := eval(p, el2)
+ out
+
+ cyclePartition p ==
+ partition([#c for c in coerceToCycle(p, false)])$Partition
+
+ order p ==
+ ord: I := lcm removeDuplicates convert cyclePartition p
+ ord::NNI
+
+ sign(p) ==
+ even? p => 1
+ - 1
+
+
+ even?(p) == even?(#(p.1) - numberOfCycles p)
+ -- see the book of James and Kerber on symmetric groups
+ -- for this formula.
+
+ odd?(p) == odd?(#(p.1) - numberOfCycles p)
+
+ pa < pb ==
+ pacyc:= coerceToCycle(pa,true)
+ pbcyc:= coerceToCycle(pb,true)
+ for i in pacyc for j in pbcyc repeat
+ i ^= j => return smallerCycle? ( i, j )
+ maxIndex pacyc < maxIndex pbcyc
+
+ coerce(lls : L L S): % == coerceCycle lls
+
+ coerce(ls : L S): % == cycle ls
+
+ sort(inList : L %): L % ==
+ not (S has OrderedSet or S has Finite) => inList
+ ownList: L RECCYPE := nil()$(L RECCYPE)
+ for sigma in inList repeat
+ ownList :=
+ cons([coerceToCycle(sigma,true),sigma]::RECCYPE, ownList)
+ ownList := sort(permord, ownList)$(L RECCYPE)
+ outList := nil()$(L %)
+ for rec in ownList repeat
+ outList := cons(rec.permut, outList)
+ reverse outList
+
+ coerce (p: %): OUTFORM ==
+ cycles: L L S := coerceToCycle(p,true)
+ outfmL : L OUTFORM := nil()
+ for cycle in cycles repeat
+ outcycL: L OUTFORM := nil()
+ for elt in cycle repeat
+ outcycL := cons(elt :: OUTFORM, outcycL)
+ outfmL := cons(paren blankSeparate reverse outcycL, outfmL)
+ -- The identity element will be output as 1:
+ null outfmL => outputForm(1@Integer)
+ -- represent a single cycle in the form (a b c d)
+ -- and not in the form ((a b c d)):
+ null rest outfmL => first outfmL
+ hconcat reverse outfmL
+
+ cycles(vs ) == coerceCycle vs
+
+ cycle(ls) ==
+ #ls < 2 => 1
+ duplicates? ls => error "cycle: the input contains duplicates"
+ [ls, append(rest ls, list first ls)]
+
+ coerceListOfPairs(loP) ==
+ preim := nil()$(L S)
+ im := nil()$(L S)
+ for pair in loP repeat
+ if first pair ^= second pair then
+ preim := cons(first pair, preim)
+ im := cons(second pair, im)
+ duplicates?(preim) or duplicates?(im) or brace(preim)$(Set S) _
+ ^= brace(im)$(Set S) =>
+ error "coerceListOfPairs: the input cannot be interpreted as a permutation"
+ [preim, im]
+
+ q * p ==
+ -- use vectors for efficiency??
+ preimOfp : V S := construct p.1
+ imOfp : V S := construct p.2
+ preimOfq := q.1
+ imOfq := q.2
+ preimOfqp := nil()$(L S)
+ imOfqp := nil()$(L S)
+ -- 1 = minIndex preimOfp
+ for i in 1..(maxIndex preimOfp) repeat
+ -- find index of image of p.i in q if it exists
+ j := position(imOfp.i, preimOfq)
+ if j = 0 then
+ -- it does not exist
+ preimOfqp := cons(preimOfp.i, preimOfqp)
+ imOfqp := cons(imOfp.i, imOfqp)
+ else
+ -- it exists
+ el := imOfq.j
+ -- if the composition fixes the element, we don't
+ -- have to do anything
+ if el ^= preimOfp.i then
+ preimOfqp := cons(preimOfp.i, preimOfqp)
+ imOfqp := cons(el, imOfqp)
+ -- we drop the parts of q which have to do with p
+ preimOfq := delete(preimOfq, j)
+ imOfq := delete(imOfq, j)
+ [append(preimOfqp, preimOfq), append(imOfqp, imOfq)]
+
+ 1 == new(2,empty())$Rep
+
+ inv p == [p.2, p.1]
+
+ eval(p, el) ==
+ pos := position(el, p.1)
+ pos = 0 => el
+ (p.2).pos
+
+ elt(p, el) == eval(p, el)
+
+ numberOfCycles p == #coerceToCycle(p, false)
+
+
+ if S has IntegerNumberSystem then
+
+ coerceImages (image) ==
+ preImage : L S := [i::S for i in 1..maxIndex image]
+ coercePreimagesImages [preImage,image]
+@
+
+Up to [[patch--50]] we did not check for duplicates.
+
+<<domain PERM Permutation>>=
+ if S has Finite then
+
+ coerceImages (image) ==
+ preImage : L S := [index(i::PI)::S for i in 1..maxIndex image]
+ coercePreimagesImages [preImage,image]
+@
+
+Up to [[patch--50]] we did not check for duplicates.
+
+<<domain PERM Permutation>>=
+ fixedPoints ( p ) == complement movedPoints p
+
+ cyclePartition p ==
+ pt := partition([#c for c in coerceToCycle(p, false)])$Partition
+ pt +$PT conjugate(partition([#fixedPoints(p)])$PT)$PT
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PERMCAT PermutationCategory>>
+<<domain PERM Permutation>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/perman.spad.pamphlet b/src/algebra/perman.spad.pamphlet
new file mode 100644
index 00000000..bc2f63f1
--- /dev/null
+++ b/src/algebra/perman.spad.pamphlet
@@ -0,0 +1,319 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra perman.spad}
+\author{Johannes Grabmeier, Oswald Gschnitzer}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GRAY GrayCode}
+<<package GRAY GrayCode>>=
+)abbrev package GRAY GrayCode
+++ Authors: Johannes Grabmeier, Oswald Gschnitzer
+++ Date Created: 7 August 1989
+++ Date Last Updated: 23 August 1990
+++ Basic Operations: nextSubsetGray
+++ Related Constructors: Permanent
+++ Also See: SymmetricGroupCombinatoric Functions
+++ AMS Classifications:
+++ Keywords: gray code, subsets of finite sets
+++ References:
+++ Henryk Minc: Evaluation of Permanents,
+++ Proc. of the Edinburgh Math. Soc.(1979), 22/1 pp 27-32.
+++ Nijenhuis and Wilf : Combinatorical Algorithms, Academic
+++ Press, New York 1978.
+++ S.G.Williamson, Combinatorics for Computer Science,
+++ Computer Science Press, 1985.
+++ Description:
+++ GrayCode provides a function for efficiently running
+++ through all subsets of a finite set, only changing one element
+++ by another one.
+GrayCode: public == private where
+
+ PI ==> PositiveInteger
+ I ==> Integer
+ V ==> Vector
+
+ public ==> with
+
+ nextSubsetGray: (V V I,PI) -> V V I
+ ++ nextSubsetGray(ww,n) returns a vector {\em vv} whose components
+ ++ have the following meanings:\begin{items}
+ ++ \item {\em vv.1}: a vector of length n whose entries are 0 or 1. This
+ ++ can be interpreted as a code for a subset of the set 1,...,n;
+ ++ {\em vv.1} differs from {\em ww.1} by exactly one entry;
+ ++ \item {\em vv.2.1} is the number of the entry of {\em vv.1} which
+ ++ will be changed next time;
+ ++ \item {\em vv.2.1 = n+1} means that {\em vv.1} is the last subset;
+ ++ trying to compute nextSubsetGray(vv) if {\em vv.2.1 = n+1}
+ ++ will produce an error!
+ ++ \end{items}
+ ++ The other components of {\em vv.2} are needed to compute
+ ++ nextSubsetGray efficiently.
+ ++ Note: this is an implementation of [Williamson, Topic II, 3.54,
+ ++ p. 112] for the special case {\em r1 = r2 = ... = rn = 2};
+ ++ Note: nextSubsetGray produces a side-effect, i.e.
+ ++ {\em nextSubsetGray(vv)} and {\em vv := nextSubsetGray(vv)}
+ ++ will have the same effect.
+
+ firstSubsetGray: PI -> V V I
+ ++ firstSubsetGray(n) creates the first vector {\em ww} to start a
+ ++ loop using {\em nextSubsetGray(ww,n)}
+
+ private ==> add
+
+ firstSubsetGray(n : PI) ==
+ vv : V V I := new(2,[])
+ vv.1 := new(n,0) : V I
+ vv.2 := new(n+1,1) : V I
+ for i in 1..(n+1) repeat
+ vv.2.i := i
+ vv
+
+ nextSubsetGray(vv : V V I,n : PI) ==
+ subs : V I := vv.1 -- subset
+ lab : V I := vv.2 -- labels
+ c : I := lab(1) -- element which is to be changed next
+ lab(1):= 1
+ if subs.c = 0 then subs.c := 1
+ else subs.c := 0
+ lab.c := lab(c+1)
+ lab(c+1) := c+1
+ vv
+
+@
+\section{package PERMAN Permanent}
+<<package PERMAN Permanent>>=
+)abbrev package PERMAN Permanent
+++ Authors: Johannes Grabmeier, Oswald Gschnitzer
+++ Date Created: 7 August 1989
+++ Date Last Updated: 23 August 1990
+++ Basic Operations: permanent
+++ Related Constructors: GrayCode
+++ Also See: MatrixLinearAlgebraFunctions
+++ AMS Classifications:
+++ Keywords: permanent
+++ References:
+++ Henryk Minc: Evaluation of Permanents,
+++ Proc. of the Edinburgh Math. Soc.(1979), 22/1 pp 27-32.
+++ Nijenhuis and Wilf : Combinatorical Algorithms, Academic
+++ Press, New York 1978.
+++ S.G.Williamson, Combinatorics for Computer Science,
+++ Computer Science Press, 1985.
+++ Description:
+++ Permanent implements the functions {\em permanent}, the
+++ permanent for square matrices.
+Permanent(n : PositiveInteger, R : Ring with commutative("*")):
+ public == private where
+ I ==> Integer
+ L ==> List
+ V ==> Vector
+ SM ==> SquareMatrix(n,R)
+ VECTPKG1 ==> VectorPackage1(I)
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ GRAY ==> GrayCode
+
+ public ==> with
+
+ permanent: SM -> R
+ ++ permanent(x) computes the permanent of a square matrix x.
+ ++ The {\em permanent} is equivalent to
+ ++ the \spadfun{determinant} except that coefficients have
+ ++ no change of sign. This function
+ ++ is much more difficult to compute than the
+ ++ {\em determinant}. The formula used is by H.J. Ryser,
+ ++ improved by [Nijenhuis and Wilf, Ch. 19].
+ ++ Note: permanent(x) choose one of three algorithms, depending
+ ++ on the underlying ring R and on n, the number of rows (and
+ ++ columns) of x:\begin{items}
+ ++ \item 1. if 2 has an inverse in R we can use the algorithm of
+ ++ [Nijenhuis and Wilf, ch.19,p.158]; if 2 has no inverse,
+ ++ some modifications are necessary:
+ ++ \item 2. if {\em n > 6} and R is an integral domain with characteristic
+ ++ different from 2 (the algorithm works if and only 2 is not a
+ ++ zero-divisor of R and {\em characteristic()$R ^= 2},
+ ++ but how to check that for any given R ?),
+ ++ the local function {\em permanent2} is called;
+ ++ \item 3. else, the local function {\em permanent3} is called
+ ++ (works for all commutative rings R).
+ ++ \end{items}
+
+ private ==> add
+
+ -- local functions:
+
+ permanent2: SM -> R
+
+ permanent3: SM -> R
+
+ x : SM
+ a,b : R
+ i,j,k,l : I
+
+ permanent3(x) ==
+ -- This algorithm is based upon the principle of inclusion-
+ -- exclusion. A Gray-code is used to generate the subsets of
+ -- 1,... ,n. This reduces the number of additions needed in
+ -- every step.
+ sgn : R := 1
+ k : R
+ a := 0$R
+ vv : V V I := firstSubsetGray(n)$GRAY
+ -- For the meaning of the elements of vv, see GRAY.
+ w : V R := new(n,0$R)
+ j := 1 -- Will be the number of the element changed in subset
+ while j ^= (n+1) repeat -- we sum over all subsets of (1,...,n)
+ sgn := -sgn
+ b := sgn
+ if vv.1.j = 1 then k := -1
+ else k := 1 -- was that element deleted(k=-1) or added(k=1)?
+ for i in 1..(n::I) repeat
+ w.i := w.i +$R k *$R x(i,j)
+ b := b *$R w.i
+ a := a +$R b
+ vv := nextSubsetGray(vv,n)$GRAY
+ j := vv.2.1
+ if odd?(n) then a := -a
+ a
+
+
+ permanent(x) ==
+ -- If 2 has an inverse in R, we can spare half of the calcu-
+ -- lation needed in "permanent3": This is the algorithm of
+ -- [Nijenhuis and Wilf, ch.19,p.158]
+ n = 1 => x(1,1)
+ two : R := (2:I) :: R
+ half : Union(R,"failed") := recip(two)
+ if (half case "failed") then
+ if n < 7 then return permanent3(x)
+ else return permanent2(x)
+ sgn : R := 1
+ a := 0$R
+ w : V R := new(n,0$R)
+ -- w.i will be at first x.i and later lambda.i in
+ -- [Nijenhuis and Wilf, p.158, (24a) resp.(26)].
+ rowi : V R := new(n,0$R)
+ for i in 1..n repeat
+ rowi := row(x,i) :: V R
+ b := 0$R
+ for j in 1..n repeat
+ b := b + rowi.j
+ w.i := rowi(n) - (half*b)$R
+ vv : V V I := firstSubsetGray((n-1): PI)$GRAY
+ -- For the meaning of the elements of vv, see GRAY.
+ n :: I
+ b := 1
+ for i in 1..n repeat
+ b := b * w.i
+ a := a+b
+ j := 1 -- Will be the number of the element changed in subset
+ while j ^= n repeat -- we sum over all subsets of (1,...,n-1)
+ sgn := -sgn
+ b := sgn
+ if vv.1.j = 1 then k := -1
+ else k := 1 -- was that element deleted(k=-1) or added(k=1)?
+ for i in 1..n repeat
+ w.i := w.i +$R k *$R x(i,j)
+ b := b *$R w.i
+ a := a +$R b
+ vv := nextSubsetGray(vv,(n-1) : PI)$GRAY
+ j := vv.2.1
+ if not odd?(n) then a := -a
+ two * a
+
+ permanent2(x) ==
+ c : R := 0
+ sgn : R := 1
+ if (not (R has IntegralDomain))
+ -- or (characteristic()$R = (2:NNI))
+ -- compiler refuses to compile the line above !!
+ or (sgn + sgn = c)
+ then return permanent3(x)
+ -- This is a slight modification of permanent which is
+ -- necessary if 2 is not zero or a zero-divisor in R, but has
+ -- no inverse in R.
+ n = 1 => x(1,1)
+ two : R := (2:I) :: R
+ a := 0$R
+ w : V R := new(n,0$R)
+ -- w.i will be at first x.i and later lambda.i in
+ -- [Nijenhuis and Wilf, p.158, (24a) resp.(26)].
+ rowi : V R := new(n,0$R)
+ for i in 1..n repeat
+ rowi := row(x,i) :: V R
+ b := 0$R
+ for j in 1..n repeat
+ b := b + rowi.j
+ w.i := (two*(rowi(n)))$R - b
+ vv : V V I := firstSubsetGray((n-1): PI)$GRAY
+ n :: I
+ b := 1
+ for i in 1..n repeat
+ b := b *$R w.i
+ a := a +$R b
+ j := 1 -- Will be the number of the element changed in subset
+ while j ^= n repeat -- we sum over all subsets of (1,...,n-1)
+ sgn := -sgn
+ b := sgn
+ if vv.1.j = 1 then k := -1
+ else k := 1 -- was that element deleted(k=-1) or added(k=1)?
+ c := k * two
+ for i in 1..n repeat
+ w.i := w.i +$R c *$R x(i,j)
+ b := b *$R w.i
+ a := a +$R b
+ vv := nextSubsetGray(vv,(n-1) : PI)$GRAY
+ j := vv.2.1
+ if not odd?(n) then a := -a
+ b := two ** ((n-1):NNI)
+ (a exquo b) :: R
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package GRAY GrayCode>>
+<<package PERMAN Permanent>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/permgrps.spad.pamphlet b/src/algebra/permgrps.spad.pamphlet
new file mode 100644
index 00000000..0b3fa62d
--- /dev/null
+++ b/src/algebra/permgrps.spad.pamphlet
@@ -0,0 +1,1188 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra permgrps.spad}
+\author{Gerhard Schneider, Holger Gollan, Johannes Grabmeier, M. Weller}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PERMGRP PermutationGroup}
+<<domain PERMGRP PermutationGroup>>=
+)abbrev domain PERMGRP PermutationGroup
+++ Authors: G. Schneider, H. Gollan, J. Grabmeier
+++ Date Created: 13 February 1987
+++ Date Last Updated: 24 May 1991
+++ Basic Operations:
+++ Related Constructors: PermutationGroupExamples, Permutation
+++ Also See: RepresentationTheoryPackage1
+++ AMS Classifications:
+++ Keywords: permutation, permutation group, group operation, word problem
+++ References:
+++ C. Sims: Determining the conjugacy classes of a permutation group,
+++ in Computers in Algebra and Number Theory, SIAM-AMS Proc., Vol. 4,
+++ Amer. Math. Soc., Providence, R. I., 1971, pp. 191-195
+++ Description:
+++ PermutationGroup implements permutation groups acting
+++ on a set S, i.e. all subgroups of the symmetric group of S,
+++ represented as a list of permutations (generators). Note that
+++ therefore the objects are not members of the \Language category
+++ \spadtype{Group}.
+++ Using the idea of base and strong generators by Sims,
+++ basic routines and algorithms
+++ are implemented so that the word problem for
+++ permutation groups can be solved.
+--++ Note: we plan to implement lattice operations on the subgroup
+--++ lattice in a later release
+
+PermutationGroup(S:SetCategory): public == private where
+
+ L ==> List
+ PERM ==> Permutation
+ FSET ==> Set
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ V ==> Vector
+ B ==> Boolean
+ OUT ==> OutputForm
+ SYM ==> Symbol
+ REC ==> Record ( orb : L NNI , svc : V I )
+ REC2 ==> Record(order:NNI,sgset:L V NNI,_
+ gpbase:L NNI,orbs:L REC,mp:L S,wd:L L NNI)
+ REC3 ==> Record(elt:V NNI,lst:L NNI)
+ REC4 ==> Record(bool:B,lst:L NNI)
+
+ public ==> SetCategory with
+
+ coerce : % -> L PERM S
+ ++ coerce(gp) returns the generators of the group {\em gp}.
+ generators : % -> L PERM S
+ ++ generators(gp) returns the generators of the group {\em gp}.
+ elt : (%,NNI) -> PERM S
+ ++ elt(gp,i) returns the i-th generator of the group {\em gp}.
+ random : (%,I) -> PERM S
+ ++ random(gp,i) returns a random product of maximal i generators
+ ++ of the group {\em gp}.
+ random : % -> PERM S
+ ++ random(gp) returns a random product of maximal 20 generators
+ ++ of the group {\em gp}.
+ ++ Note: {\em random(gp)=random(gp,20)}.
+ order : % -> NNI
+ ++ order(gp) returns the order of the group {\em gp}.
+ degree : % -> NNI
+ ++ degree(gp) returns the number of points moved by all permutations
+ ++ of the group {\em gp}.
+ base : % -> L S
+ ++ base(gp) returns a base for the group {\em gp}.
+ strongGenerators : % -> L PERM S
+ ++ strongGenerators(gp) returns strong generators for
+ ++ the group {\em gp}.
+ wordsForStrongGenerators : % -> L L NNI
+ ++ wordsForStrongGenerators(gp) returns the words for the strong
+ ++ generators of the group {\em gp} in the original generators of
+ ++ {\em gp}, represented by their indices in the list, given by
+ ++ {\em generators}.
+ coerce : L PERM S -> %
+ ++ coerce(ls) coerces a list of permutations {\em ls} to the group
+ ++ generated by this list.
+ permutationGroup : L PERM S -> %
+ ++ permutationGroup(ls) coerces a list of permutations {\em ls} to
+ ++ the group generated by this list.
+ orbit : (%,S) -> FSET S
+ ++ orbit(gp,el) returns the orbit of the element {\em el} under the
+ ++ group {\em gp}, i.e. the set of all points gained by applying
+ ++ each group element to {\em el}.
+ orbits : % -> FSET FSET S
+ ++ orbits(gp) returns the orbits of the group {\em gp}, i.e.
+ ++ it partitions the (finite) of all moved points.
+ orbit : (%,FSET S)-> FSET FSET S
+ ++ orbit(gp,els) returns the orbit of the unordered
+ ++ set {\em els} under the group {\em gp}.
+ orbit : (%,L S) -> FSET L S
+ ++ orbit(gp,ls) returns the orbit of the ordered
+ ++ list {\em ls} under the group {\em gp}.
+ ++ Note: return type is L L S temporarily because FSET L S has an error.
+ -- (GILT DAS NOCH?)
+ member? : (PERM S, %)-> B
+ ++ member?(pp,gp) answers the question, whether the
+ ++ permutation {\em pp} is in the group {\em gp} or not.
+ wordInStrongGenerators : (PERM S, %)-> L NNI
+ ++ wordInStrongGenerators(p,gp) returns the word for the
+ ++ permutation p in the strong generators of the group {\em gp},
+ ++ represented by the indices of the list, given by {\em strongGenerators}.
+ wordInGenerators : (PERM S, %)-> L NNI
+ ++ wordInGenerators(p,gp) returns the word for the permutation p
+ ++ in the original generators of the group {\em gp},
+ ++ represented by the indices of the list, given by {\em generators}.
+ movedPoints : % -> FSET S
+ ++ movedPoints(gp) returns the points moved by the group {\em gp}.
+ "<" : (%,%) -> B
+ ++ gp1 < gp2 returns true if and only if {\em gp1}
+ ++ is a proper subgroup of {\em gp2}.
+ "<=" : (%,%) -> B
+ ++ gp1 <= gp2 returns true if and only if {\em gp1}
+ ++ is a subgroup of {\em gp2}.
+ ++ Note: because of a bug in the parser you have to call this
+ ++ function explicitly by {\em gp1 <=$(PERMGRP S) gp2}.
+ -- (GILT DAS NOCH?)
+ initializeGroupForWordProblem : % -> Void
+ ++ initializeGroupForWordProblem(gp) initializes the group {\em gp}
+ ++ for the word problem.
+ ++ Notes: it calls the other function of this name with parameters
+ ++ 0 and 1: {\em initializeGroupForWordProblem(gp,0,1)}.
+ ++ Notes: (1) be careful: invoking this routine will destroy the
+ ++ possibly information about your group (but will recompute it again)
+ ++ (2) users need not call this function normally for the soultion of
+ ++ the word problem.
+ initializeGroupForWordProblem :(%,I,I) -> Void
+ ++ initializeGroupForWordProblem(gp,m,n) initializes the group
+ ++ {\em gp} for the word problem.
+ ++ Notes: (1) with a small integer you get shorter words, but the
+ ++ routine takes longer than the standard routine for longer words.
+ ++ (2) be careful: invoking this routine will destroy the possibly stored
+ ++ information about your group (but will recompute it again).
+ ++ (3) users need not call this function normally for the soultion of
+ ++ the word problem.
+
+ private ==> add
+
+ -- representation of the object:
+
+ Rep := Record ( gens : L PERM S , information : REC2 )
+
+ -- import of domains and packages
+
+ import Permutation S
+ import OutputForm
+ import Symbol
+ import Void
+
+ --first the local variables
+
+ sgs : L V NNI := []
+ baseOfGroup : L NNI := []
+ sizeOfGroup : NNI := 1
+ degree : NNI := 0
+ gporb : L REC := []
+ out : L L V NNI := []
+ outword : L L L NNI := []
+ wordlist : L L NNI := []
+ basePoint : NNI := 0
+ newBasePoint : B := true
+ supp : L S := []
+ ord : NNI := 1
+ wordProblem : B := true
+
+ --local functions first, signatures:
+
+ shortenWord:(L NNI, %)->L NNI
+ times:(V NNI, V NNI)->V NNI
+ strip:(V NNI,REC,L V NNI,L L NNI)->REC3
+ orbitInternal:(%,L S )->L L S
+ inv: V NNI->V NNI
+ ranelt:(L V NNI,L L NNI, I)->REC3
+ testIdentity:V NNI->B
+ pointList: %->L S
+ orbitWithSvc:(L V NNI ,NNI )->REC
+ cosetRep:(NNI ,REC ,L V NNI )->REC3
+ bsgs1:(L V NNI,NNI,L L NNI,I,%,I)->NNI
+ computeOrbits: I->L NNI
+ reduceGenerators: I->Void
+ bsgs:(%, I, I)->NNI
+ initialize: %->FSET PERM S
+ knownGroup?: %->Void
+ subgroup:(%, %)->B
+ memberInternal:(PERM S, %, B)->REC4
+
+ --local functions first, implementations:
+
+ shortenWord ( lw : L NNI , gp : % ) : L NNI ==
+ -- tries to shorten a word in the generators by removing identities
+ gpgens : L PERM S := coerce gp
+ orderList : L NNI := [ order gen for gen in gpgens ]
+ newlw : L NNI := copy lw
+ for i in 1.. maxIndex orderList repeat
+ if orderList.i = 1 then
+ while member?(i,newlw) repeat
+ -- removing the trivial element
+ pos := position(i,newlw)
+ newlw := delete(newlw,pos)
+ flag : B := true
+ while flag repeat
+ actualLength : NNI := (maxIndex newlw) pretend NNI
+ pointer := actualLength
+ test := newlw.pointer
+ anzahl : NNI := 1
+ flag := false
+ while pointer > 1 repeat
+ pointer := ( pointer - 1 )::NNI
+ if newlw.pointer ^= test then
+ -- don't get a trivial element, try next
+ test := newlw.pointer
+ anzahl := 1
+ else
+ anzahl := anzahl + 1
+ if anzahl = orderList.test then
+ -- we have an identity, so remove it
+ for i in (pointer+anzahl)..actualLength repeat
+ newlw.(i-anzahl) := newlw.i
+ newlw := first(newlw, (actualLength - anzahl) :: NNI)
+ flag := true
+ pointer := 1
+ newlw
+
+ times ( p : V NNI , q : V NNI ) : V NNI ==
+ -- internal multiplication of permutations
+ [ qelt(p,qelt(q,i)) for i in 1..degree ]
+
+ strip(element:V NNI,orbit:REC,group:L V NNI,words:L L NNI) : REC3 ==
+ -- strip an element into the stabilizer
+ actelt := element
+ schreierVector := orbit.svc
+ point := orbit.orb.1
+ outlist := nil()$(L NNI)
+ entryLessZero : B := false
+ while ^entryLessZero repeat
+ entry := schreierVector.(actelt.point)
+ entryLessZero := (entry < 0)
+ if ^entryLessZero then
+ actelt := times(group.entry, actelt)
+ if wordProblem then outlist := append ( words.(entry::NNI) , outlist )
+ [ actelt , reverse outlist ]
+
+ orbitInternal ( gp : % , startList : L S ) : L L S ==
+ orbitList : L L S := [ startList ]
+ pos : I := 1
+ while not zero? pos repeat
+ gpset : L PERM S := gp.gens
+ for gen in gpset repeat
+ newList := nil()$(L S)
+ workList := orbitList.pos
+ for j in #workList..1 by -1 repeat
+ newList := cons ( eval ( gen , workList.j ) , newList )
+ if ^member?( newList , orbitList ) then
+ orbitList := cons ( newList , orbitList )
+ pos := pos + 1
+ pos := pos - 1
+ reverse orbitList
+
+ inv ( p : V NNI ) : V NNI ==
+ -- internal inverse of a permutation
+ q : V NNI := new(degree,0)$(V NNI)
+ for i in 1..degree repeat q.(qelt(p,i)) := i
+ q
+
+ ranelt ( group : L V NNI , word : L L NNI , maxLoops : I ) : REC3 ==
+ -- generate a "random" element
+ numberOfGenerators := # group
+ randomInteger : I := 1 + (random()$Integer rem numberOfGenerators)
+ randomElement : V NNI := group.randomInteger
+ words := nil()$(L NNI)
+ if wordProblem then words := word.(randomInteger::NNI)
+ if maxLoops > 0 then
+ numberOfLoops : I := 1 + (random()$Integer rem maxLoops)
+ else
+ numberOfLoops : I := maxLoops
+ while numberOfLoops > 0 repeat
+ randomInteger : I := 1 + (random()$Integer rem numberOfGenerators)
+ randomElement := times ( group.randomInteger , randomElement )
+ if wordProblem then words := append ( word.(randomInteger::NNI) , words)
+ numberOfLoops := numberOfLoops - 1
+ [ randomElement , words ]
+
+ testIdentity ( p : V NNI ) : B ==
+ -- internal test for identity
+ for i in 1..degree repeat qelt(p,i) ^= i => return false
+ true
+
+ pointList(group : %) : L S ==
+ support : FSET S := brace() -- empty set !!
+ for perm in group.gens repeat
+ support := union(support, movedPoints perm)
+ parts support
+
+ orbitWithSvc ( group : L V NNI , point : NNI ) : REC ==
+ -- compute orbit with Schreier vector, "-2" means not in the orbit,
+ -- "-1" means starting point, the PI correspond to generators
+ newGroup := nil()$(L V NNI)
+ for el in group repeat
+ newGroup := cons ( inv el , newGroup )
+ newGroup := reverse newGroup
+ orbit : L NNI := [ point ]
+ schreierVector : V I := new ( degree , -2 )
+ schreierVector.point := -1
+ position : I := 1
+ while not zero? position repeat
+ for i in 1..#newGroup repeat
+ newPoint := orbit.position
+ newPoint := newGroup.i.newPoint
+ if ^ member? ( newPoint , orbit ) then
+ orbit := cons ( newPoint , orbit )
+ position := position + 1
+ schreierVector.newPoint := i
+ position := position - 1
+ [ reverse orbit , schreierVector ]
+
+ cosetRep ( point : NNI , o : REC , group : L V NNI ) : REC3 ==
+ ppt := point
+ xelt : V NNI := [ n for n in 1..degree ]
+ word := nil()$(L NNI)
+ oorb := o.orb
+ osvc := o.svc
+ while degree > 0 repeat
+ p := osvc.ppt
+ p < 0 => return [ xelt , word ]
+ x := group.p
+ xelt := times ( x , xelt )
+ if wordProblem then word := append ( wordlist.p , word )
+ ppt := x.ppt
+
+ bsgs1 (group:L V NNI,number1:NNI,words:L L NNI,maxLoops:I,gp:%,diff:I)_
+ : NNI ==
+ -- try to get a good approximation for the strong generators and base
+ for i in number1..degree repeat
+ ort := orbitWithSvc ( group , i )
+ k := ort.orb
+ k1 := # k
+ if k1 ^= 1 then leave
+ gpsgs := nil()$(L V NNI)
+ words2 := nil()$(L L NNI)
+ gplength : NNI := #group
+ for jj in 1..gplength repeat if (group.jj).i ^= i then leave
+ for k in 1..gplength repeat
+ el2 := group.k
+ if el2.i ^= i then
+ gpsgs := cons ( el2 , gpsgs )
+ if wordProblem then words2 := cons ( words.k , words2 )
+ else
+ gpsgs := cons ( times ( group.jj , el2 ) , gpsgs )
+ if wordProblem _
+ then words2 := cons ( append ( words.jj , words.k ) , words2 )
+ group2 := nil()$(L V NNI)
+ words3 := nil()$(L L NNI)
+ j : I := 15
+ while j > 0 repeat
+ -- find generators for the stabilizer
+ ran := ranelt ( group , words , maxLoops )
+ str := strip ( ran.elt , ort , group , words )
+ el2 := str.elt
+ if ^ testIdentity el2 then
+ if ^ member?(el2,group2) then
+ group2 := cons ( el2 , group2 )
+ if wordProblem then
+ help : L NNI := append ( reverse str.lst , ran.lst )
+ help := shortenWord ( help , gp )
+ words3 := cons ( help , words3 )
+ j := j - 2
+ j := j - 1
+ -- this is for word length control
+ if wordProblem then maxLoops := maxLoops - diff
+ if ( null group2 ) or ( maxLoops < 0 ) then
+ sizeOfGroup := k1
+ baseOfGroup := [ i ]
+ out := [ gpsgs ]
+ outword := [ words2 ]
+ return sizeOfGroup
+ k2 := bsgs1 ( group2 , i + 1 , words3 , maxLoops , gp , diff )
+ sizeOfGroup := k1 * k2
+ out := append ( out , [ gpsgs ] )
+ outword := append ( outword , [ words2 ] )
+ baseOfGroup := cons ( i , baseOfGroup )
+ sizeOfGroup
+
+ computeOrbits ( kkk : I ) : L NNI ==
+ -- compute the orbits for the stabilizers
+ sgs := nil()
+ orbitLength := nil()$(L NNI)
+ gporb := nil()
+ for i in 1..#baseOfGroup repeat
+ sgs := append ( sgs , out.i )
+ pt := #baseOfGroup - i + 1
+ obs := orbitWithSvc ( sgs , baseOfGroup.pt )
+ orbitLength := cons ( #obs.orb , orbitLength )
+ gporb := cons ( obs , gporb )
+ gporb := reverse gporb
+ reverse orbitLength
+
+ reduceGenerators ( kkk : I ) : Void ==
+ -- try to reduce number of strong generators
+ orbitLength := computeOrbits ( kkk )
+ sgs := nil()
+ wordlist := nil()
+ for i in 1..(kkk-1) repeat
+ sgs := append ( sgs , out.i )
+ if wordProblem then wordlist := append ( wordlist , outword.i )
+ removedGenerator := false
+ baseLength : NNI := #baseOfGroup
+ for nnn in kkk..(baseLength-1) repeat
+ sgs := append ( sgs , out.nnn )
+ if wordProblem then wordlist := append ( wordlist , outword.nnn )
+ pt := baseLength - nnn + 1
+ obs := orbitWithSvc ( sgs , baseOfGroup.pt )
+ i := 1
+ while not ( i > # out.nnn ) repeat
+ pos := position ( out.nnn.i , sgs )
+ sgs2 := delete(sgs, pos)
+ obs2 := orbitWithSvc ( sgs2 , baseOfGroup.pt )
+ if # obs2.orb = orbitLength.nnn then
+ test := true
+ for j in (nnn+1)..(baseLength-1) repeat
+ pt2 := baseLength - j + 1
+ sgs2 := append ( sgs2 , out.j )
+ obs2 := orbitWithSvc ( sgs2 , baseOfGroup.pt2 )
+ if # obs2.orb ^= orbitLength.j then
+ test := false
+ leave
+ if test then
+ removedGenerator := true
+ sgs := delete (sgs, pos)
+ if wordProblem then wordlist := delete(wordlist, pos)
+ out.nnn := delete (out.nnn, i)
+ if wordProblem then _
+ outword.nnn := delete(outword.nnn, i )
+ else
+ i := i + 1
+ else
+ i := i + 1
+ if removedGenerator then orbitLength := computeOrbits ( kkk )
+ void()
+
+
+ bsgs ( group : % ,maxLoops : I , diff : I ) : NNI ==
+ -- the MOST IMPORTANT part of the package
+ supp := pointList group
+ degree := # supp
+ if degree = 0 then
+ sizeOfGroup := 1
+ sgs := [ [ 0 ] ]
+ baseOfGroup := nil()
+ gporb := nil()
+ return sizeOfGroup
+ newGroup := nil()$(L V NNI)
+ gp : L PERM S := group.gens
+ words := nil()$(L L NNI)
+ for ggg in 1..#gp repeat
+ q := new(degree,0)$(V NNI)
+ for i in 1..degree repeat
+ newEl := eval ( gp.ggg , supp.i )
+ pos2 := position ( newEl , supp )
+ q.i := pos2 pretend NNI
+ newGroup := cons ( q , newGroup )
+ if wordProblem then words := cons(list ggg, words)
+ if maxLoops < 1 then
+ -- try to get the (approximate) base length
+ if zero? (# ((group.information).gpbase)) then
+ wordProblem := false
+ k := bsgs1 ( newGroup , 1 , words , 20 , group , 0 )
+ wordProblem := true
+ maxLoops := (# baseOfGroup) - 1
+ else
+ maxLoops := (# ((group.information).gpbase)) - 1
+ k := bsgs1 ( newGroup , 1 , words , maxLoops , group , diff )
+ kkk : I := 1
+ newGroup := reverse newGroup
+ noAnswer : B := true
+ while noAnswer repeat
+ reduceGenerators kkk
+-- *** Here is former "bsgs2" *** --
+ -- test whether we have a base and a strong generating set
+ sgs := nil()
+ wordlist := nil()
+ for i in 1..(kkk-1) repeat
+ sgs := append ( sgs , out.i )
+ if wordProblem then wordlist := append ( wordlist , outword.i )
+ noresult : B := true
+ for i in kkk..#baseOfGroup while noresult repeat
+ sgs := append ( sgs , out.i )
+ if wordProblem then wordlist := append ( wordlist , outword.i )
+ gporbi := gporb.i
+ for pt in gporbi.orb while noresult repeat
+ ppp := cosetRep ( pt , gporbi , sgs )
+ y1 := inv ppp.elt
+ word3 := ppp.lst
+ for jjj in 1..#sgs while noresult repeat
+ word := nil()$(L NNI)
+ z := times ( sgs.jjj , y1 )
+ if wordProblem then word := append ( wordlist.jjj , word )
+ ppp := cosetRep ( (sgs.jjj).pt , gporbi , sgs )
+ z := times ( ppp.elt , z )
+ if wordProblem then word := append ( ppp.lst , word )
+ newBasePoint := false
+ for j in (i-1)..1 by -1 while noresult repeat
+ s := gporb.j.svc
+ p := gporb.j.orb.1
+ while ( degree > 0 ) and noresult repeat
+ entry := s.(z.p)
+ if entry < 0 then
+ if entry = -1 then leave
+ basePoint := j::NNI
+ noresult := false
+ else
+ ee := sgs.entry
+ z := times ( ee , z )
+ if wordProblem then word := append ( wordlist.entry , word )
+ if noresult then
+ basePoint := 1
+ newBasePoint := true
+ noresult := testIdentity z
+ noAnswer := not (testIdentity z)
+ if noAnswer then
+ -- we have missed something
+ word2 := nil()$(L NNI)
+ if wordProblem then
+ for wd in word3 repeat
+ ttt := newGroup.wd
+ while not (testIdentity ttt) repeat
+ word2 := cons ( wd , word2 )
+ ttt := times ( ttt , newGroup.wd )
+ word := append ( word , word2 )
+ word := shortenWord ( word , group )
+ if newBasePoint then
+ for i in 1..degree repeat
+ if z.i ^= i then
+ baseOfGroup := append ( baseOfGroup , [ i ] )
+ leave
+ out := cons (list z, out )
+ if wordProblem then outword := cons (list word , outword )
+ else
+ out.basePoint := cons ( z , out.basePoint )
+ if wordProblem then outword.basePoint := cons(word ,outword.basePoint )
+ kkk := basePoint
+ sizeOfGroup := 1
+ for j in 1..#baseOfGroup repeat
+ sizeOfGroup := sizeOfGroup * # gporb.j.orb
+ sizeOfGroup
+
+
+ initialize ( group : % ) : FSET PERM S ==
+ group2 := brace()$(FSET PERM S)
+ gp : L PERM S := group.gens
+ for gen in gp repeat
+ if degree gen > 0 then insert_!(gen, group2)
+ group2
+
+ knownGroup? (gp : %) : Void ==
+ -- do we know the group already?
+ result := gp.information
+ if result.order = 0 then
+ wordProblem := false
+ ord := bsgs ( gp , 20 , 0 )
+ result := [ ord , sgs , baseOfGroup , gporb , supp , [] ]
+ gp.information := result
+ else
+ ord := result.order
+ sgs := result.sgset
+ baseOfGroup := result.gpbase
+ gporb := result.orbs
+ supp := result.mp
+ wordlist := result.wd
+ void
+
+ subgroup ( gp1 : % , gp2 : % ) : B ==
+ gpset1 := initialize gp1
+ gpset2 := initialize gp2
+ empty? difference (gpset1, gpset2) => true
+ for el in parts gpset1 repeat
+ not member? (el, gp2) => return false
+ true
+
+ memberInternal ( p : PERM S , gp : % , flag : B ) : REC4 ==
+ -- internal membership testing
+ supp := pointList gp
+ outlist := nil()$(L NNI)
+ mP : L S := parts movedPoints p
+ for x in mP repeat
+ not member? (x, supp) => return [ false , nil()$(L NNI) ]
+ if flag then
+ member? ( p , gp.gens ) => return [ true , nil()$(L NNI) ]
+ knownGroup? gp
+ else
+ result := gp.information
+ if #(result.wd) = 0 then
+ initializeGroupForWordProblem gp
+ else
+ ord := result.order
+ sgs := result.sgset
+ baseOfGroup := result.gpbase
+ gporb := result.orbs
+ supp := result.mp
+ wordlist := result.wd
+ degree := # supp
+ pp := new(degree,0)$(V NNI)
+ for i in 1..degree repeat
+ el := eval ( p , supp.i )
+ pos := position ( el , supp )
+ pp.i := pos::NNI
+ words := nil()$(L L NNI)
+ if wordProblem then
+ for i in 1..#sgs repeat
+ lw : L NNI := [ (#sgs - i + 1)::NNI ]
+ words := cons ( lw , words )
+ for i in #baseOfGroup..1 by -1 repeat
+ str := strip ( pp , gporb.i , sgs , words )
+ pp := str.elt
+ if wordProblem then outlist := append ( outlist , str.lst )
+ [ testIdentity pp , reverse outlist ]
+
+ --now the exported functions
+
+ coerce ( gp : % ) : L PERM S == gp.gens
+ generators ( gp : % ) : L PERM S == gp.gens
+
+ strongGenerators ( group ) ==
+ knownGroup? group
+ degree := # supp
+ strongGens := nil()$(L PERM S)
+ for i in sgs repeat
+ pairs := nil()$(L L S)
+ for j in 1..degree repeat
+ pairs := cons ( [ supp.j , supp.(i.j) ] , pairs )
+ strongGens := cons ( coerceListOfPairs pairs , strongGens )
+ reverse strongGens
+
+ elt ( gp , i ) == (gp.gens).i
+
+ movedPoints ( gp ) == brace pointList gp
+
+ random ( group , maximalNumberOfFactors ) ==
+ maximalNumberOfFactors < 1 => 1$(PERM S)
+ gp : L PERM S := group.gens
+ numberOfGenerators := # gp
+ randomInteger : I := 1 + (random()$Integer rem numberOfGenerators)
+ randomElement := gp.randomInteger
+ numberOfLoops : I := 1 + (random()$Integer rem maximalNumberOfFactors)
+ while numberOfLoops > 0 repeat
+ randomInteger : I := 1 + (random()$Integer rem numberOfGenerators)
+ randomElement := gp.randomInteger * randomElement
+ numberOfLoops := numberOfLoops - 1
+ randomElement
+
+ random ( group ) == random ( group , 20 )
+
+ order ( group ) ==
+ knownGroup? group
+ ord
+
+ degree ( group ) == # pointList group
+
+ base ( group ) ==
+ knownGroup? group
+ groupBase := nil()$(L S)
+ for i in baseOfGroup repeat
+ groupBase := cons ( supp.i , groupBase )
+ reverse groupBase
+
+ wordsForStrongGenerators ( group ) ==
+ knownGroup? group
+ wordlist
+
+ coerce ( gp : L PERM S ) : % ==
+ result : REC2 := [ 0 , [] , [] , [] , [] , [] ]
+ group := [ gp , result ]
+
+ permutationGroup ( gp : L PERM S ) : % ==
+ result : REC2 := [ 0 , [] , [] , [] , [] , [] ]
+ group := [ gp , result ]
+
+ coerce(group: %) : OUT ==
+ outList := nil()$(L OUT)
+ gp : L PERM S := group.gens
+ for i in (maxIndex gp)..1 by -1 repeat
+ outList := cons(coerce gp.i, outList)
+ postfix(outputForm(">":SYM),postfix(commaSeparate outList,outputForm("<":SYM)))
+
+ orbit ( gp : % , el : S ) : FSET S ==
+ elList : L S := [ el ]
+ outList := orbitInternal ( gp , elList )
+ outSet := brace()$(FSET S)
+ for i in 1..#outList repeat
+ insert_! ( outList.i.1 , outSet )
+ outSet
+
+ orbits ( gp ) ==
+ spp := movedPoints gp
+ orbits := nil()$(L FSET S)
+ while cardinality spp > 0 repeat
+ el := extract_! spp
+ orbitSet := orbit ( gp , el )
+ orbits := cons ( orbitSet , orbits )
+ spp := difference ( spp , orbitSet )
+ brace orbits
+
+ member? (p, gp) ==
+ wordProblem := false
+ mi := memberInternal ( p , gp , true )
+ mi.bool
+
+ wordInStrongGenerators (p, gp ) ==
+ mi := memberInternal ( inv p , gp , false )
+ not mi.bool => error "p is not an element of gp"
+ mi.lst
+
+ wordInGenerators (p, gp) ==
+ lll : L NNI := wordInStrongGenerators (p, gp)
+ outlist := nil()$(L NNI)
+ for wd in lll repeat
+ outlist := append ( outlist , wordlist.wd )
+ shortenWord ( outlist , gp )
+
+ gp1 < gp2 ==
+ not empty? difference ( movedPoints gp1 , movedPoints gp2 ) => false
+ not subgroup ( gp1 , gp2 ) => false
+ order gp1 = order gp2 => false
+ true
+
+ gp1 <= gp2 ==
+ not empty? difference ( movedPoints gp1 , movedPoints gp2 ) => false
+ subgroup ( gp1 , gp2 )
+
+ gp1 = gp2 ==
+ movedPoints gp1 ^= movedPoints gp2 => false
+ if #(gp1.gens) <= #(gp2.gens) then
+ not subgroup ( gp1 , gp2 ) => return false
+ else
+ not subgroup ( gp2 , gp1 ) => return false
+ order gp1 = order gp2 => true
+ false
+
+ orbit ( gp : % , startSet : FSET S ) : FSET FSET S ==
+ startList : L S := parts startSet
+ outList := orbitInternal ( gp , startList )
+ outSet := brace()$(FSET FSET S)
+ for i in 1..#outList repeat
+ newSet : FSET S := brace outList.i
+ insert_! ( newSet , outSet )
+ outSet
+
+ orbit ( gp : % , startList : L S ) : FSET L S ==
+ brace orbitInternal(gp, startList)
+
+ initializeGroupForWordProblem ( gp , maxLoops , diff ) ==
+ wordProblem := true
+ ord := bsgs ( gp , maxLoops , diff )
+ gp.information := [ ord , sgs , baseOfGroup , gporb , supp , wordlist ]
+ void
+
+ initializeGroupForWordProblem ( gp ) == initializeGroupForWordProblem ( gp , 0 , 1 )
+
+@
+\section{package PGE PermutationGroupExamples}
+<<package PGE PermutationGroupExamples>>=
+)abbrev package PGE PermutationGroupExamples
+++ Authors: M. Weller, G. Schneider, J. Grabmeier
+++ Date Created: 20 February 1990
+++ Date Last Updated: 09 June 1990
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ J. Conway, R. Curtis, S. Norton, R. Parker, R. Wilson:
+++ Atlas of Finite Groups, Oxford, Clarendon Press, 1987
+++ Description:
+++ PermutationGroupExamples provides permutation groups for
+++ some classes of groups: symmetric, alternating, dihedral, cyclic,
+++ direct products of cyclic, which are in fact the finite abelian groups
+++ of symmetric groups called Young subgroups.
+++ Furthermore, Rubik's group as permutation group of 48 integers and a list
+++ of sporadic simple groups derived from the atlas of finite groups.
+
+PermutationGroupExamples():public == private where
+
+ L ==> List
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ PERM ==> Permutation
+ PERMGRP ==> PermutationGroup
+
+ public ==> with
+
+ symmetricGroup: PI -> PERMGRP I
+ ++ symmetricGroup(n) constructs the symmetric group {\em Sn}
+ ++ acting on the integers 1,...,n, generators are the
+ ++ {\em n}-cycle {\em (1,...,n)} and the 2-cycle {\em (1,2)}.
+ symmetricGroup: L I -> PERMGRP I
+ ++ symmetricGroup(li) constructs the symmetric group acting on
+ ++ the integers in the list {\em li}, generators are the
+ ++ cycle given by {\em li} and the 2-cycle {\em (li.1,li.2)}.
+ ++ Note: duplicates in the list will be removed.
+ alternatingGroup: PI -> PERMGRP I
+ ++ alternatingGroup(n) constructs the alternating group {\em An}
+ ++ acting on the integers 1,...,n, generators are in general the
+ ++ {\em n-2}-cycle {\em (3,...,n)} and the 3-cycle {\em (1,2,3)}
+ ++ if n is odd and the product of the 2-cycle {\em (1,2)} with
+ ++ {\em n-2}-cycle {\em (3,...,n)} and the 3-cycle {\em (1,2,3)}
+ ++ if n is even.
+ alternatingGroup: L I -> PERMGRP I
+ ++ alternatingGroup(li) constructs the alternating group acting
+ ++ on the integers in the list {\em li}, generators are in general the
+ ++ {\em n-2}-cycle {\em (li.3,...,li.n)} and the 3-cycle
+ ++ {\em (li.1,li.2,li.3)}, if n is odd and
+ ++ product of the 2-cycle {\em (li.1,li.2)} with
+ ++ {\em n-2}-cycle {\em (li.3,...,li.n)} and the 3-cycle
+ ++ {\em (li.1,li.2,li.3)}, if n is even.
+ ++ Note: duplicates in the list will be removed.
+ abelianGroup: L PI -> PERMGRP I
+ ++ abelianGroup([n1,...,nk]) constructs the abelian group that
+ ++ is the direct product of cyclic groups with order {\em ni}.
+ cyclicGroup: PI -> PERMGRP I
+ ++ cyclicGroup(n) constructs the cyclic group of order n acting
+ ++ on the integers 1,...,n.
+ cyclicGroup: L I -> PERMGRP I
+ ++ cyclicGroup([i1,...,ik]) constructs the cyclic group of
+ ++ order k acting on the integers {\em i1},...,{\em ik}.
+ ++ Note: duplicates in the list will be removed.
+ dihedralGroup: PI -> PERMGRP I
+ ++ dihedralGroup(n) constructs the dihedral group of order 2n
+ ++ acting on integers 1,...,N.
+ dihedralGroup: L I -> PERMGRP I
+ ++ dihedralGroup([i1,...,ik]) constructs the dihedral group of
+ ++ order 2k acting on the integers out of {\em i1},...,{\em ik}.
+ ++ Note: duplicates in the list will be removed.
+ mathieu11: L I -> PERMGRP I
+ ++ mathieu11(li) constructs the mathieu group acting on the 11
+ ++ integers given in the list {\em li}.
+ ++ Note: duplicates in the list will be removed.
+ ++ error, if {\em li} has less or more than 11 different entries.
+ mathieu11: () -> PERMGRP I
+ ++ mathieu11 constructs the mathieu group acting on the
+ ++ integers 1,...,11.
+ mathieu12: L I -> PERMGRP I
+ ++ mathieu12(li) constructs the mathieu group acting on the 12
+ ++ integers given in the list {\em li}.
+ ++ Note: duplicates in the list will be removed
+ ++ Error: if {\em li} has less or more than 12 different entries.
+ mathieu12: () -> PERMGRP I
+ ++ mathieu12 constructs the mathieu group acting on the
+ ++ integers 1,...,12.
+ mathieu22: L I -> PERMGRP I
+ ++ mathieu22(li) constructs the mathieu group acting on the 22
+ ++ integers given in the list {\em li}.
+ ++ Note: duplicates in the list will be removed.
+ ++ Error: if {\em li} has less or more than 22 different entries.
+ mathieu22: () -> PERMGRP I
+ ++ mathieu22 constructs the mathieu group acting on the
+ ++ integers 1,...,22.
+ mathieu23: L I -> PERMGRP I
+ ++ mathieu23(li) constructs the mathieu group acting on the 23
+ ++ integers given in the list {\em li}.
+ ++ Note: duplicates in the list will be removed.
+ ++ Error: if {\em li} has less or more than 23 different entries.
+ mathieu23: () -> PERMGRP I
+ ++ mathieu23 constructs the mathieu group acting on the
+ ++ integers 1,...,23.
+ mathieu24: L I -> PERMGRP I
+ ++ mathieu24(li) constructs the mathieu group acting on the 24
+ ++ integers given in the list {\em li}.
+ ++ Note: duplicates in the list will be removed.
+ ++ Error: if {\em li} has less or more than 24 different entries.
+ mathieu24: () -> PERMGRP I
+ ++ mathieu24 constructs the mathieu group acting on the
+ ++ integers 1,...,24.
+ janko2: L I -> PERMGRP I
+ ++ janko2(li) constructs the janko group acting on the 100
+ ++ integers given in the list {\em li}.
+ ++ Note: duplicates in the list will be removed.
+ ++ Error: if {\em li} has less or more than 100 different entries
+ janko2: () -> PERMGRP I
+ ++ janko2 constructs the janko group acting on the
+ ++ integers 1,...,100.
+ rubiksGroup: () -> PERMGRP I
+ ++ rubiksGroup constructs the permutation group representing
+ ++ Rubic's Cube acting on integers {\em 10*i+j} for
+ ++ {\em 1 <= i <= 6}, {\em 1 <= j <= 8}.
+ ++ The faces of Rubik's Cube are labelled in the obvious way
+ ++ Front, Right, Up, Down, Left, Back and numbered from 1 to 6
+ ++ in this given ordering, the pieces on each face
+ ++ (except the unmoveable center piece) are clockwise numbered
+ ++ from 1 to 8 starting with the piece in the upper left
+ ++ corner. The moves of the cube are represented as permutations
+ ++ on these pieces, represented as a two digit
+ ++ integer {\em ij} where i is the numer of theface (1 to 6)
+ ++ and j is the number of the piece on this face.
+ ++ The remaining ambiguities are resolved by looking
+ ++ at the 6 generators, which represent a 90 degree turns of the
+ ++ faces, or from the following pictorial description.
+ ++ Permutation group representing Rubic's Cube acting on integers
+ ++ 10*i+j for 1 <= i <= 6, 1 <= j <=8.
+ ++
+ ++ \begin{verbatim}
+ ++ Rubik's Cube: +-----+ +-- B where: marks Side # :
+ ++ / U /|/
+ ++ / / | F(ront) <-> 1
+ ++ L --> +-----+ R| R(ight) <-> 2
+ ++ | | + U(p) <-> 3
+ ++ | F | / D(own) <-> 4
+ ++ | |/ L(eft) <-> 5
+ ++ +-----+ B(ack) <-> 6
+ ++ ^
+ ++ |
+ ++ D
+ ++
+ ++ The Cube's surface:
+ ++ The pieces on each side
+ ++ +---+ (except the unmoveable center
+ ++ |567| piece) are clockwise numbered
+ ++ |4U8| from 1 to 8 starting with the
+ ++ |321| piece in the upper left
+ ++ +---+---+---+ corner (see figure on the
+ ++ |781|123|345| left). The moves of the cube
+ ++ |6L2|8F4|2R6| are represented as
+ ++ |543|765|187| permutations on these pieces.
+ ++ +---+---+---+ Each of the pieces is
+ ++ |123| represented as a two digit
+ ++ |8D4| integer ij where i is the
+ ++ |765| # of the side ( 1 to 6 for
+ ++ +---+ F to B (see table above ))
+ ++ |567| and j is the # of the piece.
+ ++ |4B8|
+ ++ |321|
+ ++ +---+
+ ++ \end{verbatim}
+ youngGroup: L I -> PERMGRP I
+ ++ youngGroup([n1,...,nk]) constructs the direct product of the
+ ++ symmetric groups {\em Sn1},...,{\em Snk}.
+ youngGroup: Partition -> PERMGRP I
+ ++ youngGroup(lambda) constructs the direct product of the symmetric
+ ++ groups given by the parts of the partition {\em lambda}.
+
+ private ==> add
+
+ -- import the permutation and permutation group domains:
+
+ import PERM I
+ import PERMGRP I
+
+ -- import the needed map function:
+
+ import ListFunctions2(L L I,PERM I)
+ -- the internal functions:
+
+ llli2gp(l:L L L I):PERMGRP I ==
+ --++ Converts an list of permutations each represented by a list
+ --++ of cycles ( each of them represented as a list of Integers )
+ --++ to the permutation group generated by these permutations.
+ (map(cycles,l))::PERMGRP I
+
+ li1n(n:I):L I ==
+ --++ constructs the list of integers from 1 to n
+ [i for i in 1..n]
+
+ -- definition of the exported functions:
+ youngGroup(l:L I):PERMGRP I ==
+ gens:= nil()$(L L L I)
+ element:I:= 1
+ for n in l | n > 1 repeat
+ gens:=cons(list [i for i in element..(element+n-1)], gens)
+ if n >= 3 then gens := cons([[element,element+1]],gens)
+ element:=element+n
+ llli2gp
+ #gens = 0 => [[[1]]]
+ gens
+
+ youngGroup(lambda : Partition):PERMGRP I ==
+ youngGroup(convert(lambda)$Partition)
+
+ rubiksGroup():PERMGRP I ==
+ -- each generator represents a 90 degree turn of the appropriate
+ -- side.
+ f:L L I:=
+ [[11,13,15,17],[12,14,16,18],[51,31,21,41],[53,33,23,43],[52,32,22,42]]
+ r:L L I:=
+ [[21,23,25,27],[22,24,26,28],[13,37,67,43],[15,31,61,45],[14,38,68,44]]
+ u:L L I:=
+ [[31,33,35,37],[32,34,36,38],[13,51,63,25],[11,57,61,23],[12,58,62,24]]
+ d:L L I:=
+ [[41,43,45,47],[42,44,46,48],[17,21,67,55],[15,27,65,53],[16,28,66,54]]
+ l:L L I:=
+ [[51,53,55,57],[52,54,56,58],[11,41,65,35],[17,47,63,33],[18,48,64,34]]
+ b:L L I:=
+ [[61,63,65,67],[62,64,66,68],[45,25,35,55],[47,27,37,57],[46,26,36,56]]
+ llli2gp [f,r,u,d,l,b]
+
+ mathieu11(l:L I):PERMGRP I ==
+ -- permutations derived from the ATLAS
+ l:=removeDuplicates l
+ #l ^= 11 => error "Exactly 11 integers for mathieu11 needed !"
+ a:L L I:=[[l.1,l.10],[l.2,l.8],[l.3,l.11],[l.5,l.7]]
+ llli2gp [a,[[l.1,l.4,l.7,l.6],[l.2,l.11,l.10,l.9]]]
+
+ mathieu11():PERMGRP I == mathieu11 li1n 11
+
+ mathieu12(l:L I):PERMGRP I ==
+ -- permutations derived from the ATLAS
+ l:=removeDuplicates l
+ #l ^= 12 => error "Exactly 12 integers for mathieu12 needed !"
+ a:L L I:=
+ [[l.1,l.2,l.3,l.4,l.5,l.6,l.7,l.8,l.9,l.10,l.11]]
+ llli2gp [a,[[l.1,l.6,l.5,l.8,l.3,l.7,l.4,l.2,l.9,l.10],[l.11,l.12]]]
+
+ mathieu12():PERMGRP I == mathieu12 li1n 12
+
+ mathieu22(l:L I):PERMGRP I ==
+ -- permutations derived from the ATLAS
+ l:=removeDuplicates l
+ #l ^= 22 => error "Exactly 22 integers for mathieu22 needed !"
+ a:L L I:=[[l.1,l.2,l.4,l.8,l.16,l.9,l.18,l.13,l.3,l.6,l.12], _
+ [l.5,l.10,l.20,l.17,l.11,l.22,l.21,l.19,l.15,l.7,l.14]]
+ b:L L I:= [[l.1,l.2,l.6,l.18],[l.3,l.15],[l.5,l.8,l.21,l.13], _
+ [l.7,l.9,l.20,l.12],[l.10,l.16],[l.11,l.19,l.14,l.22]]
+ llli2gp [a,b]
+
+ mathieu22():PERMGRP I == mathieu22 li1n 22
+
+ mathieu23(l:L I):PERMGRP I ==
+ -- permutations derived from the ATLAS
+ l:=removeDuplicates l
+ #l ^= 23 => error "Exactly 23 integers for mathieu23 needed !"
+ a:L L I:= [[l.1,l.2,l.3,l.4,l.5,l.6,l.7,l.8,l.9,l.10,l.11,l.12,l.13,l.14,_
+ l.15,l.16,l.17,l.18,l.19,l.20,l.21,l.22,l.23]]
+ b:L L I:= [[l.2,l.16,l.9,l.6,l.8],[l.3,l.12,l.13,l.18,l.4], _
+ [l.7,l.17,l.10,l.11,l.22],[l.14,l.19,l.21,l.20,l.15]]
+ llli2gp [a,b]
+
+ mathieu23():PERMGRP I == mathieu23 li1n 23
+
+ mathieu24(l:L I):PERMGRP I ==
+ -- permutations derived from the ATLAS
+ l:=removeDuplicates l
+ #l ^= 24 => error "Exactly 24 integers for mathieu24 needed !"
+ a:L L I:= [[l.1,l.16,l.10,l.22,l.24],[l.2,l.12,l.18,l.21,l.7], _
+ [l.4,l.5,l.8,l.6,l.17],[l.9,l.11,l.13,l.19,l.15]]
+ b:L L I:= [[l.1,l.22,l.13,l.14,l.6,l.20,l.3,l.21,l.8,l.11],[l.2,l.10], _
+ [l.4,l.15,l.18,l.17,l.16,l.5,l.9,l.19,l.12,l.7],[l.23,l.24]]
+ llli2gp [a,b]
+
+ mathieu24():PERMGRP I == mathieu24 li1n 24
+
+ janko2(l:L I):PERMGRP I ==
+ -- permutations derived from the ATLAS
+ l:=removeDuplicates l
+ #l ^= 100 => error "Exactly 100 integers for janko2 needed !"
+ a:L L I:=[ _
+ [l.2,l.3,l.4,l.5,l.6,l.7,l.8], _
+ [l.9,l.10,l.11,l.12,l.13,l.14,l.15], _
+ [l.16,l.17,l.18,l.19,l.20,l.21,l.22], _
+ [l.23,l.24,l.25,l.26,l.27,l.28,l.29], _
+ [l.30,l.31,l.32,l.33,l.34,l.35,l.36], _
+ [l.37,l.38,l.39,l.40,l.41,l.42,l.43], _
+ [l.44,l.45,l.46,l.47,l.48,l.49,l.50], _
+ [l.51,l.52,l.53,l.54,l.55,l.56,l.57], _
+ [l.58,l.59,l.60,l.61,l.62,l.63,l.64], _
+ [l.65,l.66,l.67,l.68,l.69,l.70,l.71], _
+ [l.72,l.73,l.74,l.75,l.76,l.77,l.78], _
+ [l.79,l.80,l.81,l.82,l.83,l.84,l.85], _
+ [l.86,l.87,l.88,l.89,l.90,l.91,l.92], _
+ [l.93,l.94,l.95,l.96,l.97,l.98,l.99] ]
+ b:L L I:=[
+ [l.1,l.74,l.83,l.21,l.36,l.77,l.44,l.80,l.64,l.2,l.34,l.75,l.48,l.17,l.100],_
+ [l.3,l.15,l.31,l.52,l.19,l.11,l.73,l.79,l.26,l.56,l.41,l.99,l.39,l.84,l.90],_
+ [l.4,l.57,l.86,l.63,l.85,l.95,l.82,l.97,l.98,l.81,l.8,l.69,l.38,l.43,l.58],_
+ [l.5,l.66,l.49,l.59,l.61],_
+ [l.6,l.68,l.89,l.94,l.92,l.20,l.13,l.54,l.24,l.51,l.87,l.27,l.76,l.23,l.67],_
+ [l.7,l.72,l.22,l.35,l.30,l.70,l.47,l.62,l.45,l.46,l.40,l.28,l.65,l.93,l.42],_
+ [l.9,l.71,l.37,l.91,l.18,l.55,l.96,l.60,l.16,l.53,l.50,l.25,l.32,l.14,l.33],_
+ [l.10,l.78,l.88,l.29,l.12] ]
+ llli2gp [a,b]
+
+ janko2():PERMGRP I == janko2 li1n 100
+
+ abelianGroup(l:L PI):PERMGRP I ==
+ gens:= nil()$(L L L I)
+ element:I:= 1
+ for n in l | n > 1 repeat
+ gens:=cons( list [i for i in element..(element+n-1) ], gens )
+ element:=element+n
+ llli2gp
+ #gens = 0 => [[[1]]]
+ gens
+
+ alternatingGroup(l:L I):PERMGRP I ==
+ l:=removeDuplicates l
+ #l = 0 =>
+ error "Cannot construct alternating group on empty set"
+ #l < 3 => llli2gp [[[l.1]]]
+ #l = 3 => llli2gp [[[l.1,l.2,l.3]]]
+ tmp:= [l.i for i in 3..(#l)]
+ gens:L L L I:=[[tmp],[[l.1,l.2,l.3]]]
+ odd?(#l) => llli2gp gens
+ gens.1 := cons([l.1,l.2],gens.1)
+ llli2gp gens
+
+ alternatingGroup(n:PI):PERMGRP I == alternatingGroup li1n n
+
+ symmetricGroup(l:L I):PERMGRP I ==
+ l:=removeDuplicates l
+ #l = 0 => error "Cannot construct symmetric group on empty set !"
+ #l < 3 => llli2gp [[l]]
+ llli2gp [[l],[[l.1,l.2]]]
+
+ symmetricGroup(n:PI):PERMGRP I == symmetricGroup li1n n
+
+ cyclicGroup(l:L I):PERMGRP I ==
+ l:=removeDuplicates l
+ #l = 0 => error "Cannot construct cyclic group on empty set"
+ llli2gp [[l]]
+
+ cyclicGroup(n:PI):PERMGRP I == cyclicGroup li1n n
+
+ dihedralGroup(l:L I):PERMGRP I ==
+ l:=removeDuplicates l
+ #l < 3 => error "in dihedralGroup: Minimum of 3 elements needed !"
+ tmp := [[l.i, l.(#l-i+1) ] for i in 1..(#l quo 2)]
+ llli2gp [ [ l ], tmp ]
+
+ dihedralGroup(n:PI):PERMGRP I ==
+ n = 1 => symmetricGroup (2::PI)
+ n = 2 => llli2gp [[[1,2]],[[3,4]]]
+ dihedralGroup li1n n
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PERMGRP PermutationGroup>>
+<<package PGE PermutationGroupExamples>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pf.spad.pamphlet b/src/algebra/pf.spad.pamphlet
new file mode 100644
index 00000000..338b56c2
--- /dev/null
+++ b/src/algebra/pf.spad.pamphlet
@@ -0,0 +1,266 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pf.spad}
+\author{N.N., Johannes Grabmeier, Alfred Scheerhorn}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain IPF InnerPrimeField}
+<<domain IPF InnerPrimeField>>=
+)abbrev domain IPF InnerPrimeField
+-- Argument MUST be a prime.
+-- This domain does not check, PrimeField does.
+++ Authors: N.N., J.Grabmeier, A.Scheerhorn
+++ Date Created: ?, November 1990, 26.03.1991
+++ Date Last Updated: 12 April 1991
+++ Basic Operations:
+++ Related Constructors: PrimeField
+++ Also See:
+++ AMS Classifications:
+++ Keywords: prime characteristic, prime field, finite field
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ AXIOM Technical Report Series, to appear.
+++ Description:
+++ InnerPrimeField(p) implements the field with p elements.
+++ Note: argument p MUST be a prime (this domain does not check).
+++ See \spadtype{PrimeField} for a domain that does check.
+
+
+InnerPrimeField(p:PositiveInteger): Exports == Implementation where
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ TBL ==> Table(PI,NNI)
+ R ==> Record(key:PI,entry:NNI)
+ SUP ==> SparseUnivariatePolynomial
+ OUT ==> OutputForm
+
+ Exports ==> Join(FiniteFieldCategory,FiniteAlgebraicExtensionField($),_
+ ConvertibleTo(Integer))
+
+ Implementation ==> IntegerMod p add
+
+ initializeElt:() -> Void
+ initializeLog:() -> Void
+
+-- global variables ====================================================
+
+ primitiveElt:PI:=1
+ -- for the lookup the primitive Element computed by createPrimitiveElement()
+
+ sizeCG :=(p-1) pretend NonNegativeInteger
+ -- the size of the cyclic group
+
+ facOfGroupSize := nil()$(List Record(factor:Integer,exponent:Integer))
+ -- the factorization of the cyclic group size
+
+ initlog?:Boolean:=true
+ -- gets false after initialization of the logarithm table
+
+ initelt?:Boolean:=true
+ -- gets false after initialization of the primitive Element
+
+
+ discLogTable:Table(PI,TBL):=table()$Table(PI,TBL)
+ -- tables indexed by the factors of the size q of the cyclic group
+ -- discLogTable.factor is a table of with keys
+ -- primitiveElement() ** (i * (q quo factor)) and entries i for
+ -- i in 0..n-1, n computed in initialize() in order to use
+ -- the minimal size limit 'limit' optimal.
+
+-- functions ===========================================================
+
+ generator() == 1
+
+ -- This uses x**(p-1)=1 (mod p), so x**(q(p-1)+r) = x**r (mod p)
+ x:$ ** n:Integer ==
+ zero?(n) => 1
+ zero?(x) => 0
+ r := positiveRemainder(n,p-1)::NNI
+ ((x pretend IntegerMod p) **$IntegerMod(p) r) pretend $
+
+ if p <= convert(max()$SingleInteger)@Integer then
+ q := p::SingleInteger
+
+ recip x ==
+ zero?(y := convert(x)@Integer :: SingleInteger) => "failed"
+ invmod(y, q)::Integer::$
+ else
+ recip x ==
+ zero?(y := convert(x)@Integer) => "failed"
+ invmod(y, p)::$
+
+ convert(x:$) == x pretend I
+
+ normalElement() == 1
+
+ createNormalElement() == 1
+
+ characteristic() == p
+
+ factorsOfCyclicGroupSize() ==
+ p=2 => facOfGroupSize -- this fixes an infinite loop of functions
+ -- calls, problem was that factors factor(1)
+ -- is the empty list
+ if empty? facOfGroupSize then initializeElt()
+ facOfGroupSize
+
+ representationType() == "prime"
+
+ tableForDiscreteLogarithm(fac) ==
+ if initlog? then initializeLog()
+ tbl:=search(fac::PI,discLogTable)$Table(PI,TBL)
+ tbl case "failed" =>
+ error "tableForDiscreteLogarithm: argument must be prime divisor_
+ of the order of the multiplicative group"
+ tbl pretend TBL
+
+ primitiveElement() ==
+ if initelt? then initializeElt()
+ index(primitiveElt)
+
+ initializeElt() ==
+ facOfGroupSize:=factors(factor(sizeCG)$I)$(Factored I)
+ -- get a primitive element
+ primitiveElt:=lookup(createPrimitiveElement())
+ -- set initialization flag
+ initelt? := false
+ void$Void
+
+ initializeLog() ==
+ if initelt? then initializeElt()
+ -- set up tables for discrete logarithm
+ limit:Integer:=30
+ -- the minimum size for the discrete logarithm table
+ for f in facOfGroupSize repeat
+ fac:=f.factor
+ base:$:=primitiveElement() ** (sizeCG quo fac)
+ l:Integer:=length(fac)$Integer
+ n:Integer:=0
+ if odd?(l)$Integer then n:=shift(fac,-(l quo 2))
+ else n:=shift(1,(l quo 2))
+ if n < limit then
+ d:=(fac-1) quo limit + 1
+ n:=(fac-1) quo d + 1
+ tbl:TBL:=table()$TBL
+ a:$:=1
+ for i in (0::NNI)..(n-1)::NNI repeat
+ insert_!([lookup(a),i::NNI]$R,tbl)$TBL
+ a:=a*base
+ insert_!([fac::PI,copy(tbl)$TBL]_
+ $Record(key:PI,entry:TBL),discLogTable)$Table(PI,TBL)
+ -- tell user about initialization
+ -- print("discrete logarithm table initialized"::OUT)
+ -- set initialization flag
+ initlog? := false
+ void$Void
+
+ degree(x):PI == 1::PositiveInteger
+ extensionDegree():PI == 1::PositiveInteger
+
+-- sizeOfGroundField() == p::NonNegativeInteger
+
+ inGroundField?(x) == true
+
+ coordinates(x) == new(1,x)$(Vector $)
+
+ represents(v) == v.1
+
+ retract(x) == x
+
+ retractIfCan(x) == x
+
+ basis() == new(1,1::$)$(Vector $)
+ basis(n:PI) ==
+ n = 1 => basis()
+ error("basis: argument must divide extension degree")
+
+ definingPolynomial() ==
+ monomial(1,1)$(SUP $) - monomial(1,0)$(SUP $)
+
+
+ minimalPolynomial(x) ==
+ monomial(1,1)$(SUP $) - monomial(x,0)$(SUP $)
+
+ charthRoot x == x
+
+@
+\section{domain PF PrimeField}
+<<domain PF PrimeField>>=
+)abbrev domain PF PrimeField
+++ Authors: N.N.,
+++ Date Created: November 1990, 26.03.1991
+++ Date Last Updated: 31 March 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: prime characteristic, prime field, finite field
+++ References:
+++ R.Lidl, H.Niederreiter: Finite Field, Encycoldia of Mathematics and
+++ Its Applications, Vol. 20, Cambridge Univ. Press, 1983, ISBN 0 521 30240 4
+++ Description:
+++ PrimeField(p) implements the field with p elements if p is a
+++ prime number.
+++ Error: if p is not prime.
+++ Note: this domain does not check that argument is a prime.
+--++ with new compiler, want to put the error check before the add
+PrimeField(p:PositiveInteger): Exp == Impl where
+ Exp ==> Join(FiniteFieldCategory,FiniteAlgebraicExtensionField($),_
+ ConvertibleTo(Integer))
+ Impl ==> InnerPrimeField(p) add
+ if not prime?(p)$IntegerPrimesPackage(Integer) then
+ error "Argument to prime field must be a prime"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain IPF InnerPrimeField>>
+<<domain PF PrimeField>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pfbr.spad.pamphlet b/src/algebra/pfbr.spad.pamphlet
new file mode 100644
index 00000000..fd3b9900
--- /dev/null
+++ b/src/algebra/pfbr.spad.pamphlet
@@ -0,0 +1,591 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pfbr.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PFBRU PolynomialFactorizationByRecursionUnivariate}
+<<package PFBRU PolynomialFactorizationByRecursionUnivariate>>=
+)abbrev package PFBRU PolynomialFactorizationByRecursionUnivariate
+++ PolynomialFactorizationByRecursionUnivariate
+++ R is a \spadfun{PolynomialFactorizationExplicit} domain,
+++ S is univariate polynomials over R
+++ We are interested in handling SparseUnivariatePolynomials over
+++ S, is a variable we shall call z
+PolynomialFactorizationByRecursionUnivariate(R, S): public == private where
+ R:PolynomialFactorizationExplicit
+ S:UnivariatePolynomialCategory(R)
+ PI ==> PositiveInteger
+ SupR ==> SparseUnivariatePolynomial R
+ SupSupR ==> SparseUnivariatePolynomial SupR
+ SupS ==> SparseUnivariatePolynomial S
+ SupSupS ==> SparseUnivariatePolynomial SupS
+ LPEBFS ==> LinearPolynomialEquationByFractions(S)
+ public == with
+ solveLinearPolynomialEquationByRecursion: (List SupS, SupS) ->
+ Union(List SupS,"failed")
+ ++ \spad{solveLinearPolynomialEquationByRecursion([p1,...,pn],p)}
+ ++ returns the list of polynomials \spad{[q1,...,qn]}
+ ++ such that \spad{sum qi/pi = p / prod pi}, a
+ ++ recursion step for solveLinearPolynomialEquation
+ ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+ ++ (see \spadfun{solveLinearPolynomialEquation}).
+ ++ If no such list of qi exists, then "failed" is returned.
+ factorByRecursion: SupS -> Factored SupS
+ ++ factorByRecursion(p) factors polynomial p. This function
+ ++ performs the recursion step for factorPolynomial,
+ ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+ ++ (see \spadfun{factorPolynomial})
+ factorSquareFreeByRecursion: SupS -> Factored SupS
+ ++ factorSquareFreeByRecursion(p) returns the square free
+ ++ factorization of p. This functions performs
+ ++ the recursion step for factorSquareFreePolynomial,
+ ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+ ++ (see \spadfun{factorSquareFreePolynomial}).
+ randomR: -> R -- has to be global, since has alternative definitions
+ ++ randomR() produces a random element of R
+ factorSFBRlcUnit: (SupS) -> Factored SupS
+ ++ factorSFBRlcUnit(p) returns the square free factorization of
+ ++ polynomial p
+ ++ (see \spadfun{factorSquareFreeByRecursion}{PolynomialFactorizationByRecursionUnivariate})
+ ++ in the case where the leading coefficient of p
+ ++ is a unit.
+ private == add
+ supR: SparseUnivariatePolynomial R
+ pp: SupS
+ lpolys,factors: List SupS
+ r:R
+ lr:List R
+ import FactoredFunctionUtilities(SupS)
+ import FactoredFunctions2(SupR,SupS)
+ import FactoredFunctions2(S,SupS)
+ import UnivariatePolynomialCategoryFunctions2(S,SupS,R,SupR)
+ import UnivariatePolynomialCategoryFunctions2(R,SupR,S,SupS)
+ -- local function declarations
+ raise: SupR -> SupS
+ lower: SupS -> SupR
+ factorSFBRlcUnitInner: (SupS,R) -> Union(Factored SupS,"failed")
+ hensel: (SupS,R,List SupS) ->
+ Union(Record(fctrs:List SupS),"failed")
+ chooseFSQViableSubstitutions: (SupS) ->
+ Record(substnsField:R,ppRField:SupR)
+ --++ chooseFSQViableSubstitutions(p), p is a sup
+ --++ ("sparse univariate polynomial")
+ --++ over a sup over R, returns a record
+ --++ \spad{[substnsField: r, ppRField: q]} where r is a substitution point
+ --++ q is a sup over R so that the (implicit) variable in q
+ --++ does not drop in degree and remains square-free.
+ -- here for the moment, until it compiles
+ -- N.B., we know that R is NOT a FiniteField, since
+ -- that is meant to have a special implementation, to break the
+ -- recursion
+ solveLinearPolynomialEquationByRecursion(lpolys,pp) ==
+ lhsdeg:="max"/["max"/[degree v for v in coefficients u] for u in lpolys]
+ rhsdeg:="max"/[degree v for v in coefficients pp]
+ lhsdeg = 0 =>
+ lpolysLower:=[lower u for u in lpolys]
+ answer:List SupS := [0 for u in lpolys]
+ for i in 0..rhsdeg repeat
+ ppx:=map(coefficient(#1,i),pp)
+ zero? ppx => "next"
+ recAns:= solveLinearPolynomialEquation(lpolysLower,ppx)
+ recAns case "failed" => return "failed"
+ answer:=[monomial(1,i)$S * raise c + d
+ for c in recAns for d in answer]
+ answer
+ solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
+ -- local function definitions
+ hensel(pp,r,factors) ==
+ -- factors is a relatively prime factorization of pp modulo the ideal
+ -- (x-r), with suitably imposed leading coefficients.
+ -- This is lifted, without re-combinations, to a factorization
+ -- return "failed" if this can't be done
+ origFactors:=factors
+ totdegree:Integer:=0
+ proddegree:Integer:=
+ "max"/[degree(u) for u in coefficients pp]
+ n:PI:=1
+ pn:=prime:=monomial(1,1) - r::S
+ foundFactors:List SupS:=empty()
+ while (totdegree <= proddegree) repeat
+ Ecart:=(pp-*/factors) exquo pn
+ Ecart case "failed" =>
+ error "failed lifting in hensel in PFBRU"
+ zero? Ecart =>
+ -- then we have all the factors
+ return [append(foundFactors, factors)]
+ step:=solveLinearPolynomialEquation(origFactors,
+ map(elt(#1,r::S),
+ Ecart))
+ step case "failed" => return "failed" -- must be a false split
+ factors:=[a+b*pn for a in factors for b in step]
+ for a in factors for c in origFactors repeat
+ pp1:= pp exquo a
+ pp1 case "failed" => "next"
+ pp:=pp1
+ proddegree := proddegree - "max"/[degree(u)
+ for u in coefficients a]
+ factors:=remove(a,factors)
+ origFactors:=remove(c,origFactors)
+ foundFactors:=[a,:foundFactors]
+ #factors < 2 =>
+ return [(empty? factors => foundFactors;
+ [pp,:foundFactors])]
+ totdegree:= +/["max"/[degree(u)
+ for u in coefficients u1]
+ for u1 in factors]
+ n:=n+1
+ pn:=pn*prime
+ "failed" -- must have been a false split
+ chooseFSQViableSubstitutions(pp) ==
+ substns:R
+ ppR: SupR
+ while true repeat
+ substns:= randomR()
+ zero? elt(leadingCoefficient pp,substns ) => "next"
+ ppR:=map( elt(#1,substns),pp)
+ degree gcd(ppR,differentiate ppR)>0 => "next"
+ leave
+ [substns,ppR]
+ raise(supR) == map(#1:R::S,supR)
+ lower(pp) == map(retract(#1)::R,pp)
+ factorSFBRlcUnitInner(pp,r) ==
+ -- pp is square-free as a Sup, but the Up variable occurs.
+ -- Furthermore, its LC is a unit
+ -- returns "failed" if the substitution is bad, else a factorization
+ ppR:=map(elt(#1,r),pp)
+ degree ppR < degree pp => "failed"
+ degree gcd(ppR,differentiate ppR) >0 => "failed"
+ factors:=
+ fDown:=factorSquareFreePolynomial ppR
+ [raise (unit fDown * factorList(fDown).first.fctr),
+ :[raise u.fctr for u in factorList(fDown).rest]]
+ #factors = 1 => makeFR(1,[["irred",pp,1]])
+ hen:=hensel(pp,r,factors)
+ hen case "failed" => "failed"
+ makeFR(1,[["irred",u,1] for u in hen.fctrs])
+ -- exported function definitions
+ if R has StepThrough then
+ factorSFBRlcUnit(pp) ==
+ val:R := init()
+ while true repeat
+ tempAns:=factorSFBRlcUnitInner(pp,val)
+ not (tempAns case "failed") => return tempAns
+ val1:=nextItem val
+ val1 case "failed" =>
+ error "at this point, we know we have a finite field"
+ val:=val1
+ else
+ factorSFBRlcUnit(pp) ==
+ val:R := randomR()
+ while true repeat
+ tempAns:=factorSFBRlcUnitInner(pp,val)
+ not (tempAns case "failed") => return tempAns
+ val := randomR()
+ if R has StepThrough then
+ randomCount:R:= init()
+ randomR() ==
+ v:=nextItem(randomCount)
+ v case "failed" =>
+ SAY$Lisp "Taking another set of random values"
+ randomCount:=init()
+ randomCount
+ randomCount:=v
+ randomCount
+ else if R has random: -> R then
+ randomR() == random()
+ else randomR() == (random()$Integer rem 100)::R
+ factorByRecursion pp ==
+ and/[zero? degree u for u in coefficients pp] =>
+ map(raise,factorPolynomial lower pp)
+ c:=content pp
+ unit? c => refine(squareFree pp,factorSquareFreeByRecursion)
+ pp:=(pp exquo c)::SupS
+ mergeFactors(refine(squareFree pp,factorSquareFreeByRecursion),
+ map(#1:S::SupS,factor(c)$S))
+ factorSquareFreeByRecursion pp ==
+ and/[zero? degree u for u in coefficients pp] =>
+ map(raise,factorSquareFreePolynomial lower pp)
+ unit? (lcpp := leadingCoefficient pp) => factorSFBRlcUnit(pp)
+ oldnfact:NonNegativeInteger:= 999999
+ -- I hope we never have to factor a polynomial
+ -- with more than this number of factors
+ lcppPow:S
+ while true repeat -- a loop over possible false splits
+ cVS:=chooseFSQViableSubstitutions(pp)
+ newppR:=primitivePart cVS.ppRField
+ factorsR:=factorSquareFreePolynomial(newppR)
+ (nfact:=numberOfFactors factorsR) = 1 =>
+ return makeFR(1,[["irred",pp,1]])
+ -- OK, force all leading coefficients to be equal to the leading
+ -- coefficient of the input
+ nfact > oldnfact => "next" -- can't be a good reduction
+ oldnfact:=nfact
+ lcppR:=leadingCoefficient cVS.ppRField
+ factors:=[raise((lcppR exquo leadingCoefficient u.fctr) ::R * u.fctr)
+ for u in factorList factorsR]
+ -- factors now multiplies to give cVS.ppRField * lcppR^(#factors-1)
+ -- Now change the leading coefficient to be lcpp
+ factors:=[monomial(lcpp,degree u) + reductum u for u in factors]
+-- factors:=[(lcpp exquo leadingCoefficient u.fctr)::S * raise u.fctr
+-- for u in factorList factorsR]
+ ppAdjust:=(lcppPow:=lcpp**#(rest factors)) * pp
+ OK:=true
+ hen:=hensel(ppAdjust,cVS.substnsField,factors)
+ hen case "failed" => "next"
+ factors:=hen.fctrs
+ leave
+ factors:=[ (lc:=content w;
+ lcppPow:=(lcppPow exquo lc)::S;
+ (w exquo lc)::SupS)
+ for w in factors]
+ not unit? lcppPow =>
+ error "internal error in factorSquareFreeByRecursion"
+ makeFR((recip lcppPow)::S::SupS,
+ [["irred",w,1] for w in factors])
+
+@
+\section{package PFBR PolynomialFactorizationByRecursion}
+<<package PFBR PolynomialFactorizationByRecursion>>=
+)abbrev package PFBR PolynomialFactorizationByRecursion
+++ Description: PolynomialFactorizationByRecursion(R,E,VarSet,S)
+++ is used for factorization of sparse univariate polynomials over
+++ a domain S of multivariate polynomials over R.
+PolynomialFactorizationByRecursion(R,E, VarSet:OrderedSet, S): public ==
+ private where
+ R:PolynomialFactorizationExplicit
+ E:OrderedAbelianMonoidSup
+ S:PolynomialCategory(R,E,VarSet)
+ PI ==> PositiveInteger
+ SupR ==> SparseUnivariatePolynomial R
+ SupSupR ==> SparseUnivariatePolynomial SupR
+ SupS ==> SparseUnivariatePolynomial S
+ SupSupS ==> SparseUnivariatePolynomial SupS
+ LPEBFS ==> LinearPolynomialEquationByFractions(S)
+ public == with
+ solveLinearPolynomialEquationByRecursion: (List SupS, SupS) ->
+ Union(List SupS,"failed")
+ ++ \spad{solveLinearPolynomialEquationByRecursion([p1,...,pn],p)}
+ ++ returns the list of polynomials \spad{[q1,...,qn]}
+ ++ such that \spad{sum qi/pi = p / prod pi}, a
+ ++ recursion step for solveLinearPolynomialEquation
+ ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+ ++ (see \spadfun{solveLinearPolynomialEquation}).
+ ++ If no such list of qi exists, then "failed" is returned.
+ factorByRecursion: SupS -> Factored SupS
+ ++ factorByRecursion(p) factors polynomial p. This function
+ ++ performs the recursion step for factorPolynomial,
+ ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+ ++ (see \spadfun{factorPolynomial})
+ factorSquareFreeByRecursion: SupS -> Factored SupS
+ ++ factorSquareFreeByRecursion(p) returns the square free
+ ++ factorization of p. This functions performs
+ ++ the recursion step for factorSquareFreePolynomial,
+ ++ as defined in \spadfun{PolynomialFactorizationExplicit} category
+ ++ (see \spadfun{factorSquareFreePolynomial}).
+ randomR: -> R -- has to be global, since has alternative definitions
+ ++ randomR produces a random element of R
+ bivariateSLPEBR: (List SupS, SupS, VarSet) -> Union(List SupS,"failed")
+ ++ bivariateSLPEBR(lp,p,v) implements
+ ++ the bivariate case of
+ ++ \spadfunFrom{solveLinearPolynomialEquationByRecursion}{PolynomialFactorizationByRecursionUnivariate};
+ ++ its implementation depends on R
+ factorSFBRlcUnit: (List VarSet, SupS) -> Factored SupS
+ ++ factorSFBRlcUnit(p) returns the square free factorization of
+ ++ polynomial p
+ ++ (see \spadfun{factorSquareFreeByRecursion}{PolynomialFactorizationByRecursionUnivariate})
+ ++ in the case where the leading coefficient of p
+ ++ is a unit.
+ private == add
+ supR: SparseUnivariatePolynomial R
+ pp: SupS
+ lpolys,factors: List SupS
+ vv:VarSet
+ lvpolys,lvpp: List VarSet
+ r:R
+ lr:List R
+ import FactoredFunctionUtilities(SupS)
+ import FactoredFunctions2(S,SupS)
+ import FactoredFunctions2(SupR,SupS)
+ import CommuteUnivariatePolynomialCategory(S,SupS, SupSupS)
+ import UnivariatePolynomialCategoryFunctions2(S,SupS,SupS,SupSupS)
+ import UnivariatePolynomialCategoryFunctions2(SupS,SupSupS,S,SupS)
+ import UnivariatePolynomialCategoryFunctions2(S,SupS,R,SupR)
+ import UnivariatePolynomialCategoryFunctions2(R,SupR,S,SupS)
+ import UnivariatePolynomialCategoryFunctions2(S,SupS,SupR,SupSupR)
+ import UnivariatePolynomialCategoryFunctions2(SupR,SupSupR,S,SupS)
+ hensel: (SupS,VarSet,R,List SupS) ->
+ Union(Record(fctrs:List SupS),"failed")
+ chooseSLPEViableSubstitutions: (List VarSet,List SupS,SupS) ->
+ Record(substnsField:List R,lpolysRField:List SupR,ppRField:SupR)
+ --++ chooseSLPEViableSubstitutions(lv,lp,p) chooses substitutions
+ --++ for the variables in first arg (which are all
+ --++ the variables that exist) so that the polys in second argument don't
+ --++ drop in degree and remain square-free, and third arg doesn't drop
+ --++ drop in degree
+ chooseFSQViableSubstitutions: (List VarSet,SupS) ->
+ Record(substnsField:List R,ppRField:SupR)
+ --++ chooseFSQViableSubstitutions(lv,p) chooses substitutions for the variables in first arg (which are all
+ --++ the variables that exist) so that the second argument poly doesn't
+ --++ drop in degree and remains square-free
+ raise: SupR -> SupS
+ lower: SupS -> SupR
+ SLPEBR: (List SupS, List VarSet, SupS, List VarSet) ->
+ Union(List SupS,"failed")
+ factorSFBRlcUnitInner: (List VarSet, SupS,R) ->
+ Union(Factored SupS,"failed")
+ hensel(pp,vv,r,factors) ==
+ origFactors:=factors
+ totdegree:Integer:=0
+ proddegree:Integer:=
+ "max"/[degree(u,vv) for u in coefficients pp]
+ n:PI:=1
+ prime:=vv::S - r::S
+ foundFactors:List SupS:=empty()
+ while (totdegree <= proddegree) repeat
+ pn:=prime**n
+ Ecart:=(pp-*/factors) exquo pn
+ Ecart case "failed" =>
+ error "failed lifting in hensel in PFBR"
+ zero? Ecart =>
+ -- then we have all the factors
+ return [append(foundFactors, factors)]
+ step:=solveLinearPolynomialEquation(origFactors,
+ map(eval(#1,vv,r),
+ Ecart))
+ step case "failed" => return "failed" -- must be a false split
+ factors:=[a+b*pn for a in factors for b in step]
+ for a in factors for c in origFactors repeat
+ pp1:= pp exquo a
+ pp1 case "failed" => "next"
+ pp:=pp1
+ proddegree := proddegree - "max"/[degree(u,vv)
+ for u in coefficients a]
+ factors:=remove(a,factors)
+ origFactors:=remove(c,origFactors)
+ foundFactors:=[a,:foundFactors]
+ #factors < 2 =>
+ return [(empty? factors => foundFactors;
+ [pp,:foundFactors])]
+ totdegree:= +/["max"/[degree(u,vv)
+ for u in coefficients u1]
+ for u1 in factors]
+ n:=n+1
+ "failed" -- must have been a false split
+
+ factorSFBRlcUnitInner(lvpp,pp,r) ==
+ -- pp is square-free as a Sup, and its coefficients have precisely
+ -- the variables of lvpp. Furthermore, its LC is a unit
+ -- returns "failed" if the substitution is bad, else a factorization
+ ppR:=map(eval(#1,first lvpp,r),pp)
+ degree ppR < degree pp => "failed"
+ degree gcd(ppR,differentiate ppR) >0 => "failed"
+ factors:=
+ empty? rest lvpp =>
+ fDown:=factorSquareFreePolynomial map(retract(#1)::R,ppR)
+ [raise (unit fDown * factorList(fDown).first.fctr),
+ :[raise u.fctr for u in factorList(fDown).rest]]
+ fSame:=factorSFBRlcUnit(rest lvpp,ppR)
+ [unit fSame * factorList(fSame).first.fctr,
+ :[uu.fctr for uu in factorList(fSame).rest]]
+ #factors = 1 => makeFR(1,[["irred",pp,1]])
+ hen:=hensel(pp,first lvpp,r,factors)
+ hen case "failed" => "failed"
+ makeFR(1,[["irred",u,1] for u in hen.fctrs])
+ if R has StepThrough then
+ factorSFBRlcUnit(lvpp,pp) ==
+ val:R := init()
+ while true repeat
+ tempAns:=factorSFBRlcUnitInner(lvpp,pp,val)
+ not (tempAns case "failed") => return tempAns
+ val1:=nextItem val
+ val1 case "failed" =>
+ error "at this point, we know we have a finite field"
+ val:=val1
+ else
+ factorSFBRlcUnit(lvpp,pp) ==
+ val:R := randomR()
+ while true repeat
+ tempAns:=factorSFBRlcUnitInner(lvpp,pp,val)
+ not (tempAns case "failed") => return tempAns
+ val := randomR()
+ if R has random: -> R then
+ randomR() == random()
+ else randomR() == (random()$Integer)::R
+ if R has FiniteFieldCategory then
+ bivariateSLPEBR(lpolys,pp,v) ==
+ lpolysR:List SupSupR:=[map(univariate,u) for u in lpolys]
+ ppR: SupSupR:=map(univariate,pp)
+ ans:=solveLinearPolynomialEquation(lpolysR,ppR)$SupR
+ ans case "failed" => "failed"
+ [map(multivariate(#1,v),w) for w in ans]
+ else
+ bivariateSLPEBR(lpolys,pp,v) ==
+ solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
+ chooseFSQViableSubstitutions(lvpp,pp) ==
+ substns:List R
+ ppR: SupR
+ while true repeat
+ substns:= [randomR() for v in lvpp]
+ zero? eval(leadingCoefficient pp,lvpp,substns ) => "next"
+ ppR:=map((retract eval(#1,lvpp,substns))::R,pp)
+ degree gcd(ppR,differentiate ppR)>0 => "next"
+ leave
+ [substns,ppR]
+ chooseSLPEViableSubstitutions(lvpolys,lpolys,pp) ==
+ substns:List R
+ lpolysR:List SupR
+ ppR: SupR
+ while true repeat
+ substns:= [randomR() for v in lvpolys]
+ zero? eval(leadingCoefficient pp,lvpolys,substns ) => "next"
+ "or"/[zero? eval(leadingCoefficient u,lvpolys,substns)
+ for u in lpolys] => "next"
+ lpolysR:=[map((retract eval(#1,lvpolys,substns))::R,u)
+ for u in lpolys]
+ uu:=lpolysR
+ while not empty? uu repeat
+ "or"/[ degree(gcd(uu.first,v))>0 for v in uu.rest] => leave
+ uu:=rest uu
+ not empty? uu => "next"
+ leave
+ ppR:=map((retract eval(#1,lvpolys,substns))::R,pp)
+ [substns,lpolysR,ppR]
+ raise(supR) == map(#1:R::S,supR)
+ lower(pp) == map(retract(#1)::R,pp)
+ SLPEBR(lpolys,lvpolys,pp,lvpp) ==
+ not empty? (m:=setDifference(lvpp,lvpolys)) =>
+ v:=first m
+ lvpp:=remove(v,lvpp)
+ pp1:SupSupS :=swap map(univariate(#1,v),pp)
+ -- pp1 is mathematically equal to pp, but is in S[z][v]
+ -- so we wish to operate on all of its coefficients
+ ans:List SupSupS:= [0 for u in lpolys]
+ for m in reverse_! monomials pp1 repeat
+ ans1:=SLPEBR(lpolys,lvpolys,leadingCoefficient m,lvpp)
+ ans1 case "failed" => return "failed"
+ d:=degree m
+ ans:=[monomial(a1,d)+a for a in ans for a1 in ans1]
+ [map(multivariate(#1,v),swap pp1) for pp1 in ans]
+ empty? lvpolys =>
+ lpolysR:List SupR
+ ppR:SupR
+ lpolysR:=[map(retract,u) for u in lpolys]
+ ppR:=map(retract,pp)
+ ansR:=solveLinearPolynomialEquation(lpolysR,ppR)
+ ansR case "failed" => return "failed"
+ [map(#1::S,uu) for uu in ansR]
+ cVS:=chooseSLPEViableSubstitutions(lvpolys,lpolys,pp)
+ ansR:=solveLinearPolynomialEquation(cVS.lpolysRField,cVS.ppRField)
+ ansR case "failed" => "failed"
+ #lvpolys = 1 => bivariateSLPEBR(lpolys,pp, first lvpolys)
+ solveLinearPolynomialEquationByFractions(lpolys,pp)$LPEBFS
+
+ solveLinearPolynomialEquationByRecursion(lpolys,pp) ==
+ lvpolys := removeDuplicates_!
+ concat [ concat [variables z for z in coefficients u]
+ for u in lpolys]
+ lvpp := removeDuplicates_!
+ concat [variables z for z in coefficients pp]
+ SLPEBR(lpolys,lvpolys,pp,lvpp)
+
+ factorByRecursion pp ==
+ lv:List(VarSet) := removeDuplicates_!
+ concat [variables z for z in coefficients pp]
+ empty? lv =>
+ map(raise,factorPolynomial lower pp)
+ c:=content pp
+ unit? c => refine(squareFree pp,factorSquareFreeByRecursion)
+ pp:=(pp exquo c)::SupS
+ mergeFactors(refine(squareFree pp,factorSquareFreeByRecursion),
+ map(#1:S::SupS,factor(c)$S))
+ factorSquareFreeByRecursion pp ==
+ lv:List(VarSet) := removeDuplicates_!
+ concat [variables z for z in coefficients pp]
+ empty? lv =>
+ map(raise,factorPolynomial lower pp)
+ unit? (lcpp := leadingCoefficient pp) => factorSFBRlcUnit(lv,pp)
+ oldnfact:NonNegativeInteger:= 999999
+ -- I hope we never have to factor a polynomial
+ -- with more than this number of factors
+ lcppPow:S
+ while true repeat
+ cVS:=chooseFSQViableSubstitutions(lv,pp)
+ factorsR:=factorSquareFreePolynomial(cVS.ppRField)
+ (nfact:=numberOfFactors factorsR) = 1 =>
+ return makeFR(1,[["irred",pp,1]])
+ -- OK, force all leading coefficients to be equal to the leading
+ -- coefficient of the input
+ nfact > oldnfact => "next" -- can't be a good reduction
+ oldnfact:=nfact
+ factors:=[(lcpp exquo leadingCoefficient u.fctr)::S * raise u.fctr
+ for u in factorList factorsR]
+ ppAdjust:=(lcppPow:=lcpp**#(rest factors)) * pp
+ lvppList:=lv
+ OK:=true
+ for u in lvppList for v in cVS.substnsField repeat
+ hen:=hensel(ppAdjust,u,v,factors)
+ hen case "failed" =>
+ OK:=false
+ "leave"
+ factors:=hen.fctrs
+ OK => leave
+ factors:=[ (lc:=content w;
+ lcppPow:=(lcppPow exquo lc)::S;
+ (w exquo lc)::SupS)
+ for w in factors]
+ not unit? lcppPow =>
+ error "internal error in factorSquareFreeByRecursion"
+ makeFR((recip lcppPow)::S::SupS,
+ [["irred",w,1] for w in factors])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PFBRU PolynomialFactorizationByRecursionUnivariate>>
+<<package PFBR PolynomialFactorizationByRecursion>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pfo.spad.pamphlet b/src/algebra/pfo.spad.pamphlet
new file mode 100644
index 00000000..1b310c40
--- /dev/null
+++ b/src/algebra/pfo.spad.pamphlet
@@ -0,0 +1,612 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pfo.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FORDER FindOrderFinite}
+<<package FORDER FindOrderFinite>>=
+)abbrev package FORDER FindOrderFinite
+++ Finds the order of a divisor over a finite field
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 11 Jul 1990
+FindOrderFinite(F, UP, UPUP, R): Exports == Implementation where
+ F : Join(Finite, Field)
+ UP : UnivariatePolynomialCategory F
+ UPUP: UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ Exports ==> with
+ order: FiniteDivisor(F, UP, UPUP, R) -> NonNegativeInteger
+ ++ order(x) \undocumented
+ Implementation ==> add
+ order d ==
+ dd := d := reduce d
+ for i in 1.. repeat
+ principal? dd => return(i::NonNegativeInteger)
+ dd := reduce(d + dd)
+
+@
+\section{package RDIV ReducedDivisor}
+<<package RDIV ReducedDivisor>>=
+)abbrev package RDIV ReducedDivisor
+++ Finds the order of a divisor over a finite field
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 8 November 1994
+ReducedDivisor(F1, UP, UPUP, R, F2): Exports == Implementation where
+ F1 : Field
+ UP : UnivariatePolynomialCategory F1
+ UPUP : UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F1, UP, UPUP)
+ F2 : Join(Finite, Field)
+
+ N ==> NonNegativeInteger
+ FD ==> FiniteDivisor(F1, UP, UPUP, R)
+ UP2 ==> SparseUnivariatePolynomial F2
+ UPUP2 ==> SparseUnivariatePolynomial Fraction UP2
+
+ Exports ==> with
+ order: (FD, UPUP, F1 -> F2) -> N
+ ++ order(f,u,g) \undocumented
+
+ Implementation ==> add
+ algOrder : (FD, UPUP, F1 -> F2) -> N
+ rootOrder: (FD, UP, N, F1 -> F2) -> N
+
+-- pp is not necessarily monic
+ order(d, pp, f) ==
+ (r := retractIfCan(reductum pp)@Union(Fraction UP, "failed"))
+ case "failed" => algOrder(d, pp, f)
+ rootOrder(d, - retract(r::Fraction(UP) / leadingCoefficient pp)@UP,
+ degree pp, f)
+
+ algOrder(d, modulus, reduce) ==
+ redmod := map(reduce, modulus)$MultipleMap(F1,UP,UPUP,F2,UP2,UPUP2)
+ curve := AlgebraicFunctionField(F2, UP2, UPUP2, redmod)
+ order(map(reduce,
+ d)$FiniteDivisorFunctions2(F1,UP,UPUP,R,F2,UP2,UPUP2,curve)
+ )$FindOrderFinite(F2, UP2, UPUP2, curve)
+
+ rootOrder(d, radicand, n, reduce) ==
+ redrad := map(reduce,
+ radicand)$UnivariatePolynomialCategoryFunctions2(F1,UP,F2,UP2)
+ curve := RadicalFunctionField(F2, UP2, UPUP2, redrad::Fraction UP2, n)
+ order(map(reduce,
+ d)$FiniteDivisorFunctions2(F1,UP,UPUP,R,F2,UP2,UPUP2,curve)
+ )$FindOrderFinite(F2, UP2, UPUP2, curve)
+
+@
+\section{package PFOTOOLS PointsOfFiniteOrderTools}
+<<package PFOTOOLS PointsOfFiniteOrderTools>>=
+)abbrev package PFOTOOLS PointsOfFiniteOrderTools
+++ Utilities for PFOQ and PFO
+++ Author: Manuel Bronstein
+++ Date Created: 25 Aug 1988
+++ Date Last Updated: 11 Jul 1990
+PointsOfFiniteOrderTools(UP, UPUP): Exports == Implementation where
+ UP : UnivariatePolynomialCategory Fraction Integer
+ UPUP : UnivariatePolynomialCategory Fraction UP
+
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Integer
+
+ Exports ==> with
+ getGoodPrime : Z -> PI
+ ++ getGoodPrime n returns the smallest prime not dividing n
+ badNum : UP -> Record(den:Z, gcdnum:Z)
+ ++ badNum(p) \undocumented
+ badNum : UPUP -> Z
+ ++ badNum(u) \undocumented
+ mix : List Record(den:Z, gcdnum:Z) -> Z
+ ++ mix(l) \undocumented
+ doubleDisc : UPUP -> Z
+ ++ doubleDisc(u) \undocumented
+ polyred : UPUP -> UPUP
+ ++ polyred(u) \undocumented
+
+ Implementation ==> add
+ import IntegerPrimesPackage(Z)
+ import UnivariatePolynomialCommonDenominator(Z, Q, UP)
+
+ mix l == lcm(lcm [p.den for p in l], gcd [p.gcdnum for p in l])
+ badNum(p:UPUP) == mix [badNum(retract(c)@UP) for c in coefficients p]
+
+ polyred r ==
+ lcm [commonDenominator(retract(c)@UP) for c in coefficients r] * r
+
+ badNum(p:UP) ==
+ cd := splitDenominator p
+ [cd.den, gcd [retract(c)@Z for c in coefficients(cd.num)]]
+
+ getGoodPrime n ==
+ p:PI := 3
+ while zero?(n rem p) repeat
+ p := nextPrime(p::Z)::PI
+ p
+
+ doubleDisc r ==
+ d := retract(discriminant r)@UP
+ retract(discriminant((d exquo gcd(d, differentiate d))::UP))@Z
+
+@
+\section{package PFOQ PointsOfFiniteOrderRational}
+<<package PFOQ PointsOfFiniteOrderRational>>=
+)abbrev package PFOQ PointsOfFiniteOrderRational
+++ Finds the order of a divisor on a rational curve
+++ Author: Manuel Bronstein
+++ Date Created: 25 Aug 1988
+++ Date Last Updated: 3 August 1993
+++ Description:
+++ This package provides function for testing whether a divisor on a
+++ curve is a torsion divisor.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r PFOQ INPUT
+PointsOfFiniteOrderRational(UP, UPUP, R): Exports == Implementation where
+ UP : UnivariatePolynomialCategory Fraction Integer
+ UPUP : UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(Fraction Integer, UP, UPUP)
+
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Integer
+ FD ==> FiniteDivisor(Q, UP, UPUP, R)
+
+ Exports ==> with
+ order : FD -> Union(N, "failed")
+ ++ order(f) \undocumented
+ torsion? : FD -> Boolean
+ ++ torsion?(f) \undocumented
+ torsionIfCan: FD -> Union(Record(order:N, function:R), "failed")
+ ++ torsionIfCan(f) \undocumented
+
+ Implementation ==> add
+ import PointsOfFiniteOrderTools(UP, UPUP)
+
+ possibleOrder: FD -> N
+ ratcurve : (FD, UPUP, Z) -> N
+ rat : (UPUP, FD, PI) -> N
+
+ torsion? d == order(d) case N
+
+-- returns the potential order of d, 0 if d is of infinite order
+ ratcurve(d, modulus, disc) ==
+ mn := minIndex(nm := numer(i := ideal d))
+ h := lift(hh := nm(mn + 1))
+ s := separate(retract(norm hh)@UP,
+ b := retract(retract(nm.mn)@Fraction(UP))@UP).primePart
+ bd := badNum denom i
+ r := resultant(s, b)
+ bad := lcm [disc, numer r, denom r, bd.den * bd.gcdnum, badNum h]$List(Z)
+ n := rat(modulus, d, p := getGoodPrime bad)
+-- if n > 1 then it is cheaper to compute the order modulo a second prime,
+-- since computing n * d could be very expensive
+-- one? n => n
+ (n = 1) => n
+ m := rat(modulus, d, getGoodPrime(p * bad))
+ n = m => n
+ 0
+
+ rat(pp, d, p) ==
+ gf := InnerPrimeField p
+ order(d, pp,
+ numer(#1)::gf / denom(#1)::gf)$ReducedDivisor(Q, UP, UPUP, R, gf)
+
+-- returns the potential order of d, 0 if d is of infinite order
+ possibleOrder d ==
+-- zero?(genus()) or one?(#(numer ideal d)) => 1
+ zero?(genus()) or (#(numer ideal d) = 1) => 1
+ r := polyred definingPolynomial()$R
+ ratcurve(d, r, doubleDisc r)
+
+ order d ==
+ zero?(n := possibleOrder(d := reduce d)) => "failed"
+ principal? reduce(n::Z * d) => n
+ "failed"
+
+ torsionIfCan d ==
+ zero?(n := possibleOrder(d := reduce d)) => "failed"
+ (g := generator reduce(n::Z * d)) case "failed" => "failed"
+ [n, g::R]
+
+@
+\section{package FSRED FunctionSpaceReduce}
+<<package FSRED FunctionSpaceReduce>>=
+)abbrev package FSRED FunctionSpaceReduce
+++ Reduction from a function space to the rational numbers
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 11 Jul 1990
+++ Description:
+++ This package provides function which replaces transcendental kernels
+++ in a function space by random integers. The correspondence between
+++ the kernels and the integers is fixed between calls to new().
+++ Keywords: function, space, redcution.
+FunctionSpaceReduce(R, F): Exports == Implementation where
+ R: Join(OrderedSet, IntegralDomain, RetractableTo Integer)
+ F: FunctionSpace R
+
+ Z ==> Integer
+ Q ==> Fraction Integer
+ UP ==> SparseUnivariatePolynomial Q
+ K ==> Kernel F
+ ALGOP ==> "%alg"
+
+ Exports ==> with
+ bringDown: F -> Q
+ ++ bringDown(f) \undocumented
+ bringDown: (F, K) -> UP
+ ++ bringDown(f,k) \undocumented
+ newReduc : () -> Void
+ ++ newReduc() \undocumented
+
+ Implementation ==> add
+ import SparseUnivariatePolynomialFunctions2(F, Q)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, SparseMultivariatePolynomial(R, K), F)
+
+ K2Z : K -> F
+
+ redmap := table()$AssociationList(K, Z)
+
+ newReduc() ==
+ for k in keys redmap repeat remove_!(k, redmap)
+ void
+
+ bringDown(f, k) ==
+ ff := univariate(f, k)
+ (bc := extendedEuclidean(map(bringDown, denom ff),
+ m := map(bringDown, minPoly k), 1)) case "failed" =>
+ error "denominator is 0"
+ (map(bringDown, numer ff) * bc.coef1) rem m
+
+ bringDown f ==
+ retract(eval(f, lk := kernels f, [K2Z k for k in lk]))@Q
+
+ K2Z k ==
+ has?(operator k, ALGOP) => error "Cannot reduce constant field"
+ (u := search(k, redmap)) case "failed" =>
+ setelt(redmap, k, random()$Z)::F
+ u::Z::F
+
+@
+\section{package PFO PointsOfFiniteOrder}
+<<package PFO PointsOfFiniteOrder>>=
+)abbrev package PFO PointsOfFiniteOrder
+++ Finds the order of a divisor on a curve
+++ Author: Manuel Bronstein
+++ Date Created: 1988
+++ Date Last Updated: 22 July 1998
+++ Description:
+++ This package provides function for testing whether a divisor on a
+++ curve is a torsion divisor.
+++ Keywords: divisor, algebraic, curve.
+++ Examples: )r PFO INPUT
+PointsOfFiniteOrder(R0, F, UP, UPUP, R): Exports == Implementation where
+ R0 : Join(OrderedSet, IntegralDomain, RetractableTo Integer)
+ F : FunctionSpace R0
+ UP : UnivariatePolynomialCategory F
+ UPUP : UnivariatePolynomialCategory Fraction UP
+ R : FunctionFieldCategory(F, UP, UPUP)
+
+ PI ==> PositiveInteger
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ Q ==> Fraction Integer
+ UPF ==> SparseUnivariatePolynomial F
+ UPQ ==> SparseUnivariatePolynomial Q
+ QF ==> Fraction UP
+ UPUPQ ==> SparseUnivariatePolynomial Fraction UPQ
+ UP2 ==> SparseUnivariatePolynomial UPQ
+ UP3 ==> SparseUnivariatePolynomial UP2
+ FD ==> FiniteDivisor(F, UP, UPUP, R)
+ K ==> Kernel F
+ REC ==> Record(ncurve:UP3, disc:Z, dfpoly:UPQ)
+ RC0 ==> Record(ncurve:UPUPQ, disc:Z)
+ ID ==> FractionalIdeal(UP, QF, UPUP, R)
+ SMP ==> SparseMultivariatePolynomial(R0,K)
+ ALGOP ==> "%alg"
+
+ Exports ==> with
+ order : FD -> Union(N, "failed")
+ ++ order(f) \undocumented
+ torsion? : FD -> Boolean
+ ++ torsion?(f) \undocumented
+ torsionIfCan : FD -> Union(Record(order:N, function:R), "failed")
+ ++ torsionIfCan(f)\ undocumented
+
+ Implementation ==> add
+ import IntegerPrimesPackage(Z)
+ import PointsOfFiniteOrderTools(UPQ, UPUPQ)
+ import UnivariatePolynomialCommonDenominator(Z, Q, UPQ)
+
+ cmult: List SMP -> SMP
+ raise : (UPQ, K) -> F
+ raise2 : (UP2, K) -> UP
+ qmod : F -> Q
+ fmod : UPF -> UPQ
+ rmod : UP -> UPQ
+ pmod : UPUP -> UPUPQ
+ kqmod : (F, K) -> UPQ
+ krmod : (UP, K) -> UP2
+ kpmod : (UPUP, K) -> UP3
+ selectIntegers: K -> REC
+ selIntegers: () -> RC0
+ possibleOrder : FD -> N
+ ratcurve : (FD, RC0) -> N
+ algcurve : (FD, REC, K) -> N
+ kbad3Num : (UP3, UPQ) -> Z
+ kbadBadNum : (UP2, UPQ) -> Z
+ kgetGoodPrime : (REC, UPQ, UP3, UP2,UP2) -> Record(prime:PI,poly:UPQ)
+ goodRed : (REC, UPQ, UP3, UP2, UP2, PI) -> Union(UPQ, "failed")
+ good? : (UPQ, UP3, UP2, UP2, PI, UPQ) -> Boolean
+ klist : UP -> List K
+ aklist : R -> List K
+ alglist : FD -> List K
+ notIrr? : UPQ -> Boolean
+ rat : (UPUP, FD, PI) -> N
+ toQ1 : (UP2, UPQ) -> UP
+ toQ2 : (UP3, UPQ) -> R
+ Q2F : Q -> F
+ Q2UPUP : UPUPQ -> UPUP
+
+ q := FunctionSpaceReduce(R0, F)
+
+ torsion? d == order(d) case N
+ Q2F x == numer(x)::F / denom(x)::F
+ qmod x == bringDown(x)$q
+ kqmod(x,k) == bringDown(x, k)$q
+ fmod p == map(qmod, p)$SparseUnivariatePolynomialFunctions2(F, Q)
+ pmod p == map(qmod, p)$MultipleMap(F, UP, UPUP, Q, UPQ, UPUPQ)
+ Q2UPUP p == map(Q2F, p)$MultipleMap(Q, UPQ, UPUPQ, F, UP, UPUP)
+ klist d == "setUnion"/[kernels c for c in coefficients d]
+ notIrr? d == #(factors factor(d)$RationalFactorize(UPQ)) > 1
+ kbadBadNum(d, m) == mix [badNum(c rem m) for c in coefficients d]
+ kbad3Num(h, m) == lcm [kbadBadNum(c, m) for c in coefficients h]
+
+ torsionIfCan d ==
+ zero?(n := possibleOrder(d := reduce d)) => "failed"
+ (g := generator reduce(n::Z * d)) case "failed" => "failed"
+ [n, g::R]
+
+ UPQ2F(p:UPQ, k:K):F ==
+ map(Q2F, p)$UnivariatePolynomialCategoryFunctions2(Q, UPQ, F, UP) (k::F)
+
+ UP22UP(p:UP2, k:K):UP ==
+ map(UPQ2F(#1, k), p)$UnivariatePolynomialCategoryFunctions2(UPQ,UP2,F,UP)
+
+ UP32UPUP(p:UP3, k:K):UPUP ==
+ map(UP22UP(#1,k)::QF,
+ p)$UnivariatePolynomialCategoryFunctions2(UP2, UP3, QF, UPUP)
+
+ if R0 has GcdDomain then
+ cmult(l:List SMP):SMP == lcm l
+ else
+ cmult(l:List SMP):SMP == */l
+
+ doubleDisc(f:UP3):Z ==
+ d := discriminant f
+ g := gcd(d, differentiate d)
+ d := (d exquo g)::UP2
+ zero?(e := discriminant d) => 0
+ gcd [retract(c)@Z for c in coefficients e]
+
+ commonDen(p:UP):SMP ==
+ l1:List F := coefficients p
+ l2:List SMP := [denom c for c in l1]
+ cmult l2
+
+ polyred(f:UPUP):UPUP ==
+ cmult([commonDen(retract(c)@UP) for c in coefficients f])::F::UP::QF * f
+
+ aklist f ==
+ (r := retractIfCan(f)@Union(QF, "failed")) case "failed" =>
+ "setUnion"/[klist(retract(c)@UP) for c in coefficients lift f]
+ klist(retract(r::QF)@UP)
+
+ alglist d ==
+ n := numer(i := ideal d)
+ select_!(has?(operator #1, ALGOP),
+ setUnion(klist denom i,
+ "setUnion"/[aklist qelt(n,i) for i in minIndex n..maxIndex n]))
+
+ krmod(p,k) ==
+ map(kqmod(#1, k),
+ p)$UnivariatePolynomialCategoryFunctions2(F, UP, UPQ, UP2)
+
+ rmod p ==
+ map(qmod, p)$UnivariatePolynomialCategoryFunctions2(F, UP, Q, UPQ)
+
+ raise(p, k) ==
+ (map(Q2F, p)$SparseUnivariatePolynomialFunctions2(Q, F)) (k::F)
+
+ raise2(p, k) ==
+ map(raise(#1, k),
+ p)$UnivariatePolynomialCategoryFunctions2(UPQ, UP2, F, UP)
+
+ algcurve(d, rc, k) ==
+ mn := minIndex(n := numer(i := minimize ideal d))
+ h := kpmod(lift(hh := n(mn + 1)), k)
+ b2 := primitivePart
+ raise2(b := krmod(retract(retract(n.mn)@QF)@UP, k), k)
+ s := kqmod(resultant(primitivePart separate(raise2(krmod(
+ retract(norm hh)@UP, k), k), b2).primePart, b2), k)
+ pr := kgetGoodPrime(rc, s, h, b, dd := krmod(denom i, k))
+ p := pr.prime
+ pp := UP32UPUP(rc.ncurve, k)
+ mm := pr.poly
+ gf := InnerPrimeField p
+ m := map(retract(#1)@Z :: gf,
+ mm)$SparseUnivariatePolynomialFunctions2(Q, gf)
+-- one? degree m =>
+ (degree m = 1) =>
+ alpha := - coefficient(m, 0) / leadingCoefficient m
+ order(d, pp,
+ (map(numer(#1)::gf / denom(#1)::gf,
+ kqmod(#1,k))$SparseUnivariatePolynomialFunctions2(Q,gf))(alpha)
+ )$ReducedDivisor(F, UP, UPUP, R, gf)
+ -- d1 := toQ1(dd, mm)
+ -- rat(pp, divisor ideal([(toQ1(b, mm) / d1)::QF::R,
+ -- inv(d1::QF) * toQ2(h,mm)])$ID, p)
+ sae:= SimpleAlgebraicExtension(gf,SparseUnivariatePolynomial gf,m)
+ order(d, pp,
+ reduce(map(numer(#1)::gf / denom(#1)::gf,
+ kqmod(#1,k))$SparseUnivariatePolynomialFunctions2(Q,gf))$sae
+ )$ReducedDivisor(F, UP, UPUP, R, sae)
+
+-- returns the potential order of d, 0 if d is of infinite order
+ ratcurve(d, rc) ==
+ mn := minIndex(nm := numer(i := minimize ideal d))
+ h := pmod lift(hh := nm(mn + 1))
+ b := rmod(retract(retract(nm.mn)@QF)@UP)
+ s := separate(rmod(retract(norm hh)@UP), b).primePart
+ bd := badNum rmod denom i
+ r := resultant(s, b)
+ bad := lcm [rc.disc, numer r, denom r, bd.den*bd.gcdnum, badNum h]$List(Z)
+ pp := Q2UPUP(rc.ncurve)
+ n := rat(pp, d, p := getGoodPrime bad)
+-- if n > 1 then it is cheaper to compute the order modulo a second prime,
+-- since computing n * d could be very expensive
+-- one? n => n
+ (n = 1) => n
+ m := rat(pp, d, getGoodPrime(p * bad))
+ n = m => n
+ 0
+
+-- returns the order of d mod p
+ rat(pp, d, p) ==
+ gf := InnerPrimeField p
+ order(d, pp, (qq := qmod #1;numer(qq)::gf / denom(qq)::gf)
+ )$ReducedDivisor(F, UP, UPUP, R, gf)
+
+-- returns the potential order of d, 0 if d is of infinite order
+ possibleOrder d ==
+-- zero?(genus()) or one?(#(numer ideal d)) => 1
+ zero?(genus()) or (#(numer ideal d) = 1) => 1
+ empty?(la := alglist d) => ratcurve(d, selIntegers())
+ not(empty? rest la) =>
+ error "PFO::possibleOrder: more than 1 algebraic constant"
+ algcurve(d, selectIntegers first la, first la)
+
+ selIntegers():RC0 ==
+ f := definingPolynomial()$R
+ while zero?(d := doubleDisc(r := polyred pmod f)) repeat newReduc()$q
+ [r, d]
+
+ selectIntegers(k:K):REC ==
+ g := polyred(f := definingPolynomial()$R)
+ p := minPoly k
+ while zero?(d := doubleDisc(r := kpmod(g, k))) or (notIrr? fmod p)
+ repeat newReduc()$q
+ [r, d, splitDenominator(fmod p).num]
+
+ toQ1(p, d) ==
+ map(Q2F(retract(#1 rem d)@Q),
+ p)$UnivariatePolynomialCategoryFunctions2(UPQ, UP2, F, UP)
+
+ toQ2(p, d) ==
+ reduce map(toQ1(#1, d)::QF,
+ p)$UnivariatePolynomialCategoryFunctions2(UP2, UP3, QF, UPUP)
+
+ kpmod(p, k) ==
+ map(krmod(retract(#1)@UP, k),
+ p)$UnivariatePolynomialCategoryFunctions2(QF, UPUP, UP2, UP3)
+
+ order d ==
+ zero?(n := possibleOrder(d := reduce d)) => "failed"
+ principal? reduce(n::Z * d) => n
+ "failed"
+
+ kgetGoodPrime(rec, res, h, b, d) ==
+ p:PI := 3
+ while (u := goodRed(rec, res, h, b, d, p)) case "failed" repeat
+ p := nextPrime(p::Z)::PI
+ [p, u::UPQ]
+
+ goodRed(rec, res, h, b, d, p) ==
+ zero?(rec.disc rem p) => "failed"
+ gf := InnerPrimeField p
+ l := [f.factor for f in factors factor(map(retract(#1)@Z :: gf,
+ rec.dfpoly)$SparseUnivariatePolynomialFunctions2(Q,
+ gf))$DistinctDegreeFactorize(gf,
+-- SparseUnivariatePolynomial gf) | one?(f.exponent)]
+ SparseUnivariatePolynomial gf) | (f.exponent = 1)]
+ empty? l => "failed"
+ mdg := first l
+ for ff in rest l repeat
+ if degree(ff) < degree(mdg) then mdg := ff
+ md := map(convert(#1)@Z :: Q,
+ mdg)$SparseUnivariatePolynomialFunctions2(gf, Q)
+ good?(res, h, b, d, p, md) => md
+ "failed"
+
+ good?(res, h, b, d, p, m) ==
+ bd := badNum(res rem m)
+ not (zero?(bd.den rem p) or zero?(bd.gcdnum rem p) or
+ zero?(kbadBadNum(b,m) rem p) or zero?(kbadBadNum(d,m) rem p)
+ or zero?(kbad3Num(h, m) rem p))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor PFO
+-- intalg intaf efstruc rdeef intef irexpand integrat
+
+<<package FORDER FindOrderFinite>>
+<<package RDIV ReducedDivisor>>
+<<package PFOTOOLS PointsOfFiniteOrderTools>>
+<<package PFOQ PointsOfFiniteOrderRational>>
+<<package FSRED FunctionSpaceReduce>>
+<<package PFO PointsOfFiniteOrder>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pfr.spad.pamphlet b/src/algebra/pfr.spad.pamphlet
new file mode 100644
index 00000000..8286147e
--- /dev/null
+++ b/src/algebra/pfr.spad.pamphlet
@@ -0,0 +1,438 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pfr.spad}
+\author{Robert Sutor, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PFR PartialFraction}
+<<domain PFR PartialFraction>>=
+)abbrev domain PFR PartialFraction
+++ Author: Robert S. Sutor
+++ Date Created: 1986
+++ Change History:
+++ 05/20/91 BMT Converted to the new library
+++ Basic Operations: (Field), (Algebra),
+++ coerce, compactFraction, firstDenom, firstNumer,
+++ nthFractionalTerm, numberOfFractionalTerms, padicallyExpand,
+++ padicFraction, partialFraction, wholePart
+++ Related Constructors:
+++ Also See: ContinuedFraction
+++ AMS Classifications:
+++ Keywords: partial fraction, factorization, euclidean domain
+++ References:
+++ Description:
+++ The domain \spadtype{PartialFraction} implements partial fractions
+++ over a euclidean domain \spad{R}. This requirement on the
+++ argument domain allows us to normalize the fractions. Of
+++ particular interest are the 2 forms for these fractions. The
+++ ``compact'' form has only one fractional term per prime in the
+++ denominator, while the ``p-adic'' form expands each numerator
+++ p-adically via the prime p in the denominator. For computational
+++ efficiency, the compact form is used, though the p-adic form may
+++ be gotten by calling the function \spadfunFrom{padicFraction}{PartialFraction}. For a
+++ general euclidean domain, it is not known how to factor the
+++ denominator. Thus the function \spadfunFrom{partialFraction}{PartialFraction} takes as its
+++ second argument an element of \spadtype{Factored(R)}.
+
+PartialFraction(R: EuclideanDomain): Cat == Capsule where
+ FRR ==> Factored R
+ SUPR ==> SparseUnivariatePolynomial R
+
+ Cat == Join(Field, Algebra R) with
+ coerce: % -> Fraction R
+ ++ coerce(p) sums up the components of the partial fraction and
+ ++ returns a single fraction.
+
+ coerce: Fraction FRR -> %
+ ++ coerce(f) takes a fraction with numerator and denominator in
+ ++ factored form and creates a partial fraction. It is
+ ++ necessary for the parts to be factored because it is not
+ ++ known in general how to factor elements of \spad{R} and
+ ++ this is needed to decompose into partial fractions.
+
+ compactFraction: % -> %
+ ++ compactFraction(p) normalizes the partial fraction \spad{p}
+ ++ to the compact representation. In this form, the partial
+ ++ fraction has only one fractional term per prime in the
+ ++ denominator.
+
+ firstDenom: % -> FRR
+ ++ firstDenom(p) extracts the denominator of the first fractional
+ ++ term. This returns 1 if there is no fractional part (use
+ ++ \spadfunFrom{wholePart}{PartialFraction} to get the whole part).
+
+ firstNumer: % -> R
+ ++ firstNumer(p) extracts the numerator of the first fractional
+ ++ term. This returns 0 if there is no fractional part (use
+ ++ \spadfunFrom{wholePart}{PartialFraction} to get the whole part).
+
+ nthFractionalTerm: (%,Integer) -> %
+ ++ nthFractionalTerm(p,n) extracts the nth fractional term from
+ ++ the partial fraction \spad{p}. This returns 0 if the index
+ ++ \spad{n} is out of range.
+
+ numberOfFractionalTerms: % -> Integer
+ ++ numberOfFractionalTerms(p) computes the number of fractional
+ ++ terms in \spad{p}. This returns 0 if there is no fractional
+ ++ part.
+
+ padicallyExpand: (R,R) -> SUPR
+ ++ padicallyExpand(p,x) is a utility function that expands
+ ++ the second argument \spad{x} ``p-adically'' in
+ ++ the first.
+
+ padicFraction: % -> %
+ ++ padicFraction(q) expands the fraction p-adically in the primes
+ ++ \spad{p} in the denominator of \spad{q}. For example,
+ ++ \spad{padicFraction(3/(2**2)) = 1/2 + 1/(2**2)}.
+ ++ Use \spadfunFrom{compactFraction}{PartialFraction} to return to compact form.
+
+ partialFraction: (R, FRR) -> %
+ ++ partialFraction(numer,denom) is the main function for
+ ++ constructing partial fractions. The second argument is the
+ ++ denominator and should be factored.
+
+ wholePart: % -> R
+ ++ wholePart(p) extracts the whole part of the partial fraction
+ ++ \spad{p}.
+
+ Capsule == add
+
+ -- some constructor assignments and macros
+
+ Ex ==> OutputForm
+ fTerm ==> Record(num: R, den: FRR) -- den should have
+ -- unit = 1 and only
+ -- 1 factor
+ LfTerm ==> List Record(num: R, den: FRR)
+ QR ==> Record(quotient: R, remainder: R)
+
+ Rep := Record(whole:R, fract: LfTerm)
+
+ -- private function signatures
+
+ copypf: % -> %
+ LessThan: (fTerm, fTerm) -> Boolean
+ multiplyFracTerms: (fTerm, fTerm) -> %
+ normalizeFracTerm: fTerm -> %
+ partialFractionNormalized: (R, FRR) -> %
+
+ -- declarations
+
+ a,b: %
+ n: Integer
+ r: R
+
+ -- private function definitions
+
+ copypf(a: %): % == [a.whole,copy a.fract]$%
+
+ LessThan(s: fTerm, t: fTerm) ==
+ -- have to wait until FR has < operation
+ if (GGREATERP(s.den,t.den)$Lisp : Boolean) then false
+ else true
+
+ multiplyFracTerms(s : fTerm, t : fTerm) ==
+ nthFactor(s.den,1) = nthFactor(t.den,1) =>
+ normalizeFracTerm([s.num * t.num, s.den * t.den]$fTerm) : Rep
+ i : Union(Record(coef1: R, coef2: R),"failed")
+ coefs : Record(coef1: R, coef2: R)
+ i := extendedEuclidean(expand t.den, expand s.den,s.num * t.num)
+ i case "failed" => error "PartialFraction: not in ideal"
+ coefs := (i :: Record(coef1: R, coef2: R))
+ c : % := copypf 0$%
+ d : %
+ if coefs.coef2 ^= 0$R then
+ c := normalizeFracTerm ([coefs.coef2, t.den]$fTerm)
+ if coefs.coef1 ^= 0$R then
+ d := normalizeFracTerm ([coefs.coef1, s.den]$fTerm)
+ c.whole := c.whole + d.whole
+ not (null d.fract) => c.fract := append(d.fract,c.fract)
+ c
+
+ normalizeFracTerm(s : fTerm) ==
+ -- makes sure num is "less than" den, whole may be non-zero
+ qr : QR := divide(s.num, (expand s.den))
+ qr.remainder = 0$R => [qr.quotient, nil()$LfTerm]
+ -- now verify num and den are coprime
+ f : R := nthFactor(s.den,1)
+ nexpon : Integer := nthExponent(s.den,1)
+ expon : Integer := 0
+ q : QR := divide(qr.remainder, f)
+ while (q.remainder = 0$R) and (expon < nexpon) repeat
+ expon := expon + 1
+ qr.remainder := q.quotient
+ q := divide(qr.remainder,f)
+ expon = 0 => [qr.quotient,[[qr.remainder, s.den]$fTerm]$LfTerm]
+ expon = nexpon => (qr.quotient + qr.remainder) :: %
+ [qr.quotient,[[qr.remainder, nilFactor(f,nexpon-expon)]$fTerm]$LfTerm]
+
+ partialFractionNormalized(nm: R, dn : FRR) ==
+ -- assume unit dn = 1
+ nm = 0$R => 0$%
+ dn = 1$FRR => nm :: %
+ qr : QR := divide(nm, expand dn)
+ c : % := [0$R,[[qr.remainder,
+ nilFactor(nthFactor(dn,1), nthExponent(dn,1))]$fTerm]$LfTerm]
+ d : %
+ for i in 2..numberOfFactors(dn) repeat
+ d :=
+ [0$R,[[1$R,nilFactor(nthFactor(dn,i), nthExponent(dn,i))]$fTerm]$LfTerm]
+ c := c * d
+ (qr.quotient :: %) + c
+
+ -- public function definitions
+
+ padicFraction(a : %) ==
+ b: % := compactFraction a
+ null b.fract => b
+ l : LfTerm := nil
+ s : fTerm
+ f : R
+ e,d: Integer
+ for s in b.fract repeat
+ e := nthExponent(s.den,1)
+ e = 1 => l := cons(s,l)
+ f := nthFactor(s.den,1)
+ d := degree(sp := padicallyExpand(f,s.num))
+ while (sp ^= 0$SUPR) repeat
+ l := cons([leadingCoefficient sp,nilFactor(f,e-d)]$fTerm, l)
+ d := degree(sp := reductum sp)
+ [b.whole, sort(LessThan,l)]$%
+
+ compactFraction(a : %) ==
+ -- only one power for each distinct denom will remain
+ 2 > # a.fract => a
+ af : LfTerm := reverse a.fract
+ bf : LfTerm := nil
+ bw : R := a.whole
+ b : %
+ s : fTerm := [(first af).num,(first af).den]$fTerm
+ f : R := nthFactor(s.den,1)
+ e : Integer := nthExponent(s.den,1)
+ t : fTerm
+ for t in rest af repeat
+ f = nthFactor(t.den,1) =>
+ s.num := s.num + (t.num *
+ (f **$R ((e - nthExponent(t.den,1)) : NonNegativeInteger)))
+ b := normalizeFracTerm s
+ bw := bw + b.whole
+ if not (null b.fract) then bf := cons(first b.fract,bf)
+ s := [t.num, t.den]$fTerm
+ f := nthFactor(s.den,1)
+ e := nthExponent(s.den,1)
+ b := normalizeFracTerm s
+ [bw + b.whole,append(b.fract,bf)]$%
+
+ 0 == [0$R, nil()$LfTerm]
+ 1 == [1$R, nil()$LfTerm]
+ characteristic() == characteristic()$R
+
+ coerce(r): % == [r, nil()$LfTerm]
+ coerce(n): % == [(n :: R), nil()$LfTerm]
+ coerce(a): Fraction R ==
+ q : Fraction R := (a.whole :: Fraction R)
+ s : fTerm
+ for s in a.fract repeat
+ q := q + (s.num / (expand s.den))
+ q
+ coerce(q: Fraction FRR): % ==
+ u : R := (recip unit denom q):: R
+ r1 : R := u * expand numer q
+ partialFractionNormalized(r1, u * denom q)
+
+ a exquo b ==
+ b = 0$% => "failed"
+ b = 1$% => a
+ br : Fraction R := inv (b :: Fraction R)
+ a * partialFraction(numer br,(denom br) :: FRR)
+ recip a == (1$% exquo a)
+
+ firstDenom a == -- denominator of 1st fractional term
+ null a.fract => 1$FRR
+ (first a.fract).den
+ firstNumer a == -- numerator of 1st fractional term
+ null a.fract => 0$R
+ (first a.fract).num
+ numberOfFractionalTerms a == # a.fract
+ nthFractionalTerm(a,n) ==
+ l : LfTerm := a.fract
+ (n < 1) or (n > # l) => 0$%
+ [0$R,[l.n]$LfTerm]$%
+ wholePart a == a.whole
+
+ partialFraction(nm: R, dn : FRR) ==
+ nm = 0$R => 0$%
+ -- move inv unit of den to numerator
+ u : R := unit dn
+ u := (recip u) :: R
+ partialFractionNormalized(u * nm,u * dn)
+
+ padicallyExpand(p : R, r : R) ==
+ -- expands r as a sum of powers of p, with coefficients
+ -- r = HornerEval(padicallyExpand(p,r),p)
+ qr : QR := divide(r, p)
+ qr.quotient = 0$R => qr.remainder :: SUPR
+ (qr.remainder :: SUPR) + monomial(1$R,1$NonNegativeInteger)$SUPR *
+ padicallyExpand(p,qr.quotient)
+
+ a = b ==
+ a.whole ^= b.whole => false -- must verify this
+ (null a.fract) =>
+ null b.fract => a.whole = b.whole
+ false
+ null b.fract => false
+ -- oh, no! following is temporary
+ (a :: Fraction R) = (b :: Fraction R)
+
+ - a ==
+ s: fTerm
+ l: LfTerm := nil
+ for s in reverse a.fract repeat l := cons([- s.num,s.den]$fTerm,l)
+ [- a.whole,l]
+
+ r * a ==
+ r = 0$R => 0$%
+ r = 1$R => a
+ b : % := (r * a.whole) :: %
+ c : %
+ s : fTerm
+ for s in reverse a.fract repeat
+ c := normalizeFracTerm [r * s.num, s.den]$fTerm
+ b.whole := b.whole + c.whole
+ not (null c.fract) => b.fract := append(c.fract, b.fract)
+ b
+
+ n * a == (n :: R) * a
+
+ a + b ==
+ compactFraction
+ [a.whole + b.whole,
+ sort(LessThan,append(a.fract,copy b.fract))]$%
+
+ a * b ==
+ null a.fract => a.whole * b
+ null b.fract => b.whole * a
+ af : % := [0$R, a.fract]$% -- a - a.whole
+ c: % := (a.whole * b) + (b.whole * af)
+ s,t : fTerm
+ for s in a.fract repeat
+ for t in b.fract repeat
+ c := c + multiplyFracTerms(s,t)
+ c
+
+ coerce(a): Ex ==
+ null a.fract => a.whole :: Ex
+ s : fTerm
+ l : List Ex
+ if a.whole = 0 then l := nil else l := [a.whole :: Ex]
+ for s in a.fract repeat
+ s.den = 1$FRR => l := cons(s.num :: Ex, l)
+ l := cons(s.num :: Ex / s.den :: Ex, l)
+ # l = 1 => first l
+ reduce("+", reverse l)
+
+@
+\section{package PFRPAC PartialFractionPackage}
+<<package PFRPAC PartialFractionPackage>>=
+)abbrev package PFRPAC PartialFractionPackage
+++ Author: Barry M. Trager
+++ Date Created: 1992
+++ BasicOperations:
+++ Related Constructors: PartialFraction
+++ Also See:
+++ AMS Classifications:
+++ Keywords: partial fraction, factorization, euclidean domain
+++ References:
+++ Description:
+++ The package \spadtype{PartialFractionPackage} gives an easier
+++ to use interfact the domain \spadtype{PartialFraction}.
+++ The user gives a fraction of polynomials, and a variable and
+++ the package converts it to the proper datatype for the
+++ \spadtype{PartialFraction} domain.
+
+PartialFractionPackage(R): Cat == Capsule where
+-- R : UniqueFactorizationDomain -- not yet supported
+ R : Join(EuclideanDomain, CharacteristicZero)
+ FPR ==> Fraction Polynomial R
+ INDE ==> IndexedExponents Symbol
+ PR ==> Polynomial R
+ SUP ==> SparseUnivariatePolynomial
+ Cat == with
+ partialFraction: (FPR, Symbol) -> Any
+ ++ partialFraction(rf, var) returns the partial fraction decomposition
+ ++ of the rational function rf with respect to the variable var.
+ partialFraction: (PR, Factored PR, Symbol) -> Any
+ ++ partialFraction(num, facdenom, var) returns the partial fraction
+ ++ decomposition of the rational function whose numerator is num and
+ ++ whose factored denominator is facdenom with respect to the variable var.
+ Capsule == add
+ partialFraction(rf, v) ==
+ df := factor(denom rf)$MultivariateFactorize(Symbol, INDE,R,PR)
+ partialFraction(numer rf, df, v)
+
+ makeSup(p:Polynomial R, v:Symbol) : SparseUnivariatePolynomial FPR ==
+ up := univariate(p,v)
+ map(#1::FPR,up)$UnivariatePolynomialCategoryFunctions2(PR, SUP PR, FPR, SUP FPR)
+
+ partialFraction(p, facq, v) ==
+ up := UnivariatePolynomial(v, Fraction Polynomial R)
+ fup := Factored up
+ ffact : List(Record(irr:up,pow:Integer))
+ ffact:=[[makeSup(u.factor,v) pretend up,u.exponent]
+ for u in factors facq]
+ fcont:=makeSup(unit facq,v) pretend up
+ nflist:fup := fcont*(*/[primeFactor(ff.irr,ff.pow) for ff in ffact])
+ pfup:=partialFraction(makeSup(p,v) pretend up, nflist)$PartialFraction(up)
+ coerce(pfup)$AnyFunctions1(PartialFraction up)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PFR PartialFraction>>
+<<package PFRPAC PartialFractionPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pgcd.spad.pamphlet b/src/algebra/pgcd.spad.pamphlet
new file mode 100644
index 00000000..8cee7ec0
--- /dev/null
+++ b/src/algebra/pgcd.spad.pamphlet
@@ -0,0 +1,458 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pgcd.spad}
+\author{Michael Lucks, Patrizia Gianni, Barry Trager, Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PGCD PolynomialGcdPackage}
+\subsection{failure case in gcdPrimitive(p1:SUPP,p2:SUPP) : SUPP}
+Barry Trager has discovered and fixed a bug in pgcd.spad which occasionally
+(depending on choices of random substitutions) could return the
+wrong gcd. The fix is simply to comment out one line in
+$gcdPrimitive$ which was causing the division test to be skipped.
+The line used to read:
+\begin{verbatim}
+ degree result=d1 => result
+\end{verbatim}
+but has now been removed.
+<<bmtfix>>=
+@
+
+<<package PGCD PolynomialGcdPackage>>=
+)abbrev package PGCD PolynomialGcdPackage
+++ Author: Michael Lucks, P. Gianni
+++ Date Created:
+++ Date Last Updated: 17 June 1996
+++ Fix History: Moved unitCanonicals for performance (BMT);
+++ Fixed a problem with gcd(x,0) (Frederic Lehobey)
+++ Basic Functions: gcd, content
+++ Related Constructors: Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package computes multivariate polynomial gcd's using
+++ a hensel lifting strategy. The contraint on the coefficient
+++ domain is imposed by the lifting strategy. It is assumed that
+++ the coefficient domain has the property that almost all specializations
+++ preserve the degree of the gcd.
+
+I ==> Integer
+NNI ==> NonNegativeInteger
+PI ==> PositiveInteger
+
+PolynomialGcdPackage(E,OV,R,P):C == T where
+ R : EuclideanDomain
+ P : PolynomialCategory(R,E,OV)
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+
+ SUPP ==> SparseUnivariatePolynomial P
+
+ C == with
+ gcd : (P,P) -> P
+ ++ gcd(p,q) computes the gcd of the two polynomials p and q.
+ gcd : List P -> P
+ ++ gcd(lp) computes the gcd of the list of polynomials lp.
+ gcd : (SUPP,SUPP) -> SUPP
+ ++ gcd(p,q) computes the gcd of the two polynomials p and q.
+ gcd : List SUPP -> SUPP
+ ++ gcd(lp) computes the gcd of the list of polynomials lp.
+ gcdPrimitive : (P,P) -> P
+ ++ gcdPrimitive(p,q) computes the gcd of the primitive polynomials
+ ++ p and q.
+ gcdPrimitive : (SUPP,SUPP) -> SUPP
+ ++ gcdPrimitive(p,q) computes the gcd of the primitive polynomials
+ ++ p and q.
+ gcdPrimitive : List P -> P
+ ++ gcdPrimitive lp computes the gcd of the list of primitive
+ ++ polynomials lp.
+
+ T == add
+
+ SUP ==> SparseUnivariatePolynomial R
+
+ LGcd ==> Record(locgcd:SUPP,goodint:List List R)
+ UTerm ==> Record(lpol:List SUP,lint:List List R,mpol:SUPP)
+ pmod:R := (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
+
+ import MultivariateLifting(E,OV,R,P)
+ import FactoringUtilities(E,OV,R,P)
+
+ -------- Local Functions --------
+
+ myran : Integer -> Union(R,"failed")
+ better : (P,P) -> Boolean
+ failtest : (SUPP,SUPP,SUPP) -> Boolean
+ monomContent : (SUPP) -> SUPP
+ gcdMonom : (SUPP,SUPP) -> SUPP
+ gcdTermList : (P,P) -> P
+ good : (SUPP,List OV,List List R) -> Record(upol:SUP,inval:List List R)
+
+ chooseVal : (SUPP,SUPP,List OV,List List R) -> Union(UTerm,"failed")
+ localgcd : (SUPP,SUPP,List OV,List List R) -> LGcd
+ notCoprime : (SUPP,SUPP, List NNI,List OV,List List R) -> SUPP
+ imposelc : (List SUP,List OV,List R,List P) -> List SUP
+
+ lift? :(SUPP,SUPP,UTerm,List NNI,List OV) -> Union(s:SUPP,failed:"failed",notCoprime:"notCoprime")
+ lift :(SUPP,SUP,SUP,P,List OV,List NNI,List R) -> Union(SUPP,"failed")
+
+ ---- Local functions ----
+ -- test if something wrong happened in the gcd
+ failtest(f:SUPP,p1:SUPP,p2:SUPP) : Boolean ==
+ (p1 exquo f) case "failed" or (p2 exquo f) case "failed"
+
+ -- Choose the integers
+ chooseVal(p1:SUPP,p2:SUPP,lvr:List OV,ltry:List List R):Union(UTerm,"failed") ==
+ d1:=degree(p1)
+ d2:=degree(p2)
+ dd:NNI:=0$NNI
+ nvr:NNI:=#lvr
+ lval:List R :=[]
+ range:I:=8
+ repeat
+ range:=2*range
+ lval:=[ran(range) for i in 1..nvr]
+ member?(lval,ltry) => "new point"
+ ltry:=cons(lval,ltry)
+ uf1:SUP:=completeEval(p1,lvr,lval)
+ degree uf1 ^= d1 => "new point"
+ uf2:SUP:= completeEval(p2,lvr,lval)
+ degree uf2 ^= d2 => "new point"
+ u:=gcd(uf1,uf2)
+ du:=degree u
+ --the univariate gcd is 1
+ if du=0 then return [[1$SUP],ltry,0$SUPP]$UTerm
+
+ ugcd:List SUP:=[u,(uf1 exquo u)::SUP,(uf2 exquo u)::SUP]
+ uterm:=[ugcd,ltry,0$SUPP]$UTerm
+ dd=0 => dd:=du
+
+ --the degree is not changed
+ du=dd =>
+
+ --test if one of the polynomials is the gcd
+ dd=d1 =>
+ if ^((f:=p2 exquo p1) case "failed") then
+ return [[u],ltry,p1]$UTerm
+ if dd^=d2 then dd:=(dd-1)::NNI
+
+ dd=d2 =>
+ if ^((f:=p1 exquo p2) case "failed") then
+ return [[u],ltry,p2]$UTerm
+ dd:=(dd-1)::NNI
+ return uterm
+
+ --the new gcd has degree less
+ du<dd => dd:=du
+
+ good(f:SUPP,lvr:List OV,ltry:List List R):Record(upol:SUP,inval:List List R) ==
+ nvr:NNI:=#lvr
+ range:I:=1
+ while true repeat
+ range:=2*range
+ lval:=[ran(range) for i in 1..nvr]
+ member?(lval,ltry) => "new point"
+ ltry:=cons(lval,ltry)
+ uf:=completeEval(f,lvr,lval)
+ if degree gcd(uf,differentiate uf)=0 then return [uf,ltry]
+
+ -- impose the right lc
+ imposelc(lipol:List SUP,
+ lvar:List OV,lval:List R,leadc:List P):List SUP ==
+ result:List SUP :=[]
+ for pol in lipol for leadpol in leadc repeat
+ p1:= univariate eval(leadpol,lvar,lval) * pol
+ result:= cons((p1 exquo leadingCoefficient pol)::SUP,result)
+ reverse result
+
+ --Compute the gcd between not coprime polynomials
+ notCoprime(g:SUPP,p2:SUPP,ldeg:List NNI,lvar1:List OV,ltry:List List R) : SUPP ==
+ g1:=gcd(g,differentiate g)
+ l1 := (g exquo g1)::SUPP
+ lg:LGcd:=localgcd(l1,p2,lvar1,ltry)
+ (l,ltry):=(lg.locgcd,lg.goodint)
+ lval:=ltry.first
+ p2l:=(p2 exquo l)::SUPP
+ (gd1,gd2):=(l,l)
+ ul:=completeEval(l,lvar1,lval)
+ dl:=degree ul
+ if degree gcd(ul,differentiate ul) ^=0 then
+ newchoice:=good(l,lvar1,ltry)
+ ul:=newchoice.upol
+ ltry:=newchoice.inval
+ lval:=ltry.first
+ ug1:=completeEval(g1,lvar1,lval)
+ ulist:=[ug1,completeEval(p2l,lvar1,lval)]
+ lcpol:List P:=[leadingCoefficient g1, leadingCoefficient p2]
+ while true repeat
+ d:SUP:=gcd(cons(ul,ulist))
+ if degree d =0 then return gd1
+ lquo:=(ul exquo d)::SUP
+ if degree lquo ^=0 then
+ lgcd:=gcd(cons(leadingCoefficient l,lcpol))
+ (gdl:=lift(l,d,lquo,lgcd,lvar1,ldeg,lval)) case "failed" =>
+ return notCoprime(g,p2,ldeg,lvar1,ltry)
+ l:=gd2:=gdl::SUPP
+ ul:=completeEval(l,lvar1,lval)
+ dl:=degree ul
+ gd1:=gd1*gd2
+ ulist:=[(uf exquo d)::SUP for uf in ulist]
+
+ gcdPrimitive(p1:SUPP,p2:SUPP) : SUPP ==
+ if (d1:=degree(p1)) > (d2:=degree(p2)) then
+ (p1,p2):= (p2,p1)
+ (d1,d2):= (d2,d1)
+ degree p1 = 0 =>
+ p1 = 0 => unitCanonical p2
+ unitCanonical p1
+ lvar:List OV:=sort(#1>#2,setUnion(variables p1,variables p2))
+ empty? lvar =>
+ raisePolynomial(gcd(lowerPolynomial p1,lowerPolynomial p2))
+ (p2 exquo p1) case SUPP => unitCanonical p1
+ ltry:List List R:=empty()
+ totResult:=localgcd(p1,p2,lvar,ltry)
+ result: SUPP:=totResult.locgcd
+ -- special cases
+ result=1 => 1$SUPP
+<<bmtfix>>
+ while failtest(result,p1,p2) repeat
+-- SAY$Lisp "retrying gcd"
+ ltry:=totResult.goodint
+ totResult:=localgcd(p1,p2,lvar,ltry)
+ result:=totResult.locgcd
+ result
+
+ --local function for the gcd : it returns the evaluation point too
+ localgcd(p1:SUPP,p2:SUPP,lvar:List(OV),ltry:List List R) : LGcd ==
+ uterm:=chooseVal(p1,p2,lvar,ltry)::UTerm
+ ltry:=uterm.lint
+ listpol:= uterm.lpol
+ ud:=listpol.first
+ dd:= degree ud
+
+ --the univariate gcd is 1
+ dd=0 => [1$SUPP,ltry]$LGcd
+
+ --one of the polynomials is the gcd
+ dd=degree(p1) or dd=degree(p2) =>
+ [uterm.mpol,ltry]$LGcd
+ ldeg:List NNI:=map(min,degree(p1,lvar),degree(p2,lvar))
+
+ -- if there is a polynomial g s.t. g/gcd and gcd are coprime ...
+ -- I can lift
+ (h:=lift?(p1,p2,uterm,ldeg,lvar)) case notCoprime =>
+ [notCoprime(p1,p2,ldeg,lvar,ltry),ltry]$LGcd
+ h case failed => localgcd(p1,p2,lvar,ltry) -- skip bad values?
+ [h.s,ltry]$LGcd
+
+
+ -- content, internal functions return the poly if it is a monomial
+ monomContent(p:SUPP):SUPP ==
+ degree(p)=0 => 1
+ md:= minimumDegree(p)
+ monomial(gcd sort(better,coefficients p),md)
+
+ -- Ordering for gcd purposes
+ better(p1:P,p2:P):Boolean ==
+ ground? p1 => true
+ ground? p2 => false
+ degree(p1,mainVariable(p1)::OV) < degree(p2,mainVariable(p2)::OV)
+
+ -- Gcd between polynomial p1 and p2 with
+ -- mainVariable p1 < x=mainVariable p2
+ gcdTermList(p1:P,p2:P) : P ==
+ termList:=sort(better,
+ cons(p1,coefficients univariate(p2,(mainVariable p2)::OV)))
+ q:P:=termList.first
+ for term in termList.rest until q = 1$P repeat q:= gcd(q,term)
+ q
+
+ -- Gcd between polynomials with the same mainVariable
+ gcd(p1:SUPP,p2:SUPP): SUPP ==
+ if degree(p1) > degree(p2) then (p1,p2):= (p2,p1)
+ degree p1 = 0 =>
+ p1 = 0 => unitCanonical p2
+ p1 = 1 => unitCanonical p1
+ gcd(leadingCoefficient p1, content p2)::SUPP
+ reductum(p1)=0 => gcdMonom(p1,monomContent p2)
+ c1:= monomContent(p1)
+ reductum(p2)=0 => gcdMonom(c1,p2)
+ c2:= monomContent(p2)
+ p1:= (p1 exquo c1)::SUPP
+ p2:= (p2 exquo c2)::SUPP
+ gcdPrimitive(p1,p2) * gcdMonom(c1,c2)
+
+ -- gcd between 2 monomials
+ gcdMonom(m1:SUPP,m2:SUPP):SUPP ==
+ monomial(gcd(leadingCoefficient(m1),leadingCoefficient(m2)),
+ min(degree(m1),degree(m2)))
+
+
+ --If there is a pol s.t. pol/gcd and gcd are coprime I can lift
+ lift?(p1:SUPP,p2:SUPP,uterm:UTerm,ldeg:List NNI,
+ lvar:List OV) : Union(s:SUPP,failed:"failed",notCoprime:"notCoprime") ==
+ leadpol:Boolean:=false
+ (listpol,lval):=(uterm.lpol,uterm.lint.first)
+ d:=listpol.first
+ listpol:=listpol.rest
+ nolift:Boolean:=true
+ for uf in listpol repeat
+ --note uf and d not necessarily primitive
+ degree gcd(uf,d) =0 => nolift:=false
+ nolift => ["notCoprime"]
+ f:SUPP:=([p1,p2]$List(SUPP)).(position(uf,listpol))
+ lgcd:=gcd(leadingCoefficient p1, leadingCoefficient p2)
+ (l:=lift(f,d,uf,lgcd,lvar,ldeg,lval)) case "failed" => ["failed"]
+ [l :: SUPP]
+
+ -- interface with the general "lifting" function
+ lift(f:SUPP,d:SUP,uf:SUP,lgcd:P,lvar:List OV,
+ ldeg:List NNI,lval:List R):Union(SUPP,"failed") ==
+ leadpol:Boolean:=false
+ lcf:P
+ lcf:=leadingCoefficient f
+ df:=degree f
+ leadlist:List(P):=[]
+
+ if lgcd^=1 then
+ leadpol:=true
+ f:=lgcd*f
+ ldeg:=[n0+n1 for n0 in ldeg for n1 in degree(lgcd,lvar)]
+ lcd:R:=leadingCoefficient d
+ if degree(lgcd)=0 then d:=((retract lgcd) *d exquo lcd)::SUP
+ else d:=(retract(eval(lgcd,lvar,lval)) * d exquo lcd)::SUP
+ uf:=lcd*uf
+ leadlist:=[lgcd,lcf]
+ lg:=imposelc([d,uf],lvar,lval,leadlist)
+ (pl:=lifting(f,lvar,lg,lval,leadlist,ldeg,pmod)) case "failed" =>
+ "failed"
+ plist := pl :: List SUPP
+ (p0:SUPP,p1:SUPP):=(plist.first,plist.2)
+ if completeEval(p0,lvar,lval) ^= lg.first then
+ (p0,p1):=(p1,p0)
+ ^leadpol => p0
+ p0 exquo content(p0)
+
+ -- Gcd for two multivariate polynomials
+ gcd(p1:P,p2:P) : P ==
+ ground? p1 =>
+ p1 := unitCanonical p1
+ p1 = 1$P => p1
+ p1 = 0$P => unitCanonical p2
+ ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
+ gcdTermList(p1,p2)
+ ground? p2 =>
+ p2 := unitCanonical p2
+ p2 = 1$P => p2
+ p2 = 0$P => unitCanonical p1
+ gcdTermList(p2,p1)
+ (p1:= unitCanonical(p1)) = (p2:= unitCanonical(p2)) => p1
+ mv1:= mainVariable(p1)::OV
+ mv2:= mainVariable(p2)::OV
+ mv1 = mv2 => multivariate(gcd(univariate(p1,mv1),
+ univariate(p2,mv1)),mv1)
+ mv1 < mv2 => gcdTermList(p1,p2)
+ gcdTermList(p2,p1)
+
+ -- Gcd for a list of multivariate polynomials
+ gcd(listp:List P) : P ==
+ lf:=sort(better,listp)
+ f:=lf.first
+ for g in lf.rest repeat
+ f:=gcd(f,g)
+ if f=1$P then return f
+ f
+
+ gcd(listp:List SUPP) : SUPP ==
+ lf:=sort(degree(#1)<degree(#2),listp)
+ f:=lf.first
+ for g in lf.rest repeat
+ f:=gcd(f,g)
+ if f=1 then return f
+ f
+
+
+ -- Gcd for primitive polynomials
+ gcdPrimitive(p1:P,p2:P):P ==
+ (p1:= unitCanonical(p1)) = (p2:= unitCanonical(p2)) => p1
+ ground? p1 =>
+ ground? p2 => gcd((retract p1)@R,(retract p2)@R)::P
+ p1 = 0$P => p2
+ 1$P
+ ground? p2 =>
+ p2 = 0$P => p1
+ 1$P
+ mv1:= mainVariable(p1)::OV
+ mv2:= mainVariable(p2)::OV
+ mv1 = mv2 =>
+ md:=min(minimumDegree(p1,mv1),minimumDegree(p2,mv2))
+ mp:=1$P
+ if md>1 then
+ mp:=(mv1::P)**md
+ p1:=(p1 exquo mp)::P
+ p2:=(p2 exquo mp)::P
+ up1 := univariate(p1,mv1)
+ up2 := univariate(p2,mv2)
+ mp*multivariate(gcdPrimitive(up1,up2),mv1)
+ 1$P
+
+ -- Gcd for a list of primitive multivariate polynomials
+ gcdPrimitive(listp:List P) : P ==
+ lf:=sort(better,listp)
+ f:=lf.first
+ for g in lf.rest repeat
+ f:=gcdPrimitive(f,g)
+ if f=1$P then return f
+ f
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PGCD PolynomialGcdPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pgrobner.spad.pamphlet b/src/algebra/pgrobner.spad.pamphlet
new file mode 100644
index 00000000..c90a46df
--- /dev/null
+++ b/src/algebra/pgrobner.spad.pamphlet
@@ -0,0 +1,121 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pgrobner.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PGROEB PolyGroebner}
+<<package PGROEB PolyGroebner>>=
+)abbrev package PGROEB PolyGroebner
+++ Author: P. Gianni
+++ Date Created: Summer 1988
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: GroebnerPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords: groebner basis, polynomial ideals
+++ References:
+++ Description:
+++ Groebner functions for P F
+++ This package is an interface package to the groebner basis
+++ package which allows you to compute groebner bases for polynomials
+++ in either lexicographic ordering or total degree ordering refined
+++ by reverse lex. The input is the ordinary polynomial type which
+++ is internally converted to a type with the required ordering.
+++ The resulting grobner basis is converted back to ordinary polynomials.
+++ The ordering among the variables is controlled by an explicit list
+++ of variables which is passed as a second argument. The coefficient
+++ domain is allowed to be any gcd domain, but the groebner basis is
+++ computed as if the polynomials were over a field.
+
+PolyGroebner(F) : C == T
+
+ where
+ F : GcdDomain
+ NNI ==> NonNegativeInteger
+ P ==> Polynomial F
+ L ==> List
+ E ==> Symbol
+
+ C == with
+ lexGroebner : (L P,L E) -> L P
+ ++ lexGroebner(lp,lv) computes Groebner basis
+ ++ for the list of polynomials lp in lexicographic order.
+ ++ The variables are ordered by their position in the list lv.
+
+ totalGroebner : (L P, L E) -> L P
+ ++ totalGroebner(lp,lv) computes Groebner basis
+ ++ for the list of polynomials lp with the terms
+ ++ ordered first by total degree and then
+ ++ refined by reverse lexicographic ordering.
+ ++ The variables are ordered by their position in the list lv.
+
+ T == add
+ lexGroebner(lp: L P,lv:L E) : L P ==
+ PP:= PolToPol(lv,F)
+ DPoly := DistributedMultivariatePolynomial(lv,F)
+ DP:=DirectProduct(#lv,NNI)
+ OV:=OrderedVariableList lv
+ b:L DPoly:=[pToDmp(pol)$PP for pol in lp]
+ gb:L DPoly :=groebner(b)$GroebnerPackage(F,DP,OV,DPoly)
+ [dmpToP(pp)$PP for pp in gb]
+
+ totalGroebner(lp: L P,lv:L E) : L P ==
+ PP:= PolToPol(lv,F)
+ HDPoly := HomogeneousDistributedMultivariatePolynomial(lv,F)
+ HDP:=HomogeneousDirectProduct(#lv,NNI)
+ OV:=OrderedVariableList lv
+ b:L HDPoly:=[pToHdmp(pol)$PP for pol in lp]
+ gb:=groebner(b)$GroebnerPackage(F,HDP,OV,HDPoly)
+ [hdmpToP(pp)$PP for pp in gb]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PGROEB PolyGroebner>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pinterp.spad.pamphlet b/src/algebra/pinterp.spad.pamphlet
new file mode 100644
index 00000000..d8c1482f
--- /dev/null
+++ b/src/algebra/pinterp.spad.pamphlet
@@ -0,0 +1,111 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pinterp.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PINTERPA PolynomialInterpolationAlgorithms}
+<<package PINTERPA PolynomialInterpolationAlgorithms>>=
+)abbrev package PINTERPA PolynomialInterpolationAlgorithms
+++ Description:
+++ This package exports interpolation algorithms
+PolynomialInterpolationAlgorithms(F, P): Cat == Body where
+ F: Field
+ P: UnivariatePolynomialCategory(F)
+
+ Cat ==> with
+ LagrangeInterpolation: (List F, List F) -> P
+ ++ LagrangeInterpolation(l1,l2) \undocumented
+
+ Body ==> add
+ LagrangeInterpolation(lx, ly) ==
+ #lx ^= #ly =>
+ error "Different number of points and values."
+ ip: P := 0
+ for xi in lx for yi in ly for i in 0.. repeat
+ pp: P := 1
+ xp: F := 1
+ for xj in lx for j in 0.. | i ^= j repeat
+ pp := pp * (monomial(1,1) - monomial(xj,0))
+ xp := xp * (xi - xj)
+ ip := ip + (yi/xp) * pp
+ ip
+
+@
+\section{package PINTERP PolynomialInterpolation}
+<<package PINTERP PolynomialInterpolation>>=
+)abbrev package PINTERP PolynomialInterpolation
+++ Description:
+++ This package exports interpolation algorithms
+PolynomialInterpolation(xx, F): Cat == Body where
+ xx: Symbol
+ F: Field
+ UP ==> UnivariatePolynomial
+ SUP ==> SparseUnivariatePolynomial
+
+ Cat ==> with
+ interpolate: (UP(xx,F), List F, List F) -> UP(xx,F)
+ ++ interpolate(u,lf,lg) \undocumented
+ interpolate: (List F, List F) -> SUP F
+ ++ interpolate(lf,lg) \undocumented
+
+ Body ==> add
+ PIA ==> PolynomialInterpolationAlgorithms
+
+ interpolate(qx, lx, ly) ==
+ px := LagrangeInterpolation(lx, ly)$PIA(F, UP(xx, F))
+ elt(px, qx)
+
+ interpolate(lx, ly) ==
+ LagrangeInterpolation(lx, ly)$PIA(F, SUP F)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PINTERPA PolynomialInterpolationAlgorithms>>
+<<package PINTERP PolynomialInterpolation>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pleqn.spad.pamphlet b/src/algebra/pleqn.spad.pamphlet
new file mode 100644
index 00000000..8b0569f3
--- /dev/null
+++ b/src/algebra/pleqn.spad.pamphlet
@@ -0,0 +1,654 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pleqn.spad}
+\author{William Sit}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\begin{verbatim}
+++ This package completely solves a parametric linear system of equations
+++ by decomposing the set of all parametric values for which the linear
+++ system is consistent into a union of quasi-algebraic sets (which need
+++ not be irredundant, but most of the time is). Each quasi-algebraic
+++ set is described by a list of polynomials that vanish on the set, and
+++ a list of polynomials that vanish at no point of the set.
+++ For each quasi-algebraic set, the solution of the linear system
+++ is given, as a particular solution and a basis of the homogeneous
+++ system.
+++ The parametric linear system should be given in matrix form, with
+++ a coefficient matrix and a right hand side vector. The entries
+++ of the coefficient matrix and right hand side vector should be
+++ polynomials in the parametric variables, over a Euclidean domain
+++ of characteristic zero.
+++
+++ If the system is homogeneous, the right hand side need not be given.
+++ The right hand side can also be replaced by an indeterminate vector,
+++ in which case, the conditions required for consistency will also be
+++ given.
+++
+++ The package has other facilities for saving results to external
+++ files, as well as solving the system for a specified minimum rank.
+++ Altogether there are 12 mode maps for psolve, as explained below.
+
+-- modified to conform with new runtime system 06/04/90
+-- updated with comments for MB, 02/16/94
+-- also cleaned up some unnecessary arguments in regime routine
+--
+-- MB: In order to allow the rhs to be indeterminate, while working
+-- mainly with the parametric variables on the lhs (less number of
+-- variables), certain conversions of internal representation from
+-- GR to Polynomial R and Fraction Polynomial R are done. At the time
+-- of implementation, I thought that this may be more efficient. I
+-- have not done any comparison since that requires rewriting the
+-- package. My own application needs to call this package quite often,
+-- and most computations involves only polynomials in the parametric
+-- variables.
+
+-- The 12 modes of psolve are probably not all necessary. Again, I
+-- was thinking that if there are many regimes and many ranks, then
+-- the output is quite big, and it may be nice to be able to save it
+-- and read the results in later to continue computing rather than
+-- recomputing. Because of the combinatorial nature of the algorithm
+-- (computing all subdeterminants!), it does not take a very big matrix
+-- to get into many regimes. But I now have second thoughts of this
+-- design, since most of the time, the results are just intermediate,
+-- passed to be further processed. On the other hand, there is probably
+-- no penalty in leaving the options as is.
+\end{verbatim}
+\section{package PLEQN ParametricLinearEquations}
+<<package PLEQN ParametricLinearEquations>>=
+)abbrev package PLEQN ParametricLinearEquations
+++ Author: William Sit, spring 89
+ParametricLinearEquations(R,Var,Expon,GR):
+ Declaration == Definition where
+
+ R : Join(EuclideanDomain, CharacteristicZero)
+ -- Warning: does not work if R is a field! because of Fraction R
+ Var : Join(OrderedSet,ConvertibleTo (Symbol))
+ Expon : OrderedAbelianMonoidSup
+ GR : PolynomialCategory(R,Expon,Var)
+ F == Fraction R
+ FILE ==> FileCategory
+ FNAME ==> FileName
+ GB ==> EuclideanGroebnerBasisPackage
+-- GBINTERN ==> GroebnerInternalPackage
+ I ==> Integer
+ L ==> List
+ M ==> Matrix
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ P ==> Polynomial
+ PI ==> PositiveInteger
+ SEG ==> Segment
+ SM ==> SquareMatrix
+ S ==> String
+ V ==> Vector
+ mf ==> MultivariateFactorize(Var,Expon,R,GR)
+ rp ==> GB(R,Expon,Var,GR)
+ gb ==> GB(R,Expon,Var,GR)
+ PR ==> P R
+ GF ==> Fraction PR
+ plift ==> PolynomialCategoryLifting(Expon,Var,R,GR,GF)
+ Inputmode ==> Integer
+ groebner ==> euclideanGroebner
+ redPol ==> euclideanNormalForm
+
+-- MB: The following macros are data structures to store mostly
+-- intermediate results
+-- Rec stores a subdeterminant with corresponding row and column indices
+-- Fgb is a Groebner basis for the ideal generated by the subdeterminants
+-- of a given rank.
+-- Linsys specifies a linearly independent system of a given system
+-- assuming a given rank, using given row and column indices
+-- Linsoln stores the solution to the parametric linear system as a basis
+-- and a particular solution (for a given regime)
+-- Rec2 stores the rank, and a list of subdeterminants of that rank,
+-- and a Groebner basis for the ideal they generate.
+-- Rec3 stores a regime and the corresponding solution; the regime is
+-- given by a list of equations (eqzro) and one inequation (neqzro)
+-- describing the quasi-algebraic set which is the regime; the
+-- additional consistency conditions due to the rhs is given by wcond.
+-- Ranksolns stores a list of regimes and their solutions, and the number
+-- of regimes all together.
+-- Rec8 (temporary) stores a quasi-algebraic set with an indication
+-- whether it is empty (sysok = false) or not (sysok = true).
+
+-- I think psolve should be renamed parametricSolve, or even
+-- parametricLinearSolve. On the other hand, may be just solve will do.
+-- Please feel free to change it to conform with system conventions.
+-- Most psolve routines return a list of regimes and solutions,
+-- except those that output to file when the number of regimes is
+-- returned instead.
+-- This version has been tested on the pc version 1.608 March 13, 1992
+
+ Rec ==> Record(det:GR,rows:L I,cols:L I)
+ Eqns ==> L Rec
+ Fgb ==> L GR -- groebner basis
+ Linsoln ==> Record(partsol:V GF,basis:L V GF)
+ Linsys ==> Record(mat:M GF,vec:L GF,rank:NNI,rows:L I,cols:L I)
+ Rec2 ==> Record(rank:NNI,eqns:Eqns,fgb:Fgb)
+ RankConds ==> L Rec2
+ Rec3 ==> Record(eqzro:L GR, neqzro:L GR,wcond:L PR, bsoln:Linsoln)
+ Ranksolns ==> Record(rgl:L Rec3,rgsz:I)
+ Rec8 ==> Record(sysok:Boolean, z0:L GR, n0:L GR)
+
+
+ Declaration == with
+ psolve: (M GR, L GR) -> L Rec3
+ ++ psolve(c,w) solves c z = w for all possible ranks
+ ++ of the matrix c and given right hand side vector w
+ -- this is mode 1
+ psolve: (M GR, L Symbol) -> L Rec3
+ ++ psolve(c,w) solves c z = w for all possible ranks
+ ++ of the matrix c and indeterminate right hand side w
+ -- this is mode 2
+ psolve: M GR -> L Rec3
+ ++ psolve(c) solves the homogeneous linear system
+ ++ c z = 0 for all possible ranks of the matrix c
+ -- this is mode 3
+ psolve: (M GR, L GR, PI) -> L Rec3
+ ++ psolve(c,w,k) solves c z = w for all possible ranks >= k
+ ++ of the matrix c and given right hand side vector w
+ -- this is mode 4
+ psolve: (M GR, L Symbol, PI) -> L Rec3
+ ++ psolve(c,w,k) solves c z = w for all possible ranks >= k
+ ++ of the matrix c and indeterminate right hand side w
+ -- this is mode 5
+ psolve: (M GR, PI) -> L Rec3
+ ++ psolve(c) solves the homogeneous linear system
+ ++ c z = 0 for all possible ranks >= k of the matrix c
+ -- this is mode 6
+ psolve: (M GR, L GR, S) -> I
+ ++ psolve(c,w,s) solves c z = w for all possible ranks
+ ++ of the matrix c and given right hand side vector w,
+ ++ writes the results to a file named s, and returns the
+ ++ number of regimes
+ -- this is mode 7
+ psolve: (M GR, L Symbol, S) -> I
+ ++ psolve(c,w,s) solves c z = w for all possible ranks
+ ++ of the matrix c and indeterminate right hand side w,
+ ++ writes the results to a file named s, and returns the
+ ++ number of regimes
+ -- this is mode 8
+ psolve: (M GR, S) -> I
+ ++ psolve(c,s) solves c z = 0 for all possible ranks
+ ++ of the matrix c and given right hand side vector w,
+ ++ writes the results to a file named s, and returns the
+ ++ number of regimes
+ -- this is mode 9
+ psolve: (M GR, L GR, PI, S) -> I
+ ++ psolve(c,w,k,s) solves c z = w for all possible ranks >= k
+ ++ of the matrix c and given right hand side w,
+ ++ writes the results to a file named s, and returns the
+ ++ number of regimes
+ -- this is mode 10
+ psolve: (M GR, L Symbol, PI, S) -> I
+ ++ psolve(c,w,k,s) solves c z = w for all possible ranks >= k
+ ++ of the matrix c and indeterminate right hand side w,
+ ++ writes the results to a file named s, and returns the
+ ++ number of regimes
+ -- this is mode 11
+ psolve: (M GR, PI, S) -> I
+ ++ psolve(c,k,s) solves c z = 0 for all possible ranks >= k
+ ++ of the matrix c,
+ ++ writes the results to a file named s, and returns the
+ ++ number of regimes
+ -- this is mode 12
+
+ wrregime : (L Rec3, S) -> I
+ ++ wrregime(l,s) writes a list of regimes to a file named s
+ ++ and returns the number of regimes written
+ rdregime : S -> L Rec3
+ ++ rdregime(s) reads in a list from a file with name s
+
+ -- for internal use only --
+ -- these are exported so my other packages can use them
+
+ bsolve: (M GR, L GF, NNI, S, Inputmode) -> Ranksolns
+ ++ bsolve(c, w, r, s, m) returns a list of regimes and
+ ++ solutions of the system c z = w for ranks at least r;
+ ++ depending on the mode m chosen, it writes the output to
+ ++ a file given by the string s.
+ dmp2rfi: GR -> GF
+ ++ dmp2rfi(p) converts p to target domain
+ dmp2rfi: M GR -> M GF
+ ++ dmp2rfi(m) converts m to target domain
+ dmp2rfi: L GR -> L GF
+ ++ dmp2rfi(l) converts l to target domain
+ se2rfi: L Symbol -> L GF
+ ++ se2rfi(l) converts l to target domain
+ pr2dmp: PR -> GR
+ ++ pr2dmp(p) converts p to target domain
+ hasoln: (Fgb, L GR) -> Rec8
+ ++ hasoln(g, l) tests whether the quasi-algebraic set
+ ++ defined by p = 0 for p in g and q ^= 0 for q in l
+ ++ is empty or not and returns a simplified definition
+ ++ of the quasi-algebraic set
+ -- this is now done in QALGSET package
+ ParCondList: (M GR,NNI) -> RankConds
+ ++ ParCondList(c,r) computes a list of subdeterminants of each
+ ++ rank >= r of the matrix c and returns
+ ++ a groebner basis for the
+ ++ ideal they generate
+ redpps: (Linsoln, Fgb) -> Linsoln
+ ++ redpps(s,g) returns the simplified form of s after reducing
+ ++ modulo a groebner basis g
+
+
+
+-- L O C A L F U N C T I O N S
+
+ B1solve: Linsys -> Linsoln
+ ++ B1solve(s) solves the system (s.mat) z = s.vec
+ ++ for the variables given by the column indices of s.cols
+ ++ in terms of the other variables and the right hand side s.vec
+ ++ by assuming that the rank is s.rank,
+ ++ that the system is consistent, with the linearly
+ ++ independent equations indexed by the given row indices s.rows;
+ ++ the coefficients in s.mat involving parameters are treated as
+ ++ polynomials. B1solve(s) returns a particular solution to the
+ ++ system and a basis of the homogeneous system (s.mat) z = 0.
+ factorset: GR -> L GR
+ ++ factorset(p) returns the set of irreducible factors of p.
+ maxrank: RankConds -> NNI
+ ++ maxrank(r) returns the maximum rank in the list r of regimes
+ minrank: RankConds -> NNI
+ ++ minrank(r) returns the minimum rank in the list r of regimes
+ minset: L L GR -> L L GR
+ ++ minset(sl) returns the sublist of sl consisting of the minimal
+ ++ lists (with respect to inclusion) in the list sl of lists
+ nextSublist: (I, I) -> L L I
+ ++ nextSublist(n,k) returns a list of k-subsets of {1, ..., n}.
+ overset?: (L GR, L L GR) -> Boolean
+ ++ overset?(s,sl) returns true if s properly a sublist of a member
+ ++ of sl; otherwise it returns false
+ ParCond : (M GR,NNI) -> Eqns
+ ++ ParCond(m,k) returns the list of all k by k subdeterminants in
+ ++ the matrix m
+ redmat: (M GR, Fgb) -> M GR
+ ++ redmat(m,g) returns a matrix whose entries are those of m
+ ++ modulo the ideal generated by the groebner basis g
+ regime: (Rec,M GR,L GF,L L GR,NNI,NNI,Inputmode) -> Rec3
+ ++ regime(y,c, w, p, r, rm, m) returns a regime,
+ ++ a list of polynomials specifying the consistency conditions,
+ ++ a particular solution and basis representing the general
+ ++ solution of the parametric linear system c z = w
+ ++ on that regime. The regime returned depends on
+ ++ the subdeterminant y.det and the row and column indices.
+ ++ The solutions are simplified using the assumption that
+ ++ the system has rank r and maximum rank rm. The list p
+ ++ represents a list of list of factors of polynomials in
+ ++ a groebner basis of the ideal generated by higher order
+ ++ subdeterminants, and ius used for the simplification.
+ ++ The mode m
+ ++ distinguishes the cases when the system is homogeneous,
+ ++ or the right hand side is arbitrary, or when there is no
+ ++ new right hand side variables.
+ sqfree: GR -> GR
+ ++ sqfree(p) returns the product of square free factors of p
+ inconsistent?: L GR -> Boolean
+ ++ inconsistant?(pl) returns true if the system of equations
+ ++ p = 0 for p in pl is inconsistent. It is assumed
+ ++ that pl is a groebner basis.
+ -- this is needed because of change to
+ -- EuclideanGroebnerBasisPackage
+ inconsistent?: L PR -> Boolean
+ ++ inconsistant?(pl) returns true if the system of equations
+ ++ p = 0 for p in pl is inconsistent. It is assumed
+ ++ that pl is a groebner basis.
+ -- this is needed because of change to
+ -- EuclideanGroebnerBasisPackage
+
+ Definition == add
+
+ inconsistent?(pl:L GR):Boolean ==
+ for p in pl repeat
+ ground? p => return true
+ false
+ inconsistent?(pl:L PR):Boolean ==
+ for p in pl repeat
+ ground? p => return true
+ false
+
+ B1solve (sys:Linsys):Linsoln ==
+ i,j,i1,j1:I
+ rss:L I:=sys.rows
+ nss:L I:=sys.cols
+ k:=sys.rank
+ cmat:M GF:=sys.mat
+ n:=ncols cmat
+ frcols:L I:=setDifference$(L I) (expand$(SEG I) (1..n), nss)
+ w:L GF:=sys.vec
+ p:V GF:=new(n,0)
+ pbas:L V GF:=[]
+ if k ^= 0 then
+ augmat:M GF:=zero(k,n+1)
+ for i in rss for i1 in 1.. repeat
+ for j in nss for j1 in 1.. repeat
+ augmat(i1,j1):=cmat(i,j)
+ for j in frcols for j1 in k+1.. repeat
+ augmat(i1,j1):=-cmat(i,j)
+ augmat(i1,n+1):=w.i
+ augmat:=rowEchelon$(M GF) augmat
+ for i in nss for i1 in 1.. repeat p.i:=augmat(i1,n+1)
+ for j in frcols for j1 in k+1.. repeat
+ pb:V GF:=new(n,0)
+ pb.j:=1
+ for i in nss for i1 in 1.. repeat
+ pb.i:=augmat(i1,j1)
+ pbas:=cons(pb,pbas)
+ else
+ for j in frcols for j1 in k+1.. repeat
+ pb:V GF:=new(n,0)
+ pb.j:=1
+ pbas:=cons(pb,pbas)
+ [p,pbas]
+
+ regime (y, coef, w, psbf, rk, rkmax, mode) ==
+ i,j:I
+ -- use the y.det nonzero to simplify the groebner basis
+ -- of ideal generated by higher order subdeterminants
+ ydetf:L GR:=factorset y.det
+ yzero:L GR:=
+ rk = rkmax => nil$(L GR)
+ psbf:=[setDifference(x, ydetf) for x in psbf]
+ groebner$gb [*/x for x in psbf]
+ -- simplify coefficients by modulo ideal
+ nc:M GF:=dmp2rfi redmat(coef,yzero)
+ -- solve the system
+ rss:L I:=y.rows; nss:L I :=y.cols
+ sys:Linsys:=[nc,w,rk,rss,nss]$Linsys
+ pps:= B1solve(sys)
+ pp:=pps.partsol
+ frows:L I:=setDifference$(L I) (expand$(SEG I) (1..nrows coef),rss)
+ wcd:L PR:= []
+ -- case homogeneous rhs
+ entry? (mode, [3,6,9,12]$(L I)) =>
+ [yzero, ydetf,wcd, redpps(pps, yzero)]$Rec3
+ -- case arbitrary rhs, pps not reduced
+ for i in frows repeat
+ weqn:GF:=+/[nc(i,j)*(pp.j) for j in nss]
+ wnum:PR:=numer$GF (w.i - weqn)
+ wnum = 0 => "trivially satisfied"
+ ground? wnum => return [yzero, ydetf,[1$PR]$(L PR),pps]$Rec3
+ wcd:=cons(wnum,wcd)
+ entry? (mode, [2,5,8,11]$(L I)) => [yzero, ydetf, wcd, pps]$Rec3
+ -- case no new rhs variable
+ if not empty? wcd then _
+ yzero:=removeDuplicates append(yzero,[pr2dmp pw for pw in wcd])
+ test:Rec8:=hasoln (yzero, ydetf)
+ not test.sysok => [test.z0, test.n0, [1$PR]$(L PR), pps]$Rec3
+ [test.z0, test.n0, [], redpps(pps, test.z0)]$Rec3
+
+ bsolve (coeff, w, h, outname, mode) ==
+ r:=nrows coeff
+-- n:=ncols coeff
+ r ^= #w => error "number of rows unequal on lhs and rhs"
+ newfile:FNAME
+ rksoln:File Rec3
+ count:I:=0
+ lrec3:L Rec3:=[]
+ filemode:Boolean:= entry? (mode, [7,8,9,10,11,12]$(L I))
+ if filemode then
+ newfile:=new$FNAME ("",outname,"regime")
+ rksoln:=open$(File Rec3) newfile
+ y:Rec
+ k:NNI
+ rrcl:RankConds:=
+ entry? (mode,[1,2,3,7,8,9]$(L I)) => ParCondList (coeff,0)
+ entry? (mode,[4,5,6,10,11,12]$(L I)) => ParCondList (coeff,h)
+ rkmax:=maxrank rrcl
+ rkmin:=minrank rrcl
+ for k in rkmax-rkmin+1..1 by -1 repeat
+ rk:=rrcl.k.rank
+ pc:Eqns:=rrcl.k.eqns
+ psb:Fgb:= (if rk=rkmax then [] else rrcl.(k+1).fgb)
+ psbf:L L GR:= [factorset x for x in psb]
+ psbf:= minset(psbf)
+ for y in pc repeat
+ rec3:Rec3:= regime (y, coeff, w, psbf, rk, rkmax, mode)
+ inconsistent? rec3.wcond => "incompatible system"
+ if filemode then write_!(rksoln, rec3)
+ else lrec3:= cons(rec3, lrec3)
+ count:=count+1
+ if filemode then close_! rksoln
+ [lrec3, count]$Ranksolns
+
+ factorset y ==
+ ground? y => []
+ [j.factor for j in factors(factor$mf y)]
+
+ ParCondList (mat, h) ==
+ rcl: RankConds:= []
+ ps: L GR:=[]
+ pc:Eqns:=[]
+ npc: Eqns:=[]
+ psbf: Fgb:=[]
+ rc: Rec
+ done: Boolean := false
+ r:=nrows mat
+ n:=ncols mat
+ maxrk:I:=min(r,n)
+ k:NNI
+ for k in min(r,n)..h by -1 until done repeat
+ pc:= ParCond(mat,k)
+ npc:=[]
+ (empty? pc) and (k >= 1) => maxrk:= k - 1
+ if ground? pc.1.det -- only one is sufficient (neqzro = {})
+ then (npc:=pc; done:=true; ps := [1$GR])
+ else
+ zro:L GR:= (if k = maxrk then [] else rcl.1.fgb)
+ covered:Boolean:=false
+ for rc in pc until covered repeat
+ p:GR:= redPol$rp (rc.det, zro)
+ p = 0 => "incompatible or covered subdeterminant"
+ test:=hasoln(zro, [rc.det])
+-- zroideal:=ideal(zro)
+-- inRadical? (p, zroideal) => "incompatible or covered"
+ ^test.sysok => "incompatible or covered"
+-- The next line is WRONG! cannot replace zro by test.z0
+-- zro:=groebner$gb (cons(*/test.n0, test.z0))
+ zro:=groebner$gb (cons(p,zro))
+ npc:=cons(rc,npc)
+ done:= covered:= inconsistent? zro
+ ps:=zro
+ pcl: Rec2:= construct(k,npc,ps)
+ rcl:=cons(pcl,rcl)
+ rcl
+
+ redpps(pps, zz) ==
+ pv:=pps.partsol
+ r:=#pv
+ pb:=pps.basis
+ n:=#pb + 1
+ nummat:M GR:=zero(r,n)
+ denmat:M GR:=zero(r,n)
+ for i in 1..r repeat
+ nummat(i,1):=pr2dmp numer$GF pv.i
+ denmat(i,1):=pr2dmp denom$GF pv.i
+ for j in 2..n repeat
+ for i in 1..r repeat
+ nummat(i,j):=pr2dmp numer$GF (pb.(j-1)).i
+ denmat(i,j):=pr2dmp denom$GF (pb.(j-1)).i
+ nummat:=redmat(nummat, zz)
+ denmat:=redmat(denmat, zz)
+ for i in 1..r repeat
+ pv.i:=(dmp2rfi nummat(i,1))/(dmp2rfi denmat(i,1))
+ for j in 2..n repeat
+ pbj:V GF:=new(r,0)
+ for i in 1..r repeat
+ pbj.i:=(dmp2rfi nummat(i,j))/(dmp2rfi denmat(i,j))
+ pb.(j-1):=pbj
+ [pv, pb]
+
+ dmp2rfi (mat:M GR): M GF ==
+ r:=nrows mat
+ n:=ncols mat
+ nmat:M GF:=zero(r,n)
+ for i in 1..r repeat
+ for j in 1..n repeat
+ nmat(i,j):=dmp2rfi mat(i,j)
+ nmat
+
+ dmp2rfi (vl: L GR):L GF ==
+ [dmp2rfi v for v in vl]
+
+ psolve (mat:M GR, w:L GR): L Rec3 ==
+ bsolve(mat, dmp2rfi w, 1, "nofile", 1).rgl
+ psolve (mat:M GR, w:L Symbol): L Rec3 ==
+ bsolve(mat, se2rfi w, 1, "nofile", 2).rgl
+ psolve (mat:M GR): L Rec3 ==
+ bsolve(mat, [0$GF for i in 1..nrows mat], 1, "nofile", 3).rgl
+
+ psolve (mat:M GR, w:L GR, h:PI): L Rec3 ==
+ bsolve(mat, dmp2rfi w, h::NNI, "nofile", 4).rgl
+ psolve (mat:M GR, w:L Symbol, h:PI): L Rec3 ==
+ bsolve(mat, se2rfi w, h::NNI, "nofile", 5).rgl
+ psolve (mat:M GR, h:PI): L Rec3 ==
+ bsolve(mat, [0$GF for i in 1..nrows mat], h::NNI, "nofile", 6).rgl
+
+ psolve (mat:M GR, w:L GR, outname:S): I ==
+ bsolve(mat, dmp2rfi w, 1, outname, 7).rgsz
+ psolve (mat:M GR, w:L Symbol, outname:S): I ==
+ bsolve(mat, se2rfi w, 1, outname, 8).rgsz
+ psolve (mat:M GR, outname:S): I ==
+ bsolve(mat, [0$GF for i in 1..nrows mat], 1, outname, 9).rgsz
+
+ nextSublist (n,k) ==
+ n <= 0 => []
+ k <= 0 => [ nil$(List Integer) ]
+ k > n => []
+ n = 1 and k = 1 => [[1]]
+ mslist: L L I:=[]
+ for ms in nextSublist(n-1,k-1) repeat
+ mslist:=cons(append(ms,[n]),mslist)
+ append(nextSublist(n-1,k), mslist)
+
+ psolve (mat:M GR, w:L GR, h:PI, outname:S): I ==
+ bsolve(mat, dmp2rfi w, h::NNI, outname, 10).rgsz
+ psolve (mat:M GR, w:L Symbol, h:PI, outname:S): I ==
+ bsolve(mat, se2rfi w, h::NNI, outname, 11).rgsz
+ psolve (mat:M GR, h:PI, outname:S): I ==
+ bsolve(mat,[0$GF for i in 1..nrows mat],h::NNI,outname, 12).rgsz
+
+ hasoln (zro,nzro) ==
+ empty? zro => [true, zro, nzro]
+ zro:=groebner$gb zro
+ inconsistent? zro => [false, zro, nzro]
+ empty? nzro =>[true, zro, nzro]
+ pnzro:GR:=redPol$rp (*/nzro, zro)
+ pnzro = 0 => [false, zro, nzro]
+ nzro:=factorset pnzro
+ psbf:L L GR:= minset [factorset p for p in zro]
+ psbf:= [setDifference(x, nzro) for x in psbf]
+ entry? ([], psbf) => [false, zro, nzro]
+ zro:=groebner$gb [*/x for x in psbf]
+ inconsistent? zro => [false, zro, nzro]
+ nzro:=[redPol$rp (p,zro) for p in nzro]
+ nzro:=[p for p in nzro | ^(ground? p)]
+ [true, zro, nzro]
+
+
+
+ se2rfi w == [coerce$GF monomial$PR (1$PR, wi, 1) for wi in w]
+
+ pr2dmp p ==
+ ground? p => (ground p)::GR
+ algCoerceInteractive(p,PR,GR)$(Lisp) pretend GR
+
+ wrregime (lrec3, outname) ==
+ newfile:FNAME:=new$FNAME ("",outname,"regime")
+ rksoln: File Rec3:=open$(File Rec3) newfile
+ count:I:=0 -- number of distinct regimes
+-- rec3: Rec3
+ for rec3 in lrec3 repeat
+ write_!(rksoln, rec3)
+ count:=count+1
+ close_!(rksoln)
+ count
+
+ dmp2rfi (p:GR):GF ==
+ map$plift ((convert #1)@Symbol::GF, #1::PR::GF, p)
+
+
+ rdregime inname ==
+ infilename:=filename$FNAME ("",inname, "regime")
+ infile: File Rec3:=open$(File Rec3) (infilename, "input")
+ rksoln:L Rec3:=[]
+ rec3:Union(Rec3, "failed"):=readIfCan_!$(File Rec3) (infile)
+ while rec3 case Rec3 repeat
+ rksoln:=cons(rec3::Rec3,rksoln) -- replace : to :: for AIX
+ rec3:=readIfCan_!$(File Rec3) (infile)
+ close_!(infile)
+ rksoln
+
+ maxrank rcl ==
+ empty? rcl => 0
+ "max"/[j.rank for j in rcl]
+
+ minrank rcl ==
+ empty? rcl => 0
+ "min"/[j.rank for j in rcl]
+
+ minset lset ==
+ empty? lset => lset
+ [x for x in lset | ^(overset?(x,lset))]
+
+ sqfree p == */[j.factor for j in factors(squareFree p)]
+
+
+ ParCond (mat, k) ==
+ k = 0 => [[1, [], []]$Rec]
+ j:NNI:=k::NNI
+ DetEqn :Eqns := []
+ r:I:= nrows(mat)
+ n:I:= ncols(mat)
+ k > min(r,n) => error "k exceeds maximum possible rank "
+ found:Boolean:=false
+ for rss in nextSublist(r, k) until found repeat
+ for nss in nextSublist(n, k) until found repeat
+ matsub := mat(rss, nss) pretend SM(j, GR)
+ detmat := determinant(matsub)
+ if detmat ^= 0 then
+ found:= (ground? detmat)
+ detmat:=sqfree detmat
+ neweqn:Rec:=construct(detmat,rss,nss)
+ DetEqn:=cons(neweqn, DetEqn)
+ found => [first DetEqn]$Eqns
+ sort(degree #1.det < degree #2.det, DetEqn)
+
+
+
+ overset?(p,qlist) ==
+ empty? qlist => false
+ or/[(brace$(Set GR) q) <$(Set GR) (brace$(Set GR) p) _
+ for q in qlist]
+
+
+ redmat (mat,psb) ==
+ i,j:I
+ r:=nrows(mat)
+ n:=ncols(mat)
+ newmat: M GR:=zero(r,n)
+ for i in 1..r repeat
+ for j in 1..n repeat
+ p:GR:=mat(i,j)
+ ground? p => newmat(i,j):=p
+ newmat(i,j):=redPol$rp (p,psb)
+ newmat
+
+@
+<<*>>=
+-- See LICENSE.AXIOM for Copyright information
+
+<<package PLEQN ParametricLinearEquations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/plot.spad.pamphlet b/src/algebra/plot.spad.pamphlet
new file mode 100644
index 00000000..ea92ae66
--- /dev/null
+++ b/src/algebra/plot.spad.pamphlet
@@ -0,0 +1,651 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra plot.spad}
+\author{Michael Monagan, Clifton J. Williamson, Jon Steinbach, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PLOT Plot}
+<<domain PLOT Plot>>=
+)abbrev domain PLOT Plot
+++ Author: Michael Monagan (revised by Clifton J. Williamson)
+++ Date Created: Jan 1988
+++ Date Last Updated: 30 Nov 1990 by Jonathan Steinbach
+++ Basic Operations: plot, pointPlot, plotPolar, parametric?, zoom, refine,
+++ tRange, minPoints, setMinPoints, maxPoints, screenResolution, adaptive?,
+++ setAdaptive, numFunEvals, debug
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: plot, function, parametric
+++ References:
+++ Description: The Plot domain supports plotting of functions defined over a
+++ real number system. A real number system is a model for the real
+++ numbers and as such may be an approximation. For example
+++ floating point numbers and infinite continued fractions.
+++ The facilities at this point are limited to 2-dimensional plots
+++ or either a single function or a parametric function.
+Plot(): Exports == Implementation where
+ B ==> Boolean
+ F ==> DoubleFloat
+ I ==> Integer
+ L ==> List
+ N ==> NonNegativeInteger
+ OUT ==> OutputForm
+ P ==> Point F
+ RN ==> Fraction Integer
+ S ==> String
+ SEG ==> Segment
+ R ==> Segment F
+ C ==> Record(source: F -> P,ranges: L R,knots: L F,points: L P)
+
+ Exports ==> PlottablePlaneCurveCategory with
+
+--% function plots
+
+ plot: (F -> F,R) -> %
+ ++ plot(f,a..b) plots the function \spad{f(x)} on the interval \spad{[a,b]}.
+ plot: (F -> F,R,R) -> %
+ ++ plot(f,a..b,c..d) plots the function \spad{f(x)} on the interval
+ ++ \spad{[a,b]}; y-range of \spad{[c,d]} is noted in Plot object.
+
+--% multiple function plots
+
+ plot: (L(F -> F),R) -> %
+ ++ plot([f1,...,fm],a..b) plots the functions \spad{y = f1(x)},...,
+ ++ \spad{y = fm(x)} on the interval \spad{a..b}.
+ plot: (L(F -> F),R,R) -> %
+ ++ plot([f1,...,fm],a..b,c..d) plots the functions \spad{y = f1(x)},...,
+ ++ \spad{y = fm(x)} on the interval \spad{a..b}; y-range of \spad{[c,d]} is
+ ++ noted in Plot object.
+
+--% parametric plots
+
+ plot: (F -> F,F -> F,R) -> %
+ ++ plot(f,g,a..b) plots the parametric curve \spad{x = f(t)}, \spad{y = g(t)}
+ ++ as t ranges over the interval \spad{[a,b]}.
+ plot: (F -> F,F -> F,R,R,R) -> %
+ ++ plot(f,g,a..b,c..d,e..f) plots the parametric curve \spad{x = f(t)},
+ ++ \spad{y = g(t)} as t ranges over the interval \spad{[a,b]}; x-range
+ ++ of \spad{[c,d]} and y-range of \spad{[e,f]} are noted in Plot object.
+
+--% parametric plots
+
+ pointPlot: (F -> P,R) -> %
+ ++ pointPlot(t +-> (f(t),g(t)),a..b) plots the parametric curve
+ ++ \spad{x = f(t)}, \spad{y = g(t)} as t ranges over the interval \spad{[a,b]}.
+ pointPlot: (F -> P,R,R,R) -> %
+ ++ pointPlot(t +-> (f(t),g(t)),a..b,c..d,e..f) plots the parametric
+ ++ curve \spad{x = f(t)}, \spad{y = g(t)} as t ranges over the interval \spad{[a,b]};
+ ++ x-range of \spad{[c,d]} and y-range of \spad{[e,f]} are noted in Plot object.
+
+--% polar plots
+
+ plotPolar: (F -> F,R) -> %
+ ++ plotPolar(f,a..b) plots the polar curve \spad{r = f(theta)} as
+ ++ theta ranges over the interval \spad{[a,b]}; this is the same as
+ ++ the parametric curve \spad{x = f(t) * cos(t)}, \spad{y = f(t) * sin(t)}.
+
+ plotPolar: (F -> F) -> %
+ ++ plotPolar(f) plots the polar curve \spad{r = f(theta)} as theta
+ ++ ranges over the interval \spad{[0,2*%pi]}; this is the same as
+ ++ the parametric curve \spad{x = f(t) * cos(t)}, \spad{y = f(t) * sin(t)}.
+
+ plot: (%,R) -> % -- change the range
+ ++ plot(x,r) \undocumented
+ parametric?: % -> B
+ ++ parametric? determines whether it is a parametric plot?
+
+ zoom: (%,R) -> %
+ ++ zoom(x,r) \undocumented
+ zoom: (%,R,R) -> %
+ ++ zoom(x,r,s) \undocumented
+ refine: (%,R) -> %
+ ++ refine(x,r) \undocumented
+ refine: % -> %
+ ++ refine(p) performs a refinement on the plot p
+
+ tRange: % -> R
+ ++ tRange(p) returns the range of the parameter in a parametric plot p
+
+ minPoints: () -> I
+ ++ minPoints() returns the minimum number of points in a plot
+ setMinPoints: I -> I
+ ++ setMinPoints(i) sets the minimum number of points in a plot to i
+ maxPoints: () -> I
+ ++ maxPoints() returns the maximum number of points in a plot
+ setMaxPoints: I -> I
+ ++ setMaxPoints(i) sets the maximum number of points in a plot to i
+ screenResolution: () -> I
+ ++ screenResolution() returns the screen resolution
+ setScreenResolution: I -> I
+ ++ setScreenResolution(i) sets the screen resolution to i
+ adaptive?: () -> B
+ ++ adaptive?() determines whether plotting be done adaptively
+ setAdaptive: B -> B
+ ++ setAdaptive(true) turns adaptive plotting on
+ ++ \spad{setAdaptive(false)} turns adaptive plotting off
+ numFunEvals: () -> I
+ ++ numFunEvals() returns the number of points computed
+ debug: B -> B
+ ++ debug(true) turns debug mode on
+ ++ \spad{debug(false)} turns debug mode off
+
+ Implementation ==> add
+ import PointPackage(DoubleFloat)
+
+--% local functions
+
+ checkRange : R -> R
+ -- checks that left-hand endpoint is less than right-hand endpoint
+ intersect : (R,R) -> R
+ -- intersection of two intervals
+ union : (R,R) -> R
+ -- union of two intervals
+ join : (L C,I) -> R
+ parametricRange: % -> R
+ select : (L P,P -> F,(F,F) -> F) -> F
+ rangeRefine : (C,R) -> C
+ adaptivePlot : (C,R,R,R,I) -> C
+ basicPlot : (F -> P,R) -> C
+ basicRefine : (C,R) -> C
+ pt : (F,F) -> P
+ Fnan? : F -> Boolean
+ Pnan? : P -> Boolean
+
+--% representation
+
+ Rep := Record( parametric: B, _
+ display: L R, _
+ bounds: L R, _
+ axisLabels: L S, _
+ functions: L C )
+
+--% global constants
+
+ ADAPTIVE: B := true
+ MINPOINTS: I := 49
+ MAXPOINTS: I := 1000
+ NUMFUNEVALS: I := 0
+ SCREENRES: I := 500
+ ANGLEBOUND: F := cos inv (4::F)
+ DEBUG: B := false
+
+ Fnan?(x) == x ~= x
+ Pnan?(x) == any?(Fnan?,x)
+
+--% graphics output
+
+ listBranches plot ==
+ outList : L L P := nil()
+ for curve in plot.functions repeat
+ -- curve is C
+ newl:L P:=nil()
+ for p in curve.points repeat
+ if not Pnan? p then newl:=cons(p,newl)
+ else if not empty? newl then
+ outList := concat(newl:=reverse! newl,outList)
+ newl:=nil()
+ if not empty? newl then outList := concat(newl:=reverse! newl,outList)
+-- print(outList::OutputForm)
+ outList
+
+ checkRange r == (lo r > hi r => error "ranges cannot be negative"; r)
+ intersect(s,t) == checkRange (max(lo s,lo t) .. min(hi s,hi t))
+ union(s,t) == min(lo s,lo t) .. max(hi s,hi t)
+ join(l,i) ==
+ rr := first l
+ u : R :=
+ i = 0 => first(rr.ranges)
+ i = 1 => second(rr.ranges)
+ third(rr.ranges)
+ for r in rest l repeat
+ i = 0 => u := union(u,first(r.ranges))
+ i = 1 => u := union(u,second(r.ranges))
+ u := union(u,third(r.ranges))
+ u
+ parametricRange r == first(r.bounds)
+
+ minPoints() == MINPOINTS
+ setMinPoints n ==
+ if n < 3 then error "three points minimum required"
+ if MAXPOINTS < n then MAXPOINTS := n
+ MINPOINTS := n
+ maxPoints() == MAXPOINTS
+ setMaxPoints n ==
+ if n < 3 then error "three points minimum required"
+ if MINPOINTS > n then MINPOINTS := n
+ MAXPOINTS := n
+ screenResolution() == SCREENRES
+ setScreenResolution n ==
+ if n < 2 then error "buy a new terminal"
+ SCREENRES := n
+ adaptive?() == ADAPTIVE
+ setAdaptive b == ADAPTIVE := b
+ parametric? p == p.parametric
+
+ numFunEvals() == NUMFUNEVALS
+ debug b == DEBUG := b
+
+ xRange plot == second plot.bounds
+ yRange plot == third plot.bounds
+ tRange plot == first plot.bounds
+
+ select(l,f,g) ==
+ m := f first l
+ if Fnan? m then m := 0
+ for p in rest l repeat
+ n := m
+ m := g(m, f p)
+ if Fnan? m then m := n
+ m
+
+ rangeRefine(curve,nRange) ==
+ checkRange nRange; l := lo nRange; h := hi nRange
+ t := curve.knots; p := curve.points; f := curve.source
+ while not null t and first t < l repeat
+ (t := rest t; p := rest p)
+ c: L F := nil(); q: L P := nil()
+ while not null t and (first t) <= h repeat
+ c := concat(first t,c); q := concat(first p,q)
+ t := rest t; p := rest p
+ if null c then return basicPlot(f,nRange)
+ if first c < h then
+ c := concat(h,c)
+ q := concat(f h,q)
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ t := c := reverse_! c; p := q := reverse_! q
+ s := (h-l)/(minPoints()::F-1)
+ if (first t) ^= l then
+ t := c := concat(l,c)
+ p := q := concat(f l,p)
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ while not null rest t repeat
+ n := wholePart((second(t) - first(t))/s)
+ d := (second(t) - first(t))/((n+1)::F)
+ for i in 1..n repeat
+ t.rest := concat(first(t) + d,rest t)
+ p.rest := concat(f second t,rest p)
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ t := rest t; p := rest p
+ t := rest t
+ p := rest p
+ xRange := select(q,xCoord,min) .. select(q,xCoord,max)
+ yRange := select(q,yCoord,min) .. select(q,yCoord,max)
+ [ f, [nRange,xRange,yRange], c, q]
+
+ adaptivePlot(curve,tRange,xRange,yRange,pixelfraction) ==
+ xDiff := hi xRange - lo xRange
+ yDiff := hi yRange - lo yRange
+ xDiff = 0 or yDiff = 0 => curve
+ l := lo tRange; h := hi tRange
+ (tDiff := h-l) = 0 => curve
+-- if (EQL(yDiff, _$NaNvalue$Lisp)$Lisp) then yDiff := 1::F
+ t := curve.knots
+ #t < 3 => curve
+ p := curve.points; f := curve.source
+ minLength:F := 4::F/500::F
+ maxLength:F := 1::F/6::F
+ tLimit := tDiff/(pixelfraction*500)::F
+ while not null t and first t < l repeat (t := rest t; p := rest p)
+ #t < 3 => curve
+ headert := t; headerp := p
+
+ -- jitter the input points
+-- while not null rest rest t repeat
+-- t0 := second(t); t1 := third(t)
+-- jitter := (random()$I) :: F
+-- jitter := sin (jitter)
+-- val := t0 + jitter * (t1-t0)/10::F
+-- t.2 := val; p.2 := f val
+-- t := rest t; p := rest p
+-- t := headert; p := headerp
+
+ st := t; sp := p
+ todot : L L F := nil()
+ todop : L L P := nil()
+ while not null rest rest st repeat
+ todot := concat_!(todot, st)
+ todop := concat_!(todop, sp)
+ st := rest st; sp := rest sp
+ st := headert; sp := headerp
+ todo1 := todot; todo2 := todop
+ n : I := 0
+ while not null todo1 repeat
+ st := first(todo1)
+ t0 := first(st); t1 := second(st); t2 := third(st)
+ if t2 > h then leave
+ t2 - t0 < tLimit =>
+ todo1 := rest todo1
+ todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ sp := first(todo2)
+ x0 := xCoord first(sp); y0 := yCoord first(sp)
+ x1 := xCoord second(sp); y1 := yCoord second(sp)
+ x2 := xCoord third(sp); y2 := yCoord third(sp)
+ a1 := (x1-x0)/xDiff; b1 := (y1-y0)/yDiff
+ a2 := (x2-x1)/xDiff; b2 := (y2-y1)/yDiff
+ s1 := sqrt(a1**2+b1**2); s2 := sqrt(a2**2+b2**2)
+ dp := a1*a2+b1*b2
+
+ s1 < maxLength and s2 < maxLength and _
+ (s1 = 0::F or s2 = 0::F or
+ s1 < minLength and s2 < minLength or _
+ dp/s1/s2 > ANGLEBOUND) =>
+ todo1 := rest todo1
+ todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ if n > MAXPOINTS then leave else n := n + 1
+ st := rest t
+ if not null rest rest st then
+ tm := (t0+t1)/2::F
+ tj := tm
+ t.rest := concat(tj,rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := rest todo1; todo2 := rest todo2
+
+ tm := (t1+t2)/2::F
+ tj := tm
+ t.rest := concat(tj, rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ todo1 := rest todo1
+ todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ else
+ tm := (t0+t1)/2::F
+ tj := tm
+ t.rest := concat(tj,rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+
+ tm := (t1+t2)/2::F
+ tj := tm
+ t.rest := concat(tj, rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ todo1 := rest todo1
+ todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ n > 0 =>
+ NUMFUNEVALS := NUMFUNEVALS + n
+ t := curve.knots; p := curve.points
+ xRange := select(p,xCoord,min) .. select(p,xCoord,max)
+ yRange := select(p,yCoord,min) .. select(p,yCoord,max)
+ [ curve.source, [tRange,xRange,yRange], t, p ]
+ curve
+
+ basicPlot(f,tRange) ==
+ checkRange tRange
+ l := lo tRange
+ h := hi tRange
+ t : L F := list l
+ p : L P := list f l
+ s := (h-l)/(minPoints()-1)::F
+ for i in 2..minPoints()-1 repeat
+ l := l+s
+ t := concat(l,t)
+ p := concat(f l,p)
+ t := reverse_! concat(h,t)
+ p := reverse_! concat(f h,p)
+-- print(p::OutputForm)
+ xRange : R := select(p,xCoord,min) .. select(p,xCoord,max)
+ yRange : R := select(p,yCoord,min) .. select(p,yCoord,max)
+ [ f, [tRange,xRange,yRange], t, p ]
+
+ zoom(p,xRange) ==
+ [p.parametric, [xRange,third(p.display)], p.bounds, _
+ p.axisLabels, p.functions]
+ zoom(p,xRange,yRange) ==
+ [p.parametric, [xRange,yRange], p.bounds, _
+ p.axisLabels, p.functions]
+
+ basicRefine(curve,nRange) ==
+ tRange:R := first curve.ranges
+ -- curve := copy$C curve -- Yet another compiler bug
+ curve: C := [curve.source,curve.ranges,curve.knots,curve.points]
+ t := curve.knots := copy curve.knots
+ p := curve.points := copy curve.points
+ l := lo nRange; h := hi nRange
+ f := curve.source
+ while not null rest t and first t < h repeat
+ second(t) < l => (t := rest t; p := rest p)
+ -- insert new point between t.0 and t.1
+ tm : F := (first(t) + second(t))/2::F
+-- if DEBUG then output$O (tm::E)
+ pm := f tm
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ t.rest := concat(tm,rest t); t := rest rest t
+ p.rest := concat(pm,rest p); p := rest rest p
+ t := curve.knots; p := curve.points
+ xRange := select(p,xCoord,min) .. select(p,xCoord,max)
+ yRange := select(p,yCoord,min) .. select(p,yCoord,max)
+ [ curve.source, [tRange,xRange,yRange], t, p ]
+
+ refine p == refine(p,parametricRange p)
+ refine(p,nRange) ==
+ NUMFUNEVALS := 0
+ tRange := parametricRange p
+ nRange := intersect(tRange,nRange)
+ curves: L C := [basicRefine(c,nRange) for c in p.functions]
+ xRange := join(curves,1); yRange := join(curves,2)
+ if adaptive? then
+ tlimit := if parametric? p then 8 else 1
+ curves := [adaptivePlot(c,nRange,xRange,yRange, _
+ tlimit) for c in curves]
+ xRange := join(curves,1); yRange := join(curves,2)
+-- print(NUMFUNEVALS::OUT)
+ [p.parametric, p.display, [tRange,xRange,yRange], _
+ p.axisLabels, curves ]
+
+ plot(p:%,tRange:R) ==
+ -- re plot p on a new range making use of the points already
+ -- computed if possible
+ NUMFUNEVALS := 0
+ curves: L C := [rangeRefine(c,tRange) for c in p.functions]
+ xRange := join(curves,1); yRange := join(curves,2)
+ if adaptive? then
+ tlimit := if parametric? p then 8 else 1
+ curves := [adaptivePlot(c,tRange,xRange,yRange,tlimit) for c in curves]
+ xRange := join(curves,1); yRange := join(curves,2)
+-- print(NUMFUNEVALS::OUT)
+ [ p.parametric, [xRange,yRange], [tRange,xRange,yRange],
+ p.axisLabels, curves ]
+
+ pt(xx,yy) == point(l : L F := [xx,yy])
+
+ myTrap: (F-> F, F) -> F
+ myTrap(ff:F-> F, f:F):F ==
+ s := trapNumericErrors(ff(f))$Lisp :: Union(F, "failed")
+ s case "failed" => _$NaNvalue$Lisp
+ r:F:=s::F
+ r > max()$F or r < min()$F => _$NaNvalue$Lisp
+ r
+
+ plot(f:F -> F,xRange:R) ==
+ p := basicPlot(pt(#1,myTrap(f,#1)),xRange)
+ r := p.ranges
+ NUMFUNEVALS := minPoints()
+ if adaptive? then
+ p := adaptivePlot(p,first r,second r,third r,1)
+ r := p.ranges
+ [ false, rest r, r, nil(), [ p ] ]
+
+ plot(f:F -> F,xRange:R,yRange:R) ==
+ p := plot(f,xRange)
+ p.display := [xRange,checkRange yRange]
+ p
+
+ plot(f:F -> F,g:F -> F,tRange:R) ==
+ p := basicPlot(pt(myTrap(f,#1),myTrap(g,#1)),tRange)
+ r := p.ranges
+ NUMFUNEVALS := minPoints()
+ if adaptive? then
+ p := adaptivePlot(p,first r,second r,third r,8)
+ r := p.ranges
+ [ true, rest r, r, nil(), [ p ] ]
+
+ plot(f:F -> F,g:F -> F,tRange:R,xRange:R,yRange:R) ==
+ p := plot(f,g,tRange)
+ p.display := [checkRange xRange,checkRange yRange]
+ p
+
+ pointPlot(f:F -> P,tRange:R) ==
+ p := basicPlot(f,tRange)
+ r := p.ranges
+ NUMFUNEVALS := minPoints()
+ if adaptive? then
+ p := adaptivePlot(p,first r,second r,third r,8)
+ r := p.ranges
+ [ true, rest r, r, nil(), [ p ] ]
+
+ pointPlot(f:F -> P,tRange:R,xRange:R,yRange:R) ==
+ p := pointPlot(f,tRange)
+ p.display := [checkRange xRange,checkRange yRange]
+ p
+
+ plot(l:L(F -> F),xRange:R) ==
+ if null l then error "empty list of functions"
+ t: L C := [ basicPlot(pt(#1,myTrap(f,#1)),xRange) for f in l ]
+ yRange := join(t,2)
+ NUMFUNEVALS := # l * minPoints()
+ if adaptive? then
+ t := [adaptivePlot(p,xRange,xRange,yRange,1) _
+ for f in l for p in t]
+ yRange := join(t,2)
+-- print(NUMFUNEVALS::OUT)
+ [false, [xRange,yRange], [xRange,xRange,yRange], nil(), t ]
+
+ plot(l:L(F -> F),xRange:R,yRange:R) ==
+ p := plot(l,xRange)
+ p.display := [xRange,checkRange yRange]
+ p
+
+ plotPolar(f,thetaRange) ==
+ plot(f(#1) * cos(#1),f(#1) * sin(#1),thetaRange)
+
+ plotPolar f == plotPolar(f,segment(0,2*pi()))
+
+--% terminal output
+
+ coerce r ==
+ spaces: OUT := coerce " "
+ xSymbol := "x = " :: OUT
+ ySymbol := "y = " :: OUT
+ tSymbol := "t = " :: OUT
+ plotSymbol := "PLOT" :: OUT
+ tRange := (parametricRange r) :: OUT
+ f : L OUT := nil()
+ for curve in r.functions repeat
+ xRange := second(curve.ranges) :: OUT
+ yRange := third(curve.ranges) :: OUT
+ l : L OUT := [xSymbol,xRange,spaces,ySymbol,yRange]
+ if parametric? r then
+ l := concat_!([tSymbol,tRange,spaces],l)
+ h : OUT := hconcat l
+ l := [p::OUT for p in curve.points]
+ f := concat(vconcat concat(h,l),f)
+ prefix("PLOT" :: OUT, reverse_! f)
+
+@
+\section{package PLOT1 PlotFunctions1}
+<<package PLOT1 PlotFunctions1>>=
+)abbrev package PLOT1 PlotFunctions1
+++ Authors: R.T.M. Bronstein, C.J. Williamson
+++ Date Created: Jan 1989
+++ Date Last Updated: 4 Mar 1990
+++ Basic Operations: plot, plotPolar
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: PlotFunctions1 provides facilities for plotting curves
+++ where functions SF -> SF are specified by giving an expression
+PlotFunctions1(S:ConvertibleTo InputForm): with
+ plot : (S, Symbol, Segment DoubleFloat) -> Plot
+ ++ plot(fcn,x,seg) plots the graph of \spad{y = f(x)} on a interval
+ plot : (S, S, Symbol, Segment DoubleFloat) -> Plot
+ ++ plot(f,g,t,seg) plots the graph of \spad{x = f(t)}, \spad{y = g(t)} as t
+ ++ ranges over an interval.
+ plotPolar : (S, Symbol, Segment DoubleFloat) -> Plot
+ ++ plotPolar(f,theta,seg) plots the graph of \spad{r = f(theta)} as
+ ++ theta ranges over an interval
+ plotPolar : (S, Symbol) -> Plot
+ ++ plotPolar(f,theta) plots the graph of \spad{r = f(theta)} as
+ ++ theta ranges from 0 to 2 pi
+ == add
+ import MakeFloatCompiledFunction(S)
+
+ plot(f, x, xRange) == plot(makeFloatFunction(f, x), xRange)
+ plotPolar(f,theta) == plotPolar(makeFloatFunction(f,theta))
+ plot(f1, f2, t, tRange) ==
+ plot(makeFloatFunction(f1, t), makeFloatFunction(f2, t), tRange)
+ plotPolar(f,theta,thetaRange) ==
+ plotPolar(makeFloatFunction(f,theta),thetaRange)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PLOT Plot>>
+<<package PLOT1 PlotFunctions1>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/plot3d.spad.pamphlet b/src/algebra/plot3d.spad.pamphlet
new file mode 100644
index 00000000..804a1207
--- /dev/null
+++ b/src/algebra/plot3d.spad.pamphlet
@@ -0,0 +1,541 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra plot3d.spad}
+\author{Clifton J. Williamson, Michael Monagan, Jon Steinbach}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PLOT3D Plot3D}
+<<domain PLOT3D Plot3D>>=
+)abbrev domain PLOT3D Plot3D
+++ Author: Clifton J. Williamson based on code by Michael Monagan
+++ Date Created: Jan 1989
+++ Date Last Updated: 22 November 1990 (Jon Steinbach)
+++ Basic Operations: pointPlot, plot, zoom, refine, tRange, tValues,
+++ minPoints3D, setMinPoints3D, maxPoints3D, setMaxPoints3D,
+++ screenResolution3D, setScreenResolution3D, adaptive3D?, setAdaptive3D,
+++ numFunEvals3D, debug3D
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: plot, parametric
+++ References:
+++ Description: Plot3D supports parametric plots defined over a real
+++ number system. A real number system is a model for the real
+++ numbers and as such may be an approximation. For example,
+++ floating point numbers and infinite continued fractions are
+++ real number systems. The facilities at this point are limited
+++ to 3-dimensional parametric plots.
+Plot3D(): Exports == Implementation where
+ B ==> Boolean
+ F ==> DoubleFloat
+ I ==> Integer
+ L ==> List
+ N ==> NonNegativeInteger
+ OUT ==> OutputForm
+ P ==> Point F
+ S ==> String
+ R ==> Segment F
+ O ==> OutputPackage
+ C ==> Record(source: F -> P,ranges: L R, knots: L F, points: L P)
+
+ Exports ==> PlottableSpaceCurveCategory with
+
+ pointPlot: (F -> P,R) -> %
+ ++ pointPlot(f,g,h,a..b) plots {/emx = f(t), y = g(t), z = h(t)} as
+ ++ t ranges over {/em[a,b]}.
+ pointPlot: (F -> P,R,R,R,R) -> %
+ ++ pointPlot(f,x,y,z,w) \undocumented
+ plot: (F -> F,F -> F,F -> F,F -> F,R) -> %
+ ++ plot(f,g,h,a..b) plots {/emx = f(t), y = g(t), z = h(t)} as
+ ++ t ranges over {/em[a,b]}.
+ plot: (F -> F,F -> F,F -> F,F -> F,R,R,R,R) -> %
+ ++ plot(f1,f2,f3,f4,x,y,z,w) \undocumented
+
+ plot: (%,R) -> % -- change the range
+ ++ plot(x,r) \undocumented
+ zoom: (%,R,R,R) -> %
+ ++ zoom(x,r,s,t) \undocumented
+ refine: (%,R) -> %
+ ++ refine(x,r) \undocumented
+ refine: % -> %
+ ++ refine(x) \undocumented
+
+ tRange: % -> R
+ ++ tRange(p) returns the range of the parameter in a parametric plot p.
+ tValues: % -> L L F
+ ++ tValues(p) returns a list of lists of the values of the parameter for
+ ++ which a point is computed, one list for each curve in the plot p.
+
+ minPoints3D: () -> I
+ ++ minPoints3D() returns the minimum number of points in a plot.
+ setMinPoints3D: I -> I
+ ++ setMinPoints3D(i) sets the minimum number of points in a plot to i.
+ maxPoints3D: () -> I
+ ++ maxPoints3D() returns the maximum number of points in a plot.
+ setMaxPoints3D: I -> I
+ ++ setMaxPoints3D(i) sets the maximum number of points in a plot to i.
+ screenResolution3D: () -> I
+ ++ screenResolution3D() returns the screen resolution for a 3d graph.
+ setScreenResolution3D: I -> I
+ ++ setScreenResolution3D(i) sets the screen resolution for a 3d graph to i.
+ adaptive3D?: () -> B
+ ++ adaptive3D?() determines whether plotting be done adaptively.
+ setAdaptive3D: B -> B
+ ++ setAdaptive3D(true) turns adaptive plotting on;
+ ++ setAdaptive3D(false) turns adaptive plotting off.
+ numFunEvals3D: () -> I
+ ++ numFunEvals3D() returns the number of points computed.
+ debug3D: B -> B
+ ++ debug3D(true) turns debug mode on;
+ ++ debug3D(false) turns debug mode off.
+
+ Implementation ==> add
+ import PointPackage(F)
+
+--% local functions
+
+ fourth : L R -> R
+ checkRange : R -> R
+ -- checks that left-hand endpoint is less than right-hand endpoint
+ intersect : (R,R) -> R
+ -- intersection of two intervals
+ union : (R,R) -> R
+ -- union of two intervals
+ join : (L C,I) -> R
+ parametricRange: % -> R
+-- setColor : (P,F) -> F
+ select : (L P,P -> F,(F,F) -> F) -> F
+-- normalizeColor : (P,F,F) -> F
+ rangeRefine : (C,R) -> C
+ adaptivePlot : (C,R,R,R,R,I,I) -> C
+ basicPlot : (F -> P,R) -> C
+ basicRefine : (C,R) -> C
+ point : (F,F,F,F) -> P
+
+--% representation
+
+ Rep := Record( display: L R, _
+ bounds: L R, _
+ screenres: I, _
+ axisLabels: L S, _
+ functions: L C )
+
+--% global constants
+
+ ADAPTIVE : B := true
+ MINPOINTS : I := 49
+ MAXPOINTS : I := 1000
+ NUMFUNEVALS : I := 0
+ SCREENRES : I := 500
+ ANGLEBOUND : F := cos inv (4::F)
+ DEBUG : B := false
+
+ point(xx,yy,zz,col) == point(l : L F := [xx,yy,zz,col])
+
+ fourth list == first rest rest rest list
+
+ checkRange r == (lo r > hi r => error "ranges cannot be negative"; r)
+ intersect(s,t) == checkRange (max(lo s,lo t) .. min(hi s,hi t))
+ union(s:R,t:R) == min(lo s,lo t) .. max(hi s,hi t)
+ join(l,i) ==
+ rr := first l
+ u : R :=
+ i = 0 => first(rr.ranges)
+ i = 1 => second(rr.ranges)
+ i = 2 => third(rr.ranges)
+ fourth(rr.ranges)
+ for r in rest l repeat
+ i = 0 => union(u,first(r.ranges))
+ i = 1 => union(u,second(r.ranges))
+ i = 2 => union(u,third(r.ranges))
+ union(u,fourth(r.ranges))
+ u
+ parametricRange r == first(r.bounds)
+
+ minPoints3D() == MINPOINTS
+ setMinPoints3D n ==
+ if n < 3 then error "three points minimum required"
+ if MAXPOINTS < n then MAXPOINTS := n
+ MINPOINTS := n
+ maxPoints3D() == MAXPOINTS
+ setMaxPoints3D n ==
+ if n < 3 then error "three points minimum required"
+ if MINPOINTS > n then MINPOINTS := n
+ MAXPOINTS := n
+ screenResolution3D() == SCREENRES
+ setScreenResolution3D n ==
+ if n < 2 then error "buy a new terminal"
+ SCREENRES := n
+ adaptive3D?() == ADAPTIVE
+ setAdaptive3D b == ADAPTIVE := b
+
+ numFunEvals3D() == NUMFUNEVALS
+ debug3D b == DEBUG := b
+
+-- setColor(p,c) == p.colNum := c
+
+ xRange plot == second plot.bounds
+ yRange plot == third plot.bounds
+ zRange plot == fourth plot.bounds
+ tRange plot == first plot.bounds
+
+ tValues plot ==
+ outList : L L F := nil()
+ for curve in plot.functions repeat
+ outList := concat(curve.knots,outList)
+ outList
+
+ select(l,f,g) ==
+ m := f first l
+ if (EQL(m, _$NaNvalue$Lisp)$Lisp) then m := 0
+-- for p in rest l repeat m := g(m,fp)
+ for p in rest l repeat
+ fp : F := f p
+ if (EQL(fp, _$NaNvalue$Lisp)$Lisp) then fp := 0
+ m := g(m,fp)
+ m
+
+-- normalizeColor(p,lo,diff) ==
+-- p.colNum := (p.colNum - lo)/diff
+
+ rangeRefine(curve,nRange) ==
+ checkRange nRange; l := lo nRange; h := hi nRange
+ t := curve.knots; p := curve.points; f := curve.source
+ while not null t and first t < l repeat
+ (t := rest t; p := rest p)
+ c : L F := nil(); q : L P := nil()
+ while not null t and first t <= h repeat
+ c := concat(first t,c); q := concat(first p,q)
+ t := rest t; p := rest p
+ if null c then return basicPlot(f,nRange)
+ if first c < h then
+ c := concat(h,c); q := concat(f h,q)
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ t := c := reverse_! c; p := q := reverse_! q
+ s := (h-l)/(MINPOINTS::F-1)
+ if (first t) ^= l then
+ t := c := concat(l,c); p := q := concat(f l,p)
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ while not null rest t repeat
+ n := wholePart((second(t) - first(t))/s)
+ d := (second(t) - first(t))/((n+1)::F)
+ for i in 1..n repeat
+ t.rest := concat(first(t) + d,rest t); t1 := second t
+ p.rest := concat(f t1,rest p)
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ t := rest t; p := rest p
+ t := rest t
+ p := rest p
+ xRange := select(q,xCoord,min) .. select(q,xCoord,max)
+ yRange := select(q,yCoord,min) .. select(q,yCoord,max)
+ zRange := select(q,zCoord,min) .. select(q,zCoord,max)
+-- colorLo := select(q,color,min); colorHi := select(q,color,max)
+-- (diff := colorHi - colorLo) = 0 =>
+-- error "all points are the same color"
+-- map(normalizeColor(#1,colorLo,diff),q)$ListPackage1(P)
+ [f,[nRange,xRange,yRange,zRange],c,q]
+
+
+ adaptivePlot(curve,tRg,xRg,yRg,zRg,pixelfraction,resolution) ==
+ xDiff := hi xRg - lo xRg
+ yDiff := hi yRg - lo yRg
+ zDiff := hi zRg - lo zRg
+-- xDiff = 0 or yDiff = 0 or zDiff = 0 => curve--!! delete this?
+ if xDiff = 0::F then xDiff := 1::F
+ if yDiff = 0::F then yDiff := 1::F
+ if zDiff = 0::F then zDiff := 1::F
+ l := lo tRg; h := hi tRg
+ (tDiff := h-l) = 0 => curve
+ t := curve.knots
+ #t < 3 => curve
+ p := curve.points; f := curve.source
+ minLength:F := 4::F/resolution::F
+ maxLength := 1/4::F
+ tLimit := tDiff/(pixelfraction*resolution)::F
+ while not null t and first t < l repeat (t := rest t; p := rest p)
+ #t < 3 => curve
+ headert := t; headerp := p
+ st := t; sp := p
+ todot : L L F := nil()
+ todop : L L P := nil()
+ while not null rest rest st repeat
+ todot := concat_!(todot, st)
+ todop := concat_!(todop, sp)
+ st := rest st; sp := rest sp
+ st := headert; sp := headerp
+ todo1 := todot; todo2 := todop
+ n : I := 0
+
+ while not null todo1 repeat
+ st := first(todo1)
+ t0 := first(st); t1 := second(st); t2 := third(st)
+ if t2 > h then leave
+ t2 - t0 < tLimit =>
+ todo1 := rest todo1
+ todo2 := rest todo2;
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ sp := first(todo2)
+ x0 := xCoord first(sp); y0 := yCoord first(sp); z0 := zCoord first(sp)
+ x1 := xCoord second(sp); y1 := yCoord second(sp); z1 := zCoord second(sp)
+ x2 := xCoord third(sp); y2 := yCoord third(sp); z2 := zCoord third(sp)
+ a1 := (x1-x0)/xDiff; b1 := (y1-y0)/yDiff; c1 := (z1-z0)/zDiff
+ a2 := (x2-x1)/xDiff; b2 := (y2-y1)/yDiff; c2 := (z2-z1)/zDiff
+ s1 := sqrt(a1**2+b1**2+c1**2); s2 := sqrt(a2**2+b2**2+c2**2)
+ dp := a1*a2+b1*b2+c1*c2
+ s1 < maxLength and s2 < maxLength and _
+ (s1 = 0 or s2 = 0 or
+ s1 < minLength and s2 < minLength or _
+ dp/s1/s2 > ANGLEBOUND) =>
+ todo1 := rest todo1
+ todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ if n = MAXPOINTS then leave else n := n + 1
+ --if DEBUG then
+ --r : L F := [minLength,maxLength,s1,s2,dp/s1/s2,ANGLEBOUND]
+ --output(r::E)$O
+ st := rest t
+ if not null rest rest st then
+ tm := (t0+t1)/2::F
+ tj := tm
+ t.rest := concat(tj,rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := rest todo1; todo2 := rest todo2
+
+ tm := (t1+t2)/2::F
+ tj := tm
+ t.rest := concat(tj, rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ todo1 := rest todo1; todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ else
+ tm := (t0+t1)/2::F
+ tj := tm
+ t.rest := concat(tj,rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ t := rest t; p := rest p
+
+ tm := (t1+t2)/2::F
+ tj := tm
+ t.rest := concat(tj, rest t)
+ p.rest := concat(f tj, rest p)
+ todo1 := concat_!(todo1, t)
+ todo2 := concat_!(todo2, p)
+ todo1 := rest todo1; todo2 := rest todo2
+ if not null todo1 then (t := first(todo1); p := first(todo2))
+ if n > 0 then
+ NUMFUNEVALS := NUMFUNEVALS + n
+ t := curve.knots; p := curve.points
+ xRg := select(p,xCoord,min) .. select(p,xCoord,max)
+ yRg := select(p,yCoord,min) .. select(p,yCoord,max)
+ zRg := select(p,zCoord,min) .. select(p,zCoord,max)
+ [curve.source,[tRg,xRg,yRg,zRg],t,p]
+ else curve
+
+ basicPlot(f,tRange) ==
+ checkRange tRange; l := lo tRange; h := hi tRange
+ t : L F := list l; p : L P := list f l
+ s := (h-l)/(MINPOINTS-1)::F
+ for i in 2..MINPOINTS-1 repeat
+ l := l+s; t := concat(l,t)
+ p := concat(f l,p)
+ t := reverse_! concat(h,t)
+ p := reverse_! concat(f h,p)
+ xRange : R := select(p,xCoord,min) .. select(p,xCoord,max)
+ yRange : R := select(p,yCoord,min) .. select(p,yCoord,max)
+ zRange : R := select(p,zCoord,min) .. select(p,zCoord,max)
+ [f,[tRange,xRange,yRange,zRange],t,p]
+
+ zoom(p,xRange,yRange,zRange) ==
+ [[xRange,yRange,zRange],p.bounds,
+ p.screenres,p.axisLabels,p.functions]
+
+ basicRefine(curve,nRange) ==
+ tRange:R := first curve.ranges
+ -- curve := copy$C curve -- Yet another @#$%^&* compiler bug
+ curve: C := [curve.source,curve.ranges,curve.knots,curve.points]
+ t := curve.knots := copy curve.knots
+ p := curve.points := copy curve.points
+ l := lo nRange; h := hi nRange
+ f := curve.source
+ while not null rest t and first(t) < h repeat
+ second(t) < l => (t := rest t; p := rest p)
+ -- insert new point between t.0 and t.1
+ tm:F := (first(t) + second(t))/2::F
+ -- if DEBUG then output$O (tm::E)
+ pm := f tm
+ NUMFUNEVALS := NUMFUNEVALS + 1
+ t.rest := concat(tm,rest t); t := rest rest t
+ p.rest := concat(pm,rest p); p := rest rest p
+ t := curve.knots; p := curve.points
+ xRange := select(p,xCoord,min) .. select(p,xCoord,max)
+ yRange := select(p,yCoord,min) .. select(p,yCoord,max)
+ zRange := select(p,zCoord,min) .. select(p,zCoord,max)
+ [curve.source,[tRange,xRange,yRange,zRange],t,p]
+
+ refine p == refine(p,parametricRange p)
+ refine(p,nRange) ==
+ NUMFUNEVALS := 0
+ tRange := parametricRange p
+ nRange := intersect(tRange,nRange)
+ curves: L C := [basicRefine(c,nRange) for c in p.functions]
+ xRange := join(curves,1); yRange := join(curves,2)
+ zRange := join(curves,3)
+ scrres := p.screenres
+ if adaptive3D? then
+ tlimit := 8
+ curves := [adaptivePlot(c,nRange,xRange,yRange,zRange, _
+ tlimit,scrres := 2*scrres) for c in curves]
+ xRange := join(curves,1); yRange := join(curves,2)
+ zRange := join(curves,3)
+ [p.display,[tRange,xRange,yRange,zRange], _
+ scrres,p.axisLabels,curves]
+
+ plot(p:%,tRange:R) ==
+ -- re plot p on a new range making use of the points already
+ -- computed if possible
+ NUMFUNEVALS := 0
+ curves: L C := [rangeRefine(c,tRange) for c in p.functions]
+ xRange := join(curves,1); yRange := join(curves,2)
+ zRange := join(curves,3)
+ if adaptive3D? then
+ tlimit := 8
+ curves := [adaptivePlot(c,tRange,xRange,yRange,zRange,tlimit, _
+ p.screenres) for c in curves]
+ xRange := join(curves,1); yRange := join(curves,2)
+ zRange := join(curves,3)
+-- print(NUMFUNEVALS::OUT)
+ [[xRange,yRange,zRange],[tRange,xRange,yRange,zRange],
+ p.screenres,p.axisLabels,curves]
+
+ pointPlot(f:F -> P,tRange:R) ==
+ p := basicPlot(f,tRange)
+ r := p.ranges
+ NUMFUNEVALS := MINPOINTS
+ if adaptive3D? then
+ p := adaptivePlot(p,first r,second r,third r,fourth r,8,SCREENRES)
+-- print(NUMFUNEVALS::OUT)
+-- print(p::OUT)
+ [ rest r, r, SCREENRES, nil(), [ p ] ]
+
+ pointPlot(f:F -> P,tRange:R,xRange:R,yRange:R,zRange:R) ==
+ p := pointPlot(f,tRange)
+ p.display:= [checkRange xRange,checkRange yRange,checkRange zRange]
+ p
+
+ myTrap: (F-> F, F) -> F
+ myTrap(ff:F-> F, f:F):F ==
+ s := trapNumericErrors(ff(f))$Lisp :: Union(F, "failed")
+ if (s) case "failed" then
+ r:F := _$NaNvalue$Lisp
+ else
+ r:F := s
+ r
+
+ plot(f1:F -> F,f2:F -> F,f3:F -> F,col:F -> F,tRange:R) ==
+ p := basicPlot(point(myTrap(f1,#1),myTrap(f2,#1),myTrap(f3,#1),col(#1)),tRange)
+ r := p.ranges
+ NUMFUNEVALS := MINPOINTS
+ if adaptive3D? then
+ p := adaptivePlot(p,first r,second r,third r,fourth r,8,SCREENRES)
+-- print(NUMFUNEVALS::OUT)
+ [ rest r, r, SCREENRES, nil(), [ p ] ]
+
+ plot(f1:F -> F,f2:F -> F,f3:F -> F,col:F -> F,_
+ tRange:R,xRange:R,yRange:R,zRange:R) ==
+ p := plot(f1,f2,f3,col,tRange)
+ p.display:= [checkRange xRange,checkRange yRange,checkRange zRange]
+ p
+
+--% terminal output
+
+ coerce r ==
+ spaces := " " :: OUT
+ xSymbol := "x = " :: OUT; ySymbol := "y = " :: OUT
+ zSymbol := "z = " :: OUT; tSymbol := "t = " :: OUT
+ tRange := (parametricRange r) :: OUT
+ f : L OUT := nil()
+ for curve in r.functions repeat
+ xRange := coerce curve.ranges.1
+ yRange := coerce curve.ranges.2
+ zRange := coerce curve.ranges.3
+ l : L OUT := [xSymbol,xRange,spaces,ySymbol,yRange,_
+ spaces,zSymbol,zRange]
+ l := concat_!([tSymbol,tRange,spaces],l)
+ h : OUT := hconcat l
+ l := [p::OUT for p in curve.points]
+ f := concat(vconcat concat(h,l),f)
+ prefix("PLOT" :: OUT,reverse_! f)
+
+----% graphics output
+
+ listBranches plot ==
+ outList : L L P := nil()
+ for curve in plot.functions repeat
+ outList := concat(curve.points,outList)
+ outList
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PLOT3D Plot3D>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/plottool.spad.pamphlet b/src/algebra/plottool.spad.pamphlet
new file mode 100644
index 00000000..adc528ab
--- /dev/null
+++ b/src/algebra/plottool.spad.pamphlet
@@ -0,0 +1,130 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra plottool.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PLOTTOOL PlotTools}
+<<package PLOTTOOL PlotTools>>=
+)abbrev package PLOTTOOL PlotTools
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package exports plotting tools
+PlotTools(): Exports == Implementation where
+ L ==> List
+-- Pt ==> TwoDimensionalPoint
+ SEG ==> Segment
+ SF ==> DoubleFloat
+ Pt ==> Point(SF)
+ PLOT ==> Plot
+ DROP ==> DrawOption
+ S ==> String
+ VIEW2D ==> TwoDimensionalViewport
+
+ Exports ==> with
+ calcRanges: L L Pt -> L SEG SF
+ ++ calcRanges(l) \undocumented
+
+ Implementation ==> add
+ import GraphicsDefaults
+ import PLOT
+ import TwoDimensionalPlotClipping
+ import DrawOptionFunctions0
+ import ViewportPackage
+ import POINT
+ import PointPackage(SF)
+
+ --%Local functions
+ xRange0: L Pt -> SEG SF
+ xRange: L L Pt -> SEG SF
+ yRange0: L Pt -> SEG SF
+ yRange: L L Pt -> SEG SF
+ drawToScaleRanges: (SEG SF,SEG SF) -> L SEG SF
+
+ drawToScaleRanges(xVals,yVals) ==
+ xDiff := (xHi := hi xVals) - (xLo := lo xVals)
+ yDiff := (yHi := hi yVals) - (yLo := lo yVals)
+ pad := abs(yDiff - xDiff)/2
+ yDiff > xDiff => [segment(xLo - pad,xHi + pad),yVals]
+ [xVals,segment(yLo - pad,yHi + pad)]
+
+ select : (L Pt,Pt -> SF,(SF,SF) -> SF) -> SF
+ select(l,f,g) ==
+ m := f first l
+ for p in rest l repeat m := g(m,f p)
+ m
+
+ xRange0(list:L Pt) == select(list,xCoord,min) .. select(list,xCoord,max)
+ yRange0(list:L Pt) == select(list,yCoord,min) .. select(list,yCoord,max)
+
+ select2: (L L Pt,L Pt -> SF,(SF,SF) -> SF) -> SF
+ select2(l,f,g) ==
+ m := f first l
+ for p in rest l repeat m := g(m,f p)
+ m
+
+ xRange(list:L L Pt) ==
+ select2(list,lo(xRange0(#1)),min) .. select2(list,hi(xRange0(#1)),max)
+
+ yRange(list:L L Pt) ==
+ select2(list,lo(yRange0(#1)),min) .. select2(list,hi(yRange0(#1)),max)
+
+ --%Exported Functions
+ calcRanges(llp) ==
+ drawToScale() => drawToScaleRanges(xRange llp, yRange llp)
+ [xRange llp, yRange llp]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PLOTTOOL PlotTools>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/polset.spad.pamphlet b/src/algebra/polset.spad.pamphlet
new file mode 100644
index 00000000..4e21255d
--- /dev/null
+++ b/src/algebra/polset.spad.pamphlet
@@ -0,0 +1,582 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra polset.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PSETCAT PolynomialSetCategory}
+<<category PSETCAT PolynomialSetCategory>>=
+)abbrev category PSETCAT PolynomialSetCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 04/26/1994
+++ Date Last Updated: 12/15/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ References:
+++ Description: A category for finite subsets of a polynomial ring.
+++ Such a set is only regarded as a set of polynomials and not
+++ identified to the ideal it generates. So two distinct sets may
+++ generate the same the ideal. Furthermore, for \spad{R} being an
+++ integral domain, a set of polynomials may be viewed as a representation
+++ of the ideal it generates in the polynomial ring \spad{(R)^(-1) P},
+++ or the set of its zeros (described for instance by the radical of the
+++ previous ideal, or a split of the associated affine variety) and so on.
+++ So this category provides operations about those different notions.
+++ Version: 2
+
+PolynomialSetCategory(R:Ring, E:OrderedAbelianMonoidSup,_
+ VarSet:OrderedSet, P:RecursivePolynomialCategory(R,E,VarSet)): Category ==
+ Join(SetCategory,Collection(P),CoercibleTo(List(P))) with
+ finiteAggregate
+ retractIfCan : List(P) -> Union($,"failed")
+ ++ \axiom{retractIfCan(lp)} returns an element of the domain whose elements
+ ++ are the members of \axiom{lp} if such an element exists, otherwise
+ ++ \axiom{"failed"} is returned.
+ retract : List(P) -> $
+ ++ \axiom{retract(lp)} returns an element of the domain whose elements
+ ++ are the members of \axiom{lp} if such an element exists, otherwise
+ ++ an error is produced.
+ mvar : $ -> VarSet
+ ++ \axiom{mvar(ps)} returns the main variable of the non constant polynomial
+ ++ with the greatest main variable, if any, else an error is returned.
+ variables : $ -> List VarSet
+ ++ \axiom{variables(ps)} returns the decreasingly sorted list of the
+ ++ variables which are variables of some polynomial in \axiom{ps}.
+ mainVariables : $ -> List VarSet
+ ++ \axiom{mainVariables(ps)} returns the decreasingly sorted list of the
+ ++ variables which are main variables of some polynomial in \axiom{ps}.
+ mainVariable? : (VarSet,$) -> Boolean
+ ++ \axiom{mainVariable?(v,ps)} returns true iff \axiom{v} is the main variable
+ ++ of some polynomial in \axiom{ps}.
+ collectUnder : ($,VarSet) -> $
+ ++ \axiom{collectUnder(ps,v)} returns the set consisting of the
+ ++ polynomials of \axiom{ps} with main variable less than \axiom{v}.
+ collect : ($,VarSet) -> $
+ ++ \axiom{collect(ps,v)} returns the set consisting of the
+ ++ polynomials of \axiom{ps} with \axiom{v} as main variable.
+ collectUpper : ($,VarSet) -> $
+ ++ \axiom{collectUpper(ps,v)} returns the set consisting of the
+ ++ polynomials of \axiom{ps} with main variable greater than \axiom{v}.
+ sort : ($,VarSet) -> Record(under:$,floor:$,upper:$)
+ ++ \axiom{sort(v,ps)} returns \axiom{us,vs,ws} such that \axiom{us}
+ ++ is \axiom{collectUnder(ps,v)}, \axiom{vs} is \axiom{collect(ps,v)}
+ ++ and \axiom{ws} is \axiom{collectUpper(ps,v)}.
+ trivialIdeal?: $ -> Boolean
+ ++ \axiom{trivialIdeal?(ps)} returns true iff \axiom{ps} does
+ ++ not contain non-zero elements.
+ if R has IntegralDomain
+ then
+ roughBase? : $ -> Boolean
+ ++ \axiom{roughBase?(ps)} returns true iff for every pair \axiom{{p,q}}
+ ++ of polynomials in \axiom{ps} their leading monomials are
+ ++ relatively prime.
+ roughSubIdeal? : ($,$) -> Boolean
+ ++ \axiom{roughSubIdeal?(ps1,ps2)} returns true iff it can proved
+ ++ that all polynomials in \axiom{ps1} lie in the ideal generated by
+ ++ \axiom{ps2} in \axiom{\axiom{(R)^(-1) P}} without computing Groebner bases.
+ roughEqualIdeals? : ($,$) -> Boolean
+ ++ \axiom{roughEqualIdeals?(ps1,ps2)} returns true iff it can
+ ++ proved that \axiom{ps1} and \axiom{ps2} generate the same ideal
+ ++ in \axiom{(R)^(-1) P} without computing Groebner bases.
+ roughUnitIdeal? : $ -> Boolean
+ ++ \axiom{roughUnitIdeal?(ps)} returns true iff \axiom{ps} contains some
+ ++ non null element lying in the base ring \axiom{R}.
+ headRemainder : (P,$) -> Record(num:P,den:R)
+ ++ \axiom{headRemainder(a,ps)} returns \axiom{[b,r]} such that the leading
+ ++ monomial of \axiom{b} is reduced in the sense of Groebner bases w.r.t.
+ ++ \axiom{ps} and \axiom{r*a - b} lies in the ideal generated by \axiom{ps}.
+ remainder : (P,$) -> Record(rnum:R,polnum:P,den:R)
+ ++ \axiom{remainder(a,ps)} returns \axiom{[c,b,r]} such that \axiom{b} is fully
+ ++ reduced in the sense of Groebner bases w.r.t. \axiom{ps},
+ ++ \axiom{r*a - c*b} lies in the ideal generated by \axiom{ps}.
+ ++ Furthermore, if \axiom{R} is a gcd-domain, \axiom{b} is primitive.
+ rewriteIdealWithHeadRemainder : (List(P),$) -> List(P)
+ ++ \axiom{rewriteIdealWithHeadRemainder(lp,cs)} returns \axiom{lr} such that
+ ++ the leading monomial of every polynomial in \axiom{lr} is reduced
+ ++ in the sense of Groebner bases w.r.t. \axiom{cs} and \axiom{(lp,cs)}
+ ++ and \axiom{(lr,cs)} generate the same ideal in \axiom{(R)^(-1) P}.
+ rewriteIdealWithRemainder : (List(P),$) -> List(P)
+ ++ \axiom{rewriteIdealWithRemainder(lp,cs)} returns \axiom{lr} such that
+ ++ every polynomial in \axiom{lr} is fully reduced in the sense
+ ++ of Groebner bases w.r.t. \axiom{cs} and \axiom{(lp,cs)} and
+ ++ \axiom{(lr,cs)} generate the same ideal in \axiom{(R)^(-1) P}.
+ triangular? : $ -> Boolean
+ ++ \axiom{triangular?(ps)} returns true iff \axiom{ps} is a triangular set,
+ ++ i.e. two distinct polynomials have distinct main variables
+ ++ and no constant lies in \axiom{ps}.
+
+ add
+
+ NNI ==> NonNegativeInteger
+ B ==> Boolean
+
+ elements: $ -> List(P)
+
+ elements(ps:$):List(P) ==
+ lp : List(P) := members(ps)$$
+
+ variables1(lp:List(P)):(List VarSet) ==
+ lvars : List(List(VarSet)) := [variables(p)$P for p in lp]
+ sort(#1 > #2, removeDuplicates(concat(lvars)$List(VarSet)))
+
+ variables2(lp:List(P)):(List VarSet) ==
+ lvars : List(VarSet) := [mvar(p)$P for p in lp]
+ sort(#1 > #2, removeDuplicates(lvars)$List(VarSet))
+
+ variables (ps:$) ==
+ variables1(elements(ps))
+
+ mainVariables (ps:$) ==
+ variables2(remove(ground?,elements(ps)))
+
+ mainVariable? (v,ps) ==
+ lp : List(P) := remove(ground?,elements(ps))
+ while (not empty? lp) and (not (mvar(first(lp)) = v)) repeat
+ lp := rest lp
+ (not empty? lp)
+
+ collectUnder (ps,v) ==
+ lp : List P := elements(ps)
+ lq : List P := []
+ while (not empty? lp) repeat
+ p := first lp
+ lp := rest lp
+ if (ground?(p)) or (mvar(p) < v)
+ then
+ lq := cons(p,lq)
+ construct(lq)$$
+
+ collectUpper (ps,v) ==
+ lp : List P := elements(ps)
+ lq : List P := []
+ while (not empty? lp) repeat
+ p := first lp
+ lp := rest lp
+ if (not ground?(p)) and (mvar(p) > v)
+ then
+ lq := cons(p,lq)
+ construct(lq)$$
+
+ collect (ps,v) ==
+ lp : List P := elements(ps)
+ lq : List P := []
+ while (not empty? lp) repeat
+ p := first lp
+ lp := rest lp
+ if (not ground?(p)) and (mvar(p) = v)
+ then
+ lq := cons(p,lq)
+ construct(lq)$$
+
+ sort (ps,v) ==
+ lp : List P := elements(ps)
+ us : List P := []
+ vs : List P := []
+ ws : List P := []
+ while (not empty? lp) repeat
+ p := first lp
+ lp := rest lp
+ if (ground?(p)) or (mvar(p) < v)
+ then
+ us := cons(p,us)
+ else
+ if (mvar(p) = v)
+ then
+ vs := cons(p,vs)
+ else
+ ws := cons(p,ws)
+ [construct(us)$$,construct(vs)$$,construct(ws)$$]$Record(under:$,floor:$,upper:$)
+
+ ps1 = ps2 ==
+ {p for p in elements(ps1)} =$(Set P) {p for p in elements(ps2)}
+
+ exactQuo : (R,R) -> R
+
+ localInf? (p:P,q:P):B ==
+ degree(p) <$E degree(q)
+
+ localTriangular? (lp:List(P)):B ==
+ lp := remove(zero?, lp)
+ empty? lp => true
+ any? (ground?, lp) => false
+ lp := sort(mvar(#1)$P > mvar(#2)$P, lp)
+ p,q : P
+ p := first lp
+ lp := rest lp
+ while (not empty? lp) and (mvar(p) > mvar((q := first(lp)))) repeat
+ p := q
+ lp := rest lp
+ empty? lp
+
+ triangular? ps ==
+ localTriangular? elements ps
+
+ trivialIdeal? ps ==
+ empty?(remove(zero?,elements(ps))$(List(P)))$(List(P))
+
+ if R has IntegralDomain
+ then
+
+ roughUnitIdeal? ps ==
+ any?(ground?,remove(zero?,elements(ps))$(List(P)))$(List P)
+
+ relativelyPrimeLeadingMonomials? (p:P,q:P):B ==
+ dp : E := degree(p)
+ dq : E := degree(q)
+ (sup(dp,dq)$E =$E dp +$E dq)@B
+
+ roughBase? ps ==
+ lp := remove(zero?,elements(ps))$(List(P))
+ empty? lp => true
+ rB? : B := true
+ while (not empty? lp) and rB? repeat
+ p := first lp
+ lp := rest lp
+ copylp := lp
+ while (not empty? copylp) and rB? repeat
+ rB? := relativelyPrimeLeadingMonomials?(p,first(copylp))
+ copylp := rest copylp
+ rB?
+
+ roughSubIdeal?(ps1,ps2) ==
+ lp: List(P) := rewriteIdealWithRemainder(elements(ps1),ps2)
+ empty? (remove(zero?,lp))
+
+ roughEqualIdeals? (ps1,ps2) ==
+ ps1 =$$ ps2 => true
+ roughSubIdeal?(ps1,ps2) and roughSubIdeal?(ps2,ps1)
+
+ if (R has GcdDomain) and (VarSet has ConvertibleTo (Symbol))
+ then
+
+ LPR ==> List Polynomial R
+ LS ==> List Symbol
+
+ if R has EuclideanDomain
+ then
+ exactQuo(r:R,s:R):R ==
+ r quo$R s
+ else
+ exactQuo(r:R,s:R):R ==
+ (r exquo$R s)::R
+
+ headRemainder (a,ps) ==
+ lp1 : List(P) := remove(zero?, elements(ps))$(List(P))
+ empty? lp1 => [a,1$R]
+ any?(ground?,lp1) => [reductum(a),1$R]
+ r : R := 1$R
+ lp1 := sort(localInf?, reverse elements(ps))
+ lp2 := lp1
+ e : Union(E, "failed")
+ while (not zero? a) and (not empty? lp2) repeat
+ p := first lp2
+ if ((e:= subtractIfCan(degree(a),degree(p))) case E)
+ then
+ g := gcd((lca := leadingCoefficient(a)),(lcp := leadingCoefficient(p)))$R
+ (lca,lcp) := (exactQuo(lca,g),exactQuo(lcp,g))
+ a := lcp * reductum(a) - monomial(lca, e::E)$P * reductum(p)
+ r := r * lcp
+ lp2 := lp1
+ else
+ lp2 := rest lp2
+ [a,r]
+
+ makeIrreducible! (frac:Record(num:P,den:R)):Record(num:P,den:R) ==
+ g := gcd(frac.den,frac.num)$P
+-- one? g => frac
+ (g = 1) => frac
+ frac.num := exactQuotient!(frac.num,g)
+ frac.den := exactQuo(frac.den,g)
+ frac
+
+ remainder (a,ps) ==
+ hRa := makeIrreducible! headRemainder (a,ps)
+ a := hRa.num
+ r : R := hRa.den
+ zero? a => [1$R,a,r]
+ b : P := monomial(1$R,degree(a))$P
+ c : R := leadingCoefficient(a)
+ while not zero?(a := reductum a) repeat
+ hRa := makeIrreducible! headRemainder (a,ps)
+ a := hRa.num
+ r := r * hRa.den
+ g := gcd(c,(lca := leadingCoefficient(a)))$R
+ b := ((hRa.den) * exactQuo(c,g)) * b + monomial(exactQuo(lca,g),degree(a))$P
+ c := g
+ [c,b,r]
+
+ rewriteIdealWithHeadRemainder(ps,cs) ==
+ trivialIdeal? cs => ps
+ roughUnitIdeal? cs => [0$P]
+ ps := remove(zero?,ps)
+ empty? ps => ps
+ any?(ground?,ps) => [1$P]
+ rs : List P := []
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ p := (headRemainder(p,cs)).num
+ if not zero? p
+ then
+ if ground? p
+ then
+ ps := []
+ rs := [1$P]
+ else
+ primitivePart! p
+ rs := cons(p,rs)
+ removeDuplicates rs
+
+ rewriteIdealWithRemainder(ps,cs) ==
+ trivialIdeal? cs => ps
+ roughUnitIdeal? cs => [0$P]
+ ps := remove(zero?,ps)
+ empty? ps => ps
+ any?(ground?,ps) => [1$P]
+ rs : List P := []
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ p := (remainder(p,cs)).polnum
+ if not zero? p
+ then
+ if ground? p
+ then
+ ps := []
+ rs := [1$P]
+ else
+ rs := cons(unitCanonical(p),rs)
+ removeDuplicates rs
+
+@
+\section{PSETCAT.lsp BOOTSTRAP}
+{\bf PSETCAT} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf PSETCAT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf PSETCAT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<PSETCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |PolynomialSetCategory;CAT| (QUOTE NIL))
+
+(SETQ |PolynomialSetCategory;AL| (QUOTE NIL))
+
+(DEFUN |PolynomialSetCategory| (|&REST| #1=#:G82375 |&AUX| #2=#:G82373) (DSETQ #2# #1#) (LET (#3=#:G82374) (COND ((SETQ #3# (|assoc| (|devaluateList| #2#) |PolynomialSetCategory;AL|)) (CDR #3#)) (T (SETQ |PolynomialSetCategory;AL| (|cons5| (CONS (|devaluateList| #2#) (SETQ #3# (APPLY (FUNCTION |PolynomialSetCategory;|) #2#))) |PolynomialSetCategory;AL|)) #3#))))
+
+(DEFUN |PolynomialSetCategory;| (|t#1| |t#2| |t#3| |t#4|) (PROG (#1=#:G82372) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1| |t#2| |t#3| |t#4|)) (LIST (|devaluate| |t#1|) (|devaluate| |t#2|) (|devaluate| |t#3|) (|devaluate| |t#4|))) (|sublisV| (PAIR (QUOTE (#2=#:G82371)) (LIST (QUOTE (|List| |t#4|)))) (COND (|PolynomialSetCategory;CAT|) ((QUOTE T) (LETT |PolynomialSetCategory;CAT| (|Join| (|SetCategory|) (|Collection| (QUOTE |t#4|)) (|CoercibleTo| (QUOTE #2#)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|retractIfCan| ((|Union| |$| "failed") (|List| |t#4|))) T) ((|retract| (|$| (|List| |t#4|))) T) ((|mvar| (|t#3| |$|)) T) ((|variables| ((|List| |t#3|) |$|)) T) ((|mainVariables| ((|List| |t#3|) |$|)) T) ((|mainVariable?| ((|Boolean|) |t#3| |$|)) T) ((|collectUnder| (|$| |$| |t#3|)) T) ((|collect| (|$| |$| |t#3|)) T) ((|collectUpper| (|$| |$| |t#3|)) T) ((|sort| ((|Record| (|:| |under| |$|) (|:| |floor| |$|) (|:| |upper| |$|)) |$| |t#3|)) T) ((|trivialIdeal?| ((|Boolean|) |$|)) T) ((|roughBase?| ((|Boolean|) |$|)) (|has| |t#1| (|IntegralDomain|))) ((|roughSubIdeal?| ((|Boolean|) |$| |$|)) (|has| |t#1| (|IntegralDomain|))) ((|roughEqualIdeals?| ((|Boolean|) |$| |$|)) (|has| |t#1| (|IntegralDomain|))) ((|roughUnitIdeal?| ((|Boolean|) |$|)) (|has| |t#1| (|IntegralDomain|))) ((|headRemainder| ((|Record| (|:| |num| |t#4|) (|:| |den| |t#1|)) |t#4| |$|)) (|has| |t#1| (|IntegralDomain|))) ((|remainder| ((|Record| (|:| |rnum| |t#1|) (|:| |polnum| |t#4|) (|:| |den| |t#1|)) |t#4| |$|)) (|has| |t#1| (|IntegralDomain|))) ((|rewriteIdealWithHeadRemainder| ((|List| |t#4|) (|List| |t#4|) |$|)) (|has| |t#1| (|IntegralDomain|))) ((|rewriteIdealWithRemainder| ((|List| |t#4|) (|List| |t#4|) |$|)) (|has| |t#1| (|IntegralDomain|))) ((|triangular?| ((|Boolean|) |$|)) (|has| |t#1| (|IntegralDomain|))))) (QUOTE ((|finiteAggregate| T))) (QUOTE ((|Boolean|) (|List| |t#4|) (|List| |t#3|))) NIL)) . #3=(|PolynomialSetCategory|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |PolynomialSetCategory|) (|devaluate| |t#1|) (|devaluate| |t#2|) (|devaluate| |t#3|) (|devaluate| |t#4|)))))))
+@
+\section{PSETCAT-.lsp BOOTSTRAP}
+{\bf PSETCAT-} depends on {\bf PSETCAT}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf PSETCAT-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf PSETCAT-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<PSETCAT-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |PSETCAT-;elements| (|ps| |$|) (PROG (|lp|) (RETURN (LETT |lp| (SPADCALL |ps| (QREFELT |$| 12)) |PSETCAT-;elements|))))
+
+(DEFUN |PSETCAT-;variables1| (|lp| |$|) (PROG (#1=#:G82392 |p| #2=#:G82393 |lvars|) (RETURN (SEQ (LETT |lvars| (PROGN (LETT #1# NIL |PSETCAT-;variables1|) (SEQ (LETT |p| NIL |PSETCAT-;variables1|) (LETT #2# |lp| |PSETCAT-;variables1|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |p| (CAR #2#) |PSETCAT-;variables1|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |p| (QREFELT |$| 14)) #1#) |PSETCAT-;variables1|))) (LETT #2# (CDR #2#) |PSETCAT-;variables1|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |PSETCAT-;variables1|) (EXIT (SPADCALL (CONS (FUNCTION |PSETCAT-;variables1!0|) |$|) (SPADCALL (SPADCALL |lvars| (QREFELT |$| 18)) (QREFELT |$| 19)) (QREFELT |$| 21)))))))
+
+(DEFUN |PSETCAT-;variables1!0| (|#1| |#2| |$|) (SPADCALL |#2| |#1| (QREFELT |$| 16)))
+
+(DEFUN |PSETCAT-;variables2| (|lp| |$|) (PROG (#1=#:G82397 |p| #2=#:G82398 |lvars|) (RETURN (SEQ (LETT |lvars| (PROGN (LETT #1# NIL |PSETCAT-;variables2|) (SEQ (LETT |p| NIL |PSETCAT-;variables2|) (LETT #2# |lp| |PSETCAT-;variables2|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |p| (CAR #2#) |PSETCAT-;variables2|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (SPADCALL |p| (QREFELT |$| 22)) #1#) |PSETCAT-;variables2|))) (LETT #2# (CDR #2#) |PSETCAT-;variables2|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) |PSETCAT-;variables2|) (EXIT (SPADCALL (CONS (FUNCTION |PSETCAT-;variables2!0|) |$|) (SPADCALL |lvars| (QREFELT |$| 19)) (QREFELT |$| 21)))))))
+
+(DEFUN |PSETCAT-;variables2!0| (|#1| |#2| |$|) (SPADCALL |#2| |#1| (QREFELT |$| 16)))
+
+(DEFUN |PSETCAT-;variables;SL;4| (|ps| |$|) (|PSETCAT-;variables1| (|PSETCAT-;elements| |ps| |$|) |$|))
+
+(DEFUN |PSETCAT-;mainVariables;SL;5| (|ps| |$|) (|PSETCAT-;variables2| (SPADCALL (ELT |$| 24) (|PSETCAT-;elements| |ps| |$|) (QREFELT |$| 26)) |$|))
+
+(DEFUN |PSETCAT-;mainVariable?;VarSetSB;6| (|v| |ps| |$|) (PROG (|lp|) (RETURN (SEQ (LETT |lp| (SPADCALL (ELT |$| 24) (|PSETCAT-;elements| |ps| |$|) (QREFELT |$| 26)) |PSETCAT-;mainVariable?;VarSetSB;6|) (SEQ G190 (COND ((NULL (COND ((OR (NULL |lp|) (SPADCALL (SPADCALL (|SPADfirst| |lp|) (QREFELT |$| 22)) |v| (QREFELT |$| 28))) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (EXIT (LETT |lp| (CDR |lp|) |PSETCAT-;mainVariable?;VarSetSB;6|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))))))
+
+(DEFUN |PSETCAT-;collectUnder;SVarSetS;7| (|ps| |v| |$|) (PROG (|p| |lp| |lq|) (RETURN (SEQ (LETT |lp| (|PSETCAT-;elements| |ps| |$|) |PSETCAT-;collectUnder;SVarSetS;7|) (LETT |lq| NIL |PSETCAT-;collectUnder;SVarSetS;7|) (SEQ G190 (COND ((NULL (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |lp|) |PSETCAT-;collectUnder;SVarSetS;7|) (LETT |lp| (CDR |lp|) |PSETCAT-;collectUnder;SVarSetS;7|) (EXIT (COND ((OR (SPADCALL |p| (QREFELT |$| 24)) (SPADCALL (SPADCALL |p| (QREFELT |$| 22)) |v| (QREFELT |$| 16))) (LETT |lq| (CONS |p| |lq|) |PSETCAT-;collectUnder;SVarSetS;7|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |lq| (QREFELT |$| 30)))))))
+
+(DEFUN |PSETCAT-;collectUpper;SVarSetS;8| (|ps| |v| |$|) (PROG (|p| |lp| |lq|) (RETURN (SEQ (LETT |lp| (|PSETCAT-;elements| |ps| |$|) |PSETCAT-;collectUpper;SVarSetS;8|) (LETT |lq| NIL |PSETCAT-;collectUpper;SVarSetS;8|) (SEQ G190 (COND ((NULL (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |lp|) |PSETCAT-;collectUpper;SVarSetS;8|) (LETT |lp| (CDR |lp|) |PSETCAT-;collectUpper;SVarSetS;8|) (EXIT (COND ((NULL (SPADCALL |p| (QREFELT |$| 24))) (COND ((SPADCALL |v| (SPADCALL |p| (QREFELT |$| 22)) (QREFELT |$| 16)) (LETT |lq| (CONS |p| |lq|) |PSETCAT-;collectUpper;SVarSetS;8|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |lq| (QREFELT |$| 30)))))))
+
+(DEFUN |PSETCAT-;collect;SVarSetS;9| (|ps| |v| |$|) (PROG (|p| |lp| |lq|) (RETURN (SEQ (LETT |lp| (|PSETCAT-;elements| |ps| |$|) |PSETCAT-;collect;SVarSetS;9|) (LETT |lq| NIL |PSETCAT-;collect;SVarSetS;9|) (SEQ G190 (COND ((NULL (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |lp|) |PSETCAT-;collect;SVarSetS;9|) (LETT |lp| (CDR |lp|) |PSETCAT-;collect;SVarSetS;9|) (EXIT (COND ((NULL (SPADCALL |p| (QREFELT |$| 24))) (COND ((SPADCALL (SPADCALL |p| (QREFELT |$| 22)) |v| (QREFELT |$| 28)) (LETT |lq| (CONS |p| |lq|) |PSETCAT-;collect;SVarSetS;9|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |lq| (QREFELT |$| 30)))))))
+
+(DEFUN |PSETCAT-;sort;SVarSetR;10| (|ps| |v| |$|) (PROG (|p| |lp| |us| |vs| |ws|) (RETURN (SEQ (LETT |lp| (|PSETCAT-;elements| |ps| |$|) |PSETCAT-;sort;SVarSetR;10|) (LETT |us| NIL |PSETCAT-;sort;SVarSetR;10|) (LETT |vs| NIL |PSETCAT-;sort;SVarSetR;10|) (LETT |ws| NIL |PSETCAT-;sort;SVarSetR;10|) (SEQ G190 (COND ((NULL (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |lp|) |PSETCAT-;sort;SVarSetR;10|) (LETT |lp| (CDR |lp|) |PSETCAT-;sort;SVarSetR;10|) (EXIT (COND ((OR (SPADCALL |p| (QREFELT |$| 24)) (SPADCALL (SPADCALL |p| (QREFELT |$| 22)) |v| (QREFELT |$| 16))) (LETT |us| (CONS |p| |us|) |PSETCAT-;sort;SVarSetR;10|)) ((SPADCALL (SPADCALL |p| (QREFELT |$| 22)) |v| (QREFELT |$| 28)) (LETT |vs| (CONS |p| |vs|) |PSETCAT-;sort;SVarSetR;10|)) ((QUOTE T) (LETT |ws| (CONS |p| |ws|) |PSETCAT-;sort;SVarSetR;10|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (VECTOR (SPADCALL |us| (QREFELT |$| 30)) (SPADCALL |vs| (QREFELT |$| 30)) (SPADCALL |ws| (QREFELT |$| 30))))))))
+
+(DEFUN |PSETCAT-;=;2SB;11| (|ps1| |ps2| |$|) (PROG (#1=#:G82439 #2=#:G82440 #3=#:G82437 |p| #4=#:G82438) (RETURN (SEQ (SPADCALL (SPADCALL (PROGN (LETT #1# NIL |PSETCAT-;=;2SB;11|) (SEQ (LETT |p| NIL |PSETCAT-;=;2SB;11|) (LETT #2# (|PSETCAT-;elements| |ps1| |$|) |PSETCAT-;=;2SB;11|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |p| (CAR #2#) |PSETCAT-;=;2SB;11|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS |p| #1#) |PSETCAT-;=;2SB;11|))) (LETT #2# (CDR #2#) |PSETCAT-;=;2SB;11|) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 37)) (SPADCALL (PROGN (LETT #3# NIL |PSETCAT-;=;2SB;11|) (SEQ (LETT |p| NIL |PSETCAT-;=;2SB;11|) (LETT #4# (|PSETCAT-;elements| |ps2| |$|) |PSETCAT-;=;2SB;11|) G190 (COND ((OR (ATOM #4#) (PROGN (LETT |p| (CAR #4#) |PSETCAT-;=;2SB;11|) NIL)) (GO G191))) (SEQ (EXIT (LETT #3# (CONS |p| #3#) |PSETCAT-;=;2SB;11|))) (LETT #4# (CDR #4#) |PSETCAT-;=;2SB;11|) (GO G190) G191 (EXIT (NREVERSE0 #3#)))) (QREFELT |$| 37)) (QREFELT |$| 38))))))
+
+(DEFUN |PSETCAT-;localInf?| (|p| |q| |$|) (SPADCALL (SPADCALL |p| (QREFELT |$| 40)) (SPADCALL |q| (QREFELT |$| 40)) (QREFELT |$| 41)))
+
+(DEFUN |PSETCAT-;localTriangular?| (|lp| |$|) (PROG (|q| |p|) (RETURN (SEQ (LETT |lp| (SPADCALL (ELT |$| 42) |lp| (QREFELT |$| 26)) |PSETCAT-;localTriangular?|) (EXIT (COND ((NULL |lp|) (QUOTE T)) ((SPADCALL (ELT |$| 24) |lp| (QREFELT |$| 43)) (QUOTE NIL)) ((QUOTE T) (SEQ (LETT |lp| (SPADCALL (CONS (FUNCTION |PSETCAT-;localTriangular?!0|) |$|) |lp| (QREFELT |$| 45)) |PSETCAT-;localTriangular?|) (LETT |p| (|SPADfirst| |lp|) |PSETCAT-;localTriangular?|) (LETT |lp| (CDR |lp|) |PSETCAT-;localTriangular?|) (SEQ G190 (COND ((NULL (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) (SPADCALL (SPADCALL (LETT |q| (|SPADfirst| |lp|) |PSETCAT-;localTriangular?|) (QREFELT |$| 22)) (SPADCALL |p| (QREFELT |$| 22)) (QREFELT |$| 16))))) (GO G191))) (SEQ (LETT |p| |q| |PSETCAT-;localTriangular?|) (EXIT (LETT |lp| (CDR |lp|) |PSETCAT-;localTriangular?|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (NULL |lp|))))))))))
+
+(DEFUN |PSETCAT-;localTriangular?!0| (|#1| |#2| |$|) (SPADCALL (SPADCALL |#2| (QREFELT |$| 22)) (SPADCALL |#1| (QREFELT |$| 22)) (QREFELT |$| 16)))
+
+(DEFUN |PSETCAT-;triangular?;SB;14| (|ps| |$|) (|PSETCAT-;localTriangular?| (|PSETCAT-;elements| |ps| |$|) |$|))
+
+(DEFUN |PSETCAT-;trivialIdeal?;SB;15| (|ps| |$|) (NULL (SPADCALL (ELT |$| 42) (|PSETCAT-;elements| |ps| |$|) (QREFELT |$| 26))))
+
+(DEFUN |PSETCAT-;roughUnitIdeal?;SB;16| (|ps| |$|) (SPADCALL (ELT |$| 24) (SPADCALL (ELT |$| 42) (|PSETCAT-;elements| |ps| |$|) (QREFELT |$| 26)) (QREFELT |$| 43)))
+
+(DEFUN |PSETCAT-;relativelyPrimeLeadingMonomials?| (|p| |q| |$|) (PROG (|dp| |dq|) (RETURN (SEQ (LETT |dp| (SPADCALL |p| (QREFELT |$| 40)) |PSETCAT-;relativelyPrimeLeadingMonomials?|) (LETT |dq| (SPADCALL |q| (QREFELT |$| 40)) |PSETCAT-;relativelyPrimeLeadingMonomials?|) (EXIT (SPADCALL (SPADCALL |dp| |dq| (QREFELT |$| 49)) (SPADCALL |dp| |dq| (QREFELT |$| 50)) (QREFELT |$| 51)))))))
+
+(DEFUN |PSETCAT-;roughBase?;SB;18| (|ps| |$|) (PROG (|p| |lp| |rB?| |copylp|) (RETURN (SEQ (LETT |lp| (SPADCALL (ELT |$| 42) (|PSETCAT-;elements| |ps| |$|) (QREFELT |$| 26)) |PSETCAT-;roughBase?;SB;18|) (EXIT (COND ((NULL |lp|) (QUOTE T)) ((QUOTE T) (SEQ (LETT |rB?| (QUOTE T) |PSETCAT-;roughBase?;SB;18|) (SEQ G190 (COND ((NULL (COND ((NULL |lp|) (QUOTE NIL)) ((QUOTE T) |rB?|))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |lp|) |PSETCAT-;roughBase?;SB;18|) (LETT |lp| (CDR |lp|) |PSETCAT-;roughBase?;SB;18|) (LETT |copylp| |lp| |PSETCAT-;roughBase?;SB;18|) (EXIT (SEQ G190 (COND ((NULL (COND ((NULL |copylp|) (QUOTE NIL)) ((QUOTE T) |rB?|))) (GO G191))) (SEQ (LETT |rB?| (|PSETCAT-;relativelyPrimeLeadingMonomials?| |p| (|SPADfirst| |copylp|) |$|) |PSETCAT-;roughBase?;SB;18|) (EXIT (LETT |copylp| (CDR |copylp|) |PSETCAT-;roughBase?;SB;18|))) NIL (GO G190) G191 (EXIT NIL)))) NIL (GO G190) G191 (EXIT NIL)) (EXIT |rB?|)))))))))
+
+(DEFUN |PSETCAT-;roughSubIdeal?;2SB;19| (|ps1| |ps2| |$|) (PROG (|lp|) (RETURN (SEQ (LETT |lp| (SPADCALL (|PSETCAT-;elements| |ps1| |$|) |ps2| (QREFELT |$| 53)) |PSETCAT-;roughSubIdeal?;2SB;19|) (EXIT (NULL (SPADCALL (ELT |$| 42) |lp| (QREFELT |$| 26))))))))
+
+(DEFUN |PSETCAT-;roughEqualIdeals?;2SB;20| (|ps1| |ps2| |$|) (COND ((SPADCALL |ps1| |ps2| (QREFELT |$| 55)) (QUOTE T)) ((SPADCALL |ps1| |ps2| (QREFELT |$| 56)) (SPADCALL |ps2| |ps1| (QREFELT |$| 56))) ((QUOTE T) (QUOTE NIL))))
+
+(DEFUN |PSETCAT-;exactQuo| (|r| |s| |$|) (SPADCALL |r| |s| (QREFELT |$| 58)))
+
+(DEFUN |PSETCAT-;exactQuo| (|r| |s| |$|) (PROG (#1=#:G82473) (RETURN (PROG2 (LETT #1# (SPADCALL |r| |s| (QREFELT |$| 60)) |PSETCAT-;exactQuo|) (QCDR #1#) (|check-union| (QEQCAR #1# 0) (QREFELT |$| 7) #1#)))))
+
+(DEFUN |PSETCAT-;headRemainder;PSR;23| (|a| |ps| |$|) (PROG (|lp1| |p| |e| |g| |#G47| |#G48| |lca| |lcp| |r| |lp2|) (RETURN (SEQ (LETT |lp1| (SPADCALL (ELT |$| 42) (|PSETCAT-;elements| |ps| |$|) (QREFELT |$| 26)) |PSETCAT-;headRemainder;PSR;23|) (EXIT (COND ((NULL |lp1|) (CONS |a| (|spadConstant| |$| 61))) ((SPADCALL (ELT |$| 24) |lp1| (QREFELT |$| 43)) (CONS (SPADCALL |a| (QREFELT |$| 62)) (|spadConstant| |$| 61))) ((QUOTE T) (SEQ (LETT |r| (|spadConstant| |$| 61) |PSETCAT-;headRemainder;PSR;23|) (LETT |lp1| (SPADCALL (CONS (|function| |PSETCAT-;localInf?|) |$|) (REVERSE (|PSETCAT-;elements| |ps| |$|)) (QREFELT |$| 45)) |PSETCAT-;headRemainder;PSR;23|) (LETT |lp2| |lp1| |PSETCAT-;headRemainder;PSR;23|) (SEQ G190 (COND ((NULL (COND ((OR (SPADCALL |a| (QREFELT |$| 42)) (NULL |lp2|)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |lp2|) |PSETCAT-;headRemainder;PSR;23|) (LETT |e| (SPADCALL (SPADCALL |a| (QREFELT |$| 40)) (SPADCALL |p| (QREFELT |$| 40)) (QREFELT |$| 63)) |PSETCAT-;headRemainder;PSR;23|) (EXIT (COND ((QEQCAR |e| 0) (SEQ (LETT |g| (SPADCALL (LETT |lca| (SPADCALL |a| (QREFELT |$| 64)) |PSETCAT-;headRemainder;PSR;23|) (LETT |lcp| (SPADCALL |p| (QREFELT |$| 64)) |PSETCAT-;headRemainder;PSR;23|) (QREFELT |$| 65)) |PSETCAT-;headRemainder;PSR;23|) (PROGN (LETT |#G47| (|PSETCAT-;exactQuo| |lca| |g| |$|) |PSETCAT-;headRemainder;PSR;23|) (LETT |#G48| (|PSETCAT-;exactQuo| |lcp| |g| |$|) |PSETCAT-;headRemainder;PSR;23|) (LETT |lca| |#G47| |PSETCAT-;headRemainder;PSR;23|) (LETT |lcp| |#G48| |PSETCAT-;headRemainder;PSR;23|)) (LETT |a| (SPADCALL (SPADCALL |lcp| (SPADCALL |a| (QREFELT |$| 62)) (QREFELT |$| 66)) (SPADCALL (SPADCALL |lca| (QCDR |e|) (QREFELT |$| 67)) (SPADCALL |p| (QREFELT |$| 62)) (QREFELT |$| 68)) (QREFELT |$| 69)) |PSETCAT-;headRemainder;PSR;23|) (LETT |r| (SPADCALL |r| |lcp| (QREFELT |$| 70)) |PSETCAT-;headRemainder;PSR;23|) (EXIT (LETT |lp2| |lp1| |PSETCAT-;headRemainder;PSR;23|)))) ((QUOTE T) (LETT |lp2| (CDR |lp2|) |PSETCAT-;headRemainder;PSR;23|))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (CONS |a| |r|))))))))))
+
+(DEFUN |PSETCAT-;makeIrreducible!| (|frac| |$|) (PROG (|g|) (RETURN (SEQ (LETT |g| (SPADCALL (QCDR |frac|) (QCAR |frac|) (QREFELT |$| 73)) |PSETCAT-;makeIrreducible!|) (EXIT (COND ((SPADCALL |g| (QREFELT |$| 74)) |frac|) ((QUOTE T) (SEQ (PROGN (RPLACA |frac| (SPADCALL (QCAR |frac|) |g| (QREFELT |$| 75))) (QCAR |frac|)) (PROGN (RPLACD |frac| (|PSETCAT-;exactQuo| (QCDR |frac|) |g| |$|)) (QCDR |frac|)) (EXIT |frac|)))))))))
+
+(DEFUN |PSETCAT-;remainder;PSR;25| (|a| |ps| |$|) (PROG (|hRa| |r| |lca| |g| |b| |c|) (RETURN (SEQ (LETT |hRa| (|PSETCAT-;makeIrreducible!| (SPADCALL |a| |ps| (QREFELT |$| 76)) |$|) |PSETCAT-;remainder;PSR;25|) (LETT |a| (QCAR |hRa|) |PSETCAT-;remainder;PSR;25|) (LETT |r| (QCDR |hRa|) |PSETCAT-;remainder;PSR;25|) (EXIT (COND ((SPADCALL |a| (QREFELT |$| 42)) (VECTOR (|spadConstant| |$| 61) |a| |r|)) ((QUOTE T) (SEQ (LETT |b| (SPADCALL (|spadConstant| |$| 61) (SPADCALL |a| (QREFELT |$| 40)) (QREFELT |$| 67)) |PSETCAT-;remainder;PSR;25|) (LETT |c| (SPADCALL |a| (QREFELT |$| 64)) |PSETCAT-;remainder;PSR;25|) (SEQ G190 (COND ((NULL (COND ((SPADCALL (LETT |a| (SPADCALL |a| (QREFELT |$| 62)) |PSETCAT-;remainder;PSR;25|) (QREFELT |$| 42)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |hRa| (|PSETCAT-;makeIrreducible!| (SPADCALL |a| |ps| (QREFELT |$| 76)) |$|) |PSETCAT-;remainder;PSR;25|) (LETT |a| (QCAR |hRa|) |PSETCAT-;remainder;PSR;25|) (LETT |r| (SPADCALL |r| (QCDR |hRa|) (QREFELT |$| 70)) |PSETCAT-;remainder;PSR;25|) (LETT |g| (SPADCALL |c| (LETT |lca| (SPADCALL |a| (QREFELT |$| 64)) |PSETCAT-;remainder;PSR;25|) (QREFELT |$| 65)) |PSETCAT-;remainder;PSR;25|) (LETT |b| (SPADCALL (SPADCALL (SPADCALL (QCDR |hRa|) (|PSETCAT-;exactQuo| |c| |g| |$|) (QREFELT |$| 70)) |b| (QREFELT |$| 66)) (SPADCALL (|PSETCAT-;exactQuo| |lca| |g| |$|) (SPADCALL |a| (QREFELT |$| 40)) (QREFELT |$| 67)) (QREFELT |$| 77)) |PSETCAT-;remainder;PSR;25|) (EXIT (LETT |c| |g| |PSETCAT-;remainder;PSR;25|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (VECTOR |c| |b| |r|))))))))))
+
+(DEFUN |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26| (|ps| |cs| |$|) (PROG (|p| |rs|) (RETURN (SEQ (COND ((SPADCALL |cs| (QREFELT |$| 80)) |ps|) ((SPADCALL |cs| (QREFELT |$| 81)) (LIST (|spadConstant| |$| 82))) ((QUOTE T) (SEQ (LETT |ps| (SPADCALL (ELT |$| 42) |ps| (QREFELT |$| 26)) |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) (EXIT (COND ((NULL |ps|) |ps|) ((SPADCALL (ELT |$| 24) |ps| (QREFELT |$| 43)) (LIST (|spadConstant| |$| 83))) ((QUOTE T) (SEQ (LETT |rs| NIL |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) (SEQ G190 (COND ((NULL (COND ((NULL |ps|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |ps|) |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) (LETT |ps| (CDR |ps|) |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) (LETT |p| (QCAR (SPADCALL |p| |cs| (QREFELT |$| 76))) |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) (EXIT (COND ((NULL (SPADCALL |p| (QREFELT |$| 42))) (COND ((SPADCALL |p| (QREFELT |$| 24)) (SEQ (LETT |ps| NIL |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) (EXIT (LETT |rs| (LIST (|spadConstant| |$| 83)) |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|)))) ((QUOTE T) (SEQ (SPADCALL |p| (QREFELT |$| 84)) (EXIT (LETT |rs| (CONS |p| |rs|) |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|))))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |rs| (QREFELT |$| 85))))))))))))))
+
+(DEFUN |PSETCAT-;rewriteIdealWithRemainder;LSL;27| (|ps| |cs| |$|) (PROG (|p| |rs|) (RETURN (SEQ (COND ((SPADCALL |cs| (QREFELT |$| 80)) |ps|) ((SPADCALL |cs| (QREFELT |$| 81)) (LIST (|spadConstant| |$| 82))) ((QUOTE T) (SEQ (LETT |ps| (SPADCALL (ELT |$| 42) |ps| (QREFELT |$| 26)) |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) (EXIT (COND ((NULL |ps|) |ps|) ((SPADCALL (ELT |$| 24) |ps| (QREFELT |$| 43)) (LIST (|spadConstant| |$| 83))) ((QUOTE T) (SEQ (LETT |rs| NIL |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) (SEQ G190 (COND ((NULL (COND ((NULL |ps|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |p| (|SPADfirst| |ps|) |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) (LETT |ps| (CDR |ps|) |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) (LETT |p| (QVELT (SPADCALL |p| |cs| (QREFELT |$| 87)) 1) |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) (EXIT (COND ((NULL (SPADCALL |p| (QREFELT |$| 42))) (COND ((SPADCALL |p| (QREFELT |$| 24)) (SEQ (LETT |ps| NIL |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) (EXIT (LETT |rs| (LIST (|spadConstant| |$| 83)) |PSETCAT-;rewriteIdealWithRemainder;LSL;27|)))) ((QUOTE T) (LETT |rs| (CONS (SPADCALL |p| (QREFELT |$| 88)) |rs|) |PSETCAT-;rewriteIdealWithRemainder;LSL;27|))))))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |rs| (QREFELT |$| 85))))))))))))))
+
+(DEFUN |PolynomialSetCategory&| (|#1| |#2| |#3| |#4| |#5|) (PROG (|DV$1| |DV$2| |DV$3| |DV$4| |DV$5| |dv$| |$| |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #1=(|PolynomialSetCategory&|)) (LETT |DV$2| (|devaluate| |#2|) . #1#) (LETT |DV$3| (|devaluate| |#3|) . #1#) (LETT |DV$4| (|devaluate| |#4|) . #1#) (LETT |DV$5| (|devaluate| |#5|) . #1#) (LETT |dv$| (LIST (QUOTE |PolynomialSetCategory&|) |DV$1| |DV$2| |DV$3| |DV$4| |DV$5|) . #1#) (LETT |$| (GETREFV 90) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#2| (QUOTE (|IntegralDomain|))))) . #1#)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (QSETREFV |$| 7 |#2|) (QSETREFV |$| 8 |#3|) (QSETREFV |$| 9 |#4|) (QSETREFV |$| 10 |#5|) (COND ((|testBitVector| |pv$| 1) (PROGN (QSETREFV |$| 48 (CONS (|dispatchFunction| |PSETCAT-;roughUnitIdeal?;SB;16|) |$|)) (QSETREFV |$| 52 (CONS (|dispatchFunction| |PSETCAT-;roughBase?;SB;18|) |$|)) (QSETREFV |$| 54 (CONS (|dispatchFunction| |PSETCAT-;roughSubIdeal?;2SB;19|) |$|)) (QSETREFV |$| 57 (CONS (|dispatchFunction| |PSETCAT-;roughEqualIdeals?;2SB;20|) |$|))))) (COND ((|HasCategory| |#2| (QUOTE (|GcdDomain|))) (COND ((|HasCategory| |#4| (QUOTE (|ConvertibleTo| (|Symbol|)))) (PROGN (QSETREFV |$| 72 (CONS (|dispatchFunction| |PSETCAT-;headRemainder;PSR;23|) |$|)) (QSETREFV |$| 79 (CONS (|dispatchFunction| |PSETCAT-;remainder;PSR;25|) |$|)) (QSETREFV |$| 86 (CONS (|dispatchFunction| |PSETCAT-;rewriteIdealWithHeadRemainder;LSL;26|) |$|)) (QSETREFV |$| 89 (CONS (|dispatchFunction| |PSETCAT-;rewriteIdealWithRemainder;LSL;27|) |$|))))))) |$|))))
+
+(MAKEPROP (QUOTE |PolynomialSetCategory&|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|local| |#2|) (|local| |#3|) (|local| |#4|) (|local| |#5|) (|List| 10) (0 . |members|) (|List| 9) (5 . |variables|) (|Boolean|) (10 . |<|) (|List| |$|) (16 . |concat|) (21 . |removeDuplicates|) (|Mapping| 15 9 9) (26 . |sort|) (32 . |mvar|) |PSETCAT-;variables;SL;4| (37 . |ground?|) (|Mapping| 15 10) (42 . |remove|) |PSETCAT-;mainVariables;SL;5| (48 . |=|) |PSETCAT-;mainVariable?;VarSetSB;6| (54 . |construct|) |PSETCAT-;collectUnder;SVarSetS;7| |PSETCAT-;collectUpper;SVarSetS;8| |PSETCAT-;collect;SVarSetS;9| (|Record| (|:| |under| |$|) (|:| |floor| |$|) (|:| |upper| |$|)) |PSETCAT-;sort;SVarSetR;10| (|Set| 10) (59 . |brace|) (64 . |=|) |PSETCAT-;=;2SB;11| (70 . |degree|) (75 . |<|) (81 . |zero?|) (86 . |any?|) (|Mapping| 15 10 10) (92 . |sort|) |PSETCAT-;triangular?;SB;14| |PSETCAT-;trivialIdeal?;SB;15| (98 . |roughUnitIdeal?|) (103 . |sup|) (109 . |+|) (115 . |=|) (121 . |roughBase?|) (126 . |rewriteIdealWithRemainder|) (132 . |roughSubIdeal?|) (138 . |=|) (144 . |roughSubIdeal?|) (150 . |roughEqualIdeals?|) (156 . |quo|) (|Union| |$| (QUOTE "failed")) (162 . |exquo|) (168 . |One|) (172 . |reductum|) (177 . |subtractIfCan|) (183 . |leadingCoefficient|) (188 . |gcd|) (194 . |*|) (200 . |monomial|) (206 . |*|) (212 . |-|) (218 . |*|) (|Record| (|:| |num| 10) (|:| |den| 7)) (224 . |headRemainder|) (230 . |gcd|) (236 . |one?|) (241 . |exactQuotient!|) (247 . |headRemainder|) (253 . |+|) (|Record| (|:| |rnum| 7) (|:| |polnum| 10) (|:| |den| 7)) (259 . |remainder|) (265 . |trivialIdeal?|) (270 . |roughUnitIdeal?|) (275 . |Zero|) (279 . |One|) (283 . |primitivePart!|) (288 . |removeDuplicates|) (293 . |rewriteIdealWithHeadRemainder|) (299 . |remainder|) (305 . |unitCanonical|) (310 . |rewriteIdealWithRemainder|))) (QUOTE #(|variables| 316 |trivialIdeal?| 321 |triangular?| 326 |sort| 331 |roughUnitIdeal?| 337 |roughSubIdeal?| 342 |roughEqualIdeals?| 348 |roughBase?| 354 |rewriteIdealWithRemainder| 359 |rewriteIdealWithHeadRemainder| 365 |remainder| 371 |mainVariables| 377 |mainVariable?| 382 |headRemainder| 388 |collectUpper| 394 |collectUnder| 400 |collect| 406 |=| 412)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE NIL)) (CONS (QUOTE #()) (CONS (QUOTE #()) (|makeByteWordVec2| 89 (QUOTE (1 6 11 0 12 1 10 13 0 14 2 9 15 0 0 16 1 13 0 17 18 1 13 0 0 19 2 13 0 20 0 21 1 10 9 0 22 1 10 15 0 24 2 11 0 25 0 26 2 9 15 0 0 28 1 6 0 11 30 1 36 0 11 37 2 36 15 0 0 38 1 10 8 0 40 2 8 15 0 0 41 1 10 15 0 42 2 11 15 25 0 43 2 11 0 44 0 45 1 0 15 0 48 2 8 0 0 0 49 2 8 0 0 0 50 2 8 15 0 0 51 1 0 15 0 52 2 6 11 11 0 53 2 0 15 0 0 54 2 6 15 0 0 55 2 6 15 0 0 56 2 0 15 0 0 57 2 7 0 0 0 58 2 7 59 0 0 60 0 7 0 61 1 10 0 0 62 2 8 59 0 0 63 1 10 7 0 64 2 7 0 0 0 65 2 10 0 7 0 66 2 10 0 7 8 67 2 10 0 0 0 68 2 10 0 0 0 69 2 7 0 0 0 70 2 0 71 10 0 72 2 10 7 7 0 73 1 7 15 0 74 2 10 0 0 7 75 2 6 71 10 0 76 2 10 0 0 0 77 2 0 78 10 0 79 1 6 15 0 80 1 6 15 0 81 0 10 0 82 0 10 0 83 1 10 0 0 84 1 11 0 0 85 2 0 11 11 0 86 2 6 78 10 0 87 1 10 0 0 88 2 0 11 11 0 89 1 0 13 0 23 1 0 15 0 47 1 0 15 0 46 2 0 34 0 9 35 1 0 15 0 48 2 0 15 0 0 54 2 0 15 0 0 57 1 0 15 0 52 2 0 11 11 0 89 2 0 11 11 0 86 2 0 78 10 0 79 1 0 13 0 27 2 0 15 9 0 29 2 0 71 10 0 72 2 0 0 0 9 32 2 0 0 0 9 31 2 0 0 0 9 33 2 0 15 0 0 39)))))) (QUOTE |lookupComplete|)))
+@
+\section{domain GPOLSET GeneralPolynomialSet}
+<<domain GPOLSET GeneralPolynomialSet>>=
+)abbrev domain GPOLSET GeneralPolynomialSet
+++ Author: Marc Moreno Maza
+++ Date Created: 04/26/1994
+++ Date Last Updated: 12/15/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ References:
+++ Description: A domain for polynomial sets.
+++ Version: 1
+
+GeneralPolynomialSet(R,E,VarSet,P) : Exports == Implementation where
+
+ R:Ring
+ VarSet:OrderedSet
+ E:OrderedAbelianMonoidSup
+ P:RecursivePolynomialCategory(R,E,VarSet)
+ LP ==> List P
+ PtoP ==> P -> P
+
+ Exports == PolynomialSetCategory(R,E,VarSet,P) with
+
+ convert : LP -> $
+ ++ \axiom{convert(lp)} returns the polynomial set whose members
+ ++ are the polynomials of \axiom{lp}.
+
+ finiteAggregate
+ shallowlyMutable
+
+ Implementation == add
+
+ Rep := List P
+
+ construct lp ==
+ (removeDuplicates(lp)$List(P))::$
+
+ copy ps ==
+ construct(copy(members(ps)$$)$LP)$$
+
+ empty() ==
+ []
+
+ parts ps ==
+ ps pretend LP
+
+ map (f : PtoP, ps : $) : $ ==
+ construct(map(f,members(ps))$LP)$$
+
+ map! (f : PtoP, ps : $) : $ ==
+ construct(map!(f,members(ps))$LP)$$
+
+ member? (p,ps) ==
+ member?(p,members(ps))$LP
+
+ ps1 = ps2 ==
+ {p for p in parts(ps1)} =$(Set P) {p for p in parts(ps2)}
+
+ coerce(ps:$) : OutputForm ==
+ lp : List(P) := sort(infRittWu?,members(ps))$(List P)
+ brace([p::OutputForm for p in lp]$List(OutputForm))$OutputForm
+
+ mvar ps ==
+ empty? ps => error"Error from GPOLSET in mvar : #1 is empty"
+ lv : List VarSet := variables(ps)
+ empty? lv => error"Error from GPOLSET in mvar : every polynomial in #1 is constant"
+ reduce(max,lv)$(List VarSet)
+
+ retractIfCan(lp) ==
+ (construct(lp))::Union($,"failed")
+
+ coerce(ps:$) : (List P) ==
+ ps pretend (List P)
+
+ convert(lp:LP) : $ ==
+ construct lp
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PSETCAT PolynomialSetCategory>>
+<<domain GPOLSET GeneralPolynomialSet>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/poltopol.spad.pamphlet b/src/algebra/poltopol.spad.pamphlet
new file mode 100644
index 00000000..b1f1801d
--- /dev/null
+++ b/src/algebra/poltopol.spad.pamphlet
@@ -0,0 +1,204 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra poltopol.spad}
+\author{Manuel Bronstein, Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MPC2 MPolyCatFunctions2}
+<<package MPC2 MPolyCatFunctions2>>=
+)abbrev package MPC2 MPolyCatFunctions2
+++ Utilities for MPolyCat
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 28 March 1990 (PG)
+MPolyCatFunctions2(VarSet,E1,E2,R,S,PR,PS) : public == private where
+
+ VarSet : OrderedSet
+ E1 : OrderedAbelianMonoidSup
+ E2 : OrderedAbelianMonoidSup
+ R : Ring
+ S : Ring
+ PR : PolynomialCategory(R,E1,VarSet)
+ PS : PolynomialCategory(S,E2,VarSet)
+ SUPR ==> SparseUnivariatePolynomial PR
+ SUPS ==> SparseUnivariatePolynomial PS
+
+ public == with
+ map: (R -> S,PR) -> PS
+ ++ map(f,p) \undocumented
+ reshape: (List S, PR) -> PS
+ ++ reshape(l,p) \undocumented
+
+ private == add
+
+ supMap: (R -> S, SUPR) -> SUPS
+
+ supMap(fn : R -> S, supr : SUPR): SUPS ==
+ supr = 0 => monomial(fn(0$R) :: PS,0)$SUPS
+ c : PS := map(fn,leadingCoefficient supr)$%
+ monomial(c,degree supr)$SUPS + supMap(fn, reductum supr)
+
+ map(fn : R -> S, pr : PR): PS ==
+ varu : Union(VarSet,"failed") := mainVariable pr
+ varu case "failed" => -- have a constant
+ fn(retract pr) :: PS
+ var : VarSet := varu :: VarSet
+ supr : SUPR := univariate(pr,var)$PR
+ multivariate(supMap(fn,supr),var)$PS
+
+@
+\section{package MPC3 MPolyCatFunctions3}
+<<package MPC3 MPolyCatFunctions3>>=
+)abbrev package MPC3 MPolyCatFunctions3
+++ Description:
+++ This package \undocumented
+MPolyCatFunctions3(Vars1,Vars2,E1,E2,R,PR1,PR2): C == T where
+ E1 : OrderedAbelianMonoidSup
+ E2 : OrderedAbelianMonoidSup
+ Vars1: OrderedSet
+ Vars2: OrderedSet
+ R : Ring
+ PR1 : PolynomialCategory(R,E1,Vars1)
+ PR2 : PolynomialCategory(R,E2,Vars2)
+
+ C ==> with
+ map: (Vars1 -> Vars2, PR1) -> PR2
+ ++ map(f,x) \undocumented
+
+ T ==> add
+
+ map(f:Vars1 -> Vars2, p:PR1):PR2 ==
+ (x1 := mainVariable p) case "failed" =>
+ c:R:=(retract p)
+ c::PR2
+ up := univariate(p, x1::Vars1)
+ x2 := f(x1::Vars1)
+ ans:PR2 := 0
+ while up ^= 0 repeat
+ ans := ans + monomial(map(f,leadingCoefficient up),x2,degree up)
+ up := reductum up
+ ans
+
+@
+\section{package POLTOPOL PolToPol}
+<<package POLTOPOL PolToPol>>=
+)abbrev package POLTOPOL PolToPol
+++ Author : P.Gianni, Summer '88
+++ Description:
+++ Package with the conversion functions among different kind of polynomials
+PolToPol(lv,R) : C == T
+
+ where
+ R : Ring
+ lv : List Symbol
+ NNI ==> NonNegativeInteger
+ Ov ==> OrderedVariableList(lv)
+ IES ==> IndexedExponents Symbol
+
+ DP ==> DirectProduct(#lv,NonNegativeInteger)
+ DPoly ==> DistributedMultivariatePolynomial(lv,R)
+
+ HDP ==> HomogeneousDirectProduct(#lv,NonNegativeInteger)
+ HDPoly ==> HomogeneousDistributedMultivariatePolynomial(lv,R)
+ P ==> Polynomial R
+ VV ==> Vector NNI
+ MPC3 ==> MPolyCatFunctions3
+
+ C == with
+ dmpToHdmp : DPoly -> HDPoly
+ ++ dmpToHdmp(p) converts p from a \spadtype{DMP} to a \spadtype{HDMP}.
+ hdmpToDmp : HDPoly -> DPoly
+ ++ hdmpToDmp(p) converts p from a \spadtype{HDMP} to a \spadtype{DMP}.
+ pToHdmp : P -> HDPoly
+ ++ pToHdmp(p) converts p from a \spadtype{POLY} to a \spadtype{HDMP}.
+ hdmpToP : HDPoly -> P
+ ++ hdmpToP(p) converts p from a \spadtype{HDMP} to a \spadtype{POLY}.
+ dmpToP : DPoly -> P
+ ++ dmpToP(p) converts p from a \spadtype{DMP} to a \spadtype{POLY}.
+ pToDmp : P -> DPoly
+ ++ pToDmp(p) converts p from a \spadtype{POLY} to a \spadtype{DMP}.
+ T == add
+
+ variable1(xx:Symbol):Ov == variable(xx)::Ov
+
+ -- transform a P in a HDPoly --
+ pToHdmp(pol:P) : HDPoly ==
+ map(variable1,pol)$MPC3(Symbol,Ov,IES,HDP,R,P,HDPoly)
+
+ -- transform an HDPoly in a P --
+ hdmpToP(hdpol:HDPoly) : P ==
+ map(convert,hdpol)$MPC3(Ov,Symbol,HDP,IES,R,HDPoly,P)
+
+ -- transform an DPoly in a P --
+ dmpToP(dpol:DPoly) : P ==
+ map(convert,dpol)$MPC3(Ov,Symbol,DP,IES,R,DPoly,P)
+
+ -- transform a P in a DPoly --
+ pToDmp(pol:P) : DPoly ==
+ map(variable1,pol)$MPC3(Symbol,Ov,IES,DP,R,P,DPoly)
+
+ -- transform a DPoly in a HDPoly --
+ dmpToHdmp(dpol:DPoly) : HDPoly ==
+ dpol=0 => 0$HDPoly
+ monomial(leadingCoefficient dpol,
+ directProduct(degree(dpol)::VV)$HDP)$HDPoly+
+ dmpToHdmp(reductum dpol)
+
+ -- transform a HDPoly in a DPoly --
+ hdmpToDmp(hdpol:HDPoly) : DPoly ==
+ hdpol=0 => 0$DPoly
+ dd:DP:= directProduct((degree hdpol)::VV)$DP
+ monomial(leadingCoefficient hdpol,dd)$DPoly+
+ hdmpToDmp(reductum hdpol)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MPC2 MPolyCatFunctions2>>
+<<package MPC3 MPolyCatFunctions3>>
+<<package POLTOPOL PolToPol>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/poly.spad.pamphlet b/src/algebra/poly.spad.pamphlet
new file mode 100644
index 00000000..ad0206cd
--- /dev/null
+++ b/src/algebra/poly.spad.pamphlet
@@ -0,0 +1,1249 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra poly.spad}
+\author{Dave Barton, James Davenport, Barry Trager, Patrizia Gianni, Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain FM FreeModule}
+<<domain FM FreeModule>>=
+)abbrev domain FM FreeModule
+++ Author: Dave Barton, James Davenport, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: BiModule(R,R)
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A bi-module is a free module
+++ over a ring with generators indexed by an ordered set.
+++ Each element can be expressed as a finite linear combination of
+++ generators. Only non-zero terms are stored.
+
+FreeModule(R:Ring,S:OrderedSet):
+ Join(BiModule(R,R),IndexedDirectProductCategory(R,S)) with
+ if R has CommutativeRing then Module(R)
+ == IndexedDirectProductAbelianGroup(R,S) add
+ --representations
+ Term:= Record(k:S,c:R)
+ Rep:= List Term
+ --declarations
+ x,y: %
+ r: R
+ n: Integer
+ f: R -> R
+ s: S
+ --define
+ if R has EntireRing then
+ r * x ==
+ zero? r => 0
+-- one? r => x
+ (r = 1) => x
+ --map(r*#1,x)
+ [[u.k,r*u.c] for u in x ]
+ else
+ r * x ==
+ zero? r => 0
+-- one? r => x
+ (r = 1) => x
+ --map(r*#1,x)
+ [[u.k,a] for u in x | (a:=r*u.c) ^= 0$R]
+ if R has EntireRing then
+ x * r ==
+ zero? r => 0
+-- one? r => x
+ (r = 1) => x
+ --map(r*#1,x)
+ [[u.k,u.c*r] for u in x ]
+ else
+ x * r ==
+ zero? r => 0
+-- one? r => x
+ (r = 1) => x
+ --map(r*#1,x)
+ [[u.k,a] for u in x | (a:=u.c*r) ^= 0$R]
+
+ coerce(x) : OutputForm ==
+ null x => (0$R) :: OutputForm
+ le : List OutputForm := nil
+ for rec in reverse x repeat
+ rec.c = 1 => le := cons(rec.k :: OutputForm, le)
+ le := cons(rec.c :: OutputForm * rec.k :: OutputForm, le)
+ reduce("+",le)
+
+@
+\section{domain PR PolynomialRing}
+<<domain PR PolynomialRing>>=
+)abbrev domain PR PolynomialRing
+++ Author: Dave Barton, James Davenport, Barry Trager
+++ Date Created:
+++ Date Last Updated: 14.08.2000. Improved exponentiation [MMM/TTT]
+++ Basic Functions: Ring, degree, coefficient, monomial, reductum
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents generalized polynomials with coefficients
+++ (from a not necessarily commutative ring), and terms
+++ indexed by their exponents (from an arbitrary ordered abelian monoid).
+++ This type is used, for example,
+++ by the \spadtype{DistributedMultivariatePolynomial} domain where
+++ the exponent domain is a direct product of non negative integers.
+
+PolynomialRing(R:Ring,E:OrderedAbelianMonoid): T == C
+ where
+ T == FiniteAbelianMonoidRing(R,E) with
+ --assertions
+ if R has IntegralDomain and E has CancellationAbelianMonoid then
+ fmecg: (%,E,R,%) -> %
+ ++ fmecg(p1,e,r,p2) finds X : p1 - r * X**e * p2
+ if R has canonicalUnitNormal then canonicalUnitNormal
+ ++ canonicalUnitNormal guarantees that the function
+ ++ unitCanonical returns the same representative for all
+ ++ associates of any particular element.
+
+ C == FreeModule(R,E) add
+ --representations
+ Term:= Record(k:E,c:R)
+ Rep:= List Term
+
+
+ --declarations
+ x,y,p,p1,p2: %
+ n: Integer
+ nn: NonNegativeInteger
+ np: PositiveInteger
+ e: E
+ r: R
+ --local operations
+ 1 == [[0$E,1$R]]
+ characteristic == characteristic$R
+ numberOfMonomials x == (# x)$Rep
+ degree p == if null p then 0 else p.first.k
+ minimumDegree p == if null p then 0 else (last p).k
+ leadingCoefficient p == if null p then 0$R else p.first.c
+ leadingMonomial p == if null p then 0 else [p.first]
+ reductum p == if null p then p else p.rest
+ retractIfCan(p:%):Union(R,"failed") ==
+ null p => 0$R
+ not null p.rest => "failed"
+ zero?(p.first.k) => p.first.c
+ "failed"
+ coefficient(p,e) ==
+ for tm in p repeat
+ tm.k=e => return tm.c
+ tm.k < e => return 0$R
+ 0$R
+ recip(p) ==
+ null p => "failed"
+ p.first.k > 0$E => "failed"
+ (u:=recip(p.first.c)) case "failed" => "failed"
+ (u::R)::%
+
+ coerce(r) == if zero? r then 0$% else [[0$E,r]]
+ coerce(n) == (n::R)::%
+
+ ground?(p): Boolean == empty? p or (empty? rest p and zero? degree p)
+
+ qsetrest!: (Rep, Rep) -> Rep
+ qsetrest!(l: Rep, e: Rep): Rep == RPLACD(l, e)$Lisp
+
+ times!: (R, %) -> %
+ times: (R, E, %) -> %
+
+ entireRing? := R has EntireRing
+
+ times!(r: R, x: %): % ==
+ res, endcell, newend, xx: Rep
+ if entireRing? then
+ for tx in x repeat tx.c := r*tx.c
+ else
+ xx := x
+ res := empty()
+ while not empty? xx repeat
+ tx := first xx
+ tx.c := r * tx.c
+ if zero? tx.c then
+ xx := rest xx
+ else
+ newend := xx
+ xx := rest xx
+ if empty? res then
+ res := newend
+ endcell := res
+ else
+ qsetrest!(endcell, newend)
+ endcell := newend
+ res;
+
+ --- term * polynomial
+ termTimes: (R, E, Term) -> Term
+ termTimes(r: R, e: E, tx:Term): Term == [e+tx.k, r*tx.c]
+ times(tco: R, tex: E, rx: %): % ==
+ if entireRing? then
+ map(termTimes(tco, tex, #1), rx::Rep)
+ else
+ [[tex + tx.k, r] for tx in rx::Rep | not zero? (r := tco * tx.c)]
+
+
+
+ -- local addm!
+ addm!: (Rep, R, E, Rep) -> Rep
+ -- p1 + coef*x^E * p2
+ -- `spare' (commented out) is for storage efficiency (not so good for
+ -- performance though.
+ addm!(p1:Rep, coef:R, exp: E, p2:Rep): Rep ==
+ --local res, newend, last: Rep
+ res, newcell, endcell: Rep
+ spare: List Rep
+ res := empty()
+ endcell := empty()
+ --spare := empty()
+ while not empty? p1 and not empty? p2 repeat
+ tx := first p1
+ ty := first p2
+ exy := exp + ty.k
+ newcell := empty();
+ if tx.k = exy then
+ newcoef := tx.c + coef * ty.c
+ if not zero? newcoef then
+ tx.c := newcoef
+ newcell := p1
+ --else
+ -- spare := cons(p1, spare)
+ p1 := rest p1
+ p2 := rest p2
+ else if tx.k > exy then
+ newcell := p1
+ p1 := rest p1
+ else
+ newcoef := coef * ty.c
+ if not entireRing? and zero? newcoef then
+ newcell := empty()
+ --else if empty? spare then
+ -- ttt := [exy, newcoef]
+ -- newcell := cons(ttt, empty())
+ --else
+ -- newcell := first spare
+ -- spare := rest spare
+ -- ttt := first newcell
+ -- ttt.k := exy
+ -- ttt.c := newcoef
+ else
+ ttt := [exy, newcoef]
+ newcell := cons(ttt, empty())
+ p2 := rest p2
+ if not empty? newcell then
+ if empty? res then
+ res := newcell
+ endcell := res
+ else
+ qsetrest!(endcell, newcell)
+ endcell := newcell
+ if not empty? p1 then -- then end is const * p1
+ newcell := p1
+ else -- then end is (coef, exp) * p2
+ newcell := times(coef, exp, p2)
+ empty? res => newcell
+ qsetrest!(endcell, newcell)
+ res
+ pomopo! (p1, r, e, p2) == addm!(p1, r, e, p2)
+ p1 * p2 ==
+ xx := p1::Rep
+ empty? xx => p1
+ yy := p2::Rep
+ empty? yy => p2
+ zero? first(xx).k => first(xx).c * p2
+ zero? first(yy).k => p1 * first(yy).c
+ --if #xx > #yy then
+ -- (xx, yy) := (yy, xx)
+ -- (p1, p2) := (p2, p1)
+ xx := reverse xx
+ res : Rep := empty()
+ for tx in xx repeat res:=addm!(res,tx.c,tx.k,yy)
+ res
+
+-- if R has EntireRing then
+-- p1 * p2 ==
+-- null p1 => 0
+-- null p2 => 0
+-- zero?(p1.first.k) => p1.first.c * p2
+-- one? p2 => p1
+-- +/[[[t1.k+t2.k,t1.c*t2.c]$Term for t2 in p2]
+-- for t1 in reverse(p1)]
+-- -- This 'reverse' is an efficiency improvement:
+-- -- reduces both time and space [Abbott/Bradford/Davenport]
+-- else
+-- p1 * p2 ==
+-- null p1 => 0
+-- null p2 => 0
+-- zero?(p1.first.k) => p1.first.c * p2
+-- one? p2 => p1
+-- +/[[[t1.k+t2.k,r]$Term for t2 in p2 | (r:=t1.c*t2.c) ^= 0]
+-- for t1 in reverse(p1)]
+-- -- This 'reverse' is an efficiency improvement:
+-- -- reduces both time and space [Abbott/Bradford/Davenport]
+ if R has CommutativeRing then
+ p ** np == p ** (np pretend NonNegativeInteger)
+ p ^ np == p ** (np pretend NonNegativeInteger)
+ p ^ nn == p ** nn
+
+
+ p ** nn ==
+ null p => 0
+ zero? nn => 1
+-- one? nn => p
+ (nn = 1) => p
+ empty? p.rest =>
+ zero?(cc:=p.first.c ** nn) => 0
+ [[nn * p.first.k, cc]]
+ binomThmExpt([p.first], p.rest, nn)
+
+ if R has Field then
+ unitNormal(p) ==
+ null p or (lcf:R:=p.first.c) = 1 => [1,p,1]
+ a := inv lcf
+ [lcf::%, [[p.first.k,1],:(a * p.rest)], a::%]
+ unitCanonical(p) ==
+ null p or (lcf:R:=p.first.c) = 1 => p
+ a := inv lcf
+ [[p.first.k,1],:(a * p.rest)]
+ else if R has IntegralDomain then
+ unitNormal(p) ==
+ null p or p.first.c = 1 => [1,p,1]
+ (u,cf,a):=unitNormal(p.first.c)
+ [u::%, [[p.first.k,cf],:(a * p.rest)], a::%]
+ unitCanonical(p) ==
+ null p or p.first.c = 1 => p
+ (u,cf,a):=unitNormal(p.first.c)
+ [[p.first.k,cf],:(a * p.rest)]
+ if R has IntegralDomain then
+ associates?(p1,p2) ==
+ null p1 => null p2
+ null p2 => false
+ p1.first.k = p2.first.k and
+ associates?(p1.first.c,p2.first.c) and
+ ((p2.first.c exquo p1.first.c)::R * p1.rest = p2.rest)
+ p exquo r ==
+ [(if (a:= tm.c exquo r) case "failed"
+ then return "failed" else [tm.k,a])
+ for tm in p] :: Union(%,"failed")
+ if E has CancellationAbelianMonoid then
+ fmecg(p1:%,e:E,r:R,p2:%):% == -- p1 - r * X**e * p2
+ rout:%:= []
+ r:= - r
+ for tm in p2 repeat
+ e2:= e + tm.k
+ c2:= r * tm.c
+ c2 = 0 => "next term"
+ while not null p1 and p1.first.k > e2 repeat
+ (rout:=[p1.first,:rout]; p1:=p1.rest) --use PUSH and POP?
+ null p1 or p1.first.k < e2 => rout:=[[e2,c2],:rout]
+ if (u:=p1.first.c + c2) ^= 0 then rout:=[[e2, u],:rout]
+ p1:=p1.rest
+ NRECONC(rout,p1)$Lisp
+ if R has approximate then
+ p1 exquo p2 ==
+ null p2 => error "Division by 0"
+ p2 = 1 => p1
+ p1=p2 => 1
+ --(p1.lastElt.c exquo p2.lastElt.c) case "failed" => "failed"
+ rout:= []@List(Term)
+ while not null p1 repeat
+ (a:= p1.first.c exquo p2.first.c)
+ a case "failed" => return "failed"
+ ee:= subtractIfCan(p1.first.k, p2.first.k)
+ ee case "failed" => return "failed"
+ p1:= fmecg(p1.rest, ee, a, p2.rest)
+ rout:= [[ee,a], :rout]
+ null p1 => reverse(rout)::% -- nreverse?
+ "failed"
+ else -- R not approximate
+ p1 exquo p2 ==
+ null p2 => error "Division by 0"
+ p2 = 1 => p1
+ --(p1.lastElt.c exquo p2.lastElt.c) case "failed" => "failed"
+ rout:= []@List(Term)
+ while not null p1 repeat
+ (a:= p1.first.c exquo p2.first.c)
+ a case "failed" => return "failed"
+ ee:= subtractIfCan(p1.first.k, p2.first.k)
+ ee case "failed" => return "failed"
+ p1:= fmecg(p1.rest, ee, a, p2.rest)
+ rout:= [[ee,a], :rout]
+ null p1 => reverse(rout)::% -- nreverse?
+ "failed"
+ if R has Field then
+ x/r == inv(r)*x
+
+@
+\section{domain SUP SparseUnivariatePolynomial}
+<<domain SUP SparseUnivariatePolynomial>>=
+)abbrev domain SUP SparseUnivariatePolynomial
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, monomial, coefficient, reductum, differentiate,
+++ elt, map, resultant, discriminant
+++ Related Constructors: UnivariatePolynomial, Polynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents univariate polynomials over arbitrary
+++ (not necessarily commutative) coefficient rings. The variable is
+++ unspecified so that the variable displays as \spad{?} on output.
+++ If it is necessary to specify the variable name, use type \spadtype{UnivariatePolynomial}.
+++ The representation is sparse
+++ in the sense that only non-zero terms are represented.
+++ Note: if the coefficient ring is a field, this domain forms a euclidean domain.
+
+SparseUnivariatePolynomial(R:Ring): UnivariatePolynomialCategory(R) with
+ outputForm : (%,OutputForm) -> OutputForm
+ ++ outputForm(p,var) converts the SparseUnivariatePolynomial p to
+ ++ an output form (see \spadtype{OutputForm}) printed as a polynomial in the
+ ++ output form variable.
+ fmecg: (%,NonNegativeInteger,R,%) -> %
+ ++ fmecg(p1,e,r,p2) finds X : p1 - r * X**e * p2
+ == PolynomialRing(R,NonNegativeInteger)
+ add
+ --representations
+ Term := Record(k:NonNegativeInteger,c:R)
+ Rep := List Term
+ p:%
+ n:NonNegativeInteger
+ np: PositiveInteger
+ FP ==> SparseUnivariatePolynomial %
+ pp,qq: FP
+ lpp:List FP
+
+ -- for karatsuba
+ kBound: NonNegativeInteger := 63
+ upmp := UnivariatePolynomialMultiplicationPackage(R,%)
+
+
+ if R has FieldOfPrimeCharacteristic then
+ p ** np == p ** (np pretend NonNegativeInteger)
+ p ^ np == p ** (np pretend NonNegativeInteger)
+ p ^ n == p ** n
+ p ** n ==
+ null p => 0
+ zero? n => 1
+-- one? n => p
+ (n = 1) => p
+ empty? p.rest =>
+ zero?(cc:=p.first.c ** n) => 0
+ [[n * p.first.k, cc]]
+ -- not worth doing special trick if characteristic is too small
+ if characteristic()$R < 3 then return expt(p,n pretend PositiveInteger)$RepeatedSquaring(%)
+ y:%:=1
+ -- break up exponent in qn * characteristic + rn
+ -- exponentiating by the characteristic is fast
+ rec := divide(n, characteristic()$R)
+ qn:= rec.quotient
+ rn:= rec.remainder
+ repeat
+ if rn = 1 then y := y * p
+ if rn > 1 then y:= y * binomThmExpt([p.first], p.rest, rn)
+ zero? qn => return y
+ -- raise to the characteristic power
+ p:= [[t.k * characteristic()$R , primeFrobenius(t.c)$R ]$Term for t in p]
+ rec := divide(qn, characteristic()$R)
+ qn:= rec.quotient
+ rn:= rec.remainder
+ y
+
+
+
+ zero?(p): Boolean == empty?(p)
+-- one?(p):Boolean == not empty? p and (empty? rest p and zero? first(p).k and one? first(p).c)
+ one?(p):Boolean == not empty? p and (empty? rest p and zero? first(p).k and (first(p).c = 1))
+ ground?(p): Boolean == empty? p or (empty? rest p and zero? first(p).k)
+ multiplyExponents(p,n) == [ [u.k*n,u.c] for u in p]
+ divideExponents(p,n) ==
+ null p => p
+ m:= (p.first.k :: Integer exquo n::Integer)
+ m case "failed" => "failed"
+ u:= divideExponents(p.rest,n)
+ u case "failed" => "failed"
+ [[m::Integer::NonNegativeInteger,p.first.c],:u]
+ karatsubaDivide(p, n) ==
+ zero? n => [p, 0]
+ lowp: Rep := p
+ highp: Rep := []
+ repeat
+ if empty? lowp then break
+ t := first lowp
+ if t.k < n then break
+ lowp := rest lowp
+ highp := cons([subtractIfCan(t.k,n)::NonNegativeInteger,t.c]$Term,highp)
+ [ reverse highp, lowp]
+ shiftRight(p, n) ==
+ [[subtractIfCan(t.k,n)::NonNegativeInteger,t.c]$Term for t in p]
+ shiftLeft(p, n) ==
+ [[t.k + n,t.c]$Term for t in p]
+ pomopo!(p1,r,e,p2) ==
+ rout:%:= []
+ for tm in p2 repeat
+ e2:= e + tm.k
+ c2:= r * tm.c
+ c2 = 0 => "next term"
+ while not null p1 and p1.first.k > e2 repeat
+ (rout:=[p1.first,:rout]; p1:=p1.rest) --use PUSH and POP?
+ null p1 or p1.first.k < e2 => rout:=[[e2,c2],:rout]
+ if (u:=p1.first.c + c2) ^= 0 then rout:=[[e2, u],:rout]
+ p1:=p1.rest
+ NRECONC(rout,p1)$Lisp
+
+-- implementation using karatsuba algorithm conditionally
+--
+-- p1 * p2 ==
+-- xx := p1::Rep
+-- empty? xx => p1
+-- yy := p2::Rep
+-- empty? yy => p2
+-- zero? first(xx).k => first(xx).c * p2
+-- zero? first(yy).k => p1 * first(yy).c
+-- (first(xx).k > kBound) and (first(yy).k > kBound) and (#xx > kBound) and (#yy > kBound) =>
+-- karatsubaOnce(p1,p2)$upmp
+-- xx := reverse xx
+-- res : Rep := empty()
+-- for tx in xx repeat res:= rep pomopo!( res,tx.c,tx.k,p2)
+-- res
+
+
+ univariate(p:%) == p pretend SparseUnivariatePolynomial(R)
+ multivariate(sup:SparseUnivariatePolynomial(R),v:SingletonAsOrderedSet) ==
+ sup pretend %
+ univariate(p:%,v:SingletonAsOrderedSet) ==
+ zero? p => 0
+ monomial(leadingCoefficient(p)::%,degree p) +
+ univariate(reductum p,v)
+ multivariate(supp:SparseUnivariatePolynomial(%),v:SingletonAsOrderedSet) ==
+ zero? supp => 0
+ lc:=leadingCoefficient supp
+ degree lc > 0 => error "bad form polynomial"
+ monomial(leadingCoefficient lc,degree supp) +
+ multivariate(reductum supp,v)
+ if R has FiniteFieldCategory and R has PolynomialFactorizationExplicit then
+ RXY ==> SparseUnivariatePolynomial SparseUnivariatePolynomial R
+ squareFreePolynomial pp ==
+ squareFree(pp)$UnivariatePolynomialSquareFree(%,FP)
+ factorPolynomial pp ==
+ (generalTwoFactor(pp pretend RXY)$TwoFactorize(R))
+ pretend Factored SparseUnivariatePolynomial %
+ factorSquareFreePolynomial pp ==
+ (generalTwoFactor(pp pretend RXY)$TwoFactorize(R))
+ pretend Factored SparseUnivariatePolynomial %
+ gcdPolynomial(pp,qq) == gcd(pp,qq)$FP
+ factor p == factor(p)$DistinctDegreeFactorize(R,%)
+ solveLinearPolynomialEquation(lpp,pp) ==
+ solveLinearPolynomialEquation(lpp, pp)$FiniteFieldSolveLinearPolynomialEquation(R,%,FP)
+ else if R has PolynomialFactorizationExplicit then
+ import PolynomialFactorizationByRecursionUnivariate(R,%)
+ solveLinearPolynomialEquation(lpp,pp)==
+ solveLinearPolynomialEquationByRecursion(lpp,pp)
+ factorPolynomial(pp) ==
+ factorByRecursion(pp)
+ factorSquareFreePolynomial(pp) ==
+ factorSquareFreeByRecursion(pp)
+
+ if R has IntegralDomain then
+ if R has approximate then
+ p1 exquo p2 ==
+ null p2 => error "Division by 0"
+ p2 = 1 => p1
+ p1=p2 => 1
+ --(p1.lastElt.c exquo p2.lastElt.c) case "failed" => "failed"
+ rout:= []@List(Term)
+ while not null p1 repeat
+ (a:= p1.first.c exquo p2.first.c)
+ a case "failed" => return "failed"
+ ee:= subtractIfCan(p1.first.k, p2.first.k)
+ ee case "failed" => return "failed"
+ p1:= fmecg(p1.rest, ee, a, p2.rest)
+ rout:= [[ee,a], :rout]
+ null p1 => reverse(rout)::% -- nreverse?
+ "failed"
+ else -- R not approximate
+ p1 exquo p2 ==
+ null p2 => error "Division by 0"
+ p2 = 1 => p1
+ --(p1.lastElt.c exquo p2.lastElt.c) case "failed" => "failed"
+ rout:= []@List(Term)
+ while not null p1 repeat
+ (a:= p1.first.c exquo p2.first.c)
+ a case "failed" => return "failed"
+ ee:= subtractIfCan(p1.first.k, p2.first.k)
+ ee case "failed" => return "failed"
+ p1:= fmecg(p1.rest, ee, a, p2.rest)
+ rout:= [[ee,a], :rout]
+ null p1 => reverse(rout)::% -- nreverse?
+ "failed"
+ fmecg(p1,e,r,p2) == -- p1 - r * X**e * p2
+ rout:%:= []
+ r:= - r
+ for tm in p2 repeat
+ e2:= e + tm.k
+ c2:= r * tm.c
+ c2 = 0 => "next term"
+ while not null p1 and p1.first.k > e2 repeat
+ (rout:=[p1.first,:rout]; p1:=p1.rest) --use PUSH and POP?
+ null p1 or p1.first.k < e2 => rout:=[[e2,c2],:rout]
+ if (u:=p1.first.c + c2) ^= 0 then rout:=[[e2, u],:rout]
+ p1:=p1.rest
+ NRECONC(rout,p1)$Lisp
+ pseudoRemainder(p1,p2) ==
+ null p2 => error "PseudoDivision by Zero"
+ null p1 => 0
+ co:=p2.first.c;
+ e:=p2.first.k;
+ p2:=p2.rest;
+ e1:=max(p1.first.k:Integer-e+1,0):NonNegativeInteger
+ while not null p1 repeat
+ if (u:=subtractIfCan(p1.first.k,e)) case "failed" then leave
+ p1:=fmecg(co * p1.rest, u, p1.first.c, p2)
+ e1:= (e1 - 1):NonNegativeInteger
+ e1 = 0 => p1
+ co ** e1 * p1
+ toutput(t1:Term,v:OutputForm):OutputForm ==
+ t1.k = 0 => t1.c :: OutputForm
+ if t1.k = 1
+ then mon:= v
+ else mon := v ** t1.k::OutputForm
+ t1.c = 1 => mon
+ t1.c = -1 and
+ ((t1.c :: OutputForm) = (-1$Integer)::OutputForm)@Boolean => - mon
+ t1.c::OutputForm * mon
+ outputForm(p:%,v:OutputForm) ==
+ l: List(OutputForm)
+ l:=[toutput(t,v) for t in p]
+ null l => (0$Integer)::OutputForm -- else FreeModule 0 problems
+ reduce("+",l)
+
+ coerce(p:%):OutputForm == outputForm(p, "?"::OutputForm)
+ elt(p:%,val:R) ==
+ null p => 0$R
+ co:=p.first.c
+ n:=p.first.k
+ for tm in p.rest repeat
+ co:= co * val ** (n - (n:=tm.k)):NonNegativeInteger + tm.c
+ n = 0 => co
+ co * val ** n
+ elt(p:%,val:%) ==
+ null p => 0$%
+ coef:% := p.first.c :: %
+ n:=p.first.k
+ for tm in p.rest repeat
+ coef:= coef * val ** (n-(n:=tm.k)):NonNegativeInteger+(tm.c::%)
+ n = 0 => coef
+ coef * val ** n
+
+ monicDivide(p1:%,p2:%) ==
+ null p2 => error "monicDivide: division by 0"
+ leadingCoefficient p2 ^= 1 => error "Divisor Not Monic"
+ p2 = 1 => [p1,0]
+ null p1 => [0,0]
+ degree p1 < (n:=degree p2) => [0,p1]
+ rout:Rep := []
+ p2 := p2.rest
+ while not null p1 repeat
+ (u:=subtractIfCan(p1.first.k, n)) case "failed" => leave
+ rout:=[[u, p1.first.c], :rout]
+ p1:=fmecg(p1.rest, rout.first.k, rout.first.c, p2)
+ [reverse_!(rout),p1]
+
+ if R has IntegralDomain then
+ discriminant(p) == discriminant(p)$PseudoRemainderSequence(R,%)
+-- discriminant(p) ==
+-- null p or zero?(p.first.k) => error "cannot take discriminant of constants"
+-- dp:=differentiate p
+-- corr:= p.first.c ** ((degree p - 1 - degree dp)::NonNegativeInteger)
+-- (-1)**((p.first.k*(p.first.k-1)) quo 2):NonNegativeInteger
+-- * (corr * resultant(p,dp) exquo p.first.c)::R
+
+ subResultantGcd(p1,p2) == subResultantGcd(p1,p2)$PseudoRemainderSequence(R,%)
+-- subResultantGcd(p1,p2) == --args # 0, non-coef, prim, ans not prim
+-- --see algorithm 1 (p. 4) of Brown's latest (unpublished) paper
+-- if p1.first.k < p2.first.k then (p1,p2):=(p2,p1)
+-- p:=pseudoRemainder(p1,p2)
+-- co:=1$R;
+-- e:= (p1.first.k - p2.first.k):NonNegativeInteger
+-- while not null p and p.first.k ^= 0 repeat
+-- p1:=p2; p2:=p; p:=pseudoRemainder(p1,p2)
+-- null p or p.first.k = 0 => "enuf"
+-- co:=(p1.first.c ** e exquo co ** max(0, (e-1))::NonNegativeInteger)::R
+-- e:= (p1.first.k - p2.first.k):NonNegativeInteger; c1:=co**e
+-- p:=[[tm.k,((tm.c exquo p1.first.c)::R exquo c1)::R] for tm in p]
+-- if null p then p2 else 1$%
+
+ resultant(p1,p2) == resultant(p1,p2)$PseudoRemainderSequence(R,%)
+-- resultant(p1,p2) == --SubResultant PRS Algorithm
+-- null p1 or null p2 => 0$R
+-- 0 = degree(p1) => ((first p1).c)**degree(p2)
+-- 0 = degree(p2) => ((first p2).c)**degree(p1)
+-- if p1.first.k < p2.first.k then
+-- (if odd?(p1.first.k) then p1:=-p1; (p1,p2):=(p2,p1))
+-- p:=pseudoRemainder(p1,p2)
+-- co:=1$R; e:=(p1.first.k-p2.first.k):NonNegativeInteger
+-- while not null p repeat
+-- if not odd?(e) then p:=-p
+-- p1:=p2; p2:=p; p:=pseudoRemainder(p1,p2)
+-- co:=(p1.first.c ** e exquo co ** max(e:Integer-1,0):NonNegativeInteger)::R
+-- e:= (p1.first.k - p2.first.k):NonNegativeInteger; c1:=co**e
+-- p:=(p exquo ((leadingCoefficient p1) * c1))::%
+-- degree p2 > 0 => 0$R
+-- (p2.first.c**e exquo co**((e-1)::NonNegativeInteger))::R
+ if R has GcdDomain then
+ content(p) == if null p then 0$R else "gcd"/[tm.c for tm in p]
+ --make CONTENT more efficient?
+
+ primitivePart(p) ==
+ null p => p
+ ct :=content(p)
+ unitCanonical((p exquo ct)::%)
+ -- exquo present since % is now an IntegralDomain
+
+ gcd(p1,p2) ==
+ gcdPolynomial(p1 pretend SparseUnivariatePolynomial R,
+ p2 pretend SparseUnivariatePolynomial R) pretend %
+
+ if R has Field then
+ divide( p1, p2) ==
+ zero? p2 => error "Division by 0"
+-- one? p2 => [p1,0]
+ (p2 = 1) => [p1,0]
+ ct:=inv(p2.first.c)
+ n:=p2.first.k
+ p2:=p2.rest
+ rout:=empty()$List(Term)
+ while p1 ^= 0 repeat
+ (u:=subtractIfCan(p1.first.k, n)) case "failed" => leave
+ rout:=[[u, ct * p1.first.c], :rout]
+ p1:=fmecg(p1.rest, rout.first.k, rout.first.c, p2)
+ [reverse_!(rout),p1]
+
+ p / co == inv(co) * p
+
+@
+\section{package SUP2 SparseUnivariatePolynomialFunctions2}
+<<package SUP2 SparseUnivariatePolynomialFunctions2>>=
+)abbrev package SUP2 SparseUnivariatePolynomialFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package lifts a mapping from coefficient rings R to S to
+++ a mapping from sparse univariate polynomial over R to
+++ a sparse univariate polynomial over S.
+++ Note that the mapping is assumed
+++ to send zero to zero, since it will only be applied to the non-zero
+++ coefficients of the polynomial.
+
+SparseUnivariatePolynomialFunctions2(R:Ring, S:Ring): with
+ map:(R->S,SparseUnivariatePolynomial R) -> SparseUnivariatePolynomial S
+ ++ map(func, poly) creates a new polynomial by applying func to
+ ++ every non-zero coefficient of the polynomial poly.
+ == add
+ map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
+ SparseUnivariatePolynomial R, S, SparseUnivariatePolynomial S)
+
+@
+\section{domain UP UnivariatePolynomial}
+<<domain UP UnivariatePolynomial>>=
+)abbrev domain UP UnivariatePolynomial
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, monomial, coefficient, reductum, differentiate,
+++ elt, map, resultant, discriminant
+++ Related Constructors: SparseUnivariatePolynomial, MultivariatePolynomial
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents univariate polynomials in some symbol
+++ over arbitrary (not necessarily commutative) coefficient rings.
+++ The representation is sparse
+++ in the sense that only non-zero terms are represented.
+++ Note: if the coefficient ring is a field, then this domain forms a euclidean domain.
+
+UnivariatePolynomial(x:Symbol, R:Ring):
+ UnivariatePolynomialCategory(R) with
+ coerce: Variable(x) -> %
+ ++ coerce(x) converts the variable x to a univariate polynomial.
+ fmecg: (%,NonNegativeInteger,R,%) -> %
+ ++ fmecg(p1,e,r,p2) finds X : p1 - r * X**e * p2
+ == SparseUnivariatePolynomial(R) add
+ Rep:=SparseUnivariatePolynomial(R)
+ coerce(p:%):OutputForm == outputForm(p, outputForm x)
+ coerce(v:Variable(x)):% == monomial(1, 1)
+
+@
+\section{package UP2 UnivariatePolynomialFunctions2}
+<<package UP2 UnivariatePolynomialFunctions2>>=
+)abbrev package UP2 UnivariatePolynomialFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package lifts a mapping from coefficient rings R to S to
+++ a mapping from \spadtype{UnivariatePolynomial}(x,R) to
+++ \spadtype{UnivariatePolynomial}(y,S). Note that the mapping is assumed
+++ to send zero to zero, since it will only be applied to the non-zero
+++ coefficients of the polynomial.
+
+UnivariatePolynomialFunctions2(x:Symbol, R:Ring, y:Symbol, S:Ring): with
+ map: (R -> S, UnivariatePolynomial(x,R)) -> UnivariatePolynomial(y,S)
+ ++ map(func, poly) creates a new polynomial by applying func to
+ ++ every non-zero coefficient of the polynomial poly.
+ == add
+ map(f, p) == map(f, p)$UnivariatePolynomialCategoryFunctions2(R,
+ UnivariatePolynomial(x, R), S, UnivariatePolynomial(y, S))
+
+@
+\section{package POLY2UP PolynomialToUnivariatePolynomial}
+<<package POLY2UP PolynomialToUnivariatePolynomial>>=
+)abbrev package POLY2UP PolynomialToUnivariatePolynomial
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package is primarily to help the interpreter do coercions.
+++ It allows you to view a polynomial as a
+++ univariate polynomial in one of its variables with
+++ coefficients which are again a polynomial in all the
+++ other variables.
+
+PolynomialToUnivariatePolynomial(x:Symbol, R:Ring): with
+ univariate: (Polynomial R, Variable x) ->
+ UnivariatePolynomial(x, Polynomial R)
+ ++ univariate(p, x) converts the polynomial p to a one of type
+ ++ \spad{UnivariatePolynomial(x,Polynomial(R))}, ie. as a member of \spad{R[...][x]}.
+ == add
+ univariate(p, y) ==
+ q:SparseUnivariatePolynomial(Polynomial R) := univariate(p, x)
+ map(#1, q)$UnivariatePolynomialCategoryFunctions2(Polynomial R,
+ SparseUnivariatePolynomial Polynomial R, Polynomial R,
+ UnivariatePolynomial(x, Polynomial R))
+
+@
+\section{package UPSQFREE UnivariatePolynomialSquareFree}
+<<package UPSQFREE UnivariatePolynomialSquareFree>>=
+)abbrev package UPSQFREE UnivariatePolynomialSquareFree
+++ Author: Dave Barton, Barry Trager
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: squareFree, squareFreePart
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides for square-free decomposition of
+++ univariate polynomials over arbitrary rings, i.e.
+++ a partial factorization such that each factor is a product
+++ of irreducibles with multiplicity one and the factors are
+++ pairwise relatively prime. If the ring
+++ has characteristic zero, the result is guaranteed to satisfy
+++ this condition. If the ring is an infinite ring of
+++ finite characteristic, then it may not be possible to decide when
+++ polynomials contain factors which are pth powers. In this
+++ case, the flag associated with that polynomial is set to "nil"
+++ (meaning that that polynomials are not guaranteed to be square-free).
+
+UnivariatePolynomialSquareFree(RC:IntegralDomain,P):C == T
+ where
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FF ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
+ P:Join(UnivariatePolynomialCategory(RC),IntegralDomain) with
+ gcd: (%,%) -> %
+ ++ gcd(p,q) computes the greatest-common-divisor of p and q.
+
+ C == with
+ squareFree: P -> Factored(P)
+ ++ squareFree(p) computes the square-free factorization of the
+ ++ univariate polynomial p. Each factor has no repeated roots, and the
+ ++ factors are pairwise relatively prime.
+ squareFreePart: P -> P
+ ++ squareFreePart(p) returns a polynomial which has the same
+ ++ irreducible factors as the univariate polynomial p, but each
+ ++ factor has multiplicity one.
+ BumInSepFFE: FF -> FF
+ ++ BumInSepFFE(f) is a local function, exported only because
+ ++ it has multiple conditional definitions.
+
+ T == add
+
+ if RC has CharacteristicZero then
+ squareFreePart(p:P) == (p exquo gcd(p, differentiate p))::P
+ else
+ squareFreePart(p:P) ==
+ unit(s := squareFree(p)$%) * */[f.factor for f in factors s]
+
+ if RC has FiniteFieldCategory then
+ BumInSepFFE(ffe:FF) ==
+ ["sqfr", map(charthRoot,ffe.fctr), characteristic$P*ffe.xpnt]
+ else if RC has CharacteristicNonZero then
+ BumInSepFFE(ffe:FF) ==
+ np := multiplyExponents(ffe.fctr,characteristic$P:NonNegativeInteger)
+ (nthrp := charthRoot(np)) case "failed" =>
+ ["nil", np, ffe.xpnt]
+ ["sqfr", nthrp, characteristic$P*ffe.xpnt]
+
+ else
+ BumInSepFFE(ffe:FF) ==
+ ["nil",
+ multiplyExponents(ffe.fctr,characteristic$P:NonNegativeInteger),
+ ffe.xpnt]
+
+
+ if RC has CharacteristicZero then
+ squareFree(p:P) == --Yun's algorithm - see SYMSAC '76, p.27
+ --Note ci primitive is, so GCD's don't need to %do contents.
+ --Change gcd to return cofctrs also?
+ ci:=p; di:=differentiate(p); pi:=gcd(ci,di)
+ degree(pi)=0 =>
+ (u,c,a):=unitNormal(p)
+ makeFR(u,[["sqfr",c,1]])
+ i:NonNegativeInteger:=0; lffe:List FF:=[]
+ lcp := leadingCoefficient p
+ while degree(ci)^=0 repeat
+ ci:=(ci exquo pi)::P
+ di:=(di exquo pi)::P - differentiate(ci)
+ pi:=gcd(ci,di)
+ i:=i+1
+ degree(pi) > 0 =>
+ lcp:=(lcp exquo (leadingCoefficient(pi)**i))::RC
+ lffe:=[["sqfr",pi,i],:lffe]
+ makeFR(lcp::P,lffe)
+
+ else
+ squareFree(p:P) == --Musser's algorithm - see SYMSAC '76, p.27
+ --p MUST BE PRIMITIVE, Any characteristic.
+ --Note ci primitive, so GCD's don't need to %do contents.
+ --Change gcd to return cofctrs also?
+ ci := gcd(p,differentiate(p))
+ degree(ci)=0 =>
+ (u,c,a):=unitNormal(p)
+ makeFR(u,[["sqfr",c,1]])
+ di := (p exquo ci)::P
+ i:NonNegativeInteger:=0; lffe:List FF:=[]
+ dunit : P := 1
+ while degree(di)^=0 repeat
+ diprev := di
+ di := gcd(ci,di)
+ ci:=(ci exquo di)::P
+ i:=i+1
+ degree(diprev) = degree(di) =>
+ lc := (leadingCoefficient(diprev) exquo leadingCoefficient(di))::RC
+ dunit := lc**i * dunit
+ pi:=(diprev exquo di)::P
+ lffe:=[["sqfr",pi,i],:lffe]
+ dunit := dunit * di ** (i+1)
+ degree(ci)=0 => makeFR(dunit*ci,lffe)
+ redSqfr:=squareFree(divideExponents(ci,characteristic$P)::P)
+ lsnil:= [BumInSepFFE(ffe) for ffe in factorList redSqfr]
+ lffe:=append(lsnil,lffe)
+ makeFR(dunit*(unit redSqfr),lffe)
+
+@
+\section{package PSQFR PolynomialSquareFree}
+<<package PSQFR PolynomialSquareFree>>=
+)abbrev package PSQFR PolynomialSquareFree
+++ Author:
+++ Date Created:
+++ Date Last Updated: November 1993, (P.Gianni)
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package computes square-free decomposition of multivariate
+++ polynomials over a coefficient ring which is an arbitrary gcd domain.
+++ The requirement on the coefficient domain guarantees that the \spadfun{content} can be
+++ removed so that factors will be primitive as well as square-free.
+++ Over an infinite ring of finite characteristic,it may not be possible to
+++ guarantee that the factors are square-free.
+
+PolynomialSquareFree(VarSet:OrderedSet,E,RC:GcdDomain,P):C == T where
+ E:OrderedAbelianMonoidSup
+ P:PolynomialCategory(RC,E,VarSet)
+
+ C == with
+ squareFree : P -> Factored P
+ ++ squareFree(p) returns the square-free factorization of the
+ ++ polynomial p. Each factor has no repeated roots, and the
+ ++ factors are pairwise relatively prime.
+
+ T == add
+ SUP ==> SparseUnivariatePolynomial(P)
+ NNI ==> NonNegativeInteger
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FF ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
+
+ finSqFr : (P,List VarSet) -> Factored P
+ pthPower : P -> Factored P
+ pPolRoot : P -> P
+ putPth : P -> P
+
+ chrc:=characteristic$RC
+
+ if RC has CharacteristicNonZero then
+ -- find the p-th root of a polynomial
+ pPolRoot(f:P) : P ==
+ lvar:=variables f
+ empty? lvar => f
+ mv:=first lvar
+ uf:=univariate(f,mv)
+ uf:=divideExponents(uf,chrc)::SUP
+ uf:=map(pPolRoot,uf)
+ multivariate(uf,mv)
+
+ -- substitute variables with their p-th power
+ putPth(f:P) : P ==
+ lvar:=variables f
+ empty? lvar => f
+ mv:=first lvar
+ uf:=univariate(f,mv)
+ uf:=multiplyExponents(uf,chrc)::SUP
+ uf:=map(putPth,uf)
+ multivariate(uf,mv)
+
+ -- the polynomial is a perfect power
+ pthPower(f:P) : Factored P ==
+ proot : P := 0
+ isSq : Boolean := false
+ if (g:=charthRoot f) case "failed" then proot:=pPolRoot(f)
+ else
+ proot := g :: P
+ isSq := true
+ psqfr:=finSqFr(proot,variables f)
+ isSq =>
+ makeFR((unit psqfr)**chrc,[[u.flg,u.fctr,
+ (u.xpnt)*chrc] for u in factorList psqfr])
+ makeFR((unit psqfr),[["nil",putPth u.fctr,u.xpnt]
+ for u in factorList psqfr])
+
+ -- compute the square free decomposition, finite characteristic case
+ finSqFr(f:P,lvar:List VarSet) : Factored P ==
+ empty? lvar => pthPower(f)
+ mv:=first lvar
+ lvar:=lvar.rest
+ differentiate(f,mv)=0 => finSqFr(f,lvar)
+ uf:=univariate(f,mv)
+ cont := content uf
+ cont1:P:=1
+ uf := (uf exquo cont)::SUP
+ squf := squareFree(uf)$UnivariatePolynomialSquareFree(P,SUP)
+ pfaclist:List FF :=[]
+ for u in factorList squf repeat
+ uexp:NNI:=(u.xpnt):NNI
+ u.flg = "sqfr" => -- the square free factor is OK
+ pfaclist:= cons([u.flg,multivariate(u.fctr,mv),uexp],
+ pfaclist)
+ --listfin1:= finSqFr(multivariate(u.fctr,mv),lvar)
+ listfin1:= squareFree multivariate(u.fctr,mv)
+ flistfin1:=[[uu.flg,uu.fctr,uu.xpnt*uexp]
+ for uu in factorList listfin1]
+ cont1:=cont1*((unit listfin1)**uexp)
+ pfaclist:=append(flistfin1,pfaclist)
+ cont:=cont*cont1
+ cont ^= 1 =>
+ sqp := squareFree cont
+ pfaclist:= append (factorList sqp,pfaclist)
+ makeFR(unit(sqp)*coefficient(unit squf,0),pfaclist)
+ makeFR(coefficient(unit squf,0),pfaclist)
+
+ squareFree(p:P) ==
+ mv:=mainVariable p
+ mv case "failed" => makeFR(p,[])$Factored(P)
+ characteristic$RC ^=0 => finSqFr(p,variables p)
+ up:=univariate(p,mv)
+ cont := content up
+ up := (up exquo cont)::SUP
+ squp := squareFree(up)$UnivariatePolynomialSquareFree(P,SUP)
+ pfaclist:List FF :=
+ [[u.flg,multivariate(u.fctr,mv),u.xpnt]
+ for u in factorList squp]
+ cont ^= 1 =>
+ sqp := squareFree cont
+ makeFR(unit(sqp)*coefficient(unit squp,0),
+ append(factorList sqp, pfaclist))
+ makeFR(coefficient(unit squp,0),pfaclist)
+
+@
+\section{package UPMP UnivariatePolynomialMultiplicationPackage}
+<<package UPMP UnivariatePolynomialMultiplicationPackage>>=
+)abbrev package UPMP UnivariatePolynomialMultiplicationPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 14.08.2000
+++ Description:
+++ This package implements Karatsuba's trick for multiplying
+++ (large) univariate polynomials. It could be improved with
+++ a version doing the work on place and also with a special
+++ case for squares. We've done this in Basicmath, but we
+++ believe that this out of the scope of AXIOM.
+
+UnivariatePolynomialMultiplicationPackage(R: Ring, U: UnivariatePolynomialCategory(R)): C == T
+ where
+ HL ==> Record(quotient:U,remainder:U)
+ C == with
+ noKaratsuba: (U, U) -> U
+ ++ \spad{noKaratsuba(a,b)} returns \spad{a*b} without
+ ++ using Karatsuba's trick at all.
+ karatsubaOnce: (U, U) -> U
+ ++ \spad{karatsuba(a,b)} returns \spad{a*b} by applying
+ ++ Karatsuba's trick once. The other multiplications
+ ++ are performed by calling \spad{*} from \spad{U}.
+ karatsuba: (U, U, NonNegativeInteger, NonNegativeInteger) -> U;
+ ++ \spad{karatsuba(a,b,l,k)} returns \spad{a*b} by applying
+ ++ Karatsuba's trick provided that both \spad{a} and \spad{b}
+ ++ have at least \spad{l} terms and \spad{k > 0} holds
+ ++ and by calling \spad{noKaratsuba} otherwise. The other
+ ++ multiplications are performed by recursive calls with
+ ++ the same third argument and \spad{k-1} as fourth argument.
+
+ T == add
+ noKaratsuba(a,b) ==
+ zero? a => a
+ zero? b => b
+ zero?(degree(a)) => leadingCoefficient(a) * b
+ zero?(degree(b)) => a * leadingCoefficient(b)
+ lu: List(U) := reverse monomials(a)
+ res: U := 0;
+ for u in lu repeat
+ res := pomopo!(res, leadingCoefficient(u), degree(u), b)
+ res
+ karatsubaOnce(a:U,b:U): U ==
+ da := minimumDegree(a)
+ db := minimumDegree(b)
+ if not zero? da then a := shiftRight(a,da)
+ if not zero? db then b := shiftRight(b,db)
+ d := da + db
+ n: NonNegativeInteger := min(degree(a),degree(b)) quo 2
+ rec: HL := karatsubaDivide(a, n)
+ ha := rec.quotient
+ la := rec.remainder
+ rec := karatsubaDivide(b, n)
+ hb := rec.quotient
+ lb := rec.remainder
+ w: U := (ha - la) * (lb - hb)
+ u: U := la * lb
+ v: U := ha * hb
+ w := w + (u + v)
+ w := shiftLeft(w,n) + u
+ zero? d => shiftLeft(v,2*n) + w
+ shiftLeft(v,2*n + d) + shiftLeft(w,d)
+ karatsuba(a:U,b:U,l:NonNegativeInteger,k:NonNegativeInteger): U ==
+ zero? k => noKaratsuba(a,b)
+ degree(a) < l => noKaratsuba(a,b)
+ degree(b) < l => noKaratsuba(a,b)
+ numberOfMonomials(a) < l => noKaratsuba(a,b)
+ numberOfMonomials(b) < l => noKaratsuba(a,b)
+ da := minimumDegree(a)
+ db := minimumDegree(b)
+ if not zero? da then a := shiftRight(a,da)
+ if not zero? db then b := shiftRight(b,db)
+ d := da + db
+ n: NonNegativeInteger := min(degree(a),degree(b)) quo 2
+ k := subtractIfCan(k,1)::NonNegativeInteger
+ rec: HL := karatsubaDivide(a, n)
+ ha := rec.quotient
+ la := rec.remainder
+ rec := karatsubaDivide(b, n)
+ hb := rec.quotient
+ lb := rec.remainder
+ w: U := karatsuba(ha - la, lb - hb, l, k)
+ u: U := karatsuba(la, lb, l, k)
+ v: U := karatsuba(ha, hb, l, k)
+ w := w + (u + v)
+ w := shiftLeft(w,n) + u
+ zero? d => shiftLeft(v,2*n) + w
+ shiftLeft(v,2*n + d) + shiftLeft(w,d)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain FM FreeModule>>
+<<domain PR PolynomialRing>>
+<<package UPSQFREE UnivariatePolynomialSquareFree>>
+<<package PSQFR PolynomialSquareFree>>
+<<package UPMP UnivariatePolynomialMultiplicationPackage>>
+<<domain SUP SparseUnivariatePolynomial>>
+<<package SUP2 SparseUnivariatePolynomialFunctions2>>
+<<domain UP UnivariatePolynomial>>
+<<package UP2 UnivariatePolynomialFunctions2>>
+<<package POLY2UP PolynomialToUnivariatePolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/polycat.spad.pamphlet b/src/algebra/polycat.spad.pamphlet
new file mode 100644
index 00000000..01cbbccc
--- /dev/null
+++ b/src/algebra/polycat.spad.pamphlet
@@ -0,0 +1,4785 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra polycat.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category AMR AbelianMonoidRing}
+<<category AMR AbelianMonoidRing>>=
+)abbrev category AMR AbelianMonoidRing
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Abelian monoid ring elements (not necessarily of finite support)
+++ of this ring are of the form formal SUM (r_i * e_i)
+++ where the r_i are coefficents and the e_i, elements of the
+++ ordered abelian monoid, are thought of as exponents or monomials.
+++ The monomials commute with each other, and with
+++ the coefficients (which themselves may or may not be commutative).
+++ See \spadtype{FiniteAbelianMonoidRing} for the case of finite support
+++ a useful common model for polynomials and power series.
+++ Conceptually at least, only the non-zero terms are ever operated on.
+
+AbelianMonoidRing(R:Ring, E:OrderedAbelianMonoid): Category ==
+ Join(Ring,BiModule(R,R)) with
+ leadingCoefficient: % -> R
+ ++ leadingCoefficient(p) returns the coefficient highest degree term of p.
+ leadingMonomial: % -> %
+ ++ leadingMonomial(p) returns the monomial of p with the highest degree.
+ degree: % -> E
+ ++ degree(p) returns the maximum of the exponents of the terms of p.
+ map: (R -> R, %) -> %
+ ++ map(fn,u) maps function fn onto the coefficients
+ ++ of the non-zero monomials of u.
+ monomial?: % -> Boolean
+ ++ monomial?(p) tests if p is a single monomial.
+ monomial: (R,E) -> %
+ ++ monomial(r,e) makes a term from a coefficient r and an exponent e.
+ reductum: % -> %
+ ++ reductum(u) returns u minus its leading monomial
+ ++ returns zero if handed the zero element.
+ coefficient: (%,E) -> R
+ ++ coefficient(p,e) extracts the coefficient of the monomial with
+ ++ exponent e from polynomial p, or returns zero if exponent is not present.
+ if R has Field then "/": (%,R) -> %
+ ++ p/c divides p by the coefficient c.
+ if R has CommutativeRing then
+ CommutativeRing
+ Algebra R
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has IntegralDomain then IntegralDomain
+ if R has Algebra Fraction Integer then Algebra Fraction Integer
+ add
+ monomial? x == zero? reductum x
+
+ map(fn:R -> R, x: %) ==
+ -- this default definition assumes that reductum is cheap
+ zero? x => 0
+ r:=fn leadingCoefficient x
+ zero? r => map(fn,reductum x)
+ monomial(r, degree x) + map(fn,reductum x)
+
+ if R has Algebra Fraction Integer then
+ q:Fraction(Integer) * p:% == map(q * #1, p)
+
+@
+\section{category FAMR FiniteAbelianMonoidRing}
+<<category FAMR FiniteAbelianMonoidRing>>=
+)abbrev category FAMR FiniteAbelianMonoidRing
+++ Author:
+++ Date Created:
+++ Date Last Updated: 14.08.2000 Exported pomopo! and binomThmExpt [MMM]
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: This category is
+++ similar to AbelianMonoidRing, except that the sum is assumed to be finite.
+++ It is a useful model for polynomials,
+++ but is somewhat more general.
+
+FiniteAbelianMonoidRing(R:Ring, E:OrderedAbelianMonoid): Category ==
+ Join(AbelianMonoidRing(R,E),FullyRetractableTo R) with
+ ground?: % -> Boolean
+ ++ ground?(p) tests if polynomial p is a member of the coefficient ring.
+ -- can't be defined earlier, since a power series
+ -- might not know if there were other terms or not
+ ground: % -> R
+ ++ ground(p) retracts polynomial p to the coefficient ring.
+ coefficients: % -> List R
+ ++ coefficients(p) gives the list of non-zero coefficients of polynomial p.
+ numberOfMonomials: % -> NonNegativeInteger
+ ++ numberOfMonomials(p) gives the number of non-zero monomials in polynomial p.
+ minimumDegree: % -> E
+ ++ minimumDegree(p) gives the least exponent of a non-zero term of polynomial p.
+ ++ Error: if applied to 0.
+ mapExponents: (E -> E, %) -> %
+ ++ mapExponents(fn,u) maps function fn onto the exponents
+ ++ of the non-zero monomials of polynomial u.
+ pomopo!: (%,R,E,%) -> %
+ ++ \spad{pomopo!(p1,r,e,p2)} returns \spad{p1 + monomial(e,r) * p2}
+ ++ and may use \spad{p1} as workspace. The constaant \spad{r} is
+ ++ assumed to be nonzero.
+ if R has CommutativeRing then
+ binomThmExpt: (%,%,NonNegativeInteger) -> %
+ ++ \spad{binomThmExpt(p,q,n)} returns \spad{(x+y)^n}
+ ++ by means of the binomial theorem trick.
+ if R has IntegralDomain then
+ "exquo": (%,R) -> Union(%,"failed")
+ ++ exquo(p,r) returns the exact quotient of polynomial p by r, or "failed"
+ ++ if none exists.
+ if R has GcdDomain then
+ content: % -> R
+ ++ content(p) gives the gcd of the coefficients of polynomial p.
+ primitivePart: % -> %
+ ++ primitivePart(p) returns the unit normalized form of polynomial p
+ ++ divided by the content of p.
+ add
+ pomopo!(p1,r,e,p2) == p1 + r * mapExponents(#1+e,p2)
+
+ if R has CommutativeRing then
+ binomThmExpt(x,y,nn) ==
+ nn = 0 => 1$%
+ ans,xn,yn: %
+ bincoef: Integer
+ powl: List(%):= [x]
+ for i in 2..nn repeat powl:=[x * powl.first, :powl]
+ yn:=y; ans:=powl.first; i:=1; bincoef:=nn
+ for xn in powl.rest repeat
+ ans:= bincoef * xn * yn + ans
+ bincoef:= (nn-i) * bincoef quo (i+1); i:= i+1
+ -- last I and BINCOEF unused
+ yn:= y * yn
+ ans + yn
+ ground? x ==
+ retractIfCan(x)@Union(R,"failed") case "failed" => false
+ true
+ ground x == retract(x)@R
+ mapExponents (fn:E -> E, x: %) ==
+ -- this default definition assumes that reductum is cheap
+ zero? x => 0
+ monomial(leadingCoefficient x,fn degree x)+mapExponents(fn,reductum x)
+ coefficients x ==
+ zero? x => empty()
+ concat(leadingCoefficient x, coefficients reductum x)
+
+ if R has Field then
+ x/r == map(#1/r,x)
+ if R has IntegralDomain then
+ x exquo r ==
+ -- probably not a very good definition in most special cases
+ zero? x => 0
+ ans:% :=0
+ t:=leadingCoefficient x exquo r
+ while not (t case "failed") and not zero? x repeat
+ ans:=ans+monomial(t::R,degree x)
+ x:=reductum x
+ if not zero? x then t:=leadingCoefficient x exquo r
+ t case "failed" => "failed"
+ ans
+ if R has GcdDomain then
+ content x == -- this assumes reductum is cheap
+ zero? x => 0
+ r:=leadingCoefficient x
+ x:=reductum x
+-- while not zero? x and not one? r repeat
+ while not zero? x and not (r = 1) repeat
+ r:=gcd(r,leadingCoefficient x)
+ x:=reductum x
+ r
+ primitivePart x ==
+ zero? x => x
+ c := content x
+ unitCanonical((x exquo c)::%)
+
+@
+\section{category POLYCAT PolynomialCategory}
+<<category POLYCAT PolynomialCategory>>=
+)abbrev category POLYCAT PolynomialCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, monomial, coefficient, differentiate, eval
+++ Related Constructors: Polynomial, DistributedMultivariatePolynomial
+++ Also See: UnivariatePolynomialCategory
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category for general multi-variate polynomials over a ring
+++ R, in variables from VarSet, with exponents from the
+++ \spadtype{OrderedAbelianMonoidSup}.
+
+PolynomialCategory(R:Ring, E:OrderedAbelianMonoidSup, VarSet:OrderedSet):
+ Category ==
+ Join(PartialDifferentialRing VarSet, FiniteAbelianMonoidRing(R, E),
+ Evalable %, InnerEvalable(VarSet, R),
+ InnerEvalable(VarSet, %), RetractableTo VarSet,
+ FullyLinearlyExplicitRingOver R) with
+ -- operations
+ degree : (%,VarSet) -> NonNegativeInteger
+ ++ degree(p,v) gives the degree of polynomial p with respect to the variable v.
+ degree : (%,List(VarSet)) -> List(NonNegativeInteger)
+ ++ degree(p,lv) gives the list of degrees of polynomial p
+ ++ with respect to each of the variables in the list lv.
+ coefficient: (%,VarSet,NonNegativeInteger) -> %
+ ++ coefficient(p,v,n) views the polynomial p as a univariate
+ ++ polynomial in v and returns the coefficient of the \spad{v**n} term.
+ coefficient: (%,List VarSet,List NonNegativeInteger) -> %
+ ++ coefficient(p, lv, ln) views the polynomial p as a polynomial
+ ++ in the variables of lv and returns the coefficient of the term
+ ++ \spad{lv**ln}, i.e. \spad{prod(lv_i ** ln_i)}.
+ monomials: % -> List %
+ ++ monomials(p) returns the list of non-zero monomials of polynomial p, i.e.
+ ++ \spad{monomials(sum(a_(i) X^(i))) = [a_(1) X^(1),...,a_(n) X^(n)]}.
+ univariate : (%,VarSet) -> SparseUnivariatePolynomial(%)
+ ++ univariate(p,v) converts the multivariate polynomial p
+ ++ into a univariate polynomial in v, whose coefficients are still
+ ++ multivariate polynomials (in all the other variables).
+ univariate : % -> SparseUnivariatePolynomial(R)
+ ++ univariate(p) converts the multivariate polynomial p,
+ ++ which should actually involve only one variable,
+ ++ into a univariate polynomial
+ ++ in that variable, whose coefficients are in the ground ring.
+ ++ Error: if polynomial is genuinely multivariate
+ mainVariable : % -> Union(VarSet,"failed")
+ ++ mainVariable(p) returns the biggest variable which actually
+ ++ occurs in the polynomial p, or "failed" if no variables are
+ ++ present.
+ ++ fails precisely if polynomial satisfies ground?
+ minimumDegree : (%,VarSet) -> NonNegativeInteger
+ ++ minimumDegree(p,v) gives the minimum degree of polynomial p
+ ++ with respect to v, i.e. viewed a univariate polynomial in v
+ minimumDegree : (%,List(VarSet)) -> List(NonNegativeInteger)
+ ++ minimumDegree(p, lv) gives the list of minimum degrees of the
+ ++ polynomial p with respect to each of the variables in the list lv
+ monicDivide : (%,%,VarSet) -> Record(quotient:%,remainder:%)
+ ++ monicDivide(a,b,v) divides the polynomial a by the polynomial b,
+ ++ with each viewed as a univariate polynomial in v returning
+ ++ both the quotient and remainder.
+ ++ Error: if b is not monic with respect to v.
+ monomial : (%,VarSet,NonNegativeInteger) -> %
+ ++ monomial(a,x,n) creates the monomial \spad{a*x**n} where \spad{a} is
+ ++ a polynomial, x is a variable and n is a nonnegative integer.
+ monomial : (%,List VarSet,List NonNegativeInteger) -> %
+ ++ monomial(a,[v1..vn],[e1..en]) returns \spad{a*prod(vi**ei)}.
+ multivariate : (SparseUnivariatePolynomial(R),VarSet) -> %
+ ++ multivariate(sup,v) converts an anonymous univariable
+ ++ polynomial sup to a polynomial in the variable v.
+ multivariate : (SparseUnivariatePolynomial(%),VarSet) -> %
+ ++ multivariate(sup,v) converts an anonymous univariable
+ ++ polynomial sup to a polynomial in the variable v.
+ isPlus: % -> Union(List %, "failed")
+ ++ isPlus(p) returns \spad{[m1,...,mn]} if polynomial \spad{p = m1 + ... + mn} and
+ ++ \spad{n >= 2} and each mi is a nonzero monomial.
+ isTimes: % -> Union(List %, "failed")
+ ++ isTimes(p) returns \spad{[a1,...,an]} if polynomial \spad{p = a1 ... an}
+ ++ and \spad{n >= 2}, and, for each i, ai is either a nontrivial constant in R or else of the
+ ++ form \spad{x**e}, where \spad{e > 0} is an integer and x in a member of VarSet.
+ isExpt: % -> Union(Record(var:VarSet, exponent:NonNegativeInteger),_
+ "failed")
+ ++ isExpt(p) returns \spad{[x, n]} if polynomial p has the form \spad{x**n} and \spad{n > 0}.
+ totalDegree : % -> NonNegativeInteger
+ ++ totalDegree(p) returns the largest sum over all monomials
+ ++ of all exponents of a monomial.
+ totalDegree : (%,List VarSet) -> NonNegativeInteger
+ ++ totalDegree(p, lv) returns the maximum sum (over all monomials of polynomial p)
+ ++ of the variables in the list lv.
+ variables : % -> List(VarSet)
+ ++ variables(p) returns the list of those variables actually
+ ++ appearing in the polynomial p.
+ primitiveMonomials: % -> List %
+ ++ primitiveMonomials(p) gives the list of monomials of the
+ ++ polynomial p with their coefficients removed.
+ ++ Note: \spad{primitiveMonomials(sum(a_(i) X^(i))) = [X^(1),...,X^(n)]}.
+ if R has OrderedSet then OrderedSet
+ -- OrderedRing view removed to allow EXPR to define abs
+ --if R has OrderedRing then OrderedRing
+ if (R has ConvertibleTo InputForm) and
+ (VarSet has ConvertibleTo InputForm) then
+ ConvertibleTo InputForm
+ if (R has ConvertibleTo Pattern Integer) and
+ (VarSet has ConvertibleTo Pattern Integer) then
+ ConvertibleTo Pattern Integer
+ if (R has ConvertibleTo Pattern Float) and
+ (VarSet has ConvertibleTo Pattern Float) then
+ ConvertibleTo Pattern Float
+ if (R has PatternMatchable Integer) and
+ (VarSet has PatternMatchable Integer) then
+ PatternMatchable Integer
+ if (R has PatternMatchable Float) and
+ (VarSet has PatternMatchable Float) then
+ PatternMatchable Float
+ if R has CommutativeRing then
+ resultant : (%,%,VarSet) -> %
+ ++ resultant(p,q,v) returns the resultant of the polynomials
+ ++ p and q with respect to the variable v.
+ discriminant : (%,VarSet) -> %
+ ++ discriminant(p,v) returns the disriminant of the polynomial p
+ ++ with respect to the variable v.
+ if R has GcdDomain then
+ GcdDomain
+ content: (%,VarSet) -> %
+ ++ content(p,v) is the gcd of the coefficients of the polynomial p
+ ++ when p is viewed as a univariate polynomial with respect to the
+ ++ variable v.
+ ++ Thus, for polynomial 7*x**2*y + 14*x*y**2, the gcd of the
+ ++ coefficients with respect to x is 7*y.
+ primitivePart: % -> %
+ ++ primitivePart(p) returns the unitCanonical associate of the
+ ++ polynomial p with its content divided out.
+ primitivePart: (%,VarSet) -> %
+ ++ primitivePart(p,v) returns the unitCanonical associate of the
+ ++ polynomial p with its content with respect to the variable v
+ ++ divided out.
+ squareFree: % -> Factored %
+ ++ squareFree(p) returns the square free factorization of the
+ ++ polynomial p.
+ squareFreePart: % -> %
+ ++ squareFreePart(p) returns product of all the irreducible factors
+ ++ of polynomial p each taken with multiplicity one.
+
+ -- assertions
+ if R has canonicalUnitNormal then canonicalUnitNormal
+ ++ we can choose a unique representative for each
+ ++ associate class.
+ ++ This normalization is chosen to be normalization of
+ ++ leading coefficient (by default).
+ if R has PolynomialFactorizationExplicit then
+ PolynomialFactorizationExplicit
+ add
+ p:%
+ v:VarSet
+ ln:List NonNegativeInteger
+ lv:List VarSet
+ n:NonNegativeInteger
+ pp,qq:SparseUnivariatePolynomial %
+ eval(p:%, l:List Equation %) ==
+ empty? l => p
+ for e in l repeat
+ retractIfCan(lhs e)@Union(VarSet,"failed") case "failed" =>
+ error "cannot find a variable to evaluate"
+ lvar:=[retract(lhs e)@VarSet for e in l]
+ eval(p, lvar,[rhs e for e in l]$List(%))
+ monomials p ==
+-- zero? p => empty()
+-- concat(leadingMonomial p, monomials reductum p)
+-- replaced by sequential version for efficiency, by WMSIT, 7/30/90
+ ml:= empty$List(%)
+ while p ^= 0 repeat
+ ml:=concat(leadingMonomial p, ml)
+ p:= reductum p
+ reverse ml
+ isPlus p ==
+ empty? rest(l := monomials p) => "failed"
+ l
+ isTimes p ==
+ empty?(lv := variables p) or not monomial? p => "failed"
+ l := [monomial(1, v, degree(p, v)) for v in lv]
+-- one?(r := leadingCoefficient p) =>
+ ((r := leadingCoefficient p) = 1) =>
+ empty? rest lv => "failed"
+ l
+ concat(r::%, l)
+ isExpt p ==
+ (u := mainVariable p) case "failed" => "failed"
+ p = monomial(1, u::VarSet, d := degree(p, u::VarSet)) =>
+ [u::VarSet, d]
+ "failed"
+ coefficient(p,v,n) == coefficient(univariate(p,v),n)
+ coefficient(p,lv,ln) ==
+ empty? lv =>
+ empty? ln => p
+ error "mismatched lists in coefficient"
+ empty? ln => error "mismatched lists in coefficient"
+ coefficient(coefficient(univariate(p,first lv),first ln),
+ rest lv,rest ln)
+ monomial(p,lv,ln) ==
+ empty? lv =>
+ empty? ln => p
+ error "mismatched lists in monomial"
+ empty? ln => error "mismatched lists in monomial"
+ monomial(monomial(p,first lv, first ln),rest lv, rest ln)
+ retract(p:%):VarSet ==
+ q := mainVariable(p)::VarSet
+ q::% = p => q
+ error "Polynomial is not a single variable"
+ retractIfCan(p:%):Union(VarSet, "failed") ==
+ ((q := mainVariable p) case VarSet) and (q::VarSet::% = p) => q
+ "failed"
+ mkPrim(p:%):% == monomial(1,degree p)
+ primitiveMonomials p == [mkPrim q for q in monomials p]
+ totalDegree p ==
+ ground? p => 0
+ u := univariate(p, mainVariable(p)::VarSet)
+ d: NonNegativeInteger := 0
+ while u ^= 0 repeat
+ d := max(d, degree u + totalDegree leadingCoefficient u)
+ u := reductum u
+ d
+ totalDegree(p,lv) ==
+ ground? p => 0
+ u := univariate(p, v:=(mainVariable(p)::VarSet))
+ d: NonNegativeInteger := 0
+ w: NonNegativeInteger := 0
+ if member?(v, lv) then w:=1
+ while u ^= 0 repeat
+ d := max(d, w*(degree u) + totalDegree(leadingCoefficient u,lv))
+ u := reductum u
+ d
+
+ if R has CommutativeRing then
+ resultant(p1,p2,mvar) ==
+ resultant(univariate(p1,mvar),univariate(p2,mvar))
+ discriminant(p,var) ==
+ discriminant(univariate(p,var))
+
+ if R has IntegralDomain then
+ allMonoms(l:List %):List(%) ==
+ removeDuplicates_! concat [primitiveMonomials p for p in l]
+ P2R(p:%, b:List E, n:NonNegativeInteger):Vector(R) ==
+ w := new(n, 0)$Vector(R)
+ for i in minIndex w .. maxIndex w for bj in b repeat
+ qsetelt_!(w, i, coefficient(p, bj))
+ w
+ eq2R(l:List %, b:List E):Matrix(R) ==
+ matrix [[coefficient(p, bj) for p in l] for bj in b]
+ reducedSystem(m:Matrix %):Matrix(R) ==
+ l := listOfLists m
+ b := removeDuplicates_!
+ concat [allMonoms r for r in l]$List(List(%))
+ d := [degree bj for bj in b]
+ mm := eq2R(first l, d)
+ l := rest l
+ while not empty? l repeat
+ mm := vertConcat(mm, eq2R(first l, d))
+ l := rest l
+ mm
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix R, vec:Vector R) ==
+ l := listOfLists m
+ r := entries v
+ b : List % := removeDuplicates_! concat(allMonoms r,
+ concat [allMonoms s for s in l]$List(List(%)))
+ d := [degree bj for bj in b]
+ n := #d
+ mm := eq2R(first l, d)
+ w := P2R(first r, d, n)
+ l := rest l
+ r := rest r
+ while not empty? l repeat
+ mm := vertConcat(mm, eq2R(first l, d))
+ w := concat(w, P2R(first r, d, n))
+ l := rest l
+ r := rest r
+ [mm, w]
+
+ if R has PolynomialFactorizationExplicit then
+ -- we might be in trouble if its actually only
+ -- a univariate polynomial category - have to remember to
+ -- over-ride these in UnivariatePolynomialCategory
+ PFBR ==>PolynomialFactorizationByRecursion(R,E,VarSet,%)
+ gcdPolynomial(pp,qq) ==
+ gcdPolynomial(pp,qq)$GeneralPolynomialGcdPackage(E,VarSet,R,%)
+ solveLinearPolynomialEquation(lpp,pp) ==
+ solveLinearPolynomialEquationByRecursion(lpp,pp)$PFBR
+ factorPolynomial(pp) ==
+ factorByRecursion(pp)$PFBR
+ factorSquareFreePolynomial(pp) ==
+ factorSquareFreeByRecursion(pp)$PFBR
+ factor p ==
+ v:Union(VarSet,"failed"):=mainVariable p
+ v case "failed" =>
+ ansR:=factor leadingCoefficient p
+ makeFR(unit(ansR)::%,
+ [[w.flg,w.fctr::%,w.xpnt] for w in factorList ansR])
+ up:SparseUnivariatePolynomial %:=univariate(p,v)
+ ansSUP:=factorByRecursion(up)$PFBR
+ makeFR(multivariate(unit(ansSUP),v),
+ [[ww.flg,multivariate(ww.fctr,v),ww.xpnt]
+ for ww in factorList ansSUP])
+ if R has CharacteristicNonZero then
+ mat: Matrix %
+ conditionP mat ==
+ ll:=listOfLists transpose mat -- hence each list corresponds to a
+ -- column, i.e. to one variable
+ llR:List List R := [ empty() for z in first ll]
+ monslist:List List % := empty()
+ ch:=characteristic()$%
+ for l in ll repeat
+ mons:= "setUnion"/[primitiveMonomials u for u in l]
+ redmons:List % :=[]
+ for m in mons repeat
+ vars:=variables m
+ degs:=degree(m,vars)
+ deg1:List NonNegativeInteger
+ deg1:=[ ((nd:=d:Integer exquo ch:Integer)
+ case "failed" => return "failed" ;
+ nd::Integer::NonNegativeInteger)
+ for d in degs ]
+ redmons:=[monomial(1,vars,deg1),:redmons]
+ llR:=[[ground coefficient(u,vars,degs),:v] for u in l for v in llR]
+ monslist:=[redmons,:monslist]
+ ans:=conditionP transpose matrix llR
+ ans case "failed" => "failed"
+ i:NonNegativeInteger:=0
+ [ +/[m*(ans.(i:=i+1))::% for m in mons ]
+ for mons in monslist]
+
+ if R has CharacteristicNonZero then
+ charthRootlv: (%,List VarSet,NonNegativeInteger) -> Union(%,"failed")
+ charthRoot p ==
+ vars:= variables p
+ empty? vars =>
+ ans := charthRoot ground p
+ ans case "failed" => "failed"
+ ans::R::%
+ ch:=characteristic()$%
+ charthRootlv(p,vars,ch)
+ charthRootlv(p,vars,ch) ==
+ empty? vars =>
+ ans := charthRoot ground p
+ ans case "failed" => "failed"
+ ans::R::%
+ v:=first vars
+ vars:=rest vars
+ d:=degree(p,v)
+ ans:% := 0
+ while (d>0) repeat
+ (dd:=(d::Integer exquo ch::Integer)) case "failed" =>
+ return "failed"
+ cp:=coefficient(p,v,d)
+ p:=p-monomial(cp,v,d)
+ ansx:=charthRootlv(cp,vars,ch)
+ ansx case "failed" => return "failed"
+ d:=degree(p,v)
+ ans:=ans+monomial(ansx,v,dd::Integer::NonNegativeInteger)
+ ansx:=charthRootlv(p,vars,ch)
+ ansx case "failed" => return "failed"
+ return ans+ansx
+
+ monicDivide(p1,p2,mvar) ==
+ result:=monicDivide(univariate(p1,mvar),univariate(p2,mvar))
+ [multivariate(result.quotient,mvar),
+ multivariate(result.remainder,mvar)]
+
+
+ if R has GcdDomain then
+ if R has EuclideanDomain and R has CharacteristicZero then
+ squareFree p == squareFree(p)$MultivariateSquareFree(E,VarSet,R,%)
+ else
+ squareFree p == squareFree(p)$PolynomialSquareFree(VarSet,E,R,%)
+ squareFreePart p ==
+ unit(s := squareFree p) * */[f.factor for f in factors s]
+ content(p,v) == content univariate(p,v)
+ primitivePart p ==
+ unitNormal((p exquo content p) ::%).canonical
+ primitivePart(p,v) ==
+ unitNormal((p exquo content(p,v)) ::%).canonical
+ if R has OrderedSet then
+ p:% < q:% ==
+ (dp:= degree p) < (dq := degree q) => (leadingCoefficient q) > 0
+ dq < dp => (leadingCoefficient p) < 0
+ leadingCoefficient(p - q) < 0
+ if (R has PatternMatchable Integer) and
+ (VarSet has PatternMatchable Integer) then
+ patternMatch(p:%, pat:Pattern Integer,
+ l:PatternMatchResult(Integer, %)) ==
+ patternMatch(p, pat,
+ l)$PatternMatchPolynomialCategory(Integer,E,VarSet,R,%)
+ if (R has PatternMatchable Float) and
+ (VarSet has PatternMatchable Float) then
+ patternMatch(p:%, pat:Pattern Float,
+ l:PatternMatchResult(Float, %)) ==
+ patternMatch(p, pat,
+ l)$PatternMatchPolynomialCategory(Float,E,VarSet,R,%)
+
+ if (R has ConvertibleTo Pattern Integer) and
+ (VarSet has ConvertibleTo Pattern Integer) then
+ convert(x:%):Pattern(Integer) ==
+ map(convert, convert,
+ x)$PolynomialCategoryLifting(E,VarSet,R,%,Pattern Integer)
+ if (R has ConvertibleTo Pattern Float) and
+ (VarSet has ConvertibleTo Pattern Float) then
+ convert(x:%):Pattern(Float) ==
+ map(convert, convert,
+ x)$PolynomialCategoryLifting(E, VarSet, R, %, Pattern Float)
+ if (R has ConvertibleTo InputForm) and
+ (VarSet has ConvertibleTo InputForm) then
+ convert(p:%):InputForm ==
+ map(convert, convert,
+ p)$PolynomialCategoryLifting(E,VarSet,R,%,InputForm)
+
+@
+\section{POLYCAT.lsp BOOTSTRAP}
+{\bf POLYCAT} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf POLYCAT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf POLYCAT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<POLYCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |PolynomialCategory;CAT| (QUOTE NIL))
+
+(SETQ |PolynomialCategory;AL| (QUOTE NIL))
+
+(DEFUN |PolynomialCategory| (|&REST| #1=#:G101841 |&AUX| #2=#:G101839)
+ (DSETQ #2# #1#)
+ (LET (#3=#:G101840)
+ (COND
+ ((SETQ #3# (|assoc| (|devaluateList| #2#) |PolynomialCategory;AL|))
+ (CDR #3#))
+ (T
+ (SETQ |PolynomialCategory;AL|
+ (|cons5|
+ (CONS
+ (|devaluateList| #2#)
+ (SETQ #3# (APPLY (FUNCTION |PolynomialCategory;|) #2#)))
+ |PolynomialCategory;AL|))
+ #3#))))
+
+(DEFUN |PolynomialCategory;| (|t#1| |t#2| |t#3|)
+ (PROG (#1=#:G101838)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR
+ (QUOTE (|t#1| |t#2| |t#3|))
+ (LIST
+ (|devaluate| |t#1|)
+ (|devaluate| |t#2|)
+ (|devaluate| |t#3|)))
+ (COND
+ (|PolynomialCategory;CAT|)
+ ((QUOTE T)
+ (LETT |PolynomialCategory;CAT|
+ (|Join|
+ (|PartialDifferentialRing| (QUOTE |t#3|))
+ (|FiniteAbelianMonoidRing| (QUOTE |t#1|) (QUOTE |t#2|))
+ (|Evalable| (QUOTE |$|))
+ (|InnerEvalable| (QUOTE |t#3|) (QUOTE |t#1|))
+ (|InnerEvalable| (QUOTE |t#3|) (QUOTE |$|))
+ (|RetractableTo| (QUOTE |t#3|))
+ (|FullyLinearlyExplicitRingOver| (QUOTE |t#1|))
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|degree| ((|NonNegativeInteger|) |$| |t#3|)) T)
+ ((|degree|
+ ((|List| (|NonNegativeInteger|))
+ |$|
+ (|List| |t#3|))) T)
+ ((|coefficient|
+ (|$| |$| |t#3| (|NonNegativeInteger|))) T)
+ ((|coefficient|
+ (|$|
+ |$|
+ (|List| |t#3|)
+ (|List| (|NonNegativeInteger|)))) T)
+ ((|monomials| ((|List| |$|) |$|)) T)
+ ((|univariate|
+ ((|SparseUnivariatePolynomial| |$|) |$| |t#3|)) T)
+ ((|univariate|
+ ((|SparseUnivariatePolynomial| |t#1|) |$|)) T)
+ ((|mainVariable| ((|Union| |t#3| "failed") |$|)) T)
+ ((|minimumDegree|
+ ((|NonNegativeInteger|) |$| |t#3|)) T)
+ ((|minimumDegree|
+ ((|List| (|NonNegativeInteger|))
+ |$|
+ (|List| |t#3|))) T)
+ ((|monicDivide|
+ ((|Record|
+ (|:| |quotient| |$|)
+ (|:| |remainder| |$|))
+ |$|
+ |$|
+ |t#3|)) T)
+ ((|monomial| (|$| |$| |t#3| (|NonNegativeInteger|))) T)
+ ((|monomial|
+ (|$|
+ |$|
+ (|List| |t#3|)
+ (|List| (|NonNegativeInteger|)))) T)
+ ((|multivariate|
+ (|$| (|SparseUnivariatePolynomial| |t#1|) |t#3|)) T)
+ ((|multivariate|
+ (|$| (|SparseUnivariatePolynomial| |$|) |t#3|)) T)
+ ((|isPlus| ((|Union| (|List| |$|) "failed") |$|)) T)
+ ((|isTimes| ((|Union| (|List| |$|) "failed") |$|)) T)
+ ((|isExpt|
+ ((|Union|
+ (|Record|
+ (|:| |var| |t#3|)
+ (|:| |exponent| (|NonNegativeInteger|)))
+ "failed")
+ |$|)) T)
+ ((|totalDegree| ((|NonNegativeInteger|) |$|)) T)
+ ((|totalDegree|
+ ((|NonNegativeInteger|) |$| (|List| |t#3|))) T)
+ ((|variables| ((|List| |t#3|) |$|)) T)
+ ((|primitiveMonomials| ((|List| |$|) |$|)) T)
+ ((|resultant| (|$| |$| |$| |t#3|))
+ (|has| |t#1| (|CommutativeRing|)))
+ ((|discriminant| (|$| |$| |t#3|))
+ (|has| |t#1| (|CommutativeRing|)))
+ ((|content| (|$| |$| |t#3|))
+ (|has| |t#1| (|GcdDomain|)))
+ ((|primitivePart| (|$| |$|))
+ (|has| |t#1| (|GcdDomain|)))
+ ((|primitivePart| (|$| |$| |t#3|))
+ (|has| |t#1| (|GcdDomain|)))
+ ((|squareFree| ((|Factored| |$|) |$|))
+ (|has| |t#1| (|GcdDomain|)))
+ ((|squareFreePart| (|$| |$|)) (
+ |has| |t#1| (|GcdDomain|)))))
+ (QUOTE (
+ ((|OrderedSet|) (|has| |t#1| (|OrderedSet|)))
+ ((|ConvertibleTo| (|InputForm|))
+ (AND
+ (|has| |t#3| (|ConvertibleTo| (|InputForm|)))
+ (|has| |t#1| (|ConvertibleTo| (|InputForm|)))))
+ ((|ConvertibleTo| (|Pattern| (|Integer|)))
+ (AND
+ (|has| |t#3|
+ (|ConvertibleTo| (|Pattern| (|Integer|))))
+ (|has| |t#1|
+ (|ConvertibleTo| (|Pattern| (|Integer|))))))
+ ((|ConvertibleTo| (|Pattern| (|Float|)))
+ (AND
+ (|has| |t#3|
+ (|ConvertibleTo| (|Pattern| (|Float|))))
+ (|has| |t#1|
+ (|ConvertibleTo| (|Pattern| (|Float|))))))
+ ((|PatternMatchable| (|Integer|))
+ (AND
+ (|has| |t#3| (|PatternMatchable| (|Integer|)))
+ (|has| |t#1| (|PatternMatchable| (|Integer|)))))
+ ((|PatternMatchable| (|Float|))
+ (AND
+ (|has| |t#3| (|PatternMatchable| (|Float|)))
+ (|has| |t#1| (|PatternMatchable| (|Float|)))))
+ ((|GcdDomain|) (|has| |t#1| (|GcdDomain|)))
+ (|canonicalUnitNormal|
+ (|has| |t#1| (ATTRIBUTE |canonicalUnitNormal|)))
+ ((|PolynomialFactorizationExplicit|)
+ (|has| |t#1| (|PolynomialFactorizationExplicit|)))))
+ (QUOTE (
+ (|Factored| |$|)
+ (|List| |$|)
+ (|List| |t#3|)
+ (|NonNegativeInteger|)
+ (|SparseUnivariatePolynomial| |$|)
+ (|SparseUnivariatePolynomial| |t#1|)
+ (|List| (|NonNegativeInteger|))))
+ NIL))
+ . #2=(|PolynomialCategory|)))))
+ . #2#)
+ (SETELT #1# 0
+ (LIST
+ (QUOTE |PolynomialCategory|)
+ (|devaluate| |t#1|)
+ (|devaluate| |t#2|)
+ (|devaluate| |t#3|)))))))
+
+@
+\section{POLYCAT-.lsp BOOTSTRAP}
+{\bf POLYCAT-} depends on {\bf POLYCAT}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf POLYCAT-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf POLYCAT-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<POLYCAT-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |POLYCAT-;eval;SLS;1| (|p| |l| |$|)
+ (PROG (#1=#:G101870 #2=#:G101860 #3=#:G101868 #4=#:G101869
+ |lvar| #5=#:G101866 |e| #6=#:G101867)
+ (RETURN
+ (SEQ
+ (COND
+ ((NULL |l|) |p|)
+ ((QUOTE T)
+ (SEQ
+ (SEQ
+ (EXIT
+ (SEQ
+ (LETT |e| NIL |POLYCAT-;eval;SLS;1|)
+ (LETT #1# |l| |POLYCAT-;eval;SLS;1|)
+ G190
+ (COND
+ ((OR
+ (ATOM #1#)
+ (PROGN (LETT |e| (CAR #1#) |POLYCAT-;eval;SLS;1|) NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (COND
+ ((QEQCAR
+ (SPADCALL
+ (SPADCALL |e| (QREFELT |$| 11))
+ (QREFELT |$| 13))
+ 1)
+ (PROGN
+ (LETT #2#
+ (|error| "cannot find a variable to evaluate")
+ |POLYCAT-;eval;SLS;1|)
+ (GO #2#))))))
+ (LETT #1# (CDR #1#) |POLYCAT-;eval;SLS;1|)
+ (GO G190)
+ G191
+ (EXIT NIL)))
+ #2#
+ (EXIT #2#))
+ (LETT |lvar|
+ (PROGN
+ (LETT #3# NIL |POLYCAT-;eval;SLS;1|)
+ (SEQ
+ (LETT |e| NIL |POLYCAT-;eval;SLS;1|)
+ (LETT #4# |l| |POLYCAT-;eval;SLS;1|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |e| (CAR #4#) |POLYCAT-;eval;SLS;1|) NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #3#
+ (CONS
+ (SPADCALL
+ (SPADCALL |e| (QREFELT |$| 11))
+ (QREFELT |$| 14))
+ #3#)
+ |POLYCAT-;eval;SLS;1|)))
+ (LETT #4# (CDR #4#) |POLYCAT-;eval;SLS;1|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #3#))))
+ |POLYCAT-;eval;SLS;1|)
+ (EXIT
+ (SPADCALL
+ |p|
+ |lvar|
+ (PROGN
+ (LETT #5# NIL |POLYCAT-;eval;SLS;1|)
+ (SEQ
+ (LETT |e| NIL |POLYCAT-;eval;SLS;1|)
+ (LETT #6# |l| |POLYCAT-;eval;SLS;1|)
+ G190
+ (COND
+ ((OR
+ (ATOM #6#)
+ (PROGN
+ (LETT |e| (CAR #6#) |POLYCAT-;eval;SLS;1|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #5#
+ (CONS (SPADCALL |e| (QREFELT |$| 15)) #5#)
+ |POLYCAT-;eval;SLS;1|)))
+ (LETT #6# (CDR #6#) |POLYCAT-;eval;SLS;1|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #5#))))
+ (QREFELT |$| 18))))))))))
+
+(DEFUN |POLYCAT-;monomials;SL;2| (|p| |$|)
+ (PROG (|ml|)
+ (RETURN
+ (SEQ
+ (LETT |ml| NIL |POLYCAT-;monomials;SL;2|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL |p| (|spadConstant| |$| 21) (QREFELT |$| 24))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |ml|
+ (CONS (SPADCALL |p| (QREFELT |$| 25)) |ml|)
+ |POLYCAT-;monomials;SL;2|)
+ (EXIT
+ (LETT |p|
+ (SPADCALL |p| (QREFELT |$| 26))
+ |POLYCAT-;monomials;SL;2|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT (REVERSE |ml|))))))
+
+(DEFUN |POLYCAT-;isPlus;SU;3| (|p| |$|)
+ (PROG (|l|)
+ (RETURN
+ (COND
+ ((NULL
+ (CDR
+ (LETT |l|
+ (SPADCALL |p| (QREFELT |$| 28))
+ |POLYCAT-;isPlus;SU;3|)))
+ (CONS 1 "failed"))
+ ((QUOTE T) (CONS 0 |l|))))))
+
+(DEFUN |POLYCAT-;isTimes;SU;4| (|p| |$|)
+ (PROG (|lv| #1=#:G101892 |v| #2=#:G101893 |l| |r|)
+ (RETURN
+ (SEQ
+ (COND
+ ((OR
+ (NULL
+ (LETT |lv|
+ (SPADCALL |p| (QREFELT |$| 31))
+ |POLYCAT-;isTimes;SU;4|))
+ (NULL (SPADCALL |p| (QREFELT |$| 32))))
+ (CONS 1 "failed"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |l|
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;isTimes;SU;4|)
+ (SEQ
+ (LETT |v| NIL |POLYCAT-;isTimes;SU;4|)
+ (LETT #2# |lv| |POLYCAT-;isTimes;SU;4|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |v| (CAR #2#) |POLYCAT-;isTimes;SU;4|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS
+ (SPADCALL
+ (|spadConstant| |$| 33)
+ |v|
+ (SPADCALL |p| |v| (QREFELT |$| 36))
+ (QREFELT |$| 37))
+ #1#)
+ |POLYCAT-;isTimes;SU;4|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;isTimes;SU;4|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ |POLYCAT-;isTimes;SU;4|)
+ (EXIT
+ (COND
+ ((SPADCALL
+ (LETT |r|
+ (SPADCALL |p| (QREFELT |$| 38))
+ |POLYCAT-;isTimes;SU;4|)
+ (QREFELT |$| 39))
+ (COND
+ ((NULL (CDR |lv|)) (CONS 1 "failed"))
+ ((QUOTE T) (CONS 0 |l|))))
+ ((QUOTE T)
+ (CONS 0
+ (CONS (SPADCALL |r| (QREFELT |$| 40)) |l|))))))))))))
+
+(DEFUN |POLYCAT-;isExpt;SU;5| (|p| |$|)
+ (PROG (|u| |d|)
+ (RETURN
+ (SEQ
+ (LETT |u| (SPADCALL |p| (QREFELT |$| 42)) |POLYCAT-;isExpt;SU;5|)
+ (EXIT
+ (COND
+ ((OR
+ (QEQCAR |u| 1)
+ (NULL
+ (SPADCALL |p|
+ (SPADCALL
+ (|spadConstant| |$| 33)
+ (QCDR |u|)
+ (LETT |d|
+ (SPADCALL |p| (QCDR |u|) (QREFELT |$| 36))
+ |POLYCAT-;isExpt;SU;5|)
+ (QREFELT |$| 37))
+ (QREFELT |$| 24))))
+ (CONS 1 "failed"))
+ ((QUOTE T) (CONS 0 (CONS (QCDR |u|) |d|)))))))))
+
+(DEFUN |POLYCAT-;coefficient;SVarSetNniS;6| (|p| |v| |n| |$|)
+ (SPADCALL (SPADCALL |p| |v| (QREFELT |$| 47)) |n| (QREFELT |$| 49)))
+
+(DEFUN |POLYCAT-;coefficient;SLLS;7| (|p| |lv| |ln| |$|)
+ (COND
+ ((NULL |lv|)
+ (COND
+ ((NULL |ln|) |p|)
+ ((QUOTE T) (|error| "mismatched lists in coefficient"))))
+ ((NULL |ln|)
+ (|error| "mismatched lists in coefficient"))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |p| (|SPADfirst| |lv|) (QREFELT |$| 47))
+ (|SPADfirst| |ln|)
+ (QREFELT |$| 49))
+ (CDR |lv|)
+ (CDR |ln|)
+ (QREFELT |$| 52)))))
+
+(DEFUN |POLYCAT-;monomial;SLLS;8| (|p| |lv| |ln| |$|)
+ (COND
+ ((NULL |lv|)
+ (COND
+ ((NULL |ln|) |p|)
+ ((QUOTE T) (|error| "mismatched lists in monomial"))))
+ ((NULL |ln|)
+ (|error| "mismatched lists in monomial"))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL |p| (|SPADfirst| |lv|) (|SPADfirst| |ln|) (QREFELT |$| 37))
+ (CDR |lv|)
+ (CDR |ln|)
+ (QREFELT |$| 54)))))
+
+(DEFUN |POLYCAT-;retract;SVarSet;9| (|p| |$|)
+ (PROG (#1=#:G101918 |q|)
+ (RETURN
+ (SEQ
+ (LETT |q|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p| (QREFELT |$| 42))
+ |POLYCAT-;retract;SVarSet;9|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 9) #1#))
+ |POLYCAT-;retract;SVarSet;9|)
+ (EXIT
+ (COND
+ ((SPADCALL
+ (SPADCALL |q| (QREFELT |$| 56))
+ |p|
+ (QREFELT |$| 24))
+ |q|)
+ ((QUOTE T)
+ (|error| "Polynomial is not a single variable"))))))))
+
+(DEFUN |POLYCAT-;retractIfCan;SU;10| (|p| |$|)
+ (PROG (|q| #1=#:G101926)
+ (RETURN
+ (SEQ
+ (EXIT
+ (SEQ
+ (SEQ
+ (LETT |q|
+ (SPADCALL |p| (QREFELT |$| 42))
+ |POLYCAT-;retractIfCan;SU;10|)
+ (EXIT
+ (COND
+ ((QEQCAR |q| 0)
+ (COND
+ ((SPADCALL
+ (SPADCALL (QCDR |q|) (QREFELT |$| 56))
+ |p|
+ (QREFELT |$| 24))
+ (PROGN
+ (LETT #1# |q| |POLYCAT-;retractIfCan;SU;10|)
+ (GO #1#))))))))
+ (EXIT (CONS 1 "failed"))))
+ #1#
+ (EXIT #1#)))))
+
+(DEFUN |POLYCAT-;mkPrim| (|p| |$|)
+ (SPADCALL
+ (|spadConstant| |$| 34)
+ (SPADCALL |p| (QREFELT |$| 59))
+ (QREFELT |$| 60)))
+
+(DEFUN |POLYCAT-;primitiveMonomials;SL;12| (|p| |$|)
+ (PROG (#1=#:G101931 |q| #2=#:G101932)
+ (RETURN
+ (SEQ
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;primitiveMonomials;SL;12|)
+ (SEQ
+ (LETT |q| NIL |POLYCAT-;primitiveMonomials;SL;12|)
+ (LETT #2#
+ (SPADCALL |p| (QREFELT |$| 28))
+ |POLYCAT-;primitiveMonomials;SL;12|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |q| (CAR #2#) |POLYCAT-;primitiveMonomials;SL;12|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS
+ (|POLYCAT-;mkPrim| |q| |$|)
+ #1#)
+ |POLYCAT-;primitiveMonomials;SL;12|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;primitiveMonomials;SL;12|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))))))
+
+(DEFUN |POLYCAT-;totalDegree;SNni;13| (|p| |$|)
+ (PROG (#1=#:G101934 |d| |u|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 62)) 0)
+ ((QUOTE T)
+ (SEQ
+ (LETT |u|
+ (SPADCALL |p|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p| (QREFELT |$| 42))
+ |POLYCAT-;totalDegree;SNni;13|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 9) #1#))
+ (QREFELT |$| 47))
+ |POLYCAT-;totalDegree;SNni;13|)
+ (LETT |d| 0 |POLYCAT-;totalDegree;SNni;13|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL |u| (|spadConstant| |$| 63) (QREFELT |$| 64))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T)))) (GO G191)))
+ (SEQ
+ (LETT |d|
+ (MAX |d|
+ (|+|
+ (SPADCALL |u| (QREFELT |$| 65))
+ (SPADCALL
+ (SPADCALL |u| (QREFELT |$| 66))
+ (QREFELT |$| 67))))
+ |POLYCAT-;totalDegree;SNni;13|)
+ (EXIT
+ (LETT |u|
+ (SPADCALL |u| (QREFELT |$| 68))
+ |POLYCAT-;totalDegree;SNni;13|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |d|))))))))
+
+(DEFUN |POLYCAT-;totalDegree;SLNni;14| (|p| |lv| |$|)
+ (PROG (#1=#:G101942 |v| |w| |d| |u|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 62)) 0)
+ ((QUOTE T)
+ (SEQ
+ (LETT |u|
+ (SPADCALL |p|
+ (LETT |v|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p| (QREFELT |$| 42))
+ |POLYCAT-;totalDegree;SLNni;14|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 9) #1#))
+ |POLYCAT-;totalDegree;SLNni;14|)
+ (QREFELT |$| 47))
+ |POLYCAT-;totalDegree;SLNni;14|)
+ (LETT |d| 0 |POLYCAT-;totalDegree;SLNni;14|)
+ (LETT |w| 0 |POLYCAT-;totalDegree;SLNni;14|)
+ (COND
+ ((SPADCALL |v| |lv| (QREFELT |$| 70))
+ (LETT |w| 1 |POLYCAT-;totalDegree;SLNni;14|)))
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL |u| (|spadConstant| |$| 63) (QREFELT |$| 64))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |d|
+ (MAX |d|
+ (|+|
+ (|*| |w| (SPADCALL |u| (QREFELT |$| 65)))
+ (SPADCALL
+ (SPADCALL |u| (QREFELT |$| 66))
+ |lv|
+ (QREFELT |$| 71))))
+ |POLYCAT-;totalDegree;SLNni;14|)
+ (EXIT
+ (LETT |u|
+ (SPADCALL |u| (QREFELT |$| 68))
+ |POLYCAT-;totalDegree;SLNni;14|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |d|))))))))
+
+(DEFUN |POLYCAT-;resultant;2SVarSetS;15| (|p1| |p2| |mvar| |$|)
+ (SPADCALL
+ (SPADCALL |p1| |mvar| (QREFELT |$| 47))
+ (SPADCALL |p2| |mvar| (QREFELT |$| 47))
+ (QREFELT |$| 73)))
+
+(DEFUN |POLYCAT-;discriminant;SVarSetS;16| (|p| |var| |$|)
+ (SPADCALL (SPADCALL |p| |var| (QREFELT |$| 47)) (QREFELT |$| 75)))
+
+(DEFUN |POLYCAT-;allMonoms| (|l| |$|)
+ (PROG (#1=#:G101954 |p| #2=#:G101955)
+ (RETURN
+ (SEQ
+ (SPADCALL
+ (SPADCALL
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;allMonoms|)
+ (SEQ
+ (LETT |p| NIL |POLYCAT-;allMonoms|)
+ (LETT #2# |l| |POLYCAT-;allMonoms|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN (LETT |p| (CAR #2#) |POLYCAT-;allMonoms|) NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS (SPADCALL |p| (QREFELT |$| 77)) #1#)
+ |POLYCAT-;allMonoms|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;allMonoms|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ (QREFELT |$| 79))
+ (QREFELT |$| 80))))))
+
+(DEFUN |POLYCAT-;P2R| (|p| |b| |n| |$|)
+ (PROG (|w| |bj| #1=#:G101960 |i| #2=#:G101959)
+ (RETURN
+ (SEQ
+ (LETT |w|
+ (SPADCALL |n| (|spadConstant| |$| 22) (QREFELT |$| 82))
+ |POLYCAT-;P2R|)
+ (SEQ
+ (LETT |bj| NIL |POLYCAT-;P2R|)
+ (LETT #1# |b| |POLYCAT-;P2R|)
+ (LETT |i| (SPADCALL |w| (QREFELT |$| 84)) |POLYCAT-;P2R|)
+ (LETT #2# (QVSIZE |w|) |POLYCAT-;P2R|)
+ G190
+ (COND
+ ((OR
+ (|>| |i| #2#)
+ (ATOM #1#)
+ (PROGN (LETT |bj| (CAR #1#) |POLYCAT-;P2R|) NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (SPADCALL |w| |i|
+ (SPADCALL |p| |bj| (QREFELT |$| 85))
+ (QREFELT |$| 86))))
+ (LETT |i|
+ (PROG1
+ (|+| |i| 1)
+ (LETT #1# (CDR #1#) |POLYCAT-;P2R|))
+ |POLYCAT-;P2R|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |w|)))))
+
+(DEFUN |POLYCAT-;eq2R| (|l| |b| |$|)
+ (PROG (#1=#:G101964 |bj| #2=#:G101965 #3=#:G101966 |p| #4=#:G101967)
+ (RETURN
+ (SEQ
+ (SPADCALL
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;eq2R|)
+ (SEQ
+ (LETT |bj| NIL |POLYCAT-;eq2R|)
+ (LETT #2# |b| |POLYCAT-;eq2R|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN (LETT |bj| (CAR #2#) |POLYCAT-;eq2R|) NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS
+ (PROGN
+ (LETT #3# NIL |POLYCAT-;eq2R|)
+ (SEQ
+ (LETT |p| NIL |POLYCAT-;eq2R|)
+ (LETT #4# |l| |POLYCAT-;eq2R|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |p| (CAR #4#) |POLYCAT-;eq2R|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #3#
+ (CONS (SPADCALL |p| |bj| (QREFELT |$| 85)) #3#)
+ |POLYCAT-;eq2R|)))
+ (LETT #4# (CDR #4#) |POLYCAT-;eq2R|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #3#))))
+ #1#)
+ |POLYCAT-;eq2R|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;eq2R|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ (QREFELT |$| 89))))))
+
+(DEFUN |POLYCAT-;reducedSystem;MM;20| (|m| |$|)
+ (PROG (#1=#:G101979 |r| #2=#:G101980 |b| #3=#:G101977
+ |bj| #4=#:G101978 |d| |mm| |l|)
+ (RETURN
+ (SEQ
+ (LETT |l|
+ (SPADCALL |m| (QREFELT |$| 92))
+ |POLYCAT-;reducedSystem;MM;20|)
+ (LETT |b|
+ (SPADCALL
+ (SPADCALL
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;reducedSystem;MM;20|)
+ (SEQ
+ (LETT |r| NIL |POLYCAT-;reducedSystem;MM;20|)
+ (LETT #2# |l| |POLYCAT-;reducedSystem;MM;20|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |r| (CAR #2#) |POLYCAT-;reducedSystem;MM;20|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS (|POLYCAT-;allMonoms| |r| |$|) #1#)
+ |POLYCAT-;reducedSystem;MM;20|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;reducedSystem;MM;20|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ (QREFELT |$| 79))
+ (QREFELT |$| 80))
+ |POLYCAT-;reducedSystem;MM;20|)
+ (LETT |d|
+ (PROGN
+ (LETT #3# NIL |POLYCAT-;reducedSystem;MM;20|)
+ (SEQ
+ (LETT |bj| NIL |POLYCAT-;reducedSystem;MM;20|)
+ (LETT #4# |b| |POLYCAT-;reducedSystem;MM;20|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |bj| (CAR #4#) |POLYCAT-;reducedSystem;MM;20|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #3#
+ (CONS (SPADCALL |bj| (QREFELT |$| 59)) #3#)
+ |POLYCAT-;reducedSystem;MM;20|)))
+ (LETT #4# (CDR #4#) |POLYCAT-;reducedSystem;MM;20|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #3#))))
+ |POLYCAT-;reducedSystem;MM;20|)
+ (LETT |mm|
+ (|POLYCAT-;eq2R| (|SPADfirst| |l|) |d| |$|)
+ |POLYCAT-;reducedSystem;MM;20|)
+ (LETT |l| (CDR |l|) |POLYCAT-;reducedSystem;MM;20|)
+ (SEQ G190
+ (COND
+ ((NULL (COND ((NULL |l|) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |mm|
+ (SPADCALL |mm|
+ (|POLYCAT-;eq2R| (|SPADfirst| |l|) |d| |$|) (QREFELT |$| 93))
+ |POLYCAT-;reducedSystem;MM;20|)
+ (EXIT (LETT |l| (CDR |l|) |POLYCAT-;reducedSystem;MM;20|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |mm|)))))
+
+(DEFUN |POLYCAT-;reducedSystem;MVR;21| (|m| |v| |$|)
+ (PROG (#1=#:G101994 |s| #2=#:G101995 |b| #3=#:G101992 |bj| #4=#:G101993
+ |d| |n| |mm| |w| |l| |r|)
+ (RETURN
+ (SEQ
+ (LETT |l| (SPADCALL |m| (QREFELT |$| 92)) |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |r| (SPADCALL |v| (QREFELT |$| 97)) |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |b|
+ (SPADCALL
+ (SPADCALL
+ (|POLYCAT-;allMonoms| |r| |$|)
+ (SPADCALL
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;reducedSystem;MVR;21|)
+ (SEQ
+ (LETT |s| NIL |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT #2# |l| |POLYCAT-;reducedSystem;MVR;21|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |s| (CAR #2#) |POLYCAT-;reducedSystem;MVR;21|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS (|POLYCAT-;allMonoms| |s| |$|) #1#)
+ |POLYCAT-;reducedSystem;MVR;21|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;reducedSystem;MVR;21|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ (QREFELT |$| 79))
+ (QREFELT |$| 98))
+ (QREFELT |$| 80))
+ |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |d|
+ (PROGN
+ (LETT #3# NIL |POLYCAT-;reducedSystem;MVR;21|)
+ (SEQ
+ (LETT |bj| NIL |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT #4# |b| |POLYCAT-;reducedSystem;MVR;21|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |bj| (CAR #4#) |POLYCAT-;reducedSystem;MVR;21|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #3#
+ (CONS (SPADCALL |bj| (QREFELT |$| 59)) #3#)
+ |POLYCAT-;reducedSystem;MVR;21|)))
+ (LETT #4# (CDR #4#) |POLYCAT-;reducedSystem;MVR;21|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #3#))))
+ |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |n| (LENGTH |d|) |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |mm|
+ (|POLYCAT-;eq2R| (|SPADfirst| |l|) |d| |$|)
+ |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |w|
+ (|POLYCAT-;P2R| (|SPADfirst| |r|) |d| |n| |$|)
+ |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |l| (CDR |l|) |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |r| (CDR |r|) |POLYCAT-;reducedSystem;MVR;21|)
+ (SEQ G190
+ (COND
+ ((NULL (COND ((NULL |l|) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |mm|
+ (SPADCALL |mm|
+ (|POLYCAT-;eq2R| (|SPADfirst| |l|) |d| |$|)
+ (QREFELT |$| 93))
+ |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |w|
+ (SPADCALL |w|
+ (|POLYCAT-;P2R| (|SPADfirst| |r|) |d| |n| |$|)
+ (QREFELT |$| 99))
+ |POLYCAT-;reducedSystem;MVR;21|)
+ (LETT |l| (CDR |l|) |POLYCAT-;reducedSystem;MVR;21|)
+ (EXIT (LETT |r| (CDR |r|) |POLYCAT-;reducedSystem;MVR;21|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT (CONS |mm| |w|))))))
+
+(DEFUN |POLYCAT-;gcdPolynomial;3Sup;22| (|pp| |qq| |$|)
+ (SPADCALL |pp| |qq| (QREFELT |$| 104)))
+
+(DEFUN |POLYCAT-;solveLinearPolynomialEquation;LSupU;23| (|lpp| |pp| |$|)
+ (SPADCALL |lpp| |pp| (QREFELT |$| 109)))
+
+(DEFUN |POLYCAT-;factorPolynomial;SupF;24| (|pp| |$|)
+ (SPADCALL |pp| (QREFELT |$| 114)))
+
+(DEFUN |POLYCAT-;factorSquareFreePolynomial;SupF;25| (|pp| |$|)
+ (SPADCALL |pp| (QREFELT |$| 117)))
+
+(DEFUN |POLYCAT-;factor;SF;26| (|p| |$|)
+ (PROG (|v| |ansR| #1=#:G102039 |w| #2=#:G102040 |up| |ansSUP|
+ #3=#:G102037 |ww| #4=#:G102038)
+ (RETURN
+ (SEQ
+ (LETT |v| (SPADCALL |p| (QREFELT |$| 42)) |POLYCAT-;factor;SF;26|)
+ (EXIT
+ (COND
+ ((QEQCAR |v| 1)
+ (SEQ
+ (LETT |ansR|
+ (SPADCALL (SPADCALL |p| (QREFELT |$| 38)) (QREFELT |$| 120))
+ |POLYCAT-;factor;SF;26|)
+ (EXIT
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |ansR| (QREFELT |$| 122))
+ (QREFELT |$| 40))
+ (PROGN
+ (LETT #1# NIL |POLYCAT-;factor;SF;26|)
+ (SEQ
+ (LETT |w| NIL |POLYCAT-;factor;SF;26|)
+ (LETT #2#
+ (SPADCALL |ansR| (QREFELT |$| 126))
+ |POLYCAT-;factor;SF;26|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |w| (CAR #2#) |POLYCAT-;factor;SF;26|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS
+ (VECTOR
+ (QVELT |w| 0)
+ (SPADCALL (QVELT |w| 1) (QREFELT |$| 40))
+ (QVELT |w| 2))
+ #1#)
+ |POLYCAT-;factor;SF;26|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;factor;SF;26|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ (QREFELT |$| 130)))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |up|
+ (SPADCALL |p| (QCDR |v|) (QREFELT |$| 47))
+ |POLYCAT-;factor;SF;26|)
+ (LETT |ansSUP|
+ (SPADCALL |up| (QREFELT |$| 114))
+ |POLYCAT-;factor;SF;26|)
+ (EXIT
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |ansSUP| (QREFELT |$| 131))
+ (QCDR |v|)
+ (QREFELT |$| 132))
+ (PROGN
+ (LETT #3# NIL |POLYCAT-;factor;SF;26|)
+ (SEQ
+ (LETT |ww| NIL |POLYCAT-;factor;SF;26|)
+ (LETT #4#
+ (SPADCALL |ansSUP| (QREFELT |$| 135))
+ |POLYCAT-;factor;SF;26|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |ww| (CAR #4#) |POLYCAT-;factor;SF;26|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #3#
+ (CONS
+ (VECTOR
+ (QVELT |ww| 0)
+ (SPADCALL
+ (QVELT |ww| 1)
+ (QCDR |v|)
+ (QREFELT |$| 132))
+ (QVELT |ww| 2))
+ #3#)
+ |POLYCAT-;factor;SF;26|)))
+ (LETT #4# (CDR #4#) |POLYCAT-;factor;SF;26|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #3#))))
+ (QREFELT |$| 130)))))))))))
+
+(DEFUN |POLYCAT-;conditionP;MU;27| (|mat| |$|)
+ (PROG (|ll| #1=#:G102087 |z| #2=#:G102088 |ch| |l| #3=#:G102079
+ #4=#:G102086 #5=#:G102047 #6=#:G102045 #7=#:G102046 #8=#:G102080
+ |vars| |degs| #9=#:G102084 |d| #10=#:G102085 |nd| #11=#:G102074
+ #12=#:G102054 |deg1| |redmons| #13=#:G102081 |v| #14=#:G102083 |u|
+ #15=#:G102082 |llR| |monslist| |ans| #16=#:G102075 #17=#:G102076
+ |mons| #18=#:G102077 |m| #19=#:G102078 |i| #20=#:G102070
+ #21=#:G102068 #22=#:G102069)
+ (RETURN
+ (SEQ
+ (EXIT
+ (SEQ
+ (LETT |ll|
+ (SPADCALL (SPADCALL |mat| (QREFELT |$| 137)) (QREFELT |$| 92))
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT |llR|
+ (PROGN (LETT #1# NIL |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |z| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #2# (|SPADfirst| |ll|) |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |z| (CAR #2#) |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1# (CONS NIL #1#) |POLYCAT-;conditionP;MU;27|)))
+ (LETT #2# (CDR #2#) |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT |monslist| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT |ch|
+ (SPADCALL (QREFELT |$| 138))
+ |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |l| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #3# |ll| |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #3#)
+ (PROGN
+ (LETT |l| (CAR #3#) |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (LETT |mons|
+ (PROGN
+ (LETT #7# NIL |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |u| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #4# |l| |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #4#)
+ (PROGN
+ (LETT |u| (CAR #4#) |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (PROGN
+ (LETT #5#
+ (SPADCALL |u| (QREFELT |$| 77))
+ |POLYCAT-;conditionP;MU;27|)
+ (COND
+ (#7#
+ (LETT #6#
+ (SPADCALL #6# #5# (QREFELT |$| 139))
+ |POLYCAT-;conditionP;MU;27|))
+ ((QUOTE T)
+ (PROGN
+ (LETT #6# #5# |POLYCAT-;conditionP;MU;27|)
+ (LETT #7#
+ (QUOTE T)
+ |POLYCAT-;conditionP;MU;27|)))))))
+ (LETT #4# (CDR #4#) |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ (#7# #6#)
+ ((QUOTE T) (|IdentityError| (QUOTE |setUnion|)))))
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT |redmons| NIL |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |m| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #8# |mons| |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #8#)
+ (PROGN
+ (LETT |m| (CAR #8#) |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (LETT |vars|
+ (SPADCALL |m| (QREFELT |$| 31))
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT |degs|
+ (SPADCALL |m| |vars| (QREFELT |$| 140))
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT |deg1|
+ (PROGN
+ (LETT #9# NIL |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |d| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #10# |degs| |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #10#)
+ (PROGN
+ (LETT |d|
+ (CAR #10#)
+ |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #9#
+ (CONS
+ (SEQ
+ (LETT |nd|
+ (SPADCALL |d| |ch| (QREFELT |$| 142))
+ |POLYCAT-;conditionP;MU;27|)
+ (EXIT
+ (COND
+ ((QEQCAR |nd| 1)
+ (PROGN
+ (LETT #11#
+ (CONS 1 "failed")
+ |POLYCAT-;conditionP;MU;27|)
+ (GO #11#)))
+ ((QUOTE T)
+ (PROG1
+ (LETT #12#
+ (QCDR |nd|)
+ |POLYCAT-;conditionP;MU;27|)
+ (|check-subtype|
+ (|>=| #12# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #12#))))))
+ #9#)
+ |POLYCAT-;conditionP;MU;27|)))
+ (LETT #10# (CDR #10#) |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #9#))))
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT |redmons|
+ (CONS
+ (SPADCALL
+ (|spadConstant| |$| 33)
+ |vars|
+ |deg1|
+ (QREFELT |$| 54))
+ |redmons|)
+ |POLYCAT-;conditionP;MU;27|)
+ (EXIT
+ (LETT |llR|
+ (PROGN
+ (LETT #13# NIL |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |v| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #14# |llR| |POLYCAT-;conditionP;MU;27|)
+ (LETT |u| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #15# |l| |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #15#)
+ (PROGN
+ (LETT |u|
+ (CAR #15#)
+ |POLYCAT-;conditionP;MU;27|)
+ NIL)
+ (ATOM #14#)
+ (PROGN
+ (LETT |v|
+ (CAR #14#)
+ |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #13#
+ (CONS
+ (CONS
+ (SPADCALL
+ (SPADCALL
+ |u|
+ |vars|
+ |degs|
+ (QREFELT |$| 52))
+ (QREFELT |$| 143))
+ |v|)
+ #13#)
+ |POLYCAT-;conditionP;MU;27|)))
+ (LETT #15#
+ (PROG1
+ (CDR #15#)
+ (LETT #14#
+ (CDR #14#)
+ |POLYCAT-;conditionP;MU;27|))
+ |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #13#))))
+ |POLYCAT-;conditionP;MU;27|)))
+ (LETT #8# (CDR #8#) |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT
+ (LETT |monslist|
+ (CONS |redmons| |monslist|)
+ |POLYCAT-;conditionP;MU;27|)))
+ (LETT #3# (CDR #3#) |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (LETT |ans|
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |llR| (QREFELT |$| 89))
+ (QREFELT |$| 144))
+ (QREFELT |$| 146))
+ |POLYCAT-;conditionP;MU;27|)
+ (EXIT
+ (COND
+ ((QEQCAR |ans| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |i| 0 |POLYCAT-;conditionP;MU;27|)
+ (EXIT
+ (CONS
+ 0
+ (PRIMVEC2ARR
+ (PROGN
+ (LETT #16#
+ (GETREFV (SIZE |monslist|))
+ |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT #17# 0 |POLYCAT-;conditionP;MU;27|)
+ (LETT |mons| NIL |POLYCAT-;conditionP;MU;27|)
+ (LETT #18#
+ |monslist|
+ |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #18#)
+ (PROGN
+ (LETT |mons|
+ (CAR #18#)
+ |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (SETELT
+ #16#
+ #17#
+ (PROGN
+ (LETT #22#
+ NIL
+ |POLYCAT-;conditionP;MU;27|)
+ (SEQ
+ (LETT |m|
+ NIL
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT #19#
+ |mons|
+ |POLYCAT-;conditionP;MU;27|)
+ G190
+ (COND
+ ((OR
+ (ATOM #19#)
+ (PROGN
+ (LETT |m|
+ (CAR #19#)
+ |POLYCAT-;conditionP;MU;27|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (PROGN
+ (LETT #20#
+ (SPADCALL |m|
+ (SPADCALL
+ (SPADCALL
+ (QCDR |ans|)
+ (LETT |i|
+ (|+| |i| 1)
+ |POLYCAT-;conditionP;MU;27|)
+ (QREFELT |$| 147))
+ (QREFELT |$| 40))
+ (QREFELT |$| 148))
+ |POLYCAT-;conditionP;MU;27|)
+ (COND
+ (#22#
+ (LETT #21#
+ (SPADCALL #21# #20#
+ (QREFELT |$| 149))
+ |POLYCAT-;conditionP;MU;27|))
+ ((QUOTE T)
+ (PROGN
+ (LETT #21# #20#
+ |POLYCAT-;conditionP;MU;27|)
+ (LETT #22# (QUOTE T)
+ |POLYCAT-;conditionP;MU;27|)))))))
+ (LETT #19# (CDR #19#)
+ |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ (#22# #21#)
+ ((QUOTE T)
+ (|spadConstant| |$| 21)))))))
+ (LETT #18#
+ (PROG1
+ (CDR #18#)
+ (LETT #17#
+ (QSADD1 #17#)
+ |POLYCAT-;conditionP;MU;27|))
+ |POLYCAT-;conditionP;MU;27|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ #16#))))))))))
+ #11#
+ (EXIT #11#)))))
+
+(DEFUN |POLYCAT-;charthRoot;SU;28| (|p| |$|)
+ (PROG (|vars| |ans| |ch|)
+ (RETURN
+ (SEQ
+ (LETT |vars|
+ (SPADCALL |p| (QREFELT |$| 31)) |POLYCAT-;charthRoot;SU;28|)
+ (EXIT
+ (COND
+ ((NULL |vars|)
+ (SEQ
+ (LETT |ans|
+ (SPADCALL
+ (SPADCALL |p| (QREFELT |$| 143))
+ (QREFELT |$| 151))
+ |POLYCAT-;charthRoot;SU;28|)
+ (EXIT
+ (COND
+ ((QEQCAR |ans| 1)
+ (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS 0 (SPADCALL (QCDR |ans|) (QREFELT |$| 40))))))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |ch|
+ (SPADCALL (QREFELT |$| 138))
+ |POLYCAT-;charthRoot;SU;28|)
+ (EXIT (|POLYCAT-;charthRootlv| |p| |vars| |ch| |$|))))))))))
+
+(DEFUN |POLYCAT-;charthRootlv| (|p| |vars| |ch| |$|)
+ (PROG (|v| |dd| |cp| |d| #1=#:G102109 |ans| |ansx| #2=#:G102116)
+ (RETURN
+ (SEQ
+ (EXIT
+ (COND
+ ((NULL |vars|)
+ (SEQ
+ (LETT |ans|
+ (SPADCALL (SPADCALL |p| (QREFELT |$| 143)) (QREFELT |$| 151))
+ |POLYCAT-;charthRootlv|)
+ (EXIT
+ (COND
+ ((QEQCAR |ans| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS 0 (SPADCALL (QCDR |ans|) (QREFELT |$| 40))))))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |v| (|SPADfirst| |vars|) |POLYCAT-;charthRootlv|)
+ (LETT |vars| (CDR |vars|) |POLYCAT-;charthRootlv|)
+ (LETT |d|
+ (SPADCALL |p| |v| (QREFELT |$| 36))
+ |POLYCAT-;charthRootlv|)
+ (LETT |ans| (|spadConstant| |$| 21) |POLYCAT-;charthRootlv|)
+ (SEQ G190
+ (COND ((NULL (|<| 0 |d|)) (GO G191)))
+ (SEQ
+ (LETT |dd|
+ (SPADCALL |d| |ch| (QREFELT |$| 142))
+ |POLYCAT-;charthRootlv|)
+ (EXIT
+ (COND
+ ((QEQCAR |dd| 1)
+ (PROGN
+ (LETT #2#
+ (CONS 1 "failed")
+ |POLYCAT-;charthRootlv|)
+ (GO #2#)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |cp|
+ (SPADCALL |p| |v| |d| (QREFELT |$| 154))
+ |POLYCAT-;charthRootlv|)
+ (LETT |p|
+ (SPADCALL |p|
+ (SPADCALL |cp| |v| |d| (QREFELT |$| 37))
+ (QREFELT |$| 155))
+ |POLYCAT-;charthRootlv|)
+ (LETT |ansx|
+ (|POLYCAT-;charthRootlv| |cp| |vars| |ch| |$|)
+ |POLYCAT-;charthRootlv|)
+ (EXIT
+ (COND
+ ((QEQCAR |ansx| 1)
+ (PROGN
+ (LETT #2#
+ (CONS 1 "failed")
+ |POLYCAT-;charthRootlv|)
+ (GO #2#)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |d|
+ (SPADCALL |p| |v| (QREFELT |$| 36))
+ |POLYCAT-;charthRootlv|)
+ (EXIT
+ (LETT |ans|
+ (SPADCALL |ans|
+ (SPADCALL
+ (QCDR |ansx|)
+ |v|
+ (PROG1
+ (LETT #1#
+ (QCDR |dd|)
+ |POLYCAT-;charthRootlv|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ (QREFELT |$| 37))
+ (QREFELT |$| 149))
+ |POLYCAT-;charthRootlv|)))))))))))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (LETT |ansx|
+ (|POLYCAT-;charthRootlv| |p| |vars| |ch| |$|)
+ |POLYCAT-;charthRootlv|)
+ (EXIT
+ (COND
+ ((QEQCAR |ansx| 1)
+ (PROGN
+ (LETT #2# (CONS 1 "failed") |POLYCAT-;charthRootlv|)
+ (GO #2#)))
+ ((QUOTE T)
+ (PROGN
+ (LETT #2#
+ (CONS
+ 0
+ (SPADCALL |ans| (QCDR |ansx|) (QREFELT |$| 149)))
+ |POLYCAT-;charthRootlv|)
+ (GO #2#)))))))))
+ #2#
+ (EXIT #2#)))))
+
+(DEFUN |POLYCAT-;monicDivide;2SVarSetR;30| (|p1| |p2| |mvar| |$|)
+ (PROG (|result|)
+ (RETURN
+ (SEQ
+ (LETT |result|
+ (SPADCALL
+ (SPADCALL |p1| |mvar| (QREFELT |$| 47))
+ (SPADCALL |p2| |mvar| (QREFELT |$| 47))
+ (QREFELT |$| 157))
+ |POLYCAT-;monicDivide;2SVarSetR;30|)
+ (EXIT
+ (CONS
+ (SPADCALL (QCAR |result|) |mvar| (QREFELT |$| 132))
+ (SPADCALL (QCDR |result|) |mvar| (QREFELT |$| 132))))))))
+
+(DEFUN |POLYCAT-;squareFree;SF;31| (|p| |$|)
+ (SPADCALL |p| (QREFELT |$| 160)))
+
+(DEFUN |POLYCAT-;squareFree;SF;32| (|p| |$|)
+ (SPADCALL |p| (QREFELT |$| 163)))
+
+(DEFUN |POLYCAT-;squareFree;SF;33| (|p| |$|)
+ (SPADCALL |p| (QREFELT |$| 163)))
+
+(DEFUN |POLYCAT-;squareFreePart;2S;34| (|p| |$|)
+ (PROG (|s| |f| #1=#:G102132 #2=#:G102130 #3=#:G102128 #4=#:G102129)
+ (RETURN
+ (SEQ
+ (SPADCALL
+ (SPADCALL
+ (LETT |s|
+ (SPADCALL |p| (QREFELT |$| 164))
+ |POLYCAT-;squareFreePart;2S;34|)
+ (QREFELT |$| 165))
+ (PROGN
+ (LETT #4# NIL |POLYCAT-;squareFreePart;2S;34|)
+ (SEQ
+ (LETT |f| NIL |POLYCAT-;squareFreePart;2S;34|)
+ (LETT #1#
+ (SPADCALL |s| (QREFELT |$| 168))
+ |POLYCAT-;squareFreePart;2S;34|)
+ G190
+ (COND
+ ((OR
+ (ATOM #1#)
+ (PROGN
+ (LETT |f| (CAR #1#) |POLYCAT-;squareFreePart;2S;34|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (PROGN
+ (LETT #2# (QCAR |f|) |POLYCAT-;squareFreePart;2S;34|)
+ (COND
+ (#4#
+ (LETT #3#
+ (SPADCALL #3# #2# (QREFELT |$| 148))
+ |POLYCAT-;squareFreePart;2S;34|))
+ ((QUOTE T)
+ (PROGN
+ (LETT #3# #2# |POLYCAT-;squareFreePart;2S;34|)
+ (LETT #4#
+ (QUOTE T)
+ |POLYCAT-;squareFreePart;2S;34|)))))))
+ (LETT #1# (CDR #1#) |POLYCAT-;squareFreePart;2S;34|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ (#4# #3#)
+ ((QUOTE T) (|spadConstant| |$| 33))))
+ (QREFELT |$| 148))))))
+
+(DEFUN |POLYCAT-;content;SVarSetS;35| (|p| |v| |$|)
+ (SPADCALL (SPADCALL |p| |v| (QREFELT |$| 47)) (QREFELT |$| 170)))
+
+(DEFUN |POLYCAT-;primitivePart;2S;36| (|p| |$|)
+ (PROG (#1=#:G102135)
+ (RETURN
+ (QVELT
+ (SPADCALL
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p| (SPADCALL |p| (QREFELT |$| 172)) (QREFELT |$| 173))
+ |POLYCAT-;primitivePart;2S;36|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 6) #1#))
+ (QREFELT |$| 175))
+ 1))))
+
+(DEFUN |POLYCAT-;primitivePart;SVarSetS;37| (|p| |v| |$|)
+ (PROG (#1=#:G102141)
+ (RETURN
+ (QVELT
+ (SPADCALL
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p|
+ (SPADCALL |p| |v| (QREFELT |$| 177))
+ (QREFELT |$| 178))
+ |POLYCAT-;primitivePart;SVarSetS;37|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 6) #1#))
+ (QREFELT |$| 175)) 1))))
+
+(DEFUN |POLYCAT-;<;2SB;38| (|p| |q| |$|)
+ (PROG (|dp| |dq|)
+ (RETURN
+ (SEQ
+ (LETT |dp| (SPADCALL |p| (QREFELT |$| 59)) |POLYCAT-;<;2SB;38|)
+ (LETT |dq| (SPADCALL |q| (QREFELT |$| 59)) |POLYCAT-;<;2SB;38|)
+ (EXIT
+ (COND
+ ((SPADCALL |dp| |dq| (QREFELT |$| 180))
+ (SPADCALL
+ (|spadConstant| |$| 22)
+ (SPADCALL |q| (QREFELT |$| 38))
+ (QREFELT |$| 181)))
+ ((SPADCALL |dq| |dp| (QREFELT |$| 180))
+ (SPADCALL
+ (SPADCALL |p| (QREFELT |$| 38))
+ (|spadConstant| |$| 22)
+ (QREFELT |$| 181)))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |p| |q| (QREFELT |$| 155))
+ (QREFELT |$| 38))
+ (|spadConstant| |$| 22)
+ (QREFELT |$| 181)))))))))
+
+(DEFUN |POLYCAT-;patternMatch;SP2Pmr;39| (|p| |pat| |l| |$|)
+ (SPADCALL |p| |pat| |l| (QREFELT |$| 186)))
+
+(DEFUN |POLYCAT-;patternMatch;SP2Pmr;40| (|p| |pat| |l| |$|)
+ (SPADCALL |p| |pat| |l| (QREFELT |$| 192)))
+
+(DEFUN |POLYCAT-;convert;SP;41| (|x| |$|)
+ (SPADCALL (ELT |$| 195) (ELT |$| 196) |x| (QREFELT |$| 200)))
+
+(DEFUN |POLYCAT-;convert;SP;42| (|x| |$|)
+ (SPADCALL (ELT |$| 202) (ELT |$| 203) |x| (QREFELT |$| 207)))
+
+(DEFUN |POLYCAT-;convert;SIf;43| (|p| |$|)
+ (SPADCALL (ELT |$| 210) (ELT |$| 211) |p| (QREFELT |$| 215)))
+
+(DEFUN |PolynomialCategory&| (|#1| |#2| |#3| |#4|)
+ (PROG (|DV$1| |DV$2| |DV$3| |DV$4| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|PolynomialCategory&|))
+ (LETT |DV$2| (|devaluate| |#2|) . #1#)
+ (LETT |DV$3| (|devaluate| |#3|) . #1#)
+ (LETT |DV$4| (|devaluate| |#4|) . #1#)
+ (LETT |dv$|
+ (LIST
+ (QUOTE |PolynomialCategory&|) |DV$1| |DV$2| |DV$3| |DV$4|) . #1#)
+ (LETT |$| (GETREFV 225) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3
+ (LETT |pv$|
+ (|buildPredVector| 0 0
+ (LIST
+ (|HasCategory| |#2|
+ (QUOTE (|PolynomialFactorizationExplicit|)))
+ (|HasAttribute| |#2| (QUOTE |canonicalUnitNormal|))
+ (|HasCategory| |#2| (QUOTE (|GcdDomain|)))
+ (|HasCategory| |#2| (QUOTE (|CommutativeRing|)))
+ (|HasCategory| |#4| (QUOTE (|PatternMatchable| (|Float|))))
+ (|HasCategory| |#2| (QUOTE (|PatternMatchable| (|Float|))))
+ (|HasCategory| |#4| (QUOTE (|PatternMatchable| (|Integer|))))
+ (|HasCategory| |#2| (QUOTE (|PatternMatchable| (|Integer|))))
+ (|HasCategory| |#4|
+ (QUOTE (|ConvertibleTo| (|Pattern| (|Float|)))))
+ (|HasCategory| |#2|
+ (QUOTE (|ConvertibleTo| (|Pattern| (|Float|)))))
+ (|HasCategory| |#4|
+ (QUOTE (|ConvertibleTo| (|Pattern| (|Integer|)))))
+ (|HasCategory| |#2|
+ (QUOTE (|ConvertibleTo| (|Pattern| (|Integer|)))))
+ (|HasCategory| |#4| (QUOTE (|ConvertibleTo| (|InputForm|))))
+ (|HasCategory| |#2| (QUOTE (|ConvertibleTo| (|InputForm|))))
+ (|HasCategory| |#2| (QUOTE (|OrderedSet|))))) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ (QSETREFV |$| 7 |#2|)
+ (QSETREFV |$| 8 |#3|)
+ (QSETREFV |$| 9 |#4|)
+ (COND
+ ((|testBitVector| |pv$| 4)
+ (PROGN
+ (QSETREFV |$| 74
+ (CONS
+ (|dispatchFunction| |POLYCAT-;resultant;2SVarSetS;15|)
+ |$|))
+ (QSETREFV |$| 76
+ (CONS
+ (|dispatchFunction| |POLYCAT-;discriminant;SVarSetS;16|)
+ |$|)))))
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|IntegralDomain|)))
+ (PROGN
+ (QSETREFV |$| 95
+ (CONS (|dispatchFunction| |POLYCAT-;reducedSystem;MM;20|) |$|))
+ (QSETREFV |$| 102
+ (CONS
+ (|dispatchFunction| |POLYCAT-;reducedSystem;MVR;21|)
+ |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 1)
+ (PROGN
+ (QSETREFV |$| 105
+ (CONS
+ (|dispatchFunction| |POLYCAT-;gcdPolynomial;3Sup;22|)
+ |$|))
+ (QSETREFV |$| 112
+ (CONS
+ (|dispatchFunction|
+ |POLYCAT-;solveLinearPolynomialEquation;LSupU;23|)
+ |$|))
+ (QSETREFV |$| 116
+ (CONS
+ (|dispatchFunction| |POLYCAT-;factorPolynomial;SupF;24|)
+ |$|))
+ (QSETREFV |$| 118
+ (CONS
+ (|dispatchFunction|
+ |POLYCAT-;factorSquareFreePolynomial;SupF;25|)
+ |$|))
+ (QSETREFV |$| 136
+ (CONS
+ (|dispatchFunction| |POLYCAT-;factor;SF;26|) |$|))
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|CharacteristicNonZero|)))
+ (PROGN
+ (QSETREFV |$| 150
+ (CONS
+ (|dispatchFunction| |POLYCAT-;conditionP;MU;27|)
+ |$|))))))))
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|CharacteristicNonZero|)))
+ (PROGN
+ (QSETREFV |$| 152
+ (CONS
+ (|dispatchFunction| |POLYCAT-;charthRoot;SU;28|)
+ |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 3)
+ (PROGN
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|EuclideanDomain|)))
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|CharacteristicZero|)))
+ (QSETREFV |$| 161
+ (CONS
+ (|dispatchFunction| |POLYCAT-;squareFree;SF;31|)
+ |$|)))
+ ((QUOTE T)
+ (QSETREFV |$| 161
+ (CONS
+ (|dispatchFunction| |POLYCAT-;squareFree;SF;32|)
+ |$|)))))
+ ((QUOTE T)
+ (QSETREFV |$| 161
+ (CONS
+ (|dispatchFunction| |POLYCAT-;squareFree;SF;33|) |$|))))
+ (QSETREFV |$| 169
+ (CONS
+ (|dispatchFunction| |POLYCAT-;squareFreePart;2S;34|) |$|))
+ (QSETREFV |$| 171
+ (CONS (|dispatchFunction| |POLYCAT-;content;SVarSetS;35|) |$|))
+ (QSETREFV |$| 176
+ (CONS (|dispatchFunction| |POLYCAT-;primitivePart;2S;36|) |$|))
+ (QSETREFV |$| 179
+ (CONS
+ (|dispatchFunction| |POLYCAT-;primitivePart;SVarSetS;37|) |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 15)
+ (PROGN
+ (QSETREFV |$| 182
+ (CONS (|dispatchFunction| |POLYCAT-;<;2SB;38|) |$|))
+ (COND
+ ((|testBitVector| |pv$| 8)
+ (COND
+ ((|testBitVector| |pv$| 7)
+ (QSETREFV |$| 188
+ (CONS
+ (|dispatchFunction|
+ |POLYCAT-;patternMatch;SP2Pmr;39|)
+ |$|))))))
+ (COND
+ ((|testBitVector| |pv$| 6)
+ (COND
+ ((|testBitVector| |pv$| 5)
+ (QSETREFV |$| 194
+ (CONS
+ (|dispatchFunction|
+ |POLYCAT-;patternMatch;SP2Pmr;40|)
+ |$|)))))))))
+ (COND
+ ((|testBitVector| |pv$| 12)
+ (COND
+ ((|testBitVector| |pv$| 11)
+ (QSETREFV |$| 201
+ (CONS (|dispatchFunction| |POLYCAT-;convert;SP;41|) |$|))))))
+ (COND
+ ((|testBitVector| |pv$| 10)
+ (COND
+ ((|testBitVector| |pv$| 9)
+ (QSETREFV |$| 208
+ (CONS (|dispatchFunction| |POLYCAT-;convert;SP;42|) |$|))))))
+ (COND
+ ((|testBitVector| |pv$| 14)
+ (COND
+ ((|testBitVector| |pv$| 13)
+ (QSETREFV |$| 216
+ (CONS
+ (|dispatchFunction| |POLYCAT-;convert;SIf;43|)
+ |$|))))))
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |PolynomialCategory&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|local| |#2|)
+ (|local| |#3|)
+ (|local| |#4|)
+ (|Equation| 6)
+ (0 . |lhs|)
+ (|Union| 9 (QUOTE "failed"))
+ (5 . |retractIfCan|)
+ (10 . |retract|)
+ (15 . |rhs|)
+ (|List| 9)
+ (|List| |$|)
+ (20 . |eval|)
+ (|List| 220)
+ |POLYCAT-;eval;SLS;1|
+ (27 . |Zero|)
+ (31 . |Zero|)
+ (|Boolean|)
+ (35 . |=|)
+ (41 . |leadingMonomial|)
+ (46 . |reductum|)
+ |POLYCAT-;monomials;SL;2|
+ (51 . |monomials|)
+ (|Union| 17 (QUOTE "failed"))
+ |POLYCAT-;isPlus;SU;3|
+ (56 . |variables|)
+ (61 . |monomial?|)
+ (66 . |One|)
+ (70 . |One|)
+ (|NonNegativeInteger|)
+ (74 . |degree|)
+ (80 . |monomial|)
+ (87 . |leadingCoefficient|)
+ (92 . |one?|)
+ (97 . |coerce|)
+ |POLYCAT-;isTimes;SU;4|
+ (102 . |mainVariable|)
+ (|Record| (|:| |var| 9) (|:| |exponent| 35))
+ (|Union| 43 (QUOTE "failed"))
+ |POLYCAT-;isExpt;SU;5|
+ (|SparseUnivariatePolynomial| |$|)
+ (107 . |univariate|)
+ (|SparseUnivariatePolynomial| 6)
+ (113 . |coefficient|)
+ |POLYCAT-;coefficient;SVarSetNniS;6|
+ (|List| 35)
+ (119 . |coefficient|)
+ |POLYCAT-;coefficient;SLLS;7|
+ (126 . |monomial|)
+ |POLYCAT-;monomial;SLLS;8|
+ (133 . |coerce|)
+ |POLYCAT-;retract;SVarSet;9|
+ |POLYCAT-;retractIfCan;SU;10|
+ (138 . |degree|)
+ (143 . |monomial|)
+ |POLYCAT-;primitiveMonomials;SL;12|
+ (149 . |ground?|)
+ (154 . |Zero|)
+ (158 . |=|)
+ (164 . |degree|)
+ (169 . |leadingCoefficient|)
+ (174 . |totalDegree|)
+ (179 . |reductum|)
+ |POLYCAT-;totalDegree;SNni;13|
+ (184 . |member?|)
+ (190 . |totalDegree|)
+ |POLYCAT-;totalDegree;SLNni;14|
+ (196 . |resultant|)
+ (202 . |resultant|)
+ (209 . |discriminant|)
+ (214 . |discriminant|)
+ (220 . |primitiveMonomials|)
+ (|List| 6)
+ (225 . |concat|)
+ (230 . |removeDuplicates!|)
+ (|Vector| 7)
+ (235 . |new|)
+ (|Integer|)
+ (241 . |minIndex|)
+ (246 . |coefficient|)
+ (252 . |qsetelt!|)
+ (|List| 219)
+ (|Matrix| 7)
+ (259 . |matrix|)
+ (|List| 78)
+ (|Matrix| 6)
+ (264 . |listOfLists|)
+ (269 . |vertConcat|)
+ (|Matrix| |$|)
+ (275 . |reducedSystem|)
+ (|Vector| 6)
+ (280 . |entries|)
+ (285 . |concat|)
+ (291 . |concat|)
+ (|Record| (|:| |mat| 88) (|:| |vec| 81))
+ (|Vector| |$|)
+ (297 . |reducedSystem|)
+ (|GeneralPolynomialGcdPackage| 8 9 7 6)
+ (303 . |gcdPolynomial|)
+ (309 . |gcdPolynomial|)
+ (|Union| 107 (QUOTE "failed"))
+ (|List| 48)
+ (|PolynomialFactorizationByRecursion| 7 8 9 6)
+ (315 . |solveLinearPolynomialEquationByRecursion|)
+ (|Union| 111 (QUOTE "failed"))
+ (|List| 46)
+ (321 . |solveLinearPolynomialEquation|)
+ (|Factored| 48)
+ (327 . |factorByRecursion|)
+ (|Factored| 46)
+ (332 . |factorPolynomial|)
+ (337 . |factorSquareFreeByRecursion|)
+ (342 . |factorSquareFreePolynomial|)
+ (|Factored| |$|)
+ (347 . |factor|)
+ (|Factored| 7)
+ (352 . |unit|)
+ (|Union| (QUOTE "nil") (QUOTE "sqfr") (QUOTE "irred") (QUOTE "prime"))
+ (|Record| (|:| |flg| 123) (|:| |fctr| 7) (|:| |xpnt| 83))
+ (|List| 124)
+ (357 . |factorList|)
+ (|Record| (|:| |flg| 123) (|:| |fctr| 6) (|:| |xpnt| 83))
+ (|List| 127)
+ (|Factored| 6)
+ (362 . |makeFR|)
+ (368 . |unit|)
+ (373 . |multivariate|)
+ (|Record| (|:| |flg| 123) (|:| |fctr| 48) (|:| |xpnt| 83))
+ (|List| 133)
+ (379 . |factorList|)
+ (384 . |factor|)
+ (389 . |transpose|)
+ (394 . |characteristic|)
+ (398 . |setUnion|)
+ (404 . |degree|)
+ (|Union| |$| (QUOTE "failed"))
+ (410 . |exquo|)
+ (416 . |ground|)
+ (421 . |transpose|)
+ (|Union| 101 (QUOTE "failed"))
+ (426 . |conditionP|)
+ (431 . |elt|)
+ (437 . |*|)
+ (443 . |+|)
+ (449 . |conditionP|)
+ (454 . |charthRoot|)
+ (459 . |charthRoot|)
+ (464 . |Zero|)
+ (468 . |coefficient|)
+ (475 . |-|)
+ (|Record| (|:| |quotient| |$|) (|:| |remainder| |$|))
+ (481 . |monicDivide|)
+ |POLYCAT-;monicDivide;2SVarSetR;30|
+ (|MultivariateSquareFree| 8 9 7 6)
+ (487 . |squareFree|)
+ (492 . |squareFree|)
+ (|PolynomialSquareFree| 9 8 7 6)
+ (497 . |squareFree|)
+ (502 . |squareFree|)
+ (507 . |unit|)
+ (|Record| (|:| |factor| 6) (|:| |exponent| 83))
+ (|List| 166)
+ (512 . |factors|)
+ (517 . |squareFreePart|)
+ (522 . |content|)
+ (527 . |content|)
+ (533 . |content|)
+ (538 . |exquo|)
+ (|Record| (|:| |unit| |$|) (|:| |canonical| |$|) (|:| |associate| |$|))
+ (544 . |unitNormal|)
+ (549 . |primitivePart|)
+ (554 . |content|)
+ (560 . |exquo|)
+ (566 . |primitivePart|)
+ (572 . |<|)
+ (578 . |<|)
+ (584 . |<|)
+ (|PatternMatchResult| 83 6)
+ (|Pattern| 83)
+ (|PatternMatchPolynomialCategory| 83 8 9 7 6)
+ (590 . |patternMatch|)
+ (|PatternMatchResult| 83 |$|)
+ (597 . |patternMatch|)
+ (|PatternMatchResult| (|Float|) 6)
+ (|Pattern| (|Float|))
+ (|PatternMatchPolynomialCategory| (|Float|) 8 9 7 6)
+ (604 . |patternMatch|)
+ (|PatternMatchResult| (|Float|) |$|)
+ (611 . |patternMatch|)
+ (618 . |convert|)
+ (623 . |convert|)
+ (|Mapping| 184 9)
+ (|Mapping| 184 7)
+ (|PolynomialCategoryLifting| 8 9 7 6 184)
+ (628 . |map|)
+ (635 . |convert|)
+ (640 . |convert|)
+ (645 . |convert|)
+ (|Mapping| 190 9)
+ (|Mapping| 190 7)
+ (|PolynomialCategoryLifting| 8 9 7 6 190)
+ (650 . |map|)
+ (657 . |convert|)
+ (|InputForm|)
+ (662 . |convert|)
+ (667 . |convert|)
+ (|Mapping| 209 9)
+ (|Mapping| 209 7)
+ (|PolynomialCategoryLifting| 8 9 7 6 209)
+ (672 . |map|)
+ (679 . |convert|)
+ (|Record| (|:| |mat| 218) (|:| |vec| (|Vector| 83)))
+ (|Matrix| 83)
+ (|List| 7)
+ (|Equation| |$|)
+ (|Union| 83 (QUOTE "failed"))
+ (|Union| 223 (QUOTE "failed"))
+ (|Fraction| 83)
+ (|Union| 7 (QUOTE "failed"))))
+ (QUOTE
+ #(|totalDegree| 684 |squareFreePart| 695 |squareFree| 700
+ |solveLinearPolynomialEquation| 705 |retractIfCan| 711 |retract| 716
+ |resultant| 721 |reducedSystem| 728 |primitivePart| 739
+ |primitiveMonomials| 750 |patternMatch| 755 |monomials| 769
+ |monomial| 774 |monicDivide| 781 |isTimes| 788 |isPlus| 793
+ |isExpt| 798 |gcdPolynomial| 803 |factorSquareFreePolynomial| 809
+ |factorPolynomial| 814 |factor| 819 |eval| 824 |discriminant| 830
+ |convert| 836 |content| 851 |conditionP| 857 |coefficient| 862
+ |charthRoot| 876 |<| 881))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 216
+ (QUOTE
+ (1 10 6 0 11 1 6 12 0 13 1 6 9 0 14 1 10 6 0 15 3 6 0 0 16
+ 17 18 0 6 0 21 0 7 0 22 2 6 23 0 0 24 1 6 0 0 25 1 6 0 0
+ 26 1 6 17 0 28 1 6 16 0 31 1 6 23 0 32 0 6 0 33 0 7 0 34 2
+ 6 35 0 9 36 3 6 0 0 9 35 37 1 6 7 0 38 1 7 23 0 39 1 6 0 7
+ 40 1 6 12 0 42 2 6 46 0 9 47 2 48 6 0 35 49 3 6 0 0 16 51
+ 52 3 6 0 0 16 51 54 1 6 0 9 56 1 6 8 0 59 2 6 0 7 8 60 1 6
+ 23 0 62 0 48 0 63 2 48 23 0 0 64 1 48 35 0 65 1 48 6 0 66
+ 1 6 35 0 67 1 48 0 0 68 2 16 23 9 0 70 2 6 35 0 16 71 2 48
+ 6 0 0 73 3 0 0 0 0 9 74 1 48 6 0 75 2 0 0 0 9 76 1 6 17 0
+ 77 1 78 0 17 79 1 78 0 0 80 2 81 0 35 7 82 1 81 83 0 84 2
+ 6 7 0 8 85 3 81 7 0 83 7 86 1 88 0 87 89 1 91 90 0 92 2 88
+ 0 0 0 93 1 0 88 94 95 1 96 78 0 97 2 78 0 0 0 98 2 81 0 0
+ 0 99 2 0 100 94 101 102 2 103 48 48 48 104 2 0 46 46 46
+ 105 2 108 106 107 48 109 2 0 110 111 46 112 1 108 113 48
+ 114 1 0 115 46 116 1 108 113 48 117 1 0 115 46 118 1 7 119
+ 0 120 1 121 7 0 122 1 121 125 0 126 2 129 0 6 128 130 1 113
+ 48 0 131 2 6 0 46 9 132 1 113 134 0 135 1 0 119 0 136 1 91
+ 0 0 137 0 6 35 138 2 78 0 0 0 139 2 6 51 0 16 140 2 83 141
+ 0 0 142 1 6 7 0 143 1 88 0 0 144 1 7 145 94 146 2 81 7 0
+ 83 147 2 6 0 0 0 148 2 6 0 0 0 149 1 0 145 94 150 1 7 141
+ 0 151 1 0 141 0 152 0 8 0 153 3 6 0 0 9 35 154 2 6 0 0 0
+ 155 2 48 156 0 0 157 1 159 129 6 160 1 0 119 0 161 1 162
+ 129 6 163 1 6 119 0 164 1 129 6 0 165 1 129 167 0 168 1 0
+ 0 0 169 1 48 6 0 170 2 0 0 0 9 171 1 6 7 0 172 2 6 141 0 7
+ 173 1 6 174 0 175 1 0 0 0 176 2 6 0 0 9 177 2 6 141 0 0
+ 178 2 0 0 0 9 179 2 8 23 0 0 180 2 7 23 0 0 181 2 0 23 0 0
+ 182 3 185 183 6 184 183 186 3 0 187 0 184 187 188 3 191 189
+ 6 190 189 192 3 0 193 0 190 193 194 1 9 184 0 195 1 7 184
+ 0 196 3 199 184 197 198 6 200 1 0 184 0 201 1 9 190 0 202
+ 1 7 190 0 203 3 206 190 204 205 6 207 1 0 190 0 208 1 9
+ 209 0 210 1 7 209 0 211 3 214 209 212 213 6 215 1 0 209 0
+ 216 2 0 35 0 16 72 1 0 35 0 69 1 0 0 0 169 1 0 119 0 161 2
+ 0 110 111 46 112 1 0 12 0 58 1 0 9 0 57 3 0 0 0 0 9 74 1 0
+ 88 94 95 2 0 100 94 101 102 2 0 0 0 9 179 1 0 0 0 176 1 0
+ 17 0 61 3 0 187 0 184 187 188 3 0 193 0 190 193 194 1 0 17
+ 0 27 3 0 0 0 16 51 55 3 0 156 0 0 9 158 1 0 29 0 41 1 0 29
+ 0 30 1 0 44 0 45 2 0 46 46 46 105 1 0 115 46 118 1 0 115
+ 46 116 1 0 119 0 136 2 0 0 0 19 20 2 0 0 0 9 76 1 0 209 0
+ 216 1 0 184 0 201 1 0 190 0 208 2 0 0 0 9 171 1 0 145 94
+ 150 3 0 0 0 16 51 53 3 0 0 0 9 35 50 1 0 141 0 152 2 0
+ 23 0 0 182))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{package POLYLIFT PolynomialCategoryLifting}
+<<package POLYLIFT PolynomialCategoryLifting>>=
+)abbrev package POLYLIFT PolynomialCategoryLifting
+++ Author: Manuel Bronstein
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides a very general map function, which
+++ given a set S and polynomials over R with maps from the
+++ variables into S and the coefficients into S, maps polynomials
+++ into S. S is assumed to support \spad{+}, \spad{*} and \spad{**}.
+
+PolynomialCategoryLifting(E,Vars,R,P,S): Exports == Implementation where
+ E : OrderedAbelianMonoidSup
+ Vars: OrderedSet
+ R : Ring
+ P : PolynomialCategory(R, E, Vars)
+ S : SetCategory with
+ "+" : (%, %) -> %
+ "*" : (%, %) -> %
+ "**": (%, NonNegativeInteger) -> %
+
+ Exports ==> with
+ map: (Vars -> S, R -> S, P) -> S
+ ++ map(varmap, coefmap, p) takes a
+ ++ varmap, a mapping from the variables of polynomial p into S,
+ ++ coefmap, a mapping from coefficients of p into S, and p, and
+ ++ produces a member of S using the corresponding arithmetic.
+ ++ in S
+
+ Implementation ==> add
+ map(fv, fc, p) ==
+ (x1 := mainVariable p) case "failed" => fc leadingCoefficient p
+ up := univariate(p, x1::Vars)
+ t := fv(x1::Vars)
+ ans:= fc 0
+ while not ground? up repeat
+ ans := ans + map(fv,fc, leadingCoefficient up) * t ** (degree up)
+ up := reductum up
+ ans + map(fv, fc, leadingCoefficient up)
+
+@
+\section{category UPOLYC UnivariatePolynomialCategory}
+<<category UPOLYC UnivariatePolynomialCategory>>=
+)abbrev category UPOLYC UnivariatePolynomialCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions: Ring, monomial, coefficient, reductum, differentiate,
+++ elt, map, resultant, discriminant
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of univariate polynomials over a ring R.
+++ No particular model is assumed - implementations can be either
+++ sparse or dense.
+
+UnivariatePolynomialCategory(R:Ring): Category ==
+ Join(PolynomialCategory(R, NonNegativeInteger, SingletonAsOrderedSet),
+ Eltable(R, R), Eltable(%, %), DifferentialRing,
+ DifferentialExtension R) with
+ vectorise : (%,NonNegativeInteger) -> Vector R
+ ++ vectorise(p, n) returns \spad{[a0,...,a(n-1)]} where
+ ++ \spad{p = a0 + a1*x + ... + a(n-1)*x**(n-1)} + higher order terms.
+ ++ The degree of polynomial p can be different from \spad{n-1}.
+ makeSUP: % -> SparseUnivariatePolynomial R
+ ++ makeSUP(p) converts the polynomial p to be of type
+ ++ SparseUnivariatePolynomial over the same coefficients.
+ unmakeSUP: SparseUnivariatePolynomial R -> %
+ ++ unmakeSUP(sup) converts sup of type \spadtype{SparseUnivariatePolynomial(R)}
+ ++ to be a member of the given type.
+ ++ Note: converse of makeSUP.
+ multiplyExponents: (%,NonNegativeInteger) -> %
+ ++ multiplyExponents(p,n) returns a new polynomial resulting from
+ ++ multiplying all exponents of the polynomial p by the non negative
+ ++ integer n.
+ divideExponents: (%,NonNegativeInteger) -> Union(%,"failed")
+ ++ divideExponents(p,n) returns a new polynomial resulting from
+ ++ dividing all exponents of the polynomial p by the non negative
+ ++ integer n, or "failed" if some exponent is not exactly divisible
+ ++ by n.
+ monicDivide: (%,%) -> Record(quotient:%,remainder:%)
+ ++ monicDivide(p,q) divide the polynomial p by the monic polynomial q,
+ ++ returning the pair \spad{[quotient, remainder]}.
+ ++ Error: if q isn't monic.
+-- These three are for Karatsuba
+ karatsubaDivide: (%,NonNegativeInteger) -> Record(quotient:%,remainder:%)
+ ++ \spad{karatsubaDivide(p,n)} returns the same as \spad{monicDivide(p,monomial(1,n))}
+ shiftRight: (%,NonNegativeInteger) -> %
+ ++ \spad{shiftRight(p,n)} returns \spad{monicDivide(p,monomial(1,n)).quotient}
+ shiftLeft: (%,NonNegativeInteger) -> %
+ ++ \spad{shiftLeft(p,n)} returns \spad{p * monomial(1,n)}
+ pseudoRemainder: (%,%) -> %
+ ++ pseudoRemainder(p,q) = r, for polynomials p and q, returns the remainder when
+ ++ \spad{p' := p*lc(q)**(deg p - deg q + 1)}
+ ++ is pseudo right-divided by q, i.e. \spad{p' = s q + r}.
+ differentiate: (%, R -> R, %) -> %
+ ++ differentiate(p, d, x') extends the R-derivation d to an
+ ++ extension D in \spad{R[x]} where Dx is given by x', and returns \spad{Dp}.
+ if R has StepThrough then StepThrough
+ if R has CommutativeRing then
+ discriminant: % -> R
+ ++ discriminant(p) returns the discriminant of the polynomial p.
+ resultant: (%,%) -> R
+ ++ resultant(p,q) returns the resultant of the polynomials p and q.
+ if R has IntegralDomain then
+ Eltable(Fraction %, Fraction %)
+ elt : (Fraction %, Fraction %) -> Fraction %
+ ++ elt(a,b) evaluates the fraction of univariate polynomials \spad{a}
+ ++ with the distinguished variable replaced by b.
+ order: (%, %) -> NonNegativeInteger
+ ++ order(p, q) returns the largest n such that \spad{q**n} divides polynomial p
+ ++ i.e. the order of \spad{p(x)} at \spad{q(x)=0}.
+ subResultantGcd: (%,%) -> %
+ ++ subResultantGcd(p,q) computes the gcd of the polynomials p and q
+ ++ using the SubResultant GCD algorithm.
+ composite: (%, %) -> Union(%, "failed")
+ ++ composite(p, q) returns h if \spad{p = h(q)}, and "failed" no such h exists.
+ composite: (Fraction %, %) -> Union(Fraction %, "failed")
+ ++ composite(f, q) returns h if f = h(q), and "failed" is no such h exists.
+ pseudoQuotient: (%,%) -> %
+ ++ pseudoQuotient(p,q) returns r, the quotient when
+ ++ \spad{p' := p*lc(q)**(deg p - deg q + 1)}
+ ++ is pseudo right-divided by q, i.e. \spad{p' = s q + r}.
+ pseudoDivide: (%, %) -> Record(coef:R, quotient: %, remainder:%)
+ ++ pseudoDivide(p,q) returns \spad{[c, q, r]}, when
+ ++ \spad{p' := p*lc(q)**(deg p - deg q + 1) = c * p}
+ ++ is pseudo right-divided by q, i.e. \spad{p' = s q + r}.
+ if R has GcdDomain then
+ separate: (%, %) -> Record(primePart:%, commonPart: %)
+ ++ separate(p, q) returns \spad{[a, b]} such that polynomial \spad{p = a b} and
+ ++ \spad{a} is relatively prime to q.
+ if R has Field then
+ EuclideanDomain
+ additiveValuation
+ ++ euclideanSize(a*b) = euclideanSize(a) + euclideanSize(b)
+ elt : (Fraction %, R) -> R
+ ++ elt(a,r) evaluates the fraction of univariate polynomials \spad{a}
+ ++ with the distinguished variable replaced by the constant r.
+ if R has Algebra Fraction Integer then
+ integrate: % -> %
+ ++ integrate(p) integrates the univariate polynomial p with respect
+ ++ to its distinguished variable.
+ add
+ pp,qq: SparseUnivariatePolynomial %
+ variables(p) ==
+ zero? p or zero?(degree p) => []
+ [create()]
+ degree(p:%,v:SingletonAsOrderedSet) == degree p
+ totalDegree(p:%,lv:List SingletonAsOrderedSet) ==
+ empty? lv => 0
+ totalDegree p
+ degree(p:%,lv:List SingletonAsOrderedSet) ==
+ empty? lv => []
+ [degree p]
+ eval(p:%,lv: List SingletonAsOrderedSet,lq: List %):% ==
+ empty? lv => p
+ not empty? rest lv => error "can only eval a univariate polynomial once"
+ eval(p,first lv,first lq)$%
+ eval(p:%,v:SingletonAsOrderedSet,q:%):% == p(q)
+ eval(p:%,lv: List SingletonAsOrderedSet,lr: List R):% ==
+ empty? lv => p
+ not empty? rest lv => error "can only eval a univariate polynomial once"
+ eval(p,first lv,first lr)$%
+ eval(p:%,v:SingletonAsOrderedSet,r:R):% == p(r)::%
+ eval(p:%,le:List Equation %):% ==
+ empty? le => p
+ not empty? rest le => error "can only eval a univariate polynomial once"
+ mainVariable(lhs first le) case "failed" => p
+ p(rhs first le)
+ mainVariable(p:%) ==
+ zero? degree p => "failed"
+ create()$SingletonAsOrderedSet
+ minimumDegree(p:%,v:SingletonAsOrderedSet) == minimumDegree p
+ minimumDegree(p:%,lv:List SingletonAsOrderedSet) ==
+ empty? lv => []
+ [minimumDegree p]
+ monomial(p:%,v:SingletonAsOrderedSet,n:NonNegativeInteger) ==
+ mapExponents(#1+n,p)
+ coerce(v:SingletonAsOrderedSet):% == monomial(1,1)
+ makeSUP p ==
+ zero? p => 0
+ monomial(leadingCoefficient p,degree p) + makeSUP reductum p
+ unmakeSUP sp ==
+ zero? sp => 0
+ monomial(leadingCoefficient sp,degree sp) + unmakeSUP reductum sp
+ karatsubaDivide(p:%,n:NonNegativeInteger) == monicDivide(p,monomial(1,n))
+ shiftRight(p:%,n:NonNegativeInteger) == monicDivide(p,monomial(1,n)).quotient
+ shiftLeft(p:%,n:NonNegativeInteger) == p * monomial(1,n)
+ if R has PolynomialFactorizationExplicit then
+ PFBRU ==>PolynomialFactorizationByRecursionUnivariate(R,%)
+ pp,qq:SparseUnivariatePolynomial %
+ lpp:List SparseUnivariatePolynomial %
+ SupR ==> SparseUnivariatePolynomial R
+ sp:SupR
+
+ solveLinearPolynomialEquation(lpp,pp) ==
+ solveLinearPolynomialEquationByRecursion(lpp,pp)$PFBRU
+ factorPolynomial(pp) ==
+ factorByRecursion(pp)$PFBRU
+ factorSquareFreePolynomial(pp) ==
+ factorSquareFreeByRecursion(pp)$PFBRU
+ import FactoredFunctions2(SupR,S)
+ factor p ==
+ zero? degree p =>
+ ansR:=factor leadingCoefficient p
+ makeFR(unit(ansR)::%,
+ [[w.flg,w.fctr::%,w.xpnt] for w in factorList ansR])
+ map(unmakeSUP,factorPolynomial(makeSUP p)$R)
+
+ vectorise(p, n) ==
+ m := minIndex(v := new(n, 0)$Vector(R))
+ for i in minIndex v .. maxIndex v repeat
+ qsetelt_!(v, i, coefficient(p, (i - m)::NonNegativeInteger))
+ v
+ retract(p:%):R ==
+ zero? p => 0
+ zero? degree p => leadingCoefficient p
+ error "Polynomial is not of degree 0"
+ retractIfCan(p:%):Union(R, "failed") ==
+ zero? p => 0
+ zero? degree p => leadingCoefficient p
+ "failed"
+
+ if R has StepThrough then
+ init() == init()$R::%
+ nextItemInner: % -> Union(%,"failed")
+ nextItemInner(n) ==
+ zero? n => nextItem(0$R)::R::% -- assumed not to fail
+ zero? degree n =>
+ nn:=nextItem leadingCoefficient n
+ nn case "failed" => "failed"
+ nn::R::%
+ n1:=reductum n
+ n2:=nextItemInner n1 -- try stepping the reductum
+ n2 case % => monomial(leadingCoefficient n,degree n) + n2
+ 1+degree n1 < degree n => -- there was a hole between lt n and n1
+ monomial(leadingCoefficient n,degree n)+
+ monomial(nextItem(init()$R)::R,1+degree n1)
+ n3:=nextItem leadingCoefficient n
+ n3 case "failed" => "failed"
+ monomial(n3,degree n)
+ nextItem(n) ==
+ n1:=nextItemInner n
+ n1 case "failed" => monomial(nextItem(init()$R)::R,1+degree(n))
+ n1
+
+ if R has GcdDomain then
+
+ content(p:%,v:SingletonAsOrderedSet) == content(p)::%
+
+ primeFactor: (%, %) -> %
+
+ primeFactor(p, q) ==
+ (p1 := (p exquo gcd(p, q))::%) = p => p
+ primeFactor(p1, q)
+
+ separate(p, q) ==
+ a := primeFactor(p, q)
+ [a, (p exquo a)::%]
+
+ if R has CommutativeRing then
+ differentiate(x:%, deriv:R -> R, x':%) ==
+ d:% := 0
+ while (dg := degree x) > 0 repeat
+ lc := leadingCoefficient x
+ d := d + x' * monomial(dg * lc, (dg - 1)::NonNegativeInteger)
+ + monomial(deriv lc, dg)
+ x := reductum x
+ d + deriv(leadingCoefficient x)::%
+ else
+ ncdiff: (NonNegativeInteger, %) -> %
+ -- computes d(x**n) given dx = x', non-commutative case
+ ncdiff(n, x') ==
+ zero? n => 0
+ zero?(n1 := (n - 1)::NonNegativeInteger) => x'
+ x' * monomial(1, n1) + monomial(1, 1) * ncdiff(n1, x')
+
+ differentiate(x:%, deriv:R -> R, x':%) ==
+ d:% := 0
+ while (dg := degree x) > 0 repeat
+ lc := leadingCoefficient x
+ d := d + monomial(deriv lc, dg) + lc * ncdiff(dg, x')
+ x := reductum x
+ d + deriv(leadingCoefficient x)::%
+ differentiate(x:%, deriv:R -> R) == differentiate(x, deriv, 1$%)$%
+ differentiate(x:%) ==
+ d:% := 0
+ while (dg := degree x) > 0 repeat
+ d := d + monomial(dg * leadingCoefficient x, (dg - 1)::NonNegativeInteger)
+ x := reductum x
+ d
+ differentiate(x:%,v:SingletonAsOrderedSet) == differentiate x
+ if R has IntegralDomain then
+ elt(g:Fraction %, f:Fraction %) == ((numer g) f) / ((denom g) f)
+
+ pseudoQuotient(p, q) ==
+ (n := degree(p)::Integer - degree q + 1) < 1 => 0
+ ((leadingCoefficient(q)**(n::NonNegativeInteger) * p
+ - pseudoRemainder(p, q)) exquo q)::%
+
+ pseudoDivide(p, q) ==
+ (n := degree(p)::Integer - degree q + 1) < 1 => [1, 0, p]
+ prem := pseudoRemainder(p, q)
+ lc := leadingCoefficient(q)**(n::NonNegativeInteger)
+ [lc,((lc*p - prem) exquo q)::%, prem]
+
+ composite(f:Fraction %, q:%) ==
+ (n := composite(numer f, q)) case "failed" => "failed"
+ (d := composite(denom f, q)) case "failed" => "failed"
+ n::% / d::%
+
+ composite(p:%, q:%) ==
+ ground? p => p
+ cqr := pseudoDivide(p, q)
+ ground?(cqr.remainder) and
+ ((v := cqr.remainder exquo cqr.coef) case %) and
+ ((u := composite(cqr.quotient, q)) case %) and
+ ((w := (u::%) exquo cqr.coef) case %) =>
+ v::% + monomial(1, 1) * w::%
+ "failed"
+
+ elt(p:%, f:Fraction %) ==
+ zero? p => 0
+ ans:Fraction(%) := (leadingCoefficient p)::%::Fraction(%)
+ n := degree p
+ while not zero?(p:=reductum p) repeat
+ ans := ans * f ** (n - (n := degree p))::NonNegativeInteger +
+ (leadingCoefficient p)::%::Fraction(%)
+ zero? n => ans
+ ans * f ** n
+
+ order(p, q) ==
+ zero? p => error "order: arguments must be nonzero"
+ degree(q) < 1 => error "order: place must be non-trivial"
+ ans:NonNegativeInteger := 0
+ repeat
+ (u := p exquo q) case "failed" => return ans
+ p := u::%
+ ans := ans + 1
+
+ if R has GcdDomain then
+ squareFree(p:%) ==
+ squareFree(p)$UnivariatePolynomialSquareFree(R, %)
+
+ squareFreePart(p:%) ==
+ squareFreePart(p)$UnivariatePolynomialSquareFree(R, %)
+
+ if R has PolynomialFactorizationExplicit then
+
+ gcdPolynomial(pp,qq) ==
+ zero? pp => unitCanonical qq -- subResultantGcd can't handle 0
+ zero? qq => unitCanonical pp
+ unitCanonical(gcd(content (pp),content(qq))*
+ primitivePart
+ subResultantGcd(primitivePart pp,primitivePart qq))
+
+ squareFreePolynomial pp ==
+ squareFree(pp)$UnivariatePolynomialSquareFree(%,
+ SparseUnivariatePolynomial %)
+
+ if R has Field then
+ elt(f:Fraction %, r:R) == ((numer f) r) / ((denom f) r)
+
+ euclideanSize x ==
+ zero? x =>
+ error "euclideanSize called on 0 in Univariate Polynomial"
+ degree x
+ divide(x,y) ==
+ zero? y => error "division by 0 in Univariate Polynomials"
+ quot:=0
+ lc := inv leadingCoefficient y
+ while not zero?(x) and (degree x >= degree y) repeat
+ f:=lc*leadingCoefficient x
+ n:=(degree x - degree y)::NonNegativeInteger
+ quot:=quot+monomial(f,n)
+ x:=x-monomial(f,n)*y
+ [quot,x]
+ if R has Algebra Fraction Integer then
+ integrate p ==
+ ans:% := 0
+ while p ^= 0 repeat
+ l := leadingCoefficient p
+ d := 1 + degree p
+ ans := ans + inv(d::Fraction(Integer)) * monomial(l, d)
+ p := reductum p
+ ans
+
+@
+\section{UPOLYC.lsp BOOTSTRAP}
+{\bf UPOLYC} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf UPOLYC}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf UPOLYC.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<UPOLYC.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |UnivariatePolynomialCategory;CAT| (QUOTE NIL))
+
+(SETQ |UnivariatePolynomialCategory;AL| (QUOTE NIL))
+
+(DEFUN |UnivariatePolynomialCategory| (#1=#:G103214)
+ (LET (#2=#:G103215)
+ (COND
+ ((SETQ #2# (|assoc| (|devaluate| #1#) |UnivariatePolynomialCategory;AL|))
+ (CDR #2#))
+ (T
+ (SETQ |UnivariatePolynomialCategory;AL|
+ (|cons5|
+ (CONS
+ (|devaluate| #1#)
+ (SETQ #2# (|UnivariatePolynomialCategory;| #1#)))
+ |UnivariatePolynomialCategory;AL|))
+ #2#))))
+
+(DEFUN |UnivariatePolynomialCategory;| (|t#1|)
+ (PROG (#1=#:G103213)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|)))
+ (|sublisV|
+ (PAIR
+ (QUOTE (#2=#:G103211 #3=#:G103212))
+ (LIST
+ (QUOTE (|NonNegativeInteger|))
+ (QUOTE (|SingletonAsOrderedSet|))))
+ (COND
+ (|UnivariatePolynomialCategory;CAT|)
+ ((QUOTE T)
+ (LETT |UnivariatePolynomialCategory;CAT|
+ (|Join|
+ (|PolynomialCategory|
+ (QUOTE |t#1|) (QUOTE #2#) (QUOTE #3#))
+ (|Eltable| (QUOTE |t#1|) (QUOTE |t#1|))
+ (|Eltable| (QUOTE |$|) (QUOTE |$|))
+ (|DifferentialRing|)
+ (|DifferentialExtension| (QUOTE |t#1|))
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|vectorise|
+ ((|Vector| |t#1|) |$| (|NonNegativeInteger|))) T)
+ ((|makeSUP|
+ ((|SparseUnivariatePolynomial| |t#1|) |$|)) T)
+ ((|unmakeSUP|
+ (|$| (|SparseUnivariatePolynomial| |t#1|))) T)
+ ((|multiplyExponents|
+ (|$| |$| (|NonNegativeInteger|))) T)
+ ((|divideExponents|
+ ((|Union| |$| "failed")
+ |$|
+ (|NonNegativeInteger|))) T)
+ ((|monicDivide|
+ ((|Record|
+ (|:| |quotient| |$|)
+ (|:| |remainder| |$|))
+ |$|
+ |$|)) T)
+ ((|karatsubaDivide|
+ ((|Record|
+ (|:| |quotient| |$|)
+ (|:| |remainder| |$|))
+ |$|
+ (|NonNegativeInteger|))) T)
+ ((|shiftRight| (|$| |$| (|NonNegativeInteger|))) T)
+ ((|shiftLeft| (|$| |$| (|NonNegativeInteger|))) T)
+ ((|pseudoRemainder| (|$| |$| |$|)) T)
+ ((|differentiate|
+ (|$| |$| (|Mapping| |t#1| |t#1|) |$|)) T)
+ ((|discriminant| (|t#1| |$|))
+ (|has| |t#1| (|CommutativeRing|)))
+ ((|resultant| (|t#1| |$| |$|))
+ (|has| |t#1| (|CommutativeRing|)))
+ ((|elt|
+ ((|Fraction| |$|)
+ (|Fraction| |$|)
+ (|Fraction| |$|)))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|order| ((|NonNegativeInteger|) |$| |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|subResultantGcd| (|$| |$| |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|composite| ((|Union| |$| "failed") |$| |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|composite|
+ ((|Union| (|Fraction| |$|) "failed")
+ (|Fraction| |$|)
+ |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|pseudoQuotient| (|$| |$| |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|pseudoDivide|
+ ((|Record|
+ (|:| |coef| |t#1|)
+ (|:| |quotient| |$|)
+ (|:| |remainder| |$|))
+ |$|
+ |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|separate|
+ ((|Record|
+ (|:| |primePart| |$|)
+ (|:| |commonPart| |$|))
+ |$|
+ |$|))
+ (|has| |t#1| (|GcdDomain|)))
+ ((|elt| (|t#1| (|Fraction| |$|) |t#1|))
+ (|has| |t#1| (|Field|)))
+ ((|integrate| (|$| |$|))
+ (|has| |t#1|
+ (|Algebra| (|Fraction| (|Integer|)))))))
+ (QUOTE (
+ ((|StepThrough|) (|has| |t#1| (|StepThrough|)))
+ ((|Eltable|
+ (|Fraction| |$|)
+ (|Fraction| |$|))
+ (|has| |t#1| (|IntegralDomain|)))
+ ((|EuclideanDomain|) (|has| |t#1| (|Field|)))
+ (|additiveValuation| (|has| |t#1| (|Field|)))))
+ (QUOTE (
+ (|Fraction| |$|)
+ (|NonNegativeInteger|)
+ (|SparseUnivariatePolynomial| |t#1|)
+ (|Vector| |t#1|)))
+ NIL))
+ . #4=(|UnivariatePolynomialCategory|))))))
+ . #4#)
+ (SETELT #1# 0
+ (LIST
+ (QUOTE |UnivariatePolynomialCategory|)
+ (|devaluate| |t#1|)))))))
+
+@
+\section{UPOLYC-.lsp BOOTSTRAP}
+{\bf UPOLYC-} depends on {\bf UPOLYC}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf UPOLYC-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf UPOLYC-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<UPOLYC-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |UPOLYC-;variables;SL;1| (|p| |$|)
+ (COND
+ ((OR
+ (SPADCALL |p| (QREFELT |$| 9))
+ (ZEROP (SPADCALL |p| (QREFELT |$| 11))))
+ NIL)
+ ((QUOTE T) (LIST (SPADCALL (QREFELT |$| 13))))))
+
+(DEFUN |UPOLYC-;degree;SSaosNni;2| (|p| |v| |$|)
+ (SPADCALL |p| (QREFELT |$| 11)))
+
+(DEFUN |UPOLYC-;totalDegree;SLNni;3| (|p| |lv| |$|)
+ (COND ((NULL |lv|) 0) ((QUOTE T) (SPADCALL |p| (QREFELT |$| 17)))))
+
+(DEFUN |UPOLYC-;degree;SLL;4| (|p| |lv| |$|)
+ (COND ((NULL |lv|) NIL) ((QUOTE T) (LIST (SPADCALL |p| (QREFELT |$| 11))))))
+
+(DEFUN |UPOLYC-;eval;SLLS;5| (|p| |lv| |lq| |$|)
+ (COND
+ ((NULL |lv|) |p|)
+ ((NULL (NULL (CDR |lv|)))
+ (|error| "can only eval a univariate polynomial once"))
+ ((QUOTE T)
+ (SPADCALL |p| (|SPADfirst| |lv|) (|SPADfirst| |lq|) (QREFELT |$| 21)))))
+
+(DEFUN |UPOLYC-;eval;SSaos2S;6| (|p| |v| |q| |$|)
+ (SPADCALL |p| |q| (QREFELT |$| 24)))
+
+(DEFUN |UPOLYC-;eval;SLLS;7| (|p| |lv| |lr| |$|)
+ (COND
+ ((NULL |lv|) |p|)
+ ((NULL (NULL (CDR |lv|)))
+ (|error| "can only eval a univariate polynomial once"))
+ ((QUOTE T)
+ (SPADCALL |p| (|SPADfirst| |lv|) (|SPADfirst| |lr|) (QREFELT |$| 26)))))
+
+(DEFUN |UPOLYC-;eval;SSaosRS;8| (|p| |v| |r| |$|)
+ (SPADCALL (SPADCALL |p| |r| (QREFELT |$| 29)) (QREFELT |$| 30)))
+
+(DEFUN |UPOLYC-;eval;SLS;9| (|p| |le| |$|)
+ (COND
+ ((NULL |le|) |p|)
+ ((NULL (NULL (CDR |le|)))
+ (|error| "can only eval a univariate polynomial once"))
+ ((QUOTE T)
+ (COND
+ ((QEQCAR
+ (SPADCALL
+ (SPADCALL (|SPADfirst| |le|) (QREFELT |$| 33))
+ (QREFELT |$| 35))
+ 1)
+ |p|)
+ ((QUOTE T)
+ (SPADCALL |p|
+ (SPADCALL (|SPADfirst| |le|) (QREFELT |$| 36))
+ (QREFELT |$| 24)))))))
+
+(DEFUN |UPOLYC-;mainVariable;SU;10| (|p| |$|)
+ (COND
+ ((ZEROP (SPADCALL |p| (QREFELT |$| 11))) (CONS 1 "failed"))
+ ((QUOTE T) (CONS 0 (SPADCALL (QREFELT |$| 13))))))
+
+(DEFUN |UPOLYC-;minimumDegree;SSaosNni;11| (|p| |v| |$|)
+ (SPADCALL |p| (QREFELT |$| 40)))
+
+(DEFUN |UPOLYC-;minimumDegree;SLL;12| (|p| |lv| |$|)
+ (COND ((NULL |lv|) NIL) ((QUOTE T) (LIST (SPADCALL |p| (QREFELT |$| 40))))))
+
+(DEFUN |UPOLYC-;monomial;SSaosNniS;13| (|p| |v| |n| |$|)
+ (SPADCALL
+ (CONS (FUNCTION |UPOLYC-;monomial;SSaosNniS;13!0|) (VECTOR |$| |n|))
+ |p|
+ (QREFELT |$| 45)))
+
+(DEFUN |UPOLYC-;monomial;SSaosNniS;13!0| (|#1| |$$|)
+ (SPADCALL |#1| (QREFELT |$$| 1) (QREFELT (QREFELT |$$| 0) 43)))
+
+(DEFUN |UPOLYC-;coerce;SaosS;14| (|v| |$|)
+ (SPADCALL (|spadConstant| |$| 48) 1 (QREFELT |$| 49)))
+
+(DEFUN |UPOLYC-;makeSUP;SSup;15| (|p| |$|)
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 9)) (|spadConstant| |$| 52))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |p| (QREFELT |$| 53))
+ (SPADCALL |p| (QREFELT |$| 11))
+ (QREFELT |$| 54))
+ (SPADCALL
+ (SPADCALL |p| (QREFELT |$| 55))
+ (QREFELT |$| 56))
+ (QREFELT |$| 57)))))
+
+(DEFUN |UPOLYC-;unmakeSUP;SupS;16| (|sp| |$|)
+ (COND
+ ((SPADCALL |sp| (QREFELT |$| 59)) (|spadConstant| |$| 60))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |sp| (QREFELT |$| 61))
+ (SPADCALL |sp| (QREFELT |$| 62))
+ (QREFELT |$| 49))
+ (SPADCALL (SPADCALL |sp| (QREFELT |$| 63)) (QREFELT |$| 64))
+ (QREFELT |$| 65)))))
+
+(DEFUN |UPOLYC-;karatsubaDivide;SNniR;17| (|p| |n| |$|)
+ (SPADCALL |p|
+ (SPADCALL (|spadConstant| |$| 48) |n| (QREFELT |$| 49))
+ (QREFELT |$| 68)))
+
+(DEFUN |UPOLYC-;shiftRight;SNniS;18| (|p| |n| |$|)
+ (QCAR
+ (SPADCALL |p|
+ (SPADCALL (|spadConstant| |$| 48) |n| (QREFELT |$| 49))
+ (QREFELT |$| 68))))
+
+(DEFUN |UPOLYC-;shiftLeft;SNniS;19| (|p| |n| |$|)
+ (SPADCALL |p|
+ (SPADCALL (|spadConstant| |$| 48) |n| (QREFELT |$| 49)) (QREFELT |$| 71)))
+
+(DEFUN |UPOLYC-;solveLinearPolynomialEquation;LSupU;20| (|lpp| |pp| |$|)
+ (SPADCALL |lpp| |pp| (QREFELT |$| 77)))
+
+(DEFUN |UPOLYC-;factorPolynomial;SupF;21| (|pp| |$|)
+ (SPADCALL |pp| (QREFELT |$| 83)))
+
+(DEFUN |UPOLYC-;factorSquareFreePolynomial;SupF;22| (|pp| |$|)
+ (SPADCALL |pp| (QREFELT |$| 86)))
+
+(DEFUN |UPOLYC-;factor;SF;23| (|p| |$|)
+ (PROG (|ansR| #1=#:G103310 |w| #2=#:G103311)
+ (RETURN
+ (SEQ
+ (COND
+ ((ZEROP (SPADCALL |p| (QREFELT |$| 11)))
+ (SEQ
+ (LETT |ansR|
+ (SPADCALL
+ (SPADCALL |p| (QREFELT |$| 53))
+ (QREFELT |$| 89))
+ |UPOLYC-;factor;SF;23|)
+ (EXIT
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |ansR| (QREFELT |$| 91))
+ (QREFELT |$| 30))
+ (PROGN
+ (LETT #1# NIL |UPOLYC-;factor;SF;23|)
+ (SEQ
+ (LETT |w| NIL |UPOLYC-;factor;SF;23|)
+ (LETT #2#
+ (SPADCALL |ansR| (QREFELT |$| 95))
+ |UPOLYC-;factor;SF;23|)
+ G190
+ (COND
+ ((OR
+ (ATOM #2#)
+ (PROGN
+ (LETT |w| (CAR #2#) |UPOLYC-;factor;SF;23|)
+ NIL))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT #1#
+ (CONS
+ (VECTOR
+ (QVELT |w| 0)
+ (SPADCALL (QVELT |w| 1) (QREFELT |$| 30))
+ (QVELT |w| 2))
+ #1#)
+ |UPOLYC-;factor;SF;23|)))
+ (LETT #2# (CDR #2#) |UPOLYC-;factor;SF;23|)
+ (GO G190)
+ G191
+ (EXIT (NREVERSE0 #1#))))
+ (QREFELT |$| 99)))))
+ ((QUOTE T)
+ (SPADCALL
+ (ELT |$| 64)
+ (SPADCALL (SPADCALL |p| (QREFELT |$| 56)) (QREFELT |$| 100))
+ (QREFELT |$| 104))))))))
+
+(DEFUN |UPOLYC-;vectorise;SNniV;24| (|p| |n| |$|)
+ (PROG (|v| |m| |i| #1=#:G103316 #2=#:G103312)
+ (RETURN
+ (SEQ
+ (LETT |m|
+ (SPADCALL
+ (LETT |v|
+ (SPADCALL |n| (|spadConstant| |$| 106) (QREFELT |$| 108))
+ |UPOLYC-;vectorise;SNniV;24|)
+ (QREFELT |$| 110))
+ |UPOLYC-;vectorise;SNniV;24|)
+ (SEQ
+ (LETT |i|
+ (SPADCALL |v| (QREFELT |$| 110))
+ |UPOLYC-;vectorise;SNniV;24|)
+ (LETT #1# (QVSIZE |v|) |UPOLYC-;vectorise;SNniV;24|)
+ G190
+ (COND ((|>| |i| #1#) (GO G191)))
+ (SEQ
+ (EXIT
+ (SPADCALL |v| |i|
+ (SPADCALL |p|
+ (PROG1
+ (LETT #2# (|-| |i| |m|) |UPOLYC-;vectorise;SNniV;24|)
+ (|check-subtype|
+ (|>=| #2# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #2#))
+ (QREFELT |$| 111))
+ (QREFELT |$| 112))))
+ (LETT |i| (|+| |i| 1) |UPOLYC-;vectorise;SNniV;24|)
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |v|)))))
+
+(DEFUN |UPOLYC-;retract;SR;25| (|p| |$|)
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 9)) (|spadConstant| |$| 106))
+ ((ZEROP (SPADCALL |p| (QREFELT |$| 11))) (SPADCALL |p| (QREFELT |$| 53)))
+ ((QUOTE T) (|error| "Polynomial is not of degree 0"))))
+
+(DEFUN |UPOLYC-;retractIfCan;SU;26| (|p| |$|)
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 9)) (CONS 0 (|spadConstant| |$| 106)))
+ ((ZEROP (SPADCALL |p| (QREFELT |$| 11)))
+ (CONS 0 (SPADCALL |p| (QREFELT |$| 53))))
+ ((QUOTE T) (CONS 1 "failed"))))
+
+(DEFUN |UPOLYC-;init;S;27| (|$|)
+ (SPADCALL (|spadConstant| |$| 117) (QREFELT |$| 30)))
+
+(DEFUN |UPOLYC-;nextItemInner| (|n| |$|)
+ (PROG (|nn| |n1| |n2| #1=#:G103337 |n3|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |n| (QREFELT |$| 9))
+ (CONS
+ 0
+ (SPADCALL
+ (PROG2
+ (LETT #1#
+ (SPADCALL (|spadConstant| |$| 106) (QREFELT |$| 120))
+ |UPOLYC-;nextItemInner|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 7) #1#))
+ (QREFELT |$| 30))))
+ ((ZEROP (SPADCALL |n| (QREFELT |$| 11)))
+ (SEQ
+ (LETT |nn|
+ (SPADCALL (SPADCALL |n| (QREFELT |$| 53)) (QREFELT |$| 120))
+ |UPOLYC-;nextItemInner|)
+ (EXIT
+ (COND
+ ((QEQCAR |nn| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS 0 (SPADCALL (QCDR |nn|) (QREFELT |$| 30))))))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |n1|
+ (SPADCALL |n| (QREFELT |$| 55))
+ |UPOLYC-;nextItemInner|)
+ (LETT |n2|
+ (|UPOLYC-;nextItemInner| |n1| |$|)
+ |UPOLYC-;nextItemInner|)
+ (EXIT
+ (COND
+ ((QEQCAR |n2| 0)
+ (CONS
+ 0
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |n| (QREFELT |$| 53))
+ (SPADCALL |n| (QREFELT |$| 11))
+ (QREFELT |$| 49))
+ (QCDR |n2|)
+ (QREFELT |$| 65))))
+ ((|<|
+ (|+| 1 (SPADCALL |n1| (QREFELT |$| 11)))
+ (SPADCALL |n| (QREFELT |$| 11)))
+ (CONS
+ 0
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |n| (QREFELT |$| 53))
+ (SPADCALL |n| (QREFELT |$| 11))
+ (QREFELT |$| 49))
+ (SPADCALL
+ (PROG2
+ (LETT #1#
+ (SPADCALL
+ (|spadConstant| |$| 117)
+ (QREFELT |$| 120))
+ |UPOLYC-;nextItemInner|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 7) #1#))
+ (|+| 1 (SPADCALL |n1| (QREFELT |$| 11)))
+ (QREFELT |$| 49))
+ (QREFELT |$| 65))))
+ ((QUOTE T)
+ (SEQ
+ (LETT |n3|
+ (SPADCALL
+ (SPADCALL |n| (QREFELT |$| 53))
+ (QREFELT |$| 120))
+ |UPOLYC-;nextItemInner|)
+ (EXIT
+ (COND
+ ((QEQCAR |n3| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS
+ 0
+ (SPADCALL
+ (QCDR |n3|)
+ (SPADCALL |n| (QREFELT |$| 11))
+ (QREFELT |$| 49)))))))))))))))))
+
+(DEFUN |UPOLYC-;nextItem;SU;29| (|n| |$|)
+ (PROG (|n1| #1=#:G103350)
+ (RETURN
+ (SEQ
+ (LETT |n1| (|UPOLYC-;nextItemInner| |n| |$|) |UPOLYC-;nextItem;SU;29|)
+ (EXIT
+ (COND
+ ((QEQCAR |n1| 1)
+ (CONS
+ 0
+ (SPADCALL
+ (PROG2
+ (LETT #1#
+ (SPADCALL (|spadConstant| |$| 117) (QREFELT |$| 120))
+ |UPOLYC-;nextItem;SU;29|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 7) #1#))
+ (|+| 1 (SPADCALL |n| (QREFELT |$| 11)))
+ (QREFELT |$| 49))))
+ ((QUOTE T) |n1|)))))))
+
+(DEFUN |UPOLYC-;content;SSaosS;30| (|p| |v| |$|)
+ (SPADCALL (SPADCALL |p| (QREFELT |$| 123)) (QREFELT |$| 30)))
+
+(DEFUN |UPOLYC-;primeFactor| (|p| |q| |$|)
+ (PROG (#1=#:G103356 |p1|)
+ (RETURN
+ (SEQ
+ (LETT |p1|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p|
+ (SPADCALL |p| |q| (QREFELT |$| 125))
+ (QREFELT |$| 126))
+ |UPOLYC-;primeFactor|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 6) #1#))
+ |UPOLYC-;primeFactor|)
+ (EXIT
+ (COND
+ ((SPADCALL |p1| |p| (QREFELT |$| 127)) |p|)
+ ((QUOTE T) (|UPOLYC-;primeFactor| |p1| |q| |$|))))))))
+
+(DEFUN |UPOLYC-;separate;2SR;32| (|p| |q| |$|)
+ (PROG (|a| #1=#:G103362)
+ (RETURN
+ (SEQ
+ (LETT |a|
+ (|UPOLYC-;primeFactor| |p| |q| |$|)
+ |UPOLYC-;separate;2SR;32|)
+ (EXIT
+ (CONS
+ |a|
+ (PROG2
+ (LETT #1#
+ (SPADCALL |p| |a| (QREFELT |$| 126))
+ |UPOLYC-;separate;2SR;32|)
+ (QCDR #1#)
+ (|check-union| (QEQCAR #1# 0) (QREFELT |$| 6) #1#))))))))
+
+(DEFUN |UPOLYC-;differentiate;SM2S;33| (|x| |deriv| |x'| |$|)
+ (PROG (|dg| |lc| #1=#:G103367 |d|)
+ (RETURN
+ (SEQ
+ (LETT |d| (|spadConstant| |$| 60) |UPOLYC-;differentiate;SM2S;33|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (|<| 0
+ (LETT |dg|
+ (SPADCALL |x| (QREFELT |$| 11))
+ |UPOLYC-;differentiate;SM2S;33|)))
+ (GO G191)))
+ (SEQ
+ (LETT |lc|
+ (SPADCALL |x| (QREFELT |$| 53))
+ |UPOLYC-;differentiate;SM2S;33|)
+ (LETT |d|
+ (SPADCALL
+ (SPADCALL |d|
+ (SPADCALL |x'|
+ (SPADCALL
+ (SPADCALL |dg| |lc| (QREFELT |$| 131))
+ (PROG1
+ (LETT #1# (|-| |dg| 1) |UPOLYC-;differentiate;SM2S;33|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ (QREFELT |$| 49))
+ (QREFELT |$| 71))
+ (QREFELT |$| 65))
+ (SPADCALL
+ (SPADCALL |lc| |deriv|)
+ |dg|
+ (QREFELT |$| 49))
+ (QREFELT |$| 65))
+ |UPOLYC-;differentiate;SM2S;33|)
+ (EXIT
+ (LETT |x|
+ (SPADCALL |x| (QREFELT |$| 55))
+ |UPOLYC-;differentiate;SM2S;33|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT
+ (SPADCALL |d|
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |x| (QREFELT |$| 53))
+ |deriv|)
+ (QREFELT |$| 30))
+ (QREFELT |$| 65)))))))
+
+(DEFUN |UPOLYC-;ncdiff| (|n| |x'| |$|)
+ (PROG (#1=#:G103385 |n1|)
+ (RETURN
+ (COND
+ ((ZEROP |n|) (|spadConstant| |$| 60))
+ ((ZEROP
+ (LETT |n1|
+ (PROG1
+ (LETT #1# (|-| |n| 1) |UPOLYC-;ncdiff|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ |UPOLYC-;ncdiff|))
+ |x'|)
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL |x'|
+ (SPADCALL (|spadConstant| |$| 48) |n1| (QREFELT |$| 49))
+ (QREFELT |$| 71))
+ (SPADCALL
+ (SPADCALL (|spadConstant| |$| 48) 1 (QREFELT |$| 49))
+ (|UPOLYC-;ncdiff| |n1| |x'| |$|)
+ (QREFELT |$| 71))
+ (QREFELT |$| 65)))))))
+
+(DEFUN |UPOLYC-;differentiate;SM2S;35| (|x| |deriv| |x'| |$|)
+ (PROG (|dg| |lc| |d|)
+ (RETURN
+ (SEQ
+ (LETT |d| (|spadConstant| |$| 60) |UPOLYC-;differentiate;SM2S;35|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (|<| 0
+ (LETT |dg|
+ (SPADCALL |x| (QREFELT |$| 11))
+ |UPOLYC-;differentiate;SM2S;35|)))
+ (GO G191)))
+ (SEQ
+ (LETT |lc|
+ (SPADCALL |x| (QREFELT |$| 53))
+ |UPOLYC-;differentiate;SM2S;35|)
+ (LETT |d|
+ (SPADCALL
+ (SPADCALL |d|
+ (SPADCALL
+ (SPADCALL |lc| |deriv|)
+ |dg|
+ (QREFELT |$| 49))
+ (QREFELT |$| 65))
+ (SPADCALL |lc|
+ (|UPOLYC-;ncdiff| |dg| |x'| |$|)
+ (QREFELT |$| 134))
+ (QREFELT |$| 65))
+ |UPOLYC-;differentiate;SM2S;35|)
+ (EXIT
+ (LETT |x|
+ (SPADCALL |x| (QREFELT |$| 55))
+ |UPOLYC-;differentiate;SM2S;35|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT
+ (SPADCALL |d|
+ (SPADCALL
+ (SPADCALL (SPADCALL |x| (QREFELT |$| 53)) |deriv|)
+ (QREFELT |$| 30))
+ (QREFELT |$| 65)))))))
+
+(DEFUN |UPOLYC-;differentiate;SMS;36| (|x| |deriv| |$|)
+ (SPADCALL |x| |deriv| (|spadConstant| |$| 47) (QREFELT |$| 135)))
+
+(DEFUN |UPOLYC-;differentiate;2S;37| (|x| |$|)
+ (PROG (|dg| #1=#:G103394 |d|)
+ (RETURN
+ (SEQ
+ (LETT |d| (|spadConstant| |$| 60) |UPOLYC-;differentiate;2S;37|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (|<| 0
+ (LETT |dg|
+ (SPADCALL |x| (QREFELT |$| 11))
+ |UPOLYC-;differentiate;2S;37|)))
+ (GO G191)))
+ (SEQ
+ (LETT |d|
+ (SPADCALL |d|
+ (SPADCALL
+ (SPADCALL |dg|
+ (SPADCALL |x| (QREFELT |$| 53)) (QREFELT |$| 131))
+ (PROG1
+ (LETT #1# (|-| |dg| 1) |UPOLYC-;differentiate;2S;37|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ (QREFELT |$| 49))
+ (QREFELT |$| 65))
+ |UPOLYC-;differentiate;2S;37|)
+ (EXIT
+ (LETT |x|
+ (SPADCALL |x| (QREFELT |$| 55))
+ |UPOLYC-;differentiate;2S;37|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |d|)))))
+
+(DEFUN |UPOLYC-;differentiate;SSaosS;38| (|x| |v| |$|)
+ (SPADCALL |x| (QREFELT |$| 138)))
+
+(DEFUN |UPOLYC-;elt;3F;39| (|g| |f| |$|)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |g| (QREFELT |$| 141))
+ |f|
+ (QREFELT |$| 143))
+ (SPADCALL (SPADCALL |g| (QREFELT |$| 144)) |f| (QREFELT |$| 143))
+ (QREFELT |$| 145)))
+
+(DEFUN |UPOLYC-;pseudoQuotient;3S;40| (|p| |q| |$|)
+ (PROG (|n| #1=#:G103440 #2=#:G103442)
+ (RETURN
+ (SEQ
+ (LETT |n|
+ (|+|
+ (|-|
+ (SPADCALL |p| (QREFELT |$| 11))
+ (SPADCALL |q| (QREFELT |$| 11))) 1)
+ |UPOLYC-;pseudoQuotient;3S;40|)
+ (EXIT
+ (COND
+ ((|<| |n| 1) (|spadConstant| |$| 60))
+ ((QUOTE T)
+ (PROG2
+ (LETT #2#
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |q| (QREFELT |$| 53))
+ (PROG1
+ (LETT #1# |n| |UPOLYC-;pseudoQuotient;3S;40|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ (QREFELT |$| 147))
+ |p|
+ (QREFELT |$| 134))
+ (SPADCALL |p| |q| (QREFELT |$| 148))
+ (QREFELT |$| 149))
+ |q|
+ (QREFELT |$| 126))
+ |UPOLYC-;pseudoQuotient;3S;40|)
+ (QCDR #2#)
+ (|check-union| (QEQCAR #2# 0) (QREFELT |$| 6) #2#)))))))))
+
+(DEFUN |UPOLYC-;pseudoDivide;2SR;41| (|p| |q| |$|)
+ (PROG (|n| |prem| #1=#:G103448 |lc| #2=#:G103450)
+ (RETURN
+ (SEQ
+ (LETT |n|
+ (|+|
+ (|-|
+ (SPADCALL |p| (QREFELT |$| 11))
+ (SPADCALL |q| (QREFELT |$| 11))) 1)
+ |UPOLYC-;pseudoDivide;2SR;41|)
+ (EXIT
+ (COND
+ ((|<| |n| 1)
+ (VECTOR (|spadConstant| |$| 48) (|spadConstant| |$| 60) |p|))
+ ((QUOTE T)
+ (SEQ
+ (LETT |prem|
+ (SPADCALL |p| |q| (QREFELT |$| 148))
+ |UPOLYC-;pseudoDivide;2SR;41|)
+ (LETT |lc|
+ (SPADCALL
+ (SPADCALL |q| (QREFELT |$| 53))
+ (PROG1
+ (LETT #1# |n| |UPOLYC-;pseudoDivide;2SR;41|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|)) #1#))
+ (QREFELT |$| 147))
+ |UPOLYC-;pseudoDivide;2SR;41|)
+ (EXIT
+ (VECTOR |lc|
+ (PROG2
+ (LETT #2#
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |lc| |p| (QREFELT |$| 134))
+ |prem|
+ (QREFELT |$| 149))
+ |q|
+ (QREFELT |$| 126))
+ |UPOLYC-;pseudoDivide;2SR;41|)
+ (QCDR #2#)
+ (|check-union| (QEQCAR #2# 0) (QREFELT |$| 6) #2#))
+ |prem|))))))))))
+
+(DEFUN |UPOLYC-;composite;FSU;42| (|f| |q| |$|)
+ (PROG (|n| |d|)
+ (RETURN
+ (SEQ
+ (LETT |n|
+ (SPADCALL (SPADCALL |f| (QREFELT |$| 141)) |q| (QREFELT |$| 153))
+ |UPOLYC-;composite;FSU;42|)
+ (EXIT
+ (COND
+ ((QEQCAR |n| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |d|
+ (SPADCALL
+ (SPADCALL |f| (QREFELT |$| 144)) |q| (QREFELT |$| 153))
+ |UPOLYC-;composite;FSU;42|)
+ (EXIT
+ (COND
+ ((QEQCAR |d| 1) (CONS 1 "failed"))
+ ((QUOTE T)
+ (CONS
+ 0
+ (SPADCALL
+ (QCDR |n|)
+ (QCDR |d|)
+ (QREFELT |$| 154))))))))))))))
+
+(DEFUN |UPOLYC-;composite;2SU;43| (|p| |q| |$|)
+ (PROG (|cqr| |v| |u| |w| #1=#:G103476)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 157)) (CONS 0 |p|))
+ ((QUOTE T)
+ (SEQ
+ (EXIT
+ (SEQ
+ (LETT |cqr|
+ (SPADCALL |p| |q| (QREFELT |$| 158))
+ |UPOLYC-;composite;2SU;43|)
+ (COND
+ ((SPADCALL (QVELT |cqr| 2) (QREFELT |$| 157))
+ (SEQ
+ (LETT |v|
+ (SPADCALL
+ (QVELT |cqr| 2)
+ (QVELT |cqr| 0)
+ (QREFELT |$| 159))
+ |UPOLYC-;composite;2SU;43|)
+ (EXIT
+ (COND
+ ((QEQCAR |v| 0)
+ (SEQ
+ (LETT |u|
+ (SPADCALL
+ (QVELT |cqr| 1)
+ |q|
+ (QREFELT |$| 153))
+ |UPOLYC-;composite;2SU;43|)
+ (EXIT
+ (COND
+ ((QEQCAR |u| 0)
+ (SEQ
+ (LETT |w|
+ (SPADCALL
+ (QCDR |u|)
+ (QVELT |cqr| 0)
+ (QREFELT |$| 159))
+ |UPOLYC-;composite;2SU;43|)
+ (EXIT
+ (COND
+ ((QEQCAR |w| 0)
+ (PROGN
+ (LETT #1#
+ (CONS
+ 0
+ (SPADCALL
+ (QCDR |v|)
+ (SPADCALL
+ (SPADCALL
+ (|spadConstant| |$| 48)
+ 1
+ (QREFELT |$| 49))
+ (QCDR |w|)
+ (QREFELT |$| 71))
+ (QREFELT |$| 65)))
+ |UPOLYC-;composite;2SU;43|)
+ (GO #1#))))))))))))))))
+ (EXIT (CONS 1 "failed"))))
+ #1#
+ (EXIT #1#))))))))
+
+(DEFUN |UPOLYC-;elt;S2F;44| (|p| |f| |$|)
+ (PROG (|n| #1=#:G103483 |ans|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 9)) (|spadConstant| |$| 161))
+ ((QUOTE T)
+ (SEQ
+ (LETT |ans|
+ (SPADCALL
+ (SPADCALL (SPADCALL |p| (QREFELT |$| 53)) (QREFELT |$| 30))
+ (QREFELT |$| 162))
+ |UPOLYC-;elt;S2F;44|)
+ (LETT |n| (SPADCALL |p| (QREFELT |$| 11)) |UPOLYC-;elt;S2F;44|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL
+ (LETT |p|
+ (SPADCALL |p| (QREFELT |$| 55))
+ |UPOLYC-;elt;S2F;44|)
+ (QREFELT |$| 9))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (EXIT
+ (LETT |ans|
+ (SPADCALL
+ (SPADCALL |ans|
+ (SPADCALL |f|
+ (PROG1
+ (LETT #1#
+ (|-| |n|
+ (LETT |n|
+ (SPADCALL |p| (QREFELT |$| 11))
+ |UPOLYC-;elt;S2F;44|))
+ |UPOLYC-;elt;S2F;44|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ (QREFELT |$| 163))
+ (QREFELT |$| 164))
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |p| (QREFELT |$| 53))
+ (QREFELT |$| 30))
+ (QREFELT |$| 162))
+ (QREFELT |$| 165))
+ |UPOLYC-;elt;S2F;44|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT
+ (COND
+ ((ZEROP |n|) |ans|)
+ ((QUOTE T)
+ (SPADCALL |ans|
+ (SPADCALL |f| |n| (QREFELT |$| 166))
+ (QREFELT |$| 164))))))))))))
+
+(DEFUN |UPOLYC-;order;2SNni;45| (|p| |q| |$|)
+ (PROG (|u| #1=#:G103497 |ans|)
+ (RETURN
+ (SEQ
+ (EXIT
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 9))
+ (|error| "order: arguments must be nonzero"))
+ ((|<| (SPADCALL |q| (QREFELT |$| 11)) 1)
+ (|error| "order: place must be non-trivial"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |ans| 0 |UPOLYC-;order;2SNni;45|)
+ (EXIT
+ (SEQ G190
+ NIL
+ (SEQ
+ (LETT |u|
+ (SPADCALL |p| |q| (QREFELT |$| 126))
+ |UPOLYC-;order;2SNni;45|)
+ (EXIT
+ (COND
+ ((QEQCAR |u| 1)
+ (PROGN
+ (LETT #1# |ans| |UPOLYC-;order;2SNni;45|)
+ (GO #1#)))
+ ((QUOTE T)
+ (SEQ
+ (LETT |p| (QCDR |u|) |UPOLYC-;order;2SNni;45|)
+ (EXIT
+ (LETT
+ |ans|
+ (|+| |ans| 1)
+ |UPOLYC-;order;2SNni;45|)))))))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL)))))))
+ #1#
+ (EXIT #1#)))))
+
+(DEFUN |UPOLYC-;squareFree;SF;46| (|p| |$|)
+ (SPADCALL |p| (QREFELT |$| 170)))
+
+(DEFUN |UPOLYC-;squareFreePart;2S;47| (|p| |$|)
+ (SPADCALL |p| (QREFELT |$| 172)))
+
+(DEFUN |UPOLYC-;gcdPolynomial;3Sup;48| (|pp| |qq| |$|)
+ (COND
+ ((SPADCALL |pp| (QREFELT |$| 174)) (SPADCALL |qq| (QREFELT |$| 175)))
+ ((SPADCALL |qq| (QREFELT |$| 174)) (SPADCALL |pp| (QREFELT |$| 175)))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |pp| (QREFELT |$| 176))
+ (SPADCALL |qq| (QREFELT |$| 176)) (QREFELT |$| 125))
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |pp| (QREFELT |$| 177))
+ (SPADCALL |qq| (QREFELT |$| 177)) (QREFELT |$| 178))
+ (QREFELT |$| 177))
+ (QREFELT |$| 179))
+ (QREFELT |$| 175)))))
+
+(DEFUN |UPOLYC-;squareFreePolynomial;SupF;49| (|pp| |$|)
+ (SPADCALL |pp| (QREFELT |$| 182)))
+
+(DEFUN |UPOLYC-;elt;F2R;50| (|f| |r| |$|)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |f| (QREFELT |$| 141))
+ |r|
+ (QREFELT |$| 29))
+ (SPADCALL (SPADCALL |f| (QREFELT |$| 144)) |r| (QREFELT |$| 29))
+ (QREFELT |$| 184)))
+
+(DEFUN |UPOLYC-;euclideanSize;SNni;51| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 9))
+ (|error| "euclideanSize called on 0 in Univariate Polynomial"))
+ ((QUOTE T) (SPADCALL |x| (QREFELT |$| 11)))))
+
+(DEFUN |UPOLYC-;divide;2SR;52| (|x| |y| |$|)
+ (PROG (|lc| |f| #1=#:G103510 |n| |quot|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |y| (QREFELT |$| 9))
+ (|error| "division by 0 in Univariate Polynomials"))
+ ((QUOTE T)
+ (SEQ
+ (LETT |quot| (|spadConstant| |$| 60) |UPOLYC-;divide;2SR;52|)
+ (LETT |lc|
+ (SPADCALL (SPADCALL |y| (QREFELT |$| 53)) (QREFELT |$| 187))
+ |UPOLYC-;divide;2SR;52|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((OR
+ (SPADCALL |x| (QREFELT |$| 9))
+ (|<|
+ (SPADCALL |x| (QREFELT |$| 11))
+ (SPADCALL |y| (QREFELT |$| 11))))
+ (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |f|
+ (SPADCALL |lc|
+ (SPADCALL |x| (QREFELT |$| 53))
+ (QREFELT |$| 188))
+ |UPOLYC-;divide;2SR;52|)
+ (LETT |n|
+ (PROG1
+ (LETT #1#
+ (|-|
+ (SPADCALL |x| (QREFELT |$| 11))
+ (SPADCALL |y| (QREFELT |$| 11)))
+ |UPOLYC-;divide;2SR;52|)
+ (|check-subtype|
+ (|>=| #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#))
+ |UPOLYC-;divide;2SR;52|)
+ (LETT |quot|
+ (SPADCALL |quot|
+ (SPADCALL |f| |n| (QREFELT |$| 49))
+ (QREFELT |$| 65))
+ |UPOLYC-;divide;2SR;52|)
+ (EXIT
+ (LETT |x|
+ (SPADCALL |x|
+ (SPADCALL
+ (SPADCALL |f| |n| (QREFELT |$| 49))
+ |y|
+ (QREFELT |$| 71))
+ (QREFELT |$| 149))
+ |UPOLYC-;divide;2SR;52|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT (CONS |quot| |x|)))))))))
+
+(DEFUN |UPOLYC-;integrate;2S;53| (|p| |$|)
+ (PROG (|l| |d| |ans|)
+ (RETURN
+ (SEQ
+ (LETT |ans| (|spadConstant| |$| 60) |UPOLYC-;integrate;2S;53|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL |p| (|spadConstant| |$| 60) (QREFELT |$| 127))
+ (QUOTE NIL))
+ ((QUOTE T) (QUOTE T)))) (GO G191)))
+ (SEQ
+ (LETT |l|
+ (SPADCALL |p| (QREFELT |$| 53))
+ |UPOLYC-;integrate;2S;53|)
+ (LETT |d|
+ (|+| 1 (SPADCALL |p| (QREFELT |$| 11)))
+ |UPOLYC-;integrate;2S;53|)
+ (LETT |ans|
+ (SPADCALL |ans|
+ (SPADCALL
+ (SPADCALL (SPADCALL |d| (QREFELT |$| 191)) (QREFELT |$| 192))
+ (SPADCALL |l| |d| (QREFELT |$| 49)) (QREFELT |$| 193))
+ (QREFELT |$| 65))
+ |UPOLYC-;integrate;2S;53|)
+ (EXIT
+ (LETT |p|
+ (SPADCALL |p| (QREFELT |$| 55))
+ |UPOLYC-;integrate;2S;53|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (EXIT |ans|)))))
+
+(DEFUN |UnivariatePolynomialCategory&| (|#1| |#2|)
+ (PROG (|DV$1| |DV$2| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|UnivariatePolynomialCategory&|))
+ (LETT |DV$2| (|devaluate| |#2|) . #1#)
+ (LETT |dv$|
+ (LIST (QUOTE |UnivariatePolynomialCategory&|) |DV$1| |DV$2|) . #1#)
+ (LETT |$| (GETREFV 201) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3
+ (LETT |pv$|
+ (|buildPredVector| 0 0
+ (LIST
+ (|HasCategory| |#2|
+ (QUOTE (|Algebra| (|Fraction| (|Integer|)))))
+ (|HasCategory| |#2| (QUOTE (|Field|)))
+ (|HasCategory| |#2| (QUOTE (|GcdDomain|)))
+ (|HasCategory| |#2| (QUOTE (|IntegralDomain|)))
+ (|HasCategory| |#2| (QUOTE (|CommutativeRing|)))
+ (|HasCategory| |#2| (QUOTE (|StepThrough|))))) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ (QSETREFV |$| 7 |#2|)
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|PolynomialFactorizationExplicit|)))
+ (PROGN
+ (QSETREFV |$| 81
+ (CONS
+ (|dispatchFunction|
+ |UPOLYC-;solveLinearPolynomialEquation;LSupU;20|)
+ |$|))
+ (QSETREFV |$| 85
+ (CONS
+ (|dispatchFunction| |UPOLYC-;factorPolynomial;SupF;21|)
+ |$|))
+ (QSETREFV |$| 87
+ (CONS
+ (|dispatchFunction|
+ |UPOLYC-;factorSquareFreePolynomial;SupF;22|)
+ |$|))
+ (QSETREFV |$| 105
+ (CONS (|dispatchFunction| |UPOLYC-;factor;SF;23|) |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 6)
+ (PROGN
+ (QSETREFV |$| 118
+ (CONS (|dispatchFunction| |UPOLYC-;init;S;27|) |$|))
+ NIL
+ (QSETREFV |$| 122
+ (CONS (|dispatchFunction| |UPOLYC-;nextItem;SU;29|) |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 3)
+ (PROGN
+ (QSETREFV |$| 124
+ (CONS (|dispatchFunction| |UPOLYC-;content;SSaosS;30|) |$|))
+ NIL
+ (QSETREFV |$| 129
+ (CONS (|dispatchFunction| |UPOLYC-;separate;2SR;32|) |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 5)
+ (QSETREFV |$| 133
+ (CONS
+ (|dispatchFunction| |UPOLYC-;differentiate;SM2S;33|)
+ |$|)))
+ ((QUOTE T)
+ (PROGN
+ (QSETREFV |$| 133
+ (CONS
+ (|dispatchFunction| |UPOLYC-;differentiate;SM2S;35|)
+ |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 4)
+ (PROGN
+ (QSETREFV |$| 146
+ (CONS (|dispatchFunction| |UPOLYC-;elt;3F;39|) |$|))
+ (QSETREFV |$| 150
+ (CONS (|dispatchFunction| |UPOLYC-;pseudoQuotient;3S;40|) |$|))
+ (QSETREFV |$| 152
+ (CONS (|dispatchFunction| |UPOLYC-;pseudoDivide;2SR;41|) |$|))
+ (QSETREFV |$| 156
+ (CONS (|dispatchFunction| |UPOLYC-;composite;FSU;42|) |$|))
+ (QSETREFV |$| 160
+ (CONS (|dispatchFunction| |UPOLYC-;composite;2SU;43|) |$|))
+ (QSETREFV |$| 167
+ (CONS (|dispatchFunction| |UPOLYC-;elt;S2F;44|) |$|))
+ (QSETREFV |$| 168
+ (CONS (|dispatchFunction| |UPOLYC-;order;2SNni;45|) |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 3)
+ (PROGN
+ (QSETREFV |$| 171
+ (CONS (|dispatchFunction| |UPOLYC-;squareFree;SF;46|) |$|))
+ (QSETREFV |$| 173
+ (CONS
+ (|dispatchFunction| |UPOLYC-;squareFreePart;2S;47|)
+ |$|)))))
+ (COND
+ ((|HasCategory| |#2| (QUOTE (|PolynomialFactorizationExplicit|)))
+ (PROGN
+ (QSETREFV |$| 180
+ (CONS
+ (|dispatchFunction| |UPOLYC-;gcdPolynomial;3Sup;48|)
+ |$|))
+ (QSETREFV |$| 183
+ (CONS
+ (|dispatchFunction| |UPOLYC-;squareFreePolynomial;SupF;49|)
+ |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 2)
+ (PROGN
+ (QSETREFV |$| 185
+ (CONS (|dispatchFunction| |UPOLYC-;elt;F2R;50|) |$|))
+ (QSETREFV |$| 186
+ (CONS
+ (|dispatchFunction| |UPOLYC-;euclideanSize;SNni;51|)
+ |$|))
+ (QSETREFV |$| 189
+ (CONS (|dispatchFunction| |UPOLYC-;divide;2SR;52|) |$|)))))
+ (COND
+ ((|testBitVector| |pv$| 1)
+ (QSETREFV |$| 194
+ (CONS
+ (|dispatchFunction| |UPOLYC-;integrate;2S;53|)
+ |$|)))) |$|))))
+
+(MAKEPROP
+ (QUOTE |UnivariatePolynomialCategory&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|local| |#2|)
+ (|Boolean|)
+ (0 . |zero?|)
+ (|NonNegativeInteger|)
+ (5 . |degree|)
+ (|SingletonAsOrderedSet|)
+ (10 . |create|)
+ (|List| 12)
+ |UPOLYC-;variables;SL;1|
+ |UPOLYC-;degree;SSaosNni;2|
+ (14 . |totalDegree|)
+ |UPOLYC-;totalDegree;SLNni;3|
+ (|List| 10)
+ |UPOLYC-;degree;SLL;4|
+ (19 . |eval|)
+ (|List| |$|)
+ |UPOLYC-;eval;SLLS;5|
+ (26 . |elt|)
+ |UPOLYC-;eval;SSaos2S;6|
+ (32 . |eval|)
+ (|List| 7)
+ |UPOLYC-;eval;SLLS;7|
+ (39 . |elt|)
+ (45 . |coerce|)
+ |UPOLYC-;eval;SSaosRS;8|
+ (|Equation| 6)
+ (50 . |lhs|)
+ (|Union| 12 (QUOTE "failed"))
+ (55 . |mainVariable|)
+ (60 . |rhs|)
+ (|List| 197)
+ |UPOLYC-;eval;SLS;9|
+ |UPOLYC-;mainVariable;SU;10|
+ (65 . |minimumDegree|)
+ |UPOLYC-;minimumDegree;SSaosNni;11|
+ |UPOLYC-;minimumDegree;SLL;12|
+ (70 . |+|)
+ (|Mapping| 10 10)
+ (76 . |mapExponents|)
+ |UPOLYC-;monomial;SSaosNniS;13|
+ (82 . |One|)
+ (86 . |One|)
+ (90 . |monomial|)
+ |UPOLYC-;coerce;SaosS;14|
+ (|SparseUnivariatePolynomial| 7)
+ (96 . |Zero|)
+ (100 . |leadingCoefficient|)
+ (105 . |monomial|)
+ (111 . |reductum|)
+ (116 . |makeSUP|)
+ (121 . |+|)
+ |UPOLYC-;makeSUP;SSup;15|
+ (127 . |zero?|)
+ (132 . |Zero|)
+ (136 . |leadingCoefficient|)
+ (141 . |degree|)
+ (146 . |reductum|)
+ (151 . |unmakeSUP|)
+ (156 . |+|)
+ |UPOLYC-;unmakeSUP;SupS;16|
+ (|Record| (|:| |quotient| |$|) (|:| |remainder| |$|))
+ (162 . |monicDivide|)
+ |UPOLYC-;karatsubaDivide;SNniR;17|
+ |UPOLYC-;shiftRight;SNniS;18|
+ (168 . |*|)
+ |UPOLYC-;shiftLeft;SNniS;19|
+ (|Union| 74 (QUOTE "failed"))
+ (|List| 75)
+ (|SparseUnivariatePolynomial| 6)
+ (|PolynomialFactorizationByRecursionUnivariate| 7 6)
+ (174 . |solveLinearPolynomialEquationByRecursion|)
+ (|Union| 79 (QUOTE "failed"))
+ (|List| 80)
+ (|SparseUnivariatePolynomial| |$|)
+ (180 . |solveLinearPolynomialEquation|)
+ (|Factored| 75)
+ (186 . |factorByRecursion|)
+ (|Factored| 80)
+ (191 . |factorPolynomial|)
+ (196 . |factorSquareFreeByRecursion|)
+ (201 . |factorSquareFreePolynomial|)
+ (|Factored| |$|)
+ (206 . |factor|)
+ (|Factored| 7)
+ (211 . |unit|)
+ (|Union| (QUOTE "nil") (QUOTE "sqfr") (QUOTE "irred") (QUOTE "prime"))
+ (|Record| (|:| |flg| 92) (|:| |fctr| 7) (|:| |xpnt| 109))
+ (|List| 93)
+ (216 . |factorList|)
+ (|Record| (|:| |flg| 92) (|:| |fctr| 6) (|:| |xpnt| 109))
+ (|List| 96)
+ (|Factored| 6)
+ (221 . |makeFR|)
+ (227 . |factorPolynomial|)
+ (|Mapping| 6 51)
+ (|Factored| 51)
+ (|FactoredFunctions2| 51 6)
+ (232 . |map|)
+ (238 . |factor|)
+ (243 . |Zero|)
+ (|Vector| 7)
+ (247 . |new|)
+ (|Integer|)
+ (253 . |minIndex|)
+ (258 . |coefficient|)
+ (264 . |qsetelt!|)
+ |UPOLYC-;vectorise;SNniV;24|
+ |UPOLYC-;retract;SR;25|
+ (|Union| 7 (QUOTE "failed"))
+ |UPOLYC-;retractIfCan;SU;26|
+ (271 . |init|)
+ (275 . |init|)
+ (|Union| |$| (QUOTE "failed"))
+ (279 . |nextItem|)
+ (284 . |One|)
+ (288 . |nextItem|)
+ (293 . |content|)
+ (298 . |content|)
+ (304 . |gcd|)
+ (310 . |exquo|)
+ (316 . |=|)
+ (|Record| (|:| |primePart| |$|) (|:| |commonPart| |$|))
+ (322 . |separate|)
+ (328 . |Zero|)
+ (332 . |*|)
+ (|Mapping| 7 7)
+ (338 . |differentiate|)
+ (345 . |*|)
+ (351 . |differentiate|)
+ |UPOLYC-;differentiate;SMS;36|
+ |UPOLYC-;differentiate;2S;37|
+ (358 . |differentiate|)
+ |UPOLYC-;differentiate;SSaosS;38|
+ (|Fraction| 6)
+ (363 . |numer|)
+ (|Fraction| |$|)
+ (368 . |elt|)
+ (374 . |denom|)
+ (379 . |/|)
+ (385 . |elt|)
+ (391 . |**|)
+ (397 . |pseudoRemainder|)
+ (403 . |-|)
+ (409 . |pseudoQuotient|)
+ (|Record| (|:| |coef| 7) (|:| |quotient| |$|) (|:| |remainder| |$|))
+ (415 . |pseudoDivide|)
+ (421 . |composite|)
+ (427 . |/|)
+ (|Union| 142 (QUOTE "failed"))
+ (433 . |composite|)
+ (439 . |ground?|)
+ (444 . |pseudoDivide|)
+ (450 . |exquo|)
+ (456 . |composite|)
+ (462 . |Zero|)
+ (466 . |coerce|)
+ (471 . |**|)
+ (477 . |*|)
+ (483 . |+|)
+ (489 . |**|)
+ (495 . |elt|)
+ (501 . |order|)
+ (|UnivariatePolynomialSquareFree| 7 6)
+ (507 . |squareFree|)
+ (512 . |squareFree|)
+ (517 . |squareFreePart|)
+ (522 . |squareFreePart|)
+ (527 . |zero?|)
+ (532 . |unitCanonical|)
+ (537 . |content|)
+ (542 . |primitivePart|)
+ (547 . |subResultantGcd|)
+ (553 . |*|)
+ (559 . |gcdPolynomial|)
+ (|UnivariatePolynomialSquareFree| 6 75)
+ (565 . |squareFree|)
+ (570 . |squareFreePolynomial|)
+ (575 . |/|)
+ (581 . |elt|)
+ (587 . |euclideanSize|)
+ (592 . |inv|)
+ (597 . |*|)
+ (603 . |divide|)
+ (|Fraction| 109)
+ (609 . |coerce|)
+ (614 . |inv|)
+ (619 . |*|)
+ (625 . |integrate|)
+ (|Symbol|)
+ (|List| 195)
+ (|Equation| |$|)
+ (|Union| 109 (QUOTE "failed"))
+ (|Union| 190 (QUOTE "failed"))
+ (|OutputForm|)))
+ (QUOTE
+ #(|vectorise| 630 |variables| 636 |unmakeSUP| 641 |totalDegree| 646
+ |squareFreePolynomial| 652 |squareFreePart| 657 |squareFree| 662
+ |solveLinearPolynomialEquation| 667 |shiftRight| 673 |shiftLeft| 679
+ |separate| 685 |retractIfCan| 691 |retract| 696 |pseudoQuotient| 701
+ |pseudoDivide| 707 |order| 713 |nextItem| 719 |monomial| 724
+ |minimumDegree| 731 |makeSUP| 743 |mainVariable| 748
+ |karatsubaDivide| 753 |integrate| 759 |init| 764 |gcdPolynomial| 768
+ |factorSquareFreePolynomial| 774 |factorPolynomial| 779 |factor| 784
+ |eval| 789 |euclideanSize| 823 |elt| 828 |divide| 846
+ |differentiate| 852 |degree| 876 |content| 888 |composite| 894
+ |coerce| 906))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 194
+ (QUOTE
+ (1 6 8 0 9 1 6 10 0 11 0 12 0 13 1 6 10 0 17 3 6 0 0 12 0 21 2
+ 6 0 0 0 24 3 6 0 0 12 7 26 2 6 7 0 7 29 1 6 0 7 30 1 32 6 0 33
+ 1 6 34 0 35 1 32 6 0 36 1 6 10 0 40 2 10 0 0 0 43 2 6 0 44 0
+ 45 0 6 0 47 0 7 0 48 2 6 0 7 10 49 0 51 0 52 1 6 7 0 53 2 51
+ 0 7 10 54 1 6 0 0 55 1 6 51 0 56 2 51 0 0 0 57 1 51 8 0 59 0
+ 6 0 60 1 51 7 0 61 1 51 10 0 62 1 51 0 0 63 1 6 0 51 64 2 6 0
+ 0 0 65 2 6 67 0 0 68 2 6 0 0 0 71 2 76 73 74 75 77 2 0 78 79
+ 80 81 1 76 82 75 83 1 0 84 80 85 1 76 82 75 86 1 0 84 80 87 1
+ 7 88 0 89 1 90 7 0 91 1 90 94 0 95 2 98 0 6 97 99 1 7 84 80
+ 100 2 103 98 101 102 104 1 0 88 0 105 0 7 0 106 2 107 0 10 7
+ 108 1 107 109 0 110 2 6 7 0 10 111 3 107 7 0 109 7 112 0 7 0
+ 117 0 0 0 118 1 7 119 0 120 0 75 0 121 1 0 119 0 122 1 6 7 0
+ 123 2 0 0 0 12 124 2 6 0 0 0 125 2 6 119 0 0 126 2 6 8 0 0 127
+ 2 0 128 0 0 129 0 75 0 130 2 7 0 10 0 131 3 0 0 0 132 0 133 2
+ 6 0 7 0 134 3 6 0 0 132 0 135 1 6 0 0 138 1 140 6 0 141 2 6
+ 142 0 142 143 1 140 6 0 144 2 140 0 0 0 145 2 0 142 142 142
+ 146 2 7 0 0 10 147 2 6 0 0 0 148 2 6 0 0 0 149 2 0 0 0 0 150
+ 2 0 151 0 0 152 2 6 119 0 0 153 2 140 0 6 6 154 2 0 155 142 0
+ 156 1 6 8 0 157 2 6 151 0 0 158 2 6 119 0 7 159 2 0 119 0 0
+ 160 0 140 0 161 1 140 0 6 162 2 140 0 0 109 163 2 140 0 0 0
+ 164 2 140 0 0 0 165 2 140 0 0 10 166 2 0 142 0 142 167 2 0 10
+ 0 0 168 1 169 98 6 170 1 0 88 0 171 1 169 6 6 172 1 0 0 0 173
+ 1 75 8 0 174 1 75 0 0 175 1 75 6 0 176 1 75 0 0 177 2 75 0 0
+ 0 178 2 75 0 6 0 179 2 0 80 80 80 180 1 181 82 75 182 1 0 84
+ 80 183 2 7 0 0 0 184 2 0 7 142 7 185 1 0 10 0 186 1 7 0 0 187
+ 2 7 0 0 0 188 2 0 67 0 0 189 1 190 0 109 191 1 190 0 0 192 2
+ 6 0 190 0 193 1 0 0 0 194 2 0 107 0 10 113 1 0 14 0 15 1 0 0
+ 51 66 2 0 10 0 14 18 1 0 84 80 183 1 0 0 0 173 1 0 88 0 171 2
+ 0 78 79 80 81 2 0 0 0 10 70 2 0 0 0 10 72 2 0 128 0 0 129 1 0
+ 115 0 116 1 0 7 0 114 2 0 0 0 0 150 2 0 151 0 0 152 2 0 10 0
+ 0 168 1 0 119 0 122 3 0 0 0 12 10 46 2 0 19 0 14 42 2 0 10 0
+ 12 41 1 0 51 0 58 1 0 34 0 39 2 0 67 0 10 69 1 0 0 0 194 0 0
+ 0 118 2 0 80 80 80 180 1 0 84 80 87 1 0 84 80 85 1 0 88 0 105
+ 3 0 0 0 12 0 25 3 0 0 0 14 22 23 3 0 0 0 14 27 28 3 0 0 0 12
+ 7 31 2 0 0 0 37 38 1 0 10 0 186 2 0 142 0 142 167 2 0 7 142 7
+ 185 2 0 142 142 142 146 2 0 67 0 0 189 3 0 0 0 132 0 133 2 0
+ 0 0 132 136 1 0 0 0 137 2 0 0 0 12 139 2 0 10 0 12 16 2 0 19
+ 0 14 20 2 0 0 0 12 124 2 0 119 0 0 160 2 0 155 142 0 156 1 0
+ 0 12 50))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{package UPOLYC2 UnivariatePolynomialCategoryFunctions2}
+<<package UPOLYC2 UnivariatePolynomialCategoryFunctions2>>=
+)abbrev package UPOLYC2 UnivariatePolynomialCategoryFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Mapping from polynomials over R to polynomials over S
+++ given a map from R to S assumed to send zero to zero.
+
+UnivariatePolynomialCategoryFunctions2(R,PR,S,PS): Exports == Impl where
+ R, S: Ring
+ PR : UnivariatePolynomialCategory R
+ PS : UnivariatePolynomialCategory S
+
+ Exports ==> with
+ map: (R -> S, PR) -> PS
+ ++ map(f, p) takes a function f from R to S,
+ ++ and applies it to each (non-zero) coefficient of a polynomial p
+ ++ over R, getting a new polynomial over S.
+ ++ Note: since the map is not applied to zero elements, it may map zero
+ ++ to zero.
+
+ Impl ==> add
+ map(f, p) ==
+ ans:PS := 0
+ while p ^= 0 repeat
+ ans := ans + monomial(f leadingCoefficient p, degree p)
+ p := reductum p
+ ans
+
+@
+\section{package COMMUPC CommuteUnivariatePolynomialCategory}
+<<package COMMUPC CommuteUnivariatePolynomialCategory>>=
+)abbrev package COMMUPC CommuteUnivariatePolynomialCategory
+++ Author: Manuel Bronstein
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A package for swapping the order of two variables in a tower of two
+++ UnivariatePolynomialCategory extensions.
+
+CommuteUnivariatePolynomialCategory(R, UP, UPUP): Exports == Impl where
+ R : Ring
+ UP : UnivariatePolynomialCategory R
+ UPUP: UnivariatePolynomialCategory UP
+
+ N ==> NonNegativeInteger
+
+ Exports ==> with
+ swap: UPUP -> UPUP
+ ++ swap(p(x,y)) returns p(y,x).
+
+ Impl ==> add
+ makePoly: (UP, N) -> UPUP
+
+-- converts P(x,y) to P(y,x)
+ swap poly ==
+ ans:UPUP := 0
+ while poly ^= 0 repeat
+ ans := ans + makePoly(leadingCoefficient poly, degree poly)
+ poly := reductum poly
+ ans
+
+ makePoly(poly, d) ==
+ ans:UPUP := 0
+ while poly ^= 0 repeat
+ ans := ans +
+ monomial(monomial(leadingCoefficient poly, d), degree poly)
+ poly := reductum poly
+ ans
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category AMR AbelianMonoidRing>>
+<<category FAMR FiniteAbelianMonoidRing>>
+<<category POLYCAT PolynomialCategory>>
+<<package POLYLIFT PolynomialCategoryLifting>>
+<<category UPOLYC UnivariatePolynomialCategory>>
+<<package UPOLYC2 UnivariatePolynomialCategoryFunctions2>>
+<<package COMMUPC CommuteUnivariatePolynomialCategory>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/primelt.spad.pamphlet b/src/algebra/primelt.spad.pamphlet
new file mode 100644
index 00000000..baee4e62
--- /dev/null
+++ b/src/algebra/primelt.spad.pamphlet
@@ -0,0 +1,269 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra primelt.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PRIMELT PrimitiveElement}
+<<package PRIMELT PrimitiveElement>>=
+)abbrev package PRIMELT PrimitiveElement
+++ Computation of primitive elements.
+++ Author: Manuel Bronstein
+++ Date Created: 6 Jun 1990
+++ Date Last Updated: 25 April 1991
+++ Description:
+++ PrimitiveElement provides functions to compute primitive elements
+++ in algebraic extensions;
+++ Keywords: algebraic, extension, primitive.
+PrimitiveElement(F): Exports == Implementation where
+ F : Join(Field, CharacteristicZero)
+
+ SY ==> Symbol
+ P ==> Polynomial F
+ UP ==> SparseUnivariatePolynomial F
+ RC ==> Record(coef1: Integer, coef2: Integer, prim:UP)
+ REC ==> Record(coef: List Integer, poly:List UP, prim: UP)
+
+ Exports ==> with
+ primitiveElement: (P, SY, P, SY) -> RC
+ ++ primitiveElement(p1, a1, p2, a2) returns \spad{[c1, c2, q]}
+ ++ such that \spad{k(a1, a2) = k(a)}
+ ++ where \spad{a = c1 a1 + c2 a2, and q(a) = 0}.
+ ++ The pi's are the defining polynomials for the ai's.
+ ++ The p2 may involve a1, but p1 must not involve a2.
+ ++ This operation uses \spadfun{resultant}.
+ primitiveElement: (List P, List SY) -> REC
+ ++ primitiveElement([p1,...,pn], [a1,...,an]) returns
+ ++ \spad{[[c1,...,cn], [q1,...,qn], q]}
+ ++ such that then \spad{k(a1,...,an) = k(a)},
+ ++ where \spad{a = a1 c1 + ... + an cn},
+ ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+ ++ The pi's are the defining polynomials for the ai's.
+ ++ This operation uses the technique of
+ ++ \spadglossSee{groebner bases}{Groebner basis}.
+ primitiveElement: (List P, List SY, SY) -> REC
+ ++ primitiveElement([p1,...,pn], [a1,...,an], a) returns
+ ++ \spad{[[c1,...,cn], [q1,...,qn], q]}
+ ++ such that then \spad{k(a1,...,an) = k(a)},
+ ++ where \spad{a = a1 c1 + ... + an cn},
+ ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+ ++ The pi's are the defining polynomials for the ai's.
+ ++ This operation uses the technique of
+ ++ \spadglossSee{groebner bases}{Groebner basis}.
+
+ Implementation ==> add
+ import PolyGroebner(F)
+
+ multi : (UP, SY) -> P
+ randomInts: (NonNegativeInteger, NonNegativeInteger) -> List Integer
+ findUniv : (List P, SY, SY) -> Union(P, "failed")
+ incl? : (List SY, List SY) -> Boolean
+ triangularLinearIfCan:(List P,List SY,SY) -> Union(List UP,"failed")
+ innerPrimitiveElement: (List P, List SY, SY) -> REC
+
+ multi(p, v) == multivariate(map(#1, p), v)
+ randomInts(n, m) == [symmetricRemainder(random()$Integer, m) for i in 1..n]
+ incl?(a, b) == every?(member?(#1, b), a)
+ primitiveElement(l, v) == primitiveElement(l, v, new()$SY)
+
+ primitiveElement(p1, a1, p2, a2) ==
+-- one? degree(p2, a1) => [0, 1, univariate resultant(p1, p2, a1)]
+ (degree(p2, a1) = 1) => [0, 1, univariate resultant(p1, p2, a1)]
+ u := (new()$SY)::P
+ b := a2::P
+ for i in 10.. repeat
+ c := symmetricRemainder(random()$Integer, i)
+ w := u - c * b
+ r := univariate resultant(eval(p1, a1, w), eval(p2, a1, w), a2)
+ not zero? r and r = squareFreePart r => return [1, c, r]
+
+ findUniv(l, v, opt) ==
+ for p in l repeat
+ degree(p, v) > 0 and incl?(variables p, [v, opt]) => return p
+ "failed"
+
+ triangularLinearIfCan(l, lv, w) ==
+ (u := findUniv(l, w, w)) case "failed" => "failed"
+ pw := univariate(u::P)
+ ll := nil()$List(UP)
+ for v in lv repeat
+ ((u := findUniv(l, v, w)) case "failed") or
+ (degree(p := univariate(u::P, v)) ^= 1) => return "failed"
+ (bc := extendedEuclidean(univariate leadingCoefficient p, pw,1))
+ case "failed" => error "Should not happen"
+ ll := concat(map(#1,
+ (- univariate(coefficient(p,0)) * bc.coef1) rem pw), ll)
+ concat(map(#1, pw), reverse_! ll)
+
+ primitiveElement(l, vars, uu) ==
+ u := uu::P
+ vv := [v::P for v in vars]
+ elim := concat(vars, uu)
+ w := uu::P
+ n := #l
+ for i in 10.. repeat
+ cf := randomInts(n, i)
+ (tt := triangularLinearIfCan(lexGroebner(
+ concat(w - +/[c * t for c in cf for t in vv], l), elim),
+ vars, uu)) case List(UP) =>
+ ltt := tt::List(UP)
+ return([cf, rest ltt, first ltt])
+
+@
+\section{package FSPRMELT FunctionSpacePrimitiveElement}
+<<package FSPRMELT FunctionSpacePrimitiveElement>>=
+)abbrev package FSPRMELT FunctionSpacePrimitiveElement
+++ Computation of primitive elements.
+++ Author: Manuel Bronstein
+++ Date Created: 6 Jun 1990
+++ Date Last Updated: 25 April 1991
+++ Description:
+++ FunctionsSpacePrimitiveElement provides functions to compute
+++ primitive elements in functions spaces;
+++ Keywords: algebraic, extension, primitive.
+FunctionSpacePrimitiveElement(R, F): Exports == Implementation where
+ R: Join(IntegralDomain, OrderedSet, CharacteristicZero)
+ F: FunctionSpace R
+
+ SY ==> Symbol
+ P ==> Polynomial F
+ K ==> Kernel F
+ UP ==> SparseUnivariatePolynomial F
+ REC ==> Record(primelt:F, poly:List UP, prim:UP)
+
+ Exports ==> with
+ primitiveElement: List F -> Record(primelt:F, poly:List UP, prim:UP)
+ ++ primitiveElement([a1,...,an]) returns \spad{[a, [q1,...,qn], q]}
+ ++ such that then \spad{k(a1,...,an) = k(a)},
+ ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+ ++ This operation uses the technique of
+ ++ \spadglossSee{groebner bases}{Groebner basis}.
+ if F has AlgebraicallyClosedField then
+ primitiveElement: (F,F)->Record(primelt:F,pol1:UP,pol2:UP,prim:UP)
+ ++ primitiveElement(a1, a2) returns \spad{[a, q1, q2, q]}
+ ++ such that \spad{k(a1, a2) = k(a)},
+ ++ \spad{ai = qi(a)}, and \spad{q(a) = 0}.
+ ++ The minimal polynomial for a2 may involve a1, but the
+ ++ minimal polynomial for a1 may not involve a2;
+ ++ This operations uses \spadfun{resultant}.
+
+ Implementation ==> add
+ import PrimitiveElement(F)
+ import AlgebraicManipulations(R, F)
+ import PolynomialCategoryLifting(IndexedExponents K,
+ K, R, SparseMultivariatePolynomial(R, K), P)
+
+ F2P: (F, List SY) -> P
+ K2P: (K, List SY) -> P
+
+ F2P(f, l) == inv(denom(f)::F) * map(K2P(#1, l), #1::F::P, numer f)
+
+ K2P(k, l) ==
+ ((v := symbolIfCan k) case SY) and member?(v::SY, l) => v::SY::P
+ k::F::P
+
+ primitiveElement l ==
+ u := string(uu := new()$SY)
+ vars := [concat(u, string i)::SY for i in 1..#l]
+ vv := [kernel(v)$K :: F for v in vars]
+ kers := [retract(a)@K for a in l]
+ pols := [F2P(subst(ratDenom((minPoly k) v, kers), kers, vv), vars)
+ for k in kers for v in vv]
+ rec := primitiveElement(pols, vars, uu)
+ [+/[c * a for c in rec.coef for a in l], rec.poly, rec.prim]
+
+ if F has AlgebraicallyClosedField then
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, SparseMultivariatePolynomial(R, K), F)
+
+ F2UP: (UP, K, UP) -> UP
+ getpoly: (UP, F) -> UP
+
+ F2UP(p, k, q) ==
+ ans:UP := 0
+ while not zero? p repeat
+ f := univariate(leadingCoefficient p, k)
+ ans := ans + ((numer f) q)
+ * monomial(inv(retract(denom f)@F), degree p)
+ p := reductum p
+ ans
+
+ primitiveElement(a1, a2) ==
+ a := (aa := new()$SY)::F
+ b := (bb := new()$SY)::F
+ l := [aa, bb]$List(SY)
+ p1 := minPoly(k1 := retract(a1)@K)
+ p2 := map(subst(ratDenom(#1, [k1]), [k1], [a]),
+ minPoly(retract(a2)@K))
+ rec := primitiveElement(F2P(p1 a, l), aa, F2P(p2 b, l), bb)
+ w := rec.coef1 * a1 + rec.coef2 * a2
+ g := rootOf(rec.prim)
+ zero?(rec.coef1) =>
+ c2g := inv(rec.coef2 :: F) * g
+ r := gcd(p1, univariate(p2 c2g, retract(a)@K, p1))
+ q := getpoly(r, g)
+ [w, q, rec.coef2 * monomial(1, 1)$UP, rec.prim]
+ ic1 := inv(rec.coef1 :: F)
+ gg := (ic1 * g)::UP - monomial(rec.coef2 * ic1, 1)$UP
+ kg := retract(g)@K
+ r := gcd(p1 gg, F2UP(p2, retract(a)@K, gg))
+ q := getpoly(r, g)
+ [w, monomial(ic1, 1)$UP - rec.coef2 * ic1 * q, q, rec.prim]
+
+ getpoly(r, g) ==
+-- one? degree r =>
+ (degree r = 1) =>
+ k := retract(g)@K
+ univariate(-coefficient(r,0)/leadingCoefficient r,k,minPoly k)
+ error "GCD not of degree 1"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PRIMELT PrimitiveElement>>
+<<package FSPRMELT FunctionSpacePrimitiveElement>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/print.spad.pamphlet b/src/algebra/print.spad.pamphlet
new file mode 100644
index 00000000..8d836394
--- /dev/null
+++ b/src/algebra/print.spad.pamphlet
@@ -0,0 +1,75 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra print.spad}
+\author{Scott Morrison}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PRINT PrintPackage}
+<<package PRINT PrintPackage>>=
+)abbrev package PRINT PrintPackage
+++ Author: Scott Morrison
+++ Date Created: Aug. 1, 1990
+++ Date Last Updated:
+++ Basic Operations: print
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: print
+++ References:
+++ Description: PrintPackage provides a print function for output forms.
+PrintPackage(): with
+ print : OutputForm -> Void
+ ++ print(o) writes the output form o on standard output using the
+ ++ two-dimensional formatter.
+ == add
+ print(x) == print(x)$OutputForm
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PRINT PrintPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/product.spad.pamphlet b/src/algebra/product.spad.pamphlet
new file mode 100644
index 00000000..0787277e
--- /dev/null
+++ b/src/algebra/product.spad.pamphlet
@@ -0,0 +1,151 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra product.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PRODUCT Product}
+<<domain PRODUCT Product>>=
+)abbrev domain PRODUCT Product
+++ Description:
+++ This domain implements cartesian product
+Product (A:SetCategory,B:SetCategory) : C == T
+ where
+ C == SetCategory with
+ if A has Finite and B has Finite then Finite
+ if A has Monoid and B has Monoid then Monoid
+ if A has AbelianMonoid and B has AbelianMonoid then AbelianMonoid
+ if A has CancellationAbelianMonoid and
+ B has CancellationAbelianMonoid then CancellationAbelianMonoid
+ if A has Group and B has Group then Group
+ if A has AbelianGroup and B has AbelianGroup then AbelianGroup
+ if A has OrderedAbelianMonoidSup and B has OrderedAbelianMonoidSup
+ then OrderedAbelianMonoidSup
+ if A has OrderedSet and B has OrderedSet then OrderedSet
+
+ makeprod : (A,B) -> %
+ ++ makeprod(a,b) \undocumented
+ selectfirst : % -> A
+ ++ selectfirst(x) \undocumented
+ selectsecond : % -> B
+ ++ selectsecond(x) \undocumented
+
+ T == add
+
+ --representations
+ Rep := Record(acomp:A,bcomp:B)
+
+ --declarations
+ x,y: %
+ i: NonNegativeInteger
+ p: NonNegativeInteger
+ a: A
+ b: B
+ d: Integer
+
+ --define
+ coerce(x):OutputForm == paren [(x.acomp)::OutputForm,
+ (x.bcomp)::OutputForm]
+ x=y ==
+ x.acomp = y.acomp => x.bcomp = y.bcomp
+ false
+ makeprod(a:A,b:B) :% == [a,b]
+
+ selectfirst(x:%) : A == x.acomp
+
+ selectsecond (x:%) : B == x.bcomp
+
+ if A has Monoid and B has Monoid then
+ 1 == [1$A,1$B]
+ x * y == [x.acomp * y.acomp,x.bcomp * y.bcomp]
+ x ** p == [x.acomp ** p ,x.bcomp ** p]
+
+ if A has Finite and B has Finite then
+ size == size$A () * size$B ()
+
+ if A has Group and B has Group then
+ inv(x) == [inv(x.acomp),inv(x.bcomp)]
+
+ if A has AbelianMonoid and B has AbelianMonoid then
+ 0 == [0$A,0$B]
+
+ x + y == [x.acomp + y.acomp,x.bcomp + y.bcomp]
+
+ c:NonNegativeInteger * x == [c * x.acomp,c*x.bcomp]
+
+ if A has CancellationAbelianMonoid and
+ B has CancellationAbelianMonoid then
+ subtractIfCan(x, y) : Union(%,"failed") ==
+ (na:= subtractIfCan(x.acomp, y.acomp)) case "failed" => "failed"
+ (nb:= subtractIfCan(x.bcomp, y.bcomp)) case "failed" => "failed"
+ [na::A,nb::B]
+
+ if A has AbelianGroup and B has AbelianGroup then
+ - x == [- x.acomp,-x.bcomp]
+ (x - y):% == [x.acomp - y.acomp,x.bcomp - y.bcomp]
+ d * x == [d * x.acomp,d * x.bcomp]
+
+ if A has OrderedAbelianMonoidSup and B has OrderedAbelianMonoidSup then
+ sup(x,y) == [sup(x.acomp,y.acomp),sup(x.bcomp,y.bcomp)]
+
+ if A has OrderedSet and B has OrderedSet then
+ x < y ==
+ xa:= x.acomp ; ya:= y.acomp
+ xa < ya => true
+ xb:= x.bcomp ; yb:= y.bcomp
+ xa = ya => (xb < yb)
+ false
+
+-- coerce(x:%):Symbol ==
+-- PrintableForm()
+-- formList([x.acomp::Expression,x.bcomp::Expression])$PrintableForm
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PRODUCT Product>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/prs.spad.pamphlet b/src/algebra/prs.spad.pamphlet
new file mode 100644
index 00000000..f3662063
--- /dev/null
+++ b/src/algebra/prs.spad.pamphlet
@@ -0,0 +1,986 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra prs.spad}
+\author{Lionel Ducos}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PRS PseudoRemainderSequence}
+The package constructor {\bf PseudoRemainderSequence} provides
+efficient algorithms by Lionel Ducos (University of Poitiers, France)
+for computing sub-resultants. This leads to a speed up in many places
+in Axiom where sub-resultants are computed (polynomial system solving,
+algebraic factorization, integration).
+<<package PRS PseudoRemainderSequence>>=
+)abbrev package PRS PseudoRemainderSequence
+++ Author: Ducos Lionel
+++ Date Created: january 1995
+++ Date Last Updated: 5 february 1999
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description: This package contains some functions:
+++ \axiomOpFrom{discriminant}{PseudoRemainderSequence},
+++ \axiomOpFrom{resultant}{PseudoRemainderSequence},
+++ \axiomOpFrom{subResultantGcd}{PseudoRemainderSequence},
+++ \axiomOpFrom{chainSubResultants}{PseudoRemainderSequence},
+++ \axiomOpFrom{degreeSubResultant}{PseudoRemainderSequence},
+++ \axiomOpFrom{lastSubResultant}{PseudoRemainderSequence},
+++ \axiomOpFrom{resultantEuclidean}{PseudoRemainderSequence},
+++ \axiomOpFrom{subResultantGcdEuclidean}{PseudoRemainderSequence},
+++ \axiomOpFrom{semiSubResultantGcdEuclidean1}{PseudoRemainderSequence},
+++ \axiomOpFrom{semiSubResultantGcdEuclidean2}{PseudoRemainderSequence}, etc.
+++ This procedures are coming from improvements
+++ of the subresultants algorithm.
+++ Version : 7
+++ References : Lionel Ducos "Optimizations of the subresultant algorithm"
+++ to appear in the Journal of Pure and Applied Algebra.
+++ Author : Ducos Lionel \axiom{Lionel.Ducos@mathlabo.univ-poitiers.fr}
+
+PseudoRemainderSequence(R, polR) : Specification == Implementation where
+ R : IntegralDomain
+ polR : UnivariatePolynomialCategory(R)
+ NNI ==> NonNegativeInteger
+ LC ==> leadingCoefficient
+
+ Specification == with
+ resultant : (polR, polR) -> R
+ ++ \axiom{resultant(P, Q)} returns the resultant
+ ++ of \axiom{P} and \axiom{Q}
+
+ resultantEuclidean : (polR, polR) ->
+ Record(coef1 : polR, coef2 : polR, resultant : R)
+ ++ \axiom{resultantEuclidean(P,Q)} carries out the equality
+ ++ \axiom{coef1*P + coef2*Q = resultant(P,Q)}
+
+ semiResultantEuclidean2 : (polR, polR) ->
+ Record(coef2 : polR, resultant : R)
+ ++ \axiom{semiResultantEuclidean2(P,Q)} carries out the equality
+ ++ \axiom{...P + coef2*Q = resultant(P,Q)}.
+ ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+ semiResultantEuclidean1 : (polR, polR) ->
+ Record(coef1 : polR, resultant : R)
+ ++ \axiom{semiResultantEuclidean1(P,Q)} carries out the equality
+ ++ \axiom{coef1.P + ? Q = resultant(P,Q)}.
+
+ indiceSubResultant : (polR, polR, NNI) -> polR
+ ++ \axiom{indiceSubResultant(P, Q, i)} returns
+ ++ the subresultant of indice \axiom{i}
+
+ indiceSubResultantEuclidean : (polR, polR, NNI) ->
+ Record(coef1 : polR, coef2 : polR, subResultant : polR)
+ ++ \axiom{indiceSubResultant(P, Q, i)} returns
+ ++ the subresultant \axiom{S_i(P,Q)} and carries out the equality
+ ++ \axiom{coef1*P + coef2*Q = S_i(P,Q)}
+
+ semiIndiceSubResultantEuclidean : (polR, polR, NNI) ->
+ Record(coef2 : polR, subResultant : polR)
+ ++ \axiom{semiIndiceSubResultantEuclidean(P, Q, i)} returns
+ ++ the subresultant \axiom{S_i(P,Q)} and carries out the equality
+ ++ \axiom{...P + coef2*Q = S_i(P,Q)}
+ ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+ degreeSubResultant : (polR, polR, NNI) -> polR
+ ++ \axiom{degreeSubResultant(P, Q, d)} computes
+ ++ a subresultant of degree \axiom{d}.
+
+ degreeSubResultantEuclidean : (polR, polR, NNI) ->
+ Record(coef1 : polR, coef2 : polR, subResultant : polR)
+ ++ \axiom{indiceSubResultant(P, Q, i)} returns
+ ++ a subresultant \axiom{S} of degree \axiom{d}
+ ++ and carries out the equality \axiom{coef1*P + coef2*Q = S_i}.
+
+ semiDegreeSubResultantEuclidean : (polR, polR, NNI) ->
+ Record(coef2 : polR, subResultant : polR)
+ ++ \axiom{indiceSubResultant(P, Q, i)} returns
+ ++ a subresultant \axiom{S} of degree \axiom{d}
+ ++ and carries out the equality \axiom{...P + coef2*Q = S_i}.
+ ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+ lastSubResultant : (polR, polR) -> polR
+ ++ \axiom{lastSubResultant(P, Q)} computes
+ ++ the last non zero subresultant of \axiom{P} and \axiom{Q}
+
+ lastSubResultantEuclidean : (polR, polR) ->
+ Record(coef1 : polR, coef2 : polR, subResultant : polR)
+ ++ \axiom{lastSubResultantEuclidean(P, Q)} computes
+ ++ the last non zero subresultant \axiom{S}
+ ++ and carries out the equality \axiom{coef1*P + coef2*Q = S}.
+
+ semiLastSubResultantEuclidean : (polR, polR) ->
+ Record(coef2 : polR, subResultant : polR)
+ ++ \axiom{semiLastSubResultantEuclidean(P, Q)} computes
+ ++ the last non zero subresultant \axiom{S}
+ ++ and carries out the equality \axiom{...P + coef2*Q = S}.
+ ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+ subResultantGcd : (polR, polR) -> polR
+ ++ \axiom{subResultantGcd(P, Q)} returns the gcd
+ ++ of two primitive polynomials \axiom{P} and \axiom{Q}.
+
+ subResultantGcdEuclidean : (polR, polR)
+ -> Record(coef1 : polR, coef2 : polR, gcd : polR)
+ ++ \axiom{subResultantGcdEuclidean(P,Q)} carries out the equality
+ ++ \axiom{coef1*P + coef2*Q = +/- S_i(P,Q)}
+ ++ where the degree (not the indice)
+ ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
+
+ semiSubResultantGcdEuclidean2 : (polR, polR)
+ -> Record(coef2 : polR, gcd : polR)
+ ++ \axiom{semiSubResultantGcdEuclidean2(P,Q)} carries out the equality
+ ++ \axiom{...P + coef2*Q = +/- S_i(P,Q)}
+ ++ where the degree (not the indice)
+ ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
+ ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+ semiSubResultantGcdEuclidean1: (polR, polR)->Record(coef1: polR, gcd: polR)
+ ++ \axiom{semiSubResultantGcdEuclidean1(P,Q)} carries out the equality
+ ++ \axiom{coef1*P + ? Q = +/- S_i(P,Q)}
+ ++ where the degree (not the indice)
+ ++ of the subresultant \axiom{S_i(P,Q)} is the smaller as possible.
+
+ discriminant : polR -> R
+ ++ \axiom{discriminant(P, Q)} returns the discriminant
+ ++ of \axiom{P} and \axiom{Q}.
+
+ discriminantEuclidean : polR ->
+ Record(coef1 : polR, coef2 : polR, discriminant : R)
+ ++ \axiom{discriminantEuclidean(P)} carries out the equality
+ ++ \axiom{coef1 * P + coef2 * D(P) = discriminant(P)}.
+
+ semiDiscriminantEuclidean : polR ->
+ Record(coef2 : polR, discriminant : R)
+ ++ \axiom{discriminantEuclidean(P)} carries out the equality
+ ++ \axiom{...P + coef2 * D(P) = discriminant(P)}.
+ ++ Warning: \axiom{degree(P) >= degree(Q)}.
+
+ chainSubResultants : (polR, polR) -> List(polR)
+ ++ \axiom{chainSubResultants(P, Q)} computes the list
+ ++ of non zero subresultants of \axiom{P} and \axiom{Q}.
+
+ schema : (polR, polR) -> List(NNI)
+ ++ \axiom{schema(P,Q)} returns the list of degrees of
+ ++ non zero subresultants of \axiom{P} and \axiom{Q}.
+
+ if R has GcdDomain then
+ resultantReduit : (polR, polR) -> R
+ ++ \axiom{resultantReduit(P,Q)} returns the "reduce resultant"
+ ++ of \axiom{P} and \axiom{Q}.
+
+ resultantReduitEuclidean : (polR, polR) ->
+ Record(coef1 : polR, coef2 : polR, resultantReduit : R)
+ ++ \axiom{resultantReduitEuclidean(P,Q)} returns
+ ++ the "reduce resultant" and carries out the equality
+ ++ \axiom{coef1*P + coef2*Q = resultantReduit(P,Q)}.
+
+ semiResultantReduitEuclidean : (polR, polR) ->
+ Record(coef2 : polR, resultantReduit : R)
+ ++ \axiom{semiResultantReduitEuclidean(P,Q)} returns
+ ++ the "reduce resultant" and carries out the equality
+ ++ \axiom{...P + coef2*Q = resultantReduit(P,Q)}.
+
+ gcd : (polR, polR) -> polR
+ ++ \axiom{gcd(P, Q)} returns the gcd of \axiom{P} and \axiom{Q}.
+
+ -- sub-routines exported for convenience ----------------------------
+
+ "*" : (R, Vector(polR)) -> Vector(polR)
+ ++ \axiom{r * v} computes the product of \axiom{r} and \axiom{v}
+
+ "exquo" : (Vector(polR), R) -> Vector(polR)
+ ++ \axiom{v exquo r} computes
+ ++ the exact quotient of \axiom{v} by \axiom{r}
+
+ pseudoDivide : (polR, polR) ->
+ Record(coef:R, quotient:polR, remainder:polR)
+ ++ \axiom{pseudoDivide(P,Q)} computes the pseudoDivide
+ ++ of \axiom{P} by \axiom{Q}.
+
+ divide : (polR, polR) -> Record(quotient : polR, remainder : polR)
+ ++ \axiom{divide(F,G)} computes quotient and rest
+ ++ of the exact euclidean division of \axiom{F} by \axiom{G}.
+
+ Lazard : (R, R, NNI) -> R
+ ++ \axiom{Lazard(x, y, n)} computes \axiom{x**n/y**(n-1)}
+
+ Lazard2 : (polR, R, R, NNI) -> polR
+ ++ \axiom{Lazard2(F, x, y, n)} computes \axiom{(x/y)**(n-1) * F}
+
+ next_sousResultant2 : (polR, polR, polR, R) -> polR
+ ++ \axiom{nextsousResultant2(P, Q, Z, s)} returns
+ ++ the subresultant \axiom{S_{e-1}} where
+ ++ \axiom{P ~ S_d, Q = S_{d-1}, Z = S_e, s = lc(S_d)}
+
+ resultant_naif : (polR, polR) -> R
+ ++ \axiom{resultantEuclidean_naif(P,Q)} returns
+ ++ the resultant of \axiom{P} and \axiom{Q} computed
+ ++ by means of the naive algorithm.
+
+ resultantEuclidean_naif : (polR, polR) ->
+ Record(coef1 : polR, coef2 : polR, resultant : R)
+ ++ \axiom{resultantEuclidean_naif(P,Q)} returns
+ ++ the extended resultant of \axiom{P} and \axiom{Q} computed
+ ++ by means of the naive algorithm.
+
+ semiResultantEuclidean_naif : (polR, polR) ->
+ Record(coef2 : polR, resultant : R)
+ ++ \axiom{resultantEuclidean_naif(P,Q)} returns
+ ++ the semi-extended resultant of \axiom{P} and \axiom{Q} computed
+ ++ by means of the naive algorithm.
+
+ Implementation == add
+ X : polR := monomial(1$R,1)
+
+ r : R * v : Vector(polR) == r::polR * v
+ -- the instruction map(r * #1, v) is slower !?
+
+ v : Vector(polR) exquo r : R == map((#1 exquo r)::polR, v)
+
+ pseudoDivide(P : polR, Q : polR) :
+ Record(coef:R,quotient:polR,remainder:polR) ==
+ -- computes the pseudoDivide of P by Q
+ zero?(Q) => error("PseudoDivide$PRS : division by 0")
+ zero?(P) => construct(1, 0, P)
+ lcQ : R := LC(Q)
+ (degP, degQ) := (degree(P), degree(Q))
+ degP < degQ => construct(1, 0, P)
+ Q := reductum(Q)
+ i : NNI := (degP - degQ + 1)::NNI
+ co : R := lcQ**i
+ quot : polR := 0$polR
+ while (delta : Integer := degree(P) - degQ) >= 0 repeat
+ i := (i - 1)::NNI
+ mon := monomial(LC(P), delta::NNI)$polR
+ quot := quot + lcQ**i * mon
+ P := lcQ * reductum(P) - mon * Q
+ P := lcQ**i * P
+ return construct(co, quot, P)
+
+ divide(F : polR, G : polR) : Record(quotient : polR, remainder : polR)==
+ -- computes quotient and rest of the exact euclidean division of F by G
+ lcG : R := LC(G)
+ degG : NNI := degree(G)
+ zero?(degG) => ( F := (F exquo lcG)::polR; return construct(F, 0))
+ G : polR := reductum(G)
+ quot : polR := 0
+ while (delta := degree(F) - degG) >= 0 repeat
+ mon : polR := monomial((LC(F) exquo lcG)::R, delta::NNI)
+ quot := quot + mon
+ F := reductum(F) - mon * G
+ return construct(quot, F)
+
+ resultant_naif(P : polR, Q : polR) : R ==
+ -- valid over a field
+ a : R := 1
+ repeat
+ zero?(Q) => return 0
+ (degP, degQ) := (degree(P), degree(Q))
+ if odd?(degP) and odd?(degQ) then a := - a
+ zero?(degQ) => return (a * LC(Q)**degP)
+ U : polR := divide(P, Q).remainder
+ a := a * LC(Q)**(degP - degree(U))::NNI
+ (P, Q) := (Q, U)
+
+ resultantEuclidean_naif(P : polR, Q : polR) :
+ Record(coef1 : polR, coef2 : polR, resultant : R) ==
+ -- valid over a field.
+ a : R := 1
+ old_cf1 : polR := 1 ; cf1 : polR := 0
+ old_cf2 : polR := 0 ; cf2 : polR := 1
+ repeat
+ zero?(Q) => construct(0::polR, 0::polR, 0::R)
+ (degP, degQ) := (degree(P), degree(Q))
+ if odd?(degP) and odd?(degQ) then a := -a
+ if zero?(degQ) then
+ a := a * LC(Q)**(degP-1)::NNI
+ return construct(a*cf1, a*cf2, a*LC(Q))
+ divid := divide(P,Q)
+ a := a * LC(Q)**(degP - degree(divid.remainder))::NNI
+ (P, Q) := (Q, divid.remainder)
+ (old_cf1, old_cf2, cf1, cf2) := (cf1, cf2,
+ old_cf1 - divid.quotient * cf1, old_cf2 - divid.quotient * cf2)
+
+ semiResultantEuclidean_naif(P : polR, Q : polR) :
+ Record(coef2 : polR, resultant : R) ==
+ -- valid over a field
+ a : R := 1
+ old_cf2 : polR := 0 ; cf2 : polR := 1
+ repeat
+ zero?(Q) => construct(0::polR, 0::R)
+ (degP, degQ) := (degree(P), degree(Q))
+ if odd?(degP) and odd?(degQ) then a := -a
+ if zero?(degQ) then
+ a := a * LC(Q)**(degP-1)::NNI
+ return construct(a*cf2, a*LC(Q))
+ divid := divide(P,Q)
+ a := a * LC(Q)**(degP - degree(divid.remainder))::NNI
+ (P, Q) := (Q, divid.remainder)
+ (old_cf2, cf2) := (cf2, old_cf2 - divid.quotient * cf2)
+
+ Lazard(x : R, y : R, n : NNI) : R ==
+ zero?(n) => error("Lazard$PRS : n = 0")
+-- one?(n) => x
+ (n = 1) => x
+ a : NNI := 1
+ while n >= (b := 2*a) repeat a := b
+ c : R := x
+ n := (n - a)::NNI
+ repeat -- c = x**i / y**(i-1), i=n_0 quo a, a=2**?
+-- one?(a) => return c
+ (a = 1) => return c
+ a := a quo 2
+ c := ((c * c) exquo y)::R
+ if n >= a then ( c := ((c * x) exquo y)::R ; n := (n - a)::NNI )
+
+ Lazard2(F : polR, x : R, y : R, n : NNI) : polR ==
+ zero?(n) => error("Lazard2$PRS : n = 0")
+-- one?(n) => F
+ (n = 1) => F
+ x := Lazard(x, y, (n-1)::NNI)
+ return ((x * F) exquo y)::polR
+
+ Lazard3(V : Vector(polR), x : R, y : R, n : NNI) : Vector(polR) ==
+ -- computes x**(n-1) * V / y**(n-1)
+ zero?(n) => error("Lazard2$prs : n = 0")
+-- one?(n) => V
+ (n = 1) => V
+ x := Lazard(x, y, (n-1)::NNI)
+ return ((x * V) exquo y)
+
+ next_sousResultant2(P : polR, Q : polR, Z : polR, s : R) : polR ==
+ (lcP, c, se) := (LC(P), LC(Q), LC(Z))
+ (d, e) := (degree(P), degree(Q))
+ (P, Q, H) := (reductum(P), reductum(Q), - reductum(Z))
+ A : polR := coefficient(P, e) * H
+ for i in e+1..d-1 repeat
+ H := if degree(H) = e-1 then
+ X * reductum(H) - ((LC(H) * Q) exquo c)::polR
+ else
+ X * H
+ -- H = s_e * X^i mod S_d-1
+ A := coefficient(P, i) * H + A
+ while degree(P) >= e repeat P := reductum(P)
+ A := A + se * P -- A = s_e * reductum(P_0) mod S_d-1
+ A := (A exquo lcP)::polR -- A = s_e * reductum(S_d) / s_d mod S_d-1
+ A := if degree(H) = e-1 then
+ c * (X * reductum(H) + A) - LC(H) * Q
+ else
+ c * (X * H + A)
+ A := (A exquo s)::polR -- A = +/- S_e-1
+ return (if odd?(d-e) then A else - A)
+
+ next_sousResultant3(VP : Vector(polR), VQ : Vector(polR), s : R, ss : R) :
+ Vector(polR) ==
+ -- P ~ S_d, Q = S_d-1, s = lc(S_d), ss = lc(S_e)
+ (P, Q) := (VP.1, VQ.1)
+ (lcP, c) := (LC(P), LC(Q))
+ e : NNI := degree(Q)
+-- if one?(delta := degree(P) - e) then -- algo_new
+ if ((delta := degree(P) - e) = 1) then -- algo_new
+ VP := c * VP - coefficient(P, e) * VQ
+ VP := VP exquo lcP
+ VP := c * (VP - X * VQ) + coefficient(Q, (e-1)::NNI) * VQ
+ VP := VP exquo s
+ else -- algorithm of Lickteig - Roy
+ (r, rr) := (s * lcP, ss * c)
+ divid := divide(rr * P, Q)
+ VP.1 := (divid.remainder exquo r)::polR
+ for i in 2..#VP repeat
+ VP.i := rr * VP.i - VQ.i * divid.quotient
+ VP.i := (VP.i exquo r)::polR
+ return (if odd?(delta) then VP else - VP)
+
+ algo_new(P : polR, Q : polR) : R ==
+ delta : NNI := (degree(P) - degree(Q))::NNI
+ s : R := LC(Q)**delta
+ (P, Q) := (Q, pseudoRemainder(P, -Q))
+ repeat
+ -- P = S_c-1 (except the first turn : P ~ S_c-1),
+ -- Q = S_d-1, s = lc(S_d)
+ zero?(Q) => return 0
+ delta := (degree(P) - degree(Q))::NNI
+ Z : polR := Lazard2(Q, LC(Q), s, delta)
+ -- Z = S_e ~ S_d-1
+ zero?(degree(Z)) => return LC(Z)
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ resultant(P : polR, Q : polR) : R ==
+ zero?(Q) or zero?(P) => 0
+ if degree(P) < degree(Q) then
+ (P, Q) := (Q, P)
+ if odd?(degree(P)) and odd?(degree(Q)) then Q := - Q
+ zero?(degree(Q)) => LC(Q)**degree(P)
+ -- degree(P) >= degree(Q) > 0
+ R has Finite => resultant_naif(P, Q)
+ return algo_new(P, Q)
+
+ subResultantEuclidean(P : polR, Q : polR) :
+ Record(coef1 : polR, coef2 : polR, resultant : R) ==
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 0::polR, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s=lc(S_d)
+ -- S_{c-1} = VP.2 P_0 + VP.3 Q_0, S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) => return construct(0::polR, 0::polR, 0::R)
+ e : NNI := degree(Q)
+ delta : NNI := (degree(P) - e)::NNI
+ if zero?(e) then
+ l : Vector(polR) := Lazard3(VQ, LC(Q), s, delta)
+ return construct(l.2, l.3, LC(l.1))
+ ss : R := Lazard(LC(Q), s, delta)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ resultantEuclidean(P : polR, Q : polR) :
+ Record(coef1 : polR, coef2 : polR, resultant : R) ==
+ zero?(P) or zero?(Q) => construct(0::polR, 0::polR, 0::R)
+ if degree(P) < degree(Q) then
+ e : Integer := if odd?(degree(P)) and odd?(degree(Q)) then -1 else 1
+ l := resultantEuclidean(Q, e * P)
+ return construct(e * l.coef2, l.coef1, l.resultant)
+ if zero?(degree(Q)) then
+ degP : NNI := degree(P)
+ zero?(degP) => error("resultantEuclidean$PRS : constant polynomials")
+ s : R := LC(Q)**(degP-1)::NNI
+ return construct(0::polR, s::polR, s * LC(Q))
+ R has Finite => resultantEuclidean_naif(P, Q)
+ return subResultantEuclidean(P,Q)
+
+ semiSubResultantEuclidean(P : polR, Q : polR) :
+ Record(coef2 : polR, resultant : R) ==
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s=lc(S_d)
+ -- S_{c-1} = ...P_0 + VP.3 Q_0, S_{d-1} = ...P_0 + VQ.3 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) => return construct(0::polR, 0::R)
+ e : NNI := degree(Q)
+ delta : NNI := (degree(P) - e)::NNI
+ if zero?(e) then
+ l : Vector(polR) := Lazard3(VQ, LC(Q), s, delta)
+ return construct(l.2, LC(l.1))
+ ss : R := Lazard(LC(Q), s, delta)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ semiResultantEuclidean2(P : polR, Q : polR) :
+ Record(coef2 : polR, resultant : R) ==
+ zero?(P) or zero?(Q) => construct(0::polR, 0::R)
+ degree(P) < degree(Q) => error("semiResultantEuclidean2 : bad degrees")
+ if zero?(degree(Q)) then
+ degP : NNI := degree(P)
+ zero?(degP) => error("semiResultantEuclidean2 : constant polynomials")
+ s : R := LC(Q)**(degP-1)::NNI
+ return construct(s::polR, s * LC(Q))
+ R has Finite => semiResultantEuclidean_naif(P, Q)
+ return semiSubResultantEuclidean(P,Q)
+
+ semiResultantEuclidean1(P : polR, Q : polR) :
+ Record(coef1 : polR, resultant : R) ==
+ result := resultantEuclidean(P,Q)
+ [result.coef1, result.resultant]
+
+ indiceSubResultant(P : polR, Q : polR, i : NNI) : polR ==
+ zero?(Q) or zero?(P) => 0
+ if degree(P) < degree(Q) then
+ (P, Q) := (Q, P)
+ if odd?(degree(P)-i) and odd?(degree(Q)-i) then Q := - Q
+ if i = degree(Q) then
+ delta : NNI := (degree(P)-degree(Q))::NNI
+ zero?(delta) => error("indiceSubResultant$PRS : bad degrees")
+ s : R := LC(Q)**(delta-1)::NNI
+ return s*Q
+ i > degree(Q) => 0
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ (P, Q) := (Q, pseudoRemainder(P, -Q))
+ repeat
+ -- P = S_{c-1} ~ S_d , Q = S_{d-1}, s = lc(S_d), i < d
+ (degP, degQ) := (degree(P), degree(Q))
+ i = degP-1 => return Q
+ zero?(Q) or (i > degQ) => return 0
+ Z : polR := Lazard2(Q, LC(Q), s, (degP - degQ)::NNI)
+ -- Z = S_e ~ S_d-1
+ i = degQ => return Z
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ indiceSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
+ Record(coef1 : polR, coef2 : polR, subResultant : polR) ==
+ zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
+ if degree(P) < degree(Q) then
+ e := if odd?(degree(P)-i) and odd?(degree(Q)-i) then -1 else 1
+ l := indiceSubResultantEuclidean(Q, e * P, i)
+ return construct(e * l.coef2, l.coef1, l.subResultant)
+ if i = degree(Q) then
+ delta : NNI := (degree(P)-degree(Q))::NNI
+ zero?(delta) =>
+ error("indiceSubResultantEuclidean$PRS : bad degrees")
+ s : R := LC(Q)**(delta-1)::NNI
+ return construct(0::polR, s::polR, s * Q)
+ i > degree(Q) => construct(0::polR, 0::polR, 0::polR)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 0::polR, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s=lc(S_d), i < d
+ -- S_{c-1} = VP.2 P_0 + VP.3 Q_0, S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) => return construct(0::polR, 0::polR, 0::polR)
+ (degP, degQ) := (degree(P), degree(Q))
+ i = degP-1 => return construct(VQ.2, VQ.3, VQ.1)
+ (i > degQ) => return construct(0::polR, 0::polR, 0::polR)
+ VZ := Lazard3(VQ, LC(Q), s, (degP - degQ)::NNI)
+ i = degQ => return construct(VZ.2, VZ.3, VZ.1)
+ ss : R := LC(VZ.1)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ semiIndiceSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
+ Record(coef2 : polR, subResultant : polR) ==
+ zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
+ degree(P) < degree(Q) =>
+ error("semiIndiceSubResultantEuclidean$PRS : bad degrees")
+ if i = degree(Q) then
+ delta : NNI := (degree(P)-degree(Q))::NNI
+ zero?(delta) =>
+ error("semiIndiceSubResultantEuclidean$PRS : bad degrees")
+ s : R := LC(Q)**(delta-1)::NNI
+ return construct(s::polR, s * Q)
+ i > degree(Q) => construct(0::polR, 0::polR)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s = lc(S_d), i < d
+ -- S_{c-1} = ...P_0 + VP.2 Q_0, S_{d-1} = ...P_0 + ...Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) => return construct(0::polR, 0::polR)
+ (degP, degQ) := (degree(P), degree(Q))
+ i = degP-1 => return construct(VQ.2, VQ.1)
+ (i > degQ) => return construct(0::polR, 0::polR)
+ VZ := Lazard3(VQ, LC(Q), s, (degP - degQ)::NNI)
+ i = degQ => return construct(VZ.2, VZ.1)
+ ss : R := LC(VZ.1)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ degreeSubResultant(P : polR, Q : polR, i : NNI) : polR ==
+ zero?(Q) or zero?(P) => 0
+ if degree(P) < degree(Q) then (P, Q) := (Q, P)
+ if i = degree(Q) then
+ delta : NNI := (degree(P)-degree(Q))::NNI
+ zero?(delta) => error("degreeSubResultant$PRS : bad degrees")
+ s : R := LC(Q)**(delta-1)::NNI
+ return s*Q
+ i > degree(Q) => 0
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ (P, Q) := (Q, pseudoRemainder(P, -Q))
+ repeat
+ -- P = S_{c-1}, Q = S_{d-1}, s = lc(S_d)
+ zero?(Q) or (i > degree(Q)) => return 0
+ i = degree(Q) => return Q
+ Z : polR := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
+ -- Z = S_e ~ S_d-1
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ degreeSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
+ Record(coef1 : polR, coef2 : polR, subResultant : polR) ==
+ zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
+ if degree(P) < degree(Q) then
+ l := degreeSubResultantEuclidean(Q, P, i)
+ return construct(l.coef2, l.coef1, l.subResultant)
+ if i = degree(Q) then
+ delta : NNI := (degree(P)-degree(Q))::NNI
+ zero?(delta) =>
+ error("degreeSubResultantEuclidean$PRS : bad degrees")
+ s : R := LC(Q)**(delta-1)::NNI
+ return construct(0::polR, s::polR, s * Q)
+ i > degree(Q) => construct(0::polR, 0::polR, 0::polR)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 0::polR, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s=lc(S_d)
+ -- S_{c-1} = ...P_0 + VP.3 Q_0, S_{d-1} = ...P_0 + VQ.3 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) or (i > degree(Q)) =>
+ return construct(0::polR, 0::polR, 0::polR)
+ i = degree(Q) => return construct(VQ.2, VQ.3, VQ.1)
+ ss : R := Lazard(LC(Q), s, (degree(P)-degree(Q))::NNI)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ semiDegreeSubResultantEuclidean(P : polR, Q : polR, i : NNI) :
+ Record(coef2 : polR, subResultant : polR) ==
+ zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
+ degree(P) < degree(Q) =>
+ error("semiDegreeSubResultantEuclidean$PRS : bad degrees")
+ if i = degree(Q) then
+ delta : NNI := (degree(P)-degree(Q))::NNI
+ zero?(delta) =>
+ error("semiDegreeSubResultantEuclidean$PRS : bad degrees")
+ s : R := LC(Q)**(delta-1)::NNI
+ return construct(s::polR, s * Q)
+ i > degree(Q) => construct(0::polR, 0::polR)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s=lc(S_d)
+ -- S_{c-1} = ...P_0 + VP.3 Q_0, S_{d-1} = ...P_0 + VQ.3 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) or (i > degree(Q)) =>
+ return construct(0::polR, 0::polR)
+ i = degree(Q) => return construct(VQ.2, VQ.1)
+ ss : R := Lazard(LC(Q), s, (degree(P)-degree(Q))::NNI)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ lastSubResultant(P : polR, Q : polR) : polR ==
+ zero?(Q) or zero?(P) => 0
+ if degree(P) < degree(Q) then (P, Q) := (Q, P)
+ zero?(degree(Q)) => (LC(Q)**degree(P))::polR
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ (P, Q) := (Q, pseudoRemainder(P, -Q))
+ Z : polR := P
+ repeat
+ -- Z = S_d (except the first turn : Z = P)
+ -- P = S_{c-1} ~ S_d, Q = S_{d-1}, s = lc(S_d)
+ zero?(Q) => return Z
+ Z := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
+ -- Z = S_e ~ S_{d-1}
+ zero?(degree(Z)) => return Z
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ lastSubResultantEuclidean(P : polR, Q : polR) :
+ Record(coef1 : polR, coef2 : polR, subResultant : polR) ==
+ zero?(Q) or zero?(P) => construct(0::polR, 0::polR, 0::polR)
+ if degree(P) < degree(Q) then
+ l := lastSubResultantEuclidean(Q, P)
+ return construct(l.coef2, l.coef1, l.subResultant)
+ if zero?(degree(Q)) then
+ degP : NNI := degree(P)
+ zero?(degP) =>
+ error("lastSubResultantEuclidean$PRS : constant polynomials")
+ s : R := LC(Q)**(degP-1)::NNI
+ return construct(0::polR, s::polR, s * Q)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 0::polR, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+ VZ : Vector(polR) := copy(VP)
+ repeat
+ -- VZ.1 = S_d, VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s = lc(S_d)
+ -- S_{c-1} = VP.2 P_0 + VP.3 Q_0
+ -- S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+ -- S_d = VZ.2 P_0 + VZ.3 Q_0
+ (Q, Z) := (VQ.1, VZ.1)
+ zero?(Q) => return construct(VZ.2, VZ.3, VZ.1)
+ VZ := Lazard3(VQ, LC(Q), s, (degree(Z) - degree(Q))::NNI)
+ zero?(degree(Q)) => return construct(VZ.2, VZ.3, VZ.1)
+ ss : R := LC(VZ.1)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ semiLastSubResultantEuclidean(P : polR, Q : polR) :
+ Record(coef2 : polR, subResultant : polR) ==
+ zero?(Q) or zero?(P) => construct(0::polR, 0::polR)
+ degree(P) < degree(Q) =>
+ error("semiLastSubResultantEuclidean$PRS : bad degrees")
+ if zero?(degree(Q)) then
+ degP : NNI := degree(P)
+ zero?(degP) =>
+ error("semiLastSubResultantEuclidean$PRS : constant polynomials")
+ s : R := LC(Q)**(degP-1)::NNI
+ return construct(s::polR, s * Q)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+ VZ : Vector(polR) := copy(VP)
+ repeat
+ -- VZ.1 = S_d, VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s = lc(S_d)
+ -- S_{c-1} = ... P_0 + VP.2 Q_0
+ -- S_{d-1} = ... P_0 + VQ.2 Q_0
+ -- S_d = ... P_0 + VZ.2 Q_0
+ (Q, Z) := (VQ.1, VZ.1)
+ zero?(Q) => return construct(VZ.2, VZ.1)
+ VZ := Lazard3(VQ, LC(Q), s, (degree(Z) - degree(Q))::NNI)
+ zero?(degree(Q)) => return construct(VZ.2, VZ.1)
+ ss : R := LC(VZ.1)
+ (VP, VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ chainSubResultants(P : polR, Q : polR) : List(polR) ==
+ zero?(Q) or zero?(P) => []
+ if degree(P) < degree(Q) then
+ (P, Q) := (Q, P)
+ if odd?(degree(P)) and odd?(degree(Q)) then Q := - Q
+ L : List(polR) := []
+ zero?(degree(Q)) => L
+ L := [Q]
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ (P, Q) := (Q, pseudoRemainder(P, -Q))
+ repeat
+ -- P = S_{c-1}, Q = S_{d-1}, s = lc(S_d)
+ -- L = [S_d,....,S_{q-1}]
+ zero?(Q) => return L
+ L := concat(Q, L)
+ -- L = [S_{d-1},....,S_{q-1}]
+ delta : NNI := (degree(P) - degree(Q))::NNI
+ Z : polR := Lazard2(Q, LC(Q), s, delta) -- Z = S_e ~ S_d-1
+ if delta > 1 then L := concat(Z, L)
+ -- L = [S_e,....,S_{q-1}]
+ zero?(degree(Z)) => return L
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ schema(P : polR, Q : polR) : List(NNI) ==
+ zero?(Q) or zero?(P) => []
+ if degree(P) < degree(Q) then (P, Q) := (Q, P)
+ zero?(degree(Q)) => [0]
+ L : List(NNI) := []
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ (P, Q) := (Q, pseudoRemainder(P, Q))
+ repeat
+ -- P = S_{c-1} ~ S_d, Q = S_{d-1}, s = lc(S_d)
+ zero?(Q) => return L
+ e : NNI := degree(Q)
+ L := concat(e, L)
+ delta : NNI := (degree(P) - e)::NNI
+ Z : polR := Lazard2(Q, LC(Q), s, delta) -- Z = S_e ~ S_d-1
+ if delta > 1 then L := concat(e, L)
+ zero?(e) => return L
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ subResultantGcd(P : polR, Q : polR) : polR ==
+ zero?(P) and zero?(Q) => 0
+ zero?(P) => Q
+ zero?(Q) => P
+ if degree(P) < degree(Q) then (P, Q) := (Q, P)
+ zero?(degree(Q)) => 1$polR
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ (P, Q) := (Q, pseudoRemainder(P, -Q))
+ repeat
+ -- P = S_{c-1}, Q = S_{d-1}, s = lc(S_d)
+ zero?(Q) => return P
+ zero?(degree(Q)) => return 1$polR
+ Z : polR := Lazard2(Q, LC(Q), s, (degree(P) - degree(Q))::NNI)
+ -- Z = S_e ~ S_d-1
+ (P, Q) := (Q, next_sousResultant2(P, Q, Z, s))
+ s := LC(Z)
+
+ subResultantGcdEuclidean(P : polR, Q : polR) :
+ Record(coef1 : polR, coef2 : polR, gcd : polR) ==
+ zero?(P) and zero?(Q) => construct(0::polR, 0::polR, 0::polR)
+ zero?(P) => construct(0::polR, 1::polR, Q)
+ zero?(Q) => construct(1::polR, 0::polR, P)
+ if degree(P) < degree(Q) then
+ l := subResultantGcdEuclidean(Q, P)
+ return construct(l.coef2, l.coef1, l.gcd)
+ zero?(degree(Q)) => construct(0::polR, 1::polR, Q)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 0::polR, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.coef::polR, pdiv.quotient]
+ repeat
+ -- VP.1 = S_{c-1}, VQ.1 = S_{d-1}, s=lc(S_d)
+ -- S_{c-1} = VP.2 P_0 + VP.3 Q_0, S_{d-1} = VQ.2 P_0 + VQ.3 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) => return construct(VP.2, VP.3, P)
+ e : NNI := degree(Q)
+ zero?(e) => return construct(VQ.2, VQ.3, Q)
+ ss := Lazard(LC(Q), s, (degree(P) - e)::NNI)
+ (VP,VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ semiSubResultantGcdEuclidean2(P : polR, Q : polR) :
+ Record(coef2 : polR, gcd : polR) ==
+ zero?(P) and zero?(Q) => construct(0::polR, 0::polR)
+ zero?(P) => construct(1::polR, Q)
+ zero?(Q) => construct(0::polR, P)
+ degree(P) < degree(Q) =>
+ error("semiSubResultantGcdEuclidean2$PRS : bad degrees")
+ zero?(degree(Q)) => construct(1::polR, Q)
+ s : R := LC(Q)**(degree(P) - degree(Q))::NNI
+ VP : Vector(polR) := [Q, 1::polR]
+ pdiv := pseudoDivide(P, -Q)
+ VQ : Vector(polR) := [pdiv.remainder, pdiv.quotient]
+ repeat
+ -- P=S_{c-1}, Q=S_{d-1}, s=lc(S_d)
+ -- S_{c-1} = ? P_0 + old_cf2 Q_0, S_{d-1} = ? P_0 + cf2 Q_0
+ (P, Q) := (VP.1, VQ.1)
+ zero?(Q) => return construct(VP.2, P)
+ e : NNI := degree(Q)
+ zero?(e) => return construct(VQ.2, Q)
+ ss := Lazard(LC(Q), s, (degree(P) - e)::NNI)
+ (VP,VQ) := (VQ, next_sousResultant3(VP, VQ, s, ss))
+ s := ss
+
+ semiSubResultantGcdEuclidean1(P : polR, Q : polR) :
+ Record(coef1 : polR, gcd : polR) ==
+ result := subResultantGcdEuclidean(P,Q)
+ [result.coef1, result.gcd]
+
+ discriminant(P : polR) : R ==
+ d : Integer := degree(P)
+ zero?(d) => error "cannot take discriminant of constants"
+ a : Integer := (d * (d-1)) quo 2
+ a := (-1)**a::NonNegativeInteger
+ dP : polR := differentiate P
+ r : R := resultant(P, dP)
+ d := d - degree(dP) - 1
+ return (if zero?(d) then a * (r exquo LC(P))::R
+ else a * r * LC(P)**(d-1)::NNI)
+
+ discriminantEuclidean(P : polR) :
+ Record(coef1 : polR, coef2 : polR, discriminant : R) ==
+ d : Integer := degree(P)
+ zero?(d) => error "cannot take discriminant of constants"
+ a : Integer := (d * (d-1)) quo 2
+ a := (-1)**a::NonNegativeInteger
+ dP : polR := differentiate P
+ rE := resultantEuclidean(P, dP)
+ d := d - degree(dP) - 1
+ if zero?(d) then
+ c1 : polR := a * (rE.coef1 exquo LC(P))::polR
+ c2 : polR := a * (rE.coef2 exquo LC(P))::polR
+ cr : R := a * (rE.resultant exquo LC(P))::R
+ else
+ c1 : polR := a * rE.coef1 * LC(P)**(d-1)::NNI
+ c2 : polR := a * rE.coef2 * LC(P)**(d-1)::NNI
+ cr : R := a * rE.resultant * LC(P)**(d-1)::NNI
+ return construct(c1, c2, cr)
+
+ semiDiscriminantEuclidean(P : polR) :
+ Record(coef2 : polR, discriminant : R) ==
+ d : Integer := degree(P)
+ zero?(d) => error "cannot take discriminant of constants"
+ a : Integer := (d * (d-1)) quo 2
+ a := (-1)**a::NonNegativeInteger
+ dP : polR := differentiate P
+ rE := semiResultantEuclidean2(P, dP)
+ d := d - degree(dP) - 1
+ if zero?(d) then
+ c2 : polR := a * (rE.coef2 exquo LC(P))::polR
+ cr : R := a * (rE.resultant exquo LC(P))::R
+ else
+ c2 : polR := a * rE.coef2 * LC(P)**(d-1)::NNI
+ cr : R := a * rE.resultant * LC(P)**(d-1)::NNI
+ return construct(c2, cr)
+
+ if R has GcdDomain then
+ resultantReduit(P : polR, Q : polR) : R ==
+ UV := subResultantGcdEuclidean(P, Q)
+ UVs : polR := UV.gcd
+ degree(UVs) > 0 => 0
+ l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
+ return (LC(UVs) exquo gcd(l))::R
+
+ resultantReduitEuclidean(P : polR, Q : polR) :
+ Record(coef1 : polR, coef2 : polR, resultantReduit : R) ==
+ UV := subResultantGcdEuclidean(P, Q)
+ UVs : polR := UV.gcd
+ degree(UVs) > 0 => construct(0::polR, 0::polR, 0::R)
+ l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
+ gl : R := gcd(l)
+ c1 : polR := (UV.coef1 exquo gl)::polR
+ c2 : polR := (UV.coef2 exquo gl)::polR
+ rr : R := (LC(UVs) exquo gl)::R
+ return construct(c1, c2, rr)
+
+ semiResultantReduitEuclidean(P : polR, Q : polR) :
+ Record(coef2 : polR, resultantReduit : R) ==
+ UV := subResultantGcdEuclidean(P, Q)
+ UVs : polR := UV.gcd
+ degree(UVs) > 0 => construct(0::polR, 0::R)
+ l : List(R) := concat(coefficients(UV.coef1), coefficients(UV.coef2))
+ gl : R := gcd(l)
+ c2 : polR := (UV.coef2 exquo gl)::polR
+ rr : R := (LC(UVs) exquo gl)::R
+ return construct(c2, rr)
+
+ gcd_naif(P : polR, Q : polR) : polR ==
+ -- valid over a field
+ zero?(P) => (Q exquo LC(Q))::polR
+ repeat
+ zero?(Q) => return (P exquo LC(P))::polR
+ zero?(degree(Q)) => return 1$polR
+ (P, Q) := (Q, divide(P, Q).remainder)
+
+ gcd(P : polR, Q : polR) : polR ==
+ R has Finite => gcd_naif(P,Q)
+ zero?(P) => Q
+ zero?(Q) => P
+ cP : R := content(P)
+ cQ : R := content(Q)
+ P := (P exquo cP)::polR
+ Q := (Q exquo cQ)::polR
+ G : polR := subResultantGcd(P, Q)
+ return gcd(cP,cQ) * primitivePart(G)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PRS PseudoRemainderSequence>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/prtition.spad.pamphlet b/src/algebra/prtition.spad.pamphlet
new file mode 100644
index 00000000..6b3cd538
--- /dev/null
+++ b/src/algebra/prtition.spad.pamphlet
@@ -0,0 +1,218 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra prtition.spad}
+\author{William H. Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain PRTITION Partition}
+<<domain PRTITION Partition>>=
+)abbrev domain PRTITION Partition
+++ Domain for partitions of positive integers
+++ Author: William H. Burge
+++ Date Created: 29 October 1987
+++ Date Last Updated: 23 Sept 1991
+++ Keywords:
+++ Examples:
+++ References:
+Partition: Exports == Implementation where
+ ++ Partition is an OrderedCancellationAbelianMonoid which is used
+ ++ as the basis for symmetric polynomial representation of the
+ ++ sums of powers in SymmetricPolynomial. Thus, \spad{(5 2 2 1)} will
+ ++ represent \spad{s5 * s2**2 * s1}.
+ L ==> List
+ I ==> Integer
+ OUT ==> OutputForm
+ NNI ==> NonNegativeInteger
+ UN ==> Union(%,"failed")
+
+ Exports ==> Join(OrderedCancellationAbelianMonoid,
+ ConvertibleTo List Integer) with
+ partition: L I -> %
+ ++ partition(li) converts a list of integers li to a partition
+ powers: L I -> L L I
+ ++ powers(li) returns a list of 2-element lists. For each 2-element
+ ++ list, the first element is an entry of li and the second
+ ++ element is the multiplicity with which the first element
+ ++ occurs in li. There is a 2-element list for each value
+ ++ occurring in l.
+ pdct: % -> I
+ ++ \spad{pdct(a1**n1 a2**n2 ...)} returns
+ ++ \spad{n1! * a1**n1 * n2! * a2**n2 * ...}.
+ ++ This function is used in the package \spadtype{CycleIndicators}.
+ conjugate: % -> %
+ ++ conjugate(p) returns the conjugate partition of a partition p
+ coerce:% -> List Integer
+ ++ coerce(p) coerces a partition into a list of integers
+
+ Implementation ==> add
+
+ import PartitionsAndPermutations
+
+ Rep := List Integer
+ 0 == nil()
+
+ coerce (s:%) == s pretend List Integer
+ convert x == copy(x pretend L I)
+
+ partition list == sort(#2 < #1,list)
+
+ x < y ==
+ empty? x => not empty? y
+ empty? y => false
+ first x = first y => rest x < rest y
+ first x < first y
+
+ x = y ==
+ EQUAL(x,y)$Lisp
+-- empty? x => empty? y
+-- empty? y => false
+-- first x = first y => rest x = rest y
+-- false
+
+ x + y ==
+ empty? x => y
+ empty? y => x
+ first x > first y => concat(first x,rest(x) + y)
+ concat(first y,x + rest(y))
+ n:NNI * x:% == (zero? n => 0; x + (subtractIfCan(n,1) :: NNI) * x)
+
+ dp: (I,%) -> %
+ dp(i,x) ==
+ empty? x => 0
+ first x = i => rest x
+ concat(first x,dp(i,rest x))
+
+ remv: (I,%) -> UN
+ remv(i,x) == (member?(i,x) => dp(i,x); "failed")
+
+ subtractIfCan(x, y) ==
+ empty? x =>
+ empty? y => 0
+ "failed"
+ empty? y => x
+ (aa := remv(first y,x)) case "failed" => "failed"
+ subtractIfCan((aa :: %), rest y)
+
+ li1 : L I --!! 'bite' won't compile without this
+ bite: (I,L I) -> L I
+ bite(i,li) ==
+ empty? li => concat(0,nil())
+ first li = i =>
+ li1 := bite(i,rest li)
+ concat(first(li1) + 1,rest li1)
+ concat(0,li)
+
+ li : L I --!! 'powers' won't compile without this
+ powers l ==
+ empty? l => nil()
+ li := bite(first l,rest l)
+ concat([first l,first(li) + 1],powers(rest li))
+
+ conjugate x == conjugate(x pretend Rep)$PartitionsAndPermutations
+
+ mkterm: (I,I) -> OUT
+ mkterm(i1,i2) ==
+ i2 = 1 => (i1 :: OUT) ** (" " :: OUT)
+ (i1 :: OUT) ** (i2 :: OUT)
+
+ mkexp1: L L I -> L OUT
+ mkexp1 lli ==
+ empty? lli => nil()
+ li := first lli
+ empty?(rest lli) and second(li) = 1 =>
+ concat(first(li) :: OUT,nil())
+ concat(mkterm(first li,second li),mkexp1(rest lli))
+
+ coerce(x:%):OUT ==
+ empty? (x pretend Rep) => coerce(x pretend Rep)$Rep
+ paren(reduce("*",mkexp1(powers(x pretend Rep))))
+
+ pdct x ==
+ */[factorial(second a) * (first(a) ** (second(a) pretend NNI))
+ for a in powers(x pretend Rep)]
+
+@
+\section{domain SYMPOLY SymmetricPolynomial}
+<<domain SYMPOLY SymmetricPolynomial>>=
+)abbrev domain SYMPOLY SymmetricPolynomial
+++ Description:
+++ This domain implements symmetric polynomial
+SymmetricPolynomial(R:Ring) == PolynomialRing(R,Partition) add
+ Term:= Record(k:Partition,c:R)
+ Rep:= List Term
+
+-- override PR implementation because coeff. arithmetic too expensive (??)
+
+ if R has EntireRing then
+ (p1:%) * (p2:%) ==
+ null p1 => 0
+ null p2 => 0
+ zero?(p1.first.k) => p1.first.c * p2
+-- one? p2 => p1
+ (p2 = 1) => p1
+ +/[[[t1.k+t2.k,t1.c*t2.c]$Term for t2 in p2]
+ for t1 in reverse(p1)]
+ -- This 'reverse' is an efficiency improvement:
+ -- reduces both time and space [Abbott/Bradford/Davenport]
+ else
+ (p1:%) * (p2:%) ==
+ null p1 => 0
+ null p2 => 0
+ zero?(p1.first.k) => p1.first.c * p2
+-- one? p2 => p1
+ (p2 = 1) => p1
+ +/[[[t1.k+t2.k,r]$Term for t2 in p2 | (r:=t1.c*t2.c) ^= 0]
+ for t1 in reverse(p1)]
+ -- This 'reverse' is an efficiency improvement:
+ -- reduces both time and space [Abbott/Bradford/Davenport]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain PRTITION Partition>>
+<<domain SYMPOLY SymmetricPolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pscat.spad.pamphlet b/src/algebra/pscat.spad.pamphlet
new file mode 100644
index 00000000..115c4ac9
--- /dev/null
+++ b/src/algebra/pscat.spad.pamphlet
@@ -0,0 +1,691 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pscat.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PSCAT PowerSeriesCategory}
+<<category PSCAT PowerSeriesCategory>>=
+)abbrev category PSCAT PowerSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 25 February 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: power series
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{PowerSeriesCategory} is the most general power series
+++ category with exponents in an ordered abelian monoid.
+PowerSeriesCategory(Coef,Expon,Var): Category == Definition where
+ Coef : Ring
+ Expon : OrderedAbelianMonoid
+ Var : OrderedSet
+ I ==> Integer
+ RN ==> Fraction Integer
+
+ Definition ==> AbelianMonoidRing(Coef,Expon) with
+
+ monomial: (%,Var,Expon) -> %
+ ++ \spad{monomial(a,x,n)} computes \spad{a*x**n}.
+ monomial: (%,List Var,List Expon) -> %
+ ++ \spad{monomial(a,[x1,..,xk],[n1,..,nk])} computes
+ ++ \spad{a * x1**n1 * .. * xk**nk}.
+ leadingMonomial: % -> %
+ ++ leadingMonomial(f) returns the monomial of \spad{f} of lowest order.
+ leadingCoefficient: % -> Coef
+ ++ leadingCoefficient(f) returns the coefficient of the lowest order
+ ++ term of \spad{f}
+ degree : % -> Expon
+ ++ degree(f) returns the exponent of the lowest order term of \spad{f}.
+ variables: % -> List Var
+ ++ \spad{variables(f)} returns a list of the variables occuring in the
+ ++ power series f.
+ pole?: % -> Boolean
+ ++ \spad{pole?(f)} determines if the power series f has a pole.
+ complete: % -> %
+ ++ \spad{complete(f)} causes all terms of f to be computed.
+ ++ Note: this results in an infinite loop
+ ++ if f has infinitely many terms.
+
+ add
+ n:I * ps:% == (zero? n => 0; map(n * #1,ps))
+ r:Coef * ps:% == (zero? r => 0; map(r * #1,ps))
+ ps:% * r:Coef == (zero? r => 0; map(#1 * r,ps))
+ - ps == map(- #1,ps)
+
+ if Coef has Algebra Fraction Integer then
+ r:RN * ps:% == (zero? r => 0; map(r * #1,ps))
+ ps:% * r:RN == (zero? r => 0; map(#1 * r,ps))
+
+ if Coef has Field then
+ ps:% / r:Coef == map(#1 / r,ps)
+
+@
+\section{category UPSCAT UnivariatePowerSeriesCategory}
+<<category UPSCAT UnivariatePowerSeriesCategory>>=
+)abbrev category UPSCAT UnivariatePowerSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 20 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{UnivariatePowerSeriesCategory} is the most general
+++ univariate power series category with exponents in an ordered
+++ abelian monoid.
+++ Note: this category exports a substitution function if it is
+++ possible to multiply exponents.
+++ Note: this category exports a derivative operation if it is possible
+++ to multiply coefficients by exponents.
+UnivariatePowerSeriesCategory(Coef,Expon): Category == Definition where
+ Coef : Ring
+ Expon : OrderedAbelianMonoid
+ Term ==> Record(k:Expon,c:Coef)
+
+ Definition ==> PowerSeriesCategory(Coef,Expon,SingletonAsOrderedSet) with
+
+ terms: % -> Stream Term
+ ++ \spad{terms(f(x))} returns a stream of non-zero terms, where a
+ ++ a term is an exponent-coefficient pair. The terms in the stream
+ ++ are ordered by increasing order of exponents.
+ --series: Stream Term -> %
+ --++ \spad{series(st)} creates a series from a stream of non-zero terms,
+ --++ where a term is an exponent-coefficient pair. The terms in the
+ --++ stream should be ordered by increasing order of exponents.
+ elt: (%,Expon) -> Coef
+ ++ \spad{elt(f(x),r)} returns the coefficient of the term of degree r in
+ ++ \spad{f(x)}. This is the same as the function \spadfun{coefficient}.
+ variable: % -> Symbol
+ ++ \spad{variable(f)} returns the (unique) power series variable of
+ ++ the power series f.
+ center: % -> Coef
+ ++ \spad{center(f)} returns the point about which the series f is
+ ++ expanded.
+ multiplyExponents: (%,PositiveInteger) -> %
+ ++ \spad{multiplyExponents(f,n)} multiplies all exponents of the power
+ ++ series f by the positive integer n.
+ order: % -> Expon
+ ++ \spad{order(f)} is the degree of the lowest order non-zero term in f.
+ ++ This will result in an infinite loop if f has no non-zero terms.
+ order: (%,Expon) -> Expon
+ ++ \spad{order(f,n) = min(m,n)}, where m is the degree of the
+ ++ lowest order non-zero term in f.
+ truncate: (%,Expon) -> %
+ ++ \spad{truncate(f,k)} returns a (finite) power series consisting of
+ ++ the sum of all terms of f of degree \spad{<= k}.
+ truncate: (%,Expon,Expon) -> %
+ ++ \spad{truncate(f,k1,k2)} returns a (finite) power
+ ++ series consisting of
+ ++ the sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
+ if Coef has coerce: Symbol -> Coef then
+ if Coef has "**":(Coef,Expon) -> Coef then
+ approximate: (%,Expon) -> Coef
+ ++ \spad{approximate(f)} returns a truncated power series with the
+ ++ series variable viewed as an element of the coefficient domain.
+ extend: (%,Expon) -> %
+ ++ \spad{extend(f,n)} causes all terms of f of degree <= n to be computed.
+ if Expon has SemiGroup then Eltable(%,%)
+ if Coef has "*": (Expon,Coef) -> Coef then
+ DifferentialRing
+ --!! DifferentialExtension Coef
+ if Coef has PartialDifferentialRing Symbol then
+ PartialDifferentialRing Symbol
+ if Coef has "**": (Coef,Expon) -> Coef then
+ eval: (%,Coef) -> Stream Coef
+ ++ \spad{eval(f,a)} evaluates a power series at a value in the
+ ++ ground ring by returning a stream of partial sums.
+
+ add
+ degree f == order f
+ leadingCoefficient f == coefficient(f,order f)
+ leadingMonomial f ==
+ ord := order f
+ monomial(coefficient(f,ord),ord)
+ monomial(f:%,listVar:List SingletonAsOrderedSet,listExpon:List Expon) ==
+ empty? listVar or not empty? rest listVar =>
+ error "monomial: variable list must have exactly one entry"
+ empty? listExpon or not empty? rest listExpon =>
+ error "monomial: exponent list must have exactly one entry"
+ f * monomial(1,first listExpon)
+ monomial(f:%,v:SingletonAsOrderedSet,n:Expon) ==
+ f * monomial(1,n)
+ reductum f == f - leadingMonomial f
+ variables f == list create()
+
+@
+\section{category UTSCAT UnivariateTaylorSeriesCategory}
+<<category UTSCAT UnivariateTaylorSeriesCategory>>=
+)abbrev category UTSCAT UnivariateTaylorSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 26 May 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Taylor, linebacker
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{UnivariateTaylorSeriesCategory} is the category of Taylor
+++ series in one variable.
+UnivariateTaylorSeriesCategory(Coef): Category == Definition where
+ Coef : Ring
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ RN ==> Fraction Integer
+ STTA ==> StreamTaylorSeriesOperations Coef
+ STTF ==> StreamTranscendentalFunctions Coef
+ STNC ==> StreamTranscendentalFunctionsNonCommutative Coef
+ Term ==> Record(k:NNI,c:Coef)
+
+ Definition ==> UnivariatePowerSeriesCategory(Coef,NNI) with
+
+ series: Stream Term -> %
+ ++ \spad{series(st)} creates a series from a stream of non-zero terms,
+ ++ where a term is an exponent-coefficient pair. The terms in the
+ ++ stream should be ordered by increasing order of exponents.
+ coefficients: % -> Stream Coef
+ ++ \spad{coefficients(a0 + a1 x + a2 x**2 + ...)} returns a stream
+ ++ of coefficients: \spad{[a0,a1,a2,...]}. The entries of the stream
+ ++ may be zero.
+ series: Stream Coef -> %
+ ++ \spad{series([a0,a1,a2,...])} is the Taylor series
+ ++ \spad{a0 + a1 x + a2 x**2 + ...}.
+ quoByVar: % -> %
+ ++ \spad{quoByVar(a0 + a1 x + a2 x**2 + ...)}
+ ++ returns \spad{a1 + a2 x + a3 x**2 + ...}
+ ++ Thus, this function substracts the constant term and divides by
+ ++ the series variable. This function is used when Laurent series
+ ++ are represented by a Taylor series and an order.
+ multiplyCoefficients: (I -> Coef,%) -> %
+ ++ \spad{multiplyCoefficients(f,sum(n = 0..infinity,a[n] * x**n))}
+ ++ returns \spad{sum(n = 0..infinity,f(n) * a[n] * x**n)}.
+ ++ This function is used when Laurent series are represented by
+ ++ a Taylor series and an order.
+ polynomial: (%,NNI) -> Polynomial Coef
+ ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
+ ++ of all terms of f of degree \spad{<= k}.
+ polynomial: (%,NNI,NNI) -> Polynomial Coef
+ ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
+ ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
+
+ if Coef has Field then
+ "**": (%,Coef) -> %
+ ++ \spad{f(x) ** a} computes a power of a power series.
+ ++ When the coefficient ring is a field, we may raise a series
+ ++ to an exponent from the coefficient ring provided that the
+ ++ constant coefficient of the series is 1.
+
+ if Coef has Algebra Fraction Integer then
+ integrate: % -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+ integrate: (%,Symbol) -> %
+ ++ \spad{integrate(f(x),y)} returns an anti-derivative of the
+ ++ power series \spad{f(x)} with respect to the variable \spad{y}.
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+ integrate: (%,Symbol) -> %
+ ++ \spad{integrate(f(x),y)} returns an anti-derivative of
+ ++ the power series \spad{f(x)} with respect to the variable
+ ++ \spad{y}.
+ RadicalCategory
+ --++ We provide rational powers when we can divide coefficients
+ --++ by integers.
+ TranscendentalFunctionCategory
+ --++ We provide transcendental functions when we can divide
+ --++ coefficients by integers.
+
+ add
+
+ zero? x ==
+ empty? (coefs := coefficients x) => true
+ (zero? frst coefs) and (empty? rst coefs) => true
+ false
+
+--% OutputForms
+
+-- We provide defaulr output functions on UTSCAT using the functions
+-- 'coefficients', 'center', and 'variable'.
+
+ factorials?: () -> Boolean
+ -- check a global Lisp variable
+ factorials?() == false
+
+ termOutput: (I,Coef,OUT) -> OUT
+ termOutput(k,c,vv) ==
+ -- creates a term c * vv ** k
+ k = 0 => c :: OUT
+ mon := (k = 1 => vv; vv ** (k :: OUT))
+-- if factorials?() and k > 1 then
+-- c := factorial(k)$IntegerCombinatoricFunctions * c
+-- mon := mon / hconcat(k :: OUT,"!" :: OUT)
+ c = 1 => mon
+ c = -1 => -mon
+ (c :: OUT) * mon
+
+ showAll?: () -> Boolean
+ -- check a global Lisp variable
+ showAll?() == true
+
+ coerce(p:%):OUT ==
+ empty? (uu := coefficients p) => (0$Coef) :: OUT
+ var := variable p; cen := center p
+ vv :=
+ zero? cen => var :: OUT
+ paren(var :: OUT - cen :: OUT)
+ n : NNI ; count : NNI := _$streamCount$Lisp
+ l : L OUT := empty()
+ for n in 0..count while not empty? uu repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput(n :: I,frst uu,vv),l)
+ uu := rst uu
+ if showAll?() then
+ for n in (count + 1).. while explicitEntries? uu and _
+ not eq?(uu,rst uu) repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput(n :: I,frst uu,vv),l)
+ uu := rst uu
+ l :=
+ explicitlyEmpty? uu => l
+ eq?(uu,rst uu) and frst uu = 0 => l
+ concat(prefix("O" :: OUT,[vv ** (n :: OUT)]),l)
+ empty? l => (0$Coef) :: OUT
+ reduce("+",reverse_! l)
+
+ if Coef has Field then
+ (x:%) ** (r:Coef) == series power(r,coefficients x)$STTA
+
+ if Coef has Algebra Fraction Integer then
+ if Coef has CommutativeRing then
+ (x:%) ** (y:%) == series(coefficients x **$STTF coefficients y)
+ (x:%) ** (r:RN) == series powern(r,coefficients x)$STTA
+
+ exp x == series exp(coefficients x)$STTF
+ log x == series log(coefficients x)$STTF
+
+ sin x == series sin(coefficients x)$STTF
+ cos x == series cos(coefficients x)$STTF
+ tan x == series tan(coefficients x)$STTF
+ cot x == series cot(coefficients x)$STTF
+ sec x == series sec(coefficients x)$STTF
+ csc x == series csc(coefficients x)$STTF
+
+ asin x == series asin(coefficients x)$STTF
+ acos x == series acos(coefficients x)$STTF
+ atan x == series atan(coefficients x)$STTF
+ acot x == series acot(coefficients x)$STTF
+ asec x == series asec(coefficients x)$STTF
+ acsc x == series acsc(coefficients x)$STTF
+
+ sinh x == series sinh(coefficients x)$STTF
+ cosh x == series cosh(coefficients x)$STTF
+ tanh x == series tanh(coefficients x)$STTF
+ coth x == series coth(coefficients x)$STTF
+ sech x == series sech(coefficients x)$STTF
+ csch x == series csch(coefficients x)$STTF
+
+ asinh x == series asinh(coefficients x)$STTF
+ acosh x == series acosh(coefficients x)$STTF
+ atanh x == series atanh(coefficients x)$STTF
+ acoth x == series acoth(coefficients x)$STTF
+ asech x == series asech(coefficients x)$STTF
+ acsch x == series acsch(coefficients x)$STTF
+
+ else
+ (x:%) ** (y:%) == series(coefficients x **$STNC coefficients y)
+
+ (x:%) ** (r:RN) ==
+ coefs := coefficients x
+ empty? coefs =>
+ positive? r => 0
+ zero? r => error "0**0 undefined"
+ error "0 raised to a negative power"
+-- not one? frst coefs =>
+ not (frst coefs = 1) =>
+ error "**: constant coefficient should be 1"
+ coefs := concat(0,rst coefs)
+ onePlusX := monom(1,0)$STTA + $STTA monom(1,1)$STTA
+ ratPow := powern(r,onePlusX)$STTA
+ series compose(ratPow,coefs)$STTA
+
+ exp x == series exp(coefficients x)$STNC
+ log x == series log(coefficients x)$STNC
+
+ sin x == series sin(coefficients x)$STNC
+ cos x == series cos(coefficients x)$STNC
+ tan x == series tan(coefficients x)$STNC
+ cot x == series cot(coefficients x)$STNC
+ sec x == series sec(coefficients x)$STNC
+ csc x == series csc(coefficients x)$STNC
+
+ asin x == series asin(coefficients x)$STNC
+ acos x == series acos(coefficients x)$STNC
+ atan x == series atan(coefficients x)$STNC
+ acot x == series acot(coefficients x)$STNC
+ asec x == series asec(coefficients x)$STNC
+ acsc x == series acsc(coefficients x)$STNC
+
+ sinh x == series sinh(coefficients x)$STNC
+ cosh x == series cosh(coefficients x)$STNC
+ tanh x == series tanh(coefficients x)$STNC
+ coth x == series coth(coefficients x)$STNC
+ sech x == series sech(coefficients x)$STNC
+ csch x == series csch(coefficients x)$STNC
+
+ asinh x == series asinh(coefficients x)$STNC
+ acosh x == series acosh(coefficients x)$STNC
+ atanh x == series atanh(coefficients x)$STNC
+ acoth x == series acoth(coefficients x)$STNC
+ asech x == series asech(coefficients x)$STNC
+ acsch x == series acsch(coefficients x)$STNC
+
+@
+\section{category ULSCAT UnivariateLaurentSeriesCategory}
+<<category ULSCAT UnivariateLaurentSeriesCategory>>=
+)abbrev category ULSCAT UnivariateLaurentSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 20 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Laurent
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{UnivariateLaurentSeriesCategory} is the category of
+++ Laurent series in one variable.
+UnivariateLaurentSeriesCategory(Coef): Category == Definition where
+ Coef : Ring
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ Term ==> Record(k:I,c:Coef)
+
+ Definition ==> UnivariatePowerSeriesCategory(Coef,Integer) with
+
+ series: Stream Term -> %
+ ++ \spad{series(st)} creates a series from a stream of non-zero terms,
+ ++ where a term is an exponent-coefficient pair. The terms in the
+ ++ stream should be ordered by increasing order of exponents.
+ multiplyCoefficients: (I -> Coef,%) -> %
+ ++ \spad{multiplyCoefficients(f,sum(n = n0..infinity,a[n] * x**n)) =
+ ++ sum(n = 0..infinity,f(n) * a[n] * x**n)}.
+ ++ This function is used when Puiseux series are represented by
+ ++ a Laurent series and an exponent.
+ if Coef has IntegralDomain then
+ rationalFunction: (%,I) -> Fraction Polynomial Coef
+ ++ \spad{rationalFunction(f,k)} returns a rational function
+ ++ consisting of the sum of all terms of f of degree <= k.
+ rationalFunction: (%,I,I) -> Fraction Polynomial Coef
+ ++ \spad{rationalFunction(f,k1,k2)} returns a rational function
+ ++ consisting of the sum of all terms of f of degree d with
+ ++ \spad{k1 <= d <= k2}.
+
+ if Coef has Algebra Fraction Integer then
+ integrate: % -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 1.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+ integrate: (%,Symbol) -> %
+ ++ \spad{integrate(f(x),y)} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with respect to the variable \spad{y}.
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+ integrate: (%,Symbol) -> %
+ ++ \spad{integrate(f(x),y)} returns an anti-derivative of
+ ++ the power series \spad{f(x)} with respect to the variable
+ ++ \spad{y}.
+ RadicalCategory
+ --++ We provide rational powers when we can divide coefficients
+ --++ by integers.
+ TranscendentalFunctionCategory
+ --++ We provide transcendental functions when we can divide
+ --++ coefficients by integers.
+ if Coef has Field then Field
+ --++ Univariate Laurent series over a field form a field.
+ --++ In fact, K((x)) is the quotient field of K[[x]].
+
+@
+\section{ULSCAT.lsp BOOTSTRAP}
+{\bf ULSCAT} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf ULSCAT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf ULSCAT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ULSCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |UnivariateLaurentSeriesCategory;CAT| (QUOTE NIL))
+
+(SETQ |UnivariateLaurentSeriesCategory;AL| (QUOTE NIL))
+
+(DEFUN |UnivariateLaurentSeriesCategory| (#1=#:G83278) (LET (#2=#:G83279) (COND ((SETQ #2# (|assoc| (|devaluate| #1#) |UnivariateLaurentSeriesCategory;AL|)) (CDR #2#)) (T (SETQ |UnivariateLaurentSeriesCategory;AL| (|cons5| (CONS (|devaluate| #1#) (SETQ #2# (|UnivariateLaurentSeriesCategory;| #1#))) |UnivariateLaurentSeriesCategory;AL|)) #2#))))
+
+(DEFUN |UnivariateLaurentSeriesCategory;| (|t#1|) (PROG (#1=#:G83277) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1|)) (LIST (|devaluate| |t#1|))) (|sublisV| (PAIR (QUOTE (#2=#:G83276)) (LIST (QUOTE (|Integer|)))) (COND (|UnivariateLaurentSeriesCategory;CAT|) ((QUOTE T) (LETT |UnivariateLaurentSeriesCategory;CAT| (|Join| (|UnivariatePowerSeriesCategory| (QUOTE |t#1|) (QUOTE #2#)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|series| (|$| (|Stream| (|Record| (|:| |k| (|Integer|)) (|:| |c| |t#1|))))) T) ((|multiplyCoefficients| (|$| (|Mapping| |t#1| (|Integer|)) |$|)) T) ((|rationalFunction| ((|Fraction| (|Polynomial| |t#1|)) |$| (|Integer|))) (|has| |t#1| (|IntegralDomain|))) ((|rationalFunction| ((|Fraction| (|Polynomial| |t#1|)) |$| (|Integer|) (|Integer|))) (|has| |t#1| (|IntegralDomain|))) ((|integrate| (|$| |$|)) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|))))) ((|integrate| (|$| |$| (|Symbol|))) (AND (|has| |t#1| (SIGNATURE |variables| ((|List| (|Symbol|)) |t#1|))) (|has| |t#1| (SIGNATURE |integrate| (|t#1| |t#1| (|Symbol|)))) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|)))))) ((|integrate| (|$| |$| (|Symbol|))) (AND (|has| |t#1| (|AlgebraicallyClosedFunctionSpace| (|Integer|))) (|has| |t#1| (|PrimitiveFunctionCategory|)) (|has| |t#1| (|TranscendentalFunctionCategory|)) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|)))))))) (QUOTE (((|RadicalCategory|) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|))))) ((|TranscendentalFunctionCategory|) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|))))) ((|Field|) (|has| |t#1| (|Field|))))) (QUOTE ((|Symbol|) (|Fraction| (|Polynomial| |t#1|)) (|Integer|) (|Stream| (|Record| (|:| |k| (|Integer|)) (|:| |c| |t#1|))))) NIL)) . #3=(|UnivariateLaurentSeriesCategory|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |UnivariateLaurentSeriesCategory|) (|devaluate| |t#1|)))))))
+@
+\section{category UPXSCAT UnivariatePuiseuxSeriesCategory}
+<<category UPXSCAT UnivariatePuiseuxSeriesCategory>>=
+)abbrev category UPXSCAT UnivariatePuiseuxSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 20 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Puiseux
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{UnivariatePuiseuxSeriesCategory} is the category of Puiseux
+++ series in one variable.
+UnivariatePuiseuxSeriesCategory(Coef): Category == Definition where
+ Coef : Ring
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+ Term ==> Record(k:RN,c:Coef)
+
+ Definition ==> UnivariatePowerSeriesCategory(Coef,RN) with
+
+ series: (NNI,Stream Term) -> %
+ ++ \spad{series(n,st)} creates a series from a common denomiator and
+ ++ a stream of non-zero terms, where a term is an exponent-coefficient
+ ++ pair. The terms in the stream should be ordered by increasing order
+ ++ of exponents and \spad{n} should be a common denominator for the
+ ++ exponents in the stream of terms.
+ multiplyExponents: (%,Fraction Integer) -> %
+ ++ \spad{multiplyExponents(f,r)} multiplies all exponents of the power
+ ++ series f by the positive rational number r.
+
+ if Coef has Algebra Fraction Integer then
+ integrate: % -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 1.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by rational numbers.
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+ integrate: (%,Symbol) -> %
+ ++ \spad{integrate(f(x),var)} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with respect to the variable \spad{var}.
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+ integrate: (%,Symbol) -> %
+ ++ \spad{integrate(f(x),y)} returns an anti-derivative of
+ ++ the power series \spad{f(x)} with respect to the variable
+ ++ \spad{y}.
+ RadicalCategory
+ --++ We provide rational powers when we can divide coefficients
+ --++ by integers.
+ TranscendentalFunctionCategory
+ --++ We provide transcendental functions when we can divide
+ --++ coefficients by integers.
+ if Coef has Field then Field
+ --++ Univariate Puiseux series over a field form a field.
+
+@
+\section{category MTSCAT MultivariateTaylorSeriesCategory}
+<<category MTSCAT MultivariateTaylorSeriesCategory>>=
+)abbrev category MTSCAT MultivariateTaylorSeriesCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 6 March 1990
+++ Date Last Updated: 6 March 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: multivariate, Taylor, series
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{MultivariateTaylorSeriesCategory} is the most general
+++ multivariate Taylor series category.
+MultivariateTaylorSeriesCategory(Coef,Var): Category == Definition where
+ Coef : Ring
+ Var : OrderedSet
+ L ==> List
+ NNI ==> NonNegativeInteger
+
+ Definition ==> Join(PartialDifferentialRing Var,_
+ PowerSeriesCategory(Coef,IndexedExponents Var,Var),_
+ InnerEvalable(Var,%),Evalable %) with
+ coefficient: (%,Var,NNI) -> %
+ ++ \spad{coefficient(f,x,n)} returns the coefficient of \spad{x^n} in f.
+ coefficient: (%,L Var,L NNI) -> %
+ ++ \spad{coefficient(f,[x1,x2,...,xk],[n1,n2,...,nk])} returns the
+ ++ coefficient of \spad{x1^n1 * ... * xk^nk} in f.
+ extend: (%,NNI) -> %
+ ++ \spad{extend(f,n)} causes all terms of f of degree
+ ++ \spad{<= n} to be computed.
+ monomial: (%,Var,NNI) -> %
+ ++ \spad{monomial(a,x,n)} returns \spad{a*x^n}.
+ monomial: (%,L Var,L NNI) -> %
+ ++ \spad{monomial(a,[x1,x2,...,xk],[n1,n2,...,nk])} returns
+ ++ \spad{a * x1^n1 * ... * xk^nk}.
+ order: (%,Var) -> NNI
+ ++ \spad{order(f,x)} returns the order of f viewed as a series in x
+ ++ may result in an infinite loop if f has no non-zero terms.
+ order: (%,Var,NNI) -> NNI
+ ++ \spad{order(f,x,n)} returns \spad{min(n,order(f,x))}.
+ polynomial: (%,NNI) -> Polynomial Coef
+ ++ \spad{polynomial(f,k)} returns a polynomial consisting of the sum
+ ++ of all terms of f of degree \spad{<= k}.
+ polynomial: (%,NNI,NNI) -> Polynomial Coef
+ ++ \spad{polynomial(f,k1,k2)} returns a polynomial consisting of the
+ ++ sum of all terms of f of degree d with \spad{k1 <= d <= k2}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Var) -> %
+ ++ \spad{integrate(f,x)} returns the anti-derivative of the power
+ ++ series \spad{f(x)} with respect to the variable x with constant
+ ++ coefficient 1. We may integrate a series when we can divide
+ ++ coefficients by integers.
+ RadicalCategory
+ --++ We provide rational powers when we can divide coefficients
+ --++ by integers.
+ TranscendentalFunctionCategory
+ --++ We provide transcendental functions when we can divide
+ --++ coefficients by integers.
+
+@
+\section{MTSCAT.lsp BOOTSTRAP}
+{\bf MTSCAT} depends on a chain of files. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf MTSCAT}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf MTSCAT.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<MTSCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |MultivariateTaylorSeriesCategory;CAT| (QUOTE NIL))
+
+(SETQ |MultivariateTaylorSeriesCategory;AL| (QUOTE NIL))
+
+(DEFUN |MultivariateTaylorSeriesCategory| (|&REST| #1=#:G83334 |&AUX| #2=#:G83332) (DSETQ #2# #1#) (LET (#3=#:G83333) (COND ((SETQ #3# (|assoc| (|devaluateList| #2#) |MultivariateTaylorSeriesCategory;AL|)) (CDR #3#)) (T (SETQ |MultivariateTaylorSeriesCategory;AL| (|cons5| (CONS (|devaluateList| #2#) (SETQ #3# (APPLY (FUNCTION |MultivariateTaylorSeriesCategory;|) #2#))) |MultivariateTaylorSeriesCategory;AL|)) #3#))))
+
+(DEFUN |MultivariateTaylorSeriesCategory;| (|t#1| |t#2|) (PROG (#1=#:G83331) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1| |t#2|)) (LIST (|devaluate| |t#1|) (|devaluate| |t#2|))) (|sublisV| (PAIR (QUOTE (#2=#:G83330)) (LIST (QUOTE (|IndexedExponents| |t#2|)))) (COND (|MultivariateTaylorSeriesCategory;CAT|) ((QUOTE T) (LETT |MultivariateTaylorSeriesCategory;CAT| (|Join| (|PartialDifferentialRing| (QUOTE |t#2|)) (|PowerSeriesCategory| (QUOTE |t#1|) (QUOTE #2#) (QUOTE |t#2|)) (|InnerEvalable| (QUOTE |t#2|) (QUOTE |$|)) (|Evalable| (QUOTE |$|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|coefficient| (|$| |$| |t#2| (|NonNegativeInteger|))) T) ((|coefficient| (|$| |$| (|List| |t#2|) (|List| (|NonNegativeInteger|)))) T) ((|extend| (|$| |$| (|NonNegativeInteger|))) T) ((|monomial| (|$| |$| |t#2| (|NonNegativeInteger|))) T) ((|monomial| (|$| |$| (|List| |t#2|) (|List| (|NonNegativeInteger|)))) T) ((|order| ((|NonNegativeInteger|) |$| |t#2|)) T) ((|order| ((|NonNegativeInteger|) |$| |t#2| (|NonNegativeInteger|))) T) ((|polynomial| ((|Polynomial| |t#1|) |$| (|NonNegativeInteger|))) T) ((|polynomial| ((|Polynomial| |t#1|) |$| (|NonNegativeInteger|) (|NonNegativeInteger|))) T) ((|integrate| (|$| |$| |t#2|)) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|))))))) (QUOTE (((|RadicalCategory|) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|))))) ((|TranscendentalFunctionCategory|) (|has| |t#1| (|Algebra| (|Fraction| (|Integer|))))))) (QUOTE ((|Polynomial| |t#1|) (|NonNegativeInteger|) (|List| |t#2|) (|List| (|NonNegativeInteger|)))) NIL)) . #3=(|MultivariateTaylorSeriesCategory|)))))) . #3#) (SETELT #1# 0 (LIST (QUOTE |MultivariateTaylorSeriesCategory|) (|devaluate| |t#1|) (|devaluate| |t#2|)))))))
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PSCAT PowerSeriesCategory>>
+<<category UPSCAT UnivariatePowerSeriesCategory>>
+<<category UTSCAT UnivariateTaylorSeriesCategory>>
+<<category ULSCAT UnivariateLaurentSeriesCategory>>
+<<category UPXSCAT UnivariatePuiseuxSeriesCategory>>
+<<category MTSCAT MultivariateTaylorSeriesCategory>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/pseudolin.spad.pamphlet b/src/algebra/pseudolin.spad.pamphlet
new file mode 100644
index 00000000..3eb384b4
--- /dev/null
+++ b/src/algebra/pseudolin.spad.pamphlet
@@ -0,0 +1,208 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra pseudolin.spad}
+\author{Bruno Zuercher}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package PSEUDLIN PseudoLinearNormalForm}
+<<package PSEUDLIN PseudoLinearNormalForm>>=
+)abbrev package PSEUDLIN PseudoLinearNormalForm
+++ Normal forms of pseudo-linear operators
+++ Author: Bruno Zuercher
+++ Date Created: November 1993
+++ Date Last Updated: 12 April 1994
+++ Description:
+++ PseudoLinearNormalForm provides a function for computing a block-companion
+++ form for pseudo-linear operators.
+PseudoLinearNormalForm(K:Field): Exports == Implementation where
+ ER ==> Record(C: Matrix K, g: Vector K)
+ REC ==> Record(R: Matrix K, A: Matrix K, Ainv: Matrix K)
+
+ Exports ==> with
+ normalForm: (Matrix K, Automorphism K, K -> K) -> REC
+ ++ normalForm(M, sig, der) returns \spad{[R, A, A^{-1}]} such that
+ ++ the pseudo-linear operator whose matrix in the basis \spad{y} is
+ ++ \spad{M} had matrix \spad{R} in the basis \spad{z = A y}.
+ ++ \spad{der} is a \spad{sig}-derivation.
+ changeBase: (Matrix K, Matrix K, Automorphism K, K -> K) -> Matrix K
+ ++ changeBase(M, A, sig, der): computes the new matrix of a pseudo-linear
+ ++ transform given by the matrix M under the change of base A
+ companionBlocks: (Matrix K, Vector K) -> List ER
+ ++ companionBlocks(m, v) returns \spad{[[C_1, g_1],...,[C_k, g_k]]}
+ ++ such that each \spad{C_i} is a companion block and
+ ++ \spad{m = diagonal(C_1,...,C_k)}.
+
+ Implementation ==> add
+ normalForm0: (Matrix K, Automorphism K, Automorphism K, K -> K) -> REC
+ mulMatrix: (Integer, Integer, K) -> Matrix K
+ -- mulMatrix(N, i, a): under a change of base with the resulting matrix of
+ -- size N*N the following operations are performed:
+ -- D1: column i will be multiplied by sig(a)
+ -- D2: row i will be multiplied by 1/a
+ -- D3: addition of der(a)/a to the element at position (i,i)
+ addMatrix: (Integer, Integer, Integer, K) -> Matrix K
+ -- addMatrix(N, i, k, a): under a change of base with the resulting matrix
+ -- of size N*N the following operations are performed:
+ -- C1: addition of column i multiplied by sig(a) to column k
+ -- C2: addition of row k multiplied by -a to row i
+ -- C3: addition of -a*der(a) to the element at position (i,k)
+ permutationMatrix: (Integer, Integer, Integer) -> Matrix K
+ -- permutationMatrix(N, i, k): under a change of base with the resulting
+ -- permutation matrix of size N*N the following operations are performed:
+ -- P1: columns i and k will be exchanged
+ -- P2: rows i and k will be exchanged
+ inv: Matrix K -> Matrix K
+ -- inv(M): computes the inverse of a invertable matrix M.
+ -- avoids possible type conflicts
+
+ inv m == inverse(m) :: Matrix K
+ changeBase(M, A, sig, der) == inv(A) * (M * map(sig #1, A) + map(der, A))
+ normalForm(M, sig, der) == normalForm0(M, sig, inv sig, der)
+
+ companionBlocks(R, w) ==
+ -- decomposes the rational matrix R into single companion blocks
+ -- and the inhomogenity w as well
+ i:Integer := 1
+ n := nrows R
+ l:List(ER) := empty()
+ while i <= n repeat
+ j := i
+ while j+1 <= n and R(j,j+1) = 1 repeat j := j+1
+ --split block now
+ v:Vector K := new((j-i+1)::NonNegativeInteger, 0)
+ for k in i..j repeat v(k-i+1) := w k
+ l := concat([subMatrix(R,i,j,i,j), v], l)
+ i := j+1
+ l
+
+ normalForm0(M, sig, siginv, der) ==
+ -- the changes of base will be incremented in B and Binv,
+ -- where B**(-1)=Binv; E defines an elementary matrix
+ B, Binv, E : Matrix K
+ recOfMatrices : REC
+ N := nrows M
+ B := diagonalMatrix [1 for k in 1..N]
+ Binv := copy B
+ -- avoid unnecessary recursion
+ if diagonal?(M) then return [M, B, Binv]
+ i : Integer := 1
+ while i < N repeat
+ j := i + 1
+ while j <= N and M(i, j) = 0 repeat j := j + 1
+ if j <= N then
+ -- expand companionblock by lemma 5
+ if j ^= i+1 then
+ -- perform first a permutation
+ E := permutationMatrix(N, i+1, j)
+ M := changeBase(M, E, sig, der)
+ B := B*E
+ Binv := E*Binv
+ -- now is M(i, i+1) ^= 0
+ E := mulMatrix(N, i+1, siginv inv M(i,i+1))
+ M := changeBase(M, E, sig, der)
+ B := B*E
+ Binv := inv(E)*Binv
+ for j in 1..N repeat
+ if j ^= i+1 then
+ E := addMatrix(N, i+1, j, siginv(-M(i,j)))
+ M := changeBase(M, E, sig, der)
+ B := B*E
+ Binv := inv(E)*Binv
+ i := i + 1
+ else
+ -- apply lemma 6
+ for j in i..2 by -1 repeat
+ for k in (i+1)..N repeat
+ E := addMatrix(N, k, j-1, M(k,j))
+ M := changeBase(M, E, sig, der)
+ B := B*E
+ Binv := inv(E)*Binv
+ j := i + 1
+ while j <= N and M(j,1) = 0 repeat j := j + 1
+ if j <= N then
+ -- expand companionblock by lemma 8
+ E := permutationMatrix(N, 1, j)
+ M := changeBase(M, E, sig, der)
+ B := B*E
+ Binv := E*Binv
+ -- start again to establish rational form
+ i := 1
+ else
+ -- split a direct factor
+ recOfMatrices :=
+ normalForm(subMatrix(M, i+1, N, i+1, N), sig, der)
+ setsubMatrix!(M, i+1, i+1, recOfMatrices.R)
+ E := diagonalMatrix [1 for k in 1..N]
+ setsubMatrix!(E, i+1, i+1, recOfMatrices.A)
+ B := B*E
+ setsubMatrix!(E, i+1, i+1, recOfMatrices.Ainv)
+ Binv := E*Binv
+ -- M in blockdiagonalform, stop program
+ i := N
+ [M, B, Binv]
+
+ mulMatrix(N, i, a) ==
+ M : Matrix K := diagonalMatrix [1 for j in 1..N]
+ M(i, i) := a
+ M
+
+ addMatrix(N, i, k, a) ==
+ A : Matrix K := diagonalMatrix [1 for j in 1..N]
+ A(i, k) := a
+ A
+
+ permutationMatrix(N, i, k) ==
+ P : Matrix K := diagonalMatrix [1 for j in 1..N]
+ P(i, i) := P(k, k) := 0
+ P(i, k) := P(k, i) := 1
+ P
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package PSEUDLIN PseudoLinearNormalForm>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ptranfn.spad.pamphlet b/src/algebra/ptranfn.spad.pamphlet
new file mode 100644
index 00000000..306346d7
--- /dev/null
+++ b/src/algebra/ptranfn.spad.pamphlet
@@ -0,0 +1,146 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ptranfn.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category PTRANFN PartialTranscendentalFunctions}
+<<category PTRANFN PartialTranscendentalFunctions>>=
+)abbrev category PTRANFN PartialTranscendentalFunctions
+++ Description of a package which provides partial transcendental
+++ functions, i.e. functions which return an answer or "failed"
+++ Author: Clifton J. Williamson
+++ Date Created: 12 February 1990
+++ Date Last Updated: 14 February 1990
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This is the description of any package which provides partial
+++ functions on a domain belonging to TranscendentalFunctionCategory.
+
+PartialTranscendentalFunctions(K): Category == Definition where
+ K : TranscendentalFunctionCategory
+ NNI ==> NonNegativeInteger
+
+ Definition ==> with
+
+--% Exponentials and Logarithms
+
+ nthRootIfCan: (K,NNI) -> Union(K,"failed")
+ ++ nthRootIfCan(z,n) returns the nth root of z if possible,
+ ++ and "failed" otherwise.
+ expIfCan: K -> Union(K,"failed")
+ ++ expIfCan(z) returns exp(z) if possible, and "failed" otherwise.
+ logIfCan: K -> Union(K,"failed")
+ ++ logIfCan(z) returns log(z) if possible, and "failed" otherwise.
+
+--% TrigonometricFunctionCategory
+
+ sinIfCan : K -> Union(K,"failed")
+ ++ sinIfCan(z) returns sin(z) if possible, and "failed" otherwise.
+ cosIfCan: K -> Union(K,"failed")
+ ++ cosIfCan(z) returns cos(z) if possible, and "failed" otherwise.
+ tanIfCan: K -> Union(K,"failed")
+ ++ tanIfCan(z) returns tan(z) if possible, and "failed" otherwise.
+ cotIfCan: K -> Union(K,"failed")
+ ++ cotIfCan(z) returns cot(z) if possible, and "failed" otherwise.
+ secIfCan: K -> Union(K,"failed")
+ ++ secIfCan(z) returns sec(z) if possible, and "failed" otherwise.
+ cscIfCan: K -> Union(K,"failed")
+ ++ cscIfCan(z) returns csc(z) if possible, and "failed" otherwise.
+
+--% ArcTrigonometricFunctionCategory
+
+ asinIfCan: K -> Union(K,"failed")
+ ++ asinIfCan(z) returns asin(z) if possible, and "failed" otherwise.
+ acosIfCan: K -> Union(K,"failed")
+ ++ acosIfCan(z) returns acos(z) if possible, and "failed" otherwise.
+ atanIfCan: K -> Union(K,"failed")
+ ++ atanIfCan(z) returns atan(z) if possible, and "failed" otherwise.
+ acotIfCan: K -> Union(K,"failed")
+ ++ acotIfCan(z) returns acot(z) if possible, and "failed" otherwise.
+ asecIfCan: K -> Union(K,"failed")
+ ++ asecIfCan(z) returns asec(z) if possible, and "failed" otherwise.
+ acscIfCan: K -> Union(K,"failed")
+ ++ acscIfCan(z) returns acsc(z) if possible, and "failed" otherwise.
+
+--% HyperbolicFunctionCategory
+
+ sinhIfCan: K -> Union(K,"failed")
+ ++ sinhIfCan(z) returns sinh(z) if possible, and "failed" otherwise.
+ coshIfCan: K -> Union(K,"failed")
+ ++ coshIfCan(z) returns cosh(z) if possible, and "failed" otherwise.
+ tanhIfCan: K -> Union(K,"failed")
+ ++ tanhIfCan(z) returns tanh(z) if possible, and "failed" otherwise.
+ cothIfCan: K -> Union(K,"failed")
+ ++ cothIfCan(z) returns coth(z) if possible, and "failed" otherwise.
+ sechIfCan: K -> Union(K,"failed")
+ ++ sechIfCan(z) returns sech(z) if possible, and "failed" otherwise.
+ cschIfCan: K -> Union(K,"failed")
+ ++ cschIfCan(z) returns csch(z) if possible, and "failed" otherwise.
+
+--% ArcHyperbolicFunctionCategory
+
+ asinhIfCan: K -> Union(K,"failed")
+ ++ asinhIfCan(z) returns asinh(z) if possible, and "failed" otherwise.
+ acoshIfCan: K -> Union(K,"failed")
+ ++ acoshIfCan(z) returns acosh(z) if possible, and "failed" otherwise.
+ atanhIfCan: K -> Union(K,"failed")
+ ++ atanhIfCan(z) returns atanh(z) if possible, and "failed" otherwise.
+ acothIfCan: K -> Union(K,"failed")
+ ++ acothIfCan(z) returns acoth(z) if possible, and "failed" otherwise.
+ asechIfCan: K -> Union(K,"failed")
+ ++ asechIfCan(z) returns asech(z) if possible, and "failed" otherwise.
+ acschIfCan: K -> Union(K,"failed")
+ ++ acschIfCan(z) returns acsch(z) if possible, and "failed" otherwise.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category PTRANFN PartialTranscendentalFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/puiseux.spad.pamphlet b/src/algebra/puiseux.spad.pamphlet
new file mode 100644
index 00000000..3d1f8162
--- /dev/null
+++ b/src/algebra/puiseux.spad.pamphlet
@@ -0,0 +1,658 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra puiseux.spad}
+\author{Clifton J. Williamson, Scott C. Morrison}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory}
+<<category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory>>=
+)abbrev category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory
+++ Author: Clifton J. Williamson
+++ Date Created: 6 February 1990
+++ Date Last Updated: 22 March 1990
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Puiseux, Laurent
+++ Examples:
+++ References:
+++ Description:
+++ This is a category of univariate Puiseux series constructed
+++ from univariate Laurent series. A Puiseux series is represented
+++ by a pair \spad{[r,f(x)]}, where r is a positive rational number and
+++ \spad{f(x)} is a Laurent series. This pair represents the Puiseux
+++ series \spad{f(x^r)}.
+UnivariatePuiseuxSeriesConstructorCategory(Coef,ULS):_
+ Category == Definition where
+ Coef : Ring
+ ULS : UnivariateLaurentSeriesCategory Coef
+ I ==> Integer
+ RN ==> Fraction Integer
+
+ Definition ==> Join(UnivariatePuiseuxSeriesCategory(Coef),_
+ RetractableTo ULS) with
+ puiseux: (RN,ULS) -> %
+ ++ \spad{puiseux(r,f(x))} returns \spad{f(x^r)}.
+ rationalPower: % -> RN
+ ++ \spad{rationalPower(f(x))} returns r where the Puiseux series
+ ++ \spad{f(x) = g(x^r)}.
+ laurentRep : % -> ULS
+ ++ \spad{laurentRep(f(x))} returns \spad{g(x)} where the Puiseux series
+ ++ \spad{f(x) = g(x^r)} is represented by \spad{[r,g(x)]}.
+ degree: % -> RN
+ ++ \spad{degree(f(x))} returns the degree of the leading term of the
+ ++ Puiseux series \spad{f(x)}, which may have zero as a coefficient.
+ coerce: ULS -> %
+ ++ \spad{coerce(f(x))} converts the Laurent series \spad{f(x)} to a
+ ++ Puiseux series.
+ laurent: % -> ULS
+ ++ \spad{laurent(f(x))} converts the Puiseux series \spad{f(x)} to a
+ ++ Laurent series if possible. Error: if this is not possible.
+ laurentIfCan: % -> Union(ULS,"failed")
+ ++ \spad{laurentIfCan(f(x))} converts the Puiseux series \spad{f(x)}
+ ++ to a Laurent series if possible.
+ ++ If this is not possible, "failed" is returned.
+
+ add
+
+ zero? x == zero? laurentRep x
+ retract(x:%):ULS == laurent x
+ retractIfCan(x:%):Union(ULS,"failed") == laurentIfCan x
+
+@
+\section{domain UPXSCONS UnivariatePuiseuxSeriesConstructor}
+<<domain UPXSCONS UnivariatePuiseuxSeriesConstructor>>=
+)abbrev domain UPXSCONS UnivariatePuiseuxSeriesConstructor
+++ Author: Clifton J. Williamson
+++ Date Created: 9 May 1989
+++ Date Last Updated: 30 November 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Puiseux, Laurent
+++ Examples:
+++ References:
+++ Description:
+++ This package enables one to construct a univariate Puiseux series
+++ domain from a univariate Laurent series domain. Univariate
+++ Puiseux series are represented by a pair \spad{[r,f(x)]}, where r is
+++ a positive rational number and \spad{f(x)} is a Laurent series.
+++ This pair represents the Puiseux series \spad{f(x^r)}.
+
+UnivariatePuiseuxSeriesConstructor(Coef,ULS):_
+ Exports == Implementation where
+ Coef : Ring
+ ULS : UnivariateLaurentSeriesCategory Coef
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ PI ==> PositiveInteger
+ RN ==> Fraction Integer
+ ST ==> Stream Coef
+ LTerm ==> Record(k:I,c:Coef)
+ PTerm ==> Record(k:RN,c:Coef)
+ ST2LP ==> StreamFunctions2(LTerm,PTerm)
+ ST2PL ==> StreamFunctions2(PTerm,LTerm)
+
+ Exports ==> UnivariatePuiseuxSeriesConstructorCategory(Coef,ULS)
+
+ Implementation ==> add
+
+--% representation
+
+ Rep := Record(expon:RN,lSeries:ULS)
+
+ getExpon: % -> RN
+ getULS : % -> ULS
+
+ getExpon pxs == pxs.expon
+ getULS pxs == pxs.lSeries
+
+--% creation and destruction
+
+ puiseux(n,ls) == [n,ls]
+ laurentRep x == getULS x
+ rationalPower x == getExpon x
+ degree x == getExpon(x) * degree(getULS(x))
+
+ 0 == puiseux(1,0)
+ 1 == puiseux(1,1)
+
+ monomial(c,k) ==
+ k = 0 => c :: %
+ k < 0 => puiseux(-k,monomial(c,-1))
+ puiseux(k,monomial(c,1))
+
+ coerce(ls:ULS) == puiseux(1,ls)
+ coerce(r:Coef) == r :: ULS :: %
+ coerce(i:I) == i :: Coef :: %
+
+ laurentIfCan upxs ==
+ r := getExpon upxs
+-- one? denom r =>
+ (denom r) = 1 =>
+ multiplyExponents(getULS upxs,numer(r) :: PI)
+ "failed"
+
+ laurent upxs ==
+ (uls := laurentIfCan upxs) case "failed" =>
+ error "laurent: Puiseux series has fractional powers"
+ uls :: ULS
+
+ multExp: (RN,LTerm) -> PTerm
+ multExp(r,lTerm) == [r * lTerm.k,lTerm.c]
+
+ terms upxs == map(multExp(getExpon upxs,#1),terms getULS upxs)$ST2LP
+
+ clearDen: (I,PTerm) -> LTerm
+ clearDen(n,lTerm) ==
+ (int := retractIfCan(n * lTerm.k)@Union(I,"failed")) case "failed" =>
+ error "series: inappropriate denominator"
+ [int :: I,lTerm.c]
+
+ series(n,stream) ==
+ str := map(clearDen(n,#1),stream)$ST2PL
+ puiseux(1/n,series str)
+
+--% normalizations
+
+ rewrite:(%,PI) -> %
+ rewrite(upxs,m) ==
+ -- rewrites a series in x**r as a series in x**(r/m)
+ puiseux((getExpon upxs)*(1/m),multiplyExponents(getULS upxs,m))
+
+ ratGcd: (RN,RN) -> RN
+ ratGcd(r1,r2) ==
+ -- if r1 = prod(p prime,p ** ep(r1)) and
+ -- if r2 = prod(p prime,p ** ep(r2)), then
+ -- ratGcd(r1,r2) = prod(p prime,p ** min(ep(r1),ep(r2)))
+ gcd(numer r1,numer r2) / lcm(denom r1,denom r2)
+
+ withNewExpon:(%,RN) -> %
+ withNewExpon(upxs,r) ==
+ rewrite(upxs,numer(getExpon(upxs)/r) pretend PI)
+
+--% predicates
+
+ upxs1 = upxs2 ==
+ r1 := getExpon upxs1; r2 := getExpon upxs2
+ ls1 := getULS upxs1; ls2 := getULS upxs2
+ (r1 = r2) => (ls1 = ls2)
+ r := ratGcd(r1,r2)
+ m1 := numer(getExpon(upxs1)/r) pretend PI
+ m2 := numer(getExpon(upxs2)/r) pretend PI
+ multiplyExponents(ls1,m1) = multiplyExponents(ls2,m2)
+
+ pole? upxs == pole? getULS upxs
+
+--% arithmetic
+
+ applyFcn:((ULS,ULS) -> ULS,%,%) -> %
+ applyFcn(op,pxs1,pxs2) ==
+ r1 := getExpon pxs1; r2 := getExpon pxs2
+ ls1 := getULS pxs1; ls2 := getULS pxs2
+ (r1 = r2) => puiseux(r1,op(ls1,ls2))
+ r := ratGcd(r1,r2)
+ m1 := numer(getExpon(pxs1)/r) pretend PI
+ m2 := numer(getExpon(pxs2)/r) pretend PI
+ puiseux(r,op(multiplyExponents(ls1,m1),multiplyExponents(ls2,m2)))
+
+ pxs1 + pxs2 == applyFcn(#1 +$ULS #2,pxs1,pxs2)
+ pxs1 - pxs2 == applyFcn(#1 -$ULS #2,pxs1,pxs2)
+ pxs1:% * pxs2:% == applyFcn(#1 *$ULS #2,pxs1,pxs2)
+
+ pxs:% ** n:NNI == puiseux(getExpon pxs,getULS(pxs)**n)
+
+ recip pxs ==
+ rec := recip getULS pxs
+ rec case "failed" => "failed"
+ puiseux(getExpon pxs,rec :: ULS)
+
+ RATALG : Boolean := Coef has Algebra(Fraction Integer)
+
+ elt(upxs1:%,upxs2:%) ==
+ uls1 := laurentRep upxs1; uls2 := laurentRep upxs2
+ r1 := rationalPower upxs1; r2 := rationalPower upxs2
+ (n := retractIfCan(r1)@Union(Integer,"failed")) case Integer =>
+ puiseux(r2,uls1(uls2 ** r1))
+ RATALG =>
+ if zero? (coef := coefficient(uls2,deg := degree uls2)) then
+ deg := order(uls2,deg + 1000)
+ zero? (coef := coefficient(uls2,deg)) =>
+ error "elt: series with many leading zero coefficients"
+ -- a fractional power of a Laurent series may not be defined:
+ -- if f(x) = c * x**n + ..., then f(x) ** (p/q) will be defined
+ -- only if q divides n
+ b := lcm(denom r1,deg); c := b quo deg
+ mon : ULS := monomial(1,c)
+ uls2 := elt(uls2,mon) ** r1
+ puiseux(r2*(1/c),elt(uls1,uls2))
+ error "elt: rational powers not available for this coefficient domain"
+
+ if Coef has "**": (Coef,Integer) -> Coef and
+ Coef has "**": (Coef, RN) -> Coef then
+ eval(upxs:%,a:Coef) == eval(getULS upxs,a ** getExpon(upxs))
+
+ if Coef has Field then
+
+ pxs1:% / pxs2:% == applyFcn(#1 /$ULS #2,pxs1,pxs2)
+
+ inv upxs ==
+ (invUpxs := recip upxs) case "failed" =>
+ error "inv: multiplicative inverse does not exist"
+ invUpxs :: %
+
+--% values
+
+ variable upxs == variable getULS upxs
+ center upxs == center getULS upxs
+
+ coefficient(upxs,rn) ==
+-- one? denom(n := rn / getExpon upxs) =>
+ (denom(n := rn / getExpon upxs)) = 1 =>
+ coefficient(getULS upxs,numer n)
+ 0
+
+ elt(upxs:%,rn:RN) == coefficient(upxs,rn)
+
+--% other functions
+
+ roundDown: RN -> I
+ roundDown rn ==
+ -- returns the largest integer <= rn
+ (den := denom rn) = 1 => numer rn
+ n := (num := numer rn) quo den
+ positive?(num) => n
+ n - 1
+
+ roundUp: RN -> I
+ roundUp rn ==
+ -- returns the smallest integer >= rn
+ (den := denom rn) = 1 => numer rn
+ n := (num := numer rn) quo den
+ positive?(num) => n + 1
+ n
+
+ order upxs == getExpon upxs * order getULS upxs
+ order(upxs,r) ==
+ e := getExpon upxs
+ ord := order(getULS upxs, n := roundDown(r / e))
+ ord = n => r
+ ord * e
+
+ truncate(upxs,r) ==
+ e := getExpon upxs
+ puiseux(e,truncate(getULS upxs,roundDown(r / e)))
+
+ truncate(upxs,r1,r2) ==
+ e := getExpon upxs
+ puiseux(e,truncate(getULS upxs,roundUp(r1 / e),roundDown(r2 / e)))
+
+ complete upxs == puiseux(getExpon upxs,complete getULS upxs)
+ extend(upxs,r) ==
+ e := getExpon upxs
+ puiseux(e,extend(getULS upxs,roundDown(r / e)))
+
+ map(fcn,upxs) == puiseux(getExpon upxs,map(fcn,getULS upxs))
+
+ characteristic() == characteristic()$Coef
+
+ -- multiplyCoefficients(f,upxs) ==
+ -- r := getExpon upxs
+ -- puiseux(r,multiplyCoefficients(f(#1 * r),getULS upxs))
+
+ multiplyExponents(upxs:%,n:RN) ==
+ puiseux(n * getExpon(upxs),getULS upxs)
+ multiplyExponents(upxs:%,n:PI) ==
+ puiseux(n * getExpon(upxs),getULS upxs)
+
+ if Coef has "*": (Fraction Integer, Coef) -> Coef then
+
+ differentiate upxs ==
+ r := getExpon upxs
+ puiseux(r,differentiate getULS upxs) * monomial(r :: Coef,r-1)
+
+ if Coef has PartialDifferentialRing(Symbol) then
+
+ differentiate(upxs:%,s:Symbol) ==
+ (s = variable(upxs)) => differentiate upxs
+ dcds := differentiate(center upxs,s)
+ map(differentiate(#1,s),upxs) - dcds*differentiate(upxs)
+
+ if Coef has Algebra Fraction Integer then
+
+ coerce(r:RN) == r :: Coef :: %
+
+ ratInv: RN -> Coef
+ ratInv r ==
+ zero? r => 1
+ inv(r) :: Coef
+
+ integrate upxs ==
+ not zero? coefficient(upxs,-1) =>
+ error "integrate: series has term of order -1"
+ r := getExpon upxs
+ uls := getULS upxs
+ uls := multiplyCoefficients(ratInv(#1 * r + 1),uls)
+ monomial(1,1) * puiseux(r,uls)
+
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+
+ integrate(upxs:%,s:Symbol) ==
+ (s = variable(upxs)) => integrate upxs
+ not entry?(s,variables center upxs) => map(integrate(#1,s),upxs)
+ error "integrate: center is a function of variable of integration"
+
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+
+ integrateWithOneAnswer: (Coef,Symbol) -> Coef
+ integrateWithOneAnswer(f,s) ==
+ res := integrate(f,s)$FunctionSpaceIntegration(I,Coef)
+ res case Coef => res :: Coef
+ first(res :: List Coef)
+
+ integrate(upxs:%,s:Symbol) ==
+ (s = variable(upxs)) => integrate upxs
+ not entry?(s,variables center upxs) =>
+ map(integrateWithOneAnswer(#1,s),upxs)
+ error "integrate: center is a function of variable of integration"
+
+ if Coef has Field then
+ (upxs:%) ** (q:RN) ==
+ num := numer q; den := denom q
+-- one? den => upxs ** num
+ den = 1 => upxs ** num
+ r := rationalPower upxs; uls := laurentRep upxs
+ deg := degree uls
+ if zero?(coef := coefficient(uls,deg)) then
+ deg := order(uls,deg + 1000)
+ zero?(coef := coefficient(uls,deg)) =>
+ error "power of series with many leading zero coefficients"
+ ulsPow := (uls * monomial(1,-deg)$ULS) ** q
+ puiseux(r,ulsPow) * monomial(1,deg*q*r)
+
+ applyUnary: (ULS -> ULS,%) -> %
+ applyUnary(fcn,upxs) ==
+ puiseux(rationalPower upxs,fcn laurentRep upxs)
+
+ exp upxs == applyUnary(exp,upxs)
+ log upxs == applyUnary(log,upxs)
+ sin upxs == applyUnary(sin,upxs)
+ cos upxs == applyUnary(cos,upxs)
+ tan upxs == applyUnary(tan,upxs)
+ cot upxs == applyUnary(cot,upxs)
+ sec upxs == applyUnary(sec,upxs)
+ csc upxs == applyUnary(csc,upxs)
+ asin upxs == applyUnary(asin,upxs)
+ acos upxs == applyUnary(acos,upxs)
+ atan upxs == applyUnary(atan,upxs)
+ acot upxs == applyUnary(acot,upxs)
+ asec upxs == applyUnary(asec,upxs)
+ acsc upxs == applyUnary(acsc,upxs)
+ sinh upxs == applyUnary(sinh,upxs)
+ cosh upxs == applyUnary(cosh,upxs)
+ tanh upxs == applyUnary(tanh,upxs)
+ coth upxs == applyUnary(coth,upxs)
+ sech upxs == applyUnary(sech,upxs)
+ csch upxs == applyUnary(csch,upxs)
+ asinh upxs == applyUnary(asinh,upxs)
+ acosh upxs == applyUnary(acosh,upxs)
+ atanh upxs == applyUnary(atanh,upxs)
+ acoth upxs == applyUnary(acoth,upxs)
+ asech upxs == applyUnary(asech,upxs)
+ acsch upxs == applyUnary(acsch,upxs)
+
+@
+\section{domain UPXS UnivariatePuiseuxSeries}
+<<domain UPXS UnivariatePuiseuxSeries>>=
+)abbrev domain UPXS UnivariatePuiseuxSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 28 January 1990
+++ Date Last Updated: 21 September 1993
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: series, Puiseux
+++ Examples:
+++ References:
+++ Description: Dense Puiseux series in one variable
+++ \spadtype{UnivariatePuiseuxSeries} is a domain representing Puiseux
+++ series in one variable with coefficients in an arbitrary ring. The
+++ parameters of the type specify the coefficient ring, the power series
+++ variable, and the center of the power series expansion. For example,
+++ \spad{UnivariatePuiseuxSeries(Integer,x,3)} represents Puiseux series in
+++ \spad{(x - 3)} with \spadtype{Integer} coefficients.
+UnivariatePuiseuxSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ RN ==> Fraction Integer
+ ST ==> Stream Coef
+ UTS ==> UnivariateTaylorSeries(Coef,var,cen)
+ ULS ==> UnivariateLaurentSeries(Coef,var,cen)
+
+ Exports ==> Join(UnivariatePuiseuxSeriesConstructorCategory(Coef,ULS),_
+ RetractableTo UTS) with
+ coerce: Variable(var) -> %
+ ++ coerce(var) converts the series variable \spad{var} into a
+ ++ Puiseux series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} returns the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> UnivariatePuiseuxSeriesConstructor(Coef,ULS) add
+
+ Rep := Record(expon:RN,lSeries:ULS)
+
+ getExpon: % -> RN
+ getExpon pxs == pxs.expon
+
+ variable upxs == var
+ center upxs == cen
+
+ coerce(uts:UTS) == uts :: ULS :: %
+
+ retractIfCan(upxs:%):Union(UTS,"failed") ==
+ (ulsIfCan := retractIfCan(upxs)@Union(ULS,"failed")) case "failed" =>
+ "failed"
+ retractIfCan(ulsIfCan :: ULS)
+
+ --retract(upxs:%):UTS ==
+ --(ulsIfCan := retractIfCan(upxs)@Union(ULS,"failed")) case "failed" =>
+ --error "retractIfCan: series has fractional exponents"
+ --utsIfCan := retractIfCan(ulsIfCan :: ULS)@Union(UTS,"failed")
+ --utsIfCan case "failed" =>
+ --error "retractIfCan: series has negative exponents"
+ --utsIfCan :: UTS
+
+ coerce(v:Variable(var)) ==
+ zero? cen => monomial(1,1)
+ monomial(1,1) + monomial(cen,0)
+
+ if Coef has "*": (Fraction Integer, Coef) -> Coef then
+ differentiate(upxs:%,v:Variable(var)) == differentiate upxs
+
+ if Coef has Algebra Fraction Integer then
+ integrate(upxs:%,v:Variable(var)) == integrate upxs
+
+ if Coef has coerce: Symbol -> Coef then
+ if Coef has "**": (Coef,RN) -> Coef then
+
+ roundDown: RN -> I
+ roundDown rn ==
+ -- returns the largest integer <= rn
+ (den := denom rn) = 1 => numer rn
+ n := (num := numer rn) quo den
+ positive?(num) => n
+ n - 1
+
+ stToCoef: (ST,Coef,NNI,NNI) -> Coef
+ stToCoef(st,term,n,n0) ==
+ (n > n0) or (empty? st) => 0
+ frst(st) * term ** n + stToCoef(rst st,term,n + 1,n0)
+
+ approximateLaurent: (ULS,Coef,I) -> Coef
+ approximateLaurent(x,term,n) ==
+ (m := n - (e := degree x)) < 0 => 0
+ app := stToCoef(coefficients taylorRep x,term,0,m :: NNI)
+ zero? e => app
+ app * term ** (e :: RN)
+
+ approximate(x,r) ==
+ e := rationalPower(x)
+ term := ((variable(x) :: Coef) - center(x)) ** e
+ approximateLaurent(laurentRep x,term,roundDown(r / e))
+
+ termOutput:(RN,Coef,OUT) -> OUT
+ termOutput(k,c,vv) ==
+ -- creates a term c * vv ** k
+ k = 0 => c :: OUT
+ mon :=
+ k = 1 => vv
+ vv ** (k :: OUT)
+ c = 1 => mon
+ c = -1 => -mon
+ (c :: OUT) * mon
+
+ showAll?:() -> Boolean
+ -- check a global Lisp variable
+ showAll?() == true
+
+ termsToOutputForm:(RN,RN,ST,OUT) -> OUT
+ termsToOutputForm(m,rat,uu,xxx) ==
+ l : L OUT := empty()
+ empty? uu => 0 :: OUT
+ n : NNI; count : NNI := _$streamCount$Lisp
+ for n in 0..count while not empty? uu repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput((n :: I) * rat + m,frst uu,xxx),l)
+ uu := rst uu
+ if showAll?() then
+ for n in (count + 1).. while explicitEntries? uu and _
+ not eq?(uu,rst uu) repeat
+ if frst(uu) ^= 0 then
+ l := concat(termOutput((n :: I) * rat + m,frst uu,xxx),l)
+ uu := rst uu
+ l :=
+ explicitlyEmpty? uu => l
+ eq?(uu,rst uu) and frst uu = 0 => l
+ concat(prefix("O" :: OUT,[xxx ** (((n::I) * rat + m) :: OUT)]),l)
+ empty? l => 0 :: OUT
+ reduce("+",reverse_! l)
+
+ coerce(upxs:%):OUT ==
+ rat := getExpon upxs; uls := laurentRep upxs
+ count : I := _$streamCount$Lisp
+ uls := removeZeroes(_$streamCount$Lisp,uls)
+ m : RN := (degree uls) * rat
+ p := coefficients taylorRep uls
+ xxx :=
+ zero? cen => var :: OUT
+ paren(var :: OUT - cen :: OUT)
+ termsToOutputForm(m,rat,p,xxx)
+
+@
+\section{package UPXS2 UnivariatePuiseuxSeriesFunctions2}
+<<package UPXS2 UnivariatePuiseuxSeriesFunctions2>>=
+)abbrev package UPXS2 UnivariatePuiseuxSeriesFunctions2
+++ Mapping package for univariate Puiseux series
+++ Author: Scott C. Morrison
+++ Date Created: 5 April 1991
+++ Date Last Updated: 5 April 1991
+++ Keywords: Puiseux series, map
+++ Examples:
+++ References:
+++ Description:
+++ Mapping package for univariate Puiseux series.
+++ This package allows one to apply a function to the coefficients of
+++ a univariate Puiseux series.
+UnivariatePuiseuxSeriesFunctions2(Coef1,Coef2,var1,var2,cen1,cen2):_
+ Exports == Implementation where
+ Coef1 : Ring
+ Coef2 : Ring
+ var1: Symbol
+ var2: Symbol
+ cen1: Coef1
+ cen2: Coef2
+ UPS1 ==> UnivariatePuiseuxSeries(Coef1, var1, cen1)
+ UPS2 ==> UnivariatePuiseuxSeries(Coef2, var2, cen2)
+ ULSP2 ==> UnivariateLaurentSeriesFunctions2(Coef1, Coef2, var1, var2, cen1, cen2)
+
+ Exports ==> with
+ map: (Coef1 -> Coef2,UPS1) -> UPS2
+ ++ \spad{map(f,g(x))} applies the map f to the coefficients of the
+ ++ Puiseux series \spad{g(x)}.
+
+ Implementation ==> add
+
+ map(f,ups) == puiseux(rationalPower ups, map(f, laurentRep ups)$ULSP2)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category UPXSCCA UnivariatePuiseuxSeriesConstructorCategory>>
+<<domain UPXSCONS UnivariatePuiseuxSeriesConstructor>>
+<<domain UPXS UnivariatePuiseuxSeries>>
+<<package UPXS2 UnivariatePuiseuxSeriesFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/qalgset.spad.pamphlet b/src/algebra/qalgset.spad.pamphlet
new file mode 100644
index 00000000..7f5a0371
--- /dev/null
+++ b/src/algebra/qalgset.spad.pamphlet
@@ -0,0 +1,353 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra qalgset.spad}
+\author{William Sit}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain QALGSET QuasiAlgebraicSet}
+<<domain QALGSET QuasiAlgebraicSet>>=
+)abbrev domain QALGSET QuasiAlgebraicSet
+++ Author: William Sit
+++ Date Created: March 13, 1992
+++ Date Last Updated: June 12, 1992
+++ Basic Operations:
+++ Related Constructors:GroebnerPackage
+++ See Also: QuasiAlgebraicSet2
+++ AMS Classifications:
+++ Keywords: Zariski closed sets, quasi-algebraic sets
+++ References:William Sit, "An Algorithm for Parametric Linear Systems"
+++ J. Sym. Comp., April, 1992
+++ Description:
+++ \spadtype{QuasiAlgebraicSet} constructs a domain representing
+++ quasi-algebraic sets, which
+++ is the intersection of a Zariski
+++ closed set, defined as the common zeros of a given list of
+++ polynomials (the defining polynomials for equations), and a principal
+++ Zariski open set, defined as the complement of the common
+++ zeros of a polynomial f (the defining polynomial for the inequation).
+++ This domain provides simplification of a user-given representation
+++ using groebner basis computations.
+++ There are two simplification routines: the first function
+++ \spadfun{idealSimplify} uses groebner
+++ basis of ideals alone, while the second, \spadfun{simplify} uses both
+++ groebner basis and factorization. The resulting defining equations L
+++ always form a groebner basis, and the resulting defining
+++ inequation f is always reduced. The function \spadfun{simplify} may
+++ be applied several times if desired. A third simplification
+++ routine \spadfun{radicalSimplify} is provided in
+++ \spadtype{QuasiAlgebraicSet2} for comparison study only,
+++ as it is inefficient compared to the other two, as well as is
+++ restricted to only certain coefficient domains. For detail analysis
+++ and a comparison of the three methods, please consult the reference
+++ cited.
+++
+++ A polynomial function q defined on the quasi-algebraic set
+++ is equivalent to its reduced form with respect to L. While
+++ this may be obtained using the usual normal form
+++ algorithm, there is no canonical form for q.
+++
+++ The ordering in groebner basis computation is determined by
+++ the data type of the input polynomials. If it is possible
+++ we suggest to use refinements of total degree orderings.
+QuasiAlgebraicSet(R, Var,Expon,Dpoly) : C == T
+ where
+ R : GcdDomain
+ Expon : OrderedAbelianMonoidSup
+ Var : OrderedSet
+ Dpoly : PolynomialCategory(R,Expon,Var)
+ NNI ==> NonNegativeInteger
+ newExpon ==> Product(NNI,Expon)
+ newPoly ==> PolynomialRing(R,newExpon)
+ Ex ==> OutputForm
+ mrf ==> MultivariateFactorize(Var,Expon,R,Dpoly)
+ Status ==> Union(Boolean,"failed") -- empty or not, or don't know
+
+ C == Join(SetCategory, CoercibleTo OutputForm) with
+ --- should be Object instead of SetCategory, bug in LIST Object ---
+ --- equality is not implemented ---
+ empty: () -> $
+ ++ empty() returns the empty quasi-algebraic set
+ quasiAlgebraicSet: (List Dpoly, Dpoly) -> $
+ ++ quasiAlgebraicSet(pl,q) returns the quasi-algebraic set
+ ++ with defining equations p = 0 for p belonging to the list pl, and
+ ++ defining inequation q ^= 0.
+ status: $ -> Status
+ ++ status(s) returns true if the quasi-algebraic set is empty,
+ ++ false if it is not, and "failed" if not yet known
+ setStatus: ($, Status) -> $
+ ++ setStatus(s,t) returns the same representation for s, but
+ ++ asserts the following: if t is true, then s is empty,
+ ++ if t is false, then s is non-empty, and if t = "failed",
+ ++ then no assertion is made (that is, "don't know").
+ ++ Note: for internal use only, with care.
+ empty? : $ -> Boolean
+ ++ empty?(s) returns
+ ++ true if the quasialgebraic set s has no points,
+ ++ and false otherwise.
+ definingEquations: $ -> List Dpoly
+ ++ definingEquations(s) returns a list of defining polynomials
+ ++ for equations, that is, for the Zariski closed part of s.
+ definingInequation: $ -> Dpoly
+ ++ definingInequation(s) returns a single defining polynomial for the
+ ++ inequation, that is, the Zariski open part of s.
+ idealSimplify:$ -> $
+ ++ idealSimplify(s) returns a different and presumably simpler
+ ++ representation of s with the defining polynomials for the
+ ++ equations
+ ++ forming a groebner basis, and the defining polynomial for the
+ ++ inequation reduced with respect to the basis, using Buchberger's
+ ++ algorithm.
+ if (R has EuclideanDomain) and (R has CharacteristicZero) then
+ simplify:$ -> $
+ ++ simplify(s) returns a different and presumably simpler
+ ++ representation of s with the defining polynomials for the
+ ++ equations
+ ++ forming a groebner basis, and the defining polynomial for the
+ ++ inequation reduced with respect to the basis, using a heuristic
+ ++ algorithm based on factoring.
+ T == add
+ Rep := Record(status:Status,zero:List Dpoly, nzero:Dpoly)
+ x:$
+
+ import GroebnerPackage(R,Expon,Var,Dpoly)
+ import GroebnerPackage(R,newExpon,Var,newPoly)
+ import GroebnerInternalPackage(R,Expon,Var,Dpoly)
+
+ ---- Local Functions ----
+
+ minset : List List Dpoly -> List List Dpoly
+ overset? : (List Dpoly, List List Dpoly) -> Boolean
+ npoly : Dpoly -> newPoly
+ oldpoly : newPoly -> Union(Dpoly,"failed")
+
+
+ if (R has EuclideanDomain) and (R has CharacteristicZero) then
+ factorset (y:Dpoly):List Dpoly ==
+ ground? y => []
+ [j.factor for j in factors factor$mrf y]
+
+ simplify x ==
+ if x.status case "failed" then
+ x:=quasiAlgebraicSet(zro:=groebner x.zero, redPol(x.nzero,zro))
+ (pnzero:=x.nzero)=0 => empty()
+ nzro:=factorset pnzero
+ mset:=minset [factorset p for p in x.zero]
+ mset:=[setDifference(s,nzro) for s in mset]
+ zro:=groebner [*/s for s in mset]
+ member? (1$Dpoly, zro) => empty()
+ [x.status, zro, primitivePart redPol(*/nzro, zro)]
+
+ npoly(f:Dpoly) : newPoly ==
+ zero? f => 0
+ monomial(leadingCoefficient f,makeprod(0,degree f))$newPoly +
+ npoly(reductum f)
+
+ oldpoly(q:newPoly) : Union(Dpoly,"failed") ==
+ q=0$newPoly => 0$Dpoly
+ dq:newExpon:=degree q
+ n:NNI:=selectfirst (dq)
+ n^=0 => "failed"
+ ((g:=oldpoly reductum q) case "failed") => "failed"
+ monomial(leadingCoefficient q,selectsecond dq)$Dpoly + (g::Dpoly)
+
+ coerce x ==
+ x.status = true => "Empty"::Ex
+ bracket [[hconcat(f::Ex, " = 0"::Ex) for f in x.zero ]::Ex,
+ hconcat( x.nzero::Ex, " != 0"::Ex)]
+
+ empty? x ==
+ if x.status case "failed" then x:=idealSimplify x
+ x.status :: Boolean
+
+ empty() == [true::Status, [1$Dpoly], 0$Dpoly]
+ status x == x.status
+ setStatus(x,t) == [t,x.zero,x.nzero]
+ definingEquations x == x.zero
+ definingInequation x == x.nzero
+ quasiAlgebraicSet(z0,n0) == ["failed", z0, n0]
+
+ idealSimplify x ==
+ x.status case Boolean => x
+ z0:= x.zero
+ n0:= x.nzero
+ empty? z0 => [false, z0, n0]
+ member? (1$Dpoly, z0) => empty()
+ tp:newPoly:=(monomial(1,makeprod(1,0$Expon))$newPoly * npoly n0)-1
+ ngb:=groebner concat(tp, [npoly g for g in z0])
+ member? (1$newPoly, ngb) => empty()
+ gb:List Dpoly:=nil
+ while not empty? ngb repeat
+ if ((f:=oldpoly ngb.first) case Dpoly) then gb:=concat(f, gb)
+ ngb:=ngb.rest
+ [false::Status, gb, primitivePart redPol(n0, gb)]
+
+
+ minset lset ==
+ empty? lset => lset
+ [s for s in lset | ^(overset?(s,lset))]
+
+ overset?(p,qlist) ==
+ empty? qlist => false
+ or/[(brace$(Set Dpoly) q) <$(Set Dpoly) (brace$(Set Dpoly) p) for q in qlist]
+
+@
+\section{package QALGSET2 QuasiAlgebraicSet2}
+<<package QALGSET2 QuasiAlgebraicSet2>>=
+)abbrev package QALGSET2 QuasiAlgebraicSet2
+++ Author: William Sit
+++ Date Created: March 13, 1992
+++ Date Last Updated: June 12, 1992
+++ Basic Operations:
+++ Related Constructors:GroebnerPackage, IdealDecompositionPackage,
+++ PolynomialIdeals
+++ See Also: QuasiAlgebraicSet
+++ AMS Classifications:
+++ Keywords: Zariski closed sets, quasi-algebraic sets
+++ References:William Sit, "An Algorithm for Parametric Linear Systems"
+++ J. Sym. Comp., April, 1992
+++ Description:
+++ \spadtype{QuasiAlgebraicSet2} adds a function \spadfun{radicalSimplify}
+++ which uses \spadtype{IdealDecompositionPackage} to simplify
+++ the representation of a quasi-algebraic set. A quasi-algebraic set
+++ is the intersection of a Zariski
+++ closed set, defined as the common zeros of a given list of
+++ polynomials (the defining polynomials for equations), and a principal
+++ Zariski open set, defined as the complement of the common
+++ zeros of a polynomial f (the defining polynomial for the inequation).
+++ Quasi-algebraic sets are implemented in the domain
+++ \spadtype{QuasiAlgebraicSet}, where two simplification routines are
+++ provided:
+++ \spadfun{idealSimplify} and \spadfun{simplify}.
+++ The function
+++ \spadfun{radicalSimplify} is added
+++ for comparison study only. Because the domain
+++ \spadtype{IdealDecompositionPackage} provides facilities for
+++ computing with radical ideals, it is necessary to restrict
+++ the ground ring to the domain \spadtype{Fraction Integer},
+++ and the polynomial ring to be of type
+++ \spadtype{DistributedMultivariatePolynomial}.
+++ The routine \spadfun{radicalSimplify} uses these to compute groebner
+++ basis of radical ideals and
+++ is inefficient and restricted when compared to the
+++ two in \spadtype{QuasiAlgebraicSet}.
+QuasiAlgebraicSet2(vl,nv) : C == T where
+ vl : List Symbol
+ nv : NonNegativeInteger
+ R ==> Integer
+ F ==> Fraction R
+ Var ==> OrderedVariableList vl
+ NNI ==> NonNegativeInteger
+ Expon ==> DirectProduct(nv,NNI)
+ Dpoly ==> DistributedMultivariatePolynomial(vl,F)
+ QALG ==> QuasiAlgebraicSet(F, Var, Expon, Dpoly)
+ newExpon ==> DirectProduct(#newvl, NNI)
+ newPoly ==> DistributedMultivariatePolynomial(newvl,F)
+ newVar ==> OrderedVariableList newvl
+ Status ==> Union(Boolean,"failed") -- empty or not, or don't know
+
+ C == with
+ radicalSimplify:QALG -> QALG
+ ++ radicalSimplify(s) returns a different and presumably simpler
+ ++ representation of s with the defining polynomials for the
+ ++ equations
+ ++ forming a groebner basis, and the defining polynomial for the
+ ++ inequation reduced with respect to the basis, using
+ ++ using groebner basis of radical ideals
+ T == add
+ ---- Local Functions ----
+ ts:=new()$Symbol
+ newvl:=concat(ts, vl)
+ tv:newVar:=(variable ts)::newVar
+ npoly : Dpoly -> newPoly
+ oldpoly : newPoly -> Union(Dpoly,"failed")
+ f : Var -> newPoly
+ g : newVar -> Dpoly
+
+ import PolynomialIdeals(F,newExpon,newVar,newPoly)
+ import GroebnerPackage(F,Expon,Var,Dpoly)
+ import GroebnerPackage(F,newExpon,newVar,newPoly)
+ import IdealDecompositionPackage(newvl,#newvl)
+ import QuasiAlgebraicSet(F, Var, Expon, Dpoly)
+ import PolynomialCategoryLifting(Expon,Var,F,Dpoly,newPoly)
+ import PolynomialCategoryLifting(newExpon,newVar,F,newPoly,Dpoly)
+ f(v:Var):newPoly ==
+ variable((convert v)@Symbol)@Union(newVar,"failed")::newVar
+ ::newPoly
+ g(v:newVar):Dpoly ==
+ v = tv => 0
+ variable((convert v)@Symbol)@Union(Var,"failed")::Var::Dpoly
+
+ npoly(p:Dpoly) : newPoly == map(f #1, #1::newPoly, p)
+
+ oldpoly(q:newPoly) : Union(Dpoly,"failed") ==
+ (x:=mainVariable q) case "failed" => (leadingCoefficient q)::Dpoly
+ (x::newVar = tv) => "failed"
+ map(g #1,#1::Dpoly, q)
+
+ radicalSimplify x ==
+ status(x)$QALG = true => x -- x is empty
+ z0:=definingEquations x
+ n0:=definingInequation x
+ t:newPoly:= coerce(tv)$newPoly
+ tp:newPoly:= t * (npoly n0) - 1$newPoly
+ gen:List newPoly:= concat(tp, [npoly g for g in z0])
+ id:=ideal gen
+ ngb:=generators radical(id)
+ member? (1$newPoly, ngb) => empty()$QALG
+ gb:List Dpoly:=nil
+ while not empty? ngb repeat
+ if ((k:=oldpoly ngb.first) case Dpoly) then gb:=concat(k, gb)
+ ngb:=ngb.rest
+ y:=quasiAlgebraicSet(gb, primitivePart normalForm(n0, gb))
+ setStatus(y,false::Status)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain QALGSET QuasiAlgebraicSet>>
+<<package QALGSET2 QuasiAlgebraicSet2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/quat.spad.pamphlet b/src/algebra/quat.spad.pamphlet
new file mode 100644
index 00000000..98701089
--- /dev/null
+++ b/src/algebra/quat.spad.pamphlet
@@ -0,0 +1,312 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra quat.spad}
+\author{Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category QUATCAT QuaternionCategory}
+<<category QUATCAT QuaternionCategory>>=
+)abbrev category QUATCAT QuaternionCategory
+++ Author: Robert S. Sutor
+++ Date Created: 23 May 1990
+++ Change History:
+++ 10 September 1990
+++ Basic Operations: (Algebra)
+++ abs, conjugate, imagI, imagJ, imagK, norm, quatern, rational,
+++ rational?, real
+++ Related Constructors: Quaternion, QuaternionCategoryFunctions2
+++ Also See: DivisionRing
+++ AMS Classifications: 11R52
+++ Keywords: quaternions, division ring, algebra
+++ Description:
+++ \spadtype{QuaternionCategory} describes the category of quaternions
+++ and implements functions that are not representation specific.
+
+QuaternionCategory(R: CommutativeRing): Category ==
+ Join(Algebra R, FullyRetractableTo R, DifferentialExtension R,
+ FullyEvalableOver R, FullyLinearlyExplicitRingOver R) with
+
+ conjugate: $ -> $
+ ++ conjugate(q) negates the imaginary parts of quaternion \spad{q}.
+ imagI: $ -> R
+ ++ imagI(q) extracts the imaginary i part of quaternion \spad{q}.
+ imagJ: $ -> R
+ ++ imagJ(q) extracts the imaginary j part of quaternion \spad{q}.
+ imagK: $ -> R
+ ++ imagK(q) extracts the imaginary k part of quaternion \spad{q}.
+ norm: $ -> R
+ ++ norm(q) computes the norm of \spad{q} (the sum of the
+ ++ squares of the components).
+ quatern: (R,R,R,R) -> $
+ ++ quatern(r,i,j,k) constructs a quaternion from scalars.
+ real: $ -> R
+ ++ real(q) extracts the real part of quaternion \spad{q}.
+
+ if R has EntireRing then EntireRing
+ if R has OrderedSet then OrderedSet
+ if R has Field then DivisionRing
+ if R has ConvertibleTo InputForm then ConvertibleTo InputForm
+ if R has CharacteristicZero then CharacteristicZero
+ if R has CharacteristicNonZero then CharacteristicNonZero
+ if R has RealNumberSystem then
+ abs : $ -> R
+ ++ abs(q) computes the absolute value of quaternion \spad{q}
+ ++ (sqrt of norm).
+ if R has IntegerNumberSystem then
+ rational? : $ -> Boolean
+ ++ rational?(q) returns {\it true} if all the imaginary
+ ++ parts of \spad{q} are zero and the real part can be
+ ++ converted into a rational number, and {\it false}
+ ++ otherwise.
+ rational : $ -> Fraction Integer
+ ++ rational(q) tries to convert \spad{q} into a
+ ++ rational number. Error: if this is not
+ ++ possible. If \spad{rational?(q)} is true, the
+ ++ conversion will be done and the rational number returned.
+ rationalIfCan: $ -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(q) returns \spad{q} as a rational number,
+ ++ or "failed" if this is not possible.
+ ++ Note: if \spad{rational?(q)} is true, the conversion
+ ++ can be done and the rational number will be returned.
+
+ add
+
+ characteristic() ==
+ characteristic()$R
+ conjugate x ==
+ quatern(real x, - imagI x, - imagJ x, - imagK x)
+ map(fn, x) ==
+ quatern(fn real x, fn imagI x, fn imagJ x, fn imagK x)
+ norm x ==
+ real x * real x + imagI x * imagI x +
+ imagJ x * imagJ x + imagK x * imagK x
+ x = y ==
+ (real x = real y) and (imagI x = imagI y) and
+ (imagJ x = imagJ y) and (imagK x = imagK y)
+ x + y ==
+ quatern(real x + real y, imagI x + imagI y,
+ imagJ x + imagJ y, imagK x + imagK y)
+ x - y ==
+ quatern(real x - real y, imagI x - imagI y,
+ imagJ x - imagJ y, imagK x - imagK y)
+ - x ==
+ quatern(- real x, - imagI x, - imagJ x, - imagK x)
+ r:R * x:$ ==
+ quatern(r * real x, r * imagI x, r * imagJ x, r * imagK x)
+ n:Integer * x:$ ==
+ quatern(n * real x, n * imagI x, n * imagJ x, n * imagK x)
+ differentiate(x:$, d:R -> R) ==
+ quatern(d real x, d imagI x, d imagJ x, d imagK x)
+ coerce(r:R) ==
+ quatern(r,0$R,0$R,0$R)
+ coerce(n:Integer) ==
+ quatern(n :: R,0$R,0$R,0$R)
+ one? x ==
+-- one? real x and zero? imagI x and
+ (real x) = 1 and zero? imagI x and
+ zero? imagJ x and zero? imagK x
+ zero? x ==
+ zero? real x and zero? imagI x and
+ zero? imagJ x and zero? imagK x
+ retract(x):R ==
+ not (zero? imagI x and zero? imagJ x and zero? imagK x) =>
+ error "Cannot retract quaternion."
+ real x
+ retractIfCan(x):Union(R,"failed") ==
+ not (zero? imagI x and zero? imagJ x and zero? imagK x) =>
+ "failed"
+ real x
+
+ coerce(x:$):OutputForm ==
+ part,z : OutputForm
+ y : $
+ zero? x => (0$R) :: OutputForm
+ not zero?(real x) =>
+ y := quatern(0$R,imagI(x),imagJ(x),imagK(x))
+ zero? y => real(x) :: OutputForm
+ (real(x) :: OutputForm) + (y :: OutputForm)
+ -- we know that the real part is 0
+ not zero?(imagI(x)) =>
+ y := quatern(0$R,0$R,imagJ(x),imagK(x))
+ z :=
+ part := "i"::Symbol::OutputForm
+-- one? imagI(x) => part
+ (imagI(x) = 1) => part
+ (imagI(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part and i part are 0
+ not zero?(imagJ(x)) =>
+ y := quatern(0$R,0$R,0$R,imagK(x))
+ z :=
+ part := "j"::Symbol::OutputForm
+-- one? imagJ(x) => part
+ (imagJ(x) = 1) => part
+ (imagJ(x) :: OutputForm) * part
+ zero? y => z
+ z + (y :: OutputForm)
+ -- we know that the real part and i and j parts are 0
+ part := "k"::Symbol::OutputForm
+-- one? imagK(x) => part
+ (imagK(x) = 1) => part
+ (imagK(x) :: OutputForm) * part
+
+ if R has Field then
+ inv x ==
+ norm x = 0 => error "This quaternion is not invertible."
+ (inv norm x) * conjugate x
+
+ if R has ConvertibleTo InputForm then
+ convert(x:$):InputForm ==
+ l : List InputForm := [convert("quatern" :: Symbol),
+ convert(real x)$R, convert(imagI x)$R, convert(imagJ x)$R,
+ convert(imagK x)$R]
+ convert(l)$InputForm
+
+ if R has OrderedSet then
+ x < y ==
+ real x = real y =>
+ imagI x = imagI y =>
+ imagJ x = imagJ y =>
+ imagK x < imagK y
+ imagJ x < imagJ y
+ imagI x < imagI y
+ real x < real y
+
+ if R has RealNumberSystem then
+ abs x == sqrt norm x
+
+ if R has IntegerNumberSystem then
+ rational? x ==
+ (zero? imagI x) and (zero? imagJ x) and (zero? imagK x)
+ rational x ==
+ rational? x => rational real x
+ error "Not a rational number"
+ rationalIfCan x ==
+ rational? x => rational real x
+ "failed"
+
+@
+\section{domain QUAT Quaternion}
+<<domain QUAT Quaternion>>=
+)abbrev domain QUAT Quaternion
+++ Author: Robert S. Sutor
+++ Date Created: 23 May 1990
+++ Change History:
+++ 10 September 1990
+++ Basic Operations: (Algebra)
+++ abs, conjugate, imagI, imagJ, imagK, norm, quatern, rational,
+++ rational?, real
+++ Related Constructors: QuaternionCategoryFunctions2
+++ Also See: QuaternionCategory, DivisionRing
+++ AMS Classifications: 11R52
+++ Keywords: quaternions, division ring, algebra
+++ Description: \spadtype{Quaternion} implements quaternions over a
+++ commutative ring. The main constructor function is \spadfun{quatern}
+++ which takes 4 arguments: the real part, the i imaginary part, the j
+++ imaginary part and the k imaginary part.
+
+Quaternion(R:CommutativeRing): QuaternionCategory(R) == add
+ Rep := Record(r:R,i:R,j:R,k:R)
+
+ 0 == [0,0,0,0]
+ 1 == [1,0,0,0]
+
+ a,b,c,d : R
+ x,y : $
+
+ real x == x.r
+ imagI x == x.i
+ imagJ x == x.j
+ imagK x == x.k
+
+ quatern(a,b,c,d) == [a,b,c,d]
+
+ x * y == [x.r*y.r-x.i*y.i-x.j*y.j-x.k*y.k,
+ x.r*y.i+x.i*y.r+x.j*y.k-x.k*y.j,
+ x.r*y.j+x.j*y.r+x.k*y.i-x.i*y.k,
+ x.r*y.k+x.k*y.r+x.i*y.j-x.j*y.i]
+
+@
+\section{package QUATCT2 QuaternionCategoryFunctions2}
+<<package QUATCT2 QuaternionCategoryFunctions2>>=
+)abbrev package QUATCT2 QuaternionCategoryFunctions2
+++ Author: Robert S. Sutor
+++ Date Created: 23 May 1990
+++ Change History:
+++ 23 May 1990
+++ Basic Operations: map
+++ Related Constructors: QuaternionCategory, Quaternion
+++ Also See:
+++ AMS Classifications: 11R52
+++ Keywords: quaternions, division ring, map
+++ Description:
+++ \spadtype{QuaternionCategoryFunctions2} implements functions between
+++ two quaternion domains. The function \spadfun{map} is used by
+++ the system interpreter to coerce between quaternion types.
+
+QuaternionCategoryFunctions2(QR,R,QS,S) : Exports ==
+ Implementation where
+ R : CommutativeRing
+ S : CommutativeRing
+ QR : QuaternionCategory R
+ QS : QuaternionCategory S
+ Exports == with
+ map: (R -> S, QR) -> QS
+ ++ map(f,u) maps f onto the component parts of the quaternion
+ ++ u.
+ Implementation == add
+ map(fn : R -> S, u : QR): QS ==
+ quatern(fn real u, fn imagI u, fn imagJ u, fn imagK u)$QS
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category QUATCAT QuaternionCategory>>
+<<domain QUAT Quaternion>>
+<<package QUATCT2 QuaternionCategoryFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/radeigen.spad.pamphlet b/src/algebra/radeigen.spad.pamphlet
new file mode 100644
index 00000000..04e006fb
--- /dev/null
+++ b/src/algebra/radeigen.spad.pamphlet
@@ -0,0 +1,235 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra radeigen.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REP RadicalEigenPackage}
+<<package REP RadicalEigenPackage>>=
+)abbrev package REP RadicalEigenPackage
+++ Author: P.Gianni
+++ Date Created: Summer 1987
+++ Date Last Updated: October 1992
+++ Basic Functions:
+++ Related Constructors: EigenPackage, RadicalSolve
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Package for the computation of eigenvalues and eigenvectors.
+++ This package works for matrices with coefficients which are
+++ rational functions over the integers.
+++ (see \spadtype{Fraction Polynomial Integer}).
+++ The eigenvalues and eigenvectors are expressed in terms of radicals.
+RadicalEigenPackage() : C == T
+ where
+ R ==> Integer
+ P ==> Polynomial R
+ F ==> Fraction P
+ RE ==> Expression R
+ SE ==> Symbol()
+ M ==> Matrix(F)
+ MRE ==> Matrix(RE)
+ ST ==> SuchThat(SE,P)
+ NNI ==> NonNegativeInteger
+
+ EigenForm ==> Record(eigval:Union(F,ST),eigmult:NNI,eigvec:List(M))
+ RadicalForm ==> Record(radval:RE,radmult:Integer,radvect:List(MRE))
+
+
+
+ C == with
+ radicalEigenvectors : M -> List(RadicalForm)
+ ++ radicalEigenvectors(m) computes
+ ++ the eigenvalues and the corresponding eigenvectors of the
+ ++ matrix m;
+ ++ when possible, values are expressed in terms of radicals.
+
+ radicalEigenvector : (RE,M) -> List(MRE)
+ ++ radicalEigenvector(c,m) computes the eigenvector(s) of the
+ ++ matrix m corresponding to the eigenvalue c;
+ ++ when possible, values are
+ ++ expressed in terms of radicals.
+
+ radicalEigenvalues : M -> List RE
+ ++ radicalEigenvalues(m) computes the eigenvalues of the matrix m;
+ ++ when possible, the eigenvalues are expressed in terms of radicals.
+
+ eigenMatrix : M -> Union(MRE,"failed")
+ ++ eigenMatrix(m) returns the matrix b
+ ++ such that \spad{b*m*(inverse b)} is diagonal,
+ ++ or "failed" if no such b exists.
+
+ normalise : MRE -> MRE
+ ++ normalise(v) returns the column
+ ++ vector v
+ ++ divided by its euclidean norm;
+ ++ when possible, the vector v is expressed in terms of radicals.
+
+ gramschmidt : List(MRE) -> List(MRE)
+ ++ gramschmidt(lv) converts the list of column vectors lv into
+ ++ a set of orthogonal column vectors
+ ++ of euclidean length 1 using the Gram-Schmidt algorithm.
+
+ orthonormalBasis : M -> List(MRE)
+ ++ orthonormalBasis(m) returns the orthogonal matrix b such that
+ ++ \spad{b*m*(inverse b)} is diagonal.
+ ++ Error: if m is not a symmetric matrix.
+
+ T == add
+ PI ==> PositiveInteger
+ RSP := RadicalSolvePackage R
+ import EigenPackage R
+
+ ---- Local Functions ----
+ evalvect : (M,RE,SE) -> MRE
+ innerprod : (MRE,MRE) -> RE
+
+ ---- eval a vector of F in a radical expression ----
+ evalvect(vect:M,alg:RE,x:SE) : MRE ==
+ n:=nrows vect
+ xx:=kernel(x)$Kernel(RE)
+ w:MRE:=zero(n,1)$MRE
+ for i in 1..n repeat
+ v:=eval(vect(i,1) :: RE,xx,alg)
+ setelt(w,i,1,v)
+ w
+ ---- inner product ----
+ innerprod(v1:MRE,v2:MRE): RE == (((transpose v1)* v2)::MRE)(1,1)
+
+ ---- normalization of a vector ----
+ normalise(v:MRE) : MRE ==
+ normv:RE := sqrt(innerprod(v,v))
+ normv = 0$RE => v
+ (1/normv)*v
+
+ ---- Eigenvalues of the matrix A ----
+ radicalEigenvalues(A:M): List(RE) ==
+ x:SE :=new()$SE
+ pol:= characteristicPolynomial(A,x) :: F
+ radicalRoots(pol,x)$RSP
+
+ ---- Eigenvectors belonging to a given eigenvalue ----
+ ---- expressed in terms of radicals ----
+ radicalEigenvector(alpha:RE,A:M) : List(MRE) ==
+ n:=nrows A
+ B:MRE := zero(n,n)$MRE
+ for i in 1..n repeat
+ for j in 1..n repeat B(i,j):=(A(i,j))::RE
+ B(i,i):= B(i,i) - alpha
+ [v::MRE for v in nullSpace B]
+
+ ---- eigenvectors and eigenvalues ----
+ radicalEigenvectors(A:M) : List(RadicalForm) ==
+ leig:List EigenForm := eigenvectors A
+ n:=nrows A
+ sln:List RadicalForm := empty()
+ veclist: List MRE
+ for eig in leig repeat
+ eig.eigval case F =>
+ veclist := empty()
+ for ll in eig.eigvec repeat
+ m:MRE:=zero(n,1)
+ for i in 1..n repeat m(i,1):=(ll(i,1))::RE
+ veclist:=cons(m,veclist)
+ sln:=cons([(eig.eigval)::F::RE,eig.eigmult,veclist]$RadicalForm,sln)
+ sym := eig.eigval :: ST
+ xx:= lhs sym
+ lval : List RE := radicalRoots((rhs sym) :: F ,xx)$RSP
+ for alg in lval repeat
+ nsl:=[alg,eig.eigmult,
+ [evalvect(ep,alg,xx) for ep in eig.eigvec]]$RadicalForm
+ sln:=cons(nsl,sln)
+ sln
+
+ ---- orthonormalization of a list of vectors ----
+ ---- Grahm - Schmidt process ----
+
+ gramschmidt(lvect:List(MRE)) : List(MRE) ==
+ lvect=[] => []
+ v:=lvect.first
+ n := nrows v
+ RMR:=RectangularMatrix(n:PI,1,RE)
+ orth:List(MRE):=[(normalise v)]
+ for v in lvect.rest repeat
+ pol:=((v:RMR)-(+/[(innerprod(w,v)*w):RMR for w in orth])):MRE
+ orth:=cons(normalise pol,orth)
+ orth
+
+
+ ---- The matrix of eigenvectors ----
+
+ eigenMatrix(A:M) : Union(MRE,"failed") ==
+ lef:List(MRE):=[:eiv.radvect for eiv in radicalEigenvectors(A)]
+ n:=nrows A
+ #lef <n => "failed"
+ d:MRE:=copy(lef.first)
+ for v in lef.rest repeat d:=(horizConcat(d,v))::MRE
+ d
+
+ ---- orthogonal basis for a symmetric matrix ----
+
+ orthonormalBasis(A:M):List(MRE) ==
+ ^symmetric?(A) => error "the matrix is not symmetric"
+ basis:List(MRE):=[]
+ lvec:List(MRE) := []
+ alglist:List(RadicalForm):=radicalEigenvectors(A)
+ n:=nrows A
+ for alterm in alglist repeat
+ if (lvec:=alterm.radvect)=[] then error "sorry "
+ if #(lvec)>1 then
+ lvec:= gramschmidt(lvec)
+ basis:=[:lvec,:basis]
+ else basis:=[normalise(lvec.first),:basis]
+ basis
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REP RadicalEigenPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/radix.spad.pamphlet b/src/algebra/radix.spad.pamphlet
new file mode 100644
index 00000000..d26f7b52
--- /dev/null
+++ b/src/algebra/radix.spad.pamphlet
@@ -0,0 +1,427 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra radix.spad}
+\author{Stephen M. Watt, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain RADIX RadixExpansion}
+<<domain RADIX RadixExpansion>>=
+)abbrev domain RADIX RadixExpansion
+++ Author: Stephen M. Watt
+++ Date Created: October 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations: wholeRadix, fractRadix, wholeRagits, fractRagits
+++ Related Domains: BinaryExpansion, DecimalExpansion, HexadecimalExpansion,
+++ RadixUtilities
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, repeating decimal
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ decimal expansions or more generally as repeating expansions in any base.
+
+RadixExpansion(bb): Exports == Implementation where
+ bb : Integer
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ RN ==> Fraction Integer
+ ST ==> Stream Integer
+ QuoRem ==> Record(quotient: Integer, remainder: Integer)
+
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(rx) converts a radix expansion to a rational number.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(rx) returns the fractional part of a radix expansion.
+ wholeRagits: % -> List Integer
+ ++ wholeRagits(rx) returns the ragits of the integer part
+ ++ of a radix expansion.
+ fractRagits: % -> Stream Integer
+ ++ fractRagits(rx) returns the ragits of the fractional part
+ ++ of a radix expansion.
+ prefixRagits: % -> List Integer
+ ++ prefixRagits(rx) returns the non-cyclic part of the ragits
+ ++ of the fractional part of a radix expansion.
+ ++ For example, if \spad{x = 3/28 = 0.10 714285 714285 ...},
+ ++ then \spad{prefixRagits(x)=[1,0]}.
+ cycleRagits: % -> List Integer
+ ++ cycleRagits(rx) returns the cyclic part of the ragits of the
+ ++ fractional part of a radix expansion.
+ ++ For example, if \spad{x = 3/28 = 0.10 714285 714285 ...},
+ ++ then \spad{cycleRagits(x) = [7,1,4,2,8,5]}.
+ wholeRadix: List Integer -> %
+ ++ wholeRadix(l) creates an integral radix expansion from a list
+ ++ of ragits.
+ ++ For example, \spad{wholeRadix([1,3,4])} will return \spad{134}.
+ fractRadix: (List Integer, List Integer) -> %
+ ++ fractRadix(pre,cyc) creates a fractional radix expansion
+ ++ from a list of prefix ragits and a list of cyclic ragits.
+ ++ For example, \spad{fractRadix([1],[6])} will return \spad{0.16666666...}.
+
+ Implementation ==> add
+ -- The efficiency of arithmetic operations is poor.
+ -- Could use a lazy eval where either rational rep
+ -- or list of ragit rep (the current) or both are kept
+ -- as demanded.
+
+ bb < 2 => error "Radix base must be at least 2"
+ Rep := Record(sgn: Integer, int: List Integer,
+ pfx: List Integer, cyc: List Integer)
+
+ q: RN
+ qr: QuoRem
+ a,b: %
+ n: I
+
+ radixInt: (I, I) -> List I
+ radixFrac: (I, I, I) -> Record(pfx: List I, cyc: List I)
+ checkRagits: List I -> Boolean
+
+ -- Arithmetic operations
+ characteristic() == 0
+ differentiate a == 0
+
+ 0 == [1, nil(), nil(), nil()]
+ 1 == [1, [1], nil(), nil()]
+ - a == (a = 0 => 0; [-a.sgn, a.int, a.pfx, a.cyc])
+ a + b == (a::RN + b::RN)::%
+ a - b == (a::RN - b::RN)@RN::%
+ n * a == (n * a::RN)::%
+ a * b == (a::RN * b::RN)::%
+ a / b == (a::RN / b::RN)::%
+ (i:I) / (j:I) == (i/j)@RN :: %
+ a < b == a::RN < b::RN
+ a = b == a.sgn = b.sgn and a.int = b.int and
+ a.pfx = b.pfx and a.cyc = b.cyc
+ numer a == numer(a::RN)
+ denom a == denom(a::RN)
+
+ -- Algebraic coercions
+ coerce(a):RN == (wholePart a) :: RN + fractionPart a
+ coerce(n):% == n :: RN :: %
+ coerce(q):% ==
+ s := 1; if q < 0 then (s := -1; q := -q)
+ qr := divide(numer q,denom q)
+ whole := radixInt (qr.quotient,bb)
+ fractn := radixFrac(qr.remainder,denom q,bb)
+ cycle := (fractn.cyc = [0] => nil(); fractn.cyc)
+ [s,whole,fractn.pfx,cycle]
+
+ retractIfCan(a):Union(RN,"failed") == a::RN
+ retractIfCan(a):Union(I,"failed") ==
+ empty?(a.pfx) and empty?(a.cyc) => wholePart a
+ "failed"
+
+ -- Exported constructor/destructors
+ ceiling a == ceiling(a::RN)
+ floor a == floor(a::RN)
+
+ wholePart a ==
+ n0 := 0
+ for r in a.int repeat n0 := bb*n0 + r
+ a.sgn*n0
+ fractionPart a ==
+ n0 := 0
+ for r in a.pfx repeat n0 := bb*n0 + r
+ null a.cyc =>
+ a.sgn*n0/bb**((#a.pfx)::NNI)
+ n1 := n0
+ for r in a.cyc repeat n1 := bb*n1 + r
+ n := n1 - n0
+ d := (bb**((#a.cyc)::NNI) - 1) * bb**((#a.pfx)::NNI)
+ a.sgn*n/d
+
+ wholeRagits a == a.int
+ fractRagits a == concat(construct(a.pfx)@ST,repeating a.cyc)
+ prefixRagits a == a.pfx
+ cycleRagits a == a.cyc
+
+ wholeRadix li ==
+ checkRagits li
+ [1, li, nil(), nil()]
+ fractRadix(lpfx, lcyc) ==
+ checkRagits lpfx; checkRagits lcyc
+ [1, nil(), lpfx, lcyc]
+
+ -- Output
+
+ ALPHAS : String := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+ intToExpr(i:I): OUT ==
+ -- computes a digit for bases between 11 and 36
+ i < 10 => i :: OUT
+ elt(ALPHAS,(i-10) + minIndex(ALPHAS)) :: OUT
+
+ exprgroup(le: List OUT): OUT ==
+ empty? le => error "exprgroup needs non-null list"
+ empty? rest le => first le
+ abs bb <= 36 => hconcat le
+ blankSeparate le
+
+ intgroup(li: List I): OUT ==
+ empty? li => error "intgroup needs non-null list"
+ empty? rest li => intToExpr first(li)
+ abs bb <= 10 => hconcat [i :: OUT for i in li]
+ abs bb <= 36 => hconcat [intToExpr(i) for i in li]
+ blankSeparate [i :: OUT for i in li]
+
+ overBar(li: List I): OUT == overbar intgroup li
+
+ coerce(a): OUT ==
+ le : List OUT := nil()
+ if not null a.cyc then le := concat(overBar a.cyc,le)
+ if not null a.pfx then le := concat(intgroup a.pfx,le)
+ if not null le then le := concat("." :: OUT,le)
+ if not null a.int then le := concat(intgroup a.int,le)
+ else le := concat(0 :: OUT,le)
+ rex := exprgroup le
+ if a.sgn < 0 then -rex else rex
+
+ -- Construction utilities
+ checkRagits li ==
+ for i in li repeat if i < 0 or i >= bb then
+ error "Each ragit (digit) must be between 0 and base-1"
+ true
+
+ radixInt(n,bas) ==
+ rits: List I := nil()
+ while abs n ^= 0 repeat
+ qr := divide(n,bas)
+ n := qr.quotient
+ rits := concat(qr.remainder,rits)
+ rits
+
+ radixFrac(num,den,bas) ==
+ -- Rits is the sequence of quotient/remainder pairs
+ -- in calculating the radix expansion of the rational number.
+ -- We wish to find p and c such that
+ -- rits.i are distinct for 0<=i<=p+c-1
+ -- rits.i = rits.(i+p) for i>p
+ -- I.e. p is the length of the non-periodic prefix and c is
+ -- the length of the cycle.
+
+ -- Compute p and c using Floyd's algorithm.
+ -- 1. Find smallest n s.t. rits.n = rits.(2*n)
+ qr := divide(bas * num, den)
+ i : I := 0
+ qr1i := qr2i := qr
+ rits: List QuoRem := [qr]
+ until qr1i = qr2i repeat
+ qr1i := divide(bas * qr1i.remainder,den)
+ qrt := divide(bas * qr2i.remainder,den)
+ qr2i := divide(bas * qrt.remainder,den)
+ rits := concat(qr2i, concat(qrt, rits))
+ i := i + 1
+ rits := reverse_! rits
+ n := i
+ -- 2. Find p = first i such that rits.i = rits.(i+n)
+ ritsi := rits
+ ritsn := rits; for i in 1..n repeat ritsn := rest ritsn
+ i := 0
+ while first(ritsi) ^= first(ritsn) repeat
+ ritsi := rest ritsi
+ ritsn := rest ritsn
+ i := i + 1
+ p := i
+ -- 3. Find c = first i such that rits.p = rits.(p+i)
+ ritsn := rits; for i in 1..n repeat ritsn := rest ritsn
+ rn := first ritsn
+ cfound:= false
+ c : I := 0
+ for i in 1..p while not cfound repeat
+ ritsn := rest ritsn
+ if rn = first(ritsn) then
+ c := i
+ cfound := true
+ if not cfound then c := n
+ -- 4. Now produce the lists of ragits.
+ ritspfx: List I := nil()
+ ritscyc: List I := nil()
+ for i in 1..p repeat
+ ritspfx := concat(first(rits).quotient, ritspfx)
+ rits := rest rits
+ for i in 1..c repeat
+ ritscyc := concat(first(rits).quotient, ritscyc)
+ rits := rest rits
+ [reverse_! ritspfx, reverse_! ritscyc]
+
+@
+\section{domain BINARY BinaryExpansion}
+<<domain BINARY BinaryExpansion>>=
+)abbrev domain BINARY BinaryExpansion
+++ Author: Clifton J. Williamson
+++ Date Created: April 26, 1990
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, binary
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ binary expansions.
+
+BinaryExpansion(): Exports == Implementation where
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(b) converts a binary expansion to a rational number.
+ coerce: % -> RadixExpansion(2)
+ ++ coerce(b) converts a binary expansion to a radix expansion with base 2.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(b) returns the fractional part of a binary expansion.
+ binary: Fraction Integer -> %
+ ++ binary(r) converts a rational number to a binary expansion.
+
+ Implementation ==> RadixExpansion(2) add
+ binary r == r :: %
+ coerce(x:%): RadixExpansion(2) == x pretend RadixExpansion(2)
+
+@
+\section{domain DECIMAL DecimalExpansion}
+<<domain DECIMAL DecimalExpansion>>=
+)abbrev domain DECIMAL DecimalExpansion
+++ Author: Stephen M. Watt
+++ Date Created: October, 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, repeating decimal
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ decimal expansions.
+DecimalExpansion(): Exports == Implementation where
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(d) converts a decimal expansion to a rational number.
+ coerce: % -> RadixExpansion(10)
+ ++ coerce(d) converts a decimal expansion to a radix expansion
+ ++ with base 10.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(d) returns the fractional part of a decimal expansion.
+ decimal: Fraction Integer -> %
+ ++ decimal(r) converts a rational number to a decimal expansion.
+
+ Implementation ==> RadixExpansion(10) add
+ decimal r == r :: %
+ coerce(x:%): RadixExpansion(10) == x pretend RadixExpansion(10)
+
+@
+\section{domain HEXADEC HexadecimalExpansion}
+<<domain HEXADEC HexadecimalExpansion>>=
+)abbrev domain HEXADEC HexadecimalExpansion
+++ Author: Clifton J. Williamson
+++ Date Created: April 26, 1990
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, hexadecimal
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ hexadecimal expansions.
+
+HexadecimalExpansion(): Exports == Implementation where
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(h) converts a hexadecimal expansion to a rational number.
+ coerce: % -> RadixExpansion(16)
+ ++ coerce(h) converts a hexadecimal expansion to a radix expansion
+ ++ with base 16.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(h) returns the fractional part of a hexadecimal expansion.
+ hex: Fraction Integer -> %
+ ++ hex(r) converts a rational number to a hexadecimal expansion.
+
+ Implementation ==> RadixExpansion(16) add
+ hex r == r :: %
+ coerce(x:%): RadixExpansion(16) == x pretend RadixExpansion(16)
+
+@
+\section{package RADUTIL RadixUtilities}
+<<package RADUTIL RadixUtilities>>=
+)abbrev package RADUTIL RadixUtilities
+++ Author: Stephen M. Watt
+++ Date Created: October 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, repeading decimal
+++ Examples:
+++ References:
+++ Description:
+++ This package provides tools for creating radix expansions.
+RadixUtilities: Exports == Implementation where
+ Exports ==> with
+ radix: (Fraction Integer,Integer) -> Any
+ ++ radix(x,b) converts x to a radix expansion in base b.
+ Implementation ==> add
+ radix(q, b) ==
+ coerce(q :: RadixExpansion(b))$AnyFunctions1(RadixExpansion b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain RADIX RadixExpansion>>
+<<domain BINARY BinaryExpansion>>
+<<domain DECIMAL DecimalExpansion>>
+<<domain HEXADEC HexadecimalExpansion>>
+<<package RADUTIL RadixUtilities>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/random.spad.pamphlet b/src/algebra/random.spad.pamphlet
new file mode 100644
index 00000000..9699789c
--- /dev/null
+++ b/src/algebra/random.spad.pamphlet
@@ -0,0 +1,348 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra random.spad}
+\author{Stephen M. Watt, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package RANDSRC RandomNumberSource}
+<<package RANDSRC RandomNumberSource>>=
+)abbrev package RANDSRC RandomNumberSource
+++ Author:S.M.Watt
+++ Date Created: April 87
+++ Date Last Updated:Jan 92, May 1995 (MCD)
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:Random number generators
+--% RandomNumberSource
+++ All random numbers used in the system should originate from
+++ the same generator. This package is intended to be the source.
+--
+-- Possible improvements:
+-- 1) Start where the user left off
+-- 2) Be able to switch between methods in the random number source.
+RandomNumberSource(): with
+ -- If r := randnum() then 0 <= r < size().
+ randnum: () -> Integer
+ ++ randnum() is a random number between 0 and size().
+ -- If r := randnum() then 0 <= r < size().
+ size: () -> Integer
+ ++ size() is the base of the random number generator
+
+ -- If r := randnum n and n <= size() then 0 <= r < n.
+ randnum: Integer -> Integer
+ ++ randnum(n) is a random number between 0 and n.
+ reseed: Integer -> Void
+ ++ reseed(n) restarts the random number generator at n.
+ seed : () -> Integer
+ ++ seed() returns the current seed value.
+
+ == add
+ -- This random number generator passes the spectral test
+ -- with flying colours. [Knuth vol2, 2nd ed, p105]
+ ranbase: Integer := 2**31-1
+ x0: Integer := 1231231231
+ x1: Integer := 3243232987
+
+ randnum() ==
+ t := (271828183 * x1 - 314159269 * x0) rem ranbase
+ if t < 0 then t := t + ranbase
+ x0:= x1
+ x1:= t
+
+ size() == ranbase
+ reseed n ==
+ x0 := n rem ranbase
+ -- x1 := (n quo ranbase) rem ranbase
+ x1 := n quo ranbase
+
+ seed() == x1*ranbase + x0
+
+ -- Compute an integer in 0..n-1.
+ randnum n ==
+ (n * randnum()) quo ranbase
+
+@
+\section{package RDIST RandomDistributions}
+<<package RDIST RandomDistributions>>=
+)abbrev package RDIST RandomDistributions
+++ Description:
+++ This package exports random distributions
+RandomDistributions(S: SetCategory): with
+ uniform: Set S -> (() -> S)
+ ++ uniform(s) \undocumented
+ weighted: List Record(value: S, weight: Integer) -> (()->S)
+ ++ weighted(l) \undocumented
+ rdHack1: (Vector S,Vector Integer,Integer)->(()->S)
+ ++ rdHack1(v,u,n) \undocumented
+ == add
+ import RandomNumberSource()
+
+ weighted lvw ==
+ -- Collapse duplicates, adding weights.
+ t: Table(S, Integer) := table()
+ for r in lvw repeat
+ u := search(r.value,t)
+ w := (u case "failed" => 0; u::Integer)
+ t r.value := w + r.weight
+
+ -- Construct vectors of values and cumulative weights.
+ kl := keys t
+ n := (#kl)::NonNegativeInteger
+ n = 0 => error "Cannot select from empty set"
+ kv: Vector(S) := new(n, kl.0)
+ wv: Vector(Integer) := new(n, 0)
+
+ totwt: Integer := 0
+ for k in kl for i in 1..n repeat
+ kv.i := k
+ totwt:= totwt + t k
+ wv.i := totwt
+
+ -- Function to generate an integer and lookup.
+ rdHack1(kv, wv, totwt)
+
+ rdHack1(kv, wv, totwt) ==
+ w := randnum totwt
+ -- do binary search in wv
+ kv.1
+
+ uniform fset ==
+ l := members fset
+ n := #l
+ l.(randnum(n)+1)
+
+@
+\section{package INTBIT IntegerBits}
+<<package INTBIT IntegerBits>>=
+)abbrev package INTBIT IntegerBits
+----> Bug! Cannot precompute params and return a function which
+----> simpy computes the last call. e.g. ridHack1, below.
+
+--% IntegerBits
+-- Functions related to the binary representation of integers.
+-- These functions directly access the bits in the big integer
+-- representation and so are much facter than using a quotient loop.
+-- SMW Sept 86.
+
+
+++ Description:
+++ This package provides functions to lookup bits in integers
+IntegerBits: with
+ -- bitLength(n) == # of bits to represent abs(n)
+ -- bitCoef (n,i) == coef of 2**i in abs(n)
+ -- bitTruth(n,i) == true if coef of 2**i in abs(n) is 1
+
+ bitLength: Integer -> Integer
+ ++ bitLength(n) returns the number of bits to represent abs(n)
+ bitCoef: (Integer, Integer) -> Integer
+ ++ bitCoef(n,m) returns the coefficient of 2**m in abs(n)
+ bitTruth: (Integer, Integer) -> Boolean
+ ++ bitTruth(n,m) returns true if coefficient of 2**m in abs(n) is 1
+
+ == add
+ bitLength n == INTEGER_-LENGTH(n)$Lisp
+ bitCoef (n,i) == if INTEGER_-BIT(n,i)$Lisp then 1 else 0
+ bitTruth(n,i) == INTEGER_-BIT(n,i)$Lisp
+
+@
+\section{package RIDIST RandomIntegerDistributions}
+<<package RIDIST RandomIntegerDistributions>>=
+)abbrev package RIDIST RandomIntegerDistributions
+++ Description:
+++ This package exports integer distributions
+RandomIntegerDistributions(): with
+ uniform: Segment Integer -> (() -> Integer)
+ ++ uniform(s) \undocumented
+ binomial: (Integer, RationalNumber) -> (() -> Integer)
+ ++ binomial(n,f) \undocumented
+ poisson: RationalNumber -> (() -> Integer)
+ ++ poisson(f) \undocumented
+ geometric: RationalNumber -> (() -> Integer)
+ ++ geometric(f) \undocumented
+
+ ridHack1: (Integer,Integer,Integer,Integer) -> Integer
+ ++ ridHack1(i,j,k,l) \undocumented
+ == add
+ import RandomNumberSource()
+ import IntegerBits()
+
+ -- Compute uniform(a..b) as
+ --
+ -- l + U0 + w*U1 + w**2*U2 +...+ w**(n-1)*U-1 + w**n*M
+ --
+ -- where
+ -- l = min(a,b)
+ -- m = abs(b-a) + 1
+ -- w**n < m < w**(n+1)
+ -- U0,...,Un-1 are uniform on 0..w-1
+ -- M is uniform on 0..(m quo w**n)-1
+
+ uniform aTob ==
+ a := lo aTob; b := hi aTob
+ l := min(a,b); m := abs(a-b) + 1
+
+ w := 2**(bitLength size() quo 2)::NonNegativeInteger
+
+ n := 0
+ mq := m -- m quo w**n
+ while (mqnext := mq quo w) > 0 repeat
+ n := n + 1
+ mq := mqnext
+ ridHack1(mq, n, w, l)
+
+ ridHack1(mq, n, w, l) ==
+ r := randnum mq
+ for i in 1..n repeat r := r*w + randnum w
+ r + l
+
+@
+\section{package RFDIST RandomFloatDistributions}
+<<package RFDIST RandomFloatDistributions>>=
+)abbrev package RFDIST RandomFloatDistributions
+++ Description:
+++ This package exports random floating-point distributions
+RationalNumber==> Fraction Integer
+RandomFloatDistributions(): Cat == Body where
+ NNI ==> NonNegativeInteger
+
+ Cat ==> with
+ uniform01: () -> Float
+ ++ uniform01() \undocumented
+ normal01: () -> Float
+ ++ normal01() \undocumented
+ exponential1:() -> Float
+ ++ exponential1() \undocumented
+ chiSquare1: NNI -> Float
+ ++ chiSquare1(n) \undocumented
+
+ uniform: (Float, Float) -> (() -> Float)
+ ++ uniform(f,g) \undocumented
+ normal: (Float, Float) -> (() -> Float)
+ ++ normal(f,g) \undocumented
+ exponential: (Float) -> (() -> Float)
+ ++ exponential(f) \undocumented
+ chiSquare: (NNI) -> (() -> Float)
+ ++ chiSquare(n) \undocumented
+ Beta: (NNI, NNI) -> (() -> Float)
+ ++ Beta(n,m) \undocumented
+ F: (NNI, NNI) -> (() -> Float)
+ ++ F(n,m) \undocumented
+ t: (NNI) -> (() -> Float)
+ ++ t(n) \undocumented
+
+
+ Body ==> add
+ import RandomNumberSource()
+-- FloatPackage0()
+
+ -- random() generates numbers in 0..rnmax
+ rnmax := (size()$RandomNumberSource() - 1)::Float
+
+ uniform01() ==
+ randnum()::Float/rnmax
+ uniform(a,b) ==
+ a + uniform01()*(b-a)
+
+ exponential1() ==
+ u: Float := 0
+ -- This test should really be u < m where m is
+ -- the minumum acceptible argument to log.
+ while u = 0 repeat u := uniform01()
+ - log u
+ exponential(mean) ==
+ mean*exponential1()
+
+ -- This method is correct but slow.
+ normal01() ==
+ s := 2::Float
+ while s >= 1 repeat
+ v1 := 2 * uniform01() - 1
+ v2 := 2 * uniform01() - 1
+ s := v1**2 + v2**2
+ v1 * sqrt(-2 * log s/s)
+ normal(mean, stdev) ==
+ mean + stdev*normal01()
+
+ chiSquare1 dgfree ==
+ x: Float := 0
+ for i in 1..dgfree quo 2 repeat
+ x := x + 2*exponential1()
+ if odd? dgfree then
+ x := x + normal01()**2
+ x
+ chiSquare dgfree ==
+ chiSquare1 dgfree
+
+ Beta(dgfree1, dgfree2) ==
+ y1 := chiSquare1 dgfree1
+ y2 := chiSquare1 dgfree2
+ y1/(y1 + y2)
+
+ F(dgfree1, dgfree2) ==
+ y1 := chiSquare1 dgfree1
+ y2 := chiSquare1 dgfree2
+ (dgfree2 * y1)/(dgfree1 * y2)
+
+ t dgfree ==
+ n := normal01()
+ d := chiSquare1(dgfree) / (dgfree::Float)
+ n / sqrt d
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package RANDSRC RandomNumberSource>>
+<<package RDIST RandomDistributions>>
+<<package INTBIT IntegerBits>>
+<<package RIDIST RandomIntegerDistributions>>
+<<package RFDIST RandomFloatDistributions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ratfact.spad.pamphlet b/src/algebra/ratfact.spad.pamphlet
new file mode 100644
index 00000000..68a83a3f
--- /dev/null
+++ b/src/algebra/ratfact.spad.pamphlet
@@ -0,0 +1,113 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ratfact.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package RATFACT RationalFactorize}
+<<package RATFACT RationalFactorize>>=
+)abbrev package RATFACT RationalFactorize
+++ Author: P. Gianni
+++ Date created: ??
+++ Date last updated: December 1993
+++ Factorization of extended polynomials with rational coefficients.
+++ This package implements factorization of extended polynomials
+++ whose coefficients are rational numbers. It does this by taking the
+++ lcm of the coefficients of the polynomial and creating a polynomial
+++ with integer coefficients. The algorithm in \spadtype{GaloisGroupFactorizer} is then
+++ used to factor the integer polynomial. The result is normalized
+++ with respect to the original lcm of the denominators.
+++ Keywords: factorization, hensel, rational number
+I ==> Integer
+RN ==> Fraction Integer
+
+RationalFactorize(RP) : public == private where
+ BP ==> SparseUnivariatePolynomial(I)
+ RP : UnivariatePolynomialCategory RN
+
+ public ==> with
+
+ factor : RP -> Factored RP
+ ++ factor(p) factors an extended polynomial p over the rational numbers.
+ factorSquareFree : RP -> Factored RP
+ ++ factorSquareFree(p) factors an extended squareFree
+ ++ polynomial p over the rational numbers.
+
+ private ==> add
+ import GaloisGroupFactorizer (BP)
+ ParFact ==> Record(irr:BP,pow:I)
+ FinalFact ==> Record(contp:I,factors:List(ParFact))
+ URNI ==> UnivariatePolynomialCategoryFunctions2(RN,RP,I,BP)
+ UIRN ==> UnivariatePolynomialCategoryFunctions2(I,BP,RN,RP)
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FFE ==> Record(flg:fUnion, fctr:RP, xpnt:I)
+
+ factor(p:RP) : Factored(RP) ==
+ p = 0 => 0
+ pden: I := lcm([denom c for c in coefficients p])
+ pol : RP := pden*p
+ ipol: BP := map(numer,pol)$URNI
+ ffact: FinalFact := henselFact(ipol,false)
+ makeFR(((ffact.contp)/pden)::RP,
+ [["prime",map(coerce,u.irr)$UIRN,u.pow]$FFE
+ for u in ffact.factors])
+
+ factorSquareFree(p:RP) : Factored(RP) ==
+ p = 0 => 0
+ pden: I := lcm([denom c for c in coefficients p])
+ pol : RP := pden*p
+ ipol: BP := map(numer,pol)$URNI
+ ffact: FinalFact := henselFact(ipol,true)
+ makeFR(((ffact.contp)/pden)::RP,
+ [["prime",map(coerce,u.irr)$UIRN,u.pow]$FFE
+ for u in ffact.factors])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package RATFACT RationalFactorize>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rdeef.spad.pamphlet b/src/algebra/rdeef.spad.pamphlet
new file mode 100644
index 00000000..662c1f27
--- /dev/null
+++ b/src/algebra/rdeef.spad.pamphlet
@@ -0,0 +1,568 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rdeef.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package INTTOOLS IntegrationTools}
+<<package INTTOOLS IntegrationTools>>=
+)abbrev package INTTOOLS IntegrationTools
+++ Tools for the integrator
+++ Author: Manuel Bronstein
+++ Date Created: 25 April 1990
+++ Date Last Updated: 9 June 1993
+++ Keywords: elementary, function, integration.
+IntegrationTools(R:OrderedSet, F:FunctionSpace R): Exp == Impl where
+ K ==> Kernel F
+ SE ==> Symbol
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ IR ==> IntegrationResult F
+ ANS ==> Record(special:F, integrand:F)
+ U ==> Union(ANS, "failed")
+ ALGOP ==> "%alg"
+
+ Exp ==> with
+ varselect: (List K, SE) -> List K
+ ++ varselect([k1,...,kn], x) returns the ki which involve x.
+ kmax : List K -> K
+ ++ kmax([k1,...,kn]) returns the top-level ki for integration.
+ ksec : (K, List K, SE) -> K
+ ++ ksec(k, [k1,...,kn], x) returns the second top-level ki
+ ++ after k involving x.
+ union : (List K, List K) -> List K
+ ++ union(l1, l2) returns set-theoretic union of l1 and l2.
+ vark : (List F, SE) -> List K
+ ++ vark([f1,...,fn],x) returns the set-theoretic union of
+ ++ \spad{(varselect(f1,x),...,varselect(fn,x))}.
+ if R has IntegralDomain then
+ removeConstantTerm: (F, SE) -> F
+ ++ removeConstantTerm(f, x) returns f minus any additive constant
+ ++ with respect to x.
+ if R has GcdDomain and F has ElementaryFunctionCategory then
+ mkPrim: (F, SE) -> F
+ ++ mkPrim(f, x) makes the logs in f which are linear in x
+ ++ primitive with respect to x.
+ if R has ConvertibleTo Pattern Integer and R has PatternMatchable Integer
+ and F has LiouvillianFunctionCategory and F has RetractableTo SE then
+ intPatternMatch: (F, SE, (F, SE) -> IR, (F, SE) -> U) -> IR
+ ++ intPatternMatch(f, x, int, pmint) tries to integrate \spad{f}
+ ++ first by using the integration function \spad{int}, and then
+ ++ by using the pattern match intetgration function \spad{pmint}
+ ++ on any remaining unintegrable part.
+
+ Impl ==> add
+ better?: (K, K) -> Boolean
+
+ union(l1, l2) == setUnion(l1, l2)
+ varselect(l, x) == [k for k in l | member?(x, variables(k::F))]
+ ksec(k, l, x) == kmax setUnion(remove(k, l), vark(argument k, x))
+
+ vark(l, x) ==
+ varselect(reduce("setUnion",[kernels f for f in l],empty()$List(K)), x)
+
+ kmax l ==
+ ans := first l
+ for k in rest l repeat
+ if better?(k, ans) then ans := k
+ ans
+
+-- true if x should be considered before y in the tower
+ better?(x, y) ==
+ height(y) ^= height(x) => height(y) < height(x)
+ has?(operator y, ALGOP) or
+ (is?(y, "exp"::SE) and not is?(x, "exp"::SE)
+ and not has?(operator x, ALGOP))
+
+ if R has IntegralDomain then
+ removeConstantTerm(f, x) ==
+ not freeOf?((den := denom f)::F, x) => f
+ (u := isPlus(num := numer f)) case "failed" =>
+ freeOf?(num::F, x) => 0
+ f
+ ans:P := 0
+ for term in u::List(P) repeat
+ if not freeOf?(term::F, x) then ans := ans + term
+ ans / den
+
+ if R has GcdDomain and F has ElementaryFunctionCategory then
+ psimp : (P, SE) -> Record(coef:Integer, logand:F)
+ cont : (P, List K) -> P
+ logsimp : (F, SE) -> F
+ linearLog?: (K, F, SE) -> Boolean
+
+ logsimp(f, x) ==
+ r1 := psimp(numer f, x)
+ r2 := psimp(denom f, x)
+ g := gcd(r1.coef, r2.coef)
+ g * log(r1.logand ** (r1.coef quo g) / r2.logand ** (r2.coef quo g))
+
+ cont(p, l) ==
+ empty? l => p
+ q := univariate(p, first l)
+ cont(unitNormal(leadingCoefficient q).unit * content q, rest l)
+
+ linearLog?(k, f, x) ==
+ is?(k, "log"::SE) and
+ ((u := retractIfCan(univariate(f,k))@Union(UP,"failed")) case UP)
+-- and one?(degree(u::UP))
+ and (degree(u::UP) = 1)
+ and not member?(x, variables leadingCoefficient(u::UP))
+
+ mkPrim(f, x) ==
+ lg := [k for k in kernels f | linearLog?(k, f, x)]
+ eval(f, lg, [logsimp(first argument k, x) for k in lg])
+
+ psimp(p, x) ==
+ (u := isExpt(p := ((p exquo cont(p, varselect(variables p, x)))::P)))
+ case "failed" => [1, p::F]
+ [u.exponent, u.var::F]
+
+ if R has Join(ConvertibleTo Pattern Integer, PatternMatchable Integer)
+ and F has Join(LiouvillianFunctionCategory, RetractableTo SE) then
+ intPatternMatch(f, x, int, pmint) ==
+ ir := int(f, x)
+ empty?(l := notelem ir) => ir
+ ans := ratpart ir
+ nl:List(Record(integrand:F, intvar:F)) := empty()
+ lg := logpart ir
+ for rec in l repeat
+ u := pmint(rec.integrand, retract(rec.intvar))
+ if u case ANS then
+ rc := u::ANS
+ ans := ans + rc.special
+ if rc.integrand ^= 0 then
+ ir0 := intPatternMatch(rc.integrand, x, int, pmint)
+ ans := ans + ratpart ir0
+ lg := concat(logpart ir0, lg)
+ nl := concat(notelem ir0, nl)
+ else nl := concat(rec, nl)
+ mkAnswer(ans, lg, nl)
+
+@
+\section{package RDEEF ElementaryRischDE}
+<<package RDEEF ElementaryRischDE>>=
+)abbrev package RDEEF ElementaryRischDE
+++ Risch differential equation, elementary case.
+++ Author: Manuel Bronstein
+++ Date Created: 1 February 1988
+++ Date Last Updated: 2 November 1995
+++ Keywords: elementary, function, integration.
+ElementaryRischDE(R, F): Exports == Implementation where
+ R : Join(GcdDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory, AlgebraicallyClosedField,
+ FunctionSpace R)
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ SE ==> Symbol
+ LF ==> List F
+ K ==> Kernel F
+ LK ==> List K
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ GP ==> LaurentPolynomial(F, UP)
+ Data ==> List Record(coeff:Z, argument:P)
+ RRF ==> Record(mainpart:F,limitedlogs:List NL)
+ NL ==> Record(coeff:F,logand:F)
+ U ==> Union(RRF, "failed")
+ UF ==> Union(F, "failed")
+ UUP ==> Union(UP, "failed")
+ UGP ==> Union(GP, "failed")
+ URF ==> Union(RF, "failed")
+ UEX ==> Union(Record(ratpart:F, coeff:F), "failed")
+ PSOL==> Record(ans:F, right:F, sol?:Boolean)
+ FAIL==> error("Function not supported by Risch d.e.")
+ ALGOP ==> "%alg"
+
+ Exports ==> with
+ rischDE: (Z, F, F, SE, (F, LF) -> U, (F, F) -> UEX) -> PSOL
+ ++ rischDE(n, f, g, x, lim, ext) returns \spad{[y, h, b]} such that
+ ++ \spad{dy/dx + n df/dx y = h} and \spad{b := h = g}.
+ ++ The equation \spad{dy/dx + n df/dx y = g} has no solution
+ ++ if \spad{h \~~= g} (y is a partial solution in that case).
+ ++ Notes: lim is a limited integration function, and
+ ++ ext is an extended integration function.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import TranscendentalRischDE(F, UP)
+ import TranscendentalIntegration(F, UP)
+ import PureAlgebraicIntegration(R, F, F)
+ import FunctionSpacePrimitiveElement(R, F)
+ import ElementaryFunctionStructurePackage(R, F)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+ RF2GP: RF -> GP
+ makeData : (F, SE, K) -> Data
+ normal0 : (Z, F, F, SE) -> UF
+ normalise0: (Z, F, F, SE) -> PSOL
+ normalise : (Z, F, F, F, SE, K, (F, LF) -> U, (F, F) -> UEX) -> PSOL
+ rischDEalg: (Z, F, F, F, K, LK, SE, (F, LF) -> U, (F, F) -> UEX) -> PSOL
+ rischDElog: (LK, RF, RF, SE, K, UP->UP,(F,LF)->U,(F,F)->UEX) -> URF
+ rischDEexp: (LK, RF, RF, SE, K, UP->UP,(F,LF)->U,(F,F)->UEX) -> URF
+ polyDElog : (LK, UP, UP,UP,SE,K,UP->UP,(F,LF)->U,(F,F)->UEX) -> UUP
+ polyDEexp : (LK, UP, UP,UP,SE,K,UP->UP,(F,LF)->U,(F,F)->UEX) -> UUP
+ gpolDEexp : (LK, UP, GP,GP,SE,K,UP->UP,(F,LF)->U,(F,F)->UEX) -> UGP
+ boundAt0 : (LK, F, Z, Z, SE, K, (F, LF) -> U) -> Z
+ boundInf : (LK, F, Z, Z, Z, SE, K, (F, LF) -> U) -> Z
+ logdegrad : (LK, F, UP, Z, SE, K,(F,LF)->U, (F,F) -> UEX) -> UUP
+ expdegrad : (LK, F, UP, Z, SE, K,(F,LF)->U, (F,F) -> UEX) -> UUP
+ logdeg : (UP, F, Z, SE, F, (F, LF) -> U, (F, F) -> UEX) -> UUP
+ expdeg : (UP, F, Z, SE, F, (F, LF) -> U, (F, F) -> UEX) -> UUP
+ exppolyint: (UP, (Z, F) -> PSOL) -> UUP
+ RRF2F : RRF -> F
+ logdiff : (List K, List K) -> List K
+
+ tab:AssociationList(F, Data) := table()
+
+ RF2GP f == (numer(f)::GP exquo denom(f)::GP)::GP
+
+ logdiff(twr, bad) ==
+ [u for u in twr | is?(u, "log"::SE) and not member?(u, bad)]
+
+ rischDEalg(n, nfp, f, g, k, l, x, limint, extint) ==
+ symbolIfCan(kx := ksec(k, l, x)) case SE =>
+ (u := palgRDE(nfp, f, g, kx, k, normal0(n, #1, #2, #3))) case "failed"
+ => [0, 0, false]
+ [u::F, g, true]
+ has?(operator kx, ALGOP) =>
+ rec := primitiveElement(kx::F, k::F)
+ y := rootOf(rec.prim)
+ lk:LK := [kx, k]
+ lv:LF := [(rec.pol1) y, (rec.pol2) y]
+ rc := rischDE(n, eval(f, lk, lv), eval(g, lk, lv), x, limint, extint)
+ rc.sol? => [eval(rc.ans, retract(y)@K, rec.primelt), rc.right, true]
+ [0, 0, false]
+ FAIL
+
+-- solve y' + n f'y = g for a rational function y
+ rischDE(n, f, g, x, limitedint, extendedint) ==
+ zero? g => [0, g, true]
+ zero?(nfp := n * differentiate(f, x)) =>
+ (u := limitedint(g, empty())) case "failed" => [0, 0, false]
+ [u.mainpart, g, true]
+ freeOf?(y := g / nfp, x) => [y, g, true]
+ vl := varselect(union(kernels nfp, kernels g), x)
+ symbolIfCan(k := kmax vl) case SE => normalise0(n, f, g, x)
+ is?(k, "log"::SE) or is?(k, "exp"::SE) =>
+ normalise(n, nfp, f, g, x, k, limitedint, extendedint)
+ has?(operator k, ALGOP) =>
+ rischDEalg(n, nfp, f, g, k, vl, x, limitedint, extendedint)
+ FAIL
+
+ normal0(n, f, g, x) ==
+ rec := normalise0(n, f, g, x)
+ rec.sol? => rec.ans
+ "failed"
+
+-- solve y' + n f' y = g
+-- when f' and g are rational functions over a constant field
+ normalise0(n, f, g, x) ==
+ k := kernel(x)@K
+ if (data1 := search(f, tab)) case "failed" then
+ tab.f := data := makeData(f, x, k)
+ else data := data1::Data
+ f' := nfprime := n * differentiate(f, x)
+ p:P := 1
+ for v in data | (m := n * v.coeff) > 0 repeat
+ p := p * v.argument ** (m::N)
+ f' := f' - m * differentiate(v.argument::F, x) / (v.argument::F)
+ rec := baseRDE(univariate(f', k), univariate(p::F * g, k))
+ y := multivariate(rec.ans, k) / p::F
+ rec.nosol => [y, differentiate(y, x) + nfprime * y, false]
+ [y, g, true]
+
+-- make f weakly normalized, and solve y' + n f' y = g
+ normalise(n, nfp, f, g, x, k, limitedint, extendedint) ==
+ if (data1:= search(f, tab)) case "failed" then
+ tab.f := data := makeData(f, x, k)
+ else data := data1::Data
+ p:P := 1
+ for v in data | (m := n * v.coeff) > 0 repeat
+ p := p * v.argument ** (m::N)
+ f := f - v.coeff * log(v.argument::F)
+ nfp := nfp - m * differentiate(v.argument::F, x) / (v.argument::F)
+ newf := univariate(nfp, k)
+ newg := univariate(p::F * g, k)
+ twr := union(logdiff(tower f, empty()), logdiff(tower g, empty()))
+ ans1 :=
+ is?(k, "log"::SE) =>
+ rischDElog(twr, newf, newg, x, k,
+ differentiate(#1, differentiate(#1, x),
+ differentiate(k::F, x)::UP),
+ limitedint, extendedint)
+ is?(k, "exp"::SE) =>
+ rischDEexp(twr, newf, newg, x, k,
+ differentiate(#1, differentiate(#1, x),
+ monomial(differentiate(first argument k, x), 1)),
+ limitedint, extendedint)
+ ans1 case "failed" => [0, 0, false]
+ [multivariate(ans1::RF, k) / p::F, g, true]
+
+-- find the n * log(P) appearing in f, where P is in P, n in Z
+ makeData(f, x, k) ==
+ disasters := empty()$Data
+ fnum := numer f
+ fden := denom f
+ for u in varselect(kernels f, x) | is?(u, "log"::SE) repeat
+ logand := first argument u
+ if zero?(degree univariate(fden, u)) and
+-- one?(degree(num := univariate(fnum, u))) then
+ (degree(num := univariate(fnum, u)) = 1) then
+ cf := (leadingCoefficient num) / fden
+ if (n := retractIfCan(cf)@Union(Z, "failed")) case Z then
+ if degree(numer logand, k) > 0 then
+ disasters := concat([n::Z, numer logand], disasters)
+ if degree(denom logand, k) > 0 then
+ disasters := concat([-(n::Z), denom logand], disasters)
+ disasters
+
+ rischDElog(twr, f, g, x, theta, driv, limint, extint) ==
+ (u := monomRDE(f, g, driv)) case "failed" => "failed"
+ (v := polyDElog(twr, u.a, retract(u.b), retract(u.c), x, theta, driv,
+ limint, extint)) case "failed" => "failed"
+ v::UP / u.t
+
+ rischDEexp(twr, f, g, x, theta, driv, limint, extint) ==
+ (u := monomRDE(f, g, driv)) case "failed" => "failed"
+ (v := gpolDEexp(twr, u.a, RF2GP(u.b), RF2GP(u.c), x, theta, driv,
+ limint, extint)) case "failed" => "failed"
+ convert(v::GP)@RF / u.t::RF
+
+ polyDElog(twr, aa, bb, cc, x, t, driv, limint, extint) ==
+ zero? cc => 0
+ t' := differentiate(t::F, x)
+ zero? bb =>
+ (u := cc exquo aa) case "failed" => "failed"
+ primintfldpoly(u::UP, extint(#1, t'), t')
+ n := degree(cc)::Z - (db := degree(bb)::Z)
+ if ((da := degree(aa)::Z) = db) and (da > 0) then
+ lk0 := tower(f0 :=
+ - (leadingCoefficient bb) / (leadingCoefficient aa))
+ lk1 := logdiff(twr, lk0)
+ (if0 := limint(f0, [first argument u for u in lk1]))
+ case "failed" => error "Risch's theorem violated"
+ (alph := validExponential(lk0, RRF2F(if0::RRF), x)) case F =>
+ return
+ (ans := polyDElog(twr, alph::F * aa,
+ differentiate(alph::F, x) * aa + alph::F * bb,
+ cc, x, t, driv, limint, extint)) case "failed" => "failed"
+ alph::F * ans::UP
+ if (da > db + 1) then n := max(0, degree(cc)::Z - da + 1)
+ if (da = db + 1) then
+ i := limint(- (leadingCoefficient bb) / (leadingCoefficient aa),
+ [first argument t])
+ if not(i case "failed") then
+ r :=
+ null(i.limitedlogs) => 0$F
+ i.limitedlogs.first.coeff
+ if (nn := retractIfCan(r)@Union(Z, "failed")) case Z then
+ n := max(nn::Z, n)
+ (v := polyRDE(aa, bb, cc, n, driv)) case ans =>
+ v.ans.nosol => "failed"
+ v.ans.ans
+ w := v.eq
+ zero?(w.b) =>
+ degree(w.c) > w.m => "failed"
+ (u := primintfldpoly(w.c, extint(#1,t'), t')) case "failed" => "failed"
+ degree(u::UP) > w.m => "failed"
+ w.alpha * u::UP + w.beta
+ (u := logdegrad(twr, retract(w.b), w.c, w.m, x, t, limint, extint))
+ case "failed" => "failed"
+ w.alpha * u::UP + w.beta
+
+ gpolDEexp(twr, a, b, c, x, t, driv, limint, extint) ==
+ zero? c => 0
+ zero? b =>
+ (u := c exquo (a::GP)) case "failed" => "failed"
+ expintfldpoly(u::GP,
+ rischDE(#1, first argument t, #2, x, limint, extint))
+ lb := boundAt0(twr, - coefficient(b, 0) / coefficient(a, 0),
+ nb := order b, nc := order c, x, t, limint)
+ tm := monomial(1, (m := max(0, max(-nb, lb - nc)))::N)$UP
+ (v := polyDEexp(twr,a * tm,lb * differentiate(first argument t, x)
+ * a * tm + retract(b * tm::GP)@UP,
+ retract(c * monomial(1, m - lb))@UP,
+ x, t, driv, limint, extint)) case "failed" => "failed"
+ v::UP::GP * monomial(1, lb)
+
+ polyDEexp(twr, aa, bb, cc, x, t, driv, limint, extint) ==
+ zero? cc => 0
+ zero? bb =>
+ (u := cc exquo aa) case "failed" => "failed"
+ exppolyint(u::UP, rischDE(#1, first argument t, #2, x, limint, extint))
+ n := boundInf(twr,-leadingCoefficient(bb) / (leadingCoefficient aa),
+ degree(aa)::Z, degree(bb)::Z, degree(cc)::Z, x, t, limint)
+ (v := polyRDE(aa, bb, cc, n, driv)) case ans =>
+ v.ans.nosol => "failed"
+ v.ans.ans
+ w := v.eq
+ zero?(w.b) =>
+ degree(w.c) > w.m => "failed"
+ (u := exppolyint(w.c,
+ rischDE(#1, first argument t, #2, x, limint, extint)))
+ case "failed" => "failed"
+ w.alpha * u::UP + w.beta
+ (u := expdegrad(twr, retract(w.b), w.c, w.m, x, t, limint, extint))
+ case "failed" => "failed"
+ w.alpha * u::UP + w.beta
+
+ exppolyint(p, rischdiffeq) ==
+ (u := expintfldpoly(p::GP, rischdiffeq)) case "failed" => "failed"
+ retractIfCan(u::GP)@Union(UP, "failed")
+
+ boundInf(twr, f0, da, db, dc, x, t, limitedint) ==
+ da < db => dc - db
+ da > db => max(0, dc - da)
+ l1 := logdiff(twr, l0 := tower f0)
+ (if0 := limitedint(f0, [first argument u for u in l1]))
+ case "failed" => error "Risch's theorem violated"
+ (alpha := validExponential(concat(t, l0), RRF2F(if0::RRF), x))
+ case F =>
+ al := separate(univariate(alpha::F, t))$GP
+ zero?(al.fracPart) and monomial?(al.polyPart) =>
+ max(0, max(degree(al.polyPart), dc - db))
+ dc - db
+ dc - db
+
+ boundAt0(twr, f0, nb, nc, x, t, limitedint) ==
+ nb ^= 0 => min(0, nc - min(0, nb))
+ l1 := logdiff(twr, l0 := tower f0)
+ (if0 := limitedint(f0, [first argument u for u in l1]))
+ case "failed" => error "Risch's theorem violated"
+ (alpha := validExponential(concat(t, l0), RRF2F(if0::RRF), x))
+ case F =>
+ al := separate(univariate(alpha::F, t))$GP
+ zero?(al.fracPart) and monomial?(al.polyPart) =>
+ min(0, min(degree(al.polyPart), nc))
+ min(0, nc)
+ min(0, nc)
+
+-- case a = 1, deg(B) = 0, B <> 0
+-- cancellation at infinity is possible
+ logdegrad(twr, b, c, n, x, t, limitedint, extint) ==
+ t' := differentiate(t::F, x)
+ lk1 := logdiff(twr, lk0 := tower(f0 := - b))
+ (if0 := limitedint(f0, [first argument u for u in lk1]))
+ case "failed" => error "Risch's theorem violated"
+ (alpha := validExponential(lk0, RRF2F(if0::RRF), x)) case F =>
+ (u1 := primintfldpoly(inv(alpha::F) * c, extint(#1, t'), t'))
+ case "failed" => "failed"
+ degree(u1::UP)::Z > n => "failed"
+ alpha::F * u1::UP
+ logdeg(c, - if0.mainpart -
+ +/[v.coeff * log(v.logand) for v in if0.limitedlogs],
+ n, x, t', limitedint, extint)
+
+-- case a = 1, degree(b) = 0, and (exp integrate b) is not in F
+-- this implies no cancellation at infinity
+ logdeg(c, f, n, x, t', limitedint, extint) ==
+ answr:UP := 0
+ repeat
+ zero? c => return answr
+ (n < 0) or ((m := degree c)::Z > n) => return "failed"
+ u := rischDE(1, f, leadingCoefficient c, x, limitedint, extint)
+ ~u.sol? => return "failed"
+ zero? m => return(answr + u.ans::UP)
+ n := m::Z - 1
+ c := (reductum c) - monomial(m::Z * t' * u.ans, (m - 1)::N)
+ answr := answr + monomial(u.ans, m)
+
+-- case a = 1, deg(B) = 0, B <> 0
+-- cancellation at infinity is possible
+ expdegrad(twr, b, c, n, x, t, limint, extint) ==
+ lk1 := logdiff(twr, lk0 := tower(f0 := - b))
+ (if0 := limint(f0, [first argument u for u in lk1]))
+ case "failed" => error "Risch's theorem violated"
+ intf0 := - if0.mainpart -
+ +/[v.coeff * log(v.logand) for v in if0.limitedlogs]
+ (alpha := validExponential(concat(t, lk0), RRF2F(if0::RRF), x))
+ case F =>
+ al := separate(univariate(alpha::F, t))$GP
+ zero?(al.fracPart) and monomial?(al.polyPart) and
+ (degree(al.polyPart) >= 0) =>
+ (u1 := expintfldpoly(c::GP * recip(al.polyPart)::GP,
+ rischDE(#1, first argument t, #2, x, limint, extint)))
+ case "failed" => "failed"
+ degree(u1::GP) > n => "failed"
+ retractIfCan(al.polyPart * u1::GP)@Union(UP, "failed")
+ expdeg(c, intf0, n, x, first argument t, limint,extint)
+ expdeg(c, intf0, n, x, first argument t, limint, extint)
+
+-- case a = 1, degree(b) = 0, and (exp integrate b) is not a monomial
+-- this implies no cancellation at infinity
+ expdeg(c, f, n, x, eta, limitedint, extint) ==
+ answr:UP := 0
+ repeat
+ zero? c => return answr
+ (n < 0) or ((m := degree c)::Z > n) => return "failed"
+ u := rischDE(1, f + m * eta, leadingCoefficient c, x,limitedint,extint)
+ ~u.sol? => return "failed"
+ zero? m => return(answr + u.ans::UP)
+ n := m::Z - 1
+ c := reductum c
+ answr := answr + monomial(u.ans, m)
+
+ RRF2F rrf ==
+ rrf.mainpart + +/[v.coeff*log(v.logand) for v in rrf.limitedlogs]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux rderf intrf curve curvepkg divisor pfo
+-- intalg intaf efstruc RDEEF intef irexpand integrat
+
+<<package INTTOOLS IntegrationTools>>
+<<package RDEEF ElementaryRischDE>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rderf.spad.pamphlet b/src/algebra/rderf.spad.pamphlet
new file mode 100644
index 00000000..33dcd1dd
--- /dev/null
+++ b/src/algebra/rderf.spad.pamphlet
@@ -0,0 +1,226 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rderf.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package RDETR TranscendentalRischDE}
+<<package RDETR TranscendentalRischDE>>=
+)abbrev package RDETR TranscendentalRischDE
+++ Risch differential equation, transcendental case.
+++ Author: Manuel Bronstein
+++ Date Created: Jan 1988
+++ Date Last Updated: 2 November 1995
+TranscendentalRischDE(F, UP): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Integer)
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ REC ==> Record(a:UP, b:UP, c:UP, t:UP)
+ SPE ==> Record(b:UP, c:UP, m:Z, alpha:UP, beta:UP)
+ PSOL==> Record(ans:UP, nosol:Boolean)
+ ANS ==> Union(ans:PSOL, eq:SPE)
+ PSQ ==> Record(ans:RF, nosol:Boolean)
+
+ Exports ==> with
+ monomRDE: (RF,RF,UP->UP) -> Union(Record(a:UP,b:RF,c:RF,t:UP), "failed")
+ ++ monomRDE(f,g,D) returns \spad{[A, B, C, T]} such that
+ ++ \spad{y' + f y = g} has a solution if and only if \spad{y = Q / T},
+ ++ where Q satisfies \spad{A Q' + B Q = C} and has no normal pole.
+ ++ A and T are polynomials and B and C have no normal poles.
+ ++ D is the derivation to use.
+ baseRDE : (RF, RF) -> PSQ
+ ++ baseRDE(f, g) returns a \spad{[y, b]} such that \spad{y' + fy = g}
+ ++ if \spad{b = true}, y is a partial solution otherwise (no solution
+ ++ in that case).
+ ++ D is the derivation to use.
+ polyRDE : (UP, UP, UP, Z, UP -> UP) -> ANS
+ ++ polyRDE(a, B, C, n, D) returns either:
+ ++ 1. \spad{[Q, b]} such that \spad{degree(Q) <= n} and
+ ++ \spad{a Q'+ B Q = C} if \spad{b = true}, Q is a partial solution
+ ++ otherwise.
+ ++ 2. \spad{[B1, C1, m, \alpha, \beta]} such that any polynomial solution
+ ++ of degree at most n of \spad{A Q' + BQ = C} must be of the form
+ ++ \spad{Q = \alpha H + \beta} where \spad{degree(H) <= m} and
+ ++ H satisfies \spad{H' + B1 H = C1}.
+ ++ D is the derivation to use.
+
+ Implementation ==> add
+ import MonomialExtensionTools(F, UP)
+
+ getBound : (UP, UP, Z) -> Z
+ SPDEnocancel1: (UP, UP, Z, UP -> UP) -> PSOL
+ SPDEnocancel2: (UP, UP, Z, Z, F, UP -> UP) -> ANS
+ SPDE : (UP, UP, UP, Z, UP -> UP) -> Union(SPE, "failed")
+
+-- cancellation at infinity is possible, A is assumed nonzero
+-- needs tagged union because of branch choice problem
+-- always returns a PSOL in the base case (never a SPE)
+ polyRDE(aa, bb, cc, d, derivation) ==
+ n:Z
+ (u := SPDE(aa, bb, cc, d, derivation)) case "failed" => [[0, true]]
+ zero?(u.c) => [[u.beta, false]]
+-- baseCase? := one?(dt := derivation monomial(1, 1))
+ baseCase? := ((dt := derivation monomial(1, 1)) = 1)
+ n := degree(dt)::Z - 1
+ b0? := zero?(u.b)
+ (~b0?) and (baseCase? or degree(u.b) > max(0, n)) =>
+ answ := SPDEnocancel1(u.b, u.c, u.m, derivation)
+ [[u.alpha * answ.ans + u.beta, answ.nosol]]
+ (n > 0) and (b0? or degree(u.b) < n) =>
+ uansw := SPDEnocancel2(u.b,u.c,u.m,n,leadingCoefficient dt,derivation)
+ uansw case ans=> [[u.alpha * uansw.ans.ans + u.beta, uansw.ans.nosol]]
+ [[uansw.eq.b, uansw.eq.c, uansw.eq.m,
+ u.alpha * uansw.eq.alpha, u.alpha * uansw.eq.beta + u.beta]]
+ b0? and baseCase? =>
+ degree(u.c) >= u.m => [[0, true]]
+ [[u.alpha * integrate(u.c) + u.beta, false]]
+ [u::SPE]
+
+-- cancellation at infinity is possible, A is assumed nonzero
+-- if u.b = 0 then u.a = 1 already, but no degree check is done
+-- returns "failed" if a p' + b p = c has no soln of degree at most d,
+-- otherwise [B, C, m, \alpha, \beta] such that any soln p of degree at
+-- most d of a p' + b p = c must be of the form p = \alpha h + \beta,
+-- where h' + B h = C and h has degree at most m
+ SPDE(aa, bb, cc, d, derivation) ==
+ zero? cc => [0, 0, 0, 0, 0]
+ d < 0 => "failed"
+ (u := cc exquo (g := gcd(aa, bb))) case "failed" => "failed"
+ aa := (aa exquo g)::UP
+ bb := (bb exquo g)::UP
+ cc := u::UP
+ (ra := retractIfCan(aa)@Union(F, "failed")) case F =>
+ a1 := inv(ra::F)
+ [a1 * bb, a1 * cc, d, 1, 0]
+ bc := extendedEuclidean(bb, aa, cc)::Record(coef1:UP, coef2:UP)
+ qr := divide(bc.coef1, aa)
+ r := qr.remainder -- z = bc.coef2 + b * qr.quotient
+ (v := SPDE(aa, bb + derivation aa,
+ bc.coef2 + bb * qr.quotient - derivation r,
+ d - degree(aa)::Z, derivation)) case "failed" => "failed"
+ [v.b, v.c, v.m, aa * v.alpha, aa * v.beta + r]
+
+-- solves q' + b q = c with deg(q) <= d
+-- case (B <> 0) and (D = d/dt or degree(B) > max(0, degree(Dt) - 1))
+-- this implies no cancellation at infinity, BQ term dominates
+-- returns [Q, flag] such that Q is a solution if flag is false,
+-- a partial solution otherwise.
+ SPDEnocancel1(bb, cc, d, derivation) ==
+ q:UP := 0
+ db := (degree bb)::Z
+ lb := leadingCoefficient bb
+ while cc ^= 0 repeat
+ d < 0 or (n := (degree cc)::Z - db) < 0 or n > d => return [q, true]
+ r := monomial((leadingCoefficient cc) / lb, n::N)
+ cc := cc - bb * r - derivation r
+ d := n - 1
+ q := q + r
+ [q, false]
+
+-- case (t is a nonlinear monomial) and (B = 0 or degree(B) < degree(Dt) - 1)
+-- this implies no cancellation at infinity, DQ term dominates or degree(Q) = 0
+-- dtm1 = degree(Dt) - 1
+ SPDEnocancel2(bb, cc, d, dtm1, lt, derivation) ==
+ q:UP := 0
+ while cc ^= 0 repeat
+ d < 0 or (n := (degree cc)::Z - dtm1) < 0 or n > d => return [[q, true]]
+ if n > 0 then
+ r := monomial((leadingCoefficient cc) / (n * lt), n::N)
+ cc := cc - bb * r - derivation r
+ d := n - 1
+ q := q + r
+ else -- n = 0 so solution must have degree 0
+ db:N := (zero? bb => 0; degree bb);
+ db ^= degree(cc) => return [[q, true]]
+ zero? db => return [[bb, cc, 0, 1, q]]
+ r := leadingCoefficient(cc) / leadingCoefficient(bb)
+ cc := cc - r * bb - derivation(r::UP)
+ d := - 1
+ q := q + r::UP
+ [[q, false]]
+
+ monomRDE(f, g, derivation) ==
+ gg := gcd(d := normalDenom(f,derivation), e := normalDenom(g,derivation))
+ tt := (gcd(e, differentiate e) exquo gcd(gg,differentiate gg))::UP
+ (u := ((tt * (aa := d * tt)) exquo e)) case "failed" => "failed"
+ [aa, aa * f - (d * derivation tt)::RF, u::UP * e * g, tt]
+
+-- solve y' + f y = g for y in RF
+-- assumes that f is weakly normalized (no finite cancellation)
+-- base case: F' = 0
+ baseRDE(f, g) ==
+ (u := monomRDE(f, g, differentiate)) case "failed" => [0, true]
+ n := getBound(u.a,bb := retract(u.b)@UP,degree(cc := retract(u.c)@UP)::Z)
+ v := polyRDE(u.a, bb, cc, n, differentiate).ans
+ [v.ans / u.t, v.nosol]
+
+-- return an a bound on the degree of a solution of A P'+ B P = C,A ^= 0
+-- cancellation at infinity is possible
+-- base case: F' = 0
+ getBound(a, b, dc) ==
+ da := (degree a)::Z
+ zero? b => max(0, dc - da + 1)
+ db := (degree b)::Z
+ da > (db + 1) => max(0, dc - da + 1)
+ da < (db + 1) => dc - db
+ (n := retractIfCan(- leadingCoefficient(b) / leadingCoefficient(a)
+ )@Union(Z, "failed")) case Z => max(n::Z, dc - db)
+ dc - db
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- SPAD files for the integration world should be compiled in the
+-- following order:
+--
+-- intaux RDERF intrf rdeef intef irexpand integrat
+
+<<package RDETR TranscendentalRischDE>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rdesys.spad.pamphlet b/src/algebra/rdesys.spad.pamphlet
new file mode 100644
index 00000000..b2eabefd
--- /dev/null
+++ b/src/algebra/rdesys.spad.pamphlet
@@ -0,0 +1,362 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rdesys.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package RDETRS TranscendentalRischDESystem}
+<<package RDETRS TranscendentalRischDESystem>>=
+)abbrev package RDETRS TranscendentalRischDESystem
+++ Risch differential equation system, transcendental case.
+++ Author: Manuel Bronstein
+++ Date Created: 17 August 1992
+++ Date Last Updated: 3 February 1994
+TranscendentalRischDESystem(F, UP): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Integer)
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ V ==> Vector UP
+ U ==> Union(List UP, "failed")
+ REC ==> Record(z1:UP, z2:UP, r1:UP, r2:UP)
+
+ Exports ==> with
+ monomRDEsys: (RF, RF, RF, UP -> UP) -> _
+ Union(Record(a:UP, b:RF, h:UP, c1:RF, c2:RF, t:UP),"failed")
+ ++ monomRDEsys(f,g1,g2,D) returns \spad{[A, B, H, C1, C2, T]} such that
+ ++ \spad{(y1', y2') + ((0, -f), (f, 0)) (y1,y2) = (g1,g2)} has a solution
+ ++ if and only if \spad{y1 = Q1 / T, y2 = Q2 / T},
+ ++ where \spad{B,C1,C2,Q1,Q2} have no normal poles and satisfy
+ ++ A \spad{(Q1', Q2') + ((H, -B), (B, H)) (Q1,Q2) = (C1,C2)}
+ ++ D is the derivation to use.
+ baseRDEsys: (RF, RF, RF) -> Union(List RF, "failed")
+ ++ baseRDEsys(f, g1, g2) returns fractions \spad{y_1.y_2} such that
+ ++ \spad{(y1', y2') + ((0, -f), (f, 0)) (y1,y2) = (g1,g2)}
+ ++ if \spad{y_1,y_2} exist, "failed" otherwise.
+
+ Implementation ==> add
+ import MonomialExtensionTools(F, UP)
+ import SmithNormalForm(UP, V, V, Matrix UP)
+
+ diophant: (UP, UP, UP, UP, UP) -> Union(REC, "failed")
+ getBound: (UP, UP, UP, UP, UP) -> Z
+ SPDEsys : (UP, UP, UP, UP, UP, Z, UP -> UP, (F, F, F, UP, UP, Z) -> U) -> U
+ DSPDEsys: (F, UP, UP, UP, UP, Z, UP -> UP) -> U
+ DSPDEmix: (UP, UP, F, F, N, Z, F) -> U
+ DSPDEhdom: (UP, UP, F, F, N, Z) -> U
+ DSPDEbdom: (UP, UP, F, F, N, Z) -> U
+ DSPDEsys0: (F, UP, UP, UP, UP, F, F, Z, UP -> UP, (UP,UP,F,F,N) -> U) -> U
+
+-- reduces (y1', y2') + ((0, -f), (f, 0)) (y1,y2) = (g1,g2) to
+-- A (Q1', Q2') + ((H, -B), (B, H)) (Q1,Q2) = (C1,C2), Q1 = y1 T, Q2 = y2 T
+-- where A and H are polynomials, and B,C1,C2,Q1 and Q2 have no normal poles.
+-- assumes that f is weakly normalized (no finite cancellation)
+ monomRDEsys(f, g1, g2, derivation) ==
+ gg := gcd(d := normalDenom(f, derivation),
+ e := lcm(normalDenom(g1,derivation),normalDenom(g2,derivation)))
+ tt := (gcd(e, differentiate e) exquo gcd(gg,differentiate gg))::UP
+ (u := ((tt * (aa := d * tt)) exquo e)) case "failed" => "failed"
+ [aa, tt * d * f, - d * derivation tt, u::UP * e * g1, u::UP * e * g2, tt]
+
+-- solve (y1', y2') + ((0, -f), (f, 0)) (y1,y2) = (g1,g2) for y1,y2 in RF
+-- assumes that f is weakly normalized (no finite cancellation) and nonzero
+-- base case: F' = 0
+ baseRDEsys(f, g1, g2) ==
+ zero? f => error "baseRDEsys: f must be nonzero"
+ zero? g1 and zero? g2 => [0, 0]
+ (u := monomRDEsys(f, g1, g2, differentiate)) case "failed" => "failed"
+ n := getBound(u.a, bb := retract(u.b), u.h,
+ cc1 := retract(u.c1), cc2 := retract(u.c2))
+ (v := SPDEsys(u.a, bb, u.h, cc1, cc2, n, differentiate,
+ DSPDEsys(#1, #2::UP, #3::UP, #4, #5, #6, differentiate)))
+ case "failed" => "failed"
+ l := v::List(UP)
+ [first(l) / u.t, second(l) / u.t]
+
+-- solve
+-- D1 = A Z1 + B R1 - C R2
+-- D2 = A Z2 + C R1 + B R2
+-- i.e. (D1,D2) = ((A, 0, B, -C), (0, A, C, B)) (Z1, Z2, R1, R2)
+-- for R1, R2 with degree(Ri) < degree(A)
+-- assumes (A,B,C) = (1) and A and C are nonzero
+ diophant(a, b, c, d1, d2) ==
+ (u := diophantineSystem(matrix [[a,0,b,-c], [0,a,c,b]],
+ vector [d1,d2]).particular) case "failed" => "failed"
+ v := u::V
+ qr1 := divide(v 3, a)
+ qr2 := divide(v 4, a)
+ [v.1 + b * qr1.quotient - c * qr2.quotient,
+ v.2 + c * qr1.quotient + b * qr2.quotient, qr1.remainder, qr2.remainder]
+
+-- solve
+-- A (Q1', Q2') + ((H, -B), (B, H)) (Q1,Q2) = (C1,C2)
+-- for polynomials Q1 and Q2 with degree <= n
+-- A and B are nonzero
+-- cancellation at infinity is possible
+ SPDEsys(a, b, h, c1, c2, n, derivation, degradation) ==
+ zero? c1 and zero? c2 => [0, 0]
+ n < 0 => "failed"
+ g := gcd(a, gcd(b, h))
+ ((u1 := c1 exquo g) case "failed") or
+ ((u2 := c2 exquo g) case "failed") => "failed"
+ a := (a exquo g)::UP
+ b := (b exquo g)::UP
+ h := (h exquo g)::UP
+ c1 := u1::UP
+ c2 := u2::UP
+ (da := degree a) > 0 =>
+ (u := diophant(a, h, b, c1, c2)) case "failed" => "failed"
+ rec := u::REC
+ v := SPDEsys(a, b, h + derivation a, rec.z1 - derivation(rec.r1),
+ rec.z2 - derivation(rec.r2),n-da::Z,derivation,degradation)
+ v case "failed" => "failed"
+ l := v::List(UP)
+ [a * first(l) + rec.r1, a * second(l) + rec.r2]
+ ra := retract(a)@F
+ ((rb := retractIfCan(b)@Union(F, "failed")) case "failed") or
+ ((rh := retractIfCan(h)@Union(F, "failed")) case "failed") =>
+ DSPDEsys(ra, b, h, c1, c2, n, derivation)
+ degradation(ra, rb::F, rh::F, c1, c2, n)
+
+-- solve
+-- a (Q1', Q2') + ((H, -B), (B, H)) (Q1,Q2) = (C1,C2)
+-- for polynomials Q1 and Q2 with degree <= n
+-- a and B are nonzero, either B or H has positive degree
+-- cancellation at infinity is not possible
+ DSPDEsys(a, b, h, c1, c2, n, derivation) ==
+ bb := degree(b)::Z
+ hh:Z :=
+ zero? h => 0
+ degree(h)::Z
+ lb := leadingCoefficient b
+ lh := leadingCoefficient h
+ bb < hh =>
+ DSPDEsys0(a,b,h,c1,c2,lb,lh,n,derivation,DSPDEhdom(#1,#2,#3,#4,#5,hh))
+ bb > hh =>
+ DSPDEsys0(a,b,h,c1,c2,lb,lh,n,derivation,DSPDEbdom(#1,#2,#3,#4,#5,bb))
+ det := lb * lb + lh * lh
+ DSPDEsys0(a,b,h,c1,c2,lb,lh,n,derivation,DSPDEmix(#1,#2,#3,#4,#5,bb,det))
+
+ DSPDEsys0(a, b, h, c1, c2, lb, lh, n, derivation, getlc) ==
+ ans1 := ans2 := 0::UP
+ repeat
+ zero? c1 and zero? c2 => return [ans1, ans2]
+ n < 0 or (u := getlc(c1,c2,lb,lh,n::N)) case "failed" => return "failed"
+ lq := u::List(UP)
+ q1 := first lq
+ q2 := second lq
+ c1 := c1 - a * derivation(q1) - h * q1 + b * q2
+ c2 := c2 - a * derivation(q2) - b * q1 - h * q2
+ n := n - 1
+ ans1 := ans1 + q1
+ ans2 := ans2 + q2
+
+ DSPDEmix(c1, c2, lb, lh, n, d, det) ==
+ rh1:F :=
+ zero? c1 => 0
+ (d1 := degree(c1)::Z - d) < n => 0
+ d1 > n => return "failed"
+ leadingCoefficient c1
+ rh2:F :=
+ zero? c2 => 0
+ (d2 := degree(c2)::Z - d) < n => 0
+ d2 > n => return "failed"
+ leadingCoefficient c2
+ q1 := (rh1 * lh + rh2 * lb) / det
+ q2 := (rh2 * lh - rh1 * lb) / det
+ [monomial(q1, n), monomial(q2, n)]
+
+
+ DSPDEhdom(c1, c2, lb, lh, n, d) ==
+ q1:UP :=
+ zero? c1 => 0
+ (d1 := degree(c1)::Z - d) < n => 0
+ d1 > n => return "failed"
+ monomial(leadingCoefficient(c1) / lh, n)
+ q2:UP :=
+ zero? c2 => 0
+ (d2 := degree(c2)::Z - d) < n => 0
+ d2 > n => return "failed"
+ monomial(leadingCoefficient(c2) / lh, n)
+ [q1, q2]
+
+ DSPDEbdom(c1, c2, lb, lh, n, d) ==
+ q1:UP :=
+ zero? c2 => 0
+ (d2 := degree(c2)::Z - d) < n => 0
+ d2 > n => return "failed"
+ monomial(leadingCoefficient(c2) / lb, n)
+ q2:UP :=
+ zero? c1 => 0
+ (d1 := degree(c1)::Z - d) < n => 0
+ d1 > n => return "failed"
+ monomial(- leadingCoefficient(c1) / lb, n)
+ [q1, q2]
+
+-- return a common bound on the degrees of a solution of
+-- A (Q1', Q2') + ((H, -B), (B, H)) (Q1,Q2) = (C1,C2), Q1 = y1 T, Q2 = y2 T
+-- cancellation at infinity is possible
+-- a and b are nonzero
+-- base case: F' = 0
+ getBound(a, b, h, c1, c2) ==
+ da := (degree a)::Z
+ dc :=
+ zero? c1 => degree(c2)::Z
+ zero? c2 => degree(c1)::Z
+ max(degree c1, degree c2)::Z
+ hh:Z :=
+ zero? h => 0
+ degree(h)::Z
+ db := max(hh, bb := degree(b)::Z)
+ da < db + 1 => dc - db
+ da > db + 1 => max(0, dc - da + 1)
+ bb >= hh => dc - db
+ (n := retractIfCan(leadingCoefficient(h) / leadingCoefficient(a)
+ )@Union(Z, "failed")) case Z => max(n::Z, dc - db)
+ dc - db
+
+@
+\section{package RDEEFS ElementaryRischDESystem}
+<<package RDEEFS ElementaryRischDESystem>>=
+)abbrev package RDEEFS ElementaryRischDESystem
+++ Risch differential equation, elementary case.
+++ Author: Manuel Bronstein
+++ Date Created: 12 August 1992
+++ Date Last Updated: 17 August 1992
+++ Keywords: elementary, function, integration.
+ElementaryRischDESystem(R, F): Exports == Implementation where
+ R : Join(GcdDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory, AlgebraicallyClosedField,
+ FunctionSpace R)
+
+ Z ==> Integer
+ SE ==> Symbol
+ K ==> Kernel F
+ P ==> SparseMultivariatePolynomial(R, K)
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+ NL ==> Record(coeff:F,logand:F)
+ RRF ==> Record(mainpart:F,limitedlogs:List NL)
+ U ==> Union(RRF, "failed")
+ ULF ==> Union(List F, "failed")
+ UEX ==> Union(Record(ratpart:F, coeff:F), "failed")
+
+ Exports ==> with
+ rischDEsys: (Z, F, F, F, SE, (F, List F) -> U, (F, F) -> UEX) -> ULF
+ ++ rischDEsys(n, f, g_1, g_2, x,lim,ext) returns \spad{y_1.y_2} such that
+ ++ \spad{(dy1/dx,dy2/dx) + ((0, - n df/dx),(n df/dx,0)) (y1,y2) = (g1,g2)}
+ ++ if \spad{y_1,y_2} exist, "failed" otherwise.
+ ++ lim is a limited integration function,
+ ++ ext is an extended integration function.
+
+ Implementation ==> add
+ import IntegrationTools(R, F)
+ import ElementaryRischDE(R, F)
+ import TranscendentalRischDESystem(F, UP)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents K,
+ K, R, P, F)
+
+-- sm1 := sqrt(-1::F)
+-- ks1 := retract(sm1)@K
+
+-- gcoeffs : P -> ULF
+-- gets1coeffs: F -> ULF
+-- cheat : (Z, F, F, F, SE, (F, List F) -> U, (F, F) -> UEX) -> ULF
+ basecase : (F, F, F, K) -> ULF
+
+-- solve (y1',y2') + ((0, -nfp), (nfp, 0)) (y1,y2) = (g1, g2), base case
+ basecase(nfp, g1, g2, k) ==
+ (ans := baseRDEsys(univariate(nfp, k), univariate(g1, k),
+ univariate(g2, k))) case "failed" => "failed"
+ l := ans::List(RF)
+ [multivariate(first l, k), multivariate(second l, k)]
+
+-- returns [x,y] s.t. f = x + y %i
+-- f can be of the form (a + b %i) / (c + d %i)
+-- gets1coeffs f ==
+-- (lnum := gcoeffs(numer f)) case "failed" => "failed"
+-- (lden := gcoeffs(denom f)) case "failed" => "failed"
+-- a := first(lnum::List F)
+-- b := second(lnum::List F)
+-- c := first(lden::List F)
+-- zero?(d := second(lden::List F)) => [a/c, b/c]
+-- cd := c * c + d * d
+-- [(a * c + b * d) / cd, (b * c - a * d) / cd]
+
+-- gcoeffs p ==
+-- degree(q := univariate(p, ks1)) > 1 => "failed"
+-- [coefficient(q, 0)::F, coefficient(q, 1)::F]
+
+-- cheat(n, f, g1, g2, x, limint, extint) ==
+-- (u := rischDE(n, sm1 * f, g1 + sm1 * g2, x, limint, extint))
+-- case "failed" => "failed"
+-- (l := gets1coeffs(u::F)) case "failed" =>
+-- error "rischDEsys: expect linear result in sqrt(-1)"
+-- l::List F
+
+-- solve (y1',y2') + ((0, -n f'), (n f', 0)) (y1,y2) = (g1, g2)
+ rischDEsys(n, f, g1, g2, x, limint, extint) ==
+ zero? g1 and zero? g2 => [0, 0]
+ zero?(nfp := n * differentiate(f, x)) =>
+ ((u1 := limint(g1, empty())) case "failed") or
+ ((u2 := limint(g1, empty())) case "failed") => "failed"
+ [u1.mainpart, u2.mainpart]
+ freeOf?(y1 := g2 / nfp, x) and freeOf?(y2 := - g1 / nfp, x) => [y1, y2]
+ vl := varselect(union(kernels nfp, union(kernels g1, kernels g2)), x)
+ symbolIfCan(k := kmax vl) case SE => basecase(nfp, g1, g2, k)
+-- cheat(n, f, g1, g2, x, limint, extint)
+ error "rischDEsys: can only handle rational functions for now"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package RDETRS TranscendentalRischDESystem>>
+<<package RDEEFS ElementaryRischDESystem>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/real0q.spad.pamphlet b/src/algebra/real0q.spad.pamphlet
new file mode 100644
index 00000000..5a891c92
--- /dev/null
+++ b/src/algebra/real0q.spad.pamphlet
@@ -0,0 +1,129 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra real0q.spad}
+\author{Andy Neff, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REAL0Q RealZeroPackageQ}
+<<package REAL0Q RealZeroPackageQ>>=
+)abbrev package REAL0Q RealZeroPackageQ
+++ Author: Andy Neff, Barry Trager
+++ Date Created:
+++ Date Last Updated: 7 April 1991
+++ Basic Functions:
+++ Related Constructors: UnivariatePolynomial, RealZeroPackageQ
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides functions for finding the real zeros
+++ of univariate polynomials over the rational numbers to arbitrary user-specified
+++ precision. The results are returned as a list of
+++ isolating intervals, expressed as records with "left" and "right" rational number components.
+
+RealZeroPackageQ(Pol): T == C where
+ RN ==> Fraction Integer
+ I ==> Integer
+ SUP ==> SparseUnivariatePolynomial
+ Pol: UnivariatePolynomialCategory RN
+ Interval ==> Record(left : RN, right : RN)
+ isoList ==> List(Interval)
+ ApproxInfo ==> Record(approx : RN, exFlag : Boolean)
+ T == with
+ -- next two functions find isolating intervals
+ realZeros: (Pol) -> isoList
+ ++ realZeros(pol) returns a list of isolating intervals for
+ ++ all the real zeros of the univariate polynomial pol.
+ realZeros: (Pol, Interval) -> isoList
+ ++ realZeros(pol, range) returns a list of isolating intervals
+ ++ for all the real zeros of the univariate polynomial pol which
+ ++ lie in the interval expressed by the record range.
+ -- next two functions return intervals smaller then tolerence
+ realZeros: (Pol, RN) -> isoList
+ ++ realZeros(pol, eps) returns a list of intervals of length less
+ ++ than the rational number eps for all the real roots of the
+ ++ polynomial pol.
+ realZeros: (Pol, Interval, RN) -> isoList
+ ++ realZeros(pol, int, eps) returns a list of intervals of length
+ ++ less than the rational number eps for all the real roots of the
+ ++ polynomial pol which lie in the interval expressed by the
+ ++ record int.
+ refine: (Pol, Interval, RN) -> Interval
+ ++ refine(pol, int, eps) refines the interval int containing
+ ++ exactly one root of the univariate polynomial pol to size less
+ ++ than the rational number eps.
+ refine: (Pol, Interval, Interval) -> Union(Interval,"failed")
+ ++ refine(pol, int, range) takes a univariate polynomial pol and
+ ++ and isolating interval int which must contain exactly one real
+ ++ root of pol, and returns an isolating interval which
+ ++ is contained within range, or "failed" if no such isolating interval exists.
+ C == add
+ import RealZeroPackage SparseUnivariatePolynomial Integer
+
+ convert2PolInt: Pol -> SparseUnivariatePolynomial Integer
+
+ convert2PolInt(f : Pol) ==
+ pden:I :=lcm([denom c for c in coefficients f])
+ map(numer,pden * f)$UnivariatePolynomialCategoryFunctions2(RN,Pol,I,SUP I)
+
+ realZeros(f : Pol) == realZeros(convert2PolInt f)
+ realZeros(f : Pol, rn : RN) == realZeros(convert2PolInt f, rn)
+ realZeros(f : Pol, bounds : Interval) ==
+ realZeros(convert2PolInt f, bounds)
+ realZeros(f : Pol, bounds : Interval, rn : RN) ==
+ realZeros(convert2PolInt f, bounds, rn)
+ refine(f : Pol, int : Interval, eps : RN) ==
+ refine(convert2PolInt f, int, eps)
+ refine(f : Pol, int : Interval, bounds : Interval) ==
+ refine(convert2PolInt f, int, bounds)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REAL0Q RealZeroPackageQ>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/realzero.spad.pamphlet b/src/algebra/realzero.spad.pamphlet
new file mode 100644
index 00000000..27374130
--- /dev/null
+++ b/src/algebra/realzero.spad.pamphlet
@@ -0,0 +1,347 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra realzero.spad}
+\author{Andy Neff}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REAL0 RealZeroPackage}
+<<package REAL0 RealZeroPackage>>=
+)abbrev package REAL0 RealZeroPackage
+++ Author: Andy Neff
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: UnivariatePolynomial, RealZeroPackageQ
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides functions for finding the real zeros
+++ of univariate polynomials over the integers to arbitrary user-specified
+++ precision. The results are returned as a list of
+++ isolating intervals which are expressed as records with "left" and "right" rational number
+++ components.
+
+RealZeroPackage(Pol): T == C where
+ Pol: UnivariatePolynomialCategory Integer
+ RN ==> Fraction Integer
+ Interval ==> Record(left : RN, right : RN)
+ isoList ==> List(Interval)
+ T == with
+ -- next two functions find isolating intervals
+ realZeros: (Pol) -> isoList
+ ++ realZeros(pol) returns a list of isolating intervals for
+ ++ all the real zeros of the univariate polynomial pol.
+ realZeros: (Pol, Interval) -> isoList
+ ++ realZeros(pol, range) returns a list of isolating intervals
+ ++ for all the real zeros of the univariate polynomial pol which
+ ++ lie in the interval expressed by the record range.
+ -- next two functions return intervals smaller then tolerence
+ realZeros: (Pol, RN) -> isoList
+ ++ realZeros(pol, eps) returns a list of intervals of length less
+ ++ than the rational number eps for all the real roots of the
+ ++ polynomial pol.
+ realZeros: (Pol, Interval, RN) -> isoList
+ ++ realZeros(pol, int, eps) returns a list of intervals of length
+ ++ less than the rational number eps for all the real roots of the
+ ++ polynomial pol which lie in the interval expressed by the
+ ++ record int.
+ refine: (Pol, Interval, RN) -> Interval
+ ++ refine(pol, int, eps) refines the interval int containing
+ ++ exactly one root of the univariate polynomial pol to size less
+ ++ than the rational number eps.
+ refine: (Pol, Interval, Interval) -> Union(Interval,"failed")
+ ++ refine(pol, int, range) takes a univariate polynomial pol and
+ ++ and isolating interval int containing exactly one real
+ ++ root of pol; the operation returns an isolating interval which
+ ++ is contained within range, or "failed" if no such isolating interval exists.
+ midpoint: Interval -> RN
+ ++ midpoint(int) returns the midpoint of the interval int.
+ midpoints: isoList -> List RN
+ ++ midpoints(isolist) returns the list of midpoints for the list
+ ++ of intervals isolist.
+ C == add
+ --Local Functions
+ makeSqfr: Pol -> Pol
+ ReZeroSqfr: (Pol) -> isoList
+ PosZero: (Pol) -> isoList
+ Zero1: (Pol) -> isoList
+ transMult: (Integer, Pol) -> Pol
+ transMultInv: (Integer, Pol) -> Pol
+ transAdd1: (Pol) -> Pol
+ invert: (Pol) -> Pol
+ minus: (Pol) -> Pol
+ negate: Interval -> Interval
+ rootBound: (Pol) -> Integer
+ var: (Pol) -> Integer
+
+ negate(int : Interval):Interval == [-int.right,-int.left]
+
+ midpoint(i : Interval):RN == (1/2)*(i.left + i.right)
+
+ midpoints(li : isoList) : List RN ==
+ [midpoint x for x in li]
+
+ makeSqfr(F : Pol):Pol ==
+ sqfr := squareFree F
+ F := */[s.factor for s in factors(sqfr)]
+
+ realZeros(F : Pol) ==
+ ReZeroSqfr makeSqfr F
+
+ realZeros(F : Pol, rn : RN) ==
+ F := makeSqfr F
+ [refine(F,int,rn) for int in ReZeroSqfr(F)]
+
+ realZeros(F : Pol, bounds : Interval) ==
+ F := makeSqfr F
+ [rint::Interval for int in ReZeroSqfr(F) |
+ (rint:=refine(F,int,bounds)) case Interval]
+
+ realZeros(F : Pol, bounds : Interval, rn : RN) ==
+ F := makeSqfr F
+ [refine(F,int,rn) for int in realZeros(F,bounds)]
+
+ ReZeroSqfr(F : Pol) ==
+ F = 0 => error "ReZeroSqfr: zero polynomial"
+ L : isoList := []
+ degree(F) = 0 => L
+ if (r := minimumDegree(F)) > 0 then
+ L := [[0,0]$Interval]
+ tempF := F exquo monomial(1, r)
+ if not (tempF case "failed") then
+ F := tempF
+ J:isoList := [negate int for int in reverse(PosZero(minus(F)))]
+ K : isoList := PosZero(F)
+ append(append(J, L), K)
+
+ PosZero(F : Pol) == --F is square free, primitive
+ --and F(0) ^= 0; returns isoList for positive
+ --roots of F
+
+ b : Integer := rootBound(F)
+ F := transMult(b,F)
+ L : isoList := Zero1(F)
+ int : Interval
+ L := [[b*int.left, b*int.right]$Interval for int in L]
+
+ Zero1(F : Pol) == --returns isoList for roots of F in (0,1)
+ J : isoList
+ K : isoList
+ L : isoList
+ L := []
+ (v := var(transAdd1(invert(F)))) = 0 => []
+ v = 1 => L := [[0,1]$Interval]
+ G : Pol := transMultInv(2, F)
+ H : Pol := transAdd1(G)
+ if minimumDegree H > 0 then
+ -- H has a root at 0 => F has one at 1/2, and G at 1
+ L := [[1/2,1/2]$Interval]
+ Q : Pol := monomial(1, 1)
+ tempH : Union(Pol, "failed") := H exquo Q
+ if not (tempH case "failed") then H := tempH
+ Q := Q + monomial(-1, 0)
+ tempG : Union(Pol, "failed") := G exquo Q
+ if not (tempG case "failed") then G := tempG
+ int : Interval
+ J := [[(int.left+1)* (1/2),(int.right+1) * (1/2)]$Interval
+ for int in Zero1(H)]
+ K := [[int.left * (1/2), int.right * (1/2)]$Interval
+ for int in Zero1(G)]
+ append(append(J, L), K)
+
+ rootBound(F : Pol) == --returns power of 2 that is a bound
+ --for the positive roots of F
+ if leadingCoefficient(F) < 0 then F := -F
+ lcoef := leadingCoefficient(F)
+ F := reductum(F)
+ i : Integer := 0
+ while not (F = 0) repeat
+ if (an := leadingCoefficient(F)) < 0 then i := i - an
+ F := reductum(F)
+ b : Integer := 1
+ while (b * lcoef) <= i repeat
+ b := 2 * b
+ b
+
+ transMult(c : Integer, F : Pol) ==
+ --computes Pol G such that G(x) = F(c*x)
+ G : Pol := 0
+ while not (F = 0) repeat
+ n := degree(F)
+ G := G + monomial((c**n) * leadingCoefficient(F), n)
+ F := reductum(F)
+ G
+
+ transMultInv(c : Integer, F : Pol) ==
+ --computes Pol G such that G(x) = (c**n) * F(x/c)
+ d := degree(F)
+ cc : Integer := 1
+ G : Pol := monomial(leadingCoefficient F,d)
+ while (F:=reductum(F)) ^= 0 repeat
+ n := degree(F)
+ cc := cc*(c**(d-n):NonNegativeInteger)
+ G := G + monomial(cc * leadingCoefficient(F), n)
+ d := n
+ G
+
+-- otransAdd1(F : Pol) ==
+-- --computes Pol G such that G(x) = F(x+1)
+-- G : Pol := F
+-- n : Integer := 1
+-- while (F := differentiate(F)) ^= 0 repeat
+-- if not ((tempF := F exquo n) case "failed") then F := tempF
+-- G := G + F
+-- n := n + 1
+-- G
+
+ transAdd1(F : Pol) ==
+ --computes Pol G such that G(x) = F(x+1)
+ n := degree F
+ v := vectorise(F, n+1)
+ for i in 0..(n-1) repeat
+ for j in (n-i)..n repeat
+ qsetelt_!(v,j, qelt(v,j) + qelt(v,(j+1)))
+ ans : Pol := 0
+ for i in 0..n repeat
+ ans := ans + monomial(qelt(v,(i+1)),i)
+ ans
+
+
+ minus(F : Pol) ==
+ --computes Pol G such that G(x) = F(-x)
+ G : Pol := 0
+ while not (F = 0) repeat
+ n := degree(F)
+ coef := leadingCoefficient(F)
+ odd? n =>
+ G := G + monomial(-coef, n)
+ F := reductum(F)
+ G := G + monomial(coef, n)
+ F := reductum(F)
+ G
+
+ invert(F : Pol) ==
+ --computes Pol G such that G(x) = (x**n) * F(1/x)
+ G : Pol := 0
+ n := degree(F)
+ while not (F = 0) repeat
+ G := G + monomial(leadingCoefficient(F),
+ (n-degree(F))::NonNegativeInteger)
+ F := reductum(F)
+ G
+
+ var(F : Pol) == --number of sign variations in coefs of F
+ i : Integer := 0
+ LastCoef : Boolean
+ next : Boolean
+ LastCoef := leadingCoefficient(F) < 0
+ while not ((F := reductum(F)) = 0) repeat
+ next := leadingCoefficient(F) < 0
+ if ((not LastCoef) and next) or
+ ((not next) and LastCoef) then i := i+1
+ LastCoef := next
+ i
+
+ refine(F : Pol, int : Interval, bounds : Interval) ==
+ lseg := min(int.right,bounds.right) - max(int.left,bounds.left)
+ lseg < 0 => "failed"
+ lseg = 0 =>
+ pt :=
+ int.left = bounds.right => int.left
+ int.right
+ elt(transMultInv(denom(pt),F),numer pt) = 0 => [pt,pt]
+ "failed"
+ lseg = int.right - int.left => int
+ refine(F, refine(F, int, lseg), bounds)
+
+ refine(F : Pol, int : Interval, eps : RN) ==
+ a := int.left
+ b := int.right
+ a=b => [a,b]$Interval
+ an : Integer := numer(a)
+ ad : Integer := denom(a)
+ bn : Integer := numer(b)
+ bd : Integer := denom(b)
+ xfl : Boolean := false
+ if (u:=elt(transMultInv(ad, F), an)) = 0 then
+ F := (F exquo (monomial(ad,1)-monomial(an,0)))::Pol
+ u:=elt(transMultInv(ad, F), an)
+ if (v:=elt(transMultInv(bd, F), bn)) = 0 then
+ F := (F exquo (monomial(bd,1)-monomial(bn,0)))::Pol
+ v:=elt(transMultInv(bd, F), bn)
+ u:=elt(transMultInv(ad, F), an)
+ if u > 0 then (F:=-F;v:=-v)
+ if v < 0 then
+ error [int, "is not a valid isolation interval for", F]
+ if eps <= 0 then error "precision must be positive"
+ while (b - a) >= eps repeat
+ mid : RN := (b + a) * (1/2)
+ midn : Integer := numer(mid)
+ midd : Integer := denom(mid)
+ (v := elt(transMultInv(midd, F), midn)) < 0 =>
+ a := mid
+ an := midn
+ ad := midd
+ v > 0 =>
+ b := mid
+ bn := midn
+ bd := midd
+ v = 0 =>
+ a := mid
+ b := mid
+ an := midn
+ ad := midd
+ xfl := true
+ [a, b]$Interval
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REAL0 RealZeroPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/reclos.spad.pamphlet b/src/algebra/reclos.spad.pamphlet
new file mode 100644
index 00000000..b0400ad1
--- /dev/null
+++ b/src/algebra/reclos.spad.pamphlet
@@ -0,0 +1,1242 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra reclos.spad}
+\author{Renaud Rioboo}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+This file describes the Real Closure 1.0 package which consists of different
+packages, categoris and domains :
+
+- the package RealPolynomialUtilitiesPackage whichs receives a field and a
+univariate polynomial domain with coefficients in the field. It computes some
+simple functions such as Strum and Sylvester sequences.
+
+- The category RealRootCharacterizationCategory provides abstarct
+functionalities to work with "real roots" of univariate polynomials. These
+resemble variables with some functionalities needed to compute important
+operations.
+
+- RealClosedField is a category with provides comon operations available over
+real closed fiels. These include finding all the roots of univariate
+polynomial, taking square roots, ...
+
+- The domain RightOpenIntervalRootCharacterization is the main code that
+provides the functionalities of RealRootCharacterizationCategory for the case
+of archimedean fileds. Abstract roots are encoded with a left closed right
+open interval containing the root together with a defining polynomial for the
+root.
+
+- The RealClosure domain is the end-user code, it provides usual arithmetics
+with real algebraic numbers, along with the functionalities of a real closed
+field. It also provides functions to approximate a real algebraic number by an
+element of the base field. This approximation may either be absolute
+(approximate) or relative (realtivApprox).
+
+
+CAVEEATS
+
+Since real algebraic expressions are stored as depending on "real roots" which
+are managed like variables, there is an ordering on these. This ordering is
+dynamical in the sense that any new algebraic takes precedence over older
+ones. In particular every cretaion function raises a new "real root". This has
+the effect that when you type something like sqrt(2) + sqrt(2) you have two
+new variables which happen to be equal. To avoid this name the expression such
+as in s2 := sqrt(2) ; s2 + s2
+
+Also note that computing times depend strongly on the ordering you implicitly
+provide. Please provide algebraics in the order which most natural to you.
+
+LIMITATIONS
+
+The file reclos.input show some basic use of the package. This packages uses
+algorithms which are published in [1] and [2] which are based on field
+arithmetics, inparticular for polynomial gcd related algorithms. This can be
+quite slow for high degree polynomials and subresultants methods usually work
+best. Betas versions of the package try to use these techniques in a better
+way and work significantly faster. These are mostly based on unpublished
+algorithms and cannot be distributed. Please contact the author if you have a
+particular problem to solve or want to use these versions.
+
+Be aware that approximations behave as post-processing and that all
+computations are done excatly. They can thus be quite time consuming when
+depending on several "real roots".
+\section{package POLUTIL RealPolynomialUtilitiesPackage}
+<<package POLUTIL RealPolynomialUtilitiesPackage>>=
+)abbrev package POLUTIL RealPolynomialUtilitiesPackage
+++ Author: Renaud Rioboo
+++ Date Created: summer 1992
+++ Basic Functions: provides polynomial utilities
+++ Related Constructors: RealClosure,
+++ Date Last Updated: July 2004
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Sturm sequences
+++ References:
+++ Description:
+++ \axiomType{RealPolynomialUtilitiesPackage} provides common functions used
+++ by interval coding.
+RealPolynomialUtilitiesPackage(TheField,ThePols) : PUB == PRIV where
+
+ TheField : Field
+ ThePols : UnivariatePolynomialCategory(TheField)
+
+ Z ==> Integer
+ N ==> NonNegativeInteger
+ P ==> ThePols
+
+ PUB == with
+
+ sylvesterSequence : (ThePols,ThePols) -> List ThePols
+ ++ \axiom{sylvesterSequence(p,q)} is the negated remainder sequence
+ ++ of p and q divided by the last computed term
+ sturmSequence : ThePols -> List ThePols
+ ++ \axiom{sturmSequence(p) = sylvesterSequence(p,p')}
+ if TheField has OrderedRing then
+ boundOfCauchy : ThePols -> TheField
+ ++ \axiom{boundOfCauchy(p)} bounds the roots of p
+ sturmVariationsOf : List TheField -> N
+ ++ \axiom{sturmVariationsOf(l)} is the number of sign variations
+ ++ in the list of numbers l,
+ ++ note that the first term counts as a sign
+ lazyVariations : (List(TheField), Z, Z) -> N
+ ++ \axiom{lazyVariations(l,s1,sn)} is the number of sign variations
+ ++ in the list of non null numbers [s1::l]@sn,
+
+
+ PRIV == add
+
+ sturmSequence(p) ==
+ sylvesterSequence(p,differentiate(p))
+
+ sylvesterSequence(p1,p2) ==
+ res : List(ThePols) := [p1]
+ while (p2 ^= 0) repeat
+ res := cons(p2 , res)
+ (p1 , p2) := (p2 , -(p1 rem p2))
+ if degree(p1) > 0
+ then
+ p1 := unitCanonical(p1)
+ res := [ term quo p1 for term in res ]
+ reverse! res
+
+ if TheField has OrderedRing
+ then
+
+ boundOfCauchy(p) ==
+ c :TheField := inv(leadingCoefficient(p))
+ l := [ c*term for term in rest(coefficients(p))]
+ null(l) => 1
+ 1 + ("max" / [ abs(t) for t in l ])
+
+-- sturmVariationsOf(l) ==
+-- res : N := 0
+-- lsg := sign(first(l))
+-- for term in l repeat
+-- if ^( (sg := sign(term) ) = 0 ) then
+-- if (sg ^= lsg) then res := res + 1
+-- lsg := sg
+-- res
+
+ sturmVariationsOf(l) ==
+ null(l) => error "POLUTIL: sturmVariationsOf: empty list !"
+ l1 := first(l)
+ -- first 0 counts as a sign
+ ll : List(TheField) := []
+ for term in rest(l) repeat
+ -- zeros don't count
+ if not(zero?(term)) then ll := cons(term,ll)
+ -- if l1 is not zero then ll = reverse(l)
+ null(ll) => error "POLUTIL: sturmVariationsOf: Bad sequence"
+ ln := first(ll)
+ ll := reverse(rest(ll))
+ -- if l1 is not zero then first(l) = first(ll)
+ -- if l1 is zero then first zero should count as a sign
+ zero?(l1) => 1 + lazyVariations(rest(ll),sign(first(ll)),sign(ln))
+ lazyVariations(ll, sign(l1), sign(ln))
+
+ lazyVariations(l,sl,sh) ==
+ zero?(sl) or zero?(sh) => error "POLUTIL: lazyVariations: zero sign!"
+ null(l) =>
+ if sl = sh then 0 else 1
+ null(rest(l)) =>
+ if zero?(first(l))
+ then error "POLUTIL: lazyVariations: zero sign!"
+ else
+ if sl = sh
+ then
+ if (sl = sign(first(l)))
+ then 0
+ else 2
+ -- in this case we save one test
+ else 1
+ s := sign(l.2)
+ lazyVariations([first(l)],sl,s) +
+ lazyVariations(rest(rest(l)),s,sh)
+
+@
+\section{category RRCC RealRootCharacterizationCategory}
+<<category RRCC RealRootCharacterizationCategory>>=
+)abbrev category RRCC RealRootCharacterizationCategory
+++ Author: Renaud Rioboo
+++ Date Created: summer 1992
+++ Date Last Updated: January 2004
+++ Basic Functions: provides operations with generic real roots of
+++ polynomials
+++ Related Constructors: RealClosure, RightOpenIntervalRootCharacterization
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Real Algebraic Numbers
+++ References:
+++ Description:
+++ \axiomType{RealRootCharacterizationCategory} provides common acces
+++ functions for all real root codings.
+RealRootCharacterizationCategory(TheField, ThePols ) : Category == PUB where
+
+ TheField : Join(OrderedRing, Field)
+ ThePols : UnivariatePolynomialCategory(TheField)
+
+ Z ==> Integer
+ N ==> PositiveInteger
+
+ PUB ==>
+ SetCategory with
+
+ sign: ( ThePols, $ ) -> Z
+ ++ \axiom{sign(pol,aRoot)} gives the sign of \axiom{pol}
+ ++ interpreted as \axiom{aRoot}
+ zero? : ( ThePols, $ ) -> Boolean
+ ++ \axiom{zero?(pol,aRoot)} answers if \axiom{pol}
+ ++ interpreted as \axiom{aRoot} is \axiom{0}
+ negative?: ( ThePols, $ ) -> Boolean
+ ++ \axiom{negative?(pol,aRoot)} answers if \axiom{pol}
+ ++ interpreted as \axiom{aRoot} is negative
+ positive?: ( ThePols, $ ) -> Boolean
+ ++ \axiom{positive?(pol,aRoot)} answers if \axiom{pol}
+ ++ interpreted as \axiom{aRoot} is positive
+ recip: ( ThePols, $ ) -> Union(ThePols,"failed")
+ ++ \axiom{recip(pol,aRoot)} tries to inverse \axiom{pol}
+ ++ interpreted as \axiom{aRoot}
+ definingPolynomial: $ -> ThePols
+ ++ \axiom{definingPolynomial(aRoot)} gives a polynomial
+ ++ such that \axiom{definingPolynomial(aRoot).aRoot = 0}
+ allRootsOf: ThePols -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots of \axiom{pol}
+ ++ in the Real Closure, assumed in order.
+ rootOf: ( ThePols, N ) -> Union($,"failed")
+ ++ \axiom{rootOf(pol,n)} gives the nth root for the order of the
+ ++ Real Closure
+ approximate : (ThePols,$,TheField) -> TheField
+ ++ \axiom{approximate(term,root,prec)} gives an approximation
+ ++ of \axiom{term} over \axiom{root} with precision \axiom{prec}
+
+ relativeApprox : (ThePols,$,TheField) -> TheField
+ ++ \axiom{approximate(term,root,prec)} gives an approximation
+ ++ of \axiom{term} over \axiom{root} with precision \axiom{prec}
+
+ add
+
+ zero?(toTest, rootChar) ==
+ sign(toTest, rootChar) = 0
+
+ negative?(toTest, rootChar) ==
+ sign(toTest, rootChar) < 0
+
+ positive?(toTest, rootChar) ==
+ sign(toTest, rootChar) > 0
+
+ rootOf(pol,n) ==
+ liste:List($):= allRootsOf(pol)
+ # liste > n => "failed"
+ liste.n
+
+ recip(toInv,rootChar) ==
+ degree(toInv) = 0 =>
+ res := recip(leadingCoefficient(toInv))
+ if (res case "failed") then "failed" else (res::TheField::ThePols)
+ defPol := definingPolynomial(rootChar)
+ d := principalIdeal([defPol,toInv])
+ zero?(d.generator,rootChar) => "failed"
+ if (degree(d.generator) ^= 0 )
+ then
+ defPol := (defPol exquo (d.generator))::ThePols
+ d := principalIdeal([defPol,toInv])
+ d.coef.2
+
+@
+\section{category RCFIELD RealClosedField}
+<<category RCFIELD RealClosedField>>=
+)abbrev category RCFIELD RealClosedField
+++ Author: Renaud Rioboo
+++ Date Created: may 1993
+++ Date Last Updated: January 2004
+++ Basic Functions: provides computations with generic real roots of
+++ polynomials
+++ Related Constructors: SimpleOrderedAlgebraicExtension, RealClosure
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Real Algebraic Numbers
+++ References:
+++ Description:
+++ \axiomType{RealClosedField} provides common acces
+++ functions for all real closed fields.
+RealClosedField : Category == PUB where
+
+ E ==> OutputForm
+ SUP ==> SparseUnivariatePolynomial
+ OFIELD ==> Join(OrderedRing,Field)
+ PME ==> SUP($)
+ N ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ RN ==> Fraction(Integer)
+ Z ==> Integer
+ POLY ==> Polynomial
+ PACK ==> SparseUnivariatePolynomialFunctions2
+
+ PUB == Join(CharacteristicZero,
+ OrderedRing,
+ CommutativeRing,
+ Field,
+ FullyRetractableTo(Fraction(Integer)),
+ Algebra Integer,
+ Algebra(Fraction(Integer)),
+ RadicalCategory) with
+
+ mainForm : $ -> Union(E,"failed")
+ ++ \axiom{mainForm(x)} is the main algebraic quantity name of
+ ++ \axiom{x}
+
+ mainDefiningPolynomial : $ -> Union(PME,"failed")
+ ++ \axiom{mainDefiningPolynomial(x)} is the defining
+ ++ polynomial for the main algebraic quantity of \axiom{x}
+
+ mainValue : $ -> Union(PME,"failed")
+ ++ \axiom{mainValue(x)} is the expression of \axiom{x} in terms
+ ++ of \axiom{SparseUnivariatePolynomial($)}
+
+ rootOf: (PME,PI,E) -> Union($,"failed")
+ ++ \axiom{rootOf(pol,n,name)} creates the nth root for the order
+ ++ of \axiom{pol} and names it \axiom{name}
+
+ rootOf: (PME,PI) -> Union($,"failed")
+ ++ \axiom{rootOf(pol,n)} creates the nth root for the order
+ ++ of \axiom{pol} and gives it unique name
+
+ allRootsOf: PME -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots
+ ++ of \axiom{pol} naming each uniquely
+
+ allRootsOf: (SUP(RN)) -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots
+ ++ of \axiom{pol} naming each uniquely
+
+ allRootsOf: (SUP(Z)) -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots
+ ++ of \axiom{pol} naming each uniquely
+
+ allRootsOf: (POLY($)) -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots
+ ++ of \axiom{pol} naming each uniquely
+
+ allRootsOf: (POLY(RN)) -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots
+ ++ of \axiom{pol} naming each uniquely
+
+ allRootsOf: (POLY(Z)) -> List $
+ ++ \axiom{allRootsOf(pol)} creates all the roots
+ ++ of \axiom{pol} naming each uniquely
+
+ sqrt: ($,N) -> $
+ ++ \axiom{sqrt(x,n)} is \axiom{x ** (1/n)}
+
+ sqrt: $ -> $
+ ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
+
+ sqrt: RN -> $
+ ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
+
+ sqrt: Z -> $
+ ++ \axiom{sqrt(x)} is \axiom{x ** (1/2)}
+
+ rename! : ($,E) -> $
+ ++ \axiom{rename!(x,name)} changes the way \axiom{x} is printed
+
+ rename : ($,E) -> $
+ ++ \axiom{rename(x,name)} gives a new number that prints as name
+
+ approximate: ($,$) -> RN
+ ++ \axiom{approximate(n,p)} gives an approximation of \axiom{n}
+ ++ that has precision \axiom{p}
+
+ add
+
+ sqrt(a:$):$ == sqrt(a,2)
+
+ sqrt(a:RN):$ == sqrt(a::$,2)
+
+ sqrt(a:Z):$ == sqrt(a::$,2)
+
+ characteristic() == 0
+
+ rootOf(pol,n,o) ==
+ r := rootOf(pol,n)
+ r case "failed" => "failed"
+ rename!(r,o)
+
+ rootOf(pol,n) ==
+ liste:List($):= allRootsOf(pol)
+ # liste > n => "failed"
+ liste.n
+
+
+ sqrt(x,n) ==
+ n = 0 => 1
+ n = 1 => x
+ zero?(x) => 0
+ one?(x) => 1
+ if odd?(n)
+ then
+ r := rootOf(monomial(1,n) - (x :: PME), 1)
+ else
+ r := rootOf(monomial(1,n) - (x :: PME), 2)
+ r case "failed" => error "no roots"
+ n = 2 => rename(r,root(x::E)$E)
+ rename(r,root(x :: E, n :: E)$E)
+
+ (x : $) ** (rn : RN) == sqrt(x**numer(rn),denom(rn)::N)
+
+ nthRoot(x, n) ==
+ zero?(n) => x
+ negative?(n) => inv(sqrt(x,(-n) :: N))
+ sqrt(x,n :: N)
+
+ allRootsOf(p:SUP(RN)) == allRootsOf(map(#1 :: $ ,p)$PACK(RN,$))
+
+ allRootsOf(p:SUP(Z)) == allRootsOf(map(#1 :: $ ,p)$PACK(Z,$))
+
+ allRootsOf(p:POLY($)) == allRootsOf(univariate(p))
+
+ allRootsOf(p:POLY(RN)) == allRootsOf(univariate(p))
+
+ allRootsOf(p:POLY(Z)) == allRootsOf(univariate(p))
+
+@
+\section{domain ROIRC RightOpenIntervalRootCharacterization}
+\subsection{makeChar performance problem}
+The following lines of code, which check for a possible error,
+cause major performance problems and were removed by Renaud Rioboo,
+the original author. They were originally inserted for debugging.
+\begin{verbatim}
+ right <= left => error "ROIRC: makeChar: Bad interval"
+ (pol.left * pol.right) > 0 => error "ROIRC: makeChar: Bad pol"
+\end{verbatim}
+<<performance problem>>=
+@
+<<domain ROIRC RightOpenIntervalRootCharacterization>>=
+)abbrev domain ROIRC RightOpenIntervalRootCharacterization
+++ Author: Renaud Rioboo
+++ Date Created: summer 1992
+++ Date Last Updated: January 2004
+++ Basic Functions: provides computations with real roots of olynomials
+++ Related Constructors: RealRootCharacterizationCategory, RealClosure
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Real Algebraic Numbers
+++ References:
+++ Description:
+++ \axiomType{RightOpenIntervalRootCharacterization} provides work with
+++ interval root coding.
+RightOpenIntervalRootCharacterization(TheField,ThePolDom) : PUB == PRIV where
+
+ TheField : Join(OrderedRing,Field)
+ ThePolDom : UnivariatePolynomialCategory(TheField)
+
+
+ Z ==> Integer
+ P ==> ThePolDom
+ N ==> NonNegativeInteger
+ B ==> Boolean
+ UTIL ==> RealPolynomialUtilitiesPackage(TheField,ThePolDom)
+ RRCC ==> RealRootCharacterizationCategory
+ O ==> OutputForm
+ TwoPoints ==> Record(low:TheField , high:TheField)
+
+ PUB == RealRootCharacterizationCategory(TheField, ThePolDom) with
+
+ left : $ -> TheField
+ ++ \axiom{left(rootChar)} is the left bound of the isolating
+ ++ interval
+ right : $ -> TheField
+ ++ \axiom{right(rootChar)} is the right bound of the isolating
+ ++ interval
+ size : $ -> TheField
+ ++ The size of the isolating interval
+ middle : $ -> TheField
+ ++ \axiom{middle(rootChar)} is the middle of the isolating
+ ++ interval
+ refine : $ -> $
+ ++ \axiom{refine(rootChar)} shrinks isolating interval around
+ ++ \axiom{rootChar}
+ mightHaveRoots : (P,$) -> B
+ ++ \axiom{mightHaveRoots(p,r)} is false if \axiom{p.r} is not 0
+ relativeApprox : (P,$,TheField) -> TheField
+ ++ \axiom{relativeApprox(exp,c,p) = a} is relatively close to exp
+ ++ as a polynomial in c ip to precision p
+
+ PRIV == add
+
+
+
+-- local functions
+
+
+ makeChar: (TheField,TheField,ThePolDom) -> $
+ refine! : $ -> $
+ sturmIsolate : (List(P), TheField, TheField,N,N) -> List TwoPoints
+ isolate : List(P) -> List TwoPoints
+ rootBound : P -> TheField
+-- varStar : P -> N
+ linearRecip : ( P , $) -> Union(P, "failed")
+ linearZero? : (TheField,$) -> B
+ linearSign : (P,$) -> Z
+ sturmNthRoot : (List(P), TheField, TheField,N,N,N) -> Union(TwoPoints,"failed")
+ addOne : P -> P
+ minus : P -> P
+ translate : (P,TheField) -> P
+ dilate : (P,TheField) -> P
+ invert : P -> P
+ evalOne : P -> TheField
+ hasVarsl: List(TheField) -> B
+ hasVars: P -> B
+
+-- Representation
+
+ Rep:= Record(low:TheField,high:TheField,defPol:ThePolDom)
+
+-- and now the code !
+
+
+ size(rootCode) ==
+ rootCode.high - rootCode.low
+
+ relativeApprox(pval,rootCode,prec) ==
+ -- beurk !
+ dPol := rootCode.defPol
+ degree(dPol) = 1 =>
+ c := -coefficient(dPol,0)/leadingCoefficient(dPol)
+ pval.c
+ pval := pval rem dPol
+ degree(pval) = 0 => leadingCoefficient(pval)
+ zero?(pval,rootCode) => 0
+ while mightHaveRoots(pval,rootCode) repeat
+ rootCode := refine(rootCode)
+ dpval := differentiate(pval)
+ degree(dpval) = 0 =>
+ l := left(rootCode)
+ r := right(rootCode)
+ a := pval.l
+ b := pval.r
+ while ( abs(2*(a-b)/(a+b)) > prec ) repeat
+ rootCode := refine(rootCode)
+ l := left(rootCode)
+ r := right(rootCode)
+ a := pval.l
+ b := pval.r
+ (a+b)/(2::TheField)
+ zero?(dpval,rootCode) =>
+ relativeApprox(pval,
+ [left(rootCode),
+ right(rootCode),
+ gcd(dpval,rootCode.defPol)]$Rep,
+ prec)
+ while mightHaveRoots(dpval,rootCode) repeat
+ rootCode := refine(rootCode)
+ l := left(rootCode)
+ r := right(rootCode)
+ a := pval.l
+ b := pval.r
+ while ( abs(2*(a-b)/(a+b)) > prec ) repeat
+ rootCode := refine(rootCode)
+ l := left(rootCode)
+ r := right(rootCode)
+ a := pval.l
+ b := pval.r
+ (a+b)/(2::TheField)
+
+ approximate(pval,rootCode,prec) ==
+ -- glurp
+ dPol := rootCode.defPol
+ degree(dPol) = 1 =>
+ c := -coefficient(dPol,0)/leadingCoefficient(dPol)
+ pval.c
+ pval := pval rem dPol
+ degree(pval) = 0 => leadingCoefficient(pval)
+ dpval := differentiate(pval)
+ degree(dpval) = 0 =>
+ l := left(rootCode)
+ r := right(rootCode)
+ while ( abs((a := pval.l) - (b := pval.r)) > prec ) repeat
+ rootCode := refine(rootCode)
+ l := left(rootCode)
+ r := right(rootCode)
+ (a+b)/(2::TheField)
+ zero?(dpval,rootCode) =>
+ approximate(pval,
+ [left(rootCode),
+ right(rootCode),
+ gcd(dpval,rootCode.defPol)]$Rep,
+ prec)
+ while mightHaveRoots(dpval,rootCode) repeat
+ rootCode := refine(rootCode)
+ l := left(rootCode)
+ r := right(rootCode)
+ while ( abs((a := pval.l) - (b := pval.r)) > prec ) repeat
+ rootCode := refine(rootCode)
+ l := left(rootCode)
+ r := right(rootCode)
+ (a+b)/(2::TheField)
+
+
+ addOne(p) == p.(monomial(1,1)+(1::P))
+
+ minus(p) == p.(monomial(-1,1))
+
+ translate(p,a) == p.(monomial(1,1)+(a::P))
+
+ dilate(p,a) == p.(monomial(a,1))
+
+ evalOne(p) == "+" / coefficients(p)
+
+ invert(p) ==
+ d := degree(p)
+ mapExponents((d-#1)::N, p)
+
+ rootBound(p) ==
+ res : TheField := 1
+ raw :TheField := 1+boundOfCauchy(p)$UTIL
+ while (res < raw) repeat
+ res := 2*(res)
+ res
+
+ sturmNthRoot(lp,l,r,vl,vr,n) ==
+ nv := (vl - vr)::N
+ nv < n => "failed"
+ ((nv = 1) and (n = 1)) => [l,r]
+ int := (l+r)/(2::TheField)
+ lt:List(TheField):=[]
+ for t in lp repeat
+ lt := cons(t.int , lt)
+ vi := sturmVariationsOf(reverse! lt)$UTIL
+ o :Z := n - vl + vi
+ if o > 0
+ then
+ sturmNthRoot(lp,int,r,vi,vr,o::N)
+ else
+ sturmNthRoot(lp,l,int,vl,vi,n)
+
+ sturmIsolate(lp,l,r,vl,vr) ==
+ r <= l => error "ROIRC: sturmIsolate: bad bounds"
+ n := (vl - vr)::N
+ zero?(n) => []
+ one?(n) => [[l,r]]
+ int := (l+r)/(2::TheField)
+ vi := sturmVariationsOf( [t.int for t in lp ] )$UTIL
+ append(sturmIsolate(lp,l,int,vl,vi),sturmIsolate(lp,int,r,vi,vr))
+
+ isolate(lp) ==
+ b := rootBound(first(lp))
+ l1,l2 : List(TheField)
+ (l1,l2) := ([] , [])
+ for t in reverse(lp) repeat
+ if odd?(degree(t))
+ then
+ (l1,l2):= (cons(-leadingCoefficient(t),l1),
+ cons(leadingCoefficient(t),l2))
+ else
+ (l1,l2):= (cons(leadingCoefficient(t),l1),
+ cons(leadingCoefficient(t),l2))
+ sturmIsolate(lp,
+ -b,
+ b,
+ sturmVariationsOf(l1)$UTIL,
+ sturmVariationsOf(l2)$UTIL)
+
+ rootOf(pol,n) ==
+ ls := sturmSequence(pol)$UTIL
+ pol := unitCanonical(first(ls)) -- this one is SqFR
+ degree(pol) = 0 => "failed"
+ numberOfMonomials(pol) = 1 => ([0,1,monomial(1,1)]$Rep)::$
+ b := rootBound(pol)
+ l1,l2 : List(TheField)
+ (l1,l2) := ([] , [])
+ for t in reverse(ls) repeat
+ if odd?(degree(t))
+ then
+ (l1,l2):= (cons(leadingCoefficient(t),l1),
+ cons(-leadingCoefficient(t),l2))
+ else
+ (l1,l2):= (cons(leadingCoefficient(t),l1),
+ cons(leadingCoefficient(t),l2))
+ res := sturmNthRoot(ls,
+ -b,
+ b,
+ sturmVariationsOf(l2)$UTIL,
+ sturmVariationsOf(l1)$UTIL,
+ n)
+ res case "failed" => "failed"
+ makeChar(res.low,res.high,pol)
+
+ allRootsOf(pol) ==
+ ls := sturmSequence(unitCanonical pol)$UTIL
+ pol := unitCanonical(first(ls)) -- this one is SqFR
+ degree(pol) = 0 => []
+ numberOfMonomials(pol) = 1 => [[0,1,monomial(1,1)]$Rep]
+ [ makeChar(term.low,term.high,pol) for term in isolate(ls) ]
+
+
+ hasVarsl(l:List(TheField)) ==
+ null(l) => false
+ f := sign(first(l))
+ for term in rest(l) repeat
+ if f*term < 0 then return(true)
+ false
+
+ hasVars(p:P) ==
+ zero?(p) => error "ROIRC: hasVars: null polynonial"
+ zero?(coefficient(p,0)) => true
+ hasVarsl(coefficients(p))
+
+
+ mightHaveRoots(p,rootChar) ==
+ a := rootChar.low
+ q := translate(p,a)
+ not(hasVars(q)) => false
+-- varStar(q) = 0 => false
+ a := (rootChar.high) - a
+ q := dilate(q,a)
+ sign(coefficient(q,0))*sign(evalOne(q)) <= 0 => true
+ q := minus(addOne(q))
+ not(hasVars(q)) => false
+-- varStar(q) = 0 => false
+ q := invert(q)
+ hasVars(addOne(q))
+-- ^(varStar(addOne(q)) = 0)
+
+ coerce(rootChar:$):O ==
+ commaSeparate([ hconcat("[" :: O , (rootChar.low)::O),
+ hconcat((rootChar.high)::O,"[" ::O ) ])
+
+ c1 = c2 ==
+ mM := max(c1.low,c2.low)
+ Mm := min(c1.high,c2.high)
+ mM >= Mm => false
+ rr : ThePolDom := gcd(c1.defPol,c2.defPol)
+ degree(rr) = 0 => false
+ sign(rr.mM) * sign(rr.Mm) <= 0
+
+ makeChar(left,right,pol) ==
+<<performance problem>>
+ res :$ := [left,right,leadingMonomial(pol)+reductum(pol)]$Rep -- safe copy
+ while zero?(pol.(res.high)) repeat refine!(res)
+ while (res.high * res.low < 0 ) repeat refine!(res)
+ zero?(pol.(res.low)) => [res.low,res.high,monomial(1,1)-(res.low)::P]
+ res
+
+ definingPolynomial(rootChar) == rootChar.defPol
+
+ linearRecip(toTest,rootChar) ==
+ c := - inv(leadingCoefficient(toTest)) * coefficient(toTest,0)
+ r := recip(rootChar.defPol.c)
+ if (r case "failed")
+ then
+ if (c - rootChar.low) * (c - rootChar.high) <= 0
+ then
+ "failed"
+ else
+ newPol := (rootChar.defPol exquo toTest)::P
+ ((1$ThePolDom - inv(newPol.c)*newPol) exquo toTest)::P
+ else
+ ((1$ThePolDom - (r::TheField)*rootChar.defPol) exquo toTest)::P
+
+ recip(toTest,rootChar) ==
+ degree(toTest) = 0 or degree(rootChar.defPol) <= degree(toTest) =>
+ error "IRC: recip: Not reduced"
+ degree(rootChar.defPol) = 1 =>
+ error "IRC: recip: Linear Defining Polynomial"
+ degree(toTest) = 1 =>
+ linearRecip(toTest, rootChar)
+ d := extendedEuclidean((rootChar.defPol),toTest)
+ (degree(d.generator) = 0 ) =>
+ d.coef2
+ d.generator := unitCanonical(d.generator)
+ (d.generator.(rootChar.low) *
+ d.generator.(rootChar.high)<= 0) => "failed"
+ newPol := (rootChar.defPol exquo (d.generator))::P
+ degree(newPol) = 1 =>
+ c := - inv(leadingCoefficient(newPol)) * coefficient(newPol,0)
+ inv(toTest.c)::P
+ degree(toTest) = 1 =>
+ c := - coefficient(toTest,0)/ leadingCoefficient(toTest)
+ ((1$ThePolDom - inv(newPol.(c))*newPol) exquo toTest)::P
+ d := extendedEuclidean(newPol,toTest)
+ d.coef2
+
+ linearSign(toTest,rootChar) ==
+ c := - inv(leadingCoefficient(toTest)) * coefficient(toTest,0)
+ ev := sign(rootChar.defPol.c)
+ if zero?(ev)
+ then
+ if (c - rootChar.low) * (c - rootChar.high) <= 0
+ then
+ 0
+ else
+ sign(toTest.(rootChar.high))
+ else
+ if (ev*sign(rootChar.defPol.(rootChar.high)) <= 0 )
+ then
+ sign(toTest.(rootChar.high))
+ else
+ sign(toTest.(rootChar.low))
+
+ sign(toTest,rootChar) ==
+ degree(toTest) = 0 or degree(rootChar.defPol) <= degree(toTest) =>
+ error "IRC: sign: Not reduced"
+ degree(rootChar.defPol) = 1 =>
+ error "IRC: sign: Linear Defining Polynomial"
+ degree(toTest) = 1 =>
+ linearSign(toTest, rootChar)
+ s := sign(leadingCoefficient(toTest))
+ toTest := monomial(1,degree(toTest))+
+ inv(leadingCoefficient(toTest))*reductum(toTest)
+ delta := gcd(toTest,rootChar.defPol)
+ newChar := [rootChar.low,rootChar.high,rootChar.defPol]$Rep
+ if degree(delta) > 0
+ then
+ if sign(delta.(rootChar.low) * delta.(rootChar.high)) <= 0
+ then
+ return(0)
+ else
+ newChar.defPol := (newChar.defPol exquo delta) :: P
+ toTest := toTest rem (newChar.defPol)
+ degree(toTest) = 0 => s * sign(leadingCoefficient(toTest))
+ degree(toTest) = 1 => s * linearSign(toTest, newChar)
+ while mightHaveRoots(toTest,newChar) repeat
+ newChar := refine(newChar)
+ s*sign(toTest.(newChar.low))
+
+ linearZero?(c,rootChar) ==
+ zero?((rootChar.defPol).c) and
+ (c - rootChar.low) * (c - rootChar.high) <= 0
+
+ zero?(toTest,rootChar) ==
+ degree(toTest) = 0 or degree(rootChar.defPol) <= degree(toTest) =>
+ error "IRC: zero?: Not reduced"
+ degree(rootChar.defPol) = 1 =>
+ error "IRC: zero?: Linear Defining Polynomial"
+ degree(toTest) = 1 =>
+ linearZero?(- inv(leadingCoefficient(toTest)) * coefficient(toTest,0),
+ rootChar)
+ toTest := monomial(1,degree(toTest))+
+ inv(leadingCoefficient(toTest))*reductum(toTest)
+ delta := gcd(toTest,rootChar.defPol)
+ degree(delta) = 0 => false
+ sign(delta.(rootChar.low) * delta.(rootChar.high)) <= 0
+
+
+ refine!(rootChar) ==
+ -- this is not a safe function, it can work with badly created object
+ -- we do not assume (rootChar.defPol).(rootChar.high) <> 0
+ int := middle(rootChar)
+ s1 := sign((rootChar.defPol).(rootChar.low))
+ zero?(s1) =>
+ rootChar.high := int
+ rootChar.defPol := monomial(1,1) - (rootChar.low)::P
+ rootChar
+ s2 := sign((rootChar.defPol).int)
+ zero?(s2) =>
+ rootChar.low := int
+ rootChar.defPol := monomial(1,1) - int::P
+ rootChar
+ if (s1*s2 < 0)
+ then
+ rootChar.high := int
+ else
+ rootChar.low := int
+ rootChar
+
+ refine(rootChar) ==
+ -- we assume (rootChar.defPol).(rootChar.high) <> 0
+ int := middle(rootChar)
+ s:= (rootChar.defPol).int * (rootChar.defPol).(rootChar.high)
+ zero?(s) => [int,rootChar.high,monomial(1,1)-int::P]
+ if s < 0
+ then
+ [int,rootChar.high,rootChar.defPol]
+ else
+ [rootChar.low,int,rootChar.defPol]
+
+ left(rootChar) == rootChar.low
+
+ right(rootChar) == rootChar.high
+
+ middle(rootChar) == (rootChar.low + rootChar.high)/(2::TheField)
+
+-- varStar(p) == -- if 0 no roots in [0,:infty[
+-- res : N := 0
+-- lsg := sign(coefficient(p,0))
+-- l := [ sign(i) for i in reverse!(coefficients(p))]
+-- for sg in l repeat
+-- if (sg ^= lsg) then res := res + 1
+-- lsg := sg
+-- res
+@
+\section{domain RECLOS RealClosure}
+The domain constructore {\bf RealClosure} by Renaud Rioboo (University
+of Paris 6, France) provides the real closure of an ordered field.
+The implementation is based on interval arithmetic. Moreover, the
+design of this constructor and its related packages allows an easy
+use of other codings for real algebraic numbers.
+ordered field
+<<domain RECLOS RealClosure>>=
+)abbrev domain RECLOS RealClosure
+++ Author: Renaud Rioboo
+++ Date Created: summer 1988
+++ Date Last Updated: January 2004
+++ Basic Functions: provides computations in an ordered real closure
+++ Related Constructors: RightOpenIntervalRootCharacterization
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Real Algebraic Numbers
+++ References:
+++ Description:
+++ This domain implements the real closure of an ordered field.
+++ Note:
+++ The code here is generic i.e. it does not depend of the way the operations
+++ are done. The two macros PME and SEG should be passed as functorial
+++ arguments to the domain. It does not help much to write a category
+++ since non trivial methods cannot be placed there either.
+++
+RealClosure(TheField): PUB == PRIV where
+
+ TheField : Join(OrderedRing, Field, RealConstant)
+
+-- ThePols : UnivariatePolynomialCategory($)
+-- PME ==> ThePols
+-- TheCharDom : RealRootCharacterizationCategory($, ThePols )
+-- SEG ==> TheCharDom
+-- this does not work yet
+
+ E ==> OutputForm
+ Z ==> Integer
+ SE ==> Symbol
+ B ==> Boolean
+ SUP ==> SparseUnivariatePolynomial($)
+ N ==> PositiveInteger
+ RN ==> Fraction Z
+ LF ==> ListFunctions2($,N)
+
+-- *****************************************************************
+-- *****************************************************************
+-- PUT YOUR OWN PREFERENCE HERE
+-- *****************************************************************
+-- *****************************************************************
+ PME ==> SparseUnivariatePolynomial($)
+ SEG ==> RightOpenIntervalRootCharacterization($,PME)
+-- *****************************************************************
+-- *****************************************************************
+
+
+ PUB == Join(RealClosedField,
+ FullyRetractableTo TheField,
+ Algebra TheField) with
+
+ algebraicOf : (SEG,E) -> $
+ ++ \axiom{algebraicOf(char)} is the external number
+
+ mainCharacterization : $ -> Union(SEG,"failed")
+ ++ \axiom{mainCharacterization(x)} is the main algebraic
+ ++ quantity of \axiom{x} (\axiom{SEG})
+
+ relativeApprox : ($,$) -> RN
+ ++ \axiom{relativeApprox(n,p)} gives a relative
+ ++ approximation of \axiom{n}
+ ++ that has precision \axiom{p}
+
+ PRIV == add
+
+-- local functions
+
+ lessAlgebraic : $ -> $
+ newElementIfneeded : (SEG,E) -> $
+
+-- Representation
+
+ Rec := Record(seg: SEG, val:PME, outForm:E, order:N)
+ Rep := Union(TheField,Rec)
+
+-- global (mutable) variables
+
+ orderOfCreation : N := 1$N
+ -- it is internally used to sort the algebraic levels
+
+ instanceName : Symbol := new()$Symbol
+ -- this used to print the results, thus different instanciations
+ -- use different names
+
+-- now the code
+
+ relativeApprox(nbe,prec) ==
+ nbe case TheField => retract(nbe)
+ appr := relativeApprox(nbe.val, nbe.seg, prec)
+ -- now appr has the good exact precision but is $
+ relativeApprox(appr,prec)
+
+
+ approximate(nbe,prec) ==
+ abs(nbe) < prec => 0
+ nbe case TheField => retract(nbe)
+ appr := approximate(nbe.val, nbe.seg, prec)
+ -- now appr has the good exact precision but is $
+ approximate(appr,prec)
+
+ newElementIfneeded(s,o) ==
+ p := definingPolynomial(s)
+ degree(p) = 1 =>
+ - coefficient(p,0) / leadingCoefficient(p)
+ res := [s, monomial(1,1), o, orderOfCreation ]$Rec
+ orderOfCreation := orderOfCreation + 1
+ res :: $
+
+ algebraicOf(s,o) ==
+ pol := definingPolynomial(s)
+ degree(pol) = 1 =>
+ -coefficient(pol,0) / leadingCoefficient(pol)
+ res := [s, monomial(1,1), o, orderOfCreation ]$Rec
+ orderOfCreation := orderOfCreation + 1
+ res :: $
+
+ rename!(x,o) ==
+ x.outForm := o
+ x
+
+ rename(x,o) ==
+ [x.seg, x.val, o, x.order]$Rec
+
+ rootOf(pol,n) ==
+ degree(pol) = 0 => "failed"
+ degree(pol) = 1 =>
+ if n=1
+ then
+ -coefficient(pol,0) / leadingCoefficient(pol)
+ else
+ "failed"
+ r := rootOf(pol,n)$SEG
+ r case "failed" => "failed"
+ o := hconcat(instanceName :: E , orderOfCreation :: E)$E
+ algebraicOf(r,o)
+
+ allRootsOf(pol:SUP):List($) ==
+ degree(pol)=0 => []
+ degree(pol)=1 => [-coefficient(pol,0) / leadingCoefficient(pol)]
+ liste := allRootsOf(pol)$SEG
+ res : List $ := []
+ for term in liste repeat
+ o := hconcat(instanceName :: E , orderOfCreation :: E)$E
+ res := cons(algebraicOf(term,o), res)
+ reverse! res
+
+ coerce(x:$):$ ==
+ x case TheField => x
+ [x.seg,x.val rem$PME definingPolynomial(x.seg),x.outForm,x.order]$Rec
+
+ positive?(x) ==
+ x case TheField => positive?(x)$TheField
+ positive?(x.val,x.seg)$SEG
+
+ negative?(x) ==
+ x case TheField => negative?(x)$TheField
+ negative?(x.val,x.seg)$SEG
+
+ abs(x) == sign(x)*x
+
+ sign(x) ==
+ x case TheField => sign(x)$TheField
+ sign(x.val,x.seg)$SEG
+
+ x < y == positive?(y-x)
+
+ x = y == zero?(x-y)
+
+ mainCharacterization(x) ==
+ x case TheField => "failed"
+ x.seg
+
+ mainDefiningPolynomial(x) ==
+ x case TheField => "failed"
+ definingPolynomial x.seg
+
+ mainForm(x) ==
+ x case TheField => "failed"
+ x.outForm
+
+ mainValue(x) ==
+ x case TheField => "failed"
+ x.val
+
+ coerce(x:$):E ==
+ x case TheField => x::TheField :: E
+ xx:$ := coerce(x)
+ outputForm(univariate(xx.val),x.outForm)$SUP
+
+
+ inv(x) ==
+ (res:= recip x) case "failed" => error "Division by 0"
+ res :: $
+
+ recip(x) ==
+ x case TheField =>
+ if ((r := recip(x)$TheField) case TheField)
+ then r::$
+ else "failed"
+ if ((r := recip(x.val,x.seg)$SEG) case "failed")
+ then "failed"
+ else lessAlgebraic([x.seg,r::PME,x.outForm,x.order]$Rec)
+
+ (n:Z * x:$):$ ==
+ x case TheField => n *$TheField x
+ zero?(n) => 0
+ one?(n) => x
+ [x.seg,map(n * #1, x.val),x.outForm,x.order]$Rec
+
+ (rn:TheField * x:$):$ ==
+ x case TheField => rn *$TheField x
+ zero?(rn) => 0
+ one?(rn) => x
+ [x.seg,map(rn * #1, x.val),x.outForm,x.order]$Rec
+
+ (x:$ * y:$):$ ==
+ (x case TheField) and (y case TheField) => x *$TheField y
+ (x case TheField) => x::TheField * y
+ -- x is no longer TheField
+ (y case TheField) => y::TheField * x
+ -- now both are algebraic
+ y.order > x.order =>
+ [y.seg,map(x * #1 , y.val),y.outForm,y.order]$Rec
+ x.order > y.order =>
+ [x.seg,map( #1 * y , x.val),x.outForm,x.order]$Rec
+ -- now x.exp = y.exp
+ -- we will multiply the polynomials and then reduce
+ -- however wee need to call lessAlgebraic
+ lessAlgebraic([x.seg,
+ (x.val * y.val) rem definingPolynomial(x.seg),
+ x.outForm,
+ x.order]$Rec)
+
+ nonNull(rep:Rec):$ ==
+ degree(rep.val)=0 => leadingCoefficient(rep.val)
+ numberOfMonomials(rep.val) = 1 => rep
+ zero?(rep.val,rep.seg)$SEG => 0
+ rep
+
+-- zero?(x) ==
+-- x case TheField => zero?(x)$TheField
+-- zero?(x.val,x.seg)$SEG
+
+ zero?(x) ==
+ x case TheField => zero?(x)$TheField
+ false
+
+ x + y ==
+ (x case TheField) and (y case TheField) => x +$TheField y
+ (x case TheField) =>
+ if zero?(x)
+ then
+ y
+ else
+ nonNull([y.seg,x::PME+(y.val),y.outForm,y.order]$Rec)
+ -- x is no longer TheField
+ (y case TheField) =>
+ if zero?(y)
+ then
+ x
+ else
+ nonNull([x.seg,(x.val)+y::PME,x.outForm,x.order]$Rec)
+ -- now both are algebraic
+ y.order > x.order =>
+ nonNull([y.seg,x::PME+y.val,y.outForm,y.order]$Rec)
+ x.order > y.order =>
+ nonNull([x.seg,(x.val)+y::PME,x.outForm,x.order]$Rec)
+ -- now x.exp = y.exp
+ -- we simply add polynomials (since degree cannot increase)
+ -- however wee need to call lessAlgebraic
+ nonNull([x.seg,x.val + y.val,x.outForm,x.order])
+
+
+ -x ==
+ x case TheField => -$TheField (x::TheField)
+ [x.seg,-$PME x.val,x.outForm,x.order]$Rec
+
+
+ retractIfCan(x:$):Union(TheField,"failed") ==
+ x case TheField => x
+ o := x.order
+ res := lessAlgebraic x
+ res case TheField => res
+ o = res.order => "failed"
+ retractIfCan res
+
+ retract(x:$):TheField ==
+ x case TheField => x
+ o := x.order
+ res := lessAlgebraic x
+ res case TheField => res
+ o = res.order => error "Can't retract"
+ retract res
+
+
+ lessAlgebraic(x) ==
+ x case TheField => x
+ degree(x.val) = 0 => leadingCoefficient(x.val)
+ def := definingPolynomial(x.seg)
+ degree(def) = 1 =>
+ x.val.(- coefficient(def,0) / leadingCoefficient(def))
+ x
+
+ 0 == (0$TheField) :: $
+
+ 1 == (1$TheField) :: $
+
+ coerce(rn:TheField):$ == rn :: $
+
+@
+\section{License}
+<<license>>=
+-----------------------------------------------------------------------------
+-- This software was written by Renaud Rioboo (Computer Algebra group of
+-- Laboratoire d'Informatique de Paris 6) and is the property of university
+-- Paris 6.
+-----------------------------------------------------------------------------
+@
+<<*>>=
+<<license>>
+<<package POLUTIL RealPolynomialUtilitiesPackage>>
+<<category RRCC RealRootCharacterizationCategory>>
+<<category RCFIELD RealClosedField>>
+<<domain ROIRC RightOpenIntervalRootCharacterization>>
+<<domain RECLOS RealClosure>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} R. Rioboo,
+{\sl Real Algebraic Closure of an ordered Field : Implementation in Axiom.},
+In proceedings of the ISSAC'92 Conference, Berkeley 1992 pp. 206-215.
+\bibitem{2} Z. Ligatsikas, R. Rioboo, M. F. Roy
+{\sl Generic computation of the real closure of an ordered field.},
+In Mathematics and Computers in Simulation Volume 42, Issue 4-6,
+November 1996.
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/regset.spad.pamphlet b/src/algebra/regset.spad.pamphlet
new file mode 100644
index 00000000..99d0747e
--- /dev/null
+++ b/src/algebra/regset.spad.pamphlet
@@ -0,0 +1,1806 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra regset.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category RSETCAT RegularTriangularSetCategory}
+<<category RSETCAT RegularTriangularSetCategory>>=
+)abbrev category RSETCAT RegularTriangularSetCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 09/03/1998
+++ Date Last Updated: 12/15/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See: essai Graphisme
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ Description:
+++ The category of regular triangular sets, introduced under
+++ the name regular chains in [1] (and other papers).
+++ In [3] it is proved that regular triangular sets and towers of simple
+++ extensions of a field are equivalent notions.
+++ In the following definitions, all polynomials and ideals
+++ are taken from the polynomial ring \spad{k[x1,...,xn]} where \spad{k}
+++ is the fraction field of \spad{R}.
+++ The triangular set \spad{[t1,...,tm]} is regular
+++ iff for every \spad{i} the initial of \spad{ti+1} is invertible
+++ in the tower of simple extensions associated with \spad{[t1,...,ti]}.
+++ A family \spad{[T1,...,Ts]} of regular triangular sets
+++ is a split of Kalkbrener of a given ideal \spad{I}
+++ iff the radical of \spad{I} is equal to the intersection
+++ of the radical ideals generated by the saturated ideals
+++ of the \spad{[T1,...,Ti]}.
+++ A family \spad{[T1,...,Ts]} of regular triangular sets
+++ is a split of Kalkbrener of a given triangular set \spad{T}
+++ iff it is a split of Kalkbrener of the saturated ideal of \spad{T}.
+++ Let \spad{K} be an algebraic closure of \spad{k}.
+++ Assume that \spad{V} is finite with cardinality
+++ \spad{n} and let \spad{A} be the affine space \spad{K^n}.
+++ For a regular triangular set \spad{T} let denote by \spad{W(T)} the
+++ set of regular zeros of \spad{T}.
+++ A family \spad{[T1,...,Ts]} of regular triangular sets
+++ is a split of Lazard of a given subset \spad{S} of \spad{A}
+++ iff the union of the \spad{W(Ti)} contains \spad{S} and
+++ is contained in the closure of \spad{S} (w.r.t. Zariski topology).
+++ A family \spad{[T1,...,Ts]} of regular triangular sets
+++ is a split of Lazard of a given triangular set \spad{T}
+++ if it is a split of Lazard of \spad{W(T)}.
+++ Note that if \spad{[T1,...,Ts]} is a split of Lazard of
+++ \spad{T} then it is also a split of Kalkbrener of \spad{T}.
+++ The converse is false.
+++ This category provides operations related to both kinds of
+++ splits, the former being related to ideals decomposition whereas
+++ the latter deals with varieties decomposition.
+++ See the example illustrating the \spadtype{RegularTriangularSet} constructor
+++ for more explanations about decompositions by means of regular triangular sets. \newline
+++ References :
+++ [1] M. KALKBRENER "Three contributions to elimination theory"
+++ Phd Thesis, University of Linz, Austria, 1991.
+++ [2] M. KALKBRENER "Algorithmic properties of polynomial rings"
+++ Journal of Symbol. Comp. 1998
+++ [3] P. AUBRY, D. LAZARD and M. MORENO MAZA "On the Theories
+++ of Triangular Sets" Journal of Symbol. Comp. (to appear)
+++ [4] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 2
+
+RegularTriangularSetCategory(R:GcdDomain, E:OrderedAbelianMonoidSup,_
+ V:OrderedSet,P:RecursivePolynomialCategory(R,E,V)):
+ Category ==
+ TriangularSetCategory(R,E,V,P) with
+
+ purelyAlgebraic?: (P,$) -> Boolean
+ ++ \spad{purelyAlgebraic?(p,ts)} returns \spad{true} iff every
+ ++ variable of \spad{p} is algebraic w.r.t. \spad{ts}.
+ purelyTranscendental? : (P,$) -> Boolean
+ ++ \spad{purelyTranscendental?(p,ts)} returns \spad{true} iff every
+ ++ variable of \spad{p} is not algebraic w.r.t. \spad{ts}
+ algebraicCoefficients? : (P,$) -> Boolean
+ ++ \spad{algebraicCoefficients?(p,ts)} returns \spad{true} iff every
+ ++ variable of \spad{p} which is not the main one of \spad{p}
+ ++ is algebraic w.r.t. \spad{ts}.
+ purelyAlgebraic?: $ -> Boolean
+ ++ \spad{purelyAlgebraic?(ts)} returns true iff for every algebraic
+ ++ variable \spad{v} of \spad{ts} we have
+ ++ \spad{algebraicCoefficients?(t_v,ts_v_-)} where \spad{ts_v}
+ ++ is \axiomOpFrom{select}{TriangularSetCategory}(ts,v) and \spad{ts_v_-} is
+ ++ \axiomOpFrom{collectUnder}{TriangularSetCategory}(ts,v).
+ purelyAlgebraicLeadingMonomial?: (P, $) -> Boolean
+ ++ \spad{purelyAlgebraicLeadingMonomial?(p,ts)} returns true iff
+ ++ the main variable of any non-constant iterarted initial
+ ++ of \spad{p} is algebraic w.r.t. \spad{ts}.
+ invertibleElseSplit? : (P,$) -> Union(Boolean,List $)
+ ++ \spad{invertibleElseSplit?(p,ts)} returns \spad{true} (resp.
+ ++ \spad{false}) if \spad{p} is invertible in the tower
+ ++ associated with \spad{ts} or returns a split of Kalkbrener
+ ++ of \spad{ts}.
+ invertible? : (P,$) -> List Record(val : Boolean, tower : $)
+ ++ \spad{invertible?(p,ts)} returns \spad{lbwt} where \spad{lbwt.i}
+ ++ is the result of \spad{invertibleElseSplit?(p,lbwt.i.tower)} and
+ ++ the list of the \spad{(lqrwt.i).tower} is a split of Kalkbrener of \spad{ts}.
+ invertible?: (P,$) -> Boolean
+ ++ \spad{invertible?(p,ts)} returns true iff \spad{p} is invertible
+ ++ in the tower associated with \spad{ts}.
+ invertibleSet: (P,$) -> List $
+ ++ \spad{invertibleSet(p,ts)} returns a split of Kalkbrener of the
+ ++ quotient ideal of the ideal \axiom{I} by \spad{p} where \spad{I} is
+ ++ the radical of saturated of \spad{ts}.
+ lastSubResultantElseSplit: (P, P, $) -> Union(P,List $)
+ ++ \spad{lastSubResultantElseSplit(p1,p2,ts)} returns either
+ ++ \spad{g} a quasi-monic gcd of \spad{p1} and \spad{p2} w.r.t.
+ ++ the \spad{ts} or a split of Kalkbrener of \spad{ts}.
+ ++ This assumes that \spad{p1} and \spad{p2} have the same maim
+ ++ variable and that this variable is greater that any variable
+ ++ occurring in \spad{ts}.
+ lastSubResultant: (P, P, $) -> List Record(val : P, tower : $)
+ ++ \spad{lastSubResultant(p1,p2,ts)} returns \spad{lpwt} such that
+ ++ \spad{lpwt.i.val} is a quasi-monic gcd of \spad{p1} and \spad{p2}
+ ++ w.r.t. \spad{lpwt.i.tower}, for every \spad{i}, and such
+ ++ that the list of the \spad{lpwt.i.tower} is a split of Kalkbrener of
+ ++ \spad{ts}. Moreover, if \spad{p1} and \spad{p2} do not
+ ++ have a non-trivial gcd w.r.t. \spad{lpwt.i.tower} then \spad{lpwt.i.val}
+ ++ is the resultant of these polynomials w.r.t. \spad{lpwt.i.tower}.
+ ++ This assumes that \spad{p1} and \spad{p2} have the same maim
+ ++ variable and that this variable is greater that any variable
+ ++ occurring in \spad{ts}.
+ squareFreePart: (P,$) -> List Record(val : P, tower : $)
+ ++ \spad{squareFreePart(p,ts)} returns \spad{lpwt} such that
+ ++ \spad{lpwt.i.val} is a square-free polynomial
+ ++ w.r.t. \spad{lpwt.i.tower}, this polynomial being associated with \spad{p}
+ ++ modulo \spad{lpwt.i.tower}, for every \spad{i}. Moreover,
+ ++ the list of the \spad{lpwt.i.tower} is a split
+ ++ of Kalkbrener of \spad{ts}.
+ ++ WARNING: This assumes that \spad{p} is a non-constant polynomial such that
+ ++ if \spad{p} is added to \spad{ts}, then the resulting set is a
+ ++ regular triangular set.
+ intersect: (P,$) -> List $
+ ++ \spad{intersect(p,ts)} returns the same as
+ ++ \spad{intersect([p],ts)}
+ intersect: (List P, $) -> List $
+ ++ \spad{intersect(lp,ts)} returns \spad{lts} a split of Lazard
+ ++ of the intersection of the affine variety associated
+ ++ with \spad{lp} and the regular zero set of \spad{ts}.
+ intersect: (List P, List $) -> List $
+ ++ \spad{intersect(lp,lts)} returns the same as
+ ++ \spad{concat([intersect(lp,ts) for ts in lts])|}
+ intersect: (P, List $) -> List $
+ ++ \spad{intersect(p,lts)} returns the same as
+ ++ \spad{intersect([p],lts)}
+ augment: (P,$) -> List $
+ ++ \spad{augment(p,ts)} assumes that \spad{p} is a non-constant
+ ++ polynomial whose main variable is greater than any variable
+ ++ of \spad{ts}. This operation assumes also that if \spad{p} is
+ ++ added to \spad{ts} the resulting set, say \spad{ts+p}, is a
+ ++ regular triangular set. Then it returns a split of Kalkbrener
+ ++ of \spad{ts+p}. This may not be \spad{ts+p} itself, if for
+ ++ instance \spad{ts+p} is required to be square-free.
+ augment: (P,List $) -> List $
+ ++ \spad{augment(p,lts)} returns the same as
+ ++ \spad{concat([augment(p,ts) for ts in lts])}
+ augment: (List P,$) -> List $
+ ++ \spad{augment(lp,ts)} returns \spad{ts} if \spad{empty? lp},
+ ++ \spad{augment(p,ts)} if \spad{lp = [p]}, otherwise
+ ++ \spad{augment(first lp, augment(rest lp, ts))}
+ augment: (List P,List $) -> List $
+ ++ \spad{augment(lp,lts)} returns the same as
+ ++ \spad{concat([augment(lp,ts) for ts in lts])}
+ internalAugment: (P, $) -> $
+ ++ \spad{internalAugment(p,ts)} assumes that \spad{augment(p,ts)}
+ ++ returns a singleton and returns it.
+ internalAugment: (List P, $) -> $
+ ++ \spad{internalAugment(lp,ts)} returns \spad{ts} if \spad{lp}
+ ++ is empty otherwise returns
+ ++ \spad{internalAugment(rest lp, internalAugment(first lp, ts))}
+ extend: (P,$) -> List $
+ ++ \spad{extend(p,ts)} assumes that \spad{p} is a non-constant
+ ++ polynomial whose main variable is greater than any variable
+ ++ of \spad{ts}. Then it returns a split of Kalkbrener
+ ++ of \spad{ts+p}. This may not be \spad{ts+p} itself, if for
+ ++ instance \spad{ts+p} is not a regular triangular set.
+ extend: (P, List $) -> List $
+ ++ \spad{extend(p,lts)} returns the same as
+ ++ \spad{concat([extend(p,ts) for ts in lts])|}
+ extend: (List P,$) -> List $
+ ++ \spad{extend(lp,ts)} returns \spad{ts} if \spad{empty? lp}
+ ++ \spad{extend(p,ts)} if \spad{lp = [p]} else
+ ++ \spad{extend(first lp, extend(rest lp, ts))}
+ extend: (List P,List $) -> List $
+ ++ \spad{extend(lp,lts)} returns the same as
+ ++ \spad{concat([extend(lp,ts) for ts in lts])|}
+ zeroSetSplit: (List P, Boolean) -> List $
+ ++ \spad{zeroSetSplit(lp,clos?)} returns \spad{lts} a split of Kalkbrener
+ ++ of the radical ideal associated with \spad{lp}.
+ ++ If \spad{clos?} is false, it is also a decomposition of the
+ ++ variety associated with \spad{lp} into the regular zero set of the \spad{ts} in \spad{lts}
+ ++ (or, in other words, a split of Lazard of this variety).
+ ++ See the example illustrating the \spadtype{RegularTriangularSet} constructor
+ ++ for more explanations about decompositions by means of regular triangular sets.
+
+ add
+
+ NNI ==> NonNegativeInteger
+ INT ==> Integer
+ LP ==> List P
+ PWT ==> Record(val : P, tower : $)
+ LpWT ==> Record(val : (List P), tower : $)
+ Split ==> List $
+ pack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+
+ purelyAlgebraic?(p: P, ts: $): Boolean ==
+ ground? p => true
+ not algebraic?(mvar(p),ts) => false
+ algebraicCoefficients?(p,ts)
+
+ purelyTranscendental?(p:P,ts:$): Boolean ==
+ empty? ts => true
+ lv : List V := variables(p)$P
+ while (not empty? lv) and (not algebraic?(first(lv),ts)) repeat lv := rest lv
+ empty? lv
+
+ purelyAlgebraicLeadingMonomial?(p: P, ts: $): Boolean ==
+ ground? p => true
+ algebraic?(mvar(p),ts) and purelyAlgebraicLeadingMonomial?(init(p), ts)
+
+ algebraicCoefficients?(p:P,ts:$): Boolean ==
+ ground? p => true
+ (not ground? init(p)) and not (algebraic?(mvar(init(p)),ts)) => false
+ algebraicCoefficients?(init(p),ts) =>
+ ground? tail(p) => true
+ mvar(tail(p)) = mvar(p) =>
+ algebraicCoefficients?(tail(p),ts)
+ algebraic?(mvar(tail(p)),ts) =>
+ algebraicCoefficients?(tail(p),ts)
+ false
+ false
+
+ if V has Finite
+ then
+ purelyAlgebraic?(ts: $): Boolean ==
+ empty? ts => true
+ size()$V = #ts => true
+ lp: LP := sort(infRittWu?,members(ts))
+ i: NonNegativeInteger := size()$V
+ for p in lp repeat
+ v: V := mvar(p)
+ (i = (lookup(v)$V)::NNI) =>
+ i := subtractIfCan(i,1)::NNI
+ univariate?(p)$pack =>
+ i := subtractIfCan(i,1)::NNI
+ not algebraicCoefficients?(p,collectUnder(ts,v)) =>
+ return false
+ i := subtractIfCan(i,1)::NNI
+ true
+
+ else
+
+ purelyAlgebraic?(ts: $): Boolean ==
+ empty? ts => true
+ v: V := mvar(ts)
+ p: P := select(ts,v)::P
+ ts := collectUnder(ts,v)
+ empty? ts => univariate?(p)$pack
+ not purelyAlgebraic?(ts) => false
+ algebraicCoefficients?(p,ts)
+
+ augment(p:P,lts:List $) ==
+ toSave: Split := []
+ while not empty? lts repeat
+ ts := first lts
+ lts := rest lts
+ toSave := concat(augment(p,ts),toSave)
+ toSave
+
+ augment(lp:LP,ts:$) ==
+ toSave: Split := [ts]
+ empty? lp => toSave
+ lp := sort(infRittWu?,lp)
+ while not empty? lp repeat
+ p := first lp
+ lp := rest lp
+ toSave := augment(p,toSave)
+ toSave
+
+ augment(lp:LP,lts:List $) ==
+ empty? lp => lts
+ toSave: Split := []
+ while not empty? lts repeat
+ ts := first lts
+ lts := rest lts
+ toSave := concat(augment(lp,ts),toSave)
+ toSave
+
+ extend(p:P,lts:List $) ==
+ toSave : Split := []
+ while not empty? lts repeat
+ ts := first lts
+ lts := rest lts
+ toSave := concat(extend(p,ts),toSave)
+ toSave
+
+ extend(lp:LP,ts:$) ==
+ toSave: Split := [ts]
+ empty? lp => toSave
+ lp := sort(infRittWu?,lp)
+ while not empty? lp repeat
+ p := first lp
+ lp := rest lp
+ toSave := extend(p,toSave)
+ toSave
+
+ extend(lp:LP,lts:List $) ==
+ empty? lp => lts
+ toSave: Split := []
+ while not empty? lts repeat
+ ts := first lts
+ lts := rest lts
+ toSave := concat(extend(lp,ts),toSave)
+ toSave
+
+ intersect(lp:LP,lts:List $): List $ ==
+ -- A VERY GENERAL default algorithm
+ (empty? lp) or (empty? lts) => lts
+ lp := [primitivePart(p) for p in lp]
+ lp := removeDuplicates lp
+ lp := remove(zero?,lp)
+ any?(ground?,lp) => []
+ toSee: List LpWT := [[lp,ts]$LpWT for ts in lts]
+ toSave: List $ := []
+ lp: LP
+ p: P
+ ts: $
+ lus: List $
+ while (not empty? toSee) repeat
+ lpwt := first toSee; toSee := rest toSee
+ lp := lpwt.val; ts := lpwt.tower
+ empty? lp => toSave := cons(ts, toSave)
+ p := first lp; lp := rest lp
+ lus := intersect(p,ts)
+ toSee := concat([[lp,us]$LpWT for us in lus], toSee)
+ toSave
+
+ intersect(lp: LP,ts: $): List $ ==
+ intersect(lp,[ts])
+
+ intersect(p: P,lts: List $): List $ ==
+ intersect([p],lts)
+
+@
+\section{package QCMPACK QuasiComponentPackage}
+<<package QCMPACK QuasiComponentPackage>>=
+)abbrev package QCMPACK QuasiComponentPackage
+++ Author: Marc Moreno Maza
+++ marc@nag.co.uk
+++ Date Created: 08/30/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See: `tosedom.spad'
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A package for removing redundant quasi-components and redundant
+++ branches when decomposing a variety by means of quasi-components
+++ of regular triangular sets. \newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+++ [2] M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+++ [3] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 3.
+
+QuasiComponentPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : RegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ LP ==> List P
+ PtoP ==> P -> P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Branch ==> Record(eq: List P, tower: TS, ineq: List P)
+ UBF ==> Union(Branch,"failed")
+ Split ==> List TS
+ Key ==> Record(left:TS, right:TS)
+ Entry ==> Boolean
+ H ==> TabulatedComputationPackage(Key, Entry)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+
+ Exports == with
+ startTable!: (S,S,S) -> Void
+ ++ \axiom{startTableGcd!(s1,s2,s3)}
+ ++ is an internal subroutine, exported only for developement.
+ stopTable!: () -> Void
+ ++ \axiom{stopTableGcd!()}
+ ++ is an internal subroutine, exported only for developement.
+ supDimElseRittWu?: (TS,TS) -> Boolean
+ ++ \axiom{supDimElseRittWu(ts,us)} returns true iff \axiom{ts}
+ ++ has less elements than \axiom{us} otherwise if \axiom{ts}
+ ++ has higher rank than \axiom{us} w.r.t. Riit and Wu ordering.
+ algebraicSort: Split -> Split
+ ++ \axiom{algebraicSort(lts)} sorts \axiom{lts} w.r.t
+ ++ \axiomOpFrom{supDimElseRittWu?}{QuasiComponentPackage}.
+ moreAlgebraic?: (TS,TS) -> Boolean
+ ++ \axiom{moreAlgebraic?(ts,us)} returns false iff \axiom{ts}
+ ++ and \axiom{us} are both empty, or \axiom{ts}
+ ++ has less elements than \axiom{us}, or some variable is
+ ++ algebraic w.r.t. \axiom{us} and is not w.r.t. \axiom{ts}.
+ subTriSet?: (TS,TS) -> Boolean
+ ++ \axiom{subTriSet?(ts,us)} returns true iff \axiom{ts} is
+ ++ a sub-set of \axiom{us}.
+ subPolSet?: (LP, LP) -> Boolean
+ ++ \axiom{subPolSet?(lp1,lp2)} returns true iff \axiom{lp1} is
+ ++ a sub-set of \axiom{lp2}.
+ internalSubPolSet?: (LP, LP) -> Boolean
+ ++ \axiom{internalSubPolSet?(lp1,lp2)} returns true iff \axiom{lp1} is
+ ++ a sub-set of \axiom{lp2} assuming that these lists are sorted
+ ++ increasingly w.r.t. \axiomOpFrom{infRittWu?}{RecursivePolynomialCategory}.
+ internalInfRittWu?: (LP, LP) -> Boolean
+ ++ \axiom{internalInfRittWu?(lp1,lp2)}
+ ++ is an internal subroutine, exported only for developement.
+ infRittWu?: (LP, LP) -> Boolean
+ ++ \axiom{infRittWu?(lp1,lp2)}
+ ++ is an internal subroutine, exported only for developement.
+ internalSubQuasiComponent?: (TS,TS) -> Union(Boolean,"failed")
+ ++ \axiom{internalSubQuasiComponent?(ts,us)} returns a boolean \spad{b} value
+ ++ if the fact that the regular zero set of \axiom{us} contains that of
+ ++ \axiom{ts} can be decided (and in that case \axiom{b} gives this
+ ++ inclusion) otherwise returns \axiom{"failed"}.
+ subQuasiComponent?: (TS,TS) -> Boolean
+ ++ \axiom{subQuasiComponent?(ts,us)} returns true iff
+ ++ \axiomOpFrom{internalSubQuasiComponent?}{QuasiComponentPackage}
+ ++ returs true.
+ subQuasiComponent?: (TS,Split) -> Boolean
+ ++ \axiom{subQuasiComponent?(ts,lus)} returns true iff
+ ++ \axiom{subQuasiComponent?(ts,us)} holds for one \spad{us} in \spad{lus}.
+ removeSuperfluousQuasiComponents: Split -> Split
+ ++ \axiom{removeSuperfluousQuasiComponents(lts)} removes from \axiom{lts}
+ ++ any \spad{ts} such that \axiom{subQuasiComponent?(ts,us)} holds for
+ ++ another \spad{us} in \axiom{lts}.
+ subCase?: (LpWT,LpWT) -> Boolean
+ ++ \axiom{subCase?(lpwt1,lpwt2)}
+ ++ is an internal subroutine, exported only for developement.
+ removeSuperfluousCases: List LpWT -> List LpWT
+ ++ \axiom{removeSuperfluousCases(llpwt)}
+ ++ is an internal subroutine, exported only for developement.
+ prepareDecompose: (LP, List(TS),B,B) -> List Branch
+ ++ \axiom{prepareDecompose(lp,lts,b1,b2)}
+ ++ is an internal subroutine, exported only for developement.
+ branchIfCan: (LP,TS,LP,B,B,B,B,B) -> Union(Branch,"failed")
+ ++ \axiom{branchIfCan(leq,ts,lineq,b1,b2,b3,b4,b5)}
+ ++ is an internal subroutine, exported only for developement.
+
+ Implementation == add
+
+ squareFreeFactors(lp: LP): LP ==
+ lsflp: LP := []
+ for p in lp repeat
+ lsfp := squareFreeFactors(p)$polsetpack
+ lsflp := concat(lsfp,lsflp)
+ sort(infRittWu?,removeDuplicates lsflp)
+
+ startTable!(ok: S, ko: S, domainName: S): Void ==
+ initTable!()$H
+ if (not empty? ok) and (not empty? ko) then printInfo!(ok,ko)$H
+ if (not empty? domainName) then startStats!(domainName)$H
+ void()
+
+ stopTable!(): Void ==
+ if makingStats?()$H then printStats!()$H
+ clearTable!()$H
+
+ supDimElseRittWu? (ts:TS,us:TS): Boolean ==
+ #ts < #us => true
+ #ts > #us => false
+ lp1 :LP := members(ts)
+ lp2 :LP := members(us)
+ while (not empty? lp1) and (not infRittWu?(first(lp2),first(lp1))) repeat
+ lp1 := rest lp1
+ lp2 := rest lp2
+ not empty? lp1
+
+ algebraicSort (lts:Split): Split ==
+ lts := removeDuplicates lts
+ sort(supDimElseRittWu?,lts)
+
+ moreAlgebraic?(ts:TS,us:TS): Boolean ==
+ empty? ts => empty? us
+ empty? us => true
+ #ts < #us => false
+ for p in (members us) repeat
+ not algebraic?(mvar(p),ts) => return false
+ true
+
+ subTriSet?(ts:TS,us:TS): Boolean ==
+ empty? ts => true
+ empty? us => false
+ mvar(ts) > mvar(us) => false
+ mvar(ts) < mvar(us) => subTriSet?(ts,rest(us)::TS)
+ first(ts)::P = first(us)::P => subTriSet?(rest(ts)::TS,rest(us)::TS)
+ false
+
+ internalSubPolSet?(lp1: LP, lp2: LP): Boolean ==
+ empty? lp1 => true
+ empty? lp2 => false
+ associates?(first lp1, first lp2) =>
+ internalSubPolSet?(rest lp1, rest lp2)
+ infRittWu?(first lp1, first lp2) => false
+ internalSubPolSet?(lp1, rest lp2)
+
+ subPolSet?(lp1: LP, lp2: LP): Boolean ==
+ lp1 := sort(infRittWu?, lp1)
+ lp2 := sort(infRittWu?, lp2)
+ internalSubPolSet?(lp1,lp2)
+
+ infRittWu?(lp1: LP, lp2: LP): Boolean ==
+ lp1 := sort(infRittWu?, lp1)
+ lp2 := sort(infRittWu?, lp2)
+ internalInfRittWu?(lp1,lp2)
+
+ internalInfRittWu?(lp1: LP, lp2: LP): Boolean ==
+ empty? lp1 => not empty? lp2
+ empty? lp2 => false
+ infRittWu?(first lp1, first lp2)$P => true
+ infRittWu?(first lp2, first lp1)$P => false
+ infRittWu?(rest lp1, rest lp2)$$
+
+ subCase? (lpwt1:LpWT,lpwt2:LpWT): Boolean ==
+ -- ASSUME lpwt.{1,2}.val is sorted w.r.t. infRittWu?
+ not internalSubPolSet?(lpwt2.val, lpwt1.val) => false
+ subQuasiComponent?(lpwt1.tower,lpwt2.tower)
+
+ internalSubQuasiComponent?(ts:TS,us:TS): Union(Boolean,"failed") ==
+ -- "failed" is false iff saturate(us) is radical
+ subTriSet?(us,ts) => true
+ not moreAlgebraic?(ts,us) => false::Union(Boolean,"failed")
+ for p in (members us) repeat
+ mdeg(p) < mdeg(select(ts,mvar(p))::P) =>
+ return("failed"::Union(Boolean,"failed"))
+ for p in (members us) repeat
+ not zero? initiallyReduce(p,ts) =>
+ return("failed"::Union(Boolean,"failed"))
+ lsfp := squareFreeFactors(initials us)
+ for p in lsfp repeat
+ not invertible?(p,ts)@B =>
+ return(false::Union(Boolean,"failed"))
+ true::Union(Boolean,"failed")
+
+ subQuasiComponent?(ts:TS,us:TS): Boolean ==
+ k: Key := [ts, us]
+ e := extractIfCan(k)$H
+ e case Entry => e::Entry
+ ubf: Union(Boolean,"failed") := internalSubQuasiComponent?(ts,us)
+ b: Boolean := (ubf case Boolean) and (ubf::Boolean)
+ insert!(k,b)$H
+ b
+
+ subQuasiComponent?(ts:TS,lus:Split): Boolean ==
+ for us in lus repeat
+ subQuasiComponent?(ts,us)@B => return true
+ false
+
+ removeSuperfluousCases (cases:List LpWT) ==
+ #cases < 2 => cases
+ toSee := sort(supDimElseRittWu?(#1.tower,#2.tower),cases)
+ lpwt1,lpwt2 : LpWT
+ toSave,headmaxcases,maxcases,copymaxcases : List LpWT
+ while not empty? toSee repeat
+ lpwt1 := first toSee
+ toSee := rest toSee
+ toSave := []
+ for lpwt2 in toSee repeat
+ if subCase?(lpwt1,lpwt2)
+ then
+ lpwt1 := lpwt2
+ else
+ if not subCase?(lpwt2,lpwt1)
+ then
+ toSave := cons(lpwt2,toSave)
+ if empty? maxcases
+ then
+ headmaxcases := [lpwt1]
+ maxcases := headmaxcases
+ else
+ copymaxcases := maxcases
+ while (not empty? copymaxcases) and _
+ (not subCase?(lpwt1,first(copymaxcases))) repeat
+ copymaxcases := rest copymaxcases
+ if empty? copymaxcases
+ then
+ setrest!(headmaxcases,[lpwt1])
+ headmaxcases := rest headmaxcases
+ toSee := reverse toSave
+ maxcases
+
+ removeSuperfluousQuasiComponents(lts: Split): Split ==
+ lts := removeDuplicates lts
+ #lts < 2 => lts
+ toSee := algebraicSort lts
+ toSave,headmaxlts,maxlts,copymaxlts : Split
+ while not empty? toSee repeat
+ ts := first toSee
+ toSee := rest toSee
+ toSave := []
+ for us in toSee repeat
+ if subQuasiComponent?(ts,us)@B
+ then
+ ts := us
+ else
+ if not subQuasiComponent?(us,ts)@B
+ then
+ toSave := cons(us,toSave)
+ if empty? maxlts
+ then
+ headmaxlts := [ts]
+ maxlts := headmaxlts
+ else
+ copymaxlts := maxlts
+ while (not empty? copymaxlts) and _
+ (not subQuasiComponent?(ts,first(copymaxlts))@B) repeat
+ copymaxlts := rest copymaxlts
+ if empty? copymaxlts
+ then
+ setrest!(headmaxlts,[ts])
+ headmaxlts := rest headmaxlts
+ toSee := reverse toSave
+ algebraicSort maxlts
+
+ removeAssociates (lp:LP):LP ==
+ removeDuplicates [primitivePart(p) for p in lp]
+
+ branchIfCan(leq: LP,ts: TS,lineq: LP, b1:B,b2:B,b3:B,b4:B,b5:B):UBF ==
+ -- ASSUME pols in leq are squarefree and mainly primitive
+ -- if b1 then CLEAN UP leq
+ -- if b2 then CLEAN UP lineq
+ -- if b3 then SEARCH for ZERO in lineq with leq
+ -- if b4 then SEARCH for ZERO in lineq with ts
+ -- if b5 then SEARCH for ONE in leq with lineq
+ if b1
+ then
+ leq := removeAssociates(leq)
+ leq := remove(zero?,leq)
+ any?(ground?,leq) =>
+ return("failed"::Union(Branch,"failed"))
+ if b2
+ then
+ any?(zero?,lineq) =>
+ return("failed"::Union(Branch,"failed"))
+ lineq := removeRedundantFactors(lineq)$polsetpack
+ if b3
+ then
+ ps: PS := construct(leq)$PS
+ for q in lineq repeat
+ zero? remainder(q,ps).polnum =>
+ return("failed"::Union(Branch,"failed"))
+ (empty? leq) or (empty? lineq) => ([leq, ts, lineq]$Branch)::UBF
+ if b4
+ then
+ for q in lineq repeat
+ zero? initiallyReduce(q,ts) =>
+ return("failed"::Union(Branch,"failed"))
+ if b5
+ then
+ newleq: LP := []
+ for p in leq repeat
+ for q in lineq repeat
+ if mvar(p) = mvar(q)
+ then
+ g := gcd(p,q)
+ newp := (p exquo g)::P
+ ground? newp =>
+ return("failed"::Union(Branch,"failed"))
+ newleq := cons(newp,newleq)
+ else
+ newleq := cons(p,newleq)
+ leq := newleq
+ leq := sort(infRittWu?, removeDuplicates leq)
+ ([leq, ts, lineq]$Branch)::UBF
+
+ prepareDecompose(lp: LP, lts: List(TS), b1: B, b2: B): List Branch ==
+ -- if b1 then REMOVE REDUNDANT COMPONENTS in lts
+ -- if b2 then SPLIT the input system with squareFree
+ lp := sort(infRittWu?, remove(zero?,removeAssociates(lp)))
+ any?(ground?,lp) => []
+ empty? lts => []
+ if b1 then lts := removeSuperfluousQuasiComponents lts
+ not b2 =>
+ [[lp,ts,squareFreeFactors(initials ts)]$Branch for ts in lts]
+ toSee: List Branch
+ lq: LP := []
+ toSee := [[lq,ts,squareFreeFactors(initials ts)]$Branch for ts in lts]
+ empty? lp => toSee
+ for p in lp repeat
+ lsfp := squareFreeFactors(p)$polsetpack
+ branches: List Branch := []
+ lq := []
+ for f in lsfp repeat
+ for branch in toSee repeat
+ leq : LP := branch.eq
+ ts := branch.tower
+ lineq : LP := branch.ineq
+ ubf1: UBF := branchIfCan(leq,ts,lq,false,false,true,true,true)@UBF
+ ubf1 case "failed" => "leave"
+ ubf2: UBF := branchIfCan([f],ts,lineq,false,false,true,true,true)@UBF
+ ubf2 case "failed" => "leave"
+ leq := sort(infRittWu?,removeDuplicates concat(ubf1.eq,ubf2.eq))
+ lineq := sort(infRittWu?,removeDuplicates concat(ubf1.ineq,ubf2.ineq))
+ newBranch := branchIfCan(leq,ts,lineq,false,false,false,false,false)
+ branches:= cons(newBranch::Branch,branches)
+ lq := cons(f,lq)
+ toSee := branches
+ sort(supDimElseRittWu?(#1.tower,#2.tower),toSee)
+
+@
+\section{package RSETGCD RegularTriangularSetGcdPackage}
+<<package RSETGCD RegularTriangularSetGcdPackage>>=
+)abbrev package RSETGCD RegularTriangularSetGcdPackage
+++ Author: Marc Moreno Maza (marc@nag.co.uk)
+++ Date Created: 08/30/1998
+++ Date Last Updated: 12/15/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ An internal package for computing gcds and resultants of univariate
+++ polynomials with coefficients in a tower of simple extensions of a field.\newline
+++ References :
+++ [1] M. MORENO MAZA and R. RIOBOO "Computations of gcd over
+++ algebraic towers of simple extensions" In proceedings of AAECC11
+++ Paris, 1995.
+++ [2] M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+++ [3] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 4.
+
+RegularTriangularSetGcdPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : RegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ LP ==> List P
+ PtoP ==> P -> P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Branch ==> Record(eq: List P, tower: TS, ineq: List P)
+ UBF ==> Union(Branch,"failed")
+ Split ==> List TS
+ KeyGcd ==> Record(arg1: P, arg2: P, arg3: TS, arg4: B)
+ EntryGcd ==> List PWT
+ HGcd ==> TabulatedComputationPackage(KeyGcd, EntryGcd)
+ KeyInvSet ==> Record(arg1: P, arg3: TS)
+ EntryInvSet ==> List TS
+ HInvSet ==> TabulatedComputationPackage(KeyInvSet, EntryInvSet)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppack ==> QuasiComponentPackage(R,E,V,P,TS)
+
+ Exports == with
+ startTableGcd!: (S,S,S) -> Void
+ ++ \axiom{startTableGcd!(s1,s2,s3)}
+ ++ is an internal subroutine, exported only for developement.
+ stopTableGcd!: () -> Void
+ ++ \axiom{stopTableGcd!()}
+ ++ is an internal subroutine, exported only for developement.
+ startTableInvSet!: (S,S,S) -> Void
+ ++ \axiom{startTableInvSet!(s1,s2,s3)}
+ ++ is an internal subroutine, exported only for developement.
+ stopTableInvSet!: () -> Void
+ ++ \axiom{stopTableInvSet!()} is an internal subroutine,
+ ++ exported only for developement.
+ prepareSubResAlgo: (P,P,TS) -> List LpWT
+ ++ \axiom{prepareSubResAlgo(p1,p2,ts)}
+ ++ is an internal subroutine, exported only for developement.
+ internalLastSubResultant: (P,P,TS,B,B) -> List PWT
+ ++ \axiom{internalLastSubResultant(p1,p2,ts,inv?,break?)}
+ ++ is an internal subroutine, exported only for developement.
+ internalLastSubResultant: (List LpWT,V,B) -> List PWT
+ ++ \axiom{internalLastSubResultant(lpwt,v,flag)} is an internal
+ ++ subroutine, exported only for developement.
+ integralLastSubResultant: (P,P,TS) -> List PWT
+ ++ \axiom{integralLastSubResultant(p1,p2,ts)}
+ ++ is an internal subroutine, exported only for developement.
+ toseLastSubResultant: (P,P,TS) -> List PWT
+ ++ \axiom{toseLastSubResultant(p1,p2,ts)} has the same specifications as
+ ++ \axiomOpFrom{lastSubResultant}{RegularTriangularSetCategory}.
+ toseInvertible?: (P,TS) -> B
+ ++ \axiom{toseInvertible?(p1,p2,ts)} has the same specifications as
+ ++ \axiomOpFrom{invertible?}{RegularTriangularSetCategory}.
+ toseInvertible?: (P,TS) -> List BWT
+ ++ \axiom{toseInvertible?(p1,p2,ts)} has the same specifications as
+ ++ \axiomOpFrom{invertible?}{RegularTriangularSetCategory}.
+ toseInvertibleSet: (P,TS) -> Split
+ ++ \axiom{toseInvertibleSet(p1,p2,ts)} has the same specifications as
+ ++ \axiomOpFrom{invertibleSet}{RegularTriangularSetCategory}.
+ toseSquareFreePart: (P,TS) -> List PWT
+ ++ \axiom{toseSquareFreePart(p,ts)} has the same specifications as
+ ++ \axiomOpFrom{squareFreePart}{RegularTriangularSetCategory}.
+
+ Implementation == add
+
+ startTableGcd!(ok: S, ko: S, domainName: S): Void ==
+ initTable!()$HGcd
+ printInfo!(ok,ko)$HGcd
+ startStats!(domainName)$HGcd
+ void()
+
+ stopTableGcd!(): Void ==
+ if makingStats?()$HGcd then printStats!()$HGcd
+ clearTable!()$HGcd
+
+ startTableInvSet!(ok: S, ko: S, domainName: S): Void ==
+ initTable!()$HInvSet
+ printInfo!(ok,ko)$HInvSet
+ startStats!(domainName)$HInvSet
+ void()
+
+ stopTableInvSet!(): Void ==
+ if makingStats?()$HInvSet then printStats!()$HInvSet
+ clearTable!()$HInvSet
+
+ toseInvertible?(p:P,ts:TS): Boolean ==
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => false
+ normalized?(q,ts) => true
+ v := mvar(q)
+ not algebraic?(v,ts) =>
+ toCheck: List BWT := toseInvertible?(p,ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val = false => return false
+ return true
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ lgwt := internalLastSubResultant(ts_v,q,ts_v_-,false,true)
+ for gwt in lgwt repeat
+ g := gwt.val;
+ (not ground? g) and (mvar(g) = v) =>
+ return false
+ true
+
+ toseInvertible?(p:P,ts:TS): List BWT ==
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => [[false,ts]$BWT]
+ normalized?(q,ts) => [[true,ts]$BWT]
+ v := mvar(q)
+ not algebraic?(v,ts) =>
+ lbwt: List BWT := []
+ toCheck: List BWT := toseInvertible?(init(q),ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val => lbwt := cons(bwt,lbwt)
+ newq := removeZero(q,bwt.tower)
+ zero? newq => lbwt := cons(bwt,lbwt)
+ lbwt := concat(toseInvertible?(newq,bwt.tower)@(List BWT), lbwt)
+ return lbwt
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ lgwt := internalLastSubResultant(ts_v,q,ts_v_-,false,false)
+ lbwt: List BWT := []
+ for gwt in lgwt repeat
+ g := gwt.val; ts := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ ts := internalAugment(ts_v,ts)
+ ts := internalAugment(members(ts_v_+),ts)
+ lbwt := cons([true, ts]$BWT,lbwt)
+ g := mainPrimitivePart g
+ ts_g := internalAugment(g,ts)
+ ts_g := internalAugment(members(ts_v_+),ts_g)
+ -- USE internalAugment with parameters ??
+ lbwt := cons([false, ts_g]$BWT,lbwt)
+ h := lazyPquo(ts_v,g)
+ (ground? h) or (mvar(h) < v) => "leave"
+ h := mainPrimitivePart h
+ ts_h := internalAugment(h,ts)
+ ts_h := internalAugment(members(ts_v_+),ts_h)
+ -- USE internalAugment with parameters ??
+ -- CAN BE OPTIMIZED if the input tower is separable
+ inv := toseInvertible?(q,ts_h)@(List BWT)
+ lbwt := concat([bwt for bwt in inv | bwt.val],lbwt)
+ sort(#1.val < #2.val,lbwt)
+
+ toseInvertibleSet(p:P,ts:TS): Split ==
+ k: KeyInvSet := [p,ts]
+ e := extractIfCan(k)$HInvSet
+ e case EntryInvSet => e::EntryInvSet
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => []
+ normalized?(q,ts) => [ts]
+ v := mvar(q)
+ toSave: Split := []
+ not algebraic?(v,ts) =>
+ toCheck: List BWT := toseInvertible?(init(q),ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val => toSave := cons(bwt.tower,toSave)
+ newq := removeZero(q,bwt.tower)
+ zero? newq => "leave"
+ toSave := concat(toseInvertibleSet(newq,bwt.tower), toSave)
+ toSave := removeDuplicates toSave
+ return algebraicSort(toSave)$quasicomppack
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ lgwt := internalLastSubResultant(ts_v,q,ts_v_-,false,false)
+ for gwt in lgwt repeat
+ g := gwt.val; ts := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ ts := internalAugment(ts_v,ts)
+ ts := internalAugment(members(ts_v_+),ts)
+ toSave := cons(ts,toSave)
+ g := mainPrimitivePart g
+ h := lazyPquo(ts_v,g)
+ h := mainPrimitivePart h
+ (ground? h) or (mvar(h) < v) => "leave"
+ ts_h := internalAugment(h,ts)
+ ts_h := internalAugment(members(ts_v_+),ts_h)
+ inv := toseInvertibleSet(q,ts_h)
+ toSave := removeDuplicates concat(inv,toSave)
+ toSave := algebraicSort(toSave)$quasicomppack
+ insert!(k,toSave)$HInvSet
+ toSave
+
+ toseSquareFreePart_wip(p:P, ts: TS): List PWT ==
+ -- ASSUME p is not constant and mvar(p) > mvar(ts)
+ -- ASSUME init(p) is invertible w.r.t. ts
+ -- ASSUME p is mainly primitive
+-- one? mdeg(p) => [[p,ts]$PWT]
+ mdeg(p) = 1 => [[p,ts]$PWT]
+ v := mvar(p)$P
+ q: P := mainPrimitivePart D(p,v)
+ lgwt: List PWT := internalLastSubResultant(p,q,ts,true,false)
+ lpwt : List PWT := []
+ sfp : P
+ for gwt in lgwt repeat
+ g := gwt.val; us := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ lpwt := cons([p,us],lpwt)
+ g := mainPrimitivePart g
+ sfp := lazyPquo(p,g)
+ sfp := mainPrimitivePart stronglyReduce(sfp,us)
+ lpwt := cons([sfp,us],lpwt)
+ lpwt
+
+ toseSquareFreePart_base(p:P, ts: TS): List PWT == [[p,ts]$PWT]
+
+ toseSquareFreePart(p:P, ts: TS): List PWT == toseSquareFreePart_wip(p,ts)
+
+ prepareSubResAlgo(p1:P,p2:P,ts:TS): List LpWT ==
+ -- ASSUME mvar(p1) = mvar(p2) > mvar(ts) and mdeg(p1) >= mdeg(p2)
+ -- ASSUME init(p1) invertible modulo ts !!!
+ toSee: List LpWT := [[[p1,p2],ts]$LpWT]
+ toSave: List LpWT := []
+ v := mvar(p1)
+ while (not empty? toSee) repeat
+ lpwt := first toSee; toSee := rest toSee
+ p1 := lpwt.val.1; p2 := lpwt.val.2
+ ts := lpwt.tower
+ lbwt := toseInvertible?(leadingCoefficient(p2,v),ts)@(List BWT)
+ for bwt in lbwt repeat
+ (bwt.val = true) and (degree(p2,v) > 0) =>
+ p3 := prem(p1, -p2)
+ s: P := init(p2)**(mdeg(p1) - mdeg(p2))::N
+ toSave := cons([[p2,p3,s],bwt.tower]$LpWT,toSave)
+ -- p2 := initiallyReduce(p2,bwt.tower)
+ newp2 := primitivePart initiallyReduce(p2,bwt.tower)
+ (bwt.val = true) =>
+ -- toSave := cons([[p2,0,1],bwt.tower]$LpWT,toSave)
+ toSave := cons([[p2,0,1],bwt.tower]$LpWT,toSave)
+ -- zero? p2 =>
+ zero? newp2 =>
+ toSave := cons([[p1,0,1],bwt.tower]$LpWT,toSave)
+ -- toSee := cons([[p1,p2],ts]$LpWT,toSee)
+ toSee := cons([[p1,newp2],bwt.tower]$LpWT,toSee)
+ toSave
+
+ integralLastSubResultant(p1:P,p2:P,ts:TS): List PWT ==
+ -- ASSUME mvar(p1) = mvar(p2) > mvar(ts) and mdeg(p1) >= mdeg(p2)
+ -- ASSUME p1 and p2 have no algebraic coefficients
+ lsr := lastSubResultant(p1, p2)
+ ground?(lsr) => [[lsr,ts]$PWT]
+ mvar(lsr) < mvar(p1) => [[lsr,ts]$PWT]
+ gi1i2 := gcd(init(p1),init(p2))
+ ex: Union(P,"failed") := (gi1i2 * lsr) exquo$P init(lsr)
+ ex case "failed" => [[lsr,ts]$PWT]
+ [[ex::P,ts]$PWT]
+
+ internalLastSubResultant(p1:P,p2:P,ts:TS,b1:B,b2:B): List PWT ==
+ -- ASSUME mvar(p1) = mvar(p2) > mvar(ts) and mdeg(p1) >= mdeg(p2)
+ -- if b1 ASSUME init(p2) invertible w.r.t. ts
+ -- if b2 BREAK with the first non-trivial gcd
+ k: KeyGcd := [p1,p2,ts,b2]
+ e := extractIfCan(k)$HGcd
+ e case EntryGcd => e::EntryGcd
+ toSave: List PWT
+ empty? ts =>
+ toSave := integralLastSubResultant(p1,p2,ts)
+ insert!(k,toSave)$HGcd
+ return toSave
+ toSee: List LpWT
+ if b1
+ then
+ p3 := prem(p1, -p2)
+ s: P := init(p2)**(mdeg(p1) - mdeg(p2))::N
+ toSee := [[[p2,p3,s],ts]$LpWT]
+ else
+ toSee := prepareSubResAlgo(p1,p2,ts)
+ toSave := internalLastSubResultant(toSee,mvar(p1),b2)
+ insert!(k,toSave)$HGcd
+ toSave
+
+ internalLastSubResultant(llpwt: List LpWT,v:V,b2:B): List PWT ==
+ toReturn: List PWT := []; toSee: List LpWT;
+ while (not empty? llpwt) repeat
+ toSee := llpwt; llpwt := []
+ -- CONSIDER FIRST the vanishing current last subresultant
+ for lpwt in toSee repeat
+ p1 := lpwt.val.1; p2 := lpwt.val.2; s := lpwt.val.3; ts := lpwt.tower
+ lbwt := toseInvertible?(leadingCoefficient(p2,v),ts)@(List BWT)
+ for bwt in lbwt repeat
+ bwt.val = false =>
+ toReturn := cons([p1,bwt.tower]$PWT, toReturn)
+ b2 and positive?(degree(p1,v)) => return toReturn
+ llpwt := cons([[p1,p2,s],bwt.tower]$LpWT, llpwt)
+ empty? llpwt => "leave"
+ -- CONSIDER NOW the branches where the computations continue
+ toSee := llpwt; llpwt := []
+ lpwt := first toSee; toSee := rest toSee
+ p1 := lpwt.val.1; p2 := lpwt.val.2; s := lpwt.val.3
+ delta: N := (mdeg(p1) - degree(p2,v))::N
+ p3: P := LazardQuotient2(p2, leadingCoefficient(p2,v), s, delta)
+ zero?(degree(p3,v)) =>
+ toReturn := cons([p3,lpwt.tower]$PWT, toReturn)
+ for lpwt in toSee repeat
+ toReturn := cons([p3,lpwt.tower]$PWT, toReturn)
+ (p1, p2) := (p3, next_subResultant2(p1, p2, p3, s))
+ s := leadingCoefficient(p1,v)
+ llpwt := cons([[p1,p2,s],lpwt.tower]$LpWT, llpwt)
+ for lpwt in toSee repeat
+ llpwt := cons([[p1,p2,s],lpwt.tower]$LpWT, llpwt)
+ toReturn
+
+ toseLastSubResultant(p1:P,p2:P,ts:TS): List PWT ==
+ ground? p1 =>
+ error"in toseLastSubResultantElseSplit$TOSEGCD : bad #1"
+ ground? p2 =>
+ error"in toseLastSubResultantElseSplit$TOSEGCD : bad #2"
+ not (mvar(p2) = mvar(p1)) =>
+ error"in toseLastSubResultantElseSplit$TOSEGCD : bad #2"
+ algebraic?(mvar(p1),ts) =>
+ error"in toseLastSubResultantElseSplit$TOSEGCD : bad #1"
+ not initiallyReduced?(p1,ts) =>
+ error"in toseLastSubResultantElseSplit$TOSEGCD : bad #1"
+ not initiallyReduced?(p2,ts) =>
+ error"in toseLastSubResultantElseSplit$TOSEGCD : bad #2"
+ purelyTranscendental?(p1,ts) and purelyTranscendental?(p2,ts) =>
+ integralLastSubResultant(p1,p2,ts)
+ if mdeg(p1) < mdeg(p2) then
+ (p1, p2) := (p2, p1)
+ if odd?(mdeg(p1)) and odd?(mdeg(p2)) then p2 := - p2
+ internalLastSubResultant(p1,p2,ts,false,false)
+
+@
+\section{package RSDCMPK RegularSetDecompositionPackage}
+<<package RSDCMPK RegularSetDecompositionPackage>>=
+)abbrev package RSDCMPK RegularSetDecompositionPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 09/16/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A package providing a new algorithm for solving polynomial systems
+++ by means of regular chains. Two ways of solving are proposed:
+++ in the sense of Zariski closure (like in Kalkbrener's algorithm)
+++ or in the sense of the regular zeros (like in Wu, Wang or Lazard
+++ methods). This algorithm is valid for nay type
+++ of regular set. It does not care about the way a polynomial is
+++ added in an regular set, or how two quasi-components are compared
+++ (by an inclusion-test), or how the invertibility test is made in
+++ the tower of simple extensions associated with a regular set.
+++ These operations are realized respectively by the domain \spad{TS}
+++ and the packages \axiomType{QCMPACK}(R,E,V,P,TS) and \axiomType{RSETGCD}(R,E,V,P,TS).
+++ The same way it does not care about the way univariate polynomial
+++ gcd (with coefficients in the tower of simple extensions associated
+++ with a regular set) are computed. The only requirement is that these
+++ gcd need to have invertible initials (normalized or not).
+++ WARNING. There is no need for a user to call diectly any operation
+++ of this package since they can be accessed by the domain \axiom{TS}.
+++ Thus, the operations of this package are not documented.\newline
+++ References :
+++ [1] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 5. Same as 4 but Does NOT use any unproved criteria.
+
+RegularSetDecompositionPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : RegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Wip ==> Record(done: Split, todo: List LpWT)
+ Branch ==> Record(eq: List P, tower: TS, ineq: List P)
+ UBF ==> Union(Branch,"failed")
+ Split ==> List TS
+ iprintpack ==> InternalPrintPackage()
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppack ==> QuasiComponentPackage(R,E,V,P,TS)
+ regsetgcdpack ==> RegularTriangularSetGcdPackage(R,E,V,P,TS)
+
+ Exports == with
+
+ KrullNumber: (LP, Split) -> N
+ numberOfVariables: (LP, Split) -> N
+ algebraicDecompose: (P,TS,B) -> Record(done: Split, todo: List LpWT)
+ transcendentalDecompose: (P,TS,N) -> Record(done: Split, todo: List LpWT)
+ transcendentalDecompose: (P,TS) -> Record(done: Split, todo: List LpWT)
+ internalDecompose: (P,TS,N,B) -> Record(done: Split, todo: List LpWT)
+ internalDecompose: (P,TS,N) -> Record(done: Split, todo: List LpWT)
+ internalDecompose: (P,TS) -> Record(done: Split, todo: List LpWT)
+ decompose: (LP, Split, B, B) -> Split
+ decompose: (LP, Split, B, B, B, B, B) -> Split
+ upDateBranches: (LP,Split,List LpWT,Wip,N) -> List LpWT
+ convert: Record(val: List P,tower: TS) -> String
+ printInfo: (List Record(val: List P,tower: TS), N) -> Void
+
+ Implementation == add
+
+ KrullNumber(lp: LP, lts: Split): N ==
+ ln: List N := [#(ts) for ts in lts]
+ n := #lp + reduce(max,ln)
+
+ numberOfVariables(lp: LP, lts: Split): N ==
+ lv: List V := variables([lp]$PS)
+ for ts in lts repeat lv := concat(variables(ts), lv)
+ # removeDuplicates(lv)
+
+ algebraicDecompose(p: P, ts: TS, clos?: B): Record(done: Split, todo: List LpWT) ==
+ ground? p =>
+ error " in algebraicDecompose$REGSET: should never happen !"
+ v := mvar(p); n := #ts
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ ts_v := select(ts,v)::P
+ if mdeg(p) < mdeg(ts_v)
+ then
+ lgwt := internalLastSubResultant(ts_v,p,ts_v_-,true,false)$regsetgcdpack
+ else
+ lgwt := internalLastSubResultant(p,ts_v,ts_v_-,true,false)$regsetgcdpack
+ lts: Split := []
+ llpwt: List LpWT := []
+ for gwt in lgwt repeat
+ g := gwt.val; us := gwt.tower
+ zero? g =>
+ error " in algebraicDecompose$REGSET: should never happen !!"
+ ground? g => "leave"
+ if mvar(g) = v then lts := concat(augment(members(ts_v_+),augment(g,us)),lts)
+ h := leadingCoefficient(g,v)
+ b: Boolean := purelyAlgebraic?(us)
+ lsfp := squareFreeFactors(h)$polsetpack
+ lus := augment(members(ts_v_+),augment(ts_v,us)@Split)
+ for f in lsfp repeat
+ ground? f => "leave"
+ b and purelyAlgebraic?(f,us) => "leave"
+ for vs in lus repeat
+ llpwt := cons([[f,p],vs]$LpWT, llpwt)
+ [lts,llpwt]
+
+ transcendentalDecompose(p: P, ts: TS,bound: N): Record(done: Split, todo: List LpWT) ==
+ lts: Split
+ if #ts < bound
+ then
+ lts := augment(p,ts)
+ else
+ lts := []
+ llpwt: List LpWT := []
+ [lts,llpwt]
+
+ transcendentalDecompose(p: P, ts: TS): Record(done: Split, todo: List LpWT) ==
+ lts: Split:= augment(p,ts)
+ llpwt: List LpWT := []
+ [lts,llpwt]
+
+ internalDecompose(p: P, ts: TS,bound: N,clos?:B): Record(done: Split, todo: List LpWT) ==
+ clos? => internalDecompose(p,ts,bound)
+ internalDecompose(p,ts)
+
+ internalDecompose(p: P, ts: TS,bound: N): Record(done: Split, todo: List LpWT) ==
+ -- ASSUME p not constant
+ llpwt: List LpWT := []
+ lts: Split := []
+ -- EITHER mvar(p) is null
+ if (not zero? tail(p)) and (not ground? (lmp := leastMonomial(p)))
+ then
+ llpwt := cons([[mvar(p)::P],ts]$LpWT,llpwt)
+ p := (p exquo lmp)::P
+ ip := squareFreePart init(p); tp := tail p
+ p := mainPrimitivePart p
+ -- OR init(p) is null or not
+ lbwt := invertible?(ip,ts)@(List BWT)
+ for bwt in lbwt repeat
+ bwt.val =>
+ if algebraic?(mvar(p),bwt.tower)
+ then
+ rsl := algebraicDecompose(p,bwt.tower,true)
+ else
+ rsl := transcendentalDecompose(p,bwt.tower,bound)
+ lts := concat(rsl.done,lts)
+ llpwt := concat(rsl.todo,llpwt)
+ -- purelyAlgebraicLeadingMonomial?(ip,bwt.tower) => "leave" -- UNPROVED CRITERIA
+ purelyAlgebraic?(ip,bwt.tower) and purelyAlgebraic?(bwt.tower) => "leave" -- SAFE
+ (not ground? ip) =>
+ zero? tp => llpwt := cons([[ip],bwt.tower]$LpWT, llpwt)
+ (not ground? tp) => llpwt := cons([[ip,tp],bwt.tower]$LpWT, llpwt)
+ riv := removeZero(ip,bwt.tower)
+ (zero? riv) =>
+ zero? tp => lts := cons(bwt.tower,lts)
+ (not ground? tp) => llpwt := cons([[tp],bwt.tower]$LpWT, llpwt)
+ llpwt := cons([[riv * mainMonomial(p) + tp],bwt.tower]$LpWT, llpwt)
+ [lts,llpwt]
+
+ internalDecompose(p: P, ts: TS): Record(done: Split, todo: List LpWT) ==
+ -- ASSUME p not constant
+ llpwt: List LpWT := []
+ lts: Split := []
+ -- EITHER mvar(p) is null
+ if (not zero? tail(p)) and (not ground? (lmp := leastMonomial(p)))
+ then
+ llpwt := cons([[mvar(p)::P],ts]$LpWT,llpwt)
+ p := (p exquo lmp)::P
+ ip := squareFreePart init(p); tp := tail p
+ p := mainPrimitivePart p
+ -- OR init(p) is null or not
+ lbwt := invertible?(ip,ts)@(List BWT)
+ for bwt in lbwt repeat
+ bwt.val =>
+ if algebraic?(mvar(p),bwt.tower)
+ then
+ rsl := algebraicDecompose(p,bwt.tower,false)
+ else
+ rsl := transcendentalDecompose(p,bwt.tower)
+ lts := concat(rsl.done,lts)
+ llpwt := concat(rsl.todo,llpwt)
+ purelyAlgebraic?(ip,bwt.tower) and purelyAlgebraic?(bwt.tower) => "leave"
+ (not ground? ip) =>
+ zero? tp => llpwt := cons([[ip],bwt.tower]$LpWT, llpwt)
+ (not ground? tp) => llpwt := cons([[ip,tp],bwt.tower]$LpWT, llpwt)
+ riv := removeZero(ip,bwt.tower)
+ (zero? riv) =>
+ zero? tp => lts := cons(bwt.tower,lts)
+ (not ground? tp) => llpwt := cons([[tp],bwt.tower]$LpWT, llpwt)
+ llpwt := cons([[riv * mainMonomial(p) + tp],bwt.tower]$LpWT, llpwt)
+ [lts,llpwt]
+
+ decompose(lp: LP, lts: Split, clos?: B, info?: B): Split ==
+ decompose(lp,lts,false,false,clos?,true,info?)
+
+ convert(lpwt: LpWT): String ==
+ ls: List String := ["<", string((#(lpwt.val))::Z), ",", string((#(lpwt.tower))::Z), ">" ]
+ concat ls
+
+ printInfo(toSee: List LpWT, n: N): Void ==
+ lpwt := first toSee
+ s: String := concat ["[", string((#toSee)::Z), " ", convert(lpwt)@String]
+ m: N := #(lpwt.val)
+ toSee := rest toSee
+ for lpwt in toSee repeat
+ m := m + #(lpwt.val)
+ s := concat [s, ",", convert(lpwt)@String]
+ s := concat [s, " -> |", string(m::Z), "|; {", string(n::Z),"}]"]
+ iprint(s)$iprintpack
+ void()
+
+ decompose(lp: LP, lts: Split, cleanW?: B, sqfr?: B, clos?: B, rem?: B, info?: B): Split ==
+ -- if cleanW? then REMOVE REDUNDANT COMPONENTS in lts
+ -- if sqfr? then SPLIT the system with SQUARE-FREE FACTORIZATION
+ -- if clos? then SOLVE in the closure sense
+ -- if rem? then REDUCE the current p by using remainder
+ -- if info? then PRINT info
+ empty? lp => lts
+ branches: List Branch := prepareDecompose(lp,lts,cleanW?,sqfr?)$quasicomppack
+ empty? branches => []
+ toSee: List LpWT := [[br.eq,br.tower]$LpWT for br in branches]
+ toSave: Split := []
+ if clos? then bound := KrullNumber(lp,lts) else bound := numberOfVariables(lp,lts)
+ while (not empty? toSee) repeat
+ if info? then printInfo(toSee,#toSave)
+ lpwt := first toSee; toSee := rest toSee
+ lp := lpwt.val; ts := lpwt.tower
+ empty? lp =>
+ toSave := cons(ts, toSave)
+ p := first lp; lp := rest lp
+ if rem? and (not ground? p) and (not empty? ts)
+ then
+ p := remainder(p,ts).polnum
+ p := removeZero(p,ts)
+ zero? p => toSee := cons([lp,ts]$LpWT, toSee)
+ ground? p => "leave"
+ rsl := internalDecompose(p,ts,bound,clos?)
+ toSee := upDateBranches(lp,toSave,toSee,rsl,bound)
+ removeSuperfluousQuasiComponents(toSave)$quasicomppack
+
+ upDateBranches(leq:LP,lts:Split,current:List LpWT,wip: Wip,n:N): List LpWT ==
+ newBranches: List LpWT := wip.todo
+ newComponents: Split := wip.done
+ branches1, branches2: List LpWT
+ branches1 := []; branches2 := []
+ for branch in newBranches repeat
+ us := branch.tower
+ #us > n => "leave"
+ newleq := sort(infRittWu?,concat(leq,branch.val))
+ --foo := rewriteSetWithReduction(newleq,us,initiallyReduce,initiallyReduced?)
+ --any?(ground?,foo) => "leave"
+ branches1 := cons([newleq,us]$LpWT, branches1)
+ for us in newComponents repeat
+ #us > n => "leave"
+ subQuasiComponent?(us,lts)$quasicomppack => "leave"
+ --newleq := leq
+ --foo := rewriteSetWithReduction(newleq,us,initiallyReduce,initiallyReduced?)
+ --any?(ground?,foo) => "leave"
+ branches2 := cons([leq,us]$LpWT, branches2)
+ empty? branches1 =>
+ empty? branches2 => current
+ concat(branches2, current)
+ branches := concat [branches2, branches1, current]
+ -- branches := concat(branches,current)
+ removeSuperfluousCases(branches)$quasicomppack
+
+@
+\section{domain REGSET RegularTriangularSet}
+Several domain constructors implement regular triangular sets (or regular
+chains). Among them {\bf RegularTriangularSet} and
+{\bf SquareFreeRegularTriangularSet}. They also implement an algorithm
+by Marc Moreno Maza for computing triangular decompositions of polynomial
+systems. This method is refined in the package {\bf LazardSetSolvingPackage}
+in order to produce decompositions by means of Lazard triangular sets.
+<<domain REGSET RegularTriangularSet>>=
+)abbrev domain REGSET RegularTriangularSet
+++ Author: Marc Moreno Maza
+++ Date Created: 08/25/1998
+++ Date Last Updated: 16/12/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ This domain provides an implementation of regular chains.
+++ Moreover, the operation \axiomOpFrom{zeroSetSplit}{RegularTriangularSetCategory}
+++ is an implementation of a new algorithm for solving polynomial systems by
+++ means of regular chains.\newline
+++ References :
+++ [1] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: Version 11.
+
+RegularTriangularSet(R,E,V,P) : Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ PtoP ==> P -> P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : $)
+ BWT ==> Record(val : Boolean, tower : $)
+ LpWT ==> Record(val : (List P), tower : $)
+ Split ==> List $
+ iprintpack ==> InternalPrintPackage()
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppack ==> QuasiComponentPackage(R,E,V,P,$)
+ regsetgcdpack ==> RegularTriangularSetGcdPackage(R,E,V,P,$)
+ regsetdecomppack ==> RegularSetDecompositionPackage(R,E,V,P,$)
+
+ Exports == RegularTriangularSetCategory(R,E,V,P) with
+
+ internalAugment: (P,$,B,B,B,B,B) -> List $
+ ++ \axiom{internalAugment(p,ts,b1,b2,b3,b4,b5)}
+ ++ is an internal subroutine, exported only for developement.
+ zeroSetSplit: (LP, B, B) -> Split
+ ++ \axiom{zeroSetSplit(lp,clos?,info?)} has the same specifications as
+ ++ \axiomOpFrom{zeroSetSplit}{RegularTriangularSetCategory}.
+ ++ Moreover, if \axiom{clos?} then solves in the sense of the Zariski closure
+ ++ else solves in the sense of the regular zeros. If \axiom{info?} then
+ ++ do print messages during the computations.
+ zeroSetSplit: (LP, B, B, B, B) -> Split
+ ++ \axiom{zeroSetSplit(lp,b1,b2.b3,b4)}
+ ++ is an internal subroutine, exported only for developement.
+ internalZeroSetSplit: (LP, B, B, B) -> Split
+ ++ \axiom{internalZeroSetSplit(lp,b1,b2,b3)}
+ ++ is an internal subroutine, exported only for developement.
+ pre_process: (LP, B, B) -> Record(val: LP, towers: Split)
+ ++ \axiom{pre_process(lp,b1,b2)}
+ ++ is an internal subroutine, exported only for developement.
+
+ Implementation == add
+
+ Rep ==> LP
+
+ rep(s:$):Rep == s pretend Rep
+ per(l:Rep):$ == l pretend $
+
+ copy ts ==
+ per(copy(rep(ts))$LP)
+ empty() ==
+ per([])
+ empty?(ts:$) ==
+ empty?(rep(ts))
+ parts ts ==
+ rep(ts)
+ members ts ==
+ rep(ts)
+ map (f : PtoP, ts : $) : $ ==
+ construct(map(f,rep(ts))$LP)$$
+ map! (f : PtoP, ts : $) : $ ==
+ construct(map!(f,rep(ts))$LP)$$
+ member? (p,ts) ==
+ member?(p,rep(ts))$LP
+ unitIdealIfCan() ==
+ "failed"::Union($,"failed")
+ roughUnitIdeal? ts ==
+ false
+ coerce(ts:$) : OutputForm ==
+ lp : List(P) := reverse(rep(ts))
+ brace([p::OutputForm for p in lp]$List(OutputForm))$OutputForm
+ mvar ts ==
+ empty? ts => error "mvar$REGSET: #1 is empty"
+ mvar(first(rep(ts)))$P
+ first ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ first(rep(ts))::Union(P,"failed")
+ last ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ last(rep(ts))::Union(P,"failed")
+ rest ts ==
+ empty? ts => "failed"::Union($,"failed")
+ per(rest(rep(ts)))::Union($,"failed")
+ coerce(ts:$) : (List P) ==
+ rep(ts)
+
+ collectUpper (ts,v) ==
+ empty? ts => ts
+ lp := rep(ts)
+ newlp : Rep := []
+ while (not empty? lp) and (mvar(first(lp)) > v) repeat
+ newlp := cons(first(lp),newlp)
+ lp := rest lp
+ per(reverse(newlp))
+
+ collectUnder (ts,v) ==
+ empty? ts => ts
+ lp := rep(ts)
+ while (not empty? lp) and (mvar(first(lp)) >= v) repeat
+ lp := rest lp
+ per(lp)
+
+ construct(lp:List(P)) ==
+ ts : $ := per([])
+ empty? lp => ts
+ lp := sort(infRittWu?,lp)
+ while not empty? lp repeat
+ eif := extendIfCan(ts,first(lp))
+ not (eif case $) =>
+ error"in construct : List P -> $ from REGSET : bad #1"
+ ts := eif::$
+ lp := rest lp
+ ts
+
+ extendIfCan(ts:$,p:P) ==
+ ground? p => "failed"::Union($,"failed")
+ empty? ts =>
+ p := primitivePart p
+ (per([p]))::Union($,"failed")
+ not (mvar(ts) < mvar(p)) => "failed"::Union($,"failed")
+ invertible?(init(p),ts)@Boolean =>
+ (per(cons(p,rep(ts))))::Union($,"failed")
+ "failed"::Union($,"failed")
+
+ removeZero(p:P, ts:$): P ==
+ (ground? p) or (empty? ts) => p
+ v := mvar(p)
+ ts_v_- := collectUnder(ts,v)
+ if algebraic?(v,ts)
+ then
+ q := lazyPrem(p,select(ts,v)::P)
+ zero? q => return q
+ zero? removeZero(q,ts_v_-) => return 0
+ empty? ts_v_- => p
+ q: P := 0
+ while positive? degree(p,v) repeat
+ q := removeZero(init(p),ts_v_-) * mainMonomial(p) + q
+ p := tail(p)
+ q + removeZero(p,ts_v_-)
+
+ internalAugment(p:P,ts:$): $ ==
+ -- ASSUME that adding p to ts DOES NOT require any split
+ ground? p => error "in internalAugment$REGSET: ground? #1"
+ first(internalAugment(p,ts,false,false,false,false,false))
+
+ internalAugment(lp:List(P),ts:$): $ ==
+ -- ASSUME that adding p to ts DOES NOT require any split
+ empty? lp => ts
+ internalAugment(rest lp, internalAugment(first lp, ts))
+
+ internalAugment(p:P,ts:$,rem?:B,red?:B,prim?:B,sqfr?:B,extend?:B): Split ==
+ -- ASSUME p is not a constant
+ -- ASSUME mvar(p) is not algebraic w.r.t. ts
+ -- ASSUME init(p) invertible modulo ts
+ -- if rem? then REDUCE p by remainder
+ -- if prim? then REPLACE p by its main primitive part
+ -- if sqfr? then FACTORIZE SQUARE FREE p over R
+ -- if extend? DO NOT ASSUME every pol in ts_v_+ is invertible modulo ts
+ v := mvar(p)
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ if rem? then p := remainder(p,ts_v_-).polnum
+ -- if rem? then p := reduceByQuasiMonic(p,ts_v_-)
+ if red? then p := removeZero(p,ts_v_-)
+ if prim? then p := mainPrimitivePart p
+ if sqfr?
+ then
+ lsfp := squareFreeFactors(p)$polsetpack
+ lts: Split := [per(cons(f,rep(ts_v_-))) for f in lsfp]
+ else
+ lts: Split := [per(cons(p,rep(ts_v_-)))]
+ extend? => extend(members(ts_v_+),lts)
+ [per(concat(rep(ts_v_+),rep(us))) for us in lts]
+
+ augment(p:P,ts:$): List $ ==
+ ground? p => error "in augment$REGSET: ground? #1"
+ algebraic?(mvar(p),ts) => error "in augment$REGSET: bad #1"
+ -- ASSUME init(p) invertible modulo ts
+ -- DOES NOT ASSUME anything else.
+ -- THUS reduction, mainPrimitivePart and squareFree are NEEDED
+ internalAugment(p,ts,true,true,true,true,true)
+
+ extend(p:P,ts:$): List $ ==
+ ground? p => error "in extend$REGSET: ground? #1"
+ v := mvar(p)
+ not (mvar(ts) < mvar(p)) => error "in extend$REGSET: bad #1"
+ lts: List($) := []
+ split: List($) := invertibleSet(init(p),ts)
+ for us in split repeat
+ lts := concat(augment(p,us),lts)
+ lts
+
+ invertible?(p:P,ts:$): Boolean ==
+ toseInvertible?(p,ts)$regsetgcdpack
+
+ invertible?(p:P,ts:$): List BWT ==
+ toseInvertible?(p,ts)$regsetgcdpack
+
+ invertibleSet(p:P,ts:$): Split ==
+ toseInvertibleSet(p,ts)$regsetgcdpack
+
+ lastSubResultant(p1:P,p2:P,ts:$): List PWT ==
+ toseLastSubResultant(p1,p2,ts)$regsetgcdpack
+
+ squareFreePart(p:P, ts: $): List PWT ==
+ toseSquareFreePart(p,ts)$regsetgcdpack
+
+ intersect(p:P, ts: $): List($) == decompose([p], [ts], false, false)$regsetdecomppack
+
+ intersect(lp: LP, lts: List($)): List($) == decompose(lp, lts, false, false)$regsetdecomppack
+ -- SOLVE in the regular zero sense
+ -- and DO NOT PRINT info
+
+ decompose(p:P, ts: $): List($) == decompose([p], [ts], true, false)$regsetdecomppack
+
+ decompose(lp: LP, lts: List($)): List($) == decompose(lp, lts, true, false)$regsetdecomppack
+ -- SOLVE in the closure sense
+ -- and DO NOT PRINT info
+
+ zeroSetSplit(lp:List(P)) == zeroSetSplit(lp,true,false)
+ -- by default SOLVE in the closure sense
+ -- and DO NOT PRINT info
+
+ zeroSetSplit(lp:List(P), clos?: B) == zeroSetSplit(lp,clos?, false)
+ -- DO NOT PRINT info
+
+ zeroSetSplit(lp:List(P), clos?: B, info?: B) ==
+ -- if clos? then SOLVE in the closure sense
+ -- if info? then PRINT info
+ -- by default USE hash-tables
+ -- and PREPROCESS the input system
+ zeroSetSplit(lp,true,clos?,info?,true)
+
+ zeroSetSplit(lp:List(P),hash?:B,clos?:B,info?:B,prep?:B) ==
+ -- if hash? then USE hash-tables
+ -- if info? then PRINT information
+ -- if clos? then SOLVE in the closure sense
+ -- if prep? then PREPROCESS the input system
+ if hash?
+ then
+ s1, s2, s3, dom1, dom2, dom3: String
+ e: String := empty()$String
+ if info? then (s1,s2,s3) := ("w","g","i") else (s1,s2,s3) := (e,e,e)
+ if info?
+ then
+ (dom1, dom2, dom3) := ("QCMPACK", "REGSETGCD: Gcd", "REGSETGCD: Inv Set")
+ else
+ (dom1, dom2, dom3) := (e,e,e)
+ startTable!(s1,"W",dom1)$quasicomppack
+ startTableGcd!(s2,"G",dom2)$regsetgcdpack
+ startTableInvSet!(s3,"I",dom3)$regsetgcdpack
+ lts := internalZeroSetSplit(lp,clos?,info?,prep?)
+ if hash?
+ then
+ stopTable!()$quasicomppack
+ stopTableGcd!()$regsetgcdpack
+ stopTableInvSet!()$regsetgcdpack
+ lts
+
+ internalZeroSetSplit(lp:LP,clos?:B,info?:B,prep?:B) ==
+ -- if info? then PRINT information
+ -- if clos? then SOLVE in the closure sense
+ -- if prep? then PREPROCESS the input system
+ if prep?
+ then
+ pp := pre_process(lp,clos?,info?)
+ lp := pp.val
+ lts := pp.towers
+ else
+ ts: $ := [[]]
+ lts := [ts]
+ lp := remove(zero?, lp)
+ any?(ground?, lp) => []
+ empty? lp => lts
+ empty? lts => lts
+ lp := sort(infRittWu?,lp)
+ clos? => decompose(lp,lts, clos?, info?)$regsetdecomppack
+ -- IN DIM > 0 with clos? the following is false ...
+ for p in lp repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lts
+
+ largeSystem?(lp:LP): Boolean ==
+ -- Gonnet and Gerdt and not Wu-Wang.2
+ #lp > 16 => true
+ #lp < 13 => false
+ lts: List($) := []
+ (#lp :: Z - numberOfVariables(lp,lts)$regsetdecomppack :: Z) > 3
+
+ smallSystem?(lp:LP): Boolean ==
+ -- neural, Vermeer, Liu, and not f-633 and not Hairer-2
+ #lp < 5
+
+ mediumSystem?(lp:LP): Boolean ==
+ -- f-633 and not Hairer-2
+ lts: List($) := []
+ (numberOfVariables(lp,lts)$regsetdecomppack :: Z - #lp :: Z) < 2
+
+-- lin?(p:P):Boolean == ground?(init(p)) and one?(mdeg(p))
+ lin?(p:P):Boolean == ground?(init(p)) and (mdeg(p) = 1)
+
+ pre_process(lp:LP,clos?:B,info?:B): Record(val: LP, towers: Split) ==
+ -- if info? then PRINT information
+ -- if clos? then SOLVE in the closure sense
+ ts: $ := [[]];
+ lts: Split := [ts]
+ empty? lp => [lp,lts]
+ lp1: List P := []
+ lp2: List P := []
+ for p in lp repeat
+ ground? (tail p) => lp1 := cons(p, lp1)
+ lp2 := cons(p, lp2)
+ lts: Split := decompose(lp1,[ts],clos?,info?)$regsetdecomppack
+ probablyZeroDim?(lp)$polsetpack =>
+ largeSystem?(lp) => return [lp2,lts]
+ if #lp > 7
+ then
+ -- Butcher (8,8) + Wu-Wang.2 (13,16)
+ lp2 := crushedSet(lp2)$polsetpack
+ lp2 := remove(zero?,lp2)
+ any?(ground?,lp2) => return [lp2, lts]
+ lp3 := [p for p in lp2 | lin?(p)]
+ lp4 := [p for p in lp2 | not lin?(p)]
+ if clos?
+ then
+ lts := decompose(lp4,lts, clos?, info?)$regsetdecomppack
+ else
+ lp4 := sort(infRittWu?,lp4)
+ for p in lp4 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lp2 := lp3
+ else
+ lp2 := crushedSet(lp2)$polsetpack
+ lp2 := remove(zero?,lp2)
+ any?(ground?,lp2) => return [lp2, lts]
+ if clos?
+ then
+ lts := decompose(lp2,lts, clos?, info?)$regsetdecomppack
+ else
+ lp2 := sort(infRittWu?,lp2)
+ for p in lp2 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lp2 := []
+ return [lp2,lts]
+ smallSystem?(lp) => [lp2,lts]
+ mediumSystem?(lp) => [crushedSet(lp2)$polsetpack,lts]
+ lp3 := [p for p in lp2 | lin?(p)]
+ lp4 := [p for p in lp2 | not lin?(p)]
+ if clos?
+ then
+ lts := decompose(lp4,lts, clos?, info?)$regsetdecomppack
+ else
+ lp4 := sort(infRittWu?,lp4)
+ for p in lp4 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ if clos?
+ then
+ lts := decompose(lp3,lts, clos?, info?)$regsetdecomppack
+ else
+ lp3 := sort(infRittWu?,lp3)
+ for p in lp3 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lp2 := []
+ return [lp2,lts]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category RSETCAT RegularTriangularSetCategory>>
+<<package QCMPACK QuasiComponentPackage>>
+<<package RSETGCD RegularTriangularSetGcdPackage>>
+<<package RSDCMPK RegularSetDecompositionPackage>>
+<<domain REGSET RegularTriangularSet>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rep1.spad.pamphlet b/src/algebra/rep1.spad.pamphlet
new file mode 100644
index 00000000..b65c7675
--- /dev/null
+++ b/src/algebra/rep1.spad.pamphlet
@@ -0,0 +1,380 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rep1.spad}
+\author{Holger Gollan, Johannes Grabmeier, Thorsten Werther}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REP1 RepresentationPackage1}
+<<package REP1 RepresentationPackage1>>=
+)abbrev package REP1 RepresentationPackage1
+++ Authors: Holger Gollan, Johannes Grabmeier, Thorsten Werther
+++ Date Created: 12 September 1987
+++ Date Last Updated: 24 May 1991
+++ Basic Operations: antisymmetricTensors,symmetricTensors,
+++ tensorProduct, permutationRepresentation
+++ Related Constructors: RepresentationPackage1, Permutation
+++ Also See: IrrRepSymNatPackage
+++ AMS Classifications:
+++ Keywords: representation, symmetrization, tensor product
+++ References:
+++ G. James, A. Kerber: The Representation Theory of the Symmetric
+++ Group. Encycl. of Math. and its Appl. Vol 16., Cambr. Univ Press 1981;
+++ J. Grabmeier, A. Kerber: The Evaluation of Irreducible
+++ Polynomial Representations of the General Linear Groups
+++ and of the Unitary Groups over Fields of Characteristic 0,
+++ Acta Appl. Math. 8 (1987), 271-291;
+++ H. Gollan, J. Grabmeier: Algorithms in Representation Theory and
+++ their Realization in the Computer Algebra System Scratchpad,
+++ Bayreuther Mathematische Schriften, Heft 33, 1990, 1-23
+++ Description:
+++ RepresentationPackage1 provides functions for representation theory
+++ for finite groups and algebras.
+++ The package creates permutation representations and uses tensor products
+++ and its symmetric and antisymmetric components to create new
+++ representations of larger degree from given ones.
+++ Note: instead of having parameters from \spadtype{Permutation}
+++ this package allows list notation of permutations as well:
+++ e.g. \spad{[1,4,3,2]} denotes permutes 2 and 4 and fixes 1 and 3.
+
+RepresentationPackage1(R): public == private where
+
+ R : Ring
+ OF ==> OutputForm
+ NNI ==> NonNegativeInteger
+ PI ==> PositiveInteger
+ I ==> Integer
+ L ==> List
+ M ==> Matrix
+ P ==> Polynomial
+ SM ==> SquareMatrix
+ V ==> Vector
+ ICF ==> IntegerCombinatoricFunctions Integer
+ SGCF ==> SymmetricGroupCombinatoricFunctions
+ PERM ==> Permutation
+
+ public ==> with
+
+ if R has commutative("*") then
+ antisymmetricTensors : (M R,PI) -> M R
+ ++ antisymmetricTensors(a,n) applies to the square matrix
+ ++ {\em a} the irreducible, polynomial representation of the
+ ++ general linear group {\em GLm}, where m is the number of
+ ++ rows of {\em a}, which corresponds to the partition
+ ++ {\em (1,1,...,1,0,0,...,0)} of n.
+ ++ Error: if n is greater than m.
+ ++ Note: this corresponds to the symmetrization of the representation
+ ++ with the sign representation of the symmetric group {\em Sn}.
+ ++ The carrier spaces of the representation are the antisymmetric
+ ++ tensors of the n-fold tensor product.
+ if R has commutative("*") then
+ antisymmetricTensors : (L M R, PI) -> L M R
+ ++ antisymmetricTensors(la,n) applies to each
+ ++ m-by-m square matrix in
+ ++ the list {\em la} the irreducible, polynomial representation
+ ++ of the general linear group {\em GLm}
+ ++ which corresponds
+ ++ to the partition {\em (1,1,...,1,0,0,...,0)} of n.
+ ++ Error: if n is greater than m.
+ ++ Note: this corresponds to the symmetrization of the representation
+ ++ with the sign representation of the symmetric group {\em Sn}.
+ ++ The carrier spaces of the representation are the antisymmetric
+ ++ tensors of the n-fold tensor product.
+ createGenericMatrix : NNI -> M P R
+ ++ createGenericMatrix(m) creates a square matrix of dimension k
+ ++ whose entry at the i-th row and j-th column is the
+ ++ indeterminate {\em x[i,j]} (double subscripted).
+ symmetricTensors : (M R, PI) -> M R
+ ++ symmetricTensors(a,n) applies to the m-by-m
+ ++ square matrix {\em a} the
+ ++ irreducible, polynomial representation of the general linear
+ ++ group {\em GLm}
+ ++ which corresponds to the partition {\em (n,0,...,0)} of n.
+ ++ Error: if {\em a} is not a square matrix.
+ ++ Note: this corresponds to the symmetrization of the representation
+ ++ with the trivial representation of the symmetric group {\em Sn}.
+ ++ The carrier spaces of the representation are the symmetric
+ ++ tensors of the n-fold tensor product.
+ symmetricTensors : (L M R, PI) -> L M R
+ ++ symmetricTensors(la,n) applies to each m-by-m square matrix in the
+ ++ list {\em la} the irreducible, polynomial representation
+ ++ of the general linear group {\em GLm}
+ ++ which corresponds
+ ++ to the partition {\em (n,0,...,0)} of n.
+ ++ Error: if the matrices in {\em la} are not square matrices.
+ ++ Note: this corresponds to the symmetrization of the representation
+ ++ with the trivial representation of the symmetric group {\em Sn}.
+ ++ The carrier spaces of the representation are the symmetric
+ ++ tensors of the n-fold tensor product.
+ tensorProduct : (M R, M R) -> M R
+ ++ tensorProduct(a,b) calculates the Kronecker product
+ ++ of the matrices {\em a} and b.
+ ++ Note: if each matrix corresponds to a group representation
+ ++ (repr. of generators) of one group, then these matrices
+ ++ correspond to the tensor product of the two representations.
+ tensorProduct : (L M R, L M R) -> L M R
+ ++ tensorProduct([a1,...,ak],[b1,...,bk]) calculates the list of
+ ++ Kronecker products of the matrices {\em ai} and {\em bi}
+ ++ for {1 <= i <= k}.
+ ++ Note: If each list of matrices corresponds to a group representation
+ ++ (repr. of generators) of one group, then these matrices
+ ++ correspond to the tensor product of the two representations.
+ tensorProduct : M R -> M R
+ ++ tensorProduct(a) calculates the Kronecker product
+ ++ of the matrix {\em a} with itself.
+ tensorProduct : L M R -> L M R
+ ++ tensorProduct([a1,...ak]) calculates the list of
+ ++ Kronecker products of each matrix {\em ai} with itself
+ ++ for {1 <= i <= k}.
+ ++ Note: If the list of matrices corresponds to a group representation
+ ++ (repr. of generators) of one group, then these matrices correspond
+ ++ to the tensor product of the representation with itself.
+ permutationRepresentation : (PERM I, I) -> M I
+ ++ permutationRepresentation(pi,n) returns the matrix
+ ++ {\em (deltai,pi(i))} (Kronecker delta) for a permutation
+ ++ {\em pi} of {\em {1,2,...,n}}.
+ permutationRepresentation : L I -> M I
+ ++ permutationRepresentation(pi,n) returns the matrix
+ ++ {\em (deltai,pi(i))} (Kronecker delta) if the permutation
+ ++ {\em pi} is in list notation and permutes {\em {1,2,...,n}}.
+ permutationRepresentation : (L PERM I, I) -> L M I
+ ++ permutationRepresentation([pi1,...,pik],n) returns the list
+ ++ of matrices {\em [(deltai,pi1(i)),...,(deltai,pik(i))]}
+ ++ (Kronecker delta) for the permutations {\em pi1,...,pik}
+ ++ of {\em {1,2,...,n}}.
+ permutationRepresentation : L L I -> L M I
+ ++ permutationRepresentation([pi1,...,pik],n) returns the list
+ ++ of matrices {\em [(deltai,pi1(i)),...,(deltai,pik(i))]}
+ ++ if the permutations {\em pi1},...,{\em pik} are in
+ ++ list notation and are permuting {\em {1,2,...,n}}.
+
+ private ==> add
+
+ -- import of domains and packages
+
+ import OutputForm
+
+ -- declaration of local functions:
+
+
+ calcCoef : (L I, M I) -> I
+ -- calcCoef(beta,C) calculates the term
+ -- |S(beta) gamma S(alpha)| / |S(beta)|
+
+
+ invContent : L I -> V I
+ -- invContent(alpha) calculates the weak monoton function f with
+ -- f : m -> n with invContent alpha. f is stored in the returned
+ -- vector
+
+
+ -- definition of local functions
+
+
+ calcCoef(beta,C) ==
+ prod : I := 1
+ for i in 1..maxIndex beta repeat
+ prod := prod * multinomial(beta(i), entries row(C,i))$ICF
+ prod
+
+
+ invContent(alpha) ==
+ n : NNI := (+/alpha)::NNI
+ f : V I := new(n,0)
+ i : NNI := 1
+ j : I := - 1
+ for og in alpha repeat
+ j := j + 1
+ for k in 1..og repeat
+ f(i) := j
+ i := i + 1
+ f
+
+
+ -- exported functions:
+
+
+
+ if R has commutative("*") then
+ antisymmetricTensors ( a : M R , k : PI ) ==
+
+ n : NNI := nrows a
+ k = 1 => a
+ k > n =>
+ error("second parameter for antisymmetricTensors is too large")
+ m : I := binomial(n,k)$ICF
+ il : L L I := [subSet(n,k,i)$SGCF for i in 0..m-1]
+ b : M R := zero(m::NNI, m::NNI)
+ for i in 1..m repeat
+ for j in 1..m repeat
+ c : M R := zero(k,k)
+ lr: L I := il.i
+ lt: L I := il.j
+ for r in 1..k repeat
+ for t in 1..k repeat
+ rr : I := lr.r
+ tt : I := lt.t
+ --c.r.t := a.(1+rr).(1+tt)
+ setelt(c,r,t,elt(a, 1+rr, 1+tt))
+ setelt(b, i, j, determinant c)
+ b
+
+
+ if R has commutative("*") then
+ antisymmetricTensors(la: L M R, k: PI) ==
+ [antisymmetricTensors(ma,k) for ma in la]
+
+
+
+ symmetricTensors (a : M R, n : PI) ==
+
+ m : NNI := nrows a
+ m ^= ncols a =>
+ error("Input to symmetricTensors is no square matrix")
+ n = 1 => a
+
+ dim : NNI := (binomial(m+n-1,n)$ICF)::NNI
+ c : M R := new(dim,dim,0)
+ f : V I := new(n,0)
+ g : V I := new(n,0)
+ nullMatrix : M I := new(1,1,0)
+ colemanMatrix : M I
+
+ for i in 1..dim repeat
+ -- unrankImproperPartitions1 starts counting from 0
+ alpha := unrankImproperPartitions1(n,m,i-1)$SGCF
+ f := invContent(alpha)
+ for j in 1..dim repeat
+ -- unrankImproperPartitions1 starts counting from 0
+ beta := unrankImproperPartitions1(n,m,j-1)$SGCF
+ g := invContent(beta)
+ colemanMatrix := nextColeman(alpha,beta,nullMatrix)$SGCF
+ while colemanMatrix ^= nullMatrix repeat
+ gamma := inverseColeman(alpha,beta,colemanMatrix)$SGCF
+ help : R := calcCoef(beta,colemanMatrix)::R
+ for k in 1..n repeat
+ help := help * a( (1+f k)::NNI, (1+g(gamma k))::NNI )
+ c(i,j) := c(i,j) + help
+ colemanMatrix := nextColeman(alpha,beta,colemanMatrix)$SGCF
+ -- end of while
+ -- end of j-loop
+ -- end of i-loop
+
+ c
+
+
+ symmetricTensors(la : L M R, k : PI) ==
+ [symmetricTensors (ma, k) for ma in la]
+
+
+ tensorProduct(a: M R, b: M R) ==
+ n : NNI := nrows a
+ m : NNI := nrows b
+ nc : NNI := ncols a
+ mc : NNI := ncols b
+ c : M R := zero(n * m, nc * mc)
+ indexr : NNI := 1 -- row index
+ for i in 1..n repeat
+ for k in 1..m repeat
+ indexc : NNI := 1 -- column index
+ for j in 1..nc repeat
+ for l in 1..mc repeat
+ c(indexr,indexc) := a(i,j) * b(k,l)
+ indexc := indexc + 1
+ indexr := indexr + 1
+ c
+
+
+ tensorProduct (la: L M R, lb: L M R) ==
+ [tensorProduct(la.i, lb.i) for i in 1..maxIndex la]
+
+
+ tensorProduct(a : M R) == tensorProduct(a, a)
+
+ tensorProduct(la : L M R) ==
+ tensorProduct(la :: L M R, la :: L M R)
+
+ permutationRepresentation (p : PERM I, n : I) ==
+ -- permutations are assumed to permute {1,2,...,n}
+ a : M I := zero(n :: NNI, n :: NNI)
+ for i in 1..n repeat
+ a(eval(p,i)$(PERM I),i) := 1
+ a
+
+
+ permutationRepresentation (p : L I) ==
+ -- permutations are assumed to permute {1,2,...,n}
+ n : I := #p
+ a : M I := zero(n::NNI, n::NNI)
+ for i in 1..n repeat
+ a(p.i,i) := 1
+ a
+
+
+ permutationRepresentation(listperm : L PERM I, n : I) ==
+ -- permutations are assumed to permute {1,2,...,n}
+ [permutationRepresentation(perm, n) for perm in listperm]
+
+ permutationRepresentation (listperm : L L I) ==
+ -- permutations are assumed to permute {1,2,...,n}
+ [permutationRepresentation perm for perm in listperm]
+
+ createGenericMatrix(m) ==
+ res : M P R := new(m,m,0$(P R))
+ for i in 1..m repeat
+ for j in 1..m repeat
+ iof : OF := coerce(i)$Integer
+ jof : OF := coerce(j)$Integer
+ le : L OF := cons(iof,list jof)
+ sy : Symbol := subscript(x::Symbol, le)$Symbol
+ res(i,j) := (sy :: P R)
+ res
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REP1 RepresentationPackage1>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rep2.spad.pamphlet b/src/algebra/rep2.spad.pamphlet
new file mode 100644
index 00000000..64fec1fc
--- /dev/null
+++ b/src/algebra/rep2.spad.pamphlet
@@ -0,0 +1,827 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rep2.spad}
+\author{Holger Gollan, Johannes Grabmeier}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package REP2 RepresentationPackage2}
+<<package REP2 RepresentationPackage2>>=
+)abbrev package REP2 RepresentationPackage2
+++ Authors: Holger Gollan, Johannes Grabmeier
+++ Date Created: 10 September 1987
+++ Date Last Updated: 20 August 1990
+++ Basic Operations: areEquivalent?, isAbsolutelyIrreducible?,
+++ split, meatAxe
+++ Related Constructors: RepresentationTheoryPackage1
+++ Also See: IrrRepSymNatPackage
+++ AMS Classifications:
+++ Keywords: meat-axe, modular representation
+++ Reference:
+++ R. A. Parker: The Computer Calculation of Modular Characters
+++ (The Meat-Axe), in M. D. Atkinson (Ed.), Computational Group Theory
+++ Academic Press, Inc., London 1984
+++ H. Gollan, J. Grabmeier: Algorithms in Representation Theory and
+++ their Realization in the Computer Algebra System Scratchpad,
+++ Bayreuther Mathematische Schriften, Heft 33, 1990, 1-23.
+++ Description:
+++ RepresentationPackage2 provides functions for working with
+++ modular representations of finite groups and algebra.
+++ The routines in this package are created, using ideas of R. Parker,
+++ (the meat-Axe) to get smaller representations from bigger ones,
+++ i.e. finding sub- and factormodules, or to show, that such the
+++ representations are irreducible.
+++ Note: most functions are randomized functions of Las Vegas type
+++ i.e. every answer is correct, but with small probability
+++ the algorithm fails to get an answer.
+RepresentationPackage2(R): public == private where
+
+ R : Ring
+ OF ==> OutputForm
+ I ==> Integer
+ L ==> List
+ SM ==> SquareMatrix
+ M ==> Matrix
+ NNI ==> NonNegativeInteger
+ V ==> Vector
+ PI ==> PositiveInteger
+ B ==> Boolean
+ RADIX ==> RadixExpansion
+
+ public ==> with
+
+ completeEchelonBasis : V V R -> M R
+ ++ completeEchelonBasis(lv) completes the basis {\em lv} assumed
+ ++ to be in echelon form of a subspace of {\em R**n} (n the length
+ ++ of all the vectors in {\em lv}) with unit vectors to a basis of
+ ++ {\em R**n}. It is assumed that the argument is not an empty
+ ++ vector and that it is not the basis of the 0-subspace.
+ ++ Note: the rows of the result correspond to the vectors of the basis.
+ createRandomElement : (L M R, M R) -> M R
+ ++ createRandomElement(aG,x) creates a random element of the group
+ ++ algebra generated by {\em aG}.
+ -- randomWord : (L L I, L M) -> M R
+ --++ You can create your own 'random' matrix with "randomWord(lli, lm)".
+ --++ Each li in lli determines a product of matrices, the entries in li
+ --++ determine which matrix from lm is chosen. Finally we sum over all
+ --++ products. The result "sm" can be used to call split with (e.g.)
+ --++ second parameter "first nullSpace sm"
+ if R has EuclideanDomain then -- using rowEchelon
+ cyclicSubmodule : (L M R, V R) -> V V R
+ ++ cyclicSubmodule(lm,v) generates a basis as follows.
+ ++ It is assumed that the size n of the vector equals the number
+ ++ of rows and columns of the matrices. Then the matrices generate
+ ++ a subalgebra, say \spad{A}, of the algebra of all square matrices of
+ ++ dimension n. {\em V R} is an \spad{A}-module in the natural way.
+ ++ cyclicSubmodule(lm,v) generates the R-Basis of {\em Av} as
+ ++ described in section 6 of R. A. Parker's "The Meat-Axe".
+ ++ Note: in contrast to the description in "The Meat-Axe" and to
+ ++ {\em standardBasisOfCyclicSubmodule} the result is in
+ ++ echelon form.
+ standardBasisOfCyclicSubmodule : (L M R, V R) -> M R
+ ++ standardBasisOfCyclicSubmodule(lm,v) returns a matrix as follows.
+ ++ It is assumed that the size n of the vector equals the number
+ ++ of rows and columns of the matrices. Then the matrices generate
+ ++ a subalgebra, say \spad{A},
+ ++ of the algebra of all square matrices of
+ ++ dimension n. {\em V R} is an \spad{A}-module in the natural way.
+ ++ standardBasisOfCyclicSubmodule(lm,v) calculates a matrix whose
+ ++ non-zero column vectors are the R-Basis of {\em Av} achieved
+ ++ in the way as described in section 6
+ ++ of R. A. Parker's "The Meat-Axe".
+ ++ Note: in contrast to {\em cyclicSubmodule}, the result is not
+ ++ in echelon form.
+ if R has Field then -- only because of inverse in SM
+ areEquivalent? : (L M R, L M R, B, I) -> M R
+ ++ areEquivalent?(aG0,aG1,randomelements,numberOfTries) tests
+ ++ whether the two lists of matrices, all assumed of same
+ ++ square shape, can be simultaneously conjugated by a non-singular
+ ++ matrix. If these matrices represent the same group generators,
+ ++ the representations are equivalent.
+ ++ The algorithm tries
+ ++ {\em numberOfTries} times to create elements in the
+ ++ generated algebras in the same fashion. If their ranks differ,
+ ++ they are not equivalent. If an
+ ++ isomorphism is assumed, then
+ ++ the kernel of an element of the first algebra
+ ++ is mapped to the kernel of the corresponding element in the
+ ++ second algebra. Now consider the one-dimensional ones.
+ ++ If they generate the whole space (e.g. irreducibility !)
+ ++ we use {\em standardBasisOfCyclicSubmodule} to create the
+ ++ only possible transition matrix. The method checks whether the
+ ++ matrix conjugates all corresponding matrices from {\em aGi}.
+ ++ The way to choose the singular matrices is as in {\em meatAxe}.
+ ++ If the two representations are equivalent, this routine
+ ++ returns the transformation matrix {\em TM} with
+ ++ {\em aG0.i * TM = TM * aG1.i} for all i. If the representations
+ ++ are not equivalent, a small 0-matrix is returned.
+ ++ Note: the case
+ ++ with different sets of group generators cannot be handled.
+ areEquivalent? : (L M R, L M R) -> M R
+ ++ areEquivalent?(aG0,aG1) calls {\em areEquivalent?(aG0,aG1,true,25)}.
+ ++ Note: the choice of 25 was rather arbitrary.
+ areEquivalent? : (L M R, L M R, I) -> M R
+ ++ areEquivalent?(aG0,aG1,numberOfTries) calls
+ ++ {\em areEquivalent?(aG0,aG1,true,25)}.
+ ++ Note: the choice of 25 was rather arbitrary.
+ isAbsolutelyIrreducible? : (L M R, I) -> B
+ ++ isAbsolutelyIrreducible?(aG, numberOfTries) uses
+ ++ Norton's irreducibility test to check for absolute
+ ++ irreduciblity, assuming if a one-dimensional kernel is found.
+ ++ As no field extension changes create "new" elements
+ ++ in a one-dimensional space, the criterium stays true
+ ++ for every extension. The method looks for one-dimensionals only
+ ++ by creating random elements (no fingerprints) since
+ ++ a run of {\em meatAxe} would have proved absolute irreducibility
+ ++ anyway.
+ isAbsolutelyIrreducible? : L M R -> B
+ ++ isAbsolutelyIrreducible?(aG) calls
+ ++ {\em isAbsolutelyIrreducible?(aG,25)}.
+ ++ Note: the choice of 25 was rather arbitrary.
+ split : (L M R, V R) -> L L M R
+ ++ split(aG, vector) returns a subalgebra \spad{A} of all
+ ++ square matrix of dimension n as a list of list of matrices,
+ ++ generated by the list of matrices aG, where n denotes both
+ ++ the size of vector as well as the dimension of each of the
+ ++ square matrices.
+ ++ {\em V R} is an A-module in the natural way.
+ ++ split(aG, vector) then checks whether the cyclic submodule
+ ++ generated by {\em vector} is a proper submodule of {\em V R}.
+ ++ If successful, it returns a two-element list, which contains
+ ++ first the list of the representations of the submodule,
+ ++ then the list of the representations of the factor module.
+ ++ If the vector generates the whole module, a one-element list
+ ++ of the old representation is given.
+ ++ Note: a later version this should call the other split.
+ split: (L M R, V V R) -> L L M R
+ ++ split(aG,submodule) uses a proper submodule of {\em R**n}
+ ++ to create the representations of the submodule and of
+ ++ the factor module.
+ if (R has Finite) and (R has Field) then
+ meatAxe : (L M R, B, I, I) -> L L M R
+ ++ meatAxe(aG,randomElements,numberOfTries, maxTests) returns
+ ++ a 2-list of representations as follows.
+ ++ All matrices of argument aG are assumed to be square
+ ++ and of equal size.
+ ++ Then \spad{aG} generates a subalgebra, say \spad{A}, of the algebra
+ ++ of all square matrices of dimension n. {\em V R} is an A-module
+ ++ in the usual way.
+ ++ meatAxe(aG,numberOfTries, maxTests) creates at most
+ ++ {\em numberOfTries} random elements of the algebra, tests
+ ++ them for singularity. If singular, it tries at most {\em maxTests}
+ ++ elements of its kernel to generate a proper submodule.
+ ++ If successful, a 2-list is returned: first, a list
+ ++ containing first the list of the
+ ++ representations of the submodule, then a list of the
+ ++ representations of the factor module.
+ ++ Otherwise, if we know that all the kernel is already
+ ++ scanned, Norton's irreducibility test can be used either
+ ++ to prove irreducibility or to find the splitting.
+ ++ If {\em randomElements} is {\em false}, the first 6 tries
+ ++ use Parker's fingerprints.
+ meatAxe : L M R -> L L M R
+ ++ meatAxe(aG) calls {\em meatAxe(aG,false,25,7)} returns
+ ++ a 2-list of representations as follows.
+ ++ All matrices of argument \spad{aG} are assumed to be square
+ ++ and of
+ ++ equal size. Then \spad{aG} generates a subalgebra,
+ ++ say \spad{A}, of the algebra
+ ++ of all square matrices of dimension n. {\em V R} is an A-module
+ ++ in the usual way.
+ ++ meatAxe(aG) creates at most 25 random elements
+ ++ of the algebra, tests
+ ++ them for singularity. If singular, it tries at most 7
+ ++ elements of its kernel to generate a proper submodule.
+ ++ If successful a list which contains first the list of the
+ ++ representations of the submodule, then a list of the
+ ++ representations of the factor module is returned.
+ ++ Otherwise, if we know that all the kernel is already
+ ++ scanned, Norton's irreducibility test can be used either
+ ++ to prove irreducibility or to find the splitting.
+ ++ Notes: the first 6 tries use Parker's fingerprints.
+ ++ Also, 7 covers the case of three-dimensional kernels over
+ ++ the field with 2 elements.
+ meatAxe: (L M R, B) -> L L M R
+ ++ meatAxe(aG, randomElements) calls {\em meatAxe(aG,false,6,7)},
+ ++ only using Parker's fingerprints, if {\em randomElemnts} is false.
+ ++ If it is true, it calls {\em meatAxe(aG,true,25,7)},
+ ++ only using random elements.
+ ++ Note: the choice of 25 was rather arbitrary.
+ ++ Also, 7 covers the case of three-dimensional kernels over the field
+ ++ with 2 elements.
+ meatAxe : (L M R, PI) -> L L M R
+ ++ meatAxe(aG, numberOfTries) calls
+ ++ {\em meatAxe(aG,true,numberOfTries,7)}.
+ ++ Notes: 7 covers the case of three-dimensional
+ ++ kernels over the field with 2 elements.
+ scanOneDimSubspaces: (L V R, I) -> V R
+ ++ scanOneDimSubspaces(basis,n) gives a canonical representative
+ ++ of the {\em n}-th one-dimensional subspace of the vector space
+ ++ generated by the elements of {\em basis}, all from {\em R**n}.
+ ++ The coefficients of the representative are of shape
+ ++ {\em (0,...,0,1,*,...,*)}, {\em *} in R. If the size of R
+ ++ is q, then there are {\em (q**n-1)/(q-1)} of them.
+ ++ We first reduce n modulo this number, then find the
+ ++ largest i such that {\em +/[q**i for i in 0..i-1] <= n}.
+ ++ Subtracting this sum of powers from n results in an
+ ++ i-digit number to basis q. This fills the positions of the
+ ++ stars.
+ -- would prefer to have (V V R,.... but nullSpace results
+ -- in L V R
+
+ private ==> add
+
+ -- import of domain and packages
+ import OutputForm
+
+ -- declarations and definitions of local variables and
+ -- local function
+
+ blockMultiply: (M R, M R, L I, I) -> M R
+ -- blockMultiply(a,b,li,n) assumes that a has n columns
+ -- and b has n rows, li is a sublist of the rows of a and
+ -- a sublist of the columns of b. The result is the
+ -- multiplication of the (li x n) part of a with the
+ -- (n x li) part of b. We need this, because just matrix
+ -- multiplying the parts would require extra storage.
+ blockMultiply(a, b, li, n) ==
+ matrix([[ +/[a(i,s) * b(s,j) for s in 1..n ] _
+ for j in li ] for i in li])
+
+ fingerPrint: (NNI, M R, M R, M R) -> M R
+ -- is local, because one should know all the results for smaller i
+ fingerPrint (i : NNI, a : M R, b : M R, x :M R) ==
+ -- i > 2 only gives the correct result if the value of x from
+ -- the parameter list equals the result of fingerprint(i-1,...)
+ (i::PI) = 1 => x := a + b + a*b
+ (i::PI) = 2 => x := (x + a*b)*b
+ (i::PI) = 3 => x := a + b*x
+ (i::PI) = 4 => x := x + b
+ (i::PI) = 5 => x := x + a*b
+ (i::PI) = 6 => x := x - a + b*a
+ error "Sorry, but there are only 6 fingerprints!"
+ x
+
+
+ -- definition of exported functions
+
+
+ --randomWord(lli,lm) ==
+ -- -- we assume that all matrices are square of same size
+ -- numberOfMatrices := #lm
+ -- +/[*/[lm.(1+i rem numberOfMatrices) for i in li ] for li in lli]
+
+ completeEchelonBasis(basis) ==
+
+ dimensionOfSubmodule : NNI := #basis
+ n : NNI := # basis.1
+ indexOfVectorToBeScanned : NNI := 1
+ row : NNI := dimensionOfSubmodule
+
+ completedBasis : M R := zero(n, n)
+ for i in 1..dimensionOfSubmodule repeat
+ completedBasis := setRow_!(completedBasis, i, basis.i)
+ if #basis <= n then
+ newStart : NNI := 1
+ for j in 1..n
+ while indexOfVectorToBeScanned <= dimensionOfSubmodule repeat
+ if basis.indexOfVectorToBeScanned.j = 0 then
+ completedBasis(1+row,j) := 1 --put unit vector into basis
+ row := row + 1
+ else
+ indexOfVectorToBeScanned := indexOfVectorToBeScanned + 1
+ newStart : NNI := j + 1
+ for j in newStart..n repeat
+ completedBasis(j,j) := 1 --put unit vector into basis
+ completedBasis
+
+
+ createRandomElement(aG,algElt) ==
+ numberOfGenerators : NNI := #aG
+ -- randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ algElt := algElt * aG.randomIndex
+ -- randomIndxElement := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ algElt + aG.randomIndex
+
+
+ if R has EuclideanDomain then
+ cyclicSubmodule (lm : L M R, v : V R) ==
+ basis : M R := rowEchelon matrix list entries v
+ -- normalizing the vector
+ -- all these elements lie in the submodule generated by v
+ furtherElts : L V R := [(lm.i*v)::V R for i in 1..maxIndex lm]
+ --furtherElts has elements of the generated submodule. It will
+ --will be checked whether they are in the span of the vectors
+ --computed so far. Of course we stop if we have got the whole
+ --space.
+ while (^null furtherElts) and (nrows basis < #v) repeat
+ w : V R := first furtherElts
+ nextVector : M R := matrix list entries w -- normalizing the vector
+ -- will the rank change if we add this nextVector
+ -- to the basis so far computed?
+ addedToBasis : M R := vertConcat(basis, nextVector)
+ if rank addedToBasis ^= nrows basis then
+ basis := rowEchelon addedToBasis -- add vector w to basis
+ updateFurtherElts : L V R := _
+ [(lm.i*w)::V R for i in 1..maxIndex lm]
+ furtherElts := append (rest furtherElts, updateFurtherElts)
+ else
+ -- the vector w lies in the span of matrix, no updating
+ -- of the basis
+ furtherElts := rest furtherElts
+ vector [row(basis, i) for i in 1..maxRowIndex basis]
+
+
+ standardBasisOfCyclicSubmodule (lm : L M R, v : V R) ==
+ dim : NNI := #v
+ standardBasis : L L R := list(entries v)
+ basis : M R := rowEchelon matrix list entries v
+ -- normalizing the vector
+ -- all these elements lie in the submodule generated by v
+ furtherElts : L V R := [(lm.i*v)::V R for i in 1..maxIndex lm]
+ --furtherElts has elements of the generated submodule. It will
+ --will be checked whether they are in the span of the vectors
+ --computed so far. Of course we stop if we have got the whole
+ --space.
+ while (^null furtherElts) and (nrows basis < #v) repeat
+ w : V R := first furtherElts
+ nextVector : M R := matrix list entries w -- normalizing the vector
+ -- will the rank change if we add this nextVector
+ -- to the basis so far computed?
+ addedToBasis : M R := vertConcat(basis, nextVector)
+ if rank addedToBasis ^= nrows basis then
+ standardBasis := cons(entries w, standardBasis)
+ basis := rowEchelon addedToBasis -- add vector w to basis
+ updateFurtherElts : L V R := _
+ [lm.i*w for i in 1..maxIndex lm]
+ furtherElts := append (rest furtherElts, updateFurtherElts)
+ else
+ -- the vector w lies in the span of matrix, therefore
+ -- no updating of matrix
+ furtherElts := rest furtherElts
+ transpose matrix standardBasis
+
+
+ if R has Field then -- only because of inverse in Matrix
+
+ -- as conditional local functions, *internal have to be here
+
+ splitInternal: (L M R, V R, B) -> L L M R
+ splitInternal(algebraGenerators : L M R, vector: V R,doSplitting? : B) ==
+
+ n : I := # vector -- R-rank of representation module =
+ -- degree of representation
+ submodule : V V R := cyclicSubmodule (algebraGenerators,vector)
+ rankOfSubmodule : I := # submodule -- R-Rank of submodule
+ submoduleRepresentation : L M R := nil()
+ factormoduleRepresentation : L M R := nil()
+ if n ^= rankOfSubmodule then
+ messagePrint " A proper cyclic submodule is found."
+ if doSplitting? then -- no else !!
+ submoduleIndices : L I := [i for i in 1..rankOfSubmodule]
+ factormoduleIndices : L I := [i for i in (1+rankOfSubmodule)..n]
+ transitionMatrix : M R := _
+ transpose completeEchelonBasis submodule
+ messagePrint " Transition matrix computed"
+ inverseTransitionMatrix : M R := _
+ autoCoerce(inverse transitionMatrix)$Union(M R,"failed")
+ messagePrint " The inverse of the transition matrix computed"
+ messagePrint " Now transform the matrices"
+ for i in 1..maxIndex algebraGenerators repeat
+ helpMatrix : M R := inverseTransitionMatrix * algebraGenerators.i
+ -- in order to not create extra space and regarding the fact
+ -- that we only want the two blocks in the main diagonal we
+ -- multiply with the aid of the local function blockMultiply
+ submoduleRepresentation := cons( blockMultiply( _
+ helpMatrix,transitionMatrix,submoduleIndices,n), _
+ submoduleRepresentation)
+ factormoduleRepresentation := cons( blockMultiply( _
+ helpMatrix,transitionMatrix,factormoduleIndices,n), _
+ factormoduleRepresentation)
+ [reverse submoduleRepresentation, reverse _
+ factormoduleRepresentation]
+ else -- represesentation is irreducible
+ messagePrint " The generated cyclic submodule was not proper"
+ [algebraGenerators]
+
+
+
+ irreducibilityTestInternal: (L M R, M R, B) -> L L M R
+ irreducibilityTestInternal(algebraGenerators,_
+ singularMatrix,split?) ==
+ algebraGeneratorsTranspose : L M R := [transpose _
+ algebraGenerators.j for j in 1..maxIndex algebraGenerators]
+ xt : M R := transpose singularMatrix
+ messagePrint " We know that all the cyclic submodules generated by all"
+ messagePrint " non-trivial element of the singular matrix under view are"
+ messagePrint " not proper, hence Norton's irreducibility test can be done:"
+ -- actually we only would need one (!) non-trivial element from
+ -- the kernel of xt, such an element must exist as the transpose
+ -- of a singular matrix is of course singular. Question: Can
+ -- we get it more easily from the kernel of x = singularMatrix?
+ kernel : L V R := nullSpace xt
+ result : L L M R := _
+ splitInternal(algebraGeneratorsTranspose,first kernel,split?)
+ if null rest result then -- this means first kernel generates
+ -- the whole module
+ if 1 = #kernel then
+ messagePrint " Representation is absolutely irreducible"
+ else
+ messagePrint " Representation is irreducible, but we don't know "
+ messagePrint " whether it is absolutely irreducible"
+ else
+ if split? then
+ messagePrint " Representation is not irreducible and it will be split:"
+ -- these are the dual representations, so calculate the
+ -- dual to get the desired result, i.e. "transpose inverse"
+ -- improvements??
+ for i in 1..maxIndex result repeat
+ for j in 1..maxIndex (result.i) repeat
+ mat : M R := result.i.j
+ result.i.j := _
+ transpose autoCoerce(inverse mat)$Union(M R,"failed")
+ else
+ messagePrint " Representation is not irreducible, use meatAxe to split"
+ -- if "split?" then dual representation interchange factor
+ -- and submodules, hence reverse
+ reverse result
+
+
+
+ -- exported functions for FiniteField-s.
+
+
+ areEquivalent? (aG0, aG1) ==
+ areEquivalent? (aG0, aG1, true, 25)
+
+
+ areEquivalent? (aG0, aG1, numberOfTries) ==
+ areEquivalent? (aG0, aG1, true, numberOfTries)
+
+
+ areEquivalent? (aG0, aG1, randomelements, numberOfTries) ==
+ result : B := false
+ transitionM : M R := zero(1, 1)
+ numberOfGenerators : NNI := #aG0
+ -- need a start value for creating random matrices:
+ -- if we switch to randomelements later, we take the last
+ -- fingerprint.
+ if randomelements then -- random should not be from I
+ --randomIndex : I := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x0 : M R := aG0.randomIndex
+ x1 : M R := aG1.randomIndex
+ n : NNI := #row(x0,1) -- degree of representation
+ foundResult : B := false
+ for i in 1..numberOfTries until foundResult repeat
+ -- try to create a non-singular element of the algebra
+ -- generated by "aG". If only two generators,
+ -- i < 7 and not "randomelements" use Parker's fingerprints
+ -- i >= 7 create random elements recursively:
+ -- x_i+1 :=x_i * mr1 + mr2, where mr1 and mr2 are randomly
+ -- chosen elements form "aG".
+ if i = 7 then randomelements := true
+ if randomelements then
+ --randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x0 := x0 * aG0.randomIndex
+ x1 := x1 * aG1.randomIndex
+ --randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x0 := x0 + aG0.randomIndex
+ x1 := x1 + aG1.randomIndex
+ else
+ x0 := fingerPrint (i, aG0.0, aG0.1 ,x0)
+ x1 := fingerPrint (i, aG1.0, aG1.1 ,x1)
+ -- test singularity of x0 and x1
+ rk0 : NNI := rank x0
+ rk1 : NNI := rank x1
+ rk0 ^= rk1 =>
+ messagePrint "Dimensions of kernels differ"
+ foundResult := true
+ result := false
+ -- can assume dimensions are equal
+ rk0 ^= n - 1 =>
+ -- not of any use here if kernel not one-dimensional
+ if randomelements then
+ messagePrint "Random element in generated algebra does"
+ messagePrint " not have a one-dimensional kernel"
+ else
+ messagePrint "Fingerprint element in generated algebra does"
+ messagePrint " not have a one-dimensional kernel"
+ -- can assume dimensions are equal and equal to n-1
+ if randomelements then
+ messagePrint "Random element in generated algebra has"
+ messagePrint " one-dimensional kernel"
+ else
+ messagePrint "Fingerprint element in generated algebra has"
+ messagePrint " one-dimensional kernel"
+ kernel0 : L V R := nullSpace x0
+ kernel1 : L V R := nullSpace x1
+ baseChange0 : M R := standardBasisOfCyclicSubmodule(_
+ aG0,kernel0.1)
+ baseChange1 : M R := standardBasisOfCyclicSubmodule(_
+ aG1,kernel1.1)
+ (ncols baseChange0) ^= (ncols baseChange1) =>
+ messagePrint " Dimensions of generated cyclic submodules differ"
+ foundResult := true
+ result := false
+ -- can assume that dimensions of cyclic submodules are equal
+ (ncols baseChange0) = n => -- full dimension
+ transitionM := baseChange0 * _
+ autoCoerce(inverse baseChange1)$Union(M R,"failed")
+ foundResult := true
+ result := true
+ for j in 1..numberOfGenerators while result repeat
+ if (aG0.j*transitionM) ^= (transitionM*aG1.j) then
+ result := false
+ transitionM := zero(1 ,1)
+ messagePrint " There is no isomorphism, as the only possible one"
+ messagePrint " fails to do the necessary base change"
+ -- can assume that dimensions of cyclic submodules are not "n"
+ messagePrint " Generated cyclic submodules have equal, but not full"
+ messagePrint " dimension, hence we can not draw any conclusion"
+ -- here ends the for-loop
+ if not foundResult then
+ messagePrint " "
+ messagePrint "Can neither prove equivalence nor inequivalence."
+ messagePrint " Try again."
+ else
+ if result then
+ messagePrint " "
+ messagePrint "Representations are equivalent."
+ else
+ messagePrint " "
+ messagePrint "Representations are not equivalent."
+ transitionM
+
+
+ isAbsolutelyIrreducible?(aG) == isAbsolutelyIrreducible?(aG,25)
+
+
+ isAbsolutelyIrreducible?(aG, numberOfTries) ==
+ result : B := false
+ numberOfGenerators : NNI := #aG
+ -- need a start value for creating random matrices:
+ -- randomIndex : I := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x : M R := aG.randomIndex
+ n : NNI := #row(x,1) -- degree of representation
+ foundResult : B := false
+ for i in 1..numberOfTries until foundResult repeat
+ -- try to create a non-singular element of the algebra
+ -- generated by "aG", dimension of its kernel being 1.
+ -- create random elements recursively:
+ -- x_i+1 :=x_i * mr1 + mr2, where mr1 and mr2 are randomly
+ -- chosen elements form "aG".
+ -- randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x := x * aG.randomIndex
+ --randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x := x + aG.randomIndex
+ -- test whether rank of x is n-1
+ rk : NNI := rank x
+ if rk = n - 1 then
+ foundResult := true
+ messagePrint "Random element in generated algebra has"
+ messagePrint " one-dimensional kernel"
+ kernel : L V R := nullSpace x
+ if n=#cyclicSubmodule(aG, first kernel) then
+ result := (irreducibilityTestInternal(aG,x,false)).1 ^= nil()$(L M R)
+ -- result := not null? first irreducibilityTestInternal(aG,x,false) -- this down't compile !!
+ else -- we found a proper submodule
+ result := false
+ --split(aG,kernel.1) -- to get the splitting
+ else -- not of any use here if kernel not one-dimensional
+ messagePrint "Random element in generated algebra does"
+ messagePrint " not have a one-dimensional kernel"
+ -- here ends the for-loop
+ if not foundResult then
+ messagePrint "We have not found a one-dimensional kernel so far,"
+ messagePrint " as we do a random search you could try again"
+ --else
+ -- if not result then
+ -- messagePrint "Representation is not irreducible."
+ -- else
+ -- messagePrint "Representation is irreducible."
+ result
+
+
+
+ split(algebraGenerators: L M R, vector: V R) ==
+ splitInternal(algebraGenerators, vector, true)
+
+
+ split(algebraGenerators : L M R, submodule: V V R) == --not zero submodule
+ n : NNI := #submodule.1 -- R-rank of representation module =
+ -- degree of representation
+ rankOfSubmodule : I := (#submodule) :: I --R-Rank of submodule
+ submoduleRepresentation : L M R := nil()
+ factormoduleRepresentation : L M R := nil()
+ submoduleIndices : L I := [i for i in 1..rankOfSubmodule]
+ factormoduleIndices : L I := [i for i in (1+rankOfSubmodule)..(n::I)]
+ transitionMatrix : M R := _
+ transpose completeEchelonBasis submodule
+ messagePrint " Transition matrix computed"
+ inverseTransitionMatrix : M R :=
+ autoCoerce(inverse transitionMatrix)$Union(M R,"failed")
+ messagePrint " The inverse of the transition matrix computed"
+ messagePrint " Now transform the matrices"
+ for i in 1..maxIndex algebraGenerators repeat
+ helpMatrix : M R := inverseTransitionMatrix * algebraGenerators.i
+ -- in order to not create extra space and regarding the fact
+ -- that we only want the two blocks in the main diagonal we
+ -- multiply with the aid of the local function blockMultiply
+ submoduleRepresentation := cons( blockMultiply( _
+ helpMatrix,transitionMatrix,submoduleIndices,n), _
+ submoduleRepresentation)
+ factormoduleRepresentation := cons( blockMultiply( _
+ helpMatrix,transitionMatrix,factormoduleIndices,n), _
+ factormoduleRepresentation)
+ cons(reverse submoduleRepresentation, list( reverse _
+ factormoduleRepresentation)::(L L M R))
+
+
+ -- the following is "under" "if R has Field", as there are compiler
+ -- problems with conditinally defined local functions, i.e. it
+ -- doesn't know, that "FiniteField" has "Field".
+
+
+ -- we are scanning through the vectorspaces
+ if (R has Finite) and (R has Field) then
+
+ meatAxe(algebraGenerators, randomelements, numberOfTries, _
+ maxTests) ==
+ numberOfGenerators : NNI := #algebraGenerators
+ result : L L M R := nil()$(L L M R)
+ q : PI := size()$R:PI
+ -- need a start value for creating random matrices:
+ -- if we switch to randomelements later, we take the last
+ -- fingerprint.
+ if randomelements then -- random should not be from I
+ --randomIndex : I := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x : M R := algebraGenerators.randomIndex
+ foundResult : B := false
+ for i in 1..numberOfTries until foundResult repeat
+ -- try to create a non-singular element of the algebra
+ -- generated by "algebraGenerators". If only two generators,
+ -- i < 7 and not "randomelements" use Parker's fingerprints
+ -- i >= 7 create random elements recursively:
+ -- x_i+1 :=x_i * mr1 + mr2, where mr1 and mr2 are randomly
+ -- chosen elements form "algebraGenerators".
+ if i = 7 then randomelements := true
+ if randomelements then
+ --randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x := x * algebraGenerators.randomIndex
+ --randomIndex := randnum numberOfGenerators
+ randomIndex := 1+(random()$Integer rem numberOfGenerators)
+ x := x + algebraGenerators.randomIndex
+ else
+ x := fingerPrint (i, algebraGenerators.1,_
+ algebraGenerators.2 , x)
+ -- test singularity of x
+ n : NNI := #row(x, 1) -- degree of representation
+ if (rank x) ^= n then -- x singular
+ if randomelements then
+ messagePrint "Random element in generated algebra is singular"
+ else
+ messagePrint "Fingerprint element in generated algebra is singular"
+ kernel : L V R := nullSpace x
+ -- the first number is the maximal number of one dimensional
+ -- subspaces of the kernel, the second is a user given
+ -- constant
+ numberOfOneDimSubspacesInKernel : I := (q**(#kernel)-1)quo(q-1)
+ numberOfTests : I := _
+ min(numberOfOneDimSubspacesInKernel, maxTests)
+ for j in 1..numberOfTests repeat
+ --we create an element in the kernel, there is a good
+ --probability for it to generate a proper submodule, the
+ --called "split" does the further work:
+ result := _
+ split(algebraGenerators,scanOneDimSubspaces(kernel,j))
+ -- we had "not null rest result" directly in the following
+ -- if .. then, but the statment there foundResult := true
+ -- didn't work properly
+ foundResult := not null rest result
+ if foundResult then
+ leave -- inner for-loop
+ -- finish here with result
+ else -- no proper submodule
+ -- we were not successfull, i.e gen. submodule was
+ -- not proper, if the whole kernel is already scanned,
+ -- Norton's irreducibility test is used now.
+ if (j+1)>numberOfOneDimSubspacesInKernel then
+ -- we know that all the cyclic submodules generated
+ -- by all non-trivial elements of the kernel are proper.
+ foundResult := true
+ result : L L M R := irreducibilityTestInternal (_
+ algebraGenerators,x,true)
+ leave -- inner for-loop
+ -- here ends the inner for-loop
+ else -- x non-singular
+ if randomelements then
+ messagePrint "Random element in generated algebra is non-singular"
+ else
+ messagePrint "Fingerprint element in generated algebra is non-singular"
+ -- here ends the outer for-loop
+ if not foundResult then
+ result : L L M R := [nil()$(L M R), nil()$(L M R)]
+ messagePrint " "
+ messagePrint "Sorry, no result, try meatAxe(...,true)"
+ messagePrint " or consider using an extension field."
+ result
+
+
+ meatAxe (algebraGenerators) ==
+ meatAxe(algebraGenerators, false, 25, 7)
+
+
+ meatAxe (algebraGenerators, randomElements?) ==
+ randomElements? => meatAxe (algebraGenerators, true, 25, 7)
+ meatAxe(algebraGenerators, false, 6, 7)
+
+
+ meatAxe (algebraGenerators:L M R, numberOfTries:PI) ==
+ meatAxe (algebraGenerators, true, numberOfTries, 7)
+
+
+
+ scanOneDimSubspaces(basis,n) ==
+ -- "dimension" of subspace generated by "basis"
+ dim : NNI := #basis
+ -- "dimension of the whole space:
+ nn : NNI := #(basis.1)
+ q : NNI := size()$R
+ -- number of all one-dimensional subspaces:
+ nred : I := n rem ((q**dim -1) quo (q-1))
+ pos : I := nred
+ i : I := 0
+ for i in 0..dim-1 while nred >= 0 repeat
+ pos := nred
+ nred := nred - (q**i)
+ i := if i = 0 then 0 else i-1
+ coefficients : V R := new(dim,0$R)
+ coefficients.(dim-i) := 1$R
+ iR : L I := wholeRagits(pos::RADIX q)
+ for j in 1..(maxIndex iR) repeat
+ coefficients.(dim-((#iR)::I) +j) := index((iR.j+(q::I))::PI)$R
+ result : V R := new(nn,0)
+ for i in 1..maxIndex coefficients repeat
+ newAdd : V R := coefficients.i * basis.i
+ for j in 1..nn repeat
+ result.j := result.j + newAdd.j
+ result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package REP2 RepresentationPackage2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/resring.spad.pamphlet b/src/algebra/resring.spad.pamphlet
new file mode 100644
index 00000000..5137df07
--- /dev/null
+++ b/src/algebra/resring.spad.pamphlet
@@ -0,0 +1,109 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra resring.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain RESRING ResidueRing}
+<<domain RESRING ResidueRing>>=
+)abbrev domain RESRING ResidueRing
+++ Author: P.Gianni
+++ Date Created: December 1992
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: ResidueRing is the quotient of a polynomial ring by an ideal.
+++ The ideal is given as a list of generators. The elements of the domain
+++ are equivalence classes expressed in terms of reduced elements
+
+ResidueRing(F,Expon,VarSet,FPol,LFPol) : Dom == Body
+ where
+ F : Field
+ Expon : OrderedAbelianMonoidSup
+ VarSet : OrderedSet
+ FPol : PolynomialCategory(F, Expon, VarSet)
+ LFPol : List FPol
+
+ Dom == Join(CommutativeRing, Algebra F) with
+ reduce : FPol -> $
+ ++ reduce(f) produces the equivalence class of f in the residue ring
+ coerce : FPol -> $
+ ++ coerce(f) produces the equivalence class of f in the residue ring
+ lift : $ -> FPol
+ ++ lift(x) return the canonical representative of the equivalence class x
+ Body == add
+ --representation
+ Rep:= FPol
+ import GroebnerPackage(F,Expon,VarSet,FPol)
+ relations:= groebner(LFPol)
+ relations = [1] => error "the residue ring is the zero ring"
+ --declarations
+ x,y: $
+ --definitions
+ 0 == 0$Rep
+ 1 == 1$Rep
+ reduce(f : FPol) : $ == normalForm(f,relations)
+ coerce(f : FPol) : $ == normalForm(f,relations)
+ lift x == x :: Rep :: FPol
+ x + y == x +$Rep y
+ -x == -$Rep x
+ x*y == normalForm(lift(x *$Rep y),relations)
+ (n : Integer) * x == n *$Rep x
+ (a : F) * x == a *$Rep x
+ x = y == x =$Rep y
+ characteristic() == characteristic()$F
+ coerce(x) : OutputForm == coerce(x)$Rep
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain RESRING ResidueRing>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/retract.spad.pamphlet b/src/algebra/retract.spad.pamphlet
new file mode 100644
index 00000000..8738f2cf
--- /dev/null
+++ b/src/algebra/retract.spad.pamphlet
@@ -0,0 +1,137 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra retract.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category FRETRCT FullyRetractableTo}
+<<category FRETRCT FullyRetractableTo>>=
+)abbrev category FRETRCT FullyRetractableTo
+++ Author: Manuel Bronstein
+++ Description:
+++ A is fully retractable to B means that A is retractable to B, and,
+++ in addition, if B is retractable to the integers or rational
+++ numbers then so is A.
+++ In particular, what we are asserting is that there are no integers
+++ (rationals) in A which don't retract into B.
+++ Date Created: March 1990
+++ Date Last Updated: 9 April 1991
+FullyRetractableTo(S: Type): Category == RetractableTo(S) with
+ if (S has RetractableTo Integer) then RetractableTo Integer
+ if (S has RetractableTo Fraction Integer) then
+ RetractableTo Fraction Integer
+ add
+ if not(S is Integer) then
+ if (S has RetractableTo Integer) then -- induction
+ coerce(n:Integer):% == n::S::%
+ retract(r:%):Integer == retract(retract(r)@S)
+
+ retractIfCan(r:%):Union(Integer, "failed") ==
+ (u:= retractIfCan(r)@Union(S,"failed")) case "failed"=> "failed"
+ retractIfCan(u::S)
+
+ if not(S is Fraction Integer) then
+ if (S has RetractableTo Fraction Integer) then -- induction
+ coerce(n:Fraction Integer):% == n::S::%
+ retract(r:%):Fraction(Integer) == retract(retract(r)@S)
+
+ retractIfCan(r:%):Union(Fraction Integer, "failed") ==
+ (u:=retractIfCan(r)@Union(S,"failed")) case "failed"=>"failed"
+ retractIfCan(u::S)
+
+@
+\section{package INTRET IntegerRetractions}
+<<package INTRET IntegerRetractions>>=
+)abbrev package INTRET IntegerRetractions
+++ Author: Manuel Bronstein
+++ Description: Provides integer testing and retraction functions.
+++ Date Created: March 1990
+++ Date Last Updated: 9 April 1991
+IntegerRetractions(S:RetractableTo(Integer)): with
+ integer : S -> Integer
+ ++ integer(x) returns x as an integer;
+ ++ error if x is not an integer;
+ integer? : S -> Boolean
+ ++ integer?(x) is true if x is an integer, false otherwise;
+ integerIfCan: S -> Union(Integer, "failed")
+ ++ integerIfCan(x) returns x as an integer,
+ ++ "failed" if x is not an integer;
+ == add
+ integer s == retract s
+ integer? s == retractIfCan(s) case Integer
+ integerIfCan s == retractIfCan s
+
+@
+\section{package RATRET RationalRetractions}
+<<package RATRET RationalRetractions>>=
+)abbrev package RATRET RationalRetractions
+++ Author: Manuel Bronstein
+++ Description: rational number testing and retraction functions.
+++ Date Created: March 1990
+++ Date Last Updated: 9 April 1991
+RationalRetractions(S:RetractableTo(Fraction Integer)): with
+ rational : S -> Fraction Integer
+ ++ rational(x) returns x as a rational number;
+ ++ error if x is not a rational number;
+ rational? : S -> Boolean
+ ++ rational?(x) returns true if x is a rational number,
+ ++ false otherwise;
+ rationalIfCan: S -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(x) returns x as a rational number,
+ ++ "failed" if x is not a rational number;
+ == add
+ rational s == retract s
+ rational? s == retractIfCan(s) case Fraction(Integer)
+ rationalIfCan s == retractIfCan s
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category FRETRCT FullyRetractableTo>>
+<<package INTRET IntegerRetractions>>
+<<package RATRET RationalRetractions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rf.spad.pamphlet b/src/algebra/rf.spad.pamphlet
new file mode 100644
index 00000000..26220e4c
--- /dev/null
+++ b/src/algebra/rf.spad.pamphlet
@@ -0,0 +1,263 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rf.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package POLYCATQ PolynomialCategoryQuotientFunctions}
+<<package POLYCATQ PolynomialCategoryQuotientFunctions>>=
+)abbrev package POLYCATQ PolynomialCategoryQuotientFunctions
+++ Manipulations on polynomial quotients
+++ Author: Manuel Bronstein
+++ Date Created: March 1988
+++ Date Last Updated: 9 July 1990
+++ Description:
+++ This package transforms multivariate polynomials or fractions into
+++ univariate polynomials or fractions, and back.
+++ Keywords: polynomial, fraction, transformation
+PolynomialCategoryQuotientFunctions(E, V, R, P, F):
+ Exports == Implementation where
+ E: OrderedAbelianMonoidSup
+ V: OrderedSet
+ R: Ring
+ P: PolynomialCategory(R, E, V)
+ F: Field with
+ coerce: P -> %
+ numer : % -> P
+ denom : % -> P
+
+ UP ==> SparseUnivariatePolynomial F
+ RF ==> Fraction UP
+
+ Exports ==> with
+ variables : F -> List V
+ ++ variables(f) returns the list of variables appearing
+ ++ in the numerator or the denominator of f.
+ mainVariable: F -> Union(V, "failed")
+ ++ mainVariable(f) returns the highest variable appearing
+ ++ in the numerator or the denominator of f, "failed" if
+ ++ f has no variables.
+ univariate : (F, V) -> RF
+ ++ univariate(f, v) returns f viewed as a univariate
+ ++ rational function in v.
+ multivariate: (RF, V) -> F
+ ++ multivariate(f, v) applies both the numerator and
+ ++ denominator of f to v.
+ univariate : (F, V, UP) -> UP
+ ++ univariate(f, x, p) returns f viewed as a univariate
+ ++ polynomial in x, using the side-condition \spad{p(x) = 0}.
+ isPlus : F -> Union(List F, "failed")
+ ++ isPlus(p) returns [m1,...,mn] if \spad{p = m1 + ... + mn} and
+ ++ \spad{n > 1}, "failed" otherwise.
+ isTimes : F -> Union(List F, "failed")
+ ++ isTimes(p) returns \spad{[a1,...,an]} if
+ ++ \spad{p = a1 ... an} and \spad{n > 1},
+ ++ "failed" otherwise.
+ isExpt : F -> Union(Record(var:V, exponent:Integer), "failed")
+ ++ isExpt(p) returns \spad{[x, n]} if \spad{p = x**n} and \spad{n <> 0},
+ ++ "failed" otherwise.
+ isPower : F -> Union(Record(val:F, exponent:Integer), "failed")
+ ++ isPower(p) returns \spad{[x, n]} if \spad{p = x**n} and \spad{n <> 0},
+ ++ "failed" otherwise.
+
+ Implementation ==> add
+ P2UP: (P, V) -> UP
+
+ univariate(f, x) == P2UP(numer f, x) / P2UP(denom f, x)
+
+ univariate(f, x, modulus) ==
+ (bc := extendedEuclidean(P2UP(denom f, x), modulus, 1))
+ case "failed" => error "univariate: denominator is 0 mod p"
+ (P2UP(numer f, x) * bc.coef1) rem modulus
+
+ multivariate(f, x) ==
+ v := x::P::F
+ ((numer f) v) / ((denom f) v)
+
+ mymerge:(List V,List V) ->List V
+ mymerge(l:List V,m:List V):List V==
+ empty? l => m
+ empty? m => l
+ first l = first m => cons(first l,mymerge(rest l,rest m))
+ first l > first m => cons(first l,mymerge(rest l,m))
+ cons(first m,mymerge(l,rest m))
+
+ variables f ==
+ mymerge(variables numer f, variables denom f)
+
+ isPower f ==
+ (den := denom f) ^= 1 =>
+ numer f ^= 1 => "failed"
+ (ur := isExpt den) case "failed" => [den::F, -1]
+ r := ur::Record(var:V, exponent:NonNegativeInteger)
+ [r.var::P::F, - (r.exponent::Integer)]
+ (ur := isExpt numer f) case "failed" => "failed"
+ r := ur::Record(var:V, exponent:NonNegativeInteger)
+ [r.var::P::F, r.exponent::Integer]
+
+ isExpt f ==
+ (ur := isExpt numer f) case "failed" =>
+-- one? numer f =>
+ (numer f) = 1 =>
+ (ur := isExpt denom f) case "failed" => "failed"
+ r := ur::Record(var:V, exponent:NonNegativeInteger)
+ [r.var, - (r.exponent::Integer)]
+ "failed"
+ r := ur::Record(var:V, exponent:NonNegativeInteger)
+-- one? denom f => [r.var, r.exponent::Integer]
+ (denom f) = 1 => [r.var, r.exponent::Integer]
+ "failed"
+
+ isTimes f ==
+ t := isTimes(num := numer f)
+ l:Union(List F, "failed") :=
+ t case "failed" => "failed"
+ [x::F for x in t]
+-- one?(den := denom f) => l
+ ((den := denom f) = 1) => l
+-- one? num => "failed"
+ num = 1 => "failed"
+ d := inv(den::F)
+ l case "failed" => [num::F, d]
+ concat_!(l::List(F), d)
+
+ isPlus f ==
+ denom f ^= 1 => "failed"
+ (s := isPlus numer f) case "failed" => "failed"
+ [x::F for x in s]
+
+ mainVariable f ==
+ a := mainVariable numer f
+ (b := mainVariable denom f) case "failed" => a
+ a case "failed" => b
+ max(a::V, b::V)
+
+ P2UP(p, x) ==
+ map(#1::F,
+ univariate(p, x))$SparseUnivariatePolynomialFunctions2(P, F)
+
+@
+\section{package RF RationalFunction}
+<<package RF RationalFunction>>=
+)abbrev package RF RationalFunction
+++ Top-level manipulations of rational functions
+++ Author: Manuel Bronstein
+++ Date Created: 1987
+++ Date Last Updated: 18 April 1991
+++ Description:
+++ Utilities that provide the same top-level manipulations on
+++ fractions than on polynomials.
+++ Keywords: polynomial, fraction
+-- Do not make into a domain!
+RationalFunction(R:IntegralDomain): Exports == Implementation where
+ V ==> Symbol
+ P ==> Polynomial R
+ Q ==> Fraction P
+ QF ==> PolynomialCategoryQuotientFunctions(IndexedExponents Symbol,
+ Symbol, R, P, Q)
+
+ Exports ==> with
+ variables : Q -> List V
+ ++ variables(f) returns the list of variables appearing
+ ++ in the numerator or the denominator of f.
+ mainVariable: Q -> Union(V, "failed")
+ ++ mainVariable(f) returns the highest variable appearing
+ ++ in the numerator or the denominator of f, "failed" if
+ ++ f has no variables.
+ univariate : (Q, V) -> Fraction SparseUnivariatePolynomial Q
+ ++ univariate(f, v) returns f viewed as a univariate
+ ++ rational function in v.
+ multivariate: (Fraction SparseUnivariatePolynomial Q, V) -> Q
+ ++ multivariate(f, v) applies both the numerator and
+ ++ denominator of f to v.
+ eval : (Q, V, Q) -> Q
+ ++ eval(f, v, g) returns f with v replaced by g.
+ eval : (Q, List V, List Q) -> Q
+ ++ eval(f, [v1,...,vn], [g1,...,gn]) returns f with
+ ++ each vi replaced by gi in parallel, i.e. vi's appearing
+ ++ inside the gi's are not replaced.
+ eval : (Q, Equation Q) -> Q
+ ++ eval(f, v = g) returns f with v replaced by g.
+ ++ Error: if v is not a symbol.
+ eval : (Q, List Equation Q) -> Q
+ ++ eval(f, [v1 = g1,...,vn = gn]) returns f with
+ ++ each vi replaced by gi in parallel, i.e. vi's appearing
+ ++ inside the gi's are not replaced.
+ ++ Error: if any vi is not a symbol.
+ coerce : R -> Q
+ ++ coerce(r) returns r viewed as a rational function over R.
+
+ Implementation ==> add
+ foo : (List V, List Q, V) -> Q
+ peval: (P, List V, List Q) -> Q
+
+ coerce(r:R):Q == r::P::Q
+ variables f == variables(f)$QF
+ mainVariable f == mainVariable(f)$QF
+ univariate(f, x) == univariate(f, x)$QF
+ multivariate(f, x) == multivariate(f, x)$QF
+ eval(x:Q, s:V, y:Q) == eval(x, [s], [y])
+ eval(x:Q, eq:Equation Q) == eval(x, [eq])
+ foo(ls, lv, x) == match(ls, lv, x, x::Q)$ListToMap(V, Q)
+
+ eval(x:Q, l:List Equation Q) ==
+ eval(x, [retract(lhs eq)@V for eq in l]$List(V),
+ [rhs eq for eq in l]$List(Q))
+
+ eval(x:Q, ls:List V, lv:List Q) ==
+ peval(numer x, ls, lv) / peval(denom x, ls, lv)
+
+ peval(p, ls, lv) ==
+ map(foo(ls, lv, #1), #1::Q,
+ p)$PolynomialCategoryLifting(IndexedExponents V,V,R,P,Q)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package POLYCATQ PolynomialCategoryQuotientFunctions>>
+<<package RF RationalFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/riccati.spad.pamphlet b/src/algebra/riccati.spad.pamphlet
new file mode 100644
index 00000000..30485093
--- /dev/null
+++ b/src/algebra/riccati.spad.pamphlet
@@ -0,0 +1,600 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra riccati.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ODEPRRIC PrimitiveRatRicDE}
+<<package ODEPRRIC PrimitiveRatRicDE>>=
+)abbrev package ODEPRRIC PrimitiveRatRicDE
+++ Author: Manuel Bronstein
+++ Date Created: 22 October 1991
+++ Date Last Updated: 2 February 1993
+++ Description: In-field solution of Riccati equations, primitive case.
+PrimitiveRatRicDE(F, UP, L, LQ): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+ L : LinearOrdinaryDifferentialOperatorCategory UP
+ LQ : LinearOrdinaryDifferentialOperatorCategory Fraction UP
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ RF ==> Fraction UP
+ UP2 ==> SparseUnivariatePolynomial UP
+ REC ==> Record(deg:N, eq:UP)
+ REC2 ==> Record(deg:N, eq:UP2)
+ POL ==> Record(poly:UP, eq:L)
+ FRC ==> Record(frac:RF, eq:L)
+ CNT ==> Record(constant:F, eq:L)
+ IJ ==> Record(ij: List Z, deg:N)
+
+ Exports ==> with
+ denomRicDE: L -> UP
+ ++ denomRicDE(op) returns a polynomial \spad{d} such that any rational
+ ++ solution of the associated Riccati equation of \spad{op y = 0} is
+ ++ of the form \spad{p/d + q'/q + r} for some polynomials p and q
+ ++ and a reduced r. Also, \spad{deg(p) < deg(d)} and {gcd(d,q) = 1}.
+ leadingCoefficientRicDE: L -> List REC
+ ++ leadingCoefficientRicDE(op) returns
+ ++ \spad{[[m1, p1], [m2, p2], ... , [mk, pk]]} such that the polynomial
+ ++ part of any rational solution of the associated Riccati equation of
+ ++ \spad{op y = 0} must have degree mj for some j, and its leading
+ ++ coefficient is then a zero of pj. In addition,\spad{m1>m2> ... >mk}.
+ constantCoefficientRicDE: (L, UP -> List F) -> List CNT
+ ++ constantCoefficientRicDE(op, ric) returns
+ ++ \spad{[[a1, L1], [a2, L2], ... , [ak, Lk]]} such that any rational
+ ++ solution with no polynomial part of the associated Riccati equation of
+ ++ \spad{op y = 0} must be one of the ai's in which case the equation for
+ ++ \spad{z = y e^{-int ai}} is \spad{Li z = 0}.
+ ++ \spad{ric} is a Riccati equation solver over \spad{F}, whose input
+ ++ is the associated linear equation.
+ polyRicDE: (L, UP -> List F) -> List POL
+ ++ polyRicDE(op, zeros) returns
+ ++ \spad{[[p1, L1], [p2, L2], ... , [pk, Lk]]} such that the polynomial
+ ++ part of any rational solution of the associated Riccati equation of
+ ++ \spad{op y=0} must be one of the pi's (up to the constant coefficient),
+ ++ in which case the equation for \spad{z=y e^{-int p}} is \spad{Li z =0}.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ singRicDE: (L, (UP, UP2) -> List UP, UP -> Factored UP) -> List FRC
+ ++ singRicDE(op, zeros, ezfactor) returns
+ ++ \spad{[[f1, L1], [f2, L2], ... , [fk, Lk]]} such that the singular
+ ++ part of any rational solution of the associated Riccati equation of
+ ++ \spad{op y=0} must be one of the fi's (up to the constant coefficient),
+ ++ in which case the equation for \spad{z=y e^{-int p}} is \spad{Li z=0}.
+ ++ \spad{zeros(C(x),H(x,y))} returns all the \spad{P_i(x)}'s such that
+ ++ \spad{H(x,P_i(x)) = 0 modulo C(x)}.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+ changeVar: (L, UP) -> L
+ ++ changeVar(+/[ai D^i], a) returns the operator \spad{+/[ai (D+a)^i]}.
+ changeVar: (L, RF) -> L
+ ++ changeVar(+/[ai D^i], a) returns the operator \spad{+/[ai (D+a)^i]}.
+
+ Implementation ==> add
+ import PrimitiveRatDE(F, UP, L, LQ)
+ import BalancedFactorisation(F, UP)
+
+ bound : (UP, L) -> N
+ lambda : (UP, L) -> List IJ
+ infmax : (IJ, L) -> List Z
+ dmax : (IJ, UP, L) -> List Z
+ getPoly : (IJ, L, List Z) -> UP
+ getPol : (IJ, UP, L, List Z) -> UP2
+ innerlb : (L, UP -> Z) -> List IJ
+ innermax : (IJ, L, UP -> Z) -> List Z
+ tau0 : (UP, UP) -> UP
+ poly1 : (UP, UP, Z) -> UP2
+ getPol1 : (List Z, UP, L) -> UP2
+ getIndices : (N, List IJ) -> List Z
+ refine : (List UP, UP -> Factored UP) -> List UP
+ polysol : (L, N, Boolean, UP -> List F) -> List POL
+ fracsol : (L, (UP, UP2) -> List UP, List UP) -> List FRC
+ padicsol l : (UP, L, N, Boolean, (UP, UP2) -> List UP) -> List FRC
+ leadingDenomRicDE : (UP, L) -> List REC2
+ factoredDenomRicDE: L -> List UP
+ constantCoefficientOperator: (L, N) -> UP
+ infLambda: L -> List IJ
+ -- infLambda(op) returns
+ -- \spad{[[[i,j], (\deg(a_i)-\deg(a_j))/(i-j) ]]} for all the pairs
+ -- of indices \spad{i,j} such that \spad{(\deg(a_i)-\deg(a_j))/(i-j)} is
+ -- an integer.
+
+ diff := D()$L
+ diffq := D()$LQ
+
+ lambda(c, l) == innerlb(l, order(#1, c)::Z)
+ infLambda l == innerlb(l, -(degree(#1)::Z))
+ infmax(rec, l) == innermax(rec, l, degree(#1)::Z)
+ dmax(rec, c, l) == innermax(rec, l, - order(#1, c)::Z)
+ tau0(p, q) == ((q exquo (p ** order(q, p)))::UP) rem p
+ poly1(c, cp, i) == */[monomial(1,1)$UP2 - (j * cp)::UP2 for j in 0..i-1]
+ getIndices(n, l) == removeDuplicates_! concat [r.ij for r in l | r.deg=n]
+ denomRicDE l == */[c ** bound(c, l) for c in factoredDenomRicDE l]
+ polyRicDE(l, zeros) == concat([0, l], polysol(l, 0, false, zeros))
+
+-- refine([p1,...,pn], foo) refines the list of factors using foo
+ refine(l, ezfactor) ==
+ concat [[r.factor for r in factors ezfactor p] for p in l]
+
+-- returns [] if the solutions of l have no p-adic component at c
+ padicsol(c, op, b, finite?, zeros) ==
+ ans:List(FRC) := empty()
+ finite? and zero? b => ans
+ lc := leadingDenomRicDE(c, op)
+ if finite? then lc := select_!(#1.deg <= b, lc)
+ for rec in lc repeat
+ for r in zeros(c, rec.eq) | r ^= 0 repeat
+ rcn := r /$RF (c ** rec.deg)
+ neweq := changeVar(op, rcn)
+ sols := padicsol(c, neweq, (rec.deg-1)::N, true, zeros)
+ ans :=
+ empty? sols => concat([rcn, neweq], ans)
+ concat_!([[rcn + sol.frac, sol.eq] for sol in sols], ans)
+ ans
+
+ leadingDenomRicDE(c, l) ==
+ ind:List(Z) -- to cure the compiler... (won't compile without)
+ lb := lambda(c, l)
+ done:List(N) := empty()
+ ans:List(REC2) := empty()
+ for rec in lb | (not member?(rec.deg, done)) and
+ not(empty?(ind := dmax(rec, c, l))) repeat
+ ans := concat([rec.deg, getPol(rec, c, l, ind)], ans)
+ done := concat(rec.deg, done)
+ sort_!(#1.deg > #2.deg, ans)
+
+ getPol(rec, c, l, ind) ==
+-- one?(rec.deg) => getPol1(ind, c, l)
+ (rec.deg = 1) => getPol1(ind, c, l)
+ +/[monomial(tau0(c, coefficient(l, i::N)), i::N)$UP2 for i in ind]
+
+ getPol1(ind, c, l) ==
+ cp := diff c
+ +/[tau0(c, coefficient(l, i::N)) * poly1(c, cp, i) for i in ind]
+
+ constantCoefficientRicDE(op, ric) ==
+ m := "max"/[degree p for p in coefficients op]
+ [[a, changeVar(op,a::UP)] for a in ric constantCoefficientOperator(op,m)]
+
+ constantCoefficientOperator(op, m) ==
+ ans:UP := 0
+ while op ^= 0 repeat
+ if degree(p := leadingCoefficient op) = m then
+ ans := ans + monomial(leadingCoefficient p, degree op)
+ op := reductum op
+ ans
+
+ getPoly(rec, l, ind) ==
+ +/[monomial(leadingCoefficient coefficient(l,i::N),i::N)$UP for i in ind]
+
+-- returns empty() if rec is does not reach the max,
+-- the list of indices (including rec) that reach the max otherwise
+ innermax(rec, l, nu) ==
+ n := degree l
+ i := first(rec.ij)
+ m := i * (d := rec.deg) + nu coefficient(l, i::N)
+ ans:List(Z) := empty()
+ for j in 0..n | (f := coefficient(l, j)) ^= 0 repeat
+ if ((k := (j * d + nu f)) > m) then return empty()
+ else if (k = m) then ans := concat(j, ans)
+ ans
+
+ leadingCoefficientRicDE l ==
+ ind:List(Z) -- to cure the compiler... (won't compile without)
+ lb := infLambda l
+ done:List(N) := empty()
+ ans:List(REC) := empty()
+ for rec in lb | (not member?(rec.deg, done)) and
+ not(empty?(ind := infmax(rec, l))) repeat
+ ans := concat([rec.deg, getPoly(rec, l, ind)], ans)
+ done := concat(rec.deg, done)
+ sort_!(#1.deg > #2.deg, ans)
+
+ factoredDenomRicDE l ==
+ bd := factors balancedFactorisation(leadingCoefficient l, coefficients l)
+ [dd.factor for dd in bd]
+
+ changeVar(l:L, a:UP) ==
+ dpa := diff + a::L -- the operator (D + a)
+ dpan:L := 1 -- will accumulate the powers of (D + a)
+ op:L := 0
+ for i in 0..degree l repeat
+ op := op + coefficient(l, i) * dpan
+ dpan := dpa * dpan
+ primitivePart op
+
+ changeVar(l:L, a:RF) ==
+ dpa := diffq + a::LQ -- the operator (D + a)
+ dpan:LQ := 1 -- will accumulate the powers of (D + a)
+ op:LQ := 0
+ for i in 0..degree l repeat
+ op := op + coefficient(l, i)::RF * dpan
+ dpan := dpa * dpan
+ splitDenominator(op, empty()).eq
+
+ bound(c, l) ==
+ empty?(lb := lambda(c, l)) => 1
+ "max"/[rec.deg for rec in lb]
+
+-- returns all the pairs [[i, j], n] such that
+-- n = (nu(i) - nu(j)) / (i - j) is an integer
+ innerlb(l, nu) ==
+ lb:List(IJ) := empty()
+ n := degree l
+ for i in 0..n | (li := coefficient(l, i)) ^= 0repeat
+ for j in i+1..n | (lj := coefficient(l, j)) ^= 0 repeat
+ u := (nu li - nu lj) exquo (i-j)
+ if (u case Z) and ((b := u::Z) > 0) then
+ lb := concat([[i, j], b::N], lb)
+ lb
+
+ singRicDE(l, zeros, ezfactor) ==
+ concat([0, l], fracsol(l, zeros, refine(factoredDenomRicDE l, ezfactor)))
+
+-- returns [] if the solutions of l have no singular component
+ fracsol(l, zeros, lc) ==
+ ans:List(FRC) := empty()
+ empty? lc => ans
+ empty?(sols := padicsol(first lc, l, 0, false, zeros)) =>
+ fracsol(l, zeros, rest lc)
+ for rec in sols repeat
+ neweq := changeVar(l, rec.frac)
+ sols := fracsol(neweq, zeros, rest lc)
+ ans :=
+ empty? sols => concat(rec, ans)
+ concat_!([[rec.frac + sol.frac, sol.eq] for sol in sols], ans)
+ ans
+
+-- returns [] if the solutions of l have no polynomial component
+ polysol(l, b, finite?, zeros) ==
+ ans:List(POL) := empty()
+ finite? and zero? b => ans
+ lc := leadingCoefficientRicDE l
+ if finite? then lc := select_!(#1.deg <= b, lc)
+ for rec in lc repeat
+ for a in zeros(rec.eq) | a ^= 0 repeat
+ atn:UP := monomial(a, rec.deg)
+ neweq := changeVar(l, atn)
+ sols := polysol(neweq, (rec.deg - 1)::N, true, zeros)
+ ans :=
+ empty? sols => concat([atn, neweq], ans)
+ concat_!([[atn + sol.poly, sol.eq] for sol in sols], ans)
+ ans
+
+@
+\section{package ODERTRIC RationalRicDE}
+<<package ODERTRIC RationalRicDE>>=
+)abbrev package ODERTRIC RationalRicDE
+++ Author: Manuel Bronstein
+++ Date Created: 22 October 1991
+++ Date Last Updated: 11 April 1994
+++ Description: In-field solution of Riccati equations, rational case.
+RationalRicDE(F, UP): Exports == Implementation where
+ F : Join(Field, CharacteristicZero, RetractableTo Integer,
+ RetractableTo Fraction Integer)
+ UP : UnivariatePolynomialCategory F
+
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ SY ==> Symbol
+ P ==> Polynomial F
+ RF ==> Fraction P
+ EQ ==> Equation RF
+ QF ==> Fraction UP
+ UP2 ==> SparseUnivariatePolynomial UP
+ SUP ==> SparseUnivariatePolynomial P
+ REC ==> Record(poly:SUP, vars:List SY)
+ SOL ==> Record(var:List SY, val:List F)
+ POL ==> Record(poly:UP, eq:L)
+ FRC ==> Record(frac:QF, eq:L)
+ CNT ==> Record(constant:F, eq:L)
+ UTS ==> UnivariateTaylorSeries(F, dummy, 0)
+ UPS ==> SparseUnivariatePolynomial UTS
+ L ==> LinearOrdinaryDifferentialOperator2(UP, QF)
+ LQ ==> LinearOrdinaryDifferentialOperator1 QF
+
+ Exports ==> with
+ ricDsolve: (LQ, UP -> List F) -> List QF
+ ++ ricDsolve(op, zeros) returns the rational solutions of the associated
+ ++ Riccati equation of \spad{op y = 0}.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ ricDsolve: (LQ, UP -> List F, UP -> Factored UP) -> List QF
+ ++ ricDsolve(op, zeros, ezfactor) returns the rational
+ ++ solutions of the associated Riccati equation of \spad{op y = 0}.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+ ricDsolve: (L, UP -> List F) -> List QF
+ ++ ricDsolve(op, zeros) returns the rational solutions of the associated
+ ++ Riccati equation of \spad{op y = 0}.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ ricDsolve: (L, UP -> List F, UP -> Factored UP) -> List QF
+ ++ ricDsolve(op, zeros, ezfactor) returns the rational
+ ++ solutions of the associated Riccati equation of \spad{op y = 0}.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+ singRicDE: (L, UP -> Factored UP) -> List FRC
+ ++ singRicDE(op, ezfactor) returns \spad{[[f1,L1], [f2,L2],..., [fk,Lk]]}
+ ++ such that the singular ++ part of any rational solution of the
+ ++ associated Riccati equation of \spad{op y = 0} must be one of the fi's
+ ++ (up to the constant coefficient), in which case the equation for
+ ++ \spad{z = y e^{-int ai}} is \spad{Li z = 0}.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+ polyRicDE: (L, UP -> List F) -> List POL
+ ++ polyRicDE(op, zeros) returns \spad{[[p1, L1], [p2, L2], ... , [pk,Lk]]}
+ ++ such that the polynomial part of any rational solution of the
+ ++ associated Riccati equation of \spad{op y = 0} must be one of the pi's
+ ++ (up to the constant coefficient), in which case the equation for
+ ++ \spad{z = y e^{-int p}} is \spad{Li z = 0}.
+ ++ \spad{zeros} is a zero finder in \spad{UP}.
+ if F has AlgebraicallyClosedField then
+ ricDsolve: LQ -> List QF
+ ++ ricDsolve(op) returns the rational solutions of the associated
+ ++ Riccati equation of \spad{op y = 0}.
+ ricDsolve: (LQ, UP -> Factored UP) -> List QF
+ ++ ricDsolve(op, ezfactor) returns the rational solutions of the
+ ++ associated Riccati equation of \spad{op y = 0}.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+ ricDsolve: L -> List QF
+ ++ ricDsolve(op) returns the rational solutions of the associated
+ ++ Riccati equation of \spad{op y = 0}.
+ ricDsolve: (L, UP -> Factored UP) -> List QF
+ ++ ricDsolve(op, ezfactor) returns the rational solutions of the
+ ++ associated Riccati equation of \spad{op y = 0}.
+ ++ Argument \spad{ezfactor} is a factorisation in \spad{UP},
+ ++ not necessarily into irreducibles.
+
+ Implementation ==> add
+ import RatODETools(P, SUP)
+ import RationalLODE(F, UP)
+ import NonLinearSolvePackage F
+ import PrimitiveRatDE(F, UP, L, LQ)
+ import PrimitiveRatRicDE(F, UP, L, LQ)
+
+ FifCan : RF -> Union(F, "failed")
+ UP2SUP : UP -> SUP
+ innersol : (List UP, Boolean) -> List QF
+ mapeval : (SUP, List SY, List F) -> UP
+ ratsol : List List EQ -> List SOL
+ ratsln : List EQ -> Union(SOL, "failed")
+ solveModulo : (UP, UP2) -> List UP
+ logDerOnly : L -> List QF
+ nonSingSolve : (N, L, UP -> List F) -> List QF
+ constantRic : (UP, UP -> List F) -> List F
+ nopoly : (N, UP, L, UP -> List F) -> List QF
+ reverseUP : UP -> UTS
+ reverseUTS : (UTS, N) -> UP
+ newtonSolution : (L, F, N, UP -> List F) -> UP
+ newtonSolve : (UPS, F, N) -> Union(UTS, "failed")
+ genericPolynomial: (SY, Z) -> Record(poly:SUP, vars:List SY)
+ -- genericPolynomial(s, n) returns
+ -- \spad{[[s0 + s1 X +...+ sn X^n],[s0,...,sn]]}.
+
+ dummy := new()$SY
+
+ UP2SUP p == map(#1::P,p)$UnivariatePolynomialCategoryFunctions2(F,UP,P,SUP)
+ logDerOnly l == [differentiate(s) / s for s in ratDsolve(l, 0).basis]
+ ricDsolve(l:LQ, zeros:UP -> List F) == ricDsolve(l, zeros, squareFree)
+ ricDsolve(l:L, zeros:UP -> List F) == ricDsolve(l, zeros, squareFree)
+ singRicDE(l, ezfactor) == singRicDE(l, solveModulo, ezfactor)
+
+ ricDsolve(l:LQ, zeros:UP -> List F, ezfactor:UP -> Factored UP) ==
+ ricDsolve(splitDenominator(l, empty()).eq, zeros, ezfactor)
+
+ mapeval(p, ls, lv) ==
+ map(ground eval(#1, ls, lv),
+ p)$UnivariatePolynomialCategoryFunctions2(P, SUP, F, UP)
+
+ FifCan f ==
+ ((n := retractIfCan(numer f))@Union(F, "failed") case F) and
+ ((d := retractIfCan(denom f))@Union(F, "failed") case F) =>
+ (n::F) / (d::F)
+ "failed"
+
+-- returns [0, []] if n < 0
+ genericPolynomial(s, n) ==
+ ans:SUP := 0
+ l:List(SY) := empty()
+ for i in 0..n repeat
+ ans := ans + monomial((sy := new s)::P, i::N)
+ l := concat(sy, l)
+ [ans, reverse_! l]
+
+ ratsln l ==
+ ls:List(SY) := empty()
+ lv:List(F) := empty()
+ for eq in l repeat
+ ((u := FifCan rhs eq) case "failed") or
+ ((v := retractIfCan(lhs eq)@Union(SY, "failed")) case "failed")
+ => return "failed"
+ lv := concat(u::F, lv)
+ ls := concat(v::SY, ls)
+ [ls, lv]
+
+ ratsol l ==
+ ans:List(SOL) := empty()
+ for sol in l repeat
+ if ((u := ratsln sol) case SOL) then ans := concat(u::SOL, ans)
+ ans
+
+-- returns [] if the solutions of l have no polynomial component
+ polyRicDE(l, zeros) ==
+ ans:List(POL) := [[0, l]]
+ empty?(lc := leadingCoefficientRicDE l) => ans
+ rec := first lc -- one with highest degree
+ for a in zeros(rec.eq) | a ^= 0 repeat
+ if (p := newtonSolution(l, a, rec.deg, zeros)) ^= 0 then
+ ans := concat([p, changeVar(l, p)], ans)
+ ans
+
+-- reverseUP(a_0 + a_1 x + ... + an x^n) = a_n + ... + a_0 x^n
+ reverseUP p ==
+ ans:UTS := 0
+ n := degree(p)::Z
+ while p ^= 0 repeat
+ ans := ans + monomial(leadingCoefficient p, (n - degree p)::N)
+ p := reductum p
+ ans
+
+-- reverseUTS(a_0 + a_1 x + ..., n) = a_n + ... + a_0 x^n
+ reverseUTS(s, n) ==
+ +/[monomial(coefficient(s, i), (n - i)::N)$UP for i in 0..n]
+
+-- returns a potential polynomial solution p with leading coefficient a*?**n
+ newtonSolution(l, a, n, zeros) ==
+ i:N
+ m:Z := 0
+ aeq:UPS := 0
+ op := l
+ while op ^= 0 repeat
+ mu := degree(op) * n + degree leadingCoefficient op
+ op := reductum op
+ if mu > m then m := mu
+ while l ^= 0 repeat
+ c := leadingCoefficient l
+ d := degree l
+ s:UTS := monomial(1, (m - d * n - degree c)::N)$UTS * reverseUP c
+ aeq := aeq + monomial(s, d)
+ l := reductum l
+ (u := newtonSolve(aeq, a, n)) case UTS => reverseUTS(u::UTS, n)
+ -- newton lifting failed, so revert to traditional method
+ atn := monomial(a, n)$UP
+ neq := changeVar(l, atn)
+ sols := [sol.poly for sol in polyRicDE(neq, zeros) | degree(sol.poly) < n]
+ empty? sols => atn
+ atn + first sols
+
+-- solves the algebraic equation eq for y, returns a solution of degree n with
+-- initial term a
+-- uses naive newton approximation for now
+-- an example where this fails is y^2 + 2 x y + 1 + x^2 = 0
+-- which arises from the differential operator D^2 + 2 x D + 1 + x^2
+ newtonSolve(eq, a, n) ==
+ deq := differentiate eq
+ sol := a::UTS
+ for i in 1..n repeat
+ (xquo := eq(sol) exquo deq(sol)) case "failed" => return "failed"
+ sol := truncate(sol - xquo::UTS, i)
+ sol
+
+-- there could be the same solutions coming in different ways, so we
+-- stop when the number of solutions reaches the order of the equation
+ ricDsolve(l:L, zeros:UP -> List F, ezfactor:UP -> Factored UP) ==
+ n := degree l
+ ans:List(QF) := empty()
+ for rec in singRicDE(l, ezfactor) repeat
+ ans := removeDuplicates_! concat_!(ans,
+ [rec.frac + f for f in nonSingSolve(n, rec.eq, zeros)])
+ #ans = n => return ans
+ ans
+
+-- there could be the same solutions coming in different ways, so we
+-- stop when the number of solutions reaches the order of the equation
+ nonSingSolve(n, l, zeros) ==
+ ans:List(QF) := empty()
+ for rec in polyRicDE(l, zeros) repeat
+ ans := removeDuplicates_! concat_!(ans, nopoly(n,rec.poly,rec.eq,zeros))
+ #ans = n => return ans
+ ans
+
+ constantRic(p, zeros) ==
+ zero? degree p => empty()
+ zeros squareFreePart p
+
+-- there could be the same solutions coming in different ways, so we
+-- stop when the number of solutions reaches the order of the equation
+ nopoly(n, p, l, zeros) ==
+ ans:List(QF) := empty()
+ for rec in constantCoefficientRicDE(l, constantRic(#1, zeros)) repeat
+ ans := removeDuplicates_! concat_!(ans,
+ [(rec.constant::UP + p)::QF + f for f in logDerOnly(rec.eq)])
+ #ans = n => return ans
+ ans
+
+-- returns [p1,...,pn] s.t. h(x,pi(x)) = 0 mod c(x)
+ solveModulo(c, h) ==
+ rec := genericPolynomial(dummy, degree(c)::Z - 1)
+ unk:SUP := 0
+ while not zero? h repeat
+ unk := unk + UP2SUP(leadingCoefficient h) * (rec.poly ** degree h)
+ h := reductum h
+ sol := ratsol solve(coefficients(monicDivide(unk,UP2SUP c).remainder),
+ rec.vars)
+ [mapeval(rec.poly, s.var, s.val) for s in sol]
+
+ if F has AlgebraicallyClosedField then
+ zro1: UP -> List F
+ zro : (UP, UP -> Factored UP) -> List F
+
+ ricDsolve(l:L) == ricDsolve(l, squareFree)
+ ricDsolve(l:LQ) == ricDsolve(l, squareFree)
+
+ ricDsolve(l:L, ezfactor:UP -> Factored UP) ==
+ ricDsolve(l, zro(#1, ezfactor), ezfactor)
+
+ ricDsolve(l:LQ, ezfactor:UP -> Factored UP) ==
+ ricDsolve(l, zro(#1, ezfactor), ezfactor)
+
+ zro(p, ezfactor) ==
+ concat [zro1(r.factor) for r in factors ezfactor p]
+
+ zro1 p ==
+ [zeroOf(map(#1, p)$UnivariatePolynomialCategoryFunctions2(F, UP,
+ F, SparseUnivariatePolynomial F))]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- Compile order for the differential equation solver:
+-- oderf.spad odealg.spad nlode.spad nlinsol.spad riccati.spad odeef.spad
+
+<<package ODEPRRIC PrimitiveRatRicDE>>
+<<package ODERTRIC RationalRicDE>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rinterp.spad.pamphlet b/src/algebra/rinterp.spad.pamphlet
new file mode 100644
index 00000000..41fa6c59
--- /dev/null
+++ b/src/algebra/rinterp.spad.pamphlet
@@ -0,0 +1,150 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rinterp.spad}
+\author{Martin Rubey}
+\maketitle
+\begin{abstract}
+Rational Interpolation
+\end{abstract}
+\eject
+\section{Introduction}
+This file contains a crude na\"ive implementation of rational interpolation,
+where the coefficients of the rational function are in any given field.
+
+\section{Questions and Outlook}
+\begin{itemize}
+\item Maybe this file should be joined with pinterp.spad, where polynomial
+ Lagrange interpolation is implemented. I have a second version that parallels
+ the structure of pinterp.spad closely.
+\item There are probably better ways to implement rational interpolation. Maybe
+ {http://www.cs.ucsb.edu/~omer/personal/abstracts/rational.html} contains
+ something useful, but I don't know.
+\item Comments welcome!
+\end{itemize}
+
+\section{RationalInterpolation}
+
+<<RINTERP Header>>=
+)abbrev package RINTERP RationalInterpolation
+++ Description:
+++ This package exports rational interpolation algorithms
+RationalInterpolation(xx,F): Exports == Implementation where
+ xx: Symbol
+ F: Field
+@
+
+<<RINTERP Exports>>=
+ Exports == with
+ interpolate: (List F, List F, NonNegativeInteger,
+ NonNegativeInteger) -> Fraction Polynomial F
+@
+
+The implementation sets up a system of linear equations and solves it.
+<<RINTERP Implementation>>=
+ Implementation == add
+ interpolate(xlist, ylist, m, k) ==
+@
+
+First we check whether we have the right number of points and values. Clearly
+the number of points and the number of values must be identical. Note that we
+want to determine the numerator and denominator polynomials only up to a
+factor. Thus, we want to determine $m+k+1$ coefficients, where $m$ is the degree
+of the polynomial in the numerator and $k$ is the degree of the polynomial in
+the denominator.
+
+In fact, we could also leave -- for example -- $k$ unspecified and determine it
+as $k=[[#xlist]]-m-1$: I don't know whether this would be better.
+<<RINTERP Implementation>>=
+ #xlist ^= #ylist =>
+ error "Different number of points and values."
+ #xlist ^= m+k+1 =>
+ error "wrong number of points"
+@
+
+The next step is to set up the matrix. Suppose that our numerator polynomial is
+$p(x)=a_0+a_1x+\dots+a_mx^m$ and that our denominator polynomial is
+$q(x)=b_0+b_1x+\dots+b_mx^m$. Then we have the following equations, writing $n$
+for $m+k+1$:
+\noindent
+$$
+\begin{array}{rl}
+ p(x_1)-y_1q(x_1)&=a_0+a_1x_1+\dots +a_mx_1^m-y_1(b_0+b_1x_1+\dots +b_kx_1^k)=0\\
+ p(x_2)-y_2q(x_2)&=a_0+a_1x_2+\dots +a_mx_2^m-y_2(b_0+b_1x_2+\dots +b_kx_2^k)=0\\
+ &\;\;\vdots\\
+ p(x_n)-y_nq(x_n)&=a_0+a_1x_n+\dots +a_mx_n^m-y_n(b_0+b_1x_n+\dots +b_kx_n^k)=0
+\end{array}
+$$
+This can be written as
+$$
+\left[
+\begin{array}{cccccccc}
+1&x_1&\dots&x_1^m&-y_1&-y_1x_1&\dots&-y_1x_1^k\\
+1&x_2&\dots&x_2^m&-y_2&-y_2x_2&\dots&-y_2x_2^k\\
+&&&\vdots&&&&\\
+1&x_n&\dots&x_n^m&-y_n&-y_nx_n&\dots&-y_nx_2^k
+\end{array}
+\right]
+\left[
+\begin{array}{c}
+a_0\\a_1\\\vdots\\a_m\\b_0\\b_1\\\vdots\\b_k
+\end{array}
+\right]
+=\mathbf 0
+$$
+We generate this matrix columnwise:
+<<RINTERP Implementation>>=
+ tempvec: List F := [1 for i in 1..(m+k+1)]
+
+ collist: List List F := cons(tempvec,
+ [(tempvec := [tempvec.i * xlist.i _
+ for i in 1..(m+k+1)]) _
+ for j in 1..max(m,k)])
+
+ collist := append([collist.j for j in 1..(m+1)], _
+ [[- collist.j.i * ylist.i for i in 1..(m+k+1)] _
+ for j in 1..(k+1)])
+@
+Now we can solve the system:
+<<RINTERP Implementation>>=
+ res: List Vector F := nullSpace((transpose matrix collist) _
+ ::Matrix F)
+@
+
+Note that it may happen that the system has several solutions. In this case,
+some of the data points may not be interpolated correctly. However, the
+solution is often still useful, thus we do not signal an error.
+
+<<RINTERP Implementation>>=
+ if #res~=1 then output("Warning: unattainable points!" _
+ ::OutputForm)$OutputPackage
+@
+
+In this situation, all the solutions will be equivalent, thus we can always
+simply take the first one:
+
+<<RINTERP Implementation>>=
+ reslist: List List Polynomial F := _
+ [[(res.1).(i+1)*(xx::Polynomial F)**i for i in 0..m], _
+ [(res.1).(i+m+2)*(xx::Polynomial F)**i for i in 0..k]]
+@
+Finally, we generate the rational function:
+<<RINTERP Implementation>>=
+ reduce((_+),reslist.1)/reduce((_+),reslist.2)
+@
+\section{Rational Interpolation Code}
+<<package RINTERP RationalInterpolation>>=
+<<RINTERP Header>>
+<<RINTERP Exports>>
+<<RINTERP Implementation>>
+@
+<<*>>=
+<<RINTERP Header>>
+<<RINTERP Exports>>
+<<RINTERP Implementation>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/routines.spad.pamphlet b/src/algebra/routines.spad.pamphlet
new file mode 100644
index 00000000..c491b23d
--- /dev/null
+++ b/src/algebra/routines.spad.pamphlet
@@ -0,0 +1,648 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra routines.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ROUTINE RoutinesTable}
+<<domain ROUTINE RoutinesTable>>=
+)abbrev domain ROUTINE RoutinesTable
+++ Author: Brian Dupee
+++ Date Created: August 1994
+++ Date Last Updated: December 1997
+++ Basic Operations: routines, getMeasure
+++ Related Constructors: TableAggregate(Symbol,Any)
+++ Description:
+++ \axiomType{RoutinesTable} implements a database and associated tuning
+++ mechanisms for a set of known NAG routines
+RoutinesTable(): E == I where
+ F ==> Float
+ ST ==> String
+ LST ==> List String
+ Rec ==> Record(key:Symbol,entry:Any)
+ RList ==> List(Record(key:Symbol,entry:Any))
+ IFL ==> List(Record(ifail:Integer,instruction:ST))
+ Entry ==> Record(chapter:ST, type:ST, domainName: ST,
+ defaultMin:F, measure:F, failList:IFL, explList:LST)
+
+ E ==> TableAggregate(Symbol,Any) with
+
+ concat:(%,%) -> %
+ ++ concat(x,y) merges two tables x and y
+ routines:() -> %
+ ++ routines() initialises a database of known NAG routines
+ selectIntegrationRoutines:% -> %
+ ++ selectIntegrationRoutines(R) chooses only those routines from
+ ++ the database which are for integration
+ selectOptimizationRoutines:% -> %
+ ++ selectOptimizationRoutines(R) chooses only those routines from
+ ++ the database which are for integration
+ selectPDERoutines:% -> %
+ ++ selectPDERoutines(R) chooses only those routines from the
+ ++ database which are for the solution of PDE's
+ selectODEIVPRoutines:% -> %
+ ++ selectODEIVPRoutines(R) chooses only those routines from the
+ ++ database which are for the solution of ODE's
+ selectFiniteRoutines:% -> %
+ ++ selectFiniteRoutines(R) chooses only those routines from the
+ ++ database which are designed for use with finite expressions
+ selectSumOfSquaresRoutines:% -> %
+ ++ selectSumOfSquaresRoutines(R) chooses only those routines from the
+ ++ database which are designed for use with sums of squares
+ selectNonFiniteRoutines:% -> %
+ ++ selectNonFiniteRoutines(R) chooses only those routines from the
+ ++ database which are designed for use with non-finite expressions.
+ selectMultiDimensionalRoutines:% -> %
+ ++ selectMultiDimensionalRoutines(R) chooses only those routines from
+ ++ the database which are designed for use with multi-dimensional
+ ++ expressions
+ changeThreshhold:(%,Symbol,F) -> %
+ ++ changeThreshhold(R,s,newValue) changes the value below which,
+ ++ given a NAG routine generating a higher measure, the routines will
+ ++ make no attempt to generate a measure.
+ changeMeasure:(%,Symbol,F) -> %
+ ++ changeMeasure(R,s,newValue) changes the maximum value for a
+ ++ measure of the given NAG routine.
+ getMeasure:(%,Symbol) -> F
+ ++ getMeasure(R,s) gets the current value of the maximum measure for
+ ++ the given NAG routine.
+ getExplanations:(%,ST) -> LST
+ ++ getExplanations(R,s) gets the explanations of the output parameters for
+ ++ the given NAG routine.
+ deleteRoutine!:(%,Symbol) -> %
+ ++ deleteRoutine!(R,s) destructively deletes the given routine from
+ ++ the current database of NAG routines
+ showTheRoutinesTable:() -> %
+ ++ showTheRoutinesTable() returns the current table of NAG routines.
+ recoverAfterFail:(%,ST,Integer) -> Union(ST,"failed")
+ ++ recoverAfterFail(routs,routineName,ifailValue) acts on the
+ ++ instructions given by the ifail list
+ finiteAggregate
+
+ I ==> Result add
+
+ Rep := Result
+ import Rep
+
+ theRoutinesTable:% := routines()
+
+ showTheRoutinesTable():% == theRoutinesTable
+
+ integrationRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,chapter) = "Integration"
+ false
+
+ selectIntegrationRoutines(R:%):% == select(integrationRoutine?,R)
+
+ optimizationRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,chapter) = "Optimization"
+ false
+
+ selectOptimizationRoutines(R:%):% == select(optimizationRoutine?,R)
+
+ PDERoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,chapter) = "PDE"
+ false
+
+ selectPDERoutines(R:%):% == select(PDERoutine?,R)
+
+ ODERoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,chapter) = "ODE"
+ false
+
+ selectODEIVPRoutines(R:%):% == select(ODERoutine?,R)
+
+ sumOfSquaresRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,type) = "SS"
+ false
+
+ selectSumOfSquaresRoutines(R:%):% == select(sumOfSquaresRoutine?,R)
+
+ finiteRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,type) = "One-dimensional finite"
+ false
+
+ selectFiniteRoutines(R:%):% == select(finiteRoutine?,R)
+
+ infiniteRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,type) = "One-dimensional infinite"
+ false
+
+ semiInfiniteRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,type) = "One-dimensional semi-infinite"
+ false
+
+ nonFiniteRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (semiInfiniteRoutine?(r) or infiniteRoutine?(r))
+
+ selectNonFiniteRoutines(R:%):% == select(nonFiniteRoutine?,R)
+
+ multiDimensionalRoutine?(r:Record(key:Symbol,entry:Any)):Boolean ==
+ (a := retractIfCan(r.entry)$AnyFunctions1(Entry)) case Entry =>
+ elt(a,type) = "Multi-dimensional"
+ false
+
+ selectMultiDimensionalRoutines(R:%):% == select(multiDimensionalRoutine?,R)
+
+ concat(a:%,b:%):% ==
+ membersOfa := (members(a)@List(Record(key:Symbol,entry:Any)))
+ membersOfb := (members(b)@List(Record(key:Symbol,entry:Any)))
+ allMembers:=
+ concat(membersOfa,membersOfb)$List(Record(key:Symbol,entry:Any))
+ construct(allMembers)
+
+ changeThreshhold(R:%,s:Symbol,newValue:F):% ==
+ (a := search(s,R)) case Any =>
+ e := retract(a)$AnyFunctions1(Entry)
+ e.defaultMin := newValue
+ a := coerce(e)$AnyFunctions1(Entry)
+ insert!([s,a],R)
+ error("changeThreshhold","Cannot find routine of that name")$ErrorFunctions
+
+ changeMeasure(R:%,s:Symbol,newValue:F):% ==
+ (a := search(s,R)) case Any =>
+ e := retract(a)$AnyFunctions1(Entry)
+ e.measure := newValue
+ a := coerce(e)$AnyFunctions1(Entry)
+ insert!([s,a],R)
+ error("changeMeasure","Cannot find routine of that name")$ErrorFunctions
+
+ getMeasure(R:%,s:Symbol):F ==
+ (a := search(s,R)) case Any =>
+ e := retract(a)$AnyFunctions1(Entry)
+ e.measure
+ error("getMeasure","Cannot find routine of that name")$ErrorFunctions
+
+ deleteRoutine!(R:%,s:Symbol):% ==
+ (a := search(s,R)) case Any =>
+ e:Record(key:Symbol,entry:Any) := [s,a]
+ remove!(e,R)
+ error("deleteRoutine!","Cannot find routine of that name")$ErrorFunctions
+
+ routines():% ==
+ f := "One-dimensional finite"
+ s := "One-dimensional semi-infinite"
+ i := "One-dimensional infinite"
+ m := "Multi-dimensional"
+ int := "Integration"
+ ode := "ODE"
+ pde := "PDE"
+ opt := "Optimization"
+ d01ajfExplList:LST := ["result: Calculated value of the integral",
+ "iw: iw(1) contains the actual number of sub-intervals used, the rest is workspace",
+ "w: contains the end-points of the sub-intervals used along with the integral contributions and error estimates over the sub-intervals",
+ "abserr: the estimate of the absolute error of the result",
+ "ifail: the error warning parameter",
+ "method: details of the method used and measures of all methods",
+ "attributes: a list of the attributes pertaining to the integrand which had some bearing on the choice of method"]
+ d01asfExplList:LST := ["result: Calculated value of the integral",
+ "iw: iw(1) contains the actual number of sub-intervals used, the rest is workspace",
+ "lst: contains the actual number of sub-intervals used",
+ "erlst: contains the error estimates over the sub-intervals",
+ "rslst: contains the integral contributions of the sub-intervals",
+ "ierlst: contains the error flags corresponding to the values in rslst",
+ "abserr: the estimate of the absolute error of the result",
+ "ifail: the error warning parameter",
+ "method: details of the method used and measures of all methods",
+ "attributes: a list of the attributes pertaining to the integrand which had some bearing on the choice of method"]
+ d01fcfExplList:LST := ["result: Calculated value of the integral",
+ "acc: the estimate of the relative error of the result",
+ "minpts: the number of integrand evaluations",
+ "ifail: the error warning parameter",
+ "method: details of the method used and measures of all methods",
+ "attributes: a list of the attributes pertaining to the integrand which had some bearing on the choice of method"]
+ d01transExplList:LST := ["result: Calculated value of the integral",
+ "abserr: the estimate of the absolute error of the result",
+ "method: details of the method and transformation used and measures of all methods",
+ "d01***AnnaTypeAnswer: the individual results from the routines",
+ "attributes: a list of the attributes pertaining to the integrand which had some bearing on the choice of method"]
+ d02bhfExplList:LST := ["x: the value of x at the end of the calculation",
+ "y: the computed values of Y\[1\]..Y\[n\] at x",
+ "tol: the (possible) estimate of the error; this is not guarunteed",
+ "ifail: the error warning parameter",
+ "method: details of the method used and measures of all methods",
+ "intensityFunctions: a list of the attributes and values pertaining to the ODE which had some bearing on the choice of method"]
+ d02bbfExplList:LST := concat(["result: the computed values of the solution at the required points"],d02bhfExplList)$LST
+ d03eefExplList:LST := ["See the NAG On-line Documentation for D03EEF/D03EDF",
+ "u: the computed solution u[i][j] is returned in u(i+(j-1)*ngx),for i = 1,2,..ngx; j = 1,2,..ngy"]
+ e04fdfExplList:LST := ["x: the position of the minimum",
+ "objf: the value of the objective function at x",
+ "ifail: the error warning parameter",
+ "method: details of the method used and measures of all methods",
+ "attributes: a list of the attributes pertaining to the function or functions which had some bearing on the choice of method"]
+ e04dgfExplList:LST := concat(e04fdfExplList,
+ ["objgrd: the values of the derivatives at x",
+ "iter: the number of iterations performed"])$LST
+ e04jafExplList:LST := concat(e04fdfExplList,
+ ["bu: the values of the upper bounds used",
+ "bl: the values of the lower bounds used"])$LST
+ e04ucfExplList:LST := concat(e04dgfExplList,
+ ["istate: the status of every constraint at x",
+ "clamda: the QP multipliers for the last QP sub-problem",
+ "For other output parameters see the NAG On-line Documentation for E04UCF"])$LST
+ e04mbfExplList:LST := concat(e04fdfExplList,
+ ["istate: the status of every constraint at x",
+ "clamda: the Lagrange multipliers for each constraint"])$LST
+ d01ajfIfail:IFL := [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"delete"], [6,"delete"]]
+ d01akfIfail:IFL := [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"]]
+ d01alfIfail:IFL := [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"delete"], [6,"delete"], [7,"delete"]]
+ d01amfIfail:IFL := [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"delete"], [6,"delete"]]
+ d01anfIfail:IFL := [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"delete"], [6,"delete"], [7,"delete"]]
+ d01apfIfail:IFL :=
+ [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"], [5,"delete"]]
+ d01aqfIfail:IFL :=
+ [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"], [5,"delete"]]
+ d01asfIfail:IFL := [[1,"incrFunEvals"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"delete"], [6,"delete"], [7,"delete"], [8,"delete"], [9,"delete"]]
+ d01fcfIfail:IFL := [[1,"delete"], [2,"incrFunEvals"], [3,"delete"]]
+ d01gbfIfail:IFL := [[1,"delete"], [2,"incrFunEvals"]]
+ d02bbfIfail:IFL :=
+ [[1,"delete"], [2,"decrease tolerance"], [3,"increase tolerance"],
+ [4,"delete"], [5,"delete"], [6,"delete"], [7,"delete"]]
+ d02bhfIfail:IFL :=
+ [[1,"delete"], [2,"decrease tolerance"], [3,"increase tolerance"],
+ [4,"no action"], [5,"delete"], [6,"delete"], [7,"delete"]]
+ d02cjfIfail:IFL :=
+ [[1,"delete"], [2,"decrease tolerance"], [3,"increase tolerance"],
+ [4,"delete"], [5,"delete"], [6,"no action"], [7,"delete"]]
+ d02ejfIfail:IFL :=
+ [[1,"delete"], [2,"decrease tolerance"], [3,"increase tolerance"],
+ [4,"delete"], [5,"delete"], [6,"no action"], [7,"delete"], [8,"delete"],
+ [9,"delete"]]
+ e04dgfIfail:IFL := [[3,"delete"], [4,"no action"], [6,"delete"],
+ [7,"delete"], [8,"delete"], [9,"delete"]]
+ e04fdfIfail:IFL :=
+ [[1,"delete"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"no action"], [6,"no action"], [7,"delete"], [8,"delete"]]
+ e04gcfIfail:IFL := [[1,"delete"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"no action"], [6,"no action"], [7,"delete"], [8,"delete"], [9,"delete"]]
+ e04jafIfail:IFL := [[1,"delete"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"no action"], [6,"no action"], [7,"delete"], [8,"delete"], [9,"delete"]]
+ e04mbfIfail:IFL :=
+ [[1,"delete"], [2,"delete"], [3,"delete"], [4,"delete"], [5,"delete"]]
+ e04nafIfail:IFL :=
+ [[1,"delete"], [2,"delete"], [3,"delete"], [4,"delete"], [5,"delete"],
+ [6,"delete"], [7,"delete"], [8,"delete"], [9,"delete"]]
+ e04ucfIfail:IFL := [[1,"delete"], [2,"delete"], [3,"delete"], [4,"delete"],
+ [5,"delete"], [6,"delete"], [7,"delete"], [8,"delete"], [9,"delete"]]
+ d01ajfEntry:Entry := [int, f, "d01ajfAnnaType",0.4,0.4,d01ajfIfail,d01ajfExplList]
+ d01akfEntry:Entry := [int, f, "d01akfAnnaType",0.6,1.0,d01akfIfail,d01ajfExplList]
+ d01alfEntry:Entry := [int, f, "d01alfAnnaType",0.6,0.6,d01alfIfail,d01ajfExplList]
+ d01amfEntry:Entry := [int, i, "d01amfAnnaType",0.5,0.5,d01amfIfail,d01ajfExplList]
+ d01anfEntry:Entry := [int, f, "d01anfAnnaType",0.6,0.9,d01anfIfail,d01ajfExplList]
+ d01apfEntry:Entry := [int, f, "d01apfAnnaType",0.7,0.7,d01apfIfail,d01ajfExplList]
+ d01aqfEntry:Entry := [int, f, "d01aqfAnnaType",0.6,0.7,d01aqfIfail,d01ajfExplList]
+ d01asfEntry:Entry := [int, s, "d01asfAnnaType",0.6,0.9,d01asfIfail,d01asfExplList]
+ d01transEntry:Entry:=[int, i, "d01TransformFunctionType",0.6,0.9,[],d01transExplList]
+ d01gbfEntry:Entry := [int, m, "d01gbfAnnaType",0.6,0.6,d01gbfIfail,d01fcfExplList]
+ d01fcfEntry:Entry := [int, m, "d01fcfAnnaType",0.5,0.5,d01fcfIfail,d01fcfExplList]
+ d02bbfEntry:Entry := [ode, "IVP", "d02bbfAnnaType",0.7,0.5,d02bbfIfail,d02bbfExplList]
+ d02bhfEntry:Entry := [ode, "IVP", "d02bhfAnnaType",0.7,0.49,d02bhfIfail,d02bhfExplList]
+ d02cjfEntry:Entry := [ode, "IVP", "d02cjfAnnaType",0.7,0.5,d02cjfIfail,d02bbfExplList]
+ d02ejfEntry:Entry := [ode, "IVP", "d02ejfAnnaType",0.7,0.5,d02ejfIfail,d02bbfExplList]
+ d03eefEntry:Entry := [pde, "2", "d03eefAnnaType",0.6,0.5,[],d03eefExplList]
+ --d03fafEntry:Entry := [pde, "3", "d03fafAnnaType",0.6,0.5,[],[]]
+ e04dgfEntry:Entry := [opt, "CGA", "e04dgfAnnaType",0.4,0.4,e04dgfIfail,e04dgfExplList]
+ e04fdfEntry:Entry := [opt, "SS", "e04fdfAnnaType",0.7,0.7,e04fdfIfail,e04fdfExplList]
+ e04gcfEntry:Entry := [opt, "SS", "e04gcfAnnaType",0.8,0.8,e04gcfIfail,e04fdfExplList]
+ e04jafEntry:Entry := [opt, "QNA", "e04jafAnnaType",0.5,0.5,e04jafIfail,e04jafExplList]
+ e04mbfEntry:Entry := [opt, "LP", "e04mbfAnnaType",0.7,0.7,e04mbfIfail,e04mbfExplList]
+ e04nafEntry:Entry := [opt, "QP", "e04nafAnnaType",0.7,0.7,e04nafIfail,e04mbfExplList]
+ e04ucfEntry:Entry := [opt, "SQP", "e04ucfAnnaType",0.6,0.6,e04ucfIfail,e04ucfExplList]
+ rl:RList :=
+ [["d01apf" :: Symbol, coerce(d01apfEntry)$AnyFunctions1(Entry)],_
+ ["d01aqf" :: Symbol, coerce(d01aqfEntry)$AnyFunctions1(Entry)],_
+ ["d01alf" :: Symbol, coerce(d01alfEntry)$AnyFunctions1(Entry)],_
+ ["d01anf" :: Symbol, coerce(d01anfEntry)$AnyFunctions1(Entry)],_
+ ["d01akf" :: Symbol, coerce(d01akfEntry)$AnyFunctions1(Entry)],_
+ ["d01ajf" :: Symbol, coerce(d01ajfEntry)$AnyFunctions1(Entry)],_
+ ["d01asf" :: Symbol, coerce(d01asfEntry)$AnyFunctions1(Entry)],_
+ ["d01amf" :: Symbol, coerce(d01amfEntry)$AnyFunctions1(Entry)],_
+ ["d01transform" :: Symbol, coerce(d01transEntry)$AnyFunctions1(Entry)],_
+ ["d01gbf" :: Symbol, coerce(d01gbfEntry)$AnyFunctions1(Entry)],_
+ ["d01fcf" :: Symbol, coerce(d01fcfEntry)$AnyFunctions1(Entry)],_
+ ["d02bbf" :: Symbol, coerce(d02bbfEntry)$AnyFunctions1(Entry)],_
+ ["d02bhf" :: Symbol, coerce(d02bhfEntry)$AnyFunctions1(Entry)],_
+ ["d02cjf" :: Symbol, coerce(d02cjfEntry)$AnyFunctions1(Entry)],_
+ ["d02ejf" :: Symbol, coerce(d02ejfEntry)$AnyFunctions1(Entry)],_
+ ["d03eef" :: Symbol, coerce(d03eefEntry)$AnyFunctions1(Entry)],_
+ --["d03faf" :: Symbol, coerce(d03fafEntry)$AnyFunctions1(Entry)],
+ ["e04dgf" :: Symbol, coerce(e04dgfEntry)$AnyFunctions1(Entry)],_
+ ["e04fdf" :: Symbol, coerce(e04fdfEntry)$AnyFunctions1(Entry)],_
+ ["e04gcf" :: Symbol, coerce(e04gcfEntry)$AnyFunctions1(Entry)],_
+ ["e04jaf" :: Symbol, coerce(e04jafEntry)$AnyFunctions1(Entry)],_
+ ["e04mbf" :: Symbol, coerce(e04mbfEntry)$AnyFunctions1(Entry)],_
+ ["e04naf" :: Symbol, coerce(e04nafEntry)$AnyFunctions1(Entry)],_
+ ["e04ucf" :: Symbol, coerce(e04ucfEntry)$AnyFunctions1(Entry)]]
+ construct(rl)
+
+ getIFL(s:Symbol,l:%):Union(IFL,"failed") ==
+ o := search(s,l)$%
+ o case "failed" => "failed"
+ e := retractIfCan(o)$AnyFunctions1(Entry)
+ e case "failed" => "failed"
+ e.failList
+
+ getInstruction(l:IFL,ifailValue:Integer):Union(ST,"failed") ==
+ output := empty()$ST
+ for i in 1..#l repeat
+ if ((l.i).ifail=ifailValue)@Boolean then
+ output := (l.i).instruction
+ empty?(output)$ST => "failed"
+ output
+
+ recoverAfterFail(routs:%,routineName:ST,
+ ifailValue:Integer):Union(ST,"failed") ==
+ name := routineName :: Symbol
+ failedList := getIFL(name,routs)
+ failedList case "failed" => "failed"
+ empty? failedList => "failed"
+ instr := getInstruction(failedList,ifailValue)
+ instr case "failed" => concat(routineName," failed")$ST
+ (instr = "delete")@Boolean =>
+ deleteRoutine!(routs,name)
+ concat(routineName," failed - trying alternatives")$ST
+ instr
+
+ getExplanations(R:%,routineName:ST):LST ==
+ name := routineName :: Symbol
+ (a := search(name,R)) case Any =>
+ e := retract(a)$AnyFunctions1(Entry)
+ e.explList
+ empty()$LST
+
+@
+\section{domain ATTRBUT AttributeButtons}
+<<domain ATTRBUT AttributeButtons>>=
+)abbrev domain ATTRBUT AttributeButtons
+++ Author: Brian Dupee
+++ Date Created: April 1996
+++ Date Last Updated: December 1997
+++ Basic Operations: increase, decrease, getButtonValue, setButtonValue
+++ Related Constructors: Table(String,Float)
+++ Description:
+++ \axiomType{AttributeButtons} implements a database and associated
+++ adjustment mechanisms for a set of attributes.
+++
+++ For ODEs these attributes are "stiffness", "stability" (i.e. how much
+++ affect the cosine or sine component of the solution has on the stability of
+++ the result), "accuracy" and "expense" (i.e. how expensive is the evaluation
+++ of the ODE). All these have bearing on the cost of calculating the
+++ solution given that reducing the step-length to achieve greater accuracy
+++ requires considerable number of evaluations and calculations.
+++
+++ The effect of each of these attributes can be altered by increasing or
+++ decreasing the button value.
+++
+++ For Integration there is a button for increasing and decreasing the preset
+++ number of function evaluations for each method. This is automatically used
+++ by ANNA when a method fails due to insufficient workspace or where the
+++ limit of function evaluations has been reached before the required
+++ accuracy is achieved.
+++
+AttributeButtons(): E == I where
+ F ==> Float
+ ST ==> String
+ LST ==> List String
+ Rec ==> Record(key:Symbol,entry:Any)
+ RList ==> List(Record(key:Symbol,entry:Any))
+ IFL ==> List(Record(ifail:Integer,instruction:ST))
+ Entry ==> Record(chapter:ST, type:ST, domainName: ST,
+ defaultMin:F, measure:F, failList:IFL, explList:LST)
+
+
+ E ==> SetCategory with
+
+ increase:(ST,ST) -> F
+ ++ \axiom{increase(routineName,attributeName)} increases the value
+ ++ for the effect of the attribute \axiom{attributeName} with routine
+ ++ \axiom{routineName}.
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ increase:(ST) -> F
+ ++ \axiom{increase(attributeName)} increases the value for the
+ ++ effect of the attribute \axiom{attributeName} with all routines.
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ decrease:(ST,ST) -> F
+ ++ \axiom{decrease(routineName,attributeName)} decreases the value
+ ++ for the effect of the attribute \axiom{attributeName} with routine
+ ++ \axiom{routineName}.
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ decrease:(ST) -> F
+ ++ \axiom{decrease(attributeName)} decreases the value for the
+ ++ effect of the attribute \axiom{attributeName} with all routines.
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ getButtonValue:(ST,ST) -> F
+ ++ \axiom{getButtonValue(routineName,attributeName)} returns the
+ ++ current value for the effect of the attribute \axiom{attributeName}
+ ++ with routine \axiom{routineName}.
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ resetAttributeButtons:() -> Void
+ ++ \axiom{resetAttributeButtons()} resets the Attribute buttons to a
+ ++ neutral level.
+ setAttributeButtonStep:(F) -> F
+ ++ \axiom{setAttributeButtonStep(n)} sets the value of the steps for
+ ++ increasing and decreasing the button values. \axiom{n} must be
+ ++ greater than 0 and less than 1. The preset value is 0.5.
+ setButtonValue:(ST,F) -> F
+ ++ \axiom{setButtonValue(attributeName,n)} sets the
+ ++ value of all buttons of attribute \spad{attributeName}
+ ++ to \spad{n}. \spad{n} must be in the range [0..1].
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ setButtonValue:(ST,ST,F) -> F
+ ++ \axiom{setButtonValue(attributeName,routineName,n)} sets the
+ ++ value of the button of attribute \spad{attributeName} to routine
+ ++ \spad{routineName} to \spad{n}. \spad{n} must be in the range [0..1].
+ ++
+ ++ \axiom{attributeName} should be one of the values
+ ++ "stiffness", "stability", "accuracy", "expense" or
+ ++ "functionEvaluations".
+ finiteAggregate
+
+ I ==> add
+
+ Rep := StringTable(F)
+ import Rep
+
+ buttons:() -> $
+
+ buttons():$ ==
+ eList := empty()$List(Record(key:ST,entry:F))
+ l1:List String := ["stability","stiffness","accuracy","expense"]
+ l2:List String := ["functionEvaluations"]
+ ro1 := selectODEIVPRoutines(r := routines()$RoutinesTable)$RoutinesTable
+ ro2 := selectIntegrationRoutines(r)$RoutinesTable
+ k1:List String := [string(i)$Symbol for i in keys(ro1)$RoutinesTable]
+ k2:List String := [string(i)$Symbol for i in keys(ro2)$RoutinesTable]
+ for i in k1 repeat
+ for j in l1 repeat
+ e:Record(key:ST,entry:F) := [i j,0.5]
+ eList := cons(e,eList)$List(Record(key:ST,entry:F))
+ for i in k2 repeat
+ for j in l2 repeat
+ e:Record(key:ST,entry:F) := [i j,0.5]
+ eList := cons(e,eList)$List(Record(key:ST,entry:F))
+ construct(eList)$Rep
+
+ attributeButtons:$ := buttons()
+
+ attributeStep:F := 0.5
+
+ setAttributeButtonStep(n:F):F ==
+ positive?(n)$F and (n<1$F) => attributeStep:F := n
+ error("setAttributeButtonStep","New value must be in (0..1)")$ErrorFunctions
+
+ resetAttributeButtons():Void ==
+ attributeButtons := buttons()
+ void()$Void
+
+ setButtonValue(routineName:ST,attributeName:ST,n:F):F ==
+ f := search(routineName attributeName,attributeButtons)$Rep
+ f case Float =>
+ n>=0$F and n<=1$F =>
+ setelt(attributeButtons,routineName attributeName,n)$Rep
+ error("setAttributeButtonStep","New value must be in [0..1]")$ErrorFunctions
+ error("setButtonValue","attribute name " attributeName
+ " not found for routine " routineName)$ErrorFunctions
+
+ setButtonValue(attributeName:ST,n:F):F ==
+ ro1 := selectODEIVPRoutines(r := routines()$RoutinesTable)$RoutinesTable
+ ro2 := selectIntegrationRoutines(r)$RoutinesTable
+ l1:List String := ["stability","stiffness","accuracy","expense"]
+ l2:List String := ["functionEvaluations"]
+ if attributeName="functionEvaluations" then
+ for i in keys(ro2)$RoutinesTable repeat
+ setButtonValue(string(i)$Symbol,attributeName,n)
+ else
+ for i in keys(ro1)$RoutinesTable repeat
+ setButtonValue(string(i)$Symbol,attributeName,n)
+ n
+
+ increase(routineName:ST,attributeName:ST):F ==
+ f := search(routineName attributeName,attributeButtons)$Rep
+ f case Float =>
+ newValue:F := (1$F-attributeStep)*f+attributeStep
+ setButtonValue(routineName,attributeName,newValue)
+ error("increase","attribute name " attributeName
+ " not found for routine " routineName)$ErrorFunctions
+
+ increase(attributeName:ST):F ==
+ ro1 := selectODEIVPRoutines(r := routines()$RoutinesTable)$RoutinesTable
+ ro2 := selectIntegrationRoutines(r)$RoutinesTable
+ l1:List String := ["stability","stiffness","accuracy","expense"]
+ l2:List String := ["functionEvaluations"]
+ if attributeName="functionEvaluations" then
+ for i in keys(ro2)$RoutinesTable repeat
+ increase(string(i)$Symbol,attributeName)
+ else
+ for i in keys(ro1)$RoutinesTable repeat
+ increase(string(i)$Symbol,attributeName)
+ getButtonValue(string(i)$Symbol,attributeName)
+
+ decrease(routineName:ST,attributeName:ST):F ==
+ f := search(routineName attributeName,attributeButtons)$Rep
+ f case Float =>
+ newValue:F := (1$F-attributeStep)*f
+ setButtonValue(routineName,attributeName,newValue)
+ error("increase","attribute name " attributeName
+ " not found for routine " routineName)$ErrorFunctions
+
+ decrease(attributeName:ST):F ==
+ ro1 := selectODEIVPRoutines(r := routines()$RoutinesTable)$RoutinesTable
+ ro2 := selectIntegrationRoutines(r)$RoutinesTable
+ l1:List String := ["stability","stiffness","accuracy","expense"]
+ l2:List String := ["functionEvaluations"]
+ if attributeName="functionEvaluations" then
+ for i in keys(ro2)$RoutinesTable repeat
+ decrease(string(i)$Symbol,attributeName)
+ else
+ for i in keys(ro1)$RoutinesTable repeat
+ decrease(string(i)$Symbol,attributeName)
+ getButtonValue(string(i)$Symbol,attributeName)
+
+
+ getButtonValue(routineName:ST,attributeName:ST):F ==
+ f := search(routineName attributeName,attributeButtons)$Rep
+ f case Float => f
+ error("getButtonValue","attribute name " attributeName
+ " not found for routine " routineName)$ErrorFunctions
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ROUTINE RoutinesTable>>
+<<domain ATTRBUT AttributeButtons>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/rule.spad.pamphlet b/src/algebra/rule.spad.pamphlet
new file mode 100644
index 00000000..ce3011bc
--- /dev/null
+++ b/src/algebra/rule.spad.pamphlet
@@ -0,0 +1,349 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra rule.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain RULE RewriteRule}
+<<domain RULE RewriteRule>>=
+)abbrev domain RULE RewriteRule
+++ Rules for the pattern matcher
+++ Author: Manuel Bronstein
+++ Date Created: 24 Oct 1988
+++ Date Last Updated: 26 October 1993
+++ Keywords: pattern, matching, rule.
+RewriteRule(Base, R, F): Exports == Implementation where
+ Base : SetCategory
+ R : Join(Ring, PatternMatchable Base, OrderedSet,
+ ConvertibleTo Pattern Base)
+ F : Join(FunctionSpace R, PatternMatchable Base,
+ ConvertibleTo Pattern Base)
+
+ P ==> Pattern Base
+
+ Exports ==>
+ Join(SetCategory, Eltable(F, F), RetractableTo Equation F) with
+ rule : (F, F) -> $
+ ++ rule(f, g) creates the rewrite rule: \spad{f == eval(g, g is f)},
+ ++ with left-hand side f and right-hand side g.
+ rule : (F, F, List Symbol) -> $
+ ++ rule(f, g, [f1,...,fn]) creates the rewrite rule
+ ++ \spad{f == eval(eval(g, g is f), [f1,...,fn])},
+ ++ that is a rule with left-hand side f and right-hand side g;
+ ++ The symbols f1,...,fn are the operators that are considered
+ ++ quoted, that is they are not evaluated during any rewrite,
+ ++ but just applied formally to their arguments.
+ suchThat: ($, List Symbol, List F -> Boolean) -> $
+ ++ suchThat(r, [a1,...,an], f) returns the rewrite rule r with
+ ++ the predicate \spad{f(a1,...,an)} attached to it.
+ pattern : $ -> P
+ ++ pattern(r) returns the pattern corresponding to
+ ++ the left hand side of the rule r.
+ lhs : $ -> F
+ ++ lhs(r) returns the left hand side of the rule r.
+ rhs : $ -> F
+ ++ rhs(r) returns the right hand side of the rule r.
+ elt : ($, F, PositiveInteger) -> F
+ ++ elt(r,f,n) or r(f, n) applies the rule r to f at most n times.
+ quotedOperators: $ -> List Symbol
+ ++ quotedOperators(r) returns the list of operators
+ ++ on the right hand side of r that are considered
+ ++ quoted, that is they are not evaluated during any rewrite,
+ ++ but just applied formally to their arguments.
+
+ Implementation ==> add
+ import ApplyRules(Base, R, F)
+ import PatternFunctions1(Base, F)
+ import FunctionSpaceAssertions(R, F)
+
+ Rep := Record(pat: P, lft: F, rgt: F, qot: List Symbol)
+
+ mkRule : (P, F, F, List Symbol) -> $
+ transformLhs: P -> Record(plus: F, times: F)
+ bad? : Union(List P, "failed") -> Boolean
+ appear? : (P, List P) -> Boolean
+ opt : F -> P
+ F2Symbol : F -> F
+
+ pattern x == x.pat
+ lhs x == x.lft
+ rhs x == x.rgt
+ quotedOperators x == x.qot
+ mkRule(pt, p, s, l) == [pt, p, s, l]
+ coerce(eq:Equation F):$ == rule(lhs eq, rhs eq, empty())
+ rule(l, r) == rule(l, r, empty())
+ elt(r:$, s:F) == applyRules([r pretend RewriteRule(Base, R, F)], s)
+
+ suchThat(x, l, f) ==
+ mkRule(suchThat(pattern x,l,f), lhs x, rhs x, quotedOperators x)
+
+ x = y ==
+ (lhs x = lhs y) and (rhs x = rhs y) and
+ (quotedOperators x = quotedOperators y)
+
+ elt(r:$, s:F, n:PositiveInteger) ==
+ applyRules([r pretend RewriteRule(Base, R, F)], s, n)
+
+-- remove the extra properties from the constant symbols in f
+ F2Symbol f ==
+ l := select_!(symbolIfCan #1 case Symbol, tower f)$List(Kernel F)
+ eval(f, l, [symbolIfCan(k)::Symbol::F for k in l])
+
+ retractIfCan r ==
+ constant? pattern r =>
+ (u:= retractIfCan(lhs r)@Union(Kernel F,"failed")) case "failed"
+ => "failed"
+ F2Symbol(u::Kernel(F)::F) = rhs r
+ "failed"
+
+ rule(p, s, l) ==
+ lh := transformLhs(pt := convert(p)@P)
+ mkRule(opt(lh.times) * (opt(lh.plus) + pt),
+ lh.times * (lh.plus + p), lh.times * (lh.plus + s), l)
+
+ opt f ==
+ retractIfCan(f)@Union(R, "failed") case R => convert f
+ convert optional f
+
+-- appear?(x, [p1,...,pn]) is true if x appears as a variable in
+-- a composite pattern pi.
+ appear?(x, l) ==
+ for p in l | p ^= x repeat
+ member?(x, variables p) => return true
+ false
+
+-- a sum/product p1 @ ... @ pn is "bad" if it will not match
+-- a sum/product p1 @ ... @ pn @ p(n+1)
+-- in which case one should transform p1 @ ... @ pn to
+-- p1 @ ... @ ?p(n+1) which does not change its meaning.
+-- examples of "bad" combinations
+-- sin(x) @ sin(y) sin(x) @ x
+-- examples of "good" combinations
+-- sin(x) @ y
+ bad? u ==
+ u case List(P) =>
+ for x in u::List(P) repeat
+ generic? x and not appear?(x, u::List(P)) => return false
+ true
+ false
+
+ transformLhs p ==
+ bad? isPlus p => [new()$Symbol :: F, 1]
+ bad? isTimes p => [0, new()$Symbol :: F]
+ [0, 1]
+
+ coerce(x:$):OutputForm ==
+ infix(" == "::Symbol::OutputForm,
+ lhs(x)::OutputForm, rhs(x)::OutputForm)
+
+@
+\section{package APPRULE ApplyRules}
+<<package APPRULE ApplyRules>>=
+)abbrev package APPRULE ApplyRules
+++ Applications of rules to expressions
+++ Author: Manuel Bronstein
+++ Date Created: 20 Mar 1990
+++ Date Last Updated: 5 Jul 1990
+++ Description:
+++ This package apply rewrite rules to expressions, calling
+++ the pattern matcher.
+++ Keywords: pattern, matching, rule.
+ApplyRules(Base, R, F): Exports == Implementation where
+ Base : SetCategory
+ R : Join(Ring, PatternMatchable Base, OrderedSet,
+ ConvertibleTo Pattern Base)
+ F : Join(FunctionSpace R, PatternMatchable Base,
+ ConvertibleTo Pattern Base)
+
+ P ==> Pattern Base
+ PR ==> PatternMatchResult(Base, F)
+ RR ==> RewriteRule(Base, R, F)
+ K ==> Kernel F
+
+ Exports ==> with
+ applyRules : (List RR, F) -> F
+ ++ applyRules([r1,...,rn], expr) applies the rules
+ ++ r1,...,rn to f an unlimited number of times, i.e. until
+ ++ none of r1,...,rn is applicable to the expression.
+ applyRules : (List RR, F, PositiveInteger) -> F
+ ++ applyRules([r1,...,rn], expr, n) applies the rules
+ ++ r1,...,rn to f a most n times.
+ localUnquote: (F, List Symbol) -> F
+ ++ localUnquote(f,ls) is a local function.
+
+ Implementation ==> add
+ import PatternFunctions1(Base, F)
+
+ splitRules: List RR -> Record(lker: List K,lval: List F,rl: List RR)
+ localApply : (List K, List F, List RR, F, PositiveInteger) -> F
+ rewrite : (F, PR, List Symbol) -> F
+ app : (List RR, F) -> F
+ applist : (List RR, List F) -> List F
+ isit : (F, P) -> PR
+ isitwithpred: (F, P, List P, List PR) -> PR
+
+ applist(lrule, arglist) == [app(lrule, arg) for arg in arglist]
+
+ splitRules l ==
+ ncr := empty()$List(RR)
+ lk := empty()$List(K)
+ lv := empty()$List(F)
+ for r in l repeat
+ if (u := retractIfCan(r)@Union(Equation F, "failed"))
+ case "failed" then ncr := concat(r, ncr)
+ else
+ lk := concat(retract(lhs(u::Equation F))@K, lk)
+ lv := concat(rhs(u::Equation F), lv)
+ [lk, lv, ncr]
+
+ applyRules(l, s) ==
+ rec := splitRules l
+ repeat
+ (new:= localApply(rec.lker,rec.lval,rec.rl,s,1)) = s => return s
+ s := new
+
+ applyRules(l, s, n) ==
+ rec := splitRules l
+ localApply(rec.lker, rec.lval, rec.rl, s, n)
+
+ localApply(lk, lv, lrule, subject, n) ==
+ for i in 1..n repeat
+ for k in lk for v in lv repeat
+ subject := eval(subject, k, v)
+ subject := app(lrule, subject)
+ subject
+
+ rewrite(f, res, l) ==
+ lk := empty()$List(K)
+ lv := empty()$List(F)
+ for rec in destruct res repeat
+ lk := concat(kernel(rec.key), lk)
+ lv := concat(rec.entry, lv)
+ localUnquote(eval(f, lk, lv), l)
+
+ if R has ConvertibleTo InputForm then
+ localUnquote(f, l) ==
+ empty? l => f
+ eval(f, l)
+ else
+ localUnquote(f, l) == f
+
+ isitwithpred(subject, pat, vars, bad) ==
+ failed?(u := patternMatch(subject, pat, new()$PR)) => u
+ satisfy?(u, pat)::Boolean => u
+ member?(u, bad) => failed()
+ for v in vars repeat addBadValue(v, getMatch(v, u)::F)
+ isitwithpred(subject, pat, vars, concat(u, bad))
+
+ isit(subject, pat) ==
+ hasTopPredicate? pat =>
+ for v in (l := variables pat) repeat resetBadValues v
+ isitwithpred(subject, pat, l, empty())
+ patternMatch(subject, pat, new()$PR)
+
+ app(lrule, subject) ==
+ for r in lrule repeat
+ not failed?(u := isit(subject, pattern r)) =>
+ return rewrite(rhs r, u, quotedOperators r)
+ (k := retractIfCan(subject)@Union(K, "failed")) case K =>
+ operator(k::K) applist(lrule, argument(k::K))
+ (l := isPlus subject) case List(F) => +/applist(lrule,l::List(F))
+ (l := isTimes subject) case List(F) => */applist(lrule,l::List(F))
+ (e := isPower subject) case Record(val:F, exponent:Integer) =>
+ ee := e::Record(val:F, exponent:Integer)
+ f := app(lrule, ee.val)
+ positive?(ee.exponent) => f ** (ee.exponent)::NonNegativeInteger
+ recip(f)::F ** (- ee.exponent)::NonNegativeInteger
+ subject
+
+@
+\section{domain RULESET Ruleset}
+<<domain RULESET Ruleset>>=
+)abbrev domain RULESET Ruleset
+++ Sets of rules for the pattern matcher
+++ Author: Manuel Bronstein
+++ Date Created: 20 Mar 1990
+++ Date Last Updated: 29 Jun 1990
+++ Description:
+++ A ruleset is a set of pattern matching rules grouped together.
+++ Keywords: pattern, matching, rule.
+Ruleset(Base, R, F): Exports == Implementation where
+ Base : SetCategory
+ R : Join(Ring, PatternMatchable Base, OrderedSet,
+ ConvertibleTo Pattern Base)
+ F : Join(FunctionSpace R, PatternMatchable Base,
+ ConvertibleTo Pattern Base)
+
+ RR ==> RewriteRule(Base, R, F)
+
+ Exports ==> Join(SetCategory, Eltable(F, F)) with
+ ruleset: List RR -> $
+ ++ ruleset([r1,...,rn]) creates the rule set \spad{{r1,...,rn}}.
+ rules : $ -> List RR
+ ++ rules(r) returns the rules contained in r.
+ elt : ($, F, PositiveInteger) -> F
+ ++ elt(r,f,n) or r(f, n) applies all the rules of r to f at most n times.
+
+ Implementation ==> add
+ import ApplyRules(Base, R, F)
+
+ Rep := Set RR
+
+ ruleset l == {l}$Rep
+ coerce(x:$):OutputForm == coerce(x)$Rep
+ x = y == x =$Rep y
+ elt(x:$, f:F) == applyRules(rules x, f)
+ elt(r:$, s:F, n:PositiveInteger) == applyRules(rules r, s, n)
+ rules x == parts(x)$Rep
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain RULE RewriteRule>>
+<<package APPRULE ApplyRules>>
+<<domain RULESET Ruleset>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/s.spad.pamphlet b/src/algebra/s.spad.pamphlet
new file mode 100644
index 00000000..7da7e734
--- /dev/null
+++ b/src/algebra/s.spad.pamphlet
@@ -0,0 +1,833 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra s.spad}
+\author{Godfrey Nolan, Mike Dewar}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NAGS NagSpecialFunctionsPackage}
+<<package NAGS NagSpecialFunctionsPackage>>=
+)abbrev package NAGS NagSpecialFunctionsPackage
+++ Author: Godfrey Nolan and Mike Dewar
+++ Date Created: Jan 1994
+++ Date Last Updated: Thu May 12 17:45:44 1994
+++Description:
+++This package uses the NAG Library to compute some commonly
+++occurring physical and mathematical functions.
+++See \downlink{Manual Page}{manpageXXs}.
+NagSpecialFunctionsPackage(): Exports == Implementation where
+ S ==> Symbol
+ FOP ==> FortranOutputStackPackage
+
+ Exports ==> with
+ s01eaf : (Complex DoubleFloat,Integer) -> Result
+ ++ s01eaf(z,ifail)
+ ++ S01EAF evaluates the exponential function exp(z) , for complex z.
+ ++ See \downlink{Manual Page}{manpageXXs01eaf}.
+ s13aaf : (DoubleFloat,Integer) -> Result
+ ++ s13aaf(x,ifail)
+ ++ returns the value of the exponential integral
+ ++ E (x), via the routine name.
+ ++ 1
+ ++ See \downlink{Manual Page}{manpageXXs13aaf}.
+ s13acf : (DoubleFloat,Integer) -> Result
+ ++ s13acf(x,ifail)
+ ++ returns the value of the cosine integral
+ ++ See \downlink{Manual Page}{manpageXXs13acf}.
+ s13adf : (DoubleFloat,Integer) -> Result
+ ++ s13adf(x,ifail)
+ ++ returns the value of the sine integral
+ ++ See \downlink{Manual Page}{manpageXXs13adf}.
+ s14aaf : (DoubleFloat,Integer) -> Result
+ ++ s14aaf(x,ifail) returns the value of the Gamma function (Gamma)(x), via
+ ++ the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs14aaf}.
+ s14abf : (DoubleFloat,Integer) -> Result
+ ++ s14abf(x,ifail) returns a value for the log, ln(Gamma(x)), via
+ ++ the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs14abf}.
+ s14baf : (DoubleFloat,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ s14baf(a,x,tol,ifail)
+ ++ computes values for the incomplete gamma functions P(a,x)
+ ++ and Q(a,x).
+ ++ See \downlink{Manual Page}{manpageXXs14baf}.
+ s15adf : (DoubleFloat,Integer) -> Result
+ ++ s15adf(x,ifail)
+ ++ returns the value of the complementary error function,
+ ++ erfc(x), via the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs15adf}.
+ s15aef : (DoubleFloat,Integer) -> Result
+ ++ s15aef(x,ifail)
+ ++ returns the value of the error function erf(x), via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs15aef}.
+ s17acf : (DoubleFloat,Integer) -> Result
+ ++ s17acf(x,ifail)
+ ++ returns the value of the Bessel Function
+ ++ Y (x), via the routine name.
+ ++ 0
+ ++ See \downlink{Manual Page}{manpageXXs17acf}.
+ s17adf : (DoubleFloat,Integer) -> Result
+ ++ s17adf(x,ifail)
+ ++ returns the value of the Bessel Function
+ ++ Y (x), via the routine name.
+ ++ 1
+ ++ See \downlink{Manual Page}{manpageXXs17adf}.
+ s17aef : (DoubleFloat,Integer) -> Result
+ ++ s17aef(x,ifail)
+ ++ returns the value of the Bessel Function
+ ++ J (x), via the routine name.
+ ++ 0
+ ++ See \downlink{Manual Page}{manpageXXs17aef}.
+ s17aff : (DoubleFloat,Integer) -> Result
+ ++ s17aff(x,ifail)
+ ++ returns the value of the Bessel Function
+ ++ J (x), via the routine name.
+ ++ 1
+ ++ See \downlink{Manual Page}{manpageXXs17aff}.
+ s17agf : (DoubleFloat,Integer) -> Result
+ ++ s17agf(x,ifail)
+ ++ returns a value for the Airy function, Ai(x), via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs17agf}.
+ s17ahf : (DoubleFloat,Integer) -> Result
+ ++ s17ahf(x,ifail)
+ ++ returns a value of the Airy function, Bi(x), via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs17ahf}.
+ s17ajf : (DoubleFloat,Integer) -> Result
+ ++ s17ajf(x,ifail)
+ ++ returns a value of the derivative of the Airy function
+ ++ Ai(x), via the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs17ajf}.
+ s17akf : (DoubleFloat,Integer) -> Result
+ ++ s17akf(x,ifail)
+ ++ returns a value for the derivative of the Airy function
+ ++ Bi(x), via the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs17akf}.
+ s17dcf : (DoubleFloat,Complex DoubleFloat,Integer,String,_
+ Integer) -> Result
+ ++ s17dcf(fnu,z,n,scale,ifail)
+ ++ returns a sequence of values for the Bessel functions
+ ++ Y (z) for complex z, non-negative (nu) and n=0,1,...,N-1,
+ ++ (nu)+n
+ ++ with an option for exponential scaling.
+ ++ See \downlink{Manual Page}{manpageXXs17dcf}.
+ s17def : (DoubleFloat,Complex DoubleFloat,Integer,String,_
+ Integer) -> Result
+ ++ s17def(fnu,z,n,scale,ifail)
+ ++ returns a sequence of values for the Bessel functions
+ ++ J (z) for complex z, non-negative (nu) and n=0,1,...,N-1,
+ ++ (nu)+n
+ ++ with an option for exponential scaling.
+ ++ See \downlink{Manual Page}{manpageXXs17def}.
+ s17dgf : (String,Complex DoubleFloat,String,Integer) -> Result
+ ++ s17dgf(deriv,z,scale,ifail)
+ ++ returns the value of the Airy function Ai(z) or its
+ ++ derivative Ai'(z) for complex z, with an option for exponential
+ ++ scaling.
+ ++ See \downlink{Manual Page}{manpageXXs17dgf}.
+ s17dhf : (String,Complex DoubleFloat,String,Integer) -> Result
+ ++ s17dhf(deriv,z,scale,ifail)
+ ++ returns the value of the Airy function Bi(z) or its
+ ++ derivative Bi'(z) for complex z, with an option for exponential
+ ++ scaling.
+ ++ See \downlink{Manual Page}{manpageXXs17dhf}.
+ s17dlf : (Integer,DoubleFloat,Complex DoubleFloat,Integer,_
+ String,Integer) -> Result
+ ++ s17dlf(m,fnu,z,n,scale,ifail)
+ ++ returns a sequence of values for the Hankel functions
+ ++ (1) (2)
+ ++ H (z) or H (z) for complex z, non-negative (nu) and
+ ++ (nu)+n (nu)+n
+ ++ n=0,1,...,N-1, with an option for exponential scaling.
+ ++ See \downlink{Manual Page}{manpageXXs17dlf}.
+ s18acf : (DoubleFloat,Integer) -> Result
+ ++ s18acf(x,ifail)
+ ++ returns the value of the modified Bessel Function
+ ++ K (x), via the routine name.
+ ++ 0
+ ++ See \downlink{Manual Page}{manpageXXs18acf}.
+ s18adf : (DoubleFloat,Integer) -> Result
+ ++ s18adf(x,ifail)
+ ++ returns the value of the modified Bessel Function
+ ++ K (x), via the routine name.
+ ++ 1
+ ++ See \downlink{Manual Page}{manpageXXs18adf}.
+ s18aef : (DoubleFloat,Integer) -> Result
+ ++ s18aef(x,ifail)
+ ++ returns the value of the modified Bessel Function
+ ++ I (x), via the routine name.
+ ++ 0
+ ++ See \downlink{Manual Page}{manpageXXs18aef}.
+ s18aff : (DoubleFloat,Integer) -> Result
+ ++ s18aff(x,ifail)
+ ++ returns a value for the modified Bessel Function
+ ++ I (x), via the routine name.
+ ++ 1
+ ++ See \downlink{Manual Page}{manpageXXs18aff}.
+ s18dcf : (DoubleFloat,Complex DoubleFloat,Integer,String,_
+ Integer) -> Result
+ ++ s18dcf(fnu,z,n,scale,ifail)
+ ++ returns a sequence of values for the modified Bessel functions
+ ++ K (z) for complex z, non-negative (nu) and
+ ++ (nu)+n
+ ++ n=0,1,...,N-1, with an option for exponential scaling.
+ ++ See \downlink{Manual Page}{manpageXXs18dcf}.
+ s18def : (DoubleFloat,Complex DoubleFloat,Integer,String,_
+ Integer) -> Result
+ ++ s18def(fnu,z,n,scale,ifail)
+ ++ returns a sequence of values for the modified Bessel functions
+ ++ I (z) for complex z, non-negative (nu) and
+ ++ (nu)+n
+ ++ n=0,1,...,N-1, with an option for exponential scaling.
+ ++ See \downlink{Manual Page}{manpageXXs18def}.
+ s19aaf : (DoubleFloat,Integer) -> Result
+ ++ s19aaf(x,ifail)
+ ++ returns a value for the Kelvin function ber(x) via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs19aaf}.
+ s19abf : (DoubleFloat,Integer) -> Result
+ ++ s19abf(x,ifail)
+ ++ returns a value for the Kelvin function bei(x) via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs19abf}.
+ s19acf : (DoubleFloat,Integer) -> Result
+ ++ s19acf(x,ifail)
+ ++ returns a value for the Kelvin function ker(x), via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs19acf}.
+ s19adf : (DoubleFloat,Integer) -> Result
+ ++ s19adf(x,ifail)
+ ++ returns a value for the Kelvin function kei(x) via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs19adf}.
+ s20acf : (DoubleFloat,Integer) -> Result
+ ++ s20acf(x,ifail)
+ ++ returns a value for the Fresnel Integral S(x), via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs20acf}.
+ s20adf : (DoubleFloat,Integer) -> Result
+ ++ s20adf(x,ifail)
+ ++ returns a value for the Fresnel Integral C(x), via the
+ ++ routine name.
+ ++ See \downlink{Manual Page}{manpageXXs20adf}.
+ s21baf : (DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ s21baf(x,y,ifail)
+ ++ returns a value of an elementary integral, which occurs as
+ ++ a degenerate case of an elliptic integral of the first kind, via
+ ++ the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs21baf}.
+ s21bbf : (DoubleFloat,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ s21bbf(x,y,z,ifail)
+ ++ returns a value of the symmetrised elliptic integral of
+ ++ the first kind, via the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs21bbf}.
+ s21bcf : (DoubleFloat,DoubleFloat,DoubleFloat,Integer) -> Result
+ ++ s21bcf(x,y,z,ifail)
+ ++ returns a value of the symmetrised elliptic integral of
+ ++ the second kind, via the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs21bcf}.
+ s21bdf : (DoubleFloat,DoubleFloat,DoubleFloat,DoubleFloat,_
+ Integer) -> Result
+ ++ s21bdf(x,y,z,r,ifail)
+ ++ returns a value of the symmetrised elliptic integral of
+ ++ the third kind, via the routine name.
+ ++ See \downlink{Manual Page}{manpageXXs21bdf}.
+ Implementation ==> add
+
+ import Lisp
+ import DoubleFloat
+ import Any
+ import Record
+ import Integer
+ import Matrix DoubleFloat
+ import Boolean
+ import NAGLinkSupportPackage
+ import AnyFunctions1(Complex DoubleFloat)
+ import AnyFunctions1(Integer)
+ import AnyFunctions1(DoubleFloat)
+ import AnyFunctions1(String)
+
+
+ s01eaf(zArg:Complex DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s01eaf",_
+ ["z"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["integer"::S,"ifail"::S]$Lisp_
+ ,["double complex"::S,"s01eafResult"::S,"z"::S]$Lisp_
+ ]$Lisp,_
+ ["s01eafResult"::S,"ifail"::S]$Lisp,_
+ [([zArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s13aaf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s13aaf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s13aafResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s13aafResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s13acf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s13acf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s13acfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s13acfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s13adf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s13adf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s13adfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s13adfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s14aaf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s14aaf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s14aafResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s14aafResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s14abf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s14abf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s14abfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s14abfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s14baf(aArg:DoubleFloat,xArg:DoubleFloat,tolArg:DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s14baf",_
+ ["a"::S,"x"::S,"tol"::S,"p"::S,"q"::S_
+ ,"ifail"::S]$Lisp,_
+ ["p"::S,"q"::S]$Lisp,_
+ [["double"::S,"a"::S,"x"::S,"tol"::S,"p"::S_
+ ,"q"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["p"::S,"q"::S,"ifail"::S]$Lisp,_
+ [([aArg::Any,xArg::Any,tolArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s15adf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s15adf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s15adfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s15adfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s15aef(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s15aef",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s15aefResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s15aefResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17acf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17acf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17acfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17acfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17adf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17adf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17adfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17adfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17aef(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17aef",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17aefResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17aefResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17aff(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17aff",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17affResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17affResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17agf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17agf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17agfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17agfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17ahf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17ahf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17ahfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17ahfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17ajf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17ajf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17ajfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17ajfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17akf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17akf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s17akfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s17akfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+
+ s17dcf(fnuArg:DoubleFloat,zArg:Complex DoubleFloat,nArg:Integer,_
+ scaleArg:String,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17dcf",_
+ ["fnu"::S,"z"::S,"n"::S,"scale"::S,"nz"::S_
+ ,"ifail"::S,"cy"::S,"cwrk"::S]$Lisp,_
+ ["cy"::S,"nz"::S,"cwrk"::S]$Lisp,_
+ [["double"::S,"fnu"::S]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,["cy"::S,"n"::S]$Lisp,["cwrk"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["cy"::S,"nz"::S,"ifail"::S]$Lisp,_
+ [([fnuArg::Any,zArg::Any,nArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17def(fnuArg:DoubleFloat,zArg:Complex DoubleFloat,nArg:Integer,_
+ scaleArg:String,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17def",_
+ ["fnu"::S,"z"::S,"n"::S,"scale"::S,"nz"::S_
+ ,"ifail"::S,"cy"::S]$Lisp,_
+ ["cy"::S,"nz"::S]$Lisp,_
+ [["double"::S,"fnu"::S]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,["cy"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["cy"::S,"nz"::S,"ifail"::S]$Lisp,_
+ [([fnuArg::Any,zArg::Any,nArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17dgf(derivArg:String,zArg:Complex DoubleFloat,scaleArg:String,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17dgf",_
+ ["deriv"::S,"z"::S,"scale"::S,"ai"::S,"nz"::S_
+ ,"ifail"::S]$Lisp,_
+ ["ai"::S,"nz"::S]$Lisp,_
+ [["integer"::S,"nz"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"deriv"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,"ai"::S]$Lisp_
+ ]$Lisp,_
+ ["ai"::S,"nz"::S,"ifail"::S]$Lisp,_
+ [([derivArg::Any,zArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17dhf(derivArg:String,zArg:Complex DoubleFloat,scaleArg:String,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17dhf",_
+ ["deriv"::S,"z"::S,"scale"::S,"bi"::S,"ifail"::S_
+ ]$Lisp,_
+ ["bi"::S]$Lisp,_
+ [["integer"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"deriv"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,"bi"::S]$Lisp_
+ ]$Lisp,_
+ ["bi"::S,"ifail"::S]$Lisp,_
+ [([derivArg::Any,zArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s17dlf(mArg:Integer,fnuArg:DoubleFloat,zArg:Complex DoubleFloat,_
+ nArg:Integer,scaleArg:String,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s17dlf",_
+ ["m"::S,"fnu"::S,"z"::S,"n"::S,"scale"::S_
+ ,"nz"::S,"ifail"::S,"cy"::S]$Lisp,_
+ ["cy"::S,"nz"::S]$Lisp,_
+ [["double"::S,"fnu"::S]$Lisp_
+ ,["integer"::S,"m"::S,"n"::S,"nz"::S,"ifail"::S_
+ ]$Lisp_
+ ,["character"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,["cy"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["cy"::S,"nz"::S,"ifail"::S]$Lisp,_
+ [([mArg::Any,fnuArg::Any,zArg::Any,nArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s18acf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s18acf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s18acfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s18acfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s18adf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s18adf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s18adfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s18adfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s18aef(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s18aef",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s18aefResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s18aefResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s18aff(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s18aff",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s18affResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s18affResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s18dcf(fnuArg:DoubleFloat,zArg:Complex DoubleFloat,nArg:Integer,_
+ scaleArg:String,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s18dcf",_
+ ["fnu"::S,"z"::S,"n"::S,"scale"::S,"nz"::S_
+ ,"ifail"::S,"cy"::S]$Lisp,_
+ ["cy"::S,"nz"::S]$Lisp,_
+ [["double"::S,"fnu"::S]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,["cy"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["cy"::S,"nz"::S,"ifail"::S]$Lisp,_
+ [([fnuArg::Any,zArg::Any,nArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s18def(fnuArg:DoubleFloat,zArg:Complex DoubleFloat,nArg:Integer,_
+ scaleArg:String,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s18def",_
+ ["fnu"::S,"z"::S,"n"::S,"scale"::S,"nz"::S_
+ ,"ifail"::S,"cy"::S]$Lisp,_
+ ["cy"::S,"nz"::S]$Lisp,_
+ [["double"::S,"fnu"::S]$Lisp_
+ ,["integer"::S,"n"::S,"nz"::S,"ifail"::S]$Lisp_
+ ,["character"::S,"scale"::S]$Lisp_
+ ,["double complex"::S,"z"::S,["cy"::S,"n"::S]$Lisp]$Lisp_
+ ]$Lisp,_
+ ["cy"::S,"nz"::S,"ifail"::S]$Lisp,_
+ [([fnuArg::Any,zArg::Any,nArg::Any,scaleArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s19aaf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s19aaf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s19aafResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s19aafResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s19abf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s19abf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s19abfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s19abfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s19acf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s19acf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s19acfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s19acfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s19adf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s19adf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s19adfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s19adfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s20acf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s20acf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s20acfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s20acfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s20adf(xArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s20adf",_
+ ["x"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s20adfResult"::S,"x"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s20adfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s21baf(xArg:DoubleFloat,yArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s21baf",_
+ ["x"::S,"y"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s21bafResult"::S,"x"::S,"y"::S_
+ ]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s21bafResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,yArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s21bbf(xArg:DoubleFloat,yArg:DoubleFloat,zArg:DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s21bbf",_
+ ["x"::S,"y"::S,"z"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s21bbfResult"::S,"x"::S,"y"::S_
+ ,"z"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s21bbfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,yArg::Any,zArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s21bcf(xArg:DoubleFloat,yArg:DoubleFloat,zArg:DoubleFloat,_
+ ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s21bcf",_
+ ["x"::S,"y"::S,"z"::S,"ifail"::S]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s21bcfResult"::S,"x"::S,"y"::S_
+ ,"z"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s21bcfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,yArg::Any,zArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+ s21bdf(xArg:DoubleFloat,yArg:DoubleFloat,zArg:DoubleFloat,_
+ rArg:DoubleFloat,ifailArg:Integer): Result ==
+ [(invokeNagman(NIL$Lisp,_
+ "s21bdf",_
+ ["x"::S,"y"::S,"z"::S,"r"::S,"ifail"::S_
+ ]$Lisp,_
+ []$Lisp,_
+ [["double"::S,"s21bdfResult"::S,"x"::S,"y"::S_
+ ,"z"::S,"r"::S]$Lisp_
+ ,["integer"::S,"ifail"::S]$Lisp_
+ ]$Lisp,_
+ ["s21bdfResult"::S,"ifail"::S]$Lisp,_
+ [([xArg::Any,yArg::Any,zArg::Any,rArg::Any,ifailArg::Any ])_
+ @List Any]$Lisp)$Lisp)_
+ pretend List (Record(key:Symbol,entry:Any))]$Result
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NAGS NagSpecialFunctionsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/seg.spad.pamphlet b/src/algebra/seg.spad.pamphlet
new file mode 100644
index 00000000..63036d6c
--- /dev/null
+++ b/src/algebra/seg.spad.pamphlet
@@ -0,0 +1,531 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra seg.spad}
+\author{Stephen M. Watt, Robert Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category SEGCAT SegmentCategory}
+<<category SEGCAT SegmentCategory>>=
+)abbrev category SEGCAT SegmentCategory
+++ Author: Stephen M. Watt
+++ Date Created: December 1986
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: range, segment
+++ Examples:
+++ References:
+++ Description:
+++ This category provides operations on ranges, or {\em segments}
+++ as they are called.
+
+SegmentCategory(S:Type): Category == Type with
+ SEGMENT: (S, S) -> %
+ ++ \spad{l..h} creates a segment with l and h as the endpoints.
+ BY: (%, Integer) -> %
+ ++ \spad{s by n} creates a new segment in which only every \spad{n}-th
+ ++ element is used.
+ lo: % -> S
+ ++ lo(s) returns the first endpoint of s.
+ ++ Note: \spad{lo(l..h) = l}.
+ hi: % -> S
+ ++ hi(s) returns the second endpoint of s.
+ ++ Note: \spad{hi(l..h) = h}.
+ low: % -> S
+ ++ low(s) returns the first endpoint of s.
+ ++ Note: \spad{low(l..h) = l}.
+ high: % -> S
+ ++ high(s) returns the second endpoint of s.
+ ++ Note: \spad{high(l..h) = h}.
+ incr: % -> Integer
+ ++ incr(s) returns \spad{n}, where s is a segment in which every
+ ++ \spad{n}-th element is used.
+ ++ Note: \spad{incr(l..h by n) = n}.
+ segment: (S, S) -> %
+ ++ segment(i,j) is an alternate way to create the segment \spad{i..j}.
+ convert: S -> %
+ ++ convert(i) creates the segment \spad{i..i}.
+
+@
+\section{category SEGXCAT SegmentExpansionCategory}
+<<category SEGXCAT SegmentExpansionCategory>>=
+)abbrev category SEGXCAT SegmentExpansionCategory
+++ Author: Stephen M. Watt
+++ Date Created: June 5, 1991
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains: Segment, UniversalSegment
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This category provides an interface for expanding segments to
+++ a stream of elements.
+SegmentExpansionCategory(S: OrderedRing, L: StreamAggregate(S)): Category ==
+ SegmentCategory(S) with
+ expand: List % -> L
+ ++ expand(l) creates a new value of type L in which each segment
+ ++ \spad{l..h by k} is replaced with \spad{l, l+k, ... lN},
+ ++ where \spad{lN <= h < lN+k}.
+ ++ For example, \spad{expand [1..4, 7..9] = [1,2,3,4,7,8,9]}.
+ expand: % -> L
+ ++ expand(l..h by k) creates value of type L with elements
+ ++ \spad{l, l+k, ... lN} where \spad{lN <= h < lN+k}.
+ ++ For example, \spad{expand(1..5 by 2) = [1,3,5]}.
+ map: (S -> S, %) -> L
+ ++ map(f,l..h by k) produces a value of type L by applying f
+ ++ to each of the succesive elements of the segment, that is,
+ ++ \spad{[f(l), f(l+k), ..., f(lN)]}, where \spad{lN <= h < lN+k}.
+
+@
+\section{domain SEG Segment}
+<<domain SEG Segment>>=
+)abbrev domain SEG Segment
+++ Author: Stephen M. Watt
+++ Date Created: December 1986
+++ Date Last Updated: June 3, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: range, segment
+++ Examples:
+++ References:
+++ Description:
+++ This type is used to specify a range of values from type \spad{S}.
+
+Segment(S:Type): SegmentCategory(S) with
+ if S has SetCategory then SetCategory
+ if S has OrderedRing then SegmentExpansionCategory(S, List S)
+ == add
+
+ Rep := Record(low: S, high: S, incr: Integer)
+
+ a..b == [a,b,1]
+ lo s == s.low
+ low s == s.low
+ hi s == s.high
+ high s == s.high
+ incr s == s.incr
+ segment(a,b) == [a,b,1]
+ BY(s, r) == [lo s, hi s, r]
+
+ if S has SetCategory then
+ (s1:%) = (s2:%) ==
+ s1.low = s2.low and s1.high=s2.high and s1.incr = s2.incr
+
+ coerce(s:%):OutputForm ==
+ seg := SEGMENT(s.low::OutputForm, s.high::OutputForm)
+ s.incr = 1 => seg
+ infix(" by "::OutputForm, seg, s.incr::OutputForm)
+
+ convert a == [a,a,1]
+
+ if S has OrderedRing then
+ expand(ls: List %):List S ==
+ lr := nil()$List(S)
+ for s in ls repeat
+ l := lo s
+ h := hi s
+ inc := (incr s)::S
+ zero? inc => error "Cannot expand a segment with an increment of zero"
+ if inc > 0 then
+ while l <= h repeat
+ lr := concat(l, lr)
+ l := l + inc
+ else
+ while l >= h repeat
+ lr := concat(l, lr)
+ l := l + inc
+ reverse_! lr
+
+ expand(s : %) == expand([s]$List(%))$%
+ map(f : S->S, s : %): List S ==
+ lr := nil()$List(S)
+ l := lo s
+ h := hi s
+ inc := (incr s)::S
+ if inc > 0 then
+ while l <= h repeat
+ lr := concat(f l, lr)
+ l := l + inc
+ else
+ while l >= h repeat
+ lr := concat(f l, lr)
+ l := l + inc
+ reverse_! lr
+
+@
+\section{package SEG2 SegmentFunctions2}
+<<package SEG2 SegmentFunctions2>>=
+)abbrev package SEG2 SegmentFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: Segment, UniversalSegment
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This package provides operations for mapping functions onto segments.
+
+SegmentFunctions2(R:Type, S:Type): public == private where
+ public ==> with
+ map: (R -> S, Segment R) -> Segment S
+ ++ map(f,l..h) returns a new segment \spad{f(l)..f(h)}.
+
+ if R has OrderedRing then
+ map: (R -> S, Segment R) -> List S
+ ++ map(f,s) expands the segment s, applying \spad{f} to each
+ ++ value. For example, if \spad{s = l..h by k}, then the list
+ ++ \spad{[f(l), f(l+k),..., f(lN)]} is computed, where
+ ++ \spad{lN <= h < lN+k}.
+
+
+ private ==> add
+ map(f : R->S, r : Segment R): Segment S ==
+ SEGMENT(f lo r,f hi r)$Segment(S)
+
+ if R has OrderedRing then
+ map(f : R->S, r : Segment R): List S ==
+ lr := nil()$List(S)
+ l := lo r
+ h := hi r
+ inc := (incr r)::R
+ if inc > 0 then
+ while l <= h repeat
+ lr := concat(f(l), lr)
+ l := l + inc
+ else
+ while l >= h repeat
+ lr := concat(f(l), lr)
+ l := l + inc
+ reverse_! lr
+
+@
+\section{domain SEGBIND SegmentBinding}
+<<domain SEGBIND SegmentBinding>>=
+)abbrev domain SEGBIND SegmentBinding
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: Equation, Segment, Symbol
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This domain is used to provide the function argument syntax \spad{v=a..b}.
+++ This is used, for example, by the top-level \spadfun{draw} functions.
+SegmentBinding(S:Type): Type with
+ equation: (Symbol, Segment S) -> %
+ ++ equation(v,a..b) creates a segment binding value with variable
+ ++ \spad{v} and segment \spad{a..b}. Note that the interpreter parses
+ ++ \spad{v=a..b} to this form.
+ variable: % -> Symbol
+ ++ variable(segb) returns the variable from the left hand side of
+ ++ the \spadtype{SegmentBinding}. For example, if \spad{segb} is
+ ++ \spad{v=a..b}, then \spad{variable(segb)} returns \spad{v}.
+ segment : % -> Segment S
+ ++ segment(segb) returns the segment from the right hand side of
+ ++ the \spadtype{SegmentBinding}. For example, if \spad{segb} is
+ ++ \spad{v=a..b}, then \spad{segment(segb)} returns \spad{a..b}.
+
+ if S has SetCategory then SetCategory
+ == add
+ Rep := Record(var:Symbol, seg:Segment S)
+ equation(x,s) == [x, s]
+ variable b == b.var
+ segment b == b.seg
+
+ if S has SetCategory then
+
+ b1 = b2 == variable b1 = variable b2 and segment b1 = segment b2
+
+ coerce(b:%):OutputForm ==
+ variable(b)::OutputForm = segment(b)::OutputForm
+
+@
+\section{package SEGBIND2 SegmentBindingFunctions2}
+<<package SEGBIND2 SegmentBindingFunctions2>>=
+)abbrev package SEGBIND2 SegmentBindingFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: SegmentBinding, Segment, Equation
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This package provides operations for mapping functions onto
+++ \spadtype{SegmentBinding}s.
+SegmentBindingFunctions2(R:Type, S:Type): with
+ map: (R -> S, SegmentBinding R) -> SegmentBinding S
+ ++ map(f,v=a..b) returns the value given by \spad{v=f(a)..f(b)}.
+ == add
+ map(f, b) ==
+ equation(variable b, map(f, segment b)$SegmentFunctions2(R, S))
+
+@
+\section{domain UNISEG UniversalSegment}
+<<domain UNISEG UniversalSegment>>=
+)abbrev domain UNISEG UniversalSegment
+++ Author: Robert S. Sutor
+++ Date Created: 1987
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: Segment
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides segments which may be half open.
+++ That is, ranges of the form \spad{a..} or \spad{a..b}.
+
+UniversalSegment(S: Type): SegmentCategory(S) with
+ SEGMENT: S -> %
+ ++ \spad{l..} produces a half open segment,
+ ++ that is, one with no upper bound.
+ segment: S -> %
+ ++ segment(l) is an alternate way to construct the segment \spad{l..}.
+ coerce : Segment S -> %
+ ++ coerce(x) allows \spadtype{Segment} values to be used as %.
+ hasHi: % -> Boolean
+ ++ hasHi(s) tests whether the segment s has an upper bound.
+
+ if S has SetCategory then SetCategory
+
+ if S has OrderedRing then
+ SegmentExpansionCategory(S, Stream S)
+-- expand : (List %, S) -> Stream S
+-- expand : (%, S) -> Stream S
+
+ == add
+ Rec ==> Record(low: S, high: S, incr: Integer)
+ Rec2 ==> Record(low: S, incr: Integer)
+ SEG ==> Segment S
+
+ Rep := Union(Rec2, Rec)
+ a,b : S
+ s : %
+ i: Integer
+ ls : List %
+
+ segment a == [a, 1]$Rec2 :: Rep
+ segment(a,b) == [a,b,1]$Rec :: Rep
+ BY(s,i) ==
+ s case Rec => [lo s, hi s, i]$Rec ::Rep
+ [lo s, i]$Rec2 :: Rep
+
+ lo s ==
+ s case Rec2 => (s :: Rec2).low
+ (s :: Rec).low
+
+ low s ==
+ s case Rec2 => (s :: Rec2).low
+ (s :: Rec).low
+
+ hasHi s == s case Rec
+
+ hi s ==
+ not hasHi(s) => error "hi: segment has no upper bound"
+ (s :: Rec).high
+
+ high s ==
+ not hasHi(s) => error "high: segment has no upper bound"
+ (s :: Rec).high
+
+ incr s ==
+ s case Rec2 => (s :: Rec2).incr
+ (s :: Rec).incr
+
+ SEGMENT(a) == segment a
+ SEGMENT(a,b) == segment(a,b)
+
+ coerce(sg : SEG): % == segment(lo sg, hi sg)
+
+ convert a == [a,a,1]
+
+ if S has SetCategory then
+
+ (s1:%) = (s2:%) ==
+ s1 case Rec2 =>
+ s2 case Rec2 =>
+ s1.low = s2.low and s1.incr = s2.incr
+ false
+ s1 case Rec =>
+ s2 case Rec =>
+ s2.low = s2.low and s1.high=s2.high and s1.incr=s2.incr
+ false
+ false
+
+ coerce(s: %): OutputForm ==
+ seg :=
+ e := (lo s)::OutputForm
+ hasHi s => SEGMENT(e, (hi s)::OutputForm)
+ SEGMENT e
+ inc := incr s
+ inc = 1 => seg
+ infix(" by "::OutputForm, seg, inc::OutputForm)
+
+ if S has OrderedRing then
+ expand(s:%) == expand([s])
+ map(f:S->S, s:%) == map(f, expand s)
+
+ plusInc(t: S, a: S): S == t + a
+
+ expand(ls: List %):Stream S ==
+ st:Stream S := empty()
+ null ls => st
+
+ lb:List(Segment S) := nil()
+ while not null ls and hasHi first ls repeat
+ s := first ls
+ ls := rest ls
+ ns := BY(SEGMENT(lo s, hi s), incr s)$Segment(S)
+ lb := concat_!(lb,ns)
+ if not null ls then
+ s := first ls
+ st: Stream S := generate(#1 + incr(s)::S, lo s)
+ else
+ st: Stream S := empty()
+ concat(construct expand(lb), st)
+
+@
+\section{package UNISEG2 UniversalSegmentFunctions2}
+<<package UNISEG2 UniversalSegmentFunctions2>>=
+)abbrev package UNISEG2 UniversalSegmentFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: Segment, UniversalSegment
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This package provides operations for mapping functions onto segments.
+
+UniversalSegmentFunctions2(R:Type, S:Type): with
+ map: (R -> S, UniversalSegment R) -> UniversalSegment S
+ ++ map(f,seg) returns the new segment obtained by applying
+ ++ f to the endpoints of seg.
+
+ if R has OrderedRing then
+ map: (R -> S, UniversalSegment R) -> Stream S
+ ++ map(f,s) expands the segment s, applying \spad{f} to each value.
+
+
+ == add
+ map(f:R -> S, u:UniversalSegment R):UniversalSegment S ==
+ s := f lo u
+ hasHi u => segment(s, f hi u)
+ segment s
+
+ if R has OrderedRing then
+ map(f:R -> S, u:UniversalSegment R): Stream S ==
+ map(f, expand u)$StreamFunctions2(R, S)
+
+@
+\section{package INCRMAPS IncrementingMaps}
+<<package INCRMAPS IncrementingMaps>>=
+)abbrev package INCRMAPS IncrementingMaps
+++ Author:
+++ Date Created:
+++ Date Last Updated: June 4, 1991
+++ Basic Operations:
+++ Related Domains: UniversalSegment
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This package provides operations to create incrementing functions.
+
+IncrementingMaps(R:Join(Monoid, AbelianSemiGroup)): with
+ increment: () -> (R -> R)
+ ++ increment() produces a function which adds \spad{1} to whatever
+ ++ argument it is given. For example, if {f := increment()} then
+ ++ \spad{f x} is \spad{x+1}.
+ incrementBy: R -> (R -> R)
+ ++ incrementBy(n) produces a function which adds \spad{n} to whatever
+ ++ argument it is given. For example, if {f := increment(n)} then
+ ++ \spad{f x} is \spad{x+n}.
+ == add
+ increment() == 1 + #1
+ incrementBy n == n + #1
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category SEGCAT SegmentCategory>>
+<<category SEGXCAT SegmentExpansionCategory>>
+<<domain SEG Segment>>
+<<package SEG2 SegmentFunctions2>>
+<<domain SEGBIND SegmentBinding>>
+<<package SEGBIND2 SegmentBindingFunctions2>>
+<<domain UNISEG UniversalSegment>>
+<<package UNISEG2 UniversalSegmentFunctions2>>
+<<package INCRMAPS IncrementingMaps>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/setorder.spad.pamphlet b/src/algebra/setorder.spad.pamphlet
new file mode 100644
index 00000000..198d8d85
--- /dev/null
+++ b/src/algebra/setorder.spad.pamphlet
@@ -0,0 +1,186 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra setorder.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package UDPO UserDefinedPartialOrdering}
+<<package UDPO UserDefinedPartialOrdering>>=
+)abbrev package UDPO UserDefinedPartialOrdering
+++ Author: Manuel Bronstein
+++ Date Created: March 1990
+++ Date Last Updated: 9 April 1991
+++ Description:
+++ Provides functions to force a partial ordering on any set.
+UserDefinedPartialOrdering(S:SetCategory): with
+ setOrder : List S -> Void
+ ++ setOrder([a1,...,an]) defines a partial ordering on S given by:
+ ++ (1) \spad{a1 < a2 < ... < an}.
+ ++ (2) \spad{b < ai for i = 1..n} and b not among the ai's.
+ ++ (3) undefined on \spad{(b, c)} if neither is among the ai's.
+ setOrder : (List S, List S) -> Void
+ ++ setOrder([b1,...,bm], [a1,...,an]) defines a partial
+ ++ ordering on S given by:
+ ++ (1) \spad{b1 < b2 < ... < bm < a1 < a2 < ... < an}.
+ ++ (2) \spad{bj < c < ai} for c not among the ai's and bj's.
+ ++ (3) undefined on \spad{(c,d)} if neither is among the ai's,bj's.
+ getOrder : () -> Record(low: List S, high: List S)
+ ++ getOrder() returns \spad{[[b1,...,bm], [a1,...,an]]} such that the
+ ++ partial ordering on S was given by
+ ++ \spad{setOrder([b1,...,bm],[a1,...,an])}.
+ less? : (S, S) -> Union(Boolean, "failed")
+ ++ less?(a, b) compares \spad{a} and b in the partial ordering induced by
+ ++ setOrder.
+ less? : (S, S, (S, S) -> Boolean) -> Boolean
+ ++ less?(a, b, fn) compares \spad{a} and b in the partial ordering induced
+ ++ by setOrder, and returns \spad{fn(a, b)} if \spad{a}
+ ++ and b are not comparable
+ ++ in that ordering.
+ largest : (List S, (S, S) -> Boolean) -> S
+ ++ largest(l, fn) returns the largest element of l where the partial
+ ++ ordering induced by setOrder is completed into a total one by fn.
+ userOrdered?: () -> Boolean
+ ++ userOrdered?() tests if the partial ordering induced by
+ ++ \spadfunFrom{setOrder}{UserDefinedPartialOrdering} is not empty.
+ if S has OrderedSet then
+ largest: List S -> S
+ ++ largest l returns the largest element of l where the partial
+ ++ ordering induced by setOrder is completed into a total one by
+ ++ the ordering on S.
+ more? : (S, S) -> Boolean
+ ++ more?(a, b) compares \spad{a} and b in the partial ordering induced
+ ++ by setOrder, and uses the ordering on S if \spad{a} and b are not
+ ++ comparable in the partial ordering.
+
+ == add
+ llow :Reference List S := ref nil()
+ lhigh:Reference List S := ref nil()
+
+ userOrdered?() == not(empty? deref llow) or not(empty? deref lhigh)
+ getOrder() == [deref llow, deref lhigh]
+ setOrder l == setOrder(nil(), l)
+
+ setOrder(l, h) ==
+ setref(llow, removeDuplicates l)
+ setref(lhigh, removeDuplicates h)
+ void
+
+ less?(a, b, f) ==
+ (u := less?(a, b)) case "failed" => f(a, b)
+ u::Boolean
+
+ largest(x, f) ==
+ empty? x => error "largest: empty list"
+ empty? rest x => first x
+ a := largest(rest x, f)
+ less?(first x, a, f) => a
+ first x
+
+ less?(a, b) ==
+ for x in deref llow repeat
+ x = a => return(a ^= b)
+ x = b => return false
+ aa := bb := false$Boolean
+ for x in deref lhigh repeat
+ if x = a then
+ bb => return false
+ aa := true
+ if x = b then
+ aa => return(a ^= b)
+ bb := true
+ aa => false
+ bb => true
+ "failed"
+
+ if S has OrderedSet then
+ more?(a, b) == not less?(a, b, #1 <$S #2)
+ largest x == largest(x, #1 <$S #2)
+
+@
+\section{package UDVO UserDefinedVariableOrdering}
+<<package UDVO UserDefinedVariableOrdering>>=
+)abbrev package UDVO UserDefinedVariableOrdering
+++ Author: Manuel Bronstein
+++ Date Created: March 1990
+++ Date Last Updated: 9 April 1991
+++ Description:
+++ This packages provides functions to allow the user to select the ordering
+++ on the variables and operators for displaying polynomials,
+++ fractions and expressions. The ordering affects the display
+++ only and not the computations.
+UserDefinedVariableOrdering(): with
+ setVariableOrder : List Symbol -> Void
+ ++ setVariableOrder([a1,...,an]) defines an ordering on the
+ ++ variables given by \spad{a1 > a2 > ... > an > other variables}.
+ setVariableOrder : (List Symbol, List Symbol) -> Void
+ ++ setVariableOrder([b1,...,bm], [a1,...,an]) defines an ordering
+ ++ on the variables given by
+ ++ \spad{b1 > b2 > ... > bm >} other variables \spad{> a1 > a2 > ... > an}.
+ getVariableOrder : () -> Record(high:List Symbol, low:List Symbol)
+ ++ getVariableOrder() returns \spad{[[b1,...,bm], [a1,...,an]]} such that
+ ++ the ordering on the variables was given by
+ ++ \spad{setVariableOrder([b1,...,bm], [a1,...,an])}.
+ resetVariableOrder: () -> Void
+ ++ resetVariableOrder() cancels any previous use of
+ ++ setVariableOrder and returns to the default system ordering.
+ == add
+ import UserDefinedPartialOrdering(Symbol)
+
+ setVariableOrder l == setOrder reverse l
+ setVariableOrder(l1, l2) == setOrder(reverse l2, reverse l1)
+ resetVariableOrder() == setVariableOrder(nil(), nil())
+
+ getVariableOrder() ==
+ r := getOrder()
+ [reverse(r.high), reverse(r.low)]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package UDPO UserDefinedPartialOrdering>>
+<<package UDVO UserDefinedVariableOrdering>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sets.spad.pamphlet b/src/algebra/sets.spad.pamphlet
new file mode 100644
index 00000000..5f373d4d
--- /dev/null
+++ b/src/algebra/sets.spad.pamphlet
@@ -0,0 +1,233 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sets.spad}
+\author{Michael Monagan, Richard Jenks}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SET Set}
+<<domain SET Set>>=
+)abbrev domain SET Set
+++ Author: Michael Monagan; revised by Richard Jenks
+++ Date Created: August 87 through August 88
+++ Date Last Updated: May 1991
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A set over a domain D models the usual mathematical notion of a finite set
+++ of elements from D.
+++ Sets are unordered collections of distinct elements
+++ (that is, order and duplication does not matter).
+++ The notation \spad{set [a,b,c]} can be used to create
+++ a set and the usual operations such as union and intersection are available
+++ to form new sets.
+++ In our implementation, \Language{} maintains the entries in
+++ sorted order. Specifically, the parts function returns the entries
+++ as a list in ascending order and
+++ the extract operation returns the maximum entry.
+++ Given two sets s and t where \spad{#s = m} and \spad{#t = n},
+++ the complexity of
+++ \spad{s = t} is \spad{O(min(n,m))}
+++ \spad{s < t} is \spad{O(max(n,m))}
+++ \spad{union(s,t)}, \spad{intersect(s,t)}, \spad{minus(s,t)}, \spad{symmetricDifference(s,t)} is \spad{O(max(n,m))}
+++ \spad{member(x,t)} is \spad{O(n log n)}
+++ \spad{insert(x,t)} and \spad{remove(x,t)} is \spad{O(n)}
+Set(S:SetCategory): FiniteSetAggregate S == add
+ Rep := FlexibleArray(S)
+ # s == _#$Rep s
+ brace() == empty()
+ set() == empty()
+ empty() == empty()$Rep
+ copy s == copy(s)$Rep
+ parts s == parts(s)$Rep
+ inspect s == (empty? s => error "Empty set"; s(maxIndex s))
+
+ extract_! s ==
+ x := inspect s
+ delete_!(s, maxIndex s)
+ x
+
+ find(f, s) == find(f, s)$Rep
+
+ map(f, s) == map_!(f,copy s)
+
+ map_!(f,s) ==
+ map_!(f,s)$Rep
+ removeDuplicates_! s
+
+ reduce(f, s) == reduce(f, s)$Rep
+
+ reduce(f, s, x) == reduce(f, s, x)$Rep
+
+ reduce(f, s, x, y) == reduce(f, s, x, y)$Rep
+
+ if S has ConvertibleTo InputForm then
+ convert(x:%):InputForm ==
+ convert [convert("set"::Symbol)@InputForm,
+ convert(parts x)@InputForm]
+
+ if S has OrderedSet then
+ s = t == s =$Rep t
+ max s == inspect s
+ min s == (empty? s => error "Empty set"; s(minIndex s))
+
+ construct l ==
+ zero?(n := #l) => empty()
+ a := new(n, first l)
+ for i in minIndex(a).. for x in l repeat a.i := x
+ removeDuplicates_! sort_! a
+
+ insert_!(x, s) ==
+ n := inc maxIndex s
+ k := minIndex s
+ while k < n and x > s.k repeat k := inc k
+ k < n and s.k = x => s
+ insert_!(x, s, k)
+
+ member?(x, s) == -- binary search
+ empty? s => false
+ t := maxIndex s
+ b := minIndex s
+ while b < t repeat
+ m := (b+t) quo 2
+ if x > s.m then b := m+1 else t := m
+ x = s.t
+
+ remove_!(x:S, s:%) ==
+ n := inc maxIndex s
+ k := minIndex s
+ while k < n and x > s.k repeat k := inc k
+ k < n and x = s.k => delete_!(s, k)
+ s
+
+ -- the set operations are implemented as variations of merging
+ intersect(s, t) ==
+ m := maxIndex s
+ n := maxIndex t
+ i := minIndex s
+ j := minIndex t
+ r := empty()
+ while i <= m and j <= n repeat
+ s.i = t.j => (concat_!(r, s.i); i := i+1; j := j+1)
+ if s.i < t.j then i := i+1 else j := j+1
+ r
+
+ difference(s:%, t:%) ==
+ m := maxIndex s
+ n := maxIndex t
+ i := minIndex s
+ j := minIndex t
+ r := empty()
+ while i <= m and j <= n repeat
+ s.i = t.j => (i := i+1; j := j+1)
+ s.i < t.j => (concat_!(r, s.i); i := i+1)
+ j := j+1
+ while i <= m repeat (concat_!(r, s.i); i := i+1)
+ r
+
+ symmetricDifference(s, t) ==
+ m := maxIndex s
+ n := maxIndex t
+ i := minIndex s
+ j := minIndex t
+ r := empty()
+ while i <= m and j <= n repeat
+ s.i < t.j => (concat_!(r, s.i); i := i+1)
+ s.i > t.j => (concat_!(r, t.j); j := j+1)
+ i := i+1; j := j+1
+ while i <= m repeat (concat_!(r, s.i); i := i+1)
+ while j <= n repeat (concat_!(r, t.j); j := j+1)
+ r
+
+ subset?(s, t) ==
+ m := maxIndex s
+ n := maxIndex t
+ m > n => false
+ i := minIndex s
+ j := minIndex t
+ while i <= m and j <= n repeat
+ s.i = t.j => (i := i+1; j := j+1)
+ s.i > t.j => j := j+1
+ return false
+ i > m
+
+ union(s:%, t:%) ==
+ m := maxIndex s
+ n := maxIndex t
+ i := minIndex s
+ j := minIndex t
+ r := empty()
+ while i <= m and j <= n repeat
+ s.i = t.j => (concat_!(r, s.i); i := i+1; j := j+1)
+ s.i < t.j => (concat_!(r, s.i); i := i+1)
+ (concat_!(r, t.j); j := j+1)
+ while i <= m repeat (concat_!(r, s.i); i := i+1)
+ while j <= n repeat (concat_!(r, t.j); j := j+1)
+ r
+
+ else
+ insert_!(x, s) ==
+ for k in minIndex s .. maxIndex s repeat
+ s.k = x => return s
+ insert_!(x, s, inc maxIndex s)
+
+ remove_!(x:S, s:%) ==
+ n := inc maxIndex s
+ k := minIndex s
+ while k < n repeat
+ x = s.k => return delete_!(s, k)
+ k := inc k
+ s
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SET Set>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sex.spad.pamphlet b/src/algebra/sex.spad.pamphlet
new file mode 100644
index 00000000..90fdea78
--- /dev/null
+++ b/src/algebra/sex.spad.pamphlet
@@ -0,0 +1,217 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sex.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category SEXCAT SExpressionCategory}
+<<category SEXCAT SExpressionCategory>>=
+)abbrev category SEXCAT SExpressionCategory
+++ Category for Lisp values
+++ Author: S.M.Watt
+++ Date Created: July 1987
+++ Date Last Modified: 23 May 1991
+++ Description:
+++ This category allows the manipulation of Lisp values while keeping
+++ the grunge fairly localized.
+-- The coerce to expression lets the
+-- values be displayed in the usual parenthesized way (displaying
+-- them as type Expression can cause the formatter to die, since
+-- certain magic cookies are in unexpected places).
+-- SMW July 87
+SExpressionCategory(Str, Sym, Int, Flt, Expr): Category == Decl where
+ Str, Sym, Int, Flt, Expr: SetCategory
+
+ Decl ==> SetCategory with
+ eq: (%,%) -> Boolean
+ ++ eq(s, t) is true if EQ(s,t) is true in Lisp.
+ null?: % -> Boolean
+ ++ null?(s) is true if s is the S-expression ().
+ atom?: % -> Boolean
+ ++ atom?(s) is true if s is a Lisp atom.
+ pair?: % -> Boolean
+ ++ pair?(s) is true if s has is a non-null Lisp list.
+ list?: % -> Boolean
+ ++ list?(s) is true if s is a Lisp list, possibly ().
+ string?: % -> Boolean
+ ++ string?(s) is true if s is an atom and belong to Str.
+ symbol?: % -> Boolean
+ ++ symbol?(s) is true if s is an atom and belong to Sym.
+ integer?: % -> Boolean
+ ++ integer?(s) is true if s is an atom and belong to Int.
+ float?: % -> Boolean
+ ++ float?(s) is true if s is an atom and belong to Flt.
+ destruct: % -> List %
+ ++ destruct((a1,...,an)) returns the list [a1,...,an].
+ string: % -> Str
+ ++ string(s) returns s as an element of Str.
+ ++ Error: if s is not an atom that also belongs to Str.
+ symbol: % -> Sym
+ ++ symbol(s) returns s as an element of Sym.
+ ++ Error: if s is not an atom that also belongs to Sym.
+ integer: % -> Int
+ ++ integer(s) returns s as an element of Int.
+ ++ Error: if s is not an atom that also belongs to Int.
+ float: % -> Flt
+ ++ float(s) returns s as an element of Flt;
+ ++ Error: if s is not an atom that also belongs to Flt.
+ expr: % -> Expr
+ ++ expr(s) returns s as an element of Expr;
+ ++ Error: if s is not an atom that also belongs to Expr.
+ convert: List % -> %
+ ++ convert([a1,...,an]) returns the S-expression \spad{(a1,...,an)}.
+ convert: Str -> %
+ ++ convert(x) returns the Lisp atom x;
+ convert: Sym -> %
+ ++ convert(x) returns the Lisp atom x.
+ convert: Int -> %
+ ++ convert(x) returns the Lisp atom x.
+ convert: Flt -> %
+ ++ convert(x) returns the Lisp atom x.
+ convert: Expr -> %
+ ++ convert(x) returns the Lisp atom x.
+ car: % -> %
+ ++ car((a1,...,an)) returns a1.
+ cdr: % -> %
+ ++ cdr((a1,...,an)) returns \spad{(a2,...,an)}.
+ "#": % -> Integer
+ ++ #((a1,...,an)) returns n.
+ elt: (%, Integer) -> %
+ ++ elt((a1,...,an), i) returns \spad{ai}.
+ elt: (%, List Integer) -> %
+ ++ elt((a1,...,an), [i1,...,im]) returns \spad{(a_i1,...,a_im)}.
+
+@
+\section{domain SEXOF SExpressionOf}
+<<domain SEXOF SExpressionOf>>=
+)abbrev domain SEXOF SExpressionOf
+++ Domain for Lisp values over arbitrary atomic types
+++ Author: S.M.Watt
+++ Date Created: July 1987
+++ Date Last Modified: 23 May 1991
+++ Description:
+++ This domain allows the manipulation of Lisp values over
+++ arbitrary atomic types.
+-- Allows the names of the atomic types to be chosen.
+-- *** Warning *** Although the parameters are declared only to be Sets,
+-- *** Warning *** they must have the appropriate representations.
+SExpressionOf(Str, Sym, Int, Flt, Expr): Decl == Body where
+ Str, Sym, Int, Flt, Expr: SetCategory
+
+ Decl ==> SExpressionCategory(Str, Sym, Int, Flt, Expr)
+
+ Body ==> add
+ Rep := Expr
+
+ dotex:OutputForm := INTERN(".")$Lisp
+
+ coerce(b:%):OutputForm ==
+ null? b => paren empty()
+ atom? b => coerce(b)$Rep
+ r := b
+ while not atom? r repeat r := cdr r
+ l1 := [b1::OutputForm for b1 in (l := destruct b)]
+ not null? r =>
+ paren blankSeparate concat_!(l1, [dotex, r::OutputForm])
+ #l = 2 and (first(l1) = QUOTE)@Boolean => quote first rest l1
+ paren blankSeparate l1
+
+ b1 = b2 == EQUAL(b1,b2)$Lisp
+ eq(b1, b2) == EQ(b1,b2)$Lisp
+
+ null? b == NULL(b)$Lisp
+ atom? b == ATOM(b)$Lisp
+ pair? b == PAIRP(b)$Lisp
+
+ list? b == PAIRP(b)$Lisp or NULL(b)$Lisp
+ string? b == STRINGP(b)$Lisp
+ symbol? b == IDENTP(b)$Lisp
+ integer? b == INTP(b)$Lisp
+ float? b == RNUMP(b)$Lisp
+
+ destruct b == (list? b => b pretend List %; error "Non-list")
+ string b == (STRINGP(b)$Lisp=> b pretend Str;error "Non-string")
+ symbol b == (IDENTP(b)$Lisp => b pretend Sym;error "Non-symbol")
+ float b == (RNUMP(b)$Lisp => b pretend Flt;error "Non-float")
+ integer b == (INTP(b)$Lisp => b pretend Int;error "Non-integer")
+ expr b == b pretend Expr
+
+ convert(l: List %) == l pretend %
+ convert(st: Str) == st pretend %
+ convert(sy: Sym) == sy pretend %
+ convert(n: Int) == n pretend %
+ convert(f: Flt) == f pretend %
+ convert(e: Expr) == e pretend %
+
+ car b == CAR(b)$Lisp
+ cdr b == CDR(b)$Lisp
+ # b == LENGTH(b)$Lisp
+ elt(b:%, i:Integer) == destruct(b).i
+ elt(b:%, li:List Integer) ==
+ for i in li repeat b := destruct(b).i
+ b
+
+@
+\section{domain SEX SExpression}
+<<domain SEX SExpression>>=
+)abbrev domain SEX SExpression
+++ Domain for the standard Lisp values
+++ Author: S.M.Watt
+++ Date Created: July 1987
+++ Date Last Modified: 23 May 1991
+++ Description:
+++ This domain allows the manipulation of the usual Lisp values;
+SExpression()
+ == SExpressionOf(String, Symbol, Integer, DoubleFloat, OutputForm)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category SEXCAT SExpressionCategory>>
+<<domain SEXOF SExpressionOf>>
+<<domain SEX SExpression>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sf.spad.pamphlet b/src/algebra/sf.spad.pamphlet
new file mode 100644
index 00000000..5ceed4b8
--- /dev/null
+++ b/src/algebra/sf.spad.pamphlet
@@ -0,0 +1,1403 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sf.spad}
+\author{Michael Monagan, Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category REAL RealConstant}
+<<category REAL RealConstant>>=
+)abbrev category REAL RealConstant
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of real numeric domains, i.e. convertible to floats.
+RealConstant(): Category ==
+ Join(ConvertibleTo DoubleFloat, ConvertibleTo Float)
+
+@
+\section{category RADCAT RadicalCategory}
+<<category RADCAT RadicalCategory>>=
+)abbrev category RADCAT RadicalCategory
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: nthRoot, sqrt, **
+++ Related Constructors:
+++ Keywords: rational numbers
+++ Description: The \spad{RadicalCategory} is a model for the rational numbers.
+RadicalCategory(): Category == with
+ sqrt : % -> %
+ ++ sqrt(x) returns the square root of x.
+ nthRoot: (%, Integer) -> %
+ ++ nthRoot(x,n) returns the nth root of x.
+ _*_* : (%, Fraction Integer) -> %
+ ++ x ** y is the rational exponentiation of x by the power y.
+ add
+ sqrt x == x ** inv(2::Fraction(Integer))
+ nthRoot(x, n) == x ** inv(n::Fraction(Integer))
+
+@
+\section{category RNS RealNumberSystem}
+<<category RNS RealNumberSystem>>=
+)abbrev category RNS RealNumberSystem
+++ Author: Michael Monagan and Stephen M. Watt
+++ Date Created:
+++ January 1988
+++ Change History:
+++ Basic Operations: abs, ceiling, wholePart, floor, fractionPart, norm, round, truncate
+++ Related Constructors:
+++ Keywords: real numbers
+++ Description:
+++ The real number system category is intended as a model for the real
+++ numbers. The real numbers form an ordered normed field. Note that
+++ we have purposely not included \spadtype{DifferentialRing} or the elementary
+++ functions (see \spadtype{TranscendentalFunctionCategory}) in the definition.
+RealNumberSystem(): Category ==
+ Join(Field, OrderedRing, RealConstant, RetractableTo Integer,
+ RetractableTo Fraction Integer, RadicalCategory,
+ ConvertibleTo Pattern Float, PatternMatchable Float,
+ CharacteristicZero) with
+ norm : % -> %
+ ++ norm x returns the same as absolute value.
+ ceiling : % -> %
+ ++ ceiling x returns the small integer \spad{>= x}.
+ floor: % -> %
+ ++ floor x returns the largest integer \spad{<= x}.
+ wholePart : % -> Integer
+ ++ wholePart x returns the integer part of x.
+ fractionPart : % -> %
+ ++ fractionPart x returns the fractional part of x.
+ truncate: % -> %
+ ++ truncate x returns the integer between x and 0 closest to x.
+ round: % -> %
+ ++ round x computes the integer closest to x.
+ abs : % -> %
+ ++ abs x returns the absolute value of x.
+
+ add
+ characteristic() == 0
+ fractionPart x == x - truncate x
+ truncate x == (negative? x => -floor(-x); floor x)
+ round x == (negative? x => truncate(x-1/2::%); truncate(x+1/2::%))
+ norm x == abs x
+ coerce(x:Fraction Integer):% == numer(x)::% / denom(x)::%
+ convert(x:%):Pattern(Float) == convert(x)@Float :: Pattern(Float)
+
+ floor x ==
+ x1 := (wholePart x) :: %
+ x = x1 => x
+ x < 0 => (x1 - 1)
+ x1
+
+ ceiling x ==
+ x1 := (wholePart x)::%
+ x = x1 => x
+ x >= 0 => (x1 + 1)
+ x1
+
+ patternMatch(x, p, l) ==
+ generic? p => addMatch(p, x, l)
+ constant? p =>
+ (r := retractIfCan(p)@Union(Float, "failed")) case Float =>
+ convert(x)@Float = r::Float => l
+ failed()
+ failed()
+ failed()
+
+@
+\section{RNS.lsp BOOTSTRAP}
+{\bf RNS} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf RNS} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf RNS.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RNS.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |RealNumberSystem;AL| (QUOTE NIL))
+
+(DEFUN |RealNumberSystem| NIL
+ (LET (#:G105478)
+ (COND
+ (|RealNumberSystem;AL|)
+ (T (SETQ |RealNumberSystem;AL| (|RealNumberSystem;|))))))
+
+(DEFUN |RealNumberSystem;| NIL
+ (PROG (#1=#:G105476)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|sublisV|
+ (PAIR
+ (QUOTE (#2=#:G105472 #3=#:G105473 #4=#:G105474 #5=#:G105475))
+ (LIST
+ (QUOTE (|Integer|))
+ (QUOTE (|Fraction| (|Integer|)))
+ (QUOTE (|Pattern| (|Float|)))
+ (QUOTE (|Float|))))
+ (|Join|
+ (|Field|)
+ (|OrderedRing|)
+ (|RealConstant|)
+ (|RetractableTo| (QUOTE #2#))
+ (|RetractableTo| (QUOTE #3#))
+ (|RadicalCategory|)
+ (|ConvertibleTo| (QUOTE #4#))
+ (|PatternMatchable| (QUOTE #5#))
+ (|CharacteristicZero|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|norm| (|$| |$|)) T)
+ ((|ceiling| (|$| |$|)) T)
+ ((|floor| (|$| |$|)) T)
+ ((|wholePart| ((|Integer|) |$|)) T)
+ ((|fractionPart| (|$| |$|)) T)
+ ((|truncate| (|$| |$|)) T)
+ ((|round| (|$| |$|)) T)
+ ((|abs| (|$| |$|)) T)))
+ NIL
+ (QUOTE ((|Integer|)))
+ NIL)))
+ |RealNumberSystem|)
+ (SETELT #1# 0 (QUOTE (|RealNumberSystem|)))))))
+
+(MAKEPROP (QUOTE |RealNumberSystem|) (QUOTE NILADIC) T)
+
+@
+\section{RNS-.lsp BOOTSTRAP}
+{\bf RNS-} depends {\bf RNS}.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf RNS-} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf RNS.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<RNS-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT
+ (QUOTE |RNS-;characteristic;Nni;1|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL 0)))
+
+(DEFUN |RNS-;characteristic;Nni;1| (|$|) 0)
+
+(DEFUN |RNS-;fractionPart;2S;2| (|x| |$|)
+ (SPADCALL |x| (SPADCALL |x| (QREFELT |$| 9)) (QREFELT |$| 10)))
+
+(DEFUN |RNS-;truncate;2S;3| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 13))
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |x| (QREFELT |$| 14))
+ (QREFELT |$| 15))
+ (QREFELT |$| 14)))
+ ((QUOTE T) (SPADCALL |x| (QREFELT |$| 15)))))
+
+(DEFUN |RNS-;round;2S;4| (|x| |$|)
+ (COND
+ ((SPADCALL |x| (QREFELT |$| 13))
+ (SPADCALL
+ (SPADCALL |x|
+ (SPADCALL
+ (|spadConstant| |$| 17)
+ (SPADCALL 2 (QREFELT |$| 19))
+ (QREFELT |$| 20))
+ (QREFELT |$| 10))
+ (QREFELT |$| 9)))
+ ((QUOTE T)
+ (SPADCALL
+ (SPADCALL |x|
+ (SPADCALL
+ (|spadConstant| |$| 17)
+ (SPADCALL 2 (QREFELT |$| 19))
+ (QREFELT |$| 20))
+ (QREFELT |$| 21))
+ (QREFELT |$| 9)))))
+
+(DEFUN |RNS-;norm;2S;5| (|x| |$|)
+ (SPADCALL |x| (QREFELT |$| 23)))
+
+(DEFUN |RNS-;coerce;FS;6| (|x| |$|)
+ (SPADCALL
+ (SPADCALL
+ (SPADCALL |x| (QREFELT |$| 26))
+ (QREFELT |$| 19))
+ (SPADCALL
+ (SPADCALL |x| (QREFELT |$| 27))
+ (QREFELT |$| 19))
+ (QREFELT |$| 20)))
+
+(DEFUN |RNS-;convert;SP;7| (|x| |$|)
+ (SPADCALL (SPADCALL |x| (QREFELT |$| 30)) (QREFELT |$| 32)))
+
+(DEFUN |RNS-;floor;2S;8| (|x| |$|)
+ (PROG (|x1|)
+ (RETURN
+ (SEQ
+ (LETT |x1|
+ (SPADCALL (SPADCALL |x| (QREFELT |$| 34)) (QREFELT |$| 19))
+ |RNS-;floor;2S;8|)
+ (EXIT
+ (COND
+ ((SPADCALL |x| |x1| (QREFELT |$| 35)) |x|)
+ ((SPADCALL |x| (|spadConstant| |$| 36) (QREFELT |$| 37))
+ (SPADCALL |x1| (|spadConstant| |$| 17) (QREFELT |$| 10)))
+ ((QUOTE T) |x1|)))))))
+
+(DEFUN |RNS-;ceiling;2S;9| (|x| |$|)
+ (PROG (|x1|)
+ (RETURN
+ (SEQ
+ (LETT |x1|
+ (SPADCALL (SPADCALL |x| (QREFELT |$| 34)) (QREFELT |$| 19))
+ |RNS-;ceiling;2S;9|)
+ (EXIT
+ (COND
+ ((SPADCALL |x| |x1| (QREFELT |$| 35)) |x|)
+ ((SPADCALL |x| (|spadConstant| |$| 36) (QREFELT |$| 37)) |x1|)
+ ((QUOTE T)
+ (SPADCALL |x1| (|spadConstant| |$| 17) (QREFELT |$| 21)))))))))
+
+(DEFUN |RNS-;patternMatch;SP2Pmr;10| (|x| |p| |l| |$|)
+ (PROG (|r|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |p| (QREFELT |$| 40))
+ (SPADCALL |p| |x| |l| (QREFELT |$| 42)))
+ ((SPADCALL |p| (QREFELT |$| 43))
+ (SEQ
+ (LETT |r|
+ (SPADCALL |p| (QREFELT |$| 45))
+ |RNS-;patternMatch;SP2Pmr;10|)
+ (EXIT
+ (COND
+ ((QEQCAR |r| 0)
+ (COND
+ ((SPADCALL
+ (SPADCALL |x| (QREFELT |$| 30))
+ (QCDR |r|)
+ (QREFELT |$| 46))
+ |l|)
+ ((QUOTE T) (SPADCALL (QREFELT |$| 47)))))
+ ((QUOTE T) (SPADCALL (QREFELT |$| 47)))))))
+ ((QUOTE T) (SPADCALL (QREFELT |$| 47))))))))
+
+(DEFUN |RealNumberSystem&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|RealNumberSystem&|))
+ (LETT |dv$| (LIST (QUOTE |RealNumberSystem&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 52) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |RealNumberSystem&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|NonNegativeInteger|)
+ |RNS-;characteristic;Nni;1|
+ (0 . |truncate|)
+ (5 . |-|)
+ |RNS-;fractionPart;2S;2|
+ (|Boolean|)
+ (11 . |negative?|)
+ (16 . |-|)
+ (21 . |floor|)
+ |RNS-;truncate;2S;3|
+ (26 . |One|)
+ (|Integer|)
+ (30 . |coerce|)
+ (35 . |/|)
+ (41 . |+|)
+ |RNS-;round;2S;4|
+ (47 . |abs|)
+ |RNS-;norm;2S;5|
+ (|Fraction| 18)
+ (52 . |numer|)
+ (57 . |denom|)
+ |RNS-;coerce;FS;6|
+ (|Float|)
+ (62 . |convert|)
+ (|Pattern| 29)
+ (67 . |coerce|)
+ |RNS-;convert;SP;7|
+ (72 . |wholePart|)
+ (77 . |=|)
+ (83 . |Zero|)
+ (87 . |<|)
+ |RNS-;floor;2S;8|
+ |RNS-;ceiling;2S;9|
+ (93 . |generic?|)
+ (|PatternMatchResult| 29 6)
+ (98 . |addMatch|)
+ (105 . |constant?|)
+ (|Union| 29 (QUOTE "failed"))
+ (110 . |retractIfCan|)
+ (115 . |=|)
+ (121 . |failed|)
+ (|PatternMatchResult| 29 |$|)
+ |RNS-;patternMatch;SP2Pmr;10|
+ (|DoubleFloat|)
+ (|OutputForm|)))
+ (QUOTE
+ #(|truncate| 125 |round| 130 |patternMatch| 135 |norm| 142
+ |fractionPart| 147 |floor| 152 |convert| 157 |coerce| 162
+ |characteristic| 172 |ceiling| 176))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 49
+ (QUOTE
+ (1 6 0 0 9 2 6 0 0 0 10 1 6 12 0 13 1 6 0 0 14 1 6 0 0 15 0 6 0
+ 17 1 6 0 18 19 2 6 0 0 0 20 2 6 0 0 0 21 1 6 0 0 23 1 25 18 0
+ 26 1 25 18 0 27 1 6 29 0 30 1 31 0 29 32 1 6 18 0 34 2 6 12 0
+ 0 35 0 6 0 36 2 6 12 0 0 37 1 31 12 0 40 3 41 0 31 6 0 42 1 31
+ 12 0 43 1 31 44 0 45 2 29 12 0 0 46 0 41 0 47 1 0 0 0 16 1 0 0
+ 0 22 3 0 48 0 31 48 49 1 0 0 0 24 1 0 0 0 11 1 0 0 0 38 1 0 31
+ 0 33 1 0 0 25 28 1 0 0 25 28 0 0 7 8 1 0 0 0 39))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{category FPS FloatingPointSystem}
+<<category FPS FloatingPointSystem>>=
+)abbrev category FPS FloatingPointSystem
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: approximate, base, bits, digits, exponent, float,
+++ mantissa, order, precision, round?
+++ Related Constructors:
+++ Keywords: float, floating point
+++ Description:
+++ This category is intended as a model for floating point systems.
+++ A floating point system is a model for the real numbers. In fact,
+++ it is an approximation in the sense that not all real numbers are
+++ exactly representable by floating point numbers.
+++ A floating point system is characterized by the following:
+++
+++ 1: \spadfunFrom{base}{FloatingPointSystem} of the \spadfunFrom{exponent}{FloatingPointSystem}.
+++ (actual implemenations are usually binary or decimal)
+++ 2: \spadfunFrom{precision}{FloatingPointSystem} of the \spadfunFrom{mantissa}{FloatingPointSystem} (arbitrary or fixed)
+++ 3: rounding error for operations
+--++ 4: when, and what happens if exponent overflow/underflow occurs
+++
+++ Because a Float is an approximation to the real numbers, even though
+++ it is defined to be a join of a Field and OrderedRing, some of
+++ the attributes do not hold. In particular associative("+")
+++ does not hold. Algorithms defined over a field need special
+++ considerations when the field is a floating point system.
+FloatingPointSystem(): Category == RealNumberSystem() with
+ approximate
+ ++ \spad{approximate} means "is an approximation to the real numbers".
+ float: (Integer,Integer) -> %
+ ++ float(a,e) returns \spad{a * base() ** e}.
+ float: (Integer,Integer,PositiveInteger) -> %
+ ++ float(a,e,b) returns \spad{a * b ** e}.
+ order: % -> Integer
+ ++ order x is the order of magnitude of x.
+ ++ Note: \spad{base ** order x <= |x| < base ** (1 + order x)}.
+ base: () -> PositiveInteger
+ ++ base() returns the base of the \spadfunFrom{exponent}{FloatingPointSystem}.
+ exponent: % -> Integer
+ ++ exponent(x) returns the \spadfunFrom{exponent}{FloatingPointSystem} part of x.
+ mantissa: % -> Integer
+ ++ mantissa(x) returns the mantissa part of x.
+ -- round?: () -> B
+ -- ++ round?() returns the rounding or chopping.
+
+ bits: () -> PositiveInteger
+ ++ bits() returns ceiling's precision in bits.
+ digits: () -> PositiveInteger
+ ++ digits() returns ceiling's precision in decimal digits.
+ precision: () -> PositiveInteger
+ ++ precision() returns the precision in digits base.
+
+ if % has arbitraryPrecision then
+ bits: PositiveInteger -> PositiveInteger
+ ++ bits(n) set the \spadfunFrom{precision}{FloatingPointSystem} to n bits.
+ digits: PositiveInteger -> PositiveInteger
+ ++ digits(d) set the \spadfunFrom{precision}{FloatingPointSystem} to d digits.
+ precision: PositiveInteger -> PositiveInteger
+ ++ precision(n) set the precision in the base to n decimal digits.
+ increasePrecision: Integer -> PositiveInteger
+ ++ increasePrecision(n) increases the current
+ ++ \spadfunFrom{precision}{FloatingPointSystem} by n decimal digits.
+ decreasePrecision: Integer -> PositiveInteger
+ ++ decreasePrecision(n) decreases the current
+ ++ \spadfunFrom{precision}{FloatingPointSystem} precision by n decimal digits.
+ if not (% has arbitraryExponent) then
+ -- overflow: (()->Exit) -> Void
+ -- ++ overflow() returns the Exponent overflow of float
+ -- underflow: (()->Exit) -> Void
+ -- ++ underflow() returns the Exponent underflow of float
+ -- maxExponent: () -> Integer
+ -- ++ maxExponent() returns the max Exponent of float
+ if not (% has arbitraryPrecision) then
+ min: () -> %
+ ++ min() returns the minimum floating point number.
+ max: () -> %
+ ++ max() returns the maximum floating point number.
+ add
+ float(ma, ex) == float(ma, ex, base())
+ digits() == max(1,4004 * (bits()-1) quo 13301)::PositiveInteger
+
+@
+\section{FPS.lsp BOOTSTRAP}
+{\bf FPS} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf FPS} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf FPS.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<FPS.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |FloatingPointSystem;AL| (QUOTE NIL))
+
+(DEFUN |FloatingPointSystem| NIL
+ (LET (#:G105645)
+ (COND
+ (|FloatingPointSystem;AL|)
+ (T (SETQ |FloatingPointSystem;AL| (|FloatingPointSystem;|))))))
+
+(DEFUN |FloatingPointSystem;| NIL
+ (PROG (#1=#:G105643)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (|Join|
+ (|RealNumberSystem|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|float| (|$| (|Integer|) (|Integer|))) T)
+ ((|float| (|$| (|Integer|) (|Integer|) (|PositiveInteger|))) T)
+ ((|order| ((|Integer|) |$|)) T)
+ ((|base| ((|PositiveInteger|))) T)
+ ((|exponent| ((|Integer|) |$|)) T)
+ ((|mantissa| ((|Integer|) |$|)) T)
+ ((|bits| ((|PositiveInteger|))) T)
+ ((|digits| ((|PositiveInteger|))) T)
+ ((|precision| ((|PositiveInteger|))) T)
+ ((|bits| ((|PositiveInteger|) (|PositiveInteger|)))
+ (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ ((|digits| ((|PositiveInteger|) (|PositiveInteger|)))
+ (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ ((|precision| ((|PositiveInteger|) (|PositiveInteger|)))
+ (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ ((|increasePrecision| ((|PositiveInteger|) (|Integer|)))
+ (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ ((|decreasePrecision| ((|PositiveInteger|) (|Integer|)))
+ (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ ((|min| (|$|))
+ (AND
+ (|not| (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ (|not| (|has| |$| (ATTRIBUTE |arbitraryExponent|)))))
+ ((|max| (|$|))
+ (AND
+ (|not| (|has| |$| (ATTRIBUTE |arbitraryPrecision|)))
+ (|not| (|has| |$| (ATTRIBUTE |arbitraryExponent|)))))))
+ (QUOTE ((|approximate| T)))
+ (QUOTE ((|PositiveInteger|) (|Integer|)))
+ NIL))
+ |FloatingPointSystem|)
+ (SETELT #1# 0 (QUOTE (|FloatingPointSystem|)))))))
+
+(MAKEPROP (QUOTE |FloatingPointSystem|) (QUOTE NILADIC) T)
+
+@
+\section{FPS-.lsp BOOTSTRAP}
+{\bf FPS-} depends {\bf FPS}.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf FPS-} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf FPS-.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<FPS-.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |FPS-;float;2IS;1| (|ma| |ex| |$|)
+ (SPADCALL |ma| |ex| (SPADCALL (QREFELT |$| 8)) (QREFELT |$| 10)))
+
+(DEFUN |FPS-;digits;Pi;2| (|$|)
+ (PROG (#1=#:G105654)
+ (RETURN
+ (PROG1
+ (LETT #1#
+ (MAX 1
+ (QUOTIENT2
+ (SPADCALL 4004
+ (|-| (SPADCALL (QREFELT |$| 13)) 1)
+ (QREFELT |$| 14))
+ 13301))
+ |FPS-;digits;Pi;2|)
+ (|check-subtype| (|>| #1# 0) (QUOTE (|PositiveInteger|)) #1#)))))
+
+(DEFUN |FloatingPointSystem&| (|#1|)
+ (PROG (|DV$1| |dv$| |$| |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |DV$1| (|devaluate| |#1|) . #1=(|FloatingPointSystem&|))
+ (LETT |dv$| (LIST (QUOTE |FloatingPointSystem&|) |DV$1|) . #1#)
+ (LETT |$| (GETREFV 17) . #1#)
+ (QSETREFV |$| 0 |dv$|)
+ (QSETREFV |$| 3
+ (LETT |pv$|
+ (|buildPredVector| 0 0
+ (LIST
+ (|HasAttribute| |#1| (QUOTE |arbitraryExponent|))
+ (|HasAttribute| |#1| (QUOTE |arbitraryPrecision|)))) . #1#))
+ (|stuffDomainSlots| |$|)
+ (QSETREFV |$| 6 |#1|)
+ |$|))))
+
+(MAKEPROP
+ (QUOTE |FloatingPointSystem&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|PositiveInteger|)
+ (0 . |base|)
+ (|Integer|)
+ (4 . |float|)
+ |FPS-;float;2IS;1|
+ (11 . |One|)
+ (15 . |bits|)
+ (19 . |*|)
+ (25 . |max|)
+ |FPS-;digits;Pi;2|))
+ (QUOTE #(|float| 29 |digits| 35))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 16
+ (QUOTE
+ (0 6 7 8 3 6 0 9 9 7 10 0 6 0 12 0 6 7 13 2 9 0 7 0 14 0 6 0 15
+ 2 0 0 9 9 11 0 0 7 16))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{domain DFLOAT DoubleFloat}
+Greg Vanuxem has added some functionality to allow the user to modify
+the printed format of floating point numbers. The format of the numbers
+follows the common lisp format specification for floats. First we include
+Greg's email to show the use of this feature:
+\begin{verbatim}
+PS: For those who use the Doublefloat domain
+ there is an another (undocumented) patch that adds a
+ lisp format to the DoubleFloat output routine. Copy
+ int/algebra/DFLOAT.spad to your working directory,
+ patch it, compile it and ")lib" it when necessary.
+
+
+(1) -> )boot $useBFasDefault:=false
+
+(SPADLET |$useBFasDefault| NIL)
+Value = NIL
+(1) -> a:= matrix [ [0.5978,0.2356], [0.4512,0.2355] ]
+
+ + 0.5978 0.2356 +
+ (1) | |
+ +0.45119999999999999 0.23549999999999999+
+ Type: Matrix DoubleFloat
+(2) -> )lib DFLOAT
+ DoubleFloat is now explicitly exposed in frame initial
+ DoubleFloat will be automatically loaded when needed
+from /home/greg/Axiom/DFLOAT.NRLIB/code
+(2) -> doubleFloatFormat("~,4,,F")
+
+ (2) "~G"
+ Type: String
+(3) -> a
+
+ +0.5978 0.2356+
+ (3) | |
+ +0.4512 0.2355+
+ Type: Matrix DoubleFloat
+
+\end{verbatim}
+So it is clear that he has added a new function called
+{\tt doubleFloatFormat} which takes a string argument that
+specifies the common lisp format control string (\"{}\~{},4,,F\"{}).
+For reference we quote from the common lisp manual \cite{1}.
+On page 582 we find:
+
+\begin{quote}
+A format directive consists of a tilde (\~{}), optional prefix
+parameters separated by commas, optional colon (:) and at-sign (@)
+modifiers, and a single character indicating what kind of directive this is.
+The alphabetic case of the directive character is ignored. The prefix
+parameters are generally integers, notated as optionally signed decimal
+numbers.
+
+X3J13 voted in June 1987 (80) to specify that if both colon and at-sign
+modifiers are present, they may appear in either order; thus \~{}:@R
+and \~{}@:R mean the same thing. However, it is traditional to put the
+colon first, and all examples in the book put colon before at-signs.
+\end{quote}
+
+\noindent
+On page 588 we find:
+
+\begin{quote}
+\~{}F
+
+{\sl Fixed-format floating-point}. The next {\sl arg} is printed as a
+floating point number.
+
+The full form is {\sl \~{}w,d,k,overfowchar,padchar}F. The parameter
+{\sl w} is the width of the filed to be printed; {\sl d} is the number
+of digits to print after the decimal point; {\sl k} is a scale factor
+that defaults to zero.
+
+Exactly {\sl w} characters will be output. First, leading copies of the
+character {\sl padchar} (which defaults to a space) are printed, if
+necessary, to pad the field on the left. If the {\sl arg} is negative,
+then a minus sign is printed; if the {\sl arg} is not negative, then
+a plus signed is printed if and only if the @ modifier was specified.
+Then a sequence of digits, containing a single embedded decimal point,
+is printed; this represents the magnitude of the value of {\sl arg}
+times $10^k$, rounded to {\sl d} fractional digits. (When rounding up
+and rounding down would produce printed values equidistant from the
+scaled value of {\sl arg}, then the implementation is free to use
+either one. For example, printing the argument 6.375 using the format
+\~{}4.2F may correctly produce either 6.37 or 6.38.) Leading zeros are
+not permitted, except that a single zero digit is output before the
+decimal point if the printed value is less than 1, and this single zero
+digit is not output after all if $w = d + 1$.
+
+If it is impossible to print the value in the required format in the
+field of width {\sl w}, then one of two actions is taken. If the
+parameter {\sl overflowchar} is specified, then {\sl w} copies of that
+parameter are printed instead of the scaled value of {\sl arg}. If the
+{\sl overflowchar} parameter is omitted, then the scaled value is
+printed using more than {\sl w} characters, as many more as may be
+needed.
+
+If the {\sl w} parameter is omitted, then the field is of variable width.
+In effect, a value is chosen for {\sl w} in such a way that no leading pad
+characters need to be printed and exactly {\sl d} characters will follow
+the decimal point. For example, the directive \~{},2F will print exactly
+two digits after the decimal point and as many as necessary before the
+decimal point.
+
+If the parameter {\sl d} is omitted, then there is no constraint on the
+number of digits to appear after the decimal point. A value is chosen
+for {\sl d} in such a way that as many digits as possible may be printed
+subject to the width constraint imposed by the parameter {\sl w} and the
+constraint that no trailing zero digits may appear in the fraction, except
+that if the fraction to be printed is zero, then a single zero digit should
+appear after the decimal point if permitted by the width constraint.
+
+If both {\sl w} and {\sl d} are omitted, then the effect is to print the
+value using ordinary free-format output; {\tt prin1} uses this format
+for any number whose magnitude is either zero or between $10^{-3}$
+(inclusive) and $10^7$ (exclusive).
+
+If {\sl w} is omitted, then if the magnitude of {\sl arg} is so large
+(or, if {\sl d} is also omitted, so small) that more than 100 digits
+would have to be printed, then an implementation is free, at its
+discretion, to print the number using exponential notation instead,
+as if by the directive \~{}E (with all parameters of \~{}E defaulted,
+not taking their valued from the \~{}F directive).
+
+If {\sl arg} is a rational number, then it is coerced to be a
+{\tt single-float} and then printed. (Alternatively, an implementation
+is permitted to process a rational number by any other method that has
+essentially the same behavior but avoids such hazards as loss of
+precision or overflow because of the coercion. However, note that if
+{\sl w} and {\sl d} are unspecified and the number has no exact decimal
+representation, for example 1/3, some precision cutoff must be chosen
+by the implementation; only a finite number of digits may be printed.)
+
+If {\sl arg} is a complex number or some non-numeric object, then it
+is printed using the format directive {\sl \~{}w}D, thereby printing
+it in decimal radix and a minimum field width of {\sl w}. (If it is
+desired to print each of the real part and imaginary part of a
+complex number using a \~{}F directive, then this must be done explicitly
+with two \~{}F directives and code to extract the two parts of the
+complex number.)
+
+
+\end{quote}
+<<domain DFLOAT DoubleFloat>>=
+)abbrev domain DFLOAT DoubleFloat
+++ Author: Michael Monagan
+++ Date Created:
+++ January 1988
+++ Change History:
+++ Basic Operations: exp1, hash, log2, log10, rationalApproximation, / , **
+++ Related Constructors:
+++ Keywords: small float
+++ Description: \spadtype{DoubleFloat} is intended to make accessible
+++ hardware floating point arithmetic in \Language{}, either native double
+++ precision, or IEEE. On most machines, there will be hardware support for
+++ the arithmetic operations:
+++ \spadfunFrom{+}{DoubleFloat}, \spadfunFrom{*}{DoubleFloat},
+++ \spadfunFrom{/}{DoubleFloat} and possibly also the
+++ \spadfunFrom{sqrt}{DoubleFloat} operation.
+++ The operations \spadfunFrom{exp}{DoubleFloat},
+++ \spadfunFrom{log}{DoubleFloat}, \spadfunFrom{sin}{DoubleFloat},
+++ \spadfunFrom{cos}{DoubleFloat},
+++ \spadfunFrom{atan}{DoubleFloat} are normally coded in
+++ software based on minimax polynomial/rational approximations.
+++ Note that under Lisp/VM, \spadfunFrom{atan}{DoubleFloat}
+++ is not available at this time.
+++ Some general comments about the accuracy of the operations:
+++ the operations \spadfunFrom{+}{DoubleFloat},
+++ \spadfunFrom{*}{DoubleFloat}, \spadfunFrom{/}{DoubleFloat} and
+++ \spadfunFrom{sqrt}{DoubleFloat} are expected to be fully accurate.
+++ The operations \spadfunFrom{exp}{DoubleFloat},
+++ \spadfunFrom{log}{DoubleFloat}, \spadfunFrom{sin}{DoubleFloat},
+++ \spadfunFrom{cos}{DoubleFloat} and
+++ \spadfunFrom{atan}{DoubleFloat} are not expected to be
+++ fully accurate. In particular, \spadfunFrom{sin}{DoubleFloat}
+++ and \spadfunFrom{cos}{DoubleFloat}
+++ will lose all precision for large arguments.
+++
+++ The \spadtype{Float} domain provides an alternative to the \spad{DoubleFloat} domain.
+++ It provides an arbitrary precision model of floating point arithmetic.
+++ This means that accuracy problems like those above are eliminated
+++ by increasing the working precision where necessary. \spadtype{Float}
+++ provides some special functions such as \spadfunFrom{erf}{DoubleFloat},
+++ the error function
+++ in addition to the elementary functions. The disadvantage of
+++ \spadtype{Float} is that it is much more expensive than small floats when the latter can be used.
+-- I've put some timing comparisons in the notes for the Float
+-- domain about the difference in speed between the two domains.
+DoubleFloat(): Join(FloatingPointSystem, DifferentialRing, OpenMath,
+ TranscendentalFunctionCategory, ConvertibleTo InputForm) with
+ _/ : (%, Integer) -> %
+ ++ x / i computes the division from x by an integer i.
+ _*_* : (%,%) -> %
+ ++ x ** y returns the yth power of x (equal to \spad{exp(y log x)}).
+ exp1 : () -> %
+ ++ exp1() returns the natural log base \spad{2.718281828...}.
+ hash : % -> Integer
+ ++ hash(x) returns the hash key for x
+ log2 : % -> %
+ ++ log2(x) computes the logarithm with base 2 for x.
+ log10: % -> %
+ ++ log10(x) computes the logarithm with base 10 for x.
+ atan : (%,%) -> %
+ ++ atan(x,y) computes the arc tangent from x with phase y.
+ Gamma: % -> %
+ ++ Gamma(x) is the Euler Gamma function.
+ Beta : (%,%) -> %
+ ++ Beta(x,y) is \spad{Gamma(x) * Gamma(y)/Gamma(x+y)}.
+ doubleFloatFormat : String -> String
+ ++ change the output format for doublefloats using lisp format strings
+ rationalApproximation: (%, NonNegativeInteger) -> Fraction Integer
+ ++ rationalApproximation(f, n) computes a rational approximation
+ ++ r to f with relative error \spad{< 10**(-n)}.
+ rationalApproximation: (%, NonNegativeInteger, NonNegativeInteger) -> Fraction Integer
+ ++ rationalApproximation(f, n, b) computes a rational
+ ++ approximation r to f with relative error \spad{< b**(-n)}
+ ++ (that is, \spad{|(r-f)/f| < b**(-n)}).
+
+ == add
+ format: String := "~G"
+ MER ==> Record(MANTISSA:Integer,EXPONENT:Integer)
+
+ manexp: % -> MER
+
+ doubleFloatFormat(s:String): String ==
+ ss: String := format
+ format := s
+ ss
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ OMputFloat(dev, convert x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ OMputFloat(dev, convert x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ OMputFloat(dev, convert x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ OMputFloat(dev, convert x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ checkComplex(x:%):% == C_-TO_-R(x)$Lisp
+ -- In AKCL we used to have to make the arguments to ASIN ACOS ACOSH ATANH
+ -- complex to get the correct behaviour.
+ --makeComplex(x: %):% == COMPLEX(x, 0$%)$Lisp
+
+ base() == FLOAT_-RADIX(0$%)$Lisp
+ mantissa x == manexp(x).MANTISSA
+ exponent x == manexp(x).EXPONENT
+ precision() == FLOAT_-DIGITS(0$%)$Lisp
+ bits() ==
+ base() = 2 => precision()
+ base() = 16 => 4*precision()
+ wholePart(precision()*log2(base()::%))::PositiveInteger
+ max() == MOST_-POSITIVE_-LONG_-FLOAT$Lisp
+ min() == MOST_-NEGATIVE_-LONG_-FLOAT$Lisp
+ order(a) == precision() + exponent a - 1
+ 0 == FLOAT(0$Lisp,MOST_-POSITIVE_-LONG_-FLOAT$Lisp)$Lisp
+ 1 == FLOAT(1$Lisp,MOST_-POSITIVE_-LONG_-FLOAT$Lisp)$Lisp
+ -- rational approximation to e accurate to 23 digits
+ exp1() == FLOAT(534625820200,MOST_-POSITIVE_-LONG_-FLOAT$Lisp)$Lisp / FLOAT(196677847971,MOST_-POSITIVE_-LONG_-FLOAT$Lisp)$Lisp
+ pi() == PI$Lisp
+ coerce(x:%):OutputForm ==
+ outputForm(FORMAT(NIL$Lisp,format,x)$Lisp pretend DoubleFloat)
+ convert(x:%):InputForm == convert(x pretend DoubleFloat)$InputForm
+ x < y == (x<y)$Lisp
+ - x == (-x)$Lisp
+ x + y == (x+y)$Lisp
+ x:% - y:% == (x-y)$Lisp
+ x:% * y:% == (x*y)$Lisp
+ i:Integer * x:% == (i*x)$Lisp
+ max(x,y) == MAX(x,y)$Lisp
+ min(x,y) == MIN(x,y)$Lisp
+ x = y == (x=y)$Lisp
+ x:% / i:Integer == (x/i)$Lisp
+ sqrt x == checkComplex SQRT(x)$Lisp
+ log10 x == checkComplex log(x)$Lisp
+ x:% ** i:Integer == EXPT(x,i)$Lisp
+ x:% ** y:% == checkComplex EXPT(x,y)$Lisp
+ coerce(i:Integer):% == FLOAT(i,MOST_-POSITIVE_-LONG_-FLOAT$Lisp)$Lisp
+ exp x == EXP(x)$Lisp
+ log x == checkComplex LN(x)$Lisp
+ log2 x == checkComplex LOG2(x)$Lisp
+ sin x == SIN(x)$Lisp
+ cos x == COS(x)$Lisp
+ tan x == TAN(x)$Lisp
+ cot x == COT(x)$Lisp
+ sec x == SEC(x)$Lisp
+ csc x == CSC(x)$Lisp
+ asin x == checkComplex ASIN(x)$Lisp -- can be complex
+ acos x == checkComplex ACOS(x)$Lisp -- can be complex
+ atan x == ATAN(x)$Lisp
+ acsc x == checkComplex ACSC(x)$Lisp
+ acot x == ACOT(x)$Lisp
+ asec x == checkComplex ASEC(x)$Lisp
+ sinh x == SINH(x)$Lisp
+ cosh x == COSH(x)$Lisp
+ tanh x == TANH(x)$Lisp
+ csch x == CSCH(x)$Lisp
+ coth x == COTH(x)$Lisp
+ sech x == SECH(x)$Lisp
+ asinh x == ASINH(x)$Lisp
+ acosh x == checkComplex ACOSH(x)$Lisp -- can be complex
+ atanh x == checkComplex ATANH(x)$Lisp -- can be complex
+ acsch x == ACSCH(x)$Lisp
+ acoth x == checkComplex ACOTH(x)$Lisp
+ asech x == checkComplex ASECH(x)$Lisp
+ x:% / y:% == (x/y)$Lisp
+ negative? x == MINUSP(x)$Lisp
+ zero? x == ZEROP(x)$Lisp
+ hash x == HASHEQ(x)$Lisp
+ recip(x) == (zero? x => "failed"; 1 / x)
+ differentiate x == 0
+
+ SFSFUN ==> DoubleFloatSpecialFunctions()
+ sfx ==> x pretend DoubleFloat
+ sfy ==> y pretend DoubleFloat
+ Gamma x == Gamma(sfx)$SFSFUN pretend %
+ Beta(x,y) == Beta(sfx,sfy)$SFSFUN pretend %
+
+ wholePart x == FIX(x)$Lisp
+ float(ma,ex,b) == ma*(b::%)**ex
+ convert(x:%):DoubleFloat == x pretend DoubleFloat
+ convert(x:%):Float == convert(x pretend DoubleFloat)$Float
+ rationalApproximation(x, d) == rationalApproximation(x, d, 10)
+
+ atan(x,y) ==
+ x = 0 =>
+ y > 0 => pi()/2
+ y < 0 => -pi()/2
+ 0
+ -- Only count on first quadrant being on principal branch.
+ theta := atan abs(y/x)
+ if x < 0 then theta := pi() - theta
+ if y < 0 then theta := - theta
+ theta
+
+ retract(x:%):Fraction(Integer) ==
+ rationalApproximation(x, (precision() - 1)::NonNegativeInteger, base())
+
+ retractIfCan(x:%):Union(Fraction Integer, "failed") ==
+ rationalApproximation(x, (precision() - 1)::NonNegativeInteger, base())
+
+ retract(x:%):Integer ==
+ x = ((n := wholePart x)::%) => n
+ error "Not an integer"
+
+ retractIfCan(x:%):Union(Integer, "failed") ==
+ x = ((n := wholePart x)::%) => n
+ "failed"
+
+ sign(x) == retract FLOAT_-SIGN(x,1)$Lisp
+ abs x == FLOAT_-SIGN(1,x)$Lisp
+
+
+
+ manexp(x) ==
+ zero? x => [0,0]
+ s := sign x; x := abs x
+ if x > max()$% then return [s*mantissa(max())+1,exponent max()]
+ me:Record(man:%,exp:Integer) := MANEXP(x)$Lisp
+ two53:= base()**precision()
+ [s*wholePart(two53 * me.man ),me.exp-precision()]
+
+-- rationalApproximation(y,d,b) ==
+-- this is the quotient remainder algorithm (requires wholePart operation)
+-- x := y
+-- if b < 2 then error "base must be > 1"
+-- tol := (b::%)**d
+-- p0,p1,q0,q1 : Integer
+-- p0 := 0; p1 := 1; q0 := 1; q1 := 0
+-- repeat
+-- a := wholePart x
+-- x := fractionPart x
+-- p2 := p0+a*p1
+-- q2 := q0+a*q1
+-- if x = 0 or tol*abs(q2*y-(p2::%)) < abs(q2*y) then
+-- return (p2/q2)
+-- (p0,p1) := (p1,p2)
+-- (q0,q1) := (q1,q2)
+-- x := 1/x
+
+ rationalApproximation(f,d,b) ==
+ -- this algorithm expresses f as n / d where d = BASE ** k
+ -- then all arithmetic operations are done over the integers
+ (nu, ex) := manexp f
+ BASE := base()
+ ex >= 0 => (nu * BASE ** (ex::NonNegativeInteger))::Fraction(Integer)
+ de :Integer := BASE**((-ex)::NonNegativeInteger)
+ b < 2 => error "base must be > 1"
+ tol := b**d
+ s := nu; t := de
+ p0:Integer := 0; p1:Integer := 1; q0:Integer := 1; q1:Integer := 0
+ repeat
+ (q,r) := divide(s, t)
+ p2 := q*p1+p0
+ q2 := q*q1+q0
+ r = 0 or tol*abs(nu*q2-de*p2) < de*abs(p2) => return(p2/q2)
+ (p0,p1) := (p1,p2)
+ (q0,q1) := (q1,q2)
+ (s,t) := (t,r)
+
+ x:% ** r:Fraction Integer ==
+ zero? x =>
+ zero? r => error "0**0 is undefined"
+ negative? r => error "division by 0"
+ 0
+-- zero? r or one? x => 1
+ zero? r or (x = 1) => 1
+-- one? r => x
+ (r = 1) => x
+ n := numer r
+ d := denom r
+ negative? x =>
+ odd? d =>
+ odd? n => return -((-x)**r)
+ return ((-x)**r)
+ error "negative root"
+ d = 2 => sqrt(x) ** n
+ x ** (n::% / d::%)
+
+@
+\section{DFLOAT.lsp BOOTSTRAP}
+{\bf DFLOAT} depends on itself.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf DFLOAT} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf DFLOAT.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<DFLOAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |DFLOAT;OMwrite;$S;1| (|x| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |DFLOAT;OMwrite;$S;1|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |DFLOAT;OMwrite;$S;1|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 7)) (QREFELT |$| 10)) |DFLOAT;OMwrite;$S;1|) (SPADCALL |dev| (QREFELT |$| 12)) (SPADCALL |dev| |x| (QREFELT |$| 14)) (SPADCALL |dev| (QREFELT |$| 15)) (SPADCALL |dev| (QREFELT |$| 16)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |DFLOAT;OMwrite;$S;1|) (EXIT |s|)))))
+
+(DEFUN |DFLOAT;OMwrite;$BS;2| (|x| |wholeObj| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |DFLOAT;OMwrite;$BS;2|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |DFLOAT;OMwrite;$BS;2|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 7)) (QREFELT |$| 10)) |DFLOAT;OMwrite;$BS;2|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 12)))) (SPADCALL |dev| |x| (QREFELT |$| 14)) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 15)))) (SPADCALL |dev| (QREFELT |$| 16)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |DFLOAT;OMwrite;$BS;2|) (EXIT |s|)))))
+
+(DEFUN |DFLOAT;OMwrite;Omd$V;3| (|dev| |x| |$|) (SEQ (SPADCALL |dev| (QREFELT |$| 12)) (SPADCALL |dev| |x| (QREFELT |$| 14)) (EXIT (SPADCALL |dev| (QREFELT |$| 15)))))
+
+(DEFUN |DFLOAT;OMwrite;Omd$BV;4| (|dev| |x| |wholeObj| |$|) (SEQ (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 12)))) (SPADCALL |dev| |x| (QREFELT |$| 14)) (EXIT (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 15)))))))
+
+(PUT (QUOTE |DFLOAT;checkComplex|) (QUOTE |SPADreplace|) (QUOTE |C-TO-R|))
+
+(DEFUN |DFLOAT;checkComplex| (|x| |$|) (|C-TO-R| |x|))
+
+(PUT (QUOTE |DFLOAT;base;Pi;6|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (|FLOAT-RADIX| 0.0))))
+
+(DEFUN |DFLOAT;base;Pi;6| (|$|) (|FLOAT-RADIX| 0.0))
+
+(DEFUN |DFLOAT;mantissa;$I;7| (|x| |$|) (QCAR (|DFLOAT;manexp| |x| |$|)))
+
+(DEFUN |DFLOAT;exponent;$I;8| (|x| |$|) (QCDR (|DFLOAT;manexp| |x| |$|)))
+
+(PUT (QUOTE |DFLOAT;precision;Pi;9|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (|FLOAT-DIGITS| 0.0))))
+
+(DEFUN |DFLOAT;precision;Pi;9| (|$|) (|FLOAT-DIGITS| 0.0))
+
+(DEFUN |DFLOAT;bits;Pi;10| (|$|) (PROG (#1=#:G105705) (RETURN (COND ((EQL (|FLOAT-RADIX| 0.0) 2) (|FLOAT-DIGITS| 0.0)) ((EQL (|FLOAT-RADIX| 0.0) 16) (|*| 4 (|FLOAT-DIGITS| 0.0))) ((QUOTE T) (PROG1 (LETT #1# (FIX (SPADCALL (|FLOAT-DIGITS| 0.0) (SPADCALL (FLOAT (|FLOAT-RADIX| 0.0) |MOST-POSITIVE-LONG-FLOAT|) (QREFELT |$| 28)) (QREFELT |$| 29))) |DFLOAT;bits;Pi;10|) (|check-subtype| (|>| #1# 0) (QUOTE (|PositiveInteger|)) #1#)))))))
+
+(PUT (QUOTE |DFLOAT;max;$;11|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL |MOST-POSITIVE-LONG-FLOAT|)))
+
+(DEFUN |DFLOAT;max;$;11| (|$|) |MOST-POSITIVE-LONG-FLOAT|)
+
+(PUT (QUOTE |DFLOAT;min;$;12|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL |MOST-NEGATIVE-LONG-FLOAT|)))
+
+(DEFUN |DFLOAT;min;$;12| (|$|) |MOST-NEGATIVE-LONG-FLOAT|)
+
+(DEFUN |DFLOAT;order;$I;13| (|a| |$|) (|-| (|+| (|FLOAT-DIGITS| 0.0) (SPADCALL |a| (QREFELT |$| 26))) 1))
+
+(PUT (QUOTE |DFLOAT;Zero;$;14|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (FLOAT 0 |MOST-POSITIVE-LONG-FLOAT|))))
+
+(DEFUN |DFLOAT;Zero;$;14| (|$|) (FLOAT 0 |MOST-POSITIVE-LONG-FLOAT|))
+
+(PUT (QUOTE |DFLOAT;One;$;15|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (FLOAT 1 |MOST-POSITIVE-LONG-FLOAT|))))
+
+(DEFUN |DFLOAT;One;$;15| (|$|) (FLOAT 1 |MOST-POSITIVE-LONG-FLOAT|))
+
+(DEFUN |DFLOAT;exp1;$;16| (|$|) (|/| (FLOAT 534625820200 |MOST-POSITIVE-LONG-FLOAT|) (FLOAT 196677847971 |MOST-POSITIVE-LONG-FLOAT|)))
+
+(PUT (QUOTE |DFLOAT;pi;$;17|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL PI)))
+
+(DEFUN |DFLOAT;pi;$;17| (|$|) PI)
+
+(DEFUN |DFLOAT;coerce;$Of;18| (|x| |$|) (SPADCALL |x| (QREFELT |$| 39)))
+
+(DEFUN |DFLOAT;convert;$If;19| (|x| |$|) (SPADCALL |x| (QREFELT |$| 42)))
+
+(PUT (QUOTE |DFLOAT;<;2$B;20|) (QUOTE |SPADreplace|) (QUOTE |<|))
+
+(DEFUN |DFLOAT;<;2$B;20| (|x| |y| |$|) (|<| |x| |y|))
+
+(PUT (QUOTE |DFLOAT;-;2$;21|) (QUOTE |SPADreplace|) (QUOTE |-|))
+
+(DEFUN |DFLOAT;-;2$;21| (|x| |$|) (|-| |x|))
+
+(PUT (QUOTE |DFLOAT;+;3$;22|) (QUOTE |SPADreplace|) (QUOTE |+|))
+
+(DEFUN |DFLOAT;+;3$;22| (|x| |y| |$|) (|+| |x| |y|))
+
+(PUT (QUOTE |DFLOAT;-;3$;23|) (QUOTE |SPADreplace|) (QUOTE |-|))
+
+(DEFUN |DFLOAT;-;3$;23| (|x| |y| |$|) (|-| |x| |y|))
+
+(PUT (QUOTE |DFLOAT;*;3$;24|) (QUOTE |SPADreplace|) (QUOTE |*|))
+
+(DEFUN |DFLOAT;*;3$;24| (|x| |y| |$|) (|*| |x| |y|))
+
+(PUT (QUOTE |DFLOAT;*;I2$;25|) (QUOTE |SPADreplace|) (QUOTE |*|))
+
+(DEFUN |DFLOAT;*;I2$;25| (|i| |x| |$|) (|*| |i| |x|))
+
+(PUT (QUOTE |DFLOAT;max;3$;26|) (QUOTE |SPADreplace|) (QUOTE MAX))
+
+(DEFUN |DFLOAT;max;3$;26| (|x| |y| |$|) (MAX |x| |y|))
+
+(PUT (QUOTE |DFLOAT;min;3$;27|) (QUOTE |SPADreplace|) (QUOTE MIN))
+
+(DEFUN |DFLOAT;min;3$;27| (|x| |y| |$|) (MIN |x| |y|))
+
+(PUT (QUOTE |DFLOAT;=;2$B;28|) (QUOTE |SPADreplace|) (QUOTE |=|))
+
+(DEFUN |DFLOAT;=;2$B;28| (|x| |y| |$|) (|=| |x| |y|))
+
+(PUT (QUOTE |DFLOAT;/;$I$;29|) (QUOTE |SPADreplace|) (QUOTE |/|))
+
+(DEFUN |DFLOAT;/;$I$;29| (|x| |i| |$|) (|/| |x| |i|))
+
+(DEFUN |DFLOAT;sqrt;2$;30| (|x| |$|) (|DFLOAT;checkComplex| (SQRT |x|) |$|))
+
+(DEFUN |DFLOAT;log10;2$;31| (|x| |$|) (|DFLOAT;checkComplex| (|log| |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;**;$I$;32|) (QUOTE |SPADreplace|) (QUOTE EXPT))
+
+(DEFUN |DFLOAT;**;$I$;32| (|x| |i| |$|) (EXPT |x| |i|))
+
+(DEFUN |DFLOAT;**;3$;33| (|x| |y| |$|) (|DFLOAT;checkComplex| (EXPT |x| |y|) |$|))
+
+(PUT (QUOTE |DFLOAT;coerce;I$;34|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|i|) (FLOAT |i| |MOST-POSITIVE-LONG-FLOAT|))))
+
+(DEFUN |DFLOAT;coerce;I$;34| (|i| |$|) (FLOAT |i| |MOST-POSITIVE-LONG-FLOAT|))
+
+(PUT (QUOTE |DFLOAT;exp;2$;35|) (QUOTE |SPADreplace|) (QUOTE EXP))
+
+(DEFUN |DFLOAT;exp;2$;35| (|x| |$|) (EXP |x|))
+
+(DEFUN |DFLOAT;log;2$;36| (|x| |$|) (|DFLOAT;checkComplex| (LN |x|) |$|))
+
+(DEFUN |DFLOAT;log2;2$;37| (|x| |$|) (|DFLOAT;checkComplex| (LOG2 |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;sin;2$;38|) (QUOTE |SPADreplace|) (QUOTE SIN))
+
+(DEFUN |DFLOAT;sin;2$;38| (|x| |$|) (SIN |x|))
+
+(PUT (QUOTE |DFLOAT;cos;2$;39|) (QUOTE |SPADreplace|) (QUOTE COS))
+
+(DEFUN |DFLOAT;cos;2$;39| (|x| |$|) (COS |x|))
+
+(PUT (QUOTE |DFLOAT;tan;2$;40|) (QUOTE |SPADreplace|) (QUOTE TAN))
+
+(DEFUN |DFLOAT;tan;2$;40| (|x| |$|) (TAN |x|))
+
+(PUT (QUOTE |DFLOAT;cot;2$;41|) (QUOTE |SPADreplace|) (QUOTE COT))
+
+(DEFUN |DFLOAT;cot;2$;41| (|x| |$|) (COT |x|))
+
+(PUT (QUOTE |DFLOAT;sec;2$;42|) (QUOTE |SPADreplace|) (QUOTE SEC))
+
+(DEFUN |DFLOAT;sec;2$;42| (|x| |$|) (SEC |x|))
+
+(PUT (QUOTE |DFLOAT;csc;2$;43|) (QUOTE |SPADreplace|) (QUOTE CSC))
+
+(DEFUN |DFLOAT;csc;2$;43| (|x| |$|) (CSC |x|))
+
+(DEFUN |DFLOAT;asin;2$;44| (|x| |$|) (|DFLOAT;checkComplex| (ASIN |x|) |$|))
+
+(DEFUN |DFLOAT;acos;2$;45| (|x| |$|) (|DFLOAT;checkComplex| (ACOS |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;atan;2$;46|) (QUOTE |SPADreplace|) (QUOTE ATAN))
+
+(DEFUN |DFLOAT;atan;2$;46| (|x| |$|) (ATAN |x|))
+
+(DEFUN |DFLOAT;acsc;2$;47| (|x| |$|) (|DFLOAT;checkComplex| (ACSC |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;acot;2$;48|) (QUOTE |SPADreplace|) (QUOTE ACOT))
+
+(DEFUN |DFLOAT;acot;2$;48| (|x| |$|) (ACOT |x|))
+
+(DEFUN |DFLOAT;asec;2$;49| (|x| |$|) (|DFLOAT;checkComplex| (ASEC |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;sinh;2$;50|) (QUOTE |SPADreplace|) (QUOTE SINH))
+
+(DEFUN |DFLOAT;sinh;2$;50| (|x| |$|) (SINH |x|))
+
+(PUT (QUOTE |DFLOAT;cosh;2$;51|) (QUOTE |SPADreplace|) (QUOTE COSH))
+
+(DEFUN |DFLOAT;cosh;2$;51| (|x| |$|) (COSH |x|))
+
+(PUT (QUOTE |DFLOAT;tanh;2$;52|) (QUOTE |SPADreplace|) (QUOTE TANH))
+
+(DEFUN |DFLOAT;tanh;2$;52| (|x| |$|) (TANH |x|))
+
+(PUT (QUOTE |DFLOAT;csch;2$;53|) (QUOTE |SPADreplace|) (QUOTE CSCH))
+
+(DEFUN |DFLOAT;csch;2$;53| (|x| |$|) (CSCH |x|))
+
+(PUT (QUOTE |DFLOAT;coth;2$;54|) (QUOTE |SPADreplace|) (QUOTE COTH))
+
+(DEFUN |DFLOAT;coth;2$;54| (|x| |$|) (COTH |x|))
+
+(PUT (QUOTE |DFLOAT;sech;2$;55|) (QUOTE |SPADreplace|) (QUOTE SECH))
+
+(DEFUN |DFLOAT;sech;2$;55| (|x| |$|) (SECH |x|))
+
+(PUT (QUOTE |DFLOAT;asinh;2$;56|) (QUOTE |SPADreplace|) (QUOTE ASINH))
+
+(DEFUN |DFLOAT;asinh;2$;56| (|x| |$|) (ASINH |x|))
+
+(DEFUN |DFLOAT;acosh;2$;57| (|x| |$|) (|DFLOAT;checkComplex| (ACOSH |x|) |$|))
+
+(DEFUN |DFLOAT;atanh;2$;58| (|x| |$|) (|DFLOAT;checkComplex| (ATANH |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;acsch;2$;59|) (QUOTE |SPADreplace|) (QUOTE ACSCH))
+
+(DEFUN |DFLOAT;acsch;2$;59| (|x| |$|) (ACSCH |x|))
+
+(DEFUN |DFLOAT;acoth;2$;60| (|x| |$|) (|DFLOAT;checkComplex| (ACOTH |x|) |$|))
+
+(DEFUN |DFLOAT;asech;2$;61| (|x| |$|) (|DFLOAT;checkComplex| (ASECH |x|) |$|))
+
+(PUT (QUOTE |DFLOAT;/;3$;62|) (QUOTE |SPADreplace|) (QUOTE |/|))
+
+(DEFUN |DFLOAT;/;3$;62| (|x| |y| |$|) (|/| |x| |y|))
+
+(PUT (QUOTE |DFLOAT;negative?;$B;63|) (QUOTE |SPADreplace|) (QUOTE MINUSP))
+
+(DEFUN |DFLOAT;negative?;$B;63| (|x| |$|) (MINUSP |x|))
+
+(PUT (QUOTE |DFLOAT;zero?;$B;64|) (QUOTE |SPADreplace|) (QUOTE ZEROP))
+
+(DEFUN |DFLOAT;zero?;$B;64| (|x| |$|) (ZEROP |x|))
+
+(PUT (QUOTE |DFLOAT;hash;$I;65|) (QUOTE |SPADreplace|) (QUOTE HASHEQ))
+
+(DEFUN |DFLOAT;hash;$I;65| (|x| |$|) (HASHEQ |x|))
+
+(DEFUN |DFLOAT;recip;$U;66| (|x| |$|) (COND ((ZEROP |x|) (CONS 1 "failed")) ((QUOTE T) (CONS 0 (|/| 1.0 |x|)))))
+
+(PUT (QUOTE |DFLOAT;differentiate;2$;67|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) 0.0)))
+
+(DEFUN |DFLOAT;differentiate;2$;67| (|x| |$|) 0.0)
+
+(DEFUN |DFLOAT;Gamma;2$;68| (|x| |$|) (SPADCALL |x| (QREFELT |$| 93)))
+
+(DEFUN |DFLOAT;Beta;3$;69| (|x| |y| |$|) (SPADCALL |x| |y| (QREFELT |$| 95)))
+
+(PUT (QUOTE |DFLOAT;wholePart;$I;70|) (QUOTE |SPADreplace|) (QUOTE FIX))
+
+(DEFUN |DFLOAT;wholePart;$I;70| (|x| |$|) (FIX |x|))
+
+(DEFUN |DFLOAT;float;2IPi$;71| (|ma| |ex| |b| |$|) (|*| |ma| (EXPT (FLOAT |b| |MOST-POSITIVE-LONG-FLOAT|) |ex|)))
+
+(PUT (QUOTE |DFLOAT;convert;2$;72|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) |x|)))
+
+(DEFUN |DFLOAT;convert;2$;72| (|x| |$|) |x|)
+
+(DEFUN |DFLOAT;convert;$F;73| (|x| |$|) (SPADCALL |x| (QREFELT |$| 101)))
+
+(DEFUN |DFLOAT;rationalApproximation;$NniF;74| (|x| |d| |$|) (SPADCALL |x| |d| 10 (QREFELT |$| 105)))
+
+(DEFUN |DFLOAT;atan;3$;75| (|x| |y| |$|) (PROG (|theta|) (RETURN (SEQ (COND ((|=| |x| 0.0) (COND ((|<| 0.0 |y|) (|/| PI 2)) ((|<| |y| 0.0) (|-| (|/| PI 2))) ((QUOTE T) 0.0))) ((QUOTE T) (SEQ (LETT |theta| (ATAN (|FLOAT-SIGN| 1.0 (|/| |y| |x|))) |DFLOAT;atan;3$;75|) (COND ((|<| |x| 0.0) (LETT |theta| (|-| PI |theta|) |DFLOAT;atan;3$;75|))) (COND ((|<| |y| 0.0) (LETT |theta| (|-| |theta|) |DFLOAT;atan;3$;75|))) (EXIT |theta|))))))))
+
+(DEFUN |DFLOAT;retract;$F;76| (|x| |$|) (PROG (#1=#:G105780) (RETURN (SPADCALL |x| (PROG1 (LETT #1# (|-| (|FLOAT-DIGITS| 0.0) 1) |DFLOAT;retract;$F;76|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (|FLOAT-RADIX| 0.0) (QREFELT |$| 105)))))
+
+(DEFUN |DFLOAT;retractIfCan;$U;77| (|x| |$|) (PROG (#1=#:G105785) (RETURN (CONS 0 (SPADCALL |x| (PROG1 (LETT #1# (|-| (|FLOAT-DIGITS| 0.0) 1) |DFLOAT;retractIfCan;$U;77|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (|FLOAT-RADIX| 0.0) (QREFELT |$| 105))))))
+
+(DEFUN |DFLOAT;retract;$I;78| (|x| |$|) (PROG (|n|) (RETURN (SEQ (LETT |n| (FIX |x|) |DFLOAT;retract;$I;78|) (EXIT (COND ((|=| |x| (FLOAT |n| |MOST-POSITIVE-LONG-FLOAT|)) |n|) ((QUOTE T) (|error| "Not an integer"))))))))
+
+(DEFUN |DFLOAT;retractIfCan;$U;79| (|x| |$|) (PROG (|n|) (RETURN (SEQ (LETT |n| (FIX |x|) |DFLOAT;retractIfCan;$U;79|) (EXIT (COND ((|=| |x| (FLOAT |n| |MOST-POSITIVE-LONG-FLOAT|)) (CONS 0 |n|)) ((QUOTE T) (CONS 1 "failed"))))))))
+
+(DEFUN |DFLOAT;sign;$I;80| (|x| |$|) (SPADCALL (|FLOAT-SIGN| |x| 1.0) (QREFELT |$| 111)))
+
+(PUT (QUOTE |DFLOAT;abs;2$;81|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x|) (|FLOAT-SIGN| 1.0 |x|))))
+
+(DEFUN |DFLOAT;abs;2$;81| (|x| |$|) (|FLOAT-SIGN| 1.0 |x|))
+
+(DEFUN |DFLOAT;manexp| (|x| |$|) (PROG (|s| #1=#:G105806 |me| |two53|) (RETURN (SEQ (EXIT (COND ((ZEROP |x|) (CONS 0 0)) ((QUOTE T) (SEQ (LETT |s| (SPADCALL |x| (QREFELT |$| 114)) |DFLOAT;manexp|) (LETT |x| (|FLOAT-SIGN| 1.0 |x|) |DFLOAT;manexp|) (COND ((|<| |MOST-POSITIVE-LONG-FLOAT| |x|) (PROGN (LETT #1# (CONS (|+| (|*| |s| (SPADCALL |MOST-POSITIVE-LONG-FLOAT| (QREFELT |$| 25))) 1) (SPADCALL |MOST-POSITIVE-LONG-FLOAT| (QREFELT |$| 26))) |DFLOAT;manexp|) (GO #1#)))) (LETT |me| (MANEXP |x|) |DFLOAT;manexp|) (LETT |two53| (EXPT (|FLOAT-RADIX| 0.0) (|FLOAT-DIGITS| 0.0)) |DFLOAT;manexp|) (EXIT (CONS (|*| |s| (FIX (|*| |two53| (QCAR |me|)))) (|-| (QCDR |me|) (|FLOAT-DIGITS| 0.0)))))))) #1# (EXIT #1#)))))
+
+(DEFUN |DFLOAT;rationalApproximation;$2NniF;83| (|f| |d| |b| |$|) (PROG (|#G102| |nu| |ex| BASE #1=#:G105809 |de| |tol| |#G103| |q| |r| |p2| |q2| #2=#:G105827 |#G104| |#G105| |p0| |p1| |#G106| |#G107| |q0| |q1| |#G108| |#G109| |s| |t| #3=#:G105825) (RETURN (SEQ (EXIT (SEQ (PROGN (LETT |#G102| (|DFLOAT;manexp| |f| |$|) |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |nu| (QCAR |#G102|) |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |ex| (QCDR |#G102|) |DFLOAT;rationalApproximation;$2NniF;83|) |#G102|) (LETT BASE (|FLOAT-RADIX| 0.0) |DFLOAT;rationalApproximation;$2NniF;83|) (EXIT (COND ((|<| |ex| 0) (SEQ (LETT |de| (EXPT BASE (PROG1 (LETT #1# (|-| |ex|) |DFLOAT;rationalApproximation;$2NniF;83|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#))) |DFLOAT;rationalApproximation;$2NniF;83|) (EXIT (COND ((|<| |b| 2) (|error| "base must be > 1")) ((QUOTE T) (SEQ (LETT |tol| (EXPT |b| |d|) |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |s| |nu| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |t| |de| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |p0| 0 |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |p1| 1 |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |q0| 1 |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |q1| 0 |DFLOAT;rationalApproximation;$2NniF;83|) (EXIT (SEQ G190 NIL (SEQ (PROGN (LETT |#G103| (DIVIDE2 |s| |t|) |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |q| (QCAR |#G103|) |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |r| (QCDR |#G103|) |DFLOAT;rationalApproximation;$2NniF;83|) |#G103|) (LETT |p2| (|+| (|*| |q| |p1|) |p0|) |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |q2| (|+| (|*| |q| |q1|) |q0|) |DFLOAT;rationalApproximation;$2NniF;83|) (COND ((OR (EQL |r| 0) (|<| (SPADCALL |tol| (ABS (|-| (|*| |nu| |q2|) (|*| |de| |p2|))) (QREFELT |$| 118)) (|*| |de| (ABS |p2|)))) (EXIT (PROGN (LETT #2# (SPADCALL |p2| |q2| (QREFELT |$| 117)) |DFLOAT;rationalApproximation;$2NniF;83|) (GO #2#))))) (PROGN (LETT |#G104| |p1| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |#G105| |p2| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |p0| |#G104| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |p1| |#G105| |DFLOAT;rationalApproximation;$2NniF;83|)) (PROGN (LETT |#G106| |q1| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |#G107| |q2| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |q0| |#G106| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |q1| |#G107| |DFLOAT;rationalApproximation;$2NniF;83|)) (EXIT (PROGN (LETT |#G108| |t| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |#G109| |r| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |s| |#G108| |DFLOAT;rationalApproximation;$2NniF;83|) (LETT |t| |#G109| |DFLOAT;rationalApproximation;$2NniF;83|)))) NIL (GO G190) G191 (EXIT NIL))))))))) ((QUOTE T) (SPADCALL (|*| |nu| (EXPT BASE (PROG1 (LETT #3# |ex| |DFLOAT;rationalApproximation;$2NniF;83|) (|check-subtype| (|>=| #3# 0) (QUOTE (|NonNegativeInteger|)) #3#)))) (QREFELT |$| 119))))))) #2# (EXIT #2#)))))
+
+(DEFUN |DFLOAT;**;$F$;84| (|x| |r| |$|) (PROG (|n| |d| #1=#:G105837) (RETURN (SEQ (EXIT (COND ((ZEROP |x|) (COND ((SPADCALL |r| (QREFELT |$| 120)) (|error| "0**0 is undefined")) ((SPADCALL |r| (QREFELT |$| 121)) (|error| "division by 0")) ((QUOTE T) 0.0))) ((OR (SPADCALL |r| (QREFELT |$| 120)) (SPADCALL |x| (QREFELT |$| 122))) 1.0) ((QUOTE T) (COND ((SPADCALL |r| (QREFELT |$| 123)) |x|) ((QUOTE T) (SEQ (LETT |n| (SPADCALL |r| (QREFELT |$| 124)) |DFLOAT;**;$F$;84|) (LETT |d| (SPADCALL |r| (QREFELT |$| 125)) |DFLOAT;**;$F$;84|) (EXIT (COND ((MINUSP |x|) (COND ((ODDP |d|) (COND ((ODDP |n|) (PROGN (LETT #1# (|-| (SPADCALL (|-| |x|) |r| (QREFELT |$| 126))) |DFLOAT;**;$F$;84|) (GO #1#))) ((QUOTE T) (PROGN (LETT #1# (SPADCALL (|-| |x|) |r| (QREFELT |$| 126)) |DFLOAT;**;$F$;84|) (GO #1#))))) ((QUOTE T) (|error| "negative root")))) ((EQL |d| 2) (EXPT (SPADCALL |x| (QREFELT |$| 54)) |n|)) ((QUOTE T) (SPADCALL |x| (|/| (FLOAT |n| |MOST-POSITIVE-LONG-FLOAT|) (FLOAT |d| |MOST-POSITIVE-LONG-FLOAT|)) (QREFELT |$| 57))))))))))) #1# (EXIT #1#)))))
+
+(DEFUN |DoubleFloat| NIL (PROG NIL (RETURN (PROG (#1=#:G105850) (RETURN (COND ((LETT #1# (HGET |$ConstructorCache| (QUOTE |DoubleFloat|)) |DoubleFloat|) (|CDRwithIncrement| (CDAR #1#))) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (CDDAR (HPUT |$ConstructorCache| (QUOTE |DoubleFloat|) (LIST (CONS NIL (CONS 1 (|DoubleFloat;|)))))) (LETT #1# T |DoubleFloat|)) (COND ((NOT #1#) (HREM |$ConstructorCache| (QUOTE |DoubleFloat|))))))))))))
+
+(DEFUN |DoubleFloat;| NIL (PROG (|dv$| |$| |pv$|) (RETURN (PROGN (LETT |dv$| (QUOTE (|DoubleFloat|)) . #1=(|DoubleFloat|)) (LETT |$| (GETREFV 140) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|haddProp| |$ConstructorCache| (QUOTE |DoubleFloat|) NIL (CONS 1 |$|)) (|stuffDomainSlots| |$|) |$|))))
+
+(MAKEPROP (QUOTE |DoubleFloat|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|OpenMathEncoding|) (0 . |OMencodingXML|) (|String|) (|OpenMathDevice|) (4 . |OMopenString|) (|Void|) (10 . |OMputObject|) (|DoubleFloat|) (15 . |OMputFloat|) (21 . |OMputEndObject|) (26 . |OMclose|) |DFLOAT;OMwrite;$S;1| (|Boolean|) |DFLOAT;OMwrite;$BS;2| |DFLOAT;OMwrite;Omd$V;3| |DFLOAT;OMwrite;Omd$BV;4| (|PositiveInteger|) |DFLOAT;base;Pi;6| (|Integer|) |DFLOAT;mantissa;$I;7| |DFLOAT;exponent;$I;8| |DFLOAT;precision;Pi;9| |DFLOAT;log2;2$;37| (31 . |*|) |DFLOAT;bits;Pi;10| |DFLOAT;max;$;11| |DFLOAT;min;$;12| |DFLOAT;order;$I;13| (CONS IDENTITY (FUNCALL (|dispatchFunction| |DFLOAT;Zero;$;14|) |$|)) (CONS IDENTITY (FUNCALL (|dispatchFunction| |DFLOAT;One;$;15|) |$|)) |DFLOAT;exp1;$;16| |DFLOAT;pi;$;17| (|OutputForm|) (37 . |outputForm|) |DFLOAT;coerce;$Of;18| (|InputForm|) (42 . |convert|) |DFLOAT;convert;$If;19| |DFLOAT;<;2$B;20| |DFLOAT;-;2$;21| |DFLOAT;+;3$;22| |DFLOAT;-;3$;23| |DFLOAT;*;3$;24| |DFLOAT;*;I2$;25| |DFLOAT;max;3$;26| |DFLOAT;min;3$;27| |DFLOAT;=;2$B;28| |DFLOAT;/;$I$;29| |DFLOAT;sqrt;2$;30| |DFLOAT;log10;2$;31| |DFLOAT;**;$I$;32| |DFLOAT;**;3$;33| |DFLOAT;coerce;I$;34| |DFLOAT;exp;2$;35| |DFLOAT;log;2$;36| |DFLOAT;sin;2$;38| |DFLOAT;cos;2$;39| |DFLOAT;tan;2$;40| |DFLOAT;cot;2$;41| |DFLOAT;sec;2$;42| |DFLOAT;csc;2$;43| |DFLOAT;asin;2$;44| |DFLOAT;acos;2$;45| |DFLOAT;atan;2$;46| |DFLOAT;acsc;2$;47| |DFLOAT;acot;2$;48| |DFLOAT;asec;2$;49| |DFLOAT;sinh;2$;50| |DFLOAT;cosh;2$;51| |DFLOAT;tanh;2$;52| |DFLOAT;csch;2$;53| |DFLOAT;coth;2$;54| |DFLOAT;sech;2$;55| |DFLOAT;asinh;2$;56| |DFLOAT;acosh;2$;57| |DFLOAT;atanh;2$;58| |DFLOAT;acsch;2$;59| |DFLOAT;acoth;2$;60| |DFLOAT;asech;2$;61| |DFLOAT;/;3$;62| |DFLOAT;negative?;$B;63| |DFLOAT;zero?;$B;64| |DFLOAT;hash;$I;65| (|Union| |$| (QUOTE "failed")) |DFLOAT;recip;$U;66| |DFLOAT;differentiate;2$;67| (|DoubleFloatSpecialFunctions|) (47 . |Gamma|) |DFLOAT;Gamma;2$;68| (52 . |Beta|) |DFLOAT;Beta;3$;69| |DFLOAT;wholePart;$I;70| |DFLOAT;float;2IPi$;71| |DFLOAT;convert;2$;72| (|Float|) (58 . |convert|) |DFLOAT;convert;$F;73| (|Fraction| 24) (|NonNegativeInteger|) |DFLOAT;rationalApproximation;$2NniF;83| |DFLOAT;rationalApproximation;$NniF;74| |DFLOAT;atan;3$;75| |DFLOAT;retract;$F;76| (|Union| 103 (QUOTE "failed")) |DFLOAT;retractIfCan;$U;77| |DFLOAT;retract;$I;78| (|Union| 24 (QUOTE "failed")) |DFLOAT;retractIfCan;$U;79| |DFLOAT;sign;$I;80| |DFLOAT;abs;2$;81| (63 . |Zero|) (67 . |/|) (73 . |*|) (79 . |coerce|) (84 . |zero?|) (89 . |negative?|) (94 . |one?|) (99 . |one?|) (104 . |numer|) (109 . |denom|) |DFLOAT;**;$F$;84| (|Pattern| 100) (|PatternMatchResult| 100 |$|) (|Factored| |$|) (|Union| 131 (QUOTE "failed")) (|List| |$|) (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|) (|:| |generator| |$|)) (|Record| (|:| |coef1| |$|) (|:| |coef2| |$|)) (|Union| 133 (QUOTE "failed")) (|Record| (|:| |quotient| |$|) (|:| |remainder| |$|)) (|Record| (|:| |coef| 131) (|:| |generator| |$|)) (|SparseUnivariatePolynomial| |$|) (|Record| (|:| |unit| |$|) (|:| |canonical| |$|) (|:| |associate| |$|)) (|SingleInteger|))) (QUOTE #(|~=| 114 |zero?| 120 |wholePart| 125 |unitNormal| 130 |unitCanonical| 135 |unit?| 140 |truncate| 145 |tanh| 150 |tan| 155 |subtractIfCan| 160 |squareFreePart| 166 |squareFree| 171 |sqrt| 176 |sizeLess?| 181 |sinh| 187 |sin| 192 |sign| 197 |sech| 202 |sec| 207 |sample| 212 |round| 216 |retractIfCan| 221 |retract| 231 |rem| 241 |recip| 247 |rationalApproximation| 252 |quo| 265 |principalIdeal| 271 |prime?| 276 |precision| 281 |positive?| 285 |pi| 290 |patternMatch| 294 |order| 301 |one?| 306 |nthRoot| 311 |norm| 317 |negative?| 322 |multiEuclidean| 327 |min| 333 |max| 343 |mantissa| 353 |log2| 358 |log10| 363 |log| 368 |lcm| 373 |latex| 384 |inv| 389 |hash| 394 |gcdPolynomial| 404 |gcd| 410 |fractionPart| 421 |floor| 426 |float| 431 |factor| 444 |extendedEuclidean| 449 |exquo| 462 |expressIdealMember| 468 |exponent| 474 |exp1| 479 |exp| 483 |euclideanSize| 488 |divide| 493 |digits| 499 |differentiate| 503 |csch| 514 |csc| 519 |coth| 524 |cot| 529 |cosh| 534 |cos| 539 |convert| 544 |coerce| 564 |characteristic| 594 |ceiling| 598 |bits| 603 |base| 607 |atanh| 611 |atan| 616 |associates?| 627 |asinh| 633 |asin| 638 |asech| 643 |asec| 648 |acsch| 653 |acsc| 658 |acoth| 663 |acot| 668 |acosh| 673 |acos| 678 |abs| 683 |^| 688 |Zero| 706 |One| 710 |OMwrite| 714 |Gamma| 738 D 743 |Beta| 754 |>=| 760 |>| 766 |=| 772 |<=| 778 |<| 784 |/| 790 |-| 802 |+| 813 |**| 819 |*| 849)) (QUOTE ((|approximate| . 0) (|canonicalsClosed| . 0) (|canonicalUnitNormal| . 0) (|noZeroDivisors| . 0) ((|commutative| "*") . 0) (|rightUnitary| . 0) (|leftUnitary| . 0) (|unitsKnown| . 0))) (CONS (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))) (CONS (QUOTE #(|FloatingPointSystem&| |RealNumberSystem&| |Field&| |EuclideanDomain&| NIL |UniqueFactorizationDomain&| |GcdDomain&| |DivisionRing&| |IntegralDomain&| |Algebra&| |Algebra&| |DifferentialRing&| NIL |OrderedRing&| |Module&| NIL NIL |Module&| NIL NIL NIL |Ring&| NIL NIL NIL NIL NIL NIL NIL |AbelianGroup&| NIL NIL |AbelianMonoid&| |Monoid&| NIL |OrderedSet&| |AbelianSemiGroup&| |SemiGroup&| |TranscendentalFunctionCategory&| NIL |SetCategory&| NIL |ElementaryFunctionCategory&| NIL |HyperbolicFunctionCategory&| |ArcTrigonometricFunctionCategory&| |TrigonometricFunctionCategory&| NIL NIL |RadicalCategory&| |RetractableTo&| |RetractableTo&| NIL NIL |BasicType&| NIL)) (CONS (QUOTE #((|FloatingPointSystem|) (|RealNumberSystem|) (|Field|) (|EuclideanDomain|) (|PrincipalIdealDomain|) (|UniqueFactorizationDomain|) (|GcdDomain|) (|DivisionRing|) (|IntegralDomain|) (|Algebra| 103) (|Algebra| |$$|) (|DifferentialRing|) (|CharacteristicZero|) (|OrderedRing|) (|Module| 103) (|EntireRing|) (|CommutativeRing|) (|Module| |$$|) (|OrderedAbelianGroup|) (|BiModule| 103 103) (|BiModule| |$$| |$$|) (|Ring|) (|OrderedCancellationAbelianMonoid|) (|RightModule| 103) (|LeftModule| 103) (|LeftModule| |$$|) (|Rng|) (|RightModule| |$$|) (|OrderedAbelianMonoid|) (|AbelianGroup|) (|OrderedAbelianSemiGroup|) (|CancellationAbelianMonoid|) (|AbelianMonoid|) (|Monoid|) (|PatternMatchable| 100) (|OrderedSet|) (|AbelianSemiGroup|) (|SemiGroup|) (|TranscendentalFunctionCategory|) (|RealConstant|) (|SetCategory|) (|ConvertibleTo| 41) (|ElementaryFunctionCategory|) (|ArcHyperbolicFunctionCategory|) (|HyperbolicFunctionCategory|) (|ArcTrigonometricFunctionCategory|) (|TrigonometricFunctionCategory|) (|OpenMath|) (|ConvertibleTo| 127) (|RadicalCategory|) (|RetractableTo| 103) (|RetractableTo| 24) (|ConvertibleTo| 100) (|ConvertibleTo| 13) (|BasicType|) (|CoercibleTo| 38))) (|makeByteWordVec2| 139 (QUOTE (0 6 0 7 2 9 0 8 6 10 1 9 11 0 12 2 9 11 0 13 14 1 9 11 0 15 1 9 11 0 16 2 0 0 22 0 29 1 38 0 13 39 1 41 0 13 42 1 92 13 13 93 2 92 13 13 13 95 1 100 0 13 101 0 103 0 116 2 103 0 24 24 117 2 24 0 104 0 118 1 103 0 24 119 1 103 18 0 120 1 103 18 0 121 1 0 18 0 122 1 103 18 0 123 1 103 24 0 124 1 103 24 0 125 2 0 18 0 0 1 1 0 18 0 87 1 0 24 0 97 1 0 138 0 1 1 0 0 0 1 1 0 18 0 1 1 0 0 0 1 1 0 0 0 75 1 0 0 0 63 2 0 89 0 0 1 1 0 0 0 1 1 0 129 0 1 1 0 0 0 54 2 0 18 0 0 1 1 0 0 0 73 1 0 0 0 61 1 0 24 0 114 1 0 0 0 78 1 0 0 0 65 0 0 0 1 1 0 0 0 1 1 0 109 0 110 1 0 112 0 113 1 0 103 0 108 1 0 24 0 111 2 0 0 0 0 1 1 0 89 0 90 2 0 103 0 104 106 3 0 103 0 104 104 105 2 0 0 0 0 1 1 0 136 131 1 1 0 18 0 1 0 0 22 27 1 0 18 0 1 0 0 0 37 3 0 128 0 127 128 1 1 0 24 0 33 1 0 18 0 122 2 0 0 0 24 1 1 0 0 0 1 1 0 18 0 86 2 0 130 131 0 1 0 0 0 32 2 0 0 0 0 51 0 0 0 31 2 0 0 0 0 50 1 0 24 0 25 1 0 0 0 28 1 0 0 0 55 1 0 0 0 60 1 0 0 131 1 2 0 0 0 0 1 1 0 8 0 1 1 0 0 0 1 1 0 24 0 88 1 0 139 0 1 2 0 137 137 137 1 1 0 0 131 1 2 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 3 0 0 24 24 22 98 2 0 0 24 24 1 1 0 129 0 1 2 0 132 0 0 1 3 0 134 0 0 0 1 2 0 89 0 0 1 2 0 130 131 0 1 1 0 24 0 26 0 0 0 36 1 0 0 0 59 1 0 104 0 1 2 0 135 0 0 1 0 0 22 1 1 0 0 0 91 2 0 0 0 104 1 1 0 0 0 76 1 0 0 0 66 1 0 0 0 77 1 0 0 0 64 1 0 0 0 74 1 0 0 0 62 1 0 41 0 43 1 0 127 0 1 1 0 13 0 99 1 0 100 0 102 1 0 0 103 1 1 0 0 24 58 1 0 0 103 1 1 0 0 24 58 1 0 0 0 1 1 0 38 0 40 0 0 104 1 1 0 0 0 1 0 0 22 30 0 0 22 23 1 0 0 0 81 2 0 0 0 0 107 1 0 0 0 69 2 0 18 0 0 1 1 0 0 0 79 1 0 0 0 67 1 0 0 0 84 1 0 0 0 72 1 0 0 0 82 1 0 0 0 70 1 0 0 0 83 1 0 0 0 71 1 0 0 0 80 1 0 0 0 68 1 0 0 0 115 2 0 0 0 24 1 2 0 0 0 104 1 2 0 0 0 22 1 0 0 0 34 0 0 0 35 2 0 11 9 0 20 3 0 11 9 0 18 21 1 0 8 0 17 2 0 8 0 18 19 1 0 0 0 94 1 0 0 0 1 2 0 0 0 104 1 2 0 0 0 0 96 2 0 18 0 0 1 2 0 18 0 0 1 2 0 18 0 0 52 2 0 18 0 0 1 2 0 18 0 0 44 2 0 0 0 24 53 2 0 0 0 0 85 2 0 0 0 0 47 1 0 0 0 45 2 0 0 0 0 46 2 0 0 0 0 57 2 0 0 0 103 126 2 0 0 0 24 56 2 0 0 0 104 1 2 0 0 0 22 1 2 0 0 0 103 1 2 0 0 103 0 1 2 0 0 0 0 48 2 0 0 24 0 49 2 0 0 104 0 1 2 0 0 22 0 29)))))) (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |DoubleFloat|) (QUOTE NILADIC) T)
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category REAL RealConstant>>
+<<category RADCAT RadicalCategory>>
+<<category RNS RealNumberSystem>>
+<<category FPS FloatingPointSystem>>
+<<domain DFLOAT DoubleFloat>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} Steele, Guy L. Jr. ``Common Lisp The Language''
+Second Edition 1990 ISBN 1-55558-041-6 Digital Press
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sgcf.spad.pamphlet b/src/algebra/sgcf.spad.pamphlet
new file mode 100644
index 00000000..b2740766
--- /dev/null
+++ b/src/algebra/sgcf.spad.pamphlet
@@ -0,0 +1,526 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sgcf.spad}
+\author{Johannes Grabmeier, Thorsten Werther}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SGCF SymmetricGroupCombinatoricFunctions}
+<<package SGCF SymmetricGroupCombinatoricFunctions>>=
+)abbrev package SGCF SymmetricGroupCombinatoricFunctions
+++ Authors: Johannes Grabmeier, Thorsten Werther
+++ Date Created: 03 September 1988
+++ Date Last Updated: 07 June 1990
+++ Basic Operations: nextPartition, numberOfImproperPartitions,
+++ listYoungTableaus, subSet, unrankImproperPartitions0
+++ Related Constructors: IntegerCombinatoricFunctions
+++ Also See: RepresentationTheoryPackage1, RepresentationTheoryPackage2,
+++ IrrRepSymNatPackage
+++ AMS Classifications:
+++ Keywords: improper partition, partition, subset, Coleman
+++ References:
+++ G. James/ A. Kerber: The Representation Theory of the Symmetric
+++ Group. Encycl. of Math. and its Appl., Vol. 16., Cambridge
+++ Univ. Press 1981, ISBN 0-521-30236-6.
+++ S.G. Williamson: Combinatorics for Computer Science,
+++ Computer Science Press, Rockville, Maryland, USA, ISBN 0-88175-020-4.
+++ A. Nijenhuis / H.S. Wilf: Combinatoral Algorithms, Academic Press 1978.
+++ ISBN 0-12-519260-6.
+++ H. Gollan, J. Grabmeier: Algorithms in Representation Theory and
+++ their Realization in the Computer Algebra System Scratchpad,
+++ Bayreuther Mathematische Schriften, Heft 33, 1990, 1-23.
+++ Description:
+++ SymmetricGroupCombinatoricFunctions contains combinatoric
+++ functions concerning symmetric groups and representation
+++ theory: list young tableaus, improper partitions, subsets
+++ bijection of Coleman.
+
+SymmetricGroupCombinatoricFunctions(): public == private where
+
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ L ==> List
+ M ==> Matrix
+ V ==> Vector
+ B ==> Boolean
+ ICF ==> IntegerCombinatoricFunctions Integer
+
+ public ==> with
+
+-- IS THERE A WORKING DOMAIN Tableau ??
+-- coerce : M I -> Tableau(I)
+-- ++ coerce(ytab) coerces the Young-Tableau ytab to an element of
+-- ++ the domain Tableau(I).
+
+ coleman : (L I, L I, L I) -> M I
+ ++ coleman(alpha,beta,pi):
+ ++ there is a bijection from the set of matrices having nonnegative
+ ++ entries and row sums {\em alpha}, column sums {\em beta}
+ ++ to the set of {\em Salpha - Sbeta} double cosets of the
+ ++ symmetric group {\em Sn}. ({\em Salpha} is the Young subgroup
+ ++ corresponding to the improper partition {\em alpha}).
+ ++ For a representing element {\em pi} of such a double coset,
+ ++ coleman(alpha,beta,pi) generates the Coleman-matrix
+ ++ corresponding to {\em alpha, beta, pi}.
+ ++ Note: The permutation {\em pi} of {\em {1,2,...,n}} has to be given
+ ++ in list form.
+ ++ Note: the inverse of this map is {\em inverseColeman}
+ ++ (if {\em pi} is the lexicographical smallest permutation
+ ++ in the coset). For details see James/Kerber.
+ inverseColeman : (L I, L I, M I) -> L I
+ ++ inverseColeman(alpha,beta,C):
+ ++ there is a bijection from the set of matrices having nonnegative
+ ++ entries and row sums {\em alpha}, column sums {\em beta}
+ ++ to the set of {\em Salpha - Sbeta} double cosets of the
+ ++ symmetric group {\em Sn}. ({\em Salpha} is the Young subgroup
+ ++ corresponding to the improper partition {\em alpha}).
+ ++ For such a matrix C, inverseColeman(alpha,beta,C)
+ ++ calculates the lexicographical smallest {\em pi} in the
+ ++ corresponding double coset.
+ ++ Note: the resulting permutation {\em pi} of {\em {1,2,...,n}}
+ ++ is given in list form.
+ ++ Notes: the inverse of this map is {\em coleman}.
+ ++ For details, see James/Kerber.
+ listYoungTableaus : (L I) -> L M I
+ ++ listYoungTableaus(lambda) where {\em lambda} is a proper partition
+ ++ generates the list of all standard tableaus of shape {\em lambda}
+ ++ by means of lattice permutations. The numbers of the lattice
+ ++ permutation are interpreted as column labels. Hence the
+ ++ contents of these lattice permutations are the conjugate of
+ ++ {\em lambda}.
+ ++ Notes: the functions {\em nextLatticePermutation} and
+ ++ {\em makeYoungTableau} are used.
+ ++ The entries are from {\em 0,...,n-1}.
+ makeYoungTableau : (L I,L I) -> M I
+ ++ makeYoungTableau(lambda,gitter) computes for a given lattice
+ ++ permutation {\em gitter} and for an improper partition {\em lambda}
+ ++ the corresponding standard tableau of shape {\em lambda}.
+ ++ Notes: see {\em listYoungTableaus}.
+ ++ The entries are from {\em 0,...,n-1}.
+ nextColeman : (L I, L I, M I) -> M I
+ ++ nextColeman(alpha,beta,C) generates the next Coleman matrix
+ ++ of column sums {\em alpha} and row sums {\em beta} according
+ ++ to the lexicographical order from bottom-to-top.
+ ++ The first Coleman matrix is achieved by {\em C=new(1,1,0)}.
+ ++ Also, {\em new(1,1,0)} indicates that C is the last Coleman matrix.
+ nextLatticePermutation : (L I, L I, B) -> L I
+ ++ nextLatticePermutation(lambda,lattP,constructNotFirst) generates
+ ++ the lattice permutation according to the proper partition
+ ++ {\em lambda} succeeding the lattice permutation {\em lattP} in
+ ++ lexicographical order as long as {\em constructNotFirst} is true.
+ ++ If {\em constructNotFirst} is false, the first lattice permutation
+ ++ is returned.
+ ++ The result {\em nil} indicates that {\em lattP} has no successor.
+ nextPartition : (V I, V I, I) -> V I
+ ++ nextPartition(gamma,part,number) generates the partition of
+ ++ {\em number} which follows {\em part} according to the right-to-left
+ ++ lexicographical order. The partition has the property that
+ ++ its components do not exceed the corresponding components of
+ ++ {\em gamma}. The first partition is achieved by {\em part=[]}.
+ ++ Also, {\em []} indicates that {\em part} is the last partition.
+ nextPartition : (L I, V I, I) -> V I
+ ++ nextPartition(gamma,part,number) generates the partition of
+ ++ {\em number} which follows {\em part} according to the right-to-left
+ ++ lexicographical order. The partition has the property that
+ ++ its components do not exceed the corresponding components of
+ ++ {\em gamma}. the first partition is achieved by {\em part=[]}.
+ ++ Also, {\em []} indicates that {\em part} is the last partition.
+ numberOfImproperPartitions: (I,I) -> I
+ ++ numberOfImproperPartitions(n,m) computes the number of partitions
+ ++ of the nonnegative integer n in m nonnegative parts with regarding
+ ++ the order (improper partitions).
+ ++ Example: {\em numberOfImproperPartitions (3,3)} is 10,
+ ++ since {\em [0,0,3], [0,1,2], [0,2,1], [0,3,0], [1,0,2], [1,1,1],
+ ++ [1,2,0], [2,0,1], [2,1,0], [3,0,0]} are the possibilities.
+ ++ Note: this operation has a recursive implementation.
+ subSet : (I,I,I) -> L I
+ ++ subSet(n,m,k) calculates the {\em k}-th {\em m}-subset of the set
+ ++ {\em 0,1,...,(n-1)} in the lexicographic order considered as
+ ++ a decreasing map from {\em 0,...,(m-1)} into {\em 0,...,(n-1)}.
+ ++ See S.G. Williamson: Theorem 1.60.
+ ++ Error: if not {\em (0 <= m <= n and 0 < = k < (n choose m))}.
+ unrankImproperPartitions0 : (I,I,I) -> L I
+ ++ unrankImproperPartitions0(n,m,k) computes the {\em k}-th improper
+ ++ partition of nonnegative n in m nonnegative parts in reverse
+ ++ lexicographical order.
+ ++ Example: {\em [0,0,3] < [0,1,2] < [0,2,1] < [0,3,0] <
+ ++ [1,0,2] < [1,1,1] < [1,2,0] < [2,0,1] < [2,1,0] < [3,0,0]}.
+ ++ Error: if k is negative or too big.
+ ++ Note: counting of subtrees is done by
+ ++ \spadfunFrom{numberOfImproperPartitions}{SymmetricGroupCombinatoricFunctions}.
+
+ unrankImproperPartitions1: (I,I,I) -> L I
+ ++ unrankImproperPartitions1(n,m,k) computes the {\em k}-th improper
+ ++ partition of nonnegative n in at most m nonnegative parts
+ ++ ordered as follows: first, in reverse
+ ++ lexicographically according to their non-zero parts, then
+ ++ according to their positions (i.e. lexicographical order
+ ++ using {\em subSet}: {\em [3,0,0] < [0,3,0] < [0,0,3] < [2,1,0] <
+ ++ [2,0,1] < [0,2,1] < [1,2,0] < [1,0,2] < [0,1,2] < [1,1,1]}).
+ ++ Note: counting of subtrees is done by
+ ++ {\em numberOfImproperPartitionsInternal}.
+
+ private == add
+
+ import Set I
+
+ -- declaration of local functions
+
+
+ numberOfImproperPartitionsInternal: (I,I,I) -> I
+ -- this is used as subtree counting function in
+ -- "unrankImproperPartitions1". For (n,m,cm) it counts
+ -- the following set of m-tuples: The first (from left
+ -- to right) m-cm non-zero entries are equal, the remaining
+ -- positions sum up to n. Example: (3,3,2) counts
+ -- [x,3,0], [x,0,3], [0,x,3], [x,2,1], [x,1,2], x non-zero.
+
+
+ -- definition of local functions
+
+
+ numberOfImproperPartitionsInternal(n,m,cm) ==
+ n = 0 => binomial(m,cm)$ICF
+ cm = 0 and n > 0 => 0
+ s := 0
+ for i in 0..n-1 repeat
+ s := s + numberOfImproperPartitionsInternal(i,m,cm-1)
+ s
+
+
+ -- definition of exported functions
+
+ numberOfImproperPartitions(n,m) ==
+ if n < 0 or m < 1 then return 0
+ if m = 1 or n = 0 then return 1
+ s := 0
+ for i in 0..n repeat
+ s := s + numberOfImproperPartitions(n-i,m-1)
+ s
+
+
+ unrankImproperPartitions0(n,m,k) ==
+ l : L I := nil$(L I)
+ k < 0 => error"counting of partitions is started at 0"
+ k >= numberOfImproperPartitions(n,m) =>
+ error"there are not so many partitions"
+ for t in 0..(m-2) repeat
+ s : I := 0
+ for y in 0..n repeat
+ sOld := s
+ s := s + numberOfImproperPartitions(n-y,m-t-1)
+ if s > k then leave
+ l := append(l,list(y)$(L I))$(L I)
+ k := k - sOld
+ n := n - y
+ l := append(l,list(n)$(L I))$(L I)
+ l
+
+
+ unrankImproperPartitions1(n,m,k) ==
+ -- we use the counting procedure of the leaves in a tree
+ -- having the following structure: First of all non-zero
+ -- labels for the sons. If addition along a path gives n,
+ -- then we go on creating the subtree for (n choose cm)
+ -- where cm is the length of the path. These subsets determine
+ -- the positions for the non-zero labels for the partition
+ -- to be formeded. The remaining positions are filled by zeros.
+ nonZeros : L I := nil$(L I)
+ partition : V I := new(m::NNI,0$I)$(V I)
+ k < 0 => nonZeros
+ k >= numberOfImproperPartitions(n,m) => nonZeros
+ cm : I := m --cm gives the depth of the tree
+ while n ^= 0 repeat
+ s : I := 0
+ cm := cm - 1
+ for y in n..1 by -1 repeat --determination of the next son
+ sOld := s -- remember old s
+ -- this functions counts the number of elements in a subtree
+ s := s + numberOfImproperPartitionsInternal(n-y,m,cm)
+ if s > k then leave
+ -- y is the next son, so put it into the pathlist "nonZero"
+ nonZeros := append(nonZeros,list(y)$(L I))$(L I)
+ k := k - sOld --updating
+ n := n - y --updating
+ --having found all m-cm non-zero entries we change the structure
+ --of the tree and determine the non-zero positions
+ nonZeroPos : L I := reverse subSet(m,m-cm,k)
+ --building the partition
+ for i in 1..m-cm repeat partition.(1+nonZeroPos.i) := nonZeros.i
+ entries partition
+
+
+ subSet(n,m,k) ==
+ k < 0 or n < 0 or m < 0 or m > n =>
+ error "improper argument to subSet"
+ bin : I := binomial$ICF (n,m)
+ k >= bin =>
+ error "there are not so many subsets"
+ l : L I := []
+ n = 0 => l
+ mm : I := k
+ s : I := m
+ for t in 0..(m-1) repeat
+ for y in (s-1)..(n+1) repeat
+ if binomial$ICF (y,s) > mm then leave
+ l := append (l,list(y-1)$(L I))
+ mm := mm - binomial$ICF (y-1,s)
+ s := s-1
+ l
+
+
+ nextLatticePermutation(lambda, lattP, constructNotFirst) ==
+
+ lprime : L I := conjugate(lambda)$PartitionsAndPermutations
+ columns : NNI := (first(lambda)$(L I))::NNI
+ rows : NNI := (first(lprime)$(L I))::NNI
+ n : NNI :=(+/lambda)::NNI
+
+ not constructNotFirst => -- first lattice permutation
+ lattP := nil$(L I)
+ for i in columns..1 by -1 repeat
+ for l in 1..lprime(i) repeat
+ lattP := cons(i,lattP)
+ lattP
+
+ help : V I := new(columns,0) -- entry help(i) stores the number
+ -- of occurences of number i on our way from right to left
+ rightPosition : NNI := n
+ leftEntry : NNI := lattP(rightPosition)::NNI
+ ready : B := false
+ until (ready or (not constructNotFirst)) repeat
+ rightEntry : NNI := leftEntry
+ leftEntry := lattP(rightPosition-1)::NNI
+ help(rightEntry) := help(rightEntry) + 1
+ -- search backward decreasing neighbour elements
+ if rightEntry > leftEntry then
+ if ((lprime(leftEntry)-help(leftEntry)) >_
+ (lprime(rightEntry)-help(rightEntry)+1)) then
+ -- the elements may be swapped because the number of occurances
+ -- of leftEntry would still be greater than those of rightEntry
+ ready := true
+ j : NNI := leftEntry + 1
+ -- search among the numbers leftEntry+1..rightEntry for the
+ -- smallest one which can take the place of leftEntry.
+ -- negation of condition above:
+ while (help(j)=0) or ((lprime(leftEntry)-lprime(j))
+ < (help(leftEntry)-help(j)+2)) repeat j := j + 1
+ lattP(rightPosition-1) := j
+ help(j) := help(j)-1
+ help(leftEntry) := help(leftEntry) + 1
+ -- reconstruct the rest of the list in increasing order
+ for l in rightPosition..n repeat
+ j := 0
+ while help(1+j) = 0 repeat j := j + 1
+ lattP(l::NNI) := j+1
+ help(1+j) := help(1+j) - 1
+ -- end of "if rightEntry > leftEntry"
+ rightPosition := (rightPosition-1)::NNI
+ if rightPosition = 1 then constructNotFirst := false
+ -- end of repeat-loop
+ not constructNotFirst => nil$(L I)
+ lattP
+
+
+ makeYoungTableau(lambda,gitter) ==
+ lprime : L I := conjugate(lambda)$PartitionsAndPermutations
+ columns : NNI := (first(lambda)$(L I))::NNI
+ rows : NNI := (first(lprime)$(L I))::NNI
+ ytab : M I := new(rows,columns,0)
+ help : V I := new(columns,1)
+ i : I := -1 -- this makes the entries ranging from 0,..,n-1
+ -- i := 0 would make it from 1,..,n.
+ j : I := 0
+ for l in 1..maxIndex gitter repeat
+ j := gitter(l)
+ i := i + 1
+ ytab(help(j),j) := i
+ help(j) := help(j) + 1
+ ytab
+
+
+-- coerce(ytab) ==
+-- lli := listOfLists(ytab)$(M I)
+-- -- remove the filling zeros in each row. It is assumed that
+-- -- that there are no such in row 0.
+-- for i in 2..maxIndex lli repeat
+-- THIS IS DEFINIVELY WRONG, I NEED A FUNCTION WHICH DELETES THE
+-- 0s, in my version there are no mapping facilities yet.
+-- deleteInPlace(not zero?,lli i)
+-- tableau(lli)$Tableau(I)
+
+
+ listYoungTableaus(lambda) ==
+ lattice : L I
+ ytab : M I
+ younglist : L M I := nil$(L M I)
+ lattice := nextLatticePermutation(lambda,lattice,false)
+ until null lattice repeat
+ ytab := makeYoungTableau(lambda,lattice)
+ younglist := append(younglist,[ytab]$(L M I))$(L M I)
+ lattice := nextLatticePermutation(lambda,lattice,true)
+ younglist
+
+
+ nextColeman(alpha,beta,C) ==
+ nrow : NNI := #beta
+ ncol : NNI := #alpha
+ vnull : V I := vector(nil()$(L I)) -- empty vector
+ vzero : V I := new(ncol,0)
+ vrest : V I := new(ncol,0)
+ cnull : M I := new(1,1,0)
+ coleman := copy C
+ if coleman ^= cnull then
+ -- look for the first row of "coleman" that has a succeeding
+ -- partition, this can be atmost row nrow-1
+ i : NNI := (nrow-1)::NNI
+ vrest := row(coleman,i) + row(coleman,nrow)
+ --for k in 1..ncol repeat
+ -- vrest(k) := coleman(i,k) + coleman(nrow,k)
+ succ := nextPartition(vrest,row(coleman, i),beta(i))
+ while (succ = vnull) repeat
+ if i = 1 then return cnull -- part is last partition
+ i := (i - 1)::NNI
+ --for k in 1..ncol repeat
+ -- vrest(k) := vrest(k) + coleman(i,k)
+ vrest := vrest + row(coleman,i)
+ succ := nextPartition(vrest, row(coleman, i), beta(i))
+ j : I := i
+ coleman := setRow_!(coleman, i, succ)
+ --for k in 1..ncol repeat
+ -- vrest(k) := vrest(k) - coleman(i,k)
+ vrest := vrest - row(coleman,i)
+ else
+ vrest := vector alpha
+ -- for k in 1..ncol repeat
+ -- vrest(k) := alpha(k)
+ coleman := new(nrow,ncol,0)
+ j : I := 0
+ for i in (j+1)::NNI..nrow-1 repeat
+ succ := nextPartition(vrest,vnull,beta(i))
+ coleman := setRow_!(coleman, i, succ)
+ vrest := vrest - succ
+ --for k in 1..ncol repeat
+ -- vrest(k) := vrest(k) - succ(k)
+ setRow_!(coleman, nrow, vrest)
+
+
+ nextPartition(gamma:V I, part:V I, number:I) ==
+ nextPartition(entries gamma, part, number)
+
+
+ nextPartition(gamma:L I,part:V I,number:I) ==
+ n : NNI := #gamma
+ vnull : V I := vector(nil()$(L I)) -- empty vector
+ if part ^= vnull then
+ i : NNI := 2
+ sum := part(1)
+ while (part(i) = gamma(i)) or (sum = 0) repeat
+ sum := sum + part(i)
+ i := i + 1
+ if i = 1+n then return vnull -- part is last partition
+ sum := sum - 1
+ part(i) := part(i) + 1
+ else
+ sum := number
+ part := new(n,0)
+ i := 1+n
+ j : NNI := 1
+ while sum > gamma(j) repeat
+ part(j) := gamma(j)
+ sum := sum - gamma(j)
+ j := j + 1
+ part(j) := sum
+ for k in j+1..i-1 repeat
+ part(k) := 0
+ part
+
+
+ inverseColeman(alpha,beta,C) ==
+ pi : L I := nil$(L I)
+ nrow : NNI := #beta
+ ncol : NNI := #alpha
+ help : V I := new(nrow,0)
+ sum : I := 1
+ for i in 1..nrow repeat
+ help(i) := sum
+ sum := sum + beta(i)
+ for j in 1..ncol repeat
+ for i in 1..nrow repeat
+ for k in 2..1+C(i,j) repeat
+ pi := append(pi,list(help(i))$(L I))
+ help(i) := help(i) + 1
+ pi
+
+
+ coleman(alpha,beta,pi) ==
+ nrow : NNI := #beta
+ ncol : NNI := #alpha
+ temp : L L I := nil$(L L I)
+ help : L I := nil$(L I)
+ colematrix : M I := new(nrow,ncol,0)
+ betasum : NNI := 0
+ alphasum : NNI := 0
+ for i in 1..ncol repeat
+ help := nil$(L I)
+ for j in alpha(i)..1 by-1 repeat
+ help := cons(pi(j::NNI+alphasum),help)
+ alphasum := (alphasum + alpha(i))::NNI
+ temp := append(temp,list(help)$(L L I))
+ for i in 1..nrow repeat
+ help := nil$(L I)
+ for j in beta(i)..1 by-1 repeat
+ help := cons(j::NNI+betasum, help)
+ betasum := (betasum + beta(i))::NNI
+ for j in 1..ncol repeat
+ colematrix(i,j) := #intersect(brace(help),brace(temp(j)))
+ colematrix
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SGCF SymmetricGroupCombinatoricFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/si.spad.pamphlet b/src/algebra/si.spad.pamphlet
new file mode 100644
index 00000000..b7be18aa
--- /dev/null
+++ b/src/algebra/si.spad.pamphlet
@@ -0,0 +1,1557 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra si.spad}
+\author{Stephen M. Watt, Michael Monagan, James Davenport, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category INS IntegerNumberSystem}
+<<category INS IntegerNumberSystem>>=
+)abbrev category INS IntegerNumberSystem
+++ Author: Stephen M. Watt
+++ Date Created:
+++ January 1988
+++ Change History:
+++ Basic Operations:
+++ addmod, base, bit?, copy, dec, even?, hash, inc, invmod, length, mask,
+++ positiveRemainder, symmetricRemainder, multiplicativeValuation, mulmod,
+++ odd?, powmod, random, rational, rational?, rationalIfCan, shift, submod
+++ Description: An \spad{IntegerNumberSystem} is a model for the integers.
+IntegerNumberSystem(): Category ==
+ Join(UniqueFactorizationDomain, EuclideanDomain, OrderedIntegralDomain,
+ DifferentialRing, ConvertibleTo Integer, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, ConvertibleTo InputForm,
+ ConvertibleTo Pattern Integer, PatternMatchable Integer,
+ CombinatorialFunctionCategory, RealConstant,
+ CharacteristicZero, StepThrough) with
+ odd? : % -> Boolean
+ ++ odd?(n) returns true if and only if n is odd.
+ even? : % -> Boolean
+ ++ even?(n) returns true if and only if n is even.
+ multiplicativeValuation
+ ++ euclideanSize(a*b) returns \spad{euclideanSize(a)*euclideanSize(b)}.
+ base : () -> %
+ ++ base() returns the base for the operations of \spad{IntegerNumberSystem}.
+ length : % -> %
+ ++ length(a) length of \spad{a} in digits.
+ shift : (%, %) -> %
+ ++ shift(a,i) shift \spad{a} by i digits.
+ bit? : (%, %) -> Boolean
+ ++ bit?(n,i) returns true if and only if i-th bit of n is a 1.
+ positiveRemainder : (%, %) -> %
+ ++ positiveRemainder(a,b) (where \spad{b > 1}) yields r
+ ++ where \spad{0 <= r < b} and \spad{r == a rem b}.
+ symmetricRemainder : (%, %) -> %
+ ++ symmetricRemainder(a,b) (where \spad{b > 1}) yields r
+ ++ where \spad{ -b/2 <= r < b/2 }.
+ rational?: % -> Boolean
+ ++ rational?(n) tests if n is a rational number
+ ++ (see \spadtype{Fraction Integer}).
+ rational : % -> Fraction Integer
+ ++ rational(n) creates a rational number (see \spadtype{Fraction Integer})..
+ rationalIfCan: % -> Union(Fraction Integer, "failed")
+ ++ rationalIfCan(n) creates a rational number, or returns "failed" if this is not possible.
+ random : () -> %
+ ++ random() creates a random element.
+ random : % -> %
+ ++ random(a) creates a random element from 0 to \spad{n-1}.
+ hash : % -> %
+ ++ hash(n) returns the hash code of n.
+ copy : % -> %
+ ++ copy(n) gives a copy of n.
+ inc : % -> %
+ ++ inc(x) returns \spad{x + 1}.
+ dec : % -> %
+ ++ dec(x) returns \spad{x - 1}.
+ mask : % -> %
+ ++ mask(n) returns \spad{2**n-1} (an n bit mask).
+ addmod : (%,%,%) -> %
+ ++ addmod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a+b mod p}.
+ submod : (%,%,%) -> %
+ ++ submod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a-b mod p}.
+ mulmod : (%,%,%) -> %
+ ++ mulmod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a*b mod p}.
+ powmod : (%,%,%) -> %
+ ++ powmod(a,b,p), \spad{0<=a,b<p>1}, means \spad{a**b mod p}.
+ invmod : (%,%) -> %
+ ++ invmod(a,b), \spad{0<=a<b>1}, \spad{(a,b)=1} means \spad{1/a mod b}.
+ canonicalUnitNormal
+-- commutative("*") -- follows from the above
+
+ add
+ characteristic() == 0
+ differentiate x == 0
+ even? x == not odd? x
+ positive? x == x > 0
+ copy x == x
+ bit?(x, i) == odd? shift(x, -i)
+ mask n == dec shift(1, n)
+ rational? x == true
+ euclideanSize(x) ==
+ x=0 => error "euclideanSize called on zero"
+ x<0 => (-convert(x)@Integer)::NonNegativeInteger
+ convert(x)@Integer::NonNegativeInteger
+ convert(x:%):Float == (convert(x)@Integer)::Float
+ convert(x:%):DoubleFloat == (convert(x)@Integer)::DoubleFloat
+ convert(x:%):InputForm == convert(convert(x)@Integer)
+ retract(x:%):Integer == convert(x)@Integer
+ convert(x:%):Pattern(Integer)== convert(x)@Integer ::Pattern(Integer)
+ factor x == factor(x)$IntegerFactorizationPackage(%)
+ squareFree x == squareFree(x)$IntegerFactorizationPackage(%)
+ prime? x == prime?(x)$IntegerPrimesPackage(%)
+ factorial x == factorial(x)$IntegerCombinatoricFunctions(%)
+ binomial(n, m) == binomial(n, m)$IntegerCombinatoricFunctions(%)
+ permutation(n, m) == permutation(n,m)$IntegerCombinatoricFunctions(%)
+ retractIfCan(x:%):Union(Integer, "failed") == convert(x)@Integer
+
+ init() == 0
+
+ -- iterates in order 0,1,-1,2,-2,3,-3,...
+ nextItem(n) ==
+ zero? n => 1
+ n>0 => -n
+ 1-n
+
+ patternMatch(x, p, l) ==
+ patternMatch(x, p, l)$PatternMatchIntegerNumberSystem(%)
+
+ rational(x:%):Fraction(Integer) ==
+ (convert(x)@Integer)::Fraction(Integer)
+
+ rationalIfCan(x:%):Union(Fraction Integer, "failed") ==
+ (convert(x)@Integer)::Fraction(Integer)
+
+ symmetricRemainder(x, n) ==
+ r := x rem n
+ r = 0 => r
+ if n < 0 then n:=-n
+ r > 0 =>
+ 2 * r > n => r - n
+ r
+ 2*r + n <= 0 => r + n
+ r
+
+ invmod(a, b) ==
+ if negative? a then a := positiveRemainder(a, b)
+ c := a; c1:% := 1
+ d := b; d1:% := 0
+ while not zero? d repeat
+ q := c quo d
+ r := c-q*d
+ r1 := c1-q*d1
+ c := d; c1 := d1
+ d := r; d1 := r1
+-- not one? c => error "inverse does not exist"
+ not (c = 1) => error "inverse does not exist"
+ negative? c1 => c1 + b
+ c1
+
+ powmod(x, n, p) ==
+ if negative? x then x := positiveRemainder(x, p)
+ zero? x => 0
+ zero? n => 1
+ y:% := 1
+ z := x
+ repeat
+ if odd? n then y := mulmod(y, z, p)
+ zero?(n := shift(n, -1)) => return y
+ z := mulmod(z, z, p)
+
+@
+\section{INS.lsp BOOTSTRAP}
+{\bf INS} depends on itself. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf INS}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf INS.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+<<INS.lsp BOOTSTRAP>>=
+
+(/VERSIONCHECK 2)
+
+(SETQ |IntegerNumberSystem;AL| (QUOTE NIL))
+
+(DEFUN |IntegerNumberSystem| NIL
+ (LET (#:G1068)
+ (COND
+ (|IntegerNumberSystem;AL|)
+ (T (SETQ |IntegerNumberSystem;AL| (|IntegerNumberSystem;|))))))
+
+(DEFUN |IntegerNumberSystem;| NIL (PROG (#0=#:G1066)
+ (RETURN
+ (PROG1
+ (LETT #0#
+ (|sublisV|
+ (PAIR
+ (QUOTE (#1=#:G1060 #2=#:G1061 #3=#:G1062
+ #4=#:G1063 #5=#:G1064 #6=#:G1065))
+ (LIST
+ (QUOTE (|Integer|))
+ (QUOTE (|Integer|))
+ (QUOTE (|Integer|))
+ (QUOTE (|InputForm|))
+ (QUOTE (|Pattern| (|Integer|)))
+ (QUOTE (|Integer|))))
+ (|Join|
+ (|UniqueFactorizationDomain|)
+ (|EuclideanDomain|)
+ (|OrderedIntegralDomain|)
+ (|DifferentialRing|)
+ (|ConvertibleTo| (QUOTE #1#))
+ (|RetractableTo| (QUOTE #2#))
+ (|LinearlyExplicitRingOver| (QUOTE #3#))
+ (|ConvertibleTo| (QUOTE #4#))
+ (|ConvertibleTo| (QUOTE #5#))
+ (|PatternMatchable| (QUOTE #6#))
+ (|CombinatorialFunctionCategory|)
+ (|RealConstant|)
+ (|CharacteristicZero|)
+ (|StepThrough|)
+ (|mkCategory|
+ (QUOTE |domain|)
+ (QUOTE (
+ ((|odd?| ((|Boolean|) $)) T)
+ ((|even?| ((|Boolean|) $)) T)
+ ((|base| ($)) T)
+ ((|length| ($ $)) T)
+ ((|shift| ($ $ $)) T)
+ ((|bit?| ((|Boolean|) $ $)) T)
+ ((|positiveRemainder| ($ $ $)) T)
+ ((|symmetricRemainder| ($ $ $)) T)
+ ((|rational?| ((|Boolean|) $)) T)
+ ((|rational| ((|Fraction| (|Integer|)) $)) T)
+ ((|rationalIfCan|
+ ((|Union| (|Fraction| (|Integer|)) "failed") $)) T)
+ ((|random| ($)) T)
+ ((|random| ($ $)) T)
+ ((|hash| ($ $)) T)
+ ((|copy| ($ $)) T)
+ ((|inc| ($ $)) T)
+ ((|dec| ($ $)) T)
+ ((|mask| ($ $)) T)
+ ((|addmod| ($ $ $ $)) T)
+ ((|submod| ($ $ $ $)) T)
+ ((|mulmod| ($ $ $ $)) T)
+ ((|powmod| ($ $ $ $)) T)
+ ((|invmod| ($ $ $)) T)))
+ (QUOTE ((|multiplicativeValuation| T) (|canonicalUnitNormal| T)))
+ (QUOTE ((|Fraction| (|Integer|)) (|Boolean|))) NIL)))
+ |IntegerNumberSystem|)
+ (SETELT #0# 0 (QUOTE (|IntegerNumberSystem|)))))))
+
+(MAKEPROP (QUOTE |IntegerNumberSystem|) (QUOTE NILADIC) T)
+
+@
+\section{INS-.lsp BOOTSTRAP}
+{\bf INS-} depends on {\bf INS}. We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf INS-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf INS-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+<<INS-.lsp BOOTSTRAP>>=
+
+(/VERSIONCHECK 2)
+
+(PUT
+ (QUOTE |INS-;characteristic;Nni;1|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL 0)))
+
+(DEFUN |INS-;characteristic;Nni;1| ($) 0)
+
+(DEFUN |INS-;differentiate;2S;2| (|x| $)
+ (|spadConstant| $ 9))
+
+(DEFUN |INS-;even?;SB;3| (|x| $)
+ (COND
+ ((SPADCALL |x| (QREFELT $ 12)) (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+
+(DEFUN |INS-;positive?;SB;4| (|x| $)
+ (SPADCALL (|spadConstant| $ 9) |x| (QREFELT $ 14)))
+
+(PUT
+ (QUOTE |INS-;copy;2S;5|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|x|) |x|)))
+
+(DEFUN |INS-;copy;2S;5| (|x| $) |x|)
+
+(DEFUN |INS-;bit?;2SB;6| (|x| |i| $)
+ (SPADCALL
+ (SPADCALL |x|
+ (SPADCALL |i| (QREFELT $ 17))
+ (QREFELT $ 18))
+ (QREFELT $ 12)))
+
+(DEFUN |INS-;mask;2S;7| (|n| $)
+ (SPADCALL
+ (SPADCALL (|spadConstant| $ 20) |n| (QREFELT $ 18))
+ (QREFELT $ 21)))
+
+(PUT
+ (QUOTE |INS-;rational?;SB;8|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|x|) (QUOTE T))))
+
+(DEFUN |INS-;rational?;SB;8| (|x| $)
+ (QUOTE T))
+
+(DEFUN |INS-;euclideanSize;SNni;9| (|x| $)
+ (PROG (#0=#:G1078 #1=#:G1079)
+ (RETURN
+ (COND
+ ((SPADCALL |x| (|spadConstant| $ 9) (QREFELT $ 24))
+ (|error| "euclideanSize called on zero"))
+ ((SPADCALL |x| (|spadConstant| $ 9) (QREFELT $ 14))
+ (PROG1
+ (LETT #0#
+ (- (SPADCALL |x| (QREFELT $ 26)))
+ |INS-;euclideanSize;SNni;9|)
+ (|check-subtype|
+ (>= #0# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #0#)))
+ ((QUOTE T)
+ (PROG1
+ (LETT #1#
+ (SPADCALL |x| (QREFELT $ 26))
+ |INS-;euclideanSize;SNni;9|)
+ (|check-subtype|
+ (>= #1# 0)
+ (QUOTE (|NonNegativeInteger|))
+ #1#)))))))
+
+(DEFUN |INS-;convert;SF;10| (|x| $)
+ (SPADCALL (SPADCALL |x| (QREFELT $ 26)) (QREFELT $ 29)))
+
+(DEFUN |INS-;convert;SDf;11| (|x| $)
+ (FLOAT (SPADCALL |x| (QREFELT $ 26)) MOST-POSITIVE-LONG-FLOAT))
+
+(DEFUN |INS-;convert;SIf;12| (|x| $)
+ (SPADCALL (SPADCALL |x| (QREFELT $ 26)) (QREFELT $ 34)))
+
+(DEFUN |INS-;retract;SI;13| (|x| $)
+ (SPADCALL |x| (QREFELT $ 26)))
+
+(DEFUN |INS-;convert;SP;14| (|x| $)
+ (SPADCALL (SPADCALL |x| (QREFELT $ 26)) (QREFELT $ 38)))
+
+(DEFUN |INS-;factor;SF;15| (|x| $)
+ (SPADCALL |x| (QREFELT $ 42)))
+
+(DEFUN |INS-;squareFree;SF;16| (|x| $)
+ (SPADCALL |x| (QREFELT $ 45)))
+
+(DEFUN |INS-;prime?;SB;17| (|x| $)
+ (SPADCALL |x| (QREFELT $ 48)))
+
+(DEFUN |INS-;factorial;2S;18| (|x| $)
+ (SPADCALL |x| (QREFELT $ 51)))
+
+(DEFUN |INS-;binomial;3S;19| (|n| |m| $)
+ (SPADCALL |n| |m| (QREFELT $ 53)))
+
+(DEFUN |INS-;permutation;3S;20| (|n| |m| $)
+ (SPADCALL |n| |m| (QREFELT $ 55)))
+
+(DEFUN |INS-;retractIfCan;SU;21| (|x| $)
+ (CONS 0 (SPADCALL |x| (QREFELT $ 26))))
+
+(DEFUN |INS-;init;S;22| ($)
+ (|spadConstant| $ 9))
+
+(DEFUN |INS-;nextItem;SU;23| (|n| $)
+ (COND
+ ((SPADCALL |n| (QREFELT $ 60))
+ (CONS 0 (|spadConstant| $ 20)))
+ ((SPADCALL (|spadConstant| $ 9) |n| (QREFELT $ 14))
+ (CONS 0 (SPADCALL |n| (QREFELT $ 17))))
+ ((QUOTE T)
+ (CONS 0 (SPADCALL (|spadConstant| $ 20) |n| (QREFELT $ 61))))))
+
+(DEFUN |INS-;patternMatch;SP2Pmr;24| (|x| |p| |l| $)
+ (SPADCALL |x| |p| |l| (QREFELT $ 66)))
+
+(DEFUN |INS-;rational;SF;25| (|x| $)
+ (SPADCALL (SPADCALL |x| (QREFELT $ 26)) (QREFELT $ 70)))
+
+(DEFUN |INS-;rationalIfCan;SU;26| (|x| $)
+ (CONS 0 (SPADCALL (SPADCALL |x| (QREFELT $ 26)) (QREFELT $ 70))))
+
+(DEFUN |INS-;symmetricRemainder;3S;27| (|x| |n| $)
+ (PROG (|r|)
+ (RETURN
+ (SEQ
+ (LETT |r|
+ (SPADCALL |x| |n| (QREFELT $ 74))
+ |INS-;symmetricRemainder;3S;27|)
+ (EXIT
+ (COND
+ ((SPADCALL |r| (|spadConstant| $ 9) (QREFELT $ 24)) |r|)
+ ((QUOTE T)
+ (SEQ
+ (COND
+ ((SPADCALL |n| (|spadConstant| $ 9) (QREFELT $ 14))
+ (LETT |n|
+ (SPADCALL |n| (QREFELT $ 17))
+ |INS-;symmetricRemainder;3S;27|)))
+ (EXIT
+ (COND
+ ((SPADCALL (|spadConstant| $ 9) |r| (QREFELT $ 14))
+ (COND
+ ((SPADCALL |n|
+ (SPADCALL 2 |r| (QREFELT $ 76))
+ (QREFELT $ 14))
+ (SPADCALL |r| |n| (QREFELT $ 61)))
+ ((QUOTE T) |r|)))
+ ((NULL
+ (SPADCALL
+ (|spadConstant| $ 9)
+ (SPADCALL
+ (SPADCALL 2 |r| (QREFELT $ 76))
+ |n|
+ (QREFELT $ 77))
+ (QREFELT $ 14)))
+ (SPADCALL |r| |n| (QREFELT $ 77)))
+ ((QUOTE T) |r|)))))))))))
+
+(DEFUN |INS-;invmod;3S;28| (|a| |b| $)
+ (PROG (|q| |r| |r1| |c| |c1| |d| |d1|)
+ (RETURN
+ (SEQ
+ (COND
+ ((SPADCALL |a| (QREFELT $ 79))
+ (LETT |a| (SPADCALL |a| |b| (QREFELT $ 80)) |INS-;invmod;3S;28|)))
+ (LETT |c| |a| |INS-;invmod;3S;28|)
+ (LETT |c1| (|spadConstant| $ 20) |INS-;invmod;3S;28|)
+ (LETT |d| |b| |INS-;invmod;3S;28|)
+ (LETT |d1| (|spadConstant| $ 9) |INS-;invmod;3S;28|)
+ (SEQ G190
+ (COND
+ ((NULL
+ (COND
+ ((SPADCALL |d| (QREFELT $ 60)) (QUOTE NIL))
+ ((QUOTE T) (QUOTE T))))
+ (GO G191)))
+ (SEQ
+ (LETT |q| (SPADCALL |c| |d| (QREFELT $ 81)) |INS-;invmod;3S;28|)
+ (LETT |r|
+ (SPADCALL |c| (SPADCALL |q| |d| (QREFELT $ 82)) (QREFELT $ 61))
+ |INS-;invmod;3S;28|)
+ (LETT |r1|
+ (SPADCALL |c1| (SPADCALL |q| |d1| (QREFELT $ 82)) (QREFELT $ 61))
+ |INS-;invmod;3S;28|)
+ (LETT |c| |d| |INS-;invmod;3S;28|)
+ (LETT |c1| |d1| |INS-;invmod;3S;28|)
+ (LETT |d| |r| |INS-;invmod;3S;28|)
+ (EXIT (LETT |d1| |r1| |INS-;invmod;3S;28|)))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL))
+ (COND
+ ((NULL (SPADCALL |c| (QREFELT $ 83)))
+ (EXIT (|error| "inverse does not exist"))))
+ (EXIT
+ (COND
+ ((SPADCALL |c1| (QREFELT $ 79)) (SPADCALL |c1| |b| (QREFELT $ 77)))
+ ((QUOTE T) |c1|)))))))
+
+(DEFUN |INS-;powmod;4S;29| (|x| |n| |p| $)
+ (PROG (|y| #0=#:G1137 |z|)
+ (RETURN
+ (SEQ
+ (EXIT
+ (SEQ
+ (COND
+ ((SPADCALL |x| (QREFELT $ 79))
+ (LETT |x|
+ (SPADCALL |x| |p| (QREFELT $ 80))
+ |INS-;powmod;4S;29|)))
+ (EXIT
+ (COND
+ ((SPADCALL |x| (QREFELT $ 60)) (|spadConstant| $ 9))
+ ((SPADCALL |n| (QREFELT $ 60)) (|spadConstant| $ 20))
+ ((QUOTE T)
+ (SEQ
+ (LETT |y| (|spadConstant| $ 20) |INS-;powmod;4S;29|)
+ (LETT |z| |x| |INS-;powmod;4S;29|)
+ (EXIT
+ (SEQ G190
+ NIL
+ (SEQ
+ (COND
+ ((SPADCALL |n| (QREFELT $ 12))
+ (LETT |y|
+ (SPADCALL |y| |z| |p| (QREFELT $ 85))
+ |INS-;powmod;4S;29|)))
+ (EXIT
+ (COND
+ ((SPADCALL
+ (LETT |n|
+ (SPADCALL |n|
+ (SPADCALL
+ (|spadConstant| $ 20)
+ (QREFELT $ 17))
+ (QREFELT $ 18))
+ |INS-;powmod;4S;29|)
+ (QREFELT $ 60))
+ (PROGN
+ (LETT #0# |y| |INS-;powmod;4S;29|)
+ (GO #0#)))
+ ((QUOTE T)
+ (LETT |z|
+ (SPADCALL |z| |z| |p| (QREFELT $ 85))
+ |INS-;powmod;4S;29|)))))
+ NIL
+ (GO G190)
+ G191
+ (EXIT NIL)))))))))
+ #0#
+ (EXIT #0#)))))
+
+(DEFUN |IntegerNumberSystem&| (|#1|)
+ (PROG (DV$1 |dv$| $ |pv$|)
+ (RETURN
+ (PROGN
+ (LETT DV$1 (|devaluate| |#1|) . #0=(|IntegerNumberSystem&|))
+ (LETT |dv$| (LIST (QUOTE |IntegerNumberSystem&|) DV$1) . #0#)
+ (LETT $ (GETREFV 87) . #0#)
+ (QSETREFV $ 0 |dv$|)
+ (QSETREFV $ 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #0#))
+ (|stuffDomainSlots| $)
+ (QSETREFV $ 6 |#1|)
+ $))))
+
+(MAKEPROP
+ (QUOTE |IntegerNumberSystem&|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (|local| |#1|)
+ (|NonNegativeInteger|)
+ |INS-;characteristic;Nni;1|
+ (0 . |Zero|)
+ |INS-;differentiate;2S;2|
+ (|Boolean|)
+ (4 . |odd?|)
+ |INS-;even?;SB;3|
+ (9 . <)
+ |INS-;positive?;SB;4|
+ |INS-;copy;2S;5|
+ (15 . -)
+ (20 . |shift|)
+ |INS-;bit?;2SB;6|
+ (26 . |One|)
+ (30 . |dec|)
+ |INS-;mask;2S;7|
+ |INS-;rational?;SB;8|
+ (35 . =)
+ (|Integer|)
+ (41 . |convert|)
+ |INS-;euclideanSize;SNni;9|
+ (|Float|)
+ (46 . |coerce|)
+ |INS-;convert;SF;10|
+ (|DoubleFloat|)
+ |INS-;convert;SDf;11|
+ (|InputForm|)
+ (51 . |convert|)
+ |INS-;convert;SIf;12|
+ |INS-;retract;SI;13|
+ (|Pattern| 25)
+ (56 . |coerce|)
+ |INS-;convert;SP;14|
+ (|Factored| 6)
+ (|IntegerFactorizationPackage| 6)
+ (61 . |factor|)
+ (|Factored| $)
+ |INS-;factor;SF;15|
+ (66 . |squareFree|)
+ |INS-;squareFree;SF;16|
+ (|IntegerPrimesPackage| 6)
+ (71 . |prime?|)
+ |INS-;prime?;SB;17|
+ (|IntegerCombinatoricFunctions| 6)
+ (76 . |factorial|)
+ |INS-;factorial;2S;18|
+ (81 . |binomial|)
+ |INS-;binomial;3S;19|
+ (87 . |permutation|)
+ |INS-;permutation;3S;20|
+ (|Union| 25 (QUOTE "failed"))
+ |INS-;retractIfCan;SU;21|
+ |INS-;init;S;22|
+ (93 . |zero?|)
+ (98 . -)
+ (|Union| $ (QUOTE "failed"))
+ |INS-;nextItem;SU;23|
+ (|PatternMatchResult| 25 6)
+ (|PatternMatchIntegerNumberSystem| 6)
+ (104 . |patternMatch|)
+ (|PatternMatchResult| 25 $)
+ |INS-;patternMatch;SP2Pmr;24|
+ (|Fraction| 25)
+ (111 . |coerce|)
+ |INS-;rational;SF;25|
+ (|Union| 69 (QUOTE "failed"))
+ |INS-;rationalIfCan;SU;26|
+ (116 . |rem|)
+ (|PositiveInteger|)
+ (122 . *)
+ (128 . +)
+ |INS-;symmetricRemainder;3S;27|
+ (134 . |negative?|)
+ (139 . |positiveRemainder|)
+ (145 . |quo|)
+ (151 . *)
+ (157 . |one?|)
+ |INS-;invmod;3S;28|
+ (162 . |mulmod|)
+ |INS-;powmod;4S;29|))
+ (QUOTE
+ #(|symmetricRemainder| 169 |squareFree| 175 |retractIfCan| 180
+ |retract| 185 |rationalIfCan| 190 |rational?| 195 |rational| 200
+ |prime?| 205 |powmod| 210 |positive?| 217 |permutation| 222
+ |patternMatch| 228 |nextItem| 235 |mask| 240 |invmod| 245 |init| 251
+ |factorial| 255 |factor| 260 |even?| 265 |euclideanSize| 270
+ |differentiate| 275 |copy| 280 |convert| 285 |characteristic| 305
+ |bit?| 309 |binomial| 315))
+ (QUOTE NIL)
+ (CONS
+ (|makeByteWordVec2| 1 (QUOTE NIL))
+ (CONS
+ (QUOTE #())
+ (CONS
+ (QUOTE #())
+ (|makeByteWordVec2| 86
+ (QUOTE
+ (0 6 0 9 1 6 11 0 12 2 6 11 0 0 14 1 6 0 0 17 2 6 0 0 0 18 0 6
+ 0 20 1 6 0 0 21 2 6 11 0 0 24 1 6 25 0 26 1 28 0 25 29 1 33 0
+ 25 34 1 37 0 25 38 1 41 40 6 42 1 41 40 6 45 1 47 11 6 48 1 50
+ 6 6 51 2 50 6 6 6 53 2 50 6 6 6 55 1 6 11 0 60 2 6 0 0 0 61 3
+ 65 64 6 37 64 66 1 69 0 25 70 2 6 0 0 0 74 2 6 0 75 0 76 2 6 0
+ 0 0 77 1 6 11 0 79 2 6 0 0 0 80 2 6 0 0 0 81 2 6 0 0 0 82 1 6
+ 11 0 83 3 6 0 0 0 0 85 2 0 0 0 0 78 1 0 43 0 46 1 0 57 0 58 1
+ 0 25 0 36 1 0 72 0 73 1 0 11 0 23 1 0 69 0 71 1 0 11 0 49 3 0
+ 0 0 0 0 86 1 0 11 0 15 2 0 0 0 0 56 3 0 67 0 37 67 68 1 0 62
+ 0 63 1 0 0 0 22 2 0 0 0 0 84 0 0 0 59 1 0 0 0 52 1 0 43 0 44
+ 1 0 11 0 13 1 0 7 0 27 1 0 0 0 10 1 0 0 0 16 1 0 31 0 32 1 0
+ 28 0 30 1 0 37 0 39 1 0 33 0 35 0 0 7 8 2 0 11 0 0 19 2 0 0
+ 0 0 54))))))
+ (QUOTE |lookupComplete|)))
+
+@
+\section{domain SINT SingleInteger}
+The definition of {\bf one?} has been rewritten
+as it relies on calling {\bf ONEP} which is a function specific
+to Codemist Common Lisp but is not defined in Common Lisp.
+<<domain SINT SingleInteger>>=
+)abbrev domain SINT SingleInteger
+
+-- following patch needed to deal with *:(I,%) -> %
+-- affects behavior of SourceLevelSubset
+--)bo $noSubsets := true
+-- No longer - JHD !! still needed 5/3/91 BMT
+
+++ Author: Michael Monagan
+++ Date Created:
+++ January 1988
+++ Change History:
+++ Basic Operations: max, min,
+++ not, and, or, xor, Not, And, Or
+++ Related Constructors:
+++ Keywords: single integer
+++ Description: SingleInteger is intended to support machine integer
+++ arithmetic.
+
+-- MAXINT, BASE (machine integer constants)
+-- MODULUS, MULTIPLIER (random number generator constants)
+
+
+-- Lisp dependencies
+-- EQ, ABSVAL, TIMES, INTEGER-LENGTH, HASHEQ, REMAINDER
+-- QSLESSP, QSGREATERP, QSADD1, QSSUB1, QSMINUS, QSPLUS, QSDIFFERENCE
+-- QSTIMES, QSREMAINDER, QSODDP, QSZEROP, QSMAX, QSMIN, QSNOT, QSAND
+-- QSOR, QSXOR, QSLEFTSHIFT, QSADDMOD, QSDIFMOD, QSMULTMOD
+
+
+SingleInteger(): Join(IntegerNumberSystem,Logic,OpenMath) with
+ canonical
+ ++ \spad{canonical} means that mathematical equality is implied by data structure equality.
+ canonicalsClosed
+ ++ \spad{canonicalClosed} means two positives multiply to give positive.
+ noetherian
+ ++ \spad{noetherian} all ideals are finitely generated (in fact principal).
+
+ max : () -> %
+ ++ max() returns the largest single integer.
+ min : () -> %
+ ++ min() returns the smallest single integer.
+
+ -- bit operations
+ "not": % -> %
+ ++ not(n) returns the bit-by-bit logical {\em not} of the single integer n.
+ "~" : % -> %
+ ++ ~ n returns the bit-by-bit logical {\em not } of the single integer n.
+ "/\": (%, %) -> %
+ ++ n /\ m returns the bit-by-bit logical {\em and} of
+ ++ the single integers n and m.
+ "\/" : (%, %) -> %
+ ++ n \/ m returns the bit-by-bit logical {\em or} of
+ ++ the single integers n and m.
+ "xor": (%, %) -> %
+ ++ xor(n,m) returns the bit-by-bit logical {\em xor} of
+ ++ the single integers n and m.
+ Not : % -> %
+ ++ Not(n) returns the bit-by-bit logical {\em not} of the single integer n.
+ And : (%,%) -> %
+ ++ And(n,m) returns the bit-by-bit logical {\em and} of
+ ++ the single integers n and m.
+ Or : (%,%) -> %
+ ++ Or(n,m) returns the bit-by-bit logical {\em or} of
+ ++ the single integers n and m.
+
+ == add
+
+ seed : % := 1$Lisp -- for random()
+ MAXINT ==> MOST_-POSITIVE_-FIXNUM$Lisp
+ MININT ==> MOST_-NEGATIVE_-FIXNUM$Lisp
+ BASE ==> 67108864$Lisp -- 2**26
+ MULTIPLIER ==> 314159269$Lisp -- from Knuth's table
+ MODULUS ==> 2147483647$Lisp -- 2**31-1
+
+ writeOMSingleInt(dev: OpenMathDevice, x: %): Void ==
+ if x < 0 then
+ OMputApp(dev)
+ OMputSymbol(dev, "arith1", "unary_minus")
+ OMputInteger(dev, convert(-x))
+ OMputEndApp(dev)
+ else
+ OMputInteger(dev, convert(x))
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMSingleInt(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMSingleInt(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMSingleInt(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMSingleInt(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ reducedSystem m == m pretend Matrix(Integer)
+ coerce(x):OutputForm == (convert(x)@Integer)::OutputForm
+ convert(x:%):Integer == x pretend Integer
+ i:Integer * y:% == i::% * y
+ 0 == 0$Lisp
+ 1 == 1$Lisp
+ base() == 2$Lisp
+ max() == MAXINT
+ min() == MININT
+ x = y == EQL(x,y)$Lisp
+ _~ x == LOGNOT(x)$Lisp
+ not(x) == LOGNOT(x)$Lisp
+ _/_\(x,y) == LOGAND(x,y)$Lisp
+ _\_/(x,y) == LOGIOR(x,y)$Lisp
+ Not(x) == LOGNOT(x)$Lisp
+ And(x,y) == LOGAND(x,y)$Lisp
+ Or(x,y) == LOGIOR(x,y)$Lisp
+ xor(x,y) == LOGXOR(x,y)$Lisp
+ x < y == QSLESSP(x,y)$Lisp
+ inc x == QSADD1(x)$Lisp
+ dec x == QSSUB1(x)$Lisp
+ - x == QSMINUS(x)$Lisp
+ x + y == QSPLUS(x,y)$Lisp
+ x:% - y:% == QSDIFFERENCE(x,y)$Lisp
+ x:% * y:% == QSTIMES(x,y)$Lisp
+ x:% ** n:NonNegativeInteger == ((EXPT(x, n)$Lisp) pretend Integer)::%
+ x quo y == QSQUOTIENT(x,y)$Lisp
+ x rem y == QSREMAINDER(x,y)$Lisp
+ divide(x, y) == CONS(QSQUOTIENT(x,y)$Lisp,QSREMAINDER(x,y)$Lisp)$Lisp
+ gcd(x,y) == GCD(x,y)$Lisp
+ abs(x) == QSABSVAL(x)$Lisp
+ odd?(x) == QSODDP(x)$Lisp
+ zero?(x) == QSZEROP(x)$Lisp
+-- one?(x) == ONEP(x)$Lisp
+ one?(x) == x = 1
+ max(x,y) == QSMAX(x,y)$Lisp
+ min(x,y) == QSMIN(x,y)$Lisp
+ hash(x) == HASHEQ(x)$Lisp
+ length(x) == INTEGER_-LENGTH(x)$Lisp
+ shift(x,n) == QSLEFTSHIFT(x,n)$Lisp
+ mulmod(a,b,p) == QSMULTMOD(a,b,p)$Lisp
+ addmod(a,b,p) == QSADDMOD(a,b,p)$Lisp
+ submod(a,b,p) == QSDIFMOD(a,b,p)$Lisp
+ negative?(x) == QSMINUSP$Lisp x
+
+
+ reducedSystem(m, v) ==
+ [m pretend Matrix(Integer), v pretend Vector(Integer)]
+
+ positiveRemainder(x,n) ==
+ r := QSREMAINDER(x,n)$Lisp
+ QSMINUSP(r)$Lisp =>
+ QSMINUSP(n)$Lisp => QSDIFFERENCE(x, n)$Lisp
+ QSPLUS(r, n)$Lisp
+ r
+
+ coerce(x:Integer):% ==
+ (x <= max pretend Integer) and (x >= min pretend Integer) =>
+ x pretend %
+ error "integer too large to represent in a machine word"
+
+ random() ==
+ seed := REMAINDER(TIMES(MULTIPLIER,seed)$Lisp,MODULUS)$Lisp
+ REMAINDER(seed,BASE)$Lisp
+
+ random(n) == RANDOM(n)$Lisp
+
+ UCA ==> Record(unit:%,canonical:%,associate:%)
+ unitNormal x ==
+ x < 0 => [-1,-x,-1]$UCA
+ [1,x,1]$UCA
+
+)bo $noSubsets := false
+
+@
+\section{SINT.lsp BOOTSTRAP}
+<<SINT.lsp BOOTSTRAP>>=
+
+(/VERSIONCHECK 2)
+
+(DEFUN |SINT;writeOMSingleInt| (|dev| |x| $)
+ (SEQ
+ (COND
+ ((QSLESSP |x| 0)
+ (SEQ
+ (SPADCALL |dev| (QREFELT $ 9))
+ (SPADCALL |dev| "arith1" "unaryminus" (QREFELT $ 11))
+ (SPADCALL |dev| (QSMINUS |x|) (QREFELT $ 13))
+ (EXIT (SPADCALL |dev| (QREFELT $ 14)))))
+ ((QUOTE T) (SPADCALL |dev| |x| (QREFELT $ 13))))))
+
+(DEFUN |SINT;OMwrite;$S;2| (|x| $)
+ (PROG (|sp| |dev| |s|)
+ (RETURN
+ (SEQ
+ (LETT |s| "" |SINT;OMwrite;$S;2|)
+ (LETT |sp| (OM-STRINGTOSTRINGPTR |s|) |SINT;OMwrite;$S;2|)
+ (LETT |dev|
+ (SPADCALL |sp| (SPADCALL (QREFELT $ 16)) (QREFELT $ 17))
+ |SINT;OMwrite;$S;2|)
+ (SPADCALL |dev| (QREFELT $ 18))
+ (|SINT;writeOMSingleInt| |dev| |x| $)
+ (SPADCALL |dev| (QREFELT $ 19))
+ (SPADCALL |dev| (QREFELT $ 20))
+ (LETT |s| (OM-STRINGPTRTOSTRING |sp|) |SINT;OMwrite;$S;2|)
+ (EXIT |s|)))))
+
+(DEFUN |SINT;OMwrite;$BS;3| (|x| |wholeObj| $)
+ (PROG (|sp| |dev| |s|)
+ (RETURN
+ (SEQ
+ (LETT |s| "" |SINT;OMwrite;$BS;3|)
+ (LETT |sp| (OM-STRINGTOSTRINGPTR |s|) |SINT;OMwrite;$BS;3|)
+ (LETT |dev|
+ (SPADCALL |sp| (SPADCALL (QREFELT $ 16)) (QREFELT $ 17))
+ |SINT;OMwrite;$BS;3|)
+ (COND (|wholeObj| (SPADCALL |dev| (QREFELT $ 18))))
+ (|SINT;writeOMSingleInt| |dev| |x| $)
+ (COND (|wholeObj| (SPADCALL |dev| (QREFELT $ 19))))
+ (SPADCALL |dev| (QREFELT $ 20))
+ (LETT |s| (OM-STRINGPTRTOSTRING |sp|) |SINT;OMwrite;$BS;3|)
+ (EXIT |s|)))))
+
+(DEFUN |SINT;OMwrite;Omd$V;4| (|dev| |x| $)
+ (SEQ
+ (SPADCALL |dev| (QREFELT $ 18))
+ (|SINT;writeOMSingleInt| |dev| |x| $)
+ (EXIT (SPADCALL |dev| (QREFELT $ 19)))))
+
+(DEFUN |SINT;OMwrite;Omd$BV;5| (|dev| |x| |wholeObj| $)
+ (SEQ
+ (COND (|wholeObj| (SPADCALL |dev| (QREFELT $ 18))))
+ (|SINT;writeOMSingleInt| |dev| |x| $)
+ (EXIT (COND (|wholeObj| (SPADCALL |dev| (QREFELT $ 19)))))))
+
+(PUT
+ (QUOTE |SINT;reducedSystem;MM;6|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|m|) |m|)))
+
+(DEFUN |SINT;reducedSystem;MM;6| (|m| $) |m|)
+
+(DEFUN |SINT;coerce;$Of;7| (|x| $)
+ (SPADCALL |x| (QREFELT $ 30)))
+
+(PUT
+ (QUOTE |SINT;convert;$I;8|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM (|x|) |x|)))
+
+(DEFUN |SINT;convert;$I;8| (|x| $) |x|)
+
+(DEFUN |SINT;*;I2$;9| (|i| |y| $)
+ (QSTIMES (SPADCALL |i| (QREFELT $ 33)) |y|))
+
+(PUT
+ (QUOTE |SINT;Zero;$;10|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL 0)))
+
+(DEFUN |SINT;Zero;$;10| ($) 0)
+
+(PUT
+ (QUOTE |SINT;One;$;11|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL 1)))
+
+(DEFUN |SINT;One;$;11| ($) 1)
+
+(PUT
+ (QUOTE |SINT;base;$;12|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL 2)))
+
+(DEFUN |SINT;base;$;12| ($) 2)
+
+(PUT
+ (QUOTE |SINT;max;$;13|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL MOST-POSITIVE-FIXNUM)))
+
+(DEFUN |SINT;max;$;13| ($) MOST-POSITIVE-FIXNUM)
+
+(PUT
+ (QUOTE |SINT;min;$;14|)
+ (QUOTE |SPADreplace|)
+ (QUOTE (XLAM NIL MOST-NEGATIVE-FIXNUM)))
+
+(DEFUN |SINT;min;$;14| ($) MOST-NEGATIVE-FIXNUM)
+
+(PUT
+ (QUOTE |SINT;=;2$B;15|)
+ (QUOTE |SPADreplace|)
+ (QUOTE EQL))
+
+(DEFUN |SINT;=;2$B;15| (|x| |y| $)
+ (EQL |x| |y|))
+
+(PUT
+ (QUOTE |SINT;~;2$;16|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGNOT))
+
+(DEFUN |SINT;~;2$;16| (|x| $)
+ (LOGNOT |x|))
+
+(PUT
+ (QUOTE |SINT;not;2$;17|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGNOT))
+
+(DEFUN |SINT;not;2$;17| (|x| $)
+ (LOGNOT |x|))
+
+(PUT
+ (QUOTE |SINT;/\\;3$;18|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGAND))
+
+(DEFUN |SINT;/\\;3$;18| (|x| |y| $)
+ (LOGAND |x| |y|))
+
+(PUT
+ (QUOTE |SINT;\\/;3$;19|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGIOR))
+
+(DEFUN |SINT;\\/;3$;19| (|x| |y| $)
+ (LOGIOR |x| |y|))
+
+(PUT
+ (QUOTE |SINT;Not;2$;20|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGNOT))
+
+(DEFUN |SINT;Not;2$;20| (|x| $)
+ (LOGNOT |x|))
+
+(PUT
+ (QUOTE |SINT;And;3$;21|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGAND))
+
+(DEFUN |SINT;And;3$;21| (|x| |y| $)
+ (LOGAND |x| |y|))
+
+(PUT
+ (QUOTE |SINT;Or;3$;22|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGIOR))
+
+(DEFUN |SINT;Or;3$;22| (|x| |y| $)
+ (LOGIOR |x| |y|))
+
+(PUT
+ (QUOTE |SINT;xor;3$;23|)
+ (QUOTE |SPADreplace|)
+ (QUOTE LOGXOR))
+
+(DEFUN |SINT;xor;3$;23| (|x| |y| $)
+ (LOGXOR |x| |y|))
+
+(PUT
+ (QUOTE |SINT;<;2$B;24|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSLESSP))
+
+(DEFUN |SINT;<;2$B;24| (|x| |y| $)
+ (QSLESSP |x| |y|))
+
+(PUT
+ (QUOTE |SINT;inc;2$;25|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSADD1))
+
+(DEFUN |SINT;inc;2$;25| (|x| $)
+ (QSADD1 |x|))
+
+(PUT
+ (QUOTE |SINT;dec;2$;26|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSSUB1))
+
+(DEFUN |SINT;dec;2$;26| (|x| $)
+ (QSSUB1 |x|))
+
+(PUT
+ (QUOTE |SINT;-;2$;27|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSMINUS))
+
+(DEFUN |SINT;-;2$;27| (|x| $)
+ (QSMINUS |x|))
+
+(PUT
+ (QUOTE |SINT;+;3$;28|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSPLUS))
+
+(DEFUN |SINT;+;3$;28| (|x| |y| $)
+ (QSPLUS |x| |y|))
+
+(PUT
+ (QUOTE |SINT;-;3$;29|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSDIFFERENCE))
+
+(DEFUN |SINT;-;3$;29| (|x| |y| $)
+ (QSDIFFERENCE |x| |y|))
+
+(PUT
+ (QUOTE |SINT;*;3$;30|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSTIMES))
+
+(DEFUN |SINT;*;3$;30| (|x| |y| $)
+ (QSTIMES |x| |y|))
+
+(DEFUN |SINT;**;$Nni$;31| (|x| |n| $)
+ (SPADCALL (EXPT |x| |n|) (QREFELT $ 33)))
+
+(PUT
+ (QUOTE |SINT;quo;3$;32|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSQUOTIENT))
+
+(DEFUN |SINT;quo;3$;32| (|x| |y| $)
+ (QSQUOTIENT |x| |y|))
+
+(PUT
+ (QUOTE |SINT;rem;3$;33|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSREMAINDER))
+
+(DEFUN |SINT;rem;3$;33| (|x| |y| $)
+ (QSREMAINDER |x| |y|))
+
+(DEFUN |SINT;divide;2$R;34| (|x| |y| $)
+ (CONS (QSQUOTIENT |x| |y|) (QSREMAINDER |x| |y|)))
+
+(PUT (QUOTE |SINT;gcd;3$;35|)
+ (QUOTE |SPADreplace|) (QUOTE GCD))
+
+(DEFUN |SINT;gcd;3$;35| (|x| |y| $)
+ (GCD |x| |y|))
+
+(PUT
+ (QUOTE |SINT;abs;2$;36|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSABSVAL))
+
+(DEFUN |SINT;abs;2$;36| (|x| $)
+ (QSABSVAL |x|))
+
+(PUT
+ (QUOTE |SINT;odd?;$B;37|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSODDP))
+
+(DEFUN |SINT;odd?;$B;37| (|x| $)
+ (QSODDP |x|))
+
+(PUT
+ (QUOTE |SINT;zero?;$B;38|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSZEROP))
+
+(DEFUN |SINT;zero?;$B;38| (|x| $)
+ (QSZEROP |x|))
+
+(PUT
+ (QUOTE |SINT;max;3$;39|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSMAX))
+
+(DEFUN |SINT;max;3$;39| (|x| |y| $)
+ (QSMAX |x| |y|))
+
+(PUT
+ (QUOTE |SINT;min;3$;40|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSMIN))
+
+(DEFUN |SINT;min;3$;40| (|x| |y| $)
+ (QSMIN |x| |y|))
+
+(PUT
+ (QUOTE |SINT;hash;2$;41|)
+ (QUOTE |SPADreplace|)
+ (QUOTE HASHEQ))
+
+(DEFUN |SINT;hash;2$;41| (|x| $)
+ (HASHEQ |x|))
+
+(PUT
+ (QUOTE |SINT;length;2$;42|)
+ (QUOTE |SPADreplace|)
+ (QUOTE INTEGER-LENGTH))
+
+(DEFUN |SINT;length;2$;42| (|x| $)
+ (INTEGER-LENGTH |x|))
+
+(PUT
+ (QUOTE |SINT;shift;3$;43|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSLEFTSHIFT))
+
+(DEFUN |SINT;shift;3$;43| (|x| |n| $)
+ (QSLEFTSHIFT |x| |n|))
+
+(PUT
+ (QUOTE |SINT;mulmod;4$;44|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSMULTMOD))
+
+(DEFUN |SINT;mulmod;4$;44| (|a| |b| |p| $)
+ (QSMULTMOD |a| |b| |p|))
+
+(PUT
+ (QUOTE |SINT;addmod;4$;45|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSADDMOD))
+
+(DEFUN |SINT;addmod;4$;45| (|a| |b| |p| $)
+ (QSADDMOD |a| |b| |p|))
+
+(PUT
+ (QUOTE |SINT;submod;4$;46|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSDIFMOD))
+
+(DEFUN |SINT;submod;4$;46| (|a| |b| |p| $)
+ (QSDIFMOD |a| |b| |p|))
+
+(PUT
+ (QUOTE |SINT;negative?;$B;47|)
+ (QUOTE |SPADreplace|)
+ (QUOTE QSMINUSP))
+
+(DEFUN |SINT;negative?;$B;47| (|x| $)
+ (QSMINUSP |x|))
+
+(PUT
+ (QUOTE |SINT;reducedSystem;MVR;48|)
+ (QUOTE |SPADreplace|)
+ (QUOTE CONS))
+
+(DEFUN |SINT;reducedSystem;MVR;48| (|m| |v| $)
+ (CONS |m| |v|))
+
+(DEFUN |SINT;positiveRemainder;3$;49| (|x| |n| $)
+ (PROG (|r|)
+ (RETURN
+ (SEQ
+ (LETT |r| (QSREMAINDER |x| |n|) |SINT;positiveRemainder;3$;49|)
+ (EXIT
+ (COND
+ ((QSMINUSP |r|)
+ (COND
+ ((QSMINUSP |n|) (QSDIFFERENCE |x| |n|))
+ ((QUOTE T) (QSPLUS |r| |n|))))
+ ((QUOTE T) |r|)))))))
+
+(DEFUN |SINT;coerce;I$;50| (|x| $)
+ (SEQ
+ (COND
+ ((NULL (< MOST-POSITIVE-FIXNUM |x|))
+ (COND ((NULL (< |x| MOST-NEGATIVE-FIXNUM)) (EXIT |x|)))))
+ (EXIT (|error| "integer too large to represent in a machine word"))))
+
+(DEFUN |SINT;random;$;51| ($)
+ (SEQ
+ (SETELT $ 6 (REMAINDER (TIMES 314159269 (QREFELT $ 6)) 2147483647))
+ (EXIT (REMAINDER (QREFELT $ 6) 67108864))))
+
+(PUT
+ (QUOTE |SINT;random;2$;52|)
+ (QUOTE |SPADreplace|)
+ (QUOTE RANDOM))
+
+(DEFUN |SINT;random;2$;52| (|n| $)
+ (RANDOM |n|))
+
+(DEFUN |SINT;unitNormal;$R;53| (|x| $)
+ (COND
+ ((QSLESSP |x| 0) (VECTOR -1 (QSMINUS |x|) -1))
+ ((QUOTE T) (VECTOR 1 |x| 1))))
+
+(DEFUN |SingleInteger| NIL
+ (PROG NIL
+ (RETURN
+ (PROG (#0=#:G1358)
+ (RETURN
+ (COND
+ ((LETT #0#
+ (HGET |$ConstructorCache| (QUOTE |SingleInteger|))
+ |SingleInteger|)
+ (|CDRwithIncrement| (CDAR #0#)))
+ ((QUOTE T)
+ (UNWIND-PROTECT
+ (PROG1
+ (CDDAR
+ (HPUT
+ |$ConstructorCache|
+ (QUOTE |SingleInteger|)
+ (LIST (CONS NIL (CONS 1 (|SingleInteger;|))))))
+ (LETT #0# T |SingleInteger|))
+ (COND
+ ((NOT #0#)
+ (HREM |$ConstructorCache|
+ (QUOTE |SingleInteger|))))))))))))
+
+(DEFUN |SingleInteger;| NIL
+ (PROG (|dv$| $ |pv$|)
+ (RETURN
+ (PROGN
+ (LETT |dv$| (QUOTE (|SingleInteger|)) . #0=(|SingleInteger|))
+ (LETT $ (GETREFV 103) . #0#)
+ (QSETREFV $ 0 |dv$|)
+ (QSETREFV $ 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #0#))
+ (|haddProp| |$ConstructorCache| (QUOTE |SingleInteger|) NIL (CONS 1 $))
+ (|stuffDomainSlots| $) (QSETREFV $ 6 1) $))))
+
+(MAKEPROP
+ (QUOTE |SingleInteger|)
+ (QUOTE |infovec|)
+ (LIST
+ (QUOTE
+ #(NIL NIL NIL NIL NIL NIL
+ (QUOTE |seed|)
+ (|Void|)
+ (|OpenMathDevice|)
+ (0 . |OMputApp|)
+ (|String|)
+ (5 . |OMputSymbol|)
+ (|Integer|)
+ (12 . |OMputInteger|)
+ (18 . |OMputEndApp|)
+ (|OpenMathEncoding|)
+ (23 . |OMencodingXML|)
+ (27 . |OMopenString|)
+ (33 . |OMputObject|)
+ (38 . |OMputEndObject|)
+ (43 . |OMclose|)
+ |SINT;OMwrite;$S;2|
+ (|Boolean|)
+ |SINT;OMwrite;$BS;3|
+ |SINT;OMwrite;Omd$V;4|
+ |SINT;OMwrite;Omd$BV;5|
+ (|Matrix| 12)
+ (|Matrix| $)
+ |SINT;reducedSystem;MM;6|
+ (|OutputForm|)
+ (48 . |coerce|)
+ |SINT;coerce;$Of;7|
+ |SINT;convert;$I;8|
+ (53 . |coerce|)
+ |SINT;*;I2$;9|
+ (CONS IDENTITY (FUNCALL (|dispatchFunction| |SINT;Zero;$;10|) $))
+ (CONS IDENTITY (FUNCALL (|dispatchFunction| |SINT;One;$;11|) $))
+ |SINT;base;$;12|
+ |SINT;max;$;13|
+ |SINT;min;$;14|
+ |SINT;=;2$B;15|
+ |SINT;~;2$;16|
+ |SINT;not;2$;17|
+ |SINT;/\\;3$;18|
+ |SINT;\\/;3$;19|
+ |SINT;Not;2$;20|
+ |SINT;And;3$;21|
+ |SINT;Or;3$;22|
+ |SINT;xor;3$;23|
+ |SINT;<;2$B;24|
+ |SINT;inc;2$;25|
+ |SINT;dec;2$;26|
+ |SINT;-;2$;27|
+ |SINT;+;3$;28|
+ |SINT;-;3$;29|
+ |SINT;*;3$;30|
+ (|NonNegativeInteger|)
+ |SINT;**;$Nni$;31|
+ |SINT;quo;3$;32|
+ |SINT;rem;3$;33|
+ (|Record| (|:| |quotient| $) (|:| |remainder| $))
+ |SINT;divide;2$R;34|
+ |SINT;gcd;3$;35|
+ |SINT;abs;2$;36|
+ |SINT;odd?;$B;37|
+ |SINT;zero?;$B;38|
+ |SINT;max;3$;39|
+ |SINT;min;3$;40|
+ |SINT;hash;2$;41|
+ |SINT;length;2$;42|
+ |SINT;shift;3$;43|
+ |SINT;mulmod;4$;44|
+ |SINT;addmod;4$;45|
+ |SINT;submod;4$;46|
+ |SINT;negative?;$B;47|
+ (|Record| (|:| |mat| 26) (|:| |vec| (|Vector| 12)))
+ (|Vector| $)
+ |SINT;reducedSystem;MVR;48|
+ |SINT;positiveRemainder;3$;49|
+ |SINT;coerce;I$;50|
+ |SINT;random;$;51|
+ |SINT;random;2$;52|
+ (|Record| (|:| |unit| $) (|:| |canonical| $) (|:| |associate| $))
+ |SINT;unitNormal;$R;53|
+ (|Union| 85 (QUOTE "failed"))
+ (|Fraction| 12)
+ (|Union| $ (QUOTE "failed"))
+ (|Float|)
+ (|DoubleFloat|)
+ (|Pattern| 12)
+ (|PatternMatchResult| 12 $)
+ (|InputForm|)
+ (|Union| 12 (QUOTE "failed"))
+ (|Record| (|:| |coef| 94) (|:| |generator| $))
+ (|List| $)
+ (|Union| 94 (QUOTE "failed"))
+ (|Record| (|:| |coef1| $) (|:| |coef2| $) (|:| |generator| $))
+ (|Record| (|:| |coef1| $) (|:| |coef2| $))
+ (|Union| 97 (QUOTE "failed"))
+ (|Factored| $)
+ (|SparseUnivariatePolynomial| $)
+ (|PositiveInteger|)
+ (|SingleInteger|)))
+ (QUOTE
+ #(~= 58 ~ 64 |zero?| 69 |xor| 74 |unitNormal| 80 |unitCanonical| 85
+ |unit?| 90 |symmetricRemainder| 95 |subtractIfCan| 101 |submod| 107
+ |squareFreePart| 114 |squareFree| 119 |sizeLess?| 124 |sign| 130
+ |shift| 135 |sample| 141 |retractIfCan| 145 |retract| 150 |rem| 155
+ |reducedSystem| 161 |recip| 172 |rationalIfCan| 177 |rational?| 182
+ |rational| 187 |random| 192 |quo| 201 |principalIdeal| 207
+ |prime?| 212 |powmod| 217 |positiveRemainder| 224 |positive?| 230
+ |permutation| 235 |patternMatch| 241 |one?| 248 |odd?| 253 |not| 258
+ |nextItem| 263 |negative?| 268 |multiEuclidean| 273 |mulmod| 279
+ |min| 286 |max| 296 |mask| 306 |length| 311 |lcm| 316 |latex| 327
+ |invmod| 332 |init| 338 |inc| 342 |hash| 347 |gcdPolynomial| 357
+ |gcd| 363 |factorial| 374 |factor| 379 |extendedEuclidean| 384
+ |exquo| 397 |expressIdealMember| 403 |even?| 409 |euclideanSize| 414
+ |divide| 419 |differentiate| 425 |dec| 436 |copy| 441 |convert| 446
+ |coerce| 471 |characteristic| 491 |bit?| 495 |binomial| 501
+ |base| 507 |associates?| 511 |addmod| 517 |abs| 524 ^ 529 |\\/| 541
+ |Zero| 547 |Or| 551 |One| 557 |OMwrite| 561 |Not| 585 D 590
+ |And| 601 >= 607 > 613 = 619 <= 625 < 631 |/\\| 637 - 643 + 654
+ ** 660 * 672))
+ (QUOTE (
+ (|noetherian| . 0)
+ (|canonicalsClosed| . 0)
+ (|canonical| . 0)
+ (|canonicalUnitNormal| . 0)
+ (|multiplicativeValuation| . 0)
+ (|noZeroDivisors| . 0)
+ ((|commutative| "*") . 0)
+ (|rightUnitary| . 0)
+ (|leftUnitary| . 0)
+ (|unitsKnown| . 0)))
+ (CONS
+ (|makeByteWordVec2| 1
+ (QUOTE (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)))
+ (CONS
+ (QUOTE
+ #(|IntegerNumberSystem&| |EuclideanDomain&|
+ |UniqueFactorizationDomain&| NIL NIL |GcdDomain&|
+ |IntegralDomain&| |Algebra&| |Module&| NIL |Module&| NIL NIL
+ |Module&| NIL |DifferentialRing&| |OrderedRing&| NIL |Module&|
+ NIL |Module&| NIL NIL NIL NIL NIL NIL |Ring&| NIL NIL NIL NIL
+ NIL NIL NIL NIL NIL NIL NIL NIL NIL |AbelianGroup&| NIL NIL
+ |AbelianMonoid&| |Monoid&| NIL NIL NIL NIL |OrderedSet&|
+ |AbelianSemiGroup&| |SemiGroup&| |Logic&| NIL |SetCategory&| NIL
+ NIL NIL NIL |RetractableTo&| NIL NIL NIL |RetractableTo&| NIL NIL
+ NIL NIL NIL NIL |RetractableTo&| NIL |BasicType&| NIL))
+ (CONS
+ (QUOTE
+ #((|IntegerNumberSystem|) (|EuclideanDomain|)
+ (|UniqueFactorizationDomain|) (|PrincipalIdealDomain|)
+ (|OrderedIntegralDomain|) (|GcdDomain|) (|IntegralDomain|)
+ (|Algebra| $$) (|Module| 12) (|LinearlyExplicitRingOver| 12)
+ (|Module| #0=#:G1062) (|LinearlyExplicitRingOver| #0#)
+ (|CharacteristicZero|) (|Module| #1=#:G106217)
+ (|LinearlyExplicitRingOver| #1#) (|DifferentialRing|)
+ (|OrderedRing|) (|CommutativeRing|) (|Module| |t#1|)
+ (|EntireRing|) (|Module| $$) (|BiModule| 12 12)
+ (|BiModule| #0# #0#) (|BiModule| #1# #1#)
+ (|OrderedAbelianGroup|) (|BiModule| |t#1| |t#1|)
+ (|BiModule| $$ $$) (|Ring|) (|RightModule| 12)
+ (|LeftModule| 12) (|RightModule| #0#) (|LeftModule| #0#)
+ (|RightModule| #1#) (|LeftModule| #1#)
+ (|OrderedCancellationAbelianMonoid|) (|RightModule| |t#1|)
+ (|LeftModule| |t#1|) (|LeftModule| $$) (|Rng|)
+ (|RightModule| $$) (|OrderedAbelianMonoid|) (|AbelianGroup|)
+ (|OrderedAbelianSemiGroup|) (|CancellationAbelianMonoid|)
+ (|AbelianMonoid|) (|Monoid|) (|PatternMatchable| 12)
+ (|PatternMatchable| #:G1065) (|StepThrough|)
+ (|PatternMatchable| #:G106220) (|OrderedSet|)
+ (|AbelianSemiGroup|) (|SemiGroup|) (|Logic|) (|RealConstant|)
+ (|SetCategory|) (|OpenMath|) (|CoercibleTo| #:G82356)
+ (|ConvertibleTo| 89) (|ConvertibleTo| 91) (|RetractableTo| 12)
+ (|ConvertibleTo| 12) (|ConvertibleTo| #:G1064)
+ (|ConvertibleTo| #:G1063) (|RetractableTo| #:G1061)
+ (|ConvertibleTo| #:G1060) (|ConvertibleTo| 87)
+ (|ConvertibleTo| 88) (|CombinatorialFunctionCategory|)
+ (|ConvertibleTo| #:G106219) (|ConvertibleTo| #:G106218)
+ (|RetractableTo| #:G106216) (|ConvertibleTo| #:G106215)
+ (|BasicType|) (|CoercibleTo| 29)))
+ (|makeByteWordVec2| 102
+ (QUOTE
+ (1 8 7 0 9 3 8 7 0 10 10 11 2 8 7 0 12 13 1 8 7 0 14 0 15 0
+ 16 2 8 0 10 15 17 1 8 7 0 18 1 8 7 0 19 1 8 7 0 20 1 12 29
+ 0 30 1 0 0 12 33 2 0 22 0 0 1 1 0 0 0 41 1 0 22 0 65 2 0 0
+ 0 0 48 1 0 82 0 83 1 0 0 0 1 1 0 22 0 1 2 0 0 0 0 1 2 0 86
+ 0 0 1 3 0 0 0 0 0 73 1 0 0 0 1 1 0 99 0 1 2 0 22 0 0 1 1 0
+ 12 0 1 2 0 0 0 0 70 0 0 0 1 1 0 92 0 1 1 0 12 0 1 2 0 0 0 0
+ 59 1 0 26 27 28 2 0 75 27 76 77 1 0 86 0 1 1 0 84 0 1 1 0
+ 22 0 1 1 0 85 0 1 1 0 0 0 81 0 0 0 80 2 0 0 0 0 58 1 0 93
+ 94 1 1 0 22 0 1 3 0 0 0 0 0 1 2 0 0 0 0 78 1 0 22 0 1 2 0 0
+ 0 0 1 3 0 90 0 89 90 1 1 0 22 0 1 1 0 22 0 64 1 0 0 0 42 1
+ 0 86 0 1 1 0 22 0 74 2 0 95 94 0 1 3 0 0 0 0 0 71 0 0 0 39
+ 2 0 0 0 0 67 0 0 0 38 2 0 0 0 0 66 1 0 0 0 1 1 0 0 0 69 1 0
+ 0 94 1 2 0 0 0 0 1 1 0 10 0 1 2 0 0 0 0 1 0 0 0 1 1 0 0 0 50
+ 1 0 0 0 68 1 0 102 0 1 2 0 100 100 100 1 1 0 0 94 1 2 0 0 0
+ 0 62 1 0 0 0 1 1 0 99 0 1 2 0 96 0 0 1 3 0 98 0 0 0 1 2 0 86
+ 0 0 1 2 0 95 94 0 1 1 0 22 0 1 1 0 56 0 1 2 0 60 0 0 61 1 0
+ 0 0 1 2 0 0 0 56 1 1 0 0 0 51 1 0 0 0 1 1 0 87 0 1 1 0 88 0
+ 1 1 0 89 0 1 1 0 91 0 1 1 0 12 0 32 1 0 0 12 79 1 0 0 0 1 1
+ 0 0 12 79 1 0 29 0 31 0 0 56 1 2 0 22 0 0 1 2 0 0 0 0 1 0 0
+ 0 37 2 0 22 0 0 1 3 0 0 0 0 0 72 1 0 0 0 63 2 0 0 0 56 1 2 0
+ 0 0 101 1 2 0 0 0 0 44 0 0 0 35 2 0 0 0 0 47 0 0 0 36 3 0 7
+ 8 0 22 25 2 0 10 0 22 23 2 0 7 8 0 24 1 0 10 0 21 1 0 0 0 45
+ 1 0 0 0 1 2 0 0 0 56 1 2 0 0 0 0 46 2 0 22 0 0 1 2 0 22 0 0
+ 1 2 0 22 0 0 40 2 0 22 0 0 1 2 0 22 0 0 49 2 0 0 0 0 43 1 0
+ 0 0 52 2 0 0 0 0 54 2 0 0 0 0 53 2 0 0 0 56 57 2 0 0 0 101 1
+ 2 0 0 0 0 55 2 0 0 12 0 34 2 0 0 56 0 1 2 0 0 101 0 1))))))
+ (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |SingleInteger|) (QUOTE NILADIC) T)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category INS IntegerNumberSystem>>
+<<domain SINT SingleInteger>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sign.spad.pamphlet b/src/algebra/sign.spad.pamphlet
new file mode 100644
index 00000000..a9c3a5c3
--- /dev/null
+++ b/src/algebra/sign.spad.pamphlet
@@ -0,0 +1,392 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sign.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package TOOLSIGN ToolsForSign}
+<<package TOOLSIGN ToolsForSign>>=
+)abbrev package TOOLSIGN ToolsForSign
+++ Tools for the sign finding utilities
+++ Author: Manuel Bronstein
+++ Date Created: 25 August 1989
+++ Date Last Updated: 26 November 1991
+++ Description: Tools for the sign finding utilities.
+ToolsForSign(R:Ring): with
+ sign : R -> Union(Integer, "failed")
+ ++ sign(r) \undocumented
+ nonQsign : R -> Union(Integer, "failed")
+ ++ nonQsign(r) \undocumented
+ direction: String -> Integer
+ ++ direction(s) \undocumented
+ == add
+
+ if R is AlgebraicNumber then
+ nonQsign r ==
+ sign((r pretend AlgebraicNumber)::Expression(
+ Integer))$ElementaryFunctionSign(Integer, Expression Integer)
+ else
+ nonQsign r == "failed"
+
+ if R has RetractableTo Fraction Integer then
+ sign r ==
+ (u := retractIfCan(r)@Union(Fraction Integer, "failed"))
+ case Fraction(Integer) => sign(u::Fraction Integer)
+ nonQsign r
+
+ else
+ if R has RetractableTo Integer then
+ sign r ==
+ (u := retractIfCan(r)@Union(Integer, "failed"))
+ case "failed" => "failed"
+ sign(u::Integer)
+
+ else
+ sign r ==
+ zero? r => 0
+-- one? r => 1
+ r = 1 => 1
+ r = -1 => -1
+ "failed"
+
+ direction st ==
+ st = "right" => 1
+ st = "left" => -1
+ error "Unknown option"
+
+@
+\section{package INPSIGN InnerPolySign}
+<<package INPSIGN InnerPolySign>>=
+)abbrev package INPSIGN InnerPolySign
+--%% InnerPolySign
+++ Author: Manuel Bronstein
+++ Date Created: 23 Aug 1989
+++ Date Last Updated: 19 Feb 1990
+++ Description:
+++ Find the sign of a polynomial around a point or infinity.
+InnerPolySign(R, UP): Exports == Implementation where
+ R : Ring
+ UP: UnivariatePolynomialCategory R
+
+ U ==> Union(Integer, "failed")
+
+ Exports ==> with
+ signAround: (UP, Integer, R -> U) -> U
+ ++ signAround(u,i,f) \undocumented
+ signAround: (UP, R, Integer, R -> U) -> U
+ ++ signAround(u,r,i,f) \undocumented
+ signAround: (UP, R, R -> U) -> U
+ ++ signAround(u,r,f) \undocumented
+
+ Implementation ==> add
+ signAround(p:UP, x:R, rsign:R -> U) ==
+ (ur := signAround(p, x, 1, rsign)) case "failed" => "failed"
+ (ul := signAround(p, x, -1, rsign)) case "failed" => "failed"
+ (ur::Integer) = (ul::Integer) => ur
+ "failed"
+
+ signAround(p, x, dir, rsign) ==
+ zero? p => 0
+ zero?(r := p x) =>
+ (u := signAround(differentiate p, x, dir, rsign)) case "failed"
+ => "failed"
+ dir * u::Integer
+ rsign r
+
+ signAround(p:UP, dir:Integer, rsign:R -> U) ==
+ zero? p => 0
+ (u := rsign leadingCoefficient p) case "failed" => "failed"
+ (dir > 0) or (even? degree p) => u::Integer
+ - (u::Integer)
+
+@
+\section{package SIGNRF RationalFunctionSign}
+<<package SIGNRF RationalFunctionSign>>=
+)abbrev package SIGNRF RationalFunctionSign
+--%% RationalFunctionSign
+++ Author: Manuel Bronstein
+++ Date Created: 23 August 1989
+++ Date Last Updated: 26 November 1991
+++ Description:
+++ Find the sign of a rational function around a point or infinity.
+RationalFunctionSign(R:GcdDomain): Exports == Implementation where
+ SE ==> Symbol
+ P ==> Polynomial R
+ RF ==> Fraction P
+ ORF ==> OrderedCompletion RF
+ UP ==> SparseUnivariatePolynomial RF
+ U ==> Union(Integer, "failed")
+ SGN ==> ToolsForSign(R)
+
+ Exports ==> with
+ sign: RF -> U
+ ++ sign f returns the sign of f if it is constant everywhere.
+ sign: (RF, SE, ORF) -> U
+ ++ sign(f, x, a) returns the sign of f as x approaches \spad{a},
+ ++ from both sides if \spad{a} is finite.
+ sign: (RF, SE, RF, String) -> U
+ ++ sign(f, x, a, s) returns the sign of f as x nears \spad{a} from
+ ++ the left (below) if s is the string \spad{"left"},
+ ++ or from the right (above) if s is the string \spad{"right"}.
+
+ Implementation ==> add
+ import SGN
+ import InnerPolySign(RF, UP)
+ import PolynomialCategoryQuotientFunctions(IndexedExponents SE,
+ SE, R, P, RF)
+
+ psign : P -> U
+ sqfrSign : P -> U
+ termSign : P -> U
+ listSign : (List P, Integer) -> U
+ finiteSign: (Fraction UP, RF) -> U
+
+ sign f ==
+ (un := psign numer f) case "failed" => "failed"
+ (ud := psign denom f) case "failed" => "failed"
+ (un::Integer) * (ud::Integer)
+
+ finiteSign(g, a) ==
+ (ud := signAround(denom g, a, sign$%)) case "failed" => "failed"
+ (un := signAround(numer g, a, sign$%)) case "failed" => "failed"
+ (un::Integer) * (ud::Integer)
+
+ sign(f, x, a) ==
+ g := univariate(f, x)
+ zero?(n := whatInfinity a) => finiteSign(g, retract a)
+ (ud := signAround(denom g, n, sign$%)) case "failed" => "failed"
+ (un := signAround(numer g, n, sign$%)) case "failed" => "failed"
+ (un::Integer) * (ud::Integer)
+
+ sign(f, x, a, st) ==
+ (ud := signAround(denom(g := univariate(f, x)), a,
+ d := direction st, sign$%)) case "failed" => "failed"
+ (un := signAround(numer g, a, d, sign$%)) case "failed" => "failed"
+ (un::Integer) * (ud::Integer)
+
+ psign p ==
+ (r := retractIfCan(p)@Union(R, "failed")) case R => sign(r::R)$SGN
+ (u := sign(retract(unit(s := squareFree p))@R)$SGN) case "failed" =>
+ "failed"
+ ans := u::Integer
+ for term in factors s | odd?(term.exponent) repeat
+ (u := sqfrSign(term.factor)) case "failed" => return "failed"
+ ans := ans * (u::Integer)
+ ans
+
+ sqfrSign p ==
+ (u := termSign first(l := monomials p)) case "failed" => "failed"
+ listSign(rest l, u::Integer)
+
+ listSign(l, s) ==
+ for term in l repeat
+ (u := termSign term) case "failed" => return "failed"
+ u::Integer ^= s => return "failed"
+ s
+
+ termSign term ==
+ for var in variables term repeat
+ odd? degree(term, var) => return "failed"
+ sign(leadingCoefficient term)$SGN
+
+@
+\section{package LIMITRF RationalFunctionLimitPackage}
+<<package LIMITRF RationalFunctionLimitPackage>>=
+)abbrev package LIMITRF RationalFunctionLimitPackage
+++ Computation of limits for rational functions
+++ Author: Manuel Bronstein
+++ Date Created: 4 October 1989
+++ Date Last Updated: 26 November 1991
+++ Description: Computation of limits for rational functions.
+++ Keywords: limit, rational function.
+RationalFunctionLimitPackage(R:GcdDomain):Exports==Implementation where
+ Z ==> Integer
+ P ==> Polynomial R
+ RF ==> Fraction P
+ EQ ==> Equation
+ ORF ==> OrderedCompletion RF
+ OPF ==> OnePointCompletion RF
+ UP ==> SparseUnivariatePolynomial RF
+ SE ==> Symbol
+ QF ==> Fraction SparseUnivariatePolynomial RF
+ Result ==> Union(ORF, "failed")
+ TwoSide ==> Record(leftHandLimit:Result, rightHandLimit:Result)
+ U ==> Union(ORF, TwoSide, "failed")
+ RFSGN ==> RationalFunctionSign(R)
+
+ Exports ==> with
+-- The following are the one we really want, but the interpreter cannot
+-- handle them...
+-- limit: (RF,EQ ORF) -> U
+-- ++ limit(f(x),x,a) computes the real two-sided limit lim(x -> a,f(x))
+
+-- complexLimit: (RF,EQ OPF) -> OPF
+-- ++ complexLimit(f(x),x,a) computes the complex limit lim(x -> a,f(x))
+
+-- ... so we replace them by the following 4:
+ limit: (RF,EQ OrderedCompletion P) -> U
+ ++ limit(f(x),x = a) computes the real two-sided limit
+ ++ of f as its argument x approaches \spad{a}.
+ limit: (RF,EQ RF) -> U
+ ++ limit(f(x),x = a) computes the real two-sided limit
+ ++ of f as its argument x approaches \spad{a}.
+ complexLimit: (RF,EQ OnePointCompletion P) -> OPF
+ ++ \spad{complexLimit(f(x),x = a)} computes the complex limit
+ ++ of \spad{f} as its argument x approaches \spad{a}.
+ complexLimit: (RF,EQ RF) -> OPF
+ ++ complexLimit(f(x),x = a) computes the complex limit
+ ++ of f as its argument x approaches \spad{a}.
+ limit: (RF,EQ RF,String) -> Result
+ ++ limit(f(x),x,a,"left") computes the real limit
+ ++ of f as its argument x approaches \spad{a} from the left;
+ ++ limit(f(x),x,a,"right") computes the corresponding limit as x
+ ++ approaches \spad{a} from the right.
+
+ Implementation ==> add
+ import ToolsForSign R
+ import InnerPolySign(RF, UP)
+ import RFSGN
+ import PolynomialCategoryQuotientFunctions(IndexedExponents SE,
+ SE, R, P, RF)
+
+ finiteComplexLimit: (QF, RF) -> OPF
+ finiteLimit : (QF, RF) -> U
+ fLimit : (Z, UP, RF, Z) -> Result
+
+-- These 2 should be exported, see comment above
+ locallimit : (RF, SE, ORF) -> U
+ locallimitcomplex: (RF, SE, OPF) -> OPF
+
+ limit(f:RF,eq:EQ RF) ==
+ (xx := retractIfCan(lhs eq)@Union(SE,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ x := xx :: SE; a := rhs eq
+ locallimit(f,x,a::ORF)
+
+ complexLimit(f:RF,eq:EQ RF) ==
+ (xx := retractIfCan(lhs eq)@Union(SE,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ x := xx :: SE; a := rhs eq
+ locallimitcomplex(f,x,a::OPF)
+
+ limit(f:RF,eq:EQ OrderedCompletion P) ==
+ (p := retractIfCan(lhs eq)@Union(P,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ (xx := retractIfCan(p)@Union(SE,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ x := xx :: SE
+ a := map(#1::RF,rhs eq)$OrderedCompletionFunctions2(P,RF)
+ locallimit(f,x,a)
+
+ complexLimit(f:RF,eq:EQ OnePointCompletion P) ==
+ (p := retractIfCan(lhs eq)@Union(P,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ (xx := retractIfCan(p)@Union(SE,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ x := xx :: SE
+ a := map(#1::RF,rhs eq)$OnePointCompletionFunctions2(P,RF)
+ locallimitcomplex(f,x,a)
+
+ fLimit(n, d, a, dir) ==
+ (s := signAround(d, a, dir, sign$RFSGN)) case "failed" => "failed"
+ n * (s::Z) * plusInfinity()
+
+ finiteComplexLimit(f, a) ==
+ zero?(n := (numer f) a) => 0
+ zero?(d := (denom f) a) => infinity()
+ (n / d)::OPF
+
+ finiteLimit(f, a) ==
+ zero?(n := (numer f) a) => 0
+ zero?(d := (denom f) a) =>
+ (s := sign(n)$RFSGN) case "failed" => "failed"
+ rhsl := fLimit(s::Z, denom f, a, 1)
+ lhsl := fLimit(s::Z, denom f, a, -1)
+ rhsl case "failed" =>
+ lhsl case "failed" => "failed"
+ [lhsl, rhsl]
+ lhsl case "failed" => [lhsl, rhsl]
+ rhsl::ORF = lhsl::ORF => lhsl::ORF
+ [lhsl, rhsl]
+ (n / d)::ORF
+
+ locallimit(f,x,a) ==
+ g := univariate(f, x)
+ zero?(n := whatInfinity a) => finiteLimit(g, retract a)
+ (dn := degree numer g) > (dd := degree denom g) =>
+ (sn := signAround(numer g, n, sign$RFSGN)) case "failed" => "failed"
+ (sd := signAround(denom g, n, sign$RFSGN)) case "failed" => "failed"
+ (sn::Z) * (sd::Z) * plusInfinity()
+ dn < dd => 0
+ ((leadingCoefficient numer g) / (leadingCoefficient denom g))::ORF
+
+ limit(f,eq,st) ==
+ (xx := retractIfCan(lhs eq)@Union(SE,"failed")) case "failed" =>
+ error "limit: left hand side must be a variable"
+ x := xx :: SE; a := rhs eq
+ zero?(n := (numer(g := univariate(f, x))) a) => 0
+ zero?(d := (denom g) a) =>
+ (s := sign(n)$RFSGN) case "failed" => "failed"
+ fLimit(s::Z, denom g, a, direction st)
+ (n / d)::ORF
+
+ locallimitcomplex(f,x,a) ==
+ g := univariate(f, x)
+ (r := retractIfCan(a)@Union(RF, "failed")) case RF =>
+ finiteComplexLimit(g, r::RF)
+ (dn := degree numer g) > (dd := degree denom g) => infinity()
+ dn < dd => 0
+ ((leadingCoefficient numer g) / (leadingCoefficient denom g))::OPF
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package TOOLSIGN ToolsForSign>>
+<<package INPSIGN InnerPolySign>>
+<<package SIGNRF RationalFunctionSign>>
+<<package LIMITRF RationalFunctionLimitPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/smith.spad.pamphlet b/src/algebra/smith.spad.pamphlet
new file mode 100644
index 00000000..8c89d9ef
--- /dev/null
+++ b/src/algebra/smith.spad.pamphlet
@@ -0,0 +1,284 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra smith.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SMITH SmithNormalForm}
+<<package SMITH SmithNormalForm>>=
+)abbrev package SMITH SmithNormalForm
+++ Author: Patrizia Gianni
+++ Date Created: October 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains: Matrix(R)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: matrix, canonical forms, linear algebra
+++ Examples:
+++ References:
+++ Description:
+++ \spadtype{SmithNormalForm} is a package
+++ which provides some standard canonical forms for matrices.
+
+SmithNormalForm(R,Row,Col,M) : Exports == Implementation where
+
+ R : EuclideanDomain
+ Row : FiniteLinearAggregate R
+ Col : FiniteLinearAggregate R
+ M : MatrixCategory(R,Row,Col)
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ HermiteForm ==> Record(Hermite:M,eqMat:M)
+ SmithForm ==> Record(Smith : M, leftEqMat : M, rightEqMat : M)
+ PartialV ==> Union(Col, "failed")
+ Both ==> Record(particular: PartialV, basis: List Col)
+
+ Exports == with
+ hermite : M -> M
+ ++ \spad{hermite(m)} returns the Hermite normal form of the
+ ++ matrix m.
+ completeHermite : M -> HermiteForm
+ ++ \spad{completeHermite} returns a record that contains
+ ++ the Hermite normal form H of the matrix and the equivalence matrix
+ ++ U such that U*m = H
+ smith : M -> M
+ ++ \spad{smith(m)} returns the Smith Normal form of the matrix m.
+ completeSmith : M -> SmithForm
+ ++ \spad{completeSmith} returns a record that contains
+ ++ the Smith normal form H of the matrix and the left and right
+ ++ equivalence matrices U and V such that U*m*v = H
+ diophantineSystem : (M,Col) -> Both
+ ++ \spad{diophantineSystem(A,B)} returns a particular integer solution and
+ ++ an integer basis of the equation \spad{AX = B}.
+
+ Implementation == add
+ MATCAT1 ==> MatrixCategoryFunctions2(R,Row,Col,M,QF,Row2,Col2,M2)
+ MATCAT2 ==> MatrixCategoryFunctions2(QF,Row2,Col2,M2,R,Row,Col,M)
+ QF ==> Fraction R
+ Row2 ==> Vector QF
+ Col2 ==> Vector QF
+ M2 ==> Matrix QF
+
+ ------ Local Functions -----
+ elRow1 : (M,I,I) -> M
+ elRow2 : (M,R,I,I) -> M
+ elColumn2 : (M,R,I,I) -> M
+ isDiagonal? : M -> Boolean
+ ijDivide : (SmithForm ,I,I) -> SmithForm
+ lastStep : SmithForm -> SmithForm
+ test1 : (M,Col,NNI) -> Union(NNI, "failed")
+ test2 : (M, Col,NNI,NNI) -> Union( Col, "failed")
+
+ -- inconsistent system : case 0 = c --
+ test1(sm:M,b:Col,m1 : NNI) : Union(NNI , "failed") ==
+ km:=m1
+ while zero? sm(km,km) repeat
+ if not zero?(b(km)) then return "failed"
+ km:= (km - 1) :: NNI
+ km
+
+ if Col has shallowlyMutable then
+
+ test2(sm : M ,b : Col, n1:NNI,dk:NNI) : Union( Col, "failed") ==
+ -- test divisibility --
+ sol:Col := new(n1,0)
+ for k in 1..dk repeat
+ if (c:=(b(k) exquo sm(k,k))) case "failed" then return "failed"
+ sol(k):= c::R
+ sol
+
+ -- test if the matrix is diagonal or pseudo-diagonal --
+ isDiagonal?(m : M) : Boolean ==
+ m1:= nrows m
+ n1:= ncols m
+ for i in 1..m1 repeat
+ for j in 1..n1 | (j ^= i) repeat
+ if not zero?(m(i,j)) then return false
+ true
+
+ -- elementary operation of first kind: exchange two rows --
+ elRow1(m:M,i:I,j:I) : M ==
+ vec:=row(m,i)
+ setRow!(m,i,row(m,j))
+ setRow!(m,j,vec)
+ m
+
+ -- elementary operation of second kind: add to row i--
+ -- a*row j (i^=j) --
+ elRow2(m : M,a:R,i:I,j:I) : M ==
+ vec:= map(a*#1,row(m,j))
+ vec:=map("+",row(m,i),vec)
+ setRow!(m,i,vec)
+ m
+ -- elementary operation of second kind: add to column i --
+ -- a*column j (i^=j) --
+ elColumn2(m : M,a:R,i:I,j:I) : M ==
+ vec:= map(a*#1,column(m,j))
+ vec:=map("+",column(m,i),vec)
+ setColumn!(m,i,vec)
+ m
+
+ -- modify SmithForm in such a way that the term m(i,i) --
+ -- divides the term m(j,j). m is diagonal --
+ ijDivide(sf : SmithForm , i : I,j : I) : SmithForm ==
+ m:=sf.Smith
+ mii:=m(i,i)
+ mjj:=m(j,j)
+ extGcd:=extendedEuclidean(mii,mjj)
+ d := extGcd.generator
+ mii:=(mii exquo d)::R
+ mjj := (mjj exquo d) :: R
+ -- add to row j extGcd.coef1*row i --
+ lMat:=elRow2(sf.leftEqMat,extGcd.coef1,j,i)
+ -- switch rows i and j --
+ lMat:=elRow1(lMat,i,j)
+ -- add to row j -mii*row i --
+ lMat := elRow2(lMat,-mii,j,i)
+-- lMat := ijModify(mii,mjj,extGcd.coef1,extGcd.coef2,sf.leftEqMat,i,j)
+ m(j,j):= m(i,i) * mjj
+ m(i,i):= d
+ -- add to column i extGcd.coef2 * column j --
+ rMat := elColumn2(sf.rightEqMat,extGcd.coef2,i,j)
+ -- add to column j -mjj*column i --
+ rMat:=elColumn2(rMat,-mjj,j,i)
+ -- multiply by -1 column j --
+ setColumn!(rMat,j,map(-1 * #1,column(rMat,j)))
+ [m,lMat,rMat]
+
+
+ -- given a diagonal matrix compute its Smith form --
+ lastStep(sf : SmithForm) : SmithForm ==
+ m:=sf.Smith
+ m1:=min(nrows m,ncols m)
+ for i in 1..m1 while (mii:=m(i,i)) ^=0 repeat
+ for j in i+1..m1 repeat
+ if (m(j,j) exquo mii) case "failed" then return
+ lastStep(ijDivide(sf,i,j))
+ sf
+
+ -- given m and t row-equivalent matrices, with t in upper triangular --
+ -- form compute the matrix u such that u*m=t --
+ findEqMat(m : M,t : M) : Record(Hermite : M, eqMat : M) ==
+ m1:=nrows m
+ n1:=ncols m
+ "and"/[zero? t(m1,j) for j in 1..n1] => -- there are 0 rows
+ if "and"/[zero? t(1,j) for j in 1..n1]
+ then return [m,scalarMatrix(m1,1)] -- m is the zero matrix
+ mm:=horizConcat(m,scalarMatrix(m1,1))
+ mmh:=rowEchelon mm
+ [subMatrix(mmh,1,m1,1,n1), subMatrix(mmh,1,m1,n1+1,n1+m1)]
+ u:M:=zero(m1,m1)
+ j:=1
+ while t(1,j)=0 repeat j:=j+1 -- there are 0 columns
+ t1:=copy t
+ mm:=copy m
+ if j>1 then
+ t1:=subMatrix(t,1,m1,j,n1)
+ mm:=subMatrix(m,1,m1,j,n1)
+ t11:=t1(1,1)
+ for i in 1..m1 repeat
+ u(i,1) := (mm(i,1) exquo t11) :: R
+ for j in 2..m1 repeat
+ j0:=j
+ while zero?(tjj:=t1(j,j0)) repeat j0:=j0+1
+ u(i,j) :=((mm(i,j0) - ("+"/[u(i,k) * t1(k,j0) for k in 1..(j-1)])) exquo
+ tjj) :: R
+ u1:M2:= map(#1 :: QF,u)$MATCAT1
+ [t,map(retract$QF,(inverse u1)::M2)$MATCAT2]
+
+ --- Hermite normal form of m ---
+ hermite(m:M) : M == rowEchelon m
+
+ -- Hermite normal form and equivalence matrix --
+ completeHermite(m : M) : Record(Hermite : M, eqMat : M) ==
+ findEqMat(m,rowEchelon m)
+
+ smith(m : M) : M == completeSmith(m).Smith
+
+ completeSmith(m : M) : Record(Smith : M, leftEqMat : M, rightEqMat : M) ==
+ cm1:=completeHermite m
+ leftm:=cm1.eqMat
+ m1:=cm1.Hermite
+ isDiagonal? m1 => lastStep([m1,leftm,scalarMatrix(ncols m,1)])
+ nr:=nrows m
+ cm1:=completeHermite transpose m1
+ rightm:= transpose cm1.eqMat
+ m1:=cm1.Hermite
+ isDiagonal? m1 =>
+ cm2:=lastStep([m1,leftm,rightm])
+ nrows(m:=cm2.Smith) = nr => cm2
+ [transpose m,cm2.leftEqMat, cm2.rightEqMat]
+ cm2:=completeSmith m1
+ cm2:=lastStep([cm2.Smith,transpose(cm2.rightEqMat)*leftm,
+ rightm*transpose(cm2.leftEqMat)])
+ nrows(m:=cm2.Smith) = nr => cm2
+ [transpose m, cm2.leftEqMat, cm2.rightEqMat]
+
+ -- Find the solution in R of the linear system mX = b --
+ diophantineSystem(m : M, b : Col) : Both ==
+ sf:=completeSmith m
+ sm:=sf.Smith
+ m1:=nrows sm
+ lm:=sf.leftEqMat
+ b1:Col:= lm* b
+ (t1:=test1(sm,b1,m1)) case "failed" => ["failed",empty()]
+ dk:=t1 :: NNI
+ n1:=ncols sm
+ (t2:=test2(sm,b1,n1,dk)) case "failed" => ["failed",empty()]
+ rm := sf.rightEqMat
+ sol:=rm*(t2 :: Col) -- particular solution
+ dk = n1 => [sol,list new(n1,0)]
+ lsol:List Col := [column(rm,i) for i in (dk+1)..n1]
+ [sol,lsol]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SMITH SmithNormalForm>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/solvedio.spad.pamphlet b/src/algebra/solvedio.spad.pamphlet
new file mode 100644
index 00000000..dcf0d2d2
--- /dev/null
+++ b/src/algebra/solvedio.spad.pamphlet
@@ -0,0 +1,232 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra solvedio.spad}
+\author{Albrecht Fortenbacher}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DIOSP DiophantineSolutionPackage}
+<<package DIOSP DiophantineSolutionPackage>>=
+)abbrev package DIOSP DiophantineSolutionPackage
+++ Author: A. Fortenbacher
+++ Date Created: 29 March 1991
+++ Date Last Updated: 29 March 1991
+++ Basic Operations: dioSolve
+++ Related Constructors: Equation, Vector
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Diophantine equation, nonnegative solutions,
+++ basis, depth-first-search
+++ Reference:
+++ M. Clausen, A. Fortenbacher: Efficient Solution of
+++ Linear Diophantine Equations. in JSC (1989) 8, 201-216
+++ Description:
+++ any solution of a homogeneous linear Diophantine equation
+++ can be represented as a sum of minimal solutions, which
+++ form a "basis" (a minimal solution cannot be represented
+++ as a nontrivial sum of solutions)
+++ in the case of an inhomogeneous linear Diophantine equation,
+++ each solution is the sum of a inhomogeneous solution and
+++ any number of homogeneous solutions
+++ therefore, it suffices to compute two sets:
+++ 1. all minimal inhomogeneous solutions
+++ 2. all minimal homogeneous solutions
+++ the algorithm implemented is a completion procedure, which
+++ enumerates all solutions in a recursive depth-first-search
+++ it can be seen as finding monotone paths in a graph
+++ for more details see Reference
+
+DiophantineSolutionPackage(): Cat == Capsule where
+
+ B ==> Boolean
+ I ==> Integer
+ NI ==> NonNegativeInteger
+
+ LI ==> List(I)
+ VI ==> Vector(I)
+ VNI ==> Vector(NI)
+
+ POLI ==> Polynomial(I)
+ EPOLI ==> Equation(POLI)
+ LPOLI ==> List(POLI)
+
+ S ==> Symbol
+ LS ==> List(S)
+
+ ListSol ==> List(VNI)
+ Solutions ==> Record(varOrder: LS, inhom: Union(ListSol,"failed"),
+ hom: ListSol)
+
+ Node ==> Record(vert: VI, free: B)
+ Graph ==> Record(vn: Vector(Node), dim : NI, zeroNode: I)
+
+ Cat ==> with
+
+ dioSolve: EPOLI -> Solutions
+ ++ dioSolve(u) computes a basis of all minimal solutions for
+ ++ linear homogeneous Diophantine equation u,
+ ++ then all minimal solutions of inhomogeneous equation
+
+ Capsule ==> add
+
+ import I
+ import POLI
+
+ -- local function specifications
+
+ initializeGraph: (LPOLI, I) -> Graph
+ createNode: (I, VI, NI, I) -> Node
+ findSolutions: (VNI, I, I, I, Graph, B) -> ListSol
+ verifyMinimality: (VNI, Graph, B) -> B
+ verifySolution: (VNI, I, I, I, Graph) -> B
+
+ -- exported functions
+
+ dioSolve(eq) ==
+ p := lhs(eq) - rhs(eq)
+ n := totalDegree(p)
+ n = 0 or n > 1 =>
+ error "a linear Diophantine equation is expected"
+ mon := empty()$LPOLI
+ c : I := 0
+ for x in monomials(p) repeat
+ ground?(x) =>
+ c := ground(x) :: I
+ mon := cons(x, mon)$LPOLI
+ graph := initializeGraph(mon, c)
+ sol := zero(graph.dim)$VNI
+ hs := findSolutions(sol, graph.zeroNode, 1, 1, graph, true)
+ ihs : ListSol :=
+ c = 0 => [sol]
+ findSolutions(sol, graph.zeroNode + c, 1, 1, graph, false)
+ vars := [first(variables(x))$LS for x in mon]
+ [vars, if empty?(ihs)$ListSol then "failed" else ihs, hs]
+
+ -- local functions
+
+ initializeGraph(mon, c) ==
+ coeffs := vector([first(coefficients(x))$LI for x in mon])$VI
+ k := #coeffs
+ m := min(c, reduce(min, coeffs)$VI)
+ n := max(c, reduce(max, coeffs)$VI)
+ [[createNode(i, coeffs, k, 1 - m) for i in m..n], k, 1 - m]
+
+ createNode(ind, coeffs, k, zeroNode) ==
+ -- create vertices from node ind to other nodes
+ v := zero(k)$VI
+ for i in 1..k repeat
+ ind > 0 =>
+ coeffs.i < 0 =>
+ v.i := zeroNode + ind + coeffs.i
+ coeffs.i > 0 =>
+ v.i := zeroNode + ind + coeffs.i
+ [v, true]
+
+ findSolutions(sol, ind, m, n, graph, flag) ==
+ -- return all solutions (paths) from node ind to node zeroNode
+ sols := empty()$ListSol
+ node := graph.vn.ind
+ node.free =>
+ node.free := false
+ v := node.vert
+ k := if ind < graph.zeroNode then m else n
+ for i in k..graph.dim repeat
+ x := sol.i
+ v.i > 0 => -- vertex exists to other node
+ sol.i := x + 1
+ v.i = graph.zeroNode => -- solution found
+ verifyMinimality(sol, graph, flag) =>
+ sols := cons(copy(sol)$VNI, sols)$ListSol
+ sol.i := x
+ sol.i := x
+ s :=
+ ind < graph.zeroNode =>
+ findSolutions(sol, v.i, i, n, graph, flag)
+ findSolutions(sol, v.i, m, i, graph, flag)
+ sols := append(s, sols)$ListSol
+ sol.i := x
+ node.free := true
+ sols
+ sols
+
+ verifyMinimality(sol, graph, flag) ==
+ -- test whether sol contains a minimal homogeneous solution
+ flag => -- sol is a homogeneous solution
+ i := 1
+ while sol.i = 0 repeat
+ i := i + 1
+ x := sol.i
+ sol.i := (x - 1) :: NI
+ flag := verifySolution(sol, graph.zeroNode, 1, 1, graph)
+ sol.i := x
+ flag
+ verifySolution(sol, graph.zeroNode, 1, 1, graph)
+
+ verifySolution(sol, ind, m, n, graph) ==
+ -- test whether sol contains a path from ind to zeroNode
+ flag := true
+ node := graph.vn.ind
+ v := node.vert
+ k := if ind < graph.zeroNode then m else n
+ for i in k..graph.dim while flag repeat
+ x := sol.i
+ x > 0 and v.i > 0 => -- vertex exists to other node
+ sol.i := (x - 1) :: NI
+ v.i = graph.zeroNode => -- solution found
+ flag := false
+ sol.i := x
+ flag :=
+ ind < graph.zeroNode =>
+ verifySolution(sol, v.i, i, n, graph)
+ verifySolution(sol, v.i, m, i, graph)
+ sol.i := x
+ flag
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DIOSP DiophantineSolutionPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/solvefor.spad.pamphlet b/src/algebra/solvefor.spad.pamphlet
new file mode 100644
index 00000000..7095d4e1
--- /dev/null
+++ b/src/algebra/solvefor.spad.pamphlet
@@ -0,0 +1,327 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra solvefor.spad}
+\author{Stephen M. Watt, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SOLVEFOR PolynomialSolveByFormulas}
+<<package SOLVEFOR PolynomialSolveByFormulas>>=
+)abbrev package SOLVEFOR PolynomialSolveByFormulas
+-- Current fields with "**": (%, RationalNumber) -> % are
+-- ComplexFloat, RadicalExtension(K) and RationalRadical
+-- SMW June 86, BMT Sept 93
+++ Description:
+++ This package factors the formulas out of the general solve code,
+++ allowing their recursive use over different domains.
+++ Care is taken to introduce few radicals so that radical extension
+++ domains can more easily simplify the results.
+
+PolynomialSolveByFormulas(UP, F): PSFcat == PSFdef where
+
+ UP: UnivariatePolynomialCategory F
+ F: Field with "**": (%, Fraction Integer) -> %
+
+ L ==> List
+
+ PSFcat == with
+ solve: UP -> L F
+ ++ solve(u) \undocumented
+ particularSolution: UP -> F
+ ++ particularSolution(u) \undocumented
+ mapSolve: (UP, F -> F) -> Record(solns: L F,
+ maps: L Record(arg:F,res:F))
+ ++ mapSolve(u,f) \undocumented
+
+ linear: UP -> L F
+ ++ linear(u) \undocumented
+ quadratic: UP -> L F
+ ++ quadratic(u) \undocumented
+ cubic: UP -> L F
+ ++ cubic(u) \undocumented
+ quartic: UP -> L F
+ ++ quartic(u) \undocumented
+
+ -- Arguments give coefs from high to low degree.
+ linear: (F, F) -> L F
+ ++ linear(f,g) \undocumented
+ quadratic: (F, F, F) -> L F
+ ++ quadratic(f,g,h) \undocumented
+ cubic: (F, F, F, F) -> L F
+ ++ cubic(f,g,h,i) \undocumented
+ quartic: (F, F, F, F, F) -> L F
+ ++ quartic(f,g,h,i,j) \undocumented
+
+ aLinear: (F, F) -> F
+ ++ aLinear(f,g) \undocumented
+ aQuadratic: (F, F, F) -> F
+ ++ aQuadratic(f,g,h) \undocumented
+ aCubic: (F, F, F, F) -> F
+ ++ aCubic(f,g,h,j) \undocumented
+ aQuartic: (F, F, F, F, F) -> F
+ ++ aQuartic(f,g,h,i,k) \undocumented
+
+ PSFdef == add
+
+ -----------------------------------------------------------------
+ -- Stuff for mapSolve
+ -----------------------------------------------------------------
+ id ==> (IDENTITY$Lisp)
+
+ maplist: List Record(arg: F, res: F) := []
+ mapSolving?: Boolean := false
+ -- map: F -> F := id #1 replaced with line below
+ map: Boolean := false
+
+ mapSolve(p, fn) ==
+ -- map := fn #1 replaced with line below
+ locmap: F -> F := fn #1; map := id locmap
+ mapSolving? := true; maplist := []
+ slist := solve p
+ mapSolving? := false;
+ -- map := id #1 replaced with line below
+ locmap := id #1; map := id locmap
+ [slist, maplist]
+
+ part(s: F): F ==
+ not mapSolving? => s
+ -- t := map s replaced with line below
+ t: F := SPADCALL(s, map)$Lisp
+ t = s => s
+ maplist := cons([t, s], maplist)
+ t
+
+ -----------------------------------------------------------------
+ -- Entry points and error handling
+ -----------------------------------------------------------------
+ cc ==> coefficient
+
+ -- local intsolve
+ intsolve(u:UP):L(F) ==
+ u := (factors squareFree u).1.factor
+ n := degree u
+ n=1 => linear (cc(u,1), cc(u,0))
+ n=2 => quadratic (cc(u,2), cc(u,1), cc(u,0))
+ n=3 => cubic (cc(u,3), cc(u,2), cc(u,1), cc(u,0))
+ n=4 => quartic (cc(u,4), cc(u,3), cc(u,2), cc(u,1), cc(u,0))
+ error "All sqfr factors of polynomial must be of degree < 5"
+
+ solve u ==
+ ls := nil$L(F)
+ for f in factors squareFree u repeat
+ lsf := intsolve f.factor
+ for i in 1..(f.exponent) repeat ls := [:lsf,:ls]
+ ls
+
+ particularSolution u ==
+ u := (factors squareFree u).1.factor
+ n := degree u
+ n=1 => aLinear (cc(u,1), cc(u,0))
+ n=2 => aQuadratic (cc(u,2), cc(u,1), cc(u,0))
+ n=3 => aCubic (cc(u,3), cc(u,2), cc(u,1), cc(u,0))
+ n=4 => aQuartic (cc(u,4), cc(u,3), cc(u,2), cc(u,1), cc(u,0))
+ error "All sqfr factors of polynomial must be of degree < 5"
+
+ needDegree(n: Integer, u: UP): Boolean ==
+ degree u = n => true
+ error concat("Polynomial must be of degree ", n::String)
+
+ needLcoef(cn: F): Boolean ==
+ cn ^= 0 => true
+ error "Leading coefficient must not be 0."
+
+ needChar0(): Boolean ==
+ characteristic()$F = 0 => true
+ error "Formula defined only for fields of characteristic 0."
+
+ linear u ==
+ needDegree(1, u)
+ linear (coefficient(u,1), coefficient(u,0))
+
+ quadratic u ==
+ needDegree(2, u)
+ quadratic (coefficient(u,2), coefficient(u,1),
+ coefficient(u,0))
+
+ cubic u ==
+ needDegree(3, u)
+ cubic (coefficient(u,3), coefficient(u,2),
+ coefficient(u,1), coefficient(u,0))
+
+ quartic u ==
+ needDegree(4, u)
+ quartic (coefficient(u,4),coefficient(u,3),
+ coefficient(u,2),coefficient(u,1),coefficient(u,0))
+
+ -----------------------------------------------------------------
+ -- The formulas
+ -----------------------------------------------------------------
+
+ -- local function for testing equality of radicals.
+ -- This function is necessary to detect at least some of the
+ -- situations like sqrt(9)-3 = 0 --> false.
+ equ(x:F,y:F):Boolean ==
+ ( (recip(x-y)) case "failed" ) => true
+ false
+
+ linear(c1, c0) ==
+ needLcoef c1
+ [- c0/c1 ]
+
+ aLinear(c1, c0) ==
+ first linear(c1,c0)
+
+ quadratic(c2, c1, c0) ==
+ needLcoef c2; needChar0()
+ (c0 = 0) => [0$F,:linear(c2, c1)]
+ (c1 = 0) => [(-c0/c2)**(1/2),-(-c0/c2)**(1/2)]
+ D := part(c1**2 - 4*c2*c0)**(1/2)
+ [(-c1+D)/(2*c2), (-c1-D)/(2*c2)]
+
+ aQuadratic(c2, c1, c0) ==
+ needLcoef c2; needChar0()
+ (c0 = 0) => 0$F
+ (c1 = 0) => (-c0/c2)**(1/2)
+ D := part(c1**2 - 4*c2*c0)**(1/2)
+ (-c1+D)/(2*c2)
+
+ w3: F := (-1 + (-3::F)**(1/2)) / 2::F
+
+ cubic(c3, c2, c1, c0) ==
+ needLcoef c3; needChar0()
+
+ -- case one root = 0, not necessary but keeps result small
+ (c0 = 0) => [0$F,:quadratic(c3, c2, c1)]
+ a1 := c2/c3; a2 := c1/c3; a3 := c0/c3
+
+ -- case x**3-a3 = 0, not necessary but keeps result small
+ (a1 = 0 and a2 = 0) =>
+ [ u*(-a3)**(1/3) for u in [1, w3, w3**2 ] ]
+
+ -- case x**3 + a1*x**2 + a1**2*x/3 + a3 = 0, the general for-
+ -- mula is not valid in this case, but solution is easy.
+ P := part(-a1/3::F)
+ equ(a1**2,3*a2) =>
+ S := part((- a3 + (a1**3)/27::F)**(1/3))
+ [ P + S*u for u in [1,w3,w3**2] ]
+
+ -- general case
+ Q := part((3*a2 - a1**2)/9::F)
+ R := part((9*a1*a2 - 27*a3 - 2*a1**3)/54::F)
+ D := part(Q**3 + R**2)**(1/2)
+ S := part(R + D)**(1/3)
+ -- S = 0 is done in the previous case
+ [ P + S*u - Q/(S*u) for u in [1, w3, w3**2] ]
+
+ aCubic(c3, c2, c1, c0) ==
+ needLcoef c3; needChar0()
+ (c0 = 0) => 0$F
+ a1 := c2/c3; a2 := c1/c3; a3 := c0/c3
+ (a1 = 0 and a2 = 0) => (-a3)**(1/3)
+ P := part(-a1/3::F)
+ equ(a1**2,3*a2) =>
+ S := part((- a3 + (a1**3)/27::F)**(1/3))
+ P + S
+ Q := part((3*a2 - a1**2)/9::F)
+ R := part((9*a1*a2 - 27*a3 - 2*a1**3)/54::F)
+ D := part(Q**3 + R**2)**(1/2)
+ S := part(R + D)**(1/3)
+ P + S - Q/S
+
+ quartic(c4, c3, c2, c1, c0) ==
+ needLcoef c4; needChar0()
+
+ -- case one root = 0, not necessary but keeps result small
+ (c0 = 0) => [0$F,:cubic(c4, c3, c2, c1)]
+ -- Make monic:
+ a1 := c3/c4; a2 := c2/c4; a3 := c1/c4; a4 := c0/c4
+
+ -- case x**4 + a4 = 0 <=> (x**2-sqrt(-a4))*(x**2+sqrt(-a4))
+ -- not necessary but keeps result small.
+ (a1 = 0 and a2 = 0 and a3 = 0) =>
+ append( quadratic(1, 0, (-a4)**(1/2)),_
+ quadratic(1 ,0, -((-a4)**(1/2))) )
+
+ -- Translate w = x+a1/4 to eliminate a1: w**4+p*w**2+q*w+r
+ p := part(a2-3*a1*a1/8::F)
+ q := part(a3-a1*a2/2::F + a1**3/8::F)
+ r := part(a4-a1*a3/4::F + a1**2*a2/16::F - 3*a1**4/256::F)
+ -- t0 := the cubic resolvent of x**3-p*x**2-4*r*x+4*p*r-q**2
+ -- The roots of the translated polynomial are those of
+ -- two quadratics. (What about rt=0 ?)
+ -- rt=0 can be avoided by picking a root ^= p of the cubic
+ -- polynomial above. This is always possible provided that
+ -- the input is squarefree. In this case the two other roots
+ -- are +(-) 2*r**(1/2).
+ if equ(q,0) -- this means p is a root
+ then t0 := part(2*(r**(1/2)))
+ else t0 := aCubic(1, -p, -4*r, 4*p*r - q**2)
+ rt := part(t0 - p)**(1/2)
+ slist := append( quadratic( 1, rt, (-q/rt + t0)/2::F ),
+ quadratic( 1, -rt, ( q/rt + t0)/2::F ))
+ -- Translate back:
+ [s - a1/4::F for s in slist]
+
+ aQuartic(c4, c3, c2, c1, c0) ==
+ needLcoef c4; needChar0()
+ (c0 = 0) => 0$F
+ a1 := c3/c4; a2 := c2/c4; a3 := c1/c4; a4 := c0/c4
+ (a1 = 0 and a2 = 0 and a3 = 0) => (-a4)**(1/4)
+ p := part(a2-3*a1*a1/8::F)
+ q := part(a3-a1*a2/2::F + a1**2*a1/8::F)
+ r := part(a4-a1*a3/4::F + a1**2*a2/16::F - 3*a1**4/256::F)
+ if equ(q,0)
+ then t0 := part(2*(r**(1/2)))
+ else t0 := aCubic(1, -p, -4*r, 4*p*r - q**2)
+ rt := part(t0 - p)**(1/2)
+ s := aQuadratic( 1, rt, (-q/rt + t0)/2::F )
+ s - a1/4::F
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SOLVEFOR PolynomialSolveByFormulas>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/solvelin.spad.pamphlet b/src/algebra/solvelin.spad.pamphlet
new file mode 100644
index 00000000..9c35d201
--- /dev/null
+++ b/src/algebra/solvelin.spad.pamphlet
@@ -0,0 +1,282 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra solvelin.spad}
+\author{Patrizia Gianni, Stephen M. Watt, Robert Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package LSMP LinearSystemMatrixPackage}
+<<package LSMP LinearSystemMatrixPackage>>=
+)abbrev package LSMP LinearSystemMatrixPackage
+++ Author: P.Gianni, S.Watt
+++ Date Created: Summer 1985
+++ Date Last Updated:Summer 1990
+++ Basic Functions: solve, particularSolution, hasSolution?, rank
+++ Related Constructors: LinearSystemMatrixPackage1
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package solves linear system in the matrix form \spad{AX = B}.
+
+LinearSystemMatrixPackage(F, Row, Col, M): Cat == Capsule where
+ F: Field
+ Row: FiniteLinearAggregate F with shallowlyMutable
+ Col: FiniteLinearAggregate F with shallowlyMutable
+ M : MatrixCategory(F, Row, Col)
+
+ N ==> NonNegativeInteger
+ PartialV ==> Union(Col, "failed")
+ Both ==> Record(particular: PartialV, basis: List Col)
+
+ Cat ==> with
+ solve : (M, Col) -> Both
+ ++ solve(A,B) finds a particular solution of the system \spad{AX = B}
+ ++ and a basis of the associated homogeneous system \spad{AX = 0}.
+ solve : (M, List Col) -> List Both
+ ++ solve(A,LB) finds a particular soln of the systems \spad{AX = B}
+ ++ and a basis of the associated homogeneous systems \spad{AX = 0}
+ ++ where B varies in the list of column vectors LB.
+
+ particularSolution: (M, Col) -> PartialV
+ ++ particularSolution(A,B) finds a particular solution of the linear
+ ++ system \spad{AX = B}.
+ hasSolution?: (M, Col) -> Boolean
+ ++ hasSolution?(A,B) tests if the linear system \spad{AX = B}
+ ++ has a solution.
+ rank : (M, Col) -> N
+ ++ rank(A,B) computes the rank of the complete matrix \spad{(A|B)}
+ ++ of the linear system \spad{AX = B}.
+
+ Capsule ==> add
+ systemMatrix : (M, Col) -> M
+ aSolution : M -> PartialV
+
+ -- rank theorem
+ hasSolution?(A, b) == rank A = rank systemMatrix(A, b)
+ systemMatrix(m, v) == horizConcat(m, -(v::M))
+ rank(A, b) == rank systemMatrix(A, b)
+ particularSolution(A, b) == aSolution rowEchelon systemMatrix(A,b)
+
+ -- m should be in row-echelon form.
+ -- last column of m is -(right-hand-side of system)
+ aSolution m ==
+ nvar := (ncols m - 1)::N
+ rk := maxRowIndex m
+ while (rk >= minRowIndex m) and every?(zero?, row(m, rk))
+ repeat rk := dec rk
+ rk < minRowIndex m => new(nvar, 0)
+ ck := minColIndex m
+ while (ck < maxColIndex m) and zero? qelt(m, rk, ck) repeat
+ ck := inc ck
+ ck = maxColIndex m => "failed"
+ sol := new(nvar, 0)$Col
+ -- find leading elements of diagonal
+ v := new(nvar, minRowIndex m - 1)$PrimitiveArray(Integer)
+ for i in minRowIndex m .. rk repeat
+ for j in 0.. while zero? qelt(m, i, j+minColIndex m) repeat 0
+ v.j := i
+ for j in 0..nvar-1 repeat
+ if v.j >= minRowIndex m then
+ qsetelt_!(sol, j+minIndex sol, - qelt(m, v.j, maxColIndex m))
+ sol
+
+ solve(A:M, b:Col) ==
+ -- Special case for homogeneous systems.
+ every?(zero?, b) => [new(ncols A, 0), nullSpace A]
+ -- General case.
+ m := rowEchelon systemMatrix(A, b)
+ [aSolution m,
+ nullSpace subMatrix(m, minRowIndex m, maxRowIndex m,
+ minColIndex m, maxColIndex m - 1)]
+
+ solve(A:M, l:List Col) ==
+ null l => [[new(ncols A, 0), nullSpace A]]
+ nl := (sol0 := solve(A, first l)).basis
+ cons(sol0,
+ [[aSolution rowEchelon systemMatrix(A, b), nl]
+ for b in rest l])
+
+@
+\section{package LSMP1 LinearSystemMatrixPackage1}
+<<package LSMP1 LinearSystemMatrixPackage1>>=
+)abbrev package LSMP1 LinearSystemMatrixPackage1
+++ Author: R. Sutor
+++ Date Created: June, 1994
+++ Date Last Updated:
+++ Basic Functions: solve, particularSolution, hasSolution?, rank
+++ Related Constructors: LinearSystemMatrixPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords: solve
+++ References:
+++ Description:
+++ This package solves linear system in the matrix form \spad{AX = B}.
+++ It is essentially a particular instantiation of the package
+++ \spadtype{LinearSystemMatrixPackage} for Matrix and Vector. This
+++ package's existence makes it easier to use \spadfun{solve} in the
+++ AXIOM interpreter.
+
+LinearSystemMatrixPackage1(F): Cat == Capsule where
+ F: Field
+ Row ==> Vector F
+ Col ==> Vector F
+ M ==> Matrix(F)
+ LL ==> List List F
+
+ N ==> NonNegativeInteger
+ PartialV ==> Union(Col, "failed")
+ Both ==> Record(particular: PartialV, basis: List Col)
+ LSMP ==> LinearSystemMatrixPackage(F, Row, Col, M)
+
+ Cat ==> with
+ solve : (M, Col) -> Both
+ ++ solve(A,B) finds a particular solution of the system \spad{AX = B}
+ ++ and a basis of the associated homogeneous system \spad{AX = 0}.
+ solve : (LL, Col) -> Both
+ ++ solve(A,B) finds a particular solution of the system \spad{AX = B}
+ ++ and a basis of the associated homogeneous system \spad{AX = 0}.
+ solve : (M, List Col) -> List Both
+ ++ solve(A,LB) finds a particular soln of the systems \spad{AX = B}
+ ++ and a basis of the associated homogeneous systems \spad{AX = 0}
+ ++ where B varies in the list of column vectors LB.
+ solve : (LL, List Col) -> List Both
+ ++ solve(A,LB) finds a particular soln of the systems \spad{AX = B}
+ ++ and a basis of the associated homogeneous systems \spad{AX = 0}
+ ++ where B varies in the list of column vectors LB.
+
+ particularSolution: (M, Col) -> PartialV
+ ++ particularSolution(A,B) finds a particular solution of the linear
+ ++ system \spad{AX = B}.
+ hasSolution?: (M, Col) -> Boolean
+ ++ hasSolution?(A,B) tests if the linear system \spad{AX = B}
+ ++ has a solution.
+ rank : (M, Col) -> N
+ ++ rank(A,B) computes the rank of the complete matrix \spad{(A|B)}
+ ++ of the linear system \spad{AX = B}.
+
+ Capsule ==> add
+ solve(m : M, c: Col): Both == solve(m,c)$LSMP
+ solve(ll : LL, c: Col): Both == solve(matrix(ll)$M,c)$LSMP
+ solve(m : M, l : List Col): List Both == solve(m, l)$LSMP
+ solve(ll : LL, l : List Col): List Both == solve(matrix(ll)$M, l)$LSMP
+ particularSolution (m : M, c : Col): PartialV == particularSolution(m, c)$LSMP
+ hasSolution?(m :M, c : Col): Boolean == hasSolution?(m, c)$LSMP
+ rank(m : M, c : Col): N == rank(m, c)$LSMP
+
+@
+\section{package LSPP LinearSystemPolynomialPackage}
+<<package LSPP LinearSystemPolynomialPackage>>=
+)abbrev package LSPP LinearSystemPolynomialPackage
+++ Author: P.Gianni
+++ Date Created: Summer 1985
+++ Date Last Updated: Summer 1993
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References: SystemSolvePackage
+++ Description:
+++ this package finds the solutions of linear systems presented as a
+++ list of polynomials.
+
+LinearSystemPolynomialPackage(R, E, OV, P): Cat == Capsule where
+ R : IntegralDomain
+ OV : OrderedSet
+ E : OrderedAbelianMonoidSup
+ P : PolynomialCategory(R,E,OV)
+
+ F ==> Fraction P
+ NNI ==> NonNegativeInteger
+ V ==> Vector
+ M ==> Matrix
+ Soln ==> Record(particular: Union(V F, "failed"), basis: List V F)
+
+ Cat == with
+ linSolve: (List P, List OV) -> Soln
+ ++ linSolve(lp,lvar) finds the solutions of the linear system
+ ++ of polynomials lp = 0 with respect to the list of symbols lvar.
+
+ Capsule == add
+
+ ---- Local Functions ----
+
+ poly2vect: (P, List OV) -> Record(coefvec: V F, reductum: F)
+ intoMatrix: (List P, List OV) -> Record(mat: M F, vec: V F)
+
+
+ poly2vect(p : P, vs : List OV) : Record(coefvec: V F, reductum: F) ==
+ coefs := new(#vs, 0)$(V F)
+ for v in vs for i in 1.. while p ^= 0 repeat
+ u := univariate(p, v)
+ degree u = 0 => "next v"
+ coefs.i := (c := leadingCoefficient u)::F
+ p := p - monomial(c,v, 1)
+ [coefs, p :: F]
+
+ intoMatrix(ps : List P, vs : List OV ) : Record(mat: M F, vec: V F) ==
+ m := zero(#ps, #vs)$M(F)
+ v := new(#ps, 0)$V(F)
+ for p in ps for i in 1.. repeat
+ totalDegree(p,vs) > 1 => error "The system is not linear"
+ r := poly2vect(p,vs)
+ m:=setRow_!(m,i,r.coefvec)
+ v.i := - r.reductum
+ [m, v]
+
+ linSolve(ps, vs) ==
+ r := intoMatrix(ps, vs)
+ solve(r.mat, r.vec)$LinearSystemMatrixPackage(F,V F,V F,M F)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package LSMP LinearSystemMatrixPackage>>
+<<package LSMP1 LinearSystemMatrixPackage1>>
+<<package LSPP LinearSystemPolynomialPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/solverad.spad.pamphlet b/src/algebra/solverad.spad.pamphlet
new file mode 100644
index 00000000..59e92725
--- /dev/null
+++ b/src/algebra/solverad.spad.pamphlet
@@ -0,0 +1,328 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra solverad.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SOLVERAD RadicalSolvePackage}
+<<package SOLVERAD RadicalSolvePackage>>=
+)abbrev package SOLVERAD RadicalSolvePackage
+++ Author: P.Gianni
+++ Date Created: Summer 1990
+++ Date Last Updated: October 1991
+++ Basic Functions:
+++ Related Constructors: SystemSolvePackage, FloatingRealPackage,
+++ FloatingComplexPackage
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package tries to find solutions
+++ expressed in terms of radicals for systems of equations
+++ of rational functions with coefficients in an integral domain R.
+RadicalSolvePackage(R): Cat == Capsule where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero)
+ PI ==> PositiveInteger
+ NNI==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ ST ==> String
+ PR ==> Polynomial R
+ UP ==> SparseUnivariatePolynomial PR
+ LA ==> LocalAlgebra(PR, Z, Z)
+ RF ==> Fraction PR
+ RE ==> Expression R
+ EQ ==> Equation
+ SY ==> Symbol
+ SU ==> SuchThat(List RE, List Equation RE)
+ SUP==> SparseUnivariatePolynomial
+ L ==> List
+ P ==> Polynomial
+
+ SOLVEFOR ==> PolynomialSolveByFormulas(SUP RE, RE)
+ UPF2 ==> SparseUnivariatePolynomialFunctions2(PR,RE)
+
+ Cat ==> with
+
+ radicalSolve : (RF,SY) -> L EQ RE
+ ++ radicalSolve(rf,x) finds the solutions expressed in terms of
+ ++ radicals of the equation rf = 0 with respect to the symbol x,
+ ++ where rf is a rational function.
+ radicalSolve : RF -> L EQ RE
+ ++ radicalSolve(rf) finds the solutions expressed in terms of
+ ++ radicals of the equation rf = 0, where rf is a
+ ++ univariate rational function.
+ radicalSolve : (EQ RF,SY) -> L EQ RE
+ ++ radicalSolve(eq,x) finds the solutions expressed in terms of
+ ++ radicals of the equation of rational functions eq
+ ++ with respect to the symbol x.
+ radicalSolve : EQ RF -> L EQ RE
+ ++ radicalSolve(eq) finds the solutions expressed in terms of
+ ++ radicals of the equation of rational functions eq
+ ++ with respect to the unique symbol x appearing in eq.
+ radicalSolve : (L RF,L SY) -> L L EQ RE
+ ++ radicalSolve(lrf,lvar) finds the solutions expressed in terms of
+ ++ radicals of the system of equations lrf = 0 with
+ ++ respect to the list of symbols lvar,
+ ++ where lrf is a list of rational functions.
+ radicalSolve : L RF -> L L EQ RE
+ ++ radicalSolve(lrf) finds the solutions expressed in terms of
+ ++ radicals of the system of equations lrf = 0, where lrf is a
+ ++ system of univariate rational functions.
+ radicalSolve : (L EQ RF,L SY) -> L L EQ RE
+ ++ radicalSolve(leq,lvar) finds the solutions expressed in terms of
+ ++ radicals of the system of equations of rational functions leq
+ ++ with respect to the list of symbols lvar.
+ radicalSolve : L EQ RF -> L L EQ RE
+ ++ radicalSolve(leq) finds the solutions expressed in terms of
+ ++ radicals of the system of equations of rational functions leq
+ ++ with respect to the unique symbol x appearing in leq.
+ radicalRoots : (RF,SY) -> L RE
+ ++ radicalRoots(rf,x) finds the roots expressed in terms of radicals
+ ++ of the rational function rf with respect to the symbol x.
+ radicalRoots : (L RF,L SY) -> L L RE
+ ++ radicalRoots(lrf,lvar) finds the roots expressed in terms of
+ ++ radicals of the list of rational functions lrf
+ ++ with respect to the list of symbols lvar.
+ contractSolve: (EQ RF,SY) -> SU
+ ++ contractSolve(eq,x) finds the solutions expressed in terms of
+ ++ radicals of the equation of rational functions eq
+ ++ with respect to the symbol x. The result contains new
+ ++ symbols for common subexpressions in order to reduce the
+ ++ size of the output.
+ contractSolve: (RF,SY) -> SU
+ ++ contractSolve(rf,x) finds the solutions expressed in terms of
+ ++ radicals of the equation rf = 0 with respect to the symbol x,
+ ++ where rf is a rational function. The result contains new
+ ++ symbols for common subexpressions in order to reduce the
+ ++ size of the output.
+ Capsule ==> add
+ import DegreeReductionPackage(PR, R)
+ import SOLVEFOR
+
+ SideEquations: List EQ RE := []
+ ContractSoln: B := false
+
+ ---- Local Function Declarations ----
+ solveInner:(PR, SY, B) -> SU
+ linear: UP -> List RE
+ quadratic: UP -> List RE
+ cubic: UP -> List RE
+ quartic: UP -> List RE
+ rad: PI -> RE
+ wrap: RE -> RE
+ New: RE -> RE
+ makeEq : (List RE,L SY) -> L EQ RE
+ select : L L RE -> L L RE
+ isGeneric? : (L PR,L SY) -> Boolean
+ findGenZeros : (L PR,L SY) -> L L RE
+ findZeros : (L PR,L SY) -> L L RE
+
+
+ New s ==
+ s = 0 => 0
+ S := new()$Symbol ::PR::RF::RE
+ SideEquations := append([S = s], SideEquations)
+ S
+
+ linear u == [(-coefficient(u,0))::RE /(coefficient(u,1))::RE]
+ quadratic u == quadratic(map(coerce,u)$UPF2)$SOLVEFOR
+ cubic u == cubic(map(coerce,u)$UPF2)$SOLVEFOR
+ quartic u == quartic(map(coerce,u)$UPF2)$SOLVEFOR
+ rad n == n::Z::RE
+ wrap s == (ContractSoln => New s; s)
+
+
+ ---- Exported Functions ----
+
+
+ -- find the zeros of components in "generic" position --
+ findGenZeros(rlp:L PR,rlv:L SY) : L L RE ==
+ pp:=rlp.first
+ v:=first rlv
+ rlv:=rest rlv
+ res:L L RE:=[]
+ res:=append([reverse cons(r,[eval(
+ (-coefficient(univariate(p,vv),0)::RE)/(leadingCoefficient univariate(p,vv))::RE,
+ kernel(v)@Kernel(RE),r) for vv in rlv for p in rlp.rest])
+ for r in radicalRoots(pp::RF,v)],res)
+ res
+
+
+ findZeros(rlp:L PR,rlv:L SY) : L L RE ==
+ parRes:=[radicalRoots(p::RF,v) for p in rlp for v in rlv]
+ parRes:=select parRes
+ res:L L RE :=[]
+ res1:L RE
+ for par in parRes repeat
+ res1:=[par.first]
+ lv1:L Kernel(RE):=[kernel rlv.first]
+ rlv1:=rlv.rest
+ p1:=par.rest
+ while p1^=[] repeat
+ res1:=cons(eval(p1.first,lv1,res1),res1)
+ p1:=p1.rest
+ lv1:=cons(kernel rlv1.first,lv1)
+ rlv1:=rlv1.rest
+ res:=cons(res1,res)
+ res
+
+ radicalSolve(pol:RF,v:SY) ==
+ [equation(v::RE,r) for r in radicalRoots(pol,v)]
+
+ radicalSolve(p:RF) ==
+ zero? p =>
+ error "equation is always satisfied"
+ lv:=removeDuplicates
+ concat(variables numer p, variables denom p)
+ empty? lv => error "inconsistent equation"
+ #lv>1 => error "too many variables"
+ radicalSolve(p,lv.first)
+
+ radicalSolve(eq: EQ RF) ==
+ radicalSolve(lhs eq -rhs eq)
+
+ radicalSolve(eq: EQ RF,v:SY) ==
+ radicalSolve(lhs eq - rhs eq,v)
+
+ radicalRoots(lp: L RF,lv: L SY) ==
+ parRes:=triangularSystems(lp,lv)$SystemSolvePackage(R)
+ parRes= list [] => []
+ -- select the components in "generic" form
+ rlv:=reverse lv
+ rpRes:=[reverse res for res in parRes]
+ listGen:= [res for res in rpRes|isGeneric?(res,rlv)]
+ result:L L RE:=[]
+ if listGen^=[] then
+ result:="append"/[findGenZeros(res,rlv) for res in listGen]
+ for res in listGen repeat
+ rpRes:=delete(rpRes,position(res,rpRes))
+ -- non-generic components
+ rpRes = [] => result
+ append("append"/[findZeros(res,rlv) for res in rpRes],
+ result)
+
+ radicalSolve(lp:L RF,lv:L SY) ==
+ [makeEq(lres,lv) for lres in radicalRoots(lp,lv)]
+
+ radicalSolve(lp: L RF) ==
+ lv:="setUnion"/[setUnion(variables numer p,variables denom p)
+ for p in lp]
+ [makeEq(lres,lv) for lres in radicalRoots(lp,lv)]
+
+ radicalSolve(le:L EQ RF,lv:L SY) ==
+ lp:=[rhs p -lhs p for p in le]
+ [makeEq(lres,lv) for lres in radicalRoots(lp,lv)]
+
+ radicalSolve(le: L EQ RF) ==
+ lp:=[rhs p -lhs p for p in le]
+ lv:="setUnion"/[setUnion(variables numer p,variables denom p)
+ for p in lp]
+ [makeEq(lres,lv) for lres in radicalRoots(lp,lv)]
+
+ contractSolve(eq:EQ RF, v:SY)==
+ solveInner(numer(lhs eq - rhs eq), v, true)
+
+ contractSolve(pq:RF, v:SY) == solveInner(numer pq, v, true)
+
+ radicalRoots(pq:RF, v:SY) == lhs solveInner(numer pq, v, false)
+
+
+ -- test if the ideal is radical in generic position --
+ isGeneric?(rlp:L PR,rlv:L SY) : Boolean ==
+ "and"/[degree(f,x)=1 for f in rest rlp for x in rest rlv]
+
+ ---- select the univariate factors
+ select(lp:L L RE) : L L RE ==
+ lp=[] => list []
+ [:[cons(f,lsel) for lsel in select lp.rest] for f in lp.first]
+
+ ---- Local Functions ----
+ -- construct the equation
+ makeEq(nres:L RE,lv:L SY) : L EQ RE ==
+ [equation(x :: RE,r) for x in lv for r in nres]
+
+ solveInner(pq:PR,v:SY,contractFlag:B) ==
+ SideEquations := []
+ ContractSoln := contractFlag
+
+ factors:= factors
+ (factor pq)$MultivariateFactorize(SY,IndexedExponents SY,R,PR)
+
+ constants: List PR := []
+ unsolved: List PR := []
+ solutions: List RE := []
+
+ for f in factors repeat
+ ff:=f.factor
+ ^ member?(v, variables (ff)) =>
+ constants := cons(ff, constants)
+ u := univariate(ff, v)
+ t := reduce u
+ u := t.pol
+ n := degree u
+ l: List RE :=
+ n = 1 => linear u
+ n = 2 => quadratic u
+ n = 3 => cubic u
+ n = 4 => quartic u
+ unsolved := cons(ff, unsolved)
+ []
+ for s in l repeat
+ if t.deg > 1 then s := wrap s
+ T0 := expand(s, t.deg)
+ for i in 1..f.exponent repeat
+ solutions := append(T0, solutions)
+ re := SideEquations
+ [solutions, SideEquations]$SU
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SOLVERAD RadicalSolvePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sortpak.spad.pamphlet b/src/algebra/sortpak.spad.pamphlet
new file mode 100644
index 00000000..2d10ddf3
--- /dev/null
+++ b/src/algebra/sortpak.spad.pamphlet
@@ -0,0 +1,107 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sortpak.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SORTPAK SortPackage}
+<<package SORTPAK SortPackage>>=
+)abbrev package SORTPAK SortPackage
+++ Description:
+++ This package exports sorting algorithnms
+SortPackage(S,A) : Exports == Implementation where
+ S: Type
+ A: IndexedAggregate(Integer,S)
+ with (finiteAggregate; shallowlyMutable)
+
+ Exports == with
+ bubbleSort_!: (A,(S,S) -> Boolean) -> A
+ ++ bubbleSort!(a,f) \undocumented
+ insertionSort_!: (A, (S,S) -> Boolean) -> A
+ ++ insertionSort!(a,f) \undocumented
+ if S has OrderedSet then
+ bubbleSort_!: A -> A
+ ++ bubbleSort!(a) \undocumented
+ insertionSort_!: A -> A
+ ++ insertionSort! \undocumented
+
+ Implementation == add
+ bubbleSort_!(m,f) ==
+ n := #m
+ for i in 1..(n-1) repeat
+ for j in n..(i+1) by -1 repeat
+ if f(m.j,m.(j-1)) then swap_!(m,j,j-1)
+ m
+ insertionSort_!(m,f) ==
+ for i in 2..#m repeat
+ j := i
+ while j > 1 and f(m.j,m.(j-1)) repeat
+ swap_!(m,j,j-1)
+ j := (j - 1) pretend PositiveInteger
+ m
+ if S has OrderedSet then
+ bubbleSort_!(m) == bubbleSort_!(m,_<$S)
+ insertionSort_!(m) == insertionSort_!(m,_<$S)
+ if A has UnaryRecursiveAggregate(S) then
+ bubbleSort_!(m,fn) ==
+ empty? m => m
+ l := m
+ while not empty? (r := l.rest) repeat
+ r := bubbleSort_!(r,fn)
+ x := l.first
+ if fn(r.first,x) then
+ l.first := r.first
+ r.first := x
+ l.rest := r
+ l := l.rest
+ m
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SORTPAK SortPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/space.spad.pamphlet b/src/algebra/space.spad.pamphlet
new file mode 100644
index 00000000..1f1235d2
--- /dev/null
+++ b/src/algebra/space.spad.pamphlet
@@ -0,0 +1,700 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra space.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category SPACEC ThreeSpaceCategory}
+<<category SPACEC ThreeSpaceCategory>>=
+)abbrev category SPACEC ThreeSpaceCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Operations: create3Space, numberOfComponents, numberOfComposites,
+++ merge, composite, components, copy, enterPointData, modifyPointData, point,
+++ point?, curve, curve?, closedCurve, closedCurve?, polygon, polygon? mesh,
+++ mesh?, lp, lllip, lllp, llprop, lprop, objects, check, subspace, coerce
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: The category ThreeSpaceCategory is used for creating
+++ three dimensional objects using functions for defining points, curves,
+++ polygons, constructs and the subspaces containing them.
+
+ThreeSpaceCategory(R:Ring): Exports == Implementation where
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ L ==> List
+ B ==> Boolean
+ O ==> OutputForm
+ SUBSPACE ==> SubSpace(3,R)
+ POINT ==> Point(R)
+ PROP ==> SubSpaceComponentProperty()
+ REP3D ==> Record(lp:L POINT,llliPt:L L L NNI, llProp:L L PROP, lProp:L PROP)
+ OBJ3D ==> Record(points:NNI, curves:NNI, polygons:NNI, constructs:NNI)
+
+ Exports ==> Category
+ Implementation ==>
+ SetCategory with
+ create3Space : () -> %
+ ++ create3Space() creates a \spadtype{ThreeSpace} object capable of
+ ++ holding point, curve, mesh components and any combination.
+ create3Space : SUBSPACE -> %
+ ++ create3Space(s) creates a \spadtype{ThreeSpace} object containing
+ ++ objects pre-defined within some \spadtype{SubSpace} s.
+ numberOfComponents : % -> NNI
+ ++ numberOfComponents(s) returns the number of distinct
+ ++ object components in the indicated \spadtype{ThreeSpace}, s, such
+ ++ as points, curves, polygons, and constructs.
+ numberOfComposites : % -> NNI
+ ++ numberOfComposites(s) returns the number of supercomponents,
+ ++ or composites, in the \spadtype{ThreeSpace}, s; Composites are
+ ++ arbitrary groupings of otherwise distinct and unrelated components;
+ ++ A \spadtype{ThreeSpace} need not have any composites defined at all
+ ++ and, outside of the requirement that no component can belong
+ ++ to more than one composite at a time, the definition and
+ ++ interpretation of composites are unrestricted.
+ merge : L % -> %
+ ++ merge([s1,s2,...,sn]) will create a new \spadtype{ThreeSpace} that has
+ ++ the components of all the ones in the list; Groupings of components
+ ++ into composites are maintained.
+ merge : (%,%) -> %
+ ++ merge(s1,s2) will create a new \spadtype{ThreeSpace} that has the
+ ++ components of \spad{s1} and \spad{s2}; Groupings of components
+ ++ into composites are maintained.
+ composite : L % -> %
+ ++ composite([s1,s2,...,sn]) will create a new \spadtype{ThreeSpace} that
+ ++ is a union of all the components from each \spadtype{ThreeSpace} in
+ ++ the parameter list, grouped as a composite.
+ components : % -> L %
+ ++ components(s) takes the \spadtype{ThreeSpace} s, and creates a list
+ ++ containing a unique \spadtype{ThreeSpace} for each single component
+ ++ of s. If s has no components defined, the list returned is empty.
+ composites : % -> L %
+ ++ composites(s) takes the \spadtype{ThreeSpace} s, and creates a list
+ ++ containing a unique \spadtype{ThreeSpace} for each single composite
+ ++ of s. If s has no composites defined (composites need to be explicitly
+ ++ created), the list returned is empty. Note that not all the components
+ ++ need to be part of a composite.
+ copy : % -> %
+ ++ copy(s) returns a new \spadtype{ThreeSpace} that is an exact copy of s.
+ enterPointData : (%,L POINT) -> NNI
+ ++ enterPointData(s,[p0,p1,...,pn]) adds a list of points from p0 through
+ ++ pn to the \spadtype{ThreeSpace}, s, and returns the index, to the
+ ++ starting point of the list;
+ modifyPointData : (%,NNI,POINT) -> %
+ ++ modifyPointData(s,i,p) changes the point at the indexed
+ ++ location i in the \spadtype{ThreeSpace}, s, to that of point p.
+ ++ This is useful for making changes to a point which has been
+ ++ transformed.
+
+ -- 3D primitives
+ point : (%,POINT) -> %
+ ++ point(s,p) adds a point component defined by the point, p, specified as
+ ++ a list from \spad{List(R)}, to the \spadtype{ThreeSpace}, s,
+ ++ where R is the \spadtype{Ring} over which the point is defined.
+ point : (%,L R) -> %
+ ++ point(s,[x,y,z]) adds a point component defined by a list of elements
+ ++ which are from the \spad{PointDomain(R)} to the \spadtype{ThreeSpace},
+ ++ s, where R is the \spadtype{Ring} over which the point elements are
+ ++ defined.
+ point : (%,NNI) -> %
+ ++ point(s,i) adds a point component which is placed into a component
+ ++ list of the \spadtype{ThreeSpace}, s, at the index given by i.
+ point : POINT -> %
+ ++ point(p) returns a \spadtype{ThreeSpace} object which is composed of
+ ++ one component, the point p.
+ point : % -> POINT
+ ++ point(s) checks to see if the \spadtype{ThreeSpace}, s, is composed of
+ ++ only a single point and if so, returns the point. An error
+ ++ is signaled otherwise.
+ point? : % -> B
+ ++ point?(s) queries whether the \spadtype{ThreeSpace}, s, is composed of
+ ++ a single component which is a point and returns the boolean result.
+ curve : (%,L POINT) -> %
+ ++ curve(s,[p0,p1,...,pn]) adds a space curve component defined by a
+ ++ list of points \spad{p0} through \spad{pn}, to the \spadtype{ThreeSpace} s.
+ curve : (%,L L R) -> %
+ ++ curve(s,[[p0],[p1],...,[pn]]) adds a space curve which is a list of
+ ++ points p0 through pn defined by lists of elements from the domain
+ ++ \spad{PointDomain(m,R)}, where R is the \spadtype{Ring} over which the
+ ++ point elements are defined and m is the dimension of the points, to
+ ++ the \spadtype{ThreeSpace} s.
+ curve : L POINT -> %
+ ++ curve([p0,p1,p2,...,pn]) creates a space curve defined
+ ++ by the list of points \spad{p0} through \spad{pn}, and returns the
+ ++ \spadtype{ThreeSpace} whose component is the curve.
+ curve : % -> L POINT
+ ++ curve(s) checks to see if the \spadtype{ThreeSpace}, s, is composed of
+ ++ a single curve defined by a list of points and if so, returns the
+ ++ curve, i.e., list of points. An error is signaled otherwise.
+ curve? : % -> B
+ ++ curve?(s) queries whether the \spadtype{ThreeSpace}, s, is a curve,
+ ++ i.e., has one component, a list of list of points, and returns true if
+ ++ it is, or false otherwise.
+ closedCurve : (%,L POINT) -> %
+ ++ closedCurve(s,[p0,p1,...,pn,p0]) adds a closed curve component which is
+ ++ a list of points defined by the first element p0 through the last
+ ++ element pn and back to the first element p0 again, to the
+ ++ \spadtype{ThreeSpace} s.
+ closedCurve : (%,L L R) -> %
+ ++ closedCurve(s,[[lr0],[lr1],...,[lrn],[lr0]]) adds a closed curve
+ ++ component defined by a list of points \spad{lr0} through \spad{lrn},
+ ++ which are lists of elements from the domain \spad{PointDomain(m,R)},
+ ++ where R is the \spadtype{Ring} over which the point elements are
+ ++ defined and m is the dimension of the points, in which the last element
+ ++ of the list of points contains a copy of the first element list, lr0.
+ ++ The closed curve is added to the \spadtype{ThreeSpace}, s.
+ closedCurve : L POINT -> %
+ ++ closedCurve(lp) sets a list of points defined by the first element
+ ++ of lp through the last element of lp and back to the first elelment
+ ++ again and returns a \spadtype{ThreeSpace} whose component is the
+ ++ closed curve defined by lp.
+ closedCurve : % -> L POINT
+ ++ closedCurve(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a single closed curve component defined by a list of
+ ++ points in which the first point is also the last point, all of which
+ ++ are from the domain \spad{PointDomain(m,R)} and if so, returns the
+ ++ list of points. An error is signaled otherwise.
+ closedCurve? : % -> B
+ ++ closedCurve?(s) returns true if the \spadtype{ThreeSpace} s contains
+ ++ a single closed curve component, i.e., the first element of the curve
+ ++ is also the last element, or false otherwise.
+ polygon : (%,L POINT) -> %
+ ++ polygon(s,[p0,p1,...,pn]) adds a polygon component defined by a list of
+ ++ points, p0 throught pn, to the \spadtype{ThreeSpace} s.
+ polygon : (%,L L R) -> %
+ ++ polygon(s,[[r0],[r1],...,[rn]]) adds a polygon component defined
+ ++ by a list of points \spad{r0} through \spad{rn}, which are lists of
+ ++ elements from the domain \spad{PointDomain(m,R)} to the
+ ++ \spadtype{ThreeSpace} s, where m is the dimension of the points
+ ++ and R is the \spadtype{Ring} over which the points are defined.
+ polygon : L POINT -> %
+ ++ polygon([p0,p1,...,pn]) creates a polygon defined by a list of points,
+ ++ p0 through pn, and returns a \spadtype{ThreeSpace} whose component
+ ++ is the polygon.
+ polygon : % -> L POINT
+ ++ polygon(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a single polygon component defined by a list of
+ ++ points, and if so, returns the list of points; An error is signaled
+ ++ otherwise.
+ polygon? : % -> B
+ ++ polygon?(s) returns true if the \spadtype{ThreeSpace} s contains
+ ++ a single polygon component, or false otherwise.
+ mesh : (%,L L POINT,L PROP,PROP) -> %
+ ++ mesh(s,[[p0],[p1],...,[pn]],[props],prop) adds a surface component,
+ ++ defined over a list curves which contains lists of points, to the
+ ++ \spadtype{ThreeSpace} s; props is a list which contains the subspace
+ ++ component properties for each surface parameter, and prop is the
+ ++ subspace component property by which the points are defined.
+ mesh : (%,L L L R,L PROP,PROP) -> %
+ ++ mesh(s,[ [[r10]...,[r1m]], [[r20]...,[r2m]],..., [[rn0]...,[rnm]] ], [props], prop)
+ ++ adds a surface component to the \spadtype{ThreeSpace} s, which is
+ ++ defined over a rectangular domain of size WxH where W is the number
+ ++ of lists of points from the domain \spad{PointDomain(R)} and H is the
+ ++ number of elements in each of those lists; lprops is the list of the
+ ++ subspace component properties for each curve list, and prop is
+ ++ the subspace component property by which the points are defined.
+ mesh : (%,L L POINT,B,B) -> %
+ ++ mesh(s,[[p0],[p1],...,[pn]], close1, close2) adds a surface component to
+ ++ the \spadtype{ThreeSpace}, which is defined over a list of curves,
+ ++ in which each of these curves is a list of points.
+ ++ The boolean arguments close1 and close2 indicate how the surface
+ ++ is to be closed. Argument close1 equal true
+ ++ means that each individual list (a curve) is to be closed, i.e. the
+ ++ last point of the list is to be connected to the first point.
+ ++ Argument close2 equal true
+ ++ means that the boundary at one end of the surface is to be
+ ++ connected to the boundary at the other end, i.e. the boundaries
+ ++ are defined as the first list of points (curve) and
+ ++ the last list of points (curve).
+ mesh : (%,L L L R,B,B) -> %
+ ++ mesh(s,[ [[r10]...,[r1m]], [[r20]...,[r2m]],..., [[rn0]...,[rnm]] ], close1, close2)
+ ++ adds a surface component to the \spadtype{ThreeSpace} s, which is
+ ++ defined over a rectangular domain of size WxH where W is the number
+ ++ of lists of points from the domain \spad{PointDomain(R)} and H is the
+ ++ number of elements in each of those lists; the booleans close1 and
+ ++ close2 indicate how the surface is to be closed: if close1 is true
+ ++ this means that each individual list (a curve) is to be closed (i.e.,
+ ++ the last point of the list is to be connected to the first point);
+ ++ if close2 is true, this means that the boundary at one end of the
+ ++ surface is to be connected to the boundary at the other end
+ ++ (the boundaries are defined as the first list of points (curve)
+ ++ and the last list of points (curve)).
+ mesh : L L POINT -> %
+ ++ mesh([[p0],[p1],...,[pn]]) creates a surface defined by a list of
+ ++ curves which are lists, p0 through pn, of points, and returns a
+ ++ \spadtype{ThreeSpace} whose component is the surface.
+ mesh : (L L POINT,B,B) -> %
+ ++ mesh([[p0],[p1],...,[pn]], close1, close2) creates a surface defined
+ ++ over a list of curves, p0 through pn, which are lists of points;
+ ++ the booleans close1 and close2 indicate how the surface is to be
+ ++ closed: close1 set to true means that each individual list (a curve)
+ ++ is to be closed (that is, the last point of the list is to be
+ ++ connected to the first point); close2 set to true means that the
+ ++ boundary at one end of the surface is to be connected to the boundary
+ ++ at the other end (the boundaries are defined as the first list of
+ ++ points (curve) and the last list of points (curve)); the
+ ++ \spadtype{ThreeSpace} containing this surface is returned.
+ mesh : % -> L L POINT
+ ++ mesh(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a single surface component defined by a list curves which
+ ++ contain lists of points, and if so, returns the list of lists of
+ ++ points; An error is signaled otherwise.
+ mesh? : % -> B
+ ++ mesh?(s) returns true if the \spadtype{ThreeSpace} s is composed of one
+ ++ component, a mesh comprising a list of curves which are lists
+ ++ of points, or returns false if otherwise
+ lp : % -> L POINT
+ ++ lp(s) returns the list of points component which the
+ ++ \spadtype{ThreeSpace}, s, contains; these points are used by reference,
+ ++ i.e., the component holds indices referring to the points rather
+ ++ than the points themselves. This allows for sharing of the points.
+ lllip : % -> L L L NNI
+ ++ lllip(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a list of components, which are lists of curves,
+ ++ which are lists of indices to points, and if so, returns the list of
+ ++ lists of lists; An error is signaled otherwise.
+ lllp : % -> L L L POINT -- used by view3D
+ ++ lllp(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a list of components, which are lists of curves,
+ ++ which are lists of points, and if so, returns the list of
+ ++ lists of lists; An error is signaled otherwise.
+ llprop : % -> L L PROP -- used by view3D
+ ++ llprop(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a list of curves which are lists of the
+ ++ subspace component properties of the curves, and if so, returns the
+ ++ list of lists; An error is signaled otherwise.
+ lprop : % -> L PROP -- used by view3D
+ ++ lprop(s) checks to see if the \spadtype{ThreeSpace}, s, is
+ ++ composed of a list of subspace component properties, and if so,
+ ++ returns the list; An error is signaled otherwise.
+ objects : % -> OBJ3D
+ ++ objects(s) returns the \spadtype{ThreeSpace}, s, in the form of a
+ ++ 3D object record containing information on the number of points,
+ ++ curves, polygons and constructs comprising the \spadtype{ThreeSpace}..
+ check : % -> % -- used by mesh
+ ++ check(s) returns lllpt, list of lists of lists of point information
+ ++ about the \spadtype{ThreeSpace} s.
+ subspace : % -> SUBSPACE
+ ++ subspace(s) returns the \spadtype{SubSpace} which holds all the point
+ ++ information in the \spadtype{ThreeSpace}, s.
+ coerce : % -> O
+ ++ coerce(s) returns the \spadtype{ThreeSpace} s to Output format.
+
+@
+\section{domain SPACE3 ThreeSpace}
+<<domain SPACE3 ThreeSpace>>=
+)abbrev domain SPACE3 ThreeSpace
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Operations: create3Space, numberOfComponents, numberOfComposites,
+++ merge, composite, components, copy, enterPointData, modifyPointData, point,
+++ point?, curve, curve?, closedCurve, closedCurve?, polygon, polygon? mesh,
+++ mesh?, lp, lllip, lllp, llprop, lprop, objects, check, subspace, coerce
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: The domain ThreeSpace is used for creating three dimensional
+++ objects using functions for defining points, curves, polygons, constructs
+++ and the subspaces containing them.
+
+ThreeSpace(R:Ring):Exports == Implementation where
+ -- m is the dimension of the point
+
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ L ==> List
+ B ==> Boolean
+ O ==> OutputForm
+ SUBSPACE ==> SubSpace(3,R)
+ POINT ==> Point(R)
+ PROP ==> SubSpaceComponentProperty()
+ REP3D ==> Record(lp:L POINT,llliPt:L L L NNI, llProp:L L PROP, lProp:L PROP)
+ OBJ3D ==> Record(points:NNI, curves:NNI, polygons:NNI, constructs:NNI)
+
+ Exports ==> ThreeSpaceCategory(R)
+ Implementation ==> add
+ import COMPPROP
+ import POINT
+ import SUBSPACE
+ import ListFunctions2(List(R),POINT)
+ import Set(NNI)
+
+ Rep := Record( subspaceField:SUBSPACE, compositesField:L SUBSPACE, _
+ rep3DField:REP3D, objectsField:OBJ3D, _
+ converted:B)
+
+--% Local Functions
+ convertSpace : % -> %
+ convertSpace space ==
+ space.converted => space
+ space.converted := true
+ lllipt : L L L NNI := []
+ llprop : L L PROP := []
+ lprop : L PROP := []
+ for component in children space.subspaceField repeat
+ lprop := cons(extractProperty component,lprop)
+ tmpllipt : L L NNI := []
+ tmplprop : L PROP := []
+ for curve in children component repeat
+ tmplprop := cons(extractProperty curve,tmplprop)
+ tmplipt : L NNI := []
+ for point in children curve repeat
+ tmplipt := cons(extractIndex point,tmplipt)
+ tmpllipt := cons(reverse_! tmplipt,tmpllipt)
+ llprop := cons(reverse_! tmplprop, llprop)
+ lllipt := cons(reverse_! tmpllipt, lllipt)
+ space.rep3DField := [pointData space.subspaceField,
+ reverse_! lllipt,reverse_! llprop,reverse_! lprop]
+ space
+
+
+--% Exported Functions
+ polygon(space:%,points:L POINT) ==
+ #points < 3 =>
+ error "You need at least 3 points to define a polygon"
+ pt := addPoint2(space.subspaceField,first points)
+ points := rest points
+ addPointLast(space.subspaceField, pt, first points, 1)
+ for p in rest points repeat
+ addPointLast(space.subspaceField, pt, p, 2)
+ space.converted := false
+ space
+ create3Space() == [ new()$SUBSPACE, [], [ [], [], [], [] ], [0,0,0,0], false ]
+ create3Space(s) == [ s, [], [ [], [], [], [] ], [0,0,0,0], false ]
+ numberOfComponents(space) == #(children((space::Rep).subspaceField))
+ numberOfComposites(space) == #((space::Rep).compositesField)
+ merge(listOfThreeSpaces) ==
+ -- * -- we may want to remove duplicate components when that functionality exists in List
+ newspace := create3Space(merge([ts.subspaceField for ts in listOfThreeSpaces]))
+-- newspace.compositesField := [for cs in ts.compositesField for ts in listOfThreeSpaces]
+ for ts in listOfThreeSpaces repeat
+ newspace.compositesField := append(ts.compositesField,newspace.compositesField)
+ newspace
+ merge(s1,s2) == merge([s1,s2])
+ composite(listOfThreeSpaces) ==
+ space := create3Space()
+ space.subspaceField := merge [s.subspaceField for s in listOfThreeSpaces]
+ space.compositesField := [deepCopy space.subspaceField]
+-- for aSpace in listOfThreeSpaces repeat
+ -- create a composite (which are supercomponents that group
+ -- separate components together) out of all possible components
+-- space.compositesField := append(children aSpace.subspaceField,space.compositesField)
+ space
+ components(space) == [create3Space(s) for s in separate space.subspaceField]
+ composites(space) == [create3Space(s) for s in space.compositesField]
+ copy(space) ==
+ spc := create3Space(deepCopy(space.subspaceField))
+ spc.compositesField := [deepCopy s for s in space.compositesField]
+ spc
+
+ enterPointData(space,listOfPoints) ==
+ for p in listOfPoints repeat
+ addPoint(space.subspaceField,p)
+ #(pointData space.subspaceField)
+ modifyPointData(space,i,p) ==
+ modifyPoint(space.subspaceField,i,p)
+ space
+
+ -- 3D primitives, each grouped in the following order
+ -- xxx?(s) : query whether the threespace, s, holds an xxx
+ -- xxx(s) : extract xxx from threespace, s
+ -- xxx(p) : create a new three space with xxx, p
+ -- xxx(s,p) : add xxx, p, to a three space, s
+ -- xxx(s,q) : add an xxx, convertable from q, to a three space, s
+ -- xxx(s,i) : add an xxx, the data for xxx being indexed by reference *** complete this
+ point?(space:%) ==
+ #(c:=children space.subspaceField) > 1$NNI =>
+ error "This ThreeSpace has more than one component"
+ -- our 3-space has one component, a list of list of points
+ #(kid:=children first c) = 1$NNI => -- the component has one subcomponent (a list of points)
+ #(children first kid) = 1$NNI -- this list of points only has one entry, so it's a point
+ false
+ point(space:%) ==
+ point? space => extractPoint(traverse(space.subspaceField,[1,1,1]::L NNI))
+ error "This ThreeSpace holds something other than a single point - try the objects() command"
+ point(aPoint:POINT) == point(create3Space(),aPoint)
+ point(space:%,aPoint:POINT) ==
+ addPoint(space.subspaceField,[],aPoint)
+ space.converted := false
+ space
+ point(space:%,l:L R) ==
+ pt := point(l)
+ point(space,pt)
+ point(space:%,i:NNI) ==
+ addPoint(space.subspaceField,[],i)
+ space.converted := false
+ space
+
+ curve?(space:%) ==
+ #(c:=children space.subspaceField) > 1$NNI =>
+ error "This ThreeSpace has more than one component"
+ -- our 3-space has one component, a list of list of points
+ #(children first c) = 1$NNI -- there is only one subcomponent, so it's a list of points
+ curve(space:%) ==
+ curve? space =>
+ spc := first children first children space.subspaceField
+ [extractPoint(s) for s in children spc]
+ error "This ThreeSpace holds something other than a curve - try the objects() command"
+ curve(points:L POINT) == curve(create3Space(),points)
+ curve(space:%,points:L POINT) ==
+ addPoint(space.subspaceField,[],first points)
+ path : L NNI := [#(children space.subspaceField),1]
+ for p in rest points repeat
+ addPoint(space.subspaceField,path,p)
+ space.converted := false
+ space
+ curve(space:%,points:L L R) ==
+ pts := map(point,points)
+ curve(space,pts)
+
+ closedCurve?(space:%) ==
+ #(c:=children space.subspaceField) > 1$NNI =>
+ error "This ThreeSpace has more than one component"
+ -- our 3-space has one component, a list of list of points
+ #(kid := children first c) = 1$NNI => -- there is one subcomponent => it's a list of points
+ extractClosed first kid -- is it a closed curve?
+ false
+ closedCurve(space:%) ==
+ closedCurve? space =>
+ spc := first children first children space.subspaceField
+ -- get the list of points
+ [extractPoint(s) for s in children spc]
+ -- for now, we are not repeating points...
+ error "This ThreeSpace holds something other than a curve - try the objects() command"
+ closedCurve(points:L POINT) == closedCurve(create3Space(),points)
+ closedCurve(space:%,points:L POINT) ==
+ addPoint(space.subspaceField,[],first points)
+ path : L NNI := [#(children space.subspaceField),1]
+ closeComponent(space.subspaceField,path,true)
+ for p in rest points repeat
+ addPoint(space.subspaceField,path,p)
+ space.converted := false
+ space
+ closedCurve(space:%,points:L L R) ==
+ pts := map(point,points)
+ closedCurve(space,pts)
+
+ polygon?(space:%) ==
+ #(c:=children space.subspaceField) > 1$NNI =>
+ error "This ThreeSpace has more than one component"
+ -- our 3-space has one component, a list of list of points
+ #(kid:=children first c) = 2::NNI =>
+ -- there are two subcomponents
+ -- the convention is to have one point in the first child and to put
+ -- the remaining points (2 or more) in the second, and last, child
+ #(children first kid) = 1$NNI and #(children second kid) > 2::NNI
+ false -- => returns Void...?
+ polygon(space:%) ==
+ polygon? space =>
+ listOfPoints : L POINT :=
+ [extractPoint(first children first (cs := children first children space.subspaceField))]
+ [extractPoint(s) for s in children second cs]
+ error "This ThreeSpace holds something other than a polygon - try the objects() command"
+ polygon(points:L POINT) == polygon(create3Space(),points)
+ polygon(space:%,points:L L R) ==
+ pts := map(point,points)
+ polygon(space,pts)
+
+ mesh?(space:%) ==
+ #(c:=children space.subspaceField) > 1$NNI =>
+ error "This ThreeSpace has more than one component"
+ -- our 3-space has one component, a list of list of points
+ #(kid:=children first c) > 1$NNI =>
+ -- there are two or more subcomponents (list of points)
+ -- so this may be a definition of a mesh; if the size
+ -- of each list of points is the same and they are all
+ -- greater than 1(?) then we have an acceptable mesh
+ -- use a set to hold the curve size info: if heterogenous
+ -- curve sizes exist, then the set would hold all the sizes;
+ -- otherwise it would just have the one element indicating
+ -- the sizes for all the curves
+ whatSizes := brace()$Set(NNI)
+ for eachCurve in kid repeat
+ insert_!(#children eachCurve,whatSizes)
+ #whatSizes > 1 => error "Mesh defined with curves of different sizes"
+ first parts whatSizes < 2 =>
+ error "Mesh defined with single point curves (use curve())"
+ true
+ false
+ mesh(space:%) ==
+ mesh? space =>
+ llp : L L POINT := []
+ for lpSpace in children first children space.subspaceField repeat
+ llp := cons([extractPoint(s) for s in children lpSpace],llp)
+ llp
+ error "This ThreeSpace holds something other than a mesh - try the objects() command"
+ mesh(points:L L POINT) == mesh(create3Space(),points,false,false)
+ mesh(points:L L POINT,prop1:B,prop2:B) == mesh(create3Space(),points,prop1,prop2)
+--+ old ones \/
+ mesh(space:%,llpoints:L L L R,lprops:L PROP,prop:PROP) ==
+ pts := [map(point,points) for points in llpoints]
+ mesh(space,pts,lprops,prop)
+ mesh(space:%,llp:L L POINT,lprops:L PROP,prop:PROP) ==
+ addPoint(space.subspaceField,[],first first llp)
+ defineProperty(space.subspaceField,path:L NNI:=[#children space.subspaceField],prop)
+ path := append(path,[1])
+ defineProperty(space.subspaceField,path,first lprops)
+ for p in rest (first llp) repeat
+ addPoint(space.subspaceField,path,p)
+ for lp in rest llp for aProp in rest lprops for count in 2.. repeat
+ addPoint(space.subspaceField,path := [first path],first lp)
+ path := append(path,[count])
+ defineProperty(space.subspaceField,path,aProp)
+ for p in rest lp repeat
+ addPoint(space.subspaceField,path,p)
+ space.converted := false
+ space
+--+ old ones /\
+ mesh(space:%,llpoints:L L L R,prop1:B,prop2:B) ==
+ pts := [map(point,points) for points in llpoints]
+ mesh(space,pts,prop1,prop2)
+ mesh(space:%,llp:L L POINT,prop1:B,prop2:B) ==
+ -- prop2 refers to property of the ends of a surface (list of lists of points)
+ -- while prop1 refers to the individual curves (list of points)
+ -- ** note we currently use Booleans for closed (rather than a pair
+ -- ** of booleans for closed and solid)
+ propA : PROP := new()
+ close(propA,prop1)
+ propB : PROP := new()
+ close(propB,prop2)
+ addPoint(space.subspaceField,[],first first llp)
+ defineProperty(space.subspaceField,path:L NNI:=[#children space.subspaceField],propB)
+ path := append(path,[1])
+ defineProperty(space.subspaceField,path,propA)
+ for p in rest (first llp) repeat
+ addPoint(space.subspaceField,path,p)
+ for lp in rest llp for count in 2.. repeat
+ addPoint(space.subspaceField,path := [first path],first lp)
+ path := append(path,[count])
+ defineProperty(space.subspaceField,path,propA)
+ for p in rest lp repeat
+ addPoint(space.subspaceField,path,p)
+ space.converted := false
+ space
+
+ lp space ==
+ if ^space.converted then space := convertSpace space
+ space.rep3DField.lp
+ lllip space ==
+ if ^space.converted then space := convertSpace space
+ space.rep3DField.llliPt
+-- lllp space ==
+-- if ^space.converted then space := convertSpace space
+-- space.rep3DField.lllPt
+ llprop space ==
+ if ^space.converted then space := convertSpace space
+ space.rep3DField.llProp
+ lprop space ==
+ if ^space.converted then space := convertSpace space
+ space.rep3DField.lProp
+
+ -- this function is just to see how this representation really
+ -- does work
+ objects space ==
+ if ^space.converted then space := convertSpace space
+ numPts := 0$NNI
+ numCurves := 0$NNI
+ numPolys := 0$NNI
+ numConstructs := 0$NNI
+ for component in children space.subspaceField repeat
+ #(kid:=children component) = 1 =>
+ #(children first kid) = 1 => numPts := numPts + 1
+ numCurves := numCurves + 1
+ (#kid = 2) and _
+ (#children first kid = 1) and _
+ (#children first rest kid ^= 1) =>
+ numPolys := numPolys + 1
+ numConstructs := numConstructs + 1
+ -- otherwise, a mathematical surface is assumed
+ -- there could also be garbage representation
+ -- since there are always more permutations that
+ -- we could ever want, so the user should not
+ -- fumble around too much with the structure
+ -- as other applications need to interpret it
+ [numPts,numCurves,numPolys,numConstructs]
+
+ check(s) ==
+ ^s.converted => convertSpace s
+ s
+
+ subspace(s) == s.subspaceField
+
+ coerce(s) ==
+ if ^s.converted then s := convertSpace s
+ hconcat(["3-Space with "::O, _
+ (sizo:=#(s.rep3DField.llliPt))::O, _
+ (sizo=1=>" component"::O;" components"::O)])
+
+@
+\section{package TOPSP TopLevelThreeSpace}
+<<package TOPSP TopLevelThreeSpace>>=
+)abbrev package TOPSP TopLevelThreeSpace
+++ Description:
+++ This package exports a function for making a \spadtype{ThreeSpace}
+TopLevelThreeSpace(): with
+ createThreeSpace: () -> ThreeSpace DoubleFloat
+ ++ createThreeSpace() creates a \spadtype{ThreeSpace(DoubleFloat)} object
+ ++ capable of holding point, curve, mesh components and any combination.
+ == add
+ createThreeSpace() == create3Space()$ThreeSpace(DoubleFloat)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category SPACEC ThreeSpaceCategory>>
+<<domain SPACE3 ThreeSpace>>
+<<package TOPSP TopLevelThreeSpace>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/special.spad.pamphlet b/src/algebra/special.spad.pamphlet
new file mode 100644
index 00000000..1765eebd
--- /dev/null
+++ b/src/algebra/special.spad.pamphlet
@@ -0,0 +1,456 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra special.spad}
+\author{Bruce W. Char, Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DFSFUN DoubleFloatSpecialFunctions}
+<<package DFSFUN DoubleFloatSpecialFunctions>>=
+)abbrev package DFSFUN DoubleFloatSpecialFunctions
+++ Author: Bruce W. Char, Stephen M. Watt
+++ Date Created: 1990
+++ Date Last Updated: June 25, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package provides special functions for double precision
+++ real and complex floating point.
+
+DoubleFloatSpecialFunctions(): Exports == Impl where
+ NNI ==> NonNegativeInteger
+ R ==> DoubleFloat
+ C ==> Complex DoubleFloat
+
+ Exports ==> with
+ Gamma: R -> R
+ ++ Gamma(x) is the Euler gamma function, \spad{Gamma(x)}, defined by
+ ++ \spad{Gamma(x) = integrate(t^(x-1)*exp(-t), t=0..%infinity)}.
+ Gamma: C -> C
+ ++ Gamma(x) is the Euler gamma function, \spad{Gamma(x)}, defined by
+ ++ \spad{Gamma(x) = integrate(t^(x-1)*exp(-t), t=0..%infinity)}.
+
+ Beta: (R, R) -> R
+ ++ Beta(x, y) is the Euler beta function, \spad{B(x,y)}, defined by
+ ++ \spad{Beta(x,y) = integrate(t^(x-1)*(1-t)^(y-1), t=0..1)}.
+ ++ This is related to \spad{Gamma(x)} by
+ ++ \spad{Beta(x,y) = Gamma(x)*Gamma(y) / Gamma(x + y)}.
+ Beta: (C, C) -> C
+ ++ Beta(x, y) is the Euler beta function, \spad{B(x,y)}, defined by
+ ++ \spad{Beta(x,y) = integrate(t^(x-1)*(1-t)^(y-1), t=0..1)}.
+ ++ This is related to \spad{Gamma(x)} by
+ ++ \spad{Beta(x,y) = Gamma(x)*Gamma(y) / Gamma(x + y)}.
+
+ logGamma: R -> R
+ ++ logGamma(x) is the natural log of \spad{Gamma(x)}.
+ ++ This can often be computed even if \spad{Gamma(x)} cannot.
+ logGamma: C -> C
+ ++ logGamma(x) is the natural log of \spad{Gamma(x)}.
+ ++ This can often be computed even if \spad{Gamma(x)} cannot.
+
+ digamma: R -> R
+ ++ digamma(x) is the function, \spad{psi(x)}, defined by
+ ++ \spad{psi(x) = Gamma'(x)/Gamma(x)}.
+ digamma: C -> C
+ ++ digamma(x) is the function, \spad{psi(x)}, defined by
+ ++ \spad{psi(x) = Gamma'(x)/Gamma(x)}.
+
+ polygamma: (NNI, R) -> R
+ ++ polygamma(n, x) is the n-th derivative of \spad{digamma(x)}.
+ polygamma: (NNI, C) -> C
+ ++ polygamma(n, x) is the n-th derivative of \spad{digamma(x)}.
+
+
+ besselJ: (R,R) -> R
+ ++ besselJ(v,x) is the Bessel function of the first kind,
+ ++ \spad{J(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) + (x^2-v^2)w(x) = 0}.
+ besselJ: (C,C) -> C
+ ++ besselJ(v,x) is the Bessel function of the first kind,
+ ++ \spad{J(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) + (x^2-v^2)w(x) = 0}.
+
+ besselY: (R, R) -> R
+ ++ besselY(v,x) is the Bessel function of the second kind,
+ ++ \spad{Y(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) + (x^2-v^2)w(x) = 0}.
+ ++ Note: The default implmentation uses the relation
+ ++ \spad{Y(v,x) = (J(v,x) cos(v*%pi) - J(-v,x))/sin(v*%pi)}
+ ++ so is not valid for integer values of v.
+ besselY: (C, C) -> C
+ ++ besselY(v,x) is the Bessel function of the second kind,
+ ++ \spad{Y(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) + (x^2-v^2)w(x) = 0}.
+ ++ Note: The default implmentation uses the relation
+ ++ \spad{Y(v,x) = (J(v,x) cos(v*%pi) - J(-v,x))/sin(v*%pi)}
+ ++ so is not valid for integer values of v.
+
+ besselI: (R,R) -> R
+ ++ besselI(v,x) is the modified Bessel function of the first kind,
+ ++ \spad{I(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) - (x^2+v^2)w(x) = 0}.
+ besselI: (C,C) -> C
+ ++ besselI(v,x) is the modified Bessel function of the first kind,
+ ++ \spad{I(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) - (x^2+v^2)w(x) = 0}.
+
+ besselK: (R, R) -> R
+ ++ besselK(v,x) is the modified Bessel function of the first kind,
+ ++ \spad{K(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) - (x^2+v^2)w(x) = 0}.
+ ++ Note: The default implmentation uses the relation
+ ++ \spad{K(v,x) = %pi/2*(I(-v,x) - I(v,x))/sin(v*%pi)}.
+ ++ so is not valid for integer values of v.
+ besselK: (C, C) -> C
+ ++ besselK(v,x) is the modified Bessel function of the first kind,
+ ++ \spad{K(v,x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{x^2 w''(x) + x w'(x) - (x^2+v^2)w(x) = 0}.
+ ++ Note: The default implmentation uses the relation
+ ++ \spad{K(v,x) = %pi/2*(I(-v,x) - I(v,x))/sin(v*%pi)}
+ ++ so is not valid for integer values of v.
+
+ airyAi: C -> C
+ ++ airyAi(x) is the Airy function \spad{Ai(x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{Ai''(x) - x * Ai(x) = 0}.
+ airyAi: R -> R
+ ++ airyAi(x) is the Airy function \spad{Ai(x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{Ai''(x) - x * Ai(x) = 0}.
+
+ airyBi: R -> R
+ ++ airyBi(x) is the Airy function \spad{Bi(x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{Bi''(x) - x * Bi(x) = 0}.
+ airyBi: C -> C
+ ++ airyBi(x) is the Airy function \spad{Bi(x)}.
+ ++ This function satisfies the differential equation:
+ ++ \spad{Bi''(x) - x * Bi(x) = 0}.
+
+ hypergeometric0F1: (R, R) -> R
+ ++ hypergeometric0F1(c,z) is the hypergeometric function
+ ++ \spad{0F1(; c; z)}.
+ hypergeometric0F1: (C, C) -> C
+ ++ hypergeometric0F1(c,z) is the hypergeometric function
+ ++ \spad{0F1(; c; z)}.
+
+
+ Impl ==> add
+ a, v, w, z: C
+ n, x, y: R
+
+ -- These are hooks to Bruce's boot code.
+ Gamma z == CGAMMA(z)$Lisp
+ Gamma x == RGAMMA(x)$Lisp
+
+ polygamma(k,z) == CPSI(k, z)$Lisp
+ polygamma(k,x) == RPSI(k, x)$Lisp
+
+ logGamma z == CLNGAMMA(z)$Lisp
+ logGamma x == RLNGAMMA(x)$Lisp
+
+ besselJ(v,z) == CBESSELJ(v,z)$Lisp
+ besselJ(n,x) == RBESSELJ(n,x)$Lisp
+
+ besselI(v,z) == CBESSELI(v,z)$Lisp
+ besselI(n,x) == RBESSELI(n,x)$Lisp
+
+ hypergeometric0F1(a,z) == CHYPER0F1(a, z)$Lisp
+ hypergeometric0F1(n,x) == retract hypergeometric0F1(n::C, x::C)
+
+
+ -- All others are defined in terms of these.
+ digamma x == polygamma(0, x)
+ digamma z == polygamma(0, z)
+
+ Beta(x,y) == Gamma(x)*Gamma(y)/Gamma(x+y)
+ Beta(w,z) == Gamma(w)*Gamma(z)/Gamma(w+z)
+
+ fuzz := (10::R)**(-7)
+
+ import IntegerRetractions(R)
+ import IntegerRetractions(C)
+
+ besselY(n,x) ==
+ if integer? n then n := n + fuzz
+ vp := n * pi()$R
+ (cos(vp) * besselJ(n,x) - besselJ(-n,x) )/sin(vp)
+ besselY(v,z) ==
+ if integer? v then v := v + fuzz::C
+ vp := v * pi()$C
+ (cos(vp) * besselJ(v,z) - besselJ(-v,z) )/sin(vp)
+
+ besselK(n,x) ==
+ if integer? n then n := n + fuzz
+ p := pi()$R
+ vp := n*p
+ ahalf:= 1/(2::R)
+ p * ahalf * ( besselI(-n,x) - besselI(n,x) )/sin(vp)
+ besselK(v,z) ==
+ if integer? v then v := v + fuzz::C
+ p := pi()$C
+ vp := v*p
+ ahalf:= 1/(2::C)
+ p * ahalf * ( besselI(-v,z) - besselI(v,z) )/sin(vp)
+
+ airyAi x ==
+ ahalf := recip(2::R)::R
+ athird := recip(3::R)::R
+ eta := 2 * athird * (-x) ** (3*ahalf)
+ (-x)**ahalf * athird * (besselJ(-athird,eta) + besselJ(athird,eta))
+ airyAi z ==
+ ahalf := recip(2::C)::C
+ athird := recip(3::C)::C
+ eta := 2 * athird * (-z) ** (3*ahalf)
+ (-z)**ahalf * athird * (besselJ(-athird,eta) + besselJ(athird,eta))
+
+ airyBi x ==
+ ahalf := recip(2::R)::R
+ athird := recip(3::R)::R
+ eta := 2 * athird * (-x) ** (3*ahalf)
+ (-x*athird)**ahalf * ( besselJ(-athird,eta) - besselJ(athird,eta) )
+
+ airyBi z ==
+ ahalf := recip(2::C)::C
+ athird := recip(3::C)::C
+ eta := 2 * athird * (-z) ** (3*ahalf)
+ (-z*athird)**ahalf * ( besselJ(-athird,eta) - besselJ(athird,eta) )
+
+@
+\section{package ORTHPOL OrthogonalPolynomialFunctions}
+<<package ORTHPOL OrthogonalPolynomialFunctions>>=
+)abbrev package ORTHPOL OrthogonalPolynomialFunctions
+++ Author: Stephen M. Watt
+++ Date Created: 1990
+++ Date Last Updated: June 25, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package provides orthogonal polynomials as functions on a ring.
+
+OrthogonalPolynomialFunctions(R: CommutativeRing): Exports == Impl where
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+
+ Exports ==> with
+
+ chebyshevT: (NNI, R) -> R
+ ++ chebyshevT(n,x) is the n-th Chebyshev polynomial of the first
+ ++ kind, \spad{T[n](x)}. These are defined by
+ ++ \spad{(1-t*x)/(1-2*t*x+t**2) = sum(T[n](x) *t**n, n = 0..)}.
+
+ chebyshevU: (NNI, R) -> R
+ ++ chebyshevU(n,x) is the n-th Chebyshev polynomial of the second
+ ++ kind, \spad{U[n](x)}. These are defined by
+ ++ \spad{1/(1-2*t*x+t**2) = sum(T[n](x) *t**n, n = 0..)}.
+
+ hermiteH: (NNI, R) -> R
+ ++ hermiteH(n,x) is the n-th Hermite polynomial, \spad{H[n](x)}.
+ ++ These are defined by
+ ++ \spad{exp(2*t*x-t**2) = sum(H[n](x)*t**n/n!, n = 0..)}.
+
+ laguerreL: (NNI, R) -> R
+ ++ laguerreL(n,x) is the n-th Laguerre polynomial, \spad{L[n](x)}.
+ ++ These are defined by
+ ++ \spad{exp(-t*x/(1-t))/(1-t) = sum(L[n](x)*t**n/n!, n = 0..)}.
+
+ laguerreL: (NNI, NNI, R) -> R
+ ++ laguerreL(m,n,x) is the associated Laguerre polynomial,
+ ++ \spad{L<m>[n](x)}. This is the m-th derivative of \spad{L[n](x)}.
+
+ if R has Algebra RN then
+ legendreP: (NNI, R) -> R
+ ++ legendreP(n,x) is the n-th Legendre polynomial,
+ ++ \spad{P[n](x)}. These are defined by
+ ++ \spad{1/sqrt(1-2*x*t+t**2) = sum(P[n](x)*t**n, n = 0..)}.
+
+ Impl ==> add
+ p0, p1: R
+ cx: Integer
+
+ import IntegerCombinatoricFunctions()
+
+ laguerreL(n, x) ==
+ n = 0 => 1
+ (p1, p0) := (-x + 1, 1)
+ for i in 1..n-1 repeat
+ (p1, p0) := ((2*i::R + 1 - x)*p1 - i**2*p0, p1)
+ p1
+ laguerreL(m, n, x) ==
+ ni := n::Integer
+ mi := m::Integer
+ cx := (-1)**m * binomial(ni,ni-mi) * factorial(ni)
+ p0 := 1
+ p1 := cx::R
+ for j in 1..ni-mi repeat
+ cx := -cx*(ni-mi-j+1)
+ cx := (cx exquo ((mi+j)*j))::Integer
+ p0 := p0 * x
+ p1 := p1 + cx*p0
+ p1
+ chebyshevT(n, x) ==
+ n = 0 => 1
+ (p1, p0) := (x, 1)
+ for i in 1..n-1 repeat
+ (p1, p0) := (2*x*p1 - p0, p1)
+ p1
+ chebyshevU(n, x) ==
+ n = 0 => 1
+ (p1, p0) := (2*x, 1)
+ for i in 1..n-1 repeat
+ (p1, p0) := (2*x*p1 - p0, p1)
+ p1
+ hermiteH(n, x) ==
+ n = 0 => 1
+ (p1, p0) := (2*x, 1)
+ for i in 1..n-1 repeat
+ (p1, p0) := (2*x*p1 - 2*i*p0, p1)
+ p1
+ if R has Algebra RN then
+ legendreP(n, x) ==
+ n = 0 => 1
+ p0 := 1
+ p1 := x
+ for i in 1..n-1 repeat
+ c: RN := 1/(i+1)
+ (p1, p0) := (c*((2*i+1)*x*p1 - i*p0), p1)
+ p1
+
+@
+\section{package NTPOLFN NumberTheoreticPolynomialFunctions}
+<<package NTPOLFN NumberTheoreticPolynomialFunctions>>=
+)abbrev package NTPOLFN NumberTheoreticPolynomialFunctions
+++ Author: Stephen M. Watt
+++ Date Created: 1990
+++ Date Last Updated: June 25, 1991
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package provides polynomials as functions on a ring.
+
+NumberTheoreticPolynomialFunctions(R: CommutativeRing): Exports == Impl where
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+
+ Exports ==> with
+
+ cyclotomic: (NNI, R) -> R
+ ++ cyclotomic(n,r) \undocumented
+
+ if R has Algebra RN then
+ bernoulliB: (NNI, R) -> R
+ ++ bernoulliB(n,r) \undocumented
+ eulerE: (NNI, R) -> R
+ ++ eulerE(n,r) \undocumented
+
+ Impl ==> add
+
+ import PolynomialNumberTheoryFunctions()
+
+ I ==> Integer
+ SUP ==> SparseUnivariatePolynomial
+
+ -- This is the wrong way to evaluate the polynomial.
+ cyclotomic(k, x) ==
+ p: SUP(I) := cyclotomic(k)
+ r: R := 0
+ while p ^= 0 repeat
+ d := degree p
+ c := leadingCoefficient p
+ p := reductum p
+ r := c*x**d + r
+ r
+
+ if R has Algebra RN then
+ eulerE(k, x) ==
+ p: SUP(RN) := euler(k)
+ r: R := 0
+ while p ^= 0 repeat
+ d := degree p
+ c := leadingCoefficient p
+ p := reductum p
+ r := c*x**d + r
+ r
+ bernoulliB(k, x) ==
+ p: SUP(RN) := bernoulli(k)
+ r: R := 0
+ while p ^= 0 repeat
+ d := degree p
+ c := leadingCoefficient p
+ p := reductum p
+ r := c*x**d + r
+ r
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DFSFUN DoubleFloatSpecialFunctions>>
+<<package ORTHPOL OrthogonalPolynomialFunctions>>
+<<package NTPOLFN NumberTheoreticPolynomialFunctions>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sregset.spad.pamphlet b/src/algebra/sregset.spad.pamphlet
new file mode 100644
index 00000000..19886881
--- /dev/null
+++ b/src/algebra/sregset.spad.pamphlet
@@ -0,0 +1,1606 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sregset.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category SFRTCAT SquareFreeRegularTriangularSetCategory}
+<<category SFRTCAT SquareFreeRegularTriangularSetCategory>>=
+)abbrev category SFRTCAT SquareFreeRegularTriangularSetCategory
+++ Author: Marc Moreno Maza
+++ Date Created: 09/03/1996
+++ Date Last Updated: 09/10/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See: essai Graphisme
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ Description:
+++ The category of square-free regular triangular sets.
+++ A regular triangular set \spad{ts} is square-free if
+++ the gcd of any polynomial \spad{p} in \spad{ts} and
+++ \spad{differentiate(p,mvar(p))} w.r.t.
+++ \axiomOpFrom{collectUnder}{TriangularSetCategory}(ts,\axiomOpFrom{mvar}{RecursivePolynomialCategory}(p))
+++ has degree zero w.r.t. \spad{mvar(p)}. Thus any square-free regular
+++ set defines a tower of square-free simple extensions.\newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+++ [2] M. KALKBRENER "Algorithmic properties of polynomial rings"
+++ Habilitation Thesis, ETZH, Zurich, 1995.
+++ [3] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+
+
+
+SquareFreeRegularTriangularSetCategory(R:GcdDomain,E:OrderedAbelianMonoidSup,_
+ V:OrderedSet,P:RecursivePolynomialCategory(R,E,V)):
+ Category ==
+ RegularTriangularSetCategory(R,E,V,P)
+
+@
+\section{package SFQCMPK SquareFreeQuasiComponentPackage}
+<<package SFQCMPK SquareFreeQuasiComponentPackage>>=
+)abbrev package SFQCMPK SquareFreeQuasiComponentPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 09/23/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A internal package for removing redundant quasi-components and redundant
+++ branches when decomposing a variety by means of quasi-components
+++ of regular triangular sets. \newline
+++ References :
+++ [1] D. LAZARD "A new method for solving algebraic systems of
+++ positive dimension" Discr. App. Math. 33:147-160,1991
+++ Tech. Report (PoSSo project)
+++ [2] M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+++ [3] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 1.
+
+SquareFreeQuasiComponentPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : RegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ LP ==> List P
+ PtoP ==> P -> P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Branch ==> Record(eq: List P, tower: TS, ineq: List P)
+ UBF ==> Union(Branch,"failed")
+ Split ==> List TS
+ Key ==> Record(left:TS, right:TS)
+ Entry ==> Boolean
+ H ==> TabulatedComputationPackage(Key, Entry)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ SQUAREFREE ==> SquareFreeRegularTriangularSetCategory(R,E,V,P)
+
+ Exports == with
+ startTable!: (S,S,S) -> Void
+ ++ \axiom{startTableGcd!(s1,s2,s3)}
+ ++ is an internal subroutine, exported only for developement.
+ stopTable!: () -> Void
+ ++ \axiom{stopTableGcd!()}
+ ++ is an internal subroutine, exported only for developement.
+ supDimElseRittWu?: (TS,TS) -> Boolean
+ ++ \axiom{supDimElseRittWu(ts,us)} returns true iff \axiom{ts}
+ ++ has less elements than \axiom{us} otherwise if \axiom{ts}
+ ++ has higher rank than \axiom{us} w.r.t. Riit and Wu ordering.
+ algebraicSort: Split -> Split
+ ++ \axiom{algebraicSort(lts)} sorts \axiom{lts} w.r.t
+ ++ \axiomOpFrom{supDimElseRittWu}{QuasiComponentPackage}.
+ moreAlgebraic?: (TS,TS) -> Boolean
+ ++ \axiom{moreAlgebraic?(ts,us)} returns false iff \axiom{ts}
+ ++ and \axiom{us} are both empty, or \axiom{ts}
+ ++ has less elements than \axiom{us}, or some variable is
+ ++ algebraic w.r.t. \axiom{us} and is not w.r.t. \axiom{ts}.
+ subTriSet?: (TS,TS) -> Boolean
+ ++ \axiom{subTriSet?(ts,us)} returns true iff \axiom{ts} is
+ ++ a sub-set of \axiom{us}.
+ subPolSet?: (LP, LP) -> Boolean
+ ++ \axiom{subPolSet?(lp1,lp2)} returns true iff \axiom{lp1} is
+ ++ a sub-set of \axiom{lp2}.
+ internalSubPolSet?: (LP, LP) -> Boolean
+ ++ \axiom{internalSubPolSet?(lp1,lp2)} returns true iff \axiom{lp1} is
+ ++ a sub-set of \axiom{lp2} assuming that these lists are sorted
+ ++ increasingly w.r.t. \axiomOpFrom{infRittWu?}{RecursivePolynomialCategory}.
+ internalInfRittWu?: (LP, LP) -> Boolean
+ ++ \axiom{internalInfRittWu?(lp1,lp2)}
+ ++ is an internal subroutine, exported only for developement.
+ infRittWu?: (LP, LP) -> Boolean
+ ++ \axiom{infRittWu?(lp1,lp2)}
+ ++ is an internal subroutine, exported only for developement.
+ internalSubQuasiComponent?: (TS,TS) -> Union(Boolean,"failed")
+ ++ \axiom{internalSubQuasiComponent?(ts,us)} returns a boolean \spad{b} value
+ ++ if the fact the regular zero set of \axiom{us} contains that of
+ ++ \axiom{ts} can be decided (and in that case \axiom{b} gives this
+ ++ inclusion) otherwise returns \axiom{"failed"}.
+ subQuasiComponent?: (TS,TS) -> Boolean
+ ++ \axiom{subQuasiComponent?(ts,us)} returns true iff
+ ++ \axiomOpFrom{internalSubQuasiComponent?(ts,us)}{QuasiComponentPackage}
+ ++ returs true.
+ subQuasiComponent?: (TS,Split) -> Boolean
+ ++ \axiom{subQuasiComponent?(ts,lus)} returns true iff
+ ++ \axiom{subQuasiComponent?(ts,us)} holds for one \spad{us} in \spad{lus}.
+ removeSuperfluousQuasiComponents: Split -> Split
+ ++ \axiom{removeSuperfluousQuasiComponents(lts)} removes from \axiom{lts}
+ ++ any \spad{ts} such that \axiom{subQuasiComponent?(ts,us)} holds for
+ ++ another \spad{us} in \axiom{lts}.
+ subCase?: (LpWT,LpWT) -> Boolean
+ ++ \axiom{subCase?(lpwt1,lpwt2)}
+ ++ is an internal subroutine, exported only for developement.
+ removeSuperfluousCases: List LpWT -> List LpWT
+ ++ \axiom{removeSuperfluousCases(llpwt)}
+ ++ is an internal subroutine, exported only for developement.
+ prepareDecompose: (LP, List(TS),B,B) -> List Branch
+ ++ \axiom{prepareDecompose(lp,lts,b1,b2)}
+ ++ is an internal subroutine, exported only for developement.
+ branchIfCan: (LP,TS,LP,B,B,B,B,B) -> Union(Branch,"failed")
+ ++ \axiom{branchIfCan(leq,ts,lineq,b1,b2,b3,b4,b5)}
+ ++ is an internal subroutine, exported only for developement.
+
+ Implementation == add
+
+ squareFreeFactors(lp: LP): LP ==
+ lsflp: LP := []
+ for p in lp repeat
+ lsfp := squareFreeFactors(p)$polsetpack
+ lsflp := concat(lsfp,lsflp)
+ sort(infRittWu?,removeDuplicates lsflp)
+
+ startTable!(ok: S, ko: S, domainName: S): Void ==
+ initTable!()$H
+ if (not empty? ok) and (not empty? ko) then printInfo!(ok,ko)$H
+ if (not empty? domainName) then startStats!(domainName)$H
+ void()
+
+ stopTable!(): Void ==
+ if makingStats?()$H then printStats!()$H
+ clearTable!()$H
+
+ supDimElseRittWu? (ts:TS,us:TS): Boolean ==
+ #ts < #us => true
+ #ts > #us => false
+ lp1 :LP := members(ts)
+ lp2 :LP := members(us)
+ while (not empty? lp1) and (not infRittWu?(first(lp2),first(lp1))) repeat
+ lp1 := rest lp1
+ lp2 := rest lp2
+ not empty? lp1
+
+ algebraicSort (lts:Split): Split ==
+ lts := removeDuplicates lts
+ sort(supDimElseRittWu?,lts)
+
+ moreAlgebraic?(ts:TS,us:TS): Boolean ==
+ empty? ts => empty? us
+ empty? us => true
+ #ts < #us => false
+ for p in (members us) repeat
+ not algebraic?(mvar(p),ts) => return false
+ true
+
+ subTriSet?(ts:TS,us:TS): Boolean ==
+ empty? ts => true
+ empty? us => false
+ mvar(ts) > mvar(us) => false
+ mvar(ts) < mvar(us) => subTriSet?(ts,rest(us)::TS)
+ first(ts)::P = first(us)::P => subTriSet?(rest(ts)::TS,rest(us)::TS)
+ false
+
+ internalSubPolSet?(lp1: LP, lp2: LP): Boolean ==
+ empty? lp1 => true
+ empty? lp2 => false
+ associates?(first lp1, first lp2) =>
+ internalSubPolSet?(rest lp1, rest lp2)
+ infRittWu?(first lp1, first lp2) => false
+ internalSubPolSet?(lp1, rest lp2)
+
+ subPolSet?(lp1: LP, lp2: LP): Boolean ==
+ lp1 := sort(infRittWu?, lp1)
+ lp2 := sort(infRittWu?, lp2)
+ internalSubPolSet?(lp1,lp2)
+
+ infRittWu?(lp1: LP, lp2: LP): Boolean ==
+ lp1 := sort(infRittWu?, lp1)
+ lp2 := sort(infRittWu?, lp2)
+ internalInfRittWu?(lp1,lp2)
+
+ internalInfRittWu?(lp1: LP, lp2: LP): Boolean ==
+ empty? lp1 => not empty? lp2
+ empty? lp2 => false
+ infRittWu?(first lp1, first lp2)$P => true
+ infRittWu?(first lp2, first lp1)$P => false
+ infRittWu?(rest lp1, rest lp2)$$
+
+ subCase? (lpwt1:LpWT,lpwt2:LpWT): Boolean ==
+ -- ASSUME lpwt.{1,2}.val is sorted w.r.t. infRittWu?
+ not internalSubPolSet?(lpwt2.val, lpwt1.val) => false
+ subQuasiComponent?(lpwt1.tower,lpwt2.tower)
+
+ if TS has SquareFreeRegularTriangularSetCategory(R,E,V,P)
+ then
+
+ internalSubQuasiComponent?(ts:TS,us:TS): Union(Boolean,"failed") ==
+ subTriSet?(us,ts) => true
+ not moreAlgebraic?(ts,us) => false::Union(Boolean,"failed")
+ for p in (members us) repeat
+ mdeg(p) < mdeg(select(ts,mvar(p))::P) =>
+ return("failed"::Union(Boolean,"failed"))
+ for p in (members us) repeat
+ not zero? initiallyReduce(p,ts) =>
+ return("failed"::Union(Boolean,"failed"))
+ lsfp := squareFreeFactors(initials us)
+ for p in lsfp repeat
+ b: B := invertible?(p,ts)$TS
+ not b =>
+ return(false::Union(Boolean,"failed"))
+ true::Union(Boolean,"failed")
+
+ else
+
+ internalSubQuasiComponent?(ts:TS,us:TS): Union(Boolean,"failed") ==
+ subTriSet?(us,ts) => true
+ not moreAlgebraic?(ts,us) => false::Union(Boolean,"failed")
+ for p in (members us) repeat
+ mdeg(p) < mdeg(select(ts,mvar(p))::P) =>
+ return("failed"::Union(Boolean,"failed"))
+ for p in (members us) repeat
+ not zero? reduceByQuasiMonic(p,ts) =>
+ return("failed"::Union(Boolean,"failed"))
+ true::Union(Boolean,"failed")
+
+ subQuasiComponent?(ts:TS,us:TS): Boolean ==
+ k: Key := [ts, us]
+ e := extractIfCan(k)$H
+ e case Entry => e::Entry
+ ubf: Union(Boolean,"failed") := internalSubQuasiComponent?(ts,us)
+ b: Boolean := (ubf case Boolean) and (ubf::Boolean)
+ insert!(k,b)$H
+ b
+
+ subQuasiComponent?(ts:TS,lus:Split): Boolean ==
+ for us in lus repeat
+ subQuasiComponent?(ts,us)@B => return true
+ false
+
+ removeSuperfluousCases (cases:List LpWT) ==
+ #cases < 2 => cases
+ toSee := sort(supDimElseRittWu?(#1.tower,#2.tower),cases)
+ lpwt1,lpwt2 : LpWT
+ toSave,headmaxcases,maxcases,copymaxcases : List LpWT
+ while not empty? toSee repeat
+ lpwt1 := first toSee
+ toSee := rest toSee
+ toSave := []
+ for lpwt2 in toSee repeat
+ if subCase?(lpwt1,lpwt2)
+ then
+ lpwt1 := lpwt2
+ else
+ if not subCase?(lpwt2,lpwt1)
+ then
+ toSave := cons(lpwt2,toSave)
+ if empty? maxcases
+ then
+ headmaxcases := [lpwt1]
+ maxcases := headmaxcases
+ else
+ copymaxcases := maxcases
+ while (not empty? copymaxcases) and _
+ (not subCase?(lpwt1,first(copymaxcases))) repeat
+ copymaxcases := rest copymaxcases
+ if empty? copymaxcases
+ then
+ setrest!(headmaxcases,[lpwt1])
+ headmaxcases := rest headmaxcases
+ toSee := reverse toSave
+ maxcases
+
+ removeSuperfluousQuasiComponents(lts: Split): Split ==
+ lts := removeDuplicates lts
+ #lts < 2 => lts
+ toSee := algebraicSort lts
+ toSave,headmaxlts,maxlts,copymaxlts : Split
+ while not empty? toSee repeat
+ ts := first toSee
+ toSee := rest toSee
+ toSave := []
+ for us in toSee repeat
+ if subQuasiComponent?(ts,us)@B
+ then
+ ts := us
+ else
+ if not subQuasiComponent?(us,ts)@B
+ then
+ toSave := cons(us,toSave)
+ if empty? maxlts
+ then
+ headmaxlts := [ts]
+ maxlts := headmaxlts
+ else
+ copymaxlts := maxlts
+ while (not empty? copymaxlts) and _
+ (not subQuasiComponent?(ts,first(copymaxlts))@B) repeat
+ copymaxlts := rest copymaxlts
+ if empty? copymaxlts
+ then
+ setrest!(headmaxlts,[ts])
+ headmaxlts := rest headmaxlts
+ toSee := reverse toSave
+ algebraicSort maxlts
+
+ removeAssociates (lp:LP):LP ==
+ removeDuplicates [primitivePart(p) for p in lp]
+
+ branchIfCan(leq: LP,ts: TS,lineq: LP, b1:B,b2:B,b3:B,b4:B,b5:B):UBF ==
+ -- ASSUME pols in leq are squarefree and mainly primitive
+ -- if b1 then CLEAN UP leq
+ -- if b2 then CLEAN UP lineq
+ -- if b3 then SEARCH for ZERO in lineq with leq
+ -- if b4 then SEARCH for ZERO in lineq with ts
+ -- if b5 then SEARCH for ONE in leq with lineq
+ if b1
+ then
+ leq := removeAssociates(leq)
+ leq := remove(zero?,leq)
+ any?(ground?,leq) =>
+ return("failed"::Union(Branch,"failed"))
+ if b2
+ then
+ any?(zero?,lineq) =>
+ return("failed"::Union(Branch,"failed"))
+ lineq := removeRedundantFactors(lineq)$polsetpack
+ if b3
+ then
+ ps: PS := construct(leq)$PS
+ for q in lineq repeat
+ zero? remainder(q,ps).polnum =>
+ return("failed"::Union(Branch,"failed"))
+ (empty? leq) or (empty? lineq) => ([leq, ts, lineq]$Branch)::UBF
+ if b4
+ then
+ for q in lineq repeat
+ zero? initiallyReduce(q,ts) =>
+ return("failed"::Union(Branch,"failed"))
+ if b5
+ then
+ newleq: LP := []
+ for p in leq repeat
+ for q in lineq repeat
+ if mvar(p) = mvar(q)
+ then
+ g := gcd(p,q)
+ newp := (p exquo g)::P
+ ground? newp =>
+ return("failed"::Union(Branch,"failed"))
+ newleq := cons(newp,newleq)
+ else
+ newleq := cons(p,newleq)
+ leq := newleq
+ leq := sort(infRittWu?, removeDuplicates leq)
+ ([leq, ts, lineq]$Branch)::UBF
+
+ prepareDecompose(lp: LP, lts: List(TS), b1: B, b2: B): List Branch ==
+ -- if b1 then REMOVE REDUNDANT COMPONENTS in lts
+ -- if b2 then SPLIT the input system with squareFree
+ lp := sort(infRittWu?, remove(zero?,removeAssociates(lp)))
+ any?(ground?,lp) => []
+ empty? lts => []
+ if b1 then lts := removeSuperfluousQuasiComponents lts
+ not b2 =>
+ [[lp,ts,squareFreeFactors(initials ts)]$Branch for ts in lts]
+ toSee: List Branch
+ lq: LP := []
+ toSee := [[lq,ts,squareFreeFactors(initials ts)]$Branch for ts in lts]
+ empty? lp => toSee
+ for p in lp repeat
+ lsfp := squareFreeFactors(p)$polsetpack
+ branches: List Branch := []
+ lq := []
+ for f in lsfp repeat
+ for branch in toSee repeat
+ leq : LP := branch.eq
+ ts := branch.tower
+ lineq : LP := branch.ineq
+ ubf1: UBF := branchIfCan(leq,ts,lq,false,false,true,true,true)@UBF
+ ubf1 case "failed" => "leave"
+ ubf2: UBF := branchIfCan([f],ts,lineq,false,false,true,true,true)@UBF
+ ubf2 case "failed" => "leave"
+ leq := sort(infRittWu?,removeDuplicates concat(ubf1.eq,ubf2.eq))
+ lineq := sort(infRittWu?,removeDuplicates concat(ubf1.ineq,ubf2.ineq))
+ newBranch := branchIfCan(leq,ts,lineq,false,false,false,false,false)
+ branches:= cons(newBranch::Branch,branches)
+ lq := cons(f,lq)
+ toSee := branches
+ sort(supDimElseRittWu?(#1.tower,#2.tower),toSee)
+
+@
+\section{package SFRGCD SquareFreeRegularTriangularSetGcdPackage}
+<<package SFRGCD SquareFreeRegularTriangularSetGcdPackage>>=
+)abbrev package SFRGCD SquareFreeRegularTriangularSetGcdPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 09/23/1998
+++ Date Last Updated: 10/01/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A internal package for computing gcds and resultants of univariate polynomials
+++ with coefficients in a tower of simple extensions of a field.
+++ There is no need to use directly this package since its main operations are
+++ available from \spad{TS}. \newline
+++ References :
+++ [1] M. MORENO MAZA and R. RIOBOO "Computations of gcd over
+++ algebraic towers of simple extensions" In proceedings of AAECC11
+++ Paris, 1995.
+++ [2] M. MORENO MAZA "Calculs de pgcd au-dessus des tours
+++ d'extensions simples et resolution des systemes d'equations
+++ algebriques" These, Universite P.etM. Curie, Paris, 1997.
+++ [3] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 1.
+
+SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : RegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ LP ==> List P
+ PtoP ==> P -> P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Branch ==> Record(eq: List P, tower: TS, ineq: List P)
+ UBF ==> Union(Branch,"failed")
+ Split ==> List TS
+ KeyGcd ==> Record(arg1: P, arg2: P, arg3: TS, arg4: B)
+ EntryGcd ==> List PWT
+ HGcd ==> TabulatedComputationPackage(KeyGcd, EntryGcd)
+ KeyInvSet ==> Record(arg1: P, arg3: TS)
+ EntryInvSet ==> List TS
+ HInvSet ==> TabulatedComputationPackage(KeyInvSet, EntryInvSet)
+ iprintpack ==> InternalPrintPackage()
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppack ==> SquareFreeQuasiComponentPackage(R,E,V,P,TS)
+
+ SQUAREFREE ==> SquareFreeRegularTriangularSetCategory(R,E,V,P)
+
+ Exports == with
+ startTableGcd!: (S,S,S) -> Void
+ stopTableGcd!: () -> Void
+ startTableInvSet!: (S,S,S) -> Void
+ stopTableInvSet!: () -> Void
+ stosePrepareSubResAlgo: (P,P,TS) -> List LpWT
+ stoseInternalLastSubResultant: (P,P,TS,B,B) -> List PWT
+ stoseInternalLastSubResultant: (List LpWT,V,B) -> List PWT
+ stoseIntegralLastSubResultant: (P,P,TS) -> List PWT
+ stoseLastSubResultant: (P,P,TS) -> List PWT
+ stoseInvertible?: (P,TS) -> B
+ stoseInvertible?_sqfreg: (P,TS) -> List BWT
+ stoseInvertibleSet_sqfreg: (P,TS) -> Split
+ stoseInvertible?_reg: (P,TS) -> List BWT
+ stoseInvertibleSet_reg: (P,TS) -> Split
+ stoseInvertible?: (P,TS) -> List BWT
+ stoseInvertibleSet: (P,TS) -> Split
+ stoseSquareFreePart: (P,TS) -> List PWT
+
+ Implementation == add
+
+ startTableGcd!(ok: S, ko: S, domainName: S): Void ==
+ initTable!()$HGcd
+ printInfo!(ok,ko)$HGcd
+ startStats!(domainName)$HGcd
+ void()
+
+ stopTableGcd!(): Void ==
+ if makingStats?()$HGcd then printStats!()$HGcd
+ clearTable!()$HGcd
+
+ startTableInvSet!(ok: S, ko: S, domainName: S): Void ==
+ initTable!()$HInvSet
+ printInfo!(ok,ko)$HInvSet
+ startStats!(domainName)$HInvSet
+ void()
+
+ stopTableInvSet!(): Void ==
+ if makingStats?()$HInvSet then printStats!()$HInvSet
+ clearTable!()$HInvSet
+
+ stoseInvertible?(p:P,ts:TS): Boolean ==
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => false
+ normalized?(q,ts) => true
+ v := mvar(q)
+ not algebraic?(v,ts) =>
+ toCheck: List BWT := stoseInvertible?(p,ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val = false => return false
+ return true
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ lgwt := stoseInternalLastSubResultant(ts_v,q,ts_v_-,false,true)
+ for gwt in lgwt repeat
+ g := gwt.val;
+ (not ground? g) and (mvar(g) = v) =>
+ return false
+ true
+
+ stosePrepareSubResAlgo(p1:P,p2:P,ts:TS): List LpWT ==
+ -- ASSUME mvar(p1) = mvar(p2) > mvar(ts) and mdeg(p1) >= mdeg(p2)
+ -- ASSUME init(p1) invertible modulo ts !!!
+ toSee: List LpWT := [[[p1,p2],ts]$LpWT]
+ toSave: List LpWT := []
+ v := mvar(p1)
+ while (not empty? toSee) repeat
+ lpwt := first toSee; toSee := rest toSee
+ p1 := lpwt.val.1; p2 := lpwt.val.2
+ ts := lpwt.tower
+ lbwt := stoseInvertible?(leadingCoefficient(p2,v),ts)@(List BWT)
+ for bwt in lbwt repeat
+ (bwt.val = true) and (degree(p2,v) > 0) =>
+ p3 := prem(p1, -p2)
+ s: P := init(p2)**(mdeg(p1) - mdeg(p2))::N
+ toSave := cons([[p2,p3,s],bwt.tower]$LpWT,toSave)
+ -- p2 := initiallyReduce(p2,bwt.tower)
+ newp2 := primitivePart initiallyReduce(p2,bwt.tower)
+ (bwt.val = true) =>
+ -- toSave := cons([[p2,0,1],bwt.tower]$LpWT,toSave)
+ toSave := cons([[p2,0,1],bwt.tower]$LpWT,toSave)
+ -- zero? p2 =>
+ zero? newp2 =>
+ toSave := cons([[p1,0,1],bwt.tower]$LpWT,toSave)
+ -- toSee := cons([[p1,p2],bwt.tower]$LpWT,toSee)
+ toSee := cons([[p1,newp2],bwt.tower]$LpWT,toSee)
+ toSave
+
+ stoseIntegralLastSubResultant(p1:P,p2:P,ts:TS): List PWT ==
+ -- ASSUME mvar(p1) = mvar(p2) > mvar(ts) and mdeg(p1) >= mdeg(p2)
+ -- ASSUME p1 and p2 have no algebraic coefficients
+ lsr := lastSubResultant(p1, p2)
+ ground?(lsr) => [[lsr,ts]$PWT]
+ mvar(lsr) < mvar(p1) => [[lsr,ts]$PWT]
+ gi1i2 := gcd(init(p1),init(p2))
+ ex: Union(P,"failed") := (gi1i2 * lsr) exquo$P init(lsr)
+ ex case "failed" => [[lsr,ts]$PWT]
+ [[ex::P,ts]$PWT]
+
+ stoseInternalLastSubResultant(p1:P,p2:P,ts:TS,b1:B,b2:B): List PWT ==
+ -- ASSUME mvar(p1) = mvar(p2) > mvar(ts) and mdeg(p1) >= mdeg(p2)
+ -- if b1 ASSUME init(p2) invertible w.r.t. ts
+ -- if b2 BREAK with the first non-trivial gcd
+ k: KeyGcd := [p1,p2,ts,b2]
+ e := extractIfCan(k)$HGcd
+ e case EntryGcd => e::EntryGcd
+ toSave: List PWT
+ empty? ts =>
+ toSave := stoseIntegralLastSubResultant(p1,p2,ts)
+ insert!(k,toSave)$HGcd
+ return toSave
+ toSee: List LpWT
+ if b1
+ then
+ p3 := prem(p1, -p2)
+ s: P := init(p2)**(mdeg(p1) - mdeg(p2))::N
+ toSee := [[[p2,p3,s],ts]$LpWT]
+ else
+ toSee := stosePrepareSubResAlgo(p1,p2,ts)
+ toSave := stoseInternalLastSubResultant(toSee,mvar(p1),b2)
+ insert!(k,toSave)$HGcd
+ toSave
+
+ stoseInternalLastSubResultant(llpwt: List LpWT,v:V,b2:B): List PWT ==
+ toReturn: List PWT := []; toSee: List LpWT;
+ while (not empty? llpwt) repeat
+ toSee := llpwt; llpwt := []
+ -- CONSIDER FIRST the vanishing current last subresultant
+ for lpwt in toSee repeat
+ p1 := lpwt.val.1; p2 := lpwt.val.2; s := lpwt.val.3; ts := lpwt.tower
+ lbwt := stoseInvertible?(leadingCoefficient(p2,v),ts)@(List BWT)
+ for bwt in lbwt repeat
+ bwt.val = false =>
+ toReturn := cons([p1,bwt.tower]$PWT, toReturn)
+ b2 and positive?(degree(p1,v)) => return toReturn
+ llpwt := cons([[p1,p2,s],bwt.tower]$LpWT, llpwt)
+ empty? llpwt => "leave"
+ -- CONSIDER NOW the branches where the computations continue
+ toSee := llpwt; llpwt := []
+ lpwt := first toSee; toSee := rest toSee
+ p1 := lpwt.val.1; p2 := lpwt.val.2; s := lpwt.val.3
+ delta: N := (mdeg(p1) - degree(p2,v))::N
+ p3: P := LazardQuotient2(p2, leadingCoefficient(p2,v), s, delta)
+ zero?(degree(p3,v)) =>
+ toReturn := cons([p3,lpwt.tower]$PWT, toReturn)
+ for lpwt in toSee repeat
+ toReturn := cons([p3,lpwt.tower]$PWT, toReturn)
+ (p1, p2) := (p3, next_subResultant2(p1, p2, p3, s))
+ s := leadingCoefficient(p1,v)
+ llpwt := cons([[p1,p2,s],lpwt.tower]$LpWT, llpwt)
+ for lpwt in toSee repeat
+ llpwt := cons([[p1,p2,s],lpwt.tower]$LpWT, llpwt)
+ toReturn
+
+ stoseLastSubResultant(p1:P,p2:P,ts:TS): List PWT ==
+ ground? p1 =>
+ error"in stoseLastSubResultantElseSplit$SFRGCD : bad #1"
+ ground? p2 =>
+ error"in stoseLastSubResultantElseSplit$SFRGCD : bad #2"
+ not (mvar(p2) = mvar(p1)) =>
+ error"in stoseLastSubResultantElseSplit$SFRGCD : bad #2"
+ algebraic?(mvar(p1),ts) =>
+ error"in stoseLastSubResultantElseSplit$SFRGCD : bad #1"
+ not initiallyReduced?(p1,ts) =>
+ error"in stoseLastSubResultantElseSplit$SFRGCD : bad #1"
+ not initiallyReduced?(p2,ts) =>
+ error"in stoseLastSubResultantElseSplit$SFRGCD : bad #2"
+ purelyTranscendental?(p1,ts) and purelyTranscendental?(p2,ts) =>
+ stoseIntegralLastSubResultant(p1,p2,ts)
+ if mdeg(p1) < mdeg(p2) then
+ (p1, p2) := (p2, p1)
+ if odd?(mdeg(p1)) and odd?(mdeg(p2)) then p2 := - p2
+ stoseInternalLastSubResultant(p1,p2,ts,false,false)
+
+ stoseSquareFreePart_wip(p:P, ts: TS): List PWT ==
+ -- ASSUME p is not constant and mvar(p) > mvar(ts)
+ -- ASSUME init(p) is invertible w.r.t. ts
+ -- ASSUME p is mainly primitive
+-- one? mdeg(p) => [[p,ts]$PWT]
+ mdeg(p) = 1 => [[p,ts]$PWT]
+ v := mvar(p)$P
+ q: P := mainPrimitivePart D(p,v)
+ lgwt: List PWT := stoseInternalLastSubResultant(p,q,ts,true,false)
+ lpwt : List PWT := []
+ sfp : P
+ for gwt in lgwt repeat
+ g := gwt.val; us := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ lpwt := cons([p,us],lpwt)
+ g := mainPrimitivePart g
+ sfp := lazyPquo(p,g)
+ sfp := mainPrimitivePart stronglyReduce(sfp,us)
+ lpwt := cons([sfp,us],lpwt)
+ lpwt
+
+ stoseSquareFreePart_base(p:P, ts: TS): List PWT == [[p,ts]$PWT]
+
+ stoseSquareFreePart(p:P, ts: TS): List PWT == stoseSquareFreePart_wip(p,ts)
+
+ stoseInvertible?_sqfreg(p:P,ts:TS): List BWT ==
+ --iprint("+")$iprintpack
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => [[false,ts]$BWT]
+ normalized?(q,ts) => [[true,ts]$BWT]
+ v := mvar(q)
+ not algebraic?(v,ts) =>
+ lbwt: List BWT := []
+ toCheck: List BWT := stoseInvertible?_sqfreg(init(q),ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val => lbwt := cons(bwt,lbwt)
+ newq := removeZero(q,bwt.tower)
+ zero? newq => lbwt := cons(bwt,lbwt)
+ lbwt := concat(stoseInvertible?_sqfreg(newq,bwt.tower)@(List BWT), lbwt)
+ return lbwt
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ lgwt := stoseInternalLastSubResultant(ts_v,q,ts_v_-,false,false)
+ lbwt: List BWT := []
+ lts, lts_g, lts_h: Split
+ for gwt in lgwt repeat
+ g := gwt.val; ts := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ lts := augment(ts_v,ts)$TS
+ lts := augment(members(ts_v_+),lts)$TS
+ for ts in lts repeat
+ lbwt := cons([true, ts]$BWT,lbwt)
+ g := mainPrimitivePart g
+ lts_g := augment(g,ts)$TS
+ lts_g := augment(members(ts_v_+),lts_g)$TS
+ -- USE stoseInternalAugment with parameters ??
+ for ts_g in lts_g repeat
+ lbwt := cons([false, ts_g]$BWT,lbwt)
+ h := lazyPquo(ts_v,g)
+ (ground? h) or (mvar(h) < v) => "leave"
+ h := mainPrimitivePart h
+ lts_h := augment(h,ts)$TS
+ lts_h := augment(members(ts_v_+),lts_h)$TS
+ -- USE stoseInternalAugment with parameters ??
+ for ts_h in lts_h repeat
+ lbwt := cons([true, ts_h]$BWT,lbwt)
+ sort(#1.val < #2.val,lbwt)
+
+ stoseInvertibleSet_sqfreg(p:P,ts:TS): Split ==
+ --iprint("*")$iprintpack
+ k: KeyInvSet := [p,ts]
+ e := extractIfCan(k)$HInvSet
+ e case EntryInvSet => e::EntryInvSet
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => []
+ normalized?(q,ts) => [ts]
+ v := mvar(q)
+ toSave: Split := []
+ not algebraic?(v,ts) =>
+ toCheck: List BWT := stoseInvertible?_sqfreg(init(q),ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val => toSave := cons(bwt.tower,toSave)
+ newq := removeZero(q,bwt.tower)
+ zero? newq => "leave"
+ toSave := concat(stoseInvertibleSet_sqfreg(newq,bwt.tower), toSave)
+ toSave := removeDuplicates toSave
+ return algebraicSort(toSave)$quasicomppack
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ lgwt := stoseInternalLastSubResultant(ts_v,q,ts_v_-,false,false)
+ lts, lts_h: Split
+ for gwt in lgwt repeat
+ g := gwt.val; ts := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ lts := augment(ts_v,ts)$TS
+ lts := augment(members(ts_v_+),lts)$TS
+ toSave := concat(lts,toSave)
+ g := mainPrimitivePart g
+ h := lazyPquo(ts_v,g)
+ h := mainPrimitivePart h
+ (ground? h) or (mvar(h) < v) => "leave"
+ lts_h := augment(h,ts)$TS
+ lts_h := augment(members(ts_v_+),lts_h)$TS
+ toSave := concat(lts_h,toSave)
+ toSave := algebraicSort(toSave)$quasicomppack
+ insert!(k,toSave)$HInvSet
+ toSave
+
+ stoseInvertible?_reg(p:P,ts:TS): List BWT ==
+ --iprint("-")$iprintpack
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => [[false,ts]$BWT]
+ normalized?(q,ts) => [[true,ts]$BWT]
+ v := mvar(q)
+ not algebraic?(v,ts) =>
+ lbwt: List BWT := []
+ toCheck: List BWT := stoseInvertible?_reg(init(q),ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val => lbwt := cons(bwt,lbwt)
+ newq := removeZero(q,bwt.tower)
+ zero? newq => lbwt := cons(bwt,lbwt)
+ lbwt := concat(stoseInvertible?_reg(newq,bwt.tower)@(List BWT), lbwt)
+ return lbwt
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ lgwt := stoseInternalLastSubResultant(ts_v,q,ts_v_-,false,false)
+ lbwt: List BWT := []
+ lts, lts_g, lts_h: Split
+ for gwt in lgwt repeat
+ g := gwt.val; ts := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ lts := augment(ts_v,ts)$TS
+ lts := augment(members(ts_v_+),lts)$TS
+ for ts in lts repeat
+ lbwt := cons([true, ts]$BWT,lbwt)
+ g := mainPrimitivePart g
+ lts_g := augment(g,ts)$TS
+ lts_g := augment(members(ts_v_+),lts_g)$TS
+ -- USE internalAugment with parameters ??
+ for ts_g in lts_g repeat
+ lbwt := cons([false, ts_g]$BWT,lbwt)
+ h := lazyPquo(ts_v,g)
+ (ground? h) or (mvar(h) < v) => "leave"
+ h := mainPrimitivePart h
+ lts_h := augment(h,ts)$TS
+ lts_h := augment(members(ts_v_+),lts_h)$TS
+ -- USE internalAugment with parameters ??
+ for ts_h in lts_h repeat
+ inv := stoseInvertible?_reg(q,ts_h)@(List BWT)
+ lbwt := concat([bwt for bwt in inv | bwt.val],lbwt)
+ sort(#1.val < #2.val,lbwt)
+
+ stoseInvertibleSet_reg(p:P,ts:TS): Split ==
+ --iprint("/")$iprintpack
+ k: KeyInvSet := [p,ts]
+ e := extractIfCan(k)$HInvSet
+ e case EntryInvSet => e::EntryInvSet
+ q := primitivePart initiallyReduce(p,ts)
+ zero? q => []
+ normalized?(q,ts) => [ts]
+ v := mvar(q)
+ toSave: Split := []
+ not algebraic?(v,ts) =>
+ toCheck: List BWT := stoseInvertible?_reg(init(q),ts)@(List BWT)
+ for bwt in toCheck repeat
+ bwt.val => toSave := cons(bwt.tower,toSave)
+ newq := removeZero(q,bwt.tower)
+ zero? newq => "leave"
+ toSave := concat(stoseInvertibleSet_reg(newq,bwt.tower), toSave)
+ toSave := removeDuplicates toSave
+ return algebraicSort(toSave)$quasicomppack
+ ts_v := select(ts,v)::P
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ lgwt := stoseInternalLastSubResultant(ts_v,q,ts_v_-,false,false)
+ lts, lts_h: Split
+ for gwt in lgwt repeat
+ g := gwt.val; ts := gwt.tower
+ (ground? g) or (mvar(g) < v) =>
+ lts := augment(ts_v,ts)$TS
+ lts := augment(members(ts_v_+),lts)$TS
+ toSave := concat(lts,toSave)
+ g := mainPrimitivePart g
+ h := lazyPquo(ts_v,g)
+ h := mainPrimitivePart h
+ (ground? h) or (mvar(h) < v) => "leave"
+ lts_h := augment(h,ts)$TS
+ lts_h := augment(members(ts_v_+),lts_h)$TS
+ for ts_h in lts_h repeat
+ inv := stoseInvertibleSet_reg(q,ts_h)
+ toSave := removeDuplicates concat(inv,toSave)
+ toSave := algebraicSort(toSave)$quasicomppack
+ insert!(k,toSave)$HInvSet
+ toSave
+
+ if TS has SquareFreeRegularTriangularSetCategory(R,E,V,P)
+ then
+
+ stoseInvertible?(p:P,ts:TS): List BWT == stoseInvertible?_sqfreg(p,ts)
+
+ stoseInvertibleSet(p:P,ts:TS): Split == stoseInvertibleSet_sqfreg(p,ts)
+
+ else
+
+ stoseInvertible?(p:P,ts:TS): List BWT == stoseInvertible?_reg(p,ts)
+
+ stoseInvertibleSet(p:P,ts:TS): Split == stoseInvertibleSet_reg(p,ts)
+
+@
+\section{package SRDCMPK SquareFreeRegularSetDecompositionPackage}
+<<package SRDCMPK SquareFreeRegularSetDecompositionPackage>>=
+)abbrev package SRDCMPK SquareFreeRegularSetDecompositionPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 09/23/1998
+++ Date Last Updated: 12/16/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A package providing a new algorithm for solving polynomial systems
+++ by means of regular chains. Two ways of solving are provided:
+++ in the sense of Zariski closure (like in Kalkbrener's algorithm)
+++ or in the sense of the regular zeros (like in Wu, Wang or Lazard-
+++ Moreno methods). This algorithm is valid for nay type
+++ of regular set. It does not care about the way a polynomial is
+++ added in an regular set, or how two quasi-components are compared
+++ (by an inclusion-test), or how the invertibility test is made in
+++ the tower of simple extensions associated with a regular set.
+++ These operations are realized respectively by the domain \spad{TS}
+++ and the packages \spad{QCMPPK(R,E,V,P,TS)} and \spad{RSETGCD(R,E,V,P,TS)}.
+++ The same way it does not care about the way univariate polynomial
+++ gcds (with coefficients in the tower of simple extensions associated
+++ with a regular set) are computed. The only requirement is that these
+++ gcds need to have invertible initials (normalized or not).
+++ WARNING. There is no need for a user to call diectly any operation
+++ of this package since they can be accessed by the domain \axiomType{TS}.
+++ Thus, the operations of this package are not documented.\newline
+++ References :
+++ [1] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 2. Does not use any unproved criteria.
+
+SquareFreeRegularSetDecompositionPackage(R,E,V,P,TS): Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : SquareFreeRegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : TS)
+ BWT ==> Record(val : Boolean, tower : TS)
+ LpWT ==> Record(val : (List P), tower : TS)
+ Wip ==> Record(done: Split, todo: List LpWT)
+ Branch ==> Record(eq: List P, tower: TS, ineq: List P)
+ UBF ==> Union(Branch,"failed")
+ Split ==> List TS
+ iprintpack ==> InternalPrintPackage()
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppack ==> SquareFreeQuasiComponentPackage(R,E,V,P,TS)
+ regsetgcdpack ==> SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,TS)
+
+ Exports == with
+
+ KrullNumber: (LP, Split) -> N
+ numberOfVariables: (LP, Split) -> N
+ algebraicDecompose: (P,TS) -> Record(done: Split, todo: List LpWT)
+ transcendentalDecompose: (P,TS,N) -> Record(done: Split, todo: List LpWT)
+ transcendentalDecompose: (P,TS) -> Record(done: Split, todo: List LpWT)
+ internalDecompose: (P,TS,N,B) -> Record(done: Split, todo: List LpWT)
+ internalDecompose: (P,TS,N) -> Record(done: Split, todo: List LpWT)
+ internalDecompose: (P,TS) -> Record(done: Split, todo: List LpWT)
+ decompose: (LP, Split, B, B) -> Split
+ decompose: (LP, Split, B, B, B, B, B) -> Split
+ upDateBranches: (LP,Split,List LpWT,Wip,N) -> List LpWT
+ convert: Record(val: List P,tower: TS) -> String
+ printInfo: (List Record(val: List P,tower: TS), N) -> Void
+
+ Implementation == add
+
+ KrullNumber(lp: LP, lts: Split): N ==
+ ln: List N := [#(ts) for ts in lts]
+ n := #lp + reduce(max,ln)
+
+ numberOfVariables(lp: LP, lts: Split): N ==
+ lv: List V := variables([lp]$PS)
+ for ts in lts repeat lv := concat(variables(ts), lv)
+ # removeDuplicates(lv)
+
+ algebraicDecompose(p: P, ts: TS): Record(done: Split, todo: List LpWT) ==
+ ground? p =>
+ error " in algebraicDecompose$REGSET: should never happen !"
+ v := mvar(p); n := #ts
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ ts_v := select(ts,v)::P
+ lgwt: List PWT
+ if mdeg(p) < mdeg(ts_v)
+ then
+ lgwt := stoseInternalLastSubResultant(ts_v,p,ts_v_-,true,false)$regsetgcdpack
+ else
+ lgwt := stoseInternalLastSubResultant(p,ts_v,ts_v_-,true,false)$regsetgcdpack
+ lts: Split := []
+ llpwt: List LpWT := []
+ for gwt in lgwt repeat
+ g := gwt.val; us := gwt.tower
+ zero? g =>
+ error " in algebraicDecompose$REGSET: should never happen !!"
+ ground? g => "leave"
+ h := leadingCoefficient(g,v)
+ lus := augment(members(ts_v_+),augment(ts_v,us)$TS)$TS
+ lsfp := squareFreeFactors(h)$polsetpack
+ for f in lsfp repeat
+ ground? f => "leave"
+ for vs in lus repeat
+ llpwt := cons([[f,p],vs]$LpWT, llpwt)
+ n < #us =>
+ error " in algebraicDecompose$REGSET: should never happen !!!"
+ mvar(g) = v =>
+ lts := concat(augment(members(ts_v_+),augment(g,us)$TS)$TS,lts)
+ [lts,llpwt]
+
+ transcendentalDecompose(p: P, ts: TS,bound: N): Record(done: Split, todo: List LpWT) ==
+ lts: Split
+ if #ts < bound
+ then
+ lts := augment(p,ts)$TS
+ else
+ lts := []
+ llpwt: List LpWT := []
+ [lts,llpwt]
+
+ transcendentalDecompose(p: P, ts: TS): Record(done: Split, todo: List LpWT) ==
+ lts: Split:= augment(p,ts)$TS
+ llpwt: List LpWT := []
+ [lts,llpwt]
+
+ internalDecompose(p: P, ts: TS,bound: N,clos?:B): Record(done: Split, todo: List LpWT) ==
+ clos? => internalDecompose(p,ts,bound)
+ internalDecompose(p,ts)
+
+ internalDecompose(p: P, ts: TS,bound: N): Record(done: Split, todo: List LpWT) ==
+ -- ASSUME p not constant
+ llpwt: List LpWT := []
+ lts: Split := []
+ -- EITHER mvar(p) is null
+ if (not zero? tail(p)) and (not ground? (lmp := leastMonomial(p)))
+ then
+ llpwt := cons([[mvar(p)::P],ts]$LpWT,llpwt)
+ p := (p exquo lmp)::P
+ ip := squareFreePart init(p); tp := tail p
+ p := mainPrimitivePart p
+ -- OR init(p) is null or not
+ lbwt: List BWT := stoseInvertible?_sqfreg(ip,ts)$regsetgcdpack
+ for bwt in lbwt repeat
+ bwt.val =>
+ if algebraic?(mvar(p),bwt.tower)
+ then
+ rsl := algebraicDecompose(p,bwt.tower)
+ else
+ rsl := transcendentalDecompose(p,bwt.tower,bound)
+ lts := concat(rsl.done,lts)
+ llpwt := concat(rsl.todo,llpwt)
+ (not ground? ip) =>
+ zero? tp => llpwt := cons([[ip],bwt.tower]$LpWT, llpwt)
+ (not ground? tp) => llpwt := cons([[ip,tp],bwt.tower]$LpWT, llpwt)
+ riv := removeZero(ip,bwt.tower)
+ (zero? riv) =>
+ zero? tp => lts := cons(bwt.tower,lts)
+ (not ground? tp) => llpwt := cons([[tp],bwt.tower]$LpWT, llpwt)
+ llpwt := cons([[riv * mainMonomial(p) + tp],bwt.tower]$LpWT, llpwt)
+ [lts,llpwt]
+
+ internalDecompose(p: P, ts: TS): Record(done: Split, todo: List LpWT) ==
+ -- ASSUME p not constant
+ llpwt: List LpWT := []
+ lts: Split := []
+ -- EITHER mvar(p) is null
+ if (not zero? tail(p)) and (not ground? (lmp := leastMonomial(p)))
+ then
+ llpwt := cons([[mvar(p)::P],ts]$LpWT,llpwt)
+ p := (p exquo lmp)::P
+ ip := squareFreePart init(p); tp := tail p
+ p := mainPrimitivePart p
+ -- OR init(p) is null or not
+ lbwt: List BWT := stoseInvertible?_sqfreg(ip,ts)$regsetgcdpack
+ for bwt in lbwt repeat
+ bwt.val =>
+ if algebraic?(mvar(p),bwt.tower)
+ then
+ rsl := algebraicDecompose(p,bwt.tower)
+ else
+ rsl := transcendentalDecompose(p,bwt.tower)
+ lts := concat(rsl.done,lts)
+ llpwt := concat(rsl.todo,llpwt)
+ (not ground? ip) =>
+ zero? tp => llpwt := cons([[ip],bwt.tower]$LpWT, llpwt)
+ (not ground? tp) => llpwt := cons([[ip,tp],bwt.tower]$LpWT, llpwt)
+ riv := removeZero(ip,bwt.tower)
+ (zero? riv) =>
+ zero? tp => lts := cons(bwt.tower,lts)
+ (not ground? tp) => llpwt := cons([[tp],bwt.tower]$LpWT, llpwt)
+ llpwt := cons([[riv * mainMonomial(p) + tp],bwt.tower]$LpWT, llpwt)
+ [lts,llpwt]
+
+ decompose(lp: LP, lts: Split, clos?: B, info?: B): Split ==
+ decompose(lp,lts,false,false,clos?,true,info?)
+
+ convert(lpwt: LpWT): String ==
+ ls: List String := ["<", string((#(lpwt.val))::Z), ",", string((#(lpwt.tower))::Z), ">" ]
+ concat ls
+
+ printInfo(toSee: List LpWT, n: N): Void ==
+ lpwt := first toSee
+ s: String := concat ["[", string((#toSee)::Z), " ", convert(lpwt)@String]
+ m: N := #(lpwt.val)
+ toSee := rest toSee
+ for lpwt in toSee repeat
+ m := m + #(lpwt.val)
+ s := concat [s, ",", convert(lpwt)@String]
+ s := concat [s, " -> |", string(m::Z), "|; {", string(n::Z),"}]"]
+ iprint(s)$iprintpack
+ void()
+
+ decompose(lp: LP, lts: Split, cleanW?: B, sqfr?: B, clos?: B, rem?: B, info?: B): Split ==
+ -- if cleanW? then REMOVE REDUNDANT COMPONENTS in lts
+ -- if sqfr? then SPLIT the system with SQUARE-FREE FACTORIZATION
+ -- if clos? then SOLVE in the closure sense
+ -- if rem? then REDUCE the current p by using remainder
+ -- if info? then PRINT info
+ empty? lp => lts
+ branches: List Branch := prepareDecompose(lp,lts,cleanW?,sqfr?)$quasicomppack
+ empty? branches => []
+ toSee: List LpWT := [[br.eq,br.tower]$LpWT for br in branches]
+ toSave: Split := []
+ if clos? then bound := KrullNumber(lp,lts) else bound := numberOfVariables(lp,lts)
+ while (not empty? toSee) repeat
+ if info? then printInfo(toSee,#toSave)
+ lpwt := first toSee; toSee := rest toSee
+ lp := lpwt.val; ts := lpwt.tower
+ empty? lp =>
+ toSave := cons(ts, toSave)
+ p := first lp; lp := rest lp
+ if rem? and (not ground? p) and (not empty? ts)
+ then
+ p := remainder(p,ts).polnum
+ p := removeZero(p,ts)
+ zero? p => toSee := cons([lp,ts]$LpWT, toSee)
+ ground? p => "leave"
+ rsl := internalDecompose(p,ts,bound,clos?)
+ toSee := upDateBranches(lp,toSave,toSee,rsl,bound)
+ removeSuperfluousQuasiComponents(toSave)$quasicomppack
+
+ upDateBranches(leq:LP,lts:Split,current:List LpWT,wip: Wip,n:N): List LpWT ==
+ newBranches: List LpWT := wip.todo
+ newComponents: Split := wip.done
+ branches1, branches2: List LpWT
+ branches1 := []; branches2 := []
+ for branch in newBranches repeat
+ us := branch.tower
+ #us > n => "leave"
+ newleq := sort(infRittWu?,concat(leq,branch.val))
+ --foo := rewriteSetWithReduction(newleq,us,initiallyReduce,initiallyReduced?)
+ --any?(ground?,foo) => "leave"
+ branches1 := cons([newleq,us]$LpWT, branches1)
+ for us in newComponents repeat
+ #us > n => "leave"
+ subQuasiComponent?(us,lts)$quasicomppack => "leave"
+ --newleq := leq
+ --foo := rewriteSetWithReduction(newleq,us,initiallyReduce,initiallyReduced?)
+ --any?(ground?,foo) => "leave"
+ branches2 := cons([leq,us]$LpWT, branches2)
+ empty? branches1 =>
+ empty? branches2 => current
+ concat(branches2, current)
+ branches := concat [branches2, branches1, current]
+ -- branches := concat(branches,current)
+ removeSuperfluousCases(branches)$quasicomppack
+
+@
+\section{domain SREGSET SquareFreeRegularTriangularSet}
+<<domain SREGSET SquareFreeRegularTriangularSet>>=
+)abbrev domain SREGSET SquareFreeRegularTriangularSet
+++ Author: Marc Moreno Maza
+++ Date Created: 08/25/1998
+++ Date Last Updated: 16/12/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ This domain provides an implementation of square-free regular chains.
+++ Moreover, the operation \axiomOpFrom{zeroSetSplit}{SquareFreeRegularTriangularSetCategory}
+++ is an implementation of a new algorithm for solving polynomial systems by
+++ means of regular chains.\newline
+++ References :
+++ [1] M. MORENO MAZA "A new algorithm for computing triangular
+++ decomposition of algebraic varieties" NAG Tech. Rep. 4/98.
+++ Version: 2
+
+SquareFreeRegularTriangularSet(R,E,V,P) : Exports == Implementation where
+
+ R : GcdDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ PtoP ==> P -> P
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ PWT ==> Record(val : P, tower : $)
+ BWT ==> Record(val : Boolean, tower : $)
+ LpWT ==> Record(val : (List P), tower : $)
+ Split ==> List $
+ iprintpack ==> InternalPrintPackage()
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppack ==> SquareFreeQuasiComponentPackage(R,E,V,P,$)
+ regsetgcdpack ==> SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,$)
+ regsetdecomppack ==> SquareFreeRegularSetDecompositionPackage(R,E,V,P,$)
+
+ Exports == SquareFreeRegularTriangularSetCategory(R,E,V,P) with
+
+ internalAugment: (P,$,B,B,B,B,B) -> List $
+ ++ \axiom{internalAugment(p,ts,b1,b2,b3,b4,b5)}
+ ++ is an internal subroutine, exported only for developement.
+ zeroSetSplit: (LP, B, B) -> Split
+ ++ \axiom{zeroSetSplit(lp,clos?,info?)} has the same specifications as
+ ++ \axiomOpFrom{zeroSetSplit}{RegularTriangularSetCategory}
+ ++ from \spadtype{RegularTriangularSetCategory}
+ ++ Moreover, if \axiom{clos?} then solves in the sense of the Zariski closure
+ ++ else solves in the sense of the regular zeros. If \axiom{info?} then
+ ++ do print messages during the computations.
+ zeroSetSplit: (LP, B, B, B, B) -> Split
+ ++ \axiom{zeroSetSplit(lp,b1,b2.b3,b4)}
+ ++ is an internal subroutine, exported only for developement.
+ internalZeroSetSplit: (LP, B, B, B) -> Split
+ ++ \axiom{internalZeroSetSplit(lp,b1,b2,b3)}
+ ++ is an internal subroutine, exported only for developement.
+ pre_process: (LP, B, B) -> Record(val: LP, towers: Split)
+ ++ \axiom{pre_process(lp,b1,b2)}
+ ++ is an internal subroutine, exported only for developement.
+
+ Implementation == add
+
+ Rep ==> LP
+
+ rep(s:$):Rep == s pretend Rep
+ per(l:Rep):$ == l pretend $
+
+ copy ts ==
+ per(copy(rep(ts))$LP)
+ empty() ==
+ per([])
+ empty?(ts:$) ==
+ empty?(rep(ts))
+ parts ts ==
+ rep(ts)
+ members ts ==
+ rep(ts)
+ map (f : PtoP, ts : $) : $ ==
+ construct(map(f,rep(ts))$LP)$$
+ map! (f : PtoP, ts : $) : $ ==
+ construct(map!(f,rep(ts))$LP)$$
+ member? (p,ts) ==
+ member?(p,rep(ts))$LP
+ unitIdealIfCan() ==
+ "failed"::Union($,"failed")
+ roughUnitIdeal? ts ==
+ false
+ coerce(ts:$) : OutputForm ==
+ lp : List(P) := reverse(rep(ts))
+ brace([p::OutputForm for p in lp]$List(OutputForm))$OutputForm
+ mvar ts ==
+ empty? ts => error "mvar$SREGSET: #1 is empty"
+ mvar(first(rep(ts)))$P
+ first ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ first(rep(ts))::Union(P,"failed")
+ last ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ last(rep(ts))::Union(P,"failed")
+ rest ts ==
+ empty? ts => "failed"::Union($,"failed")
+ per(rest(rep(ts)))::Union($,"failed")
+ coerce(ts:$) : (List P) ==
+ rep(ts)
+
+ collectUpper (ts,v) ==
+ empty? ts => ts
+ lp := rep(ts)
+ newlp : Rep := []
+ while (not empty? lp) and (mvar(first(lp)) > v) repeat
+ newlp := cons(first(lp),newlp)
+ lp := rest lp
+ per(reverse(newlp))
+
+ collectUnder (ts,v) ==
+ empty? ts => ts
+ lp := rep(ts)
+ while (not empty? lp) and (mvar(first(lp)) >= v) repeat
+ lp := rest lp
+ per(lp)
+
+ construct(lp:List(P)) ==
+ ts : $ := per([])
+ empty? lp => ts
+ lp := sort(infRittWu?,lp)
+ while not empty? lp repeat
+ eif := extendIfCan(ts,first(lp))
+ not (eif case $) =>
+ error"in construct : List P -> $ from SREGSET : bad #1"
+ ts := eif::$
+ lp := rest lp
+ ts
+
+ extendIfCan(ts:$,p:P) ==
+ ground? p => "failed"::Union($,"failed")
+ empty? ts =>
+ p := squareFreePart primitivePart p
+ (per([p]))::Union($,"failed")
+ not (mvar(ts) < mvar(p)) => "failed"::Union($,"failed")
+ invertible?(init(p),ts)@Boolean =>
+ lts: Split := augment(p,ts)
+ #lts ~= 1 => "failed"::Union($,"failed")
+ (first lts)::Union($,"failed")
+ "failed"::Union($,"failed")
+
+ removeZero(p:P, ts:$): P ==
+ (ground? p) or (empty? ts) => p
+ v := mvar(p)
+ ts_v_- := collectUnder(ts,v)
+ if algebraic?(v,ts)
+ then
+ q := lazyPrem(p,select(ts,v)::P)
+ zero? q => return q
+ zero? removeZero(q,ts_v_-) => return 0
+ empty? ts_v_- => p
+ q: P := 0
+ while positive? degree(p,v) repeat
+ q := removeZero(init(p),ts_v_-) * mainMonomial(p) + q
+ p := tail(p)
+ q + removeZero(p,ts_v_-)
+
+ internalAugment(p:P,ts:$): $ ==
+ -- ASSUME that adding p to ts DOES NOT require any split
+ ground? p => error "in internalAugment$SREGSET: ground? #1"
+ first(internalAugment(p,ts,false,false,false,false,false))
+
+ internalAugment(lp:List(P),ts:$): $ ==
+ -- ASSUME that adding p to ts DOES NOT require any split
+ empty? lp => ts
+ internalAugment(rest lp, internalAugment(first lp, ts))
+
+ internalAugment(p:P,ts:$,rem?:B,red?:B,prim?:B,sqfr?:B,extend?:B): Split ==
+ -- ASSUME p is not a constant
+ -- ASSUME mvar(p) is not algebraic w.r.t. ts
+ -- ASSUME init(p) invertible modulo ts
+ -- if rem? then REDUCE p by remainder
+ -- if prim? then REPLACE p by its main primitive part
+ -- if sqfr? then FACTORIZE SQUARE FREE p over R
+ -- if extend? DO NOT ASSUME every pol in ts_v_+ is invertible modulo ts
+ v := mvar(p)
+ ts_v_- := collectUnder(ts,v)
+ ts_v_+ := collectUpper(ts,v)
+ if rem? then p := remainder(p,ts_v_-).polnum
+ -- if rem? then p := reduceByQuasiMonic(p,ts_v_-)
+ if red? then p := removeZero(p,ts_v_-)
+ if prim? then p := mainPrimitivePart p
+ lts: Split
+ if sqfr?
+ then
+ lts: Split := []
+ lsfp := squareFreeFactors(p)$polsetpack
+ for f in lsfp repeat
+ (ground? f) or (mvar(f) < v) => "leave"
+ lpwt := squareFreePart(f,ts_v_-)
+ for pwt in lpwt repeat
+ sfp := pwt.val; us := pwt.tower
+ lts := cons( per(cons(pwt.val, rep(pwt.tower))), lts)
+ else
+ lts: Split := [per(cons(p,rep(ts_v_-)))]
+ extend? => extend(members(ts_v_+),lts)
+ [per(concat(rep(ts_v_+),rep(us))) for us in lts]
+
+ augment(p:P,ts:$): List $ ==
+ ground? p => error "in augment$SREGSET: ground? #1"
+ algebraic?(mvar(p),ts) => error "in augment$SREGSET: bad #1"
+ -- ASSUME init(p) invertible modulo ts
+ -- DOES NOT ASSUME anything else.
+ -- THUS reduction, mainPrimitivePart and squareFree are NEEDED
+ internalAugment(p,ts,true,true,true,true,true)
+
+ extend(p:P,ts:$): List $ ==
+ ground? p => error "in extend$SREGSET: ground? #1"
+ v := mvar(p)
+ not (mvar(ts) < mvar(p)) => error "in extend$SREGSET: bad #1"
+ split: List($) := invertibleSet(init(p),ts)
+ lts: List($) := []
+ for us in split repeat
+ lts := concat(augment(p,us),lts)
+ lts
+
+ invertible?(p:P,ts:$): Boolean ==
+ stoseInvertible?(p,ts)$regsetgcdpack
+
+ invertible?(p:P,ts:$): List BWT ==
+ stoseInvertible?_sqfreg(p,ts)$regsetgcdpack
+
+ invertibleSet(p:P,ts:$): Split ==
+ stoseInvertibleSet_sqfreg(p,ts)$regsetgcdpack
+
+ lastSubResultant(p1:P,p2:P,ts:$): List PWT ==
+ stoseLastSubResultant(p1,p2,ts)$regsetgcdpack
+
+ squareFreePart(p:P, ts: $): List PWT ==
+ stoseSquareFreePart(p,ts)$regsetgcdpack
+
+ intersect(p:P, ts: $): List($) == decompose([p], [ts], false, false)$regsetdecomppack
+
+ intersect(lp: LP, lts: List($)): List($) == decompose(lp, lts, false, false)$regsetdecomppack
+ -- SOLVE in the regular zero sense
+ -- and DO NOT PRINT info
+
+ decompose(p:P, ts: $): List($) == decompose([p], [ts], true, false)$regsetdecomppack
+
+ decompose(lp: LP, lts: List($)): List($) == decompose(lp, lts, true, false)$regsetdecomppack
+ -- SOLVE in the closure sense
+ -- and DO NOT PRINT info
+
+ zeroSetSplit(lp:List(P)) == zeroSetSplit(lp,true,false)
+ -- by default SOLVE in the closure sense
+ -- and DO NOT PRINT info
+
+ zeroSetSplit(lp:List(P), clos?: B) == zeroSetSplit(lp,clos?, false)
+
+ zeroSetSplit(lp:List(P), clos?: B, info?: B) ==
+ -- if clos? then SOLVE in the closure sense
+ -- if info? then PRINT info
+ -- by default USE hash-tables
+ -- and PREPROCESS the input system
+ zeroSetSplit(lp,true,clos?,info?,true)
+
+ zeroSetSplit(lp:List(P),hash?:B,clos?:B,info?:B,prep?:B) ==
+ -- if hash? then USE hash-tables
+ -- if info? then PRINT information
+ -- if clos? then SOLVE in the closure sense
+ -- if prep? then PREPROCESS the input system
+ if hash?
+ then
+ s1, s2, s3, dom1, dom2, dom3: String
+ e: String := empty()$String
+ if info? then (s1,s2,s3) := ("w","g","i") else (s1,s2,s3) := (e,e,e)
+ if info?
+ then
+ (dom1, dom2, dom3) := ("QCMPACK", "REGSETGCD: Gcd", "REGSETGCD: Inv Set")
+ else
+ (dom1, dom2, dom3) := (e,e,e)
+ startTable!(s1,"W",dom1)$quasicomppack
+ startTableGcd!(s2,"G",dom2)$regsetgcdpack
+ startTableInvSet!(s3,"I",dom3)$regsetgcdpack
+ lts := internalZeroSetSplit(lp,clos?,info?,prep?)
+ if hash?
+ then
+ stopTable!()$quasicomppack
+ stopTableGcd!()$regsetgcdpack
+ stopTableInvSet!()$regsetgcdpack
+ lts
+
+ internalZeroSetSplit(lp:LP,clos?:B,info?:B,prep?:B) ==
+ -- if info? then PRINT information
+ -- if clos? then SOLVE in the closure sense
+ -- if prep? then PREPROCESS the input system
+ if prep?
+ then
+ pp := pre_process(lp,clos?,info?)
+ lp := pp.val
+ lts := pp.towers
+ else
+ ts: $ := [[]]
+ lts := [ts]
+ lp := remove(zero?, lp)
+ any?(ground?, lp) => []
+ empty? lp => lts
+ empty? lts => lts
+ lp := sort(infRittWu?,lp)
+ clos? => decompose(lp,lts, clos?, info?)$regsetdecomppack
+ -- IN DIM > 0 with clos? the following is not false ...
+ for p in lp repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lts
+
+ largeSystem?(lp:LP): Boolean ==
+ -- Gonnet and Gerdt and not Wu-Wang.2
+ #lp > 16 => true
+ #lp < 13 => false
+ lts: List($) := []
+ (#lp :: Z - numberOfVariables(lp,lts)$regsetdecomppack :: Z) > 3
+
+ smallSystem?(lp:LP): Boolean ==
+ -- neural, Vermeer, Liu, and not f-633 and not Hairer-2
+ #lp < 5
+
+ mediumSystem?(lp:LP): Boolean ==
+ -- f-633 and not Hairer-2
+ lts: List($) := []
+ (numberOfVariables(lp,lts)$regsetdecomppack :: Z - #lp :: Z) < 2
+
+-- lin?(p:P):Boolean == ground?(init(p)) and one?(mdeg(p))
+ lin?(p:P):Boolean == ground?(init(p)) and (mdeg(p) = 1)
+
+ pre_process(lp:LP,clos?:B,info?:B): Record(val: LP, towers: Split) ==
+ -- if info? then PRINT information
+ -- if clos? then SOLVE in the closure sense
+ ts: $ := [[]];
+ lts: Split := [ts]
+ empty? lp => [lp,lts]
+ lp1: List P := []
+ lp2: List P := []
+ for p in lp repeat
+ ground? (tail p) => lp1 := cons(p, lp1)
+ lp2 := cons(p, lp2)
+ lts: Split := decompose(lp1,[ts],clos?,info?)$regsetdecomppack
+ probablyZeroDim?(lp)$polsetpack =>
+ largeSystem?(lp) => return [lp2,lts]
+ if #lp > 7
+ then
+ -- Butcher (8,8) + Wu-Wang.2 (13,16)
+ lp2 := crushedSet(lp2)$polsetpack
+ lp2 := remove(zero?,lp2)
+ any?(ground?,lp2) => return [lp2, lts]
+ lp3 := [p for p in lp2 | lin?(p)]
+ lp4 := [p for p in lp2 | not lin?(p)]
+ if clos?
+ then
+ lts := decompose(lp4,lts, clos?, info?)$regsetdecomppack
+ else
+ lp4 := sort(infRittWu?,lp4)
+ for p in lp4 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lp2 := lp3
+ else
+ lp2 := crushedSet(lp2)$polsetpack
+ lp2 := remove(zero?,lp2)
+ any?(ground?,lp2) => return [lp2, lts]
+ if clos?
+ then
+ lts := decompose(lp2,lts, clos?, info?)$regsetdecomppack
+ else
+ lp2 := sort(infRittWu?,lp2)
+ for p in lp2 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lp2 := []
+ return [lp2,lts]
+ smallSystem?(lp) => [lp2,lts]
+ mediumSystem?(lp) => [crushedSet(lp2)$polsetpack,lts]
+ lp3 := [p for p in lp2 | lin?(p)]
+ lp4 := [p for p in lp2 | not lin?(p)]
+ if clos?
+ then
+ lts := decompose(lp4,lts, clos?, info?)$regsetdecomppack
+ else
+ lp4 := sort(infRittWu?,lp4)
+ for p in lp4 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ if clos?
+ then
+ lts := decompose(lp3,lts, clos?, info?)$regsetdecomppack
+ else
+ lp3 := sort(infRittWu?,lp3)
+ for p in lp3 repeat
+ lts := decompose([p],lts, clos?, info?)$regsetdecomppack
+ lp2 := []
+ return [lp2,lts]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category SFRTCAT SquareFreeRegularTriangularSetCategory>>
+<<package SFQCMPK SquareFreeQuasiComponentPackage>>
+<<package SFRGCD SquareFreeRegularTriangularSetGcdPackage>>
+<<package SRDCMPK SquareFreeRegularSetDecompositionPackage>>
+<<domain SREGSET SquareFreeRegularTriangularSet>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/stream.spad.pamphlet b/src/algebra/stream.spad.pamphlet
new file mode 100644
index 00000000..4edd8509
--- /dev/null
+++ b/src/algebra/stream.spad.pamphlet
@@ -0,0 +1,1296 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra stream.spad}
+\author{Clifton J. Williamson, William Burge, Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category LZSTAGG LazyStreamAggregate}
+<<category LZSTAGG LazyStreamAggregate>>=
+)abbrev category LZSTAGG LazyStreamAggregate
+++ Category of streams with lazy evaluation
+++ Author: Clifton J. Williamson
+++ Date Created: 22 November 1989
+++ Date Last Updated: 20 July 1990
+++ Keywords: stream, infinite list, infinite sequence
+++ Description:
+++ LazyStreamAggregate is the category of streams with lazy
+++ evaluation. It is understood that the function 'empty?' will
+++ cause lazy evaluation if necessary to determine if there are
+++ entries. Functions which call 'empty?', e.g. 'first' and 'rest',
+++ will also cause lazy evaluation if necessary.
+
+LazyStreamAggregate(S:Type): Category == StreamAggregate(S) with
+ remove: (S -> Boolean,%) -> %
+ ++ remove(f,st) returns a stream consisting of those elements of stream
+ ++ st which do not satisfy the predicate f.
+ ++ Note: \spad{remove(f,st) = [x for x in st | not f(x)]}.
+ select: (S -> Boolean,%) -> %
+ ++ select(f,st) returns a stream consisting of those elements of stream
+ ++ st satisfying the predicate f.
+ ++ Note: \spad{select(f,st) = [x for x in st | f(x)]}.
+ explicitEntries?: % -> Boolean
+ ++ explicitEntries?(s) returns true if the stream s has
+ ++ explicitly computed entries, and false otherwise.
+ explicitlyEmpty?: % -> Boolean
+ ++ explicitlyEmpty?(s) returns true if the stream is an
+ ++ (explicitly) empty stream.
+ ++ Note: this is a null test which will not cause lazy evaluation.
+ lazy?: % -> Boolean
+ ++ lazy?(s) returns true if the first node of the stream s
+ ++ is a lazy evaluation mechanism which could produce an
+ ++ additional entry to s.
+ lazyEvaluate: % -> %
+ ++ lazyEvaluate(s) causes one lazy evaluation of stream s.
+ ++ Caution: the first node must be a lazy evaluation mechanism
+ ++ (satisfies \spad{lazy?(s) = true}) as there is no error check.
+ ++ Note: a call to this function may
+ ++ or may not produce an explicit first entry
+ frst: % -> S
+ ++ frst(s) returns the first element of stream s.
+ ++ Caution: this function should only be called after a \spad{empty?} test
+ ++ has been made since there no error check.
+ rst: % -> %
+ ++ rst(s) returns a pointer to the next node of stream s.
+ ++ Caution: this function should only be called after a \spad{empty?} test
+ ++ has been made since there no error check.
+ numberOfComputedEntries: % -> NonNegativeInteger
+ ++ numberOfComputedEntries(st) returns the number of explicitly
+ ++ computed entries of stream st which exist immediately prior to the time
+ ++ this function is called.
+ extend: (%,Integer) -> %
+ ++ extend(st,n) causes entries to be computed, if necessary,
+ ++ so that 'st' will have at least 'n' explicit entries or so
+ ++ that all entries of 'st' will be computed if 'st' is finite
+ ++ with length <= n.
+ complete: % -> %
+ ++ complete(st) causes all entries of 'st' to be computed.
+ ++ this function should only be called on streams which are
+ ++ known to be finite.
+
+ add
+
+ MIN ==> 1 -- minimal stream index
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ L ==> List
+ U ==> UniversalSegment Integer
+
+ indexx? : (Integer,%) -> Boolean
+ cycleElt : % -> Union(%,"failed")
+ computeCycleLength : % -> NNI
+ computeCycleEntry : (%,%) -> %
+
+--% SETCAT functions
+
+ if S has SetCategory then
+
+ x = y ==
+ eq?(x,y) => true
+ explicitlyFinite? x and explicitlyFinite? y =>
+ entries x = entries y
+ explicitEntries? x and explicitEntries? y =>
+ frst x = frst y and EQ(rst x, rst y)$Lisp
+ -- treat cyclic streams
+ false
+
+--% HOAGG functions
+
+ --null x == empty? x
+
+ less?(x,n) ==
+ n = 0 => false
+ empty? x => true
+ less?(rst x,(n-1) :: NNI)
+
+ more?(x,n) ==
+ empty? x => false
+ n = 0 => true
+ more?(rst x,(n-1) :: NNI)
+
+ size?(x,n) ==
+ empty? x => n = 0
+ size?(rst x,(n-1) :: NNI)
+
+ # x ==
+ -- error if stream is not finite
+ y := x
+ for i in 0.. repeat
+ explicitlyEmpty? y => return i
+ lazy? y => error "#: infinite stream"
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => error "#: infinite stream"
+
+--% CLAGG functions
+
+ any?(f,x) ==
+ -- error message only when x is a stream with lazy
+ -- evaluation and f(s) = false for all stream elements
+ -- 's' which have been computed when the function is
+ -- called
+ y := x
+ for i in 0.. repeat
+ explicitlyEmpty? y => return false
+ lazy? y => error "any?: infinite stream"
+ f frst y => return true
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => return false
+
+ every?(f,x) ==
+ -- error message only when x is a stream with lazy
+ -- evaluation and f(s) = true for all stream elements
+ -- 's' which have been computed when the function is
+ -- called
+ y := x
+ for i in 0.. repeat
+ explicitlyEmpty? y => return true
+ lazy? y => error "every?: infinite stream"
+ not f frst y => return false
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => return true
+
+-- following ops count and member? are only exported if $ has finiteAggregate
+
+-- count(f:S -> Boolean,x:%) ==
+-- -- error if stream is not finite
+-- count : NNI := 0
+-- y := x
+-- for i in 0.. repeat
+-- explicitlyEmpty? y => return count
+-- lazy? y => error "count: infinite stream"
+-- if f frst y then count := count + 1
+-- y := rst y
+-- if odd? i then x := rst x
+-- eq?(x,y) => error "count: infinite stream"
+
+
+-- if S has SetCategory then
+
+-- count(s:S,x:%) == count(#1 = s,x)
+-- -- error if stream is not finite
+
+-- member?(s,x) ==
+-- -- error message only when x is a stream with lazy
+-- -- evaluation and 's' is not among the stream elements
+-- -- which have been computed when the function is called
+-- y := x
+-- for i in 0.. repeat
+-- explicitlyEmpty? y => return false
+-- lazy? y => error "member?: infinite stream"
+-- frst y = s => return true
+-- y := rst y
+-- if odd? i then x := rst x
+-- eq?(x,y) => return false
+
+ entries x ==
+ -- returns a list of elements which have been computed
+ -- error if infinite
+ y := x
+ l : L S := empty()
+ for i in 0.. repeat
+ explicitlyEmpty? y => return reverse_! l
+ lazy? y => error "infinite stream"
+ l := concat(frst y,l)
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => error "infinite stream"
+
+--% CNAGG functions
+
+ construct l ==
+ empty? l => empty()
+ concat(first l, construct rest l)
+
+ --entries x ==
+ -- returns a list of the stream elements
+ -- error if the stream is not finite
+ --members x
+
+--% ELTAGG functions
+
+ elt(x:%,n:I) ==
+ n < MIN or empty? x => error "elt: no such element"
+ n = MIN => frst x
+ elt(rst x,n - 1)
+
+ elt(x:%,n:I,s:S) ==
+ n < MIN or empty? x => s
+ n = MIN => frst x
+ elt(rst x,n - 1)
+
+--% IXAGG functions
+
+-- following assumes % has finiteAggregate and S has SetCategory
+-- entry?(s,x) ==
+-- -- error message only when x is a stream with lazy
+-- -- evaluation and 's' is not among the stream elements
+-- -- which have been computed when the function is called
+-- member?(s,x)
+
+ --entries x ==
+ -- error if the stream is not finite
+ --members x
+
+ indexx?(n,x) ==
+ empty? x => false
+ n = MIN => true
+ indexx?(n-1,rst x)
+
+ index?(n,x) ==
+ -- returns 'true' iff 'n' is the index of an entry which
+ -- may or may not have been computed when the function is
+ -- called
+ -- additional entries are computed if necessary
+ n < MIN => false
+ indexx?(n,x)
+
+ indices x ==
+ -- error if stream is not finite
+ y := x
+ l : L I := empty()
+ for i in MIN.. repeat
+ explicitlyEmpty? y => return reverse_! l
+ lazy? y => error "indices: infinite stream"
+ l := concat(i,l)
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => error "indices: infinite stream"
+
+ maxIndex x ==
+ -- error if stream is not finite
+ empty? x =>
+ error "maxIndex: no maximal index for empty stream"
+ y := rst x
+ for i in MIN.. repeat
+ explicitlyEmpty? y => return i
+ lazy? y => error "maxIndex: infinite stream"
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => error "maxIndex: infinite stream"
+
+ minIndex x ==
+ empty? x => error "minIndex: no minimal index for empty stream"
+ MIN
+
+--% LNAGG functions
+
+ delete(x:%,n:I) ==
+ -- non-destructive
+ not index?(n,x) => error "delete: index out of range"
+ concat(first(x,(n - MIN) :: NNI), rest(x,(n - MIN + 1) :: NNI))
+
+ delete(x:%,seg:U) ==
+ low := lo seg
+ hasHi seg =>
+ high := hi seg
+ high < low => copy x
+ (not index?(low,x)) or (not index?(high,x)) =>
+ error "delete: index out of range"
+ concat(first(x,(low - MIN) :: NNI),rest(x,(high - MIN + 1) :: NNI))
+ not index?(low,x) => error "delete: index out of range"
+ first(x,(low - MIN) :: NNI)
+
+ elt(x:%,seg:U) ==
+ low := lo seg
+ hasHi seg =>
+ high := hi seg
+ high < low => empty()
+ (not index?(low,x)) or (not index?(high,x)) =>
+ error "elt: index out of range"
+ first(rest(x,(low - MIN) :: NNI),(high - low + 1) :: NNI)
+ not index?(low,x) => error "elt: index out of range"
+ rest(x,(low - MIN) :: NNI)
+
+ insert(s:S,x:%,n:I) ==
+ not index?(n,x) => error "insert: index out of range"
+ nn := (n - MIN) :: NNI
+ concat([first(x,nn), concat(s, empty()), rest(x,nn)])
+
+ insert(y:%,x:%,n:I) ==
+ not index?(n,x) => error "insert: index out of range"
+ nn := (n - MIN) :: NNI
+ concat([first(x,nn), y, rest(x,nn)])
+
+--% RCAGG functions
+
+ cycleElt x == cycleElt(x)$CyclicStreamTools(S,%)
+
+ cyclic? x ==
+ cycleElt(x) case "failed" => false
+ true
+
+ if S has SetCategory then
+ child?(x,y) ==
+ empty? y => error "child: no children"
+ x = rst y
+
+ children x ==
+ empty? x => error "children: no children"
+ [rst x]
+
+ distance(x,z) ==
+ y := x
+ for i in 0.. repeat
+ eq?(y,z) => return i
+ (explicitlyEmpty? y) or (lazy? y) =>
+ error "distance: 2nd arg not a descendent of the 1st"
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) =>
+ error "distance: 2nd arg not a descendent of the 1st"
+
+ if S has SetCategory then
+ node?(z,x) ==
+ -- error message only when x is a stream with lazy
+ -- evaluation and 'y' is not a node of 'x'
+ -- which has been computed when the function is called
+ y := x
+ for i in 0.. repeat
+ z = y => return true
+ explicitlyEmpty? y => return false
+ lazy? y => error "node?: infinite stream"
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => return false
+
+ nodes x ==
+ y := x
+ l : L % := []
+ for i in 0.. repeat
+ explicitlyEmpty? y => return reverse_! l
+ lazy? y => error "nodes: infinite stream"
+ l := concat(y,l)
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => error "nodes: infinite stream"
+ l -- @#$%^& compiler
+
+ leaf? x == empty? rest x
+
+ value x == first x
+
+--% URAGG functions
+
+ computeCycleLength cycElt ==
+ computeCycleLength(cycElt)$CyclicStreamTools(S,%)
+
+ computeCycleEntry(x,cycElt) ==
+ computeCycleEntry(x,cycElt)$CyclicStreamTools(S,%)
+
+ cycleEntry x ==
+ cycElt := cycleElt x
+ cycElt case "failed" =>
+ error "cycleEntry: non-cyclic stream"
+ computeCycleEntry(x,cycElt::%)
+
+ cycleLength x ==
+ cycElt := cycleElt x
+ cycElt case "failed" =>
+ error "cycleLength: non-cyclic stream"
+ computeCycleLength(cycElt::%)
+
+ cycleTail x ==
+ cycElt := cycleElt x
+ cycElt case "failed" =>
+ error "cycleTail: non-cyclic stream"
+ y := x := computeCycleEntry(x,cycElt::%)
+ z := rst x
+ repeat
+ eq?(x,z) => return y
+ y := z ; z := rst z
+
+ elt(x,"first") == first x
+
+ first(x,n) ==
+ -- former name: take
+ n = 0 or empty? x => empty()
+ concat(frst x, first(rst x,(n-1) :: NNI))
+
+ rest x ==
+ empty? x => error "Can't take the rest of an empty stream."
+ rst x
+
+ elt(x,"rest") == rest x
+
+ rest(x,n) ==
+ -- former name: drop
+ n = 0 or empty? x => x
+ rest(rst x,(n-1) :: NNI)
+
+ last x ==
+ -- error if stream is not finite
+ empty? x => error "last: empty stream"
+ y1 := x
+ y2 := rst x
+ for i in 0.. repeat
+ explicitlyEmpty? y2 => return frst y1
+ lazy? y2 => error "last: infinite stream"
+ y1 := y2
+ y2 := rst y2
+ if odd? i then x := rst x
+ eq?(x,y2) => error "last: infinite stream"
+
+ if % has finiteAggregate then -- # is only defined for finiteAggregates
+ last(x,n) ==
+ possiblyInfinite? x => error "last: infinite stream"
+ m := # x
+ m < n => error "last: index out of range"
+ copy rest(x,(m-n)::NNI)
+
+ elt(x,"last") == last x
+
+ tail x ==
+ -- error if stream is not finite
+ empty? x => error "tail: empty stream"
+ y1 := x
+ y2 := rst x
+ for i in 0.. repeat
+ explicitlyEmpty? y2 => return y1
+ lazy? y2 => error "tail: infinite stream"
+ y1 := y2
+ y2 := rst y2
+ if odd? i then x := rst x
+ eq?(x,y2) => error "tail: infinite stream"
+
+--% STAGG functions
+
+ possiblyInfinite? x ==
+ y := x
+ for i in 0.. repeat
+ explicitlyEmpty? y => return false
+ lazy? y => return true
+ if odd? i then x := rst x
+ y := rst y
+ eq?(x,y) => return true
+
+ explicitlyFinite? x == not possiblyInfinite? x
+
+--% LZSTAGG functions
+
+ extend(x,n) ==
+ y := x
+ for i in 1..n while not empty? y repeat y := rst y
+ x
+
+ complete x ==
+ y := x
+ while not empty? y repeat y := rst y
+ x
+
+@
+\section{package CSTTOOLS CyclicStreamTools}
+<<package CSTTOOLS CyclicStreamTools>>=
+)abbrev package CSTTOOLS CyclicStreamTools
+++ Functions for dealing with cyclic streams
+++ Author: Clifton J. Williamson
+++ Date Created: 5 December 1989
+++ Date Last Updated: 5 December 1989
+++ Keywords: stream, cyclic
+++ Description:
+++ This package provides tools for working with cyclic streams.
+CyclicStreamTools(S,ST): Exports == Implementation where
+ S : Type
+ ST : LazyStreamAggregate S
+
+ Exports ==> with
+
+ cycleElt: ST -> Union(ST,"failed")
+ ++ cycleElt(s) returns a pointer to a node in the cycle if the stream s is
+ ++ cyclic and returns "failed" if s is not cyclic
+ computeCycleLength: ST -> NonNegativeInteger
+ ++ computeCycleLength(s) returns the length of the cycle of a
+ ++ cyclic stream t, where s is a pointer to a node in the
+ ++ cyclic part of t.
+ computeCycleEntry: (ST,ST) -> ST
+ ++ computeCycleEntry(x,cycElt), where cycElt is a pointer to a
+ ++ node in the cyclic part of the cyclic stream x, returns a
+ ++ pointer to the first node in the cycle
+
+ Implementation ==> add
+
+ cycleElt x ==
+ y := x
+ for i in 0.. repeat
+ (explicitlyEmpty? y) or (lazy? y) => return "failed"
+ y := rst y
+ if odd? i then x := rst x
+ eq?(x,y) => return y
+
+ computeCycleLength cycElt ==
+ i : NonNegativeInteger
+ y := cycElt
+ for i in 1.. repeat
+ y := rst y
+ eq?(y,cycElt) => return i
+
+ computeCycleEntry(x,cycElt) ==
+ y := rest(x, computeCycleLength cycElt)
+ repeat
+ eq?(x,y) => return x
+ x := rst x ; y := rst y
+
+@
+\section{domain STREAM Stream}
+<<domain STREAM Stream>>=
+)abbrev domain STREAM Stream
+++ Implementation of streams via lazy evaluation
+++ Authors: Burge, Watt; updated by Clifton J. Williamson
+++ Date Created: July 1986
+++ Date Last Updated: 30 March 1990
+++ Keywords: stream, infinite list, infinite sequence
+++ Examples:
+++ References:
+++ Description:
+++ A stream is an implementation of an infinite sequence using
+++ a list of terms that have been computed and a function closure
+++ to compute additional terms when needed.
+
+Stream(S): Exports == Implementation where
+-- problems:
+-- 1) dealing with functions which basically want a finite structure
+-- 2) 'map' doesn't deal with cycles very well
+
+ S : Type
+ B ==> Boolean
+ OUT ==> OutputForm
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ U ==> UniversalSegment I
+
+ Exports ==> LazyStreamAggregate(S) with
+ shallowlyMutable
+ ++ one may destructively alter a stream by assigning new
+ ++ values to its entries.
+
+ coerce: L S -> %
+ ++ coerce(l) converts a list l to a stream.
+ repeating: L S -> %
+ ++ repeating(l) is a repeating stream whose period is the list l.
+ if S has SetCategory then
+ repeating?: (L S,%) -> B
+ ++ repeating?(l,s) returns true if a stream s is periodic
+ ++ with period l, and false otherwise.
+ findCycle: (NNI,%) -> Record(cycle?: B, prefix: NNI, period: NNI)
+ ++ findCycle(n,st) determines if st is periodic within n.
+ delay: (() -> %) -> %
+ ++ delay(f) creates a stream with a lazy evaluation defined by function f.
+ ++ Caution: This function can only be called in compiled code.
+ cons: (S,%) -> %
+ ++ cons(a,s) returns a stream whose \spad{first} is \spad{a}
+ ++ and whose \spad{rest} is s.
+ ++ Note: \spad{cons(a,s) = concat(a,s)}.
+ if S has SetCategory then
+ output: (I, %) -> Void
+ ++ output(n,st) computes and displays the first n entries
+ ++ of st.
+ showAllElements: % -> OUT
+ ++ showAllElements(s) creates an output form which displays all
+ ++ computed elements.
+ showAll?: () -> B
+ ++ showAll?() returns true if all computed entries of streams
+ ++ will be displayed.
+ --!! this should be a function of one argument
+ setrest_!: (%,I,%) -> %
+ ++ setrest!(x,n,y) sets rest(x,n) to y. The function will expand
+ ++ cycles if necessary.
+ generate: (() -> S) -> %
+ ++ generate(f) creates an infinite stream all of whose elements are
+ ++ equal to \spad{f()}.
+ ++ Note: \spad{generate(f) = [f(),f(),f(),...]}.
+ generate: (S -> S,S) -> %
+ ++ generate(f,x) creates an infinite stream whose first element is
+ ++ x and whose nth element (\spad{n > 1}) is f applied to the previous
+ ++ element. Note: \spad{generate(f,x) = [x,f(x),f(f(x)),...]}.
+ filterWhile: (S -> Boolean,%) -> %
+ ++ filterWhile(p,s) returns \spad{[x0,x1,...,x(n-1)]} where
+ ++ \spad{s = [x0,x1,x2,..]} and
+ ++ n is the smallest index such that \spad{p(xn) = false}.
+ filterUntil: (S -> Boolean,%) -> %
+ ++ filterUntil(p,s) returns \spad{[x0,x1,...,x(n)]} where
+ ++ \spad{s = [x0,x1,x2,..]} and
+ ++ n is the smallest index such that \spad{p(xn) = true}.
+-- if S has SetCategory then
+-- map: ((S,S) -> S,%,%,S) -> %
+-- ++ map(f,x,y,a) is equivalent to map(f,x,y)
+-- ++ If z = map(f,x,y,a), then z = map(f,x,y) except if
+-- ++ x.n = a and rest(rest(x,n)) = rest(x,n) in which case
+-- ++ rest(z,n) = rest(y,n) or if y.m = a and rest(rest(y,m)) =
+-- ++ rest(y,m) in which case rest(z,n) = rest(x,n).
+-- ++ Think of the case where f(xi,yi) = xi + yi and a = 0.
+
+ Implementation ==> add
+ MIN ==> 1 -- minimal stream index; see also the defaults in LZSTAGG
+ x:%
+
+ import CyclicStreamTools(S,%)
+
+--% representation
+
+ -- This description of the rep is not quite true.
+ -- The Rep is a pair of one of three forms:
+ -- [value: S, rest: %]
+ -- [nullstream: Magic, NIL ]
+ -- [nonnullstream: Magic, fun: () -> %]
+ -- Could use a record of unions if we could guarantee no tags.
+
+ NullStream: S := _$NullStream$Lisp pretend S
+ NonNullStream: S := _$NonNullStream$Lisp pretend S
+
+ Rep := Record(firstElt: S, restOfStream: %)
+
+ explicitlyEmpty? x == EQ(frst x,NullStream)$Lisp
+ lazy? x == EQ(frst x,NonNullStream)$Lisp
+
+--% signatures of local functions
+
+ setfrst_! : (%,S) -> S
+ setrst_! : (%,%) -> %
+ setToNil_! : % -> %
+ setrestt_! : (%,I,%) -> %
+ lazyEval : % -> %
+ expand_! : (%,I) -> %
+
+--% functions to access or change record fields without lazy evaluation
+
+ frst x == x.firstElt
+ rst x == x.restOfStream
+
+ setfrst_!(x,s) == x.firstElt := s
+ setrst_!(x,y) == x.restOfStream := y
+
+ setToNil_! x ==
+ -- destructively changes x to a null stream
+ setfrst_!(x,NullStream); setrst_!(x,NIL$Lisp)
+ x
+
+--% SETCAT functions
+
+ if S has SetCategory then
+
+ getm : (%,L OUT,I) -> L OUT
+ streamCountCoerce : % -> OUT
+ listm : (%,L OUT,I) -> L OUT
+
+ getm(x,le,n) ==
+ explicitlyEmpty? x => le
+ lazy? x =>
+ n > 0 =>
+ empty? x => le
+ getm(rst x,concat(frst(x) :: OUT,le),n - 1)
+ concat(message("..."),le)
+ eq?(x,rst x) => concat(overbar(frst(x) :: OUT),le)
+ n > 0 => getm(rst x,concat(frst(x) :: OUT,le),n - 1)
+ concat(message("..."),le)
+
+ streamCountCoerce x ==
+ -- this will not necessarily display all stream elements
+ -- which have been computed
+ count := _$streamCount$Lisp
+ -- compute count elements
+ y := x
+ for i in 1..count while not empty? y repeat y := rst y
+ fc := findCycle(count,x)
+ not fc.cycle? => bracket reverse_! getm(x,empty(),count)
+ le : L OUT := empty()
+ for i in 1..fc.prefix repeat
+ le := concat(first(x) :: OUT,le)
+ x := rest x
+ pp : OUT :=
+ fc.period = 1 => overbar(frst(x) :: OUT)
+ pl : L OUT := empty()
+ for i in 1..fc.period repeat
+ pl := concat(frst(x) :: OUT,pl)
+ x := rest x
+ overbar commaSeparate reverse_! pl
+ bracket reverse_! concat(pp,le)
+
+ listm(x,le,n) ==
+ explicitlyEmpty? x => le
+ lazy? x =>
+ n > 0 =>
+ empty? x => le
+ listm(rst x, concat(frst(x) :: OUT,le),n-1)
+ concat(message("..."),le)
+ listm(rst x,concat(frst(x) :: OUT,le),n-1)
+
+ showAllElements x ==
+ -- this will display all stream elements which have been computed
+ -- and will display at least n elements with n = streamCount$Lisp
+ extend(x,_$streamCount$Lisp)
+ cycElt := cycleElt x
+ cycElt case "failed" =>
+ le := listm(x,empty(),_$streamCount$Lisp)
+ bracket reverse_! le
+ cycEnt := computeCycleEntry(x,cycElt :: %)
+ le : L OUT := empty()
+ while not eq?(x,cycEnt) repeat
+ le := concat(frst(x) :: OUT,le)
+ x := rst x
+ len := computeCycleLength(cycElt :: %)
+ pp : OUT :=
+ len = 1 => overbar(frst(x) :: OUT)
+ pl : L OUT := []
+ for i in 1..len repeat
+ pl := concat(frst(x) :: OUT,pl)
+ x := rst x
+ overbar commaSeparate reverse_! pl
+ bracket reverse_! concat(pp,le)
+
+ showAll?() ==
+ NULL(_$streamsShowAll$Lisp)$Lisp => false
+ true
+
+ coerce(x):OUT ==
+ showAll?() => showAllElements x
+ streamCountCoerce x
+
+--% AGG functions
+
+ lazyCopy:% -> %
+ lazyCopy x == delay
+ empty? x => empty()
+ concat(frst x, copy rst x)
+
+ copy x ==
+ cycElt := cycleElt x
+ cycElt case "failed" => lazyCopy x
+ ce := cycElt :: %
+ len := computeCycleLength(ce)
+ e := computeCycleEntry(x,ce)
+ d := distance(x,e)
+ cycle := complete first(e,len)
+ setrst_!(tail cycle,cycle)
+ d = 0 => cycle
+ head := complete first(x,d::NNI)
+ setrst_!(tail head,cycle)
+ head
+
+--% CNAGG functions
+
+ construct l ==
+ -- copied from defaults to avoid loading defaults
+ empty? l => empty()
+ concat(first l, construct rest l)
+
+--% ELTAGG functions
+
+ elt(x:%,n:I) ==
+ -- copied from defaults to avoid loading defaults
+ n < MIN or empty? x => error "elt: no such element"
+ n = MIN => frst x
+ elt(rst x,n - 1)
+
+ seteltt:(%,I,S) -> S
+ seteltt(x,n,s) ==
+ n = MIN => setfrst_!(x,s)
+ seteltt(rst x,n - 1,s)
+
+ setelt(x,n:I,s:S) ==
+ n < MIN or empty? x => error "setelt: no such element"
+ x := expand_!(x,n - MIN + 1)
+ seteltt(x,n,s)
+
+--% IXAGG functions
+
+ removee: ((S -> Boolean),%) -> %
+ removee(p,x) == delay
+ empty? x => empty()
+ p(frst x) => remove(p,rst x)
+ concat(frst x,remove(p,rst x))
+
+ remove(p,x) ==
+ explicitlyEmpty? x => empty()
+ eq?(x,rst x) =>
+ p(frst x) => empty()
+ x
+ removee(p,x)
+
+ selectt: ((S -> Boolean),%) -> %
+ selectt(p,x) == delay
+ empty? x => empty()
+ not p(frst x) => select(p, rst x)
+ concat(frst x,select(p,rst x))
+
+ select(p,x) ==
+ explicitlyEmpty? x => empty()
+ eq?(x,rst x) =>
+ p(frst x) => x
+ empty()
+ selectt(p,x)
+
+ map(f,x) ==
+ map(f,x pretend Stream(S))$StreamFunctions2(S,S) pretend %
+
+ map(g,x,y) ==
+ xs := x pretend Stream(S); ys := y pretend Stream(S)
+ map(g,xs,ys)$StreamFunctions3(S,S,S) pretend %
+
+ fill_!(x,s) ==
+ setfrst_!(x,s)
+ setrst_!(x,x)
+
+ map_!(f,x) ==
+ -- too many problems with map_! on a lazy stream, so
+ -- in this case, an error message is returned
+ cyclic? x =>
+ tail := cycleTail x ; y := x
+ until y = tail repeat
+ setfrst_!(y,f frst y)
+ y := rst y
+ x
+ explicitlyFinite? x =>
+ y := x
+ while not empty? y repeat
+ setfrst_!(y,f frst y)
+ y := rst y
+ x
+ error "map!: stream with lazy evaluation"
+
+ swap_!(x,m,n) ==
+ (not index?(m,x)) or (not index?(n,x)) =>
+ error "swap!: no such elements"
+ x := expand_!(x,max(m,n) - MIN + 1)
+ xm := elt(x,m); xn := elt(x,n)
+ setelt(x,m,xn); setelt(x,n,xm)
+ x
+
+--% LNAGG functions
+
+ concat(x:%,s:S) == delay
+ empty? x => concat(s,empty())
+ concat(frst x,concat(rst x,s))
+
+ concat(x:%,y:%) == delay
+ empty? x => copy y
+ concat(frst x,concat(rst x, y))
+
+ concat l == delay
+ empty? l => empty()
+ empty?(x := first l) => concat rest l
+ concat(frst x,concat(rst x,concat rest l))
+
+ setelt(x,seg:U,s:S) ==
+ low := lo seg
+ hasHi seg =>
+ high := hi seg
+ high < low => s
+ (not index?(low,x)) or (not index?(high,x)) =>
+ error "setelt: index out of range"
+ x := expand_!(x,high - MIN + 1)
+ y := rest(x,(low - MIN) :: NNI)
+ for i in 0..(high-low) repeat
+ setfrst_!(y,s)
+ y := rst y
+ s
+ not index?(low,x) => error "setelt: index out of range"
+ x := rest(x,(low - MIN) :: NNI)
+ setrst_!(x,x)
+ setfrst_!(x,s)
+
+--% RCAGG functions
+
+ empty() == [NullStream, NIL$Lisp]
+
+ lazyEval x == (rst(x):(()-> %)) ()
+
+ lazyEvaluate x ==
+ st := lazyEval x
+ setfrst_!(x, frst st)
+ setrst_!(x,if EQ(rst st,st)$Lisp then x else rst st)
+ x
+
+ -- empty? is the only function that explicitly causes evaluation
+ -- of a stream element
+ empty? x ==
+ while lazy? x repeat
+ st := lazyEval x
+ setfrst_!(x, frst st)
+ setrst_!(x,if EQ(rst st,st)$Lisp then x else rst st)
+ explicitlyEmpty? x
+
+ --setvalue(x,s) == setfirst_!(x,s)
+
+ --setchildren(x,l) ==
+ --empty? l => error "setchildren: empty list of children"
+ --not(empty? rest l) => error "setchildren: wrong number of children"
+ --setrest_!(x,first l)
+
+--% URAGG functions
+
+ first(x,n) == delay
+ -- former name: take
+ n = 0 or empty? x => empty()
+ (concat(frst x, first(rst x,(n-1) :: NNI)))
+
+ concat(s:S,x:%) == [s,x]
+ cons(s,x) == concat(s,x)
+
+ cycleSplit_! x ==
+ cycElt := cycleElt x
+ cycElt case "failed" =>
+ error "cycleSplit_!: non-cyclic stream"
+ y := computeCycleEntry(x,cycElt :: %)
+ eq?(x,y) => (setToNil_! x; return y)
+ z := rst x
+ repeat
+ eq?(y,z) => (setrest_!(x,empty()); return y)
+ x := z ; z := rst z
+
+ expand_!(x,n) ==
+ -- expands cycles (if necessary) so that the first n
+ -- elements of x will not be part of a cycle
+ n < 1 => x
+ y := x
+ for i in 1..n while not empty? y repeat y := rst y
+ cycElt := cycleElt x
+ cycElt case "failed" => x
+ e := computeCycleEntry(x,cycElt :: %)
+ d : I := distance(x,e)
+ d >= n => x
+ if d = 0 then
+ -- roll the cycle 1 entry
+ d := 1
+ t := cycleTail e
+ if eq?(t,e) then
+ t := concat(frst t,empty())
+ e := setrst_!(t,t)
+ setrst_!(x,e)
+ else
+ setrst_!(t,concat(frst e,rst e))
+ e := rst e
+ nLessD := (n-d) :: NNI
+ y := complete first(e,nLessD)
+ e := rest(e,nLessD)
+ setrst_!(tail y,e)
+ setrst_!(rest(x,(d-1) :: NNI),y)
+ x
+
+ first x ==
+ empty? x => error "Can't take the first of an empty stream."
+ frst x
+
+ concat_!(x:%,y:%) ==
+ empty? x => y
+ setrst_!(tail x,y)
+
+ concat_!(x:%,s:S) ==
+ concat_!(x,concat(s,empty()))
+
+ setfirst_!(x,s) == setelt(x,0,s)
+ setelt(x,"first",s) == setfirst_!(x,s)
+ setrest_!(x,y) ==
+ empty? x => error "setrest!: empty stream"
+ setrst_!(x,y)
+ setelt(x,"rest",y) == setrest_!(x,y)
+
+ setlast_!(x,s) ==
+ empty? x => error "setlast!: empty stream"
+ setfrst_!(tail x, s)
+ setelt(x,"last",s) == setlast_!(x,s)
+
+ split_!(x,n) ==
+ n < MIN => error "split!: index out of range"
+ n = MIN =>
+ y : % := empty()
+ setfrst_!(y,frst x)
+ setrst_!(y,rst x)
+ setToNil_! x
+ y
+ x := expand_!(x,n - MIN)
+ x := rest(x,(n - MIN - 1) :: NNI)
+ y := rest x
+ setrst_!(x,empty())
+ y
+
+--% STREAM functions
+
+ coerce(l: L S) == construct l
+
+ repeating l ==
+ empty? l =>
+ error "Need a non-null list to make a repeating stream."
+ x0 : % := x := construct l
+ while not empty? rst x repeat x := rst x
+ setrst_!(x,x0)
+
+ if S has SetCategory then
+
+ repeating?(l, x) ==
+ empty? l =>
+ error "Need a non-empty? list to make a repeating stream."
+ empty? rest l =>
+ not empty? x and frst x = first l and x = rst x
+ x0 := x
+ for s in l repeat
+ empty? x or s ^= frst x => return false
+ x := rst x
+ eq?(x,x0)
+
+ findCycle(n, x) ==
+ hd := x
+ -- Determine whether periodic within n.
+ tl := rest(x, n)
+ explicitlyEmpty? tl => [false, 0, 0]
+ i := 0; while not eq?(x,tl) repeat (x := rst x; i := i + 1)
+ i = n => [false, 0, 0]
+ -- Find period. Now x=tl, so step over and find it again.
+ x := rst x; per := 1
+ while not eq?(x,tl) repeat (x := rst x; per := per + 1)
+ -- Find non-periodic part.
+ x := hd; xp := rest(hd, per); npp := 0
+ while not eq?(x,xp) repeat (x := rst x; xp := rst xp; npp := npp+1)
+ [true, npp, per]
+
+ delay(fs:()->%) == [NonNullStream, fs pretend %]
+
+-- explicitlyEmpty? x == markedNull? x
+
+ explicitEntries? x ==
+ not explicitlyEmpty? x and not lazy? x
+
+ numberOfComputedEntries x ==
+ explicitEntries? x => numberOfComputedEntries(rst x) + 1
+ 0
+
+ if S has SetCategory then
+
+ output(n,x) ==
+ (not(n>0))or empty? x => void()
+ mathPrint(frst(x)::OUT)$Lisp
+ output(n-1, rst x)
+
+ setrestt_!(x,n,y) ==
+ n = 0 => setrst_!(x,y)
+ setrestt_!(rst x,n-1,y)
+
+ setrest_!(x,n,y) ==
+ n < 0 or empty? x => error "setrest!: no such rest"
+ x := expand_!(x,n+1)
+ setrestt_!(x,n,y)
+
+ generate f == delay concat(f(), generate f)
+ gen:(S -> S,S) -> %
+ gen(f,s) == delay(ss:=f s; concat(ss, gen(f,ss)))
+ generate(f,s)==concat(s,gen(f,s))
+
+ concat(x:%,y:%) ==delay
+ empty? x => y
+ concat(frst x,concat(rst x,y))
+
+ swhilee:(S -> Boolean,%) -> %
+ swhilee(p,x) == delay
+ empty? x => empty()
+ not p(frst x) => empty()
+ concat(frst x,filterWhile(p,rst x))
+ filterWhile(p,x)==
+ explicitlyEmpty? x => empty()
+ eq?(x,rst x) =>
+ p(frst x) => x
+ empty()
+ swhilee(p,x)
+
+ suntill: (S -> Boolean,%) -> %
+ suntill(p,x) == delay
+ empty? x => empty()
+ p(frst x) => concat(frst x,empty())
+ concat(frst x, filterUntil(p, rst x))
+
+ filterUntil(p,x)==
+ explicitlyEmpty? x => empty()
+ eq?(x,rst x) =>
+ p(frst x) => concat(frst x,empty())
+ x
+ suntill(p,x)
+
+-- if S has SetCategory then
+-- mapp: ((S,S) -> S,%,%,S) -> %
+-- mapp(f,x,y,a) == delay
+-- empty? x or empty? y => empty()
+-- concat(f(frst x,frst y), map(f,rst x,rst y,a))
+-- map(f,x,y,a) ==
+-- explicitlyEmpty? x => empty()
+-- eq?(x,rst x) =>
+-- frst x=a => y
+-- map(f(frst x,#1),y)
+-- explicitlyEmpty? y => empty()
+-- eq?(y,rst y) =>
+-- frst y=a => x
+-- p(f(#1,frst y),x)
+-- mapp(f,x,y,a)
+
+@
+\section{package STREAM1 StreamFunctions1}
+<<package STREAM1 StreamFunctions1>>=
+)abbrev package STREAM1 StreamFunctions1
+++ Authors: Burge, Watt; updated by Clifton J. Williamson
+++ Date Created: July 1986
+++ Date Last Updated: 29 January 1990
+++ Keywords: stream, infinite list, infinite sequence
+StreamFunctions1(S:Type): Exports == Implementation where
+ ++ Functions defined on streams with entries in one set.
+ ST ==> Stream
+
+ Exports ==> with
+ concat: ST ST S -> ST S
+ ++ concat(u) returns the left-to-right concatentation of the streams in u.
+ ++ Note: \spad{concat(u) = reduce(concat,u)}.
+
+ Implementation ==> add
+
+ concat z == delay
+ empty? z => empty()
+ empty?(x := frst z) => concat rst z
+ concat(frst x,concat(rst x,concat rst z))
+
+@
+\section{package STREAM2 StreamFunctions2}
+<<package STREAM2 StreamFunctions2>>=
+)abbrev package STREAM2 StreamFunctions2
+++ Authors: Burge, Watt; updated by Clifton J. Williamson
+++ Date Created: July 1986
+++ Date Last Updated: 29 January 1990
+++ Keywords: stream, infinite list, infinite sequence
+StreamFunctions2(A:Type,B:Type): Exports == Implementation where
+ ++ Functions defined on streams with entries in two sets.
+ ST ==> Stream
+
+ Exports ==> with
+ map: ((A -> B),ST A) -> ST B
+ ++ map(f,s) returns a stream whose elements are the function f applied
+ ++ to the corresponding elements of s.
+ ++ Note: \spad{map(f,[x0,x1,x2,...]) = [f(x0),f(x1),f(x2),..]}.
+ scan: (B,((A,B) -> B),ST A) -> ST B
+ ++ scan(b,h,[x0,x1,x2,...]) returns \spad{[y0,y1,y2,...]}, where
+ ++ \spad{y0 = h(x0,b)},
+ ++ \spad{y1 = h(x1,y0)},\spad{...}
+ ++ \spad{yn = h(xn,y(n-1))}.
+ reduce: (B,(A,B) -> B,ST A) -> B
+ ++ reduce(b,f,u), where u is a finite stream \spad{[x0,x1,...,xn]},
+ ++ returns the value \spad{r(n)} computed as follows:
+ ++ \spad{r0 = f(x0,b),
+ ++ r1 = f(x1,r0),...,
+ ++ r(n) = f(xn,r(n-1))}.
+-- rreduce: (B,(A,B) -> B,ST A) -> B
+-- ++ reduce(b,h,[x0,x1,..,xn]) = h(x1,h(x2(..,h(x(n-1),h(xn,b))..)
+-- reshape: (ST B,ST A) -> ST B
+-- ++ reshape(y,x) = y
+
+ Implementation ==> add
+
+ mapp: (A -> B,ST A) -> ST B
+ mapp(f,x)== delay
+ empty? x => empty()
+ concat(f frst x, map(f,rst x))
+
+ map(f,x) ==
+ explicitlyEmpty? x => empty()
+ eq?(x,rst x) => repeating([f frst x])
+ mapp(f, x)
+
+-- reshape(y,x) == y
+
+ scan(b,h,x) == delay
+ empty? x => empty()
+ c := h(frst x,b)
+ concat(c,scan(c,h,rst x))
+
+ reduce(b,h,x) ==
+ empty? x => b
+ reduce(h(frst x,b),h,rst x)
+-- rreduce(b,h,x) ==
+-- empty? x => b
+-- h(frst x,rreduce(b,h,rst x))
+
+@
+\section{package STREAM3 StreamFunctions3}
+<<package STREAM3 StreamFunctions3>>=
+)abbrev package STREAM3 StreamFunctions3
+++ Authors: Burge, Watt; updated by Clifton J. Williamson
+++ Date Created: July 1986
+++ Date Last Updated: 29 January 1990
+++ Keywords: stream, infinite list, infinite sequence
+StreamFunctions3(A,B,C): Exports == Implementation where
+ ++ Functions defined on streams with entries in three sets.
+ A : Type
+ B : Type
+ C : Type
+ ST ==> Stream
+
+ Exports ==> with
+ map: ((A,B) -> C,ST A,ST B) -> ST C
+ ++ map(f,st1,st2) returns the stream whose elements are the
+ ++ function f applied to the corresponding elements of st1 and st2.
+ ++ Note: \spad{map(f,[x0,x1,x2,..],[y0,y1,y2,..]) = [f(x0,y0),f(x1,y1),..]}.
+
+ Implementation ==> add
+
+ mapp:((A,B) -> C,ST A,ST B) -> ST C
+ mapp(g,x,y) == delay
+ empty? x or empty? y => empty()
+ concat(g(frst x,frst y), map(g,rst x,rst y))
+
+ map(g,x,y) ==
+ explicitlyEmpty? x => empty()
+ eq?(x,rst x) => map(g(frst x,#1),y)$StreamFunctions2(B,C)
+ explicitlyEmpty? y => empty()
+ eq?(y,rst y) => map(g(#1,frst y),x)$StreamFunctions2(A,C)
+ mapp(g,x,y)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category LZSTAGG LazyStreamAggregate>>
+<<package CSTTOOLS CyclicStreamTools>>
+<<domain STREAM Stream>>
+<<package STREAM1 StreamFunctions1>>
+<<package STREAM2 StreamFunctions2>>
+<<package STREAM3 StreamFunctions3>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/string.spad.pamphlet b/src/algebra/string.spad.pamphlet
new file mode 100644
index 00000000..6fb42a50
--- /dev/null
+++ b/src/algebra/string.spad.pamphlet
@@ -0,0 +1,735 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra string.spad}
+\author{Stephen M. Watt, Michael Monagan, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain CHAR Character}
+<<domain CHAR Character>>=
+)abbrev domain CHAR Character
+++ Author: Stephen M. Watt
+++ Date Created: July 1986
+++ Date Last Updated: June 20, 1991
+++ Basic Operations: char
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: character, string
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides the basic character data type.
+
+Character: OrderedFinite() with
+ ord: % -> Integer
+ ++ ord(c) provides an integral code corresponding to the
+ ++ character c. It is always true that \spad{char ord c = c}.
+ char: Integer -> %
+ ++ char(i) provides a character corresponding to the integer
+ ++ code i. It is always true that \spad{ord char i = i}.
+ char: String -> %
+ ++ char(s) provides a character from a string s of length one.
+ space: () -> %
+ ++ space() provides the blank character.
+ quote: () -> %
+ ++ quote() provides the string quote character, \spad{"}.
+ escape: () -> %
+ ++ escape() provides the escape character, \spad{_}, which
+ ++ is used to allow quotes and other characters {\em within}
+ ++ strings.
+ upperCase: % -> %
+ ++ upperCase(c) converts a lower case letter to the corresponding
+ ++ upper case letter. If c is not a lower case letter, then
+ ++ it is returned unchanged.
+ lowerCase: % -> %
+ ++ lowerCase(c) converts an upper case letter to the corresponding
+ ++ lower case letter. If c is not an upper case letter, then
+ ++ it is returned unchanged.
+ digit?: % -> Boolean
+ ++ digit?(c) tests if c is a digit character,
+ ++ i.e. one of 0..9.
+ hexDigit?: % -> Boolean
+ ++ hexDigit?(c) tests if c is a hexadecimal numeral,
+ ++ i.e. one of 0..9, a..f or A..F.
+ alphabetic?: % -> Boolean
+ ++ alphabetic?(c) tests if c is a letter,
+ ++ i.e. one of a..z or A..Z.
+ upperCase?: % -> Boolean
+ ++ upperCase?(c) tests if c is an upper case letter,
+ ++ i.e. one of A..Z.
+ lowerCase?: % -> Boolean
+ ++ lowerCase?(c) tests if c is an lower case letter,
+ ++ i.e. one of a..z.
+ alphanumeric?: % -> Boolean
+ ++ alphanumeric?(c) tests if c is either a letter or number,
+ ++ i.e. one of 0..9, a..z or A..Z.
+
+ == add
+ Rep := SingleInteger -- 0..255
+
+ CC ==> CharacterClass()
+ import CC
+
+ --cl: Record(dig:CC,hex:CC,upp:CC,low:CC,alpha:CC,alnum:CC) :=
+ -- [ digit(), hexDigit(),
+ -- upperCase(), lowerCase(), alphabetic(), alphanumeric() ]
+
+ OutChars:PrimitiveArray(OutputForm) :=
+ construct [NUM2CHAR(i)$Lisp for i in 0..255]
+
+ minChar := minIndex OutChars
+
+ a = b == a =$Rep b
+ a < b == a <$Rep b
+ size() == 256
+ index n == char((n - 1)::Integer)
+ lookup c == (1 + ord c)::PositiveInteger
+ char(n:Integer) == n::%
+ ord c == convert(c)$Rep
+ random() == char(random()$Integer rem size())
+ space == QENUM(" ", 0$Lisp)$Lisp
+ quote == QENUM("_" ", 0$Lisp)$Lisp
+ escape == QENUM("__ ", 0$Lisp)$Lisp
+ coerce(c:%):OutputForm == OutChars(minChar + ord c)
+ digit? c == member?(c pretend Character, digit())
+ hexDigit? c == member?(c pretend Character, hexDigit())
+ upperCase? c == member?(c pretend Character, upperCase())
+ lowerCase? c == member?(c pretend Character, lowerCase())
+ alphabetic? c == member?(c pretend Character, alphabetic())
+ alphanumeric? c == member?(c pretend Character, alphanumeric())
+
+ latex c ==
+ concat("\mbox{`", concat(new(1,c pretend Character)$String, "'}")$String)$String
+
+ char(s:String) ==
+-- one?(#s) => s(minIndex s) pretend %
+ (#s) = 1 => s(minIndex s) pretend %
+ error "String is not a single character"
+
+ upperCase c ==
+ QENUM(PNAME(UPCASE(NUM2CHAR(ord c)$Lisp)$Lisp)$Lisp,
+ 0$Lisp)$Lisp
+
+ lowerCase c ==
+ QENUM(PNAME(DOWNCASE(NUM2CHAR(ord c)$Lisp)$Lisp)$Lisp,
+ 0$Lisp)$Lisp
+
+@
+\section{CHAR.lsp BOOTSTRAP}
+{\bf CHAR} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf CHAR} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf CHAR.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<CHAR.lsp BOOTSTRAP>>=
+
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |CHAR;=;2$B;1|) (QUOTE |SPADreplace|) (QUOTE EQL))
+
+(DEFUN |CHAR;=;2$B;1| (|a| |b| |$|) (EQL |a| |b|))
+
+(PUT (QUOTE |CHAR;<;2$B;2|) (QUOTE |SPADreplace|) (QUOTE QSLESSP))
+
+(DEFUN |CHAR;<;2$B;2| (|a| |b| |$|) (QSLESSP |a| |b|))
+
+(PUT (QUOTE |CHAR;size;Nni;3|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL 256)))
+
+(DEFUN |CHAR;size;Nni;3| (|$|) 256)
+
+(DEFUN |CHAR;index;Pi$;4| (|n| |$|) (SPADCALL (|-| |n| 1) (QREFELT |$| 18)))
+
+(DEFUN |CHAR;lookup;$Pi;5| (|c| |$|) (PROG (#1=#:G90919) (RETURN (PROG1 (LETT #1# (|+| 1 (SPADCALL |c| (QREFELT |$| 21))) |CHAR;lookup;$Pi;5|) (|check-subtype| (|>| #1# 0) (QUOTE (|PositiveInteger|)) #1#)))))
+
+(DEFUN |CHAR;char;I$;6| (|n| |$|) (SPADCALL |n| (QREFELT |$| 23)))
+
+(PUT (QUOTE |CHAR;ord;$I;7|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|c|) |c|)))
+
+(DEFUN |CHAR;ord;$I;7| (|c| |$|) |c|)
+
+(DEFUN |CHAR;random;$;8| (|$|) (SPADCALL (REMAINDER2 (|random|) (SPADCALL (QREFELT |$| 16))) (QREFELT |$| 18)))
+
+(PUT (QUOTE |CHAR;space;$;9|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (QENUM " " 0))))
+
+(DEFUN |CHAR;space;$;9| (|$|) (QENUM " " 0))
+
+(PUT (QUOTE |CHAR;quote;$;10|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (QENUM "\" " 0))))
+
+(DEFUN |CHAR;quote;$;10| (|$|) (QENUM "\" " 0))
+
+(PUT (QUOTE |CHAR;escape;$;11|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (QENUM "_ " 0))))
+
+(DEFUN |CHAR;escape;$;11| (|$|) (QENUM "_ " 0))
+
+(DEFUN |CHAR;coerce;$Of;12| (|c| |$|) (ELT (QREFELT |$| 10) (|+| (QREFELT |$| 11) (SPADCALL |c| (QREFELT |$| 21)))))
+
+(DEFUN |CHAR;digit?;$B;13| (|c| |$|) (SPADCALL |c| (|spadConstant| |$| 31) (QREFELT |$| 33)))
+
+(DEFUN |CHAR;hexDigit?;$B;14| (|c| |$|) (SPADCALL |c| (|spadConstant| |$| 35) (QREFELT |$| 33)))
+
+(DEFUN |CHAR;upperCase?;$B;15| (|c| |$|) (SPADCALL |c| (|spadConstant| |$| 37) (QREFELT |$| 33)))
+
+(DEFUN |CHAR;lowerCase?;$B;16| (|c| |$|) (SPADCALL |c| (|spadConstant| |$| 39) (QREFELT |$| 33)))
+
+(DEFUN |CHAR;alphabetic?;$B;17| (|c| |$|) (SPADCALL |c| (|spadConstant| |$| 41) (QREFELT |$| 33)))
+
+(DEFUN |CHAR;alphanumeric?;$B;18| (|c| |$|) (SPADCALL |c| (|spadConstant| |$| 43) (QREFELT |$| 33)))
+
+(DEFUN |CHAR;latex;$S;19| (|c| |$|) (STRCONC "\\mbox{`" (STRCONC (|MAKE-FULL-CVEC| 1 |c|) "'}")))
+
+(DEFUN |CHAR;char;S$;20| (|s| |$|) (COND ((EQL (QCSIZE |s|) 1) (SPADCALL |s| (SPADCALL |s| (QREFELT |$| 47)) (QREFELT |$| 48))) ((QUOTE T) (|error| "String is not a single character"))))
+
+(DEFUN |CHAR;upperCase;2$;21| (|c| |$|) (QENUM (PNAME (UPCASE (NUM2CHAR (SPADCALL |c| (QREFELT |$| 21))))) 0))
+
+(DEFUN |CHAR;lowerCase;2$;22| (|c| |$|) (QENUM (PNAME (DOWNCASE (NUM2CHAR (SPADCALL |c| (QREFELT |$| 21))))) 0))
+
+(DEFUN |Character| NIL (PROG NIL (RETURN (PROG (#1=#:G90941) (RETURN (COND ((LETT #1# (HGET |$ConstructorCache| (QUOTE |Character|)) |Character|) (|CDRwithIncrement| (CDAR #1#))) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (CDDAR (HPUT |$ConstructorCache| (QUOTE |Character|) (LIST (CONS NIL (CONS 1 (|Character;|)))))) (LETT #1# T |Character|)) (COND ((NOT #1#) (HREM |$ConstructorCache| (QUOTE |Character|))))))))))))
+
+(DEFUN |Character;| NIL (PROG (|dv$| |$| |pv$| #1=#:G90939 |i|) (RETURN (SEQ (PROGN (LETT |dv$| (QUOTE (|Character|)) . #2=(|Character|)) (LETT |$| (GETREFV 53) . #2#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #2#)) (|haddProp| |$ConstructorCache| (QUOTE |Character|) NIL (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 (|SingleInteger|)) (QSETREFV |$| 10 (SPADCALL (PROGN (LETT #1# NIL . #2#) (SEQ (LETT |i| 0 . #2#) G190 (COND ((QSGREATERP |i| 255) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (NUM2CHAR |i|) #1#) . #2#))) (LETT |i| (QSADD1 |i|) . #2#) (GO G190) G191 (EXIT (NREVERSE0 #1#)))) (QREFELT |$| 9))) (QSETREFV |$| 11 0) |$|)))))
+
+(MAKEPROP (QUOTE |Character|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (QUOTE |Rep|) (|List| 28) (|PrimitiveArray| 28) (0 . |construct|) (QUOTE |OutChars|) (QUOTE |minChar|) (|Boolean|) |CHAR;=;2$B;1| |CHAR;<;2$B;2| (|NonNegativeInteger|) |CHAR;size;Nni;3| (|Integer|) |CHAR;char;I$;6| (|PositiveInteger|) |CHAR;index;Pi$;4| |CHAR;ord;$I;7| |CHAR;lookup;$Pi;5| (5 . |coerce|) |CHAR;random;$;8| |CHAR;space;$;9| |CHAR;quote;$;10| |CHAR;escape;$;11| (|OutputForm|) |CHAR;coerce;$Of;12| (|CharacterClass|) (10 . |digit|) (|Character|) (14 . |member?|) |CHAR;digit?;$B;13| (20 . |hexDigit|) |CHAR;hexDigit?;$B;14| (24 . |upperCase|) |CHAR;upperCase?;$B;15| (28 . |lowerCase|) |CHAR;lowerCase?;$B;16| (32 . |alphabetic|) |CHAR;alphabetic?;$B;17| (36 . |alphanumeric|) |CHAR;alphanumeric?;$B;18| (|String|) |CHAR;latex;$S;19| (40 . |minIndex|) (45 . |elt|) |CHAR;char;S$;20| |CHAR;upperCase;2$;21| |CHAR;lowerCase;2$;22| (|SingleInteger|))) (QUOTE #(|~=| 51 |upperCase?| 57 |upperCase| 62 |space| 67 |size| 71 |random| 75 |quote| 79 |ord| 83 |min| 88 |max| 94 |lowerCase?| 100 |lowerCase| 105 |lookup| 110 |latex| 115 |index| 120 |hexDigit?| 125 |hash| 130 |escape| 135 |digit?| 139 |coerce| 144 |char| 149 |alphanumeric?| 159 |alphabetic?| 164 |>=| 169 |>| 175 |=| 181 |<=| 187 |<| 193)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0))) (CONS (QUOTE #(NIL |OrderedSet&| NIL |SetCategory&| |BasicType&| NIL)) (CONS (QUOTE #((|OrderedFinite|) (|OrderedSet|) (|Finite|) (|SetCategory|) (|BasicType|) (|CoercibleTo| 28))) (|makeByteWordVec2| 52 (QUOTE (1 8 0 7 9 1 6 0 17 23 0 30 0 31 2 30 12 32 0 33 0 30 0 35 0 30 0 37 0 30 0 39 0 30 0 41 0 30 0 43 1 45 17 0 47 2 45 32 0 17 48 2 0 12 0 0 1 1 0 12 0 38 1 0 0 0 50 0 0 0 25 0 0 15 16 0 0 0 24 0 0 0 26 1 0 17 0 21 2 0 0 0 0 1 2 0 0 0 0 1 1 0 12 0 40 1 0 0 0 51 1 0 19 0 22 1 0 45 0 46 1 0 0 19 20 1 0 12 0 36 1 0 52 0 1 0 0 0 27 1 0 12 0 34 1 0 28 0 29 1 0 0 45 49 1 0 0 17 18 1 0 12 0 44 1 0 12 0 42 2 0 12 0 0 1 2 0 12 0 0 1 2 0 12 0 0 13 2 0 12 0 0 1 2 0 12 0 0 14)))))) (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |Character|) (QUOTE NILADIC) T)
+@
+\section{domain CCLASS CharacterClass}
+<<domain CCLASS CharacterClass>>=
+)abbrev domain CCLASS CharacterClass
+++ Author: Stephen M. Watt
+++ Date Created: July 1986
+++ Date Last Updated: June 20, 1991
+++ Basic Operations: charClass
+++ Related Domains: Character, Bits
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows classes of characters to be defined and manipulated
+++ efficiently.
+
+
+CharacterClass: Join(SetCategory, ConvertibleTo String,
+ FiniteSetAggregate Character, ConvertibleTo List Character) with
+ charClass: String -> %
+ ++ charClass(s) creates a character class which contains
+ ++ exactly the characters given in the string s.
+ charClass: List Character -> %
+ ++ charClass(l) creates a character class which contains
+ ++ exactly the characters given in the list l.
+ digit: constant -> %
+ ++ digit() returns the class of all characters
+ ++ for which \spadfunFrom{digit?}{Character} is true.
+ hexDigit: constant -> %
+ ++ hexDigit() returns the class of all characters for which
+ ++ \spadfunFrom{hexDigit?}{Character} is true.
+ upperCase: constant -> %
+ ++ upperCase() returns the class of all characters for which
+ ++ \spadfunFrom{upperCase?}{Character} is true.
+ lowerCase: constant -> %
+ ++ lowerCase() returns the class of all characters for which
+ ++ \spadfunFrom{lowerCase?}{Character} is true.
+ alphabetic : constant -> %
+ ++ alphabetic() returns the class of all characters for which
+ ++ \spadfunFrom{alphabetic?}{Character} is true.
+ alphanumeric: constant -> %
+ ++ alphanumeric() returns the class of all characters for which
+ ++ \spadfunFrom{alphanumeric?}{Character} is true.
+
+ == add
+ Rep := IndexedBits(0)
+ N := size()$Character
+
+ a, b: %
+
+ digit() == charClass "0123456789"
+ hexDigit() == charClass "0123456789abcdefABCDEF"
+ upperCase() == charClass "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ lowerCase() == charClass "abcdefghijklmnopqrstuvwxyz"
+ alphabetic() == union(upperCase(), lowerCase())
+ alphanumeric() == union(alphabetic(), digit())
+
+ a = b == a =$Rep b
+
+ member?(c, a) == a(ord c)
+ union(a,b) == Or(a, b)
+ intersect (a,b) == And(a, b)
+ difference(a,b) == And(a, Not b)
+ complement a == Not a
+
+ convert(cl):String ==
+ construct(convert(cl)@List(Character))
+ convert(cl:%):List(Character) ==
+ [char(i) for i in 0..N-1 | cl.i]
+
+ charClass(s: String) ==
+ cl := new(N, false)
+ for i in minIndex(s)..maxIndex(s) repeat cl(ord s.i) := true
+ cl
+
+ charClass(l: List Character) ==
+ cl := new(N, false)
+ for c in l repeat cl(ord c) := true
+ cl
+
+ coerce(cl):OutputForm == (convert(cl)@String)::OutputForm
+
+ -- Stuff to make a legal SetAggregate view
+ # a == (n := 0; for i in 0..N-1 | a.i repeat n := n+1; n)
+ empty():% == charClass []
+ brace():% == charClass []
+
+ insert_!(c, a) == (a(ord c) := true; a)
+ remove_!(c, a) == (a(ord c) := false; a)
+
+ inspect(a) ==
+ for i in 0..N-1 | a.i repeat
+ return char i
+ error "Cannot take a character from an empty class."
+ extract_!(a) ==
+ for i in 0..N-1 | a.i repeat
+ a.i := false
+ return char i
+ error "Cannot take a character from an empty class."
+
+ map(f, a) ==
+ b := new(N, false)
+ for i in 0..N-1 | a.i repeat b(ord f char i) := true
+ b
+
+ temp: % := new(N, false)$Rep
+ map_!(f, a) ==
+ fill_!(temp, false)
+ for i in 0..N-1 | a.i repeat temp(ord f char i) := true
+ copyInto_!(a, temp, 0)
+
+ parts a ==
+ [char i for i in 0..N-1 | a.i]
+
+@
+\section{domain ISTRING IndexedString}
+<<domain ISTRING IndexedString>>=
+)abbrev domain ISTRING IndexedString
+++ Authors: Stephen Watt, Michael Monagan, Manuel Bronstein 1986 .. 1991
+-- The following Lisp dependencies are divided into two groups
+-- Those that are required
+-- QENUM QESET QCSIZE MAKE-FULL-CVEC EQ QSLESSP QSGREATERP
+-- Those that can are included for efficiency only
+-- COPY STRCONC SUBSTRING STRPOS RPLACSTR DOWNCASE UPCASE CGREATERP
+++ Description:
+++ This domain implements low-level strings
+
+IndexedString(mn:Integer): Export == Implementation where
+ B ==> Boolean
+ C ==> Character
+ I ==> Integer
+ N ==> NonNegativeInteger
+ U ==> UniversalSegment Integer
+
+ Export ==> StringAggregate() with
+ hash: % -> I
+ ++ hash(x) provides a hashing function for strings
+
+ Implementation ==> add
+ -- These assume Character's Rep is Small I
+ Qelt ==> QENUM$Lisp
+ Qequal ==> EQUAL$Lisp
+ Qsetelt ==> QESET$Lisp
+ Qsize ==> QCSIZE$Lisp
+ Cheq ==> EQL$Lisp
+ Chlt ==> QSLESSP$Lisp
+ Chgt ==> QSGREATERP$Lisp
+
+ c: Character
+ cc: CharacterClass
+
+-- new n == MAKE_-FULL_-CVEC(n, space$C)$Lisp
+ new(n, c) == MAKE_-FULL_-CVEC(n, c)$Lisp
+ empty() == MAKE_-FULL_-CVEC(0$Lisp)$Lisp
+ empty?(s) == Qsize(s) = 0
+ #s == Qsize(s)
+ s = t == Qequal(s, t)
+ s < t == CGREATERP(t,s)$Lisp
+ concat(s:%,t:%) == STRCONC(s,t)$Lisp
+ copy s == COPY_-SEQ(s)$Lisp
+ insert(s:%, t:%, i:I) == concat(concat(s(mn..i-1), t), s(i..))
+ coerce(s:%):OutputForm == outputForm(s pretend String)
+ minIndex s == mn
+ upperCase_! s == map_!(upperCase, s)
+ lowerCase_! s == map_!(lowerCase, s)
+
+ latex s == concat("\mbox{``", concat(s pretend String, "''}"))
+
+ replace(s, sg, t) ==
+ l := lo(sg) - mn
+ m := #s
+ n := #t
+ h:I := if hasHi sg then hi(sg) - mn else maxIndex s - mn
+ l < 0 or h >= m or h < l-1 => error "index out of range"
+ r := new((m-(h-l+1)+n)::N, space$C)
+ for k in 0.. for i in 0..l-1 repeat Qsetelt(r, k, Qelt(s, i))
+ for k in k.. for i in 0..n-1 repeat Qsetelt(r, k, Qelt(t, i))
+ for k in k.. for i in h+1..m-1 repeat Qsetelt(r, k, Qelt(s, i))
+ r
+
+ setelt(s:%, i:I, c:C) ==
+ i < mn or i > maxIndex(s) => error "index out of range"
+ Qsetelt(s, i - mn, c)
+ c
+
+ substring?(part, whole, startpos) ==
+ np:I := Qsize part
+ nw:I := Qsize whole
+ (startpos := startpos - mn) < 0 => error "index out of bounds"
+ np > nw - startpos => false
+ for ip in 0..np-1 for iw in startpos.. repeat
+ not Cheq(Qelt(part, ip), Qelt(whole, iw)) => return false
+ true
+
+ position(s:%, t:%, startpos:I) ==
+ (startpos := startpos - mn) < 0 => error "index out of bounds"
+ startpos >= Qsize t => mn - 1
+ r:I := STRPOS(s, t, startpos, NIL$Lisp)$Lisp
+ EQ(r, NIL$Lisp)$Lisp => mn - 1
+ r + mn
+ position(c: Character, t: %, startpos: I) ==
+ (startpos := startpos - mn) < 0 => error "index out of bounds"
+ startpos >= Qsize t => mn - 1
+ for r in startpos..Qsize t - 1 repeat
+ if Cheq(Qelt(t, r), c) then return r + mn
+ mn - 1
+ position(cc: CharacterClass, t: %, startpos: I) ==
+ (startpos := startpos - mn) < 0 => error "index out of bounds"
+ startpos >= Qsize t => mn - 1
+ for r in startpos..Qsize t - 1 repeat
+ if member?(Qelt(t,r), cc) then return r + mn
+ mn - 1
+
+ suffix?(s, t) ==
+ (m := maxIndex s) > (n := maxIndex t) => false
+ substring?(s, t, mn + n - m)
+
+ split(s, c) ==
+ n := maxIndex s
+ for i in mn..n while s.i = c repeat 0
+ l := empty()$List(%)
+ j:Integer -- j is conditionally intialized
+ while i <= n and (j := position(c, s, i)) >= mn repeat
+ l := concat(s(i..j-1), l)
+ for i in j..n while s.i = c repeat 0
+ if i <= n then l := concat(s(i..n), l)
+ reverse_! l
+ split(s, cc) ==
+ n := maxIndex s
+ for i in mn..n while member?(s.i,cc) repeat 0
+ l := empty()$List(%)
+ j:Integer -- j is conditionally intialized
+ while i <= n and (j := position(cc, s, i)) >= mn repeat
+ l := concat(s(i..j-1), l)
+ for i in j..n while member?(s.i,cc) repeat 0
+ if i <= n then l := concat(s(i..n), l)
+ reverse_! l
+
+ leftTrim(s, c) ==
+ n := maxIndex s
+ for i in mn .. n while s.i = c repeat 0
+ s(i..n)
+ leftTrim(s, cc) ==
+ n := maxIndex s
+ for i in mn .. n while member?(s.i,cc) repeat 0
+ s(i..n)
+
+ rightTrim(s, c) ==
+ for j in maxIndex s .. mn by -1 while s.j = c repeat 0
+ s(minIndex(s)..j)
+ rightTrim(s, cc) ==
+ for j in maxIndex s .. mn by -1 while member?(s.j, cc) repeat 0
+ s(minIndex(s)..j)
+
+ concat l ==
+ t := new(+/[#s for s in l], space$C)
+ i := mn
+ for s in l repeat
+ copyInto_!(t, s, i)
+ i := i + #s
+ t
+
+ copyInto_!(y, x, s) ==
+ m := #x
+ n := #y
+ s := s - mn
+ s < 0 or s+m > n => error "index out of range"
+ RPLACSTR(y, s, m, x, 0, m)$Lisp
+ y
+
+ elt(s:%, i:I) ==
+ i < mn or i > maxIndex(s) => error "index out of range"
+ Qelt(s, i - mn)
+
+ elt(s:%, sg:U) ==
+ l := lo(sg) - mn
+ h := if hasHi sg then hi(sg) - mn else maxIndex s - mn
+ l < 0 or h >= #s => error "index out of bound"
+ SUBSTRING(s, l, max(0, h-l+1))$Lisp
+
+ hash(s:$):Integer ==
+ n:I := Qsize s
+ zero? n => 0
+-- one? n => ord(s.mn)
+ (n = 1) => ord(s.mn)
+ ord(s.mn) * ord s(mn+n-1) * ord s(mn + n quo 2)
+
+ match(pattern,target,wildcard) == stringMatch(pattern,target,CHARACTER(wildcard)$Lisp)$Lisp
+
+@
+
+Up to [[patch--40]] this read
+
+\begin{verbatim}
+ match(pattern,target,wildcard) == stringMatch(pattern,target,wildcard)$Lisp
+\end{verbatim}
+
+which did not work (Issue~\#97), since [[wildcard]] is an Axiom-[[Character]],
+not a Lisp-[[Character]]. The operation [[CHARACTER]] from [[Lisp]] performs
+the coercion.
+
+<<domain ISTRING IndexedString>>=
+ match?(pattern, target, dontcare) ==
+ n := maxIndex pattern
+ p := position(dontcare, pattern, m := minIndex pattern)::N
+ p = m-1 => pattern = target
+ (p ^= m) and not prefix?(pattern(m..p-1), target) => false
+ i := p -- index into target
+ q := position(dontcare, pattern, p + 1)::N
+ while q ^= m-1 repeat
+ s := pattern(p+1..q-1)
+ i := position(s, target, i)::N
+ i = m-1 => return false
+ i := i + #s
+ p := q
+ q := position(dontcare, pattern, q + 1)::N
+ (p ^= n) and not suffix?(pattern(p+1..n), target) => false
+ true
+
+@
+\section{ISTRING.lsp BOOTSTRAP}
+{\bf ISTRING} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf ISTRING} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf ISTRING.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<ISTRING.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(PUT (QUOTE |ISTRING;new;NniC$;1|) (QUOTE |SPADreplace|) (QUOTE |MAKE-FULL-CVEC|))
+
+(DEFUN |ISTRING;new;NniC$;1| (|n| |c| |$|) (|MAKE-FULL-CVEC| |n| |c|))
+
+(PUT (QUOTE |ISTRING;empty;$;2|) (QUOTE |SPADreplace|) (QUOTE (XLAM NIL (|MAKE-FULL-CVEC| 0))))
+
+(DEFUN |ISTRING;empty;$;2| (|$|) (|MAKE-FULL-CVEC| 0))
+
+(DEFUN |ISTRING;empty?;$B;3| (|s| |$|) (EQL (QCSIZE |s|) 0))
+
+(PUT (QUOTE |ISTRING;#;$Nni;4|) (QUOTE |SPADreplace|) (QUOTE QCSIZE))
+
+(DEFUN |ISTRING;#;$Nni;4| (|s| |$|) (QCSIZE |s|))
+
+(PUT (QUOTE |ISTRING;=;2$B;5|) (QUOTE |SPADreplace|) (QUOTE EQUAL))
+
+(DEFUN |ISTRING;=;2$B;5| (|s| |t| |$|) (EQUAL |s| |t|))
+
+(PUT (QUOTE |ISTRING;<;2$B;6|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|s| |t|) (CGREATERP |t| |s|))))
+
+(DEFUN |ISTRING;<;2$B;6| (|s| |t| |$|) (CGREATERP |t| |s|))
+
+(PUT (QUOTE |ISTRING;concat;3$;7|) (QUOTE |SPADreplace|) (QUOTE STRCONC))
+
+(DEFUN |ISTRING;concat;3$;7| (|s| |t| |$|) (STRCONC |s| |t|))
+
+(PUT (QUOTE |ISTRING;copy;2$;8|) (QUOTE |SPADreplace|) (QUOTE |COPY-SEQ|))
+
+(DEFUN |ISTRING;copy;2$;8| (|s| |$|) (|COPY-SEQ| |s|))
+
+(DEFUN |ISTRING;insert;2$I$;9| (|s| |t| |i| |$|) (SPADCALL (SPADCALL (SPADCALL |s| (SPADCALL (QREFELT |$| 6) (|-| |i| 1) (QREFELT |$| 20)) (QREFELT |$| 21)) |t| (QREFELT |$| 16)) (SPADCALL |s| (SPADCALL |i| (QREFELT |$| 22)) (QREFELT |$| 21)) (QREFELT |$| 16)))
+
+(DEFUN |ISTRING;coerce;$Of;10| (|s| |$|) (SPADCALL |s| (QREFELT |$| 26)))
+
+(DEFUN |ISTRING;minIndex;$I;11| (|s| |$|) (QREFELT |$| 6))
+
+(DEFUN |ISTRING;upperCase!;2$;12| (|s| |$|) (SPADCALL (ELT |$| 31) |s| (QREFELT |$| 33)))
+
+(DEFUN |ISTRING;lowerCase!;2$;13| (|s| |$|) (SPADCALL (ELT |$| 36) |s| (QREFELT |$| 33)))
+
+(DEFUN |ISTRING;latex;$S;14| (|s| |$|) (STRCONC "\\mbox{``" (STRCONC |s| "''}")))
+
+(DEFUN |ISTRING;replace;$Us2$;15| (|s| |sg| |t| |$|) (PROG (|l| |m| |n| |h| #1=#:G91425 |r| #2=#:G91433 #3=#:G91432 |i| #4=#:G91431 |k|) (RETURN (SEQ (LETT |l| (|-| (SPADCALL |sg| (QREFELT |$| 39)) (QREFELT |$| 6)) |ISTRING;replace;$Us2$;15|) (LETT |m| (SPADCALL |s| (QREFELT |$| 13)) |ISTRING;replace;$Us2$;15|) (LETT |n| (SPADCALL |t| (QREFELT |$| 13)) |ISTRING;replace;$Us2$;15|) (LETT |h| (COND ((SPADCALL |sg| (QREFELT |$| 40)) (|-| (SPADCALL |sg| (QREFELT |$| 41)) (QREFELT |$| 6))) ((QUOTE T) (|-| (SPADCALL |s| (QREFELT |$| 42)) (QREFELT |$| 6)))) |ISTRING;replace;$Us2$;15|) (COND ((OR (OR (|<| |l| 0) (NULL (|<| |h| |m|))) (|<| |h| (|-| |l| 1))) (EXIT (|error| "index out of range")))) (LETT |r| (SPADCALL (PROG1 (LETT #1# (|+| (|-| |m| (|+| (|-| |h| |l|) 1)) |n|) |ISTRING;replace;$Us2$;15|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (SPADCALL (QREFELT |$| 43)) (QREFELT |$| 9)) |ISTRING;replace;$Us2$;15|) (SEQ (LETT |i| 0 |ISTRING;replace;$Us2$;15|) (LETT #2# (|-| |l| 1) |ISTRING;replace;$Us2$;15|) (LETT |k| 0 |ISTRING;replace;$Us2$;15|) G190 (COND ((QSGREATERP |i| #2#) (GO G191))) (SEQ (EXIT (QESET |r| |k| (QENUM |s| |i|)))) (LETT |k| (PROG1 (QSADD1 |k|) (LETT |i| (QSADD1 |i|) |ISTRING;replace;$Us2$;15|)) |ISTRING;replace;$Us2$;15|) (GO G190) G191 (EXIT NIL)) (SEQ (LETT |i| 0 |ISTRING;replace;$Us2$;15|) (LETT #3# (|-| |n| 1) |ISTRING;replace;$Us2$;15|) (LETT |k| |k| |ISTRING;replace;$Us2$;15|) G190 (COND ((QSGREATERP |i| #3#) (GO G191))) (SEQ (EXIT (QESET |r| |k| (QENUM |t| |i|)))) (LETT |k| (PROG1 (|+| |k| 1) (LETT |i| (QSADD1 |i|) |ISTRING;replace;$Us2$;15|)) |ISTRING;replace;$Us2$;15|) (GO G190) G191 (EXIT NIL)) (SEQ (LETT |i| (|+| |h| 1) |ISTRING;replace;$Us2$;15|) (LETT #4# (|-| |m| 1) |ISTRING;replace;$Us2$;15|) (LETT |k| |k| |ISTRING;replace;$Us2$;15|) G190 (COND ((|>| |i| #4#) (GO G191))) (SEQ (EXIT (QESET |r| |k| (QENUM |s| |i|)))) (LETT |k| (PROG1 (|+| |k| 1) (LETT |i| (|+| |i| 1) |ISTRING;replace;$Us2$;15|)) |ISTRING;replace;$Us2$;15|) (GO G190) G191 (EXIT NIL)) (EXIT |r|)))))
+
+(DEFUN |ISTRING;setelt;$I2C;16| (|s| |i| |c| |$|) (SEQ (COND ((OR (|<| |i| (QREFELT |$| 6)) (|<| (SPADCALL |s| (QREFELT |$| 42)) |i|)) (|error| "index out of range")) ((QUOTE T) (SEQ (QESET |s| (|-| |i| (QREFELT |$| 6)) |c|) (EXIT |c|))))))
+
+(DEFUN |ISTRING;substring?;2$IB;17| (|part| |whole| |startpos| |$|) (PROG (|np| |nw| |iw| |ip| #1=#:G91443 #2=#:G91442 #3=#:G91438) (RETURN (SEQ (EXIT (SEQ (LETT |np| (QCSIZE |part|) |ISTRING;substring?;2$IB;17|) (LETT |nw| (QCSIZE |whole|) |ISTRING;substring?;2$IB;17|) (LETT |startpos| (|-| |startpos| (QREFELT |$| 6)) |ISTRING;substring?;2$IB;17|) (EXIT (COND ((|<| |startpos| 0) (|error| "index out of bounds")) ((|<| (|-| |nw| |startpos|) |np|) (QUOTE NIL)) ((QUOTE T) (SEQ (SEQ (EXIT (SEQ (LETT |iw| |startpos| |ISTRING;substring?;2$IB;17|) (LETT |ip| 0 |ISTRING;substring?;2$IB;17|) (LETT #1# (|-| |np| 1) |ISTRING;substring?;2$IB;17|) G190 (COND ((QSGREATERP |ip| #1#) (GO G191))) (SEQ (EXIT (COND ((NULL (EQL (QENUM |part| |ip|) (QENUM |whole| |iw|))) (PROGN (LETT #3# (PROGN (LETT #2# (QUOTE NIL) |ISTRING;substring?;2$IB;17|) (GO #2#)) |ISTRING;substring?;2$IB;17|) (GO #3#)))))) (LETT |ip| (PROG1 (QSADD1 |ip|) (LETT |iw| (|+| |iw| 1) |ISTRING;substring?;2$IB;17|)) |ISTRING;substring?;2$IB;17|) (GO G190) G191 (EXIT NIL))) #3# (EXIT #3#)) (EXIT (QUOTE T)))))))) #2# (EXIT #2#)))))
+
+(DEFUN |ISTRING;position;2$2I;18| (|s| |t| |startpos| |$|) (PROG (|r|) (RETURN (SEQ (LETT |startpos| (|-| |startpos| (QREFELT |$| 6)) |ISTRING;position;2$2I;18|) (EXIT (COND ((|<| |startpos| 0) (|error| "index out of bounds")) ((NULL (|<| |startpos| (QCSIZE |t|))) (|-| (QREFELT |$| 6) 1)) ((QUOTE T) (SEQ (LETT |r| (STRPOS |s| |t| |startpos| NIL) |ISTRING;position;2$2I;18|) (EXIT (COND ((EQ |r| NIL) (|-| (QREFELT |$| 6) 1)) ((QUOTE T) (|+| |r| (QREFELT |$| 6)))))))))))))
+
+(DEFUN |ISTRING;position;C$2I;19| (|c| |t| |startpos| |$|) (PROG (|r| #1=#:G91454 #2=#:G91453) (RETURN (SEQ (EXIT (SEQ (LETT |startpos| (|-| |startpos| (QREFELT |$| 6)) |ISTRING;position;C$2I;19|) (EXIT (COND ((|<| |startpos| 0) (|error| "index out of bounds")) ((NULL (|<| |startpos| (QCSIZE |t|))) (|-| (QREFELT |$| 6) 1)) ((QUOTE T) (SEQ (SEQ (LETT |r| |startpos| |ISTRING;position;C$2I;19|) (LETT #1# (QSDIFFERENCE (QCSIZE |t|) 1) |ISTRING;position;C$2I;19|) G190 (COND ((|>| |r| #1#) (GO G191))) (SEQ (EXIT (COND ((EQL (QENUM |t| |r|) |c|) (PROGN (LETT #2# (|+| |r| (QREFELT |$| 6)) |ISTRING;position;C$2I;19|) (GO #2#)))))) (LETT |r| (|+| |r| 1) |ISTRING;position;C$2I;19|) (GO G190) G191 (EXIT NIL)) (EXIT (|-| (QREFELT |$| 6) 1)))))))) #2# (EXIT #2#)))))
+
+(DEFUN |ISTRING;position;Cc$2I;20| (|cc| |t| |startpos| |$|) (PROG (|r| #1=#:G91461 #2=#:G91460) (RETURN (SEQ (EXIT (SEQ (LETT |startpos| (|-| |startpos| (QREFELT |$| 6)) |ISTRING;position;Cc$2I;20|) (EXIT (COND ((|<| |startpos| 0) (|error| "index out of bounds")) ((NULL (|<| |startpos| (QCSIZE |t|))) (|-| (QREFELT |$| 6) 1)) ((QUOTE T) (SEQ (SEQ (LETT |r| |startpos| |ISTRING;position;Cc$2I;20|) (LETT #1# (QSDIFFERENCE (QCSIZE |t|) 1) |ISTRING;position;Cc$2I;20|) G190 (COND ((|>| |r| #1#) (GO G191))) (SEQ (EXIT (COND ((SPADCALL (QENUM |t| |r|) |cc| (QREFELT |$| 49)) (PROGN (LETT #2# (|+| |r| (QREFELT |$| 6)) |ISTRING;position;Cc$2I;20|) (GO #2#)))))) (LETT |r| (|+| |r| 1) |ISTRING;position;Cc$2I;20|) (GO G190) G191 (EXIT NIL)) (EXIT (|-| (QREFELT |$| 6) 1)))))))) #2# (EXIT #2#)))))
+
+(DEFUN |ISTRING;suffix?;2$B;21| (|s| |t| |$|) (PROG (|n| |m|) (RETURN (SEQ (LETT |n| (SPADCALL |t| (QREFELT |$| 42)) |ISTRING;suffix?;2$B;21|) (LETT |m| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;suffix?;2$B;21|) (EXIT (COND ((|<| |n| |m|) (QUOTE NIL)) ((QUOTE T) (SPADCALL |s| |t| (|-| (|+| (QREFELT |$| 6) |n|) |m|) (QREFELT |$| 46)))))))))
+
+(DEFUN |ISTRING;split;$CL;22| (|s| |c| |$|) (PROG (|n| |j| |i| |l|) (RETURN (SEQ (LETT |n| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;split;$CL;22|) (SEQ (LETT |i| (QREFELT |$| 6) |ISTRING;split;$CL;22|) G190 (COND ((OR (|>| |i| |n|) (NULL (SPADCALL (SPADCALL |s| |i| (QREFELT |$| 52)) |c| (QREFELT |$| 53)))) (GO G191))) (SEQ (EXIT 0)) (LETT |i| (|+| |i| 1) |ISTRING;split;$CL;22|) (GO G190) G191 (EXIT NIL)) (LETT |l| (SPADCALL (QREFELT |$| 55)) |ISTRING;split;$CL;22|) (SEQ G190 (COND ((NULL (COND ((|<| |n| |i|) (QUOTE NIL)) ((QUOTE T) (SEQ (LETT |j| (SPADCALL |c| |s| |i| (QREFELT |$| 48)) |ISTRING;split;$CL;22|) (EXIT (COND ((|<| |j| (QREFELT |$| 6)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))))))) (GO G191))) (SEQ (LETT |l| (SPADCALL (SPADCALL |s| (SPADCALL |i| (|-| |j| 1) (QREFELT |$| 20)) (QREFELT |$| 21)) |l| (QREFELT |$| 56)) |ISTRING;split;$CL;22|) (EXIT (SEQ (LETT |i| |j| |ISTRING;split;$CL;22|) G190 (COND ((OR (|>| |i| |n|) (NULL (SPADCALL (SPADCALL |s| |i| (QREFELT |$| 52)) |c| (QREFELT |$| 53)))) (GO G191))) (SEQ (EXIT 0)) (LETT |i| (|+| |i| 1) |ISTRING;split;$CL;22|) (GO G190) G191 (EXIT NIL)))) NIL (GO G190) G191 (EXIT NIL)) (COND ((NULL (|<| |n| |i|)) (LETT |l| (SPADCALL (SPADCALL |s| (SPADCALL |i| |n| (QREFELT |$| 20)) (QREFELT |$| 21)) |l| (QREFELT |$| 56)) |ISTRING;split;$CL;22|))) (EXIT (SPADCALL |l| (QREFELT |$| 57)))))))
+
+(DEFUN |ISTRING;split;$CcL;23| (|s| |cc| |$|) (PROG (|n| |j| |i| |l|) (RETURN (SEQ (LETT |n| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;split;$CcL;23|) (SEQ (LETT |i| (QREFELT |$| 6) |ISTRING;split;$CcL;23|) G190 (COND ((OR (|>| |i| |n|) (NULL (SPADCALL (SPADCALL |s| |i| (QREFELT |$| 52)) |cc| (QREFELT |$| 49)))) (GO G191))) (SEQ (EXIT 0)) (LETT |i| (|+| |i| 1) |ISTRING;split;$CcL;23|) (GO G190) G191 (EXIT NIL)) (LETT |l| (SPADCALL (QREFELT |$| 55)) |ISTRING;split;$CcL;23|) (SEQ G190 (COND ((NULL (COND ((|<| |n| |i|) (QUOTE NIL)) ((QUOTE T) (SEQ (LETT |j| (SPADCALL |cc| |s| |i| (QREFELT |$| 50)) |ISTRING;split;$CcL;23|) (EXIT (COND ((|<| |j| (QREFELT |$| 6)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))))))) (GO G191))) (SEQ (LETT |l| (SPADCALL (SPADCALL |s| (SPADCALL |i| (|-| |j| 1) (QREFELT |$| 20)) (QREFELT |$| 21)) |l| (QREFELT |$| 56)) |ISTRING;split;$CcL;23|) (EXIT (SEQ (LETT |i| |j| |ISTRING;split;$CcL;23|) G190 (COND ((OR (|>| |i| |n|) (NULL (SPADCALL (SPADCALL |s| |i| (QREFELT |$| 52)) |cc| (QREFELT |$| 49)))) (GO G191))) (SEQ (EXIT 0)) (LETT |i| (|+| |i| 1) |ISTRING;split;$CcL;23|) (GO G190) G191 (EXIT NIL)))) NIL (GO G190) G191 (EXIT NIL)) (COND ((NULL (|<| |n| |i|)) (LETT |l| (SPADCALL (SPADCALL |s| (SPADCALL |i| |n| (QREFELT |$| 20)) (QREFELT |$| 21)) |l| (QREFELT |$| 56)) |ISTRING;split;$CcL;23|))) (EXIT (SPADCALL |l| (QREFELT |$| 57)))))))
+
+(DEFUN |ISTRING;leftTrim;$C$;24| (|s| |c| |$|) (PROG (|n| |i|) (RETURN (SEQ (LETT |n| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;leftTrim;$C$;24|) (SEQ (LETT |i| (QREFELT |$| 6) |ISTRING;leftTrim;$C$;24|) G190 (COND ((OR (|>| |i| |n|) (NULL (SPADCALL (SPADCALL |s| |i| (QREFELT |$| 52)) |c| (QREFELT |$| 53)))) (GO G191))) (SEQ (EXIT 0)) (LETT |i| (|+| |i| 1) |ISTRING;leftTrim;$C$;24|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |s| (SPADCALL |i| |n| (QREFELT |$| 20)) (QREFELT |$| 21)))))))
+
+(DEFUN |ISTRING;leftTrim;$Cc$;25| (|s| |cc| |$|) (PROG (|n| |i|) (RETURN (SEQ (LETT |n| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;leftTrim;$Cc$;25|) (SEQ (LETT |i| (QREFELT |$| 6) |ISTRING;leftTrim;$Cc$;25|) G190 (COND ((OR (|>| |i| |n|) (NULL (SPADCALL (SPADCALL |s| |i| (QREFELT |$| 52)) |cc| (QREFELT |$| 49)))) (GO G191))) (SEQ (EXIT 0)) (LETT |i| (|+| |i| 1) |ISTRING;leftTrim;$Cc$;25|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |s| (SPADCALL |i| |n| (QREFELT |$| 20)) (QREFELT |$| 21)))))))
+
+(DEFUN |ISTRING;rightTrim;$C$;26| (|s| |c| |$|) (PROG (|j| #1=#:G91487) (RETURN (SEQ (SEQ (LETT |j| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;rightTrim;$C$;26|) (LETT #1# (QREFELT |$| 6) |ISTRING;rightTrim;$C$;26|) G190 (COND ((OR (|<| |j| #1#) (NULL (SPADCALL (SPADCALL |s| |j| (QREFELT |$| 52)) |c| (QREFELT |$| 53)))) (GO G191))) (SEQ (EXIT 0)) (LETT |j| (|+| |j| -1) |ISTRING;rightTrim;$C$;26|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |s| (SPADCALL (SPADCALL |s| (QREFELT |$| 28)) |j| (QREFELT |$| 20)) (QREFELT |$| 21)))))))
+
+(DEFUN |ISTRING;rightTrim;$Cc$;27| (|s| |cc| |$|) (PROG (|j| #1=#:G91491) (RETURN (SEQ (SEQ (LETT |j| (SPADCALL |s| (QREFELT |$| 42)) |ISTRING;rightTrim;$Cc$;27|) (LETT #1# (QREFELT |$| 6) |ISTRING;rightTrim;$Cc$;27|) G190 (COND ((OR (|<| |j| #1#) (NULL (SPADCALL (SPADCALL |s| |j| (QREFELT |$| 52)) |cc| (QREFELT |$| 49)))) (GO G191))) (SEQ (EXIT 0)) (LETT |j| (|+| |j| -1) |ISTRING;rightTrim;$Cc$;27|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL |s| (SPADCALL (SPADCALL |s| (QREFELT |$| 28)) |j| (QREFELT |$| 20)) (QREFELT |$| 21)))))))
+
+(DEFUN |ISTRING;concat;L$;28| (|l| |$|) (PROG (#1=#:G91500 #2=#:G91494 #3=#:G91492 #4=#:G91493 |t| |s| #5=#:G91499 |i|) (RETURN (SEQ (LETT |t| (SPADCALL (PROGN (LETT #4# NIL |ISTRING;concat;L$;28|) (SEQ (LETT |s| NIL |ISTRING;concat;L$;28|) (LETT #1# |l| |ISTRING;concat;L$;28|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |s| (CAR #1#) |ISTRING;concat;L$;28|) NIL)) (GO G191))) (SEQ (EXIT (PROGN (LETT #2# (SPADCALL |s| (QREFELT |$| 13)) |ISTRING;concat;L$;28|) (COND (#4# (LETT #3# (|+| #3# #2#) |ISTRING;concat;L$;28|)) ((QUOTE T) (PROGN (LETT #3# #2# |ISTRING;concat;L$;28|) (LETT #4# (QUOTE T) |ISTRING;concat;L$;28|))))))) (LETT #1# (CDR #1#) |ISTRING;concat;L$;28|) (GO G190) G191 (EXIT NIL)) (COND (#4# #3#) ((QUOTE T) 0))) (SPADCALL (QREFELT |$| 43)) (QREFELT |$| 9)) |ISTRING;concat;L$;28|) (LETT |i| (QREFELT |$| 6) |ISTRING;concat;L$;28|) (SEQ (LETT |s| NIL |ISTRING;concat;L$;28|) (LETT #5# |l| |ISTRING;concat;L$;28|) G190 (COND ((OR (ATOM #5#) (PROGN (LETT |s| (CAR #5#) |ISTRING;concat;L$;28|) NIL)) (GO G191))) (SEQ (SPADCALL |t| |s| |i| (QREFELT |$| 65)) (EXIT (LETT |i| (|+| |i| (SPADCALL |s| (QREFELT |$| 13))) |ISTRING;concat;L$;28|))) (LETT #5# (CDR #5#) |ISTRING;concat;L$;28|) (GO G190) G191 (EXIT NIL)) (EXIT |t|)))))
+
+(DEFUN |ISTRING;copyInto!;2$I$;29| (|y| |x| |s| |$|) (PROG (|m| |n|) (RETURN (SEQ (LETT |m| (SPADCALL |x| (QREFELT |$| 13)) |ISTRING;copyInto!;2$I$;29|) (LETT |n| (SPADCALL |y| (QREFELT |$| 13)) |ISTRING;copyInto!;2$I$;29|) (LETT |s| (|-| |s| (QREFELT |$| 6)) |ISTRING;copyInto!;2$I$;29|) (COND ((OR (|<| |s| 0) (|<| |n| (|+| |s| |m|))) (EXIT (|error| "index out of range")))) (RPLACSTR |y| |s| |m| |x| 0 |m|) (EXIT |y|)))))
+
+(DEFUN |ISTRING;elt;$IC;30| (|s| |i| |$|) (COND ((OR (|<| |i| (QREFELT |$| 6)) (|<| (SPADCALL |s| (QREFELT |$| 42)) |i|)) (|error| "index out of range")) ((QUOTE T) (QENUM |s| (|-| |i| (QREFELT |$| 6))))))
+
+(DEFUN |ISTRING;elt;$Us$;31| (|s| |sg| |$|) (PROG (|l| |h|) (RETURN (SEQ (LETT |l| (|-| (SPADCALL |sg| (QREFELT |$| 39)) (QREFELT |$| 6)) |ISTRING;elt;$Us$;31|) (LETT |h| (COND ((SPADCALL |sg| (QREFELT |$| 40)) (|-| (SPADCALL |sg| (QREFELT |$| 41)) (QREFELT |$| 6))) ((QUOTE T) (|-| (SPADCALL |s| (QREFELT |$| 42)) (QREFELT |$| 6)))) |ISTRING;elt;$Us$;31|) (COND ((OR (|<| |l| 0) (NULL (|<| |h| (SPADCALL |s| (QREFELT |$| 13))))) (EXIT (|error| "index out of bound")))) (EXIT (SUBSTRING |s| |l| (MAX 0 (|+| (|-| |h| |l|) 1))))))))
+
+(DEFUN |ISTRING;hash;$I;32| (|s| |$|) (PROG (|n|) (RETURN (SEQ (LETT |n| (QCSIZE |s|) |ISTRING;hash;$I;32|) (EXIT (COND ((ZEROP |n|) 0) ((EQL |n| 1) (SPADCALL (SPADCALL |s| (QREFELT |$| 6) (QREFELT |$| 52)) (QREFELT |$| 67))) ((QUOTE T) (|*| (|*| (SPADCALL (SPADCALL |s| (QREFELT |$| 6) (QREFELT |$| 52)) (QREFELT |$| 67)) (SPADCALL (SPADCALL |s| (|-| (|+| (QREFELT |$| 6) |n|) 1) (QREFELT |$| 52)) (QREFELT |$| 67))) (SPADCALL (SPADCALL |s| (|+| (QREFELT |$| 6) (QUOTIENT2 |n| 2)) (QREFELT |$| 52)) (QREFELT |$| 67))))))))))
+
+(PUT (QUOTE |ISTRING;match;2$CNni;33|) (QUOTE |SPADreplace|) (QUOTE |stringMatch|))
+
+(DEFUN |ISTRING;match;2$CNni;33| (|pattern| |target| |wildcard| |$|) (|stringMatch| |pattern| |target| |wildcard|))
+
+(DEFUN |ISTRING;match?;2$CB;34| (|pattern| |target| |dontcare| |$|) (PROG (|n| |m| #1=#:G91514 #2=#:G91516 |s| #3=#:G91518 #4=#:G91526 |i| |p| #5=#:G91519 |q|) (RETURN (SEQ (EXIT (SEQ (LETT |n| (SPADCALL |pattern| (QREFELT |$| 42)) |ISTRING;match?;2$CB;34|) (LETT |p| (PROG1 (LETT #1# (SPADCALL |dontcare| |pattern| (LETT |m| (SPADCALL |pattern| (QREFELT |$| 28)) |ISTRING;match?;2$CB;34|) (QREFELT |$| 48)) |ISTRING;match?;2$CB;34|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) |ISTRING;match?;2$CB;34|) (EXIT (COND ((EQL |p| (|-| |m| 1)) (SPADCALL |pattern| |target| (QREFELT |$| 14))) ((QUOTE T) (SEQ (COND ((NULL (EQL |p| |m|)) (COND ((NULL (SPADCALL (SPADCALL |pattern| (SPADCALL |m| (|-| |p| 1) (QREFELT |$| 20)) (QREFELT |$| 21)) |target| (QREFELT |$| 70))) (EXIT (QUOTE NIL)))))) (LETT |i| |p| |ISTRING;match?;2$CB;34|) (LETT |q| (PROG1 (LETT #2# (SPADCALL |dontcare| |pattern| (|+| |p| 1) (QREFELT |$| 48)) |ISTRING;match?;2$CB;34|) (|check-subtype| (|>=| #2# 0) (QUOTE (|NonNegativeInteger|)) #2#)) |ISTRING;match?;2$CB;34|) (SEQ G190 (COND ((NULL (COND ((EQL |q| (|-| |m| 1)) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |s| (SPADCALL |pattern| (SPADCALL (|+| |p| 1) (|-| |q| 1) (QREFELT |$| 20)) (QREFELT |$| 21)) |ISTRING;match?;2$CB;34|) (LETT |i| (PROG1 (LETT #3# (SPADCALL |s| |target| |i| (QREFELT |$| 47)) |ISTRING;match?;2$CB;34|) (|check-subtype| (|>=| #3# 0) (QUOTE (|NonNegativeInteger|)) #3#)) |ISTRING;match?;2$CB;34|) (EXIT (COND ((EQL |i| (|-| |m| 1)) (PROGN (LETT #4# (QUOTE NIL) |ISTRING;match?;2$CB;34|) (GO #4#))) ((QUOTE T) (SEQ (LETT |i| (|+| |i| (SPADCALL |s| (QREFELT |$| 13))) |ISTRING;match?;2$CB;34|) (LETT |p| |q| |ISTRING;match?;2$CB;34|) (EXIT (LETT |q| (PROG1 (LETT #5# (SPADCALL |dontcare| |pattern| (|+| |q| 1) (QREFELT |$| 48)) |ISTRING;match?;2$CB;34|) (|check-subtype| (|>=| #5# 0) (QUOTE (|NonNegativeInteger|)) #5#)) |ISTRING;match?;2$CB;34|))))))) NIL (GO G190) G191 (EXIT NIL)) (COND ((NULL (EQL |p| |n|)) (COND ((NULL (SPADCALL (SPADCALL |pattern| (SPADCALL (|+| |p| 1) |n| (QREFELT |$| 20)) (QREFELT |$| 21)) |target| (QREFELT |$| 51))) (EXIT (QUOTE NIL)))))) (EXIT (QUOTE T)))))))) #4# (EXIT #4#)))))
+
+(DEFUN |IndexedString| (#1=#:G91535) (PROG NIL (RETURN (PROG (#2=#:G91536) (RETURN (COND ((LETT #2# (|lassocShiftWithFunction| (LIST (|devaluate| #1#)) (HGET |$ConstructorCache| (QUOTE |IndexedString|)) (QUOTE |domainEqualList|)) |IndexedString|) (|CDRwithIncrement| #2#)) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (|IndexedString;| #1#) (LETT #2# T |IndexedString|)) (COND ((NOT #2#) (HREM |$ConstructorCache| (QUOTE |IndexedString|))))))))))))
+
+(DEFUN |IndexedString;| (|#1|) (PROG (|DV$1| |dv$| |$| #1=#:G91534 #2=#:G91533 |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #3=(|IndexedString|)) (LETT |dv$| (LIST (QUOTE |IndexedString|) |DV$1|) . #3#) (LETT |$| (GETREFV 83) . #3#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| (|Character|) (QUOTE (|SetCategory|))) (|HasCategory| (|Character|) (QUOTE (|ConvertibleTo| (|InputForm|)))) (LETT #1# (|HasCategory| (|Character|) (QUOTE (|OrderedSet|))) . #3#) (OR #1# (|HasCategory| (|Character|) (QUOTE (|SetCategory|)))) (|HasCategory| (|Integer|) (QUOTE (|OrderedSet|))) (LETT #2# (AND (|HasCategory| (|Character|) (QUOTE (|Evalable| (|Character|)))) (|HasCategory| (|Character|) (QUOTE (|SetCategory|)))) . #3#) (OR (AND (|HasCategory| (|Character|) (QUOTE (|Evalable| (|Character|)))) #1#) #2#))) . #3#)) (|haddProp| |$ConstructorCache| (QUOTE |IndexedString|) (LIST |DV$1|) (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) |$|))))
+
+(MAKEPROP (QUOTE |IndexedString|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|local| |#1|) (|NonNegativeInteger|) (|Character|) |ISTRING;new;NniC$;1| |ISTRING;empty;$;2| (|Boolean|) |ISTRING;empty?;$B;3| |ISTRING;#;$Nni;4| |ISTRING;=;2$B;5| |ISTRING;<;2$B;6| |ISTRING;concat;3$;7| |ISTRING;copy;2$;8| (|Integer|) (|UniversalSegment| 18) (0 . SEGMENT) |ISTRING;elt;$Us$;31| (6 . SEGMENT) |ISTRING;insert;2$I$;9| (|String|) (|OutputForm|) (11 . |outputForm|) |ISTRING;coerce;$Of;10| |ISTRING;minIndex;$I;11| (|CharacterClass|) (16 . |upperCase|) (20 . |upperCase|) (|Mapping| 8 8) (25 . |map!|) |ISTRING;upperCase!;2$;12| (31 . |lowerCase|) (35 . |lowerCase|) |ISTRING;lowerCase!;2$;13| |ISTRING;latex;$S;14| (40 . |lo|) (45 . |hasHi|) (50 . |hi|) (55 . |maxIndex|) (60 . |space|) |ISTRING;replace;$Us2$;15| |ISTRING;setelt;$I2C;16| |ISTRING;substring?;2$IB;17| |ISTRING;position;2$2I;18| |ISTRING;position;C$2I;19| (64 . |member?|) |ISTRING;position;Cc$2I;20| |ISTRING;suffix?;2$B;21| |ISTRING;elt;$IC;30| (70 . |=|) (|List| |$$|) (76 . |empty|) (80 . |concat|) (86 . |reverse!|) (|List| |$|) |ISTRING;split;$CL;22| |ISTRING;split;$CcL;23| |ISTRING;leftTrim;$C$;24| |ISTRING;leftTrim;$Cc$;25| |ISTRING;rightTrim;$C$;26| |ISTRING;rightTrim;$Cc$;27| |ISTRING;copyInto!;2$I$;29| |ISTRING;concat;L$;28| (91 . |ord|) |ISTRING;hash;$I;32| |ISTRING;match;2$CNni;33| (96 . |prefix?|) |ISTRING;match?;2$CB;34| (|List| 8) (|List| 74) (|Equation| 8) (|Mapping| 8 8 8) (|InputForm|) (|SingleInteger|) (|Mapping| 11 8) (|Mapping| 11 8 8) (|Void|) (|Union| 8 (QUOTE "failed")) (|List| 18))) (QUOTE #(|~=| 102 |upperCase!| 108 |upperCase| 113 |trim| 118 |swap!| 130 |suffix?| 137 |substring?| 143 |split| 150 |sorted?| 162 |sort!| 173 |sort| 184 |size?| 195 |setelt| 201 |select| 215 |sample| 221 |rightTrim| 225 |reverse!| 237 |reverse| 242 |replace| 247 |removeDuplicates| 254 |remove| 259 |reduce| 271 |qsetelt!| 292 |qelt| 299 |prefix?| 305 |position| 311 |parts| 344 |new| 349 |more?| 355 |minIndex| 361 |min| 366 |merge| 372 |members| 385 |member?| 390 |maxIndex| 396 |max| 401 |match?| 407 |match| 414 |map!| 421 |map| 427 |lowerCase!| 440 |lowerCase| 445 |less?| 450 |leftTrim| 456 |latex| 468 |insert| 473 |indices| 487 |index?| 492 |hash| 498 |first| 508 |find| 513 |fill!| 519 |every?| 525 |eval| 531 |eq?| 557 |entry?| 563 |entries| 569 |empty?| 574 |empty| 579 |elt| 583 |delete| 608 |count| 620 |copyInto!| 632 |copy| 639 |convert| 644 |construct| 649 |concat| 654 |coerce| 677 |any?| 687 |>=| 693 |>| 699 |=| 705 |<=| 711 |<| 717 |#| 723)) (QUOTE ((|shallowlyMutable| . 0) (|finiteAggregate| . 0))) (CONS (|makeByteWordVec2| 7 (QUOTE (0 0 0 0 0 0 0 3 0 0 7 4 0 0 7 1 2 4))) (CONS (QUOTE #(|StringAggregate&| |OneDimensionalArrayAggregate&| |FiniteLinearAggregate&| |LinearAggregate&| |IndexedAggregate&| |Collection&| |HomogeneousAggregate&| |OrderedSet&| |Aggregate&| |EltableAggregate&| |Evalable&| |SetCategory&| NIL NIL |InnerEvalable&| NIL NIL |BasicType&|)) (CONS (QUOTE #((|StringAggregate|) (|OneDimensionalArrayAggregate| 8) (|FiniteLinearAggregate| 8) (|LinearAggregate| 8) (|IndexedAggregate| 18 8) (|Collection| 8) (|HomogeneousAggregate| 8) (|OrderedSet|) (|Aggregate|) (|EltableAggregate| 18 8) (|Evalable| 8) (|SetCategory|) (|Type|) (|Eltable| 18 8) (|InnerEvalable| 8 8) (|CoercibleTo| 25) (|ConvertibleTo| 76) (|BasicType|))) (|makeByteWordVec2| 82 (QUOTE (2 19 0 18 18 20 1 19 0 18 22 1 25 0 24 26 0 29 0 30 1 8 0 0 31 2 0 0 32 0 33 0 29 0 35 1 8 0 0 36 1 19 18 0 39 1 19 11 0 40 1 19 18 0 41 1 0 18 0 42 0 8 0 43 2 29 11 8 0 49 2 8 11 0 0 53 0 54 0 55 2 54 0 2 0 56 1 54 0 0 57 1 8 18 0 67 2 0 11 0 0 70 2 1 11 0 0 1 1 0 0 0 34 1 0 0 0 1 2 0 0 0 8 1 2 0 0 0 29 1 3 0 80 0 18 18 1 2 0 11 0 0 51 3 0 11 0 0 18 46 2 0 58 0 29 60 2 0 58 0 8 59 1 3 11 0 1 2 0 11 79 0 1 1 3 0 0 1 2 0 0 79 0 1 1 3 0 0 1 2 0 0 79 0 1 2 0 11 0 7 1 3 0 8 0 19 8 1 3 0 8 0 18 8 45 2 0 0 78 0 1 0 0 0 1 2 0 0 0 8 63 2 0 0 0 29 64 1 0 0 0 1 1 0 0 0 1 3 0 0 0 19 0 44 1 1 0 0 1 2 1 0 8 0 1 2 0 0 78 0 1 4 1 8 75 0 8 8 1 3 0 8 75 0 8 1 2 0 8 75 0 1 3 0 8 0 18 8 1 2 0 8 0 18 1 2 0 11 0 0 70 3 1 18 8 0 18 48 2 1 18 8 0 1 3 0 18 29 0 18 50 3 0 18 0 0 18 47 2 0 18 78 0 1 1 0 72 0 1 2 0 0 7 8 9 2 0 11 0 7 1 1 5 18 0 28 2 3 0 0 0 1 2 3 0 0 0 1 3 0 0 79 0 0 1 1 0 72 0 1 2 1 11 8 0 1 1 5 18 0 42 2 3 0 0 0 1 3 0 11 0 0 8 71 3 0 7 0 0 8 69 2 0 0 32 0 33 3 0 0 75 0 0 1 2 0 0 32 0 1 1 0 0 0 37 1 0 0 0 1 2 0 11 0 7 1 2 0 0 0 8 61 2 0 0 0 29 62 1 1 24 0 38 3 0 0 8 0 18 1 3 0 0 0 0 18 23 1 0 82 0 1 2 0 11 18 0 1 1 1 77 0 1 1 0 18 0 68 1 5 8 0 1 2 0 81 78 0 1 2 0 0 0 8 1 2 0 11 78 0 1 3 6 0 0 72 72 1 3 6 0 0 8 8 1 2 6 0 0 73 1 2 6 0 0 74 1 2 0 11 0 0 1 2 1 11 8 0 1 1 0 72 0 1 1 0 11 0 12 0 0 0 10 2 0 0 0 0 1 2 0 0 0 19 21 2 0 8 0 18 52 3 0 8 0 18 8 1 2 0 0 0 18 1 2 0 0 0 19 1 2 1 7 8 0 1 2 0 7 78 0 1 3 0 0 0 0 18 65 1 0 0 0 17 1 2 76 0 1 1 0 0 72 1 1 0 0 58 66 2 0 0 0 0 16 2 0 0 0 8 1 2 0 0 8 0 1 1 1 25 0 27 1 0 0 8 1 2 0 11 78 0 1 2 3 11 0 0 1 2 3 11 0 0 1 2 1 11 0 0 14 2 3 11 0 0 1 2 3 11 0 0 15 1 0 7 0 13)))))) (QUOTE |lookupComplete|)))
+@
+\section{domain STRING String}
+<<domain STRING String>>=
+)abbrev domain STRING String
+++ Description:
+++ This is the domain of character strings.
+MINSTRINGINDEX ==> 1 -- as of 3/14/90.
+
+String(): StringCategory == IndexedString(MINSTRINGINDEX) add
+ string n == STRINGIMAGE(n)$Lisp
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ OMputString(dev, x pretend String)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ OMputString(dev, x pretend String)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ OMputString(dev, x pretend String)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ OMputString(dev, x pretend String)
+ if wholeObj then
+ OMputEndObject(dev)
+
+@
+\section{category STRICAT StringCategory}
+<<category STRICAT StringCategory>>=
+)abbrev category STRICAT StringCategory
+-- Note that StringCategory is built into the old compiler
+-- redundant SetCategory added to help A# compiler
+++ Description:
+++ A category for string-like objects
+
+StringCategory():Category == Join(StringAggregate(), SetCategory, OpenMath) with
+ string: Integer -> %
+ ++ string(i) returns the decimal representation of i in a string
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain CHAR Character>>
+<<domain CCLASS CharacterClass>>
+<<domain ISTRING IndexedString>>
+<<category STRICAT StringCategory>>
+<<domain STRING String>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sttaylor.spad.pamphlet b/src/algebra/sttaylor.spad.pamphlet
new file mode 100644
index 00000000..27a16ec0
--- /dev/null
+++ b/src/algebra/sttaylor.spad.pamphlet
@@ -0,0 +1,515 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sttaylor.spad}
+\author{William Burge, Stephen Watt, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package STTAYLOR StreamTaylorSeriesOperations}
+Problems raising a UTS to a negative integer power.
+
+The code in [[powern(rn,x)]] which raises an unnecessary error
+where no distinction between rational and integer powers are made.
+
+The fix is easy. Since the problem does not exist in SUPS we can
+just take the definition there.
+
+<<package STTAYLOR StreamTaylorSeriesOperations>>=
+)abbrev package STTAYLOR StreamTaylorSeriesOperations
+++ Author: William Burge, Stephen Watt, Clifton J. Williamson
+++ Date Created: 1986
+++ Date Last Updated: 26 May 1994
+++ Basic Operations:
+++ Related Domains: Stream(A), ParadoxicalCombinatorsForStreams(A),
+++ StreamTranscendentalFunctions(A),
+++ StreamTranscendentalFunctionsNonCommutative(A)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: stream, Taylor series
+++ Examples:
+++ References:
+++ Description:
+++ StreamTaylorSeriesOperations implements Taylor series arithmetic,
+++ where a Taylor series is represented by a stream of its coefficients.
+StreamTaylorSeriesOperations(A): Exports == Implementation where
+ A : Ring
+ RN ==> Fraction Integer
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ ST ==> Stream
+ SP2 ==> StreamFunctions2
+ SP3 ==> StreamFunctions3
+ L ==> List
+ LA ==> List A
+ YS ==> Y$ParadoxicalCombinatorsForStreams(A)
+ UN ==> Union(ST A,"failed")
+ Exports ==> with
+ "+" : (ST A,ST A) -> ST A
+ ++ a + b returns the power series sum of \spad{a} and \spad{b}:
+ ++ \spad{[a0,a1,..] + [b0,b1,..] = [a0 + b0,a1 + b1,..]}
+ "-" : (ST A,ST A) -> ST A
+ ++ a - b returns the power series difference of \spad{a} and
+ ++ \spad{b}: \spad{[a0,a1,..] - [b0,b1,..] = [a0 - b0,a1 - b1,..]}
+ "-" : ST A -> ST A
+ ++ - a returns the power series negative of \spad{a}:
+ ++ \spad{- [a0,a1,...] = [- a0,- a1,...]}
+ "*" : (ST A,ST A) -> ST A
+ ++ a * b returns the power series (Cauchy) product of \spad{a} and b:
+ ++ \spad{[a0,a1,...] * [b0,b1,...] = [c0,c1,...]} where
+ ++ \spad{ck = sum(i + j = k,ai * bk)}.
+ "*" : (A,ST A) -> ST A
+ ++ r * a returns the power series scalar multiplication of r by \spad{a}:
+ ++ \spad{r * [a0,a1,...] = [r * a0,r * a1,...]}
+ "*" : (ST A,A) -> ST A
+ ++ a * r returns the power series scalar multiplication of \spad{a} by r:
+ ++ \spad{[a0,a1,...] * r = [a0 * r,a1 * r,...]}
+ "exquo" : (ST A,ST A) -> Union(ST A,"failed")
+ ++ exquo(a,b) returns the power series quotient of \spad{a} by b,
+ ++ if the quotient exists, and "failed" otherwise
+ "/" : (ST A,ST A) -> ST A
+ ++ a / b returns the power series quotient of \spad{a} by b.
+ ++ An error message is returned if \spad{b} is not invertible.
+ ++ This function is used in fixed point computations.
+ recip : ST A -> UN
+ ++ recip(a) returns the power series reciprocal of \spad{a}, or
+ ++ "failed" if not possible.
+ monom : (A,I) -> ST A
+ ++ monom(deg,coef) is a monomial of degree deg with coefficient
+ ++ coef.
+ integers : I -> ST I
+ ++ integers(n) returns \spad{[n,n+1,n+2,...]}.
+ oddintegers : I -> ST I
+ ++ oddintegers(n) returns \spad{[n,n+2,n+4,...]}.
+ int : A -> ST A
+ ++ int(r) returns [r,r+1,r+2,...], where r is a ring element.
+ mapmult : (ST A,ST A) -> ST A
+ ++ mapmult([a0,a1,..],[b0,b1,..])
+ ++ returns \spad{[a0*b0,a1*b1,..]}.
+ deriv : ST A -> ST A
+ ++ deriv(a) returns the derivative of the power series with
+ ++ respect to the power series variable. Thus
+ ++ \spad{deriv([a0,a1,a2,...])} returns \spad{[a1,2 a2,3 a3,...]}.
+ gderiv : (I -> A,ST A) -> ST A
+ ++ gderiv(f,[a0,a1,a2,..]) returns
+ ++ \spad{[f(0)*a0,f(1)*a1,f(2)*a2,..]}.
+ coerce : A -> ST A
+ ++ coerce(r) converts a ring element r to a stream with one element.
+ eval : (ST A,A) -> ST A
+ ++ eval(a,r) returns a stream of partial sums of the power series
+ ++ \spad{a} evaluated at the power series variable equal to r.
+ compose : (ST A,ST A) -> ST A
+ ++ compose(a,b) composes the power series \spad{a} with
+ ++ the power series b.
+ lagrange : ST A -> ST A
+ ++ lagrange(g) produces the power series for f where f is
+ ++ implicitly defined as \spad{f(z) = z*g(f(z))}.
+ revert : ST A -> ST A
+ ++ revert(a) computes the inverse of a power series \spad{a}
+ ++ with respect to composition.
+ ++ the series should have constant coefficient 0 and first
+ ++ order coefficient 1.
+ addiag : ST ST A -> ST A
+ ++ addiag(x) performs diagonal addition of a stream of streams. if x =
+ ++ \spad{[[a<0,0>,a<0,1>,..],[a<1,0>,a<1,1>,..],[a<2,0>,a<2,1>,..],..]}
+ ++ and \spad{addiag(x) = [b<0,b<1>,...], then b<k> = sum(i+j=k,a<i,j>)}.
+ lambert : ST A -> ST A
+ ++ lambert(st) computes \spad{f(x) + f(x**2) + f(x**3) + ...}
+ ++ if st is a stream representing \spad{f(x)}.
+ ++ This function is used for computing infinite products.
+ ++ If \spad{f(x)} is a power series with constant coefficient 1 then
+ ++ \spad{prod(f(x**n),n = 1..infinity) = exp(lambert(log(f(x))))}.
+ oddlambert : ST A -> ST A
+ ++ oddlambert(st) computes \spad{f(x) + f(x**3) + f(x**5) + ...}
+ ++ if st is a stream representing \spad{f(x)}.
+ ++ This function is used for computing infinite products.
+ ++ If f(x) is a power series with constant coefficient 1 then
+ ++ \spad{prod(f(x**(2*n-1)),n=1..infinity) = exp(oddlambert(log(f(x))))}.
+ evenlambert : ST A -> ST A
+ ++ evenlambert(st) computes \spad{f(x**2) + f(x**4) + f(x**6) + ...}
+ ++ if st is a stream representing \spad{f(x)}.
+ ++ This function is used for computing infinite products.
+ ++ If \spad{f(x)} is a power series with constant coefficient 1, then
+ ++ \spad{prod(f(x**(2*n)),n=1..infinity) = exp(evenlambert(log(f(x))))}.
+ generalLambert : (ST A,I,I) -> ST A
+ ++ generalLambert(f(x),a,d) returns
+ ++ \spad{f(x**a) + f(x**(a + d)) + f(x**(a + 2 d)) + ...}.
+ ++ \spad{f(x)} should have zero constant
+ ++ coefficient and \spad{a} and d should be positive.
+ multisect : (I,I,ST A) -> ST A
+ ++ multisect(a,b,st)
+ ++ selects the coefficients of \spad{x**((a+b)*n+a)},
+ ++ and changes them to \spad{x**n}.
+ invmultisect : (I,I,ST A) -> ST A
+ ++ invmultisect(a,b,st) substitutes \spad{x**((a+b)*n)} for \spad{x**n}
+ ++ and multiplies by \spad{x**b}.
+ if A has Algebra RN then
+ integrate : (A,ST A) -> ST A
+ ++ integrate(r,a) returns the integral of the power series \spad{a}
+ ++ with respect to the power series variableintegration where
+ ++ r denotes the constant of integration. Thus
+ ++ \spad{integrate(a,[a0,a1,a2,...]) = [a,a0,a1/2,a2/3,...]}.
+ lazyIntegrate : (A,() -> ST A) -> ST A
+ ++ lazyIntegrate(r,f) is a local function
+ ++ used for fixed point computations.
+ nlde : ST ST A -> ST A
+ ++ nlde(u) solves a
+ ++ first order non-linear differential equation described by u of the
+ ++ form \spad{[[b<0,0>,b<0,1>,...],[b<1,0>,b<1,1>,.],...]}.
+ ++ the differential equation has the form
+ ++ \spad{y' = sum(i=0 to infinity,j=0 to infinity,b<i,j>*(x**i)*(y**j))}.
+ powern : (RN,ST A) -> ST A
+ ++ powern(r,f) raises power series f to the power r.
+ if A has Field then
+ mapdiv : (ST A,ST A) -> ST A
+ ++ mapdiv([a0,a1,..],[b0,b1,..]) returns
+ ++ \spad{[a0/b0,a1/b1,..]}.
+ lazyGintegrate : (I -> A,A,() -> ST A) -> ST A
+ ++ lazyGintegrate(f,r,g) is used for fixed point computations.
+ power : (A,ST A) -> ST A
+ ++ power(a,f) returns the power series f raised to the power \spad{a}.
+
+ Implementation ==> add
+
+--% definitions
+
+ zro: () -> ST A
+ -- returns a zero power series
+ zro() == empty()$ST(A)
+
+--% arithmetic
+
+ x + y == delay
+ empty? y => x
+ empty? x => y
+ eq?(x,rst x) => map(frst x + #1,y)
+ eq?(y,rst y) => map(frst y + #1,x)
+ concat(frst x + frst y,rst x + rst y)
+
+ x - y == delay
+ empty? y => x
+ empty? x => -y
+ eq?(x,rst x) => map(frst x - #1,y)
+ eq?(y,rst y) => map(#1 - frst y,x)
+ concat(frst x - frst y,rst x - rst y)
+
+ -y == map(_-#1,y)
+
+ (x:ST A) * (y:ST A) == delay
+ empty? y => zro()
+ empty? x => zro()
+ concat(frst x * frst y,frst x * rst y + rst x * y)
+
+ (s:A) * (x:ST A) ==
+ zero? s => zro()
+ map(s * #1,x)
+
+ (x:ST A) * (s:A) ==
+ zero? s => zro()
+ map(#1 * s,x)
+
+ iDiv: (ST A,ST A,A) -> ST A
+ iDiv(x,y,ry0) == delay
+ empty? x => empty()
+ c0 := frst x * ry0
+ concat(c0,iDiv(rst x - c0 * rst y,y,ry0))
+
+ x exquo y ==
+ for n in 1.. repeat
+ n > 1000 => return "failed"
+ empty? y => return "failed"
+ empty? x => return empty()
+ frst y = 0 =>
+ frst x = 0 => (x := rst x; y := rst y)
+ return "failed"
+ leave "first entry in y is non-zero"
+ (ry0 := recip frst y) case "failed" => "failed"
+ empty? rst y => map(#1 * (ry0 :: A),x)
+ iDiv(x,y,ry0 :: A)
+
+ (x:ST A) / (y:ST A) == delay
+ empty? y => error "/: division by zero"
+ empty? x => empty()
+ (ry0 := recip frst y) case "failed" =>
+ error "/: second argument is not invertible"
+ empty? rst y => map(#1 * (ry0 :: A),x)
+ iDiv(x,y,ry0 :: A)
+
+ recip x ==
+ empty? x => "failed"
+ rh1 := recip frst x
+ rh1 case "failed" => "failed"
+ rh := rh1 :: A
+ delay
+ concat(rh,iDiv(- rh * rst x,x,rh))
+
+--% coefficients
+
+ rp: (I,A) -> L A
+ -- rp(z,s) is a list of length z each of whose entries is s.
+ rp(z,s) ==
+ z <= 0 => empty()
+ concat(s,rp(z-1,s))
+
+ rpSt: (I,A) -> ST A
+ -- rpSt(z,s) is a stream of length z each of whose entries is s.
+ rpSt(z,s) == delay
+ z <= 0 => empty()
+ concat(s,rpSt(z-1,s))
+
+ monom(s,z) ==
+ z < 0 => error "monom: cannot create monomial of negative degree"
+ concat(rpSt(z,0),concat(s,zro()))
+
+--% some streams of integers
+ nnintegers: NNI -> ST NNI
+ nnintegers zz == generate(#1 + 1,zz)
+ integers z == generate(#1 + 1,z)
+ oddintegers z == generate(#1 + 2,z)
+ int s == generate(#1 + 1,s)
+
+--% derivatives
+
+ mapmult(x,y) == delay
+ empty? y => zro()
+ empty? x => zro()
+ concat(frst x * frst y,mapmult(rst x,rst y))
+
+ deriv x ==
+ empty? x => zro()
+ mapmult(int 1,rest x)
+
+ gderiv(f,x) ==
+ empty? x => zro()
+ mapmult(map(f,integers 0)$SP2(I,A),x)
+
+--% coercions
+
+ coerce(s:A) ==
+ zero? s => zro()
+ concat(s,zro())
+
+--% evaluations and compositions
+
+ eval(x,at) == scan(0,#1 + #2,mapmult(x,generate(at * #1,1)))$SP2(A,A)
+
+ compose(x,y) == delay
+ empty? y => concat(frst x,zro())
+ not zero? frst y =>
+ error "compose: 2nd argument should have 0 constant coefficient"
+ empty? x => zro()
+ concat(frst x,compose(rst x,y) * rst(y))
+
+--% reversion
+
+ lagrangere:(ST A,ST A) -> ST A
+ lagrangere(x,c) == delay(concat(0,compose(x,c)))
+ lagrange x == YS(lagrangere(x,#1))
+
+ revert x ==
+ empty? x => error "revert should start 0,1,..."
+ zero? frst x =>
+ empty? rst x => error "revert: should start 0,1,..."
+-- one? frst rst x => lagrange(recip(rst x) :: (ST A))
+ (frst rst x) = 1 => lagrange(recip(rst x) :: (ST A))
+ error "revert:should start 0,1,..."
+
+--% lambert functions
+
+ addiag(ststa:ST ST A) == delay
+ empty? ststa => zro()
+ empty? frst ststa => concat(0,addiag rst ststa)
+ concat(frst(frst ststa),rst(frst ststa) + addiag(rst ststa))
+
+-- lambert operates on a series +/[a[i]x**i for i in 1..] , and produces
+-- the series +/[a[i](x**i/(1-x**i)) for i in 1..] i.e. forms the
+-- coefficients A[n] which is the sum of a[i] for all divisors i of n
+-- (including 1 and n)
+
+ rptg1:(I,A) -> ST A
+ -- ---------
+ -- returns the repeating stream [s,0,...,0]; (there are z zeroes)
+ rptg1(z,s) == repeating concat(s,rp(z,0))
+
+ rptg2:(I,A) -> ST A
+ -- ---------
+ -- returns the repeating stream [0,...,0,s,0,...,0]
+ -- there are z leading zeroes and z-1 in the period
+ rptg2(z,s) == repeating concat(rp(z,0),concat(s,rp(z-1,0)))
+
+ rptg3:(I,I,I,A) -> ST A
+ rptg3(a,d,n,s) ==
+ concat(rpSt(n*(a-1),0),repeating(concat(s,rp(d*n-1,0))))
+
+ lambert x == delay
+ empty? x => zro()
+ zero? frst x =>
+ concat(0,addiag(map(rptg1,integers 0,rst x)$SP3(I,A,ST A)))
+ error "lambert:constant coefficient should be zero"
+
+ oddlambert x == delay
+ empty? x => zro()
+ zero? frst x =>
+ concat(0,addiag(map(rptg1,oddintegers 1,rst x)$SP3(I,A,ST A)))
+ error "oddlambert: constant coefficient should be zero"
+
+ evenlambert x == delay
+ empty? x => zro()
+ zero? frst x =>
+ concat(0,addiag(map(rptg2,integers 1,rst x)$SP3(I,A,ST A)))
+ error "evenlambert: constant coefficient should be zero"
+
+ generalLambert(st,a,d) == delay
+ a < 1 or d < 1 =>
+ error "generalLambert: both integer arguments must be positive"
+ empty? st => zro()
+ zero? frst st =>
+ concat(0,addiag(map(rptg3(a,d,#1,#2),_
+ integers 1,rst st)$SP3(I,A,ST A)))
+ error "generalLambert: constant coefficient should be zero"
+
+--% misc. functions
+
+ ms: (I,I,ST A) -> ST A
+ ms(m,n,s) == delay
+ empty? s => zro()
+ zero? n => concat(frst s,ms(m,m-1,rst s))
+ ms(m,n-1,rst s)
+
+ multisect(b,a,x) == ms(a+b,0,rest(x,a :: NNI))
+
+ altn: (ST A,ST A) -> ST A
+ altn(zs,s) == delay
+ empty? s => zro()
+ concat(frst s,concat(zs,altn(zs,rst s)))
+
+ invmultisect(a,b,x) ==
+ concat(rpSt(b,0),altn(rpSt(a + b - 1,0),x))
+
+-- comps(ststa,y) forms the composition of +/b[i,j]*y**i*x**j
+-- where y is a power series in y.
+
+ cssa ==> concat$(ST ST A)
+ mapsa ==> map$SP2(ST A,ST A)
+ comps: (ST ST A,ST A) -> ST ST A
+ comps(ststa,x) == delay$(ST ST A)
+ empty? ststa => empty()$(ST ST A)
+ empty? x => cssa(frst ststa,empty()$(ST ST A))
+ cssa(frst ststa,mapsa((rst x) * #1,comps(rst ststa,x)))
+
+ if A has Algebra RN then
+ integre: (ST A,I) -> ST A
+ integre(x,n) == delay
+ empty? x => zro()
+ concat((1$I/n) * frst(x),integre(rst x,n + 1))
+
+ integ: ST A -> ST A
+ integ x == integre(x,1)
+
+ integrate(a,x) == concat(a,integ x)
+ lazyIntegrate(s,xf) == concat(s,integ(delay xf))
+
+ nldere:(ST ST A,ST A) -> ST A
+ nldere(lslsa,c) == lazyIntegrate(0,addiag(comps(lslsa,c)))
+ nlde lslsa == YS(nldere(lslsa,#1))
+
+ RATPOWERS : Boolean := A has "**": (A,RN) -> A
+
+ smult: (RN,ST A) -> ST A
+ smult(rn,x) == map(rn * #1,x)
+ powerrn:(RN,ST A,ST A) -> ST A
+ powerrn(rn,x,c) == delay
+ concat(1,integ(smult(rn + 1,c * deriv x)) - rst x * c)
+ powern(rn,x) ==
+ order : I := 0
+ for n in 0.. repeat
+ empty? x => return zro()
+ not zero? frst x => (order := n; leave x)
+ x := rst x
+ n = 1000 =>
+ error "**: series with many leading zero coefficients"
+ (ord := (order exquo denom(rn))) case "failed" =>
+ error "**: rational power does not exist"
+ co := frst x
+ (invCo := recip co) case "failed" =>
+ error "** rational power of coefficient undefined"
+-- This error message is misleading, isn't it? see sups.spad/cRationalPower
+ power :=
+-- one? co => YS(powerrn(rn,x,#1))
+ (co = 1) => YS(powerrn(rn,x,#1))
+ (denom rn) = 1 =>
+ not negative?(num := numer rn) =>
+-- It seems that this cannot happen, but I don't know why
+ (co**num::NNI) * YS(powerrn(rn,(invCo :: A) * x,#1))
+ (invCo :: A)**((-num)::NNI) * YS(powerrn(rn,(invCo :: A) * x,#1))
+
+ RATPOWERS => co**rn * YS(powerrn(rn,(invCo :: A) * x,#1))
+ error "** rational power of coefficient undefined"
+
+ if A has Field then
+ mapdiv(x,y) == delay
+ empty? y => error "stream division by zero"
+ empty? x => zro()
+ concat(frst x/frst y,mapdiv(rst x,rst y))
+
+ ginteg: (I -> A,ST A) -> ST A
+ ginteg(f,x) == mapdiv(x,map(f,integers 1)$SP2(I,A))
+
+ lazyGintegrate(fntoa,s,xf) == concat(s,ginteg(fntoa,delay xf))
+
+ finteg: ST A -> ST A
+ finteg x == mapdiv(x,int 1)
+ powerre: (A,ST A,ST A) -> ST A
+ powerre(s,x,c) == delay
+ empty? x => zro()
+ frst x^=1 => error "**:constant coefficient should be 1"
+ concat(frst x,finteg((s+1)*(c*deriv x))-rst x * c)
+ power(s,x) == YS(powerre(s,x,#1))
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package STTAYLOR StreamTaylorSeriesOperations>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sttf.spad.pamphlet b/src/algebra/sttf.spad.pamphlet
new file mode 100644
index 00000000..1cbc7038
--- /dev/null
+++ b/src/algebra/sttf.spad.pamphlet
@@ -0,0 +1,743 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sttf.spad}
+\author{William Burge, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package STTF StreamTranscendentalFunctions}
+<<package STTF StreamTranscendentalFunctions>>=
+)abbrev package STTF StreamTranscendentalFunctions
+++ Author: William Burge, Clifton J. Williamson
+++ Date Created: 1986
+++ Date Last Updated: 6 March 1995
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, elementary function, transcendental function
+++ Examples:
+++ References:
+++ Description:
+++ StreamTranscendentalFunctions implements transcendental functions on
+++ Taylor series, where a Taylor series is represented by a stream of
+++ its coefficients.
+StreamTranscendentalFunctions(Coef): Exports == Implementation where
+ Coef : Algebra Fraction Integer
+ L ==> List
+ I ==> Integer
+ RN ==> Fraction Integer
+ SG ==> String
+ ST ==> Stream Coef
+ STT ==> StreamTaylorSeriesOperations Coef
+ YS ==> Y$ParadoxicalCombinatorsForStreams(Coef)
+
+ Exports ==> with
+--% Exponentials and Logarithms
+ exp : ST -> ST
+ ++ exp(st) computes the exponential of a power series st.
+ log : ST -> ST
+ ++ log(st) computes the log of a power series.
+ "**" : (ST,ST) -> ST
+ ++ st1 ** st2 computes the power of a power series st1 by another
+ ++ power series st2.
+
+--% TrigonometricFunctionCategory
+ sincos : ST -> Record(sin:ST, cos:ST)
+ ++ sincos(st) returns a record containing the sine and cosine
+ ++ of a power series st.
+ sin : ST -> ST
+ ++ sin(st) computes sine of a power series st.
+ cos : ST -> ST
+ ++ cos(st) computes cosine of a power series st.
+ tan : ST -> ST
+ ++ tan(st) computes tangent of a power series st.
+ cot : ST -> ST
+ ++ cot(st) computes cotangent of a power series st.
+ sec : ST -> ST
+ ++ sec(st) computes secant of a power series st.
+ csc : ST -> ST
+ ++ csc(st) computes cosecant of a power series st.
+ asin : ST -> ST
+ ++ asin(st) computes arcsine of a power series st.
+ acos : ST -> ST
+ ++ acos(st) computes arccosine of a power series st.
+ atan : ST -> ST
+ ++ atan(st) computes arctangent of a power series st.
+ acot : ST -> ST
+ ++ acot(st) computes arccotangent of a power series st.
+ asec : ST -> ST
+ ++ asec(st) computes arcsecant of a power series st.
+ acsc : ST -> ST
+ ++ acsc(st) computes arccosecant of a power series st.
+
+--% HyperbloicTrigonometricFunctionCategory
+ sinhcosh: ST -> Record(sinh:ST, cosh:ST)
+ ++ sinhcosh(st) returns a record containing
+ ++ the hyperbolic sine and cosine
+ ++ of a power series st.
+ sinh : ST -> ST
+ ++ sinh(st) computes the hyperbolic sine of a power series st.
+ cosh : ST -> ST
+ ++ cosh(st) computes the hyperbolic cosine of a power series st.
+ tanh : ST -> ST
+ ++ tanh(st) computes the hyperbolic tangent of a power series st.
+ coth : ST -> ST
+ ++ coth(st) computes the hyperbolic cotangent of a power series st.
+ sech : ST -> ST
+ ++ sech(st) computes the hyperbolic secant of a power series st.
+ csch : ST -> ST
+ ++ csch(st) computes the hyperbolic cosecant of a power series st.
+ asinh : ST -> ST
+ ++ asinh(st) computes the inverse hyperbolic sine of a power series st.
+ acosh : ST -> ST
+ ++ acosh(st) computes the inverse hyperbolic cosine
+ ++ of a power series st.
+ atanh : ST -> ST
+ ++ atanh(st) computes the inverse hyperbolic tangent
+ ++ of a power series st.
+ acoth : ST -> ST
+ ++ acoth(st) computes the inverse hyperbolic
+ ++ cotangent of a power series st.
+ asech : ST -> ST
+ ++ asech(st) computes the inverse hyperbolic secant of a
+ ++ power series st.
+ acsch : ST -> ST
+ ++ acsch(st) computes the inverse hyperbolic
+ ++ cosecant of a power series st.
+
+ Implementation ==> add
+ import StreamTaylorSeriesOperations Coef
+
+ TRANSFCN : Boolean := Coef has TranscendentalFunctionCategory
+
+--% Error Reporting
+
+ TRCONST : SG := "series expansion involves transcendental constants"
+ NPOWERS : SG := "series expansion has terms of negative degree"
+ FPOWERS : SG := "series expansion has terms of fractional degree"
+ MAYFPOW : SG := "series expansion may have terms of fractional degree"
+ LOGS : SG := "series expansion has logarithmic term"
+ NPOWLOG : SG :=
+ "series expansion has terms of negative degree or logarithmic term"
+ FPOWLOG : SG :=
+ "series expansion has terms of fractional degree or logarithmic term"
+ NOTINV : SG := "leading coefficient not invertible"
+
+--% Exponentials and Logarithms
+
+ expre:(Coef,ST,ST) -> ST
+ expre(r,e,dx) == lazyIntegrate(r,e*dx)
+
+ exp z ==
+ empty? z => 1 :: ST
+ (coef := frst z) = 0 => YS expre(1,#1,deriv z)
+ TRANSFCN => YS expre(exp coef,#1,deriv z)
+ error concat("exp: ",TRCONST)
+
+ log z ==
+ empty? z => error "log: constant coefficient should not be 0"
+ (coef := frst z) = 0 => error "log: constant coefficient should not be 0"
+ coef = 1 => lazyIntegrate(0,deriv z/z)
+ TRANSFCN => lazyIntegrate(log coef,deriv z/z)
+ error concat("log: ",TRCONST)
+
+ z1:ST ** z2:ST == exp(z2 * log z1)
+
+--% Trigonometric Functions
+
+ sincosre:(Coef,Coef,L ST,ST,Coef) -> L ST
+ sincosre(rs,rc,sc,dx,sign) ==
+ [lazyIntegrate(rs,(second sc)*dx),lazyIntegrate(rc,sign*(first sc)*dx)]
+
+ -- When the compiler had difficulties with the above definition,
+ -- I did the following to help it:
+
+ -- sincosre:(Coef,Coef,L ST,ST,Coef) -> L ST
+ -- sincosre(rs,rc,sc,dx,sign) ==
+ -- st1 : ST := (second sc) * dx
+ -- st2 : ST := (first sc) * dx
+ -- st2 := sign * st2
+ -- [lazyIntegrate(rs,st1),lazyIntegrate(rc,st2)]
+
+ sincos z ==
+ empty? z => [0 :: ST,1 :: ST]
+ l :=
+ (coef := frst z) = 0 => YS(sincosre(0,1,#1,deriv z,-1),2)
+ TRANSFCN => YS(sincosre(sin coef,cos coef,#1,deriv z,-1),2)
+ error concat("sincos: ",TRCONST)
+ [first l,second l]
+
+ sin z == sincos(z).sin
+ cos z == sincos(z).cos
+
+ tanre:(Coef,ST,ST,Coef) -> ST
+ tanre(r,t,dx,sign) == lazyIntegrate(r,((1 :: ST) + sign*t*t)*dx)
+
+ -- When the compiler had difficulties with the above definition,
+ -- I did the following to help it:
+
+ -- tanre:(Coef,ST,ST,Coef) -> ST
+ -- tanre(r,t,dx,sign) ==
+ -- st1 : ST := t * t
+ -- st1 := sign * st1
+ -- st2 : ST := 1 :: ST
+ -- st1 := st2 + st1
+ -- st1 := st1 * dx
+ -- lazyIntegrate(r,st1)
+
+ tan z ==
+ empty? z => 0 :: ST
+ (coef := frst z) = 0 => YS tanre(0,#1,deriv z,1)
+ TRANSFCN => YS tanre(tan coef,#1,deriv z,1)
+ error concat("tan: ",TRCONST)
+
+ cotre:(Coef,ST,ST) -> ST
+ cotre(r,t,dx) == lazyIntegrate(r,-((1 :: ST) + t*t)*dx)
+
+ -- When the compiler had difficulties with the above definition,
+ -- I did the following to help it:
+
+ -- cotre:(Coef,ST,ST) -> ST
+ -- cotre(r,t,dx) ==
+ -- st1 : ST := t * t
+ -- st2 : ST := 1 :: ST
+ -- st1 := st2 + st1
+ -- st1 := st1 * dx
+ -- st1 := -st1
+ -- lazyIntegrate(r,st1)
+
+ cot z ==
+ empty? z => error "cot: cot(0) is undefined"
+ (coef := frst z) = 0 => error concat("cot: ",NPOWERS)
+ TRANSFCN => YS cotre(cot coef,#1,deriv z)
+ error concat("cot: ",TRCONST)
+
+ sec z ==
+ empty? z => 1 :: ST
+ frst z = 0 => recip(cos z) :: ST
+ TRANSFCN =>
+ cosz := cos z
+ first cosz = 0 => error concat("sec: ",NPOWERS)
+ recip(cosz) :: ST
+ error concat("sec: ",TRCONST)
+
+ csc z ==
+ empty? z => error "csc: csc(0) is undefined"
+ TRANSFCN =>
+ sinz := sin z
+ first sinz = 0 => error concat("csc: ",NPOWERS)
+ recip(sinz) :: ST
+ error concat("csc: ",TRCONST)
+
+ orderOrFailed : ST -> Union(I,"failed")
+ orderOrFailed x ==
+ -- returns the order of x or "failed"
+ -- if -1 is returned, the series is identically zero
+ for n in 0..1000 repeat
+ empty? x => return -1
+ not zero? frst x => return n :: I
+ x := rst x
+ "failed"
+
+ asin z ==
+ empty? z => 0 :: ST
+ (coef := frst z) = 0 =>
+ integrate(0,powern(-1/2,(1 :: ST) - z*z) * (deriv z))
+ TRANSFCN =>
+ coef = 1 or coef = -1 =>
+ x := (1 :: ST) - z*z
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asin: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asin(coef) :: ST
+ odd? order => error concat("asin: ",FPOWERS)
+ squirt := powern(1/2,x)
+ (quot := (deriv z) exquo squirt) case "failed" =>
+ error concat("asin: ",NOTINV)
+ integrate(asin coef,quot :: ST)
+ integrate(asin coef,powern(-1/2,(1 :: ST) - z*z) * (deriv z))
+ error concat("asin: ",TRCONST)
+
+ acos z ==
+ empty? z =>
+ TRANSFCN => acos(0)$Coef :: ST
+ error concat("acos: ",TRCONST)
+ TRANSFCN =>
+ coef := frst z
+ coef = 1 or coef = -1 =>
+ x := (1 :: ST) - z*z
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acos: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acos(coef) :: ST
+ odd? order => error concat("acos: ",FPOWERS)
+ squirt := powern(1/2,x)
+ (quot := (-deriv z) exquo squirt) case "failed" =>
+ error concat("acos: ",NOTINV)
+ integrate(acos coef,quot :: ST)
+ integrate(acos coef,-powern(-1/2,(1 :: ST) - z*z) * (deriv z))
+ error concat("acos: ",TRCONST)
+
+ atan z ==
+ empty? z => 0 :: ST
+ (coef := frst z) = 0 =>
+ integrate(0,(recip((1 :: ST) + z*z) :: ST) * (deriv z))
+ TRANSFCN =>
+ (y := recip((1 :: ST) + z*z)) case "failed" =>
+ error concat("atan: ",LOGS)
+ integrate(atan coef,(y :: ST) * (deriv z))
+ error concat("atan: ",TRCONST)
+
+ acot z ==
+ empty? z =>
+ TRANSFCN => acot(0)$Coef :: ST
+ error concat("acot: ",TRCONST)
+ TRANSFCN =>
+ (y := recip((1 :: ST) + z*z)) case "failed" =>
+ error concat("acot: ",LOGS)
+ integrate(acot frst z,-(y :: ST) * (deriv z))
+ error concat("acot: ",TRCONST)
+
+ asec z ==
+ empty? z => error "asec: constant coefficient should not be 0"
+ TRANSFCN =>
+ (coef := frst z) = 0 =>
+ error "asec: constant coefficient should not be 0"
+ coef = 1 or coef = -1 =>
+ x := z*z - (1 :: ST)
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asec: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asec(coef) :: ST
+ odd? order => error concat("asec: ",FPOWERS)
+ squirt := powern(1/2,x)
+ (quot := (deriv z) exquo squirt) case "failed" =>
+ error concat("asec: ",NOTINV)
+ (quot2 := (quot :: ST) exquo z) case "failed" =>
+ error concat("asec: ",NOTINV)
+ integrate(asec coef,quot2 :: ST)
+ integrate(asec coef,(powern(-1/2,z*z-(1::ST))*(deriv z)) / z)
+ error concat("asec: ",TRCONST)
+
+ acsc z ==
+ empty? z => error "acsc: constant coefficient should not be zero"
+ TRANSFCN =>
+ (coef := frst z) = 0 =>
+ error "acsc: constant coefficient should not be zero"
+ coef = 1 or coef = -1 =>
+ x := z*z - (1 :: ST)
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acsc: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acsc(coef) :: ST
+ odd? order => error concat("acsc: ",FPOWERS)
+ squirt := powern(1/2,x)
+ (quot := (-deriv z) exquo squirt) case "failed" =>
+ error concat("acsc: ",NOTINV)
+ (quot2 := (quot :: ST) exquo z) case "failed" =>
+ error concat("acsc: ",NOTINV)
+ integrate(acsc coef,quot2 :: ST)
+ integrate(acsc coef,-(powern(-1/2,z*z-(1::ST))*(deriv z)) / z)
+ error concat("acsc: ",TRCONST)
+
+--% Hyperbolic Trigonometric Functions
+
+ sinhcosh z ==
+ empty? z => [0 :: ST,1 :: ST]
+ l :=
+ (coef := frst z) = 0 => YS(sincosre(0,1,#1,deriv z,1),2)
+ TRANSFCN => YS(sincosre(sinh coef,cosh coef,#1,deriv z,1),2)
+ error concat("sinhcosh: ",TRCONST)
+ [first l,second l]
+
+ sinh z == sinhcosh(z).sinh
+ cosh z == sinhcosh(z).cosh
+
+ tanh z ==
+ empty? z => 0 :: ST
+ (coef := frst z) = 0 => YS tanre(0,#1,deriv z,-1)
+ TRANSFCN => YS tanre(tanh coef,#1,deriv z,-1)
+ error concat("tanh: ",TRCONST)
+
+ coth z ==
+ tanhz := tanh z
+ empty? tanhz => error "coth: coth(0) is undefined"
+ (frst tanhz) = 0 => error concat("coth: ",NPOWERS)
+ recip(tanhz) :: ST
+
+ sech z ==
+ coshz := cosh z
+ (empty? coshz) or (frst coshz = 0) => error concat("sech: ",NPOWERS)
+ recip(coshz) :: ST
+
+ csch z ==
+ sinhz := sinh z
+ (empty? sinhz) or (frst sinhz = 0) => error concat("csch: ",NPOWERS)
+ recip(sinhz) :: ST
+
+ asinh z ==
+ empty? z => 0 :: ST
+ (coef := frst z) = 0 => log(z + powern(1/2,(1 :: ST) + z*z))
+ TRANSFCN =>
+ x := (1 :: ST) + z*z
+ -- compute order of 'x', in case coefficient(z,0) = +- %i
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asinh: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asinh(coef) :: ST
+ odd? order => error concat("asinh: ",FPOWERS)
+ -- the argument to 'log' must have a non-zero constant term
+ log(z + powern(1/2,x))
+ error concat("asinh: ",TRCONST)
+
+ acosh z ==
+ empty? z =>
+ TRANSFCN => acosh(0)$Coef :: ST
+ error concat("acosh: ",TRCONST)
+ TRANSFCN =>
+ coef := frst z
+ coef = 1 or coef = -1 =>
+ x := z*z - (1 :: ST)
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acosh: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acosh(coef) :: ST
+ odd? order => error concat("acosh: ",FPOWERS)
+ -- the argument to 'log' must have a non-zero constant term
+ log(z + powern(1/2,x))
+ log(z + powern(1/2,z*z - (1 :: ST)))
+ error concat("acosh: ",TRCONST)
+
+ atanh z ==
+ empty? z => 0 :: ST
+ (coef := frst z) = 0 =>
+ (inv(2::RN)::Coef) * log(((1 :: ST) + z)/((1 :: ST) - z))
+ TRANSFCN =>
+ coef = 1 or coef = -1 => error concat("atanh: ",LOGS)
+ (inv(2::RN)::Coef) * log(((1 :: ST) + z)/((1 :: ST) - z))
+ error concat("atanh: ",TRCONST)
+
+ acoth z ==
+ empty? z =>
+ TRANSFCN => acoth(0)$Coef :: ST
+ error concat("acoth: ",TRCONST)
+ TRANSFCN =>
+ frst z = 1 or frst z = -1 => error concat("acoth: ",LOGS)
+ (inv(2::RN)::Coef) * log((z + (1 :: ST))/(z - (1 :: ST)))
+ error concat("acoth: ",TRCONST)
+
+ asech z ==
+ empty? z => error "asech: asech(0) is undefined"
+ TRANSFCN =>
+ (coef := frst z) = 0 => error concat("asech: ",NPOWLOG)
+ coef = 1 or coef = -1 =>
+ x := (1 :: ST) - z*z
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asech: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asech(coef) :: ST
+ odd? order => error concat("asech: ",FPOWERS)
+ log(((1 :: ST) + powern(1/2,x))/z)
+ log(((1 :: ST) + powern(1/2,(1 :: ST) - z*z))/z)
+ error concat("asech: ",TRCONST)
+
+ acsch z ==
+ empty? z => error "acsch: acsch(0) is undefined"
+ TRANSFCN =>
+ frst z = 0 => error concat("acsch: ",NPOWLOG)
+ x := z*z + (1 :: ST)
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acsc: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acsch(frst z) :: ST
+ odd? order => error concat("acsch: ",FPOWERS)
+ log(((1 :: ST) + powern(1/2,x))/z)
+ error concat("acsch: ",TRCONST)
+
+@
+\section{package STTFNC StreamTranscendentalFunctionsNonCommutative}
+<<package STTFNC StreamTranscendentalFunctionsNonCommutative>>=
+)abbrev package STTFNC StreamTranscendentalFunctionsNonCommutative
+++ Author: Clifton J. Williamson
+++ Date Created: 26 May 1994
+++ Date Last Updated: 26 May 1994
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, transcendental function, non-commutative
+++ Examples:
+++ References:
+++ Description:
+++ StreamTranscendentalFunctionsNonCommutative implements transcendental
+++ functions on Taylor series over a non-commutative ring, where a Taylor
+++ series is represented by a stream of its coefficients.
+StreamTranscendentalFunctionsNonCommutative(Coef): _
+ Exports == Implementation where
+ Coef : Algebra Fraction Integer
+ I ==> Integer
+ SG ==> String
+ ST ==> Stream Coef
+ STTF ==> StreamTranscendentalFunctions Coef
+
+ Exports ==> with
+--% Exponentials and Logarithms
+ exp : ST -> ST
+ ++ exp(st) computes the exponential of a power series st.
+ log : ST -> ST
+ ++ log(st) computes the log of a power series.
+ "**" : (ST,ST) -> ST
+ ++ st1 ** st2 computes the power of a power series st1 by another
+ ++ power series st2.
+
+--% TrigonometricFunctionCategory
+ sin : ST -> ST
+ ++ sin(st) computes sine of a power series st.
+ cos : ST -> ST
+ ++ cos(st) computes cosine of a power series st.
+ tan : ST -> ST
+ ++ tan(st) computes tangent of a power series st.
+ cot : ST -> ST
+ ++ cot(st) computes cotangent of a power series st.
+ sec : ST -> ST
+ ++ sec(st) computes secant of a power series st.
+ csc : ST -> ST
+ ++ csc(st) computes cosecant of a power series st.
+ asin : ST -> ST
+ ++ asin(st) computes arcsine of a power series st.
+ acos : ST -> ST
+ ++ acos(st) computes arccosine of a power series st.
+ atan : ST -> ST
+ ++ atan(st) computes arctangent of a power series st.
+ acot : ST -> ST
+ ++ acot(st) computes arccotangent of a power series st.
+ asec : ST -> ST
+ ++ asec(st) computes arcsecant of a power series st.
+ acsc : ST -> ST
+ ++ acsc(st) computes arccosecant of a power series st.
+
+--% HyperbloicTrigonometricFunctionCategory
+ sinh : ST -> ST
+ ++ sinh(st) computes the hyperbolic sine of a power series st.
+ cosh : ST -> ST
+ ++ cosh(st) computes the hyperbolic cosine of a power series st.
+ tanh : ST -> ST
+ ++ tanh(st) computes the hyperbolic tangent of a power series st.
+ coth : ST -> ST
+ ++ coth(st) computes the hyperbolic cotangent of a power series st.
+ sech : ST -> ST
+ ++ sech(st) computes the hyperbolic secant of a power series st.
+ csch : ST -> ST
+ ++ csch(st) computes the hyperbolic cosecant of a power series st.
+ asinh : ST -> ST
+ ++ asinh(st) computes the inverse hyperbolic sine of a power series st.
+ acosh : ST -> ST
+ ++ acosh(st) computes the inverse hyperbolic cosine
+ ++ of a power series st.
+ atanh : ST -> ST
+ ++ atanh(st) computes the inverse hyperbolic tangent
+ ++ of a power series st.
+ acoth : ST -> ST
+ ++ acoth(st) computes the inverse hyperbolic
+ ++ cotangent of a power series st.
+ asech : ST -> ST
+ ++ asech(st) computes the inverse hyperbolic secant of a
+ ++ power series st.
+ acsch : ST -> ST
+ ++ acsch(st) computes the inverse hyperbolic
+ ++ cosecant of a power series st.
+
+ Implementation ==> add
+ import StreamTaylorSeriesOperations(Coef)
+
+--% Error Reporting
+
+ ZERO : SG := "series must have constant coefficient zero"
+ ONE : SG := "series must have constant coefficient one"
+ NPOWERS : SG := "series expansion has terms of negative degree"
+
+--% Exponentials and Logarithms
+
+ exp z ==
+ empty? z => 1 :: ST
+ (frst z) = 0 =>
+ expx := exp(monom(1,1))$STTF
+ compose(expx,z)
+ error concat("exp: ",ZERO)
+
+ log z ==
+ empty? z => error concat("log: ",ONE)
+ (frst z) = 1 =>
+ log1PlusX := log(monom(1,0) + monom(1,1))$STTF
+ compose(log1PlusX,z - monom(1,0))
+ error concat("log: ",ONE)
+
+ (z1:ST) ** (z2:ST) == exp(log(z1) * z2)
+
+--% Trigonometric Functions
+
+ sin z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ sinx := sin(monom(1,1))$STTF
+ compose(sinx,z)
+ error concat("sin: ",ZERO)
+
+ cos z ==
+ empty? z => 1 :: ST
+ (frst z) = 0 =>
+ cosx := cos(monom(1,1))$STTF
+ compose(cosx,z)
+ error concat("cos: ",ZERO)
+
+ tan z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ tanx := tan(monom(1,1))$STTF
+ compose(tanx,z)
+ error concat("tan: ",ZERO)
+
+ cot z ==
+ empty? z => error "cot: cot(0) is undefined"
+ (frst z) = 0 => error concat("cot: ",NPOWERS)
+ error concat("cot: ",ZERO)
+
+ sec z ==
+ empty? z => 1 :: ST
+ (frst z) = 0 =>
+ secx := sec(monom(1,1))$STTF
+ compose(secx,z)
+ error concat("sec: ",ZERO)
+
+ csc z ==
+ empty? z => error "csc: csc(0) is undefined"
+ (frst z) = 0 => error concat("csc: ",NPOWERS)
+ error concat("csc: ",ZERO)
+
+ asin z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ asinx := asin(monom(1,1))$STTF
+ compose(asinx,z)
+ error concat("asin: ",ZERO)
+
+ atan z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ atanx := atan(monom(1,1))$STTF
+ compose(atanx,z)
+ error concat("atan: ",ZERO)
+
+ acos z == error "acos: acos undefined on this coefficient domain"
+ acot z == error "acot: acot undefined on this coefficient domain"
+ asec z == error "asec: asec undefined on this coefficient domain"
+ acsc z == error "acsc: acsc undefined on this coefficient domain"
+
+--% Hyperbolic Trigonometric Functions
+
+ sinh z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ sinhx := sinh(monom(1,1))$STTF
+ compose(sinhx,z)
+ error concat("sinh: ",ZERO)
+
+ cosh z ==
+ empty? z => 1 :: ST
+ (frst z) = 0 =>
+ coshx := cosh(monom(1,1))$STTF
+ compose(coshx,z)
+ error concat("cosh: ",ZERO)
+
+ tanh z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ tanhx := tanh(monom(1,1))$STTF
+ compose(tanhx,z)
+ error concat("tanh: ",ZERO)
+
+ coth z ==
+ empty? z => error "coth: coth(0) is undefined"
+ (frst z) = 0 => error concat("coth: ",NPOWERS)
+ error concat("coth: ",ZERO)
+
+ sech z ==
+ empty? z => 1 :: ST
+ (frst z) = 0 =>
+ sechx := sech(monom(1,1))$STTF
+ compose(sechx,z)
+ error concat("sech: ",ZERO)
+
+ csch z ==
+ empty? z => error "csch: csch(0) is undefined"
+ (frst z) = 0 => error concat("csch: ",NPOWERS)
+ error concat("csch: ",ZERO)
+
+ asinh z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ asinhx := asinh(monom(1,1))$STTF
+ compose(asinhx,z)
+ error concat("asinh: ",ZERO)
+
+ atanh z ==
+ empty? z => 0 :: ST
+ (frst z) = 0 =>
+ atanhx := atanh(monom(1,1))$STTF
+ compose(atanhx,z)
+ error concat("atanh: ",ZERO)
+
+ acosh z == error "acosh: acosh undefined on this coefficient domain"
+ acoth z == error "acoth: acoth undefined on this coefficient domain"
+ asech z == error "asech: asech undefined on this coefficient domain"
+ acsch z == error "acsch: acsch undefined on this coefficient domain"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package STTF StreamTranscendentalFunctions>>
+<<package STTFNC StreamTranscendentalFunctionsNonCommutative>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sturm.spad.pamphlet b/src/algebra/sturm.spad.pamphlet
new file mode 100644
index 00000000..462c1c00
--- /dev/null
+++ b/src/algebra/sturm.spad.pamphlet
@@ -0,0 +1,421 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sturm.spad}
+\author{Lalo Gonzalez-Vega}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SHP SturmHabichtPackage}
+<<package SHP SturmHabichtPackage>>=
+)abbrev package SHP SturmHabichtPackage
+++ Author: Lalo Gonzalez-Vega
+++ Date Created: 1994?
+++ Date Last Updated: 30 January 1996
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: localization
+++ References:
+++ Description:
+++ This package produces functions for counting
+++ etc. real roots of univariate polynomials in x over R, which must
+++ be an OrderedIntegralDomain
+SturmHabichtPackage(R,x): T == C where
+ R: OrderedIntegralDomain
+ x: Symbol
+
+ UP ==> UnivariatePolynomial
+ L ==> List
+ INT ==> Integer
+ NNI ==> NonNegativeInteger
+
+ T == with
+-- subresultantSequenceBegin:(UP(x,R),UP(x,R)) -> L UP(x,R)
+-- ++ \spad{subresultantSequenceBegin(p1,p2)} computes the initial terms
+-- ++ of the Subresultant sequence Sres(j)(P,deg(P),Q,deg(P)-1)
+-- ++ when deg(Q)<deg(P)
+-- subresultantSequenceNext:L UP(x,R) -> L UP(x,R)
+-- subresultantSequenceInner:(UP(x,R),UP(x,R)) -> L UP(x,R)
+ subresultantSequence:(UP(x,R),UP(x,R)) -> L UP(x,R)
+ ++ subresultantSequence(p1,p2) computes the (standard)
+ ++ subresultant sequence of p1 and p2
+-- sign:R -> R
+-- delta:NNI -> R
+
+-- polsth1:(UP(x,R),NNI,UP(x,R),NNI,R) -> L UP(x,R)
+-- polsth2:(UP(x,R),NNI,UP(x,R),NNI,R) -> L UP(x,R)
+-- polsth3:(UP(x,R),NNI,UP(x,R),NNI,R) -> L UP(x,R)
+ SturmHabichtSequence:(UP(x,R),UP(x,R)) -> L UP(x,R)
+ ++ SturmHabichtSequence(p1,p2) computes the Sturm-Habicht
+ ++ sequence of p1 and p2
+ SturmHabichtCoefficients:(UP(x,R),UP(x,R)) -> L R
+ ++ SturmHabichtCoefficients(p1,p2) computes the principal
+ ++ Sturm-Habicht coefficients of p1 and p2
+
+-- variation:L R -> INT
+-- permanence:L R -> INT
+-- qzeros:L R -> L R
+-- epsil:(NNI,R,R) -> INT
+-- numbnce:L R -> NNI
+-- numbce:L R -> NNI
+-- wfunctaux:L R -> INT
+-- wfunct:L R -> INT
+
+ SturmHabicht:(UP(x,R),UP(x,R)) -> INT
+ ++ SturmHabicht(p1,p2) computes c_{+}-c_{-} where
+ ++ c_{+} is the number of real roots of p1 with p2>0 and c_{-}
+ ++ is the number of real roots of p1 with p2<0. If p2=1 what
+ ++ you get is the number of real roots of p1.
+ countRealRoots:(UP(x,R)) -> INT
+ ++ countRealRoots(p) says how many real roots p has
+ if R has GcdDomain then
+ SturmHabichtMultiple:(UP(x,R),UP(x,R)) -> INT
+ ++ SturmHabichtMultiple(p1,p2) computes c_{+}-c_{-} where
+ ++ c_{+} is the number of real roots of p1 with p2>0 and c_{-}
+ ++ is the number of real roots of p1 with p2<0. If p2=1 what
+ ++ you get is the number of real roots of p1.
+ countRealRootsMultiple:(UP(x,R)) -> INT
+ ++ countRealRootsMultiple(p) says how many real roots p has,
+ ++ counted with multiplicity
+
+
+ C == add
+ p1,p2: UP(x,R)
+ Ex ==> OutputForm
+ import OutputForm
+
+ subresultantSequenceBegin(p1,p2):L UP(x,R) ==
+ d1:NNI:=degree(p1)
+ d2:NNI:=degree(p2)
+ n:NNI:=(d1-1)::NNI
+ d2 = n =>
+ Pr:UP(x,R):=pseudoRemainder(p1,p2)
+ append([p1,p2]::L UP(x,R),[Pr]::L UP(x,R))
+ d2 = (n-1)::NNI =>
+ Lc1:UP(x,R):=leadingCoefficient(p1)*leadingCoefficient(p2)*p2
+ Lc2:UP(x,R):=-leadingCoefficient(p1)*pseudoRemainder(p1,p2)
+ append([p1,p2]::L UP(x,R),[Lc1,Lc2]::L UP(x,R))
+ LSubr:L UP(x,R):=[p1,p2]
+ in1:INT:=(d2+1)::INT
+ in2:INT:=(n-1)::INT
+ for i in in1..in2 repeat
+ LSubr:L UP(x,R):=append(LSubr::L UP(x,R),[0]::L UP(x,R))
+ c1:R:=(leadingCoefficient(p1)*leadingCoefficient(p2))**((n-d2)::NNI)
+ Lc1:UP(x,R):=monomial(c1,0)*p2
+ Lc2:UP(x,R):=
+ (-leadingCoefficient(p1))**((n-d2)::NNI)*pseudoRemainder(p1,p2)
+ append(LSubr::L UP(x,R),[Lc1,Lc2]::L UP(x,R))
+
+ subresultantSequenceNext(LcsI:L UP(x,R)):L UP(x,R) ==
+ p2:UP(x,R):=last LcsI
+ p1:UP(x,R):=first rest reverse LcsI
+ d1:NNI:=degree(p1)
+ d2:NNI:=degree(p2)
+ in1:NNI:=(d1-1)::NNI
+ d2 = in1 =>
+ pr1:UP(x,R):=
+ (pseudoRemainder(p1,p2) exquo (leadingCoefficient(p1))**2)::UP(x,R)
+ append(LcsI:L UP(x,R),[pr1]:L UP(x,R))
+ d2 < in1 =>
+ c1:R:=leadingCoefficient(p1)
+ pr1:UP(x,R):=
+ (leadingCoefficient(p2)**((in1-d2)::NNI)*p2 exquo
+ c1**((in1-d2)::NNI))::UP(x,R)
+ pr2:UP(x,R):=
+ (pseudoRemainder(p1,p2) exquo (-c1)**((in1-d2+2)::NNI))::UP(x,R)
+ LSub:L UP(x,R):=[pr1,pr2]
+ for k in ((d2+1)::INT)..((in1-1)::INT) repeat
+ LSub:L UP(x,R):=append([0]:L UP(x,R),LSub:L UP(x,R))
+ append(LcsI:L UP(x,R),LSub:L UP(x,R))
+
+ subresultantSequenceInner(p1,p2):L UP(x,R) ==
+ Lin:L UP(x,R):=subresultantSequenceBegin(p1:UP(x,R),p2:UP(x,R))
+ indf:NNI:= if not(Lin.last::UP(x,R) = 0) then degree(Lin.last::UP(x,R))
+ else 0
+ while not(indf = 0) repeat
+ Lin:L UP(x,R):=subresultantSequenceNext(Lin:L UP(x,R))
+ indf:NNI:= if not(Lin.last::UP(x,R)=0) then degree(Lin.last::UP(x,R))
+ else 0
+ for j in #(Lin:L UP(x,R))..degree(p1) repeat
+ Lin:L UP(x,R):=append(Lin:L UP(x,R),[0]:L UP(x,R))
+ Lin
+
+
+-- Computation of the subresultant sequence Sres(j)(P,p,Q,q) when:
+-- deg(P) = p and deg(Q) = q and p > q
+
+ subresultantSequence(p1,p2):L UP(x,R) ==
+ p:NNI:=degree(p1)
+ q:NNI:=degree(p2)
+ List1:L UP(x,R):=subresultantSequenceInner(p1,p2)
+ List2:L UP(x,R):=[p1,p2]
+ c1:R:=leadingCoefficient(p1)
+ for j in 3..#(List1) repeat
+ Pr0:UP(x,R):=List1.j
+ Pr1:UP(x,R):=(Pr0 exquo c1**((p-q-1)::NNI))::UP(x,R)
+ List2:L UP(x,R):=append(List2:L UP(x,R),[Pr1]:L UP(x,R))
+ List2
+
+
+-- Computation of the sign (+1,0,-1) of an element in an ordered integral
+-- domain
+
+-- sign(r:R):R ==
+-- r =$R 0 => 0
+-- r >$R 0 => 1
+-- -1
+
+
+-- Computation of the delta function:
+
+ delta(int1:NNI):R ==
+ (-1)**((int1*(int1+1) exquo 2)::NNI)
+
+
+-- Computation of the Sturm-Habicht sequence of two polynomials P and Q
+-- in R[x] where R is an ordered integral domaine
+
+ polsth1(p1,p:NNI,p2,q:NNI,c1:R):L UP(x,R) ==
+ sc1:R:=(sign(c1))::R
+ Pr1:UP(x,R):=pseudoRemainder(differentiate(p1)*p2,p1)
+ Pr2:UP(x,R):=(Pr1 exquo c1**(q::NNI))::UP(x,R)
+ c2:R:=leadingCoefficient(Pr2)
+ r:NNI:=degree(Pr2)
+ Pr3:UP(x,R):=monomial(sc1**((p-r-1)::NNI),0)*p1
+ Pr4:UP(x,R):=monomial(sc1**((p-r-1)::NNI),0)*Pr2
+ Listf:L UP(x,R):=[Pr3,Pr4]
+ if r < p-1 then
+ Pr5:UP(x,R):=monomial(delta((p-r-1)::NNI)*c2**((p-r-1)::NNI),0)*Pr2
+ for j in ((r+1)::INT)..((p-2)::INT) repeat
+ Listf:L UP(x,R):=append(Listf:L UP(x,R),[0]:L UP(x,R))
+ Listf:L UP(x,R):=append(Listf:L UP(x,R),[Pr5]:L UP(x,R))
+ if Pr1=0 then List1:L UP(x,R):=Listf
+ else List1:L UP(x,R):=subresultantSequence(p1,Pr2)
+ List2:L UP(x,R):=[]
+ for j in 0..((r-1)::INT) repeat
+ Pr6:UP(x,R):=monomial(delta((p-j-1)::NNI),0)*List1.((p-j+1)::NNI)
+ List2:L UP(x,R):=append([Pr6]:L UP(x,R),List2:L UP(x,R))
+ append(Listf:L UP(x,R),List2:L UP(x,R))
+
+ polsth2(p1,p:NNI,p2,q:NNI,c1:R):L UP(x,R) ==
+ sc1:R:=(sign(c1))::R
+ Pr1:UP(x,R):=monomial(sc1,0)*p1
+ Pr2:UP(x,R):=differentiate(p1)*p2
+ Pr3:UP(x,R):=monomial(sc1,0)*Pr2
+ Listf:L UP(x,R):=[Pr1,Pr3]
+ List1:L UP(x,R):=subresultantSequence(p1,Pr2)
+ List2:L UP(x,R):=[]
+ for j in 0..((p-2)::INT) repeat
+ Pr4:UP(x,R):=monomial(delta((p-j-1)::NNI),0)*List1.((p-j+1)::NNI)
+ Pr5:UP(x,R):=(Pr4 exquo c1)::UP(x,R)
+ List2:L UP(x,R):=append([Pr5]:L UP(x,R),List2:L UP(x,R))
+ append(Listf:L UP(x,R),List2:L UP(x,R))
+
+ polsth3(p1,p:NNI,p2,q:NNI,c1:R):L UP(x,R) ==
+ sc1:R:=(sign(c1))::R
+ q1:NNI:=(q-1)::NNI
+ v:NNI:=(p+q1)::NNI
+ Pr1:UP(x,R):=monomial(delta(q1::NNI)*sc1**((q+1)::NNI),0)*p1
+ Listf:L UP(x,R):=[Pr1]
+ List1:L UP(x,R):=subresultantSequence(differentiate(p1)*p2,p1)
+ List2:L UP(x,R):=[]
+ for j in 0..((p-1)::NNI) repeat
+ Pr2:UP(x,R):=monomial(delta((v-j)::NNI),0)*List1.((v-j+1)::NNI)
+ Pr3:UP(x,R):=(Pr2 exquo c1)::UP(x,R)
+ List2:L UP(x,R):=append([Pr3]:L UP(x,R),List2:L UP(x,R))
+ append(Listf:L UP(x,R),List2:L UP(x,R))
+
+ SturmHabichtSequence(p1,p2):L UP(x,R) ==
+ p:NNI:=degree(p1)
+ q:NNI:=degree(p2)
+ c1:R:=leadingCoefficient(p1)
+ c1 = 1 or q = 1 => polsth1(p1,p,p2,q,c1)
+ q = 0 => polsth2(p1,p,p2,q,c1)
+ polsth3(p1,p,p2,q,c1)
+
+
+-- Computation of the Sturm-Habicht principal coefficients of two
+-- polynomials P and Q in R[x] where R is an ordered integral domain
+
+ SturmHabichtCoefficients(p1,p2):L R ==
+ List1:L UP(x,R):=SturmHabichtSequence(p1,p2)
+-- List2:L R:=[]
+ qp:NNI:=#(List1)::NNI
+ [coefficient(p,(qp-j)::NNI) for p in List1 for j in 1..qp]
+-- for j in 1..qp repeat
+-- Ply:R:=coefficient(List1.j,(qp-j)::NNI)
+-- List2:L R:=append(List2,[Ply])
+-- List2
+
+
+-- Computation of the number of sign variations of a list of non zero
+-- elements in an ordered integral domain
+
+ variation(Lsig:L R):INT ==
+ size?(Lsig,1) => 0
+ elt1:R:=first Lsig
+ elt2:R:=Lsig.2
+ sig1:R:=(sign(elt1*elt2))::R
+ List1:L R:=rest Lsig
+ sig1 = 1 => variation List1
+ 1+variation List1
+
+
+-- Computation of the number of sign permanences of a list of non zero
+-- elements in an ordered integral domain
+
+ permanence(Lsig:L R):INT ==
+ size?(Lsig,1) => 0
+ elt1:R:=first Lsig
+ elt2:R:=Lsig.2
+ sig1:R:=(sign(elt1*elt2))::R
+ List1:L R:=rest Lsig
+ sig1 = -1 => permanence List1
+ 1+permanence List1
+
+
+-- Computation of the functional W which works over a list of elements
+-- in an ordered integral domain, with non zero first element
+
+ qzeros(Lsig:L R):L R ==
+ while last Lsig = 0 repeat
+ Lsig:L R:=reverse rest reverse Lsig
+ Lsig
+
+ epsil(int1:NNI,elt1:R,elt2:R):INT ==
+ int1 = 0 => 0
+ odd? int1 => 0
+ ct1:INT:=if elt1 > 0 then 1 else -1
+ ct2:INT:=if elt2 > 0 then 1 else -1
+ ct3:NNI:=(int1 exquo 2)::NNI
+ ct4:INT:=(ct1*ct2)::INT
+ ((-1)**(ct3::NNI))*ct4
+
+ numbnce(Lsig:L R):NNI ==
+ null Lsig => 0
+ eltp:R:=Lsig.1
+ eltp = 0 => 0
+ 1 + numbnce(rest Lsig)
+
+ numbce(Lsig:L R):NNI ==
+ null Lsig => 0
+ eltp:R:=Lsig.1
+ not(eltp = 0) => 0
+ 1 + numbce(rest Lsig)
+
+ wfunctaux(Lsig:L R):INT ==
+ null Lsig => 0
+ List2:L R:=[]
+ List1:L R:=Lsig:L R
+ cont1:NNI:=numbnce(List1:L R)
+ for j in 1..cont1 repeat
+ List2:L R:=append(List2:L R,[first List1]:L R)
+ List1:L R:=rest List1
+ ind2:INT:=0
+ cont2:NNI:=numbce(List1:L R)
+ for j in 1..cont2 repeat
+ List1:L R:=rest List1
+ ind2:INT:=epsil(cont2:NNI,last List2,first List1)
+ ind3:INT:=permanence(List2:L R)-variation(List2:L R)
+ ind4:INT:=ind2+ind3
+ ind4+wfunctaux(List1:L R)
+
+ wfunct(Lsig:L R):INT ==
+ List1:L R:=qzeros(Lsig:L R)
+ wfunctaux(List1:L R)
+
+
+-- Computation of the integer number:
+-- #[{a in Rc(R)/P(a)=0 Q(a)>0}] - #[{a in Rc(R)/P(a)=0 Q(a)<0}]
+-- where:
+-- - R is an ordered integral domain,
+-- - Rc(R) is the real clousure of R,
+-- - P and Q are polynomials in R[x],
+-- - by #[A] we note the cardinal of the set A
+
+-- In particular:
+-- - SturmHabicht(P,1) is the number of "real" roots of P,
+-- - SturmHabicht(P,Q**2) is the number of "real" roots of P making Q neq 0
+
+ SturmHabicht(p1,p2):INT ==
+-- print("+" :: Ex)
+ p2 = 0 => 0
+ degree(p1:UP(x,R)) = 0 => 0
+ List1:L UP(x,R):=SturmHabichtSequence(p1,p2)
+ qp:NNI:=#(List1)::NNI
+ wfunct [coefficient(p,(qp-j)::NNI) for p in List1 for j in 1..qp]
+
+ countRealRoots(p1):INT == SturmHabicht(p1,1)
+
+ if R has GcdDomain then
+ SturmHabichtMultiple(p1,p2):INT ==
+ -- print("+" :: Ex)
+ p2 = 0 => 0
+ degree(p1:UP(x,R)) = 0 => 0
+ SH:L UP(x,R):=SturmHabichtSequence(p1,p2)
+ qp:NNI:=#(SH)::NNI
+ ans:= wfunct [coefficient(p,(qp-j)::NNI) for p in SH for j in 1..qp]
+ SH:=reverse SH
+ while first SH = 0 repeat SH:=rest SH
+ degree first SH = 0 => ans
+ -- OK: it probably wasn't square free, so this item is probably the
+ -- gcd of p1 and p1'
+ -- unless p1 and p2 have a factor in common (naughty!)
+ differentiate(p1) exquo first SH case UP(x,R) =>
+ -- it was the gcd of p1 and p1'
+ ans+SturmHabichtMultiple(first SH,p2)
+ sqfr:=factorList squareFree p1
+ #sqfr = 1 and sqfr.first.xpnt=1 => ans
+ reduce("+",[f.xpnt*SturmHabicht(f.fctr,p2) for f in sqfr])
+
+ countRealRootsMultiple(p1):INT == SturmHabichtMultiple(p1,1)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SHP SturmHabichtPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/suchthat.spad.pamphlet b/src/algebra/suchthat.spad.pamphlet
new file mode 100644
index 00000000..f26514fe
--- /dev/null
+++ b/src/algebra/suchthat.spad.pamphlet
@@ -0,0 +1,79 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra suchthat.spad}
+\author{Timothy Daly}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SUCH SuchThat}
+<<domain SUCH SuchThat>>=
+)abbrev domain SUCH SuchThat
+++ Description:
+++ This domain implements "such that" forms
+SuchThat(S1, S2): Cat == Capsule where
+ E ==> OutputForm
+ S1, S2: SetCategory
+
+ Cat == SetCategory with
+ construct: (S1, S2) -> %
+ ++ construct(s,t) makes a form s:t
+ lhs: % -> S1
+ ++ lhs(f) returns the left side of f
+ rhs: % -> S2
+ ++ rhs(f) returns the right side of f
+
+ Capsule == add
+ Rep := Record(obj: S1, cond: S2)
+ construct(o, c) == [o, c]$Record(obj: S1, cond: S2)
+ lhs st == st.obj
+ rhs st == st.cond
+ coerce(w):E == infix("|"::E, w.obj::E, w.cond::E)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SUCH SuchThat>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/suls.spad.pamphlet b/src/algebra/suls.spad.pamphlet
new file mode 100644
index 00000000..8bdf483b
--- /dev/null
+++ b/src/algebra/suls.spad.pamphlet
@@ -0,0 +1,250 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra suls.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SULS SparseUnivariateLaurentSeries}
+<<domain SULS SparseUnivariateLaurentSeries>>=
+)abbrev domain SULS SparseUnivariateLaurentSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 11 November 1994
+++ Date Last Updated: 10 March 1995
+++ Basic Operations:
+++ Related Domains: InnerSparseUnivariatePowerSeries,
+++ SparseUnivariateTaylorSeries, SparseUnivariatePuiseuxSeries
+++ Also See:
+++ AMS Classifications:
+++ Keywords: sparse, series
+++ Examples:
+++ References:
+++ Description: Sparse Laurent series in one variable
+++ \spadtype{SparseUnivariateLaurentSeries} is a domain representing Laurent
+++ series in one variable with coefficients in an arbitrary ring. The
+++ parameters of the type specify the coefficient ring, the power series
+++ variable, and the center of the power series expansion. For example,
+++ \spad{SparseUnivariateLaurentSeries(Integer,x,3)} represents Laurent
+++ series in \spad{(x - 3)} with integer coefficients.
+SparseUnivariateLaurentSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ P ==> Polynomial Coef
+ RF ==> Fraction Polynomial Coef
+ RN ==> Fraction Integer
+ S ==> String
+ SUTS ==> SparseUnivariateTaylorSeries(Coef,var,cen)
+ EFULS ==> ElementaryFunctionsUnivariateLaurentSeries(Coef,SUTS,%)
+
+ Exports ==> UnivariateLaurentSeriesConstructorCategory(Coef,SUTS) with
+ coerce: Variable(var) -> %
+ ++ \spad{coerce(var)} converts the series variable \spad{var} into a
+ ++ Laurent series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} returns the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> InnerSparseUnivariatePowerSeries(Coef) add
+
+ Rep := InnerSparseUnivariatePowerSeries(Coef)
+
+ variable x == var
+ center x == cen
+
+ coerce(v: Variable(var)) ==
+ zero? cen => monomial(1,1)
+ monomial(1,1) + monomial(cen,0)
+
+ pole? x == negative? order(x,0)
+
+--% operations with Taylor series
+
+ coerce(uts:SUTS) == uts pretend %
+
+ taylorIfCan uls ==
+ pole? uls => "failed"
+ uls pretend SUTS
+
+ taylor uls ==
+ (uts := taylorIfCan uls) case "failed" =>
+ error "taylor: Laurent series has a pole"
+ uts :: SUTS
+
+ retractIfCan(x:%):Union(SUTS,"failed") == taylorIfCan x
+
+ laurent(n,uts) == monomial(1,n) * (uts :: %)
+
+ removeZeroes uls == uls
+ removeZeroes(n,uls) == uls
+
+ taylorRep uls == taylor(monomial(1,-order(uls,0)) * uls)
+ degree uls == order(uls,0)
+
+ numer uls == taylorRep uls
+ denom uls == monomial(1,(-order(uls,0)) :: NNI)$SUTS
+
+ (uts:SUTS) * (uls:%) == (uts :: %) * uls
+ (uls:%) * (uts:SUTS) == uls * (uts :: %)
+
+ if Coef has Field then
+ (uts1:SUTS) / (uts2:SUTS) == (uts1 :: %) / (uts2 :: %)
+
+ recip(uls) == iExquo(1,uls,false)
+
+ if Coef has IntegralDomain then
+ uls1 exquo uls2 == iExquo(uls1,uls2,false)
+
+ if Coef has Field then
+ uls1:% / uls2:% ==
+ (q := uls1 exquo uls2) case "failed" =>
+ error "quotient cannot be computed"
+ q :: %
+
+ differentiate(uls:%,v:Variable(var)) == differentiate uls
+
+ elt(uls1:%,uls2:%) ==
+ order(uls2,1) < 1 =>
+ error "elt: second argument must have positive order"
+ negative?(ord := order(uls1,0)) =>
+ (recipr := recip uls2) case "failed" =>
+ error "elt: second argument not invertible"
+ uls3 := uls1 * monomial(1,-ord)
+ iCompose(uls3,uls2) * (recipr :: %) ** ((-ord) :: NNI)
+ iCompose(uls1,uls2)
+
+ if Coef has IntegralDomain then
+ rationalFunction(uls,n) ==
+ zero?(e := order(uls,0)) =>
+ negative? n => 0
+ polynomial(taylor uls,n :: NNI) :: RF
+ negative?(m := n - e) => 0
+ poly := polynomial(taylor(monomial(1,-e) * uls),m :: NNI) :: RF
+ v := variable(uls) :: RF; c := center(uls) :: P :: RF
+ poly / (v - c) ** ((-e) :: NNI)
+
+ rationalFunction(uls,n1,n2) == rationalFunction(truncate(uls,n1,n2),n2)
+
+ if Coef has Algebra Fraction Integer then
+
+ integrate uls ==
+ zero? coefficient(uls,-1) =>
+ error "integrate: series has term of order -1"
+ integrate(uls)$Rep
+
+ integrate(uls:%,v:Variable(var)) == integrate uls
+
+ (uls1:%) ** (uls2:%) == exp(log(uls1) * uls2)
+
+ exp uls == exp(uls)$EFULS
+ log uls == log(uls)$EFULS
+ sin uls == sin(uls)$EFULS
+ cos uls == cos(uls)$EFULS
+ tan uls == tan(uls)$EFULS
+ cot uls == cot(uls)$EFULS
+ sec uls == sec(uls)$EFULS
+ csc uls == csc(uls)$EFULS
+ asin uls == asin(uls)$EFULS
+ acos uls == acos(uls)$EFULS
+ atan uls == atan(uls)$EFULS
+ acot uls == acot(uls)$EFULS
+ asec uls == asec(uls)$EFULS
+ acsc uls == acsc(uls)$EFULS
+ sinh uls == sinh(uls)$EFULS
+ cosh uls == cosh(uls)$EFULS
+ tanh uls == tanh(uls)$EFULS
+ coth uls == coth(uls)$EFULS
+ sech uls == sech(uls)$EFULS
+ csch uls == csch(uls)$EFULS
+ asinh uls == asinh(uls)$EFULS
+ acosh uls == acosh(uls)$EFULS
+ atanh uls == atanh(uls)$EFULS
+ acoth uls == acoth(uls)$EFULS
+ asech uls == asech(uls)$EFULS
+ acsch uls == acsch(uls)$EFULS
+
+ if Coef has CommutativeRing then
+
+ (uls:%) ** (r:RN) == cRationalPower(uls,r)
+
+ else
+
+ (uls:%) ** (r:RN) ==
+ negative?(ord0 := order(uls,0)) =>
+ order := ord0 :: I
+ (n := order exquo denom(r)) case "failed" =>
+ error "**: rational power does not exist"
+ uts := retract(uls * monomial(1,-order))@SUTS
+ utsPow := (uts ** r) :: %
+ monomial(1,(n :: I) * numer(r)) * utsPow
+ uts := retract(uls)@SUTS
+ (uts ** r) :: %
+
+--% OutputForms
+
+ coerce(uls:%): OUT ==
+ st := getStream uls
+ if not(explicitlyEmpty? st or explicitEntries? st) _
+ and (nx := retractIfCan(elt getRef uls))@Union(I,"failed") case I then
+ count : NNI := _$streamCount$Lisp
+ degr := min(count,(nx :: I) + count + 1)
+ extend(uls,degr)
+ seriesToOutputForm(st,getRef uls,variable uls,center uls,1)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SULS SparseUnivariateLaurentSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sum.spad.pamphlet b/src/algebra/sum.spad.pamphlet
new file mode 100644
index 00000000..e6b315bc
--- /dev/null
+++ b/src/algebra/sum.spad.pamphlet
@@ -0,0 +1,390 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sum.spad}
+\author{Stephen M. Watt, Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ISUMP InnerPolySum}
+<<package ISUMP InnerPolySum>>=
+)abbrev package ISUMP InnerPolySum
+++ Summation of polynomials
+++ Author: SMW
+++ Date Created: ???
+++ Date Last Updated: 19 April 1991
+++ Description: tools for the summation packages.
+InnerPolySum(E, V, R, P): Exports == Impl where
+ E: OrderedAbelianMonoidSup
+ V: OrderedSet
+ R: IntegralDomain
+ P: PolynomialCategory(R, E, V)
+
+ Z ==> Integer
+ Q ==> Fraction Z
+ SUP ==> SparseUnivariatePolynomial
+
+ Exports ==> with
+ sum: (P, V, Segment P) -> Record(num:P, den:Z)
+ ++ sum(p(n), n = a..b) returns \spad{p(a) + p(a+1) + ... + p(b)}.
+ sum: (P, V) -> Record(num:P, den: Z)
+ ++ sum(p(n), n) returns \spad{P(n)},
+ ++ the indefinite sum of \spad{p(n)} with respect to
+ ++ upward difference on n, i.e. \spad{P(n+1) - P(n) = a(n)};
+
+ Impl ==> add
+ import PolynomialNumberTheoryFunctions()
+ import UnivariatePolynomialCommonDenominator(Z, Q, SUP Q)
+
+ pmul: (P, SUP Q) -> Record(num:SUP P, den:Z)
+
+ pmul(c, p) ==
+ pn := (rec := splitDenominator p).num
+ [map(numer(#1) * c,
+ pn)$SparseUnivariatePolynomialFunctions2(Q, P), rec.den]
+
+ sum(p, v, s) ==
+ indef := sum(p, v)
+ [eval(indef.num, v, 1 + hi s) - eval(indef.num, v, lo s),
+ indef.den]
+
+ sum(p, v) ==
+ up := univariate(p, v)
+ lp := nil()$List(SUP P)
+ ld := nil()$List(Z)
+ while up ^= 0 repeat
+ ud := degree up; uc := leadingCoefficient up
+ up := reductum up
+ rec := pmul(uc, 1 / (ud+1) * bernoulli(ud+1))
+ lp := concat(rec.num, lp)
+ ld := concat(rec.den, ld)
+ d := lcm ld
+ vp := +/[(d exquo di)::Z * pi for di in ld for pi in lp]
+ [multivariate(vp, v), d]
+
+@
+\section{package GOSPER GosperSummationMethod}
+<<package GOSPER GosperSummationMethod>>=
+)abbrev package GOSPER GosperSummationMethod
+++ Gosper's summation algorithm
+++ Author: SMW
+++ Date Created: ???
+++ Date Last Updated: 19 August 1991
+++ Description: Gosper's summation algorithm.
+GosperSummationMethod(E, V, R, P, Q): Exports == Impl where
+ E: OrderedAbelianMonoidSup
+ V: OrderedSet
+ R: IntegralDomain
+ P: PolynomialCategory(R, E, V)
+ Q: Join(RetractableTo Fraction Integer, Field with
+ (coerce: P -> %; numer : % -> P; denom : % -> P))
+
+ I ==> Integer
+ RN ==> Fraction I
+ PQ ==> SparseMultivariatePolynomial(RN, V)
+ RQ ==> Fraction PQ
+
+ Exports ==> with
+ GospersMethod: (Q, V, () -> V) -> Union(Q, "failed")
+ ++ GospersMethod(b, n, new) returns a rational function
+ ++ \spad{rf(n)} such that \spad{a(n) * rf(n)} is the indefinite
+ ++ sum of \spad{a(n)}
+ ++ with respect to upward difference on \spad{n}, i.e.
+ ++ \spad{a(n+1) * rf(n+1) - a(n) * rf(n) = a(n)},
+ ++ where \spad{b(n) = a(n)/a(n-1)} is a rational function.
+ ++ Returns "failed" if no such rational function \spad{rf(n)}
+ ++ exists.
+ ++ Note: \spad{new} is a nullary function returning a new
+ ++ V every time.
+ ++ The condition on \spad{a(n)} is that \spad{a(n)/a(n-1)}
+ ++ is a rational function of \spad{n}.
+ --++ \spad{sum(a(n), n) = rf(n) * a(n)}.
+
+ Impl ==> add
+ import PolynomialCategoryQuotientFunctions(E, V, R, P, Q)
+ import LinearSystemMatrixPackage(RQ,Vector RQ,Vector RQ,Matrix RQ)
+
+ InnerGospersMethod: (RQ, V, () -> V) -> Union(RQ, "failed")
+ GosperPQR: (PQ, PQ, V, () -> V) -> List PQ
+ GosperDegBd: (PQ, PQ, PQ, V, () -> V) -> I
+ GosperF: (I, PQ, PQ, PQ, V, () -> V) -> Union(RQ, "failed")
+ linearAndNNIntRoot: (PQ, V) -> Union(I, "failed")
+ deg0: (PQ, V) -> I -- degree with deg 0 = -1.
+ pCoef: (PQ, PQ) -> PQ -- pCoef(p, a*b**2)
+ RF2QIfCan: Q -> Union(RQ, "failed")
+ UP2QIfCan: P -> Union(PQ,"failed")
+ RFQ2R : RQ -> Q
+ PQ2R : PQ -> Q
+ rat? : R -> Boolean
+
+ deg0(p, v) == (zero? p => -1; degree(p, v))
+ rat? x == retractIfCan(x::P::Q)@Union(RN, "failed") case RN
+ RFQ2R f == PQ2R(numer f) / PQ2R(denom f)
+
+ PQ2R p ==
+ map(#1::P::Q, #1::Q, p)$PolynomialCategoryLifting(
+ IndexedExponents V, V, RN, PQ, Q)
+
+ GospersMethod(aquo, n, newV) ==
+ ((q := RF2QIfCan aquo) case "failed") or
+ ((u := InnerGospersMethod(q::RQ, n, newV)) case "failed") =>
+ "failed"
+ RFQ2R(u::RQ)
+
+ RF2QIfCan f ==
+ (n := UP2QIfCan numer f) case "failed" => "failed"
+ (d := UP2QIfCan denom f) case "failed" => "failed"
+ n::PQ / d::PQ
+
+ UP2QIfCan p ==
+ every?(rat?, coefficients p) =>
+ map(#1::PQ, (retractIfCan(#1::P::Q)@Union(RN, "failed"))::RN::PQ,
+ p)$PolynomialCategoryLifting(E, V, R, P, PQ)
+ "failed"
+
+ InnerGospersMethod(aquo, n, newV) ==
+ -- 1. Define coprime polys an,anm1 such that
+ -- an/anm1=a(n)/a(n-1)
+ an := numer aquo
+ anm1 := denom aquo
+
+ -- 2. Define p,q,r such that
+ -- a(n)/a(n-1) = (p(n)/p(n-1)) * (q(n)/r(n))
+ -- and
+ -- gcd(q(n), r(n+j)) = 1, for all j: NNI.
+ pqr:= GosperPQR(an, anm1, n, newV)
+ pn := first pqr; qn := second pqr; rn := third pqr
+
+ -- 3. If the sum is a rational fn, there is a poly f with
+ -- sum(a(n), n) = q(n+1)/p(n) * a(n) * f(n).
+
+ -- 4. Bound the degree of f(n).
+ (k := GosperDegBd(pn, qn, rn, n, newV)) < 0 => "failed"
+
+ -- 5. Find a polynomial f of degree at most k, satisfying
+ -- p(n) = q(n+1)*f(n) - r(n)*f(n-1)
+ (ufn := GosperF(k, pn, qn, rn, n, newV)) case "failed" =>
+ "failed"
+ fn := ufn::RQ
+
+ -- 6. The sum is q(n-1)/p(n)*f(n) * a(n). We leave out a(n).
+ --qnm1 := eval(qn,n,n::PQ - 1)
+ --qnm1/pn * fn
+ qn1 := eval(qn,n,n::PQ + 1)
+ qn1/pn * fn
+
+ GosperF(k, pn, qn, rn, n, newV) ==
+ mv := newV(); mp := mv::PQ; np := n::PQ
+ fn: PQ := +/[mp**(i+1) * np**i for i in 0..k]
+ fnminus1: PQ := eval(fn, n, np-1)
+ qnplus1 := eval(qn, n, np+1)
+ zro := qnplus1 * fn - rn * fnminus1 - pn
+ zron := univariate(zro, n)
+ dz := degree zron
+ mat: Matrix RQ := zero(dz+1, (k+1)::NonNegativeInteger)
+ vec: Vector RQ := new(dz+1, 0)
+ while zron ^= 0 repeat
+ cz := leadingCoefficient zron
+ dz := degree zron
+ zron := reductum zron
+ mz := univariate(cz, mv)
+ while mz ^= 0 repeat
+ cmz := leadingCoefficient(mz)::RQ
+ dmz := degree mz
+ mz := reductum mz
+ dmz = 0 => vec(dz + minIndex vec) := -cmz
+ qsetelt_!(mat, dz + minRowIndex mat,
+ dmz + minColIndex(mat) - 1, cmz)
+ (soln := particularSolution(mat, vec)) case "failed" => "failed"
+ vec := soln::Vector RQ
+ (+/[np**i * vec(i + minIndex vec) for i in 0..k])@RQ
+
+ GosperPQR(an, anm1, n, newV) ==
+ np := n::PQ -- polynomial version of n
+ -- Initial guess.
+ pn: PQ := 1
+ qn: PQ := an
+ rn: PQ := anm1
+ -- Find all j: NNI giving common factors to q(n) and r(n+j).
+ j := newV()
+ rnj := eval(rn, n, np + j::PQ)
+ res := resultant(qn, rnj, n)
+ fres := factor(res)$MRationalFactorize(IndexedExponents V,
+ V, I, PQ)
+ js := [rt::I for fe in factors fres
+ | (rt := linearAndNNIntRoot(fe.factor,j)) case I]
+ -- For each such j, change variables to remove the gcd.
+ for rt in js repeat
+ rtp:= rt::PQ -- polynomial version of rt
+ gn := gcd(qn, eval(rn,n,np+rtp))
+ qn := (qn exquo gn)::PQ
+ rn := (rn exquo eval(gn, n, np-rtp))::PQ
+ pn := pn * */[eval(gn, n, np-i::PQ) for i in 0..rt-1]
+ [pn, qn, rn]
+
+ -- Find a degree bound for the polynomial f(n) which satisfies
+ -- p(n) = q(n+1)*f(n) - r(n)*f(n-1).
+ GosperDegBd(pn, qn, rn, n, newV) ==
+ np := n::PQ
+ qnplus1 := eval(qn, n, np+1)
+ lplus := deg0(qnplus1 + rn, n)
+ lminus := deg0(qnplus1 - rn, n)
+ degp := deg0(pn, n)
+ k := degp - max(lplus-1, lminus)
+ lplus <= lminus => k
+ -- Find L(k), such that
+ -- p(n) = L(k)*c[k]*n**(k + lplus - 1) + ...
+ -- To do this, write f(n) and f(n-1) symbolically.
+ -- f(n) = c[k]*n**k + c[k-1]*n**(k-1) +O(n**(k-2))
+ -- f(n-1)=c[k]*n**k + (c[k-1]-k*c[k])*n**(k-1)+O(n**(k-2))
+ kk := newV()::PQ
+ ck := newV()::PQ
+ ckm1 := newV()::PQ
+ nkm1:= newV()::PQ
+ nk := np*nkm1
+ headfn := ck*nk + ckm1*nkm1
+ headfnm1 := ck*nk + (ckm1-kk*ck)*nkm1
+ -- Then p(n) = q(n+1)*f(n) - r(n)*f(n-1) gives L(k).
+ pk := qnplus1 * headfn - rn * headfnm1
+ lcpk := pCoef(pk, ck*np*nkm1)
+ -- The degree bd is now given by k, and the root of L.
+ k0 := linearAndNNIntRoot(lcpk, mainVariable(kk)::V)
+ k0 case "failed" => k
+ max(k0::I, k)
+
+ pCoef(p, nom) ==
+ not monomial? nom =>
+ error "pCoef requires a monomial 2nd arg"
+ vlist := variables nom
+ for v in vlist while p ^= 0 repeat
+ unom:= univariate(nom,v)
+ pow:=degree unom
+ nom:=leadingCoefficient unom
+ up := univariate(p, v)
+ p := coefficient(up, pow)
+ p
+
+ linearAndNNIntRoot(mp, v) ==
+ p := univariate(mp, v)
+ degree p ^= 1 => "failed"
+ (p1 := retractIfCan(coefficient(p, 1))@Union(RN,"failed"))
+ case "failed" or
+ (p0 := retractIfCan(coefficient(p, 0))@Union(RN,"failed"))
+ case "failed" => "failed"
+ rt := -(p0::RN)/(p1::RN)
+ rt < 0 or denom rt ^= 1 => "failed"
+ numer rt
+
+@
+\section{package SUMRF RationalFunctionSum}
+<<package SUMRF RationalFunctionSum>>=
+)abbrev package SUMRF RationalFunctionSum
+++ Summation of rational functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 19 April 1991
+++ Description: Computes sums of rational functions;
+RationalFunctionSum(R): Exports == Impl where
+ R: Join(IntegralDomain, OrderedSet, RetractableTo Integer)
+
+ P ==> Polynomial R
+ RF ==> Fraction P
+ FE ==> Expression R
+ SE ==> Symbol
+
+ Exports ==> with
+ sum: (P, SE) -> RF
+ ++ sum(a(n), n) returns \spad{A} which
+ ++ is the indefinite sum of \spad{a} with respect to
+ ++ upward difference on \spad{n}, i.e. \spad{A(n+1) - A(n) = a(n)}.
+ sum: (RF, SE) -> Union(RF, FE)
+ ++ sum(a(n), n) returns \spad{A} which
+ ++ is the indefinite sum of \spad{a} with respect to
+ ++ upward difference on \spad{n}, i.e. \spad{A(n+1) - A(n) = a(n)}.
+ sum: (P, SegmentBinding P) -> RF
+ ++ sum(f(n), n = a..b) returns \spad{f(a) + f(a+1) + ... f(b)}.
+ sum: (RF, SegmentBinding RF) -> Union(RF, FE)
+ ++ sum(f(n), n = a..b) returns \spad{f(a) + f(a+1) + ... f(b)}.
+
+ Impl ==> add
+ import RationalFunction R
+ import GosperSummationMethod(IndexedExponents SE, SE, R, P, RF)
+
+ innersum : (RF, SE) -> Union(RF, "failed")
+ innerpolysum: (P, SE) -> RF
+
+ sum(f:RF, s:SegmentBinding RF) ==
+ (indef := innersum(f, v := variable s)) case "failed" =>
+ summation(f::FE,map(#1::FE,s)$SegmentBindingFunctions2(RF,FE))
+ eval(indef::RF, v, 1 + hi segment s)
+ - eval(indef::RF, v,lo segment s)
+
+ sum(an:RF, n:SE) ==
+ (u := innersum(an, n)) case "failed" => summation(an::FE, n)
+ u::RF
+
+ sum(p:P, s:SegmentBinding P) ==
+ f := sum(p, v := variable s)
+ eval(f, v, (1 + hi segment s)::RF) - eval(f,v,lo(segment s)::RF)
+
+ innersum(an, n) ==
+ (r := retractIfCan(an)@Union(P, "failed")) case "failed" =>
+ an1 := eval(an, n, -1 + n::RF)
+ (u := GospersMethod(an/an1, n, new$SE)) case "failed" =>
+ "failed"
+ an1 * eval(u::RF, n, -1 + n::RF)
+ sum(r::P, n)
+
+ sum(p:P, n:SE) ==
+ rec := sum(p, n)$InnerPolySum(IndexedExponents SE, SE, R, P)
+ rec.num / (rec.den :: P)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ISUMP InnerPolySum>>
+<<package GOSPER GosperSummationMethod>>
+<<package SUMRF RationalFunctionSum>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/sups.spad.pamphlet b/src/algebra/sups.spad.pamphlet
new file mode 100644
index 00000000..289a0f64
--- /dev/null
+++ b/src/algebra/sups.spad.pamphlet
@@ -0,0 +1,1114 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra sups.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ISUPS InnerSparseUnivariatePowerSeries}
+<<domain ISUPS InnerSparseUnivariatePowerSeries>>=
+)abbrev domain ISUPS InnerSparseUnivariatePowerSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 28 October 1994
+++ Date Last Updated: 9 March 1995
+++ Basic Operations:
+++ Related Domains: SparseUnivariateTaylorSeries, SparseUnivariateLaurentSeries
+++ SparseUnivariatePuiseuxSeries
+++ Also See:
+++ AMS Classifications:
+++ Keywords: sparse, series
+++ Examples:
+++ References:
+++ Description: InnerSparseUnivariatePowerSeries is an internal domain
+++ used for creating sparse Taylor and Laurent series.
+InnerSparseUnivariatePowerSeries(Coef): Exports == Implementation where
+ Coef : Ring
+ B ==> Boolean
+ COM ==> OrderedCompletion Integer
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ PI ==> PositiveInteger
+ REF ==> Reference OrderedCompletion Integer
+ RN ==> Fraction Integer
+ Term ==> Record(k:Integer,c:Coef)
+ SG ==> String
+ ST ==> Stream Term
+
+ Exports ==> UnivariatePowerSeriesCategory(Coef,Integer) with
+ makeSeries: (REF,ST) -> %
+ ++ makeSeries(refer,str) creates a power series from the reference
+ ++ \spad{refer} and the stream \spad{str}.
+ getRef: % -> REF
+ ++ getRef(f) returns a reference containing the order to which the
+ ++ terms of f have been computed.
+ getStream: % -> ST
+ ++ getStream(f) returns the stream of terms representing the series f.
+ series: ST -> %
+ ++ series(st) creates a series from a stream of non-zero terms,
+ ++ where a term is an exponent-coefficient pair. The terms in the
+ ++ stream should be ordered by increasing order of exponents.
+ monomial?: % -> B
+ ++ monomial?(f) tests if f is a single monomial.
+ multiplyCoefficients: (I -> Coef,%) -> %
+ ++ multiplyCoefficients(fn,f) returns the series
+ ++ \spad{sum(fn(n) * an * x^n,n = n0..)},
+ ++ where f is the series \spad{sum(an * x^n,n = n0..)}.
+ iExquo: (%,%,B) -> Union(%,"failed")
+ ++ iExquo(f,g,taylor?) is the quotient of the power series f and g.
+ ++ If \spad{taylor?} is \spad{true}, then we must have
+ ++ \spad{order(f) >= order(g)}.
+ taylorQuoByVar: % -> %
+ ++ taylorQuoByVar(a0 + a1 x + a2 x**2 + ...)
+ ++ returns \spad{a1 + a2 x + a3 x**2 + ...}
+ iCompose: (%,%) -> %
+ ++ iCompose(f,g) returns \spad{f(g(x))}. This is an internal function
+ ++ which should only be called for Taylor series \spad{f(x)} and
+ ++ \spad{g(x)} such that the constant coefficient of \spad{g(x)} is zero.
+ seriesToOutputForm: (ST,REF,Symbol,Coef,RN) -> OutputForm
+ ++ seriesToOutputForm(st,refer,var,cen,r) prints the series
+ ++ \spad{f((var - cen)^r)}.
+ if Coef has Algebra Fraction Integer then
+ integrate: % -> %
+ ++ integrate(f(x)) returns an anti-derivative of the power series
+ ++ \spad{f(x)} with constant coefficient 0.
+ ++ Warning: function does not check for a term of degree -1.
+ cPower: (%,Coef) -> %
+ ++ cPower(f,r) computes \spad{f^r}, where f has constant coefficient 1.
+ ++ For use when the coefficient ring is commutative.
+ cRationalPower: (%,RN) -> %
+ ++ cRationalPower(f,r) computes \spad{f^r}.
+ ++ For use when the coefficient ring is commutative.
+ cExp: % -> %
+ ++ cExp(f) computes the exponential of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cLog: % -> %
+ ++ cLog(f) computes the logarithm of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cSin: % -> %
+ ++ cSin(f) computes the sine of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cCos: % -> %
+ ++ cCos(f) computes the cosine of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cTan: % -> %
+ ++ cTan(f) computes the tangent of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cCot: % -> %
+ ++ cCot(f) computes the cotangent of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cSec: % -> %
+ ++ cSec(f) computes the secant of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cCsc: % -> %
+ ++ cCsc(f) computes the cosecant of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAsin: % -> %
+ ++ cAsin(f) computes the arcsine of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAcos: % -> %
+ ++ cAcos(f) computes the arccosine of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAtan: % -> %
+ ++ cAtan(f) computes the arctangent of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAcot: % -> %
+ ++ cAcot(f) computes the arccotangent of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAsec: % -> %
+ ++ cAsec(f) computes the arcsecant of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAcsc: % -> %
+ ++ cAcsc(f) computes the arccosecant of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cSinh: % -> %
+ ++ cSinh(f) computes the hyperbolic sine of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cCosh: % -> %
+ ++ cCosh(f) computes the hyperbolic cosine of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cTanh: % -> %
+ ++ cTanh(f) computes the hyperbolic tangent of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cCoth: % -> %
+ ++ cCoth(f) computes the hyperbolic cotangent of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cSech: % -> %
+ ++ cSech(f) computes the hyperbolic secant of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cCsch: % -> %
+ ++ cCsch(f) computes the hyperbolic cosecant of the power series f.
+ ++ For use when the coefficient ring is commutative.
+ cAsinh: % -> %
+ ++ cAsinh(f) computes the inverse hyperbolic sine of the power
+ ++ series f. For use when the coefficient ring is commutative.
+ cAcosh: % -> %
+ ++ cAcosh(f) computes the inverse hyperbolic cosine of the power
+ ++ series f. For use when the coefficient ring is commutative.
+ cAtanh: % -> %
+ ++ cAtanh(f) computes the inverse hyperbolic tangent of the power
+ ++ series f. For use when the coefficient ring is commutative.
+ cAcoth: % -> %
+ ++ cAcoth(f) computes the inverse hyperbolic cotangent of the power
+ ++ series f. For use when the coefficient ring is commutative.
+ cAsech: % -> %
+ ++ cAsech(f) computes the inverse hyperbolic secant of the power
+ ++ series f. For use when the coefficient ring is commutative.
+ cAcsch: % -> %
+ ++ cAcsch(f) computes the inverse hyperbolic cosecant of the power
+ ++ series f. For use when the coefficient ring is commutative.
+
+ Implementation ==> add
+ import REF
+
+ Rep := Record(%ord: REF,%str: Stream Term)
+ -- when the value of 'ord' is n, this indicates that all non-zero
+ -- terms of order up to and including n have been computed;
+ -- when 'ord' is plusInfinity, all terms have been computed;
+ -- lazy evaluation of 'str' has the side-effect of modifying the value
+ -- of 'ord'
+
+--% Local functions
+
+ makeTerm: (Integer,Coef) -> Term
+ getCoef: Term -> Coef
+ getExpon: Term -> Integer
+ iSeries: (ST,REF) -> ST
+ iExtend: (ST,COM,REF) -> ST
+ iTruncate0: (ST,REF,REF,COM,I,I) -> ST
+ iTruncate: (%,COM,I) -> %
+ iCoefficient: (ST,Integer) -> Coef
+ iOrder: (ST,COM,REF) -> I
+ iMap1: ((Coef,I) -> Coef,I -> I,B,ST,REF,REF,Integer) -> ST
+ iMap2: ((Coef,I) -> Coef,I -> I,B,%) -> %
+ iPlus1: ((Coef,Coef) -> Coef,ST,REF,ST,REF,REF,I) -> ST
+ iPlus2: ((Coef,Coef) -> Coef,%,%) -> %
+ productByTerm: (Coef,I,ST,REF,REF,I) -> ST
+ productLazyEval: (ST,REF,ST,REF,COM) -> Void
+ iTimes: (ST,REF,ST,REF,REF,I) -> ST
+ iDivide: (ST,REF,ST,REF,Coef,I,REF,I) -> ST
+ divide: (%,I,%,I,Coef) -> %
+ compose0: (ST,REF,ST,REF,I,%,%,I,REF,I) -> ST
+ factorials?: () -> Boolean
+ termOutput: (RN,Coef,OUT) -> OUT
+ showAll?: () -> Boolean
+
+--% macros
+
+ makeTerm(exp,coef) == [exp,coef]
+ getCoef term == term.c
+ getExpon term == term.k
+
+ makeSeries(refer,x) == [refer,x]
+ getRef ups == ups.%ord
+ getStream ups == ups.%str
+
+--% creation and destruction of series
+
+ monomial(coef,expon) ==
+ nix : ST := empty()
+ st :=
+ zero? coef => nix
+ concat(makeTerm(expon,coef),nix)
+ makeSeries(ref plusInfinity(),st)
+
+ monomial? ups == (not empty? getStream ups) and (empty? rst getStream ups)
+
+ coerce(n:I) == n :: Coef :: %
+ coerce(r:Coef) == monomial(r,0)
+
+ iSeries(x,refer) ==
+ empty? x => (setelt(refer,plusInfinity()); empty())
+ setelt(refer,(getExpon frst x) :: COM)
+ concat(frst x,iSeries(rst x,refer))
+
+ series(x:ST) ==
+ empty? x => 0
+ n := getExpon frst x; refer := ref(n :: COM)
+ makeSeries(refer,iSeries(x,refer))
+
+--% values
+
+ characteristic() == characteristic()$Coef
+
+ 0 == monomial(0,0)
+ 1 == monomial(1,0)
+
+ iExtend(st,n,refer) ==
+ (elt refer) < n =>
+ explicitlyEmpty? st => (setelt(refer,plusInfinity()); st)
+ explicitEntries? st => iExtend(rst st,n,refer)
+ iExtend(lazyEvaluate st,n,refer)
+ st
+
+ extend(x,n) == (iExtend(getStream x,n :: COM,getRef x); x)
+ complete x == (iExtend(getStream x,plusInfinity(),getRef x); x)
+
+ iTruncate0(x,xRefer,refer,minExp,maxExp,n) == delay
+ explicitlyEmpty? x => (setelt(refer,plusInfinity()); empty())
+ nn := n :: COM
+ while (elt xRefer) < nn repeat lazyEvaluate x
+ explicitEntries? x =>
+ (nx := getExpon(xTerm := frst x)) > maxExp =>
+ (setelt(refer,plusInfinity()); empty())
+ setelt(refer,nx :: COM)
+ (nx :: COM) >= minExp =>
+ concat(makeTerm(nx,getCoef xTerm),_
+ iTruncate0(rst x,xRefer,refer,minExp,maxExp,nx + 1))
+ iTruncate0(rst x,xRefer,refer,minExp,maxExp,nx + 1)
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt xRefer)@I
+ setelt(refer,degr :: COM)
+ iTruncate0(x,xRefer,refer,minExp,maxExp,degr + 1)
+
+ iTruncate(ups,minExp,maxExp) ==
+ x := getStream ups; xRefer := getRef ups
+ explicitlyEmpty? x => 0
+ explicitEntries? x =>
+ deg := getExpon frst x
+ refer := ref((deg - 1) :: COM)
+ makeSeries(refer,iTruncate0(x,xRefer,refer,minExp,maxExp,deg))
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt xRefer)@I
+ refer := ref(degr :: COM)
+ makeSeries(refer,iTruncate0(x,xRefer,refer,minExp,maxExp,degr + 1))
+
+ truncate(ups,n) == iTruncate(ups,minusInfinity(),n)
+ truncate(ups,n1,n2) ==
+ if n1 > n2 then (n1,n2) := (n2,n1)
+ iTruncate(ups,n1 :: COM,n2)
+
+ iCoefficient(st,n) ==
+ explicitEntries? st =>
+ term := frst st
+ (expon := getExpon term) > n => 0
+ expon = n => getCoef term
+ iCoefficient(rst st,n)
+ 0
+
+ coefficient(x,n) == (extend(x,n); iCoefficient(getStream x,n))
+ elt(x:%,n:Integer) == coefficient(x,n)
+
+ iOrder(st,n,refer) ==
+ explicitlyEmpty? st => error "order: series has infinite order"
+ explicitEntries? st =>
+ ((r := getExpon frst st) :: COM) >= n => retract(n)@Integer
+ r
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt refer)@I
+ (degr :: COM) >= n => retract(n)@Integer
+ iOrder(lazyEvaluate st,n,refer)
+
+ order x == iOrder(getStream x,plusInfinity(),getRef x)
+ order(x,n) == iOrder(getStream x,n :: COM,getRef x)
+
+ terms x == getStream x
+
+--% predicates
+
+ zero? ups ==
+ x := getStream ups; ref := getRef ups
+ whatInfinity(n := elt ref) = 1 => explicitlyEmpty? x
+ count : NNI := _$streamCount$Lisp
+ for i in 1..count repeat
+ explicitlyEmpty? x => return true
+ explicitEntries? x => return false
+ lazyEvaluate x
+ false
+
+ ups1 = ups2 == zero?(ups1 - ups2)
+
+--% arithmetic
+
+ iMap1(cFcn,eFcn,check?,x,xRefer,refer,n) == delay
+ -- when this function is called, all terms in 'x' of order < n have been
+ -- computed and we compute the eFcn(n)th order coefficient of the result
+ explicitlyEmpty? x => (setelt(refer,plusInfinity()); empty())
+ -- if terms in 'x' up to order n have not been computed,
+ -- apply lazy evaluation
+ nn := n :: COM
+ while (elt xRefer) < nn repeat lazyEvaluate x
+ -- 'x' may now be empty: retest
+ explicitlyEmpty? x => (setelt(refer,plusInfinity()); empty())
+ -- must have nx >= n
+ explicitEntries? x =>
+ xCoef := getCoef(xTerm := frst x); nx := getExpon xTerm
+ newCoef := cFcn(xCoef,nx); m := eFcn nx
+ setelt(refer,m :: COM)
+ not check? =>
+ concat(makeTerm(m,newCoef),_
+ iMap1(cFcn,eFcn,check?,rst x,xRefer,refer,nx + 1))
+ zero? newCoef => iMap1(cFcn,eFcn,check?,rst x,xRefer,refer,nx + 1)
+ concat(makeTerm(m,newCoef),_
+ iMap1(cFcn,eFcn,check?,rst x,xRefer,refer,nx + 1))
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt xRefer)@I
+ setelt(refer,eFcn(degr) :: COM)
+ iMap1(cFcn,eFcn,check?,x,xRefer,refer,degr + 1)
+
+ iMap2(cFcn,eFcn,check?,ups) ==
+ -- 'eFcn' must be a strictly increasing function,
+ -- i.e. i < j => eFcn(i) < eFcn(j)
+ xRefer := getRef ups; x := getStream ups
+ explicitlyEmpty? x => 0
+ explicitEntries? x =>
+ deg := getExpon frst x
+ refer := ref(eFcn(deg - 1) :: COM)
+ makeSeries(refer,iMap1(cFcn,eFcn,check?,x,xRefer,refer,deg))
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt xRefer)@I
+ refer := ref(eFcn(degr) :: COM)
+ makeSeries(refer,iMap1(cFcn,eFcn,check?,x,xRefer,refer,degr + 1))
+
+ map(fcn,x) == iMap2(fcn(#1),#1,true,x)
+ differentiate x == iMap2(#2 * #1,#1 - 1,true,x)
+ multiplyCoefficients(f,x) == iMap2(f(#2) * #1,#1,true,x)
+ multiplyExponents(x,n) == iMap2(#1,n * #1,false,x)
+
+ iPlus1(op,x,xRefer,y,yRefer,refer,n) == delay
+ -- when this function is called, all terms in 'x' and 'y' of order < n
+ -- have been computed and we are computing the nth order coefficient of
+ -- the result; note the 'op' is either '+' or '-'
+ explicitlyEmpty? x => iMap1(op(0,#1),#1,false,y,yRefer,refer,n)
+ explicitlyEmpty? y => iMap1(op(#1,0),#1,false,x,xRefer,refer,n)
+ -- if terms up to order n have not been computed,
+ -- apply lazy evaluation
+ nn := n :: COM
+ while (elt xRefer) < nn repeat lazyEvaluate x
+ while (elt yRefer) < nn repeat lazyEvaluate y
+ -- 'x' or 'y' may now be empty: retest
+ explicitlyEmpty? x => iMap1(op(0,#1),#1,false,y,yRefer,refer,n)
+ explicitlyEmpty? y => iMap1(op(#1,0),#1,false,x,xRefer,refer,n)
+ -- must have nx >= n, ny >= n
+ -- both x and y have explicit terms
+ explicitEntries?(x) and explicitEntries?(y) =>
+ xCoef := getCoef(xTerm := frst x); nx := getExpon xTerm
+ yCoef := getCoef(yTerm := frst y); ny := getExpon yTerm
+ nx = ny =>
+ setelt(refer,nx :: COM)
+ zero? (coef := op(xCoef,yCoef)) =>
+ iPlus1(op,rst x,xRefer,rst y,yRefer,refer,nx + 1)
+ concat(makeTerm(nx,coef),_
+ iPlus1(op,rst x,xRefer,rst y,yRefer,refer,nx + 1))
+ nx < ny =>
+ setelt(refer,nx :: COM)
+ concat(makeTerm(nx,op(xCoef,0)),_
+ iPlus1(op,rst x,xRefer,y,yRefer,refer,nx + 1))
+ setelt(refer,ny :: COM)
+ concat(makeTerm(ny,op(0,yCoef)),_
+ iPlus1(op,x,xRefer,rst y,yRefer,refer,ny + 1))
+ -- y has no term of degree n
+ explicitEntries? x =>
+ xCoef := getCoef(xTerm := frst x); nx := getExpon xTerm
+ -- can't have elt(yRefer) = infty unless all terms have been computed
+ (degr := retract(elt yRefer)@I) < nx =>
+ setelt(refer,elt yRefer)
+ iPlus1(op,x,xRefer,y,yRefer,refer,degr + 1)
+ setelt(refer,nx :: COM)
+ concat(makeTerm(nx,op(xCoef,0)),_
+ iPlus1(op,rst x,xRefer,y,yRefer,refer,nx + 1))
+ -- x has no term of degree n
+ explicitEntries? y =>
+ yCoef := getCoef(yTerm := frst y); ny := getExpon yTerm
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ (degr := retract(elt xRefer)@I) < ny =>
+ setelt(refer,elt xRefer)
+ iPlus1(op,x,xRefer,y,yRefer,refer,degr + 1)
+ setelt(refer,ny :: COM)
+ concat(makeTerm(ny,op(0,yCoef)),_
+ iPlus1(op,x,xRefer,rst y,yRefer,refer,ny + 1))
+ -- neither x nor y has a term of degree n
+ setelt(refer,xyRef := min(elt xRefer,elt yRefer))
+ -- can't have xyRef = infty unless all terms have been computed
+ iPlus1(op,x,xRefer,y,yRefer,refer,retract(xyRef)@I + 1)
+
+ iPlus2(op,ups1,ups2) ==
+ xRefer := getRef ups1; x := getStream ups1
+ xDeg :=
+ explicitlyEmpty? x => return map(op(0$Coef,#1),ups2)
+ explicitEntries? x => (getExpon frst x) - 1
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ retract(elt xRefer)@I
+ yRefer := getRef ups2; y := getStream ups2
+ yDeg :=
+ explicitlyEmpty? y => return map(op(#1,0$Coef),ups1)
+ explicitEntries? y => (getExpon frst y) - 1
+ -- can't have elt(yRefer) = infty unless all terms have been computed
+ retract(elt yRefer)@I
+ deg := min(xDeg,yDeg); refer := ref(deg :: COM)
+ makeSeries(refer,iPlus1(op,x,xRefer,y,yRefer,refer,deg + 1))
+
+ x + y == iPlus2(#1 + #2,x,y)
+ x - y == iPlus2(#1 - #2,x,y)
+ - y == iMap2(_-#1,#1,false,y)
+
+ -- gives correct defaults for I, NNI and PI
+ n:I * x:% == (zero? n => 0; map(n * #1,x))
+ n:NNI * x:% == (zero? n => 0; map(n * #1,x))
+ n:PI * x:% == (zero? n => 0; map(n * #1,x))
+
+ productByTerm(coef,expon,x,xRefer,refer,n) ==
+ iMap1(coef * #1,#1 + expon,true,x,xRefer,refer,n)
+
+ productLazyEval(x,xRefer,y,yRefer,nn) ==
+ explicitlyEmpty?(x) or explicitlyEmpty?(y) => void()
+ explicitEntries? x =>
+ explicitEntries? y => void()
+ xDeg := (getExpon frst x) :: COM
+ while (xDeg + elt(yRefer)) < nn repeat lazyEvaluate y
+ void()
+ explicitEntries? y =>
+ yDeg := (getExpon frst y) :: COM
+ while (yDeg + elt(xRefer)) < nn repeat lazyEvaluate x
+ void()
+ lazyEvaluate x
+ -- if x = y, then y may now have explicit entries
+ if lazy? y then lazyEvaluate y
+ productLazyEval(x,xRefer,y,yRefer,nn)
+
+ iTimes(x,xRefer,y,yRefer,refer,n) == delay
+ -- when this function is called, we are computing the nth order
+ -- coefficient of the product
+ productLazyEval(x,xRefer,y,yRefer,n :: COM)
+ explicitlyEmpty?(x) or explicitlyEmpty?(y) =>
+ (setelt(refer,plusInfinity()); empty())
+ -- must have nx + ny >= n
+ explicitEntries?(x) and explicitEntries?(y) =>
+ xCoef := getCoef(xTerm := frst x); xExpon := getExpon xTerm
+ yCoef := getCoef(yTerm := frst y); yExpon := getExpon yTerm
+ expon := xExpon + yExpon
+ setelt(refer,expon :: COM)
+ scRefer := ref(expon :: COM)
+ scMult := productByTerm(xCoef,xExpon,rst y,yRefer,scRefer,yExpon + 1)
+ prRefer := ref(expon :: COM)
+ pr := iTimes(rst x,xRefer,y,yRefer,prRefer,expon + 1)
+ sm := iPlus1(#1 + #2,scMult,scRefer,pr,prRefer,refer,expon + 1)
+ zero?(coef := xCoef * yCoef) => sm
+ concat(makeTerm(expon,coef),sm)
+ explicitEntries? x =>
+ xExpon := getExpon frst x
+ -- can't have elt(yRefer) = infty unless all terms have been computed
+ degr := retract(elt yRefer)@I
+ setelt(refer,(xExpon + degr) :: COM)
+ iTimes(x,xRefer,y,yRefer,refer,xExpon + degr + 1)
+ explicitEntries? y =>
+ yExpon := getExpon frst y
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt xRefer)@I
+ setelt(refer,(yExpon + degr) :: COM)
+ iTimes(x,xRefer,y,yRefer,refer,yExpon + degr + 1)
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ xDegr := retract(elt xRefer)@I
+ yDegr := retract(elt yRefer)@I
+ setelt(refer,(xDegr + yDegr) :: COM)
+ iTimes(x,xRefer,y,yRefer,refer,xDegr + yDegr + 1)
+
+ ups1:% * ups2:% ==
+ xRefer := getRef ups1; x := getStream ups1
+ xDeg :=
+ explicitlyEmpty? x => return 0
+ explicitEntries? x => (getExpon frst x) - 1
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ retract(elt xRefer)@I
+ yRefer := getRef ups2; y := getStream ups2
+ yDeg :=
+ explicitlyEmpty? y => return 0
+ explicitEntries? y => (getExpon frst y) - 1
+ -- can't have elt(yRefer) = infty unless all terms have been computed
+ retract(elt yRefer)@I
+ deg := xDeg + yDeg + 1; refer := ref(deg :: COM)
+ makeSeries(refer,iTimes(x,xRefer,y,yRefer,refer,deg + 1))
+
+ iDivide(x,xRefer,y,yRefer,rym,m,refer,n) == delay
+ -- when this function is called, we are computing the nth order
+ -- coefficient of the result
+ explicitlyEmpty? x => (setelt(refer,plusInfinity()); empty())
+ -- if terms up to order n - m have not been computed,
+ -- apply lazy evaluation
+ nm := (n + m) :: COM
+ while (elt xRefer) < nm repeat lazyEvaluate x
+ -- 'x' may now be empty: retest
+ explicitlyEmpty? x => (setelt(refer,plusInfinity()); empty())
+ -- must have nx >= n + m
+ explicitEntries? x =>
+ newCoef := getCoef(xTerm := frst x) * rym; nx := getExpon xTerm
+ prodRefer := ref(nx :: COM)
+ prod := productByTerm(-newCoef,nx - m,rst y,yRefer,prodRefer,1)
+ sumRefer := ref(nx :: COM)
+ sum := iPlus1(#1 + #2,rst x,xRefer,prod,prodRefer,sumRefer,nx + 1)
+ setelt(refer,(nx - m) :: COM); term := makeTerm(nx - m,newCoef)
+ concat(term,iDivide(sum,sumRefer,y,yRefer,rym,m,refer,nx - m + 1))
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := retract(elt xRefer)@I
+ setelt(refer,(degr - m) :: COM)
+ iDivide(x,xRefer,y,yRefer,rym,m,refer,degr - m + 1)
+
+ divide(ups1,deg1,ups2,deg2,r) ==
+ xRefer := getRef ups1; x := getStream ups1
+ yRefer := getRef ups2; y := getStream ups2
+ refer := ref((deg1 - deg2) :: COM)
+ makeSeries(refer,iDivide(x,xRefer,y,yRefer,r,deg2,refer,deg1 - deg2 + 1))
+
+ iExquo(ups1,ups2,taylor?) ==
+ xRefer := getRef ups1; x := getStream ups1
+ yRefer := getRef ups2; y := getStream ups2
+ n : I := 0
+ -- try to find first non-zero term in y
+ -- give up after 1000 lazy evaluations
+ while not explicitEntries? y repeat
+ explicitlyEmpty? y => return "failed"
+ lazyEvaluate y
+ (n := n + 1) > 1000 => return "failed"
+ yCoef := getCoef(yTerm := frst y); ny := getExpon yTerm
+ (ry := recip yCoef) case "failed" => "failed"
+ nn := ny :: COM
+ if taylor? then
+ while (elt(xRefer) < nn) repeat
+ explicitlyEmpty? x => return 0
+ explicitEntries? x => return "failed"
+ lazyEvaluate x
+ -- check if ups2 is a monomial
+ empty? rst y => iMap2(#1 * (ry :: Coef),#1 - ny,false,ups1)
+ explicitlyEmpty? x => 0
+ nx :=
+ explicitEntries? x =>
+ ((deg := getExpon frst x) < ny) and taylor? => return "failed"
+ deg - 1
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ retract(elt xRefer)@I
+ divide(ups1,nx,ups2,ny,ry :: Coef)
+
+ taylorQuoByVar ups ==
+ iMap2(#1,#1 - 1,false,ups - monomial(coefficient(ups,0),0))
+
+ compose0(x,xRefer,y,yRefer,yOrd,y1,yn0,n0,refer,n) == delay
+ -- when this function is called, we are computing the nth order
+ -- coefficient of the composite
+ explicitlyEmpty? x => (setelt(refer,plusInfinity()); empty())
+ -- if terms in 'x' up to order n have not been computed,
+ -- apply lazy evaluation
+ nn := n :: COM; yyOrd := yOrd :: COM
+ while (yyOrd * elt(xRefer)) < nn repeat lazyEvaluate x
+ explicitEntries? x =>
+ xCoef := getCoef(xTerm := frst x); n1 := getExpon xTerm
+ zero? n1 =>
+ setelt(refer,n1 :: COM)
+ concat(makeTerm(n1,xCoef),_
+ compose0(rst x,xRefer,y,yRefer,yOrd,y1,yn0,n0,refer,n1 + 1))
+ yn1 := yn0 * y1 ** ((n1 - n0) :: NNI)
+ z := getStream yn1; zRefer := getRef yn1
+ degr := yOrd * n1; prodRefer := ref((degr - 1) :: COM)
+ prod := iMap1(xCoef * #1,#1,true,z,zRefer,prodRefer,degr)
+ coRefer := ref((degr + yOrd - 1) :: COM)
+ co := compose0(rst x,xRefer,y,yRefer,yOrd,y1,yn1,n1,coRefer,degr + yOrd)
+ setelt(refer,(degr - 1) :: COM)
+ iPlus1(#1 + #2,prod,prodRefer,co,coRefer,refer,degr)
+ -- can't have elt(xRefer) = infty unless all terms have been computed
+ degr := yOrd * (retract(elt xRefer)@I + 1)
+ setelt(refer,(degr - 1) :: COM)
+ compose0(x,xRefer,y,yRefer,yOrd,y1,yn0,n0,refer,degr)
+
+ iCompose(ups1,ups2) ==
+ x := getStream ups1; xRefer := getRef ups1
+ y := getStream ups2; yRefer := getRef ups2
+ -- try to compute the order of 'ups2'
+ n : I := _$streamCount$Lisp
+ for i in 1..n while not explicitEntries? y repeat
+ explicitlyEmpty? y => coefficient(ups1,0) :: %
+ lazyEvaluate y
+ explicitlyEmpty? y => coefficient(ups1,0) :: %
+ yOrd : I :=
+ explicitEntries? y => getExpon frst y
+ retract(elt yRefer)@I
+ compRefer := ref((-1) :: COM)
+ makeSeries(compRefer,_
+ compose0(x,xRefer,y,yRefer,yOrd,ups2,1,0,compRefer,0))
+
+ if Coef has Algebra Fraction Integer then
+
+ integrate x == iMap2(1/(#2 + 1) * #1,#1 + 1,true,x)
+
+--% Fixed point computations
+
+ Ys ==> Y$ParadoxicalCombinatorsForStreams(Term)
+
+ integ0: (ST,REF,REF,I) -> ST
+ integ0(x,intRef,ansRef,n) == delay
+ nLess1 := (n - 1) :: COM
+ while (elt intRef) < nLess1 repeat lazyEvaluate x
+ explicitlyEmpty? x => (setelt(ansRef,plusInfinity()); empty())
+ explicitEntries? x =>
+ xCoef := getCoef(xTerm := frst x); nx := getExpon xTerm
+ setelt(ansRef,(n1 := (nx + 1)) :: COM)
+ concat(makeTerm(n1,inv(n1 :: RN) * xCoef),_
+ integ0(rst x,intRef,ansRef,n1))
+ -- can't have elt(intRef) = infty unless all terms have been computed
+ degr := retract(elt intRef)@I; setelt(ansRef,(degr + 1) :: COM)
+ integ0(x,intRef,ansRef,degr + 2)
+
+ integ1: (ST,REF,REF) -> ST
+ integ1(x,intRef,ansRef) == integ0(x,intRef,ansRef,1)
+
+ lazyInteg: (Coef,() -> ST,REF,REF) -> ST
+ lazyInteg(a,xf,intRef,ansRef) ==
+ ansStr : ST := integ1(delay xf,intRef,ansRef)
+ concat(makeTerm(0,a),ansStr)
+
+ cPower(f,r) ==
+ -- computes f^r. f should have constant coefficient 1.
+ fp := differentiate f
+ fInv := iExquo(1,f,false) :: %; y := r * fp * fInv
+ yRef := getRef y; yStr := getStream y
+ intRef := ref((-1) :: COM); ansRef := ref(0 :: COM)
+ ansStr := Ys lazyInteg(1,iTimes(#1,ansRef,yStr,yRef,intRef,0),_
+ intRef,ansRef)
+ makeSeries(ansRef,ansStr)
+
+ iExp: (%,Coef) -> %
+ iExp(f,cc) ==
+ -- computes exp(f). cc = exp coefficient(f,0)
+ fp := differentiate f
+ fpRef := getRef fp; fpStr := getStream fp
+ intRef := ref((-1) :: COM); ansRef := ref(0 :: COM)
+ ansStr := Ys lazyInteg(cc,iTimes(#1,ansRef,fpStr,fpRef,intRef,0),_
+ intRef,ansRef)
+ makeSeries(ansRef,ansStr)
+
+ sincos0: (Coef,Coef,L ST,REF,REF,ST,REF,ST,REF) -> L ST
+ sincos0(sinc,cosc,list,sinRef,cosRef,fpStr,fpRef,fpStr2,fpRef2) ==
+ sinStr := first list; cosStr := second list
+ prodRef1 := ref((-1) :: COM); prodRef2 := ref((-1) :: COM)
+ prodStr1 := iTimes(cosStr,cosRef,fpStr,fpRef,prodRef1,0)
+ prodStr2 := iTimes(sinStr,sinRef,fpStr2,fpRef2,prodRef2,0)
+ [lazyInteg(sinc,prodStr1,prodRef1,sinRef),_
+ lazyInteg(cosc,prodStr2,prodRef2,cosRef)]
+
+ iSincos: (%,Coef,Coef,I) -> Record(%sin: %, %cos: %)
+ iSincos(f,sinc,cosc,sign) ==
+ fp := differentiate f
+ fpRef := getRef fp; fpStr := getStream fp
+-- fp2 := (one? sign => fp; -fp)
+ fp2 := ((sign = 1) => fp; -fp)
+ fpRef2 := getRef fp2; fpStr2 := getStream fp2
+ sinRef := ref(0 :: COM); cosRef := ref(0 :: COM)
+ sincos :=
+ Ys(sincos0(sinc,cosc,#1,sinRef,cosRef,fpStr,fpRef,fpStr2,fpRef2),2)
+ sinStr := (zero? sinc => rst first sincos; first sincos)
+ cosStr := (zero? cosc => rst second sincos; second sincos)
+ [makeSeries(sinRef,sinStr),makeSeries(cosRef,cosStr)]
+
+ tan0: (Coef,ST,REF,ST,REF,I) -> ST
+ tan0(cc,ansStr,ansRef,fpStr,fpRef,sign) ==
+ sqRef := ref((-1) :: COM)
+ sqStr := iTimes(ansStr,ansRef,ansStr,ansRef,sqRef,0)
+ one : % := 1; oneStr := getStream one; oneRef := getRef one
+ yRef := ref((-1) :: COM)
+ yStr : ST :=
+-- one? sign => iPlus1(#1 + #2,oneStr,oneRef,sqStr,sqRef,yRef,0)
+ (sign = 1) => iPlus1(#1 + #2,oneStr,oneRef,sqStr,sqRef,yRef,0)
+ iPlus1(#1 - #2,oneStr,oneRef,sqStr,sqRef,yRef,0)
+ intRef := ref((-1) :: COM)
+ lazyInteg(cc,iTimes(yStr,yRef,fpStr,fpRef,intRef,0),intRef,ansRef)
+
+ iTan: (%,%,Coef,I) -> %
+ iTan(f,fp,cc,sign) ==
+ -- computes the tangent (and related functions) of f.
+ fpRef := getRef fp; fpStr := getStream fp
+ ansRef := ref(0 :: COM)
+ ansStr := Ys tan0(cc,#1,ansRef,fpStr,fpRef,sign)
+ zero? cc => makeSeries(ansRef,rst ansStr)
+ makeSeries(ansRef,ansStr)
+
+--% Error Reporting
+
+ TRCONST : SG := "series expansion involves transcendental constants"
+ NPOWERS : SG := "series expansion has terms of negative degree"
+ FPOWERS : SG := "series expansion has terms of fractional degree"
+ MAYFPOW : SG := "series expansion may have terms of fractional degree"
+ LOGS : SG := "series expansion has logarithmic term"
+ NPOWLOG : SG :=
+ "series expansion has terms of negative degree or logarithmic term"
+ NOTINV : SG := "leading coefficient not invertible"
+
+--% Rational powers and transcendental functions
+
+ orderOrFailed : % -> Union(I,"failed")
+ orderOrFailed uts ==
+ -- returns the order of x or "failed"
+ -- if -1 is returned, the series is identically zero
+ x := getStream uts
+ for n in 0..1000 repeat
+ explicitlyEmpty? x => return -1
+ explicitEntries? x => return getExpon frst x
+ lazyEvaluate x
+ "failed"
+
+ RATPOWERS : Boolean := Coef has "**": (Coef,RN) -> Coef
+ TRANSFCN : Boolean := Coef has TranscendentalFunctionCategory
+
+ cRationalPower(uts,r) ==
+ (ord0 := orderOrFailed uts) case "failed" =>
+ error "**: series with many leading zero coefficients"
+ order := ord0 :: I
+ (n := order exquo denom(r)) case "failed" =>
+ error "**: rational power does not exist"
+ cc := coefficient(uts,order)
+ (ccInv := recip cc) case "failed" => error concat("**: ",NOTINV)
+ ccPow :=
+-- one? cc => cc
+ (cc = 1) => cc
+-- one? denom r =>
+ (denom r) = 1 =>
+ not negative?(num := numer r) => cc ** (num :: NNI)
+ (ccInv :: Coef) ** ((-num) :: NNI)
+ RATPOWERS => cc ** r
+ error "** rational power of coefficient undefined"
+ uts1 := (ccInv :: Coef) * uts
+ uts2 := uts1 * monomial(1,-order)
+ monomial(ccPow,(n :: I) * numer(r)) * cPower(uts2,r :: Coef)
+
+ cExp uts ==
+ zero?(cc := coefficient(uts,0)) => iExp(uts,1)
+ TRANSFCN => iExp(uts,exp cc)
+ error concat("exp: ",TRCONST)
+
+ cLog uts ==
+ zero?(cc := coefficient(uts,0)) =>
+ error "log: constant coefficient should not be 0"
+-- one? cc => integrate(differentiate(uts) * (iExquo(1,uts,true) :: %))
+ (cc = 1) => integrate(differentiate(uts) * (iExquo(1,uts,true) :: %))
+ TRANSFCN =>
+ y := iExquo(1,uts,true) :: %
+ (log(cc) :: %) + integrate(y * differentiate(uts))
+ error concat("log: ",TRCONST)
+
+ sincos: % -> Record(%sin: %, %cos: %)
+ sincos uts ==
+ zero?(cc := coefficient(uts,0)) => iSincos(uts,0,1,-1)
+ TRANSFCN => iSincos(uts,sin cc,cos cc,-1)
+ error concat("sincos: ",TRCONST)
+
+ cSin uts == sincos(uts).%sin
+ cCos uts == sincos(uts).%cos
+
+ cTan uts ==
+ zero?(cc := coefficient(uts,0)) => iTan(uts,differentiate uts,0,1)
+ TRANSFCN => iTan(uts,differentiate uts,tan cc,1)
+ error concat("tan: ",TRCONST)
+
+ cCot uts ==
+ zero? uts => error "cot: cot(0) is undefined"
+ zero?(cc := coefficient(uts,0)) => error error concat("cot: ",NPOWERS)
+ TRANSFCN => iTan(uts,-differentiate uts,cot cc,1)
+ error concat("cot: ",TRCONST)
+
+ cSec uts ==
+ zero?(cc := coefficient(uts,0)) => iExquo(1,cCos uts,true) :: %
+ TRANSFCN =>
+ cosUts := cCos uts
+ zero? coefficient(cosUts,0) => error concat("sec: ",NPOWERS)
+ iExquo(1,cosUts,true) :: %
+ error concat("sec: ",TRCONST)
+
+ cCsc uts ==
+ zero? uts => error "csc: csc(0) is undefined"
+ TRANSFCN =>
+ sinUts := cSin uts
+ zero? coefficient(sinUts,0) => error concat("csc: ",NPOWERS)
+ iExquo(1,sinUts,true) :: %
+ error concat("csc: ",TRCONST)
+
+ cAsin uts ==
+ zero?(cc := coefficient(uts,0)) =>
+ integrate(cRationalPower(1 - uts*uts,-1/2) * differentiate(uts))
+ TRANSFCN =>
+ x := 1 - uts * uts
+ cc = 1 or cc = -1 =>
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asin: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asin(cc) :: %
+ odd? order => error concat("asin: ",FPOWERS)
+ c0 := asin(cc) :: %
+ c0 + integrate(cRationalPower(x,-1/2) * differentiate(uts))
+ c0 := asin(cc) :: %
+ c0 + integrate(cRationalPower(x,-1/2) * differentiate(uts))
+ error concat("asin: ",TRCONST)
+
+ cAcos uts ==
+ zero? uts =>
+ TRANSFCN => acos(0)$Coef :: %
+ error concat("acos: ",TRCONST)
+ TRANSFCN =>
+ x := 1 - uts * uts
+ cc := coefficient(uts,0)
+ cc = 1 or cc = -1 =>
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acos: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acos(cc) :: %
+ odd? order => error concat("acos: ",FPOWERS)
+ c0 := acos(cc) :: %
+ c0 + integrate(-cRationalPower(x,-1/2) * differentiate(uts))
+ c0 := acos(cc) :: %
+ c0 + integrate(-cRationalPower(x,-1/2) * differentiate(uts))
+ error concat("acos: ",TRCONST)
+
+ cAtan uts ==
+ zero?(cc := coefficient(uts,0)) =>
+ y := iExquo(1,(1 :: %) + uts*uts,true) :: %
+ integrate(y * (differentiate uts))
+ TRANSFCN =>
+ (y := iExquo(1,(1 :: %) + uts*uts,true)) case "failed" =>
+ error concat("atan: ",LOGS)
+ (atan(cc) :: %) + integrate((y :: %) * (differentiate uts))
+ error concat("atan: ",TRCONST)
+
+ cAcot uts ==
+ TRANSFCN =>
+ (y := iExquo(1,(1 :: %) + uts*uts,true)) case "failed" =>
+ error concat("acot: ",LOGS)
+ cc := coefficient(uts,0)
+ (acot(cc) :: %) + integrate(-(y :: %) * (differentiate uts))
+ error concat("acot: ",TRCONST)
+
+ cAsec uts ==
+ zero?(cc := coefficient(uts,0)) =>
+ error "asec: constant coefficient should not be 0"
+ TRANSFCN =>
+ x := uts * uts - 1
+ y :=
+ cc = 1 or cc = -1 =>
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asec: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asec(cc) :: %
+ odd? order => error concat("asec: ",FPOWERS)
+ cRationalPower(x,-1/2) * differentiate(uts)
+ cRationalPower(x,-1/2) * differentiate(uts)
+ (z := iExquo(y,uts,true)) case "failed" =>
+ error concat("asec: ",NOTINV)
+ (asec(cc) :: %) + integrate(z :: %)
+ error concat("asec: ",TRCONST)
+
+ cAcsc uts ==
+ zero?(cc := coefficient(uts,0)) =>
+ error "acsc: constant coefficient should not be 0"
+ TRANSFCN =>
+ x := uts * uts - 1
+ y :=
+ cc = 1 or cc = -1 =>
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acsc: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acsc(cc) :: %
+ odd? order => error concat("acsc: ",FPOWERS)
+ -cRationalPower(x,-1/2) * differentiate(uts)
+ -cRationalPower(x,-1/2) * differentiate(uts)
+ (z := iExquo(y,uts,true)) case "failed" =>
+ error concat("asec: ",NOTINV)
+ (acsc(cc) :: %) + integrate(z :: %)
+ error concat("acsc: ",TRCONST)
+
+ sinhcosh: % -> Record(%sinh: %, %cosh: %)
+ sinhcosh uts ==
+ zero?(cc := coefficient(uts,0)) =>
+ tmp := iSincos(uts,0,1,1)
+ [tmp.%sin,tmp.%cos]
+ TRANSFCN =>
+ tmp := iSincos(uts,sinh cc,cosh cc,1)
+ [tmp.%sin,tmp.%cos]
+ error concat("sinhcosh: ",TRCONST)
+
+ cSinh uts == sinhcosh(uts).%sinh
+ cCosh uts == sinhcosh(uts).%cosh
+
+ cTanh uts ==
+ zero?(cc := coefficient(uts,0)) => iTan(uts,differentiate uts,0,-1)
+ TRANSFCN => iTan(uts,differentiate uts,tanh cc,-1)
+ error concat("tanh: ",TRCONST)
+
+ cCoth uts ==
+ tanhUts := cTanh uts
+ zero? tanhUts => error "coth: coth(0) is undefined"
+ zero? coefficient(tanhUts,0) => error concat("coth: ",NPOWERS)
+ iExquo(1,tanhUts,true) :: %
+
+ cSech uts ==
+ coshUts := cCosh uts
+ zero? coefficient(coshUts,0) => error concat("sech: ",NPOWERS)
+ iExquo(1,coshUts,true) :: %
+
+ cCsch uts ==
+ sinhUts := cSinh uts
+ zero? coefficient(sinhUts,0) => error concat("csch: ",NPOWERS)
+ iExquo(1,sinhUts,true) :: %
+
+ cAsinh uts ==
+ x := 1 + uts * uts
+ zero?(cc := coefficient(uts,0)) => cLog(uts + cRationalPower(x,1/2))
+ TRANSFCN =>
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asinh: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asinh(cc) :: %
+ odd? order => error concat("asinh: ",FPOWERS)
+ -- the argument to 'log' must have a non-zero constant term
+ cLog(uts + cRationalPower(x,1/2))
+ error concat("asinh: ",TRCONST)
+
+ cAcosh uts ==
+ zero? uts =>
+ TRANSFCN => acosh(0)$Coef :: %
+ error concat("acosh: ",TRCONST)
+ TRANSFCN =>
+ cc := coefficient(uts,0); x := uts*uts - 1
+ cc = 1 or cc = -1 =>
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acosh: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acosh(cc) :: %
+ odd? order => error concat("acosh: ",FPOWERS)
+ -- the argument to 'log' must have a non-zero constant term
+ cLog(uts + cRationalPower(x,1/2))
+ cLog(uts + cRationalPower(x,1/2))
+ error concat("acosh: ",TRCONST)
+
+ cAtanh uts ==
+ half := inv(2 :: RN) :: Coef
+ zero?(cc := coefficient(uts,0)) =>
+ half * (cLog(1 + uts) - cLog(1 - uts))
+ TRANSFCN =>
+ cc = 1 or cc = -1 => error concat("atanh: ",LOGS)
+ half * (cLog(1 + uts) - cLog(1 - uts))
+ error concat("atanh: ",TRCONST)
+
+ cAcoth uts ==
+ zero? uts =>
+ TRANSFCN => acoth(0)$Coef :: %
+ error concat("acoth: ",TRCONST)
+ TRANSFCN =>
+ cc := coefficient(uts,0); half := inv(2 :: RN) :: Coef
+ cc = 1 or cc = -1 => error concat("acoth: ",LOGS)
+ half * (cLog(uts + 1) - cLog(uts - 1))
+ error concat("acoth: ",TRCONST)
+
+ cAsech uts ==
+ zero? uts => error "asech: asech(0) is undefined"
+ TRANSFCN =>
+ zero?(cc := coefficient(uts,0)) =>
+ error concat("asech: ",NPOWLOG)
+ x := 1 - uts * uts
+ cc = 1 or cc = -1 =>
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("asech: ",MAYFPOW)
+ (order := ord :: I) = -1 => return asech(cc) :: %
+ odd? order => error concat("asech: ",FPOWERS)
+ (utsInv := iExquo(1,uts,true)) case "failed" =>
+ error concat("asech: ",NOTINV)
+ cLog((1 + cRationalPower(x,1/2)) * (utsInv :: %))
+ (utsInv := iExquo(1,uts,true)) case "failed" =>
+ error concat("asech: ",NOTINV)
+ cLog((1 + cRationalPower(x,1/2)) * (utsInv :: %))
+ error concat("asech: ",TRCONST)
+
+ cAcsch uts ==
+ zero? uts => error "acsch: acsch(0) is undefined"
+ TRANSFCN =>
+ zero?(cc := coefficient(uts,0)) => error concat("acsch: ",NPOWLOG)
+ x := uts * uts + 1
+ -- compute order of 'x'
+ (ord := orderOrFailed x) case "failed" =>
+ error concat("acsc: ",MAYFPOW)
+ (order := ord :: I) = -1 => return acsch(cc) :: %
+ odd? order => error concat("acsch: ",FPOWERS)
+ (utsInv := iExquo(1,uts,true)) case "failed" =>
+ error concat("acsch: ",NOTINV)
+ cLog((1 + cRationalPower(x,1/2)) * (utsInv :: %))
+ error concat("acsch: ",TRCONST)
+
+--% Output forms
+
+ -- check a global Lisp variable
+ factorials?() == false
+
+ termOutput(k,c,vv) ==
+ -- creates a term c * vv ** k
+ k = 0 => c :: OUT
+ mon := (k = 1 => vv; vv ** (k :: OUT))
+-- if factorials?() and k > 1 then
+-- c := factorial(k)$IntegerCombinatoricFunctions * c
+-- mon := mon / hconcat(k :: OUT,"!" :: OUT)
+ c = 1 => mon
+ c = -1 => -mon
+ (c :: OUT) * mon
+
+ -- check a global Lisp variable
+ showAll?() == true
+
+ seriesToOutputForm(st,refer,var,cen,r) ==
+ vv :=
+ zero? cen => var :: OUT
+ paren(var :: OUT - cen :: OUT)
+ l : L OUT := empty()
+ while explicitEntries? st repeat
+ term := frst st
+ l := concat(termOutput(getExpon(term) * r,getCoef term,vv),l)
+ st := rst st
+ l :=
+ explicitlyEmpty? st => l
+ (deg := retractIfCan(elt refer)@Union(I,"failed")) case I =>
+ concat(prefix("O" :: OUT,[vv ** ((((deg :: I) + 1) * r) :: OUT)]),l)
+ l
+ empty? l => (0$Coef) :: OUT
+ reduce("+",reverse_! l)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ISUPS InnerSparseUnivariatePowerSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/supxs.spad.pamphlet b/src/algebra/supxs.spad.pamphlet
new file mode 100644
index 00000000..311d6cd6
--- /dev/null
+++ b/src/algebra/supxs.spad.pamphlet
@@ -0,0 +1,142 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra supxs.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SUPXS SparseUnivariatePuiseuxSeries}
+<<domain SUPXS SparseUnivariatePuiseuxSeries>>=
+)abbrev domain SUPXS SparseUnivariatePuiseuxSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 11 November 1994
+++ Date Last Updated: 28 February 1995
+++ Basic Operations:
+++ Related Domains: InnerSparseUnivariatePowerSeries,
+++ SparseUnivariateTaylorSeries, SparseUnivariateLaurentSeries
+++ Also See:
+++ AMS Classifications:
+++ Keywords: sparse, series
+++ Examples:
+++ References:
+++ Description: Sparse Puiseux series in one variable
+++ \spadtype{SparseUnivariatePuiseuxSeries} is a domain representing Puiseux
+++ series in one variable with coefficients in an arbitrary ring. The
+++ parameters of the type specify the coefficient ring, the power series
+++ variable, and the center of the power series expansion. For example,
+++ \spad{SparseUnivariatePuiseuxSeries(Integer,x,3)} represents Puiseux
+++ series in \spad{(x - 3)} with \spadtype{Integer} coefficients.
+SparseUnivariatePuiseuxSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ RN ==> Fraction Integer
+ SUTS ==> SparseUnivariateTaylorSeries(Coef,var,cen)
+ SULS ==> SparseUnivariateLaurentSeries(Coef,var,cen)
+ SUPS ==> InnerSparseUnivariatePowerSeries(Coef)
+
+ Exports ==> Join(UnivariatePuiseuxSeriesConstructorCategory(Coef,SULS),_
+ RetractableTo SUTS) with
+ coerce: Variable(var) -> %
+ ++ coerce(var) converts the series variable \spad{var} into a
+ ++ Puiseux series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} returns the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x))} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> UnivariatePuiseuxSeriesConstructor(Coef,SULS) add
+
+ Rep := Record(expon:RN,lSeries:SULS)
+
+ getExpon: % -> RN
+ getExpon pxs == pxs.expon
+
+ variable x == var
+ center x == cen
+
+ coerce(v: Variable(var)) ==
+ zero? cen => monomial(1,1)
+ monomial(1,1) + monomial(cen,0)
+
+ coerce(uts:SUTS) == uts :: SULS :: %
+
+ retractIfCan(upxs:%):Union(SUTS,"failed") ==
+ (uls := retractIfCan(upxs)@Union(SULS,"failed")) case "failed" =>
+ "failed"
+ retractIfCan(uls :: SULS)@Union(SUTS,"failed")
+
+ if Coef has "*": (Fraction Integer, Coef) -> Coef then
+ differentiate(upxs:%,v:Variable(var)) == differentiate upxs
+
+ if Coef has Algebra Fraction Integer then
+ integrate(upxs:%,v:Variable(var)) == integrate upxs
+
+--% OutputForms
+
+ coerce(x:%): OUT ==
+ sups : SUPS := laurentRep(x) pretend SUPS
+ st := getStream sups; refer := getRef sups
+ if not(explicitlyEmpty? st or explicitEntries? st) _
+ and (nx := retractIfCan(elt refer)@Union(I,"failed")) case I then
+ count : NNI := _$streamCount$Lisp
+ degr := min(count,(nx :: I) + count + 1)
+ extend(sups,degr)
+ seriesToOutputForm(st,refer,variable x,center x,rationalPower x)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SUPXS SparseUnivariatePuiseuxSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/suts.spad.pamphlet b/src/algebra/suts.spad.pamphlet
new file mode 100644
index 00000000..131d99b4
--- /dev/null
+++ b/src/algebra/suts.spad.pamphlet
@@ -0,0 +1,439 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra suts.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SUTS SparseUnivariateTaylorSeries}
+<<domain SUTS SparseUnivariateTaylorSeries>>=
+)abbrev domain SUTS SparseUnivariateTaylorSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 16 February 1990
+++ Date Last Updated: 10 March 1995
+++ Basic Operations:
+++ Related Domains: InnerSparseUnivariatePowerSeries,
+++ SparseUnivariateLaurentSeries, SparseUnivariatePuiseuxSeries
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, sparse power series
+++ Examples:
+++ References:
+++ Description: Sparse Taylor series in one variable
+++ \spadtype{SparseUnivariateTaylorSeries} is a domain representing Taylor
+++ series in one variable with coefficients in an arbitrary ring. The
+++ parameters of the type specify the coefficient ring, the power series
+++ variable, and the center of the power series expansion. For example,
+++ \spadtype{SparseUnivariateTaylorSeries}(Integer,x,3) represents Taylor
+++ series in \spad{(x - 3)} with \spadtype{Integer} coefficients.
+SparseUnivariateTaylorSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ COM ==> OrderedCompletion Integer
+ I ==> Integer
+ L ==> List
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ P ==> Polynomial Coef
+ REF ==> Reference OrderedCompletion Integer
+ RN ==> Fraction Integer
+ Term ==> Record(k:Integer,c:Coef)
+ SG ==> String
+ ST ==> Stream Term
+ UP ==> UnivariatePolynomial(var,Coef)
+
+ Exports ==> UnivariateTaylorSeriesCategory(Coef) with
+ coerce: UP -> %
+ ++\spad{coerce(p)} converts a univariate polynomial p in the variable
+ ++\spad{var} to a univariate Taylor series in \spad{var}.
+ univariatePolynomial: (%,NNI) -> UP
+ ++\spad{univariatePolynomial(f,k)} returns a univariate polynomial
+ ++ consisting of the sum of all terms of f of degree \spad{<= k}.
+ coerce: Variable(var) -> %
+ ++\spad{coerce(var)} converts the series variable \spad{var} into a
+ ++ Taylor series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} computes the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x),x)} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> InnerSparseUnivariatePowerSeries(Coef) add
+ import REF
+
+ Rep := InnerSparseUnivariatePowerSeries(Coef)
+
+ makeTerm: (Integer,Coef) -> Term
+ makeTerm(exp,coef) == [exp,coef]
+ getCoef: Term -> Coef
+ getCoef term == term.c
+ getExpon: Term -> Integer
+ getExpon term == term.k
+
+ monomial(coef,expon) == monomial(coef,expon)$Rep
+ extend(x,n) == extend(x,n)$Rep
+
+ 0 == monomial(0,0)$Rep
+ 1 == monomial(1,0)$Rep
+
+ recip uts == iExquo(1,uts,true)
+
+ if Coef has IntegralDomain then
+ uts1 exquo uts2 == iExquo(uts1,uts2,true)
+
+ quoByVar uts == taylorQuoByVar(uts)$Rep
+
+ differentiate(x:%,v:Variable(var)) == differentiate x
+
+--% Creation and destruction of series
+
+ coerce(v: Variable(var)) ==
+ zero? cen => monomial(1,1)
+ monomial(1,1) + monomial(cen,0)
+
+ coerce(p:UP) ==
+ zero? p => 0
+ if not zero? cen then p := p(monomial(1,1)$UP + monomial(cen,0)$UP)
+ st : ST := empty()
+ while not zero? p repeat
+ st := concat(makeTerm(degree p,leadingCoefficient p),st)
+ p := reductum p
+ makeSeries(ref plusInfinity(),st)
+
+ univariatePolynomial(x,n) ==
+ extend(x,n); st := getStream x
+ ans : UP := 0; oldDeg : I := 0;
+ mon := monomial(1,1)$UP - monomial(center x,0)$UP; monPow : UP := 1
+ while explicitEntries? st repeat
+ (xExpon := getExpon(xTerm := frst st)) > n => return ans
+ pow := (xExpon - oldDeg) :: NNI; oldDeg := xExpon
+ monPow := monPow * mon ** pow
+ ans := ans + getCoef(xTerm) * monPow
+ st := rst st
+ ans
+
+ polynomial(x,n) ==
+ extend(x,n); st := getStream x
+ ans : P := 0; oldDeg : I := 0;
+ mon := (var :: P) - (center(x) :: P); monPow : P := 1
+ while explicitEntries? st repeat
+ (xExpon := getExpon(xTerm := frst st)) > n => return ans
+ pow := (xExpon - oldDeg) :: NNI; oldDeg := xExpon
+ monPow := monPow * mon ** pow
+ ans := ans + getCoef(xTerm) * monPow
+ st := rst st
+ ans
+
+ polynomial(x,n1,n2) == polynomial(truncate(x,n1,n2),n2)
+
+ truncate(x,n) == truncate(x,n)$Rep
+ truncate(x,n1,n2) == truncate(x,n1,n2)$Rep
+
+ iCoefficients: (ST,REF,I) -> Stream Coef
+ iCoefficients(x,refer,n) == delay
+ -- when this function is called, we are computing the nth order
+ -- coefficient of the series
+ explicitlyEmpty? x => empty()
+ -- if terms up to order n have not been computed,
+ -- apply lazy evaluation
+ nn := n :: COM
+ while (nx := elt refer) < nn repeat lazyEvaluate x
+ -- must have nx >= n
+ explicitEntries? x =>
+ xCoef := getCoef(xTerm := frst x); xExpon := getExpon xTerm
+ xExpon = n => concat(xCoef,iCoefficients(rst x,refer,n + 1))
+ -- must have nx > n
+ concat(0,iCoefficients(x,refer,n + 1))
+ concat(0,iCoefficients(x,refer,n + 1))
+
+ coefficients uts ==
+ refer := getRef uts; x := getStream uts
+ iCoefficients(x,refer,0)
+
+ terms uts == terms(uts)$Rep pretend Stream Record(k:NNI,c:Coef)
+
+ iSeries: (Stream Coef,I,REF) -> ST
+ iSeries(st,n,refer) == delay
+ -- when this function is called, we are creating the nth order
+ -- term of a series
+ empty? st => (setelt(refer,plusInfinity()); empty())
+ setelt(refer,n :: COM)
+ zero? (coef := frst st) => iSeries(rst st,n + 1,refer)
+ concat(makeTerm(n,coef),iSeries(rst st,n + 1,refer))
+
+ series(st:Stream Coef) ==
+ refer := ref(-1)
+ makeSeries(refer,iSeries(st,0,refer))
+
+ nniToI: Stream Record(k:NNI,c:Coef) -> ST
+ nniToI st ==
+ empty? st => empty()
+ term : Term := [(frst st).k,(frst st).c]
+ concat(term,nniToI rst st)
+
+ series(st:Stream Record(k:NNI,c:Coef)) == series(nniToI st)$Rep
+
+--% Values
+
+ variable x == var
+ center x == cen
+
+ coefficient(x,n) == coefficient(x,n)$Rep
+ elt(x:%,n:NonNegativeInteger) == coefficient(x,n)
+
+ pole? x == false
+
+ order x == (order(x)$Rep) :: NNI
+ order(x,n) == (order(x,n)$Rep) :: NNI
+
+--% Composition
+
+ elt(uts1:%,uts2:%) ==
+ zero? uts2 => coefficient(uts1,0) :: %
+ not zero? coefficient(uts2,0) =>
+ error "elt: second argument must have positive order"
+ iCompose(uts1,uts2)
+
+--% Integration
+
+ if Coef has Algebra Fraction Integer then
+
+ integrate(x:%,v:Variable(var)) == integrate x
+
+--% Transcendental functions
+
+ (uts1:%) ** (uts2:%) == exp(log(uts1) * uts2)
+
+ if Coef has CommutativeRing then
+
+ (uts:%) ** (r:RN) == cRationalPower(uts,r)
+
+ exp uts == cExp uts
+ log uts == cLog uts
+
+ sin uts == cSin uts
+ cos uts == cCos uts
+ tan uts == cTan uts
+ cot uts == cCot uts
+ sec uts == cSec uts
+ csc uts == cCsc uts
+
+ asin uts == cAsin uts
+ acos uts == cAcos uts
+ atan uts == cAtan uts
+ acot uts == cAcot uts
+ asec uts == cAsec uts
+ acsc uts == cAcsc uts
+
+ sinh uts == cSinh uts
+ cosh uts == cCosh uts
+ tanh uts == cTanh uts
+ coth uts == cCoth uts
+ sech uts == cSech uts
+ csch uts == cCsch uts
+
+ asinh uts == cAsinh uts
+ acosh uts == cAcosh uts
+ atanh uts == cAtanh uts
+ acoth uts == cAcoth uts
+ asech uts == cAsech uts
+ acsch uts == cAcsch uts
+
+ else
+
+ ZERO : SG := "series must have constant coefficient zero"
+ ONE : SG := "series must have constant coefficient one"
+ NPOWERS : SG := "series expansion has terms of negative degree"
+
+ (uts:%) ** (r:RN) ==
+-- not one? coefficient(uts,0) =>
+ not (coefficient(uts,0) = 1) =>
+ error "**: constant coefficient must be one"
+ onePlusX : % := monomial(1,0) + monomial(1,1)
+ ratPow := cPower(uts,r :: Coef)
+ iCompose(ratPow,uts - 1)
+
+ exp uts ==
+ zero? coefficient(uts,0) =>
+ expx := cExp monomial(1,1)
+ iCompose(expx,uts)
+ error concat("exp: ",ZERO)
+
+ log uts ==
+-- one? coefficient(uts,0) =>
+ (coefficient(uts,0) = 1) =>
+ log1PlusX := cLog(monomial(1,0) + monomial(1,1))
+ iCompose(log1PlusX,uts - 1)
+ error concat("log: ",ONE)
+
+ sin uts ==
+ zero? coefficient(uts,0) =>
+ sinx := cSin monomial(1,1)
+ iCompose(sinx,uts)
+ error concat("sin: ",ZERO)
+
+ cos uts ==
+ zero? coefficient(uts,0) =>
+ cosx := cCos monomial(1,1)
+ iCompose(cosx,uts)
+ error concat("cos: ",ZERO)
+
+ tan uts ==
+ zero? coefficient(uts,0) =>
+ tanx := cTan monomial(1,1)
+ iCompose(tanx,uts)
+ error concat("tan: ",ZERO)
+
+ cot uts ==
+ zero? uts => error "cot: cot(0) is undefined"
+ zero? coefficient(uts,0) => error concat("cot: ",NPOWERS)
+ error concat("cot: ",ZERO)
+
+ sec uts ==
+ zero? coefficient(uts,0) =>
+ secx := cSec monomial(1,1)
+ iCompose(secx,uts)
+ error concat("sec: ",ZERO)
+
+ csc uts ==
+ zero? uts => error "csc: csc(0) is undefined"
+ zero? coefficient(uts,0) => error concat("csc: ",NPOWERS)
+ error concat("csc: ",ZERO)
+
+ asin uts ==
+ zero? coefficient(uts,0) =>
+ asinx := cAsin monomial(1,1)
+ iCompose(asinx,uts)
+ error concat("asin: ",ZERO)
+
+ atan uts ==
+ zero? coefficient(uts,0) =>
+ atanx := cAtan monomial(1,1)
+ iCompose(atanx,uts)
+ error concat("atan: ",ZERO)
+
+ acos z == error "acos: acos undefined on this coefficient domain"
+ acot z == error "acot: acot undefined on this coefficient domain"
+ asec z == error "asec: asec undefined on this coefficient domain"
+ acsc z == error "acsc: acsc undefined on this coefficient domain"
+
+ sinh uts ==
+ zero? coefficient(uts,0) =>
+ sinhx := cSinh monomial(1,1)
+ iCompose(sinhx,uts)
+ error concat("sinh: ",ZERO)
+
+ cosh uts ==
+ zero? coefficient(uts,0) =>
+ coshx := cCosh monomial(1,1)
+ iCompose(coshx,uts)
+ error concat("cosh: ",ZERO)
+
+ tanh uts ==
+ zero? coefficient(uts,0) =>
+ tanhx := cTanh monomial(1,1)
+ iCompose(tanhx,uts)
+ error concat("tanh: ",ZERO)
+
+ coth uts ==
+ zero? uts => error "coth: coth(0) is undefined"
+ zero? coefficient(uts,0) => error concat("coth: ",NPOWERS)
+ error concat("coth: ",ZERO)
+
+ sech uts ==
+ zero? coefficient(uts,0) =>
+ sechx := cSech monomial(1,1)
+ iCompose(sechx,uts)
+ error concat("sech: ",ZERO)
+
+ csch uts ==
+ zero? uts => error "csch: csch(0) is undefined"
+ zero? coefficient(uts,0) => error concat("csch: ",NPOWERS)
+ error concat("csch: ",ZERO)
+
+ asinh uts ==
+ zero? coefficient(uts,0) =>
+ asinhx := cAsinh monomial(1,1)
+ iCompose(asinhx,uts)
+ error concat("asinh: ",ZERO)
+
+ atanh uts ==
+ zero? coefficient(uts,0) =>
+ atanhx := cAtanh monomial(1,1)
+ iCompose(atanhx,uts)
+ error concat("atanh: ",ZERO)
+
+ acosh uts == error "acosh: acosh undefined on this coefficient domain"
+ acoth uts == error "acoth: acoth undefined on this coefficient domain"
+ asech uts == error "asech: asech undefined on this coefficient domain"
+ acsch uts == error "acsch: acsch undefined on this coefficient domain"
+
+ if Coef has Field then
+ if Coef has Algebra Fraction Integer then
+
+ (uts:%) ** (r:Coef) ==
+-- not one? coefficient(uts,1) =>
+ not (coefficient(uts,1) = 1) =>
+ error "**: constant coefficient should be 1"
+ cPower(uts,r)
+
+--% OutputForms
+
+ coerce(x:%): OUT ==
+ count : NNI := _$streamCount$Lisp
+ extend(x,count)
+ seriesToOutputForm(getStream x,getRef x,variable x,center x,1)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SUTS SparseUnivariateTaylorSeries>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/symbol.spad.pamphlet b/src/algebra/symbol.spad.pamphlet
new file mode 100644
index 00000000..96382e7b
--- /dev/null
+++ b/src/algebra/symbol.spad.pamphlet
@@ -0,0 +1,462 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra symbol.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain SYMBOL Symbol}
+<<domain SYMBOL Symbol>>=
+)abbrev domain SYMBOL Symbol
+++ Author: Stephen Watt
+++ Date Created: 1986
+++ Date Last Updated: 7 Mar 1991, 29 Apr. 1994 (FDLL)
+++ Description:
+++ Basic and scripted symbols.
+++ Keywords: symbol.
+Symbol(): Exports == Implementation where
+ L ==> List OutputForm
+ Scripts ==> Record(sub:L,sup:L,presup:L,presub:L,args:L)
+
+ Exports ==> Join(OrderedSet, ConvertibleTo InputForm, OpenMath,
+ ConvertibleTo Symbol,
+ ConvertibleTo Pattern Integer, ConvertibleTo Pattern Float,
+ PatternMatchable Integer, PatternMatchable Float) with
+ new: () -> %
+ ++ new() returns a new symbol whose name starts with %.
+ new: % -> %
+ ++ new(s) returns a new symbol whose name starts with %s.
+ resetNew: () -> Void
+ ++ resetNew() resets the internals counters that new() and
+ ++ new(s) use to return distinct symbols every time.
+ coerce: String -> %
+ ++ coerce(s) converts the string s to a symbol.
+ name: % -> %
+ ++ name(s) returns s without its scripts.
+ scripted?: % -> Boolean
+ ++ scripted?(s) is true if s has been given any scripts.
+ scripts: % -> Scripts
+ ++ scripts(s) returns all the scripts of s.
+ script: (%, List L) -> %
+ ++ script(s, [a,b,c,d,e]) returns s with subscripts a,
+ ++ superscripts b, pre-superscripts c, pre-subscripts d,
+ ++ and argument-scripts e. Omitted components are taken to be empty.
+ ++ For example, \spad{script(s, [a,b,c])} is equivalent to
+ ++ \spad{script(s,[a,b,c,[],[]])}.
+ script: (%, Scripts) -> %
+ ++ script(s, [a,b,c,d,e]) returns s with subscripts a,
+ ++ superscripts b, pre-superscripts c, pre-subscripts d,
+ ++ and argument-scripts e.
+ subscript: (%, L) -> %
+ ++ subscript(s, [a1,...,an]) returns s
+ ++ subscripted by \spad{[a1,...,an]}.
+ superscript: (%, L) -> %
+ ++ superscript(s, [a1,...,an]) returns s
+ ++ superscripted by \spad{[a1,...,an]}.
+ argscript: (%, L) -> %
+ ++ argscript(s, [a1,...,an]) returns s
+ ++ arg-scripted by \spad{[a1,...,an]}.
+ elt: (%, L) -> %
+ ++ elt(s,[a1,...,an]) or s([a1,...,an]) returns s subscripted by \spad{[a1,...,an]}.
+ string: % -> String
+ ++ string(s) converts the symbol s to a string.
+ ++ Error: if the symbol is subscripted.
+ list: % -> List %
+ ++ list(sy) takes a scripted symbol and produces a list
+ ++ of the name followed by the scripts.
+ sample: constant -> %
+ ++ sample() returns a sample of %
+
+ Implementation ==> add
+ count: Reference(Integer) := ref 0
+ xcount: AssociationList(%, Integer) := empty()
+ istrings:PrimitiveArray(String) :=
+ construct ["0","1","2","3","4","5","6","7","8","9"]
+ -- the following 3 strings shall be of empty intersection
+ nums:String:="0123456789"
+ ALPHAS:String:="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ alphas:String:="abcdefghijklmnopqrstuvwxyz"
+
+ writeOMSym(dev: OpenMathDevice, x: %): Void ==
+ scripted? x =>
+ error "Cannot convert a scripted symbol to OpenMath"
+ OMputVariable(dev, x pretend Symbol)
+
+ OMwrite(x: %): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ OMputObject(dev)
+ writeOMSym(dev, x)
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(x: %, wholeObj: Boolean): String ==
+ s: String := ""
+ sp := OM_-STRINGTOSTRINGPTR(s)$Lisp
+ dev: OpenMathDevice := OMopenString(sp pretend String, OMencodingXML)
+ if wholeObj then
+ OMputObject(dev)
+ writeOMSym(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+ OMclose(dev)
+ s := OM_-STRINGPTRTOSTRING(sp)$Lisp pretend String
+ s
+
+ OMwrite(dev: OpenMathDevice, x: %): Void ==
+ OMputObject(dev)
+ writeOMSym(dev, x)
+ OMputEndObject(dev)
+
+ OMwrite(dev: OpenMathDevice, x: %, wholeObj: Boolean): Void ==
+ if wholeObj then
+ OMputObject(dev)
+ writeOMSym(dev, x)
+ if wholeObj then
+ OMputEndObject(dev)
+
+ hd:String := "*"
+ lhd := #hd
+ ord0 := ord char("0")$Character
+
+ istring : Integer -> String
+ syprefix : Scripts -> String
+ syscripts: Scripts -> L
+
+ convert(s:%):InputForm == convert(s pretend Symbol)$InputForm
+ convert(s:%):Symbol == s pretend Symbol
+ coerce(s:String):% == VALUES(INTERN(s)$Lisp)$Lisp
+ x = y == EQUAL(x,y)$Lisp
+ x < y == GGREATERP(y, x)$Lisp
+ coerce(x:%):OutputForm == outputForm(x pretend Symbol)
+ subscript(sy, lx) == script(sy, [lx, nil, nil(), nil(), nil()])
+ elt(sy,lx) == subscript(sy,lx)
+ superscript(sy, lx) == script(sy,[nil(),lx, nil(), nil(), nil()])
+ argscript(sy, lx) == script(sy,[nil(),nil(), nil(), nil(), lx])
+
+ patternMatch(x:%,p:Pattern Integer,l:PatternMatchResult(Integer,%))==
+ (patternMatch(x pretend Symbol, p, l pretend
+ PatternMatchResult(Integer, Symbol))$PatternMatchSymbol(Integer))
+ pretend PatternMatchResult(Integer, %)
+
+ patternMatch(x:%, p:Pattern Float, l:PatternMatchResult(Float, %)) ==
+ (patternMatch(x pretend Symbol, p, l pretend
+ PatternMatchResult(Float, Symbol))$PatternMatchSymbol(Float))
+ pretend PatternMatchResult(Float, %)
+
+ convert(x:%):Pattern(Float) ==
+ coerce(x pretend Symbol)$Pattern(Float)
+
+ convert(x:%):Pattern(Integer) ==
+ coerce(x pretend Symbol)$Pattern(Integer)
+
+ syprefix sc ==
+ ns: List Integer := [#sc.presub, #sc.presup, #sc.sup, #sc.sub]
+ while #ns >= 2 and zero? first ns repeat ns := rest ns
+ concat concat(concat(hd, istring(#sc.args)),
+ [istring n for n in reverse_! ns])
+
+ syscripts sc ==
+ all := sc.presub
+ all := concat(sc.presup, all)
+ all := concat(sc.sup, all)
+ all := concat(sc.sub, all)
+ concat(all, sc.args)
+
+ script(sy: %, ls: List L) ==
+ sc: Scripts := [nil(), nil(), nil(), nil(), nil()]
+ if not null ls then (sc.sub := first ls; ls := rest ls)
+ if not null ls then (sc.sup := first ls; ls := rest ls)
+ if not null ls then (sc.presup := first ls; ls := rest ls)
+ if not null ls then (sc.presub := first ls; ls := rest ls)
+ if not null ls then (sc.args := first ls; ls := rest ls)
+ script(sy, sc)
+
+ script(sy: %, sc: Scripts) ==
+ scripted? sy => error "Cannot add scripts to a scripted symbol"
+ (concat(concat(syprefix sc, string name sy)::%::OutputForm,
+ syscripts sc)) pretend %
+
+ string e ==
+ not scripted? e => PNAME(e)$Lisp
+ error "Cannot form string from non-atomic symbols."
+
+-- Scripts ==> Record(sub:L,sup:L,presup:L,presub:L,args:L)
+ latex e ==
+ s : String := (PNAME(name e)$Lisp) pretend String
+ if #s > 1 and s.1 ^= char "\" then
+ s := concat("\mbox{\it ", concat(s, "}")$String)$String
+ not scripted? e => s
+ ss : Scripts := scripts e
+ lo : List OutputForm := ss.sub
+ sc : String
+ if not empty? lo then
+ sc := "__{"
+ while not empty? lo repeat
+ sc := concat(sc, latex first lo)$String
+ lo := rest lo
+ if not empty? lo then sc := concat(sc, ", ")$String
+ sc := concat(sc, "}")$String
+ s := concat(s, sc)$String
+ lo := ss.sup
+ if not empty? lo then
+ sc := "^{"
+ while not empty? lo repeat
+ sc := concat(sc, latex first lo)$String
+ lo := rest lo
+ if not empty? lo then sc := concat(sc, ", ")$String
+ sc := concat(sc, "}")$String
+ s := concat(s, sc)$String
+ lo := ss.presup
+ if not empty? lo then
+ sc := "{}^{"
+ while not empty? lo repeat
+ sc := concat(sc, latex first lo)$String
+ lo := rest lo
+ if not empty? lo then sc := concat(sc, ", ")$String
+ sc := concat(sc, "}")$String
+ s := concat(sc, s)$String
+ lo := ss.presub
+ if not empty? lo then
+ sc := "{}__{"
+ while not empty? lo repeat
+ sc := concat(sc, latex first lo)$String
+ lo := rest lo
+ if not empty? lo then sc := concat(sc, ", ")$String
+ sc := concat(sc, "}")$String
+ s := concat(sc, s)$String
+ lo := ss.args
+ if not empty? lo then
+ sc := "\left( {"
+ while not empty? lo repeat
+ sc := concat(sc, latex first lo)$String
+ lo := rest lo
+ if not empty? lo then sc := concat(sc, ", ")$String
+ sc := concat(sc, "} \right)")$String
+ s := concat(s, sc)$String
+ s
+
+ anyRadix(n:Integer,s:String):String ==
+ ns:String:=""
+ repeat
+ qr := divide(n,#s)
+ n := qr.quotient
+ ns := concat(s.(qr.remainder+minIndex s),ns)
+ if zero?(n) then return ns
+
+ new() ==
+ sym := anyRadix(count()::Integer,ALPHAS)
+ count() := count() + 1
+ concat("%",sym)::%
+
+ new x ==
+ n:Integer :=
+ (u := search(x, xcount)) case "failed" => 0
+ inc(u::Integer)
+ xcount(x) := n
+ xx :=
+ not scripted? x => string x
+ string name x
+ xx := concat("%",xx)
+ xx :=
+ (position(xx.maxIndex(xx),nums)>=minIndex(nums)) =>
+ concat(xx, anyRadix(n,alphas))
+ concat(xx, anyRadix(n,nums))
+ not scripted? x => xx::%
+ script(xx::%,scripts x)
+
+ resetNew() ==
+ count() := 0
+ for k in keys xcount repeat remove_!(k, xcount)
+ void
+
+ scripted? sy ==
+ not ATOM(sy)$Lisp
+
+ name sy ==
+ not scripted? sy => sy
+ str := string first list sy
+ for i in lhd+1..#str repeat
+ not digit?(str.i) => return((str.(i..#str))::%)
+ error "Improper scripted symbol"
+
+ scripts sy ==
+ not scripted? sy => [nil(), nil(), nil(), nil(), nil()]
+ nscripts: List NonNegativeInteger := [0, 0, 0, 0, 0]
+ lscripts: List L := [nil(), nil(), nil(), nil(), nil()]
+ str := string first list sy
+ nstr := #str
+ m := minIndex nscripts
+ for i in m.. for j in lhd+1..nstr while digit?(str.j) repeat
+ nscripts.i := (ord(str.j) - ord0)::NonNegativeInteger
+ -- Put the number of function scripts at the end.
+ nscripts := concat(rest nscripts, first nscripts)
+ allscripts := rest list sy
+ m := minIndex lscripts
+ for i in m.. for n in nscripts repeat
+ #allscripts < n => error "Improper script count in symbol"
+ lscripts.i := [a::OutputForm for a in first(allscripts, n)]
+ allscripts := rest(allscripts, n)
+ [lscripts.m, lscripts.(m+1), lscripts.(m+2),
+ lscripts.(m+3), lscripts.(m+4)]
+
+ istring n ==
+ n > 9 => error "Can have at most 9 scripts of each kind"
+ istrings.(n + minIndex istrings)
+
+ list sy ==
+ not scripted? sy =>
+ error "Cannot convert a symbol to a list if it is not subscripted"
+ sy pretend List(%)
+
+ sample() == "aSymbol"::%
+
+@
+\section{SYMBOL.lsp BOOTSTRAP}
+{\bf SYMBOL} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf SYMBOL} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf SYMBOL.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<SYMBOL.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |SYMBOL;writeOMSym| (|dev| |x| |$|) (COND ((SPADCALL |x| (QREFELT |$| 21)) (|error| "Cannot convert a scripted symbol to OpenMath")) ((QUOTE T) (SPADCALL |dev| |x| (QREFELT |$| 25)))))
+
+(DEFUN |SYMBOL;OMwrite;$S;2| (|x| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |SYMBOL;OMwrite;$S;2|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |SYMBOL;OMwrite;$S;2|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 27)) (QREFELT |$| 29)) |SYMBOL;OMwrite;$S;2|) (SPADCALL |dev| (QREFELT |$| 30)) (|SYMBOL;writeOMSym| |dev| |x| |$|) (SPADCALL |dev| (QREFELT |$| 31)) (SPADCALL |dev| (QREFELT |$| 32)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |SYMBOL;OMwrite;$S;2|) (EXIT |s|)))))
+
+(DEFUN |SYMBOL;OMwrite;$BS;3| (|x| |wholeObj| |$|) (PROG (|sp| |dev| |s|) (RETURN (SEQ (LETT |s| "" |SYMBOL;OMwrite;$BS;3|) (LETT |sp| (|OM-STRINGTOSTRINGPTR| |s|) |SYMBOL;OMwrite;$BS;3|) (LETT |dev| (SPADCALL |sp| (SPADCALL (QREFELT |$| 27)) (QREFELT |$| 29)) |SYMBOL;OMwrite;$BS;3|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 30)))) (|SYMBOL;writeOMSym| |dev| |x| |$|) (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 31)))) (SPADCALL |dev| (QREFELT |$| 32)) (LETT |s| (|OM-STRINGPTRTOSTRING| |sp|) |SYMBOL;OMwrite;$BS;3|) (EXIT |s|)))))
+
+(DEFUN |SYMBOL;OMwrite;Omd$V;4| (|dev| |x| |$|) (SEQ (SPADCALL |dev| (QREFELT |$| 30)) (|SYMBOL;writeOMSym| |dev| |x| |$|) (EXIT (SPADCALL |dev| (QREFELT |$| 31)))))
+
+(DEFUN |SYMBOL;OMwrite;Omd$BV;5| (|dev| |x| |wholeObj| |$|) (SEQ (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 30)))) (|SYMBOL;writeOMSym| |dev| |x| |$|) (EXIT (COND (|wholeObj| (SPADCALL |dev| (QREFELT |$| 31)))))))
+
+(DEFUN |SYMBOL;convert;$If;6| (|s| |$|) (SPADCALL |s| (QREFELT |$| 44)))
+
+(PUT (QUOTE |SYMBOL;convert;2$;7|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|s|) |s|)))
+
+(DEFUN |SYMBOL;convert;2$;7| (|s| |$|) |s|)
+
+(DEFUN |SYMBOL;coerce;S$;8| (|s| |$|) (VALUES (INTERN |s|)))
+
+(PUT (QUOTE |SYMBOL;=;2$B;9|) (QUOTE |SPADreplace|) (QUOTE EQUAL))
+
+(DEFUN |SYMBOL;=;2$B;9| (|x| |y| |$|) (EQUAL |x| |y|))
+
+(PUT (QUOTE |SYMBOL;<;2$B;10|) (QUOTE |SPADreplace|) (QUOTE (XLAM (|x| |y|) (GGREATERP |y| |x|))))
+
+(DEFUN |SYMBOL;<;2$B;10| (|x| |y| |$|) (GGREATERP |y| |x|))
+
+(DEFUN |SYMBOL;coerce;$Of;11| (|x| |$|) (SPADCALL |x| (QREFELT |$| 51)))
+
+(DEFUN |SYMBOL;subscript;$L$;12| (|sy| |lx| |$|) (SPADCALL |sy| (LIST |lx| NIL NIL NIL NIL) (QREFELT |$| 54)))
+
+(DEFUN |SYMBOL;elt;$L$;13| (|sy| |lx| |$|) (SPADCALL |sy| |lx| (QREFELT |$| 56)))
+
+(DEFUN |SYMBOL;superscript;$L$;14| (|sy| |lx| |$|) (SPADCALL |sy| (LIST NIL |lx| NIL NIL NIL) (QREFELT |$| 54)))
+
+(DEFUN |SYMBOL;argscript;$L$;15| (|sy| |lx| |$|) (SPADCALL |sy| (LIST NIL NIL NIL NIL |lx|) (QREFELT |$| 54)))
+
+(DEFUN |SYMBOL;patternMatch;$P2Pmr;16| (|x| |p| |l| |$|) (SPADCALL |x| |p| |l| (QREFELT |$| 63)))
+
+(DEFUN |SYMBOL;patternMatch;$P2Pmr;17| (|x| |p| |l| |$|) (SPADCALL |x| |p| |l| (QREFELT |$| 69)))
+
+(DEFUN |SYMBOL;convert;$P;18| (|x| |$|) (SPADCALL |x| (QREFELT |$| 72)))
+
+(DEFUN |SYMBOL;convert;$P;19| (|x| |$|) (SPADCALL |x| (QREFELT |$| 74)))
+
+(DEFUN |SYMBOL;syprefix| (|sc| |$|) (PROG (|ns| #1=#:G108218 |n| #2=#:G108219) (RETURN (SEQ (LETT |ns| (LIST (LENGTH (QVELT |sc| 3)) (LENGTH (QVELT |sc| 2)) (LENGTH (QVELT |sc| 1)) (LENGTH (QVELT |sc| 0))) |SYMBOL;syprefix|) (SEQ G190 (COND ((NULL (COND ((|<| (LENGTH |ns|) 2) (QUOTE NIL)) ((QUOTE T) (ZEROP (|SPADfirst| |ns|))))) (GO G191))) (SEQ (EXIT (LETT |ns| (CDR |ns|) |SYMBOL;syprefix|))) NIL (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL (CONS (STRCONC (QREFELT |$| 37) (|SYMBOL;istring| (LENGTH (QVELT |sc| 4)) |$|)) (PROGN (LETT #1# NIL |SYMBOL;syprefix|) (SEQ (LETT |n| NIL |SYMBOL;syprefix|) (LETT #2# (NREVERSE |ns|) |SYMBOL;syprefix|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |n| (CAR #2#) |SYMBOL;syprefix|) NIL)) (GO G191))) (SEQ (EXIT (LETT #1# (CONS (|SYMBOL;istring| |n| |$|) #1#) |SYMBOL;syprefix|))) (LETT #2# (CDR #2#) |SYMBOL;syprefix|) (GO G190) G191 (EXIT (NREVERSE0 #1#))))) (QREFELT |$| 77)))))))
+
+(DEFUN |SYMBOL;syscripts| (|sc| |$|) (PROG (|all|) (RETURN (SEQ (LETT |all| (QVELT |sc| 3) |SYMBOL;syscripts|) (LETT |all| (SPADCALL (QVELT |sc| 2) |all| (QREFELT |$| 78)) |SYMBOL;syscripts|) (LETT |all| (SPADCALL (QVELT |sc| 1) |all| (QREFELT |$| 78)) |SYMBOL;syscripts|) (LETT |all| (SPADCALL (QVELT |sc| 0) |all| (QREFELT |$| 78)) |SYMBOL;syscripts|) (EXIT (SPADCALL |all| (QVELT |sc| 4) (QREFELT |$| 78)))))))
+
+(DEFUN |SYMBOL;script;$L$;22| (|sy| |ls| |$|) (PROG (|sc|) (RETURN (SEQ (LETT |sc| (VECTOR NIL NIL NIL NIL NIL) |SYMBOL;script;$L$;22|) (COND ((NULL (NULL |ls|)) (SEQ (QSETVELT |sc| 0 (|SPADfirst| |ls|)) (EXIT (LETT |ls| (CDR |ls|) |SYMBOL;script;$L$;22|))))) (COND ((NULL (NULL |ls|)) (SEQ (QSETVELT |sc| 1 (|SPADfirst| |ls|)) (EXIT (LETT |ls| (CDR |ls|) |SYMBOL;script;$L$;22|))))) (COND ((NULL (NULL |ls|)) (SEQ (QSETVELT |sc| 2 (|SPADfirst| |ls|)) (EXIT (LETT |ls| (CDR |ls|) |SYMBOL;script;$L$;22|))))) (COND ((NULL (NULL |ls|)) (SEQ (QSETVELT |sc| 3 (|SPADfirst| |ls|)) (EXIT (LETT |ls| (CDR |ls|) |SYMBOL;script;$L$;22|))))) (COND ((NULL (NULL |ls|)) (SEQ (QSETVELT |sc| 4 (|SPADfirst| |ls|)) (EXIT (LETT |ls| (CDR |ls|) |SYMBOL;script;$L$;22|))))) (EXIT (SPADCALL |sy| |sc| (QREFELT |$| 80)))))))
+
+(DEFUN |SYMBOL;script;$R$;23| (|sy| |sc| |$|) (COND ((SPADCALL |sy| (QREFELT |$| 21)) (|error| "Cannot add scripts to a scripted symbol")) ((QUOTE T) (CONS (SPADCALL (SPADCALL (STRCONC (|SYMBOL;syprefix| |sc| |$|) (SPADCALL (SPADCALL |sy| (QREFELT |$| 81)) (QREFELT |$| 82))) (QREFELT |$| 47)) (QREFELT |$| 52)) (|SYMBOL;syscripts| |sc| |$|)))))
+
+(DEFUN |SYMBOL;string;$S;24| (|e| |$|) (COND ((NULL (SPADCALL |e| (QREFELT |$| 21))) (PNAME |e|)) ((QUOTE T) (|error| "Cannot form string from non-atomic symbols."))))
+
+(DEFUN |SYMBOL;latex;$S;25| (|e| |$|) (PROG (|ss| |lo| |sc| |s|) (RETURN (SEQ (LETT |s| (PNAME (SPADCALL |e| (QREFELT |$| 81))) |SYMBOL;latex;$S;25|) (COND ((|<| 1 (QCSIZE |s|)) (COND ((NULL (SPADCALL (SPADCALL |s| 1 (QREFELT |$| 83)) (SPADCALL "\\" (QREFELT |$| 40)) (QREFELT |$| 84))) (LETT |s| (STRCONC "\\mbox{\\it " (STRCONC |s| "}")) |SYMBOL;latex;$S;25|))))) (COND ((NULL (SPADCALL |e| (QREFELT |$| 21))) (EXIT |s|))) (LETT |ss| (SPADCALL |e| (QREFELT |$| 85)) |SYMBOL;latex;$S;25|) (LETT |lo| (QVELT |ss| 0) |SYMBOL;latex;$S;25|) (COND ((NULL (NULL |lo|)) (SEQ (LETT |sc| "_{" |SYMBOL;latex;$S;25|) (SEQ G190 (COND ((NULL (COND ((NULL |lo|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |sc| (STRCONC |sc| (SPADCALL (|SPADfirst| |lo|) (QREFELT |$| 86))) |SYMBOL;latex;$S;25|) (LETT |lo| (CDR |lo|) |SYMBOL;latex;$S;25|) (EXIT (COND ((NULL (NULL |lo|)) (LETT |sc| (STRCONC |sc| ", ") |SYMBOL;latex;$S;25|))))) NIL (GO G190) G191 (EXIT NIL)) (LETT |sc| (STRCONC |sc| "}") |SYMBOL;latex;$S;25|) (EXIT (LETT |s| (STRCONC |s| |sc|) |SYMBOL;latex;$S;25|))))) (LETT |lo| (QVELT |ss| 1) |SYMBOL;latex;$S;25|) (COND ((NULL (NULL |lo|)) (SEQ (LETT |sc| "^{" |SYMBOL;latex;$S;25|) (SEQ G190 (COND ((NULL (COND ((NULL |lo|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |sc| (STRCONC |sc| (SPADCALL (|SPADfirst| |lo|) (QREFELT |$| 86))) |SYMBOL;latex;$S;25|) (LETT |lo| (CDR |lo|) |SYMBOL;latex;$S;25|) (EXIT (COND ((NULL (NULL |lo|)) (LETT |sc| (STRCONC |sc| ", ") |SYMBOL;latex;$S;25|))))) NIL (GO G190) G191 (EXIT NIL)) (LETT |sc| (STRCONC |sc| "}") |SYMBOL;latex;$S;25|) (EXIT (LETT |s| (STRCONC |s| |sc|) |SYMBOL;latex;$S;25|))))) (LETT |lo| (QVELT |ss| 2) |SYMBOL;latex;$S;25|) (COND ((NULL (NULL |lo|)) (SEQ (LETT |sc| "{}^{" |SYMBOL;latex;$S;25|) (SEQ G190 (COND ((NULL (COND ((NULL |lo|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |sc| (STRCONC |sc| (SPADCALL (|SPADfirst| |lo|) (QREFELT |$| 86))) |SYMBOL;latex;$S;25|) (LETT |lo| (CDR |lo|) |SYMBOL;latex;$S;25|) (EXIT (COND ((NULL (NULL |lo|)) (LETT |sc| (STRCONC |sc| ", ") |SYMBOL;latex;$S;25|))))) NIL (GO G190) G191 (EXIT NIL)) (LETT |sc| (STRCONC |sc| "}") |SYMBOL;latex;$S;25|) (EXIT (LETT |s| (STRCONC |sc| |s|) |SYMBOL;latex;$S;25|))))) (LETT |lo| (QVELT |ss| 3) |SYMBOL;latex;$S;25|) (COND ((NULL (NULL |lo|)) (SEQ (LETT |sc| "{}_{" |SYMBOL;latex;$S;25|) (SEQ G190 (COND ((NULL (COND ((NULL |lo|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |sc| (STRCONC |sc| (SPADCALL (|SPADfirst| |lo|) (QREFELT |$| 86))) |SYMBOL;latex;$S;25|) (LETT |lo| (CDR |lo|) |SYMBOL;latex;$S;25|) (EXIT (COND ((NULL (NULL |lo|)) (LETT |sc| (STRCONC |sc| ", ") |SYMBOL;latex;$S;25|))))) NIL (GO G190) G191 (EXIT NIL)) (LETT |sc| (STRCONC |sc| "}") |SYMBOL;latex;$S;25|) (EXIT (LETT |s| (STRCONC |sc| |s|) |SYMBOL;latex;$S;25|))))) (LETT |lo| (QVELT |ss| 4) |SYMBOL;latex;$S;25|) (COND ((NULL (NULL |lo|)) (SEQ (LETT |sc| "\\left( {" |SYMBOL;latex;$S;25|) (SEQ G190 (COND ((NULL (COND ((NULL |lo|) (QUOTE NIL)) ((QUOTE T) (QUOTE T)))) (GO G191))) (SEQ (LETT |sc| (STRCONC |sc| (SPADCALL (|SPADfirst| |lo|) (QREFELT |$| 86))) |SYMBOL;latex;$S;25|) (LETT |lo| (CDR |lo|) |SYMBOL;latex;$S;25|) (EXIT (COND ((NULL (NULL |lo|)) (LETT |sc| (STRCONC |sc| ", ") |SYMBOL;latex;$S;25|))))) NIL (GO G190) G191 (EXIT NIL)) (LETT |sc| (STRCONC |sc| "} \\right)") |SYMBOL;latex;$S;25|) (EXIT (LETT |s| (STRCONC |s| |sc|) |SYMBOL;latex;$S;25|))))) (EXIT |s|)))))
+
+(DEFUN |SYMBOL;anyRadix| (|n| |s| |$|) (PROG (|qr| |ns| #1=#:G108274) (RETURN (SEQ (EXIT (SEQ (LETT |ns| "" |SYMBOL;anyRadix|) (EXIT (SEQ G190 NIL (SEQ (LETT |qr| (DIVIDE2 |n| (QCSIZE |s|)) |SYMBOL;anyRadix|) (LETT |n| (QCAR |qr|) |SYMBOL;anyRadix|) (LETT |ns| (SPADCALL (SPADCALL |s| (|+| (QCDR |qr|) (SPADCALL |s| (QREFELT |$| 88))) (QREFELT |$| 83)) |ns| (QREFELT |$| 89)) |SYMBOL;anyRadix|) (EXIT (COND ((ZEROP |n|) (PROGN (LETT #1# |ns| |SYMBOL;anyRadix|) (GO #1#)))))) NIL (GO G190) G191 (EXIT NIL))))) #1# (EXIT #1#)))))
+
+(DEFUN |SYMBOL;new;$;27| (|$|) (PROG (|sym|) (RETURN (SEQ (LETT |sym| (|SYMBOL;anyRadix| (SPADCALL (QREFELT |$| 9) (QREFELT |$| 90)) (QREFELT |$| 18) |$|) |SYMBOL;new;$;27|) (SPADCALL (QREFELT |$| 9) (|+| (SPADCALL (QREFELT |$| 9) (QREFELT |$| 90)) 1) (QREFELT |$| 91)) (EXIT (SPADCALL (STRCONC "%" |sym|) (QREFELT |$| 47)))))))
+
+(DEFUN |SYMBOL;new;2$;28| (|x| |$|) (PROG (|u| |n| |xx|) (RETURN (SEQ (LETT |n| (SEQ (LETT |u| (SPADCALL |x| (QREFELT |$| 12) (QREFELT |$| 94)) |SYMBOL;new;2$;28|) (EXIT (COND ((QEQCAR |u| 1) 0) ((QUOTE T) (|+| (QCDR |u|) 1))))) |SYMBOL;new;2$;28|) (SPADCALL (QREFELT |$| 12) |x| |n| (QREFELT |$| 95)) (LETT |xx| (COND ((NULL (SPADCALL |x| (QREFELT |$| 21))) (SPADCALL |x| (QREFELT |$| 82))) ((QUOTE T) (SPADCALL (SPADCALL |x| (QREFELT |$| 81)) (QREFELT |$| 82)))) |SYMBOL;new;2$;28|) (LETT |xx| (STRCONC "%" |xx|) |SYMBOL;new;2$;28|) (LETT |xx| (COND ((NULL (|<| (SPADCALL (SPADCALL |xx| (SPADCALL |xx| (QREFELT |$| 96)) (QREFELT |$| 83)) (QREFELT |$| 17) (QREFELT |$| 97)) (SPADCALL (QREFELT |$| 17) (QREFELT |$| 88)))) (STRCONC |xx| (|SYMBOL;anyRadix| |n| (QREFELT |$| 19) |$|))) ((QUOTE T) (STRCONC |xx| (|SYMBOL;anyRadix| |n| (QREFELT |$| 17) |$|)))) |SYMBOL;new;2$;28|) (COND ((NULL (SPADCALL |x| (QREFELT |$| 21))) (EXIT (SPADCALL |xx| (QREFELT |$| 47))))) (EXIT (SPADCALL (SPADCALL |xx| (QREFELT |$| 47)) (SPADCALL |x| (QREFELT |$| 85)) (QREFELT |$| 80)))))))
+
+(DEFUN |SYMBOL;resetNew;V;29| (|$|) (PROG (|k| #1=#:G108297) (RETURN (SEQ (SPADCALL (QREFELT |$| 9) 0 (QREFELT |$| 91)) (SEQ (LETT |k| NIL |SYMBOL;resetNew;V;29|) (LETT #1# (SPADCALL (QREFELT |$| 12) (QREFELT |$| 100)) |SYMBOL;resetNew;V;29|) G190 (COND ((OR (ATOM #1#) (PROGN (LETT |k| (CAR #1#) |SYMBOL;resetNew;V;29|) NIL)) (GO G191))) (SEQ (EXIT (SPADCALL |k| (QREFELT |$| 12) (QREFELT |$| 101)))) (LETT #1# (CDR #1#) |SYMBOL;resetNew;V;29|) (GO G190) G191 (EXIT NIL)) (EXIT (SPADCALL (QREFELT |$| 102)))))))
+
+(DEFUN |SYMBOL;scripted?;$B;30| (|sy| |$|) (COND ((ATOM |sy|) (QUOTE NIL)) ((QUOTE T) (QUOTE T))))
+
+(DEFUN |SYMBOL;name;2$;31| (|sy| |$|) (PROG (|str| |i| #1=#:G108304 #2=#:G108303 #3=#:G108301) (RETURN (SEQ (EXIT (COND ((NULL (SPADCALL |sy| (QREFELT |$| 21))) |sy|) ((QUOTE T) (SEQ (LETT |str| (SPADCALL (SPADCALL (SPADCALL |sy| (QREFELT |$| 104)) (QREFELT |$| 105)) (QREFELT |$| 82)) |SYMBOL;name;2$;31|) (SEQ (EXIT (SEQ (LETT |i| (|+| (QREFELT |$| 38) 1) |SYMBOL;name;2$;31|) (LETT #1# (QCSIZE |str|) |SYMBOL;name;2$;31|) G190 (COND ((|>| |i| #1#) (GO G191))) (SEQ (EXIT (COND ((NULL (SPADCALL (SPADCALL |str| |i| (QREFELT |$| 83)) (QREFELT |$| 106))) (PROGN (LETT #3# (PROGN (LETT #2# (SPADCALL (SPADCALL |str| (SPADCALL |i| (QCSIZE |str|) (QREFELT |$| 108)) (QREFELT |$| 109)) (QREFELT |$| 47)) |SYMBOL;name;2$;31|) (GO #2#)) |SYMBOL;name;2$;31|) (GO #3#)))))) (LETT |i| (|+| |i| 1) |SYMBOL;name;2$;31|) (GO G190) G191 (EXIT NIL))) #3# (EXIT #3#)) (EXIT (|error| "Improper scripted symbol")))))) #2# (EXIT #2#)))))
+
+(DEFUN |SYMBOL;scripts;$R;32| (|sy| |$|) (PROG (|lscripts| |str| |nstr| |j| #1=#:G108307 |nscripts| |m| |n| #2=#:G108316 |i| #3=#:G108317 |a| #4=#:G108318 |allscripts|) (RETURN (SEQ (COND ((NULL (SPADCALL |sy| (QREFELT |$| 21))) (VECTOR NIL NIL NIL NIL NIL)) ((QUOTE T) (SEQ (LETT |nscripts| (LIST 0 0 0 0 0) |SYMBOL;scripts;$R;32|) (LETT |lscripts| (LIST NIL NIL NIL NIL NIL) |SYMBOL;scripts;$R;32|) (LETT |str| (SPADCALL (SPADCALL (SPADCALL |sy| (QREFELT |$| 104)) (QREFELT |$| 105)) (QREFELT |$| 82)) |SYMBOL;scripts;$R;32|) (LETT |nstr| (QCSIZE |str|) |SYMBOL;scripts;$R;32|) (LETT |m| (SPADCALL |nscripts| (QREFELT |$| 111)) |SYMBOL;scripts;$R;32|) (SEQ (LETT |j| (|+| (QREFELT |$| 38) 1) |SYMBOL;scripts;$R;32|) (LETT |i| |m| |SYMBOL;scripts;$R;32|) G190 (COND ((OR (|>| |j| |nstr|) (NULL (SPADCALL (SPADCALL |str| |j| (QREFELT |$| 83)) (QREFELT |$| 106)))) (GO G191))) (SEQ (EXIT (SPADCALL |nscripts| |i| (PROG1 (LETT #1# (|-| (SPADCALL (SPADCALL |str| |j| (QREFELT |$| 83)) (QREFELT |$| 41)) (QREFELT |$| 42)) |SYMBOL;scripts;$R;32|) (|check-subtype| (|>=| #1# 0) (QUOTE (|NonNegativeInteger|)) #1#)) (QREFELT |$| 113)))) (LETT |i| (PROG1 (|+| |i| 1) (LETT |j| (|+| |j| 1) |SYMBOL;scripts;$R;32|)) |SYMBOL;scripts;$R;32|) (GO G190) G191 (EXIT NIL)) (LETT |nscripts| (SPADCALL (CDR |nscripts|) (|SPADfirst| |nscripts|) (QREFELT |$| 114)) |SYMBOL;scripts;$R;32|) (LETT |allscripts| (SPADCALL (SPADCALL |sy| (QREFELT |$| 104)) (QREFELT |$| 115)) |SYMBOL;scripts;$R;32|) (LETT |m| (SPADCALL |lscripts| (QREFELT |$| 116)) |SYMBOL;scripts;$R;32|) (SEQ (LETT |n| NIL |SYMBOL;scripts;$R;32|) (LETT #2# |nscripts| |SYMBOL;scripts;$R;32|) (LETT |i| |m| |SYMBOL;scripts;$R;32|) G190 (COND ((OR (ATOM #2#) (PROGN (LETT |n| (CAR #2#) |SYMBOL;scripts;$R;32|) NIL)) (GO G191))) (SEQ (EXIT (COND ((|<| (SPADCALL |allscripts| (QREFELT |$| 117)) |n|) (|error| "Improper script count in symbol")) ((QUOTE T) (SEQ (SPADCALL |lscripts| |i| (PROGN (LETT #3# NIL |SYMBOL;scripts;$R;32|) (SEQ (LETT |a| NIL |SYMBOL;scripts;$R;32|) (LETT #4# (SPADCALL |allscripts| |n| (QREFELT |$| 118)) |SYMBOL;scripts;$R;32|) G190 (COND ((OR (ATOM #4#) (PROGN (LETT |a| (CAR #4#) |SYMBOL;scripts;$R;32|) NIL)) (GO G191))) (SEQ (EXIT (LETT #3# (CONS (SPADCALL |a| (QREFELT |$| 52)) #3#) |SYMBOL;scripts;$R;32|))) (LETT #4# (CDR #4#) |SYMBOL;scripts;$R;32|) (GO G190) G191 (EXIT (NREVERSE0 #3#)))) (QREFELT |$| 119)) (EXIT (LETT |allscripts| (SPADCALL |allscripts| |n| (QREFELT |$| 120)) |SYMBOL;scripts;$R;32|))))))) (LETT |i| (PROG1 (|+| |i| 1) (LETT #2# (CDR #2#) |SYMBOL;scripts;$R;32|)) |SYMBOL;scripts;$R;32|) (GO G190) G191 (EXIT NIL)) (EXIT (VECTOR (SPADCALL |lscripts| |m| (QREFELT |$| 121)) (SPADCALL |lscripts| (|+| |m| 1) (QREFELT |$| 121)) (SPADCALL |lscripts| (|+| |m| 2) (QREFELT |$| 121)) (SPADCALL |lscripts| (|+| |m| 3) (QREFELT |$| 121)) (SPADCALL |lscripts| (|+| |m| 4) (QREFELT |$| 121)))))))))))
+
+(DEFUN |SYMBOL;istring| (|n| |$|) (COND ((|<| 9 |n|) (|error| "Can have at most 9 scripts of each kind")) ((QUOTE T) (ELT (QREFELT |$| 16) (|+| |n| 0)))))
+
+(DEFUN |SYMBOL;list;$L;34| (|sy| |$|) (COND ((NULL (SPADCALL |sy| (QREFELT |$| 21))) (|error| "Cannot convert a symbol to a list if it is not subscripted")) ((QUOTE T) |sy|)))
+
+(DEFUN |SYMBOL;sample;$;35| (|$|) (SPADCALL "aSymbol" (QREFELT |$| 47)))
+
+(DEFUN |Symbol| NIL (PROG NIL (RETURN (PROG (#1=#:G108325) (RETURN (COND ((LETT #1# (HGET |$ConstructorCache| (QUOTE |Symbol|)) |Symbol|) (|CDRwithIncrement| (CDAR #1#))) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (CDDAR (HPUT |$ConstructorCache| (QUOTE |Symbol|) (LIST (CONS NIL (CONS 1 (|Symbol;|)))))) (LETT #1# T |Symbol|)) (COND ((NOT #1#) (HREM |$ConstructorCache| (QUOTE |Symbol|))))))))))))
+
+(DEFUN |Symbol;| NIL (PROG (|dv$| |$| |pv$|) (RETURN (PROGN (LETT |dv$| (QUOTE (|Symbol|)) . #1=(|Symbol|)) (LETT |$| (GETREFV 124) . #1#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 NIL) . #1#)) (|haddProp| |$ConstructorCache| (QUOTE |Symbol|) NIL (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 9 (SPADCALL 0 (QREFELT |$| 8))) (QSETREFV |$| 12 (SPADCALL (QREFELT |$| 11))) (QSETREFV |$| 16 (SPADCALL (LIST #2="0" "1" "2" "3" "4" "5" "6" "7" "8" "9") (QREFELT |$| 15))) (QSETREFV |$| 17 "0123456789") (QSETREFV |$| 18 "ABCDEFGHIJKLMNOPQRSTUVWXYZ") (QSETREFV |$| 19 "abcdefghijklmnopqrstuvwxyz") (QSETREFV |$| 37 "*") (QSETREFV |$| 38 (QCSIZE (QREFELT |$| 37))) (QSETREFV |$| 42 (SPADCALL (SPADCALL #2# (QREFELT |$| 40)) (QREFELT |$| 41))) |$|))))
+
+(MAKEPROP (QUOTE |Symbol|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL NIL (|Integer|) (|Reference| 6) (0 . |ref|) (QUOTE |count|) (|AssociationList| |$$| 6) (5 . |empty|) (QUOTE |xcount|) (|List| 28) (|PrimitiveArray| 28) (9 . |construct|) (QUOTE |istrings|) (QUOTE |nums|) (QUOTE ALPHAS) (QUOTE |alphas|) (|Boolean|) |SYMBOL;scripted?;$B;30| (|Void|) (|Symbol|) (|OpenMathDevice|) (14 . |OMputVariable|) (|OpenMathEncoding|) (20 . |OMencodingXML|) (|String|) (24 . |OMopenString|) (30 . |OMputObject|) (35 . |OMputEndObject|) (40 . |OMclose|) |SYMBOL;OMwrite;$S;2| |SYMBOL;OMwrite;$BS;3| |SYMBOL;OMwrite;Omd$V;4| |SYMBOL;OMwrite;Omd$BV;5| (QUOTE |hd|) (QUOTE |lhd|) (|Character|) (45 . |char|) (50 . |ord|) (QUOTE |ord0|) (|InputForm|) (55 . |convert|) |SYMBOL;convert;$If;6| |SYMBOL;convert;2$;7| |SYMBOL;coerce;S$;8| |SYMBOL;=;2$B;9| |SYMBOL;<;2$B;10| (|OutputForm|) (60 . |outputForm|) |SYMBOL;coerce;$Of;11| (|List| 55) |SYMBOL;script;$L$;22| (|List| 50) |SYMBOL;subscript;$L$;12| |SYMBOL;elt;$L$;13| |SYMBOL;superscript;$L$;14| |SYMBOL;argscript;$L$;15| (|PatternMatchResult| 6 23) (|Pattern| 6) (|PatternMatchSymbol| 6) (65 . |patternMatch|) (|PatternMatchResult| 6 |$|) |SYMBOL;patternMatch;$P2Pmr;16| (|PatternMatchResult| (|Float|) 23) (|Pattern| (|Float|)) (|PatternMatchSymbol| (|Float|)) (72 . |patternMatch|) (|PatternMatchResult| (|Float|) |$|) |SYMBOL;patternMatch;$P2Pmr;17| (79 . |coerce|) |SYMBOL;convert;$P;18| (84 . |coerce|) |SYMBOL;convert;$P;19| (|List| |$|) (89 . |concat|) (94 . |concat|) (|Record| (|:| |sub| 55) (|:| |sup| 55) (|:| |presup| 55) (|:| |presub| 55) (|:| |args| 55)) |SYMBOL;script;$R$;23| |SYMBOL;name;2$;31| |SYMBOL;string;$S;24| (100 . |elt|) (106 . |=|) |SYMBOL;scripts;$R;32| (112 . |latex|) |SYMBOL;latex;$S;25| (117 . |minIndex|) (122 . |concat|) (128 . |elt|) (133 . |setelt|) |SYMBOL;new;$;27| (|Union| 6 (QUOTE "failed")) (139 . |search|) (145 . |setelt|) (152 . |maxIndex|) (157 . |position|) |SYMBOL;new;2$;28| (|List| |$$|) (163 . |keys|) (168 . |remove!|) (174 . |void|) |SYMBOL;resetNew;V;29| |SYMBOL;list;$L;34| (178 . |first|) (183 . |digit?|) (|UniversalSegment| 6) (188 . SEGMENT) (194 . |elt|) (|List| 112) (200 . |minIndex|) (|NonNegativeInteger|) (205 . |setelt|) (212 . |concat|) (218 . |rest|) (223 . |minIndex|) (228 . |#|) (233 . |first|) (239 . |setelt|) (246 . |rest|) (252 . |elt|) (CONS IDENTITY (FUNCALL (|dispatchFunction| |SYMBOL;sample;$;35|) |$|)) (|SingleInteger|))) (QUOTE #(|~=| 258 |superscript| 264 |subscript| 270 |string| 276 |scripts| 281 |scripted?| 286 |script| 291 |sample| 303 |resetNew| 307 |patternMatch| 311 |new| 325 |name| 334 |min| 339 |max| 345 |list| 351 |latex| 356 |hash| 361 |elt| 366 |convert| 372 |coerce| 392 |argscript| 402 |OMwrite| 408 |>=| 432 |>| 438 |=| 444 |<=| 450 |<| 456)) (QUOTE NIL) (CONS (|makeByteWordVec2| 1 (QUOTE (0 0 0 0 0 0 0 0 0 0 0))) (CONS (QUOTE #(|OrderedSet&| NIL NIL |SetCategory&| |BasicType&| NIL NIL NIL NIL NIL NIL)) (CONS (QUOTE #((|OrderedSet|) (|PatternMatchable| (|Float|)) (|PatternMatchable| 6) (|SetCategory|) (|BasicType|) (|ConvertibleTo| 67) (|ConvertibleTo| 61) (|ConvertibleTo| 23) (|OpenMath|) (|ConvertibleTo| 43) (|CoercibleTo| 50))) (|makeByteWordVec2| 123 (QUOTE (1 7 0 6 8 0 10 0 11 1 14 0 13 15 2 24 22 0 23 25 0 26 0 27 2 24 0 28 26 29 1 24 22 0 30 1 24 22 0 31 1 24 22 0 32 1 39 0 28 40 1 39 6 0 41 1 43 0 23 44 1 50 0 23 51 3 62 60 23 61 60 63 3 68 66 23 67 66 69 1 67 0 23 72 1 61 0 23 74 1 28 0 76 77 2 55 0 0 0 78 2 28 39 0 6 83 2 39 20 0 0 84 1 50 28 0 86 1 28 6 0 88 2 28 0 39 0 89 1 7 6 0 90 2 7 6 0 6 91 2 10 93 2 0 94 3 10 6 0 2 6 95 1 28 6 0 96 2 28 6 39 0 97 1 10 99 0 100 2 10 93 2 0 101 0 22 0 102 1 99 2 0 105 1 39 20 0 106 2 107 0 6 6 108 2 28 0 0 107 109 1 110 6 0 111 3 110 112 0 6 112 113 2 110 0 0 112 114 1 99 0 0 115 1 53 6 0 116 1 99 112 0 117 2 99 0 0 112 118 3 53 55 0 6 55 119 2 99 0 0 112 120 2 53 55 0 6 121 2 0 20 0 0 1 2 0 0 0 55 58 2 0 0 0 55 56 1 0 28 0 82 1 0 79 0 85 1 0 20 0 21 2 0 0 0 53 54 2 0 0 0 79 80 0 0 0 122 0 0 22 103 3 0 64 0 61 64 65 3 0 70 0 67 70 71 1 0 0 0 98 0 0 0 92 1 0 0 0 81 2 0 0 0 0 1 2 0 0 0 0 1 1 0 76 0 104 1 0 28 0 87 1 0 123 0 1 2 0 0 0 55 57 1 0 61 0 75 1 0 67 0 73 1 0 23 0 46 1 0 43 0 45 1 0 0 28 47 1 0 50 0 52 2 0 0 0 55 59 3 0 22 24 0 20 36 2 0 28 0 20 34 2 0 22 24 0 35 1 0 28 0 33 2 0 20 0 0 1 2 0 20 0 0 1 2 0 20 0 0 48 2 0 20 0 0 1 2 0 20 0 0 49)))))) (QUOTE |lookupComplete|)))
+
+(MAKEPROP (QUOTE |Symbol|) (QUOTE NILADIC) T)
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain SYMBOL Symbol>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/syssolp.spad.pamphlet b/src/algebra/syssolp.spad.pamphlet
new file mode 100644
index 00000000..2a7f1250
--- /dev/null
+++ b/src/algebra/syssolp.spad.pamphlet
@@ -0,0 +1,297 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra syssolp.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SYSSOLP SystemSolvePackage}
+<<package SYSSOLP SystemSolvePackage>>=
+)abbrev package SYSSOLP SystemSolvePackage
+++ Author: P. Gianni
+++ Date Created: summer 1988
+++ Date Last Updated: summer 1990
+++ Basic Functions:
+++ Related Constructors: Fraction, Polynomial, FloatingRealPackage,
+++ FloatingComplexPackage, RadicalSolvePackage
+++ Also See: LinearSystemMatrixPackage, GroebnerSolve
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Symbolic solver for systems of rational functions with coefficients
+++ in an integral domain R.
+++ The systems are solved in the field of rational functions over R.
+++ Solutions are exact of the form variable = value when the value is
+++ a member of the coefficient domain R. Otherwise the solutions
+++ are implicitly expressed as roots of univariate polynomial equations over R.
+++ Care is taken to guarantee that the denominators of the input
+++ equations do not vanish on the solution sets.
+++ The arguments to solve can either be given as equations or
+++ as rational functions interpreted as equal
+++ to zero. The user can specify an explicit list of symbols to
+++ be solved for, treating all other symbols appearing as parameters
+++ or omit the list of symbols in which case the system tries to
+++ solve with respect to all symbols appearing in the input.
+
+NNI ==> NonNegativeInteger
+P ==> Polynomial
+EQ ==> Equation
+L ==> List
+V ==> Vector
+M ==> Matrix
+UP ==> SparseUnivariatePolynomial
+SE ==> Symbol
+IE ==> IndexedExponents Symbol
+SUP ==> SparseUnivariatePolynomial
+
+SystemSolvePackage(R): Cat == Cap where
+ R : IntegralDomain
+ F ==> Fraction Polynomial R
+ PP2 ==> PolynomialFunctions2(R,F)
+ PPR ==> Polynomial Polynomial R
+
+ Cat == with
+ solve: (L F, L SE) -> L L EQ F
+ ++ solve(lp,lv) finds the solutions of the list lp of
+ ++ rational functions with respect to the list of symbols lv.
+
+ solve: (L EQ F, L SE) -> L L EQ F
+ ++ solve(le,lv) finds the solutions of the
+ ++ list le of equations of rational functions
+ ++ with respect to the list of symbols lv.
+
+ solve: L F -> L L EQ F
+ ++ solve(lp) finds the solutions of the list lp of rational
+ ++ functions with respect to all symbols appearing in lp.
+
+ solve: L EQ F -> L L EQ F
+ ++ solve(le) finds the solutions of the list le of equations of
+ ++ rational functions with respect to all symbols appearing in le.
+
+ solve: (F, SE) -> L EQ F
+ ++ solve(p,v) solves the equation p=0, where p is a rational function
+ ++ with respect to the variable v.
+
+ solve: (EQ F,SE) -> L EQ F
+ ++ solve(eq,v) finds the solutions of the equation
+ ++ eq with respect to the variable v.
+
+ solve: F -> L EQ F
+ ++ solve(p) finds the solution of a rational function p = 0
+ ++ with respect to the unique variable appearing in p.
+
+ solve: EQ F -> L EQ F
+ ++ solve(eq) finds the solutions of the equation eq
+ ++ with respect to the unique variable appearing in eq.
+
+ triangularSystems: (L F, L SE) -> L L P R
+ ++ triangularSystems(lf,lv) solves the system of equations
+ ++ defined by lf with respect to the list of symbols lv;
+ ++ the system of equations is obtaining
+ ++ by equating to zero the list of rational functions lf.
+ ++ The output is a list of solutions where
+ ++ each solution is expressed as a "reduced" triangular system of
+ ++ polynomials.
+
+ Cap == add
+
+ import MPolyCatRationalFunctionFactorizer(IE,SE,R,P F)
+
+ ---- Local Functions ----
+ linSolve: (L F, L SE) -> Union(L EQ F, "failed")
+ makePolys : L EQ F -> L F
+
+ makeR2F(r : R) : F == r :: (P R) :: F
+
+ makeP2F(p:P F):F ==
+ lv:=variables p
+ lv = [] => retract p
+ for v in lv repeat p:=pushdown(p,v)
+ retract p
+ ---- Local Functions ----
+ makeEq(p:P F,lv:L SE): EQ F ==
+ z:=last lv
+ np:=numer makeP2F p
+ lx:=variables np
+ for x in lv repeat if member?(x,lx) then leave x
+ up:=univariate(np,x)
+ (degree up)=1 =>
+ equation(x::P(R)::F,-coefficient(up,0)/leadingCoefficient up)
+ equation(np::F,0$F)
+
+ varInF(v: SE): F == v::P(R) :: F
+
+ newInF(n: Integer):F==varInF new()$SE
+
+ testDegree(f :P R , lv :L SE) : Boolean ==
+ "or"/[degree(f,vv)>0 for vv in lv]
+ ---- Exported Functions ----
+
+ -- solve a system of rational functions
+ triangularSystems(lf: L F,lv:L SE) : L L P R ==
+ empty? lv => empty()
+ empty? lf => empty()
+ #lf = 1 =>
+ p:= numer(first lf)
+ fp:=(factor p)$GeneralizedMultivariateFactorize(SE,IE,R,R,P R)
+ [[ff.factor] for ff in factors fp | testDegree(ff.factor,lv)]
+ dmp:=DistributedMultivariatePolynomial(lv,P R)
+ OV:=OrderedVariableList(lv)
+ DP:=DirectProduct(#lv, NonNegativeInteger)
+ push:=PushVariables(R,DP,OV,dmp)
+ lq : L dmp
+ lvv:L OV:=[variable(vv)::OV for vv in lv]
+ lq:=[pushup(df::dmp,lvv)$push for f in lf|(df:=denom f)^=1]
+ lp:=[pushup(numer(f)::dmp,lvv)$push for f in lf]
+ parRes:=groebSolve(lp,lvv)$GroebnerSolve(lv,P R,R)
+ if lq^=[] then
+ gb:=GroebnerInternalPackage(P R,DirectProduct(#lv,NNI),OV,dmp)
+ parRes:=[pr for pr in parRes|
+ and/[(redPol(fq,pr pretend List(dmp))$gb) ^=0
+ for fq in lq]]
+ [[retract pushdown(pf,lvv)$push for pf in pr] for pr in parRes]
+
+ -- One polynomial. Implicit variable --
+ solve(pol : F) ==
+ zero? pol =>
+ error "equation is always satisfied"
+ lv:=removeDuplicates
+ concat(variables numer pol, variables denom pol)
+ empty? lv => error "inconsistent equation"
+ #lv>1 => error "too many variables"
+ solve(pol,first lv)
+
+ -- general solver. Input in equation style. Implicit variables --
+ solve(eq : EQ F) ==
+ pol:= lhs eq - rhs eq
+ zero? pol =>
+ error "equation is always satisfied"
+ lv:=removeDuplicates
+ concat(variables numer pol, variables denom pol)
+ empty? lv => error "inconsistent equation"
+ #lv>1 => error "too many variables"
+ solve(pol,first lv)
+
+ -- general solver. Input in equation style --
+ solve(eq:EQ F,var:SE) == solve(lhs eq - rhs eq,var)
+
+ -- general solver. Input in polynomial style --
+ solve(pol:F,var:SE) ==
+ if R has GcdDomain then
+ p:=primitivePart(numer pol,var)
+ fp:=(factor p)$GeneralizedMultivariateFactorize(SE,IE,R,R,P R)
+ [makeEq(map(makeR2F,ff.factor)$PP2,[var]) for ff in factors fp]
+ else empty()
+
+ -- Convert a list of Equations in a list of Polynomials
+ makePolys(l: L EQ F):L F == [lhs e - rhs e for e in l]
+
+ -- linear systems solver. Input as list of polynomials --
+ linSolve(lp:L F,lv:L SE) ==
+ rec:Record(particular:Union(V F,"failed"),basis:L V F)
+ lr : L P R:=[numer f for f in lp]
+ rec:=linSolve(lr,lv)$LinearSystemPolynomialPackage(R,IE,SE,P R)
+ rec.particular case "failed" => "failed"
+ rhs := rec.particular :: V F
+ zeron:V F:=zero(#lv)
+ for p in rec.basis | p ^= zeron repeat
+ sym := newInF(1)
+ for i in 1..#lv repeat
+ rhs.i := rhs.i + sym*p.i
+ eqs: L EQ F := []
+ for i in 1..#lv repeat
+ eqs := append(eqs,[(lv.i)::(P R)::F = rhs.i])
+ eqs
+
+ -- general solver. Input in polynomial style. Implicit variables --
+ solve(lr : L F) ==
+ lv :="setUnion"/[setUnion(variables numer p, variables denom p)
+ for p in lr]
+ solve(lr,lv)
+
+ -- general solver. Input in equation style. Implicit variables --
+ solve(le : L EQ F) ==
+ lr:=makePolys le
+ lv :="setUnion"/[setUnion(variables numer p, variables denom p)
+ for p in lr]
+ solve(lr,lv)
+
+ -- general solver. Input in equation style --
+ solve(le:L EQ F,lv:L SE) == solve(makePolys le, lv)
+
+ checkLinear(lr:L F,vl:L SE):Boolean ==
+ ld:=[denom pol for pol in lr]
+ for f in ld repeat
+ if (or/[member?(x,vl) for x in variables f]) then return false
+ and/[totalDegree(numer pol,vl) < 2 for pol in lr]
+
+ -- general solver. Input in polynomial style --
+ solve(lr:L F,vl:L SE) ==
+ empty? vl => empty()
+ checkLinear(lr,vl) =>
+ -- linear system --
+ soln := linSolve(lr, vl)
+ soln case "failed" => []
+ eqns: L EQ F := []
+ for i in 1..#vl repeat
+ lhs := (vl.i::(P R))::F
+ rhs := rhs soln.i
+ eqns := append(eqns, [lhs = rhs])
+ [eqns]
+
+ -- polynomial system --
+ if R has GcdDomain then
+ parRes:=triangularSystems(lr,vl)
+ [[makeEq(map(makeR2F,f)$PP2,vl) for f in pr]
+ for pr in parRes]
+ else [[]]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SYSSOLP SystemSolvePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/system.spad.pamphlet b/src/algebra/system.spad.pamphlet
new file mode 100644
index 00000000..56050d6c
--- /dev/null
+++ b/src/algebra/system.spad.pamphlet
@@ -0,0 +1,86 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra system.spad}
+\author{Timothy Daly}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package MSYSCMD MoreSystemCommands}
+<<package MSYSCMD MoreSystemCommands>>=
+)abbrev package MSYSCMD MoreSystemCommands
+++ Author:
+++ Date Created:
+++ Change History:
+++ Basic Operations: systemCommand
+++ Related Constructors:
+++ Also See:
+++ AMS Classification:
+++ Keywords: command
+++ Description:
+++ \spadtype{MoreSystemCommands} implements an interface with the
+++ system command facility. These are the commands that are issued
+++ from source files or the system interpreter and they start with
+++ a close parenthesis, e.g., \spadsyscom{what} commands.
+
+MoreSystemCommands: public == private where
+
+ public == with
+
+ systemCommand: String -> Void
+ ++ systemCommand(cmd) takes the string \spadvar{cmd} and passes
+ ++ it to the runtime environment for execution as a system
+ ++ command. Although various things may be printed, no usable
+ ++ value is returned.
+
+ private == add
+
+ systemCommand cmd == doSystemCommand(cmd)$Lisp
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package MSYSCMD MoreSystemCommands>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/table.spad.pamphlet b/src/algebra/table.spad.pamphlet
new file mode 100644
index 00000000..4d073045
--- /dev/null
+++ b/src/algebra/table.spad.pamphlet
@@ -0,0 +1,265 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra table.spad}
+\author{Stephen M. Watt, Barry Trager}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain HASHTBL HashTable}
+<<domain HASHTBL HashTable>>=
+)abbrev domain HASHTBL HashTable
+++ Author: Stephen M. Watt
+++ Date Created: 1985
+++ Date Last Updated: June 21, 1991
+++ Basic Operations:
+++ Related Domains: Table, EqTable, StringTable
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides access to the underlying Lisp hash tables.
+++ By varying the hashfn parameter, tables suited for different
+++ purposes can be obtained.
+
+HashTable(Key, Entry, hashfn): Exports == Implementation where
+ Key, Entry: SetCategory
+ hashfn: String -- Union("EQ", "UEQUAL", "CVEC", "ID")
+
+ Exports ==> TableAggregate(Key, Entry) with
+ finiteAggregate
+
+ Implementation ==> add
+ Pair ==> Record(key: Key, entry: Entry)
+ Ex ==> OutputForm
+ failMsg := GENSYM()$Lisp
+
+ t1 = t2 == EQ(t1, t2)$Lisp
+ keys t == HKEYS(t)$Lisp
+ # t == HCOUNT(t)$Lisp
+ setelt(t, k, e) == HPUT(t,k,e)$Lisp
+ remove_!(k:Key, t:%) ==
+ r := HGET(t,k,failMsg)$Lisp
+ not EQ(r,failMsg)$Lisp =>
+ HREM(t, k)$Lisp
+ r pretend Entry
+ "failed"
+
+ empty() ==
+ MAKE_-HASHTABLE(INTERN(hashfn)$Lisp,
+ INTERN("STRONG")$Lisp)$Lisp
+
+ search(k:Key, t:%) ==
+ r := HGET(t, k, failMsg)$Lisp
+ not EQ(r, failMsg)$Lisp => r pretend Entry
+ "failed"
+
+@
+\section{domain INTABL InnerTable}
+<<domain INTABL InnerTable>>=
+)abbrev domain INTABL InnerTable
+++ Author: Barry Trager
+++ Date Created: 1992
+++ Date Last Updated: Sept 15, 1992
+++ Basic Operations:
+++ Related Domains: HashTable, AssociationList, Table
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This domain is used to provide a conditional "add" domain
+++ for the implementation of \spadtype{Table}.
+
+InnerTable(Key: SetCategory, Entry: SetCategory, addDom):Exports == Implementation where
+ addDom : TableAggregate(Key, Entry) with
+ finiteAggregate
+ Exports ==> TableAggregate(Key, Entry) with
+ finiteAggregate
+ Implementation ==> addDom
+
+@
+\section{domain TABLE Table}
+<<domain TABLE Table>>=
+)abbrev domain TABLE Table
+++ Author: Stephen M. Watt, Barry Trager
+++ Date Created: 1985
+++ Date Last Updated: Sept 15, 1992
+++ Basic Operations:
+++ Related Domains: HashTable, EqTable, StringTable, AssociationList
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This is the general purpose table type.
+++ The keys are hashed to look up the entries.
+++ This creates a \spadtype{HashTable} if equal for the Key
+++ domain is consistent with Lisp EQUAL otherwise an
+++ \spadtype{AssociationList}
+
+Table(Key: SetCategory, Entry: SetCategory):Exports == Implementation where
+ Exports ==> TableAggregate(Key, Entry) with
+ finiteAggregate
+
+ Implementation ==> InnerTable(Key, Entry,
+ if hashable(Key)$Lisp then HashTable(Key, Entry, "UEQUAL")
+ else AssociationList(Key, Entry))
+
+@
+\section{domain EQTBL EqTable}
+<<domain EQTBL EqTable>>=
+)abbrev domain EQTBL EqTable
+++ Author: Stephen M. Watt
+++ Date Created:
+++ Date Last Updated: June 21, 1991
+++ Basic Operations:
+++ Related Domains: HashTable, Table, StringTable
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides tables where the keys are compared using
+++ \spadfun{eq?}. Thus keys are considered equal only if they
+++ are the same instance of a structure.
+EqTable(Key: SetCategory, Entry: SetCategory) ==
+ HashTable(Key, Entry, "EQ")
+
+@
+\section{domain STRTBL StringTable}
+<<domain STRTBL StringTable>>=
+)abbrev domain STRTBL StringTable
+++ Author: Stephen M. Watt
+++ Date Created:
+++ Date Last Updated: June 21, 1991
+++ Basic Operations:
+++ Related Domains: Table
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ This domain provides tables where the keys are strings.
+++ A specialized hash function for strings is used.
+StringTable(Entry: SetCategory) ==
+ HashTable(String, Entry, "CVEC")
+
+@
+\section{domain GSTBL GeneralSparseTable}
+<<domain GSTBL GeneralSparseTable>>=
+)abbrev domain GSTBL GeneralSparseTable
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: June 21, 1991
+++ Basic Operations:
+++ Related Domains: Table
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ A sparse table has a default entry, which is returned if no other
+++ value has been explicitly stored for a key.
+GeneralSparseTable(Key, Entry, Tbl, dent): TableAggregate(Key, Entry) == Impl
+ where
+ Key, Entry: SetCategory
+ Tbl: TableAggregate(Key, Entry)
+ dent: Entry
+
+ Impl ==> Tbl add
+ Rep := Tbl
+
+ elt(t:%, k:Key) ==
+ (u := search(k, t)$Rep) case "failed" => dent
+ u::Entry
+
+ setelt(t:%, k:Key, e:Entry) ==
+ e = dent => (remove_!(k, t); e)
+ setelt(t, k, e)$Rep
+
+ search(k:Key, t:%) ==
+ (u := search(k, t)$Rep) case "failed" => dent
+ u
+
+@
+\section{domain STBL SparseTable}
+<<domain STBL SparseTable>>=
+)abbrev domain STBL SparseTable
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: June 21, 1991
+++ Basic Operations:
+++ Related Domains: Table
+++ Also See:
+++ AMS Classifications:
+++ Keywords: equation
+++ Examples:
+++ References:
+++ Description:
+++ A sparse table has a default entry, which is returned if no other
+++ value has been explicitly stored for a key.
+
+SparseTable(Key:SetCategory, Ent:SetCategory, dent:Ent) ==
+ GeneralSparseTable(Key, Ent, Table(Key, Ent), dent)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain HASHTBL HashTable>>
+<<domain INTABL InnerTable>>
+<<domain TABLE Table>>
+<<domain EQTBL EqTable>>
+<<domain STRTBL StringTable>>
+<<domain GSTBL GeneralSparseTable>>
+<<domain STBL SparseTable>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/tableau.spad.pamphlet b/src/algebra/tableau.spad.pamphlet
new file mode 100644
index 00000000..baa49c34
--- /dev/null
+++ b/src/algebra/tableau.spad.pamphlet
@@ -0,0 +1,234 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra tableau.spad}
+\author{William H. Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain TABLEAU Tableau}
+<<domain TABLEAU Tableau>>=
+)abbrev domain TABLEAU Tableau
+++ Author: William H. Burge
+++ Date Created: 1987
+++ Date Last Updated: 23 Sept 1991
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Young tableau
+++ References:
+++ Description:
+++ The tableau domain is for printing Young tableaux, and
+++ coercions to and from List List S where S is a set.
+Tableau(S:SetCategory):Exports == Implementation where
+ ++ The tableau domain is for printing Young tableaux, and
+ ++ coercions to and from List List S where S is a set.
+ L ==> List
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ V ==> Vector
+ fm==>formMatrix$PrintableForm()
+ Exports ==> with
+ tableau : L L S -> %
+ ++ tableau(ll) converts a list of lists ll to a tableau.
+ listOfLists : % -> L L S
+ ++ listOfLists t converts a tableau t to a list of lists.
+ coerce : % -> OUT
+ ++ coerce(t) converts a tableau t to an output form.
+ Implementation ==> add
+
+ Rep := L L S
+
+ tableau(lls:(L L S)) == lls pretend %
+ listOfLists(x:%):(L L S) == x pretend (L L S)
+ makeupv : (NNI,L S) -> L OUT
+ makeupv(n,ls)==
+ v:=new(n,message " ")$(List OUT)
+ for i in 1..#ls for s in ls repeat v.i:=box(s::OUT)
+ v
+ maketab : L L S -> OUT
+ maketab lls ==
+ ll : L OUT :=
+ empty? lls => [[empty()]]
+ sz:NNI:=# first lls
+ [blankSeparate makeupv(sz,i) for i in lls]
+ pile ll
+
+ coerce(x:%):OUT == maketab listOfLists x
+
+@
+\section{package TABLBUMP TableauxBumpers}
+<<package TABLBUMP TableauxBumpers>>=
+)abbrev package TABLBUMP TableauxBumpers
+++ Author: William H. Burge
+++ Date Created: 1987
+++ Date Last Updated: 23 Sept 1991
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Young tableau
+++ References:
+++ Description:
+++ TableauBumpers implements the Schenstead-Knuth
+++ correspondence between sequences and pairs of Young tableaux.
+++ The 2 Young tableaux are represented as a single tableau with
+++ pairs as components.
+TableauxBumpers(S:OrderedSet):T==C where
+ L==>List
+ ST==>Stream
+ B==>Boolean
+ ROW==>Record(fs:B,sd:L S,td:L L S)
+ RC==>Record(f1:L S,f2:L L L S,f3:L L S,f4:L L L S)
+ PAIR==>L S
+ T== with
+ bumprow:((S,S)->B,PAIR,L PAIR)->ROW
+ ++ bumprow(cf,pr,r) is an auxiliary function which
+ ++ bumps a row r with a pair pr
+ ++ using comparison function cf, and returns a record
+ bumptab:((S,S)->B,PAIR,L L PAIR)->L L PAIR
+ ++ bumptab(cf,pr,t) bumps a tableau t with a pair pr
+ ++ using comparison function cf, returning a new tableau
+ bumptab1:(PAIR,L L PAIR)->L L PAIR
+ ++ bumptab1(pr,t) bumps a tableau t with a pair pr
+ ++ using comparison function \spadfun{<},
+ ++ returning a new tableau
+ untab: (L PAIR,L L PAIR)->L PAIR
+ ++ untab(lp,llp) is an auxiliary function
+ ++ which unbumps a tableau llp,
+ ++ using lp to accumulate pairs
+ bat1:L L PAIR->L PAIR
+ ++ bat1(llp) unbumps a tableau llp.
+ ++ Operation bat1 is the inverse of tab1.
+ bat:Tableau(L S)->L L S
+ ++ bat(ls) unbumps a tableau ls
+ tab1:L PAIR->L L PAIR
+ ++ tab1(lp) creates a tableau from a list of pairs lp
+ tab:L S->Tableau(L S)
+ ++ tab(ls) creates a tableau from ls by first creating
+ ++ a list of pairs using \spadfunFrom{slex}{TableauBumpers},
+ ++ then creating a tableau using \spadfunFrom{tab1}{TableauBumpers}.
+ lex:L PAIR->L PAIR
+ ++ lex(ls) sorts a list of pairs to lexicographic order
+ slex:L S->L PAIR
+ ++ slex(ls) sorts the argument sequence ls, then
+ ++ zips (see \spadfunFrom{map}{ListFunctions3}) the
+ ++ original argument sequence with the sorted result to
+ ++ a list of pairs
+ inverse:L S->L S
+ ++ inverse(ls) forms the inverse of a sequence ls
+ maxrow:(PAIR,L L PAIR,L PAIR,L L PAIR,L L PAIR,L L PAIR)->RC
+ ++ maxrow(a,b,c,d,e) is an auxiliary function for mr
+ mr:L L PAIR->RC
+ ++ mr(t) is an auxiliary function which
+ ++ finds the position of the maximum element of a tableau t
+ ++ which is in the lowest row, producing a record of results
+ C== add
+ cf:(S,S)->B
+ bumprow(cf,x:(PAIR),lls:(L PAIR))==
+ if null lls
+ then [false,x,[x]]$ROW
+ else (y:(PAIR):=first lls;
+ if cf(x.2,y.2)
+ then [true,[x.1,y.2],cons([y.1,x.2],rest lls)]$ROW
+ else (rw:ROW:=bumprow(cf,x,rest lls);
+ [rw.fs,rw.sd,cons(first lls,rw.td)]$ROW ))
+
+ bumptab(cf,x:(PAIR),llls:(L L PAIR))==
+ if null llls
+ then [[x]]
+ else (rw:ROW:= bumprow(cf,x,first llls);
+ if rw.fs
+ then cons(rw.td, bumptab(cf,rw.sd,rest llls))
+ else cons(rw.td,rest llls))
+
+ bumptab1(x,llls)==bumptab(#1<#2,x,llls)
+
+ rd==> reduce$StreamFunctions2(PAIR,L L PAIR)
+ tab1(lls:(L PAIR))== rd([],bumptab1,lls::(ST PAIR))
+
+ srt==>sort$(PAIR)
+ lexorder:(PAIR,PAIR)->B
+ lexorder(p1,p2)==if p1.1=p2.1 then p1.2<p2.2 else p1.1<p2.1
+ lex lp==(sort$(L PAIR))(lexorder(#1,#2),lp)
+ slex ls==lex([[i,j] for i in srt(#1<#2,ls) for j in ls])
+ inverse ls==[lss.2 for lss in
+ lex([[j,i] for i in srt(#1<#2,ls) for j in ls])]
+
+ tab(ls:(PAIR))==(tableau tab1 slex ls )
+
+ maxrow(n,a,b,c,d,llls)==
+ if null llls or null(first llls)
+ then [n,a,b,c]$RC
+ else (fst:=first first llls;rst:=rest first llls;
+ if fst.1>n.1
+ then maxrow(fst,d,rst,rest llls,cons(first llls,d),rest llls)
+ else maxrow(n,a,b,c,cons(first llls,d),rest llls))
+
+ mr llls==maxrow(first first llls,[],rest first llls,rest llls,
+ [],llls)
+
+ untab(lp, llls)==
+ if null llls
+ then lp
+ else (rc:RC:=mr llls;
+ rv:=reverse (bumptab(#2<#1,rc.f1,rc.f2));
+ untab(cons(first first rv,lp)
+ ,append(rest rv,
+ if null rc.f3
+ then []
+ else cons(rc.f3,rc.f4))))
+
+ bat1 llls==untab([],[reverse lls for lls in llls])
+ bat tb==bat1(listOfLists tb)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain TABLEAU Tableau>>
+<<package TABLBUMP TableauxBumpers>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/taylor.spad.pamphlet b/src/algebra/taylor.spad.pamphlet
new file mode 100644
index 00000000..7fa64c04
--- /dev/null
+++ b/src/algebra/taylor.spad.pamphlet
@@ -0,0 +1,490 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra taylor.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain ITAYLOR InnerTaylorSeries}
+<<domain ITAYLOR InnerTaylorSeries>>=
+)abbrev domain ITAYLOR InnerTaylorSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 25 February 1989
+++ Basic Operations:
+++ Related Domains: UnivariateTaylorSeries(Coef,var,cen)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: stream, dense Taylor series
+++ Examples:
+++ References:
+++ Description: Internal package for dense Taylor series.
+++ This is an internal Taylor series type in which Taylor series
+++ are represented by a \spadtype{Stream} of \spadtype{Ring} elements.
+++ For univariate series, the \spad{Stream} elements are the Taylor
+++ coefficients. For multivariate series, the \spad{n}th Stream element
+++ is a form of degree n in the power series variables.
+
+InnerTaylorSeries(Coef): Exports == Implementation where
+ Coef : Ring
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ ST ==> Stream Coef
+ STT ==> StreamTaylorSeriesOperations Coef
+
+ Exports ==> Ring with
+ coefficients: % -> Stream Coef
+ ++\spad{coefficients(x)} returns a stream of ring elements.
+ ++ When x is a univariate series, this is a stream of Taylor
+ ++ coefficients. When x is a multivariate series, the
+ ++ \spad{n}th element of the stream is a form of
+ ++ degree n in the power series variables.
+ series: Stream Coef -> %
+ ++\spad{series(s)} creates a power series from a stream of
+ ++ ring elements.
+ ++ For univariate series types, the stream s should be a stream
+ ++ of Taylor coefficients. For multivariate series types, the
+ ++ stream s should be a stream of forms the \spad{n}th element
+ ++ of which is a
+ ++ form of degree n in the power series variables.
+ pole?: % -> Boolean
+ ++\spad{pole?(x)} tests if the series x has a pole.
+ ++ Note: this is false when x is a Taylor series.
+ order: % -> NNI
+ ++\spad{order(x)} returns the order of a power series x,
+ ++ i.e. the degree of the first non-zero term of the series.
+ order: (%,NNI) -> NNI
+ ++\spad{order(x,n)} returns the minimum of n and the order of x.
+ "*" : (Coef,%)->%
+ ++\spad{c*x} returns the product of c and the series x.
+ "*" : (%,Coef)->%
+ ++\spad{x*c} returns the product of c and the series x.
+ "*" : (%,Integer)->%
+ ++\spad{x*i} returns the product of integer i and the series x.
+ if Coef has IntegralDomain then IntegralDomain
+ --++ An IntegralDomain provides 'exquo'
+
+ Implementation ==> add
+
+ Rep := Stream Coef
+
+--% declarations
+ x,y: %
+
+--% definitions
+
+ -- In what follows, we will be calling operations on Streams
+ -- which are NOT defined in the package Stream. Thus, it is
+ -- necessary to explicitly pass back and forth between Rep and %.
+ -- This will be done using the functions 'stream' and 'series'.
+
+ stream : % -> Stream Coef
+ stream x == x pretend Stream(Coef)
+ series st == st pretend %
+
+ 0 == coerce(0)$STT
+ 1 == coerce(1)$STT
+
+ x = y ==
+ -- tests if two power series are equal
+ -- difference must be a finite stream of zeroes of length <= n + 1,
+ -- where n = $streamCount$Lisp
+ st : ST := stream(x - y)
+ n : I := _$streamCount$Lisp
+ for i in 0..n repeat
+ empty? st => return true
+ frst st ^= 0 => return false
+ st := rst st
+ empty? st
+
+ coefficients x == stream x
+
+ x + y == stream(x) +$STT stream(y)
+ x - y == stream(x) -$STT stream(y)
+ (x:%) * (y:%) == stream(x) *$STT stream(y)
+ - x == -$STT (stream x)
+ (i:I) * (x:%) == (i::Coef) *$STT stream x
+ (x:%) * (i:I) == stream(x) *$STT (i::Coef)
+ (c:Coef) * (x:%) == c *$STT stream x
+ (x:%) * (c:Coef) == stream(x) *$STT c
+
+ recip x ==
+ (rec := recip$STT stream x) case "failed" => "failed"
+ series(rec :: ST)
+
+ if Coef has IntegralDomain then
+
+ x exquo y ==
+ (quot := stream(x) exquo$STT stream(y)) case "failed" => "failed"
+ series(quot :: ST)
+
+ x:% ** n:NNI ==
+ n = 0 => 1
+ expt(x,n :: PositiveInteger)$RepeatedSquaring(%)
+
+ characteristic() == characteristic()$Coef
+ pole? x == false
+
+ iOrder: (ST,NNI,NNI) -> NNI
+ iOrder(st,n,n0) ==
+ (n = n0) or (empty? st) => n0
+ zero? frst st => iOrder(rst st,n + 1,n0)
+ n
+
+ order(x,n) == iOrder(stream x,0,n)
+
+ iOrder2: (ST,NNI) -> NNI
+ iOrder2(st,n) ==
+ empty? st => error "order: series has infinite order"
+ zero? frst st => iOrder2(rst st,n + 1)
+ n
+
+ order x == iOrder2(stream x,0)
+
+@
+\section{domain UTS UnivariateTaylorSeries}
+<<domain UTS UnivariateTaylorSeries>>=
+)abbrev domain UTS UnivariateTaylorSeries
+++ Author: Clifton J. Williamson
+++ Date Created: 21 December 1989
+++ Date Last Updated: 21 September 1993
+++ Basic Operations:
+++ Related Domains: UnivariateLaurentSeries(Coef,var,cen), UnivariatePuiseuxSeries(Coef,var,cen)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: dense, Taylor series
+++ Examples:
+++ References:
+++ Description: Dense Taylor series in one variable
+++ \spadtype{UnivariateTaylorSeries} is a domain representing Taylor
+++ series in
+++ one variable with coefficients in an arbitrary ring. The parameters
+++ of the type specify the coefficient ring, the power series variable,
+++ and the center of the power series expansion. For example,
+++ \spadtype{UnivariateTaylorSeries}(Integer,x,3) represents
+++ Taylor series in
+++ \spad{(x - 3)} with \spadtype{Integer} coefficients.
+UnivariateTaylorSeries(Coef,var,cen): Exports == Implementation where
+ Coef : Ring
+ var : Symbol
+ cen : Coef
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ P ==> Polynomial Coef
+ RN ==> Fraction Integer
+ ST ==> Stream
+ STT ==> StreamTaylorSeriesOperations Coef
+ TERM ==> Record(k:NNI,c:Coef)
+ UP ==> UnivariatePolynomial(var,Coef)
+ Exports ==> UnivariateTaylorSeriesCategory(Coef) with
+ coerce: UP -> %
+ ++\spad{coerce(p)} converts a univariate polynomial p in the variable
+ ++\spad{var} to a univariate Taylor series in \spad{var}.
+ univariatePolynomial: (%,NNI) -> UP
+ ++\spad{univariatePolynomial(f,k)} returns a univariate polynomial
+ ++ consisting of the sum of all terms of f of degree \spad{<= k}.
+ coerce: Variable(var) -> %
+ ++\spad{coerce(var)} converts the series variable \spad{var} into a
+ ++ Taylor series.
+ differentiate: (%,Variable(var)) -> %
+ ++ \spad{differentiate(f(x),x)} computes the derivative of
+ ++ \spad{f(x)} with respect to \spad{x}.
+ lagrange: % -> %
+ ++\spad{lagrange(g(x))} produces the Taylor series for \spad{f(x)}
+ ++ where \spad{f(x)} is implicitly defined as \spad{f(x) = x*g(f(x))}.
+ lambert: % -> %
+ ++\spad{lambert(f(x))} returns \spad{f(x) + f(x^2) + f(x^3) + ...}.
+ ++ This function is used for computing infinite products.
+ ++ \spad{f(x)} should have zero constant coefficient.
+ ++ If \spad{f(x)} is a Taylor series with constant term 1, then
+ ++ \spad{product(n = 1..infinity,f(x^n)) = exp(log(lambert(f(x))))}.
+ oddlambert: % -> %
+ ++\spad{oddlambert(f(x))} returns \spad{f(x) + f(x^3) + f(x^5) + ...}.
+ ++ \spad{f(x)} should have a zero constant coefficient.
+ ++ This function is used for computing infinite products.
+ ++ If \spad{f(x)} is a Taylor series with constant term 1, then
+ ++ \spad{product(n=1..infinity,f(x^(2*n-1)))=exp(log(oddlambert(f(x))))}.
+ evenlambert: % -> %
+ ++\spad{evenlambert(f(x))} returns \spad{f(x^2) + f(x^4) + f(x^6) + ...}.
+ ++ \spad{f(x)} should have a zero constant coefficient.
+ ++ This function is used for computing infinite products.
+ ++ If \spad{f(x)} is a Taylor series with constant term 1, then
+ ++ \spad{product(n=1..infinity,f(x^(2*n))) = exp(log(evenlambert(f(x))))}.
+ generalLambert: (%,I,I) -> %
+ ++\spad{generalLambert(f(x),a,d)} returns \spad{f(x^a) + f(x^(a + d)) +
+ ++ f(x^(a + 2 d)) + ... }. \spad{f(x)} should have zero constant
+ ++ coefficient and \spad{a} and d should be positive.
+ revert: % -> %
+ ++ \spad{revert(f(x))} returns a Taylor series \spad{g(x)} such that
+ ++ \spad{f(g(x)) = g(f(x)) = x}. Series \spad{f(x)} should have constant
+ ++ coefficient 0 and 1st order coefficient 1.
+ multisect: (I,I,%) -> %
+ ++\spad{multisect(a,b,f(x))} selects the coefficients of
+ ++ \spad{x^((a+b)*n+a)}, and changes this monomial to \spad{x^n}.
+ invmultisect: (I,I,%) -> %
+ ++\spad{invmultisect(a,b,f(x))} substitutes \spad{x^((a+b)*n)}
+ ++ for \spad{x^n} and multiples by \spad{x^b}.
+ if Coef has Algebra Fraction Integer then
+ integrate: (%,Variable(var)) -> %
+ ++ \spad{integrate(f(x),x)} returns an anti-derivative of the power
+ ++ series \spad{f(x)} with constant coefficient 0.
+ ++ We may integrate a series when we can divide coefficients
+ ++ by integers.
+
+ Implementation ==> InnerTaylorSeries(Coef) add
+
+ Rep := Stream Coef
+
+--% creation and destruction of series
+
+ stream: % -> Stream Coef
+ stream x == x pretend Stream(Coef)
+
+ coerce(v:Variable(var)) ==
+ zero? cen => monomial(1,1)
+ monomial(1,1) + monomial(cen,0)
+
+ coerce(n:I) == n :: Coef :: %
+ coerce(r:Coef) == coerce(r)$STT
+ monomial(c,n) == monom(c,n)$STT
+
+ getExpon: TERM -> NNI
+ getExpon term == term.k
+ getCoef: TERM -> Coef
+ getCoef term == term.c
+ rec: (NNI,Coef) -> TERM
+ rec(expon,coef) == [expon,coef]
+
+ recs: (ST Coef,NNI) -> ST TERM
+ recs(st,n) == delay$ST(TERM)
+ empty? st => empty()
+ zero? (coef := frst st) => recs(rst st,n + 1)
+ concat(rec(n,coef),recs(rst st,n + 1))
+
+ terms x == recs(stream x,0)
+
+ recsToCoefs: (ST TERM,NNI) -> ST Coef
+ recsToCoefs(st,n) == delay
+ empty? st => empty()
+ term := frst st; expon := getExpon term
+ n = expon => concat(getCoef term,recsToCoefs(rst st,n + 1))
+ concat(0,recsToCoefs(st,n + 1))
+
+ series(st: ST TERM) == recsToCoefs(st,0)
+
+ stToPoly: (ST Coef,P,NNI,NNI) -> P
+ stToPoly(st,term,n,n0) ==
+ (n > n0) or (empty? st) => 0
+ frst(st) * term ** n + stToPoly(rst st,term,n + 1,n0)
+
+ polynomial(x,n) == stToPoly(stream x,(var :: P) - (cen :: P),0,n)
+
+ polynomial(x,n1,n2) ==
+ if n1 > n2 then (n1,n2) := (n2,n1)
+ stToPoly(rest(stream x,n1),(var :: P) - (cen :: P),n1,n2)
+
+ stToUPoly: (ST Coef,UP,NNI,NNI) -> UP
+ stToUPoly(st,term,n,n0) ==
+ (n > n0) or (empty? st) => 0
+ frst(st) * term ** n + stToUPoly(rst st,term,n + 1,n0)
+
+ univariatePolynomial(x,n) ==
+ stToUPoly(stream x,monomial(1,1)$UP - monomial(cen,0)$UP,0,n)
+
+ coerce(p:UP) ==
+ zero? p => 0
+ if not zero? cen then
+ p := p(monomial(1,1)$UP + monomial(cen,0)$UP)
+ st : ST Coef := empty()
+ oldDeg : NNI := degree(p) + 1
+ while not zero? p repeat
+ deg := degree p
+ delta := (oldDeg - deg - 1) :: NNI
+ for i in 1..delta repeat st := concat(0$Coef,st)
+ st := concat(leadingCoefficient p,st)
+ oldDeg := deg; p := reductum p
+ for i in 1..oldDeg repeat st := concat(0$Coef,st)
+ st
+
+ if Coef has coerce: Symbol -> Coef then
+ if Coef has "**": (Coef,NNI) -> Coef then
+
+ stToCoef: (ST Coef,Coef,NNI,NNI) -> Coef
+ stToCoef(st,term,n,n0) ==
+ (n > n0) or (empty? st) => 0
+ frst(st) * term ** n + stToCoef(rst st,term,n + 1,n0)
+
+ approximate(x,n) ==
+ stToCoef(stream x,(var :: Coef) - cen,0,n)
+
+--% values
+
+ variable x == var
+ center s == cen
+
+ coefficient(x,n) ==
+ -- Cannot use elt! Should return 0 if stream doesn't have it.
+ u := stream x
+ while not empty? u and n > 0 repeat
+ u := rst u
+ n := (n - 1) :: NNI
+ empty? u or n ^= 0 => 0
+ frst u
+
+ elt(x:%,n:NNI) == coefficient(x,n)
+
+--% functions
+
+ map(f,x) == map(f,x)$Rep
+ eval(x:%,r:Coef) == eval(stream x,r-cen)$STT
+ differentiate x == deriv(stream x)$STT
+ differentiate(x:%,v:Variable(var)) == differentiate x
+ if Coef has PartialDifferentialRing(Symbol) then
+ differentiate(x:%,s:Symbol) ==
+ (s = variable(x)) => differentiate x
+ map(differentiate(#1,s),x) - differentiate(center x,s)*differentiate(x)
+ multiplyCoefficients(f,x) == gderiv(f,stream x)$STT
+ lagrange x == lagrange(stream x)$STT
+ lambert x == lambert(stream x)$STT
+ oddlambert x == oddlambert(stream x)$STT
+ evenlambert x == evenlambert(stream x)$STT
+ generalLambert(x:%,a:I,d:I) == generalLambert(stream x,a,d)$STT
+ extend(x,n) == extend(x,n+1)$Rep
+ complete x == complete(x)$Rep
+ truncate(x,n) == first(stream x,n + 1)$Rep
+ truncate(x,n1,n2) ==
+ if n2 < n1 then (n1,n2) := (n2,n1)
+ m := (n2 - n1) :: NNI
+ st := first(rest(stream x,n1)$Rep,m + 1)$Rep
+ for i in 1..n1 repeat st := concat(0$Coef,st)
+ st
+ elt(x:%,y:%) == compose(stream x,stream y)$STT
+ revert x == revert(stream x)$STT
+ multisect(a,b,x) == multisect(a,b,stream x)$STT
+ invmultisect(a,b,x) == invmultisect(a,b,stream x)$STT
+ multiplyExponents(x,n) == invmultisect(n,0,x)
+ quoByVar x == (empty? x => 0; rst x)
+ if Coef has IntegralDomain then
+ unit? x == unit? coefficient(x,0)
+ if Coef has Field then
+ if Coef is RN then
+ (x:%) ** (s:Coef) == powern(s,stream x)$STT
+ else
+ (x:%) ** (s:Coef) == power(s,stream x)$STT
+
+ if Coef has Algebra Fraction Integer then
+ coerce(r:RN) == r :: Coef :: %
+
+ integrate x == integrate(0,stream x)$STT
+ integrate(x:%,v:Variable(var)) == integrate x
+
+ if Coef has integrate: (Coef,Symbol) -> Coef and _
+ Coef has variables: Coef -> List Symbol then
+ integrate(x:%,s:Symbol) ==
+ (s = variable(x)) => integrate x
+ not entry?(s,variables center x) => map(integrate(#1,s),x)
+ error "integrate: center is a function of variable of integration"
+
+ if Coef has TranscendentalFunctionCategory and _
+ Coef has PrimitiveFunctionCategory and _
+ Coef has AlgebraicallyClosedFunctionSpace Integer then
+
+ integrateWithOneAnswer: (Coef,Symbol) -> Coef
+ integrateWithOneAnswer(f,s) ==
+ res := integrate(f,s)$FunctionSpaceIntegration(I,Coef)
+ res case Coef => res :: Coef
+ first(res :: List Coef)
+
+ integrate(x:%,s:Symbol) ==
+ (s = variable(x)) => integrate x
+ not entry?(s,variables center x) =>
+ map(integrateWithOneAnswer(#1,s),x)
+ error "integrate: center is a function of variable of integration"
+
+--% OutputForms
+-- We use the default coerce: % -> OutputForm in UTSCAT&
+
+@
+\section{package UTS2 UnivariateTaylorSeriesFunctions2}
+<<package UTS2 UnivariateTaylorSeriesFunctions2>>=
+)abbrev package UTS2 UnivariateTaylorSeriesFunctions2
+++ Author: Clifton J. Williamson
+++ Date Created: 9 February 1990
+++ Date Last Updated: 9 February 1990
+++ Basic Operations:
+++ Related Domains: UnivariateTaylorSeries(Coef1,var,cen)
+++ Also See:
+++ AMS Classifications:
+++ Keywords: Taylor series, map
+++ Examples:
+++ References:
+++ Description: Mapping package for univariate Taylor series.
+++ This package allows one to apply a function to the coefficients of
+++ a univariate Taylor series.
+UnivariateTaylorSeriesFunctions2(Coef1,Coef2,UTS1,UTS2):_
+ Exports == Implementation where
+ Coef1 : Ring
+ Coef2 : Ring
+ UTS1 : UnivariateTaylorSeriesCategory Coef1
+ UTS2 : UnivariateTaylorSeriesCategory Coef2
+ ST2 ==> StreamFunctions2(Coef1,Coef2)
+
+ Exports ==> with
+ map: (Coef1 -> Coef2,UTS1) -> UTS2
+ ++\spad{map(f,g(x))} applies the map f to the coefficients of
+ ++ the Taylor series \spad{g(x)}.
+
+ Implementation ==> add
+
+ map(f,uts) == series map(f,coefficients uts)$ST2
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain ITAYLOR InnerTaylorSeries>>
+<<domain UTS UnivariateTaylorSeries>>
+<<package UTS2 UnivariateTaylorSeriesFunctions2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/tex.spad.pamphlet b/src/algebra/tex.spad.pamphlet
new file mode 100644
index 00000000..7577e3f4
--- /dev/null
+++ b/src/algebra/tex.spad.pamphlet
@@ -0,0 +1,709 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra tex.spad}
+\author{Robert S. Sutor}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain TEX TexFormat}
+\subsection{product(product(i*j,i=a..b),j=c..d) fix}
+The expression prints properly in ascii text but the tex output
+is incorrect. Originally the input
+\begin{verbatim}
+product(product(i*j,i=a..b),j=c..d)
+\end{verbatim}
+prints as
+$$
+PI2
+\left(
+{{j=c}, \: d, \: {PI2
+\left(
+{{i=a}, \: b, \: {i \ j}}
+\right)}}
+\right)
+\leqno(1)
+$$
+but now says:
+The problem is in [[src/algebra/tex.spad.pamphlet]] in the list of
+constants.
+The code used to read
+\begin{verbatim}
+ plexOps : L S := ["SIGMA","SIGMA2","PI","INTSIGN","INDEFINTEGRAL"]$(L S)
+ plexPrecs : L I := [ 700, 800, 700, 700]$(L I)
+\end{verbatim}
+it now reads:
+<<product(product(i*j,i=a..b),j=c..d) fix>>=
+ plexOps : L S := ["SIGMA","SIGMA2","PI","PI2","INTSIGN","INDEFINTEGRAL"]$(L S)
+ plexPrecs : L I := [ 700, 800, 700, 800 , 700, 700]$(L I)
+@
+in addition we need to add a line defining [[PI2]] in [[formatPlex]]:
+<<define PI2>>=
+ op = "PI2" => "\prod"
+@
+\subsection{domain TEX TexFormat}
+<<domain TEX TexFormat>>=
+)abbrev domain TEX TexFormat
+++ Author: Robert S. Sutor
+++ Date Created: 1987 through 1992
+++ Change History:
+++ 05/15/91 RSS Changed matrix formatting to use array environment.
+++ 06/27/91 RSS Fixed segments
+++ 08/12/91 RSS Removed some grouping for things, added newWithNum and
+++ ungroup, improved line splitting
+++ 08/15/91 RSS Added mbox support for strings
+++ 10/15/91 RSS Handle \%\% at beginning of string
+++ 01/22/92 RSS Use \[ and \] instead of $$ and $$. Use
+++ %AXIOM STEP NUMBER: instead of \leqno
+++ 02/27/92 RSS Escape dollar signs appearing in the input.
+++ 03/09/92 RSS Handle explicit blank appearing in the input.
+++ 11/28/93 JHD Added code for the VCONCAT and TAG operations.
+++ 06/27/95 RSS Change back to $$ and \leqno for Saturn
+++ Basic Operations: coerce, convert, display, epilogue,
+++ tex, new, prologue, setEpilogue!, setTex!, setPrologue!
+++ Related Constructors: TexFormat1
+++ Also See: ScriptFormulaFormat
+++ AMS Classifications:
+++ Keywords: TeX, LaTeX, output, format
+++ References: \TeX{} is a trademark of the American Mathematical Society.
+++ Description:
+++ \spadtype{TexFormat} provides a coercion from \spadtype{OutputForm} to
+++ \TeX{} format. The particular dialect of \TeX{} used is \LaTeX{}.
+++ The basic object consists of three parts: a prologue, a
+++ tex part and an epilogue. The functions \spadfun{prologue},
+++ \spadfun{tex} and \spadfun{epilogue} extract these parts,
+++ respectively. The main guts of the expression go into the tex part.
+++ The other parts can be set (\spadfun{setPrologue!},
+++ \spadfun{setEpilogue!}) so that contain the appropriate tags for
+++ printing. For example, the prologue and epilogue might simply
+++ contain ``\verb+\[+'' and ``\verb+\]+'', respectively, so that
+++ the TeX section will be printed in LaTeX display math mode.
+
+TexFormat(): public == private where
+ E ==> OutputForm
+ I ==> Integer
+ L ==> List
+ S ==> String
+ US ==> UniversalSegment(Integer)
+
+ public == SetCategory with
+ coerce: E -> $
+ ++ coerce(o) changes o in the standard output format to TeX
+ ++ format.
+ convert: (E,I) -> $
+ ++ convert(o,step) changes o in standard output format to
+ ++ TeX format and also adds the given step number. This is useful
+ ++ if you want to create equations with given numbers or have the
+ ++ equation numbers correspond to the interpreter step numbers.
+ convert: (E,I,E) -> $
+ ++ convert(o,step,type) changes o in standard output format to
+ ++ TeX format and also adds the given step number and type. This
+ ++ is useful if you want to create equations with given numbers
+ ++ or have the equation numbers correspond to the interpreter step
+ ++ numbers.
+ display: ($, I) -> Void
+ ++ display(t,width) outputs the TeX formatted code t so that each
+ ++ line has length less than or equal to \spadvar{width}.
+ display: $ -> Void
+ ++ display(t) outputs the TeX formatted code t so that each
+ ++ line has length less than or equal to the value set by
+ ++ the system command \spadsyscom{set output length}.
+ epilogue: $ -> L S
+ ++ epilogue(t) extracts the epilogue section of a TeX form t.
+ tex: $ -> L S
+ ++ tex(t) extracts the TeX section of a TeX form t.
+ new: () -> $
+ ++ new() create a new, empty object. Use \spadfun{setPrologue!},
+ ++ \spadfun{setTex!} and \spadfun{setEpilogue!} to set the various
+ ++ components of this object.
+ prologue: $ -> L S
+ ++ prologue(t) extracts the prologue section of a TeX form t.
+ setEpilogue!: ($, L S) -> L S
+ ++ setEpilogue!(t,strings) sets the epilogue section of a TeX form t to strings.
+ setTex!: ($, L S) -> L S
+ ++ setTex!(t,strings) sets the TeX section of a TeX form t to strings.
+ setPrologue!: ($, L S) -> L S
+ ++ setPrologue!(t,strings) sets the prologue section of a TeX form t to strings.
+
+ private == add
+ import OutputForm
+ import Character
+ import Integer
+ import List OutputForm
+ import List String
+
+ Rep := Record(prolog : L S, TeX : L S, epilog : L S)
+
+ -- local variables declarations and definitions
+
+ expr: E
+ prec,opPrec: I
+ str: S
+ blank : S := " \ "
+
+ maxPrec : I := 1000000
+ minPrec : I := 0
+
+ unaryOps : L S := ["-","^"]$(L S)
+ unaryPrecs : L I := [700,260]$(L I)
+
+ -- the precedence of / in the following is relatively low because
+ -- the bar obviates the need for parentheses.
+ binaryOps : L S := ["+->","|","**","/","<",">","=","OVER"]$(L S)
+ binaryPrecs : L I := [0,0,900, 700,400,400,400, 700]$(L I)
+
+ naryOps : L S := ["-","+","*",blank,",",";"," ","ROW","",
+ " \cr ","&"," \\ "]$(L S)
+ naryPrecs : L I := [700,700,800, 800,110,110, 0, 0, 0,
+ 0, 0, 0]$(L I)
+ naryNGOps : L S := ["ROW","&"]$(L S)
+
+<<product(product(i*j,i=a..b),j=c..d) fix>>
+
+ specialOps : L S := ["MATRIX","BRACKET","BRACE","CONCATB","VCONCAT", _
+ "AGGLST","CONCAT","OVERBAR","ROOT","SUB","TAG", _
+ "SUPERSUB","ZAG","AGGSET","SC","PAREN", _
+ "SEGMENT","QUOTE","theMap" ]
+
+ -- the next two lists provide translations for some strings for
+ -- which TeX provides special macros.
+
+ specialStrings : L S :=
+ ["cos", "cot", "csc", "log", "sec", "sin", "tan",
+ "cosh", "coth", "csch", "sech", "sinh", "tanh",
+ "acos","asin","atan","erf","...","$","infinity"]
+ specialStringsInTeX : L S :=
+ ["\cos","\cot","\csc","\log","\sec","\sin","\tan",
+ "\cosh","\coth","\csch","\sech","\sinh","\tanh",
+ "\arccos","\arcsin","\arctan","\erf","\ldots","\$","\infty"]
+
+ -- local function signatures
+
+ addBraces: S -> S
+ addBrackets: S -> S
+ group: S -> S
+ formatBinary: (S,L E, I) -> S
+ formatFunction: (S,L E, I) -> S
+ formatMatrix: L E -> S
+ formatNary: (S,L E, I) -> S
+ formatNaryNoGroup: (S,L E, I) -> S
+ formatNullary: S -> S
+ formatPlex: (S,L E, I) -> S
+ formatSpecial: (S,L E, I) -> S
+ formatUnary: (S, E, I) -> S
+ formatTex: (E,I) -> S
+ newWithNum: I -> $
+ parenthesize: S -> S
+ precondition: E -> E
+ postcondition: S -> S
+ splitLong: (S,I) -> L S
+ splitLong1: (S,I) -> L S
+ stringify: E -> S
+ ungroup: S -> S
+
+ -- public function definitions
+
+ new() : $ ==
+-- [["\["]$(L S), [""]$(L S), ["\]"]$(L S)]$Rep
+ [["$$"]$(L S), [""]$(L S), ["$$"]$(L S)]$Rep
+
+ newWithNum(stepNum: I) : $ ==
+-- num : S := concat("%AXIOM STEP NUMBER: ",string(stepNum)$S)
+-- [["\["]$(L S), [""]$(L S), ["\]",num]$(L S)]$Rep
+ num : S := concat(concat("\leqno(",string(stepNum)$S),")")$S
+ [["$$"]$(L S), [""]$(L S), [num,"$$"]$(L S)]$Rep
+
+ coerce(expr : E): $ ==
+ f : $ := new()$$
+ f.TeX := [postcondition
+ formatTex(precondition expr, minPrec)]$(L S)
+ f
+
+ convert(expr : E, stepNum : I): $ ==
+ f : $ := newWithNum(stepNum)
+ f.TeX := [postcondition
+ formatTex(precondition expr, minPrec)]$(L S)
+ f
+
+ display(f : $, len : I) ==
+ s,t : S
+ for s in f.prolog repeat sayTeX$Lisp s
+ for s in f.TeX repeat
+ for t in splitLong(s, len) repeat sayTeX$Lisp t
+ for s in f.epilog repeat sayTeX$Lisp s
+ void()$Void
+
+ display(f : $) ==
+ display(f, _$LINELENGTH$Lisp pretend I)
+
+ prologue(f : $) == f.prolog
+ tex(f : $) == f.TeX
+ epilogue(f : $) == f.epilog
+
+ setPrologue!(f : $, l : L S) == f.prolog := l
+ setTex!(f : $, l : L S) == f.TeX := l
+ setEpilogue!(f : $, l : L S) == f.epilog := l
+
+ coerce(f : $): E ==
+ s,t : S
+ l : L S := nil
+ for s in f.prolog repeat l := concat(s,l)
+ for s in f.TeX repeat
+ for t in splitLong(s, (_$LINELENGTH$Lisp pretend Integer) - 4) repeat
+ l := concat(t,l)
+ for s in f.epilog repeat l := concat(s,l)
+ (reverse l) :: E
+
+ -- local function definitions
+
+ ungroup(str: S): S ==
+ len : I := #str
+ len < 2 => str
+ lbrace : Character := char "{"
+ rbrace : Character := char "}"
+ -- drop leading and trailing braces
+ if (str.1 =$Character lbrace) and (str.len =$Character rbrace) then
+ u : US := segment(2,len-1)$US
+ str := str.u
+ str
+
+ postcondition(str: S): S ==
+ str := ungroup str
+ len : I := #str
+ plus : Character := char "+"
+ minus: Character := char "-"
+ len < 4 => str
+ for i in 1..(len-1) repeat
+ if (str.i =$Character plus) and (str.(i+1) =$Character minus)
+ then setelt(str,i,char " ")$S
+ str
+
+ stringify expr == (object2String$Lisp expr) pretend S
+
+ lineConcat( line : S, lines: L S ) : L S ==
+ length := #line
+
+ if ( length > 0 ) then
+ -- If the last character is a backslash then split at "\ ".
+ -- Reinstate the blank.
+
+ if (line.length = char "\" ) then line := concat(line, " ")
+
+ -- Remark: for some reason, "\%" at the beginning
+ -- of a line has the "\" erased when printed
+
+ if ( line.1 = char "%" ) then line := concat(" \", line)
+ else if ( line.1 = char "\" ) and length > 1 and ( line.2 = char "%" ) then
+ line := concat(" ", line)
+
+ lines := concat(line,lines)$List(S)
+ lines
+
+ splitLong(str : S, len : I): L S ==
+ -- this blocks into lines
+ if len < 20 then len := _$LINELENGTH$Lisp
+ splitLong1(str, len)
+
+ splitLong1(str : S, len : I) ==
+ -- We first build the list of lines backwards and then we
+ -- reverse it.
+
+ l : List S := nil
+ s : S := ""
+ ls : I := 0
+ ss : S
+ lss : I
+ for ss in split(str,char " ") repeat
+ -- have the newline macro end a line (even if it means the line
+ -- is slightly too long)
+
+ ss = "\\" =>
+ l := lineConcat( concat(s,ss), l )
+ s := ""
+ ls := 0
+
+ lss := #ss
+
+ -- place certain tokens on their own lines for clarity
+
+ ownLine : Boolean :=
+ u : US := segment(1,4)$US
+ (lss > 3) and ("\end" = ss.u) => true
+ u := segment(1,5)$US
+ (lss > 4) and ("\left" = ss.u) => true
+ u := segment(1,6)$US
+ (lss > 5) and (("\right" = ss.u) or ("\begin" = ss.u)) => true
+ false
+
+ if ownLine or (ls + lss > len) then
+ if not empty? s then l := lineConcat( s, l )
+ s := ""
+ ls := 0
+
+ ownLine or lss > len => l := lineConcat( ss, l )
+
+ (lss = 1) and (ss.1 = char "\") =>
+ ls := ls + lss + 2
+ s := concat(s,concat(ss," ")$S)$S
+
+ ls := ls + lss + 1
+ s := concat(s,concat(ss," ")$S)$S
+
+ if ls > 0 then l := lineConcat( s, l )
+
+ reverse l
+
+ group str ==
+ concat ["{",str,"}"]
+
+ addBraces str ==
+ concat ["\left\{ ",str," \right\}"]
+
+ addBrackets str ==
+ concat ["\left[ ",str," \right]"]
+
+ parenthesize str ==
+ concat ["\left( ",str," \right)"]
+
+ precondition expr ==
+ outputTran$Lisp expr
+
+ formatSpecial(op : S, args : L E, prec : I) : S ==
+ arg : E
+ prescript : Boolean := false
+ op = "theMap" => "\mbox{theMap(...)}"
+ op = "AGGLST" =>
+ formatNary(",",args,prec)
+ op = "AGGSET" =>
+ formatNary(";",args,prec)
+ op = "TAG" =>
+ group concat [formatTex(first args,prec),
+ "\rightarrow",
+ formatTex(second args,prec)]
+ op = "VCONCAT" =>
+ group concat("\begin{array}{c}",
+ concat(concat([concat(formatTex(u, minPrec),"\\")
+ for u in args]::L S),
+ "\end{array}"))
+ op = "CONCATB" =>
+ formatNary(" ",args,prec)
+ op = "CONCAT" =>
+ formatNary("",args,minPrec)
+ op = "QUOTE" =>
+ group concat("{\tt '}",formatTex(first args, minPrec))
+ op = "BRACKET" =>
+ group addBrackets ungroup formatTex(first args, minPrec)
+ op = "BRACE" =>
+ group addBraces ungroup formatTex(first args, minPrec)
+ op = "PAREN" =>
+ group parenthesize ungroup formatTex(first args, minPrec)
+ op = "OVERBAR" =>
+ null args => ""
+ group concat ["\overline ",formatTex(first args, minPrec)]
+ op = "ROOT" =>
+ null args => ""
+ tmp : S := group formatTex(first args, minPrec)
+ null rest args => group concat ["\sqrt ",tmp]
+ group concat
+ ["\root ",group formatTex(first rest args, minPrec)," \of ",tmp]
+ op = "SEGMENT" =>
+ tmp : S := concat [formatTex(first args, minPrec),".."]
+ group
+ null rest args => tmp
+ concat [tmp,formatTex(first rest args, minPrec)]
+ op = "SUB" =>
+ group concat [formatTex(first args, minPrec)," \sb ",
+ formatSpecial("AGGLST",rest args,minPrec)]
+ op = "SUPERSUB" =>
+ -- variable name
+ form : List S := [formatTex(first args, minPrec)]
+ -- subscripts
+ args := rest args
+ null args => concat(form)$S
+ tmp : S := formatTex(first args, minPrec)
+ if (tmp ^= "") and (tmp ^= "{}") and (tmp ^= " ") then
+ form := append(form,[" \sb ",group tmp])$(List S)
+ -- superscripts
+ args := rest args
+ null args => group concat(form)$S
+ tmp : S := formatTex(first args, minPrec)
+ if (tmp ^= "") and (tmp ^= "{}") and (tmp ^= " ") then
+ form := append(form,[" \sp ",group tmp])$(List S)
+ -- presuperscripts
+ args := rest args
+ null args => group concat(form)$S
+ tmp : S := formatTex(first args, minPrec)
+ if (tmp ^= "") and (tmp ^= "{}") and (tmp ^= " ") then
+ form := append([" \sp ",group tmp],form)$(List S)
+ prescript := true
+ -- presubscripts
+ args := rest args
+ null args =>
+ group concat
+ prescript => cons("{}",form)
+ form
+ tmp : S := formatTex(first args, minPrec)
+ if (tmp ^= "") and (tmp ^= "{}") and (tmp ^= " ") then
+ form := append([" \sb ",group tmp],form)$(List S)
+ prescript := true
+ group concat
+ prescript => cons("{}",form)
+ form
+ op = "SC" =>
+ -- need to handle indentation someday
+ null args => ""
+ tmp := formatNaryNoGroup(" \\ ", args, minPrec)
+ group concat ["\begin{array}{l} ",tmp," \end{array} "]
+ op = "MATRIX" => formatMatrix rest args
+ op = "ZAG" =>
+ concat [" \zag{",formatTex(first args, minPrec),"}{",
+ formatTex(first rest args,minPrec),"}"]
+ concat ["not done yet for ",op]
+
+ formatPlex(op : S, args : L E, prec : I) : S ==
+ hold : S
+ p : I := position(op,plexOps)
+ p < 1 => error "unknown Tex unary op"
+ opPrec := plexPrecs.p
+ n : I := #args
+ (n ^= 2) and (n ^= 3) => error "wrong number of arguments for plex"
+ s : S :=
+ op = "SIGMA" => "\sum"
+ op = "SIGMA2" => "\sum"
+ op = "PI" => "\prod"
+<<define PI2>>
+ op = "INTSIGN" => "\int"
+ op = "INDEFINTEGRAL" => "\int"
+ "????"
+ hold := formatTex(first args,minPrec)
+ args := rest args
+ if op ^= "INDEFINTEGRAL" then
+ if hold ^= "" then
+ s := concat [s," \sb",group concat ["\displaystyle ",hold]]
+ if not null rest args then
+ hold := formatTex(first args,minPrec)
+ if hold ^= "" then
+ s := concat [s," \sp",group concat ["\displaystyle ",hold]]
+ args := rest args
+ s := concat [s," ",formatTex(first args,minPrec)]
+ else
+ hold := group concat [hold," ",formatTex(first args,minPrec)]
+ s := concat [s," ",hold]
+ if opPrec < prec then s := parenthesize s
+ group s
+
+ formatMatrix(args : L E) : S ==
+ -- format for args is [[ROW ...],[ROW ...],[ROW ...]]
+ -- generate string for formatting columns (centered)
+ cols : S := "{"
+ for i in 2..#(first(args) pretend L E) repeat
+ cols := concat(cols,"c")
+ cols := concat(cols,"} ")
+ group addBrackets concat
+ ["\begin{array}",cols,formatNaryNoGroup(" \\ ",args,minPrec),
+ " \end{array} "]
+
+ formatFunction(op : S, args : L E, prec : I) : S ==
+ group concat [op, " ", parenthesize formatNary(",",args,minPrec)]
+
+ formatNullary(op : S) ==
+ op = "NOTHING" => ""
+ group concat [op,"()"]
+
+ formatUnary(op : S, arg : E, prec : I) ==
+ p : I := position(op,unaryOps)
+ p < 1 => error "unknown Tex unary op"
+ opPrec := unaryPrecs.p
+ s : S := concat [op,formatTex(arg,opPrec)]
+ opPrec < prec => group parenthesize s
+ op = "-" => s
+ group s
+
+ formatBinary(op : S, args : L E, prec : I) : S ==
+ p : I := position(op,binaryOps)
+ p < 1 => error "unknown Tex binary op"
+ op :=
+ op = "|" => " \mid "
+ op = "**" => " \sp "
+ op = "/" => " \over "
+ op = "OVER" => " \over "
+ op = "+->" => " \mapsto "
+ op
+ opPrec := binaryPrecs.p
+ s : S := formatTex(first args, opPrec)
+ s := concat [s,op,formatTex(first rest args, opPrec)]
+ group
+ op = " \over " => s
+ opPrec < prec => parenthesize s
+ s
+
+ formatNary(op : S, args : L E, prec : I) : S ==
+ group formatNaryNoGroup(op, args, prec)
+
+ formatNaryNoGroup(op : S, args : L E, prec : I) : S ==
+ null args => ""
+ p : I := position(op,naryOps)
+ p < 1 => error "unknown Tex nary op"
+ op :=
+ op = "," => ", \: "
+ op = ";" => "; \: "
+ op = "*" => blank
+ op = " " => " \ "
+ op = "ROW" => " & "
+ op
+ l : L S := nil
+ opPrec := naryPrecs.p
+ for a in args repeat
+ l := concat(op,concat(formatTex(a,opPrec),l)$L(S))$L(S)
+ s : S := concat reverse rest l
+ opPrec < prec => parenthesize s
+ s
+
+ formatTex(expr,prec) ==
+ i,len : Integer
+ intSplitLen : Integer := 20
+ ATOM(expr)$Lisp pretend Boolean =>
+ str := stringify expr
+ len := #str
+ FIXP$Lisp expr =>
+ i := expr pretend Integer
+ if (i < 0) or (i > 9)
+ then
+ group
+ nstr : String := ""
+ -- insert some blanks into the string, if too long
+ while ((len := #str) > intSplitLen) repeat
+ nstr := concat [nstr," ",
+ elt(str,segment(1,intSplitLen)$US)]
+ str := elt(str,segment(intSplitLen+1)$US)
+ empty? nstr => str
+ nstr :=
+ empty? str => nstr
+ concat [nstr," ",str]
+ elt(nstr,segment(2)$US)
+ else str
+ str = "%pi" => "\pi"
+ str = "%e" => "e"
+ str = "%i" => "i"
+ len > 1 and str.1 = char "%" and str.2 = char "%" =>
+ u : US := segment(3,len)$US
+ concat(" \%\%",str.u)
+ len > 0 and str.1 = char "%" => concat(" \",str)
+ len > 1 and digit? str.1 => group str -- should handle floats
+ len > 0 and str.1 = char "_"" =>
+ concat(concat(" \mbox{\tt ",str),"} ")
+ len = 1 and str.1 = char " " => "{\ }"
+ (i := position(str,specialStrings)) > 0 =>
+ specialStringsInTeX.i
+ (i := position(char " ",str)) > 0 =>
+ -- We want to preserve spacing, so use a roman font.
+ concat(concat(" \mbox{\rm ",str),"} ")
+ str
+ l : L E := (expr pretend L E)
+ null l => blank
+ op : S := stringify first l
+ args : L E := rest l
+ nargs : I := #args
+
+ -- special cases
+ member?(op, specialOps) => formatSpecial(op,args,prec)
+ member?(op, plexOps) => formatPlex(op,args,prec)
+
+ -- nullary case
+ 0 = nargs => formatNullary op
+
+ -- unary case
+ (1 = nargs) and member?(op, unaryOps) =>
+ formatUnary(op, first args, prec)
+
+ -- binary case
+ (2 = nargs) and member?(op, binaryOps) =>
+ formatBinary(op, args, prec)
+
+ -- nary case
+ member?(op,naryNGOps) => formatNaryNoGroup(op,args, prec)
+ member?(op,naryOps) => formatNary(op,args, prec)
+ op := formatTex(first l,minPrec)
+ formatFunction(op,args,prec)
+
+@
+\section{package TEX1 TexFormat1}
+<<package TEX1 TexFormat1>>=
+)abbrev package TEX1 TexFormat1
+++ Author: Robert S. Sutor
+++ Date Created: 1987 through 1990
+++ Change History:
+++ Basic Operations: coerce
+++ Related Constructors: TexFormat
+++ Also See: ScriptFormulaFormat, ScriptFormulaFormat1
+++ AMS Classifications:
+++ Keywords: TeX, output, format
+++ References: \TeX{} is a trademark of the American Mathematical
+++ Society.
+++ Description:
+++ \spadtype{TexFormat1} provides a utility coercion for changing
+++ to TeX format anything that has a coercion to the standard output
+++ format.
+
+TexFormat1(S : SetCategory): public == private where
+ public == with
+ coerce: S -> TexFormat()
+ ++ coerce(s) provides a direct coercion from a domain S to
+ ++ TeX format. This allows the user to skip the step of first
+ ++ manually coercing the object to standard output format before
+ ++ it is coerced to TeX format.
+
+ private == add
+ import TexFormat()
+
+ coerce(s : S): TexFormat ==
+ coerce(s :: OutputForm)$TexFormat
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain TEX TexFormat>>
+<<package TEX1 TexFormat1>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/tools.spad.pamphlet b/src/algebra/tools.spad.pamphlet
new file mode 100644
index 00000000..fb0ed1fe
--- /dev/null
+++ b/src/algebra/tools.spad.pamphlet
@@ -0,0 +1,470 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra tools.spad}
+\author{Brian Dupee}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package ESTOOLS ExpertSystemToolsPackage}
+<<package ESTOOLS ExpertSystemToolsPackage>>=
+)abbrev package ESTOOLS ExpertSystemToolsPackage
+++ Author: Brian Dupee
+++ Date Created: May 1994
+++ Date Last Updated: July 1996
+++ Basic Operations:
+++ Description:
+++ \axiom{ExpertSystemToolsPackage} contains some useful functions for use
+++ by the computational agents of numerical solvers.
+ExpertSystemToolsPackage():E == I where
+ LEDF ==> List Expression DoubleFloat
+ KEDF ==> Kernel Expression DoubleFloat
+ LKEDF ==> List Kernel Expression DoubleFloat
+ VEDF ==> Vector Expression DoubleFloat
+ VEF ==> Vector Expression Float
+ VMF ==> Vector MachineFloat
+ EF2 ==> ExpressionFunctions2
+ EFI ==> Expression Fraction Integer
+ MDF ==> Matrix DoubleFloat
+ LDF ==> List DoubleFloat
+ PDF ==> Polynomial DoubleFloat
+ EDF ==> Expression DoubleFloat
+ EF ==> Expression Float
+ SDF ==> Stream DoubleFloat
+ DF ==> DoubleFloat
+ F ==> Float
+ MF ==> MachineFloat
+ INT ==> Integer
+ NNI ==> NonNegativeInteger
+ LS ==> List Symbol
+ ST ==> String
+ LST ==> List String
+ SS ==> Stream String
+ FI ==> Fraction Integer
+ R ==> Ring
+ OR ==> OrderedRing
+ ON ==> Record(additions:INT,multiplications:INT,exponentiations:INT,functionCalls:INT)
+ RVE ==> Record(val:EDF,exponent:INT)
+ BO ==> BasicOperator
+ OCF ==> OrderedCompletion Float
+ OCDF ==> OrderedCompletion DoubleFloat
+ SOCF ==> Segment OrderedCompletion Float
+ SOCDF ==> Segment OrderedCompletion DoubleFloat
+ Measure ==> Record(measure:F, name:String, explanations:List String)
+ Measure2 ==> Record(measure:F, name:String, explanations:List String, extra:Result)
+ CTYPE ==> Union(continuous: "Continuous at the end points",
+ lowerSingular: "There is a singularity at the lower end point",
+ upperSingular: "There is a singularity at the upper end point",
+ bothSingular: "There are singularities at both end points",
+ notEvaluated: "End point continuity not yet evaluated")
+ RTYPE ==> Union(finite: "The range is finite",
+ lowerInfinite: "The bottom of range is infinite",
+ upperInfinite: "The top of range is infinite",
+ bothInfinite: "Both top and bottom points are infinite",
+ notEvaluated: "Range not yet evaluated")
+ STYPE ==> Union(str:SDF,
+ notEvaluated:"Internal singularities not yet evaluated")
+ ATT ==> Record(endPointContinuity:CTYPE,singularitiesStream:STYPE,range:RTYPE)
+ IFV ==> Record(stiffness:F,stability:F,expense:F,accuracy:F,intermediateResults:F)
+
+ E ==> with
+
+ f2df:F -> DF
+ ++ f2df(f) is a function to convert a \axiomType{Float} to a
+ ++ \axiomType{DoubleFloat}
+ ef2edf:EF -> EDF
+ ++ ef2edf(f) is a function to convert an \axiomType{Expression Float}
+ ++ to an \axiomType{Expression DoubleFloat}
+ ocf2ocdf: OCF -> OCDF
+ ++ ocf2ocdf(a) is a function to convert an \axiomType{OrderedCompletion
+ ++ Float} to an \axiomType{OrderedCompletion DoubleFloat}
+ socf2socdf: SOCF -> SOCDF
+ ++ socf2socdf(a) is a function to convert a \axiomType{Segment OrderedCompletion Float}
+ ++ to a \axiomType{Segment OrderedCompletion DoubleFloat}
+ convert: List SOCF -> List SOCDF
+ ++ convert(l) is a function to convert a \axiomType{Segment OrderedCompletion Float}
+ ++ to a \axiomType{Segment OrderedCompletion DoubleFloat}
+ df2fi :DF -> FI
+ ++ df2fi(n) is a function to convert a \axiomType{DoubleFloat} to a
+ ++ \axiomType{Fraction Integer}
+ edf2fi :EDF -> FI
+ ++ edf2fi(n) maps \axiomType{Expression DoubleFloat} to
+ ++ \axiomType{Fraction Integer}
+ ++ It is an error if n is not coercible to Fraction Integer
+ edf2df :EDF -> DF
+ ++ edf2df(n) maps \axiomType{Expression DoubleFloat} to
+ ++ \axiomType{DoubleFloat}
+ ++ It is an error if \spad{n} is not coercible to DoubleFloat
+ isQuotient:EDF -> Union(EDF,"failed")
+ ++ isQuotient(expr) returns the quotient part of the input
+ ++ expression or \spad{"failed"} if the expression is not of that form.
+ expenseOfEvaluation:VEDF -> F
+ ++ expenseOfEvaluation(o) gives an approximation of the cost of
+ ++ evaluating a list of expressions in terms of the number of basic
+ ++ operations.
+ ++ < 0.3 inexpensive ; 0.5 neutral ; > 0.7 very expensive
+ ++ 400 `operation units' -> 0.75
+ ++ 200 `operation units' -> 0.5
+ ++ 83 `operation units' -> 0.25
+ ++ ** = 4 units , function calls = 10 units.
+ numberOfOperations:VEDF -> ON
+ ++ numberOfOperations(ode) counts additions, multiplications,
+ ++ exponentiations and function calls in the input set of expressions.
+ edf2efi:EDF -> EFI
+ ++ edf2efi(e) coerces \axiomType{Expression DoubleFloat} into
+ ++ \axiomType{Expression Fraction Integer}
+ dfRange:SOCDF -> SOCDF
+ ++ dfRange(r) converts a range including
+ ++ \inputbitmap{\htbmdir{}/plusminus.bitmap} \infty
+ ++ to \axiomType{DoubleFloat} equavalents.
+ dflist:List(Record(left:FI,right:FI)) -> LDF
+ ++ dflist(l) returns a list of \axiomType{DoubleFloat} equivalents of list l
+ df2mf:DF -> MF
+ ++ df2mf(n) coerces a \axiomType{DoubleFloat} to \axiomType{MachineFloat}
+ ldf2vmf:LDF -> VMF
+ ++ ldf2vmf(l) coerces a \axiomType{List DoubleFloat} to
+ ++ \axiomType{List MachineFloat}
+ edf2ef:EDF -> EF
+ ++ edf2ef(e) maps \axiomType{Expression DoubleFloat} to
+ ++ \axiomType{Expression Float}
+ vedf2vef:VEDF -> VEF
+ ++ vedf2vef(v) maps \axiomType{Vector Expression DoubleFloat} to
+ ++ \axiomType{Vector Expression Float}
+ in?:(DF,SOCDF) -> Boolean
+ ++ in?(p,range) tests whether point p is internal to the
+ ++ range range
+ df2st:DF -> ST
+ ++ df2st(n) coerces a \axiomType{DoubleFloat} to \axiomType{String}
+ f2st:F -> ST
+ ++ f2st(n) coerces a \axiomType{Float} to \axiomType{String}
+ ldf2lst:LDF -> LST
+ ++ ldf2lst(ln) coerces a \axiomType{List DoubleFloat} to \axiomType{List String}
+ sdf2lst:SDF -> LST
+ ++ sdf2lst(ln) coerces a \axiomType{Stream DoubleFloat} to \axiomType{String}
+ getlo : SOCDF -> DF
+ ++ getlo(u) gets the \axiomType{DoubleFloat} equivalent of
+ ++ the first endpoint of the range \spad{u}
+ gethi : SOCDF -> DF
+ ++ gethi(u) gets the \axiomType{DoubleFloat} equivalent of
+ ++ the second endpoint of the range \spad{u}
+ concat:(Result,Result) -> Result
+ ++ concat(a,b) adds two aggregates of type \axiomType{Result}.
+ concat:(List Result) -> Result
+ ++ concat(l) concatenates a list of aggregates of type \axiomType{Result}
+ outputMeasure:F -> ST
+ ++ outputMeasure(n) rounds \spad{n} to 3 decimal places and outputs
+ ++ it as a string
+ measure2Result:Measure -> Result
+ ++ measure2Result(m) converts a measure record into a \axiomType{Result}
+ measure2Result:Measure2 -> Result
+ ++ measure2Result(m) converts a measure record into a \axiomType{Result}
+ att2Result:ATT -> Result
+ ++ att2Result(m) converts a attributes record into a \axiomType{Result}
+ iflist2Result:IFV -> Result
+ ++ iflist2Result(m) converts a attributes record into a \axiomType{Result}
+ pdf2ef:PDF -> EF
+ ++ pdf2ef(p) coerces a \axiomType{Polynomial DoubleFloat} to
+ ++ \axiomType{Expression Float}
+ pdf2df:PDF -> DF
+ ++ pdf2df(p) coerces a \axiomType{Polynomial DoubleFloat} to
+ ++ \axiomType{DoubleFloat}. It is an error if \axiom{p} is not
+ ++ retractable to DoubleFloat.
+ df2ef:DF -> EF
+ ++ df2ef(a) coerces a \axiomType{DoubleFloat} to \axiomType{Expression Float}
+ fi2df:FI -> DF
+ ++ fi2df(f) coerces a \axiomType{Fraction Integer} to \axiomType{DoubleFloat}
+ mat:(LDF,NNI) -> MDF
+ ++ mat(a,n) constructs a one-dimensional matrix of a.
+
+ I ==> add
+
+ mat(a:LDF,n:NNI):MDF ==
+ empty?(a)$LDF => zero(1,n)$MDF
+ matrix(list([i for i in a for j in 1..n])$(List LDF))$MDF
+
+ f2df(f:F):DF == (convert(f)@DF)$F
+
+ ef2edf(f:EF):EDF == map(f2df,f)$EF2(F,DF)
+
+ fi2df(f:FI):DF == coerce(f)$DF
+
+ ocf2ocdf(a:OCF):OCDF ==
+ finite? a => (f2df(retract(a)@F))::OCDF
+ a pretend OCDF
+
+ socf2socdf(a:SOCF):SOCDF ==
+ segment(ocf2ocdf(lo a),ocf2ocdf(hi a))
+
+ convert(l:List SOCF):List SOCDF == [socf2socdf a for a in l]
+
+ pdf2df(p:PDF):DF == retract(p)@DF
+
+ df2ef(a:DF):EF ==
+ b := convert(a)@Float
+ coerce(b)$EF
+
+ pdf2ef(p:PDF):EF == df2ef(pdf2df(p))
+
+ edf2fi(m:EDF):FI == retract(retract(m)@DF)@FI
+
+ edf2df(m:EDF):DF == retract(m)@DF
+
+ df2fi(r:DF):FI == (retract(r)@FI)$DF
+
+ dfRange(r:SOCDF):SOCDF ==
+ if infinite?(lo(r))$OCDF then r := -(max()$DF :: OCDF)..hi(r)$SOCDF
+ if infinite?(hi(r))$OCDF then r := lo(r)$SOCDF..(max()$DF :: OCDF)
+ r
+
+ dflist(l:List(Record(left:FI,right:FI))):LDF == [u.left :: DF for u in l]
+
+ edf2efi(f:EDF):EFI == map(df2fi,f)$EF2(DF,FI)
+
+ df2st(n:DF):String == (convert((convert(n)@Float)$DF)@ST)$Float
+
+ f2st(n:F):String == (convert(n)@ST)$Float
+
+ ldf2lst(ln:LDF):LST == [df2st f for f in ln]
+
+ sdf2lst(ln:SDF):LST ==
+ explicitlyFinite? ln =>
+ m := map(df2st,ln)$StreamFunctions2(DF,ST)
+ if index?(20,m)$SS then
+ split!(m,20)
+ m := concat(m,".......")
+ m := complete(m)$SS
+ entries(m)$SS
+ empty()$LST
+
+ df2mf(n:DF):MF == (df2fi(n))::MF
+
+ ldf2vmf(l:LDF):VMF ==
+ m := [df2mf(n) for n in l]
+ vector(m)$VMF
+
+ edf2ef(e:EDF):EF == map(convert$DF,e)$EF2(DF,Float)
+
+ vedf2vef(vedf:VEDF):VEF == vector([edf2ef e for e in members(vedf)])
+
+ getlo(u:SOCDF):DF == retract(lo(u))@DF
+
+ gethi(u:SOCDF):DF == retract(hi(u))@DF
+
+ in?(p:DF,range:SOCDF):Boolean ==
+ top := gethi(range)
+ bottom := getlo(range)
+ a:Boolean := (p < top)$DF
+ b:Boolean := (p > bottom)$DF
+ (a and b)@Boolean
+
+ isQuotient(expr:EDF):Union(EDF,"failed") ==
+ (k := mainKernel expr) case KEDF =>
+ (expr = inv(f := k :: KEDF :: EDF)$EDF)$EDF => f
+-- one?(numerator expr) => denominator expr
+ (numerator expr) = 1 => denominator expr
+ "failed"
+ "failed"
+
+ numberOfOperations1(fn:EDF,numbersSoFar:ON):ON ==
+ (u := isQuotient(fn)) case EDF =>
+ numbersSoFar := numberOfOperations1(u,numbersSoFar)
+ (p := isPlus(fn)) case LEDF =>
+ p := coerce(p)@LEDF
+ np := #p
+ numbersSoFar.additions := (numbersSoFar.additions)+np-1
+ for i in 1..np repeat
+ numbersSoFar := numberOfOperations1(p.i,numbersSoFar)
+ numbersSoFar
+ (t:=isTimes(fn)) case LEDF =>
+ t := coerce(t)@LEDF
+ nt := #t
+ numbersSoFar.multiplications := (numbersSoFar.multiplications)+nt-1
+ for i in 1..nt repeat
+ numbersSoFar := numberOfOperations1(t.i,numbersSoFar)
+ numbersSoFar
+ if (e:=isPower(fn)) case RVE then
+ e := coerce(e)@RVE
+ e.exponent>1 =>
+ numbersSoFar.exponentiations := inc(numbersSoFar.exponentiations)
+ numbersSoFar := numberOfOperations1(e.val,numbersSoFar)
+ lk := kernels(fn)
+ #lk = 1 => -- #lk = 0 => constant found (no further action)
+ k := first(lk)$LKEDF
+ n := name(operator(k)$KEDF)$BO
+ entry?(n,variables(fn)$EDF)$LS => numbersSoFar -- solo variable found
+ a := first(argument(k)$KEDF)$LEDF
+ numbersSoFar.functionCalls := inc(numbersSoFar.functionCalls)$INT
+ numbersSoFar := numberOfOperations1(a,numbersSoFar)
+ numbersSoFar
+
+ numberOfOperations(ode:VEDF):ON ==
+ n:ON := [0,0,0,0]
+ for i in 1..#ode repeat
+ n:ON := numberOfOperations1(ode.i,n)
+ n
+
+ expenseOfEvaluation(o:VEDF):F ==
+ ln:ON := numberOfOperations(o)
+ a := ln.additions
+ m := ln.multiplications
+ e := ln.exponentiations
+ f := 10*ln.functionCalls
+ n := (a + m + 4*e + 10*e)
+ (1.0-exp((-n::F/288.0))$F)
+
+ concat(a:Result,b:Result):Result ==
+ membersOfa := (members(a)@List(Record(key:Symbol,entry:Any)))
+ membersOfb := (members(b)@List(Record(key:Symbol,entry:Any)))
+ allMembers:=
+ concat(membersOfa,membersOfb)$List(Record(key:Symbol,entry:Any))
+ construct(allMembers)
+
+ concat(l:List Result):Result ==
+ import List Result
+ empty? l => empty()$Result
+ f := first l
+ if empty?(r := rest l) then
+ f
+ else
+ concat(f,concat r)
+
+ outputMeasure(m:F):ST ==
+ fl:Float := round(m*(f:= 1000.0))/f
+ convert(fl)@ST
+
+ measure2Result(m:Measure):Result ==
+ mm := coerce(m.measure)$AnyFunctions1(Float)
+ mmr:Record(key:Symbol,entry:Any) := [bestMeasure@Symbol,mm]
+ mn := coerce(m.name)$AnyFunctions1(ST)
+ mnr:Record(key:Symbol,entry:Any) := [nameOfRoutine@Symbol,mn]
+ me := coerce(m.explanations)$AnyFunctions1(List String)
+ mer:Record(key:Symbol,entry:Any) := [allMeasures@Symbol,me]
+ mr := construct([mmr,mnr,mer])$Result
+ met := coerce(mr)$AnyFunctions1(Result)
+ meth:Record(key:Symbol,entry:Any):=[method@Symbol,met]
+ construct([meth])$Result
+
+ measure2Result(m:Measure2):Result ==
+ mm := coerce(m.measure)$AnyFunctions1(Float)
+ mmr:Record(key:Symbol,entry:Any) := [bestMeasure@Symbol,mm]
+ mn := coerce(m.name)$AnyFunctions1(ST)
+ mnr:Record(key:Symbol,entry:Any) := [nameOfRoutine@Symbol,mn]
+ me := coerce(m.explanations)$AnyFunctions1(List String)
+ mer:Record(key:Symbol,entry:Any) := [allMeasures@Symbol,me]
+ mx := coerce(m.extra)$AnyFunctions1(Result)
+ mxr:Record(key:Symbol,entry:Any) := [other@Symbol,mx]
+ mr := construct([mmr,mnr,mer,mxr])$Result
+ met := coerce(mr)$AnyFunctions1(Result)
+ meth:Record(key:Symbol,entry:Any):=[method@Symbol,met]
+ construct([meth])$Result
+
+ att2Result(att:ATT):Result ==
+ aepc := coerce(att.endPointContinuity)$AnyFunctions1(CTYPE)
+ ar := coerce(att.range)$AnyFunctions1(RTYPE)
+ as := coerce(att.singularitiesStream)$AnyFunctions1(STYPE)
+ aa:List Any := [aepc,ar,as]
+ aaa := coerce(aa)$AnyFunctions1(List Any)
+ aar:Record(key:Symbol,entry:Any) := [attributes@Symbol,aaa]
+ construct([aar])$Result
+
+ iflist2Result(ifv:IFV):Result ==
+ ifvs:List String :=
+ [concat(["stiffness: ",outputMeasure(ifv.stiffness)]),
+ concat(["stability: ",outputMeasure(ifv.stability)]),
+ concat(["expense: ",outputMeasure(ifv.expense)]),
+ concat(["accuracy: ",outputMeasure(ifv.accuracy)]),
+ concat(["intermediateResults: ",outputMeasure(ifv.intermediateResults)])]
+ ifa:= coerce(ifvs)$AnyFunctions1(List String)
+ ifr:Record(key:Symbol,entry:Any) := [intensityFunctions@Symbol,ifa]
+ construct([ifr])$Result
+
+@
+\section{package ESTOOLS1 ExpertSystemToolsPackage1}
+<<package ESTOOLS1 ExpertSystemToolsPackage1>>=
+)abbrev package ESTOOLS1 ExpertSystemToolsPackage1
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: February 1995
+++ Basic Operations: neglist
+++ Description:
+++ \axiom{ExpertSystemToolsPackage1} contains some useful functions for use
+++ by the computational agents of Ordinary Differential Equation solvers.
+ExpertSystemToolsPackage1(R1:OR): E == I where
+ OR ==> OrderedRing
+ E ==> with
+ neglist:List R1 -> List R1
+ ++ neglist(l) returns only the negative elements of the list \spad{l}
+ I ==> add
+ neglist(l:List R1):List R1 == [u for u in l | negative?(u)$R1]
+
+@
+\section{package ESTOOLS2 ExpertSystemToolsPackage2}
+<<package ESTOOLS2 ExpertSystemToolsPackage2>>=
+)abbrev package ESTOOLS2 ExpertSystemToolsPackage2
+++ Author: Brian Dupee
+++ Date Created: February 1995
+++ Date Last Updated: July 1996
+++ Basic Operations: map
+++ Related Constructors: Matrix
+++ Description:
+++ \axiom{ExpertSystemToolsPackage2} contains some useful functions for use
+++ by the computational agents of Ordinary Differential Equation solvers.
+ExpertSystemToolsPackage2(R1:R,R2:R): E == I where
+ R ==> Ring
+ E ==> with
+ map:(R1->R2,Matrix R1) -> Matrix R2
+ ++ map(f,m) applies a mapping f:R1 -> R2 onto a matrix
+ ++ \spad{m} in R1 returning a matrix in R2
+ I ==> add
+ map(f:R1->R2,m:Matrix R1):Matrix R2 ==
+ matrix([[f u for u in v] for v in listOfLists(m)$(Matrix R1)])$(Matrix R2)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package ESTOOLS ExpertSystemToolsPackage>>
+<<package ESTOOLS1 ExpertSystemToolsPackage1>>
+<<package ESTOOLS2 ExpertSystemToolsPackage2>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/transsolve.spad.pamphlet b/src/algebra/transsolve.spad.pamphlet
new file mode 100644
index 00000000..168619fa
--- /dev/null
+++ b/src/algebra/transsolve.spad.pamphlet
@@ -0,0 +1,694 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra transsolve.spad}
+\author{Waldemar Wiwianka, Martin Rubey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package SOLVETRA TransSolvePackage}
+<<package SOLVETRA TransSolvePackage>>=
+)abbrev package SOLVETRA TransSolvePackage
+++ Author: W. Wiwianka, Martin Rubey
+++ Date Created: Summer 1991
+++ Change History: 9/91
+++ Basic Operations: solve
+++ Related Constructors: RadicalSolvePackage, FloatingRealPackage
+++ Keywords:
+++ Description:
+++ This package tries to find solutions of equations of type Expression(R).
+++ This means expressions involving transcendental, exponential, logarithmic
+++ and nthRoot functions.
+++ After trying to transform different kernels to one kernel by applying
+++ several rules, it calls zerosOf for the SparseUnivariatePolynomial in
+++ the remaining kernel.
+++ For example the expression \spad{sin(x)*cos(x)-2} will be transformed to
+++ \spad{-2 tan(x/2)**4 -2 tan(x/2)**3 -4 tan(x/2)**2 +2 tan(x/2) -2}
+++ by using the function normalize and then to
+++ \spad{-2 tan(x)**2 + tan(x) -2}
+++ with help of subsTan. This function tries to express the given function
+++ in terms of \spad{tan(x/2)} to express in terms of \spad{tan(x)} .
+++ Other examples are the expressions \spad{sqrt(x+1)+sqrt(x+7)+1} or
+++ \spad{sqrt(sin(x))+1} .
+
+
+TransSolvePackage(R) : Exports == Implementation where
+ R : Join(OrderedSet, EuclideanDomain, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer, CharacteristicZero)
+
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ RE ==> Expression R
+ EQ ==> Equation
+ S ==> Symbol
+ V ==> Variable
+ L ==> List
+ K ==> Kernel RE
+ SUP ==> SparseUnivariatePolynomial
+ C ==> Complex
+ F ==> Float
+ INT ==> Interval
+ SMP ==> SparseMultivariatePolynomial
+
+
+ Exports == with
+
+ solve : RE -> L EQ RE
+ ++ solve(expr) finds the solutions of the equation expr = 0
+ ++ where expr is a function of type Expression(R)
+ ++ with respect to the unique symbol x appearing in eq.
+ solve : EQ RE -> L EQ RE
+ ++ solve(eq) finds the solutions of the equation eq
+ ++ where eq is an equation of functions of type Expression(R)
+ ++ with respect to the unique symbol x appearing in eq.
+ solve : ( EQ RE , S ) -> L EQ RE
+ ++ solve(eq,x) finds the solutions of the equation eq
+ ++ where eq is an equation of functions of type Expression(R)
+ ++ with respect to the symbol x.
+ solve : ( RE , S) -> L EQ RE
+ ++ solve(expr,x) finds the solutions of the equation expr = 0
+ ++ with respect to the symbol x where expr is a function
+ ++ of type Expression(R).
+ solve : (L EQ RE, L S) -> L L EQ RE
+ ++ solve(leqs, lvar) returns a list of solutions to the list of
+ ++ equations leqs with respect to the list of symbols lvar.
+-- solve : (L EQ RE, L Kernel RE) -> L L EQ RE
+-- ++ solve(leqs, lker) returns a list of solutions to the list
+-- ++ of equations leqs with respect to the list of kernels lker.
+
+ Implementation == add
+ import ACF
+ import HomogeneousAggregate(R)
+ import AlgebraicManipulations(R, RE)
+ import TranscendentalManipulations(R, RE)
+ import TrigonometricManipulations(R, RE)
+ import ElementaryFunctionStructurePackage(R, RE)
+ import SparseUnivariatePolynomial(R)
+ import LinearSystemMatrixPackage(RE,Vector RE,Vector RE,Matrix RE)
+ import TransSolvePackageService(R)
+ import MultivariateFactorize(K, IndexedExponents K, R, SMP(R, K))
+
+
+
+ ---- Local Function Declarations ----
+
+ solveInner : (RE, S) -> L EQ RE
+ tryToTrans : ( RE , S) -> RE
+
+ eliminateKernRoot: (RE , K) -> RE
+ eliminateRoot: (RE , S) -> RE
+
+ combineLog : ( RE , S ) -> RE
+ testLog : ( RE , S ) -> Boolean
+ splitExpr : ( RE ) -> L RE
+ buildnexpr : ( RE , S ) -> L RE
+ logsumtolog : RE -> RE
+ logexpp : ( RE , RE ) -> RE
+
+ testRootk : ( RE, S) -> Boolean
+ testkernel : ( RE , S ) -> Boolean
+ funcinv : ( RE , RE ) -> Union(RE,"failed")
+ testTrig : ( RE , S ) -> Boolean
+ testHTrig : ( RE , S ) -> Boolean
+ tableXkernels : ( RE , S ) -> L RE
+ subsTan : ( RE , S ) -> RE
+
+
+ -- exported functions
+
+
+ solve(oside: RE) : L EQ RE ==
+ zero? oside => error "equation is always satisfied"
+ lv := variables oside
+ empty? lv => error "inconsistent equation"
+ #lv>1 => error "too many variables"
+ solve(oside,lv.first)
+
+ solve(equ:EQ RE) : L EQ RE ==
+ solve(lhs(equ)-rhs(equ))
+
+ solve(equ:EQ RE, x:S) : L EQ RE ==
+ oneside:=lhs(equ)-rhs(equ)
+ solve(oneside,x)
+
+ testZero?(lside:RE,sol:EQ RE):Boolean ==
+ if R has QuotientFieldCategory(Integer) then
+ retractIfCan(rhs sol)@Union(Integer,"failed") case "failed" => true
+ else
+ retractIfCan(rhs sol)@Union(Fraction Integer,"failed") case "failed" => true
+ zero? eval(lside,sol) => true
+ false
+
+ solve(lside: RE, x:S) : L EQ RE ==
+ [sol for sol in solveInner(lside,x) | testZero?(lside,sol)]
+
+ solveInner(lside: RE, x:S) : L EQ RE ==
+ lside:=eliminateRoot(lside,x)
+ ausgabe1:=tableXkernels(lside,x)
+
+ X:=new()@Symbol
+ Y:=new()@Symbol::RE
+ (#ausgabe1) = 1 =>
+ bigX:= (first ausgabe1)::RE
+ eq1:=eval(lside,bigX=(X::RE))
+ -- Type : Expression R
+ f:=univariate(eq1,first kernels (X::RE))
+ -- Type : Fraction SparseUnivariatePolynomial Expression R
+ lfatt:= factors factorPolynomial numer f
+ lr:L RE := "append" /[zerosOf(fatt.factor,x) for fatt in lfatt]
+ -- Type : List Expression R
+ r1:=[]::L RE
+ for i in 1..#lr repeat
+ finv := funcinv(bigX,lr(i))
+ if finv case RE then r1:=cons(finv::RE,r1)
+ bigX_back:=funcinv(bigX,bigX)::RE
+ if not testkernel(bigX_back,x) then
+ if bigX = bigX_back then return []::L EQ RE
+ return
+ "append"/[solve(bigX_back-ri, x) for ri in r1]
+ newlist:=[]::L EQ RE
+
+ for i in 1..#r1 repeat
+ elR := eliminateRoot((numer(bigX_back - r1(i))::RE ),x)
+ f:=univariate(elR, kernel(x))
+ -- Type : Fraction SparseUnivariatePolynomial Expression R
+ lfatt:= factors factorPolynomial numer f
+ secondsol:="append" /[zerosOf(ff.factor,x) for ff in lfatt]
+ for j in 1..#secondsol repeat
+ newlist:=cons((x::RE)=rootSimp( secondsol(j) ),newlist)
+ newlist
+ newlside:=tryToTrans(lside,x) ::RE
+ listofkernels:=tableXkernels(newlside,x)
+ (#listofkernels) = 1 => solve(newlside,x)
+ lfacts := factors factor(numer lside)
+ #lfacts > 1 =>
+ sols : L EQ RE := []
+ for frec in lfacts repeat
+ sols := append(solve(frec.factor :: RE, x), sols)
+ sols
+ return []::L EQ RE
+
+ -- local functions
+
+ -- This function was suggested by Manuel Bronstein as a simpler
+ -- alternative to normalize.
+ simplifyingLog(f:RE):RE ==
+ (u:=isExpt(f,"exp"::Symbol)) case Record(var:Kernel RE,exponent:Integer) =>
+ rec := u::Record(var:Kernel RE,exponent:Integer)
+ rec.exponent * first argument(rec.var)
+ log f
+
+
+ testkernel(var1:RE,y:S) : Boolean ==
+ var1:=eliminateRoot(var1,y)
+ listvar1:=tableXkernels(var1,y)
+ if (#listvar1 = 1) and ((listvar1(1) = (y::RE))@Boolean ) then
+ true
+ else if #listvar1 = 0 then true
+ else false
+
+ solveRetract(lexpr:L RE, lvar:L S):Union(L L EQ RE, "failed") ==
+ nlexpr : L Fraction Polynomial R := []
+ for expr in lexpr repeat
+ rf:Union(Fraction Polynomial R, "failed") := retractIfCan(expr)$RE
+ rf case "failed" => return "failed"
+ nlexpr := cons(rf, nlexpr)
+ radicalSolve(nlexpr, lvar)$RadicalSolvePackage(R)
+
+ tryToTrans(lside: RE, x:S) : RE ==
+ if testTrig(lside,x) or testHTrig(lside,x) then
+ convLside:=( simplify(lside) )::RE
+ resultLside:=convLside
+ listConvLside:=tableXkernels(convLside,x)
+ if (#listConvLside) > 1 then
+ NormConvLside:=normalize(convLside,x)
+ NormConvLside:=( NormConvLside ) :: RE
+ resultLside:=subsTan(NormConvLside , x)
+
+ else if testLog(lside,x) then
+ numlside:=numer(lside)::RE
+ resultLside:=combineLog(numlside,x)
+ else
+ NormConvLside:=normalize(lside,x)
+ NormConvLside:=( NormConvLside ) :: RE
+ resultLside:=NormConvLside
+ listConvLside:=tableXkernels(NormConvLside,x)
+ if (#listConvLside) > 1 then
+ cnormConvLside:=complexNormalize(lside,x)
+ cnormConvLside:=cnormConvLside::RE
+ resultLside:=cnormConvLside
+ listcnorm:=tableXkernels(cnormConvLside,x)
+ if (#listcnorm) > 1 then
+ if testLog(cnormConvLside,x) then
+ numlside:=numer(cnormConvLside)::RE
+ resultLside:=combineLog(numlside,x)
+ resultLside
+
+
+ subsTan(exprvar:RE,y:S) : RE ==
+ Z:=new()@Symbol
+ listofkern:=tableXkernels(exprvar,y)
+ varkern:=(first listofkern)::RE
+ Y:=(numer first argument first (kernels(varkern)))::RE
+ test : Boolean := varkern=tan(((Y::RE)/(2::RE))::RE)
+ if not( (#listofkern=1) and test) then
+ return exprvar
+ fZ:=eval(exprvar,varkern=(Z::RE))
+ fN:=(numer fZ)::RE
+ f:=univariate(fN, first kernels(Z::RE))
+ secondfun:=(-2*(Y::RE)/((Y::RE)**2-1) )::RE
+ g:=univariate(secondfun,first kernels(y::RE))
+ H:=(new()@Symbol)::RE
+ newH:=univariate(H,first kernels(Z::RE))
+ result:=decomposeFunc(f,g,newH)
+ if not ( result = f ) then
+ result1:=result( H::RE )
+ resultnew:=eval(result1,H=(( tan((Y::RE))::RE ) ))
+ else return exprvar
+
+
+ eliminateKernRoot(var: RE, varkern: K) : RE ==
+ X:=new()@Symbol
+ var1:=eval(var, (varkern::RE)=(X::RE) )
+ var2:=numer univariate(var1, first kernels(X::RE))
+ var3:= monomial(1, ( retract( second argument varkern)@I )::NNI)@SUP RE_
+ - monomial(first argument varkern, 0::NNI)@SUP RE
+ resultvar:=resultant(var2, var3)
+
+ eliminateRoot(var:RE, y:S) : RE ==
+ var1:=var
+ while testRootk(var1,y) repeat
+ varlistk1:=tableXkernels(var1,y)
+ for i in varlistk1 repeat
+ if is?(i, "nthRoot"::S) then
+ var1:=eliminateKernRoot(var1,first kernels(i::RE))
+ var1
+
+
+ logsumtolog(var:RE) : RE ==
+ (listofexpr:=isPlus(var)) case "failed" => var
+ listofexpr:= listofexpr ::L RE
+ listforgcd:=[]::L R
+ for i in listofexpr repeat
+ exprcoeff:=leadingCoefficient(numer(i))
+ listforgcd:=cons(exprcoeff, listforgcd)
+ gcdcoeff:=gcd(listforgcd)::RE
+ newexpr:RE :=0
+ for i in listofexpr repeat
+ exprlist:=splitExpr(i::RE)
+ newexpr:=newexpr + logexpp(exprlist.2, exprlist.1/gcdcoeff)
+ kernelofvar:=kernels(newexpr)
+ var2:=1::RE
+ for i in kernelofvar repeat
+ var2:=var2*(first argument i)
+ gcdcoeff * log(var2)
+
+
+ testLog(expr:RE,Z:S) : Boolean ==
+ testList:=[log]::L S
+ kernelofexpr:=tableXkernels(expr,Z)
+ if #kernelofexpr = 0 then
+ return false
+ for i in kernelofexpr repeat
+ if not member?(name(first kernels(i)),testList) or _
+ not testkernel( (first argument first kernels(i)) ,Z) then
+ return false
+ true
+
+ splitExpr(expr:RE) : L RE ==
+ lcoeff:=leadingCoefficient((numer expr))
+ exprwcoeff:=expr
+ listexpr:=isTimes(exprwcoeff)
+ if listexpr case "failed" then
+ [1::RE , expr]
+ else
+ listexpr:=remove_!(lcoeff::RE , listexpr)
+ cons(lcoeff::RE , listexpr)
+
+ buildnexpr(expr:RE, Z:S) : L RE ==
+ nlist:=splitExpr(expr)
+ n2list:=remove_!(nlist.1, nlist)
+ anscoeff:RE:=1
+ ansmant:RE:=0
+ for i in n2list repeat
+ if freeOf?(i::RE,Z) then
+ anscoeff:=(i::RE)*anscoeff
+ else
+ ansmant:=(i::RE)
+ [anscoeff, ansmant * nlist.1 ]
+
+ logexpp(expr1:RE, expr2:RE) : RE ==
+ log( (first argument first kernels(expr1))**expr2 )
+
+ combineLog(expr:RE,Y:S) : RE ==
+ exprtable:Table(RE,RE):=table()
+ (isPlus(expr)) case "failed" => expr
+ ans:RE:=0
+ while expr ^= 0 repeat
+ loopexpr:RE:=leadingMonomial(numer(expr))::RE
+ if testLog(loopexpr,Y) and (#tableXkernels(loopexpr,Y)=1) then
+ exprr:=buildnexpr(loopexpr,Y)
+ if search(exprr.1,exprtable) case "failed" then
+ exprtable.(exprr.1):=0
+ exprtable.(exprr.1):= exprtable.(exprr.1) + exprr.2
+ else
+ ans:=ans+loopexpr
+ expr:=(reductum(numer expr))::RE
+ ansexpr:RE:=0
+ for i in keys(exprtable) repeat
+ ansexpr:=ansexpr + logsumtolog(exprtable.i) * (i::RE)
+ ansexpr:=ansexpr + ans
+
+
+ testRootk(varlistk:RE,y:S) : Boolean ==
+ testList:=[nthRoot]::L S
+ kernelofeqnvar:=tableXkernels(varlistk,y)
+ if #kernelofeqnvar = 0 then
+ return false
+ for i in kernelofeqnvar repeat
+ if member?(name(first kernels(i)),testList) then
+ return true
+ false
+
+ tableXkernels(evar:RE,Z:S) : L RE ==
+ kOfvar:=kernels(evar)
+ listkOfvar:=[]::L RE
+ for i in kOfvar repeat
+ if not freeOf?(i::RE,Z) then
+ listkOfvar:=cons(i::RE,listkOfvar)
+ listkOfvar
+
+ testTrig(eqnvar:RE,Z:S) : Boolean ==
+ testList:=[sin , cos , tan , cot , sec , csc]::L S
+ kernelofeqnvar:=tableXkernels(eqnvar,Z)
+ if #kernelofeqnvar = 0 then
+ return false
+ for i in kernelofeqnvar repeat
+ if not member?(name(first kernels(i)),testList) or _
+ not testkernel( (first argument first kernels(i)) ,Z) then
+ return false
+ true
+
+
+ testHTrig(eqnvar:RE,Z:S) : Boolean ==
+ testList:=[sinh , cosh , tanh , coth , sech , csch]::L S
+ kernelofeqnvar:=tableXkernels(eqnvar,Z)
+ if #kernelofeqnvar = 0 then
+ return false
+ for i in kernelofeqnvar repeat
+ if not member?(name(first kernels(i)),testList) or _
+ not testkernel( (first argument first kernels(i)) ,Z) then
+ return false
+ true
+
+ -- Auxiliary local function for use in funcinv.
+ makeInterval(l:R):C INT F ==
+ if R has complex and R has ConvertibleTo(C F) then
+ map(interval$INT(F),convert(l)$R)$ComplexFunctions2(F,INT F)
+ else
+ error "This should never happen"
+
+ funcinv(k:RE,l:RE) : Union(RE,"failed") ==
+ is?(k, "sin"::Symbol) => asin(l)
+ is?(k, "cos"::Symbol) => acos(l)
+ is?(k, "tan"::Symbol) => atan(l)
+ is?(k, "cot"::Symbol) => acot(l)
+ is?(k, "sec"::Symbol) =>
+ l = 0 => "failed"
+ asec(l)
+ is?(k, "csc"::Symbol) =>
+ l = 0 => "failed"
+ acsc(l)
+ is?(k, "sinh"::Symbol) => asinh(l)
+ is?(k, "cosh"::Symbol) => acosh(l)
+ is?(k, "tanh"::Symbol) => atanh(l)
+ is?(k, "coth"::Symbol) => acoth(l)
+ is?(k, "sech"::Symbol) => asech(l)
+ is?(k, "csch"::Symbol) => acsch(l)
+ is?(k, "atan"::Symbol) => tan(l)
+ is?(k, "acot"::Symbol) =>
+ l = 0 => "failed"
+ cot(l)
+ is?(k, "asin"::Symbol) => sin(l)
+ is?(k, "acos"::Symbol) => cos(l)
+ is?(k, "asec"::Symbol) => sec(l)
+ is?(k, "acsc"::Symbol) =>
+ l = 0 => "failed"
+ csc(l)
+ is?(k, "asinh"::Symbol) => sinh(l)
+ is?(k, "acosh"::Symbol) => cosh(l)
+ is?(k, "atanh"::Symbol) => tanh(l)
+ is?(k, "acoth"::Symbol) =>
+ l = 0 => "failed"
+ coth(l)
+ is?(k, "asech"::Symbol) => sech(l)
+ is?(k, "acsch"::Symbol) =>
+ l = 0 => "failed"
+ csch(l)
+ is?(k, "exp"::Symbol) =>
+ l = 0 => "failed"
+ simplifyingLog l
+ is?(k, "log"::Symbol) =>
+ if R has complex and R has ConvertibleTo(C F) then
+ -- We will check to see if the imaginary part lies in [-Pi,Pi)
+ ze : Expression C INT F
+ ze := map(makeInterval,l)$ExpressionFunctions2(R,C INT F)
+ z : Union(C INT F,"failed") := retractIfCan ze
+ z case "failed" => exp l
+ im := imag z
+ fpi : Float := pi()
+ (-fpi < inf(im)) and (sup(im) <= fpi) => exp l
+ "failed"
+ else -- R not Complex or something which doesn't map to Complex Floats
+ exp l
+ is?(k, "%power"::Symbol) =>
+ (t:=normalize(l)) = 0 => "failed"
+ log t
+ l
+
+ import SystemSolvePackage(RE)
+
+ ker2Poly(k:Kernel RE, lvar:L S):Polynomial RE ==
+ member?(nm:=name k, lvar) => nm :: Polynomial RE
+ k :: RE :: Polynomial RE
+
+ smp2Poly(pol:SMP(R,Kernel RE), lvar:L S):Polynomial RE ==
+ map(ker2Poly(#1, lvar),
+ #1::RE::Polynomial RE, pol)$PolynomialCategoryLifting(
+ IndexedExponents Kernel RE, Kernel RE, R, SMP(R, Kernel RE),
+ Polynomial RE)
+
+ makeFracPoly(expr:RE, lvar:L S):Fraction Polynomial RE ==
+ smp2Poly(numer expr, lvar) / smp2Poly(denom expr, lvar)
+
+ makeREpol(pol:Polynomial RE):RE ==
+ lvar := variables pol
+ lval : List RE := [v::RE for v in lvar]
+ ground eval(pol,lvar,lval)
+
+ makeRE(frac:Fraction Polynomial RE):RE ==
+ makeREpol(numer frac)/makeREpol(denom frac)
+
+ solve1Pol(pol:Polynomial RE, var: S, sol:L EQ RE):L L EQ RE ==
+ repol := eval(makeREpol pol, sol)
+ vsols := solve(repol, var)
+ [cons(vsol, sol) for vsol in vsols]
+
+ solve1Sys(plist:L Polynomial RE, lvar:L S):L L EQ RE ==
+ rplist := reverse plist
+ rlvar := reverse lvar
+ sols : L L EQ RE := list(empty())
+ for p in rplist for v in rlvar repeat
+ sols := "append"/[solve1Pol(p,v,sol) for sol in sols]
+ sols
+
+@
+The input
+\begin{verbatim}
+ solve(sinh(z)=cosh(z),z)
+\end{verbatim}
+generates the error (reported as bug \# 102):
+\begin{verbatim}
+ >> Error detected within library code:
+ No identity element for reduce of empty list using operation append
+\end{verbatim}
+<<package SOLVETRA TransSolvePackage>>=
+
+ solveList(lexpr:L RE, lvar:L S):L L EQ RE ==
+ ans1 := solveRetract(lexpr, lvar)
+ not(ans1 case "failed") => ans1 :: L L EQ RE
+ lfrac:L Fraction Polynomial RE :=
+ [makeFracPoly(expr, lvar) for expr in lexpr]
+ trianglist := triangularSystems(lfrac, lvar)
+-- "append"/[solve1Sys(plist, lvar) for plist in trianglist]
+ l: L L L EQ RE := [solve1Sys(plist, lvar) for plist in trianglist]
+ reduce(append, l, [])
+
+ solve(leqs:L EQ RE, lvar:L S):L L EQ RE ==
+ lexpr:L RE := [lhs(eq)-rhs(eq) for eq in leqs]
+ solveList(lexpr, lvar)
+
+-- solve(leqs:L EQ RE, lker:L Kernel RE):L L EQ RE ==
+-- lexpr:L RE := [lhs(eq)-rhs(eq) for eq in leqs]
+-- lvar :L S := [new()$S for k in lker]
+-- lval :L RE := [kernel v for v in lvar]
+-- nlexpr := [eval(expr,lker,lval) for expr in lexpr]
+-- ans := solveList(nlexpr, lvar)
+-- lker2 :L Kernel RE := [v::Kernel(RE) for v in lvar]
+-- lval2 := [k::RE for k in lker]
+-- [[map(eval(#1,lker2,lval2), neq) for neq in sol] for sol in ans]
+
+@
+\section{package SOLVESER TransSolvePackageService}
+<<package SOLVESER TransSolvePackageService>>=
+)abbrev package SOLVESER TransSolvePackageService
+++ Author: W. Wiwianka
+++ Date Created: Summer 1991
+++ Change History: 9/91
+++ Basic Operations: decomposeFunc, unvectorise
+++ Related Constructors:
+++ Keywords:
+++ Description: This package finds the function func3 where func1 and func2
+++ are given and func1 = func3(func2) . If there is no solution then
+++ function func1 will be returned.
+++ An example would be \spad{func1:= 8*X**3+32*X**2-14*X ::EXPR INT} and
+++ \spad{func2:=2*X ::EXPR INT} convert them via univariate
+++ to FRAC SUP EXPR INT and then the solution is \spad{func3:=X**3+X**2-X}
+++ of type FRAC SUP EXPR INT
+TransSolvePackageService(R) : Exports == Implementation where
+ R : Join(IntegralDomain, OrderedSet)
+
+ RE ==> Expression R
+ EQ ==> Equation
+ S ==> Symbol
+ V ==> Variable
+ L ==> List
+ SUP ==> SparseUnivariatePolynomial
+ ACF ==> AlgebraicallyClosedField()
+
+
+ Exports == with
+
+ decomposeFunc : ( Fraction SUP RE , Fraction SUP RE, Fraction SUP RE ) -> Fraction SUP RE
+ ++ decomposeFunc(func1, func2, newvar) returns a function func3 where
+ ++ func1 = func3(func2) and expresses it in the new variable newvar.
+ ++ If there is no solution then func1 will be returned.
+ unvectorise : ( Vector RE , Fraction SUP RE , Integer ) -> Fraction SUP RE
+ ++ unvectorise(vect, var, n) returns
+ ++ \spad{vect(1) + vect(2)*var + ... + vect(n+1)*var**(n)} where
+ ++ vect is the vector of the coefficients of the polynomail , var
+ ++ the new variable and n the degree.
+
+
+ Implementation == add
+ import ACF
+ import TranscendentalManipulations(R, RE)
+ import ElementaryFunctionStructurePackage(R, RE)
+ import SparseUnivariatePolynomial(R)
+ import LinearSystemMatrixPackage(RE,Vector RE,Vector RE,Matrix RE)
+ import HomogeneousAggregate(R)
+
+ ---- Local Function Declarations ----
+
+ subsSolve : ( SUP RE, NonNegativeInteger, SUP RE, SUP RE, Integer, Fraction SUP RE) -> Union(SUP RE , "failed" )
+ --++ subsSolve(f, degf, g1, g2, m, h)
+
+
+ -- exported functions
+
+
+ unvectorise(vect:Vector RE, var:Fraction SUP RE,n:Integer) : Fraction SUP RE ==
+ Z:=new()@Symbol
+ polyvar: Fraction SUP RE :=0
+ for i in 1..((n+1)::Integer) repeat
+ vecti:=univariate(vect( i ),first kernels(Z::RE))
+ polyvar:=polyvar + ( vecti )*( var )**( (n-i+1)::NonNegativeInteger )
+ polyvar
+
+
+ decomposeFunc(exprf:Fraction SUP RE , exprg:Fraction SUP RE, newH:Fraction SUP RE ) : Fraction SUP RE ==
+ X:=new()@Symbol
+ f1:=numer(exprf)
+ f2:=denom(exprf)
+ g1:=numer(exprg)
+ g2:=denom(exprg)
+ degF:=max(degree(numer(exprf)),degree(denom(exprf)))
+ degG:=max(degree(g1),degree(g2))
+ newF1,newF2 : Union(SUP RE, "failed")
+ N:= degF exquo degG
+ if not ( N case "failed" ) then
+ m:=N::Integer
+ newF1:=subsSolve(f1,degF,g1,g2,m,newH)
+ if f2 = 1 then
+ newF2:= 1 :: SUP RE
+ else newF2:=subsSolve(f2,degF,g1,g2,m,newH)
+ if ( not ( newF1 case "failed" ) ) and ( not ( newF2 case "failed" ) ) then
+ newF:=newF1/newF2
+ else return exprf
+ else return exprf
+
+
+ -- local functions
+
+
+ subsSolve(F:SUP RE, DegF:NonNegativeInteger, G1:SUP RE, G2:SUP RE, M:Integer, HH: Fraction SUP RE) : Union(SUP RE , "failed" ) ==
+ coeffmat:=new((DegF+1),1,0)@Matrix RE
+ for i in 0..M repeat
+ coeffmat:=horizConcat(coeffmat, (vectorise( ( ( G1**((M-i)::NonNegativeInteger) )*G2**i ), (DegF+1) )::Matrix RE) )
+ vec:= vectorise(F,DegF+1)
+ coeffma:=subMatrix(coeffmat,1,(DegF+1),2,(M+2))
+ solvar:=solve(coeffma,vec)
+ if not ( solvar.particular case "failed" ) then
+ solvevarlist:=(solvar.particular)::Vector RE
+ resul:= numer(unvectorise(solvevarlist,( HH ),M))
+ resul
+ else return "failed"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package SOLVETRA TransSolvePackage>>
+<<package SOLVESER TransSolvePackageService>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/tree.spad.pamphlet b/src/algebra/tree.spad.pamphlet
new file mode 100644
index 00000000..ff8ba34c
--- /dev/null
+++ b/src/algebra/tree.spad.pamphlet
@@ -0,0 +1,694 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra tree.spad}
+\author{William Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain TREE Tree}
+<<domain TREE Tree>>=
+)abbrev domain TREE Tree
+++ Author:W. H. Burge
+++ Date Created:17 Feb 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: \spadtype{Tree(S)} is a basic domains of tree structures.
+++ Each tree is either empty or else is a {\it node} consisting of a value and
+++ a list of (sub)trees.
+Tree(S: SetCategory): T==C where
+ T== RecursiveAggregate(S) with
+ finiteAggregate
+ shallowlyMutable
+ tree: (S,List %) -> %
+ ++ tree(nd,ls) creates a tree with value nd, and children
+ ++ ls.
+ tree: List S -> %
+ ++ tree(ls) creates a tree from a list of elements of s.
+ tree: S -> %
+ ++ tree(nd) creates a tree with value nd, and no children
+ cyclic?: % -> Boolean
+ ++ cyclic?(t) tests if t is a cyclic tree.
+ cyclicCopy: % -> %
+ ++ cyclicCopy(l) makes a copy of a (possibly) cyclic tree l.
+ cyclicEntries: % -> List %
+ ++ cyclicEntries(t) returns a list of top-level cycles in tree t.
+ cyclicEqual?: (%, %) -> Boolean
+ ++ cyclicEqual?(t1, t2) tests of two cyclic trees have
+ ++ the same structure.
+ cyclicParents: % -> List %
+ ++ cyclicParents(t) returns a list of cycles that are parents of t.
+ C== add
+ cycleTreeMax ==> 5
+
+ Rep := Union(node:Record(value: S, args: List %),empty:"empty")
+ t:%
+ br:%
+ s: S
+ ls: List S
+ empty? t == t case empty
+ empty() == ["empty"]
+ children t ==
+ t case empty => error "cannot take the children of an empty tree"
+ (t.node.args)@List(%)
+ setchildren_!(t,lt) ==
+ t case empty => error "cannot set children of an empty tree"
+ (t.node.args:=lt;t pretend %)
+ setvalue_!(t,s) ==
+ t case empty => error "cannot set value of an empty tree"
+ (t.node.value:=s;s)
+ count(n, t) ==
+ t case empty => 0
+ i := +/[count(n, c) for c in children t]
+ value t = n => i + 1
+ i
+ count(fn: S -> Boolean, t: %): NonNegativeInteger ==
+ t case empty => 0
+ i := +/[count(fn, c) for c in children t]
+ fn value t => i + 1
+ i
+ map(fn, t) ==
+ t case empty => t
+ tree(fn value t,[map(fn, c) for c in children t])
+ map_!(fn, t) ==
+ t case empty => t
+ setvalue_!(t, fn value t)
+ for c in children t repeat map_!(fn, c)
+ tree(s,lt) == [[s,lt]]
+ tree(s) == [[s,[]]]
+ tree(ls) ==
+ empty? ls => empty()
+ tree(first ls, [tree s for s in rest ls])
+ value t ==
+ t case empty => error "cannot take the value of an empty tree"
+ t.node.value
+ child?(t1,t2) ==
+ empty? t2 => false
+ "or"/[t1 = t for t in children t2]
+ distance1(t1: %, t2: %): Integer ==
+ t1 = t2 => 0
+ t2 case empty => -1
+ u := [n for t in children t2 | (n := distance1(t1,t)) >= 0]
+ #u > 0 => 1 + "min"/u
+ -1
+ distance(t1,t2) ==
+ n := distance1(t1, t2)
+ n >= 0 => n
+ distance1(t2, t1)
+ node?(t1, t2) ==
+ t1 = t2 => true
+ t case empty => false
+ "or"/[node?(t1, t) for t in children t2]
+ leaf? t ==
+ t case empty => false
+ empty? children t
+ leaves t ==
+ t case empty => empty()
+ leaf? t => [value t]
+ "append"/[leaves c for c in children t]
+ less? (t, n) == # t < n
+ more?(t, n) == # t > n
+ nodes t == ---buggy
+ t case empty => empty()
+ nl := [nodes c for c in children t]
+ nl = empty() => [t]
+ cons(t,"append"/nl)
+ size? (t, n) == # t = n
+ any?(fn, t) == ---bug fixed
+ t case empty => false
+ fn value t or "or"/[any?(fn, c) for c in children t]
+ every?(fn, t) ==
+ t case empty => true
+ fn value t and "and"/[every?(fn, c) for c in children t]
+ member?(n, t) ==
+ t case empty => false
+ n = value t or "or"/[member?(n, c) for c in children t]
+ members t == parts t
+ parts t == --buggy?
+ t case empty => empty()
+ u := [parts c for c in children t]
+ u = empty() => [value t]
+ cons(value t,"append"/u)
+
+ ---Functions that guard against cycles: =, #, copy-------------
+
+ -----> =
+ equal?: (%, %, %, %, Integer) -> Boolean
+
+ t1 = t2 == equal?(t1, t2, t1, t2, 0)
+
+ equal?(t1, t2, ot1, ot2, k) ==
+ k = cycleTreeMax and (cyclic? ot1 or cyclic? ot2) =>
+ error "use cyclicEqual? to test equality on cyclic trees"
+ t1 case empty => t2 case empty
+ t2 case empty => false
+ value t1 = value t2 and (c1 := children t1) = (c2 := children t2) and
+ "and"/[equal?(x,y,ot1, ot2,k + 1) for x in c1 for y in c2]
+
+ -----> #
+ treeCount: (%, %, NonNegativeInteger) -> NonNegativeInteger
+ # t == treeCount(t, t, 0)
+ treeCount(t, origTree, k) ==
+ k = cycleTreeMax and cyclic? origTree =>
+ error "# is not defined on cyclic trees"
+ t case empty => 0
+ 1 + +/[treeCount(c, origTree, k + 1) for c in children t]
+
+ -----> copy
+ copy1: (%, %, Integer) -> %
+ copy t == copy1(t, t, 0)
+ copy1(t, origTree, k) ==
+ k = cycleTreeMax and cyclic? origTree =>
+ error "use cyclicCopy to copy a cyclic tree"
+ t case empty => t
+ empty? children t => tree value t
+ tree(value t, [copy1(x, origTree, k + 1) for x in children t])
+
+ -----------Functions that allow cycles---------------
+ --local utility functions:
+ eqUnion: (List %, List %) -> List %
+ eqMember?: (%, List %) -> Boolean
+ eqMemberIndex: (%, List %, Integer) -> Integer
+ lastNode: List % -> List %
+ insert: (%, List %) -> List %
+
+ -----> coerce to OutputForm
+ if S has SetCategory then
+ multipleOverbar: (OutputForm, Integer, List %) -> OutputForm
+ coerce1: (%, List %, List %) -> OutputForm
+
+ coerce(t:%): OutputForm == coerce1(t, empty()$(List %), cyclicParents t)
+
+ coerce1(t,parents, pl) ==
+ t case empty => empty()@List(S)::OutputForm
+ eqMember?(t, parents) =>
+ multipleOverbar((".")::OutputForm,eqMemberIndex(t, pl,0),pl)
+ empty? children t => value t::OutputForm
+ nodeForm := (value t)::OutputForm
+ if (k := eqMemberIndex(t, pl, 0)) > 0 then
+ nodeForm := multipleOverbar(nodeForm, k, pl)
+ prefix(nodeForm,
+ [coerce1(br,cons(t,parents),pl) for br in children t])
+
+ multipleOverbar(x, k, pl) ==
+ k < 1 => x
+ #pl = 1 => overbar x
+ s : String := "abcdefghijklmnopqrstuvwxyz"
+ c := s.(1 + ((k - 1) rem 26))
+ overlabel(c::OutputForm, x)
+
+ -----> cyclic?
+ cyclic2?: (%, List %) -> Boolean
+
+ cyclic? t == cyclic2?(t, empty()$(List %))
+
+ cyclic2?(x,parents) ==
+ empty? x => false
+ eqMember?(x, parents) => true
+ for y in children x repeat
+ cyclic2?(y,cons(x, parents)) => return true
+ false
+
+ -----> cyclicCopy
+ cyclicCopy2: (%, List %) -> %
+ copyCycle2: (%, List %) -> %
+ copyCycle4: (%, %, %, List %) -> %
+
+ cyclicCopy(t) == cyclicCopy2(t, cyclicEntries t)
+
+ cyclicCopy2(t, cycles) ==
+ eqMember?(t, cycles) => return copyCycle2(t, cycles)
+ tree(value t, [cyclicCopy2(c, cycles) for c in children t])
+
+ copyCycle2(cycle, cycleList) ==
+ newCycle := tree(value cycle, nil)
+ setchildren!(newCycle,
+ [copyCycle4(c,cycle,newCycle, cycleList) for c in children cycle])
+ newCycle
+
+ copyCycle4(t, cycle, newCycle, cycleList) ==
+ empty? cycle => empty()
+ eq?(t, cycle) => newCycle
+ eqMember?(t, cycleList) => copyCycle2(t, cycleList)
+ tree(value t,
+ [copyCycle4(c, cycle, newCycle, cycleList) for c in children t])
+
+ -----> cyclicEntries
+ cyclicEntries3: (%, List %, List %) -> List %
+
+ cyclicEntries(t) == cyclicEntries3(t, empty()$(List %), empty()$(List %))
+
+ cyclicEntries3(t, parents, cl) ==
+ empty? t => cl
+ eqMember?(t, parents) => insert(t, cl)
+ parents := cons(t, parents)
+ for y in children t repeat
+ cl := cyclicEntries3(t, parents, cl)
+ cl
+
+ -----> cyclicEqual?
+ cyclicEqual4?: (%, %, List %, List %) -> Boolean
+
+ cyclicEqual?(t1, t2) ==
+ cp1 := cyclicParents t1
+ cp2 := cyclicParents t2
+ #cp1 ^= #cp2 or null cp1 => t1 = t2
+ cyclicEqual4?(t1, t2, cp1, cp2)
+
+ cyclicEqual4?(t1, t2, cp1, cp2) ==
+ t1 case empty => t2 case empty
+ t2 case empty => false
+ 0 ^= (k := eqMemberIndex(t1, cp1, 0)) => eq?(t2, cp2 . k)
+ value t1 = value t2 and
+ "and"/[cyclicEqual4?(x,y,cp1,cp2)
+ for x in children t1 for y in children t2]
+
+ -----> cyclicParents t
+ cyclicParents3: (%, List %, List %) -> List %
+
+ cyclicParents t == cyclicParents3(t, empty()$(List %), empty()$(List %))
+
+ cyclicParents3(x, parents, pl) ==
+ empty? x => pl
+ eqMember?(x, parents) =>
+ cycleMembers := [y for y in parents while not eq?(x,y)]
+ eqUnion(cons(x, cycleMembers), pl)
+ parents := cons(x, parents)
+ for y in children x repeat
+ pl := cyclicParents3(y, parents, pl)
+ pl
+
+ insert(x, l) ==
+ eqMember?(x, l) => l
+ cons(x, l)
+
+ lastNode l ==
+ empty? l => error "empty tree has no last node"
+ while not empty? rest l repeat l := rest l
+ l
+
+ eqMember?(y,l) ==
+ for x in l repeat eq?(x,y) => return true
+ false
+
+ eqMemberIndex(x, l, k) ==
+ null l => k
+ k := k + 1
+ eq?(x, first l) => k
+ eqMemberIndex(x, rest l, k)
+
+ eqUnion(u, v) ==
+ null u => v
+ x := first u
+ newV :=
+ eqMember?(x, v) => v
+ cons(x, v)
+ eqUnion(rest u, newV)
+
+@
+\section{category BTCAT BinaryTreeCategory}
+<<category BTCAT BinaryTreeCategory>>=
+)abbrev category BTCAT BinaryTreeCategory
+++ Author:W. H. Burge
+++ Date Created:17 Feb 1992
+++ Date Last Updated:
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: \spadtype{BinaryTreeCategory(S)} is the category of
+++ binary trees: a tree which is either empty or else is a \spadfun{node} consisting
+++ of a value and a \spadfun{left} and \spadfun{right}, both binary trees.
+BinaryTreeCategory(S: SetCategory): Category == BinaryRecursiveAggregate(S) with
+ shallowlyMutable
+ ++ Binary trees have updateable components
+ finiteAggregate
+ ++ Binary trees have a finite number of components
+ node: (%,S,%) -> %
+ ++ node(left,v,right) creates a binary tree with value \spad{v}, a binary
+ ++ tree \spad{left}, and a binary tree \spad{right}.
+ add
+ cycleTreeMax ==> 5
+
+ copy t ==
+ empty? t => empty()
+ node(copy left t, value t, copy right t)
+ if % has shallowlyMutable then
+ map_!(f,t) ==
+ empty? t => t
+ t.value := f(t.value)
+ map_!(f,left t)
+ map_!(f,right t)
+ t
+ if % has finiteAggregate then
+ treeCount : (%, NonNegativeInteger) -> NonNegativeInteger
+ #t == treeCount(t,0)
+ treeCount(t,k) ==
+ empty? t => k
+ k := k + 1
+ k = cycleTreeMax and cyclic? t => error "cyclic binary tree"
+ k := treeCount(left t,k)
+ treeCount(right t,k)
+
+@
+\section{domain BTREE BinaryTree}
+<<domain BTREE BinaryTree>>=
+)abbrev domain BTREE BinaryTree
+++ Description: \spadtype{BinaryTree(S)} is the domain of all
+++ binary trees. A binary tree over \spad{S} is either empty or has
+++ a \spadfun{value} which is an S and a \spadfun{right}
+++ and \spadfun{left} which are both binary trees.
+BinaryTree(S: SetCategory): Exports == Implementation where
+ Exports == BinaryTreeCategory(S) with
+ binaryTree: S -> %
+ ++ binaryTree(v) is an non-empty binary tree
+ ++ with value v, and left and right empty.
+ binaryTree: (%,S,%) -> %
+ ++ binaryTree(l,v,r) creates a binary tree with
+ ++ value v with left subtree l and right subtree r.
+ Implementation == add
+ Rep := List Tree S
+ t1 = t2 == (t1::Rep) =$Rep (t2::Rep)
+ empty()== [] pretend %
+ empty()== [] pretend %
+ node(l,v,r) == cons(tree(v,l:Rep),r:Rep)
+ binaryTree(l,v,r) == node(l,v,r)
+ binaryTree(v:S) == node(empty(),v,empty())
+ empty? t == empty?(t)$Rep
+ leaf? t == empty? t or empty? left t and empty? right t
+ right t ==
+ empty? t => error "binaryTree:no right"
+ rest t
+ left t ==
+ empty? t => error "binaryTree:no left"
+ children first t
+ value t==
+ empty? t => error "binaryTree:no value"
+ value first t
+ setvalue_! (t,nd)==
+ empty? t => error "binaryTree:no value to set"
+ setvalue_!(first(t:Rep),nd)
+ nd
+ setleft_!(t1,t2) ==
+ empty? t1 => error "binaryTree:no left to set"
+ setchildren_!(first(t1:Rep),t2:Rep)
+ t1
+ setright_!(t1,t2) ==
+ empty? t1 => error "binaryTree:no right to set"
+ setrest_!(t1:List Tree S,t2)
+
+@
+\section{domain BSTREE BinarySearchTree}
+<<domain BSTREE BinarySearchTree>>=
+)abbrev domain BSTREE BinarySearchTree
+++ Description: BinarySearchTree(S) is the domain of
+++ a binary trees where elements are ordered across the tree.
+++ A binary search tree is either empty or has
+++ a value which is an S, and a
+++ right and left which are both BinaryTree(S)
+++ Elements are ordered across the tree.
+BinarySearchTree(S: OrderedSet): Exports == Implementation where
+ Exports == BinaryTreeCategory(S) with
+ shallowlyMutable
+ finiteAggregate
+ binarySearchTree: List S -> %
+ ++ binarySearchTree(l) \undocumented
+ insert_!: (S,%) -> %
+ ++ insert!(x,b) inserts element x as leaves into binary search tree b.
+ insertRoot_!: (S,%) -> %
+ ++ insertRoot!(x,b) inserts element x as a root of binary search tree b.
+ split: (S,%) -> Record(less: %, greater: %)
+ ++ split(x,b) splits binary tree b into two trees, one with elements greater
+ ++ than x, the other with elements less than x.
+ Implementation == BinaryTree(S) add
+ Rep := BinaryTree(S)
+ binarySearchTree(u:List S) ==
+ null u => empty()
+ tree := binaryTree(first u)
+ for x in rest u repeat insert_!(x,tree)
+ tree
+ insert_!(x,t) ==
+ empty? t => binaryTree(x)
+ x >= value t =>
+ setright_!(t,insert_!(x,right t))
+ t
+ setleft_!(t,insert_!(x,left t))
+ t
+ split(x,t) ==
+ empty? t => [empty(),empty()]
+ x > value t =>
+ a := split(x,right t)
+ [node(left t, value t, a.less), a.greater]
+ a := split(x,left t)
+ [a.less, node(a.greater, value t, right t)]
+ insertRoot_!(x,t) ==
+ a := split(x,t)
+ node(a.less, x, a.greater)
+
+@
+\section{domain BTOURN BinaryTournament}
+<<domain BTOURN BinaryTournament>>=
+)abbrev domain BTOURN BinaryTournament
+++ Description: \spadtype{BinaryTournament(S)} is the domain of
+++ binary trees where elements are ordered down the tree.
+++ A binary search tree is either empty or is a node containing a
+++ \spadfun{value} of type \spad{S}, and a \spadfun{right}
+++ and a \spadfun{left} which are both \spadtype{BinaryTree(S)}
+BinaryTournament(S: OrderedSet): Exports == Implementation where
+ Exports == BinaryTreeCategory(S) with
+ shallowlyMutable
+ binaryTournament: List S -> %
+ ++ binaryTournament(ls) creates a binary tournament with the
+ ++ elements of ls as values at the nodes.
+ insert_!: (S,%) -> %
+ ++ insert!(x,b) inserts element x as leaves into binary tournament b.
+ Implementation == BinaryTree(S) add
+ Rep := BinaryTree(S)
+ binaryTournament(u:List S) ==
+ null u => empty()
+ tree := binaryTree(first u)
+ for x in rest u repeat insert_!(x,tree)
+ tree
+ insert_!(x,t) ==
+ empty? t => binaryTree(x)
+ x > value t =>
+ setleft_!(t,copy t)
+ setvalue_!(t,x)
+ setright_!(t,empty())
+ setright_!(t,insert_!(x,right t))
+ t
+
+@
+\section{domain BBTREE BalancedBinaryTree}
+<<domain BBTREE BalancedBinaryTree>>=
+)abbrev domain BBTREE BalancedBinaryTree
+++ Description: \spadtype{BalancedBinaryTree(S)} is the domain of balanced
+++ binary trees (bbtree). A balanced binary tree of \spad{2**k} leaves,
+++ for some \spad{k > 0}, is symmetric, that is, the left and right
+++ subtree of each interior node have identical shape.
+++ In general, the left and right subtree of a given node can differ
+++ by at most leaf node.
+BalancedBinaryTree(S: SetCategory): Exports == Implementation where
+ Exports == BinaryTreeCategory(S) with
+ finiteAggregate
+ shallowlyMutable
+-- BUG: applies wrong fnct for balancedBinaryTree(0,[1,2,3,4])
+-- balancedBinaryTree: (S, List S) -> %
+-- ++ balancedBinaryTree(s, ls) creates a balanced binary tree with
+-- ++ s at the interior nodes and elements of ls at the
+-- ++ leaves.
+ balancedBinaryTree: (NonNegativeInteger, S) -> %
+ ++ balancedBinaryTree(n, s) creates a balanced binary tree with
+ ++ n nodes each with value s.
+ setleaves_!: (%, List S) -> %
+ ++ setleaves!(t, ls) sets the leaves of t in left-to-right order
+ ++ to the elements of ls.
+ mapUp_!: (%, (S,S) -> S) -> S
+ ++ mapUp!(t,f) traverses balanced binary tree t in an "endorder"
+ ++ (left then right then node) fashion returning t with the value
+ ++ at each successive interior node of t replaced by
+ ++ f(l,r) where l and r are the values at the immediate
+ ++ left and right nodes.
+ mapUp_!: (%, %, (S,S,S,S) -> S) -> %
+ ++ mapUp!(t,t1,f) traverses t in an "endorder" (left then right then node)
+ ++ fashion returning t with the value at each successive interior
+ ++ node of t replaced by
+ ++ f(l,r,l1,r1) where l and r are the values at the immediate
+ ++ left and right nodes. Values l1 and r1 are values at the
+ ++ corresponding nodes of a balanced binary tree t1, of identical
+ ++ shape at t.
+ mapDown_!: (%,S,(S,S) -> S) -> %
+ ++ mapDown!(t,p,f) returns t after traversing t in "preorder"
+ ++ (node then left then right) fashion replacing the successive
+ ++ interior nodes as follows. The root value x is
+ ++ replaced by q := f(p,x). The mapDown!(l,q,f) and
+ ++ mapDown!(r,q,f) are evaluated for the left and right subtrees
+ ++ l and r of t.
+ mapDown_!: (%,S, (S,S,S) -> List S) -> %
+ ++ mapDown!(t,p,f) returns t after traversing t in "preorder"
+ ++ (node then left then right) fashion replacing the successive
+ ++ interior nodes as follows. Let l and r denote the left and
+ ++ right subtrees of t. The root value x of t is replaced by p.
+ ++ Then f(value l, value r, p), where l and r denote the left
+ ++ and right subtrees of t, is evaluated producing two values
+ ++ pl and pr. Then \spad{mapDown!(l,pl,f)} and \spad{mapDown!(l,pr,f)}
+ ++ are evaluated.
+ Implementation == BinaryTree(S) add
+ Rep := BinaryTree(S)
+ leaf? x ==
+ empty? x => false
+ empty? left x and empty? right x
+-- balancedBinaryTree(x: S, u: List S) ==
+-- n := #u
+-- n = 0 => empty()
+-- setleaves_!(balancedBinaryTree(n, x), u)
+ setleaves_!(t, u) ==
+ n := #u
+ n = 0 =>
+ empty? t => t
+ error "the tree and list must have the same number of elements"
+ n = 1 =>
+ setvalue_!(t,first u)
+ t
+ m := n quo 2
+ acc := empty()$(List S)
+ for i in 1..m repeat
+ acc := [first u,:acc]
+ u := rest u
+ setleaves_!(left t, reverse_! acc)
+ setleaves_!(right t, u)
+ t
+ balancedBinaryTree(n: NonNegativeInteger, val: S) ==
+ n = 0 => empty()
+ n = 1 => node(empty(),val,empty())
+ m := n quo 2
+ node(balancedBinaryTree(m, val), val,
+ balancedBinaryTree((n - m) pretend NonNegativeInteger, val))
+ mapUp_!(x,fn) ==
+ empty? x => error "mapUp! called on a null tree"
+ leaf? x => x.value
+ x.value := fn(mapUp_!(x.left,fn),mapUp_!(x.right,fn))
+ mapUp_!(x,y,fn) ==
+ empty? x => error "mapUp! is called on a null tree"
+ leaf? x =>
+ leaf? y => x
+ error "balanced binary trees are incompatible"
+ leaf? y => error "balanced binary trees are incompatible"
+ mapUp_!(x.left,y.left,fn)
+ mapUp_!(x.right,y.right,fn)
+ x.value := fn(x.left.value,x.right.value,y.left.value,y.right.value)
+ x
+ mapDown_!(x: %, p: S, fn: (S,S) -> S ) ==
+ empty? x => x
+ x.value := fn(p, x.value)
+ mapDown_!(x.left, x.value, fn)
+ mapDown_!(x.right, x.value, fn)
+ x
+ mapDown_!(x: %, p: S, fn: (S,S,S) -> List S) ==
+ empty? x => x
+ x.value := p
+ leaf? x => x
+ u := fn(x.left.value, x.right.value, p)
+ mapDown_!(x.left, u.1, fn)
+ mapDown_!(x.right, u.2, fn)
+ x
+
+@
+\section{domain PENDTREE PendantTree}
+<<domain PENDTREE PendantTree>>=
+)abbrev domain PENDTREE PendantTree
+++ A PendantTree(S)is either a leaf? and is an S or has
+++ a left and a right both PendantTree(S)'s
+PendantTree(S: SetCategory): T == C where
+ T == BinaryRecursiveAggregate(S) with
+ ptree : S->%
+ ++ ptree(s) is a leaf? pendant tree
+ ptree:(%, %)->%
+ ++ ptree(x,y) \undocumented
+ coerce:%->Tree S
+ ++ coerce(x) \undocumented
+
+
+ C == add
+ Rep := Tree S
+ import Tree S
+ coerce (t:%):Tree S == t pretend Tree S
+ ptree(n) == tree(n,[])$Rep pretend %
+ ptree(l,r) == tree(value(r:Rep)$Rep,cons(l,children(r:Rep)$Rep)):%
+ leaf? t == empty?(children(t)$Rep)
+ t1=t2 == (t1:Rep) = (t2:Rep)
+ left b ==
+ leaf? b => error "ptree:no left"
+ first(children(b)$Rep)
+ right b ==
+ leaf? b => error "ptree:no right"
+ tree(value(b)$Rep,rest (children(b)$Rep))
+ value b ==
+ leaf? b => value(b)$Rep
+ error "the pendant tree has no value"
+ coerce(b:%): OutputForm ==
+ leaf? b => value(b)$Rep :: OutputForm
+ paren blankSeparate [left b::OutputForm,right b ::OutputForm]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain TREE Tree>>
+<<category BTCAT BinaryTreeCategory>>
+<<domain BTREE BinaryTree>>
+<<domain BBTREE BalancedBinaryTree>>
+<<domain BSTREE BinarySearchTree>>
+<<domain BTOURN BinaryTournament>>
+<<domain PENDTREE PendantTree>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/trigcat.spad.pamphlet b/src/algebra/trigcat.spad.pamphlet
new file mode 100644
index 00000000..e3d7bb32
--- /dev/null
+++ b/src/algebra/trigcat.spad.pamphlet
@@ -0,0 +1,333 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra trigcat.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category ELEMFUN ElementaryFunctionCategory}
+<<category ELEMFUN ElementaryFunctionCategory>>=
+)abbrev category ELEMFUN ElementaryFunctionCategory
+++ Category for the elementary functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the elementary functions;
+ElementaryFunctionCategory(): Category == with
+ log : $ -> $ ++ log(x) returns the natural logarithm of x.
+ exp : $ -> $ ++ exp(x) returns %e to the power x.
+ "**": ($, $) -> $ ++ x**y returns x to the power y.
+ add
+ if $ has Monoid then
+ x ** y == exp(y * log x)
+
+@
+\section{category AHYP ArcHyperbolicFunctionCategory}
+<<category AHYP ArcHyperbolicFunctionCategory>>=
+)abbrev category AHYP ArcHyperbolicFunctionCategory
+++ Category for the inverse hyperbolic trigonometric functions
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description:
+++ Category for the inverse hyperbolic trigonometric functions;
+ArcHyperbolicFunctionCategory(): Category == with
+ acosh: $ -> $ ++ acosh(x) returns the hyperbolic arc-cosine of x.
+ acoth: $ -> $ ++ acoth(x) returns the hyperbolic arc-cotangent of x.
+ acsch: $ -> $ ++ acsch(x) returns the hyperbolic arc-cosecant of x.
+ asech: $ -> $ ++ asech(x) returns the hyperbolic arc-secant of x.
+ asinh: $ -> $ ++ asinh(x) returns the hyperbolic arc-sine of x.
+ atanh: $ -> $ ++ atanh(x) returns the hyperbolic arc-tangent of x.
+
+@
+\section{category ATRIG ArcTrigonometricFunctionCategory}
+The [[asec]] and [[acsc]] functions were modified to include an
+intermediate test to check that the argument has a reciprocal values.
+<<category ATRIG ArcTrigonometricFunctionCategory>>=
+)abbrev category ATRIG ArcTrigonometricFunctionCategory
+++ Category for the inverse trigonometric functions
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the inverse trigonometric functions;
+ArcTrigonometricFunctionCategory(): Category == with
+ acos: $ -> $ ++ acos(x) returns the arc-cosine of x.
+ acot: $ -> $ ++ acot(x) returns the arc-cotangent of x.
+ acsc: $ -> $ ++ acsc(x) returns the arc-cosecant of x.
+ asec: $ -> $ ++ asec(x) returns the arc-secant of x.
+ asin: $ -> $ ++ asin(x) returns the arc-sine of x.
+ atan: $ -> $ ++ atan(x) returns the arc-tangent of x.
+ add
+ if $ has Ring then
+ asec(x) ==
+ (a := recip x) case "failed" => error "asec: no reciprocal"
+ acos(a::$)
+ acsc(x) ==
+ (a := recip x) case "failed" => error "acsc: no reciprocal"
+ asin(a::$)
+
+@
+\section{category HYPCAT HyperbolicFunctionCategory}
+The [[csch]] and [[sech]] functions were modified to include an
+intermediate test to check that the argument has a reciprocal values.
+<<category HYPCAT HyperbolicFunctionCategory>>=
+)abbrev category HYPCAT HyperbolicFunctionCategory
+++ Category for the hyperbolic trigonometric functions
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the hyperbolic trigonometric functions;
+HyperbolicFunctionCategory(): Category == with
+ cosh: $ -> $ ++ cosh(x) returns the hyperbolic cosine of x.
+ coth: $ -> $ ++ coth(x) returns the hyperbolic cotangent of x.
+ csch: $ -> $ ++ csch(x) returns the hyperbolic cosecant of x.
+ sech: $ -> $ ++ sech(x) returns the hyperbolic secant of x.
+ sinh: $ -> $ ++ sinh(x) returns the hyperbolic sine of x.
+ tanh: $ -> $ ++ tanh(x) returns the hyperbolic tangent of x.
+ add
+ if $ has Ring then
+ csch x ==
+ (a := recip(sinh x)) case "failed" => error "csch: no reciprocal"
+ a::$
+ sech x ==
+ (a := recip(cosh x)) case "failed" => error "sech: no reciprocal"
+ a::$
+ tanh x == sinh x * sech x
+ coth x == cosh x * csch x
+ if $ has ElementaryFunctionCategory then
+ cosh x ==
+ e := exp x
+ (e + recip(e)::$) * recip(2::$)::$
+ sinh(x):$ ==
+ e := exp x
+ (e - recip(e)::$) * recip(2::$)::$
+
+@
+\section{category TRANFUN TranscendentalFunctionCategory}
+The [[acsch]], [[asech]], and [[acoth]] functions were modified to
+include an intermediate test to check that the argument has a
+reciprocal values.
+<<category TRANFUN TranscendentalFunctionCategory>>=
+)abbrev category TRANFUN TranscendentalFunctionCategory
+++ Category for the transcendental elementary functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the transcendental elementary functions;
+TranscendentalFunctionCategory(): Category ==
+ Join(TrigonometricFunctionCategory,ArcTrigonometricFunctionCategory,
+ HyperbolicFunctionCategory,ArcHyperbolicFunctionCategory,
+ ElementaryFunctionCategory) with
+ pi : () -> $ ++ pi() returns the constant pi.
+ add
+ if $ has Ring then
+ pi() == 2*asin(1)
+ acsch x ==
+ (a := recip x) case "failed" => error "acsch: no reciprocal"
+ asinh(a::$)
+ asech x ==
+ (a := recip x) case "failed" => error "asech: no reciprocal"
+ acosh(a::$)
+ acoth x ==
+ (a := recip x) case "failed" => error "acoth: no reciprocal"
+ atanh(a::$)
+ if $ has Field and $ has sqrt: $ -> $ then
+ asin x == atan(x/sqrt(1-x**2))
+ acos x == pi()/2::$ - asin x
+ acot x == pi()/2::$ - atan x
+ asinh x == log(x + sqrt(x**2 + 1))
+ acosh x == 2*log(sqrt((x+1)/2::$) + sqrt((x-1)/2::$))
+ atanh x == (log(1+x)-log(1-x))/2::$
+
+@
+\section{category TRIGCAT TrigonometricFunctionCategory}
+The [[csc]] and [[sec]] functions were modified to include an
+intermediate test to check that the argument has a reciprocal values.
+<<category TRIGCAT TrigonometricFunctionCategory>>=
+)abbrev category TRIGCAT TrigonometricFunctionCategory
+++ Category for the trigonometric functions
+++ Author: ???
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the trigonometric functions;
+TrigonometricFunctionCategory(): Category == with
+ cos: $ -> $ ++ cos(x) returns the cosine of x.
+ cot: $ -> $ ++ cot(x) returns the cotangent of x.
+ csc: $ -> $ ++ csc(x) returns the cosecant of x.
+ sec: $ -> $ ++ sec(x) returns the secant of x.
+ sin: $ -> $ ++ sin(x) returns the sine of x.
+ tan: $ -> $ ++ tan(x) returns the tangent of x.
+ add
+ if $ has Ring then
+ csc x ==
+ (a := recip(sin x)) case "failed" => error "csc: no reciprocal"
+ a::$
+ sec x ==
+ (a := recip(cos x)) case "failed" => error "sec: no reciprocal"
+ a::$
+ tan x == sin x * sec x
+ cot x == cos x * csc x
+
+@
+\section{category PRIMCAT PrimitiveFunctionCategory}
+<<category PRIMCAT PrimitiveFunctionCategory>>=
+)abbrev category PRIMCAT PrimitiveFunctionCategory
+++ Category for the integral functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the functions defined by integrals;
+PrimitiveFunctionCategory(): Category == with
+ integral: ($, Symbol) -> $
+ ++ integral(f, x) returns the formal integral of f dx.
+ integral: ($, SegmentBinding $) -> $
+ ++ integral(f, x = a..b) returns the formal definite integral
+ ++ of f dx for x between \spad{a} and b.
+
+@
+\section{category LFCAT LiouvillianFunctionCategory}
+<<category LFCAT LiouvillianFunctionCategory>>=
+)abbrev category LFCAT LiouvillianFunctionCategory
+++ Category for the transcendental Liouvillian functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the transcendental Liouvillian functions;
+LiouvillianFunctionCategory(): Category ==
+ Join(PrimitiveFunctionCategory, TranscendentalFunctionCategory) with
+ Ei : $ -> $
+ ++ Ei(x) returns the exponential integral of x, i.e.
+ ++ the integral of \spad{exp(x)/x dx}.
+ Si : $ -> $
+ ++ Si(x) returns the sine integral of x, i.e.
+ ++ the integral of \spad{sin(x) / x dx}.
+ Ci : $ -> $
+ ++ Ci(x) returns the cosine integral of x, i.e.
+ ++ the integral of \spad{cos(x) / x dx}.
+ li : $ -> $
+ ++ li(x) returns the logarithmic integral of x, i.e.
+ ++ the integral of \spad{dx / log(x)}.
+ dilog : $ -> $
+ ++ dilog(x) returns the dilogarithm of x, i.e.
+ ++ the integral of \spad{log(x) / (1 - x) dx}.
+ erf : $ -> $
+ ++ erf(x) returns the error function of x, i.e.
+ ++ \spad{2 / sqrt(%pi)} times the integral of \spad{exp(-x**2) dx}.
+
+@
+\section{category CFCAT CombinatorialFunctionCategory}
+<<category CFCAT CombinatorialFunctionCategory>>=
+)abbrev category CFCAT CombinatorialFunctionCategory
+++ Category for the usual combinatorial functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 14 May 1991
+++ Description: Category for the usual combinatorial functions;
+CombinatorialFunctionCategory(): Category == with
+ binomial : ($, $) -> $
+ ++ binomial(n,r) returns the \spad{(n,r)} binomial coefficient
+ ++ (often denoted in the literature by \spad{C(n,r)}).
+ ++ Note: \spad{C(n,r) = n!/(r!(n-r)!)} where \spad{n >= r >= 0}.
+ factorial : $ -> $
+ ++ factorial(n) computes the factorial of n
+ ++ (denoted in the literature by \spad{n!})
+ ++ Note: \spad{n! = n (n-1)! when n > 0}; also, \spad{0! = 1}.
+ permutation: ($, $) -> $
+ ++ permutation(n, m) returns the number of
+ ++ permutations of n objects taken m at a time.
+ ++ Note: \spad{permutation(n,m) = n!/(n-m)!}.
+
+@
+\section{category SPFCAT SpecialFunctionCategory}
+<<category SPFCAT SpecialFunctionCategory>>=
+)abbrev category SPFCAT SpecialFunctionCategory
+++ Category for the other special functions
+++ Author: Manuel Bronstein
+++ Date Created: ???
+++ Date Last Updated: 11 May 1993
+++ Description: Category for the other special functions;
+SpecialFunctionCategory(): Category == with
+ abs : $ -> $
+ ++ abs(x) returns the absolute value of x.
+ Gamma: $ -> $
+ ++ Gamma(x) is the Euler Gamma function.
+ Beta: ($,$)->$
+ ++ Beta(x,y) is \spad{Gamma(x) * Gamma(y)/Gamma(x+y)}.
+ digamma: $ -> $
+ ++ digamma(x) is the logarithmic derivative of \spad{Gamma(x)}
+ ++ (often written \spad{psi(x)} in the literature).
+ polygamma: ($, $) -> $
+ ++ polygamma(k,x) is the \spad{k-th} derivative of \spad{digamma(x)},
+ ++ (often written \spad{psi(k,x)} in the literature).
+ Gamma: ($, $) -> $
+ ++ Gamma(a,x) is the incomplete Gamma function.
+ besselJ: ($,$) -> $
+ ++ besselJ(v,z) is the Bessel function of the first kind.
+ besselY: ($,$) -> $
+ ++ besselY(v,z) is the Bessel function of the second kind.
+ besselI: ($,$) -> $
+ ++ besselI(v,z) is the modified Bessel function of the first kind.
+ besselK: ($,$) -> $
+ ++ besselK(v,z) is the modified Bessel function of the second kind.
+ airyAi: $ -> $
+ ++ airyAi(x) is the Airy function \spad{Ai(x)}.
+ airyBi: $ -> $
+ ++ airyBi(x) is the Airy function \spad{Bi(x)}.
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category ELEMFUN ElementaryFunctionCategory>>
+<<category TRIGCAT TrigonometricFunctionCategory>>
+<<category ATRIG ArcTrigonometricFunctionCategory>>
+<<category HYPCAT HyperbolicFunctionCategory>>
+<<category AHYP ArcHyperbolicFunctionCategory>>
+<<category TRANFUN TranscendentalFunctionCategory>>
+<<category PRIMCAT PrimitiveFunctionCategory>>
+<<category LFCAT LiouvillianFunctionCategory>>
+<<category CFCAT CombinatorialFunctionCategory>>
+<<category SPFCAT SpecialFunctionCategory>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/triset.spad.pamphlet b/src/algebra/triset.spad.pamphlet
new file mode 100644
index 00000000..28327621
--- /dev/null
+++ b/src/algebra/triset.spad.pamphlet
@@ -0,0 +1,1739 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra triset.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category TSETCAT TriangularSetCategory}
+<<category TSETCAT TriangularSetCategory>>=
+)abbrev category TSETCAT TriangularSetCategory
+++ Author: Marc Moreno Maza (marc@nag.co.uk)
+++ Date Created: 04/26/1994
+++ Date Last Updated: 12/15/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords: polynomial, multivariate, ordered variables set
+++ Description:
+++ The category of triangular sets of multivariate polynomials
+++ with coefficients in an integral domain.
+++ Let \axiom{R} be an integral domain and \axiom{V} a finite ordered set of
+++ variables, say \axiom{X1 < X2 < ... < Xn}.
+++ A set \axiom{S} of polynomials in \axiom{R[X1,X2,...,Xn]} is triangular
+++ if no elements of \axiom{S} lies in \axiom{R}, and if two distinct
+++ elements of \axiom{S} have distinct main variables.
+++ Note that the empty set is a triangular set. A triangular set is not
+++ necessarily a (lexicographical) Groebner basis and the notion of
+++ reduction related to triangular sets is based on the recursive view
+++ of polynomials. We recall this notion here and refer to [1] for more details.
+++ A polynomial \axiom{P} is reduced w.r.t a non-constant polynomial
+++ \axiom{Q} if the degree of \axiom{P} in the main variable of \axiom{Q}
+++ is less than the main degree of \axiom{Q}.
+++ A polynomial \axiom{P} is reduced w.r.t a triangular set \axiom{T}
+++ if it is reduced w.r.t. every polynomial of \axiom{T}. \newline
+++ References :
+++ [1] P. AUBRY, D. LAZARD and M. MORENO MAZA "On the Theories
+++ of Triangular Sets" Journal of Symbol. Comp. (to appear)
+++ Version: 4.
+
+TriangularSetCategory(R:IntegralDomain,E:OrderedAbelianMonoidSup,_
+ V:OrderedSet,P:RecursivePolynomialCategory(R,E,V)):
+ Category ==
+ PolynomialSetCategory(R,E,V,P) with
+ finiteAggregate
+ shallowlyMutable
+
+ infRittWu? : ($,$) -> Boolean
+ ++ \axiom{infRittWu?(ts1,ts2)} returns true iff \axiom{ts2} has higher rank
+ ++ than \axiom{ts1} in Wu Wen Tsun sense.
+ basicSet : (List P,((P,P)->Boolean)) -> Union(Record(bas:$,top:List P),"failed")
+ ++ \axiom{basicSet(ps,redOp?)} returns \axiom{[bs,ts]} where
+ ++ \axiom{concat(bs,ts)} is \axiom{ps} and \axiom{bs}
+ ++ is a basic set in Wu Wen Tsun sense of \axiom{ps} w.r.t
+ ++ the reduction-test \axiom{redOp?}, if no non-zero constant
+ ++ polynomial lie in \axiom{ps}, otherwise \axiom{"failed"} is returned.
+ basicSet : (List P,(P->Boolean),((P,P)->Boolean)) -> Union(Record(bas:$,top:List P),"failed")
+ ++ \axiom{basicSet(ps,pred?,redOp?)} returns the same as \axiom{basicSet(qs,redOp?)}
+ ++ where \axiom{qs} consists of the polynomials of \axiom{ps}
+ ++ satisfying property \axiom{pred?}.
+ initials : $ -> List P
+ ++ \axiom{initials(ts)} returns the list of the non-constant initials
+ ++ of the members of \axiom{ts}.
+ degree : $ -> NonNegativeInteger
+ ++ \axiom{degree(ts)} returns the product of main degrees of the
+ ++ members of \axiom{ts}.
+ quasiComponent : $ -> Record(close:List P,open:List P)
+ ++ \axiom{quasiComponent(ts)} returns \axiom{[lp,lq]} where \axiom{lp} is the list
+ ++ of the members of \axiom{ts} and \axiom{lq}is \axiom{initials(ts)}.
+ normalized? : (P,$) -> Boolean
+ ++ \axiom{normalized?(p,ts)} returns true iff \axiom{p} and all its iterated initials
+ ++ have degree zero w.r.t. the main variables of the polynomials of \axiom{ts}
+ normalized? : $ -> Boolean
+ ++ \axiom{normalized?(ts)} returns true iff for every axiom{p} in axiom{ts} we have
+ ++ \axiom{normalized?(p,us)} where \axiom{us} is \axiom{collectUnder(ts,mvar(p))}.
+ reduced? : (P,$,((P,P) -> Boolean)) -> Boolean
+ ++ \axiom{reduced?(p,ts,redOp?)} returns true iff \axiom{p} is reduced w.r.t.
+ ++ in the sense of the operation \axiom{redOp?}, that is if for every \axiom{t} in
+ ++ \axiom{ts} \axiom{redOp?(p,t)} holds.
+ stronglyReduced? : (P,$) -> Boolean
+ ++ \axiom{stronglyReduced?(p,ts)} returns true iff \axiom{p}
+ ++ is reduced w.r.t. \axiom{ts}.
+ headReduced? : (P,$) -> Boolean
+ ++ \axiom{headReduced?(p,ts)} returns true iff the head of \axiom{p} is
+ ++ reduced w.r.t. \axiom{ts}.
+ initiallyReduced? : (P,$) -> Boolean
+ ++ \axiom{initiallyReduced?(p,ts)} returns true iff \axiom{p} and all its iterated initials
+ ++ are reduced w.r.t. to the elements of \axiom{ts} with the same main variable.
+ autoReduced? : ($,((P,List(P)) -> Boolean)) -> Boolean
+ ++ \axiom{autoReduced?(ts,redOp?)} returns true iff every element of \axiom{ts} is
+ ++ reduced w.r.t to every other in the sense of \axiom{redOp?}
+ stronglyReduced? : $ -> Boolean
+ ++ \axiom{stronglyReduced?(ts)} returns true iff every element of \axiom{ts} is
+ ++ reduced w.r.t to any other element of \axiom{ts}.
+ headReduced? : $ -> Boolean
+ ++ headReduced?(ts) returns true iff the head of every element of \axiom{ts} is
+ ++ reduced w.r.t to any other element of \axiom{ts}.
+ initiallyReduced? : $ -> Boolean
+ ++ initiallyReduced?(ts) returns true iff for every element \axiom{p} of \axiom{ts}
+ ++ \axiom{p} and all its iterated initials are reduced w.r.t. to the other elements
+ ++ of \axiom{ts} with the same main variable.
+ reduce : (P,$,((P,P) -> P),((P,P) -> Boolean) ) -> P
+ ++ \axiom{reduce(p,ts,redOp,redOp?)} returns a polynomial \axiom{r} such that
+ ++ \axiom{redOp?(r,p)} holds for every \axiom{p} of \axiom{ts}
+ ++ and there exists some product \axiom{h} of the initials of the members
+ ++ of \axiom{ts} such that \axiom{h*p - r} lies in the ideal generated by \axiom{ts}.
+ ++ The operation \axiom{redOp} must satisfy the following conditions.
+ ++ For every \axiom{p} and \axiom{q} we have \axiom{redOp?(redOp(p,q),q)}
+ ++ and there exists an integer \axiom{e} and a polynomial \axiom{f} such that
+ ++ \axiom{init(q)^e*p = f*q + redOp(p,q)}.
+ rewriteSetWithReduction : (List P,$,((P,P) -> P),((P,P) -> Boolean) ) -> List P
+ ++ \axiom{rewriteSetWithReduction(lp,ts,redOp,redOp?)} returns a list \axiom{lq} of
+ ++ polynomials such that \axiom{[reduce(p,ts,redOp,redOp?) for p in lp]} and \axiom{lp}
+ ++ have the same zeros inside the regular zero set of \axiom{ts}. Moreover, for every
+ ++ polynomial \axiom{q} in \axiom{lq} and every polynomial \axiom{t} in \axiom{ts}
+ ++ \axiom{redOp?(q,t)} holds and there exists a polynomial \axiom{p}
+ ++ in the ideal generated by \axiom{lp} and a product \axiom{h} of \axiom{initials(ts)}
+ ++ such that \axiom{h*p - r} lies in the ideal generated by \axiom{ts}.
+ ++ The operation \axiom{redOp} must satisfy the following conditions.
+ ++ For every \axiom{p} and \axiom{q} we have \axiom{redOp?(redOp(p,q),q)}
+ ++ and there exists an integer \axiom{e} and a polynomial \axiom{f}
+ ++ such that \axiom{init(q)^e*p = f*q + redOp(p,q)}.
+ stronglyReduce : (P,$) -> P
+ ++ \axiom{stronglyReduce(p,ts)} returns a polynomial \axiom{r} such that
+ ++ \axiom{stronglyReduced?(r,ts)} holds and there exists some product
+ ++ \axiom{h} of \axiom{initials(ts)}
+ ++ such that \axiom{h*p - r} lies in the ideal generated by \axiom{ts}.
+ headReduce : (P,$) -> P
+ ++ \axiom{headReduce(p,ts)} returns a polynomial \axiom{r} such that \axiom{headReduce?(r,ts)}
+ ++ holds and there exists some product \axiom{h} of \axiom{initials(ts)}
+ ++ such that \axiom{h*p - r} lies in the ideal generated by \axiom{ts}.
+ initiallyReduce : (P,$) -> P
+ ++ \axiom{initiallyReduce(p,ts)} returns a polynomial \axiom{r}
+ ++ such that \axiom{initiallyReduced?(r,ts)}
+ ++ holds and there exists some product \axiom{h} of \axiom{initials(ts)}
+ ++ such that \axiom{h*p - r} lies in the ideal generated by \axiom{ts}.
+ removeZero: (P, $) -> P
+ ++ \axiom{removeZero(p,ts)} returns \axiom{0} if \axiom{p} reduces
+ ++ to \axiom{0} by pseudo-division w.r.t \axiom{ts} otherwise
+ ++ returns a polynomial \axiom{q} computed from \axiom{p}
+ ++ by removing any coefficient in \axiom{p} reducing to \axiom{0}.
+ collectQuasiMonic: $ -> $
+ ++ \axiom{collectQuasiMonic(ts)} returns the subset of \axiom{ts}
+ ++ consisting of the polynomials with initial in \axiom{R}.
+ reduceByQuasiMonic: (P, $) -> P
+ ++ \axiom{reduceByQuasiMonic(p,ts)} returns the same as
+ ++ \axiom{remainder(p,collectQuasiMonic(ts)).polnum}.
+ zeroSetSplit : List P -> List $
+ ++ \axiom{zeroSetSplit(lp)} returns a list \axiom{lts} of triangular sets such that
+ ++ the zero set of \axiom{lp} is the union of the closures of the regular zero sets
+ ++ of the members of \axiom{lts}.
+ zeroSetSplitIntoTriangularSystems : List P -> List Record(close:$,open:List P)
+ ++ \axiom{zeroSetSplitIntoTriangularSystems(lp)} returns a list of triangular
+ ++ systems \axiom{[[ts1,qs1],...,[tsn,qsn]]} such that the zero set of \axiom{lp}
+ ++ is the union of the closures of the \axiom{W_i} where \axiom{W_i} consists
+ ++ of the zeros of \axiom{ts} which do not cancel any polynomial in \axiom{qsi}.
+ first : $ -> Union(P,"failed")
+ ++ \axiom{first(ts)} returns the polynomial of \axiom{ts} with greatest main variable
+ ++ if \axiom{ts} is not empty, otherwise returns \axiom{"failed"}.
+ last : $ -> Union(P,"failed")
+ ++ \axiom{last(ts)} returns the polynomial of \axiom{ts} with smallest main variable
+ ++ if \axiom{ts} is not empty, otherwise returns \axiom{"failed"}.
+ rest : $ -> Union($,"failed")
+ ++ \axiom{rest(ts)} returns the polynomials of \axiom{ts} with smaller main variable
+ ++ than \axiom{mvar(ts)} if \axiom{ts} is not empty, otherwise returns "failed"
+ algebraicVariables : $ -> List(V)
+ ++ \axiom{algebraicVariables(ts)} returns the decreasingly sorted list of the main
+ ++ variables of the polynomials of \axiom{ts}.
+ algebraic? : (V,$) -> Boolean
+ ++ \axiom{algebraic?(v,ts)} returns true iff \axiom{v} is the main variable of some
+ ++ polynomial in \axiom{ts}.
+ select : ($,V) -> Union(P,"failed")
+ ++ \axiom{select(ts,v)} returns the polynomial of \axiom{ts} with \axiom{v} as
+ ++ main variable, if any.
+ extendIfCan : ($,P) -> Union($,"failed")
+ ++ \axiom{extendIfCan(ts,p)} returns a triangular set which encodes the simple
+ ++ extension by \axiom{p} of the extension of the base field defined by \axiom{ts},
+ ++ according to the properties of triangular sets of the current domain.
+ ++ If the required properties do not hold then "failed" is returned.
+ ++ This operation encodes in some sense the properties of the
+ ++ triangular sets of the current category. Is is used to implement
+ ++ the \axiom{construct} operation to guarantee that every triangular
+ ++ set build from a list of polynomials has the required properties.
+ extend : ($,P) -> $
+ ++ \axiom{extend(ts,p)} returns a triangular set which encodes the simple
+ ++ extension by \axiom{p} of the extension of the base field defined by \axiom{ts},
+ ++ according to the properties of triangular sets of the current category
+ ++ If the required properties do not hold an error is returned.
+ if V has Finite
+ then
+ coHeight : $ -> NonNegativeInteger
+ ++ \axiom{coHeight(ts)} returns \axiom{size()\$V} minus \axiom{\#ts}.
+ add
+
+ GPS ==> GeneralPolynomialSet(R,E,V,P)
+ B ==> Boolean
+ RBT ==> Record(bas:$,top:List P)
+
+ ts:$ = us:$ ==
+ empty?(ts)$$ => empty?(us)$$
+ empty?(us)$$ => false
+ first(ts)::P =$P first(us)::P => rest(ts)::$ =$$ rest(us)::$
+ false
+
+ infRittWu?(ts,us) ==
+ empty?(us)$$ => not empty?(ts)$$
+ empty?(ts)$$ => false
+ p : P := (last(ts))::P
+ q : P := (last(us))::P
+ infRittWu?(p,q)$P => true
+ supRittWu?(p,q)$P => false
+ v : V := mvar(p)
+ infRittWu?(collectUpper(ts,v),collectUpper(us,v))$$
+
+ reduced?(p,ts,redOp?) ==
+ lp : List P := members(ts)
+ while (not empty? lp) and (redOp?(p,first(lp))) repeat
+ lp := rest lp
+ empty? lp
+
+ basicSet(ps,redOp?) ==
+ ps := remove(zero?,ps)
+ any?(ground?,ps) => "failed"::Union(RBT,"failed")
+ ps := sort(infRittWu?,ps)
+ p,b : P
+ bs := empty()$$
+ ts : List P := []
+ while not empty? ps repeat
+ b := first(ps)
+ bs := extend(bs,b)$$
+ ps := rest ps
+ while (not empty? ps) and (not reduced?((p := first(ps)),bs,redOp?)) repeat
+ ts := cons(p,ts)
+ ps := rest ps
+ ([bs,ts]$RBT)::Union(RBT,"failed")
+
+ basicSet(ps,pred?,redOp?) ==
+ ps := remove(zero?,ps)
+ any?(ground?,ps) => "failed"::Union(RBT,"failed")
+ gps : List P := []
+ bps : List P := []
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ if pred?(p)
+ then
+ gps := cons(p,gps)
+ else
+ bps := cons(p,bps)
+ gps := sort(infRittWu?,gps)
+ p,b : P
+ bs := empty()$$
+ ts : List P := []
+ while not empty? gps repeat
+ b := first(gps)
+ bs := extend(bs,b)$$
+ gps := rest gps
+ while (not empty? gps) and (not reduced?((p := first(gps)),bs,redOp?)) repeat
+ ts := cons(p,ts)
+ gps := rest gps
+ ts := sort(infRittWu?,concat(ts,bps))
+ ([bs,ts]$RBT)::Union(RBT,"failed")
+
+ initials ts ==
+ lip : List P := []
+ empty? ts => lip
+ lp := members(ts)
+ while not empty? lp repeat
+ p := first(lp)
+ if not ground?((ip := init(p)))
+ then
+ lip := cons(primPartElseUnitCanonical(ip),lip)
+ lp := rest lp
+ removeDuplicates lip
+
+ degree ts ==
+ empty? ts => 0$NonNegativeInteger
+ lp := members ts
+ d : NonNegativeInteger := mdeg(first lp)
+ while not empty? (lp := rest lp) repeat
+ d := d * mdeg(first lp)
+ d
+
+ quasiComponent ts ==
+ [members(ts),initials(ts)]
+
+ normalized?(p,ts) ==
+ normalized?(p,members(ts))$P
+
+ stronglyReduced? (p,ts) ==
+ reduced?(p,members(ts))$P
+
+ headReduced? (p,ts) ==
+ stronglyReduced?(head(p),ts)
+
+ initiallyReduced? (p,ts) ==
+ lp : List (P) := members(ts)
+ red : Boolean := true
+ while (not empty? lp) and (not ground?(p)$P) and red repeat
+ while (not empty? lp) and (mvar(first(lp)) > mvar(p)) repeat
+ lp := rest lp
+ if (not empty? lp)
+ then
+ if (mvar(first(lp)) = mvar(p))
+ then
+ if reduced?(p,first(lp))
+ then
+ lp := rest lp
+ p := init(p)
+ else
+ red := false
+ else
+ p := init(p)
+ red
+
+ reduce(p,ts,redOp,redOp?) ==
+ (empty? ts) or (ground? p) => p
+ ts0 := ts
+ while (not empty? ts) and (not ground? p) repeat
+ reductor := (first ts)::P
+ ts := (rest ts)::$
+ if not redOp?(p,reductor)
+ then
+ p := redOp(p,reductor)
+ ts := ts0
+ p
+
+ rewriteSetWithReduction(lp,ts,redOp,redOp?) ==
+ trivialIdeal? ts => lp
+ lp := remove(zero?,lp)
+ empty? lp => lp
+ any?(ground?,lp) => [1$P]
+ rs : List P := []
+ while not empty? lp repeat
+ p := first lp
+ lp := rest lp
+ p := primPartElseUnitCanonical reduce(p,ts,redOp,redOp?)
+ if not zero? p
+ then
+ if ground? p
+ then
+ lp := []
+ rs := [1$P]
+ else
+ rs := cons(p,rs)
+ removeDuplicates rs
+
+ stronglyReduce(p,ts) ==
+ reduce (p,ts,lazyPrem,reduced?)
+
+ headReduce(p,ts) ==
+ reduce (p,ts,headReduce,headReduced?)
+
+ initiallyReduce(p,ts) ==
+ reduce (p,ts,initiallyReduce,initiallyReduced?)
+
+ removeZero(p,ts) ==
+ (ground? p) or (empty? ts) => p
+ v := mvar(p)
+ ts_v_- := collectUnder(ts,v)
+ if algebraic?(v,ts)
+ then
+ q := lazyPrem(p,select(ts,v)::P)
+ zero? q => return q
+ zero? removeZero(q,ts_v_-) => return 0
+ empty? ts_v_- => p
+ q: P := 0
+ while positive? degree(p,v) repeat
+ q := removeZero(init(p),ts_v_-) * mainMonomial(p) + q
+ p := tail(p)
+ q + removeZero(p,ts_v_-)
+
+ reduceByQuasiMonic(p, ts) ==
+ (ground? p) or (empty? ts) => p
+ remainder(p,collectQuasiMonic(ts)).polnum
+
+ autoReduced?(ts : $,redOp? : ((P,List(P)) -> Boolean)) ==
+ empty? ts => true
+ lp : List (P) := members(ts)
+ p : P := first(lp)
+ lp := rest lp
+ while (not empty? lp) and redOp?(p,lp) repeat
+ p := first lp
+ lp := rest lp
+ empty? lp
+
+ stronglyReduced? ts ==
+ autoReduced? (ts, reduced?)
+
+ normalized? ts ==
+ autoReduced? (ts,normalized?)
+
+ headReduced? ts ==
+ autoReduced? (ts,headReduced?)
+
+ initiallyReduced? ts ==
+ autoReduced? (ts,initiallyReduced?)
+
+ mvar ts ==
+ empty? ts => error"Error from TSETCAT in mvar : #1 is empty"
+ mvar((first(ts))::P)$P
+
+ first ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ lp : List(P) := sort(supRittWu?,members(ts))$(List P)
+ first(lp)::Union(P,"failed")
+
+ last ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ lp : List(P) := sort(infRittWu?,members(ts))$(List P)
+ first(lp)::Union(P,"failed")
+
+ rest ts ==
+ empty? ts => "failed"::Union($,"failed")
+ lp : List(P) := sort(supRittWu?,members(ts))$(List P)
+ construct(rest(lp))::Union($,"failed")
+
+ coerce (ts:$) : List(P) ==
+ sort(supRittWu?,members(ts))$(List P)
+
+ algebraicVariables ts ==
+ [mvar(p) for p in members(ts)]
+
+ algebraic? (v,ts) ==
+ member?(v,algebraicVariables(ts))
+
+ select (ts,v) ==
+ lp : List (P) := sort(supRittWu?,members(ts))$(List P)
+ while (not empty? lp) and (not (v = mvar(first lp))) repeat
+ lp := rest lp
+ empty? lp => "failed"::Union(P,"failed")
+ (first lp)::Union(P,"failed")
+
+ collectQuasiMonic ts ==
+ lp: List(P) := members(ts)
+ newlp: List(P) := []
+ while (not empty? lp) repeat
+ if ground? init(first(lp)) then newlp := cons(first(lp),newlp)
+ lp := rest lp
+ construct(newlp)
+
+ collectUnder (ts,v) ==
+ lp : List (P) := sort(supRittWu?,members(ts))$(List P)
+ while (not empty? lp) and (not (v > mvar(first lp))) repeat
+ lp := rest lp
+ construct(lp)
+
+ collectUpper (ts,v) ==
+ lp1 : List(P) := sort(supRittWu?,members(ts))$(List P)
+ lp2 : List(P) := []
+ while (not empty? lp1) and (mvar(first lp1) > v) repeat
+ lp2 := cons(first(lp1),lp2)
+ lp1 := rest lp1
+ construct(reverse lp2)
+
+ construct(lp:List(P)) ==
+ rif := retractIfCan(lp)@Union($,"failed")
+ not (rif case $) => error"in construct : LP -> $ from TSETCAT : bad arg"
+ rif::$
+
+ retractIfCan(lp:List(P)) ==
+ empty? lp => (empty()$$)::Union($,"failed")
+ lp := sort(supRittWu?,lp)
+ rif := retractIfCan(rest(lp))@Union($,"failed")
+ not (rif case $) => error"in retractIfCan : LP -> ... from TSETCAT : bad arg"
+ extendIfCan(rif::$,first(lp))@Union($,"failed")
+
+ extend(ts:$,p:P):$ ==
+ eif := extendIfCan(ts,p)@Union($,"failed")
+ not (eif case $) => error"in extend : ($,P) -> $ from TSETCAT : bad ars"
+ eif::$
+
+ if V has Finite
+ then
+
+ coHeight ts ==
+ n := size()$V
+ m := #(members ts)
+ subtractIfCan(n,m)$NonNegativeInteger::NonNegativeInteger
+
+@
+\section{TSETCAT.lsp BOOTSTRAP}
+{\bf TSETCAT} depends on a chain of
+files. We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf TSETCAT} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf TSETCAT.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<TSETCAT.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(SETQ |TriangularSetCategory;CAT| (QUOTE NIL))
+
+(SETQ |TriangularSetCategory;AL| (QUOTE NIL))
+
+(DEFUN |TriangularSetCategory| (|&REST| #1=#:G82394 |&AUX| #2=#:G82392) (DSETQ #2# #1#) (LET (#3=#:G82393) (COND ((SETQ #3# (|assoc| (|devaluateList| #2#) |TriangularSetCategory;AL|)) (CDR #3#)) (T (SETQ |TriangularSetCategory;AL| (|cons5| (CONS (|devaluateList| #2#) (SETQ #3# (APPLY (FUNCTION |TriangularSetCategory;|) #2#))) |TriangularSetCategory;AL|)) #3#))))
+
+(DEFUN |TriangularSetCategory;| (|t#1| |t#2| |t#3| |t#4|) (PROG (#1=#:G82391) (RETURN (PROG1 (LETT #1# (|sublisV| (PAIR (QUOTE (|t#1| |t#2| |t#3| |t#4|)) (LIST (|devaluate| |t#1|) (|devaluate| |t#2|) (|devaluate| |t#3|) (|devaluate| |t#4|))) (COND (|TriangularSetCategory;CAT|) ((QUOTE T) (LETT |TriangularSetCategory;CAT| (|Join| (|PolynomialSetCategory| (QUOTE |t#1|) (QUOTE |t#2|) (QUOTE |t#3|) (QUOTE |t#4|)) (|mkCategory| (QUOTE |domain|) (QUOTE (((|infRittWu?| ((|Boolean|) |$| |$|)) T) ((|basicSet| ((|Union| (|Record| (|:| |bas| |$|) (|:| |top| (|List| |t#4|))) "failed") (|List| |t#4|) (|Mapping| (|Boolean|) |t#4| |t#4|))) T) ((|basicSet| ((|Union| (|Record| (|:| |bas| |$|) (|:| |top| (|List| |t#4|))) "failed") (|List| |t#4|) (|Mapping| (|Boolean|) |t#4|) (|Mapping| (|Boolean|) |t#4| |t#4|))) T) ((|initials| ((|List| |t#4|) |$|)) T) ((|degree| ((|NonNegativeInteger|) |$|)) T) ((|quasiComponent| ((|Record| (|:| |close| (|List| |t#4|)) (|:| |open| (|List| |t#4|))) |$|)) T) ((|normalized?| ((|Boolean|) |t#4| |$|)) T) ((|normalized?| ((|Boolean|) |$|)) T) ((|reduced?| ((|Boolean|) |t#4| |$| (|Mapping| (|Boolean|) |t#4| |t#4|))) T) ((|stronglyReduced?| ((|Boolean|) |t#4| |$|)) T) ((|headReduced?| ((|Boolean|) |t#4| |$|)) T) ((|initiallyReduced?| ((|Boolean|) |t#4| |$|)) T) ((|autoReduced?| ((|Boolean|) |$| (|Mapping| (|Boolean|) |t#4| (|List| |t#4|)))) T) ((|stronglyReduced?| ((|Boolean|) |$|)) T) ((|headReduced?| ((|Boolean|) |$|)) T) ((|initiallyReduced?| ((|Boolean|) |$|)) T) ((|reduce| (|t#4| |t#4| |$| (|Mapping| |t#4| |t#4| |t#4|) (|Mapping| (|Boolean|) |t#4| |t#4|))) T) ((|rewriteSetWithReduction| ((|List| |t#4|) (|List| |t#4|) |$| (|Mapping| |t#4| |t#4| |t#4|) (|Mapping| (|Boolean|) |t#4| |t#4|))) T) ((|stronglyReduce| (|t#4| |t#4| |$|)) T) ((|headReduce| (|t#4| |t#4| |$|)) T) ((|initiallyReduce| (|t#4| |t#4| |$|)) T) ((|removeZero| (|t#4| |t#4| |$|)) T) ((|collectQuasiMonic| (|$| |$|)) T) ((|reduceByQuasiMonic| (|t#4| |t#4| |$|)) T) ((|zeroSetSplit| ((|List| |$|) (|List| |t#4|))) T) ((|zeroSetSplitIntoTriangularSystems| ((|List| (|Record| (|:| |close| |$|) (|:| |open| (|List| |t#4|)))) (|List| |t#4|))) T) ((|first| ((|Union| |t#4| "failed") |$|)) T) ((|last| ((|Union| |t#4| "failed") |$|)) T) ((|rest| ((|Union| |$| "failed") |$|)) T) ((|algebraicVariables| ((|List| |t#3|) |$|)) T) ((|algebraic?| ((|Boolean|) |t#3| |$|)) T) ((|select| ((|Union| |t#4| "failed") |$| |t#3|)) T) ((|extendIfCan| ((|Union| |$| "failed") |$| |t#4|)) T) ((|extend| (|$| |$| |t#4|)) T) ((|coHeight| ((|NonNegativeInteger|) |$|)) (|has| |t#3| (|Finite|))))) (QUOTE ((|finiteAggregate| T) (|shallowlyMutable| T))) (QUOTE ((|NonNegativeInteger|) (|Boolean|) (|List| |t#3|) (|List| (|Record| (|:| |close| |$|) (|:| |open| (|List| |t#4|)))) (|List| |t#4|) (|List| |$|))) NIL)) . #2=(|TriangularSetCategory|))))) . #2#) (SETELT #1# 0 (LIST (QUOTE |TriangularSetCategory|) (|devaluate| |t#1|) (|devaluate| |t#2|) (|devaluate| |t#3|) (|devaluate| |t#4|)))))))
+@
+\section{TSETCAT-.lsp BOOTSTRAP}
+{\bf TSETCAT-} depends on a chain of files.
+We need to break this cycle to build
+the algebra. So we keep a cached copy of the translated {\bf TSETCAT-}
+category which we can write into the {\bf MID} directory. We compile
+the lisp code and copy the {\bf TSETCAT-.o} file to the {\bf OUT} directory.
+This is eventually forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<TSETCAT-.lsp BOOTSTRAP>>=
+@
+\section{domain GTSET GeneralTriangularSet}
+<<domain GTSET GeneralTriangularSet>>=
+)abbrev domain GTSET GeneralTriangularSet
+++ Author: Marc Moreno Maza (marc@nag.co.uk)
+++ Date Created: 10/06/1995
+++ Date Last Updated: 06/12/1996
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A domain constructor of the category \axiomType{TriangularSetCategory}.
+++ The only requirement for a list of polynomials to be a member of such
+++ a domain is the following: no polynomial is constant and two distinct
+++ polynomials have distinct main variables. Such a triangular set may
+++ not be auto-reduced or consistent. Triangular sets are stored
+++ as sorted lists w.r.t. the main variables of their members but they
+++ are displayed in reverse order.\newline
+++ References :
+++ [1] P. AUBRY, D. LAZARD and M. MORENO MAZA "On the Theories
+++ of Triangular Sets" Journal of Symbol. Comp. (to appear)
+++ Version: 1
+
+GeneralTriangularSet(R,E,V,P) : Exports == Implementation where
+
+ R : IntegralDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ PtoP ==> P -> P
+
+ Exports == TriangularSetCategory(R,E,V,P)
+
+ Implementation == add
+
+ Rep ==> LP
+
+ rep(s:$):Rep == s pretend Rep
+ per(l:Rep):$ == l pretend $
+
+ copy ts ==
+ per(copy(rep(ts))$LP)
+ empty() ==
+ per([])
+ empty?(ts:$) ==
+ empty?(rep(ts))
+ parts ts ==
+ rep(ts)
+ members ts ==
+ rep(ts)
+ map (f : PtoP, ts : $) : $ ==
+ construct(map(f,rep(ts))$LP)$$
+ map! (f : PtoP, ts : $) : $ ==
+ construct(map!(f,rep(ts))$LP)$$
+ member? (p,ts) ==
+ member?(p,rep(ts))$LP
+
+ unitIdealIfCan() ==
+ "failed"::Union($,"failed")
+ roughUnitIdeal? ts ==
+ false
+
+ -- the following assume that rep(ts) is decreasingly sorted
+ -- w.r.t. the main variavles of the polynomials in rep(ts)
+ coerce(ts:$) : OutputForm ==
+ lp : List(P) := reverse(rep(ts))
+ brace([p::OutputForm for p in lp]$List(OutputForm))$OutputForm
+ mvar ts ==
+ empty? ts => error"failed in mvar : $ -> V from GTSET"
+ mvar(first(rep(ts)))$P
+ first ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ first(rep(ts))::Union(P,"failed")
+ last ts ==
+ empty? ts => "failed"::Union(P,"failed")
+ last(rep(ts))::Union(P,"failed")
+ rest ts ==
+ empty? ts => "failed"::Union($,"failed")
+ per(rest(rep(ts)))::Union($,"failed")
+ coerce(ts:$) : (List P) ==
+ rep(ts)
+ collectUpper (ts,v) ==
+ empty? ts => ts
+ lp := rep(ts)
+ newlp : Rep := []
+ while (not empty? lp) and (mvar(first(lp)) > v) repeat
+ newlp := cons(first(lp),newlp)
+ lp := rest lp
+ per(reverse(newlp))
+ collectUnder (ts,v) ==
+ empty? ts => ts
+ lp := rep(ts)
+ while (not empty? lp) and (mvar(first(lp)) >= v) repeat
+ lp := rest lp
+ per(lp)
+
+ -- for another domain of TSETCAT build on this domain GTSET
+ -- the following operations must be redefined
+ extendIfCan(ts:$,p:P) ==
+ ground? p => "failed"::Union($,"failed")
+ empty? ts => (per([unitCanonical(p)]$LP))::Union($,"failed")
+ not (mvar(ts) < mvar(p)) => "failed"::Union($,"failed")
+ (per(cons(p,rep(ts))))::Union($,"failed")
+
+@
+\section{package PSETPK PolynomialSetUtilitiesPackage}
+<<package PSETPK PolynomialSetUtilitiesPackage>>=
+)abbrev package PSETPK PolynomialSetUtilitiesPackage
+++ Author: Marc Moreno Maza (marc@nag.co.uk)
+++ Date Created: 12/01/1995
+++ Date Last Updated: 12/15/1998
+++ SPARC Version
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description:
+++ This package provides modest routines for polynomial system solving.
+++ The aim of many of the operations of this package is to remove certain
+++ factors in some polynomials in order to avoid unnecessary computations
+++ in algorithms involving splitting techniques by partial factorization.
+++ Version: 3
+
+PolynomialSetUtilitiesPackage (R,E,V,P) : Exports == Implementation where
+
+ R : IntegralDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ FP ==> Factored P
+ T ==> GeneralTriangularSet(R,E,V,P)
+ RRZ ==> Record(factor: P,exponent: Integer)
+ RBT ==> Record(bas:T,top:LP)
+ RUL ==> Record(chs:Union(T,"failed"),rfs:LP)
+ GPS ==> GeneralPolynomialSet(R,E,V,P)
+ pf ==> MultivariateFactorize(V, E, R, P)
+
+ Exports == with
+
+ removeRedundantFactors: LP -> LP
+ ++ \axiom{removeRedundantFactors(lp)} returns \axiom{lq} such that if
+ ++ \axiom{lp = [p1,...,pn]} and \axiom{lq = [q1,...,qm]}
+ ++ then the product \axiom{p1*p2*...*pn} vanishes iff the product \axiom{q1*q2*...*qm} vanishes,
+ ++ and the product of degrees of the \axiom{qi} is not greater than
+ ++ the one of the \axiom{pj}, and no polynomial in \axiom{lq}
+ ++ divides another polynomial in \axiom{lq}. In particular,
+ ++ polynomials lying in the base ring \axiom{R} are removed.
+ ++ Moreover, \axiom{lq} is sorted w.r.t \axiom{infRittWu?}.
+ ++ Furthermore, if R is gcd-domain, the polynomials in \axiom{lq} are
+ ++ pairwise without common non trivial factor.
+ removeRedundantFactors: (P,P) -> LP
+ ++ \axiom{removeRedundantFactors(p,q)} returns the same as
+ ++ \axiom{removeRedundantFactors([p,q])}
+ removeSquaresIfCan : LP -> LP
+ ++ \axiom{removeSquaresIfCan(lp)} returns
+ ++ \axiom{removeDuplicates [squareFreePart(p)$P for p in lp]}
+ ++ if \axiom{R} is gcd-domain else returns \axiom{lp}.
+ unprotectedRemoveRedundantFactors: (P,P) -> LP
+ ++ \axiom{unprotectedRemoveRedundantFactors(p,q)} returns the same as
+ ++ \axiom{removeRedundantFactors(p,q)} but does assume that neither
+ ++ \axiom{p} nor \axiom{q} lie in the base ring \axiom{R} and assumes that
+ ++ \axiom{infRittWu?(p,q)} holds. Moreover, if \axiom{R} is gcd-domain,
+ ++ then \axiom{p} and \axiom{q} are assumed to be square free.
+ removeRedundantFactors: (LP,P) -> LP
+ ++ \axiom{removeRedundantFactors(lp,q)} returns the same as
+ ++ \axiom{removeRedundantFactors(cons(q,lp))} assuming
+ ++ that \axiom{removeRedundantFactors(lp)} returns \axiom{lp}
+ ++ up to replacing some polynomial \axiom{pj} in \axiom{lp}
+ ++ by some some polynomial \axiom{qj} associated to \axiom{pj}.
+ removeRedundantFactors : (LP,LP) -> LP
+ ++ \axiom{removeRedundantFactors(lp,lq)} returns the same as
+ ++ \axiom{removeRedundantFactors(concat(lp,lq))} assuming
+ ++ that \axiom{removeRedundantFactors(lp)} returns \axiom{lp}
+ ++ up to replacing some polynomial \axiom{pj} in \axiom{lp}
+ ++ by some polynomial \axiom{qj} associated to \axiom{pj}.
+ removeRedundantFactors : (LP,LP,(LP -> LP)) -> LP
+ ++ \axiom{removeRedundantFactors(lp,lq,remOp)} returns the same as
+ ++ \axiom{concat(remOp(removeRoughlyRedundantFactorsInPols(lp,lq)),lq)}
+ ++ assuming that \axiom{remOp(lq)} returns \axiom{lq} up to similarity.
+ certainlySubVariety? : (LP,LP) -> B
+ ++ \axiom{certainlySubVariety?(newlp,lp)} returns true iff for every \axiom{p}
+ ++ in \axiom{lp} the remainder of \axiom{p} by \axiom{newlp} using the division algorithm
+ ++ of Groebner techniques is zero.
+ possiblyNewVariety? : (LP, List LP) -> B
+ ++ \axiom{possiblyNewVariety?(newlp,llp)} returns true iff for every \axiom{lp}
+ ++ in \axiom{llp} certainlySubVariety?(newlp,lp) does not hold.
+ probablyZeroDim?: LP -> B
+ ++ \axiom{probablyZeroDim?(lp)} returns true iff the number of polynomials
+ ++ in \axiom{lp} is not smaller than the number of variables occurring
+ ++ in these polynomials.
+ selectPolynomials : ((P -> B),LP) -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{selectPolynomials(pred?,ps)} returns \axiom{gps,bps} where
+ ++ \axiom{gps} is a list of the polynomial \axiom{p} in \axiom{ps}
+ ++ such that \axiom{pred?(p)} holds and \axiom{bps} are the other ones.
+ selectOrPolynomials : (List (P -> B),LP) -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{selectOrPolynomials(lpred?,ps)} returns \axiom{gps,bps} where
+ ++ \axiom{gps} is a list of the polynomial \axiom{p} in \axiom{ps}
+ ++ such that \axiom{pred?(p)} holds for some \axiom{pred?} in \axiom{lpred?}
+ ++ and \axiom{bps} are the other ones.
+ selectAndPolynomials : (List (P -> B),LP) -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{selectAndPolynomials(lpred?,ps)} returns \axiom{gps,bps} where
+ ++ \axiom{gps} is a list of the polynomial \axiom{p} in \axiom{ps}
+ ++ such that \axiom{pred?(p)} holds for every \axiom{pred?} in \axiom{lpred?}
+ ++ and \axiom{bps} are the other ones.
+ quasiMonicPolynomials : LP -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{quasiMonicPolynomials(lp)} returns \axiom{qmps,nqmps} where
+ ++ \axiom{qmps} is a list of the quasi-monic polynomials in \axiom{lp}
+ ++ and \axiom{nqmps} are the other ones.
+ univariate? : P -> B
+ ++ \axiom{univariate?(p)} returns true iff \axiom{p} involves one and
+ ++ only one variable.
+ univariatePolynomials : LP -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{univariatePolynomials(lp)} returns \axiom{ups,nups} where
+ ++ \axiom{ups} is a list of the univariate polynomials,
+ ++ and \axiom{nups} are the other ones.
+ linear? : P -> B
+ ++ \axiom{linear?(p)} returns true iff \axiom{p} does not lie
+ ++ in the base ring \axiom{R} and has main degree \axiom{1}.
+ linearPolynomials : LP -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{linearPolynomials(lp)} returns \axiom{lps,nlps} where
+ ++ \axiom{lps} is a list of the linear polynomials in lp,
+ ++ and \axiom{nlps} are the other ones.
+ bivariate? : P -> B
+ ++ \axiom{bivariate?(p)} returns true iff \axiom{p} involves two and
+ ++ only two variables.
+ bivariatePolynomials : LP -> Record(goodPols:LP,badPols:LP)
+ ++ \axiom{bivariatePolynomials(lp)} returns \axiom{bps,nbps} where
+ ++ \axiom{bps} is a list of the bivariate polynomials,
+ ++ and \axiom{nbps} are the other ones.
+ removeRoughlyRedundantFactorsInPols : (LP, LP) -> LP
+ ++ \axiom{removeRoughlyRedundantFactorsInPols(lp,lf)} returns
+ ++ \axiom{newlp}where \axiom{newlp} is obtained from \axiom{lp}
+ ++ by removing in every polynomial \axiom{p} of \axiom{lp}
+ ++ any occurence of a polynomial \axiom{f} in \axiom{lf}.
+ ++ This may involve a lot of exact-quotients computations.
+ removeRoughlyRedundantFactorsInPols : (LP, LP,B) -> LP
+ ++ \axiom{removeRoughlyRedundantFactorsInPols(lp,lf,opt)} returns
+ ++ the same as \axiom{removeRoughlyRedundantFactorsInPols(lp,lf)}
+ ++ if \axiom{opt} is \axiom{false} and if the previous operation
+ ++ does not return any non null and constant polynomial,
+ ++ else return \axiom{[1]}.
+ removeRoughlyRedundantFactorsInPol : (P,LP) -> P
+ ++ \axiom{removeRoughlyRedundantFactorsInPol(p,lf)} returns the same as
+ ++ removeRoughlyRedundantFactorsInPols([p],lf,true)
+ interReduce: LP -> LP
+ ++ \axiom{interReduce(lp)} returns \axiom{lq} such that \axiom{lp}
+ ++ and \axiom{lq} generate the same ideal and no polynomial
+ ++ in \axiom{lq} is reducuble by the others in the sense
+ ++ of Groebner bases. Since no assumptions are required
+ ++ the result may depend on the ordering the reductions are
+ ++ performed.
+ roughBasicSet: LP -> Union(Record(bas:T,top:LP),"failed")
+ ++ \axiom{roughBasicSet(lp)} returns the smallest (with Ritt-Wu
+ ++ ordering) triangular set contained in \axiom{lp}.
+ crushedSet: LP -> LP
+ ++ \axiom{crushedSet(lp)} returns \axiom{lq} such that \axiom{lp} and
+ ++ and \axiom{lq} generate the same ideal and no rough basic
+ ++ sets reduce (in the sense of Groebner bases) the other
+ ++ polynomials in \axiom{lq}.
+ rewriteSetByReducingWithParticularGenerators : (LP,(P->B),((P,P)->B),((P,P)->P)) -> LP
+ ++ \axiom{rewriteSetByReducingWithParticularGenerators(lp,pred?,redOp?,redOp)}
+ ++ returns \axiom{lq} where \axiom{lq} is computed by the following
+ ++ algorithm. Chose a basic set w.r.t. the reduction-test \axiom{redOp?}
+ ++ among the polynomials satisfying property \axiom{pred?},
+ ++ if it is empty then leave, else reduce the other polynomials by
+ ++ this basic set w.r.t. the reduction-operation \axiom{redOp}.
+ ++ Repeat while another basic set with smaller rank can be computed.
+ ++ See code. If \axiom{pred?} is \axiom{quasiMonic?} the ideal is unchanged.
+ rewriteIdealWithQuasiMonicGenerators : (LP,((P,P)->B),((P,P)->P)) -> LP
+ ++ \axiom{rewriteIdealWithQuasiMonicGenerators(lp,redOp?,redOp)} returns
+ ++ \axiom{lq} where \axiom{lq} and \axiom{lp} generate
+ ++ the same ideal in \axiom{R^(-1) P} and \axiom{lq}
+ ++ has rank not higher than the one of \axiom{lp}.
+ ++ Moreover, \axiom{lq} is computed by reducing \axiom{lp}
+ ++ w.r.t. some basic set of the ideal generated by
+ ++ the quasi-monic polynomials in \axiom{lp}.
+ if R has GcdDomain
+ then
+ squareFreeFactors : P -> LP
+ ++ \axiom{squareFreeFactors(p)} returns the square-free factors of \axiom{p}
+ ++ over \axiom{R}
+ univariatePolynomialsGcds : LP -> LP
+ ++ \axiom{univariatePolynomialsGcds(lp)} returns \axiom{lg} where
+ ++ \axiom{lg} is a list of the gcds of every pair in \axiom{lp}
+ ++ of univariate polynomials in the same main variable.
+ univariatePolynomialsGcds : (LP,B) -> LP
+ ++ \axiom{univariatePolynomialsGcds(lp,opt)} returns the same as
+ ++ \axiom{univariatePolynomialsGcds(lp)} if \axiom{opt} is
+ ++ \axiom{false} and if the previous operation does not return
+ ++ any non null and constant polynomial, else return \axiom{[1]}.
+ removeRoughlyRedundantFactorsInContents : (LP, LP) -> LP
+ ++ \axiom{removeRoughlyRedundantFactorsInContents(lp,lf)} returns
+ ++ \axiom{newlp}where \axiom{newlp} is obtained from \axiom{lp}
+ ++ by removing in the content of every polynomial of \axiom{lp}
+ ++ any occurence of a polynomial \axiom{f} in \axiom{lf}. Moreover,
+ ++ squares over \axiom{R} are first removed in the content
+ ++ of every polynomial of \axiom{lp}.
+ removeRedundantFactorsInContents : (LP, LP) -> LP
+ ++ \axiom{removeRedundantFactorsInContents(lp,lf)} returns \axiom{newlp}
+ ++ where \axiom{newlp} is obtained from \axiom{lp} by removing
+ ++ in the content of every polynomial of \axiom{lp} any non trivial
+ ++ factor of any polynomial \axiom{f} in \axiom{lf}. Moreover,
+ ++ squares over \axiom{R} are first removed in the content
+ ++ of every polynomial of \axiom{lp}.
+ removeRedundantFactorsInPols : (LP, LP) -> LP
+ ++ \axiom{removeRedundantFactorsInPols(lp,lf)} returns \axiom{newlp}
+ ++ where \axiom{newlp} is obtained from \axiom{lp} by removing
+ ++ in every polynomial \axiom{p} of \axiom{lp} any non trivial
+ ++ factor of any polynomial \axiom{f} in \axiom{lf}. Moreover,
+ ++ squares over \axiom{R} are first removed in every
+ ++ polynomial \axiom{lp}.
+ if (R has EuclideanDomain) and (R has CharacteristicZero)
+ then
+ irreducibleFactors : LP -> LP
+ ++ \axiom{irreducibleFactors(lp)} returns \axiom{lf} such that if
+ ++ \axiom{lp = [p1,...,pn]} and \axiom{lf = [f1,...,fm]} then
+ ++ \axiom{p1*p2*...*pn=0} means \axiom{f1*f2*...*fm=0}, and the \axiom{fi}
+ ++ are irreducible over \axiom{R} and are pairwise distinct.
+ lazyIrreducibleFactors : LP -> LP
+ ++ \axiom{lazyIrreducibleFactors(lp)} returns \axiom{lf} such that if
+ ++ \axiom{lp = [p1,...,pn]} and \axiom{lf = [f1,...,fm]} then
+ ++ \axiom{p1*p2*...*pn=0} means \axiom{f1*f2*...*fm=0}, and the \axiom{fi}
+ ++ are irreducible over \axiom{R} and are pairwise distinct.
+ ++ The algorithm tries to avoid factorization into irreducible
+ ++ factors as far as possible and makes previously use of gcd
+ ++ techniques over \axiom{R}.
+ removeIrreducibleRedundantFactors : (LP, LP) -> LP
+ ++ \axiom{removeIrreducibleRedundantFactors(lp,lq)} returns the same
+ ++ as \axiom{irreducibleFactors(concat(lp,lq))} assuming
+ ++ that \axiom{irreducibleFactors(lp)} returns \axiom{lp}
+ ++ up to replacing some polynomial \axiom{pj} in \axiom{lp}
+ ++ by some polynomial \axiom{qj} associated to \axiom{pj}.
+
+ Implementation == add
+
+ autoRemainder: T -> List(P)
+
+ removeAssociates (lp:LP):LP ==
+ removeDuplicates [primPartElseUnitCanonical(p) for p in lp]
+
+ selectPolynomials (pred?,ps) ==
+ gps : LP := []
+ bps : LP := []
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ if pred?(p)
+ then
+ gps := cons(p,gps)
+ else
+ bps := cons(p,bps)
+ gps := sort(infRittWu?,gps)
+ bps := sort(infRittWu?,bps)
+ [gps,bps]
+
+ selectOrPolynomials (lpred?,ps) ==
+ gps : LP := []
+ bps : LP := []
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ clpred? := lpred?
+ while (not empty? clpred?) and (not (first clpred?)(p)) repeat
+ clpred? := rest clpred?
+ if not empty?(clpred?)
+ then
+ gps := cons(p,gps)
+ else
+ bps := cons(p,bps)
+ gps := sort(infRittWu?,gps)
+ bps := sort(infRittWu?,bps)
+ [gps,bps]
+
+ selectAndPolynomials (lpred?,ps) ==
+ gps : LP := []
+ bps : LP := []
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ clpred? := lpred?
+ while (not empty? clpred?) and ((first clpred?)(p)) repeat
+ clpred? := rest clpred?
+ if empty?(clpred?)
+ then
+ gps := cons(p,gps)
+ else
+ bps := cons(p,bps)
+ gps := sort(infRittWu?,gps)
+ bps := sort(infRittWu?,bps)
+ [gps,bps]
+
+ linear? p ==
+ ground? p => false
+-- one?(mdeg(p))
+ (mdeg(p) = 1)
+
+ linearPolynomials ps ==
+ selectPolynomials(linear?,ps)
+
+ univariate? p ==
+ ground? p => false
+ not(ground?(init(p))) => false
+ tp := tail(p)
+ ground?(tp) => true
+ not (mvar(p) = mvar(tp)) => false
+ univariate?(tp)
+
+ univariatePolynomials ps ==
+ selectPolynomials(univariate?,ps)
+
+ bivariate? p ==
+ ground? p => false
+ ground? tail(p) => univariate?(init(p))
+ vp := mvar(p)
+ vtp := mvar(tail(p))
+ ((ground? init(p)) and (vp = vtp)) => bivariate? tail(p)
+ ((ground? init(p)) and (vp > vtp)) => univariate? tail(p)
+ not univariate?(init(p)) => false
+ vip := mvar(init(p))
+ vip > vtp => false
+ vip = vtp => univariate? tail(p)
+ vtp < vp => false
+ zero? degree(tail(p),vip) => univariate? tail(p)
+ bivariate? tail(p)
+
+ bivariatePolynomials ps ==
+ selectPolynomials(bivariate?,ps)
+
+ quasiMonicPolynomials ps ==
+ selectPolynomials(quasiMonic?,ps)
+
+ removeRoughlyRedundantFactorsInPols (lp,lf,opt) ==
+ empty? lp => lp
+ newlp : LP := []
+ stop : B := false
+ lp := remove(zero?,lp)
+ lf := sort(infRittWu?,lf)
+ test : Union(P,"failed")
+ while (not empty? lp) and (not stop) repeat
+ p := first lp
+ lp := rest lp
+ copylf := lf
+ while (not empty? copylf) and (not ground? p) and (not (mvar(p) < mvar(first copylf))) repeat
+ f := first copylf
+ copylf := rest copylf
+ while (((test := p exquo$P f)) case P) repeat
+ p := test::P
+ stop := opt and ground?(p)
+ newlp := cons(unitCanonical(p),newlp)
+ stop => [1$P]
+ newlp
+
+ removeRoughlyRedundantFactorsInPol(p,lf) ==
+ zero? p => p
+ lp : LP := [p]
+ first removeRoughlyRedundantFactorsInPols (lp,lf,true()$B)
+
+ removeRoughlyRedundantFactorsInPols (lp,lf) ==
+ removeRoughlyRedundantFactorsInPols (lp,lf,false()$B)
+
+ possiblyNewVariety?(newlp,llp) ==
+ while (not empty? llp) and _
+ (not certainlySubVariety?(newlp,first(llp))) repeat
+ llp := rest llp
+ empty? llp
+
+ certainlySubVariety?(lp,lq) ==
+ gs := construct(lp)$GPS
+ while (not empty? lq) and _
+ (zero? (remainder(first(lq),gs)$GPS).polnum) repeat
+ lq := rest lq
+ empty? lq
+
+ probablyZeroDim?(lp: List P) : Boolean ==
+ m := #lp
+ lv : List V := variables(first lp)
+ while not empty? (lp := rest lp) repeat
+ lv := concat(variables(first lp),lv)
+ n := #(removeDuplicates lv)
+ not (n > m)
+
+ interReduce(lp: LP): LP ==
+ ps := lp
+ rs: List(P) := []
+ repeat
+ empty? ps => return rs
+ ps := sort(supRittWu?, ps)
+ p := first ps
+ ps := rest ps
+ r := remainder(p,[ps]$GPS).polnum
+ zero? r => "leave"
+ ground? r => return []
+ associates?(r,p) => rs := cons(r,rs)
+ ps := concat(ps,cons(r,rs))
+ rs := []
+
+ roughRed?(p:P,q:P):B ==
+ ground? p => false
+ ground? q => true
+ mvar(p) > mvar(q)
+
+ roughBasicSet(lp) == basicSet(lp,roughRed?)$T
+
+ autoRemainder(ts:T): List(P) ==
+ empty? ts => members(ts)
+ lp := sort(infRittWu?, reverse members(ts))
+ newlp : List(P) := [primPartElseUnitCanonical first(lp)]
+ lp := rest(lp)
+ while not empty? lp repeat
+ p := (remainder(first(lp),construct(newlp)$GPS)$GPS).polnum
+ if not zero? p
+ then
+ if ground? p
+ then
+ newlp := [1$P]
+ lp := []
+ else
+ newlp := cons(p,newlp)
+ lp := rest(lp)
+ else
+ lp := rest(lp)
+ newlp
+
+ crushedSet(lp) ==
+ rec := roughBasicSet(lp)
+ contradiction := (rec case "failed")@B
+ finished : B := false
+ while (not finished) and (not contradiction) repeat
+ bs := (rec::RBT).bas
+ rs := (rec::RBT).top
+ rs := rewriteIdealWithRemainder(rs,bs)$T
+-- contradiction := ((not empty? rs) and (one? first(rs)))
+ contradiction := ((not empty? rs) and (first(rs) = 1))
+ if not contradiction
+ then
+ rs := concat(rs,autoRemainder(bs))
+ rec := roughBasicSet(rs)
+ contradiction := (rec case "failed")@B
+ not contradiction => finished := not infRittWu?((rec::RBT).bas,bs)
+ contradiction => [1$P]
+ rs
+
+ rewriteSetByReducingWithParticularGenerators (ps,pred?,redOp?,redOp) ==
+ rs : LP := remove(zero?,ps)
+ any?(ground?,rs) => [1$P]
+ contradiction : B := false
+ bs1 : T := empty()$T
+ rec : Union(RBT,"failed")
+ ar : Union(T,List(P))
+ stop : B := false
+ while (not contradiction) and (not stop) repeat
+ rec := basicSet(rs,pred?,redOp?)$T
+ bs2 : T := (rec::RBT).bas
+ rs := (rec::RBT).top
+ -- ar := autoReduce(bs2,lazyPrem,reduced?)@Union(T,List(P))
+ ar := bs2::Union(T,List(P))
+ if (ar case T)@B
+ then
+ bs2 := ar::T
+ if infRittWu?(bs2,bs1)
+ then
+ rs := rewriteSetWithReduction(rs,bs2,redOp,redOp?)$T
+ bs1 := bs2
+ else
+ stop := true
+ rs := concat(members(bs2),rs)
+ else
+ rs := concat(ar::LP,rs)
+ if any?(ground?,rs)
+ then
+ contradiction := true
+ rs := [1$P]
+ rs
+
+ removeRedundantFactors (lp:LP,lq :LP, remOp : (LP -> LP)) ==
+ -- ASSUME remOp(lp) returns lp up to similarity
+ lq := removeRoughlyRedundantFactorsInPols(lq,lp,false)
+ lq := remOp lq
+ sort(infRittWu?,concat(lp,lq))
+
+ removeRedundantFactors (lp:LP,lq :LP) ==
+ lq := removeRoughlyRedundantFactorsInPols(lq,lp,false)
+ lq := removeRedundantFactors lq
+ sort(infRittWu?,concat(lp,lq))
+
+ if (R has EuclideanDomain) and (R has CharacteristicZero)
+ then
+ irreducibleFactors lp ==
+ newlp : LP := []
+ lrrz : List RRZ
+ rrz : RRZ
+ fp : FP
+ while not empty? lp repeat
+ p := first lp
+ lp := rest lp
+ fp := factor(p)$pf
+ lrrz := factors(fp)$FP
+ lf := remove(ground?,[rrz.factor for rrz in lrrz])
+ newlp := concat(lf,newlp)
+ removeDuplicates newlp
+
+ lazyIrreducibleFactors lp ==
+ lp := removeRedundantFactors(lp)
+ newlp : LP := []
+ lrrz : List RRZ
+ rrz : RRZ
+ fp : FP
+ while not empty? lp repeat
+ p := first lp
+ lp := rest lp
+ fp := factor(p)$pf
+ lrrz := factors(fp)$FP
+ lf := remove(ground?,[rrz.factor for rrz in lrrz])
+ newlp := concat(lf,newlp)
+ newlp
+
+ removeIrreducibleRedundantFactors (lp:LP,lq :LP) ==
+ -- ASSUME lp only contains irreducible factors over R
+ lq := removeRoughlyRedundantFactorsInPols(lq,lp,false)
+ lq := irreducibleFactors lq
+ sort(infRittWu?,concat(lp,lq))
+
+ if R has GcdDomain
+ then
+
+ squareFreeFactors(p:P) ==
+ sfp: Factored P := squareFree(p)$P
+ lsf: List P := [foo.factor for foo in factors(sfp)]
+ lsf
+
+ univariatePolynomialsGcds (ps,opt) ==
+ lg : LP := []
+ pInV : LP
+ stop : B := false
+ ps := sort(infRittWu?,ps)
+ p,g : P
+ v : V
+ while (not empty? ps) and (not stop) repeat
+ while (not empty? ps) and (not univariate?((p := first(ps)))) repeat
+ ps := rest ps
+ if not empty? ps
+ then
+ v := mvar(p)$P
+ pInV := [p]
+ while (not empty? ps) and (mvar((p := first(ps))) = v) repeat
+ if (univariate?(p))
+ then
+ pInV := cons(p,pInV)
+ ps := rest ps
+ g := gcd(pInV)$P
+ stop := opt and (ground? g)
+ lg := cons(g,lg)
+ stop => [1$P]
+ lg
+
+ univariatePolynomialsGcds ps ==
+ univariatePolynomialsGcds (ps,false)
+
+ removeSquaresIfCan lp ==
+ empty? lp => lp
+ removeDuplicates [squareFreePart(p)$P for p in lp]
+
+ rewriteIdealWithQuasiMonicGenerators (ps,redOp?,redOp) ==
+ ups := removeSquaresIfCan(univariatePolynomialsGcds(ps,true))
+ ps := removeDuplicates concat(ups,ps)
+ rewriteSetByReducingWithParticularGenerators(ps,quasiMonic?,redOp?,redOp)
+
+ removeRoughlyRedundantFactorsInContents (ps,lf) ==
+ empty? ps => ps
+ newps : LP := []
+ p,newp,cp,newcp,f,g : P
+ test : Union(P,"failed")
+ copylf : LP
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ cp := mainContent(p)$P
+ newcp := squareFreePart(cp)$P
+ newp := (p exquo$P cp)::P
+ if not ground? newcp
+ then
+ copylf := [f for f in lf | mvar(f) <= mvar(newcp)]
+ while (not empty? copylf) and (not ground? newcp) repeat
+ f := first copylf
+ copylf := rest copylf
+ test := (newcp exquo$P f)
+ if (test case P)@B
+ then
+ newcp := test::P
+ if ground? newcp
+ then
+ newp := unitCanonical(newp)
+ else
+ newp := unitCanonical(newp * newcp)
+ newps := cons(newp,newps)
+ newps
+
+ removeRedundantFactorsInContents (ps,lf) ==
+ empty? ps => ps
+ newps : LP := []
+ p,newp,cp,newcp,f,g : P
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ cp := mainContent(p)$P
+ newcp := squareFreePart(cp)$P
+ newp := (p exquo$P cp)::P
+ if not ground? newcp
+ then
+ copylf := lf
+ while (not empty? copylf) and (not ground? newcp) repeat
+ f := first copylf
+ copylf := rest copylf
+ g := gcd(newcp,f)$P
+ if not ground? g
+ then
+ newcp := (newcp exquo$P g)::P
+ if ground? newcp
+ then
+ newp := unitCanonical(newp)
+ else
+ newp := unitCanonical(newp * newcp)
+ newps := cons(newp,newps)
+ newps
+
+ removeRedundantFactorsInPols (ps,lf) ==
+ empty? ps => ps
+ newps : LP := []
+ p,newp,cp,newcp,f,g : P
+ while not empty? ps repeat
+ p := first ps
+ ps := rest ps
+ cp := mainContent(p)$P
+ newcp := squareFreePart(cp)$P
+ newp := (p exquo$P cp)::P
+ newp := squareFreePart(newp)$P
+ copylf := lf
+ while not empty? copylf repeat
+ f := first copylf
+ copylf := rest copylf
+ if not ground? newcp
+ then
+ g := gcd(newcp,f)$P
+ if not ground? g
+ then
+ newcp := (newcp exquo$P g)::P
+ if not ground? newp
+ then
+ g := gcd(newp,f)$P
+ if not ground? g
+ then
+ newp := (newp exquo$P g)::P
+ if ground? newcp
+ then
+ newp := unitCanonical(newp)
+ else
+ newp := unitCanonical(newp * newcp)
+ newps := cons(newp,newps)
+ newps
+
+ removeRedundantFactors (a:P,b:P) : LP ==
+ a := primPartElseUnitCanonical(squareFreePart(a))
+ b := primPartElseUnitCanonical(squareFreePart(b))
+ if not infRittWu?(a,b)
+ then
+ (a,b) := (b,a)
+ if ground? a
+ then
+ if ground? b
+ then
+ return([])
+ else
+ return([b])
+ else
+ if ground? b
+ then
+ return([a])
+ else
+ return(unprotectedRemoveRedundantFactors(a,b))
+
+ unprotectedRemoveRedundantFactors (a,b) ==
+ c := b exquo$P a
+ if (c case P)@B
+ then
+ d : P := c::P
+ if ground? d
+ then
+ return([a])
+ else
+ return([a,d])
+ else
+ g : P := gcd(a,b)$P
+ if ground? g
+ then
+ return([a,b])
+ else
+ return([g,(a exquo$P g)::P,(b exquo$P g)::P])
+
+ else
+
+ removeSquaresIfCan lp ==
+ lp
+
+ rewriteIdealWithQuasiMonicGenerators (ps,redOp?,redOp) ==
+ rewriteSetByReducingWithParticularGenerators(ps,quasiMonic?,redOp?,redOp)
+
+ removeRedundantFactors (a:P,b:P) ==
+ a := primPartElseUnitCanonical(a)
+ b := primPartElseUnitCanonical(b)
+ if not infRittWu?(a,b)
+ then
+ (a,b) := (b,a)
+ if ground? a
+ then
+ if ground? b
+ then
+ return([])
+ else
+ return([b])
+ else
+ if ground? b
+ then
+ return([a])
+ else
+ return(unprotectedRemoveRedundantFactors(a,b))
+
+ unprotectedRemoveRedundantFactors (a,b) ==
+ c := b exquo$P a
+ if (c case P)@B
+ then
+ d : P := c::P
+ if ground? d
+ then
+ return([a])
+ else
+ if infRittWu?(d,a) then (a,d) := (d,a)
+ return(unprotectedRemoveRedundantFactors(a,d))
+ else
+ return([a,b])
+
+ removeRedundantFactors (lp:LP) ==
+ lp := remove(ground?, lp)
+ lp := removeDuplicates [primPartElseUnitCanonical(p) for p in lp]
+ lp := removeSquaresIfCan lp
+ lp := removeDuplicates [unitCanonical(p) for p in lp]
+ empty? lp => lp
+ size?(lp,1$N)$(List P) => lp
+ lp := sort(infRittWu?,lp)
+ p : P := first lp
+ lp := rest lp
+ base : LP := unprotectedRemoveRedundantFactors(p,first lp)
+ top : LP := rest lp
+ while not empty? top repeat
+ p := first top
+ base := removeRedundantFactors(base,p)
+ top := rest top
+ base
+
+ removeRedundantFactors (lp:LP,a:P) ==
+ lp := remove(ground?, lp)
+ lp := sort(infRittWu?, lp)
+ ground? a => lp
+ empty? lp => [a]
+ toSee : LP := lp
+ toSave : LP := []
+ while not empty? toSee repeat
+ b := first toSee
+ toSee := rest toSee
+ if not infRittWu?(b,a)
+ then
+ (c,d) := (a,b)
+ else
+ (c,d) := (b,a)
+ rrf := unprotectedRemoveRedundantFactors(c,d)
+ empty? rrf => error"in removeRedundantFactors : (LP,P) -> LP from PSETPK"
+ c := first rrf
+ rrf := rest rrf
+ if empty? rrf
+ then
+ if associates?(c,b)
+ then
+ toSave := concat(toSave,toSee)
+ a := b
+ toSee := []
+ else
+ a := c
+ toSee := concat(toSave,toSee)
+ toSave := []
+ else
+ d := first rrf
+ rrf := rest rrf
+ if empty? rrf
+ then
+ if associates?(c,b)
+ then
+ toSave := concat(toSave,[b])
+ a := d
+ else
+ if associates?(d,b)
+ then
+ toSave := concat(toSave,[b])
+ a := c
+ else
+ toSave := removeRedundantFactors(toSave,c)
+ a := d
+ else
+ e := first rrf
+ not empty? rest(rrf) => error"in removeRedundantFactors:(LP,P)->LP from PSETPK"
+ -- ASSUME that neither c, nor d, nor e may be associated to b
+ toSave := removeRedundantFactors(toSave,c)
+ toSave := removeRedundantFactors(toSave,d)
+ a := e
+ if empty? toSee
+ then
+ toSave := sort(infRittWu?,cons(a,toSave))
+ toSave
+
+@
+\section{domain WUTSET WuWenTsunTriangularSet}
+<<domain WUTSET WuWenTsunTriangularSet>>=
+)abbrev domain WUTSET WuWenTsunTriangularSet
+++ Author: Marc Moreno Maza (marc@nag.co.uk)
+++ Date Created: 11/18/1995
+++ Date Last Updated: 12/15/1998
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description: A domain constructor of the category \axiomType{GeneralTriangularSet}.
+++ The only requirement for a list of polynomials to be a member of such
+++ a domain is the following: no polynomial is constant and two distinct
+++ polynomials have distinct main variables. Such a triangular set may
+++ not be auto-reduced or consistent. The \axiomOpFrom{construct}{WuWenTsunTriangularSet} operation
+++ does not check the previous requirement. Triangular sets are stored
+++ as sorted lists w.r.t. the main variables of their members.
+++ Furthermore, this domain exports operations dealing with the
+++ characteristic set method of Wu Wen Tsun and some optimizations
+++ mainly proposed by Dong Ming Wang.\newline
+++ References :
+++ [1] W. T. WU "A Zero Structure Theorem for polynomial equations solving"
+++ MM Research Preprints, 1987.
+++ [2] D. M. WANG "An implementation of the characteristic set method in Maple"
+++ Proc. DISCO'92. Bath, England.
+++ Version: 3
+
+WuWenTsunTriangularSet(R,E,V,P) : Exports == Implementation where
+
+ R : IntegralDomain
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LP ==> List P
+ A ==> FiniteEdge P
+ H ==> FiniteSimpleHypergraph P
+ GPS ==> GeneralPolynomialSet(R,E,V,P)
+ RBT ==> Record(bas:$,top:LP)
+ RUL ==> Record(chs:Union($,"failed"),rfs:LP)
+ pa ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ NLpT ==> SplittingNode(LP,$)
+ ALpT ==> SplittingTree(LP,$)
+ O ==> OutputForm
+ OP ==> OutputPackage
+
+ Exports == TriangularSetCategory(R,E,V,P) with
+
+ medialSet : (LP,((P,P)->B),((P,P)->P)) -> Union($,"failed")
+ ++ \axiom{medialSet(ps,redOp?,redOp)} returns \axiom{bs} a basic set
+ ++ (in Wu Wen Tsun sense w.r.t the reduction-test \axiom{redOp?})
+ ++ of some set generating the same ideal as \axiom{ps} (with
+ ++ rank not higher than any basic set of \axiom{ps}), if no non-zero
+ ++ constant polynomials appear during the computatioms, else
+ ++ \axiom{"failed"} is returned. In the former case, \axiom{bs} has to be
+ ++ understood as a candidate for being a characteristic set of \axiom{ps}.
+ ++ In the original algorithm, \axiom{bs} is simply a basic set of \axiom{ps}.
+ medialSet: LP -> Union($,"failed")
+ ++ \axiom{medial(ps)} returns the same as
+ ++ \axiom{medialSet(ps,initiallyReduced?,initiallyReduce)}.
+ characteristicSet : (LP,((P,P)->B),((P,P)->P)) -> Union($,"failed")
+ ++ \axiom{characteristicSet(ps,redOp?,redOp)} returns a non-contradictory
+ ++ characteristic set of \axiom{ps} in Wu Wen Tsun sense w.r.t the
+ ++ reduction-test \axiom{redOp?} (using \axiom{redOp} to reduce
+ ++ polynomials w.r.t a \axiom{redOp?} basic set), if no
+ ++ non-zero constant polynomial appear during those reductions,
+ ++ else \axiom{"failed"} is returned.
+ ++ The operations \axiom{redOp} and \axiom{redOp?} must satisfy
+ ++ the following conditions: \axiom{redOp?(redOp(p,q),q)} holds
+ ++ for every polynomials \axiom{p,q} and there exists an integer
+ ++ \axiom{e} and a polynomial \axiom{f} such that we have
+ ++ \axiom{init(q)^e*p = f*q + redOp(p,q)}.
+ characteristicSet: LP -> Union($,"failed")
+ ++ \axiom{characteristicSet(ps)} returns the same as
+ ++ \axiom{characteristicSet(ps,initiallyReduced?,initiallyReduce)}.
+ characteristicSerie : (LP,((P,P)->B),((P,P)->P)) -> List $
+ ++ \axiom{characteristicSerie(ps,redOp?,redOp)} returns a list \axiom{lts}
+ ++ of triangular sets such that the zero set of \axiom{ps} is the
+ ++ union of the regular zero sets of the members of \axiom{lts}.
+ ++ This is made by the Ritt and Wu Wen Tsun process applying
+ ++ the operation \axiom{characteristicSet(ps,redOp?,redOp)}
+ ++ to compute characteristic sets in Wu Wen Tsun sense.
+ characteristicSerie: LP -> List $
+ ++ \axiom{characteristicSerie(ps)} returns the same as
+ ++ \axiom{characteristicSerie(ps,initiallyReduced?,initiallyReduce)}.
+
+ Implementation == GeneralTriangularSet(R,E,V,P) add
+
+ removeSquares: $ -> Union($,"failed")
+
+ Rep ==> LP
+
+ rep(s:$):Rep == s pretend Rep
+ per(l:Rep):$ == l pretend $
+
+ removeAssociates (lp:LP):LP ==
+ removeDuplicates [primPartElseUnitCanonical(p) for p in lp]
+
+ medialSetWithTrace (ps:LP,redOp?:((P,P)->B),redOp:((P,P)->P)):Union(RBT,"failed") ==
+ qs := rewriteIdealWithQuasiMonicGenerators(ps,redOp?,redOp)$pa
+ contradiction : B := any?(ground?,ps)
+ contradiction => "failed"::Union(RBT,"failed")
+ rs : LP := qs
+ bs : $
+ while (not empty? rs) and (not contradiction) repeat
+ rec := basicSet(rs,redOp?)
+ contradiction := (rec case "failed")@B
+ if not contradiction
+ then
+ bs := (rec::RBT).bas
+ rs := (rec::RBT).top
+ rs := rewriteIdealWithRemainder(rs,bs)
+-- contradiction := ((not empty? rs) and (one? first(rs)))
+ contradiction := ((not empty? rs) and (first(rs) = 1))
+ if (not empty? rs) and (not contradiction)
+ then
+ rs := rewriteSetWithReduction(rs,bs,redOp,redOp?)
+-- contradiction := ((not empty? rs) and (one? first(rs)))
+ contradiction := ((not empty? rs) and (first(rs) = 1))
+ if (not empty? rs) and (not contradiction)
+ then
+ rs := removeDuplicates concat(rs,members(bs))
+ rs := rewriteIdealWithQuasiMonicGenerators(rs,redOp?,redOp)$pa
+-- contradiction := ((not empty? rs) and (one? first(rs)))
+ contradiction := ((not empty? rs) and (first(rs) = 1))
+ contradiction => "failed"::Union(RBT,"failed")
+ ([bs,qs]$RBT)::Union(RBT,"failed")
+
+ medialSet(ps:LP,redOp?:((P,P)->B),redOp:((P,P)->P)) ==
+ foo: Union(RBT,"failed") := medialSetWithTrace(ps,redOp?,redOp)
+ (foo case "failed") => "failed" :: Union($,"failed")
+ ((foo::RBT).bas) :: Union($,"failed")
+
+ medialSet(ps:LP) == medialSet(ps,initiallyReduced?,initiallyReduce)
+
+ characteristicSetUsingTrace(ps:LP,redOp?:((P,P)->B),redOp:((P,P)->P)):Union($,"failed") ==
+ ps := removeAssociates ps
+ ps := remove(zero?,ps)
+ contradiction : B := any?(ground?,ps)
+ contradiction => "failed"::Union($,"failed")
+ rs : LP := ps
+ qs : LP := ps
+ ms : $
+ while (not empty? rs) and (not contradiction) repeat
+ rec := medialSetWithTrace (qs,redOp?,redOp)
+ contradiction := (rec case "failed")@B
+ if not contradiction
+ then
+ ms := (rec::RBT).bas
+ qs := (rec::RBT).top
+ qs := rewriteIdealWithRemainder(qs,ms)
+-- contradiction := ((not empty? qs) and (one? first(qs)))
+ contradiction := ((not empty? qs) and (first(qs) = 1))
+ if not contradiction
+ then
+ rs := rewriteSetWithReduction(qs,ms,lazyPrem,reduced?)
+-- contradiction := ((not empty? rs) and (one? first(rs)))
+ contradiction := ((not empty? rs) and (first(rs) = 1))
+ if (not contradiction) and (not empty? rs)
+ then
+ qs := removeDuplicates(concat(rs,concat(members(ms),qs)))
+ contradiction => "failed"::Union($,"failed")
+ ms::Union($,"failed")
+
+ characteristicSet(ps:LP,redOp?:((P,P)->B),redOp:((P,P)->P)) ==
+ characteristicSetUsingTrace(ps,redOp?,redOp)
+
+ characteristicSet(ps:LP) == characteristicSet(ps,initiallyReduced?,initiallyReduce)
+
+ characteristicSerie(ps:LP,redOp?:((P,P)->B),redOp:((P,P)->P)) ==
+ a := [[ps,empty()$$]$NLpT]$ALpT
+ while ((esl := extractSplittingLeaf(a)) case ALpT) repeat
+ ps := value(value(esl::ALpT)$ALpT)$NLpT
+ charSet? := characteristicSetUsingTrace(ps,redOp?,redOp)
+ if not (charSet? case $)
+ then
+ setvalue!(esl::ALpT,[nil()$LP,empty()$$,true]$NLpT)
+ updateStatus!(a)
+ else
+ cs := (charSet?)::$
+ lics := initials(cs)
+ lics := removeRedundantFactors(lics)$pa
+ lics := sort(infRittWu?,lics)
+ if empty? lics
+ then
+ setvalue!(esl::ALpT,[ps,cs,true]$NLpT)
+ updateStatus!(a)
+ else
+ ln : List NLpT := [[nil()$LP,cs,true]$NLpT]
+ while not empty? lics repeat
+ newps := cons(first(lics),concat(cs::LP,ps))
+ lics := rest lics
+ newps := removeDuplicates newps
+ newps := sort(infRittWu?,newps)
+ ln := cons([newps,empty()$$,false]$NLpT,ln)
+ splitNodeOf!(esl::ALpT,a,ln)
+ remove(empty()$$,conditions(a))
+
+ characteristicSerie(ps:LP) == characteristicSerie (ps,initiallyReduced?,initiallyReduce)
+
+ if R has GcdDomain
+ then
+
+ removeSquares (ts:$):Union($,"failed") ==
+ empty?(ts)$$ => ts::Union($,"failed")
+ p := (first ts)::P
+ rsts : Union($,"failed")
+ rsts := removeSquares((rest ts)::$)
+ not(rsts case $) => "failed"::Union($,"failed")
+ newts := rsts::$
+ empty? newts =>
+ p := squareFreePart(p)
+ (per([primitivePart(p)]$LP))::Union($,"failed")
+ zero? initiallyReduce(init(p),newts) => "failed"::Union($,"failed")
+ p := primitivePart(removeZero(p,newts))
+ ground? p => "failed"::Union($,"failed")
+ not (mvar(newts) < mvar(p)) => "failed"::Union($,"failed")
+ p := squareFreePart(p)
+ (per(cons(unitCanonical(p),rep(newts))))::Union($,"failed")
+
+ zeroSetSplit lp ==
+ lts : List $ := characteristicSerie(lp,initiallyReduced?,initiallyReduce)
+ lts := removeDuplicates(lts)$(List $)
+ newlts : List $ := []
+ while not empty? lts repeat
+ ts := first lts
+ lts := rest lts
+ iic := removeSquares(ts)
+ if iic case $
+ then
+ newlts := cons(iic::$,newlts)
+ newlts := removeDuplicates(newlts)$(List $)
+ sort(infRittWu?, newlts)
+
+ else
+
+ zeroSetSplit lp ==
+ lts : List $ := characteristicSerie(lp,initiallyReduced?,initiallyReduce)
+ sort(infRittWu?, removeDuplicates lts)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category TSETCAT TriangularSetCategory>>
+<<domain GTSET GeneralTriangularSet>>
+<<package PSETPK PolynomialSetUtilitiesPackage>>
+<<domain WUTSET WuWenTsunTriangularSet>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/tube.spad.pamphlet b/src/algebra/tube.spad.pamphlet
new file mode 100644
index 00000000..9d74406f
--- /dev/null
+++ b/src/algebra/tube.spad.pamphlet
@@ -0,0 +1,508 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra tube.spad}
+\author{Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain TUBE TubePlot}
+<<domain TUBE TubePlot>>=
+)abbrev domain TUBE TubePlot
+++ Author: Clifton J. Williamson
+++ Date Created: Bastille Day 1989
+++ Date Last Updated: 5 June 1990
+++ Keywords:
+++ Examples:
+++ Description:
+++ Package for constructing tubes around 3-dimensional parametric curves.
+++ Domain of tubes around 3-dimensional parametric curves.
+TubePlot(Curve): Exports == Implementation where
+ Curve : PlottableSpaceCurveCategory
+ B ==> Boolean
+ L ==> List
+ Pt ==> Point DoubleFloat
+
+ Exports ==> with
+ getCurve: % -> Curve
+ ++ getCurve(t) returns the \spadtype{PlottableSpaceCurveCategory}
+ ++ representing the parametric curve of the given tube plot t.
+ listLoops: % -> L L Pt
+ ++ listLoops(t) returns the list of lists of points, or the 'loops',
+ ++ of the given tube plot t.
+ closed?: % -> B
+ ++ closed?(t) tests whether the given tube plot t is closed.
+ open?: % -> B
+ ++ open?(t) tests whether the given tube plot t is open.
+ setClosed: (%,B) -> B
+ ++ setClosed(t,b) declares the given tube plot t to be closed if
+ ++ b is true, or if b is false, t is set to be open.
+ tube: (Curve,L L Pt,B) -> %
+ ++ tube(c,ll,b) creates a tube of the domain \spadtype{TubePlot} from a
+ ++ space curve c of the category \spadtype{PlottableSpaceCurveCategory},
+ ++ a list of lists of points (loops) ll and a boolean b which if
+ ++ true indicates a closed tube, or if false an open tube.
+
+ Implementation ==> add
+
+--% representation
+
+ Rep := Record(parCurve:Curve,loops:L L Pt,closedTube?:B)
+
+ getCurve plot == plot.parCurve
+
+ listLoops plot == plot.loops
+
+ closed? plot == plot.closedTube?
+ open? plot == not plot.closedTube?
+
+ setClosed(plot,flag) == plot.closedTube? := flag
+
+ tube(curve,ll,b) == [curve,ll,b]
+
+@
+\section{package TUBETOOL TubePlotTools}
+<<package TUBETOOL TubePlotTools>>=
+)abbrev package TUBETOOL TubePlotTools
+++ Author: Clifton J. Williamson
+++ Date Created: Bastille Day 1989
+++ Date Last Updated: 5 June 1990
+++ Keywords:
+++ Examples:
+++ Description:
+++ Tools for constructing tubes around 3-dimensional parametric curves.
+TubePlotTools(): Exports == Implementation where
+ I ==> Integer
+ SF ==> DoubleFloat
+ L ==> List
+ Pt ==> Point SF
+
+ Exports ==> with
+ point: (SF,SF,SF,SF) -> Pt
+ ++ point(x1,x2,x3,c) creates and returns a point from the three
+ ++ specified coordinates \spad{x1}, \spad{x2}, \spad{x3}, and also
+ ++ a fourth coordinate, c, which is generally used to specify the
+ ++ color of the point.
+ "*" : (SF,Pt) -> Pt
+ ++ s * p returns a point whose coordinates are the scalar multiple
+ ++ of the point p by the scalar s, preserving the color, or fourth
+ ++ coordinate, of p.
+ "+" : (Pt,Pt) -> Pt
+ ++ p + q computes and returns a point whose coordinates are the sums
+ ++ of the coordinates of the two points \spad{p} and \spad{q}, using
+ ++ the color, or fourth coordinate, of the first point \spad{p}
+ ++ as the color also of the point \spad{q}.
+ "-" : (Pt,Pt) -> Pt
+ ++ p - q computes and returns a point whose coordinates are the
+ ++ differences of the coordinates of two points \spad{p} and \spad{q},
+ ++ using the color, or fourth coordinate, of the first point \spad{p}
+ ++ as the color also of the point \spad{q}.
+ dot : (Pt,Pt) -> SF
+ ++ dot(p,q) computes the dot product of the two points \spad{p}
+ ++ and \spad{q} using only the first three coordinates, and returns
+ ++ the resulting \spadtype{DoubleFloat}.
+ cross : (Pt,Pt) -> Pt
+ ++ cross(p,q) computes the cross product of the two points \spad{p}
+ ++ and \spad{q} using only the first three coordinates, and keeping
+ ++ the color of the first point p. The result is returned as a point.
+ unitVector: Pt -> Pt
+ ++ unitVector(p) creates the unit vector of the point p and returns
+ ++ the result as a point. Note: \spad{unitVector(p) = p/|p|}.
+ cosSinInfo: I -> L L SF
+ ++ cosSinInfo(n) returns the list of lists of values for n, in the
+ ++ form: \spad{[[cos(n - 1) a,sin(n - 1) a],...,[cos 2 a,sin 2 a],[cos a,sin a]]}
+ ++ where \spad{a = 2 pi/n}. Note: n should be greater than 2.
+ loopPoints: (Pt,Pt,Pt,SF,L L SF) -> L Pt
+ ++ loopPoints(p,n,b,r,lls) creates and returns a list of points
+ ++ which form the loop with radius r, around the center point
+ ++ indicated by the point p, with the principal normal vector of
+ ++ the space curve at point p given by the point(vector) n, and the
+ ++ binormal vector given by the point(vector) b, and a list of lists,
+ ++ lls, which is the \spadfun{cosSinInfo} of the number of points
+ ++ defining the loop.
+
+ Implementation ==> add
+ import PointPackage(SF)
+
+ point(x,y,z,c) == point(l : L SF := [x,y,z,c])
+
+ getColor: Pt -> SF
+ getColor pt == (maxIndex pt > 3 => color pt; 0)
+
+ getColor2: (Pt,Pt) -> SF
+ getColor2(p0,p1) ==
+ maxIndex p0 > 3 => color p0
+ maxIndex p1 > 3 => color p1
+ 0
+
+ a * p ==
+ l : L SF := [a * xCoord p,a * yCoord p,a * zCoord p,getColor p]
+ point l
+
+ p0 + p1 ==
+ l : L SF := [xCoord p0 + xCoord p1,yCoord p0 + yCoord p1,_
+ zCoord p0 + zCoord p1,getColor2(p0,p1)]
+ point l
+
+ p0 - p1 ==
+ l : L SF := [xCoord p0 - xCoord p1,yCoord p0 - yCoord p1,_
+ zCoord p0 - zCoord p1,getColor2(p0,p1)]
+ point l
+
+ dot(p0,p1) ==
+ (xCoord p0 * xCoord p1) + (yCoord p0 * yCoord p1) +_
+ (zCoord p0 * zCoord p1)
+
+ cross(p0,p1) ==
+ x0 := xCoord p0; y0 := yCoord p0; z0 := zCoord p0;
+ x1 := xCoord p1; y1 := yCoord p1; z1 := zCoord p1;
+ l : L SF := [y0 * z1 - y1 * z0,z0 * x1 - z1 * x0,_
+ x0 * y1 - x1 * y0,getColor2(p0,p1)]
+ point l
+
+ unitVector p == (inv sqrt dot(p,p)) * p
+
+ cosSinInfo n ==
+ ans : L L SF := nil()
+ theta : SF := 2 * pi()/n
+ for i in 1..(n-1) repeat --!! make more efficient
+ angle := i * theta
+ ans := concat([cos angle,sin angle],ans)
+ ans
+
+ loopPoints(ctr,pNorm,bNorm,rad,cosSin) ==
+ ans : L Pt := nil()
+ while not null cosSin repeat
+ cossin := first cosSin; cos := first cossin; sin := second cossin
+ ans := cons(ctr + rad * (cos * pNorm + sin * bNorm),ans)
+ cosSin := rest cosSin
+ pt := ctr + rad * pNorm
+ concat(pt,concat(ans,pt))
+
+@
+\section{package EXPRTUBE ExpressionTubePlot}
+<<package EXPRTUBE ExpressionTubePlot>>=
+)abbrev package EXPRTUBE ExpressionTubePlot
+++ Author: Clifton J. Williamson
+++ Date Created: Bastille Day 1989
+++ Date Last Updated: 5 June 1990
+++ Keywords:
+++ Examples:
+++ Package for constructing tubes around 3-dimensional parametric curves.
+ExpressionTubePlot(): Exports == Implementation where
+ B ==> Boolean
+ I ==> Integer
+ FE ==> Expression Integer
+ SY ==> Symbol
+ SF ==> DoubleFloat
+ L ==> List
+ S ==> String
+ SEG ==> Segment
+ F2F ==> MakeFloatCompiledFunction(FE)
+ Pt ==> Point SF
+ PLOT3 ==> Plot3D
+ TUBE ==> TubePlot Plot3D
+
+ Exports ==> with
+ constantToUnaryFunction: SF -> (SF -> SF)
+ ++ constantToUnaryFunction(s) is a local function which takes the
+ ++ value of s, which may be a function of a constant, and returns
+ ++ a function which always returns the value \spadtype{DoubleFloat} s.
+ tubePlot: (FE,FE,FE,SF -> SF,SEG SF,SF -> SF,I) -> TUBE
+ ++ tubePlot(f,g,h,colorFcn,a..b,r,n) puts a tube of radius r(t) with
+ ++ n points on each circle about the curve \spad{x = f(t)},
+ ++ \spad{y = g(t)}, \spad{z = h(t)} for t in \spad{[a,b]}.
+ ++ The tube is considered to be open.
+ tubePlot: (FE,FE,FE,SF -> SF,SEG SF,SF -> SF,I,S) -> TUBE
+ ++ tubePlot(f,g,h,colorFcn,a..b,r,n,s) puts a tube of radius \spad{r(t)}
+ ++ with n points on each circle about the curve \spad{x = f(t)},
+ ++ \spad{y = g(t)},
+ ++ \spad{z = h(t)} for t in \spad{[a,b]}. If s = "closed", the tube is
+ ++ considered to be closed; if s = "open", the tube is considered
+ ++ to be open.
+ tubePlot: (FE,FE,FE,SF -> SF,SEG SF,SF,I) -> TUBE
+ ++ tubePlot(f,g,h,colorFcn,a..b,r,n) puts a tube of radius r with
+ ++ n points on each circle about the curve \spad{x = f(t)},
+ ++ \spad{y = g(t)}, \spad{z = h(t)} for t in \spad{[a,b]}.
+ ++ The tube is considered to be open.
+ tubePlot: (FE,FE,FE,SF -> SF,SEG SF,SF,I,S) -> TUBE
+ ++ tubePlot(f,g,h,colorFcn,a..b,r,n,s) puts a tube of radius r with
+ ++ n points on each circle about the curve \spad{x = f(t)},
+ ++ \spad{y = g(t)}, \spad{z = h(t)} for t in \spad{[a,b]}.
+ ++ If s = "closed", the tube is
+ ++ considered to be closed; if s = "open", the tube is considered
+ ++ to be open.
+
+ Implementation ==> add
+ import Plot3D
+ import F2F
+ import TubePlotTools
+
+--% variables
+
+ getVariable: (FE,FE,FE) -> SY
+ getVariable(x,y,z) ==
+ varList1 := variables x
+ varList2 := variables y
+ varList3 := variables z
+ (not (# varList1 <= 1)) or (not (# varList2 <= 1)) or _
+ (not (# varList3 <= 1)) =>
+ error "tubePlot: only one variable may be used"
+ null varList1 =>
+ null varList2 =>
+ null varList3 =>
+ error "tubePlot: a variable must appear in functions"
+ first varList3
+ t2 := first varList2
+ null varList3 => t2
+ not (first varList3 = t2) =>
+ error "tubePlot: only one variable may be used"
+ t1 := first varList1
+ null varList2 =>
+ null varList3 => t1
+ not (first varList3 = t1) =>
+ error "tubePlot: only one variable may be used"
+ t1
+ t2 := first varList2
+ null varList3 =>
+ not (t1 = t2) =>
+ error "tubePlot: only one variable may be used"
+ t1
+ not (first varList3 = t1) or not (t2 = t1) =>
+ error "tubePlot: only one variable may be used"
+ t1
+
+--% tubes: variable radius
+
+ tubePlot(x:FE,y:FE,z:FE,colorFcn:SF -> SF,_
+ tRange:SEG SF,radFcn:SF -> SF,n:I,string:S) ==
+ -- check value of n
+ n < 3 => error "tubePlot: n should be at least 3"
+ -- check string
+ flag : B :=
+ string = "closed" => true
+ string = "open" => false
+ error "tubePlot: last argument should be open or closed"
+ -- check variables
+ t := getVariable(x,y,z)
+ -- coordinate functions
+ xFunc := makeFloatFunction(x,t)
+ yFunc := makeFloatFunction(y,t)
+ zFunc := makeFloatFunction(z,t)
+ -- derivatives of coordinate functions
+ xp := differentiate(x,t)
+ yp := differentiate(y,t)
+ zp := differentiate(z,t)
+ -- derivative of arc length
+ sp := sqrt(xp ** 2 + yp ** 2 + zp ** 2)
+ -- coordinates of unit tangent vector
+ Tx := xp/sp; Ty := yp/sp; Tz := zp/sp
+ -- derivatives of coordinates of unit tangent vector
+ Txp := differentiate(Tx,t)
+ Typ := differentiate(Ty,t)
+ Tzp := differentiate(Tz,t)
+ -- K = curvature = length of curvature vector
+ K := sqrt(Txp ** 2 + Typ ** 2 + Tzp ** 2)
+ -- coordinates of principal normal vector
+ Nx := Txp / K; Ny := Typ / K; Nz := Tzp / K
+ -- functions SF->SF giving coordinates of principal normal vector
+ NxFunc := makeFloatFunction(Nx,t);
+ NyFunc := makeFloatFunction(Ny,t);
+ NzFunc := makeFloatFunction(Nz,t);
+ -- coordinates of binormal vector
+ Bx := Ty * Nz - Tz * Ny
+ By := Tz * Nx - Tx * Nz
+ Bz := Tx * Ny - Ty * Nx
+ -- functions SF -> SF giving coordinates of binormal vector
+ BxFunc := makeFloatFunction(Bx,t);
+ ByFunc := makeFloatFunction(By,t);
+ BzFunc := makeFloatFunction(Bz,t);
+ -- create Plot3D
+ parPlot := plot(xFunc,yFunc,zFunc,colorFcn,tRange)
+ tvals := first tValues parPlot
+ curvePts := first listBranches parPlot
+ cosSin := cosSinInfo n
+ loopList : L L Pt := nil()
+ while not null tvals repeat
+ -- note: tvals and curvePts have the same number of elements
+ tval := first tvals; tvals := rest tvals
+ ctr := first curvePts; curvePts := rest curvePts
+ pNormList : L SF :=
+ [NxFunc tval,NyFunc tval,NzFunc tval,colorFcn tval]
+ pNorm : Pt := point pNormList
+ bNormList : L SF :=
+ [BxFunc tval,ByFunc tval,BzFunc tval,colorFcn tval]
+ bNorm : Pt := point bNormList
+ lps := loopPoints(ctr,pNorm,bNorm,radFcn tval,cosSin)
+ loopList := cons(lps,loopList)
+ tube(parPlot,reverse_! loopList,flag)
+
+ tubePlot(x:FE,y:FE,z:FE,colorFcn:SF -> SF,_
+ tRange:SEG SF,radFcn:SF -> SF,n:I) ==
+ tubePlot(x,y,z,colorFcn,tRange,radFcn,n,"open")
+
+--% tubes: constant radius
+
+ project: (SF,SF) -> SF
+ project(x,y) == x
+
+ constantToUnaryFunction x == project(x,#1)
+
+ tubePlot(x:FE,y:FE,z:FE,colorFcn:SF -> SF,_
+ tRange:SEG SF,rad:SF,n:I,s:S) ==
+ tubePlot(x,y,z,colorFcn,tRange,constantToUnaryFunction rad,n,s)
+
+ tubePlot(x:FE,y:FE,z:FE,colorFcn:SF -> SF,_
+ tRange:SEG SF,rad:SF,n:I) ==
+ tubePlot(x,y,z,colorFcn,tRange,rad,n,"open")
+
+@
+\section{package NUMTUBE NumericTubePlot}
+<<package NUMTUBE NumericTubePlot>>=
+)abbrev package NUMTUBE NumericTubePlot
+++ Author: Clifton J. Williamson
+++ Date Created: Bastille Day 1989
+++ Date Last Updated: 5 June 1990
+++ Keywords:
+++ Examples:
+++ Package for constructing tubes around 3-dimensional parametric curves.
+NumericTubePlot(Curve): Exports == Implementation where
+ Curve : PlottableSpaceCurveCategory
+ B ==> Boolean
+ I ==> Integer
+ SF ==> DoubleFloat
+ L ==> List
+ S ==> String
+ SEG ==> Segment
+ Pt ==> Point SF
+ TUBE ==> TubePlot Curve
+ Triad ==> Record(tang:Pt,norm:Pt,bin:Pt)
+
+ Exports ==> with
+ tube: (Curve,SF,I) -> TUBE
+ ++ tube(c,r,n) creates a tube of radius r around the curve c.
+
+ Implementation ==> add
+ import TubePlotTools
+
+ LINMAX := convert(0.995)@SF
+ XHAT := point(1,0,0,0)
+ YHAT := point(0,1,0,0)
+ PREV0 := point(1,1,0,0)
+ PREV := PREV0
+
+ colinearity: (Pt,Pt) -> SF
+ colinearity(x,y) == dot(x,y)**2/(dot(x,x) * dot(y,y))
+
+ orthog: (Pt,Pt) -> Pt
+ orthog(x,y) ==
+ if colinearity(x,y) > LINMAX then y := PREV
+ if colinearity(x,y) > LINMAX then
+ y := (colinearity(x,XHAT) < LINMAX => XHAT; YHAT)
+ a := -dot(x,y)/dot(x,x)
+ PREV := a*x + y
+
+ poTriad:(Pt,Pt,Pt) -> Triad
+ poTriad(pl,po,pr) ==
+ -- use divided difference for t.
+ t := unitVector(pr - pl)
+ -- compute n as orthogonal to t in plane containing po.
+ pol := pl - po
+ n := unitVector orthog(t,pol)
+ [t,n,cross(t,n)]
+
+ curveTriads: L Pt -> L Triad
+ curveTriads l ==
+ (k := #l) < 2 => error "Need at least 2 points to specify a curve"
+ PREV := PREV0
+ k = 2 =>
+ t := unitVector(second l - first l)
+ n := unitVector(t - XHAT)
+ b := cross(t,n)
+ triad : Triad := [t,n,b]
+ [triad,triad]
+ -- compute interior triads using divided differences
+ midtriads : L Triad :=
+ [poTriad(pl,po,pr) for pl in l for po in rest l _
+ for pr in rest rest l]
+ -- compute first triad using a forward difference
+ x := first midtriads
+ t := unitVector(second l - first l)
+ n := unitVector orthog(t,x.norm)
+ begtriad : Triad := [t,n,cross(t,n)]
+ -- compute last triad using a backward difference
+ x := last midtriads
+ -- efficiency!!
+ t := unitVector(l.k - l.(k-1))
+ n := unitVector orthog(t,x.norm)
+ endtriad : Triad := [t,n,cross(t,n)]
+ concat(begtriad,concat(midtriads,endtriad))
+
+ curveLoops: (L Pt,SF,I) -> L L Pt
+ curveLoops(pts,r,nn) ==
+ triads := curveTriads pts
+ cosSin := cosSinInfo nn
+ loops : L L Pt := nil()
+ for pt in pts for triad in triads repeat
+ n := triad.norm; b := triad.bin
+ loops := concat(loopPoints(pt,n,b,r,cosSin),loops)
+ reverse_! loops
+
+ tube(curve,r,n) ==
+ n < 3 => error "tube: n should be at least 3"
+ brans := listBranches curve
+ loops : L L Pt := nil()
+ for bran in brans repeat
+ loops := concat(loops,curveLoops(bran,r,n))
+ tube(curve,loops,false)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain TUBE TubePlot>>
+<<package TUBETOOL TubePlotTools>>
+<<package EXPRTUBE ExpressionTubePlot>>
+<<package NUMTUBE NumericTubePlot>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/twofact.spad.pamphlet b/src/algebra/twofact.spad.pamphlet
new file mode 100644
index 00000000..f3e99f53
--- /dev/null
+++ b/src/algebra/twofact.spad.pamphlet
@@ -0,0 +1,330 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra twofact.spad}
+\author{Patrizia Gianni, James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package NORMRETR NormRetractPackage}
+<<package NORMRETR NormRetractPackage>>=
+)abbrev package NORMRETR NormRetractPackage
+++ Description:
+++ This package \undocumented
+NormRetractPackage(F, ExtF, SUEx, ExtP, n):C == T where
+ F : FiniteFieldCategory
+ ExtF : FiniteAlgebraicExtensionField(F)
+ SUEx : UnivariatePolynomialCategory ExtF
+ ExtP : UnivariatePolynomialCategory SUEx
+ n : PositiveInteger
+ SUP ==> SparseUnivariatePolynomial
+ R ==> SUP F
+ P ==> SUP R
+
+ C ==> with
+ normFactors : ExtP -> List ExtP
+ ++ normFactors(x) \undocumented
+ retractIfCan : ExtP -> Union(P, "failed")
+ ++ retractIfCan(x) \undocumented
+ Frobenius : ExtP -> ExtP
+ ++ Frobenius(x) \undocumented
+
+ T ==> add
+
+ normFactors(p:ExtP):List ExtP ==
+ facs : List ExtP := [p]
+ for i in 1..n-1 repeat
+ member?((p := Frobenius p), facs) => return facs
+ facs := cons(p, facs)
+ facs
+
+ Frobenius(ff:ExtP):ExtP ==
+ fft:ExtP:=0
+ while ff^=0 repeat
+ fft:=fft + monomial(map(Frobenius, leadingCoefficient ff),
+ degree ff)
+ ff:=reductum ff
+ fft
+
+ retractIfCan(ff:ExtP):Union(P, "failed") ==
+ fft:P:=0
+ while ff ^= 0 repeat
+ lc : SUEx := leadingCoefficient ff
+ plc: SUP F := 0
+ while lc ^= 0 repeat
+ lclc:ExtF := leadingCoefficient lc
+ (retlc := retractIfCan lclc) case "failed" => return "failed"
+ plc := plc + monomial(retlc::F, degree lc)
+ lc := reductum lc
+ fft:=fft+monomial(plc, degree ff)
+ ff:=reductum ff
+ fft
+
+@
+\section{package TWOFACT TwoFactorize}
+<<package TWOFACT TwoFactorize>>=
+)abbrev package TWOFACT TwoFactorize
+++ Authors : P.Gianni, J.H.Davenport
+++ Date Created : May 1990
+++ Date Last Updated: March 1992
+++ Description:
+++ A basic package for the factorization of bivariate polynomials
+++ over a finite field.
+++ The functions here represent the base step for the multivariate factorizer.
+
+TwoFactorize(F) : C == T
+ where
+ F : FiniteFieldCategory
+ SUP ==> SparseUnivariatePolynomial
+ R ==> SUP F
+ P ==> SUP R
+ UPCF2 ==> UnivariatePolynomialCategoryFunctions2
+
+ C == with
+ generalTwoFactor : (P) -> Factored P
+ ++ generalTwoFactor(p) returns the factorisation of polynomial p,
+ ++ a sparse univariate polynomial (sup) over a
+ ++ sup over F.
+ generalSqFr : (P) -> Factored P
+ ++ generalSqFr(p) returns the square-free factorisation of polynomial p,
+ ++ a sparse univariate polynomial (sup) over a
+ ++ sup over F.
+ twoFactor : (P,Integer) -> Factored P
+ ++ twoFactor(p,n) returns the factorisation of polynomial p,
+ ++ a sparse univariate polynomial (sup) over a
+ ++ sup over F.
+ ++ Also, p is assumed primitive and square-free and n is the
+ ++ degree of the inner variable of p (maximum of the degrees
+ ++ of the coefficients of p).
+
+ T == add
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ import CommuteUnivariatePolynomialCategory(F,R,P)
+
+ ---- Local Functions ----
+ computeDegree : (P,Integer,Integer) -> PI
+ exchangeVars : P -> P
+ exchangeVarTerm: (R, NNI) -> P
+ pthRoot : (R, NNI, NNI) -> R
+
+ -- compute the degree of the extension to reduce the polynomial to a
+ -- univariate one
+ computeDegree(m : P,mx:Integer,q:Integer): PI ==
+ my:=degree m
+ n1:Integer:=length(10*mx*my)
+ n2:Integer:=length(q)-1
+ n:=(n1 quo n2)+1
+ n::PI
+-- n=1 => 1$PositiveInteger
+-- (nextPrime(max(n,min(mx,my)))$IntegerPrimesPackage(Integer))::PI
+
+ exchangeVars(p : P) : P ==
+ p = 0 => 0
+ exchangeVarTerm(leadingCoefficient p, degree p) +
+ exchangeVars(reductum p)
+
+ exchangeVarTerm(c:R, e:NNI) : P ==
+ c = 0 => 0
+ monomial(monomial(leadingCoefficient c, e)$R, degree c)$P +
+ exchangeVarTerm(reductum c, e)
+
+ pthRoot(poly:R,p:NonNegativeInteger,PthRootPow:NonNegativeInteger):R ==
+ tmp:=divideExponents(map((#1::F)**PthRootPow,poly),p)
+ tmp case "failed" => error "consistency error in TwoFactor"
+ tmp
+
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FF ==> Record(flg:fUnion, fctr:P, xpnt:Integer)
+
+ generalSqFr(m:P): Factored P ==
+ m = 0 => 0
+ degree m = 0 =>
+ l:=squareFree(leadingCoefficient m)
+ makeFR(unit(l)::P,[[u.flg,u.fctr::P,u.xpnt] for u in factorList l])
+ cont := content m
+ m := (m exquo cont)::P
+ sqfrm := squareFree m
+ pfaclist : List FF := empty()
+ unitPart := unit sqfrm
+ for u in factorList sqfrm repeat
+ u.flg = "nil" =>
+ uexp:NNI:=(u.xpnt):NNI
+ nfacs:=squareFree(exchangeVars u.fctr)
+ for v in factorList nfacs repeat
+ pfaclist:=cons([v.flg, exchangeVars v.fctr, v.xpnt*uexp],
+ pfaclist)
+ unitPart := unit(nfacs)**uexp * unitPart
+ pfaclist := cons(u,pfaclist)
+ cont ^= 1 =>
+ sqp := squareFree cont
+ contlist:=[[w.flg,(w.fctr)::P,w.xpnt] for w in factorList sqp]
+ pfaclist:= append(contlist, pfaclist)
+ makeFR(unit(sqp)*unitPart,pfaclist)
+ makeFR(unitPart,pfaclist)
+
+
+ generalTwoFactor(m:P): Factored P ==
+ m = 0 => 0
+ degree m = 0 =>
+ l:=factor(leadingCoefficient m)$DistinctDegreeFactorize(F,R)
+ makeFR(unit(l)::P,[[u.flg,u.fctr::P,u.xpnt] for u in factorList l])
+ ll:List FF
+ ll:=[]
+ unitPart:P
+ cont:=content m
+ if degree(cont)>0 then
+ m1:=m exquo cont
+ m1 case "failed" => error "content doesn't divide"
+ m:=m1
+ contfact:=factor(cont)$DistinctDegreeFactorize(F,R)
+ unitPart:=(unit contfact)::P
+ ll:=[[w.flg,(w.fctr)::P,w.xpnt] for w in factorList contfact]
+ else
+ unitPart:=cont::P
+ sqfrm:=squareFree m
+ for u in factors sqfrm repeat
+ expo:=u.exponent
+ if expo < 0 then error "negative exponent in a factorisation"
+ expon:NonNegativeInteger:=expo::NonNegativeInteger
+ fac:=u.factor
+ degree fac = 1 => ll:=[["irred",fac,expon],:ll]
+ differentiate fac = 0 =>
+ -- the polynomial is inseparable w.r.t. its main variable
+ map(differentiate,fac) = 0 =>
+ p:=characteristic$F
+ PthRootPow:=(size$F exquo p)::NonNegativeInteger
+ m1:=divideExponents(map(pthRoot(#1,p,PthRootPow),fac),p)
+ m1 case "failed" => error "consistency error in TwoFactor"
+ res:=generalTwoFactor m1
+ unitPart:=unitPart*unit(res)**((p*expon)::NNI)
+ ll:=[:[[v.flg,v.fctr,expon *p*v.xpnt] for v in factorList res],:ll]
+ m2:=generalTwoFactor swap fac
+ unitPart:=unitPart*unit(m2)**(expon::NNI)
+ ll:=[:[[v.flg,swap v.fctr,expon*v.xpnt] for v in factorList m2],:ll]
+ ydeg:="max"/[degree w for w in coefficients fac]
+ twoF:=twoFactor(fac,ydeg)
+ unitPart:=unitPart*unit(twoF)**expon
+ ll:=[:[[v.flg,v.fctr,expon*v.xpnt] for v in factorList twoF],
+ :ll]
+ makeFR(unitPart,ll)
+
+ -- factorization of a primitive square-free bivariate polynomial --
+ twoFactor(m:P,dx:Integer):Factored P ==
+ -- choose the degree for the extension
+ n:PI:=computeDegree(m,dx,size()$F)
+ -- extend the field
+ -- find the substitution for x
+ look:Boolean:=true
+ dm:=degree m
+ try:Integer:=min(5,size()$F)
+ i:Integer:=0
+ lcm := leadingCoefficient m
+ umv : R
+ while look and i < try repeat
+ vval := random()$F
+ i:=i+1
+ zero? elt(lcm, vval) => "next value"
+ umv := map(elt(#1,vval), m)$UPCF2(R, P, F, R)
+ degree(gcd(umv,differentiate umv))^=0 => "next val"
+ n := 1
+ look := false
+ extField:=FiniteFieldExtension(F,n)
+ SUEx:=SUP extField
+ TP:=SparseUnivariatePolynomial SUEx
+ mm:TP:=0
+ m1:=m
+ while m1^=0 repeat
+ mm:=mm+monomial(map(coerce,leadingCoefficient m1)$UPCF2(F,R,
+ extField,SUEx),degree m1)
+ m1:=reductum m1
+ lcmm := leadingCoefficient mm
+ val : extField
+ umex : SUEx
+ if not look then
+ val := vval :: extField
+ umex := map(coerce, umv)$UPCF2(F, R, extField, SUEx)
+ while look repeat
+ val:=random()$extField
+ i:=i+1
+ elt(lcmm,val)=0 => "next value"
+ umex := map(elt(#1,val), mm)$UPCF2(SUEx, TP, extField, SUEx)
+ degree(gcd(umex,differentiate umex))^=0 => "next val"
+ look:=false
+ prime:SUEx:=monomial(1,1)-monomial(val,0)
+ fumex:=factor(umex)$DistinctDegreeFactorize(extField,SUEx)
+ lfact1:=factors fumex
+
+ #lfact1=1 => primeFactor(m,1)
+ lfact : List TP :=
+ [map(coerce,lf.factor)$UPCF2(extField,SUEx,SUEx,TP)
+ for lf in lfact1]
+ lfact:=cons(map(coerce,unit fumex)$UPCF2(extField,SUEx,SUEx,TP),
+ lfact)
+ import GeneralHenselPackage(SUEx,TP)
+ dx1:PI:=(dx+1)::PI
+ lfacth:=completeHensel(mm,lfact,prime,dx1)
+ lfactk: List P :=[]
+ Normp := NormRetractPackage(F, extField, SUEx, TP, n)
+
+ while not empty? lfacth repeat
+ ff := first lfacth
+ lfacth := rest lfacth
+ if (c:=leadingCoefficient leadingCoefficient ff) ^=1 then
+ ff:=((inv c)::SUEx)* ff
+ not ((ffu:= retractIfCan(ff)$Normp) case "failed") =>
+ lfactk := cons(ffu::P, lfactk)
+ normfacs := normFactors(ff)$Normp
+ lfacth := [g for g in lfacth | not member?(g, normfacs)]
+ ffn := */normfacs
+ lfactk:=cons(retractIfCan(ffn)$Normp :: P, lfactk)
+ */[primeFactor(ff1,1) for ff1 in lfactk]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package NORMRETR NormRetractPackage>>
+<<package TWOFACT TwoFactorize>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/unifact.spad.pamphlet b/src/algebra/unifact.spad.pamphlet
new file mode 100644
index 00000000..672a3c69
--- /dev/null
+++ b/src/algebra/unifact.spad.pamphlet
@@ -0,0 +1,368 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra unifact.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package UNIFACT UnivariateFactorize}
+<<package UNIFACT UnivariateFactorize>>=
+)abbrev package UNIFACT UnivariateFactorize
+++ Factorisation of univariate polynomials with integer coefficients
+++ Author: Patrizia Gianni
+++ Date Created: ???
+++ Date Last Updated: December 1993
+++ Description:
+++ Package for the factorization of univariate polynomials with integer
+++ coefficients. The factorization is done by "lifting" (HENSEL) the
+++ factorization over a finite field.
+UnivariateFactorize(ZP) : public == private where
+ Z ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SUPZ ==> SparseUnivariatePolynomial Z
+
+ ZP : UnivariatePolynomialCategory Z
+
+ FR ==> Factored ZP
+ fUnion ==> Union("nil", "sqfr", "irred", "prime")
+ FFE ==> Record(flg:fUnion, fctr:ZP, xpnt:Z)
+ ParFact ==> Record(irr: ZP,pow: Z)
+ FinalFact ==> Record(contp: Z,factors:List(ParFact))
+
+
+ public == with
+ factor : ZP -> FR
+ ++ factor(m) returns the factorization of m
+ factorSquareFree : ZP -> FR
+ ++ factorSquareFree(m) returns the factorization of m square free
+ ++ polynomial
+ henselFact : (ZP,Boolean) -> FinalFact
+ ++ henselFact(m,flag) returns the factorization of m,
+ ++ FinalFact is a Record s.t. FinalFact.contp=content m,
+ ++ FinalFact.factors=List of irreducible factors
+ ++ of m with exponent , if flag =true the polynomial is
+ ++ assumed square free.
+
+ private == add
+ --- local functions ---
+
+ henselfact : ZP -> List(ZP)
+ quadratic : ZP -> List(ZP)
+ remp : (Z, PI) -> Z
+ negShiftz : (Z, PI) -> Z
+ negShiftp : (ZP,PI) -> ZP
+ bound : ZP -> PI
+ choose : ZP -> FirstStep
+ eisenstein : ZP -> Boolean
+ isPowerOf2 : Z -> Boolean
+ subMinusX : SUPZ -> ZP
+ sqroot : Z -> Z
+
+ --- declarations ---
+ CYC ==> CyclotomicPolynomialPackage()
+ DDRecord ==> Record(factor: ZP,degree: Z)
+ DDList ==> List DDRecord
+ FirstStep ==> Record(prime:PI,factors:DDList)
+ ContPrim ==> Record(cont: Z,prim: ZP)
+
+ import GeneralHenselPackage(Z,ZP)
+ import ModularDistinctDegreeFactorizer ZP
+
+
+ factor(m: ZP) ==
+ flist := henselFact(m,false)
+ ctp:=unitNormal flist.contp
+ makeFR((ctp.unit)::ZP,cons(["nil",ctp.canonical::ZP,1$Z]$FFE,
+ [["prime",u.irr,u.pow]$FFE for u in flist.factors]))
+
+ factorSquareFree(m: ZP) ==
+ flist := henselFact(m,true)
+ ctp:=unitNormal flist.contp
+ makeFR((ctp.unit)::ZP,cons(["nil",ctp.canonical::ZP,1$Z]$FFE,
+ [["prime",u.irr,u.pow]$FFE for u in flist.factors]))
+
+
+ -- Integer square root: returns 0 if t is non-positive
+ sqroot(t: Z): Z ==
+ t <= 0 => 0
+ s:Integer:=t::Integer
+ s:=approxSqrt(s)$IntegerRoots(Integer)
+ t:=s::Z
+ t
+
+ -- Eisenstein criterion: returns true if polynomial is
+ -- irreducible. Result of false in inconclusive.
+ eisenstein(m : ZP): Boolean ==
+ -- calculate the content of the terms after the first
+ c := content reductum m
+ c = 0 => false
+ c = 1 => false
+ -- factor the content
+ -- if there is a prime in the factorization that does not divide
+ -- the leading term and appears to multiplicity 1, and the square
+ -- of this does not divide the last coef, return true.
+ -- Otherwise reurn false.
+ lead := leadingCoefficient m
+ trail := lead
+ m := reductum m
+ while m ^= 0 repeat
+ trail := leadingCoefficient m
+ m:= reductum m
+ fc := factor(c) :: Factored(Z)
+ for r in factors fc repeat
+ if (r.exponent = 1) and (0 ^= (lead rem r.factor)) and
+ (0 ^= (trail rem (r.factor ** 2))) then return true
+ false
+
+ negShiftz(n: Z,Modulus:PI): Z ==
+ if n < 0 then n := n+Modulus
+ n > (Modulus quo 2) => n-Modulus
+ n
+
+ negShiftp(pp: ZP,Modulus:PI): ZP ==
+ map(negShiftz(#1,Modulus),pp)
+
+ -- Choose the bound for the coefficients of factors
+ bound(m: ZP):PI ==
+ nm,nmq2,lcm,bin0,bin1:NNI
+ cbound,j : PI
+ k:NNI
+ lcm := abs(leadingCoefficient m)::NNI
+ nm := (degree m)::NNI
+ nmq2:NNI := nm quo 2
+ norm: Z := sqroot(+/[coefficient(m,k)**2 for k in 0..nm])
+ if nmq2^=1 then nm := (nmq2-1):NNI
+ else nm := nmq2
+ bin0 := nm
+ cbound := (bin0*norm+lcm)::PI
+ for i in 2..(nm-1)::NNI repeat
+ bin1 := bin0
+ bin0 := (bin0*(nm+1-i):NNI) quo i
+ j := (bin0*norm+bin1*lcm)::PI
+ if cbound<j then cbound := j
+ (2*cbound*lcm)::PI -- adjusted by lcm to prepare for exquo in ghensel
+
+ remp(t: Z,q:PI): Z == ((t := t rem q)<0 => t+q ;t)
+
+ numFactors(ddlist:DDList): Z ==
+ ans: Z := 0
+ for dd in ddlist repeat
+ (d := degree(dd.factor)) = 0 => nil
+ ans := ans + ((d pretend Z) exquo dd.degree):: Z
+ ans
+
+ -- select the prime,try up to 4 primes,
+ -- choose the one yielding the fewest factors, but stopping if
+ -- fewer than 9 factors
+ choose(m: ZP):FirstStep ==
+ qSave:PI := 1
+ ddSave:DDList := []
+ numberOfFactors: Z := 0
+ lcm := leadingCoefficient m
+ k: Z := 1
+ ddRep := 5
+ disc:ZP:=0
+ q:PI:=2
+ while k<ddRep repeat
+ -- q must be a new prime number at each iteration
+ q:=nextPrime(q)$IntegerPrimesPackage(Z) pretend PI
+ (rr:=lcm rem q) = 0$Z => "next prime"
+ disc:=gcd(m,differentiate m,q)
+ (degree disc)^=0 => "next prime"
+ k := k+1
+ newdd := ddFact(m,q)
+ ((n := numFactors(newdd)) < 9) =>
+ ddSave := newdd
+ qSave := q
+ k := 5
+ (numberOfFactors = 0) or (n < numberOfFactors) =>
+ ddSave := newdd
+ qSave := q
+ numberOfFactors := n
+ [qSave,ddSave]$FirstStep
+
+ -- Find the factors of m,primitive, square-free, with lc positive
+ -- and mindeg m = 0
+ henselfact1(m: ZP):List(ZP) ==
+ zero? degree m =>
+-- one? m => []
+ (m = 1) => []
+ [m]
+ selected := choose(m)
+ (numFactors(selected.factors) = 1$Z) => [m]
+ q := selected.prime
+ fl := separateFactors(selected.factors,q)
+ --choose the bound
+ cbound := bound(m)
+ completeHensel(m,fl,q,cbound)
+
+ -- check for possible degree reduction
+ -- could use polynomial decomposition ?
+ henselfact(m: ZP):List ZP ==
+ deggcd:=degree m
+ mm:= m
+ while not zero? mm repeat (deggcd:=gcd(deggcd, degree mm); mm:=reductum mm)
+ deggcd>1 and deggcd<degree m =>
+ faclist := henselfact1(divideExponents(m, deggcd)::ZP)
+ "append"/[henselfact1 multiplyExponents(mm, deggcd) for mm in faclist]
+ henselfact1 m
+
+ quadratic(m: ZP):List(ZP) ==
+ d,d2: Z
+ d := coefficient(m,1)**2-4*coefficient(m,0)*coefficient(m,2)
+ d2 := sqroot(d)
+ (d-d2**2)^=0 => [m]
+ alpha: Z := coefficient(m,1)+d2
+ beta: Z := 2*coefficient(m,2)
+ d := gcd(alpha,beta)
+ if d ^=1 then
+ alpha := alpha quo d
+ beta := beta quo d
+ m0: ZP := monomial(beta,1)+monomial(alpha,0)
+ cons(m0,[(m exquo m0):: ZP])
+
+ isPowerOf2(n : Z): Boolean ==
+ n = 1 => true
+ qr : Record(quotient: Z, remainder: Z) := divide(n,2)
+ qr.remainder = 1 => false
+ isPowerOf2 qr.quotient
+
+ subMinusX(supPol : SUPZ): ZP ==
+ minusX : SUPZ := monomial(-1,1)$SUPZ
+ (elt(supPol,minusX)$SUPZ) : ZP
+
+-- Factorize the polynomial m, test=true if m is known to be
+-- square-free, false otherwise.
+-- FinalFact.contp=content m, FinalFact.factors=List of irreducible
+-- factors with exponent .
+ henselFact(m: ZP,test:Boolean):FinalFact ==
+ factorlist : List(ParFact) := []
+ c : Z
+
+ -- make m primitive
+ c := content m
+ m := (m exquo c)::ZP
+
+ -- make the lc m positive
+ if leadingCoefficient m < 0 then
+ c := -c
+ m := -m
+
+ -- is x**d factor of m?
+ if (d := minimumDegree m) >0 then
+ m := (monicDivide(m,monomial(1,d))).quotient
+ factorlist := [[monomial(1,1),d]$ParFact]
+
+ d := degree m
+
+ -- is m constant?
+ d=0 => [c,factorlist]$FinalFact
+
+ -- is m linear?
+ d=1 => [c,cons([m,1]$ParFact,factorlist)]$FinalFact
+
+ -- does m satisfy Eisenstein's criterion?
+ eisenstein m => [c,cons([m,1]$ParFact,factorlist)]$FinalFact
+
+ lcPol : ZP := leadingCoefficient(m) :: ZP
+
+ -- is m cyclotomic (x**n - 1)?
+ -lcPol = reductum(m) => -- if true, both will = 1
+ for fac in
+ (cyclotomicDecomposition(degree m)$CYC : List ZP) repeat
+ factorlist := cons([fac,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is m odd cyclotomic (x**(2*n+1) + 1)?
+ odd?(d) and (lcPol = reductum(m)) =>
+ for sfac in cyclotomicDecomposition(degree m)$CYC repeat
+ fac:=subMinusX sfac
+ if leadingCoefficient fac < 0 then fac := -fac
+ factorlist := cons([fac,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is the poly of the form x**n + 1 with n a power of 2?
+ -- if so, then irreducible
+ isPowerOf2(d) and (lcPol = reductum(m)) =>
+ factorlist := cons([m,1]$ParFact,factorlist)
+ [c,factorlist]$FinalFact
+
+ -- is m quadratic?
+ d=2 =>
+ lfq:List(ZP) := quadratic m
+ #lfq=1 => [c,cons([lfq.first,1]$ParFact,factorlist)]$FinalFact
+ (lf0,lf1) := (lfq.first,second lfq)
+ if lf0=lf1 then factorlist := cons([lf0,2]$ParFact,factorlist)
+ else factorlist := append([[v,1]$ParFact for v in lfq],factorlist)
+ [c,factorlist]$FinalFact
+
+ -- m is square-free
+ test =>
+ fln := henselfact(m)
+ [c,append(factorlist,[[pf,1]$ParFact for pf in fln])]$FinalFact
+
+ -- find the square-free decomposition of m
+ irrFact := squareFree(m)
+ llf := factors irrFact
+
+ -- factorize the square-free primitive terms
+ for l1 in llf repeat
+ d1 := l1.exponent
+ pol := l1.factor
+ degree pol=1 => factorlist := cons([pol,d1]$ParFact,factorlist)
+ degree pol=2 =>
+ fln := quadratic(pol)
+ factorlist := append([[pf,d1]$ParFact for pf in fln],factorlist)
+ fln := henselfact(pol)
+ factorlist := append([[pf,d1]$ParFact for pf in fln],factorlist)
+ [c,factorlist]$FinalFact
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package UNIFACT UnivariateFactorize>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/updecomp.spad.pamphlet b/src/algebra/updecomp.spad.pamphlet
new file mode 100644
index 00000000..c300db68
--- /dev/null
+++ b/src/algebra/updecomp.spad.pamphlet
@@ -0,0 +1,178 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra updecomp.spad}
+\author{Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package UPDECOMP UnivariatePolynomialDecompositionPackage}
+<<package UPDECOMP UnivariatePolynomialDecompositionPackage>>=
+)abbrev package UPDECOMP UnivariatePolynomialDecompositionPackage
+++ Author: Frederic Lehobey
+++ Date Created: 17 June 1996
+++ Date Last Updated: 4 June 1997
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keyword:
+++ Exemples:
+++ References:
+++ [1] Peter Henrici, Automatic Computations with Power Series,
+++ Journal of the Association for Computing Machinery, Volume 3, No. 1,
+++ January 1956, 10-15
+++ [2] Dexter Kozen and Susan Landau, Polynomial Decomposition
+++ Algorithms, Journal of Symbolic Computation (1989) 7, 445-456
+-- Decomposition would be speeded up (O(n log n) instead of O(n^2)) by
+-- implementing the algorithm described in [3] based on [4] and [5].
+++ [3] Joachim von zur Gathen, Functional Decomposition Polynomials:
+++ the Tame Case, Journal of Symbolic Computation (1990) 9, 281-299
+++ [4] R. P. Brent and H. T. Kung, Fast Algorithms for Manipulating
+++ Formal Power Series, Journal of the Association for Computing
+++ Machinery, Vol. 25, No. 4, October 1978, 581-595
+++ [5] R. P. Brent, Multiple-Precision Zero-Finding Methods and the
+++ Complexity of Elementary Function Evaluation, Analytic
+++ Computational Complexity, J. F. Traub, Ed., Academic Press,
+++ New York 1975, 151-176
+++ Description: UnivariatePolynomialDecompositionPackage implements
+++ functional decomposition of univariate polynomial with coefficients
+++ in an \spad{IntegralDomain} of \spad{CharacteristicZero}.
+UnivariatePolynomialDecompositionPackage(R,UP): Exports == Implementation where
+ R : Join(IntegralDomain,CharacteristicZero)
+ UP : UnivariatePolynomialCategory(R)
+ N ==> NonNegativeInteger
+ LR ==> Record(left: UP, right: UP)
+ QR ==> Record(quotient: UP, remainder: UP)
+
+
+ Exports ==> with
+
+ monicRightFactorIfCan: (UP,N) -> Union(UP,"failed")
+ ++ monicRightFactorIfCan(f,d) returns a candidate to be the
+ ++ monic right factor (h in f = g o h) of degree d of a
+ ++ functional decomposition of the polynomial f or
+ ++ \spad{"failed"} if no such candidate.
+ rightFactorIfCan: (UP,N,R) -> Union(UP,"failed")
+ ++ rightFactorIfCan(f,d,c) returns a candidate to be the
+ ++ right factor (h in f = g o h) of degree d with leading
+ ++ coefficient c of a functional decomposition of the
+ ++ polynomial f or \spad{"failed"} if no such candidate.
+ leftFactorIfCan: (UP,UP) -> Union(UP,"failed")
+ ++ leftFactorIfCan(f,h) returns the left factor (g in f = g o h)
+ ++ of the functional decomposition of the polynomial f with
+ ++ given h or \spad{"failed"} if g does not exist.
+ monicDecomposeIfCan: UP -> Union(LR,"failed")
+ ++ monicDecomposeIfCan(f) returns a functional decomposition
+ ++ of the monic polynomial f of "failed" if it has not found any.
+ monicCompleteDecompose: UP -> List UP
+ ++ monicCompleteDecompose(f) returns a list of factors of f for
+ ++ the functional decomposition ([ f1, ..., fn ] means
+ ++ f = f1 o ... o fn).
+
+ Implementation ==> add
+
+ rightFactorIfCan(p,dq,lcq) ==
+ dp := degree p
+ zero? lcq =>
+ error "rightFactorIfCan: leading coefficient may not be zero"
+ (zero? dp) or (zero? dq) => "failed"
+ nc := dp exquo dq
+ nc case "failed" => "failed"
+ n := nc::N
+ s := subtractIfCan(dq,1)::N
+ lcp := leadingCoefficient p
+ q: UP := monomial(lcq,dq)
+ k: N
+ for k in 1..s repeat
+ c: R := 0
+ i: N
+ for i in 0..subtractIfCan(k,1)::N repeat
+ c := c+(k::R-(n::R+1)*(i::R))*
+ coefficient(q,subtractIfCan(dq,i)::N)*
+ coefficient(p,subtractIfCan(dp+i,k)::N)
+ cquo := c exquo ((k*n)::R*lcp)
+ cquo case "failed" => return "failed"
+ q := q+monomial(cquo::R,subtractIfCan(dq,k)::N)
+ q
+
+ monicRightFactorIfCan(p,dq) == rightFactorIfCan(p,dq,1$R)
+
+ import UnivariatePolynomialDivisionPackage(R,UP)
+
+ leftFactorIfCan(f,h) ==
+ g: UP := 0
+ zero? degree h => "failed"
+ for i in 0.. while not zero? f repeat
+ qrf := divideIfCan(f,h)
+ qrf case "failed" => return "failed"
+ qr := qrf :: QR
+ r := qr.remainder
+ not ground? r => return "failed"
+ g := g+monomial(ground(r),i)
+ f := qr.quotient
+ g
+
+ monicDecomposeIfCan f ==
+ df := degree f
+ zero? df => "failed"
+ for dh in 2..subtractIfCan(df,1)::N | zero?(df rem dh) repeat
+ h := monicRightFactorIfCan(f,dh)
+ h case UP =>
+ g := leftFactorIfCan(f,h::UP)
+ g case UP => return [g::UP,h::UP]
+ "failed"
+
+ monicCompleteDecompose f ==
+ cf := monicDecomposeIfCan f
+ cf case "failed" => [ f ]
+ lr := cf :: LR
+ append(monicCompleteDecompose lr.left,[lr.right])
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package UPDECOMP UnivariatePolynomialDecompositionPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/updivp.spad.pamphlet b/src/algebra/updivp.spad.pamphlet
new file mode 100644
index 00000000..67934a57
--- /dev/null
+++ b/src/algebra/updivp.spad.pamphlet
@@ -0,0 +1,99 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra updivp.spad}
+\author{Frederic Lehobey}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package UPDIVP UnivariatePolynomialDivisionPackage}
+<<package UPDIVP UnivariatePolynomialDivisionPackage>>=
+)abbrev package UPDIVP UnivariatePolynomialDivisionPackage
+++ Author: Frederic Lehobey
+++ Date Created: 3 June 1997
+++ Date Last Updated: 3 June 1997
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keyword:
+++ Exemples:
+++ References:
+++ Description: UnivariatePolynomialDivisionPackage provides a
+++ division for non monic univarite polynomials with coefficients in
+++ an \spad{IntegralDomain}.
+UnivariatePolynomialDivisionPackage(R,UP): Exports == Implementation where
+ R : IntegralDomain
+ UP : UnivariatePolynomialCategory(R)
+ N ==> NonNegativeInteger
+ QR ==> Record(quotient: UP, remainder: UP)
+
+ Exports ==> with
+
+ divideIfCan: (UP,UP) -> Union(QR,"failed")
+ ++ divideIfCan(f,g) returns quotient and remainder of the
+ ++ division of f by g or "failed" if it has not succeeded.
+
+ Implementation ==> add
+
+ divideIfCan(p1:UP,p2:UP):Union(QR,"failed") ==
+ zero? p2 => error "divideIfCan: division by zero"
+-- one? (lc := leadingCoefficient p2) => monicDivide(p1,p2)
+ ((lc := leadingCoefficient p2) = 1) => monicDivide(p1,p2)
+ q: UP := 0
+ while not ((e := subtractIfCan(degree(p1),degree(p2))) case "failed")
+ repeat
+ c := leadingCoefficient(p1) exquo lc
+ c case "failed" => return "failed"
+ ee := e::N
+ q := q+monomial(c::R,ee)
+ p1 := p1-c*mapExponents(#1+ee,p2)
+ [q,p1]
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package UPDIVP UnivariatePolynomialDivisionPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/utsode.spad.pamphlet b/src/algebra/utsode.spad.pamphlet
new file mode 100644
index 00000000..26d03144
--- /dev/null
+++ b/src/algebra/utsode.spad.pamphlet
@@ -0,0 +1,181 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra utsode.spad}
+\author{Stephen M. Watt, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package UTSODE UnivariateTaylorSeriesODESolver}
+<<package UTSODE UnivariateTaylorSeriesODESolver>>=
+)abbrev package UTSODE UnivariateTaylorSeriesODESolver
+++ Taylor series solutions of explicit ODE's.
+++ Author: Stephen Watt (revised by Clifton J. Williamson)
+++ Date Created: February 1988
+++ Date Last Updated: 30 September 1993
+++ Keywords: differential equation, ODE, Taylor series
+++ Examples:
+++ References:
+UnivariateTaylorSeriesODESolver(Coef,UTS):_
+ Exports == Implementation where
+ ++ This package provides Taylor series solutions to regular
+ ++ linear or non-linear ordinary differential equations of
+ ++ arbitrary order.
+ Coef : Algebra Fraction Integer
+ UTS : UnivariateTaylorSeriesCategory Coef
+ L ==> List
+ L2 ==> ListFunctions2
+ FN ==> (L UTS) -> UTS
+ ST ==> Stream Coef
+ YS ==> Y$ParadoxicalCombinatorsForStreams(Coef)
+ STT ==> StreamTaylorSeriesOperations(Coef)
+
+ Exports ==> with
+ stFunc1: (UTS -> UTS) -> (ST -> ST)
+ ++ stFunc1(f) is a local function exported due to compiler problem.
+ ++ This function is of no interest to the top-level user.
+ stFunc2: ((UTS,UTS) -> UTS) -> ((ST,ST) -> ST)
+ ++ stFunc2(f) is a local function exported due to compiler problem.
+ ++ This function is of no interest to the top-level user.
+ stFuncN: FN -> ((L ST) -> ST)
+ ++ stFuncN(f) is a local function xported due to compiler problem.
+ ++ This function is of no interest to the top-level user.
+ fixedPointExquo: (UTS,UTS) -> UTS
+ ++ fixedPointExquo(f,g) computes the exact quotient of \spad{f} and
+ ++ \spad{g} using a fixed point computation.
+ ode1: ((UTS -> UTS),Coef) -> UTS
+ ++ ode1(f,c) is the solution to \spad{y' = f(y)}
+ ++ such that \spad{y(a) = c}.
+ ode2: ((UTS, UTS) -> UTS,Coef,Coef) -> UTS
+ ++ ode2(f,c0,c1) is the solution to \spad{y'' = f(y,y')} such that
+ ++ \spad{y(a) = c0} and \spad{y'(a) = c1}.
+ ode: (FN,List Coef) -> UTS
+ ++ ode(f,cl) is the solution to \spad{y<n>=f(y,y',..,y<n-1>)} such that
+ ++ \spad{y<i>(a) = cl.i} for i in 1..n.
+ mpsode:(L Coef,L FN) -> L UTS
+ ++ mpsode(r,f) solves the system of differential equations
+ ++ \spad{dy[i]/dx =f[i] [x,y[1],y[2],...,y[n]]},
+ ++ \spad{y[i](a) = r[i]} for i in 1..n.
+
+ Implementation ==> add
+
+ stFunc1 f == coefficients f series(#1)
+ stFunc2 f == coefficients f(series(#1),series(#2))
+ stFuncN f == coefficients f map(series,#1)$ListFunctions2(ST,UTS)
+
+ import StreamTaylorSeriesOperations(Coef)
+ divloopre:(Coef,ST,Coef,ST,ST) -> ST
+ divloopre(hx,tx,hy,ty,c) == delay(concat(hx*hy,hy*(tx-(ty*c))))
+ divloop: (Coef,ST,Coef,ST) -> ST
+ divloop(hx,tx,hy,ty) == YS(divloopre(hx,tx,hy,ty,#1))
+
+ sdiv:(ST,ST) -> ST
+ sdiv(x,y) == delay
+ empty? x => empty()
+ empty? y => error "stream division by zero"
+ hx := frst x; tx := rst x
+ hy := frst y; ty := rst y
+ zero? hy =>
+ zero? hx => sdiv(tx,ty)
+ error "stream division by zero"
+ rhy := recip hy
+ rhy case "failed" => error "stream division:no reciprocal"
+ divloop(hx,tx,rhy::Coef,ty)
+
+ fixedPointExquo(f,g) == series sdiv(coefficients f,coefficients g)
+
+-- first order
+
+ ode1re: (ST -> ST,Coef,ST) -> ST
+ ode1re(f,c,y) == lazyIntegrate(c,f y)$STT
+
+ iOde1: ((ST -> ST),Coef) -> ST
+ iOde1(f,c) == YS ode1re(f,c,#1)
+
+ ode1(f,c) == series iOde1(stFunc1 f,c)
+
+-- second order
+
+ ode2re: ((ST,ST)-> ST,Coef,Coef,ST) -> ST
+ ode2re(f,c0,c1,y)==
+ yi := lazyIntegrate(c1,f(y,deriv(y)$STT))$STT
+ lazyIntegrate(c0,yi)$STT
+
+ iOde2: ((ST,ST) -> ST,Coef,Coef) -> ST
+ iOde2(f,c0,c1) == YS ode2re(f,c0,c1,#1)
+
+ ode2(f,c0,c1) == series iOde2(stFunc2 f,c0,c1)
+
+-- nth order
+
+ odeNre: (List ST -> ST,List Coef,List ST) -> List ST
+ odeNre(f,cl,yl) ==
+ -- yl is [y, y', ..., y<n>]
+ -- integrate [y',..,y<n>] to get [y,..,y<n-1>]
+ yil := [lazyIntegrate(c,y)$STT for c in cl for y in rest yl]
+ -- use y<n> = f(y,..,y<n-1>)
+ concat(yil,[f yil])
+
+ iOde: ((L ST) -> ST,List Coef) -> ST
+ iOde(f,cl) == first YS(odeNre(f,cl,#1),#cl + 1)
+
+ ode(f,cl) == series iOde(stFuncN f,cl)
+
+ simulre:(L Coef,L ((L ST) -> ST),L ST) -> L ST
+ simulre(cst,lsf,c) ==
+ [lazyIntegrate(csti,lsfi concat(monom(1,1)$STT,c))_
+ for csti in cst for lsfi in lsf]
+ iMpsode:(L Coef,L ((L ST) -> ST)) -> L ST
+ iMpsode(cs,lsts) == YS(simulre(cs,lsts,#1),# cs)
+ mpsode(cs,lsts) ==
+-- stSol := iMpsode(cs,map(stFuncN,lsts)$L2(FN,(L ST) -> ST))
+ stSol := iMpsode(cs,[stFuncN(lst) for lst in lsts])
+ map(series,stSol)$L2(ST,UTS)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package UTSODE UnivariateTaylorSeriesODESolver>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/variable.spad.pamphlet b/src/algebra/variable.spad.pamphlet
new file mode 100644
index 00000000..0f50171d
--- /dev/null
+++ b/src/algebra/variable.spad.pamphlet
@@ -0,0 +1,146 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra variable.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain OVAR OrderedVariableList}
+<<domain OVAR OrderedVariableList>>=
+)abbrev domain OVAR OrderedVariableList
+++ Description:
+++ This domain implements ordered variables
+OrderedVariableList(VariableList:List Symbol):
+ Join(OrderedFinite, ConvertibleTo Symbol, ConvertibleTo InputForm,
+ ConvertibleTo Pattern Float, ConvertibleTo Pattern Integer) with
+ variable: Symbol -> Union(%,"failed")
+ ++ variable(s) returns a member of the variable set or failed
+ == add
+ VariableList := removeDuplicates VariableList
+ Rep := PositiveInteger
+ s1,s2:%
+ convert(s1):Symbol == VariableList.((s1::Rep)::PositiveInteger)
+ coerce(s1):OutputForm == (convert(s1)@Symbol)::OutputForm
+ convert(s1):InputForm == convert(convert(s1)@Symbol)
+ convert(s1):Pattern(Integer) == convert(convert(s1)@Symbol)
+ convert(s1):Pattern(Float) == convert(convert(s1)@Symbol)
+ index i == i::%
+ lookup j == j :: Rep
+ size () == #VariableList
+ variable(exp:Symbol) ==
+ for i in 1.. for exp2 in VariableList repeat
+ if exp=exp2 then return i::PositiveInteger::%
+ "failed"
+ s1 < s2 == s2 <$Rep s1
+ s1 = s2 == s1 =$Rep s2
+ latex(x:%):String == latex(convert(x)@Symbol)
+
+@
+\section{domain VARIABLE Variable}
+<<domain VARIABLE Variable>>=
+)abbrev domain VARIABLE Variable
+++ Description:
+++ This domain implements variables
+Variable(sym:Symbol): Join(SetCategory, CoercibleTo Symbol) with
+ coerce : % -> Symbol
+ ++ coerce(x) returns the symbol
+ variable: () -> Symbol
+ ++ variable() returns the symbol
+ == add
+ coerce(x:%):Symbol == sym
+ coerce(x:%):OutputForm == sym::OutputForm
+ variable() == sym
+ x = y == true
+ latex(x:%):String == latex sym
+
+@
+\section{domain RULECOLD RuleCalled}
+<<domain RULECOLD RuleCalled>>=
+)abbrev domain RULECOLD RuleCalled
+++ Description:
+++ This domain implements named rules
+RuleCalled(f:Symbol): SetCategory with
+ name: % -> Symbol
+ ++ name(x) returns the symbol
+ == add
+ name r == f
+ coerce(r:%):OutputForm == f::OutputForm
+ x = y == true
+ latex(x:%):String == latex f
+
+@
+\section{domain FUNCTION FunctionCalled}
+<<domain FUNCTION FunctionCalled>>=
+)abbrev domain FUNCTION FunctionCalled
+++ Description:
+++ This domain implements named functions
+FunctionCalled(f:Symbol): SetCategory with
+ name: % -> Symbol
+ ++ name(x) returns the symbol
+ == add
+ name r == f
+ coerce(r:%):OutputForm == f::OutputForm
+ x = y == true
+ latex(x:%):String == latex f
+
+@
+\section{domain ANON AnonymousFunction}
+<<domain ANON AnonymousFunction>>=
+)abbrev domain ANON AnonymousFunction
+++ Description:
+++ This domain implements anonymous functions
+AnonymousFunction():SetCategory == add
+ coerce(x:%):OutputForm == x pretend OutputForm
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain VARIABLE Variable>>
+<<domain RULECOLD RuleCalled>>
+<<domain FUNCTION FunctionCalled>>
+<<domain OVAR OrderedVariableList>>
+<<domain ANON AnonymousFunction>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/vector.spad.pamphlet b/src/algebra/vector.spad.pamphlet
new file mode 100644
index 00000000..0406479e
--- /dev/null
+++ b/src/algebra/vector.spad.pamphlet
@@ -0,0 +1,528 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra vector.spad}
+\author{The Axiom Team}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{category VECTCAT VectorCategory}
+<<category VECTCAT VectorCategory>>=
+)abbrev category VECTCAT VectorCategory
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: DirectProductCategory, Vector, IndexedVector
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ \spadtype{VectorCategory} represents the type of vector like objects,
+++ i.e. finite sequences indexed by some finite segment of the
+++ integers. The operations available on vectors depend on the structure
+++ of the underlying components. Many operations from the component domain
+++ are defined for vectors componentwise. It can by assumed that extraction or
+++ updating components can be done in constant time.
+
+VectorCategory(R:Type): Category == OneDimensionalArrayAggregate R with
+ if R has AbelianSemiGroup then
+ _+ : (%, %) -> %
+ ++ x + y returns the component-wise sum of the vectors x and y.
+ ++ Error: if x and y are not of the same length.
+ if R has AbelianMonoid then
+ zero: NonNegativeInteger -> %
+ ++ zero(n) creates a zero vector of length n.
+ if R has AbelianGroup then
+ _- : % -> %
+ ++ -x negates all components of the vector x.
+ _- : (%, %) -> %
+ ++ x - y returns the component-wise difference of the vectors x and y.
+ ++ Error: if x and y are not of the same length.
+ _* : (Integer, %) -> %
+ ++ n * y multiplies each component of the vector y by the integer n.
+ if R has Monoid then
+ _* : (R, %) -> %
+ ++ r * y multiplies the element r times each component of the vector y.
+ _* : (%, R) -> %
+ ++ y * r multiplies each component of the vector y by the element r.
+ if R has Ring then
+ dot: (%, %) -> R
+ ++ dot(x,y) computes the inner product of the two vectors x and y.
+ ++ Error: if x and y are not of the same length.
+ outerProduct: (%, %) -> Matrix R
+ ++ outerProduct(u,v) constructs the matrix whose (i,j)'th element is
+ ++ u(i)*v(j).
+ cross: (%, %) -> %
+ ++ vectorProduct(u,v) constructs the cross product of u and v.
+ ++ Error: if u and v are not of length 3.
+ if R has RadicalCategory and R has Ring then
+ length: % -> R
+ ++ length(v) computes the sqrt(dot(v,v)), i.e. the magnitude
+ magnitude: % -> R
+ ++ magnitude(v) computes the sqrt(dot(v,v)), i.e. the length
+ add
+ if R has AbelianSemiGroup then
+ u + v ==
+ (n := #u) ^= #v => error "Vectors must be of the same length"
+ map(_+ , u, v)
+
+ if R has AbelianMonoid then
+ zero n == new(n, 0)
+
+ if R has AbelianGroup then
+ - u == map(- #1, u)
+ n:Integer * u:% == map(n * #1, u)
+ u - v == u + (-v)
+
+ if R has Monoid then
+ u:% * r:R == map(#1 * r, u)
+ r:R * u:% == map(r * #1, u)
+
+ if R has Ring then
+ dot(u, v) ==
+ #u ^= #v => error "Vectors must be of the same length"
+ _+/[qelt(u, i) * qelt(v, i) for i in minIndex u .. maxIndex u]
+ outerProduct(u, v) ==
+ matrix [[qelt(u, i) * qelt(v,j) for i in minIndex u .. maxIndex u] _
+ for j in minIndex v .. maxIndex v]
+ cross(u, v) ==
+ #u ^= 3 or #v ^= 3 => error "Vectors must be of length 3"
+ construct [qelt(u, 2)*qelt(v, 3) - qelt(u, 3)*qelt(v, 2) , _
+ qelt(u, 3)*qelt(v, 1) - qelt(u, 1)*qelt(v, 3) , _
+ qelt(u, 1)*qelt(v, 2) - qelt(u, 2)*qelt(v, 1) ]
+
+ if R has RadicalCategory and R has Ring then
+ length p ==
+ sqrt(dot(p,p))
+ magnitude p ==
+ sqrt(dot(p,p))
+
+@
+\section{domain IVECTOR IndexedVector}
+<<domain IVECTOR IndexedVector>>=
+)abbrev domain IVECTOR IndexedVector
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Vector, DirectProduct
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type represents vector like objects with varying lengths
+++ and a user-specified initial index.
+
+IndexedVector(R:Type, mn:Integer):
+ VectorCategory R == IndexedOneDimensionalArray(R, mn)
+
+@
+\section{domain VECTOR Vector}
+<<domain VECTOR Vector>>=
+)abbrev domain VECTOR Vector
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: IndexedVector, DirectProduct
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type represents vector like objects with varying lengths
+++ and indexed by a finite segment of integers starting at 1.
+
+Vector(R:Type): Exports == Implementation where
+ VECTORMININDEX ==> 1 -- if you want to change this, be my guest
+
+ Exports ==> VectorCategory R with
+ vector: List R -> %
+ ++ vector(l) converts the list l to a vector.
+ Implementation ==>
+ IndexedVector(R, VECTORMININDEX) add
+ vector l == construct l
+ if R has ConvertibleTo InputForm then
+ convert(x:%):InputForm ==
+ convert [convert("vector"::Symbol)@InputForm,
+ convert(parts x)@InputForm]
+
+@
+\section{VECTOR.lsp BOOTSTRAP}
+{\bf VECTOR} depends on itself.
+We need to break this cycle to build the algebra. So we keep a
+cached copy of the translated {\bf VECTOR} category which we can write
+into the {\bf MID} directory. We compile the lisp code and copy the
+{\bf VECTOR.o} file to the {\bf OUT} directory. This is eventually
+forcibly replaced by a recompiled version.
+
+Note that this code is not included in the generated catdef.spad file.
+
+<<VECTOR.lsp BOOTSTRAP>>=
+
+(|/VERSIONCHECK| 2)
+
+(DEFUN |VECTOR;vector;L$;1| (|l| |$|) (SPADCALL |l| (QREFELT |$| 8)))
+
+(DEFUN |VECTOR;convert;$If;2| (|x| |$|) (SPADCALL (LIST (SPADCALL (SPADCALL "vector" (QREFELT |$| 12)) (QREFELT |$| 14)) (SPADCALL (SPADCALL |x| (QREFELT |$| 15)) (QREFELT |$| 16))) (QREFELT |$| 18)))
+
+(DEFUN |Vector| (#1=#:G84134) (PROG NIL (RETURN (PROG (#2=#:G84135) (RETURN (COND ((LETT #2# (|lassocShiftWithFunction| (LIST (|devaluate| #1#)) (HGET |$ConstructorCache| (QUOTE |Vector|)) (QUOTE |domainEqualList|)) |Vector|) (|CDRwithIncrement| #2#)) ((QUOTE T) (|UNWIND-PROTECT| (PROG1 (|Vector;| #1#) (LETT #2# T |Vector|)) (COND ((NOT #2#) (HREM |$ConstructorCache| (QUOTE |Vector|))))))))))))
+
+(DEFUN |Vector;| (|#1|) (PROG (|DV$1| |dv$| |$| #1=#:G84133 |pv$|) (RETURN (PROGN (LETT |DV$1| (|devaluate| |#1|) . #2=(|Vector|)) (LETT |dv$| (LIST (QUOTE |Vector|) |DV$1|) . #2#) (LETT |$| (GETREFV 36) . #2#) (QSETREFV |$| 0 |dv$|) (QSETREFV |$| 3 (LETT |pv$| (|buildPredVector| 0 0 (LIST (|HasCategory| |#1| (QUOTE (|SetCategory|))) (|HasCategory| |#1| (QUOTE (|ConvertibleTo| (|InputForm|)))) (LETT #1# (|HasCategory| |#1| (QUOTE (|OrderedSet|))) . #2#) (OR #1# (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (|HasCategory| (|Integer|) (QUOTE (|OrderedSet|))) (|HasCategory| |#1| (QUOTE (|AbelianSemiGroup|))) (|HasCategory| |#1| (QUOTE (|AbelianMonoid|))) (|HasCategory| |#1| (QUOTE (|AbelianGroup|))) (|HasCategory| |#1| (QUOTE (|Monoid|))) (|HasCategory| |#1| (QUOTE (|Ring|))) (AND (|HasCategory| |#1| (QUOTE (|RadicalCategory|))) (|HasCategory| |#1| (QUOTE (|Ring|)))) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|)))) (OR (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) #1#) (AND (|HasCategory| |#1| (LIST (QUOTE |Evalable|) (|devaluate| |#1|))) (|HasCategory| |#1| (QUOTE (|SetCategory|))))))) . #2#)) (|haddProp| |$ConstructorCache| (QUOTE |Vector|) (LIST |DV$1|) (CONS 1 |$|)) (|stuffDomainSlots| |$|) (QSETREFV |$| 6 |#1|) (COND ((|testBitVector| |pv$| 2) (QSETREFV |$| 19 (CONS (|dispatchFunction| |VECTOR;convert;$If;2|) |$|)))) |$|))))
+
+(MAKEPROP (QUOTE |Vector|) (QUOTE |infovec|) (LIST (QUOTE #(NIL NIL NIL NIL NIL (|IndexedVector| 6 (NRTEVAL 1)) (|local| |#1|) (|List| 6) (0 . |construct|) |VECTOR;vector;L$;1| (|String|) (|Symbol|) (5 . |coerce|) (|InputForm|) (10 . |convert|) (15 . |parts|) (20 . |convert|) (|List| |$|) (25 . |convert|) (30 . |convert|) (|Mapping| 6 6 6) (|Boolean|) (|NonNegativeInteger|) (|List| 24) (|Equation| 6) (|Integer|) (|Mapping| 21 6) (|Mapping| 21 6 6) (|UniversalSegment| 25) (|Void|) (|Mapping| 6 6) (|Matrix| 6) (|OutputForm|) (|SingleInteger|) (|Union| 6 (QUOTE "failed")) (|List| 25))) (QUOTE #(|vector| 35 |parts| 40 |convert| 45 |construct| 50)) (QUOTE ((|shallowlyMutable| . 0) (|finiteAggregate| . 0))) (CONS (|makeByteWordVec2| 13 (QUOTE (0 0 0 0 0 0 0 3 0 0 13 4 0 0 13 1 2 4))) (CONS (QUOTE #(|VectorCategory&| |OneDimensionalArrayAggregate&| |FiniteLinearAggregate&| |LinearAggregate&| |IndexedAggregate&| |Collection&| |HomogeneousAggregate&| |OrderedSet&| |Aggregate&| |EltableAggregate&| |Evalable&| |SetCategory&| NIL NIL |InnerEvalable&| NIL NIL |BasicType&|)) (CONS (QUOTE #((|VectorCategory| 6) (|OneDimensionalArrayAggregate| 6) (|FiniteLinearAggregate| 6) (|LinearAggregate| 6) (|IndexedAggregate| 25 6) (|Collection| 6) (|HomogeneousAggregate| 6) (|OrderedSet|) (|Aggregate|) (|EltableAggregate| 25 6) (|Evalable| 6) (|SetCategory|) (|Type|) (|Eltable| 25 6) (|InnerEvalable| 6 6) (|CoercibleTo| 32) (|ConvertibleTo| 13) (|BasicType|))) (|makeByteWordVec2| 19 (QUOTE (1 0 0 7 8 1 11 0 10 12 1 13 0 11 14 1 0 7 0 15 1 7 13 0 16 1 13 0 17 18 1 0 13 0 19 1 0 0 7 9 1 0 7 0 15 1 2 13 0 19 1 0 0 7 8)))))) (QUOTE |lookupIncomplete|)))
+@
+\section{package VECTOR2 VectorFunctions2}
+<<package VECTOR2 VectorFunctions2>>=
+)abbrev package VECTOR2 VectorFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides operations which all take as arguments
+++ vectors of elements of some type \spad{A} and functions from \spad{A} to
+++ another of type B. The operations all iterate over their vector argument
+++ and either return a value of type B or a vector over B.
+
+VectorFunctions2(A, B): Exports == Implementation where
+ A, B: Type
+
+ VA ==> Vector A
+ VB ==> Vector B
+ O2 ==> FiniteLinearAggregateFunctions2(A, VA, B, VB)
+ UB ==> Union(B,"failed")
+
+ Exports ==> with
+ scan : ((A, B) -> B, VA, B) -> VB
+ ++ scan(func,vec,ident) creates a new vector whose elements are
+ ++ the result of applying reduce to the binary function func,
+ ++ increasing initial subsequences of the vector vec,
+ ++ and the element ident.
+ reduce : ((A, B) -> B, VA, B) -> B
+ ++ reduce(func,vec,ident) combines the elements in vec using the
+ ++ binary function func. Argument ident is returned if vec is empty.
+ map : (A -> B, VA) -> VB
+ ++ map(f, v) applies the function f to every element of the vector v
+ ++ producing a new vector containing the values.
+ map : (A -> UB, VA) -> Union(VB,"failed")
+ ++ map(f, v) applies the function f to every element of the vector v
+ ++ producing a new vector containing the values or \spad{"failed"}.
+
+ Implementation ==> add
+ scan(f, v, b) == scan(f, v, b)$O2
+ reduce(f, v, b) == reduce(f, v, b)$O2
+ map(f:(A->B), v:VA):VB == map(f, v)$O2
+
+ map(f:(A -> UB), a:VA):Union(VB,"failed") ==
+ res : List B := []
+ for u in entries(a) repeat
+ r := f u
+ r = "failed" => return "failed"
+ res := [r::B,:res]
+ vector reverse! res
+
+@
+\section{category DIRPCAT DirectProductCategory}
+<<category DIRPCAT DirectProductCategory>>=
+)abbrev category DIRPCAT DirectProductCategory
+-- all direct product category domains must be compiled
+-- without subsumption, set SourceLevelSubset to EQUAL
+--)bo $noSubsumption := true
+
+--% DirectProductCategory
+
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: DirectProduct
+++ Also See: VectorCategory
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This category represents a finite cartesian product of a given type.
+++ Many categorical properties are preserved under this construction.
+
+DirectProductCategory(dim:NonNegativeInteger, R:Type): Category ==
+ Join(IndexedAggregate(Integer, R), CoercibleTo Vector R) with
+ finiteAggregate
+ ++ attribute to indicate an aggregate of finite size
+ directProduct: Vector R -> %
+ ++ directProduct(v) converts the vector v to become
+ ++ a direct product. Error: if the length of v is
+ ++ different from dim.
+ if R has SetCategory then FullyRetractableTo R
+ if R has Ring then
+ BiModule(R, R)
+ DifferentialExtension R
+ FullyLinearlyExplicitRingOver R
+ unitVector: PositiveInteger -> %
+ ++ unitVector(n) produces a vector with 1 in position n and
+ ++ zero elsewhere.
+ dot: (%, %) -> R
+ ++ dot(x,y) computes the inner product of the vectors x and y.
+ if R has AbelianSemiGroup then AbelianSemiGroup
+ if R has CancellationAbelianMonoid then CancellationAbelianMonoid
+ if R has Monoid then
+ _* : (R, %) -> %
+ ++ r * y multiplies the element r times each component of the
+ ++ vector y.
+ _* : (%, R) -> %
+ ++ y * r multiplies each component of the vector y by the element r.
+ if R has Finite then Finite
+ if R has CommutativeRing then
+ Algebra R
+ CommutativeRing
+ if R has unitsKnown then unitsKnown
+ if R has OrderedRing then OrderedRing
+ if R has OrderedAbelianMonoidSup then OrderedAbelianMonoidSup
+ if R has Field then VectorSpace R
+ add
+ if R has Ring then
+ equation2R: Vector % -> Matrix R
+
+ coerce(n:Integer):% == n::R::%
+ characteristic() == characteristic()$R
+ differentiate(z:%, d:R -> R) == map(d, z)
+
+ equation2R v ==
+ ans:Matrix(R) := new(dim, #v, 0)
+ for i in minRowIndex ans .. maxRowIndex ans repeat
+ for j in minColIndex ans .. maxColIndex ans repeat
+ qsetelt_!(ans, i, j, qelt(qelt(v, j), i))
+ ans
+
+ reducedSystem(m:Matrix %):Matrix(R) ==
+ empty? m => new(0, 0, 0)
+ reduce(vertConcat, [equation2R row(m, i)
+ for i in minRowIndex m .. maxRowIndex m])$List(Matrix R)
+
+ reducedSystem(m:Matrix %, v:Vector %):
+ Record(mat:Matrix R, vec:Vector R) ==
+ vh:Vector(R) :=
+ empty? v => empty()
+ rh := reducedSystem(v::Matrix %)@Matrix(R)
+ column(rh, minColIndex rh)
+ [reducedSystem(m)@Matrix(R), vh]
+
+ if R has Finite then size == size$R ** dim
+
+ if R has Field then
+ x / b == x * inv b
+ dimension() == dim::CardinalNumber
+
+@
+\section{domain DIRPROD DirectProduct}
+<<domain DIRPROD DirectProduct>>=
+)abbrev domain DIRPROD DirectProduct
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors: Vector, IndexedVector
+++ Also See: OrderedDirectProduct
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type represents the finite direct or cartesian product of an
+++ underlying component type. This contrasts with simple vectors in that
+++ the members can be viewed as having constant length. Thus many
+++ categorical properties can by lifted from the underlying component type.
+++ Component extraction operations are provided but no updating operations.
+++ Thus new direct product elements can either be created by converting
+++ vector elements using the \spadfun{directProduct} function
+++ or by taking appropriate linear combinations of basis vectors provided
+++ by the \spad{unitVector} operation.
+
+DirectProduct(dim:NonNegativeInteger, R:Type):
+ DirectProductCategory(dim, R) == Vector R add
+
+ Rep := Vector R
+
+ coerce(z:%):Vector(R) == copy(z)$Rep pretend Vector(R)
+ coerce(r:R):% == new(dim, r)$Rep
+
+ parts x == VEC2LIST(x)$Lisp
+
+ directProduct z ==
+ size?(z, dim) => copy(z)$Rep
+ error "Not of the correct length"
+
+
+ if R has SetCategory then
+ same?: % -> Boolean
+ same? z == every?(#1 = z(minIndex z), z)
+
+ x = y == _and/[qelt(x,i)$Rep = qelt(y,i)$Rep for i in 1..dim]
+
+ retract(z:%):R ==
+ same? z => z(minIndex z)
+ error "Not retractable"
+
+ retractIfCan(z:%):Union(R, "failed") ==
+ same? z => z(minIndex z)
+ "failed"
+
+
+ if R has AbelianSemiGroup then
+ u:% + v:% == map(_+ , u, v)$Rep
+
+ if R has AbelianMonoid then
+ 0 == zero(dim)$Vector(R) pretend %
+
+ if R has Monoid then
+ 1 == new(dim, 1)$Vector(R) pretend %
+ u:% * r:R == map(#1 * r, u)
+ r:R * u:% == map(r * #1, u)
+
+
+ if R has CancellationAbelianMonoid then
+ subtractIfCan(u:%, v:%):Union(%,"failed") ==
+ w := new(dim,0)$Vector(R)
+ for i in 1..dim repeat
+ (c := subtractIfCan(qelt(u, i)$Rep, qelt(v,i)$Rep)) case "failed" =>
+ return "failed"
+ qsetelt_!(w, i, c::R)$Rep
+ w pretend %
+
+ if R has Ring then
+
+ u:% * v:% == map(_* , u, v)$Rep
+
+ recip z ==
+ w := new(dim,0)$Vector(R)
+ for i in minIndex w .. maxIndex w repeat
+ (u := recip qelt(z, i)) case "failed" => return "failed"
+ qsetelt_!(w, i, u::R)
+ w pretend %
+
+ unitVector i ==
+ v:= new(dim,0)$Vector(R)
+ v.i := 1
+ v pretend %
+
+ if R has OrderedSet then
+ x < y ==
+ for i in 1..dim repeat
+ qelt(x,i) < qelt(y,i) => return true
+ qelt(x,i) > qelt(y,i) => return false
+ false
+
+ if R has OrderedAbelianMonoidSup then sup(x, y) == map(sup, x, y)
+
+--)bo $noSubsumption := false
+
+@
+\section{package DIRPROD2 DirectProductFunctions2}
+<<package DIRPROD2 DirectProductFunctions2>>=
+)abbrev package DIRPROD2 DirectProductFunctions2
+++ Author:
+++ Date Created:
+++ Date Last Updated:
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides operations which all take as arguments
+++ direct products of elements of some type \spad{A} and functions from \spad{A} to another
+++ type B. The operations all iterate over their vector argument
+++ and either return a value of type B or a direct product over B.
+
+DirectProductFunctions2(dim, A, B): Exports == Implementation where
+ dim : NonNegativeInteger
+ A, B: Type
+
+ DA ==> DirectProduct(dim, A)
+ DB ==> DirectProduct(dim, B)
+ VA ==> Vector A
+ VB ==> Vector B
+ O2 ==> FiniteLinearAggregateFunctions2(A, VA, B, VB)
+
+ Exports ==> with
+ scan : ((A, B) -> B, DA, B) -> DB
+ ++ scan(func,vec,ident) creates a new vector whose elements are
+ ++ the result of applying reduce to the binary function func,
+ ++ increasing initial subsequences of the vector vec,
+ ++ and the element ident.
+ reduce : ((A, B) -> B, DA, B) -> B
+ ++ reduce(func,vec,ident) combines the elements in vec using the
+ ++ binary function func. Argument ident is returned if the vector is empty.
+ map : (A -> B, DA) -> DB
+ ++ map(f, v) applies the function f to every element of the vector v
+ ++ producing a new vector containing the values.
+
+ Implementation ==> add
+ import FiniteLinearAggregateFunctions2(A, VA, B, VB)
+
+ map(f, v) == directProduct map(f, v::VA)
+ scan(f, v, b) == directProduct scan(f, v::VA, b)
+ reduce(f, v, b) == reduce(f, v::VA, b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<category VECTCAT VectorCategory>>
+<<domain IVECTOR IndexedVector>>
+<<domain VECTOR Vector>>
+<<package VECTOR2 VectorFunctions2>>
+<<category DIRPCAT DirectProductCategory>>
+<<domain DIRPROD DirectProduct>>
+<<package DIRPROD2 DirectProductFunctions2>>
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/view2D.spad.pamphlet b/src/algebra/view2D.spad.pamphlet
new file mode 100644
index 00000000..5676019e
--- /dev/null
+++ b/src/algebra/view2D.spad.pamphlet
@@ -0,0 +1,1170 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra view2D.spad}
+\author{James Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain GRIMAGE GraphImage}
+<<domain GRIMAGE GraphImage>>=
+)abbrev domain GRIMAGE GraphImage
+++ Author: Jim Wen
+++ Date Created: 27 April 1989
+++ Date Last Updated: 1995 September 20, Mike Richardson (MGR)
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TwoDimensionalGraph creates virtual two dimensional graphs
+++ (to be displayed on TwoDimensionalViewports).
+GraphImage (): Exports == Implementation where
+
+ VIEW ==> VIEWPORTSERVER$Lisp
+ sendI ==> SOCK_-SEND_-INT
+ sendSF ==> SOCK_-SEND_-FLOAT
+ sendSTR ==> SOCK_-SEND_-STRING
+ getI ==> SOCK_-GET_-INT
+ getSF ==> SOCK_-GET_-FLOAT
+
+ typeGRAPH ==> 2
+ typeVIEW2D ==> 3
+
+ makeGRAPH ==> (-1)$SingleInteger
+ makeVIEW2D ==> (-1)$SingleInteger
+
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SF ==> DoubleFloat
+ F ==> Float
+ L ==> List
+ P ==> Point(SF)
+ V ==> Vector
+ SEG ==> Segment
+ RANGESF ==> L SEG SF
+ RANGEF ==> L SEG F
+ UNITSF ==> L SF
+ UNITF ==> L F
+ PAL ==> Palette
+ E ==> OutputForm
+ DROP ==> DrawOption
+ PP ==> PointPackage(SF)
+ COORDSYS ==> CoordinateSystems(SF)
+
+ Exports ==> SetCategory with
+ graphImage : () -> $
+ ++ graphImage() returns an empty graph with 0 point lists
+ ++ of the domain \spadtype{GraphImage}. A graph image contains
+ ++ the graph data component of a two dimensional viewport.
+ makeGraphImage : $ -> $
+ ++ makeGraphImage(gi) takes the given graph, \spad{gi} of the
+ ++ domain \spadtype{GraphImage}, and sends it's data to the
+ ++ viewport manager where it waits to be included in a two-dimensional
+ ++ viewport window. \spad{gi} cannot be an empty graph, and it's
+ ++ elements must have been created using the \spadfun{point} or
+ ++ \spadfun{component} functions, not by a previous
+ ++ \spadfun{makeGraphImage}.
+ makeGraphImage : (L L P) -> $
+ ++ makeGraphImage(llp) returns a graph of the domain
+ ++ \spadtype{GraphImage} which is composed of the points and
+ ++ lines from the list of lists of points, \spad{llp}, with
+ ++ default point size and default point and line colours. The graph
+ ++ data is then sent to the viewport manager where it waits to be
+ ++ included in a two-dimensional viewport window.
+ makeGraphImage : (L L P,L PAL,L PAL,L PI) -> $
+ ++ makeGraphImage(llp,lpal1,lpal2,lp) returns a graph of the
+ ++ domain \spadtype{GraphImage} which is composed of the points
+ ++ and lines from the list of lists of points, \spad{llp}, whose
+ ++ point colors are indicated by the list of palette colors,
+ ++ \spad{lpal1}, and whose lines are colored according to the list
+ ++ of palette colors, \spad{lpal2}. The paramater lp is a list of
+ ++ integers which denote the size of the data points. The graph
+ ++ data is then sent to the viewport manager where it waits to be
+ ++ included in a two-dimensional viewport window.
+ makeGraphImage : (L L P,L PAL,L PAL,L PI,L DROP) -> $
+ ++ makeGraphImage(llp,lpal1,lpal2,lp,lopt) returns a graph of
+ ++ the domain \spadtype{GraphImage} which is composed of the
+ ++ points and lines from the list of lists of points, \spad{llp},
+ ++ whose point colors are indicated by the list of palette colors,
+ ++ \spad{lpal1}, and whose lines are colored according to the list
+ ++ of palette colors, \spad{lpal2}. The paramater lp is a list of
+ ++ integers which denote the size of the data points, and \spad{lopt}
+ ++ is the list of draw command options. The graph data is then sent
+ ++ to the viewport manager where it waits to be included in a
+ ++ two-dimensional viewport window.
+ pointLists : $ -> L L P
+ ++ pointLists(gi) returns the list of lists of points which compose
+ ++ the given graph, \spad{gi}, of the domain \spadtype{GraphImage}.
+ key : $ -> I
+ ++ key(gi) returns the process ID of the given graph, \spad{gi},
+ ++ of the domain \spadtype{GraphImage}.
+ ranges : $ -> RANGEF
+ ++ ranges(gi) returns the list of ranges of the point components from
+ ++ the indicated graph, \spad{gi}, of the domain \spadtype{GraphImage}.
+ ranges : ($,RANGEF) -> RANGEF
+ ++ ranges(gi,lr) modifies the list of ranges for the given graph,
+ ++ \spad{gi} of the domain \spadtype{GraphImage}, to be that of the
+ ++ list of range segments, \spad{lr}, and returns the new range list
+ ++ for \spad{gi}.
+ units : $ -> UNITF
+ ++ units(gi) returns the list of unit increments for the x and y
+ ++ axes of the indicated graph, \spad{gi}, of the domain
+ ++ \spadtype{GraphImage}.
+ units : ($,UNITF) -> UNITF
+ ++ units(gi,lu) modifies the list of unit increments for the x and y
+ ++ axes of the given graph, \spad{gi} of the domain
+ ++ \spadtype{GraphImage}, to be that of the list of unit increments,
+ ++ \spad{lu}, and returns the new list of units for \spad{gi}.
+ component : ($,L P,PAL,PAL,PI) -> Void
+ ++ component(gi,lp,pal1,pal2,p) sets the components of the
+ ++ graph, \spad{gi} of the domain \spadtype{GraphImage}, to the
+ ++ values given. The point list for \spad{gi} is set to the list
+ ++ \spad{lp}, the color of the points in \spad{lp} is set to
+ ++ the palette color \spad{pal1}, the color of the lines which
+ ++ connect the points \spad{lp} is set to the palette color
+ ++ \spad{pal2}, and the size of the points in \spad{lp} is given
+ ++ by the integer p.
+ component : ($,P) -> Void
+ ++ component(gi,pt) modifies the graph \spad{gi} of the domain
+ ++ \spadtype{GraphImage} to contain one point component, \spad{pt}
+ ++ whose point color, line color and point size are determined by
+ ++ the default functions \spadfun{pointColorDefault},
+ ++ \spadfun{lineColorDefault}, and \spadfun{pointSizeDefault}.
+ component : ($,P,PAL,PAL,PI) -> Void
+ ++ component(gi,pt,pal1,pal2,ps) modifies the graph \spad{gi} of
+ ++ the domain \spadtype{GraphImage} to contain one point component,
+ ++ \spad{pt} whose point color is set to the palette color \spad{pal1},
+ ++ line color is set to the palette color \spad{pal2}, and point
+ ++ size is set to the positive integer \spad{ps}.
+ appendPoint : ($,P) -> Void
+ ++ appendPoint(gi,pt) appends the point \spad{pt} to the end
+ ++ of the list of points component for the graph, \spad{gi}, which is
+ ++ of the domain \spadtype{GraphImage}.
+ point : ($,P,PAL) -> Void
+ ++ point(gi,pt,pal) modifies the graph \spad{gi} of the domain
+ ++ \spadtype{GraphImage} to contain one point component, \spad{pt}
+ ++ whose point color is set to be the palette color \spad{pal}, and
+ ++ whose line color and point size are determined by the default
+ ++ functions \spadfun{lineColorDefault} and \spadfun{pointSizeDefault}.
+ coerce : L L P -> $
+ ++ coerce(llp)
+ ++ component(gi,pt) creates and returns a graph of the domain
+ ++ \spadtype{GraphImage} which is composed of the list of list
+ ++ of points given by \spad{llp}, and whose point colors, line colors
+ ++ and point sizes are determined by the default functions
+ ++ \spadfun{pointColorDefault}, \spadfun{lineColorDefault}, and
+ ++ \spadfun{pointSizeDefault}. The graph data is then sent to the
+ ++ viewport manager where it waits to be included in a two-dimensional
+ ++ viewport window.
+ coerce : $ -> E
+ ++ coerce(gi) returns the indicated graph, \spad{gi}, of domain
+ ++ \spadtype{GraphImage} as output of the domain \spadtype{OutputForm}.
+ putColorInfo : (L L P,L PAL) -> L L P
+ ++ putColorInfo(llp,lpal) takes a list of list of points, \spad{llp},
+ ++ and returns the points with their hue and shade components
+ ++ set according to the list of palette colors, \spad{lpal}.
+ figureUnits : L L P -> UNITSF
+
+ Implementation ==> add
+ import Color()
+ import Palette()
+ import ViewDefaultsPackage()
+ import PlotTools()
+ import DrawOptionFunctions0
+ import P
+ import PP
+ import COORDSYS
+
+ Rep := Record(key: I, rangesField: RANGESF, unitsField: UNITSF, _
+ llPoints: L L P, pointColors: L PAL, lineColors: L PAL, pointSizes: L PI, _
+ optionsField: L DROP)
+
+--%Internal Functions
+
+ graph : RANGEF -> $
+ scaleStep : SF -> SF
+ makeGraph : $ -> $
+
+
+ numberCheck(nums:Point SF):Void ==
+ for i in minIndex(nums)..maxIndex(nums) repeat
+ COMPLEXP(nums.(i::PositiveInteger))$Lisp =>
+ error "An unexpected complex number was encountered in the calculations."
+
+
+ doOptions(g:Rep):Void ==
+ lr : RANGEF := ranges(g.optionsField,ranges g)
+ if (#lr > 1$I) then
+ g.rangesField := [segment(convert(lo(lr.1))@SF,convert(hi(lr.1))@SF)$(Segment(SF)),
+ segment(convert(lo(lr.2))@SF,convert(hi(lr.2))@SF)$(Segment(SF))]
+ else
+ g.rangesField := []
+ lu : UNITF := units(g.optionsField,units g)
+ if (#lu > 1$I) then
+ g.unitsField := [convert(lu.1)@SF,convert(lu.2)@SF]
+ else
+ g.unitsField := []
+ -- etc - graphimage specific stuff...
+
+ putColorInfo(llp,listOfPalettes) ==
+ llp2 : L L P := []
+ for lp in llp for pal in listOfPalettes repeat
+ lp2 : L P := []
+ daHue := (hue(hue pal))::SF
+ daShade := (shade pal)::SF
+ for p in lp repeat
+ if (d := dimension p) < 3 then
+ p := extend(p,[daHue,daShade])
+ else
+ p.3 := daHue
+ d < 4 => p := extend(p,[daShade])
+ p.4 := daShade
+ lp2 := cons(p,lp2)
+ llp2 := cons(reverse_! lp2,llp2)
+ reverse_! llp2
+
+ graph demRanges ==
+ null demRanges => [ 0, [], [], [], [], [], [], [] ]
+ demRangesSF : RANGESF := _
+ [ segment(convert(lo demRanges.1)@SF,convert(hi demRanges.1)@SF)$(Segment(SF)), _
+ segment(convert(lo demRanges.1)@SF,convert(hi demRanges.1)@SF)$(Segment(SF)) ]
+ [ 0, demRangesSF, [], [], [], [], [], [] ]
+
+ scaleStep(range) == -- MGR
+
+ adjust:NNI
+ tryStep:SF
+ scaleDown:SF
+ numerals:String
+ adjust := 0
+ while range < 100.0::SF repeat
+ adjust := adjust + 1
+ range := range * 10.0::SF -- might as well take big steps
+ tryStep := range/10.0::SF
+ numerals := string(((retract(ceiling(tryStep)$SF)$SF)@I))$String
+ scaleDown := (10@I **$I (((#(numerals)@I) - 1$I) pretend PI))::SF
+ scaleDown*ceiling(tryStep/scaleDown - 0.5::SF)/((10 **$I adjust)::SF)
+
+ figureUnits(listOfListsOfPoints) ==
+ -- figure out the min/max and divide by 10 for unit markers
+ xMin := xMax := xCoord first first listOfListsOfPoints
+ yMin := yMax := yCoord first first listOfListsOfPoints
+ if xMin ~= xMin then xMin:=max()
+ if xMax ~= xMax then xMax:=min()
+ if yMin ~= yMin then yMin:=max()
+ if yMax ~= yMax then yMax:=min()
+ for pL in listOfListsOfPoints repeat
+ for p in pL repeat
+ if ((px := (xCoord p)) < xMin) then
+ xMin := px
+ if px > xMax then
+ xMax := px
+ if ((py := (yCoord p)) < yMin) then
+ yMin := py
+ if py > yMax then
+ yMax := py
+ if xMin = xMax then
+ xMin := xMin - convert(0.5)$Float
+ xMax := xMax + convert(0.5)$Float
+ if yMin = yMax then
+ yMin := yMin - convert(0.5)$Float
+ yMax := yMax + convert(0.5)$Float
+ [scaleStep(xMax-xMin),scaleStep(yMax-yMin)]
+
+ plotLists(graf:Rep,listOfListsOfPoints:L L P,listOfPointColors:L PAL,listOfLineColors:L PAL,listOfPointSizes:L PI):$ ==
+ givenLen := #listOfListsOfPoints
+ -- take out point lists that are actually empty
+ listOfListsOfPoints := [ l for l in listOfListsOfPoints | ^null l ]
+ if (null listOfListsOfPoints) then
+ error "GraphImage was given a list that contained no valid point lists"
+ if ((len := #listOfListsOfPoints) ^= givenLen) then
+ sayBrightly([" Warning: Ignoring pointless point list"::E]$List(E))$Lisp
+ graf.llPoints := listOfListsOfPoints
+ -- do point colors
+ if ((givenLen := #listOfPointColors) > len) then
+ -- pad or discard elements if given list has length different from the point list
+ graf.pointColors := concat(listOfPointColors,
+ new((len - givenLen)::NonNegativeInteger + 1, pointColorDefault()))
+ else graf.pointColors := first(listOfPointColors, len)
+ -- do line colors
+ if ((givenLen := #listOfLineColors) > len) then
+ graf.lineColors := concat(listOfLineColors,
+ new((len - givenLen)::NonNegativeInteger + 1, lineColorDefault()))
+ else graf.lineColors := first(listOfLineColors, len)
+ -- do point sizes
+ if ((givenLen := #listOfPointSizes) > len) then
+ graf.pointSizes := concat(listOfPointSizes,
+ new((len - givenLen)::NonNegativeInteger + 1, pointSizeDefault()))
+ else graf.pointSizes := first(listOfPointSizes, len)
+ graf
+
+ makeGraph graf ==
+ doOptions(graf)
+ (s := #(graf.llPoints)) = 0 =>
+ error "You are trying to make a graph with no points"
+ key graf ^= 0 =>
+ error "You are trying to draw over an existing graph"
+ transform := coord(graf.optionsField,cartesian$COORDSYS)$DrawOptionFunctions0
+ graf.llPoints:= putColorInfo(graf.llPoints,graf.pointColors)
+ if null(ranges graf) then -- figure out best ranges for points
+ graf.rangesField := calcRanges(graf.llPoints) --::V SEG SF
+ if null(units graf) then -- figure out best ranges for points
+ graf.unitsField := figureUnits(graf.llPoints) --::V SEG SF
+ sayBrightly([" Graph data being transmitted to the viewport manager..."::E]$List(E))$Lisp
+ sendI(VIEW,typeGRAPH)$Lisp
+ sendI(VIEW,makeGRAPH)$Lisp
+ tonto := (graf.rangesField)::RANGESF
+ sendSF(VIEW,lo(first tonto))$Lisp
+ sendSF(VIEW,hi(first tonto))$Lisp
+ sendSF(VIEW,lo(second tonto))$Lisp
+ sendSF(VIEW,hi(second tonto))$Lisp
+ sendSF(VIEW,first (graf.unitsField))$Lisp
+ sendSF(VIEW,second (graf.unitsField))$Lisp
+ sendI(VIEW,s)$Lisp -- how many lists of points are being sent
+ for aList in graf.llPoints for pColor in graf.pointColors for lColor in graf.lineColors for s in graf.pointSizes repeat
+ sendI(VIEW,#aList)$Lisp -- how many points in this list
+ for p in aList repeat
+ aPoint := transform p
+ sendSF(VIEW,xCoord aPoint)$Lisp
+ sendSF(VIEW,yCoord aPoint)$Lisp
+ sendSF(VIEW,hue(p)$PP)$Lisp -- ?use aPoint as well...?
+ sendSF(VIEW,shade(p)$PP)$Lisp
+ hueShade := hue hue pColor + shade pColor * numberOfHues()
+ sendI(VIEW,hueShade)$Lisp
+ hueShade := (hue hue lColor -1)*5 + shade lColor
+ sendI(VIEW,hueShade)$Lisp
+ sendI(VIEW,s)$Lisp
+ graf.key := getI(VIEW)$Lisp
+ graf
+
+
+--%Exported Functions
+ makeGraphImage(graf:$) == makeGraph graf
+ key graf == graf.key
+ pointLists graf == graf.llPoints
+ ranges graf ==
+ null graf.rangesField => []
+ [segment(convert(lo graf.rangesField.1)@F,convert(hi graf.rangesField.1)@F), _
+ segment(convert(lo graf.rangesField.2)@F,convert(hi graf.rangesField.2)@F)]
+ ranges(graf,rangesList) ==
+ graf.rangesField :=
+ [segment(convert(lo rangesList.1)@SF,convert(hi rangesList.1)@SF), _
+ segment(convert(lo rangesList.2)@SF,convert(hi rangesList.2)@SF)]
+ rangesList
+ units graf ==
+ null(graf.unitsField) => []
+ [convert(graf.unitsField.1)@F,convert(graf.unitsField.2)@F]
+ units (graf,unitsToBe) ==
+ graf.unitsField := [convert(unitsToBe.1)@SF,convert(unitsToBe.2)@SF]
+ unitsToBe
+ graphImage == graph []
+
+ makeGraphImage(llp) ==
+ makeGraphImage(llp,
+ [pointColorDefault() for i in 1..(l:=#llp)],
+ [lineColorDefault() for i in 1..l],
+ [pointSizeDefault() for i in 1..l])
+
+ makeGraphImage(llp,lpc,llc,lps) ==
+ makeGraphImage(llp,lpc,llc,lps,[])
+
+ makeGraphImage(llp,lpc,llc,lps,opts) ==
+ graf := graph(ranges(opts,[]))
+ graf.optionsField := opts
+ graf := plotLists(graf,llp,lpc,llc,lps)
+ transform := coord(graf.optionsField,cartesian$COORDSYS)$DrawOptionFunctions0
+ for aList in graf.llPoints repeat
+ for p in aList repeat
+ aPoint := transform p
+ numberCheck aPoint
+ makeGraph graf
+
+ component (graf:$,ListOfPoints:L P,PointColor:PAL,LineColor:PAL,PointSize:PI) ==
+ graf.llPoints := append(graf.llPoints,[ListOfPoints])
+ graf.pointColors := append(graf.pointColors,[PointColor])
+ graf.lineColors := append(graf.lineColors,[LineColor])
+ graf.pointSizes := append(graf.pointSizes,[PointSize])
+
+ component (graf,aPoint) ==
+ component(graf,aPoint,pointColorDefault(),lineColorDefault(),pointSizeDefault())
+
+ component (graf:$,aPoint:P,PointColor:PAL,LineColor:PAL,PointSize:PI) ==
+ component (graf,[aPoint],PointColor,LineColor,PointSize)
+
+ appendPoint (graf,aPoint) ==
+ num : I := #(graf.llPoints) - 1
+ num < 0 => error "No point lists to append to!"
+ (graf.llPoints.num) := append((graf.llPoints.num),[aPoint])
+
+ point (graf,aPoint,PointColor) ==
+ component(graf,aPoint,PointColor,lineColorDefault(),pointSizeDefault())
+
+ coerce (llp : L L P) : $ ==
+ makeGraphImage(llp,
+ [pointColorDefault() for i in 1..(l:=#llp)],
+ [lineColorDefault() for i in 1..l],
+ [pointSizeDefault() for i in 1..l])
+
+ coerce (graf : $) : E ==
+ hconcat( ["Graph with " :: E,(p := # pointLists graf) :: E,
+ (p=1 => " point list"; " point lists") :: E])
+
+@
+\section{domain VIEW2D TwoDimensionalViewport}
+\subsection{Creating multiple graphs in a Viewport}
+We want to graph $x^3 * (a+b*x)$ on the interval $x=-1\ldots1$
+so we clear out the workspace
+<<multigraph.input>>=
+)clear all
+@
+We assign values to the constants
+<<multigraph.input>>=
+a:=0.5
+b:=0.5
+@
+We draw the first case of the graph
+<<multigraph.input>>=
+y1:=draw(x^3*(a+b*x),x=-1..1,title=="2.2.10 explicit")
+@
+We fetch the graph of the first object
+<<multigraph.input>>=
+g1:=getGraph(y1,1)
+@
+We extract its points
+<<multigraph.input>>=
+pointLists g1
+@
+
+Now we create a second graph with a changed parameter
+<<multigraph.input>>=
+b:=1.0
+@
+We draw it
+<<multigraph.input>>=
+y2:=draw(x^3*(a+b*x),x=-1..1)
+@
+We fetch this new graph
+<<multigraph.input>>=
+g2:=getGraph(y2,1)
+@
+We get the points from this graph
+<<multigraph.input>>=
+pointLists g2
+@
+and we put these points, $g2$ onto the first graph $y1$ as graph $2$
+<<multigraph.input>>=
+putGraph(y1,g2,2)
+@
+And now we do the whole sequence again
+<<multigraph.input>>=
+b:=2.0
+y3:=draw(x^3*(a+b*x),x=-1..1)
+g3:=getGraph(y3,1)
+pointLists g3
+@
+and put the third graphs points $g3$ onto the first graph $y1$ as graph $3$
+<<multigraph.input>>=
+putGraph(y1,g3,3)
+@
+Finally we show the combined result
+<<multigraph.input>>=
+vp:=makeViewport2D(y1)
+@
+<<domain VIEW2D TwoDimensionalViewport>>=
+)abbrev domain VIEW2D TwoDimensionalViewport
+++ Author: Jim Wen
+++ Date Created: 28 April 1989
+++ Date Last Updated: 29 October 1991, Jon Steinbach
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: TwoDimensionalViewport creates viewports to display graphs.
+TwoDimensionalViewport ():Exports == Implementation where
+
+ VIEW ==> VIEWPORTSERVER$Lisp
+ sendI ==> SOCK_-SEND_-INT
+ sendSF ==> SOCK_-SEND_-FLOAT
+ sendSTR ==> SOCK_-SEND_-STRING
+ getI ==> SOCK_-GET_-INT
+ getSF ==> SOCK_-GET_-FLOAT
+
+ typeGRAPH ==> 2
+ typeVIEW2D ==> 3
+
+ makeGRAPH ==> (-1)$SingleInteger
+ makeVIEW2D ==> (-1)$SingleInteger
+
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ XY ==> Record( X:I, Y:I )
+ XYP ==> Record( X:PI, Y:PI )
+ XYNN ==> Record( X:NNI, Y:NNI )
+ F ==> Float
+ SF ==> DoubleFloat
+ STR ==> String
+ L ==> List
+ V ==> Vector
+ E ==> OutputForm
+ FLAG ==> Record( showCP:I )
+ PAL ==> Palette()
+ B ==> Boolean
+ G ==> GraphImage
+ GS ==> Record( scaleX:SF, scaleY:SF, deltaX:SF, deltaY:SF, _
+ points:I, connect:I, spline:I, _
+ axes:I, axesColor:PAL, units:I, unitsColor:PAL, _
+ showing:I)
+ GU ==> Union(G,"undefined")
+ DROP ==> DrawOption
+ POINT ==> Point(SF)
+
+ TRANSLATE2D ==> 0$I
+ SCALE2D ==> 1$I
+ pointsOnOff ==> 2
+ connectOnOff ==> 3
+ spline2D ==> 4 -- used for controlling regions, now
+ reset2D ==> 5
+ hideControl2D ==> 6
+ closeAll2D ==> 7
+ axesOnOff2D ==> 8
+ unitsOnOff2D ==> 9
+
+ SPADBUTTONPRESS ==> 100
+ MOVE ==> 102
+ RESIZE ==> 103
+ TITLE ==> 104
+ showing2D ==> 105 -- as defined in include/actions.h
+ putGraph2D ==> 106
+ writeView ==> 110
+ axesColor2D ==> 112
+ unitsColor2D ==> 113
+ getPickedPTS ==> 119
+
+ graphStart ==> 13 -- as defined in include/actions.h
+
+ noControl ==> 0$I
+
+ yes ==> 1$I
+ no ==> 0$I
+
+ maxGRAPHS ==> 9::I -- should be the same as maxGraphs in include/view2D.h
+
+ fileTypeDefs ==> ["PIXMAP"] -- see include/write.h for things to include
+
+ Exports ==> SetCategory with
+ getPickedPoints : $ -> L POINT
+ ++ getPickedPoints(x)
+ ++ returns a list of small floats for the points the
+ ++ user interactively picked on the viewport
+ ++ for full integration into the system, some design
+ ++ issues need to be addressed: e.g. how to go through
+ ++ the GraphImage interface, how to default to graphs, etc.
+ viewport2D : () -> $
+ ++ viewport2D() returns an undefined two-dimensional viewport
+ ++ of the domain \spadtype{TwoDimensionalViewport} whose
+ ++ contents are empty.
+ makeViewport2D : $ -> $
+ ++ makeViewport2D(v) takes the given two-dimensional viewport,
+ ++ v, of the domain \spadtype{TwoDimensionalViewport} and
+ ++ displays a viewport window on the screen which contains
+ ++ the contents of v.
+ options : $ -> L DROP
+ ++ options(v) takes the given two-dimensional viewport, v, of the
+ ++ domain \spadtype{TwoDimensionalViewport} and returns a list
+ ++ containing the draw options from the domain \spadtype{DrawOption}
+ ++ for v.
+ options : ($,L DROP) -> $
+ ++ options(v,lopt) takes the given two-dimensional viewport, v,
+ ++ of the domain \spadtype{TwoDimensionalViewport} and returns
+ ++ v with it's draw options modified to be those which are indicated
+ ++ in the given list, \spad{lopt} of domain \spadtype{DrawOption}.
+ makeViewport2D : (G,L DROP) -> $
+ ++ makeViewport2D(gi,lopt) creates and displays a viewport window
+ ++ of the domain \spadtype{TwoDimensionalViewport} whose graph
+ ++ field is assigned to be the given graph, \spad{gi}, of domain
+ ++ \spadtype{GraphImage}, and whose options field is set to be
+ ++ the list of options, \spad{lopt} of domain \spadtype{DrawOption}.
+ graphState : ($,PI,SF,SF,SF,SF,I,I,I,I,PAL,I,PAL,I) -> Void
+ ++ graphState(v,num,sX,sY,dX,dY,pts,lns,box,axes,axesC,un,unC,cP)
+ ++ sets the state of the characteristics for the graph indicated
+ ++ by \spad{num} in the given two-dimensional viewport v, of domain
+ ++ \spadtype{TwoDimensionalViewport}, to the values given as
+ ++ parameters. The scaling of the graph in the x and y component
+ ++ directions is set to be \spad{sX} and \spad{sY}; the window
+ ++ translation in the x and y component directions is set to be
+ ++ \spad{dX} and \spad{dY}; The graph points, lines, bounding box,
+ ++ axes, or units will be shown in the viewport if their given
+ ++ parameters \spad{pts}, \spad{lns}, \spad{box}, \spad{axes} or
+ ++ \spad{un} are set to be \spad{1}, but will not be shown if they
+ ++ are set to \spad{0}. The color of the axes and the color of the
+ ++ units are indicated by the palette colors \spad{axesC} and
+ ++ \spad{unC} respectively. To display the control panel when
+ ++ the viewport window is displayed, set \spad{cP} to \spad{1},
+ ++ otherwise set it to \spad{0}.
+ graphStates : $ -> V GS
+ ++ graphStates(v) returns and shows a listing of a record containing
+ ++ the current state of the characteristics of each of the ten graph
+ ++ records in the given two-dimensional viewport, v, which is of
+ ++ domain \spadtype{TwoDimensionalViewport}.
+ graphs : $ -> V GU
+ ++ graphs(v) returns a vector, or list, which is a union of all
+ ++ the graphs, of the domain \spadtype{GraphImage}, which are
+ ++ allocated for the two-dimensional viewport, v, of domain
+ ++ \spadtype{TwoDimensionalViewport}. Those graphs which have
+ ++ no data are labeled "undefined", otherwise their contents
+ ++ are shown.
+ title : ($,STR) -> Void
+ ++ title(v,s) changes the title which is shown in the two-dimensional
+ ++ viewport window, v of domain \spadtype{TwoDimensionalViewport}.
+ putGraph : ($,G,PI) -> Void
+ ++ putGraph(v,gi,n) sets the graph field indicated by n, of the
+ ++ indicated two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, to be the graph, \spad{gi}
+ ++ of domain \spadtype{GraphImage}. The contents of viewport, v,
+ ++ will contain \spad{gi} when the function \spadfun{makeViewport2D}
+ ++ is called to create the an updated viewport v.
+ getGraph : ($,PI) -> G
+ ++ getGraph(v,n) returns the graph which is of the domain
+ ++ \spadtype{GraphImage} which is located in graph field n
+ ++ of the given two-dimensional viewport, v, which is of the
+ ++ domain \spadtype{TwoDimensionalViewport}.
+ axes : ($,PI,STR) -> Void
+ ++ axes(v,n,s) displays the axes of the graph in field n of
+ ++ the given two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does
+ ++ not display the axes if s is "off".
+ axes : ($,PI,PAL) -> Void
+ ++ axes(v,n,c) displays the axes of the graph in field n of
+ ++ the given two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, with the axes color set to
+ ++ the given palette color c.
+ units : ($,PI,STR) -> Void
+ ++ units(v,n,s) displays the units of the graph in field n of
+ ++ the given two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does
+ ++ not display the units if s is "off".
+ units : ($,PI,PAL) -> Void
+ ++ units(v,n,c) displays the units of the graph in field n of
+ ++ the given two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, with the units color set to
+ ++ the given palette color c.
+ points : ($,PI,STR) -> Void
+ ++ points(v,n,s) displays the points of the graph in field n of
+ ++ the given two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does
+ ++ not display the points if s is "off".
+ region : ($,PI,STR) -> Void
+ ++ region(v,n,s) displays the bounding box of the graph in
+ ++ field n of the given two-dimensional viewport, v, which is
+ ++ of domain \spadtype{TwoDimensionalViewport}, if s is "on",
+ ++ or does not display the bounding box if s is "off".
+ connect : ($,PI,STR) -> Void
+ ++ connect(v,n,s) displays the lines connecting the graph
+ ++ points in field n of the given two-dimensional viewport, v,
+ ++ which is of domain \spadtype{TwoDimensionalViewport}, if s
+ ++ is "on", or does not display the lines if s is "off".
+ controlPanel : ($,STR) -> Void
+ ++ controlPanel(v,s) displays the control panel of the given
+ ++ two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, if s is "on", or hides
+ ++ the control panel if s is "off".
+ close : $ -> Void
+ ++ close(v) closes the viewport window of the given
+ ++ two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, and terminates the
+ ++ corresponding process ID.
+ dimensions : ($,NNI,NNI,PI,PI) -> Void
+ ++ dimensions(v,x,y,width,height) sets the position of the
+ ++ upper left-hand corner of the two-dimensional viewport, v,
+ ++ which is of domain \spadtype{TwoDimensionalViewport}, to
+ ++ the window coordinate x, y, and sets the dimensions of the
+ ++ window to that of \spad{width}, \spad{height}. The new
+ ++ dimensions are not displayed until the function
+ ++ \spadfun{makeViewport2D} is executed again for v.
+ scale : ($,PI,F,F) -> Void
+ ++ scale(v,n,sx,sy) displays the graph in field n of the given
+ ++ two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, scaled by the factor \spad{sx}
+ ++ in the x-coordinate direction and by the factor \spad{sy} in
+ ++ the y-coordinate direction.
+ translate : ($,PI,F,F) -> Void
+ ++ translate(v,n,dx,dy) displays the graph in field n of the given
+ ++ two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, translated by \spad{dx} in
+ ++ the x-coordinate direction from the center of the viewport, and
+ ++ by \spad{dy} in the y-coordinate direction from the center.
+ ++ Setting \spad{dx} and \spad{dy} to \spad{0} places the center
+ ++ of the graph at the center of the viewport.
+ show : ($,PI,STR) -> Void
+ ++ show(v,n,s) displays the graph in field n of the given
+ ++ two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, if s is "on", or does not
+ ++ display the graph if s is "off".
+ move : ($,NNI,NNI) -> Void
+ ++ move(v,x,y) displays the two-dimensional viewport, v, which
+ ++ is of domain \spadtype{TwoDimensionalViewport}, with the upper
+ ++ left-hand corner of the viewport window at the screen
+ ++ coordinate position x, y.
+ update :($,G,PI) -> Void
+ ++ update(v,gr,n) drops the graph \spad{gr} in slot \spad{n}
+ ++ of viewport \spad{v}. The graph gr must have been
+ ++ transmitted already and acquired an integer key.
+ resize : ($,PI,PI) -> Void
+ ++ resize(v,w,h) displays the two-dimensional viewport, v, which
+ ++ is of domain \spadtype{TwoDimensionalViewport}, with a width
+ ++ of w and a height of h, keeping the upper left-hand corner
+ ++ position unchanged.
+ write : ($,STR) -> STR
+ ++ write(v,s) takes the given two-dimensional viewport, v, which
+ ++ is of domain \spadtype{TwoDimensionalViewport}, and creates
+ ++ a directory indicated by s, which contains the graph data
+ ++ files for v.
+ write : ($,STR,STR) -> STR
+ ++ write(v,s,f) takes the given two-dimensional viewport, v, which
+ ++ is of domain \spadtype{TwoDimensionalViewport}, and creates
+ ++ a directory indicated by s, which contains the graph data
+ ++ files for v and an optional file type f.
+ write : ($,STR,L STR) -> STR
+ ++ write(v,s,lf) takes the given two-dimensional viewport, v, which
+ ++ is of domain \spadtype{TwoDimensionalViewport}, and creates
+ ++ a directory indicated by s, which contains the graph data
+ ++ files for v and the optional file types indicated by the list lf.
+ reset : $ -> Void
+ ++ reset(v) sets the current state of the graph characteristics
+ ++ of the given two-dimensional viewport, v, which is of domain
+ ++ \spadtype{TwoDimensionalViewport}, back to their initial settings.
+ key : $ -> I
+ ++ key(v) returns the process ID number of the given two-dimensional
+ ++ viewport, v, which is of domain \spadtype{TwoDimensionalViewport}.
+ coerce : $ -> E
+ ++ coerce(v) returns the given two-dimensional viewport, v, which
+ ++ is of domain \spadtype{TwoDimensionalViewport} as output of
+ ++ the domain \spadtype{OutputForm}.
+
+ Implementation ==> add
+
+ import GraphImage()
+ import Color()
+ import Palette()
+ import ViewDefaultsPackage()
+ import DrawOptionFunctions0
+ import POINT
+
+ Rep := Record (key:I, graphsField:V GU, graphStatesField:V GS, _
+ title:STR, moveTo:XYNN, size:XYP, flags:FLAG, optionsField:L DROP)
+
+ defaultGS : GS := [convert(0.9)@SF, convert(0.9)@SF, 0$SF, 0$SF, _
+ yes, yes, no, _
+ yes, axesColorDefault(), no, unitsColorDefault(), _
+ yes]
+
+
+ --% Local Functions
+ checkViewport (viewport:$):B ==
+ -- checks to see if this viewport still exists
+ -- by sending the key to the viewport manager and
+ -- waiting for its reply after it checks it against
+ -- the viewports in its list. a -1 means it doesn't
+ -- exist.
+ sendI(VIEW,viewport.key)$Lisp
+ i := getI(VIEW)$Lisp
+ (i < 0$I) =>
+ viewport.key := 0$I
+ error "This viewport has already been closed!"
+ true
+
+ doOptions(v:Rep):Void ==
+ v.title := title(v.optionsField,"AXIOM2D")
+ -- etc - 2D specific stuff...
+
+ --% Exported Functions
+
+ options viewport ==
+ viewport.optionsField
+
+ options(viewport,opts) ==
+ viewport.optionsField := opts
+ viewport
+
+ putGraph (viewport,aGraph,which) ==
+ if ((which > maxGRAPHS) or (which < 1)) then
+ error "Trying to put a graph with a negative index or too big an index"
+ viewport.graphsField.which := aGraph
+
+ getGraph (viewport,which) ==
+ if ((which > maxGRAPHS) or (which < 1)) then
+ error "Trying to get a graph with a negative index or too big an index"
+ viewport.graphsField.which case "undefined" =>
+ error "Graph is undefined!"
+ viewport.graphsField.which::GraphImage
+
+
+ graphStates viewport == viewport.graphStatesField
+ graphs viewport == viewport.graphsField
+ key viewport == viewport.key
+
+ dimensions(viewport,ViewX,ViewY,ViewWidth,ViewHeight) ==
+ viewport.moveTo := [ViewX,ViewY]
+ viewport.size := [ViewWidth,ViewHeight]
+
+ move(viewport,xLoc,yLoc) ==
+ viewport.moveTo := [xLoc,yLoc]
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,MOVE)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,xLoc)$Lisp
+ sendI(VIEW,yLoc)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ update(viewport,graph,slot) ==
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,putGraph2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,key graph)$Lisp
+ sendI(VIEW,slot)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ resize(viewport,xSize,ySize) ==
+ viewport.size := [xSize,ySize]
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,RESIZE)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,xSize)$Lisp
+ sendI(VIEW,ySize)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ translate(viewport,graphIndex,xTranslateF,yTranslateF) ==
+ xTranslate := convert(xTranslateF)@SF
+ yTranslate := convert(yTranslateF)@SF
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ viewport.graphStatesField.graphIndex.deltaX := xTranslate
+ viewport.graphStatesField.graphIndex.deltaY := yTranslate
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,TRANSLATE2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendSF(VIEW,xTranslate)$Lisp
+ sendSF(VIEW,yTranslate)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ scale(viewport,graphIndex,xScaleF,yScaleF) ==
+ xScale := convert(xScaleF)@SF
+ yScale := convert(yScaleF)@SF
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ viewport.graphStatesField.graphIndex.scaleX := xScale -- check union (undefined?)
+ viewport.graphStatesField.graphIndex.scaleY := yScale -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,SCALE2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendSF(VIEW,xScale)$Lisp
+ sendSF(VIEW,yScale)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ viewport2D ==
+ [0,new(maxGRAPHS,"undefined"), _
+ new(maxGRAPHS,copy defaultGS),"AXIOM2D", _
+ [viewPosDefault().1,viewPosDefault().2],[viewSizeDefault().1,viewSizeDefault().2], _
+ [noControl], [] ]
+
+ makeViewport2D(g:G,opts:L DROP) ==
+ viewport := viewport2D()
+ viewport.graphsField.1 := g
+ viewport.optionsField := opts
+ makeViewport2D viewport
+
+ makeViewport2D viewportDollar ==
+ viewport := viewportDollar::Rep
+ doOptions viewport --local function to extract and assign optional arguments for 2D viewports
+ sayBrightly([" AXIOM2D data being transmitted to the viewport manager..."::E]$List(E))$Lisp
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,makeVIEW2D)$Lisp
+ sendSTR(VIEW,viewport.title)$Lisp
+ sendI(VIEW,viewport.moveTo.X)$Lisp
+ sendI(VIEW,viewport.moveTo.Y)$Lisp
+ sendI(VIEW,viewport.size.X)$Lisp
+ sendI(VIEW,viewport.size.Y)$Lisp
+ sendI(VIEW,viewport.flags.showCP)$Lisp
+ for i in 1..maxGRAPHS repeat
+ g := (graphs viewport).i
+ if g case "undefined" then
+ sendI(VIEW,0$I)$Lisp
+ else
+ sendI(VIEW,key(g::G))$Lisp
+ gs := (graphStates viewport).i
+ sendSF(VIEW,gs.scaleX)$Lisp
+ sendSF(VIEW,gs.scaleY)$Lisp
+ sendSF(VIEW,gs.deltaX)$Lisp
+ sendSF(VIEW,gs.deltaY)$Lisp
+ sendI(VIEW,gs.points)$Lisp
+ sendI(VIEW,gs.connect)$Lisp
+ sendI(VIEW,gs.spline)$Lisp
+ sendI(VIEW,gs.axes)$Lisp
+ hueShade := hue hue gs.axesColor + shade gs.axesColor * numberOfHues()
+ sendI(VIEW,hueShade)$Lisp
+ sendI(VIEW,gs.units)$Lisp
+ hueShade := hue hue gs.unitsColor + shade gs.unitsColor * numberOfHues()
+ sendI(VIEW,hueShade)$Lisp
+ sendI(VIEW,gs.showing)$Lisp
+ viewport.key := getI(VIEW)$Lisp
+ viewport
+
+ graphState(viewport,num,sX,sY,dX,dY,Points,Lines,Spline, _
+ Axes,AxesColor,Units,UnitsColor,Showing) ==
+ viewport.graphStatesField.num := [sX,sY,dX,dY,Points,Lines,Spline, _
+ Axes,AxesColor,Units,UnitsColor,Showing]
+
+ title(viewport,Title) ==
+ viewport.title := Title
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,TITLE)$Lisp
+ checkViewport viewport =>
+ sendSTR(VIEW,Title)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ reset viewport ==
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,SPADBUTTONPRESS)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,reset2D)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ axes (viewport:$,graphIndex:PI,onOff:STR) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ if onOff = "on" then
+ status := yes
+ else
+ status := no
+ viewport.graphStatesField.graphIndex.axes := status -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,axesOnOff2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendI(VIEW,status)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ axes (viewport:$,graphIndex:PI,color:PAL) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ viewport.graphStatesField.graphIndex.axesColor := color
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,axesColor2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ hueShade := hue hue color + shade color * numberOfHues()
+ sendI(VIEW,hueShade)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ units (viewport:$,graphIndex:PI,onOff:STR) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ if onOff = "on" then
+ status := yes
+ else
+ status := no
+ viewport.graphStatesField.graphIndex.units := status -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,unitsOnOff2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendI(VIEW,status)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ units (viewport:$,graphIndex:PI,color:PAL) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ viewport.graphStatesField.graphIndex.unitsColor := color
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,unitsColor2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ hueShade := hue hue color + shade color * numberOfHues()
+ sendI(VIEW,hueShade)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ connect (viewport:$,graphIndex:PI,onOff:STR) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ if onOff = "on" then
+ status := 1$I
+ else
+ status := 0$I
+ viewport.graphStatesField.graphIndex.connect := status -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,connectOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendI(VIEW,status)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ points (viewport:$,graphIndex:PI,onOff:STR) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ if onOff = "on" then
+ status := 1$I
+ else
+ status := 0$I
+ viewport.graphStatesField.graphIndex.points := status -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,pointsOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendI(VIEW,status)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ region (viewport:$,graphIndex:PI,onOff:STR) : Void ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ if onOff = "on" then
+ status := 1$I
+ else
+ status := 0$I
+ viewport.graphStatesField.graphIndex.spline := status -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,spline2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendI(VIEW,status)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ show (viewport,graphIndex,onOff) ==
+ if (graphIndex > maxGRAPHS) then
+ error "Referring to a graph with too big an index"
+ if onOff = "on" then
+ status := 1$I
+ else
+ status := 0$I
+ viewport.graphStatesField.graphIndex.showing := status -- check union (undefined?)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,showing2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,graphIndex)$Lisp
+ sendI(VIEW,status)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ controlPanel (viewport,onOff) ==
+ if onOff = "on" then viewport.flags.showCP := yes
+ else viewport.flags.showCP := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,hideControl2D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.flags.showCP)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ close viewport ==
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,closeAll2D)$Lisp
+ checkViewport viewport =>
+ getI(VIEW)$Lisp -- acknowledge
+ viewport.key := 0$I
+
+ coerce viewport ==
+ (key(viewport) = 0$I) =>
+ hconcat ["Closed or Undefined TwoDimensionalViewport: "::E,
+ (viewport.title)::E]
+ hconcat ["TwoDimensionalViewport: "::E, (viewport.title)::E]
+
+ write(viewport:$,Filename:STR,aThingToWrite:STR) ==
+ write(viewport,Filename,[aThingToWrite])
+
+ write(viewport,Filename) ==
+ write(viewport,Filename,viewWriteDefault())
+
+ write(viewport:$,Filename:STR,thingsToWrite:L STR) ==
+ stringToSend : STR := ""
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW2D)$Lisp
+ sendI(VIEW,writeView)$Lisp
+ checkViewport viewport =>
+ sendSTR(VIEW,Filename)$Lisp
+ m := minIndex(avail := viewWriteAvailable())
+ for aTypeOfFile in thingsToWrite repeat
+ if (writeTypeInt:= position(upperCase aTypeOfFile,avail)-m) < 0 then
+ sayBrightly([" > "::E,(concat(aTypeOfFile, _
+ " is not a valid file type for writing a 2D viewport"))::E]$List(E))$Lisp
+ else
+ sendI(VIEW,writeTypeInt+(1$I))$Lisp
+ -- stringToSend := concat [stringToSend,"%",aTypeOfFile]
+ -- sendSTR(VIEW,stringToSend)$Lisp
+ sendI(VIEW,0$I)$Lisp -- no more types of things to write
+ getI(VIEW)$Lisp -- acknowledge
+ Filename
+
+@
+\subsection{TEST VIEW2D}
+<<TEST VIEW2D>>=
+<<multigraph.input>>
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain GRIMAGE GraphImage>>
+<<domain VIEW2D TwoDimensionalViewport>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/view3D.spad.pamphlet b/src/algebra/view3D.spad.pamphlet
new file mode 100644
index 00000000..2bcb53a7
--- /dev/null
+++ b/src/algebra/view3D.spad.pamphlet
@@ -0,0 +1,1006 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra view3D.spad}
+\author{James Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain VIEW3D ThreeDimensionalViewport}
+<<domain VIEW3D ThreeDimensionalViewport>>=
+)abbrev domain VIEW3D ThreeDimensionalViewport
+++ Author: Jim Wen
+++ Date Created: 28 April 1989
+++ Date Last Updated: 2 November 1991, Jim Wen
+++ Basic Operations:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: ThreeDimensionalViewport creates viewports to display graphs
+VIEW ==> VIEWPORTSERVER$Lisp
+sendI ==> SOCK_-SEND_-INT
+sendSF ==> SOCK_-SEND_-FLOAT
+sendSTR ==> SOCK_-SEND_-STRING
+getI ==> SOCK_-GET_-INT
+getSF ==> SOCK_-GET_-FLOAT
+
+typeVIEW3D ==> 1$I
+typeVIEWTube ==> 4
+
+makeVIEW3D ==> (-1)$SingleInteger
+
+ThreeDimensionalViewport(): Exports == Implementation where
+ I ==> Integer
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ XY ==> Record( X:I, Y:I )
+ XYP ==> Record( X:PI, Y:PI )
+ XYNN ==> Record( X:NNI, Y:NNI )
+ SF ==> DoubleFloat
+ F ==> Float
+ L ==> List
+ Pt ==> ColoredThreeDimensionalPoint
+ SEG ==> Segment
+ S ==> String
+ E ==> OutputForm
+ PLOT3D ==> Plot3D
+ TUBE ==> TubePlot
+ V ==> Record( theta:SF, phi:SF, scale:SF, scaleX:SF, scaleY:SF, scaleZ:SF, deltaX:SF, deltaY:SF )
+ H ==> Record( hueOffset:I, hueNumber:I)
+ FLAG ==> Record( showCP:I, style:I, axesOn:I, diagonalsOn:I, outlineRenderOn:I, showRegionField:I )
+ FR ==> Record( fn:Fn2, fc: FnU, xmin:SF, xmax:SF, ymin:SF, ymax:SF, xnum:I, ynum:I )
+ FParamR ==> Record( theTube:TUBE )
+ LR ==> Record( lightX:SF, lightY:SF, lightZ:SF, lightTheta:SF, lightPhi:SF , translucence:SF)
+ UFR ==> Union(FR,FParamR,"undefined")
+ PR ==> Record( perspectiveField:I, eyeDistance:SF, hitherPlane:SF)
+ VR ==> Record( clipXMin:SF, clipXMax:SF, clipYMin:SF, clipYMax:SF, clipZMin:SF, clipZMax:SF, clipRegionField:I, clipSurfaceField:I)
+ C ==> Color()
+ B ==> Boolean
+ POINT ==> Point(SF)
+ SUBSPACE ==> SubSpace(3,SF)
+ SPACE3 ==> ThreeSpace(SF)
+ DROP ==> DrawOption
+ COORDSYS ==> CoordinateSystems(SF)
+
+ -- the below macros correspond to the ones in include/actions.h
+ ROTATE ==> 0$I -- rotate in actions.h
+ ZOOM ==> 1$I -- zoom in actions.h
+ TRANSLATE ==> 2 -- translate in actions.h
+ rendered ==> 3 -- render in actions.h
+ hideControl ==> 4
+ closeAll ==> 5
+ axesOnOff ==> 6
+ opaque ==> 7 -- opaqueMesh in action.h
+ contour ==> 24
+ RESET ==> 8
+ wireMesh ==> 9 -- transparent in actions.h
+ region3D ==> 12
+ smooth ==> 22
+ diagOnOff ==> 26
+ outlineOnOff ==> 13
+ zoomx ==> 14
+ zoomy ==> 15
+ zoomz ==> 16
+ perspectiveOnOff ==> 27
+ clipRegionOnOff ==> 66
+ clipSurfaceOnOff ==> 67
+
+ SPADBUTTONPRESS ==> 100
+ COLORDEF ==> 101
+ MOVE ==> 102
+ RESIZE ==> 103
+ TITLE ==> 104
+ lightDef ==> 108
+ translucenceDef ==> 109
+ writeView ==> 110
+ eyeDistanceData ==> 111
+ modifyPOINT ==> 114
+-- printViewport ==> 115
+ hitherPlaneData ==> 116
+ queryVIEWPOINT ==> 117
+ changeVIEWPOINT ==> 118
+
+ noControl ==> 0$I
+
+ yes ==> 1$I
+ no ==> 0$I
+
+ EYED ==> 500::SF -- see draw.h, should be the same(?) as clipOffset
+ HITHER ==> (-250)::SF -- see process.h in view3D/ (not yet passed to viewman)
+
+ openTube ==> 1$I
+ closedTube ==> 0$I
+
+ fun2Var3D ==> " Three Dimensional Viewport: Function of Two Variables"
+ para1Var3D ==> " Three Dimensional Viewport: Parametric Curve of One Variable"
+ undef3D ==> " Three Dimensional Viewport: No function defined for this viewport yet"
+
+ Exports ==> SetCategory with
+ viewThetaDefault : () -> F
+ ++ viewThetaDefault() returns the current default longitudinal
+ ++ view angle in radians.
+ viewThetaDefault : F -> F
+ ++ viewThetaDefault(t) sets the current default longitudinal
+ ++ view angle in radians to the value t and returns t.
+ viewPhiDefault : () -> F
+ ++ viewPhiDefault() returns the current default latitudinal
+ ++ view angle in radians.
+ viewPhiDefault : F -> F
+ ++ viewPhiDefault(p) sets the current default latitudinal
+ ++ view angle in radians to the value p and returns p.
+ viewZoomDefault : () -> F
+ ++ viewZoomDefault() returns the current default graph scaling
+ ++ value.
+ viewZoomDefault : F -> F
+ ++ viewZoomDefault(s) sets the current default graph scaling
+ ++ value to s and returns s.
+ viewDeltaXDefault : () -> F
+ ++ viewDeltaXDefault() returns the current default horizontal
+ ++ offset from the center of the viewport window.
+ viewDeltaXDefault : F -> F
+ ++ viewDeltaXDefault(dx) sets the current default horizontal
+ ++ offset from the center of the viewport window to be \spad{dx}
+ ++ and returns \spad{dx}.
+ viewDeltaYDefault : () -> F
+ ++ viewDeltaYDefault() returns the current default vertical
+ ++ offset from the center of the viewport window.
+ viewDeltaYDefault : F -> F
+ ++ viewDeltaYDefault(dy) sets the current default vertical
+ ++ offset from the center of the viewport window to be \spad{dy}
+ ++ and returns \spad{dy}.
+ viewport3D : () -> %
+ ++ viewport3D() returns an undefined three-dimensional viewport
+ ++ of the domain \spadtype{ThreeDimensionalViewport} whose
+ ++ contents are empty.
+ makeViewport3D : % -> %
+ ++ makeViewport3D(v) takes the given three-dimensional viewport,
+ ++ v, of the domain \spadtype{ThreeDimensionalViewport} and
+ ++ displays a viewport window on the screen which contains
+ ++ the contents of v.
+ makeViewport3D : (SPACE3,S) -> %
+ ++ makeViewport3D(sp,s) takes the given space, \spad{sp} which is
+ ++ of the domain \spadtype{ThreeSpace} and displays a viewport
+ ++ window on the screen which contains the contents of \spad{sp},
+ ++ and whose title is given by s.
+ makeViewport3D : (SPACE3,L DROP) -> %
+ ++ makeViewport3D(sp,lopt) takes the given space, \spad{sp} which is
+ ++ of the domain \spadtype{ThreeSpace} and displays a viewport
+ ++ window on the screen which contains the contents of \spad{sp},
+ ++ and whose draw options are indicated by the list \spad{lopt}, which
+ ++ is a list of options from the domain \spad{DrawOption}.
+ subspace : % -> SPACE3
+ ++ subspace(v) returns the contents of the viewport v, which is
+ ++ of the domain \spadtype{ThreeDimensionalViewport}, as a subspace
+ ++ of the domain \spad{ThreeSpace}.
+ subspace : (%,SPACE3) -> %
+ ++ subspace(v,sp) places the contents of the viewport v, which is
+ ++ of the domain \spadtype{ThreeDimensionalViewport}, in the subspace
+ ++ \spad{sp}, which is of the domain \spad{ThreeSpace}.
+ modifyPointData : (%,NNI,POINT) -> Void
+ ++ modifyPointData(v,ind,pt) takes the viewport, v, which is of the
+ ++ domain \spadtype{ThreeDimensionalViewport}, and places the data
+ ++ point, \spad{pt} into the list of points database of v at the index
+ ++ location given by \spad{ind}.
+ options : % -> L DROP
+ ++ options(v) takes the viewport, v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport} and returns a list of all
+ ++ the draw options from the domain \spad{DrawOption} which are
+ ++ being used by v.
+ options : (%,L DROP) -> %
+ ++ options(v,lopt) takes the viewport, v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport} and sets the draw options
+ ++ being used by v to those indicated in the list, \spad{lopt},
+ ++ which is a list of options from the domain \spad{DrawOption}.
+ move : (%,NNI,NNI) -> Void
+ ++ move(v,x,y) displays the three-dimensional viewport, v, which
+ ++ is of domain \spadtype{ThreeDimensionalViewport}, with the upper
+ ++ left-hand corner of the viewport window at the screen
+ ++ coordinate position x, y.
+ resize : (%,PI,PI) -> Void
+ ++ resize(v,w,h) displays the three-dimensional viewport, v, which
+ ++ is of domain \spadtype{ThreeDimensionalViewport}, with a width
+ ++ of w and a height of h, keeping the upper left-hand corner
+ ++ position unchanged.
+ title : (%,S) -> Void
+ ++ title(v,s) changes the title which is shown in the three-dimensional
+ ++ viewport window, v of domain \spadtype{ThreeDimensionalViewport}.
+ dimensions : (%,NNI,NNI,PI,PI) -> Void
+ ++ dimensions(v,x,y,width,height) sets the position of the
+ ++ upper left-hand corner of the three-dimensional viewport, v,
+ ++ which is of domain \spadtype{ThreeDimensionalViewport}, to
+ ++ the window coordinate x, y, and sets the dimensions of the
+ ++ window to that of \spad{width}, \spad{height}. The new
+ ++ dimensions are not displayed until the function
+ ++ \spadfun{makeViewport3D} is executed again for v.
+ viewpoint : (%,F,F,F,F,F) -> Void
+ ++ viewpoint(v,th,phi,s,dx,dy) sets the longitudinal view angle
+ ++ to \spad{th} radians, the latitudinal view angle to \spad{phi}
+ ++ radians, the scale factor to \spad{s}, the horizontal viewport
+ ++ offset to \spad{dx}, and the vertical viewport offset to \spad{dy}
+ ++ for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}. The new viewpoint position
+ ++ is not displayed until the function \spadfun{makeViewport3D} is
+ ++ executed again for v.
+ viewpoint : (%) -> V
+ ++ viewpoint(v) returns the current viewpoint setting of the given
+ ++ viewport, v. This function is useful in the situation where the
+ ++ user has created a viewport, proceeded to interact with it via
+ ++ the control panel and desires to save the values of the viewpoint
+ ++ as the default settings for another viewport to be created using
+ ++ the system.
+ viewpoint : (%,V) -> Void
+ ++ viewpoint(v,viewpt) sets the viewpoint for the viewport. The
+ ++ viewport record consists of the latitudal and longitudal angles,
+ ++ the zoom factor, the X, Y, and Z scales, and the X and Y displacements.
+ viewpoint : (%,I,I,F,F,F) -> Void
+ ++ viewpoint(v,th,phi,s,dx,dy) sets the longitudinal view angle
+ ++ to \spad{th} degrees, the latitudinal view angle to \spad{phi}
+ ++ degrees, the scale factor to \spad{s}, the horizontal viewport
+ ++ offset to \spad{dx}, and the vertical viewport offset to \spad{dy}
+ ++ for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}. The new viewpoint position
+ ++ is not displayed until the function \spadfun{makeViewport3D} is
+ ++ executed again for v.
+ viewpoint : (%,F,F) -> Void
+ ++ viewpoint(v,th,phi) sets the longitudinal view angle to \spad{th}
+ ++ radians and the latitudinal view angle to \spad{phi} radians
+ ++ for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}. The new viewpoint position
+ ++ is not displayed until the function \spadfun{makeViewport3D} is
+ ++ executed again for v.
+ viewpoint : (%,F,F,F) -> Void
+ ++ viewpoint(v,rotx,roty,rotz) sets the rotation about the x-axis
+ ++ to be \spad{rotx} radians, sets the rotation about the y-axis
+ ++ to be \spad{roty} radians, and sets the rotation about the z-axis
+ ++ to be \spad{rotz} radians, for the viewport v, which is of the
+ ++ domain \spadtype{ThreeDimensionalViewport} and displays v with
+ ++ the new view position.
+ controlPanel : (%,S) -> Void
+ ++ controlPanel(v,s) displays the control panel of the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}, if s is "on", or hides
+ ++ the control panel if s is "off".
+ axes : (%,S) -> Void
+ ++ axes(v,s) displays the axes of the given three-dimensional
+ ++ viewport, v, which is of domain \spadtype{ThreeDimensionalViewport},
+ ++ if s is "on", or does not display the axes if s is "off".
+ diagonals : (%,S) -> Void
+ ++ diagonals(v,s) displays the diagonals of the polygon outline
+ ++ showing a triangularized surface instead of a quadrilateral
+ ++ surface outline, for the given three-dimensional viewport v
+ ++ which is of domain \spadtype{ThreeDimensionalViewport}, if s is
+ ++ "on", or does not display the diagonals if s is "off".
+ outlineRender : (%,S) -> Void
+ ++ outlineRender(v,s) displays the polygon outline showing either
+ ++ triangularized surface or a quadrilateral surface outline depending
+ ++ on the whether the \spadfun{diagonals} function has been set, for
+ ++ the given three-dimensional viewport v which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}, if s is "on", or does not
+ ++ display the polygon outline if s is "off".
+ drawStyle : (%,S) -> Void
+ ++ drawStyle(v,s) displays the surface for the given three-dimensional
+ ++ viewport v which is of domain \spadtype{ThreeDimensionalViewport}
+ ++ in the style of drawing indicated by s. If s is not a valid
+ ++ drawing style the style is wireframe by default. Possible
+ ++ styles are \spad{"shade"}, \spad{"solid"} or \spad{"opaque"},
+ ++ \spad{"smooth"}, and \spad{"wireMesh"}.
+ rotate : (%,F,F) -> Void
+ ++ rotate(v,th,phi) rotates the graph to the longitudinal view angle
+ ++ \spad{th} radians and the latitudinal view angle \spad{phi} radians
+ ++ for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ rotate : (%,I,I) -> Void
+ ++ rotate(v,th,phi) rotates the graph to the longitudinal view angle
+ ++ \spad{th} degrees and the latitudinal view angle \spad{phi} degrees
+ ++ for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}. The new rotation position
+ ++ is not displayed until the function \spadfun{makeViewport3D} is
+ ++ executed again for v.
+ zoom : (%,F) -> Void
+ ++ zoom(v,s) sets the graph scaling factor to s, for the viewport v,
+ ++ which is of the domain \spadtype{ThreeDimensionalViewport}.
+ zoom : (%,F,F,F) -> Void
+ ++ zoom(v,sx,sy,sz) sets the graph scaling factors for the x-coordinate
+ ++ axis to \spad{sx}, the y-coordinate axis to \spad{sy} and the
+ ++ z-coordinate axis to \spad{sz} for the viewport v, which is of
+ ++ the domain \spadtype{ThreeDimensionalViewport}.
+ translate : (%,F,F) -> Void
+ ++ translate(v,dx,dy) sets the horizontal viewport offset to \spad{dx}
+ ++ and the vertical viewport offset to \spad{dy}, for the viewport v,
+ ++ which is of the domain \spadtype{ThreeDimensionalViewport}.
+ perspective : (%,S) -> Void
+ ++ perspective(v,s) displays the graph in perspective if s is "on",
+ ++ or does not display perspective if s is "off" for the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ eyeDistance : (%,F) -> Void
+ ++ eyeDistance(v,d) sets the distance of the observer from the center
+ ++ of the graph to d, for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ hitherPlane : (%,F) -> Void
+ ++ hitherPlane(v,h) sets the hither clipping plane of the graph to h,
+ ++ for the viewport v, which is of the domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ showRegion : (%,S) -> Void
+ ++ showRegion(v,s) displays the bounding box of the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}, if s is "on", or does not
+ ++ display the box if s is "off".
+ showClipRegion : (%,S) -> Void
+ ++ showClipRegion(v,s) displays the clipping region of the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}, if s is "on", or does not
+ ++ display the region if s is "off".
+ clipSurface : (%,S) -> Void
+ ++ clipSurface(v,s) displays the graph with the specified
+ ++ clipping region removed if s is "on", or displays the graph
+ ++ without clipping implemented if s is "off", for the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ lighting : (%,F,F,F) -> Void
+ ++ lighting(v,x,y,z) sets the position of the light source to
+ ++ the coordinates x, y, and z and displays the graph for the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ intensity : (%,F) -> Void
+ ++ intensity(v,i) sets the intensity of the light source to i, for
+ ++ the given three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ reset : % -> Void
+ ++ reset(v) sets the current state of the graph characteristics
+ ++ of the given three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}, back to their initial settings.
+ colorDef : (%,C,C) -> Void
+ ++ colorDef(v,c1,c2) sets the range of colors along the colormap so
+ ++ that the lower end of the colormap is defined by \spad{c1} and the
+ ++ top end of the colormap is defined by \spad{c2}, for the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}.
+ write : (%,S) -> S
+ ++ write(v,s) takes the given three-dimensional viewport, v, which
+ ++ is of domain \spadtype{ThreeDimensionalViewport}, and creates
+ ++ a directory indicated by s, which contains the graph data
+ ++ file for v.
+ write : (%,S,S) -> S
+ ++ write(v,s,f) takes the given three-dimensional viewport, v, which
+ ++ is of domain \spadtype{ThreeDimensionalViewport}, and creates
+ ++ a directory indicated by s, which contains the graph data
+ ++ file for v and an optional file type f.
+ write : (%,S,L S) -> S
+ ++ write(v,s,lf) takes the given three-dimensional viewport, v, which
+ ++ is of domain \spadtype{ThreeDimensionalViewport}, and creates
+ ++ a directory indicated by s, which contains the graph data
+ ++ file for v and the optional file types indicated by the list lf.
+ close : % -> Void
+ ++ close(v) closes the viewport window of the given
+ ++ three-dimensional viewport, v, which is of domain
+ ++ \spadtype{ThreeDimensionalViewport}, and terminates the
+ ++ corresponding process ID.
+ key : % -> I
+ ++ key(v) returns the process ID number of the given three-dimensional
+ ++ viewport, v, which is of domain \spadtype{ThreeDimensionalViewport}.
+-- print : % -> Void
+
+ Implementation ==> add
+ import Color()
+ import ViewDefaultsPackage()
+ import Plot3D()
+ import TubePlot()
+ import POINT
+ import PointPackage(SF)
+ import SubSpaceComponentProperty()
+ import SPACE3
+ import MeshCreationRoutinesForThreeDimensions()
+ import DrawOptionFunctions0
+ import COORDSYS
+ import Set(PositiveInteger)
+
+ Rep := Record (key:I, fun:I, _
+ title:S, moveTo:XYNN, size:XYP, viewpoint:V, colors:H, flags:FLAG, _
+ lighting:LR, perspective:PR, volume:VR, _
+ space3D:SPACE3, _
+ optionsField:L DROP)
+
+ degrees := pi()$F / 180.0
+ degreesSF := pi()$SF / 180
+ defaultTheta : Reference(SF) := ref(convert(pi()$F/4.0)@SF)
+ defaultPhi : Reference(SF) := ref(convert(-pi()$F/4.0)@SF)
+ defaultZoom : Reference(SF) := ref(convert(1.2)@SF)
+ defaultDeltaX : Reference(SF) := ref 0
+ defaultDeltaY : Reference(SF) := ref 0
+
+
+--%Local Functions
+ checkViewport (viewport:%):B ==
+ -- checks to see if this viewport still exists
+ -- by sending the key to the viewport manager and
+ -- waiting for its reply after it checks it against
+ -- the viewports in its list. a -1 means it doesn't
+ -- exist.
+ sendI(VIEW,viewport.key)$Lisp
+ i := getI(VIEW)$Lisp
+ (i < 0$I) =>
+ viewport.key := 0$I
+ error "This viewport has already been closed!"
+ true
+
+ arcsinTemp(x:SF):SF ==
+ -- the asin function doesn't exist in the SF domain currently
+ x >= 1 => (pi()$SF / 2) -- to avoid floating point error from SF (ie 1.0 -> 1.00001)
+ x <= -1 => 3 * pi()$SF / 2
+ convert(asin(convert(x)@Float)$Float)@SF
+
+ arctanTemp(x:SF):SF == convert(atan(convert(x)@Float)$Float)@SF
+
+ doOptions(v:Rep):Void ==
+ v.title := title(v.optionsField,"AXIOM3D")
+ st:S := style(v.optionsField,"wireMesh")
+ if (st = "shade" or st = "render") then
+ v.flags.style := rendered
+ else if (st = "solid" or st = "opaque") then
+ v.flags.style := opaque
+ else if (st = "contour") then
+ v.flags.style := contour
+ else if (st = "smooth") then
+ v.flags.style := smooth
+ else v.flags.style := wireMesh
+ v.viewpoint := viewpoint(v.optionsField,
+ [deref defaultTheta,deref defaultPhi,deref defaultZoom, _
+ 1$SF,1$SF,1$SF,deref defaultDeltaX, deref defaultDeltaY])
+ -- etc - 3D specific stuff...
+
+--%Exported Functions : Default Settings
+ viewport3D() ==
+ [0,typeVIEW3D,"AXIOM3D",[viewPosDefault().1,viewPosDefault().2], _
+ [viewSizeDefault().1,viewSizeDefault().2], _
+ [deref defaultTheta,deref defaultPhi,deref defaultZoom, _
+ 1$SF,1$SF,1$SF,deref defaultDeltaX, deref defaultDeltaY], [0,27], _
+ [noControl,wireMesh,yes,no,no,no], [0$SF,0$SF,1$SF,0$SF,0$SF,1$SF], _
+ [yes, EYED, HITHER], [0$SF,1$SF,0$SF,1$SF,0$SF,1$SF,no,yes], _
+ create3Space()$SPACE3, [] ]
+
+ subspace viewport ==
+ viewport.space3D
+
+ subspace(viewport,space) ==
+ viewport.space3D := space
+ viewport
+
+ options viewport ==
+ viewport.optionsField
+
+ options(viewport,opts) ==
+ viewport.optionsField := opts
+ viewport
+
+ makeViewport3D(space:SPACE3,Title:S):% ==
+ v := viewport3D()
+ v.space3D := space
+ v.optionsField := [title(Title)]
+ makeViewport3D v
+
+ makeViewport3D(space:SPACE3,opts:L DROP):% ==
+ v := viewport3D()
+ v.space3D := space
+ v.optionsField := opts
+ makeViewport3D v
+
+ makeViewport3D viewport ==
+ doOptions viewport --local function to extract and assign optional arguments for 3D viewports
+ sayBrightly([" Transmitting data..."::E]$List(E))$Lisp
+ transform := coord(viewport.optionsField,cartesian$COORDSYS)$DrawOptionFunctions0
+ check(viewport.space3D)
+ lpts := lp(viewport.space3D)
+ lllipts := lllip(viewport.space3D)
+ llprops := llprop(viewport.space3D)
+ lprops := lprop(viewport.space3D)
+ -- check for dimensionality of points
+ -- if they are all 4D points, then everything is okay
+ -- if they are all 3D points, then pad an extra constant
+ -- coordinate for color
+ -- if they have varying dimensionalities, give an error
+ s := brace()$Set(PI)
+ for pt in lpts repeat
+ insert_!(dimension pt,s)
+ #s > 1 => error "All points should have the same dimension"
+ (n := first parts s) < 3 => error "Dimension of points should be greater than 2"
+ sendI(VIEW,viewport.fun)$Lisp
+ sendI(VIEW,makeVIEW3D)$Lisp
+ sendSTR(VIEW,viewport.title)$Lisp
+ sendSF(VIEW,viewport.viewpoint.deltaX)$Lisp
+ sendSF(VIEW,viewport.viewpoint.deltaY)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scale)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleX)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleY)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleZ)$Lisp
+ sendSF(VIEW,viewport.viewpoint.theta)$Lisp
+ sendSF(VIEW,viewport.viewpoint.phi)$Lisp
+ sendI(VIEW,viewport.moveTo.X)$Lisp
+ sendI(VIEW,viewport.moveTo.Y)$Lisp
+ sendI(VIEW,viewport.size.X)$Lisp
+ sendI(VIEW,viewport.size.Y)$Lisp
+ sendI(VIEW,viewport.flags.showCP)$Lisp
+ sendI(VIEW,viewport.flags.style)$Lisp
+ sendI(VIEW,viewport.flags.axesOn)$Lisp
+ sendI(VIEW,viewport.flags.diagonalsOn)$Lisp
+ sendI(VIEW,viewport.flags.outlineRenderOn)$Lisp
+ sendI(VIEW,viewport.flags.showRegionField)$Lisp -- add to make3D.c
+ sendI(VIEW,viewport.volume.clipRegionField)$Lisp -- add to make3D.c
+ sendI(VIEW,viewport.volume.clipSurfaceField)$Lisp -- add to make3D.c
+ sendI(VIEW,viewport.colors.hueOffset)$Lisp
+ sendI(VIEW,viewport.colors.hueNumber)$Lisp
+ sendSF(VIEW,viewport.lighting.lightX)$Lisp
+ sendSF(VIEW,viewport.lighting.lightY)$Lisp
+ sendSF(VIEW,viewport.lighting.lightZ)$Lisp
+ sendSF(VIEW,viewport.lighting.translucence)$Lisp
+ sendI(VIEW,viewport.perspective.perspectiveField)$Lisp
+ sendSF(VIEW,viewport.perspective.eyeDistance)$Lisp
+ -- new, crazy points domain stuff
+ -- first, send the point data list
+ sendI(VIEW,#lpts)$Lisp
+ for pt in lpts repeat
+ aPoint := transform pt
+ sendSF(VIEW,xCoord aPoint)$Lisp
+ sendSF(VIEW,yCoord aPoint)$Lisp
+ sendSF(VIEW,zCoord aPoint)$Lisp
+ n = 3 => sendSF(VIEW,zCoord aPoint)$Lisp
+ sendSF(VIEW,color aPoint)$Lisp -- change to c
+ -- now, send the 3d subspace structure
+ sendI(VIEW,#lllipts)$Lisp
+ for allipts in lllipts for oneprop in lprops for onelprops in llprops repeat
+ -- the following is false for f(x,y) and user-defined for [x(t),y(t),z(t)]
+ -- this is temporary - until the generalized points stuff gets put in
+ sendI(VIEW,(closed? oneprop => yes; no))$Lisp
+ sendI(VIEW,(solid? oneprop => yes; no))$Lisp
+ sendI(VIEW,#allipts)$Lisp
+ for alipts in allipts for tinyprop in onelprops repeat
+ -- the following is false for f(x,y) and true for [x(t),y(t),z(t)]
+ -- this is temporary -- until the generalized points stuff gets put in
+ sendI(VIEW,(closed? tinyprop => yes;no))$Lisp
+ sendI(VIEW,(solid? tinyprop => yes;no))$Lisp
+ sendI(VIEW,#alipts)$Lisp
+ for oneIndexedPoint in alipts repeat
+ sendI(VIEW,oneIndexedPoint)$Lisp
+ viewport.key := getI(VIEW)$Lisp
+ viewport
+ -- the key (now set to 0) should be what the viewport returns
+
+ viewThetaDefault == convert(defaultTheta())@F
+ viewThetaDefault t ==
+ defaultTheta() := convert(t)@SF
+ t
+ viewPhiDefault == convert(defaultPhi())@F
+ viewPhiDefault t ==
+ defaultPhi() := convert(t)@SF
+ t
+ viewZoomDefault == convert(defaultZoom())@F
+ viewZoomDefault t ==
+ defaultZoom() := convert(t)@SF
+ t
+ viewDeltaXDefault == convert(defaultDeltaX())@F
+ viewDeltaXDefault t ==
+ defaultDeltaX() := convert(t)@SF
+ t
+ viewDeltaYDefault == convert(defaultDeltaY())@F
+ viewDeltaYDefault t ==
+ defaultDeltaY() := convert(t)@SF
+ t
+
+--Exported Functions: Available features for 3D viewports
+ lighting(viewport,Xlight,Ylight,Zlight) ==
+ viewport.lighting.lightX := convert(Xlight)@SF
+ viewport.lighting.lightY := convert(Ylight)@SF
+ viewport.lighting.lightZ := convert(Zlight)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,lightDef)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.lighting.lightX)$Lisp
+ sendSF(VIEW,viewport.lighting.lightY)$Lisp
+ sendSF(VIEW,viewport.lighting.lightZ)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ axes (viewport,onOff) ==
+ if onOff = "on" then viewport.flags.axesOn := yes
+ else viewport.flags.axesOn := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,axesOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.flags.axesOn)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ diagonals (viewport,onOff) ==
+ if onOff = "on" then viewport.flags.diagonalsOn := yes
+ else viewport.flags.diagonalsOn := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,diagOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.flags.diagonalsOn)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ outlineRender (viewport,onOff) ==
+ if onOff = "on" then viewport.flags.outlineRenderOn := yes
+ else viewport.flags.outlineRenderOn := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,outlineOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.flags.outlineRenderOn)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ controlPanel (viewport,onOff) ==
+ if onOff = "on" then viewport.flags.showCP := yes
+ else viewport.flags.showCP := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,hideControl)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.flags.showCP)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ drawStyle (viewport,how) ==
+ if (how = "shade") then -- render
+ viewport.flags.style := rendered
+ else if (how = "solid") then -- opaque
+ viewport.flags.style := opaque
+ else if (how = "contour") then -- contour
+ viewport.flags.style := contour
+ else if (how = "smooth") then -- smooth
+ viewport.flags.style := smooth
+ else viewport.flags.style := wireMesh
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,viewport.flags.style)$Lisp
+ checkViewport viewport =>
+ getI(VIEW)$Lisp -- acknowledge
+
+ reset viewport ==
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,SPADBUTTONPRESS)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,RESET)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ close viewport ==
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,closeAll)$Lisp
+ checkViewport viewport =>
+ getI(VIEW)$Lisp -- acknowledge
+ viewport.key := 0$I
+
+ viewpoint (viewport:%):V ==
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,queryVIEWPOINT)$Lisp
+ checkViewport viewport =>
+ deltaX_sf : SF := getSF(VIEW)$Lisp
+ deltaY_sf : SF := getSF(VIEW)$Lisp
+ scale_sf : SF := getSF(VIEW)$Lisp
+ scaleX_sf : SF := getSF(VIEW)$Lisp
+ scaleY_sf : SF := getSF(VIEW)$Lisp
+ scaleZ_sf : SF := getSF(VIEW)$Lisp
+ theta_sf : SF := getSF(VIEW)$Lisp
+ phi_sf : SF := getSF(VIEW)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+ viewport.viewpoint :=
+ [ theta_sf, phi_sf, scale_sf, scaleX_sf, scaleY_sf, scaleZ_sf,
+ deltaX_sf, deltaY_sf ]
+ viewport.viewpoint
+
+ viewpoint (viewport:%, viewpt:V):Void ==
+ viewport.viewpoint := viewpt
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,changeVIEWPOINT)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.viewpoint.deltaX)$Lisp
+ sendSF(VIEW,viewport.viewpoint.deltaY)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scale)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleX)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleY)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleZ)$Lisp
+ sendSF(VIEW,viewport.viewpoint.theta)$Lisp
+ sendSF(VIEW,viewport.viewpoint.phi)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+
+ viewpoint (viewport:%,Theta:F,Phi:F,Scale:F,DeltaX:F,DeltaY:F):Void ==
+ viewport.viewpoint :=
+ [convert(Theta)@SF,convert(Phi)@SF,convert(Scale)@SF,1$SF,1$SF,1$SF,convert(DeltaX)@SF,convert(DeltaY)@SF]
+
+ viewpoint (viewport:%,Theta:I,Phi:I,Scale:F,DeltaX:F,DeltaY:F):Void ==
+ viewport.viewpoint := [convert(Theta)@SF * degreesSF,convert(Phi)@SF * degreesSF,
+ convert(Scale)@SF,1$SF,1$SF,1$SF,convert(DeltaX)@SF,convert(DeltaY)@SF]
+
+ viewpoint (viewport:%,Theta:F,Phi:F):Void ==
+ viewport.viewpoint.theta := convert(Theta)@SF * degreesSF
+ viewport.viewpoint.phi := convert(Phi)@SF * degreesSF
+
+ viewpoint (viewport:%,X:F,Y:F,Z:F):Void ==
+ Theta : F
+ Phi : F
+ if (X=0$F) and (Y=0$F) then
+ Theta := 0$F
+ if (Z>=0$F) then
+ Phi := 0$F
+ else
+ Phi := 180.0
+ else
+ Theta := asin(Y/(R := sqrt(X*X+Y*Y)))
+ if (Z=0$F) then
+ Phi := 90.0
+ else
+ Phi := atan(Z/R)
+ rotate(viewport, Theta * degrees, Phi * degrees)
+
+ title (viewport,Title) ==
+ viewport.title := Title
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,TITLE)$Lisp
+ checkViewport viewport =>
+ sendSTR(VIEW,Title)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ colorDef (viewport,HueOffset,HueNumber) ==
+ viewport.colors := [h := (hue HueOffset),(hue HueNumber) - h]
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,COLORDEF)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,hue HueOffset)$Lisp
+ sendI(VIEW,hue HueNumber)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ dimensions (viewport,ViewX,ViewY,ViewWidth,ViewHeight) ==
+ viewport.moveTo := [ViewX,ViewY]
+ viewport.size := [ViewWidth,ViewHeight]
+
+ move(viewport,xLoc,yLoc) ==
+ viewport.moveTo := [xLoc,yLoc]
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,MOVE)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,xLoc)$Lisp
+ sendI(VIEW,yLoc)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ resize(viewport,xSize,ySize) ==
+ viewport.size := [xSize,ySize]
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,RESIZE)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,xSize)$Lisp
+ sendI(VIEW,ySize)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ coerce viewport ==
+ (key(viewport) = 0$I) =>
+ hconcat
+ ["Closed or Undefined ThreeDimensionalViewport: "::E,
+ (viewport.title)::E]
+ hconcat ["ThreeDimensionalViewport: "::E, (viewport.title)::E]
+
+ key viewport == viewport.key
+
+ rotate(viewport:%,Theta:I,Phi:I) ==
+ rotate(viewport,Theta::F * degrees,Phi::F * degrees)
+
+ rotate(viewport:%,Theta:F,Phi:F) ==
+ viewport.viewpoint.theta := convert(Theta)@SF
+ viewport.viewpoint.phi := convert(Phi)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,ROTATE)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.viewpoint.theta)$Lisp
+ sendSF(VIEW,viewport.viewpoint.phi)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ zoom(viewport:%,Scale:F) ==
+ viewport.viewpoint.scale := convert(Scale)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,ZOOM)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.viewpoint.scale)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ zoom(viewport:%,ScaleX:F,ScaleY:F,ScaleZ:F) ==
+ viewport.viewpoint.scaleX := convert(ScaleX)@SF
+ viewport.viewpoint.scaleY := convert(ScaleY)@SF
+ viewport.viewpoint.scaleZ := convert(ScaleZ)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,zoomx)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.viewpoint.scaleX)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleY)$Lisp
+ sendSF(VIEW,viewport.viewpoint.scaleZ)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ translate(viewport,DeltaX,DeltaY) ==
+ viewport.viewpoint.deltaX := convert(DeltaX)@SF
+ viewport.viewpoint.deltaY := convert(DeltaY)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,TRANSLATE)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.viewpoint.deltaX)$Lisp
+ sendSF(VIEW,viewport.viewpoint.deltaY)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ intensity(viewport,Amount) ==
+ if (Amount < 0$F) or (Amount > 1$F) then
+ error "The intensity must be a value between 0 and 1, inclusively."
+ viewport.lighting.translucence := convert(Amount)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,translucenceDef)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.lighting.translucence)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ write(viewport:%,Filename:S,aThingToWrite:S) ==
+ write(viewport,Filename,[aThingToWrite])
+
+ write(viewport,Filename) ==
+ write(viewport,Filename,viewWriteDefault())
+
+ write(viewport:%,Filename:S,thingsToWrite:L S) ==
+ stringToSend : S := ""
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,writeView)$Lisp
+ checkViewport viewport =>
+ sendSTR(VIEW,Filename)$Lisp
+ m := minIndex(avail := viewWriteAvailable())
+ for aTypeOfFile in thingsToWrite repeat
+ if (writeTypeInt:= position(upperCase aTypeOfFile,avail)-m) < 0 then
+ sayBrightly([" > "::E,(concat(aTypeOfFile, _
+ " is not a valid file type for writing a 3D viewport"))::E]$List(E))$Lisp
+ else
+ sendI(VIEW,writeTypeInt+(1$I))$Lisp
+ sendI(VIEW,0$I)$Lisp -- no more types of things to write
+ getI(VIEW)$Lisp -- acknowledge
+ Filename
+
+ perspective (viewport,onOff) ==
+ if onOff = "on" then viewport.perspective.perspectiveField := yes
+ else viewport.perspective.perspectiveField := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,perspectiveOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.perspective.perspectiveField)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ showRegion (viewport,onOff) ==
+ if onOff = "on" then viewport.flags.showRegionField := yes
+ else viewport.flags.showRegionField := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,region3D)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.flags.showRegionField)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ showClipRegion (viewport,onOff) ==
+ if onOff = "on" then viewport.volume.clipRegionField := yes
+ else viewport.volume.clipRegionField := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,clipRegionOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.volume.clipRegionField)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ clipSurface (viewport,onOff) ==
+ if onOff = "on" then viewport.volume.clipSurfaceField := yes
+ else viewport.volume.clipSurfaceField := no
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,clipSurfaceOnOff)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,viewport.volume.clipSurfaceField)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ eyeDistance(viewport:%,EyeDistance:F) ==
+ viewport.perspective.eyeDistance := convert(EyeDistance)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,eyeDistanceData)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.perspective.eyeDistance)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ hitherPlane(viewport:%,HitherPlane:F) ==
+ viewport.perspective.hitherPlane := convert(HitherPlane)@SF
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,hitherPlaneData)$Lisp
+ checkViewport viewport =>
+ sendSF(VIEW,viewport.perspective.hitherPlane)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+ modifyPointData(viewport,anIndex,aPoint) ==
+ (n := dimension aPoint) < 3 => error "The point should have dimension of at least 3"
+ viewport.space3D := modifyPointData(viewport.space3D,anIndex,aPoint)
+ (key(viewport) ^= 0$I) =>
+ sendI(VIEW,typeVIEW3D)$Lisp
+ sendI(VIEW,modifyPOINT)$Lisp
+ checkViewport viewport =>
+ sendI(VIEW,anIndex)$Lisp
+ sendSF(VIEW,xCoord aPoint)$Lisp
+ sendSF(VIEW,yCoord aPoint)$Lisp
+ sendSF(VIEW,zCoord aPoint)$Lisp
+ if (n = 3) then sendSF(VIEW,convert(0.5)@SF)$Lisp
+ else sendSF(VIEW,color aPoint)$Lisp
+ getI(VIEW)$Lisp -- acknowledge
+
+-- print viewport ==
+-- (key(viewport) ^= 0$I) =>
+-- sendI(VIEW,typeVIEW3D)$Lisp
+-- sendI(VIEW,printViewport)$Lisp
+-- checkViewport viewport =>
+-- getI(VIEW)$Lisp -- acknowledge
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+-- this is a new graphics package and does not depend on any of the
+-- current plotting stuff
+-- so it is best to run it in a minimum system (like spadsys)
+
+<<domain VIEW3D ThreeDimensionalViewport>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/viewDef.spad.pamphlet b/src/algebra/viewDef.spad.pamphlet
new file mode 100644
index 00000000..645a9c79
--- /dev/null
+++ b/src/algebra/viewDef.spad.pamphlet
@@ -0,0 +1,264 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra viewDef.spad}
+\author{James Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package VIEWDEF ViewDefaultsPackage}
+<<package VIEWDEF ViewDefaultsPackage>>=
+)abbrev package VIEWDEF ViewDefaultsPackage
+++ Author: Jim Wen
+++ Date Created: 15 January 1990
+++ Date Last Updated:
+++ Basic Operations: pointColorDefault, lineColorDefault, axesColorDefault,
+++ unitsColorDefault, pointSizeDefault, viewPosDefault, viewSizeDefault,
+++ viewDefaults, viewWriteDefault, viewWriteAvailable, var1StepsDefault,
+++ var2StepsDefault, tubePointsDefault, tubeRadiusDefault
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: ViewportDefaultsPackage describes default and user definable
+++ values for graphics
+
+ViewDefaultsPackage():Exports == Implementation where
+ I ==> Integer
+ C ==> Color
+ PAL ==> Palette
+ L ==> List
+ S ==> String
+ E ==> Expression
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ SF ==> DoubleFloat
+ B ==> Boolean
+
+ writeAvailable ==> (["PIXMAP","BITMAP","POSTSCRIPT","IMAGE"]::L S)
+ -- need not worry about case of letters
+
+ Exports ==> with
+ pointColorDefault : () -> PAL
+ ++ pointColorDefault() returns the default color of points in a 2D
+ ++ viewport.
+ pointColorDefault : PAL -> PAL
+ ++ pointColorDefault(p) sets the default color of points in a 2D viewport
+ ++ to the palette p.
+ lineColorDefault : () -> PAL
+ ++ lineColorDefault() returns the default color of lines connecting
+ ++ points in a 2D viewport.
+ lineColorDefault : PAL -> PAL
+ ++ lineColorDefault(p) sets the default color of lines connecting points
+ ++ in a 2D viewport to the palette p.
+ axesColorDefault : () -> PAL
+ ++ axesColorDefault() returns the default color of the axes in a
+ ++ 2D viewport.
+ axesColorDefault : PAL -> PAL
+ ++ axesColorDefault(p) sets the default color of the axes in a 2D
+ ++ viewport to the palette p.
+ unitsColorDefault : () -> PAL
+ ++ unitsColorDefault() returns the default color of the unit ticks in
+ ++ a 2D viewport.
+ unitsColorDefault : PAL -> PAL
+ ++ unitsColorDefault(p) sets the default color of the unit ticks in
+ ++ a 2D viewport to the palette p.
+ pointSizeDefault : () -> PI
+ ++ pointSizeDefault() returns the default size of the points in
+ ++ a 2D viewport.
+ pointSizeDefault : PI -> PI
+ ++ pointSizeDefault(i) sets the default size of the points in a 2D
+ ++ viewport to i.
+ viewPosDefault : () -> L NNI
+ ++ viewPosDefault() returns the default X and Y position of a
+ ++ viewport window unless overriden explicityly, newly created
+ ++ viewports will have this X and Y coordinate.
+ viewPosDefault : L NNI -> L NNI
+ ++ viewPosDefault([x,y]) sets the default X and Y position of a
+ ++ viewport window unless overriden explicityly, newly created
+ ++ viewports will have th X and Y coordinates x, y.
+ viewSizeDefault : () -> L PI
+ ++ viewSizeDefault() returns the default viewport width and height.
+ viewSizeDefault : L PI -> L PI
+ ++ viewSizeDefault([w,h]) sets the default viewport width to w and height
+ ++ to h.
+ viewDefaults : () -> Void
+ ++ viewDefaults() resets all the default graphics settings.
+ viewWriteDefault : () -> L S
+ ++ viewWriteDefault() returns the list of things to write in a viewport
+ ++ data file; a viewAlone file is always generated.
+ viewWriteDefault : L S -> L S
+ ++ viewWriteDefault(l) sets the default list of things to write in a
+ ++ viewport data file to the strings in l; a viewAlone file is always
+ ++ genereated.
+ viewWriteAvailable : () -> L S
+ ++ viewWriteAvailable() returns a list of available methods for writing,
+ ++ such as BITMAP, POSTSCRIPT, etc.
+ var1StepsDefault : () -> PI
+ ++ var1StepsDefault() is the current setting for the number of steps to
+ ++ take when creating a 3D mesh in the direction of the first defined
+ ++ free variable (a free variable is considered defined when its
+ ++ range is specified (e.g. x=0..10)).
+ var2StepsDefault : () -> PI
+ ++ var2StepsDefault() is the current setting for the number of steps to
+ ++ take when creating a 3D mesh in the direction of the first defined
+ ++ free variable (a free variable is considered defined when its
+ ++ range is specified (e.g. x=0..10)).
+ var1StepsDefault : PI -> PI
+ ++ var1StepsDefault(i) sets the number of steps to take when creating a
+ ++ 3D mesh in the direction of the first defined free variable to i
+ ++ (a free variable is considered defined when its range is specified
+ ++ (e.g. x=0..10)).
+ var2StepsDefault : PI -> PI
+ ++ var2StepsDefault(i) sets the number of steps to take when creating a
+ ++ 3D mesh in the direction of the first defined free variable to i
+ ++ (a free variable is considered defined when its range is specified
+ ++ (e.g. x=0..10)).
+ tubePointsDefault : PI -> PI
+ ++ tubePointsDefault(i) sets the number of points to use when creating
+ ++ the circle to be used in creating a 3D tube plot to i.
+ tubePointsDefault : () -> PI
+ ++ tubePointsDefault() returns the number of points to be used when
+ ++ creating the circle to be used in creating a 3D tube plot.
+ tubeRadiusDefault : Float -> SF -- current tube.spad asks for SF
+ ++ tubeRadiusDefault(r) sets the default radius for a 3D tube plot to r.
+ tubeRadiusDefault : () -> SF
+ ++ tubeRadiusDefault() returns the radius used for a 3D tube plot.
+
+ Implementation ==> add
+
+ import Color()
+ import Palette()
+ --import StringManipulations()
+
+ defaultPointColor : Reference(PAL) := ref bright red()
+ defaultLineColor : Reference(PAL) := ref pastel green() --bright blue()
+ defaultAxesColor : Reference(PAL) := ref dim red()
+ defaultUnitsColor : Reference(PAL) := ref dim yellow()
+ defaultPointSize : Reference(PI) := ref(3::PI)
+ defaultXPos : Reference(NNI) := ref(0::NNI)
+ defaultYPos : Reference(NNI) := ref(0::NNI)
+ defaultWidth : Reference(PI) := ref(400::PI)
+ defaultHeight : Reference(PI) := ref(400::PI)
+ defaultThingsToWrite : Reference(L S) := ref([]::L S)
+ defaultVar1Steps : Reference(PI) := ref(27::PI)
+ defaultVar2Steps : Reference(PI) := ref(27::PI)
+ defaultTubePoints : Reference(PI) := ref(6::PI)
+ defaultTubeRadius : Reference(SF) := ref(convert(0.5)@SF)
+ defaultClosed : Reference(B) := ref(false)
+
+--%Viewport window dimensions specifications
+ viewPosDefault == [defaultXPos(),defaultYPos()]
+ viewPosDefault l ==
+ #l < 2 => error "viewPosDefault expects a list with two elements"
+ [defaultXPos() := first l,defaultYPos() := last l]
+
+ viewSizeDefault == [defaultWidth(),defaultHeight()]
+ viewSizeDefault l ==
+ #l < 2 => error "viewSizeDefault expects a list with two elements"
+ [defaultWidth() := first l,defaultHeight() := last l]
+
+ viewDefaults ==
+ defaultPointColor : Reference(PAL) := ref bright red()
+ defaultLineColor : Reference(PAL) := ref pastel green() --bright blue()
+ defaultAxesColor : Reference(PAL) := ref dim red()
+ defaultUnitsColor : Reference(PAL) := ref dim yellow()
+ defaultPointSize : Reference(PI) := ref(3::PI)
+ defaultXPos : Reference(NNI) := ref(0::NNI)
+ defaultYPos : Reference(NNI) := ref(0::NNI)
+ defaultWidth : Reference(PI) := ref(400::PI)
+ defaultHeight : Reference(PI) := ref(427::PI)
+
+--%2D graphical output specifications
+ pointColorDefault == defaultPointColor()
+ pointColorDefault p == defaultPointColor() := p
+
+ lineColorDefault == defaultLineColor()
+ lineColorDefault p == defaultLineColor() := p
+
+ axesColorDefault == defaultAxesColor()
+ axesColorDefault p == defaultAxesColor() := p
+
+ unitsColorDefault == defaultUnitsColor()
+ unitsColorDefault p == defaultUnitsColor() := p
+
+ pointSizeDefault == defaultPointSize()
+ pointSizeDefault x == defaultPointSize() := x
+
+
+--%3D specific stuff
+ var1StepsDefault == defaultVar1Steps()
+ var1StepsDefault i == defaultVar1Steps() := i
+
+ var2StepsDefault == defaultVar2Steps()
+ var2StepsDefault i == defaultVar2Steps() := i
+
+ tubePointsDefault == defaultTubePoints()
+ tubePointsDefault i == defaultTubePoints() := i
+
+ tubeRadiusDefault == defaultTubeRadius()
+ tubeRadiusDefault f == defaultTubeRadius() := convert(f)@SF
+
+--%File output stuff
+ viewWriteAvailable == writeAvailable
+
+ viewWriteDefault == defaultThingsToWrite()
+
+ viewWriteDefault listOfThings ==
+ thingsToWrite : L S := []
+ for aTypeOfFile in listOfThings repeat
+ if (writeTypeInt := position(upperCase aTypeOfFile,viewWriteAvailable())) < 0 then
+ sayBrightly([" > ",concat(aTypeOfFile,
+ " is not a valid file type for writing a viewport")])$Lisp
+ else
+ thingsToWrite := append(thingsToWrite,[aTypeOfFile])
+ defaultThingsToWrite() := thingsToWrite
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package VIEWDEF ViewDefaultsPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/viewpack.spad.pamphlet b/src/algebra/viewpack.spad.pamphlet
new file mode 100644
index 00000000..5655f96e
--- /dev/null
+++ b/src/algebra/viewpack.spad.pamphlet
@@ -0,0 +1,156 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra viewpack.spad}
+\author{James Wen}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package VIEW ViewportPackage}
+<<package VIEW ViewportPackage>>=
+)abbrev package VIEW ViewportPackage
+++ Author: Jim Wen
+++ Date Created: 30 April 1989
+++ Date Last Updated: 15 June 1990
+++ Basic Operations: graphCurves, drawCurves, coerce
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description: ViewportPackage provides functions for creating GraphImages
+++ and TwoDimensionalViewports from lists of lists of points.
+
+ViewportPackage():Exports == Implementation where
+ DROP ==> DrawOption
+ GRIMAGE ==> GraphImage
+ L ==> List
+ P ==> Point DoubleFloat
+ PAL ==> Palette
+ PI ==> PositiveInteger
+ VIEW2D ==> TwoDimensionalViewport
+
+ Exports ==> with
+
+ graphCurves : (L L P,PAL,PAL,PI,L DROP) -> GRIMAGE
+ ++ graphCurves([[p0],[p1],...,[pn]],ptColor,lineColor,ptSize,[options])
+ ++ creates a \spadtype{GraphImage} from the list of lists of points, p0
+ ++ throught pn, using the options specified in the list \spad{options}.
+ ++ The graph point color is specified by \spad{ptColor}, the graph line
+ ++ color is specified by \spad{lineColor}, and the size of the points is
+ ++ specified by \spad{ptSize}.
+ graphCurves : L L P -> GRIMAGE
+ ++ graphCurves([[p0],[p1],...,[pn]]) creates a \spadtype{GraphImage} from
+ ++ the list of lists of points indicated by p0 through pn.
+ graphCurves : (L L P,L DROP) -> GRIMAGE
+ ++ graphCurves([[p0],[p1],...,[pn]],[options]) creates a
+ ++ \spadtype{GraphImage} from the list of lists of points, p0 throught pn,
+ ++ using the options specified in the list \spad{options}.
+ drawCurves : (L L P,PAL,PAL,PI,L DROP) -> VIEW2D
+ ++ drawCurves([[p0],[p1],...,[pn]],ptColor,lineColor,ptSize,[options])
+ ++ creates a \spadtype{TwoDimensionalViewport} from the list of lists of
+ ++ points, p0 throught pn, using the options specified in the list
+ ++ \spad{options}. The point color is specified by \spad{ptColor}, the
+ ++ line color is specified by \spad{lineColor}, and the point size is
+ ++ specified by \spad{ptSize}.
+ drawCurves : (L L P,L DROP) -> VIEW2D
+ ++ drawCurves([[p0],[p1],...,[pn]],[options]) creates a
+ ++ \spadtype{TwoDimensionalViewport} from the list of lists of points,
+ ++ p0 throught pn, using the options specified in the list \spad{options};
+ coerce : GRIMAGE -> VIEW2D
+ ++ coerce(gi) converts the indicated \spadtype{GraphImage}, gi, into the
+ ++ \spadtype{TwoDimensionalViewport} form.
+
+ Implementation ==> add
+
+ import ViewDefaultsPackage
+ import DrawOptionFunctions0
+
+--% Functions that return GraphImages
+
+ graphCurves(listOfListsOfPoints) ==
+ graphCurves(listOfListsOfPoints, pointColorDefault(),_
+ lineColorDefault(), pointSizeDefault(),nil())
+
+ graphCurves(listOfListsOfPoints,optionsList) ==
+ graphCurves(listOfListsOfPoints, pointColorDefault(),_
+ lineColorDefault(), pointSizeDefault(),optionsList)
+
+ graphCurves(listOfListsOfPoints,ptColor,lineColor,ptSize,optionsList) ==
+ len := #listOfListsOfPoints
+ listOfPointColors : L PAL := [ptColor for i in 1..len]
+ listOfLineColors : L PAL := [lineColor for i in 1..len]
+ listOfPointSizes : L PI := [ptSize for i in 1..len]
+ makeGraphImage(listOfListsOfPoints,listOfPointColors, _
+ listOfLineColors,listOfPointSizes,optionsList)
+
+--% Functions that return Two Dimensional Viewports
+
+ drawCurves(listOfListsOfPoints,optionsList) ==
+ drawCurves(listOfListsOfPoints,pointColorDefault(),_
+ lineColorDefault(),pointSizeDefault(),optionsList)
+
+ drawCurves(ptLists:L L P,ptColor:PAL,lColor:PAL,ptSize:PI,optList:L DROP) ==
+ v := viewport2D()
+ options(v,optList)
+ g := graphCurves(ptLists,ptColor,lColor,ptSize,optList)
+ putGraph(v,g,1)
+ makeViewport2D v
+
+--% Coercions
+
+ coerce(graf:GRIMAGE):VIEW2D ==
+ if (key graf = 0) then makeGraphImage graf
+ v := viewport2D()
+ title(v,"VIEW2D")
+-- dimensions(v,viewPosDefault().1,viewPosDefault().2,viewSizeDefault().1,viewSizeDefault().2)
+ putGraph(v,graf,1::PI)
+ makeViewport2D v
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package VIEW ViewportPackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/void.spad.pamphlet b/src/algebra/void.spad.pamphlet
new file mode 100644
index 00000000..1a27a5fb
--- /dev/null
+++ b/src/algebra/void.spad.pamphlet
@@ -0,0 +1,145 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra void.spad}
+\author{Stephen M. Watt}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain VOID Void}
+<<domain VOID Void>>=
+)abbrev domain VOID Void
+-- These types act as the top and bottom of the type lattice
+-- and are known to the compiler and interpreter for type resolution.
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: ErrorFunctions, ResolveLatticeCompletion, Exit
+++ Also See:
+++ AMS Classifications:
+++ Keywords: type, mode, coerce, no value
+++ Examples:
+++ References:
+++ Description:
+++ This type is used when no value is needed, e.g., in the \spad{then}
+++ part of a one armed \spad{if}.
+++ All values can be coerced to type Void. Once a value has been coerced
+++ to Void, it cannot be recovered.
+
+Void: with
+ void: () -> % ++ void() produces a void object.
+ coerce: % -> OutputForm ++ coerce(v) coerces void object to outputForm.
+ == add
+ Rep := String
+ void() == voidValue()$Lisp
+ coerce(v:%) == coerce(v)$Rep
+
+@
+\section{domain EXIT Exit}
+<<domain EXIT Exit>>=
+)abbrev domain EXIT Exit
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: ErrorFunctions, ResolveLatticeCompletion, Void
+++ Also See:
+++ AMS Classifications:
+++ Keywords: exit, throw, error, non-local return
+++ Examples:
+++ References:
+++ Description:
+++ A function which does not return directly to its caller should
+++ have Exit as its return type.
+++
+++ Note: It is convenient to have a formal \spad{coerce} into each type from
+++ type Exit. This allows, for example, errors to be raised in
+++ one half of a type-balanced \spad{if}.
+Exit: SetCategory == add
+ coerce(n:%) == error "Cannot use an Exit value."
+ n1 = n2 == error "Cannot use an Exit value."
+
+@
+\section{package RESLATC ResolveLatticeCompletion}
+<<package RESLATC ResolveLatticeCompletion>>=
+)abbrev package RESLATC ResolveLatticeCompletion
+++ Author: Stephen M. Watt
+++ Date Created: 1986
+++ Date Last Updated: May 30, 1991
+++ Basic Operations:
+++ Related Domains: ErrorFunctions, Exit, Void
+++ Also See:
+++ AMS Classifications:
+++ Keywords: mode, resolve, type lattice
+++ Examples:
+++ References:
+++ Description:
+++ This package provides coercions for the special types \spadtype{Exit}
+++ and \spadtype{Void}.
+ResolveLatticeCompletion(S: Type): with
+ coerce: S -> Void
+ ++ coerce(s) throws all information about s away.
+ ++ This coercion allows values of any type to appear
+ ++ in contexts where they will not be used.
+ ++ For example, it allows the resolution of different types in
+ ++ the \spad{then} and \spad{else} branches when an \spad{if}
+ ++ is in a context where the resulting value is not used.
+ coerce: Exit -> S
+ ++ coerce(e) is never really evaluated. This coercion is
+ ++ used for formal type correctness when a function will not
+ ++ return directly to its caller.
+ == add
+ coerce(s: S): Void == void()
+ coerce(e: Exit): S ==
+ error "Bug: Should not be able to obtain value of type Exit"
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain VOID Void>>
+<<domain EXIT Exit>>
+<<package RESLATC ResolveLatticeCompletion>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/weier.spad.pamphlet b/src/algebra/weier.spad.pamphlet
new file mode 100644
index 00000000..47da09ad
--- /dev/null
+++ b/src/algebra/weier.spad.pamphlet
@@ -0,0 +1,202 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra weier.spad}
+\author{William H. Burge}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package WEIER WeierstrassPreparation}
+<<package WEIER WeierstrassPreparation>>=
+)abbrev package WEIER WeierstrassPreparation
+++ Author:William H. Burge
+++ Date Created:Sept 1988
+++ Date Last Updated:Feb 15 1992
+++ Basic Operations:
+++ Related Domains:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Examples:
+++ References:
+++ Description: This package implements the Weierstrass preparation
+++ theorem f or multivariate power series.
+++ weierstrass(v,p) where v is a variable, and p is a
+++ TaylorSeries(R) in which the terms
+++ of lowest degree s must include c*v**s where c is a constant,s>0,
+++ is a list of TaylorSeries coefficients A[i] of the
+++ equivalent polynomial
+++ A = A[0] + A[1]*v + A[2]*v**2 + ... + A[s-1]*v**(s-1) + v**s
+++ such that p=A*B , B being a TaylorSeries of minimum degree 0
+WeierstrassPreparation(R): Defn == Impl where
+ R : Field
+ VarSet==>Symbol
+ SMP ==> Polynomial R
+ PS ==> InnerTaylorSeries SMP
+ NNI ==> NonNegativeInteger
+ ST ==> Stream
+ StS ==> Stream SMP
+ STPS==>StreamTaylorSeriesOperations
+ STTAYLOR==>StreamTaylorSeriesOperations
+ SUP==> SparseUnivariatePolynomial(SMP)
+ ST2==>StreamFunctions2
+ SMPS==> TaylorSeries(R)
+ L==>List
+ null ==> empty?
+ likeUniv ==> univariate
+ coef ==> coefficient$SUP
+ nil ==> empty
+
+
+ Defn ==> with
+
+ crest:(NNI->( StS-> StS))
+ ++\spad{crest n} is used internally.
+ cfirst:(NNI->( StS-> StS))
+ ++\spad{cfirst n} is used internally.
+ sts2stst:(VarSet,StS)->ST StS
+ ++\spad{sts2stst(v,s)} is used internally.
+ clikeUniv:VarSet->(SMP->SUP)
+ ++\spad{clikeUniv(v)} is used internally.
+ weierstrass:(VarSet,SMPS)->L SMPS
+ ++\spad{weierstrass(v,ts)} where v is a variable and ts is
+ ++ a TaylorSeries, impements the Weierstrass Preparation
+ ++ Theorem. The result is a list of TaylorSeries that
+ ++ are the coefficients of the equivalent series.
+ qqq:(NNI,SMPS,ST SMPS)->((ST SMPS)->ST SMPS)
+ ++\spad{qqq(n,s,st)} is used internally.
+
+ Impl ==> add
+ import TaylorSeries(R)
+ import StreamTaylorSeriesOperations SMP
+ import StreamTaylorSeriesOperations SMPS
+
+
+ map1==>map$(ST2(SMP,SUP))
+ map2==>map$(ST2(StS,SMP))
+ map3==>map$(ST2(StS,StS))
+ transback:ST SMPS->L SMPS
+ transback smps==
+ if null smps
+ then nil()$(L SMPS)
+ else
+ if null first (smps:(ST StS))
+ then nil()$(L SMPS)
+ else
+ cons(map2(first,smps:ST StS):SMPS,
+ transback(map3(rest,smps:ST StS):(ST SMPS)))$(L SMPS)
+
+
+ clikeUniv(var)==likeUniv(#1,var)
+ mind:(NNI,StS)->NNI
+ mind(n, sts)==
+ if null sts
+ then error "no mindegree"
+ else if first sts=0
+ then mind(n+1,rest sts)
+ else n
+ mindegree (sts:StS):NNI== mind(0,sts)
+
+
+ streamlikeUniv:(SUP,NNI)->StS
+ streamlikeUniv(p:SUP,n:NNI): StS ==
+ if n=0
+ then cons(coef (p,0),nil()$StS)
+ else cons(coef (p,n),streamlikeUniv(p,(n-1):NNI))
+
+ transpose:ST StS->ST StS
+ transpose(s:ST StS)==delay(
+ if null s
+ then nil()$(ST StS)
+ else cons(map2(first,s),transpose(map3(rest,rst s))))
+
+ zp==>map$StreamFunctions3(SUP,NNI,StS)
+
+ sts2stst(var, sts)==
+ zp(streamlikeUniv(#1,#2),
+ map1(clikeUniv var, sts),(integers 0):(ST NNI))
+
+ tp:(VarSet,StS)->ST StS
+ tp(v,sts)==transpose sts2stst(v,sts)
+ map4==>map$(ST2 (StS,StS))
+ maptake:(NNI,ST StS)->ST SMPS
+ maptake(n,p)== map4(cfirst n,p) pretend ST SMPS
+ mapdrop:(NNI,ST StS)->ST SMPS
+ mapdrop(n,p)== map4(crest n,p) pretend ST SMPS
+ YSS==>Y$ParadoxicalCombinatorsForStreams(SMPS)
+ weier:(VarSet,StS)->ST SMPS
+ weier(v,sts)==
+ a:=mindegree sts
+ if a=0
+ then error "has constant term"
+ else
+ p:=tp(v,sts) pretend (ST SMPS)
+ b:StS:=rest(((first p pretend StS)),a::NNI)
+ c:=retractIfCan first b
+ c case "failed"=>_
+ error "the coefficient of the lowest degree of the variable should _
+ be a constant"
+ e:=recip b
+ f:= if e case "failed"
+ then error "no reciprocal"
+ else e::StS
+ q:=(YSS qqq(a,f:SMPS,rest p))
+ maptake(a,(p*q) pretend ST StS)
+
+ cfirst n== first(#1,n)$StS
+ crest n== rest(#1,n)$StS
+ qq:(NNI,SMPS,ST SMPS,ST SMPS)->ST SMPS
+ qq(a,e,p,c)==
+ cons(e,(-e)*mapdrop(a,(p*c)pretend(ST StS)))
+ qqq(a,e,p)== qq(a,e,p,#1)
+ wei:(VarSet,SMPS)->ST SMPS
+ wei(v:VarSet,s:SMPS)==weier(v,s:StS)
+ weierstrass(v,smps)== transback wei (v,smps)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package WEIER WeierstrassPreparation>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/wtpol.spad.pamphlet b/src/algebra/wtpol.spad.pamphlet
new file mode 100644
index 00000000..c3ee8d28
--- /dev/null
+++ b/src/algebra/wtpol.spad.pamphlet
@@ -0,0 +1,199 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra wtpol.spad}
+\author{James Davenport}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain WP WeightedPolynomials}
+<<domain WP WeightedPolynomials>>=
+)abbrev domain WP WeightedPolynomials
+++ Author: James Davenport
+++ Date Created: 17 April 1992
+++ Date Last Updated: 12 July 1992
+++ Basic Functions: Ring, changeWeightLevel
+++ Related Constructors: PolynomialRing
+++ Also See: OrdinaryWeightedPolynomials
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents truncated weighted polynomials over a general
+++ (not necessarily commutative) polynomial type. The variables must be
+++ specified, as must the weights.
+++ The representation is sparse
+++ in the sense that only non-zero terms are represented.
+
+WeightedPolynomials(R:Ring,VarSet: OrderedSet, E:OrderedAbelianMonoidSup,
+ P:PolynomialCategory(R,E,VarSet),
+ vl:List VarSet, wl:List NonNegativeInteger,
+ wtlevel:NonNegativeInteger):
+ Ring with
+ if R has CommutativeRing then Algebra(R)
+ coerce: $ -> P
+ ++ convert back into a "P", ignoring weights
+ if R has Field then "/": ($,$) -> Union($,"failed")
+ ++ x/y division (only works if minimum weight
+ ++ of divisor is zero, and if R is a Field)
+ coerce: P -> $
+ ++ coerce(p) coerces p into Weighted form, applying weights and ignoring terms
+ changeWeightLevel: NonNegativeInteger -> Void
+ ++ changeWeightLevel(n) changes the weight level to the new value given:
+ ++ NB: previously calculated terms are not affected
+ ==
+ add
+ --representations
+ Rep := PolynomialRing(P,NonNegativeInteger)
+ p:P
+ w,x1,x2:$
+ n:NonNegativeInteger
+ z:Integer
+ changeWeightLevel(n) ==
+ wtlevel:=n
+ lookupList:List Record(var:VarSet, weight:NonNegativeInteger)
+ if #vl ^= #wl then error "incompatible length lists in WeightedPolynomial"
+ lookupList:=[[v,n] for v in vl for n in wl]
+ -- local operation
+ innercoerce:(p,z) -> $
+ lookup:Varset -> NonNegativeInteger
+ lookup v ==
+ l:=lookupList
+ while l ^= [] repeat
+ v = l.first.var => return l.first.weight
+ l:=l.rest
+ 0
+ innercoerce(p,z) ==
+ z<0 => 0
+ zero? p => 0
+ mv:= mainVariable p
+ mv case "failed" => monomial(p,0)
+ n:=lookup(mv)
+ up:=univariate(p,mv)
+ ans:$
+ ans:=0
+ while not zero? up repeat
+ d:=degree up
+ f:=n*d
+ lcup:=leadingCoefficient up
+ up:=up-leadingMonomial up
+ mon:=monomial(1,mv,d)
+ f<=z =>
+ tmp:= innercoerce(lcup,z-f)
+ while not zero? tmp repeat
+ ans:=ans+ monomial(mon*leadingCoefficient(tmp),degree(tmp)+f)
+ tmp:=reductum tmp
+ ans
+ coerce(p):$ == innercoerce(p,wtlevel)
+ coerce(w):P == "+"/[c for c in coefficients w]
+ coerce(p:$):OutputForm ==
+ zero? p => (0$Integer)::OutputForm
+ degree p = 0 => leadingCoefficient(p):: OutputForm
+ reduce("+",(reverse [paren(c::OutputForm) for c in coefficients p])
+ ::List OutputForm)
+ 0 == 0$Rep
+ 1 == 1$Rep
+ x1 = x2 ==
+ -- Note that we must strip out any terms greater than wtlevel
+ while degree x1 > wtlevel repeat
+ x1 := reductum x1
+ while degree x2 > wtlevel repeat
+ x2 := reductum x2
+ x1 =$Rep x2
+ x1 + x2 == x1 +$Rep x2
+ -x1 == -(x1::Rep)
+ x1 * x2 ==
+ -- Note that this is probably an extremely inefficient definition
+ w:=x1 *$Rep x2
+ while degree(w) > wtlevel repeat
+ w:=reductum w
+ w
+
+@
+\section{domain OWP OrdinaryWeightedPolynomials}
+<<domain OWP OrdinaryWeightedPolynomials>>=
+)abbrev domain OWP OrdinaryWeightedPolynomials
+++ Author: James Davenport
+++ Date Created: 17 April 1992
+++ Date Last Updated: 12 July 1992
+++ Basic Functions: Ring, changeWeightLevel
+++ Related Constructors: WeightedPolynomials
+++ Also See: PolynomialRing
+++ AMS classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents truncated weighted polynomials over the
+++ "Polynomial" type. The variables must be
+++ specified, as must the weights.
+++ The representation is sparse
+++ in the sense that only non-zero terms are represented.
+
+OrdinaryWeightedPolynomials(R:Ring,
+ vl:List Symbol, wl:List NonNegativeInteger,
+ wtlevel:NonNegativeInteger):
+ Ring with
+ if R has CommutativeRing then Algebra(R)
+ coerce: $ -> Polynomial(R)
+ ++ coerce(p) converts back into a Polynomial(R), ignoring weights
+ coerce: Polynomial(R) -> $
+ ++ coerce(p) coerces a Polynomial(R) into Weighted form,
+ ++ applying weights and ignoring terms
+ if R has Field then "/": ($,$) -> Union($,"failed")
+ ++ x/y division (only works if minimum weight
+ ++ of divisor is zero, and if R is a Field)
+ changeWeightLevel: NonNegativeInteger -> Void
+ ++ changeWeightLevel(n) This changes the weight level to the new value given:
+ ++ NB: previously calculated terms are not affected
+ == WeightedPolynomials(R,Symbol,IndexedExponents(Symbol),
+ Polynomial(R),
+ vl,wl,wtlevel)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain WP WeightedPolynomials>>
+<<domain OWP OrdinaryWeightedPolynomials>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/xlpoly.spad.pamphlet b/src/algebra/xlpoly.spad.pamphlet
new file mode 100644
index 00000000..c863ac2f
--- /dev/null
+++ b/src/algebra/xlpoly.spad.pamphlet
@@ -0,0 +1,1216 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra xlpoly.spad}
+\author{Michel Petitot}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain MAGMA Magma}
+<<domain MAGMA Magma>>=
+)abbrev domain MAGMA Magma
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type is the basic representation of
+++ parenthesized words (binary trees over arbitrary symbols)
+++ useful in \spadtype{LiePolynomial}. \newline Author: Michel Petitot (petitot@lifl.fr).
+
+Magma(VarSet:OrderedSet):Public == Private where
+ WORD ==> OrderedFreeMonoid(VarSet)
+ EX ==> OutputForm
+
+ Public == Join(OrderedSet,RetractableTo VarSet) with
+ "*" : ($,$) -> $
+ ++ \axiom{x*y} returns the tree \axiom{[x,y]}.
+ coerce : $ -> WORD
+ ++ \axiom{coerce(x)} returns the element of \axiomType{OrderedFreeMonoid}(VarSet)
+ ++ corresponding to \axiom{x} by removing parentheses.
+ first : $ -> VarSet
+ ++ \axiom{first(x)} returns the first entry of the tree \axiom{x}.
+ left : $ -> $
+ ++ \axiom{left(x)} returns left subtree of \axiom{x} or
+ ++ error if \axiomOpFrom{retractable?}{Magma}(\axiom{x}) is true.
+ length : $ -> PositiveInteger
+ ++ \axiom{length(x)} returns the number of entries in \axiom{x}.
+ lexico : ($,$) -> Boolean
+ ++ \axiom{lexico(x,y)} returns \axiom{true} iff \axiom{x} is smaller than
+ ++ \axiom{y} w.r.t. the lexicographical ordering induced by \axiom{VarSet}.
+ ++ N.B. This operation does not take into account the tree structure of
+ ++ its arguments. Thus this is not a total ordering.
+ mirror : $ -> $
+ ++ \axiom{mirror(x)} returns the reversed word of \axiom{x}.
+ ++ That is \axiom{x} itself if \axiomOpFrom{retractable?}{Magma}(\axiom{x}) is true and
+ ++ \axiom{mirror(z) * mirror(y)} if \axiom{x} is \axiom{y*z}.
+ rest : $ -> $
+ ++ \axiom{rest(x)} return \axiom{x} without the first entry or
+ ++ error if \axiomOpFrom{retractable?}{Magma}(\axiom{x}) is true.
+ retractable? : $ -> Boolean
+ ++ \axiom{retractable?(x)} tests if \axiom{x} is a tree with only one entry.
+ right : $ -> $
+ ++ \axiom{right(x)} returns right subtree of \axiom{x} or
+ ++ error if \axiomOpFrom{retractable?}{Magma}(\axiom{x}) is true.
+ varList : $ -> List VarSet
+ ++ \axiom{varList(x)} returns the list of distinct entries of \axiom{x}.
+
+ Private == add
+ -- representation
+ VWORD := Record(left:$ ,right:$)
+ Rep:= Union(VarSet,VWORD)
+
+ recursif: ($,$) -> Boolean
+
+ -- define
+ x:$ = y:$ ==
+ x case VarSet =>
+ y case VarSet => x::VarSet = y::VarSet
+ false
+ y case VWORD => x::VWORD = y::VWORD
+ false
+
+ varList x ==
+ x case VarSet => [x::VarSet]
+ lv: List VarSet := setUnion(varList x.left, varList x.right)
+ sort_!(lv)
+
+ left x ==
+ x case VarSet => error "x has only one entry"
+ x.left
+
+ right x ==
+ x case VarSet => error "x has only one entry"
+ x.right
+ retractable? x == (x case VarSet)
+
+ retract x ==
+ x case VarSet => x::VarSet
+ error "Not retractable"
+
+ retractIfCan x == (retractable? x => x::VarSet ; "failed")
+ coerce(l:VarSet):$ == l
+
+ mirror x ==
+ x case VarSet => x
+ [mirror x.right, mirror x.left]$VWORD
+
+ coerce(x:$): WORD ==
+ x case VarSet => x::VarSet::WORD
+ x.left::WORD * x.right::WORD
+
+ coerce(x:$):EX ==
+ x case VarSet => x::VarSet::EX
+ bracket [x.left::EX, x.right::EX]
+
+ x * y == [x,y]$VWORD
+
+ first x ==
+ x case VarSet => x::VarSet
+ first x.left
+
+ rest x ==
+ x case VarSet => error "rest$Magma: inexistant rest"
+ lx:$ := x.left
+ lx case VarSet => x.right
+ [rest lx , x.right]$VWORD
+
+ length x ==
+ x case VarSet => 1
+ length(x.left) + length(x.right)
+
+ recursif(x,y) ==
+ x case VarSet =>
+ y case VarSet => x::VarSet < y::VarSet
+ true
+ y case VarSet => false
+ x.left = y.left => x.right < y.right
+ x.left < y.left
+
+ lexico(x,y) == -- peut etre amelioree !!!!!!!!!!!
+ x case VarSet =>
+ y case VarSet => x::VarSet < y::VarSet
+ x::VarSet <= first y
+ y case VarSet => first x < retract y
+ fx:VarSet := first x ; fy:VarSet := first y
+ fx = fy => lexico(rest x , rest y)
+ fx < fy
+
+ x < y == -- recursif par longueur
+ lx,ly: PositiveInteger
+ lx:= length x ; ly:= length y
+ lx = ly => recursif(x,y)
+ lx < ly
+
+@
+\section{domain LWORD LyndonWord}
+A function $f \epsilon \lbrace 0,1 \rbrace$ is called acyclic if
+$C(F)$ consists of $n$ different objects. The canonical representative
+of the orbit of an acyclic function is usually called a Lyndon Word \cite{1}.
+If $f$ is acyclic, then all elements in the orbit $C(f)$ are acyclic
+as well, and we call $C(f)$ an acyclic orbit.
+<<domain LWORD LyndonWord>>=
+)abbrev domain LWORD LyndonWord
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References: Free Lie Algebras by C. Reutenauer (Oxford science publications).
+++ Description:
+++ Lyndon words over arbitrary (ordered) symbols:
+++ see Free Lie Algebras by C. Reutenauer (Oxford science publications).
+++ A Lyndon word is a word which is smaller than any of its right factors
+++ w.r.t. the pure lexicographical ordering.
+++ If \axiom{a} and \axiom{b} are two Lyndon words such that \axiom{a < b}
+++ holds w.r.t lexicographical ordering then \axiom{a*b} is a Lyndon word.
+++ Parenthesized Lyndon words can be generated from symbols by using the following
+++ rule: \axiom{[[a,b],c]} is a Lyndon word iff \axiom{a*b < c <= b} holds.
+++ Lyndon words are internally represented by binary trees using the
+++ \spadtype{Magma} domain constructor.
+++ Two ordering are provided: lexicographic and
+++ length-lexicographic. \newline
+++ Author : Michel Petitot (petitot@lifl.fr).
+
+LyndonWord(VarSet:OrderedSet):Public == Private where
+ OFMON ==> OrderedFreeMonoid(VarSet)
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ OF ==> OutputForm
+ ARRAY1==> OneDimensionalArray
+
+ Public == Join(OrderedSet,RetractableTo VarSet) with
+ retractable? : $ -> Boolean
+ ++ \axiom{retractable?(x)} tests if \axiom{x} is a tree with only one entry.
+ left : $ -> $
+ ++ \axiom{left(x)} returns left subtree of \axiom{x} or
+ ++ error if \axiomOpFrom{retractable?}{LyndonWord}(\axiom{x}) is true.
+ right : $ -> $
+ ++ \axiom{right(x)} returns right subtree of \axiom{x} or
+ ++ error if \axiomOpFrom{retractable?}{LyndonWord}(\axiom{x}) is true.
+ length : $ -> PI
+ ++ \axiom{length(x)} returns the number of entries in \axiom{x}.
+ lexico : ($,$) -> Boolean
+ ++ \axiom{lexico(x,y)} returns \axiom{true} iff \axiom{x} is smaller than
+ ++ \axiom{y} w.r.t. the lexicographical ordering induced by \axiom{VarSet}.
+ coerce : $ -> OFMON
+ ++ \axiom{coerce(x)} returns the element of \axiomType{OrderedFreeMonoid}(VarSet)
+ ++ corresponding to \axiom{x}.
+ coerce : $ -> Magma VarSet
+ ++ \axiom{coerce(x)} returns the element of \axiomType{Magma}(VarSet)
+ ++ corresponding to \axiom{x}.
+ factor : OFMON -> List $
+ ++ \axiom{factor(x)} returns the decreasing factorization into Lyndon words.
+ lyndon?: OFMON -> Boolean
+ ++ \axiom{lyndon?(w)} test if \axiom{w} is a Lyndon word.
+ lyndon : OFMON -> $
+ ++ \axiom{lyndon(w)} convert \axiom{w} into a Lyndon word,
+ ++ error if \axiom{w} is not a Lyndon word.
+ lyndonIfCan : OFMON -> Union($, "failed")
+ ++ \axiom{lyndonIfCan(w)} convert \axiom{w} into a Lyndon word.
+ varList : $ -> List VarSet
+ ++ \axiom{varList(x)} returns the list of distinct entries of \axiom{x}.
+ LyndonWordsList1: (List VarSet, PI) -> ARRAY1 List $
+ ++ \axiom{LyndonWordsList1(vl, n)} returns an array of lists of Lyndon
+ ++ words over the alphabet \axiom{vl}, up to order \axiom{n}.
+ LyndonWordsList : (List VarSet, PI) -> List $
+ ++ \axiom{LyndonWordsList(vl, n)} returns the list of Lyndon
+ ++ words over the alphabet \axiom{vl}, up to order \axiom{n}.
+
+ Private == Magma(VarSet) add
+ -- Representation
+ Rep:= Magma(VarSet)
+
+ -- Fonctions locales
+ LetterList : OFMON -> List VarSet
+ factor1 : (List $, $, List $) -> List $
+
+ -- Definitions
+ lyndon? w ==
+ w = 1$OFMON => false
+ f: OFMON := rest w
+ while f ^= 1$OFMON repeat
+ not lexico(w,f) => return false
+ f := rest f
+ true
+
+ lyndonIfCan w ==
+ l: List $ := factor w
+ # l = 1 => first l
+ "failed"
+
+ lyndon w ==
+ l: List $ := factor w
+ # l = 1 => first l
+ error "This word is not a Lyndon word"
+
+ LetterList w ==
+ w = 1 => []
+ cons(first w , LetterList rest w)
+
+ factor1 (gauche, x, droite) ==
+ g: List $ := gauche; d: List $ := droite
+ while not null g repeat ++ (l in g or l=x) et u in d
+ lexico( g.first , x ) => ++ => right(l) >= u
+ x := g.first *$Rep x -- crochetage
+ null(d) => g := rest g
+ g := cons( x, rest g) -- mouvement a droite
+ x := first d
+ d := rest d
+ d := cons( x , d) -- mouvement a gauche
+ x := first g
+ g := rest g
+ return cons(x, d)
+
+ factor w ==
+ w = 1 => []
+ l : List $ := reverse [ u::$ for u in LetterList w]
+ factor1( rest l, first l , [] )
+
+ x < y == -- lexicographique par longueur
+ lx,ly: PI
+ lx:= length x ; ly:= length y
+ lx = ly => lexico(x,y)
+ lx < ly
+
+ coerce(x:$):OF == bracket(x::OFMON::OF)
+ coerce(x:$):Magma VarSet == x::Rep
+
+ LyndonWordsList1 (vl,n) == -- a ameliorer !!!!!!!!!!!
+ null vl => error "empty list"
+ base: ARRAY1 List $ := new(n::I::NNI ,[])
+
+ -- mots de longueur 1
+ lbase1:List $ := [w::$ for w in sort(vl)]
+ base.1 := lbase1
+
+ -- calcul des mots de longueur ll
+ for ll in 2..n:I repeat
+ lbase1 := []
+ for a in base(1) repeat -- lettre + mot
+ for b in base(ll-1) repeat
+ if lexico(a,b) then lbase1:=cons(a*b,lbase1)
+
+ for i in 2..ll-1 repeat -- mot + mot
+ for a in base(i) repeat
+ for b in base(ll-i) repeat
+ if lexico(a,b) and (lexico(b,right a) or b = right a )
+ then lbase1:=cons(a*b,lbase1)
+
+ base(ll):= sort_!(lexico, lbase1)
+ return base
+
+ LyndonWordsList (vl,n) ==
+ v:ARRAY1 List $ := LyndonWordsList1(vl,n)
+ "append"/ [v.i for i in 1..n]
+
+@
+\section{category LIECAT LieAlgebra}
+<<category LIECAT LieAlgebra>>=
+)abbrev category LIECAT LieAlgebra
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of Lie Algebras.
+++ It is used by the following domains of non-commutative algebra:
+++ \axiomType{LiePolynomial} and
+++ \axiomType{XPBWPolynomial}. \newline Author : Michel Petitot (petitot@lifl.fr).
+LieAlgebra(R: CommutativeRing): Category == Module(R) with
+ --attributes
+ NullSquare
+ ++ \axiom{NullSquare} means that \axiom{[x,x] = 0} holds.
+ JacobiIdentity
+ ++ \axiom{JacobiIdentity} means that \axiom{[x,[y,z]]+[y,[z,x]]+[z,[x,y]] = 0} holds.
+ --exports
+ construct: ($,$) -> $
+ ++ \axiom{construct(x,y)} returns the Lie bracket of \axiom{x} and \axiom{y}.
+ if R has Field then
+ "/" : ($,R) -> $
+ ++ \axiom{x/r} returns the division of \axiom{x} by \axiom{r}.
+
+
+ add
+ if R has Field then x / r == inv(r)$R * x
+
+@
+\section{category FLALG FreeLieAlgebra}
+<<category FLALG FreeLieAlgebra>>=
+)abbrev category FLALG FreeLieAlgebra
+++ Author: Michel Petitot (petitot@lifl.fr)
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The category of free Lie algebras.
+++ It is used by domains of non-commutative algebra:
+++ \spadtype{LiePolynomial} and
+++ \spadtype{XPBWPolynomial}. \newline Author: Michel Petitot (petitot@lifl.fr)
+
+FreeLieAlgebra(VarSet:OrderedSet, R:CommutativeRing) :Category == CatDef where
+ XRPOLY ==> XRecursivePolynomial(VarSet,R)
+ XDPOLY ==> XDistributedPolynomial(VarSet,R)
+ RN ==> Fraction Integer
+ LWORD ==> LyndonWord(VarSet)
+
+ CatDef == Join(LieAlgebra(R)) with
+ coef : (XRPOLY , $) -> R
+ ++ \axiom{coef(x,y)} returns the scalar product of \axiom{x} by \axiom{y},
+ ++ the set of words being regarded as an orthogonal basis.
+ coerce : VarSet -> $
+ ++ \axiom{coerce(x)} returns \axiom{x} as a Lie polynomial.
+ coerce : $ -> XDPOLY
+ ++ \axiom{coerce(x)} returns \axiom{x} as distributed polynomial.
+ coerce : $ -> XRPOLY
+ ++ \axiom{coerce(x)} returns \axiom{x} as a recursive polynomial.
+ degree : $ -> NonNegativeInteger
+ ++ \axiom{degree(x)} returns the greatest length of a word in the support of \axiom{x}.
+ --if R has Module(RN) then
+ -- Hausdorff : ($,$,PositiveInteger) -> $
+ lquo : (XRPOLY , $) -> XRPOLY
+ ++ \axiom{lquo(x,y)} returns the left simplification of \axiom{x} by \axiom{y}.
+ rquo : (XRPOLY , $) -> XRPOLY
+ ++ \axiom{rquo(x,y)} returns the right simplification of \axiom{x} by \axiom{y}.
+ LiePoly : LWORD -> $
+ ++ \axiom{LiePoly(l)} returns the bracketed form of \axiom{l} as a Lie polynomial.
+ mirror : $ -> $
+ ++ \axiom{mirror(x)} returns \axiom{Sum(r_i mirror(w_i))}
+ ++ if \axiom{x} is \axiom{Sum(r_i w_i)}.
+ trunc : ($, NonNegativeInteger) -> $
+ ++ \axiom{trunc(p,n)} returns the polynomial \axiom{p}
+ ++ truncated at order \axiom{n}.
+ varList : $ -> List VarSet
+ ++ \axiom{varList(x)} returns the list of distinct entries of \axiom{x}.
+ eval : ($, VarSet, $) -> $
+ ++ \axiom{eval(p, x, v)} replaces \axiom{x} by \axiom{v} in \axiom{p}.
+ eval : ($, List VarSet, List $) -> $
+ ++ \axiom{eval(p, [x1,...,xn], [v1,...,vn])} replaces \axiom{xi} by \axiom{vi}
+ ++ in \axiom{p}.
+
+@
+\section{package XEXPPKG XExponentialPackage}
+<<package XEXPPKG XExponentialPackage>>=
+)abbrev package XEXPPKG XExponentialPackage
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This package provides computations of logarithms and exponentials
+++ for polynomials in non-commutative
+++ variables. \newline Author: Michel Petitot (petitot@lifl.fr).
+
+XExponentialPackage(R, VarSet, XPOLY): Public == Private where
+ RN ==> Fraction Integer
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ R : Join(Ring, Module RN)
+ -- R : Field
+ VarSet : OrderedSet
+ XPOLY : XPolynomialsCat(VarSet, R)
+
+ Public == with
+ exp: (XPOLY, NNI) -> XPOLY
+ ++ \axiom{exp(p, n)} returns the exponential of \axiom{p}
+ ++ truncated at order \axiom{n}.
+ log: (XPOLY, NNI) -> XPOLY
+ ++ \axiom{log(p, n)} returns the logarithm of \axiom{p}
+ ++ truncated at order \axiom{n}.
+ Hausdorff: (XPOLY, XPOLY, NNI) -> XPOLY
+ ++ \axiom{Hausdorff(a,b,n)} returns log(exp(a)*exp(b))
+ ++ truncated at order \axiom{n}.
+
+ Private == add
+
+ log (p,n) ==
+ p1 : XPOLY := p - 1
+ not quasiRegular? p1 =>
+ error "constant term <> 1, impossible log"
+ s : XPOLY := 0 -- resultat
+ k : I := n :: I
+ for i in 1 .. n repeat
+ k1 :RN := 1/k
+ k2 : R := k1 * 1$R
+ s := trunc( trunc(p1,i) * (k2 :: XPOLY - s) , i)
+ k := k - 1
+ s
+
+ exp (p,n) ==
+ not quasiRegular? p =>
+ error "constant term <> 0, exp impossible"
+ p = 0 => 1
+ s : XPOLY := 1$XPOLY -- resultat
+ k : I := n :: I
+ for i in 1 .. n repeat
+ k1 :RN := 1/k
+ k2 : R := k1 * 1$R
+ s := trunc( 1 +$XPOLY k2 * trunc(p,i) * s , i)
+ k := k - 1
+ s
+
+ Hausdorff(p,q,n) ==
+ p1: XPOLY := exp(p,n)
+ q1: XPOLY := exp(q,n)
+ log(p1*q1, n)
+
+@
+\section{domain LPOLY LiePolynomial}
+<<domain LPOLY LiePolynomial>>=
+)abbrev domain LPOLY LiePolynomial
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:Free Lie Algebras by C. Reutenauer (Oxford science publications).
+++ Description:
+++ This type supports Lie polynomials in Lyndon basis
+++ see Free Lie Algebras by C. Reutenauer
+++ (Oxford science publications). \newline Author: Michel Petitot (petitot@lifl.fr).
+
+LiePolynomial(VarSet:OrderedSet, R:CommutativeRing) : Public == Private where
+ MAGMA ==> Magma(VarSet)
+ LWORD ==> LyndonWord(VarSet)
+ WORD ==> OrderedFreeMonoid(VarSet)
+ XDPOLY ==> XDistributedPolynomial(VarSet,R)
+ XRPOLY ==> XRecursivePolynomial(VarSet,R)
+ NNI ==> NonNegativeInteger
+ RN ==> Fraction Integer
+ EX ==> OutputForm
+ TERM ==> Record(k: LWORD, c: R)
+
+ Public == Join(FreeLieAlgebra(VarSet,R), FreeModuleCat(R,LWORD)) with
+ LiePolyIfCan: XDPOLY -> Union($, "failed")
+ ++ \axiom{LiePolyIfCan(p)} returns \axiom{p} in Lyndon basis
+ ++ if \axiom{p} is a Lie polynomial, otherwise \axiom{"failed"}
+ ++ is returned.
+ construct: (LWORD, LWORD) -> $
+ ++ \axiom{construct(x,y)} returns the Lie bracket \axiom{[x,y]}.
+ construct: (LWORD, $) -> $
+ ++ \axiom{construct(x,y)} returns the Lie bracket \axiom{[x,y]}.
+ construct: ($, LWORD) -> $
+ ++ \axiom{construct(x,y)} returns the Lie bracket \axiom{[x,y]}.
+
+ Private == FreeModule1(R, LWORD) add
+ import(TERM)
+
+ --representation
+ Rep := List TERM
+
+ -- fonctions locales
+ cr1 : (LWORD, $ ) -> $
+ cr2 : ($, LWORD ) -> $
+ crw : (LWORD, LWORD) -> $ -- crochet de 2 mots de Lyndon
+ DPoly: LWORD -> XDPOLY
+ lquo1: (XRPOLY , LWORD) -> XRPOLY
+ lyndon: (LWORD, LWORD) -> $
+ makeLyndon: (LWORD, LWORD) -> LWORD
+ rquo1: (XRPOLY , LWORD) -> XRPOLY
+ RPoly: LWORD -> XRPOLY
+ eval1: (LWORD, VarSet, $) -> $ -- 08/03/98
+ eval2: (LWORD, List VarSet, List $) -> $ -- 08/03/98
+
+
+ -- Evaluation
+ eval1(lw,v,nv) == -- 08/03/98
+ not member?(v, varList(lw)$LWORD) => LiePoly lw
+ (s := retractIfCan(lw)$LWORD) case VarSet =>
+ if (s::VarSet) = v then nv else LiePoly lw
+ l: LWORD := left lw
+ r: LWORD := right lw
+ construct(eval1(l,v,nv), eval1(r,v,nv))
+
+ eval2(lw,lv,lnv) == -- 08/03/98
+ p: Integer
+ (s := retractIfCan(lw)$LWORD) case VarSet =>
+ p := position(s::VarSet, lv)$List(VarSet)
+ if p=0 then lw::$ else elt(lnv,p)$List($)
+ l: LWORD := left lw
+ r: LWORD := right lw
+ construct(eval2(l,lv,lnv), eval2(r,lv,lnv))
+
+ eval(p:$, v: VarSet, nv: $): $ == -- 08/03/98
+ +/ [t.c * eval1(t.k, v, nv) for t in p]
+
+ eval(p:$, lv: List(VarSet), lnv: List($)): $ == -- 08/03/98
+ +/ [t.c * eval2(t.k, lv, lnv) for t in p]
+
+ lquo1(p,lw) ==
+ constant? p => 0$XRPOLY
+ retractable? lw => lquo(p, retract lw)$XRPOLY
+ lquo1(lquo1(p, left lw),right lw) - lquo1(lquo1(p, right lw),left lw)
+ rquo1(p,lw) ==
+ constant? p => 0$XRPOLY
+ retractable? lw => rquo(p, retract lw)$XRPOLY
+ rquo1(rquo1(p, left lw),right lw) - rquo1(rquo1(p, right lw),left lw)
+
+ coef(p, lp) == coef(p, lp::XRPOLY)$XRPOLY
+
+ lquo(p, lp) ==
+ lp = 0 => 0$XRPOLY
+ +/ [t.c * lquo1(p,t.k) for t in lp]
+
+ rquo(p, lp) ==
+ lp = 0 => 0$XRPOLY
+ +/ [t.c * rquo1(p,t.k) for t in lp]
+
+ LiePolyIfCan p == -- inefficace a cause de la rep. de XDPOLY
+ not quasiRegular? p => "failed"
+ p1: XDPOLY := p ; r:$ := 0
+ while p1 ^= 0 repeat
+ t: Record(k:WORD, c:R) := mindegTerm p1
+ w: WORD := t.k; coef:R := t.c
+ (l := lyndonIfCan(w)$LWORD) case "failed" => return "failed"
+ lp:$ := coef * LiePoly(l::LWORD)
+ r := r + lp
+ p1 := p1 - lp::XDPOLY
+ r
+
+ --definitions locales
+ makeLyndon(u,v) == (u::MAGMA * v::MAGMA) pretend LWORD
+
+ crw(u,v) == -- u et v sont des mots de Lyndon
+ u = v => 0
+ lexico(u,v) => lyndon(u,v)
+ - lyndon (v,u)
+
+ lyndon(u,v) == -- u et v sont des mots de Lyndon tq u < v
+ retractable? u => monom(makeLyndon(u,v),1)
+ u1: LWORD := left u
+ u2: LWORD := right u
+ lexico(u2,v) => cr1(u1, lyndon(u2,v)) + cr2(lyndon(u1,v), u2)
+ monom(makeLyndon(u,v),1)
+
+ cr1 (l, p) ==
+ +/[t.c * crw(l, t.k) for t in p]
+
+ cr2 (p, l) ==
+ +/[t.c * crw(t.k, l) for t in p]
+
+ DPoly w ==
+ retractable? w => retract(w) :: XDPOLY
+ l:XDPOLY := DPoly left w
+ r:XDPOLY := DPoly right w
+ l*r - r*l
+
+ RPoly w ==
+ retractable? w => retract(w) :: XRPOLY
+ l:XRPOLY := RPoly left w
+ r:XRPOLY := RPoly right w
+ l*r - r*l
+
+ -- definitions
+
+ coerce(v:VarSet) == monom(v::LWORD , 1)
+
+ construct(x:$ , y:$):$ ==
+ +/[t.c * cr1(t.k, y) for t in x]
+
+ construct(l:LWORD , p:$):$ == cr1(l,p)
+ construct(p:$ , l:LWORD):$ == cr2(p,l)
+ construct(u:LWORD , v:LWORD):$ == crw(u,v)
+
+ coerce(p:$):XDPOLY ==
+ +/ [t.c * DPoly(t.k) for t in p]
+
+ coerce(p:$):XRPOLY ==
+ +/ [t.c * RPoly(t.k) for t in p]
+
+ LiePoly(l) == monom(l,1)
+
+ varList p ==
+ le : List VarSet := "setUnion"/[varList(t.k)$LWORD for t in p]
+ sort(le)$List(VarSet)
+
+ mirror p ==
+ [[t.k, (odd? length t.k => t.c; -t.c)]$TERM for t in p]
+
+ trunc(p, n) ==
+ degree(p) > n => trunc( reductum p , n)
+ p
+
+ degree p ==
+ null p => 0
+ length( p.first.k)$LWORD
+
+ -- ListOfTerms p == p pretend List TERM
+
+-- coerce(x) : EX ==
+-- null x => (0$R) :: EX
+-- le : List EX := nil
+-- for rec in x repeat
+-- rec.c = 1$R => le := cons(rec.k :: EX, le)
+-- le := cons(mkBinary("*"::EX, rec.c :: EX, rec.k :: EX), le)
+-- 1 = #le => first le
+-- mkNary("+" :: EX,le)
+
+@
+\section{domain PBWLB PoincareBirkhoffWittLyndonBasis}
+<<domain PBWLB PoincareBirkhoffWittLyndonBasis>>=
+)abbrev domain PBWLB PoincareBirkhoffWittLyndonBasis
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain provides the internal representation
+++ of polynomials in non-commutative variables written
+++ over the Poincare-Birkhoff-Witt basis.
+++ See the \spadtype{XPBWPolynomial} domain constructor.
+++ See Free Lie Algebras by C. Reutenauer
+++ (Oxford science publications). \newline Author: Michel Petitot (petitot@lifl.fr).
+
+PoincareBirkhoffWittLyndonBasis(VarSet: OrderedSet): Public == Private where
+ WORD ==> OrderedFreeMonoid(VarSet)
+ LWORD ==> LyndonWord(VarSet)
+ LWORDS ==> List(LWORD)
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ EX ==> OutputForm
+
+ Public == Join(OrderedSet, RetractableTo LWORD) with
+ 1: constant -> %
+ ++ \spad{1} returns the empty list.
+ coerce : $ -> WORD
+ ++ \spad{coerce([l1]*[l2]*...[ln])} returns the word \spad{l1*l2*...*ln},
+ ++ where \spad{[l_i]} is the backeted form of the Lyndon word \spad{l_i}.
+ coerce : VarSet -> $
+ ++ \spad{coerce(v)} return \spad{v}
+ first : $ -> LWORD
+ ++ \spad{first([l1]*[l2]*...[ln])} returns the Lyndon word \spad{l1}.
+ length : $ -> NNI
+ ++ \spad{length([l1]*[l2]*...[ln])} returns the length of the word \spad{l1*l2*...*ln}.
+ ListOfTerms : $ -> LWORDS
+ ++ \spad{ListOfTerms([l1]*[l2]*...[ln])} returns the list of words \spad{l1, l2, .... ln}.
+ rest : $ -> $
+ ++ \spad{rest([l1]*[l2]*...[ln])} returns the list \spad{l2, .... ln}.
+ retractable? : $ -> Boolean
+ ++ \spad{retractable?([l1]*[l2]*...[ln])} returns true iff \spad{n} equals \spad{1}.
+ varList : $ -> List VarSet
+ ++ \spad{varList([l1]*[l2]*...[ln])} returns the list of
+ ++ variables in the word \spad{l1*l2*...*ln}.
+
+ Private == add
+
+ -- Representation
+ Rep := LWORDS
+
+ -- Locales
+ recursif: ($,$) -> Boolean
+
+ -- Define
+ 1 == nil
+
+ x = y == x =$Rep y
+
+ varList x ==
+ null x => nil
+ le: List VarSet := "setUnion"/ [varList$LWORD l for l in x]
+
+ first x == first(x)$Rep
+ rest x == rest(x)$Rep
+
+ coerce(v: VarSet):$ == [ v::LWORD ]
+ coerce(l: LWORD):$ == [l]
+ ListOfTerms(x:$):LWORDS == x pretend LWORDS
+
+ coerce(x:$):WORD ==
+ null x => 1
+ x.first :: WORD *$WORD coerce(x.rest)
+
+ coerce(x:$):EX ==
+ null x => outputForm(1$Integer)$EX
+ reduce(_* ,[l :: EX for l in x])$List(EX)
+
+ retractable? x ==
+ null x => false
+ null x.rest
+
+ retract x ==
+ #x ^= 1 => error "cannot convert to Lyndon word"
+ x.first
+
+ retractIfCan x ==
+ retractable? x => x.first
+ "failed"
+
+ length x ==
+ n: Integer := +/[ length l for l in x]
+ n::NNI
+
+ recursif(x, y) ==
+ null y => false
+ null x => true
+ x.first = y.first => recursif(rest(x), rest(y))
+ lexico(x.first, y.first)
+
+ x < y ==
+ lx: NNI := length x; ly: NNI := length y
+ lx = ly => recursif(x,y)
+ lx < ly
+
+@
+\section{domain XPBWPOLY XPBWPolynomial}
+<<domain XPBWPOLY XPBWPolynomial>>=
+)abbrev domain XPBWPOLY XPBWPolynomial
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain constructor implements polynomials in non-commutative
+++ variables written in the Poincare-Birkhoff-Witt basis from the
+++ Lyndon basis.
+++ These polynomials can be used to compute Baker-Campbell-Hausdorff
+++ relations. \newline Author: Michel Petitot (petitot@lifl.fr).
+
+XPBWPolynomial(VarSet:OrderedSet,R:CommutativeRing): XDPcat == XDPdef where
+
+ WORD ==> OrderedFreeMonoid(VarSet)
+ LWORD ==> LyndonWord(VarSet)
+ LWORDS ==> List LWORD
+ BASIS ==> PoincareBirkhoffWittLyndonBasis(VarSet)
+ TERM ==> Record(k:BASIS, c:R)
+ LTERMS ==> List(TERM)
+ LPOLY ==> LiePolynomial(VarSet,R)
+ EX ==> OutputForm
+ XDPOLY ==> XDistributedPolynomial(VarSet,R)
+ XRPOLY ==> XRecursivePolynomial(VarSet,R)
+ TERM1 ==> Record(k:LWORD, c:R)
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ RN ==> Fraction(Integer)
+
+ XDPcat == Join(XPolynomialsCat(VarSet,R), FreeModuleCat(R, BASIS)) with
+ coerce : LPOLY -> $
+ ++ \axiom{coerce(p)} returns \axiom{p}.
+ coerce : $ -> XDPOLY
+ ++ \axiom{coerce(p)} returns \axiom{p} as a distributed polynomial.
+ coerce : $ -> XRPOLY
+ ++ \axiom{coerce(p)} returns \axiom{p} as a recursive polynomial.
+ LiePolyIfCan: $ -> Union(LPOLY,"failed")
+ ++ \axiom{LiePolyIfCan(p)} return \axiom{p} if \axiom{p} is a Lie polynomial.
+ product : ($,$,NNI) -> $ -- produit tronque a l'ordre n
+ ++ \axiom{product(a,b,n)} returns \axiom{a*b} (truncated up to order \axiom{n}).
+
+ if R has Module(RN) then
+ exp : ($,NNI) -> $
+ ++ \axiom{exp(p,n)} returns the exponential of \axiom{p}
+ ++ (truncated up to order \axiom{n}).
+ log : ($,NNI) -> $
+ ++ \axiom{log(p,n)} returns the logarithm of \axiom{p}
+ ++ (truncated up to order \axiom{n}).
+
+ XDPdef == FreeModule1(R,BASIS) add
+ import(TERM)
+
+ -- Representation
+ Rep:= LTERMS
+
+ -- local functions
+ prod1: (BASIS, $) -> $
+ prod2: ($, BASIS) -> $
+ prod : (BASIS, BASIS) -> $
+
+ prod11: (BASIS, $, NNI) -> $
+ prod22: ($, BASIS, NNI) -> $
+
+ outForm : TERM -> EX
+ Dexpand : BASIS -> XDPOLY
+ Rexpand : BASIS -> XRPOLY
+ process : (List LWORD, LWORD, List LWORD) -> $
+ mirror1 : BASIS -> $
+
+ -- functions locales
+ outForm t ==
+ t.c =$R 1 => t.k :: EX
+ t.k =$BASIS 1 => t.c :: EX
+ t.c::EX * t.k ::EX
+
+ prod1(b:BASIS, p:$):$ ==
+ +/ [t.c * prod(b, t.k) for t in p]
+
+ prod2(p:$, b:BASIS):$ ==
+ +/ [t.c * prod(t.k, b) for t in p]
+
+ prod11(b,p,n) ==
+ limit: I := n -$I length b
+ +/ [t.c * prod(b, t.k) for t in p| length(t.k) :: I <= limit]
+
+ prod22(p,b,n) ==
+ limit: I := n -$I length b
+ +/ [t.c * prod(t.k, b) for t in p| length(t.k) :: I <= limit]
+
+ prod(g,d) ==
+ d = 1 => monom(g,1)
+ g = 1 => monom(d,1)
+ process(reverse ListOfTerms g, first d, rest ListOfTerms d)
+
+ Dexpand b ==
+ b = 1 => 1$XDPOLY
+ */ [LiePoly(l)$LPOLY :: XDPOLY for l in ListOfTerms b]
+
+ Rexpand b ==
+ b = 1 => 1$XRPOLY
+ */ [LiePoly(l)$LPOLY :: XRPOLY for l in ListOfTerms b]
+
+ mirror1(b:BASIS):$ ==
+ b = 1 => 1
+ lp: LPOLY := LiePoly first b
+ lp := mirror lp
+ mirror1(rest b) * lp :: $
+
+ process(gauche, x, droite) == -- algo du "collect process"
+ null gauche => monom( cons(x, droite) pretend BASIS, 1$R)
+ r1, r2 : $
+ not lexico(first gauche, x) => -- cas facile !!!
+ monom(append(reverse gauche, cons(x, droite)) pretend BASIS , 1$R)
+
+ p: LPOLY := [first gauche , x] -- on crochete !!!
+ null droite =>
+ r1 := +/ [t.c * process(rest gauche, t.k, droite) for t in _
+ ListOfTerms p]
+ r2 := process( rest gauche, x, list first gauche)
+ r1 + r2
+ rd: List LWORD := rest droite; fd: LWORD := first droite
+ r1 := +/ [t.c * process(list t.k, fd, rd) for t in ListOfTerms p]
+ r1 := +/ [t.c * process(rest gauche, first t.k, rest ListOfTerms(t.k))_
+ for t in r1]
+ r2 := process([first gauche, x], fd, rd)
+ r2 := +/ [t.c * process(rest gauche, first t.k, rest ListOfTerms(t.k))_
+ for t in r2]
+ r1 + r2
+
+ -- definitions
+ 1 == monom(1$BASIS, 1$R)
+
+ coerce(r:R):$ == [[1$BASIS , r]$TERM ]
+
+ coerce(p:$):EX ==
+ null p => (0$R) :: EX
+ le : List EX := nil
+ for rec in p repeat le := cons(outForm rec, le)
+ reduce(_+, le)$List(EX)
+
+ coerce(v: VarSet):$ == monom(v::BASIS , 1$R)
+ coerce(p: LPOLY):$ ==
+ [[t.k :: BASIS , t.c ]$TERM for t in ListOfTerms p]
+
+ coerce(p:$):XDPOLY ==
+ +/ [t.c * Dexpand t.k for t in p]
+
+ coerce(p:$):XRPOLY ==
+ p = 0 => 0$XRPOLY
+ +/ [t.c * Rexpand t.k for t in p]
+
+ constant? p == (null p) or (leadingMonomial(p) =$BASIS 1)
+ constant p ==
+ null p => 0$R
+ p.last.k = 1$BASIS => p.last.c
+ 0$R
+
+ quasiRegular? p == (p=0) or (p.last.k ^= 1$BASIS)
+ quasiRegular p ==
+ p = 0 => p
+ p.last.k = 1$BASIS => delete(p, maxIndex p)
+ p
+
+ x:$ * y:$ ==
+ y = 0$$ => 0
+ +/ [t.c * prod1(t.k, y) for t in x]
+
+-- ListOfTerms p == p pretend LTERMS
+
+ varList p ==
+ lv: List VarSet := "setUnion"/ [varList(b.k)$BASIS for b in p]
+ sort(lv)
+
+ degree(p) ==
+ p=0 => error "null polynomial"
+ length(leadingMonomial p)
+
+ trunc(p, n) ==
+ p = 0 => p
+ degree(p) > n => trunc( reductum p , n)
+ p
+
+ product(x,y,n) ==
+ x = 0 => 0
+ y = 0 => 0
+ +/ [t.c * prod11(t.k, y, n) for t in x]
+
+ if R has Module(RN) then
+ exp (p,n) ==
+ p = 0 => 1
+ not quasiRegular? p =>
+ error "a proper polynomial is required"
+ s : $ := 1 ; r: $ := 1 -- resultat
+ for i in 1..n repeat
+ k1 :RN := 1/i
+ k2 : R := k1 * 1$R
+ s := k2 * product(p, s, n)
+ r := r + s
+ r
+
+ log (p,n) ==
+ p = 1 => 0
+ p1: $ := 1 - p
+ not quasiRegular? p1 =>
+ error "constant term <> 1, impossible log "
+ s : $ := - 1 ; r: $ := 0 -- resultat
+ for i in 1..n repeat
+ k1 :RN := 1/i
+ k2 : R := k1 * 1$R
+ s := product(p1, s, n)
+ r := k2 * s + r
+ r
+
+ LiePolyIfCan p ==
+ p = 0 => 0$LPOLY
+ "and"/ [retractable?(t.k)$BASIS for t in p] =>
+ lt : List TERM1 := _
+ [[retract(t.k)$BASIS, t.c]$TERM1 for t in p]
+ lt pretend LPOLY
+ "failed"
+
+ mirror p ==
+ +/ [t.c * mirror1(t.k) for t in p]
+
+@
+\section{domain LEXP LieExponentials}
+<<domain LEXP LieExponentials>>=
+)abbrev domain LEXP LieExponentials
+++ Author: Michel Petitot (petitot@lifl.fr).
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ Management of the Lie Group associated with a
+++ free nilpotent Lie algebra. Every Lie bracket with
+++ length greater than \axiom{Order} are
+++ assumed to be null.
+++ The implementation inherits from the \spadtype{XPBWPolynomial}
+++ domain constructor: Lyndon
+++ coordinates are exponential coordinates
+++ of the second kind. \newline Author: Michel Petitot (petitot@lifl.fr).
+
+LieExponentials(VarSet, R, Order): XDPcat == XDPdef where
+
+ EX ==> OutputForm
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ RN ==> Fraction(I)
+ R : Join(CommutativeRing, Module RN)
+ Order : PI
+ VarSet : OrderedSet
+ LWORD ==> LyndonWord(VarSet)
+ LWORDS ==> List LWORD
+ BASIS ==> PoincareBirkhoffWittLyndonBasis(VarSet)
+ TERM ==> Record(k:BASIS, c:R)
+ LTERMS ==> List(TERM)
+ LPOLY ==> LiePolynomial(VarSet,R)
+ XDPOLY ==> XDistributedPolynomial(VarSet,R)
+ PBWPOLY==> XPBWPolynomial(VarSet, R)
+ TERM1 ==> Record(k:LWORD, c:R)
+ EQ ==> Equation(R)
+
+ XDPcat == Group with
+ exp : LPOLY -> $
+ ++ \axiom{exp(p)} returns the exponential of \axiom{p}.
+ log : $ -> LPOLY
+ ++ \axiom{log(p)} returns the logarithm of \axiom{p}.
+ ListOfTerms : $ -> LTERMS
+ ++ \axiom{ListOfTerms(p)} returns the internal representation of \axiom{p}.
+ coerce : $ -> XDPOLY
+ ++ \axiom{coerce(g)} returns the internal representation of \axiom{g}.
+ coerce : $ -> PBWPOLY
+ ++ \axiom{coerce(g)} returns the internal representation of \axiom{g}.
+ mirror : $ -> $
+ ++ \axiom{mirror(g)} is the mirror of the internal representation of \axiom{g}.
+ varList : $ -> List VarSet
+ ++ \axiom{varList(g)} returns the list of variables of \axiom{g}.
+ LyndonBasis : List VarSet -> List LPOLY
+ ++ \axiom{LyndonBasis(lv)} returns the Lyndon basis of the nilpotent free
+ ++ Lie algebra.
+ LyndonCoordinates: $ -> List TERM1
+ ++ \axiom{LyndonCoordinates(g)} returns the exponential coordinates of \axiom{g}.
+ identification: ($,$) -> List EQ
+ ++ \axiom{identification(g,h)} returns the list of equations \axiom{g_i = h_i},
+ ++ where \axiom{g_i} (resp. \axiom{h_i}) are exponential coordinates
+ ++ of \axiom{g} (resp. \axiom{h}).
+
+ XDPdef == PBWPOLY add
+
+ -- Representation
+ Rep := PBWPOLY
+
+ -- local functions
+ compareTerm1s: (TERM1, TERM1) -> Boolean
+ out: TERM1 -> EX
+ ident: (List TERM1, List TERM1) -> List EQ
+
+ -- functions locales
+ ident(l1, l2) ==
+ import(TERM1)
+ null l1 => [equation(0$R,t.c)$EQ for t in l2]
+ null l2 => [equation(t.c, 0$R)$EQ for t in l1]
+ u1 : LWORD := l1.first.k; c1 :R := l1.first.c
+ u2 : LWORD := l2.first.k; c2 :R := l2.first.c
+ u1 = u2 =>
+ r: R := c1 - c2
+ r = 0 => ident(rest l1, rest l2)
+ cons(equation(c1,c2)$EQ , ident(rest l1, rest l2))
+ lexico(u1, u2)$LWORD =>
+ cons(equation(0$R,c2)$EQ , ident(l1, rest l2))
+ cons(equation(c1,0$R)$EQ , ident(rest l1, l2))
+
+ -- ordre lexico decroissant
+ compareTerm1s(u:TERM1, v:TERM1):Boolean == lexico(v.k, u.k)$LWORD
+
+ out(t:TERM1):EX ==
+ t.c =$R 1 => char("e")$Character :: EX ** t.k ::EX
+ char("e")$Character :: EX ** (t.c::EX * t.k::EX)
+
+ -- definitions
+ identification(x,y) ==
+ l1: List TERM1 := LyndonCoordinates x
+ l2: List TERM1 := LyndonCoordinates y
+ ident(l1, l2)
+
+ LyndonCoordinates x ==
+ lt: List TERM1 := [[l::LWORD, t.c]$TERM1 for t in ListOfTerms x | _
+ (l := retractIfCan(t.k)$BASIS) case LWORD ]
+ lt := sort(compareTerm1s,lt)
+
+ x:$ * y:$ == product(x::Rep, y::Rep, Order::I::NNI)$Rep
+
+ exp p == exp(p::Rep , Order::I::NNI)$Rep
+
+ log p == LiePolyIfCan(log(p,Order::I::NNI))$Rep :: LPOLY
+
+ coerce(p:$):EX ==
+ p = 1$$ => 1$R :: EX
+ lt : List TERM1 := LyndonCoordinates p
+ reduce(_*, [out t for t in lt])$List(EX)
+
+
+ LyndonBasis(lv) ==
+ [LiePoly(l)$LPOLY for l in LyndonWordsList(lv,Order)$LWORD]
+
+ coerce(p:$):PBWPOLY == p::Rep
+
+ inv x ==
+ x = 1 => 1
+ lt:LTERMS := ListOfTerms mirror x
+ lt:= [[t.k, (odd? length(t.k)$BASIS => - t.c; t.c)]$TERM for t in lt ]
+ lt pretend $
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain MAGMA Magma>>
+<<domain LWORD LyndonWord>>
+<<category LIECAT LieAlgebra>>
+<<category FLALG FreeLieAlgebra>>
+<<package XEXPPKG XExponentialPackage>>
+<<domain LPOLY LiePolynomial>>
+<<domain PBWLB PoincareBirkhoffWittLyndonBasis>>
+<<domain XPBWPOLY XPBWPolynomial>>
+<<domain LEXP LieExponentials>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1}
+{\bf http://www.mathe2.uni-bayreuth.de/frib/html/canonsgif/canons.html}
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/xpoly.spad.pamphlet b/src/algebra/xpoly.spad.pamphlet
new file mode 100644
index 00000000..6ff416b1
--- /dev/null
+++ b/src/algebra/xpoly.spad.pamphlet
@@ -0,0 +1,1132 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra xpoly.spad}
+\author{Michel Petitot}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain OFMONOID OrderedFreeMonoid}
+<<domain OFMONOID OrderedFreeMonoid>>=
+)abbrev domain OFMONOID OrderedFreeMonoid
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The free monoid on a set \spad{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 non-negative integers. The multiplication is not commutative.
+++ For two elements \spad{x} and \spad{y} the relation \spad{x < y}
+++ holds if either \spad{length(x) < length(y)} holds or if these lengths
+++ are equal and if \spad{x} is smaller than \spad{y} w.r.t. the lexicographical
+++ ordering induced by \spad{S}.
+++ This domain inherits implementation from \spadtype{FreeMonoid}.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+OrderedFreeMonoid(S: OrderedSet): OFMcategory == OFMdefinition where
+ NNI ==> NonNegativeInteger
+ REC ==> Record(gen:S, exp:NNI)
+
+ OFMcategory == Join(OrderedMonoid, RetractableTo S) with
+ "*": (S, %) -> %
+ ++ \spad{s * x} returns the product of \spad{x} by \spad{s} on the left.
+ "*": (%, S) -> %
+ ++ \spad{x * s} returns the product of \spad{x} by \spad{s} on the right.
+ "**": (S, NNI) -> %
+ ++ \spad{s ** n} returns the product of \spad{s} by itself \spad{n} times.
+ first: % -> S
+ ++ \spad{first(x)} returns the first letter of \spad{x}.
+ rest: % -> %
+ ++ \spad{rest(x)} returns \spad{x} except the first letter.
+ mirror: % -> %
+ ++ \spad{mirror(x)} returns the reversed word of \spad{x}.
+ lexico: (%,%) -> Boolean
+ ++ \spad{lexico(x,y)} returns \spad{true} iff \spad{x} is smaller than \spad{y}
+ ++ w.r.t. the pure lexicographical ordering induced by \spad{S}.
+ hclf: (%, %) -> %
+ ++ \spad{hclf(x, y)} returns the highest common left factor
+ ++ of \spad{x} and \spad{y},
+ ++ that is the largest \spad{d} such that \spad{x = d a} and \spad{y = d b}.
+ hcrf: (%, %) -> %
+ ++ \spad{hcrf(x, y)} returns the highest common right
+ ++ factor of \spad{x} and \spad{y},
+ ++ that is the largest \spad{d} such that \spad{x = a d} and \spad{y = b d}.
+ lquo: (%, %) -> Union(%, "failed")
+ ++ \spad{lquo(x, y)} returns the exact left quotient of \spad{x}
+ ++ by \spad{y} that is \spad{q} such that \spad{x = y * q},
+ ++ "failed" if \spad{x} is not of the form \spad{y * q}.
+ rquo: (%, %) -> Union(%, "failed")
+ ++ \spad{rquo(x, y)} returns the exact right quotient of \spad{x}
+ ++ by \spad{y} that is \spad{q} such that \spad{x = q * y},
+ ++ "failed" if \spad{x} is not of the form \spad{q * y}.
+ lquo: (%, S) -> Union(%, "failed")
+ ++ \spad{lquo(x, s)} returns the exact left quotient of \spad{x}
+ ++ by \spad{s}.
+ rquo: (%, S) -> Union(%, "failed")
+ ++ \spad{rquo(x, s)} returns the exact right quotient
+ ++ of \spad{x} by \spad{s}.
+ "div": (%, %) -> Union(Record(lm: %, rm: %), "failed")
+ ++ \spad{x div y} returns the left and right exact quotients of
+ ++ \spad{x} by \spad{y}, that is \spad{[l, r]} such that \spad{x = l * y * r}.
+ ++ "failed" is returned iff \spad{x} is not of the form \spad{l * y * r}.
+ overlap: (%, %) -> Record(lm: %, mm: %, rm: %)
+ ++ \spad{overlap(x, y)} returns \spad{[l, m, r]} such that
+ ++ \spad{x = l * m} and \spad{y = m * r} hold and such that
+ ++ \spad{l} and \spad{r} have no overlap,
+ ++ that is \spad{overlap(l, r) = [l, 1, r]}.
+ size: % -> NNI
+ ++ \spad{size(x)} returns the number of monomials in \spad{x}.
+ nthExpon: (%, Integer) -> NNI
+ ++ \spad{nthExpon(x, n)} returns the exponent of the
+ ++ \spad{n-th} monomial of \spad{x}.
+ nthFactor: (%, Integer) -> S
+ ++ \spad{nthFactor(x, n)} returns the factor of the \spad{n-th}
+ ++ monomial of \spad{x}.
+ factors: % -> List REC
+ ++ \spad{factors(a1\^e1,...,an\^en)} returns \spad{[[a1, e1],...,[an, en]]}.
+ length: % -> NNI
+ ++ \spad{length(x)} returns the length of \spad{x}.
+ varList: % -> List S
+ ++ \spad{varList(x)} returns the list of variables of \spad{x}.
+
+ OFMdefinition == FreeMonoid(S) add
+ Rep := ListMonoidOps(S, NNI, 1)
+
+ -- definitions
+ lquo(w:%, l:S) ==
+ x: List REC := listOfMonoms(w)$Rep
+ null x => "failed"
+ fx: REC := first x
+ fx.gen ^= l => "failed"
+ fx.exp = 1 => makeMulti rest(x)
+ makeMulti [[fx.gen, (fx.exp - 1)::NNI ]$REC, :rest x]
+
+ rquo(w:%, l:S) ==
+ u:% := reverse w
+ (r := lquo (u,l)) case "failed" => "failed"
+ reverse_! (r::%)
+
+ length x == reduce("+" ,[f.exp for f in listOfMonoms x], 0)
+
+ varList x ==
+ le: List S := [t.gen for t in listOfMonoms x]
+ sort_! removeDuplicates(le)
+
+ first w ==
+ x: List REC := listOfMonoms w
+ null x => error "empty word !!!"
+ x.first.gen
+
+ rest w ==
+ x: List REC := listOfMonoms w
+ null x => error "empty word !!!"
+ fx: REC := first x
+ fx.exp = 1 => makeMulti rest x
+ makeMulti [[fx.gen , (fx.exp - 1)::NNI ]$REC , :rest x]
+
+ lexico(a,b) == -- ordre lexicographique
+ la := listOfMonoms a
+ lb := listOfMonoms b
+ while (not null la) and (not null lb) 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
+ 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
+ else
+ lb:=concat([lb.first.gen,
+ (lb.first.exp-la.first.exp)::NNI], rest la)
+ la:=rest la
+ empty? la and not empty? lb
+
+
+ a < b == -- ordre lexicographique par longueur
+ la:NNI := length a; lb:NNI := length b
+ la = lb => lexico(a,b)
+ la < lb
+
+ mirror x == reverse(x)$Rep
+
+@
+\section{category FMCAT FreeModuleCat}
+<<category FMCAT FreeModuleCat>>=
+)abbrev category FMCAT FreeModuleCat
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A domain of this category
+++ implements formal linear combinations
+++ of elements from a domain \spad{Basis} with coefficients
+++ in a domain \spad{R}. The domain \spad{Basis} needs only
+++ to belong to the category \spadtype{SetCategory} and \spad{R}
+++ to the category \spadtype{Ring}. Thus the coefficient ring
+++ may be non-commutative.
+++ See the \spadtype{XDistributedPolynomial} constructor
+++ for examples of domains built with the \spadtype{FreeModuleCat}
+++ category constructor.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+FreeModuleCat(R, Basis):Category == Exports where
+ R: Ring
+ Basis: SetCategory
+ TERM ==> Record(k: Basis, c: R)
+
+ Exports == Join(BiModule(R,R), RetractableTo Basis) with
+ "*" : (R, Basis) -> %
+ ++ \spad{r*b} returns the product of \spad{r} by \spad{b}.
+ coefficient : (%, Basis) -> R
+ ++ \spad{coefficient(x,b)} returns the coefficient
+ ++ of \spad{b} in \spad{x}.
+ map : (R -> R, %) -> %
+ ++ \spad{map(fn,u)} maps function \spad{fn} onto the coefficients
+ ++ of the non-zero monomials of \spad{u}.
+ monom : (Basis, R) -> %
+ ++ \spad{monom(b,r)} returns the element with the single monomial
+ ++ \spad{b} and coefficient \spad{r}.
+ monomial? : % -> Boolean
+ ++ \spad{monomial?(x)} returns true if \spad{x} contains a single
+ ++ monomial.
+ ListOfTerms : % -> List TERM
+ ++ \spad{ListOfTerms(x)} returns a list \spad{lt} of terms with type
+ ++ \spad{Record(k: Basis, c: R)} such that \spad{x} equals
+ ++ \spad{reduce(+, map(x +-> monom(x.k, x.c), lt))}.
+ coefficients : % -> List R
+ ++ \spad{coefficients(x)} returns the list of coefficients of \spad{x}.
+ monomials : % -> List %
+ ++ \spad{monomials(x)} returns the list of \spad{r_i*b_i}
+ ++ whose sum is \spad{x}.
+ numberOfMonomials : % -> NonNegativeInteger
+ ++ \spad{numberOfMonomials(x)} returns the number of monomials of \spad{x}.
+ leadingMonomial : % -> Basis
+ ++ \spad{leadingMonomial(x)} returns the first element from \spad{Basis}
+ ++ which appears in \spad{ListOfTerms(x)}.
+ leadingCoefficient : % -> R
+ ++ \spad{leadingCoefficient(x)} returns the first coefficient
+ ++ which appears in \spad{ListOfTerms(x)}.
+ leadingTerm : % -> TERM
+ ++ \spad{leadingTerm(x)} returns the first term which
+ ++ appears in \spad{ListOfTerms(x)}.
+ reductum : % -> %
+ ++ \spad{reductum(x)} returns \spad{x} minus its leading term.
+
+ -- attributs
+ if R has CommutativeRing then Module(R)
+
+@
+\section{domain FM1 FreeModule1}
+<<domain FM1 FreeModule1>>=
+)abbrev domain FM1 FreeModule1
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain implements linear combinations
+++ of elements from the domain \spad{S} with coefficients
+++ in the domain \spad{R} where \spad{S} is an ordered set
+++ and \spad{R} is a ring (which may be non-commutative).
+++ This domain is used by domains of non-commutative algebra such as:
+++ \spadtype{XDistributedPolynomial},
+++ \spadtype{XRecursivePolynomial}.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+FreeModule1(R:Ring,S:OrderedSet): FMcat == FMdef where
+ EX ==> OutputForm
+ TERM ==> Record(k:S,c:R)
+
+ FMcat == FreeModuleCat(R,S) with
+ "*":(S,R) -> %
+ ++ \spad{s*r} returns the product \spad{r*s}
+ ++ used by \spadtype{XRecursivePolynomial}
+ FMdef == FreeModule(R,S) add
+ -- representation
+ Rep := List TERM
+
+ -- declarations
+ lt: List TERM
+ x : %
+ r : R
+ s : S
+
+ -- define
+ numberOfMonomials p ==
+ # (p::Rep)
+
+ ListOfTerms(x) == x:List TERM
+
+ leadingTerm x == x.first
+ leadingMonomial x == x.first.k
+ coefficients x == [t.c for t in x]
+ monomials x == [ monom (t.k, t.c) for t in x]
+
+ retractIfCan x ==
+ numberOfMonomials(x) ^= 1 => "failed"
+ x.first.c = 1 => x.first.k
+ "failed"
+
+ coerce(s:S):% == [[s,1$R]]
+ retract x ==
+ (rr := retractIfCan x) case "failed" => error "FM1.retract impossible"
+ rr :: S
+
+ if R has noZeroDivisors then
+ r * x ==
+ r = 0 => 0
+ [[u.k,r * u.c]$TERM for u in x]
+ x * r ==
+ r = 0 => 0
+ [[u.k,u.c * r]$TERM for u in x]
+ else
+ r * x ==
+ r = 0 => 0
+ [[u.k,a] for u in x | not (a:=r*u.c)= 0$R]
+ x * r ==
+ r = 0 => 0
+ [[u.k,a] for u in x | not (a:=u.c*r)= 0$R]
+
+ r * s ==
+ r = 0 => 0
+ [[s,r]$TERM]
+
+ s * r ==
+ r = 0 => 0
+ [[s,r]$TERM]
+
+ monom(b,r):% == [[b,r]$TERM]
+
+ outTerm(r:R, s:S):EX ==
+ r=1 => s::EX
+ r::EX * s::EX
+
+ coerce(a:%):EX ==
+ empty? a => (0$R)::EX
+ reduce(_+, reverse_! [outTerm(t.c, t.k) for t in a])$List(EX)
+
+ coefficient(x,s) ==
+ null x => 0$R
+ x.first.k > s => coefficient(rest x,s)
+ x.first.k = s => x.first.c
+ 0$R
+
+@
+\section{category XALG XAlgebra}
+<<category XALG XAlgebra>>=
+)abbrev category XALG XAlgebra
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This is the category of algebras over non-commutative rings.
+++ It is used by constructors of non-commutative algebras such as:
+++ \spadtype{XPolynomialRing}.
+++ \spadtype{XFreeAlgebra}
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XAlgebra(R: Ring): Category ==
+ Join(Ring, BiModule(R,R)) with
+ --operations
+ coerce: R -> %
+ ++ \spad{coerce(r)} equals \spad{r*1}.
+ -- attributs
+ if R has CommutativeRing then Algebra(R)
+ -- if R has CommutativeRing then Module(R)
+-- add
+-- coerce(x:R):% == x * 1$%
+
+@
+\section{category XFALG XFreeAlgebra}
+<<category XFALG XFreeAlgebra>>=
+)abbrev category XFALG XFreeAlgebra
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This category specifies opeations for polynomials
+++ and formal series with non-commutative variables.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XFreeAlgebra(vl:OrderedSet,R:Ring):Category == Catdef where
+ WORD ==> OrderedFreeMonoid(vl) -- monoide libre
+ NNI ==> NonNegativeInteger
+ I ==> Integer
+ TERM ==> Record(k: WORD, c: R)
+
+ Catdef == Join(Ring, XAlgebra(R), RetractableTo WORD)
+ with
+ "*": (vl,%) -> %
+ ++ \spad{v * x} returns the product of a variable \spad{x} by \spad{x}.
+ "*": (%, R) -> %
+ ++ \spad{x * r} returns the product of \spad{x} by \spad{r}.
+ ++ Usefull if \spad{R} is a non-commutative Ring.
+ mindeg: % -> WORD
+ ++ \spad{mindeg(x)} returns the little word which appears in \spad{x}.
+ ++ Error if \spad{x=0}.
+ mindegTerm: % -> TERM
+ ++ \spad{mindegTerm(x)} returns the term whose word is \spad{mindeg(x)}.
+ coef : (%,WORD) -> R
+ ++ \spad{coef(x,w)} returns the coefficient of the word \spad{w} in \spad{x}.
+ coef : (%,%) -> R
+ ++ \spad{coef(x,y)} returns scalar product of \spad{x} by \spad{y},
+ ++ the set of words being regarded as an orthogonal basis.
+ lquo : (%,vl) -> %
+ ++ \spad{lquo(x,v)} returns the left simplification of \spad{x} by the variable \spad{v}.
+ lquo : (%,WORD) -> %
+ ++ \spad{lquo(x,w)} returns the left simplification of \spad{x} by the word \spad{w}.
+ lquo : (%,%) -> %
+ ++ \spad{lquo(x,y)} returns the left simplification of \spad{x} by \spad{y}.
+ rquo : (%,vl) -> %
+ ++ \spad{rquo(x,v)} returns the right simplification of \spad{x} by the variable \spad{v}.
+ rquo : (%,WORD) -> %
+ ++ \spad{rquo(x,w)} returns the right simplification of \spad{x} by \spad{w}.
+ rquo : (%,%) -> %
+ ++ \spad{rquo(x,y)} returns the right simplification of \spad{x} by \spad{y}.
+ monom : (WORD , R) -> %
+ ++ \spad{monom(w,r)} returns the product of the word \spad{w} by the coefficient \spad{r}.
+ monomial? : % -> Boolean
+ ++ \spad{monomial?(x)} returns true if \spad{x} is a monomial
+ mirror: % -> %
+ ++ \spad{mirror(x)} returns \spad{Sum(r_i mirror(w_i))} if \spad{x} writes \spad{Sum(r_i w_i)}.
+ coerce : vl -> %
+ ++ \spad{coerce(v)} returns \spad{v}.
+ constant?:% -> Boolean
+ ++ \spad{constant?(x)} returns true if \spad{x} is constant.
+ constant: % -> R
+ ++ \spad{constant(x)} returns the constant term of \spad{x}.
+ quasiRegular? : % -> Boolean
+ ++ \spad{quasiRegular?(x)} return true if \spad{constant(x)} is zero.
+ quasiRegular : % -> %
+ ++ \spad{quasiRegular(x)} return \spad{x} minus its constant term.
+ if R has CommutativeRing then
+ sh :(%,%) -> %
+ ++ \spad{sh(x,y)} returns the shuffle-product of \spad{x} by \spad{y}.
+ ++ This multiplication is associative and commutative.
+ sh :(%,NNI) -> %
+ ++ \spad{sh(x,n)} returns the shuffle power of \spad{x} to the \spad{n}.
+ map : (R -> R, %) -> %
+ ++ \spad{map(fn,x)} returns \spad{Sum(fn(r_i) w_i)} if \spad{x} writes \spad{Sum(r_i w_i)}.
+ varList: % -> List vl
+ ++ \spad{varList(x)} returns the list of variables which appear in \spad{x}.
+
+ -- Attributs
+ if R has noZeroDivisors then noZeroDivisors
+
+@
+\section{category XPOLYC XPolynomialsCat}
+<<category XPOLYC XPolynomialsCat>>=
+)abbrev category XPOLYC XPolynomialsCat
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ The Category of polynomial rings with non-commutative variables.
+++ The coefficient ring may be non-commutative too.
+++ However coefficients commute with vaiables.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XPolynomialsCat(vl:OrderedSet,R:Ring):Category == Export where
+ WORD ==> OrderedFreeMonoid(vl)
+
+ Export == XFreeAlgebra(vl,R) with
+ maxdeg: % -> WORD
+ ++ \spad{maxdeg(p)} returns the greatest leading word in the support of \spad{p}.
+ degree: % -> NonNegativeInteger
+ ++ \spad{degree(p)} returns the degree of \spad{p}.
+ ++ Note that the degree of a word is its length.
+ trunc : (% , NonNegativeInteger) -> %
+ ++ \spad{trunc(p,n)} returns the polynomial \spad{p} truncated at order \spad{n}.
+
+@
+\section{domain XPR XPolynomialRing}
+<<domain XPR XPolynomialRing>>=
+)abbrev domain XPR XPolynomialRing
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This domain represents generalized polynomials with coefficients
+++ (from a not necessarily commutative ring), and words
+++ belonging to an arbitrary \spadtype{OrderedMonoid}.
+++ This type is used, for instance, by the \spadtype{XDistributedPolynomial}
+++ domain constructor where the Monoid is free.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XPolynomialRing(R:Ring,E:OrderedMonoid): T == C where
+ TERM ==> Record(k: E, c: R)
+ EX ==> OutputForm
+ NNI ==> NonNegativeInteger
+
+ T == Join(Ring, XAlgebra(R), FreeModuleCat(R,E)) with
+ --operations
+ "*": (%,R) -> %
+ ++ \spad{p*r} returns the product of \spad{p} by \spad{r}.
+ "#": % -> NonNegativeInteger
+ ++ \spad{# p} returns the number of terms in \spad{p}.
+ coerce: E -> %
+ ++ \spad{coerce(e)} returns \spad{1*e}
+ maxdeg: % -> E
+ ++ \spad{maxdeg(p)} returns the greatest word occurring in the polynomial \spad{p}
+ ++ with a non-zero coefficient. An error is produced if \spad{p} is zero.
+ mindeg: % -> E
+ ++ \spad{mindeg(p)} returns the smallest word occurring in the polynomial \spad{p}
+ ++ with a non-zero coefficient. An error is produced if \spad{p} is zero.
+ reductum : % -> %
+ ++ \spad{reductum(p)} returns \spad{p} minus its leading term.
+ ++ An error is produced if \spad{p} is zero.
+ coef : (%,E) -> R
+ ++ \spad{coef(p,e)} extracts the coefficient of the monomial \spad{e}.
+ ++ Returns zero if \spad{e} is not present.
+ constant?:% -> Boolean
+ ++ \spad{constant?(p)} tests whether the polynomial \spad{p} belongs to the
+ ++ coefficient ring.
+ constant: % -> R
+ ++ \spad{constant(p)} return the constant term of \spad{p}.
+ quasiRegular? : % -> Boolean
+ ++ \spad{quasiRegular?(x)} return true if \spad{constant(p)} is zero.
+ quasiRegular : % -> %
+ ++ \spad{quasiRegular(x)} return \spad{x} minus its constant term.
+ map : (R -> R, %) -> %
+ ++ \spad{map(fn,x)} returns \spad{Sum(fn(r_i) w_i)} if \spad{x} writes \spad{Sum(r_i w_i)}.
+ if R has Field then "/" : (%,R) -> %
+ ++ \spad{p/r} returns \spad{p*(1/r)}.
+
+ --assertions
+ if R has noZeroDivisors then noZeroDivisors
+ if R has unitsKnown then unitsKnown
+ if R has canonicalUnitNormal then canonicalUnitNormal
+ ++ canonicalUnitNormal guarantees that the function
+ ++ unitCanonical returns the same representative for all
+ ++ associates of any particular element.
+
+
+ C == FreeModule1(R,E) add
+ --representations
+ Rep:= List TERM
+ --uses
+ repeatMultExpt: (%,NonNegativeInteger) -> %
+ --define
+ 1 == [[1$E,1$R]]
+
+ characteristic == characteristic$R
+ #x == #$Rep x
+ maxdeg p == if null p then error " polynome nul !!"
+ else p.first.k
+ mindeg p == if null p then error " polynome nul !!"
+ else (last p).k
+
+ coef(p,e) ==
+ for tm in p repeat
+ tm.k=e => return tm.c
+ tm.k < e => return 0$R
+ 0$R
+
+ constant? p == (p = 0) or (maxdeg(p) = 1$E)
+ constant p == coef(p,1$E)
+
+ quasiRegular? p == (p=0) or (last p).k ^= 1$E
+ quasiRegular p ==
+ quasiRegular?(p) => p
+ [t for t in p | not(t.k = 1$E)]
+
+ recip(p) ==
+ p=0 => "failed"
+ p.first.k > 1$E => "failed"
+ (u:=recip(p.first.c)) case "failed" => "failed"
+ (u::R)::%
+
+ coerce(r:R) == if r=0$R then 0$% else [[1$E,r]]
+ coerce(n:Integer) == (n::R)::%
+
+ if R has noZeroDivisors then
+ p1:% * p2:% ==
+ null p1 => 0
+ null p2 => 0
+ p1.first.k = 1$E => p1.first.c * p2
+ p2 = 1 => p1
+-- +/[[[t1.k*t2.k,t1.c*t2.c]$TERM for t2 in p2]
+-- for t1 in reverse(p1)]
+ +/[[[t1.k*t2.k,t1.c*t2.c]$TERM for t2 in p2]
+ for t1 in p1]
+ else
+ p1:% * p2:% ==
+ null p1 => 0
+ null p2 => 0
+ p1.first.k = 1$E => p1.first.c * p2
+ p2 = 1 => p1
+-- +/[[[t1.k*t2.k,r]$TERM for t2 in p2 | not (r:=t1.c*t2.c) =$R 0]
+-- for t1 in reverse(p1)]
+ +/[[[t1.k*t2.k,r]$TERM for t2 in p2 | not (r:=t1.c*t2.c) =$R 0]
+ for t1 in p1]
+ p:% ** nn:NNI == repeatMultExpt(p,nn)
+ repeatMultExpt(x,nn) ==
+ nn = 0 => 1
+ y:% := x
+ for i in 2..nn repeat y:= x * y
+ y
+
+ outTerm(r:R, m:E):EX ==
+ r=1 => m::EX
+ m=1 => r::EX
+ r::EX * m::EX
+
+-- coerce(x:%) : EX ==
+-- null x => (0$R) :: EX
+-- le : List EX := nil
+-- for rec in x repeat
+-- rec.c = 1$R => le := cons(rec.k :: EX, le)
+-- rec.k = 1$E => le := cons(rec.c :: EX, le)
+-- le := cons(mkBinary("*"::EX,rec.c :: EX,
+-- rec.k :: EX), le)
+-- 1 = #le => first le
+-- mkNary("+" :: EX,le)
+
+ coerce(a:%):EX ==
+ empty? a => (0$R)::EX
+ reduce(_+, reverse_! [outTerm(t.c, t.k) for t in a])$List(EX)
+
+
+ if R has Field then
+ x/r == inv(r)*x
+
+@
+\section{domain XDPOLY XDistributedPolynomial}
+Polynomial arithmetic with non-commutative variables has been improved
+by a contribution of Michel Petitot (University of Lille I, France).
+The domain constructor
+{\bf XDistributedPolynomial} provide a distributed
+representation for these polynomials. It is the non-commutative
+equivalent for the
+{\bf DistributedMultivariatePolynomial} constructor.
+<<domain XDPOLY XDistributedPolynomial>>=
+)abbrev domain XDPOLY XDistributedPolynomial
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type supports distributed multivariate polynomials
+++ whose variables do not commute.
+++ The coefficient ring may be non-commutative too.
+++ However, coefficients and variables commute.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XDistributedPolynomial(vl:OrderedSet,R:Ring): XDPcat == XDPdef where
+
+ WORD ==> OrderedFreeMonoid(vl)
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ TERM ==> Record(k:WORD, c:R)
+
+ XDPcat == Join(FreeModuleCat(R, WORD), XPolynomialsCat(vl,R))
+
+ XDPdef == XPolynomialRing(R,WORD) add
+
+ import( WORD, TERM)
+
+ -- Representation
+ Rep := List TERM
+
+ -- local functions
+ shw: (WORD , WORD) -> % -- shuffle de 2 mots
+
+ -- definitions
+
+ mindegTerm p == last(p)$Rep
+
+ if R has CommutativeRing then
+ sh(p:%, n:NNI):% ==
+ n=0 => 1
+ n=1 => p
+ n1: NNI := (n-$I 1)::NNI
+ sh(p, sh(p,n1))
+
+
+ sh(p1:%, p2:%) ==
+ p:% := 0
+ for t1 in p1 repeat
+ for t2 in p2 repeat
+ p := p + (t1.c * t2.c) * shw(t1.k,t2.k)
+ p
+
+ coerce(v: vl):% == coerce(v::WORD)
+ v:vl * p:% ==
+ [[v * t.k , t.c]$TERM for t in p]
+
+ mirror p ==
+ null p => p
+ monom(mirror$WORD leadingMonomial p, leadingCoefficient p) + _
+ mirror reductum p
+
+ degree(p) == length(maxdeg(p))$WORD
+
+ trunc(p, n) ==
+ p = 0 => p
+ degree(p) > n => trunc( reductum p , n)
+ p
+
+ varList p ==
+ constant? p => []
+ le : List vl := "setUnion"/[varList(t.k) for t in p]
+ sort_!(le)
+
+ rquo(p:% , w: WORD) ==
+ [[r::WORD,t.c]$TERM for t in p | not (r:= rquo(t.k,w)) case "failed" ]
+ lquo(p:% , w: WORD) ==
+ [[r::WORD,t.c]$TERM for t in p | not (r:= lquo(t.k,w)) case "failed" ]
+ rquo(p:% , v: vl) ==
+ [[r::WORD,t.c]$TERM for t in p | not (r:= rquo(t.k,v)) case "failed" ]
+ lquo(p:% , v: vl) ==
+ [[r::WORD,t.c]$TERM for t in p | not (r:= lquo(t.k,v)) case "failed" ]
+
+ shw(w1,w2) ==
+ w1 = 1$WORD => w2::%
+ w2 = 1$WORD => w1::%
+ x: vl := first w1 ; y: vl := first w2
+ x * shw(rest w1,w2) + y * shw(w1,rest w2)
+
+ lquo(p:%,q:%):% ==
+ +/ [r * t.c for t in q | (r := lquo(p,t.k)) ^= 0]
+
+ rquo(p:%,q:%):% ==
+ +/ [r * t.c for t in q | (r := rquo(p,t.k)) ^= 0]
+
+ coef(p:%,q:%):R ==
+ p = 0 => 0$R
+ q = 0 => 0$R
+ p.first.k > q.first.k => coef(p.rest,q)
+ p.first.k < q.first.k => coef(p,q.rest)
+ return p.first.c * q.first.c + coef(p.rest,q.rest)
+
+@
+\section{domain XRPOLY XRecursivePolynomial}
+Polynomial arithmetic with non-commutative variables has been improved
+by a contribution of Michel Petitot (University of Lille I, France).
+The domain constructors {\bf XRecursivePolynomial}
+provides a recursive for these polynomials. It is the non-commutative
+equivalents for the {\bf SparseMultivariatePolynomial} constructor.
+<<domain XRPOLY XRecursivePolynomial>>=
+)abbrev domain XRPOLY XRecursivePolynomial
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ extend renomme en expand
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type supports multivariate polynomials
+++ whose variables do not commute.
+++ The representation is recursive.
+++ The coefficient ring may be non-commutative.
+++ Coefficients and variables commute.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XRecursivePolynomial(VarSet:OrderedSet,R:Ring): Xcat == Xdef where
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ XDPOLY ==> XDistributedPolynomial(VarSet, R)
+ EX ==> OutputForm
+ WORD ==> OrderedFreeMonoid(VarSet)
+ TERM ==> Record(k:VarSet , c:%)
+ LTERMS ==> List(TERM)
+ REGPOLY==> FreeModule1(%, VarSet)
+ VPOLY ==> Record(c0:R, reg:REGPOLY)
+
+ Xcat == XPolynomialsCat(VarSet,R) with
+ expand: % -> XDPOLY
+ ++ \spad{expand(p)} returns \spad{p} in distributed form.
+ unexpand : XDPOLY -> %
+ ++ \spad{unexpand(p)} returns \spad{p} in recursive form.
+ RemainderList: % -> LTERMS
+ ++ \spad{RemainderList(p)} returns the regular part of \spad{p}
+ ++ as a list of terms.
+
+ Xdef == add
+ import(VPOLY)
+
+ -- representation
+ Rep := Union(R,VPOLY)
+
+ -- local functions
+ construct: LTERMS -> REGPOLY
+ simplifie: VPOLY -> %
+ lquo1: (LTERMS,LTERMS) -> % ++ a ajouter
+ coef1: (LTERMS,LTERMS) -> R ++ a ajouter
+ outForm: REGPOLY -> EX
+
+ --define
+ construct(lt) == lt pretend REGPOLY
+ p1:% = p2:% ==
+ p1 case R =>
+ p2 case R => p1 =$R p2
+ false
+ p2 case R => false
+ p1.c0 =$R p2.c0 and p1.reg =$REGPOLY p2.reg
+
+ monom(w, r) ==
+ r =0 => 0
+ r * w::%
+
+-- if R has Field then -- Bug non resolu !!!!!!!!
+-- p:% / r: R == inv(r) * p
+
+ rquo(p1:%, p2:%):% ==
+ p2 case R => p1 * p2::R
+ p1 case R => p1 * p2.c0
+ x:REGPOLY := construct [[t.k, a]$TERM for t in ListOfTerms(p1.reg) _
+ | (a:= rquo(t.c,p2)) ^= 0$% ]$LTERMS
+ simplifie [coef(p1,p2) , x]$VPOLY
+
+ trunc(p,n) ==
+ n = 0 or (p case R) => (constant p)::%
+ n1: NNI := (n-1)::NNI
+ lt: LTERMS := [[t.k, r]$TERM for t in ListOfTerms p.reg _
+ | (r := trunc(t.c, n1)) ^= 0]$LTERMS
+ x: REGPOLY := construct lt
+ simplifie [constant p, x]$VPOLY
+
+ unexpand p ==
+ constant? p => (constant p)::%
+ vl: List VarSet := sort(#1 > #2, varList p)
+ x : REGPOLY := _
+ construct [[v, unexpand r]$TERM for v in vl| (r:=lquo(p,v)) ^= 0]
+ [constant p, x]$VPOLY
+
+ if R has CommutativeRing then
+ sh(p:%, n:NNI):% ==
+ n = 0 => 1
+ p case R => (p::R)** n
+ n1: NNI := (n-1)::NNI
+ p1: % := n * sh(p, n1)
+ lt: LTERMS := [[t.k, sh(t.c, p1)]$TERM for t in ListOfTerms p.reg]
+ [p.c0 ** n, construct lt]$VPOLY
+
+ sh(p1:%, p2:%) ==
+ p1 case R => p1::R * p2
+ p2 case R => p1 * p2::R
+ lt1:LTERMS := ListOfTerms p1.reg ; lt2:LTERMS := ListOfTerms p2.reg
+ x: REGPOLY := construct [[t.k,sh(t.c,p2)]$TERM for t in lt1]
+ y: REGPOLY := construct [[t.k,sh(p1,t.c)]$TERM for t in lt2]
+ [p1.c0*p2.c0,x + y]$VPOLY
+
+ RemainderList p ==
+ p case R => []
+ ListOfTerms( p.reg)$REGPOLY
+
+ lquo(p1:%,p2:%):% ==
+ p2 case R => p1 * p2
+ p1 case R => p1 *$R p2.c0
+ p1 * p2.c0 +$% lquo1(ListOfTerms p1.reg, ListOfTerms p2.reg)
+
+ lquo1(x:LTERMS,y:LTERMS):% ==
+ null x => 0$%
+ null y => 0$%
+ x.first.k < y.first.k => lquo1(x,y.rest)
+ x.first.k = y.first.k =>
+ lquo(x.first.c,y.first.c) + lquo1(x.rest,y.rest)
+ return lquo1(x.rest,y)
+
+ coef(p1:%, p2:%):R ==
+ p1 case R => p1::R * constant p2
+ p2 case R => p1.c0 * p2::R
+ p1.c0 * p2.c0 +$R coef1(ListOfTerms p1.reg, ListOfTerms p2.reg)
+
+ coef1(x:LTERMS,y:LTERMS):R ==
+ null x => 0$R
+ null y => 0$R
+ x.first.k < y.first.k => coef1(x,y.rest)
+ x.first.k = y.first.k =>
+ coef(x.first.c,y.first.c) + coef1(x.rest,y.rest)
+ return coef1(x.rest,y)
+
+ --------------------------------------------------------------
+ outForm(p:REGPOLY): EX ==
+ le : List EX := [t.k::EX * t.c::EX for t in ListOfTerms p]
+ reduce(_+, reverse_! le)$List(EX)
+
+ coerce(p:$): EX ==
+ p case R => (p::R)::EX
+ p.c0 = 0 => outForm p.reg
+ p.c0::EX + outForm p.reg
+
+ 0 == 0$R::%
+ 1 == 1$R::%
+ constant? p == p case R
+ constant p ==
+ p case R => p
+ p.c0
+
+ simplifie p ==
+ p.reg = 0$REGPOLY => (p.c0)::%
+ p
+
+ coerce (v:VarSet):% ==
+ [0$R,coerce(v)$REGPOLY]$VPOLY
+
+ coerce (r:R):% == r::%
+ coerce (n:Integer) == n::R::%
+ coerce (w:WORD) ==
+ w = 1 => 1$R
+ (first w) * coerce(rest w)
+
+ expand p ==
+ p case R => p::R::XDPOLY
+ lt:LTERMS := ListOfTerms(p.reg)
+ ep:XDPOLY := (p.c0)::XDPOLY
+ for t in lt repeat
+ ep:= ep + t.k * expand(t.c)
+ ep
+
+ - p:% ==
+ p case R => -$R p
+ [- p.c0, - p.reg]$VPOLY
+
+ p1 + p2 ==
+ p1 case R and p2 case R => p1 +$R p2
+ p1 case R => [p1 + p2.c0 , p2.reg]$VPOLY
+ p2 case R => [p2 + p1.c0 , p1.reg]$VPOLY
+ simplifie [p1.c0 + p2.c0 , p1.reg +$REGPOLY p2.reg]$VPOLY
+
+ p1 - p2 ==
+ p1 case R and p2 case R => p1 -$R p2
+ p1 case R => [p1 - p2.c0 , -p2.reg]$VPOLY
+ p2 case R => [p1.c0 - p2 , p1.reg]$VPOLY
+ simplifie [p1.c0 - p2.c0 , p1.reg -$REGPOLY p2.reg]$VPOLY
+
+ n:Integer * p:% ==
+ n=0 => 0$%
+ p case R => n *$R p
+ -- [ n*p.c0,n*p.reg]$VPOLY
+ simplifie [ n*p.c0,n*p.reg]$VPOLY
+
+ r:R * p:% ==
+ r=0 => 0$%
+ p case R => r *$R p
+ -- [ r*p.c0,r*p.reg]$VPOLY
+ simplifie [ r*p.c0,r*p.reg]$VPOLY
+
+ p:% * r:R ==
+ r=0 => 0$%
+ p case R => p *$R r
+ -- [ p.c0 * r,p.reg * r]$VPOLY
+ simplifie [ r*p.c0,r*p.reg]$VPOLY
+
+ v:VarSet * p:% ==
+ p = 0 => 0$%
+ [0$R, v *$REGPOLY p]$VPOLY
+
+ p1:% * p2:% ==
+ p1 case R => p1::R * p2
+ p2 case R => p1 * p2::R
+ x:REGPOLY := p1.reg *$REGPOLY p2
+ y:REGPOLY := (p1.c0)::% *$REGPOLY p2.reg -- maladroit:(p1.c0)::% !!
+ -- [ p1.c0 * p2.c0 , x+y ]$VPOLY
+ simplifie [ p1.c0 * p2.c0 , x+y ]$VPOLY
+
+ lquo(p:%, v:VarSet):% ==
+ p case R => 0
+ coefficient(p.reg,v)$REGPOLY
+
+ lquo(p:%, w:WORD):% ==
+ w = 1$WORD => p
+ lquo(lquo(p,first w),rest w)
+
+ rquo(p:%, v:VarSet):% ==
+ p case R => 0
+ x:REGPOLY := construct [[t.k, a]$TERM for t in ListOfTerms(p.reg)
+ | (a:= rquo(t.c,v)) ^= 0 ]
+ simplifie [constant(coefficient(p.reg,v)) , x]$VPOLY
+
+ rquo(p:%, w:WORD):% ==
+ w = 1$WORD => p
+ rquo(rquo(p,rest w),first w)
+
+ coef(p:%, w:WORD):R ==
+ constant lquo(p,w)
+
+ quasiRegular? p ==
+ p case R => p = 0$R
+ p.c0 = 0$R
+
+ quasiRegular p ==
+ p case R => 0$%
+ [0$R,p.reg]$VPOLY
+
+ characteristic == characteristic()$R
+ recip p ==
+ p case R => recip(p::R)
+ "failed"
+
+ mindeg p ==
+ p case R =>
+ p = 0 => error "XRPOLY.mindeg: polynome nul !!"
+ 1$WORD
+ p.c0 ^= 0 => 1$WORD
+ "min"/[(t.k) *$WORD mindeg(t.c) for t in ListOfTerms p.reg]
+
+ maxdeg p ==
+ p case R =>
+ p = 0 => error "XRPOLY.maxdeg: polynome nul !!"
+ 1$WORD
+ "max"/[(t.k) *$WORD maxdeg(t.c) for t in ListOfTerms p.reg]
+
+ degree p ==
+ p = 0 => error "XRPOLY.degree: polynome nul !!"
+ length(maxdeg p)
+
+ map(fn,p) ==
+ p case R => fn(p::R)
+ x:REGPOLY := construct [[t.k,a]$TERM for t in ListOfTerms p.reg
+ |(a := map(fn,t.c)) ^= 0$R]
+ simplifie [fn(p.c0),x]$VPOLY
+
+ varList p ==
+ p case R => []
+ lv: List VarSet := "setUnion"/[varList(t.c) for t in ListOfTerms p.reg]
+ lv:= setUnion(lv,[t.k for t in ListOfTerms p.reg])
+ sort_!(lv)
+
+@
+\section{domain XPOLY XPolynomial}
+<<domain XPOLY XPolynomial>>=
+)abbrev domain XPOLY XPolynomial
+++ Author: Michel Petitot petitot@lifl.fr
+++ Date Created: 91
+++ Date Last Updated: 7 Juillet 92
+++ Fix History: compilation v 2.1 le 13 dec 98
+++ extend renomme en expand
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ This type supports multivariate polynomials
+++ whose set of variables is \spadtype{Symbol}.
+++ The representation is recursive.
+++ The coefficient ring may be non-commutative and the variables
+++ do not commute.
+++ However, coefficients and variables commute.
+++ Author: Michel Petitot (petitot@lifl.fr)
+
+XPolynomial(R:Ring) == XRecursivePolynomial(Symbol, R)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain OFMONOID OrderedFreeMonoid>>
+<<category FMCAT FreeModuleCat>>
+<<domain FM1 FreeModule1>>
+<<category XALG XAlgebra>>
+<<category XFALG XFreeAlgebra>>
+<<category XPOLYC XPolynomialsCat>>
+<<domain XPR XPolynomialRing>>
+<<domain XDPOLY XDistributedPolynomial>>
+<<domain XRPOLY XRecursivePolynomial>>
+<<domain XPOLY XPolynomial>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/ystream.spad.pamphlet b/src/algebra/ystream.spad.pamphlet
new file mode 100644
index 00000000..0a443168
--- /dev/null
+++ b/src/algebra/ystream.spad.pamphlet
@@ -0,0 +1,96 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra ystream.spad}
+\author{William Burge, Stephen M. Watt, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package YSTREAM ParadoxicalCombinatorsForStreams}
+<<package YSTREAM ParadoxicalCombinatorsForStreams>>=
+)abbrev package YSTREAM ParadoxicalCombinatorsForStreams
+++ Computation of fixed points of mappings on streams
+++ Author: Burge, Watt (revised by Williamson)
+++ Date Created: 1986
+++ Date Last Updated: 21 October 1989
+++ Keywords: stream, fixed point
+++ Examples:
+++ References:
+ParadoxicalCombinatorsForStreams(A):Exports == Implementation where
+ ++ This package implements fixed-point computations on streams.
+ A : Type
+ ST ==> Stream
+ L ==> List
+ I ==> Integer
+
+ Exports ==> with
+ Y: (ST A -> ST A) -> ST A
+ ++ Y(f) computes a fixed point of the function f.
+ Y: (L ST A -> L ST A,I) -> L ST A
+ ++ Y(g,n) computes a fixed point of the function g, where g takes
+ ++ a list of n streams and returns a list of n streams.
+
+ Implementation ==> add
+
+ Y f ==
+ y : ST A := CONS(0$I,0$I)$Lisp
+ j := f y
+ RPLACA(y,frst j)$Lisp
+ RPLACD(y,rst j)$Lisp
+ y
+
+ Y(g,n) ==
+ x : L ST A := [CONS(0$I,0$I)$Lisp for i in 1..n]
+ j := g x
+ for xi in x for ji in j repeat
+ RPLACA(xi,frst ji)$Lisp
+ RPLACD(xi,rst ji)$Lisp
+ x
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package YSTREAM ParadoxicalCombinatorsForStreams>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}
diff --git a/src/algebra/zerodim.spad.pamphlet b/src/algebra/zerodim.spad.pamphlet
new file mode 100644
index 00000000..6b1db2a9
--- /dev/null
+++ b/src/algebra/zerodim.spad.pamphlet
@@ -0,0 +1,1189 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra zerodim.spad}
+\author{Marc Moreno Maza}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package FGLMICPK FGLMIfCanPackage}
+<<package FGLMICPK FGLMIfCanPackage>>=
+)abbrev package FGLMICPK FGLMIfCanPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 08/02/1999
+++ Date Last Updated: 08/02/1999
+++ Description:
+++ This is just an interface between several packages and domains.
+++ The goal is to compute lexicographical Groebner bases
+++ of sets of polynomial with type \spadtype{Polynomial R}
+++ by the {\em FGLM} algorithm if this is possible (i.e.
+++ if the input system generates a zero-dimensional ideal).
+++ Version: 1.
+FGLMIfCanPackage(R,ls): Exports == Implementation where
+ R: GcdDomain
+ ls: List Symbol
+ V ==> OrderedVariableList ls
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ Q1 ==> Polynomial R
+ Q2 ==> HomogeneousDistributedMultivariatePolynomial(ls,R)
+ Q3 ==> DistributedMultivariatePolynomial(ls,R)
+ E2 ==> HomogeneousDirectProduct(#ls,NonNegativeInteger)
+ E3 ==> DirectProduct(#ls,NonNegativeInteger)
+ poltopol ==> PolToPol(ls, R)
+ lingrobpack ==> LinGroebnerPackage(ls,R)
+ groebnerpack2 ==> GroebnerPackage(R,E2,V,Q2)
+ groebnerpack3 ==> GroebnerPackage(R,E3,V,Q3)
+ Exports == with
+
+ zeroDimensional?: List(Q1) -> B
+ ++ \axiom{zeroDimensional?(lq1)} returns true iff
+ ++ \axiom{lq1} generates a zero-dimensional ideal
+ ++ w.r.t. the variables of \axiom{ls}.
+ fglmIfCan: List(Q1) -> Union(List(Q1), "failed")
+ ++ \axiom{fglmIfCan(lq1)} returns the lexicographical Groebner
+ ++ basis of \axiom{lq1} by using the {\em FGLM} strategy,
+ ++ if \axiom{zeroDimensional?(lq1)} holds.
+ groebner: List(Q1) -> List(Q1)
+ ++ \axiom{groebner(lq1)} returns the lexicographical Groebner
+ ++ basis of \axiom{lq1}. If \axiom{lq1} generates a zero-dimensional
+ ++ ideal then the {\em FGLM} strategy is used, otherwise
+ ++ the {\em Sugar} strategy is used.
+
+ Implementation == add
+
+ zeroDim?(lq2: List Q2): Boolean ==
+ lq2 := groebner(lq2)$groebnerpack2
+ empty? lq2 => false
+ #lq2 < #ls => false
+ lv: List(V) := [(variable(s)$V)::V for s in ls]
+ for q2 in lq2 while not empty?(lv) repeat
+ m := leadingMonomial(q2)
+ x := mainVariable(m)::V
+ if ground?(leadingCoefficient(univariate(m,x))) then
+ lv := remove(x, lv)
+ empty? lv
+
+ zeroDimensional?(lq1: List(Q1)): Boolean ==
+ lq2: List(Q2) := [pToHdmp(q1)$poltopol for q1 in lq1]
+ zeroDim?(lq2)
+
+ fglmIfCan(lq1:List(Q1)): Union(List(Q1),"failed") ==
+ lq2: List(Q2) := [pToHdmp(q1)$poltopol for q1 in lq1]
+ lq2 := groebner(lq2)$groebnerpack2
+ not zeroDim?(lq2) => "failed"::Union(List(Q1),"failed")
+ lq3: List(Q3) := totolex(lq2)$lingrobpack
+ lq1 := [dmpToP(q3)$poltopol for q3 in lq3]
+ lq1::Union(List(Q1),"failed")
+
+ groebner(lq1:List(Q1)): List(Q1) ==
+ lq2: List(Q2) := [pToHdmp(q1)$poltopol for q1 in lq1]
+ lq2 := groebner(lq2)$groebnerpack2
+ not zeroDim?(lq2) =>
+ lq3: List(Q3) := [pToDmp(q1)$poltopol for q1 in lq1]
+ lq3 := groebner(lq3)$groebnerpack3
+ [dmpToP(q3)$poltopol for q3 in lq3]
+ lq3: List(Q3) := totolex(lq2)$lingrobpack
+ [dmpToP(q3)$poltopol for q3 in lq3]
+
+@
+\section{domain RGCHAIN RegularChain}
+<<domain RGCHAIN RegularChain>>=
+)abbrev domain RGCHAIN RegularChain
+++ Author: Marc Moreno Maza
+++ Date Created: 01/1999
+++ Date Last Updated: 23/01/1999
+++ Description:
+++ A domain for regular chains (i.e. regular triangular sets) over
+++ a Gcd-Domain and with a fix list of variables.
+++ This is just a front-end for the \spadtype{RegularTriangularSet}
+++ domain constructor.
+++ Version: 1.
+
+RegularChain(R,ls): Exports == Implementation where
+ R : GcdDomain
+ ls: List Symbol
+ V ==> OrderedVariableList ls
+ E ==> IndexedExponents V
+ P ==> NewSparseMultivariatePolynomial(R,V)
+ TS ==> RegularTriangularSet(R,E,V,P)
+
+ Exports == RegularTriangularSetCategory(R,E,V,P) with
+ zeroSetSplit: (List P, Boolean, Boolean) -> List $
+ ++ \spad{zeroSetSplit(lp,clos?,info?)} returns a list \spad{lts} of regular
+ ++ chains such that the union of the closures of their regular zero sets
+ ++ equals the affine variety associated with \spad{lp}. Moreover,
+ ++ if \spad{clos?} is \spad{false} then the union of the regular zero
+ ++ set of the \spad{ts} (for \spad{ts} in \spad{lts}) equals this variety.
+ ++ If \spad{info?} is \spad{true} then some information is
+ ++ displayed during the computations. See
+ ++ \axiomOpFrom{zeroSetSplit}{RegularTriangularSet}.
+
+ Implementation == RegularTriangularSet(R,E,V,P)
+
+@
+\section{package LEXTRIPK LexTriangularPackage}
+<<package LEXTRIPK LexTriangularPackage>>=
+)abbrev package LEXTRIPK LexTriangularPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 08/02/1999
+++ Date Last Updated: 08/02/1999
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ A package for solving polynomial systems with finitely many solutions.
+++ The decompositions are given by means of regular triangular sets.
+++ The computations use lexicographical Groebner bases.
+++ The main operations are \axiomOpFrom{lexTriangular}{LexTriangularPackage}
+++ and \axiomOpFrom{squareFreeLexTriangular}{LexTriangularPackage}.
+++ The second one provide decompositions by means of square-free regular triangular sets.
+++ Both are based on the {\em lexTriangular} method described in [1].
+++ They differ from the algorithm described in [2] by the fact that
+++ multiciplities of the roots are not kept.
+++ With the \axiomOpFrom{squareFreeLexTriangular}{LexTriangularPackage} operation
+++ all multiciplities are removed. With the other operation some multiciplities may remain.
+++ Both operations admit an optional argument to produce normalized triangular sets. \newline
+++ References: \newline
+++ [1] D. LAZARD "Solving Zero-dimensional Algebraic Systems"
+++ published in the J. of Symbol. Comput. (1992) 13, 117-131.\newline
+++ [2] M. MORENO MAZA and R. RIOBOO "Computations of gcd over
+++ algebraic towers of simple extensions" In proceedings of AAECC11, Paris, 1995.\newline
+++ Version: 2.
+
+LexTriangularPackage(R,ls): Exports == Implementation where
+
+ R: GcdDomain
+ ls: List Symbol
+ V ==> OrderedVariableList ls
+ E ==> IndexedExponents V
+ P ==> NewSparseMultivariatePolynomial(R,V)
+ TS ==> RegularChain(R,ls)
+ ST ==> SquareFreeRegularTriangularSet(R,E,V,P)
+ Q1 ==> Polynomial R
+ PS ==> GeneralPolynomialSet(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ S ==> String
+ K ==> Fraction R
+ LP ==> List P
+ BWTS ==> Record(val : Boolean, tower : TS)
+ LpWTS ==> Record(val : (List P), tower : TS)
+ BWST ==> Record(val : Boolean, tower : ST)
+ LpWST ==> Record(val : (List P), tower : ST)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ quasicomppackTS ==> QuasiComponentPackage(R,E,V,P,TS)
+ regsetgcdpackTS ==> SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,TS)
+ normalizpackTS ==> NormalizationPackage(R,E,V,P,TS)
+ quasicomppackST ==> QuasiComponentPackage(R,E,V,P,ST)
+ regsetgcdpackST ==> SquareFreeRegularTriangularSetGcdPackage(R,E,V,P,ST)
+ normalizpackST ==> NormalizationPackage(R,E,V,P,ST)
+
+ Exports == with
+
+ zeroDimensional?: LP -> B
+ ++ \axiom{zeroDimensional?(lp)} returns true iff
+ ++ \axiom{lp} generates a zero-dimensional ideal
+ ++ w.r.t. the variables involved in \axiom{lp}.
+ fglmIfCan: LP -> Union(LP, "failed")
+ ++ \axiom{fglmIfCan(lp)} returns the lexicographical Groebner
+ ++ basis of \axiom{lp} by using the {\em FGLM} strategy,
+ ++ if \axiom{zeroDimensional?(lp)} holds .
+ groebner: LP -> LP
+ ++ \axiom{groebner(lp)} returns the lexicographical Groebner
+ ++ basis of \axiom{lp}. If \axiom{lp} generates a zero-dimensional
+ ++ ideal then the {\em FGLM} strategy is used, otherwise
+ ++ the {\em Sugar} strategy is used.
+ lexTriangular: (LP, B) -> List TS
+ ++ \axiom{lexTriangular(base, norm?)} decomposes the variety
+ ++ associated with \axiom{base} into regular chains.
+ ++ Thus a point belongs to this variety iff it is a regular
+ ++ zero of a regular set in in the output.
+ ++ Note that \axiom{base} needs to be a lexicographical Groebner basis
+ ++ of a zero-dimensional ideal. If \axiom{norm?} is \axiom{true}
+ ++ then the regular sets are normalized.
+ squareFreeLexTriangular: (LP, B) -> List ST
+ ++ \axiom{squareFreeLexTriangular(base, norm?)} decomposes the variety
+ ++ associated with \axiom{base} into square-free regular chains.
+ ++ Thus a point belongs to this variety iff it is a regular
+ ++ zero of a regular set in in the output.
+ ++ Note that \axiom{base} needs to be a lexicographical Groebner basis
+ ++ of a zero-dimensional ideal. If \axiom{norm?} is \axiom{true}
+ ++ then the regular sets are normalized.
+ zeroSetSplit: (LP, B) -> List TS
+ ++ \axiom{zeroSetSplit(lp, norm?)} decomposes the variety
+ ++ associated with \axiom{lp} into regular chains.
+ ++ Thus a point belongs to this variety iff it is a regular
+ ++ zero of a regular set in in the output.
+ ++ Note that \axiom{lp} needs to generate a zero-dimensional ideal.
+ ++ If \axiom{norm?} is \axiom{true} then the regular sets are normalized.
+ zeroSetSplit: (LP, B) -> List ST
+ ++ \axiom{zeroSetSplit(lp, norm?)} decomposes the variety
+ ++ associated with \axiom{lp} into square-free regular chains.
+ ++ Thus a point belongs to this variety iff it is a regular
+ ++ zero of a regular set in in the output.
+ ++ Note that \axiom{lp} needs to generate a zero-dimensional ideal.
+ ++ If \axiom{norm?} is \axiom{true} then the regular sets are normalized.
+
+ Implementation == add
+
+ trueVariables(lp: List(P)): List Symbol ==
+ lv: List V := variables([lp]$PS)
+ truels: List Symbol := []
+ for s in ls repeat
+ if member?(variable(s)::V, lv) then truels := cons(s,truels)
+ reverse truels
+
+ zeroDimensional?(lp:List(P)): Boolean ==
+ truels: List Symbol := trueVariables(lp)
+ fglmpack := FGLMIfCanPackage(R,truels)
+ lq1: List(Q1) := [p::Q1 for p in lp]
+ zeroDimensional?(lq1)$fglmpack
+
+ fglmIfCan(lp:List(P)): Union(List(P), "failed") ==
+ truels: List Symbol := trueVariables(lp)
+ fglmpack := FGLMIfCanPackage(R,truels)
+ lq1: List(Q1) := [p::Q1 for p in lp]
+ foo := fglmIfCan(lq1)$fglmpack
+ foo case "failed" => return("failed" :: Union(List(P), "failed"))
+ lp := [retract(q1)$P for q1 in (foo :: List(Q1))]
+ lp::Union(List(P), "failed")
+
+ groebner(lp:List(P)): List(P) ==
+ truels: List Symbol := trueVariables(lp)
+ fglmpack := FGLMIfCanPackage(R,truels)
+ lq1: List(Q1) := [p::Q1 for p in lp]
+ lq1 := groebner(lq1)$fglmpack
+ lp := [retract(q1)$P for q1 in lq1]
+
+ lexTriangular(base: List(P), norm?: Boolean): List(TS) ==
+ base := sort(infRittWu?,base)
+ base := remove(zero?, base)
+ any?(ground?, base) => []
+ ts: TS := empty()
+ toSee: List LpWTS := [[base,ts]$LpWTS]
+ toSave: List TS := []
+ while not empty? toSee repeat
+ lpwt := first toSee; toSee := rest toSee
+ lp := lpwt.val; ts := lpwt.tower
+ empty? lp => toSave := cons(ts, toSave)
+ p := first lp; lp := rest lp; v := mvar(p)
+ algebraic?(v,ts) =>
+ error "lexTriangular$LEXTRIPK: should never happen !"
+ norm? and zero? remainder(init(p),ts).polnum =>
+ toSee := cons([lp, ts]$LpWTS, toSee)
+ (not norm?) and zero? (initiallyReduce(init(p),ts)) =>
+ toSee := cons([lp, ts]$LpWTS, toSee)
+ lbwt: List BWTS := invertible?(init(p),ts)$TS
+ while (not empty? lbwt) repeat
+ bwt := first lbwt; lbwt := rest lbwt
+ b := bwt.val; us := bwt.tower
+ (not b) => toSee := cons([lp, us], toSee)
+ lus: List TS
+ if norm?
+ then
+ newp := normalizedAssociate(p,us)$normalizpackTS
+ lus := [internalAugment(newp,us)$TS]
+ else
+ newp := p
+ lus := augment(newp,us)$TS
+ newlp := lp
+ while (not empty? newlp) and (mvar(first newlp) = v) repeat
+ newlp := rest newlp
+ for us in lus repeat
+ toSee := cons([newlp, us]$LpWTS, toSee)
+ algebraicSort(toSave)$quasicomppackTS
+
+ zeroSetSplit(lp:List(P), norm?:B): List TS ==
+ bar := fglmIfCan(lp)
+ bar case "failed" =>
+ error "zeroSetSplit$LEXTRIPK: #1 not zero-dimensional"
+ lexTriangular(bar::(List P),norm?)
+
+ squareFreeLexTriangular(base: List(P), norm?: Boolean): List(ST) ==
+ base := sort(infRittWu?,base)
+ base := remove(zero?, base)
+ any?(ground?, base) => []
+ ts: ST := empty()
+ toSee: List LpWST := [[base,ts]$LpWST]
+ toSave: List ST := []
+ while not empty? toSee repeat
+ lpwt := first toSee; toSee := rest toSee
+ lp := lpwt.val; ts := lpwt.tower
+ empty? lp => toSave := cons(ts, toSave)
+ p := first lp; lp := rest lp; v := mvar(p)
+ algebraic?(v,ts) =>
+ error "lexTriangular$LEXTRIPK: should never happen !"
+ norm? and zero? remainder(init(p),ts).polnum =>
+ toSee := cons([lp, ts]$LpWST, toSee)
+ (not norm?) and zero? (initiallyReduce(init(p),ts)) =>
+ toSee := cons([lp, ts]$LpWST, toSee)
+ lbwt: List BWST := invertible?(init(p),ts)$ST
+ while (not empty? lbwt) repeat
+ bwt := first lbwt; lbwt := rest lbwt
+ b := bwt.val; us := bwt.tower
+ (not b) => toSee := cons([lp, us], toSee)
+ lus: List ST
+ if norm?
+ then
+ newp := normalizedAssociate(p,us)$normalizpackST
+ lus := augment(newp,us)$ST
+ else
+ lus := augment(p,us)$ST
+ newlp := lp
+ while (not empty? newlp) and (mvar(first newlp) = v) repeat
+ newlp := rest newlp
+ for us in lus repeat
+ toSee := cons([newlp, us]$LpWST, toSee)
+ algebraicSort(toSave)$quasicomppackST
+
+ zeroSetSplit(lp:List(P), norm?:B): List ST ==
+ bar := fglmIfCan(lp)
+ bar case "failed" =>
+ error "zeroSetSplit$LEXTRIPK: #1 not zero-dimensional"
+ squareFreeLexTriangular(bar::(List P),norm?)
+
+@
+\section{package IRURPK InternalRationalUnivariateRepresentationPackage}
+<<package IRURPK InternalRationalUnivariateRepresentationPackage>>=
+)abbrev package IRURPK InternalRationalUnivariateRepresentationPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 01/1999
+++ Date Last Updated: 23/01/1999
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ Description:
+++ An internal package for computing the rational univariate representation
+++ of a zero-dimensional algebraic variety given by a square-free
+++ triangular set.
+++ The main operation is \axiomOpFrom{rur}{InternalRationalUnivariateRepresentationPackage}.
+++ It is based on the {\em generic} algorithm description in [1]. \newline References:
+++ [1] D. LAZARD "Solving Zero-dimensional Algebraic Systems"
+++ Journal of Symbolic Computation, 1992, 13, 117-131
+++ Version: 1.
+
+InternalRationalUnivariateRepresentationPackage(R,E,V,P,TS): Exports == Implementation where
+ R : Join(EuclideanDomain,CharacteristicZero)
+ E : OrderedAbelianMonoidSup
+ V : OrderedSet
+ P : RecursivePolynomialCategory(R,E,V)
+ TS : SquareFreeRegularTriangularSetCategory(R,E,V,P)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ LV ==> List V
+ LP ==> List P
+ PWT ==> Record(val: P, tower: TS)
+ LPWT ==> Record(val: LP, tower: TS)
+ WIP ==> Record(pol: P, gap: Z, tower: TS)
+ BWT ==> Record(val:Boolean, tower: TS)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,P)
+ normpack ==> NormalizationPackage(R,E,V,P,TS)
+
+ Exports == with
+
+ rur: (TS,B) -> List TS
+ ++ \spad{rur(ts,univ?)} returns a rational univariate representation
+ ++ of \spad{ts}. This assumes that the lowest polynomial in \spad{ts}
+ ++ is a variable \spad{v} which does not occur in the other polynomials
+ ++ of \spad{ts}. This variable will be used to define the simple
+ ++ algebraic extension over which these other polynomials will be
+ ++ rewritten as univariate polynomials with degree one.
+ ++ If \spad{univ?} is \spad{true} then these polynomials will have
+ ++ a constant initial.
+ checkRur: (TS, List TS) -> Boolean
+ ++ \spad{checkRur(ts,lus)} returns \spad{true} if \spad{lus}
+ ++ is a rational univariate representation of \spad{ts}.
+
+ Implementation == add
+
+ checkRur(ts: TS, lts: List TS): Boolean ==
+ f0 := last(ts)::P
+ z := mvar(f0)
+ ts := collectUpper(ts,z)
+ dts: N := degree(ts)
+ lp := parts(ts)
+ dlts: N := 0
+ for us in lts repeat
+ dlts := dlts + degree(us)
+ rems := [removeZero(p,us) for p in lp]
+ not every?(zero?,rems) =>
+ output(us::OutputForm)$OutputPackage
+ return false
+ (dts =$N dlts)@Boolean
+
+ convert(p:P,sqfr?:B):TS ==
+ -- if sqfr? ASSUME p is square-free
+ newts: TS := empty()
+ sqfr? => internalAugment(p,newts)
+ p := squareFreePart(p)
+ internalAugment(p,newts)
+
+ prepareRur(ts: TS): List LPWT ==
+ not purelyAlgebraic?(ts)$TS =>
+ error "rur$IRURPK: #1 is not zero-dimensional"
+ lp: LP := parts(ts)$TS
+ lp := sort(infRittWu?,lp)
+ empty? lp =>
+ error "rur$IRURPK: #1 is empty"
+ f0 := first lp; lp := rest lp
+-- not (one?(init(f0)) and one?(mdeg(f0)) and zero?(tail(f0))) =>
+ not ((init(f0) = 1) and (mdeg(f0) = 1) and zero?(tail(f0))) =>
+ error "rur$IRURPK: #1 has no generating root."
+ empty? lp =>
+ error "rur$IRURPK: #1 has a generating root but no indeterminates"
+ z: V := mvar(f0)
+ f1 := first lp; lp := rest lp
+ x1: V := mvar(f1)
+ newf1 := x1::P - z::P
+ toSave: List LPWT := []
+ for ff1 in irreducibleFactors([f1])$polsetpack repeat
+ newf0 := eval(ff1,mvar(f1),f0)
+ ts := internalAugment(newf1,convert(newf0,true)@TS)
+ toSave := cons([lp,ts],toSave)
+ toSave
+
+ makeMonic(z:V,c:P,r:P,ts:TS,s:P,univ?:B): TS ==
+ --ASSUME r is a irreducible univariate polynomial in z
+ --ASSUME c and s only depends on z and mvar(s)
+ --ASSUME c and a have main degree 1
+ --ASSUME c and s have a constant initial
+ --ASSUME mvar(ts) < mvar(s)
+ lp: LP := parts(ts)
+ lp := sort(infRittWu?,lp)
+ newts: TS := convert(r,true)@TS
+ s := remainder(s,newts).polnum
+ if univ?
+ then
+ s := normalizedAssociate(s,newts)$normpack
+ for p in lp repeat
+ p := lazyPrem(eval(p,z,c),s)
+ p := remainder(p,newts).polnum
+ newts := internalAugment(p,newts)
+ internalAugment(s,newts)
+
+ next(lambda:Z):Z ==
+ if lambda < 0 then lambda := - lambda + 1 else lambda := - lambda
+
+ makeLinearAndMonic(p: P, xi: V, ts: TS, univ?:B, check?: B, info?: B): List TS ==
+ -- if check? THEN some VERIFICATIONS are performed
+ -- if info? THEN some INFORMATION is displayed
+ f0 := last(ts)::P
+ z: V := mvar(f0)
+ lambda: Z := 1
+ ts := collectUpper(ts,z)
+ toSee: List WIP := [[f0,lambda,ts]$WIP]
+ toSave: List TS := []
+ while not empty? toSee repeat
+ wip := first toSee; toSee := rest toSee
+ (f0, lambda, ts) := (wip.pol, wip.gap, wip.tower)
+ if check? and ((not univariate?(f0)$polsetpack) or (mvar(f0) ~= z))
+ then
+ output("Bad f0: ")$OutputPackage
+ output(f0::OutputForm)$OutputPackage
+ c: P := lambda * xi::P + z::P
+ f := eval(f0,z,c); q := eval(p,z,c)
+ prs := subResultantChain(q,f)
+ r := first prs; prs := rest prs
+ check? and ((not zero? degree(r,xi)) or (empty? prs)) =>
+ error "rur$IRURPK: should never happen !"
+ s := first prs; prs := rest prs
+ check? and (zero? degree(s,xi)) and (empty? prs) =>
+ error "rur$IRURPK: should never happen !!"
+ if zero? degree(s,xi) then s := first prs
+-- not one? degree(s,xi) =>
+ not (degree(s,xi) = 1) =>
+ toSee := cons([f0,next(lambda),ts]$WIP,toSee)
+ h := init(s)
+ r := squareFreePart(r)
+ ground?(h) or ground?(gcd(h,r)) =>
+ for fr in irreducibleFactors([r])$polsetpack repeat
+ ground? fr => "leave"
+ toSave := cons(makeMonic(z,c,fr,ts,s,univ?),toSave)
+ if info?
+ then
+ output("Unlucky lambda")$OutputPackage
+ output(h::OutputForm)$OutputPackage
+ output(r::OutputForm)$OutputPackage
+ toSee := cons([f0,next(lambda),ts]$WIP,toSee)
+ toSave
+
+ rur (ts: TS,univ?:Boolean): List TS ==
+ toSee: List LPWT := prepareRur(ts)
+ toSave: List TS := []
+ while not empty? toSee repeat
+ wip := first toSee; toSee := rest toSee
+ ts: TS := wip.tower
+ lp: LP := wip.val
+ empty? lp => toSave := cons(ts,toSave)
+ p := first lp; lp := rest lp
+ xi: V := mvar(p)
+ p := remainder(p,ts).polnum
+ if not univ?
+ then
+ p := primitivePart stronglyReduce(p,ts)
+ ground?(p) or (mvar(p) < xi) =>
+ error "rur$IRUROK: should never happen"
+-- (one? mdeg(p)) and (ground? init(p)) =>
+ (mdeg(p) = 1) and (ground? init(p)) =>
+ ts := internalAugment(p,ts)
+ wip := [lp,ts]
+ toSee := cons(wip,toSee)
+ lts := makeLinearAndMonic(p,xi,ts,univ?,false,false)
+ for ts in lts repeat
+ wip := [lp,ts]
+ toSee := cons(wip,toSee)
+ toSave
+
+@
+\section{package RURPK RationalUnivariateRepresentationPackage}
+<<package RURPK RationalUnivariateRepresentationPackage>>=
+)abbrev package RURPK RationalUnivariateRepresentationPackage
+++ Author: Marc Moreno Maza
+++ Date Created: 01/1999
+++ Date Last Updated: 23/01/1999
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Description:
+++ A package for computing the rational univariate representation
+++ of a zero-dimensional algebraic variety given by a regular
+++ triangular set. This package is essentially an interface for the
+++ \spadtype{InternalRationalUnivariateRepresentationPackage} constructor.
+++ It is used in the \spadtype{ZeroDimensionalSolvePackage}
+++ for solving polynomial systems with finitely many solutions.
+++ Version: 1.
+
+RationalUnivariateRepresentationPackage(R,ls): Exports == Implementation where
+ R : Join(EuclideanDomain,CharacteristicZero)
+ ls: List Symbol
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ P ==> Polynomial R
+ LP ==> List P
+ U ==> SparseUnivariatePolynomial(R)
+ RUR ==> Record(complexRoots: U, coordinates: LP)
+
+ Exports == with
+
+ rur: (LP,Boolean) -> List RUR
+ ++ \spad{rur(lp,univ?)} returns a rational univariate representation
+ ++ of \spad{lp}. This assumes that \spad{lp} defines a regular
+ ++ triangular \spad{ts} whose associated variety is zero-dimensional
+ ++ over \spad{R}. \spad{rur(lp,univ?)} returns a list of items
+ ++ \spad{[u,lc]} where \spad{u} is an irreducible univariate polynomial
+ ++ and each \spad{c} in \spad{lc} involves two variables: one from \spad{ls},
+ ++ called the coordinate of \spad{c}, and an extra variable which
+ ++ represents any root of \spad{u}. Every root of \spad{u} leads to
+ ++ a tuple of values for the coordinates of \spad{lc}. Moreover,
+ ++ a point \spad{x} belongs to the variety associated with \spad{lp} iff
+ ++ there exists an item \spad{[u,lc]} in \spad{rur(lp,univ?)} and
+ ++ a root \spad{r} of \spad{u} such that \spad{x} is given by the
+ ++ tuple of values for the coordinates of \spad{lc} evaluated at \spad{r}.
+ ++ If \spad{univ?} is \spad{true} then each polynomial \spad{c}
+ ++ will have a constant leading coefficient w.r.t. its coordinate.
+ ++ See the example which illustrates the \spadtype{ZeroDimensionalSolvePackage}
+ ++ package constructor.
+ rur: (LP) -> List RUR
+ ++ \spad{rur(lp)} returns the same as \spad{rur(lp,true)}
+ rur: (LP,Boolean,Boolean) -> List RUR
+ ++ \spad{rur(lp,univ?,check?)} returns the same as \spad{rur(lp,true)}.
+ ++ Moreover, if \spad{check?} is \spad{true} then the result is checked.
+
+ Implementation == add
+ news: Symbol := new()$Symbol
+ lv: List Symbol := concat(ls,news)
+ V ==> OrderedVariableList(lv)
+ Q ==> NewSparseMultivariatePolynomial(R,V)
+ E ==> IndexedExponents V
+ TS ==> SquareFreeRegularTriangularSet(R,E,V,Q)
+ QWT ==> Record(val: Q, tower: TS)
+ LQWT ==> Record(val: List Q, tower: TS)
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E,V,Q)
+ normpack ==> NormalizationPackage(R,E,V,Q,TS)
+ rurpack ==> InternalRationalUnivariateRepresentationPackage(R,E,V,Q,TS)
+ newv: V := variable(news)::V
+ newq : Q := newv :: Q
+
+ rur(lp: List P, univ?: Boolean, check?: Boolean): List RUR ==
+ lp := remove(zero?,lp)
+ empty? lp =>
+ error "rur$RURPACK: #1 is empty"
+ any?(ground?,lp) =>
+ error "rur$RURPACK: #1 is not a triangular set"
+ ts: TS := [[newq]$(List Q)]
+ lq: List Q := []
+ for p in lp repeat
+ rif: Union(Q,"failed") := retractIfCan(p)$Q
+ rif case "failed" =>
+ error "rur$RURPACK: #1 is not a subset of R[ls]"
+ q: Q := rif::Q
+ lq := cons(q,lq)
+ lq := sort(infRittWu?,lq)
+ toSee: List LQWT := [[lq,ts]$LQWT]
+ toSave: List TS := []
+ while not empty? toSee repeat
+ lqwt := first toSee; toSee := rest toSee
+ lq := lqwt.val; ts := lqwt.tower
+ empty? lq =>
+ -- output(ts::OutputForm)$OutputPackage
+ toSave := cons(ts,toSave)
+ q := first lq; lq := rest lq
+ not (mvar(q) > mvar(ts)) =>
+ error "rur$RURPACK: #1 is not a triangular set"
+ empty? (rest(ts)::TS) =>
+ lfq := irreducibleFactors([q])$polsetpack
+ for fq in lfq repeat
+ newts := internalAugment(fq,ts)
+ newlq := [remainder(q,newts).polnum for q in lq]
+ toSee := cons([newlq,newts]$LQWT,toSee)
+ lsfqwt: List QWT := squareFreePart(q,ts)
+ for qwt in lsfqwt repeat
+ q := qwt.val; ts := qwt.tower
+ if not ground? init(q)
+ then
+ q := normalizedAssociate(q,ts)$normpack
+ newts := internalAugment(q,ts)
+ newlq := [remainder(q,newts).polnum for q in lq]
+ toSee := cons([newlq,newts]$LQWT,toSee)
+ toReturn: List RUR := []
+ for ts in toSave repeat
+ lus := rur(ts,univ?)$rurpack
+ check? and (not checkRur(ts,lus)$rurpack) =>
+ output("RUR for: ")$OutputPackage
+ output(ts::OutputForm)$OutputPackage
+ output("Is: ")$OutputPackage
+ for us in lus repeat output(us::OutputForm)$OutputPackage
+ error "rur$RURPACK: bad result with function rur$IRURPK"
+ for us in lus repeat
+ g: U := univariate(select(us,newv)::Q)$Q
+ lc: LP := [convert(q)@P for q in parts(collectUpper(us,newv))]
+ toReturn := cons([g,lc]$RUR, toReturn)
+ toReturn
+
+ rur(lp: List P, univ?: Boolean): List RUR ==
+ rur(lp,univ?,false)
+
+ rur(lp: List P): List RUR == rur(lp,true)
+
+@
+\section{package ZDSOLVE ZeroDimensionalSolvePackage}
+Based on triangular decompositions and the {\bf RealClosure} constructor,
+the pacakge {\bf ZeroDimensionalSolvePackage} provides operations for
+computing symbolically the real or complex roots of polynomial systems
+with finitely many solutions.
+<<package ZDSOLVE ZeroDimensionalSolvePackage>>=
+)abbrev package ZDSOLVE ZeroDimensionalSolvePackage
+++ Author: Marc Moreno Maza
+++ Date Created: 23/01/1999
+++ Date Last Updated: 08/02/1999
+++ Basic Functions:
+++ Related Constructors:
+++ Also See:
+++ AMS Classifications:
+++ Keywords:
+++ References:
+++ Description:
+++ A package for computing symbolically the complex and real roots of
+++ zero-dimensional algebraic systems over the integer or rational
+++ numbers. Complex roots are given by means of univariate representations
+++ of irreducible regular chains. Real roots are given by means of tuples
+++ of coordinates lying in the \spadtype{RealClosure} of the coefficient ring.
+++ This constructor takes three arguments. The first one \spad{R} is the
+++ coefficient ring. The second one \spad{ls} is the list of variables involved
+++ in the systems to solve. The third one must be \spad{concat(ls,s)} where
+++ \spad{s} is an additional symbol used for the univariate representations.
+++ WARNING: The third argument is not checked.
+++ All operations are based on triangular decompositions.
+++ The default is to compute these decompositions directly from the input
+++ system by using the \spadtype{RegularChain} domain constructor.
+++ The lexTriangular algorithm can also be used for computing these decompositions
+++ (see the \spadtype{LexTriangularPackage} package constructor).
+++ For that purpose, the operations \axiomOpFrom{univariateSolve}{ZeroDimensionalSolvePackage},
+++ \axiomOpFrom{realSolve}{ZeroDimensionalSolvePackage} and
+++ \axiomOpFrom{positiveSolve}{ZeroDimensionalSolvePackage} admit an optional
+++ argument. \newline Author: Marc Moreno Maza.
+
+++ Version: 1.
+
+ZeroDimensionalSolvePackage(R,ls,ls2): Exports == Implementation where
+ R : Join(OrderedRing,EuclideanDomain,CharacteristicZero,RealConstant)
+ ls: List Symbol
+ ls2: List Symbol
+ V ==> OrderedVariableList(ls)
+ N ==> NonNegativeInteger
+ Z ==> Integer
+ B ==> Boolean
+ P ==> Polynomial R
+ LP ==> List P
+ LS ==> List Symbol
+ Q ==> NewSparseMultivariatePolynomial(R,V)
+ U ==> SparseUnivariatePolynomial(R)
+ TS ==> RegularChain(R,ls)
+ RUR ==> Record(complexRoots: U, coordinates: LP)
+ K ==> Fraction R
+ RC ==> RealClosure(K)
+ PRC ==> Polynomial RC
+ REALSOL ==> List RC
+ URC ==> SparseUnivariatePolynomial RC
+ V2 ==> OrderedVariableList(ls2)
+ Q2 ==> NewSparseMultivariatePolynomial(R,V2)
+ E2 ==> IndexedExponents V2
+ ST ==> SquareFreeRegularTriangularSet(R,E2,V2,Q2)
+ Q2WT ==> Record(val: Q2, tower: ST)
+ LQ2WT ==> Record(val: List(Q2), tower: ST)
+ WIP ==> Record(reals: List(RC), vars: List(Symbol), pols: List(Q2))
+ polsetpack ==> PolynomialSetUtilitiesPackage(R,E2,V2,Q2)
+ normpack ==> NormalizationPackage(R,E2,V2,Q2,ST)
+ rurpack ==> InternalRationalUnivariateRepresentationPackage(R,E2,V2,Q2,ST)
+ quasicomppack ==> SquareFreeQuasiComponentPackage(R,E2,V2,Q2,ST)
+ lextripack ==> LexTriangularPackage(R,ls)
+
+ Exports == with
+ triangSolve: (LP,B,B) -> List RegularChain(R,ls)
+ ++ \spad{triangSolve(lp,info?,lextri?)} decomposes the variety
+ ++ associated with \axiom{lp} into regular chains.
+ ++ Thus a point belongs to this variety iff it is a regular
+ ++ zero of a regular set in in the output.
+ ++ Note that \axiom{lp} needs to generate a zero-dimensional ideal.
+ ++ If \axiom{lp} is not zero-dimensional then the result is only
+ ++ a decomposition of its zero-set in the sense of the closure
+ ++ (w.r.t. Zarisky topology).
+ ++ Moreover, if \spad{info?} is \spad{true} then some information is
+ ++ displayed during the computations.
+ ++ See \axiomOpFrom{zeroSetSplit}{RegularTriangularSetCategory}(lp,true,info?).
+ ++ If \spad{lextri?} is \spad{true} then the lexTriangular algorithm is called
+ ++ from the \spadtype{LexTriangularPackage} constructor
+ ++ (see \axiomOpFrom{zeroSetSplit}{LexTriangularPackage}(lp,false)).
+ ++ Otherwise, the triangular decomposition is computed directly from the input
+ ++ system by using the \axiomOpFrom{zeroSetSplit}{RegularChain} from \spadtype{RegularChain}.
+ triangSolve: (LP,B) -> List RegularChain(R,ls)
+ ++ \spad{triangSolve(lp,info?)} returns the same as \spad{triangSolve(lp,false)}
+ triangSolve: LP -> List RegularChain(R,ls)
+ ++ \spad{triangSolve(lp)} returns the same as \spad{triangSolve(lp,false,false)}
+ univariateSolve: RegularChain(R,ls) -> List Record(complexRoots: U, coordinates: LP)
+ ++ \spad{univariateSolve(ts)} returns a univariate representation
+ ++ of \spad{ts}.
+ ++ See \axiomOpFrom{rur}{RationalUnivariateRepresentationPackage}(lp,true).
+ univariateSolve: (LP,B,B,B) -> List RUR
+ ++ \spad{univariateSolve(lp,info?,check?,lextri?)} returns a univariate
+ ++ representation of the variety associated with \spad{lp}.
+ ++ Moreover, if \spad{info?} is \spad{true} then some information is
+ ++ displayed during the decomposition into regular chains.
+ ++ If \spad{check?} is \spad{true} then the result is checked.
+ ++ See \axiomOpFrom{rur}{RationalUnivariateRepresentationPackage}(lp,true).
+ ++ If \spad{lextri?} is \spad{true} then the lexTriangular algorithm is called
+ ++ from the \spadtype{LexTriangularPackage} constructor
+ ++ (see \axiomOpFrom{zeroSetSplit}{LexTriangularPackage}(lp,false)).
+ ++ Otherwise, the triangular decomposition is computed directly from the input
+ ++ system by using the \axiomOpFrom{zeroSetSplit}{RegularChain} from \spadtype{RegularChain}.
+ univariateSolve: (LP,B,B) -> List RUR
+ ++ \spad{univariateSolve(lp,info?,check?)} returns the same as
+ ++ \spad{univariateSolve(lp,info?,check?,false)}.
+ univariateSolve: (LP,B) -> List RUR
+ ++ \spad{univariateSolve(lp,info?)} returns the same as
+ ++ \spad{univariateSolve(lp,info?,false,false)}.
+ univariateSolve: LP -> List RUR
+ ++ \spad{univariateSolve(lp)} returns the same as
+ ++ \spad{univariateSolve(lp,false,false,false)}.
+ realSolve: RegularChain(R,ls) -> List REALSOL
+ ++ \spad{realSolve(ts)} returns the set of the points in the regular
+ ++ zero set of \spad{ts} whose coordinates are all real.
+ ++ WARNING: For each set of coordinates given by \spad{realSolve(ts)}
+ ++ the ordering of the indeterminates is reversed w.r.t. \spad{ls}.
+ realSolve: (LP,B,B,B) -> List REALSOL
+ ++ \spad{realSolve(ts,info?,check?,lextri?)} returns the set of the points
+ ++ in the variety associated with \spad{lp} whose coordinates are all real.
+ ++ Moreover, if \spad{info?} is \spad{true} then some information is
+ ++ displayed during decomposition into regular chains.
+ ++ If \spad{check?} is \spad{true} then the result is checked.
+ ++ If \spad{lextri?} is \spad{true} then the lexTriangular algorithm is called
+ ++ from the \spadtype{LexTriangularPackage} constructor
+ ++ (see \axiomOpFrom{zeroSetSplit}{LexTriangularPackage}(lp,false)).
+ ++ Otherwise, the triangular decomposition is computed directly from the input
+ ++ system by using the \axiomOpFrom{zeroSetSplit}{RegularChain} from \spadtype{RegularChain}.
+ ++ WARNING: For each set of coordinates given by \spad{realSolve(ts,info?,check?,lextri?)}
+ ++ the ordering of the indeterminates is reversed w.r.t. \spad{ls}.
+ realSolve: (LP,B,B) -> List REALSOL
+ ++ \spad{realSolve(ts,info?,check?)} returns the same as \spad{realSolve(ts,info?,check?,false)}.
+ realSolve: (LP,B) -> List REALSOL
+ ++ \spad{realSolve(ts,info?)} returns the same as \spad{realSolve(ts,info?,false,false)}.
+ realSolve: LP -> List REALSOL
+ ++ \spad{realSolve(lp)} returns the same as \spad{realSolve(ts,false,false,false)}
+ positiveSolve: RegularChain(R,ls) -> List REALSOL
+ ++ \spad{positiveSolve(ts)} returns the points of the regular
+ ++ set of \spad{ts} with (real) strictly positive coordinates.
+ positiveSolve: (LP,B,B) -> List REALSOL
+ ++ \spad{positiveSolve(lp,info?,lextri?)} returns the set of the points
+ ++ in the variety associated with \spad{lp} whose coordinates are (real) strictly positive.
+ ++ Moreover, if \spad{info?} is \spad{true} then some information is
+ ++ displayed during decomposition into regular chains.
+ ++ If \spad{lextri?} is \spad{true} then the lexTriangular algorithm is called
+ ++ from the \spadtype{LexTriangularPackage} constructor
+ ++ (see \axiomOpFrom{zeroSetSplit}{LexTriangularPackage}(lp,false)).
+ ++ Otherwise, the triangular decomposition is computed directly from the input
+ ++ system by using the \axiomOpFrom{zeroSetSplit}{RegularChain} from \spadtype{RegularChain}.
+ ++ WARNING: For each set of coordinates given by \spad{positiveSolve(lp,info?,lextri?)}
+ ++ the ordering of the indeterminates is reversed w.r.t. \spad{ls}.
+ positiveSolve: (LP,B) -> List REALSOL
+ ++ \spad{positiveSolve(lp)} returns the same as \spad{positiveSolve(lp,info?,false)}.
+ positiveSolve: LP -> List REALSOL
+ ++ \spad{positiveSolve(lp)} returns the same as \spad{positiveSolve(lp,false,false)}.
+ squareFree: (TS) -> List ST
+ ++ \spad{squareFree(ts)} returns the square-free factorization of \spad{ts}.
+ ++ Moreover, each factor is a Lazard triangular set and the decomposition
+ ++ is a Kalkbrener split of \spad{ts}, which is enough here for
+ ++ the matter of solving zero-dimensional algebraic systems.
+ ++ WARNING: \spad{ts} is not checked to be zero-dimensional.
+ convert: Q -> Q2
+ ++ \spad{convert(q)} converts \spad{q}.
+ convert: P -> PRC
+ ++ \spad{convert(p)} converts \spad{p}.
+ convert: Q2 -> PRC
+ ++ \spad{convert(q)} converts \spad{q}.
+ convert: U -> URC
+ ++ \spad{convert(u)} converts \spad{u}.
+ convert: ST -> List Q2
+ ++ \spad{convert(st)} returns the members of \spad{st}.
+
+ Implementation == add
+ news: Symbol := last(ls2)$(List Symbol)
+ newv: V2 := (variable(news)$V2)::V2
+ newq: Q2 := newv :: Q2
+
+ convert(q:Q):Q2 ==
+ ground? q => (ground(q))::Q2
+ q2: Q2 := 0
+ while not ground?(q) repeat
+ v: V := mvar(q)
+ d: N := mdeg(q)
+ v2: V2 := (variable(convert(v)@Symbol)$V2)::V2
+ iq2: Q2 := convert(init(q))@Q2
+ lq2: Q2 := (v2 :: Q2)
+ lq2 := lq2 ** d
+ q2 := iq2 * lq2 + q2
+ q := tail(q)
+ q2 + (ground(q))::Q2
+
+ squareFree(ts:TS):List(ST) ==
+ irred?: Boolean := false
+ st: ST := [[newq]$(List Q2)]
+ lq: List(Q2) := [convert(p)@Q2 for p in parts(ts)]
+ lq := sort(infRittWu?,lq)
+ toSee: List LQ2WT := []
+ if irred?
+ then
+ lf := irreducibleFactors([first lq])$polsetpack
+ lq := rest lq
+ for f in lf repeat
+ toSee := cons([cons(f,lq),st]$LQ2WT, toSee)
+ else
+ toSee := [[lq,st]$LQ2WT]
+ toSave: List ST := []
+ while not empty? toSee repeat
+ lqwt := first toSee; toSee := rest toSee
+ lq := lqwt.val; st := lqwt.tower
+ empty? lq =>
+ toSave := cons(st,toSave)
+ q := first lq; lq := rest lq
+ lsfqwt: List Q2WT := squareFreePart(q,st)$ST
+ for sfqwt in lsfqwt repeat
+ q := sfqwt.val; st := sfqwt.tower
+ if not ground? init(q)
+ then
+ q := normalizedAssociate(q,st)$normpack
+ newts := internalAugment(q,st)$ST
+ newlq := [remainder(q,newts).polnum for q in lq]
+ toSee := cons([newlq,newts]$LQ2WT,toSee)
+ toSave
+
+
+ triangSolve(lp: LP, info?: B, lextri?: B): List TS ==
+ lq: List(Q) := [convert(p)$Q for p in lp]
+ lextri? => zeroSetSplit(lq,false)$lextripack
+ zeroSetSplit(lq,true,info?)$TS
+
+ triangSolve(lp: LP, info?: B): List TS == triangSolve(lp,info?,false)
+
+ triangSolve(lp: LP): List TS == triangSolve(lp,false)
+
+ convert(u: U): URC ==
+ zero? u => 0
+ ground? u => ((ground(u) :: K)::RC)::URC
+ uu: URC := 0
+ while not ground? u repeat
+ uu := monomial((leadingCoefficient(u) :: K):: RC,degree(u)) + uu
+ u := reductum u
+ uu + ((ground(u) :: K)::RC)::URC
+
+ coerceFromRtoRC(r:R): RC ==
+ (r::K)::RC
+
+ convert(p:P): PRC ==
+ map(coerceFromRtoRC,p)$PolynomialFunctions2(R,RC)
+
+ convert(q2:Q2): PRC ==
+ p: P := coerce(q2)$Q2
+ convert(p)@PRC
+
+ convert(sts:ST): List Q2 ==
+ lq2: List(Q2) := parts(sts)$ST
+ lq2 := sort(infRittWu?,lq2)
+ rest(lq2)
+
+ realSolve(ts: TS): List REALSOL ==
+ lsts: List ST := squareFree(ts)
+ lr: REALSOL := []
+ lv: List Symbol := []
+ toSee := [[lr,lv,convert(sts)@(List Q2)]$WIP for sts in lsts]
+ toSave: List REALSOL := []
+ while not empty? toSee repeat
+ wip := first toSee; toSee := rest toSee
+ lr := wip.reals; lv := wip.vars; lq2 := wip.pols
+ (empty? lq2) and (not empty? lr) =>
+ toSave := cons(reverse(lr),toSave)
+ q2 := first lq2; lq2 := rest lq2
+ qrc := convert(q2)@PRC
+ if not empty? lr
+ then
+ for r in reverse(lr) for v in reverse(lv) repeat
+ qrc := eval(qrc,v,r)
+ lv := cons((mainVariable(qrc) :: Symbol),lv)
+ urc: URC := univariate(qrc)@URC
+ urcRoots := allRootsOf(urc)$RC
+ for urcRoot in urcRoots repeat
+ toSee := cons([cons(urcRoot,lr),lv,lq2]$WIP, toSee)
+ toSave
+
+ realSolve(lp: List(P), info?:Boolean, check?:Boolean, lextri?: Boolean): List REALSOL ==
+ lts: List TS
+ lq: List(Q) := [convert(p)$Q for p in lp]
+ if lextri?
+ then
+ lts := zeroSetSplit(lq,false)$lextripack
+ else
+ lts := zeroSetSplit(lq,true,info?)$TS
+ lsts: List ST := []
+ for ts in lts repeat
+ lsts := concat(squareFree(ts), lsts)
+ lsts := removeSuperfluousQuasiComponents(lsts)$quasicomppack
+ lr: REALSOL := []
+ lv: List Symbol := []
+ toSee := [[lr,lv,convert(sts)@(List Q2)]$WIP for sts in lsts]
+ toSave: List REALSOL := []
+ while not empty? toSee repeat
+ wip := first toSee; toSee := rest toSee
+ lr := wip.reals; lv := wip.vars; lq2 := wip.pols
+ (empty? lq2) and (not empty? lr) =>
+ toSave := cons(reverse(lr),toSave)
+ q2 := first lq2; lq2 := rest lq2
+ qrc := convert(q2)@PRC
+ if not empty? lr
+ then
+ for r in reverse(lr) for v in reverse(lv) repeat
+ qrc := eval(qrc,v,r)
+ lv := cons((mainVariable(qrc) :: Symbol),lv)
+ urc: URC := univariate(qrc)@URC
+ urcRoots := allRootsOf(urc)$RC
+ for urcRoot in urcRoots repeat
+ toSee := cons([cons(urcRoot,lr),lv,lq2]$WIP, toSee)
+ if check?
+ then
+ for p in lp repeat
+ for realsol in toSave repeat
+ prc: PRC := convert(p)@PRC
+ for rr in realsol for symb in reverse(ls) repeat
+ prc := eval(prc,symb,rr)
+ not zero? prc =>
+ error "realSolve$ZDSOLVE: bad result"
+ toSave
+
+ realSolve(lp: List(P), info?:Boolean, check?:Boolean): List REALSOL ==
+ realSolve(lp,info?,check?,false)
+
+ realSolve(lp: List(P), info?:Boolean): List REALSOL ==
+ realSolve(lp,info?,false,false)
+
+ realSolve(lp: List(P)): List REALSOL ==
+ realSolve(lp,false,false,false)
+
+ positiveSolve(ts: TS): List REALSOL ==
+ lsts: List ST := squareFree(ts)
+ lr: REALSOL := []
+ lv: List Symbol := []
+ toSee := [[lr,lv,convert(sts)@(List Q2)]$WIP for sts in lsts]
+ toSave: List REALSOL := []
+ while not empty? toSee repeat
+ wip := first toSee; toSee := rest toSee
+ lr := wip.reals; lv := wip.vars; lq2 := wip.pols
+ (empty? lq2) and (not empty? lr) =>
+ toSave := cons(reverse(lr),toSave)
+ q2 := first lq2; lq2 := rest lq2
+ qrc := convert(q2)@PRC
+ if not empty? lr
+ then
+ for r in reverse(lr) for v in reverse(lv) repeat
+ qrc := eval(qrc,v,r)
+ lv := cons((mainVariable(qrc) :: Symbol),lv)
+ urc: URC := univariate(qrc)@URC
+ urcRoots := allRootsOf(urc)$RC
+ for urcRoot in urcRoots repeat
+ if positive? urcRoot
+ then
+ toSee := cons([cons(urcRoot,lr),lv,lq2]$WIP, toSee)
+ toSave
+
+ positiveSolve(lp: List(P), info?:Boolean, lextri?: Boolean): List REALSOL ==
+ lts: List TS
+ lq: List(Q) := [convert(p)$Q for p in lp]
+ if lextri?
+ then
+ lts := zeroSetSplit(lq,false)$lextripack
+ else
+ lts := zeroSetSplit(lq,true,info?)$TS
+ lsts: List ST := []
+ for ts in lts repeat
+ lsts := concat(squareFree(ts), lsts)
+ lsts := removeSuperfluousQuasiComponents(lsts)$quasicomppack
+ lr: REALSOL := []
+ lv: List Symbol := []
+ toSee := [[lr,lv,convert(sts)@(List Q2)]$WIP for sts in lsts]
+ toSave: List REALSOL := []
+ while not empty? toSee repeat
+ wip := first toSee; toSee := rest toSee
+ lr := wip.reals; lv := wip.vars; lq2 := wip.pols
+ (empty? lq2) and (not empty? lr) =>
+ toSave := cons(reverse(lr),toSave)
+ q2 := first lq2; lq2 := rest lq2
+ qrc := convert(q2)@PRC
+ if not empty? lr
+ then
+ for r in reverse(lr) for v in reverse(lv) repeat
+ qrc := eval(qrc,v,r)
+ lv := cons((mainVariable(qrc) :: Symbol),lv)
+ urc: URC := univariate(qrc)@URC
+ urcRoots := allRootsOf(urc)$RC
+ for urcRoot in urcRoots repeat
+ if positive? urcRoot
+ then
+ toSee := cons([cons(urcRoot,lr),lv,lq2]$WIP, toSee)
+ toSave
+
+ positiveSolve(lp: List(P), info?:Boolean): List REALSOL ==
+ positiveSolve(lp, info?, false)
+
+ positiveSolve(lp: List(P)): List REALSOL ==
+ positiveSolve(lp, false, false)
+
+ univariateSolve(ts: TS): List RUR ==
+ toSee: List ST := squareFree(ts)
+ toSave: List RUR := []
+ for st in toSee repeat
+ lus: List ST := rur(st,true)$rurpack
+ for us in lus repeat
+ g: U := univariate(select(us,newv)::Q2)$Q2
+ lc: LP := [convert(q2)@P for q2 in parts(collectUpper(us,newv)$ST)$ST]
+ toSave := cons([g,lc]$RUR, toSave)
+ toSave
+
+ univariateSolve(lp: List(P), info?:Boolean, check?:Boolean, lextri?: Boolean): List RUR ==
+ lts: List TS
+ lq: List(Q) := [convert(p)$Q for p in lp]
+ if lextri?
+ then
+ lts := zeroSetSplit(lq,false)$lextripack
+ else
+ lts := zeroSetSplit(lq,true,info?)$TS
+ toSee: List ST := []
+ for ts in lts repeat
+ toSee := concat(squareFree(ts), toSee)
+ toSee := removeSuperfluousQuasiComponents(toSee)$quasicomppack
+ toSave: List RUR := []
+ if check?
+ then
+ lq2: List(Q2) := [convert(p)$Q2 for p in lp]
+ for st in toSee repeat
+ lus: List ST := rur(st,true)$rurpack
+ for us in lus repeat
+ if check?
+ then
+ rems: List(Q2) := [removeZero(q2,us)$ST for q2 in lq2]
+ not every?(zero?,rems) =>
+ output(st::OutputForm)$OutputPackage
+ output("Has a bad RUR component:")$OutputPackage
+ output(us::OutputForm)$OutputPackage
+ error "univariateSolve$ZDSOLVE: bad RUR"
+ g: U := univariate(select(us,newv)::Q2)$Q2
+ lc: LP := [convert(q2)@P for q2 in parts(collectUpper(us,newv)$ST)$ST]
+ toSave := cons([g,lc]$RUR, toSave)
+ toSave
+
+ univariateSolve(lp: List(P), info?:Boolean, check?:Boolean): List RUR ==
+ univariateSolve(lp,info?,check?,false)
+
+ univariateSolve(lp: List(P), info?:Boolean): List RUR ==
+ univariateSolve(lp,info?,false,false)
+
+ univariateSolve(lp: List(P)): List RUR ==
+ univariateSolve(lp,false,false,false)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package FGLMICPK FGLMIfCanPackage>>
+<<domain RGCHAIN RegularChain>>
+<<package LEXTRIPK LexTriangularPackage>>
+<<package IRURPK InternalRationalUnivariateRepresentationPackage>>
+<<package RURPK RationalUnivariateRepresentationPackage>>
+<<package ZDSOLVE ZeroDimensionalSolvePackage>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}