clsimpl.red 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. % ----------------------------------------------------------------------
  2. % $Id: clsimpl.red,v 1.11 1999/04/13 13:11:01 sturm Exp $
  3. % ----------------------------------------------------------------------
  4. % Copyright (c) 1995-1999 Andreas Dolzmann and Thomas Sturm
  5. % ----------------------------------------------------------------------
  6. % $Log: clsimpl.red,v $
  7. % Revision 1.11 1999/04/13 13:11:01 sturm
  8. % Updated comments for exported procedures.
  9. %
  10. % Revision 1.10 1999/03/22 17:06:43 dolzmann
  11. % Changed copyright information.
  12. % Added and reformatted comments.
  13. %
  14. % Revision 1.9 1999/03/21 13:34:45 dolzmann
  15. % Added the cl-part of the super simplifier susi.
  16. %
  17. % Revision 1.8 1999/01/17 15:36:43 dolzmann
  18. % Corrected some typos in the comments.
  19. %
  20. % Revision 1.7 1997/08/24 16:14:56 sturm
  21. % Added procedure cl_sitheo using fluid !*rlsithok.
  22. % Added service rl_surep with black box rl_multsurep.
  23. % Added service rl_siaddatl.
  24. %
  25. % Revision 1.6 1996/10/07 11:45:55 sturm
  26. % Added fluids for CVS and copyright information.
  27. %
  28. % Revision 1.5 1996/09/05 11:50:11 dolzmann
  29. % Minor changes in procedure cl_simplat.
  30. %
  31. % Revision 1.4 1996/09/05 11:14:20 dolzmann
  32. % Fixed a bug in cl_simplat: atomic formulas are always simplified.
  33. %
  34. % Revision 1.3 1996/07/13 11:01:59 dolzmann
  35. % Fixed a bug in cl_simpl.
  36. % Introduced new black box rl_smcpknowl.
  37. % Removed procedure cl_cpknowl.
  38. % Added context independent black box implementations cl_smcpknowl,
  39. % cl_smrmknowl, cl_smupdknowl, cl_smmkatl, cl_smsimpl!-impl, and
  40. % cl_smsimpl!-equiv1.
  41. %
  42. % Revision 1.2 1996/03/25 08:50:55 sturm
  43. % Fixed a bug in procedure cl_simpl.
  44. %
  45. % Revision 1.1 1996/03/22 10:31:32 sturm
  46. % Moved and split.
  47. %
  48. % ----------------------------------------------------------------------
  49. lisp <<
  50. fluid '(cl_simpl_rcsid!* cl_simpl_copyright!*);
  51. cl_simpl_rcsid!* := "$Id: clsimpl.red,v 1.11 1999/04/13 13:11:01 sturm Exp $";
  52. cl_simpl_copyright!* := "(c) 1995-1999 by A. Dolzmann and T. Sturm"
  53. >>;
  54. module clsimpl;
  55. % Common logic simplification routines. Submodule of [cl]. Here the
  56. % standard simplifier is implemented.
  57. %DS
  58. % <theory> ::= (<atomic_formula>,...)
  59. procedure cl_simpl(f,atl,n);
  60. % Common logic simplify. [f] is a formula; [atl] is a list of
  61. % atomic formulas, which are considered to describe a theory; [n]
  62. % is an integer. Depends on switches [!*rlsism], [!*rlsichk],
  63. % [!*rlsiso], [!*rlsiidem]. Returns the identifier [inctheo] or a
  64. % formula. [inctheo] means that [atl] is inconsistent. Else the
  65. % result is [f], simplified (wrt. [atl]). For non-negative [n],
  66. % simplification stops at level [n].
  67. begin scalar w;
  68. if null !*rlsism then
  69. return cl_simpl1(f,nil,n,nil);
  70. atl := cl_sitheo atl;
  71. if atl eq 'inctheo then
  72. return 'inctheo;
  73. w := rl_smupdknowl('and,atl,nil,n+1);
  74. if w eq 'false then return 'inctheo;
  75. return cl_simpl1(f,w,n,nil)
  76. end;
  77. procedure cl_sitheo(atl);
  78. % Common logic simplify theory. [atl] is a THEORY. Returns either a
  79. % list $l$ of atomic formulas, or the identifier [inctheo]. In the
  80. % first case the conjunction over $l$ is equivalent to the
  81. % conjuction over [atl], and $l$ contains only simplified atomic
  82. % formulas. The return value [inctheo] means that the conjunction
  83. % over [atl] is equivalent to [false]. Accesses the fluid
  84. % [rlsithok], and returns [atl] in case that [rlsithok] is
  85. % non-[nil].
  86. begin scalar atf,w,natl,!*rlsiexpla;
  87. if !*rlsithok then
  88. return atl;
  89. while atl do <<
  90. atf := car atl;
  91. atl := cdr atl;
  92. w := cl_simplat(atf,nil);
  93. if w eq 'false then <<
  94. atf := 'inctheo;
  95. atl := nil
  96. >> else if w neq 'true then
  97. natl := w . natl
  98. >>;
  99. if atf eq 'inctheo then
  100. return 'inctheo;
  101. return natl
  102. end;
  103. procedure cl_simpl1(f,knowl,n,sop);
  104. % Common logic simplify. [f] is a formula; [knowl] is an IRL; [n]
  105. % is an integer; [sop] is a CL operator. Depends on switches
  106. % [!*rlsism], [!*rlsichk], [!*rlsiso], [!*rlsiidem]. Returns a
  107. % formula. Simplifies [f] recursively using [knowl].
  108. begin scalar op,result,w,newknowl;
  109. if eqn(n,0) then return f;
  110. op := rl_op f;
  111. if rl_tvalp op then return f;
  112. if rl_junctp op then
  113. return rl_smkn(op,cl_smsimpl!-junct(op,rl_argn f,knowl,n));
  114. if op eq 'not then <<
  115. result := cl_simpl1(rl_arg1 f,knowl,n-1,'not);
  116. if rl_tvalp result then return cl_flip result;
  117. if cl_atfp result then return rl_negateat result;
  118. return cl_negate!-invol(result)
  119. >>;
  120. if rl_quap op then <<
  121. if !*rlsism then knowl := rl_smrmknowl(knowl,rl_var f);
  122. result := cl_simpl1(rl_mat f,knowl,n-1,op);
  123. if rl_tvalp result then return result;
  124. return rl_mkq(op,rl_var f,result)
  125. >>;
  126. if op eq 'impl then
  127. return cl_smsimpl!-imprep(rl_arg2l f,rl_arg2r f,knowl,n);
  128. if op eq 'repl then
  129. return cl_smsimpl!-imprep(rl_arg2r f,rl_arg2l f,knowl,n);
  130. if op eq 'equiv then
  131. return cl_smsimpl!-equiv(rl_arg2l f,rl_arg2r f,knowl,n);
  132. w := cl_simplat(f,sop);
  133. if !*rlsism then <<
  134. op := rl_op w;
  135. if rl_junctp op then
  136. return rl_smkn(op,cl_smsimpl!-junct(op,rl_argn w,knowl,n));
  137. if rl_tvalp op then
  138. return w;
  139. % [w] is atomic.
  140. newknowl := rl_smupdknowl('and,{w},rl_smcpknowl knowl,n);
  141. if newknowl eq 'false then return 'false;
  142. w := rl_smmkatl('and,knowl,newknowl,n);
  143. return rl_smkn('and,w)
  144. >>;
  145. if w then return w;
  146. rederr {"cl_simpl1(): unknown operator",op}
  147. end;
  148. procedure cl_negate!-invol(f);
  149. % Common logic negate applying the law of involutivity. [f] is a
  150. % formula. Returns $\phi$ if [f] is of the form $\lnot \phi$,
  151. % $\lnot [f]$ else.
  152. if rl_op f eq 'not then rl_arg1 f else rl_mk1('not,f);
  153. procedure cl_gand!-col(fl,n,gand,knowl);
  154. % Common logic generic ['and] collect. [fl] is a list of formulas;
  155. % [n] is an integer; [gand] is one of ['and], ['or]; [knowl] is an
  156. % IRL. Depends on switch [!*rlsichk]. Returns a list $l$ of
  157. % simplified formulas such that $[gand](l)$ is equivalent to
  158. % $[gand]([fl])$. With [!*rlsichk] on, $l$ does not contain any
  159. % double entries. Moreover there are no truth values in $l$, and no
  160. % element of $l$ has [gand] as its top-level operator.
  161. begin scalar result,a,gtrue,gfalse;
  162. gtrue := cl_cflip('true,gand eq 'and);
  163. gfalse := cl_flip(gtrue);
  164. while fl do <<
  165. a := cl_simpl1(car fl,knowl,n-1,gand);
  166. fl := cdr fl;
  167. if a eq gfalse then <<
  168. result := {gfalse};
  169. fl := nil
  170. >> else if a neq gtrue then
  171. if rl_op a eq gand then <<
  172. if !*rlsichk then
  173. for each subf in rl_argn a do
  174. (if not (subf member result) then
  175. result := subf . result)
  176. else
  177. for each subf in rl_argn a do
  178. result := subf . result
  179. >> else
  180. if not (!*rlsichk and a member result) then
  181. result := a . result;
  182. >>;
  183. return if result then reversip result else {gtrue}
  184. end;
  185. procedure cl_smsimpl!-junct(op,junct,knowl,n);
  186. % Common logic smart simplify. [op] is one of [and], [or]; [junct]
  187. % is a list of formulas; [knowl] is an IRL; [n] is an integer.
  188. % Returns a list of formulas. Accesses the switch [!*rlsism]. With
  189. % [!*rlsism] on sophisticated simplifications are applied to
  190. % [junct].
  191. begin scalar break,w,atl,col,newknowl;
  192. if not !*rlsism then
  193. return cl_gand!-col(junct,n,op,nil);
  194. newknowl := rl_smcpknowl knowl;
  195. break := cl_cflip('false,op eq 'and);
  196. for each subf in junct do <<
  197. w := if cl_atfp subf then cl_simplat(subf,op) else subf;
  198. if cl_atfp w then atl := w . atl else col := w . col
  199. >>;
  200. newknowl := rl_smupdknowl(op,atl,newknowl,n);
  201. if newknowl eq 'false then return {break};
  202. return cl_smsimpl!-junct1(op,atl,reversip col,knowl,newknowl,n,break)
  203. end;
  204. procedure cl_smsimpl!-junct1(op,atl,col,knowl,newknowl,n,break);
  205. % Common logic smart simplify. [op] is one of [and], [or]; [atl] is
  206. % a list of atomic formulas; [col] is a list of complex formulas;
  207. % [knowl] and [newknowl] are IRL's; [n] is an integer; [break] is
  208. % one of [true], [false] corresponding to [op]. Returns a list of
  209. % formulas.
  210. begin scalar a,w,wop,argl,sicol,natl;
  211. while col do <<
  212. a := car col;
  213. col := cdr col;
  214. w := cl_simpl1(a,newknowl,n-1,op);
  215. wop := rl_op w;
  216. if wop eq break then <<
  217. a := break;
  218. col := nil
  219. >> else if wop eq op then <<
  220. argl := rl_argn w;
  221. while argl and cl_atfp car argl do <<
  222. natl := car argl . natl;
  223. argl := cdr argl
  224. >>;
  225. if !*rlsiidem and natl then <<
  226. col := nconc(reversip sicol,col);
  227. sicol := nil
  228. >>;
  229. sicol := nconc(sicol,reverse argl) % necessarily constructive!
  230. >> else if rl_cxp wop then
  231. (if wop neq cl_flip break then sicol := w . sicol)
  232. else << % [w] is atomic.
  233. if !*rlsiidem then <<
  234. col := nconc(reversip sicol,col);
  235. sicol := nil
  236. >>;
  237. natl := {w}
  238. >>;
  239. if natl then <<
  240. newknowl := rl_smupdknowl(op,natl,newknowl,n);
  241. if newknowl eq 'false then <<
  242. a := break;
  243. col := nil
  244. >>;
  245. natl := nil
  246. >>
  247. >>;
  248. if a eq break then return {break};
  249. return cl_smsimpl!-junct2(op,sicol,knowl,newknowl,n,break)
  250. end;
  251. procedure cl_smsimpl!-junct2(op,sicol,knowl,newknowl,n,break);
  252. % Common logic smart simplify. [op] is one of [and], [or]; [col] is
  253. % a list of complex formulas; [knowl] and [newknowl] are IRL's; [n]
  254. % is an integer; [break] is one of [true], [false] corresponding to
  255. % [op]. Returns a list of formulas.
  256. begin scalar atl,w;
  257. atl := rl_smmkatl(op,knowl,newknowl,n);
  258. if !*rlsichk then <<
  259. w := sicol;
  260. sicol := nil;
  261. for each x in w do sicol := lto_insert(x,sicol)
  262. >> else
  263. sicol := reversip sicol;
  264. if !*rlsiso then atl := sort(atl,'rl_ordatp);
  265. w := nconc(atl,sicol);
  266. if w then return w;
  267. return {cl_flip break}
  268. end;
  269. procedure cl_smsimpl!-imprep(prem,concl,knowl,n);
  270. % Common logic smart simplify implication/replication. [prem] and
  271. % [concl] are formulas; [knowl] is an IRL; [n] is an integer.
  272. % Returns a formula equivalent to [prem impl concl] assuming
  273. % [knowl].
  274. begin
  275. if not !*rlsism then
  276. return cl_imprep!-col(prem,concl,knowl,n);
  277. if cl_atfp prem then
  278. prem := cl_simplat(prem,'prem);
  279. if cl_atfp concl then
  280. concl := cl_simplat(concl,'concl);
  281. if prem eq 'false or concl eq 'true then
  282. return 'true;
  283. return cl_smsimpl!-imprep1(prem,concl,knowl,n)
  284. end;
  285. procedure cl_imprep!-col(prem,concl,knowl,n);
  286. begin scalar w;
  287. prem := cl_simpl1(prem,knowl,n-1,'prem);
  288. concl := cl_simpl1(concl,knowl,n-1,'concl);
  289. if w := cl_smtvchk!-impl(prem,concl) then
  290. return w;
  291. if prem = concl then return 'true;
  292. return rl_mk2('impl,prem,concl)
  293. end;
  294. procedure cl_smsimpl!-imprep1(prem,concl,knowl,n);
  295. % Common logic smart simplify implication/replication. [prem] and
  296. % [concl] are formulas; [knowl] is an IRL; [n] is an integer.
  297. % Returns a formula equivalent to [prem impl concl] assuming
  298. % [knowl].
  299. begin scalar w;
  300. if cl_atfp prem then
  301. return cl_smsimpl!-imprep!-atprem(prem,concl,knowl,n);
  302. if cl_atfp concl then
  303. return cl_smsimpl!-imprep!-atconcl(prem,concl,knowl,n);
  304. prem := cl_simpl1(prem,knowl,n-1,'prem);
  305. concl := cl_simpl1(concl,knowl,n-1,'concl);
  306. if w := cl_smtvchk!-impl(prem,concl) then
  307. return w;
  308. if cl_cxfp prem and cl_cxfp concl then <<
  309. if !*rlsichk and prem = concl then
  310. return 'true;
  311. return rl_mk2('impl,prem,concl)
  312. >>;
  313. return cl_smsimpl!-imprep1(prem,concl,knowl,n)
  314. end;
  315. procedure cl_smtvchk!-impl(prem,concl);
  316. if prem eq 'true then
  317. concl
  318. else if concl eq 'false then
  319. cl_simpl(rl_mk1('not,prem),nil,1)
  320. else if prem eq 'false or concl eq 'true then
  321. 'true;
  322. procedure cl_smsimpl!-imprep!-atprem(atprem,concl,knowl,n);
  323. begin scalar w,newknowl;
  324. newknowl := rl_smcpknowl knowl;
  325. if cl_atfp concl then
  326. return rl_smsimpl!-impl(atprem,concl,knowl,newknowl,n);
  327. newknowl := rl_smupdknowl('and,{atprem},newknowl,n);
  328. concl := cl_simpl1(concl,newknowl,n-1,'concl);
  329. if w := cl_smtvchk!-impl(atprem,concl) then
  330. return w;
  331. if cl_atfp concl then
  332. return rl_smsimpl!-impl(atprem,concl,knowl,newknowl,n);
  333. return rl_mk2('impl,atprem,concl)
  334. end;
  335. procedure cl_smsimpl!-imprep!-atconcl(prem,atconcl,knowl,n);
  336. % CL smart simplify implication/replication with atomic formula
  337. % conclusion. [prem] is a complex formula; [atconcl] is a
  338. % simplified atomic formula; [knowl] is an IRL; [n] is an integer.
  339. % Returns a formula.
  340. begin scalar w,newknowl;
  341. newknowl := rl_smupdknowl('or,{atconcl},rl_smcpknowl knowl,n);
  342. prem := cl_simpl1(prem,newknowl,n-1,'prem);
  343. if w := cl_smtvchk!-impl(prem,atconcl) then
  344. return w;
  345. if cl_atfp prem then
  346. return rl_smsimpl!-impl(prem,atconcl,knowl,newknowl,n);
  347. return rl_mk2('impl,prem,atconcl)
  348. end;
  349. procedure cl_smtvchk!-equiv(lhs,rhs);
  350. if lhs eq 'true then
  351. rhs
  352. else if rhs eq 'true then
  353. lhs
  354. else if lhs eq 'false then
  355. cl_simpl(rl_mk1('not,rhs),nil,1)
  356. else if rhs eq 'false then
  357. cl_simpl(rl_mk1('not,lhs),nil,1);
  358. procedure cl_smsimpl!-equiv(lhs,rhs,knowl,n);
  359. begin scalar w,newknowl;
  360. lhs := cl_simpl1(lhs,knowl,n-1,'equiv);
  361. rhs := cl_simpl1(rhs,knowl,n-1,'equiv);
  362. if w := cl_smtvchk!-equiv(lhs,rhs) then
  363. return w;
  364. if !*rlsichk and lhs = rhs then
  365. return 'true;
  366. if null !*rlsism or cl_cxfp lhs or cl_cxfp rhs then <<
  367. if cl_ordp(lhs,rhs) then
  368. return rl_mk2('equiv,lhs,rhs);
  369. return rl_mk2('equiv,rhs,lhs)
  370. >>;
  371. newknowl := rl_smcpknowl(knowl);
  372. return rl_smsimpl!-equiv1(lhs,rhs,knowl,newknowl,n)
  373. end;
  374. procedure cl_ordp(f1,f2);
  375. % Common logic order predicate. [f1] and [f2] are formulas. Returns
  376. % [T] or [nil]. [nil] is returned if [f1] and [f2] are atomic
  377. % formulas and [f1] is less than [f2] wrt. [rl_ordatp].
  378. cl_cxfp f2 or (cl_atfp f1 and rl_ordatp(f1,f2));
  379. procedure cl_simplat(atf,sop);
  380. % Common logic simplify atomic formula. [atf] is an atomic formula;
  381. % [sop] is a CL operator. Returns a quantifier-free formula
  382. % equivalent to [atf].
  383. if not !*rlidentify then
  384. rl_simplat1(atf,sop)
  385. else
  386. cl_apply2ats(rl_simplat1(atf,sop),'cl_identifyat);
  387. procedure cl_identifyat(atf);
  388. % Common logic identify atomic formula. [atf] is an atomic formula.
  389. % Returns an atomic formula equal to [atf].
  390. begin scalar w;
  391. if rl_tvalp atf then return atf;
  392. if (w := atf member cl_identify!-atl!*) then return car w;
  393. cl_identify!-atl!* := atf . cl_identify!-atl!*;
  394. return atf
  395. end;
  396. % The following code implements a "generic smart simplification". All
  397. % black boxes for the smart simplification are implemented generically
  398. % using only a non generic black box rl_negateat. rl_negateat must
  399. % return an atomic formula.
  400. procedure cl_smcpknowl(knowl);
  401. % Common logic smart simplifier copy knowledge. [knowl] is a
  402. % knowledge base. Returns a toplevel copy of [knowl].
  403. for each p in knowl collect p;
  404. procedure cl_smrmknowl(knowl,v);
  405. % Common logic smart simplifier remove knowledge. [knowl] is a
  406. % knowledge base; [v] is a variable. Returns a knowledge base.
  407. % Removes all knowledge involving [v] from the knowledge base.
  408. nil;
  409. procedure cl_smupdknowl(op,atl,knowl,n);
  410. % Common logic smart simplifier update knowledge. [op] is one of
  411. % the operators [and], [or]; [atl] is a list of atomic formulas;
  412. % [knowl] is knowledge base; [n] is an integer. Returns a knowledge
  413. % base. If [op] is [and], then all knowledge in [atl] is added to
  414. % the [knowl] with the tag [n]. If [op] is [or], then the negation
  415. % of all knowledge in [atl] is added to [knowl].
  416. begin scalar at;
  417. while atl do <<
  418. at := car atl;
  419. atl := cdr atl;
  420. knowl := cl_smupdknowl1(op,at,knowl,n);
  421. if knowl eq 'false then <<
  422. atl := nil;
  423. at := 'break
  424. >>
  425. >>;
  426. if at eq 'break then
  427. return 'false
  428. else
  429. return knowl
  430. end;
  431. procedure cl_smupdknowl1(op,at,knowl,n);
  432. begin scalar ent,contra;
  433. if op eq 'or then <<
  434. ent := rl_negateat at;
  435. contra := at
  436. >> else <<
  437. ent := at;
  438. contra := rl_negateat at
  439. >>;
  440. if assoc(contra,knowl) then
  441. return 'false;
  442. if assoc(ent,knowl) then
  443. return knowl;
  444. return knowl := (ent . n) . knowl
  445. end;
  446. procedure cl_smmkatl(op,knowl,newknowl,n);
  447. % Common logic smart simplifier make atomic formula list. [op] is
  448. % one of the operators [and], [or]; [knowl], [newknowl] are
  449. % knowledge bases; [n] is an integer. Returns a list of atomic
  450. % formulas. All knowledge tagged with [n] is extraced from
  451. % [newknowl] and returned as a list of atomic formulas.
  452. begin scalar res;
  453. res := for each pair in newknowl join
  454. if cdr pair = n then {car pair};
  455. if op eq 'or then
  456. res := for each at in res collect rl_negateat at;
  457. return res
  458. end;
  459. procedure cl_smsimpl!-impl(atprem,atconcl,oldknowl,newknowl,n);
  460. % Common logic smart simplifier simplify implication. [atprem] and
  461. % [atconcl] are atomic formulas; [oldknowl] and [newknowl] are
  462. % knowledge bases; [n] is an integer. Returns a formula.
  463. begin scalar w;
  464. w := cl_simpl1(rl_nnf rl_mk2('impl,atprem,atconcl),oldknowl,n,nil);
  465. if rl_tvalp w or cl_atfp w then
  466. return w;
  467. atprem := cl_simpl1(atprem,oldknowl,n,'prem);
  468. atconcl := cl_simpl1(atconcl,oldknowl,n,'concl);
  469. return rl_mk2('impl,atprem,atconcl)
  470. end;
  471. procedure cl_smsimpl!-equiv1(lhs,rhs,oldknowl,newknowl,n);
  472. % Common logic smart simplifier simplify equivalence. [lhs] and
  473. % [rhs] are atomic formulas; [oldknowl] and [newknowl] are
  474. % knowledge bases; [n] is an integer. Returns a formula.
  475. begin scalar w,x;
  476. w := cl_simpl1(rl_nnf rl_mk2('equiv,lhs,rhs),oldknowl,n,nil);
  477. if rl_tvalp w or cl_atfp w then
  478. return w;
  479. x := rl_argn w;
  480. if cl_atfp car x and cl_atfp cadr x and null cddr x then
  481. return w;
  482. lhs := cl_simpl1(lhs,oldknowl,n,'equiv);
  483. rhs := cl_simpl1(rhs,oldknowl,n,'equiv);
  484. if cl_ordp(lhs,rhs) then
  485. return rl_mk2('equiv,lhs,rhs);
  486. return rl_mk2('equiv,rhs,lhs)
  487. end;
  488. procedure cl_siaddatl(atl,c);
  489. % Common logic simplifying add atomic formula list. [atl] is a list
  490. % of atomic formulas; [c] is [true], a simplified atomic formula,
  491. % or a simplified conjunction of atomic formulas. Returns [true],
  492. % [false], a simplified atomic formula, or a simplified conjunction
  493. % of atomic formulas. The result is equivalent to $\bigwedge [atl]
  494. % \land [c]$.
  495. begin scalar w,sicd;
  496. atl := cl_sitheo atl;
  497. if atl eq 'inctheo then
  498. return 'false;
  499. sicd := if c eq 'true then
  500. nil
  501. else if cl_cxfp c then
  502. rl_argn c
  503. else
  504. {c};
  505. w := rl_smupdknowl('and,nconc(atl,sicd),nil,1);
  506. if w eq 'false then
  507. return 'false;
  508. w := rl_smmkatl('and,nil,w,1);
  509. if !*rlsiso then w := sort(w,'rl_ordatp);
  510. return rl_smkn('and,w)
  511. end;
  512. %DS
  513. % <KNOWL> ::= (...,<LAT>,...)
  514. % <LAT> ::= (<ATOMIC FORMULA> . <LABEL>)
  515. % <LABEL> ::= <INTEGER> | ['ignore]
  516. procedure cl_susimkatl(op,knowl,newknowl,n);
  517. % Common logic susi make atomic formula list. [op] is one of the
  518. % operators [and], [or]; [knowl], [newknowl] are KNOWL's; [n] is an
  519. % integer. Returns an list $L$ of atomic formulas. All knowledge
  520. % tagged with [n] is extraced from [newknowl] into $L$.
  521. begin scalar res;
  522. res := for each pair in newknowl join
  523. if cdr pair = n then {car pair};
  524. if null res then return nil;
  525. res := rl_susipost(res,knowl); % TRUE | FALSE | INCTHEO | atl
  526. if rl_tvalp res then
  527. return {cl_cflip(res,op eq 'and)};
  528. if res eq 'inctheo then % Das hatte man auch frueher
  529. return cl_cflip('false,op eq 'and); % wissen koennen.
  530. if op eq 'or then
  531. res := for each at in res collect rl_negateat at;
  532. res := for each at in res collect rl_susitf(at,knowl);
  533. return res
  534. end;
  535. procedure cl_susicpknowl(knowl);
  536. % Common logic susi copy knowledge. [knowl] is a KNOWL. Returns a
  537. % KNOWL. Copies the toplevel and the LAT's of [knowl].
  538. for each p in knowl collect (car p . cdr p);
  539. procedure cl_susiupdknowl(op,atl,knowl,n);
  540. % Common logic susi update knowledge. [op] is one of the operators
  541. % [and], [or]; [atl] is a list of (simplified) atomic formulas;
  542. % [knowl] is a KNOWL; [n] is the current level. Returns a KNOWL.
  543. % Destructively updates [knowl] wrt. the [atl] information.
  544. begin scalar at;
  545. while atl do <<
  546. at := car atl;
  547. atl := cdr atl;
  548. knowl := cl_susiupdknowl1(op,at,knowl,n);
  549. if knowl eq 'false then <<
  550. atl := nil;
  551. at := 'break
  552. >>
  553. >>;
  554. if at eq 'break then
  555. return 'false
  556. else
  557. return knowl
  558. end;
  559. procedure cl_susiupdknowl1(op,at,knowl,n);
  560. % Common logic susi update knowledge subroutine. [op] is one of
  561. % [and], [or]; [at] is a (simplified) atomic formula; [knowl] is a
  562. % KNOWL; [n] is the current level. Returns a KNOWL. Destructively
  563. % updates [knowl] wrt. [at].
  564. if op eq 'and then
  565. cl_susiupdknowl2((at . n),knowl,n)
  566. else % We know [op eq 'or]
  567. cl_susiupdknowl2(((rl_negateat at) . n),knowl,n);
  568. procedure cl_susiupdknowl2(lat,knowl,n);
  569. % Common logic susi update knowledge subroutine. [lat] is a LAT;
  570. % [knowl] is a KNOWL; [n] is the current level. Returns a KNOWL.
  571. % Destructively updates [knowl] wrt. [lat].
  572. begin scalar a,w,sck,ignflg,delflg,addl;
  573. sck := knowl;
  574. while sck do <<
  575. a := car sck;
  576. sck := cdr sck;
  577. w := rl_susibin(a,lat); % 'true | 'false | nil | {commands,...}
  578. if w eq 'false then % What happens with atoms neq false ???
  579. sck := nil
  580. else <<
  581. w := cl_susiinter(w,knowl,a);
  582. addl := nconc(addl,cadr w);
  583. knowl := car w;
  584. if caddr w then
  585. ignflg := T;
  586. if cadddr w then <<
  587. delflg := T;
  588. sck := nil
  589. >>
  590. >>
  591. >>;
  592. if w eq 'false then return 'false;
  593. if null delflg then <<
  594. if ignflg then cdr lat := 'ignore;
  595. knowl := lat . knowl
  596. >>;
  597. while addl do <<
  598. knowl := cl_susiupdknowl2(car addl,knowl,n);
  599. if knowl eq 'false then
  600. addl := nil
  601. else
  602. addl := cdr addl
  603. >>;
  604. return knowl;
  605. end;
  606. procedure cl_susiinter(prg,knowl,a);
  607. % Common logic susi interpreter. [prg] is a SUSIPRG; [knowl] is a
  608. % KNOWL; [a] is a LAT. Returns a list
  609. % $(\kappa,\alpha,\iota,\delta)$, where $\kappa$ and $\alpha$ are
  610. % KNOWL's; $\iota$ and $\delta$ are flags.
  611. begin scalar addl,ignflg,delflg;
  612. for each p in prg do
  613. if car p eq 'delete or car p eq 'ignore then
  614. % if car p eq 'ignore then % We ignore ['ignore]!
  615. % if cdr p then
  616. % ignflg := T
  617. % else
  618. % cdr a := 'ignore
  619. % else if car p eq 'delete then
  620. if cdr p then
  621. delflg := T
  622. else
  623. knowl := delqip(a,knowl)
  624. else if car p eq 'add then
  625. addl := cdr p . addl;
  626. return {knowl,addl,ignflg,delflg}
  627. end;
  628. endmodule; % [clsimpl]
  629. end; % of file