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 ?)
57 *ipolmon
*iterm isyz
*icofpol -ipol -ipol2
58 *gpolmon
*gterm -gpol
*gcofpol
59 ired2 idiv-tete2
*gcd primpart
62 apparier rafraichir reduire inserer vivier
63 macplus macmoins macdiv mactimes
64 notdivmon densif sousp
67 $nbsyz $nbred $nbreduc $nbred0 ordexp orddeg ordpairs ordlex
71 ;; Keep the header for the last cre polynomial formed during a LIRE.
74 ;(defun $stand ($liste ordre)(grobner (lire $liste ordre) ordre))
75 (defun $stand
($liste
&optional
(ordre 'ordlex
))
76 (let* ((lis (lire $liste ordre
))
77 (base (grobner lis ordre
)))
79 (loop for w in base collect
($decode_poly w nil
)))))
85 ;Il faut traduire une liste de polynomes CRE; on suppose ici les
86 ;coefficients rationnels
87 ;Il faut avoir appele' RAT sur la liste de polynomes pour toutes les variables
88 ;apparaissent dans les en-tetes de tous les polynomes
90 ;Passer de CRE a polynome en la premiere variable
91 (defun lire1 (pol var
) ;en-tete deja enlevee
92 (cond ((numberp pol
) (list (list pol
0)))
93 ((equal (car pol
) var
)
94 (let ((res (cons nil nil
)))
95 (do ((p (cdr pol
) (cddr p
))
98 (rplacd r
(cons (list (cadr p
) (car p
))
100 (t (list (list pol
0)))))
102 ;passer de CRE a polynome en n variables
103 (defun lire2 (pol lvar
)
104 (cond ((null (cdr lvar
))
105 (lire1 pol
(car lvar
)))
107 (mapcan #'(lambda (u)
108 (mapcar #'(lambda (v)
110 (lire2 (car u
) (cdr lvar
))))
111 (lire1 pol
(car lvar
))))))
113 ;appliquer lire2 a une liste macsyma de polynomes
114 (defun lire (mliste ordexp
)
115 (or ($ratp mliste
) (setq mliste
($rat mliste
)))
116 (setq $header
(car (second mliste
)))
117 (or (eq (car $header
) 'mrat
) (error "bad rat form"))
118 (mapcar #'(lambda (u)
121 (reverse (cadddr (caadr mliste
))))
122 #'(lambda (v w
) (ordexp (cdr v
) (cdr w
)))))
126 ;ordre lexico inverse pour les exposants
127 (defun orddeg (m1 m2
)
128 (let ((d (- (apply '+ m1
) (apply '+ m2
))))
131 (t (do ((m1 (cdr m1
) (cdr m1
))
132 (m2 (cdr m2
) (cdr m2
))
133 (a (- (car m1
) (car m2
)) (- (car m1
) (car m2
))))
134 ((not (and (zerop a
) m1
)) (minusp a
)))))))
135 (setq orddeg
'orddeg
)
136 (setq $orddeg
'orddeg
)
138 (defun ordlex (m1 m2
)
139 (do ((m1 (cdr m1
) (cdr m1
))
140 (m2 (cdr m2
) (cdr m2
))
141 (a (- (car m1
) (car m2
)) (- (car m1
) (car m2
))))
142 ((not (and (zerop a
) m1
)) (plusp a
))))
144 (setq ordlex
'ordlex
)
145 (setq $ordlex
'ordlex
)
147 (defun ordexp (m1 m2
) ;ancienne version
148 (let ((d (- (apply '+ m1
) (apply '+ m2
))))
151 (t (do ((m1 m1
(cdr m1
))
153 ((not (and m1
(= (car m1
) (car m2
))))
154 (and m1
(< (car m1
) (car m2
)))))))))
156 (defun ordpairs (p1 p2
) ;nouvelle version moins bonne, mais
157 (let ((d1 (apply '+ (caar p1
))) ; ? meilleure pour lexico
158 (d2 (apply '+ (caar p2
))))
161 (or (funcall ordexp
(caadr p2
) (caadr p1
))
162 (and (equal (caadr p1
) (caadr p2
))
163 (funcall ordexp
(cdadr p2
) (cdadr p1
))))))))
165 (defun ordpairs (p1 p2
) ;ancienne version
166 (let ((exp1 (caar p1
))
168 (or (funcall ordexp exp2 exp1
)
169 (and (equal exp1 exp2
)
170 (or (funcall ordexp
(caadr p2
) (caadr p1
))
171 (and (equal (caadr p1
) (caadr p2
))
172 (funcall ordexp
(cdadr p2
) (cdadr p1
))))))))
174 (setq ordpairs
'ordpairs
)
176 ;OPERATIONS ELEMENTAIRES PRESERVATIVES (POLYNOMES) COEFFICIENTS GENERAUX
178 ;definition des multiplications
179 ;mactimes peut etre change si les coefficients sont restreints
180 ;par exemple, pour des entiers, on peut prendre "times"
182 (defun *gpolmon
(pol mon
)
183 (mapcar #'(lambda (u)
187 (defun *gterm
(m1 m2
)
189 (mactimes (car m1
) (car m2
))
190 (mapcar '+ (cdr m1
) (cdr m2
))))
193 ;(defun +pol (p1 p2) ;non destructif
194 ; (cond ((null p1) p2) ;recursion non terminale
195 ; ((null p2) p1) ;non utilise
196 ; ((equal (cdar p1) (cdar p2))
197 ; (let ((a (macplus (caar p1) (caar p2))))
198 ; (cond ((zerop a) (+pol (cdr p1) (cdr p2)))
201 ; (+pol (cdr p1) (cdr p2)))))))
202 ; ((funcall ordexp (cdar p1)(cdar p2))
203 ; (cons (car p1) (+pol (cdr p1) p2)))
204 ; (t (cons (car p2) (+pol (cdr p2) p1)))))
207 ; (let ((f (caddr pair))
210 ; (-pol (*polmon f (cons (caar g) (mapcar '- exp (cdar f))))
211 ; (*polmon (cdr g) (cons (caar f) (mapcar '- exp (cdar g)))))))
213 ;OPERATIONS ELEMENTAIRES DESTRUCTIVES (POLYNOMES) COEFFICIENTS GENERAUX
215 (defun *gcofpol
(c p
) ;destructif resultat dans p
216 (mapc #'(lambda(u) (rplaca u
(mactimes c
(car u
)))) p
))
218 ;Cette fonction retourne et lie a p1 la difference (cdr p1) - p2
219 ;iteratif et destructif
220 ;le polynome nul est retourne (cons nil nil)
226 (rplaca p1
(cadr p1
))
227 (rplacd p1
(cddr p1
)))
231 ((funcall ordexp e1 e2
)
234 (let ((a (macmoins (caadr p
) (caar q
))))
239 (rplaca (car p
) a
))))
242 (setq p
(cdr (rplacd p
(cons
244 (macmoins 0 (caar q
))
249 ;On definit maintenant la division d'un polynome par une base unitaire
250 ;Le polynome est remplace par le resultat
252 (defun red1 (pol1 p pol2
) ;destructif
253 (let ((a (mapcar '-
(cdar p
) (cdar pol2
)))) ;resultat dans pol1
254 (cond ((minusp (apply 'min a
)) ;pol2 est unitaire
260 (cons (caar p
) a
)))))))
262 (defun div-terme (p1 p base
)
263 (do ((a (cdar p
) (cdar p
))
266 (mapc #'(lambda (u) (red1 p1 p u
)) base
)))
268 (defun divise (p1 base
)
269 (do ((p (cdr (div-terme p1 p1 base
)) (cdr (div-terme p1 p base
))))
273 (let ((c (caar pol
)))
275 (rplaca u
(macdiv (car u
) c
)))
278 ; ;Comme ce qui precede, mais pseudo division pour eviter
279 ; ;les divisions de coefficients
280 ;(defun red2 (pol1 pol2) ;destructif
281 ; (let ((a (mapcar '- (cdar pol1) (cdar pol2))) ;resultat dans pol1
283 ; (cond ((minusp (apply 'min a)) nil) ;sans division
284 ; ((-pol (*cofpol (caar pol2) pol1) ;rend nil si pol1..
285 ; (*polmon (cdr pol2) ;..non modifie
288 ;(defun div-tete2 (p1 base)
289 ; (do ((a (cdar p1) (cdar p1))
292 ; (mapc #'(lambda (u) (red2 p1 u)) base)))
294 ;(defun divise2 (p1 base)
295 ; (do ((p (cdr p1) (cdr (div-tete2 p base))))
298 ;OPERATIONS ELEMENTAIRES PRESERVATIVES (POLYNOMES) COEFFICIENTS ENTIERS
300 ;definition des multiplications
301 ;mactimes peut etre change si les coefficients sont restreints
302 ; exemple, pour des entiers, on peut prendre "times"
304 (defun *ipolmon
(pol mon
)
305 (mapcar #'(lambda (u) (*iterm u mon
)) pol
))
307 (defun *iterm
(m1 m2
)
309 (* (car m1
) (car m2
))
310 (mapcar #'+ (cdr m1
) (cdr m2
))))
313 (let ((f (caddr pair
))
317 (setq $nbsyz
(1+ $nbsyz
)
323 (-ipol (*ipolmon f
(cons a
(mapcar '- exp
(cdar f
))))
324 (*ipolmon
(cdr g
) (cons b
(mapcar '- exp
(cdar g
)))))))
326 ;OPERATIONS ELEMENTAIRES DESTRUCTIVES (POLYNOMES) COEFFICIENTS ENTIERS
328 (defun *icofpol
(c p
) ;destructif resultat dans p
329 (mapc #'(lambda(u) (rplaca u
(* c
(car u
)))) p
))
331 ;Cette fonction retourne et lie a p1 la difference (cdr p1) - p2
332 ;iteratif et destructif
333 ;le polynome nul est retourne (cons nil nil)
336 (rplaca p1
(cadr p1
))
337 (rplacd p1
(cddr p1
)))
339 (defun -ipol2 (p1 p2
)
347 ((funcall ordexp e1 e2
)
350 (let ((a (- (caadr p
) (caar q
))))
355 (rplaca (car p
) a
))))
358 (setq p
(cdr (rplacd p
(cons
365 ;On definit maintenant la division d'un polynome par une base
366 ;Le polynome est remplace par le resultat
367 ;Pseudo division pour eviter
368 ;les divisions de coefficients
369 (defun ired2 (pol1 pol2
) ;destructif
370 (let ((a (mapcar '-
(cdar pol1
) (cdar pol2
))) ;resultat dans pol1
371 (c)(b)(d)) ;sans division
372 (cond ((minusp (apply 'min a
)) nil
) ;rend nil si pol1..
373 (t (setq $nbred
(1+ $nbred
) ;..non modifie
376 d
(gcd b c
) ;rend (cons nil nil)
377 b
(quotient b d
) ;si pol1 devient nul
379 (*icofpol b
(cdr pol1
))
384 (defun iredp (p1 p q
)
388 (cond ((not (minusp (apply 'min
389 (setq a
(mapcar '-
(cdar pp
) (cdar q
))))))
399 (rplacd p
(cdr pp
)))))))
401 (defun idivp (p1 p base
) ;pour idivise2, il faut multiplier
402 (do ((a (cdadr p
) (cdadr p
)) ;tout le polynome dividende
405 (mapc #'(lambda (u) (iredp p1 p u
)) base
)))
407 (defun idivise2 (p1 base
)
408 (do ((p p1
(idivp p1 p base
)))
409 ((null p
) (primpart p1
))))
411 ;OPERATIONS SUR LES COEFFICIENTS
413 (defun mactimes (a b
)
414 (meval (list '(mtimes) a b
)))
417 (meval (list '(mplus) a b
)))
419 (defun macmoins (a b
)
420 (meval (list '(mplus) a
(list '(mminus) b
))))
423 (meval (list '(mquotient) a b
)))
426 ; (do ((r (car lnb) (gcd r (car l)))
427 ; (l (cdr lnb) (cdr l)))
431 (let ((d (do ((p (cdr p
) (cdr p
)) ;calcul du contenu
432 (g (caar p
) (gcd g
(caar p
))))
433 ((or (eql (abs g
) 1) (null p
))
436 (mapc #'(lambda (u) ;diviser par le contenu
437 (rplaca u
(quotient (car u
) d
)))
442 ; (let ((d (*gcd (mapcar 'car
444 ; (mapc #'(lambda (u)
445 ; (rplaca u (quotient (car u) d)))
450 ;Construction de la base
451 ;Methode a la Buchberger-Bouzeghoub
452 ;base: liste de polynomes
453 ;paires: candidats sygyzies: ((exp."deja reduite").((exp1.exp2).(f.g)))
456 ; reduire tous les polynomes
457 ; calculer la liste des paires; vivier construit celles qui ne sont
459 ; reduire la premiere paire, inserer le resultat dans la base et
461 ;remettre a jour la liste des paires et recommencer
463 (defun grobner (gener ordexp
)
464 (setq $base
(cons nil
(sort (copy-tree gener
)
465 #'(lambda (u v
) (ordexp (cdar v
) (cdar u
))))))
467 (setq $nbsyz
0 $nbred
0 $nbreduc
0 $nbred0
0)
468 (reduire $base
(cdr $base
) (cddr $base
))
470 (mapcon #'(lambda (u)
471 (let ((exp (cdaar u
))
473 (mapcar #'(lambda (v) (apparier f v exp
(cdar v
)))
478 (sort paires ordpairs
)))
479 (do ((l (vivier paires
)) ;parcourir les paires
480 (exp) (exp1) (exp2) (p) (q))
482 (setq p
(car l
) exp
(caar p
)
483 exp1
(caadr p
) exp2
(cdadr p
))
484 (cond ((cdar p
) ;paire deja vue
486 ;on cherche maintenant h dans base tel
487 ;que h divise exp et que les syzygies
488 ;(f h) et (g h) ont ete calculees
489 ((do ((l1 (cdr $base
) l3
) ;"critere 3"
490 (l3 (cddr $base
) (cdr l3
))
491 (h (cadr $base
) (car l3
))
492 (exph (cdaadr $base
) (cdaar l3
)))
493 ((cond ((null l1
) t
) ;pas trouve de h
494 ((funcall ordexp exph exp
) (not (setq l1 nil
)))
496 (not (minusp (apply 'min
497 (mapcar '- exp exph
))))
498 (let ((exph1 (mapcar 'max exph exp1
)))
499 (or (funcall ordexp exp exph1
)
500 (and (equal exp exph1
)
501 (funcall ordexp exp2 exph
))))
502 (let ((exph2 (mapcar 'max exph exp2
)))
503 (or (funcall ordexp exp exph2
)
504 (and (equal exp exph2
)
505 (funcall ordexp exp1 exph
)))))))
509 (rplacd (car p
) t
)) ;le critere 3 est verifie
511 (rplacd (car p
) t
) ;la paire va etre traitee
515 (reduire $base q nil
)
516 (format t
"~% nbsyz = ~a nbred = ~a nbreduc = ~a nbred0 = ~a lbase = ~d~%"
517 $nbsyz $nbred $nbreduc $nbred0
(length (cdr base
)))
519 (print (escalier (cdr $base
)))
522 (rafraichir paires p $base
)
523 (setq l
(vivier paires
)))
526 (format t
"~% nbsyz = ~a nbred = ~a nbreduc = ~a nbred0 = ~a lbase = ~a~% paires a voir = ~d~%"
527 $nbsyz $nbred $nbreduc $nbred0
(length (cdr base
)) (length l
))
529 ))))) ;paire suivante
530 (setq $base
(cdr $base
))
531 (mapc #'(lambda (u) (idivise2 u $base
))
532 $base
) ;reduire completement
533 (mapc 'monic $base
)))
535 (defun apparier (p q expp expq
)
538 (mapcar #'max expp expq
) ;caar
539 (zerop (apply #'+ ;cdar ;exposants etrangers
540 (mapcar 'min expp expq
))))
542 (cons expp expq
) ;caadr cdadr
543 (cons p q
)))) ;caddr cdddr
545 (defun vivier (paires)
546 (let ((v (cons nil nil
)))
547 (do ((l (cdr paires
) (cdr l
))
550 (or (cdaar l
) ;paire deja vue
551 (setq r
(cdr (rplacd r
552 (cons (car l
) nil
))))))
553 (sort (cdr v
) ordpairs
)))
555 (defun rafraichir (paires q base
)
556 (let ((nvp (cons nil nil
)))
557 (cond ((car q
) ;paires p q pour p dans base
558 (do ((l (cdr base
) (cdr l
))
559 (p (cadr base
) (cadr l
))
560 (nvpa nvp
) ;liste des nouvelles paires
567 (setq nvpa
(cdr (rplacd nvpa
572 (setq nvpa
(cdr (rplacd nvpa
576 (do ((l paires
) ;rafraichir les anciennes
577 (pp) (f) (g) (ef) (eg))
580 f
(caddr pp
) g
(cdddr pp
)
581 ef
(cdar f
) eg
(cdar g
))
582 (cond ((or (null ef
) ;enlever si un pol est nul
585 ((or (not (equal ef
(caadr pp
))) ;un pol a change?
586 (not (equal eg
(cdadr pp
))))
587 (setq pp
(cond ((funcall ordexp ef eg
)
588 (apparier g f eg ef
))
589 (t (apparier f g ef eg
))))
590 (rplacd l
(cons pp
(cddr l
)))
592 (t (setq l
(cdr l
)))))
593 (nconc paires
(cdr nvp
))))
595 ;recherche des reductibles et reduction des elements de base
596 (defun reduire (base a b
) ;a ---> dernier element reduit
597 (do ((l0 a
) ; (vient d'etre insere)
598 (l1 (cdr a
)) ;b ---> provenance de cet element
600 (q (cadr a
) (car l1
))
601 (bit (eq a
(cdr b
)) (or bit
(eq l1
(cdr b
)))))
603 (cond (bit ;reduction par tout ce qui precede
604 (do ((l (cdr base
) (cdr l
))) ;q reductible?
606 ((eq l l1
) (setq l0 l1
)) ;q irreductible
607 ((ired2 q
(car l
)) ;ired2 est un predicat
608 (rplacd l0
(cdr l1
)) ;enlever q
609 (setq $nbreduc
(1+ $nbreduc
))
610 (and (setq l1
(inserer q base
))
611 (setq q0 q b l0 l0 l1
612 bit
(eq l0
(cdr b
))))
614 (t ;reduction par q0 seulement
615 (cond ((ired2 q q0
) ;q reductible
616 (rplacd l0
(cdr l1
)) ;enlever q
617 (setq $nbreduc
(1+ $nbreduc
))
618 (and (setq l1
(inserer q base
))
619 (setq q0 q b l0 l0 l1
620 bit
(eq l0
(cdr b
)))))
624 (defun inserer (q base
) ;retourne le lieu d'insertion
625 (do ((l2 base
) ;chercher ou`
626 (l3 (cdr base
)) ;inserer q...
627 (qq (cadr base
) (car l3
))
631 (setq $nbred0
(1+ $nbred0
))
632 (setq l2 q
)) ;si q est nul retourner nil..
633 ((or ;... pour inserer, mais t pour cond
635 (funcall ordexp
(cdar qq
) expq
))
636 (rplacd l2 nil
) ;pour accelerer la reduction
637 (setq q
(primpart q
))
638 (setq q
(idivise2 q
(cdr $base
))) ;reduire completement
639 (rplacd l2
(cons q l3
)))) ;inserer q
640 (cdr l2
)) ;lieu a retourner
641 (cond ((ired2 q qq
) ;reduire q
642 (setq expq
(cdar q
)) ;et
643 (setq l2 base
)) ;repartir
649 ;RESOLUTION DE SYSTEMES
650 ;On part d'une base standard pour un ordre compatible avec le degre. Elle
651 ;est representee par une liste de polynomes, chacun d'eux etant une liste de
652 ;monomes de la forme (coeff e1 ... en).
654 ;L'escalier est la liste des vecteurs exposants des monomes dominants.
655 (defun escalier (base)
658 ;La avriete est vide(i.e. de dim. -1) si l'escalier est reduit au vecteur nul
661 (apply 'and
(mapcar 'zerop
(car esc
))) )
663 ;La dimension est 0 si il y a un element de l'escalier sur chaque axe.
664 ;On suppose la base reduite, ce qui implique qu'il n'y a pas 2 elements de
665 ;l'escalier sur le meme axe
673 (mapcar #'(lambda (u) (min u
1))
675 ((null l
)(= i
(length (car esc
)))))))
677 ;Construction de la liste des monomes sous l'escalier
678 ;Le predicat sousp indique si un monome est sous l'escalier
679 (defun sous-esc (esc)
681 (m (mapcar #'(lambda (u)u
0) (car esc
)))
684 (rplaca i
(1+ (car i
)))
686 (setq l
(cons (copy-tree m
) l
))
692 ;Test mon2 ne divise pas mon1 pour 2 vecteurs d'exposants
693 (defun notdivmon (mon1 mon2
)
694 (minusp (apply 'min
(mapcar '- mon1 mon2
))))
696 ;sousp est utilise par sous-esc pour tester si un monome est au sous
698 (defun sousp (mon esc
)
700 (mapcar #'(lambda (u) (notdivmon mon u
)) esc
)))
702 ;ICI, IL FAUT RANGER LE RESULTAT DE LA FONCTION PRECEDENTE POUR L'ORDRE
703 ;COMPATIBLE CHOISI; CE RESULTAT EST UTILISE SOUS LE NOM DE basli
705 ;Construction de la matrice dont le polynome caracteristique a pour racine
706 ;les premieres coordonnees des solutions
707 ;les lignes et colonnes sont indexees par basli, chaque ligne etant en
708 ;representation creuse
709 ;LA FONCTION DIVISE RETOURNE LE RESTE DE LA DIVISION D'UN POLYNOME PAR LA
711 (defun umat (basli base
)
712 (mapcar #'(lambda (u) (divise
714 (cons 1 (rplaca (copy-tree u
) (1+ (car u
))))
719 ;densification d'une ligne
720 (defun densif (ligne basli
)
721 (let ((nl (cons '(mlist) nil
)))
722 (do ((b basli
(cdr b
))
725 (nl nl
(cdr (rplacd nl
(cons c nil
)))))
727 (and (equal (car b
) (cdar l
))
732 ;La suite appelle des fonctions macsyma et se trouve dans japsmac.l
733 ;Partie macsyma de japs.l
735 ;matrice macsyma; umatr est le resultat de umat
736 (defun matmac (basli base
)
737 (meval (cons '($matrix
) (mapcar #'(lambda (u) (densif u basli
))
738 (umat basli base
)))))
740 ;Enfin le polynome eliminant, retourne en macsyma
741 (defun elimpol (base ordexp var1
)
743 (let ((esc (escalier base
))
749 (matmac (sort (sous-esc esc
) ordexp
)
752 (t "dimension positive"))))
754 (defun $elimpol_err
(ordexp var1
)
755 (elimpol $errexp1 ordexp var1
))
757 ;;;; -*- Mode: LISP; Package: Macsyma; Base:10 -*- Saved by dl
758 ;;;; Macsyma version 309.0
761 ; ((mlist) $base $var1 $ordre)
762 ; ((elimpol) $base $var1 $ordre))
764 ;(add2lnc '(($elimpol) $base $var1 $ordre) $functions)
768 #'(lambda (u v
) (list '(mexpt) u v
))
782 (mapcar 'decterm a
))))
784 (defun decode (lpol lvar
)
787 (mapcar 'decpol lpol
))))
789 (defun $decode_poly
(poly sample
&aux header
)
790 (cond ((and sample
(consp sample
)) (setq header
(car sample
)))
791 (t (setq header $header
)))
792 (let ((monoms (loop for v in
(fourth header
)
793 collect
(list v
1 1))))
799 (loop for deg in
(cdr v
)
802 when
(not (eql 0 deg
))
803 do
(setq term
(ptimes term
805 finally
(return term
)
811 (defun show-lazard (term)
812 (cond ((or (atom term
) (atom (car term
)))(error "bad term"))
813 ((consp (caar term
)) (loop for v in term do
(show-lazard v
)))
814 (t (displa ($decode_poly term nil
)))))