[racket] Confusion with circular structs

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Fri Jul 26 17:49:10 EDT 2013

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
>


Posted on the users mailing list.