automake-patches
[Top][All Lists]
Advanced

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

Re: Automake::Conditional::simplify (Quine-McCluskey)


From: Alexandre Duret-Lutz
Subject: Re: Automake::Conditional::simplify (Quine-McCluskey)
Date: Tue, 19 Nov 2002 21:01:46 +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> Things are quite OK right now, if you ask me :-)

Ok, I'm reassured by all your comments.  Thanks.

Here is the final patch I'm checking in.  I managed to use up to
31 variables so I'm using this as a limit (there is a test-case for this).

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

        * lib/Automake/ConditionalSet.pm (_simplify, simplify): New methods.
        (true): Cache return value, so _simplify can use it.
        * lib/Automake/tests/ConditionalSet.pl (test_simplify): New function.
        * automake.in (variable_not_always_defined_in_cond): Return
        a simplified ConditionalSet.
        (macro_define, require_variables): Adjust.
        * tests/Makefile.am (TEST): Add library3.test.
        * tests/library3.test: New file.
        * tests/pluseq9.test: Adjust.
        Thanks to Raja R Harinath.

Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1388
diff -u -r1.1388 automake.in
--- automake.in 14 Nov 2002 22:37:29 -0000      1.1388
+++ automake.in 19 Nov 2002 19:59:08 -0000
@@ -6184,7 +6184,7 @@
       push @res, $icond
        if ($cond->true_when ($icond)); # (3)
     }
-  return @res;
+  return (new Automake::ConditionalSet @res)->simplify;
 }
 
 # &macro_define($VAR, $OWNER, $TYPE, $COND, $VALUE, $WHERE)
@@ -6326,13 +6326,14 @@
          #   X += Z
          # should be rejected because X is not defined for all conditions
          # where `+=' applies.
-         my @undef_cond = variable_not_always_defined_in_cond $var, $cond;
-         if (@undef_cond != 0)
+         my $undef_cond = variable_not_always_defined_in_cond $var, $cond;
+         if (! $undef_cond->false)
            {
              err ($where,
                   "Cannot apply `+=' because `$var' is not defined "
                   . "in\nthe following conditions:\n  "
-                  . join ("\n  ", map { $_->string } @undef_cond)
+                  . join ("\n  ",
+                          map { $_->string } $undef_cond->conds)
                   . "\nEither define `$var' in these conditions,"
                   . " or use\n`+=' in the same conditions as"
                   . " the definitions.");
@@ -8961,15 +8962,15 @@
        if ((exists $var_value{$var} && exists $var_value{$var}{$cond})
            || exists $configure_vars{$var});
 
-      my @undef_cond = variable_not_always_defined_in_cond $var, $cond;
+      my $undef_cond = variable_not_always_defined_in_cond $var, $cond;
       next VARIABLE
-       unless @undef_cond;
+       if $undef_cond->false;
 
       my $text = "$reason`$var' is undefined\n";
-      if (@undef_cond && $undef_cond[0] != TRUE)
+      if (! $undef_cond->true)
        {
          $text .= ("in the following conditions:\n  "
-                   . join ("\n  ", map { $_->string } @undef_cond));
+                   . join ("\n  ", map { $_->string } $undef_cond->conds));
        }
 
       ++$res;
Index: stamp-vti
===================================================================
RCS file: /cvs/automake/automake/stamp-vti,v
retrieving revision 1.219
diff -u -r1.219 stamp-vti
--- stamp-vti   18 Nov 2002 18:41:44 -0000      1.219
+++ stamp-vti   19 Nov 2002 19:59:08 -0000
@@ -1,4 +1,4 @@
address@hidden UPDATED 17 November 2002
address@hidden UPDATED 13 November 2002
 @set UPDATED-MONTH November 2002
 @set EDITION 1.7a
 @set VERSION 1.7a
Index: version.texi
===================================================================
RCS file: /cvs/automake/automake/version.texi,v
retrieving revision 1.291
diff -u -r1.291 version.texi
--- version.texi        18 Nov 2002 18:41:44 -0000      1.291
+++ version.texi        19 Nov 2002 19:59:08 -0000
@@ -1,4 +1,4 @@
address@hidden UPDATED 17 November 2002
address@hidden UPDATED 13 November 2002
 @set UPDATED-MONTH November 2002
 @set EDITION 1.7a
 @set VERSION 1.7a
Index: lib/Automake/ConditionalSet.pm
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/ConditionalSet.pm,v
retrieving revision 1.4
diff -u -r1.4 ConditionalSet.pm
--- lib/Automake/ConditionalSet.pm      18 Nov 2002 18:43:24 -0000      1.4
+++ lib/Automake/ConditionalSet.pm      19 Nov 2002 19:59:11 -0000
@@ -195,7 +195,11 @@
 sub true ($ )
 {
   my ($self) = @_;
-  return $self->invert->false;
+  # We cache 'true' so that simplify() can use the value if it's available.
+  return $self->{'true'} if defined $self->{'true'};
+  my $res = $self->invert->false;
+  $self->{'true'} = $res;
+  return $res;
 }
 
 =item C<$str = $set-E<gt>string>
@@ -342,6 +346,251 @@
   # It's tempting to also set $res->{'invert'} to $self, but that
   # is a bad idea as $self hasn't been normalized in any way.
   # (Different inputs can produce the same inverted set.)
+  return $res;
+}
+
+=item C<$simp = $set->simplify>
+
+Find prime implicants and return a simplified C<ConditionalSet>.
+
+=cut
+
+sub _simplify ($)              # Based on Quine-McCluskey's algorithm.
+{
+  my ($self) = @_;
+
+  # If we know this ConditionalSet is always true, we have nothing to do.
+  # Use the cached value if true if available.  Never call true()
+  # as this would call invert() which can be slow.
+  return new Automake::ConditionalSet TRUE
+    if $self->{'hash'}{&TRUE} || $self->{'true'};
+
+  my $nvars = 0;
+  my %var_rank;
+  my @rank_var;
+
+  # Initialization.
+  # Translate and-terms into bit string pairs: [$true, $false].
+  #
+  # Each variable is given a bit position in the strings.
+  #
+  # The first string in the pair tells wether a variable is
+  # uncomplemented in the term.
+  # The second string tells whether a variable is complemented.
+  # If a variable does not appear in the term, then its
+  # corresponding bit is unset in both strings.
+
+  # Order the resulting bit string pairs by the number of
+  # variables involved:
+  #   @{$subcubes[2]} is the list of string pairs involving two variables.
+  # (Level 0 is used for "TRUE".)
+  my @subcubes;
+  for my $and_conds ($self->conds)
+    {
+      my $true = 0;            # Bit string for uncomplemented variables.
+      my $false = 0;           # Bit string for complemented variables.
+
+      my @conds = $and_conds->conds;
+      for my $cond (@conds)
+       {
+         # Which variable is this condition about?
+         confess "can't parse `$cond'"
+           unless $cond =~ /^(.*_)(FALSE|TRUE)$/;
+
+         # Get the variabe's rank, or assign it a new one.
+         my $rank = $var_rank{$1};
+         if (! defined $rank)
+           {
+             $rank = $nvars++;
+
+             # FIXME: simplify() cannot work with more that 31 variables.
+             # We need a bitset implementation to allow more variables.
+             # For now we just return the input, as is, not simplified.
+             return $self if $rank >= 31;
+
+             $var_rank{$1} = $rank;
+             $rank_var[$rank] = $1;
+           }
+
+         # Fire the relevant bit in the strings.
+         if ($2 eq 'FALSE')
+           {
+             $false |= 1 << $rank;
+           }
+         else
+           {
+             $true |= 1 << $rank;
+           }
+       }
+
+      # Register this term.
+      push @{$subcubes[1 + $#conds]}, [$true, $false];
+    }
+
+  # Real work.  Let's combine terms.
+
+  # Process terms in diminishing size order.  Those
+  # involving the maximum number of variables first.
+  for (my $m = $#subcubes; $m > 0; --$m)
+    {
+      my $m_subcubes = $#{$subcubes[$m]};
+
+      # Consider all terms with $m variables.
+      for (my $j = 0; $j <= $m_subcubes; ++$j)
+       {
+         my $tj = $subcubes[$m][$j];
+         my $jtrue = $tj->[0];
+         my $jfalse = $tj->[1];
+
+         # Compare them with all other terms with $m variables.
+       COMBINATION:
+         for (my $k = $j + 1; $k <= $m_subcubes; ++$k)
+           {
+             my $tk = $subcubes[$m][$k];
+             my $ktrue = $tk->[0];
+             my $kfalse = $tk->[1];
+
+             # Two terms can combine if they differ only by one variable
+             # (i.e., a bit here), which is complemented in one term
+             # and uncomplemented in the other.
+             my $true  = $jtrue  ^ $ktrue;
+             my $false = $jfalse ^ $kfalse;
+             next COMBINATION if $true != $false;
+             # There should be exactly one bit set.
+             # (`$true & ($true - 1)' unsets the rightmost 1 bit in $true.)
+             next COMBINATION if $true == 0 || $true & ($true - 1);
+
+             # At this point we know we can combine the two terms.
+
+             # Mark these two terms as "combined", so they will be
+             # deleted after we have processed all other combinations.
+             $tj->[2] = 1;
+             $tk->[2] = 1;
+
+             # Actually combine the two terms.
+             my $ctrue  = $jtrue  & $ktrue;
+             my $cfalse = $jfalse & $kfalse;
+
+             # Don't add the combined term if it already exists.
+           DUP_SEARCH:
+             for my $c (@{$subcubes[$m - 1]})
+               {
+                 next DUP_SEARCH  if $ctrue  != $c->[0];
+                 next COMBINATION if $cfalse == $c->[1];
+               }
+             push @{$subcubes[$m - 1]}, [$ctrue, $cfalse];
+           }
+       }
+
+      # Delete all covered terms.
+      for (my $j = 0; $j <= $m_subcubes; ++$j)
+       {
+         delete $subcubes[$m][$j] if $subcubes[$m][$j][2];
+       }
+    }
+
+  # Finally merge bit strings back into a Automake::ConditionalSet.
+
+  # If level 0 has been filled, we've found `TRUE'.  No need to translate
+  # anything.
+  return new Automake::ConditionalSet TRUE if $#{$subcubes[0]} >= 0;
+
+  # Otherwise, translate uncombined terms in other levels.
+
+  my @or_conds = ();
+  # Process terms in diminishing size order.  Those
+  # involving the maximum number of variables first.
+  for (my $m = 1; $m <= $#subcubes; ++$m)
+    {
+      my $m_subcubes = $#{$subcubes[$m]};
+      # Consider all terms with $m variables.
+      for (my $j = 0; $j <= $m_subcubes; ++$j)
+       {
+         my $tj = $subcubes[$m][$j];
+         next unless $tj;      # Skip deleted terms.
+         my $jtrue  = $tj->[0];
+         my $jfalse = $tj->[1];
+
+         # Filter-out implied terms.
+         #
+         # An and-term at level N might cover and-terms at level M>N.
+         # We need to mark all these covered terms so that they are
+         # not output in the result formula.
+         #
+         # If $tj was generated by combining two terms at level N+1,
+         # there two terms are already marked.  However there might be
+         # implied terms deeper.
+         #
+         #    For instance consider this input: "A_TRUE | A_TRUE C_FALSE".
+         #
+         #    This can also occur with and-term generated by the
+         #    combining algorith.  E.g., consider
+         #    "A_TRUE B_TRUE" | "A_TRUE B_FALSE" | "A_TRUE C_FALSE D_FALSE"
+         #     - at level 3 we can't combine "A_TRUE C_FALSE D_FALSE"
+         #     - at level 2 we can combine "A_TRUE B_TRUE" | "A_TRUE B_FALSE"
+         #       into "A_TRUE
+         #     - at level 1 we an't combine "A_TRUE"
+         #    so without more simplification we would output
+         #    "A_TRUE | A_TRUE C_FALSE D_FALSE"
+         #
+         # So let's filter-out and-terms which are implied by other
+         # and-terms. An and-term $tk is implied by an and-term $tj if $k
+         # involves more variables than $tj (i.e., N>M) and if
+         # all variables occurring in $tk also occur in A in the
+         # same state (complemented or uncomplemented.)
+         for (my $n = $m + 1; $n <= $#subcubes; ++$n)
+           {
+             my $n_subcubes = $#{$subcubes[$n]};
+             for (my $k = 0; $k <= $n_subcubes; ++$k)
+               {
+                 my $tk = $subcubes[$n][$k];
+                 next unless $tk; # Skip deleted terms.
+                 my $ktrue = $tk->[0];
+                 my $kfalse = $tk->[1];
+
+                 next unless $ktrue == ($ktrue | $jtrue);
+                 next unless $kfalse == ($kfalse | $jfalse);
+
+                 delete $subcubes[$n][$k];
+               }
+           }
+
+         # Translate $tj.
+         my @and_conds = ();
+         my $rank = 0;
+         while ($jtrue > 0)
+           {
+             if ($jtrue & 1)
+               {
+                 push @and_conds, $rank_var[$rank] . 'TRUE';
+               }
+             $jtrue >>= 1;
+             ++$rank;
+           }
+         $rank = 0;
+         while ($jfalse > 0)
+           {
+             if ($jfalse & 1)
+               {
+                 push @and_conds, $rank_var[$rank] . 'FALSE';
+               }
+             $jfalse >>= 1;
+             ++$rank;
+           }
+
+         push @or_conds, new Automake::Conditional @and_conds if @and_conds;
+       }
+    }
+
+  return new Automake::ConditionalSet @or_conds;
+}
+
+sub simplify ($)
+{
+  my ($self) = @_;
+  return $self->{'simplify'} if defined $self->{'simplify'};
+  my $res = $self->_simplify ;
+  $self->{'simplify'} = $res;
   return $res;
 }
 
Index: lib/Automake/tests/ConditionalSet.pl
===================================================================
RCS file: /cvs/automake/automake/lib/Automake/tests/ConditionalSet.pl,v
retrieving revision 1.1
diff -u -r1.1 ConditionalSet.pl
--- lib/Automake/tests/ConditionalSet.pl        18 Nov 2002 18:43:28 -0000      
1.1
+++ lib/Automake/tests/ConditionalSet.pl        19 Nov 2002 19:59:11 -0000
@@ -92,7 +92,7 @@
       my $per = $set->permutations;
       if ($per != $res)
        {
-         print $per->string . ' != ' . $res->string . "\n";
+         print " (P) " . $per->string . ' != ' . $res->string . "\n";
          return 1;
        }
     }
@@ -137,14 +137,189 @@
       my $inv = $set->invert;
       if ($inv != $res)
        {
-         print $inv->string . ' != ' . $res->string . "\n";
+         print " (I) " . $inv->string . ' != ' . $res->string . "\n";
          return 1;
        }
     }
   return 0;
 }
 
-exit (test_basics || test_permutations || test_invert);
+sub test_simplify ()
+{
+  my @tests = ([[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
+                ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"]],
+               [["FOO_TRUE", "BAR_FALSE"]]],
+
+              [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
+                ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
+                ["FOO_TRUE", "BAR_TRUE"]],
+               [["FOO_TRUE"]]],
+
+              [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
+                ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
+                ["FOO_TRUE", "BAR_TRUE"],
+                ["FOO_FALSE"]],
+               [["TRUE"]]],
+
+              [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
+                ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
+                            ["BAR_TRUE",  "BAZ_TRUE"],
+                            ["BAR_FALSE", "BAZ_TRUE"]],
+               [["BAZ_TRUE"], ["FOO_TRUE", "BAR_FALSE"]]],
+
+              [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
+                ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
+                            ["BAR_TRUE",  "BAZ_TRUE"],
+                            ["BAR_FALSE", "BAZ_TRUE"],
+                ["FOO_FALSE"]],
+               # Note that this could be further simplified to
+               # [["FOO_FALSE"], ["BAZ_TRUE"], ["BAR_FALSE"]]
+               # but simplify isn't able to detect this.
+               [["FOO_FALSE"], ["BAZ_TRUE"], ["BAR_FALSE", "FOO_TRUE"]]],
+
+              [[["B_TRUE"],
+                ["A_FALSE", "B_TRUE"]],
+               [["B_TRUE"]]],
+
+              [[["B_TRUE"],
+                ["A_FALSE", "B_FALSE", "C_TRUE"],
+                ["A_FALSE", "B_FALSE", "C_FALSE"]],
+               # Note that this could be further simplified to
+               # [["A_FALSE"], ["B_TRUE"]]
+               # but simplify isn't able to detect this.
+               [["A_FALSE", "B_FALSE"], ["B_TRUE"]]],
+
+              [[["B_TRUE"],
+                ["A_FALSE", "B_FALSE", "C_TRUE"],
+                ["A_FALSE", "B_FALSE", "C_FALSE"],
+                ["A_TRUE", "B_FALSE"]],
+               [["TRUE"]]],
+
+              [[["A_TRUE", "B_TRUE"],
+                ["A_TRUE", "B_FALSE"],
+                ["A_TRUE", "C_FALSE", "D_FALSE"]],
+               [["A_TRUE"]]],
+
+              [[["A_FALSE", "B_FALSE", "C_FALSE", "D_TRUE",  "E_FALSE"],
+                ["A_FALSE", "B_FALSE", "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                ["A_FALSE", "B_TRUE",  "C_TRUE",  "D_FALSE", "E_TRUE"],
+                ["A_FALSE", "B_TRUE",  "C_FALSE", "D_FALSE", "E_FALSE"],
+                ["A_TRUE",  "B_TRUE",  "C_FALSE", "D_FALSE", "E_FALSE"],
+                ["A_TRUE",  "B_TRUE",  "C_TRUE",  "D_FALSE", "E_TRUE"],
+                ["A_TRUE",  "B_FALSE", "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                ["A_TRUE",  "B_FALSE", "C_FALSE", "D_TRUE",  "E_FALSE"]],
+               [           ["B_FALSE", "C_FALSE", "D_TRUE",  "E_FALSE"],
+                           ["B_FALSE", "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                           ["B_TRUE",  "C_TRUE",  "D_FALSE", "E_TRUE"],
+                           ["B_TRUE",  "C_FALSE", "D_FALSE", "E_FALSE"]]],
+
+              [[["A_FALSE", "B_FALSE", "C_FALSE", "D_TRUE",  "E_FALSE"],
+                ["A_FALSE", "B_FALSE", "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                ["A_FALSE", "B_TRUE",  "C_TRUE",  "D_FALSE", "E_TRUE"],
+                ["A_FALSE", "B_TRUE",  "C_FALSE", "D_FALSE", "E_FALSE"],
+                ["A_TRUE",  "B_TRUE",  "C_FALSE", "D_FALSE", "E_FALSE"],
+                ["A_TRUE",  "B_TRUE",  "C_TRUE",  "D_FALSE", "E_TRUE"],
+                ["A_TRUE",  "B_FALSE", "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                ["A_TRUE",  "B_FALSE", "C_FALSE", "D_TRUE",  "E_FALSE"],
+                ["A_FALSE", "B_FALSE", "C_FALSE", "D_FALSE", "E_FALSE"],
+                ["A_FALSE", "B_FALSE", "C_TRUE",  "D_FALSE", "E_TRUE"],
+                ["A_FALSE", "B_TRUE",  "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                ["A_FALSE", "B_TRUE",  "C_FALSE", "D_TRUE",  "E_FALSE"],
+                ["A_TRUE",  "B_TRUE",  "C_FALSE", "D_TRUE",  "E_FALSE"],
+                ["A_TRUE",  "B_TRUE",  "C_TRUE",  "D_TRUE",  "E_TRUE"],
+                ["A_TRUE",  "B_FALSE", "C_TRUE",  "D_FALSE", "E_TRUE"],
+                ["A_TRUE",  "B_FALSE", "C_FALSE", "D_FALSE", "E_FALSE"]],
+               [["C_FALSE", "E_FALSE"],
+                ["C_TRUE", "E_TRUE"]]],
+
+              [[["A_FALSE"],
+                ["A_TRUE", "B_FALSE"],
+                ["A_TRUE", "B_TRUE", "C_FALSE"],
+                ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE"],
+                ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_FALSE"],
+                ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE", "F_FALSE"],
+                ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"]],
+               [["TRUE"]]],
+
+              # Simplify should work with up to 31 variables.
+              [[["V01_TRUE", "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
+                 "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
+                 "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
+                 "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
+                 "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
+                 "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
+                 "V31_TRUE"],
+                ["V01_TRUE", "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
+                 "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
+                 "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
+                 "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
+                 "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
+                 "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
+                 "V31_FALSE"],
+                ["V01_FALSE","V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
+                 "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
+                 "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
+                 "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
+                 "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
+                 "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
+                 "V31_TRUE"],
+                ["V01_FALSE","V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
+                 "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
+                 "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
+                 "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
+                 "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
+                 "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
+                 "V31_FALSE"]],
+               [[            "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
+                 "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
+                 "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
+                 "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
+                 "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
+                 "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE"
+                 ]]]);
+
+  for my $t (@tests)
+    {
+      my $set = build_set @{$t->[0]};
+      my $res = build_set @{$t->[1]};
+
+      # Make sure simplify() yields the expected result.
+      my $sim = $set->simplify;
+      if ($sim != $res)
+       {
+         print " (S1) " . $set->string . "\n\t"
+           . $sim->string . ' != ' . $res->string . "\n";
+         return 1;
+       }
+
+      # Make sure simplify() is idempotent.
+      my $sim2 = $sim->simplify;
+      if ($sim2 != $sim)
+       {
+         print " (S2) " . $sim->string . "\n\t"
+           . $sim2->string . ' != ' . $sim->string . "\n";
+         return 1;
+       }
+
+      # Also exercize invert() while we are at it.
+
+      # FIXME: Don't run invert() with too much conditionals, this is too slow.
+      next if $#{$t->[0][0]} > 8;
+
+      my $inv1 = $set->invert->simplify;
+      my $inv2 = $sim->invert->simplify;
+      if ($inv1 != $inv2)
+       {
+         print " (S3) " . $set->string . ", " . $sim->string . "\n\t"
+           . $inv1->string . ' != ' . $inv2->string . "\n";
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+exit (test_basics || test_permutations || test_invert || test_simplify);
 
 ### Setup "GNU" style for perl-mode and cperl-mode.
 ## Local Variables:
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.am,v
retrieving revision 1.453
diff -u -r1.453 Makefile.am
--- tests/Makefile.am   18 Nov 2002 18:43:32 -0000      1.453
+++ tests/Makefile.am   19 Nov 2002 19:59:12 -0000
@@ -229,6 +229,7 @@
 libobj12b.test \
 library.test \
 library2.test \
+library3.test \
 libtool.test \
 libtool2.test \
 libtool3.test \
Index: tests/Makefile.in
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.in,v
retrieving revision 1.588
diff -u -r1.588 Makefile.in
--- tests/Makefile.in   18 Nov 2002 18:43:35 -0000      1.588
+++ tests/Makefile.in   19 Nov 2002 19:59:12 -0000
@@ -322,6 +322,7 @@
 libobj12b.test \
 library.test \
 library2.test \
+library3.test \
 libtool.test \
 libtool2.test \
 libtool3.test \
Index: tests/library3.test
===================================================================
RCS file: tests/library3.test
diff -N tests/library3.test
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/library3.test 19 Nov 2002 19:59:13 -0000
@@ -0,0 +1,59 @@
+#! /bin/sh
+# Copyright (C) 2002  Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Automake is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with autoconf; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Make sure Automake simplify conditions in diagnostics.
+
+. ./defs || exit 1
+
+set -e
+
+cat >>configure.in <<EOF
+AC_PROG_CC
+AM_CONDITIONAL([A], [:])
+AM_CONDITIONAL([B], [:])
+AM_CONDITIONAL([C], [:])
+AM_CONDITIONAL([D], [:])
+EOF
+
+cat > Makefile.am << 'END'
+if A
+if !B
+  RANLIB = anb
+else
+  RANLIB = ab
+endif
+endif
+if C
+  RANLIB = c
+endif
+if !C
+if D
+  RANLIB = ncd
+endif
+endif
+EXTRA_LIBRARIES = libfoo.a
+END
+
+$ACLOCAL
+$AUTOMAKE 2>stderr && exit 1
+cat stderr
+grep '^Makefile.am:.*:   A_FALSE C_FALSE D_FALSE$' stderr
+# Is there only one missing condition?
+test `grep ':  ' stderr | wc -l` = 1 || exit 1
Index: tests/pluseq9.test
===================================================================
RCS file: /cvs/automake/automake/tests/pluseq9.test,v
retrieving revision 1.3
diff -u -r1.3 pluseq9.test
--- tests/pluseq9.test  8 Sep 2002 13:07:55 -0000       1.3
+++ tests/pluseq9.test  19 Nov 2002 19:59:13 -0000
@@ -61,9 +61,7 @@
 #
 # Makefile.am:19: Cannot apply `+=' because `B' is not defined in
 # Makefile.am:19: the following conditions:
-# Makefile.am:19:   COND3_FALSE
-# Makefile.am:19:   COND1_FALSE COND2_FALSE
-# Makefile.am:19:   COND1_FALSE COND2_TRUE
+# Makefile.am:19:   COND1_FALSE COND3_FALSE
 # Makefile.am:19: Either define `B' in these conditions, or use
 # Makefile.am:19: `+=' in the same conditions as the definitions.
 #
@@ -71,10 +69,8 @@
 # COND1_FALSE (merging the last two conditions), so we'll support
 # this case in the check too.
 
-# Are COND3_FALSE and COND1_FALSE mentioned?
-grep ':.*COND3_FALSE$' stderr || exit 1
-grep ':.*COND1_FALSE' stderr || exit 1
-# Make sure there are no more than three missing conditions.
-test `grep ':  ' stderr | wc -l` -le 3 || exit 1
+grep ':   COND1_FALSE COND3_FALSE$' stderr || exit 1
+# Make sure there is exactly one missing condition.
+test `grep ':  ' stderr | wc -l` = 1 || exit 1
 
 :
-- 
Alexandre Duret-Lutz





reply via email to

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