pasf.red 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. % ----------------------------------------------------------------------
  2. % $Id: pasf.red,v 1.57 2004/02/22 21:08:15 lasaruk Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 2002 Andreas Dolzmann, Andreas Seidl, and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: pasf.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/30 10:25:56 lasaruk
  13. % Fixed bug in pasf_resimpat that caused crashes after value substitutions
  14. %
  15. % Revision 1.55 2003/12/11 15:24:02 sturm
  16. % Switch on rlsusi for this context.
  17. %
  18. % Revision 1.54 2003/12/11 10:51:19 lasaruk
  19. % Smart simplification improoved.
  20. %
  21. % Revision 1.53 2003/12/02 14:36:31 sturm
  22. % Witch rlpasfvb off by default!
  23. %
  24. % Revision 1.52 2003/11/28 12:59:38 sturm
  25. % Print congruences as ~n~ instead of =n= to avoid confusion.
  26. %
  27. % Revision 1.51 2003/11/07 12:08:12 sturm
  28. % Improved printing.
  29. %
  30. % Revision 1.50 2003/11/05 13:56:19 lasaruk
  31. % Some more changes. pasf_content renamed to pasf_gcd with more
  32. % exact specificaton. lisp, symbolic and some "comments" are removed.
  33. %
  34. % Revision 1.49 2003/11/05 13:27:14 lasaruk
  35. % Some major redlog programming rules applied to the code.
  36. % Formulas are made positive acc. to the current kernel order.
  37. %
  38. % Revision 1.48 2003/10/16 16:17:38 lasaruk
  39. % Compiler error messages partially removed. All others are due
  40. % to the noncompleteness of packet.
  41. %
  42. % Revision 1.47 2003/10/12 19:41:11 sturm
  43. % Introduced rl_texmacs. The test "if get('or,'fancy!-infix!-symbol) = 218"
  44. % does not work in general since Windows does not guarantee to load
  45. % fmprint at startup.
  46. %
  47. % Revision 1.46 2003/10/12 18:26:14 sturm
  48. % Printing for both fmprint and tmprint in pasf now.
  49. % The test is done via "if get('or,'fancy!-infix!-symbol) = 218" for now.
  50. % IBALP printing remains to be adapted.
  51. %
  52. % Revision 1.45 2003/10/12 16:53:26 sturm
  53. % Texmacs fancy-printing crashed Windows. Substituted fancy procedures
  54. % by less fancy but working ones for now.
  55. %
  56. % Revision 1.44 2003/09/09 10:56:17 lasaruk
  57. % check for correct form improoved
  58. %
  59. % Revision 1.43 2003/09/02 07:22:41 seidl
  60. % Changed fancyprinting for TeXmacs from division to congruence.
  61. %
  62. % Revision 1.42 2003/08/28 15:30:40 lasaruk
  63. % Simplification verbose output done better. QE-Bug with truth values
  64. % corrected (will be done more effitient). Some fancy examples added.
  65. %
  66. % Revision 1.41 2003/08/27 16:10:04 lasaruk
  67. % Added switch rlpasfatfsimpvb to print out simplification steps if
  68. % simplification was really done. Check for correct PASF form added.
  69. %
  70. % Revision 1.40 2003/08/21 14:52:02 seidl
  71. % Fancy printing for bounded quantifiers (for TeXmacs).
  72. %
  73. % Revision 1.39 2003/08/19 09:36:11 seidl
  74. % Defined blackbox "bsatp" to be pasf_qff2ivl; there could be a more
  75. % efficient implementation. Introduced temporarly switch rlsiverbose,
  76. % which provides verbose output for rules (TV), (EQ), (SB), (SM), (STRB)
  77. % during simplification of bounded quantifiers.
  78. %
  79. % Revision 1.38 2003/08/14 21:44:38 seidl
  80. % Simplification of bounded quantifiers looks quite good now. A hack has
  81. % to be cured by a blackbox bsatp (bound sat. predicate). rlsism can be
  82. % savely turned on now in pasf, but there is a problem with susi and
  83. % congruences.
  84. %
  85. % Revision 1.37 2003/07/22 08:45:03 seidl
  86. % Improved simplifiations of equations and negated equations. Still there
  87. % can be done more. Simplification of atomic formulas has to be thoroughly
  88. % revised.
  89. %
  90. % Revision 1.36 2003/07/21 21:57:41 seidl
  91. % Intermediate check-in. Part of advanced smart simplification works
  92. % already.
  93. %
  94. % Revision 1.35 2003/07/17 16:12:20 lasaruk
  95. % Congruence bug removed. Printing methods for congruences rewritten.
  96. %
  97. % Revision 1.34 2003/07/16 13:50:47 lasaruk
  98. % Debug messages removed. Bug in printing congurences removed.
  99. % Testfile adjusted to changes (working cases).
  100. %
  101. % Revision 1.33 2003/07/16 12:43:44 lasaruk
  102. % conflicts resolved. pasf_simpl removed. implementation of
  103. % pasf_simplb and pasf_b2terml added and tested.
  104. % temporary method for pasf_b2terml in algebraic mode added.
  105. % empty list bug in pasf_ivl2qff removed.
  106. % expansion method uses now pasf_b2terml. some comments done
  107. % better.
  108. %
  109. % Revision 1.32 2003/07/15 12:40:41 seidl
  110. % Renamed pasf_iv2qff to pasf_ivl2qff and pasf_qff2iv to pasf_qff2ivl.
  111. % Provided algebraic mode access to simplb, ivl2qff, qdd2ivl. Changed
  112. % pasf_mkrng so intervals with same upper and lower bound result in an
  113. % equation. Fixed serious bug in pasf_prepat. Added cvs header to
  114. % pasf.tst. Todo Lasaruk: pasf_ivl2qff crashes with empty interval as
  115. % argument, see testfile.
  116. %
  117. % Revision 1.31 2003/07/14 12:37:58 lasaruk
  118. % Common utilities attached and tested (see the testfile).
  119. %
  120. % Revision 1.30 2003/06/04 12:33:40 lasaruk
  121. % Some smaller modifications.
  122. %
  123. % Revision 1.29 2003/05/22 22:00:58 lasaruk
  124. % DNF added.
  125. %
  126. % Revision 1.28 2003/05/17 16:27:56 lasaruk
  127. % Pasf simplification added. Some errors corrected.
  128. %
  129. % Revision 1.27 2003/04/20 12:04:04 lasaruk
  130. % Completely removed any reference to range predicates (in input
  131. % also). PNF made shorter.
  132. %
  133. % Revision 1.26 2003/04/14 10:11:39 lasaruk
  134. % Changes to work with bounded quantifieres added . Simplification bug
  135. % (content) removed. Range predicates removed.
  136. %
  137. % Revision 1.25 2003/03/26 11:19:23 lasaruk
  138. % Formula runthrough rewritten as cl_atnum. True/false in rlexpabnd bug
  139. % removed. Some services added.
  140. %
  141. % Revision 1.24 2003/03/11 00:41:29 lasaruk
  142. % Prenex normal form with correct range predicate handling added. Documentation
  143. % extended. Todo section added.
  144. %
  145. % Revision 1.23 2003/03/04 09:33:23 lasaruk
  146. % Advanced simplification. PNF code attached but not used yet. Some code
  147. % migration. Documentation debugged.
  148. %
  149. % Revision 1.22 2003/02/17 10:55:40 lasaruk
  150. % Stable full featured version
  151. %
  152. % Revision 1.21 2003/02/01 07:38:33 lasaruk
  153. % Recursive range expansion.
  154. %
  155. % Revision 1.20 2003/01/31 14:09:17 lasaruk
  156. % Test for range predicate check added.
  157. %
  158. % Revision 1.19 2003/01/30 11:48:26 sturm
  159. % Fixed bugs in operator declaration for congruences and range.
  160. % Changed output routine for range.
  161. %
  162. % Revision 1.18 2003/01/29 15:24:47 sturm
  163. % Added service rlexpand for context pasf. Had to split pasf_exprng for this.
  164. %
  165. % Revision 1.17 2003/01/29 15:06:52 sturm
  166. % Made rlsism a context switch. It has to be off in this context for now.
  167. %
  168. % Revision 1.16 2003/01/27 17:40:01 lasaruk
  169. % Switches renamed. Bugs in docu fixed.
  170. %
  171. % Revision 1.15 2003/01/26 17:49:37 lasaruk
  172. % Null congruence error added. Terms without quant. varl. stay
  173. % untouched. Bugs fixed.
  174. %
  175. % Revision 1.14 2003/01/21 10:43:34 lasaruk
  176. % logging changed to verbose
  177. %
  178. % Revision 1.13 2003/01/20 10:35:56 lasaruk
  179. % Switches pasf_logging and pasf_rangeexpand added.
  180. % WARNING: Actually block elimination does not work in not expansion mode.
  181. %
  182. % Revision 1.12 2002/12/23 07:06:33 lasaruk
  183. % operator pasf_opn and pasf_op differed
  184. %
  185. % Revision 1.11 2002/12/10 08:49:41 lasaruk
  186. % Correct elimination of an exist. quantifier call added.
  187. % Procedures debugged.
  188. %
  189. % Revision 1.10 2002/12/02 12:53:37 lasaruk
  190. % Elimination of one variable in front of an ex quantifier. Not really
  191. % worth looking at.
  192. %
  193. % Revision 1.9 2002/10/18 13:39:11 lasaruk
  194. % QE one variable preparation added. No bounded quantifiers first.
  195. %
  196. % Revision 1.8 2002/10/10 09:09:20 lasaruk
  197. % Range predicate implemented. Todo: logical negation of range predicate
  198. %
  199. % Revision 1.7 2002/10/02 14:31:19 lasaruk
  200. % Initial check in. Only dummy methods for advanced simplification first.
  201. %
  202. % Revision 1.6 2002/09/26 14:54:55 lasaruk
  203. % Errors corrected. Negation form implemented.
  204. %
  205. % Revision 1.5 2002/09/26 10:47:31 lasaruk
  206. % Prenex normal form functionality added. Tests follow.
  207. %
  208. % Revision 1.4 2002/09/19 08:49:42 lasaruk
  209. % All operators are binary. Before printing modulus of cong and ncong is
  210. % put directly after the operator. Ordering corrected.
  211. %
  212. % Revision 1.3 2002/09/16 10:49:55 lasaruk
  213. % Testversion for cong and ncong with dotted pair operator and 2 parameters.
  214. %
  215. % Revision 1.2 2002/08/23 08:07:19 seidl
  216. % Added service rl_atl with trival black box rl_ordatp.
  217. % Created module pasfmisc for this.
  218. %
  219. % Revision 1.1 2002/08/22 14:01:54 sturm
  220. % Initial check-in.
  221. %
  222. % ----------------------------------------------------------------------
  223. lisp <<
  224. fluid '(pasf_rcsid!* pasf_copyright!*);
  225. pasf_rcsid!* := "$Id: pasf.red,v 1.57 2004/02/22 21:08:15 lasaruk Exp $";
  226. pasf_copyright!* :=
  227. "Copyright (c) 1995-2002 by A. Dolzmann, A. Seidl, and T. Sturm"
  228. >>;
  229. module pasf;
  230. % Presburger arithmetic standard form. Main module. Algorithms on
  231. % first-order formulas over the language of rings together with
  232. % congruences, i.e., binary relations [equal], [neq], [cong], [ncong],
  233. % [leq], [geq], [lessp], [greaterp]. The terms are SF's.
  234. create!-package('(pasf pasfbnf pasfmisc pasfnf pasfsiat pasfqe pasfsism),nil);
  235. load!-package 'cl;
  236. load!-package 'rltools;
  237. imports rltools,cl;
  238. fluid '(!*rlverbose);
  239. flag('(pasf),'rl_package);
  240. % Switches
  241. switch rlpasfrangeexpand;
  242. switch rlpasfvb;
  243. switch rlpasfsimplify;
  244. switch rlsiverbose;
  245. switch rlsusitr;
  246. switch rlsusisubst;
  247. % Verboseswitch for atomic formula simplification
  248. switch rlpasfatfsimpvb;
  249. off1 'rlpasfrangeexpand;
  250. off1 'rlpasfvb;
  251. on1 'rlpasfsimplify;
  252. off1 'rlsiverbose;
  253. off1 'rlsusitr;
  254. off1 'rlpasfatfsimpvb;
  255. off1 'rlsusisubst;
  256. % Parameters
  257. put('pasf,'rl_params,'(
  258. (rl_subat!* . pasf_subat)
  259. (rl_subalchk!* . pasf_subalchk)
  260. (rl_eqnrhskernels!* . pasf_eqnrhskernels)
  261. (rl_simplat1!* . pasf_simplat1)
  262. (rl_ordatp!* . pasf_ordatp)
  263. (rl_op!* . pasf_op)
  264. (rl_simplb!* . pasf_simplb)
  265. (rl_varsubstat!* . pasf_varsubstat)
  266. (rl_negateat!* . pasf_negateat)
  267. (rl_bnfsimpl!* . cl_bnfsimpl)
  268. (rl_tordp!* . ordp)
  269. (rl_termmlat!* . pasf_termmlat)
  270. (rl_sacat!* . pasf_sacat)
  271. (rl_sacatlp!* . cl_sacatlp)
  272. (rl_varlat!* . pasf_varlat)
  273. (rl_smupdknowl!* . pasf_smwupdknowl)
  274. (rl_smrmknowl!* . pasf_smwrmknowl)
  275. (rl_smcpknowl!* . pasf_smwcpknowl)
  276. (rl_smmkatl!* . pasf_smwmkatl)
  277. (rl_smsimpl!-impl!* . cl_smsimpl!-impl)
  278. (rl_smsimpl!-equiv1!* . cl_smsimpl!-equiv1)
  279. (rl_susibin!* . pasf_susibin)
  280. (rl_susipost!* . pasf_susipost)
  281. (rl_susitf!* . pasf_susitf)
  282. (rl_bsatp!* . pasf_qff2ivl)
  283. ));
  284. % Services
  285. put('pasf,'rl_services,'(
  286. (rl_apnf!* . cl_apnf)
  287. (rl_atml!* . cl_atml)
  288. (rl_terml!* . cl_terml)
  289. (rl_termml!* . cl_termml)
  290. (rl_tnf!* . cl_tnf)
  291. (rl_varl!* . cl_varl)
  292. (rl_fvarl!* . cl_fvarl)
  293. (rl_bvarl!* . cl_bvarl)
  294. (rl_all!* . cl_all)
  295. (rl_ex!* . cl_ex)
  296. (rl_simpl!* . cl_simpl)
  297. (rl_atnum!* . cl_atnum)
  298. (rl_matrix!* . cl_matrix)
  299. (rl_qe!* . pasf_qe)
  300. (rl_expand!* . pasf_expand)
  301. (rl_atl!* . cl_atl)
  302. (rl_pnf!* . pasf_pnf)
  303. (rl_dnf!* . cl_dnf)
  304. (rl_cnf!* . cl_cnf)
  305. (rl_nnf!* . cl_nnf)
  306. (rl_simplb!* . pasf_simplb)
  307. (rl_b2terml!* . pasf_b2terml)
  308. (rl_b2atl!* . pasf_b2atl)
  309. ));
  310. % Switches
  311. put('pasf,'rl_cswitches,'(
  312. (rlsism . t)
  313. (rlsusi . t)));
  314. % Admin
  315. put('pasf,'simpfnname,'pasf_simpfn);
  316. put('pasf,'rl_prepat,'pasf_prepat);
  317. put('pasf,'rl_resimpat,'pasf_resimpat);
  318. put('pasf,'rl_lengthat,'pasf_lengthat);
  319. put('pasf,'rl_prepterm,'prepf);
  320. put('pasf,'rl_simpterm,'pasf_simpterm);
  321. algebraic infix equal;
  322. put('equal,'pasf_simpfn,'pasf_simpat);
  323. put('equal,'number!-of!-args,2);
  324. algebraic infix neq;
  325. put('neq,'pasf_simpfn,'pasf_simpat);
  326. put('neq,'number!-of!-args,2);
  327. put('neq,'rtypefn,'quotelog);
  328. newtok '((!< !>) neq);
  329. algebraic operator cong;
  330. put('cong,'prifn,'pasf_pricong);
  331. put('cong,'pasf_simpfn,'pasf_simpat);
  332. put('cong,'number!-of!-args,3);
  333. put('cong,'rtypefn,'quotelog);
  334. put('cong,'fancy!-prifn,'pasf_fancy!-pricong);
  335. procedure pasf_pricong(x);
  336. if null !*nat then
  337. 'failed
  338. else <<
  339. maprin cadr x;
  340. prin2!* " ~";
  341. maprin cadddr x;
  342. prin2!* "~ ";
  343. maprin caddr x
  344. >>;
  345. % alternative printing with |
  346. %symbolic procedure pasf_fancy!-pricong(c);
  347. % if null !*nat then
  348. % 'failed
  349. % else <<
  350. % maprin cadddr c;
  351. % if car c eq 'cong then
  352. % fancy!-prin2 "|"
  353. % else
  354. % fancy!-prin2 "\not|";
  355. % maprin cadr c;
  356. % >>;
  357. procedure pasf_fancy!-pricong(c);
  358. if rl_texmacsp() then
  359. pasf_fancy!-pricong!-texmacs c
  360. else
  361. pasf_fancy!-pricong!-fm c;
  362. procedure pasf_fancy!-pricong!-texmacs(c);
  363. if null !*nat then
  364. 'failed
  365. else <<
  366. maprin cadr c; % lhs
  367. if car c eq 'cong then
  368. fancy!-prin2 "\equiv"
  369. else
  370. fancy!-prin2 "\not\equiv";
  371. fancy!-prin2!-underscore();
  372. fancy!-prin2 "{";
  373. maprin cadddr c; % modulus
  374. fancy!-prin2 "}";
  375. fancy!-prin2 " ";
  376. maprin caddr c; % rhs
  377. >>;
  378. procedure pasf_fancy!-pricong!-fm(x);
  379. if null !*nat then
  380. 'failed
  381. else <<
  382. maprin cadr x;
  383. if car x eq 'cong then
  384. fancy!-special!-symbol(186,2)
  385. else <<
  386. fancy!-prin2 "/";
  387. fancy!-special!-symbol(186,2)
  388. >>;
  389. maprin caddr x;
  390. fancy!-prin2 " (";
  391. maprin cadddr x;
  392. fancy!-prin2 ")"
  393. >>;
  394. algebraic operator ncong;
  395. put('ncong,'prifn,'pasf_princong);
  396. put('ncong,'pasf_simpfn,'pasf_simpat);
  397. put('ncong,'number!-of!-args,3);
  398. put('ncong,'rtypefn,'quotelog);
  399. put('ncong,'fancy!-prifn,'pasf_fancy!-pricong);
  400. procedure pasf_princong(x);
  401. if null !*nat then
  402. 'failed
  403. else <<
  404. maprin cadr x;
  405. prin2!* " #";
  406. maprin cadddr x;
  407. prin2!* "# ";
  408. maprin caddr x
  409. >>;
  410. algebraic infix leq;
  411. put('leq,'pasf_simpfn,'pasf_simpat);
  412. put('leq,'number!-of!-args,2);
  413. put('leq,'rtypefn,'quotelog);
  414. algebraic infix geq;
  415. put('geq,'pasf_simpfn,'pasf_simpat);
  416. put('geq,'number!-of!-args,2);
  417. put('geq,'rtypefn,'quotelog);
  418. algebraic infix lessp;
  419. put('lessp,'pasf_simpfn,'pasf_simpat);
  420. put('lessp,'number!-of!-args,2);
  421. put('lessp,'rtypefn,'quotelog);
  422. algebraic infix greaterp;
  423. put('greaterp,'pasf_simpfn,'pasf_simpat);
  424. put('greaterp,'number!-of!-args,2);
  425. put('greaterp,'rtypefn,'quotelog);
  426. flag('(equal neq leq geq lessp greaterp),'spaced);
  427. flag('(pasf_simpat),'full);
  428. % Temporarily introduced algebraic mode interfaces
  429. operator rlqeex;
  430. procedure rlqeex(phi,k);
  431. rl_mk!*fof pasf_qeex(rl_simp phi,k);
  432. operator rlsimplb;
  433. procedure rlsimplb(phi,k);
  434. rl_mk!*fof rl_simplb(rl_simp phi,k);
  435. %rl_mk!*fof rl_simp phi;
  436. operator rlstrb;
  437. procedure rlstrb(phi);
  438. (if res then rl_mk!*fof res else '(list))
  439. where res = cl_simpl!-bqua!-strb(rl_simp phi,'unknown);
  440. operator rleq;
  441. procedure rleq(phi);
  442. (if res then rl_mk!*fof res else '(list))
  443. where res = cl_simpl!-bqua!-eq(rl_simp phi);
  444. operator rlsimplat;
  445. procedure rlsimplat(phi);
  446. rl_mk!*fof rl_simplat1(rl_simp phi,'dummy);
  447. operator rlivl2qff;
  448. procedure rlivl2qff(ivl,var);
  449. rl_mk!*fof pasf_ivl2qff(for each iv in cdr ivl collect
  450. cadr iv . caddr iv,var);
  451. operator rlqff2ivl;
  452. procedure rlqff2ivl(f);
  453. 'list . for each iv in pasf_qff2ivl1(rl_simp f) collect
  454. {'list,car iv,cdr iv};
  455. operator rlb2terml;
  456. procedure rlb2terml(b, var);
  457. 'list . pasf_b2terml(rl_simp b, var);
  458. operator rlb2atl;
  459. procedure rlb2atl(b, var);
  460. 'list . for each at in rl_b2atl(rl_simp b, var) collect rl_mk!*fof at;
  461. % End of temporary methods
  462. procedure pasf_verbosep();
  463. % Presburger arithmetic verbose verbose switch. Returns true if the
  464. % main switch rlverbose is on and the secondary switch rlpasfvb is
  465. % on.
  466. !*rlverbose and !*rlpasfvb;
  467. procedure pasf_simpterm(u);
  468. % Presburger arithmetic simp term. [u] is Lisp Prefix. Returns
  469. % the [u] as a PASF term.
  470. numr simp u;
  471. procedure pasf_prepat(f);
  472. % Presburger arithmetic prep atomic formula. [f] is a PASF
  473. % atomic formula. Returns [f] in Lisp prefix form.
  474. if pasf_cong f then
  475. {pasf_opn f,prepf pasf_arg2l f,prepf pasf_arg2r f,pasf_m f}
  476. else
  477. pasf_opn f . for each arg in pasf_argn f collect prepf arg;
  478. procedure pasf_resimpat(f);
  479. % Presburger arithmetic resimp atomic formula. [f] is an PASF
  480. % atomic formula. Returns the atomic formula [f] with resimplified
  481. % terms.
  482. pasf_mkn(pasf_op f,for each arg in pasf_argn f collect
  483. numr resimp !*f2q arg);
  484. procedure pasf_lengthat(f);
  485. % Presburger arithmetic length of atomic formula. [f] is an
  486. % atomic formula. Returns a number, the length of [f].
  487. length pasf_argn f;
  488. procedure pasf_simpat(u);
  489. % Presburger arithmetic simp atomic formula. [u] is Lisp prefix.
  490. % Returns [u] as an atomic formula.
  491. begin scalar op,lhs,rhs,m,term,atf;
  492. op := car u;
  493. lhs := simp cadr u;
  494. if denr lhs neq 1 then
  495. typerr(u,"atomic formula");
  496. rhs := simp caddr u;
  497. if denr rhs neq 1 then
  498. typerr(u,"atomic formula");
  499. term := numr subtrsq(lhs,rhs);
  500. % Check for the correct term form. Method fails if
  501. % the term is not correct.
  502. tnf_expr2tnf term;
  503. % Now the formula term is surely correct
  504. if op memq '(cong ncong) then <<
  505. m := cadddr u;
  506. if not (numberp m) or eqn(m,0) then
  507. typerr(m,"modulus");
  508. return pasf_0mk2((op . numr simp m),term)
  509. >>;
  510. atf := pasf_0mk2(op,term);
  511. return atf;
  512. end;
  513. procedure pasf_opn(atf);
  514. % Presburger arithmetic operator name. [atf] is an atomic formula
  515. % $R(t_1,t_2)$. Returns the name of $R$.
  516. if pairp car atf then
  517. caar atf
  518. else
  519. car atf;
  520. procedure pasf_op(atf);
  521. % Presburger arithmetic operator. [atf] is an atomic formula
  522. % $R(t_1,t_2)$. Returns $R$.
  523. car atf;
  524. procedure pasf_mkop(op,m);
  525. % Presburger arithmetic make operator. [op] is one of the operators
  526. % [equal], [neq], [cong], [ncong], [leq], [geq], [lessp],
  527. % [greaterp]; m is a modulus. Returns $op$ if operator is not
  528. % [cong] or [ncong] and $(op . m)$ else.
  529. if op memq '(cong ncong) then
  530. (op . if null m then
  531. rederr{"Modulo 0 congruence created"}
  532. else
  533. m)
  534. else
  535. op;
  536. procedure pasf_atfp(f);
  537. % Presburger arithmetic atomic formula predicate. [f] is a
  538. % formula. Returns t is and only if [f] is an atomic formula.
  539. (pasf_opn f) memq '(equal neq leq geq lessp greaterp
  540. cong ncong);
  541. procedure pasf_cong(atf);
  542. % Presburger arithmetic congruence atomic formula. [atf] is an
  543. % atomic formula. Returns $t$ if the operator is [cong] or [ncong].
  544. pasf_opn(atf) memq '(cong ncong);
  545. procedure pasf_m(atf);
  546. % Presburger arithmetic modulus operator. [atf] is an atomic
  547. % formula $t_1 = t_2 ~(n)$. Returns $n$.
  548. cdar atf;
  549. procedure pasf_hasm(atf);
  550. % Presburger arithmetic has modulus operator. [atf] is an atomic
  551. % formula $t_1 = t_2 ~(n)$. Returns $true$ if and only if [atf]
  552. % is a congruence.
  553. pairp car atf;
  554. procedure pasf_arg2l(atf);
  555. % Presburger arithmetic binary operator left hand side argument.
  556. % [atf] is an atomic formula $R(t_1,t_2)$. Returns $t_1$.
  557. cadr atf;
  558. procedure pasf_arg2r(atf);
  559. % Presburger arithmetic binary operator right hand side argument.
  560. % [atf] is an atomic formula $R(t_1,t_2)$. Returns $t_2$.
  561. caddr atf;
  562. procedure pasf_argn(atf);
  563. % Presburger arithmetic n-ary operator argument list. [atf] is an
  564. % atomic formula $R(t_1,...,t_n)$. Returns the list
  565. % $(t_1,...,t_n)$.
  566. cdr atf;
  567. procedure pasf_mk2(op,lhs,rhs);
  568. % Presburger arithmetic make atomic formula for binary operator.
  569. % [op] is one of the operators [equal], [neq], [div], [sdiv],
  570. % [assoc], and [nassoc]; [lhs] and [rhs] are terms. Returns the
  571. % atomic formula $[op]([lhs],[rhs])$.
  572. {op,lhs,rhs};
  573. procedure pasf_0mk2(op,lhs);
  574. % Presburger arithmetic make zero right hand atomic formula for
  575. % binary operator. [op] is one of the operators [equal], [neq],
  576. % [div], [sdiv], [assoc], and [nassoc]; [lhs] is a term. Returns
  577. % the atomic formula $[op]([lhs],0)$.
  578. {op,lhs,nil};
  579. procedure pasf_mkn(op,argl);
  580. % Presburger arithmetic make atomic formula for n-ary operator.
  581. % [op] is one of the operators [equal], [neq], [div], [sdiv],
  582. % [assoc], and [nassoc]; [argl] is a list $(t_1,t_2)$ of terms.
  583. % Returns the atomic formula $[op](t_1,t_2)$.
  584. op . argl;
  585. procedure pasf_mkrng(bv,lr,ur);
  586. % Presburger arithmetic make range operator. [bv] is the variable
  587. % to bound; [lr] and [ur] are the bounds. Returns the range formula
  588. % $[lr] \leq [bv] \leq [ur]$.
  589. if domainp lr and domainp ur then
  590. if lr=ur then
  591. pasf_mk2('equal,numr simp bv,lr)
  592. else rl_mkn('and,{
  593. pasf_mk2('geq,numr simp bv,numr simp lr),
  594. pasf_mk2('leq,numr simp bv,numr simp ur)})
  595. else
  596. rederr{"pasf_mkrng : Bounds should be domain valued elements"};
  597. procedure pasf_mknrng(bv,lr,ur);
  598. % Presburger arithmetic make negated range operator. [bv] is the
  599. % variable to bound; [lr] and [ur] are the bounds. Returns the
  600. % negated range formula $[lr] \leq [bv] \leq [ur]$.
  601. if domainp lr and domainp ur then
  602. rl_mkn('or,{
  603. pasf_mk2('leq,numr simp bv,lr),
  604. pasf_mk2('geq,numr simp bv,ur)})
  605. else
  606. rederr{"pasf_mkrng : Bounds should be domain valued elements"};
  607. endmodule; % [pasf]
  608. end; % of file