pasfnf.red 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. % ----------------------------------------------------------------------
  2. % $Id: pasfnf.red,v 1.15 2003/11/05 13:27:14 lasaruk Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 2001 A. Dolzmann, A. Lasaruk, A. Seidl, and T. Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: pasfnf.red,v $
  7. % Revision 1.15 2003/11/05 13:27:14 lasaruk
  8. % Some major redlog programming rules applied to the code.
  9. % Formulas are made positive acc. to the current kernel order.
  10. %
  11. % Revision 1.14 2003/07/16 13:50:47 lasaruk
  12. % Debug messages removed. Bug in printing congurences removed.
  13. % Testfile adjusted to changes (working cases).
  14. %
  15. % Revision 1.13 2003/07/14 12:37:58 lasaruk
  16. % Common utilities attached and tested (see the testfile).
  17. %
  18. % Revision 1.12 2003/05/31 14:41:50 lasaruk
  19. % PNF corrected. examples added.
  20. %
  21. % Revision 1.11 2003/04/20 12:04:04 lasaruk
  22. % Completely removed any reference to range predicates (in input
  23. % also). PNF made shorter.
  24. %
  25. % Revision 1.10 2003/04/14 10:11:39 lasaruk
  26. % Changes to work with bounded quantifieres added . Simplification bug
  27. % (content) removed. Range predicates removed.
  28. %
  29. % Revision 1.9 2003/03/26 11:19:23 lasaruk
  30. % Formula runthrough rewritten as cl_atnum. True/false in rlexpabnd bug
  31. % removed. Some services added.
  32. %
  33. % Revision 1.8 2003/03/16 22:31:45 lasaruk
  34. % PNF-bug removed.
  35. %
  36. % Revision 1.7 2003/03/11 12:30:36 lasaruk
  37. % Bug in normal form computation fixed.
  38. %
  39. % Revision 1.6 2003/03/11 00:41:29 lasaruk
  40. % Prenex normal form with correct range predicate handling added. Documentation
  41. % extended. Todo section added.
  42. %
  43. % Revision 1.5 2003/03/04 09:33:23 lasaruk
  44. % Advanced simplification. PNF code attached but not used yet. Some code
  45. % migration. Documentation debugged.
  46. %
  47. % Revision 1.4 2003/02/28 11:55:40 lasaruk
  48. % Simplifier congruence bug removed. Switch siatadv now actively used.
  49. %
  50. % Revision 1.3 2003/02/18 16:02:12 seidl
  51. % Header for CVS added.
  52. %
  53. % ----------------------------------------------------------------------
  54. lisp <<
  55. fluid '(pasf_nf_rcsid!* pasf_nf_copyright!*);
  56. pasf_misc_rcsid!* := "$Id: pasfnf.red,v 1.15 2003/11/05 13:27:14 lasaruk Exp $";
  57. pasf_nf_copyright!* :=
  58. "Copyright (c) 1995-2002 by A. Dolzmann, A. Lasaruk, A. Seidl, and T. Sturm"
  59. >>;
  60. % Pasf normal forms. Submodule of pasf.
  61. module pasfnf;
  62. procedure pasf_rednf(f);
  63. % Presburger arithmetic standard form compute the redlog normal
  64. % form $a rel b \equiv a - b rel 0$ for each atomic formula in
  65. % [f]. [f] is a formula. Returns an [f] equivalent formula in
  66. % redlog normal form.
  67. cl_apply2ats1(f,'pasf_rednf1, nil);
  68. procedure pasf_rednf1(atf);
  69. % Presburger arithmetic standard form compute the redlog normal
  70. % form $a rel b \equiv a - b rel 0$ for an atomic formula. [atf] is
  71. % a formula. Returns an [atf] equivalent atomic formula in redlog
  72. % normal form.
  73. pasf_mk2(pasf_op atf, addf(pasf_arg2l atf, negf pasf_arg2r atf), nil);
  74. procedure pasf_elimnf(psi, x);
  75. % Presburger arithmetic standard form elimination normal
  76. % form. [psi] is a matrix of the original formula, [x] is a
  77. % quantified variable. Returns [psi] in elimination normal form for
  78. % the quantified variable.
  79. cl_apply2ats1(psi,'pasf_elimnf1, {x});
  80. procedure pasf_elimnf1(atf, x);
  81. % Presburger arithmetic standard form elimination normal form
  82. % subprocedure. [atf] is an atomic formula. Returns [atf] in
  83. % elimination normal form according to the quantified variable.
  84. begin scalar op,ex,oldkorder,leadc,reduct,exr;
  85. op := pasf_op atf;
  86. ex := addf(pasf_arg2l(atf),negf pasf_arg2r(atf));
  87. if x memq kernels ex then <<
  88. oldkorder := setkorder {x};
  89. exr := reorder ex;
  90. leadc := lc exr;
  91. reduct := red exr;
  92. setkorder oldkorder;
  93. reorder ex;
  94. if minusf leadc then
  95. return pasf_anegateat pasf_mk2(op,multf(leadc,numr simp x),
  96. negf reduct)
  97. else
  98. return pasf_mk2(op,multf(leadc,numr simp x),negf reduct);
  99. >> else
  100. return pasf_mk2(op,nil,negf ex);
  101. end;
  102. procedure pasf_pnf(phi);
  103. % Presburger arithmetic standard form prenex normal form. [phi] is
  104. % a formula. Returns a prenex formula equivalent to [phi]. The
  105. % number of quantifier changes in the result is minimal among all
  106. % formulas that can be obtained from [phi] by moving quantifiers to
  107. % the outside.
  108. pasf_pnf1 rl_nnf phi;
  109. procedure pasf_pnf1(phi);
  110. % Presburger arithmetic standard form prenex normal form
  111. % subroutine. [phi] is a positive formula that does not contain any
  112. % extended boolean operator. Returns a prenex formula equivalent
  113. % to [phi]. The number of quantifier changes in the result is
  114. % minimal among all formulas that can be obtained from [phi] by
  115. % moving quantifiers to the outside.
  116. <<
  117. if null cdr erg or pasf_qb car erg < pasf_qb cadr erg then
  118. car erg
  119. else
  120. cadr erg
  121. >> where erg=pasf_pnf2(cl_rename!-vars phi);
  122. procedure pasf_pnf2(phi);
  123. begin scalar op;
  124. op := rl_op phi;
  125. if rl_quap op then
  126. return pasf_pnf2!-quantifier(phi);
  127. if rl_junctp op or rl_bquap op then
  128. return pasf_pnf2!-junctor(phi);
  129. if rl_tvalp op then
  130. return {phi};
  131. if rl_cxp op then
  132. rederr{"pasf_pnf2():",op,"invalid as operator"};
  133. return {phi}
  134. end;
  135. procedure pasf_pnf2!-quantifier(phi);
  136. <<
  137. if (null cdr e) or (rl_op phi eq rl_op car e) then
  138. {rl_mkq(rl_op phi,rl_var phi,car e)}
  139. else
  140. {rl_mkq(rl_op phi,rl_var phi,cadr e)}
  141. >> where e=pasf_pnf2 rl_mat phi;
  142. procedure pasf_pnf2!-junctor(phi);
  143. begin scalar args,bv,bound,junctor,e,l1,l2,onlyex,onlyall,phi1,phi2;
  144. integer m,qb;
  145. junctor := rl_op phi;
  146. if rl_bquap junctor then <<
  147. bv := rl_var phi;
  148. bound := rl_b phi;
  149. args := {rl_mat phi};
  150. >> else
  151. args := rl_argn phi;
  152. e := for each f in args collect pasf_pnf2(f);
  153. onlyex := T; onlyall := T;
  154. for each ej in e do <<
  155. qb := pasf_qb car ej;
  156. if qb > m then <<
  157. m := qb; onlyex := T; onlyall := T
  158. >>;
  159. if cdr ej then <<
  160. l1 := (car ej) . l1;
  161. l2 := (cadr ej) . l2
  162. >> else <<
  163. l1 := (car ej) . l1;
  164. l2 := (car ej) . l2
  165. >>;
  166. if eqn(m,qb) then <<
  167. if rl_op car l1 eq 'all then onlyex := nil;
  168. if rl_op car l2 eq 'ex then onlyall := nil
  169. >>;
  170. >>;
  171. l1 := reversip l1;
  172. l2 := reversip l2;
  173. if eqn(m,0) then return {phi};
  174. if onlyex neq onlyall then
  175. if onlyex then
  176. return {pasf_interchange(l1,junctor,'ex,bv,bound)}
  177. else % [onlyall]
  178. return {pasf_interchange(l2,junctor,'all,bv,bound)};
  179. phi1 := pasf_interchange(l1,junctor,'ex,bv,bound);
  180. phi2 := pasf_interchange(l2,junctor,'all,bv,bound);
  181. if car phi1 eq car phi2 then
  182. return {phi1}
  183. else
  184. return {phi1,phi2}
  185. end;
  186. procedure pasf_qb(phi);
  187. begin scalar q,scan!-q; integer qb;
  188. while rl_quap(scan!-q := rl_op phi) do <<
  189. if scan!-q neq q then <<
  190. qb := qb + 1;
  191. q := scan!-q
  192. >>;
  193. phi := rl_mat phi
  194. >>;
  195. return qb
  196. end;
  197. procedure pasf_interchange(l,junctor,a,bv,bound);
  198. begin scalar ql,b,result;
  199. while pasf_contains!-quantifier(l) do <<
  200. l := for each f in l collect <<
  201. while rl_op f eq a do <<
  202. b := (rl_var f) . b;
  203. f := rl_mat f
  204. >>;
  205. f
  206. >>;
  207. ql := b . ql;
  208. b := nil;
  209. a := cl_flip a
  210. >>;
  211. a := cl_flip a;
  212. result := if rl_bquap junctor then
  213. % In case of a bounded quantifier the list of
  214. % arguments of a matrix is of length 1
  215. rl_mkbq(junctor,bv,bound,car l)
  216. else
  217. rl_mkn(junctor,l);
  218. for each b in ql do <<
  219. for each v in b do result := rl_mkq(a,v,result);
  220. a := cl_flip a
  221. >>;
  222. return result
  223. end;
  224. procedure pasf_contains!-quantifier(l);
  225. l and (rl_quap rl_op car l or pasf_contains!-quantifier cdr l);
  226. endmodule; % pasfnf
  227. end;