automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: simplify variable_not_always_defined_in_cond


From: Alexandre Duret-Lutz
Subject: FYI: simplify variable_not_always_defined_in_cond
Date: Wed, 20 Nov 2002 21:11:36 +0100
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/20.7 (i386-debian-linux-gnu)

>>> "Raja" == Raja R Harinath <address@hidden> writes:

[...]
 Raja> This is for later cleanup...  But, it would be nice if more of the
 Raja> functionality of variable_not_always_defined_in_cond() is moved into
 Raja> Automake::Conditional[Set].
[...]
 Raja> Then v_n_a_d_i_c($var, $cond) would be

 Raja> $variable_conditions($var)
 Raja> -> sub_conditions($cond)
 Raja>   -> invert
 Raja>     -> simplify
 Raja>       -> mult_cond($cond)

 Raja> Almost self-documenting :-)
[...]

I'm checking in the following patch which does this.  

(Before you get puzzled by the first comment changes: the
orginial values were wrong.)

2002-11-20  Alexandre Duret-Lutz  <address@hidden>

        * 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.

Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1390
diff -u -r1.1390 automake.in
--- automake.in 20 Nov 2002 11:10:03 -0000      1.1390
+++ automake.in 20 Nov 2002 19:58:32 -0000
@@ -6119,18 +6119,15 @@
 #   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 @@
   my ($var, $cond) = @_;
 
   # It's easy to answer if the variable is not defined.
-  return (TRUE,) unless exists $var_value{$var};
+  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;
+  # Otherwise compute the subconditions where $var isn't defined.
+  return
+    variable_conditions ($var)
+      ->sub_conditions ($cond)
+       ->invert
+         ->simplify
+           ->multiply ($cond);
 }
 
 # &macro_define($VAR, $OWNER, $TYPE, $COND, $VALUE, $WHERE)
Index: lib/Automake/Conditional.pm
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/Conditional.pm,v
retrieving revision 1.5
diff -u -r1.5 Conditional.pm
--- lib/Automake/Conditional.pm 20 Nov 2002 11:10:05 -0000      1.5
+++ lib/Automake/Conditional.pm 20 Nov 2002 19:58:33 -0000
@@ -77,8 +77,8 @@
   # $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
 
Index: lib/Automake/ConditionalSet.pm
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/ConditionalSet.pm,v
retrieving revision 1.6
diff -u -r1.6 ConditionalSet.pm
--- lib/Automake/ConditionalSet.pm      20 Nov 2002 11:10:05 -0000      1.6
+++ lib/Automake/ConditionalSet.pm      20 Nov 2002 19:58:36 -0000
@@ -311,7 +311,7 @@
 
 =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 @@
      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.
@@ -349,6 +351,7 @@
 sub multiply ($$)
 {
   my ($self, $set) = @_;
+  return $self->_multiply ($set) if $set->isa('Automake::Conditional');
   return $self->_multiply ($set->conds);
 }
 
@@ -642,6 +645,61 @@
   my $res = $self->_simplify ;
   $self->{'simplify'} = $res;
   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
Index: lib/Automake/tests/ConditionalSet.pl
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/tests/ConditionalSet.pl,v
retrieving revision 1.3
diff -u -r1.3 ConditionalSet.pl
--- lib/Automake/tests/ConditionalSet.pl        20 Nov 2002 11:10:05 -0000      
1.3
+++ lib/Automake/tests/ConditionalSet.pl        20 Nov 2002 19:58:36 -0000
@@ -318,7 +318,73 @@
   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:

-- 
Alexandre Duret-Lutz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]