(MEMBER (FOO A) (NATS-BELOW (BAR B)))
Major Section: INTRODUCTION-TO-THE-THEOREM-PROVER
What rules come to mind when looking at the following subterm of a Key Checkpoint? Think of strong rules (see strong-rewrite-rules).
(MEMBER (FOO A) (NATS-BELOW (BAR B)))The definition of
NATS-BELOW is
(defun nats-below (j)
(if (zp j)
'(0)
(cons j (nats-below (- j 1)))))
Thus, (nats-below 7) is (7 6 5 4 3 2 1 0). So when is k a member
of (nats-below j)?The weakest version is
(defthm member-nats-below-weak
(implies (and (natp k)
(natp j)
(<= k j))
(member k (nats-below j))))
But clearly we could improve this to:
(defthm member-nats-below-weak-better
(implies (and (natp k)
(natp j))
(iff (member k (nats-below j))
(<= k j))))
or even
(defthm member-nats-below-weak-better
(implies (natp j)
(iff (member k (nats-below j))
(and (natp k)
(<= k j)))))
Clearly though, we'd like to get rid of the (natp j) hypothesis and the
neatest plausible version is:
(defthm member-nats-below-weak-neatest
(iff (member k (nats-below j))
(and (natp j)
(natp k)
(<= k j))))
But it is not a theorem! For example, if j is -1 and k is 0,
then the left-hand side above returns t, because (nats-below j) is (0),
but the right-hand side is nil.
But this suggests a strategy for dealing with necessary hypotheses, like (natp j).
We can move them into an IF on the right-hand side! Something like this
might be a useful rewrite rule:
(iff (member k (nats-below j))
(if (natp j)
(and (natp k)
(<= k j))
...)).
We know, from member-nats-below-weak-better, that if (natp j) is true,
the member is equivalent to (and (natp k) (<= k j)). So now consider
what we know if (natp j) is false. If we can think of some term it's equivalent
to nd that term is simpler than the member expression, we have a strong rule.
But by inspection of the definition of nats-below, we see that when
(natp j) is false, (nats-below j) is the list (0) because (zp j)
is t. That is, nats-below treats all non-natural arguments like
they were 0. Thus, when (natp j) is false, (member k (nats-below j))
is (member k '(0)), which is (equal k 0).
So the strong version is
(defthm member-nats-below-strong
(iff (member k (nats-below j))
(if (natp j)
(and (natp k)
(<= k j))
(equal k 0))))
This is a great :rewrite
rule. It gets rid of the member and nats-below and
introduces arithmetic.
This example illustrates the idea of putting an if on the right-hand-side of the
equivalence. Many users tend to limit themselves to propositional forms inside
iff or to simple expressions inside of equal. But it is quite natural to
use if to express what the answer is: if j is a natural, then k is
in (nats-below j) precisely if k is a natural less than or equal to j;
if j is not a natural, then k is in (nats-below j) precisely if k is
0.
Use if to lay out the cases you must consider, if you can think of a simpler, equivalent
expression for every possible case.
Use your browser's Back Button now to return to practice-formulating-strong-rules.