I suppose I'd parse the expression into some kind of tree structure of objects along the lines of:
role Node; class Conjunction with Node { has left => (is => 'ro', does => 'Node'); has right => (is => 'ro', does => 'Node'); } class Disjunction with Node { has left => (is => 'ro', does => 'Node'); has right => (is => 'ro', does => 'Node'); } class Negation with Node { has negated_term => (is => 'ro', does => 'Node'); } class Primative with Node { has label => (is => 'ro', isa => Str); } my $fred = Primative->new(label => "Fred"); my $john = Primative->new(label => "John"); my $fred_and_john = Conjunction->new(left => $fred, right => $john); ...;
Then I'd write a few "visitor" rules that can take a tree and tweak it, for example, finding a candidate for rewriting under De Morgan's laws...
my $demorgans_laws = sub { my $tree = $_[0]; if ($tree->isa('Conjunction') and $tree->left->isa('Negation') and $tree->right->isa('Negation')) { return Negation->new( node => Disjunction->new( left => $tree->left->negated_term, right => $tree->right->negated_term, ), ); } if ($tree->isa('Disjunction') and $tree->left->isa('Negation') and $tree->right->isa('Negation')) { return Negation->new( node => Conjunction->new( left => $tree->left->negated_term, right => $tree->right->negated_term, ), ); } return $tree; };
Then use some kind of hill-climbing algorithm to apply the tweaking rules to the tree, creating new trees; discarding trees that become more complex than the original, and retaining trees that become simpler, or at least as simple.
The problem with hill-climbing is that you can find local maxima. If you're climbing a mountain, sometimes you find a small peak, and you need to climb downwards a bit before you can reach the true summit. This is a hard problem to solve without ending up with a completely undirected search. But luckily, it's a problem that many smart people have thought about, so there's a wealth of ideas on how to solve it if you delve into AI literature.
In reply to Re: Optimize a generic boolean expression
by tobyink
in thread Optimize a generic boolean expression
by tsk1979
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |