Included Books
other
(in-package "ACL2")
include-book
(include-book "xdoc/top" :dir :system)
local
(local (include-book "system/all-fnnames" :dir :system))
install-not-normalized-namefunction
(defun install-not-normalized-name (name) (declare (xargs :guard (symbolp name))) (intern-in-package-of-symbol (concatenate 'string (symbol-name name) "$NOT-NORMALIZED") name))
install-not-normalized-fn-1function
(defun install-not-normalized-fn-1 (name wrld ens clique defthm-name enable) (declare (xargs :mode :program :guard (and (symbolp name) (symbolp defthm-name) (plist-worldp wrld) (enabled-structure-p ens) (symbol-listp clique)))) (let* ((formals (formals name wrld)) (unnormalized-body (or (getprop name 'unnormalized-body nil 'current-acl2-world wrld) (er hard? 'install-not-normalized-fn-1 "There is no defun body associated with the name, ~x0." name))) (defthm-name (or defthm-name (install-not-normalized-name name))) (controller-alist (let* ((def-bodies (getprop name 'def-bodies nil 'current-acl2-world wrld)) (def-body (and (true-listp def-bodies) (car def-bodies)))) (and (access def-body def-body :controller-alist)))) (cliquep (and clique (intersectp-eq clique (all-fnnames unnormalized-body)))) (defthmd? (case enable (:auto (if (disabledp-fn `(:definition ,NAME) ens wrld) 'defthmd 'defthm)) ((t) 'defthm) (otherwise 'defthmd)))) `((,DEFTHMD? ,DEFTHM-NAME (equal (,NAME ,@FORMALS) ,UNNORMALIZED-BODY) :hints (("Goal" :by ,NAME)) :rule-classes ((:definition :install-body t ,@(AND CLIQUEP (LIST :CLIQUE CLIQUE)) ,@(AND CLIQUEP CONTROLLER-ALIST (LIST :CONTROLLER-ALIST CONTROLLER-ALIST))))) (in-theory (disable ,NAME)))))
install-not-normalized-fn-lstfunction
(defun install-not-normalized-fn-lst (fns wrld ens all-fns defthm-name-doublets enable) (declare (xargs :mode :program :guard (and (symbol-listp fns) (symbol-listp all-fns) (symbol-alistp defthm-name-doublets) (doublet-listp defthm-name-doublets) (symbol-listp (strip-cadrs defthm-name-doublets)) (plist-worldp wrld) (enabled-structure-p ens)))) (cond ((endp fns) nil) (t (append (install-not-normalized-fn-1 (car fns) wrld ens all-fns (cadr (assoc-eq (car fns) defthm-name-doublets)) enable) (install-not-normalized-fn-lst (cdr fns) wrld ens all-fns defthm-name-doublets enable)))))
install-not-normalized-fnfunction
(defun install-not-normalized-fn (name wrld ens allp defthm-name enable) (declare (xargs :mode :program :guard (and (symbolp name) (plist-worldp wrld) (enabled-structure-p ens)))) (let* ((ctx 'install-not-normalized)) (cond ((member-eq enable '(t nil :auto)) (let* ((fns (getprop name 'recursivep nil 'current-acl2-world wrld)) (defthm-name-doublets (and defthm-name (cond ((symbolp defthm-name) (list (list name defthm-name))) ((not (and (symbol-alistp defthm-name) (doublet-listp defthm-name) (symbol-listp (strip-cadrs defthm-name)))) (er hard? ctx "Illegal :defthm-name argument: ~x0" defthm-name)) ((and (true-listp fns) (not (subsetp-eq (strip-cars defthm-name) fns))) (let ((bad (set-difference-eq (strip-cars defthm-name) fns))) (er hard? ctx "Illegal :defthm-name argument: ~x0. The ~ name~#1~[~x1 is~/s ~&1 are~] bound in your ~ :defthm-name argument but not among the ~ list of candidate names, ~x2, for being ~ given an unnormalized definition." defthm-name bad fns))) (t defthm-name))))) (cond ((symbol-listp fns) (install-not-normalized-fn-lst (or (and allp fns) (list name)) wrld ens fns defthm-name-doublets enable)) (t (er hard? ctx "Implementation error! Not a non-empty symbol-listp: ~x0" fns))))) (t (er hard? ctx "The :enable argument of ~x0 must be ~v1. The argument ~x2 is ~ thus illegal." 'install-not-normalized '(t nil :auto) enable)))))
install-not-normalizedmacro
(defmacro install-not-normalized (name &key (allp 't) defthm-name (enable ':auto)) (declare (xargs :guard (and name (symbolp name)))) `(make-event (list* 'encapsulate nil '(set-ignore-ok t) '(set-irrelevant-formals-ok t) (install-not-normalized-fn ',NAME (w state) (ens state) ,ALLP ,DEFTHM-NAME ,ENABLE))))
fn-is-body-namefunction
(defun fn-is-body-name (name) (declare (xargs :guard (symbolp name))) (intern-in-package-of-symbol (concatenate 'string (symbol-name name) "$IS-BODY") name))
fn-is-bodymacro
(defmacro fn-is-body (name &key hints thm-name rule-classes) (declare (xargs :guard (and name (symbolp name)))) `(make-event (let* ((name ',NAME) (wrld (w state)) (formals (formals name wrld)) (body (getprop name 'unnormalized-body nil 'current-acl2-world wrld))) (list* 'defthm (or ',THM-NAME (fn-is-body-name name)) (list 'equal (cons name formals) body) (append (and ',HINTS (list :hints ',HINTS)) (list :rule-classes ',RULE-CLASSES))))))
other
(defxdoc install-not-normalized :parents (proof-automation) :short "Install an unnormalized definition" :long "@({ General Form: (install-not-normalized NAME :allp FLG :defthm-name DNAME-SPEC) }) <p>We explain the arguments of @('install-not-normalized') below, but first let us illustrate its use with an example.</p> <p>By default, ACL2 simplifies definitions by ``normalizing'' their bodies; see @(see normalize). If you prefer that ACL2 avoid such simplification when expanding a function call, then you can assign the value of @('nil') to @(tsee xargs) keyword @(':normalize') (see @(see defun)) instead of the default value of @('t'). But that might not be a reasonable option, for example because the definition in question occurs in an included book that you prefer not to edit. An alternative is to call a macro, @('install-not-normalized').</p> <p>Consider the following example from Eric Smith.</p> @({ (defun return-nil (x) (declare (ignore x)) nil) (defun foo (x) (return-nil x)) ; Fails! (thm (equal (foo x) (return-nil x)) :hints (("Goal" :in-theory '(foo)))) ; Also fails! (thm (equal (foo x) (return-nil x)) :hints (("Goal" :expand ((foo x)) :in-theory (theory 'minimal-theory)))) }) <p>The problem is that ACL2 stores @('nil') for the body of @('foo'), using ``type reasoning'' to deduce that @('return-nil') always returns the value, @('nil'). So if @('foo') is the only enabled rule, then we are left trying to prove that @('nil') equals @('(return-nil x)'). Of course, this example is trivial to fix by enabling @('return-nil'), or even just its @(':')@(tsee type-prescription) rule, but we want to support development of robust tools that manipulate functions without needing to know anything about their callees. </p> <p>To solve this problem, we can invoke @('(install-not-normalized foo)'), which generates the following @(':')@(tsee definition) rule.</p> @({ (DEFTHM FOO$NOT-NORMALIZED (EQUAL (FOO X) (RETURN-NIL X)) :HINTS (("Goal" :BY FOO)) :RULE-CLASSES ((:DEFINITION :INSTALL-BODY T))) }) <p>Each of the following now succeeds. For the second, note that the rule @('FOO$NOT-NORMALIZED') has installed a new body for @('FOO').</p> @({ (thm (equal (foo x) (return-nil x)) :hints (("Goal" :in-theory '(foo$not-normalized)))) (thm (equal (foo x) (return-nil x)) :hints (("Goal" :expand ((foo x)) :in-theory (theory 'minimal-theory)))) }) <p>Let us see some more example forms; then, we discuss the general form.</p> @({ Example Forms: (install-not-normalized NAME) ; Equivalent to the form above: (install-not-normalized NAME :allp t) ; Generate a definition for NAME but not for others from its mutual-recursion: (install-not-normalized NAME :allp nil) ; Give the name BAR to the new theorem: (install-not-normalized NAME :defthm-name 'BAR) ; Give the name F1-DEF to the new theorem for F1 and ; give the name F2-DEF to the new theorem for F2: (install-not-normalized NAME :defthm-name '((f1 f1-def) (f2 f1-def))) General Form: (install-not-normalized NAME :allp FLG :defthm-name DNAME-SPEC :enable E) }) <p>where the keyword arguments are evaluated, but not @('NAME'), and:</p> <ul> <li>@('NAME') is the name of a function introduced by @(tsee defun) (or one of its variants, including @(tsee defund) and @(tsee defun-nx)), possibly using @(tsee mutual-recursion).</li> <li>@('FLG') (if supplied) is a Boolean that is relevant only in the case that @('NAME') was introduced using @('mutual-recursion'). When @('FLG') is nil, a @(tsee defthm) event is to be introduced only for @('NAME'); otherwise, there will be a new @('defthm') for every function defined with the same @('mutual-recursion') as @('NAME').</li> <li>@('DNAME-SPEC') (if supplied) is usually a symbol denoting the name of the @('defthm') event to be introduced for @('NAME'), which is @('NAME$NOT-NORMALIZED') by default — that is, the result of modifying the @(tsee symbol-name) of @('F') by adding the suffix @('"$NOT-NORMALIZED"'). Otherwise, of special interest when @('NAME') was introduced with @('mutual-recursion'): @('DNAME-SPEC') is a list of doublets of the form @('(F G)'), where @('F') is a symbol as described for @('NAME') above, and the symbol @('G') is the name of the @('defthm') event generated for the symbol @('F').</li> <li>@('E') is either @(':auto') (the default), @('t'), or @('nil'). If @('E') is @('t') or @('nil') then the generated event is a call of @('defthm') or @(tsee defthmd), respectively. If @('E') is omitted or is @(':auto'), then the generated event is a call of @('defthm') if the original @(see definition) of @('NAME') is @(see enable)d at the time the @('install-not-normalized') event is submitted, and otherwise is a call of @('defthmd').</li> </ul> <p>Any such @('defthm') event has @(':')@(tsee rule-classes) @('((:definition :install-body t))'), with suitable additional fields when appropriate for keywords @(':clique') and @(':controller-alist'). To obtain its default name programmatically:</p> @({ ACL2 !>(install-not-normalized-name 'foo) FOO$NOT-NORMALIZED ACL2 !> }) <p>Remark. Each definition installed by @('install-not-normalized') contains the original body, not a translated version. (See @(see term) for a discussion of the the notion of ``translated term''.)</p> <p>For a somewhat related utility, see @(see fn-is-body).</p> <p>For examples, see the Community Book @('misc/install-not-normalized-tests.lisp').</p>")
other
(defxdoc fn-is-body :parents (proof-automation) :short "Prove that a function called on its formals equals its body" :long "@({ General Form: (fn-is-body fn &key hints thm-name rule-classes) }) <p>Evaluation of the form above generates a @(tsee defthm) event whose name is @('thm-name') — by default, the result of adding the suffix "$IS-BODY" to @('fn'), which is a function symbol. To obtain that name programmatically:</p> @({ ACL2 !>(fn-is-body-name 'foo) FOO$IS-BODY ACL2 !> }) <p>The formula of that @('defthm') event is of the form @('(equal (fn x1 ... xn) <body>)'), where @('(x1 ... xn)') is the list of formal parameters of @('fn') and @('<body>') is the un@(see normalize)d body of @('fn'). If @(':hints') or @(':rule-classes') are supplied, they will be attached to the generated @('defthm') form.</p> <p>Note that the proof of the generated @('defthm') may not follow trivially from the function's @(':')@('definition') rule: by default, that rule is derived from the function's @(see normalize)d body, which may differ from its unnormalized body.</p> <p>For a somewhat related utility, see @(see install-not-normalized).</p> <p>For examples, see the Community Book @('misc/install-not-normalized.lisp').</p>")