4 /* Test simplification of boolean expressions.
5 * '(...) expressions are simplified but not evaluated.
8 ['("and" ()), '("or" ())]; /* analogous to * and + with no arguments */
11 /* These values are supposed to be ignored in quoted expressions '(...).
13 (a : true, b : false, c : true, 0);
16 ('(a and b), [op (%%), args (%%)]);
19 ('(a or b), [op (%%), args (%%)]);
22 ('(not a), [op (%%), args (%%)]);
25 ('(a and b or c and d), [op (%%), args (%%)]);
26 ["or", ['(a and b), '(c and d)]];
28 ('((a or b) and (c or d)), [op (%%), args (%%)]);
29 ["and", ['(a or b), '(c or d)]];
43 '[true and true, true and false, true or true, true or false, false and true, false and false, false or true, false or false];
44 [true, false, true, true, false, false, true, false];
46 '((a or true) and (b or true));
49 '(a and true or b and true);
52 '(a or b or c or false);
55 '(a and b and c and true);
59 '((not a) or (not b));
65 '((not a) and (not b));
67 '(not (a or b or c or d or e));
68 '((not a) and (not b) and (not c) and (not d) and (not e));
70 '(not (a and b and c and d and e));
71 '((not a) or (not b) or (not c) or (not d) or (not e));
73 '(not (a or b and c or d and e));
74 '((not a) and ((not b) or (not c)) and ((not d) or (not e)));
76 '(not (a and not b or c and not d and not e));
77 '(((not a) or b) and ((not c) or d or e));
91 /* Flattening nested expressions.
92 * Maxima "and" and "or" are not commutative, so order of arguments should be preserved.
93 * Flattening is a simplification => should happen in both simplification and evaluation.
99 ('(x and b and ((h and d) and c) and y), [op (%%), args (%%)]);
100 ["and", [x, b, h, d, c, y]];
102 ('(x or b or ((h or d) or c) or y), [op (%%), args (%%)]);
103 ["or", [x, b, h, d, c, y]];
105 '(x and b and ((h or d) or c) and (y and q and e));
106 x and b and (h or d or c) and y and q and e;
108 (x and b and ((h and d) and c) and y, [op (%%), args (%%)]);
109 ["and", [x, b, h, d, c, y]];
111 (x or b or ((h or d) or c) or y, [op (%%), args (%%)]);
112 ["or", [x, b, h, d, c, y]];
114 x and b and ((h or d) or c) and (y and q and e);
115 x and b and (h or d or c) and y and q and e;
117 /* Side-effects shouldn't happen in simplification (since arguments are not evaluated).
123 ('((a : true) and (b : false) and (c : foo ())), [op (%%), args (%%), a, b, c]);
124 ["and", '[a : true, b : false, c : foo ()], 'a, 'b, 'c];
126 ('(not (a : true)), [op (%%), args (%%), a]);
127 ["not", '[a : true], 'a];
129 /* Miscellaneous tests.
131 expr: '(a > b and (equal (c, d) or e = 1) and not f <= g or notequal (h, %pi));
132 '(a > b and (equal (c, d) or e = 1) and f > g or notequal (h, %pi));
134 '(a > b and b > c and true or a < b and b < c and true or false or not true);
135 '((a > b and b > c) or (a < b and b < c));
137 '(not not not not a > b);
140 '(not not not not not a > b);
143 '(not not not false and not not not not true);
147 ''(funmake ("not", '[foo (a)]));
149 '[is (not a > b or false), is (not a > b or true), is (not a > b and false)];
150 '[is (a <= b), true, false];
152 '['is (not a > b or false), 'is (not a > b or true), 'is (not a > b and false)];
153 '['is (a <= b), true, false];
155 '[maybe (not a > b or false), maybe (not a > b or true), maybe (not a > b and false)];
156 '[maybe (a <= b), true, false];
158 '['maybe (not a > b or false), 'maybe (not a > b or true), 'maybe (not a > b and false)];
159 '['maybe (a <= b), true, false];
161 /* Test evaluation of boolean expressions.
162 * Evaluate the arguments and simplify.
165 ["and" (), "or" ()]; /* analogous to * and + with no arguments */
168 (a and b, [op (%%), args (%%)]);
171 (a or b, [op (%%), args (%%)]);
174 (not a, [op (%%), args (%%)]);
177 (a and b or c and d, [op (%%), args (%%)]);
178 ["or", ['(a and b), '(c and d)]];
180 ((a or b) and (c or d), [op (%%), args (%%)]);
181 ["and", ['(a or b), '(c or d)]];
195 (a or true) and (b or true);
198 a and true or b and true;
201 a or b or c or false;
204 a and b and c and true;
208 '((not a) or (not b));
214 '((not a) and (not b));
216 not (a or b or c or d or e);
217 '((not a) and (not b) and (not c) and (not d) and (not e));
219 not (a and b and c and d and e);
220 '((not a) or (not b) or (not c) or (not d) or (not e));
222 not (a or b and c or d and e);
223 '((not a) and ((not b) or (not c)) and ((not d) or (not e)));
225 not (a and not b or c and not d and not e);
226 '(((not a) or b) and ((not c) or d or e));
240 /* Side-effects should happen in evaluation.
243 ((a : true) and (b : true) and (c : foo ()), [%%, a, b, c]);
244 [foo (), true, true, foo ()];
246 (not (a : bar ()), [%%, a]);
247 ['(not bar ()), bar ()];
252 /* Miscellaneous tests.
254 expr: a > b and (equal (c, d) or e = 1) and not f <= g or notequal (h, %pi);
255 '(a > b and equal (c, d) and f > g or notequal (h, %pi));
258 '(a > b and equal (c, d) and f > g or notequal (h, %pi));
264 '(a > b and equal (c, d) and f > g);
266 ''expr, e=89, f = g + 1;
267 '(a > b and equal (c, d) or notequal (h, %pi));
269 (assume (notequal (c, d), equal (f, 100), g < 0), 0);
273 '(notequal (h, %pi));
275 a > b and b > c and true or a < b and b < c and true or false or not true;
276 '((a > b and b > c) or (a < b and b < c));
278 not not not not a > b;
281 not not not not not a > b;
284 not not not false and not not not not true;
287 /* is-evaluation of conditionals.
288 * is(foo) => true, false, and unknown or error (depending on prederror flag).
291 ev (is (a > b or a > c), prederror=false);
294 errcatch (ev (is (a > b or a > c), prederror=true));
297 [is (not a > b or true), is (not a > b and false), 'is (not a > b or true), 'is (not a > b and false)];
298 [true, false, true, false];
300 [maybe (not a > b or false), maybe (not a > b or true), maybe (not a > b and false)];
301 [unknown, true, false];
303 ['maybe (not a > b or false), 'maybe (not a > b or true), 'maybe (not a > b and false)];
304 ['maybe (a <= b), true, false];
306 is (not a > b or true);
309 is (not a > b and false);
312 ev (maybe (not a > b or false), prederror=false);
315 ev (maybe (not a > b or false), prederror=true);
318 ev (maybe (not a > b), a = 100.0, b = 1000/3);
321 ev (maybe (not a > b), b = 100.0, a = 1000/3);
324 (kill (aa, bb, cc, dd),
325 implies (a%, b%) := (not a%) or b%,
326 equivalent (a%, b%) := implies (a%, b%) and implies (b%, a%),
327 translate (implies, equivalent));
328 [implies, equivalent];
330 /* output not fully simplified -- these next two tests show bugs */
332 implies (aa and bb, cc or dd);
333 not (aa) or not (bb) or cc or dd;
335 implies (aa and bb, aa);
336 not (aa) or not (bb) or aa;
339 (not aa or aa) and (not aa or aa);
341 /* crime scene example from mailing list 2006/05/06 tnx Mario */
344 "=>" (r, s) := not r or s,
346 implies (ante, conse, listvar) := block ([expr, npos, maxn, combis:[], bits, quot, div],
347 npos: length(listvar),
349 expr: not ante or conse,
353 for j: 1 thru npos do
354 (div: divide (quot, 2),
356 bits: cons (listvar[j]=div[2], bits)),
357 combis: cons (subst ([1=true, 0=false], bits), combis)),
358 apply ("and", makelist (subst (k, expr), k, combis))), 0);
361 implies ((p or q) and (q => r) and (p => s) and not r, s, [p, q, r, s]);
364 /* charfun examples following email discussion circa 2007-03-23 */
366 (kill (x, y, z), expr : charfun (-1 < x and x < 1));
367 '(charfun (-1 < x and x < 1));
369 [ev (expr, x = 1/2), ev (expr, x = -3/2)];
372 expr : charfun (x > 0 or y > 0);
373 '(charfun (x > 0 or y > 0));
375 [ev (expr, x = 1/2), ev (expr, x = -3/2), ev (expr, x = -3/2, y = -3/4)];
376 [1, '(charfun (y > 0)), 0];
378 /* ensure that arguments to is and maybe are evaluated exactly once */
386 is (aa = 'cc and bb = 'cc);
395 maybe (aa = 'cc and bb = 'cc);
401 /* SF bug [ 1726148 ] maybe with prederror : true */
403 (kill (a), ev (maybe (a), prederror = true));
406 ev (maybe (a or false), prederror = true);