Introduce a fixtype for good results and error results.
This is an experimental tool for now.
It is common for a function to return an error result in certain cases. Otherwise, the function returns a good (i.e. non-error) result.
In ACL2, an approach is to have the function return multiple results:
an error result
(which is
The two approaches have relative advantages and disadvantages.
An advantage of the first approach is that
disjointness of error and good results is not required
and that each result has always the same type.
However, a disadvantage is that
even though the good result is irrelevant
when the error result is non-
When functions naturally return multiple results (via mv), the first approach adds an error result, while the second approach could be applied to one of the results (e.g. the ``main'' one, if there is such a thing). Better yet from a conceptual point of view, the function can be made to return a single result, instead of multiple ones, that is either an error or a tuple of the good results. This is less efficient than multiple results (efficiency is indeed the purpose of multiple results with mv), but it may be more appropriate for a higher-level specification function, where issues of efficiency should be secondary, and where it may be more important that, in case of error, no dummy results are returned, so they cannot be accidentally used. The term `tuple' above is used in a broad sense: it does not have to be a list of values; it could be a value of a defprod type, for example. The claim above that issues of efficiency should be secondary in specification functions fits into a vision in which tools like APT are used to turn possibly inefficient or even non-executable functions into efficient ones. When instead, for expediency or practicality, a compromise is sought in which the same function is used for specification and execution (which sometimes also involves uses of mbe), then other considerations may apply, and the first approach above may be preferable to the second one. Nonetheless, there are applications where the second approach fits well.
When calling functions that may return error results
(whether the first or second approach above is used),
it is common to check whether the returned result is an error one,
and in that case also return an error,
otherwise continuing the computation if the returned result is a good one.
When using the error triple idiom,
ACL2 provides er-let* to handle this pattern,
which propagates the error triples unchanged;
b* provides the
The
When using define,
which provides automatic binding of
The reserrf and reserrf-push macros,
and the patbind-okf binder,
may be very useful for debugging,
or in general to provide informative error information.
They may be less useful for higher-level specifications,
in which errors do not carry much information
(as producing and consuming that information
may detract from the clarity and conciseness of the specification):
for higher-level specifications,
the simpler function reserr and binder patbind-ok
may be more appropriate.
Note that the
The fact that the same error result type, namely reserr,
is used in all the result types introduced by
The fixtype of good and error results introduced by
(defresult type :ok ... :pred ... :fix ... :equiv ... :parents ... :short ... :long ... :prepwork ... )
A symbol that specifies the name of the new fixtype.
A symbol that specifies the fixtype of the good results. Let
ok be the recognizer of this fixtype.
A symbol that specifies the name of the fixtype's recognizer. If this is
nil (the default), the name of the recognizer istype followed by-p .
A symbol that specifies the name of the fixtype's fixer. If this is
nil (the default), the name of the fixer istype followed by-fix .
A symbol that specifies the name of the fixtype's equivalence. If this is
nil (the default), the name of the equivalence istype followed by-equiv .
These, if present, are added to the XDOC topic generated for the fixtype.
A list of preparatory event forms. See the `Generated Events' section.
In order for
The fixtype specified by
The fixtype of good and error results.
The recognizer for the fixtype
type .
The fixer for the fixtype
type .
The equivalence for the fixtype
type .
A theorem asserting that a value in the fixtype specified by
:ok is also in the fixtypetype :(implies (ok x) (pred x))
A theorem asserting that a value in the fixtype reserrp is also in the fixtype
type :(implies (reserrp x) (pred x))
A theorem asserting that a value in the fixtype specified by
:ok is not an error in reserrp:(implies (ok x) (not (reserrp x)))This theorem is disabled by default, because it backchains from reserrp to
ok , where the former may be used without any reference to the latter.
A theorem asserting that a value in the fixtype
type that is not in the fixtypereserr is in the fixtype specified by:ok :(implies (and (pred x) (not (reserrp x))) (ok x))This theorem is disabled by default, because it backchains from
ok topred , where the former may be used without any reference to the latter.
The above events are preceded by
the events specified in
Currently the fixtype