The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Logic::TruthTable - Create and solve sets of boolean equations.

VERSION

Version 1.01

SYNOPSIS

Create a truth table.

    #
    # Create a truth table for converting zero to nine (binary)
    # to a 2-4-2-1 code.
    #
    my $tt_2421 = Logic::TruthTable->new(
        width => 4,
        algorithm => 'QuineMcCluskey',
        title => "A four-bit binary to 2-4-2-1 converter",
        vars => ['w' .. 'z'],
        functions => [qw(a3 a2 a1 a0)],
        columns => [
            {
                title => "Column a3",
                minterms => [ 5 .. 9 ],
                dontcares => [ 10 .. 15 ],
            },
            {
                title => "Column a2",
                minterms => [ 4, 6 .. 9 ],
                dontcares => [ 10 .. 15 ],
            },
            {
                title => "Column a1",
                minterms => [ 2, 3, 5, 8, 9 ],
                dontcares => [ 10 .. 15 ],
            },
            {
                title => "Column a0",
                minterms => [ 1, 3, 5, 7, 9 ],
                dontcares => [ 10 .. 15 ],
            },
        ],
    );

    #
    # Get and print the results.
    #
    my @solns = $tt_2421 ->solve();
    print join("\n\n", @solns), "\n";

    #
    # Save the truth table values as a CSV file.
    #
    open my $fh_csv, ">", "twofourtwoone.csv" or die "Error opening CSV file.";
    $tt_2421 ->export_csv(write_handle => \$fh_csv);
    close $fh_csv or warn "Error closing CSV file: $!";

    #
    # Or save the truth table values as a JSON file.
    #
    open my $fh_json, ">", "twofourtwoone.json" or die "Error opening JSON file.";
    $tt_2421 ->export_json(write_handle => \$fh_json);
    close $fh_json or warn "Error closing JSON file: $!";

Description

This module minimizes tables of Boolean expressions using the algorithms available on CPAN.

It lets you contain related sets of problems (represented by their columns) in a single object, along with the variable names, function names, and title. Methods exist to import from and export to CSV and JSON files.

Object Methods

new()

Create the truth table object. The attributes are:

'width'

The number of variables (input columns) in the Boolean expressions.

This is a required attribute.

'title'

A title for the problem you are solving.

'dc'

Default value: '-'

Change the representation of the don't-care character. The don't-care character is used in the columnstring, as character in exported CSV files, and internally as a place holder for eliminated variables in the equation, which may be examined with other methods.

This becomes the default value of the function columns; it may be individually overridden in each columns attribute.

'vars'

Default value: ['A' .. 'Z']

The variable names used to form the equation. The names will be taken from the leftmost first.

This becomes the default names of the vars attribute of the function columns; it may be individually overridden in each columns attribute.

'functions'

Default value: ['F0' .. 'F9', 'F10' .. 'F31']

The function names of each equation.

The function name becomes the default title of the individual column if the column doesn't set a title.

'algorithm'

The default algorithm that will be used to minimize each column.

Currently, there is only one minimizer algorithm ("Algorithm::QuineMcCluskey") available on CPAN, and it is the default.

The name will come from the package name, e.g., having an attribute algorithm => 'QuineMcCluskey' means that the column will be minimized using the package Algorithm::QuineMcCluskey.

The algorithm module must be installed and be of the form Algorithm::Name. The module must also have Logic::Minimizer as its parent class. This ensures that it will have the methods needed by Logic::TruthTable to create and solve the Boolean expressions.

This becomes the default value of the function columns; it may be individually overridden in each columns's attribute.

'columns'

An array of hash references. Each hash reference contains the key/value pairs used to define the Boolean expression. These are used to create a minimizer object, which in turn solves the expression.

'minterms'

An array reference of terms representing the 1-values of the Boolean expression.

'maxterms'

An array reference of terms representing the 0-values of the Boolean expression. This will also indicate that you want the expression in product-of-sum form, instead of the default sum-of-product form.

'dontcares'

An array reference of terms representing the don't-care-values of the Boolean expression. These represent inputs that simply shouldn't happen (e.g., numbers 11 through 15 in a base 10 system), and therefore don't matter to the result.

'columnstring'

Present the entire list of values of the boolean expression as a single string. The values are ordered from left to right in the string. For example, a simple two-variable AND equation would have a string "0001".

You can use only one of minterms, maxterms, or columnstring.

The minterms or maxterms do not have to be created by hand; there are functions in "Logic::TruthTable::Util" to help create the terms.

'dc'

Change the representation of the don't-care character. The don't-care character is used both in the columnstring, and internally as a place holder for eliminated variables in the equation. Defaults to the character defined in the Logic::TruthTable object.

'title'

A title for the expression you are solving. Defaults to the function name defined in the Logic::TruthTable object.

'vars'

Default value: ['A' .. 'Z']

The variable names used to form the equation. Defaults to the variable names defined in the Logic::TruthTable object.

    #
    # Create a "Rock-Paper-Scissors winners" truth table, using
    # the following values:
    #
    # Columns represent (in two bits) the winner of Rock (01)
    # vs. Paper (10), or vs. Scissors (11). A tie is 00.
    #
    # 
    #        a1 a0 b1 b0 ||  w1 w0
    #       -----------------------
    #  0     0  0  0  0  ||  -  -
    #  1     0  0  0  1  ||  -  -
    #  2     0  0  1  0  ||  -  -
    #  3     0  0  1  1  ||  -  -
    #  4     0  1  0  0  ||  -  -
    #  5     0  1  0  1  ||  0  0    (tie)
    #  6     0  1  1  0  ||  1  0    (paper)
    #  7     0  1  1  1  ||  0  1    (rock)
    #  8     1  0  0  0  ||  -  -
    #  9     1  0  0  1  ||  1  0    (paper)
    # 10     1  0  1  0  ||  0  0    (tie)
    # 11     1  0  1  1  ||  1  1    (scissors)
    # 12     1  1  0  0  ||  -  -
    # 13     1  1  0  1  ||  0  1    (rock)
    # 14     1  1  1  0  ||  1  1    (scissors)
    # 15     1  1  1  1  ||  0  0    (tie)
    #

    use Logic::TruthTable;

    my $ttbl = Logic::TruthTable->new(
        width => 4,
        algorithm => 'QuineMcCluskey',
        title => 'Rock Paper Scissors Winner Results',
        vars => ['a1', 'a0', 'b1', 'b0'],
        functions => ['w1', 'w0'],
        columns => [
            {
                title => 'Bit 1 of the result.',
                minterms => [6, 9, 11, 14],
                dontcares => [0 .. 4, 8, 12],
            },
            {
                title => 'Bit 0 of the result.',
                minterms => [7, 11, 13, 14],
                dontcares => [0 .. 4, 8, 12],
            },
        ],
    );

Alternatively, it is possible to pre-create the algorithm minimizer objects, and use them directly in the columns array, although it does result in a lot of duplicated code:

    my $q1 = Algorithm::QuineMcCluskey->new(
        title => "Column 1 of RPS winner results";
        width => 4,
        minterms => [ 2, 3, 5, 8, 9 ],
        dontcares => [ 10 .. 15 ],
        vars => ['w' .. 'z'],
    );
    my $q0 = Algorithm::QuineMcCluskey->new(
        title => "Column 0 of RPS winner results";
        width => 4,
        minterms => [ 1, 3, 5, 7, 9 ],
        dontcares => [ 10 .. 15 ],
        vars => ['w' .. 'z'],
    );

    #
    # Create the truth table using the above
    # Algorithm::QuineMcCluskey objects.
    #
    my $tt_rps = Logic::TruthTable->new(
        width => 4,
        title => 'Rock Paper Scissors Winner Results',
        functions => [qw(w1 w0)],
        columns => [$q1, $q0],
    );

solve()

Run the columns of the truth table through their solving methods. Each column's solution is returned in a list.

A way to view the solutions would be:

    my @equations = $tt->solve();

    print join("\n", @equations), "\n";

fnsolve()

Like solve(), run the columns of the truth table through their solving methods, but store the solutions in a hash table using each column's function name as a key.

all_solutions()

It is possible that there's more than one equation that solves a column's boolean expression. Therefore solve() can return a different (but equally valid) equation on separate runs.

If you wish to examine all the possible equations that solve an individual column, you may call all_solutions using the columns name.

    print "All possible equations for column F0:\n";
    print join("\n\t", $tt->all_solutions("F0")), "\n";

fncolumn()

Return a column object by name.

The columns of a Logic::TruthTable object are themselves objects, of types Algorithm::Name, where Name is the algorithm, and which may be set using the algorithm parameter in new(). (As of this writing, the only algorithm availble in the CPAN ecosystem is Algorithm::QuineMcCluseky.)

Each column is named via the functions attribute in new(), and a column can be retrieved using its name.

    my $ttable = Logic::TruthTable->new(
        title => "An Example",
        width => 5,
        functions => ['F1', 'F0'],
        columns => [
            {
                minterms => [6, 9, 23, 27],
                dontcares => [0, 2, 4, 16, 24],
            },
            {
                minterms => [7, 11, 19, 23, 29, 30],
                dontcares => [0, 2, 4, 16, 24],
            },
        ],
    );

    my $col_f0 = $ttable->fncolumn('F0');

$col_f0 will be an Algorithm::QuineMcCluskey object with minterms (7, 11, 19, 23, 29, 30).

export_csv()

export_json()

Write the truth table out as either a CSV file or a JSON file.

In either case, the calling code opens the file and provides the file handle:

    open my $fh_nq, ">:encoding(utf8)", "nq_6.json"
        or die "Can't open export file: $!";

    $tt->export_json(write_handle => $fh_nq);

    close $fh_nq or warn "Error closing JSON file: $!";

Making your code handle the opening and closing of the file may seem like an unnecessary inconvenience, but one benefit is that it allows you to make use of STDOUT:

    $tt->export_csv(write_handle => \*STDOUT, dc => 'X');

A CSV file can store the varible names, function names, minterms, maxterms, and don't-care terms. The don't-care character of the object may be overridden with your own choice by using the dc parameter. Whether the truth table uses minterms or maxterms will have to be a choice made when importing the file (see "import_csv()").

CSV is a suitable format for reading by other programs, such as spreadsheets, or the program Logic Friday, a tool for working with logic functions.

In the example below, a file is being written out for reading by Logic Friday. Note that Logic Friday insists on its own don't-care character, which we can set with the 'dc' option:

    if (open my $fh_mwc, ">", "ttmwc.csv")
    {
        #
        # Override the don't-care character, as Logic Friday
        # insists on it being an 'X'.
        #
        $truthtable->export_csv(write_handle => $fh_mwc, dc => 'X');

        close $fh_mwc or warn "Error closing CSV file: $!";
    }
    else
    {
        warn "Error opening CSV file: $!";
    }

The JSON file will store all of the attributes that were in the truth table, except for the algorithm, which will have to be set when importing the file.

The options are:

write_handle

The opened file handle for writing.

dc

The don't-care symbol to use in the file. In the case of the CSV file, becomes the character to write out. In the case of the JSON file, will become the truth table's default character.

The method returns undef if an error is encountered. On success it returns the truth table object.

import_csv()

import_json()

Read a previously written CSV or JSON file and create a Logic::TruthTable object from it.

    #
    # Read in a JSON file.
    #
    if (open my $fh_x3, "<:encoding(utf8)", "excess_3.json")
    {
        $truthtable = Logic::TruthTable->import_json(
            read_handle => $fh_x3,
            algorithm => $algorithm,
        );
        close $fh_x3 or warn "Error closing JSON file: $!";
    }


    #
    # Read in a CSV file.
    #
    if (open my $lf, "<", "excess_3.csv")
    {
        $truthtable = Logic::TruthTable->import_csv(
            read_handle => $lf,
            dc => '-',
            algorithm => $algorithm,
            title => 'Four bit Excess-3 table',
            termtype => 'minterms',
        );
        close $lf or warn "Error closing CSV file: $!";
    }

Making your code handle the opening and closing of the file may seem like an unnecessary inconvenience, but one benefit is that it allows you to make use of STDIN or the __DATA__ section:

    my $ttable = Logic::TruthTable->import_csv(
        title => "Table created from __DATA__ section.",
        read_handle => \*DATA,
    );
    print $ttable->fnsolve();
    exit(0);
    __DATA__
    c2,c1,c0,,w1,w0
    0,0,0,,X,0
    0,0,1,,X,X
    0,1,0,,X,X
    0,1,1,,X,1
    1,0,0,,X,X
    1,0,1,,0,X
    1,1,0,,1,1
    1,1,1,,0,1

The attributes read in may be set or overridden, as the file may not have the attributes that you want. CSV files in particular do not have a title or termtype, and without the dc option the truth table's don't-care character will be the object's default character, not what was stored in the file.

You can set whether the truth table object is created using its minterms or its maxterms by using the termtype attribute:

    $truthtable = Logic::TruthTable->import_csv(
        read_handle => $lf,
        termtype => 'maxterms',        # or 'minterms'.
    );

By default the truth table is created with minterms.

In addition to the termtype, you may also set the title, don't-care character, and algorithm attributes. Width, variable names, and function names cannot be set as these are read from the file.

    $truthtable = Logic::TruthTable->import_json(
        read_handle => $fh_x3,
        title => "Excess-3 multiplier",
        dc => '.',
        algorithm => 'QuineMcCluskey'
    );

The options are:

read_handle

The opened file handle for reading.

dc

The don't-care symbol to use in the truth table. In the case of the CSV file, becomes the default character of the table and its columns. In the case of the JSON file, becomes the truth table's default character, but may not be an individual column's character if it already has a value set.

algorithm

The truth table's algorithm of choice. The algorthm's module must be one that is intalled, or the truth table object will fail to build.

title

The title of the truth table.

termtype

The terms to use when creating the columns. May be either minterms (the default) or maxterms.

The method returns undef if an error is encountered.

AUTHOR

John M. Gamble, <jgamble at cpan.org>

BUGS

Please report any bugs or feature requests to bug-logic-truthtable at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Logic-TruthTable. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

This module is on Github at https://github.com/jgamble/Logic-TruthTable

You can also look for information on MetaCPAN

SEE ALSO

  • Introduction To Logic Design, by Sajjan G. Shiva, 1998.

  • Discrete Mathematics and its Applications, by Kenneth H. Rosen, 1995

  • Logic Friday ("Free software for boolean logic optimization, analysis, and synthesis.") was located on its website until some time after 4 February 2018, at which point it shut down. It was enormously useful, and can still be found on The Wayback Machine.

    It has two forms of its export format, a standard CSV file, and a minimized version of the CSV file that unfortunately was not documented. This is why only the standard CSV file can be read or written.

LICENSE AND COPYRIGHT

Copyright (c) 2019 John M. Gamble. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://dev.perl.org/licenses/ for more information.