<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">On 2015-03-24 15:16, Jesper Louis
Andersen wrote:<br>
</div>
<blockquote
cite="mid:CAGrdgiWweNKC=6tykqRc=gHaCtZjAVkdreEEAGU2utAgOJ1vhg@mail.gmail.com"
type="cite">
<div dir="ltr">Hi OTP team (and other readers),</div>
</blockquote>
<br>
Hi Jesper!<br>
<br>
Awesome! Thank you for reporting this and thank you for your
quickcheck model. =D<br>
<br>
term_to_binary binary_to_term problem has already been spotted and a
fix is on it's way.<br>
<br>
We will look into the others now.<br>
<br>
// Björn-Egil<br>
<br>
<blockquote
cite="mid:CAGrdgiWweNKC=6tykqRc=gHaCtZjAVkdreEEAGU2utAgOJ1vhg@mail.gmail.com"
type="cite">
<div dir="ltr">
<div><br>
</div>
<div>Over the weekend, I've been building up a QuickCheck model
of Erlang/OTP maps(). This is to be able to properly test the
HAMT maps of the up-and-coming 18.0 release for correctness,
but I'm testing on 17.4.1 as well. The following problem
occurs for release 17.4.1. (for the curious, 18.0 currently
segfaults on these tests):</div>
<div><br>
</div>
<div>
<div>Erlang/OTP 17 [erts-6.3.1] [source] [64-bit] [smp:8:8]
[ds:8:8:10] [async-threads:10] [kernel-poll:false]</div>
<div><br>
</div>
<div>Eshell V6.3.1 (abort with ^G)</div>
<div>1> Map = #{0 => 0,2147483648 => 0}.</div>
<div>#{0 => 0,2147483648 => 0}</div>
<div>2> Bin = term_to_binary(M).</div>
<div>* 1: variable 'M' is unbound</div>
<div>3> Bin = term_to_binary(Map).</div>
<div><<131,116,0,0,0,2,97,0,97,0,110,4,0,0,0,0,128,97,0>></div>
<div>4> Map2 = binary_to_term(Bin).</div>
<div>#{2147483648 => 0,0 => 0}</div>
<div>5> Map =:= Map2.</div>
<div>false</div>
<div><br>
</div>
<div>(copied verbatim, including my error in 2>)</div>
<div><br>
</div>
<div>The problem is that if I convert the map to a binary and
then back again, the two maps are not equal. Furthermore,
they print differently:</div>
<div><br>
</div>
<div>
<div>6> Map.</div>
<div>#{0 => 0,2147483648 => 0}</div>
<div>7> Map2.</div>
<div>#{2147483648 => 0,0 => 0}</div>
<div>8> </div>
</div>
<div><br>
</div>
<div>The value 2147483648 seems important and it is 2^31.
However, the problem also occurs at 2^31 + 1. Only testing
with "small" integers poses no problem at all. I have yet to
test against floating point numbers and this requires some
additional attention to detail as they have fun equality
rules :)</div>
<div><br>
</div>
<div>A second problem occurs in merges, which may be related
or may not be related. In the second problem, we are merging
maps</div>
<div><br>
</div>
<div>
<div>[#{-2147483649 => 0,</div>
<div> 0 => 0,</div>
<div> 97 => 0,</div>
<div> false => 0,</div>
<div> flower => 0,</div>
<div> #Fun<eqc_gen.133.121384563> => 0,</div>
<div> #Fun<eqc_gen.133.121384563> => 0,</div>
<div> <<>> => 0},</div>
<div> #{0 => 1}]</div>
</div>
<div><br>
</div>
<div>where the #Fun's are generated functions of 0 and 2
parameters respectively. Lets see how to create such a map
(one might note that direct creation through #{ ... } syntax
would make the keys which are functions illegal, but I am an
experiened Erlang programmer and have a way around such
petty limitations :P)</div>
<div><br>
</div>
<div>
<div>9> F1 = fun(_, _) -> 0 end,</div>
<div>9> F2 = fun(_, _) -> 1 end.</div>
</div>
<div><br>
</div>
<div>This defines two functions:</div>
<div><br>
</div>
<div>
<div>11> maps:from_list(</div>
<div>11> [{-2147483649, 0},</div>
<div>11> {0,0}, {97, 0}, {false, 0}, {flower, 0}, {F1,
0}, {F2, 0}, {<<>>, 0}]).</div>
<div>#{-2147483649 => 0,</div>
<div> 0 => 0,</div>
<div> 97 => 0,</div>
<div> false => 0,</div>
<div> flower => 0,</div>
<div> #Fun<erl_eval.12.90072148> => 0,</div>
<div> #Fun<erl_eval.12.90072148> => 0,</div>
<div> <<>> => 0}</div>
</div>
<div><br>
</div>
<div>Remarkably, this is well-defined, now lets merge:</div>
<div><br>
</div>
<div>
<div>12> maps:merge(v(11), #{0 => 1}).
</div>
<div>#{0 => 1,</div>
<div> -2147483649 => 0,</div>
<div> 0 => 0,</div>
<div> 97 => 0,</div>
<div> false => 0,</div>
<div> flower => 0,</div>
<div> #Fun<erl_eval.12.90072148> => 0,</div>
<div> #Fun<erl_eval.12.90072148> => 0,</div>
<div> <<>> => 0}</div>
<div>13> </div>
</div>
<div><br>
</div>
<div>The resulting map now has to '0' keys! Rejoice!</div>
<div><br>
</div>
<div>The model I am using is the following:</div>
<div><br>
</div>
<div><a moz-do-not-send="true"
href="https://github.com/jlouis/maps_eqc/tree/ac7748ce81781ae6c1ad7b4ed07ca5cd935c125d">https://github.com/jlouis/maps_eqc/tree/ac7748ce81781ae6c1ad7b4ed07ca5cd935c125d</a><br>
</div>
<div><br>
</div>
<div>(maps_iso_eqc are simple stateless tests, whereas
maps_eqc is a more complicated stateful test which also
verifies properties about copying maps between processes and
that maps are persistent data structures).</div>
<div><br>
</div>
<div>To run:</div>
<div><br>
</div>
<div>make:all([load]).</div>
<div>eqc:module({testing_budget, 20}, maps_iso_eqc).</div>
<div><br>
</div>
<div>Two test runs of mine:</div>
<div><br>
</div>
<div><a moz-do-not-send="true"
href="https://gist.github.com/jlouis/39de114e0a447af983a5">https://gist.github.com/jlouis/39de114e0a447af983a5</a><br>
</div>
<div><br>
</div>
<div>Note the latter merge test which managed to shrink over
1200 times!</div>
<div><br>
</div>
<div><br>
</div>
-- <br>
<div class="gmail_signature">J.</div>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
erlang-bugs mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-bugs">http://erlang.org/mailman/listinfo/erlang-bugs</a>
</pre>
</blockquote>
<br>
</body>
</html>