Algorithm-CP-IZ
view release on metacpan or search on metacpan
t/02search.t view on Meta::CPAN
use strict;
use warnings;
use Test::More tests => 122;
BEGIN { use_ok('Algorithm::CP::IZ') };
{
my $iz = Algorithm::CP::IZ->new();
my $v = $iz->create_int(0, 10);
$iz->search([$v]);
is($v->min, 0);
is($v->max, 0);
is($v->value, 0);
is($v->nb_elements, 1);
}
# default search
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(0, 10);
my $v2 = $iz->create_int(0, 10);
$iz->AllNeq([$v1, $v2]);
my $rc = $iz->search([$v1, $v2]);
is($rc, 1);
is($v1->value, 0);
is($v2->value, 1);
}
# search error
{
my $iz = Algorithm::CP::IZ->new();
my $err = 1;
eval {
my $rc = $iz->search(["x"]);
$err = 0;
};
my $msg = $@;
is($err, 1);
ok($msg =~ /^Algorithm::CP::IZ:/);
eval {
my $rc = $iz->search([undef]);
$err = 0;
};
$msg = $@;
is($err, 1);
ok($msg =~ /^Algorithm::CP::IZ:/);
}
# default search (use Default)
{
use Algorithm::CP::IZ::FindFreeVar;
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(0, 10);
my $v2 = $iz->create_int(0, 10);
$iz->AllNeq([$v1, $v2]);
my $rc = $iz->search([$v1, $v2],
{ FindFreeVar => Algorithm::CP::IZ::FindFreeVar::Default, }
);
is($rc, 1);
is($v1->value, 0);
is($v2->value, 1);
}
# default search (using NbElements)
{
use Algorithm::CP::IZ::FindFreeVar;
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(0, 10);
my $v2 = $iz->create_int(0, 5);
$iz->AllNeq([$v1, $v2]);
my $rc = $iz->search([$v1, $v2],
{ FindFreeVar
=> Algorithm::CP::IZ::FindFreeVar::NbElements, }
);
is($rc, 1);
# v2 must be found first.
is($v1->value, 1);
is($v2->value, 0);
}
# search eror (FindFreeVar)
t/02search.t view on Meta::CPAN
my $v2 = $iz->create_int(1, 2);
$iz->AllNeq([$v1, $v2]);
my @r;
my $callback = sub {
my $var_array = shift;
push(@r, [map { $_->value } @$var_array]);
};
my $rc = $iz->find_all([$v1, $v2], $callback,
{ FindFreeVar
=> Algorithm::CP::IZ::FindFreeVar::NbElements, });
is($rc, 1);
is_deeply($r[0], [2, 1]);
is_deeply($r[1], [3, 1]);
is_deeply($r[2], [1, 2]);
is_deeply($r[3], [3, 2]);
}
# find_all using (using NbElements)
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(1, 3);
my $v2 = $iz->create_int(1, 2);
$iz->AllNeq([$v1, $v2]);
my $func_used = 0;
my $func = sub {
my $array = shift;
my $n = scalar @$array;
for my $i (0..$n-1) {
return $i if ($array->[$i]->is_free);
}
$func_used = 1;
return -1;
};
my @r;
my $callback = sub {
my $var_array = shift;
push(@r, [map { $_->value } @$var_array]);
};
my $rc = $iz->find_all([$v1, $v2], $callback,
{ FindFreeVar => $func });
is($rc, 1);
is($func_used, 1);
is_deeply($r[0], [1, 2]);
is_deeply($r[1], [2, 1]);
is_deeply($r[2], [3, 1]);
is_deeply($r[3], [3, 2]);
}
# find_all error (callback)
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(1, 3);
my $v2 = $iz->create_int(1, 2);
my $err = 1;
eval {
my $rc = $iz->find_all([$v1, $v2], undef,
{ FindFreeVar => undef });
};
my $msg = $@;
is($err, 1);
ok($msg =~ /^Algorithm::CP::IZ:/);
}
# find_all error (FindFreeVar)
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(1, 3);
my $v2 = $iz->create_int(1, 2);
my $err = 1;
eval {
my $rc = $iz->find_all([$v1, $v2], sub {},
{ FindFreeVar => undef });
};
my $msg = $@;
is($err, 1);
ok($msg =~ /^Algorithm::CP::IZ:/);
}
# backtrack
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(1, 3);
my $v2 = $iz->create_int(1, 3);
my $b1called = 0;
my $b2called = 0;
my $btvar = undef;
my $btindex = -999;
my $b1 = sub {
my ($v, $i) = @_;
$b1called = 1;
$btvar = $v;
$btindex = $i;
};
my $b2 = sub {
my ($v, $i) = @_;
$b2called = 1;
$btvar = $v;
$btindex = $i;
};
$iz->save_context;
$iz->backtrack($v1, 123, $b1);
$iz->save_context;
$iz->backtrack($v2, 456, $b2);
is($b1called, 0);
is($b2called, 0);
$iz->restore_context;
is($b2called, 1);
is($v2->key, $btvar->key);
is($btindex, 456);
$iz->restore_context;
is($b1called, 1);
is($v1->key, $btvar->key);
is($btindex, 123);
t/02search.t view on Meta::CPAN
$iz->restore_context_until($label);
is($v1->nb_elements, 3);
}
# forget save context
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(0, 10);
$iz->save_context(); # restored here
ok($v1->Ge(1));
$iz->save_context(); # forgotton
ok($v1->Ge(2));
$iz->forget_save_context();
is($v1->min, 2);
$iz->restore_context;
is($v1->min, 0);
}
# forget save context until
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(0, 10);
$iz->save_context();
ok($v1->Ge(1));
$iz->save_context(); # restore here
ok($v1->Ge(2));
my $label = $iz->save_context(); # forgotton
ok($v1->Ge(3));
$iz->save_context();
ok($v1->Ge(4));
$iz->forget_save_context_until($label);
is($v1->min, 4);
$iz->restore_context;
is($v1->min, 1);
}
# cancel (call only)
SKIP: {
my $iz = Algorithm::CP::IZ->new();
skip "old iZ", 1
unless (defined($iz->get_version)
&& $iz->IZ_VERSION_MAJOR >= 3
&& $iz->IZ_VERSION_MINOR >= 6);
$iz->cancel_search;
ok(1);
}
# FindFreeVar error
{
my $iz = Algorithm::CP::IZ->new();
my $rc = -1234;
my $v = $iz->create_int(0, 9);
my $vs = $iz->get_value_selector(&Algorithm::CP::IZ::CS_VALUE_SELECTOR_MIN_TO_MAX);
my $label = $iz->save_context;
# nothing returned
eval {
$rc = $iz->search([$v],
{
FindFreeVar => sub {
return;
},
});
};
# error
ok($@);
is($rc, -1234);
$iz->restore_context_until($label);
$label = $iz->save_context;
# bad value
eval {
$rc = $iz->search([$v],
{
FindFreeVar => sub {
return "x";
},
});
};
# error
ok($@);
is($rc, -1234);
$iz->restore_context_until($label);
$label = $iz->save_context;
# out of range
eval {
$rc = $iz->search([$v],
{
FindFreeVar => sub {
return 1; # must be 0;
},
});
};
ok($@);
is($rc, -1234);
}
# Criteria error
{
my $iz = Algorithm::CP::IZ->new();
my $v1 = $iz->create_int(0, 10);
my $v2 = $iz->create_int(0, 10);
$iz->AllNeq([$v1, $v2]);
my $label = $iz->save_context;
# nothing returned
my $rc = -1234;
eval {
$rc = $iz->search([$v1, $v2],
{
Criteria => sub {
return;
},
});
};
ok($@);
is($rc, -1234);
$iz->restore_context_until($label);
$label = $iz->save_context;
eval {
$rc = $iz->search([$v1, $v2],
{
Criteria => sub {
return "x";
},
});
};
ok($@);
is($rc, -1234);
}
# MaxFailFunc error
SKIP: {
my $iz = Algorithm::CP::IZ->new();
skip "old iZ", 1
unless (defined($iz->get_version)
&& $iz->IZ_VERSION_MAJOR >= 3
&& $iz->IZ_VERSION_MINOR >= 6);
my $rc = -1234;
my $v = $iz->create_int(0, 9);
my $vs = $iz->get_value_selector(&Algorithm::CP::IZ::CS_VALUE_SELECTOR_MIN_TO_MAX);
my $label = $iz->save_context;
# nothing returned
eval {
$rc = $iz->search([$v],
{
ValueSelectors => [$vs],
MaxFailFunc => sub {
return;
}
});
};
# error
ok($@);
is($rc, -1234);
$iz->restore_context_until($label);
$label = $iz->save_context;
# not a integer
eval {
$rc = $iz->search([$v],
{
ValueSelectors => [$vs],
MaxFailFunc => sub {
return "x";
}
});
};
# error
ok($@);
is($rc, -1234);
}
# MaxFailFunc only
SKIP: {
my $iz = Algorithm::CP::IZ->new();
skip "old iZ", 1
unless (defined($iz->get_version)
&& $iz->IZ_VERSION_MAJOR >= 3
&& $iz->IZ_VERSION_MINOR >= 6);
my $v = $iz->create_int(0, 9);
my $vs = $iz->get_value_selector(&Algorithm::CP::IZ::CS_VALUE_SELECTOR_MIN_TO_MAX);
my $rc = $iz->search([$v],
{
MaxFailFunc => sub {
return 1;
}
});
is($rc, 1);
is($v->value, 0);
}
# search with CriteriaEmulation
{
my $iz = Algorithm::CP::IZ->new();
my $criteria_used = 0;
my $max_fail_used = 0;
my $func = sub {
my ($index, $val) = @_;
$criteria_used = 1;
if ($index == 0) {
return $val ==4 ? 0 : 100;
}
if ($index == 1) {
return $val ==5 ? 0 : 100;
}
return 0;
};
my $v1 = $iz->create_int(0, 10);
my $v2 = $iz->create_int(0, 10);
$iz->AllNeq([$v1, $v2]);
my $rc = $iz->search([$v1, $v2],
{ Criteria => $func,
MaxFailFunc => sub {
$max_fail_used = 1;
return 1;
}
}
);
is($rc, 1);
is($criteria_used, 1);
is($max_fail_used, 1);
( run in 1.444 second using v1.01-cache-2.11-cpan-2398b32b56e )