Fix the bogus translations of and/or/not when prederror is false
commitd1914dd2208839e4aa6d9fe4851d61a87bf3d2c2
authorKris Katterjohn <katterjohn@gmail.com>
Sun, 13 Nov 2022 04:31:45 +0000 (12 23:31 -0500)
committerKris Katterjohn <katterjohn@gmail.com>
Sun, 13 Nov 2022 04:31:45 +0000 (12 23:31 -0500)
tree84adcade71efd4bf0d2d6cc480eb866cd63af536
parent159bda56c35137cfb4123cac9802acce2af22507
Fix the bogus translations of and/or/not when prederror is false

When translating and/or/not in the context of evaluating via is, if,
etc., the translator implicitly assumed that prederror would be true.
It was easy to get incorrect results when prederror was false.

Here are some simple examples comparing the results of interpreted and
translated code:

(%i1) foo () := is (not 5)$

(%i2) foo ();
(%o2) unknown

(%i3) translate (foo)$

(%i4) foo (); /* compare to %o2 */
(%o4) false

(%i5) bar () := is (6 and true)$

(%i6) bar ();
(%o6) unknown

(%i7) translate (bar)$

(%i8) bar (); /* compare to %o6 */
(%o8) true

(%i9) baz () := is (7 or true)$

(%i10) baz ();
(%o10) true

(%i11) translate (baz)$

(%i12) baz (); /* compare to %o10 */
(%o12) unknown

An `and` would be translated essentially by translating its operands
and generating an AND.  This does not provide correct short-circuiting
or the generation of `and` expressions when prederror is false and the
entire expression can't be evaluated to a boolean value.

If the modes of the operands are all boolean, then we can still
generate an AND.  This check uses the mode info introduced in commit
223d1215.

(And similarly for `or` and `not`.)

See also bug #4008.

No problems with the test suite, share test suite or rtest_translator.
New tests have been added to rtest_translator.
src/trpred.lisp
tests/rtest_translator.mac