xpowers.red 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. module xpowers;
  2. % Powers, including div relation and lcm.
  3. % Author: David Hartley
  4. Comment. Factor ordering within a product is decided using the current
  5. kernel order. Term ordering is decided by ordering of the valuation of
  6. terms in the commutative monoid. The valuation of a poly is simply the
  7. list of factors in the leading power. Monoid ordering can be either
  8. lex or gradlex. The div, // and lcm operations are performed within
  9. the monoid.
  10. Monoid elements are given by the type mon:
  11. mon ::= list of kernel | {1}
  12. endcomment;
  13. fluid '(xdegreelist!* xvarlist!*);
  14. rlistat '(xorder);
  15. symbolic procedure xorder u;
  16. if u = {nil} then compress pnth(explode get('wedge,'xorder),6)
  17. else if (idp(u := car u) or idp(u := reval u)) and
  18. getd mkid('xord_,u) then
  19. <<put('wedge,'xorder,mkid('xord_,u)); u>>
  20. else typerr(u,"xorder");
  21. put('wedge,'xorder,'xord_deglex);
  22. symbolic procedure xval f;
  23. % f:pf -> xval:mon
  24. wedgefax lpow f;
  25. symbolic procedure pfordp(f,g);
  26. % f,g:pf -> pfordp:bool
  27. % partial ordering based on term ordering
  28. % returns t if f > g, otherwise nil (even when no ordering defined)
  29. if null f then nil
  30. else if null g then lpow f neq 1 % == termordp(lpow f,1)
  31. else if not(lpow f eq lpow g) then termordp(lpow f,lpow g)
  32. else pfordp(red f,red g);
  33. symbolic procedure termordp(u,v);
  34. % u,v:lpow pf -> termordp:bool
  35. % returns t if u > v
  36. monordp(wedgefax u,wedgefax v);
  37. symbolic procedure monordp(u,v);
  38. % u,v:mon -> monordp:bool
  39. % returns t if u > v
  40. apply2(get('wedge,'xorder),u,v);
  41. symbolic procedure factorordp(u,v);
  42. % u,v:kernel -> factorordp:bool
  43. % same as worder, but with strict inequality
  44. % returns t if u > v
  45. if u eq v then nil
  46. %%? else if xvarlist!* then v memq (u memq xvarlist!*)
  47. else worderp(u,v);
  48. symbolic procedure xord_lex(u,v);
  49. % u,v:mon -> xord_lex:bool
  50. if null u or car u = 1 then nil
  51. else if null v or car v = 1 then t
  52. else if car u eq car v then xord_lex(cdr u,cdr v)
  53. else factorordp(car u,car v);
  54. symbolic procedure xord_gradlex(u,v);
  55. % u,v:mon -> xord_gradlex:bool
  56. if car u = 1 then nil
  57. else if car v = 1 then t
  58. else if length u = length v then xord_lex(u,v)
  59. else length u > length v;
  60. symbolic procedure xord_deglex(u,v);
  61. % u,v:mon -> xord_deglex:bool
  62. if car u = 1 then nil
  63. else if car v = 1 then t
  64. else (if du = dv then xord_lex(u,v)
  65. else du > dv) where du = xdegreemon u,
  66. dv = xdegreemon v;
  67. symbolic procedure xdegreemon u;
  68. % u:mon -> xdegreemon:int
  69. % special degree routine for faster deglex ordering
  70. if null xdegreelist!* then xdegree mknwedge u
  71. else foreach k in u sum cdr atsoc(k,xdegreelist!*);
  72. symbolic procedure xord_deggradlex(u,v);
  73. % u,v:mon -> xord_deggradlex:bool
  74. if car u = 1 then nil
  75. else if car v = 1 then t
  76. else (if du = dv then xord_gradlex(u,v)
  77. else du > dv) where du = xdegree mknwedge u,
  78. dv = xdegree mknwedge v;
  79. symbolic procedure xlcm(r,s);
  80. % r,s:mon -> xlcm:mon
  81. % lowest common multiple
  82. if null r or car r = 1 then s
  83. else if null s or car s = 1 then r
  84. else if car r eq car s then car r . xlcm(cdr r,cdr s)
  85. else if factorordp(car r,car s) then car r . xlcm(cdr r,s)
  86. else car s . xlcm(r,cdr s);
  87. symbolic procedure xdiv(r,s);
  88. % r,s:mon -> xdiv:nil|mon
  89. % returns s//r if r div s, else nil
  90. if r = {1} then s
  91. else if sublistp(r,s) then
  92. if s := listdiff(s,r) then s else {1};
  93. symbolic procedure listunion(x,y);
  94. % x,y:list -> listunion:list
  95. % A version of union which takes multiplicities into account.
  96. % If item z occurs m(x) times in x and m(y) times in y, then it
  97. % occurs max(m(x),m(y)) times in listunion(x,y). Ordering is x,(y\x).
  98. % NB. union({z,z},{z}) gives {z}, while union({z},{z,z}) gives {z,z}.
  99. if null x then y
  100. else if null y then x
  101. else car x . listunion(cdr x,
  102. if car x member y then delete(car x,y) else y);
  103. symbolic procedure sublistp(x,y);
  104. % x,y:list -> sublistp:bool
  105. null x or car x member y and sublistp(cdr x,delete(car x,y));
  106. symbolic procedure listdiff(x,y);
  107. % x,y:list -> listdiff:list
  108. if null y then x
  109. else if null x then nil
  110. else listdiff(delete(car y,x),cdr y);
  111. endmodule;
  112. end;