[racket] Confusion with circular structs
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
>