Included Books
other
(in-package "ACL2")
include-book
(include-book "xdoc/top" :dir :system)
other
(defxdoc std/lists/abstract :parents (std/lists) :short "Abstract theories for listp, projection, and mapappend functions" :long "<p>This book defines various generic functions:</p> <ul> <li>element-p</li> <li>element-fix</li> <li>element-equiv</li> <li>element-list-p</li> <li>element-list-fix</li> <li>element-list-equiv</li> <li>element-list-projection</li> <li>element-list-mapappend</li> </ul> <p>The idea is that in other books, we can add various theorems about how these generic functions behave in relation to other functions such as nth, index-of, member, etc, which we can use in pluggable forms of @(see std::deflist), @(see std::defprojection), or @(see std::defmapappend). However, as yet this functionality is only implemented for @(see std::deflist) (and through @(see std::deflist), also @(see fty::deflist)).</p> <p>We'll describe in this documentation how to write theorems that can be instantiated by @(see std::deflist) so that they can be used for arbitrary typed lists. Eventually, this will also apply to @(see std::defprojection) and @(see std::defmapappend).</p> <h2>Writing Generic Typed-list Rules</h2> <h3>Generic Rule Macros</h3> <p>Deflist creates theorems for each new list type it defines by instantiating a list of theorems recorded in a table. To create a new theorem and add it to that table so that it is available to deflist, use the @(see def-listp-rule) macro, which is similar to defthm. There are other such macros for rules about other kinds of functions as well:</p> <ul> <li>@('def-listp-rule') theorems will be instantiated by @(see std::deflist) and @(see fty::deflist)</li> <li>@('def-listfix-rule') theorems will be instantiated by @(see fty::deflist), pertaining to the list-fix function it introduces</li> <li>@('def-projection-rule') theorems will be instantiated by @(see std::defprojection)</li> <li>@('def-mapappend-rule') theorems will be instantiated by @(see std::defmapappend).</li> </ul> <p>These macros all take the same basic arguments as @(see defthm) but some additional keyword arguments as well; the following shows an elaborate example.</p> @({ (def-listp-rule element-list-p-when-not-consp-non-true-list (implies (and (element-list-final-cdr-p t) (not (consp x))) (element-list-p x)) :hints (("goal" :expand ((element-list-p)))) :rule-classes :rewrite :otf-flg nil :requirement (not true-listp) :name element-list-p-when-not-consp :body (implies (not (consp x)) (element-list-p x)) :inst-rule-classes ((:rewrite :backchain-limit-lst 2)) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0)) :tags (:basic)) }) <p>To briefly describe the keyword arguments:</p> <ul> <li>@(':hints'), @(':rule-classes'), and @(':otf-flg') are the same as in @(see defthm) and do not affect what is stored for later instantiation</li> <li>@(':requirement') restricts this rule to only apply to certain kinds of typed lists; see the section "Variants and Requirements" below</li> <li>@(':name') overrides the theorem name template used by instantiations of this theorem</li> <li>@(':body') overrides the theorem body as the template to be used for instantiations; see the "Variants and Requirements" section</li> <li>@(':inst-rule-classes') overrides the rule-classes used by instantiations of this theorem</li> <li>@(':cheap-rule-classes') provide an alternative rule-classes if the option @(':cheap t') is given to deflist</li> <li>@(':tags') are freeform annotations of the rules, which can be used to disable in bulk certain sets of rules from being instantiated.</li> </ul> <h3>Variants and Requirements</h3> <p>Some theorems pertaining to typed lists are best phrased differently when:</p> <ul> <li>the list recognizer requires/does not require a NIL final cdr</li> <li>the list element recognizer is true of/is not true of NIL, or its value on NIL is unknown or varies with other parameters.</li> </ul> <p>The example @('def-listp-rule') form above, here reproduced with irrelevant parts removed, helps to show how we accommodate these variants:</p> @({ (def-listp-rule element-list-p-when-not-consp-non-true-list (implies (and (element-list-final-cdr-p t) (not (consp x))) (element-list-p x)) :requirement (not true-listp) :name element-list-p-when-not-consp :body (implies (not (consp x)) (element-list-p x))) }) <p>The @(':body') shows the theorem that will be produced by instantiations of this rule. However, this is only true when element-list-p is non-strict, i.e. it allows a non-nil final cdr. The generic definition of element-list-p accomodates both strict and non-strict versions by calling a constrained function @('element-list-final-cdr-p') on its final cdr. This function is constrained to either be true on every input, or to only be true on NIL; thus, it matches the two typical final cdr behaviors of list recognizers. To prove that any non-cons is element-list-p, we need to assume we are in the non-strict case -- where @('element-list-final-cdr-p') is true of every input -- which, by its constraint, is true iff @('(element-list-final-cdr-p t)'). To avoid instantiating this rule on typed lists that are strict, we add the @(':requirement') field. In @('std::deflist'), before instantiating a rule, the @(':requirement') field is evaluated with variables such as @('true-listp') bound to values based on the particular variant. Finally, the @(':name') field lets us consistently name the instantiated theorems when there are different variants; e.g., for the strict case, we can have this other form that produces a different theorem but uses the same naming convention:</p> @({ (def-listp-rule element-list-p-when-not-consp-true-list (implies (and (not (element-list-final-cdr-p t)) (not (consp x))) (equal (element-list-p x) (not x))) :requirement true-listp :name element-list-p-when-not-consp :body (implies (not (consp x)) (equal (element-list-p x) (not x)))) }) <h3>List of requirement variables recognized by @(see std::deflist)</h3> <p>Note: All of these are symbols in the ACL2 package.</p> <ul> <li>@('element-p-of-nil') is true if NIL is known to be an element</li> <li>@('not-element-p-of-nil') is true if NIL is known not to be an element. Note: mutually exclusive with @('element-p-of-nil'), but both may be false in cases where the status of NIL as an element is unknown or depends on other input parameters.</li> <li>@('negatedp') is true if we are creating a list that recognizes elements defined by @('NOT') of some predicate, which may affect the correct formulation of rewrite rules</li> <li>@('true-listp') is true if the list recognizer is strict, i.e., implies true-listp</li> <li>@('single-var') is true if the list recognizer has no parameters other than the list variable</li> <li>@('cheap') is true if the user gave an extra option requesting cheaper versions of some rules.</li> <li>@('simple') is true if the element recognizer is a simple function, rather than some more complicated term.</li> </ul> <h3>Using Tags to Disable Instantiation</h3> <p>Certain generic rules are tagged so as to group them with other rules. For example, all the rules defined in "std/osets/element-list.lisp" are tagged with @(':osets'). This makes it easy to turn these rules off so that a subsequent deflist form will not instantiate this set of rules. This form does that:</p> @({ (local (ruletable-delete-tags! acl2::listp-rules (:osets))) }) <p>On the other hand, in the unlikely event that you only wanted the rules tagged with @(':osets') you could do:</p> @({ (local (ruletable-keep-tags! acl2::listp-rules (:osets))) }) ")
local
(local (set-default-parents std/lists/abstract))
other
(defsection element-p :short "Generic typed list element recognizer." (encapsulate (((element-p *) => *) ((element-example) => *)) (local (defun element-p (x) (natp x))) (local (defun element-example nil 0))) (encapsulate (((non-element-p *) => *)) (local (defun non-element-p (x) (not (element-p x)))) (defthm non-element-p-def (iff (non-element-p x) (not (element-p x))))))
other
(defsection element-fix :short "Generic fixing function for typed list elements." (encapsulate (((element-fix *) => *)) (local (defun element-fix (x) (if (element-p x) x (element-example)))) (defthm element-p-of-element-fix (implies (element-p (element-example)) (element-p (element-fix x)))) (defthm element-fix-when-element-p (implies (element-p x) (equal (element-fix x) x))) (defthm element-fix-idempotent (equal (element-fix (element-fix x)) (element-fix x)))))
other
(defsection element-equiv :short "Generic equivalence relation among typed list elements." (defun element-equiv (x y) (declare (xargs :verify-guards nil)) (equal (element-fix x) (element-fix y))) (defequiv element-equiv) (defcong element-equiv equal (element-fix x) 1) (defthm element-fix-under-element-equiv (element-equiv (element-fix x) x)) (defthm equal-of-element-fix-1-forward-to-element-equiv (implies (equal (element-fix x) y) (element-equiv x y)) :rule-classes :forward-chaining) (defthm equal-of-element-fix-2-forward-to-element-equiv (implies (equal x (element-fix y)) (element-equiv x y)) :rule-classes :forward-chaining) (defthm element-equiv-of-element-fix-1-forward (implies (element-equiv (element-fix x) y) (element-equiv x y)) :rule-classes :forward-chaining) (defthm element-equiv-of-element-fix-2-forward (implies (element-equiv x (element-fix y)) (element-equiv x y)) :rule-classes :forward-chaining))
element-list-final-cdr-p-of-nilencapsulate
(encapsulate (((element-list-final-cdr-p *) => *)) (local (defun element-list-final-cdr-p (x) (not x))) (defthm element-list-final-cdr-p-of-nil (element-list-final-cdr-p nil)) (defthm element-list-final-cdr-p-type (or (equal (element-list-final-cdr-p x) t) (equal (element-list-final-cdr-p x) nil)) :rule-classes :type-prescription) (defthm element-list-final-cdr-p-rewrite (implies (syntaxp (and (not (equal x ''t)) (not (equal x ''nil)))) (equal (element-list-final-cdr-p x) (or (equal x nil) (element-list-final-cdr-p t))))))
def-generic-rulemacro
(defmacro def-generic-rule (tablename thmname thm &key (name 'nil name-p) (body 'nil body-p) disable (requirement 'nil requirement-p) (inst-rule-classes 'nil inst-rule-classes-p) (cheap-rule-classes 'nil cheap-rule-classes-p) (rule-classes ':rewrite) tags hints otf-flg) `(progn (defthm ,THMNAME ,THM :hints ,HINTS :rule-classes ,RULE-CLASSES :otf-flg ,OTF-FLG) (table ,TABLENAME ',THMNAME (or '(,@(AND NAME-P `((:NAME ,NAME))) ,@(AND BODY-P `((:BODY ,BODY))) ,@(AND DISABLE `((:DISABLE T))) ,@(AND REQUIREMENT-P `((:REQUIREMENT ,REQUIREMENT))) ,@(AND INST-RULE-CLASSES-P `((:RULE-CLASSES ,INST-RULE-CLASSES))) ,@(AND CHEAP-RULE-CLASSES-P `((:CHEAP-RULE-CLASSES ,CHEAP-RULE-CLASSES))) ,@(AND TAGS `((:TAGS . ,TAGS)))) t))))
ruletable-delete-tagsfunction
(defun ruletable-delete-tags (tags table) (if (atom table) nil (if (and (consp (cdar table)) (intersectp-eq tags (cdr (assoc :tags (cdar table))))) (ruletable-delete-tags tags (cdr table)) (cons (car table) (ruletable-delete-tags tags (cdr table))))))
ruletable-delete-tags!macro
(defmacro ruletable-delete-tags! (table-name tags) `(table ,TABLE-NAME nil (ruletable-delete-tags ',TAGS (table-alist ',TABLE-NAME world)) :clear))
ruletable-keep-tagsfunction
(defun ruletable-keep-tags (tags table) (if (atom table) nil (if (and (consp (cdar table)) (intersectp-eq tags (cdr (assoc :tags (cdar table))))) (cons (car table) (ruletable-keep-tags tags (cdr table))) (ruletable-keep-tags tags (cdr table)))))
ruletable-keep-tags!macro
(defmacro ruletable-keep-tags! (table-name tags) `(table ,TABLE-NAME nil (ruletable-keep-tags ',TAGS (table-alist ',TABLE-NAME world)) :clear))
other
(defsection def-projection-rule :short "Define a theorem and save it in a table, denoting that it is a rule about elementlist-projection." (defmacro def-projection-rule (&rest args) `(def-generic-rule projection-rules . ,ARGS)))
other
(defsection def-listp-rule :short "Define a theorem and save it in a table, denoting that it is a rule about element-list-p." (defmacro def-listp-rule (&rest args) `(def-generic-rule listp-rules . ,ARGS)))
other
(defsection def-nonempty-listp-rule :short "Define a theorem and save it in a table, denoting that it is a rule about element-list-nonempty-p." (defmacro def-nonempty-listp-rule (&rest args) `(def-generic-rule nonempty-listp-rules . ,ARGS)))
other
(defsection def-listfix-rule :short "Define a theorem and save it in a table, denoting that it is a rule about element-list-fix." (defmacro def-listfix-rule (&rest args) `(def-generic-rule listfix-rules . ,ARGS)))
other
(defsection def-mapappend-rule :short "Define a theorem and save it in a table, denoting that it is a rule about elementlist-mapappend." (defmacro def-mapappend-rule (&rest args) `(def-generic-rule mapappend-rules . ,ARGS)))
other
(defsection element-list-p :short "Generic typed list recognizer function." (defun element-list-p (x) (if (atom x) (element-list-final-cdr-p x) (and (element-p (car x)) (element-list-p (cdr x))))) (in-theory (disable (element-list-p))) (def-listp-rule element-list-p-of-cons (equal (element-list-p (cons a x)) (and (element-p a) (element-list-p x)))) (def-listp-rule element-list-p-of-cdr-when-element-list-p (implies (element-list-p (double-rewrite x)) (element-list-p (cdr x)))) (def-listp-rule element-list-p-when-not-consp-non-true-list (implies (and (element-list-final-cdr-p t) (not (consp x))) (element-list-p x)) :requirement (not true-listp) :name element-list-p-when-not-consp :body (implies (not (consp x)) (element-list-p x))) (def-listp-rule element-list-p-when-not-consp-true-list (implies (and (not (element-list-final-cdr-p t)) (not (consp x))) (equal (element-list-p x) (not x))) :requirement true-listp :name element-list-p-when-not-consp :body (implies (not (consp x)) (equal (element-list-p x) (not x)))) (def-listp-rule element-p-of-car-when-element-list-p-when-element-p-nil (implies (and (element-p nil) (element-list-p x)) (element-p (car x))) :requirement (and element-p-of-nil simple) :name element-p-of-car-when-element-list-p :body (implies (element-list-p x) (element-p (car x))) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-listp-rule element-p-of-car-when-element-list-p-when-not-element-p-nil-and-not-negated (implies (and (not (element-p nil)) (element-list-p x)) (iff (element-p (car x)) (consp x))) :requirement (and not-element-p-of-nil (not negatedp) simple) :name element-p-of-car-when-element-list-p :body (implies (element-list-p x) (iff (element-p (car x)) (consp x))) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-listp-rule element-p-of-car-when-element-list-p-when-not-element-p-nil-and-negated (implies (and (not (element-p nil)) (element-list-p x)) (iff (non-element-p (car x)) (not (consp x)))) :requirement (and not-element-p-of-nil negatedp simple) :name element-p-of-car-when-element-list-p :body (implies (element-list-p x) (iff (non-element-p (car x)) (not (consp x)))) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-listp-rule element-p-of-car-when-element-list-p-when-unknown-nil (implies (element-list-p x) (iff (element-p (car x)) (or (consp x) (element-p nil)))) :requirement (and (not element-p-of-nil) (not not-element-p-of-nil) (not negatedp) simple) :name element-p-of-car-when-element-list-p :body (implies (element-list-p x) (iff (element-p (car x)) (or (consp x) (element-p nil)))) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-listp-rule element-p-of-car-when-element-list-p-when-unknown-nil-negated (implies (element-list-p x) (iff (non-element-p (car x)) (and (not (consp x)) (non-element-p nil)))) :requirement (and (not element-p-of-nil) (not not-element-p-of-nil) negatedp simple) :name element-p-of-car-when-element-list-p :body (implies (element-list-p x) (iff (non-element-p (car x)) (and (not (consp x)) (non-element-p nil)))) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-listp-rule true-listp-when-element-list-p-rewrite (implies (and (element-list-p x) (not (element-list-final-cdr-p t))) (true-listp x)) :name true-listp-when-element-list-p :requirement (and true-listp (not single-var)) :body (implies (element-list-p x) (true-listp x)) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-listp-rule true-listp-when-element-list-p-compound-recognizer (implies (and (element-list-p x) (not (element-list-final-cdr-p t))) (true-listp x)) :rule-classes nil :name true-listp-when-element-list-p-compound-recognizer :requirement (and true-listp single-var) :body (implies (element-list-p x) (true-listp x)) :inst-rule-classes :compound-recognizer) (def-listp-rule element-list-p-of-append-non-true-list (implies (element-list-final-cdr-p t) (equal (element-list-p (append a b)) (and (element-list-p a) (element-list-p b)))) :requirement (not true-listp) :name element-list-p-of-append :body (equal (element-list-p (append a b)) (and (element-list-p a) (element-list-p b)))))
other
(defsection element-list-nonempty-p :short "Generic typed list recognizer function." (defun element-list-nonempty-p (x) (and (consp x) (element-p (car x)) (let ((x (cdr x))) (if (consp x) (element-list-nonempty-p x) (element-list-final-cdr-p x))))) (in-theory (disable (element-list-nonempty-p))) (def-nonempty-listp-rule element-list-nonempty-p-of-cons (implies (element-list-nonempty-p x) (iff (element-list-nonempty-p (cons a x)) (element-p a)))) (def-nonempty-listp-rule element-list-nonempty-p-of-singleton-true-list (iff (element-list-nonempty-p (cons a nil)) (element-p a)) :requirement true-listp :name element-list-nonempty-p-of-singleton) (def-nonempty-listp-rule element-list-nonempty-p-of-singleton-non-true-list (implies (and (not (consp x)) (element-list-final-cdr-p t)) (iff (element-list-nonempty-p (cons a x)) (element-p a))) :requirement (not true-listp) :name element-list-nonempty-p-of-singleton :body (implies (not (consp x)) (iff (element-list-nonempty-p (cons a x)) (element-p a)))) (def-nonempty-listp-rule element-list-nonempty-p-of-cdr-when-element-list-nonempty-p (implies (and (element-list-nonempty-p (double-rewrite x)) (consp (cdr x))) (element-list-nonempty-p (cdr x)))) (def-nonempty-listp-rule element-list-nonempty-p-when-not-consp (implies (not (consp x)) (not (element-list-nonempty-p x)))) (def-nonempty-listp-rule element-list-nonempty-p-implies-consp (implies (element-list-nonempty-p x) (consp x)) :rule-classes :forward-chaining) (def-nonempty-listp-rule element-p-of-car-when-element-list-nonempty-p (implies (element-list-nonempty-p x) (element-p (car x))) :requirement simple :name element-p-of-car-when-element-list-nonempty-p :body (implies (element-list-nonempty-p x) (element-p (car x))) :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-nonempty-listp-rule true-listp-when-element-list-nonempty-p-rewrite (implies (and (element-list-nonempty-p x) (not (element-list-final-cdr-p t))) (true-listp x)) :rule-classes nil :name true-listp-when-element-list-nonempty-p :requirement (and true-listp (not single-var)) :body (implies (element-list-nonempty-p x) (true-listp x)) :inst-rule-classes :rewrite :cheap-rule-classes ((:rewrite :backchain-limit-lst 0))) (def-nonempty-listp-rule true-listp-when-element-list-nonempty-p-compound-recognizer (implies (and (element-list-nonempty-p x) (not (element-list-final-cdr-p t))) (true-listp x)) :rule-classes nil :name true-listp-when-element-list-nonempty-p :requirement (and true-listp single-var) :body (implies (element-list-nonempty-p x) (true-listp x)) :inst-rule-classes :compound-recognizer) (def-nonempty-listp-rule element-list-nonempty-p-of-append (implies (and (element-list-nonempty-p a) (element-list-nonempty-p b)) (element-list-nonempty-p (append a b)))))
other
(defsection element-list-fix :short "Generic typed list fixing function." (defun element-list-fix (x) (if (atom x) (and (element-list-final-cdr-p t) x) (cons (element-fix (car x)) (element-list-fix (cdr x))))) (in-theory (disable (element-list-fix))) (def-listfix-rule element-list-p-of-element-list-fix (implies (element-p (element-example)) (element-list-p (element-list-fix x))) :body (element-list-p (element-list-fix x))) (def-listfix-rule element-list-fix-when-element-list-p (implies (element-list-p x) (equal (element-list-fix x) x))) (def-listfix-rule consp-of-element-list-fix (equal (consp (element-list-fix x)) (consp x))) (def-listfix-rule element-list-fix-of-cons (equal (element-list-fix (cons a x)) (cons (element-fix a) (element-list-fix x)))) (def-listfix-rule len-of-element-list-fix (equal (len (element-list-fix x)) (len x))) (def-listfix-rule element-fix-of-append (equal (element-list-fix (append a b)) (append (element-list-fix a) (element-list-fix b)))))
other
(defsection element-list-equiv :short "Generic typed list equivalence relation" (defun element-list-equiv (x y) (declare (xargs :verify-guards nil)) (equal (element-list-fix x) (element-list-fix y))) (defequiv element-list-equiv) (table listfix-rules 'element-list-equiv t) (defcong element-list-equiv equal (element-list-fix x) 1) (table listfix-rules 'element-list-equiv-implies-equal-element-list-fix-1 t) (def-listfix-rule element-list-fix-under-element-list-equiv (element-list-equiv (element-list-fix x) x)) (def-listfix-rule equal-of-element-list-fix-1-forward-to-element-list-equiv (implies (equal (element-list-fix x) y) (element-list-equiv x y)) :rule-classes :forward-chaining) (def-listfix-rule equal-of-element-list-fix-2-forward-to-element-list-equiv (implies (equal x (element-list-fix y)) (element-list-equiv x y)) :rule-classes :forward-chaining) (def-listfix-rule element-list-equiv-of-element-list-fix-1-forward (implies (element-list-equiv (element-list-fix x) y) (element-list-equiv x y)) :rule-classes :forward-chaining) (def-listfix-rule element-list-equiv-of-element-list-fix-2-forward (implies (element-list-equiv x (element-list-fix y)) (element-list-equiv x y)) :rule-classes :forward-chaining) (defcong element-list-equiv element-equiv (car x) 1) (table listfix-rules 'element-list-equiv-implies-element-equiv-car-1 t) (defcong element-list-equiv element-list-equiv (cdr x) 1) (table listfix-rules 'element-list-equiv-implies-element-list-equiv-cdr-1 t) (defcong element-equiv element-list-equiv (cons x y) 1) (table listfix-rules 'element-equiv-implies-element-list-equiv-cons-1 t) (defcong element-list-equiv element-list-equiv (cons x y) 2) (table listfix-rules 'element-list-equiv-implies-element-list-equiv-cons-2 t))
other
(defsection outelement-p :short "Generic recognizer for the output element type of a projection." (encapsulate (((outelement-p *) => *) ((outelement-example) => *)) (local (defun outelement-p (x) (natp x))) (local (defun outelement-example nil 0)) (defthm outelement-p-of-outelement-example (outelement-p (outelement-example)))))
outelement-list-final-cdr-p-of-nilencapsulate
(encapsulate (((outelement-list-final-cdr-p *) => *)) (local (defun outelement-list-final-cdr-p (x) (not x))) (defthm outelement-list-final-cdr-p-of-nil (outelement-list-final-cdr-p nil)) (defthm outelement-list-final-cdr-p-type (or (equal (outelement-list-final-cdr-p x) t) (equal (outelement-list-final-cdr-p x) nil)) :rule-classes :type-prescription) (defthm outelement-list-final-cdr-p-rewrite (implies (syntaxp (and (not (equal x ''t)) (not (equal x ''nil)))) (equal (outelement-list-final-cdr-p x) (or (equal x nil) (outelement-list-final-cdr-p t))))))
other
(defsection outelement-list-p :short "Generic recognizer for the output list type of a projection." (defun outelement-list-p (x) (if (atom x) (outelement-list-final-cdr-p x) (and (outelement-p (car x)) (outelement-list-p (cdr x))))) (in-theory (disable (outelement-list-p))) (defthm outelement-list-p-of-append (implies (and (outelement-list-p x) (outelement-list-p y)) (outelement-list-p (append x y)))))
other
(defsection element-xformer :short "Generic transform to be projected over a typed list." (encapsulate (((element-xformer *) => *)) (local (defun element-xformer (x) (declare (ignore x)) (outelement-example))) (defthm outelement-p-of-element-xformer (implies (element-p x) (outelement-p (element-xformer x))))))
other
(defsection elementlist-projection :short "Generic projection over a typed list." (defun elementlist-projection (x) (if (atom x) nil (cons (element-xformer (car x)) (elementlist-projection (cdr x))))) (def-projection-rule outelement-list-p-of-elementlist-projection (implies (element-list-p x) (outelement-list-p (elementlist-projection x))) :requirement resulttype) (def-projection-rule elementlist-projection-of-cons (equal (elementlist-projection (cons a b)) (cons (element-xformer a) (elementlist-projection b)))) (def-projection-rule elementlist-projection-when-not-consp (implies (not (consp x)) (equal (elementlist-projection x) nil))) (def-projection-rule true-listp-of-elementlist-projection (true-listp (elementlist-projection x)) :rule-classes :type-prescription :inst-rule-classes :type-prescription) (def-projection-rule len-of-elementlist-projection (equal (len (elementlist-projection x)) (len x))) (def-projection-rule consp-of-elementlist-projection (equal (consp (elementlist-projection x)) (consp x))) (def-projection-rule elementlist-projection-under-iff (iff (elementlist-projection x) (consp x))) (def-projection-rule car-of-elementlist-projection-when-nil-preservingp (implies (equal nil (element-xformer nil)) (equal (car (elementlist-projection x)) (element-xformer (car x)))) :requirement nil-preservingp :name car-of-elementlist-projection :body (equal (car (elementlist-projection x)) (element-xformer (car x)))) (def-projection-rule car-of-elementlist-projection (equal (car (elementlist-projection x)) (and (consp x) (element-xformer (car x)))) :requirement (not nil-preservingp)) (def-projection-rule cdr-of-elementlist-projection (equal (cdr (elementlist-projection x)) (elementlist-projection (cdr x)))) (def-projection-rule elementlist-projection-of-append (equal (elementlist-projection (append a b)) (append (elementlist-projection a) (elementlist-projection b)))))
other
(defsection element-listxformer :short "Generic element-list transform for mapappend" (encapsulate (((element-listxformer *) => *)) (local (defun element-listxformer (x) (declare (ignore x)) (list (outelement-example)))) (defthm outelement-list-p-of-element-listxformer (implies (element-p x) (outelement-list-p (element-listxformer x))))))
other
(defsection elementlist-mapappend :short "Generic mapappend over a typed list." (defun elementlist-mapappend (x) (if (atom x) nil (append (element-listxformer (car x)) (elementlist-mapappend (cdr x))))) (def-mapappend-rule outelement-list-p-of-elementlist-mapappend (implies (element-list-p x) (outelement-list-p (elementlist-mapappend x))) :requirement resulttype) (def-mapappend-rule elementlist-mapappend-of-cons (equal (elementlist-mapappend (cons a b)) (append (element-listxformer a) (elementlist-mapappend b)))) (def-mapappend-rule elementlist-mapappend-when-not-consp (implies (not (consp x)) (equal (elementlist-mapappend x) nil))) (def-mapappend-rule elementlist-mapappend-of-append (equal (elementlist-mapappend (append a b)) (append (elementlist-mapappend a) (elementlist-mapappend b)))))
in-theory
(in-theory (disable true-listp-when-element-list-p-rewrite))