File: realistic.lisp

package info (click to toggle)
acl2 8.5dfsg-5
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 991,452 kB
  • sloc: lisp: 15,567,759; javascript: 22,820; cpp: 13,929; ansic: 12,092; perl: 7,150; java: 4,405; xml: 3,884; makefile: 3,507; sh: 3,187; ruby: 2,633; ml: 763; python: 746; yacc: 723; awk: 295; csh: 186; php: 171; lex: 154; tcl: 49; asm: 23; haskell: 17
file content (208 lines) | stat: -rw-r--r-- 6,559 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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
(in-package "ACL2")

#|

 realistic.lisp
 ~~~~~~~~~~~~~~

Author: Sandip Ray
Date: Sun Dec  9 00:27:02 2007

This book demonstrates why the Manolios/Moore 2003 notion might not be
an adequate notion of partial correctness.  Here we consider a machine
that operates as follows.  It executes the instructions in a program,
and when it is done it resets memory and program and halts.  With this
machine we show that any arbitrary program of length 10 satisfies
Manolios/Moore's partial correctness condition, where as postcondition
I chose that the machine computes factorial.

The machine is of course a toy and not realistic at all.  But the
machine can be extended to a realistic one by keeping the basic idea.
The basic idea is that the machine computes the program instructions,
but at the time of *finally* halting, it clears off everything before
halting.  It is not important that everything is cleared, actually:
the program-specific details need to be cleared before halting.  At
any exit state before halting, there are non-trivial partial (and
total) correctness theorems that one can imagine proving on such a
machine.  But if the only thing we want to do is say that an initial
state and a modified state (according to postcondition) reach the same
halting state (as is required by Manolios/Moore notion), then we can
prove *each* program partially correct with respect to that machine.

|#

(include-book "misc/records" :dir :system)
(include-book "misc/defpun" :dir :system)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 1: Machine definition
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defmacro ctr (s) `(g :pc ,s))
(defmacro memory (s) `(g :mem ,s))
(defmacro program-of (s) `(g :program ,s))

(defun update-macro (upds result)
  (declare (xargs :guard (keyword-value-listp upds)))
  (if (endp upds) result
    (update-macro (cddr upds)
                  (list 's (car upds) (cadr upds) result))))

(defmacro update (old &rest updates)
  (declare (xargs :guard (keyword-value-listp updates)))
  (update-macro updates old))

(defmacro >s (&rest upds) `(update s ,@upds))

;; I leave the execute-op function below undefined since its semantics
;; does not matter.

(defstub execute-op (* *) => *)

;; Here of course the only thing that the language allows is
;; incrementing the pc by 1, so the language is assumed to have no
;; conditional or loops or anything.  So every program terminates.

(defun next (s)
  (let ((pc (ctr s))
        (program (program-of s)))
    (if (consp program)
        (if (<= pc (len program))
            (>s :mem (execute-op (nth pc program) s)
                :pc (1+ pc))
          (>s :pc 0
              :mem nil
              :program nil))
      s)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 2: Manolios/Moore's notion of partial correctness
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(defun halted-statep (s) (equal (next s) s))

(defpun stepw (s)
  (if (halted-statep s) s
    (stepw (next s))))

(defun == (x y)
  (equal (stepw x) (stepw y)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 3: A program and its specification
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Here we specify an arbitrary program of length 10.

(encapsulate
 (((arbitrary-program) => *))

 (local (defun arbitrary-program () (list 1 2 3 4 5 6 7 8 9 10)))

 (defthm |arbitrary program is non-empty|
   (equal (len (arbitrary-program)) 10)))

;; Now we specify the precondition and the modify condition as per
;; Manolios/Moore's notion.  The goal is to prove that for each state
;; s satisfying pre, s == (modify-factorial s).  Given the
;; precondition and the modify, this is the partial correctness of
;; factorial for the Manolios/Moore's notion.  But we prove this
;; notion for any arbitrary program of length 10.  (The choice of
;; length 10 is just so that I don't have to do an induction as
;; necessary for arbitrary length in this demonstration.)

(defun pre (s)
  (and (equal (ctr s) 0)
       (natp (nth 1 (memory s)))
       (equal (program-of s) (arbitrary-program))))

(defun ! (n)
  (if (zp n) 1
    (* n (! (1- n)))))

(defun modify-factorial (s)
  (>s :pc 10
      :mem (update-nth 3 (! (nth 1 (memory s))) (memory s))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 4: Intermediate lemmas
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(local
 (defun run (s n)
   (if (zp n) s
     (run (next s) (1- n)))))

(local
 (defthm run-expansion
   (equal (run s n)
          (if (zp n) s
            (run (next s) (1- n))))))

(local
 (defthm arbitrary-program-is-consp
   (consp (arbitrary-program))
   :rule-classes :type-prescription
   :hints (("Goal"
            :in-theory (disable |arbitrary program is non-empty|)
            :use |arbitrary program is non-empty|))))

(local
 (defthm memory-cleared-after-some-time
   (implies (pre s)
            (equal (run s 12)
                   (>s :pc 0
                       :mem nil
                       :program nil)))))

(local
 (defthm memory-cleared-after-modify
   (implies (pre s)
            (equal (run (modify-factorial s) 3)
                   (>s :pc 0
                       :mem nil
                       :program nil)))))

(local
 (defthm clear-is-halted
   (halted-statep (>s :pc 0
                      :mem nil
                      :program nil))))

(local (in-theory (disable run-expansion)))

(local
 (defthm halted-to-stepw
   (implies (halted-statep s)
            (equal (stepw s) s))))

(local
 (defthmd run-s-stepw
   (implies (halted-statep (run s n))
            (equal (stepw (run s n))
                   (stepw s)))))

(local (in-theory (disable stepw-def)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Section 5: Intermediate lemmas
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Here is the final theorem that shows that Manolios/Moore's notion
;; of partial correctness is satisfied by the program.

(defthm |arbitrary program is partially correct|
  (implies (pre s)
           (== s (modify-factorial s)))
  :hints (("Goal"
           :in-theory (disable pre run modify-factorial)
           :use ((:instance run-s-stepw
                            (n 12))
                 (:instance run-s-stepw
                            (n 3)
                            (s (modify-factorial s)))))))