pasfqe.red 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. % ----------------------------------------------------------------------
  2. % $Id: pasfqe.red,v 1.57 2004/02/22 21:08:15 lasaruk Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 2001 A. Dolzmann, A. Seidl, and T. Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: pasfqe.red,v $
  7. % Revision 1.57 2004/02/22 21:08:15 lasaruk
  8. % Added switch rlsusisubst for substitution of equalities. Substitution
  9. % results in smaller formulas or formulas with less free variables.
  10. % Up to 80% length reduction. Switch rlsusitr should not be used yet.
  11. %
  12. % Revision 1.56 2003/12/16 07:45:34 lasaruk
  13. % Redlog normal form in the simplifier.
  14. %
  15. % Revision 1.55 2003/12/11 10:51:19 lasaruk
  16. % Smart simplification improoved.
  17. %
  18. % Revision 1.54 2003/12/02 15:27:13 sturm
  19. % Introduced ioto_nterpri to avoid ugly linebreaks in verbosity output.
  20. %
  21. % Revision 1.53 2003/12/02 15:00:57 sturm
  22. % Removed a call to cl_simpl in pasf_qeex (superfluous checking for truth
  23. % values).
  24. % Do a more general check on variable not occurring.
  25. %
  26. % Revision 1.52 2003/12/02 14:37:07 sturm
  27. % Rewritten pasf_qeexblock and added canonical verbose output.
  28. %
  29. % Revision 1.51 2003/11/05 13:27:14 lasaruk
  30. % Some major redlog programming rules applied to the code.
  31. % Formulas are made positive acc. to the current kernel order.
  32. %
  33. % Revision 1.50 2003/10/28 10:02:03 dolzmann
  34. % Added correct content of fluids pasf_siat_rcsid!* and
  35. % pasf_siat_copyright!*.
  36. %
  37. % Revision 1.49 2003/10/16 16:17:38 lasaruk
  38. % Compiler error messages partially removed. All others are due
  39. % to the noncompleteness of packet.
  40. %
  41. % Revision 1.48 2003/10/12 15:18:11 sturm
  42. % pasf_qe requires second (theo, dummy for now) argument. This became visible
  43. % under CSL.
  44. %
  45. % Revision 1.47 2003/08/28 15:30:40 lasaruk
  46. % Simplification verbose output done better. QE-Bug with truth values
  47. % corrected (will be done more effitient). Some fancy examples added.
  48. %
  49. % Revision 1.46 2003/07/16 12:58:50 lasaruk
  50. % Error in QE removed.
  51. %
  52. % Revision 1.45 2003/07/16 12:51:35 lasaruk
  53. % Tipp error.
  54. %
  55. % Revision 1.44 2003/07/16 12:48:33 lasaruk
  56. % See message below.
  57. %
  58. % Revision 1.43 2003/07/15 12:40:41 seidl
  59. % Renamed pasf_iv2qff to pasf_ivl2qff and pasf_qff2iv to pasf_qff2ivl.
  60. % Provided algebraic mode access to simplb, ivl2qff, qdd2ivl. Changed
  61. % pasf_mkrng so intervals with same upper and lower bound result in an
  62. % equation. Fixed serious bug in pasf_prepat. Added cvs header to
  63. % pasf.tst. Todo Lasaruk: pasf_ivl2qff crashes with empty interval as
  64. % argument, see testfile.
  65. %
  66. % Revision 1.42 2003/06/04 12:33:40 lasaruk
  67. % Some smaller modifications.
  68. %
  69. % Revision 1.41 2003/05/28 20:37:51 lasaruk
  70. % Expansion done better.
  71. %
  72. % Revision 1.40 2003/05/26 20:50:57 lasaruk
  73. % Range expansion with congruences
  74. %
  75. % Revision 1.39 2003/05/22 22:00:58 lasaruk
  76. % DNF added.
  77. %
  78. % Revision 1.38 2003/05/17 17:04:16 lasaruk
  79. % bugs removed
  80. %
  81. % Revision 1.37 2003/05/17 16:27:56 lasaruk
  82. % Pasf simplification added. Some errors corrected.
  83. %
  84. % Revision 1.36 2003/05/15 23:34:47 lasaruk
  85. % Interval expansion added
  86. %
  87. % Revision 1.35 2003/04/20 12:04:04 lasaruk
  88. % Completely removed any reference to range predicates (in input
  89. % also). PNF made shorter.
  90. %
  91. % Revision 1.34 2003/04/14 10:11:39 lasaruk
  92. % Changes to work with bounded quantifieres added . Simplification bug
  93. % (content) removed. Range predicates removed.
  94. %
  95. % Revision 1.33 2003/03/26 11:19:23 lasaruk
  96. % Formula runthrough rewritten as cl_atnum. True/false in rlexpabnd bug
  97. % removed. Some services added.
  98. %
  99. % Revision 1.32 2003/03/04 09:33:23 lasaruk
  100. % Advanced simplification. PNF code attached but not used yet. Some code
  101. % migration. Documentation debugged.
  102. %
  103. % Revision 1.31 2003/02/24 19:50:19 lasaruk
  104. % Congruences without x removed.
  105. %
  106. % Revision 1.30 2003/02/18 12:45:03 lasaruk
  107. % Better code for some methods.
  108. %
  109. % Revision 1.29 2003/02/17 14:44:55 lasaruk
  110. % Debug messages removed.
  111. %
  112. % Revision 1.28 2003/02/17 10:55:40 lasaruk
  113. % Stable full featured version
  114. %
  115. % Revision 1.27 2003/02/03 13:41:04 lasaruk
  116. % Experimental version with full functionality. A bit buggy.
  117. %
  118. % Revision 1.26 2003/02/02 17:33:44 lasaruk
  119. % Internal representation of data is converted completely into SF's
  120. % except the representation of moduli.
  121. %
  122. % Revision 1.25 2003/02/01 08:42:50 lasaruk
  123. % Stack container implemented.
  124. %
  125. % Revision 1.24 2003/02/01 07:38:33 lasaruk
  126. % Recursive range expansion.
  127. %
  128. % Revision 1.23 2003/01/31 14:25:06 lasaruk
  129. % Bug fixed.
  130. %
  131. % Revision 1.22 2003/01/31 14:18:48 lasaruk
  132. % Found better method for impoding.
  133. %
  134. % Revision 1.21 2003/01/31 14:09:58 lasaruk
  135. % New variable method added. K is no loger fixed, but a new variable.
  136. %
  137. % Revision 1.20 2003/01/29 16:07:46 lasaruk
  138. % Better limits.
  139. %
  140. % Revision 1.19 2003/01/29 15:24:47 sturm
  141. % Added service rlexpand for context pasf. Had to split pasf_exprng for this.
  142. %
  143. % Revision 1.18 2003/01/27 17:40:02 lasaruk
  144. % Switches renamed. Bugs in docu fixed.
  145. %
  146. % Revision 1.17 2003/01/26 18:31:49 lasaruk
  147. % Simplification position altered.
  148. %
  149. % Revision 1.16 2003/01/26 17:49:37 lasaruk
  150. % Null congruence error added. Terms without quant. varl. stay
  151. % untouched. Bugs fixed.
  152. %
  153. % Revision 1.15 2003/01/21 17:39:14 lasaruk
  154. % Switch rlsiatadv turned off. Bugs fixed.
  155. %
  156. % Revision 1.14 2003/01/21 10:44:14 lasaruk
  157. % Congruence substitution added. Bugs fixed.
  158. %
  159. % Revision 1.13 2003/01/20 10:36:51 lasaruk
  160. % First trial to work with congruences. Bugs fixed.
  161. %
  162. % Revision 1.12 2003/01/06 18:20:32 lasaruk
  163. % Bugs fixed
  164. %
  165. % Revision 1.11 2003/01/06 17:33:27 lasaruk
  166. % Some simplifier bugs fixed. Alternating quantifier elimination attached.
  167. %
  168. % Revision 1.10 2003/01/05 15:55:05 lasaruk
  169. % Simplification improoved. Expansion of range predicates added.
  170. %
  171. % Revision 1.9 2002/12/31 13:57:49 lasaruk
  172. % Simplifier bugs fixed.
  173. %
  174. % Revision 1.8 2002/12/31 13:33:34 lasaruk
  175. % Standard simplifier attached. Standard simplification of expressions
  176. % attached.
  177. %
  178. % Revision 1.7 2002/12/23 07:41:19 lasaruk
  179. % Simplifier turned off temporary
  180. %
  181. % Revision 1.6 2002/12/23 07:07:05 lasaruk
  182. % Elimination code completely rewritten
  183. %
  184. % Revision 1.5 2002/12/10 08:49:41 lasaruk
  185. % Correct elimination of an exist. quantifier call added.
  186. % Procedures debugged.
  187. %
  188. % Revision 1.3 2002/12/02 12:53:37 lasaruk
  189. % Elimination of one variable in front of an ex quantifier. Not really
  190. % worth looking at.
  191. %
  192. % Revision 1.2 2002/11/15 12:00:48 seidl
  193. % Head added.
  194. %
  195. % ----------------------------------------------------------------------
  196. lisp <<
  197. fluid '(pasf_qe_rcsid!* pasf_qe_copyright!*);
  198. pasf_qe_rcsid!* :=
  199. "$Id";
  200. pasf_qe_copyright!* :=
  201. "Copyright (c) 2003 A. Dolzmann, A. Seidl, and T. Sturm"
  202. >>;
  203. module pasfqe;
  204. % Presburger arithmetic standard form quantifier
  205. % elimination. Submodule of [pasf].
  206. procedure elimdata_new(repr,n,m,min_si,max_si,ats);
  207. % Elimination data constructor. [repr] is a list of canonical
  208. % representants, [n] is the lcm of all leading coeficients of the
  209. % left hand side of the elimination normal form, [m] is the lcm of
  210. % all moduli, [min_si] and [max_si] are the minimal constant values
  211. % among all atomic formulas and [ats] is the list of (atf_j,min_sj,
  212. % max_sj) where [atf] is an atomic formula containing the
  213. % quantified variable and [min_si] and [max_si] are the minimal and
  214. % maximal constant value of atf's right hand side. Returns the
  215. % elimination data in the elimdata datastructure format.
  216. {repr,n,m,min_si,max_si,ats};
  217. procedure elimdata_repr(elimdata);
  218. % Elimination data canonical representants accessor. [elimdata] is
  219. % the elimination data. Returns the canonical representants.
  220. car elimdata;
  221. procedure elimdata_n(elimdata);
  222. % Elimination data n accessor. [elimdata] is the elimination
  223. % data. Returns n.
  224. cadr elimdata;
  225. procedure elimdata_m(elimdata);
  226. % Elimination data m accessor. [elimdata] is the elimination
  227. % data. Returns m.
  228. caddr elimdata;
  229. procedure elimdata_min_si(elimdata);
  230. % Elimination data min_si accessor. [elimdata] is the elimination
  231. % data. Returns min_si.
  232. cadddr elimdata;
  233. procedure elimdata_max_si(elimdata);
  234. % Elimination data max_si accessor. [elimdata] is the elimination
  235. % data. Returns max_si.
  236. car cddddr elimdata;
  237. procedure elimdata_ats(elimdata);
  238. % Elimination data atomic formula list accessor. [elimdata] is the
  239. % elimination data. Returns the atomic formula list.
  240. cadr cddddr elimdata;
  241. procedure elimdata_join(elimdatalst);
  242. % Elimination data join a list of elimination data information.
  243. % [elimdatalst] is a list of elimdata. Returns the common
  244. % elimination information of all list elements.
  245. begin scalar rep,n,m,min_si,max_si;
  246. rep :={};
  247. n := 1;
  248. m := 1;
  249. min_si := nil;
  250. max_si := nil;
  251. if elimdatalst then <<
  252. max_si := elimdata_max_si car elimdatalst;
  253. min_si := elimdata_min_si car elimdatalst;
  254. for each elimdata in elimdatalst do <<
  255. % Just joning the list of canonic representants
  256. rep := append(rep,elimdata_repr elimdata);
  257. % LCM of all n,m
  258. n := *lcm(n,elimdata_n elimdata);
  259. m := *lcm(m,elimdata_m elimdata);
  260. % max_si and min_si computation
  261. if minusf addf(max_si,negf elimdata_max_si elimdata) then
  262. max_si := elimdata_min_si elimdata;
  263. if minusf addf(min_si,negf elimdata_min_si elimdata) then
  264. min_si := elimdata_max_si elimdata
  265. >>
  266. >>;
  267. return elimdata_new(rep,n,m,min_si,max_si,nil)
  268. end;
  269. procedure pasf_qe(phi,theo);
  270. % Presburger arithmetic standard form compute a quantifier free
  271. % formula equivalent to psi. [psi] is a formula. Returns a
  272. % quantifier free formula equivalent to $\psi()$.
  273. begin scalar split,rslt,phi_prime;
  274. if !*rlverbose then
  275. ioto_tprin2 "++++ Entering pasf_qe";
  276. phi_prime := rl_pnf phi;
  277. split := cl_splt phi_prime;
  278. % Performing DNF on the matrix
  279. rslt := rl_dnf cadr split;
  280. for each block in car split do
  281. rslt := pasf_qeblock(car block,cdr block,rslt);
  282. return if !*rlpasfsimplify then
  283. cl_simpl(rslt,nil,-1)
  284. else
  285. rslt;
  286. end;
  287. procedure pasf_qeblock(omega,varl,psi);
  288. % Presburger erithmetic standrd form eliminate a block of
  289. % quantifiers. [omega] if the quantifier type, varl is a list of
  290. % the block bounded variables and [psi] is the matrix of the
  291. % formula.
  292. begin integer dpth,vlv;
  293. if !*rlverbose then <<
  294. ioto_tprin2 {"---- ",omega . reverse varl};
  295. dpth := length varl;
  296. if !*rlqedfs then << % should not happen by now
  297. vlv := dpth / 4;
  298. ioto_prin2t {" [DFS: depth ",dpth,", watching ",dpth - vlv,"]"}
  299. >> else
  300. ioto_prin2t {" [BFS: depth ",dpth,"]"}
  301. >>;
  302. if omega eq 'ex then
  303. return pasf_qeexblock(varl,psi,dpth,vlv);
  304. % [op eq 'all]
  305. return cl_nnfnot pasf_qeexblock(varl,cl_nnfnot psi,dpth,vlv)
  306. end;
  307. procedure pasf_qeexblock(varl,psi,dpth,vlv);
  308. % Presburger erithmetic standrd form eliminate a block of
  309. % existential quantifiers. [varl] are the bounded variables, [psi]
  310. % is the matrix of the formula. Returns a quantifier free formula
  311. % equivalent to $\exists varl \psi()$.
  312. begin scalar co,cvl,w,coe,f,newj,v; integer c,delc,oldcol,count;
  313. cvl := varl;
  314. if rl_op psi eq 'or then
  315. for each x in rl_argn psi do
  316. co := cl_save(co,{cl_mkcoel(cvl,x,nil,nil)})
  317. else
  318. co := cl_save(co,{cl_mkcoel(cvl,psi,nil,nil)});
  319. while co do <<
  320. w := cl_get co;
  321. co := cdr w;
  322. coe := car w;
  323. cvl := cl_covl coe;
  324. f := cl_cof coe;
  325. count := count + 1;
  326. if !*rlverbose then
  327. if !*rlqedfs then <<
  328. if vlv = length cvl then
  329. ioto_tprin2t {"-- crossing: ",dpth - vlv};
  330. ioto_prin2 {"[",dpth - length cvl}
  331. >> else <<
  332. if c=0 then <<
  333. ioto_tprin2t {"-- left: ",length cvl};
  334. c := cl_colength co + 1
  335. >>;
  336. ioto_nterpri(length explode c + 4);
  337. ioto_prin2 {"[",c};
  338. c := c - 1
  339. >>;
  340. v := car cvl;
  341. cvl := cdr cvl;
  342. f := pasf_qeex(f,v);
  343. if !*rlpasfsimplify then
  344. f := cl_simpl(f,nil,-1);
  345. if f eq 'true then <<
  346. co := nil;
  347. newj := '(true)
  348. >> else if null cvl then
  349. newj := adjoin(f,newj)
  350. else
  351. if rl_op f eq 'or then <<
  352. if !*rlverbose then oldcol := cl_colength co;
  353. for each x in rl_argn f do
  354. co := cl_save(co,{cl_mkcoel(cvl,x,nil,nil)});
  355. if !*rlverbose then
  356. delc := delc + oldcol + length rl_argn f - cl_colength co
  357. >> else <<
  358. if !*rlverbose then oldcol := cl_colength(co);
  359. co := cl_save(co,{cl_mkcoel(cvl,f,nil,nil)});
  360. if !*rlverbose then
  361. delc := delc + oldcol + 1 - cl_colength(co)
  362. >>;
  363. if !*rlverbose then <<
  364. ioto_prin2 "] ";
  365. if !*rlqedfs and null cvl then ioto_prin2 ". "
  366. >>
  367. >>;
  368. if !*rlverbose then ioto_prin2{"[DEL:",delc,"/",count,"]"};
  369. return rl_smkn('or,newj)
  370. end;
  371. procedure pasf_qeex(psi,x);
  372. % Presburger arithmetic standard form eliminate an existential
  373. % quantifier in front of a quantifier free formula. [psi] is a
  374. % formula, [x] is the quantified variable. Returns a quantifier
  375. % free formula equivalent to $\exists x \psi()$.
  376. begin scalar simpl,normpsi,elimdata;
  377. % Debug output
  378. if pasf_verbosep() then <<
  379. prin2 "Eliminating subformula: ";
  380. print psi;
  381. prin2 "Elimination variable: ";
  382. print x
  383. >>;
  384. % Trivial case check
  385. %
  386. % /TODO bad solution
  387. if not (x memq cl_fvarl1 psi) then <<
  388. if !*rlverbose then ioto_prin2 "*";
  389. return psi
  390. >>;
  391. if !*rlverbose then ioto_prin2 "e";
  392. % Computing the elimination normal form
  393. normpsi := pasf_elimnf(psi,x);
  394. % Getting the elimination data of psi
  395. elimdata := pasf_canrep normpsi;
  396. % Computing the quantifier free equivalent
  397. simpl := pasf_rednf if null elimdata_repr elimdata then
  398. pasf_substfc(normpsi,elimdata)
  399. else
  400. pasf_substf(normpsi,elimdata);
  401. return simpl
  402. end;
  403. procedure pasf_canrep(f);
  404. % Presburger arithmetic standard form search for canonical
  405. % representants. [f] a formula in elimination normal form with only
  406. % range predicates. Returns the elimindation data structure
  407. % elimdata.
  408. elimdata_join pasf_canrep1(f,nil);
  409. procedure pasf_canrep1(f,bvar);
  410. % Presburger arithmetic standard form search for canonical
  411. % representants subroutine. [f] a formula in elimination normal
  412. % form with only range predicates, [bvar] is the list of bounded
  413. % variables. Returns the elimindation data structure elimdata.
  414. if rl_quap rl_op f then
  415. % Formula should be pnf'ed first
  416. rederr{"pasf_canrep : Quantifier inside a formula matrix"}
  417. else
  418. if rl_bquap rl_op f then
  419. % Removing bounded quantifiers and adding new bounded
  420. % variable to the variable list.
  421. pasf_canrep1(rl_mat f,(rl_var f) . bvar)
  422. else
  423. if rl_boolp rl_op f then
  424. for each subf in rl_argn f join
  425. pasf_canrep1(subf,bvar)
  426. else
  427. % We are now sure to have no nested range predicates
  428. {pasf_compeld(f,bvar)};
  429. procedure pasf_compeld(atf,bvar);
  430. % Presburger arithmetic standard form compute elimination
  431. % data. [atf] is an atomic formula, [bvar] is the list of bounded
  432. % variables by range predicates. Returns the elimination data.
  433. begin scalar op,n,m,max_s,min_s,repr,a_i;
  434. % Avoiding formulas with no quantified variable inside
  435. if null pasf_leadc atf then
  436. return elimdata_new(nil,1,1,nil,nil,nil);
  437. % Getting the operator
  438. op := pasf_opn atf;
  439. n := 1;
  440. m := 1;
  441. max_s := nil;
  442. min_s := nil;
  443. repr := nil;
  444. if op memq '(cong ncong) then
  445. m := lcm(m,pasf_m atf)
  446. else if op memq '(equal neq leq geq lessp greaterp) then <<
  447. n := lcm(n,pasf_leadc atf);
  448. a_i := pasf_arg2r atf;
  449. % Substituting k's into a_i
  450. for each var in bvar do
  451. a_i := numr subf(a_i,{(var . nil)});
  452. % Debug output
  453. if pasf_verbosep() then <<
  454. prin2 "s_i = ";
  455. print pasf_const a_i
  456. >>;
  457. max_s := pasf_const a_i;
  458. min_s := pasf_const a_i;
  459. repr := {pasf_mk2(pasf_op atf,pasf_arg2l atf,a_i)}
  460. >>;
  461. % Debug output
  462. if pasf_verbosep() then <<
  463. prin2 "lcm(n_i) = ";
  464. print n;
  465. prin2 "lcm(m_i) = ";
  466. print m;
  467. prin2 "max_s = ";
  468. print max_s;
  469. prin2 "min_s = ";
  470. print min_s
  471. >>;
  472. return elimdata_new(repr,n,m,max_s,min_s,nil)
  473. end;
  474. procedure pasf_consteln(atf);
  475. % Presburger arithmetic standard form constant part of an atomic
  476. % formula in elimination normal form. [atf] is an atomic formula in
  477. % elimination normal form. Returns the constant part of [atf].
  478. pasf_const pasf_arg2r atf;
  479. procedure pasf_substfc(psi,elimdata);
  480. % Presburger arithmetic standard form subsitute formula with only
  481. % congruences. [psi] is the formula in elimination normal form,
  482. % [elimdata] is the elimiation data. Returns a quantifier free
  483. % formula equivalent to $ex(x,psi)$.
  484. begin scalar m;
  485. m := addf(elimdata_m elimdata,negf 1);
  486. % Debug output
  487. if pasf_verbosep() then <<
  488. prin2 "m = ";
  489. print m
  490. >>;
  491. return pasf_exprng pasf_substfc1(m,psi)
  492. end;
  493. procedure pasf_substfc1(m,psi);
  494. % Presburger arithmetic standard form subsitute formula with only
  495. % congruences subprocedure. [m] is the upper range for the range
  496. % predicate (SF), [psi] is the formula in elimination normal
  497. % form. Returns a range predicate bounded formula.
  498. begin scalar subs,rng,k;
  499. k := pasf_newvar psi;
  500. % Debug output
  501. if pasf_verbosep() then <<
  502. prin2 "Creating new variable ";
  503. print k;
  504. prin2 "m = ";
  505. print m
  506. >>;
  507. subs := cl_apply2ats1(psi,'pasf_substf2,{k,1,nil});
  508. rng := pasf_mkrng(k,0,if m then m else 0);
  509. if m then
  510. return rl_mkbq('bex,k,rng,rl_mkn('and,{subs}))
  511. else
  512. return subs
  513. end;
  514. procedure pasf_substf(psi,elimdata);
  515. % Presburger arithmetic standard form subsitute formula. [psi] is
  516. % the formula in elimination normal form and [elimdata] is the
  517. % elimination data. Returns a quantifier free formula equivalent to
  518. % $ex(x,psi)$.
  519. begin scalar n_prime,s,m;
  520. s := pasf_ceil(addf(elimdata_min_si elimdata,
  521. negf elimdata_min_si elimdata),2);
  522. % Debug output
  523. if pasf_verbosep() then <<
  524. prin2 "s = ";
  525. print s
  526. >>;
  527. n_prime := elimdata_n elimdata;
  528. % Debug output
  529. if pasf_verbosep() then <<
  530. prin2 "n' = ";
  531. print n_prime
  532. >>;
  533. m := elimdata_m elimdata;
  534. % Debug output
  535. if pasf_verbosep() then <<
  536. prin2 "m = ";
  537. print m
  538. >>;
  539. % For each canonical representant in psi
  540. return pasf_rednf rl_mkn('or,
  541. for each atf in elimdata_repr elimdata collect
  542. pasf_exprng
  543. if null pasf_arg2l atf then
  544. pasf_substf1(0,psi,atf)
  545. else
  546. pasf_substf1(multf(pasf_leadc atf,
  547. addf(s,*lcm(n_prime,m))),psi,atf));
  548. end;
  549. procedure pasf_substf1(t_j,psi,atf);
  550. % Presburger arithmetic standard form subsitute formula
  551. % subprocedure. [t_j] is the range for the range predicate, [psi]
  552. % is the formula in elimination normal form and [atf] is of one of
  553. % the canonical representants of [psi]. Returns a bounded formula.
  554. begin scalar cong,subs,rng,leadc,k;
  555. k := pasf_newvar psi;
  556. % Debug output
  557. if pasf_verbosep() then <<
  558. prin2 "Creating new variable ";
  559. print k
  560. >>;
  561. % Debug output
  562. if pasf_verbosep() then <<
  563. prin2 "t_j = ";
  564. print t_j
  565. >>;
  566. leadc := pasf_leadc atf;
  567. cong := pasf_mk2(pasf_mkop('cong,leadc),
  568. addf(pasf_arg2r atf,numr simp k),nil);
  569. subs := cl_apply2ats1(psi,'pasf_substf2,
  570. {k,leadc,pasf_arg2r atf});
  571. if null t_j then
  572. rederr{"pasf_substf1 : t_j is 0"}
  573. else
  574. rng := pasf_mkrng(k,-t_j,t_j);
  575. return rl_mkbq('bex,k,rng,rl_mkn('and,subs . {cong}))
  576. end;
  577. procedure pasf_substf2(atf,k,n_j,a_j);
  578. % Presburger arithmetic standard form subsitute formula
  579. % subprocedure. [psi] is an atomic formula in elimination normal
  580. % form, [k] is the range variable, [n_j] and [a_j] are the
  581. % substitution parameters. Returns the substituted atomic formula.
  582. begin scalar n_i,a_i;
  583. n_i := pasf_leadc atf;
  584. % Returning unchanged formula if no quantified variable in the
  585. % formula.
  586. if null n_i then return atf;
  587. a_i := pasf_arg2r atf;
  588. return if pasf_opn(atf) memq '(cong ncong) then
  589. pasf_mk2(pasf_mkop(pasf_opn atf,multf(pasf_m atf,n_j)),
  590. addf(multf(n_i,a_j),multf(n_i,numr simp k)),
  591. multf(n_j,a_i))
  592. else
  593. pasf_mk2(pasf_mkop(pasf_opn atf,0),
  594. addf(multf(n_i,a_j),multf(n_i,numr simp k)),
  595. multf(n_j,a_i));
  596. end;
  597. procedure pasf_leadc(atf);
  598. % Presburger arithmetic standard form leading coeficient of a
  599. % elimination normal form. [atf] is an atomic formula in
  600. % elimination normal form. Returns the leading coeficient.
  601. if domainp pasf_arg2l atf then
  602. % /FIXME Warning, could be a trap, because only nil possible
  603. pasf_arg2l atf
  604. else
  605. lc pasf_arg2l atf;
  606. procedure pasf_expand(f);
  607. % Presburger arithmetic standard form expand a formula with range
  608. % predicates. [f] is a formula with range predicates. Returns an
  609. % equivalent formula without range predicates.
  610. cl_simpl(pasf_exprng1 f,nil,-1);
  611. procedure pasf_exprng(f);
  612. % Presburger arithmetic standard form expand range predicate. [f]
  613. % is a formula bounded by a range quantifier. Returns an equivalent
  614. % quantifier free formula.
  615. if !*rlpasfrangeexpand then
  616. % Redlog normal form needed here because this function is called
  617. % inside the QE process, where the formulas are not neccesary in
  618. % redlog normal form.
  619. pasf_expand pasf_rednf f
  620. else
  621. f;
  622. procedure pasf_exprng1(f);
  623. % Presburger arithmetic standard form expand bounded
  624. % quantifier. [f] is a formula bounded only by bounded
  625. % quantifiers. Returns an equivalent quantifier free formula.
  626. if rl_bquap rl_op f then
  627. pasf_exprng2 rl_mkbq(rl_op f,rl_var f,rl_b f,
  628. cl_simpl(pasf_exprng1 rl_mat f,nil,-1))
  629. else
  630. if rl_boolp rl_op f then
  631. rl_mkn(rl_op f,for each subf in rl_argn f collect
  632. cl_simpl(pasf_exprng1 subf,nil,-1))
  633. else
  634. f;
  635. procedure pasf_exprng2(f);
  636. % Presburger arithmetic standard form expand bounded
  637. % quantifier. [f] is a formula bounded only by one bounded
  638. % quantifier. Returns an equivalent quantifier free formula.
  639. begin scalar evaltype,terml;
  640. % Long or or long and check
  641. if rl_op f eq 'bex then
  642. evaltype := 'or
  643. else if rl_op f eq 'ball then
  644. evaltype := 'and
  645. else
  646. % Unknown operator
  647. rederr{"pasf_expand : unknown or illegal quantifier",rl_op f};
  648. % Building the interval to substitute into
  649. terml := pasf_b2terml(rl_b f,rl_var f);
  650. return rl_mkn(evaltype,
  651. for each j in terml collect
  652. pasf_subfof(rl_var f,j,rl_mat f));
  653. end;
  654. procedure pasf_subfof(var,ex,f);
  655. % Presburger arithmetic standard form substitute into a formula.
  656. % [var] is the variable to substitute, [ex] is the expression to
  657. % substitute and [f] is the formula. Returns the formula where
  658. % every occurence of [var] is substituted by [ex].
  659. cl_apply2ats1(f,'pasf_subfof1,{var,ex});
  660. procedure pasf_subfof1(atf,var,ex);
  661. % Presburger arithmetic standard form substitute into a formula
  662. % subroutinue. [atf] is an atomic formula, [var] is the variable to
  663. % substitute and [ex] is the expression to substitute. Returns an
  664. % atomic formula where every occurence of [var] is substituted by
  665. % [ex].
  666. pasf_mk2(pasf_op atf,
  667. numr subf(pasf_arg2l atf,{(var . ex)}),
  668. numr subf(pasf_arg2r atf,{(var . ex)}));
  669. procedure pasf_newvar(f);
  670. % Presburger arithmetic standard form new variable generation. [f]
  671. % is a formula. Returns a new variable which is not present in [f].
  672. intern gensym();
  673. procedure pasf_newvar1(f);
  674. % Presburger arithmetic standard form new variable generation. [f]
  675. % is a formula. Returns a new variable which is not present in [f].
  676. begin scalar varl,varv,expld,l;
  677. varl := cl_varl pasf_rednf f;
  678. varv := 0;
  679. % Checking only the whole varlist
  680. for each var in append(car varl,cdr varl) do <<
  681. expld := explode var;
  682. % Looking for k variables
  683. if car expld eq 'k then <<
  684. l := implode cdr expld;
  685. if l >= varv then
  686. varv := l+1
  687. >>
  688. >>;
  689. return implode('k . explode(varv))
  690. end;
  691. endmodule;
  692. end;