Improve choose/2 and int/2 generators.

API level changes:

* Previously `choose/2` shrunk to the lowest limit, it now shrink to
lowest absolute value. This behavior is consistent with QuickCheck and Proper.

* Previously `int/2` ignored the bounds and always shrunk to 0. The new
behavior is equivalent to the `choose/2` function.

Implementation details:

Previously `int/2` function always decremented by 1 when shrinking. That works
for small integers, but is very inefficient and slow for large integer
boundaries. `choose/2` on the other hand always halved its value, however it
might skip interesting values around the shrink target or the Min / Max
boundaries.

The improvement is to get the best for both cases. If the current value is
close to the shrinking target then decrement by 1 is used, otherwise
halving is used. The transition is done probabilistically based on an
exponential function. The closer to the interesting boundary the value is,
there is an exponentially higher chance of decrement being used.

Fixes #66
diff --git a/THANKS b/THANKS
index c5e9548..8d28b98 100644
--- a/THANKS
+++ b/THANKS
@@ -17,3 +17,4 @@
 Zachary Kessin
 Krzysztof Jurewicz
 Harlan Lieberman-Berg
+Nick Vatamaniuc
diff --git a/src/triq_dom.erl b/src/triq_dom.erl
index fb853c3..6d7a1e7 100644
--- a/src/triq_dom.erl
+++ b/src/triq_dom.erl
@@ -105,7 +105,7 @@
 -record(noshrink, {dom}).
 -record(suchthat,{dom,pred}).
 -record(bound_domain,{dom1,val1,dom2,fun2,size}).
--record(choose,{min,max}).
+-record(choose,{min,max,shrinkto}).
 -record(elements,{elems,size,picked=none}).
 -record(seal,{dom,seed}).
 -record(unicode_binary, {size, encoding = utf8}).
@@ -597,19 +597,10 @@
          }.
 
 int(Max) ->
-    int(0, Max).
+    choose(0, Max).
 
 int(Min, Max) ->
-    Diff = Max - Min,
-    #?DOM{kind=int,
-          shrink=fun(Dom,Val) when Val>0 -> {Dom,Val-1};
-                    (Dom,Val) when Val<0 -> {Dom,Val+1};
-                    (Dom,0) -> {Dom,0}
-                 end,
-          pick=fun(Dom,_SampleSize) ->
-                       {Dom, triq_rnd:uniform(Diff) + Min}
-               end
-         }.
+    choose(Min, Max).
 
 
 -spec byte() -> domrec(integer()).
@@ -1185,7 +1176,12 @@
 
 -spec choose(M::integer(), N::integer()) -> domrec(integer()).
 choose(M,N) when is_integer(M), is_integer(N), M=<N ->
-    #?DOM{kind={choose,M,N},
+    ShrinkTo = case {M>=0, N>=0} of
+        {true, true} -> M;
+        {false, true} -> 0;
+        {false, false} -> N
+    end,
+    #?DOM{kind=#choose{min=M,max=N,shrinkto=ShrinkTo},
           pick = fun choose_pick/2,
           shrink = fun choose_shrink/2
          }.
@@ -1194,9 +1190,28 @@
     Value = triq_rnd:uniform(N-M+1) - 1 + M,
     {Dom,Value}.
 
-choose_shrink(#?DOM{kind=#choose{min=M}}=Dom, Value) ->
-    Mid = (Value - M) div 2,
-    {Dom, M + Mid}.
+choose_shrink(#?DOM{kind=#choose{shrinkto=Value}}=Dom, Value) ->
+    {Dom, Value};
+choose_shrink(#?DOM{kind=#choose{shrinkto=ShrinkTo}}=Dom, Value) ->
+    DecrementProb = 2 * math:exp(-0.1 * abs(Value - ShrinkTo)),
+    case triq_rnd:uniform() < DecrementProb of
+        true ->
+            {Dom, choose_shrink_by_decrement(Value, ShrinkTo)};
+        false ->
+            {Dom, choose_shrink_by_half(Value, ShrinkTo)}
+    end.
+
+choose_shrink_by_half(Value, ShrinkTo) ->
+    Mid = (Value - ShrinkTo) div 2,
+    ShrinkTo + Mid.
+
+choose_shrink_by_decrement(Value, ShrinkTo) when Value > ShrinkTo ->
+    Value - 1;
+choose_shrink_by_decrement(Value, ShrinkTo) when Value < ShrinkTo ->
+    Value + 1;
+choose_shrink_by_decrement(Value, Value) ->
+    Value.
+
 
 %% @doc Generates a member of the list `L'.  Shrinks towards the first element
 %% of the list.
diff --git a/test/triq_tests.erl b/test/triq_tests.erl
index 3dc077a..40cbc27 100644
--- a/test/triq_tests.erl
+++ b/test/triq_tests.erl
@@ -219,7 +219,14 @@
 choose_test_() ->
     [?_assertEqual([3], triq:counterexample(?FORALL(_, choose(3,7), false))),
      ?_assertEqual([7], triq:counterexample(?FORALL(I, choose(3,7), I < 7))),
-     ?_assertEqual([3], triq:counterexample(?FORALL(_, choose(3,3), false)))].
+     ?_assertEqual([3], triq:counterexample(?FORALL(_, choose(3,3), false))),
+     ?_assertEqual([0], triq:counterexample(?FORALL(_, choose(-3,7), false))),
+     ?_assertEqual([-3], triq:counterexample(?FORALL(_, choose(-7,-3), false))),
+     ?_assertEqual([0], triq:counterexample(?FORALL(_, choose(-3,0), false))),
+     ?_assertEqual([0], triq:counterexample(?FORALL(_, choose(0,3), false))),
+     ?_assertEqual([1], triq:counterexample(?FORALL(_, choose(1,100), false))),
+     ?_assertEqual([5], triq:counterexample(?FORALL(_, choose(5,1 bsl 80), false))),
+     ?_assertException(error, function_clause, choose(7,3))].
 
 %%
 %% Test binary shrinking