<div dir="ltr">Types need to collapse to a higher level of abstraction at some point or the fixpoint iteration of the analysis might not terminate. Note that there are an infinite number of ranges.<div><br></div><div>In order for the analysis to keep track of when to collapse the ranges instead of expanding them, the structure of the analysis would have to take into account some kind of history of range expansion (e.g., expand the range X number of times, then collapse).<br><div><br></div><div>I spent quite some time on trying to use the ranges in Dialyzer in a better way, but as I recall it, the non-termination was the reason for collapsing early.</div><div><br></div><div>We used a more precise range analysis in the HiPE compiler for optimization, and it is certainly possible to get good results for it, but it is not as straightforward as it might seem.</div><div><br></div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">2017-11-01 16:03 GMT+01:00 zxq9 <span dir="ltr"><<a href="mailto:zxq9@zxq9.com" target="_blank">zxq9@zxq9.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 2017年11月01日 水曜日 07:27:35 Fred Hebert wrote:<br>
> On 11/01, zxq9 wrote:<br>
> >What is going on here? Is this a new thing with R20's Dialyzer, or have<br>
> >I just never noticed these multi-byte leaps in value range resolution?<br>
><br>
> You never noticed it. Dialyzer kind of keeps the right to expand ranges<br>
> arbitrarily. You can see in the source code that anything set of types<br>
> above 12 gets merged into one:<br>
> <a href="https://github.com/erlang/otp/blob/fe1df7fc6bf050cb6c9bbd99eb9393c426b62f67/lib/hipe/cerl/erl_types.erl#L1997-L2011" rel="noreferrer" target="_blank">https://github.com/erlang/otp/<wbr>blob/<wbr>fe1df7fc6bf050cb6c9bbd99eb9393<wbr>c426b62f67/lib/hipe/cerl/erl_<wbr>types.erl#L1997-L2011</a><br>
><br>
> The same kind of stuff also happens with atoms or even types in general<br>
> (<a href="https://github.com/erlang/otp/blob/fe1df7fc6bf050cb6c9bbd99eb9393c426b62f67/lib/hipe/cerl/erl_types.erl#L4860-L4866" rel="noreferrer" target="_blank">https://github.com/erlang/<wbr>otp/blob/<wbr>fe1df7fc6bf050cb6c9bbd99eb9393<wbr>c426b62f67/lib/hipe/cerl/erl_<wbr>types.erl#L4860-L4866</a>)<br>
> which can be merged into the any() type.<br>
><br>
> It's frankly a bit of a bummer but I figure it's something Dialyzer does<br>
> to be less memory-hungry, at the cost of accuracy.<br>
<br>
</span>Hah! Wow. That's a pretty darn steep range curve on numerics!<br>
<br>
Incidentally, also one of the only apt uses of an `if` I've seen in a while.<br>
<br>
I've stayed away from Dialyzer internals for a reason (I get sort of obsessed about such things) but I wonder if it wouldn't be possible to establish numeric ranges as test ranges instead of enumerations?<br>
<br>
It seems like this is the case, actually, but obviously I am missing something if they can't set ?int_range(X, Y) directly and must instead only ever set either ?int_range(1, ?MAX_BYTE) or ?int_range(1, ?MAX_CHAR).<br>
<a href="https://github.com/erlang/otp/blob/fe1df7fc6bf050cb6c9bbd99eb9393c426b62f67/lib/hipe/cerl/erl_types.erl#L342" rel="noreferrer" target="_blank">https://github.com/erlang/otp/<wbr>blob/<wbr>fe1df7fc6bf050cb6c9bbd99eb9393<wbr>c426b62f67/lib/hipe/cerl/erl_<wbr>types.erl#L342</a><br>
<br>
The only place this approach seems to hold is called t_from_range_unsafe/2.<br>
<a href="https://github.com/erlang/otp/blob/fe1df7fc6bf050cb6c9bbd99eb9393c426b62f67/lib/hipe/cerl/erl_types.erl#L2018" rel="noreferrer" target="_blank">https://github.com/erlang/otp/<wbr>blob/<wbr>fe1df7fc6bf050cb6c9bbd99eb9393<wbr>c426b62f67/lib/hipe/cerl/erl_<wbr>types.erl#L2018</a><br>
I assume "unsafe" for a reason, though the expected tests actually do exist.<br>
<a href="https://github.com/erlang/otp/blob/fe1df7fc6bf050cb6c9bbd99eb9393c426b62f67/lib/hipe/cerl/erl_types.erl#L2101" rel="noreferrer" target="_blank">https://github.com/erlang/otp/<wbr>blob/<wbr>fe1df7fc6bf050cb6c9bbd99eb9393<wbr>c426b62f67/lib/hipe/cerl/erl_<wbr>types.erl#L2101</a><br>
<br>
Hm. So I'm just puzzled at the reasoning behind the need to enumerate ranges, and then the presence code that doesn't need ranges to be enumerated. Even more to the point, why not a list of arbitrary ranges? Too slow? Hard to imagine speed is the primary concern. Perhaps simply some work that never quite got polished off because, well, Dialyzer is already super useful in 90% of cases?<br>
<br>
Anyway, thanks for pointing that out. Quite interesting.<br>
<br>
-Craig<br>
<div class="HOEnZb"><div class="h5">______________________________<wbr>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-questions</a><br>
</div></div></blockquote></div><br></div>