Algorithm-QuineMcCluskey

 view release on metacpan or  search on metacpan

lib/Algorithm/QuineMcCluskey.pm  view on Meta::CPAN

use Carp;

use Algorithm::QuineMcCluskey::Util qw(:all);
use List::Util qw(uniqnum);
use List::Compare::Functional qw(get_complement is_LequivalentR);

extends 'Logic::Minimizer';

#
# Vaguely consistent Smart-Comment rules:
# 3 pound signs for the code in BUILD() and generate_*() functions.
#
# 4 pound signs for code that manipulates prime/essentials/covers hashes:
#      row_dominance().
#
# 5 pound signs for the solve() and recurse_solve() code, and the remels()
# calls.
#
# The ::Format package is only needed for Smart Comments -- comment or uncomment
# in concert with Smart::Comments as needed.
#
#use Algorithm::QuineMcCluskey::Format qw(arrayarray hasharray chart);
#use Smart::Comments ('###', '#####');

#
# Attributes inherited from Logic::Minimizer are width, minterms, maxterms,
# dontcares, columnstring, title, dc, vars, primes, essentials, covers,
# group_symbols, order_by, and minonly.
#

#
# The '_bits' fields are the terms' bitstring fields, and are
# internal attributes. No setting them at object creation.
#
has 'dc_bits'	=> (
	isa => 'ArrayRef[Str]', is => 'rw', required => 0,
	init_arg => undef,
	predicate => 'has_dc_bits'
);
has 'min_bits'	=> (
	isa => 'ArrayRef[Str]', is => 'rw', required => 0,
	init_arg => undef,
	predicate => 'has_min_bits'
);
has 'max_bits'	=> (
	isa => 'ArrayRef[Str]', is => 'rw', required => 0,
	init_arg => undef,
	predicate => 'has_max_bits'
);

our $VERSION = 1.01;

sub BUILD
{
	my $self = shift;
	my $w = $self->width;
	my $last_idx = (1 << $w) - 1;
	my @terms;

	#
	# Catch errors involving minterms, maxterms, and don't-cares.
	#
	$self->catch_errors();

	#
	# We've gotten past the error-checking. Create the object.
	#
	if ($self->has_columnstring)
	{
		my($min_ref, $max_ref, $dc_ref) =
			$self->list_to_terms(split(//, $self->columnstring));

		### min_ref: $min_ref
		### max_ref: $max_ref
		### don't cares: $dc_ref

		$self->minterms($min_ref) if (scalar @{$min_ref} );
		$self->dontcares($dc_ref) if (scalar @{$dc_ref} );
	}

	if ($self->has_minterms)
	{
		@terms = sort(uniqnum(@{$self->minterms}));

		my @bitstrings = map {
			substr(unpack("B32", pack("N", $_)), -$w)
		} @terms;

		$self->min_bits(\@bitstrings);
		### Min terms binary: $self->min_bits()
	}
	if ($self->has_maxterms)
	{
		@terms = sort(uniqnum(@{$self->maxterms}));

		my @bitstrings = map {
			substr(unpack("B32", pack("N", $_)), -$w)
		} @terms;

		$self->max_bits(\@bitstrings);
		### Max terms binary: $self->max_bits()
	}

	if ($self->has_dontcares)
	{
		my @dontcares = sort(uniqnum(@{$self->dontcares}));

		my @bitstrings = map {
			substr(unpack("B32", pack("N", $_)), -$w)
		} @dontcares;

		$self->dc_bits(\@bitstrings);
		### Don't-cares binary: $self->dc_bits()
	}

	$self->title("$w-variable truth table") unless ($self->has_title);

	return $self;
}

sub complement_terms
{
	my $self = shift;
	my @bitlist = (0 .. (1 << $self->width) - 1);
	my @termlist = @{$self->dontcares} if ($self->has_dontcares);



( run in 1.064 second using v1.01-cache-2.11-cpan-13bb782fe5a )