diff options
Diffstat (limited to 'books/workshops/2004/smith-et-al/support/bags/meta.lisp')
-rw-r--r-- | books/workshops/2004/smith-et-al/support/bags/meta.lisp | 2320 |
1 files changed, 2320 insertions, 0 deletions
diff --git a/books/workshops/2004/smith-et-al/support/bags/meta.lisp b/books/workshops/2004/smith-et-al/support/bags/meta.lisp new file mode 100644 index 0000000..50495c3 --- /dev/null +++ b/books/workshops/2004/smith-et-al/support/bags/meta.lisp @@ -0,0 +1,2320 @@ +(in-package "BAG") + +(include-book "basic") +(include-book "ordinals/e0-ordinal" :dir :system) +;eventually, move the any-subbagp meta rule below to a different book? + +#| +(defun implies-if (a term) + (declare (type t a term)) + (if a t term)) +|# + +;trying disabled... +(defund meta-subbagp (list1 list2) + (declare (type t list1 list2)) + (subbagp list1 list2)) + +;trying disabled... +(defund meta-memberp (x list) + (declare (type t x list)) + (memberp x list)) + +;;=========================================================================== +;; :meta rule to establish membership syntactically When TERM is a nest of +;; conses and appends which contains a cons of X, we can tell just by looking +;; at TERM that X is a memberp of it. +;============================================================================ + +;How much other behavior should this rule rely on? Should we rely on the fact +;that nests of appends get basically right associated (that is, that the first +;argument to an append is never another append)? What about the fact that, in +;a perm context, the conses are brought before the appends. + +#| +Without the :meta rule, this fails: +(thm (memberp x (cons y (cons yy (append w (cons x (append ww z)))))) + :hints (("Goal" :in-theory (disable memberp)))) +|# + +;The evaluator for the :meta rule syntactic-membership-meta-rule. +(defevaluator evaluator-for-memberp-cons-and-append evaluator-for-memberp-cons-and-append-list + ((memberp x l) + (binary-append x y) + (cons x y) +; (quote x) + (list-fix x) + )) + +;TERM is a nest of conses and appends +;This function looks through that nest for a cons of X. +;If it finds such a cons, it returns T. Else, it returns nil. +;It refuses to look inside any function which is not a cons or an append. +;This no longer depends on nests of appends and conses being normalized? +;BOZO don't need to repeat the checking of X on recursive calls when X doesn't change... pass in a flag? + +(defignore syntax-memberp a (x term) + (declare (xargs :guard (and (pseudo-termp x) + (pseudo-termp term)))) + (if (consp term) + (if (equal (car term) 'quote) ;; '(quote arg1) ;could make this case more efficient?? + (if (and (consp x) + (equal (car x) 'quote) + (null (cddr x)) + (null (cddr term)) + ) + (memberp (cadr x) (cadr term)) ;if x and term are quoted constants, just run memberp on the constants! + nil ;if TERM is a quoted constant but X isn't, we don't really know anything about membership + ) + (if (and (equal (car term) 'cons) ;; '(cons arg1 arg2) + (null (cdddr term)) ;consider inlining this? + ) + (if (equal (cadr term) x) + t ;If the thing consed on is x, we're done. + (syntax-memberp x (caddr term))) ;Else, skip the cons. + (if (and (equal (car term) 'binary-append) ;; '(binary-append arg1 arg2) + (null (cdddr term)) ;consider inlining this? + ) + (or (syntax-memberp x (cadr term)) + (syntax-memberp x (caddr term))) +; (if (and (equal (car term) 'list-fix) ;; '(list-fix arg1) + ; (null (cddr term)) ;consider inlining this? + ; ) +; (syntax-memberp x (cadr term)) + nil ;We've found something that is neither a cons nor an append nor a quote. + ; ) + ))) + nil)) + +(defirrelevant syntax-memberp 1 a (x term) + ) + +;We expect TERM to be of the form (memberp x y). If not, we do nothing. +;If so, we call syntax-memberp. If that function returns t, that means we can show +;syntactically that X is a memberp of Y. If that function returns nil, we don't know whether +;X is a memberp of Y; in this case, we must return something equivalent to TERM, +;so we return TERM itself ! +(defun syntax-memberp-wrapper (term) + (declare (type t term) + (xargs :guard (pseudo-termp term))) + (if (not (and (equal 3 (len term)) + (equal (car term) 'memberp))) + term + (if (syntax-memberp-fn nil (cadr term) (caddr term)) + ''t + term + ))) + +(defthm syntax-memberp-implies-memberp + (implies (syntax-memberp x y) + (memberp (evaluator-for-memberp-cons-and-append x a) + (evaluator-for-memberp-cons-and-append y a))) + :hints (("Goal" :in-theory (enable memberp))) + :rule-classes (:rewrite :forward-chaining)) + + +(defthm syntactic-membership-meta-rule + (equal (evaluator-for-memberp-cons-and-append term a) + (evaluator-for-memberp-cons-and-append (syntax-memberp-wrapper term) a)) + :hints (("Goal" :in-theory (enable syntax-memberp-irrelevant) + :do-not '(generalize eliminate-destructors))) + :rule-classes ((:meta :trigger-fns (memberp)))) + +(encapsulate + () + +;bozo how does the t-p rule get used if we disable it?? + (local (defthm memberp-meta-rule-test + (memberp x (cons y (cons yy (append w (cons x (append ww z)))))) + :hints (("Goal" :in-theory (union-theories '(syntactic-membership-meta-rule) + (theory 'minimal-theory)))))) + + (local (defthm memberp-meta-rule-test-2 + (memberp '3 (append x '(1 2 3))) + :hints (("Goal" :in-theory (union-theories '(syntactic-membership-meta-rule) + (theory 'minimal-theory)))))) + + (local (defthm memberp-meta-rule-test-3 + (memberp x (append (append y (cons x w)) z)) + :hints (("Goal" :in-theory (union-theories '(syntactic-membership-meta-rule) + (theory 'minimal-theory))))))) + + + + + + +(defund subbagp-pair (x1 x2 list1 list2) + (declare (type t x1 x2 list1 list2)) + (or (and (subbagp x1 list1) + (subbagp x2 list2)) + (and (subbagp x1 list2) + (subbagp x2 list1)))) + + + +;like remove-1, but this returns (mv hit result), where hit indicates whether anything was actually removed. +(defun run-remove-1 (a x) + (declare (type t a x)) + (if (consp x) + (if (equal a (car x)) + (mv t (cdr x)) ;we removed (car x) + (met ((hit result) (run-remove-1 a (cdr x))) + (mv hit (cons (car x) result)))) + (mv nil x))) + +(defthm v1-run-remove-1 + (equal (val 1 (run-remove-1 a x)) + (remove-1 a x))) + +(defthm v0-run-remove-1 + (equal (val 0 (run-remove-1 a x)) + (memberp a x))) + +;TERM is a term built from conses and appends (we refuse to look +;inside anything other than a cons or append). Given an element, +;ELEM, and a term, TERM, syntactically remove one copy of ELEM from +;TERM, if possible. Returns (mv hit new-term). If we found an +;occurrence of ELEM to remove, hit is t and new-list is a new TERM +;whose contents are a permutation of the contents of the removal of +;one copy of ELEM from the contents of TERM. The only way to remove +;ELEM from TERM is to find ELEM consed on somewhere in TERM. if hit +;is nil, do we ever use the return value? + + +(defignored syntax-remove-1 a (elem term) + (declare (type t elem term) + (xargs :guard (and (pseudo-termp elem) + (pseudo-termp term)))) + (if (consp term) + (if (and (equal (car term) 'binary-append) ;; '(binary-append arg1 arg2) + (null (cdddr term)) + ) + (let ((arg1 (cadr term)) + (arg2 (caddr term))) + (met ((hit newarg1) (syntax-remove-1 elem arg1)) + (if hit (mv t `(binary-append ,newarg1 ,arg2)) + (met ((hit newarg2) (syntax-remove-1 elem arg2)) + (if hit (mv t `(binary-append ,arg1 ,newarg2)) + (mv nil term)))))) + (if (and (equal (car term) 'cons) ;; '(cons arg1 arg2) + (null (cdddr term))) + (let ((arg1 (cadr term)) + (arg2 (caddr term))) + (if (equal elem arg1) ;if arg1 is equal to elem + (mv t arg2) ;then just return arg2 (we just drop arg1, since it matches elem) + (met ((hit newarg2) (syntax-remove-1 elem arg2)) ;otherwise, try to remove elem from arg2 + (if hit ;if we succeeded in removing it + (mv t `(cons ,arg1 ,newarg2)) ;the return the result of removing it, with arg1 tacked onto the front + (mv nil term) ;otherwise, we failed to remove elem from term + )))) + (if (and (equal (car term) 'quote) ;; '(quote arg1) + (consp elem) + (equal (car elem) 'quote) + (null (cddr elem)) + (null (cddr term)) + ) + (met ((hit result) (run-remove-1 (cadr elem) (cadr term))) + (if hit + (mv t `(quote ,result)) + (mv nil term))) +;; (if (and (equal (car term) 'list-fix) ;; '(list-fix arg1) +;; (consp (cdr term)) +;; (null (cddr term))) +;; (let ((arg1 (cadr term))) +;; (met ((hit newarg1) (syntax-remove-1 elem arg1)) +;; (if hit ;if we succeeded in removing it +;; (mv t `(list-fix ,newarg1)) ;should we not re-add the list-fix call around the result? +;; (mv nil term) ;otherwise, we failed to remove elem from term +;; ))) + (mv nil term) + ;) + ))) + (mv nil term))) + +(defthm not-v0-no-change-syntax-remove-1 + (implies (not (v0 (syntax-remove-1 elem term))) + (equal (v1 (syntax-remove-1 elem term)) + term)) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn)))) + +(defirrelevant syntax-remove-1 2 a (elem term) + :hints (("goal" :in-theory (enable syntax-remove-1-fn)))) + +;looks for X being appended onto something in TERM, and if it finds +;such an occurrence, removes it. does not look inside of X, so X +;shouldn't be a cons or append, for example. can X be a quoted +;constant bag? what about nil? only removes one copy of X. bozo +;handle quoted stuff? or not? can x ever be a quoted thing? bozo +;handle list-fix? + +(defignore syntax-remove-bag-1 a (x term) + (declare (type t x term) + (xargs :guard (and (pseudo-termp x) + (pseudo-termp term)))) + (if (and (consp term) + (equal (car term) 'binary-append) ;; '(binary-append arg1 arg2) + (null (cdddr term))) + (let ((arg1 (cadr term)) + (arg2 (caddr term))) + (met ((hit newarg1) (syntax-remove-bag-1 x arg1)) + (if hit + (mv t `(binary-append ,newarg1 ,arg2)) + (met ((hit2 newarg2) (syntax-remove-bag-1 x arg2)) + (if hit2 + (mv t `(binary-append ,arg1 ,newarg2)) + (mv nil term)))))) + (if (and (consp term) + (equal (car term) 'cons) ;; '(cons arg1 arg2) + (null (cdddr term))) + (let ((arg1 (cadr term)) + (arg2 (caddr term))) + (met ((hit newarg2) (syntax-remove-bag-1 x arg2)) + (if hit + (mv t `(cons ,arg1 ,newarg2)) + (mv nil term)))) +;; (if (and (equal (car term) 'quote) ;; '(quote arg1) bozo think about this +;; (consp x) +;; (equal (car x) 'quote) +;; (consp (cdr x)) +;; (null (cddr x)) +;; (consp (cdr term)) +;; (null (cddr term)) +;; ) +; (remove-bag (cadr x) (cadr term)) + (if (equal x term) + (mv t `(final-cdr ,x)) ; (mv t `(quote nil)) + (mv nil term))))) + +(defthm booleanp-of-mv-nth-0-of-syntax-remove-bag-1 + (booleanp (val 0 (syntax-remove-bag-1 term1 term2))) + :rule-classes (:rewrite :type-prescription) + :hints (("Goal" :in-theory (enable syntax-remove-bag-1-fn)))) + +(defthm not-v0-no-change-syntax-remove-bag-1 + (implies (not (v0 (syntax-remove-bag-1 x y))) + (equal (v1 (syntax-remove-bag-1 x y)) + y)) + :hints (("goal" :in-theory (enable syntax-remove-bag-1-fn)))) + +(defirrelevant syntax-remove-bag-1 2 a (x term) + :hints (("goal" :in-theory (enable syntax-remove-bag-1-fn)))) + +(defthm pseudo-termp-of-v1-of-syntax-remove-bag-1 + (implies (and (pseudo-termp term1) + (pseudo-termp term2)) + (pseudo-termp (val 1 (syntax-remove-bag-1 term1 term2))))) + +(defthm pseudo-termp-of-v1-of-syntax-remove-1 + (implies (and (pseudo-termp term1) + (pseudo-termp term2)) + (pseudo-termp (val 1 (syntax-remove-1 term1 term2)))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn)))) + + +;takes two terms and syntactically cancels common stuff from them. +;return value is of the form: (mv hit newterm1 newterm2), where hit +;indicates whether anything changed, and term1 and term2 are the new +;versions (with common stuff cancelled) of term1 and term2, +;respectively. does hit indicate that *anything* changed? what if +;the only thing changes is that something gets list fixed? what +;should (syntax-remove-bag ''3 '(cons a b)) return? (mv t ''nil +;'(cons a b))? + +(defignored syntax-remove-bag a (term1 term2) + (declare (type t term1 term2) + (xargs :verify-guards nil + :guard (and (pseudo-termp term1) + (pseudo-termp term2)))) + (if (consp term1) + (if (and (equal (car term1) 'binary-append) ;; '(binary-append arg1 arg2) + (null (cdddr term1)) + ) + (let ((arg1 (cadr term1)) + (arg2 (caddr term1))) + (met ((hit newarg1 newterm2) (syntax-remove-bag arg1 term2)) + (met ((hit2 newarg2 newerterm2) (syntax-remove-bag arg2 newterm2)) + (if (or hit hit2) + (if (and (equal newarg2 ''nil) + ;don't bother making an append term of two nils + ;(BOZO eventually, avoid making the append term if either arg is nil) + (equal newarg1 ''nil)) + (mv t ''nil newerterm2) + ;(mv t `(binary-append ,newarg1 ,newarg2) newerterm2) + (mv t `(binary-append ,newarg1 ,newarg2) newerterm2)) + (mv nil term1 term2) ;nothing changed! + )))) + (if (and (equal (car term1) 'cons) ;; '(cons arg1 arg2) + (null (cdddr term1)) + ) + (let ((arg1 (cadr term1)) + (arg2 (caddr term1))) + (met ((hit newterm2) (syntax-remove-1 arg1 term2)) + (met ((hit2 newarg2 newerterm2) (syntax-remove-bag arg2 newterm2)) + (if hit ;arg1 was removed from term2 (and perhaps stuff from arg2 was also removed from term2) + (mv t newarg2 newerterm2) + (if hit2 ;arg1 wasn't removed from term2, but stuff from arg2 was. + (mv t `(cons ,arg1 ,newarg2) newerterm2) + (mv nil term1 term2) ;nothing changed! + ))))) + (if (and (equal (car term1) 'quote) ;; '(quote arg1) + (null (cddr term1)) + ) + (let ((arg1 (cadr term1))) + (if (consp arg1) + (let ((arg1car `(quote ,(car arg1))) + (arg1cdr `(quote ,(cdr arg1)))) + (met ((hit newterm2) (syntax-remove-1 arg1car term2)) + (met ((hit2 newarg1cdr newerterm2) (syntax-remove-bag arg1cdr newterm2)) + (if hit ;arg1car was removed from term2 (and perhaps stuff from arg1cdr was also removed from term2) + (mv t newarg1cdr newerterm2) + (if hit2 ;arg1car wasn't removed from term2, but stuff from arg1cdr was. + (mv t `(cons ,arg1car ,newarg1cdr) newerterm2) + (mv nil term1 term2) ;nothing changed! + ))))) + + ;term1 is a quoted constant which is not a consp.. thus, it reprsents the empty bag + (if (equal arg1 'nil) + (mv nil term1 term2) + (mv t ''nil term2)) + )) + +;; (if (and (equal (car term1) 'list-fix) ;; '(list-fix arg1) +;; (null (cddr term1)) +;; ) +;; (let ((arg1 (cadr term1))) +;; (met ((hit newarg1 newterm2) (syntax-remove-bag arg1 term2)) ;we drop the list-fix; is that the right thing to do? +;; (declare (ignore hit)) +;; (mv t newarg1 newterm2))) + + +;term1 isn't a call to binary-append or cons: + (met ((hit newterm2) (syntax-remove-bag-1 term1 term2)) + (if hit + (mv t '(quote nil) newterm2) + (mv nil term1 term2)))) +; ) + )) + +;term1 is a non-consp: + (met ((hit newterm2) (syntax-remove-bag-1 term1 term2)) + (if hit + (mv t '(quote nil) newterm2) + (mv nil term1 term2)))) + ) + + +(defirrelevant syntax-remove-bag 3 a (term1 term2) + :hints (("goal" :in-theory (enable SYNTAX-REMOVE-1-FN + syntax-remove-bag-fn + syntax-remove-1-irrelevant + syntax-remove-bag-1-irrelevant)))) + +(defthm unchanged-syntax-remove-bag + (implies + (not (v0 (syntax-remove-bag term1 term2))) + (and + (equal (v1 (syntax-remove-bag term1 term2)) + term1) + (equal (v2 (syntax-remove-bag term1 term2)) + term2))) + :hints (("goal" :in-theory (enable syntax-remove-bag-fn)))) + +;(syntax-remove-bag '(cons 2 '(3 4)) '(cons 2 (cons 3 (cons 4 c)))) +;(syntax-subbagp '(cons 2 '(3 4)) '(cons 2 (cons 3 (cons 4 c)))) + +;I think both parts of this had to be proved together +(defthm pseudo-termp-of-syntax-remove-bag + (implies (and (pseudo-termp term1) + (pseudo-termp term2)) + (and (pseudo-termp (val 1 (syntax-remove-bag term1 term2))) + (pseudo-termp (val 2 (syntax-remove-bag term1 term2))))) + :hints (("Goal" :induct t + :in-theory (enable syntax-remove-bag-fn)))) + +(verify-guards + syntax-remove-bag-fn + ) + +#| +old version: +;Returns non-nil iff we can tell just by looking at list1 and list2 that list1 is a subbagp of list2. +;perhaps make this a separate :meta rule? <-- huh? +;We syntactically try to remove everything in list2 from list1. If doing so removes everything from list1, then +;list1 must have been a subbagp of list2. +;This seems inefficient, since it can't fail before syntax-remove-bag has completely finished. + +(defun syntax-subbagp (list1 list2) + (declare (type t list1 list2)) + (met ((hit newlist2 newlist1) (syntax-remove-bag list2 list1)) + (declare (ignore newlist2)) + (and hit ;syntax-remove-bag did something + (equal newlist1 '(quote nil)) ;syntax-remove-bag removed everything from newlist1 + ))) +|# + +;tests whether term1 is a syntactic subbag of term2 returns (mv flg +;leftover) where flg indicates whether term1 is a sytactic subbag of +;term2 and leftover represents the remainder of term2 after +;syntactically removing term1. leftover is only meaningful when flg +;is t. handle quoted constants? + +(defignored syntax-subbagp-helper a (term1 term2) + (declare (type t term1 term2) + (xargs :verify-guards nil + :guard (and (pseudo-termp term1) + (pseudo-termp term2)))) + (if (consp term1) + (if (and (equal (car term1) 'binary-append) ;; '(binary-append arg1 arg2) + (null (cdddr term1)) + ) + (let ((arg1 (cadr term1)) + (arg2 (caddr term1))) + (met ((flg newterm2) (syntax-subbagp-helper arg1 term2)) + (if flg + (syntax-subbagp-helper arg2 newterm2) + (mv nil term2)))) + (if (and (equal (car term1) 'cons) ;; '(cons arg1 arg2) + (null (cdddr term1)) + ) + (let ((arg1 (cadr term1)) + (arg2 (caddr term1))) + (met ((hit newterm2) (syntax-remove-1 arg1 term2)) + (if hit + (syntax-subbagp-helper arg2 newterm2) + (mv nil term2)))) +;term1 isn't a call to binary-append or cons: +;check whether it is a quoted constant which isn't a cons, like nil or 3 (either of which is a subbag of anything) + (if (and (equal (car term1) 'quote) ;; '(quote arg1) + (null (cddr term1)) +; (not (consp (cadr term1))) + ) + +;BOZO test (here and elsewhere) whether quoted constants are bagps? + (let ((arg1 (cadr term1))) + (if (consp arg1) + (let ((arg1car `(quote ,(car arg1))) + (arg1cdr `(quote ,(cdr arg1)))) + (met ((hit newterm2) (syntax-remove-1 arg1car term2)) + (if hit + (syntax-subbagp-helper arg1cdr newterm2) + (mv nil term2) ;since the second value returned here is irrelevant, consider just returning nil? + ))) +;term1 is a quoted constant which is not a consp.. thus, it reprsents the empty bag, which is a subbagp of anything + (mv t term2) ;is this right? ;should we normalize the quoted constant? + )) + (syntax-remove-bag-1 term1 term2)) + )) + (syntax-remove-bag-1 term1 term2))) + +(defthm pseudo-termp-syntax-subbagp-helper + (implies + (and + (pseudo-termp term1) + (pseudo-termp term2)) + (pseudo-termp (v1 (syntax-subbagp-helper term1 term2)))) + :hints (("goal" :in-theory (enable syntax-subbagp-helper-fn)))) + +(verify-guards + syntax-subbagp-helper-fn + ) + +(defirrelevant syntax-subbagp-helper 2 a (term1 term2) + :hints (("goal" :in-theory (enable syntax-subbagp-helper-fn + syntax-remove-bag-1-irrelevant + syntax-remove-1-irrelevant)))) + +(defthm booleanp-of-mv-nth-0-of-syntax-subbagp-helper + (booleanp (val 0 (syntax-subbagp-helper x2 y2))) + :rule-classes (:rewrite :type-prescription) + :hints (("Goal" :in-theory (enable syntax-subbagp-helper-fn)))) + +(defignored syntax-subbagp a (x y) + (declare (type t x y) + (xargs :guard (and (pseudo-termp x) + (pseudo-termp y)))) + (met ((hit result) (syntax-subbagp-helper x y)) + (declare (ignore result)) + hit)) + +(defirrelevant syntax-subbagp 1 a (x y) + :hints (("goal" :in-theory (enable syntax-subbagp-fn + syntax-subbagp-helper-irrelevant)))) + +(defthm booleanp-of-syntax-subbagp + (booleanp (syntax-subbagp x2 y2)) + :rule-classes (:rewrite :type-prescription) + :hints (("Goal" :in-theory (enable syntax-subbagp-fn)))) + + +;Checks whether we know syntactically that either x1 is a subbag of y1 +;and x2 is a subbag of y2 or x1 is a subbag of y2 and x2 is a subbag +;of y1 We we call this fucntion, we know that y1 and y2 are disjoint, +;so if (subbagp x1 y1) is true, we don't bother to check whether +;(subbagp x1 y2), because we know it's false. + +(defignored syntax-subbagp-pair a (x1 x2 y1 y2) + (declare (type t x1 x2 y1 y2) + (xargs :guard (and (pseudo-termp x1) + (pseudo-termp y1) + (pseudo-termp x2) + (pseudo-termp y2)))) + (if (syntax-subbagp x1 y1) + (syntax-subbagp x2 y2) + (if (syntax-subbagp x2 y1) + (syntax-subbagp x1 y2) + nil))) + +(defirrelevant syntax-subbagp-pair 1 a (x1 x2 y1 y2) + :hints (("goal" :in-theory (enable syntax-subbagp-pair-fn + syntax-subbagp-irrelevant)))) + +;try to determine syntactically whether list contains enough to +;contain both y and x (that is, we can take x out of list and list +;still contains y). might it be cheaper to create an append x and y +;and then call syntax-remove-bag once on the append? that avoids +;rebuilding two new version of list... + + + +(defignored syntax-unique-subbagps a (x y list) + (declare (type t x y list) + (xargs :guard (and (pseudo-termp x) + (pseudo-termp y) + (pseudo-termp list)))) + (met ((hitx list1 leftover) (syntax-remove-bag x list)) + (if (and hitx (equal list1 '(quote nil))) ;x is a subbagp + (met ((hity list1 list2) (syntax-remove-bag y leftover)) + (declare (ignore list2)) + (if (and hity (equal list1 '(quote nil))) + t ; '(quote t) ;why quote t? + nil)) + nil))) + +(defirrelevant syntax-unique-subbagps 1 a (x y list) + :hints (("goal" :in-theory (enable syntax-unique-subbagps-fn + syntax-remove-bag-irrelevant + )))) + + +;add guard? +(defund meta-remove-bag (x y) + (remove-bag x y)) + +#| +;drop? +(defund meta-remove-1 (x list) + (remove-1 x list)) +|# + +;remove this? +;add guard? +(defun any-subbagp (term list) + (declare (type t term list)) + (if (consp list) + (or (subbagp term (car list)) + (any-subbagp term (cdr list))) + nil)) + + + + + +;add guard? +(defund hide-disjoint (x y) + (disjoint x y)) + +(defthm hide-disjoint-forward + (implies (disjoint x y) + (hide-disjoint x y)) + :rule-classes :forward-chaining + :hints (("Goal" :in-theory (enable hide-disjoint)))) + + +;add guard? +(defund hide-unique (list) + (unique list)) + +(defthm hide-unique-forward + (implies (unique x) + (hide-unique x)) + :rule-classes :forward-chaining + :hints (("Goal" :in-theory (enable hide-unique)))) + + +;add guard? +(defund hide-subbagp (x y) + (subbagp x y)) + +(defthm hide-subbagp-forward + (implies (subbagp x y) + (hide-subbagp x y)) + :rule-classes :forward-chaining + :hints (("Goal" :in-theory (enable hide-subbagp)))) + +(defthm hide-subbagp-z-z + (hide-subbagp z z) + :hints (("Goal" :in-theory (enable hide-subbagp)))) + +;add guard? +(defund hide-memberp (x y) + (memberp x y)) + +(defthm hide-memberp-forward + (implies (memberp x y) + (hide-memberp x y)) + :rule-classes :forward-chaining + :hints (("Goal" :in-theory (enable hide-memberp)))) + + + + +(defevaluator syntax-ev syntax-ev-list + ( + (hide x) + (hide-unique list) + (hide-subbagp x y) ;added by eric + (hide-disjoint x y) ;added by eric + (hide-memberp a x) ;added by eric + (perm x y) + (unique list) +; (implies-if a term) + (if a b c) + (consp x) + (true-listp x) + (binary-append x y) + (cons a b) + (meta-subbagp list1 list2) + (remove-bag x list) + (meta-remove-bag x list) + (remove-1 x list) +; (meta-remove-1 x list) + (unique-subbagps x y list) + (subbagp-pair x1 x2 list1 list2) + (meta-memberp x list) + (any-subbagp x list) ;remove this? + (final-cdr x) + (list-fix x) + (subbagp x y) ;added by eric + (memberp a x) ;added by eric + (disjoint x y) ;added by eric +; (synp vars form term) ;added by eric + (equal x y) +)) + +;-- proof that the simplification is valid --; + +;If syntax-remove-1 signals a hit, ELEM must have been found (and removed) in TERM. +(defthm syntax-remove-1-implements-memberp + (implies (v0 (syntax-remove-1 elem term)) + (memberp (syntax-ev elem a) (syntax-ev term a))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn))) + :rule-classes (:rewrite :forward-chaining)) + +(defthm syntax-remove-bag-1-implements-subbagp + (implies (and (v0 (syntax-remove-bag-1 list1 list2)) + (equal (v1 (syntax-remove-bag-1 list1 list2)) + '(quote nil))) + (subbagp (syntax-ev list2 a) (syntax-ev list1 a))) + :rule-classes (:rewrite :forward-chaining)) + +;the new TERM returned by syntax-remove-1 represents a term which is a subbag of the original TERM. +(defthm v1-syntax-remove-1-subbagp + (subbagp (syntax-ev (v1 (syntax-remove-1 x list1)) a) + (syntax-ev list1 a)) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-1-fn)))) + +(defthm v1-syntax-remove-bag-1-subbagp + (subbagp (syntax-ev (v1 (syntax-remove-bag-1 x list1)) a) + (syntax-ev list1 a))) + +#| +(defthm syntax-remove-bag-1-not + (implies (and (v0 (syntax-remove-bag-1 list1 list2)) + (not (syntax-ev (v1 (syntax-remove-bag-1 list1 list2)) alist))) + (subbagp (syntax-ev list2 alist) + (syntax-ev list1 alist))) + :hints (("Goal" :do-not '(generalize eliminate-destructors)))) +|# + +(set-well-founded-relation e0-ord-<) + +(defthm v0-remove-1-subbagp + (implies + (v0 (syntax-remove-bag-1 list1 list2)) + (subbagp (syntax-ev list1 a) (syntax-ev list2 a))) + :rule-classes (:rewrite :forward-chaining)) + +;think more about the proof of this?? how should we handle remove-1 and +;append? If syntax-remove-1 signals a hit, then the new term it returns +;represents a bag which is a permutation of the bag resulting from the removal +;of ELEM from the bag represented by TERM. + +(defthm v1-syntax-remove-1-perm-remove-1 + (implies (v0 (syntax-remove-1 elem term)) + (perm (syntax-ev (v1 (syntax-remove-1 elem term)) a) + (remove-1 (syntax-ev elem a) (syntax-ev term a)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (e/d (;remove-1 + syntax-remove-1-fn + REMOVE-1-APPEND + ;APPEND-OF-REMOVE-1-TWO + PERM-CONS-REDUCTION + ;APPEND-OF-REMOVE-1-TWO + ) + (APPEND-REMOVE-1-REDUCTION + PERM-OF-REMOVE-1-ONE + ;PERM-CONSP-REMOVE-1 ;bozo looped! when mv-nth was enabled. + ;PERM-OF-REMOVE-1-ONE + ;PERM-OF-CONS + ;PERM-OF-CONS-MEMBERP-CASE + ;PERM-COMMUTATIVE + ))))) + + +(defthm v1-syntax-remove-bag-1-perm-remove-bag + (implies (v0 (syntax-remove-bag-1 list1 list2)) + (perm (syntax-ev (v1 (syntax-remove-bag-1 list1 list2)) a) + (remove-bag (syntax-ev list1 a) (syntax-ev list2 a)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors)))) + +;theorem we are interested in +(defthm syntax-remove-bag-1-subbagp-append + (implies (and (v0 (syntax-remove-bag-1 x list2)) + (subbagp (syntax-ev (v1 (syntax-remove-bag-1 x list2)) a) + (syntax-ev y a))) + (subbagp (syntax-ev list2 a) + (append (syntax-ev x a) + (syntax-ev y a))))) + + +;make local? +(defthmd not-v1-syntax-remove-1 + (implies (and (v0 (syntax-remove-1 x list2)) + (not (syntax-ev (v1 (syntax-remove-1 x list2)) a))) + (not (consp (remove-1 (syntax-ev x a) (syntax-ev list2 a))))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn))) + :rule-classes (:rewrite :forward-chaining)) + + +(defthm syntax-remove-bag-adds-no-elements + (implies (memberp elem (syntax-ev (val 2 (syntax-remove-bag term1 term2)) a)) + (memberp elem (syntax-ev term2 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-fn)))) + + + + + +;we don't really use this? maybe someday... +(defund syntax-count (elem term) + (declare (type t elem term) + (xargs :guard (pseudo-termp term)) + ) + (if (consp term) + (if (and (equal (car term) 'binary-append) ;; '(binary-append arg1 arg2) +; (consp (cdr term)) + ; (consp (cddr term)) + (null (cdddr term))) + (+ (syntax-count elem (cadr term)) + (syntax-count elem (caddr term))) + (if (and (equal (car term) 'cons) ;; '(cons arg1 arg2) +; (consp (cdr term)) + ; (consp (cddr term)) + (null (cdddr term))) + (if (equal (cadr term) elem) + (+ 1 (syntax-count elem (caddr term))) + (syntax-count elem (caddr term))) + 0)) + 0)) + +;(include-book "arithmetic/top" :dir :system) + + +(defthm syntax-count-of-non-consp + (implies (not (consp term1)) + (equal (syntax-count elem term1) 0)) + :hints (("Goal" :in-theory (enable syntax-count)))) + + +(defthm count-in-SYNTAX-REMOVE-1-linear + (<= (COUNT ELEM (SYNTAX-EV (VAL 1 (SYNTAX-REMOVE-1 x Y)) a)) + (COUNT ELEM (SYNTAX-EV Y a))) + :rule-classes (:rewrite :linear) + :hints (("Goal" :in-theory (enable SYNTAX-REMOVE-1-fn)))) + +(defthm count-in-SYNTAX-REMOVE-bag-1-linear + (>= (COUNT ELEM (SYNTAX-EV (VAL 1 (SYNTAX-REMOVE-bag-1 x Y)) a)) + (- (COUNT ELEM (SYNTAX-EV Y a)) + (COUNT ELEM (SYNTAX-EV x a)))) + :rule-classes (:rewrite :linear) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable SYNTAX-REMOVE-bag-1-fn)))) + +(defthm booleanp-of-VAL-of-SYNTAX-REMOVE-1 + (booleanp (VAL 0 (SYNTAX-REMOVE-1 ELEM TERM))) + :rule-classes (:rewrite :type-prescription) + :hints (("Goal" :in-theory (enable SYNTAX-REMOVE-1-fn)))) + +(encapsulate + () + + (local (defthm syntax-remove-1-did-something-iff-1 + (implies (val 0 (syntax-remove-1 elem term)) + (syntax-memberp elem term)) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn) + :do-not '(generalize eliminate-destructors))) + )) + + + (local (defthm syntax-remove-1-did-something-iff-2 + (implies (syntax-memberp elem term) + (val 0 (syntax-remove-1 elem term))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn syntax-memberp-fn) + :do-not '(generalize eliminate-destructors))) + )) + + (defthm syntax-remove-1-did-something-iff + (equal (val 0 (syntax-remove-1 elem term)) + (syntax-memberp elem term)) + :hints (("Goal" :use (syntax-remove-1-did-something-iff-1 + syntax-remove-1-did-something-iff-2) + :in-theory (disable syntax-remove-1-did-something-iff-1 + syntax-remove-1-did-something-iff-2))))) + + + +(defthm count-of-syntax-remove-1 + (equal (count (syntax-ev x a) + (syntax-ev (val 1 (syntax-remove-1 x y)) a)) + (if (syntax-memberp x y) + (+ -1 (count (syntax-ev x a) + (syntax-ev y a))) + (count (syntax-ev x a) + (syntax-ev y a)))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn) + :do-not '(generalize eliminate-destructors)))) + +(defthm count-of-syntax-remove-1-better + (equal (count elem (syntax-ev (val 1 (syntax-remove-1 x y)) a)) + (if (equal elem (syntax-ev x a)) + (if (syntax-memberp x y) + (+ -1 (count (syntax-ev x a) + (syntax-ev y a))) + (count (syntax-ev x a) + (syntax-ev y a))) + (count elem (syntax-ev y a)))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn) + :do-not '(generalize eliminate-destructors)))) + +(defthm count-in-syntax-remove-bag-linear + (>= (count elem (syntax-ev (val 2 (syntax-remove-bag x y)) a)) + (- (count elem (syntax-ev y a)) + (count elem (syntax-ev x a)))) + :rule-classes (:rewrite :linear) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-fn)))) + + +#|kill? +(thm + (IMPLIES + (< (+ (COUNT ELEM (SYNTAX-EV x1 alist)) + (COUNT ELEM (SYNTAX-EV x2 alist))) + (COUNT ELEM (SYNTAX-EV Y alist))) + (MEMBERP + ELEM + (SYNTAX-EV + (VAL + 2 + (SYNTAX-REMOVE-BAG x2 + (VAL 2 (SYNTAX-REMOVE-BAG x1 Y)))) alist))) + ) +|# + +(defthm memberp-of-syntax-remove-bag-one + (implies (memberp elem (remove-bag (syntax-ev x a) (syntax-ev y a))) + (memberp elem (syntax-ev (val 2 (syntax-remove-bag x y)) a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-fn memberp)))) + +;do we even need this? +;BOZO handle constants! +(defignored syntax-intersection a (term1 term2) + (declare (type t term1 term2) + (xargs :guard (and (pseudo-termp term1) + (pseudo-termp term2)))) + (if (consp term1) + (if (and (equal (car term1) 'binary-append) ;; '(binary-append arg1 arg2) + (null (cdddr term1)) + ) + (let ((arg1 (cadr term1)) + (arg2 (caddr term1))) + (met ((hit newarg1 newterm2) (syntax-remove-bag arg1 term2)) + (if hit +;find out what we removed: + (met ((hit2 blah diff) (syntax-remove-bag newarg1 arg1)) + (declare (ignore hit2 blah)) + (list 'binary-append diff (syntax-intersection arg2 newterm2))) + (syntax-intersection arg2 term2)))) + (if (and (equal (car term1) 'cons) ;; '(cons arg1 arg2) + (null (cdddr term1)) + ) + (let ((arg1 (cadr term1)) + (arg2 (caddr term1))) + (met ((hit newterm2) (syntax-remove-1 arg1 term2)) + (if hit + (list 'cons arg1 (syntax-intersection arg2 newterm2)) + (syntax-intersection arg2 term2)))) + +;; (if (and (equal (car term1) 'list-fix) ;; '(list-fix arg1) +;; (null (cddr term1)) +;; ) +;; (syntax-intersection (cadr term1) term2) + + (if (and (equal (car term1) 'quote) ;; '(quote arg1) + (null (cddr term1)) + ) + (let ((arg1 (cadr term1))) + (if (consp arg1) + (let ((arg1car `(quote ,(car arg1))) + (arg1cdr `(quote ,(cdr arg1)))) + (met ((hit newterm2) (syntax-remove-1 arg1car term2)) + (if hit + `(cons ,arg1car ,(syntax-intersection arg1cdr newterm2)) + (syntax-intersection arg1cdr term2)))) + ''nil + )) + +;term1 isn't a call to binary-append or cons or list-fix: + (met ((hit newterm2) (syntax-remove-bag-1 term1 term2)) + (declare (ignore newterm2)) + (if hit + term1 + ''nil))) + ;) + )) + +;term1 is a non-consp: + (met ((hit newterm2) (syntax-remove-bag-1 term1 term2)) + (declare (ignore newterm2)) + (if hit + term1 + ''nil))) + ) + +(defirrelevant syntax-intersection 1 a (term1 term2) + :hints (("goal" :in-theory (enable syntax-intersection-fn + syntax-memberp-irrelevant + syntax-remove-1-irrelevant + syntax-remove-bag-1-irrelevant + syntax-remove-bag-irrelevant + )))) + + +(defthm syntax-intersection-is-nil-when-syntax-remove-bag-does-nothing + (implies (not (val 0 (syntax-remove-bag term1 term2))) + (equal (syntax-intersection term1 term2) + ''nil)) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :induct t + :expand ((SYNTAX-INTERSECTION TERM1 TERM2)) + :in-theory (enable syntax-remove-bag-fn + syntax-remove-bag-1-fn + syntax-intersection-fn + )))) + + +(defthm kingoftown + (implies (not (syntax-memberp elem term)) + (not (syntax-memberp elem (val 1 (syntax-remove-bag-1 other-term term)))))) + +(defthm kingoftown2 + (IMPLIES + (NOT (SYNTAX-MEMBERP ELEM TERM)) + (NOT + (SYNTAX-MEMBERP ELEM + (VAL 1 + (SYNTAX-REMOVE-1 OTHER-TERM TERM))))) + :hints (("Goal" :in-theory (enable SYNTAX-REMOVE-1-fn)))) + +(defthm smith-blah + (IMPLIES (NOT (SYNTAX-MEMBERP elem term)) + (NOT (SYNTAX-MEMBERP elem (VAL 2 (SYNTAX-REMOVE-BAG other-term term))))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable SYNTAX-REMOVE-BAG-fn + SYNTAX-MEMBERP-fn)))) + + +#| + +;really want the -alt form? +(defthm not-syntax-memberp-means-not-in-syntactic-intersection + (implies (not (syntax-memberp x y)) + (not (syntax-memberp x (syntax-intersection y other-term)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-intersection syntax-memberp)))) +|# + + +(in-theory (disable SYNTAX-MEMBERP-FN)) + +(defthm hack-eric + (implies (and (val 0 (syntax-remove-bag-1 other-term y)) + (not (syntax-memberp x y)) + ) + (not (syntax-memberp x other-term))) + :hints (("Goal" :in-theory (enable syntax-memberp-fn) + :do-not '(generalize eliminate-destructors)))) + + +(defthm not-syntax-memberp-means-not-syntax-memberp-of-syntax-remove-1 + (implies (not (syntax-memberp x y)) + (not (syntax-memberp x (val 1 (syntax-remove-1 elem y))))) + :hints (("Goal" :in-theory (enable syntax-remove-1-fn syntax-memberp-fn)))) + + +#| +;could show that syntactic-intersection is a syntactic subset of each arg? +(defthm not-syntax-memberp-means-not-in-syntactic-intersection-alt + (implies (not (syntax-memberp x y)) + (not (syntax-memberp x (syntax-intersection other-term y)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (e/d (syntax-intersection syntax-memberp + ) + (poopsmith + (:induction syntax-memberp)))))) + +|# + + +;BOZO change names! +(defthm syntax-remove-bag-cannot-increase-count-one + (equal (< (count elem (syntax-ev term1 a)) + (count elem (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a))) + nil) + :hints (("Goal" :in-theory (enable syntax-remove-bag-fn)))) + +(defthm syntax-remove-bag-1-cannot-increase-count + (equal (< (count elem (syntax-ev term2 a)) + (count elem (syntax-ev (val 1 (syntax-remove-bag-1 term1 term2)) a))) + nil)) + +(defthm syntax-remove-bag-cannot-increase-count-two + (equal (< (count elem (syntax-ev term2 a)) + (count elem (syntax-ev (val 2 (syntax-remove-bag term1 term2)) a))) + nil) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-fn)))) + + +(defthm bubs + (<= (count elem (syntax-ev (val 2 (syntax-remove-bag (val 1 (syntax-remove-bag term1 term2)) term3)) a)) + (count elem (syntax-ev term3 a))) + :rule-classes (:rewrite :linear) + :hints (("Goal" :in-theory (disable syntax-remove-bag-cannot-increase-count-two) + :use (:instance syntax-remove-bag-cannot-increase-count-two (term1 (val 1 (syntax-remove-bag term1 term2))) (term2 term3))))) + + +(defthm checkinemail + (<= (count (syntax-ev elem a) + (syntax-ev (syntax-intersection term1 term2) a)) + (count (syntax-ev elem a) + (syntax-ev term1 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-intersection-fn))) + ) + + + + + + +;whoa! this proved! +(defthm syntax-remove-bag-does-the-right-thing-helper + (equal (- (count elem (syntax-ev term1 a)) + (count elem (syntax-ev term2 a))) + (- (count elem (syntax-ev (v1 (syntax-remove-bag term1 term2)) a)) + (count elem (syntax-ev (v2 (syntax-remove-bag term1 term2)) a)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-fn; subbagp + )))) + +(defthm not-syntax-memberp-means-syntax-remove-1-does-nothing + (implies (not (syntax-memberp elem term)) + (equal (val 1 (syntax-remove-1 elem term)) + term))) + + +(in-theory (disable SYNTAX-REMOVE-BAG-1-fn SYNTAX-MEMBERP-fn)) + +(in-theory (disable SUBBAGP-OF-REMOVE-1-FROM-SUBBAGP)) ;why needed? + +#| +(thm + (implies (not (syntax-memberp elem term)) + (implies (memberp (syntax-ev elem alist) + (syntax-ev (val 2 (syntax-remove-bag other-term term)) alist)) + (memberp (syntax-ev elem alist) + (syntax-ev term alist)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag)))) + + +;not true? +(thm + (implies (not (syntax-memberp elem term)) + (implies (memberp (syntax-ev elem alist) + (syntax-ev term alist)) + (memberp (syntax-ev elem alist) + (syntax-ev (val 2 (syntax-remove-bag other-term term)) alist)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag SYNTAX-REMOVE-BAG-1)))) + +;bozo make equal +(defthm syntax-remove-bag-does-the-right-thing + (implies (subbagp (syntax-ev term1 alist) (syntax-ev term2 alist)) + (subbagp (syntax-ev (v1 (syntax-remove-bag term1 term2)) alist) + (syntax-ev (v2 (syntax-remove-bag term1 term2)) alist))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag; subbagp + )))) + + + + (implies (and (v0 (syntax-remove-bag list1 list2)) + (equal (syntax-ev + (v2 (syntax-remove-bag list1 list2)) alist) + nil) + ) + (subbagp (syntax-ev list2 alist) (syntax-ev list1 alist))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) +; :induct (SYNTAX-REMOVE-BAG LIST1 LIST2) + ; :do-not-induct t + :in-theory (e/d (SUBBAGP-CONS-TO-SUBBAGP-REMOVE-1 + syntax-remove-bag + not-v1-syntax-remove-1) + ( + (:REWRITE SUBBAGP-OF-CONS) + SUBBAGP-OF-REMOVE-1-BOTH + ))) + )) + + ) + + +(thm + (IMPLIES + (SUBBAGP (SYNTAX-EV (VAL 2 (SYNTAX-REMOVE-BAG x1 Y)) alist) + (SYNTAX-EV x2 alist)) + (SUBBAGP (SYNTAX-EV Y alist) + (APPEND (SYNTAX-EV x1 alist) + (SYNTAX-EV x2 alist)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable SYNTAX-REMOVE-BAG)))) + + +(thm + (implies (not (syntax-ev (val 2 (syntax-remove-bag x y)) alist)) + (subbagp (syntax-ev y alist) (syntax-ev x alist))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag + subbagp + )))) + + +(thm + (IMPLIES + (NOT + (SYNTAX-EV + (VAL 2 + (SYNTAX-REMOVE-BAG x2 + (VAL 2 + (SYNTAX-REMOVE-BAG x1 y)))) alist)) + (SUBBAGP (SYNTAX-EV y alist) + (APPEND (SYNTAX-EV x1 alist) + (SYNTAX-EV x2 alist)))) + :hints (("Goal" :in-theory (enable SYNTAX-REMOVE-BAG)))) + +(local + (defthm syntax-subbagp-implements-subbagp-syntax-ev-nil + (implies (and (v0 (syntax-remove-bag list1 list2)) + (equal (syntax-ev (v2 (syntax-remove-bag list1 list2)) alist) + nil) + ) + (subbagp (syntax-ev list2 alist) (syntax-ev list1 alist))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) +; :induct (SYNTAX-REMOVE-BAG LIST1 LIST2) + ; :do-not-induct t + :in-theory (e/d (SUBBAGP-CONS-TO-SUBBAGP-REMOVE-1 + syntax-remove-bag + not-v1-syntax-remove-1) + ( + (:REWRITE SUBBAGP-OF-CONS) + SUBBAGP-OF-REMOVE-1-BOTH + ))) + )) + + ) + +|# + + + +(defthm *trigger*-syntax-ev-syntax-subbagp + (implies (and (unique list2) + (meta-subbagp list1 list2) + ) + (unique list1)) + :hints (("Goal" :in-theory (enable meta-subbagp)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;--------------------- SUBBAGP-PAIR -------------------------- +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;A main lemma... +;To show disjointness of x1 and x2, we can find two other bags, list1 and list2, which we know are disjoint and +;which we can tell (syntactcally) are supersets of x1 and x2 (either x1 is a subset of list1 and x2 is a subset of +;list2, or vice versa). +(defthm *trigger*-subbagp-pair-disjoint + (implies (and (disjoint list1 list2) ;list1 and list2 are free variables + (subbagp-pair x1 x2 list1 list2)) + (disjoint x1 x2)) + :hints (("goal" :in-theory (enable subbagp-pair)))) + + +(defthm v1-syntax-remove-bag-1-implication-lemma + (implies (and (v0 (syntax-remove-bag-1 u y)) + (subbagp (syntax-ev v a) + (syntax-ev (v1 (syntax-remove-bag-1 u y)) a)) + (equal (v1 (syntax-remove-bag v (v1 (syntax-remove-bag-1 u y)))) + ''nil)) + (subbagp (append (syntax-ev u a) + (syntax-ev v a)) + (syntax-ev y a)))) + + +(defthm v2-subbagp-remove-bag + (implies (and (v0 (syntax-remove-bag x list)) + (equal (v1 (syntax-remove-bag x list)) + ''nil)) + (perm (syntax-ev (v2 (syntax-remove-bag x list)) a) + (remove-bag (syntax-ev x a) (syntax-ev list a)))) + :hints (("Goal" :in-theory (enable syntax-remove-bag-fn)))) + +(defthm syntax-memberp-quoted-implies-memberp + (implies (syntax-memberp (list 'quote elem) term) + (memberp elem (syntax-ev term a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable SYNTAX-MEMBERP-fn)))) + +(defthm subbagp-when-cdr-is-non-consp + (implies (and (not (consp (cdr x))) + (consp x) ;move to conclusion? + ) + (equal (subbagp x y) + (memberp (car x) y)))) + +;key lemma for subgoal 2 of syntax-unique-subbagps-implies-unique-subbagps +(defthm v1-syntax-remove-bag-implication + (implies (and (v0 (syntax-remove-bag x y)) + (equal (v1 (syntax-remove-bag x y)) + '(quote nil))) + (subbagp (syntax-ev x a) + (syntax-ev y a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-fn)))) + + + + +;disable stuff like this? +(defthm v2-syntax-remove-bag-implication-lemma + (implies + (and + (subbagp (syntax-ev x a) (syntax-ev list a)) + (subbagp (syntax-ev y a) (syntax-ev (v2 (syntax-remove-bag x list)) a)) + (perm (syntax-ev (v2 (syntax-remove-bag x list)) a) + (remove-bag (syntax-ev x a) (syntax-ev list a))) + ) + (subbagp (syntax-ev y a) + (remove-bag (syntax-ev x a) + (syntax-ev list a))))) + +(defthm v2-syntax-remove-bag-implication + (implies + (and + (v0 (syntax-remove-bag x list)) + (equal (v1 (syntax-remove-bag x list)) + ''nil) + (v0 (syntax-remove-bag y (v2 (syntax-remove-bag x list)))) + (equal (v1 (syntax-remove-bag y (v2 (syntax-remove-bag x list)))) + ''nil) + ) + (subbagp (syntax-ev y a) + (remove-bag (syntax-ev x a) + (syntax-ev list a)))) +; Matt K. v7-1 mod for avoiding "Goal'", 2/13/2015: "Goal'" changed to "Goal". + :hints (("Goal" :in-theory (disable v1-syntax-remove-bag-implication + v2-subbagp-remove-bag) + :use ((:instance v1-syntax-remove-bag-implication (y list)) + (:instance v1-syntax-remove-bag-implication (x y) + (y (v2 (syntax-remove-bag x list)))) + (:instance v2-subbagp-remove-bag) + )))) + +;this is the key lemma for the meta rule +(defthm syntax-unique-subbagps-implies-unique-subbagps + (implies (syntax-unique-subbagps x y list) + (unique-subbagps (syntax-ev x a) + (syntax-ev y a) + (syntax-ev list a))) + :hints (("Goal" :in-theory (enable syntax-unique-subbagps-fn + unique-subbagps)))) + +(defun syntax-unique-subbagps-wrapper (term) + (declare (type t term) + (xargs :guard (pseudo-termp term)) + ) + (if (and (consp term) + (equal (car term) 'unique-subbagps) ;; (unique-subbagps x y list) + (consp (cdr term)) + (consp (cddr term)) + (consp (cdddr term)) + (null (cddddr term))) + (let ((x (cadr term)) + (y (caddr term)) + (list (cadddr term))) + (let ((hit (syntax-unique-subbagps-fn nil x y list))) + (if hit + `(quote t) + term))) + term)) + +;is this no longer used? +(defthm *meta*-syntax-ev-syntax-unique-subbagps + (equal (syntax-ev term a) + (syntax-ev (syntax-unique-subbagps-wrapper term) a)) + :rule-classes ((:meta :trigger-fns (unique-subbagps))) + :hints (("goal" :in-theory (enable syntax-unique-subbagps-irrelevant)))) + +;If list is unique and is big enough to contain both x and y, then x and y must be disjoint. +(defthm *trigger*-unique-subbagps-implies-disjointness + (implies (and (unique list) ;list is a free variable + (unique-subbagps x y list)) + (disjoint x y)) + :hints (("goal" :in-theory (enable unique-subbagps remove-bag disjoint) + :do-not '(generalize eliminate-destructors)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;-------------------------- MEMBERP ------------------------ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +#| +(defthm syntax-memberp-implements-memberp + (implies (syntax-memberp x list) + (memberp (syntax-ev x alist) (syntax-ev list alist)))) + +(defun syntax-memberp-wrapper (term) + (declare (type t term)) + (if (and (consp term) + (equal (car term) 'meta-memberp) ;; (meta-memberp x list) +; (consp (cdr term)) + ; (consp (cddr term)) + (null (cdddr term))) + (let ((x (cadr term)) + (list (caddr term))) + (let ((hit (syntax-memberp x list))) + (if hit + '(quote t) + term))) + term)) + +;replace this with eric's rule? +(defthm *meta*-syntax-ev-syntax-memberp + (equal (syntax-ev term alist) + (syntax-ev (syntax-memberp-wrapper term) alist)) + :rule-classes ((:meta :trigger-fns (meta-memberp))) + :hints (("Goal" :in-theory (enable meta-memberp)))) +|# + +;yuck? +(defthmd non-memberp-eric + (implies (and (not (memberp a y)) ;y is a free variable + (subbagp x y)) + (equal (memberp a x) + nil))) + +;bozo ti of REMOVE-BAG-OVER-REMOVE-1 and REMOVE-1-OF-REMOVE-BAG +;bozo REMOVE-BAG-REMOVE-1 and REMOVE-BAG-OVER-REMOVE-1 ! + +#| +(thm + (implies (and (true-listp x) + (true-listp y)) + (equal (ACL2-COUNT (BINARY-APPEND Y X)) + (+ (acl2-count x) (acl2-count y)))) + :hints (("Goal" :in-theory (enable append)))) +|# + + +#| +zz + +(thm + (implies (and (val 0 (syntax-remove-bag-1 x y)) + (unique (syntax-ev y alist)) + ) + (equal (syntax-ev (val 1 (syntax-remove-bag-1 x y)) alist) + (remove-bag (syntax-ev x alist) + (syntax-ev y alist)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag-1 + ;unique + )))) + +PUTBACK +(defthm v1-syntax-remove-bag-1-is-remove-bag + (implies (and (unique (syntax-ev list alist)) + (true-listp (syntax-ev list alist)) + (v0 (syntax-remove-bag-1 x list))) + (equal (syntax-ev (v1 (syntax-remove-bag-1 x list)) alist) + (remove-bag (syntax-ev x alist) (syntax-ev list alist)))) + :hints (("goal" :do-not '(generalize eliminate-destructors) + :in-theory (e/d (remove-bag-append-disjoint + syntax-remove-bag-1 +;remove-bag + ) + (remove-bag-append))))) +|# + +;when do we use these? +(defthm v1-syntax-remove-1-is-remove-1 + (implies (and (unique (syntax-ev term a)) ;why this hyp? + (v0 (syntax-remove-1 elem term))) + (equal (syntax-ev (v1 (syntax-remove-1 elem term)) a) + (remove-1 (syntax-ev elem a) (syntax-ev term a)))) + :hints (("Goal" :in-theory (e/d ( ;remove-1 + syntax-remove-1-fn + REMOVE-1-APPEND + remove-bag-append-disjoint + disjoint-memberp-implies-non-membership + SYNTAX-MEMBERP-fn + remove-1 + ) + ( + CONS-CAR-ONTO-REMOVE-1-OF-CDR ;BOZO why did i need to disable this? + )) + :do-not '(generalize eliminate-destructors)))) + +#| +PUTBACK +(defthm v2-syntax-remove-bag-is-remove-bag + (implies (and (unique (syntax-ev list a)) + (true-listp (syntax-ev list a)) + (v0 (syntax-remove-bag x list)) + (equal (v1 (syntax-remove-bag x list)) + ''nil)) + (equal (syntax-ev (v2 (syntax-remove-bag x list)) a) + (remove-bag (syntax-ev x a) (syntax-ev list a)))) + :hints (("Goal" :in-theory (enable syntax-remove-bag)))) +|# + +;BOZO it would be nice if this returned a simplified term even if the first arg didn't simplify to nil. +(defun syntax-meta-remove-bag-wrapper (term) + (declare (type t term) + (xargs :guard (pseudo-termp term))) + (if (and (consp term) + (equal (car term) 'meta-remove-bag) +; (consp (cdr term)) + ; (consp (cddr term)) + (null (cdddr term))) + (met ((hit v1 v2) (syntax-remove-bag-fn nil (cadr term) (caddr term))) + + (if (and hit + + (equal v1 '(quote nil)) + ) + ;bozo consider remove-bag here? + ;`(meta-remove-bag ,v1 ,v2) + v2 + + term)) + term)) + +;; (thm +;; (implies (not (val 0 (syntax-remove-bag term1 term2))) +;; (equal (syntax-intersection term1 term1) +;; ''nil)) +;; :hints (("Goal" :do-not '(generalize eliminate-destructors) +;; :in-theory (enable syntax-remove-bag syntax-intersection syntax-remove-bag-1)))) + + +#| + +(defthm hhelperh + (implies t;(val 0 (syntax-remove-bag term1 term2)) + (perm (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (remove-bag (syntax-ev (syntax-intersection term1 term1) a) + (syntax-ev term1 a)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag syntax-intersection)))) + + + (PERM (REMOVE-BAG (SYNTAX-EV TERM3 a) + (SYNTAX-EV TERM5 a)) + (REMOVE-BAG (SYNTAX-EV (VAL 1 (SYNTAX-REMOVE-BAG TERM3 TERM5)) a) + (SYNTAX-EV (VAL 2 (SYNTAX-REMOVE-BAG TERM3 TERM5)) a))) + +|# + +(defthm *meta*-syntax-ev-meta-remove-bag-perm + (perm (syntax-ev term a) + (syntax-ev (syntax-meta-remove-bag-wrapper term) a)) + :hints (("goal" :in-theory (enable meta-remove-bag + syntax-remove-bag-irrelevant))) + :rule-classes ((:meta :trigger-fns (meta-remove-bag)))) + +;trying a change where this handles remove-1 instead of meta-remove-1 +(defun syntax-remove-1-wrapper (term) + (declare (type t term) + (xargs :guard (pseudo-termp term))) + (if (and (consp term) + (equal (car term) 'remove-1) ;(equal (car term) 'meta-remove-1) +; (consp (cdr term)) + ; (consp (cddr term)) + (null (cdddr term)) ;why? + ) + (met ((hit v1) (syntax-remove-1-fn nil (cadr term) (caddr term))) + (if hit ;if we succeeded, then + v1 ;return the resulting term + term ;else, do nothing + )) + term)) + +#| +(defthm *meta*-syntax-ev-meta-remove-1-perm + (perm (syntax-ev term a) + (syntax-ev (syntax-meta-remove-1-wrapper term) a)) + :hints (("goal" :in-theory (enable meta-remove-1))) + :rule-classes ((:meta :trigger-fns (meta-remove-1)))) + |# + +(defthm *meta*-syntax-ev-remove-1-perm + (perm (syntax-ev term a) + (syntax-ev (syntax-remove-1-wrapper term) a)) + :hints (("goal" :in-theory (enable remove-1 + SYNTAX-MEMBERP-irrelevant + syntax-remove-1-irrelevant))) + :rule-classes ((:meta :trigger-fns (remove-1)))) + + + + +(defun which-subbagp (x list1 list2 key) + (declare (type t x list1 list2 key) + (xargs :guard (and (pseudo-termp x) + (pseudo-termp list1) + (pseudo-termp list2) + (pseudo-termp key)))) + (or (and (syntax-subbagp-fn nil x list1) + `((,key . (quote t)))) + (and (syntax-subbagp-fn nil x list2) + `((,key . (quote nil)))))) + +(defmacro replace-perm (hit x y list) + `(if ,hit (meta-remove-bag ,x (append ,y ,list)) + ,list)) + +(defthm perm-free-substitution + (implies (and (perm x y) + (bind-free (which-subbagp x list1 list2 'in1) (in1)) + (meta-subbagp x (if in1 list1 list2)) + (equal in2 (not in1)) + ) + (equal (perm list1 list2) + (perm (replace-perm in1 x y list1) + (replace-perm in2 x y list2)))) + :hints (("Goal" :in-theory (enable meta-subbagp meta-remove-bag)))) + +#| +;BOZO wrong value on (common-elements '(cons b nil) '(cons a (cons b nil)))? +;should we just write a function for the syntactic intersection of two terms, instead of calling syntax-remove-bag? +(defun common-elements (term1 term2) + (declare (type t term1 term2)) + (met ((hit xterm1 xterm2) (syntax-remove-bag term1 term2)) + (declare (ignore xterm2)) + (if (not hit) + (mv nil nil) + (met ((hit xterm1 sub) (syntax-remove-bag xterm1 term1)) + (declare (ignore xterm1)) + (mv + hit ;should this be t? what if xterm1 is nil? + sub))))) + +(defun bind-common-elements (term1 term2 key) + (declare (type t term1 term2 key)) + (met ((hit common) (common-elements term1 term2)) + (if (not hit) nil + `((,key . ,common))))) + + +;cancel common stuff from both sides of a perm. +;BOZO consider doing the same for a subbagp and a remove-bag? +(defthm perm-common-elimination + (implies (and (bind-free (bind-common-elements list1 list2 'x) (x)) + (meta-subbagp x list1) + (meta-subbagp x list2)) + (equal (perm list1 list2) + (perm (meta-remove-bag x list1) + (meta-remove-bag x list2)))) + :hints (("Goal" :in-theory (enable meta-subbagp;BOZO why did I have to enable this? + meta-remove-bag)))) +|# + +; (in-theory (disable perm-consp-remove-1)) + +;; I don't know how expensive these rules are in practice. +;; For now, I disable them until needed. + +(in-theory + (disable + perm-free-substitution +; perm-common-elimination + )) + +;; Nonetheless, perm-common-elimination should be used in +;; place of such hack rules as these .. + +(in-theory + (disable + perm-cons-x-y-z + perm-append-x-y-z + ;perm-append-y-z-a + perm-append-x-a-y-append-a-z + )) + +;; This comment is probably not entirely correct: +;; I think I know more about congruence based rewriting now. I don't +;; think we need the meta rules stated above to do effective perm +;; reasoning. +;; +;; I think proving congruence and associative rules for append/cons/ +;; etc should be enough .. we are close even now. I'm not sure how +;; destructors factor in (remove-1, remove-bag, etc), but I bet there +;; is a good strategy somewhere. +;; +;; So, in the future we may want to transition to rules of this form +;; to do perm reasoning: + +;; +;; Try to clean up the perm mess a bit .. +;; + +(in-theory + (disable +; perm-not-consp-nil + ; perm-remove-bag-x-x +; perm-append + perm-cons-append + perm-append-remove-1 +; perm-remove-1 + ; perm-remove-bag + subbagp-perm-append-remove-bag + perm-cons-reduction + perm-nil-y +; perm-remove-bag-2 + perm-consp-remove-1 + perm-subbagp-subbagp + remove-1-cons + )) + + +;; +;; Some meta trigger functions we need to keep around +;; + +(in-theory + (disable +; meta-remove-bag + ;meta-remove-1 + )) + + + +;;================================================================================= +;; :meta rule to simplify (memberp x lst) when we know that X is not a member of +;; certain things (namely, things syntactically present in LST). +;================================================================================== + +;We are rewriting a term of the form (memberp x lst). First, gather the list L of all the things which we know +;syntactically from the goal do not contain x; that is, L contains all BLAH such that the goal contains (not (memberp x blah)). +;Be careful not to use the literal which we're currently rewriting! If L is empty, do nothing. Otherwise, +;process Z as follows: Z is a nest of conses and appends. We ignore the conses. If we find an element of L being +;appended, we drop it. If we find an element of L at a leaf, we also discard it. +;We refuse to look inside any function which is not a cons or an append. + +(defevaluator ev2 ev2-list + ((memberp x l) + (binary-append x y) + (cons x y) + (not x) + (if x y z) + )) + +;returns the list of all BLAH such that mfc contains a literal of the form (not (memberp x BLAH)). +;doesn't allow BLAH to be Z, though. +;a hyp of the form (not (memberp x lst)) will appear negated in the clause as (memberp x lst) +;BOZO this should use the type-alist, not the clause +(defun get-irrel-list-from-clause (x z clause) + (declare (type t x clause) +; (xargs :guard (pseudo-termp term)) + ) + (if (not (consp clause)) + nil + (let ((literal (car clause))) + (if (and (consp literal) + (equal (car literal) 'memberp) + (consp (cdr literal)) + (equal x (cadr literal)) + (consp (cddr literal)) + (not (equal z (caddr literal))) ;skip this case... + ) + (cons (caddr literal) (get-irrel-list-from-clause x z (cdr clause))) + (get-irrel-list-from-clause x z (cdr clause)))))) + + +;pass in x? have a case to handle constants like the meta rule above does? +;write this more efficiently? bozo make this more efficient can we avoid some +;consing by adding a passing a flag which indicates whether the recursive +;calls changed anything? bozo don't depend on append nest being associated? + +(defun simplify-cons-and-append-nest-given-irrelevant-lists (nest irrel-list) + (declare (type t nest irrel-list)) + (if (not (equal 3 (len nest))) ;calls to cons and binary-append have length 3 + ;we've hit a leaf; check whether it is something in the irrelevant list. + (if (memberp nest irrel-list) + ''nil + nest) + (if (equal (car nest) 'cons) + (list 'cons (cadr nest) (simplify-cons-and-append-nest-given-irrelevant-lists (caddr nest) irrel-list)) + (if (equal (car nest) 'binary-append) + ;We don't have to recur on (cadr nest) because we know it won't be an append or a cons, because of how + ;nests of those functions get normalized? + (if (memberp (cadr nest) irrel-list) ;we're appending something irrelevant, so drop it + (simplify-cons-and-append-nest-given-irrelevant-lists (caddr nest) irrel-list) + (list 'binary-append (cadr nest) + (simplify-cons-and-append-nest-given-irrelevant-lists (caddr nest) irrel-list))) + ;We've found something that is neither a cons nor an append. + (if (memberp nest irrel-list) + ''nil + nest)) + ) + )) + +(set-state-ok t) + + +(defun simplify-cons-and-append-nest (term mfc state) + (declare (ignore state) (type t term mfc state)) + (if (not (and (equal 3 (len term)) + (equal (car term) 'memberp))) + term + (let ((irrel-list (get-irrel-list-from-clause (cadr term) (caddr term) (mfc-clause mfc)))) + (if (not (consp irrel-list)) + term + (list 'memberp + (cadr term) + (simplify-cons-and-append-nest-given-irrelevant-lists (caddr term) irrel-list)))))) + +(defun make-not-memberp-claim (x term) + (declare (type t x term)) + `(not (memberp ,x ,term))) + +(defun hyp-fun-simplify-cons-and-append-nest-given-irrelevant-lists (x nest irrel-list) + (declare (type t x nest irrel-list)) + (if (not (equal 3 (len nest))) ;calls to cons and binary-append have length 3 + ;we've hit a leaf: + (if (memberp nest irrel-list) + (make-not-memberp-claim x nest) ;we dropped nest + ''nil ;no hyps necessary + ) + (if (equal (car nest) 'cons) + (hyp-fun-simplify-cons-and-append-nest-given-irrelevant-lists x (caddr nest) irrel-list) + (if (equal (car nest) 'binary-append) + ;We don't have to recur on (cadr nest) because we know it won't be an append or a cons, because of how + ;nests of those functions get normalized? + (if (memberp (cadr nest) irrel-list) ;we're appending something irrelevant, so drop it + (list 'if (make-not-memberp-claim x (cadr nest)) + (hyp-fun-simplify-cons-and-append-nest-given-irrelevant-lists x (caddr nest) irrel-list) + ''nil) + (hyp-fun-simplify-cons-and-append-nest-given-irrelevant-lists x (caddr nest) irrel-list)) + ;We've found something that is neither a cons nor an append. + (if (memberp nest irrel-list) + (make-not-memberp-claim x nest) ;we dropped nest + ''nil ;no hyps necessary + ) + ) + ))) + + +(defun hyp-fun-simplify-cons-and-append-nest (term mfc state) + (declare (ignore state) (type t term mfc state)) + (if (not (and (equal 3 (len term)) + (equal (car term) 'memberp))) + 'nil + (let ((irrel-list (get-irrel-list-from-clause (cadr term) (caddr term) (mfc-clause mfc)))) + (if (not (consp irrel-list)) + 'nil + (hyp-fun-simplify-cons-and-append-nest-given-irrelevant-lists (cadr term) (caddr term) irrel-list))))) + +(encapsulate + () + (local + (defthm helper-eric + (implies + (ev2 (hyp-fun-simplify-cons-and-append-nest-given-irrelevant-lists x nest irrel-list) + a) + (equal (memberp (ev2 x a) (ev2 nest a)) + (memberp (ev2 x a) (ev2 (simplify-cons-and-append-nest-given-irrelevant-lists nest irrel-list) a)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors))))) + +;bozo bad name; what we're simplifying is actually a call to memberp + (defthm meta-rule-to-simplify-cons-and-append-nest + (implies (ev2 (hyp-fun-simplify-cons-and-append-nest term mfc state) a) + (equal (ev2 term a) + (ev2 (simplify-cons-and-append-nest term mfc state) a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors))) + :rule-classes ((:meta :trigger-fns (memberp))))) + + +(encapsulate + () + (local (defthm test + (implies (not (memberp x foo)) + (equal (memberp x (append a foo)) + (memberp x a))) + :hints (("Goal" :in-theory (disable memberp-of-cons MEMBERP-of-APPEND)))))) + + +(defun syntax-subbagp-wrapper (term) + (declare (type t term) + (xargs :guard (pseudo-termp term)) + ) + (if (and (consp term) + (equal (car term) 'meta-subbagp) ;; (meta-subbagp list1 list2) +; (consp (cdr term)) + ; (consp (cddr term)) + (null (cdddr term))) + (let ((list1 (cadr term)) + (list2 (caddr term))) + (let ((hit (syntax-subbagp-fn nil list1 list2))) + (if hit + '(quote t) + term))) + term)) + + +(defun syntax-subbagp-pair-wrapper (term) + (declare (type t term) + (xargs :guard (pseudo-termp term))) + (if (and (consp term) + (equal (car term) 'subbagp-pair) ;; (subbagp-pair x1 x2 list1 list2) +; (consp (cdr term)) + ; (consp (cddr term)) + ; (consp (cdddr term)) + ; (consp (cddddr term)) + (null (cdddddr term))) + (let ((x1 (cadr term)) + (x2 (caddr term)) + (list1 (cadddr term)) + (list2 (caddddr term))) + (let ((hit (syntax-subbagp-pair-fn nil x1 x2 list1 list2))) + (if hit + `(quote t) + term))) + term)) + + + +;(my-syntax-subbagp '(cons a x) '(cons b (cons a x))) +;(my-syntax-subbagp '(cons a x) '(cons a x)) + +#| + +;key lemma for *meta*-syntax-ev-syntax-subbagp +;bozo rename + (defthm syntax-subbagp-implements-subbagp + (implies (and (v0 (syntax-remove-bag list1 list2)) + (equal (v2 (syntax-remove-bag list1 list2)) + '(quote nil)) + ) + (subbagp (syntax-ev list2 a) (syntax-ev list1 a))) + :hints (("Goal" :in-theory (enable meta-subbagp))))) + +(thm + (perm (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (remove-bag (syntax-ev (syntax-intersection term1 term2) a) (syntax-ev term1 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag + syntax-intersection + )))) + + + +|# + + +(defthm hhelper + (implies (val 0 (syntax-subbagp-helper term1 term2)) + (perm (syntax-ev (val 1 (syntax-subbagp-helper term1 term2)) a) + (remove-bag (syntax-ev term1 a) (syntax-ev term2 a)))) + :hints (("Goal" :in-theory (enable syntax-subbagp-helper-fn)))) + +(defthm syntax-subbagp-helper-implements-subbagp + (implies (v0 (syntax-subbagp-helper term1 term2)) + (subbagp (syntax-ev term1 a) (syntax-ev term2 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-subbagp-helper-fn + meta-subbagp))) + :rule-classes (:rewrite :forward-chaining)) + +(defthm syntax-subbagp-implements-subbagp + (implies (syntax-subbagp term1 term2) + (subbagp (syntax-ev term1 a) (syntax-ev term2 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (e/d (meta-subbagp syntax-subbagp-fn) (syntax-subbagp-helper-fn)))) + :rule-classes (:rewrite :forward-chaining)) + +;do we need this rule? previously, meta-subbagp was enabled (!), and so this rule probably didn't fire. +;yet we seem to have gotten by without it?? +(defthm *meta*-syntax-ev-syntax-subbagp + (equal (syntax-ev term a) + (syntax-ev (syntax-subbagp-wrapper term) a)) + :rule-classes ((:meta :trigger-fns (meta-subbagp))) + :hints (("Goal" :in-theory (enable syntax-subbagp-irrelevant meta-subbagp)))) + +(defthm syntax-subbagp-pair-implies-subbagp-pair-x + (implies (syntax-subbagp-pair x1 x2 list1 list2) + (subbagp-pair (syntax-ev x1 a) + (syntax-ev x2 a) + (syntax-ev list1 a) + (syntax-ev list2 a))) + :hints (("Goal" :in-theory (enable subbagp-pair syntax-subbagp-pair-fn))) + :rule-classes (:rewrite :forward-chaining)) + +(defthm *meta*-syntax-ev-subbagp-pair + (equal (syntax-ev term a) + (syntax-ev (syntax-subbagp-pair-wrapper term) a)) + :hints (("goal" :in-theory (enable SYNTAX-SUBBAGP-PAIR-irrelevant))) + :rule-classes ((:meta :trigger-fns (subbagp-pair)))) + +;If we can tell syntactically that term1 and term2 have stuff in common, +;return an alist binding the name indicated by key to that stuff. Otherwise, +;return nil. + +(defun my-bind-common-elements (term1 term2 key) + (declare (type t term1 term2 key) + (xargs :guard (and (pseudo-termp term1) + (pseudo-termp term2) + (pseudo-termp key)))) + (let ((common (bag::syntax-intersection-fn nil term1 term2))) + (if (equal common ''nil) + nil + `((,key . ,common))))) + + +;trying with this enabled... +;BOZO consider replacing this with a :meta rule that calls syntax-remove-bag? +(defthm my-perm-common-elimination + (implies (and (bind-free (my-bind-common-elements list1 list2 'x) (x)) + (bag::meta-subbagp x list1) + (bag::meta-subbagp x list2)) + (equal (perm list1 list2) + (perm (bag::meta-remove-bag x list1) + (bag::meta-remove-bag x list2)))) + :hints (("Goal" :in-theory (enable bag::meta-subbagp ;BOZO why did I have to enable this? + bag::meta-remove-bag)))) + + +#| +(defun perm-cancel-metafunction (term) + (declare (type t term)) + (if (and (consp term) + (equal 'perm (car term)) + (consp (cdr term)) + (consp (cddr term)) + (null (cdddr term))) + (met ((hit newarg1 newarg2) (syntax-remove-bag (cadr term) (caddr term))) + (if hit + `(perm ,newarg1 ,newarg2) + term)) + term)) + + +(thm + (IMPLIES (VAL 0 (SYNTAX-REMOVE-BAG-1 TERM1 TERM2)) + (SUBBAGP (SYNTAX-EV TERM1 alist) + (SYNTAX-EV TERM2 alist)))) + +;expensive? +(defthm subbagp-other-way + (implies (subbagp y x) + (equal (subbagp x y) + (perm x y))) + :hints (("Goal" :in-theory (enable subbagp perm)))) + +(thm + (IMPLIES (SUBBAGP (SYNTAX-EV (VAL 1 (SYNTAX-REMOVE-BAG TERM1 TERM2)) alist) + (REMOVE-1 (SYNTAX-EV elem alist) + (SYNTAX-EV (VAL 2 (SYNTAX-REMOVE-BAG TERM1 TERM2)) alist))) + (SUBBAGP (SYNTAX-EV TERM1 alist) + (REMOVE-1 (SYNTAX-EV elem alist) + (SYNTAX-EV TERM2 alist)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag + subbagp)))) + +(thm + (implies (subbagp (syntax-ev (val 1 (syntax-remove-bag term1 term2)) alist) + (syntax-ev (val 2 (syntax-remove-bag term1 term2)) alist)) + (subbagp (syntax-ev term1 alist) + (syntax-ev term2 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag + subbagp)))) + + +(thm + (implies (subbagp (syntax-ev term1 a) + (syntax-ev term2 a)) + (subbagp (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (syntax-ev (val 2 (syntax-remove-bag term1 term2)) a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag perm)))) + + +(thm + (implies (perm (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (syntax-ev (val 2 (syntax-remove-bag term1 term2)) a)) + (perm (syntax-ev term1 a) + (syntax-ev term2 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag)))) + + + +(thm + (implies (perm (syntax-ev term1 a) + (syntax-ev term2 a)) + (perm (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (syntax-ev (val 2 (syntax-remove-bag term1 term2)) a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag perm)))) + +(thm + (equal (perm (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (syntax-ev (val 2 (syntax-remove-bag term1 term2)) a)) + (perm (syntax-ev term1 a) + (syntax-ev term2 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag)))) + + +(defthm meta-perm-cancel + (equal (syntax-ev term a) + (syntax-ev (perm-cancel-metafunction term) a)) + :rule-classes ((:meta :trigger-fns (perm)))) + + + + +|# + +#| + + +(defthm SYNTAX-REMOVE-BAG-kills-all-of-term1-means-subbagp + (IMPLIES (EQUAL (VAL 1 (SYNTAX-REMOVE-BAG TERM1 TERM2)) + ''NIL) + (subbagp (SYNTAX-EV TERM1 a) + (SYNTAX-EV TERM2 a) + )) + :hints (("Goal" :in-theory (enable SYNTAX-REMOVE-BAG)))) + + +(thm + (implies + (val 0 (syntax-subbagp-helper term1 term2)) + (equal (val 1 (syntax-subbagp-helper term1 term2)) + (val 2 (syntax-remove-bag term1 term2)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag syntax-subbagp-helper)))) + + + (VAL + 0 + (SYNTAX-REMOVE-BAG-1 (CADDR TERM1) + (VAL 1 + (SYNTAX-SUBBAGP-HELPER (CADR TERM1) + TERM2))))) + +(defthm syntax-remove-bag-kills-all-of-term1-means-subbagp + (implies (equal (val 1 (syntax-remove-bag term1 term2)) + ''nil) + (mv-nth 0 (syntax-subbagp-helper term1 term2))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag syntax-subbagp-helper)))) + + +(thm + (IMPLIES (EQUAL (VAL 1 (SYNTAX-REMOVE-BAG TERM1 TERM2)) + ''NIL) + (PERM (SYNTAX-EV (SYNTAX-INTERSECTION TERM1 TERM2) a) + (SYNTAX-EV TERM1 a) + + ))) + + +|# + +#| + +(defthm REMOVE-1-car-remove-bag-under-perm + (PERM + (REMOVE-1 (CAR y) (REMOVE-BAG x y)) + (REMOVE-BAG x (CDR y)))) + +;prove this! could we just code syntax-remove-bag this way? +;no! it involves consing up the intersection? but the other way involves consing up new terms? +;we say perm because the final cdrs might not match? +(thm + (perm (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a) + (remove-bag (syntax-ev (syntax-intersection term1 term2) a) (syntax-ev term1 a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag + syntax-intersection + )))) +;sheesh. do we really need a notion of syntactic perm? +(defthm not-syntax-memberp-means-not-in-syntactic-intersection-alt + (equal (syntax-memberp elem (syntax-intersection x y)) + (syntax-memberp elem (syntax-intersection y x))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-intersection syntax-memberp)))) + + + + +(defthm subbagp-from-subbagp-of-append-1 + (implies (subbagp (append x y) z) + (subbagp x z)) + :hints (("Goal" :in-theory (enable subbagp)))) + +(defthm subbagp-from-subbagp-of-append-two + (implies (subbagp (append x y) z) + (subbagp x z)) + :hints (("Goal" :use subbagp-from-subbagp-of-append-1 + :in-theory (disable subbagp-from-subbagp-of-append-1)))) + +(defthm syntax-remove-bag-does-the-right-thing + (implies (subbagp (syntax-ev term1 a) (syntax-ev term2 a)) + (subbagp (syntax-ev (v1 (syntax-remove-bag term1 term2)) a) + (syntax-ev (v2 (syntax-remove-bag term1 term2)) a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag; + ;subbagp + )))) + + +(defthm syntax-remove-bag-does-the-right-thing + (equal (subbagp (syntax-ev term1 a) (syntax-ev term2 a)) + (subbagp (syntax-ev (v1 (syntax-remove-bag term1 term2)) a) + (syntax-ev (v2 (syntax-remove-bag term1 term2)) a))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag ; +;subbagp + )))) + + +(thm + (implies + (< (syntax-count elem term1) + (syntax-count elem term2)) + (equal (count elem (syntax-ev term1 a)) + (+ (syntax-count elem term1) + (count elem + (syntax-ev (val 1 (syntax-remove-bag term1 term2)) a))))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag)))) + +(defthm syntax-remove-bag-does-the-right-thing-helper1 + (equal (count elem (syntax-ev (v1 (syntax-remove-bag term1 term2)) a)) + (- (count elem (syntax-ev term1 a)) + (min (syntax-count elem term1) + (syntax-count elem term2)))) + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag)))) + + + :hints (("Goal" :do-not '(generalize eliminate-destructors) + :in-theory (enable syntax-remove-bag; subbagp + )))) + + + + + +prove these about remove-bag-1 +(defthm count-of-syntax-remove-bag-1 + (equal (count (syntax-ev x a) + (syntax-ev (val 1 (syntax-remove-bag-1 x y)) a)) + (if (syntax-memberp x y) + (+ -1 (count (syntax-ev x a) + (syntax-ev y a))) + (count (syntax-ev x a) + (syntax-ev y a)))) + :hints (("Goal" :in-theory (enable syntax-remove-1) + :do-not '(generalize eliminate-destructors)))) + +(defthm count-of-syntax-remove-1-better + (equal (count elem (syntax-ev (val 1 (syntax-remove-1 x y)) a)) + (if (equal elem (syntax-ev x a)) + (if (syntax-memberp x y) + (+ -1 (count (syntax-ev x a) + (syntax-ev y a))) + (count (syntax-ev x a) + (syntax-ev y a))) + (count elem (syntax-ev y a)))) + :hints (("Goal" :in-theory (enable syntax-remove-1) + :do-not '(generalize eliminate-destructors)))) + +to handle + +(IMPLIES + (AND (NOT (CONSP TERM1)) + (VAL 0 (SYNTAX-REMOVE-BAG-1 TERM1 TERM2))) + (EQUAL (+ (COUNT ELEM (SYNTAX-EV TERM1 a)) + (COUNT ELEM + (SYNTAX-EV (VAL 1 (SYNTAX-REMOVE-BAG-1 TERM1 TERM2)) a))) + (COUNT ELEM (SYNTAX-EV TERM2 a)))) +|# + + + +;odd proof? +;move some of this stuff? +(defthm syntax-memberp-implements-memberp + (implies (syntax-memberp v x) + (memberp (syntax-ev v a) + (syntax-ev x a))) + :rule-classes (:rewrite :forward-chaining)) + +(defthm memberp-of-syntax-ev-helper + (implies (and (syntax-memberp x blah) + (subbagp (syntax-ev blah a) y)) + (memberp (syntax-ev x a) y)) + :hints (("Goal" :use (:instance syntax-memberp-implements-memberp (v x) (x blah) (a a)) + :in-theory (e/d ( non-memberp-eric) (syntax-memberp-implements-memberp))))) |