File: NOTE-2-9-3-PPR-CHANGE.html

package info (click to toggle)
acl2 3.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 36,712 kB
  • ctags: 38,396
  • sloc: lisp: 464,023; makefile: 5,470; sh: 86; csh: 47; cpp: 25; ansic: 22
file content (313 lines) | stat: -rw-r--r-- 8,535 bytes parent folder | download
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
<html>
<head><title>NOTE-2-9-3-PPR-CHANGE.html  --  ACL2 Version 3.1</title></head>
<body text=#000000 bgcolor="#FFFFFF">
<h3>NOTE-2-9-3-PPR-CHANGE</h3>change in pretty-printing for ACL2 Version_2.9.3
<pre>Major Section:  <a href="NOTE-2-9-3.html">NOTE-2-9-3</a>
</pre><p>

We have improved pretty-printing in ACL2 Version_2.9.3 to handle keywords a
little differently.  To see a discussion of the basics of this change,
see <a href="NOTE-2-9-3.html">note-2-9-3</a>.  In this note we describe it in considerable detail.
<p>
Those who wish to understand the ACL2 pretty-printer's implementation can now
find considerably more comments on it in the source code.  In this note, we
do not focus on the implementation.  Rather, we motivate the change and show
how the improved prettyprinter performs.<p>

Why do we want better keyword handling?  Imagine a macro that builds a new
state from an old state by changing the values in the affected fields,
leaving everything else unchanged.  One could write

<pre>
(modify th s :key1 val1 :key2 val2 :key3 val3)
</pre>

where the three keys identify fields in the state.<p>

To make it easier to read new concrete states, we may have a function that
prints them ``relative'' to a given base state, expressing the new state as a
modification of the given base state.  So we may find ourselves
prettyprinting modify forms like that above.<p>

The previous prettyprinter will sometimes print the form above as follows.

<pre>
(modify th s :key1
        val1
        :key2 val2 :key3 val3)
</pre>

This can be unpleasant to read, because of the way <code>:key1</code> and <code>val1</code> are
separated.  Here is an example of the old prettyprinter and the new one, both
printing an expression from the ACL2 source code in a width of 40:

<pre>
Old:
(ADD-TO-TAG-TREE
 'ASSUMPTION
 (MAKE
  ASSUMPTION :TYPE-ALIST TYPE-ALIST
  :TERM TERM :REWRITTENP REWRITTENP
  :IMMEDIATEP IMMEDIATEP :ASSUMNOTES
  (LIST
   (MAKE
        ASSUMNOTE :CL-ID
        NIL :RUNE RUNE :TARGET TARGET)))
 TTREE)<p>

New:
(ADD-TO-TAG-TREE
     'ASSUMPTION
     (MAKE ASSUMPTION
           :TYPE-ALIST TYPE-ALIST
           :TERM TERM
           :REWRITTENP REWRITTENP
           :IMMEDIATEP IMMEDIATEP
           :ASSUMNOTES
           (LIST (MAKE ASSUMNOTE
                       :CL-ID NIL
                       :RUNE RUNE
                       :TARGET TARGET)))
     TTREE)
</pre>

Basically the change we made forces the prettyprinter to print each <code>:key</code>
on a new line unless they all fit on a single line.  So we would now get
either

<pre>
(modify th s :key1 val1 :key2 :val2 :key3 val3)
</pre>

or

<pre>
(modify th s
        :key1 val1
        :key2 val2
        :key3 val3)
</pre>

Furthermore, we fixed it so that if <code>val1</code> (say) is a big s-expression we
may still print it on the same line as its key.  The old prettyprinter
enforced the rule that if you wanted to print <code>(foo a b)</code> and <code>b</code> gets
broken up into several lines, then it has to start on a new line.  Thus,
we'd never print

<pre>
(foo a (bbb
        (mum x)))
</pre>

but would print instead

<pre>
(foo a
     (bbb
      (mum x)))
</pre>

Now, if a is a keyword, we can print the first way.<p>

So here are some nice examples of prettyprinted keyword forms.  All of these
are printed for a page of width 40.

<pre>
&lt;--            40 chars               -&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<p>

(MODIFY TH S :KEY1 V1 :KEY2 V2)<p>

(MODIFY TH S :KEY1 V1 :KEY2 V2 :KEY3 V3)<p>

(MODIFY TH S1                               ; Because of the extra char
        :KEY1 V1                            ; in S1 the flat size exceeds
        :KEY2 V2                            ; 40 and we break it.
        :KEY3 V3)
</pre>

The old ppr would have printed this as:

<pre>
(MODIFY
     TH S1 :KEY1 V1 :KEY2 V2 :KEY3 V3)
</pre>

Returning to new examples:

<pre>
&lt;--            40 chars               -&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<p>

(MODIFY TH S
        :KEY1 (IF (IF X Y Z) AAAA BBBB)
        :KEY2 VAL2
        :KEY3 VAL3)
</pre>

Now we extend <code>AAAA</code> and <code>BBBB</code> by one char each, so it would overflow
the right margin if printed as above, and we get:

<pre>
&lt;--            40 chars               -&gt;
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<p>

(MODIFY
     TH S
     :KEY1 (IF (IF X Y Z) AAAAX BBBBX)
     :KEY2 VAL2
     :KEY3 VAL3)
</pre>

If we make these names even longer we force the value off the line containing
<code>:key1</code>:

<pre>
(MODIFY
     TH S
     :KEY1
     (IF (IF X Y Z) AAAAXXXXX BBBBXXXXX)
     :KEY2 VAL2
     :KEY3 VAL3)
</pre>

Here are some examples from the ACL2 source code, printed in 40 characters:

<pre>
(DEFTHM
 ALPHORDER-ANTI-SYMMETRIC
 (IMPLIES (AND (NOT (CONSP X))
               (NOT (CONSP Y))
               (ALPHORDER X Y)
               (ALPHORDER Y X))
          (EQUAL X Y))
 :HINTS
 (("Goal"
   :IN-THEORY
   (UNION-THEORIES
    '(STRING&lt; SYMBOL-&lt;)
    (DISABLE
       CODE-CHAR-CHAR-CODE-IS-IDENTITY))
   :USE
   ((:INSTANCE SYMBOL-EQUALITY (S1 X)
               (S2 Y))
    (:INSTANCE BAD-ATOM&lt;=-ANTISYMMETRIC)
    (:INSTANCE
         CODE-CHAR-CHAR-CODE-IS-IDENTITY
         (C Y))
    (:INSTANCE
         CODE-CHAR-CHAR-CODE-IS-IDENTITY
         (C X)))))
 :RULE-CLASSES
 ((:FORWARD-CHAINING
   :COROLLARY
   (IMPLIES
      (AND (ALPHORDER X Y)
           (NOT (CONSP X))
           (NOT (CONSP Y)))
      (IFF (ALPHORDER Y X) (EQUAL X Y)))
   :HINTS
   (("Goal"
     :IN-THEORY (DISABLE ALPHORDER))))))
</pre>

Here is that same one, printed in a width of 60.

<pre>
(DEFTHM
 ALPHORDER-ANTI-SYMMETRIC
 (IMPLIES (AND (NOT (CONSP X))
               (NOT (CONSP Y))
               (ALPHORDER X Y)
               (ALPHORDER Y X))
          (EQUAL X Y))
 :HINTS
 (("Goal"
     :IN-THEORY
     (UNION-THEORIES
          '(STRING&lt; SYMBOL-&lt;)
          (DISABLE CODE-CHAR-CHAR-CODE-IS-IDENTITY))
     :USE ((:INSTANCE SYMBOL-EQUALITY (S1 X)
                      (S2 Y))
           (:INSTANCE BAD-ATOM&lt;=-ANTISYMMETRIC)
           (:INSTANCE CODE-CHAR-CHAR-CODE-IS-IDENTITY (C Y))
           (:INSTANCE CODE-CHAR-CHAR-CODE-IS-IDENTITY
                      (C X)))))
 :RULE-CLASSES
 ((:FORWARD-CHAINING
      :COROLLARY (IMPLIES (AND (ALPHORDER X Y)
                               (NOT (CONSP X))
                               (NOT (CONSP Y)))
                          (IFF (ALPHORDER Y X) (EQUAL X Y)))
      :HINTS (("Goal" :IN-THEORY (DISABLE ALPHORDER))))))
</pre>

Just for comparison, here is the above printed in 60 columns by the old
prettyprinter.

<pre>
(DEFTHM
 ALPHORDER-ANTI-SYMMETRIC
 (IMPLIES (AND (NOT (CONSP X))
               (NOT (CONSP Y))
               (ALPHORDER X Y)
               (ALPHORDER Y X))
          (EQUAL X Y))
 :HINTS
 (("Goal" :IN-THEORY
          (UNION-THEORIES
               '(STRING&lt; SYMBOL-&lt;)
               (DISABLE CODE-CHAR-CHAR-CODE-IS-IDENTITY))
          :USE
          ((:INSTANCE SYMBOL-EQUALITY (S1 X)
                      (S2 Y))
           (:INSTANCE BAD-ATOM&lt;=-ANTISYMMETRIC)
           (:INSTANCE CODE-CHAR-CHAR-CODE-IS-IDENTITY (C Y))
           (:INSTANCE CODE-CHAR-CHAR-CODE-IS-IDENTITY
                      (C X)))))
 :RULE-CLASSES
 ((:FORWARD-CHAINING
       :COROLLARY
       (IMPLIES (AND (ALPHORDER X Y)
                     (NOT (CONSP X))
                     (NOT (CONSP Y)))
                (IFF (ALPHORDER Y X) (EQUAL X Y)))
       :HINTS
       (("Goal" :IN-THEORY (DISABLE ALPHORDER))))))
</pre>
<p>

Of course, given that you cannot tell for sure whether the keywords you're
seeing are part of a keyword/value parameter list or part of some constant
containing random keywords, the prettyprinter can't solve the problem
perfectly.  We just tried to make it work nicely on well-formed keyword/value
parameter lists.<p>

For example, here is a form printed by the each prettyprinter.

<pre>
Old:
(MEMBER
 X
 '(:MONDAY
      :MON :TUESDAY :TUES :WEDNESDAY
      :WED :THURSDAY :THURS :FRIDAY
      :FRI :SATURDAY :SAT :SUNDAY :SUN))<p>

New:
(MEMBER X
        '(:MONDAY :MON
                  :TUESDAY :TUES
                  :WEDNESDAY :WED
                  :THURSDAY :THURS
                  :FRIDAY :FRI
                  :SATURDAY :SAT
                  :SUNDAY :SUN))
</pre>
<p>

The new way is not how one would print it by hand!  But then, neither is the
old way.
<br><br><br><a href="acl2-doc.html"><img src="llogo.gif"></a> <a href="acl2-doc-index.html"><img src="index.gif"></a>
</body>
</html>