dvfsfqe.red 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. % ----------------------------------------------------------------------
  2. % $Id: dvfsfqe.red,v 1.5 1999/04/08 11:52:50 dolzmann Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: dvfsfqe.red,v $
  7. % Revision 1.5 1999/04/08 11:52:50 dolzmann
  8. % Fixed a bug reporteb by Tony Hearn: Added additional parameter bvl to
  9. % procedure dvfsf_trygauss.
  10. %
  11. % Revision 1.4 1999/03/23 08:50:37 dolzmann
  12. % Changed copyright information.
  13. % Added module comment.
  14. %
  15. % Revision 1.3 1999/01/10 11:13:54 sturm
  16. % Added black box implementation dvfsf_qemkans for rlqea.
  17. %
  18. % Revision 1.2 1996/10/07 11:32:08 sturm
  19. % Added fluids for CVS and copyright information.
  20. %
  21. % Revision 1.1 1996/07/08 12:15:23 sturm
  22. % Initial check-in.
  23. %
  24. % ----------------------------------------------------------------------
  25. lisp <<
  26. fluid '(dvfsf_qe_rcsid!* dvfsf_qe_copyright!*);
  27. dvfsf_qe_rcsid!* :=
  28. "$Id: dvfsfqe.red,v 1.5 1999/04/08 11:52:50 dolzmann Exp $";
  29. dvfsf_qe_copyright!* := "Copyright (c) 1995-1999 by A. Dolzmann and T. Sturm"
  30. >>;
  31. module dvfsfqe;
  32. % Discretely valued field standard form quantifier elimination.
  33. % Submodule of [dvfsf].
  34. procedure dvfsf_varsel(f,vl,theo);
  35. car vl;
  36. procedure dvfsf_pmultf(u);
  37. multf(u,numr simp 'p);
  38. procedure dvfsf_pmultsq(u);
  39. multsq(u,simp 'p);
  40. procedure dvfsf_ipmultsq(u);
  41. quotsq(u,simp 'p);
  42. procedure dvfsf_translat(atf,v,theo,pos,ans);
  43. begin scalar op,lhs,rhs;
  44. if not (v memq dvfsf_varlat atf) then
  45. return nil . nil;
  46. if not pos then atf := dvfsf_negateat atf;
  47. op := dvfsf_op atf;
  48. lhs := dvfsf_arg2l atf;
  49. rhs := dvfsf_arg2r atf;
  50. if op eq 'neq then
  51. return dvfsf_translat2(v,'sdiv,{lhs . rhs});
  52. if op = 'sdiv or op = 'div or op = 'equal then
  53. return dvfsf_translat2(v,op,{lhs . rhs});
  54. if op eq 'assoc then
  55. return dvfsf_translat2(v,'div,{lhs . rhs,rhs . lhs});
  56. if op eq 'nassoc then
  57. return dvfsf_translat2(v,'sdiv,{lhs . rhs,rhs . lhs});
  58. rederr "BUG IN dvfsf_translat"
  59. end;
  60. procedure dvfsf_translat2(v,op,l);
  61. begin scalar m,eqsoll,pr,cl,dl,el,fl,a,aa,b,bb,co;
  62. if op = 'equal then
  63. return {'equal . {dvfsf_mkcsol dvfsf_mkpair(caar l,v)}} . nil;
  64. for each x in l do <<
  65. pr := dvfsf_mkpair(car x,v);
  66. a := car pr;
  67. b := cdr pr;
  68. pr := dvfsf_mkpair(cdr x,v);
  69. aa := car pr;
  70. bb := cdr pr;
  71. if null aa then <<
  72. cl := lto_insert(dvfsf_mkcpoint(negf b,a),cl);
  73. dl := lto_insert(dvfsf_mkcpoint(bb,a),dl)
  74. >> else if null a then <<
  75. el := lto_insert(dvfsf_mkcpoint(b,aa),el);
  76. fl := lto_insert(dvfsf_mkcpoint(negf bb,aa),fl)
  77. >> else <<
  78. cl := lto_insert(dvfsf_mkcpoint(negf b,a),cl);
  79. dl := lto_insert(dvfsf_mkcpoint(bb,a),dl);
  80. el := lto_insert(dvfsf_mkcpoint(b,aa),el);
  81. fl := lto_insert(dvfsf_mkcpoint(negf bb,aa),fl);
  82. fl := lto_insert(dvfsf_mkcpoint(negf bb,a),fl);
  83. co := rl_mkn('and,{dvfsf_0mk2('neq,a),dvfsf_0mk2('neq,aa)});
  84. a := !*f2q a;
  85. b := !*f2q b;
  86. aa := !*f2q aa;
  87. bb := !*f2q bb;
  88. m := subtrsq(quotsq(bb,aa),quotsq(b,a));
  89. el := lto_insert({co,multsq(quotsq(a,aa),m)},el);
  90. dl := lto_insert({co,multsq(quotsq(aa,a),m)},dl)
  91. >>
  92. >>;
  93. return {'c . cl,'d . dl,'e . el,'f . fl} . nil
  94. end;
  95. procedure dvfsf_mkpair(u,v);
  96. begin scalar d;
  97. u := sfto_reorder(u,v);
  98. d := degr(u,v);
  99. if d=0 then
  100. return nil . reorder u;
  101. if d=1 then
  102. return reorder lc u . reorder red u;
  103. rederr {"degree violation in",prepf reorder u}
  104. end;
  105. procedure dvfsf_mkcsol(pr);
  106. {dvfsf_0mk2('neq,car pr),quotsq(!*f2q negf cdr pr,!*f2q car pr)};
  107. procedure dvfsf_mkcpoint(b,a);
  108. {dvfsf_0mk2('neq,a),quotsq(!*f2q b,!*f2q a)};
  109. procedure dvfsf_elimset(v,alp);
  110. % Discretely valued field elimination set. [v] is a variable;
  111. % [alp] is a pair of alists.
  112. begin scalar w,esetl,atal,cl,el,m1,m2; integer i;
  113. atal := car alp;
  114. cl := lto_catsoc('c,atal);
  115. el := lto_catsoc('e,atal);
  116. if !*rlverbose and null el then ioto_prin2 "#u"; % only upper bounds
  117. esetl := {'true,simp 1} . lto_catsoc('equal,atal); % 1
  118. esetl := nconc(lto_catsoc('f,atal),esetl); % F
  119. for each d in lto_catsoc('d,atal) do
  120. esetl := {car d,dvfsf_ipmultsq cadr d} . esetl; % p^{-1} d
  121. for each c in cl do <<
  122. esetl := {car c,dvfsf_ipmultsq cadr c} . esetl; % p^{-1} c
  123. if el then << % also lower bounds
  124. for each e in el do
  125. esetl := {rl_mkn('and,{car c,car e}),
  126. addsq(cadr e,cadr c)} . esetl; % e+c
  127. for each cc in cl do <<
  128. m2 := cadr cc;
  129. m1 := subtrsq(cadr c,m2);
  130. esetl := {rl_mkn('and,{car c,car cc}),
  131. addsq(dvfsf_pmultsq m1,m2)} . esetl; % p(c-cc)+cc
  132. % Avoid cosets.
  133. w := if dvfsf_p!* neq 0 then
  134. min(length cl,abs(dvfsf_p!*)-1)
  135. else
  136. length cl;
  137. for z := 1:w do
  138. esetl := {rl_mkn('and,{car c,car cc}),
  139. addsq(multsq(simp z,m1),m2)} . esetl % z(c-cc)+cc
  140. >>
  141. >>
  142. >>;
  143. if el then % also lower bounds
  144. esetl := nconc(cl,esetl); % C
  145. return {'dvfsf_qesubcq . esetl}
  146. end;
  147. procedure dvfsf_qesubcq(bvl,theo,f,v,c,u);
  148. % Substitute conditionally 1 quotient. [f] is a formula; [v] is a
  149. % variable; [c] is a formula which implies that the denominator of
  150. % [u] is nonzero; [u] is an SQ. Returns a quantifier-free formula
  151. % equivalent to $[c] \land [f]([v]/[u])$.
  152. if (c := cl_simpl(c,nil,-1)) eq 'false then
  153. nil . 'false
  154. else
  155. nil . rl_mkn('and,{c,dvfsf_qesubq(f,v,u)});
  156. procedure dvfsf_qesubq(f,v,u);
  157. % Substitute quotient. [f] is a formula; [v] is a variable; [u] is
  158. % an SQ. Returns a quantifier-free formula equivalent to
  159. % $[f]([v]/[u])$ provided that the denominator of [u] is nonzero.
  160. cl_apply2ats1(f,'dvfsf_qesubqat,{v,u});
  161. procedure dvfsf_qesubqat(atf,v,u);
  162. % Substitute quotient into atomic formula. [atf] is an atomic
  163. % formula; [v] is a variable; [u] is an SQ. Returns a
  164. % quantifier-free formula equivalent to $[atf]([v]/[u])$ provided
  165. % that the denominator of [u] is nonzero.
  166. begin scalar op,al,lhs,rhs;
  167. op := dvfsf_op atf;
  168. al := {v . prepsq u};
  169. lhs := subf(dvfsf_arg2l atf,al);
  170. if op memq '(equal neq) then
  171. return dvfsf_0mk2(op,numr lhs);
  172. rhs := subf(dvfsf_arg2r atf,al);
  173. return dvfsf_mk2(op,multf(numr lhs,denr rhs),multf(numr rhs,denr lhs))
  174. end;
  175. procedure dvfsf_transform(f,v);
  176. f . nil;
  177. procedure dvfsf_trygauss(f,vl,theo,ans,bvl);
  178. begin scalar w,v,fargl;
  179. if rl_op f = 'and then
  180. fargl := rl_argn f
  181. else if cl_atfp f then
  182. fargl := {f}
  183. else
  184. return 'failed;
  185. while vl do <<
  186. v := car vl;
  187. vl := cdr vl;
  188. w := dvfsf_findeqsol(fargl,v,theo,ans);
  189. if w neq 'failed then <<
  190. w := (v . w) . theo;
  191. vl := nil
  192. >>
  193. >>;
  194. return w
  195. end;
  196. procedure dvfsf_findeqsol(fl,v,theo,ans);
  197. begin scalar w;
  198. w := dvfsf_findeqsol1(car fl,v,theo,ans);
  199. if w neq 'failed then return w;
  200. if cdr fl then return dvfsf_findeqsol(cdr fl,v,theo,ans);
  201. return 'failed
  202. end;
  203. procedure dvfsf_findeqsol1(a,v,theo,ans);
  204. if cl_cxfp a or dvfsf_op a neq 'equal or not (v memq dvfsf_varlat a) then
  205. 'failed
  206. else
  207. dvfsf_gelimset(a,v);
  208. procedure dvfsf_gelimset(a,v);
  209. begin scalar pr;
  210. pr := dvfsf_mkpair(dvfsf_arg2l a,v);
  211. if numberp car pr then
  212. return {'dvfsf_qesubcq . {dvfsf_mkcsol pr}};
  213. return 'failed
  214. end;
  215. procedure dvfsf_qemkans(an,atr);
  216. sort(dvfsf_qebacksub dvfsf_qemkans1 an,
  217. function(lambda(x,y); ordp(cadr x,cadr y)));
  218. procedure dvfsf_qemkans1(an);
  219. % [an] is an answer. Returns a list of equations.
  220. for each y in an collect
  221. % cadr y = 'dvfsf_qesubcq, cadddr y = nil (atr)
  222. {'equal,car y,prepsq cadr caddr y};
  223. procedure dvfsf_qebacksub(eql);
  224. % Quantifier elimination back substitution. [eql] is a list of
  225. % equations. Returns a list of equations.
  226. begin scalar subl,rhs,w;
  227. return for each e in eql collect <<
  228. rhs := simp caddr e;
  229. w := {'equal,cadr e,prepsq subsq(rhs,subl)};
  230. subl := (cadr w . caddr w) . subl;
  231. w
  232. >>
  233. end;
  234. endmodule; % [dvfsfqe]
  235. end; % of file