Here is a complete solution which uses Algorithm::QuineMcCluskey (this module throws a number of warnings but seems to work). I only tested it on your one expression, so if you are using it, let me know whether it works well or not.
use strict; use warnings; use List::Util 'sum'; use Algorithm::QuineMcCluskey; my $bool = 'Fred&Teddy&(Fred|Teddy)|(Fred)&(John)'; my @vars = keys %{{ map { $_ => 1 } $bool =~ /\b(\w+)\b/g }}; $bool =~ s/($_)/\$b\{${1}\}/g for @vars; my $n = @vars; my @table; my %b; for (0..2**$n-1) { @b{@vars} = split //, sprintf "%0${n}b", $_; push @table, $_ if eval $bool; } my $q = new Algorithm::QuineMcCluskey( width => $n, minterms => \@tabl +e ); my( $result )= $q->solve(); $result =~ s/\+/|/g; $result =~ s/([A-Z])'/!$1/g; $result =~ s#([A-Z]+)# join( "&", map { $vars[ord($_)-ord("A")] } spli +t //, $1 ) #ge; print "$result\n";
Update: I could not help playing a little with this code. If one uses the vec function instead of a hash for the variables, one can shorten the code to:
use strict; use warnings; use Algorithm::QuineMcCluskey; my $bool = 'Fred&Teddy&(Fred|Teddy)|(Fred)&(John)'; my @vars = keys %{{ map { $_ => 1 } $bool =~ /\b(\w+)\b/g }}; $bool =~ s/$vars[-$_]/vec(\$_,$_-1,1)/g for 1..@vars; my($result) = Algorithm::QuineMcCluskey->new( width => scalar @vars, minterms => [ grep { eval + $bool } 0..2**@vars-1 ] )->solve(); $result =~ s/\+/|/g; $result =~ s/([A-Z])'/!$1/g; $result =~ s#([A-Z]+)# join( "&", map { $vars[ord($_)-ord("A")] } spli +t //, $1 ) #ge; print "$result\n";
In reply to Re: Optimize a generic boolean expression
by hdb
in thread Optimize a generic boolean expression
by tsk1979
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |