Algorithm-SAT-Backtracking
view release on metacpan or search on metacpan
lib/Algorithm/SAT/Expression.pm view on Meta::CPAN
package Algorithm::SAT::Expression;
use 5.008001;
use strict;
use warnings;
require Algorithm::SAT::Backtracking;
use Carp qw(croak);
our $VERSION = "0.13";
# Boolean expression builder. Note that the connector for clauses is `OR`;
# so, when calling the instance methods `xor`, `and`, and `or`, the clauses
# you're generating are `AND`ed with the existing clauses in the expression.
sub new {
return bless {
_literals => {},
_expr => [],
_implementation => "Algorithm::SAT::Backtracking"
},
shift;
}
sub with {
my $self = shift;
if ( eval "require $_[0];1;" ) {
$self->{_implementation} = shift;
$self->{_implementation}->import();
}
else {
croak "The '$_[0]' could not be loaded";
}
return $self;
}
# ### or
# Add a clause consisting of the provided literals or'ed together.
sub or {
my $self = shift;
$self->_ensure(@_);
push( @{ $self->{_expr} }, [@_] );
return $self;
}
# ### xor
# Add clauses causing each of the provided arguments to be xored.2
sub xor {
# This first clause is the 'or' portion. "One of them must be true."
my $self = shift;
my @literals = @_;
push( @{ $self->{_expr} }, \@_ );
$self->_ensure(@literals);
# Then, we generate clauses such that "only one of them is true".
for ( my $i = 0; $i <= $#literals; $i++ ) {
for ( my $j = $i + 1; $j <= $#literals; $j++ ) {
push(
@{ $self->{_expr} },
[ $self->negate_literal( $literals[$i] ),
$self->negate_literal( $literals[$j] )
]
);
}
}
return $self;
}
# ### and
# Add each of the provided literals into their own clause in the expression.
sub and {
my $self = shift;
$self->_ensure(@_);
push( @{ $self->{_expr} }, [$_] ) for @_;
return $self;
}
( run in 0.332 second using v1.01-cache-2.11-cpan-39bf76dae61 )