REDUNDANT-ENCAPSULATE.html -- ACL2 Version 6.3

### REDUNDANT-ENCAPSULATE

redundancy of `encapsulate` events

    Major Section:  ENCAPSULATE

For this documentation topic we assume familiarity with `encapsulate` events and the notion of redundancy for events; see encapsulate and see redundant-events.

The typical way for an `encapsulate` event to be redundant is when a syntactically identical `encapsulate` has already been executed under the same `default-defun-mode`, `default-ruler-extenders`, and `default-verify-guards-eagerness`. But more generally, the `encapsulate` events need not be syntactically identical; for example, it suffices that they agree when the contents of `local` sub-events are ignored. The precise criterion for redundancy is given below, but let us first look at a consequence of the point just made about ignoring the contents of `local` sub-events. Consider the following sequence of two events.

    (encapsulate
     ()
     (defun f (x) x)
     (local (defthm f-identity
              (equal (f x) x))))

    (encapsulate
     ()
     (defun f (x) x)
     (local (defthm false-claim
              (equal (f x) (not x)))))

You might be surprised to learn that the second is actually redundant, even though `false-claim` is clearly not a theorem; indeed, its negation is a theorem! The following two points may soften the blow. First, this behavior is as specified above (and is specified more precisely below): the contents of local events are ignored when checking redundancy of `encapsulate` events. Second, this behavior is sound, because the logical meaning of an `encapsulate` event is taken from the events that it exports, which do not include events that are local to the `encapsulate` event.

Some users, however, want to use `encapsulate` events for testing in a way that is thwarted by this ignoring of local sub-events. Consider the following sort of example.

    (encapsulate ()
                 (local (defthm test1 ...)))

    (encapsulate ()
                 (local (defthm test2 ...)))

Since the contents of local events are ignored when checking redundancy of an `encapsulate` event, the second form just above is indeed redundant, presumably not as expected by whomever wrote these two tests. A solution is to add distinct non-local forms, for example as follows.

    (encapsulate ()
                 (value-triple "test1")
                 (local (defthm test1 ...)))

    (encapsulate ()
                 (value-triple "test2")
                 (local (defthm test2 ...)))

A different solution is to use `make-event` for testing, as follows.

    (make-event (er-progn (defthm test1 ...)
                          (value '(value-triple nil))))
    (make-event (er-progn (defthm test2 ...)
                          (value '(value-triple nil))))

Also see community books `misc/eval.lisp`, `make-event/eval-check.lisp`, and `make-event/eval-tests.lisp` for more ways to test in books.

The precise criterion for redundancy of `encapsulate` events is that the existing and proposed `encapsulate` events contain the same signatures and the same number of top-level events -- let `k` be that number -- and for each `i < k`, the `i`th top-level events `E1` and `E2` from the earlier and current `encapsulate`s have one of the following properties.

o `E1` and `E2` are equal; or

o `E1` is of the form `(record-expansion E2 ...)`; or else

o `E1` and `E2` are equal after replacing each `local` sub-event by `(local (value-triple :elided))`, where a sub-event of an event `E` is either `E` itself, or a sub-event of a constituent event of `E` in the case that `E` is a call of `with-output`, `with-prover-time-limit`, `with-prover-step-limit`, `record-expansion`, `time$`, `progn`, `progn!`, or `encapsulate` itself.