2
(begin-book);$ACL2s-Preamble$|#
7
A Simple Random Number Generator Version 0.1
8
Jared Davis <jared@cs.utexas.edu> February 25, 2004
10
This file is in the public domain. You can freely use it for any
11
purpose without restriction.
13
This is just a basic pure multiplicative pseudorandom number gen-
14
erator. *M31* is the 31st mersenne prime, and *P1* is 7^5 which
15
is a primitive root of *M31*, ensuring that our period is M31 - 1.
16
This idea is described in "Elementary Number Theory and its Appli-
17
cations" by Kenneth H. Rosen, Fourth Edition, Addison Wesley 1999,
18
in Chapter 10.1, pages 356-358.
20
The random number generator uses a stobj, rand, to store the seed.
21
You will want to use the following functions:
23
(genrandom <max> rand)
24
Returns (mv k rand) where 0 <= k < max.
26
(update-seed <newseed> rand)
27
Manually switch to a new seed. By default, a large messy num-
28
ber will be used. You probably don't need to change it, but
29
it might be good if you want to be able to reproduce your re-
32
Normally we are not particularly interested in reasoning about ran-
33
dom numbers. However, we can say that the number k generated is an
34
an integer, and that 0 <= k < max when max is a positive integer.
35
See the theorems genrandom-minimum and genrandom-maximum.
39
Modified slightly by Peter Dillinger, 7 Feb 2008
40
With significant additions by Dimitris Vardoulakis & Peter Dillinger where
46
(set-verify-guards-eagerness 2)
49
(defconst *M31* 2147483647)
53
(seed :type integer :initially 1382728371))
58
(declare (xargs :stobjs (rand)))
59
(let ((s (seed rand)))
60
(if (and (integerp s) (<= 0 s))
64
(local (defthm getseed-integer
65
(and (integerp (getseed rand))
66
(<= 0 (getseed rand)))
67
:rule-classes :type-prescription))
69
(in-theory (disable getseed))
71
(defun genrandom (max rand)
72
(declare (xargs :stobjs (rand)
74
(let* ((new-seed (mod (* *P1* (getseed rand)) *M31*))
75
(rand (update-seed new-seed rand)))
82
(local (include-book "arithmetic-3/floor-mod/floor-mod" :dir :system))
84
(defthm genrandom-natural
85
(natp (car (genrandom max rand)))
86
:rule-classes :type-prescription)
88
(defthm genrandom-minimum
89
(<= 0 (car (genrandom max rand)))
90
:rule-classes :linear)
92
(defthm genrandom-maximum
94
(<= (car (genrandom max rand)) (1- max)))
95
:rule-classes :linear))
97
(in-theory (disable genrandom))
101
;=====================================================================;
103
; Begin additions by Peter Dillinger & Dimitris Vardoulakis
104
; Last modified 7 February 2008
106
;=====================================================================;
108
(defun random-boolean (rand)
109
(declare (xargs :stobjs (rand)))
112
(mv (= 1 num) rand)))
114
(defthm random-boolean-type
115
(booleanp (car (random-boolean r)))
116
:rule-classes :type-prescription)
118
(in-theory (disable random-boolean))
120
;generate naturals according to a pseudo-geometric distribution
121
(defun random-natural-basemax (base maxdigits rand)
122
(declare (xargs :stobjs (rand)
123
:guard (and (posp base)
125
(if (or (zp maxdigits) (zp base))
128
(genrandom (* 2 base) rand)
131
(random-natural-basemax base (1- maxdigits) rand)
132
(mv (+ (- v base) (* base (nfix v2))) rand))
135
(defun random-natural (rand)
136
(declare (xargs :stobjs (rand)))
137
(random-natural-basemax 10 6 rand))
139
(defun random-length (rand)
140
(declare (xargs :stobjs (rand)))
141
(random-natural-basemax 4 2 rand))
143
(defthm random-natural-basemax-type
144
(natp (car (random-natural-basemax b d r)))
145
:rule-classes :type-prescription)
147
(defthm random-natural-type
148
(natp (car (random-natural r)))
149
:rule-classes :type-prescription)
151
(defthm random-length-type
152
(natp (car (random-length r)))
153
:rule-classes :type-prescription)
155
(in-theory (disable random-natural-basemax
162
; generate indices uniformly within a specified length
163
(defun random-index (len rand)
164
(declare (xargs :stobjs (rand)
166
(genrandom len rand))
169
;generate integers according to a pseudo-geometric distribution
170
(defun random-integer (rand)
171
(declare (xargs :stobjs (rand)))
173
(random-boolean rand)
175
(random-natural rand)
176
(mv (if sign nat (- nat))
179
(defthm random-integer-type
180
(integerp (car (random-integer r)))
181
:rule-classes :type-prescription)
183
(in-theory (disable random-integer))
186
;or generate integers with a uniform distribution, between i & j (incl.)
187
(defun random-int-between (i j rand)
188
(declare (xargs :stobjs (rand)
189
:guard (and (integerp i)
191
(let ((low (ifix (min i j)))
192
(high (ifix (max i j))))
195
(genrandom (1+ (- high low)) rand)
196
(mv (+ low num) rand))))
198
(defthm random-int-between-type
199
(integerp (car (random-int-between i j r)))
200
:rule-classes :type-prescription)
202
(defthm random-int-between-lower
203
(implies (and (integerp i)
206
(<= i (car (random-int-between i j r))))
207
:rule-classes :linear)
209
(defthm random-int-between-upper
210
(implies (and (integerp i)
213
(>= j (car (random-int-between i j r))))
214
:rule-classes :linear)
216
(in-theory (disable random-int-between))
219
; generate a signed rational with pseudo-geometric numerator & denominator
220
(defun random-rational (rand)
221
(declare (xargs :stobjs (rand)))
223
(random-integer rand)
224
(mv-let (denom-1 rand)
225
(random-natural rand)
230
(defthm random-rational-type
231
(rationalp (car (random-rational r)))
232
:rule-classes :type-prescription)
234
(in-theory (disable random-rational))
237
; pseudo-uniform rational between 0 and 1 (inclusive)
238
(defun random-probability (rand)
239
(declare (xargs :stobjs (rand)))
241
(random-natural rand)
243
(random-natural rand)
244
(let ((denom (* (1+ a) (1+ b))))
246
(genrandom (1+ denom) rand)
247
(mv (/ numer denom) rand))))))
249
(defthm random-probability-type
250
(rationalp (car (random-probability r)))
251
:rule-classes :type-prescription)
253
(defthm random-probability>=0
254
(<= 0 (car (random-probability r)))
255
:rule-classes (:linear :type-prescription))
258
(local (include-book "arithmetic/rationals" :dir :system))
262
(defthm numerator<=denominator-implies-<=1
263
(implies (and (natp n)
270
(defthm random-probability<=1
271
(<= (car (random-probability r)) 1)
272
:rule-classes :linear))
274
(in-theory (disable random-probability))
277
;generate a random rational whose absolute value is lte x
278
(defun random-rational-between (x y rand)
279
(declare (xargs :stobjs (rand)
280
:guard (and (rationalp x)
283
(random-probability rand)
287
(+ y (* p (- x y)))))
290
(defthm random-rational-between-type
291
(rationalp (car (random-rational-between i j r)))
292
:rule-classes :type-prescription)
295
(local (include-book "arithmetic-3/top" :dir :system))
297
(defthm random-rational-between-lower
298
(implies (and (rationalp i)
301
(<= i (car (random-rational-between i j r))))
302
:rule-classes :linear)
304
(local (defthm random-rational-between-upper-lemma2
305
(implies (and (rationalp i)
316
(defthm random-rational-between-upper-lemma
317
(implies (and (rationalp i)
325
:hints (("Goal" :use (:instance
326
random-rational-between-upper-lemma2
329
(defthm random-rational-between-upper
330
(implies (and (rationalp i)
333
(<= (car (random-rational-between i j r)) j))
334
:rule-classes :linear))
336
(in-theory (disable random-rational-between))
340
;generate non-zero integers according to a pseudo-geometric distribution
341
(defun random-nonzero-integer (rand)
342
(declare (xargs :stobjs (rand)))
344
(random-boolean rand)
346
(random-natural rand)
347
(mv (if sign (+ 1 nat) (- -1 nat))
350
(defthm random-nonzero-integer-type
351
(and (integerp (car (random-nonzero-integer r)))
352
(not (equal (car (random-nonzero-integer r)) 0)))
353
:rule-classes :type-prescription)
355
(in-theory (disable random-nonzero-integer))
360
; generate a signed rational with pseudo-geometric numerator & denominator
361
(defun random-nonzero-rational (rand)
362
(declare (xargs :stobjs (rand)))
364
(random-nonzero-integer rand)
365
(mv-let (denom-1 rand)
366
(random-natural rand)
371
(defthm random-nonzero-rational-type
372
(and (rationalp (car (random-nonzero-rational r)))
373
(not (equal (car (random-nonzero-rational r)) 0)))
374
:rule-classes :type-prescription)
376
(in-theory (disable random-nonzero-rational))
379
; generate a (strictly) complex number from rationals
380
(defun random-complex (rand)
381
(declare (xargs :stobjs (rand)))
383
(random-rational rand)
385
(random-nonzero-rational rand)
386
(mv (complex rpart ipart) rand))))
388
(defthm random-complex-type
389
(complex-rationalp (car (random-complex r)))
390
:rule-classes :type-prescription)
392
(in-theory (disable random-complex))
397
(defmacro random-element (lst rand-rand)
398
`(mv-let (random-element-macro-idx rand)
399
(random-index (length ,lst) ,rand-rand)
400
(mv (nth random-element-macro-idx ,lst) rand)))
402
(defmacro random-element-len (lst len rand-rand)
403
`(if (mbt (<= ,len (len ,lst)))
404
(mv-let (random-element-macro-idx rand)
405
(random-index ,len ,rand-rand)
406
(mv (nth random-element-macro-idx ,lst) rand))
407
(mv (car ,lst) rand)))
411
(defconst *standard-chars-len*
412
(len *standard-chars*))
414
(defun random-char (rand)
415
(declare (xargs :stobjs (rand)))
416
(random-element-len *standard-chars*
420
(defthm random-char-type
421
(characterp (car (random-char r)))
422
:rule-classes :type-prescription)
424
(in-theory (disable random-char))
427
(defun random-char-list-len (len rand)
428
(declare (xargs :stobjs (rand)
435
(random-char-list-len (1- len) rand)
436
(mv (cons c lst) rand)))))
438
(defthm random-char-list-len-type
439
(character-listp (car (random-char-list-len l r)))
440
:rule-classes :type-prescription)
442
(in-theory (disable random-char-list-len))
445
(defun random-string-len (len rand)
446
(declare (xargs :stobjs (rand)
449
(random-char-list-len len rand)
450
(mv (coerce lst 'string) rand)))
452
(defthm random-string-len-type
453
(stringp (car (random-string-len l r)))
454
:rule-classes :type-prescription)
456
(in-theory (disable random-string-len))
459
;generate a random string of pseudogeometric length
460
(defun random-string (rand)
461
(declare (xargs :stobjs (rand)))
464
(random-string-len len rand)))
466
(defthm random-string-type
467
(stringp (car (random-string r)))
468
:rule-classes :type-prescription)
470
(in-theory (disable random-string))
473
;generate a random symbol of pseudogeometric length
474
(defun random-symbol-same-package (sym rand)
475
(declare (xargs :stobjs (rand)
476
:guard (symbolp sym)))
479
(mv (intern-in-package-of-symbol str sym) rand)))
481
(defthm random-symbol-same-package-type
482
(implies (symbolp sym)
483
(symbolp (car (random-symbol-same-package sym r))))
484
:rule-classes :type-prescription)
486
(defthmd random-symbol-same-package_expand-package
487
(implies (symbolp sym)
488
(equal (car (random-symbol-same-package sym r))
489
(intern-in-package-of-symbol
490
(symbol-name (car (random-symbol-same-package sym r)))
493
(defthmd random-symbol-same-package_suck-package
494
(implies (symbolp sym)
495
(equal (intern-in-package-of-symbol
496
(symbol-name (car (random-symbol-same-package sym r)))
498
(car (random-symbol-same-package sym r)))))
500
(in-theory (disable random-symbol-same-package))
503
(defun random-keyword (rand)
504
(declare (xargs :stobjs (rand)))
505
(random-symbol-same-package :acl2-pkg-witness rand))
507
(defthm random-keyword-type
508
(symbolp (car (random-keyword r)))
509
:hints (("Goal" :use (:instance random-symbol-same-package_expand-package
510
(sym :acl2-pkg-witness))))
511
:rule-classes :type-prescription)
516
; [Jared] Previously keyword-package-intern had the following hints:
518
;; :hints (("Goal" :use (:instance keyword-package (x str) (y key))))))
520
; But in my copy of ACL2 the keyword-package axiom doesn't seem to have any
521
; variables, so I'm not sure what's going on. I've fixed this up to work in
522
; my copy, maybe this is right?
525
(equal (member-symbol-name str nil)
527
:hints(("Goal" :in-theory (enable member-symbol-name)))))
529
(local (defthm keyword-package-intern
530
(implies (and (stringp str)
532
(equal (symbol-package-name
533
(intern-in-package-of-symbol str key))
536
:in-theory (disable keyword-package
537
SYMBOL-PACKAGE-NAME-INTERN-IN-PACKAGE-OF-SYMBOL)
538
:use ((:instance keyword-package)
539
(:instance SYMBOL-PACKAGE-NAME-INTERN-IN-PACKAGE-OF-SYMBOL
544
(defthm random-keyword-keyword
545
(equal (symbol-package-name (car (random-keyword r)))
547
:hints (("Goal" :use (:instance random-symbol-same-package_expand-package
548
(sym :acl2-pkg-witness))))))
550
(in-theory (disable random-keyword))
557
(defun random-number (rand)
558
(declare (xargs :stobjs (rand)))
560
(random-index 4 rand)
562
(0 (random-natural rand))
563
(1 (random-integer rand))
564
(2 (random-rational rand))
565
(t (random-complex rand)))))
567
(defthm random-number-type
568
(acl2-numberp (car (random-number r)))
569
:rule-classes :type-prescription)
571
(in-theory (disable random-number))
574
(defconst *acl2-exports-len*
575
(len *acl2-exports*))
576
(defconst *common-lisp-symbols-from-main-lisp-package-len*
577
(len *common-lisp-symbols-from-main-lisp-package*))
580
:off (prove observation event)
581
(defun random-symbol (rand)
582
(declare (xargs :stobjs (rand)))
584
(random-index 8 rand)
587
(0 (random-boolean rand))
588
(1 (random-element-len
592
(2 (random-element-len
593
*common-lisp-symbols-from-main-lisp-package*
594
*common-lisp-symbols-from-main-lisp-package-len*
596
(3 (random-keyword rand))
597
(4 (random-symbol-same-package 'acl2::acl2-pkg-witness rand))
598
(5 (random-symbol-same-package 'acl2-user::acl2-pkg-witness rand))
599
(6 (random-symbol-same-package 'common-lisp::acl2-pkg-witness rand))
600
(t (random-symbol-same-package 'acl2-pc::acl2-pkg-witness rand))))))
602
(local (defthm nth-symbol-list
603
(implies (force (symbol-listp l))
605
:rule-classes :type-prescription))
608
:off (prove observation event)
609
(defthm random-symbol-type
610
(symbolp (car (random-symbol r)))
611
:rule-classes :type-prescription))
613
(in-theory (disable random-symbol))
618
:off (prove observation event)
619
(defun random-acl2-symbol (rand)
620
(declare (xargs :stobjs (rand)))
622
(random-index 5 rand) ; skew toward generated symbols
625
(0 (random-boolean rand))
626
(1 (random-element-len
630
(2 (random-element-len
631
*common-lisp-symbols-from-main-lisp-package*
632
*common-lisp-symbols-from-main-lisp-package-len*
634
(t (random-symbol-same-package 'acl2::acl2-pkg-witness rand))))))
637
:off (prove observation event)
638
(defthm random-acl2-symbol-type
639
(symbolp (car (random-acl2-symbol r)))
640
:hints (("Goal" :use (:instance random-symbol-same-package_expand-package
641
(sym 'acl2::acl2-pkg-witness))))
642
:rule-classes :type-prescription))
644
(in-theory (disable random-acl2-symbol))
648
(defun random-atom (rand)
649
(declare (xargs :stobjs (rand)))
651
(random-index 4 rand)
654
(0 (random-number rand))
655
(1 (random-char rand))
656
(2 (random-symbol rand))
657
(t (random-string rand)))))
659
(defthm random-atom-type
660
(atom (car (random-atom r)))
661
:rule-classes :type-prescription)
663
(in-theory (disable random-atom))#|ACL2s-ToDo-Line|#
674
(defconst *atomic-value-types*
691
(defun random-value (spec rand)
692
(declare (xargs :stobjs (rand)))
694
(if (symbolp (car spec))
697
(if (and (consp (cdr spec))
699
(mv (cadr spec) rand)
700
(mv (er hard? 'random-value "Invalid quoted value: ~x0" spec)
703
(if (and (consp (cdr spec))
706
(mv-let (carval rand)
707
(random-value (cadr spec) rand)
708
(mv-let (cdrval rand)
709
(random-value (caddr spec) rand)
710
(mv (cons carval cdrval) rand)))
711
(mv (er hard? 'random-value "Cons should take two parameters, unlike in ~x0" spec)
b'\\ No newline at end of file'