<div dir="ltr"><div><div>Hi Nick!<br><br></div>Interesting observation. I tried the same thing with immutable hash tables in place of sets (just mapping each element to #t), and got the same results. So I don't think the set implementation is the culprit here. I suspect the built-in equality and/or hash functions for either immutable hash tables, or transparent structs, or both, doesn't properly handle circular values.<br>
<br></div>Carl Eastlund<div><div class="gmail_extra">
<br><div class="gmail_quote">On Fri, Jul 26, 2013 at 5:25 PM, Nicholas Labich <span dir="ltr"><<a href="mailto:labichn@gmail.com" target="_blank">labichn@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">I'm running into what I find to be surprising behavior with circular structures (vertices of a simple graph).<div><br></div><div>Graphically (see code below to reproduce):</div><div>0 --> 1 ;; no problem</div>
<div>2-+ ;; also no problem<br><div> ^-+</div><div><br></div><div>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.</div>
</div><div><br></div><div>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.</div>
<div><br></div><div>Any insight would be much appreciated.</div><div><br></div><div>Nick</div><div><br></div><div><div>Welcome to Racket v5.90.0.2.</div><div>> (struct vertex (value preds succs) #:mutable #:transparent)</div>
<div>> (define v0 (vertex 0 (set) (set)))</div><div>> (define v1 (vertex 1 (set) (set)))</div><div>> (set-vertex-succs! v0 (set v1))</div><div>> (set-vertex-preds! v1 (set v0)) ;; 0 --> 1</div><div>> (equal? v0 (set-first (vertex-preds v1)))</div>
<div>#t</div><div>> (define v2 (vertex 2 (set) (set)))</div><div>> (set-vertex-preds! v2 (set v2)) ;; 2--+</div><div>> (set-vertex-succs! v2 (set v2)) ;; ^--+</div><div>> v2</div><div>#0=(vertex 2 (set #0#) (set #0#))</div>
<div>;; try to add the already existing set</div>
<div>> (set-vertex-succs! v0 (set-add (vertex-succs v0) v2)) ;; loops and loops</div><div> C-c C-c^Cuser break</div><div> context...:</div><div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc</div>
<div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc</div><div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc</div><div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc...</div>
<div>;; try to make a new set instead</div><div>> (set-vertex-succs! v0 (set v1 v2))</div><div> C-c C-c^Cuser break</div><div> context...:</div><div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc</div>
<div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc</div>
<div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc</div><div> .../racket/collects/racket/private/set-types.rkt:447:3: hash-proc...</div><div> </div><div>> (shared ([v0 (vertex 0 (set) succs0)]</div>
<div> [v1 (vertex 1 preds1 (set))]</div><div> [v2 (vertex 2 preds2 succs2)]</div> [succs0 (set v1 v2)]<div> [preds1 (set v0)]</div><div> [preds2 (set v0 v2)]</div><div> [succs2 (set v2)])</div>
<div> (values v0 v1 v2))</div><div>(vertex 0 (set) (set #0=(vertex 2 (set #0#) (set #0#))))</div><div>(vertex 1 (set (vertex 0 (set) (set #0=(vertex 2 (set #0#) (set #0#))))) (set))</div><div>#0=(vertex 2 (set #0#) (set #0#))</div>
<div>;; I must be using `shared' incorrectly...</div></div></div>
<br>____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div></div></div>