dvfsfsiat.red 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. % ----------------------------------------------------------------------
  2. % $Id: dvfsfsiat.red,v 1.9 1999/03/26 08:22:36 dolzmann Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: dvfsfsiat.red,v $
  7. % Revision 1.9 1999/03/26 08:22:36 dolzmann
  8. % Added code for possibly exploding equations and inequalities:
  9. % Introduced new argument sop to the procedures dvfsf_safield and
  10. % dvfsf_saval. Adapted all calls of these procedures to the new
  11. % parameter list. Added procedure dvfsf_compose to compose the result of
  12. % dvfsf_saval1. Added procedure dvfsf_sapfacf for the factorization of
  13. % an equation or an inequality.
  14. %
  15. % Revision 1.8 1999/03/24 12:33:33 dolzmann
  16. % Added and reformatted comments.
  17. % Removed debugging code.
  18. % Replaced gcdf!* by sfto_gcdf!*.
  19. %
  20. % Revision 1.7 1999/03/23 08:45:43 dolzmann
  21. % Changed copyright information.
  22. %
  23. % Revision 1.6 1999/03/19 12:13:04 dolzmann
  24. % Added simplification for atomic formulas of the form a*p+b=0 and a*p+b<>0,
  25. % where a,b in Z and for atomic formulas of the form f || p*g, and p*f | g.
  26. %
  27. % Revision 1.5 1999/01/17 16:25:29 dolzmann
  28. % Changed copyright notice.
  29. % Added simplification procedures described in "P-adic constraint
  30. % solving" by A. Dolzmann and T. Sturm.
  31. %
  32. % Revision 1.4 1999/01/10 12:11:51 dolzmann
  33. % Added simplification of atomic formulas involving powers of p and integers.
  34. % This simplification is only for p-adic valuations correct.
  35. %
  36. % Revision 1.3 1996/10/07 11:32:09 sturm
  37. % Added fluids for CVS and copyright information.
  38. %
  39. % Revision 1.2 1996/07/15 13:32:41 sturm
  40. % Fixed a bug in dvfsf_saval1.
  41. %
  42. % Revision 1.1 1996/07/08 12:15:25 sturm
  43. % Initial check-in.
  44. %
  45. % ----------------------------------------------------------------------
  46. lisp <<
  47. fluid '(dvfsf_siat_rcsid!* dvfsf_siat_copyright!*);
  48. dvfsf_siat_rcsid!* :=
  49. "$Id: dvfsfsiat.red,v 1.9 1999/03/26 08:22:36 dolzmann Exp $";
  50. dvfsf_siat_copyright!* :=
  51. "Copyright (c) 1995-1999 by A. Dolzmann and T. Sturm"
  52. >>;
  53. module dvfsfsiat;
  54. % Discretely valued field standard simplifier for atomic formulas.
  55. % Submodule of [dvfsf].
  56. procedure dvfsf_simplat1(atf,sop);
  57. % Discretely valued field simplify atomic formula. [atf] is an
  58. % atomic formula; [sop] is a boolean operator. Returns a
  59. % quantifier-free formula that is a simplified equivalent of [atf].
  60. begin scalar op;
  61. op := dvfsf_op atf;
  62. if op eq 'equal or op eq 'neq then
  63. return dvfsf_safield(op,dvfsf_arg2l atf,sop);
  64. return dvfsf_saval(op,dvfsf_arg2l atf,dvfsf_arg2r atf,sop)
  65. end;
  66. procedure dvfsf_saval(op,lhs,rhs,sop);
  67. % Discretely valued field simplify atomic formula built with
  68. % valuation relation. [op] is one of ['assoc], ['nasso], ['div], or
  69. % ['sdiv]; [lhs] and [rhs] are SF's; [sop] is a boolean operator.
  70. % Returns a formula equivalent to $[op]([lhs],[rhs])$.
  71. begin
  72. if minusf lhs then lhs := negf lhs;
  73. if minusf rhs then rhs := negf rhs;
  74. if lhs = rhs then
  75. return if op eq 'sdiv or op eq 'nassoc then 'false else 'true;
  76. % At most one of [lhs], [rhs] is zero. The following third reatment
  77. % of zero sides is probably redundant.
  78. if null lhs then <<
  79. if op eq 'sdiv then return 'false;
  80. if op eq 'nassoc then return dvfsf_safield('neq,rhs,sop);
  81. % We know [op] is one of ['div], ['assoc].
  82. return dvfsf_safield('equal,rhs,sop)
  83. >>;
  84. if null rhs then <<
  85. if op eq 'sdiv or op eq 'nassoc then
  86. return dvfsf_safield('neq,lhs,sop);
  87. if op eq 'assoc then
  88. return dvfsf_safield('equal,lhs,sop);
  89. % We know [op eq 'div] now.
  90. return 'true
  91. >>;
  92. return dvfsf_saval1(op,lhs,rhs)
  93. end;
  94. procedure dvfsf_saval1(op,lhs,rhs);
  95. % Discretely valued field simplify atomic formula built with
  96. % valuation relation subroutine. [op] is one of [div], [sdiv],
  97. % [assoc], [nassoc]; [lhs] and [rhs] are nonzero SF's. Returns a
  98. % formula equivalent to $[op]([lhs],[rhs])$.
  99. begin scalar gcd,natf1,sff,junct;
  100. junct := if op eq 'sdiv or op eq 'nassoc then 'and else 'or;
  101. lhs := dvfsf_vsimpf lhs;
  102. rhs := dvfsf_vsimpf rhs;
  103. gcd := sfto_gcdf!*(lhs,rhs);
  104. lhs := quotf(lhs,gcd);
  105. rhs := quotf(rhs,gcd);
  106. natf1 := dvfsf_saval2(op,lhs,rhs);
  107. if junct eq 'and then <<
  108. if natf1 eq 'false then return 'false;
  109. sff := dvfsf_safield('neq,gcd,'and);
  110. return dvfsf_compose('and,natf1,sff)
  111. >>;
  112. % We know [junct eq 'or].
  113. if natf1 eq 'true then return natf1;
  114. sff := dvfsf_safield('equal,gcd,'or);
  115. return dvfsf_compose('or,natf1,sff)
  116. end;
  117. procedure dvfsf_compose(op,at,f);
  118. % Discretely valued field compose. [op] is either ['or] or ['and];
  119. % [at] is an atomic formula; [f] is a formula. Returns a formula
  120. % equivalent to $[op](at,f)$.
  121. if op eq 'or and (at eq 'true or f eq 'true) then
  122. 'true
  123. else if op eq 'and and (at eq 'false or f eq 'false) then
  124. 'false
  125. else if (at eq 'true) or (at eq 'false) then
  126. f
  127. else if (f eq 'true) or (f eq 'false) then
  128. at
  129. else if (op neq rl_op f) or not(cl_cxfp f) then
  130. rl_mk2(op,at,f)
  131. else
  132. rl_mkn(op,at . rl_argn f);
  133. procedure dvfsf_saval2(op,lhs,rhs);
  134. % Discretely valued field simplify atomic formula built with
  135. % valuation relation subroutine. [op] is one of [div], [sdiv],
  136. % [assoc], [nassoc]; [lhs] and [rhs] are nonzero SF's such that
  137. % [lhs] and [rhs] are relatively prime. Returns a formula
  138. % equivalent to $[op]([lhs],[rhs])$.
  139. begin scalar natf1,w;
  140. if dvfsf_p!* > 0 then % Concrete valuation given.
  141. natf1 := dvfsf_sacval(op,lhs,rhs)
  142. else <<
  143. w := dvfsf_saaval(op,lhs,rhs);
  144. if rl_tvalp w then
  145. natf1 := w
  146. else if w neq 'failed then <<
  147. natf1 := w; % TODO: Repeat the trivial simplifications for [w].
  148. op := dvfsf_op natf1;
  149. lhs := dvfsf_arg2l natf1;
  150. rhs := dvfsf_arg2r natf1
  151. >> else
  152. natf1 := dvfsf_mk2(op,lhs,rhs)
  153. >>;
  154. if (op eq 'assor or op eq 'nassoc) and ordp(rhs,lhs) then
  155. natf1 := dvfsf_mk2(op,rhs,lhs);
  156. return natf1
  157. end;
  158. procedure dvfsf_sacval(op,lhs,rhs);
  159. % Discretely valued field simplify atomic formula built with
  160. % valuation relation for concrete given valuation. [op] is one of
  161. % [div], [sdiv], [assoc], [nassoc]; [lhs] and [rhs] are nonzero
  162. % SF's. Returns a formula equivalent to $[op]([lhs],[rhs])$.
  163. % Evaluate variable free atomic formulas and move the domain
  164. % content to one side.
  165. begin scalar lcont,rcont,lv,rv;
  166. if domainp lhs and domainp rhs then <<
  167. if op eq 'assoc then
  168. return if dvfsf_v lhs = dvfsf_v rhs then 'true else 'false;
  169. if op eq 'nassoc then
  170. return if dvfsf_v lhs neq dvfsf_v rhs then 'true else 'false;
  171. if op eq 'sdiv then
  172. return if dvfsf_v lhs < dvfsf_v rhs then 'true else 'false;
  173. % We know [op eq 'div] now.
  174. return if dvfsf_v lhs <= dvfsf_v rhs then 'true else 'false
  175. >>;
  176. % The content is non-zero.
  177. lcont := sfto_dcontentf lhs;
  178. lhs := quotf(lhs,lcont);
  179. rcont := sfto_dcontentf rhs;
  180. rhs := quotf(rhs,rcont);
  181. lv := dvfsf_v lcont;
  182. rv := dvfsf_v rcont;
  183. if lv >= rv then
  184. lhs := multf(numr simp ((dvfsf_p!*)**(lv-rv)),lhs)
  185. else
  186. rhs := multf(numr simp ((dvfsf_p!*)**(rv-lv)),rhs);
  187. return dvfsf_mk2(op,lhs,rhs)
  188. end;
  189. procedure dvfsf_safield(op,lhs,sop);
  190. % Discretely valued field simplify atomic formula with field
  191. % relation. [op] is either ['equal] or ['neq]; [lhs] is an SF;
  192. % [sop] is a boolean operator.
  193. % Returns a quantifier-free formula equivalent to $[op]([lhs],0)$.
  194. begin
  195. lhs := dvfsf_vsimpf lhs;
  196. if domainp lhs then
  197. if op eq 'equal then
  198. return if null lhs then 'true else 'false
  199. else % [op eq 'neq]
  200. return if null lhs then 'false else 'true;
  201. lhs := sfto_dprpartf lhs;
  202. if dvfsf_p!*>0 then
  203. return dvfsf_sapfacf(op,lhs,sop);
  204. lhs := dvfsf_dppower lhs;
  205. if domainp lhs then
  206. return if op eq 'equal then 'false else 'true;
  207. return dvfsf_sapfacf(op,lhs,sop)
  208. end;
  209. procedure dvfsf_sapfacf(op,lhs,sop);
  210. % Discretely valued field standard form polynomial factorization
  211. % atomic formula with field relation. [op] is either ['equal] or
  212. % [neq]. [lhs] is an SF. Returns a formula equivalent to
  213. % $[op](lhs,0)$; [sop] is a boolean operator. This procedure
  214. % possibly factorize [lhs] to explode the respective atomic
  215. % formula.
  216. begin scalar w,junct;
  217. junct := if op eq 'equal then 'or else 'and;
  218. if !*rlsifac and (!*rlsiexpla or !*rlsiexpl and sop = junct) then
  219. return rl_smkn(junct,
  220. for each x in cdr fctrf lhs collect dvfsf_sapeq(op,car x));
  221. return dvfsf_sapeq(op,lhs)
  222. end;
  223. procedure dvfsf_dppower(f);
  224. % Discretely valued field drop p power. [f] is an SF of the form
  225. % $(p^n f')$. Returns $f'$ as an SF.
  226. begin scalar qr,p;
  227. p := numr simp 'p;
  228. qr := qremf(f,p);
  229. while null(cdr qr) do <<
  230. f := car qr;
  231. qr := qremf(car qr,p);
  232. >>;
  233. return f
  234. end;
  235. procedure dvfsf_saaval(op,lhs,rhs);
  236. % Discretely valued field simplify atomic formula for abstract
  237. % valuation. [op] is one of [div], [sdiv], [assoc], [nassoc]; [lhs]
  238. % and [rhs] are SF's. Returns ['failed] or an atomic formula
  239. % equivalent $[op]([lhs],[rhs])$.
  240. begin scalar w;
  241. w := dvfsf_sappow(op,lhs,rhs);
  242. if w neq 'failed then
  243. return w;
  244. w := dvfsf_savpc(op,lhs,rhs);
  245. if w neq 'failed then
  246. return w;
  247. w := dvfsf_sapureintc(op,lhs,rhs);
  248. if w neq 'failed then
  249. return w;
  250. w := dvfsf_sapfactor(op,lhs,rhs);
  251. if w neq 'failed then
  252. return w;
  253. return 'failed
  254. end;
  255. procedure dvfsf_sappow(op,lhs,rhs);
  256. % Discretely valued field simplify powers of p in atomic formula.
  257. % [op] is one of ['div], ['sdiv], ['nassoc], ['assoc]; [lhs] and
  258. % [rhs] are SF's. Returns ['failed] or a truth value. Simplifies
  259. % atomic formulas which relates 1 to $z p^n$, for an integer [z]
  260. % and a positive integer $n$ to a truth value. Otherwise ['failed]
  261. % is returned.
  262. begin scalar lp,rp;
  263. lp := dvfsf_ppowerp lhs;
  264. rp := dvfsf_ppowerp rhs;
  265. if rp and lhs = numr simp 1 then
  266. return if op = 'assoc then 'false else 'true;
  267. if lp and rhs = numr simp 1 then
  268. return if op = 'nassoc then 'true else 'false;
  269. return 'failed
  270. end;
  271. procedure dvfsf_savpc(op,lhs,rhs);
  272. % Discretely valued field simplify atomic formulas build with
  273. % valuation relation, p, and a constant. [op] is one of [div],
  274. % [sdiv], [assoc], [nassoc]; [lhs] and [rhs] are SF's, such that
  275. % [lhs] and [rhs] are relatively prime. Returns ['failed] or an
  276. % atomic formula equivalent to $[op]([lhs],[rhs])$. The atomic
  277. % formula is simplified, if it relates $z p^n$ to a constant;
  278. % otherwise ['failed] is returned.
  279. %
  280. % WARNING: This simplifier is correct only for p-adic valued fields.
  281. %
  282. begin scalar w,op;
  283. if not !*rlsifac then
  284. return 'failed;
  285. w := dvfsf_savpc1(op,lhs,rhs);
  286. if w eq 'failed then
  287. return 'failed;
  288. op := dvfsf_op w;
  289. if dvfsf_arg2l w = dvfsf_arg2r w then
  290. return if op eq 'nassoc then 'false else 'true;
  291. return w
  292. end;
  293. procedure dvfsf_savpc1(op,lhs,rhs);
  294. % Discretely valued field simplify atomic formulas build with
  295. % valuation relation, p, and a constant subroutine. [op] is one of
  296. % [div], [sdiv], [assoc], [nassoc]; [lhs] and [rhs] are SF's, such
  297. % that [lhs] and [rhs] are relatively prime. Returns ['failed] or
  298. % an atomic formula equivalent to $[op]([lhs],[rhs])$. The atomic
  299. % formula is simplified, if it relates $z p^n$ to a constant;
  300. % otherwise ['failed] is returned.
  301. begin scalar n;
  302. return if (domainp rhs) and (n := dvfsf_ppowerp lhs) then <<
  303. if op eq 'assoc then
  304. dvfsf_mk2('nassoc,sfto_zdeqn(rhs,n),numr simp 1)
  305. else if op eq 'nassoc then
  306. dvfsf_mk2('assoc,sfto_zdeqn(rhs,n),numr simp 1)
  307. else if op eq 'div then
  308. dvfsf_mk2('nassoc,sfto_zdgen(rhs,n),numr simp 1)
  309. else if op eq 'sdiv then
  310. dvfsf_mk2('nassoc,sfto_zdgtn(rhs,n),numr simp 1)
  311. else
  312. rederr "Bug in dvfsf_savpc"
  313. >> else if (domainp lhs) and (n := dvfsf_ppowerp rhs) then <<
  314. if op eq 'assoc then
  315. dvfsf_mk2('nassoc,sfto_zdeqn(lhs,n),numr simp 1)
  316. else if op eq 'nassoc then
  317. dvfsf_mk2('assoc,sfto_zdeqn(lhs,n),numr simp 1)
  318. else if op eq 'div then
  319. dvfsf_mk2('assoc,sfto_zdgtn(lhs,n),numr simp 1)
  320. else if op eq 'sdiv then
  321. dvfsf_mk2('assoc,sfto_zdgen(lhs,n),numr simp 1)
  322. else
  323. rederr "Bug in dvfsf_savpc"
  324. >> else
  325. 'failed
  326. end;
  327. procedure dvfsf_ppowerp(u);
  328. % Discretely valued field power of p predicate. [u] is an SF.
  329. % Returns [nil] or a positive integer $n$. Tests [u] on
  330. % representing a polynomial $z p^n$ for an integer $z$ and a
  331. % natural number $n$.
  332. begin scalar rou,w;
  333. rou := sfto_reorder(u,'p);
  334. w := (not domainp rou and mvar rou = 'p and
  335. domainp lc rou and null red rou);
  336. if w then
  337. return ldeg u
  338. end;
  339. procedure dvfsf_ppolyp(f);
  340. % Discretely valued field p polynomial predicate. [f] is an SF.
  341. % Returns [T] if [f] is a domian element or is a polynomial
  342. % containing only the variable ['p] otherwise [nil] is returned.
  343. begin scalar w;
  344. if domainp f then
  345. return T;
  346. w := kernels f;
  347. return null cdr w and car w eq 'p
  348. end;
  349. procedure dvfsf_ppolydec(f);
  350. % Discretely valued field p polynomial decomposition. [f] is an SF.
  351. % Returns a list $(...,(a_i,n_i),...)$ such that $[f]=\sum_i
  352. % a_ip^n_i$ and $n_i>n_{i+1}$.
  353. if null f then
  354. nil
  355. else if domainp f then
  356. {(f . 0)}
  357. else
  358. (lc f . ldeg f) . dvfsf_ppolydec red f;
  359. procedure dvfsf_vsimpf(f);
  360. % Discretely valued field valuation simplification standard form.
  361. % [f] is an SF. Returns an SF $f'$, such that for all terms $g$ we
  362. % have $[f] \mathrel{\varrho} g$ if and only if $f'
  363. % \mathrel{\varrho} g$.
  364. begin scalar w,fdc,cep,c,n,cdc;
  365. if domainp f then
  366. return f;
  367. if not dvfsf_ppolyp f then
  368. return f;
  369. fdc := reversip dvfsf_ppolydec(f);
  370. w := car fdc;
  371. fdc := cdr fdc;
  372. if null fdc then
  373. return f;
  374. n := cdr w;
  375. c := car w;
  376. if (c = 1) or (c = -1) then
  377. return numr simp {'expt,'p,n};
  378. cdc := sort(zfactor c,function(lambda(x,y); (cdr x > cdr y)));
  379. if n + cdr car cdc < cdr car fdc then
  380. return numr simp {'times,c,{'expt,'p,n}};
  381. while cdc do <<
  382. cep := car cdc;
  383. w := dvfsf_vsimpf1(car cep,cdr cep,n,fdc);
  384. if w eq 'failed then
  385. cdc := nil
  386. else
  387. cdc := cdr cdc;
  388. >>;
  389. if w eq 'failed then
  390. return f;
  391. return numr simp {'times,c,{'expt,'p,n}};
  392. end;
  393. procedure dvfsf_vsimpf1(q,m,n,fdc);
  394. % Discretely valued field valuation simplification standard form
  395. % subroutine. [f] is an SF. Returns an SF $f'$, such that for all
  396. % terms $g$ we have $[f] \mathrel{\varrho} g$ if and only if $f'
  397. % \mathrel{\varrho} g$.
  398. begin scalar w,k,qp;
  399. while fdc do <<
  400. w := car fdc; % a pair $(a . n)$ with $a*p^n$ is monomial of [f]
  401. k := cdr w - n;
  402. if m<k then <<
  403. w := nil;
  404. fdc := nil
  405. >> else <<
  406. qp := abs(q)^(m-k+1);
  407. if gcdf!*(qp,car w) = qp then
  408. fdc := cdr fdc
  409. else <<
  410. w := 'failed;
  411. fdc := nil;
  412. >>
  413. >>
  414. >>;
  415. if w eq 'failed then
  416. return 'failed
  417. end;
  418. procedure dvfsf_sapureintc(op,lhs,rhs);
  419. % Discretely valued field simplifiy atomic formulas pure integer
  420. % constraints. [op] is one of ['assoc], ['nassoc], ['div] or
  421. % ['sdiv]; [lhs] and [rhs] are SF's. Returns ['failed] or an atomic
  422. % formula. This procedure simplifies atomic formulas which relates
  423. % integers.
  424. if not !*rlsifac then
  425. 'failed
  426. else if not(domainp lhs and domainp rhs) then
  427. 'failed
  428. else if op eq 'assoc or op eq 'nassoc then
  429. dvfsf_mk2(op,sfto_sqfpartz(lhs*rhs),numr simp 1)
  430. else if op eq 'div then
  431. dvfsf_mk2('assoc,sfto_sqfpartz lhs,numr simp 1)
  432. else if op eq 'sdiv then
  433. dvfsf_mk2('nassoc,sfto_sqfpartz rhs,numr simp 1)
  434. else
  435. rederr "bug dvfsf_sapureintc";
  436. procedure dvfsf_sapeq(op,lhs);
  437. % Discretely valued field simplify atomic formula p equation. [op]
  438. % is either ['equal] or ['neq]. [lhs] is an SF. Returns an atomic
  439. % formula equivalent to $[op]([lhs],0)$. This procedures
  440. % simplifies atomic formulas of the form $[op](z1 p + z2,0)$, with
  441. % $z1$ and $z2$ relatively prime.
  442. if not(not(domainp lhs) and mvar lhs eq 'p and ldeg lhs = 1
  443. and domainp lc lhs and domainp red lhs)
  444. then
  445. dvfsf_mk2(op,lhs,nil)
  446. else if (lc lhs neq 1) or not(minusf red lhs) or not(primep red lhs) then
  447. if op eq 'equal then 'false else 'true
  448. else
  449. dvfsf_mk2(if op eq 'equal then 'nassoc else 'assoc,
  450. negf red lhs,numr simp 1);
  451. procedure dvfsf_sapfactor(op,lhs,rhs);
  452. % Discretely valued field simplify atomic formula p factor. [op] is
  453. % one of ['assoc], ['nassoc], ['div], or ['sdiv]. [lhs] and [rhs]
  454. % are SF's. Returns ['failed] or atomic formula equivalent to
  455. % $[op]([lhs],[rhs])$. This procedures simplifies atomic formulas
  456. % of the form $f || p*g$, $p*f | g$.
  457. begin scalar w;
  458. if op eq 'sdiv then <<
  459. w := qremf(rhs,numr simp 'p);
  460. if null cdr w then
  461. return dvfsf_mk2('div,lhs,car w);
  462. return 'failed
  463. >>;
  464. if op eq 'div then <<
  465. w := qremf(lhs,numr simp 'p);
  466. if null cdr w then
  467. return dvfsf_mk2('sdiv,car w,rhs);
  468. return 'failed
  469. >>;
  470. return 'failed
  471. end;
  472. endmodule; % [dvfsfsiat]
  473. end; % of file