It's probably because you're putting mutable data into an equal (hash-based) set, then mutating the data. That changes the keys, which causes problems for the underlying hash table.

If you change each occurrence of 'set' to 'seteq' below, the program should run.

Ryan


On 07/26/2013 05:25 PM, Nicholas Labich wrote:
I'm running into what I find to be surprising behavior with circular
structures (vertices of a simple graph).

Graphically (see code below to reproduce):
0 --> 1 ;; no problem
2-+      ;; also no problem
  ^-+

But when I try to add an edge between 0 and 2, I hit an infinite loop at
line 88 of racket/set.rkt (in 5.3.3) or line 447 of
racket/private/set-types.rkt (in the latest 5.90.0.2), both of which are
the hash-proc for set's gen:equal+hash.

Is this the expected behavior (after all, OCaml makes no guarantee of
termination for (=) on circular data)? I'm surprised that the self-edge
on 2 doesn't result in the same. I've also tried to reproduce the same
using `shared', but I'm assuming I still misunderstand its functionality
because the result is not quite what I expect it to be.

Any insight would be much appreciated.

Nick

Welcome to Racket v5.90.0.2.
 > (struct vertex (value preds succs) #:mutable #:transparent)
 > (define v0 (vertex 0 (set) (set)))
 > (define v1 (vertex 1 (set) (set)))
 > (set-vertex-succs! v0 (set v1))
 > (set-vertex-preds! v1 (set v0)) ;; 0 --> 1
 > (equal? v0 (set-first (vertex-preds v1)))
#t
 > (define v2 (vertex 2 (set) (set)))
 > (set-vertex-preds! v2 (set v2)) ;; 2--+
 > (set-vertex-succs! v2 (set v2)) ;; ^--+
 > v2
#0=(vertex 2 (set #0#) (set #0#))
;; try to add the already existing set
 > (set-vertex-succs! v0 (set-add (vertex-succs v0) v2)) ;; loops and loops
   C-c C-c^Cuser break
   context...:
  .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
  .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
  .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
  .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc...
;; try to make a new set instead
 > (set-vertex-succs! v0 (set v1 v2))
   C-c C-c^Cuser break
   context...:
   .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
   .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
   .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc
   .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc...
 > (shared ([v0 (vertex 0 (set) succs0)]
            [v1 (vertex 1 preds1 (set))]
            [v2 (vertex 2 preds2 succs2)]
            [succs0 (set v1 v2)]
            [preds1 (set v0)]
            [preds2 (set v0 v2)]
            [succs2 (set v2)])
     (values v0 v1 v2))
(vertex 0 (set) (set #0=(vertex 2 (set #0#) (set #0#))))
(vertex 1 (set (vertex 0 (set) (set #0=(vertex 2 (set #0#) (set #0#)))))
(set))
#0=(vertex 2 (set #0#) (set #0#))
;; I must be using `shared' incorrectly...


____________________
   Racket Users list:
   http://lists.racket-lang.org/users


____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to