File: convert-perm-to-how-many.lisp

package info (click to toggle)
acl2 8.3dfsg-2
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 309,408 kB
  • sloc: lisp: 3,311,842; javascript: 22,569; cpp: 9,029; ansic: 7,872; perl: 6,501; xml: 3,838; java: 3,738; makefile: 3,383; ruby: 2,633; sh: 2,489; ml: 763; python: 741; yacc: 721; awk: 260; csh: 186; php: 171; lex: 154; tcl: 49; asm: 23; haskell: 17
file content (110 lines) | stat: -rw-r--r-- 2,931 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
; (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)))))))