File: overspill.lisp

package info (click to toggle)
acl2 8.6%2Bdfsg-3
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 1,138,276 kB
  • sloc: lisp: 17,818,294; java: 125,359; python: 28,122; javascript: 23,458; cpp: 18,851; ansic: 11,569; perl: 7,678; xml: 5,591; sh: 3,978; makefile: 3,840; ruby: 2,633; yacc: 1,126; ml: 763; awk: 295; csh: 233; lex: 197; php: 178; tcl: 49; asm: 23; haskell: 17
file content (167 lines) | stat: -rw-r--r-- 5,656 bytes parent folder | download | duplicates (6)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
; Copyright (C) 2015, Regents of the University of Texas
; Written by Cuong Chau and Matt Kaufmann, April/May, 2015
; License: A 3-clause BSD license.  See the LICENSE file distributed with ACL2.

; See overspill-test.lisp for trivial applications.

; cert_param: (uses-acl2r)

(in-package "ACL2")

; Formalization of the overspill property in ACL2(r)

; In order to apply overspill-p-overspill (at the end, below) to one's own
; predicate, (p0 i x), I expect the following approach to suffice.  First,
; define p0* and p0-witness in analogy to overspill-p* and overspill-p-witness
; below, respectively.  Second, functionally instantiate overspill-p-overspill.
; Now, suppose that you prove a theorem of the form:

;   (implies (and (hyps x) (natp i) (standardp i))
;            (p0 i x))

; Then you can easily conclude the following from your functional instance of
; overspill-p-overspill, saying that p0 "overspills" to some nonstandard n:

;   (implies (hyps x)
;            (let ((n (overspill-p-witness x)))
;              (and (natp n)
;                   (overspill-p n x)
;                   (i-large n)))

; We can avoid an include-book with :dir :system, since overspill-proof is in
; this same directory.
(local (include-book "overspill-proof"))

(set-enforce-redundancy t)

(defstub overspill-p (n x) t)

(defun overspill-p* (n x)
  (if (zp n)
      (overspill-p 0 x)
    (and (overspill-p n x)
         (overspill-p* (1- n) x))))

(defchoose overspill-p-witness (n) (x)
  (or (and (natp n)
           (standardp n)
           (not (overspill-p n x)))
      (and (natp n)
           (i-large n)
           (overspill-p* n x))))

(defthm overspill-p-overspill
  (let ((n (overspill-p-witness x)))
    (or (and (natp n)
             (standardp n)
             (not (overspill-p n x)))
        (and (natp n)
             (i-large n)
             (implies (and (natp m)
                           (<= m n))
                      (overspill-p m x)))))
  :rule-classes nil)

(set-enforce-redundancy nil)

; Now we introduce a macro that automates the application of the overspill
; principle.  I suspect that with more work we could make the witness
; classical, but it's not at all clear to me that there is value in doing so.
; I actually think that it's best for the generic witness function,
; overspill-p-witness, not to be classical, to avoid needlessly restricting the
; set of legal functional substitutions.

(defun make-nth-calls (i var acc)

; Return the user-level term list ((nth 0 var) (nth 1 var) ... (nth i-1 var)).

  (declare (xargs :guard (and (natp i)
                              (symbolp var))))
  (cond ((zp i) acc)
        (t (let ((k (1- i)))
             (make-nth-calls k
                             var
                             (cons `(nth ,k ,var) acc))))))

(defun create-bindings (x y)
  (declare (xargs :guard (and (true-listp x)
                              (true-listp y))))
  (pairlis$ x (pairlis$ y nil)))

(defmacro overspill (pred params &key pred* witness pred-overspill)

; Params is a list of distinct variable names in one-to-one correspondence with
; the cdr of the formals of pred -- so, (pred n . params) is a well-formed call
; -- or else is a single variable.

  (let* ((atom-p
          (atom params))
         (nth-x ; list of expressions representing the parameters
          (if atom-p
              '(x)
            (make-nth-calls (len params) 'x nil)))
         (params
          (if (atom params) (list params) params))
         (pred*
          (or pred*
              (intern-in-package-of-symbol
               (concatenate 'string (symbol-name pred) "*")
               pred)))
         (witness
          (or witness
              (intern-in-package-of-symbol
               (concatenate 'string (symbol-name pred) "-WITNESS")
               pred)))
         (pred-overspill
          (or pred-overspill
              (intern-in-package-of-symbol
               (concatenate 'string (symbol-name pred) "-OVERSPILL")
               pred))))
    `(encapsulate
      ()

      (local (include-book ; linebreak defeats bogus cert.pl dependency
              "nonstd/nsa/overspill" :dir :system))

      (defun ,pred* (n ,@params)
        (if (zp n)
            (,pred 0 ,@params)
          (and (,pred n ,@params)
               (,pred* (1- n) ,@params))))

      (defchoose ,witness (n) (,@params)
        (or (and (natp n)
                 (standardp n)
                 (not (,pred n ,@params)))
            (and (natp n)
                 (i-large n)
                 (,pred* n ,@params))))

      (defthm ,pred-overspill
        (let ((n (,witness ,@nth-x)))
          (or (and (natp n)
                   (standardp n)
                   (not (,pred n ,@nth-x)))
              (and (natp n)
                   (i-large n)
                   (implies (and (natp m)
                                 (<= m n))
                            (,pred m ,@nth-x)))))
        :hints (("Goal"
                 :by (:functional-instance
                      overspill-p-overspill
                      (overspill-p
                       (lambda (n x)
                         (,pred n ,@nth-x)))
                      (overspill-p*
                       (lambda (n x)
                         (,pred* n ,@nth-x)))
                      (overspill-p-witness
                       (lambda (x)
                         (,witness ,@nth-x))))
                 :in-theory (theory 'minimal-theory)
                 :expand ((,pred* n ,@nth-x)))
                '(:use (:instance ,witness
                                  ,@(create-bindings params nth-x))))
        :rule-classes nil)
      )))