#617 random state not maintained correctly

open
Bruno Haible
clisp (525)
5
2011-10-23
2011-10-23
Robert Dodier
No

Clisp doesn't seem to maintain the random state correctly.

Here's an example from the CLHS.
See: http://www.lispworks.com/documentation/HyperSpec/Body/v_rnd_st.htm#STrandom-stateST
I have adapted it by putting in the required argument for RANDOM.

(setq snap-shot (make-random-state))
;; The series from any given point is random,
;; but if you backtrack to that point, you get the same series.
(list (loop for i from 1 to 10 collect (random 100))
(let ((*random-state* snap-shot))
(loop for i from 1 to 10 collect (random 100)))
(loop for i from 1 to 10 collect (random 100))
(let ((*random-state* snap-shot))
(loop for i from 1 to 10 collect (random 100))))

Expected output: first two lists are the same, second two lists are the same.
That is the behavior shown in the CLHS example.
(I don't see any reason to believe the output displayed in the CLHS is inconsistent with the CLHS's descriptions of *RANDOM-STATE* and MAKE-RANDOM-STATE.)

Actual output:

((61 35 13 7 80 62 20 2 22 86) (8 6 74 57 36 32 39 71 92 14) (65 29 40 51 38 72 16 75 74 9) (70 65 29 40 51 38 72 16 75 74))

I tried the same example w/ ECL and with SBCL, and in both cases they show the expected behavior.

$ uname -a
Linux robert-laptop 2.6.24.6 #1 SMP Sat Jan 1 00:37:06 MST 2011 i686 GNU/Linux

$ clisp --version
GNU CLISP 2.49 (2010-07-07) (built 3517447027) (memory 3517449770)
Software: GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
gcc -g -O2 -W -Wswitch -Wcomment -Wpointer-arith -Wimplicit -Wreturn-type -Wmissing-declarations -Wno-sign-compare -Wno-format-nonliteral -O2 -fexpensive-optimizations -falign-functions=4 -DENABLE_UNICODE -DDYNAMIC_MODULES -I. -lncurses -ldl -L/home/robert/tmp/clisp-2.49/tools/i686-pc-linux-gnu/lib -lsigsegv -lc libgnu_cl.a
SAFETY=0 HEAPCODES LINUX_NOEXEC_HEAPCODES GENERATIONAL_GC SPVW_BLOCKS SPVW_MIXED TRIVIALMAP_MEMORY
libsigsegv 2.8
Features:
(REGEXP SYSCALLS I18N LOOP COMPILER CLOS MOP CLISP ANSI-CL COMMON-LISP LISP=CL INTERPRETER SOCKETS GENERIC-STREAMS
LOGICAL-PATHNAMES SCREEN GETTEXT UNICODE BASE-CHAR=CHARACTER PC386 UNIX)
C Modules: (clisp i18n syscalls regexp)
Installation directory: /usr/local/lib/clisp-2.49/
User language: ENGLISH
Machine: I686 (I686) robert-laptop [127.0.0.1]

Discussion

  • Works for me... (a x86_64 linux).

    C/USER[11]> (lisp-implementation-version)
    "2.49 (2010-07-07) (built 3499302370) (memory 3499302538)"
    C/USER[12]> (setq snap-shot (make-random-state))

    #S(RANDOM-STATE #*0100001010101110101011111110101110000000111111000110100010101101)
    C/USER[13]> ;; The series from any given point is random,
    ;; but if you backtrack to that point, you get the same series.
    (list (loop for i from 1 to 10 collect (random 100))
    (let ((*random-state* snap-shot))
    (loop for i from 1 to 10 collect (random 100)))
    (loop for i from 1 to 10 collect (random 100))
    (let ((*random-state* snap-shot))
    (loop for i from 1 to 10 collect (random 100))))
    ((74 0 50 49 43 98 99 84 72 99) (74 0 50 49 43 98 99 84 72 99) (93 64 22 39 34 85 20 0 9 60) (93 64 22 39 34 85 20 0 9 60))

     
  • Bruno Haible
    Bruno Haible
    2011-10-24

    It's a regression: Your test case worked fine in version 2.34 and was broken in version 2.35 and newer.