Logic-TruthTable/lib/Logic/TruthTable/Convert81.pm
=head1 NAME
Logic::TruthTable::Convert81 - provide Base81 encoding to Logic::TruthTable
=cut
package Logic::TruthTable::Convert81;
use strict;
use warnings;
use 5.016001;
use Carp;
use Exporter;
use Convert::Base81 qw(b3_pack81 b3_unpack81 base81_check);
our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
all => [ qw(
terms_to_base81
terms_from_base81
) ],
);
our @EXPORT_OK = (
@{$EXPORT_TAGS{all}},
);
our $VERSION = 1.02;
=head1 DESCRIPTION
This module provides Base81 encoding of the truth table's columns
when saving the table in JSON format.
=head2 FUNCTIONS
=head3 terms_to_base81
Take the terms of a truth table's column and pack it into a Base81 string.
$col = $tt->fncolumn("f1");
$b81str = terms_to_base81($tt->width, $col->has_minterms,
$col->has_minterms? $col->minterms: $col->maxterms,
$col->dontcares);
=cut
sub terms_to_base81
{
my($width, $isminterms, $termref, $dontcaresref)= @_;
my ($dfltbit, $setbit, $dcbit) = ($isminterms)? qw(0 1 -): qw(1 0 -);
#
# Set up the list of trits to be packed into Base81 code.
#
my @blist = ($dfltbit) x (1 << $width);
map {$blist[$_] = $setbit} @{$termref};
map {$blist[$_] = $dcbit} (@{$dontcaresref});
return b3_pack81("01-", \@blist);
}
=head3 terms_from_base81
Retrieve arrayrefs of the minterms, maxterms, and don't-cares of a
truth table's column from a Base81 string.
(@min_max_dc) = terms_from_base81($width, $b81str);
=cut
sub terms_from_base81
{
my($width, $base81str) = @_;
#
# Does the string we read in create a column of the correct length?
# (With the edge case exception width == 1, of course.)
#
unless (length($base81str) == (1 << ($width - 2)) or
(length($base81str) == 1 and $width == 1))
{
return (undef, undef, undef);
}
my @char81 = split(//, $base81str);
if (my $c_idx = base81_check($base81str) >= 0)
{
carp "Incorrect character '" . $char81[$c_idx] .
"' at position " . $c_idx .
"; cannot create columnlist";
return (undef, undef, undef);
}
my(@maxterms, @minterms, @dontcares);
my @clist = b3_unpack81("01-", $base81str);
for my $t (0 .. $#clist)
{
my $x = $clist[$t];
if ($x eq '1')
{
push @minterms, $t;
}
elsif ($x eq '0')
{
push @maxterms, $t;
}
else
{
push @dontcares, $t;
}
}
return (\@minterms, \@maxterms, \@dontcares);
}
=head1 SEE ALSO
L<Convert::Base81>
L<Logic::TruthTable::Util>
=head1 AUTHOR
John M. Gamble C<< <jgamble@cpan.org> >>
=cut
1;
__END__