grinterf.red 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. module grinterf; % Interface of Groebner package to REDUCE.
  2. % Entry points to the main module and general
  3. % interface support.
  4. fluid '(!*factor !*complex !*exp asymplis!* current!-modulus powlis!*);
  5. global '(!*match largest!-small!-modulus);
  6. fluid '( % switches from the user interface
  7. !*groebopt !*groebfac !*groebres !*trgroeb !*trgroebs !*groebrm
  8. !*trgroeb1 !*trgroebr !*groebprereduce groebrestriction!*
  9. !*fullReduction !*groebstat !*groebprot !*gltbasis
  10. !*groebsubs
  11. !*grmod!* % indicating modular coefficients
  12. !*vdpinteger !*vdpmodular % indicating type of algorithm
  13. vdpSortMode!* % term ordering mode
  14. secondvalue!* thirdvalue!* % auxiliary: multiple return values
  15. fourthvalue!*
  16. factortime!* % computing time spent in factoring
  17. factorlvevel!* % bookkeeping of factor tree
  18. pairsdone!* % list of pairs already calculated
  19. probcount!* % counting subproblems
  20. vbcCurrentMode!* % current domain for base coeffs.
  21. vbcModule!* % for modular calculation:
  22. % current prime
  23. bczerodivl!* % coefficient zero divisors (list of
  24. % standard forms)
  25. gmodule % external module basis
  26. gmodule!* % internal module basis
  27. global!-dipvars!* % predefined variable list
  28. !*gsugar % enable sugar strategy
  29. );
  30. global '(groebrestriction % interface: name of function
  31. groebresmax % maximum number of internal results
  32. gvarslast % output: variable list
  33. groebprotfile
  34. gltb
  35. glterms % list for lterms collection
  36. );
  37. flag ('(groebrestriction groebresmax gvarslast groebprotfile
  38. gltb glterms gmodule),'share);
  39. switch groebopt,groebres,trgroeb,trgroebs,trgroeb1,
  40. trgroebr,groebstat,gltbasis,gsugar;
  41. % variables for counting and numbering
  42. fluid '(hcount!* pcount!* mcount!* fcount!* bcount!* b4count!*
  43. basecount!* hzerocount!*);
  44. % control of the polynomial arithmetic actually loaded
  45. fluid '(currentVdpModule!*);
  46. vdpsortmode!* := 'LEX; % initial mode
  47. gltb := '(list); % initially empty
  48. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  49. %
  50. % interface functions
  51. symbolic procedure groebnereval u;
  52. % non factorizing Groebner calculation
  53. begin integer n; scalar !*groebfac,!*groebrm,!*factor,
  54. !*exp; !*exp := t;
  55. n := length u;
  56. if n=1 then return cadr groebner1(reval car u,nil,nil)
  57. else if n neq 2
  58. then rerror(groebner,1,
  59. "GROEBNER called with wrong number of arguments");
  60. u:= groebner1(reval car u,reval cadr u,nil);
  61. if !*gltbasis then gltb := cadr gltb;
  62. return cadr u;
  63. end;
  64. put('groebner,'psopfn,'groebnereval);
  65. symbolic procedure groebnerFeval u;
  66. % non factorizing Groebner calculation
  67. begin integer n; scalar !*groebfac,!*groebrm,!*factor,
  68. !*exp,!*ezgcd,s,r,q; !*exp := t;
  69. if null getd 'groebFactorize then load!-package 'GROEBFAC;
  70. !*groebrm := !*groebfac := T;
  71. groebrestriction!* := reval groebrestriction;
  72. if null dmode!* then !*ezgcd:=t;
  73. n := length u;
  74. r:= if n=1 then groebner1(reval car u,nil,nil) else
  75. if n=2 then groebner1(reval car u,reval cadr u,nil) else
  76. if n neq 3
  77. then rerror(groebner,2,
  78. "GROEBNER called with wrong number of arguments")
  79. else groebner1(reval car u,reval cadr u,reval caddr u);
  80. q := r;
  81. % remove duplicates.
  82. while q do <<s := car q; q := cdr q;
  83. if member(s,q) then r := delete(s,r)>>;
  84. return r;
  85. end;
  86. put('groebnerF,'psopfn,'groebnerFeval);
  87. symbolic procedure idquotienteval u;
  88. begin integer n; scalar !*factor,!*exp; !*exp := t;
  89. n := length u;
  90. if n=2 then return groebidq(reval car u,reval cadr u,nil)
  91. else if n neq 3
  92. then rerror(groebner,3,
  93. "IDQUOTIENT called with wrong number of arguments")
  94. else return groebidq(reval car u,reval cadr u,reval caddr u)
  95. end;
  96. put('IDEALQUOTIENT,'psopfn,'idquotienteval);
  97. smacro procedure vdpNumber f;
  98. vdpGetProp(f,'NUMBER) ;
  99. symbolic procedure groebner1(u,v,r);
  100. % Buchberger algorithm system driver. u is a list of expressions
  101. % and v a list of variables or NIL in which case the variables in u
  102. % are used.
  103. begin scalar vars,w,np,oldorder,!*grmod!*;
  104. integer pcount!*;
  105. w := for each j in groerevlist u
  106. collect if eqexpr j then !*eqn2a j else j;
  107. if null w then rerror(groebner,4,"Empty list in Groebner");
  108. vars := groebnervars(w,v);
  109. if r then r := groerevlist r;
  110. groedomainmode();
  111. if vars then goto notempty;
  112. u:=0; for each p in w do if p neq 0 then u:=1;
  113. return {'list,{'list,u}};
  114. notempty:
  115. if dmode!* eq '!:mod!: and null setdiff(gvarlis w,vars)
  116. and current!-modulus < largest!-small!-modulus
  117. then !*grmod!* := t;
  118. oldorder := vdpinit vars;
  119. % cancel common denominators
  120. w := for each j in w collect reorder numr simp j;
  121. % optimize variable sequence if desired.
  122. if !*groebopt and vdpsortmode!* memq '(lex gradlex revgradlex)
  123. then << w:=vdpvordopt (w,vars); vars := cdr w;
  124. w := car w; vdpinit vars>>;
  125. w := for each j in w collect f2vdp j;
  126. if not !*vdpInteger then
  127. <<np := t;
  128. for each p in w do
  129. np := if np then vdpCoeffcientsFromDomain!? p else nil;
  130. if not np then <<!*vdpModular:= nil; !*vdpinteger := T>>;
  131. >>;
  132. if !*groebprot then
  133. <<groebprotfile := list 'LIST>>;
  134. if r then r := for each p in r collect
  135. vdpsimpcont f2vdp numr simp p;
  136. w := groebner2(w,r);
  137. if cdr w then % Remove redundant partial bases.
  138. begin scalar !*gsugar;
  139. for each b in w do
  140. for each c in w do
  141. if b and b neq c then
  142. <<v:=t; for each p in c do
  143. v:=v and vdpzero!? groebNormalForm(p,b,'list);
  144. if v then <<w:=delete(b,w); b:=nil>>;
  145. >>;
  146. end;
  147. if !*gltbasis then
  148. gltb :=
  149. 'list . for each base in w collect
  150. 'list . for each j in base collect
  151. vdp2a vdpfmon(a2vbc 1,vdpevlmon j);
  152. w := 'list . for each base in w collect
  153. 'list . for each j in base collect vdp2a j;
  154. vdpcleanup();
  155. gvarslast := 'list . vars;
  156. return w;
  157. end;
  158. symbolic procedure groebnervars(w,v);
  159. begin scalar z,dv,gdv,vars;
  160. if v='(list) then v:=nil;
  161. v:=v or (gdv:=cdr global!-dipvars!*) and global!-dipvars!*;
  162. vars :=
  163. if null v then
  164. for each j in gvarlis w collect !*a2k j
  165. else % test, if vars are really used
  166. << z := gvarlis w;
  167. groebnerzerobc setdiff(z,v:= groerevlist v);
  168. for each j in v do
  169. if member(j,z) then dv := !*a2k j . dv;
  170. dv := reversip dv;
  171. if not (length v = length dv) and !*trgroeb then
  172. << prin2 " Groebner: ";
  173. prin2 (length v - length dv);
  174. prin2t " of the variables not used";
  175. terpri () >>;
  176. dv>>;
  177. return gdv or vars;
  178. end;
  179. symbolic procedure groebnerzerobc u;
  180. % u is the list of parameters in a Groebner job. Extract the
  181. % corresponding rules from !*match and powlis!*.
  182. if u then
  183. begin scalar w,m,p;
  184. bczerodivl!* := nil;
  185. m:=!*match; !*match:=nil;
  186. p:=powlis!*; powlis!*:=nil;
  187. for each r in m do if cadr r='(nil . t) then
  188. <<w:=(numr simp {'difference,'times.for each q in car r collect
  189. {'expt,car q,cdr q}
  190. ,caddr r});
  191. for each x in kernels w do if not member(x,u) then w:=nil;
  192. if w then bczerodivl!* := w . bczerodivl!*;
  193. >>;
  194. for each r in p do if member(car r,u) and caddr r='(nil . t) then
  195. <<w:=(numr simp {'difference, {'expt,car r,cadr r} ,cadddr r});
  196. bczerodivl!* := w . bczerodivl!*;
  197. >>;
  198. for each r in asymplis!* do if member(car r,u) then
  199. bczerodivl!* := (r .*1 .+nil) . bczerodivl!*;
  200. !*match:=m; powlis!*:=p;
  201. end;
  202. % symbolic procedure maklist pl;
  203. % make list of polynomials. pl is a list of polynomials.
  204. % maklist pl returns a list of distributive polynomials.
  205. % for each p in pl collect f2vdp car p;
  206. symbolic procedure gvarlis u;
  207. % Finds variables (kernels) in the list of expressions u.
  208. sort(gvarlis1(u,nil),function ordop);
  209. symbolic procedure gvarlis1(u,v);
  210. if null u then v
  211. else union(gvar1(car u,v),gvarlis1(cdr u,v));
  212. symbolic procedure gvar1(u,v);
  213. if null u or numberp u or (u eq 'i and !*complex) then v
  214. else if atom u then if u member v then v else u . v
  215. else if get(car u,'dname) then v
  216. else if car u memq '(plus times expt difference minus)
  217. then gvarlis1(cdr u,v)
  218. else if car u eq 'quotient then gvar1(cadr u,v)
  219. else if u member v then v
  220. else u . v;
  221. symbolic procedure groebidq(u,f,v);
  222. % Ideal quotient. u is a list of expressions (Gbasis), f a polynomial
  223. % and v a list of variables or NIL
  224. begin scalar vars,w,np,oldorder,!*factor,!*exp;
  225. integer pcount!*; !*exp := t;
  226. w := for each j in groerevlist u
  227. collect if eqexpr j then !*eqn2a j else j;
  228. if null w then rerror(groebner,5,"Empty list in IDEALQUOTIENT");
  229. if eqexpr f then f := !*eqn2a f;
  230. vars := groebnervars(w,v);
  231. groedomainmode();
  232. if null vars then vdperr 'IDEALQUOTIENT;
  233. oldorder := vdpinit vars;
  234. % cancel common denominators
  235. w := for each j in w collect numr simp j;
  236. f := numr simp f;
  237. w := for each j in w collect f2vdp j;
  238. f := f2vdp f; % now do the conversions
  239. if not !*vdpInteger then
  240. <<np := t;
  241. for each p in f.w do
  242. np := if np then vdpCoeffcientsFromDomain!? p
  243. else nil;
  244. if not np then <<!*vdpModular:= nil; !*vdpinteger := T>>;
  245. >>;
  246. w := groebidq2 (w,f);
  247. w := 'list . for each j in w collect vdp2a j;
  248. setkorder oldorder;
  249. return w;
  250. end;
  251. fluid '(!*backtrace);
  252. symbolic procedure vdperr name;
  253. % case that no variables were found
  254. <<prin2 "**** Groebner illegal parmeter in "; prin2 name;
  255. if !*backtrace then backtrace();
  256. rerror(groebner,6," ,e.g. no relevant variables found")>>;
  257. symbolic procedure GroeParams(u,nmin,nmax);
  258. % u is a list of psopfn-parameters; they are given to REVAL and
  259. % the number of parameters is controlled to be between nmin, nmax
  260. % result is the list of evaluated parameters padded with NILs
  261. begin integer n; scalar w; n:= length u;
  262. if n<nmin or n>nmax then rerror(groebner,7,
  263. "Illegal number of parameters in call to Groebner package");
  264. u:= for each v in u collect
  265. <<w := reval v;
  266. if eqcar(w,'LIST) then 'LIST . groerevlist w else w>>;
  267. while length u < nmax do u := append(u,'(nil));
  268. return u;
  269. end;
  270. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  271. %
  272. % initialization of the distributive plynomial arithmetic
  273. %
  274. symbolic procedure vdpinit (vars);
  275. begin scalar r,gm;
  276. % Eventually set up module basis.
  277. if eqcar(gmodule,'list) and cdr gmodule then
  278. gm := for each y in cdr gmodule collect
  279. <<y := reval y;
  280. if not member(y,vars) then vars:=append(vars,{y});
  281. y >>;
  282. r:=vdpinit2(vars);
  283. % convert an eventual module basis.
  284. gmodule!* := if gm then vdpevlmon a2vdp ('times . gm);
  285. return r;
  286. end;
  287. symbolic procedure groedomainmode();
  288. <<!*vdpinteger := !*vdpmodular := nil;
  289. if not flagp(dmode!*,'field) then !*vdpinteger := t
  290. else
  291. if !*modular then !*vdpmodular := t>>;
  292. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  293. %
  294. % some lisp functions which are not member of standard lisp
  295. %
  296. symbolic procedure groedeletip(a,b);
  297. begin scalar q;
  298. while b and a= car b do b:= cdr b;
  299. if null b then return nil;
  300. q := b;
  301. while cdr b do if a=cadr b then cdr b := cddr b else b:= cdr b;
  302. return q;
  303. end;
  304. symbolic procedure groerevlist u;
  305. <<if idp u then u := reval u;
  306. for each p in getrlist u collect reval p>>;
  307. endmodule;
  308. end;