; (certify-book "convert-perm-to-how-many") ; See Exercise 11.50 in CAR. ; /projects/acl2/v3-1/acl2-sources/books/textbook/chap11/how-many-soln2.lisp (in-package "ACL2") (include-book "perm") (defun how-many (e x) (cond ((endp x) 0) ((equal e (car x)) (1+ (how-many e (cdr x)))) (t (how-many e (cdr x))))) ; We aim to prove that (perm x y) is the same as checking that for all e, ; (how-many e x) is (how-many e y). We can do that by defining the function ; (perm-counter-example x y) -- the counterexample generator -- that finds an e that occurs a ; different number of times in x than in y. ; Thus, the following definition is modeled after the definition of perm. (defun perm-counter-example (x y) (cond ((atom x) (car y)) ((not (memb (car x) y)) (car x)) (t (perm-counter-example (cdr x) (rm (car x) y))))) ; The right-hand side of the equal term in the last hypothesis suggests the ; following rewrite rule. (We return to this issue later.) (defthm how-many-rm (implies (not (equal a b)) (equal (how-many a (rm b x)) (how-many a x)))) (defthm not-memb-implies-rm-is-no-op (implies (and (not (memb a x)) (true-listp x)) (equal (rm a x) x))) (defthm true-listp-rm (implies (true-listp x) (true-listp (rm a x))) :rule-classes :type-prescription) (defthm not-memb-implies-how-many-is-0 (implies (not (memb a x)) (equal (how-many a x) 0))) (defthm how-many-rm-general (equal (how-many a (rm b x)) (if (and (equal a b) (memb a x)) (1- (how-many a x)) (how-many a x)))) (defthm perm-counter-example-is-counterexample-for-true-lists (implies (and (true-listp x) (true-listp y)) (equal (perm x y) (equal (how-many (perm-counter-example x y) x) (how-many (perm-counter-example x y) y)))) :rule-classes nil) (defun tlfix (x) (if (endp x) nil (cons (car x) (tlfix (cdr x))))) (defthm perm-tlfix (perm (tlfix x) x)) (defthm perm-counter-example-tlfix-1 (equal (perm-counter-example (tlfix x) y) (perm-counter-example x y))) (defthm rm-tlfix (equal (rm a (tlfix x)) (tlfix (rm a x)))) (defthm memb-tlfix (equal (memb a (tlfix x)) (memb a x))) (defthm perm-counter-example-tlfix-2 (equal (perm-counter-example x (tlfix y)) (perm-counter-example x y))) (defthm how-many-tlfix (equal (how-many a (tlfix x)) (how-many a x))) (defthm convert-perm-to-how-many (equal (perm x y) (equal (how-many (perm-counter-example x y) x) (how-many (perm-counter-example x y) y))) :hints (("Goal" :use ((:instance perm-counter-example-is-counterexample-for-true-lists (x (tlfix x)) (y (tlfix y)))))))