Index: Singular/LIB/general.lib
===================================================================
--- Singular/LIB/general.lib	(revision 584f84d6e8c6f3340af1d80fff4224b3f977de76)
+++ Singular/LIB/general.lib	(revision 7708934c4dd35b5ec3af10e0b6fe8671994ca033)
@@ -2,5 +2,5 @@
 //anne, added deleteSublist and watchdog 12.12.2000
 ///////////////////////////////////////////////////////////////////////////////
-version="$Id: general.lib,v 1.32 2000-12-29 02:19:24 greuel Exp $";
+version="$Id: general.lib,v 1.33 2000-12-30 03:00:57 greuel Exp $";
 category="General purpose";
 info="
@@ -660,15 +660,28 @@
           A module m is identified with the corresponding matrix M (columns
           of M generate m).
+@*        If v is outside the range of id, we have the empty product and the
+          result will be 1 (of type int).
 EXAMPLE:  example product; shows an example
 "
-{
+{  
+//-------------------- initialization and special feature ---------------------
    int n,j,tt;
-   string ty;
+   string ty;		                              //will become type of id
    list l;
+
+// We wish to allow something like product(x(1..10)) if x(1),...,x(10) are
+// variables. x(1..10) is a list of polys and enters the procedure with 
+// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
+// this case # is never empty. If an additional intvec v is given,
+// it is added to #, so we have to separate it first and make
+// the rest a list which has to be multiplied.
+
    int s = size(#);
    if( s!=0 )
-   {  if ( typeof(#[s])=="intvec" )
-      {  intvec v = #[s];
-         tt=1; s=s-1;
+   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")   
+      {  
+         intvec v = #[s];
+         tt=1; 
+         s=s-1;
          if ( s>0 ) { # = #[1..s]; }
       }
@@ -676,18 +689,17 @@
    if ( s>0 )
    {
-     l = list(id)+#;
-     kill id;
-     list id = l;
-     ty = "list";
+      l = list(id)+#;
+      kill id;
+      list id = l;                                    //case: id = list
+      ty = "list";
+      n = size(id);
    }
    else
-   { ty = typeof(id);
-   }
-   if( ty=="list" )
-   { n = size(id);
-     def f(1) = id[1];
-     for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)*id[j]; }
-     return(f(n));
-   }
+   { 
+      ty = typeof(id);
+      if( ty == "list" ) 
+      { n = size(id); }
+   }
+//------------------------------ reduce to 3 cases ---------------------------
    if( ty=="poly" or ty=="ideal" or ty=="vector"
        or ty=="module" or ty=="matrix" )
@@ -695,7 +707,6 @@
       ideal i = ideal(matrix(id));
       kill id;
-      ideal id = i;
-      if( tt!=0 ) { id = id[v]; }
-      n = ncols(id); poly f(1)=id[1];
+      ideal id = i;                                   //case: id = ideal
+      n = ncols(id);
    }
    if( ty=="int" or ty=="intvec" or ty=="intmat" )
@@ -705,8 +716,30 @@
       intvec i = S[1..nrows(S),1..ncols(S)];
       kill id;
-      intvec id = i;
-      if( tt!=0 ) { id = id[v]; }
-      n = size(id); int f(1)=id[1];
-   }
+      intvec id = i;                                  //case: id = intvec
+      n = size(id); 
+   }
+//--------------- consider intvec v and empty product  -----------------------
+   if( tt!=0 ) 
+   {
+      for (j=1; j<=size(v); j++)
+      {
+         if ( v[j] <= 0 or v[j] > n )                 //v outside range of id
+         { 
+            return(1);                                //empty product is 1
+         }                               
+      }
+      id = id[v];                                     //consider part of id
+   }                                                  //corresponding to v
+//--------------------- special case: one factor is zero  ---------------------
+   if ( typeof(id) == "ideal")
+   {
+      if( size(id) < ncols(id) )
+      {
+          poly f; return(f);
+      }
+   }
+//-------------------------- finally, multiply objects  -----------------------
+   n = size(id); 
+   def f(1) = id[1];
    for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)*id[j]; }
    return(f(n));
@@ -947,18 +980,30 @@
 RETURN:   The sum of all entries of id [with index given by v] of type 
           depending on the entries of id.
-NOTE:      If id is not a list, id is treated as a list of polys resp. integers.
+NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
           A module m is identified with the corresponding matrix M (columns
           of M generate m).
+@*        If v is outside the range of id, we have the empty sum and the
+          result will be 0 (of type int).
 EXAMPLE:  example sum; shows an example
 "
 {
+//-------------------- initialization and special feature ---------------------
    int n,j,tt;
-   string ty;
+   string ty;                                  // will become type of id
    list l;
+
+// We wish to allow something like sum(x(1..10)) if x(1),...,x(10) are
+// variables. x(1..10) is a list of polys and enters the procedure with 
+// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
+// this case # is never empty. If an additional intvec v is given,
+// it is added to #, so we have to separate it first and make
+// the rest a list which has to be added.
+
    int s = size(#);
    if( s!=0 )
-   {  if ( typeof(#[s])=="intvec" )
+   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
       {  intvec v = #[s];
-         tt=1; s=s-1;
+         tt=1; 
+         s=s-1;
          if ( s>0 ) { # = #[1..s]; }
       }
@@ -966,26 +1011,20 @@
    if ( s>0 )
    {
-     l = list(id)+#;
-     kill id;
-     list id = l;
-     ty = "list";
+      l = list(id)+#;
+      kill id;
+      list id = l;                                    //case: id = list
+      ty = "list";
    }
    else
-   { ty = typeof(id);
-   }
-   if( ty=="list" )
-   { n = size(id);
-     def f(1) = id[1];
-     for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)+id[j]; }
-     return(f(n));
-   }
+   { 
+      ty = typeof(id);
+   }
+//------------------------------ reduce to 3 cases ---------------------------
    if( ty=="poly" or ty=="ideal" or ty=="vector"
        or ty=="module" or ty=="matrix" )
-   {
+   {                                                 //case: id = ideal
       ideal i = ideal(matrix(id));
       kill id;
-      ideal id = i;
-      if( tt!=0 ) { id = id[v]; }
-      n = ncols(id); poly f(1)=id[1];
+      ideal id = simplify(i,2);                      //delete 0 entries
    }
    if( ty=="int" or ty=="intvec" or ty=="intmat" )
@@ -995,8 +1034,22 @@
       intvec i = S[1..nrows(S),1..ncols(S)];
       kill id;
-      intvec id = i;
-      if( tt!=0 ) { id = id[v]; }
-      n = size(id); int f(1)=id[1];
-   }
+      intvec id = i;                                 //case: id = intvec
+   }
+//------------------- consider intvec v and empty sum  -----------------------
+   if( tt!=0 ) 
+   {
+      for (j=1; j<=size(v); j++)
+      {
+         if ( v[j] <= 0 or v[j] > size(id) )         //v outside range of id
+         { 
+            return(0);                               //empty sum is 0
+         }                               
+      }
+      id = id[v];                                    //consider part of id
+   }                                                 //corresponding to v
+
+//-------------------------- finally, add objects  ---------------------------
+   n = size(id); 
+   def f(1) = id[1];
    for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)+id[j]; }
    return(f(n));   int n,j,tt;
