• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
      • Std/lists
      • Std/alists
      • Obags
      • Std/util
        • Defprojection
        • Deflist
        • Defaggregate
        • Define
        • Defmapping
        • Defenum
        • Add-io-pairs
        • Defalist
        • Defmapappend
        • Defarbrec
        • Returns-specifiers
          • ACL2::patbind-ret
          • Defret
          • Tuple
          • Defret-mutual
          • More-returns
        • Define-sk
        • Defmax-nat
        • Defines
        • Error-value-tuples
        • Defmin-int
        • Deftutorial
        • Extended-formals
        • Defrule
        • Defval
        • Defsurj
        • Defiso
        • Defconstrained-recognizer
        • Deffixer
        • Defmvtypes
        • Defconsts
        • Support
        • Defthm-signed-byte-p
        • Defthm-unsigned-byte-p
        • Std/util-extensions
        • Defthm-natp
        • Defund-sk
        • Defmacro+
        • Defsum
        • Defthm-commutative
        • Definj
        • Defirrelevant
        • Defredundant
      • Std/strings
      • Std/io
      • Std/osets
      • Std/system
      • Std/basic
      • Std/typed-lists
      • Std/bitsets
      • Std/testing
      • Std/typed-alists
      • Std/stobjs
      • Std-extensions
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
    • Testing-utilities
    • Math
  • Std/util
  • Define

Returns-specifiers

A concise way to name, document, and prove basic type-like theorems about a function's return values.

The define macro and some other std/util macros support a :returns option. This option provides a concise way to name, document, and prove basic type-like theorems about the return values of your functions. Named return values also allow your function to be used with the special ret binder for b*.

The general form is:

   :returns return-spec       ;; for single-value functions
or :returns (mv return-spec*) ;; for multiple-valued functions

There should be exactly one return-spec per return value. Each return-spec has the form:

   name               ;; just for naming return values
or (name [option]*)   ;; for naming, documenting, and proving theorems

where name is a symbol and the options can come in any order. To distinguish between the two forms of :returns, it is not legal to use mv as the name of a return value. The options are:

<xdoc>, any string literal
You can document each return value with a string literal. The string may make use of xdoc::markup and xdoc::preprocessor directives. Typically these descriptions should be short and not include document-structuring tags like <p>, <ul>, <h3>, and so forth. See the section on xdoc integration, below, for more details.
<return-type>, a symbol or term
When provided, the return type is used to generate a basic type-like theorems about the return values. A default hint is provided if no :hints keyword is present; see the discussion of :hints below.
Important Note in the multiple-valued case, this approach assumes you are using the tools/mv-nth book. The theorems we prove target terms like (mv-nth 0 (f ...)) and (mv-nth 1 (f ...)). This will not work well if mv-nth is enabled, especially about the 0th return value. For your convenience, define automatically includes the tools/mv-nth book. You really should be using it, you know.
As a convenient shorthand, you can use a single symbol like evenp. The theorem to be proven in this case might be, e.g., (evenp (f x)) for a single-valued function, or (evenp (mv-nth 3 (f x))) if this is the fourth (because of zero-indexing) return value of a multiply-valued function. The symbol t is explicitly allowed and results in no theorem. The symbol nil and keyword symbols are explicitly invalid as return types.
In certain cases, you may wish to prove a more complex theorem, e.g., say we want to prove this return value is always greater than 5. To support this, you can write a return type like (< 5 ans), where ans is the name of this return value. You can also refer to the names of other return values in this term. To make it easy to distinguish return types from other options, the return type term must be a cons and must not begin with quote.
:hyp hyp-term
This option only makes sense when there is a return-type term. By default, the return-type theorem is unconditional. If the theorem needs a hypothesis, you can put it here.
Frequently, the hypothesis you want for a type-like theorem is for the guards of the function to be met. As a convenient shorthand, hyp-term may be:
  • :guard -- use the function's guard as the hypothesis
  • :fguard -- like :guard, but force the entire guard
If neither of these is what you want, you can provide an arbitrary hyp-term. Typically this term should mention only the formals of your function. The return values of the theorem will not be bound in scope of the hyp, so trying to refer to them in a hypothesis is generally an error.
:hints hints-term
This option only makes sense when there is a return-type term; when specified, the given hints are passed to the proof attempt for the associated return-type. When no :hints keyword is present, a default hint is taken from the std::returnspec entry of the std::default-hints-table table, but this is overridden if the :hints keyword is present, even for :hints nil. To change the default hints, you may use set-returnspec-default-hints. The setting for this provided in the std/util books provides an induction and expand hint when the function introduced is singly-recursive.
A few special symbols (and even substrings of symbols) are substituted into hints; see the section "Substitutions" below.
:rule-classes classes
This option only makes sense when there is a return-type term. By default, the return-type theorem is added as a :rewrite rule. If you want to use other ACL2::rule-classes, then you will want to override this default.
A few special symbols (and even substrings of symbols) are substituted into hints; see the section "Substitutions" below.
:name name
This allows you to control the name of the associated theorem.
The default value of name is type-of-your-function. For example, natp-of-foo.
:hints-sub-returnnames
This option determines whether the return-name substitution is applied to the hints. See "Substitutions" below.

Substitutions

Certain symbols and certain substrings of symbols are replaced in the theorem body, hints, and rule-classes.

The following substitutions replace any symbol matching the given name in all three places (body, hints, and rule-classes):

  • <CALL> is replaced by the function applied to the formals.
  • <FN> is replaced by the function's macro alias, if it has one, or else its name. That is, for a form that introduces foo with macro arguments, creating a function named foo-fn, this produces foo.
  • <FN!> is replaced by the functions name, strictly, i.e. foo-fn in the example above.
  • <VALUES> is replaced by the list of return value names.

In the hints, the substrings <FN> and <FN!> of symbol names are also substituted as above. This allows hints to refer to defret-style theorem names.

In the rule-classes, the return value names are substituted for appropriate terms; i.e., if the second return value of foo is named bar, then bar becomes (mv-nth 1 (foo ...)). This substitution may also optionally be applied to the hints by setting the :hints-sub-returnnames option. This return name substitution is not applied to the theorem body, but the let-binding of the return names to the function call has a similar effect.

Configuration Object

Similar to define, a configuration object can be set up to set some options globally (local to a book). At the moment only the :hints-sub-returnnames option is read from this configuration object. The following form sets that option:

(make-returnspec-config :hints-sub-returnnames t)

Subtopics

ACL2::patbind-ret
b* binder for named return values from functions.
Defret
Prove additional theorems about a defined function, implicitly binding the return variables.
Tuple
A way to use mv-like return specifiers for tuples.
Defret-mutual
Prove additional theorems about a mutual-recursion created using defines, implicitly binding the return variables.
More-returns
Prove additional return-value theorems about a defined function.