Skip to content

Commit

Permalink
Math::Round::Fair issue
Browse files Browse the repository at this point in the history
--00248c6a5726285ea8049754402e
Content-Type: text/plain; charset=ISO-8859-1

OK, my latest patch is attached.  There might still be a bug or two in the
proof, but it's a lot more explicit now.

I'm having the same issue with this tarball that I have in the git tree.  At
some point, I'll create my own Perl install to see if that helps, but
probably not today.  Even if I can fix this, I'm concerned that other users
might also get tripped up on it, so we should consider *not* using
Devel::Assert until it becomes more ubiquitous.

Thanks,
&ers

On Fri, Dec 10, 2010 at 4:49 PM, Marc Mims <marc@questright.com> wrote:

> * Anders Johnson <andersjohnson@google.com> [101210 16:41]:
> > I'm still having trouble with the git tree build.
> >
> > I had to add "no strict 'subs'" as the second line of Makefile.PL to get
> it
> > to run with the latest Module::Install.
> >
> > Now I can't install Devel::Assert because it requires Devel::Declare,
> which
> > won't build because:
> >  *** Can't load dependency information for B::Hooks::OP::Check:
> >    Can't locate B/Hooks/OP/Check/Install/Files.pm in @inc (@inc contains:
> > inc /home/andersjohnson/tools/lib/perl5/x86_64-linux-gnu-thread-multi
> > /home/andersjohnson/tools/lib/perl5/x86_64-linux-gnu-thread-multi
> > /home/andersjohnson/tools/lib/perl5 /etc/perl /usr/local/lib/perl/5.10.1
> > /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5
> > /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at
> > /home/andersjohnson/tools/lib/perl5/ExtUtils/Depends.pm line 170.
> >
> > Does it work with perl5.10.1?  I wonder if this is related to the fact
> that
> > I'm installing stuff into a private library using a public perl install
> that
> > I can't modify.  I can always create my own perl install instead, but
> that
> > will take a while.  It seems to me that having finicky dependencies could
> > wind up being a maintenance issue.
> >
> > I'll try to get you a new version of the proof by Monday afternoon, but I
> > don't think there's any way I'll have time to finish it much sooner.
>
> I'm running perl v5.10.1, so yes, it does run with that version.
>
> I've attached a tarball created with "make dist".  I wonder if it
> builds for you.
>
>        -Marc
>

OK, my latest patch is attached.  There might still be a bug or two in the proof, but it&#39;s a lot more explicit now.<br><br>I&#39;m having the same issue with this tarball that I have in the git tree.  At some point, I&#39;ll create my own Perl install to see if that helps, but probably not today.  Even if I can fix this, I&#39;m concerned that other users might also get tripped up on it, so we should consider <i>not</i> using Devel::Assert until it becomes more ubiquitous.<br>

<br>Thanks,<br>&amp;ers<br><br><div class="gmail_quote">On Fri, Dec 10, 2010 at 4:49 PM, Marc Mims <span dir="ltr">&lt;<a href="mailto:marc@questright.com">marc@questright.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

* Anders Johnson &lt;<a href="mailto:andersjohnson@google.com">andersjohnson@google.com</a>&gt; [101210 16:41]:<br>
<div class="im">&gt; I&#39;m still having trouble with the git tree build.<br>
&gt;<br>
&gt; I had to add &quot;no strict &#39;subs&#39;&quot; as the second line of Makefile.PL to get it<br>
&gt; to run with the latest Module::Install.<br>
&gt;<br>
&gt; Now I can&#39;t install Devel::Assert because it requires Devel::Declare, which<br>
&gt; won&#39;t build because:<br>
&gt;  *** Can&#39;t load dependency information for B::Hooks::OP::Check:<br>
&gt;    Can&#39;t locate B/Hooks/OP/Check/Install/Files.pm in @inc (@inc contains:<br>
&gt; inc /home/andersjohnson/tools/lib/perl5/x86_64-linux-gnu-thread-multi<br>
&gt; /home/andersjohnson/tools/lib/perl5/x86_64-linux-gnu-thread-multi<br>
&gt; /home/andersjohnson/tools/lib/perl5 /etc/perl /usr/local/lib/perl/5.10.1<br>
&gt; /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5<br>
&gt; /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at<br>
&gt; /home/andersjohnson/tools/lib/perl5/ExtUtils/Depends.pm line 170.<br>
&gt;<br>
&gt; Does it work with perl5.10.1?  I wonder if this is related to the fact that<br>
&gt; I&#39;m installing stuff into a private library using a public perl install that<br>
&gt; I can&#39;t modify.  I can always create my own perl install instead, but that<br>
&gt; will take a while.  It seems to me that having finicky dependencies could<br>
&gt; wind up being a maintenance issue.<br>
&gt;<br>
&gt; I&#39;ll try to get you a new version of the proof by Monday afternoon, but I<br>
&gt; don&#39;t think there&#39;s any way I&#39;ll have time to finish it much sooner.<br>
<br>
</div>I&#39;m running perl v5.10.1, so yes, it does run with that version.<br>
<br>
I&#39;ve attached a tarball created with &quot;make dist&quot;.  I wonder if it<br>
builds for you.<br>
<font color="#888888"><br>
        -Marc<br>
</font></blockquote></div><br>

From bed499702a5e424c9d8a074d1a9f0da6af546f6a Mon Sep 17 00:00:00 2001
From: Anders Johnson <andersjohnson@google.com>
Date: Mon, 13 Dec 2010 16:35:17 -0800
Subject: [PATCH] Added "no strict 'subs';" to make the latest Module::Install happy.
 Rewrote proof that $tslack >= $p0 * (1 - $p0).
  • Loading branch information
andersgoog authored and semifor committed Dec 14, 2010
1 parent f3e31f4 commit 45a9c9d
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 28 deletions.
1 change: 1 addition & 0 deletions Makefile.PL
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use inc::Module::Install;
no strict 'subs';

if ( $Module::Install::AUTHOR ) {
system('pod2text lib/Math/Round/Fair.pm > README');
Expand Down
136 changes: 108 additions & 28 deletions lib/Math/Round/Fair.pm
Original file line number Diff line number Diff line change
Expand Up @@ -386,38 +386,118 @@ same terms as Perl itself.
PROOF THAT $tslack >= $p0 * (1 - $p0)
Imagine a clock, where 0.0 is noon, 0.5 is 6 o'clock, and 1.0 is noon again,
etc. If we start at 0.0, and advance clockwise first for $p0, and then for
every remaining element of @fp, then we have to wind up at noon (according
to the invariant).
If $p0 is 0 or 1, then it is possible that every element of @fp is either 0
or 1, in which case $tslack is 0 and the theorem holds trivially. Otherwise,
the clock has to somehow travel the absolute distance back to noon.
slack($_, $p0) == (1-$p0)*(1-$_) if and only if (1-$p0)*(1-$_) <= $p0*$_, or
equivalently 1-$p0-$_+$p0*$_ <= $p0*$_, or equivalently $_ >= 1-$p0. For
$_ <= 1-$p0, we can imagine the clock advancing clockwise by $_. For
$_ >= 1-$p0, we can imagine the clock retreating counter-clockwise by 1-$_.
Starting at $p0, the total absolute distance traveled clockwise must be at least
1-$p0, or the total abolute distance traveled counter-clockwise must be
at least $p0 (or both).
Mathematically:
$tslack == sum { $_ <= 1-$p0 ? $p0*$_ : (1-$p0)*(1-$_) } @fp ==
At the beginning of each iteration (i.e. initially and immediately before each
time the first element of @fp is removed), the sum of @fp must be an integer.
As a result, at least one of the following statements is true after each time
the first element of @fp is removed as $p0 but before the remaining elements
are adjusted:
(1) $_==0 || $_==1 for $p0 and for all @fp.
(2) sum { $_ <= 1-$p0 ? $_ : 0 } @fp >= 1-$p0. [That is, the remaining
elements that would alone increase the fractional part must sum to at least
enough to make the total integral.]
(3) sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp >= $p0. [That is, the complements of
the remaining elements that would alone decrease the fractional part must
sum to at least enough to make the total integral.]
To understand this, consider the following:
If no element of @fp is neither 0 nor 1, then (1) must be true.
If any element of @fp is 1-$p0, then both (2) and (3) must be true.
OTHERWISE, consider the subset @fpf of @fp whose members are neither
0 nor 1 (nor 1-$p0).
Let @fpp = @fpf[0..$#fpf-1] and let $fpN = $fpf[-1]. It must be true
that frac($p0 + (sum @fpp) + $fpN) == 0.
For (2), consider:
* $fpN == 1 - frac($p0 + sum @fpp).
* If $fpN < 1-$p0 and (3) is false, then:
* sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp < $p0 [converse of (3)]
* sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp ==
sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp +
sum { $_ >= 1-$p0 && frac($_)==0 ? 1-$_ : 0 } @fp
* sum { $_ >= 1-$p0 && frac($_)==0 ? 1-$_ : 0 } @fp == 0
* sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp ==
sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp
* sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp < $p0
* $fpN ==
1 - frac($p0 + sum { $_ > 1-$p0 ? $_ : 0 } @fpp +
sum { $_ < 1-$p0 ? $_ : 0 } @fpp) ==
1 - frac($p0 - sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp +
sum { $_ < 1-$p0 ? $_ : 0 } @fpp)
[because frac(y + sum @x) = frac(y - sum { 1-$_ } @x), for all
y >= sum { 1-$_ } @x and sum(@x) >= -y]
* $fpN >=
1 - ($p0 - sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp +
sum { $_ < 1-$p0 ? $_ : 0 } @fpp)
[because frac(x) <= x for all x >= 0, and recall that
sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp < $p0]
* 1 - ($p0 - sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp +
sum { $_ < 1-$p0 ? $_ : 0 } @fpp) >=
1 - ($p0 + sum { $_ < 1-$p0 ? $_ : 0 } @fpp)
[because 1 - (x - y) >= 1 - x for all y >= 0]
* Transitively, $fpN >= 1 - ($p0 + sum { $_ < 1-$p0 ? $_ : 0 } @fpp)
* Therefore $fpN + sum { $_ < 1-$p0 ? $_ : 0 } @fpp >= 1-$p0,
which is equivalent to (2), because:
* sum { $_ <= 1-$p0 ? $_ : 0 } @fp ==
$fpN + sum { $_ < 1-$p0 ? $_ : 0 } @fpp +
sum { $_ < 1-$p0 && frac($_) == 0 ? $_ : 0 } @fp ==
$fpN + sum { $_ < 1-$p0 ? $_ : 0 } @fpp.
Similarly for (3), consider:
* 1-$fpN == frac($p0 + sum @fpp) == 1 - frac(1-$p0 + sum { 1-$_ } @fpp)
* If $fpN > 1-$p0 and (2) is false, then:
* sum { $_ <= 1-$p0 ? $_ : 0 } @fp < 1-$p0
* sum { $_ <= 1-$p0 ? $_ : 0 } @fp ==
sum { $_ < 1-$p0 ? $_ : 0 } @fpp +
sum { $_ <= 1-$p0 && frac($_)==0 ? $_ : 0 } @fp ==
sum { $_ < 1-$p0 ? $_ : 0 } @fpp < 1-$p0
* 1-$fpN ==
1 - frac(1-$p0 + sum { $_ < 1-$p0 ? 1-$_ : 0 } @fpp +
sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp) ==
1 - frac(1-$p0 - sum { $_ < 1-$p0 ? $_ : 0 } @fpp +
sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp)
* 1-$fpN >= 1 - (1-$p0 + sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp)
* Therefore 1-$fpN + sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp >= $p0,
which is equivalent to (3), because:
* sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp ==
1-$fpN + sum { $_ > 1-$p0 ? 1-$_ : 0 } @fpp
[More intuitively, think of a clock where the hour hand represents the
fractional part, 12 o'clock being zero and 6 o'clock being one half.
If $p0 is 0.25, then you start at 3 o'clock. You can group the remaining
@fp's into the ones that are > 0.75 (call them the "counter-clockwise" ones)
and the ones that are < 0.75 (call them the "clockwise" ones).
If you can't get to noon or beyond clockwise by summing the ones <= 0.75, then
it's not going to help to include any of the ones > 0.75, because each one of
them would increase the remaining angle to get to noon clockwise. In that
case, it is still possible that you can get to noon or beyond counter-clockwise
by summing the ones >= 0.75, but, similarly, if you can't then it's not going
to help to include any of the ones < 0.75. Since it is a pre-condition that
the full sum winds up exactly at noon, in particular it must be true that
there exists a (possibly improper) subset whose sum gets you to noon or beyond
in one direction or the other.]
Note that $tslack == sum { $_ <= 1-$p0 ? $p0*$_ : (1-$p0)*(1-$_) } @fp ==
$p0 * sum { $_ <= 1-$p0 ? $_ : 0 } @fp +
(1-$p0) * sum { $_ > 1-$p0 ? 1-$_ : 0 } @fp ==
$p0 * sum { $_ < 1-$p0 ? $_ : 0 } @fp +
(1-$p0) * sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp.
sum { $_ <= 1-$p0 ? $_ : 0 } @fp >= 1-$p0. [clockwise]
sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp >= $p0. [counter-clockwise]
Because $_ >= 0 and (1-$_) >= 0 for $p0 and for all @fp, we have
$p0 * sum { $_ < 1-$p0 ? $_ : 0 } @fp >= 0 and
(1-$p0) * sum { $_ > 1-$p0 ? 1-$_ : 0 } @fp >= 0; therefore
$tslack >= $p0 * sum { $_ <= 1-$p0 ? $_ : 0 } @fp, and
$tslack >= (1-$p0) * sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp.
And if $p0 * (1 - $p0) > 0, then either
sum { $_ <= 1-$p0 ? $_ : 0 } @fp >= 1 - $p0, which implies
$tslack >= $p0 * sum { $_ <= 1-$p0 ? $_ : 0 } @fp >= $p0 * (1 - $p0);
or
sum { $_ >= 1-$p0 ? 1 - $_ : 0 } @fp >= $p0, which implies
$tslack >= (1-$p0) * sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp >= (1 - $p0) * $p0.
If (1) is true, then $tslack == $p0 * (1 - $p0) == 0; therefore
$tslack >= $p0 * (1 - $p0).
If (2) is true, then $p0 * sum { $_ <= 1-$p0 ? $_ : 0 } @fp >= $p0 * (1-$p0);
therefore, by transitivity, $tslack >= $p0 * (1 - $p0).
If (3) is true, then (1-$p0) * sum { $_ >= 1-$p0 ? 1-$_ : 0 } @fp >=
(1-$p0) * $p0; therefore, by transitivity, $tslack >= $p0 * (1 - $p0).
q.e.d.

0 comments on commit 45a9c9d

Please sign in to comment.