1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
5 ; COMPUTATIONS OF GROEBNER BASES
6 ;written by D.Lazard (jun. 1988)
7 ;-----------------------------------------------------------
8 ;This package contains (with french comments)
9 ; LIRE : a lisp function which convert a list of multivariate polynomials with
10 ; integer coefficients from macsyma CRE form to our internal form; the
11 ; whole list has to be in CRE form, not only its members.
13 ; STAND(CRE_list,ordering) : a macsyma function computing the groebner base of
14 ; a list of polynomials acceptable by LIRE ; at the present the result
15 ; is left in internal form and bounded to the (macsyma) variables BASE
16 ; and ERREXP1. ORDERING may be ORDLEX, the pure lexicographical ordering
17 ; or (better) ORDDEG the degree-reverse-lexicographical ordering; the
18 ; ordering on the variables, determined by the ordering in the CRE form,
19 ; is reversed, when passing from ORDLEX to ORDDEG.
21 ; (c1) Stand([x^2-x-u,u^2-1],ordlex);
23 ; Some statistics are given by macsyma global variables:
24 ; NBSYZ: number of computed syzygies
25 ; NBRED: number of reduction steps
26 ; NBREDUC: number of reductions of polynomials already in the
28 ; NBRED0: number of reductions leading to 0
29 ; Moreover, statistics, and the leading monomials of the polynomials in
30 ; the base are displayed when a syzygy is computed
32 ; (ELIMPOL BASE ORDERING VAR): A lisp function which, from the result of
33 ; STAND (called with the same ordering), returns
34 ; 1 if the input of STAND, viewed as a system of equations
35 ; has no solution in an algebraic closed field
36 ; "dimension positive" if the set of solutions in an algebraic
37 ; closed field is not finite
38 ; or a macsyma univariate polynomial in the variable VAR, the
39 ; roots of which are the values of the first coordinate
40 ; of the solutions; the multiplicity of a root is the
41 ; total multiplicity of the corresponding solutions.
42 ; This function is mainly useful if ORDERING is ORDDEG.
44 ; ELIMPOL_ERR (ORDERING, VAR): a macsyma function which call ELIMPOL on
46 ;-----------------------------------
49 ;l'ecrivain pour la sortie de grobner
50 ;ne trier que les paires non visitees
51 ;diminuer le nombre de divisions (comme dans le cas lexico ?)
56 $nbsyz $nbred $nbreduc $nbred0 ordexp orddeg ordpairs ordlex
60 ;; Keep the header for the last cre polynomial formed during a LIRE.
63 ;(defun $stand ($liste ordre)(grobner (lire $liste ordre) ordre))
64 (defun $stand
($liste
&optional
(ordre 'ordlex
))
65 (let* ((lis (lire $liste ordre
))
66 (base (grobner lis ordre
)))
68 (loop for w in base collect
($decode_poly w nil
)))))
74 ;Il faut traduire une liste de polynomes CRE; on suppose ici les
75 ;coefficients rationnels
76 ;Il faut avoir appele' RAT sur la liste de polynomes pour toutes les variables
77 ;apparaissent dans les en-tetes de tous les polynomes
79 ;Passer de CRE a polynome en la premiere variable
80 (defun lire1 (pol var
) ;en-tete deja enlevee
81 (cond ((numberp pol
) (list (list pol
0)))
82 ((equal (car pol
) var
)
83 (let ((res (cons nil nil
)))
84 (do ((p (cdr pol
) (cddr p
))
87 (rplacd r
(cons (list (cadr p
) (car p
))
89 (t (list (list pol
0)))))
91 ;passer de CRE a polynome en n variables
92 (defun lire2 (pol lvar
)
93 (cond ((null (cdr lvar
))
94 (lire1 pol
(car lvar
)))
99 (lire2 (car u
) (cdr lvar
))))
100 (lire1 pol
(car lvar
))))))
102 ;appliquer lire2 a une liste macsyma de polynomes
103 (defun lire (mliste ordexp
)
104 (or ($ratp mliste
) (setq mliste
($rat mliste
)))
105 (setq $header
(car (second mliste
)))
106 (or (eq (car $header
) 'mrat
) (error "bad rat form"))
107 (mapcar #'(lambda (u)
110 (reverse (cadddr (caadr mliste
))))
111 #'(lambda (v w
) (ordexp (cdr v
) (cdr w
)))))
115 ;ordre lexico inverse pour les exposants
116 (defun orddeg (m1 m2
)
117 (let ((d (- (apply '+ m1
) (apply '+ m2
))))
120 (t (do ((m1 (cdr m1
) (cdr m1
))
121 (m2 (cdr m2
) (cdr m2
))
122 (a (- (car m1
) (car m2
)) (- (car m1
) (car m2
))))
123 ((not (and (zerop a
) m1
)) (minusp a
)))))))
124 (setq orddeg
'orddeg
)
125 (setq $orddeg
'orddeg
)
127 (defun ordlex (m1 m2
)
128 (do ((m1 (cdr m1
) (cdr m1
))
129 (m2 (cdr m2
) (cdr m2
))
130 (a (- (car m1
) (car m2
)) (- (car m1
) (car m2
))))
131 ((not (and (zerop a
) m1
)) (plusp a
))))
133 (setq ordlex
'ordlex
)
134 (setq $ordlex
'ordlex
)
136 (defun ordexp (m1 m2
) ;ancienne version
137 (let ((d (- (apply '+ m1
) (apply '+ m2
))))
140 (t (do ((m1 m1
(cdr m1
))
142 ((not (and m1
(= (car m1
) (car m2
))))
143 (and m1
(< (car m1
) (car m2
)))))))))
145 (defun ordpairs (p1 p2
) ;nouvelle version moins bonne, mais
146 (let ((d1 (apply '+ (caar p1
))) ; ? meilleure pour lexico
147 (d2 (apply '+ (caar p2
))))
150 (or (funcall ordexp
(caadr p2
) (caadr p1
))
151 (and (equal (caadr p1
) (caadr p2
))
152 (funcall ordexp
(cdadr p2
) (cdadr p1
))))))))
154 (defun ordpairs (p1 p2
) ;ancienne version
155 (let ((exp1 (caar p1
))
157 (or (funcall ordexp exp2 exp1
)
158 (and (equal exp1 exp2
)
159 (or (funcall ordexp
(caadr p2
) (caadr p1
))
160 (and (equal (caadr p1
) (caadr p2
))
161 (funcall ordexp
(cdadr p2
) (cdadr p1
))))))))
163 (setq ordpairs
'ordpairs
)
165 ;OPERATIONS ELEMENTAIRES PRESERVATIVES (POLYNOMES) COEFFICIENTS GENERAUX
167 ;definition des multiplications
168 ;mactimes peut etre change si les coefficients sont restreints
169 ;par exemple, pour des entiers, on peut prendre "times"
171 (defun *gpolmon
(pol mon
)
172 (mapcar #'(lambda (u)
176 (defun *gterm
(m1 m2
)
178 (mactimes (car m1
) (car m2
))
179 (mapcar '+ (cdr m1
) (cdr m2
))))
182 ;(defun +pol (p1 p2) ;non destructif
183 ; (cond ((null p1) p2) ;recursion non terminale
184 ; ((null p2) p1) ;non utilise
185 ; ((equal (cdar p1) (cdar p2))
186 ; (let ((a (macplus (caar p1) (caar p2))))
187 ; (cond ((zerop a) (+pol (cdr p1) (cdr p2)))
190 ; (+pol (cdr p1) (cdr p2)))))))
191 ; ((funcall ordexp (cdar p1)(cdar p2))
192 ; (cons (car p1) (+pol (cdr p1) p2)))
193 ; (t (cons (car p2) (+pol (cdr p2) p1)))))
196 ; (let ((f (caddr pair))
199 ; (-pol (*polmon f (cons (caar g) (mapcar '- exp (cdar f))))
200 ; (*polmon (cdr g) (cons (caar f) (mapcar '- exp (cdar g)))))))
202 ;OPERATIONS ELEMENTAIRES DESTRUCTIVES (POLYNOMES) COEFFICIENTS GENERAUX
204 (defun *gcofpol
(c p
) ;destructif resultat dans p
205 (mapc #'(lambda(u) (rplaca u
(mactimes c
(car u
)))) p
))
207 ;Cette fonction retourne et lie a p1 la difference (cdr p1) - p2
208 ;iteratif et destructif
209 ;le polynome nul est retourne (cons nil nil)
215 (rplaca p1
(cadr p1
))
216 (rplacd p1
(cddr p1
)))
220 ((funcall ordexp e1 e2
)
223 (let ((a (macmoins (caadr p
) (caar q
))))
228 (rplaca (car p
) a
))))
231 (setq p
(cdr (rplacd p
(cons
233 (macmoins 0 (caar q
))
238 ;On definit maintenant la division d'un polynome par une base unitaire
239 ;Le polynome est remplace par le resultat
241 (defun red1 (pol1 p pol2
) ;destructif
242 (let ((a (mapcar '-
(cdar p
) (cdar pol2
)))) ;resultat dans pol1
243 (cond ((minusp (apply 'min a
)) ;pol2 est unitaire
249 (cons (caar p
) a
)))))))
251 (defun div-terme (p1 p base
)
252 (do ((a (cdar p
) (cdar p
))
255 (mapc #'(lambda (u) (red1 p1 p u
)) base
)))
257 (defun divise (p1 base
)
258 (do ((p (cdr (div-terme p1 p1 base
)) (cdr (div-terme p1 p base
))))
262 (let ((c (caar pol
)))
264 (rplaca u
(macdiv (car u
) c
)))
267 ; ;Comme ce qui precede, mais pseudo division pour eviter
268 ; ;les divisions de coefficients
269 ;(defun red2 (pol1 pol2) ;destructif
270 ; (let ((a (mapcar '- (cdar pol1) (cdar pol2))) ;resultat dans pol1
272 ; (cond ((minusp (apply 'min a)) nil) ;sans division
273 ; ((-pol (*cofpol (caar pol2) pol1) ;rend nil si pol1..
274 ; (*polmon (cdr pol2) ;..non modifie
277 ;(defun div-tete2 (p1 base)
278 ; (do ((a (cdar p1) (cdar p1))
281 ; (mapc #'(lambda (u) (red2 p1 u)) base)))
283 ;(defun divise2 (p1 base)
284 ; (do ((p (cdr p1) (cdr (div-tete2 p base))))
287 ;OPERATIONS ELEMENTAIRES PRESERVATIVES (POLYNOMES) COEFFICIENTS ENTIERS
289 ;definition des multiplications
290 ;mactimes peut etre change si les coefficients sont restreints
291 ; exemple, pour des entiers, on peut prendre "times"
293 (defun *ipolmon
(pol mon
)
294 (mapcar #'(lambda (u) (*iterm u mon
)) pol
))
296 (defun *iterm
(m1 m2
)
298 (* (car m1
) (car m2
))
299 (mapcar #'+ (cdr m1
) (cdr m2
))))
302 (let ((f (caddr pair
))
306 (setq $nbsyz
(1+ $nbsyz
)
312 (-ipol (*ipolmon f
(cons a
(mapcar '- exp
(cdar f
))))
313 (*ipolmon
(cdr g
) (cons b
(mapcar '- exp
(cdar g
)))))))
315 ;OPERATIONS ELEMENTAIRES DESTRUCTIVES (POLYNOMES) COEFFICIENTS ENTIERS
317 (defun *icofpol
(c p
) ;destructif resultat dans p
318 (mapc #'(lambda(u) (rplaca u
(* c
(car u
)))) p
))
320 ;Cette fonction retourne et lie a p1 la difference (cdr p1) - p2
321 ;iteratif et destructif
322 ;le polynome nul est retourne (cons nil nil)
325 (rplaca p1
(cadr p1
))
326 (rplacd p1
(cddr p1
)))
328 (defun -ipol2 (p1 p2
)
336 ((funcall ordexp e1 e2
)
339 (let ((a (- (caadr p
) (caar q
))))
344 (rplaca (car p
) a
))))
347 (setq p
(cdr (rplacd p
(cons
354 ;On definit maintenant la division d'un polynome par une base
355 ;Le polynome est remplace par le resultat
356 ;Pseudo division pour eviter
357 ;les divisions de coefficients
358 (defun ired2 (pol1 pol2
) ;destructif
359 (let ((a (mapcar '-
(cdar pol1
) (cdar pol2
))) ;resultat dans pol1
360 (c)(b)(d)) ;sans division
361 (cond ((minusp (apply 'min a
)) nil
) ;rend nil si pol1..
362 (t (setq $nbred
(1+ $nbred
) ;..non modifie
365 d
(gcd b c
) ;rend (cons nil nil)
366 b
(quotient b d
) ;si pol1 devient nul
368 (*icofpol b
(cdr pol1
))
373 (defun iredp (p1 p q
)
377 (cond ((not (minusp (apply 'min
378 (setq a
(mapcar '-
(cdar pp
) (cdar q
))))))
388 (rplacd p
(cdr pp
)))))))
390 (defun idivp (p1 p base
) ;pour idivise2, il faut multiplier
391 (do ((a (cdadr p
) (cdadr p
)) ;tout le polynome dividende
394 (mapc #'(lambda (u) (iredp p1 p u
)) base
)))
396 (defun idivise2 (p1 base
)
397 (do ((p p1
(idivp p1 p base
)))
398 ((null p
) (primpart p1
))))
400 ;OPERATIONS SUR LES COEFFICIENTS
402 (defun mactimes (a b
)
403 (meval (list '(mtimes) a b
)))
406 (meval (list '(mplus) a b
)))
408 (defun macmoins (a b
)
409 (meval (list '(mplus) a
(list '(mminus) b
))))
412 (meval (list '(mquotient) a b
)))
415 ; (do ((r (car lnb) (gcd r (car l)))
416 ; (l (cdr lnb) (cdr l)))
420 (let ((d (do ((p (cdr p
) (cdr p
)) ;calcul du contenu
421 (g (caar p
) (gcd g
(caar p
))))
422 ((or (eql (abs g
) 1) (null p
))
425 (mapc #'(lambda (u) ;diviser par le contenu
426 (rplaca u
(quotient (car u
) d
)))
431 ; (let ((d (*gcd (mapcar 'car
433 ; (mapc #'(lambda (u)
434 ; (rplaca u (quotient (car u) d)))
439 ;Construction de la base
440 ;Methode a la Buchberger-Bouzeghoub
441 ;base: liste de polynomes
442 ;paires: candidats sygyzies: ((exp."deja reduite").((exp1.exp2).(f.g)))
445 ; reduire tous les polynomes
446 ; calculer la liste des paires; vivier construit celles qui ne sont
448 ; reduire la premiere paire, inserer le resultat dans la base et
450 ;remettre a jour la liste des paires et recommencer
452 (defun grobner (gener ordexp
)
453 (setq $base
(cons nil
(sort (copy-tree gener
)
454 #'(lambda (u v
) (ordexp (cdar v
) (cdar u
))))))
456 (setq $nbsyz
0 $nbred
0 $nbreduc
0 $nbred0
0)
457 (reduire $base
(cdr $base
) (cddr $base
))
459 (mapcon #'(lambda (u)
460 (let ((exp (cdaar u
))
462 (mapcar #'(lambda (v) (apparier f v exp
(cdar v
)))
467 (sort paires ordpairs
)))
468 (do ((l (vivier paires
)) ;parcourir les paires
469 (exp) (exp1) (exp2) (p) (q))
471 (setq p
(car l
) exp
(caar p
)
472 exp1
(caadr p
) exp2
(cdadr p
))
473 (cond ((cdar p
) ;paire deja vue
475 ;on cherche maintenant h dans base tel
476 ;que h divise exp et que les syzygies
477 ;(f h) et (g h) ont ete calculees
478 ((do ((l1 (cdr $base
) l3
) ;"critere 3"
479 (l3 (cddr $base
) (cdr l3
))
480 (h (cadr $base
) (car l3
))
481 (exph (cdaadr $base
) (cdaar l3
)))
482 ((cond ((null l1
) t
) ;pas trouve de h
483 ((funcall ordexp exph exp
) (not (setq l1 nil
)))
485 (not (minusp (apply 'min
486 (mapcar '- exp exph
))))
487 (let ((exph1 (mapcar 'max exph exp1
)))
488 (or (funcall ordexp exp exph1
)
489 (and (equal exp exph1
)
490 (funcall ordexp exp2 exph
))))
491 (let ((exph2 (mapcar 'max exph exp2
)))
492 (or (funcall ordexp exp exph2
)
493 (and (equal exp exph2
)
494 (funcall ordexp exp1 exph
)))))))
498 (rplacd (car p
) t
)) ;le critere 3 est verifie
500 (rplacd (car p
) t
) ;la paire va etre traitee
504 (reduire $base q nil
)
505 (format t
"~% nbsyz = ~a nbred = ~a nbreduc = ~a nbred0 = ~a lbase = ~d~%"
506 $nbsyz $nbred $nbreduc $nbred0
(length (cdr base
)))
508 (print (escalier (cdr $base
)))
511 (rafraichir paires p $base
)
512 (setq l
(vivier paires
)))
515 (format t
"~% nbsyz = ~a nbred = ~a nbreduc = ~a nbred0 = ~a lbase = ~a~% paires a voir = ~d~%"
516 $nbsyz $nbred $nbreduc $nbred0
(length (cdr base
)) (length l
))
518 ))))) ;paire suivante
519 (setq $base
(cdr $base
))
520 (mapc #'(lambda (u) (idivise2 u $base
))
521 $base
) ;reduire completement
522 (mapc 'monic $base
)))
524 (defun apparier (p q expp expq
)
527 (mapcar #'max expp expq
) ;caar
528 (zerop (apply #'+ ;cdar ;exposants etrangers
529 (mapcar 'min expp expq
))))
531 (cons expp expq
) ;caadr cdadr
532 (cons p q
)))) ;caddr cdddr
534 (defun vivier (paires)
535 (let ((v (cons nil nil
)))
536 (do ((l (cdr paires
) (cdr l
))
539 (or (cdaar l
) ;paire deja vue
540 (setq r
(cdr (rplacd r
541 (cons (car l
) nil
))))))
542 (sort (cdr v
) ordpairs
)))
544 (defun rafraichir (paires q base
)
545 (let ((nvp (cons nil nil
)))
546 (cond ((car q
) ;paires p q pour p dans base
547 (do ((l (cdr base
) (cdr l
))
548 (p (cadr base
) (cadr l
))
549 (nvpa nvp
) ;liste des nouvelles paires
556 (setq nvpa
(cdr (rplacd nvpa
561 (setq nvpa
(cdr (rplacd nvpa
565 (do ((l paires
) ;rafraichir les anciennes
566 (pp) (f) (g) (ef) (eg))
569 f
(caddr pp
) g
(cdddr pp
)
570 ef
(cdar f
) eg
(cdar g
))
571 (cond ((or (null ef
) ;enlever si un pol est nul
574 ((or (not (equal ef
(caadr pp
))) ;un pol a change?
575 (not (equal eg
(cdadr pp
))))
576 (setq pp
(cond ((funcall ordexp ef eg
)
577 (apparier g f eg ef
))
578 (t (apparier f g ef eg
))))
579 (rplacd l
(cons pp
(cddr l
)))
581 (t (setq l
(cdr l
)))))
582 (nconc paires
(cdr nvp
))))
584 ;recherche des reductibles et reduction des elements de base
585 (defun reduire (base a b
) ;a ---> dernier element reduit
586 (do ((l0 a
) ; (vient d'etre insere)
587 (l1 (cdr a
)) ;b ---> provenance de cet element
589 (q (cadr a
) (car l1
))
590 (bit (eq a
(cdr b
)) (or bit
(eq l1
(cdr b
)))))
592 (cond (bit ;reduction par tout ce qui precede
593 (do ((l (cdr base
) (cdr l
))) ;q reductible?
595 ((eq l l1
) (setq l0 l1
)) ;q irreductible
596 ((ired2 q
(car l
)) ;ired2 est un predicat
597 (rplacd l0
(cdr l1
)) ;enlever q
598 (setq $nbreduc
(1+ $nbreduc
))
599 (and (setq l1
(inserer q base
))
600 (setq q0 q b l0 l0 l1
601 bit
(eq l0
(cdr b
))))
603 (t ;reduction par q0 seulement
604 (cond ((ired2 q q0
) ;q reductible
605 (rplacd l0
(cdr l1
)) ;enlever q
606 (setq $nbreduc
(1+ $nbreduc
))
607 (and (setq l1
(inserer q base
))
608 (setq q0 q b l0 l0 l1
609 bit
(eq l0
(cdr b
)))))
613 (defun inserer (q base
) ;retourne le lieu d'insertion
614 (do ((l2 base
) ;chercher ou`
615 (l3 (cdr base
)) ;inserer q...
616 (qq (cadr base
) (car l3
))
620 (setq $nbred0
(1+ $nbred0
))
621 (setq l2 q
)) ;si q est nul retourner nil..
622 ((or ;... pour inserer, mais t pour cond
624 (funcall ordexp
(cdar qq
) expq
))
625 (rplacd l2 nil
) ;pour accelerer la reduction
626 (setq q
(primpart q
))
627 (setq q
(idivise2 q
(cdr $base
))) ;reduire completement
628 (rplacd l2
(cons q l3
)))) ;inserer q
629 (cdr l2
)) ;lieu a retourner
630 (cond ((ired2 q qq
) ;reduire q
631 (setq expq
(cdar q
)) ;et
632 (setq l2 base
)) ;repartir
638 ;RESOLUTION DE SYSTEMES
639 ;On part d'une base standard pour un ordre compatible avec le degre. Elle
640 ;est representee par une liste de polynomes, chacun d'eux etant une liste de
641 ;monomes de la forme (coeff e1 ... en).
643 ;L'escalier est la liste des vecteurs exposants des monomes dominants.
644 (defun escalier (base)
647 ;La avriete est vide(i.e. de dim. -1) si l'escalier est reduit au vecteur nul
650 (apply 'and
(mapcar 'zerop
(car esc
))) )
652 ;La dimension est 0 si il y a un element de l'escalier sur chaque axe.
653 ;On suppose la base reduite, ce qui implique qu'il n'y a pas 2 elements de
654 ;l'escalier sur le meme axe
662 (mapcar #'(lambda (u) (min u
1))
664 ((null l
)(= i
(length (car esc
)))))))
666 ;Construction de la liste des monomes sous l'escalier
667 ;Le predicat sousp indique si un monome est sous l'escalier
668 (defun sous-esc (esc)
670 (m (mapcar #'(lambda (u)u
0) (car esc
)))
673 (rplaca i
(1+ (car i
)))
675 (setq l
(cons (copy-tree m
) l
))
681 ;Test mon2 ne divise pas mon1 pour 2 vecteurs d'exposants
682 (defun notdivmon (mon1 mon2
)
683 (minusp (apply 'min
(mapcar '- mon1 mon2
))))
685 ;sousp est utilise par sous-esc pour tester si un monome est au sous
687 (defun sousp (mon esc
)
689 (mapcar #'(lambda (u) (notdivmon mon u
)) esc
)))
691 ;ICI, IL FAUT RANGER LE RESULTAT DE LA FONCTION PRECEDENTE POUR L'ORDRE
692 ;COMPATIBLE CHOISI; CE RESULTAT EST UTILISE SOUS LE NOM DE basli
694 ;Construction de la matrice dont le polynome caracteristique a pour racine
695 ;les premieres coordonnees des solutions
696 ;les lignes et colonnes sont indexees par basli, chaque ligne etant en
697 ;representation creuse
698 ;LA FONCTION DIVISE RETOURNE LE RESTE DE LA DIVISION D'UN POLYNOME PAR LA
700 (defun umat (basli base
)
701 (mapcar #'(lambda (u) (divise
703 (cons 1 (rplaca (copy-tree u
) (1+ (car u
))))
708 ;densification d'une ligne
709 (defun densif (ligne basli
)
710 (let ((nl (cons '(mlist) nil
)))
711 (do ((b basli
(cdr b
))
714 (nl nl
(cdr (rplacd nl
(cons c nil
)))))
716 (and (equal (car b
) (cdar l
))
721 ;La suite appelle des fonctions macsyma et se trouve dans japsmac.l
722 ;Partie macsyma de japs.l
724 ;matrice macsyma; umatr est le resultat de umat
725 (defun matmac (basli base
)
726 (meval (cons '($matrix
) (mapcar #'(lambda (u) (densif u basli
))
727 (umat basli base
)))))
729 ;Enfin le polynome eliminant, retourne en macsyma
730 (defun elimpol (base ordexp var1
)
732 (let ((esc (escalier base
))
738 (matmac (sort (sous-esc esc
) ordexp
)
741 (t "dimension positive"))))
743 (defun $elimpol_err
(ordexp var1
)
744 (elimpol $errexp1 ordexp var1
))
746 ;;;; -*- Mode: LISP; Package: Macsyma; Base:10 -*- Saved by dl
747 ;;;; Macsyma version 309.0
750 ; ((mlist) $base $var1 $ordre)
751 ; ((elimpol) $base $var1 $ordre))
753 ;(add2lnc '(($elimpol) $base $var1 $ordre) $functions)
757 #'(lambda (u v
) (list '(mexpt) u v
))
771 (mapcar 'decterm a
))))
773 (defun decode (lpol lvar
)
776 (mapcar 'decpol lpol
))))
778 (defun $decode_poly
(poly sample
&aux header
)
779 (cond ((and sample
(consp sample
)) (setq header
(car sample
)))
780 (t (setq header $header
)))
781 (let ((monoms (loop for v in
(fourth header
)
782 collect
(list v
1 1))))
788 (loop for deg in
(cdr v
)
791 when
(not (eql 0 deg
))
792 do
(setq term
(ptimes term
794 finally
(return term
)
800 (defun show-lazard (term)
801 (cond ((or (atom term
) (atom (car term
)))(error "bad term"))
802 ((consp (caar term
)) (loop for v in term do
(show-lazard v
)))
803 (t (displa ($decode_poly term nil
)))))