Acme-Test-LogicalEquivalence
view release on metacpan or search on metacpan
bin/test-logical-equivalence view on Meta::CPAN
#!perl
# ABSTRACT: Test if expressions are logically equivalent
# PODNAME: test-logical-equivalence
use 5.008;
use warnings FATAL => 'all';
use strict;
use Test::More;
use Acme::Test::LogicalEquivalence qw(is_logically_equivalent);
sub usage {
print <<END;
$0 EXPR1 EXPR2
Test if two simple expressions are logically equivalent.
Exactly two expressions must be given.
Example: $0 '\$a || \$b' '\$b || \$a'
Remember that you may need to escape special characters like "\$" from your shell.
END
exit 1;
}
sub find_num_vars {
my $expr = shift;
my $highest = -1;
# check for scalars that look like $a or $b
for my $varname ($expr =~ /\$([a-z])/g) {
my $num = ord($varname) - 97;
$highest = $num if $highest < $num;
}
# check for scalars that index $_
for my $varname ($expr =~ /\$_\[(\d+)\]/g) {
my $num = $varname;
$highest = $num if $highest < $num;
}
return $highest + 1;
}
my $expr1 = shift or usage;
my $expr2 = shift or usage;
my $numvars1 = find_num_vars($expr1);
my $numvars2 = find_num_vars($expr2);
my $num = $numvars1 > $numvars2 ? $numvars1 : $numvars2;
if ($num < 1) {
print STDERR 'No variables detected. Variables should be one or more of $a, $b, ..., $z', "\n";
exit 2;
}
# convert $a-style vars to $_[0]-style to support more than just $a and $b
$expr1 =~ s/\$([a-z])/'$_['.(ord($1) - 97).']'/ge;
$expr2 =~ s/\$([a-z])/'$_['.(ord($1) - 97).']'/ge;
my $sub1 = eval "sub { $expr1 }" or die "Expression 1: $@\n"; ## no critic (ProhibitStringyEval)
my $sub2 = eval "sub { $expr2 }" or die "Expression 2: $@\n"; ## no critic (ProhibitStringyEval)
plan tests => (2 ** $num);
note "Testing for logical equivalence of two expressions with $num variable(s)...";
my $equivalence = is_logically_equivalent($num, $sub1, $sub2);
note $equivalence ? 'Logical equivalence proved!' : 'Bummer...';
__END__
=pod
=encoding UTF-8
=head1 NAME
test-logical-equivalence - Test if expressions are logically equivalent
=head1 VERSION
version 0.001
=head1 SYNOPSIS
# be sure to escape $ and other special characters from your shell
test-logical-equivalence '$a && $b' '$b && $a'
=head1 SEE ALSO
=over 4
=item *
L<Acme::Test::LogicalEquivalence>
=back
=head1 AUTHOR
Charles McGarvey <chazmcgarvey@brokenzipper.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2016 by Charles McGarvey.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
( run in 2.042 seconds using v1.01-cache-2.11-cpan-98e64b0badf )