* 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.
2002-11-20 Alexandre Duret-Lutz <adl@gnu.org>
+ * 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.
# 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')
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)
# $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
=item C<$prod = $set1->multiply ($set2)>
-Multiply to conditional sets.
+Multiply two conditional sets.
my $set1 = new Automake::ConditionalSet
(new Automake::Conditional ("A_TRUE"),
new Automake::Conditional ("A_TRUE", "D_FALSE"),
new Automake::Conditional ("B_TRUE", "D_FALSE"));
+The argument can also be a C<Conditional>.
+
=cut
# Same as multiply() but take a list of Conditonal as second argument.
sub multiply ($$)
{
my ($self, $set) = @_;
+ return $self->_multiply ($set) if $set->isa('Automake::Conditional');
return $self->_multiply ($set->conds);
}
return $res;
}
+=item C<$self-E<gt>sub_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-E<gt>sub_conditions ($b)> will return the following
+C<ConditionalSet>.
+
+ 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<Automake::Conditional>.
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: