(* ----------------------------------------------------------------------------
 * $Id: DIPADOM.mi,v 1.9 1995/11/05 09:26:20 kredel Exp $
 * ----------------------------------------------------------------------------
 * This file is part of MAS.
 * ----------------------------------------------------------------------------
 * Copyright (c) 1989 - 1992 Universitaet Passau
 * ----------------------------------------------------------------------------
 * $Log: DIPADOM.mi,v $
 * Revision 1.9  1995/11/05 09:26:20  kredel
 * Improved polynomial parsing.
 *
 * Revision 1.8  1994/10/21  12:33:50  pfeil
 * added procedure DIPLIR.
 *
 * Revision 1.7  1994/09/01  13:21:43  pfeil
 * modified comment
 *
 * Revision 1.6  1994/06/16  12:54:02  pfeil
 * changed number of parameters in procedure DIPSFF.
 * changed parameter type of procedures SetPFactFunc, SetPSqfrFunc.
 *
 * Revision 1.5  1994/06/10  12:07:00  pfeil
 * Minor changes.
 *
 * Revision 1.4  1994/06/09  14:48:27  pfeil
 * Added DIPFAC, DIPIRL, DIPNF, DIPRLF, DIPS, DIPSFF for DIPDCGB.
 *
 * Revision 1.3  1992/10/15  16:30:10  kredel
 * Changed rcsid variable
 *
 * Revision 1.2  1992/02/12  17:31:21  pesch
 * Moved CONST definition to the right place
 *
 * Revision 1.1  1992/01/22  15:09:35  kredel
 * Initial revision
 *
 * ----------------------------------------------------------------------------
 *)
  
IMPLEMENTATION MODULE DIPADOM;

(* DIP Arbitrary Domain Implementation Module. *)



FROM MASSTOR IMPORT LIST, SIL, BETA, FIRST, ADV, RED, COMP,
                    LENGTH, LIST1, SRED, SFIRST, INV;

FROM MASERR IMPORT severe, ERROR;

FROM MASBIOS IMPORT BLINES, SWRITE, CWRITE, CREAD, CREADB, 
                    SOLINE, BKSP, MASORD, LETTER, DIGIT;

FROM SACLIST IMPORT EQUAL, FIRST2, SECOND, LIST2, CINV, CLOUT, 
                    OWRITE, AWRITE, CCONC;

FROM SACPOL IMPORT VREAD, VLSRCH, VLWRIT;
 
FROM DIPC    IMPORT DIPNBC, DIPADS, DIPADV, DIPEVL, DIPMAD, 
                    DIPMPM, DIPFMO, 
                    DIPMCP, DIPMRD, DIPCMP, DIPTCF, DIPTCS, 
                    DIPMPV, DIPLBC, DIPINV, DIPADM, DIPNOV,
                    STVL, BACKUB, PFDIP, DIPFP, 
                    EVRASP, EVRAND, EVDFSI, EVSUM, 
                    EPREAD, EVSIGN, EVDER, EVCOMP;

FROM MASADOM IMPORT ADDIF, ADEXP, ADFI, ADGCD, ADINV, ADINVT,
                    ADLCM, ADNEG, ADONE, ADPROD, ADQUOT, 
                    ADREAD, ADSIGN, ADSUM, ADWRIT, ADFIP, 
                    ADDDREAD, ADDDWRIT, ADVLDD,
		    ADPFACT, ADPNF, ADPSFF, ADPSP;

CONST rcsidi = "$Id: DIPADOM.mi,v 1.9 1995/11/05 09:26:20 kredel Exp $";
CONST copyrighti = "Copyright (c) 1989 - 1992 Universitaet Passau";



PROCEDURE DIPEXP(A,NL: LIST): LIST; 
(*Distributive polynomial exponentiation.  D is a non zero
distributive polynomial. n is a non-negative beta-integer.
B=A**n. If n=0 then a polynomial in zero variables is returned. *)
VAR  AL, B, BL, D, KL: LIST; 
BEGIN
(*1*) (*nl less than or equal to 1.*) 
      IF NL = 0 THEN AL:=DIPLBC(A); D:=RED(AL); BL:=ADFI(D,1); 
         B:=DIPFMO(BL,BETA); END; 
      IF NL = 1 THEN B:=A; RETURN(B); END; 
(*2*) (*recursion.*) KL:=NL DIV 2; B:=DIPEXP(A,KL); B:=DIPROD(B,B); 
      IF NL > 2*KL THEN B:=DIPROD(B,A); END; 
(*5*) RETURN(B); END DIPEXP; 


PROCEDURE DIFIP(A,D: LIST): LIST; 
(*Distributive polynomial from distributive integral polynomial.
A is a distributive integral polynomial with inverse
lexicographical term ordering. D is the domain
descriptor for the distributive polynomial B. *)
VAR   AL, AP, B, BL, BLP, CL, EL, FL, v, MP, RL, RLS, RLP: LIST; 
BEGIN
(*1*) (*a = 0. *) 
      IF A = 0 THEN B:=0; RETURN(B); END; 
(*2*) (*adjust structure. *) PFDIP(A, RL,AP); 
      v:=ADVLDD(D); RLS:=LENGTH(v); RLP:=RL-RLS; 
      IF RLP < 0 THEN OWRITE(RLP); B:=0;
         ERROR(severe,"DIFIP: to few coefficient variables.");
         RETURN(B) END;
      AP:=DIPFP(RLP,AP); 
(*3*) (*convert ceofficients. *) B:=SIL; 
      REPEAT DIPMAD(AP, AL,EL,AP); 
             BL:=ADFIP(D,AL);  
             IF ADSIGN(BL) <> 0 THEN B:=DIPMCP(EL,BL,B) END; 
             UNTIL AP = SIL; 
(*4*) (*finish. *) 
      IF B = SIL THEN B:=0; ELSE B:=INV(B); END; 
(*5*) RETURN(B); END DIFIP; 


PROCEDURE DILRD(V,D: LIST): LIST; 
(*Distributive polynomial list read. V is a variable list. 
A list of distributive polynomials
in r variables, where r=length(V), r ge 0, is read from
the input stream. Any blanks preceding a are skipped. *)
VAR  A, AL, C: LIST; 
BEGIN
(*1*) (*no list. *) C:=CREADB(); 
      IF C <> MASORD("(") THEN ERROR(severe,"ERROR FOUND BY DILRD."); 
         RETURN(A); END; 
(*2*) (*read polynomials. *) A:=BETA; 
      REPEAT C:=CREADB(); 
             IF C = MASORD(",") THEN C:=CREADB(); END; 
             IF C <> MASORD(")") THEN BKSP; AL:=DIREAD(V,D); 
                A:=COMP(AL,A); END; 
             UNTIL C = MASORD(")"); 
      A:=INV(A); 
(*5*) RETURN(A); END DILRD; 


PROCEDURE DILSUM(A: LIST): LIST; 
(*Distributive polynomial list sum. D is a circular
list of distributive polynomials. B is the sum of all
polynomials in A. *)
VAR  B, BP, BPP, C, CP, CPP: LIST; 
BEGIN
(*1*) (*nothing to do. *) 
      IF A = SIL THEN B:=0; RETURN(B); END; 
(*2*) (*merge. *) C:=A; ADV(C, B,CP); 
      WHILE C <> CP DO ADV(CP, BP,CPP); BPP:=DIPSUM(B,BP); 
            SFIRST(C,BPP); SRED(C,CPP); C:=CPP; ADV(C, B,CP); END; 
(*5*) RETURN(B); END DILSUM; 


PROCEDURE DILWR(A,V: LIST); 
(*Distributive polynomial list write. V is a
variable list. A list of distributive polynomials
in r variables, where r=length(V), r ge 0, is written to
the output stream. *)
VAR  AL, AP, LS, RS: LIST; 
BEGIN
(*1*) (*format. *) BLINES(0); (*LS:=LMARG; RS:=RMARG; LMARG:=10; 
      RMARG:=60; BLINES(0); *)
(*2*) (*write polynomials. *) AP:=A; 
      WHILE AP <> SIL DO ADV(AP, AL,AP); DIWRIT(AL,V); BLINES(1); 
            END; 
      (*LMARG:=LS; RMARG:=RS;*) 
(*5*) RETURN; END DILWR; 


PROCEDURE DIPBCP(A,BL: LIST): LIST; 
(*Distributive polynomial base coefficient product. A is a
distributive polynomial, b is a base coefficient. C=A*b.*)
VAR  AL, AP, C, EL, PL: LIST; 
BEGIN
(*1*) (*a=0 or bl=0.*) 
      IF (A = 0) OR (ADSIGN(BL) = 0) THEN C:=0; RETURN(C); 
      END; 
(*2*) (*multiply.*) C:=BETA; AP:=A; 
      REPEAT DIPMAD(AP, AL,EL,AP); PL:=ADPROD(AL,BL); 
             C:=DIPMCP(EL,PL,C); 
             UNTIL AP = SIL; 
      C:=INV(C); RETURN(C); 
(*5*) END DIPBCP; 


PROCEDURE DIPDIF(A,B: LIST): LIST; 
(*Distributive polynomial difference. A and B are
distributive polynomials. C=A-B.*)
VAR  AL, AP, APP, BL, BP, C, CL, CP, CPP, EL, FL, SL: LIST; 
BEGIN
(*1*) (* a or b zero.*) 
      IF A = 0 THEN C:=DIPNEG(B); RETURN(C); END; 
      IF B = 0 THEN C:=A; RETURN(C); END; 
(*2*) (*match coefficients.*) AP:=A; BP:=B; CP:=BETA; 
      REPEAT EL:=DIPEVL(AP); FL:=DIPEVL(BP); SL:=EVCOMP(EL,FL); 
             IF SL = 1 THEN DIPMAD(AP, AL,EL,AP); 
                CP:=DIPMCP(EL,AL,CP); ELSE
                IF SL = -1 THEN DIPMAD(BP, BL,FL,BP); 
                   CL:=ADNEG(BL); CP:=DIPMCP(FL,CL,CP); ELSE DIPMAD(AP,
                   AL,EL,AP); DIPMAD(BP, BL,FL,BP); CL:=ADDIF(AL,BL); 
                   IF ADSIGN(CL) <> 0 THEN CP:=DIPMCP(EL,CL,CP); 
                   END; 
                   END; 
                END; 
             UNTIL (AP = SIL) OR (BP = SIL); 
(*3*) (*finish.*) APP:=AP; 
      IF AP = SIL THEN
         IF BP <> SIL THEN APP:=DIPNEG(BP); END; 
         END; 
      IF CP = SIL THEN C:=APP; ELSE CPP:=CP; C:=INV(CP); 
         SRED(CPP,APP); END; 
      IF C = SIL THEN C:=0; END; 
      RETURN(C); 
(*6*) END DIPDIF; 


PROCEDURE DIPFAC(A,VOO: LIST): LIST;
(* distributive polynomial factorization.
   A is a polynomial in distributive representation,
   VOO is a flag, use variable order optimization iff VOO = 1,
   returns a list ((e1,f1),...,(ek,fk)), ei positive integers,
   fi irreducible polynomials in distributive representation,
   where A = u * f1**e1 * ... * fk**ek and u unit.
   The ordering of the factors is non-deterministic !! *)
BEGIN
   IF A=0 THEN RETURN(SIL); END;
   RETURN(ADPFACT(A,VOO));
END DIPFAC;


PROCEDURE DIPIRL(VAR P: LIST; VAR CS: BOOLEAN);
(* distributive polynomials interreduced list of polynomials.
   P is a list of polynomials in distributive representation
   over an arbitrary domain,
   CS is a flag, CS = TRUE iff P is changed,
   returns a interreduced list of polynomials R=(p1,...,pk),
   R is the result of reducing each pi modulo R-(pi)
   until no further reductions are possible. *)
VAR H,f,HTf,HTg,g: LIST;
    NewHT: BOOLEAN;
BEGIN
   CS:=FALSE;
   REPEAT
      H:=SIL; NewHT:=FALSE;
      WHILE P<>SIL DO
	 ADV(P,f,P);
	 HTf:=DIPEVL(f);
	 g:=DIPNF(CCONC(P,H),f);
	 IF g<>0 THEN
	    HTg:=DIPEVL(g);
            IF EQUAL(HTf,HTg)=1 THEN
               IF EQUAL(f,g)<>1 THEN CS:=TRUE; END; 
            ELSE
	       NewHT:=TRUE; CS:=TRUE;
            END; (* IF EQUAL... *)
	    H:=COMP(g,H);
	 END; (* IF g<>0... *)
      END; (* WHILE ... *)
      P:=H;
   UNTIL NOT(NewHT);
END DIPIRL;


PROCEDURE DIPLIR(P: LIST): LIST;
(* distributive polynomial list interreduce.
   P is a list of polynomials in distributive representation
   over an arbitrary domain,
   returns a interreduced list of polynomials R=(p1,...,pk),
   R is the result of reducing each pi modulo R-(pi)
   until no further reductions are possible. *)
VAR H,f,HTf,HTg,g: LIST;
    NewHT: BOOLEAN;
BEGIN
   REPEAT
      H:=SIL; NewHT:=FALSE;
      WHILE P<>SIL DO
	 ADV(P,f,P);
	 HTf:=DIPEVL(f);
	 g:=DIPNF(CCONC(P,H),f);
	 IF g<>0 THEN
	    HTg:=DIPEVL(g);
            IF EQUAL(HTf,HTg)<>1 THEN NewHT:=TRUE; END;
	    H:=COMP(g,H);
	 END; (* IF g<>0... *)
      END; (* WHILE ... *)
      P:=H;
   UNTIL NOT(NewHT);
   RETURN(P);
END DIPLIR;


PROCEDURE DIPRLF(P,p: LIST): LIST;
(* distributive polynomials reduce list of polynomials with factor.
   P is a list of polynomials in distributive representation
   over an arbitrary domain, p is a polynomial of same kind,
   returns a list of reduced polynomials R=(p1,...,pk),
   R is the result of reducing each polynomial of P  modulo (p) *)
VAR H,f,g: LIST;
BEGIN
   H:=SIL;
   WHILE P<>SIL DO
      ADV(P,f,P);
      g:=DIPNF(LIST1(p),f);
      IF g<>0 THEN H:=COMP(g,H); END;
   END; (* WHILE P... *)
   RETURN(H);
END DIPRLF;


PROCEDURE DIPMOC(A: LIST): LIST; 
(*Distributive polynomial monic. A and A are
distributive polynomials, C=A/lbc(A) if A ne 0
C=0 if A eq 0. *)
VAR  BL, C, CL, SL: LIST; 
BEGIN
(*1*) (*a=0.*) C:=A; 
      IF A = 0 THEN RETURN(C); END; 
(*2*) (*multiply.*) BL:=DIPLBC(A); SL:=ADONE(BL); 
      IF SL = 1 THEN RETURN(C); END; 
      SL:=ADINVT(BL); 
      IF SL <> 1 THEN RETURN(C); END; 
      CL:=ADINV(BL); C:=DIPBCP(A,CL); 
(*5*) RETURN(C); END DIPMOC; 


PROCEDURE DIPNEG(A: LIST): LIST; 
(*Distributive polynomial negative. B= -A.*)
VAR  AL, AS, B, BL, EL: LIST; 
BEGIN
(*1*) (*a=0.*) 
      IF A = 0 THEN B:=0; RETURN(B); END; 
(*2*) (*general case.*) AS:=A; B:=BETA; 
      REPEAT DIPMAD(AS, AL,EL,AS); BL:=ADNEG(AL); B:=DIPMCP(EL,BL,B); 
             UNTIL AS = SIL; 
      B:=INV(B); RETURN(B); 
(*5*) END DIPNEG; 


PROCEDURE DIPNF(A,B: LIST): LIST;
(* distributive polynomial normalform.
   A is a list of polynomials in distributive representation,
   B is a polynomial as above,
   returns a polynomial h such that B is reducible to h
   modulo A and h is in normalform with respect to A *)
BEGIN
   RETURN(ADPNF(A,B));
END DIPNF;


PROCEDURE DIPQR(A,B: LIST;  VAR Q,R: LIST); 
(*Distributive polynomial quotient and remainder.
A and B are distributive polynomials with B ne 0.
Q and R are unique distributive rational polynomials such
that either B divides A, so Q=A/B and R=0  or B does not
divide A, so A=B*Q+R with deg(R) lt deg(B). *)
VAR  AL, BL, BP, DL, ML, NL, Q1, QL, QP, RP, SL, TL: LIST; 
BEGIN
(*1*) (*initialise.*) DIPMAD(B, BL,NL,BP); 
      IF BP = SIL THEN BP:=0; END; 
      Q:=BETA; R:=A; 
(*2*) (*compute quotient terms.*) 
LOOP
      WHILE R <> 0 DO ML:=DIPEVL(R); EVDFSI(ML,NL, DL,TL); 
            IF TL < 0 THEN EXIT (*GO TO 3;*) END; 
            AL:=DIPLBC(R); QL:=ADQUOT(AL,BL); Q:=DIPMCP(DL,QL,Q); 
            Q1:=DIPFMO(QL,DL); RP:=DIPMRD(R); QP:=DIPROD(BP,Q1); 
            R:=DIPDIF(RP,QP); END; 
      EXIT; END;
(*3*) (*finish.*) 
      IF Q = SIL THEN Q:=0; ELSE Q:=INV(Q); END; 
      RETURN; 
(*6*) END DIPQR; 


PROCEDURE DIPROD(A,B: LIST): LIST; 
(*Distributive polynomial product. A and B are
distributive polynomials. C=A*B.*)
VAR  AL, AP, AS, BL, BS, C, C1, CL, CS, EL, FL, GL: LIST; 
BEGIN
(*1*) (*a or b zero.*) 
      IF (A = 0) OR (B = 0) THEN C:=0; RETURN(C); END; 
(*2*) (*general case.*) AS:=CINV(A); BS:=B; C:=LIST1(0); CS:=C; 
      REPEAT DIPMAD(BS, BL,FL,BS); AP:=AS; C1:=BETA; 
             REPEAT DIPMAD(AP, EL,AL,AP); CL:=ADPROD(AL,BL); 
                    GL:=EVSUM(EL,FL); C1:=DIPMCP(CL,GL,C1); 
                    UNTIL AP = SIL; 
             C:=COMP(C1,C); 
             UNTIL BS = SIL; 
      ADV(C, C1,C); SFIRST(CS,C1); SRED(CS,C); C:=DILSUM(C); 
(*5*) RETURN(C); END DIPROD; 


PROCEDURE DIPS(A,B: LIST): LIST;
(* distributive polynomial S-polynomial.
   A and B are polynomials in distributive representation,
   returns the S-polynomial of A and B *)
BEGIN
   RETURN(ADPSP(A,B));
END DIPS;


PROCEDURE DIPSFF(A,VOO: LIST): LIST;
(* distributive polynomial squarefree factorization.
   A is a polynomial in distributive representation,
   VOO is a flag, use variable order optimization iff VOO = 1,
   returns a list ((e1,p1),...,(ek,pk)), ei positive integers,
   pi squarefree polynomials in distributive representation,
   where A = u * p1**e1 * ... * pk**ek and u unit. *)
BEGIN
   IF A=0 THEN RETURN(SIL); END;
   RETURN(ADPSFF(A,VOO));
END DIPSFF;


PROCEDURE DIPSUM(A,B: LIST): LIST; 
(*Distributive polynomial sum. A and B are
distributive polynomials. C=A+B. *)
VAR  AL, AP, APP, BL, BP, C, CL, CP, CPP, EL, FL, SL: LIST; 
BEGIN
(*1*) (* a or b zero.*) 
      IF A = 0 THEN C:=B; RETURN(C); END; 
      IF B = 0 THEN C:=A; RETURN(C); END; 
(*2*) (*match coefficients.*) AP:=A; BP:=B; CP:=BETA; 
      REPEAT EL:=DIPEVL(AP); FL:=DIPEVL(BP); SL:=EVCOMP(EL,FL); 
             IF SL = 1 THEN DIPMAD(AP, AL,EL,AP); 
                CP:=DIPMCP(EL,AL,CP); ELSE
                IF SL = -1 THEN DIPMAD(BP, BL,FL,BP); 
                   CP:=DIPMCP(FL,BL,CP); ELSE DIPMAD(AP, AL,EL,AP); 
                   DIPMAD(BP, BL,FL,BP); CL:=ADSUM(AL,BL); 
                   IF ADSIGN(CL) <> 0 THEN CP:=DIPMCP(EL,CL,CP); 
                   END; 
                   END; 
                END; 
             UNTIL (AP = SIL) OR (BP = SIL); 
(*3*) (*finish.*) 
      IF AP = SIL THEN APP:=BP; ELSE APP:=AP; END; 
      IF CP = SIL THEN C:=APP; ELSE CPP:=CP; C:=INV(CP); 
         SRED(CPP,APP); END; 
      IF C = SIL THEN C:=0; END; 
      RETURN(C); 
(*6*) END DIPSUM; 


PROCEDURE DIREAD(V,D: LIST): LIST; 
(*Distributive polynomial read. V is a variable list.
a distributive polynomial A in r variables, where
r=length(V), r ge 0, is read from the input stream. any
blanks preceding A are skipped. *)
VAR  A, A1, AL, AP, C, EL, ES, FL, IL, JL, RL, VL: LIST; 
BEGIN
(*1*) (*rl=0 or a=0.*) A:=0; C:=CREADB(); 
      IF C = MASORD("0") THEN RETURN(A); END; 
      BKSP; 
(*2*) (*initialise.*) C:=CREADB(); BKSP; 
      IF C = MASORD(",") THEN (*GO TO 7;*) 
         ERROR(severe,"ERROR FOUND BY DIREAD.");  
         RETURN(A); END; 
      FL:=0; 
      IF C = MASORD("(") THEN C:=CREADB(); FL:=1; END; 
      IF C = MASORD(")") THEN
         IF FL = 1 THEN RETURN(A); END; 
         (*GO TO 7;*) ERROR(severe,"ERROR FOUND BY DIREAD.");  
         RETURN(A); END; 
      RL:=LENGTH(V); ES:=BETA; 
      FOR IL:=1 TO RL DO ES:=COMP(0,ES); END; 
      AL:=ADFI(D,1); A1:=DIPFMO(AL,ES); AP:=A1; 
LOOP LOOP
(*3*) (*next input. determine next action. *) C:=CREADB(); 
      IF C = MASORD(")") THEN
         IF FL = 0 THEN BKSP; END; 
         RETURN(A); END; 
      IF C = MASORD(",") THEN BKSP; RETURN(A); END; 
      IF C = MASORD("-") THEN AP:=DIPNEG(AP); END; 
      IF (C = MASORD("+")) OR (C = MASORD("-")) THEN C:=CREADB(); END; 
      IF C = MASORD("*") THEN C:=CREADB(); END; 
      BKSP; 
(*4*) (*read coefficient.*) 
      IF DIGIT(C) OR (C = MASORD("(")) THEN AL:=ADREAD(D); 
         EL:=EPREAD(); 
         IF ADSIGN(AL) = 0 THEN AP:=0; ELSE AL:=ADEXP(AL,EL); 
            AP:=DIPBCP(AP,AL); END; 
         EXIT; (*GO TO 8;*) END; 
(*6*) (*read monic monomial.*) 
      IF LETTER(C) THEN VL:=VREAD(); JL:=VLSRCH(VL,V); 
         IF JL = 0 THEN BACKUB; AL:=ADREAD(D); 
            IF ADONE(AL) = 1 THEN (*GO TO 7;*)
               ERROR(severe,"ERROR FOUND BY DIREAD.");  
               RETURN(A); END; 
            EL:=EPREAD(); 
            IF ADSIGN(AL) = 0 THEN AP:=0; ELSE AL:=ADEXP(AL,EL); 
               AP:=DIPBCP(AP,AL); END; 
            ELSE EL:=EPREAD(); AP:=DIPMPV(AP,JL,EL); END; 
         EXIT; (*GO TO 8;*) END; 
      END;
(*7*) (*error.*)  
(*8*) (*complete polynomial.*) C:=CREADB(); BKSP; 
      IF (((C = MASORD("+")) OR (C = MASORD("-"))) OR (C = MASORD(")")))
      OR (C = MASORD(",")) THEN A:=DIPSUM(A,AP); AP:=A1; END; 
      END; (*GO TO 3;*) 
(*11*) END DIREAD; 


PROCEDURE DIWRIT(A,V: LIST); 
(*Distributive polynomial write. A is a distributive
polynomial in r variables, r ge 0. V is a variable list
for A. A is written in the output stream. *)
VAR   AL, AS, E, EL, FL, ES, LL, RL, SL, TL, VL, VS: LIST; 
BEGIN
(*1*) (*rl=0 or a=0.*) 
      IF A = 0 THEN AWRITE(A); RETURN; END; 
      RL:=DIPNOV(A); 
      IF RL = 0 THEN ADWRIT(DIPLBC(A)); RETURN; END; 
(*2*) (*general case.*) AS:=A; FL:=0; LL:=DIPNBC(A); 
      IF LL > 1 THEN SWRITE("("); END; 
      REPEAT DIPMAD(AS, AL,E,AS); SWRITE(" "); SL:=ADSIGN(AL); 
             IF FL <> 0 THEN 
                IF SL > 0 THEN SWRITE("+"); END; 
                IF SL < 0 THEN SWRITE("-"); AL:=ADNEG(AL); END; 
                END;
             FL:=1; TL:=EVSIGN(E); 
             IF TL = 0 THEN ADWRIT(AL); 
                ELSE SL:=ADONE(AL); 
                IF SL <> 1 THEN ADWRIT(AL); END; 
                ES:=CINV(E); VS:=V; 
                REPEAT ADV(ES, EL,ES); ADV(VS, VL,VS); 
                       IF EL > 0 THEN SWRITE(" "); CLOUT(VL); 
                          IF EL > 1 THEN SWRITE("**"); 
                             AWRITE(EL); END; 
                          END; 
                       UNTIL ES = SIL; 
                END; 
             UNTIL AS = SIL; 
      SWRITE(" "); 
      IF LL > 1 THEN SWRITE(")"); END; 
(*5*) RETURN; END DIWRIT; 


END DIPADOM.
(* -EOF- *)