Index: Singular/iparith.cc
===================================================================
--- Singular/iparith.cc	(revision c4dab43d69dd36ed09ba07d4e771236f8a7bcc39)
+++ Singular/iparith.cc	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -27,4 +27,5 @@
 #include <kernel/longtrans.h>
 #include <kernel/ideals.h>
+#include <kernel/prCopy.h>
 #include <kernel/matpol.h>
 #include <kernel/kstd1.h>
@@ -1759,4 +1760,32 @@
 {
   assumeStdFlag(v);
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    ring origR = currRing;
+    ring tempR = rCopy(origR);
+    tempR->ringtype = 0; tempR->ch = 0;
+    rComplete(tempR);
+    ideal vid = (ideal)v->Data();
+    int i = idPosConstant(vid);
+    if ((i != -1) && (nIsUnit(pGetCoeff(vid->m[i]))))
+    { /* ideal v contains unit; dim = -1 */
+      res->data = (char *)-1;
+      return FALSE;
+    }
+    rChangeCurrRing(tempR);
+    ideal vv = idrCopyR(vid, origR, currRing);
+    ideal ww = idrCopyR((ideal)w->Data(), origR, currRing);
+    /* drop degree zero generator from vv (if any) */
+    if (i != -1) pDelete(&vv->m[i]);
+    long d = (long)scDimInt(vv, ww);    
+    if (rField_is_Ring_Z(origR) && (i == -1)) d++;
+    res->data = (char *)d;
+    idDelete(&vv); idDelete(&ww);
+    rChangeCurrRing(origR);
+    rDelete(tempR);
+    return FALSE;
+  }
+#endif
   if(currQuotient==NULL)
     res->data = (char *)((long)scDimInt((ideal)(v->Data()),(ideal)w->Data()));
@@ -3599,4 +3628,31 @@
 {
   assumeStdFlag(v);
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    ring origR = currRing;
+    ring tempR = rCopy(origR);
+    tempR->ringtype = 0; tempR->ch = 0;
+    rComplete(tempR);
+    ideal vid = (ideal)v->Data();
+    int i = idPosConstant(vid);
+    if ((i != -1) && (nIsUnit(pGetCoeff(vid->m[i]))))
+    { /* ideal v contains unit; dim = -1 */
+      res->data = (char *)-1;
+      return FALSE;
+    }
+    rChangeCurrRing(tempR); rComplete(tempR);
+    ideal vv = idrCopyR(vid, origR, currRing);
+    /* drop degree zero generator from vv (if any) */
+    if (i != -1) pDelete(&vv->m[i]);
+    long d = (long)scDimInt(vv, currQuotient);    
+    if (rField_is_Ring_Z(origR) && (i == -1)) d++;
+    res->data = (char *)d;
+    idDelete(&vv);
+    rChangeCurrRing(origR);
+    rDelete(tempR);
+    return FALSE;
+  }
+#endif
   res->data = (char *)(long)scDimInt((ideal)(v->Data()),currQuotient);
   return FALSE;
Index: Tst/Short/Zdim_s.res.gz.uu
===================================================================
--- Tst/Short/Zdim_s.res.gz.uu	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
+++ Tst/Short/Zdim_s.res.gz.uu	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -0,0 +1,21 @@
+begin 644 Zdim_s.res.gz
+M'XL("#5B?TT``UID:6U?<RYR97,`I55=;]HP%'WG5UQ->X`*$DA":4&-U'4?
+M0D*H&MW#.FW()#?%K6,CVRG-?OUN4C`4RM.>$OM>'Y][S[$]N_L\G@)`+P;?
+M;\PVH\"C$5@T%DRB^<I"IC0LF$9N#"0JSYE,77;H[:^-/)B,/\$':ZPG^.+#
+MR$7Z,=#DG$MNFZU1H_I"',-]RO.Y\22N/6.9=>GG,;C_04TH809!/:,&!AE'
+MD4*G`X\%L;0*<O:$8`J-()5=<OD`:V9@H=432EB4P-*TFKS_]?+;P5YXH*M)
+M?=5M-U_:9:N=KD8-VNGL#&Y401L0%J@5(:2E9#E/@$K23)=#\)<J1]\@"FZ2
+MI7^C4O1GX^FW'Y/K[_Z,4`O!M+^:WVJ5F/G7BNY8IKCRC-KL\$5KZFJ.QK`'
+MA$RK'$QI+.;_!3ZD-DE'VRQ)M!34XA$34I$+',)449^293T"8I!R34&ERPVO
+M+3ZLN1"P5OH)5IK0M"C;L"@LY-5J(]0:M;==@PAVB3">SNZN)Q,PA,B5!"[K
+M:0=)QBF8J.V4HF5<&,^I<1D#3Y&BXZN@_>)\T^O&1#%O&ILVQRTR3J?G0F3;
+M\=5>:G"0NLL,8WBJRM&[Y"@^4M_LHOT]-AV*[B+GI_D,XK<^Y=+B`VKCG-S;
+M66X3.S+>3U4`B0:%J?(2A5G&$X[2U@L-K)><VL]>C?YZ#LQ6AEN!U=X4J.1@
+M9`(I2O)LSBVY("MDK0H3W);`#;!G4H`M!&Z65[*07(2PMZT#WWSN2,],"9+_
+ME5]]&9B:4(Y,UH>Q,LUPD]^AB\/0R5DI44J5<VHIT]PN<[0\<3G4S=U_^=?]
+M"YY9-R`K%\F6+`TPHTND:B:-78=/V"@XM)%3+3AP47#HHL!%CET41`>2W_O!
+M'^FB?2=W<ZMWT(Y:>Z)O,\]/T!Z<I'U1T0[W<R]/.C/LOJTQ[)V"#8.C&L/P
+MJ,;<Q:+C"GO==PH,^^\7&!X>IQV3P6&!X<7I`B_?%AB=E#OJ'148!;NW)J+G
+6K'JFJK>H,,U>:_2Q\0\7A7+S)@<`````
+`
+end
Index: Tst/Short/Zdim_s.stat
===================================================================
--- Tst/Short/Zdim_s.stat	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
+++ Tst/Short/Zdim_s.stat	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -0,0 +1,4 @@
+1 >> tst_memory_0 :: 1300193845:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:239720
+1 >> tst_memory_1 :: 1300193845:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:704128
+1 >> tst_memory_2 :: 1300193845:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:736928
+1 >> tst_timer_1 :: 1300193845:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:5
Index: Tst/Short/Zdim_s.tst
===================================================================
--- Tst/Short/Zdim_s.tst	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
+++ Tst/Short/Zdim_s.tst	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -0,0 +1,43 @@
+//
+// test script for dim over rings
+//
+LIB "tst.lib";
+tst_init();
+
+// case over a field -- just to make sure nothing was broken by adding Z[x]
+ring r=0,(x,y),dp;
+ideal I=2,x;
+dim(std(I));
+I=x;
+dim(std(I));
+kill r;
+ring r=0,(x,y),ds;
+ideal I=2-x,y;
+dim(std(I));
+// case over integers 
+ring r=integer,(x,y),dp;
+ideal I=2,x;
+dim(std(I));
+I=x;
+dim(std(I));
+kill r;
+// case over Z/2^n
+ring r=(integer,2,4),(x,y),dp;
+ideal I=2,x;
+dim(std(I));
+I=3,x;
+dim(std(I));
+I=x;
+dim(std(I));
+kill r;
+// case over Z/m
+ring r=(integer,10),(x,y),dp;
+ideal I=2,x;
+dim(std(I));
+I=3,x;
+dim(std(I));
+I=x;
+dim(std(I));
+kill r;
+
+tst_status(1);$
Index: Tst/Short/ZidealAdd_s.res.gz.uu
===================================================================
--- Tst/Short/ZidealAdd_s.res.gz.uu	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
+++ Tst/Short/ZidealAdd_s.res.gz.uu	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -0,0 +1,22 @@
+begin 644 ZidealAdd_s.res.gz
+M'XL("--Z?TT``UII9&5A;$%D9%]S+G)E<P"E5<%NVS@0O?LK!L4>DJXM613M
+MQ#$L(.UN"Q=!4-39PW:1-6AI'+.E1(.DZFB_OJ0LT4R3[:4GBL/AXYOW..+J
+M[H_E+0`D&<3Q8-7-2&1G8%`;T+GB>P-;J8`5!3=<5B"WP`MD0H/\A@H4KQZT
+MWYM&(1*-X&;Y!EX9;2+!-Z_F?F62@0VN><7-V?E\X$;(,OC<(E\7Q5I'%1XB
+M;9CQ>Z89^.^+J#T8U()7!A]0#<\>A\WYL-C/!Y;\Z]?PMZR!*81:N[Q<XG;+
+M<XZ5.3*&PX[GNS:CDK9"CJ+04;?WHT"FVP4$LV,&9"4:$+SD!@O8UE7NE&""
+MFP:X!O:-<<$V`KOM3BZS0XL0'.O!N^%NAS91"'DX\BM+5A6Z)50BLS2-A(-4
+M7Z^Z_!%LF.8Y[*5H*EER)FPN-[L2#<]]CC;%Z;OYSW\+OC5^HK"H\Y[L6UF+
+MHM5`[K&"HJE8:8^Q=BFFFBN(=[+$6",*KO-=_%86&*^6M^__NKG^%*\L]UHP
+M%>_7'Y7,]?J=T_$]5JB8B+3LSOA3*2M)B5JS!UNUDJ4EIPV6OPA_!3FK/'6]
+ML^(5(#=?,'>."KR"6PFZMCZ[&5@.!5=V4:JF8]:?``<N1*LW[)5%4Z(9PJ8V
+M4+K=VKJ$JC=PA>Y6("QO5W?7-S>@L;T.P*LV["&MH;5UR=V&`HV](O8*]/?W
+M,CLV$2P7L^'CJ2]F??S#(AT^$K^0C#-8_OYA/EC_D]PO9G8@]XM'.Z3WB]0.
+MU,Z(3[;]_!0W(5F+.`I"Z<\0^R3JD$9I"#4Y0I$@-`VA1NG_8%UD\-6IK$X;
+M+]V/QYIH6Z7]F7R.2[\V\RU^UO=X,CX/^KQ+)..3EC0@2I*3EM-02T)"NO0)
+MV^F/6A(GTV(2XE(GP"34DDQ"Q$F/V*\Z>18DA+AP$#34D%R&$.0)*>J39C\:
+MFXX=4HB=)B%0XL/D6$=P9)JV3@8!^D(9I/?1UY-.GAF93I\92?ZM_.K%<RO)
+M,'W!R_0R]'(4F)8&G4&".!V_8.;HY!]-CN+34YFT;89`")J^H#WMZB:^;DJ?
+=U4TGIS>)3J/V37-O5JW/DO/Y;X/OI=]3$V$'````
+`
+end
Index: Tst/Short/ZidealAdd_s.stat
===================================================================
--- Tst/Short/ZidealAdd_s.stat	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
+++ Tst/Short/ZidealAdd_s.stat	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -0,0 +1,4 @@
+1 >> tst_memory_0 :: 1300200147:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:195168
+1 >> tst_memory_1 :: 1300200147:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:667288
+1 >> tst_memory_2 :: 1300200147:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:700088
+1 >> tst_timer_1 :: 1300200147:3120- exportiert :3-1-2:x86_64-Linux:mandelbrot:6
Index: Tst/Short/ZidealAdd_s.tst
===================================================================
--- Tst/Short/ZidealAdd_s.tst	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
+++ Tst/Short/ZidealAdd_s.tst	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -0,0 +1,46 @@
+//
+// test script for addition of ideals over rings
+//
+LIB "tst.lib";
+tst_init();
+
+ring r=integer,(x,y),dp;
+ideal I=9,x;
+ideal J=3,x2;
+I+J;
+I=9,x;
+J=3,-x;
+I+J;
+I=-3,x;
+J=3,2x;
+I+J;
+kill r;
+// case over Z/m
+ring r=(integer,10),(x,y),dp;
+ideal I=4,x;
+ideal J=6,x2;
+I+J;
+I=5,x;
+J=5,-x;
+I+J;
+I=2,x;
+J=4,2x;
+I+J;
+I=9,x;
+J=2,x;
+I+J;
+I=5,2x;
+J=3x;
+I+J;
+kill r;
+// case over Z/2^n
+ring r=(integer,2,3),(x,y),dp;
+ideal I=4,-x2;
+ideal J=2x2;
+I+J;
+I=2,4x;
+J=2x;
+I+J;
+kill r;
+
+tst_status(1);$
Index: kernel/ideals.cc
===================================================================
--- kernel/ideals.cc	(revision c4dab43d69dd36ed09ba07d4e771236f8a7bcc39)
+++ kernel/ideals.cc	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -94,4 +94,17 @@
 #endif
 
+/* index of generator with leading term in ground ring (if any);
+   otherwise -1 */
+int idPosConstant(ideal id)
+{
+  int k;
+  for (k = IDELEMS(id)-1; k>=0; k--)
+  {
+    if (p_LmIsConstantComp(id->m[k], currRing) == TRUE)
+      return k;
+  }
+  return -1;
+}
+
 /*2
 * initialise the maximal ideal (at 0)
@@ -223,5 +236,5 @@
 
 /*2
-* ideal id = (id[i]), c any number
+* ideal id = (id[i]), c any unit
 * if id[i] = c*id[j] then id[j] is deleted for j > i
 */
@@ -236,8 +249,23 @@
       for (j=k; j>i; j--)
       {
-        if ((id->m[j]!=NULL)
-        && (pComparePolys(id->m[i], id->m[j])))
+        if (id->m[j]!=NULL)
         {
-          pDelete(&id->m[j]);
+#ifdef HAVE_RINGS
+          if (rField_is_Ring(currRing))
+          {
+            /* if id[j] = c*id[i] then delete id[j].
+               In the below cases of a ground field, we
+               check whether id[i] = c*id[j] and, if so,
+               delete id[j] for historical reasons (so
+               that previous output does not change) */
+            if (pComparePolys(id->m[j], id->m[i])) pDelete(&id->m[j]);
+          }
+          else
+          {
+            if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
+          }
+#else
+          if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
+#endif          
         }
       }
Index: kernel/ideals.h
===================================================================
--- kernel/ideals.h	(revision c4dab43d69dd36ed09ba07d4e771236f8a7bcc39)
+++ kernel/ideals.h	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -62,4 +62,7 @@
   /*- initialise the maximal ideal (at 0) -*/
 void idSkipZeroes (ideal ide);
+/* index of generator with leading term in ground ring (if any);
+   otherwise -1 */
+int idPosConstant (ideal id);
   /*gives an ideal the minimal possible size*/
 void idNorm(ideal id);
Index: kernel/pInline1.h
===================================================================
--- kernel/pInline1.h	(revision c4dab43d69dd36ed09ba07d4e771236f8a7bcc39)
+++ kernel/pInline1.h	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -587,4 +587,8 @@
 {
   if (p == NULL) return FALSE;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+    return (p_LmIsConstant(p, r) && nIsUnit(pGetCoeff(p)));
+#endif
   return p_LmIsConstant(p, r);
 }
Index: kernel/polys1.cc
===================================================================
--- kernel/polys1.cc	(revision c4dab43d69dd36ed09ba07d4e771236f8a7bcc39)
+++ kernel/polys1.cc	(revision dd5534a607684bd18fa828b336e69ddaf1ce55d1)
@@ -1717,4 +1717,12 @@
   if (pLength(p1) != pLength(p2))
     return FALSE;
+#ifdef HAVE_RINGS
+  if (rField_is_Ring(currRing))
+  {
+    if ((pLength(p1) == 1) && (nEqual(pGetCoeff(p1), pGetCoeff(p2))))
+      return TRUE;
+    if (!nIsUnit(pGetCoeff(p2))) return FALSE;
+  }
+#endif
   n=nDiv(pGetCoeff(p1),pGetCoeff(p2));
   while ((p1 != NULL) /*&& (p2 != NULL)*/)
