Commits

Shlomi Fish committed d2f69e6

Moved away because they are not needed.

Extracted into a CPAN module.

Comments (0)

Files changed (12)

fc-solve/presets/soft-threads/meta-moves/auto-gen/Shlomif/FCS/CalcMetaScan.pm

-package Shlomif::FCS::CalcMetaScan;
-
-use strict;
-use warnings;
-
-use IO::Handle;
-
-use Shlomif::FCS::CalcMetaScan::IterState;
-use Shlomif::FCS::CalcMetaScan::Structs;
-
-use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-use PDL ();
-
-__PACKAGE__->mk_acc_ref([qw(
-    chosen_scans
-    _iter_idx
-    _num_boards
-    _orig_scans_data
-    _optimize_for
-    _scans_data
-    _selected_scans
-    _status
-    _quotas
-    _total_boards_solved
-    _total_iters
-    _trace_cb
-)]);
-
-sub _init
-{
-    my $self = shift;
-
-    my $args = shift;
-
-    $self->_quotas($args->{'quotas'}) or
-        die "Quotas not specified!";
-
-    if (!exists($args->{'scans_data'}))
-    {
-        die "scans_data not specified!";
-    }
-
-    $self->_orig_scans_data($args->{'scans_data'}->copy());
-    $self->_scans_data($self->_orig_scans_data()->copy());
-
-    $self->_selected_scans($args->{'selected_scans'}) or
-        die "selected_scans not specified!";
-
-    $self->_num_boards($args->{'num_boards'}) or
-        die "num_boards not specified!";
-
-    $self->_trace_cb($args->{'trace_cb'});
-
-    $self->_iter_idx(0);
-
-    $self->_optimize_for($args->{'optimize_for'});
-
-    return 0;
-}
-
-my $BOARDS_DIM = 0;
-my $SCANS_DIM = 1;
-my $STATISTICS_DIM = 2;
-
-sub _next_iter_idx
-{
-    my $self = shift;
-
-    my $ret = $self->_iter_idx();
-
-    $self->_iter_idx($ret+1);
-
-    return $ret;
-}
-
-sub _get_next_quota
-{
-    my $self = shift;
-
-    my $iter = $self->_next_iter_idx();
-
-    if (ref($self->_quotas()) eq "ARRAY")
-    {
-        return $self->_quotas()->[$iter];
-    }
-    else
-    {
-        return $self->_quotas()->($iter);
-    }
-}
-
-sub _calc_get_iter_state_param_method
-{
-    my $self = shift;
-
-    my $optimize_for = $self->_optimize_for();
-
-    my %resolve =
-    (
-        len => "_get_iter_state_params_len",
-        minmax_len => "_get_iter_state_params_minmax_len",
-        speed => "_get_iter_state_params_speed",
-    );
-
-    return $resolve{$optimize_for};
-}
-
-sub _get_iter_state_params
-{
-    my $self = shift;
-
-    my $method = $self->_calc_get_iter_state_param_method();
-
-    return $self->$method();
-}
-
-sub _my_sum_over
-{
-    my $pdl = shift;
-
-    return $pdl->sumover()->slice(":,(0)");
-}
-
-sub _my_xchg_sum_over
-{
-    my $pdl = shift;
-
-    return _my_sum_over($pdl->xchg(0,1));
-}
-
-sub _get_iter_state_params_len
-{
-    my $self = shift;
-
-    my $iters_quota = 0;
-    my $num_solved_in_iter = 0;
-    my $selected_scan_idx;
-
-    # If no boards were solved, then try with a larger quota
-    while ($num_solved_in_iter == 0)
-    {
-        my $q_more = $self->_get_next_quota();
-        if (!defined($q_more))
-        {
-            Shlomif::FCS::CalcMetaScan::Error::OutOfQuotas->throw(
-                error => "No q_more",
-            );
-        }
-
-        $iters_quota += $q_more;
-
-        my $iters = $self->_scans_data()->slice(":,:,0");
-        my $solved = (($iters <= $iters_quota) & ($iters > 0));
-        my $num_moves = $self->_scans_data->slice(":,:,2");
-        my $solved_moves = $solved * $num_moves;
-        
-        my $solved_moves_sums = _my_sum_over($solved_moves);
-        my $solved_moves_counts = _my_sum_over($solved);
-        my $solved_moves_avgs = $solved_moves_sums / $solved_moves_counts;
-
-        (undef, undef, $selected_scan_idx, undef) =
-            $solved_moves_avgs->minmaximum()
-            ;
-
-        $num_solved_in_iter = $solved_moves_counts->at($selected_scan_idx);
-    }
-
-    return
-    {
-        quota => $iters_quota,
-        num_solved => $num_solved_in_iter,
-        scan_idx => $selected_scan_idx,
-    };
-}
-
-sub _get_iter_state_params_minmax_len
-{
-    my $self = shift;
-
-    my $iters_quota = 0;
-    my $num_solved_in_iter = 0;
-    my $selected_scan_idx;
-
-    # If no boards were solved, then try with a larger quota
-    while ($num_solved_in_iter == 0)
-    {
-        my $q_more = $self->_get_next_quota();
-        if (!defined($q_more))
-        {
-            Shlomif::FCS::CalcMetaScan::Error::OutOfQuotas->throw(
-                error => "No q_more",
-            );
-        }
-
-        $iters_quota += $q_more;
-
-        my $iters = $self->_scans_data()->slice(":,:,0");
-        my $solved = (($iters <= $iters_quota) & ($iters > 0));
-        my $num_moves = $self->_scans_data->slice(":,:,2");
-        my $solved_moves = $solved * $num_moves;
-        
-        my $solved_moves_maxima = $solved_moves->maximum()->slice(":,(0),(0)");
-        my $solved_moves_counts = _my_sum_over($solved);
-        
-        (undef, undef, $selected_scan_idx, undef) =
-            $solved_moves_maxima->minmaximum()
-            ;
-
-        $num_solved_in_iter = $solved_moves_counts->at($selected_scan_idx);
-    }
-
-    return
-    {
-        quota => $iters_quota,
-        num_solved => $num_solved_in_iter,
-        scan_idx => $selected_scan_idx,
-    };
-}
-
-sub _get_iter_state_params_speed
-{
-    my $self = shift;
-
-    my $iters_quota = 0;
-    my $num_solved_in_iter = 0;
-    my $selected_scan_idx;
-
-    # If no boards were solved, then try with a larger quota
-    while ($num_solved_in_iter == 0)
-    {
-        my $q_more = $self->_get_next_quota();
-        if (!defined($q_more))
-        {
-            Shlomif::FCS::CalcMetaScan::Error::OutOfQuotas->throw(
-                error => "No q_more"
-            );
-        }
-
-        $iters_quota += $q_more;
-
-        (undef, $num_solved_in_iter, undef, $selected_scan_idx) =
-            PDL::minmaximum(
-                PDL::sumover(
-                    ($self->_scans_data() <= $iters_quota) & 
-                    ($self->_scans_data() > 0)
-                )
-              );
-    }
-
-    return
-    {
-        quota => $iters_quota,
-        num_solved => $num_solved_in_iter,
-        scan_idx => $selected_scan_idx,
-    };
-}
-
-sub _get_selected_scan
-{
-    my $self = shift;
-
-    my $iter_state = 
-        Shlomif::FCS::CalcMetaScan::IterState->new(
-            $self->_get_iter_state_params(),
-        );
-
-    $iter_state->attach_to($self);
-
-    return $iter_state;
-}
-
-sub _inspect_quota
-{
-    my $self = shift;
-
-    my $state = $self->_get_selected_scan();
-
-    $state->register_params();
-
-    $state->update_total_iters();
-    
-    if ($self->_total_boards_solved() == $self->_num_boards())
-    {
-        $self->_status("solved_all");
-    }
-    else
-    {
-        $state->update_idx_slice();
-    }
-
-    $state->detach();
-}
-
-=head2 my $chosen_scans_array_ref = $self->chosen_scans()
-
-Returns the scans that have been chosen to perform the iteration. Each one is
-a Shlomif::FCS::CalcMetaScan::ScanRun object.
-
-=head2 $calc_meta_scan->calc_meta_scan()
-
-Calculates the meta-scan after initialisation. See here for the details
-of the algorithm:
-
-L<http://www.shlomifish.org/lecture/Freecell-Solver/The-Next-Pres/slides/multi-tasking/best-meta-scan/>
-
-=cut
-
-sub calc_meta_scan
-{
-    my $self = shift;
-
-    $self->chosen_scans([]);
-
-    $self->_total_boards_solved(0);
-    $self->_total_iters(0);
-
-    $self->_status("iterating");
-    # $self->_inspect_quota() throws ::Error::OutOfQuotas if
-    # it does not have any available quotas.
-    eval
-    {
-        while ($self->_status() eq "iterating")
-        {
-            $self->_inspect_quota();
-        }
-    };
-    if (my $err = Exception::Class->caught('Shlomif::FCS::CalcMetaScan::Error::OutOfQuotas'))
-    {
-        $self->_status("out_of_quotas");
-    }
-    else
-    {
-        $err = Exception::Class->caught();
-        if (ref($err))
-        {
-            $err->rethrow;
-        }
-        else
-        {
-            die $err;
-        }
-    }
-}
-
-=head2 $self->calc_flares_meta_scan()
-
-This function calculates the flares meta-scan: i.e: assuming that all atomic
-scans are run one after the other and the shortest solutions of all
-successful scans are being picked.
-
-=cut
-
-sub _get_num_scans
-{
-    my $self = shift;
-
-    return (($self->_scans_data()->dims())[$SCANS_DIM]);
-}
-
-sub calc_flares_meta_scan
-{
-    my $self = shift;
-
-    $self->chosen_scans([]);
-
-    $self->_total_boards_solved(0);
-    $self->_total_iters(0);
-
-    $self->_status("iterating");
-
-    my $iters_quota = 0;
-    my $flares_num_iters = PDL::Core::pdl([(0) x $self->_get_num_scans()]);
-    my $ones_constant = PDL::Core::pdl(
-        [map { [1] } (1 .. $self->_get_num_scans())]
-    );
-
-    my $next_num_iters_for_each_scan_x_scan = 
-        (($ones_constant x $flares_num_iters));
-
-
-    my $num_moves = $self->_scans_data->slice(":,:,1");
-
-    # The number of moves for dimension 0,1,2 above.
-    my $num_moves_repeat = $num_moves->clump(1..2)->xchg(0,1)->dummy(0,$self->_get_num_scans());
-
-    my $selected_scan_idx;
-
-    my $loop_iter_num = 0;
-
-    my $UNSOLVED_NUM_MOVES_CONSTANT = 64 * 1024 * 1024;
-
-    my $last_avg = $UNSOLVED_NUM_MOVES_CONSTANT;
-
-    FLARES_LOOP:
-    while (my $q_more = $self->_get_next_quota())
-    {
-        $iters_quota += $q_more;
-        
-        # Next number of iterations for each scan x scan combination.
-        my $next_num_iters = 
-            (($ones_constant x $flares_num_iters) + 
-                (PDL::MatrixOps::identity($self->_get_num_scans())
-                    * $iters_quota
-                )
-            );
-
-        # print "\$next_num_iters = $next_num_iters\n";
-
-        my $iters = $self->_scans_data()->slice(":,:,0");
-
-        my $iters_repeat =
-            $iters->dummy(0,$self->_get_num_scans())->xchg(1,2)->clump(2 .. 3);
-
-        # print "\$iters_repeat =", join(",",$iters_repeat->dims()), "\n";
-
-        my $next_num_iters_repeat = 
-            $next_num_iters->dummy(0,$self->_num_boards())->xchg(0,2);
-
-        # print "\$next_num_iters_repeat =", join(",",$next_num_iters_repeat->dims()), "\n";
-
-        # A boolean tensor of which boards were solved:
-        # Dimension 0 - Which scan is it. - size - _get_num_scans()
-        # Dimension 1 - Which scan we added the quota to 
-        #   - size - _get_num_scans()
-        # Dimension 2 - Which board. - size - _num_boards()
-        my $solved = ($iters_repeat >= 0) * ($iters_repeat < $next_num_iters_repeat);
-
-        # print "\$num_moves_repeat =", join(",",$num_moves_repeat->dims()), "\n";
-
-        
-
-        my $num_moves_solved = 
-            ($solved * $num_moves_repeat) + ($solved->not() * $UNSOLVED_NUM_MOVES_CONSTANT);
-
-        my $minimal_num_moves_solved = $num_moves_solved->xchg(0,1)->minimum();
-
-        my $which_minima_are_solved =
-            ($minimal_num_moves_solved != $UNSOLVED_NUM_MOVES_CONSTANT)
-            ;
-
-        my $minimal_with_zeroes =
-            $which_minima_are_solved * $minimal_num_moves_solved;
-
-        my $solved_moves_sums = _my_xchg_sum_over($minimal_with_zeroes);
-        my $solved_moves_counts = _my_xchg_sum_over($which_minima_are_solved);
-        my $solved_moves_avgs = $solved_moves_sums / $solved_moves_counts;
-
-        # print join(",", $solved_moves_avgs->minmaximum()), "\n";
-
-        my $min_avg;
-
-        ($min_avg, undef, $selected_scan_idx, undef) =
-            $solved_moves_avgs->minmaximum()
-            ;
-
-        $last_avg = $min_avg;
-
-        push @{$self->chosen_scans()}, 
-            Shlomif::FCS::CalcMetaScan::ScanRun->new(
-                {
-                    iters => $iters_quota, 
-                    scan => $selected_scan_idx,
-                }
-            );
-
-        $flares_num_iters->set($selected_scan_idx, $flares_num_iters->at($selected_scan_idx)+$iters_quota);
-        $self->_selected_scans()->[$selected_scan_idx]->mark_as_used();
-
-        $iters_quota = 0;
-
-        my $num_solved = $solved_moves_counts->at($selected_scan_idx);
-
-        my $flares_num_iters_repeat =
-            $flares_num_iters->dummy(0,$self->_num_boards());
-
-        # A boolean tensor:
-        # Dimension 0 - board.
-        # Dimension 1 - scans.
-        my $solved_with_which_iter = 
-            ($flares_num_iters_repeat >= $iters->clump(1 .. 2))
-            & ($iters->clump(1 .. 2) >= 0)
-            ;
-
-        my $total_num_iters =
-        (
-            ($solved_with_which_iter * $flares_num_iters_repeat)->sum()
-            + ($solved_with_which_iter->not()->andover() 
-                * $flares_num_iters->sum())->sum()
-        );
-
-        print "Finished ", $loop_iter_num++, " ; #Solved = $num_solved ; Iters = $total_num_iters ; Avg = $min_avg\n";
-        STDOUT->flush();
-    }
-}
-
-=head2 $calc_meta_scan->calc_board_iters($board_idx)
-
-Calculates the iterations of the board $board_idx in all the scans.
-
-Returns a hash_ref containing the key 'per_scan_iters' for the iterations
-per scan, and 'board_iters' for the total board iterations when ran in the
-scans.
-
-=cut
-
-sub calc_board_iters
-{
-    my $self = shift;
-    my $board = shift;
-
-    my $board_iters = 0;
-
-    my @info = PDL::list($self->_orig_scans_data()->slice("$board,:"));
-    my @orig_info = @info;
-
-    foreach my $s (@{$self->chosen_scans()})
-    {
-        if (($info[$s->scan()] > 0) && ($info[$s->scan()] <= $s->iters()))
-        {
-            $board_iters += $info[$s->iters()];
-            last;
-        }
-        else
-        {
-            if ($info[$s->scan()] > 0)
-            {
-                $info[$s->scan()] -= $s->iters();
-            }
-            $board_iters += $s->iters();
-        }
-    }
-
-    return
-        {
-            'per_scan_iters' => \@orig_info,
-            'board_iters' => $board_iters,
-        };
-}
-
-=head2 my $status = $calc_meta_scan->get_final_status()
-
-Returns the status as string:
-
-=over 4
-
-=item * "solved_all"
-
-=item * "iterating"
-
-=item * "out_of_quotas"
-
-=back
-
-=cut
-
-sub get_final_status
-{
-    my $self = shift;
-
-    return $self->_status();
-}
-
-=head2 my $sim_results_obj = $calc_meta_scan->simulate_board($board_idx)
-
-Simulates the board No $board_idx through the scan. Returns a 
-L<Shlomif::FCS::CalcMetaScan::SimulationResults> object.
-
-=cut
-
-sub simulate_board
-{
-    my ($self, $board) = @_;
-
-    my @info = PDL::list($self->_orig_scans_data()->slice("$board,:"));
-
-    my $board_iters = 0;
-
-    my @scan_runs;
-
-    my $status = "Unsolved";
-
-    my $add_new_scan_run = sub {
-        my $scan_run = shift;
-
-        push @scan_runs, $scan_run;
-        
-        $board_iters += $scan_run->iters();
-    };
-
-    SCANS_LOOP:
-    foreach my $s (@{$self->chosen_scans()})
-    {
-        if (($info[$s->scan()] > 0) && ($info[$s->scan()] <= $s->iters()))
-        {
-            $add_new_scan_run->(
-                Shlomif::FCS::CalcMetaScan::ScanRun->new(
-                    {
-                        iters => $info[$s->scan()],
-                        scan => $s->scan(),
-                    },
-                )
-            );
-
-            $status = "Solved";
-            last SCANS_LOOP;
-        }
-        else
-        {
-            if ($info[$s->scan()] > 0)
-            {
-                $info[$s->scan()] -= $s->iters();
-            }
-
-            $add_new_scan_run->( 
-                Shlomif::FCS::CalcMetaScan::ScanRun->new(
-                    {
-                        iters => $s->iters(),
-                        scan => $s->scan(),
-                    },
-                )
-            );
-        }
-    }
-
-    return
-        Shlomif::FCS::CalcMetaScan::SimulationResults->new(
-            {
-                status => $status,
-                scan_runs => \@scan_runs,
-                total_iters => $board_iters,
-            }
-        );
-}
-
-sub _trace
-{
-    my ($self, $args) = @_;
-    
-    if (my $trace_callback = $self->_trace_cb())
-    {
-        $trace_callback->($args);
-    }
-
-    return;
-}
-
-=head2 my $n = $calc_meta_scan->get_total_iters()
-
-Returns the total iterations count so far.
-
-=cut
-
-sub get_total_iters
-{
-    my $self = shift;
-
-    return $self->_total_iters();
-}
-
-sub _add_to_total_iters
-{
-    my $self = shift;
-    
-    my $how_much = shift;
-
-    $self->_total_iters($self->_total_iters() + $how_much);
-
-    return;
-}
-
-sub _add_to_total_boards_solved
-{
-    my $self = shift;
-    
-    my $how_much = shift;
-
-    $self->_total_boards_solved($self->_total_boards_solved() + $how_much);
-
-    return;
-}
-
-package Shlomif::FCS::CalcMetaScan::ScanRun;
-
-use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-__PACKAGE__->mk_acc_ref([qw(iters scan)]);
-
-sub _init
-{
-    my ($self, $args) = @_;
-
-    $self->iters($args->{iters});
-    $self->scan($args->{scan});
-
-    return;
-}
-
-sub clone
-{
-    my $self = shift;
-
-    return ref($self)->new({iters => $self->iters(), scan => $self->scan()});
-}
-
-package Shlomif::FCS::CalcMetaScan::SimulationResults;
-
-use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-__PACKAGE__->mk_acc_ref([qw(status scan_runs total_iters)]);
-
-sub _init
-{
-    my ($self, $args) = @_;
-
-    $self->status($args->{status});
-    $self->scan_runs($args->{scan_runs});
-    $self->total_iters($args->{total_iters});
-
-    return;
-}
-
-sub get_total_iters
-{
-    return shift->total_iters();
-}
-
-sub get_status
-{
-    return shift->status();
-}
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (c) 2010 Shlomi Fish
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-=cut
-
-1;
-

fc-solve/presets/soft-threads/meta-moves/auto-gen/Shlomif/FCS/CalcMetaScan/Base.pm

-package Shlomif::FCS::CalcMetaScan::Base;
-
-use strict;
-use warnings;
-
-=head1 NAME
-
-Shlomif::FCS::CalcMetaScan::Base - a base class.
-
-=cut
-
-use vars qw($VERSION);
-
-$VERSION = '0.0.1';
-
-use Class::XSAccessor;
-
-=head1 SYNOPSIS
-
-    use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-    sub _init
-    {
-        my ($self, $args) = @_;
-
-        $self->address($args->{address});
-
-        if (!exists($args->{name}))
-        {
-            die "No name - no cry.";
-        }
-
-        return;
-    }
-
-=head1 DESCRIPTION
-
-This is the base class for L<Shlomif::FCS::CalcMetaScan> classes.
-Everything is subject to change.
-
-=cut
-
-=head1 FUNCTIONS
-
-=head2 new($args)
-
-The constructor. Blesses and calls _init() .
-
-=cut
-
-sub new
-{
-    my $class = shift;
-    my $self = {};
-    bless $self, $class;
-
-    # May throw an exception.
-    $self->_init(@_);
-
-    return $self;
-}
-
-=head2 __PACKAGE__->mk_accessors(qw(method1 method2 method3))
-
-Equivalent to L<Class::Accessor>'s mk_accessors only using Class::XSAccessor.
-It beats running an ugly script on my code, and can be done at run-time.
-
-Gotta love dynamic languages like Perl 5.
-
-=cut
-
-sub mk_accessors
-{
-    my $package = shift;
-    return $package->mk_acc_ref([@_]); 
-}
-
-=head2 __PACKAGE__->mk_acc_ref([qw(method1 method2 method3)])
-
-Creates the accessors in the array-ref of names at run-time.
-
-=cut
-
-sub mk_acc_ref
-{
-    my $package = shift;
-    my $names = shift;
-
-    my $mapping = +{ map { $_ => $_ } @$names };
-
-    eval <<"EOF";
-package $package;
-
-Class::XSAccessor->import(
-    accessors => \$mapping,            
-);
-EOF
-
-}
-
-=head1 AUTHOR
-
-Shlomi Fish, C<< <shlomif at iglu.org.il> >>
-
-=head1 SUPPORT
-
-You can find documentation for this module with the perldoc command.
-
-    perldoc Shlomif::FCS::CalcMetaScan
-
-
-You can also look for information at:
-
-=over 4
-
-=item * RT: CPAN's request tracker
-
-L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Shlomif-FCS-CalcMetaScan>
-
-=item * AnnoCPAN: Annotated CPAN documentation
-
-L<http://annocpan.org/dist/Shlomif-FCS-CalcMetaScan>
-
-=item * CPAN Ratings
-
-L<http://cpanratings.perl.org/d/Shlomif-FCS-CalcMetaScan>
-
-=item * Search CPAN
-
-L<http://search.cpan.org/dist/Shlomif-FCS-CalcMetaScan>
-
-=back
-
-
-=head1 ACKNOWLEDGEMENTS
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (c) 2010 Shlomi Fish
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-=cut
-
-1; # End of Shlomif::FCS::CalcMetaScan::Move
-

fc-solve/presets/soft-threads/meta-moves/auto-gen/Shlomif/FCS/CalcMetaScan/CmdLine.pm

-package Shlomif::FCS::CalcMetaScan::CmdLine;
-
-use strict;
-use warnings;
-
-use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-use Getopt::Long;
-use IO::File;
-
-use Shlomif::FCS::CalcMetaScan;
-use Shlomif::FCS::CalcMetaScan::PostProcessor;
-
-use MyInput;
-
-use Carp;
-
-__PACKAGE__->mk_acc_ref(
-    [qw(
-    _add_horne_prune
-    _arbitrator
-    _chosen_scans
-    _input_obj
-    _is_flares
-    _num_boards
-    _offset_quotas
-    _optimize_for
-    _output_filename
-    _post_processor
-    _quotas_are_cb
-    _quotas_expr
-    _should_rle_be_done
-    _should_trace_be_done
-    _simulate_to
-    _start_board
-    )]
-);
-
-sub _init
-{
-    my $self = shift;
-
-    # Command line parameters
-    my $_start_board = 1;
-    my $num_boards = 32000;
-    my $output_filename = "-";
-    my $should_trace_be_done = 0;
-    my $should_rle_be_done = 1;
-    my $_quotas_expr = undef;
-    my $quotas_are_cb = 0;
-    my $optimize_for = "speed";
-    my $offset_quotas = 0;
-    my $simulate_to = undef;
-    my $_add_horne_prune = 0;
-
-    GetOptions(
-        "o|output=s" => \$output_filename,
-        "num-boards=i" => \$num_boards,
-        "trace" => \$should_trace_be_done,
-        "rle!" => \$should_rle_be_done,
-        "start-board=i" => \$_start_board,
-        "quotas-expr=s" => \$_quotas_expr,
-        "quotas-are-cb" => \$quotas_are_cb,
-        "offset-quotas" => \$offset_quotas,
-        "opt-for=s" => \$optimize_for,
-        "simulate-to=s" => \$simulate_to,
-        "sprtf" => \$_add_horne_prune,
-    ) or exit(1);
-
-    $self->_start_board($_start_board);
-    $self->_num_boards($num_boards);
-    $self->_output_filename($output_filename);
-    $self->_should_trace_be_done($should_trace_be_done);
-    $self->_should_rle_be_done($should_rle_be_done);
-    $self->_quotas_expr($_quotas_expr);
-    $self->_quotas_are_cb($quotas_are_cb);
-    $self->_optimize_for($optimize_for);
-    $self->_offset_quotas($offset_quotas);
-    $self->_simulate_to($simulate_to);
-    $self->_is_flares(0);
-    $self->_add_horne_prune($_add_horne_prune);
-
-    $self->_input_obj(
-        MyInput->new(
-            {
-                start_board => $self->_start_board(),
-                num_boards => $self->_num_boards(),
-            }
-        )
-    );
-
-    $self->_post_processor(
-        Shlomif::FCS::CalcMetaScan::PostProcessor->new(
-            {
-                do_rle => $self->_should_rle_be_done(),
-                offset_quotas => $self->_offset_quotas(),
-            }
-        )
-    );
-
-    return;
-}
-
-sub _selected_scans
-{
-    my $self = shift;
-
-    return $self->_input_obj->selected_scans();
-}
-
-sub _map_all_but_last
-{
-    my $self = shift;
-
-    my ($cb, $arr_ref) = (@_);
-
-    return [ (map {$cb->($_)} @$arr_ref[0 .. $#$arr_ref-1]), $arr_ref->[-1] ];
-}
-
-sub _get_quotas
-{
-    my $self = shift;
-    if ($self->_quotas_are_cb())
-    {
-        return scalar(eval($self->_quotas_expr()));
-    }
-    elsif (defined($self->_quotas_expr()))
-    {
-        return [eval $self->_quotas_expr()];
-    }
-    else
-    {
-        return $self->_get_default_quotas();
-    }
-}
-
-sub _get_default_quotas
-{
-    return [(350) x 5000];
-}
-
-sub _get_script_fh
-{
-    my $self = shift;
-    return IO::File->new(
-       ($self->_output_filename() eq "-") ?
-           ">&STDOUT" :
-           ($self->_output_filename(), "w")
-       );
-}
-
-sub _get_script_terminator
-{
-    return "\n\n\n";
-}
-
-sub _out_script
-{
-    my $self = shift;
-    my $cmd_line_string = shift;
-
-    $self->_get_script_fh()->print(
-        $cmd_line_string, 
-        $self->_get_script_terminator($cmd_line_string)
-    );
-}
-
-sub _get_line_of_command
-{
-    my $self = shift;
-    
-    my $args_string = 
-        join(" ", 
-            $self->_start_board(), 
-            $self->_start_board() + $self->_num_boards() - 1, 
-            1
-        );
-    return "freecell-solver-range-parallel-solve $args_string";
-}
-
-sub _line_ends_mapping
-{
-    my $self = shift;
-    return $self->_map_all_but_last(sub { "$_[0] \\\n" }, shift);
-}
-
-sub _get_used_scans
-{
-    my $self = shift;
-    return [ grep { $_->is_used() } @{$self->_selected_scans()}];
-}
-
-sub _get_scan_line
-{
-    my ($self, $line) = @_;
-
-    return $line->{'cmd_line'} . " -step 500 " 
-        . join(" ", map { $_, $line->{'id'} } 
-            ("--st-name", ($self->_is_flares() ? "--flare-name" : ()))
-        );
-}
-
-sub _get_lines_of_scan_defs
-{
-    my $self = shift;
-    return 
-        [map 
-            { $self->_get_scan_line($_) } 
-            @{$self->_get_used_scans()}
-        ];
-}
-
-sub _scan_def_line_mapping
-{
-    my ($self, $lines_aref) = @_;
-
-    return $self->_map_all_but_last(
-        sub
-        {
-            my ($line) = @_;
-
-            return $line . ' ' . ($self->_is_flares() ? "-nf" : "-nst");
-        },
-        [
-            map
-            { 
-                my $line = $_;
-                # Add the -sp r:tf flag to each scan if specified - it enhances
-                # performance, but timing the scans with it makes the total
-                # scan sub-optimal.
-                if ($self->_add_horne_prune())
-                {
-                    $line =~ s/( --st-name)/ -sp r:tf$1/;
-                }
-                $line;
-            }
-            @$lines_aref
-        ],
-    );
-}
-
-sub _calc_iter_quota
-{
-    my $self = shift;
-    my $quota = shift;
-
-    if ($self->_offset_quotas())
-    {
-        return $quota+1;
-    }
-    else
-    {
-        return $quota;
-    }
-}
-
-sub _map_scan_idx_to_id
-{
-    my $self = shift;
-    my $index = shift;
-
-    return $self->_selected_scans()->[$index]->id();
-}
-
-sub _format_prelude_iter
-{
-    my $self = shift;
-
-    my $iter = shift;
-
-    return ($self->_is_flares() ? "Run:" : "") . $iter->iters() . '@'
-        . $self->_map_scan_idx_to_id($iter->scan())
-        ;
-}
-
-sub _get_line_of_prelude
-{
-    my $self = shift;
-    return +($self->_is_flares() ? "--flares-plan" : "--prelude") . qq{ "} .
-        join(",",
-            map { $self->_format_prelude_iter($_) } 
-                @{$self->_chosen_scans()}
-        ) . "\"";
-}
-
-sub _calc_script_lines
-{
-    my $self = shift;
-    return
-        [
-            $self->_get_line_of_command(),
-            @{$self->_scan_def_line_mapping(
-                $self->_get_lines_of_scan_defs()
-            )},
-            $self->_get_line_of_prelude()
-        ];
-}
-
-sub _calc_script_text
-{
-    my $self = shift;
-    return 
-        join("",
-            @{$self->_line_ends_mapping(
-                $self->_calc_script_lines()
-            )}
-        );
-}
-
-sub _write_script
-{
-    my $self = shift;
-     
-    $self->_out_script(
-        $self->_calc_script_text()
-    );
-}
-
-sub _calc_scans_data
-{
-    my $self = shift;
-
-    my $method = 
-        (($self->_optimize_for() =~ m{len})
-            ? "get_scans_lens_data"
-            : "get_scans_data"
-        );
-
-    return $self->_input_obj->$method();
-}
-
-sub _arbitrator_trace_cb
-{
-    my $args = shift;
-    printf("%s \@ %s (%s solved)\n",
-        @$args{qw(iters_quota selected_scan_idx total_boards_solved)}
-    );
-}
-
-sub _init_arbitrator
-{
-    my $self = shift;
-
-    return $self->_arbitrator(
-        Shlomif::FCS::CalcMetaScan->new(
-            {
-                'quotas' => $self->_get_quotas(),
-                'selected_scans' => $self->_selected_scans(),
-                'num_boards' => $self->_num_boards(),
-                'scans_data' => $self->_calc_scans_data(),
-                'trace_cb' => \&_arbitrator_trace_cb,
-                'optimize_for' => $self->_optimize_for(),
-            }
-        )
-    );
-}
-
-sub _report_total_iters
-{
-    my $self = shift;
-    if ($self->_arbitrator()->get_final_status() eq "solved_all")
-    {
-        print "Solved all!\n";
-    }
-    printf("total_iters = %s\n", $self->_arbitrator()->get_total_iters());
-}
-
-sub _arbitrator_process
-{
-    my $self = shift;
-
-    $self->_arbitrator()->calc_meta_scan();
-
-    my $scans = $self->_post_processor->process(
-        $self->_arbitrator->chosen_scans()
-    );
-
-    $self->_chosen_scans($scans);
-}
-
-sub _do_trace_for_board
-{
-    my $self = shift;
-    my $board = shift;
-
-    my $results = $self->_arbitrator()->calc_board_iters($board);
-    print "\@info=". join(",", @{$results->{per_scan_iters}}). "\n";
-    print +($board+$self->_start_board()) . ": ". $results->{board_iters} . "\n";
-}
-
-sub _real_do_trace
-{
-    my $self = shift;
-    foreach my $board (0 .. $self->_num_boards()-1)
-    {
-        $self->_do_trace_for_board($board);
-    }
-}
-
-sub _do_trace
-{
-    my $self = shift;
-    # Analyze the results
-
-    if ($self->_should_trace_be_done())
-    {
-        $self->_real_do_trace();
-    }
-}
-
-sub _get_run_string
-{
-    my $self = shift;
-    my $results = shift;
-
-    return join("",
-        map 
-        { 
-            sprintf('%i@%i,', 
-                $_->iters(), 
-                $self->_map_scan_idx_to_id($_->scan())
-            )
-        }
-        @{$self->_post_processor->process($results->scan_runs())},
-    );
-}
-
-sub _do_simulation_for_board
-{
-    my ($self, $board) = @_;
-
-    my $results = $self->_arbitrator()->simulate_board($board);
-
-    my $scan_mapper = sub {
-        my $index = shift;
-
-        return $self->_map_scan_idx_to_id($index);
-    };
-
-    return 
-        sprintf("%i:%s:%s:%i",
-            $board+1,
-            $results->get_status(),
-            $self->_get_run_string($results),
-            $results->get_total_iters(),
-        );
-}
-
-sub _real_do_simulation
-{
-    my $self = shift;
-
-    open my $simulate_out_fh, ">", $self->_simulate_to()
-        or Carp::confess("Could not open " . $self->_simulate_to() . " - $!");
-
-    foreach my $board (0 .. $self->_num_boards()-1)
-    {
-        print {$simulate_out_fh} $self->_do_simulation_for_board($board), "\n";
-    }
-
-    close($simulate_out_fh);
-
-    return;
-}
-
-
-sub _do_simulation
-{
-    my $self = shift;
-    # Analyze the results
-
-    if (defined($self->_simulate_to()))
-    {
-        $self->_real_do_simulation();
-    }
-
-    return;
-}
-
-sub run
-{
-    my $self = shift;
-
-    $self->_init_arbitrator();
-    $self->_arbitrator_process();
-    $self->_report_total_iters();
-    $self->_write_script();
-    $self->_do_trace();
-    $self->_do_simulation();
-
-    return 0;
-}
-
-sub run_flares
-{
-    my $self = shift;
-
-    $self->_optimize_for("len");
-    $self->_is_flares(1);
-
-    $self->_init_arbitrator();
-
-    $self->_arbitrator()->calc_flares_meta_scan();
-
-    my $scans = $self->_post_processor->process(
-        $self->_arbitrator->chosen_scans()
-    );
-
-    $self->_chosen_scans($scans);
-    $self->_report_total_iters();
-    $self->_write_script();
-    $self->_do_trace();
-    $self->_do_simulation();
-
-    return 0;
-}
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (c) 2010 Shlomi Fish
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-=cut
-
-1;
-

fc-solve/presets/soft-threads/meta-moves/auto-gen/Shlomif/FCS/CalcMetaScan/IterState.pm

-package Shlomif::FCS::CalcMetaScan::IterState;
-
-use strict;
-use warnings;
-
-use PDL ();
-
-use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-use vars (qw(@fields %fields_map));
-@fields = (qw(
-    _main
-    _num_solved
-    _quota
-    _scan_idx
-));
-
-use Exception::Class
-(
-    'Shlomif::FCS::CalcMetaScan::Error::OutOfQuotas'
-);
-
-%fields_map = (map { $_ => 1 } @fields);
-
-__PACKAGE__->mk_acc_ref(\@fields);
-
-sub _init
-{
-    my $self = shift;
-
-    my $args = shift;
-
-    $self->_quota( $args->{'quota'} );
-    $self->_num_solved( $args->{'num_solved'} );
-    $self->_scan_idx( $args->{'scan_idx'} );
-
-    return 0;
-}
-
-sub attach_to
-{
-    my $self = shift;
-    my $main_obj = shift;
-
-    $self->_main($main_obj);
-
-    return;
-}
-
-sub get_chosen_struct
-{
-    my $self = shift;
-    return
-        Shlomif::FCS::CalcMetaScan::ScanRun->new(
-            {
-                iters => $self->_quota(), 
-                scan => $self->_scan_idx() 
-            }
-        );
-}
-
-sub detach
-{
-    my $self = shift;
-    $self->_main(undef);
-}
-
-sub idx_slice
-{
-    my $self = shift;
-
-    my $scans_data = $self->_main()->_scans_data();
-
-    my @dims = $scans_data->dims();
-
-    return $scans_data->slice(
-        join(",",
-            ":", $self->_scan_idx(), (("(0)") x (@dims-2))
-        )
-    );
-}
-
-sub update_total_iters
-{
-    my $state = shift;
-
-    # $r is the result of this scan.
-    my $r = $state->idx_slice();
-    
-    # Add the total iterations for all the states that were solved by
-    # this scan.
-    $state->_main()->_add_to_total_iters(
-        PDL::sum((($r <= $state->_quota()) & ($r > 0)) * $r)
-    );
-    
-    # Find all the states that weren't solved.
-    my $indexes = PDL::which(($r > $state->_quota()) | ($r < 0));
-    
-    # Add the iterations for all the states that have not been solved
-    # yet.
-    $state->_main()->_add_to_total_iters($indexes->nelem() * $state->_quota());
-    
-    # Keep only the states that have not been solved yet.
-    $state->_main()->_scans_data(
-        $state->_main()->_scans_data()->dice($indexes, "X")->copy()
-    );
-}
-
-sub update_idx_slice
-{
-    my $state = shift;
-    my $r = $state->idx_slice()->copy();
-    # $r cannot be 0, because the ones that were 0, were already solved
-    # in $state->update_total_iters().
-    my $idx_slice = $state->idx_slice();
-    $idx_slice .= 
-        (($r > 0) * ($r - $state->_quota())) + 
-        (($r < 0) * ($r                  ));
-}
-
-sub _mark_as_used
-{
-    my $state = shift;
-
-    $state->_main()->_selected_scans()->[$state->_scan_idx()]->mark_as_used();
-
-    return;
-}
-
-sub _add_chosen
-{
-    my $state = shift;
-
-    push @{$state->_main()->chosen_scans()}, $state->get_chosen_struct();
-
-    return;
-}
-
-sub _update_total_boards_solved
-{
-    my $state = shift;
-
-    $state->_main()->_add_to_total_boards_solved($state->_num_solved());
-
-    return;
-}
-
-sub _trace_wrapper
-{
-    my $state = shift;
-
-    $state->_main()->_trace(
-        {
-            'iters_quota' => $state->_quota(),
-            'selected_scan_idx' => $state->_scan_idx(),
-            'total_boards_solved' => $state->_main()->_total_boards_solved(),
-        }
-    );
-
-    return;
-}
-
-sub register_params
-{
-    my $state = shift;
-
-    $state->_add_chosen();
-    $state->_mark_as_used();
-    $state->_update_total_boards_solved();
-    $state->_trace_wrapper();
-
-    return;
-}
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (c) 2010 Shlomi Fish
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-=cut
-
-1;

fc-solve/presets/soft-threads/meta-moves/auto-gen/Shlomif/FCS/CalcMetaScan/PostProcessor.pm

-package Shlomif::FCS::CalcMetaScan::PostProcessor;
-
-use strict;
-use warnings;
-
-use base 'Shlomif::FCS::CalcMetaScan::Base';
-
-__PACKAGE__->mk_acc_ref([qw(
-    _should_do_rle
-    _offset_quotas
-)]);
-
-sub _init
-{
-    my $self = shift;
-    my $args = shift;
-
-    $self->_should_do_rle($args->{do_rle});
-    $self->_offset_quotas($args->{offset_quotas});
-
-    return $self;
-}
-
-
-sub scans_rle
-{
-    my $self = shift;
-
-    my @scans_list = @{shift()};
-
-    my $scan = shift(@scans_list);
-
-    my (@a);
-    while (my $next_scan = shift(@scans_list))
-    {
-        if ($next_scan->scan() == $scan->scan())
-        {
-            $scan->iters( $scan->iters() + $next_scan->iters() );
-        }
-        else
-        {
-            push @a, $scan;
-            $scan = $next_scan;
-        }
-    }
-    push @a, $scan;
-    return \@a;
-}
-
-sub process
-{
-    my $self = shift;
-
-    my $scans_orig = shift;
-
-    # clone the scans.
-    my $scans = [ map { $_->clone(); } @{$scans_orig}];
-
-    if ($self->_offset_quotas)
-    {
-        $scans =
-        [
-            map { my $ret = $_->clone(); $ret->iters($ret->iters()+1); $ret; }
-            @$scans