Here are a few potential ACL2 development tasks, separated by lines of
"<><>".  To see the one-line summaries:

grep '^{{.*}}[ ]*$' to-do.txt | sed 's/^{{//' | sed 's/}}[ ]*$//' > to-do-summary.txt

**WARNINGS**:

(1) This is for a small group of incipient ACL2 developers who have
undergone suitable training (see
http://www.cs.utexas.edu/users/moore/acl2/workshop-devel-2017/).  We
hope you will contribute!

(2) Matt and J need to approve any changes that go into any part of
the ACL2 system except for what is under books/.  So, you might want
to ask them to commit to looking at your changes before you spend time
working on them.

(3) The descriptions below are probably OK but not necessarily
polished.  Please discuss with your developer colleagues if you have
questions.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Possibly add function-symbolp to the guard of logicp.}}

Currently logicp returns t on a symbol that is not a function symbol, which is
slightly odd.  Adding function-symbolp to the guard of logicp would eliminate
this slight oddity, but would require discharging the ensuing guard verification
obligations.  Note also that some existing ACL2 code may rely on logicp
returning t on a non-function symbol, e.g., see the following line in the
definition of sublis-var!:

              (logicp (ffn-symb term) wrld) ; maybe fn is being admitted

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Perhaps split :doc hints into separate topics.}}

This item was added by Matt K. but is based on correspondence
initiated by Eric McCarthy.  Note that it could take some effort to do
well, since a lot of other stuff might point to :doc hints that would
then need to point somewhere else (e.g., in error messages).  Also,
it's pretty simple to search for a specific hint type within that
page, so this is perhaps not high priority [note from Matt: which is
why I'm adding this item here rather than doing it myself].  Eric
points out that with separate topics, "people can add more tips on
using hints and examples without making the page unmanageably large."

Perhaps a simple but adequate change would be for each kind of hint to
have HINTS as its parent.  Then error messages could still point to
:DOC hints, which would then show a clickable list of all hint types.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Improve argument names for set-guard-checking.}}

Alessandro Coglio had the following suggestions for renaming arguments
of set-guard-checking:

  :ignore instead of :none, since that mode ignores guards — nil and
  :none sound almost like synonyms

  :top instead of t, since that mode checks guards at the top-level —
  t is a bit nondescript, given that there’s also :all

Matt and J are happy with those new names, but want to keep the old
names too since they have been around for so long.  Also, the old
names are used throughout the code, and quite possibly in the books
too; it could be a substantial effort to be sure to touch all uses of
set-guard-checking and of state global 'guard-checking-on.

Instead, the idea is just to add aliases for set-guard-checking, but
continuing to use the old values of t and :none for state global
'guard-checking-on.  It will then also be important to change the
documentation, and also relevant output if any, to emphasize the
preferred names of :ignore and :top, while probably mentioning the old
names of :none and t as "aliases" or such (even though the aliasing is
actually the other way around).

I (Matt) suspect that this is a relatively simple development task,
and I expect whoever takes it on to deal not only with the
set-guard-checking implementation but also all relevant output and
documentation.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Perhaps avoid iteration for guessing type-prescriptions for non-rec functions.}}

Maybe don't look for a fixed point in type-prescription rule
generation if the function is non-recursive.  It's possible that the
code already does this, my guess is, probably not.

This one is probably not very important, but it might be a relatively
easy way to get familiar with the mechanism for generating
type-prescription rules for defuns.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Perhaps eliminate either directory-of-absolute-pathname or get-directory-of-file.}}

These two source functions seem to do roughly the same thing, though
one is more careful.  Perhaps they could be merged into a single
function, which might have a flag argument specifying whether or not
to check the filename argument and cause an error if the argument
isn't appropriate.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Strengthen state-p so that channel info has file-clocks that don't exceed file-clock.}}

[Note that duplicate-free open channel lists probably also needs to be
considered, as per Keshav.  See his email below the IRC thread,
below.]

Note that some books would probably need work to recertify if the
following is done.

Note from Keshav: the book std/io/open-channels contains several
examples of theorems which could be strengthened if this to-do list
item were implemented.

The predicate state-p is too weak for some purposes, because it
doesn't capture the invariant that the file-clock field of the state
is an upper bound for the file-clocks of the open channels (and
probably also of the read-files, though I haven't quite thought that
through).  If we strengthen it then presumably some proofs will need
to be redone.  Any thoughts on this?

<kini> mattjk`: Suppose I've come up with some invariant of the current ACL2
       state. There's no way for me to prove this invariant and make use of
       it, short of adding it to state-p1 in axioms.lisp, is there?  [08:01]
<kini> the actual example I have in mind is (and (no-duplicatesp (nth 0
       state)) (no-duplicatesp (nth 1 state)), which as far as I understand
       should always hold  [08:02]
<mattjk`> Could you just prove as a rewrite rule (implies (state-p state)
	  <property>)?  [08:04]
<mattjk`> Oh -- I guess you're saying that this isn't always true.
<mattjk`> In that case, I guess you could define (my-state-p state) = (and
	  (state-p state) <property>) and use that in your guards etc.  Any
	  reason that wouldn't work?  [08:05]
<kini> Hmm, I haven't tried that. But would it be possible to guard-verify
       such a thing?  [08:07]
<kini> I guess so, it would be self-contained...  [08:08]
<kini> hmm, but then would I be able to call such a function from the ACL2
       loop with the live state... guard-checking a guard on state seems like
       it might be hard since state contains some "fictional" things, doesn't
       it?  [08:09]
<mattjk`> OK, I see the problem.  I'm thinking on it....  [08:10]
<mattjk`> I think that the right solution might be to arrange that the
	  property indeed follows from state-p.  It almost does now, I think,
	  but we'd need the invariant that (file-clock state) is an upper
	  bound for all n such that, in the case of open-input-channels,
	  [exists file-name type . (list file-name typ n) is a key of
	  (readable-files state).  I don't know how disruptive that might be
	  to proving our way through axioms.lisp and to books that
								        [08:15]
<mattjk`> reason about state.
<mattjk`> Could be a fun task for you after the developer's workshop?  [08:16]
<kini> heheh, perhaps :)  [08:17]
<kini> but I don't quite follow
<kini> If we had the invariant you propose, how would that imply the one I
       gave about no-duplicatesp?  [08:18]
<kini> your invariant would be sufficient to prove that the built-in functions
       that modify (open-input-channels state) and (open-output-channels
       state) maintain my invariant, but not, I think, that arbitrary user
       functions that return state maintain my invariant  [08:19]
<kini> and such user functions could have been run at the ACL2 loop in the
       past
<mattjk`> First: I should have added that I came up with that by looking at
	  function open-input-channel in ACL2 source file axioms.lisp.  I
	  should also have added that a similar change would be needed for
	  open-output-channel.  [08:20]
<mattjk`> But maybe you already got that.  It seems to me that arbitrary user
	  functions would preserve the enhanced state-p, because they have no
	  way to mess directly with the file-clock.
<mattjk`> Do you want to have a short Skype about this now?  [08:21]
<kini> sorry, not at the moment -- I'm not at the office yet, which means my
       internet connection is only good for stuff like text chat, haha
<kini> perhaps later today if you have some time
<kini> maybe I need to understand better the stobj story for state  [08:23]
<mattjk`> Probably not today (things scheduled to keep me busy from 10:45
	  central time onward, maybe earlier even; maybe tonight).
<kini> OK.  Anyway there's no huge rush, it's just something that occurred to
       me
<kini> I don't need this invariant for anything at the moment
<mattjk`> I'll probably get J's thoughts on this on Friday.
<kini> I wrote some theorems about how open-input-channel-p1 of a channel is
       preserved under various orthogonal I/O operations, and one of the
       theorems was that if a channel is open and you close a different
       channel, the first channel remains open  [08:26]
<kini> so it occurred to me that it might be nice to have the sister theorem
       as well, that if a channel is open and you close the same channel, the
       channel then becomes closed
<kini> but the checkpoint I got when trying to prove this was basically asking
       me to prove that the list of input channels was no-duplicatesp
<kini> Sure, sounds good -- thanks!  [08:27]
ERC>

.....

[From Keshav via gmail, Sun, May 21, 2017 at 12:13 PM:]

  I'm still not sure that your condition about the file clock will be a
  sufficient strengthening of state-p1 to prove a theorem about a
  channel becoming closed after you attempt to close it, because it
  doesn't imply that there are no duplicates in the list of open
  channels.

  Your condition would allow me to prove that if there were currently no
  duplicate open channels in the state and I tried to open a channel,
  then there would continue to be no duplicates in the list of open
  channels.  But it doesn't seem to be strong enough to allow me to say
  that if (STATE-P STATE), then there are no duplicate open channels in
  STATE.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Maybe support custom printing for table guard violations.}}

I asked in an ACL2 seminar (12/4, I think), and nobody seemed to care
about this.  But I'm still tempted to do it.  The following recently
(11/2016) came up in a wish-list entry from Eric Smith:

--------------------

REQUESTOR: Eric
BENEFIT: VERY LOW

The error generated by this is a bit inscrutable:

(add-invisible-fns binary-+ binary-*)

I believe the problem is that binary-* is not unary?  Would it be easy
to print a message saying that?

[Matt] I've looked into this, and there isn't currently a mechanism
for printing anything better unless we want to print something as a
side effect (for example with cw or (er hard ..)), which is kind of
gross.  I could probably implement something for table guards that is
analogous to set-guard-msg for function guards.  Maybe it would take
an hour or two, or even three (documentation can take time).  If you
want me to do that let me know; otherwise you could move this to
wish-list-later.txt.  Either way is fine with me.

--------------------

From notes 11/30/2012:

[[First see if there are sufficiently many places in our own sources
to make this solution worth it.  If so, then go for it but only if
it's not too much trouble (it's not that important).  We could
consider doing this for :guard, too.  I made the point though that at
least for guards there is print-gv to help with debugging for function
guard violations.

Possible candidates:
macro-aliases-table
waterfall-parallelism-table
trusted-clause-processor-table
memoize-table
return-last-table
]]

[Someone] got the arguments backwards on add-macro-alias.  I think it
would be great to print a more useful error message in that case,
suggesting maybe switching the arguments if there are a function and
macro symbol each in the position expected for the other.  So I
imagine implementing a :guard-msg keyword, as shown below (though this
example is silly, since I've used the default message).

  (table tests nil nil :guard term      ; print the indicated
         :guard-msg                     ;   message if the table guard is false
         (msg
          "The TABLE :guard for ~x0 disallows the combination of key ~x1 and ~
           value ~x2.  The :guard is ~x3.  See :DOC table."
          name key val (untranslate term t world)))

Unlike the :guard keyword, I don't see a problem with changing the
:guard-msg later.

  (table tests nil nil :guard term)
  (table tests nil nil :guard-msg msg1)
  (table tests nil nil :guard-msg msg2)

Thoughts?

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Make file-write-date$, delete-file$, and file-length$ sensitive to the cbd.}}

Note: More ambitious would be to have the cbd be the OS-specified
directory, and idea Keshav Kini put forward for consideration.  That
is likely to be much more difficult, and it would also increase the
lisp-specific code in the system.  So I (Matt) am not in favor of that
approach, though it's intriguing.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Fix handling of state result, in old-style signatures without state argument.}}

Below is the relevant email thread (with a typo from Matt fixed by
Matt).

From: Matt Kaufmann <kaufmann@cs.utexas.edu>
Subject: Re: Old-style signature with output state
Date: October 24, 2017 at 5:20:40 AM PDT
To: Alessandro Coglio <coglio@kestrel.edu>

Wow, weird!  I'll bet it's easy to fix.  May I add it to
books/system/to-do.txt and email acl2-devel about it?  Or, feel free
to do so (or even to forward this email if you like).

Thanks for letting me know --
-- Matt
Alessandro Coglio <coglio@kestrel.edu> writes:

Hi Matt,

[...]

I found that the following is accepted by ACL2, even though my reading of :doc
signature is that state may appear in the result of the signature only if it
appears in the formals:

(encapsulate
 ((f (x) state))
 (local (defun f (x) x)))

However, the stobjs-out property of f is (nil), indicating that the state output
variable has been treated like an ordinary variable.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Verify guards for bind-macro-args.}}

See file books/system/bind-macro-args.lisp, which makes a start at
this guard verification.

If/when I know that this book is modified to guard-verify the function
bind-macro-args, then I'll do the usual "installation" of that
function in the ACL2 sources.

Optionally:

It would be cool if someone wants to try that "installation" process.
When I do it, I just read the comment in (defconst
*system-verify-guards-alist* ...) in source file
boot-strap-pass-2.lisp.  But I see that :doc
verify-guards-for-system-functions might be the more appropriate place
to start if you want to do that.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Add two missing "Non-rec" warnings.}}

There are two cases where "Non-rec" warnings fail to be printed, but
should be:

1. Non-recursive functions in triggers of type-prescription rules
2. Non-recursive functions in hypotheses of linear rules

Below we explain each of these in turn.

-----

1. Non-recursive functions in triggers of type-prescription rules

There's no non-recursive function ("[Non-rec]") warning for the
:type-prescription rule consp-my-cons below, but there should be.  The
existing code (source function chk-acceptable-type-prescription-rule)
clearly doesn't even try to give a "[Non-rec]" warning for
:type-prescription rules except for non-recursive functions in their
hypotheses.

ACL2 !>(defun my-cons (x y) (cons x y))

Since MY-CONS is non-recursive, its admission is trivial.  We observe
that the type of MY-CONS is described by the theorem (CONSP (MY-CONS X Y)).
We used primitive type reasoning.

Summary
Form:  ( DEFUN MY-CONS ...)
Rules: ((:FAKE-RUNE-FOR-TYPE-SET NIL))
Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.01)
 MY-CONS
ACL2 !>(defthm consp-my-cons
	 (consp (my-cons x y))
	 :rule-classes :type-prescription)

ACL2 Observation in ( DEFTHM CONSP-MY-CONS ...):  Our heuristics choose
(MY-CONS X Y) as the :TYPED-TERM.

Q.E.D.

Summary
Form:  ( DEFTHM CONSP-MY-CONS ...)
Rules: ((:TYPE-PRESCRIPTION MY-CONS))
Time:  0.00 seconds (prove: 0.00, print: 0.00, other: 0.00)
 CONSP-MY-CONS
ACL2 !>

-----

2. Non-recursive functions in hypotheses of linear rules

Here is one more case where we should create a "[Non-rec]" warning,
but we don't.  The log below illustrates that a rewrite rule can give
us a "[Non-rec]" in addition to the "[Free]" warning, but that's not
the case for a linear rule -- and it should be.  (Both of these are
designed to fail; of interest are the warnings.)

ACL2 !>(defthm test
         (implies (natp y) ; enabled non-rec fn
                  (< (* (car x) x) x))
         :rule-classes :rewrite)

ACL2 Warning [Free] in ( DEFTHM TEST ...):  A :REWRITE rule generated
from TEST contains the free variable Y.  This variable will be chosen
by searching for an instance of (NATP Y) in the context of the term
being rewritten.  This is generally a severe restriction on the applicability
of a :REWRITE rule.  See :DOC free-variables.


ACL2 Warning [Non-rec] in ( DEFTHM TEST ...):  As noted, we will instantiate
the free variable, Y, of a :REWRITE rule generated from TEST, by searching
for the hypothesis shown above.  However, this hypothesis mentions
the function symbol NATP, which is defun'd non-recursively.  Unless
disabled, this function symbol is unlikely to occur in the conjecture
being proved and hence the search for the required hypothesis will
likely fail.

[[.. non-warning output elided ..]]
******** FAILED ********
ACL2 !>(defthm test
         (implies (natp y) ; enabled non-rec fn
                  (< (* (car x) x) x))
         :rule-classes :linear)

ACL2 Warning [Free] in ( DEFTHM TEST ...):  A :LINEAR rule generated
from TEST will be triggered by the term (BINARY-* (CAR X) X).  When
TEST is triggered by (BINARY-* (CAR X) X) the variable Y will be chosen
by searching for an instance of (NATP Y) among the hypotheses of the
conjecture being rewritten.  This is generally a severe restriction
on the applicability of the :LINEAR rule.

[[.. non-warning output elided ..]]
******** FAILED ********
ACL2 !>

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Consider an alias or name change: VALUE-EVENT for VALUE-TRIPLE.}}

The name "VALUE-EVENT" seems more descriptive than "VALUE-TRIPLE".
Such a change might well not be sufficiently important to be worth
carrying out -- it should only be done so by someone who personally
feels that this is important, and will deal with all details that
arise from such a change.

This change is trivial at some level, but it could affect a lot of
books beyond just the community books.  So it seems important to query
the community before changing VALUE-TRIPLE to VALUE-EVENT, or more
likely, define one of them to be a macro for the other.

Before anyone embarks on this, they should read the email thread
below.

From: Alessandro Coglio <coglio@kestrel.edu>
Subject: Re: Value-triple => value-event ?
Date: Sat, 29 Sep 2018 13:22:02 -0700
To: Kaufmann Matt <kaufmann@cs.utexas.edu>
In-Reply-To: <t4dy3bk8nma.fsf@ginger.cs.utexas.edu>

Hi Matt, I understand. Adding it to the developer to-do list seems like a good idea to me. Thanks.



> On Sep 29, 2018, at 6:00 AM, Matt Kaufmann <kaufmann@cs.utexas.edu> wrote:
>
> Hi, Alessandro --
>
> Yes, I think the "triple" in "value-triple" is intended to emphasize
> that error triples are involved.  But I agree that "value-event" is a
> more descriptive [hence, better] name.  What I'm not sure of is
> whether it's sufficiently better to bother with the change.
>
> It might be very easy to make the change, by making value-event a
> macro:
>
> (defmacro value-event (&rest args)
>  `(value-triple ,@args))
>
> However, the :doc and, perhaps, error messages, would then still say
> "value-triple", so that wouldn't help much.  Things could be the other
> way around: all occurrences in the sources of value-triple could be
> changed to value-event, and then:
>
> (defmacro value-triple (&rest args)
>  `(value-event ,@args))
>
> I don't know if books changes would be needed.
>
> But even though I like your suggested "value-event" better than
> "value-triple", I don't know that it's sufficiently better to warrant
> the time spent on the changes, as there could easily be issues that
> haven't occurred to me.  I suppose that I could put this email thread
> into books/system/to-do.txt as a developer task, in case anyone wants
> to take it on.  What do you think?
>
> Thanks --
> -- Matt
> Alessandro Coglio <coglio@kestrel.edu> writes:
>
>> Hi Matt,
>>
>> Please feel free to ignore this idea, but I was wondering if 'value-event' may be a more descriptive name for what is currently called 'value-triple'. In a sense, this function “lifts” an arbitrary value to an event. I’m sure there’s a reason for the ‘triple’ of ‘value-triple’, but it’s not immediately evident to me; I looked at value-triple-fn and I see that it uses the value function to return error triples, so maybe that’s the rationale?
>>
>> Thanks.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Retain the guard of a defun-sk with :constrain t.}}

Currently a defun-sk with :constrain t has its guard set to t, regardless of
whether a different guard is specified in the defun-sk; if specified, the guard
is silently ignored. This is not a bug, because :doc defun-sk documents this
behavior, but it is undesirable.


> On May 24, 2019, at 7:57 PM, Matt Kaufmann <kaufmann@cs.utexas.edu> wrote:

> (defun-sk f (x)
>  (declare (xargs :guard (consp x)))
>  (exists y (equal (cons y y) x))
> ; Either include the following or not:
>  :constrain t)

> Then the command

> :args f

> shows that the guard is t if we use :constrain t, but the guard is
> (consp x) if we don't.  That disparity seems goofy.

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Name the free variables of each rule in the output of :pr.}}

A user may need to know the free variables for a given rule in cases
where this information is not lexically visible, for instance, when
the event generating the rule has let-bindings. Currently, :pr
writes out the LHS (for :rewrite rules)/typed term
(for :type-prescription rules)/trigger terms (for
:forward-chaining/:linear rules) without syntactic sugar; it may be
desirable for :pr to also list the free variables. Note, free
variables may arise in rule classes other than the ones mentioned above.

A developer taking on this task may find Matt Kaufmann's example,
below, helpful.

ACL2 !>(let ((rule (car (find-rules-of-rune
			 '(:rewrite symbol-<-transitive)
			 (w state)))))
	 (set-difference-eq
	  (union-eq (all-vars (access rewrite-rule rule :rhs))
		    (all-vars1-lst (access rewrite-rule rule :hyps) nil))
	  (all-vars (access rewrite-rule rule :lhs))))
(Y)
ACL2 !>

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Enable the generation of extra-info hypothesis for each functional instantiation constraint}}

A couple of reasons for this: a) knowing where constraints are coming
from is useful for debugging. and, perhaps more importantly, b) the
proofs of different constraints can have radically different
strategies.  Generating extra-info hyps would allow a user to write
robust computed hints that could employ strategies appropriate for
each constraint.

There could be a table to enable this feature.  A good model for that
is the inhibit-warnings-table, where the macro set-inhibit-warnings is
a local table event using that table:

(defmacro set-inhibit-warnings (&rest lst)
  `(local (set-inhibit-warnings! ,@lst)))

Or it could be yet another acl2-defaults-table key, which would
automatically make it local to books and encapsulate events.  That's
probably best in general, but the former approach is good if one wants
a way to make the setting global in one's session, including all books
that one is certifying in that session.

Note: extra-info hypotheses are already available for guard and
termination proofs.

Note: A cursory look into how constraints are computed reveals that
some constraints (ie: from encapsulations) are associated with
function symbols at the time of their admission:

ACL2 !>(trace$ putprop-constraints)
ACL2 !>(encapsulate
    (
     ((fn *) => *)
     )
  (local (defun fn (x) x))
  (defthm integerp-fn
    (implies
     (integerp x)
     (integerp (fn x))))
  )

1> (PUTPROP-CONSTRAINTS FN NIL
                        ((IMPLIES (INTEGERP X)
                                  (INTEGERP (FN X))))
                        NIL
                        ((FN SIBLINGS FN)
                         . |current-acl2-world|))
<1 (PUTPROP-CONSTRAINTS ((FN CONSTRAINT-LST
                             (IMPLIES (INTEGERP X)
                                      (INTEGERP (FN X))))
                         (FN SIBLINGS FN)
                         . |current-acl2-world|))

In other words, enabling the event:

:hints (("Goal" :use (:functional-instance lemma
                                           (fn zed))))

to generate an attributed constraint, such as:

(implies
 (and
  (extra-info '(:functional-instantiation) '(:constraint integerp-fn))
  (integerp x))
 (integerp (zed x)))

will require us to generate constraint attribution at the time of
function admission.

[[
Matt's reply: Or will it?  It seems to me that at the time the
:functional-instance hint is processed, we have this chain of calls:

translate-lmi
calls
translate-lmi/functional-instance
calls
relevant-constraints
calls
relevant-constraints1
calls
constraint-info

If a suitable flag were passed, then constraint-info could return
extra-info.  For example, after the encapsulate above, try this:

(defthm lemma (equal (fn x) (fn x)) :rule-classes nil)
(trace$ constraint-info)
(thm t :hints (("Goal" :use (:functional-instance lemma (fn ifix)))))

Then you'll see this:

1> (CONSTRAINT-INFO FN |current-acl2-world|)
<1 (CONSTRAINT-INFO FN
                    ((IMPLIES (INTEGERP X)
                              (INTEGERP (FN X)))))

But actually, I think it would make a lot more sense to modify
relevant-constraints1 to take a flag instead of constraint-info.
... end of Matt's reply]]

<><><><><><><><><><><><><><><><><><><><><><><><><>

{{Improve :pl output when a free variable of the rule occurs in the argument of :pl.}}

Eric Smith sent this example:

(defthm <-trans
  (implies (and (< x y) ; y is a free var
                (< y z))
           (< x z)))

and then do:

:pl (< y z)

The current output is confusing, since sometimes "Y" refers to the
free variable in the hypotheses of <-trans, and other times "Y" refers
to the variable in the input term, (< y z)::

(:REWRITE <-TRANS)
  New term: T
  Hypotheses: ((< Y Y) (< Y Z))
  Equiv: EQUAL
  Substitution: ((Z Z) (X Y))
  Free variable: Y

On the acl2-devel list we seemed to agree on the following as desired
output for this example.

(:REWRITE <-TRANS)
 New term: T
 Hypotheses: ((< Y Y{FREE}) (< Y{FREE} Z))
 Equiv: EQUAL
 Substitution: ((Z Z) (X Y) (Y Y{FREE}))
 Free variable bindings: ((Y Y{FREE}))

Of course, if Y{FREE} should be suitably "fresh"; if it weren't then
we could search for the first "fresh" variable of the form Y{FREE}1,
Y{FREE}2, etc.

The same issue arises in the proof-builder: you can see it with
(verify (< y z)) followed by sr.

This issue also applies to :linear rules and perhaps others; whoever
takes this item on should figure out which rule classes are relevant
and fix them all.  Perhaps :pl2 or :pr should also be considered (not
sure).  Here's an example involving a :linear rule.

(defthm <-trans
  (implies (and (< x y) ; y is a free var
                (< y z))
           (< (identity x) (identity z)))
  :rule-classes :linear)

:pl (identity y) currently gives this output.

(:LINEAR <-TRANS)
  Conclusion: (< (IDENTITY Y) (IDENTITY Z))
  Hypotheses: ((< Y Y) (< Y Z))
  Substitution: ((X Y))
  Free variables: Y and Z

Again, an analogous issue arises in the proof-builder: you can see it
with (verify (< (identity y) (identity z))) followed by (dv 1) and
show-linears.

<><><><><><><><><><><><><><><><><><><><><><><><><>
