• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Debugging
    • Projects
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
      • Theories
      • Rule-classes
      • Proof-builder
      • Hons-and-memoization
      • Events
      • History
      • Parallelism
      • Programming
        • Defun
        • Declare
        • System-utilities
        • Stobj
        • State
        • Memoize
        • Mbe
        • Io
        • Apply$
          • Lambda
          • Warrant
          • Defwarrant
          • Badge
          • Lambda$
          • Tame
          • Defbadge
          • Print-cl-cache
          • Introduction-to-apply$
          • Well-formed-lambda-objectp
          • Rewriting-calls-of-apply$-ev$-and-loop$-scions
            • Mixed-mode-functions
            • Explain-giant-lambda-object
            • Gratuitous-lambda-object-restrictions
            • Scion
            • Ilk
            • Ev$
            • Translam
            • Fn-equal
            • Apply$-guard
            • L<
            • Apply$-lambda-guard
            • Apply$-userfn
            • Badge-userfn
            • Defun$
            • Apply$-lambda
          • Defpkg
          • Mutual-recursion
          • Loop$
          • Programming-with-state
          • Arrays
          • Characters
          • Time$
          • Loop$-primer
          • Fast-alists
          • Defmacro
          • Defconst
          • Guard
          • Evaluation
          • Equality-variants
          • Compilation
          • Hons
          • ACL2-built-ins
            • Let
            • Declare
            • Mbe
            • Apply$
              • Lambda
              • Warrant
              • Defwarrant
              • Badge
              • Lambda$
              • Tame
              • Defbadge
              • Print-cl-cache
              • Introduction-to-apply$
              • Well-formed-lambda-objectp
              • Rewriting-calls-of-apply$-ev$-and-loop$-scions
                • Mixed-mode-functions
                • Explain-giant-lambda-object
                • Gratuitous-lambda-object-restrictions
                • Scion
                • Ilk
                • Ev$
                • Translam
                • Fn-equal
                • Apply$-guard
                • L<
                • Apply$-lambda-guard
                • Apply$-userfn
                • Badge-userfn
                • Defun$
                • Apply$-lambda
              • Fmt
              • Return-last
              • Loop$
              • Mv-let
              • Pseudo-termp
              • Defwarrant
              • Time$
              • Ec-call
              • Sys-call
              • Msg
              • Mv-nth
              • Value-triple
              • Comp
              • O-p
              • Member
              • Mbt
              • O<
              • Cw
              • Or
              • Er
              • Hons
              • Mv
              • Append
              • Flet
              • Defbadge
              • Cbd
              • *ACL2-exports*
              • Eql
              • Natp
              • Comment
              • Unsigned-byte-p
              • Posp
              • Nth
              • And
              • List
              • Len
              • Term-order
              • True-listp
              • Msgp
              • Booleanp
              • If
              • Time-tracker
              • Pseudo-term-listp
              • +
              • Not
              • Bitp
              • Equal
              • Cdr
              • Car
              • With-global-stobj
              • Symbol-listp
              • String-listp
              • Nat-listp
              • Implies
              • Iff
              • Character-listp
              • Alistp
              • The
              • Cons
              • Quote
              • Integerp
              • Consp
              • True-list-listp
              • Compress1
              • Symbolp
              • Stringp
              • *common-lisp-symbols-from-main-lisp-package*
              • Prog2$
              • <
              • *
              • Macrolet
              • Characterp
              • Last-prover-steps
              • Hons-acons
              • Eq
              • With-guard-checking
              • Let*
              • With-local-stobj
              • Hard-error
              • Length
              • Search
              • @
              • Zp
              • Aset1
              • Intersection$
              • -
              • State-global-let*
              • Assign
              • Union$
              • Set-gc-strategy
              • In-tau-intervalp
              • Pand
              • Cons-with-hint
              • Case-match
              • Symbol-name
              • Fast-alist-fork
              • Sys-call+
              • Signed-byte-p
              • Remove-duplicates
              • With-serialize-character
              • Hons-resize
              • Observation
              • Make-tau-interval
              • ACL2-count
              • Position
              • Logbitp
              • Termp
              • *standard-co*
              • Hons-acons!
              • Aref1
              • Assoc
              • Read-run-time
              • Hons-wash
              • Break-on-error
              • Expt
              • Take
              • Symbol-package-name
              • Coerce
              • Intern
              • Non-exec
              • Atom
              • Update-nth
              • Standard-oi
              • Get-internal-time
              • Formula
              • Keywordp
              • Without-evisc
              • Good-bye
              • Case
              • With-local-state
              • Spec-mv-let
              • Intern-in-package-of-symbol
              • Hons-clear
              • Binary-+
              • Ash
              • With-fast-alist
              • Standard-co
              • Set-difference$
              • Flush-compress
              • Rationalp
              • Symbol-alistp
              • Por
              • Rassoc
              • Remove-assoc
              • Logand
              • Pargs
              • Hons-copy
              • Alphorder
              • =
              • <=
              • Subsetp
              • Remove1-assoc
              • No-duplicatesp
              • Mv-list
              • Aset2
              • Floor
              • Serialize-read
              • Random$
              • Fmt-to-comment-window
              • F-put-global
              • Compress2
              • Canonical-pathname
              • Concatenate
              • Primitive
              • Nfix
              • Fast-alist-clean
              • Remove
              • Nthcdr
              • Remove1
              • Intersectp
              • Assert$
              • Endp
              • Put-assoc
              • True-list-fix
              • Keyword-value-listp
              • Illegal
              • Standard-char-p
              • Digit-char-p
              • Cond
              • With-output-lock
              • Princ$
              • Open-output-channel!
              • Fast-alist-free
              • Er-progn
              • Cw-print-base-radix
              • Truncate
              • Reverse
              • Complex
              • Add-to-set
              • Swap-stobjs
              • Set-print-case
              • Set-print-base
              • Code-char
              • Setenv$
              • Print-object$
              • Plet
              • Hons-get
              • Fmx-cw
              • Error1
              • Integer-length
              • Zip
              • With-live-state
              • Logior
              • With-guard-checking-event
              • Term-listp
              • Print-object$+
              • Hons-assoc-equal
              • String
              • Char-code
              • Unary--
              • Set-print-radix
              • Resize-list
              • Pkg-witness
              • Integer-listp
              • Boole$
              • /
              • Revappend
              • Mod
              • Term-list-listp
              • Read-ACL2-oracle
              • Make-fast-alist
              • Header
              • Extend-pathname
              • Subseq
              • Null
              • In-package
              • With-guard-checking-error-triple
              • Make-list
              • Logxor
              • Strip-cars
              • Make-ord
              • Fast-alist-free-on-exit
              • Aref2
              • Lognot
              • Must-be-equal
              • Integer-range-p
              • Getenv$
              • Ifix
              • F-get-global
              • Er-hard
              • Eqlablep
              • Cpu-core-count
              • ACL2-numberp
              • Ceiling
              • Butlast
              • Pairlis$
              • Mod-expt
              • Hons-equal
              • Gc$
              • Substitute
              • Round
              • With-stolen-alist
              • Mv?-let
              • Count
              • Char-downcase
              • Char
              • Sys-call-status
              • Set-fmt-hard-right-margin
              • Pprogn
              • Lexorder
              • Hons-summary
              • Boolean-listp
              • Assert*
              • List*
              • Char-upcase
              • Strip-cdrs
              • Serialize-write
              • Progn$
              • Keyword-listp
              • Sublis
              • String-downcase
              • Logeqv
              • Proofs-co
              • Maximum-length
              • Explode-nonnegative-integer
              • Eqlable-listp
              • Dimensions
              • Default
              • Arity
              • String-upcase
              • Max
              • Last
              • Evenp
              • Nonnegative-integer-quotient
              • Change
              • Binary-append
              • Zerop
              • String<
              • Abs
              • Set-print-base-radix
              • Intern$
              • Getprop
              • Explode-atom
              • Binary-*
              • Aset1-trusted
              • String-equal
              • Symbol<
              • String-append
              • Print-base-p
              • Mv?
              • Logic-fns-list-listp
              • Fix
              • Fast-alist-fork!
              • Er-hard?
              • Allocate-fixnum-range
              • Rem
              • 1+
              • *standard-oi*
              • Sys-call*
              • Pos-listp
              • Mbt*
              • Hons-wash!
              • Hons-clear!
              • Break$
              • Upper-case-p
              • String>=
              • String<=
              • Signum
              • Lower-case-p
              • Char-equal
              • Alpha-char-p
              • Real/rationalp
              • Rational-listp
              • O-first-coeff
              • Logic-fnsp
              • Logic-fns-listp
              • Hons-copy-persistent
              • Gc-strategy
              • Fast-alist-summary
              • Acons
              • Rfix
              • O-first-expt
              • Getpropc
              • Fast-alist-clean!
              • Digit-to-char
              • >=
              • >
              • Subst
              • Logcount
              • Evens
              • Comp-gcl
              • Atom-listp
              • Arities-okp
              • ACL2-number-listp
              • /=
              • Cadr
              • *standard-ci*
              • Unary-/
              • The-true-list
              • O-rst
              • Fast-alist-len
              • Er-soft
              • Complex/complex-rationalp
              • Array2p
              • Array1p
              • Logtest
              • Logandc1
              • Char<
              • Putprop
              • Good-atom-listp
              • Get-real-time
              • Eqlable-alistp
              • Count-keys
              • Assoc-string-equal
              • Logorc1
              • Logandc2
              • 1-
              • Standard-string-alistp
              • Packn
              • Logic-termp
              • Logic-term-list-listp
              • Get-cpu-time
              • Fmt!
              • Fms
              • Cw!
              • Assoc-keyword
              • String>
              • Numerator
              • Logorc2
              • Listp
              • Denominator
              • Char>=
              • The-number
              • Realfix
              • Odds
              • Makunbound-global
              • Make-character-list
              • Make
              • Fmt-to-comment-window!
              • Fms!
              • F-boundp-global
              • Complex-rationalp
              • Alist-to-doublets
              • Min
              • Lognor
              • Identity
              • Char>
              • Char<=
              • Zpf
              • Update-nth-array
              • Standard-char-listp
              • O-finp
              • Number-subtrees
              • Logic-term-listp
              • Last-cdr
              • Fmt1!
              • Fmt-to-comment-window!+
              • Character-alistp
              • Access
              • Oddp
              • Minusp
              • Lognand
              • Imagpart
              • Conjugate
              • Xor
              • Unquote
              • Packn-pos
              • Maybe-flush-and-compress1
              • Kwote
              • Int=
              • Fmt1
              • Fmt-to-comment-window+
              • Cw-print-base-radix!
              • Alist-keys-subsetp
              • Realpart
              • Plusp
              • First
              • Symbol-name-lst
              • R-symbol-alistp
              • R-eqlable-alistp
              • Cw!+
              • Cons-subtrees
              • Cons-count-bounded
              • Cddr
              • Caar
              • Standard-char-p+
              • Proper-consp
              • Kwote-lst
              • Improper-consp
              • Fmx
              • Cw+
              • Mbe1
              • Caddr
              • Pairlis-x2
              • Pairlis-x1
              • O>=
              • O<=
              • O-infp
              • Merge-sort-lexorder
              • Fix-true-list
              • Rest
              • Cdddr
              • Set-fmt-soft-right-margin
              • Real-listp
              • O>
              • Cddar
              • Cdar
              • Cdadr
              • Cdaar
              • Cadar
              • Caadr
              • Caaar
              • Cadddr
              • Caddar
              • Third
              • Tenth
              • Sixth
              • Seventh
              • Second
              • Ninth
              • Fourth
              • Fifth
              • Eighth
              • Cddddr
              • Cdddar
              • Cddadr
              • Cddaar
              • Cdaddr
              • Cdadar
              • Cdaadr
              • Cdaaar
              • Cadadr
              • Cadaar
              • Caaddr
              • Caadar
              • Caaadr
              • Caaaar
              • Hons-shrink-alist!
              • Hons-shrink-alist
              • Flush-hons-get-hash-table-link
              • Delete-assoc
            • System-attachments
            • Advanced-features
            • Set-check-invariant-risk
            • Developers-guide
            • Numbers
            • Irrelevant-formals
            • Efficiency
            • Introduction-to-programming-in-ACL2-for-those-who-know-lisp
            • Redefining-programs
            • Lists
            • Invariant-risk
            • Errors
            • Defabbrev
            • Conses
            • Alists
            • Set-register-invariant-risk
            • Strings
            • Program-wrapper
            • Get-internal-time
            • Basics
            • Packages
            • Defmacro-untouchable
            • Primitive
            • <<
            • Revert-world
            • Set-duplicate-keys-action
            • Unmemoize
            • Symbols
            • Def-list-constructor
            • Easy-simplify-term
            • Defiteration
            • Defopen
            • Sleep
          • Start-here
          • Real
          • Debugging
          • Miscellaneous
          • Output-controls
          • Macros
          • Interfacing-tools
        • Interfacing-tools
        • Hardware-verification
        • Software-verification
        • Testing-utilities
        • Math
      • Apply$

      Rewriting-calls-of-apply$-ev$-and-loop$-scions

      How the rewriter handles apply$, ev$, and loop$ terms

      This section focuses on how ACL2 rewrites calls of apply$, ev$, and loop$ scions. Our purpose is to explain the various ways the user can control that rewriting. We do so by taking you through a particularly simple example, starting with a loop$ expression.

      We assume that the standard apply$ book has been included,

      (include-book "projects/apply/top" :dir :system).

      and we suppose the function sq, of one argument, has been defined and warranted (see defwarrant.

      Recall that each loop$ statement is translated into a call of some loop$ scion involving lambda objects formed from the iterated expressions in the loop$ statement. Thus, for example,

      (loop$ for x in (cons a (cdr (cons x b))) collect (* (sq x) 3))

      is essentially translated into

      (COLLECT$ '(LAMBDA (LOOP$-IVAR)
                         (BINARY-* (SQ LOOP$-IVAR) '3))
                 (CONS A (CDR (CONS X B)))).

      Recall that you can view the cleaned up translation with :tc, and the discussion at tc explains what we mean by “cleaned up” here.

      So loop$ statements just introduce lambda objects and scions into any conjecture using loop$. These are rewritten like any other term in ACL2: the arguments are rewritten recursively and then enabled :rewrite rules (including the definition of the scion) are tried. Recall that ACL2 can rewrite lambda constants. (See rewrite-lambda-object for when that can occur and how to control it.)

      So now consider what happens when the rewriter encounters the translation of the loop$ above.

      (collect$ '(lambda (x) (binary-* (sq x) '3))  ; note where 3 occurs
                (cons a (cdr (cons x b)))

      it will rewrite the lambda object and the cons term, effectively turning the collect$ term into

      (collect$ '(lambda (x) (binary-* '3 (sq x)))  ; note where 3 occurs now
                (cons a b))

      Then, if other rewrite rules about collect$ don't rewrite that, the the definition of collect$ will be tentatively tried. By that we mean the body of the definition of collect$ is rewritten (in an enviroment binding locals to actuals) and then the rewriter decides heuristically whether to use the original call (with its rewritten arguments) or the rewritten body. We do not discuss those heuristics here because they're the same for loop$ scions as for all other recursive functions in ACL2.

      The logical definition of collect$ is

      (defun collect$ (fn lst)
        (if (endp lst)
            nil
            (cons (apply$ fn (list (car lst)))
                  (collect$ fn (cdr lst))))).

      And in this case, the body will be tentatively rewritten in the environment where the locals fn and lst are bound as follows.

      fn:  '(lambda (x) (binary-* '3 (sq x)))
      lst: (cons a b).

      As the rewriter descends through the body of collect$ it eventually encounters the apply$ term. After rewriting its arguments, the apply$ term effectively becomes

      (apply$ '(lambda (x) (binary-* 3 '(sq x)))
              (cons a 'nil))

      and then rules about apply$ are tried.

      Unless you disable it, the rule beta-reduction, from the standard apply$ book above, will fire, transforming the above apply$ term to

      (ev$ '(binary-* '3 (sq x))
           (cons (cons 'x a) 'nil)).

      (Beta-reduction is enabled by default. If you disable it, the apply$ term will not change unless you enable (:definition apply$), which is disabled by default.)

      But we recommend leaving beta-reduction enabled and thus converting every apply$ of a lambda object into an ev$ term. There is a special feature of the rewriter for simplifying certain ev$ terms. It is based on the fact that that (roughly speaking) the ev$ of a quoted tame term under an alist is the unquoted term with the alist applied as a substitution. That is, the ev$ term above is equal to (binary-* '3 (sq a)).

      More precisely, if a x is a tame term and every non-primitive function symbol in x has been warranted (see defwarrant) and a is a cons nest term representing a substitution sigma pairing the variable symbols occurring freely in x with terms, then (ev$ 'x  a) is equal to x/sigma, provided the warrants of all the non-primitive function symbols in x are assumed.

      This is implemented in the rewriter so that when an (ev$ 'x a) is encountered and the following conditions hold

      • the standard apply$ book has been included,
      • the rune (:rewrite ev$-opener) is enabled
      • x is a tame term
      • all non-primitive function symbols in x have been warranted (whether the warrants are assumed or not), and
      • a is a cons term representng an alist on variables,

      then the following three actions are taken,

      • The cons term a is converted to a substitution, sigma, and that substitution is extended to a substitution, sigma', by pairing with nil each variable of x that is unbound in sigma. It should be observed that an unbound variable is assigned the value nil by the definitions of ev$ (actually, of assoc).
      • The warrant for each non-primitive function in x is forced if possible unless the warrant is already assumed in the current context.
      • The (ev$ x a) term is rewritten to the result of recursively rewriting x under the substitution sigma'.

      Note that this eliminates ev$.

      If you see an ev$ of a quoted term in a checkpoint produced by the prover, you will know that one of the conditions above is not satisfied or that a necessary warrant could not be forced because forcing was disallowed or the warrant was assumed false in the context.

      If you would rather ev$ did not just disappear like this, disable (:rewrite ev$-opener). This might be desirable if the expansion produces a lot of cases and you can prove the theorem without exposing them.

      Sometimes you may wish for ev$ to expand, but to do so step-by-step, gradually working its way down through x. Such behavior can be achieved by disabling ev$-opener but enabling (:definition ev$), which is disabled by default. However, the tentative application of the mutually recursive definitions of ev$ and apply$ can be quite slow when dealing with moderately large lambda objects. Step-by-step expansion of ev$ can be accomplished by the alternative but generally faster method of disabling (:rewrite ev$-opener), leaving (:definition ev$) disabled, but proving your own version of ev$-opener under a different name.

      (defthm my-version-of-ev$-opener
        (and (implies (symbolp x)
                      (equal (ev$ x a) (cdr (assoc x a))))
             (equal (ev$ (list 'quote obj) a) obj)
             (implies (suitably-tamep-listp 3 nil args)
                      (equal (ev$ (cons 'if args) a)
                             (if (ev$ (car args) a)
                                 (ev$ (cadr args) a)
                                 (ev$ (caddr args) a))))
             (implies (and (not (eq fn 'quote))
                           (not (eq fn 'if))
                           (tamep (cons fn args)))
                      (equal (ev$ (cons fn args) a)
                             (apply$ fn (ev$-list args a)))))
        :hints (("Goal" :use ev$-opener))).

      By having the apply$ book's ev$-opener disabled you shut off the special feature described above, and by having your own version of ev$-opener enabled you push the ev$ through the quoted term with rewrite rules. This can sometimes help narrow down which of the conditiions above is unsatisfied, especially if you modify your version of the rule so that the tamep and suitably-tamep-listp hypotheses are forced.