File Coverage

blib/lib/Logic/TruthTable/Convert81.pm
Criterion Covered Total %
statement 40 43 93.0
branch 7 10 70.0
condition 1 6 16.6
subroutine 8 8 100.0
pod 2 2 100.0
total 58 69 84.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Logic::TruthTable::Convert81 - provide Base81 encoding to Logic::TruthTable
4              
5             =cut
6              
7             package Logic::TruthTable::Convert81;
8              
9 14     14   66981 use strict;
  14         45  
  14         606  
10 14     14   97 use warnings;
  14         31  
  14         541  
11 14     14   364 use 5.016001;
  14         55  
12              
13 14     14   88 use Carp;
  14         33  
  14         1073  
14 14     14   100 use Exporter;
  14         37  
  14         569  
15 14     14   7737 use Convert::Base81 qw(b3_pack81 b3_unpack81 base81_check);
  14         130288  
  14         6790  
16              
17             our @ISA = qw(Exporter);
18              
19             our %EXPORT_TAGS = (
20             all => [ qw(
21             terms_to_base81
22             terms_from_base81
23             ) ],
24             );
25              
26             our @EXPORT_OK = (
27             @{$EXPORT_TAGS{all}},
28             );
29              
30             our $VERSION = 1.01;
31              
32             =head1 DESCRIPTION
33              
34             This module provides Base81 encoding of the truth table's columns
35             when saving the table in JSON format.
36              
37             =head2 FUNCTIONS
38              
39             =head3 terms_to_base81
40              
41             Take the terms of a truth table's column and pack it into a Base81 string.
42              
43             $col = $tt->fncolumn("f1");
44             $b81str = terms_to_base81($tt->width, $col->has_minterms,
45             $col->has_minterms? $col->minterms: $col->maxterms,
46             $col->dontcares);
47              
48             =cut
49              
50             sub terms_to_base81
51             {
52 6     6 1 2571 my($width, $isminterms, $termref, $dontcaresref)= @_;
53 6 100       26 my ($dfltbit, $setbit, $dcbit) = ($isminterms)? qw(0 1 -): qw(1 0 -);
54              
55             #
56             # Set up the list of trits to be packed into Base81 code.
57             #
58 6         43 my @blist = ($dfltbit) x (1 << $width);
59 6         12 map {$blist[$_] = $setbit} @{$termref};
  58         105  
  6         14  
60 6         15 map {$blist[$_] = $dcbit} (@{$dontcaresref});
  72         108  
  6         12  
61              
62 6         34 return b3_pack81("01-", \@blist);
63             }
64              
65             =head3 terms_from_base81
66              
67             Retrieve arrayrefs of the minterms, maxterms, and don't-cares of a
68             truth table's column from a Base81 string.
69              
70             (@min_max_dc) = terms_from_base81($width, $b81str);
71              
72             =cut
73              
74             sub terms_from_base81
75             {
76 4     4 1 752 my($width, $base81str) = @_;
77              
78             #
79             # Does the string we read in create a column of the correct length?
80             # (With the edge case exception width == 1, of course.)
81             #
82 4 0 0     25 unless (length($base81str) == (1 << ($width - 2)) or
      33        
83             (length($base81str) == 1 and $width == 1))
84             {
85 0         0 return (undef, undef, undef);
86             }
87              
88 4         20 my @char81 = split(//, $base81str);
89              
90 4 50       19 if (my $c_idx = base81_check($base81str) >= 0)
91             {
92 0         0 carp "Incorrect character '" . $char81[$c_idx] .
93             "' at position " . $c_idx .
94             "; cannot create columnlist";
95 0         0 return (undef, undef, undef);
96             }
97              
98 4         189 my(@maxterms, @minterms, @dontcares);
99 4         18 my @clist = b3_unpack81("01-", $base81str);
100              
101 4         368 for my $t (0 .. $#clist)
102             {
103 128         171 my $x = $clist[$t];
104 128 100       240 if ($x eq '1')
    100          
105             {
106 36         64 push @minterms, $t;
107             }
108             elsif ($x eq '0')
109             {
110 44         68 push @maxterms, $t;
111             }
112             else
113             {
114 48         78 push @dontcares, $t;
115             }
116             }
117              
118 4         38 return (\@minterms, \@maxterms, \@dontcares);
119             }
120              
121             =head1 SEE ALSO
122              
123             L<Convert::Base81>
124              
125             L<Logic::TruthTable::Util>
126              
127             =head1 AUTHOR
128              
129             John M. Gamble C<< <jgamble@cpan.org> >>
130              
131             =cut
132              
133             1;
134              
135             __END__
136