Turn a single-value term into a multi-value term.
(mvify term) → new-term
When a multi-value term is translated by ACL2,
it looks like a single-value term,
i.e.
This utility can help obtain a multi-value untranslated term instead,
by turning certain translated occurrences of
This utility operates on translated terms, assuming that they are obtained either by translating valid untranslated multi-value terms, or by transforming translated multi-value terms in a way that preserves well-formedness with respect to multiple values (i.e. that they always return lists of two or more terms of the same length).
Certain term transformations may turn
a translated
This utility replaces occurrences of translated
All the other function calls are left unchanged (i.e. they are considered tree leaves), because presumably such functions already return multi-value results. If a variable or non-list quoted constant is encountered, it is an error: a variable or non-list quoted constant can never return a multiple value; this utility must be applied to a term that returns multiple values, which excludes variables and non-list quoted constants, and the recursion will stop before reaching any variable or non-list quoted constant if the term satisfies the assumptions stated earlier.
Function:
(defun mvify (term) (declare (xargs :guard (pseudo-termp term))) (let ((__function__ 'mvify)) (declare (ignorable __function__)) (b* (((when (variablep term)) (raise "Unexpected term: ~x0." term)) ((when (fquotep term)) (b* ((const (unquote-term term))) (if (true-listp const) (fcons-term 'mv (quote-term-list const)) (raise "Unexpected term: ~x0." term)))) (fn (ffn-symb term)) ((when (flambdap fn)) (fcons-term (make-lambda (lambda-formals fn) (mvify (lambda-body fn))) (fargs term))) ((when (eq fn 'if)) (fcons-term 'if (list (fargn term 1) (mvify (fargn term 2)) (mvify (fargn term 3))))) ((when (eq fn 'return-last)) (fcons-term 'return-last (list (fargn term 1) (mvify (fargn term 2)) (mvify (fargn term 3))))) ((mv list-call-p args) (check-list-call term))) (if list-call-p (fcons-term 'mv args) term))))
Theorem:
(defthm pseudo-termp-of-mvify (implies (and (pseudo-termp term)) (b* ((new-term (mvify term))) (pseudo-termp new-term))) :rule-classes :rewrite)