~ubuntu-branches/debian/squeeze/maxima/squeeze

« back to all changes in this revision

Viewing changes to src/risch.lisp

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2006-10-18 14:52:42 UTC
  • mto: (1.1.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20061018145242-vzyrm5hmxr8kiosf
ImportĀ upstreamĀ versionĀ 5.10.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
;;;     (c) Copyright 1982 Massachusetts Institute of Technology         ;;;
9
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
10
 
11
 
(in-package "MAXIMA")
 
11
(in-package :maxima)
12
12
(macsyma-module risch)
13
13
 
14
 
(LOAD-MACSYMA-MACROS RZMAC RATMAC)
15
 
 
16
 
(DECLARE-TOP(SPECIAL PROB ROOTFAC PARNUMER PARDENOM LOGPTDX WHOLEPART $RATALGDENOM
17
 
                  EXPEXPFLAG $LOGSIMP SWITCH1 DEGREE CARY $RATFAC $LOGEXPAND
18
 
                  RATFORM GENVAR *VAR VAR ROOTFACTOR EXPINT $KEEPFLOAT
19
 
                  TRIGINT OPERATOR $EXPONENTIALIZE $GCD $LOGARC CHANGEVP
20
 
                  KLTH R S BETA GAMMA B MAINVAR EXPFLAG EXPSTUFF LIFLAG
21
 
                  INTVAR SWITCH VARLIST NOGOOD GENVAR $ERFFLAG $LIFLAG
22
 
                  RISCHP $FACTORFLAG ALPHAR M SIMP GENPAIRS HYPERTRIGINT
23
 
                  *MOSESFLAG YYY *EXP Y $ALGEBRAIC IMPLICIT-REAL
24
 
                  ERRRJFFLAG $%E/_TO/_NUMLOG GENERATE-ATAN2 CONTEXT
25
 
                  BIGFLOATZERO RP-POLYLOGP)
26
 
         (*EXPR $EXPONENTIALIZE SUBFUNSUBS SUBFUNNAME SRATSIMP PARTFRAC MQAPPLYP)
27
 
         (*LEXPR CONTEXT POLYLOGP)
28
 
         (GENPREFIX RISCH))
29
 
 
30
 
(DEFMVAR $LIFLAG T "Controls whether RISCH generates polylogs") 
31
 
 
32
 
(DEFMVAR $ERFFLAG T "Controls whether RISCH generates ERFS") 
33
 
 
34
 
(DEFVAR CHANGEVP T #-LISPM "When nil prevents changevar hack")
35
 
 
36
 
(DEFMACRO PAIR (AL BL) `(MAPCAR (FUNCTION CONS) ,AL ,BL))
37
 
 
38
 
(DEFMACRO RISCHZERO () ''((0 . 1) 0))
39
 
 
40
 
(DEFUN RISCHNOUN (EXP1 &OPTIONAL (EXP2 EXP1 EXP2P))
41
 
  (UNLESS EXP2P (SETQ EXP1 (RZERO)))
42
 
  `(,EXP1 ((%INTEGRATE) ,(DISREP EXP2) ,INTVAR)))
43
 
 
44
 
(DEFUN GETRISCHVAR ()
45
 
       (DO ((VL VARLIST (CDR VL))
46
 
            (GL GENVAR (CDR GL)))
47
 
           ((NULL (CDR VL)) (CAR GL))))
48
 
 
49
 
(DEFUN RISCH-PCONSTP (P)
50
 
       (OR (PCOEFP P) (POINTERGP MAINVAR (CAR P))))
51
 
 
52
 
(DEFUN RISCH-CONSTP (R)
53
 
       (SETQ R (RATFIX R))
54
 
       (AND (RISCH-PCONSTP (CAR R)) (RISCH-PCONSTP (CDR R))))
55
 
 
56
 
(DEFUN RISCHADD (X Y)
57
 
       (LET (((A . B) X) ((C . D) Y))
58
 
            (CONS (R+ A C) (APPEND B D))))
59
 
 
60
 
(DEFMFUN $RISCH (EXP VAR)
61
 
       ;; Get RATINT from SININT
62
 
       (FIND-FUNCTION 'RATINT)
63
 
       (WITH-NEW-CONTEXT (CONTEXT)
64
 
         (RISCHINT EXP VAR)))
65
 
 
66
 
 
67
 
(DEFUN SPDERIVATIVE (P VAR) 
68
 
         (COND ((PCOEFP P) '(0 . 1))
69
 
               ((NULL (CDR P)) '(0 . 1))
70
 
               ((OR (NOT (ATOM (CAR P))) (NUMBERP (CAR P)))     ;P IS A RATFORM
71
 
                (LET ((DENPRIME (SPDERIVATIVE (CDR P) VAR)))
72
 
                     (COND ((RZEROP DENPRIME)
73
 
                            (RATQU (SPDERIVATIVE (CAR P) VAR) (CDR P)))
74
 
                           (T (RATQU (R- (R* (SPDERIVATIVE (CAR P) VAR)
75
 
                                             (CDR P))
76
 
                                         (R* (CAR P) DENPRIME))
77
 
                                     (R* (CDR P) (CDR P)))))))
78
 
               (T (R+ (SPDERIVATIVE1 (CAR P)
79
 
                                     (CADR P)
80
 
                                     (CADDR P)
81
 
                                     VAR)
82
 
                      (SPDERIVATIVE (CONS (CAR P) (CDDDR P))
83
 
                                    VAR)))))
84
 
 
85
 
(DEFUN SPDERIVATIVE1 (VAR1 DEG COEFF VAR) 
86
 
  (COND ((EQ VAR1 VAR)
87
 
         (R* (RATEXPT (CONS (LIST VAR 1 1) 1) (SUB1 DEG))
88
 
             (PCTIMES DEG COEFF)))
89
 
        ((POINTERGP VAR VAR1) '(0 . 1))
90
 
        ((EQUAL DEG 0) (SPDERIVATIVE COEFF VAR))
91
 
        (T (R+ (R* (RATEXPT (CONS (LIST VAR1 1 1) 1) DEG)
92
 
                   (SPDERIVATIVE COEFF VAR))
93
 
               (R* (COND ((EQUAL DEG 1) COEFF)
94
 
                         (T (R* DEG
95
 
                                COEFF
96
 
                                (RATEXPT (CONS (LIST VAR1 1 1) 1)
97
 
                                         (SUB1 DEG)))))
98
 
                   (GET VAR1 'RISCHDIFF) )))))
99
 
 
100
 
(DEFUN POLYLOGP (EXP &OPTIONAL SUB)
101
 
       (AND (MQAPPLYP EXP) (EQ (SUBFUNNAME EXP) '$LI)
102
 
            (OR (NULL SUB) (EQUAL SUB (CAR (SUBFUNSUBS EXP))))))
103
 
 
104
 
 
105
 
(DEFUN RISCHINT (EXP INTVAR &AUX ($LOGARC NIL) ($EXPONENTIALIZE NIL)
106
 
                                 ($GCD '$ALGEBRAIC) ($ALGEBRAIC T) (IMPLICIT-REAL T))
107
 
  (PROG ($%E/_TO/_NUMLOG $LOGSIMP TRIGINT OPERATOR Y Z VAR RATFORM LIFLAG
108
 
        MAINVAR VARLIST GENVAR HYPERTRIGINT $RATFAC $RATALGDENOM )
109
 
       (IF (SPECREPP EXP) (SETQ EXP (SPECDISREP EXP)))
110
 
       (IF (SPECREPP INTVAR) (SETQ INTVAR (SPECDISREP INTVAR)))
111
 
       (IF (MNUMP INTVAR)
112
 
           (MERROR "Attempt to integrate wrt a number: ~:M" INTVAR))
113
 
       (IF (AND (ATOM INTVAR) (ISINOP EXP INTVAR)) (GO NOUN))
114
 
       (RISCHFORM EXP)
115
 
       (COND (TRIGINT (RETURN (TRIGIN1 EXP INTVAR)))
116
 
             (HYPERTRIGINT (RETURN (HYPERTRIGINT1 EXP INTVAR T)))
117
 
             (OPERATOR (GO NOUN)))
118
 
       (SETQ Y (INTSETUP EXP INTVAR))
119
 
       (IF OPERATOR (GO NOUN))
120
 
       (SETQ RATFORM (CAR Y))
121
 
       (SETQ VARLIST (CADDR RATFORM))
122
 
       (SETQ MAINVAR (CAADR (RATF INTVAR)))
123
 
       (SETQ GENVAR (CADDDR RATFORM))
124
 
       (UNLESS (ORMAPC (FUNCTION ALGPGET) VARLIST) 
125
 
               (SETQ $ALGEBRAIC NIL)
126
 
               (SETQ $GCD (CAR *GCDL*)))
127
 
       (SETQ VAR (GETRISCHVAR))
128
 
       (SETQ Z (TRYRISCH (CDR Y) MAINVAR))
129
 
       (SETF (CADDR RATFORM) VARLIST)
130
 
       (SETF (CADDDR RATFORM) GENVAR)
131
 
       (RETURN (COND ((ATOM (CDR Z)) (DISREP (CAR Z)))
132
 
                     (T (LET (($LOGSIMP T) ($%E/_TO/_NUMLOG T))
133
 
                             (SIMPLIFY (LIST* '(MPLUS)
134
 
                                              (DISREP (CAR Z))
135
 
                                              (CDR Z)))))))
136
 
  NOUN (RETURN (LIST '(%INTEGRATE) EXP INTVAR))))
137
 
 
138
 
(DEFUN RISCHFORM (L) 
139
 
       (COND ((OR (ATOM L) (ALIKE1 INTVAR L) (FREEOF INTVAR L)) NIL)
140
 
             ((POLYLOGP L)
141
 
              (IF (AND (INTEGERP (CAR (SUBFUNSUBS L)))
142
 
                       (SIGNP G (CAR (SUBFUNSUBS L))))
143
 
                  (RISCHFORM (CAR (SUBFUNARGS L)))
144
 
                  (SETQ OPERATOR T)))
145
 
             ((ATOM (CAAR L))
146
 
              (CASE (CAAR L)
147
 
                ((%SIN %COS %TAN %COT %SEC %CSC)
148
 
                 (SETQ TRIGINT T $EXPONENTIALIZE T)
149
 
                 (RISCHFORM (CADR L)))
150
 
                ((%ASIN %ACOS %ATAN %ACOT %ASEC %ACSC)
151
 
                 (SETQ TRIGINT T $LOGARC T)
152
 
                 (RISCHFORM (CADR L)))
153
 
                ((%SINH %COSH %TANH %COTH %SECH %CSCH)
154
 
                 (SETQ HYPERTRIGINT T $EXPONENTIALIZE T)
155
 
                 (RISCHFORM (CADR L)))
156
 
                ((%ASINH %ACOSH %ATANH %ACOTH %ASECH %ACSCH)
157
 
                 (SETQ HYPERTRIGINT T $LOGARC T)
158
 
                 (RISCHFORM (CADR L)))
159
 
                ((MTIMES MPLUS MEXPT RAT %ERF %LOG)
160
 
                 (MAPC #'RISCHFORM (CDR L)))
161
 
                (T (SETQ OPERATOR (CAAR L)))))
162
 
             (T (SETQ OPERATOR (CAAR L)))))             
163
 
 
164
 
(DEFUN HYPERTRIGINT1 (EXP VAR HYPERFUNC)
165
 
  (IF HYPERFUNC (INTEGRATOR (RESIMPLIFY EXP) VAR)
166
 
                (RISCHINT (RESIMPLIFY EXP) VAR)))
167
 
 
168
 
(DEFUN TRIGIN1 (*EXP VAR) 
169
 
  (LET ((YYY (HYPERTRIGINT1 *EXP VAR NIL)))
170
 
    (SETQ YYY (DIV ($EXPAND ($NUM YYY))
171
 
                   ($EXPAND ($DENOM YYY))))
172
 
    (LET ((RISCHP VAR) (RP-POLYLOGP T) $LOGARC $EXPONENTIALIZE)
173
 
      (SRATSIMP (IF (AND (FREEOF '$%I *EXP) (FREEOF '$LI YYY))
174
 
                    ($REALPART YYY)
175
 
                    ($RECTFORM YYY))))))
176
 
 
177
 
 
178
 
(DEFUN TRYRISCH (EXP MAINVAR) 
179
 
       (PROG (WHOLEPART ROOTFACTOR PARNUMER PARDENOM
180
 
              SWITCH1 LOGPTDX EXPFLAG EXPSTUFF EXPINT Y) 
181
 
             (SETQ EXPSTUFF '(0 . 1))
182
 
             (COND ((EQ MAINVAR VAR)
183
 
                    (RETURN (RISCHFPROG EXP)))
184
 
                   ((EQ (GET VAR 'LEADOP)
185
 
                        'MEXPT)
186
 
                    (SETQ EXPFLAG T)))
187
 
             (SETQ Y (RISCHLOGDPROG EXP))
188
 
             (DOLIST (RAT LOGPTDX)
189
 
                     (SETQ Y (RISCHADD (RISCHLOGEPROG RAT) Y)))
190
 
             (SETQ Y (RISCHADD (TRYRISCH1 EXPSTUFF MAINVAR) Y))
191
 
             (RETURN (IF EXPINT (RISCHADD (RISCHEXPPOLY EXPINT VAR) Y)
192
 
                         Y))))
193
 
 
194
 
(DEFUN TRYRISCH1 (EXP MAINVAR)
195
 
       (LET* ((VARLIST (REVERSE (CDR (REVERSE VARLIST))))
196
 
              (VAR (GETRISCHVAR)))
197
 
             (TRYRISCH EXP MAINVAR)))
198
 
 
199
 
(DEFUN RISCHFPROG (RAT)
200
 
       (LET (ROOTFACTOR PARDENOM PARNUMER LOGPTDX WHOLEPART SWITCH1) 
201
 
            (CONS (CDR (RATREP* (DPROG RAT)))
202
 
                  (LET ((VARLIST VARLIST)
203
 
                        (GENVAR (FIRSTN (LENGTH VARLIST) GENVAR)))
204
 
                       (MAPCAR 'EPROG LOGPTDX)))))
205
 
 
206
 
(DEFUN RISCHLOGDPROG (RATARG) 
207
 
  (PROG (KLTH AROOTF DERIV THEBPG THETOP THEBOT PROD1 PROD2 ANS) 
208
 
        (SETQ ANS '(0 . 1))
209
 
        (COND ((OR (PCOEFP (CDR RATARG))
210
 
                   (POINTERGP VAR (CADR RATARG)))
211
 
               (RETURN (RISCHLOGPOLY RATARG))))
212
 
        (APROG (RATDENOMINATOR RATARG))
213
 
        (CPROG (RATNUMERATOR RATARG) (RATDENOMINATOR RATARG))
214
 
        (DO ((ROOTFACTOR (REVERSE ROOTFACTOR) (CDR ROOTFACTOR))
215
 
             (PARNUMER (REVERSE PARNUMER) (CDR PARNUMER))
216
 
             (KLTH (LENGTH ROOTFACTOR) (f1- KLTH)))
217
 
            ((= KLTH 1))
218
 
            (SETQ AROOTF (CAR ROOTFACTOR))
219
 
            (COND
220
 
             ((PCOEFP AROOTF))
221
 
             ((AND (EQ (GET (CAR AROOTF) 'LEADOP) 'MEXPT)
222
 
                   (NULL (CDDDR AROOTF)))
223
 
              (SETQ 
224
 
               EXPINT
225
 
               (APPEND
226
 
                (COND ((AND (NOT (ATOM (CAR PARNUMER)))
227
 
                            (NOT (ATOM (CAAR PARNUMER)))
228
 
                            (EQ (CAAAR PARNUMER) (CAR AROOTF)))
229
 
                       (GENNEGS AROOTF (CDAAR PARNUMER) (CDAR PARNUMER)))
230
 
                      (T (LIST
231
 
                          (LIST 'NEG (CAR PARNUMER)
232
 
                                (CAR AROOTF) KLTH (CADR AROOTF)))))
233
 
                EXPINT)))
234
 
             ((NOT (ZEROP (PDEGREE AROOTF VAR))) 
235
 
              (SETQ DERIV (SPDERIVATIVE AROOTF MAINVAR))
236
 
              (SETQ THEBPG (BPROG AROOTF (RATNUMERATOR DERIV)))
237
 
              (SETQ THETOP (CAR PARNUMER))
238
 
              (DO ((KX (f1- KLTH) (f1- KX))) ((= KX 0))
239
 
                  (SETQ PROD1 (R* THETOP (CAR THEBPG)))
240
 
                  (SETQ PROD2 (R* THETOP (CDR THEBPG) (RATDENOMINATOR DERIV)))
241
 
                  (SETQ THEBOT (PEXPT AROOTF KX))
242
 
                  (SETQ ANS (R+ ANS (RATQU (R- PROD2) (R* KX THEBOT))))
243
 
                  (SETQ THETOP
244
 
                        (R+ PROD1 (RATQU (SPDERIVATIVE PROD2 MAINVAR) KX)))
245
 
                  (SETQ THETOP (CDR (RATDIVIDE THETOP THEBOT))))
246
 
              (PUSH (RATQU THETOP AROOTF) LOGPTDX))))
247
 
        (PUSH (RATQU (CAR PARNUMER) (CAR ROOTFACTOR)) LOGPTDX)
248
 
        (COND ((OR (PZEROP ANS) (PZEROP (CAR ANS)))
249
 
               (RETURN (RISCHLOGPOLY WHOLEPART))))
250
 
        (SETQ THETOP (CADR (PDIVIDE (RATNUMERATOR ANS)
251
 
                                    (RATDENOMINATOR ANS))))
252
 
        (RETURN (RISCHADD (NCONS (RATQU THETOP (RATDENOMINATOR ANS)))
253
 
                          (RISCHLOGPOLY WHOLEPART)))))
254
 
 
255
 
(DEFUN GENNEGS (DENOM NUM NUMDENOM) 
256
 
         (COND ((NULL NUM) NIL)
257
 
               (T (CONS (LIST 'NEG (CADR NUM)
258
 
                              (CAR DENOM)
259
 
                              (DIFFERENCE KLTH (CAR NUM))
260
 
                              (R* NUMDENOM (CADDR DENOM) ))
261
 
                        (GENNEGS DENOM (CDDR NUM) NUMDENOM)))))
262
 
 
263
 
(DEFUN RISCHLOGEPROG (P) 
264
 
  (PROG (P1E P2E P2DERIV LOGCOEF NCC DCC ALLCC EXPCOEF) 
265
 
        (IF (OR (PZEROP P) (PZEROP (CAR P))) (RETURN (RISCHZERO)))
266
 
        (SETQ P1E (RATNUMERATOR P))
267
 
        (DESETQ (DCC P2E) (OLDCONTENT (RATDENOMINATOR P)))
268
 
        (COND ((AND (NOT SWITCH1)
269
 
                    (CDR (SETQ PARDENOM (INTFACTOR P2E))))
270
 
               (SETQ PARNUMER NIL)
271
 
               (SETQ SWITCH1 T)
272
 
               (DESETQ (NCC P1E) (OLDCONTENT P1E))
273
 
               (CPROG P1E P2E)
274
 
               (SETQ ALLCC (RATQU NCC DCC))
275
 
               (RETURN (DO ((PNUM PARNUMER (CDR PNUM))
276
 
                            (PDEN PARDENOM (CDR PDEN))
277
 
                            (ANS (RISCHZERO)))
278
 
                           ((OR (NULL PNUM) (NULL PDEN))
279
 
                            (SETQ SWITCH1 NIL) ANS)
280
 
                           (SETQ ANS (RISCHADD
281
 
                                      (RISCHLOGEPROG
282
 
                                       (R* ALLCC (RATQU (CAR PNUM) (CAR PDEN))))
283
 
                                      ANS))))))
284
 
        (WHEN (AND EXPFLAG (NULL (P-RED P2E)))
285
 
              (PUSH (CONS 'NEG P) EXPINT)
286
 
              (RETURN (RISCHZERO)))
287
 
        (IF EXPFLAG (SETQ EXPCOEF (R* (P-LE P2E) (RATQU (GET VAR 'RISCHDIFF)
288
 
                                                        (MAKE-POLY VAR)))))
289
 
        (SETQ P1E (RATQU P1E (PTIMES DCC (P-LC P2E)))
290
 
              P2E (RATQU P2E (P-LC P2E)))               ;MAKE DENOM MONIC
291
 
        (SETQ P2DERIV (SPDERIVATIVE P2E MAINVAR))
292
 
        (SETQ LOGCOEF (RATQU P1E
293
 
                             (IF EXPFLAG (R- P2DERIV (R* P2E EXPCOEF))
294
 
                                 P2DERIV)))
295
 
        (WHEN (RISCH-CONSTP LOGCOEF)
296
 
              (IF EXPFLAG
297
 
                  (SETQ EXPSTUFF (R- EXPSTUFF (R* EXPCOEF LOGCOEF))))
298
 
              (RETURN
299
 
               (LIST
300
 
                '(0 . 1)
301
 
                (LIST '(MTIMES)
302
 
                      (DISREP LOGCOEF)
303
 
                      (LOGMABS (DISREP P2E))))))
304
 
        (if (and expflag $liflag changevp)
305
 
            (let* ((newvar (gensym))
306
 
                   (new-int ($changevar
307
 
                             `((%integrate) ,(simplify (disrep p)) ,intvar)
308
 
                             (sub newvar (get var 'rischexpr))
309
 
                             newvar intvar))
310
 
                   (changevp nil))                ;prevents recursive changevar
311
 
              (if (and (freeof intvar new-int)
312
 
                       (freeof '%integrate
313
 
                               (setq new-int (rischint (sdiff new-int newvar)
314
 
                                                       newvar))))
315
 
                  (return
316
 
                   (list (rzero)
317
 
                         (MAXIMA-SUBSTITUTE (get var 'rischexpr) newvar new-int))))))
318
 
        (RETURN (RISCHNOUN P))))
 
14
(load-macsyma-macros rzmac ratmac)
 
15
 
 
16
(declare-top(special prob rootfac parnumer pardenom logptdx wholepart $ratalgdenom
 
17
                     expexpflag $logsimp switch1 degree cary $ratfac $logexpand
 
18
                     ratform genvar *var var rootfactor expint $keepfloat
 
19
                     trigint operator $exponentialize $gcd $logarc changevp
 
20
                     klth r s beta gamma b mainvar expflag expstuff liflag
 
21
                     intvar switch varlist nogood genvar $erfflag $liflag
 
22
                     rischp $factorflag alphar m simp genpairs hypertrigint
 
23
                     *mosesflag yyy *exp y $algebraic implicit-real
 
24
                     errrjfflag $%e/_to/_numlog generate-atan2 context
 
25
                     bigfloatzero rp-polylogp)
 
26
            (*expr $exponentialize subfunsubs subfunname sratsimp partfrac mqapplyp)
 
27
            (*lexpr context polylogp)
 
28
            (genprefix risch))
 
29
 
 
30
(defmvar $liflag t "Controls whether `risch' generates polylogs") 
 
31
 
 
32
(defmvar $erfflag t "Controls whether `risch' generates `erfs'") 
 
33
 
 
34
(defvar changevp t #-lispm "When nil prevents changevar hack")
 
35
 
 
36
(defmacro pair (al bl) `(mapcar (function cons) ,al ,bl))
 
37
 
 
38
(defmacro rischzero () ''((0 . 1) 0))
 
39
 
 
40
(defun rischnoun (exp1 &optional (exp2 exp1 exp2p))
 
41
  (unless exp2p (setq exp1 (rzero)))
 
42
  `(,exp1 ((%integrate) ,(disrep exp2) ,intvar)))
 
43
 
 
44
(defun getrischvar ()
 
45
  (do ((vl varlist (cdr vl))
 
46
       (gl genvar (cdr gl)))
 
47
      ((null (cdr vl)) (car gl))))
 
48
 
 
49
(defun risch-pconstp (p)
 
50
  (or (pcoefp p) (pointergp mainvar (car p))))
 
51
 
 
52
(defun risch-constp (r)
 
53
  (setq r (ratfix r))
 
54
  (and (risch-pconstp (car r)) (risch-pconstp (cdr r))))
 
55
 
 
56
(defun rischadd (x y)
 
57
  (destructuring-let (((a . b) x) ((c . d) y))
 
58
    (cons (r+ a c) (append b d))))
 
59
 
 
60
(defmfun $risch (exp var)
 
61
  ;; Get RATINT from SININT
 
62
  (find-function 'ratint)
 
63
  (with-new-context (context)
 
64
    (rischint exp var)))
 
65
 
 
66
 
 
67
(defun spderivative (p var) 
 
68
  (cond ((pcoefp p) '(0 . 1))
 
69
        ((null (cdr p)) '(0 . 1))
 
70
        ((or (not (atom (car p))) (numberp (car p))) ;P IS A RATFORM
 
71
         (let ((denprime (spderivative (cdr p) var)))
 
72
           (cond ((rzerop denprime)
 
73
                  (ratqu (spderivative (car p) var) (cdr p)))
 
74
                 (t (ratqu (r- (r* (spderivative (car p) var)
 
75
                                   (cdr p))
 
76
                               (r* (car p) denprime))
 
77
                           (r* (cdr p) (cdr p)))))))
 
78
        (t (r+ (spderivative1 (car p)
 
79
                              (cadr p)
 
80
                              (caddr p)
 
81
                              var)
 
82
               (spderivative (cons (car p) (cdddr p))
 
83
                             var)))))
 
84
 
 
85
(defun spderivative1 (var1 deg coeff var) 
 
86
  (cond ((eq var1 var)
 
87
         (r* (ratexpt (cons (list var 1 1) 1) (sub1 deg))
 
88
             (pctimes deg coeff)))
 
89
        ((pointergp var var1) '(0 . 1))
 
90
        ((equal deg 0) (spderivative coeff var))
 
91
        (t (r+ (r* (ratexpt (cons (list var1 1 1) 1) deg)
 
92
                   (spderivative coeff var))
 
93
               (r* (cond ((equal deg 1) coeff)
 
94
                         (t (r* deg
 
95
                                coeff
 
96
                                (ratexpt (cons (list var1 1 1) 1)
 
97
                                         (sub1 deg)))))
 
98
                   (get var1 'rischdiff) )))))
 
99
 
 
100
(defun polylogp (exp &optional sub)
 
101
  (and (mqapplyp exp) (eq (subfunname exp) '$li)
 
102
       (or (null sub) (equal sub (car (subfunsubs exp))))))
 
103
 
 
104
 
 
105
(defun rischint (exp intvar &aux ($logarc nil) ($exponentialize nil)
 
106
                 ($gcd '$algebraic) ($algebraic t) (implicit-real t))
 
107
  (prog ($%e/_to/_numlog $logsimp trigint operator y z var ratform liflag
 
108
         mainvar varlist genvar hypertrigint $ratfac $ratalgdenom )
 
109
     (if (specrepp exp) (setq exp (specdisrep exp)))
 
110
     (if (specrepp intvar) (setq intvar (specdisrep intvar)))
 
111
     (if (mnump intvar)
 
112
         (merror "Attempt to integrate wrt a number: ~:M" intvar))
 
113
     (if (and (atom intvar) (isinop exp intvar)) (go noun))
 
114
     (rischform exp)
 
115
     (cond (trigint (return (trigin1 exp intvar)))
 
116
           (hypertrigint (return (hypertrigint1 exp intvar t)))
 
117
           (operator (go noun)))
 
118
     (setq y (intsetup exp intvar))
 
119
     (if operator (go noun))
 
120
     (setq ratform (car y))
 
121
     (setq varlist (caddr ratform))
 
122
     (setq mainvar (caadr (ratf intvar)))
 
123
     (setq genvar (cadddr ratform))
 
124
     (unless (ormapc (function algpget) varlist) 
 
125
       (setq $algebraic nil)
 
126
       (setq $gcd (car *gcdl*)))
 
127
     (setq var (getrischvar))
 
128
     (setq z (tryrisch (cdr y) mainvar))
 
129
     (setf (caddr ratform) varlist)
 
130
     (setf (cadddr ratform) genvar)
 
131
     (return (cond ((atom (cdr z)) (disrep (car z)))
 
132
                   (t (let (($logsimp t) ($%e/_to/_numlog t))
 
133
                        (simplify (list* '(mplus)
 
134
                                         (disrep (car z))
 
135
                                         (cdr z)))))))
 
136
     noun (return (list '(%integrate) exp intvar))))
 
137
 
 
138
(defun rischform (l) 
 
139
  (cond ((or (atom l) (alike1 intvar l) (freeof intvar l)) nil)
 
140
        ((polylogp l)
 
141
         (if (and (integerp (car (subfunsubs l)))
 
142
                  (signp g (car (subfunsubs l))))
 
143
             (rischform (car (subfunargs l)))
 
144
             (setq operator t)))
 
145
        ((atom (caar l))
 
146
         (case (caar l)
 
147
           ((%sin %cos %tan %cot %sec %csc)
 
148
            (setq trigint t $exponentialize t)
 
149
            (rischform (cadr l)))
 
150
           ((%asin %acos %atan %acot %asec %acsc)
 
151
            (setq trigint t $logarc t)
 
152
            (rischform (cadr l)))
 
153
           ((%sinh %cosh %tanh %coth %sech %csch)
 
154
            (setq hypertrigint t $exponentialize t)
 
155
            (rischform (cadr l)))
 
156
           ((%asinh %acosh %atanh %acoth %asech %acsch)
 
157
            (setq hypertrigint t $logarc t)
 
158
            (rischform (cadr l)))
 
159
           ((mtimes mplus mexpt rat %erf %log)
 
160
            (mapc #'rischform (cdr l)))
 
161
           (t (setq operator (caar l)))))
 
162
        (t (setq operator (caar l)))))          
 
163
 
 
164
(defun hypertrigint1 (exp var hyperfunc)
 
165
  (if hyperfunc (integrator (resimplify exp) var)
 
166
      (rischint (resimplify exp) var)))
 
167
 
 
168
(defun trigin1 (*exp var) 
 
169
  (let ((yyy (hypertrigint1 *exp var nil)))
 
170
    (setq yyy (div ($expand ($num yyy))
 
171
                   ($expand ($denom yyy))))
 
172
    (let ((rischp var) (rp-polylogp t) $logarc $exponentialize)
 
173
      (sratsimp (if (and (freeof '$%i *exp) (freeof '$li yyy))
 
174
                    ($realpart yyy)
 
175
                    ($rectform yyy))))))
 
176
 
 
177
 
 
178
(defun tryrisch (exp mainvar) 
 
179
  (prog (wholepart rootfactor parnumer pardenom
 
180
         switch1 logptdx expflag expstuff expint y) 
 
181
     (setq expstuff '(0 . 1))
 
182
     (cond ((eq mainvar var)
 
183
            (return (rischfprog exp)))
 
184
           ((eq (get var 'leadop)
 
185
                'mexpt)
 
186
            (setq expflag t)))
 
187
     (setq y (rischlogdprog exp))
 
188
     (dolist (rat logptdx)
 
189
       (setq y (rischadd (rischlogeprog rat) y)))
 
190
     (setq y (rischadd (tryrisch1 expstuff mainvar) y))
 
191
     (return (if expint (rischadd (rischexppoly expint var) y)
 
192
                 y))))
 
193
 
 
194
(defun tryrisch1 (exp mainvar)
 
195
  (let* ((varlist (reverse (cdr (reverse varlist))))
 
196
         (var (getrischvar)))
 
197
    (tryrisch exp mainvar)))
 
198
 
 
199
(defun rischfprog (rat)
 
200
  (let (rootfactor pardenom parnumer logptdx wholepart switch1) 
 
201
    (cons (cdr (ratrep* (dprog rat)))
 
202
          (let ((varlist varlist)
 
203
                (genvar (firstn (length varlist) genvar)))
 
204
            (mapcar 'eprog logptdx)))))
 
205
 
 
206
(defun rischlogdprog (ratarg) 
 
207
  (prog (klth arootf deriv thebpg thetop thebot prod1 prod2 ans) 
 
208
     (setq ans '(0 . 1))
 
209
     (cond ((or (pcoefp (cdr ratarg))
 
210
                (pointergp var (cadr ratarg)))
 
211
            (return (rischlogpoly ratarg))))
 
212
     (aprog (ratdenominator ratarg))
 
213
     (cprog (ratnumerator ratarg) (ratdenominator ratarg))
 
214
     (do ((rootfactor (reverse rootfactor) (cdr rootfactor))
 
215
          (parnumer (reverse parnumer) (cdr parnumer))
 
216
          (klth (length rootfactor) (f1- klth)))
 
217
         ((= klth 1))
 
218
       (setq arootf (car rootfactor))
 
219
       (cond
 
220
         ((pcoefp arootf))
 
221
         ((and (eq (get (car arootf) 'leadop) 'mexpt)
 
222
               (null (cdddr arootf)))
 
223
          (setq 
 
224
           expint
 
225
           (append
 
226
            (cond ((and (not (atom (car parnumer)))
 
227
                        (not (atom (caar parnumer)))
 
228
                        (eq (caaar parnumer) (car arootf)))
 
229
                   (gennegs arootf (cdaar parnumer) (cdar parnumer)))
 
230
                  (t (list
 
231
                      (list 'neg (car parnumer)
 
232
                            (car arootf) klth (cadr arootf)))))
 
233
            expint)))
 
234
         ((not (zerop (pdegree arootf var))) 
 
235
          (setq deriv (spderivative arootf mainvar))
 
236
          (setq thebpg (bprog arootf (ratnumerator deriv)))
 
237
          (setq thetop (car parnumer))
 
238
          (do ((kx (f1- klth) (f1- kx))) ((= kx 0))
 
239
            (setq prod1 (r* thetop (car thebpg)))
 
240
            (setq prod2 (r* thetop (cdr thebpg) (ratdenominator deriv)))
 
241
            (setq thebot (pexpt arootf kx))
 
242
            (setq ans (r+ ans (ratqu (r- prod2) (r* kx thebot))))
 
243
            (setq thetop
 
244
                  (r+ prod1 (ratqu (spderivative prod2 mainvar) kx)))
 
245
            (setq thetop (cdr (ratdivide thetop thebot))))
 
246
          (push (ratqu thetop arootf) logptdx))))
 
247
     (push (ratqu (car parnumer) (car rootfactor)) logptdx)
 
248
     (cond ((or (pzerop ans) (pzerop (car ans)))
 
249
            (return (rischlogpoly wholepart))))
 
250
     (setq thetop (cadr (pdivide (ratnumerator ans)
 
251
                                 (ratdenominator ans))))
 
252
     (return (rischadd (ncons (ratqu thetop (ratdenominator ans)))
 
253
                       (rischlogpoly wholepart)))))
 
254
 
 
255
(defun gennegs (denom num numdenom) 
 
256
  (cond ((null num) nil)
 
257
        (t (cons (list 'neg (cadr num)
 
258
                       (car denom)
 
259
                       (difference klth (car num))
 
260
                       (r* numdenom (caddr denom) ))
 
261
                 (gennegs denom (cddr num) numdenom)))))
 
262
 
 
263
(defun rischlogeprog (p) 
 
264
  (prog (p1e p2e p2deriv logcoef ncc dcc allcc expcoef) 
 
265
     (if (or (pzerop p) (pzerop (car p))) (return (rischzero)))
 
266
     (setq p1e (ratnumerator p))
 
267
     (desetq (dcc p2e) (oldcontent (ratdenominator p)))
 
268
     (cond ((and (not switch1)
 
269
                 (cdr (setq pardenom (intfactor p2e))))
 
270
            (setq parnumer nil)
 
271
            (setq switch1 t)
 
272
            (desetq (ncc p1e) (oldcontent p1e))
 
273
            (cprog p1e p2e)
 
274
            (setq allcc (ratqu ncc dcc))
 
275
            (return (do ((pnum parnumer (cdr pnum))
 
276
                         (pden pardenom (cdr pden))
 
277
                         (ans (rischzero)))
 
278
                        ((or (null pnum) (null pden))
 
279
                         (setq switch1 nil) ans)
 
280
                      (setq ans (rischadd
 
281
                                 (rischlogeprog
 
282
                                  (r* allcc (ratqu (car pnum) (car pden))))
 
283
                                 ans))))))
 
284
     (when (and expflag (null (p-red p2e)))
 
285
       (push (cons 'neg p) expint)
 
286
       (return (rischzero)))
 
287
     (if expflag (setq expcoef (r* (p-le p2e) (ratqu (get var 'rischdiff)
 
288
                                                     (make-poly var)))))
 
289
     (setq p1e (ratqu p1e (ptimes dcc (p-lc p2e)))
 
290
           p2e (ratqu p2e (p-lc p2e)))  ;MAKE DENOM MONIC
 
291
     (setq p2deriv (spderivative p2e mainvar))
 
292
     (setq logcoef (ratqu p1e
 
293
                          (if expflag (r- p2deriv (r* p2e expcoef))
 
294
                              p2deriv)))
 
295
     (when (risch-constp logcoef)
 
296
       (if expflag
 
297
           (setq expstuff (r- expstuff (r* expcoef logcoef))))
 
298
       (return
 
299
         (list
 
300
          '(0 . 1)
 
301
          (list '(mtimes)
 
302
                (disrep logcoef)
 
303
                (logmabs (disrep p2e))))))
 
304
     (if (and expflag $liflag changevp)
 
305
         (let* ((newvar (gensym))
 
306
                (new-int ($changevar
 
307
                          `((%integrate) ,(simplify (disrep p)) ,intvar)
 
308
                          (sub newvar (get var 'rischexpr))
 
309
                          newvar intvar))
 
310
                (changevp nil))         ;prevents recursive changevar
 
311
           (if (and (freeof intvar new-int)
 
312
                    (freeof '%integrate
 
313
                            (setq new-int (rischint (sdiff new-int newvar)
 
314
                                                    newvar))))
 
315
               (return
 
316
                 (list (rzero)
 
317
                       (maxima-substitute (get var 'rischexpr) newvar new-int))))))
 
318
     (return (rischnoun p))))
319
319
         
320
320
 
321
 
(DEFUN FINDINT (EXP) (COND ((ATOM EXP) NIL)
322
 
                           ((ATOM (CAR EXP)) (FINDINT (CDR EXP)))
323
 
                           ((EQ (CAAAR EXP) '%INTEGRATE) T)
324
 
                           (T (FINDINT (CDR EXP)))))
325
 
 
326
 
(DEFUN LOGEQUIV (FN1 FN2)
327
 
  (FREEOF INTVAR ($RATSIMP (DIV* (REMABS (LEADARG FN1))
328
 
                                 (REMABS (LEADARG FN2))))))
329
 
 
330
 
(DEFUN REMABS (EXP)
331
 
       (COND ((ATOM EXP) EXP)
332
 
             ((EQ (CAAR EXP) 'MABS) (CADR EXP))
333
 
             (T EXP)))
334
 
 
335
 
(DECLARE-TOP(SPECIAL VLIST LIANS DEGREE))
336
 
 
337
 
(DEFUN GETFNSPLIT (L &AUX COEF FN)
338
 
  (MAPC #'(LAMBDA (X) (IF (FREE X INTVAR) (PUSH X COEF) (PUSH X FN))) L)
339
 
  (CONS (MULN COEF NIL) (MULN FN NIL)))
340
 
 
341
 
(DEFUN GETFNCOEFF (A FORM) 
342
 
  (COND ((NULL A) 0)
343
 
        ((EQUAL (CAR A) 0) (GETFNCOEFF (CDR A) FORM))
344
 
        ((EQ (CAAAR A) 'MPLUS) (RATPL (GETFNCOEFF (CDAR A) FORM)
345
 
                                      (GETFNCOEFF (CDR A) FORM)))
346
 
        ((EQ (CAAAR A) 'MTIMES)
347
 
         (LET (((COEF . NEWFN) (GETFNSPLIT (CDAR A))))
348
 
           (SETF (CDAR A) (LIST COEF NEWFN))
349
 
           (COND ((ZEROP1 COEF) (GETFNCOEFF (CDR A) FORM))
350
 
                 ((AND (MATANP NEWFN) (MEMQ '$%I VARLIST))
351
 
                  (LET (($LOGARC T) ($LOGEXPAND '$ALL))
352
 
                    (RPLACA A ($EXPAND (RESIMPLIFY (CAR A)))))
353
 
                  (GETFNCOEFF A FORM))
354
 
                 ((AND (ALIKE1 (LEADOP NEWFN) (LEADOP FORM))
355
 
                       (OR (ALIKE1 (LEADARG NEWFN) (LEADARG FORM))
356
 
                           (AND (MLOGP NEWFN)
357
 
                                (LOGEQUIV FORM NEWFN))))
358
 
                  (RATPL (RFORM COEF)
359
 
                         (PROG2 (RPLACA A 0)
360
 
                                (GETFNCOEFF (CDR A) FORM))))
361
 
                 ((DO ((VL VARLIST (CDR VL))) ((NULL VL))
362
 
                      (AND (NOT (ATOM (CAR VL)))
363
 
                           (ALIKE1 (LEADOP (CAR VL)) (LEADOP NEWFN))
364
 
                           (IF (MLOGP NEWFN)
365
 
                               (LOGEQUIV (CAR VL) NEWFN)
366
 
                               (ALIKE1 (CAR VL) NEWFN))
367
 
                           (RPLACA (CDDAR A) (CAR VL))
368
 
                           (RETURN NIL))))
369
 
                 ((LET (VLIST) (NEWVAR1 (CAR A)) (NULL VLIST))
370
 
                  (SETQ CARY
371
 
                        (RATPL (CDR (RATREP* (CAR A)))
372
 
                               CARY))
373
 
                  (RPLACA A 0)
374
 
                  (GETFNCOEFF (CDR A) FORM))
375
 
                 ((AND LIFLAG
376
 
                       (MLOGP FORM)
377
 
                       (MLOGP NEWFN))
378
 
                  (PUSH (DILOG (CONS (CAR A) FORM)) LIANS)
379
 
                  (RPLACA A 0)
380
 
                  (GETFNCOEFF (CDR A) FORM))
381
 
                 ((AND LIFLAG
382
 
                       (POLYLOGP FORM)
383
 
                       (MLOGP NEWFN)
384
 
                       (LOGEQUIV FORM NEWFN))
385
 
                  (PUSH (MUL* (CADAR A) (MAKE-LI (f1+ (CAR (SUBFUNSUBS FORM)))
386
 
                                                 (LEADARG FORM)))
387
 
                        LIANS)
388
 
                  (RPLACA A 0)
389
 
                  (GETFNCOEFF (CDR A) FORM))
390
 
                 (T (SETQ NOGOOD T) 0))))
391
 
        (T (RPLACA A (LIST '(MTIMES) 1 (CAR A)))
392
 
           (GETFNCOEFF A FORM))))
393
 
 
394
 
 
395
 
(DEFUN RISCHLOGPOLY (EXP) 
396
 
   (COND ((EQUAL EXP '(0 . 1)) (RISCHZERO))
397
 
         (EXPFLAG (PUSH (CONS 'POLY EXP) EXPINT)
398
 
                  (RISCHZERO))
399
 
         ((NOT (AMONG VAR EXP)) (TRYRISCH1 EXP MAINVAR))
400
 
         (T (DO ((DEGREE (PDEGREE (CAR EXP) VAR) (f1- DEGREE))
401
 
                 (P (CAR EXP))
402
 
                 (DEN (CDR EXP))
403
 
                 (LIANS ())
404
 
                 (SUM (RZERO))
405
 
                 (CARY (RZERO))
406
 
                 (Y) (Z) (AK) (NOGOOD) (LBKPL1))
407
 
                ((MINUSP DEGREE) (CONS SUM (APPEND LIANS (CDR Y))))
408
 
                (SETQ AK (R- (RATQU (POLCOEF P DEGREE) DEN)
409
 
                             (R* (CONS (ADD1 DEGREE) 1)
410
 
                                 CARY
411
 
                                 (GET VAR 'RISCHDIFF))))
412
 
                (IF (NOT (PZEROP (POLCOEF P DEGREE)))
413
 
                    (SETQ P (IF (PCOEFP P) (PZERO) (PSIMP VAR (P-RED P)))))
414
 
                (SETQ Y (TRYRISCH1 AK MAINVAR))
415
 
                (SETQ CARY (CAR Y))
416
 
                (AND (> DEGREE 0) (SETQ LIFLAG $LIFLAG))
417
 
                (SETQ Z (GETFNCOEFF (CDR Y) (GET VAR 'RISCHEXPR)))
418
 
                (SETQ LIFLAG NIL)
419
 
                (COND ((AND (GREATERP DEGREE 0)
420
 
                            (OR NOGOOD (FINDINT (CDR Y))))
421
 
                       (RETURN (RISCHNOUN SUM (R+ (R* AK
422
 
                                                      (MAKE-POLY VAR DEGREE 1))
423
 
                                                  (RATQU P DEN))))))
424
 
                (SETQ LBKPL1 (RATQU Z (CONS (f1+ DEGREE) 1)))
425
 
                (SETQ SUM (R+ (R* LBKPL1 (MAKE-POLY VAR (ADD1 DEGREE) 1))
426
 
                              (R* CARY (IF (ZEROP DEGREE) 1
427
 
                                           (MAKE-POLY VAR DEGREE 1)))
428
 
                              SUM))))))
429
 
 
430
 
(DEFUN MAKE-LI (SUB ARG)
431
 
  (SUBFUNMAKE '$LI (NCONS SUB) (NCONS ARG)))
432
 
 
433
 
;integrates log(ro)^degree*log(rn)' in terms of polylogs
434
 
;finds constants c,d and integers j,k such that
435
 
;c*ro^j+d=rn^k  If ro and rn are poly's then can assume either j=1 or k=1
436
 
(DEFUN DILOG (L)
437
 
 (LET* ((((nil COEF NLOG) . OLOG) L)
438
 
        (NARG (REMABS (CADR NLOG)))
439
 
        (VARLIST VARLIST)
440
 
        (GENVAR GENVAR)                         
441
 
        (RN (RFORM NARG))
442
 
        (RO (RFORM (CADR OLOG)))
443
 
        (VAR (CAAR RO))
444
 
        ((J . K) (RATREDUCE (PDEGREE (CAR RN) VAR) (PDEGREE (CAR RO) VAR)))
445
 
        (IDX (GENSYM))
446
 
        (RC) (RD))
447
 
   (COND ((AND (= J 1) (> K 1))
448
 
          (SETQ RN (RATEXPT RN K)
449
 
                COEF (DIV COEF K)
450
 
                NARG (RDIS RN)))
451
 
         ((AND (= K 1) (> J 1))
452
 
          (SETQ RO (RATEXPT RO J)
453
 
                COEF (DIV COEF (f* J DEGREE))
454
 
                OLOG (MUL J OLOG))))
455
 
   (DESETQ (RC . RD) (RATDIVIDE RN RO))
456
 
   (COND ((AND (RISCH-CONSTP RC)
457
 
               (RISCH-CONSTP RD))
458
 
          (SETQ NARG ($RATSIMP (SUB 1 (DIV NARG (RDIS RD)))))
459
 
          (MUL* COEF (POWER -1 (f1+ DEGREE))
460
 
                `((MFACTORIAL) ,DEGREE)
461
 
                (DOSUM (MUL* (POWER -1 IDX)
462
 
                             (DIV* (POWER OLOG IDX)
463
 
                                   `((MFACTORIAL) ,IDX))
464
 
                             (MAKE-LI (ADD DEGREE (NEG IDX) 1) NARG))
465
 
                       IDX 0 DEGREE T)))
466
 
         (T (SETQ NOGOOD T) 0))))
467
 
 
468
 
(DEFUN EXPPOLYCONTROL (FLAG F A EXPG N) 
469
 
       (LET (Y L VAR (VARLIST VARLIST) (GENVAR GENVAR)) 
470
 
            (SETQ VARLIST (REVERSE (CDR (REVERSE VARLIST))))
471
 
            (SETQ VAR (GETRISCHVAR))
472
 
            (SETQ Y (GET VAR 'LEADOP))
473
 
            (COND ((AND (NOT (PZEROP (RATNUMERATOR F)))
474
 
                        (RISCH-CONSTP (SETQ L (RATQU A F))))
475
 
                   (COND (FLAG
476
 
                          (LIST (R* L (CONS (LIST EXPG N 1) 1)) 0))
477
 
                         (T L)))
478
 
                  ((EQ Y INTVAR)
479
 
                   (RISCHEXPVAR NIL FLAG (LIST F A EXPG N)))
480
 
                  (T (RISCHEXPLOG (EQ Y 'MEXPT) FLAG F A
481
 
                                  (LIST EXPG N (GET VAR 'RISCHARG)
482
 
                                        VAR (GET VAR 'RISCHDIFF)))))))
483
 
 
484
 
(DEFUN RISCHEXPPOLY (EXPINT VAR) 
485
 
  (LET (Y W NUM DENOM TYPE (ANS (RISCHZERO))
486
 
          (EXPDIFF (RATQU (GET VAR 'RISCHDIFF) (LIST VAR 1 1)))) 
487
 
       (DO ((EXPINT EXPINT (CDR EXPINT)))
488
 
           ((NULL EXPINT) ANS)
489
 
           (DESETQ (TYPE . Y) (CAR EXPINT))
490
 
           (DESETQ (NUM . DENOM) (RATFIX Y))
491
 
           (COND ((EQ TYPE 'NEG)
492
 
                  (SETQ W (EXPPOLYCONTROL T
493
 
                                          (R* (MINUS (CADR DENOM))
494
 
                                              EXPDIFF)
495
 
                                          (RATQU NUM (CADDR DENOM))
496
 
                                          VAR
497
 
                                          (MINUS (CADR DENOM)))))
498
 
                 ((OR (NUMBERP NUM) (NOT (EQ (CAR NUM) VAR)))
499
 
                  (SETQ W (TRYRISCH1 Y MAINVAR)))
500
 
                 (T (SETQ W (RISCHZERO))
501
 
                    (DO ((NUM (CDR NUM) (CDDR NUM))) ((NULL NUM))
502
 
                        (COND ((EQUAL (CAR NUM) 0)
503
 
                               (SETQ W (RISCHADD
504
 
                                        (TRYRISCH1 (RATQU (CADR NUM) DENOM) MAINVAR)
505
 
                                        W)))
506
 
                              (T (SETQ W (RISCHADD (EXPPOLYCONTROL
507
 
                                                     T
508
 
                                                     (R* (CAR NUM) EXPDIFF)
509
 
                                                     (RATQU (CADR NUM) DENOM)
510
 
                                                     VAR
511
 
                                                     (CAR NUM))
512
 
                                                   W)))))))
513
 
           (SETQ ANS (RISCHADD W ANS)))))
514
 
 
515
 
(DEFUN RISCHEXPVAR (EXPEXPFLAG FLAG L) 
516
 
  (PROG (LCM Y M P ALPHAR BETA GAMMA DELTA R S
517
 
         TT DENOM K WL WV I YTEMP TTEMP YALPHA F A EXPG N YN YD) 
518
 
        (DESETQ (F A EXPG N) L)
519
 
        (COND ((OR (PZEROP A) (PZEROP (CAR A)))
520
 
               (RETURN (COND ((NULL FLAG) (RZERO))
521
 
                             (T (RISCHZERO))))))
522
 
        (SETQ DENOM (RATDENOMINATOR F))
523
 
        (SETQ P (FINDPR (CDR (PARTFRAC A MAINVAR))
524
 
                        (CDR (PARTFRAC F MAINVAR))))
525
 
        (SETQ LCM (PLCM (RATDENOMINATOR A) P))
526
 
        (SETQ Y (RATPL (SPDERIVATIVE (CONS 1 P) MAINVAR)
527
 
                       (RATQU F P)))
528
 
        (SETQ LCM (PLCM LCM (RATDENOMINATOR Y)))
529
 
        (SETQ R (CAR (RATQU LCM P)))
530
 
        (SETQ S (CAR (R* LCM Y)))
531
 
        (SETQ TT (CAR (R* A LCM)))
532
 
        (SETQ BETA (PDEGREE R MAINVAR))
533
 
        (SETQ GAMMA (PDEGREE S MAINVAR))
534
 
        (SETQ DELTA (PDEGREE TT MAINVAR))
535
 
        (SETQ ALPHAR (MAX (DIFFERENCE (ADD1 DELTA) BETA)
536
 
                          (DIFFERENCE DELTA GAMMA)))
537
 
        (SETQ M 0)
538
 
        (COND ((EQUAL (SUB1 BETA) GAMMA)
539
 
               (SETQ Y (R* -1
540
 
                           (RATQU (POLCOEF S GAMMA)
541
 
                                  (POLCOEF R BETA))))
542
 
               (AND (EQUAL (CDR Y) 1)
543
 
                    (NUMBERP (CAR Y))
544
 
                    (SETQ M (CAR Y)))))
545
 
        (SETQ ALPHAR (MAX ALPHAR M))
546
 
        (IF (MINUSP ALPHAR)
547
 
            (RETURN (IF FLAG (CXERFARG (RZERO) EXPG N A) NIL)))
548
 
        (COND ((NOT (AND (EQUAL ALPHAR M) (NOT (ZEROP M))))
549
 
               (GO DOWN2)))
550
 
        (SETQ K (PLUS ALPHAR BETA -2))
551
 
        (SETQ WL NIL)
552
 
   L2   (SETQ WV (LIST (CONS (POLCOEF TT K) 1)))
553
 
        (SETQ I ALPHAR)
554
 
   L1   (SETQ WV
555
 
              (CONS (R+ (R* (CONS I 1)
556
 
                            (POLCOEF R (PLUS K 1 (MINUS I))))
557
 
                        (CONS (POLCOEF S (PLUS K (MINUS I))) 1))
558
 
                    WV))
559
 
        (SETQ I (SUB1 I))
560
 
        (COND ((GREATERP I -1) (GO L1)))
561
 
        (SETQ WL (CONS WV WL))
562
 
        (SETQ K (SUB1 K))
563
 
        (COND ((GREATERP K -1) (GO L2)))
564
 
        (SETQ Y (LSA WL))
565
 
        (IF (OR (EQ Y 'SINGULAR) (EQ Y 'INCONSISTENT))
566
 
            (COND ((NULL FLAG) (RETURN NIL))
567
 
                  (T (RETURN (CXERFARG (RZERO) EXPG N A)))))
568
 
        (SETQ K 0)
569
 
        (SETQ LCM 0)
570
 
        (SETQ Y (CDR Y))
571
 
   L3   (SETQ LCM
572
 
              (R+ (R* (CAR Y) (PEXPT (LIST MAINVAR 1 1) K))
573
 
                  LCM))
574
 
        (SETQ K (ADD1 K))
575
 
        (SETQ Y (CDR Y))
576
 
        (COND ((NULL Y)
577
 
               (RETURN (COND ((NULL FLAG) (RATQU LCM P))
578
 
                             (T (LIST (R* (RATQU LCM P)
579
 
                                          (CONS (LIST EXPG N 1) 1))
580
 
                                      0))))))
581
 
        (GO L3)
582
 
   DOWN2(COND ((GREATERP (SUB1 BETA) GAMMA)
583
 
               (SETQ K (PLUS ALPHAR (SUB1 BETA)))
584
 
               (SETQ DENOM '(RATTI ALPHAR (POLCOEF R BETA) T)))
585
 
              ((LESSP (SUB1 BETA) GAMMA)
586
 
               (SETQ K (PLUS ALPHAR GAMMA))
587
 
               (SETQ DENOM '(POLCOEF S GAMMA)))
588
 
              (T (SETQ K (PLUS ALPHAR GAMMA))
589
 
                 (SETQ DENOM
590
 
                       '(RATPL (RATTI ALPHAR (POLCOEF R BETA) T)
591
 
                               (POLCOEF S GAMMA)))))
592
 
        (SETQ Y 0)
593
 
   LOOP (SETQ YN (POLCOEF (RATNUMERATOR TT) K)
594
 
              YD (R* (RATDENOMINATOR TT)                ;DENOM MAY BE 0
595
 
                     (COND ((ZEROP ALPHAR) (POLCOEF S GAMMA))
596
 
                           (T (EVAL DENOM))) ))
597
 
        (COND ((RZEROP YD)
598
 
               (COND ((PZEROP YN) (SETQ K (f1- K) ALPHAR (f1- ALPHAR))
599
 
                                  (GO LOOP))            ;need more constraints?
600
 
                     (T (COND
601
 
                         ((NULL FLAG) (RETURN NIL))
602
 
                         (T (RETURN (CXERFARG (RZERO) EXPG N A)))))))
603
 
              (T (SETQ YALPHA (RATQU YN YD))))
604
 
        (SETQ YTEMP (R+ Y (R* YALPHA
605
 
                              (CONS (LIST MAINVAR ALPHAR 1) 1) )))
606
 
        (SETQ TTEMP (R- TT (R* YALPHA
607
 
                               (R+ (R* S (CONS (LIST MAINVAR ALPHAR 1) 1))
608
 
                                   (R* R ALPHAR
609
 
                                       (LIST MAINVAR (SUB1 ALPHAR) 1))))))
610
 
        (SETQ K (SUB1 K))
611
 
        (SETQ ALPHAR (SUB1 ALPHAR))
612
 
        (COND
613
 
         ((LESSP ALPHAR 0)
614
 
          (COND
615
 
           ((RZEROP TTEMP)
616
 
            (COND
617
 
             ((NULL FLAG) (RETURN (RATQU YTEMP P)))
618
 
             (T (RETURN (LIST (RATQU (R* YTEMP (CONS (LIST EXPG N 1) 1))
619
 
                                     P)
 
321
(defun findint (exp) (cond ((atom exp) nil)
 
322
                           ((atom (car exp)) (findint (cdr exp)))
 
323
                           ((eq (caaar exp) '%integrate) t)
 
324
                           (t (findint (cdr exp)))))
 
325
 
 
326
(defun logequiv (fn1 fn2)
 
327
  (freeof intvar ($ratsimp (div* (remabs (leadarg fn1))
 
328
                                 (remabs (leadarg fn2))))))
 
329
 
 
330
(defun remabs (exp)
 
331
  (cond ((atom exp) exp)
 
332
        ((eq (caar exp) 'mabs) (cadr exp))
 
333
        (t exp)))
 
334
 
 
335
(declare-top(special vlist lians degree))
 
336
 
 
337
(defun getfnsplit (l &aux coef fn)
 
338
  (mapc #'(lambda (x) (if (free x intvar) (push x coef) (push x fn))) l)
 
339
  (cons (muln coef nil) (muln fn nil)))
 
340
 
 
341
(defun getfncoeff (a form) 
 
342
  (cond ((null a) 0)
 
343
        ((equal (car a) 0) (getfncoeff (cdr a) form))
 
344
        ((eq (caaar a) 'mplus) (ratpl (getfncoeff (cdar a) form)
 
345
                                      (getfncoeff (cdr a) form)))
 
346
        ((eq (caaar a) 'mtimes)
 
347
         (destructuring-let (((coef . newfn) (getfnsplit (cdar a))))
 
348
           (setf (cdar a) (list coef newfn))
 
349
           (cond ((zerop1 coef) (getfncoeff (cdr a) form))
 
350
                 ((and (matanp newfn) (memq '$%i varlist))
 
351
                  (let (($logarc t) ($logexpand '$all))
 
352
                    (rplaca a ($expand (resimplify (car a)))))
 
353
                  (getfncoeff a form))
 
354
                 ((and (alike1 (leadop newfn) (leadop form))
 
355
                       (or (alike1 (leadarg newfn) (leadarg form))
 
356
                           (and (mlogp newfn)
 
357
                                (logequiv form newfn))))
 
358
                  (ratpl (rform coef)
 
359
                         (prog2 (rplaca a 0)
 
360
                             (getfncoeff (cdr a) form))))
 
361
                 ((do ((vl varlist (cdr vl))) ((null vl))
 
362
                    (and (not (atom (car vl)))
 
363
                         (alike1 (leadop (car vl)) (leadop newfn))
 
364
                         (if (mlogp newfn)
 
365
                             (logequiv (car vl) newfn)
 
366
                             (alike1 (car vl) newfn))
 
367
                         (rplaca (cddar a) (car vl))
 
368
                         (return nil))))
 
369
                 ((let (vlist) (newvar1 (car a)) (null vlist))
 
370
                  (setq cary
 
371
                        (ratpl (cdr (ratrep* (car a)))
 
372
                               cary))
 
373
                  (rplaca a 0)
 
374
                  (getfncoeff (cdr a) form))
 
375
                 ((and liflag
 
376
                       (mlogp form)
 
377
                       (mlogp newfn))
 
378
                  (push (dilog (cons (car a) form)) lians)
 
379
                  (rplaca a 0)
 
380
                  (getfncoeff (cdr a) form))
 
381
                 ((and liflag
 
382
                       (polylogp form)
 
383
                       (mlogp newfn)
 
384
                       (logequiv form newfn))
 
385
                  (push (mul* (cadar a) (make-li (f1+ (car (subfunsubs form)))
 
386
                                                 (leadarg form)))
 
387
                        lians)
 
388
                  (rplaca a 0)
 
389
                  (getfncoeff (cdr a) form))
 
390
                 (t (setq nogood t) 0))))
 
391
        (t (rplaca a (list '(mtimes) 1 (car a)))
 
392
           (getfncoeff a form))))
 
393
 
 
394
 
 
395
(defun rischlogpoly (exp) 
 
396
  (cond ((equal exp '(0 . 1)) (rischzero))
 
397
        (expflag (push (cons 'poly exp) expint)
 
398
                 (rischzero))
 
399
        ((not (among var exp)) (tryrisch1 exp mainvar))
 
400
        (t (do ((degree (pdegree (car exp) var) (f1- degree))
 
401
                (p (car exp))
 
402
                (den (cdr exp))
 
403
                (lians ())
 
404
                (sum (rzero))
 
405
                (cary (rzero))
 
406
                (y) (z) (ak) (nogood) (lbkpl1))
 
407
               ((minusp degree) (cons sum (append lians (cdr y))))
 
408
             (setq ak (r- (ratqu (polcoef p degree) den)
 
409
                          (r* (cons (add1 degree) 1)
 
410
                              cary
 
411
                              (get var 'rischdiff))))
 
412
             (if (not (pzerop (polcoef p degree)))
 
413
                 (setq p (if (pcoefp p) (pzero) (psimp var (p-red p)))))
 
414
             (setq y (tryrisch1 ak mainvar))
 
415
             (setq cary (car y))
 
416
             (and (> degree 0) (setq liflag $liflag))
 
417
             (setq z (getfncoeff (cdr y) (get var 'rischexpr)))
 
418
             (setq liflag nil)
 
419
             (cond ((and (greaterp degree 0)
 
420
                         (or nogood (findint (cdr y))))
 
421
                    (return (rischnoun sum (r+ (r* ak
 
422
                                                   (make-poly var degree 1))
 
423
                                               (ratqu p den))))))
 
424
             (setq lbkpl1 (ratqu z (cons (f1+ degree) 1)))
 
425
             (setq sum (r+ (r* lbkpl1 (make-poly var (add1 degree) 1))
 
426
                           (r* cary (if (zerop degree) 1
 
427
                                        (make-poly var degree 1)))
 
428
                           sum))))))
 
429
 
 
430
(defun make-li (sub arg)
 
431
  (subfunmake '$li (ncons sub) (ncons arg)))
 
432
 
 
433
;;integrates log(ro)^degree*log(rn)' in terms of polylogs
 
434
;;finds constants c,d and integers j,k such that
 
435
;;c*ro^j+d=rn^k  If ro and rn are poly's then can assume either j=1 or k=1
 
436
(defun dilog (l)
 
437
  (destructuring-let* ((((nil coef nlog) . olog) l)
 
438
                       (narg (remabs (cadr nlog)))
 
439
                       (varlist varlist)
 
440
                       (genvar genvar)                          
 
441
                       (rn (rform narg))
 
442
                       (ro (rform (cadr olog)))
 
443
                       (var (caar ro))
 
444
                       ((j . k) (ratreduce (pdegree (car rn) var) (pdegree (car ro) var)))
 
445
                       (idx (gensym))
 
446
                       (rc) (rd))
 
447
    (cond ((and (= j 1) (> k 1))
 
448
           (setq rn (ratexpt rn k)
 
449
                 coef (div coef k)
 
450
                 narg (rdis rn)))
 
451
          ((and (= k 1) (> j 1))
 
452
           (setq ro (ratexpt ro j)
 
453
                 coef (div coef (f* j degree))
 
454
                 olog (mul j olog))))
 
455
    (desetq (rc . rd) (ratdivide rn ro))
 
456
    (cond ((and (risch-constp rc)
 
457
                (risch-constp rd))
 
458
           (setq narg ($ratsimp (sub 1 (div narg (rdis rd)))))
 
459
           (mul* coef (power -1 (f1+ degree))
 
460
                 `((mfactorial) ,degree)
 
461
                 (dosum (mul* (power -1 idx)
 
462
                              (div* (power olog idx)
 
463
                                    `((mfactorial) ,idx))
 
464
                              (make-li (add degree (neg idx) 1) narg))
 
465
                        idx 0 degree t)))
 
466
          (t (setq nogood t) 0))))
 
467
 
 
468
(defun exppolycontrol (flag f a expg n) 
 
469
  (let (y l var (varlist varlist) (genvar genvar)) 
 
470
    (setq varlist (reverse (cdr (reverse varlist))))
 
471
    (setq var (getrischvar))
 
472
    (setq y (get var 'leadop))
 
473
    (cond ((and (not (pzerop (ratnumerator f)))
 
474
                (risch-constp (setq l (ratqu a f))))
 
475
           (cond (flag
 
476
                  (list (r* l (cons (list expg n 1) 1)) 0))
 
477
                 (t l)))
 
478
          ((eq y intvar)
 
479
           (rischexpvar nil flag (list f a expg n)))
 
480
          (t (rischexplog (eq y 'mexpt) flag f a
 
481
                          (list expg n (get var 'rischarg)
 
482
                                var (get var 'rischdiff)))))))
 
483
 
 
484
(defun rischexppoly (expint var) 
 
485
  (let (y w num denom type (ans (rischzero))
 
486
          (expdiff (ratqu (get var 'rischdiff) (list var 1 1)))) 
 
487
    (do ((expint expint (cdr expint)))
 
488
        ((null expint) ans)
 
489
      (desetq (type . y) (car expint))
 
490
      (desetq (num . denom) (ratfix y))
 
491
      (cond ((eq type 'neg)
 
492
             (setq w (exppolycontrol t
 
493
                                     (r* (minus (cadr denom))
 
494
                                         expdiff)
 
495
                                     (ratqu num (caddr denom))
 
496
                                     var
 
497
                                     (minus (cadr denom)))))
 
498
            ((or (numberp num) (not (eq (car num) var)))
 
499
             (setq w (tryrisch1 y mainvar)))
 
500
            (t (setq w (rischzero))
 
501
               (do ((num (cdr num) (cddr num))) ((null num))
 
502
                 (cond ((equal (car num) 0)
 
503
                        (setq w (rischadd
 
504
                                 (tryrisch1 (ratqu (cadr num) denom) mainvar)
 
505
                                 w)))
 
506
                       (t (setq w (rischadd (exppolycontrol
 
507
                                             t
 
508
                                             (r* (car num) expdiff)
 
509
                                             (ratqu (cadr num) denom)
 
510
                                             var
 
511
                                             (car num))
 
512
                                            w)))))))
 
513
      (setq ans (rischadd w ans)))))
 
514
 
 
515
(defun rischexpvar (expexpflag flag l) 
 
516
  (prog (lcm y m p alphar beta gamma delta r s
 
517
         tt denom k wl wv i ytemp ttemp yalpha f a expg n yn yd) 
 
518
     (desetq (f a expg n) l)
 
519
     (cond ((or (pzerop a) (pzerop (car a)))
 
520
            (return (cond ((null flag) (rzero))
 
521
                          (t (rischzero))))))
 
522
     (setq denom (ratdenominator f))
 
523
     (setq p (findpr (cdr (partfrac a mainvar))
 
524
                     (cdr (partfrac f mainvar))))
 
525
     (setq lcm (plcm (ratdenominator a) p))
 
526
     (setq y (ratpl (spderivative (cons 1 p) mainvar)
 
527
                    (ratqu f p)))
 
528
     (setq lcm (plcm lcm (ratdenominator y)))
 
529
     (setq r (car (ratqu lcm p)))
 
530
     (setq s (car (r* lcm y)))
 
531
     (setq tt (car (r* a lcm)))
 
532
     (setq beta (pdegree r mainvar))
 
533
     (setq gamma (pdegree s mainvar))
 
534
     (setq delta (pdegree tt mainvar))
 
535
     (setq alphar (max (difference (add1 delta) beta)
 
536
                       (difference delta gamma)))
 
537
     (setq m 0)
 
538
     (cond ((equal (sub1 beta) gamma)
 
539
            (setq y (r* -1
 
540
                        (ratqu (polcoef s gamma)
 
541
                               (polcoef r beta))))
 
542
            (and (equal (cdr y) 1)
 
543
                 (numberp (car y))
 
544
                 (setq m (car y)))))
 
545
     (setq alphar (max alphar m))
 
546
     (if (minusp alphar)
 
547
         (return (if flag (cxerfarg (rzero) expg n a) nil)))
 
548
     (cond ((not (and (equal alphar m) (not (zerop m))))
 
549
            (go down2)))
 
550
     (setq k (plus alphar beta -2))
 
551
     (setq wl nil)
 
552
     l2   (setq wv (list (cons (polcoef tt k) 1)))
 
553
     (setq i alphar)
 
554
     l1   (setq wv
 
555
                (cons (r+ (r* (cons i 1)
 
556
                              (polcoef r (plus k 1 (minus i))))
 
557
                          (cons (polcoef s (plus k (minus i))) 1))
 
558
                      wv))
 
559
     (setq i (sub1 i))
 
560
     (cond ((greaterp i -1) (go l1)))
 
561
     (setq wl (cons wv wl))
 
562
     (setq k (sub1 k))
 
563
     (cond ((greaterp k -1) (go l2)))
 
564
     (setq y (lsa wl))
 
565
     (if (or (eq y 'singular) (eq y 'inconsistent))
 
566
         (cond ((null flag) (return nil))
 
567
               (t (return (cxerfarg (rzero) expg n a)))))
 
568
     (setq k 0)
 
569
     (setq lcm 0)
 
570
     (setq y (cdr y))
 
571
     l3   (setq lcm
 
572
                (r+ (r* (car y) (pexpt (list mainvar 1 1) k))
 
573
                    lcm))
 
574
     (setq k (add1 k))
 
575
     (setq y (cdr y))
 
576
     (cond ((null y)
 
577
            (return (cond ((null flag) (ratqu lcm p))
 
578
                          (t (list (r* (ratqu lcm p)
 
579
                                       (cons (list expg n 1) 1))
 
580
                                   0))))))
 
581
     (go l3)
 
582
     down2(cond ((greaterp (sub1 beta) gamma)
 
583
                 (setq k (plus alphar (sub1 beta)))
 
584
                 (setq denom '(ratti alphar (polcoef r beta) t)))
 
585
                ((lessp (sub1 beta) gamma)
 
586
                 (setq k (plus alphar gamma))
 
587
                 (setq denom '(polcoef s gamma)))
 
588
                (t (setq k (plus alphar gamma))
 
589
                   (setq denom
 
590
                         '(ratpl (ratti alphar (polcoef r beta) t)
 
591
                           (polcoef s gamma)))))
 
592
     (setq y 0)
 
593
     loop (setq yn (polcoef (ratnumerator tt) k)
 
594
                yd (r* (ratdenominator tt) ;DENOM MAY BE 0
 
595
                       (cond ((zerop alphar) (polcoef s gamma))
 
596
                             (t (eval denom))) ))
 
597
     (cond ((rzerop yd)
 
598
            (cond ((pzerop yn) (setq k (f1- k) alphar (f1- alphar))
 
599
                   (go loop))           ;need more constraints?
 
600
                  (t (cond
 
601
                       ((null flag) (return nil))
 
602
                       (t (return (cxerfarg (rzero) expg n a)))))))
 
603
           (t (setq yalpha (ratqu yn yd))))
 
604
     (setq ytemp (r+ y (r* yalpha
 
605
                           (cons (list mainvar alphar 1) 1) )))
 
606
     (setq ttemp (r- tt (r* yalpha
 
607
                            (r+ (r* s (cons (list mainvar alphar 1) 1))
 
608
                                (r* r alphar
 
609
                                    (list mainvar (sub1 alphar) 1))))))
 
610
     (setq k (sub1 k))
 
611
     (setq alphar (sub1 alphar))
 
612
     (cond
 
613
       ((lessp alphar 0)
 
614
        (cond
 
615
          ((rzerop ttemp)
 
616
           (cond
 
617
             ((null flag) (return (ratqu ytemp p)))
 
618
             (t (return (list (ratqu (r* ytemp (cons (list expg n 1) 1))
 
619
                                     p)
620
620
                              0)))))
621
 
           ((NULL FLAG) (RETURN NIL))
622
 
           ((AND (RISCH-CONSTP (SETQ TTEMP (RATQU TTEMP LCM)))
623
 
                 $ERFFLAG
624
 
                 (EQUAL (PDEGREE (CAR (GET EXPG 'RISCHARG)) MAINVAR) 2)
625
 
                 (EQUAL (PDEGREE (CDR (GET EXPG 'RISCHARG)) MAINVAR) 0))
626
 
            (RETURN (LIST (RATQU (R* YTEMP (CONS (LIST EXPG N 1) 1)) P)
627
 
                          (ERFARG2 (R* N (GET EXPG 'RISCHARG)) TTEMP))))
628
 
           (T (RETURN
629
 
               (CXERFARG
630
 
                (RATQU (R* Y (CONS (LIST EXPG N 1) 1)) P)
631
 
                EXPG
632
 
                N
633
 
                (RATQU TT LCM)))))))
634
 
        (SETQ Y YTEMP)
635
 
        (SETQ TT TTEMP)
636
 
        (GO LOOP)))
 
621
          ((null flag) (return nil))
 
622
          ((and (risch-constp (setq ttemp (ratqu ttemp lcm)))
 
623
                $erfflag
 
624
                (equal (pdegree (car (get expg 'rischarg)) mainvar) 2)
 
625
                (equal (pdegree (cdr (get expg 'rischarg)) mainvar) 0))
 
626
           (return (list (ratqu (r* ytemp (cons (list expg n 1) 1)) p)
 
627
                         (erfarg2 (r* n (get expg 'rischarg)) ttemp))))
 
628
          (t (return
 
629
               (cxerfarg
 
630
                (ratqu (r* y (cons (list expg n 1) 1)) p)
 
631
                expg
 
632
                n
 
633
                (ratqu tt lcm)))))))
 
634
     (setq y ytemp)
 
635
     (setq tt ttemp)
 
636
     (go loop)))
637
637
 
638
638
 
639
639
;; *JM should be declared as an array, although it is not created
640
640
;; by this file. -- cwh
641
641
 
642
 
(DEFUN LSA (MM)
643
 
 
644
 
       (PROG (D *MOSESFLAG M M2)
645
 
             (SETQ D (LENGTH (CAR MM)))
646
 
             ;; MTOA stands for MATRIX-TO-ARRAY.  An array is created and
647
 
             ;; associated functionally with the symbol *JM.  The elements
648
 
             ;; of the array are initialized from the matrix MM.
649
 
             (MTOA '*JM* (LENGTH MM) D MM)
650
 
             (SETQ M (TFGELI '*JM*  (LENGTH MM) D))
651
 
             (COND ((OR (AND (NULL (CAR M)) (NULL (CADR M)))
652
 
                        (AND (CAR M)
653
 
                             (> (LENGTH (CAR M)) (f- (LENGTH MM) (f1- D)))))
654
 
                    (RETURN 'SINGULAR))
655
 
                   ((CADR M) (RETURN 'INCONSISTENT)))
656
 
             (SETQ *MOSESFLAG T)
657
 
             (PTORAT '*JM* (f1- D) D)
658
 
             (SETQ M2 (XRUTOUT '*JM* (f1- D) D NIL NIL))
659
 
             (SETQ M2 (LSAFIX (CDR M2) (CADDR M)))
660
 
             (*REARRAY '*JM*)
661
 
             (RETURN M2)))
662
 
 
663
 
(DEFUN LSAFIX (L N)
 
642
(defun lsa (mm)
 
643
 
 
644
  (prog (d *mosesflag m m2)
 
645
     (setq d (length (car mm)))
 
646
     ;; MTOA stands for MATRIX-TO-ARRAY.  An array is created and
 
647
     ;; associated functionally with the symbol *JM.  The elements
 
648
     ;; of the array are initialized from the matrix MM.
 
649
     (mtoa '*jm* (length mm) d mm)
 
650
     (setq m (tfgeli '*jm*  (length mm) d))
 
651
     (cond ((or (and (null (car m)) (null (cadr m)))
 
652
                (and (car m)
 
653
                     (> (length (car m)) (f- (length mm) (f1- d)))))
 
654
            (return 'singular))
 
655
           ((cadr m) (return 'inconsistent)))
 
656
     (setq *mosesflag t)
 
657
     (ptorat '*jm* (f1- d) d)
 
658
     (setq m2 (xrutout '*jm* (f1- d) d nil nil))
 
659
     (setq m2 (lsafix (cdr m2) (caddr m)))
 
660
     (*rearray '*jm*)
 
661
     (return m2)))
 
662
 
 
663
(defun lsafix (l n)
664
664
  (declare (special *jm*))
665
 
       (DO ((N N (CDR N))
666
 
            (L L (CDR L)))
667
 
           ((NULL L))
668
 
           ;(STORE (*JM 1 (CAR N)) (CAR L))
669
 
           (STORE (aref *JM* 1 (CAR N)) (CAR L))
670
 
           )
671
 
       (DO ((S (LENGTH L) (f1- S))
672
 
            (ANS))
673
 
           ((= S 0) (CONS '(LIST) ANS))
674
 
           (SETQ ANS (CONS (aref *JM* 1 S) ANS))))
675
 
 
676
 
 
677
 
(DEFUN FINDPR (ALIST FLIST &AUX (P 1) ALPHAR FTERM)
678
 
    (DO ((ALIST ALIST (CDR ALIST))) ((NULL ALIST))
679
 
        (SETQ FTERM (FINDFLIST (CADAR ALIST) FLIST))
680
 
        (IF FTERM (SETQ FLIST (REMQ Y FLIST 1)))
681
 
        (SETQ ALPHAR
682
 
              (COND ((NULL FTERM) (CADDAR ALIST))
683
 
                    ((EQUAL (CADDR FTERM) 1)
684
 
                     (FPR-DIF (CAR FLIST) (CADDAR ALIST)))
685
 
                    (T (MAX (f- (CADDAR ALIST) (CADDR FTERM)) 0))))
686
 
        (IF (NOT (ZEROP ALPHAR))
687
 
            (SETQ P (PTIMES P (PEXPT (CADAR ALIST) ALPHAR)))))
688
 
    (DO ((FLIST FLIST (CDR FLIST))) ((NULL FLIST))
689
 
        (WHEN (EQUAL (CADDAR FLIST) 1)
690
 
              (SETQ ALPHAR (FPR-DIF (CAR FLIST) 0))
691
 
              (SETQ P (PTIMES P (PEXPT (CADAR FLIST) ALPHAR)))))
692
 
    P)
693
 
         
694
 
(DEFUN FPR-DIF (FTERM ALPHA)
695
 
  (LET* (((NUM DEN MULT) FTERM)
696
 
         (M (SPDERIVATIVE DEN MAINVAR))
697
 
         (N))
698
 
        (COND ((RZEROP M) ALPHA)
699
 
              (T (SETQ N (RATQU (CDR (RATDIVIDE NUM DEN))
700
 
                                M))
701
 
                 (IF (AND (EQUAL (CDR N) 1) (NUMBERP (CAR N)))
702
 
                     (MAX (CAR N) ALPHA)
703
 
                     ALPHA)))))
704
 
 
705
 
(DEFUN FINDFLIST (A LLIST) (COND ((NULL LLIST) NIL)
706
 
                                ((EQUAL (CADAR LLIST) A) (CAR LLIST))
707
 
                                (T (FINDFLIST A (CDR LLIST)))))
708
 
         
709
 
 
710
 
(DEFUN RISCHEXPLOG (EXPEXPFLAG FLAG F A L)
 
665
  (do ((n n (cdr n))
 
666
       (l l (cdr l)))
 
667
      ((null l))
 
668
                                        ;(STORE (*JM 1 (CAR N)) (CAR L))
 
669
    (store (aref *jm* 1 (car n)) (car l))
 
670
    )
 
671
  (do ((s (length l) (f1- s))
 
672
       (ans))
 
673
      ((= s 0) (cons '(list) ans))
 
674
    (setq ans (cons (aref *jm* 1 s) ans))))
 
675
 
 
676
 
 
677
(defun findpr (alist flist &aux (p 1) alphar fterm)
 
678
  (do ((alist alist (cdr alist))) ((null alist))
 
679
    (setq fterm (findflist (cadar alist) flist))
 
680
    (if fterm (setq flist (remq y flist 1)))
 
681
    (setq alphar
 
682
          (cond ((null fterm) (caddar alist))
 
683
                ((equal (caddr fterm) 1)
 
684
                 (fpr-dif (car flist) (caddar alist)))
 
685
                (t (max (f- (caddar alist) (caddr fterm)) 0))))
 
686
    (if (not (zerop alphar))
 
687
        (setq p (ptimes p (pexpt (cadar alist) alphar)))))
 
688
  (do ((flist flist (cdr flist))) ((null flist))
 
689
    (when (equal (caddar flist) 1)
 
690
      (setq alphar (fpr-dif (car flist) 0))
 
691
      (setq p (ptimes p (pexpt (cadar flist) alphar)))))
 
692
  p)
 
693
         
 
694
(defun fpr-dif (fterm alpha)
 
695
  (destructuring-let* (((num den mult) fterm)
 
696
                       (m (spderivative den mainvar))
 
697
                       (n))
 
698
    (cond ((rzerop m) alpha)
 
699
          (t (setq n (ratqu (cdr (ratdivide num den))
 
700
                            m))
 
701
             (if (and (equal (cdr n) 1) (numberp (car n)))
 
702
                 (max (car n) alpha)
 
703
                 alpha)))))
 
704
 
 
705
(defun findflist (a llist) (cond ((null llist) nil)
 
706
                                 ((equal (cadar llist) a) (car llist))
 
707
                                 (t (findflist a (cdr llist)))))
 
708
         
 
709
 
 
710
(defun rischexplog (expexpflag flag f a l)
711
711
  (declare (special var))
712
 
  (PROG (LCM Y YY M P ALPHAR BETA GAMMA DELTA
713
 
         MU R S TT DENOM YMU RBETA EXPG N ETA LOGETA LOGDIFF
714
 
     TEMP CARY NOGOOD VECTOR AARRAY RMU RRMU RARRAY) 
715
 
        (DESETQ (EXPG N ETA LOGETA LOGDIFF) L) 
716
 
        (COND ((OR (PZEROP A) (PZEROP (CAR A)))
717
 
               (RETURN (COND ((NULL FLAG) (RZERO))
718
 
                             (T (RISCHZERO))))))
719
 
        (SETQ P (FINDPR (CDR (PARTFRAC A VAR)) (CDR (PARTFRAC F VAR))))
720
 
        (SETQ LCM (PLCM (RATDENOMINATOR A) P))
721
 
        (SETQ Y (RATPL (SPDERIVATIVE (CONS 1 P) MAINVAR)
722
 
                       (RATQU F P)))
723
 
        (SETQ LCM (PLCM LCM (RATDENOMINATOR Y)))
724
 
        (SETQ R (CAR (RATQU LCM P)))
725
 
        (SETQ S (CAR (R* LCM Y)))
726
 
        (SETQ TT (CAR (R* A LCM)))
727
 
        (SETQ BETA (PDEGREE R VAR))
728
 
        (SETQ GAMMA (PDEGREE S VAR))
729
 
        (SETQ DELTA (PDEGREE TT VAR))
730
 
        (COND (EXPEXPFLAG (SETQ MU (MAX (f- DELTA BETA)
731
 
                                        (f- DELTA GAMMA)))
732
 
                          (GO EXPCASE)))
733
 
        (SETQ MU (MAX (f- (f1+ DELTA) BETA)
734
 
                      (f- (f1+ DELTA) GAMMA)))
735
 
        (COND ((< BETA GAMMA) (GO BACK))
736
 
              ((= (SUB1 BETA) GAMMA) (GO DOWN1)))
737
 
        (SETQ Y (TRYRISCH1 (RATQU (R- (R* (POLCOEF R (f1- BETA))
738
 
                                          (POLCOEF S GAMMA))
739
 
                                      (R* (POLCOEF R BETA)
740
 
                                          (POLCOEF S (f1- GAMMA))))
741
 
                                  (R* (POLCOEF R BETA)
742
 
                                      (POLCOEF R BETA) ))
743
 
                           MAINVAR))
744
 
        (SETQ CARY (CAR Y))
745
 
        (SETQ YY (GETFNCOEFF (CDR Y) (GET VAR 'RISCHEXPR)))
746
 
        (COND ((AND (NOT (FINDINT (CDR Y)))
747
 
                    (NOT NOGOOD)
748
 
                    (NOT (ATOM YY))
749
 
                    (EQUAL (CDR YY) 1)
750
 
                    (NUMBERP (CAR YY))
751
 
                    (GREATERP (CAR YY) MU))
752
 
               (SETQ MU (CAR YY))))
753
 
        (GO BACK)
754
 
   EXPCASE
755
 
        (COND ((NOT (EQUAL BETA GAMMA)) (GO BACK)))
756
 
        (SETQ Y (TRYRISCH1 (RATQU (POLCOEF S GAMMA) (POLCOEF R BETA))
757
 
                           MAINVAR))
758
 
        (COND ((FINDINT (CDR Y)) (GO BACK)))
759
 
        (SETQ YY (RATQU (R* -1 (CAR Y)) ETA))
760
 
        (COND ((AND (EQUAL (CDR YY) 1)
761
 
                    (NUMBERP (CAR YY))
762
 
                    (GREATERP (CAR YY) MU))
763
 
               (SETQ MU (CAR YY))))
764
 
        (GO BACK)
765
 
   DOWN1(SETQ Y (TRYRISCH1 (RATQU (POLCOEF S GAMMA) (POLCOEF R BETA))
766
 
                           MAINVAR))
767
 
        (SETQ CARY (CAR Y))
768
 
        (SETQ YY (GETFNCOEFF (CDR Y) (GET VAR 'RISCHEXPR)))
769
 
        (COND ((AND (NOT (FINDINT (CDR Y)))
770
 
                    (NOT NOGOOD)
771
 
                    (EQUAL (CDR YY) 1)
772
 
                    (NUMBERP (CAR YY))
773
 
                    (GREATERP (MINUS (CAR YY)) MU))
774
 
               (SETQ MU (MINUS (CAR YY)))))
775
 
   BACK (IF (MINUSP MU)
776
 
            (RETURN (IF FLAG (CXERFARG (RZERO) EXPG N A) NIL)))
777
 
        (COND ((> BETA GAMMA)(GO LSACALL))
778
 
              ((= BETA GAMMA)
779
 
               (GO RECURSE)))
780
 
        (SETQ DENOM (POLCOEF S GAMMA))
781
 
        (SETQ Y '(0 . 1))
782
 
   LINEARLOOP
783
 
        (SETQ YMU (RATQU (POLCOEF (RATNUMERATOR TT) (f+ MU GAMMA))
784
 
                         (R* (RATDENOMINATOR TT) DENOM)))
785
 
        (SETQ Y (R+ Y (SETQ YMU (R* YMU (PEXPT (LIST LOGETA 1 1) MU) ))))
786
 
        (SETQ TT (R- TT
787
 
                     (R* S YMU)
788
 
                     (R* R (SPDERIVATIVE YMU MAINVAR))))
789
 
        (SETQ MU (f1- MU))
790
 
        (COND
791
 
         ((NOT (< MU 0)) (GO LINEARLOOP))
792
 
         ((NOT FLAG) (RETURN (COND ((RZEROP TT) (RATQU Y P)) (T NIL))))
793
 
         ((RZEROP TT)
794
 
          (RETURN (CONS (RATQU (R* Y (CONS (LIST EXPG N 1) 1)) P) '(0))))
795
 
         (T (RETURN (CXERFARG (RATQU (R* Y (CONS (LIST EXPG N 1) 1)) P)
796
 
                              EXPG
797
 
                              N
798
 
                              (RATQU TT LCM)))))
799
 
   RECURSE
800
 
        (SETQ RBETA (POLCOEF R BETA))
801
 
        (SETQ Y '(0 . 1))
802
 
   RECURSELOOP
803
 
        (SETQ F (R+ (RATQU (POLCOEF S GAMMA) RBETA)
804
 
                    (COND (EXPEXPFLAG (R* MU (SPDERIVATIVE ETA MAINVAR)))
805
 
                          (T 0))))
806
 
        (SETQ YMU (EXPPOLYCONTROL NIL
807
 
                                  F
808
 
                                  (RATQU (POLCOEF (RATNUMERATOR TT)
809
 
                                                  (f+ BETA MU))
810
 
                                         (R* (RATDENOMINATOR TT) RBETA))
811
 
                                  EXPG N))
812
 
        (COND
813
 
         ((NULL YMU)
814
 
          (RETURN
815
 
           (COND
816
 
            ((NULL FLAG) NIL)
817
 
            (T (RETURN (CXERFARG (RATQU (R* Y (CONS (LIST EXPG N 1) 1)) P)
818
 
                                 EXPG N (RATQU TT LCM))))))))
819
 
        (SETQ Y (R+ Y (SETQ YMU (R* YMU (PEXPT (LIST LOGETA 1 1) MU)))))
820
 
        (SETQ TT (R- TT
821
 
                     (R* S YMU)
822
 
                     (R* R (SPDERIVATIVE YMU MAINVAR))))
823
 
        (SETQ MU (f1- MU))
824
 
        (COND
825
 
         ((NOT (< MU 0)) (GO RECURSELOOP))
826
 
         ((NOT FLAG)
827
 
          (RETURN (COND ((RZEROP TT) (RATQU Y P)) (T NIL))))
828
 
         ((RZEROP TT)
829
 
          (RETURN (CONS (RATQU (R* Y (CONS (LIST EXPG N 1) 1)) P) '(0))))
830
 
         (T (RETURN (CXERFARG (RATQU (R* Y (CONS (LIST EXPG N 1) 1)) P)
831
 
                              EXPG
832
 
                              N
833
 
                              (RATQU TT LCM)))))
834
 
   LSACALL
835
 
        (SETQ RRMU MU)
836
 
   MULOOP
837
 
        (SETQ TEMP (R* (RATEXPT (CONS (LIST LOGETA 1 1) 1) (f1- MU))
838
 
                       (R+ (R* S (CONS (LIST LOGETA 1 1) 1))
839
 
                           (R* MU R LOGDIFF ))))
840
 
   MU1  (SETQ VECTOR NIL)
841
 
        (SETQ RMU (f+ RRMU BETA))
842
 
   RMULOOP
843
 
        (SETQ VECTOR (CONS (RATQU (POLCOEF (RATNUMERATOR TEMP) RMU)
844
 
                                  (RATDENOMINATOR TEMP)) VECTOR))
845
 
        (SETQ RMU (f1- RMU))
846
 
        (COND ((NOT (< RMU 0)) (GO RMULOOP)))
847
 
        (SETQ MU (f1- MU))
848
 
        (SETQ AARRAY (APPEND AARRAY (LIST (REVERSE VECTOR))))
849
 
        (COND ((NOT (< MU 0)) (GO MULOOP))
850
 
              ((EQUAL MU -2) (GO SKIPMU)))
851
 
        (SETQ TEMP TT)
852
 
        (GO MU1)
853
 
   SKIPMU
854
 
        (SETQ RARRAY NIL)
855
 
   ARRAYLOOP
856
 
        (SETQ VECTOR NIL)
857
 
        (SETQ VECTOR (MAPCAR 'CAR AARRAY))
858
 
        (SETQ AARRAY (MAPCAR 'CDR AARRAY))
859
 
        (SETQ RARRAY (APPEND RARRAY (LIST VECTOR)))
860
 
        (COND ((NOT (NULL (CAR AARRAY))) (GO ARRAYLOOP)))
861
 
        (SETQ RMU (f1+ RRMU))
862
 
        (SETQ VECTOR NIL)
863
 
   ARRAY1LOOP
864
 
        (SETQ VECTOR (CONS '(0 . 1) VECTOR))
865
 
        (SETQ RMU (f1- RMU))
866
 
        (COND ((NOT (< RMU 0)) (GO ARRAY1LOOP)))
867
 
        (SETQ AARRAY NIL)
868
 
   ARRAY2LOOP
869
 
        (COND ((EQUAL (CAR RARRAY) VECTOR) NIL)
870
 
              (T (SETQ AARRAY (CONS (CAR RARRAY) AARRAY))))
871
 
        (SETQ RARRAY (CDR RARRAY))
872
 
        (COND (RARRAY (GO ARRAY2LOOP)))
873
 
        (SETQ RARRAY (REVERSE AARRAY))
874
 
        (SETQ TEMP (LSA RARRAY))
875
 
        (COND ((OR (EQ TEMP 'SINGULAR) (EQ TEMP 'INCONSISTENT))
876
 
               (RETURN
877
 
                (COND ((NULL FLAG) NIL)
878
 
                      (T (CXERFARG (RZERO) EXPG N A))))))
879
 
        (SETQ TEMP (reverse  (CDR TEMP)))
880
 
        (SETQ RMU 0)
881
 
        (SETQ Y 0)
882
 
   L3   (SETQ Y (R+ Y (R* (CAR TEMP) (PEXPT (LIST LOGETA 1 1) RMU))))
883
 
        (SETQ TEMP (CDR TEMP))
884
 
        (SETQ RMU (f1+ RMU))
885
 
        (COND ((NOT (> RMU RRMU)) (GO L3)))
886
 
        (RETURN (COND ((NULL FLAG) (RATQU Y P))
887
 
                      (T (CONS (R* (LIST EXPG N 1) (RATQU Y P)) '(0)))))))
888
 
 
889
 
 
890
 
(DEFUN ERFARG (EXPARG COEF)
891
 
   (PROG (NUM DENOM ERFARG)
892
 
         (SETQ EXPARG (R- EXPARG))
893
 
         (UNLESS (AND (SETQ NUM (PNTHROOTP (RATNUMERATOR EXPARG) 2))
894
 
                      (SETQ DENOM (PNTHROOTP (RATDENOMINATOR EXPARG) 2)))
895
 
                 (RETURN NIL))
896
 
         (SETQ ERFARG (CONS NUM DENOM))
897
 
         (IF (RISCH-CONSTP
898
 
              (SETQ COEF (RATQU COEF (SPDERIVATIVE ERFARG MAINVAR))))
899
 
             (RETURN (SIMPLIFY `((MTIMES) ((RAT) 1 2)
900
 
                                          ((MEXPT) $%PI ((RAT) 1 2))
901
 
                                          ,(DISREP COEF)
902
 
                                          ((%ERF) ,(DISREP ERFARG))))))))
903
 
 
904
 
(DEFUN ERFARG2 (EXPARG COEFF &AUX (VAR MAINVAR) A B C D) 
905
 
  (WHEN (AND (= (PDEGREE (CAR EXPARG) VAR) 2)
906
 
             (EQ (CAAR EXPARG) VAR)
907
 
             (RISCH-PCONSTP (CDR EXPARG))
908
 
             (RISCH-CONSTP COEFF))
909
 
        (SETQ A (RATQU (R* -1 (CADDAR EXPARG))
910
 
                       (CDR EXPARG)))
911
 
        (SETQ B (DISREP (RATQU (R* -1 (POLCOEF (CAR EXPARG) 1))
912
 
                               (CDR EXPARG))))
913
 
        (SETQ C (DISREP (RATQU (R* (POLCOEF (CAR EXPARG) 0))
914
 
                               (CDR EXPARG))))
915
 
        (SETQ D (RATSQRT A))
916
 
        (SETQ A (DISREP A))
917
 
        (SIMPLIFY `((MTIMES)
918
 
                    ((MTIMES)
919
 
                     ((MEXPT) $%E ((MPLUS) ,C
920
 
                                           ((MQUOTIENT) ((MEXPT) ,B 2)
921
 
                                                        ((MTIMES) 4 ,A))))
922
 
                     ((RAT) 1 2)
923
 
                     ,(DISREP COEFF)
924
 
                     ((MEXPT) ,D -1)
925
 
                     ((MEXPT) $%PI ((RAT) 1 2)))
926
 
                    ((%ERF) ((MPLUS)
927
 
                             ((MTIMES) ,D ,INTVAR)
928
 
                             ((MTIMES) ,B ((RAT) 1 2) ((MEXPT) ,D -1))))))))
929
 
 
930
 
 
931
 
(DEFUN CXERFARG (ANS EXPG N NUMDENOM &AUX (ARG (R* N (GET EXPG 'RISCHARG)))
932
 
                                          (FAILS 0))
933
 
  (PROG (DENOM ERFANS NUM NERF)
934
 
        (DESETQ (NUM . DENOM) NUMDENOM)
935
 
        (UNLESS $ERFFLAG (SETQ FAILS NUM) (GO LOSE))
936
 
        (IF (SETQ ERFANS (ERFARG ARG NUMDENOM))
937
 
            (RETURN (LIST ANS ERFANS)))
938
 
  AGAIN (WHEN (AND (NOT (PCOEFP DENOM))
939
 
                   (NULL (P-RED DENOM))
940
 
                   (EQ (GET (CAR DENOM) 'LEADOP) 'MEXPT))
941
 
              (SETQ ARG (R+ ARG (R* (f- (P-LE DENOM))
942
 
                                    (GET (P-VAR DENOM) 'RISCHARG)))
943
 
                    DENOM (P-LC DENOM))
944
 
              (GO AGAIN))
945
 
        (SLOOP FOR (COEF EXPARG EXPPOLY) IN (EXPLIST NUM ARG 1)
946
 
              DO (SETQ COEF (RATQU COEF DENOM)
947
 
                       NERF (OR (ERFARG2 EXPARG COEF) (ERFARG EXPARG COEF)))
948
 
                 (IF NERF (PUSH NERF ERFANS) (SETQ FAILS
949
 
                                                   (PPLUS FAILS EXPPOLY))))
950
 
   LOSE (RETURN
951
 
         (IF (PZEROP FAILS) (CONS ANS ERFANS)
952
 
             (RISCHADD (CONS ANS ERFANS)
953
 
                       (RISCHNOUN (R* (RATEXPT (CONS (MAKE-POLY EXPG) 1) N)
954
 
                                      (RATQU FAILS (CDR NUMDENOM)))))))))
955
 
 
956
 
(DEFUN EXPLIST (P OARG EXPS)
957
 
       (COND ((OR (PCOEFP P) (NOT (EQ 'MEXPT (GET (P-VAR P) 'LEADOP))))
958
 
              (LIST (LIST P OARG (PTIMES P EXPS))))
959
 
             (T (SLOOP WITH NARG = (GET (P-VAR P) 'RISCHARG)
960
 
                      FOR (EXP COEF) ON (P-TERMS P) BY 'PT-RED
961
 
                      NCONC (EXPLIST COEF
962
 
                                     (R+ OARG (R* EXP NARG))
963
 
                                     (PTIMES EXPS
964
 
                                             (MAKE-POLY (P-VAR P) EXP 1)))))))
965
 
 
966
 
 
967
 
(declare-top (SPECIAL *FNEWVARSW))
 
712
  (prog (lcm y yy m p alphar beta gamma delta
 
713
         mu r s tt denom ymu rbeta expg n eta logeta logdiff
 
714
         temp cary nogood vector aarray rmu rrmu rarray) 
 
715
     (desetq (expg n eta logeta logdiff) l) 
 
716
     (cond ((or (pzerop a) (pzerop (car a)))
 
717
            (return (cond ((null flag) (rzero))
 
718
                          (t (rischzero))))))
 
719
     (setq p (findpr (cdr (partfrac a var)) (cdr (partfrac f var))))
 
720
     (setq lcm (plcm (ratdenominator a) p))
 
721
     (setq y (ratpl (spderivative (cons 1 p) mainvar)
 
722
                    (ratqu f p)))
 
723
     (setq lcm (plcm lcm (ratdenominator y)))
 
724
     (setq r (car (ratqu lcm p)))
 
725
     (setq s (car (r* lcm y)))
 
726
     (setq tt (car (r* a lcm)))
 
727
     (setq beta (pdegree r var))
 
728
     (setq gamma (pdegree s var))
 
729
     (setq delta (pdegree tt var))
 
730
     (cond (expexpflag (setq mu (max (f- delta beta)
 
731
                                     (f- delta gamma)))
 
732
                       (go expcase)))
 
733
     (setq mu (max (f- (f1+ delta) beta)
 
734
                   (f- (f1+ delta) gamma)))
 
735
     (cond ((< beta gamma) (go back))
 
736
           ((= (sub1 beta) gamma) (go down1)))
 
737
     (setq y (tryrisch1 (ratqu (r- (r* (polcoef r (f1- beta))
 
738
                                       (polcoef s gamma))
 
739
                                   (r* (polcoef r beta)
 
740
                                       (polcoef s (f1- gamma))))
 
741
                               (r* (polcoef r beta)
 
742
                                   (polcoef r beta) ))
 
743
                        mainvar))
 
744
     (setq cary (car y))
 
745
     (setq yy (getfncoeff (cdr y) (get var 'rischexpr)))
 
746
     (cond ((and (not (findint (cdr y)))
 
747
                 (not nogood)
 
748
                 (not (atom yy))
 
749
                 (equal (cdr yy) 1)
 
750
                 (numberp (car yy))
 
751
                 (greaterp (car yy) mu))
 
752
            (setq mu (car yy))))
 
753
     (go back)
 
754
     expcase
 
755
     (cond ((not (equal beta gamma)) (go back)))
 
756
     (setq y (tryrisch1 (ratqu (polcoef s gamma) (polcoef r beta))
 
757
                        mainvar))
 
758
     (cond ((findint (cdr y)) (go back)))
 
759
     (setq yy (ratqu (r* -1 (car y)) eta))
 
760
     (cond ((and (equal (cdr yy) 1)
 
761
                 (numberp (car yy))
 
762
                 (greaterp (car yy) mu))
 
763
            (setq mu (car yy))))
 
764
     (go back)
 
765
     down1(setq y (tryrisch1 (ratqu (polcoef s gamma) (polcoef r beta))
 
766
                             mainvar))
 
767
     (setq cary (car y))
 
768
     (setq yy (getfncoeff (cdr y) (get var 'rischexpr)))
 
769
     (cond ((and (not (findint (cdr y)))
 
770
                 (not nogood)
 
771
                 (equal (cdr yy) 1)
 
772
                 (numberp (car yy))
 
773
                 (greaterp (minus (car yy)) mu))
 
774
            (setq mu (minus (car yy)))))
 
775
     back (if (minusp mu)
 
776
              (return (if flag (cxerfarg (rzero) expg n a) nil)))
 
777
     (cond ((> beta gamma)(go lsacall))
 
778
           ((= beta gamma)
 
779
            (go recurse)))
 
780
     (setq denom (polcoef s gamma))
 
781
     (setq y '(0 . 1))
 
782
     linearloop
 
783
     (setq ymu (ratqu (polcoef (ratnumerator tt) (f+ mu gamma))
 
784
                      (r* (ratdenominator tt) denom)))
 
785
     (setq y (r+ y (setq ymu (r* ymu (pexpt (list logeta 1 1) mu) ))))
 
786
     (setq tt (r- tt
 
787
                  (r* s ymu)
 
788
                  (r* r (spderivative ymu mainvar))))
 
789
     (setq mu (f1- mu))
 
790
     (cond
 
791
       ((not (< mu 0)) (go linearloop))
 
792
       ((not flag) (return (cond ((rzerop tt) (ratqu y p)) (t nil))))
 
793
       ((rzerop tt)
 
794
        (return (cons (ratqu (r* y (cons (list expg n 1) 1)) p) '(0))))
 
795
       (t (return (cxerfarg (ratqu (r* y (cons (list expg n 1) 1)) p)
 
796
                            expg
 
797
                            n
 
798
                            (ratqu tt lcm)))))
 
799
     recurse
 
800
     (setq rbeta (polcoef r beta))
 
801
     (setq y '(0 . 1))
 
802
     recurseloop
 
803
     (setq f (r+ (ratqu (polcoef s gamma) rbeta)
 
804
                 (cond (expexpflag (r* mu (spderivative eta mainvar)))
 
805
                       (t 0))))
 
806
     (setq ymu (exppolycontrol nil
 
807
                               f
 
808
                               (ratqu (polcoef (ratnumerator tt)
 
809
                                               (f+ beta mu))
 
810
                                      (r* (ratdenominator tt) rbeta))
 
811
                               expg n))
 
812
     (cond
 
813
       ((null ymu)
 
814
        (return
 
815
          (cond
 
816
            ((null flag) nil)
 
817
            (t (return (cxerfarg (ratqu (r* y (cons (list expg n 1) 1)) p)
 
818
                                 expg n (ratqu tt lcm))))))))
 
819
     (setq y (r+ y (setq ymu (r* ymu (pexpt (list logeta 1 1) mu)))))
 
820
     (setq tt (r- tt
 
821
                  (r* s ymu)
 
822
                  (r* r (spderivative ymu mainvar))))
 
823
     (setq mu (f1- mu))
 
824
     (cond
 
825
       ((not (< mu 0)) (go recurseloop))
 
826
       ((not flag)
 
827
        (return (cond ((rzerop tt) (ratqu y p)) (t nil))))
 
828
       ((rzerop tt)
 
829
        (return (cons (ratqu (r* y (cons (list expg n 1) 1)) p) '(0))))
 
830
       (t (return (cxerfarg (ratqu (r* y (cons (list expg n 1) 1)) p)
 
831
                            expg
 
832
                            n
 
833
                            (ratqu tt lcm)))))
 
834
     lsacall
 
835
     (setq rrmu mu)
 
836
     muloop
 
837
     (setq temp (r* (ratexpt (cons (list logeta 1 1) 1) (f1- mu))
 
838
                    (r+ (r* s (cons (list logeta 1 1) 1))
 
839
                        (r* mu r logdiff ))))
 
840
     mu1  (setq vector nil)
 
841
     (setq rmu (f+ rrmu beta))
 
842
     rmuloop
 
843
     (setq vector (cons (ratqu (polcoef (ratnumerator temp) rmu)
 
844
                               (ratdenominator temp)) vector))
 
845
     (setq rmu (f1- rmu))
 
846
     (cond ((not (< rmu 0)) (go rmuloop)))
 
847
     (setq mu (f1- mu))
 
848
     (setq aarray (append aarray (list (reverse vector))))
 
849
     (cond ((not (< mu 0)) (go muloop))
 
850
           ((equal mu -2) (go skipmu)))
 
851
     (setq temp tt)
 
852
     (go mu1)
 
853
     skipmu
 
854
     (setq rarray nil)
 
855
     arrayloop
 
856
     (setq vector nil)
 
857
     (setq vector (mapcar 'car aarray))
 
858
     (setq aarray (mapcar 'cdr aarray))
 
859
     (setq rarray (append rarray (list vector)))
 
860
     (cond ((not (null (car aarray))) (go arrayloop)))
 
861
     (setq rmu (f1+ rrmu))
 
862
     (setq vector nil)
 
863
     array1loop
 
864
     (setq vector (cons '(0 . 1) vector))
 
865
     (setq rmu (f1- rmu))
 
866
     (cond ((not (< rmu 0)) (go array1loop)))
 
867
     (setq aarray nil)
 
868
     array2loop
 
869
     (cond ((equal (car rarray) vector) nil)
 
870
           (t (setq aarray (cons (car rarray) aarray))))
 
871
     (setq rarray (cdr rarray))
 
872
     (cond (rarray (go array2loop)))
 
873
     (setq rarray (reverse aarray))
 
874
     (setq temp (lsa rarray))
 
875
     (cond ((or (eq temp 'singular) (eq temp 'inconsistent))
 
876
            (return
 
877
              (cond ((null flag) nil)
 
878
                    (t (cxerfarg (rzero) expg n a))))))
 
879
     (setq temp (reverse  (cdr temp)))
 
880
     (setq rmu 0)
 
881
     (setq y 0)
 
882
     l3   (setq y (r+ y (r* (car temp) (pexpt (list logeta 1 1) rmu))))
 
883
     (setq temp (cdr temp))
 
884
     (setq rmu (f1+ rmu))
 
885
     (cond ((not (> rmu rrmu)) (go l3)))
 
886
     (return (cond ((null flag) (ratqu y p))
 
887
                   (t (cons (r* (list expg n 1) (ratqu y p)) '(0)))))))
 
888
 
 
889
 
 
890
(defun erfarg (exparg coef)
 
891
  (prog (num denom erfarg)
 
892
     (setq exparg (r- exparg))
 
893
     (unless (and (setq num (pnthrootp (ratnumerator exparg) 2))
 
894
                  (setq denom (pnthrootp (ratdenominator exparg) 2)))
 
895
       (return nil))
 
896
     (setq erfarg (cons num denom))
 
897
     (if (risch-constp
 
898
          (setq coef (ratqu coef (spderivative erfarg mainvar))))
 
899
         (return (simplify `((mtimes) ((rat) 1 2)
 
900
                             ((mexpt) $%pi ((rat) 1 2))
 
901
                             ,(disrep coef)
 
902
                             ((%erf) ,(disrep erfarg))))))))
 
903
 
 
904
(defun erfarg2 (exparg coeff &aux (var mainvar) a b c d) 
 
905
  (when (and (= (pdegree (car exparg) var) 2)
 
906
             (eq (caar exparg) var)
 
907
             (risch-pconstp (cdr exparg))
 
908
             (risch-constp coeff))
 
909
    (setq a (ratqu (r* -1 (caddar exparg))
 
910
                   (cdr exparg)))
 
911
    (setq b (disrep (ratqu (r* -1 (polcoef (car exparg) 1))
 
912
                           (cdr exparg))))
 
913
    (setq c (disrep (ratqu (r* (polcoef (car exparg) 0))
 
914
                           (cdr exparg))))
 
915
    (setq d (ratsqrt a))
 
916
    (setq a (disrep a))
 
917
    (simplify `((mtimes)
 
918
                ((mtimes)
 
919
                 ((mexpt) $%e ((mplus) ,c
 
920
                               ((mquotient) ((mexpt) ,b 2)
 
921
                                ((mtimes) 4 ,a))))
 
922
                 ((rat) 1 2)
 
923
                 ,(disrep coeff)
 
924
                 ((mexpt) ,d -1)
 
925
                 ((mexpt) $%pi ((rat) 1 2)))
 
926
                ((%erf) ((mplus)
 
927
                         ((mtimes) ,d ,intvar)
 
928
                         ((mtimes) ,b ((rat) 1 2) ((mexpt) ,d -1))))))))
 
929
 
 
930
 
 
931
(defun cxerfarg (ans expg n numdenom &aux (arg (r* n (get expg 'rischarg)))
 
932
                 (fails 0))
 
933
  (prog (denom erfans num nerf)
 
934
     (desetq (num . denom) numdenom)
 
935
     (unless $erfflag (setq fails num) (go lose))
 
936
     (if (setq erfans (erfarg arg numdenom))
 
937
         (return (list ans erfans)))
 
938
     again      (when (and (not (pcoefp denom))
 
939
                           (null (p-red denom))
 
940
                           (eq (get (car denom) 'leadop) 'mexpt))
 
941
                  (setq arg (r+ arg (r* (f- (p-le denom))
 
942
                                        (get (p-var denom) 'rischarg)))
 
943
                        denom (p-lc denom))
 
944
                  (go again))
 
945
     (loop for (coef exparg exppoly) in (explist num arg 1)
 
946
            do (setq coef (ratqu coef denom)
 
947
                     nerf (or (erfarg2 exparg coef) (erfarg exparg coef)))
 
948
            (if nerf (push nerf erfans) (setq fails
 
949
                                              (pplus fails exppoly))))
 
950
     lose (return
 
951
            (if (pzerop fails) (cons ans erfans)
 
952
                (rischadd (cons ans erfans)
 
953
                          (rischnoun (r* (ratexpt (cons (make-poly expg) 1) n)
 
954
                                         (ratqu fails (cdr numdenom)))))))))
 
955
 
 
956
(defun explist (p oarg exps)
 
957
  (cond ((or (pcoefp p) (not (eq 'mexpt (get (p-var p) 'leadop))))
 
958
         (list (list p oarg (ptimes p exps))))
 
959
        (t (loop with narg = (get (p-var p) 'rischarg)
 
960
                  for (exp coef) on (p-terms p) by #'pt-red
 
961
                  nconc (explist coef
 
962
                                 (r+ oarg (r* exp narg))
 
963
                                 (ptimes exps
 
964
                                         (make-poly (p-var p) exp 1)))))))
 
965
 
 
966
 
 
967
(declare-top (special *fnewvarsw))
968
968
        
969
 
(DEFUN INTSETUP (EXP *VAR) 
970
 
  (PROG (VARLIST CLIST $FACTORFLAG DLIST GENPAIRS OLD Y Z $RATFAC $KEEPFLOAT
971
 
                 *FNEWVARSW)
972
 
   Y    (SETQ EXP (RADCAN1 EXP))
973
 
        (FNEWVAR EXP)
974
 
        (SETQ *FNEWVARSW T)
975
 
   A    (SETQ CLIST NIL)
976
 
        (SETQ DLIST NIL)
977
 
        (SETQ Z VARLIST)
978
 
   UP   (setq y (POP Z))
979
 
        (COND ((FREEOF *VAR Y) (PUSH Y CLIST))
980
 
              ((EQ Y *VAR) NIL)
981
 
              ((AND (MEXPTP Y)
982
 
                    (NOT (EQ (CADR Y) '$%E)))
983
 
               (COND ((NOT (FREEOF *VAR (CADDR Y)))
984
 
                      (SETQ DLIST `((MEXPT SIMP)
985
 
                                    $%E
986
 
                                    ,(MUL2* (CADDR Y)
987
 
                                            `((%LOG) ,(CADR Y)))))
988
 
                      (SETQ EXP (MAXIMA-SUBSTITUTE DLIST Y EXP))
989
 
                      (SETQ VARLIST NIL)  (GO Y))
990
 
                     ((ATOM (CADDR Y))
991
 
                      (COND ((NUMBERP (CADDR Y)) (PUSH Y DLIST))
992
 
                            (T (SETQ OPERATOR T)(RETURN NIL))))
993
 
                     (T (PUSH Y DLIST))))
994
 
              (T (PUSH Y DLIST)))
995
 
        (IF Z (GO UP))
996
 
        (IF (MEMQ '$%I CLIST) (SETQ CLIST (CONS '$%I (zl-DELETE '$%I CLIST))))
997
 
        (SETQ VARLIST (APPEND CLIST
998
 
                              (CONS *VAR
999
 
                                    (NREVERSE (SORT (APPEND DLIST NIL) 'INTGREAT)))))
1000
 
        (ORDERPOINTER VARLIST)
1001
 
        (SETQ OLD VARLIST)
1002
 
        (MAPC (FUNCTION INTSET1) (CONS *VAR DLIST))
1003
 
        (COND ((ALIKE OLD VARLIST) (RETURN (RATREP* EXP)))
1004
 
              (T (GO A)))))
 
969
(defun intsetup (exp *var) 
 
970
  (prog (varlist clist $factorflag dlist genpairs old y z $ratfac $keepfloat
 
971
         *fnewvarsw)
 
972
   y    (setq exp (radcan1 exp))
 
973
   (fnewvar exp)
 
974
   (setq *fnewvarsw t)
 
975
   a    (setq clist nil)
 
976
   (setq dlist nil)
 
977
   (setq z varlist)
 
978
   up   (setq y (pop z))
 
979
   (cond ((freeof *var y) (push y clist))
 
980
         ((eq y *var) nil)
 
981
         ((and (mexptp y)
 
982
               (not (eq (cadr y) '$%e)))
 
983
          (cond ((not (freeof *var (caddr y)))
 
984
                 (setq dlist `((mexpt simp)
 
985
                               $%e
 
986
                               ,(mul2* (caddr y)
 
987
                                       `((%log) ,(cadr y)))))
 
988
                 (setq exp (maxima-substitute dlist y exp))
 
989
                 (setq varlist nil)  (go y))
 
990
                ((atom (caddr y))
 
991
                 (cond ((numberp (caddr y)) (push y dlist))
 
992
                       (t (setq operator t)(return nil))))
 
993
                (t (push y dlist))))
 
994
         (t (push y dlist)))
 
995
   (if z (go up))
 
996
   (if (memq '$%i clist) (setq clist (cons '$%i (zl-delete '$%i clist))))
 
997
   (setq varlist (append clist
 
998
                         (cons *var
 
999
                               (nreverse (sort (append dlist nil) 'intgreat)))))
 
1000
   (orderpointer varlist)
 
1001
   (setq old varlist)
 
1002
   (mapc (function intset1) (cons *var dlist))
 
1003
   (cond ((alike old varlist) (return (ratrep* exp)))
 
1004
         (t (go a)))))
1005
1005
 
1006
1006
 
1007
 
(DEFUN LEADOP (EXP)
1008
 
       (COND ((ATOM EXP) EXP)
1009
 
             ((MQAPPLYP EXP) (CADR EXP))
1010
 
             (T (CAAR EXP))))
1011
 
 
1012
 
(DEFUN LEADARG (EXP)
1013
 
  (COND ((ATOM EXP) 0)
1014
 
        ((AND (MEXPTP EXP) (EQ (CADR EXP) '$%E)) (CADDR EXP))
1015
 
        ((MQAPPLYP EXP) (CAR (SUBFUNARGS EXP)))
1016
 
        (T (CADR EXP))))
1017
 
 
1018
 
(DEFUN INTSET1 (B)
1019
 
       (LET (E C D) 
1020
 
         (FNEWVAR
1021
 
          (SETQ D (IF (MEXPTP B)                        ;needed for radicals
1022
 
                      `((MTIMES SIMP)
1023
 
                        ,B
1024
 
                        ,(RADCAN1 (SDIFF (SIMPLIFY (CADDR B)) *VAR)))         
1025
 
                      (RADCAN1 (SDIFF (SIMPLIFY B) *VAR)))))
1026
 
         (SETQ D (RATREP* D))
1027
 
         (SETQ C (RATREP* (LEADARG B)))
1028
 
         (SETQ E (CDR (zl-ASSOC B (PAIR VARLIST GENVAR))))
1029
 
         (PUTPROP E (LEADOP B) 'LEADOP)
1030
 
         (PUTPROP E B 'RISCHEXPR)
1031
 
         (PUTPROP E (CDR D) 'RISCHDIFF)
1032
 
         (PUTPROP E (CDR C) 'RISCHARG)))
1033
 
 
1034
 
(DEFUN INTGREAT (A B)
1035
 
       (COND ((AND (NOT (ATOM A)) (NOT (ATOM B)))
1036
 
              (COND ((AND (NOT (FREEOF '%ERF A)) (FREEOF '%ERF B)) T)
1037
 
                    ((AND (NOT (FREEOF '$LI A)) (FREEOF '$LI B)) T)
1038
 
                    ((AND (FREEOF '$LI A) (NOT (FREEOF '$LI B))) NIL)
1039
 
                    ((AND (FREEOF '%ERF A) (NOT (FREEOF '%ERF B))) NIL)
1040
 
                    ((NOT (FREE B A)) NIL)
1041
 
                    ((NOT (FREE A B)) T)
1042
 
                    (T (GREAT (RESIMPLIFY (FIXINTGREAT A))
1043
 
                                   (RESIMPLIFY (FIXINTGREAT B))))))
1044
 
                  (T (GREAT (RESIMPLIFY (FIXINTGREAT A))
1045
 
                            (RESIMPLIFY (FIXINTGREAT B))))))
1046
 
 
1047
 
(DEFUN FIXINTGREAT (A) (SUBST '/_101X *VAR A))
1048
 
 
1049
 
#-Nil
1050
 
(DECLARE-TOP(UNSPECIAL B BETA CARY CONTEXT *EXP DEGREE GAMMA
1051
 
                    KLTH LIFLAG M NOGOOD OPERATOR PROB
1052
 
                    R S SIMP SWITCH SWITCH1 *VAR VAR  Y YYY))
 
1007
(defun leadop (exp)
 
1008
  (cond ((atom exp) exp)
 
1009
        ((mqapplyp exp) (cadr exp))
 
1010
        (t (caar exp))))
 
1011
 
 
1012
(defun leadarg (exp)
 
1013
  (cond ((atom exp) 0)
 
1014
        ((and (mexptp exp) (eq (cadr exp) '$%e)) (caddr exp))
 
1015
        ((mqapplyp exp) (car (subfunargs exp)))
 
1016
        (t (cadr exp))))
 
1017
 
 
1018
(defun intset1 (b)
 
1019
  (let (e c d) 
 
1020
    (fnewvar
 
1021
     (setq d (if (mexptp b)             ;needed for radicals
 
1022
                 `((mtimes simp)
 
1023
                   ,b
 
1024
                   ,(radcan1 (sdiff (simplify (caddr b)) *var)))              
 
1025
                 (radcan1 (sdiff (simplify b) *var)))))
 
1026
    (setq d (ratrep* d))
 
1027
    (setq c (ratrep* (leadarg b)))
 
1028
    (setq e (cdr (zl-assoc b (pair varlist genvar))))
 
1029
    (putprop e (leadop b) 'leadop)
 
1030
    (putprop e b 'rischexpr)
 
1031
    (putprop e (cdr d) 'rischdiff)
 
1032
    (putprop e (cdr c) 'rischarg)))
 
1033
 
 
1034
(defun intgreat (a b)
 
1035
  (cond ((and (not (atom a)) (not (atom b)))
 
1036
         (cond ((and (not (freeof '%erf a)) (freeof '%erf b)) t)
 
1037
               ((and (not (freeof '$li a)) (freeof '$li b)) t)
 
1038
               ((and (freeof '$li a) (not (freeof '$li b))) nil)
 
1039
               ((and (freeof '%erf a) (not (freeof '%erf b))) nil)
 
1040
               ((not (free b a)) nil)
 
1041
               ((not (free a b)) t)
 
1042
               (t (great (resimplify (fixintgreat a))
 
1043
                         (resimplify (fixintgreat b))))))
 
1044
        (t (great (resimplify (fixintgreat a))
 
1045
                  (resimplify (fixintgreat b))))))
 
1046
 
 
1047
(defun fixintgreat (a) (subst '/_101x *var a))
 
1048
 
 
1049
#-nil
 
1050
(declare-top(unspecial b beta cary context *exp degree gamma
 
1051
                       klth liflag m nogood operator prob
 
1052
                       r s simp switch switch1 *var var  y yyy))