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

      Gratuitous-lambda-object-restrictions

      Enforcement of logically unnecessary restrictions on :FN slots

      When a form is submitted to the ACL2's read-eval-print loop the terms in it are translated (``macroexpanded'') into ACL2's internal form, in which abbreviations like (cadr x) are expanded away and constants are always quoted. See term for details of the internal form.

      But translation also enforces a logically unnecessary restriction in argument positions of ilk :FN. If a quoted consp object whose car is the symbol LAMBDA occurs in a :FN slot, translate insists that the object satisfy well-formed-lambda-objectp. Well-formedness implies tameness, so any LAMBDA object that passes this translate-time test will have the ``expected behavior'' under apply$. If a quoted ill-formed ``LAMBDA-like'' object is passed into a :FN slot, an error is signaled.

      This is logically unnecessary because, like all ACL2 functions, apply$ can be called on any objects. Indeed, ill-formed LAMBDA-like objects induce some kind of default behavior by apply$ and can, sometimes, deliver non-erroneous values.

      But ground apply$ terms can be evaluated more quickly on well-formed LAMBDA objects than on ill-formed ones. See for example the discussion of performance in print-cl-cache. So this restriction is really motivated by a desire to encourage the exclusive use of well-formed LAMBDA objects.

      Why would you want to call apply$ on ill-formed input? The answer is that you might be trying to explore the semantics of apply$ by example. Since this is a time-honored methodology, we have made it possible to circumvent the translate-time check if you insist on feeding an ill-formed object into a :FN slot. Soundness is not imperiled but execution may slow down.

      Warning: Using an ill-formed LAMBDA object in a :FN slot in a defun will make it impossible to warrant the newly defined function because it will not pass the stringent tests necessary to analyze its ilks. See defwarrant. Basically these bypasses are intended primarily for top-level input to ACL2's read-eval-print loop.

      There are two ways to bypass the check. Bypass 1 is to construct the object in place rather than supply a quoted constant. This can be as simple as consing a LAMBDA onto the rest of your ill-formed constant. This, of course, costs one cons at eval-time. Bypass 2 is to cons the ill-formed object together in a defconst and then use the defined constant symbol in the :FN slot. We illustrate these and other points below.

      ; Here we show the error that occurs if you use an ill-formed
      ; LAMBDA object in a :FN slot.
      
      ACL2 !>(apply$ '(lambda (t) (cons t t)) '(a))
      
      ACL2 Error in TOP-LEVEL: The second element of a well-formed
      LAMBDA object or lambda$ term must be a true list of distinct
      legal variable symbols and (T) is not.  See :DOC
      gratuitous-lambda-object-restrictions for a workaround if you
      really mean to have an ill-formed LAMBDA-like constant in your
      code.  Note: this error occurred in the context
      (APPLY$ '(LAMBDA (T) (CONS T T)) '(A)).
      
      ; Bypass 1:  Cons the ill-formed object together in place.
      
      ACL2 !>(apply$ (cons 'lambda '((t) (cons t t))) '(a))
      (A . A)
      
      ; Bypass 1 (more attractive but perhaps too subtle): Use
      ; backquote.  This looks prettier, indeed, it is almost
      ; unnoticeable!  But it does more eval-time consing.
      
      ACL2 !>(apply$ `(lambda (t) (cons t t)) '(a))
      (A . A)
      
      ; Bypass 2:  Use defconst first.  No runtime consing.
      
      ACL2 !>(defconst *my-ill-formed-lambda*
                `(lambda (t) (cons t t)))
      ...output elided...
      
      ACL2 !>(apply$ *my-ill-formed-lambda* '(a))
      (A . A)
      
      ; You can, of course, use these bypasses when defining new
      ; functions.
      
      ACL2 !>(defun foo (x) (apply$ *my-ill-formed-lambda* (list x)))
      ...successful defun output elided...
      
      ; You can then execute the new function, possibly slowly.
      
      ACL2 !>(foo 'b)
      (B . B)
      
      ; But you can't warrant the new function because defwarrant
      ; can't determine the ilks.
      
      ACL2 !>(defwarrant foo)
      
      ACL2 Error in DEFWARRANT: FOO will not be warranted because
      a :FN slot in its body is occupied by a quoted cons object,
      '(LAMBDA (T) (CONS T T)), that is not a well-formed,
      fully-translated, closed ACL2 lambda object. ...
      
      ; Thus, you can't apply$ 'foo either.
      
      ACL2 !>(apply$ 'foo '(c))
      
      ACL2 Error in TOP-LEVEL: The value of APPLY$-USERFN is not
      specified on FOO because FOO has not been warranted.

      By the way, :FN slots are treated differently in another way by translate: lambda$ terms are only allowed in :FN slots. This restriction is necessary for ACL2's correct operation. Lambda$ expands differently in the logic than it does in the underlying Common Lisp. If lambda$ terms were allowed to occur anywhere, this difference could be detected by the difference between proved behavior and computed behavior and could be used to render ACL2 unsound.