Truth table printer

Etienne Grossmann <[email protected]>
Newsgroups gmane.comp.lang.perl.fun
Message-ID <[email protected]>
  Hi all,

this mail is just to share a little program 'ttable' that prints the
truth table of a logical expression using the perl operators plus <=>
(equivalence) and => (implication). For example:

  >> ttable "((A=>B)&&(B=>C)) => (A=>C)"
 
        A B C  |  ((A=>B)&&(B=>C)) => (A=>C)
        ------------------------------------
        0 0 0  |  1
        0 0 1  |  1
        0 1 0  |  1
        0 1 1  |  1
        1 0 0  |  1
        1 0 1  |  1
        1 1 0  |  1
        1 1 1  |  1

  At the heart, there is the code that is not optimized in any way.

    $_ = shift;
    $, = " ";
    s/([a-z]+)/\$$1/ig;
    @a{/(\$\w+)/g} = 1;
    @v = sort keys %a;
    ($t="@v  |  $_") =~ s/\$//g;
    s/<=>/==/g;
    s/=>/<=/g;
    ($l=$t) =~ s/./-/g;
    print "\n\t$t\n\t$l\n";
    eval join "",(map{"for $_ (0,1){"}@v),"print \"\\t@v  | \",(",$_,")*1,\"\\n\"","}"x@v, "\n";
    print "\n";

How much more concise could it be, beyond removing needless spaces?

The main problem is that the <=> and => operators have higher
precedence than the not operator !. Any cool ideas to change that?

  Cheers,

  Etienne

PS : I attach the whole script, with pod included (it prints its own
     documentation when run w/out argument).


-- 
Etienne Grossmann ------ http://www.cs.uky.edu/~etienne
ttable (text/plain, 1.2 KB)
#!/usr/bin/perl -w
exec "perldoc $0" unless @ARGV;
$_ = shift;
$, = " ";
s/([a-z]+)/\$$1/ig;
@a{/(\$\w+)/g} = 1;
@v = sort keys %a;
($t="@v  |  $_") =~ s/\$//g;
s/<=>/==/g;
s/=>/<=/g;
($l=$t) =~ s/./-/g;
print "\n\t$t\n\t$l\n";
eval join "",(map{"for $_ (0,1){"}@v),"print \"\\t@v  | \",(",$_,")*1,\"\\n\"","}"x@v, "\n";
print "\n";

=head1 ttable - Print truth table of a logical proposition

Prints the truth table of a logical proposition in which variable names
consist of any number of consecutive letters, true is 1, false is 0,
and operators are

  Not !     And &&    Or ||  

in that order of precedence. You may also use
 
  Then =>   Iff <=>

B<but their precedence is greater than that of "!" and they cannot be
chained>.

=head2 EXAMPLES

  >> ttable 'A && (B || A)'
 
        A B  |  A && (B || A)
        ---------------------
        0 0  |  0
        0 1  |  0
        1 0  |  1
        1 1  |  1
 
  >> ttable '(B && (B || A)) <=> B'
 
        A B  |  (B && (B || A)) <=> B
        -----------------------------
        0 0  |  1
        0 1  |  1
        1 0  |  1
        1 1  |  1
 
=head1 AUTHOR Etienne Grossmann E<lt>[email protected]<gt>

If you have never seen unreadable code, read this program's.

=cut
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.