115
118
(equal (ash i pos)
116
119
(* i (expt 2 pos))))))
121
;;;****************************************************************************
123
;;; Definitions -- Round 1.
125
;;; Type predicates and functions.
132
;;;****************************************************************************
134
(defun-inline bitp (b)
135
":doc-section logops-definitions
136
A predicate form of the type declaration (TYPE BIT b).
138
(declare (xargs :guard t))
121
(local (defthm logand-positive
123
(<= 0 (logand i mask)))
124
:rule-classes ((:linear))))
129
(local (defun my-induct (i size)
132
(my-induct (ash i -1)
135
(defthmd mod-of-expt-2-is-logand
136
(implies (and (integerp size)
139
(equal (mod i (expt 2 size))
140
(logand i (1- (ash 1 size)))))
141
:hints(("Goal" :induct (my-induct i size))))))
145
:short "Bit recognizer. @('(bitp b)') recognizes 0 and 1."
146
:long "<p>This is a predicate form of the @(see type-spec) declaration
147
@('(TYPE BIT b)').</p>"
151
:no-function t ;; Sigh, switching to :abbreviation breaks various proofs
142
(defun-inline bfix (b)
143
":doc-section logops-definitions
144
(BFIX b) coerces any object to a bit (0 or 1) by coercing non-1 objects to 0.
146
(declare (xargs :guard t))
150
":doc-section logops-definitions
151
(LBFIX b) is logically (BFIX b), but requires (BITP b) as a guard and expands
154
`(mbe :logic (bfix ,x) :exec ,x))
156
(defun-inline zbp (x)
157
":doc-section logops-definitions
158
(ZBP x) tests for `zero bits'. Any object other than 1 is considered a
161
(declare (xargs :guard (bitp x)))
156
:parents (logops-definitions bitp)
157
:short "Bit fix. @('(bfix b)') is a fixing function for @(see bitp)s. It
158
coerces any object to a bit (0 or 1) by coercing non-1 objects to 0."
159
:long "<p>See also @(see lbfix).</p>"
163
:no-function t ;; Sigh, switching to :abbreviation breaks various proofs
169
:parents (logops-definitions bitp)
170
:short "Logical bit fix. @('(lbfix b)') is logically identical to @('(bfix
171
b)') but executes as the identity. It requires @('(bitp b)') as a guard, and
172
expands to just @('b')."
176
`(mbe :logic (bfix ,x) :exec ,x)))
179
:parents (logops-definitions bitp)
180
:short "Zero bit recognizer. @('(zbp x)') tests for zero bits. Any object
181
other than @('1') is considered to be a zero bit."
162
186
(mbe :logic (equal (bfix x) 0)
163
187
:exec (/= (the (unsigned-byte 1) x) 1)))
167
:doc ":doc-section bitp
168
Rewrite: (BITP (BFIX b)).
174
:hints (("Goal" :in-theory (enable bitp)))
175
:doc ":doc-section bfix
176
Rewrite: (BFIX b) = b, when b is a bit.
182
;;;****************************************************************************
184
;;; Definition -- Round 2.
186
;;; Extensions to the CLTL logical operations and byte functions.
206
;;; LOGEXTU final-size ext-size i
211
;;; After the definitions, we define a guard macro for each that has a
212
;;; non-trivial guard, and then define :TYPE-PRESCRIPTIONS for them. We
213
;;; always define our own :TYPE-PRESCRIPTIONS in insure that we always have
214
;;; the strongest ones possible when this book is loaded. Note that we
215
;;; consider IFLOOR, IMOD, and EXPT2 to be abbreviations.
217
;;;****************************************************************************
219
(defun-inline ifloor (i j)
220
":doc-section logops-definitions
221
(IFLOOR i j) is the same as floor, except that it coerces its
222
arguments to integers.
224
(declare (xargs :guard (and (integerp i)
189
(defsection bitp-basics
197
(equal (bfix b) b))))
201
:short "@('(ifloor i j)') is the same as @(see floor), except that it coerces
202
its arguments to integers."
206
:returns (int integerp
207
:rule-classes :type-prescription
227
211
(mbe :logic (floor (ifix i) (ifix j))
228
212
:exec (floor i j)))
230
(defun-inline imod (i j)
231
":doc-section logops-definitions
232
(IMOD i j) is the same as mod, except that it coerces its
233
arguments to integers.
235
(declare (xargs :guard (and (integerp i)
215
:short "@('(imod i j)') is the same as @(see mod), except that it coerces its
216
arguments to integers."
220
:returns (int integerp
221
:rule-classes :type-prescription
238
225
(mbe :logic (mod (ifix i) (ifix j))
239
226
:exec (mod i j)))
241
(defun-inline expt2 (n)
242
":doc-section logops-definitions
243
(EXPT2 n) is the same as 2^n, except that it coerces its
244
argument to a natural.
246
(declare (xargs :guard (and (integerp n)
229
:short "@('(expt2 n)') is the same as @('(expt 2 n)'), except that it coerces
230
its argument to a natural."
233
:rule-classes :type-prescription
248
237
(mbe :logic (expt 2 (nfix n))
251
(defun-inline logcar (i)
252
":doc-section logops-definitions
253
(LOGCAR i) is the CAR of an integer conceptualized as a bit-vector (where the
254
least significant bit is at the head of the list).
256
(declare (xargs :guard (integerp i)))
238
:exec (the unsigned-byte
239
(ash 1 (the unsigned-byte n)))))
243
:short "Least significant bit of a number."
246
:long "<p>@('(logcar i)') is the @(see car) of an integer conceptualized as a
247
bit-vector, where the least significant bit is at the head of the list.</p>
249
<p>In languages like C, this might be written as @('i & 1').</p>"
257
252
(mbe :logic (imod i 2)
258
:exec (the (unsigned-byte 1) (logand i 1))))
260
(defun-inline logcdr (i)
261
":doc-section logops-definitions
262
(LOGCDR i) is the CDR of an integer conceptualized as a bit-vector (where the
263
least significant bit is at the head of the list).
265
(declare (xargs :guard (integerp i)))
253
:exec (the (unsigned-byte 1) (logand (the integer i) 1)))
257
:rule-classes ((:rewrite)
258
(:type-prescription :corollary (natp (logcar i)))
259
(:generalize :corollary
260
(or (equal (logcar i) 0)
261
(equal (logcar i) 1))))))
264
:short "All but the least significant bit of a number."
266
:returns (int integerp
267
:rule-classes :type-prescription
269
:long "<p>@('(logcdr i)') is the @(see cdr) of an integer conceptualized as a
270
bit-vector, where the least significant bit is at the head of the list.</p>
272
<p>In languages like C, this might be written as @('i >> 1').</p>"
266
275
(mbe :logic (ifloor i 2)
269
(defun-inline logcons (b i)
270
":doc-section logops-definitions
271
(LOGCONS b i) is the CONS operation for integers conceptualized as
272
bit-vectors (where i is multiplied by 2 and b becomes the new least
275
For clarity and efficiency, b is required to be BITP.~/~/"
276
(declare (xargs :guard (and (bitp b)
276
:exec (the integer (ash (the integer i) -1))))
279
:short "@('(logcons b i)') is the @(see cons) operation for integers,
280
conceptualized as bit-vectors, where the least significant bit is at the head
282
((b bitp "LSB of the result.")
283
(i integerp "All but the LSB of the result."))
284
:returns (int integerp
285
:rule-classes :type-prescription
287
:long "<p>In languages like C, this might be written as @('(i << 1) + b').</p>
289
<p>See also @(see logcar) and @(see logcdr).</p>"
278
292
(mbe :logic (let ((b (bfix b))
281
:exec (+ b (ash i 1))))
283
(defun-inline logbit (pos i)
284
":doc-section logops-definitions
285
(LOGBIT pos i) returns the bit of i at bit-position pos.
287
This is a binary equivalent to the Common Lisp function (LOGBITP pos i).~/~/"
288
(declare (xargs :guard (and (integerp pos)
291
(if (logbitp pos i) 1 0))
293
(defun-inline logmask (size)
294
":doc-section logops-definitions
295
(LOGMASK size) creates a low-order, size-bit mask.
297
(declare (xargs :guard (and (integerp size)
296
(+ (the (unsigned-byte 1) b)
297
(the integer (ash i 1))))))
300
:parents (logops-definitions logbitp)
301
:short "@('(logbit pos i)') returns the bit of @('i') at bit-position @('pos')
302
as a @(see bitp), 0 or 1."
306
:long "<p>This is just like the Common Lisp function @('(logbitp pos i)'),
307
except that we return 1 or 0 (instead of t or nil).</p>
309
<p>In languages like C, this might be written as @('(i >> pos) & 1').</p>"
312
:no-function t ;; Sigh, switching to :abbreviation breaks various proofs
319
(bitp (logbit pos i))
320
:rule-classes ((:rewrite)
321
(:type-prescription :corollary (natp (logbit pos i))))
322
;; BOZO want a generalize rule like in logcar?
327
:short "@('(logmask size)') creates a low-order, @('size')-bit mask."
330
:rule-classes :type-prescription
332
:long "<p>In languages like C, this might be written as @('(1 << size) - 1').</p>"
299
335
(mbe :logic (- (expt2 size) 1)
300
:exec (- (ash 1 size) 1)))
336
:exec (the unsigned-byte (1- (the unsigned-byte (ash 1 size))))))
303
":doc-section logops-definitions
304
(LOGMASKP i) recognizes positive masks.
306
(declare (xargs :guard t))
339
:short "@('(logmaskp i)') recognizes positive bit-masks, i.e., numbers of the
344
:long "<p>Note that this function explicitly checks @('(integerp i)'), which
345
means it doesn't satisfy an @(see int-equiv) congruence. See also @(see
346
bitmaskp), which fixes its argument and may execute slightly faster.</p>"
307
347
(mbe :logic (and (integerp i)
308
348
(>= i 0) ;; silly, this is implied by the equality below
309
349
(equal i (- (expt2 (integer-length i)) 1)))
310
350
:exec (and (integerp i)
311
(= i (- (ash 1 (integer-length i)) 1)))))
314
;; replacement for logmaskp that respects int-equiv
315
(declare (xargs :guard (integerp i)))
318
(defun-inline loghead (size i)
319
":doc-section logops-definitions
320
(LOGHEAD size i) returns the size low-order bits of i.
322
By convention we define (LOGHEAD 0 i) as 0, but this definition is a bit
324
(declare (xargs :guard (and (integerp size)
351
(eql i (the unsigned-byte
352
(- (the unsigned-byte (ash 1 (integer-length i)))
356
:short "@('(bitmaskp i)') recognizes positive masks, i.e., numbers of the form
357
@($2^n - 1$). It is like @(see logmaskp) but properly treats non-integers as 0."
361
(mbe :logic (logmaskp (mbe :logic (ifix i)
363
:exec (eql i (the unsigned-byte
364
(- (the unsigned-byte (ash 1 (integer-length i)))
368
:short "@('(loghead size i)') returns the @('size') low-order bits of @('i')."
369
((size (and (integerp size)
374
:rule-classes :type-prescription
376
:long "<p>In languages like C, this might be written as @('i & ((1 << size) -
379
<p>By convention we define @('(loghead 0 i)') as 0. This definition is a
380
bit arbitrary but generally leads to nice lemmas.</p>"
384
:guard-hints(("Goal" :in-theory (enable mod-of-expt-2-is-logand)))
327
385
(mbe :logic (imod i (expt2 size))
328
;; BOZO it'd be nicer to give this an :exec of (logand i (1- (ash 1
329
;; size))), but that'll require some additional lemmas...
330
:exec (mod i (ash 1 size))))
388
(logand i (the unsigned-byte
389
(1- (the unsigned-byte (ash 1 size))))))))
332
(defun-inline logtail (pos i)
333
":doc-section logops-definitions
334
(LOGTAIL pos i) returns the high-order part of i starting at bit position
392
:short "@('(logtail pos i)') returns the high-order part of @('i'), starting
393
at bit position @('pos')."
394
((pos (and (integerp pos)
398
:returns (int integerp
399
:rule-classes :type-prescription
401
:long "<p>In languages like C, this might be written as @('i >> pos').</p>"
337
405
(declare (xargs :guard (and (integerp pos)
340
408
(mbe :logic (ifloor i (expt2 pos))
341
409
:exec (ash i (- (the unsigned-byte pos)))))
343
(defun logapp (size i j)
344
":doc-section logops-definitions
345
(LOGAPP size i j) is a binary append of i to j (where i effectively becomes
346
the 'low' bits and j becomes the 'high' bits).
348
LOGAPP is a specification for merging integers. Note that i is truncated to
349
size bits before merging with j, and that j is also shifted to the left by
350
size bits before the merge.~/"
351
(declare (xargs :guard (and (integerp size)
412
:short "@('(logapp size i j)') is a binary append of i to j, where i
413
effectively becomes the 'low' bits and j becomes the 'high' bits."
414
((size (and (integerp size)
419
:returns (int integerp
420
:rule-classes :type-prescription
423
:long "<p>@('logapp') is a specification for merging integers. Note that
424
@('i') is truncated to @('size') bits before merging with @('j'), and that @('j')
425
is shifted to the left by @('size') bits before the merge.</p>"
355
427
(mbe :logic (let ((j (ifix j)))
356
428
(+ (loghead size i) (* j (expt2 size))))
357
429
;; BOZO could do better than calling loghead with some work
430
;; Could probably use logior instead of +.
358
431
:exec (+ (loghead size i) (ash j size))))
360
(defun logrpl (size i j)
361
":doc-section logops-definitions
362
(LOGRPL size i j) replaces the size low-order bits of j with the size
365
LOGRPL is a common specification for the result of storing short values into
366
long words, i.e., the short value simply replaces the head of the long
367
word. This function is equivalent to (WRB i (BSP size 0) j).~/~/"
368
(declare (xargs :guard (and (integerp size)
434
:short "Logical replace. @('(logrpl size i j)') replaces the @('size')
435
low-order bits of @('j') with the @('size') low-order bits of @('i')."
436
((size (and (integerp size)
440
:returns (int integerp
441
:rule-classes :type-prescription
443
:long "<p>@('logrpl') is a specification for the result of storing short
444
values into long words, i.e., the short value simply replaces the head of the
447
<p>This function is equivalent to @('(WRB i (BSP size 0) j)').</p>"
372
449
(logapp size i (logtail size j)))
374
(defun logext (size i)
375
":doc-section logops-definitions
376
(LOGEXT size i) \"sign-extends\" i to an integer with size - 1 significant
379
LOGEXT coerces any integer i into a signed integer by `sign extending'
380
the bit at size - 1 to infinity. We specify LOGEXT in terms of the `size'
381
of the result instead of as a bit position because we normally specify
382
integer subranges by the number of significant (including sign) bits.
384
Note that for consistency with SIGNED-BYTE-P, size must be strictly greater
386
(declare (xargs :guard (and (integerp size)
389
;; BOZO could do better than this with MBE with some work, see centaur/bitops/sign-extend
390
(logapp (1- size) i (if (logbitp (1- size) i) -1 0)))
392
(defun logrev1 (size i j)
393
":doc-section logops-definitions
394
Helper function for LOGREV.
396
(declare (xargs :guard (and (integerp size)
452
:short "Logical sign extension, signed version. @('(logext size i)')
453
sign-extends @('i') to an integer with @('size - 1') significant bits."
454
((size (and (integerp size)
458
:returns (int integerp
459
:rule-classes :type-prescription
462
:long "<p>@('logext') coerces any integer @('i') into a signed integer by
463
\"sign extending\" the bit at @('size - 1') to infinity.</p>
465
<p>We specify logext in terms of the @('size') of the result instead of as a
466
bit position because we normally specify integer subranges by the number of
467
significant (including sign) bits.</p>
469
<p>This function returns a (possibly negative) integer. For consistency with
470
@(see SIGNED-BYTE-P), @('size') must be strictly greater than 0. In contrast,
471
the related function @(see logextu) carries out a sign-extension but only
472
returns the low @('size') bits, i.e., it always returns a natural number.</p>
474
<p>See also @(see bitops/fast-logext) for an optimized implementation of @(see
478
(let* ((size-1 (- size 1)))
479
(declare (type unsigned-byte size-1))
481
(if (logbitp size-1 i)
487
:short "Helper function for @(see logrev)."
488
((size (and (integerp size)
494
(declare (type unsigned-byte size)
402
(logrev1 (- size 1) (logcdr i) (logcons (logcar i) j))))
404
(defun logrev (size i)
405
":doc-section logops-definitions
406
(LOGREV size i) bit-reverses the size low-order bits of i, discarding the
409
Normally we don't think of bit-reversing as a logical operation,
410
even though its hardware implementation is trivial: simply reverse the
411
wires leading from the source to the destination. LOGREV is included as a
412
logical operation to support the specification of DSPs, which may
413
provide bit-reversing in their address generators to improve the
414
performance of the FFT.
416
LOGREV entails a recursive definition of bit-reversing via the helper
418
(declare (xargs :guard (and (integerp size)
500
(logrev1 (the unsigned-byte (- size 1))
502
(logcons (logcar i) j))))
504
(local (defthm logrev1-type
506
(natp (logrev1 size i j)))
507
:rule-classes :type-prescription
508
:hints(("Goal" :in-theory (disable imod ifloor)))))
511
:short "Logical reverse. @('(logrev size i)') bit-reverses the @('size')
512
low-order bits of @('i'), discarding the high-order bits."
513
((size (and (integerp size)
517
:rule-classes :type-prescription
519
:long "<p>Normally we don't think of bit-reversing as a logical operation,
520
even though its hardware implementation is trivial: simply reverse the wires
521
leading from the source to the destination.</p>
523
<p>@('logrev') is included as a logical operation to support the specification
524
of DSPs, which may provide bit-reversing in their address generators to improve
525
the performance of the FFT.</p>
527
<p>@('logrev') entails a recursive definition of bit-reversing via the helper
528
function @(see logrev1).</p>
530
<p>See also @(see bitops/fast-logrev) for some optimized definitions of @(see
421
534
(logrev1 size i 0))
423
(defun logsat (size i)
424
":doc-section logops-definitions
425
(LOGSAT size i) coerces i to a size-bit signed integer by saturation.
427
If i can be represented as a size-bit signed integer, then i is returned.
428
Otherwise, (LOGSAT size i) returns the size-bit signed integer closest to
429
i. For positive i, this will be 2^(size-1) - 1. For negative i, this will
432
Note that for consistency with SIGNED-BYTE-P, size must be strictly
435
(declare (xargs :guard (and (integerp size)
439
(let* ((i (ifix i)) ;?
440
(val (expt2 (1- size)))
537
:short "Signed saturation. @('(logsat size i)') coerces @('i') to a
538
@('size')-bit signed integer by saturation."
539
((size (and (integerp size)
543
:returns (int integerp
544
:rule-classes :type-prescription
547
:long "<p>If @('i') can be represented as a @('size')-bit signed integer,
548
then @('i') is returned unchanged. Otherwise, @('(logsat size i)') returns
549
the @('size')-bit signed integer closest to @('i'). For positive i, this
550
will be @($2^{size-1} - 1$). For negative @('i'), this will be
551
@($-(2^{size-1}$).</p>
553
<p>This function returns a (possibly negative) integer. For consistency with
554
@(see signed-byte-p), size must be strictly greater than 0. In contrast, the
555
related @(see bitops/saturate) functions always return @('size')-bit natural
560
(let* ((i (mbe :logic (ifix i) :exec i))
561
(val (expt2 (the unsigned-byte (1- size))))
562
(maxval (the unsigned-byte (1- (the unsigned-byte val))))
442
563
(minval (- val)))
564
(declare (type unsigned-byte val maxval)
565
(type integer i minval))
444
566
(if (>= i maxval)
446
568
(if (<= i minval)
450
(defun logextu (final-size ext-size i)
451
":doc-section logops-definitions
452
(LOGEXTU final-size ext-size i) \"sign-extends\" i with (LOGEXT ext-size i),
453
then truncates the result to final-size bits, creating an unsigned integer.
455
(declare (xargs :guard (and (integerp final-size)
460
:guard-hints (("Goal" :in-theory (disable exponents-add)))))
573
:short "Logical sign extension, unsigned version. @('(logextu final-size
574
ext-size i)') \"sign-extends\" i with @('(logext ext-size i)'), then truncates
575
the result to @('final-size') bits, creating an unsigned integer."
576
((final-size (and (integerp final-size)
578
(ext-size (and (integerp ext-size)
582
:rule-classes :type-prescription
461
586
(loghead final-size (logext ext-size i)))
463
(defun lognotu (size i)
464
":doc-section logops-definitions
465
(LOGNOTU size i) is an unsigned logical NOT, truncating (LOGNOT i) to size
468
(declare (xargs :guard (and (integerp size)
589
:short "Logical negation, unsigned version. @('(lognotu size i)') is an
590
unsigned logical @('not'). It just truncates @('(lognot i)') to @('size')
592
((size (and (integerp size)
596
:rule-classes :type-prescription
471
600
(loghead size (lognot i)))
473
(defun ashu (size i cnt)
474
":doc-section logops-definitions
475
(ASHU size i cnt) is an unsigned version of ASH.
477
ASHU is a fixed-width version of ASH. The integer i is first coerced to a
478
signed integer by sign-extension, then shifted with ASH, and finally
479
truncated back to a size-bit unsigned integer.~/~/"
480
(declare (xargs :guard (and (integerp size)
484
:guard-hints (("Goal" :in-theory (disable exponents-add)))))
603
:short "Arithmetic shift, unsigned version."
604
((size (and (integerp size)
609
:rule-classes :type-prescription
611
:long "<p>@('ashu') is a fixed-width version of @(see ash). The integer
612
@('i') is first coerced to a @('size')-bit signed integer by sign-extension,
613
then shifted with @('ash'), and finally truncated back to a @('size')-bit
614
unsigned integer.</p>
616
<p>See also @(see lshu) for a logical (instead of arithmetic) shift.</p>"
485
618
(loghead size (ash (logext size i) cnt)))
487
(defun lshu (size i cnt)
488
":doc-section logops-definitions
489
(LSHU size i cnt) is an unsigned logical shift.
491
LSHU shifts i by cnt bits by first coercing i to an unsigned integer,
492
performing the shift, and coercing the result to an unsigned integer.
493
For cnt >= 0, (LSHU size i cnt) = (ASHU size i cnt). This is a model
494
of a size-bit logical shift register.~/~/"
495
(declare (xargs :guard (and (integerp size)
621
:short "Logical shift, unsigned version."
622
((size (and (integerp size)
627
:rule-classes :type-prescription
629
:long "<p>@('lshu') is a fixed-width logical shift. It shifts @('i')
630
by @('cnt') bits by first coercing @('i') to an unsigned integer of @('size')
631
bits, performing the shift, and coercing the result to an @('size')-bit
632
unsigned integer.</p>
634
<p>For @('cnt >= 0'), @('(lshu size i cnt) = (ashu size i cnt)').</p>
636
<p>This is a model of a size-bit logical shift register.</p>"
499
638
(loghead size (ash (loghead size i) cnt)))
503
;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
505
;;; Type Lemmas for the new LOGOPS. Each function is DISABLEd after we
506
;;; have enough information about it (except for IFLOOR, IMOD, and EXPT2,
507
;;; which are considered abbreviations). We prove even the most obvious
508
;;; type lemmas because you never know what theory this book will be
509
;;; loaded into, and unless the theory is strong enough you may not get
510
;;; everthing you need.
512
;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
515
(integerp (ifloor i j))
516
:rule-classes :type-prescription
517
:doc ":doc-section ifloor
518
Type-prescription: (INTEGERP (IFLOOR I J)).
522
(integerp (imod i j))
523
:rule-classes :type-prescription
524
:doc ":doc-section imod
525
Type-prescription: (INTEGERP (IMOD I J)).
530
:rule-classes :type-prescription
531
:doc ":doc-section expt2
532
Type-prescription: (NATP (EXPT2 N)).
537
:rule-classes ((:rewrite)
538
(:type-prescription :corollary (natp (logcar i)))
539
(:generalize :corollary
540
(or (equal (logcar i) 0)
541
(equal (logcar i) 1))))
542
:doc ":doc-section logcar
543
Rewrite: (BITP (LOGCAR i)).
545
This rule is also stored as appropriate :TYPE-PRESCRIPTION and
546
:GENERALIZE rules.~/~/")
549
(integerp (logcdr i))
550
:rule-classes :type-prescription
551
:doc ":doc-section logcdr
552
Type-Prescription: (INTEGERP (LOGCDR I)).
556
(integerp (logcons b i))
557
:rule-classes :type-prescription
558
:doc ":doc-section logcons
559
Type-prescription: (INTEGERP (LOGCONS b i)).
563
(bitp (logbit pos i))
564
:rule-classes ((:rewrite)
565
(:type-prescription :corollary (natp (logbit pos i))))
566
;; BOZO want a generalize rule like in logcar?
567
:doc ":doc-section logbit
568
Rewrite: (BITP (LOGBIT pos i)).
570
This rule is also stored as an appropriate :TYPE-PRESCRIPTION.~/~/")
574
:rule-classes :type-prescription
575
:doc ":doc-section logmask
576
Type-Prescription: (NATP (LOGMASK i)).
580
(natp (loghead size i))
581
:rule-classes :type-prescription
582
:doc ":doc-section loghead
583
Type-prescription: (NATP (LOGHEAD size i)).
587
(integerp (logtail pos i))
588
:rule-classes :type-prescription
589
:doc ":doc-section logcons
590
Type-prescription: (INTEGERP (LOGTAIL POS I)).
594
(integerp (logapp size i j))
595
:rule-classes :type-prescription
596
:doc ":doc-section logcons
597
Type-prescription: (INTEGERP (LOGAPP SIZE I J)).
601
(integerp (logrpl size i j))
602
:rule-classes :type-prescription
603
:doc ":doc-section logcons
604
Type-prescription: (INTEGERP (LOGRPL SIZE I J)).
608
(integerp (logext size i))
609
:rule-classes :type-prescription
610
:doc ":doc-section logext
611
Type-Prescription: (INTEGERP (LOGEXT size i)).
614
(local (defthm logrev1-type
616
(natp (logrev1 size i j)))
617
:rule-classes :type-prescription
618
:hints(("Goal" :in-theory (disable imod ifloor)))))
621
(natp (logrev size i))
622
:rule-classes :type-prescription
623
:doc ":doc-section logrev
624
Type-prescription: (NATP (LOGREV size i)).
628
(integerp (logsat size i))
629
:rule-classes :type-prescription
630
:doc ":doc-section logsat
631
Type-Prescription: (INTEGERP (LOGSAT size i)).
635
(natp (logextu final-size ext-size i))
636
:rule-classes :type-prescription
637
:doc ":doc-section logextu
638
Type-prescription: (NATP (LOGEXTU final-size ext-size i)).
642
(natp (lognotu size i))
643
:rule-classes :type-prescription
644
:doc ":doc-section lognotu
645
Type-prescription: (NATP (LOGNOTU size i)).
649
(natp (ashu size i cnt))
650
:rule-classes :type-prescription
651
:doc ":doc-section ashu
652
Type-prescription: (NATP (ASHU size i cnt)).
656
(natp (lshu size i cnt))
657
:rule-classes :type-prescription
658
:doc ":doc-section lshu
659
Type-prescription: (NATP (LSHU size i cnt)).
664
;;;****************************************************************************
666
;;; Definitions -- Round 3.
668
;;; Logical operations on single bits.
682
;;;****************************************************************************
684
(deflabel logops-bit-functions
685
:doc ":doc-section logops-definitions
686
Versions of the standard logical operations that operate on single bits.
689
We provide versions of the non-trivial standard logical operations that
690
operate on single bits. The reason that it is necessary to introduce these
691
operations separate from the standard operations is the fact that LOGNOT
692
applied to a BITP object never returns a BITP. All arguments to these
693
functions must be BITP, and we prove that each returns a BITP integer. We
694
define each function explicitly in terms of 0 and 1 to simplify
697
(defun-inline b-not (i)
698
":doc-section logops-bit-functions
700
(declare (xargs :guard (bitp i)))
642
(defxdoc logops-bit-functions
643
:parents (logops-definitions bitp)
644
:short "Versions of the standard logical operations that operate on single bits."
645
:long "<p>We provide versions of the non-trivial standard logical operations
646
that operate on single bits.</p>
648
<p>One reason that it is useful to introduce these operations separately from
649
the standard operations is the fact that @(see lognot) applied to a @(see bitp)
650
object never returns a @(see bitp).</p>
652
<p>All arguments to these functions must be @(see bitp), and we prove that
653
each returns a @(see bitp) integer, i.e., 0 or 1. We define each function
654
explicitly in terms of 0 and 1 to simplify reasoning.</p>")
656
(local (xdoc::set-default-parents logops-bit-functions))
658
(define b-not ((i bitp))
660
:short "Negation for @(see bitp)s."
701
663
(mbe :logic (if (zbp i) 1 0)
702
664
:exec (the (unsigned-byte 1)
703
665
(- 1 (the (unsigned-byte 1) i)))))
705
(defun-inline b-and (i j)
706
":doc-section logops-bit-functions
708
(declare (xargs :guard (and (bitp i) (bitp j))))
667
(define b-and ((i bitp) (j bitp))
669
:short "Conjunction for @(see bitp)s."
709
672
(mbe :logic (if (zbp i) 0 (if (zbp j) 0 1))
710
673
:exec (the (unsigned-byte 1)
711
674
(logand (the (unsigned-byte 1) i)
712
675
(the (unsigned-byte 1) j)))))
714
(defun-inline b-ior (i j)
715
":doc-section logops-bit-functions
717
(declare (xargs :guard (and (bitp i) (bitp j))))
677
(define b-ior ((i bitp) (j bitp))
679
:short "Inclusive or for @(see bitp)s."
718
682
(mbe :logic (if (zbp i) (if (zbp j) 0 1) 1)
719
683
:exec (the (unsigned-byte 1)
720
684
(logior (the (unsigned-byte 1) i)
721
685
(the (unsigned-byte 1) j)))))
723
(defun-inline b-xor (i j)
724
":doc-section logops-bit-functions
726
(declare (xargs :guard (and (bitp i) (bitp j))))
687
(define b-xor ((i bitp) (j bitp))
689
:short "Exclusive or for @(see bitp)s."
727
692
(mbe :logic (if (zbp i) (if (zbp j) 0 1) (if (zbp j) 1 0))
728
693
:exec (the (unsigned-byte 1)
729
694
(logxor (the (unsigned-byte 1) i)
730
695
(the (unsigned-byte 1) j)))))
732
(defun-inline b-eqv (i j)
733
":doc-section logops-bit-functions
735
(declare (xargs :guard (and (bitp i) (bitp j))))
697
(define b-eqv ((i bitp) (j bitp))
699
:short "Equivalence (a.k.a. if and only if, xnor) for @(see bitp)s."
736
702
(mbe :logic (if (zbp i) (if (zbp j) 1 0) (if (zbp j) 0 1))
737
703
;; Goofy definition, Using logeqv or lognot of logxor would require
738
704
;; masking (they produce -1 for, e.g., (logeqv 0 0)). So I'll just xor