vdp2dip.red 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. module vdp2dip;
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %
  4. % interface for Virtual Distributive Polynomials(VDP)
  5. %
  6. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7. %
  8. % "Distributive representation" with respect to a given set of
  9. % variables(" vdpvars ")means for a polynomial, that the polynomial
  10. % is regarded as a sequence of monomials, each of which is a
  11. % product of a " coefficient " and of some powers of the variables.
  12. % This internal representation is very closely connected to the
  13. % standard external(printed)representation of a polynomial in
  14. % REDUCE if nothing is factored out. The monomials are logically
  15. % ordered by a term order mode based on the ordering which is
  16. % given bye the sequence " vdpvars ";with respect to this ordering
  17. % the representation of a polynomial is unique. The " highest " term
  18. % is the car one. Monomials are represented by their coefficient
  19. %(" vbc ")and by a vector of the exponents(" vev ")(in the order
  20. % corresponding to the vector vars). The distributive representation
  21. % is good for those algorithms,which base their decisions on the
  22. % complete ledading monomial: this representation guarantees a
  23. % fast and uniform access to the car monomial and to the reductum
  24. %(the cdr of the polynomial beginning with the cadr monomial).
  25. % The algorithms of the Groebner package are of this type. The
  26. % interface defines the distributive polynomials as abstract data
  27. % objects via their acess functions. These functions map the
  28. % distributive operations to an arbitrary real data structure
  29. %(" virtual "). The mapping of the access functions to an actual
  30. % data structure is restricted only by the demand,that the typical
  31. % " distributive operations " be efficient. Additionally to the
  32. % algebraic value a VDP object has a property list. So the algorithms
  33. % using the VDP interface can assign name - value - pairs to individual
  34. % polynomials. The interface is defined by a set of routines which
  35. % create and handle the distributive polynomials. In general the
  36. % first letters of the routine name classifies the data its works on:
  37. %
  38. % vdp... complete virtual polynomial objects
  39. % vbc... virtual base coefficients
  40. % vev... virtual exponent vectors
  41. %
  42. % 0. general control
  43. %
  44. % vdpinit(dv)initialises the vdp package for the variables
  45. % given in the list 'dv'. vdpinit modifies the
  46. % torder and returns the prvevious torder as its
  47. % result. 'vdpinit' sets the global variable
  48. % 'vdpvars!*'.
  49. %
  50. % 1. Conversion
  51. %
  52. % a2vdp Algebraic(prefix)to vdp.
  53. % f2vdp Standard form to vdp.
  54. % a2vbc Algebraic(prefix)to vbc.
  55. % vdp2a Vdp to algebraic(prefix).
  56. % vdp2f Vdp to standard form.
  57. % vbc2a Vbc to algebraic(prefix).
  58. %
  59. % 2. Composing/decomposing
  60. %
  61. % vdpfmon Make a vdp from a vbc and an vev.
  62. % vdpmoncomp Add a monomial(vbc and vev)to the front of a vdp.
  63. % vdpappendmon Add a monomial(vbc and vev)to the bottom of a vdp.
  64. % vdpmonadd Add a monomial(vbc and vev)to a vdp,not yet
  65. % knowing the place of the insertiona.
  66. % vdpappendvdp Concat two vdps.
  67. %
  68. % vdplbc Extract leading vbc.
  69. % vdpevlmon Extract leading vev.
  70. % vdpred Reductum of vdp.
  71. % vdplastmon Last monomial of polynomial.
  72. % vevnth Nth element from exponent vector.
  73. %
  74. % 3. Testing
  75. %
  76. % vdpzero? Test vdp = 0.
  77. % vdpredzero!? Test rductum of vdp = 0.
  78. % vdpone? Test vdp = 1.
  79. % vevzero? Test vev =(0 0 ... 0).
  80. % vbczero? Test vbc = 0.
  81. % vbcminus? Test vbc <= 0(not decidable for algebraic vbcs).
  82. % vbcplus? Test vbc >= 0(not decidable for algebraic vbcs).
  83. % vbcone!? Test vbc = 1.
  84. % vbcnumberp Test vbc is a numeric value.
  85. % vevdivides? Test if vev1 < vev2 elementwise.
  86. % vevlcompless? Test ordering vev1 < vev2.
  87. % vdpvevlcomp Calculate ordering vev1 / vev1 : -1, 0 or +1.
  88. % vdpequal Test vdp1 = vdp2.
  89. % vdpmember Member based on " vdpequal ".
  90. % vevequal Test vev1 = vev2.
  91. %
  92. % 4. Arithmetic
  93. %
  94. % 4.1 Vdp arithmetic
  95. %
  96. % vdpsum vdp + vdp
  97. % Special routines for monomials : see above(2.).
  98. % vdpdif vdp - vdp.
  99. % vdpprod vdp * vdp.
  100. % vdpvbcprod vbc * vdp.
  101. % vdpdivmon vdp /(vbc,vev) divisability presumed.
  102. % vdpcancelvev Substitute all multiples of monomial(1,vev)in vdp by 0.
  103. % vdlLcomb1 vdp1 *(vbc1,vev1)+ vdp2 *(vbc2,vev2).
  104. % vdpcontent Calculate gcd over all vbcs.
  105. %
  106. % 4.2 Vbc arithmetic
  107. %
  108. % vbcsum vbc1 + vbc2.
  109. % vbcdif vbc1 - vbc2.
  110. % vbcneg - vbc.
  111. % vbcprod vbc1 * vbc2.
  112. % vbcquot vbc1 / vbc2 Divisability assumed if domain = ring.
  113. % vbcinv 1 / vbc Only usable in field.
  114. % vbcgcd gcd(vbc1,vbc2) Only usable in Euclidean field.
  115. %
  116. % 4.2 Vev arithmetic
  117. %
  118. % vevsum vev1 + vev2 Elementwise.
  119. % vevdif vev1 - vev2 Elementwise.
  120. % vevtdeg Sum over all exponents.
  121. % vevzero Generate a zero vev.
  122. %
  123. % 5. Auxiliary
  124. %
  125. % vdpputprop Assign indicator - value - pair to vdp.
  126. % The property " number " is used for printing.
  127. % vdpgetprop Read value of indicator from vdp.
  128. % vdplsort Sort list of polynomials with respect to ordering.
  129. % vdplsortin Sort a vdp into a sorted list of vdps.
  130. % vdpprint Print a vdp together with its number.
  131. % vdpprin2t Print a vdp " naked ".
  132. % vdpprin3t Print a vdp with closing ";".
  133. % vdpcondense Replace exponent vectors by equal objects from
  134. % global list dipevlist!* in order to save memory.
  135. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  136. %
  137. % RECORD STRUCTURE
  138. %
  139. % A virtual polynomial here is a record(list) with the entries
  140. % ('vdp < vdpevlmon > < vdplbc > < form > < plist >)
  141. %
  142. % ´ vdp A type tag;
  143. % < vdpevlmon > the exponents of the variables in the
  144. % leading monomial;the positions correspond to
  145. % the positions in vdpvars!*. Trailing zeroes
  146. % can be omitted.
  147. %
  148. % < lcoeff > The " coefficient " of the leading monomial,which
  149. % in general is a standard form.
  150. %
  151. % < form > The complete polynomial,e.g. as REDUCE standard form.
  152. %
  153. % < plist > An asso list for the properties of the polynomial.
  154. %
  155. % The components should not be manipulated only via the interface
  156. % functions and macros,so that application programs remain
  157. % independent from the internal representation.
  158. % The only general assumption made on < form > is,that the zero
  159. % polynomial is represented as NIL. That is the case e. g. for both,
  160. % REDUCE standard forms and DIPOLYs.
  161. %
  162. % Conventions for the usage:
  163. % -------------------------
  164. %
  165. % vdpint has to be called prveviously to all vdp calls. The list of
  166. % vdp paraemters is passed to vdpinit. The value of vdpvars!*
  167. % and the current torder must remain unmodfied afterwards.
  168. % usual are simple id's,e.g.
  169. %
  170. % Modifications to vdpvars!* during calculations
  171. % ----------------------------------------------
  172. %
  173. % This mapping of vdp operations to standard forms offers the
  174. % ability to enlarge vdpvars during the calculation in order
  175. % to add new(intermediate)variables. Basis is the convention,
  176. % that exponent vectors logically have an arbitrary number
  177. % of trailing zeros. All routines processing exponent vectors
  178. % are able to handle varying length of exponent vectors.
  179. % A new call to vdpinit is necessary.
  180. %
  181. % During calculation vdpvars may be enlarged(new variables
  182. % suffixed)without needs to modify existing polynomials;only
  183. % korder has to be set to the new variable sequence.
  184. % modifications to the sequence in vdpvars requires a
  185. % new call to vdpinit and a reordering of exisiting
  186. % polynomials,e.g. by
  187. % vdpint newvdpvars;
  188. % f2vdp vdp2f p1;f2vdp vdp2f p2;.....
  189. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  190. %
  191. % DECLARATION SECTION
  192. %
  193. % This module must be present during code generation for modules
  194. % using the vdp - sf interface.
  195. global '(vdpprintmax groebmonfac);
  196. flag('(vdpprintmax),'share);
  197. % Basic internal constructor of vdp-record:
  198. smacro procedure makevdp(vbc,vev,form);
  199. {'vdp,vev,vbc,form,nil};
  200. % Basic selectors(conversions):
  201. smacro procedure vdppoly u;cadr cddr u;
  202. smacro procedure vdplbc u;caddr u;
  203. smacro procedure vdpevlmon u;cadr u;
  204. % Basic tests:
  205. smacro procedure vdpzero!? u;null u or null vdppoly u;
  206. smacro procedure vevzero!? u;
  207. null u or(car u=0 and vevzero!?1 cdr u);
  208. smacro procedure vdpone!? p;
  209. not vdpzero!? p and vevzero!? vdpevlmon p;
  210. % Manipulating of exponent vectors.
  211. smacro procedure vevdivides!?(vev1,vev2);vevmtest!?(vev2,vev1);
  212. smacro procedure vevzero();vevmaptozero1(vdpvars!*,nil);
  213. smacro procedure vdpnumber f;vdpgetprop(f,'number);
  214. % The code for checkpointing is factored out.
  215. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  216. %
  217. % Interface for DIPOLY polynomials as records(objects).
  218. %
  219. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  220. %
  221. flag('(vdpprintmax),'share);
  222. symbolic procedure dip2vdp u;
  223. % Is used when u can be empty.
  224. (if dipzero!? uu then makevdp(a2bc 0,nil,nil)
  225. else makevdp(diplbc uu,dipevlmon uu,uu))
  226. where uu=if !*groebsubs then dipsubs2 u else u;
  227. % Some simple mappings:
  228. smacro procedure makedipzero();nil;
  229. symbolic procedure vdpredzero!? u;dipzero!? dipmred vdppoly u;
  230. symbolic procedure vdplastmon u;
  231. % Return bc. ev of last monomial of u.
  232. begin u:=vdppoly u;
  233. if dipzero!? u then return nil;
  234. while not dipzero!? u and not dipzero!? dipmred u do u:=dipmred u;
  235. return diplbc u.dipevlmon u end;
  236. symbolic procedure vbczero!? u;bczero!? u;
  237. symbolic procedure vbcnumber u;
  238. if pairp u and numberp car u and 1=cdr u then cdr u else nil;
  239. symbolic procedure vbcfi u;bcfd u;
  240. symbolic procedure a2vbc u;a2bc u;
  241. symbolic procedure vbcquot(u,v);bcquot(u,v);
  242. symbolic procedure vbcneg u;bcneg u;
  243. symbolic procedure vbcabs u;if vbcminus!? u then bcneg u else u;
  244. symbolic procedure vbcone!? u;bcone!? u;
  245. symbolic procedure vbcprod(u,v);bcprod(u,v);
  246. % Initializing vdp - dip polynomial package.
  247. symbolic procedure vdpinit2 vars;
  248. begin scalar oldorder;vdpcleanup();
  249. oldorder:=kord!*;
  250. if null vars then rerror(dipoly,8,"vdpinit: vdpvars not set");
  251. vdpvars!*:=dipvars!*:=vars;torder2 vdpsortmode!*;
  252. return oldorder end;
  253. symbolic procedure vdpcleanup();dipevlist!*:={nil};
  254. symbolic procedure vdpred u;
  255. begin scalar r,s;r:=dipmred vdppoly u;
  256. if dipzero!? r then return makevdp(nil ./ nil,nil,makedipzero());
  257. r:=makevdp(diplbc r,dipevlmon r,r);
  258. if !*gsugar and(s:=vdpgetprop(u,'sugar))then gsetsugar(r,s);
  259. return r end;
  260. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  261. %
  262. % Coefficient handling;here we assume that coefficients are
  263. % standard quotients.
  264. %
  265. symbolic procedure vbcgcd(u,v);
  266. begin scalar x;
  267. if not vbcsize(u,-100)or not vbcsize(v,-100)
  268. then return '(1 . 1);
  269. x:=if denr u=1 and denr v=1 then
  270. if fixp numr u and fixp numr v then gcdn(numr u,numr v) ./ 1
  271. else gcdf!*(numr u,numr v)./ 1
  272. else 1 ./ 1;
  273. return x end;
  274. symbolic procedure vbcsize(u,n);
  275. if n #> -1 then nil
  276. else if atom u then n
  277. else begin n:=vbcsize(car u,n #+ 1);
  278. if null n then return nil;return vbcsize(cdr u,n)end;
  279. % Cofactors: compute(q,v)such that q*a=v*b.
  280. symbolic procedure vbc!-cofac(bc1,bc2);
  281. % Compute base coefficient cofactors.
  282. <<if vbcminus!? bc1 and vbcminus!? bc2 then gcd:=vbcneg gcd;
  283. vbcquot(bc2,gcd). vbcquot(bc1,gcd)>>
  284. where gcd=vbcgcd(bc1,bc2);
  285. symbolic procedure vev!-cofac(ev1,ev2);
  286. % Compute exponent vector cofactors.
  287. (vevdif(lcm,ev1).vevdif(lcm,ev2))
  288. where lcm=vevlcm(ev1,ev2);
  289. % The following functions must be redefinable.
  290. symbolic procedure vbcplus!? u;(numberp v and v > 0)where v=numr u;
  291. symbolic procedure bcplus!? u;(numberp v and v > 0)where v=numr u;
  292. symbolic procedure vbcminus!? u;(numberp v and v < 0)where v=numr u;
  293. symbolic procedure vbcinv u;bcinv u;
  294. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  295. %
  296. % Conversion between forms, vdps and prefix expressions.
  297. %
  298. % Prefix to vdp.
  299. symbolic procedure a2vdp u;
  300. if u=0 or null u then makevdp(nil./1,nil,makedipzero())
  301. else(makevdp(diplbc r,dipevlmon r,r)where r=a2dip u);
  302. % Vdp to prefix.
  303. symbolic procedure vdp2a u;dip2a vdppoly u;
  304. symbolic procedure vbc2a u;bc2a u;
  305. % Form to vdp.
  306. symbolic procedure f2vdp u;
  307. if u=0 or null u then makevdp(nil./1,nil,makedipzero())
  308. else(makevdp(diplbc r,dipevlmon r,r)where r=f2dip u);
  309. % Vdp to form.
  310. symbolic procedure vdp2f u;dip2f vdppoly u;
  311. % Vdp from monomial.
  312. symbolic procedure vdpfmon(coef,vev);
  313. begin scalar r;r:=makevdp(coef,vev,dipfmon(coef,vev));
  314. if !*gsugar then gsetsugar(r,vevtdeg vev);return r end;
  315. % Add a monomial to a vdp in front(new vev and coeff).
  316. symbolic procedure vdpmoncomp(coef,vev,vdp);
  317. if vdpzero!? vdp then vdpfmon(coef,vev)
  318. else if vbczero!? coef then vdp
  319. else makevdp(coef,vev,dipmoncomp(coef,vev,vdppoly vdp));
  320. % Add a monomial to the end of a vdp(vev remains unchanged).
  321. symbolic procedure vdpappendmon(vdp,coef,vev);
  322. if vdpzero!? vdp then vdpfmon(coef,vev)
  323. else if vbczero!? coef then vdp
  324. else makevdp(vdplbc vdp,vdpevlmon vdp,dipsum(vdppoly vdp,dipfmon(coef,vev)));
  325. % Add monomial to vdp;place of new monomial still unknown.
  326. symbolic procedure vdpmonadd(coef,vev,vdp);
  327. if vdpzero!? vdp then vdpfmon(coef,vev)else
  328. (if c=1 then vdpmoncomp(coef,vev,vdp)else
  329. if c=-1 then makevdp(vdplbc vdp,vdpevlmon vdp,
  330. dipsum(vdppoly vdp,dipfmon(coef,vev)))
  331. else vdpsum(vdp,vdpfmon(coef,vev))
  332. )where c=vevcomp(vev,vdpevlmon vdp);
  333. symbolic procedure vdpzero();a2vdp 0;
  334. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  335. %
  336. % Comparing of exponent vectors:
  337. %
  338. symbolic procedure vdpvevlcomp(p1,p2);dipevlcomp(vdppoly p1,vdppoly p2);
  339. symbolic procedure vevilcompless!?(e1,e2);1=evilcomp(e2,e1);
  340. symbolic procedure vevilcomp(e1,e2);evilcomp(e1,e2);
  341. symbolic procedure vevcompless!?(e1,e2);1=evcomp(e2,e1);
  342. symbolic procedure vevcomp(e1,e2);evcomp(e1,e2);
  343. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  344. %
  345. % Routines traversing the " coefficients ";
  346. %
  347. % CONTENT of a vdp:
  348. % The content is the gcd of all coefficients.
  349. symbolic procedure vdpcontent d;
  350. if vdpzero!? d then a2bc 0 else
  351. <<d:=vdppoly d;dipnumcontent(dipmred d,diplbc d)>>;
  352. symbolic procedure vdpcontent1(d,c);dipnumcontent(vdppoly d,c);
  353. symbolic procedure dipnumcontent(d,c);
  354. if bcone!? c or dipzero!? d then c
  355. else dipnumcontent(dipmred d,vbcgcd(c,diplbc d));
  356. symbolic procedure dipcontenti p;
  357. % The content is a pair of the lcm of the coefficients and the
  358. % exponent list of the common monomial factor.
  359. if dipzero!? p then 1 else
  360. (if dipzero!? rp then diplbc p.
  361. (if !*groebrm then dipevlmon p else nil)
  362. else dipcontenti1(diplbc p, if !*groebrm then dipevlmon p else nil,rp))
  363. where rp=dipmred p;
  364. symbolic procedure dipcontenti1(n,ev,p1);
  365. if dipzero!? p1 then n.ev
  366. else begin scalar nn;nn:=vbcgcd(n,diplbc p1);
  367. if ev then ev:=dipcontevmin(dipevlmon p1,ev);
  368. if bcone!? nn and null ev then return nn.nil
  369. else return dipcontenti1(nn,ev,dipmred p1)end;
  370. % CONTENT and MONFAC(if groebrm is on).
  371. symbolic procedure vdpcontenti d;
  372. vdpcontent d.if !*groebrm then vdpmonfac d else nil;
  373. symbolic procedure vdpmonfac d;dipmonfac vdppoly d;
  374. symbolic procedure dipmonfac p;
  375. % Exponent list of the common monomial factor.
  376. if dipzero!? p or not !*groebrm then evzero()
  377. else(if dipzero!? rp then dipevlmon p
  378. else dipmonfac1(dipevlmon p,rp))where rp=dipmred p;
  379. symbolic procedure dipmonfac1(ev,p1);
  380. if dipzero!? p1 or evzero!? ev then ev
  381. else dipmonfac1(dipcontevmin(ev,dipevlmon p1),dipmred p1);
  382. % vdpcoeffcientsfromdomain?
  383. symbolic procedure vdpcoeffcientsfromdomain!? w;
  384. dipcoeffcientsfromdomain!? vdppoly w;
  385. symbolic procedure dipcoeffcientsfromdomain!? w;
  386. if dipzero!? w then t else
  387. (if bcdomain!? v then dipcoeffcientsfromdomain!? dipmred w
  388. else nil)where v=diplbc w;
  389. symbolic procedure vdplength f;diplength vdppoly f;
  390. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  391. %
  392. % Polynomial operations:
  393. % coefficient normalization and reduction of monomial factors.
  394. %
  395. symbolic procedure vdpequal(p1,p2);
  396. p1 eq p2
  397. or(n1 and n1=n2 % number comparison is faster most times
  398. or dipequal(vdppoly p1,vdppoly p2)
  399. where n1=vdpgetprop(p1,'number),n2=vdpgetprop(p2,'number));
  400. symbolic procedure dipequal(p1,p2);
  401. if dipzero!? p1 then dipzero!? p2 else if dipzero!? p2 then nil
  402. else diplbc p1=diplbc p2 and evequal(dipevlmon p1,dipevlmon p2)
  403. and dipequal(dipmred p1,dipmred p2);
  404. symbolic procedure evequal(e1,e2);
  405. % Test equality with variable length exponent vectors.
  406. if null e1 and null e2 then t
  407. else if null e1 then evequal('(0),e2)
  408. else if null e2 then evequal(e1,'(0))
  409. else 0=(car e1 #- car e2)and evequal(cdr e1,cdr e2);
  410. symbolic procedure vdplcm p;diplcm vdppoly p;
  411. symbolic procedure vdprectoint(p,q);dip2vdp diprectoint(vdppoly p,q);
  412. symbolic procedure vdpsimpcont(p);
  413. begin scalar r,q;q:=vdppoly p;
  414. if dipzero!? q then return p;r:=dipsimpcont q;
  415. p:=dip2vdp cdr r;% the polynomial
  416. r:=car r; % the monomial factor if any
  417. if not evzero!? r and(dipmred q or evtdeg r>1)
  418. then vdpputprop(p,'monfac,r);return p end;
  419. symbolic procedure dipsimpcont(p);
  420. if !*vdpinteger or not !*groebdivide then dipsimpconti p else dipsimpcontr p;
  421. % Routines for integer coefficient case:
  422. % calculation of contents and dividing all coefficients by it.
  423. symbolic procedure dipsimpconti p;
  424. % Calculate the contents of p and divide all coefficients by it.
  425. begin scalar co,lco,res,num;
  426. if dipzero!? p then return nil.p;co:=bcfd 1;
  427. co:=if !*groebdivide then dipcontenti p
  428. else if !*groebrm then co.dipmonfac p else co.nil;
  429. num:=car co;
  430. if not bcplus!? num then num:=bcneg num;
  431. if not bcplus!? diplbc p then num:=bcneg num;
  432. if bcone!? num and cdr co=nil then return nil.p;
  433. lco:=cdr co;
  434. if groebmonfac neq 0 then lco:=dipcontlowerev cdr co;
  435. res:=p;
  436. if not(bcone!? num and lco=nil)then res:=dipreduceconti(p,num,lco);
  437. if null cdr co then return nil.res;
  438. lco:=evdif(cdr co,lco);
  439. return(if lco and not evzero!? evdif(dipevlmon res,lco)
  440. then lco else nil).res end;
  441. symbolic procedure vdpreduceconti(p,co,vev);
  442. % Divide polynomial p by monomial from co and vev.
  443. vdpdivmon(p,co,vev);
  444. % Divide all coefficients of p by cont.
  445. symbolic procedure dipreduceconti(p,co,ev);
  446. if dipzero!? p then makedipzero()
  447. else dipmoncomp(bcquot(diplbc p,co),
  448. if ev then evdif(dipevlmon p,ev)
  449. else dipevlmon p,dipreduceconti(dipmred p,co,ev));
  450. % Routines for rational coefficient case:
  451. % calculation of contents and dividing all coefficients by it
  452. symbolic procedure dipsimpcontr p;
  453. % Calculate the contents of p and divide all coefficients by it.
  454. begin scalar co,lco,res;
  455. if dipzero!? p then return nil.p;
  456. co:=dipcontentr p;
  457. if bcone!? diplbc p and co=nil then return nil.p;
  458. lco:=dipcontlowerev co;res:=p;
  459. if not(bcone!? diplbc p and lco=nil)then
  460. res:=dipreducecontr(p,bcinv diplbc p,lco);
  461. return(if co then evdif(co,lco)else nil).res end;
  462. symbolic procedure dipcontentr p;
  463. % The content is the exponent list of the common monomial factor.
  464. (if dipzero!? rp then (if !*groebrm then dipevlmon p else nil)
  465. else dipcontentr1(if !*groebrm then dipevlmon p else nil,rp))
  466. where rp=dipmred p;
  467. symbolic procedure dipcontentr1(ev,p1);
  468. if dipzero!? p1 then ev
  469. else begin
  470. if ev then ev:=dipcontevmin(dipevlmon p1,ev);
  471. if null ev then return nil
  472. else return dipcontentr1(ev,dipmred p1)end;
  473. % Divide all coefficients of p by cont.
  474. symbolic procedure dipreducecontr(p,co,ev);
  475. if dipzero!? p then makedipzero()
  476. else dipmoncomp(bcprod(diplbc p,co),if ev then evdif(dipevlmon p,ev)
  477. else dipevlmon p,dipreducecontr(dipmred p,co,ev));
  478. symbolic procedure dipcontevmin(e1,e2);
  479. % Calculates the minimum of two exponents;if one is shorter, trailing
  480. % zeroes are assumed.
  481. % e1 is an exponent vector.e2 is a list of exponents
  482. begin scalar res;
  483. while e1 and e2 do
  484. <<res:=(if ilessp(car e1,car e2)then car e1 else car e2).res;
  485. e1:=cdr e1;e2:=cdr e2>>;
  486. while res and 0=car res do res:=cdr res;
  487. return reversip res end;
  488. symbolic procedure dipcontlowerev e1;
  489. % Subtract a 1 from those elements of an exponent vector which
  490. % are greater than 1.
  491. % e1 is a list of exponents,the result is an exponent vector.
  492. begin scalar res;
  493. while e1 do
  494. <<res:=(if igreaterp(car e1,0)then car e1 - 1 else 0).res;e1:=cdr e1>>;
  495. while res and 0=car res do res:=cdr res;
  496. if res and !*trgroebs then
  497. <<prin2 " ***** exponent reduction : ";prin2t reverse res>>;
  498. return reversip res end;
  499. symbolic procedure dipappendmon(dip,bc,ev);append(dip,dipfmon(bc,ev));
  500. smacro procedure dipnconcmon(dip,bc,ev);nconc(dip,dipfmon(bc,ev));
  501. smacro procedure dipappenddip(dip1,dip2);append(dip1,dip2);
  502. smacro procedure dipnconcdip(dip1,dip2);nconc(dip1,dip2);
  503. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  504. %
  505. % Basic polynomial arithmetic:
  506. %
  507. symbolic procedure vdpsum(d1,d2);
  508. begin scalar r;
  509. r:=dip2vdp dipsum(vdppoly d1,vdppoly d2);
  510. if !*gsugar then gsetsugar(r,max(gsugar d1,gsugar d2));return r end;
  511. symbolic procedure vdpdif(d1,d2);
  512. begin scalar r;
  513. r:=dip2vdp dipdif(vdppoly d1,vdppoly d2);
  514. if !*gsugar then gsetsugar(r,max(gsugar d1,gsugar d2));return r end;
  515. symbolic procedure vdpprod(d1,d2);
  516. begin scalar r;
  517. r:= dip2vdp dipprod(vdppoly d1,vdppoly d2);
  518. if !*gsugar then gsetsugar(r,gsugar d1 + gsugar d2);return r end;
  519. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  520. %
  521. % Linear combination: the Buchberger workhorse.
  522. %
  523. % LCOMB1: calculate mon1 * vdp1 + mon2 * vdp2.
  524. symbolic procedure vdpilcomb1(d1,vbc1,vev1,d2,vbc2,vev2);
  525. begin scalar r;
  526. r:=
  527. dip2vdp dipilcomb1(vdppoly d1,vbc1,vev1,vdppoly d2,vbc2,vev2);
  528. if !*gsugar then gsetsugar(r,max(gsugar d1 + vevtdeg vev1,
  529. gsugar d2 + vevtdeg vev2));return r end;
  530. symbolic procedure dipilcomb1(p1,bc1,ev1,p2,bc2,ev2);
  531. % Same as dipILcomb, exponent vectors multiplied in already.
  532. begin scalar gcd;
  533. gcd:=!*gcd;
  534. return
  535. begin scalar ep1,ep2,sl,res,sum,z1,z2,p1new,p2new,
  536. lptr,bptr,c,!*gcd;
  537. !*gcd:=if vbcsize(bc1,-100)and vbcsize(bc2,-100)then gcd;
  538. z1:=not evzero!? ev1;z2:=not evzero!? ev2;
  539. p1new:=p2new:=t;
  540. lptr:=bptr:=res:=makedipzero();
  541. loop:
  542. if p1new then
  543. <<if dipzero!? p1 then return if dipzero!? p2 then res else
  544. dipnconcdip(res,dipprod(p2,dipfmon(bc2,ev2)));
  545. ep1:=dipevlmon p1;
  546. if z1 then ep1:=evsum(ep1,ev1);
  547. p1new:=nil>>;
  548. if p2new then
  549. <<if dipzero!? p2 then
  550. return dipnconcdip(res,dipprod(p1,dipfmon(bc1,ev1)));
  551. ep2:=dipevlmon p2;
  552. if z2 then ep2:=evsum(ep2,ev2);
  553. p2new:=nil>>;
  554. sl:=evcomp(ep1,ep2);
  555. if sl=1 then
  556. <<if !*gcd and not vbcsize(diplbc p1,-100)then !*gcd:=nil;
  557. c:=bcprod(diplbc p1,bc1);
  558. if not bczero!? c then
  559. <<lptr:=dipnconcmon(bptr,c,ep1);
  560. bptr:=dipmred lptr>>;
  561. p1:=dipmred p1;p1new:=t;
  562. >> else if sl=-1 then
  563. <<if !*gcd and not vbcsize(diplbc p2,-100)then !*gcd:=nil;
  564. c:=bcprod(diplbc p2,bc2);
  565. if not bczero!? c then
  566. <<lptr:=dipnconcmon(bptr,c,ep2);bptr:=dipmred lptr>>;
  567. p2:=dipmred p2;p2new:=t>>
  568. else
  569. <<if !*gcd and(not vbcsize(diplbc p1,-100)or
  570. not vbcsize(diplbc p2,-100)) then !*gcd:=nil;
  571. sum:=bcsum(bcprod(diplbc p1,bc1),
  572. bcprod(diplbc p2,bc2));
  573. if not bczero!? sum then
  574. <<lptr:=dipnconcmon(bptr,sum,ep1);
  575. bptr:=dipmred lptr>>;
  576. p1:=dipmred p1;p2:=dipmred p2;p1new:=p2new:=t>>;
  577. if dipzero!? res then <<res:=bptr:=lptr>>;% initial
  578. goto loop end;end;
  579. symbolic procedure vdpvbcprod(p,a);
  580. (if !*gsugar then gsetsugar(q,gsugar p)else q)
  581. where q=dip2vdp dipbcprod(vdppoly p,a);
  582. symbolic procedure vdpdivmon(p,c,vev);
  583. (if !*gsugar then gsetsugar(q,gsugar p)else q)
  584. where q=dip2vdp dipdivmon(vdppoly p,c,vev);
  585. symbolic procedure dipdivmon(p,bc,ev);
  586. % Divides a polynomial by a monomial;
  587. % we are sure that the monomial ev is a factor of p.
  588. if dipzero!? p then makedipzero()
  589. else dipmoncomp(bcquot(diplbc p,bc),evdif(dipevlmon p,ev),
  590. dipdivmon(dipmred p,bc,ev));
  591. symbolic procedure vdpcancelmvev(p,vev);
  592. (if !*gsugar then gsetsugar(q,gsugar p)else q)
  593. where q=dip2vdp dipcancelmev(vdppoly p,vev);
  594. symbolic procedure dipcancelmev(f,ev);
  595. % Cancels all monomials in f which are multiples of ev
  596. dipcancelmev1(f,ev,makedipzero());
  597. symbolic procedure dipcancelmev1(f,ev,res);
  598. if dipzero!? f then res
  599. else if evmtest!?(dipevlmon f,ev)then dipcancelmev1(dipmred f,ev,res)
  600. else dipcancelmev1(dipmred f,ev,
  601. % dipappendmon(res,diplbc f,dipevlmon f));
  602. dipnconcmon(res,diplbc f,dipevlmon f));
  603. % Some prehistoric routines needed in resultant operation
  604. symbolic procedure vevsum0(n,p);
  605. % Exponent vector sum version 0 . n is the length of vdpvars!*.
  606. % p is a distributive polynomial.
  607. if vdpzero!? p then vevzero1 n else vevsum(vdpevlmon p,vevsum0(n,vdpred p));
  608. symbolic procedure vevzero1 n;
  609. % Returns the exponent vector power representation
  610. % of length n for a zero power.
  611. begin scalar x;for i:=1:n do x:=0 . x;return x end;
  612. symbolic procedure vdpresimp u;
  613. % if domain changes,the coefficients have to be resimped
  614. dip2vdp dipresimp vdppoly u;
  615. symbolic procedure dipresimp u;
  616. if null u then nil else
  617. (for each x in u collect
  618. <<toggle:=not toggle;
  619. if toggle then simp prepsq x else x>>)where toggle = t;
  620. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  621. %
  622. % printing of polynomials
  623. %
  624. symbolic procedure vdpprin2t u;<<vdpprint1(u,nil,9999);terpri()>>;
  625. symbolic procedure vdpprin3t u;<<vdpprint1(u,nil,9999);prin2t ";">>;
  626. symbolic procedure vdpprint u;<<vdpprin2 u;terpri()>>;
  627. symbolic procedure vdpprin2 u;
  628. <<(if x then <<prin2 " P(";prin2 x;
  629. if s then <<prin2 " / ";prin2 s>>;prin2 "): ">>)
  630. where x=vdpgetprop(u,'number),s= vdpgetprop(u,'sugar);
  631. vdpprint1(u,nil,vdpprintmax)>>;
  632. symbolic procedure vdpprint1(u,v,max);vdpprint1x(vdppoly u,v,max);
  633. symbolic procedure vdpprint1x(u,v,max);
  634. % Prints a distributive polynomial in infix form.
  635. % U is a distributive form. V is a flag which is true if a term
  636. % has preceded current form
  637. % max limits the number of terms to be printed
  638. if dipzero!? u then if null v then dipprin2 0 else nil
  639. else if max=0 then % maximum of terms reached
  640. <<terpri();prin2 " ### etc(";
  641. prin2 diplength u;prin2 " terms)### ";terpri()>>
  642. else begin scalar bool,w;
  643. w:=diplbc u;
  644. if bcminus!? w then<<bool:=t;w:=bcneg w>>;
  645. if bool then dipprin2 " - " else if v then dipprin2 " + ";
  646. (if not bcone!? w or evzero!? x then<<bcprin w;dipevlpri(x,t)>>
  647. else dipevlpri(x,nil))
  648. where x=dipevlmon u;
  649. vdpprint1x(dipmred u,t,max - 1)end;
  650. symbolic procedure dipprin2 u;<<if posn()>69 then terprit 2;prin2 u>>;
  651. symbolic procedure vdpsave u;u;
  652. % switching between term order modes
  653. symbolic procedure torder2 u;dipsortingmode u;
  654. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  655. %
  656. % additional conversion utilities
  657. % conversion dip to standard form / standard quotient
  658. symbolic procedure dip2f u;
  659. (if denr v neq 1 then
  660. <<print u;
  661. rerror(dipoly,9,
  662. " Distrib . poly . with rat coeff cannot be converted ")>>
  663. else numr v) where v=dip2sq u;
  664. symbolic procedure dip2sq u;
  665. % Convert a dip into a standard quotient.
  666. if dipzero!? u then nil ./ 1
  667. else addsq(diplmon2sq(diplbc u,dipevlmon u), dip2sq dipmred u);
  668. symbolic procedure diplmon2sq(bc,ev);
  669. % Convert a monomial into a standard quotient.
  670. multsq(bc,dipev2f(ev,dipvars!*)./ 1);
  671. symbolic procedure dipev2f(ev,vars);
  672. if null ev then 1
  673. else if car ev=0 then dipev2f(cdr ev,cdr vars)
  674. else multf(car vars .** car ev .* 1 .+ nil,dipev2f(cdr ev,cdr vars));
  675. % evaluate SUBS2 for the coefficients of a dip
  676. symbolic procedure dipsubs2 u;
  677. begin scalar v,secondvalue!*;
  678. secondvalue!*:=1 ./ 1;v:=dipsubs21 u;
  679. return diprectoint(v,secondvalue!*)end;
  680. symbolic procedure dipsubs21 u;
  681. if dipzero!? u then u else
  682. begin scalar c;c:=groebsubs2 diplbc u;
  683. if null numr c then return dipsubs21 dipmred u;
  684. if not(denr c=1)then secondvalue!*:=bclcmd(c,secondvalue!*);
  685. return dipmoncomp(c,dipevlmon u,dipsubs21 dipmred u)end;
  686. % conversion standard form to dip
  687. symbolic procedure f2dip u;f2dip1(u,evzero(),bcfd 1);
  688. symbolic procedure f2dip1(u,ev,bc);
  689. % f to dip conversion : scan the standard form. ev
  690. % and bc are the exponent and coefficient parts collected
  691. % so far from higher parts.
  692. if null u then nil
  693. else if domainp u then dipfmon(bcprod(bc,bcfd u), ev)
  694. else dipsum(f2dip2(mvar u,ldeg u,lc u,ev,bc), f2dip1(red u,ev,bc));
  695. symbolic procedure f2dip2(var,dg,c,ev,bc);
  696. % f to dip conversion:
  697. % multiply leading power either into exponent vector
  698. % or into the base coefficient.
  699. <<if ev1 then ev:=ev1
  700. else bc:=multsq(bc,var .** dg .* 1 .+ nil ./ 1);
  701. f2dip1(c,ev,bc)>>
  702. where ev1=if memq(var,dipvars!*)then
  703. evinsert(ev,var,dg,dipvars!*)else nil;
  704. symbolic procedure evinsert(ev,v,dg,vars);
  705. % f to dip conversion:
  706. % Insert the "dg" into the ev in the place of variable v.
  707. if null ev or null vars then nil
  708. else if car vars eq v then dg.cdr ev
  709. else car ev.evinsert(cdr ev,v,dg,cdr vars);
  710. symbolic procedure vdpcondense f;dipcondense car cdddr f;
  711. endmodule;;end;