From 0d4a03dcd85996d9abf61a189eec777bb7869dd4 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Wed, 20 Nov 2002 20:12:48 +0000 Subject: [PATCH] * lib/Automake/Conditional.pm [SYNOPSIS]: Fix not's description. * lib/Automake/ConditionalSet.pm (sub_conditions): New function. (multiply): Also accept an Automake::Conditional as argument. * automake.in (variable_not_always_defined_in_cond): Simplify, using only Automake::ConditionalSet methods. Suggested by Raja R Harinath. --- ChangeLog | 7 +++ automake.in | 47 +++++-------------- lib/Automake/Conditional.pm | 4 +- lib/Automake/ConditionalSet.pm | 60 +++++++++++++++++++++++- lib/Automake/tests/ConditionalSet.pl | 68 +++++++++++++++++++++++++++- 5 files changed, 147 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43cc305a..59c191ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2002-11-20 Alexandre Duret-Lutz + * lib/Automake/Conditional.pm [SYNOPSIS]: Fix not's description. + * lib/Automake/ConditionalSet.pm (sub_conditions): New function. + (multiply): Also accept an Automake::Conditional as argument. + * automake.in (variable_not_always_defined_in_cond): Simplify, + using only Automake::ConditionalSet methods. + Suggested by Raja R Harinath. + * lib/Automake/ConditionalSet.pm (conds): Use value() to simplify. (invert): Rewrite as a product-of-sums to sum-of-products converter. (_multiply, multiply): New functions. diff --git a/automake.in b/automake.in index 164255ea..9a5c4774 100755 --- a/automake.in +++ b/automake.in @@ -6119,18 +6119,15 @@ sub conditional_ambiguous_p ($$$) # C = mumble # # we should have (we display result as conditional strings in this -# illustration, but we really return Conditional objects): +# illustration, but we really return ConditionalSet objects): # variable_not_always_defined_in_cond ('A', 'COND1_TRUE COND2_TRUE') # => () # variable_not_always_defined_in_cond ('A', 'COND1_TRUE') # => () # variable_not_always_defined_in_cond ('A', 'TRUE') -# => ("COND1_FALSE COND2_FALSE COND3_FALSE", -# "COND1_FALSE COND2_TRUE COND3_FALSE", -# "COND1_TRUE COND2_FALSE COND3_FALSE", -# "COND1_TRUE COND2_TRUE COND3_FALSE") +# => ("COND1_FALSE COND3_FALSE") # variable_not_always_defined_in_cond ('B', 'COND1_TRUE') -# => ("COND3_FALSE") +# => ("COND1_TRUE COND3_FALSE") # variable_not_always_defined_in_cond ('C', 'COND1_TRUE') # => () # variable_not_always_defined_in_cond ('D', 'TRUE') @@ -6142,35 +6139,15 @@ sub variable_not_always_defined_in_cond ($$) my ($var, $cond) = @_; # It's easy to answer if the variable is not defined. - return (TRUE,) unless exists $var_value{$var}; - - # How does it work? Let's take the second example: - # - # variable_not_always_defined_in_cond ('A', 'COND1_TRUE') - # - # (1) First, we get the list of conditions where A is defined: - # - # ("COND1_TRUE COND2_TRUE", "COND1_TRUE COND2_FALSE", "COND3_TRUE") - # - # (2) Then we generate the set of inverted conditions: - # - # ("COND1_FALSE COND2_TRUE COND3_FALSE", - # "COND1_FALSE COND2_FALSE COND3_FALSE") - # - # (3) Finally we remove these conditions which are not implied by - # COND1_TRUE. This yields an empty list and we are done. - - my @res = (); - my $cond_defs = variable_conditions ($var); # (1) - foreach my $icond ($cond_defs->invert->conds) # (2) - { - prog_error "->invert returned an input condition" - if exists $var_value{$var}{$icond}; - - push @res, $icond - if ($cond->true_when ($icond)); # (3) - } - return (new Automake::ConditionalSet @res)->simplify; + return TRUE unless exists $var_value{$var}; + + # Otherwise compute the subconditions where $var isn't defined. + return + variable_conditions ($var) + ->sub_conditions ($cond) + ->invert + ->simplify + ->multiply ($cond); } # ¯o_define($VAR, $OWNER, $TYPE, $COND, $VALUE, $WHERE) diff --git a/lib/Automake/Conditional.pm b/lib/Automake/Conditional.pm index 2ce74a6e..ccd3e527 100644 --- a/lib/Automake/Conditional.pm +++ b/lib/Automake/Conditional.pm @@ -77,8 +77,8 @@ Automake::Conditional - record a conjunction of conditions # $other and $cond are implied by $both.) @conds = Automake::Conditional::reduce ($other, $both, $cond); - # Invert a Conditional. This returns a ConditionalSet. - $set = $both->not; + # Invert a Conditional. This returns a list of Conditionals. + @conds = $both->not; =head1 DESCRIPTION diff --git a/lib/Automake/ConditionalSet.pm b/lib/Automake/ConditionalSet.pm index 9ed9b9ba..b4302d66 100644 --- a/lib/Automake/ConditionalSet.pm +++ b/lib/Automake/ConditionalSet.pm @@ -311,7 +311,7 @@ sub permutations ($ ) =item C<$prod = $set1->multiply ($set2)> -Multiply to conditional sets. +Multiply two conditional sets. my $set1 = new Automake::ConditionalSet (new Automake::Conditional ("A_TRUE"), @@ -328,6 +328,8 @@ C<$set1-Emultiply ($set2)> will return new Automake::Conditional ("A_TRUE", "D_FALSE"), new Automake::Conditional ("B_TRUE", "D_FALSE")); +The argument can also be a C. + =cut # Same as multiply() but take a list of Conditonal as second argument. @@ -349,6 +351,7 @@ sub _multiply ($@) sub multiply ($$) { my ($self, $set) = @_; + return $self->_multiply ($set) if $set->isa('Automake::Conditional'); return $self->_multiply ($set->conds); } @@ -644,6 +647,61 @@ sub simplify ($) return $res; } +=item C<$self-Esub_conditions ($cond)> + +Return the subconditions of C<$self> that contains C<$cond>, with +C<$cond> stripped. + +For instance, consider: + + my $a = new Automake::ConditionalSet + (new Automake::Conditional ("A_TRUE", "B_TRUE"), + new Automake::Conditional ("A_TRUE", "C_FALSE"), + new Automake::Conditional ("A_TRUE", "B_FALSE", "C_TRUE"), + new Automake::Conditional ("A_FALSE")); + my $b = new Automake::ConditionalSet + (new Automake::Conditional ("A_TRUE", "B_FALSE")); + +Calling C<$a-Esub_conditions ($b)> will return the following +C. + + new Automake::ConditionalSet + (new Automake::Conditional ("C_FALSE"), # From A_TRUE C_FALSE + new Automake::Conditional ("C_TRUE")); # From A_TRUE B_FALSE C_TRUE" + +=cut + +sub sub_conditions ($$) +{ + my ($self, $subcond) = @_; + my @res; + + # Make $subcond blindingly apparent in the ConditionalSet. + # For instance `$a->_multiply($b)' (from the POD example) is: + # new Automake::ConditionalSet + # (new Automake::Conditional ("FALSE"), + # new Automake::Conditional ("A_TRUE", "B_FALSE", "C_FALSE"), + # new Automake::Conditional ("A_TRUE", "B_FALSE", "C_TRUE"), + # new Automake::Conditional ("FALSE")); + my $prod = $self->_multiply ($subcond); + + # Now, strip $subcond from the non-false Conditionals. + foreach my $c ($prod->conds) + { + if (! $c->false) + { + my @rescond; + foreach my $cc ($c->conds) + { + push @rescond, $cc + unless $subcond->has ($cc); + } + push @res, new Automake::Conditional @rescond; + } + } + return new Automake::ConditionalSet @res; +} + =head1 SEE ALSO L. diff --git a/lib/Automake/tests/ConditionalSet.pl b/lib/Automake/tests/ConditionalSet.pl index 5c815233..c484014f 100644 --- a/lib/Automake/tests/ConditionalSet.pl +++ b/lib/Automake/tests/ConditionalSet.pl @@ -318,7 +318,73 @@ sub test_simplify () return 0; } -exit (test_basics || test_permutations || test_invert || test_simplify); +sub test_sub_conditions () +{ + my @tests = ([[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"], + ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"], + ["FOO_FALSE"]], + ["FOO_TRUE"], + [["BAR_FALSE", "BAZ_FALSE"], + ["BAR_FALSE", "BAZ_TRUE"]]], + + [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"], + ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"], + ["FOO_FALSE"]], + ["FOO_TRUE", "BAR_FALSE"], + [["BAZ_FALSE"], + ["BAZ_TRUE"]]], + + [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"], + ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"], + ["FOO_FALSE"]], + ["FOO_TRUE", "BAR_TRUE"], + [["FALSE"]]], + + [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"], + ["FOO_TRUE", "BAZ_TRUE"], + ["FOO_FALSE"]], + ["FOO_TRUE", "BAR_TRUE"], + [["BAZ_TRUE"]]], + + [[["FOO_TRUE", "BAR_FALSE"], + ["FOO_TRUE", "BAR_TRUE"]], + ["FOO_TRUE", "BAR_TRUE"], + [["TRUE"]]], + + [[["TRUE"]], + ["TRUE"], + [["TRUE"]]], + + [[["FALSE"]], + ["TRUE"], + [["FALSE"]]], + + [[["FALSE"]], + ["FALSE"], + [["FALSE"]]]); + + for my $t (@tests) + { + my $t1 = build_set @{$t->[0]}; + my $t2 = new Automake::Conditional @{$t->[1]}; + my $t3 = build_set @{$t->[2]}; + + # Make sure simplify() yields the expected result. + my $s = $t1->sub_conditions ($t2); + if ($s != $t3) + { + print " (SC) " . $t1->string . "\n\t" + . $s->string . ' != ' . $t3->string . "\n"; + return 1; + } + } +} + +exit (test_basics + || test_permutations + || test_invert + || test_simplify + || test_sub_conditions); ### Setup "GNU" style for perl-mode and cperl-mode. ## Local Variables: -- 2.43.5